win-pvdrivers

view xenpci/xenpci.c @ 0:435e5753300f

Initial upload of files
author James Harper <james.harper@bendigoit.com.au>
date Sat Nov 10 14:40:56 2007 +1100 (2007-11-10)
parents
children 3bf1f48005d8
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"
26 DRIVER_INITIALIZE DriverEntry;
27 static NTSTATUS
28 XenPCI_AddDevice(WDFDRIVER Driver, PWDFDEVICE_INIT DeviceInit);
29 static NTSTATUS
30 XenPCI_PrepareHardware(WDFDEVICE hDevice, WDFCMRESLIST Resources, WDFCMRESLIST ResourcesTranslated);
31 static NTSTATUS
32 XenPCI_ReleaseHardware(WDFDEVICE Device, WDFCMRESLIST ResourcesTranslated);
33 static NTSTATUS
34 XenPCI_D0Entry(WDFDEVICE Device, WDF_POWER_DEVICE_STATE PreviousState);
35 static NTSTATUS
36 XenPCI_D0EntryPostInterruptsEnabled(WDFDEVICE Device, WDF_POWER_DEVICE_STATE PreviousState);
37 static NTSTATUS
38 XenPCI_D0Exit(WDFDEVICE Device, WDF_POWER_DEVICE_STATE TargetState);
39 static NTSTATUS
40 XenPCI_D0ExitPreInterruptsDisabled(WDFDEVICE Device, WDF_POWER_DEVICE_STATE TargetState);
41 static VOID
42 XenPCI_IoDefault(WDFQUEUE Queue, WDFREQUEST Request);
43 static NTSTATUS
44 XenPCI_InterruptEnable(WDFINTERRUPT Interrupt, WDFDEVICE AssociatedDevice);
45 static NTSTATUS
46 XenPCI_InterruptDisable(WDFINTERRUPT Interrupt, WDFDEVICE AssociatedDevice);
47 static NTSTATUS
48 XenPCI_ChildListCreateDevice(WDFCHILDLIST ChildList, PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER IdentificationDescription, PWDFDEVICE_INIT ChildInit);
49 static NTSTATUS
50 XenPCI_DeviceResourceRequirementsQuery(WDFDEVICE Device, WDFIORESREQLIST IoResourceRequirementsList);
51 static NTSTATUS
52 XenPCI_FilterRemoveResourceRequirements(WDFDEVICE Device, WDFIORESREQLIST IoResourceRequirementsList);
53 static NTSTATUS
54 XenPCI_FilterAddResourceRequirements(WDFDEVICE Device, WDFIORESREQLIST RequirementsList);
55 static NTSTATUS
56 XenPCI_RemoveAddedResources(WDFDEVICE Device, WDFCMRESLIST ResourcesRaw, WDFCMRESLIST ResourcesTranslated);
58 static VOID
59 XenBus_ShutdownHandler(char *Path, PVOID Data);
60 static VOID
61 XenPCI_XenBusWatchHandler(char *Path, PVOID Data);
63 #ifdef ALLOC_PRAGMA
64 #pragma alloc_text (INIT, DriverEntry)
65 #pragma alloc_text (PAGE, XenPCI_AddDevice)
66 #endif
68 shared_info_t *shared_info_area;
69 static ULONG irqNumber = 0;
71 static BOOLEAN AutoEnumerate;
73 static WDFDEVICE Device;
75 NTSTATUS
76 DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
77 {
78 WDF_DRIVER_CONFIG config;
79 NTSTATUS status;
80 UNICODE_STRING RegKeyName;
81 UNICODE_STRING RegValueName;
82 HANDLE RegHandle;
83 OBJECT_ATTRIBUTES RegObjectAttributes;
84 char Buf[200];
85 ULONG BufLen = 200;
86 PKEY_VALUE_PARTIAL_INFORMATION KeyPartialValue;
87 int State = 0;
88 int StartPos = 0;
89 WCHAR *SystemStartOptions;
90 size_t SystemStartOptionsLen;
91 size_t i;
93 //KdPrint((__DRIVER_NAME " --> DriverEntry\n"));
95 RtlInitUnicodeString(&RegKeyName, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control");
96 InitializeObjectAttributes(&RegObjectAttributes, &RegKeyName, OBJ_CASE_INSENSITIVE, NULL, NULL);
97 status = ZwOpenKey(&RegHandle, KEY_READ, &RegObjectAttributes);
98 if(!NT_SUCCESS(status))
99 {
100 KdPrint((__DRIVER_NAME " ZwOpenKey returned %08x\n", status));
101 }
103 RtlInitUnicodeString(&RegValueName, L"SystemStartOptions");
104 status = ZwQueryValueKey(RegHandle, &RegValueName, KeyValuePartialInformation, Buf, BufLen, &BufLen);
105 if(!NT_SUCCESS(status))
106 {
107 KdPrint((__DRIVER_NAME " ZwQueryKeyValue returned %08x\n", status));
108 }
109 //KdPrint((__DRIVER_NAME " BufLen = %d\n", BufLen));
110 KeyPartialValue = (PKEY_VALUE_PARTIAL_INFORMATION)Buf;
111 KdPrint((__DRIVER_NAME " Buf = %ws\n", KeyPartialValue->Data));
112 SystemStartOptions = (WCHAR *)KeyPartialValue->Data;
114 AutoEnumerate = FALSE;
116 RtlStringCbLengthW(SystemStartOptions, KeyPartialValue->DataLength, &SystemStartOptionsLen);
118 for (i = 0; i <= SystemStartOptionsLen/2; i++)
119 {
120 //KdPrint((__DRIVER_NAME " pos = %d, state = %d, char = '%wc' (%d)\n", i, State, SystemStartOptions[i], SystemStartOptions[i]));
122 switch (State)
123 {
124 case 0:
125 if (SystemStartOptions[i] == L'G')
126 {
127 StartPos = i;
128 State = 2;
129 } else if (SystemStartOptions[i] != L' ')
130 {
131 State = 1;
132 }
133 break;
134 case 1:
135 if (SystemStartOptions[i] == L' ')
136 State = 0;
137 break;
138 case 2:
139 if (SystemStartOptions[i] == L'P')
140 State = 3;
141 else
142 State = 0;
143 break;
144 case 3:
145 if (SystemStartOptions[i] == L'L')
146 State = 4;
147 else
148 State = 0;
149 break;
150 case 4:
151 if (SystemStartOptions[i] == L'P')
152 State = 5;
153 else
154 State = 0;
155 break;
156 case 5:
157 if (SystemStartOptions[i] == L'V')
158 State = 6;
159 else
160 State = 0;
161 break;
162 case 6:
163 if (SystemStartOptions[i] == L' ' || SystemStartOptions[i] == 0)
164 AutoEnumerate = TRUE;
165 State = 0;
166 break;
167 }
168 }
170 KdPrint((__DRIVER_NAME " AutoEnumerate = %d\n", AutoEnumerate));
173 WDF_DRIVER_CONFIG_INIT(&config, XenPCI_AddDevice);
174 status = WdfDriverCreate(
175 DriverObject,
176 RegistryPath,
177 WDF_NO_OBJECT_ATTRIBUTES,
178 &config,
179 WDF_NO_HANDLE);
180 if(!NT_SUCCESS(status))
181 {
182 //KdPrint((__DRIVER_NAME " WdfDriverCreate failed with status 0x%08x\n", status));
183 }
185 //KdPrint((__DRIVER_NAME " <-- DriverEntry\n"));
187 return status;
188 }
190 static void WRMSR(unsigned int msr, ULONGLONG val)
191 {
192 ULONG lo, hi;
193 lo = (ULONG)val;
194 hi = (ULONG)(val >> 32);
195 __asm {
196 mov ecx, msr
197 mov eax, lo
198 mov edx, hi
199 wrmsr
200 }
201 }
203 static int
204 get_hypercall_stubs()
205 {
206 DWORD32 cpuid_output[4];
207 char xensig[13];
208 ULONG i;
209 ULONG pages;
210 ULONG msr;
212 __cpuid(cpuid_output, 0x40000000);
213 *(ULONG*)(xensig + 0) = cpuid_output[1];
214 *(ULONG*)(xensig + 4) = cpuid_output[2];
215 *(ULONG*)(xensig + 8) = cpuid_output[3];
216 xensig[12] = '\0';
217 KdPrint((__DRIVER_NAME " Xen Signature = %s, EAX = 0x%08x\n", xensig, cpuid_output[0]));
219 __cpuid(cpuid_output, 0x40000002);
220 pages = cpuid_output[0];
221 msr = cpuid_output[1];
222 //KdPrint((__DRIVER_NAME " Hypercall area is %u pages.\n", pages));
224 hypercall_stubs = ExAllocatePoolWithTag(NonPagedPool, pages * PAGE_SIZE, XENPCI_POOL_TAG);
225 //KdPrint((__DRIVER_NAME " Hypercall area at %08x\n", hypercall_stubs));
227 if (hypercall_stubs == NULL)
228 return 1;
229 for (i = 0; i < pages; i++) {
230 ULONG pfn;
231 //pfn = vmalloc_to_pfn((char *)hypercall_stubs + i * PAGE_SIZE);
232 pfn = (ULONG)(MmGetPhysicalAddress(hypercall_stubs + i * PAGE_SIZE).QuadPart >> PAGE_SHIFT);
233 //KdPrint((__DRIVER_NAME " pfn = %08X\n", pfn));
234 WRMSR(msr, ((ULONGLONG)pfn << PAGE_SHIFT) + i);
235 }
236 return STATUS_SUCCESS;
237 }
239 static ULONG PciBusNumber;
240 static USHORT PciFunctionNumber, PciDeviceNumber;
241 static USHORT PciPinNumber;
243 static WDFINTERRUPT XenInterrupt;
245 static PHYSICAL_ADDRESS platform_mmio_addr;
246 static ULONG platform_mmio_orig_len;
247 static ULONG platform_mmio_len;
248 static ULONG platform_mmio_alloc;
250 PHYSICAL_ADDRESS
251 XenPCI_AllocMMIO(ULONG len)
252 {
253 PHYSICAL_ADDRESS addr;
255 addr = platform_mmio_addr;
256 addr.QuadPart += platform_mmio_alloc;
257 platform_mmio_alloc += len;
259 return addr;
260 }
262 static int
263 init_xen_info()
264 {
265 struct xen_add_to_physmap xatp;
266 int ret;
267 PHYSICAL_ADDRESS shared_info_area_unmapped;
269 //setup_xen_features();
270 //KdPrint((__DRIVER_NAME " init_xen_info Hypercall area at %08x\n", hypercall_stubs));
272 shared_info_area_unmapped = XenPCI_AllocMMIO(PAGE_SIZE);
273 xatp.domid = DOMID_SELF;
274 xatp.idx = 0;
275 xatp.space = XENMAPSPACE_shared_info;
276 xatp.gpfn = (xen_pfn_t)(shared_info_area_unmapped.QuadPart >> PAGE_SHIFT);
277 ret = HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp);
278 //KdPrint((__DRIVER_NAME " ret = %d\n", ret));
280 shared_info_area = (shared_info_t *)MmMapIoSpace(shared_info_area_unmapped, PAGE_SIZE, MmNonCached);
282 return 0;
283 }
285 static PKINTERRUPT interrupt;
287 static int
288 set_callback_irq(ULONGLONG irq)
289 {
290 struct xen_hvm_param a;
291 int retval;
293 //KdPrint((__DRIVER_NAME " --> set_callback_irq\n"));
294 a.domid = DOMID_SELF;
295 a.index = HVM_PARAM_CALLBACK_IRQ;
296 a.value = irq;
297 retval = HYPERVISOR_hvm_op(HVMOP_set_param, &a);
298 //KdPrint((__DRIVER_NAME " HYPERVISOR_hvm_op retval = %d\n", retval));
299 //KdPrint((__DRIVER_NAME " <-- set_callback_irq\n"));
300 return retval;
301 }
303 static NTSTATUS
304 XenPCI_AddDevice(
305 IN WDFDRIVER Driver,
306 IN PWDFDEVICE_INIT DeviceInit
307 )
308 {
309 NTSTATUS status;
310 WDF_CHILD_LIST_CONFIG config;
311 PXENPCI_DEVICE_DATA devData = NULL;
312 WDF_OBJECT_ATTRIBUTES attributes;
313 WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;
314 WDF_IO_QUEUE_CONFIG ioQConfig;
315 WDF_INTERRUPT_CONFIG interruptConfig;
316 PNP_BUS_INFORMATION busInfo;
317 BUS_INTERFACE_STANDARD BusInterface;
318 WDFDEVICE Parent;
320 //PDEVICE_OBJECT pdo;
321 //ULONG propertyAddress, length;
323 UNREFERENCED_PARAMETER(Driver);
325 //KdPrint((__DRIVER_NAME " --> DeviceAdd\n"));
327 // get PDO
328 // get parent (should be PCI bus) (WdfPdoGetParent)
329 //
331 WdfDeviceInitSetDeviceType(DeviceInit, FILE_DEVICE_BUS_EXTENDER);
332 WDF_CHILD_LIST_CONFIG_INIT(&config, sizeof(XENPCI_IDENTIFICATION_DESCRIPTION), XenPCI_ChildListCreateDevice);
333 WdfFdoInitSetDefaultChildListConfig(DeviceInit, &config, WDF_NO_OBJECT_ATTRIBUTES);
335 // WDF_FDO_EVENT_CALLBACKS_INIT(&FdoCallbacks);
336 // FdoCallbacks.EvtDeviceFilterRemoveResourceRequirements = XenPCI_FilterRemoveResourceRequirements;
337 // FdoCallbacks.EvtDeviceFilterAddResourceRequirements = XenPCI_FilterAddResourceRequirements;
338 // FdoCallbacks.EvtDeviceRemoveAddedResources = XenPCI_RemoveAddedResources;
339 // WdfFdoInitSetEventCallbacks(DeviceInit, &FdoCallbacks);
341 /*set the callback functions that will be
342 executed on PNP and Power events*/
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,
359 &attributes, &Device);
360 if(!NT_SUCCESS(status))
361 {
362 KdPrint((__DRIVER_NAME " WdfDeviceCreate failed with status 0x%08x\n", status));
363 return status;
364 }
366 status = WdfFdoQueryForInterface(Device, &GUID_BUS_INTERFACE_STANDARD, (PINTERFACE) &BusInterface, sizeof(BUS_INTERFACE_STANDARD), 1, NULL);
367 if(!NT_SUCCESS(status))
368 {
369 KdPrint((__DRIVER_NAME " WdfFdoQueryForInterface (BusInterface) failed with status 0x%08x\n", status));
370 }
372 //BusInterface.GetBusData(NULL, PCI_WHICHSPACE_CONFIG, buf,
375 busInfo.BusTypeGuid = GUID_XENPCI_DEVCLASS;
376 busInfo.LegacyBusType = PNPBus;
377 busInfo.BusNumber = 0;
379 WdfDeviceSetBusInformationForChildren(Device, &busInfo);
381 /*create the default IO queue. this one will
382 be used for all requests*/
383 WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&ioQConfig,
384 WdfIoQueueDispatchSequential);
385 ioQConfig.EvtIoDefault = XenPCI_IoDefault;
386 status = WdfIoQueueCreate(Device, &ioQConfig,
387 WDF_NO_OBJECT_ATTRIBUTES,
388 &devData->IoDefaultQueue);
389 if(!NT_SUCCESS(status))
390 {
391 KdPrint((__DRIVER_NAME " WdfIoQueueCreate failed with status 0x%08x\n", status));
392 return status;
393 }
395 /*
396 status = WdfDeviceCreateDeviceInterface(Device, &GUID_INTERFACE_XENPCI, NULL);
397 if(!NT_SUCCESS(status))
398 {
399 KdPrint((__DRIVER_NAME "WdfDeviceCreateDeviceInterface failed with status 0x%08x\n", status));
400 return status;
401 }
402 */
404 WDF_INTERRUPT_CONFIG_INIT(&interruptConfig, EvtChn_Interrupt, NULL); //EvtChn_InterruptDpc);
405 interruptConfig.EvtInterruptEnable = XenPCI_InterruptEnable;
406 interruptConfig.EvtInterruptDisable = XenPCI_InterruptDisable;
407 status = WdfInterruptCreate(Device, &interruptConfig, WDF_NO_OBJECT_ATTRIBUTES, &XenInterrupt);
408 if (!NT_SUCCESS (status))
409 {
410 KdPrint((__DRIVER_NAME "WdfInterruptCreate failed 0x%08x\n", status));
411 return status;
412 }
414 //KdPrint((__DRIVER_NAME " <-- DeviceAdd\n"));
415 return status;
416 }
418 static NTSTATUS
419 XenPCI_PrepareHardware(
420 IN WDFDEVICE Device,
421 IN WDFCMRESLIST ResourceList,
422 IN WDFCMRESLIST ResourceListTranslated)
423 {
424 NTSTATUS status = STATUS_SUCCESS;
425 PCM_PARTIAL_RESOURCE_DESCRIPTOR descriptor;
426 ULONG i;
428 UNREFERENCED_PARAMETER(Device);
430 //KdPrint((__DRIVER_NAME " --> EvtDevicePrepareHardware\n"));
432 for (i = 0; i < WdfCmResourceListGetCount(ResourceList); i++)
433 {
434 descriptor = WdfCmResourceListGetDescriptor(ResourceList, i);
435 if(!descriptor)
436 continue;
437 switch (descriptor->Type)
438 {
439 case CmResourceTypeInterrupt:
440 irqNumber = descriptor->u.Interrupt.Vector;
441 break;
442 }
443 }
445 //KdPrint((__DRIVER_NAME " GSI = %d\n", irqNumber));
447 //KdPrint((__DRIVER_NAME " ResourceListTranslated\n"));
448 for (i = 0; i < WdfCmResourceListGetCount(ResourceListTranslated); i++)
449 {
450 descriptor = WdfCmResourceListGetDescriptor(ResourceListTranslated, i);
451 if(!descriptor)
452 {
453 KdPrint((__DRIVER_NAME " --> EvtDevicePrepareHardware (No descriptor)\n"));
454 return STATUS_DEVICE_CONFIGURATION_ERROR;
455 }
456 switch (descriptor->Type) {
457 case CmResourceTypePort:
458 //KdPrint((__DRIVER_NAME " I/O mapped CSR: (%x) Length: (%d)\n", descriptor->u.Port.Start.LowPart, descriptor->u.Port.Length));
459 // deviceData->IoBaseAddress = ULongToPtr(descriptor->u.Port.Start.LowPart);
460 // deviceData->IoRange = descriptor->u.Port.Length;
461 break;
462 case CmResourceTypeMemory:
463 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));
464 platform_mmio_addr = descriptor->u.Memory.Start; //(ULONG)MmMapIoSpace(descriptor->u.Memory.Start, descriptor->u.Memory.Length, MmNonCached);
465 platform_mmio_len = descriptor->u.Memory.Length;
466 platform_mmio_alloc = 0;
467 break;
468 case CmResourceTypeInterrupt:
469 //KdPrint((__DRIVER_NAME " Interrupt level: 0x%0x, Vector: 0x%0x\n", descriptor->u.Interrupt.Level, descriptor->u.Interrupt.Vector));
470 break;
471 case CmResourceTypeDevicePrivate:
472 //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] ));
473 break;
474 default:
475 //KdPrint((__DRIVER_NAME " Unhandled resource type (0x%x)\n", descriptor->Type));
476 break;
477 }
478 }
480 get_hypercall_stubs();
482 init_xen_info();
484 GntTbl_Init();
486 EvtChn_Init();
488 set_callback_irq(irqNumber);
490 XenBus_Init();
492 //KdPrint((__DRIVER_NAME " upcall_pending = %d\n", shared_info_area->vcpu_info[0].evtchn_upcall_pending));
494 shared_info_area->vcpu_info[0].evtchn_upcall_mask = 0;
496 //xen_reboot_init();
498 //KdPrint((__DRIVER_NAME " <-- EvtDevicePrepareHardware\n"));
500 return status;
501 }
503 static NTSTATUS
504 XenPCI_ReleaseHardware(WDFDEVICE Device, WDFCMRESLIST ResourcesTranslated)
505 {
506 UNREFERENCED_PARAMETER(Device);
507 UNREFERENCED_PARAMETER(ResourcesTranslated);
509 return STATUS_SUCCESS;
510 }
512 static NTSTATUS
513 XenPCI_D0Entry(
514 IN WDFDEVICE Device,
515 IN WDF_POWER_DEVICE_STATE PreviousState
516 )
517 {
518 NTSTATUS status = STATUS_SUCCESS;
520 UNREFERENCED_PARAMETER(Device);
521 UNREFERENCED_PARAMETER(PreviousState);
523 //KdPrint((__DRIVER_NAME " --> EvtDeviceD0Entry\n"));
525 //KdPrint((__DRIVER_NAME " <-- EvtDeviceD0Entry\n"));
527 return status;
528 }
530 static HANDLE ThreadHandle;
532 static NTSTATUS
533 XenPCI_D0EntryPostInterruptsEnabled(WDFDEVICE Device, WDF_POWER_DEVICE_STATE PreviousState)
534 {
535 NTSTATUS status = STATUS_SUCCESS;
536 //OBJECT_ATTRIBUTES oa;
537 char *response;
538 char *msgTypes;
539 char **Types;
540 int i;
541 char buffer[128];
543 UNREFERENCED_PARAMETER(Device);
544 UNREFERENCED_PARAMETER(PreviousState);
546 //KdPrint((__DRIVER_NAME " --> EvtDeviceD0EntryPostInterruptsEnabled\n"));
548 XenBus_Start();
550 //InitializeObjectAttributes(&oa, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
551 //status = PsCreateSystemThread(&ThreadHandle, THREAD_ALL_ACCESS, &oa, NULL, NULL, XenBus_ThreadProc, NULL);
552 //KdPrint((__DRIVER_NAME " PsCreateSystemThread returned %08X\n", status));
554 response = XenBus_AddWatch(XBT_NIL, SHUTDOWN_PATH, XenBus_ShutdownHandler, NULL);
555 //KdPrint((__DRIVER_NAME " shutdown watch response = '%s'\n", response));
557 response = XenBus_AddWatch(XBT_NIL, "device", XenPCI_XenBusWatchHandler, NULL);
558 //KdPrint((__DRIVER_NAME " device watch response = '%s'\n", response));
560 msgTypes = XenBus_List(XBT_NIL, "device", &Types);
561 if (!msgTypes) {
562 for (i = 0; Types[i]; i++)
563 {
564 RtlStringCbPrintfA(buffer, ARRAY_SIZE(buffer), "device/%s", Types[i]);
565 //KdPrint((__DRIVER_NAME " ls device[%d] -> %s\n", i, Types[i]));
566 XenPCI_XenBusWatchHandler(buffer, NULL);
567 ExFreePoolWithTag(Types[i], XENPCI_POOL_TAG);
568 }
569 }
570 // msgInstances = XenBus_List(XBT_NIL, buffer, &Instances);
571 // for (j = 0; Instances[j]; j++)
572 // {
573 // //KdPrint((__DRIVER_NAME " ls %s[%d] -> %s\n", buffer, j, Instances[j]));
574 //
575 // sprintf(buffer, "device/%s/%s", Types[i], Instances[j]);
576 //
577 //
578 // ExFreePoolWithTag(Instances[j], XENPCI_POOL_TAG);
579 // }
581 //KdPrint((__DRIVER_NAME " <-- EvtDeviceD0EntryPostInterruptsEnabled\n"));
583 return status;
584 }
586 static NTSTATUS
587 XenPCI_D0ExitPreInterruptsDisabled(WDFDEVICE Device, WDF_POWER_DEVICE_STATE TargetState)
588 {
589 NTSTATUS status = STATUS_SUCCESS;
591 UNREFERENCED_PARAMETER(Device);
592 UNREFERENCED_PARAMETER(TargetState);
594 XenBus_Stop();
596 return status;
597 }
599 static NTSTATUS
600 XenPCI_D0Exit(WDFDEVICE Device, WDF_POWER_DEVICE_STATE TargetState)
601 {
602 NTSTATUS status = STATUS_SUCCESS;
604 UNREFERENCED_PARAMETER(Device);
605 UNREFERENCED_PARAMETER(TargetState);
607 KdPrint((__DRIVER_NAME " --> EvtDeviceD0Exit\n"));
609 KdPrint((__DRIVER_NAME " <-- EvtDeviceD0Exit\n"));
611 return status;
612 }
614 static VOID
615 XenPCI_IoDefault(
616 IN WDFQUEUE Queue,
617 IN WDFREQUEST Request
618 )
619 {
620 UNREFERENCED_PARAMETER(Queue);
622 KdPrint((__DRIVER_NAME " --> EvtDeviceIoDefault\n"));
624 WdfRequestComplete(Request, STATUS_NOT_IMPLEMENTED);
626 KdPrint((__DRIVER_NAME " <-- EvtDeviceIoDefault\n"));
627 }
629 static NTSTATUS
630 XenPCI_InterruptEnable(WDFINTERRUPT Interrupt, WDFDEVICE AssociatedDevice)
631 {
632 UNREFERENCED_PARAMETER(Interrupt);
633 UNREFERENCED_PARAMETER(AssociatedDevice);
635 KdPrint((__DRIVER_NAME " --> EvtInterruptEnable\n"));
637 shared_info_area->vcpu_info[0].evtchn_upcall_mask = 0;
639 KdPrint((__DRIVER_NAME " <-- EvtInterruptEnable\n"));
641 return STATUS_SUCCESS;
642 }
644 static NTSTATUS
645 XenPCI_InterruptDisable(WDFINTERRUPT Interrupt, WDFDEVICE AssociatedDevice)
646 {
647 UNREFERENCED_PARAMETER(Interrupt);
648 UNREFERENCED_PARAMETER(AssociatedDevice);
650 //KdPrint((__DRIVER_NAME " --> EvtInterruptDisable\n"));
652 shared_info_area->vcpu_info[0].evtchn_upcall_mask = 1;
654 //KdPrint((__DRIVER_NAME " <-- EvtInterruptDisable\n"));
656 return STATUS_SUCCESS;
657 }
659 static NTSTATUS
660 XenPCI_ChildListCreateDevice(WDFCHILDLIST ChildList, PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER IdentificationDescription, PWDFDEVICE_INIT ChildInit)
661 {
662 NTSTATUS status;
663 WDFDEVICE ChildDevice = NULL;
664 PXENPCI_IDENTIFICATION_DESCRIPTION XenIdentificationDesc;
665 XEN_IFACE_EVTCHN EvtChnInterface;
666 XEN_IFACE_XENBUS XenBusInterface;
667 XEN_IFACE_XEN XenInterface;
668 XEN_IFACE_GNTTBL GntTblInterface;
669 //UNICODE_STRING DeviceId;
670 DECLARE_UNICODE_STRING_SIZE(buffer, 20);
671 WDF_OBJECT_ATTRIBUTES PdoAttributes;
672 DECLARE_CONST_UNICODE_STRING(DeviceLocation, L"Xen Bus");
673 WDF_QUERY_INTERFACE_CONFIG qiConfig;
674 //WDF_PDO_EVENT_CALLBACKS PdoCallbacks;
675 PXENPCI_XEN_DEVICE_DATA ChildDeviceData = NULL;
676 //size_t path_len;
678 UNREFERENCED_PARAMETER(ChildList);
680 //KdPrint((__DRIVER_NAME " --> ChildListCreateDevice\n"));
682 XenIdentificationDesc = CONTAINING_RECORD(IdentificationDescription, XENPCI_IDENTIFICATION_DESCRIPTION, Header);
684 //KdPrint((__DRIVER_NAME " Type = %wZ\n", &XenIdentificationDesc->DeviceType));
686 //DeviceInit = WdfPdoInitAllocate(Device);
687 WdfDeviceInitSetDeviceType(ChildInit, FILE_DEVICE_CONTROLLER);
689 status = RtlUnicodeStringPrintf(&buffer, L"Xen\\%wZ\0", &XenIdentificationDesc->DeviceType);
690 status = WdfPdoInitAssignDeviceID(ChildInit, &buffer);
691 status = WdfPdoInitAddHardwareID(ChildInit, &buffer);
692 status = WdfPdoInitAddCompatibleID(ChildInit, &buffer);
694 status = RtlUnicodeStringPrintf(&buffer, L"%02d", 0);
695 status = WdfPdoInitAssignInstanceID(ChildInit, &buffer);
697 status = RtlUnicodeStringPrintf( &buffer, L"%wZ", &XenIdentificationDesc->DeviceType);
698 status = WdfPdoInitAddDeviceText(ChildInit, &buffer, &DeviceLocation, 0x409);
700 WdfPdoInitSetDefaultLocale(ChildInit, 0x409);
702 WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&PdoAttributes, XENPCI_XEN_DEVICE_DATA);
704 // WDF_PDO_EVENT_CALLBACKS_INIT(&PdoCallbacks);
705 // PdoCallbacks.EvtDeviceResourceRequirementsQuery = XenPCI_DeviceResourceRequirementsQuery;
706 // WdfPdoInitSetEventCallbacks(ChildInit, &PdoCallbacks);
708 status = WdfDeviceCreate(&ChildInit, &PdoAttributes, &ChildDevice);
709 if (!NT_SUCCESS(status))
710 {
711 KdPrint((__DRIVER_NAME " WdfDeviceCreate status = %08X\n", status));
712 }
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 " --> HotPlugHandler\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 " <-- HotPlugHandler\n"));
852 }
854 static void
855 XenBus_ShutdownHandler(char *Path, PVOID StartContext)
856 {
857 char *value;
858 xenbus_transaction_t xbt;
859 int retry;
861 UNREFERENCED_PARAMETER(Path);
862 UNREFERENCED_PARAMETER(StartContext);
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 /*
882 IO_RESOURCE_DESCRIPTOR MemoryDescriptor;
884 static NTSTATUS
885 XenPCI_FilterRemoveResourceRequirements(WDFDEVICE Device, WDFIORESREQLIST RequirementsList)
886 {
887 NTSTATUS status;
888 WDFIORESLIST ResourceList;
889 PIO_RESOURCE_DESCRIPTOR Descriptor;
891 int i, j;
892 int offset;
894 //KdPrint((__DRIVER_NAME " --> FilterRemoveResourceRequirements\n"));
896 for (i = 0; i < WdfIoResourceRequirementsListGetCount(RequirementsList); i++)
897 {
898 ResourceList = WdfIoResourceRequirementsListGetIoResList(RequirementsList, i);
899 //KdPrint((__DRIVER_NAME " Resource List %d\n", i));
900 //KdPrint((__DRIVER_NAME " %d resources in list\n", WdfIoResourceListGetCount(ResourceList)));
901 offset = 0;
902 for (j = 0; j < WdfIoResourceListGetCount(ResourceList); j++)
903 {
904 //KdPrint((__DRIVER_NAME " Resource %d\n", j));
905 Descriptor = WdfIoResourceListGetDescriptor(ResourceList, j - offset);
907 switch (Descriptor->Type) {
908 case CmResourceTypePort:
909 //KdPrint((__DRIVER_NAME " Port\n"));
910 break;
911 case CmResourceTypeMemory:
912 //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));
913 //KdPrint((__DRIVER_NAME " Length %08X\n", Descriptor->u.Memory.Length));
914 //KdPrint((__DRIVER_NAME " ShareDisposition %02X\n", Descriptor->ShareDisposition));
915 //KdPrint((__DRIVER_NAME " Option %02X\n", Descriptor->Option));
916 if (!Descriptor->Option || Descriptor->Option == IO_RESOURCE_PREFERRED) {
917 memcpy(&MemoryDescriptor, Descriptor, sizeof(IO_RESOURCE_DESCRIPTOR));
918 //platform_mmio_orig_len = MemoryDescriptor.u.Memory.Length;
919 //MemoryDescriptor.u.Memory.Length = PAGE_SIZE;
920 MemoryDescriptor.ShareDisposition = CmResourceShareShared;
921 }
922 WdfIoResourceListRemove(ResourceList, j - offset);
923 offset++;
924 break;
925 case CmResourceTypeInterrupt:
926 //KdPrint((__DRIVER_NAME " Interrupt\n"));
927 break;
928 case CmResourceTypeDevicePrivate:
929 //KdPrint((__DRIVER_NAME " Private\n"));
930 break;
931 default:
932 //KdPrint((__DRIVER_NAME " Unknown Type (0x%x)\n", Descriptor->Type));
933 break;
934 }
935 }
936 }
937 status = STATUS_SUCCESS;
939 KdPrint((__DRIVER_NAME " <-- FilterRemoveResourceRequirements\n"));
941 return status;
942 }
944 static NTSTATUS
945 XenPCI_FilterAddResourceRequirements(WDFDEVICE Device, WDFIORESREQLIST RequirementsList)
946 {
947 NTSTATUS status;
948 WDFIORESLIST ResourceList;
949 PIO_RESOURCE_DESCRIPTOR Descriptor;
951 int i, j;
953 KdPrint((__DRIVER_NAME " --> FilterAddResourceRequirements\n"));
956 for (i = 0; i < WdfIoResourceRequirementsListGetCount(RequirementsList); i++)
957 {
958 ResourceList = WdfIoResourceRequirementsListGetIoResList(RequirementsList, i);
959 //KdPrint((__DRIVER_NAME " Resource List %d\n", i));
960 //KdPrint((__DRIVER_NAME " %d resources in list\n", WdfIoResourceListGetCount(ResourceList)));
961 WdfIoResourceListAppendDescriptor(ResourceList, &MemoryDescriptor);
962 //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));
963 //KdPrint((__DRIVER_NAME " Length %08X\n", MemoryDescriptor.u.Memory.Length));
964 for (j = 0; j < WdfIoResourceListGetCount(ResourceList); j++)
965 {
966 //KdPrint((__DRIVER_NAME " Resource %d\n", j));
967 Descriptor = WdfIoResourceListGetDescriptor(ResourceList, j);
969 switch (Descriptor->Type) {
970 case CmResourceTypePort:
971 //KdPrint((__DRIVER_NAME " Port\n"));
972 break;
973 case CmResourceTypeMemory:
974 //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));
975 //KdPrint((__DRIVER_NAME " Length %08X\n", Descriptor->u.Memory.Length));
976 //KdPrint((__DRIVER_NAME " ShareDisposition %02X\n", Descriptor->ShareDisposition));
977 //Descriptor->ShareDisposition = CmResourceShareShared;
978 //memcpy(&MemoryDescriptor, Descriptor, sizeof(IO_RESOURCE_DESCRIPTOR));
979 //platform_mmio_orig_len = MemoryDescriptor.u.Memory.Length;
980 //MemoryDescriptor.u.Memory.Length = PAGE_SIZE;
981 //WdfIoResourceListRemove(ResourceList, j);
982 break;
983 case CmResourceTypeInterrupt:
984 //KdPrint((__DRIVER_NAME " Interrupt\n"));
985 break;
986 case CmResourceTypeDevicePrivate:
987 //KdPrint((__DRIVER_NAME " Private\n"));
988 break;
989 default:
990 //KdPrint((__DRIVER_NAME " Unknown Type (0x%x)\n", Descriptor->Type));
991 break;
992 }
993 }
994 }
995 status = STATUS_SUCCESS;
997 //KdPrint((__DRIVER_NAME " <-- FilterAddResourceRequirements\n"));
999 return status;
1002 static NTSTATUS
1003 XenPCI_RemoveAddedResources(WDFDEVICE Device, WDFCMRESLIST ResourcesRaw, WDFCMRESLIST ResourcesTranslated)
1005 //KdPrint((__DRIVER_NAME " --> RemoveAddedResources\n"));
1006 //KdPrint((__DRIVER_NAME " <-- RemoveAddedResources\n"));
1008 return STATUS_SUCCESS;
1011 */
1013 static NTSTATUS
1014 XenPCI_DeviceResourceRequirementsQuery(WDFDEVICE Device, WDFIORESREQLIST IoResourceRequirementsList)
1016 NTSTATUS status;
1017 WDFIORESLIST resourceList;
1018 IO_RESOURCE_DESCRIPTOR descriptor;
1020 UNREFERENCED_PARAMETER(Device);
1022 //KdPrint((__DRIVER_NAME " --> DeviceResourceRequirementsQuery\n"));
1024 status = WdfIoResourceListCreate(IoResourceRequirementsList, WDF_NO_OBJECT_ATTRIBUTES, &resourceList);
1025 if (!NT_SUCCESS(status))
1026 return status;
1028 /*
1029 RtlZeroMemory(&descriptor, sizeof(descriptor));
1031 descriptor.Option = 0;
1032 descriptor.Type = CmResourceTypeInterrupt;
1033 descriptor.ShareDisposition = CmResourceShareDeviceExclusive;
1034 descriptor.Flags = CM_RESOURCE_MEMORY_READ_WRITE;
1035 descriptor.u.Interrupt.MinimumVector = 1024;
1036 descriptor.u.Interrupt.MaximumVector = 1024+255;
1038 //KdPrint((__DRIVER_NAME " MinimumVector = %d, MaximumVector = %d\n", descriptor.u.Interrupt.MinimumVector, descriptor.u.Interrupt.MaximumVector));
1040 status = WdfIoResourceListAppendDescriptor(resourceList, &descriptor);
1041 if (!NT_SUCCESS(status))
1042 return status;
1043 */
1045 RtlZeroMemory(&descriptor, sizeof(descriptor));
1047 descriptor.Option = 0;
1048 descriptor.Type = CmResourceTypeMemory;
1049 descriptor.ShareDisposition = CmResourceShareShared; //CmResourceShareDeviceExclusive;
1050 descriptor.Flags = CM_RESOURCE_MEMORY_READ_WRITE;
1051 descriptor.u.Memory.Length = PAGE_SIZE;
1052 descriptor.u.Memory.Alignment = PAGE_SIZE;
1053 descriptor.u.Memory.MinimumAddress.QuadPart = platform_mmio_addr.QuadPart + PAGE_SIZE;
1054 descriptor.u.Memory.MaximumAddress.QuadPart = platform_mmio_addr.QuadPart + platform_mmio_len - 1;
1056 //KdPrint((__DRIVER_NAME " MinimumAddress = %08x, MaximumAddress = %08X\n", descriptor.u.Memory.MinimumAddress.LowPart, descriptor.u.Memory.MaximumAddress.LowPart));
1058 status = WdfIoResourceListAppendDescriptor(resourceList, &descriptor);
1059 if (!NT_SUCCESS(status))
1060 return status;
1062 status = WdfIoResourceRequirementsListAppendIoResList(IoResourceRequirementsList, resourceList);
1063 if (!NT_SUCCESS(status))
1064 return status;
1066 //KdPrint((__DRIVER_NAME " <-- DeviceResourceRequirementsQuery\n"));
1068 return status;