win-pvdrivers

view xenpci/xenpci.h @ 324:39e1a87d9189

get rid of unneeded (?) stuff that gcc complains about
Add DDKAPI to dispatch routines. These resolve to __stdcall on MinGW, which apparently it needs.
author Andy Grover <andy.grover@oracle.com>
date Thu Jun 19 15:22:00 2008 -0700 (2008-06-19)
parents a55d72ac422f
children c563a0f32b2f
line source
1 /*
2 PV Drivers for Windows Xen HVM Domains
3 Copyright (C) 2007 James Harper
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
20 #if !defined(_XENPCI_H_)
21 #define _XENPCI_H_
23 #define __attribute__(arg) /* empty */
24 #define EISCONN 127
26 #include <ntddk.h>
28 #ifndef __MINGW32__
29 #include <wdm.h>
30 //#include <wdf.h>
31 #include <initguid.h>
32 #include <wdmguid.h>
33 #include <errno.h>
34 #define NTSTRSAFE_LIB
35 #include <ntstrsafe.h>
36 #endif
38 #define __DRIVER_NAME "XenPCI"
40 #include <xen_windows.h>
41 #include <memory.h>
42 #include <grant_table.h>
43 #include <event_channel.h>
44 #include <hvm/params.h>
45 #include <hvm/hvm_op.h>
46 #include <sched.h>
47 #include <io/xenbus.h>
49 #include <xen_public.h>
51 //{C828ABE9-14CA-4445-BAA6-82C2376C6518}
52 DEFINE_GUID( GUID_XENPCI_DEVCLASS, 0xC828ABE9, 0x14CA, 0x4445, 0xBA, 0xA6, 0x82, 0xC2, 0x37, 0x6C, 0x65, 0x18);
54 #define XENPCI_POOL_TAG (ULONG) 'XenP'
56 #define NR_RESERVED_ENTRIES 8
57 #define NR_GRANT_FRAMES 4
58 #define NR_GRANT_ENTRIES (NR_GRANT_FRAMES * PAGE_SIZE / sizeof(grant_entry_t))
60 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
62 #define EVT_ACTION_TYPE_EMPTY 0
63 #define EVT_ACTION_TYPE_NORMAL 1
64 #define EVT_ACTION_TYPE_DPC 2
65 #define EVT_ACTION_TYPE_IRQ 3
67 typedef struct _ev_action_t {
68 PKSERVICE_ROUTINE ServiceRoutine;
69 PVOID ServiceContext;
70 ULONG type; /* EVT_ACTION_TYPE_* */
71 KDPC Dpc;
72 ULONG vector;
73 ULONG Count;
74 } ev_action_t;
76 typedef struct _XENBUS_WATCH_RING
77 {
78 char Path[128];
79 char Token[10];
80 } XENBUS_WATCH_RING;
82 typedef struct _XENBUS_REQ_INFO
83 {
84 int In_Use:1;
85 KEVENT WaitEvent;
86 void *Reply;
87 } XENBUS_REQ_INFO;
89 typedef struct _XENBUS_WATCH_ENTRY {
90 char Path[128];
91 PXENBUS_WATCH_CALLBACK ServiceRoutine;
92 PVOID ServiceContext;
93 int Count;
94 int Active;
95 int RemovePending;
96 int Running;
97 KEVENT CompleteEvent;
98 } XENBUS_WATCH_ENTRY, *PXENBUS_WATCH_ENTRY;
100 #define NR_EVENTS 1024
101 #define WATCH_RING_SIZE 128
102 #define NR_XB_REQS 32
103 #define MAX_WATCH_ENTRIES 128
105 #define CHILD_STATE_EMPTY 0
106 #define CHILD_STATE_DELETED 1
107 #define CHILD_STATE_ADDED 2
109 // TODO: tidy up & organize this struct
111 typedef enum {
112 Unknown = 0,
113 NotStarted,
114 Started,
115 StopPending,
116 Stopped,
117 RemovePending,
118 SurpriseRemovePending,
119 Removed
120 } DEVICE_PNP_STATE;
122 typedef struct
123 {
124 PDEVICE_OBJECT fdo;
125 PDEVICE_OBJECT pdo;
126 PDEVICE_OBJECT lower_do;
128 DEVICE_PNP_STATE current_pnp_state;
129 DEVICE_PNP_STATE previous_pnp_state;
130 DEVICE_POWER_STATE device_power_state;
131 SYSTEM_POWER_STATE system_power_state;
133 ULONG device_usage_paging;
134 ULONG device_usage_dump;
135 ULONG device_usage_hibernation;
136 } XENPCI_COMMON, *PXENPCI_COMMON;
138 static __inline void INIT_PNP_STATE(PXENPCI_COMMON common)
139 {
140 common->current_pnp_state = NotStarted;
141 common->previous_pnp_state = NotStarted;
142 }
144 static __inline void SET_PNP_STATE(PXENPCI_COMMON common, DEVICE_PNP_STATE state)
145 {
146 common->previous_pnp_state = common->current_pnp_state;
147 common->current_pnp_state = state;
148 }
150 static __inline void REVERT_PNP_STATE(PXENPCI_COMMON common)
151 {
152 common->current_pnp_state = common->previous_pnp_state;
153 }
155 #define SHUTDOWN_RING_SIZE 128
157 typedef struct {
158 XENPCI_COMMON common;
160 BOOLEAN XenBus_ShuttingDown;
162 PKINTERRUPT interrupt;
163 ULONG irq_number;
164 ULONG irq_vector;
165 KIRQL irq_level;
166 KAFFINITY irq_affinity;
168 shared_info_t *shared_info_area;
170 PHYSICAL_ADDRESS platform_mmio_addr;
171 ULONG platform_mmio_orig_len;
172 ULONG platform_mmio_len;
173 ULONG platform_mmio_alloc;
174 USHORT platform_mmio_flags;
176 char *hypercall_stubs;
178 evtchn_port_t xen_store_evtchn;
180 grant_entry_t *gnttab_table;
181 PHYSICAL_ADDRESS gnttab_table_physical;
182 grant_ref_t gnttab_list[NR_GRANT_ENTRIES];
184 ev_action_t ev_actions[NR_EVENTS];
185 // unsigned long bound_ports[NR_EVENTS/(8*sizeof(unsigned long))];
187 HANDLE XenBus_ReadThreadHandle;
188 KEVENT XenBus_ReadThreadEvent;
189 HANDLE XenBus_WatchThreadHandle;
190 KEVENT XenBus_WatchThreadEvent;
192 XENBUS_WATCH_RING XenBus_WatchRing[WATCH_RING_SIZE];
193 int XenBus_WatchRingReadIndex;
194 int XenBus_WatchRingWriteIndex;
196 struct xenstore_domain_interface *xen_store_interface;
198 XENBUS_REQ_INFO req_info[NR_XB_REQS];
199 int nr_live_reqs;
200 XENBUS_WATCH_ENTRY XenBus_WatchEntries[MAX_WATCH_ENTRIES];
202 KSPIN_LOCK WatchLock;
203 KSPIN_LOCK grant_lock;
205 //KGUARDED_MUTEX WatchHandlerMutex;
207 LIST_ENTRY child_list;
209 int suspending;
211 UNICODE_STRING interface_name;
212 BOOLEAN interface_open;
214 KSPIN_LOCK shutdown_ring_lock;
215 CHAR shutdown_ring[SHUTDOWN_RING_SIZE];
216 ULONG shutdown_prod;
217 ULONG shutdown_cons;
218 ULONG shutdown_start; /* the start of the most recent message on the ring */
219 PIRP shutdown_irp;
220 } XENPCI_DEVICE_DATA, *PXENPCI_DEVICE_DATA;
222 typedef struct {
223 XENPCI_COMMON common;
224 PDEVICE_OBJECT bus_pdo;
225 PDEVICE_OBJECT bus_fdo;
226 BOOLEAN eject_requested;
227 BOOLEAN reported_missing;
228 char path[128];
229 char device[128];
230 ULONG index;
231 ULONG irq_vector;
232 KIRQL irq_level;
233 char backend_path[128];
234 //PVOID xenbus_request;
235 KEVENT backend_state_event;
236 ULONG backend_state;
237 PHYSICAL_ADDRESS config_page_phys;
238 ULONG config_page_length;
239 PUCHAR assigned_resources_start;
240 PUCHAR assigned_resources_ptr;
241 } XENPCI_PDO_DEVICE_DATA, *PXENPCI_PDO_DEVICE_DATA;
243 typedef struct
244 {
245 LIST_ENTRY entry;
246 int state;
247 PXENPCI_PDO_DEVICE_DATA context;
248 } XEN_CHILD, *PXEN_CHILD;
250 #ifdef __GNUC__
251 #define SWINT(x) case x: asm ("int x"); break;
252 #else
253 #define SWINT(x) case x: __asm { int x } break;
254 #endif
256 #if defined(_X86_)
257 static __inline VOID
258 sw_interrupt(UCHAR intno)
259 {
260 //KdPrint((__DRIVER_NAME " Calling interrupt %02X\n", intno));
261 switch (intno)
262 {
263 SWINT(0x10) SWINT(0x11) SWINT(0x12) SWINT(0x13) SWINT(0x14) SWINT(0x15) SWINT(0x16) SWINT(0x17)
264 SWINT(0x18) SWINT(0x19) SWINT(0x1A) SWINT(0x1B) SWINT(0x1C) SWINT(0x1D) SWINT(0x1E) SWINT(0x1F)
265 SWINT(0x20) SWINT(0x21) SWINT(0x22) SWINT(0x23) SWINT(0x24) SWINT(0x25) SWINT(0x26) SWINT(0x27)
266 SWINT(0x28) SWINT(0x29) SWINT(0x2A) SWINT(0x2B) SWINT(0x2C) SWINT(0x2D) SWINT(0x2E) SWINT(0x2F)
267 SWINT(0x30) SWINT(0x31) SWINT(0x32) SWINT(0x33) SWINT(0x34) SWINT(0x35) SWINT(0x36) SWINT(0x37)
268 SWINT(0x38) SWINT(0x39) SWINT(0x3A) SWINT(0x3B) SWINT(0x3C) SWINT(0x3D) SWINT(0x3E) SWINT(0x3F)
269 SWINT(0x40) SWINT(0x41) SWINT(0x42) SWINT(0x43) SWINT(0x44) SWINT(0x45) SWINT(0x46) SWINT(0x47)
270 SWINT(0x48) SWINT(0x49) SWINT(0x4A) SWINT(0x4B) SWINT(0x4C) SWINT(0x4D) SWINT(0x4E) SWINT(0x4F)
271 SWINT(0x50) SWINT(0x51) SWINT(0x52) SWINT(0x53) SWINT(0x54) SWINT(0x55) SWINT(0x56) SWINT(0x57)
272 SWINT(0x58) SWINT(0x59) SWINT(0x5A) SWINT(0x5B) SWINT(0x5C) SWINT(0x5D) SWINT(0x5E) SWINT(0x5F)
273 SWINT(0x60) SWINT(0x61) SWINT(0x62) SWINT(0x63) SWINT(0x64) SWINT(0x65) SWINT(0x66) SWINT(0x67)
274 SWINT(0x68) SWINT(0x69) SWINT(0x6A) SWINT(0x6B) SWINT(0x6C) SWINT(0x6D) SWINT(0x6E) SWINT(0x6F)
275 SWINT(0x70) SWINT(0x71) SWINT(0x72) SWINT(0x73) SWINT(0x74) SWINT(0x75) SWINT(0x76) SWINT(0x77)
276 SWINT(0x78) SWINT(0x79) SWINT(0x7A) SWINT(0x7B) SWINT(0x7C) SWINT(0x7D) SWINT(0x7E) SWINT(0x7F)
277 SWINT(0x80) SWINT(0x81) SWINT(0x82) SWINT(0x83) SWINT(0x84) SWINT(0x85) SWINT(0x86) SWINT(0x87)
278 SWINT(0x88) SWINT(0x89) SWINT(0x8A) SWINT(0x8B) SWINT(0x8C) SWINT(0x8D) SWINT(0x8E) SWINT(0x8F)
279 SWINT(0x90) SWINT(0x91) SWINT(0x92) SWINT(0x93) SWINT(0x94) SWINT(0x95) SWINT(0x96) SWINT(0x97)
280 SWINT(0x98) SWINT(0x99) SWINT(0x9A) SWINT(0x9B) SWINT(0x9C) SWINT(0x9D) SWINT(0x9E) SWINT(0x9F)
281 SWINT(0xA0) SWINT(0xA1) SWINT(0xA2) SWINT(0xA3) SWINT(0xA4) SWINT(0xA5) SWINT(0xA6) SWINT(0xA7)
282 SWINT(0xA8) SWINT(0xA9) SWINT(0xAA) SWINT(0xAB) SWINT(0xAC) SWINT(0xAD) SWINT(0xAE) SWINT(0xAF)
283 SWINT(0xB0) SWINT(0xB1) SWINT(0xB2) SWINT(0xB3) SWINT(0xB4) SWINT(0xB5) SWINT(0xB6) SWINT(0xB7)
284 SWINT(0xB8) SWINT(0xB9) SWINT(0xBA) SWINT(0xBB) SWINT(0xBC) SWINT(0xBD) SWINT(0xBE) SWINT(0xBF)
285 SWINT(0xC0) SWINT(0xC1) SWINT(0xC2) SWINT(0xC3) SWINT(0xC4) SWINT(0xC5) SWINT(0xC6) SWINT(0xC7)
286 SWINT(0xC8) SWINT(0xC9) SWINT(0xCA) SWINT(0xCB) SWINT(0xCC) SWINT(0xCD) SWINT(0xCE) SWINT(0xCF)
287 SWINT(0xD0) SWINT(0xD1) SWINT(0xD2) SWINT(0xD3) SWINT(0xD4) SWINT(0xD5) SWINT(0xD6) SWINT(0xD7)
288 SWINT(0xD8) SWINT(0xD9) SWINT(0xDA) SWINT(0xDB) SWINT(0xDC) SWINT(0xDD) SWINT(0xDE) SWINT(0xDF)
289 SWINT(0xE0) SWINT(0xE1) SWINT(0xE2) SWINT(0xE3) SWINT(0xE4) SWINT(0xE5) SWINT(0xE6) SWINT(0xE7)
290 SWINT(0xE8) SWINT(0xE9) SWINT(0xEA) SWINT(0xEB) SWINT(0xEC) SWINT(0xED) SWINT(0xEE) SWINT(0xEF)
291 SWINT(0xF0) SWINT(0xF1) SWINT(0xF2) SWINT(0xF3) SWINT(0xF4) SWINT(0xF5) SWINT(0xF6) SWINT(0xF7)
292 SWINT(0xF8) SWINT(0xF9) SWINT(0xFA) SWINT(0xFB) SWINT(0xFC) SWINT(0xFD) SWINT(0xFE) SWINT(0xFF)
294 default:
295 KdPrint((__DRIVER_NAME " interrupt %02X not set up. Blame James.\n", intno));
296 KeBugCheckEx(('X' << 16)|('E' << 8)|('N'), 0x00000002, (ULONG)intno, 0x00000000, 0x00000000);
297 break;
298 }
299 }
300 #else
301 VOID _sw_interrupt(UCHAR);
303 static __inline VOID
304 sw_interrupt(UCHAR intno)
305 {
306 _sw_interrupt(intno);
307 }
308 #endif
311 #include "hypercall.h"
313 #define XBT_NIL ((xenbus_transaction_t)0)
315 static __inline VOID
316 XenPci_FreeMem(PVOID Ptr)
317 {
318 ExFreePoolWithTag(Ptr, XENPCI_POOL_TAG);
319 }
321 NTSTATUS
322 XenPci_Power_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
323 NTSTATUS
324 XenPci_Dummy_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
325 NTSTATUS
326 XenPci_Pnp_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
327 NTSTATUS
328 XenPci_Irp_Create_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
329 NTSTATUS
330 XenPci_Irp_Close_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
331 NTSTATUS
332 XenPci_Irp_Read_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
333 NTSTATUS
334 XenPci_Irp_Cleanup_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
336 NTSTATUS
337 XenPci_Power_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
338 //NTSTATUS
339 //XenPci_Dummy_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
340 NTSTATUS
341 XenPci_Pnp_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
342 NTSTATUS
343 XenPci_Irp_Create_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
344 NTSTATUS
345 XenPci_Irp_Close_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
346 NTSTATUS
347 XenPci_Irp_Read_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
348 NTSTATUS
349 XenPci_Irp_Cleanup_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
353 char *
354 XenBus_Read(PVOID Context, xenbus_transaction_t xbt, const char *path, char **value);
355 char *
356 XenBus_Write(PVOID Context, xenbus_transaction_t xbt, const char *path, const char *value);
357 char *
358 XenBus_Printf(PVOID Context, xenbus_transaction_t xbt, const char *path, const char *fmt, ...);
359 char *
360 XenBus_StartTransaction(PVOID Context, xenbus_transaction_t *xbt);
361 char *
362 XenBus_EndTransaction(PVOID Context, xenbus_transaction_t t, int abort, int *retry);
363 char *
364 XenBus_List(PVOID Context, xenbus_transaction_t xbt, const char *prefix, char ***contents);
365 char *
366 XenBus_AddWatch(PVOID Context, xenbus_transaction_t xbt, const char *Path, PXENBUS_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext);
367 char *
368 XenBus_RemWatch(PVOID Context, xenbus_transaction_t xbt, const char *Path, PXENBUS_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext);
369 //VOID
370 //XenBus_ThreadProc(PVOID StartContext);
371 NTSTATUS
372 XenBus_Init(PXENPCI_DEVICE_DATA xpdd);
373 NTSTATUS
374 XenBus_Close(PXENPCI_DEVICE_DATA xpdd);
375 NTSTATUS
376 XenBus_Start(PXENPCI_DEVICE_DATA xpdd);
377 NTSTATUS
378 XenBus_Stop(PXENPCI_DEVICE_DATA xpdd);
379 VOID
380 XenBus_Resume(PXENPCI_DEVICE_DATA xpdd);
382 PHYSICAL_ADDRESS
383 XenPci_AllocMMIO(PXENPCI_DEVICE_DATA xpdd, ULONG len);
385 NTSTATUS
386 EvtChn_Init(PXENPCI_DEVICE_DATA xpdd);
387 NTSTATUS
388 EvtChn_Shutdown(PXENPCI_DEVICE_DATA xpdd);
390 NTSTATUS
391 EvtChn_Mask(PVOID Context, evtchn_port_t Port);
392 NTSTATUS
393 EvtChn_Unmask(PVOID Context, evtchn_port_t Port);
394 NTSTATUS
395 EvtChn_Bind(PVOID Context, evtchn_port_t Port, PKSERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext);
396 NTSTATUS
397 EvtChn_BindDpc(PVOID Context, evtchn_port_t Port, PKSERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext);
398 NTSTATUS
399 EvtChn_BindIrq(PVOID Context, evtchn_port_t Port, ULONG vector);
400 NTSTATUS
401 EvtChn_Unbind(PVOID Context, evtchn_port_t Port);
402 NTSTATUS
403 EvtChn_Notify(PVOID Context, evtchn_port_t Port);
404 evtchn_port_t
405 EvtChn_AllocUnbound(PVOID Context, domid_t Domain);
407 VOID
408 GntTbl_Init(PXENPCI_DEVICE_DATA xpdd);
410 grant_ref_t
411 GntTbl_GrantAccess(PVOID Context, domid_t domid, uint32_t, int readonly, grant_ref_t ref);
412 BOOLEAN
413 GntTbl_EndAccess(PVOID Context, grant_ref_t ref, BOOLEAN keepref);
414 VOID
415 GntTbl_PutRef(PVOID Context, grant_ref_t ref);
416 grant_ref_t
417 GntTbl_GetRef(PVOID Context);
418 int
419 GntTbl_Map(PVOID Context, unsigned int start_idx, unsigned int end_idx);
420 #endif