win-pvdrivers

annotate xenpci/xenpci.h @ 302:af768b0bca2c

more mingw edits
I couldn't help getting rid of the huge interrupt switch statement. James please put it back if I am in error :-)
author Andy Grover <andy.grover@oracle.com>
date Tue Jun 10 20:15:37 2008 -0700 (2008-06-10)
parents 873944504204
children 5a7bfc1827a7
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>
andy@302 27
andy@302 28 #ifndef __MINGW32__
james@0 29 #include <wdm.h>
james@258 30 //#include <wdf.h>
james@0 31 #include <initguid.h>
james@0 32 #include <wdmguid.h>
james@0 33 #include <errno.h>
james@0 34 #define NTSTRSAFE_LIB
james@0 35 #include <ntstrsafe.h>
andy@302 36 #endif
james@0 37
james@74 38 #define __DRIVER_NAME "XenPCI"
james@74 39
james@0 40 #include <xen_windows.h>
james@0 41 #include <memory.h>
james@0 42 #include <grant_table.h>
james@0 43 #include <event_channel.h>
james@0 44 #include <hvm/params.h>
james@0 45 #include <hvm/hvm_op.h>
james@198 46 #include <sched.h>
james@267 47 #include <io/xenbus.h>
james@0 48
andy@15 49 #include <xen_public.h>
andy@15 50
james@0 51 //{C828ABE9-14CA-4445-BAA6-82C2376C6518}
james@0 52 DEFINE_GUID( GUID_XENPCI_DEVCLASS, 0xC828ABE9, 0x14CA, 0x4445, 0xBA, 0xA6, 0x82, 0xC2, 0x37, 0x6C, 0x65, 0x18);
james@0 53
james@0 54 #define XENPCI_POOL_TAG (ULONG) 'XenP'
james@0 55
james@0 56 #define NR_RESERVED_ENTRIES 8
james@0 57 #define NR_GRANT_FRAMES 4
james@0 58 #define NR_GRANT_ENTRIES (NR_GRANT_FRAMES * PAGE_SIZE / sizeof(grant_entry_t))
james@0 59
james@0 60 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
james@0 61
james@267 62 #define EVT_ACTION_TYPE_EMPTY 0
james@267 63 #define EVT_ACTION_TYPE_NORMAL 1
james@267 64 #define EVT_ACTION_TYPE_DPC 2
james@267 65 #define EVT_ACTION_TYPE_IRQ 3
james@267 66
andy@13 67 typedef struct _ev_action_t {
andy@13 68 PKSERVICE_ROUTINE ServiceRoutine;
andy@13 69 PVOID ServiceContext;
james@267 70 ULONG type; /* EVT_ACTION_TYPE_* */
james@258 71 KDPC Dpc;
james@267 72 ULONG vector;
andy@13 73 ULONG Count;
andy@13 74 } ev_action_t;
james@0 75
andy@15 76 typedef struct _XENBUS_WATCH_RING
andy@15 77 {
andy@15 78 char Path[128];
andy@15 79 char Token[10];
andy@15 80 } XENBUS_WATCH_RING;
james@0 81
andy@15 82 typedef struct _XENBUS_REQ_INFO
andy@15 83 {
andy@15 84 int In_Use:1;
andy@15 85 KEVENT WaitEvent;
andy@15 86 void *Reply;
andy@15 87 } XENBUS_REQ_INFO;
james@0 88
andy@15 89 typedef struct _XENBUS_WATCH_ENTRY {
andy@15 90 char Path[128];
andy@15 91 PXENBUS_WATCH_CALLBACK ServiceRoutine;
andy@15 92 PVOID ServiceContext;
andy@15 93 int Count;
andy@15 94 int Active;
james@138 95 int RemovePending;
james@128 96 int Running;
james@128 97 KEVENT CompleteEvent;
andy@15 98 } XENBUS_WATCH_ENTRY, *PXENBUS_WATCH_ENTRY;
james@0 99
andy@13 100 #define NR_EVENTS 1024
andy@15 101 #define WATCH_RING_SIZE 128
andy@15 102 #define NR_XB_REQS 32
andy@15 103 #define MAX_WATCH_ENTRIES 128
james@0 104
james@259 105 #define CHILD_STATE_EMPTY 0
james@259 106 #define CHILD_STATE_DELETED 1
james@259 107 #define CHILD_STATE_ADDED 2
james@259 108
james@259 109 // TODO: tidy up & organize this struct
james@258 110
james@274 111 typedef enum {
james@274 112 Unknown = 0,
james@274 113 NotStarted,
james@274 114 Started,
james@274 115 StopPending,
james@274 116 Stopped,
james@274 117 RemovePending,
james@274 118 SurpriseRemovePending,
james@274 119 Removed
james@274 120 } DEVICE_PNP_STATE;
james@274 121
james@258 122 typedef struct
james@258 123 {
james@258 124 PDEVICE_OBJECT fdo;
james@258 125 PDEVICE_OBJECT pdo;
james@258 126 PDEVICE_OBJECT lower_do;
james@274 127
james@284 128 DEVICE_PNP_STATE current_pnp_state;
james@284 129 DEVICE_PNP_STATE previous_pnp_state;
james@274 130 DEVICE_POWER_STATE device_power_state;
james@284 131 SYSTEM_POWER_STATE system_power_state;
james@284 132
james@284 133 ULONG device_usage_paging;
james@284 134 ULONG device_usage_dump;
james@284 135 ULONG device_usage_hibernation;
james@259 136 } XENPCI_COMMON, *PXENPCI_COMMON;
james@259 137
andy@302 138 static __inline void INIT_PNP_STATE(PXENPCI_COMMON common)
james@284 139 {
james@284 140 common->current_pnp_state = NotStarted;
james@284 141 common->previous_pnp_state = NotStarted;
james@284 142 }
james@284 143
andy@302 144 static __inline void SET_PNP_STATE(PXENPCI_COMMON common, DEVICE_PNP_STATE state)
james@284 145 {
james@284 146 common->previous_pnp_state = common->current_pnp_state;
james@284 147 common->current_pnp_state = state;
james@284 148 }
james@284 149
andy@302 150 static __inline void REVERT_PNP_STATE(PXENPCI_COMMON common)
james@284 151 {
james@284 152 common->current_pnp_state = common->previous_pnp_state;
james@284 153 }
james@284 154
james@272 155 #define SHUTDOWN_RING_SIZE 128
james@272 156
james@259 157 typedef struct {
james@259 158 XENPCI_COMMON common;
james@259 159
andy@38 160 BOOLEAN XenBus_ShuttingDown;
james@0 161
james@258 162 PKINTERRUPT interrupt;
james@258 163 ULONG irq_number;
james@258 164 ULONG irq_vector;
james@258 165 KIRQL irq_level;
james@258 166 KAFFINITY irq_affinity;
james@0 167
andy@13 168 shared_info_t *shared_info_area;
james@0 169
andy@13 170 PHYSICAL_ADDRESS platform_mmio_addr;
andy@13 171 ULONG platform_mmio_orig_len;
andy@13 172 ULONG platform_mmio_len;
andy@13 173 ULONG platform_mmio_alloc;
james@267 174 USHORT platform_mmio_flags;
andy@13 175
andy@13 176 char *hypercall_stubs;
andy@13 177
andy@13 178 evtchn_port_t xen_store_evtchn;
andy@13 179
andy@13 180 grant_entry_t *gnttab_table;
andy@13 181 PHYSICAL_ADDRESS gnttab_table_physical;
andy@13 182 grant_ref_t gnttab_list[NR_GRANT_ENTRIES];
andy@13 183
andy@13 184 ev_action_t ev_actions[NR_EVENTS];
james@258 185 // unsigned long bound_ports[NR_EVENTS/(8*sizeof(unsigned long))];
james@0 186
andy@15 187 HANDLE XenBus_ReadThreadHandle;
andy@15 188 KEVENT XenBus_ReadThreadEvent;
andy@15 189 HANDLE XenBus_WatchThreadHandle;
andy@15 190 KEVENT XenBus_WatchThreadEvent;
andy@15 191
andy@15 192 XENBUS_WATCH_RING XenBus_WatchRing[WATCH_RING_SIZE];
andy@15 193 int XenBus_WatchRingReadIndex;
andy@15 194 int XenBus_WatchRingWriteIndex;
andy@15 195
andy@15 196 struct xenstore_domain_interface *xen_store_interface;
andy@15 197
andy@15 198 XENBUS_REQ_INFO req_info[NR_XB_REQS];
andy@15 199 int nr_live_reqs;
andy@15 200 XENBUS_WATCH_ENTRY XenBus_WatchEntries[MAX_WATCH_ENTRIES];
james@0 201
james@128 202 KSPIN_LOCK WatchLock;
james@176 203 KSPIN_LOCK grant_lock;
james@191 204
andy@302 205 //KGUARDED_MUTEX WatchHandlerMutex;
james@198 206
james@259 207 LIST_ENTRY child_list;
james@258 208
james@198 209 int suspending;
james@271 210
james@271 211 UNICODE_STRING interface_name;
james@272 212 BOOLEAN interface_open;
james@272 213
james@272 214 KSPIN_LOCK shutdown_ring_lock;
james@272 215 CHAR shutdown_ring[SHUTDOWN_RING_SIZE];
james@272 216 ULONG shutdown_prod;
james@272 217 ULONG shutdown_cons;
james@272 218 ULONG shutdown_start; /* the start of the most recent message on the ring */
james@272 219 PIRP shutdown_irp;
james@0 220 } XENPCI_DEVICE_DATA, *PXENPCI_DEVICE_DATA;
james@0 221
james@274 222 /* The total number of event channels or rings allowed per device... probably never more than 2 */
james@274 223 #define MAX_RESOURCES 4
james@274 224
james@259 225 typedef struct {
james@259 226 XENPCI_COMMON common;
james@291 227 PDEVICE_OBJECT bus_pdo;
james@261 228 PDEVICE_OBJECT bus_fdo;
james@291 229 BOOLEAN ReportedMissing;
james@259 230 char path[128];
james@267 231 char device[128];
james@259 232 ULONG index;
james@267 233 ULONG irq_vector;
james@267 234 KIRQL irq_level;
james@267 235 char backend_path[128];
james@274 236 PVOID xenbus_request;
james@267 237 KEVENT backend_state_event;
james@267 238 ULONG backend_state;
james@274 239 grant_ref_t grant_refs[MAX_RESOURCES];
james@274 240 PMDL mdls[MAX_RESOURCES];
james@274 241 evtchn_port_t event_channels[MAX_RESOURCES];
james@259 242 } XENPCI_PDO_DEVICE_DATA, *PXENPCI_PDO_DEVICE_DATA;
james@0 243
james@259 244 typedef struct
james@259 245 {
james@259 246 LIST_ENTRY entry;
james@259 247 int state;
james@259 248 PXENPCI_PDO_DEVICE_DATA context;
james@259 249 } XEN_CHILD, *PXEN_CHILD;
james@267 250
james@274 251 #if defined(_X86_)
james@267 252 static __inline VOID
james@267 253 sw_interrupt(UCHAR intno)
james@267 254 {
james@269 255 //KdPrint((__DRIVER_NAME " Calling interrupt %02X\n", intno));
andy@302 256 if (intno >= 0x10)
james@267 257 {
andy@302 258 #ifdef __GNUC__
andy@302 259 /* TODO this gcc asm is wrong, need to use gcc asm extended template :( */
andy@302 260 __asm__("int $intno");
andy@302 261 #elif defined (_MSC_VER)
andy@302 262 /* James, would this work? */
andy@302 263 __asm {int intno}
andy@302 264 #else
andy@302 265 #error unknown compiler, what inline asm format to use?
andy@302 266 #endif
andy@302 267 }
andy@302 268 else
andy@302 269 {
james@267 270 KdPrint((__DRIVER_NAME " interrupt %02X not set up. Blame James.\n", intno));
james@267 271 KeBugCheckEx(('X' << 16)|('E' << 8)|('N'), 0x00000002, (ULONG)intno, 0x00000000, 0x00000000);
james@267 272 }
james@267 273 }
james@274 274 #else
james@274 275 VOID _sw_interrupt(UCHAR);
james@274 276
james@274 277 static __inline VOID
james@274 278 sw_interrupt(UCHAR intno)
james@274 279 {
james@274 280 _sw_interrupt(intno);
james@274 281 }
james@274 282 #endif
james@274 283
james@259 284
james@258 285 #include "hypercall.h"
james@124 286
james@0 287 typedef unsigned long xenbus_transaction_t;
james@0 288 typedef uint32_t XENSTORE_RING_IDX;
james@0 289
james@0 290 #define XBT_NIL ((xenbus_transaction_t)0)
james@0 291
james@267 292 static __inline VOID
james@267 293 XenPci_FreeMem(PVOID Ptr)
james@267 294 {
james@267 295 ExFreePoolWithTag(Ptr, XENPCI_POOL_TAG);
james@267 296 }
james@267 297
james@259 298 NTSTATUS
james@259 299 XenPci_Power_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
james@259 300 NTSTATUS
james@259 301 XenPci_Dummy_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
james@259 302 NTSTATUS
james@259 303 XenPci_Pnp_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
james@272 304 NTSTATUS
james@272 305 XenPci_Irp_Create_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
james@272 306 NTSTATUS
james@272 307 XenPci_Irp_Close_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
james@272 308 NTSTATUS
james@272 309 XenPci_Irp_Read_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
james@272 310 NTSTATUS
james@272 311 XenPci_Irp_Cleanup_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
james@259 312
james@259 313 NTSTATUS
james@259 314 XenPci_Power_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
james@272 315 //NTSTATUS
james@272 316 //XenPci_Dummy_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
james@259 317 NTSTATUS
james@259 318 XenPci_Pnp_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
james@272 319 NTSTATUS
james@272 320 XenPci_Irp_Create_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
james@272 321 NTSTATUS
james@272 322 XenPci_Irp_Close_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
james@272 323 NTSTATUS
james@272 324 XenPci_Irp_Read_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
james@272 325 NTSTATUS
james@272 326 XenPci_Irp_Cleanup_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
james@259 327
james@259 328
james@259 329
james@0 330 char *
andy@13 331 XenBus_Read(PVOID Context, xenbus_transaction_t xbt, const char *path, char **value);
james@0 332 char *
andy@13 333 XenBus_Write(PVOID Context, xenbus_transaction_t xbt, const char *path, const char *value);
james@0 334 char *
andy@13 335 XenBus_Printf(PVOID Context, xenbus_transaction_t xbt, const char *path, const char *fmt, ...);
james@0 336 char *
andy@13 337 XenBus_StartTransaction(PVOID Context, xenbus_transaction_t *xbt);
james@0 338 char *
andy@13 339 XenBus_EndTransaction(PVOID Context, xenbus_transaction_t t, int abort, int *retry);
andy@13 340 char *
andy@13 341 XenBus_List(PVOID Context, xenbus_transaction_t xbt, const char *prefix, char ***contents);
james@0 342 char *
andy@13 343 XenBus_AddWatch(PVOID Context, xenbus_transaction_t xbt, const char *Path, PXENBUS_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext);
james@0 344 char *
andy@13 345 XenBus_RemWatch(PVOID Context, xenbus_transaction_t xbt, const char *Path, PXENBUS_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext);
james@279 346 //VOID
james@279 347 //XenBus_ThreadProc(PVOID StartContext);
james@258 348 NTSTATUS
james@258 349 XenBus_Init(PXENPCI_DEVICE_DATA xpdd);
james@258 350 NTSTATUS
james@258 351 XenBus_Close(PXENPCI_DEVICE_DATA xpdd);
james@258 352 NTSTATUS
james@258 353 XenBus_Start(PXENPCI_DEVICE_DATA xpdd);
james@258 354 NTSTATUS
james@258 355 XenBus_Stop(PXENPCI_DEVICE_DATA xpdd);
james@279 356 VOID
james@279 357 XenBus_Resume(PXENPCI_DEVICE_DATA xpdd);
james@0 358
james@0 359 PHYSICAL_ADDRESS
james@258 360 XenPci_AllocMMIO(PXENPCI_DEVICE_DATA xpdd, ULONG len);
james@0 361
andy@15 362 NTSTATUS
james@258 363 EvtChn_Init(PXENPCI_DEVICE_DATA xpdd);
james@258 364 NTSTATUS
james@258 365 EvtChn_Shutdown(PXENPCI_DEVICE_DATA xpdd);
james@258 366
james@0 367 NTSTATUS
andy@13 368 EvtChn_Mask(PVOID Context, evtchn_port_t Port);
james@0 369 NTSTATUS
andy@13 370 EvtChn_Unmask(PVOID Context, evtchn_port_t Port);
james@0 371 NTSTATUS
andy@13 372 EvtChn_Bind(PVOID Context, evtchn_port_t Port, PKSERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext);
james@0 373 NTSTATUS
james@73 374 EvtChn_BindDpc(PVOID Context, evtchn_port_t Port, PKSERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext);
james@73 375 NTSTATUS
james@267 376 EvtChn_BindIrq(PVOID Context, evtchn_port_t Port, ULONG vector);
james@267 377 NTSTATUS
andy@13 378 EvtChn_Unbind(PVOID Context, evtchn_port_t Port);
andy@13 379 NTSTATUS
andy@13 380 EvtChn_Notify(PVOID Context, evtchn_port_t Port);
james@0 381 evtchn_port_t
andy@13 382 EvtChn_AllocUnbound(PVOID Context, domid_t Domain);
james@0 383
andy@15 384 VOID
james@258 385 GntTbl_Init(PXENPCI_DEVICE_DATA xpdd);
james@258 386
james@0 387 grant_ref_t
james@258 388 GntTbl_GrantAccess(PVOID Context, domid_t domid, uint32_t, int readonly, grant_ref_t ref);
james@0 389 BOOLEAN
james@258 390 GntTbl_EndAccess(PVOID Context, grant_ref_t ref, BOOLEAN keepref);
james@206 391 VOID
james@258 392 GntTbl_PutRef(PVOID Context, grant_ref_t ref);
james@206 393 grant_ref_t
james@258 394 GntTbl_GetRef(PVOID Context);
james@279 395 int
james@279 396 GntTbl_Map(PVOID Context, unsigned int start_idx, unsigned int end_idx);
james@0 397 #endif