win-pvdrivers

view xenpci/xenpci.h @ 340:2be08f708250

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