win-pvdrivers

view xenpci/xenpci.h @ 363:097ab7d19ea2

Merge bug fixer from WDF to WDM.
author Wayne Gong <wayne.gong@oracle.com>
date Mon Jul 07 14:03:39 2008 +0800 (2008-07-07)
parents b827e78992a3
children d76831a77d19
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 #ifdef __MINGW32__
29 #include "mingw_extras.h"
30 #else
31 #define DDKAPI
32 #include <wdm.h>
33 //#include <wdf.h>
34 #include <initguid.h>
35 #include <wdmguid.h>
36 #include <errno.h>
37 #define NTSTRSAFE_LIB
38 #include <ntstrsafe.h>
39 #endif
41 #define __DRIVER_NAME "XenPCI"
43 #include <xen_windows.h>
44 #include <memory.h>
45 #include <grant_table.h>
46 #include <event_channel.h>
47 #include <hvm/params.h>
48 #include <hvm/hvm_op.h>
49 #include <sched.h>
50 #include <io/xenbus.h>
52 #include <xen_public.h>
54 //{C828ABE9-14CA-4445-BAA6-82C2376C6518}
55 DEFINE_GUID( GUID_XENPCI_DEVCLASS, 0xC828ABE9, 0x14CA, 0x4445, 0xBA, 0xA6, 0x82, 0xC2, 0x37, 0x6C, 0x65, 0x18);
57 #define XENPCI_POOL_TAG (ULONG) 'XenP'
59 #define NR_RESERVED_ENTRIES 8
60 #define NR_GRANT_FRAMES 32
61 #define NR_GRANT_ENTRIES (NR_GRANT_FRAMES * PAGE_SIZE / sizeof(grant_entry_t))
63 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
65 #define EVT_ACTION_TYPE_EMPTY 0
66 #define EVT_ACTION_TYPE_NORMAL 1
67 #define EVT_ACTION_TYPE_DPC 2
68 #define EVT_ACTION_TYPE_IRQ 3
70 typedef struct _ev_action_t {
71 PKSERVICE_ROUTINE ServiceRoutine;
72 PVOID ServiceContext;
73 ULONG type; /* EVT_ACTION_TYPE_* */
74 KDPC Dpc;
75 ULONG vector;
76 ULONG Count;
77 PVOID xpdd;
78 } ev_action_t;
80 typedef struct _XENBUS_WATCH_RING
81 {
82 char Path[128];
83 char Token[10];
84 } XENBUS_WATCH_RING;
86 typedef struct _XENBUS_REQ_INFO
87 {
88 int In_Use:1;
89 KEVENT WaitEvent;
90 void *Reply;
91 } XENBUS_REQ_INFO;
93 typedef struct _XENBUS_WATCH_ENTRY {
94 char Path[128];
95 PXENBUS_WATCH_CALLBACK ServiceRoutine;
96 PVOID ServiceContext;
97 int Count;
98 int Active;
99 int RemovePending;
100 int Running;
101 KEVENT CompleteEvent;
102 } XENBUS_WATCH_ENTRY, *PXENBUS_WATCH_ENTRY;
104 #define NR_EVENTS 1024
105 #define WATCH_RING_SIZE 128
106 #define NR_XB_REQS 32
107 #define MAX_WATCH_ENTRIES 128
109 #define CHILD_STATE_EMPTY 0
110 #define CHILD_STATE_DELETED 1
111 #define CHILD_STATE_ADDED 2
113 // TODO: tidy up & organize this struct
115 typedef enum {
116 Unknown = 0,
117 NotStarted,
118 Started,
119 StopPending,
120 Stopped,
121 RemovePending,
122 SurpriseRemovePending,
123 Removed
124 } DEVICE_PNP_STATE;
126 typedef struct
127 {
128 PDEVICE_OBJECT fdo;
129 PDEVICE_OBJECT pdo;
130 PDEVICE_OBJECT lower_do;
132 DEVICE_PNP_STATE current_pnp_state;
133 DEVICE_PNP_STATE previous_pnp_state;
134 DEVICE_POWER_STATE device_power_state;
135 SYSTEM_POWER_STATE system_power_state;
137 ULONG device_usage_paging;
138 ULONG device_usage_dump;
139 ULONG device_usage_hibernation;
140 } XENPCI_COMMON, *PXENPCI_COMMON;
142 static __inline void INIT_PNP_STATE(PXENPCI_COMMON common)
143 {
144 common->current_pnp_state = NotStarted;
145 common->previous_pnp_state = NotStarted;
146 }
148 static __inline void SET_PNP_STATE(PXENPCI_COMMON common, DEVICE_PNP_STATE state)
149 {
150 common->previous_pnp_state = common->current_pnp_state;
151 common->current_pnp_state = state;
152 }
154 static __inline void REVERT_PNP_STATE(PXENPCI_COMMON common)
155 {
156 common->current_pnp_state = common->previous_pnp_state;
157 }
159 #define SHUTDOWN_RING_SIZE 128
161 typedef struct {
162 XENPCI_COMMON common;
164 BOOLEAN XenBus_ShuttingDown;
166 PKINTERRUPT interrupt;
167 ULONG irq_number;
168 ULONG irq_vector;
169 KIRQL irq_level;
170 KAFFINITY irq_affinity;
172 PHYSICAL_ADDRESS shared_info_area_unmapped;
173 shared_info_t *shared_info_area;
175 PHYSICAL_ADDRESS platform_mmio_addr;
176 ULONG platform_mmio_orig_len;
177 ULONG platform_mmio_len;
178 ULONG platform_mmio_alloc;
179 USHORT platform_mmio_flags;
181 char *hypercall_stubs;
183 evtchn_port_t xen_store_evtchn;
185 grant_entry_t *gnttab_table;
186 PHYSICAL_ADDRESS gnttab_table_physical;
187 grant_ref_t *gnttab_list;
189 ev_action_t ev_actions[NR_EVENTS];
190 // unsigned long bound_ports[NR_EVENTS/(8*sizeof(unsigned long))];
192 HANDLE XenBus_ReadThreadHandle;
193 KEVENT XenBus_ReadThreadEvent;
194 HANDLE XenBus_WatchThreadHandle;
195 KEVENT XenBus_WatchThreadEvent;
197 XENBUS_WATCH_RING XenBus_WatchRing[WATCH_RING_SIZE];
198 int XenBus_WatchRingReadIndex;
199 int XenBus_WatchRingWriteIndex;
201 struct xenstore_domain_interface *xen_store_interface;
203 XENBUS_REQ_INFO req_info[NR_XB_REQS];
204 int nr_live_reqs;
205 XENBUS_WATCH_ENTRY XenBus_WatchEntries[MAX_WATCH_ENTRIES];
207 KSPIN_LOCK WatchLock;
208 KSPIN_LOCK grant_lock;
210 //KGUARDED_MUTEX WatchHandlerMutex;
212 LIST_ENTRY child_list;
214 int suspending;
216 UNICODE_STRING interface_name;
217 BOOLEAN interface_open;
219 KSPIN_LOCK shutdown_ring_lock;
220 CHAR shutdown_ring[SHUTDOWN_RING_SIZE];
221 ULONG shutdown_prod;
222 ULONG shutdown_cons;
223 ULONG shutdown_start; /* the start of the most recent message on the ring */
224 PIRP shutdown_irp;
225 } XENPCI_DEVICE_DATA, *PXENPCI_DEVICE_DATA;
227 typedef struct {
228 XENPCI_COMMON common;
229 PDEVICE_OBJECT bus_pdo;
230 PDEVICE_OBJECT bus_fdo;
231 BOOLEAN eject_requested;
232 BOOLEAN reported_missing;
233 char path[128];
234 char device[128];
235 ULONG index;
236 ULONG irq_vector;
237 KIRQL irq_level;
238 char backend_path[128];
239 //PVOID xenbus_request;
240 KEVENT backend_state_event;
241 ULONG backend_state;
242 PHYSICAL_ADDRESS config_page_phys;
243 ULONG config_page_length;
244 PUCHAR requested_resources_start;
245 PUCHAR requested_resources_ptr;
246 PUCHAR assigned_resources_start;
247 PUCHAR assigned_resources_ptr;
248 XENPCI_DEVICE_STATE device_state;
249 } XENPCI_PDO_DEVICE_DATA, *PXENPCI_PDO_DEVICE_DATA;
251 typedef struct
252 {
253 LIST_ENTRY entry;
254 int state;
255 PXENPCI_PDO_DEVICE_DATA context;
256 } XEN_CHILD, *PXEN_CHILD;
258 #ifdef __GNUC__
259 #define SWINT(x) if (intno == x) { asm ("int $"#x";"); return;}
260 #else
261 #define SWINT(x) if (intno == x) { __asm { int x } return; }
262 #endif
264 #if defined(_X86_)
265 static __inline VOID
266 sw_interrupt(UCHAR intno)
267 {
268 //KdPrint((__DRIVER_NAME " Calling interrupt %02X\n", intno));
269 SWINT(0x10) SWINT(0x11) SWINT(0x12) SWINT(0x13) SWINT(0x14) SWINT(0x15) SWINT(0x16) SWINT(0x17)
270 SWINT(0x18) SWINT(0x19) SWINT(0x1A) SWINT(0x1B) SWINT(0x1C) SWINT(0x1D) SWINT(0x1E) SWINT(0x1F)
271 SWINT(0x20) SWINT(0x21) SWINT(0x22) SWINT(0x23) SWINT(0x24) SWINT(0x25) SWINT(0x26) SWINT(0x27)
272 SWINT(0x28) SWINT(0x29) SWINT(0x2A) SWINT(0x2B) SWINT(0x2C) SWINT(0x2D) SWINT(0x2E) SWINT(0x2F)
273 SWINT(0x30) SWINT(0x31) SWINT(0x32) SWINT(0x33) SWINT(0x34) SWINT(0x35) SWINT(0x36) SWINT(0x37)
274 SWINT(0x38) SWINT(0x39) SWINT(0x3A) SWINT(0x3B) SWINT(0x3C) SWINT(0x3D) SWINT(0x3E) SWINT(0x3F)
275 SWINT(0x40) SWINT(0x41) SWINT(0x42) SWINT(0x43) SWINT(0x44) SWINT(0x45) SWINT(0x46) SWINT(0x47)
276 SWINT(0x48) SWINT(0x49) SWINT(0x4A) SWINT(0x4B) SWINT(0x4C) SWINT(0x4D) SWINT(0x4E) SWINT(0x4F)
277 SWINT(0x50) SWINT(0x51) SWINT(0x52) SWINT(0x53) SWINT(0x54) SWINT(0x55) SWINT(0x56) SWINT(0x57)
278 SWINT(0x58) SWINT(0x59) SWINT(0x5A) SWINT(0x5B) SWINT(0x5C) SWINT(0x5D) SWINT(0x5E) SWINT(0x5F)
279 SWINT(0x60) SWINT(0x61) SWINT(0x62) SWINT(0x63) SWINT(0x64) SWINT(0x65) SWINT(0x66) SWINT(0x67)
280 SWINT(0x68) SWINT(0x69) SWINT(0x6A) SWINT(0x6B) SWINT(0x6C) SWINT(0x6D) SWINT(0x6E) SWINT(0x6F)
281 SWINT(0x70) SWINT(0x71) SWINT(0x72) SWINT(0x73) SWINT(0x74) SWINT(0x75) SWINT(0x76) SWINT(0x77)
282 SWINT(0x78) SWINT(0x79) SWINT(0x7A) SWINT(0x7B) SWINT(0x7C) SWINT(0x7D) SWINT(0x7E) SWINT(0x7F)
283 SWINT(0x80) SWINT(0x81) SWINT(0x82) SWINT(0x83) SWINT(0x84) SWINT(0x85) SWINT(0x86) SWINT(0x87)
284 SWINT(0x88) SWINT(0x89) SWINT(0x8A) SWINT(0x8B) SWINT(0x8C) SWINT(0x8D) SWINT(0x8E) SWINT(0x8F)
285 SWINT(0x90) SWINT(0x91) SWINT(0x92) SWINT(0x93) SWINT(0x94) SWINT(0x95) SWINT(0x96) SWINT(0x97)
286 SWINT(0x98) SWINT(0x99) SWINT(0x9A) SWINT(0x9B) SWINT(0x9C) SWINT(0x9D) SWINT(0x9E) SWINT(0x9F)
287 SWINT(0xA0) SWINT(0xA1) SWINT(0xA2) SWINT(0xA3) SWINT(0xA4) SWINT(0xA5) SWINT(0xA6) SWINT(0xA7)
288 SWINT(0xA8) SWINT(0xA9) SWINT(0xAA) SWINT(0xAB) SWINT(0xAC) SWINT(0xAD) SWINT(0xAE) SWINT(0xAF)
289 SWINT(0xB0) SWINT(0xB1) SWINT(0xB2) SWINT(0xB3) SWINT(0xB4) SWINT(0xB5) SWINT(0xB6) SWINT(0xB7)
290 SWINT(0xB8) SWINT(0xB9) SWINT(0xBA) SWINT(0xBB) SWINT(0xBC) SWINT(0xBD) SWINT(0xBE) SWINT(0xBF)
291 SWINT(0xC0) SWINT(0xC1) SWINT(0xC2) SWINT(0xC3) SWINT(0xC4) SWINT(0xC5) SWINT(0xC6) SWINT(0xC7)
292 SWINT(0xC8) SWINT(0xC9) SWINT(0xCA) SWINT(0xCB) SWINT(0xCC) SWINT(0xCD) SWINT(0xCE) SWINT(0xCF)
293 SWINT(0xD0) SWINT(0xD1) SWINT(0xD2) SWINT(0xD3) SWINT(0xD4) SWINT(0xD5) SWINT(0xD6) SWINT(0xD7)
294 SWINT(0xD8) SWINT(0xD9) SWINT(0xDA) SWINT(0xDB) SWINT(0xDC) SWINT(0xDD) SWINT(0xDE) SWINT(0xDF)
295 SWINT(0xE0) SWINT(0xE1) SWINT(0xE2) SWINT(0xE3) SWINT(0xE4) SWINT(0xE5) SWINT(0xE6) SWINT(0xE7)
296 SWINT(0xE8) SWINT(0xE9) SWINT(0xEA) SWINT(0xEB) SWINT(0xEC) SWINT(0xED) SWINT(0xEE) SWINT(0xEF)
297 SWINT(0xF0) SWINT(0xF1) SWINT(0xF2) SWINT(0xF3) SWINT(0xF4) SWINT(0xF5) SWINT(0xF6) SWINT(0xF7)
298 SWINT(0xF8) SWINT(0xF9) SWINT(0xFA) SWINT(0xFB) SWINT(0xFC) SWINT(0xFD) SWINT(0xFE) SWINT(0xFF)
300 /* not found */
301 KdPrint((__DRIVER_NAME " interrupt %02X not set up. Blame James.\n", intno));
302 KeBugCheckEx(('X' << 16)|('E' << 8)|('N'), 0x00000002, (ULONG)intno, 0x00000000, 0x00000000);
303 }
304 #else
305 VOID _sw_interrupt(UCHAR);
307 static __inline VOID
308 sw_interrupt(UCHAR intno)
309 {
310 _sw_interrupt(intno);
311 }
312 #endif
315 #include "hypercall.h"
317 #define XBT_NIL ((xenbus_transaction_t)0)
319 static __inline VOID
320 XenPci_FreeMem(PVOID Ptr)
321 {
322 ExFreePoolWithTag(Ptr, XENPCI_POOL_TAG);
323 }
325 NTSTATUS
326 hvm_get_stubs(PXENPCI_DEVICE_DATA xpdd);
327 NTSTATUS
328 hvm_free_stubs(PXENPCI_DEVICE_DATA xpdd);
330 NTSTATUS
331 XenPci_Power_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
332 NTSTATUS
333 XenPci_Dummy_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
334 NTSTATUS
335 XenPci_Pnp_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
336 NTSTATUS
337 XenPci_Irp_Create_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
338 NTSTATUS
339 XenPci_Irp_Close_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
340 NTSTATUS
341 XenPci_Irp_Read_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
342 NTSTATUS
343 XenPci_Irp_Cleanup_Fdo(PDEVICE_OBJECT device_object, PIRP irp);
345 NTSTATUS
346 XenPci_Power_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
347 //NTSTATUS
348 //XenPci_Dummy_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
349 NTSTATUS
350 XenPci_Pnp_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
351 NTSTATUS
352 XenPci_Irp_Create_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
353 NTSTATUS
354 XenPci_Irp_Close_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
355 NTSTATUS
356 XenPci_Irp_Read_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
357 NTSTATUS
358 XenPci_Irp_Cleanup_Pdo(PDEVICE_OBJECT device_object, PIRP irp);
360 NTSTATUS
361 XenPci_Resume(PDEVICE_OBJECT device_object);
363 char *
364 XenBus_Read(PVOID Context, xenbus_transaction_t xbt, const char *path, char **value);
365 char *
366 XenBus_Write(PVOID Context, xenbus_transaction_t xbt, const char *path, const char *value);
367 char *
368 XenBus_Printf(PVOID Context, xenbus_transaction_t xbt, const char *path, const char *fmt, ...);
369 char *
370 XenBus_StartTransaction(PVOID Context, xenbus_transaction_t *xbt);
371 char *
372 XenBus_EndTransaction(PVOID Context, xenbus_transaction_t t, int abort, int *retry);
373 char *
374 XenBus_List(PVOID Context, xenbus_transaction_t xbt, const char *prefix, char ***contents);
375 char *
376 XenBus_AddWatch(PVOID Context, xenbus_transaction_t xbt, const char *Path, PXENBUS_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext);
377 char *
378 XenBus_RemWatch(PVOID Context, xenbus_transaction_t xbt, const char *Path, PXENBUS_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext);
379 //VOID
380 //XenBus_ThreadProc(PVOID StartContext);
381 NTSTATUS
382 XenBus_Init(PXENPCI_DEVICE_DATA xpdd);
383 NTSTATUS
384 XenBus_Close(PXENPCI_DEVICE_DATA xpdd);
385 NTSTATUS
386 XenBus_Start(PXENPCI_DEVICE_DATA xpdd);
387 NTSTATUS
388 XenBus_Stop(PXENPCI_DEVICE_DATA xpdd);
389 VOID
390 XenBus_Resume(PXENPCI_DEVICE_DATA xpdd);
392 PHYSICAL_ADDRESS
393 XenPci_AllocMMIO(PXENPCI_DEVICE_DATA xpdd, ULONG len);
395 NTSTATUS
396 EvtChn_Init(PXENPCI_DEVICE_DATA xpdd);
397 VOID
398 EvtChn_Resume(PXENPCI_DEVICE_DATA xpdd);
399 NTSTATUS
400 EvtChn_Shutdown(PXENPCI_DEVICE_DATA xpdd);
402 NTSTATUS
403 EvtChn_Mask(PVOID Context, evtchn_port_t Port);
404 NTSTATUS
405 EvtChn_Unmask(PVOID Context, evtchn_port_t Port);
406 NTSTATUS
407 EvtChn_Bind(PVOID Context, evtchn_port_t Port, PKSERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext);
408 NTSTATUS
409 EvtChn_BindDpc(PVOID Context, evtchn_port_t Port, PKSERVICE_ROUTINE ServiceRoutine, PVOID ServiceContext);
410 NTSTATUS
411 EvtChn_BindIrq(PVOID Context, evtchn_port_t Port, ULONG vector);
412 NTSTATUS
413 EvtChn_Unbind(PVOID Context, evtchn_port_t Port);
414 NTSTATUS
415 EvtChn_Notify(PVOID Context, evtchn_port_t Port);
416 evtchn_port_t
417 EvtChn_AllocUnbound(PVOID Context, domid_t Domain);
419 VOID
420 GntTbl_Init(PXENPCI_DEVICE_DATA xpdd);
422 grant_ref_t
423 GntTbl_GrantAccess(PVOID Context, domid_t domid, uint32_t, int readonly, grant_ref_t ref);
424 BOOLEAN
425 GntTbl_EndAccess(PVOID Context, grant_ref_t ref, BOOLEAN keepref);
426 VOID
427 GntTbl_PutRef(PVOID Context, grant_ref_t ref);
428 grant_ref_t
429 GntTbl_GetRef(PVOID Context);
430 int
431 GntTbl_Map(PVOID Context, unsigned int start_idx, unsigned int end_idx);
432 #endif