win-pvdrivers

annotate xenpci/xenpci.h @ 274:874c3640830e

Lots more updates. Added pvscsi support and started working on the stub drivers. Also working on unload support.
author James Harper <james.harper@bendigoit.com.au>
date Thu May 22 13:46:15 2008 +1000 (2008-05-22)
parents 909b775a891f
children 685399b9adb0
rev   line source
james@0 1 /*
james@0 2 PV Drivers for Windows Xen HVM Domains
james@0 3 Copyright (C) 2007 James Harper
james@0 4
james@0 5 This program is free software; you can redistribute it and/or
james@0 6 modify it under the terms of the GNU General Public License
james@0 7 as published by the Free Software Foundation; either version 2
james@0 8 of the License, or (at your option) any later version.
james@0 9
james@0 10 This program is distributed in the hope that it will be useful,
james@0 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
james@0 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
james@0 13 GNU General Public License for more details.
james@0 14
james@0 15 You should have received a copy of the GNU General Public License
james@0 16 along with this program; if not, write to the Free Software
james@0 17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
james@0 18 */
james@0 19
james@0 20 #if !defined(_XENPCI_H_)
james@0 21 #define _XENPCI_H_
james@0 22
james@0 23 #define __attribute__(arg) /* empty */
james@0 24 #define EISCONN 127
james@0 25
james@0 26 #include <ntddk.h>
james@0 27 #include <wdm.h>
james@258 28 //#include <wdf.h>
james@0 29 #include <initguid.h>
james@0 30 #include <wdmguid.h>
james@0 31 #include <errno.h>
james@0 32
james@0 33 #define NTSTRSAFE_LIB
james@0 34 #include <ntstrsafe.h>
james@0 35
james@74 36 #define __DRIVER_NAME "XenPCI"
james@74 37
james@0 38 #include <xen_windows.h>
james@0 39 #include <memory.h>
james@0 40 #include <grant_table.h>
james@0 41 #include <event_channel.h>
james@0 42 #include <hvm/params.h>
james@0 43 #include <hvm/hvm_op.h>
james@198 44 #include <sched.h>
james@267 45 #include <io/xenbus.h>
james@0 46
andy@15 47 #include <xen_public.h>
andy@15 48
james@0 49 //{C828ABE9-14CA-4445-BAA6-82C2376C6518}
james@0 50 DEFINE_GUID( GUID_XENPCI_DEVCLASS, 0xC828ABE9, 0x14CA, 0x4445, 0xBA, 0xA6, 0x82, 0xC2, 0x37, 0x6C, 0x65, 0x18);
james@0 51
james@0 52 #define XENPCI_POOL_TAG (ULONG) 'XenP'
james@0 53
james@0 54 #define NR_RESERVED_ENTRIES 8
james@0 55 #define NR_GRANT_FRAMES 4
james@0 56 #define NR_GRANT_ENTRIES (NR_GRANT_FRAMES * PAGE_SIZE / sizeof(grant_entry_t))
james@0 57
james@0 58 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
james@0 59
james@267 60 #define EVT_ACTION_TYPE_EMPTY 0
james@267 61 #define EVT_ACTION_TYPE_NORMAL 1
james@267 62 #define EVT_ACTION_TYPE_DPC 2
james@267 63 #define EVT_ACTION_TYPE_IRQ 3
james@267 64
andy@13 65 typedef struct _ev_action_t {
andy@13 66 PKSERVICE_ROUTINE ServiceRoutine;
andy@13 67 PVOID ServiceContext;
james@267 68 ULONG type; /* EVT_ACTION_TYPE_* */
james@258 69 KDPC Dpc;
james@267 70 ULONG vector;
andy@13 71 ULONG Count;
andy@13 72 } ev_action_t;
james@0 73
andy@15 74 typedef struct _XENBUS_WATCH_RING
andy@15 75 {
andy@15 76 char Path[128];
andy@15 77 char Token[10];
andy@15 78 } XENBUS_WATCH_RING;
james@0 79
andy@15 80 typedef struct _XENBUS_REQ_INFO
andy@15 81 {
andy@15 82 int In_Use:1;
andy@15 83 KEVENT WaitEvent;
andy@15 84 void *Reply;
andy@15 85 } XENBUS_REQ_INFO;
james@0 86
andy@15 87 typedef struct _XENBUS_WATCH_ENTRY {
andy@15 88 char Path[128];
andy@15 89 PXENBUS_WATCH_CALLBACK ServiceRoutine;
andy@15 90 PVOID ServiceContext;
andy@15 91 int Count;
andy@15 92 int Active;
james@138 93 int RemovePending;
james@128 94 int Running;
james@128 95 KEVENT CompleteEvent;
andy@15 96 } XENBUS_WATCH_ENTRY, *PXENBUS_WATCH_ENTRY;
james@0 97
andy@13 98 #define NR_EVENTS 1024
andy@15 99 #define WATCH_RING_SIZE 128
andy@15 100 #define NR_XB_REQS 32
andy@15 101 #define MAX_WATCH_ENTRIES 128
james@0 102
james@259 103 #define CHILD_STATE_EMPTY 0
james@259 104 #define CHILD_STATE_DELETED 1
james@259 105 #define CHILD_STATE_ADDED 2
james@259 106
james@259 107 // TODO: tidy up & organize this struct
james@258 108
james@274 109 typedef enum {
james@274 110 Unknown = 0,
james@274 111 NotStarted,
james@274 112 Started,
james@274 113 StopPending,
james@274 114 Stopped,
james@274 115 RemovePending,
james@274 116 SurpriseRemovePending,
james@274 117 Removed
james@274 118 } DEVICE_PNP_STATE;
james@274 119
james@258 120 typedef struct
james@258 121 {
james@258 122 PDEVICE_OBJECT fdo;
james@258 123 PDEVICE_OBJECT pdo;
james@258 124 PDEVICE_OBJECT lower_do;
james@274 125
james@274 126 DEVICE_PNP_STATE device_pnp_state;
james@274 127 DEVICE_POWER_STATE device_power_state;
james@274 128 SYSTEM_POWER_STATE system_power_state;
james@259 129 } XENPCI_COMMON, *PXENPCI_COMMON;
james@259 130
james@272 131 #define SHUTDOWN_RING_SIZE 128
james@272 132
james@259 133 typedef struct {
james@259 134 XENPCI_COMMON common;
james@259 135
andy@38 136 BOOLEAN XenBus_ShuttingDown;
james@0 137
james@258 138 PKINTERRUPT interrupt;
james@258 139 ULONG irq_number;
james@258 140 ULONG irq_vector;
james@258 141 KIRQL irq_level;
james@258 142 KAFFINITY irq_affinity;
james@0 143
andy@13 144 shared_info_t *shared_info_area;
james@0 145
andy@13 146 PHYSICAL_ADDRESS platform_mmio_addr;
andy@13 147 ULONG platform_mmio_orig_len;
andy@13 148 ULONG platform_mmio_len;
andy@13 149 ULONG platform_mmio_alloc;
james@267 150 USHORT platform_mmio_flags;
andy@13 151
andy@13 152 char *hypercall_stubs;
andy@13 153
andy@13 154 evtchn_port_t xen_store_evtchn;
andy@13 155
andy@13 156 grant_entry_t *gnttab_table;
andy@13 157 PHYSICAL_ADDRESS gnttab_table_physical;
andy@13 158 grant_ref_t gnttab_list[NR_GRANT_ENTRIES];
andy@13 159
andy@13 160 ev_action_t ev_actions[NR_EVENTS];
james@258 161 // unsigned long bound_ports[NR_EVENTS/(8*sizeof(unsigned long))];
james@0 162
andy@15 163 HANDLE XenBus_ReadThreadHandle;
andy@15 164 KEVENT XenBus_ReadThreadEvent;
andy@15 165 HANDLE XenBus_WatchThreadHandle;
andy@15 166 KEVENT XenBus_WatchThreadEvent;
andy@15 167
andy@15 168 XENBUS_WATCH_RING XenBus_WatchRing[WATCH_RING_SIZE];
andy@15 169 int XenBus_WatchRingReadIndex;
andy@15 170 int XenBus_WatchRingWriteIndex;
andy@15 171
andy@15 172 struct xenstore_domain_interface *xen_store_interface;
andy@15 173
andy@15 174 XENBUS_REQ_INFO req_info[NR_XB_REQS];
andy@15 175 int nr_live_reqs;
andy@15 176 XENBUS_WATCH_ENTRY XenBus_WatchEntries[MAX_WATCH_ENTRIES];
james@0 177
james@128 178 KSPIN_LOCK WatchLock;
james@176 179 KSPIN_LOCK grant_lock;
james@191 180
james@191 181 KGUARDED_MUTEX WatchHandlerMutex;
james@198 182
james@259 183 LIST_ENTRY child_list;
james@258 184
james@198 185 int suspending;
james@271 186
james@271 187 UNICODE_STRING interface_name;
james@272 188 BOOLEAN interface_open;
james@272 189
james@272 190 KSPIN_LOCK shutdown_ring_lock;
james@272 191 CHAR shutdown_ring[SHUTDOWN_RING_SIZE];
james@272 192 ULONG shutdown_prod;
james@272 193 ULONG shutdown_cons;
james@272 194 ULONG shutdown_start; /* the start of the most recent message on the ring */
james@272 195 PIRP shutdown_irp;
james@0 196 } XENPCI_DEVICE_DATA, *PXENPCI_DEVICE_DATA;
james@0 197
james@274 198 /* The total number of event channels or rings allowed per device... probably never more than 2 */
james@274 199 #define MAX_RESOURCES 4
james@274 200
james@259 201 typedef struct {
james@259 202 XENPCI_COMMON common;
james@261 203 PDEVICE_OBJECT bus_fdo;
james@259 204 char path[128];
james@267 205 char device[128];
james@259 206 ULONG index;
james@267 207 ULONG irq_vector;
james@267 208 KIRQL irq_level;
james@267 209 char backend_path[128];
james@274 210 PVOID xenbus_request;
james@267 211 KEVENT backend_state_event;
james@267 212 ULONG backend_state;
james@274 213 grant_ref_t grant_refs[MAX_RESOURCES];
james@274 214 PMDL mdls[MAX_RESOURCES];
james@274 215 evtchn_port_t event_channels[MAX_RESOURCES];
james@259 216 } XENPCI_PDO_DEVICE_DATA, *PXENPCI_PDO_DEVICE_DATA;
james@0 217
james@259 218 typedef struct
james@259 219 {
james@259 220 LIST_ENTRY entry;
james@259 221 int state;
james@259 222 PXENPCI_PDO_DEVICE_DATA context;
james@259 223 } XEN_CHILD, *PXEN_CHILD;
james@267 224
james@267 225 #define SWINT(x) case x: __asm { int x } break;
james@267 226
james@274 227 #if defined(_X86_)
james@267 228 static __inline VOID
james@267 229 sw_interrupt(UCHAR intno)
james@267 230 {
james@269 231 //KdPrint((__DRIVER_NAME " Calling interrupt %02X\n", intno));
james@267 232 switch (intno)
james@267 233 {
james@267 234 SWINT(0x10) SWINT(0x11) SWINT(0x12) SWINT(0x13) SWINT(0x14) SWINT(0x15) SWINT(0x16) SWINT(0x17)
james@267 235 SWINT(0x18) SWINT(0x19) SWINT(0x1A) SWINT(0x1B) SWINT(0x1C) SWINT(0x1D) SWINT(0x1E) SWINT(0x1F)
james@267 236 SWINT(0x20) SWINT(0x21) SWINT(0x22) SWINT(0x23) SWINT(0x24) SWINT(0x25) SWINT(0x26) SWINT(0x27)
james@267 237 SWINT(0x28) SWINT(0x29) SWINT(0x2A) SWINT(0x2B) SWINT(0x2C) SWINT(0x2D) SWINT(0x2E) SWINT(0x2F)
james@267 238 SWINT(0x30) SWINT(0x31) SWINT(0x32) SWINT(0x33) SWINT(0x34) SWINT(0x35) SWINT(0x36) SWINT(0x37)
james@267 239 SWINT(0x38) SWINT(0x39) SWINT(0x3A) SWINT(0x3B) SWINT(0x3C) SWINT(0x3D) SWINT(0x3E) SWINT(0x3F)
james@267 240 SWINT(0x40) SWINT(0x41) SWINT(0x42) SWINT(0x43) SWINT(0x44) SWINT(0x45) SWINT(0x46) SWINT(0x47)
james@267 241 SWINT(0x48) SWINT(0x49) SWINT(0x4A) SWINT(0x4B) SWINT(0x4C) SWINT(0x4D) SWINT(0x4E) SWINT(0x4F)
james@267 242
james@267 243 SWINT(0x80) SWINT(0x81) SWINT(0x82) SWINT(0x83) SWINT(0x84) SWINT(0x85) SWINT(0x86) SWINT(0x87)
james@267 244 SWINT(0x88) SWINT(0x89) SWINT(0x8A) SWINT(0x8B) SWINT(0x8C) SWINT(0x8D) SWINT(0x8E) SWINT(0x8F)
james@267 245
james@267 246 SWINT(0xB0) SWINT(0xB1) SWINT(0xB2) SWINT(0xB3) SWINT(0xB4) SWINT(0xB5) SWINT(0xB6) SWINT(0xB7)
james@267 247 SWINT(0xB8) SWINT(0xB9) SWINT(0xBA) SWINT(0xBB) SWINT(0xBC) SWINT(0xBD) SWINT(0xBE) SWINT(0xBF)
james@267 248
james@267 249 default:
james@267 250 KdPrint((__DRIVER_NAME " interrupt %02X not set up. Blame James.\n", intno));
james@267 251 KeBugCheckEx(('X' << 16)|('E' << 8)|('N'), 0x00000002, (ULONG)intno, 0x00000000, 0x00000000);
james@267 252 break;
james@267 253 }
james@267 254 }
james@274 255 #else
james@274 256 VOID _sw_interrupt(UCHAR);
james@274 257
james@274 258 static __inline VOID
james@274 259 sw_interrupt(UCHAR intno)
james@274 260 {
james@274 261 _sw_interrupt(intno);
james@274 262 }
james@274 263 #endif
james@274 264
james@259 265
james@258 266 #include "hypercall.h"
james@124 267
james@0 268 typedef unsigned long xenbus_transaction_t;
james@0 269 typedef uint32_t XENSTORE_RING_IDX;
james@0 270
james@0 271 #define XBT_NIL ((xenbus_transaction_t)0)
james@0 272
james@267 273 static __inline VOID
james@267 274 XenPci_FreeMem(PVOID Ptr)
james@267 275 {
james@267 276 ExFreePoolWithTag(Ptr, XENPCI_POOL_TAG);
james@267 277 }
james@267 278
james@259 279 NTSTATUS
james@259 280 XenPci_Power_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
james@259 281 NTSTATUS
james@259 282 XenPci_Dummy_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
james@259 283 NTSTATUS
james@259 284 XenPci_Pnp_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
james@272 285 NTSTATUS
james@272 286 XenPci_Irp_Create_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
james@272 287 NTSTATUS
james@272 288 XenPci_Irp_Close_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
james@272 289 NTSTATUS
james@272 290 XenPci_Irp_Read_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
james@272 291 NTSTATUS
james@272 292 XenPci_Irp_Cleanup_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
james@259 293
james@259 294 NTSTATUS
james@259 295 XenPci_Power_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
james@272 296 //NTSTATUS
james@272 297 //XenPci_Dummy_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
james@259 298 NTSTATUS
james@259 299 XenPci_Pnp_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
james@272 300 NTSTATUS
james@272 301 XenPci_Irp_Create_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
james@272 302 NTSTATUS
james@272 303 XenPci_Irp_Close_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
james@272 304 NTSTATUS
james@272 305 XenPci_Irp_Read_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
james@272 306 NTSTATUS
james@272 307 XenPci_Irp_Cleanup_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
james@259 308
james@259 309
james@259 310
james@0 311 char *
andy@13 312 XenBus_Read(PVOID Context, xenbus_transaction_t xbt, const char *path, char **value);
james@0 313 char *
andy@13 314 XenBus_Write(PVOID Context, xenbus_transaction_t xbt, const char *path, const char *value);
james@0 315 char *
andy@13 316 XenBus_Printf(PVOID Context, xenbus_transaction_t xbt, const char *path, const char *fmt, ...);
james@0 317 char *
andy@13 318 XenBus_StartTransaction(PVOID Context, xenbus_transaction_t *xbt);
james@0 319 char *
andy@13 320 XenBus_EndTransaction(PVOID Context, xenbus_transaction_t t, int abort, int *retry);
andy@13 321 char *
andy@13 322 XenBus_List(PVOID Context, xenbus_transaction_t xbt, const char *prefix, char ***contents);
james@0 323 char *
andy@13 324 XenBus_AddWatch(PVOID Context, xenbus_transaction_t xbt, const char *Path, PXENBUS_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext);
james@0 325 char *
andy@13 326 XenBus_RemWatch(PVOID Context, xenbus_transaction_t xbt, const char *Path, PXENBUS_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext);
james@0 327 VOID
james@0 328 XenBus_ThreadProc(PVOID StartContext);
james@258 329 NTSTATUS
james@258 330 XenBus_Init(PXENPCI_DEVICE_DATA xpdd);
james@258 331 NTSTATUS
james@258 332 XenBus_Close(PXENPCI_DEVICE_DATA xpdd);
james@258 333 NTSTATUS
james@258 334 XenBus_Start(PXENPCI_DEVICE_DATA xpdd);
james@258 335 NTSTATUS
james@258 336 XenBus_Stop(PXENPCI_DEVICE_DATA xpdd);
james@0 337
james@0 338 PHYSICAL_ADDRESS
james@258 339 XenPci_AllocMMIO(PXENPCI_DEVICE_DATA xpdd, ULONG len);
james@0 340
andy@15 341 NTSTATUS
james@258 342 EvtChn_Init(PXENPCI_DEVICE_DATA xpdd);
james@258 343 NTSTATUS
james@258 344 EvtChn_Shutdown(PXENPCI_DEVICE_DATA xpdd);
james@258 345
james@0 346 NTSTATUS
andy@13 347 EvtChn_Mask(PVOID Context, evtchn_port_t Port);
james@0 348 NTSTATUS
andy@13 349 EvtChn_Unmask(PVOID Context, evtchn_port_t Port);
james@0 350 NTSTATUS
andy@13 351 EvtChn_Bind(PVOID Context, evtchn_port_t Port, PKSERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext);
james@0 352 NTSTATUS
james@73 353 EvtChn_BindDpc(PVOID Context, evtchn_port_t Port, PKSERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext);
james@73 354 NTSTATUS
james@267 355 EvtChn_BindIrq(PVOID Context, evtchn_port_t Port, ULONG vector);
james@267 356 NTSTATUS
andy@13 357 EvtChn_Unbind(PVOID Context, evtchn_port_t Port);
andy@13 358 NTSTATUS
andy@13 359 EvtChn_Notify(PVOID Context, evtchn_port_t Port);
james@0 360 evtchn_port_t
andy@13 361 EvtChn_AllocUnbound(PVOID Context, domid_t Domain);
james@0 362
andy@15 363 VOID
james@258 364 GntTbl_Init(PXENPCI_DEVICE_DATA xpdd);
james@258 365
james@0 366 grant_ref_t
james@258 367 GntTbl_GrantAccess(PVOID Context, domid_t domid, uint32_t, int readonly, grant_ref_t ref);
james@0 368 BOOLEAN
james@258 369 GntTbl_EndAccess(PVOID Context, grant_ref_t ref, BOOLEAN keepref);
james@206 370 VOID
james@258 371 GntTbl_PutRef(PVOID Context, grant_ref_t ref);
james@206 372 grant_ref_t
james@258 373 GntTbl_GetRef(PVOID Context);
james@0 374
james@0 375 #endif