win-pvdrivers

view xenpci/xenpci.h @ 1022:cd72cd0e1c19

hooking debug doesn't survive hibernate under win8. Remove it.
Remove initial balloon down - doesn't work under xen 4.2 without xenbus being loaded
author James Harper <james.harper@bendigoit.com.au>
date Tue Feb 19 15:11:49 2013 +1100 (2013-02-19)
parents 9e076343bb8e
children 471c94d04d8a
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 #include <wdf.h>
29 #include <initguid.h>
30 #include <wdmguid.h>
31 #include <errno.h>
32 #define NTSTRSAFE_LIB
33 #include <ntstrsafe.h>
35 #include <liblfds.h>
37 #define __DRIVER_NAME "XenPCI"
39 #include <xen_windows.h>
40 #include <memory.h>
41 #include <grant_table.h>
42 #include <event_channel.h>
43 #include <hvm/params.h>
44 #include <hvm/hvm_op.h>
45 #include <sched.h>
46 #include <io/xenbus.h>
47 #include <io/xs_wire.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 32
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
66 //#define EVT_ACTION_TYPE_SUSPEND 4
67 #define EVT_ACTION_TYPE_NEW 9 /* setup of event is in progress */
69 #define EVT_ACTION_FLAGS_DEFAULT 0 /* no special flags */
70 #define EVT_ACTION_FLAGS_NO_SUSPEND 1 /* should not be fired on EVT_ACTION_TYPE_SUSPEND event */
72 #define XEN_PV_PRODUCT_NUMBER 0x0002
73 #define XEN_PV_PRODUCT_BUILD 0x00000001
75 #define BALLOON_UNITS_KB (1 * 1024) /* 1MB */
76 #define BALLOON_UNIT_PAGES ((BALLOON_UNITS_KB << 10) >> PAGE_SHIFT)
78 extern ULONG qemu_protocol_version;
79 extern USHORT xen_version_major;
80 extern USHORT xen_version_minor;
82 typedef struct _ev_action_t {
83 PVOID xpdd;
84 //evtchn_port_t port;
85 PXN_EVENT_CALLBACK ServiceRoutine;
86 PVOID ServiceContext;
87 CHAR description[128];
88 ULONG type; /* EVT_ACTION_TYPE_* */
89 ULONG flags; /* EVT_ACTION_FLAGS_* */
90 KDPC Dpc;
91 ULONG vector;
92 ULONG count;
93 } ev_action_t;
95 typedef struct _XENBUS_WATCH_RING
96 {
97 char Path[128];
98 char Token[10];
99 } XENBUS_WATCH_RING;
101 typedef struct xsd_sockmsg xsd_sockmsg_t;
103 typedef struct _XENBUS_WATCH_ENTRY {
104 char Path[128];
105 PXN_WATCH_CALLBACK ServiceRoutine;
106 PVOID ServiceContext;
107 int Count;
108 int Active;
109 } XENBUS_WATCH_ENTRY, *PXENBUS_WATCH_ENTRY;
111 /* number of events is 1024 on 32 bits and 4096 on 64 bits */
112 #define NR_EVENTS (sizeof(xen_ulong_t) * 8 * sizeof(xen_ulong_t) * 8)
113 #define WATCH_RING_SIZE 128
114 #define NR_XB_REQS 32
115 #define MAX_WATCH_ENTRIES 128
117 #define CHILD_STATE_EMPTY 0
118 #define CHILD_STATE_DELETED 1
119 #define CHILD_STATE_ADDED 2
121 #define SUSPEND_STATE_NONE 0 /* no suspend in progress */
122 #define SUSPEND_STATE_SCHEDULED 1 /* suspend scheduled */
123 #define SUSPEND_STATE_HIGH_IRQL 2 /* all processors are at high IRQL and spinning */
124 #define SUSPEND_STATE_RESUMING 3 /* we are the other side of the suspend and things are starting to get back to normal */
126 /* we take some grant refs out and put them aside so that we dont get corrupted by hibernate */
127 #define HIBER_GREF_COUNT 128
129 typedef struct {
130 ULONG generation;
131 ULONG tag;
132 } grant_tag_t;
134 typedef struct {
135 WDFDEVICE wdf_device;
137 BOOLEAN tpr_patched;
139 WDFINTERRUPT interrupt;
140 ULONG irq_number;
141 ULONG irq_vector;
142 KIRQL irq_level;
143 KINTERRUPT_MODE irq_mode;
144 KAFFINITY irq_affinity;
146 PHYSICAL_ADDRESS shared_info_area_unmapped;
147 shared_info_t *shared_info_area;
148 xen_ulong_t evtchn_pending_pvt[MAX_VIRT_CPUS][sizeof(xen_ulong_t) * 8];
149 xen_ulong_t evtchn_pending_suspend[sizeof(xen_ulong_t) * 8];
150 //evtchn_port_t pdo_event_channel;
151 //KEVENT pdo_suspend_event;
152 BOOLEAN interrupts_masked;
154 PHYSICAL_ADDRESS platform_mmio_addr;
155 ULONG platform_mmio_orig_len;
156 ULONG platform_mmio_len;
157 ULONG platform_mmio_alloc;
158 USHORT platform_mmio_flags;
160 ULONG platform_ioport_addr;
161 ULONG platform_ioport_len;
163 char *hypercall_stubs;
165 evtchn_port_t xenbus_event;
167 /* grant related */
168 struct stack_state *gnttbl_ss;
169 struct stack_state *gnttbl_ss_copy;
170 grant_ref_t hiber_grefs[HIBER_GREF_COUNT];
171 PMDL gnttbl_mdl;
172 grant_entry_t *gnttbl_table;
173 grant_entry_t *gnttbl_table_copy;
174 #if DBG
175 ULONG gnttbl_generation; /* incremented once per save or hibernate */
176 grant_tag_t *gnttbl_tag;
177 grant_tag_t *gnttbl_tag_copy;
178 #endif
179 ULONG grant_frames;
181 ev_action_t ev_actions[NR_EVENTS];
182 // unsigned long bound_ports[NR_EVENTS/(8*sizeof(unsigned long))];
184 BOOLEAN xb_state;
186 struct xenstore_domain_interface *xen_store_interface;
188 PKTHREAD balloon_thread;
189 KEVENT balloon_event;
190 BOOLEAN balloon_shutdown;
191 //ULONG initial_memory_kb;
192 ULONG current_memory_kb;
193 ULONG target_memory_kb;
195 /* xenbus related */
196 XENBUS_WATCH_ENTRY XenBus_WatchEntries[MAX_WATCH_ENTRIES];
197 KSPIN_LOCK xb_ring_spinlock;
198 FAST_MUTEX xb_watch_mutex;
199 FAST_MUTEX xb_request_mutex;
200 KEVENT xb_request_complete_event;
201 struct xsd_sockmsg *xb_reply;
202 struct xsd_sockmsg *xb_msg;
203 ULONG xb_msg_offset;
205 WDFCHILDLIST child_list;
207 FAST_MUTEX suspend_mutex;
209 ULONG suspend_evtchn;
210 int suspend_state;
212 UNICODE_STRING legacy_interface_name;
213 UNICODE_STRING interface_name;
214 BOOLEAN interface_open;
216 BOOLEAN removable;
218 BOOLEAN hibernated;
220 WDFQUEUE io_queue;
222 //WDFCOLLECTION veto_devices;
223 LIST_ENTRY veto_list;
225 #if 0
226 KSPIN_LOCK mmio_freelist_lock;
227 PPFN_NUMBER mmio_freelist_base;
228 ULONG mmio_freelist_free;
229 #endif
231 } XENPCI_DEVICE_DATA, *PXENPCI_DEVICE_DATA;
233 WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(XENPCI_DEVICE_DATA, GetXpdd)
235 typedef struct {
236 UCHAR front_target;
237 UCHAR back_expected;
238 UCHAR wait; /* units = 100ms */
239 } XENPCI_STATE_MAP_ELEMENT, *PXENPCI_STATE_MAP_ELEMENT;
241 typedef struct {
242 WDFDEVICE wdf_device;
243 WDFDEVICE wdf_device_bus_fdo;
244 PXENPCI_DEVICE_DATA xpdd;
245 BOOLEAN reported_missing;
246 char path[128];
247 char device[128];
248 ULONG index;
249 ULONG irq_number;
250 ULONG irq_vector;
251 KIRQL irq_level;
252 char backend_path[128];
253 domid_t backend_id;
254 KEVENT backend_state_event;
255 ULONG backend_state;
256 PXN_DEVICE_CALLBACK device_callback;
257 PVOID device_callback_context;
258 FAST_MUTEX backend_state_mutex;
259 ULONG frontend_state;
260 BOOLEAN restart_on_resume;
261 BOOLEAN backend_initiated_remove;
262 BOOLEAN do_not_enumerate;
264 XENPCI_STATE_MAP_ELEMENT xb_pre_connect_map[5];
265 XENPCI_STATE_MAP_ELEMENT xb_post_connect_map[5];
266 XENPCI_STATE_MAP_ELEMENT xb_shutdown_map[5];
268 BOOLEAN hiber_usage_kludge;
269 } XENPCI_PDO_DEVICE_DATA, *PXENPCI_PDO_DEVICE_DATA;
271 WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(XENPCI_PDO_DEVICE_DATA, GetXppdd)
273 typedef struct {
274 WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER header;
275 CHAR path[128];
276 CHAR device[128];
277 ULONG index;
278 } XENPCI_PDO_IDENTIFICATION_DESCRIPTION, *PXENPCI_PDO_IDENTIFICATION_DESCRIPTION;
280 #define XEN_INTERFACE_VERSION 1
282 //#define DEVICE_INTERFACE_TYPE_LEGACY 0
283 #define DEVICE_INTERFACE_TYPE_XENBUS 1
284 #define DEVICE_INTERFACE_TYPE_EVTCHN 2
285 #define DEVICE_INTERFACE_TYPE_GNTDEV 3
287 typedef struct {
288 ULONG len;
289 WDFQUEUE io_queue;
290 union {
291 struct xsd_sockmsg msg;
292 UCHAR buffer[PAGE_SIZE];
293 } u;
294 LIST_ENTRY read_list_head;
295 LIST_ENTRY watch_list_head;
296 } XENBUS_INTERFACE_DATA, *PXENBUS_INTERFACE_DATA;
298 typedef struct {
299 ULONG dummy; /* fill this in with whatever is required */
300 } EVTCHN_INTERFACE_DATA, *PEVTCHN_INTERFACE_DATA;
302 typedef struct {
303 ULONG dummy; /* fill this in with whatever is required */
304 } GNTDEV_INTERFACE_DATA, *PGNTDEV_INTERFACE_DATA;
306 typedef struct {
307 ULONG type;
308 KSPIN_LOCK lock;
309 WDFQUEUE io_queue;
310 EVT_WDF_FILE_CLEANUP *EvtFileCleanup;
311 EVT_WDF_FILE_CLOSE *EvtFileClose;
312 union {
313 XENBUS_INTERFACE_DATA xenbus;
314 EVTCHN_INTERFACE_DATA evtchn;
315 GNTDEV_INTERFACE_DATA gntdev;
316 };
317 } XENPCI_DEVICE_INTERFACE_DATA, *PXENPCI_DEVICE_INTERFACE_DATA;
319 WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(XENPCI_DEVICE_INTERFACE_DATA, GetXpdid)
321 static __inline VOID
322 XenPci_FreeMem(PVOID Ptr) {
323 ExFreePoolWithTag(Ptr, XENPCI_POOL_TAG);
324 }
326 NTSTATUS XenBus_DeviceFileInit(WDFDEVICE device, PWDF_IO_QUEUE_CONFIG queue_config, WDFFILEOBJECT file_object);
328 EVT_WDF_DEVICE_FILE_CREATE XenPci_EvtDeviceFileCreate;
329 EVT_WDF_FILE_CLOSE XenPci_EvtFileClose;
330 EVT_WDF_FILE_CLEANUP XenPci_EvtFileCleanup;
331 EVT_WDF_IO_QUEUE_IO_DEFAULT XenPci_EvtIoDefault;
333 #define HYPERVISOR_memory_op(xpdd, cmd, arg) _HYPERVISOR_memory_op(xpdd->hypercall_stubs, cmd, arg)
334 #define HYPERVISOR_xen_version(xpdd, cmd, arg) _HYPERVISOR_xen_version(xpdd->hypercall_stubs, cmd, arg)
335 #define HYPERVISOR_grant_table_op(xpdd, cmd, uop, count) _HYPERVISOR_grant_table_op(xpdd->hypercall_stubs, cmd, uop, count)
336 #define HYPERVISOR_hvm_op(xpdd, op, arg) _HYPERVISOR_hvm_op(xpdd->hypercall_stubs, op, arg)
337 #define HYPERVISOR_event_channel_op(xpdd, cmd, op) _HYPERVISOR_event_channel_op(xpdd->hypercall_stubs, cmd, op)
338 #define HYPERVISOR_sched_op(xpdd, cmd, arg) _HYPERVISOR_sched_op(xpdd->hypercall_stubs, cmd, arg)
339 #define HYPERVISOR_shutdown(xpdd, reason) _HYPERVISOR_shutdown(xpdd->hypercall_stubs, reason)
341 #define hvm_get_parameter(xvdd, hvm_param) _hvm_get_parameter(xvdd->hypercall_stubs, hvm_param);
342 #define hvm_set_parameter(xvdd, hvm_param, value) _hvm_set_parameter(xvdd->hypercall_stubs, hvm_param, value);
343 #define hvm_shutdown(xvdd, reason) _hvm_shutdown(xvdd->hypercall_stubs, reason);
344 #define HYPERVISOR_yield(xvdd) _HYPERVISOR_yield(xvdd->hypercall_stubs);
346 #include "hypercall.h"
348 #define XBT_NIL ((xenbus_transaction_t)0)
350 PVOID hvm_get_hypercall_stubs();
351 VOID hvm_free_hypercall_stubs(PVOID hypercall_stubs);
353 EVT_WDF_DEVICE_PREPARE_HARDWARE XenPci_EvtDevicePrepareHardware;
354 EVT_WDF_DEVICE_RELEASE_HARDWARE XenPci_EvtDeviceReleaseHardware;
355 EVT_WDF_DEVICE_D0_ENTRY XenPci_EvtDeviceD0Entry;
356 EVT_WDF_DEVICE_D0_ENTRY_POST_INTERRUPTS_ENABLED XenPci_EvtDeviceD0EntryPostInterruptsEnabled;
357 EVT_WDF_DEVICE_D0_EXIT XenPci_EvtDeviceD0Exit;
358 EVT_WDF_DEVICE_D0_EXIT_PRE_INTERRUPTS_DISABLED XenPci_EvtDeviceD0ExitPreInterruptsDisabled;
359 EVT_WDF_DEVICE_QUERY_REMOVE XenPci_EvtDeviceQueryRemove;
360 EVT_WDF_CHILD_LIST_CREATE_DEVICE XenPci_EvtChildListCreateDevice;
361 EVT_WDF_CHILD_LIST_SCAN_FOR_CHILDREN XenPci_EvtChildListScanForChildren;
363 VOID XenPci_HideQemuDevices();
364 extern WDFCOLLECTION qemu_hide_devices;
365 extern USHORT qemu_hide_flags_value;
367 VOID XenPci_BackendStateCallback(char *path, PVOID context);
368 NTSTATUS XenPci_SuspendPdo(WDFDEVICE device);
369 NTSTATUS XenPci_ResumePdo(WDFDEVICE device);
372 VOID XenPci_DumpPdoConfig(PDEVICE_OBJECT device_object);
374 typedef VOID (*PXENPCI_HIGHSYNC_FUNCTION)(PVOID context);
376 VOID XenPci_HighSync(PXENPCI_HIGHSYNC_FUNCTION function0, PXENPCI_HIGHSYNC_FUNCTION functionN, PVOID context);
378 VOID XenPci_PatchKernel(PXENPCI_DEVICE_DATA xpdd, PVOID base, ULONG length);
380 //NTSTATUS XenPci_HookDbgPrint();
381 //NTSTATUS XenPci_ReHookDbgPrint();
382 //NTSTATUS XenPci_UnHookDbgPrint();
383 //VOID XenPci_DumpModeHookDebugPrint();
384 #include <stdlib.h>
386 NTSTATUS
387 XenPci_DebugPrintV(PCHAR format, va_list args);
388 NTSTATUS
389 XenPci_DebugPrint(PCHAR format, ...);
391 struct xsd_sockmsg *XenBus_Raw(PXENPCI_DEVICE_DATA xpdd, struct xsd_sockmsg *msg);
392 char *XenBus_Read(PVOID Context, xenbus_transaction_t xbt, char *path, char **value);
393 char *XenBus_Write(PVOID Context, xenbus_transaction_t xbt, char *path, char *value);
394 char *XenBus_Printf(PVOID Context, xenbus_transaction_t xbt, char *path, char *fmt, ...);
395 char *XenBus_StartTransaction(PVOID Context, xenbus_transaction_t *xbt);
396 char *XenBus_EndTransaction(PVOID Context, xenbus_transaction_t t, int abort, int *retry);
397 char *XenBus_List(PVOID Context, xenbus_transaction_t xbt, char *prefix, char ***contents);
398 char *XenBus_AddWatch(PVOID Context, xenbus_transaction_t xbt, char *Path, PXN_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext);
399 char *XenBus_RemWatch(PVOID Context, xenbus_transaction_t xbt, char *Path, PXN_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext);
400 NTSTATUS XenBus_Init(PXENPCI_DEVICE_DATA xpdd);
401 NTSTATUS XenBus_Halt(PXENPCI_DEVICE_DATA xpdd);
402 NTSTATUS XenBus_Suspend(PXENPCI_DEVICE_DATA xpdd);
403 NTSTATUS XenBus_Resume(PXENPCI_DEVICE_DATA xpdd);
405 PHYSICAL_ADDRESS
406 XenPci_AllocMMIO(PXENPCI_DEVICE_DATA xpdd, ULONG len);
408 EVT_WDF_INTERRUPT_ISR EvtChn_EvtInterruptIsr;
409 EVT_WDF_INTERRUPT_ENABLE EvtChn_EvtInterruptEnable;
410 EVT_WDF_INTERRUPT_DISABLE EvtChn_EvtInterruptDisable;
412 NTSTATUS EvtChn_Init(PXENPCI_DEVICE_DATA xpdd);
413 NTSTATUS EvtChn_Suspend(PXENPCI_DEVICE_DATA xpdd);
414 NTSTATUS EvtChn_Resume(PXENPCI_DEVICE_DATA xpdd);
416 NTSTATUS EvtChn_Mask(PVOID context, evtchn_port_t port);
417 NTSTATUS EvtChn_Unmask(PVOID context, evtchn_port_t port);
418 NTSTATUS EvtChn_Bind(PVOID context, evtchn_port_t port, PXN_EVENT_CALLBACK ServiceRoutine, PVOID ServiceContext, ULONG flags);
419 NTSTATUS EvtChn_BindDpc(PVOID context, evtchn_port_t port, PXN_EVENT_CALLBACK ServiceRoutine, PVOID ServiceContext, ULONG flags);
420 NTSTATUS EvtChn_Unbind(PVOID context, evtchn_port_t port);
421 NTSTATUS EvtChn_Notify(PVOID context, evtchn_port_t port);
422 VOID EvtChn_Close(PVOID context, evtchn_port_t port);
423 evtchn_port_t EvtChn_AllocUnbound(PVOID context, domid_t domain);
424 evtchn_port_t EvtChn_GetEventPort(PVOID context, evtchn_port_t port);
426 VOID GntTbl_Init(PXENPCI_DEVICE_DATA xpdd);
427 VOID GntTbl_Suspend(PXENPCI_DEVICE_DATA xpdd);
428 VOID GntTbl_Resume(PXENPCI_DEVICE_DATA xpdd);
429 grant_ref_t GntTbl_GrantAccess(PVOID Context, domid_t domid, uint32_t, int readonly, grant_ref_t ref, ULONG tag);
430 BOOLEAN GntTbl_EndAccess(PVOID Context, grant_ref_t ref, BOOLEAN keepref, ULONG tag);
431 VOID GntTbl_PutRef(PVOID Context, grant_ref_t ref, ULONG tag);
432 grant_ref_t GntTbl_GetRef(PVOID Context, ULONG tag);
434 #endif