win-pvdrivers

view xenpci/xenpci.h @ 1099:27bd2a5a4704

License change from GPL to BSD
author James Harper <james.harper@bendigoit.com.au>
date Thu Mar 13 13:38:31 2014 +1100 (2014-03-13)
parents 471c94d04d8a
children
line source
1 /*
2 PV Drivers for Windows Xen HVM Domains
4 Copyright (c) 2014, James Harper
5 All rights reserved.
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9 * Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11 * Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14 * Neither the name of James Harper nor the
15 names of its contributors may be used to endorse or promote products
16 derived from this software without specific prior written permission.
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 DISCLAIMED. IN NO EVENT SHALL JAMES HARPER BE LIABLE FOR ANY
22 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
30 #if !defined(_XENPCI_H_)
31 #define _XENPCI_H_
33 #define __attribute__(arg) /* empty */
34 #define EISCONN 127
36 #include <ntddk.h>
38 #include <wdf.h>
39 #include <initguid.h>
40 #include <wdmguid.h>
41 #include <errno.h>
42 #define NTSTRSAFE_LIB
43 #include <ntstrsafe.h>
45 #include <liblfds.h>
47 #define __DRIVER_NAME "XenPCI"
49 #include <xen_windows.h>
50 #include <memory.h>
51 #include <grant_table.h>
52 #include <event_channel.h>
53 #include <hvm/params.h>
54 #include <hvm/hvm_op.h>
55 #include <sched.h>
56 #include <io/xenbus.h>
57 #include <io/xs_wire.h>
59 #include <xen_public.h>
61 //{C828ABE9-14CA-4445-BAA6-82C2376C6518}
62 DEFINE_GUID( GUID_XENPCI_DEVCLASS, 0xC828ABE9, 0x14CA, 0x4445, 0xBA, 0xA6, 0x82, 0xC2, 0x37, 0x6C, 0x65, 0x18);
64 #define XENPCI_POOL_TAG (ULONG) 'XenP'
66 #define NR_RESERVED_ENTRIES 8
67 #define NR_GRANT_FRAMES 32
68 #define NR_GRANT_ENTRIES (NR_GRANT_FRAMES * PAGE_SIZE / sizeof(grant_entry_t))
70 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
72 #define EVT_ACTION_TYPE_EMPTY 0
73 #define EVT_ACTION_TYPE_NORMAL 1
74 #define EVT_ACTION_TYPE_DPC 2
75 //#define EVT_ACTION_TYPE_IRQ 3
76 //#define EVT_ACTION_TYPE_SUSPEND 4
77 #define EVT_ACTION_TYPE_NEW 9 /* setup of event is in progress */
79 #define EVT_ACTION_FLAGS_DEFAULT 0 /* no special flags */
80 #define EVT_ACTION_FLAGS_NO_SUSPEND 1 /* should not be fired on EVT_ACTION_TYPE_SUSPEND event */
82 #define XEN_PV_PRODUCT_NUMBER 0x0002
83 #define XEN_PV_PRODUCT_BUILD 0x00000001
85 #define BALLOON_UNITS_KB (1 * 1024) /* 1MB */
86 #define BALLOON_UNIT_PAGES ((BALLOON_UNITS_KB << 10) >> PAGE_SHIFT)
88 extern PVOID hypercall_stubs;
89 extern ULONG qemu_protocol_version;
90 extern USHORT xen_version_major;
91 extern USHORT xen_version_minor;
93 typedef struct _ev_action_t {
94 PVOID xpdd;
95 //evtchn_port_t port;
96 PXN_EVENT_CALLBACK ServiceRoutine;
97 PVOID ServiceContext;
98 CHAR description[128];
99 ULONG type; /* EVT_ACTION_TYPE_* */
100 ULONG flags; /* EVT_ACTION_FLAGS_* */
101 KDPC Dpc;
102 ULONG vector;
103 ULONG count;
104 } ev_action_t;
106 typedef struct _XENBUS_WATCH_RING
107 {
108 char Path[128];
109 char Token[10];
110 } XENBUS_WATCH_RING;
112 typedef struct xsd_sockmsg xsd_sockmsg_t;
114 typedef struct _XENBUS_WATCH_ENTRY {
115 char Path[128];
116 PXN_WATCH_CALLBACK ServiceRoutine;
117 PVOID ServiceContext;
118 int Count;
119 int Active;
120 } XENBUS_WATCH_ENTRY, *PXENBUS_WATCH_ENTRY;
122 /* number of events is 1024 on 32 bits and 4096 on 64 bits */
123 #define NR_EVENTS (sizeof(xen_ulong_t) * 8 * sizeof(xen_ulong_t) * 8)
124 #define WATCH_RING_SIZE 128
125 #define NR_XB_REQS 32
126 #define MAX_WATCH_ENTRIES 128
128 #define CHILD_STATE_EMPTY 0
129 #define CHILD_STATE_DELETED 1
130 #define CHILD_STATE_ADDED 2
132 #define SUSPEND_STATE_NONE 0 /* no suspend in progress */
133 #define SUSPEND_STATE_SCHEDULED 1 /* suspend scheduled */
134 #define SUSPEND_STATE_HIGH_IRQL 2 /* all processors are at high IRQL and spinning */
135 #define SUSPEND_STATE_RESUMING 3 /* we are the other side of the suspend and things are starting to get back to normal */
137 /* we take some grant refs out and put them aside so that we dont get corrupted by hibernate */
138 #define HIBER_GREF_COUNT 128
140 typedef struct {
141 ULONG generation;
142 ULONG tag;
143 } grant_tag_t;
145 typedef struct {
146 WDFDEVICE wdf_device;
148 BOOLEAN tpr_patched;
150 WDFINTERRUPT interrupt;
151 ULONG irq_number;
152 ULONG irq_vector;
153 KIRQL irq_level;
154 KINTERRUPT_MODE irq_mode;
155 KAFFINITY irq_affinity;
157 PHYSICAL_ADDRESS shared_info_area_unmapped;
158 shared_info_t *shared_info_area;
159 xen_ulong_t evtchn_pending_pvt[MAX_VIRT_CPUS][sizeof(xen_ulong_t) * 8];
160 xen_ulong_t evtchn_pending_suspend[sizeof(xen_ulong_t) * 8];
161 //evtchn_port_t pdo_event_channel;
162 //KEVENT pdo_suspend_event;
163 BOOLEAN interrupts_masked;
165 PHYSICAL_ADDRESS platform_mmio_addr;
166 ULONG platform_mmio_orig_len;
167 ULONG platform_mmio_len;
168 ULONG platform_mmio_alloc;
169 USHORT platform_mmio_flags;
171 ULONG platform_ioport_addr;
172 ULONG platform_ioport_len;
174 evtchn_port_t xenbus_event;
176 /* grant related */
177 struct stack_state *gnttbl_ss;
178 struct stack_state *gnttbl_ss_copy;
179 grant_ref_t hiber_grefs[HIBER_GREF_COUNT];
180 PMDL gnttbl_mdl;
181 grant_entry_t *gnttbl_table;
182 grant_entry_t *gnttbl_table_copy;
183 #if DBG
184 ULONG gnttbl_generation; /* incremented once per save or hibernate */
185 grant_tag_t *gnttbl_tag;
186 grant_tag_t *gnttbl_tag_copy;
187 #endif
188 ULONG grant_frames;
190 ev_action_t ev_actions[NR_EVENTS];
191 // unsigned long bound_ports[NR_EVENTS/(8*sizeof(unsigned long))];
193 BOOLEAN xb_state;
195 struct xenstore_domain_interface *xen_store_interface;
197 PKTHREAD balloon_thread;
198 KEVENT balloon_event;
199 BOOLEAN balloon_shutdown;
200 //ULONG initial_memory_kb;
201 ULONG current_memory_kb;
202 ULONG target_memory_kb;
204 /* xenbus related */
205 XENBUS_WATCH_ENTRY XenBus_WatchEntries[MAX_WATCH_ENTRIES];
206 KSPIN_LOCK xb_ring_spinlock;
207 FAST_MUTEX xb_watch_mutex;
208 FAST_MUTEX xb_request_mutex;
209 KEVENT xb_request_complete_event;
210 struct xsd_sockmsg *xb_reply;
211 struct xsd_sockmsg *xb_msg;
212 ULONG xb_msg_offset;
214 WDFCHILDLIST child_list;
216 FAST_MUTEX suspend_mutex;
218 ULONG suspend_evtchn;
219 int suspend_state;
221 UNICODE_STRING legacy_interface_name;
222 UNICODE_STRING interface_name;
223 BOOLEAN interface_open;
225 BOOLEAN removable;
227 BOOLEAN hibernated;
229 WDFQUEUE io_queue;
231 //WDFCOLLECTION veto_devices;
232 LIST_ENTRY veto_list;
234 #if 0
235 KSPIN_LOCK mmio_freelist_lock;
236 PPFN_NUMBER mmio_freelist_base;
237 ULONG mmio_freelist_free;
238 #endif
240 } XENPCI_DEVICE_DATA, *PXENPCI_DEVICE_DATA;
242 WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(XENPCI_DEVICE_DATA, GetXpdd)
244 typedef struct {
245 UCHAR front_target;
246 UCHAR back_expected;
247 UCHAR wait; /* units = 100ms */
248 } XENPCI_STATE_MAP_ELEMENT, *PXENPCI_STATE_MAP_ELEMENT;
250 typedef struct {
251 WDFDEVICE wdf_device;
252 WDFDEVICE wdf_device_bus_fdo;
253 PXENPCI_DEVICE_DATA xpdd;
254 BOOLEAN reported_missing;
255 char path[128];
256 char device[128];
257 ULONG index;
258 ULONG irq_number;
259 ULONG irq_vector;
260 KIRQL irq_level;
261 char backend_path[128];
262 domid_t backend_id;
263 KEVENT backend_state_event;
264 ULONG backend_state;
265 PXN_DEVICE_CALLBACK device_callback;
266 PVOID device_callback_context;
267 FAST_MUTEX backend_state_mutex;
268 ULONG frontend_state;
269 BOOLEAN restart_on_resume;
270 BOOLEAN backend_initiated_remove;
271 BOOLEAN do_not_enumerate;
273 XENPCI_STATE_MAP_ELEMENT xb_pre_connect_map[5];
274 XENPCI_STATE_MAP_ELEMENT xb_post_connect_map[5];
275 XENPCI_STATE_MAP_ELEMENT xb_shutdown_map[5];
277 BOOLEAN hiber_usage_kludge;
278 } XENPCI_PDO_DEVICE_DATA, *PXENPCI_PDO_DEVICE_DATA;
280 WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(XENPCI_PDO_DEVICE_DATA, GetXppdd)
282 typedef struct {
283 WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER header;
284 CHAR path[128];
285 CHAR device[128];
286 ULONG index;
287 } XENPCI_PDO_IDENTIFICATION_DESCRIPTION, *PXENPCI_PDO_IDENTIFICATION_DESCRIPTION;
289 #define XEN_INTERFACE_VERSION 1
291 //#define DEVICE_INTERFACE_TYPE_LEGACY 0
292 #define DEVICE_INTERFACE_TYPE_XENBUS 1
293 #define DEVICE_INTERFACE_TYPE_EVTCHN 2
294 #define DEVICE_INTERFACE_TYPE_GNTDEV 3
296 typedef struct {
297 ULONG len;
298 WDFQUEUE io_queue;
299 union {
300 struct xsd_sockmsg msg;
301 UCHAR buffer[PAGE_SIZE];
302 } u;
303 LIST_ENTRY read_list_head;
304 LIST_ENTRY watch_list_head;
305 } XENBUS_INTERFACE_DATA, *PXENBUS_INTERFACE_DATA;
307 typedef struct {
308 ULONG dummy; /* fill this in with whatever is required */
309 } EVTCHN_INTERFACE_DATA, *PEVTCHN_INTERFACE_DATA;
311 typedef struct {
312 ULONG dummy; /* fill this in with whatever is required */
313 } GNTDEV_INTERFACE_DATA, *PGNTDEV_INTERFACE_DATA;
315 typedef struct {
316 ULONG type;
317 KSPIN_LOCK lock;
318 WDFQUEUE io_queue;
319 EVT_WDF_FILE_CLEANUP *EvtFileCleanup;
320 EVT_WDF_FILE_CLOSE *EvtFileClose;
321 union {
322 XENBUS_INTERFACE_DATA xenbus;
323 EVTCHN_INTERFACE_DATA evtchn;
324 GNTDEV_INTERFACE_DATA gntdev;
325 };
326 } XENPCI_DEVICE_INTERFACE_DATA, *PXENPCI_DEVICE_INTERFACE_DATA;
328 WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(XENPCI_DEVICE_INTERFACE_DATA, GetXpdid)
330 static __inline VOID
331 XenPci_FreeMem(PVOID Ptr) {
332 ExFreePoolWithTag(Ptr, XENPCI_POOL_TAG);
333 }
335 NTSTATUS XenBus_DeviceFileInit(WDFDEVICE device, PWDF_IO_QUEUE_CONFIG queue_config, WDFFILEOBJECT file_object);
337 EVT_WDF_DEVICE_FILE_CREATE XenPci_EvtDeviceFileCreate;
338 EVT_WDF_FILE_CLOSE XenPci_EvtFileClose;
339 EVT_WDF_FILE_CLEANUP XenPci_EvtFileCleanup;
340 EVT_WDF_IO_QUEUE_IO_DEFAULT XenPci_EvtIoDefault;
342 #if 0
343 #define HYPERVISOR_memory_op(xpdd, cmd, arg) _HYPERVISOR_memory_op(xpdd->hypercall_stubs, cmd, arg)
344 #define HYPERVISOR_xen_version(xpdd, cmd, arg) _HYPERVISOR_xen_version(xpdd->hypercall_stubs, cmd, arg)
345 #define HYPERVISOR_grant_table_op(xpdd, cmd, uop, count) _HYPERVISOR_grant_table_op(xpdd->hypercall_stubs, cmd, uop, count)
346 #define HYPERVISOR_hvm_op(xpdd, op, arg) _HYPERVISOR_hvm_op(xpdd->hypercall_stubs, op, arg)
347 #define HYPERVISOR_event_channel_op(xpdd, cmd, op) _HYPERVISOR_event_channel_op(xpdd->hypercall_stubs, cmd, op)
348 #define HYPERVISOR_sched_op(xpdd, cmd, arg) _HYPERVISOR_sched_op(xpdd->hypercall_stubs, cmd, arg)
349 #define HYPERVISOR_shutdown(xpdd, reason) _HYPERVISOR_shutdown(xpdd->hypercall_stubs, reason)
351 #define hvm_get_parameter(xvdd, hvm_param) _hvm_get_parameter(xvdd->hypercall_stubs, hvm_param);
352 #define hvm_set_parameter(xvdd, hvm_param, value) _hvm_set_parameter(xvdd->hypercall_stubs, hvm_param, value);
353 #define hvm_shutdown(xvdd, reason) _hvm_shutdown(xvdd->hypercall_stubs, reason);
354 #define HYPERVISOR_yield(xvdd) _HYPERVISOR_yield(xvdd->hypercall_stubs);
355 #endif
357 #include "hypercall.h"
359 #define XBT_NIL ((xenbus_transaction_t)0)
361 //VOID hvm_get_hypercall_stubs();
362 //VOID hvm_free_hypercall_stubs();
364 EVT_WDF_DEVICE_PREPARE_HARDWARE XenPci_EvtDevicePrepareHardware;
365 EVT_WDF_DEVICE_RELEASE_HARDWARE XenPci_EvtDeviceReleaseHardware;
366 EVT_WDF_DEVICE_D0_ENTRY XenPci_EvtDeviceD0Entry;
367 EVT_WDF_DEVICE_D0_ENTRY_POST_INTERRUPTS_ENABLED XenPci_EvtDeviceD0EntryPostInterruptsEnabled;
368 EVT_WDF_DEVICE_D0_EXIT XenPci_EvtDeviceD0Exit;
369 EVT_WDF_DEVICE_D0_EXIT_PRE_INTERRUPTS_DISABLED XenPci_EvtDeviceD0ExitPreInterruptsDisabled;
370 EVT_WDF_DEVICE_QUERY_REMOVE XenPci_EvtDeviceQueryRemove;
371 EVT_WDF_CHILD_LIST_CREATE_DEVICE XenPci_EvtChildListCreateDevice;
372 EVT_WDF_CHILD_LIST_SCAN_FOR_CHILDREN XenPci_EvtChildListScanForChildren;
374 VOID XenPci_HideQemuDevices();
375 extern WDFCOLLECTION qemu_hide_devices;
376 extern USHORT qemu_hide_flags_value;
378 VOID XenPci_BackendStateCallback(char *path, PVOID context);
379 NTSTATUS XenPci_SuspendPdo(WDFDEVICE device);
380 NTSTATUS XenPci_ResumePdo(WDFDEVICE device);
383 VOID XenPci_DumpPdoConfig(PDEVICE_OBJECT device_object);
385 typedef VOID (*PXENPCI_HIGHSYNC_FUNCTION)(PVOID context);
387 VOID XenPci_HighSync(PXENPCI_HIGHSYNC_FUNCTION function0, PXENPCI_HIGHSYNC_FUNCTION functionN, PVOID context);
389 VOID XenPci_PatchKernel(PXENPCI_DEVICE_DATA xpdd, PVOID base, ULONG length);
391 //NTSTATUS XenPci_HookDbgPrint();
392 //NTSTATUS XenPci_ReHookDbgPrint();
393 //NTSTATUS XenPci_UnHookDbgPrint();
394 //VOID XenPci_DumpModeHookDebugPrint();
395 #include <stdlib.h>
397 NTSTATUS
398 XenPci_DebugPrintV(PCHAR format, va_list args);
399 NTSTATUS
400 XenPci_DebugPrint(PCHAR format, ...);
402 struct xsd_sockmsg *XenBus_Raw(PXENPCI_DEVICE_DATA xpdd, struct xsd_sockmsg *msg);
403 char *XenBus_Read(PVOID Context, xenbus_transaction_t xbt, char *path, char **value);
404 char *XenBus_Write(PVOID Context, xenbus_transaction_t xbt, char *path, char *value);
405 char *XenBus_Printf(PVOID Context, xenbus_transaction_t xbt, char *path, char *fmt, ...);
406 char *XenBus_StartTransaction(PVOID Context, xenbus_transaction_t *xbt);
407 char *XenBus_EndTransaction(PVOID Context, xenbus_transaction_t t, int abort, int *retry);
408 char *XenBus_List(PVOID Context, xenbus_transaction_t xbt, char *prefix, char ***contents);
409 char *XenBus_AddWatch(PVOID Context, xenbus_transaction_t xbt, char *Path, PXN_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext);
410 char *XenBus_RemWatch(PVOID Context, xenbus_transaction_t xbt, char *Path, PXN_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext);
411 NTSTATUS XenBus_Init(PXENPCI_DEVICE_DATA xpdd);
412 NTSTATUS XenBus_Halt(PXENPCI_DEVICE_DATA xpdd);
413 NTSTATUS XenBus_Suspend(PXENPCI_DEVICE_DATA xpdd);
414 NTSTATUS XenBus_Resume(PXENPCI_DEVICE_DATA xpdd);
416 PHYSICAL_ADDRESS
417 XenPci_AllocMMIO(PXENPCI_DEVICE_DATA xpdd, ULONG len);
419 EVT_WDF_INTERRUPT_ISR EvtChn_EvtInterruptIsr;
420 EVT_WDF_INTERRUPT_ENABLE EvtChn_EvtInterruptEnable;
421 EVT_WDF_INTERRUPT_DISABLE EvtChn_EvtInterruptDisable;
423 NTSTATUS EvtChn_Init(PXENPCI_DEVICE_DATA xpdd);
424 NTSTATUS EvtChn_Suspend(PXENPCI_DEVICE_DATA xpdd);
425 NTSTATUS EvtChn_Resume(PXENPCI_DEVICE_DATA xpdd);
427 NTSTATUS EvtChn_Mask(PVOID context, evtchn_port_t port);
428 NTSTATUS EvtChn_Unmask(PVOID context, evtchn_port_t port);
429 NTSTATUS EvtChn_Bind(PVOID context, evtchn_port_t port, PXN_EVENT_CALLBACK ServiceRoutine, PVOID ServiceContext, ULONG flags);
430 NTSTATUS EvtChn_BindDpc(PVOID context, evtchn_port_t port, PXN_EVENT_CALLBACK ServiceRoutine, PVOID ServiceContext, ULONG flags);
431 NTSTATUS EvtChn_Unbind(PVOID context, evtchn_port_t port);
432 NTSTATUS EvtChn_Notify(PVOID context, evtchn_port_t port);
433 VOID EvtChn_Close(PVOID context, evtchn_port_t port);
434 evtchn_port_t EvtChn_AllocUnbound(PVOID context, domid_t domain);
435 evtchn_port_t EvtChn_GetEventPort(PVOID context, evtchn_port_t port);
437 VOID GntTbl_Init(PXENPCI_DEVICE_DATA xpdd);
438 VOID GntTbl_Suspend(PXENPCI_DEVICE_DATA xpdd);
439 VOID GntTbl_Resume(PXENPCI_DEVICE_DATA xpdd);
440 grant_ref_t GntTbl_GrantAccess(PVOID Context, domid_t domid, uint32_t, int readonly, grant_ref_t ref, ULONG tag);
441 BOOLEAN GntTbl_EndAccess(PVOID Context, grant_ref_t ref, BOOLEAN keepref, ULONG tag);
442 VOID GntTbl_PutRef(PVOID Context, grant_ref_t ref, ULONG tag);
443 grant_ref_t GntTbl_GetRef(PVOID Context, ULONG tag);
445 #endif