win-pvdrivers

view xenpci/xenpci.h @ 1054:471c94d04d8a

Refactoring to support xencache (tmem)
author James Harper <james.harper@bendigoit.com.au>
date Sun Jun 02 16:37:21 2013 +1000 (2013-06-02)
parents cd72cd0e1c19
children 27bd2a5a4704
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 PVOID hypercall_stubs;
79 extern ULONG qemu_protocol_version;
80 extern USHORT xen_version_major;
81 extern USHORT xen_version_minor;
83 typedef struct _ev_action_t {
84 PVOID xpdd;
85 //evtchn_port_t port;
86 PXN_EVENT_CALLBACK ServiceRoutine;
87 PVOID ServiceContext;
88 CHAR description[128];
89 ULONG type; /* EVT_ACTION_TYPE_* */
90 ULONG flags; /* EVT_ACTION_FLAGS_* */
91 KDPC Dpc;
92 ULONG vector;
93 ULONG count;
94 } ev_action_t;
96 typedef struct _XENBUS_WATCH_RING
97 {
98 char Path[128];
99 char Token[10];
100 } XENBUS_WATCH_RING;
102 typedef struct xsd_sockmsg xsd_sockmsg_t;
104 typedef struct _XENBUS_WATCH_ENTRY {
105 char Path[128];
106 PXN_WATCH_CALLBACK ServiceRoutine;
107 PVOID ServiceContext;
108 int Count;
109 int Active;
110 } XENBUS_WATCH_ENTRY, *PXENBUS_WATCH_ENTRY;
112 /* number of events is 1024 on 32 bits and 4096 on 64 bits */
113 #define NR_EVENTS (sizeof(xen_ulong_t) * 8 * sizeof(xen_ulong_t) * 8)
114 #define WATCH_RING_SIZE 128
115 #define NR_XB_REQS 32
116 #define MAX_WATCH_ENTRIES 128
118 #define CHILD_STATE_EMPTY 0
119 #define CHILD_STATE_DELETED 1
120 #define CHILD_STATE_ADDED 2
122 #define SUSPEND_STATE_NONE 0 /* no suspend in progress */
123 #define SUSPEND_STATE_SCHEDULED 1 /* suspend scheduled */
124 #define SUSPEND_STATE_HIGH_IRQL 2 /* all processors are at high IRQL and spinning */
125 #define SUSPEND_STATE_RESUMING 3 /* we are the other side of the suspend and things are starting to get back to normal */
127 /* we take some grant refs out and put them aside so that we dont get corrupted by hibernate */
128 #define HIBER_GREF_COUNT 128
130 typedef struct {
131 ULONG generation;
132 ULONG tag;
133 } grant_tag_t;
135 typedef struct {
136 WDFDEVICE wdf_device;
138 BOOLEAN tpr_patched;
140 WDFINTERRUPT interrupt;
141 ULONG irq_number;
142 ULONG irq_vector;
143 KIRQL irq_level;
144 KINTERRUPT_MODE irq_mode;
145 KAFFINITY irq_affinity;
147 PHYSICAL_ADDRESS shared_info_area_unmapped;
148 shared_info_t *shared_info_area;
149 xen_ulong_t evtchn_pending_pvt[MAX_VIRT_CPUS][sizeof(xen_ulong_t) * 8];
150 xen_ulong_t evtchn_pending_suspend[sizeof(xen_ulong_t) * 8];
151 //evtchn_port_t pdo_event_channel;
152 //KEVENT pdo_suspend_event;
153 BOOLEAN interrupts_masked;
155 PHYSICAL_ADDRESS platform_mmio_addr;
156 ULONG platform_mmio_orig_len;
157 ULONG platform_mmio_len;
158 ULONG platform_mmio_alloc;
159 USHORT platform_mmio_flags;
161 ULONG platform_ioport_addr;
162 ULONG platform_ioport_len;
164 evtchn_port_t xenbus_event;
166 /* grant related */
167 struct stack_state *gnttbl_ss;
168 struct stack_state *gnttbl_ss_copy;
169 grant_ref_t hiber_grefs[HIBER_GREF_COUNT];
170 PMDL gnttbl_mdl;
171 grant_entry_t *gnttbl_table;
172 grant_entry_t *gnttbl_table_copy;
173 #if DBG
174 ULONG gnttbl_generation; /* incremented once per save or hibernate */
175 grant_tag_t *gnttbl_tag;
176 grant_tag_t *gnttbl_tag_copy;
177 #endif
178 ULONG grant_frames;
180 ev_action_t ev_actions[NR_EVENTS];
181 // unsigned long bound_ports[NR_EVENTS/(8*sizeof(unsigned long))];
183 BOOLEAN xb_state;
185 struct xenstore_domain_interface *xen_store_interface;
187 PKTHREAD balloon_thread;
188 KEVENT balloon_event;
189 BOOLEAN balloon_shutdown;
190 //ULONG initial_memory_kb;
191 ULONG current_memory_kb;
192 ULONG target_memory_kb;
194 /* xenbus related */
195 XENBUS_WATCH_ENTRY XenBus_WatchEntries[MAX_WATCH_ENTRIES];
196 KSPIN_LOCK xb_ring_spinlock;
197 FAST_MUTEX xb_watch_mutex;
198 FAST_MUTEX xb_request_mutex;
199 KEVENT xb_request_complete_event;
200 struct xsd_sockmsg *xb_reply;
201 struct xsd_sockmsg *xb_msg;
202 ULONG xb_msg_offset;
204 WDFCHILDLIST child_list;
206 FAST_MUTEX suspend_mutex;
208 ULONG suspend_evtchn;
209 int suspend_state;
211 UNICODE_STRING legacy_interface_name;
212 UNICODE_STRING interface_name;
213 BOOLEAN interface_open;
215 BOOLEAN removable;
217 BOOLEAN hibernated;
219 WDFQUEUE io_queue;
221 //WDFCOLLECTION veto_devices;
222 LIST_ENTRY veto_list;
224 #if 0
225 KSPIN_LOCK mmio_freelist_lock;
226 PPFN_NUMBER mmio_freelist_base;
227 ULONG mmio_freelist_free;
228 #endif
230 } XENPCI_DEVICE_DATA, *PXENPCI_DEVICE_DATA;
232 WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(XENPCI_DEVICE_DATA, GetXpdd)
234 typedef struct {
235 UCHAR front_target;
236 UCHAR back_expected;
237 UCHAR wait; /* units = 100ms */
238 } XENPCI_STATE_MAP_ELEMENT, *PXENPCI_STATE_MAP_ELEMENT;
240 typedef struct {
241 WDFDEVICE wdf_device;
242 WDFDEVICE wdf_device_bus_fdo;
243 PXENPCI_DEVICE_DATA xpdd;
244 BOOLEAN reported_missing;
245 char path[128];
246 char device[128];
247 ULONG index;
248 ULONG irq_number;
249 ULONG irq_vector;
250 KIRQL irq_level;
251 char backend_path[128];
252 domid_t backend_id;
253 KEVENT backend_state_event;
254 ULONG backend_state;
255 PXN_DEVICE_CALLBACK device_callback;
256 PVOID device_callback_context;
257 FAST_MUTEX backend_state_mutex;
258 ULONG frontend_state;
259 BOOLEAN restart_on_resume;
260 BOOLEAN backend_initiated_remove;
261 BOOLEAN do_not_enumerate;
263 XENPCI_STATE_MAP_ELEMENT xb_pre_connect_map[5];
264 XENPCI_STATE_MAP_ELEMENT xb_post_connect_map[5];
265 XENPCI_STATE_MAP_ELEMENT xb_shutdown_map[5];
267 BOOLEAN hiber_usage_kludge;
268 } XENPCI_PDO_DEVICE_DATA, *PXENPCI_PDO_DEVICE_DATA;
270 WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(XENPCI_PDO_DEVICE_DATA, GetXppdd)
272 typedef struct {
273 WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER header;
274 CHAR path[128];
275 CHAR device[128];
276 ULONG index;
277 } XENPCI_PDO_IDENTIFICATION_DESCRIPTION, *PXENPCI_PDO_IDENTIFICATION_DESCRIPTION;
279 #define XEN_INTERFACE_VERSION 1
281 //#define DEVICE_INTERFACE_TYPE_LEGACY 0
282 #define DEVICE_INTERFACE_TYPE_XENBUS 1
283 #define DEVICE_INTERFACE_TYPE_EVTCHN 2
284 #define DEVICE_INTERFACE_TYPE_GNTDEV 3
286 typedef struct {
287 ULONG len;
288 WDFQUEUE io_queue;
289 union {
290 struct xsd_sockmsg msg;
291 UCHAR buffer[PAGE_SIZE];
292 } u;
293 LIST_ENTRY read_list_head;
294 LIST_ENTRY watch_list_head;
295 } XENBUS_INTERFACE_DATA, *PXENBUS_INTERFACE_DATA;
297 typedef struct {
298 ULONG dummy; /* fill this in with whatever is required */
299 } EVTCHN_INTERFACE_DATA, *PEVTCHN_INTERFACE_DATA;
301 typedef struct {
302 ULONG dummy; /* fill this in with whatever is required */
303 } GNTDEV_INTERFACE_DATA, *PGNTDEV_INTERFACE_DATA;
305 typedef struct {
306 ULONG type;
307 KSPIN_LOCK lock;
308 WDFQUEUE io_queue;
309 EVT_WDF_FILE_CLEANUP *EvtFileCleanup;
310 EVT_WDF_FILE_CLOSE *EvtFileClose;
311 union {
312 XENBUS_INTERFACE_DATA xenbus;
313 EVTCHN_INTERFACE_DATA evtchn;
314 GNTDEV_INTERFACE_DATA gntdev;
315 };
316 } XENPCI_DEVICE_INTERFACE_DATA, *PXENPCI_DEVICE_INTERFACE_DATA;
318 WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(XENPCI_DEVICE_INTERFACE_DATA, GetXpdid)
320 static __inline VOID
321 XenPci_FreeMem(PVOID Ptr) {
322 ExFreePoolWithTag(Ptr, XENPCI_POOL_TAG);
323 }
325 NTSTATUS XenBus_DeviceFileInit(WDFDEVICE device, PWDF_IO_QUEUE_CONFIG queue_config, WDFFILEOBJECT file_object);
327 EVT_WDF_DEVICE_FILE_CREATE XenPci_EvtDeviceFileCreate;
328 EVT_WDF_FILE_CLOSE XenPci_EvtFileClose;
329 EVT_WDF_FILE_CLEANUP XenPci_EvtFileCleanup;
330 EVT_WDF_IO_QUEUE_IO_DEFAULT XenPci_EvtIoDefault;
332 #if 0
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);
345 #endif
347 #include "hypercall.h"
349 #define XBT_NIL ((xenbus_transaction_t)0)
351 //VOID hvm_get_hypercall_stubs();
352 //VOID hvm_free_hypercall_stubs();
354 EVT_WDF_DEVICE_PREPARE_HARDWARE XenPci_EvtDevicePrepareHardware;
355 EVT_WDF_DEVICE_RELEASE_HARDWARE XenPci_EvtDeviceReleaseHardware;
356 EVT_WDF_DEVICE_D0_ENTRY XenPci_EvtDeviceD0Entry;
357 EVT_WDF_DEVICE_D0_ENTRY_POST_INTERRUPTS_ENABLED XenPci_EvtDeviceD0EntryPostInterruptsEnabled;
358 EVT_WDF_DEVICE_D0_EXIT XenPci_EvtDeviceD0Exit;
359 EVT_WDF_DEVICE_D0_EXIT_PRE_INTERRUPTS_DISABLED XenPci_EvtDeviceD0ExitPreInterruptsDisabled;
360 EVT_WDF_DEVICE_QUERY_REMOVE XenPci_EvtDeviceQueryRemove;
361 EVT_WDF_CHILD_LIST_CREATE_DEVICE XenPci_EvtChildListCreateDevice;
362 EVT_WDF_CHILD_LIST_SCAN_FOR_CHILDREN XenPci_EvtChildListScanForChildren;
364 VOID XenPci_HideQemuDevices();
365 extern WDFCOLLECTION qemu_hide_devices;
366 extern USHORT qemu_hide_flags_value;
368 VOID XenPci_BackendStateCallback(char *path, PVOID context);
369 NTSTATUS XenPci_SuspendPdo(WDFDEVICE device);
370 NTSTATUS XenPci_ResumePdo(WDFDEVICE device);
373 VOID XenPci_DumpPdoConfig(PDEVICE_OBJECT device_object);
375 typedef VOID (*PXENPCI_HIGHSYNC_FUNCTION)(PVOID context);
377 VOID XenPci_HighSync(PXENPCI_HIGHSYNC_FUNCTION function0, PXENPCI_HIGHSYNC_FUNCTION functionN, PVOID context);
379 VOID XenPci_PatchKernel(PXENPCI_DEVICE_DATA xpdd, PVOID base, ULONG length);
381 //NTSTATUS XenPci_HookDbgPrint();
382 //NTSTATUS XenPci_ReHookDbgPrint();
383 //NTSTATUS XenPci_UnHookDbgPrint();
384 //VOID XenPci_DumpModeHookDebugPrint();
385 #include <stdlib.h>
387 NTSTATUS
388 XenPci_DebugPrintV(PCHAR format, va_list args);
389 NTSTATUS
390 XenPci_DebugPrint(PCHAR format, ...);
392 struct xsd_sockmsg *XenBus_Raw(PXENPCI_DEVICE_DATA xpdd, struct xsd_sockmsg *msg);
393 char *XenBus_Read(PVOID Context, xenbus_transaction_t xbt, char *path, char **value);
394 char *XenBus_Write(PVOID Context, xenbus_transaction_t xbt, char *path, char *value);
395 char *XenBus_Printf(PVOID Context, xenbus_transaction_t xbt, char *path, char *fmt, ...);
396 char *XenBus_StartTransaction(PVOID Context, xenbus_transaction_t *xbt);
397 char *XenBus_EndTransaction(PVOID Context, xenbus_transaction_t t, int abort, int *retry);
398 char *XenBus_List(PVOID Context, xenbus_transaction_t xbt, char *prefix, char ***contents);
399 char *XenBus_AddWatch(PVOID Context, xenbus_transaction_t xbt, char *Path, PXN_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext);
400 char *XenBus_RemWatch(PVOID Context, xenbus_transaction_t xbt, char *Path, PXN_WATCH_CALLBACK ServiceRoutine, PVOID ServiceContext);
401 NTSTATUS XenBus_Init(PXENPCI_DEVICE_DATA xpdd);
402 NTSTATUS XenBus_Halt(PXENPCI_DEVICE_DATA xpdd);
403 NTSTATUS XenBus_Suspend(PXENPCI_DEVICE_DATA xpdd);
404 NTSTATUS XenBus_Resume(PXENPCI_DEVICE_DATA xpdd);
406 PHYSICAL_ADDRESS
407 XenPci_AllocMMIO(PXENPCI_DEVICE_DATA xpdd, ULONG len);
409 EVT_WDF_INTERRUPT_ISR EvtChn_EvtInterruptIsr;
410 EVT_WDF_INTERRUPT_ENABLE EvtChn_EvtInterruptEnable;
411 EVT_WDF_INTERRUPT_DISABLE EvtChn_EvtInterruptDisable;
413 NTSTATUS EvtChn_Init(PXENPCI_DEVICE_DATA xpdd);
414 NTSTATUS EvtChn_Suspend(PXENPCI_DEVICE_DATA xpdd);
415 NTSTATUS EvtChn_Resume(PXENPCI_DEVICE_DATA xpdd);
417 NTSTATUS EvtChn_Mask(PVOID context, evtchn_port_t port);
418 NTSTATUS EvtChn_Unmask(PVOID context, evtchn_port_t port);
419 NTSTATUS EvtChn_Bind(PVOID context, evtchn_port_t port, PXN_EVENT_CALLBACK ServiceRoutine, PVOID ServiceContext, ULONG flags);
420 NTSTATUS EvtChn_BindDpc(PVOID context, evtchn_port_t port, PXN_EVENT_CALLBACK ServiceRoutine, PVOID ServiceContext, ULONG flags);
421 NTSTATUS EvtChn_Unbind(PVOID context, evtchn_port_t port);
422 NTSTATUS EvtChn_Notify(PVOID context, evtchn_port_t port);
423 VOID EvtChn_Close(PVOID context, evtchn_port_t port);
424 evtchn_port_t EvtChn_AllocUnbound(PVOID context, domid_t domain);
425 evtchn_port_t EvtChn_GetEventPort(PVOID context, evtchn_port_t port);
427 VOID GntTbl_Init(PXENPCI_DEVICE_DATA xpdd);
428 VOID GntTbl_Suspend(PXENPCI_DEVICE_DATA xpdd);
429 VOID GntTbl_Resume(PXENPCI_DEVICE_DATA xpdd);
430 grant_ref_t GntTbl_GrantAccess(PVOID Context, domid_t domid, uint32_t, int readonly, grant_ref_t ref, ULONG tag);
431 BOOLEAN GntTbl_EndAccess(PVOID Context, grant_ref_t ref, BOOLEAN keepref, ULONG tag);
432 VOID GntTbl_PutRef(PVOID Context, grant_ref_t ref, ULONG tag);
433 grant_ref_t GntTbl_GetRef(PVOID Context, ULONG tag);
435 #endif