win-pvdrivers

view xenpci/xenpci.h @ 307:6b85686a16c0

really merged with default now i think
author James Harper <james.harper@bendigoit.com.au>
date Wed Jun 11 20:27:30 2008 +1000 (2008-06-11)
parents b4f7d75fbe24 5a7bfc1827a7
children bb891f6d10e4
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 /* The total number of event channels or rings allowed per device... probably never more than 2 */
223 #define MAX_RESOURCES 4
225 typedef struct {
226 XENPCI_COMMON common;
227 PDEVICE_OBJECT bus_pdo;
228 PDEVICE_OBJECT bus_fdo;
229 BOOLEAN ReportedMissing;
230 char path[128];
231 char device[128];
232 ULONG index;
233 ULONG irq_vector;
234 KIRQL irq_level;
235 char backend_path[128];
236 PVOID xenbus_request;
237 KEVENT backend_state_event;
238 ULONG backend_state;
239 grant_ref_t grant_refs[MAX_RESOURCES];
240 PMDL mdls[MAX_RESOURCES];
241 evtchn_port_t event_channels[MAX_RESOURCES];
242 } XENPCI_PDO_DEVICE_DATA, *PXENPCI_PDO_DEVICE_DATA;
244 typedef struct
245 {
246 LIST_ENTRY entry;
247 int state;
248 PXENPCI_PDO_DEVICE_DATA context;
249 } XEN_CHILD, *PXEN_CHILD;
251 #define SWINT(x) case x: __asm { int x } break;
253 #if defined(_X86_)
254 static __inline VOID
255 sw_interrupt(UCHAR intno)
256 {
257 //KdPrint((__DRIVER_NAME " Calling interrupt %02X\n", intno));
258 switch (intno)
259 {
260 SWINT(0x10) SWINT(0x11) SWINT(0x12) SWINT(0x13) SWINT(0x14) SWINT(0x15) SWINT(0x16) SWINT(0x17)
261 SWINT(0x18) SWINT(0x19) SWINT(0x1A) SWINT(0x1B) SWINT(0x1C) SWINT(0x1D) SWINT(0x1E) SWINT(0x1F)
262 SWINT(0x20) SWINT(0x21) SWINT(0x22) SWINT(0x23) SWINT(0x24) SWINT(0x25) SWINT(0x26) SWINT(0x27)
263 SWINT(0x28) SWINT(0x29) SWINT(0x2A) SWINT(0x2B) SWINT(0x2C) SWINT(0x2D) SWINT(0x2E) SWINT(0x2F)
264 SWINT(0x30) SWINT(0x31) SWINT(0x32) SWINT(0x33) SWINT(0x34) SWINT(0x35) SWINT(0x36) SWINT(0x37)
265 SWINT(0x38) SWINT(0x39) SWINT(0x3A) SWINT(0x3B) SWINT(0x3C) SWINT(0x3D) SWINT(0x3E) SWINT(0x3F)
266 SWINT(0x40) SWINT(0x41) SWINT(0x42) SWINT(0x43) SWINT(0x44) SWINT(0x45) SWINT(0x46) SWINT(0x47)
267 SWINT(0x48) SWINT(0x49) SWINT(0x4A) SWINT(0x4B) SWINT(0x4C) SWINT(0x4D) SWINT(0x4E) SWINT(0x4F)
268 SWINT(0x50) SWINT(0x51) SWINT(0x52) SWINT(0x53) SWINT(0x54) SWINT(0x55) SWINT(0x56) SWINT(0x57)
269 SWINT(0x58) SWINT(0x59) SWINT(0x5A) SWINT(0x5B) SWINT(0x5C) SWINT(0x5D) SWINT(0x5E) SWINT(0x5F)
270 SWINT(0x60) SWINT(0x61) SWINT(0x62) SWINT(0x63) SWINT(0x64) SWINT(0x65) SWINT(0x66) SWINT(0x67)
271 SWINT(0x68) SWINT(0x69) SWINT(0x6A) SWINT(0x6B) SWINT(0x6C) SWINT(0x6D) SWINT(0x6E) SWINT(0x6F)
272 SWINT(0x70) SWINT(0x71) SWINT(0x72) SWINT(0x73) SWINT(0x74) SWINT(0x75) SWINT(0x76) SWINT(0x77)
273 SWINT(0x78) SWINT(0x79) SWINT(0x7A) SWINT(0x7B) SWINT(0x7C) SWINT(0x7D) SWINT(0x7E) SWINT(0x7F)
274 SWINT(0x80) SWINT(0x81) SWINT(0x82) SWINT(0x83) SWINT(0x84) SWINT(0x85) SWINT(0x86) SWINT(0x87)
275 SWINT(0x88) SWINT(0x89) SWINT(0x8A) SWINT(0x8B) SWINT(0x8C) SWINT(0x8D) SWINT(0x8E) SWINT(0x8F)
276 SWINT(0x90) SWINT(0x91) SWINT(0x92) SWINT(0x93) SWINT(0x94) SWINT(0x95) SWINT(0x96) SWINT(0x97)
277 SWINT(0x98) SWINT(0x99) SWINT(0x9A) SWINT(0x9B) SWINT(0x9C) SWINT(0x9D) SWINT(0x9E) SWINT(0x9F)
278 SWINT(0xA0) SWINT(0xA1) SWINT(0xA2) SWINT(0xA3) SWINT(0xA4) SWINT(0xA5) SWINT(0xA6) SWINT(0xA7)
279 SWINT(0xA8) SWINT(0xA9) SWINT(0xAA) SWINT(0xAB) SWINT(0xAC) SWINT(0xAD) SWINT(0xAE) SWINT(0xAF)
280 SWINT(0xB0) SWINT(0xB1) SWINT(0xB2) SWINT(0xB3) SWINT(0xB4) SWINT(0xB5) SWINT(0xB6) SWINT(0xB7)
281 SWINT(0xB8) SWINT(0xB9) SWINT(0xBA) SWINT(0xBB) SWINT(0xBC) SWINT(0xBD) SWINT(0xBE) SWINT(0xBF)
282 SWINT(0xC0) SWINT(0xC1) SWINT(0xC2) SWINT(0xC3) SWINT(0xC4) SWINT(0xC5) SWINT(0xC6) SWINT(0xC7)
283 SWINT(0xC8) SWINT(0xC9) SWINT(0xCA) SWINT(0xCB) SWINT(0xCC) SWINT(0xCD) SWINT(0xCE) SWINT(0xCF)
284 SWINT(0xD0) SWINT(0xD1) SWINT(0xD2) SWINT(0xD3) SWINT(0xD4) SWINT(0xD5) SWINT(0xD6) SWINT(0xD7)
285 SWINT(0xD8) SWINT(0xD9) SWINT(0xDA) SWINT(0xDB) SWINT(0xDC) SWINT(0xDD) SWINT(0xDE) SWINT(0xDF)
286 SWINT(0xE0) SWINT(0xE1) SWINT(0xE2) SWINT(0xE3) SWINT(0xE4) SWINT(0xE5) SWINT(0xE6) SWINT(0xE7)
287 SWINT(0xE8) SWINT(0xE9) SWINT(0xEA) SWINT(0xEB) SWINT(0xEC) SWINT(0xED) SWINT(0xEE) SWINT(0xEF)
288 SWINT(0xF0) SWINT(0xF1) SWINT(0xF2) SWINT(0xF3) SWINT(0xF4) SWINT(0xF5) SWINT(0xF6) SWINT(0xF7)
289 SWINT(0xF8) SWINT(0xF9) SWINT(0xFA) SWINT(0xFB) SWINT(0xFC) SWINT(0xFD) SWINT(0xFE) SWINT(0xFF)
291 default:
292 KdPrint((__DRIVER_NAME " interrupt %02X not set up. Blame James.\n", intno));
293 KeBugCheckEx(('X' << 16)|('E' << 8)|('N'), 0x00000002, (ULONG)intno, 0x00000000, 0x00000000);
294 break;
295 }
296 }
297 #else
298 VOID _sw_interrupt(UCHAR);
300 static __inline VOID
301 sw_interrupt(UCHAR intno)
302 {
303 _sw_interrupt(intno);
304 }
305 #endif
308 #include "hypercall.h"
310 typedef unsigned long xenbus_transaction_t;
311 typedef uint32_t XENSTORE_RING_IDX;
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