win-pvdrivers

view xenpci/xenpci.c @ 35:2e1d570b69e9

Final commit before 0.4.0
author James Harper <james.harper@bendigoit.com.au>
date Wed Dec 05 19:56:11 2007 +1100 (2007-12-05)
parents 28803c117324
children 3ac5c4431dbb a70cbf588756
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 #include "xenpci.h"
21 #include "hypercall.h"
22 #include <stdlib.h>
24 #define SHUTDOWN_PATH "control/shutdown"
25 #define BALLOON_PATH "memory/target"
27 DRIVER_INITIALIZE DriverEntry;
28 static NTSTATUS
29 XenPCI_AddDevice(WDFDRIVER Driver, PWDFDEVICE_INIT DeviceInit);
30 static NTSTATUS
31 XenPCI_PrepareHardware(WDFDEVICE hDevice, WDFCMRESLIST Resources, WDFCMRESLIST ResourcesTranslated);
32 static NTSTATUS
33 XenPCI_ReleaseHardware(WDFDEVICE Device, WDFCMRESLIST ResourcesTranslated);
34 static NTSTATUS
35 XenPCI_D0Entry(WDFDEVICE Device, WDF_POWER_DEVICE_STATE PreviousState);
36 static NTSTATUS
37 XenPCI_D0EntryPostInterruptsEnabled(WDFDEVICE Device, WDF_POWER_DEVICE_STATE PreviousState);
38 static NTSTATUS
39 XenPCI_D0Exit(WDFDEVICE Device, WDF_POWER_DEVICE_STATE TargetState);
40 static NTSTATUS
41 XenPCI_D0ExitPreInterruptsDisabled(WDFDEVICE Device, WDF_POWER_DEVICE_STATE TargetState);
42 static VOID
43 XenPCI_IoDefault(WDFQUEUE Queue, WDFREQUEST Request);
44 static NTSTATUS
45 XenPCI_InterruptEnable(WDFINTERRUPT Interrupt, WDFDEVICE AssociatedDevice);
46 static NTSTATUS
47 XenPCI_InterruptDisable(WDFINTERRUPT Interrupt, WDFDEVICE AssociatedDevice);
48 static NTSTATUS
49 XenPCI_ChildListCreateDevice(WDFCHILDLIST ChildList, PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER IdentificationDescription, PWDFDEVICE_INIT ChildInit);
50 static NTSTATUS
51 XenPCI_DeviceResourceRequirementsQuery(WDFDEVICE Device, WDFIORESREQLIST IoResourceRequirementsList);
52 static NTSTATUS
53 XenPCI_FilterRemoveResourceRequirements(WDFDEVICE Device, WDFIORESREQLIST IoResourceRequirementsList);
54 static NTSTATUS
55 XenPCI_FilterAddResourceRequirements(WDFDEVICE Device, WDFIORESREQLIST RequirementsList);
56 static NTSTATUS
57 XenPCI_RemoveAddedResources(WDFDEVICE Device, WDFCMRESLIST ResourcesRaw, WDFCMRESLIST ResourcesTranslated);
59 static VOID
60 XenBus_ShutdownHandler(char *Path, PVOID Data);
61 static VOID
62 XenBus_BalloonHandler(char *Path, PVOID Data);
63 static VOID
64 XenPCI_XenBusWatchHandler(char *Path, PVOID Data);
66 #ifdef ALLOC_PRAGMA
67 #pragma alloc_text (INIT, DriverEntry)
68 #pragma alloc_text (PAGE, XenPCI_AddDevice)
69 #endif
71 shared_info_t *shared_info_area;
72 static ULONG irqNumber = 0;
74 static BOOLEAN AutoEnumerate;
76 static WDFDEVICE Device;
78 NTSTATUS
79 DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
80 {
81 WDF_DRIVER_CONFIG config;
82 NTSTATUS status;
83 UNICODE_STRING RegKeyName;
84 UNICODE_STRING RegValueName;
85 HANDLE RegHandle;
86 OBJECT_ATTRIBUTES RegObjectAttributes;
87 char Buf[200];
88 ULONG BufLen = 200;
89 PKEY_VALUE_PARTIAL_INFORMATION KeyPartialValue;
90 int State = 0;
91 int StartPos = 0;
92 WCHAR *SystemStartOptions;
93 size_t SystemStartOptionsLen;
94 size_t i;
96 KdPrint((__DRIVER_NAME " --> DriverEntry\n"));
98 RtlInitUnicodeString(&RegKeyName, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control");
99 InitializeObjectAttributes(&RegObjectAttributes, &RegKeyName, OBJ_CASE_INSENSITIVE, NULL, NULL);
100 status = ZwOpenKey(&RegHandle, KEY_READ, &RegObjectAttributes);
101 if(!NT_SUCCESS(status))
102 {
103 KdPrint((__DRIVER_NAME " ZwOpenKey returned %08x\n", status));
104 }
106 RtlInitUnicodeString(&RegValueName, L"SystemStartOptions");
107 status = ZwQueryValueKey(RegHandle, &RegValueName, KeyValuePartialInformation, Buf, BufLen, &BufLen);
108 if(!NT_SUCCESS(status))
109 {
110 KdPrint((__DRIVER_NAME " ZwQueryKeyValue returned %08x\n", status));
111 }
112 //KdPrint((__DRIVER_NAME " BufLen = %d\n", BufLen));
113 KeyPartialValue = (PKEY_VALUE_PARTIAL_INFORMATION)Buf;
114 KdPrint((__DRIVER_NAME " Buf = %ws\n", KeyPartialValue->Data));
115 SystemStartOptions = (WCHAR *)KeyPartialValue->Data;
117 AutoEnumerate = FALSE;
119 RtlStringCbLengthW(SystemStartOptions, KeyPartialValue->DataLength, &SystemStartOptionsLen);
121 for (i = 0; i <= SystemStartOptionsLen/2; i++)
122 {
123 //KdPrint((__DRIVER_NAME " pos = %d, state = %d, char = '%wc' (%d)\n", i, State, SystemStartOptions[i], SystemStartOptions[i]));
125 switch (State)
126 {
127 case 0:
128 if (SystemStartOptions[i] == L'G')
129 {
130 StartPos = i;
131 State = 2;
132 } else if (SystemStartOptions[i] != L' ')
133 {
134 State = 1;
135 }
136 break;
137 case 1:
138 if (SystemStartOptions[i] == L' ')
139 State = 0;
140 break;
141 case 2:
142 if (SystemStartOptions[i] == L'P')
143 State = 3;
144 else
145 State = 0;
146 break;
147 case 3:
148 if (SystemStartOptions[i] == L'L')
149 State = 4;
150 else
151 State = 0;
152 break;
153 case 4:
154 if (SystemStartOptions[i] == L'P')
155 State = 5;
156 else
157 State = 0;
158 break;
159 case 5:
160 if (SystemStartOptions[i] == L'V')
161 State = 6;
162 else
163 State = 0;
164 break;
165 case 6:
166 if (SystemStartOptions[i] == L' ' || SystemStartOptions[i] == 0)
167 AutoEnumerate = TRUE;
168 State = 0;
169 break;
170 }
171 }
173 KdPrint((__DRIVER_NAME " AutoEnumerate = %d\n", AutoEnumerate));
175 WDF_DRIVER_CONFIG_INIT(&config, XenPCI_AddDevice);
176 status = WdfDriverCreate(
177 DriverObject,
178 RegistryPath,
179 WDF_NO_OBJECT_ATTRIBUTES,
180 &config,
181 WDF_NO_HANDLE);
182 if(!NT_SUCCESS(status))
183 {
184 KdPrint((__DRIVER_NAME " WdfDriverCreate failed with status 0x%08x\n", status));
185 }
187 KdPrint((__DRIVER_NAME " <-- DriverEntry\n"));
189 return status;
190 }
192 static void WRMSR(unsigned int msr, ULONGLONG val)
193 {
194 ULONG lo, hi;
195 lo = (ULONG)val;
196 hi = (ULONG)(val >> 32);
197 __asm {
198 mov ecx, msr
199 mov eax, lo
200 mov edx, hi
201 wrmsr
202 }
203 }
205 static int
206 get_hypercall_stubs()
207 {
208 DWORD32 cpuid_output[4];
209 char xensig[13];
210 ULONG i;
211 ULONG pages;
212 ULONG msr;
214 __cpuid(cpuid_output, 0x40000000);
215 *(ULONG*)(xensig + 0) = cpuid_output[1];
216 *(ULONG*)(xensig + 4) = cpuid_output[2];
217 *(ULONG*)(xensig + 8) = cpuid_output[3];
218 xensig[12] = '\0';
219 KdPrint((__DRIVER_NAME " Xen Signature = %s, EAX = 0x%08x\n", xensig, cpuid_output[0]));
221 __cpuid(cpuid_output, 0x40000002);
222 pages = cpuid_output[0];
223 msr = cpuid_output[1];
224 //KdPrint((__DRIVER_NAME " Hypercall area is %u pages.\n", pages));
226 hypercall_stubs = ExAllocatePoolWithTag(NonPagedPool, pages * PAGE_SIZE, XENPCI_POOL_TAG);
227 //KdPrint((__DRIVER_NAME " Hypercall area at %08x\n", hypercall_stubs));
229 if (hypercall_stubs == NULL)
230 return 1;
231 for (i = 0; i < pages; i++) {
232 ULONG pfn;
233 //pfn = vmalloc_to_pfn((char *)hypercall_stubs + i * PAGE_SIZE);
234 pfn = (ULONG)(MmGetPhysicalAddress(hypercall_stubs + i * PAGE_SIZE).QuadPart >> PAGE_SHIFT);
235 //KdPrint((__DRIVER_NAME " pfn = %08X\n", pfn));
236 WRMSR(msr, ((ULONGLONG)pfn << PAGE_SHIFT) + i);
237 }
238 return STATUS_SUCCESS;
239 }
241 static ULONG PciBusNumber;
242 static USHORT PciFunctionNumber, PciDeviceNumber;
243 static USHORT PciPinNumber;
245 static WDFINTERRUPT XenInterrupt;
247 static PHYSICAL_ADDRESS platform_mmio_addr;
248 static ULONG platform_mmio_orig_len;
249 static ULONG platform_mmio_len;
250 static ULONG platform_mmio_alloc;
252 PHYSICAL_ADDRESS
253 XenPCI_AllocMMIO(ULONG len)
254 {
255 PHYSICAL_ADDRESS addr;
257 addr = platform_mmio_addr;
258 addr.QuadPart += platform_mmio_alloc;
259 platform_mmio_alloc += len;
261 return addr;
262 }
264 static int
265 init_xen_info()
266 {
267 struct xen_add_to_physmap xatp;
268 int ret;
269 PHYSICAL_ADDRESS shared_info_area_unmapped;
271 //setup_xen_features();
272 //KdPrint((__DRIVER_NAME " init_xen_info Hypercall area at %08x\n", hypercall_stubs));
274 shared_info_area_unmapped = XenPCI_AllocMMIO(PAGE_SIZE);
275 xatp.domid = DOMID_SELF;
276 xatp.idx = 0;
277 xatp.space = XENMAPSPACE_shared_info;
278 xatp.gpfn = (xen_pfn_t)(shared_info_area_unmapped.QuadPart >> PAGE_SHIFT);
279 ret = HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp);
280 //KdPrint((__DRIVER_NAME " ret = %d\n", ret));
282 shared_info_area = (shared_info_t *)MmMapIoSpace(shared_info_area_unmapped, PAGE_SIZE, MmNonCached);
284 return 0;
285 }
287 static PKINTERRUPT interrupt;
289 static int
290 set_callback_irq(ULONGLONG irq)
291 {
292 struct xen_hvm_param a;
293 int retval;
295 //KdPrint((__DRIVER_NAME " --> set_callback_irq\n"));
296 a.domid = DOMID_SELF;
297 a.index = HVM_PARAM_CALLBACK_IRQ;
298 a.value = irq;
299 retval = HYPERVISOR_hvm_op(HVMOP_set_param, &a);
300 //KdPrint((__DRIVER_NAME " HYPERVISOR_hvm_op retval = %d\n", retval));
301 //KdPrint((__DRIVER_NAME " <-- set_callback_irq\n"));
302 return retval;
303 }
305 static NTSTATUS
306 XenPCI_AddDevice(
307 IN WDFDRIVER Driver,
308 IN PWDFDEVICE_INIT DeviceInit
309 )
310 {
311 NTSTATUS status;
312 WDF_CHILD_LIST_CONFIG config;
313 PXENPCI_DEVICE_DATA devData = NULL;
314 WDF_OBJECT_ATTRIBUTES attributes;
315 WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;
316 WDF_IO_QUEUE_CONFIG ioQConfig;
317 WDF_INTERRUPT_CONFIG interruptConfig;
318 PNP_BUS_INFORMATION busInfo;
319 BUS_INTERFACE_STANDARD BusInterface;
320 //WDFDEVICE Parent;
322 //PDEVICE_OBJECT pdo;
323 //ULONG propertyAddress, length;
325 UNREFERENCED_PARAMETER(Driver);
327 KdPrint((__DRIVER_NAME " --> DeviceAdd\n"));
329 // get PDO
330 // get parent (should be PCI bus) (WdfPdoGetParent)
331 //
333 WdfDeviceInitSetDeviceType(DeviceInit, FILE_DEVICE_BUS_EXTENDER);
334 WDF_CHILD_LIST_CONFIG_INIT(&config, sizeof(XENPCI_IDENTIFICATION_DESCRIPTION), XenPCI_ChildListCreateDevice);
335 WdfFdoInitSetDefaultChildListConfig(DeviceInit, &config, WDF_NO_OBJECT_ATTRIBUTES);
337 // WDF_FDO_EVENT_CALLBACKS_INIT(&FdoCallbacks);
338 // FdoCallbacks.EvtDeviceFilterRemoveResourceRequirements = XenPCI_FilterRemoveResourceRequirements;
339 // FdoCallbacks.EvtDeviceFilterAddResourceRequirements = XenPCI_FilterAddResourceRequirements;
340 // FdoCallbacks.EvtDeviceRemoveAddedResources = XenPCI_RemoveAddedResources;
341 // WdfFdoInitSetEventCallbacks(DeviceInit, &FdoCallbacks);
343 WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);
344 pnpPowerCallbacks.EvtDevicePrepareHardware = XenPCI_PrepareHardware;
345 pnpPowerCallbacks.EvtDeviceReleaseHardware = XenPCI_ReleaseHardware;
346 pnpPowerCallbacks.EvtDeviceD0Entry = XenPCI_D0Entry;
347 pnpPowerCallbacks.EvtDeviceD0EntryPostInterruptsEnabled = XenPCI_D0EntryPostInterruptsEnabled;
348 pnpPowerCallbacks.EvtDeviceD0ExitPreInterruptsDisabled = XenPCI_D0ExitPreInterruptsDisabled;
349 pnpPowerCallbacks.EvtDeviceD0Exit = XenPCI_D0Exit;
350 WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);
352 WdfDeviceInitSetIoType(DeviceInit, WdfDeviceIoBuffered);
354 /*initialize storage for the device context*/
355 WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, XENPCI_DEVICE_DATA);
357 /*create a device instance.*/
358 status = WdfDeviceCreate(&DeviceInit, &attributes, &Device);
359 if(!NT_SUCCESS(status))
360 {
361 KdPrint((__DRIVER_NAME " WdfDeviceCreate failed with status 0x%08x\n", status));
362 return status;
363 }
365 WdfDeviceSetSpecialFileSupport(Device, WdfSpecialFilePaging, TRUE);
366 WdfDeviceSetSpecialFileSupport(Device, WdfSpecialFileHibernation, TRUE);
367 WdfDeviceSetSpecialFileSupport(Device, WdfSpecialFileDump, TRUE);
369 status = WdfFdoQueryForInterface(Device, &GUID_BUS_INTERFACE_STANDARD, (PINTERFACE) &BusInterface, sizeof(BUS_INTERFACE_STANDARD), 1, NULL);
370 if(!NT_SUCCESS(status))
371 {
372 KdPrint((__DRIVER_NAME " WdfFdoQueryForInterface (BusInterface) failed with status 0x%08x\n", status));
373 }
375 //BusInterface.GetBusData(NULL, PCI_WHICHSPACE_CONFIG, buf,
378 busInfo.BusTypeGuid = GUID_XENPCI_DEVCLASS;
379 busInfo.LegacyBusType = PNPBus;
380 busInfo.BusNumber = 0;
382 WdfDeviceSetBusInformationForChildren(Device, &busInfo);
384 /*create the default IO queue. this one will
385 be used for all requests*/
386 /*
387 WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&ioQConfig,
388 WdfIoQueueDispatchSequential);
389 ioQConfig.EvtIoDefault = XenPCI_IoDefault;
390 status = WdfIoQueueCreate(Device, &ioQConfig,
391 WDF_NO_OBJECT_ATTRIBUTES,
392 &devData->IoDefaultQueue);
393 if(!NT_SUCCESS(status))
394 {
395 KdPrint((__DRIVER_NAME " WdfIoQueueCreate failed with status 0x%08x\n", status));
396 return status;
397 }
398 */
399 /*
400 status = WdfDeviceCreateDeviceInterface(Device, &GUID_INTERFACE_XENPCI, NULL);
401 if(!NT_SUCCESS(status))
402 {
403 KdPrint((__DRIVER_NAME "WdfDeviceCreateDeviceInterface failed with status 0x%08x\n", status));
404 return status;
405 }
406 */
408 WDF_INTERRUPT_CONFIG_INIT(&interruptConfig, EvtChn_Interrupt, NULL); //EvtChn_InterruptDpc);
409 interruptConfig.EvtInterruptEnable = XenPCI_InterruptEnable;
410 interruptConfig.EvtInterruptDisable = XenPCI_InterruptDisable;
411 status = WdfInterruptCreate(Device, &interruptConfig, WDF_NO_OBJECT_ATTRIBUTES, &XenInterrupt);
412 if (!NT_SUCCESS (status))
413 {
414 KdPrint((__DRIVER_NAME "WdfInterruptCreate failed 0x%08x\n", status));
415 return status;
416 }
418 KdPrint((__DRIVER_NAME " <-- DeviceAdd\n"));
419 return status;
420 }
422 static NTSTATUS
423 XenPCI_PrepareHardware(
424 IN WDFDEVICE Device,
425 IN WDFCMRESLIST ResourceList,
426 IN WDFCMRESLIST ResourceListTranslated)
427 {
428 NTSTATUS status = STATUS_SUCCESS;
429 PCM_PARTIAL_RESOURCE_DESCRIPTOR descriptor;
430 ULONG i;
432 UNREFERENCED_PARAMETER(Device);
434 KdPrint((__DRIVER_NAME " --> EvtDevicePrepareHardware\n"));
436 for (i = 0; i < WdfCmResourceListGetCount(ResourceList); i++)
437 {
438 descriptor = WdfCmResourceListGetDescriptor(ResourceList, i);
439 if(!descriptor)
440 continue;
441 switch (descriptor->Type)
442 {
443 case CmResourceTypeInterrupt:
444 irqNumber = descriptor->u.Interrupt.Vector;
445 break;
446 }
447 }
449 //KdPrint((__DRIVER_NAME " GSI = %d\n", irqNumber));
451 //KdPrint((__DRIVER_NAME " ResourceListTranslated\n"));
452 for (i = 0; i < WdfCmResourceListGetCount(ResourceListTranslated); i++)
453 {
454 descriptor = WdfCmResourceListGetDescriptor(ResourceListTranslated, i);
455 if(!descriptor)
456 {
457 KdPrint((__DRIVER_NAME " --> EvtDevicePrepareHardware (No descriptor)\n"));
458 return STATUS_DEVICE_CONFIGURATION_ERROR;
459 }
460 switch (descriptor->Type) {
461 case CmResourceTypePort:
462 //KdPrint((__DRIVER_NAME " I/O mapped CSR: (%x) Length: (%d)\n", descriptor->u.Port.Start.LowPart, descriptor->u.Port.Length));
463 // deviceData->IoBaseAddress = ULongToPtr(descriptor->u.Port.Start.LowPart);
464 // deviceData->IoRange = descriptor->u.Port.Length;
465 break;
466 case CmResourceTypeMemory:
467 KdPrint((__DRIVER_NAME " Memory mapped CSR:(%x:%x) Length:(%d)\n", descriptor->u.Memory.Start.LowPart, descriptor->u.Memory.Start.HighPart, descriptor->u.Memory.Length));
468 platform_mmio_addr = descriptor->u.Memory.Start; //(ULONG)MmMapIoSpace(descriptor->u.Memory.Start, descriptor->u.Memory.Length, MmNonCached);
469 platform_mmio_len = descriptor->u.Memory.Length;
470 platform_mmio_alloc = 0;
471 break;
472 case CmResourceTypeInterrupt:
473 //KdPrint((__DRIVER_NAME " Interrupt level: 0x%0x, Vector: 0x%0x\n", descriptor->u.Interrupt.Level, descriptor->u.Interrupt.Vector));
474 break;
475 case CmResourceTypeDevicePrivate:
476 //KdPrint((__DRIVER_NAME " Private Data: 0x%02x 0x%02x 0x%02x\n", descriptor->u.DevicePrivate.Data[0], descriptor->u.DevicePrivate.Data[1], descriptor->u.DevicePrivate.Data[2] ));
477 break;
478 default:
479 //KdPrint((__DRIVER_NAME " Unhandled resource type (0x%x)\n", descriptor->Type));
480 break;
481 }
482 }
484 get_hypercall_stubs();
486 init_xen_info();
488 GntTbl_Init();
490 EvtChn_Init();
492 set_callback_irq(irqNumber);
494 XenBus_Init();
496 //KdPrint((__DRIVER_NAME " upcall_pending = %d\n", shared_info_area->vcpu_info[0].evtchn_upcall_pending));
498 shared_info_area->vcpu_info[0].evtchn_upcall_mask = 0;
500 //xen_reboot_init();
502 KdPrint((__DRIVER_NAME " <-- EvtDevicePrepareHardware\n"));
504 return status;
505 }
507 static NTSTATUS
508 XenPCI_ReleaseHardware(WDFDEVICE Device, WDFCMRESLIST ResourcesTranslated)
509 {
510 UNREFERENCED_PARAMETER(Device);
511 UNREFERENCED_PARAMETER(ResourcesTranslated);
513 return STATUS_SUCCESS;
514 }
516 static NTSTATUS
517 XenPCI_D0Entry(
518 IN WDFDEVICE Device,
519 IN WDF_POWER_DEVICE_STATE PreviousState
520 )
521 {
522 NTSTATUS status = STATUS_SUCCESS;
524 UNREFERENCED_PARAMETER(Device);
525 UNREFERENCED_PARAMETER(PreviousState);
527 KdPrint((__DRIVER_NAME " --> EvtDeviceD0Entry\n"));
529 KdPrint((__DRIVER_NAME " <-- EvtDeviceD0Entry\n"));
531 return status;
532 }
534 static HANDLE ThreadHandle;
536 static NTSTATUS
537 XenPCI_D0EntryPostInterruptsEnabled(WDFDEVICE Device, WDF_POWER_DEVICE_STATE PreviousState)
538 {
539 NTSTATUS status = STATUS_SUCCESS;
540 //OBJECT_ATTRIBUTES oa;
541 char *response;
542 char *msgTypes;
543 char **Types;
544 int i;
545 char buffer[128];
547 UNREFERENCED_PARAMETER(Device);
548 UNREFERENCED_PARAMETER(PreviousState);
550 KdPrint((__DRIVER_NAME " --> EvtDeviceD0EntryPostInterruptsEnabled\n"));
552 XenBus_Start();
554 KdPrint((__DRIVER_NAME " A\n"));
556 response = XenBus_AddWatch(XBT_NIL, SHUTDOWN_PATH, XenBus_ShutdownHandler, NULL);
557 KdPrint((__DRIVER_NAME " shutdown watch response = '%s'\n", response));
559 response = XenBus_AddWatch(XBT_NIL, BALLOON_PATH, XenBus_BalloonHandler, NULL);
560 KdPrint((__DRIVER_NAME " shutdown watch response = '%s'\n", response));
562 response = XenBus_AddWatch(XBT_NIL, "device", XenPCI_XenBusWatchHandler, NULL);
563 KdPrint((__DRIVER_NAME " device watch response = '%s'\n", response));
565 msgTypes = XenBus_List(XBT_NIL, "device", &Types);
566 if (!msgTypes) {
567 for (i = 0; Types[i]; i++)
568 {
569 RtlStringCbPrintfA(buffer, ARRAY_SIZE(buffer), "device/%s", Types[i]);
570 //KdPrint((__DRIVER_NAME " ls device[%d] -> %s\n", i, Types[i]));
571 XenPCI_XenBusWatchHandler(buffer, NULL);
572 ExFreePoolWithTag(Types[i], XENPCI_POOL_TAG);
573 }
574 }
575 KdPrint((__DRIVER_NAME " <-- EvtDeviceD0EntryPostInterruptsEnabled\n"));
577 return status;
578 }
580 static NTSTATUS
581 XenPCI_D0ExitPreInterruptsDisabled(WDFDEVICE Device, WDF_POWER_DEVICE_STATE TargetState)
582 {
583 NTSTATUS status = STATUS_SUCCESS;
585 UNREFERENCED_PARAMETER(Device);
586 UNREFERENCED_PARAMETER(TargetState);
588 KdPrint((__DRIVER_NAME " --> D0ExitPreInterruptsDisabled\n"));
590 switch (KeGetCurrentIrql())
591 {
592 case PASSIVE_LEVEL:
593 KdPrint((__DRIVER_NAME " PASSIVE_LEVEL\n"));
594 break;
595 case APC_LEVEL:
596 KdPrint((__DRIVER_NAME " APC_LEVEL\n"));
597 break;
598 case DISPATCH_LEVEL:
599 KdPrint((__DRIVER_NAME " DISPATCH_LEVEL\n"));
600 break;
601 default:
602 KdPrint((__DRIVER_NAME " %d\n", KeGetCurrentIrql()));
603 break;
604 }
606 XenBus_Stop();
608 KdPrint((__DRIVER_NAME " <-- D0ExitPreInterruptsDisabled\n"));
610 return status;
611 }
613 static NTSTATUS
614 XenPCI_D0Exit(WDFDEVICE Device, WDF_POWER_DEVICE_STATE TargetState)
615 {
616 NTSTATUS status = STATUS_SUCCESS;
618 UNREFERENCED_PARAMETER(Device);
619 UNREFERENCED_PARAMETER(TargetState);
621 KdPrint((__DRIVER_NAME " --> DeviceD0Exit\n"));
623 switch (KeGetCurrentIrql())
624 {
625 case PASSIVE_LEVEL:
626 KdPrint((__DRIVER_NAME " PASSIVE_LEVEL\n"));
627 break;
628 case APC_LEVEL:
629 KdPrint((__DRIVER_NAME " APC_LEVEL\n"));
630 break;
631 case DISPATCH_LEVEL:
632 KdPrint((__DRIVER_NAME " DISPATCH_LEVEL\n"));
633 break;
634 default:
635 KdPrint((__DRIVER_NAME " %d\n", KeGetCurrentIrql()));
636 break;
637 }
639 XenBus_Close();
641 KdPrint((__DRIVER_NAME " <-- DeviceD0Exit\n"));
643 return status;
644 }
646 static VOID
647 XenPCI_IoDefault(
648 IN WDFQUEUE Queue,
649 IN WDFREQUEST Request
650 )
651 {
652 UNREFERENCED_PARAMETER(Queue);
654 KdPrint((__DRIVER_NAME " --> EvtDeviceIoDefault\n"));
656 WdfRequestComplete(Request, STATUS_NOT_IMPLEMENTED);
658 KdPrint((__DRIVER_NAME " <-- EvtDeviceIoDefault\n"));
659 }
661 static NTSTATUS
662 XenPCI_InterruptEnable(WDFINTERRUPT Interrupt, WDFDEVICE AssociatedDevice)
663 {
664 UNREFERENCED_PARAMETER(Interrupt);
665 UNREFERENCED_PARAMETER(AssociatedDevice);
667 KdPrint((__DRIVER_NAME " --> EvtInterruptEnable\n"));
669 shared_info_area->vcpu_info[0].evtchn_upcall_mask = 0;
671 KdPrint((__DRIVER_NAME " <-- EvtInterruptEnable\n"));
673 return STATUS_SUCCESS;
674 }
676 static NTSTATUS
677 XenPCI_InterruptDisable(WDFINTERRUPT Interrupt, WDFDEVICE AssociatedDevice)
678 {
679 UNREFERENCED_PARAMETER(Interrupt);
680 UNREFERENCED_PARAMETER(AssociatedDevice);
682 //KdPrint((__DRIVER_NAME " --> EvtInterruptDisable\n"));
684 shared_info_area->vcpu_info[0].evtchn_upcall_mask = 1;
685 // should we kick off any pending interrupts here?
687 //KdPrint((__DRIVER_NAME " <-- EvtInterruptDisable\n"));
689 return STATUS_SUCCESS;
690 }
692 static NTSTATUS
693 XenPCI_ChildListCreateDevice(WDFCHILDLIST ChildList, PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER IdentificationDescription, PWDFDEVICE_INIT ChildInit)
694 {
695 NTSTATUS status;
696 WDFDEVICE ChildDevice = NULL;
697 PXENPCI_IDENTIFICATION_DESCRIPTION XenIdentificationDesc;
698 XEN_IFACE_EVTCHN EvtChnInterface;
699 XEN_IFACE_XENBUS XenBusInterface;
700 XEN_IFACE_XEN XenInterface;
701 XEN_IFACE_GNTTBL GntTblInterface;
702 //UNICODE_STRING DeviceId;
703 DECLARE_UNICODE_STRING_SIZE(buffer, 20);
704 WDF_OBJECT_ATTRIBUTES PdoAttributes;
705 DECLARE_CONST_UNICODE_STRING(DeviceLocation, L"Xen Bus");
706 WDF_QUERY_INTERFACE_CONFIG qiConfig;
707 //WDF_PDO_EVENT_CALLBACKS PdoCallbacks;
708 PXENPCI_XEN_DEVICE_DATA ChildDeviceData = NULL;
709 //size_t path_len;
711 UNREFERENCED_PARAMETER(ChildList);
713 //KdPrint((__DRIVER_NAME " --> ChildListCreateDevice\n"));
715 XenIdentificationDesc = CONTAINING_RECORD(IdentificationDescription, XENPCI_IDENTIFICATION_DESCRIPTION, Header);
717 //KdPrint((__DRIVER_NAME " Type = %wZ\n", &XenIdentificationDesc->DeviceType));
719 //DeviceInit = WdfPdoInitAllocate(Device);
720 WdfDeviceInitSetDeviceType(ChildInit, FILE_DEVICE_CONTROLLER);
722 status = RtlUnicodeStringPrintf(&buffer, L"Xen\\%wZ\0", &XenIdentificationDesc->DeviceType);
723 status = WdfPdoInitAssignDeviceID(ChildInit, &buffer);
724 status = WdfPdoInitAddHardwareID(ChildInit, &buffer);
725 status = WdfPdoInitAddCompatibleID(ChildInit, &buffer);
727 status = RtlUnicodeStringPrintf(&buffer, L"%02d", 0);
728 status = WdfPdoInitAssignInstanceID(ChildInit, &buffer);
730 status = RtlUnicodeStringPrintf( &buffer, L"%wZ", &XenIdentificationDesc->DeviceType);
731 status = WdfPdoInitAddDeviceText(ChildInit, &buffer, &DeviceLocation, 0x409);
733 WdfPdoInitSetDefaultLocale(ChildInit, 0x409);
735 WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&PdoAttributes, XENPCI_XEN_DEVICE_DATA);
737 // WDF_PDO_EVENT_CALLBACKS_INIT(&PdoCallbacks);
738 // PdoCallbacks.EvtDeviceResourceRequirementsQuery = XenPCI_DeviceResourceRequirementsQuery;
739 // WdfPdoInitSetEventCallbacks(ChildInit, &PdoCallbacks);
741 status = WdfDeviceCreate(&ChildInit, &PdoAttributes, &ChildDevice);
742 if (!NT_SUCCESS(status))
743 {
744 KdPrint((__DRIVER_NAME " WdfDeviceCreate status = %08X\n", status));
745 }
747 WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFilePaging, TRUE);
748 WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFileHibernation, TRUE);
749 WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFileDump, TRUE);
751 ChildDeviceData = GetXenDeviceData(ChildDevice);
752 strncpy(ChildDeviceData->BasePath, XenIdentificationDesc->Path, 128);
754 RtlZeroMemory(&EvtChnInterface, sizeof(EvtChnInterface));
755 EvtChnInterface.InterfaceHeader.Size = sizeof(EvtChnInterface);
756 EvtChnInterface.InterfaceHeader.Version = 1;
757 EvtChnInterface.InterfaceHeader.Context = NULL;
758 EvtChnInterface.InterfaceHeader.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
759 EvtChnInterface.InterfaceHeader.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
760 EvtChnInterface.Bind = EvtChn_Bind;
761 EvtChnInterface.Unbind = EvtChn_Unbind;
762 EvtChnInterface.Mask = EvtChn_Mask;
763 EvtChnInterface.Unmask = EvtChn_Unmask;
764 EvtChnInterface.Notify = EvtChn_Notify;
765 EvtChnInterface.AllocUnbound = EvtChn_AllocUnbound;
766 WDF_QUERY_INTERFACE_CONFIG_INIT(&qiConfig, (PINTERFACE)&EvtChnInterface, &GUID_XEN_IFACE_EVTCHN, NULL);
767 status = WdfDeviceAddQueryInterface(ChildDevice, &qiConfig);
768 if (!NT_SUCCESS(status))
769 {
770 return status;
771 }
773 RtlZeroMemory(&XenInterface, sizeof(XenInterface));
774 XenInterface.InterfaceHeader.Size = sizeof(XenInterface);
775 XenInterface.InterfaceHeader.Version = 1;
776 XenInterface.InterfaceHeader.Context = NULL;
777 XenInterface.InterfaceHeader.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
778 XenInterface.InterfaceHeader.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
779 XenInterface.AllocMMIO = XenPCI_AllocMMIO;
780 WDF_QUERY_INTERFACE_CONFIG_INIT(&qiConfig, (PINTERFACE)&XenInterface, &GUID_XEN_IFACE_XEN, NULL);
781 status = WdfDeviceAddQueryInterface(ChildDevice, &qiConfig);
782 if (!NT_SUCCESS(status)) {
783 return status;
784 }
786 RtlZeroMemory(&GntTblInterface, sizeof(GntTblInterface));
787 GntTblInterface.InterfaceHeader.Size = sizeof(GntTblInterface);
788 GntTblInterface.InterfaceHeader.Version = 1;
789 GntTblInterface.InterfaceHeader.Context = NULL;
790 GntTblInterface.InterfaceHeader.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
791 GntTblInterface.InterfaceHeader.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
792 GntTblInterface.GrantAccess = GntTbl_GrantAccess;
793 GntTblInterface.EndAccess = GntTbl_EndAccess;
794 WDF_QUERY_INTERFACE_CONFIG_INIT(&qiConfig, (PINTERFACE)&GntTblInterface, &GUID_XEN_IFACE_GNTTBL, NULL);
795 status = WdfDeviceAddQueryInterface(ChildDevice, &qiConfig);
796 if (!NT_SUCCESS(status)) {
797 return status;
798 }
800 RtlZeroMemory(&XenBusInterface, sizeof(XenBusInterface));
802 XenBusInterface.InterfaceHeader.Size = sizeof(XenBusInterface);
803 XenBusInterface.InterfaceHeader.Version = 1;
804 XenBusInterface.InterfaceHeader.Context = NULL;
805 //XenBusInterface.InterfaceHeader.Context = ExAllocatePoolWithTag(NonPagedPool, (strlen(XenIdentificationDesc->Path) + 1), XENPCI_POOL_TAG);
806 //strcpy(XenBusInterface.InterfaceHeader.Context, XenIdentificationDesc->Path);
807 XenBusInterface.Read = XenBus_Read;
808 XenBusInterface.Write = XenBus_Write;
809 XenBusInterface.Printf = XenBus_Printf;
810 XenBusInterface.StartTransaction = XenBus_StartTransaction;
811 XenBusInterface.EndTransaction = XenBus_EndTransaction;
812 XenBusInterface.List = XenBus_List;
813 XenBusInterface.AddWatch = XenBus_AddWatch;
814 XenBusInterface.RemWatch = XenBus_RemWatch;
815 WDF_QUERY_INTERFACE_CONFIG_INIT(&qiConfig, (PINTERFACE)&XenBusInterface, &GUID_XEN_IFACE_XENBUS, NULL);
816 status = WdfDeviceAddQueryInterface(ChildDevice, &qiConfig);
817 if (!NT_SUCCESS(status)) {
818 return status;
819 }
821 //KdPrint((__DRIVER_NAME " <-- ChildListCreateDevice\n"));
823 return status;
824 }
826 VOID
827 XenPCI_XenBusWatchHandler(char *Path, PVOID Data)
828 {
829 XENPCI_IDENTIFICATION_DESCRIPTION description;
830 NTSTATUS status;
831 char **Bits;
832 int Count;
833 WDFCHILDLIST ChildList;
834 WDF_CHILD_LIST_ITERATOR ChildIterator;
835 WDFDEVICE ChildDevice;
836 PXENPCI_XEN_DEVICE_DATA ChildDeviceData;
838 ANSI_STRING AnsiBuf;
840 UNREFERENCED_PARAMETER(Data);
842 KdPrint((__DRIVER_NAME " --> XenBusWatchHandle\n"));
844 //KdPrint((__DRIVER_NAME " %s\n", Path));
846 ChildList = WdfFdoGetDefaultChildList(Device);
848 Bits = SplitString(Path, '/', 3, &Count);
849 switch (Count)
850 {
851 case 0:
852 case 1:
853 break;
854 case 2:
855 // add or update the device node
856 WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER_INIT(&description.Header, sizeof(description));
857 strncpy(description.Path, Path, 128);
858 RtlInitAnsiString(&AnsiBuf, Bits[1]);
859 //KdPrint((__DRIVER_NAME " Name = %s\n", Bits[1]));
860 RtlAnsiStringToUnicodeString(&description.DeviceType, &AnsiBuf, TRUE);
861 status = WdfChildListAddOrUpdateChildDescriptionAsPresent(ChildList, &description.Header, NULL);
862 break;
863 default:
864 WDF_CHILD_LIST_ITERATOR_INIT(&ChildIterator, WdfRetrievePresentChildren);
865 WdfChildListBeginIteration(ChildList, &ChildIterator);
866 while(NT_SUCCESS(WdfChildListRetrieveNextDevice(ChildList, &ChildIterator, &ChildDevice, NULL)))
867 {
868 ChildDeviceData = GetXenDeviceData(ChildDevice);
869 if (!ChildDeviceData)
870 continue;
871 if (strncmp(ChildDeviceData->BasePath, Path, strlen(ChildDeviceData->BasePath)) == 0 && Path[strlen(ChildDeviceData->BasePath)] == '/')
872 {
873 //KdPrint((__DRIVER_NAME " Child Path = %s (Match - WatchHandler = %08x)\n", ChildDeviceData->BasePath, ChildDeviceData->WatchHandler));
874 if (ChildDeviceData->WatchHandler != NULL)
875 ChildDeviceData->WatchHandler(Path, NULL);
876 }
877 else
878 {
879 //KdPrint((__DRIVER_NAME " Child Path = %s (No Match)\n", ChildDeviceData->BasePath));
880 }
881 }
882 WdfChildListEndIteration(ChildList, &ChildIterator);
883 break;
884 }
886 FreeSplitString(Bits, Count);
888 KdPrint((__DRIVER_NAME " <-- XenBusWatchHandle\n"));
889 }
891 static void
892 XenBus_ShutdownHandler(char *Path, PVOID Data)
893 {
894 char *value;
895 xenbus_transaction_t xbt;
896 int retry;
898 UNREFERENCED_PARAMETER(Path);
899 UNREFERENCED_PARAMETER(Data);
901 KdPrint((__DRIVER_NAME " --> XenBus_ShutdownHandler\n"));
903 XenBus_StartTransaction(&xbt);
905 XenBus_Read(XBT_NIL, SHUTDOWN_PATH, &value);
907 KdPrint((__DRIVER_NAME " Shutdown Value = %s\n", value));
909 // should check for error here... but why have we been called at all???
910 if (value != NULL && strlen(value) != 0)
911 XenBus_Write(XBT_NIL, SHUTDOWN_PATH, "");
913 XenBus_EndTransaction(xbt, 0, &retry);
915 KdPrint((__DRIVER_NAME " <-- XenBus_ShutdownHandler\n"));
916 }
918 static VOID
919 XenBus_BalloonHandler(char *Path, PVOID Data)
920 {
921 char *value;
922 xenbus_transaction_t xbt;
923 int retry;
925 UNREFERENCED_PARAMETER(Path);
926 UNREFERENCED_PARAMETER(Data);
928 KdPrint((__DRIVER_NAME " --> XenBus_BalloonHandler\n"));
930 XenBus_StartTransaction(&xbt);
932 XenBus_Read(XBT_NIL, BALLOON_PATH, &value);
934 KdPrint((__DRIVER_NAME " Balloon Value = %s\n", value));
936 // use the memory_op(unsigned int op, void *arg) hypercall to adjust this
937 // use XENMEM_increase_reservation and XENMEM_decrease_reservation
939 XenBus_EndTransaction(xbt, 0, &retry);
941 KdPrint((__DRIVER_NAME " <-- XenBus_BalloonHandler\n"));
942 }
944 /*
945 IO_RESOURCE_DESCRIPTOR MemoryDescriptor;
947 static NTSTATUS
948 XenPCI_FilterRemoveResourceRequirements(WDFDEVICE Device, WDFIORESREQLIST RequirementsList)
949 {
950 NTSTATUS status;
951 WDFIORESLIST ResourceList;
952 PIO_RESOURCE_DESCRIPTOR Descriptor;
954 int i, j;
955 int offset;
957 //KdPrint((__DRIVER_NAME " --> FilterRemoveResourceRequirements\n"));
959 for (i = 0; i < WdfIoResourceRequirementsListGetCount(RequirementsList); i++)
960 {
961 ResourceList = WdfIoResourceRequirementsListGetIoResList(RequirementsList, i);
962 //KdPrint((__DRIVER_NAME " Resource List %d\n", i));
963 //KdPrint((__DRIVER_NAME " %d resources in list\n", WdfIoResourceListGetCount(ResourceList)));
964 offset = 0;
965 for (j = 0; j < WdfIoResourceListGetCount(ResourceList); j++)
966 {
967 //KdPrint((__DRIVER_NAME " Resource %d\n", j));
968 Descriptor = WdfIoResourceListGetDescriptor(ResourceList, j - offset);
970 switch (Descriptor->Type) {
971 case CmResourceTypePort:
972 //KdPrint((__DRIVER_NAME " Port\n"));
973 break;
974 case CmResourceTypeMemory:
975 //KdPrint((__DRIVER_NAME " Memory %08X%08X - %08X%08X\n", Descriptor->u.Memory.MinimumAddress.HighPart, Descriptor->u.Memory.MinimumAddress.LowPart, Descriptor->u.Memory.MaximumAddress.HighPart, Descriptor->u.Memory.MaximumAddress.LowPart));
976 //KdPrint((__DRIVER_NAME " Length %08X\n", Descriptor->u.Memory.Length));
977 //KdPrint((__DRIVER_NAME " ShareDisposition %02X\n", Descriptor->ShareDisposition));
978 //KdPrint((__DRIVER_NAME " Option %02X\n", Descriptor->Option));
979 if (!Descriptor->Option || Descriptor->Option == IO_RESOURCE_PREFERRED) {
980 memcpy(&MemoryDescriptor, Descriptor, sizeof(IO_RESOURCE_DESCRIPTOR));
981 //platform_mmio_orig_len = MemoryDescriptor.u.Memory.Length;
982 //MemoryDescriptor.u.Memory.Length = PAGE_SIZE;
983 MemoryDescriptor.ShareDisposition = CmResourceShareShared;
984 }
985 WdfIoResourceListRemove(ResourceList, j - offset);
986 offset++;
987 break;
988 case CmResourceTypeInterrupt:
989 //KdPrint((__DRIVER_NAME " Interrupt\n"));
990 break;
991 case CmResourceTypeDevicePrivate:
992 //KdPrint((__DRIVER_NAME " Private\n"));
993 break;
994 default:
995 //KdPrint((__DRIVER_NAME " Unknown Type (0x%x)\n", Descriptor->Type));
996 break;
997 }
998 }
999 }
1000 status = STATUS_SUCCESS;
1002 KdPrint((__DRIVER_NAME " <-- FilterRemoveResourceRequirements\n"));
1004 return status;
1008 static NTSTATUS
1009 XenPCI_FilterAddResourceRequirements(WDFDEVICE Device, WDFIORESREQLIST RequirementsList)
1011 NTSTATUS status;
1012 WDFIORESLIST ResourceList;
1013 PIO_RESOURCE_DESCRIPTOR Descriptor;
1015 int i, j;
1017 KdPrint((__DRIVER_NAME " --> FilterAddResourceRequirements\n"));
1020 for (i = 0; i < WdfIoResourceRequirementsListGetCount(RequirementsList); i++)
1022 ResourceList = WdfIoResourceRequirementsListGetIoResList(RequirementsList, i);
1023 //KdPrint((__DRIVER_NAME " Resource List %d\n", i));
1024 //KdPrint((__DRIVER_NAME " %d resources in list\n", WdfIoResourceListGetCount(ResourceList)));
1025 WdfIoResourceListAppendDescriptor(ResourceList, &MemoryDescriptor);
1026 //KdPrint((__DRIVER_NAME " Memory %08X%08X - %08X%08X\n", MemoryDescriptor.u.Memory.MinimumAddress.HighPart, MemoryDescriptor.u.Memory.MinimumAddress.LowPart, MemoryDescriptor.u.Memory.MaximumAddress.HighPart, MemoryDescriptor.u.Memory.MaximumAddress.LowPart));
1027 //KdPrint((__DRIVER_NAME " Length %08X\n", MemoryDescriptor.u.Memory.Length));
1028 for (j = 0; j < WdfIoResourceListGetCount(ResourceList); j++)
1030 //KdPrint((__DRIVER_NAME " Resource %d\n", j));
1031 Descriptor = WdfIoResourceListGetDescriptor(ResourceList, j);
1033 switch (Descriptor->Type) {
1034 case CmResourceTypePort:
1035 //KdPrint((__DRIVER_NAME " Port\n"));
1036 break;
1037 case CmResourceTypeMemory:
1038 //KdPrint((__DRIVER_NAME " Memory %08X%08X - %08X%08X\n", Descriptor->u.Memory.MinimumAddress.HighPart, Descriptor->u.Memory.MinimumAddress.LowPart, Descriptor->u.Memory.MaximumAddress.HighPart, Descriptor->u.Memory.MaximumAddress.LowPart));
1039 //KdPrint((__DRIVER_NAME " Length %08X\n", Descriptor->u.Memory.Length));
1040 //KdPrint((__DRIVER_NAME " ShareDisposition %02X\n", Descriptor->ShareDisposition));
1041 //Descriptor->ShareDisposition = CmResourceShareShared;
1042 //memcpy(&MemoryDescriptor, Descriptor, sizeof(IO_RESOURCE_DESCRIPTOR));
1043 //platform_mmio_orig_len = MemoryDescriptor.u.Memory.Length;
1044 //MemoryDescriptor.u.Memory.Length = PAGE_SIZE;
1045 //WdfIoResourceListRemove(ResourceList, j);
1046 break;
1047 case CmResourceTypeInterrupt:
1048 //KdPrint((__DRIVER_NAME " Interrupt\n"));
1049 break;
1050 case CmResourceTypeDevicePrivate:
1051 //KdPrint((__DRIVER_NAME " Private\n"));
1052 break;
1053 default:
1054 //KdPrint((__DRIVER_NAME " Unknown Type (0x%x)\n", Descriptor->Type));
1055 break;
1059 status = STATUS_SUCCESS;
1061 //KdPrint((__DRIVER_NAME " <-- FilterAddResourceRequirements\n"));
1063 return status;
1066 static NTSTATUS
1067 XenPCI_RemoveAddedResources(WDFDEVICE Device, WDFCMRESLIST ResourcesRaw, WDFCMRESLIST ResourcesTranslated)
1069 //KdPrint((__DRIVER_NAME " --> RemoveAddedResources\n"));
1070 //KdPrint((__DRIVER_NAME " <-- RemoveAddedResources\n"));
1072 return STATUS_SUCCESS;
1075 */
1077 static NTSTATUS
1078 XenPCI_DeviceResourceRequirementsQuery(WDFDEVICE Device, WDFIORESREQLIST IoResourceRequirementsList)
1080 NTSTATUS status;
1081 WDFIORESLIST resourceList;
1082 IO_RESOURCE_DESCRIPTOR descriptor;
1084 UNREFERENCED_PARAMETER(Device);
1086 //KdPrint((__DRIVER_NAME " --> DeviceResourceRequirementsQuery\n"));
1088 status = WdfIoResourceListCreate(IoResourceRequirementsList, WDF_NO_OBJECT_ATTRIBUTES, &resourceList);
1089 if (!NT_SUCCESS(status))
1090 return status;
1092 /*
1093 RtlZeroMemory(&descriptor, sizeof(descriptor));
1095 descriptor.Option = 0;
1096 descriptor.Type = CmResourceTypeInterrupt;
1097 descriptor.ShareDisposition = CmResourceShareDeviceExclusive;
1098 descriptor.Flags = CM_RESOURCE_MEMORY_READ_WRITE;
1099 descriptor.u.Interrupt.MinimumVector = 1024;
1100 descriptor.u.Interrupt.MaximumVector = 1024+255;
1102 //KdPrint((__DRIVER_NAME " MinimumVector = %d, MaximumVector = %d\n", descriptor.u.Interrupt.MinimumVector, descriptor.u.Interrupt.MaximumVector));
1104 status = WdfIoResourceListAppendDescriptor(resourceList, &descriptor);
1105 if (!NT_SUCCESS(status))
1106 return status;
1107 */
1109 RtlZeroMemory(&descriptor, sizeof(descriptor));
1111 descriptor.Option = 0;
1112 descriptor.Type = CmResourceTypeMemory;
1113 descriptor.ShareDisposition = CmResourceShareShared; //CmResourceShareDeviceExclusive;
1114 descriptor.Flags = CM_RESOURCE_MEMORY_READ_WRITE;
1115 descriptor.u.Memory.Length = PAGE_SIZE;
1116 descriptor.u.Memory.Alignment = PAGE_SIZE;
1117 descriptor.u.Memory.MinimumAddress.QuadPart = platform_mmio_addr.QuadPart + PAGE_SIZE;
1118 descriptor.u.Memory.MaximumAddress.QuadPart = platform_mmio_addr.QuadPart + platform_mmio_len - 1;
1120 //KdPrint((__DRIVER_NAME " MinimumAddress = %08x, MaximumAddress = %08X\n", descriptor.u.Memory.MinimumAddress.LowPart, descriptor.u.Memory.MaximumAddress.LowPart));
1122 status = WdfIoResourceListAppendDescriptor(resourceList, &descriptor);
1123 if (!NT_SUCCESS(status))
1124 return status;
1126 status = WdfIoResourceRequirementsListAppendIoResList(IoResourceRequirementsList, resourceList);
1127 if (!NT_SUCCESS(status))
1128 return status;
1130 //KdPrint((__DRIVER_NAME " <-- DeviceResourceRequirementsQuery\n"));
1132 return status;