win-pvdrivers

view xenpci/xenpci.c @ 25:988042e3f1b0

Further scsiport stuff
author James Harper <james.harper@bendigoit.com.au>
date Fri Nov 30 20:56:07 2007 +1100 (2007-11-30)
parents d25a6f733a8e
children 37c64fba5fc7
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 interruptConfig.ShareVector = WdfTrue;
412 status = WdfInterruptCreate(Device, &interruptConfig, WDF_NO_OBJECT_ATTRIBUTES, &XenInterrupt);
413 if (!NT_SUCCESS (status))
414 {
415 KdPrint((__DRIVER_NAME "WdfInterruptCreate failed 0x%08x\n", status));
416 return status;
417 }
419 KdPrint((__DRIVER_NAME " <-- DeviceAdd\n"));
420 return status;
421 }
423 static NTSTATUS
424 XenPCI_PrepareHardware(
425 IN WDFDEVICE Device,
426 IN WDFCMRESLIST ResourceList,
427 IN WDFCMRESLIST ResourceListTranslated)
428 {
429 NTSTATUS status = STATUS_SUCCESS;
430 PCM_PARTIAL_RESOURCE_DESCRIPTOR descriptor;
431 ULONG i;
433 UNREFERENCED_PARAMETER(Device);
435 KdPrint((__DRIVER_NAME " --> EvtDevicePrepareHardware\n"));
437 for (i = 0; i < WdfCmResourceListGetCount(ResourceList); i++)
438 {
439 descriptor = WdfCmResourceListGetDescriptor(ResourceList, i);
440 if(!descriptor)
441 continue;
442 switch (descriptor->Type)
443 {
444 case CmResourceTypeInterrupt:
445 irqNumber = descriptor->u.Interrupt.Vector;
446 break;
447 }
448 }
450 //KdPrint((__DRIVER_NAME " GSI = %d\n", irqNumber));
452 //KdPrint((__DRIVER_NAME " ResourceListTranslated\n"));
453 for (i = 0; i < WdfCmResourceListGetCount(ResourceListTranslated); i++)
454 {
455 descriptor = WdfCmResourceListGetDescriptor(ResourceListTranslated, i);
456 if(!descriptor)
457 {
458 KdPrint((__DRIVER_NAME " --> EvtDevicePrepareHardware (No descriptor)\n"));
459 return STATUS_DEVICE_CONFIGURATION_ERROR;
460 }
461 switch (descriptor->Type) {
462 case CmResourceTypePort:
463 //KdPrint((__DRIVER_NAME " I/O mapped CSR: (%x) Length: (%d)\n", descriptor->u.Port.Start.LowPart, descriptor->u.Port.Length));
464 // deviceData->IoBaseAddress = ULongToPtr(descriptor->u.Port.Start.LowPart);
465 // deviceData->IoRange = descriptor->u.Port.Length;
466 break;
467 case CmResourceTypeMemory:
468 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));
469 platform_mmio_addr = descriptor->u.Memory.Start; //(ULONG)MmMapIoSpace(descriptor->u.Memory.Start, descriptor->u.Memory.Length, MmNonCached);
470 platform_mmio_len = descriptor->u.Memory.Length;
471 platform_mmio_alloc = 0;
472 break;
473 case CmResourceTypeInterrupt:
474 //KdPrint((__DRIVER_NAME " Interrupt level: 0x%0x, Vector: 0x%0x\n", descriptor->u.Interrupt.Level, descriptor->u.Interrupt.Vector));
475 break;
476 case CmResourceTypeDevicePrivate:
477 //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] ));
478 break;
479 default:
480 //KdPrint((__DRIVER_NAME " Unhandled resource type (0x%x)\n", descriptor->Type));
481 break;
482 }
483 }
485 get_hypercall_stubs();
487 init_xen_info();
489 GntTbl_Init();
491 EvtChn_Init();
493 set_callback_irq(irqNumber);
495 XenBus_Init();
497 //KdPrint((__DRIVER_NAME " upcall_pending = %d\n", shared_info_area->vcpu_info[0].evtchn_upcall_pending));
499 shared_info_area->vcpu_info[0].evtchn_upcall_mask = 0;
501 //xen_reboot_init();
503 KdPrint((__DRIVER_NAME " <-- EvtDevicePrepareHardware\n"));
505 return status;
506 }
508 static NTSTATUS
509 XenPCI_ReleaseHardware(WDFDEVICE Device, WDFCMRESLIST ResourcesTranslated)
510 {
511 UNREFERENCED_PARAMETER(Device);
512 UNREFERENCED_PARAMETER(ResourcesTranslated);
514 return STATUS_SUCCESS;
515 }
517 static NTSTATUS
518 XenPCI_D0Entry(
519 IN WDFDEVICE Device,
520 IN WDF_POWER_DEVICE_STATE PreviousState
521 )
522 {
523 NTSTATUS status = STATUS_SUCCESS;
525 UNREFERENCED_PARAMETER(Device);
526 UNREFERENCED_PARAMETER(PreviousState);
528 KdPrint((__DRIVER_NAME " --> EvtDeviceD0Entry\n"));
530 KdPrint((__DRIVER_NAME " <-- EvtDeviceD0Entry\n"));
532 return status;
533 }
535 static HANDLE ThreadHandle;
537 static NTSTATUS
538 XenPCI_D0EntryPostInterruptsEnabled(WDFDEVICE Device, WDF_POWER_DEVICE_STATE PreviousState)
539 {
540 NTSTATUS status = STATUS_SUCCESS;
541 //OBJECT_ATTRIBUTES oa;
542 char *response;
543 char *msgTypes;
544 char **Types;
545 int i;
546 char buffer[128];
548 UNREFERENCED_PARAMETER(Device);
549 UNREFERENCED_PARAMETER(PreviousState);
551 KdPrint((__DRIVER_NAME " --> EvtDeviceD0EntryPostInterruptsEnabled\n"));
553 XenBus_Start();
555 KdPrint((__DRIVER_NAME " A\n"));
557 response = XenBus_AddWatch(XBT_NIL, SHUTDOWN_PATH, XenBus_ShutdownHandler, NULL);
558 KdPrint((__DRIVER_NAME " shutdown watch response = '%s'\n", response));
560 response = XenBus_AddWatch(XBT_NIL, BALLOON_PATH, XenBus_BalloonHandler, NULL);
561 KdPrint((__DRIVER_NAME " shutdown watch response = '%s'\n", response));
563 response = XenBus_AddWatch(XBT_NIL, "device", XenPCI_XenBusWatchHandler, NULL);
564 KdPrint((__DRIVER_NAME " device watch response = '%s'\n", response));
566 msgTypes = XenBus_List(XBT_NIL, "device", &Types);
567 if (!msgTypes) {
568 for (i = 0; Types[i]; i++)
569 {
570 RtlStringCbPrintfA(buffer, ARRAY_SIZE(buffer), "device/%s", Types[i]);
571 //KdPrint((__DRIVER_NAME " ls device[%d] -> %s\n", i, Types[i]));
572 XenPCI_XenBusWatchHandler(buffer, NULL);
573 ExFreePoolWithTag(Types[i], XENPCI_POOL_TAG);
574 }
575 }
576 KdPrint((__DRIVER_NAME " <-- EvtDeviceD0EntryPostInterruptsEnabled\n"));
578 return status;
579 }
581 static NTSTATUS
582 XenPCI_D0ExitPreInterruptsDisabled(WDFDEVICE Device, WDF_POWER_DEVICE_STATE TargetState)
583 {
584 NTSTATUS status = STATUS_SUCCESS;
586 UNREFERENCED_PARAMETER(Device);
587 UNREFERENCED_PARAMETER(TargetState);
589 XenBus_Stop();
591 return status;
592 }
594 static NTSTATUS
595 XenPCI_D0Exit(WDFDEVICE Device, WDF_POWER_DEVICE_STATE TargetState)
596 {
597 NTSTATUS status = STATUS_SUCCESS;
599 UNREFERENCED_PARAMETER(Device);
600 UNREFERENCED_PARAMETER(TargetState);
602 KdPrint((__DRIVER_NAME " --> EvtDeviceD0Exit\n"));
604 KdPrint((__DRIVER_NAME " <-- EvtDeviceD0Exit\n"));
606 return status;
607 }
609 static VOID
610 XenPCI_IoDefault(
611 IN WDFQUEUE Queue,
612 IN WDFREQUEST Request
613 )
614 {
615 UNREFERENCED_PARAMETER(Queue);
617 KdPrint((__DRIVER_NAME " --> EvtDeviceIoDefault\n"));
619 WdfRequestComplete(Request, STATUS_NOT_IMPLEMENTED);
621 KdPrint((__DRIVER_NAME " <-- EvtDeviceIoDefault\n"));
622 }
624 static NTSTATUS
625 XenPCI_InterruptEnable(WDFINTERRUPT Interrupt, WDFDEVICE AssociatedDevice)
626 {
627 UNREFERENCED_PARAMETER(Interrupt);
628 UNREFERENCED_PARAMETER(AssociatedDevice);
630 KdPrint((__DRIVER_NAME " --> EvtInterruptEnable\n"));
632 shared_info_area->vcpu_info[0].evtchn_upcall_mask = 0;
634 KdPrint((__DRIVER_NAME " <-- EvtInterruptEnable\n"));
636 return STATUS_SUCCESS;
637 }
639 static NTSTATUS
640 XenPCI_InterruptDisable(WDFINTERRUPT Interrupt, WDFDEVICE AssociatedDevice)
641 {
642 UNREFERENCED_PARAMETER(Interrupt);
643 UNREFERENCED_PARAMETER(AssociatedDevice);
645 //KdPrint((__DRIVER_NAME " --> EvtInterruptDisable\n"));
647 shared_info_area->vcpu_info[0].evtchn_upcall_mask = 1;
648 // should we kick off any pending interrupts here?
650 //KdPrint((__DRIVER_NAME " <-- EvtInterruptDisable\n"));
652 return STATUS_SUCCESS;
653 }
655 static NTSTATUS
656 XenPCI_ChildListCreateDevice(WDFCHILDLIST ChildList, PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER IdentificationDescription, PWDFDEVICE_INIT ChildInit)
657 {
658 NTSTATUS status;
659 WDFDEVICE ChildDevice = NULL;
660 PXENPCI_IDENTIFICATION_DESCRIPTION XenIdentificationDesc;
661 XEN_IFACE_EVTCHN EvtChnInterface;
662 XEN_IFACE_XENBUS XenBusInterface;
663 XEN_IFACE_XEN XenInterface;
664 XEN_IFACE_GNTTBL GntTblInterface;
665 //UNICODE_STRING DeviceId;
666 DECLARE_UNICODE_STRING_SIZE(buffer, 20);
667 WDF_OBJECT_ATTRIBUTES PdoAttributes;
668 DECLARE_CONST_UNICODE_STRING(DeviceLocation, L"Xen Bus");
669 WDF_QUERY_INTERFACE_CONFIG qiConfig;
670 //WDF_PDO_EVENT_CALLBACKS PdoCallbacks;
671 PXENPCI_XEN_DEVICE_DATA ChildDeviceData = NULL;
672 //size_t path_len;
674 UNREFERENCED_PARAMETER(ChildList);
676 //KdPrint((__DRIVER_NAME " --> ChildListCreateDevice\n"));
678 XenIdentificationDesc = CONTAINING_RECORD(IdentificationDescription, XENPCI_IDENTIFICATION_DESCRIPTION, Header);
680 //KdPrint((__DRIVER_NAME " Type = %wZ\n", &XenIdentificationDesc->DeviceType));
682 //DeviceInit = WdfPdoInitAllocate(Device);
683 WdfDeviceInitSetDeviceType(ChildInit, FILE_DEVICE_CONTROLLER);
685 status = RtlUnicodeStringPrintf(&buffer, L"Xen\\%wZ\0", &XenIdentificationDesc->DeviceType);
686 status = WdfPdoInitAssignDeviceID(ChildInit, &buffer);
687 status = WdfPdoInitAddHardwareID(ChildInit, &buffer);
688 status = WdfPdoInitAddCompatibleID(ChildInit, &buffer);
690 status = RtlUnicodeStringPrintf(&buffer, L"%02d", 0);
691 status = WdfPdoInitAssignInstanceID(ChildInit, &buffer);
693 status = RtlUnicodeStringPrintf( &buffer, L"%wZ", &XenIdentificationDesc->DeviceType);
694 status = WdfPdoInitAddDeviceText(ChildInit, &buffer, &DeviceLocation, 0x409);
696 WdfPdoInitSetDefaultLocale(ChildInit, 0x409);
698 WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&PdoAttributes, XENPCI_XEN_DEVICE_DATA);
700 // WDF_PDO_EVENT_CALLBACKS_INIT(&PdoCallbacks);
701 // PdoCallbacks.EvtDeviceResourceRequirementsQuery = XenPCI_DeviceResourceRequirementsQuery;
702 // WdfPdoInitSetEventCallbacks(ChildInit, &PdoCallbacks);
704 status = WdfDeviceCreate(&ChildInit, &PdoAttributes, &ChildDevice);
705 if (!NT_SUCCESS(status))
706 {
707 KdPrint((__DRIVER_NAME " WdfDeviceCreate status = %08X\n", status));
708 }
710 WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFilePaging, TRUE);
711 WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFileHibernation, TRUE);
712 WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFileDump, TRUE);
714 ChildDeviceData = GetXenDeviceData(ChildDevice);
715 strncpy(ChildDeviceData->BasePath, XenIdentificationDesc->Path, 128);
717 RtlZeroMemory(&EvtChnInterface, sizeof(EvtChnInterface));
718 EvtChnInterface.InterfaceHeader.Size = sizeof(EvtChnInterface);
719 EvtChnInterface.InterfaceHeader.Version = 1;
720 EvtChnInterface.InterfaceHeader.Context = NULL;
721 EvtChnInterface.InterfaceHeader.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
722 EvtChnInterface.InterfaceHeader.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
723 EvtChnInterface.Bind = EvtChn_Bind;
724 EvtChnInterface.Unbind = EvtChn_Unbind;
725 EvtChnInterface.Mask = EvtChn_Mask;
726 EvtChnInterface.Unmask = EvtChn_Unmask;
727 EvtChnInterface.Notify = EvtChn_Notify;
728 EvtChnInterface.AllocUnbound = EvtChn_AllocUnbound;
729 WDF_QUERY_INTERFACE_CONFIG_INIT(&qiConfig, (PINTERFACE)&EvtChnInterface, &GUID_XEN_IFACE_EVTCHN, NULL);
730 status = WdfDeviceAddQueryInterface(ChildDevice, &qiConfig);
731 if (!NT_SUCCESS(status))
732 {
733 return status;
734 }
736 RtlZeroMemory(&XenInterface, sizeof(XenInterface));
737 XenInterface.InterfaceHeader.Size = sizeof(XenInterface);
738 XenInterface.InterfaceHeader.Version = 1;
739 XenInterface.InterfaceHeader.Context = NULL;
740 XenInterface.InterfaceHeader.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
741 XenInterface.InterfaceHeader.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
742 XenInterface.AllocMMIO = XenPCI_AllocMMIO;
743 WDF_QUERY_INTERFACE_CONFIG_INIT(&qiConfig, (PINTERFACE)&XenInterface, &GUID_XEN_IFACE_XEN, NULL);
744 status = WdfDeviceAddQueryInterface(ChildDevice, &qiConfig);
745 if (!NT_SUCCESS(status)) {
746 return status;
747 }
749 RtlZeroMemory(&GntTblInterface, sizeof(GntTblInterface));
750 GntTblInterface.InterfaceHeader.Size = sizeof(GntTblInterface);
751 GntTblInterface.InterfaceHeader.Version = 1;
752 GntTblInterface.InterfaceHeader.Context = NULL;
753 GntTblInterface.InterfaceHeader.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
754 GntTblInterface.InterfaceHeader.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
755 GntTblInterface.GrantAccess = GntTbl_GrantAccess;
756 GntTblInterface.EndAccess = GntTbl_EndAccess;
757 WDF_QUERY_INTERFACE_CONFIG_INIT(&qiConfig, (PINTERFACE)&GntTblInterface, &GUID_XEN_IFACE_GNTTBL, NULL);
758 status = WdfDeviceAddQueryInterface(ChildDevice, &qiConfig);
759 if (!NT_SUCCESS(status)) {
760 return status;
761 }
763 RtlZeroMemory(&XenBusInterface, sizeof(XenBusInterface));
765 XenBusInterface.InterfaceHeader.Size = sizeof(XenBusInterface);
766 XenBusInterface.InterfaceHeader.Version = 1;
767 XenBusInterface.InterfaceHeader.Context = NULL;
768 //XenBusInterface.InterfaceHeader.Context = ExAllocatePoolWithTag(NonPagedPool, (strlen(XenIdentificationDesc->Path) + 1), XENPCI_POOL_TAG);
769 //strcpy(XenBusInterface.InterfaceHeader.Context, XenIdentificationDesc->Path);
770 XenBusInterface.Read = XenBus_Read;
771 XenBusInterface.Write = XenBus_Write;
772 XenBusInterface.Printf = XenBus_Printf;
773 XenBusInterface.StartTransaction = XenBus_StartTransaction;
774 XenBusInterface.EndTransaction = XenBus_EndTransaction;
775 XenBusInterface.List = XenBus_List;
776 XenBusInterface.AddWatch = XenBus_AddWatch;
777 XenBusInterface.RemWatch = XenBus_RemWatch;
778 WDF_QUERY_INTERFACE_CONFIG_INIT(&qiConfig, (PINTERFACE)&XenBusInterface, &GUID_XEN_IFACE_XENBUS, NULL);
779 status = WdfDeviceAddQueryInterface(ChildDevice, &qiConfig);
780 if (!NT_SUCCESS(status)) {
781 return status;
782 }
784 //KdPrint((__DRIVER_NAME " <-- ChildListCreateDevice\n"));
786 return status;
787 }
789 VOID
790 XenPCI_XenBusWatchHandler(char *Path, PVOID Data)
791 {
792 XENPCI_IDENTIFICATION_DESCRIPTION description;
793 NTSTATUS status;
794 char **Bits;
795 int Count;
796 WDFCHILDLIST ChildList;
797 WDF_CHILD_LIST_ITERATOR ChildIterator;
798 WDFDEVICE ChildDevice;
799 PXENPCI_XEN_DEVICE_DATA ChildDeviceData;
801 ANSI_STRING AnsiBuf;
803 UNREFERENCED_PARAMETER(Data);
805 KdPrint((__DRIVER_NAME " --> XenBusWatchHandle\n"));
807 //KdPrint((__DRIVER_NAME " %s\n", Path));
809 ChildList = WdfFdoGetDefaultChildList(Device);
811 Bits = SplitString(Path, '/', 3, &Count);
812 switch (Count)
813 {
814 case 0:
815 case 1:
816 break;
817 case 2:
818 // add or update the device node
819 WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER_INIT(&description.Header, sizeof(description));
820 strncpy(description.Path, Path, 128);
821 RtlInitAnsiString(&AnsiBuf, Bits[1]);
822 //KdPrint((__DRIVER_NAME " Name = %s\n", Bits[1]));
823 RtlAnsiStringToUnicodeString(&description.DeviceType, &AnsiBuf, TRUE);
824 status = WdfChildListAddOrUpdateChildDescriptionAsPresent(ChildList, &description.Header, NULL);
825 break;
826 default:
827 WDF_CHILD_LIST_ITERATOR_INIT(&ChildIterator, WdfRetrievePresentChildren);
828 WdfChildListBeginIteration(ChildList, &ChildIterator);
829 while(NT_SUCCESS(WdfChildListRetrieveNextDevice(ChildList, &ChildIterator, &ChildDevice, NULL)))
830 {
831 ChildDeviceData = GetXenDeviceData(ChildDevice);
832 if (!ChildDeviceData)
833 continue;
834 if (strncmp(ChildDeviceData->BasePath, Path, strlen(ChildDeviceData->BasePath)) == 0 && Path[strlen(ChildDeviceData->BasePath)] == '/')
835 {
836 //KdPrint((__DRIVER_NAME " Child Path = %s (Match - WatchHandler = %08x)\n", ChildDeviceData->BasePath, ChildDeviceData->WatchHandler));
837 if (ChildDeviceData->WatchHandler != NULL)
838 ChildDeviceData->WatchHandler(Path, NULL);
839 }
840 else
841 {
842 //KdPrint((__DRIVER_NAME " Child Path = %s (No Match)\n", ChildDeviceData->BasePath));
843 }
844 }
845 WdfChildListEndIteration(ChildList, &ChildIterator);
846 break;
847 }
849 FreeSplitString(Bits, Count);
851 KdPrint((__DRIVER_NAME " <-- XenBusWatchHandle\n"));
852 }
854 static void
855 XenBus_ShutdownHandler(char *Path, PVOID Data)
856 {
857 char *value;
858 xenbus_transaction_t xbt;
859 int retry;
861 UNREFERENCED_PARAMETER(Path);
862 UNREFERENCED_PARAMETER(Data);
864 KdPrint((__DRIVER_NAME " --> XenBus_ShutdownHandler\n"));
866 XenBus_StartTransaction(&xbt);
868 XenBus_Read(XBT_NIL, SHUTDOWN_PATH, &value);
870 KdPrint((__DRIVER_NAME " Shutdown Value = %s\n", value));
872 // should check for error here... but why have we been called at all???
873 if (value != NULL && strlen(value) != 0)
874 XenBus_Write(XBT_NIL, SHUTDOWN_PATH, "");
876 XenBus_EndTransaction(xbt, 0, &retry);
878 KdPrint((__DRIVER_NAME " <-- XenBus_ShutdownHandler\n"));
879 }
881 static VOID
882 XenBus_BalloonHandler(char *Path, PVOID Data)
883 {
884 char *value;
885 xenbus_transaction_t xbt;
886 int retry;
888 UNREFERENCED_PARAMETER(Path);
889 UNREFERENCED_PARAMETER(Data);
891 KdPrint((__DRIVER_NAME " --> XenBus_BalloonHandler\n"));
893 XenBus_StartTransaction(&xbt);
895 XenBus_Read(XBT_NIL, BALLOON_PATH, &value);
897 KdPrint((__DRIVER_NAME " Balloon Value = %s\n", value));
899 // use the memory_op(unsigned int op, void *arg) hypercall to adjust this
900 // use XENMEM_increase_reservation and XENMEM_decrease_reservation
902 XenBus_EndTransaction(xbt, 0, &retry);
904 KdPrint((__DRIVER_NAME " <-- XenBus_BalloonHandler\n"));
905 }
907 /*
908 IO_RESOURCE_DESCRIPTOR MemoryDescriptor;
910 static NTSTATUS
911 XenPCI_FilterRemoveResourceRequirements(WDFDEVICE Device, WDFIORESREQLIST RequirementsList)
912 {
913 NTSTATUS status;
914 WDFIORESLIST ResourceList;
915 PIO_RESOURCE_DESCRIPTOR Descriptor;
917 int i, j;
918 int offset;
920 //KdPrint((__DRIVER_NAME " --> FilterRemoveResourceRequirements\n"));
922 for (i = 0; i < WdfIoResourceRequirementsListGetCount(RequirementsList); i++)
923 {
924 ResourceList = WdfIoResourceRequirementsListGetIoResList(RequirementsList, i);
925 //KdPrint((__DRIVER_NAME " Resource List %d\n", i));
926 //KdPrint((__DRIVER_NAME " %d resources in list\n", WdfIoResourceListGetCount(ResourceList)));
927 offset = 0;
928 for (j = 0; j < WdfIoResourceListGetCount(ResourceList); j++)
929 {
930 //KdPrint((__DRIVER_NAME " Resource %d\n", j));
931 Descriptor = WdfIoResourceListGetDescriptor(ResourceList, j - offset);
933 switch (Descriptor->Type) {
934 case CmResourceTypePort:
935 //KdPrint((__DRIVER_NAME " Port\n"));
936 break;
937 case CmResourceTypeMemory:
938 //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));
939 //KdPrint((__DRIVER_NAME " Length %08X\n", Descriptor->u.Memory.Length));
940 //KdPrint((__DRIVER_NAME " ShareDisposition %02X\n", Descriptor->ShareDisposition));
941 //KdPrint((__DRIVER_NAME " Option %02X\n", Descriptor->Option));
942 if (!Descriptor->Option || Descriptor->Option == IO_RESOURCE_PREFERRED) {
943 memcpy(&MemoryDescriptor, Descriptor, sizeof(IO_RESOURCE_DESCRIPTOR));
944 //platform_mmio_orig_len = MemoryDescriptor.u.Memory.Length;
945 //MemoryDescriptor.u.Memory.Length = PAGE_SIZE;
946 MemoryDescriptor.ShareDisposition = CmResourceShareShared;
947 }
948 WdfIoResourceListRemove(ResourceList, j - offset);
949 offset++;
950 break;
951 case CmResourceTypeInterrupt:
952 //KdPrint((__DRIVER_NAME " Interrupt\n"));
953 break;
954 case CmResourceTypeDevicePrivate:
955 //KdPrint((__DRIVER_NAME " Private\n"));
956 break;
957 default:
958 //KdPrint((__DRIVER_NAME " Unknown Type (0x%x)\n", Descriptor->Type));
959 break;
960 }
961 }
962 }
963 status = STATUS_SUCCESS;
965 KdPrint((__DRIVER_NAME " <-- FilterRemoveResourceRequirements\n"));
967 return status;
968 }
971 static NTSTATUS
972 XenPCI_FilterAddResourceRequirements(WDFDEVICE Device, WDFIORESREQLIST RequirementsList)
973 {
974 NTSTATUS status;
975 WDFIORESLIST ResourceList;
976 PIO_RESOURCE_DESCRIPTOR Descriptor;
978 int i, j;
980 KdPrint((__DRIVER_NAME " --> FilterAddResourceRequirements\n"));
983 for (i = 0; i < WdfIoResourceRequirementsListGetCount(RequirementsList); i++)
984 {
985 ResourceList = WdfIoResourceRequirementsListGetIoResList(RequirementsList, i);
986 //KdPrint((__DRIVER_NAME " Resource List %d\n", i));
987 //KdPrint((__DRIVER_NAME " %d resources in list\n", WdfIoResourceListGetCount(ResourceList)));
988 WdfIoResourceListAppendDescriptor(ResourceList, &MemoryDescriptor);
989 //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));
990 //KdPrint((__DRIVER_NAME " Length %08X\n", MemoryDescriptor.u.Memory.Length));
991 for (j = 0; j < WdfIoResourceListGetCount(ResourceList); j++)
992 {
993 //KdPrint((__DRIVER_NAME " Resource %d\n", j));
994 Descriptor = WdfIoResourceListGetDescriptor(ResourceList, j);
996 switch (Descriptor->Type) {
997 case CmResourceTypePort:
998 //KdPrint((__DRIVER_NAME " Port\n"));
999 break;
1000 case CmResourceTypeMemory:
1001 //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));
1002 //KdPrint((__DRIVER_NAME " Length %08X\n", Descriptor->u.Memory.Length));
1003 //KdPrint((__DRIVER_NAME " ShareDisposition %02X\n", Descriptor->ShareDisposition));
1004 //Descriptor->ShareDisposition = CmResourceShareShared;
1005 //memcpy(&MemoryDescriptor, Descriptor, sizeof(IO_RESOURCE_DESCRIPTOR));
1006 //platform_mmio_orig_len = MemoryDescriptor.u.Memory.Length;
1007 //MemoryDescriptor.u.Memory.Length = PAGE_SIZE;
1008 //WdfIoResourceListRemove(ResourceList, j);
1009 break;
1010 case CmResourceTypeInterrupt:
1011 //KdPrint((__DRIVER_NAME " Interrupt\n"));
1012 break;
1013 case CmResourceTypeDevicePrivate:
1014 //KdPrint((__DRIVER_NAME " Private\n"));
1015 break;
1016 default:
1017 //KdPrint((__DRIVER_NAME " Unknown Type (0x%x)\n", Descriptor->Type));
1018 break;
1022 status = STATUS_SUCCESS;
1024 //KdPrint((__DRIVER_NAME " <-- FilterAddResourceRequirements\n"));
1026 return status;
1029 static NTSTATUS
1030 XenPCI_RemoveAddedResources(WDFDEVICE Device, WDFCMRESLIST ResourcesRaw, WDFCMRESLIST ResourcesTranslated)
1032 //KdPrint((__DRIVER_NAME " --> RemoveAddedResources\n"));
1033 //KdPrint((__DRIVER_NAME " <-- RemoveAddedResources\n"));
1035 return STATUS_SUCCESS;
1038 */
1040 static NTSTATUS
1041 XenPCI_DeviceResourceRequirementsQuery(WDFDEVICE Device, WDFIORESREQLIST IoResourceRequirementsList)
1043 NTSTATUS status;
1044 WDFIORESLIST resourceList;
1045 IO_RESOURCE_DESCRIPTOR descriptor;
1047 UNREFERENCED_PARAMETER(Device);
1049 //KdPrint((__DRIVER_NAME " --> DeviceResourceRequirementsQuery\n"));
1051 status = WdfIoResourceListCreate(IoResourceRequirementsList, WDF_NO_OBJECT_ATTRIBUTES, &resourceList);
1052 if (!NT_SUCCESS(status))
1053 return status;
1055 /*
1056 RtlZeroMemory(&descriptor, sizeof(descriptor));
1058 descriptor.Option = 0;
1059 descriptor.Type = CmResourceTypeInterrupt;
1060 descriptor.ShareDisposition = CmResourceShareDeviceExclusive;
1061 descriptor.Flags = CM_RESOURCE_MEMORY_READ_WRITE;
1062 descriptor.u.Interrupt.MinimumVector = 1024;
1063 descriptor.u.Interrupt.MaximumVector = 1024+255;
1065 //KdPrint((__DRIVER_NAME " MinimumVector = %d, MaximumVector = %d\n", descriptor.u.Interrupt.MinimumVector, descriptor.u.Interrupt.MaximumVector));
1067 status = WdfIoResourceListAppendDescriptor(resourceList, &descriptor);
1068 if (!NT_SUCCESS(status))
1069 return status;
1070 */
1072 RtlZeroMemory(&descriptor, sizeof(descriptor));
1074 descriptor.Option = 0;
1075 descriptor.Type = CmResourceTypeMemory;
1076 descriptor.ShareDisposition = CmResourceShareShared; //CmResourceShareDeviceExclusive;
1077 descriptor.Flags = CM_RESOURCE_MEMORY_READ_WRITE;
1078 descriptor.u.Memory.Length = PAGE_SIZE;
1079 descriptor.u.Memory.Alignment = PAGE_SIZE;
1080 descriptor.u.Memory.MinimumAddress.QuadPart = platform_mmio_addr.QuadPart + PAGE_SIZE;
1081 descriptor.u.Memory.MaximumAddress.QuadPart = platform_mmio_addr.QuadPart + platform_mmio_len - 1;
1083 //KdPrint((__DRIVER_NAME " MinimumAddress = %08x, MaximumAddress = %08X\n", descriptor.u.Memory.MinimumAddress.LowPart, descriptor.u.Memory.MaximumAddress.LowPart));
1085 status = WdfIoResourceListAppendDescriptor(resourceList, &descriptor);
1086 if (!NT_SUCCESS(status))
1087 return status;
1089 status = WdfIoResourceRequirementsListAppendIoResList(IoResourceRequirementsList, resourceList);
1090 if (!NT_SUCCESS(status))
1091 return status;
1093 //KdPrint((__DRIVER_NAME " <-- DeviceResourceRequirementsQuery\n"));
1095 return status;