win-pvdrivers

view xenpci/xenpci.c @ 71:0d06cc4c5fc9

Merged
author James Harper <james.harper@bendigoit.com.au>
date Thu Dec 20 10:57:59 2007 +1100 (2007-12-20)
parents 21502e79acc3 7ae8e22810a3
children f74723639713
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 VOID
45 XenPCI_IoRead(WDFQUEUE Queue, WDFREQUEST Request, size_t Length);
46 static NTSTATUS
47 XenPCI_InterruptEnable(WDFINTERRUPT Interrupt, WDFDEVICE AssociatedDevice);
48 static NTSTATUS
49 XenPCI_InterruptDisable(WDFINTERRUPT Interrupt, WDFDEVICE AssociatedDevice);
50 static NTSTATUS
51 XenPCI_ChildListCreateDevice(WDFCHILDLIST ChildList, PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER IdentificationDescription, PWDFDEVICE_INIT ChildInit);
52 static NTSTATUS
53 XenPCI_DeviceResourceRequirementsQuery(WDFDEVICE Device, WDFIORESREQLIST IoResourceRequirementsList);
54 static NTSTATUS
55 XenPCI_FilterRemoveResourceRequirements(WDFDEVICE Device, WDFIORESREQLIST IoResourceRequirementsList);
56 static NTSTATUS
57 XenPCI_FilterAddResourceRequirements(WDFDEVICE Device, WDFIORESREQLIST RequirementsList);
58 static NTSTATUS
59 XenPCI_RemoveAddedResources(WDFDEVICE Device, WDFCMRESLIST ResourcesRaw, WDFCMRESLIST ResourcesTranslated);
61 static VOID
62 XenBus_ShutdownHandler(char *Path, PVOID Data);
63 static VOID
64 XenBus_BalloonHandler(char *Path, PVOID Data);
65 static VOID
66 XenPCI_XenBusWatchHandler(char *Path, PVOID Data);
68 #ifdef ALLOC_PRAGMA
69 #pragma alloc_text (INIT, DriverEntry)
70 #pragma alloc_text (PAGE, XenPCI_AddDevice)
71 #endif
73 /* Global (driver-wide) variables */
74 static BOOLEAN AutoEnumerate;
75 static LIST_ENTRY ShutdownMsgList;
77 typedef struct {
78 LIST_ENTRY ListEntry;
79 ULONG Ptr;
80 // ULONG Len;
81 CHAR Buf[0];
82 } SHUTDOWN_MSG_ENTRY, *PSHUTDOWN_MSG_ENTRY;
84 static KSPIN_LOCK ShutdownMsgLock;
86 CM_PARTIAL_RESOURCE_DESCRIPTOR InterruptRaw;
87 CM_PARTIAL_RESOURCE_DESCRIPTOR InterruptTranslated;
89 NTSTATUS
90 DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
91 {
92 WDF_DRIVER_CONFIG config;
93 NTSTATUS status;
94 UNICODE_STRING RegKeyName;
95 UNICODE_STRING RegValueName;
96 HANDLE RegHandle;
97 OBJECT_ATTRIBUTES RegObjectAttributes;
98 char Buf[200];
99 ULONG BufLen = 200;
100 PKEY_VALUE_PARTIAL_INFORMATION KeyPartialValue;
101 int State = 0;
102 int StartPos = 0;
103 WCHAR *SystemStartOptions;
104 size_t SystemStartOptionsLen;
105 size_t i;
107 KdPrint((__DRIVER_NAME " --> DriverEntry\n"));
109 InitializeListHead(&ShutdownMsgList);
110 KeInitializeSpinLock(&ShutdownMsgLock);
112 RtlInitUnicodeString(&RegKeyName, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control");
113 InitializeObjectAttributes(&RegObjectAttributes, &RegKeyName, OBJ_CASE_INSENSITIVE, NULL, NULL);
114 status = ZwOpenKey(&RegHandle, KEY_READ, &RegObjectAttributes);
115 if(!NT_SUCCESS(status))
116 {
117 KdPrint((__DRIVER_NAME " ZwOpenKey returned %08x\n", status));
118 }
120 RtlInitUnicodeString(&RegValueName, L"SystemStartOptions");
121 status = ZwQueryValueKey(RegHandle, &RegValueName, KeyValuePartialInformation, Buf, BufLen, &BufLen);
122 if(!NT_SUCCESS(status))
123 {
124 KdPrint((__DRIVER_NAME " ZwQueryKeyValue returned %08x\n", status));
125 }
126 //KdPrint((__DRIVER_NAME " BufLen = %d\n", BufLen));
127 KeyPartialValue = (PKEY_VALUE_PARTIAL_INFORMATION)Buf;
128 KdPrint((__DRIVER_NAME " Buf = %ws\n", KeyPartialValue->Data));
129 SystemStartOptions = (WCHAR *)KeyPartialValue->Data;
131 AutoEnumerate = FALSE;
133 RtlStringCbLengthW(SystemStartOptions, KeyPartialValue->DataLength, &SystemStartOptionsLen);
135 for (i = 0; i <= SystemStartOptionsLen/2; i++)
136 {
137 //KdPrint((__DRIVER_NAME " pos = %d, state = %d, char = '%wc' (%d)\n", i, State, SystemStartOptions[i], SystemStartOptions[i]));
139 switch (State)
140 {
141 case 0:
142 if (SystemStartOptions[i] == L'G')
143 {
144 StartPos = i;
145 State = 2;
146 } else if (SystemStartOptions[i] != L' ')
147 {
148 State = 1;
149 }
150 break;
151 case 1:
152 if (SystemStartOptions[i] == L' ')
153 State = 0;
154 break;
155 case 2:
156 if (SystemStartOptions[i] == L'P')
157 State = 3;
158 else
159 State = 0;
160 break;
161 case 3:
162 if (SystemStartOptions[i] == L'L')
163 State = 4;
164 else
165 State = 0;
166 break;
167 case 4:
168 if (SystemStartOptions[i] == L'P')
169 State = 5;
170 else
171 State = 0;
172 break;
173 case 5:
174 if (SystemStartOptions[i] == L'V')
175 State = 6;
176 else
177 State = 0;
178 break;
179 case 6:
180 if (SystemStartOptions[i] == L' ' || SystemStartOptions[i] == 0)
181 AutoEnumerate = TRUE;
182 State = 0;
183 break;
184 }
185 }
187 KdPrint((__DRIVER_NAME " AutoEnumerate = %d\n", AutoEnumerate));
189 WDF_DRIVER_CONFIG_INIT(&config, XenPCI_AddDevice);
190 status = WdfDriverCreate(
191 DriverObject,
192 RegistryPath,
193 WDF_NO_OBJECT_ATTRIBUTES,
194 &config,
195 WDF_NO_HANDLE);
196 if(!NT_SUCCESS(status))
197 {
198 KdPrint((__DRIVER_NAME " WdfDriverCreate failed with status 0x%08x\n", status));
199 }
201 KdPrint((__DRIVER_NAME " <-- DriverEntry\n"));
203 return status;
204 }
206 static NTSTATUS
207 get_hypercall_stubs(WDFDEVICE Device)
208 {
209 PXENPCI_DEVICE_DATA xpdd = GetDeviceData(Device);
210 DWORD32 cpuid_output[4];
211 char xensig[13];
212 ULONG i;
213 ULONG pages;
214 ULONG msr;
216 __cpuid(cpuid_output, 0x40000000);
217 *(ULONG*)(xensig + 0) = cpuid_output[1];
218 *(ULONG*)(xensig + 4) = cpuid_output[2];
219 *(ULONG*)(xensig + 8) = cpuid_output[3];
220 xensig[12] = '\0';
221 KdPrint((__DRIVER_NAME " Xen Signature = %s, EAX = 0x%08x\n", xensig, cpuid_output[0]));
223 __cpuid(cpuid_output, 0x40000002);
224 pages = cpuid_output[0];
225 msr = cpuid_output[1];
226 //KdPrint((__DRIVER_NAME " Hypercall area is %u pages.\n", pages));
228 xpdd->hypercall_stubs = ExAllocatePoolWithTag(NonPagedPool, pages * PAGE_SIZE, XENPCI_POOL_TAG);
229 //KdPrint((__DRIVER_NAME " Hypercall area at %08x\n", hypercall_stubs));
231 if (!xpdd->hypercall_stubs)
232 return 1;
233 for (i = 0; i < pages; i++) {
234 ULONG pfn;
235 //pfn = vmalloc_to_pfn((char *)hypercall_stubs + i * PAGE_SIZE);
236 pfn = (ULONG)(MmGetPhysicalAddress(xpdd->hypercall_stubs + i * PAGE_SIZE).QuadPart >> PAGE_SHIFT);
237 //KdPrint((__DRIVER_NAME " pfn = %08X\n", pfn));
238 __writemsr(msr, ((ULONGLONG)pfn << PAGE_SHIFT) + i);
239 }
240 return STATUS_SUCCESS;
241 }
243 PHYSICAL_ADDRESS
244 XenPCI_AllocMMIO(WDFDEVICE Device, ULONG len)
245 {
246 PXENPCI_DEVICE_DATA xpdd = GetDeviceData(Device);
248 PHYSICAL_ADDRESS addr;
250 addr = xpdd->platform_mmio_addr;
251 addr.QuadPart += xpdd->platform_mmio_alloc;
252 xpdd->platform_mmio_alloc += len;
254 return addr;
255 }
257 static int
258 init_xen_info(WDFDEVICE Device)
259 {
260 PXENPCI_DEVICE_DATA xpdd = GetDeviceData(Device);
261 struct xen_add_to_physmap xatp;
262 int ret;
263 PHYSICAL_ADDRESS shared_info_area_unmapped;
265 //setup_xen_features();
266 //KdPrint((__DRIVER_NAME " init_xen_info Hypercall area at %08x\n", hypercall_stubs));
268 shared_info_area_unmapped = XenPCI_AllocMMIO(Device, PAGE_SIZE);
269 xatp.domid = DOMID_SELF;
270 xatp.idx = 0;
271 xatp.space = XENMAPSPACE_shared_info;
272 xatp.gpfn = (xen_pfn_t)(shared_info_area_unmapped.QuadPart >> PAGE_SHIFT);
273 ret = HYPERVISOR_memory_op(Device, XENMEM_add_to_physmap, &xatp);
274 //KdPrint((__DRIVER_NAME " ret = %d\n", ret));
276 xpdd->shared_info_area = MmMapIoSpace(shared_info_area_unmapped,
277 PAGE_SIZE, MmNonCached);
279 return 0;
280 }
282 static int
283 set_callback_irq(WDFDEVICE Device, ULONGLONG irq)
284 {
285 struct xen_hvm_param a;
286 int retval;
288 //KdPrint((__DRIVER_NAME " --> set_callback_irq\n"));
289 a.domid = DOMID_SELF;
290 a.index = HVM_PARAM_CALLBACK_IRQ;
291 a.value = irq;
292 retval = HYPERVISOR_hvm_op(Device, HVMOP_set_param, &a);
293 //KdPrint((__DRIVER_NAME " HYPERVISOR_hvm_op retval = %d\n", retval));
294 //KdPrint((__DRIVER_NAME " <-- set_callback_irq\n"));
295 return retval;
296 }
298 WDFQUEUE ReadQueue;
300 static NTSTATUS
301 XenPCI_AddDevice(
302 IN WDFDRIVER Driver,
303 IN PWDFDEVICE_INIT DeviceInit
304 )
305 {
306 NTSTATUS Status;
307 WDF_CHILD_LIST_CONFIG config;
308 WDF_OBJECT_ATTRIBUTES attributes;
309 WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;
310 WDF_IO_QUEUE_CONFIG IoQConfig;
311 WDF_INTERRUPT_CONFIG InterruptConfig;
312 PNP_BUS_INFORMATION busInfo;
313 BUS_INTERFACE_STANDARD BusInterface;
314 DECLARE_CONST_UNICODE_STRING(DeviceName, L"\\Device\\XenShutdown");
315 DECLARE_CONST_UNICODE_STRING(SymbolicName, L"\\DosDevices\\XenShutdown");
316 WDFDEVICE Device;
317 PXENPCI_DEVICE_DATA xpdd;
319 UNREFERENCED_PARAMETER(Driver);
321 KdPrint((__DRIVER_NAME " --> DeviceAdd\n"));
323 WdfDeviceInitSetDeviceType(DeviceInit, FILE_DEVICE_BUS_EXTENDER);
324 WDF_CHILD_LIST_CONFIG_INIT(&config, sizeof(XENPCI_IDENTIFICATION_DESCRIPTION), XenPCI_ChildListCreateDevice);
325 WdfFdoInitSetDefaultChildListConfig(DeviceInit, &config, WDF_NO_OBJECT_ATTRIBUTES);
327 WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);
328 pnpPowerCallbacks.EvtDevicePrepareHardware = XenPCI_PrepareHardware;
329 pnpPowerCallbacks.EvtDeviceReleaseHardware = XenPCI_ReleaseHardware;
330 pnpPowerCallbacks.EvtDeviceD0Entry = XenPCI_D0Entry;
331 pnpPowerCallbacks.EvtDeviceD0EntryPostInterruptsEnabled
332 = XenPCI_D0EntryPostInterruptsEnabled;
333 pnpPowerCallbacks.EvtDeviceD0ExitPreInterruptsDisabled
334 = XenPCI_D0ExitPreInterruptsDisabled;
335 pnpPowerCallbacks.EvtDeviceD0Exit = XenPCI_D0Exit;
336 WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);
338 WdfDeviceInitSetIoType(DeviceInit, WdfDeviceIoBuffered);
340 Status = WdfDeviceInitAssignName(DeviceInit, &DeviceName);
341 if (!NT_SUCCESS(Status))
342 {
343 KdPrint((__DRIVER_NAME " WdfDeviceInitAssignName failed 0x%08x\n", Status));
344 return Status;
345 }
347 /*initialize storage for the device context*/
348 WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, XENPCI_DEVICE_DATA);
350 /*create a device instance.*/
351 Status = WdfDeviceCreate(&DeviceInit, &attributes, &Device);
352 if(!NT_SUCCESS(Status))
353 {
354 KdPrint((__DRIVER_NAME " WdfDeviceCreate failed with Status 0x%08x\n", Status));
355 return Status;
356 }
357 xpdd = GetDeviceData(Device);
358 xpdd->Device = Device;
360 WdfDeviceSetSpecialFileSupport(Device, WdfSpecialFilePaging, TRUE);
361 WdfDeviceSetSpecialFileSupport(Device, WdfSpecialFileHibernation, TRUE);
362 WdfDeviceSetSpecialFileSupport(Device, WdfSpecialFileDump, TRUE);
364 Status = WdfFdoQueryForInterface(Device, &GUID_BUS_INTERFACE_STANDARD, (PINTERFACE) &BusInterface, sizeof(BUS_INTERFACE_STANDARD), 1, NULL);
365 if(!NT_SUCCESS(Status))
366 {
367 KdPrint((__DRIVER_NAME " WdfFdoQueryForInterface (BusInterface) failed with Status 0x%08x\n", Status));
368 }
370 busInfo.BusTypeGuid = GUID_XENPCI_DEVCLASS;
371 busInfo.LegacyBusType = Internal;
372 busInfo.BusNumber = 0;
374 WdfDeviceSetBusInformationForChildren(Device, &busInfo);
376 WDF_INTERRUPT_CONFIG_INIT(&InterruptConfig, EvtChn_Interrupt, EvtChn_InterruptDpc);
377 InterruptConfig.EvtInterruptEnable = XenPCI_InterruptEnable;
378 InterruptConfig.EvtInterruptDisable = XenPCI_InterruptDisable;
379 Status = WdfInterruptCreate(Device, &InterruptConfig, WDF_NO_OBJECT_ATTRIBUTES, &xpdd->XenInterrupt);
380 if (!NT_SUCCESS (Status))
381 {
382 KdPrint((__DRIVER_NAME " WdfInterruptCreate failed 0x%08x\n", Status));
383 return Status;
384 }
386 Status = WdfDeviceCreateDeviceInterface(Device, (LPGUID)&GUID_XEN_IFACE_XEN, NULL);
387 if (!NT_SUCCESS(Status))
388 {
389 KdPrint((__DRIVER_NAME " WdfDeviceCreateDeviceInterface failed 0x%08x\n", Status));
390 return Status;
391 }
392 WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&IoQConfig, WdfIoQueueDispatchSequential);
393 IoQConfig.EvtIoDefault = XenPCI_IoDefault;
395 Status = WdfIoQueueCreate(Device, &IoQConfig, WDF_NO_OBJECT_ATTRIBUTES, NULL);
396 if (!NT_SUCCESS(Status))
397 {
398 KdPrint((__DRIVER_NAME " WdfIoQueueCreate failed 0x%08x\n", Status));
399 return Status;
400 }
402 WDF_IO_QUEUE_CONFIG_INIT(&IoQConfig, WdfIoQueueDispatchSequential);
403 IoQConfig.EvtIoRead = XenPCI_IoRead;
405 Status = WdfIoQueueCreate(Device, &IoQConfig, WDF_NO_OBJECT_ATTRIBUTES, &ReadQueue);
406 if (!NT_SUCCESS(Status))
407 {
408 KdPrint((__DRIVER_NAME " WdfIoQueueCreate (ReadQueue) failed 0x%08x\n", Status));
409 switch (Status)
410 {
411 case STATUS_INVALID_PARAMETER:
412 KdPrint((__DRIVER_NAME " STATUS_INVALID_PARAMETER\n"));
413 break;
414 case STATUS_INFO_LENGTH_MISMATCH:
415 KdPrint((__DRIVER_NAME " STATUS_INFO_LENGTH_MISMATCH\n"));
416 break;
417 case STATUS_POWER_STATE_INVALID:
418 KdPrint((__DRIVER_NAME " STATUS_POWER_STATE_INVALID\n"));
419 break;
420 case STATUS_INSUFFICIENT_RESOURCES:
421 KdPrint((__DRIVER_NAME " STATUS_INSUFFICIENT_RESOURCES\n"));
422 break;
423 case STATUS_WDF_NO_CALLBACK:
424 KdPrint((__DRIVER_NAME " STATUS_WDF_NO_CALLBACK\n"));
425 break;
426 case STATUS_UNSUCCESSFUL:
427 KdPrint((__DRIVER_NAME " STATUS_UNSUCCESSFUL\n"));
428 break;
429 }
430 return Status;
431 }
432 WdfIoQueueStopSynchronously(ReadQueue);
433 WdfDeviceConfigureRequestDispatching(Device, ReadQueue, WdfRequestTypeRead);
435 Status = WdfDeviceCreateSymbolicLink(Device, &SymbolicName);
436 if (!NT_SUCCESS(Status))
437 {
438 KdPrint((__DRIVER_NAME " WdfDeviceCreateSymbolicLink failed 0x%08x\n", Status));
439 return Status;
440 }
442 KdPrint((__DRIVER_NAME " <-- DeviceAdd\n"));
443 return Status;
444 }
446 static NTSTATUS
447 XenPCI_PrepareHardware(
448 IN WDFDEVICE Device,
449 IN WDFCMRESLIST ResourceList,
450 IN WDFCMRESLIST ResourceListTranslated)
451 {
452 NTSTATUS status = STATUS_SUCCESS;
453 PCM_PARTIAL_RESOURCE_DESCRIPTOR descriptor;
454 ULONG i;
455 PXENPCI_DEVICE_DATA xpdd = GetDeviceData(Device);
457 KdPrint((__DRIVER_NAME " --> EvtDevicePrepareHardware\n"));
459 for (i = 0; i < WdfCmResourceListGetCount(ResourceList); i++)
460 {
461 descriptor = WdfCmResourceListGetDescriptor(ResourceList, i);
462 if(!descriptor)
463 continue;
464 switch (descriptor->Type)
465 {
466 case CmResourceTypeInterrupt:
467 xpdd->irqNumber = descriptor->u.Interrupt.Vector;
468 break;
469 }
470 }
472 //KdPrint((__DRIVER_NAME " GSI = %d\n", irqNumber));
474 //KdPrint((__DRIVER_NAME " ResourceListTranslated\n"));
475 for (i = 0; i < WdfCmResourceListGetCount(ResourceListTranslated); i++)
476 {
477 descriptor = WdfCmResourceListGetDescriptor(ResourceListTranslated, i);
478 if(!descriptor)
479 {
480 KdPrint((__DRIVER_NAME " --> EvtDevicePrepareHardware (No descriptor)\n"));
481 return STATUS_DEVICE_CONFIGURATION_ERROR;
482 }
483 switch (descriptor->Type) {
484 case CmResourceTypePort:
485 //KdPrint((__DRIVER_NAME " I/O mapped CSR: (%x) Length: (%d)\n", descriptor->u.Port.Start.LowPart, descriptor->u.Port.Length));
486 break;
487 case CmResourceTypeMemory:
488 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));
489 xpdd->platform_mmio_addr = descriptor->u.Memory.Start; //(ULONG)MmMapIoSpace(descriptor->u.Memory.Start, descriptor->u.Memory.Length, MmNonCached);
490 xpdd->platform_mmio_len = descriptor->u.Memory.Length;
491 xpdd->platform_mmio_alloc = 0;
492 break;
493 case CmResourceTypeInterrupt:
494 //KdPrint((__DRIVER_NAME " Interrupt level: 0x%0x, Vector: 0x%0x\n", descriptor->u.Interrupt.Level, descriptor->u.Interrupt.Vector));
495 memcpy(&InterruptRaw, WdfCmResourceListGetDescriptor(ResourceList, i), sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
496 memcpy(&InterruptTranslated, WdfCmResourceListGetDescriptor(ResourceListTranslated, i), sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
497 break;
498 case CmResourceTypeDevicePrivate:
499 //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] ));
500 break;
501 default:
502 //KdPrint((__DRIVER_NAME " Unhandled resource type (0x%x)\n", descriptor->Type));
503 break;
504 }
505 }
507 get_hypercall_stubs(Device);
509 init_xen_info(Device);
511 GntTbl_Init(Device);
513 EvtChn_Init(Device);
515 set_callback_irq(Device, xpdd->irqNumber);
517 XenBus_Init(Device);
519 //KdPrint((__DRIVER_NAME " upcall_pending = %d\n", shared_info_area->vcpu_info[0].evtchn_upcall_pending));
521 xpdd->shared_info_area->vcpu_info[0].evtchn_upcall_mask = 0;
523 //xen_reboot_init();
525 KdPrint((__DRIVER_NAME " <-- EvtDevicePrepareHardware\n"));
527 return status;
528 }
530 static NTSTATUS
531 XenPCI_ReleaseHardware(WDFDEVICE Device, WDFCMRESLIST ResourcesTranslated)
532 {
533 UNREFERENCED_PARAMETER(Device);
534 UNREFERENCED_PARAMETER(ResourcesTranslated);
536 return STATUS_SUCCESS;
537 }
539 static NTSTATUS
540 XenPCI_D0Entry(
541 IN WDFDEVICE Device,
542 IN WDF_POWER_DEVICE_STATE PreviousState
543 )
544 {
545 NTSTATUS status = STATUS_SUCCESS;
547 UNREFERENCED_PARAMETER(Device);
548 UNREFERENCED_PARAMETER(PreviousState);
550 KdPrint((__DRIVER_NAME " --> EvtDeviceD0Entry\n"));
552 KdPrint((__DRIVER_NAME " <-- EvtDeviceD0Entry\n"));
554 return status;
555 }
557 static NTSTATUS
558 XenPCI_D0EntryPostInterruptsEnabled(WDFDEVICE Device, WDF_POWER_DEVICE_STATE PreviousState)
559 {
560 NTSTATUS status = STATUS_SUCCESS;
561 //OBJECT_ATTRIBUTES oa;
562 char *response;
563 char *msgTypes;
564 char **Types;
565 int i;
566 char buffer[128];
568 UNREFERENCED_PARAMETER(PreviousState);
570 KdPrint((__DRIVER_NAME " --> EvtDeviceD0EntryPostInterruptsEnabled\n"));
572 XenBus_Start(Device);
574 KdPrint((__DRIVER_NAME " A\n"));
576 response = XenBus_AddWatch(Device, XBT_NIL, SHUTDOWN_PATH, XenBus_ShutdownHandler, Device);
577 KdPrint((__DRIVER_NAME " shutdown watch response = '%s'\n", response));
579 response = XenBus_AddWatch(Device, XBT_NIL, BALLOON_PATH, XenBus_BalloonHandler, Device);
580 KdPrint((__DRIVER_NAME " shutdown watch response = '%s'\n", response));
582 response = XenBus_AddWatch(Device, XBT_NIL, "device", XenPCI_XenBusWatchHandler, Device);
583 KdPrint((__DRIVER_NAME " device watch response = '%s'\n", response));
585 msgTypes = XenBus_List(Device, XBT_NIL, "device", &Types);
586 if (!msgTypes) {
587 for (i = 0; Types[i]; i++)
588 {
589 RtlStringCbPrintfA(buffer, ARRAY_SIZE(buffer), "device/%s", Types[i]);
590 //KdPrint((__DRIVER_NAME " ls device[%d] -> %s\n", i, Types[i]));
591 XenPCI_XenBusWatchHandler(buffer, Device);
592 ExFreePoolWithTag(Types[i], XENPCI_POOL_TAG);
593 }
594 }
595 KdPrint((__DRIVER_NAME " <-- EvtDeviceD0EntryPostInterruptsEnabled\n"));
597 return status;
598 }
600 static NTSTATUS
601 XenPCI_D0ExitPreInterruptsDisabled(WDFDEVICE Device, WDF_POWER_DEVICE_STATE TargetState)
602 {
603 NTSTATUS status = STATUS_SUCCESS;
605 UNREFERENCED_PARAMETER(TargetState);
607 KdPrint((__DRIVER_NAME " --> D0ExitPreInterruptsDisabled\n"));
609 XenBus_Stop(Device);
611 KdPrint((__DRIVER_NAME " <-- D0ExitPreInterruptsDisabled\n"));
613 return status;
614 }
616 static NTSTATUS
617 XenPCI_D0Exit(WDFDEVICE Device, WDF_POWER_DEVICE_STATE TargetState)
618 {
619 NTSTATUS status = STATUS_SUCCESS;
621 UNREFERENCED_PARAMETER(Device);
622 UNREFERENCED_PARAMETER(TargetState);
624 KdPrint((__DRIVER_NAME " --> DeviceD0Exit\n"));
626 XenBus_Close(Device);
628 KdPrint((__DRIVER_NAME " <-- DeviceD0Exit\n"));
630 return status;
631 }
633 static VOID
634 XenPCI_IoDefault(
635 IN WDFQUEUE Queue,
636 IN WDFREQUEST Request
637 )
638 {
639 UNREFERENCED_PARAMETER(Queue);
641 KdPrint((__DRIVER_NAME " --> EvtDeviceIoDefault\n"));
643 WdfRequestComplete(Request, STATUS_NOT_IMPLEMENTED);
645 KdPrint((__DRIVER_NAME " <-- EvtDeviceIoDefault\n"));
646 }
649 static VOID
650 XenPCI_IoRead(WDFQUEUE Queue, WDFREQUEST Request, size_t Length)
651 {
652 PSHUTDOWN_MSG_ENTRY Entry;
653 ULONG Remaining;
654 ULONG CopyLen;
655 PCHAR Buffer;
656 size_t BufLen;
657 KIRQL OldIrql;
659 UNREFERENCED_PARAMETER(Queue);
660 UNREFERENCED_PARAMETER(Length);
662 KdPrint((__DRIVER_NAME " --> IoRead\n"));
664 WdfRequestRetrieveOutputBuffer(Request, 1, &Buffer, &BufLen);
666 KeAcquireSpinLock(&ShutdownMsgLock, &OldIrql);
668 Entry = (PSHUTDOWN_MSG_ENTRY)RemoveHeadList(&ShutdownMsgList);
670 if ((PLIST_ENTRY)Entry == &ShutdownMsgList)
671 {
672 KdPrint((__DRIVER_NAME " <-- IoRead (Nothing in queue... xenpci is now broken)\n"));
673 return;
674 }
676 Remaining = strlen(Entry->Buf + Entry->Ptr);
677 CopyLen = min(Remaining, BufLen);
679 memcpy(Buffer, Entry->Buf + Entry->Ptr, CopyLen);
681 if (Entry->Buf[Entry->Ptr] == 0)
682 {
683 KdPrint((__DRIVER_NAME " All done... stopping queue\n"));
684 if (IsListEmpty(&ShutdownMsgList))
685 WdfIoQueueStop(ReadQueue, NULL, NULL);
686 }
687 else
688 {
689 KdPrint((__DRIVER_NAME " More to do...\n"));
690 Entry->Ptr += CopyLen;
691 InsertHeadList(&ShutdownMsgList, &Entry->ListEntry);
692 }
694 KeReleaseSpinLock(&ShutdownMsgLock, OldIrql);
696 WdfRequestCompleteWithInformation(Request, STATUS_SUCCESS, CopyLen);
698 KdPrint((__DRIVER_NAME " <-- IoRead\n"));
699 }
702 static NTSTATUS
703 XenPCI_InterruptEnable(WDFINTERRUPT Interrupt, WDFDEVICE AssociatedDevice)
704 {
705 PXENPCI_DEVICE_DATA xpdd = GetDeviceData(AssociatedDevice);
707 UNREFERENCED_PARAMETER(Interrupt);
709 KdPrint((__DRIVER_NAME " --> EvtInterruptEnable\n"));
711 xpdd->shared_info_area->vcpu_info[0].evtchn_upcall_mask = 0;
713 KdPrint((__DRIVER_NAME " <-- EvtInterruptEnable\n"));
715 return STATUS_SUCCESS;
716 }
718 static NTSTATUS
719 XenPCI_InterruptDisable(WDFINTERRUPT Interrupt, WDFDEVICE AssociatedDevice)
720 {
721 PXENPCI_DEVICE_DATA xpdd = GetDeviceData(AssociatedDevice);
723 UNREFERENCED_PARAMETER(Interrupt);
725 //KdPrint((__DRIVER_NAME " --> EvtInterruptDisable\n"));
727 xpdd->shared_info_area->vcpu_info[0].evtchn_upcall_mask = 1;
728 // should we kick off any pending interrupts here?
730 //KdPrint((__DRIVER_NAME " <-- EvtInterruptDisable\n"));
732 return STATUS_SUCCESS;
733 }
735 static NTSTATUS
736 XenPCI_ChildListCreateDevice(
737 WDFCHILDLIST ChildList,
738 PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER IdentificationDescription,
739 PWDFDEVICE_INIT ChildInit)
740 {
741 NTSTATUS status;
742 WDFDEVICE ChildDevice = NULL;
743 PXENPCI_IDENTIFICATION_DESCRIPTION XenIdentificationDesc;
744 DECLARE_UNICODE_STRING_SIZE(buffer, 20);
745 WDF_OBJECT_ATTRIBUTES PdoAttributes;
746 DECLARE_CONST_UNICODE_STRING(DeviceLocation, L"Xen Bus");
747 WDF_QUERY_INTERFACE_CONFIG qiConfig;
748 PXENPCI_XEN_DEVICE_DATA ChildDeviceData = NULL;
750 UNREFERENCED_PARAMETER(ChildList);
752 //KdPrint((__DRIVER_NAME " --> ChildListCreateDevice\n"));
754 XenIdentificationDesc = CONTAINING_RECORD(IdentificationDescription, XENPCI_IDENTIFICATION_DESCRIPTION, Header);
756 //KdPrint((__DRIVER_NAME " Type = %wZ\n", &XenIdentificationDesc->DeviceType));
758 //DeviceInit = WdfPdoInitAllocate(Device);
759 WdfDeviceInitSetDeviceType(ChildInit, FILE_DEVICE_CONTROLLER);
761 status = RtlUnicodeStringPrintf(&buffer, L"Xen\\%wZ\0", &XenIdentificationDesc->DeviceType);
762 status = WdfPdoInitAssignDeviceID(ChildInit, &buffer);
763 status = WdfPdoInitAddHardwareID(ChildInit, &buffer);
764 status = WdfPdoInitAddCompatibleID(ChildInit, &buffer);
766 status = RtlUnicodeStringPrintf(&buffer, L"%02d", 0);
767 status = WdfPdoInitAssignInstanceID(ChildInit, &buffer);
769 status = RtlUnicodeStringPrintf( &buffer, L"%wZ", &XenIdentificationDesc->DeviceType);
770 status = WdfPdoInitAddDeviceText(ChildInit, &buffer, &DeviceLocation, 0x409);
772 WdfPdoInitSetDefaultLocale(ChildInit, 0x409);
774 WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&PdoAttributes, XENPCI_XEN_DEVICE_DATA);
776 // WDF_PDO_EVENT_CALLBACKS_INIT(&PdoCallbacks);
777 // PdoCallbacks.EvtDeviceResourceRequirementsQuery = XenPCI_DeviceResourceRequirementsQuery;
778 // WdfPdoInitSetEventCallbacks(ChildInit, &PdoCallbacks);
780 status = WdfDeviceCreate(&ChildInit, &PdoAttributes, &ChildDevice);
781 if (!NT_SUCCESS(status))
782 {
783 KdPrint((__DRIVER_NAME " WdfDeviceCreate status = %08X\n", status));
784 }
786 WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFilePaging, TRUE);
787 WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFileHibernation, TRUE);
788 WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFileDump, TRUE);
790 ChildDeviceData = GetXenDeviceData(ChildDevice);
791 ChildDeviceData->Magic = XEN_DATA_MAGIC;
792 ChildDeviceData->AutoEnumerate = AutoEnumerate;
793 ChildDeviceData->WatchHandler = NULL;
794 strncpy(ChildDeviceData->BasePath, XenIdentificationDesc->Path, 128);
795 memcpy(&ChildDeviceData->InterruptRaw, &InterruptRaw, sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
796 memcpy(&ChildDeviceData->InterruptTranslated, &InterruptTranslated, sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
798 ChildDeviceData->EvtChnInterface.InterfaceHeader.Size = sizeof(ChildDeviceData->EvtChnInterface);
799 ChildDeviceData->EvtChnInterface.InterfaceHeader.Version = 1;
800 ChildDeviceData->EvtChnInterface.InterfaceHeader.Context = WdfPdoGetParent(ChildDevice);
801 ChildDeviceData->EvtChnInterface.InterfaceHeader.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
802 ChildDeviceData->EvtChnInterface.InterfaceHeader.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
803 ChildDeviceData->EvtChnInterface.Bind = EvtChn_Bind;
804 ChildDeviceData->EvtChnInterface.Unbind = EvtChn_Unbind;
805 ChildDeviceData->EvtChnInterface.Mask = EvtChn_Mask;
806 ChildDeviceData->EvtChnInterface.Unmask = EvtChn_Unmask;
807 ChildDeviceData->EvtChnInterface.Notify = EvtChn_Notify;
808 ChildDeviceData->EvtChnInterface.AllocUnbound = EvtChn_AllocUnbound;
809 WDF_QUERY_INTERFACE_CONFIG_INIT(&qiConfig, (PINTERFACE)&ChildDeviceData->EvtChnInterface, &GUID_XEN_IFACE_EVTCHN, NULL);
810 status = WdfDeviceAddQueryInterface(ChildDevice, &qiConfig);
811 if (!NT_SUCCESS(status))
812 {
813 return status;
814 }
816 /*
817 ChildDeviceData->XenInterface.InterfaceHeader.Size = sizeof(ChildDeviceData->XenInterface);
818 ChildDeviceData->XenInterface.InterfaceHeader.Version = 1;
819 ChildDeviceData->XenInterface.InterfaceHeader.Context = NULL;
820 ChildDeviceData->XenInterface.InterfaceHeader.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
821 ChildDeviceData->XenInterface.InterfaceHeader.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
822 ChildDeviceData->XenInterface.AllocMMIO = XenPCI_AllocMMIO;
823 WDF_QUERY_INTERFACE_CONFIG_INIT(&qiConfig, (PINTERFACE)&ChildDeviceData->XenInterface, &GUID_XEN_IFACE_XEN, NULL);
824 status = WdfDeviceAddQueryInterface(ChildDevice, &qiConfig);
825 if (!NT_SUCCESS(status)) {
826 return status;
827 }
828 */
830 ChildDeviceData->GntTblInterface.InterfaceHeader.Size = sizeof(ChildDeviceData->GntTblInterface);
831 ChildDeviceData->GntTblInterface.InterfaceHeader.Version = 1;
832 ChildDeviceData->GntTblInterface.InterfaceHeader.Context = WdfPdoGetParent(ChildDevice);
833 ChildDeviceData->GntTblInterface.InterfaceHeader.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
834 ChildDeviceData->GntTblInterface.InterfaceHeader.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
835 ChildDeviceData->GntTblInterface.GrantAccess = GntTbl_GrantAccess;
836 ChildDeviceData->GntTblInterface.EndAccess = GntTbl_EndAccess;
837 WDF_QUERY_INTERFACE_CONFIG_INIT(&qiConfig, (PINTERFACE)&ChildDeviceData->GntTblInterface, &GUID_XEN_IFACE_GNTTBL, NULL);
838 status = WdfDeviceAddQueryInterface(ChildDevice, &qiConfig);
839 if (!NT_SUCCESS(status)) {
840 return status;
841 }
843 ChildDeviceData->XenBusInterface.InterfaceHeader.Size = sizeof(ChildDeviceData->XenBusInterface);
844 ChildDeviceData->XenBusInterface.InterfaceHeader.Version = 1;
845 ChildDeviceData->XenBusInterface.InterfaceHeader.Context = WdfPdoGetParent(ChildDevice);
846 //XenBusInterface.InterfaceHeader.Context = ExAllocatePoolWithTag(NonPagedPool, (strlen(XenIdentificationDesc->Path) + 1), XENPCI_POOL_TAG);
847 //strcpy(XenBusInterface.InterfaceHeader.Context, XenIdentificationDesc->Path);
848 ChildDeviceData->XenBusInterface.Read = XenBus_Read;
849 ChildDeviceData->XenBusInterface.Write = XenBus_Write;
850 ChildDeviceData->XenBusInterface.Printf = XenBus_Printf;
851 ChildDeviceData->XenBusInterface.StartTransaction = XenBus_StartTransaction;
852 ChildDeviceData->XenBusInterface.EndTransaction = XenBus_EndTransaction;
853 ChildDeviceData->XenBusInterface.List = XenBus_List;
854 ChildDeviceData->XenBusInterface.AddWatch = XenBus_AddWatch;
855 ChildDeviceData->XenBusInterface.RemWatch = XenBus_RemWatch;
856 WDF_QUERY_INTERFACE_CONFIG_INIT(&qiConfig, (PINTERFACE)&ChildDeviceData->XenBusInterface, &GUID_XEN_IFACE_XENBUS, NULL);
857 status = WdfDeviceAddQueryInterface(ChildDevice, &qiConfig);
858 if (!NT_SUCCESS(status)) {
859 return status;
860 }
862 //KdPrint((__DRIVER_NAME " <-- ChildListCreateDevice\n"));
864 return status;
865 }
867 VOID
868 XenPCI_XenBusWatchHandler(char *Path, PVOID Data)
869 {
870 XENPCI_IDENTIFICATION_DESCRIPTION description;
871 NTSTATUS status;
872 char **Bits;
873 int Count;
874 WDFDEVICE Device = Data;
875 WDFCHILDLIST ChildList;
876 WDF_CHILD_LIST_ITERATOR ChildIterator;
877 WDFDEVICE ChildDevice;
878 PXENPCI_XEN_DEVICE_DATA ChildDeviceData;
880 ANSI_STRING AnsiBuf;
882 UNREFERENCED_PARAMETER(Data);
884 KdPrint((__DRIVER_NAME " --> XenBusWatchHandler\n"));
886 //KdPrint((__DRIVER_NAME " %s\n", Path));
888 ChildList = WdfFdoGetDefaultChildList(Device);
890 Bits = SplitString(Path, '/', 3, &Count);
891 switch (Count)
892 {
893 case 0:
894 case 1:
895 break;
896 case 2:
897 // add or update the device node
898 WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER_INIT(&description.Header, sizeof(description));
899 strncpy(description.Path, Path, 128);
900 RtlInitAnsiString(&AnsiBuf, Bits[1]);
901 //KdPrint((__DRIVER_NAME " Name = %s\n", Bits[1]));
902 RtlAnsiStringToUnicodeString(&description.DeviceType, &AnsiBuf, TRUE);
903 status = WdfChildListAddOrUpdateChildDescriptionAsPresent(ChildList, &description.Header, NULL);
904 break;
905 case 3:
906 WDF_CHILD_LIST_ITERATOR_INIT(&ChildIterator, WdfRetrievePresentChildren);
907 WdfChildListBeginIteration(ChildList, &ChildIterator);
908 while (NT_SUCCESS(WdfChildListRetrieveNextDevice(ChildList, &ChildIterator, &ChildDevice, NULL)))
909 {
910 ChildDeviceData = GetXenDeviceData(ChildDevice);
911 if (!ChildDeviceData)
912 {
913 KdPrint((__FUNCTION__ " No child device data, should never happen\n"));
914 continue;
915 }
916 if (strncmp(ChildDeviceData->BasePath, Path, strlen(ChildDeviceData->BasePath)) == 0 && Path[strlen(ChildDeviceData->BasePath)] == '/')
917 {
918 //KdPrint((__DRIVER_NAME " Child Path = %s (Match - WatchHandler = %08x)\n", ChildDeviceData->BasePath, ChildDeviceData->WatchHandler));
919 if (ChildDeviceData->WatchHandler != NULL)
920 ChildDeviceData->WatchHandler(Path, ChildDeviceData->WatchContext);
921 }
922 else
923 {
924 //KdPrint((__DRIVER_NAME " Child Path = %s (No Match)\n", ChildDeviceData->BasePath));
925 }
926 }
927 WdfChildListEndIteration(ChildList, &ChildIterator);
928 break;
929 default:
930 KdPrint((__FUNCTION__ ": Unknown case %d\n", Count));
931 break;
932 }
934 FreeSplitString(Bits, Count);
936 KdPrint((__DRIVER_NAME " <-- XenBusWatchHandler\n"));
937 }
939 static void
940 XenBus_ShutdownHandler(char *Path, PVOID Data)
941 {
942 WDFDEVICE Device = Data;
943 char *Value;
944 xenbus_transaction_t xbt;
945 int retry;
946 PSHUTDOWN_MSG_ENTRY Entry;
948 UNREFERENCED_PARAMETER(Path);
950 KdPrint((__DRIVER_NAME " --> XenBus_ShutdownHandler\n"));
952 XenBus_StartTransaction(Device, &xbt);
954 XenBus_Read(Device, XBT_NIL, SHUTDOWN_PATH, &Value);
956 if (Value != NULL && strlen(Value) != 0)
957 XenBus_Write(Device, XBT_NIL, SHUTDOWN_PATH, "");
959 if (Value != NULL)
960 {
961 KdPrint((__DRIVER_NAME " Shutdown Value = %s\n", Value));
962 KdPrint((__DRIVER_NAME " strlen(...) = %d\n", strlen(Value)));
963 }
964 else
965 {
966 KdPrint((__DRIVER_NAME " Shutdown Value = <null>\n"));
967 }
969 XenBus_EndTransaction(Device, xbt, 0, &retry);
971 if (Value != NULL && strlen(Value) != 0)
972 {
973 Entry = (PSHUTDOWN_MSG_ENTRY)ExAllocatePoolWithTag(NonPagedPool, sizeof(SHUTDOWN_MSG_ENTRY) + strlen(Value) + 1 + 1, XENPCI_POOL_TAG);
974 Entry->Ptr = 0;
975 RtlStringCbPrintfA(Entry->Buf, sizeof(SHUTDOWN_MSG_ENTRY) + strlen(Value) + 1 + 1, "%s\n", Value);
976 InsertTailList(&ShutdownMsgList, &Entry->ListEntry);
977 WdfIoQueueStart(ReadQueue);
978 }
979 KdPrint((__DRIVER_NAME " <-- XenBus_ShutdownHandler\n"));
980 }
982 static VOID
983 XenBus_BalloonHandler(char *Path, PVOID Data)
984 {
985 WDFDEVICE Device = Data;
986 char *value;
987 xenbus_transaction_t xbt;
988 int retry;
990 UNREFERENCED_PARAMETER(Path);
992 KdPrint((__DRIVER_NAME " --> XenBus_BalloonHandler\n"));
994 XenBus_StartTransaction(Device, &xbt);
996 XenBus_Read(Device, XBT_NIL, BALLOON_PATH, &value);
998 KdPrint((__DRIVER_NAME " Balloon Value = %s\n", value));
1000 // use the memory_op(unsigned int op, void *arg) hypercall to adjust this
1001 // use XENMEM_increase_reservation and XENMEM_decrease_reservation
1003 XenBus_EndTransaction(Device, xbt, 0, &retry);
1005 KdPrint((__DRIVER_NAME " <-- XenBus_BalloonHandler\n"));
1008 /*
1009 IO_RESOURCE_DESCRIPTOR MemoryDescriptor;
1011 static NTSTATUS
1012 XenPCI_FilterRemoveResourceRequirements(WDFDEVICE Device, WDFIORESREQLIST RequirementsList)
1014 NTSTATUS status;
1015 WDFIORESLIST ResourceList;
1016 PIO_RESOURCE_DESCRIPTOR Descriptor;
1018 int i, j;
1019 int offset;
1021 //KdPrint((__DRIVER_NAME " --> FilterRemoveResourceRequirements\n"));
1023 for (i = 0; i < WdfIoResourceRequirementsListGetCount(RequirementsList); i++)
1025 ResourceList = WdfIoResourceRequirementsListGetIoResList(RequirementsList, i);
1026 //KdPrint((__DRIVER_NAME " Resource List %d\n", i));
1027 //KdPrint((__DRIVER_NAME " %d resources in list\n", WdfIoResourceListGetCount(ResourceList)));
1028 offset = 0;
1029 for (j = 0; j < WdfIoResourceListGetCount(ResourceList); j++)
1031 //KdPrint((__DRIVER_NAME " Resource %d\n", j));
1032 Descriptor = WdfIoResourceListGetDescriptor(ResourceList, j - offset);
1034 switch (Descriptor->Type) {
1035 case CmResourceTypePort:
1036 //KdPrint((__DRIVER_NAME " Port\n"));
1037 break;
1038 case CmResourceTypeMemory:
1039 //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));
1040 //KdPrint((__DRIVER_NAME " Length %08X\n", Descriptor->u.Memory.Length));
1041 //KdPrint((__DRIVER_NAME " ShareDisposition %02X\n", Descriptor->ShareDisposition));
1042 //KdPrint((__DRIVER_NAME " Option %02X\n", Descriptor->Option));
1043 if (!Descriptor->Option || Descriptor->Option == IO_RESOURCE_PREFERRED) {
1044 memcpy(&MemoryDescriptor, Descriptor, sizeof(IO_RESOURCE_DESCRIPTOR));
1045 //platform_mmio_orig_len = MemoryDescriptor.u.Memory.Length;
1046 //MemoryDescriptor.u.Memory.Length = PAGE_SIZE;
1047 MemoryDescriptor.ShareDisposition = CmResourceShareShared;
1049 WdfIoResourceListRemove(ResourceList, j - offset);
1050 offset++;
1051 break;
1052 case CmResourceTypeInterrupt:
1053 //KdPrint((__DRIVER_NAME " Interrupt\n"));
1054 break;
1055 case CmResourceTypeDevicePrivate:
1056 //KdPrint((__DRIVER_NAME " Private\n"));
1057 break;
1058 default:
1059 //KdPrint((__DRIVER_NAME " Unknown Type (0x%x)\n", Descriptor->Type));
1060 break;
1064 status = STATUS_SUCCESS;
1066 KdPrint((__DRIVER_NAME " <-- FilterRemoveResourceRequirements\n"));
1068 return status;
1072 static NTSTATUS
1073 XenPCI_FilterAddResourceRequirements(WDFDEVICE Device, WDFIORESREQLIST RequirementsList)
1075 NTSTATUS status;
1076 WDFIORESLIST ResourceList;
1077 PIO_RESOURCE_DESCRIPTOR Descriptor;
1079 int i, j;
1081 KdPrint((__DRIVER_NAME " --> FilterAddResourceRequirements\n"));
1084 for (i = 0; i < WdfIoResourceRequirementsListGetCount(RequirementsList); i++)
1086 ResourceList = WdfIoResourceRequirementsListGetIoResList(RequirementsList, i);
1087 //KdPrint((__DRIVER_NAME " Resource List %d\n", i));
1088 //KdPrint((__DRIVER_NAME " %d resources in list\n", WdfIoResourceListGetCount(ResourceList)));
1089 WdfIoResourceListAppendDescriptor(ResourceList, &MemoryDescriptor);
1090 //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));
1091 //KdPrint((__DRIVER_NAME " Length %08X\n", MemoryDescriptor.u.Memory.Length));
1092 for (j = 0; j < WdfIoResourceListGetCount(ResourceList); j++)
1094 //KdPrint((__DRIVER_NAME " Resource %d\n", j));
1095 Descriptor = WdfIoResourceListGetDescriptor(ResourceList, j);
1097 switch (Descriptor->Type) {
1098 case CmResourceTypePort:
1099 //KdPrint((__DRIVER_NAME " Port\n"));
1100 break;
1101 case CmResourceTypeMemory:
1102 //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));
1103 //KdPrint((__DRIVER_NAME " Length %08X\n", Descriptor->u.Memory.Length));
1104 //KdPrint((__DRIVER_NAME " ShareDisposition %02X\n", Descriptor->ShareDisposition));
1105 //Descriptor->ShareDisposition = CmResourceShareShared;
1106 //memcpy(&MemoryDescriptor, Descriptor, sizeof(IO_RESOURCE_DESCRIPTOR));
1107 //platform_mmio_orig_len = MemoryDescriptor.u.Memory.Length;
1108 //MemoryDescriptor.u.Memory.Length = PAGE_SIZE;
1109 //WdfIoResourceListRemove(ResourceList, j);
1110 break;
1111 case CmResourceTypeInterrupt:
1112 //KdPrint((__DRIVER_NAME " Interrupt\n"));
1113 break;
1114 case CmResourceTypeDevicePrivate:
1115 //KdPrint((__DRIVER_NAME " Private\n"));
1116 break;
1117 default:
1118 //KdPrint((__DRIVER_NAME " Unknown Type (0x%x)\n", Descriptor->Type));
1119 break;
1123 status = STATUS_SUCCESS;
1125 //KdPrint((__DRIVER_NAME " <-- FilterAddResourceRequirements\n"));
1127 return status;
1130 static NTSTATUS
1131 XenPCI_RemoveAddedResources(WDFDEVICE Device, WDFCMRESLIST ResourcesRaw, WDFCMRESLIST ResourcesTranslated)
1133 //KdPrint((__DRIVER_NAME " --> RemoveAddedResources\n"));
1134 //KdPrint((__DRIVER_NAME " <-- RemoveAddedResources\n"));
1136 return STATUS_SUCCESS;
1139 */
1141 static NTSTATUS
1142 XenPCI_DeviceResourceRequirementsQuery(WDFDEVICE Device, WDFIORESREQLIST IoResourceRequirementsList)
1144 NTSTATUS status;
1145 WDFIORESLIST resourceList;
1146 IO_RESOURCE_DESCRIPTOR descriptor;
1147 PXENPCI_DEVICE_DATA xpdd = GetDeviceData(Device);
1149 //KdPrint((__DRIVER_NAME " --> DeviceResourceRequirementsQuery\n"));
1151 status = WdfIoResourceListCreate(IoResourceRequirementsList, WDF_NO_OBJECT_ATTRIBUTES, &resourceList);
1152 if (!NT_SUCCESS(status))
1153 return status;
1155 /*
1156 RtlZeroMemory(&descriptor, sizeof(descriptor));
1158 descriptor.Option = 0;
1159 descriptor.Type = CmResourceTypeInterrupt;
1160 descriptor.ShareDisposition = CmResourceShareDeviceExclusive;
1161 descriptor.Flags = CM_RESOURCE_MEMORY_READ_WRITE;
1162 descriptor.u.Interrupt.MinimumVector = 1024;
1163 descriptor.u.Interrupt.MaximumVector = 1024+255;
1165 //KdPrint((__DRIVER_NAME " MinimumVector = %d, MaximumVector = %d\n", descriptor.u.Interrupt.MinimumVector, descriptor.u.Interrupt.MaximumVector));
1167 status = WdfIoResourceListAppendDescriptor(resourceList, &descriptor);
1168 if (!NT_SUCCESS(status))
1169 return status;
1170 */
1172 RtlZeroMemory(&descriptor, sizeof(descriptor));
1174 descriptor.Option = 0;
1175 descriptor.Type = CmResourceTypeMemory;
1176 descriptor.ShareDisposition = CmResourceShareShared; //CmResourceShareDeviceExclusive;
1177 descriptor.Flags = CM_RESOURCE_MEMORY_READ_WRITE;
1178 descriptor.u.Memory.Length = PAGE_SIZE;
1179 descriptor.u.Memory.Alignment = PAGE_SIZE;
1180 descriptor.u.Memory.MinimumAddress.QuadPart
1181 = xpdd->platform_mmio_addr.QuadPart + PAGE_SIZE;
1182 descriptor.u.Memory.MaximumAddress.QuadPart
1183 = xpdd->platform_mmio_addr.QuadPart + xpdd->platform_mmio_len - 1;
1185 //KdPrint((__DRIVER_NAME " MinimumAddress = %08x, MaximumAddress = %08X\n", descriptor.u.Memory.MinimumAddress.LowPart, descriptor.u.Memory.MaximumAddress.LowPart));
1187 status = WdfIoResourceListAppendDescriptor(resourceList, &descriptor);
1188 if (!NT_SUCCESS(status))
1189 return status;
1191 status = WdfIoResourceRequirementsListAppendIoResList(IoResourceRequirementsList, resourceList);
1192 if (!NT_SUCCESS(status))
1193 return status;
1195 //KdPrint((__DRIVER_NAME " <-- DeviceResourceRequirementsQuery\n"));
1197 return status;