win-pvdrivers

view xenpci/xenpci.c @ 77:b9b4b731f890

Tidyups and work on getting xennet at least as functional as it was before I started messing with it :)
author James Harper <james.harper@bendigoit.com.au>
date Fri Dec 28 23:21:49 2007 +1100 (2007-12-28)
parents dfa772949c6e
children 3a9c28d5a006
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 XenPCI_FreeMem(PVOID Ptr)
207 {
208 ExFreePoolWithTag(Ptr, XENPCI_POOL_TAG);
209 }
211 static NTSTATUS
212 get_hypercall_stubs(WDFDEVICE Device)
213 {
214 PXENPCI_DEVICE_DATA xpdd = GetDeviceData(Device);
215 DWORD32 cpuid_output[4];
216 char xensig[13];
217 ULONG i;
218 ULONG pages;
219 ULONG msr;
221 __cpuid(cpuid_output, 0x40000000);
222 *(ULONG*)(xensig + 0) = cpuid_output[1];
223 *(ULONG*)(xensig + 4) = cpuid_output[2];
224 *(ULONG*)(xensig + 8) = cpuid_output[3];
225 xensig[12] = '\0';
226 KdPrint((__DRIVER_NAME " Xen Signature = %s, EAX = 0x%08x\n", xensig, cpuid_output[0]));
228 __cpuid(cpuid_output, 0x40000002);
229 pages = cpuid_output[0];
230 msr = cpuid_output[1];
231 //KdPrint((__DRIVER_NAME " Hypercall area is %u pages.\n", pages));
233 xpdd->hypercall_stubs = ExAllocatePoolWithTag(NonPagedPool, pages * PAGE_SIZE, XENPCI_POOL_TAG);
234 //KdPrint((__DRIVER_NAME " Hypercall area at %08x\n", hypercall_stubs));
236 if (!xpdd->hypercall_stubs)
237 return 1;
238 for (i = 0; i < pages; i++) {
239 ULONG pfn;
240 //pfn = vmalloc_to_pfn((char *)hypercall_stubs + i * PAGE_SIZE);
241 pfn = (ULONG)(MmGetPhysicalAddress(xpdd->hypercall_stubs + i * PAGE_SIZE).QuadPart >> PAGE_SHIFT);
242 //KdPrint((__DRIVER_NAME " pfn = %08X\n", pfn));
243 __writemsr(msr, ((ULONGLONG)pfn << PAGE_SHIFT) + i);
244 }
245 return STATUS_SUCCESS;
246 }
248 PHYSICAL_ADDRESS
249 XenPCI_AllocMMIO(WDFDEVICE Device, ULONG len)
250 {
251 PXENPCI_DEVICE_DATA xpdd = GetDeviceData(Device);
253 PHYSICAL_ADDRESS addr;
255 addr = xpdd->platform_mmio_addr;
256 addr.QuadPart += xpdd->platform_mmio_alloc;
257 xpdd->platform_mmio_alloc += len;
259 return addr;
260 }
262 static int
263 init_xen_info(WDFDEVICE Device)
264 {
265 PXENPCI_DEVICE_DATA xpdd = GetDeviceData(Device);
266 struct xen_add_to_physmap xatp;
267 int ret;
268 PHYSICAL_ADDRESS shared_info_area_unmapped;
270 //setup_xen_features();
271 //KdPrint((__DRIVER_NAME " init_xen_info Hypercall area at %08x\n", hypercall_stubs));
273 shared_info_area_unmapped = XenPCI_AllocMMIO(Device, PAGE_SIZE);
274 xatp.domid = DOMID_SELF;
275 xatp.idx = 0;
276 xatp.space = XENMAPSPACE_shared_info;
277 xatp.gpfn = (xen_pfn_t)(shared_info_area_unmapped.QuadPart >> PAGE_SHIFT);
278 ret = HYPERVISOR_memory_op(Device, XENMEM_add_to_physmap, &xatp);
279 //KdPrint((__DRIVER_NAME " ret = %d\n", ret));
281 xpdd->shared_info_area = MmMapIoSpace(shared_info_area_unmapped,
282 PAGE_SIZE, MmNonCached);
284 return 0;
285 }
287 static int
288 set_callback_irq(WDFDEVICE Device, 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(Device, 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 WDFQUEUE ReadQueue;
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 WDF_OBJECT_ATTRIBUTES attributes;
314 WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;
315 WDF_IO_QUEUE_CONFIG IoQConfig;
316 WDF_INTERRUPT_CONFIG InterruptConfig;
317 PNP_BUS_INFORMATION busInfo;
318 BUS_INTERFACE_STANDARD BusInterface;
319 DECLARE_CONST_UNICODE_STRING(DeviceName, L"\\Device\\XenShutdown");
320 DECLARE_CONST_UNICODE_STRING(SymbolicName, L"\\DosDevices\\XenShutdown");
321 WDFDEVICE Device;
322 PXENPCI_DEVICE_DATA xpdd;
324 UNREFERENCED_PARAMETER(Driver);
326 KdPrint((__DRIVER_NAME " --> DeviceAdd\n"));
328 WdfDeviceInitSetDeviceType(DeviceInit, FILE_DEVICE_BUS_EXTENDER);
329 WDF_CHILD_LIST_CONFIG_INIT(&config, sizeof(XENPCI_IDENTIFICATION_DESCRIPTION), XenPCI_ChildListCreateDevice);
330 WdfFdoInitSetDefaultChildListConfig(DeviceInit, &config, WDF_NO_OBJECT_ATTRIBUTES);
332 WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);
333 pnpPowerCallbacks.EvtDevicePrepareHardware = XenPCI_PrepareHardware;
334 pnpPowerCallbacks.EvtDeviceReleaseHardware = XenPCI_ReleaseHardware;
335 pnpPowerCallbacks.EvtDeviceD0Entry = XenPCI_D0Entry;
336 pnpPowerCallbacks.EvtDeviceD0EntryPostInterruptsEnabled
337 = XenPCI_D0EntryPostInterruptsEnabled;
338 pnpPowerCallbacks.EvtDeviceD0ExitPreInterruptsDisabled
339 = XenPCI_D0ExitPreInterruptsDisabled;
340 pnpPowerCallbacks.EvtDeviceD0Exit = XenPCI_D0Exit;
341 WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);
343 WdfDeviceInitSetIoType(DeviceInit, WdfDeviceIoBuffered);
345 Status = WdfDeviceInitAssignName(DeviceInit, &DeviceName);
346 if (!NT_SUCCESS(Status))
347 {
348 KdPrint((__DRIVER_NAME " WdfDeviceInitAssignName failed 0x%08x\n", Status));
349 return Status;
350 }
352 /*initialize storage for the device context*/
353 WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, XENPCI_DEVICE_DATA);
355 /*create a device instance.*/
356 Status = WdfDeviceCreate(&DeviceInit, &attributes, &Device);
357 if(!NT_SUCCESS(Status))
358 {
359 KdPrint((__DRIVER_NAME " WdfDeviceCreate failed with Status 0x%08x\n", Status));
360 return Status;
361 }
362 xpdd = GetDeviceData(Device);
363 xpdd->Device = Device;
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 busInfo.BusTypeGuid = GUID_XENPCI_DEVCLASS;
376 busInfo.LegacyBusType = Internal;
377 busInfo.BusNumber = 0;
379 WdfDeviceSetBusInformationForChildren(Device, &busInfo);
381 WDF_INTERRUPT_CONFIG_INIT(&InterruptConfig, EvtChn_Interrupt, NULL); //EvtChn_InterruptDpc);
382 InterruptConfig.EvtInterruptEnable = XenPCI_InterruptEnable;
383 InterruptConfig.EvtInterruptDisable = XenPCI_InterruptDisable;
384 Status = WdfInterruptCreate(Device, &InterruptConfig, WDF_NO_OBJECT_ATTRIBUTES, &xpdd->XenInterrupt);
385 if (!NT_SUCCESS (Status))
386 {
387 KdPrint((__DRIVER_NAME " WdfInterruptCreate failed 0x%08x\n", Status));
388 return Status;
389 }
391 Status = WdfDeviceCreateDeviceInterface(Device, (LPGUID)&GUID_XEN_IFACE, NULL);
392 if (!NT_SUCCESS(Status))
393 {
394 KdPrint((__DRIVER_NAME " WdfDeviceCreateDeviceInterface failed 0x%08x\n", Status));
395 return Status;
396 }
397 WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&IoQConfig, WdfIoQueueDispatchSequential);
398 IoQConfig.EvtIoDefault = XenPCI_IoDefault;
400 Status = WdfIoQueueCreate(Device, &IoQConfig, WDF_NO_OBJECT_ATTRIBUTES, NULL);
401 if (!NT_SUCCESS(Status))
402 {
403 KdPrint((__DRIVER_NAME " WdfIoQueueCreate failed 0x%08x\n", Status));
404 return Status;
405 }
407 WDF_IO_QUEUE_CONFIG_INIT(&IoQConfig, WdfIoQueueDispatchSequential);
408 IoQConfig.EvtIoRead = XenPCI_IoRead;
410 Status = WdfIoQueueCreate(Device, &IoQConfig, WDF_NO_OBJECT_ATTRIBUTES, &ReadQueue);
411 if (!NT_SUCCESS(Status))
412 {
413 KdPrint((__DRIVER_NAME " WdfIoQueueCreate (ReadQueue) failed 0x%08x\n", Status));
414 switch (Status)
415 {
416 case STATUS_INVALID_PARAMETER:
417 KdPrint((__DRIVER_NAME " STATUS_INVALID_PARAMETER\n"));
418 break;
419 case STATUS_INFO_LENGTH_MISMATCH:
420 KdPrint((__DRIVER_NAME " STATUS_INFO_LENGTH_MISMATCH\n"));
421 break;
422 case STATUS_POWER_STATE_INVALID:
423 KdPrint((__DRIVER_NAME " STATUS_POWER_STATE_INVALID\n"));
424 break;
425 case STATUS_INSUFFICIENT_RESOURCES:
426 KdPrint((__DRIVER_NAME " STATUS_INSUFFICIENT_RESOURCES\n"));
427 break;
428 case STATUS_WDF_NO_CALLBACK:
429 KdPrint((__DRIVER_NAME " STATUS_WDF_NO_CALLBACK\n"));
430 break;
431 case STATUS_UNSUCCESSFUL:
432 KdPrint((__DRIVER_NAME " STATUS_UNSUCCESSFUL\n"));
433 break;
434 }
435 return Status;
436 }
437 WdfIoQueueStopSynchronously(ReadQueue);
438 WdfDeviceConfigureRequestDispatching(Device, ReadQueue, WdfRequestTypeRead);
440 Status = WdfDeviceCreateSymbolicLink(Device, &SymbolicName);
441 if (!NT_SUCCESS(Status))
442 {
443 KdPrint((__DRIVER_NAME " WdfDeviceCreateSymbolicLink failed 0x%08x\n", Status));
444 return Status;
445 }
447 KdPrint((__DRIVER_NAME " <-- DeviceAdd\n"));
448 return Status;
449 }
451 static NTSTATUS
452 XenPCI_PrepareHardware(
453 IN WDFDEVICE Device,
454 IN WDFCMRESLIST ResourceList,
455 IN WDFCMRESLIST ResourceListTranslated)
456 {
457 NTSTATUS status = STATUS_SUCCESS;
458 PCM_PARTIAL_RESOURCE_DESCRIPTOR descriptor;
459 ULONG i;
460 PXENPCI_DEVICE_DATA xpdd = GetDeviceData(Device);
462 KdPrint((__DRIVER_NAME " --> EvtDevicePrepareHardware\n"));
464 for (i = 0; i < WdfCmResourceListGetCount(ResourceList); i++)
465 {
466 descriptor = WdfCmResourceListGetDescriptor(ResourceList, i);
467 if(!descriptor)
468 continue;
469 switch (descriptor->Type)
470 {
471 case CmResourceTypeInterrupt:
472 xpdd->irqNumber = descriptor->u.Interrupt.Vector;
473 break;
474 }
475 }
477 //KdPrint((__DRIVER_NAME " GSI = %d\n", irqNumber));
479 //KdPrint((__DRIVER_NAME " ResourceListTranslated\n"));
480 for (i = 0; i < WdfCmResourceListGetCount(ResourceListTranslated); i++)
481 {
482 descriptor = WdfCmResourceListGetDescriptor(ResourceListTranslated, i);
483 if(!descriptor)
484 {
485 KdPrint((__DRIVER_NAME " --> EvtDevicePrepareHardware (No descriptor)\n"));
486 return STATUS_DEVICE_CONFIGURATION_ERROR;
487 }
488 switch (descriptor->Type) {
489 case CmResourceTypePort:
490 //KdPrint((__DRIVER_NAME " I/O mapped CSR: (%x) Length: (%d)\n", descriptor->u.Port.Start.LowPart, descriptor->u.Port.Length));
491 break;
492 case CmResourceTypeMemory:
493 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));
494 xpdd->platform_mmio_addr = descriptor->u.Memory.Start; //(ULONG)MmMapIoSpace(descriptor->u.Memory.Start, descriptor->u.Memory.Length, MmNonCached);
495 xpdd->platform_mmio_len = descriptor->u.Memory.Length;
496 xpdd->platform_mmio_alloc = 0;
497 break;
498 case CmResourceTypeInterrupt:
499 //KdPrint((__DRIVER_NAME " Interrupt level: 0x%0x, Vector: 0x%0x\n", descriptor->u.Interrupt.Level, descriptor->u.Interrupt.Vector));
500 memcpy(&InterruptRaw, WdfCmResourceListGetDescriptor(ResourceList, i), sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
501 memcpy(&InterruptTranslated, WdfCmResourceListGetDescriptor(ResourceListTranslated, i), sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
502 break;
503 case CmResourceTypeDevicePrivate:
504 //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] ));
505 break;
506 default:
507 //KdPrint((__DRIVER_NAME " Unhandled resource type (0x%x)\n", descriptor->Type));
508 break;
509 }
510 }
512 get_hypercall_stubs(Device);
514 init_xen_info(Device);
516 GntTbl_Init(Device);
518 EvtChn_Init(Device);
520 set_callback_irq(Device, xpdd->irqNumber);
522 XenBus_Init(Device);
524 //KdPrint((__DRIVER_NAME " upcall_pending = %d\n", shared_info_area->vcpu_info[0].evtchn_upcall_pending));
526 xpdd->shared_info_area->vcpu_info[0].evtchn_upcall_mask = 0;
528 //xen_reboot_init();
530 KdPrint((__DRIVER_NAME " <-- EvtDevicePrepareHardware\n"));
532 return status;
533 }
535 static NTSTATUS
536 XenPCI_ReleaseHardware(WDFDEVICE Device, WDFCMRESLIST ResourcesTranslated)
537 {
538 UNREFERENCED_PARAMETER(Device);
539 UNREFERENCED_PARAMETER(ResourcesTranslated);
541 return STATUS_SUCCESS;
542 }
544 static NTSTATUS
545 XenPCI_D0Entry(
546 IN WDFDEVICE Device,
547 IN WDF_POWER_DEVICE_STATE PreviousState
548 )
549 {
550 NTSTATUS status = STATUS_SUCCESS;
552 UNREFERENCED_PARAMETER(Device);
553 UNREFERENCED_PARAMETER(PreviousState);
555 KdPrint((__DRIVER_NAME " --> EvtDeviceD0Entry\n"));
557 KdPrint((__DRIVER_NAME " <-- EvtDeviceD0Entry\n"));
559 return status;
560 }
562 static NTSTATUS
563 XenPCI_D0EntryPostInterruptsEnabled(WDFDEVICE Device, WDF_POWER_DEVICE_STATE PreviousState)
564 {
565 NTSTATUS status = STATUS_SUCCESS;
566 //OBJECT_ATTRIBUTES oa;
567 char *response;
568 char *msgTypes;
569 char **Types;
570 int i;
571 char buffer[128];
573 UNREFERENCED_PARAMETER(PreviousState);
575 KdPrint((__DRIVER_NAME " --> EvtDeviceD0EntryPostInterruptsEnabled\n"));
577 XenBus_Start(Device);
579 KdPrint((__DRIVER_NAME " A\n"));
581 response = XenBus_AddWatch(Device, XBT_NIL, SHUTDOWN_PATH, XenBus_ShutdownHandler, Device);
582 KdPrint((__DRIVER_NAME " shutdown watch response = '%s'\n", response));
584 response = XenBus_AddWatch(Device, XBT_NIL, BALLOON_PATH, XenBus_BalloonHandler, Device);
585 KdPrint((__DRIVER_NAME " shutdown watch response = '%s'\n", response));
587 response = XenBus_AddWatch(Device, XBT_NIL, "device", XenPCI_XenBusWatchHandler, Device);
588 KdPrint((__DRIVER_NAME " device watch response = '%s'\n", response));
590 msgTypes = XenBus_List(Device, XBT_NIL, "device", &Types);
591 if (!msgTypes) {
592 for (i = 0; Types[i]; i++)
593 {
594 RtlStringCbPrintfA(buffer, ARRAY_SIZE(buffer), "device/%s", Types[i]);
595 //KdPrint((__DRIVER_NAME " ls device[%d] -> %s\n", i, Types[i]));
596 XenPCI_XenBusWatchHandler(buffer, Device);
597 ExFreePoolWithTag(Types[i], XENPCI_POOL_TAG);
598 }
599 }
600 KdPrint((__DRIVER_NAME " <-- EvtDeviceD0EntryPostInterruptsEnabled\n"));
602 return status;
603 }
605 static NTSTATUS
606 XenPCI_D0ExitPreInterruptsDisabled(WDFDEVICE Device, WDF_POWER_DEVICE_STATE TargetState)
607 {
608 NTSTATUS status = STATUS_SUCCESS;
610 UNREFERENCED_PARAMETER(TargetState);
612 KdPrint((__DRIVER_NAME " --> D0ExitPreInterruptsDisabled\n"));
614 XenBus_Stop(Device);
616 KdPrint((__DRIVER_NAME " <-- D0ExitPreInterruptsDisabled\n"));
618 return status;
619 }
621 static NTSTATUS
622 XenPCI_D0Exit(WDFDEVICE Device, WDF_POWER_DEVICE_STATE TargetState)
623 {
624 NTSTATUS status = STATUS_SUCCESS;
626 UNREFERENCED_PARAMETER(Device);
627 UNREFERENCED_PARAMETER(TargetState);
629 KdPrint((__DRIVER_NAME " --> DeviceD0Exit\n"));
631 XenBus_Close(Device);
633 KdPrint((__DRIVER_NAME " <-- DeviceD0Exit\n"));
635 return status;
636 }
638 static VOID
639 XenPCI_IoDefault(
640 IN WDFQUEUE Queue,
641 IN WDFREQUEST Request
642 )
643 {
644 UNREFERENCED_PARAMETER(Queue);
646 KdPrint((__DRIVER_NAME " --> EvtDeviceIoDefault\n"));
648 WdfRequestComplete(Request, STATUS_NOT_IMPLEMENTED);
650 KdPrint((__DRIVER_NAME " <-- EvtDeviceIoDefault\n"));
651 }
654 static VOID
655 XenPCI_IoRead(WDFQUEUE Queue, WDFREQUEST Request, size_t Length)
656 {
657 PSHUTDOWN_MSG_ENTRY Entry;
658 ULONG Remaining;
659 ULONG CopyLen;
660 PCHAR Buffer;
661 size_t BufLen;
662 KIRQL OldIrql;
664 UNREFERENCED_PARAMETER(Queue);
665 UNREFERENCED_PARAMETER(Length);
667 KdPrint((__DRIVER_NAME " --> IoRead\n"));
669 WdfRequestRetrieveOutputBuffer(Request, 1, &Buffer, &BufLen);
671 KeAcquireSpinLock(&ShutdownMsgLock, &OldIrql);
673 Entry = (PSHUTDOWN_MSG_ENTRY)RemoveHeadList(&ShutdownMsgList);
675 if ((PLIST_ENTRY)Entry == &ShutdownMsgList)
676 {
677 KdPrint((__DRIVER_NAME " <-- IoRead (Nothing in queue... xenpci is now broken)\n"));
678 return;
679 }
681 Remaining = strlen(Entry->Buf + Entry->Ptr);
682 CopyLen = min(Remaining, BufLen);
684 memcpy(Buffer, Entry->Buf + Entry->Ptr, CopyLen);
686 if (Entry->Buf[Entry->Ptr] == 0)
687 {
688 KdPrint((__DRIVER_NAME " All done... stopping queue\n"));
689 if (IsListEmpty(&ShutdownMsgList))
690 WdfIoQueueStop(ReadQueue, NULL, NULL);
691 }
692 else
693 {
694 KdPrint((__DRIVER_NAME " More to do...\n"));
695 Entry->Ptr += CopyLen;
696 InsertHeadList(&ShutdownMsgList, &Entry->ListEntry);
697 }
699 KeReleaseSpinLock(&ShutdownMsgLock, OldIrql);
701 WdfRequestCompleteWithInformation(Request, STATUS_SUCCESS, CopyLen);
703 KdPrint((__DRIVER_NAME " <-- IoRead\n"));
704 }
707 static NTSTATUS
708 XenPCI_InterruptEnable(WDFINTERRUPT Interrupt, WDFDEVICE AssociatedDevice)
709 {
710 PXENPCI_DEVICE_DATA xpdd = GetDeviceData(AssociatedDevice);
712 UNREFERENCED_PARAMETER(Interrupt);
714 KdPrint((__DRIVER_NAME " --> EvtInterruptEnable\n"));
716 xpdd->shared_info_area->vcpu_info[0].evtchn_upcall_mask = 0;
718 KdPrint((__DRIVER_NAME " <-- EvtInterruptEnable\n"));
720 return STATUS_SUCCESS;
721 }
723 static NTSTATUS
724 XenPCI_InterruptDisable(WDFINTERRUPT Interrupt, WDFDEVICE AssociatedDevice)
725 {
726 PXENPCI_DEVICE_DATA xpdd = GetDeviceData(AssociatedDevice);
728 UNREFERENCED_PARAMETER(Interrupt);
730 //KdPrint((__DRIVER_NAME " --> EvtInterruptDisable\n"));
732 xpdd->shared_info_area->vcpu_info[0].evtchn_upcall_mask = 1;
733 // should we kick off any pending interrupts here?
735 //KdPrint((__DRIVER_NAME " <-- EvtInterruptDisable\n"));
737 return STATUS_SUCCESS;
738 }
740 static NTSTATUS
741 XenPCI_ChildListCreateDevice(
742 WDFCHILDLIST ChildList,
743 PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER IdentificationDescription,
744 PWDFDEVICE_INIT ChildInit)
745 {
746 NTSTATUS status;
747 WDFDEVICE ChildDevice = NULL;
748 PXENPCI_IDENTIFICATION_DESCRIPTION XenIdentificationDesc;
749 DECLARE_UNICODE_STRING_SIZE(buffer, 20);
750 WDF_OBJECT_ATTRIBUTES PdoAttributes;
751 DECLARE_CONST_UNICODE_STRING(DeviceLocation, L"Xen Bus");
752 WDF_QUERY_INTERFACE_CONFIG qiConfig;
753 PXENPCI_XEN_DEVICE_DATA ChildDeviceData = NULL;
755 UNREFERENCED_PARAMETER(ChildList);
757 //KdPrint((__DRIVER_NAME " --> ChildListCreateDevice\n"));
759 XenIdentificationDesc = CONTAINING_RECORD(IdentificationDescription, XENPCI_IDENTIFICATION_DESCRIPTION, Header);
761 //KdPrint((__DRIVER_NAME " Type = %wZ\n", &XenIdentificationDesc->DeviceType));
763 //DeviceInit = WdfPdoInitAllocate(Device);
764 WdfDeviceInitSetDeviceType(ChildInit, FILE_DEVICE_CONTROLLER);
766 status = RtlUnicodeStringPrintf(&buffer, L"Xen\\%wZ\0", &XenIdentificationDesc->DeviceType);
767 status = WdfPdoInitAssignDeviceID(ChildInit, &buffer);
768 status = WdfPdoInitAddHardwareID(ChildInit, &buffer);
769 status = WdfPdoInitAddCompatibleID(ChildInit, &buffer);
771 status = RtlUnicodeStringPrintf(&buffer, L"%02d", 0);
772 status = WdfPdoInitAssignInstanceID(ChildInit, &buffer);
774 status = RtlUnicodeStringPrintf( &buffer, L"%wZ", &XenIdentificationDesc->DeviceType);
775 status = WdfPdoInitAddDeviceText(ChildInit, &buffer, &DeviceLocation, 0x409);
777 WdfPdoInitSetDefaultLocale(ChildInit, 0x409);
779 WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&PdoAttributes, XENPCI_XEN_DEVICE_DATA);
781 // WDF_PDO_EVENT_CALLBACKS_INIT(&PdoCallbacks);
782 // PdoCallbacks.EvtDeviceResourceRequirementsQuery = XenPCI_DeviceResourceRequirementsQuery;
783 // WdfPdoInitSetEventCallbacks(ChildInit, &PdoCallbacks);
785 status = WdfDeviceCreate(&ChildInit, &PdoAttributes, &ChildDevice);
786 if (!NT_SUCCESS(status))
787 {
788 KdPrint((__DRIVER_NAME " WdfDeviceCreate status = %08X\n", status));
789 }
791 WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFilePaging, TRUE);
792 WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFileHibernation, TRUE);
793 WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFileDump, TRUE);
795 ChildDeviceData = GetXenDeviceData(ChildDevice);
796 ChildDeviceData->Magic = XEN_DATA_MAGIC;
797 ChildDeviceData->AutoEnumerate = AutoEnumerate;
798 ChildDeviceData->WatchHandler = NULL;
799 strncpy(ChildDeviceData->Path, XenIdentificationDesc->Path, 128);
800 ChildDeviceData->DeviceIndex = XenIdentificationDesc->DeviceIndex;
801 memcpy(&ChildDeviceData->InterruptRaw, &InterruptRaw, sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
802 memcpy(&ChildDeviceData->InterruptTranslated, &InterruptTranslated, sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
804 ChildDeviceData->XenInterface.InterfaceHeader.Size = sizeof(ChildDeviceData->XenInterface);
805 ChildDeviceData->XenInterface.InterfaceHeader.Version = 1;
806 ChildDeviceData->XenInterface.InterfaceHeader.Context = WdfPdoGetParent(ChildDevice);
807 ChildDeviceData->XenInterface.InterfaceHeader.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
808 ChildDeviceData->XenInterface.InterfaceHeader.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
810 ChildDeviceData->XenInterface.AllocMMIO = XenPCI_AllocMMIO;
811 ChildDeviceData->XenInterface.FreeMem = XenPCI_FreeMem;
813 ChildDeviceData->XenInterface.EvtChn_Bind = EvtChn_Bind;
814 ChildDeviceData->XenInterface.EvtChn_Unbind = EvtChn_Unbind;
815 ChildDeviceData->XenInterface.EvtChn_Mask = EvtChn_Mask;
816 ChildDeviceData->XenInterface.EvtChn_Unmask = EvtChn_Unmask;
817 ChildDeviceData->XenInterface.EvtChn_Notify = EvtChn_Notify;
818 ChildDeviceData->XenInterface.EvtChn_AllocUnbound = EvtChn_AllocUnbound;
819 ChildDeviceData->XenInterface.EvtChn_BindDpc = EvtChn_BindDpc;
821 ChildDeviceData->XenInterface.GntTbl_GrantAccess = GntTbl_GrantAccess;
822 ChildDeviceData->XenInterface.GntTbl_EndAccess = GntTbl_EndAccess;
824 ChildDeviceData->XenInterface.XenBus_Read = XenBus_Read;
825 ChildDeviceData->XenInterface.XenBus_Write = XenBus_Write;
826 ChildDeviceData->XenInterface.XenBus_Printf = XenBus_Printf;
827 ChildDeviceData->XenInterface.XenBus_StartTransaction = XenBus_StartTransaction;
828 ChildDeviceData->XenInterface.XenBus_EndTransaction = XenBus_EndTransaction;
829 ChildDeviceData->XenInterface.XenBus_List = XenBus_List;
830 ChildDeviceData->XenInterface.XenBus_AddWatch = XenBus_AddWatch;
831 ChildDeviceData->XenInterface.XenBus_RemWatch = XenBus_RemWatch;
833 WDF_QUERY_INTERFACE_CONFIG_INIT(&qiConfig, (PINTERFACE)&ChildDeviceData->XenInterface, &GUID_XEN_IFACE, NULL);
834 status = WdfDeviceAddQueryInterface(ChildDevice, &qiConfig);
835 if (!NT_SUCCESS(status)) {
836 return status;
837 }
839 //KdPrint((__DRIVER_NAME " <-- ChildListCreateDevice\n"));
841 return status;
842 }
844 VOID
845 XenPCI_XenBusWatchHandler(char *Path, PVOID Data)
846 {
847 XENPCI_IDENTIFICATION_DESCRIPTION description;
848 NTSTATUS status;
849 char **Bits;
850 int Count;
851 WDFDEVICE Device = Data;
852 WDFCHILDLIST ChildList;
853 WDF_CHILD_LIST_ITERATOR ChildIterator;
854 WDFDEVICE ChildDevice;
855 PXENPCI_XEN_DEVICE_DATA ChildDeviceData;
857 ANSI_STRING AnsiBuf;
859 UNREFERENCED_PARAMETER(Data);
861 KdPrint((__DRIVER_NAME " --> XenBusWatchHandler\n"));
863 //KdPrint((__DRIVER_NAME " %s\n", Path));
865 ChildList = WdfFdoGetDefaultChildList(Device);
867 Bits = SplitString(Path, '/', 3, &Count);
868 switch (Count)
869 {
870 case 0:
871 case 1:
872 break;
873 case 2:
874 // add or update the device node
875 WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER_INIT(&description.Header, sizeof(description));
876 strncpy(description.Path, Path, 128);
877 RtlInitAnsiString(&AnsiBuf, Bits[1]);
878 //KdPrint((__DRIVER_NAME " Name = %s\n", Bits[1]));
879 RtlAnsiStringToUnicodeString(&description.DeviceType, &AnsiBuf, TRUE);
880 status = WdfChildListAddOrUpdateChildDescriptionAsPresent(ChildList, &description.Header, NULL);
881 break;
882 case 3:
883 WDF_CHILD_LIST_ITERATOR_INIT(&ChildIterator, WdfRetrievePresentChildren);
884 WdfChildListBeginIteration(ChildList, &ChildIterator);
885 while (NT_SUCCESS(WdfChildListRetrieveNextDevice(ChildList, &ChildIterator, &ChildDevice, NULL)))
886 {
887 ChildDeviceData = GetXenDeviceData(ChildDevice);
888 if (!ChildDeviceData)
889 {
890 KdPrint((__FUNCTION__ " No child device data, should never happen\n"));
891 continue;
892 }
893 if (strncmp(ChildDeviceData->Path, Path, strlen(ChildDeviceData->Path)) == 0 && Path[strlen(ChildDeviceData->Path)] == '/')
894 {
895 //KdPrint((__DRIVER_NAME " Child Path = %s (Match - WatchHandler = %08x)\n", ChildDeviceData->Path, ChildDeviceData->WatchHandler));
896 if (ChildDeviceData->WatchHandler != NULL)
897 ChildDeviceData->WatchHandler(Path, ChildDeviceData->WatchContext);
898 }
899 else
900 {
901 //KdPrint((__DRIVER_NAME " Child Path = %s (No Match)\n", ChildDeviceData->Path));
902 }
903 }
904 WdfChildListEndIteration(ChildList, &ChildIterator);
905 break;
906 default:
907 KdPrint((__FUNCTION__ ": Unknown case %d\n", Count));
908 break;
909 }
911 FreeSplitString(Bits, Count);
913 KdPrint((__DRIVER_NAME " <-- XenBusWatchHandler\n"));
914 }
916 static void
917 XenBus_ShutdownHandler(char *Path, PVOID Data)
918 {
919 WDFDEVICE Device = Data;
920 char *Value;
921 xenbus_transaction_t xbt;
922 int retry;
923 PSHUTDOWN_MSG_ENTRY Entry;
925 UNREFERENCED_PARAMETER(Path);
927 KdPrint((__DRIVER_NAME " --> XenBus_ShutdownHandler\n"));
929 XenBus_StartTransaction(Device, &xbt);
931 XenBus_Read(Device, XBT_NIL, SHUTDOWN_PATH, &Value);
933 if (Value != NULL && strlen(Value) != 0)
934 XenBus_Write(Device, XBT_NIL, SHUTDOWN_PATH, "");
936 if (Value != NULL)
937 {
938 KdPrint((__DRIVER_NAME " Shutdown Value = %s\n", Value));
939 KdPrint((__DRIVER_NAME " strlen(...) = %d\n", strlen(Value)));
940 }
941 else
942 {
943 KdPrint((__DRIVER_NAME " Shutdown Value = <null>\n"));
944 }
946 XenBus_EndTransaction(Device, xbt, 0, &retry);
948 if (Value != NULL && strlen(Value) != 0)
949 {
950 Entry = (PSHUTDOWN_MSG_ENTRY)ExAllocatePoolWithTag(NonPagedPool, sizeof(SHUTDOWN_MSG_ENTRY) + strlen(Value) + 1 + 1, XENPCI_POOL_TAG);
951 Entry->Ptr = 0;
952 RtlStringCbPrintfA(Entry->Buf, sizeof(SHUTDOWN_MSG_ENTRY) + strlen(Value) + 1 + 1, "%s\n", Value);
953 InsertTailList(&ShutdownMsgList, &Entry->ListEntry);
954 WdfIoQueueStart(ReadQueue);
955 }
956 KdPrint((__DRIVER_NAME " <-- XenBus_ShutdownHandler\n"));
957 }
959 static VOID
960 XenBus_BalloonHandler(char *Path, PVOID Data)
961 {
962 WDFDEVICE Device = Data;
963 char *value;
964 xenbus_transaction_t xbt;
965 int retry;
967 UNREFERENCED_PARAMETER(Path);
969 KdPrint((__DRIVER_NAME " --> XenBus_BalloonHandler\n"));
971 XenBus_StartTransaction(Device, &xbt);
973 XenBus_Read(Device, XBT_NIL, BALLOON_PATH, &value);
975 KdPrint((__DRIVER_NAME " Balloon Value = %s\n", value));
977 // use the memory_op(unsigned int op, void *arg) hypercall to adjust this
978 // use XENMEM_increase_reservation and XENMEM_decrease_reservation
980 XenBus_EndTransaction(Device, xbt, 0, &retry);
982 KdPrint((__DRIVER_NAME " <-- XenBus_BalloonHandler\n"));
983 }
985 /*
986 IO_RESOURCE_DESCRIPTOR MemoryDescriptor;
988 static NTSTATUS
989 XenPCI_FilterRemoveResourceRequirements(WDFDEVICE Device, WDFIORESREQLIST RequirementsList)
990 {
991 NTSTATUS status;
992 WDFIORESLIST ResourceList;
993 PIO_RESOURCE_DESCRIPTOR Descriptor;
995 int i, j;
996 int offset;
998 //KdPrint((__DRIVER_NAME " --> FilterRemoveResourceRequirements\n"));
1000 for (i = 0; i < WdfIoResourceRequirementsListGetCount(RequirementsList); i++)
1002 ResourceList = WdfIoResourceRequirementsListGetIoResList(RequirementsList, i);
1003 //KdPrint((__DRIVER_NAME " Resource List %d\n", i));
1004 //KdPrint((__DRIVER_NAME " %d resources in list\n", WdfIoResourceListGetCount(ResourceList)));
1005 offset = 0;
1006 for (j = 0; j < WdfIoResourceListGetCount(ResourceList); j++)
1008 //KdPrint((__DRIVER_NAME " Resource %d\n", j));
1009 Descriptor = WdfIoResourceListGetDescriptor(ResourceList, j - offset);
1011 switch (Descriptor->Type) {
1012 case CmResourceTypePort:
1013 //KdPrint((__DRIVER_NAME " Port\n"));
1014 break;
1015 case CmResourceTypeMemory:
1016 //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));
1017 //KdPrint((__DRIVER_NAME " Length %08X\n", Descriptor->u.Memory.Length));
1018 //KdPrint((__DRIVER_NAME " ShareDisposition %02X\n", Descriptor->ShareDisposition));
1019 //KdPrint((__DRIVER_NAME " Option %02X\n", Descriptor->Option));
1020 if (!Descriptor->Option || Descriptor->Option == IO_RESOURCE_PREFERRED) {
1021 memcpy(&MemoryDescriptor, Descriptor, sizeof(IO_RESOURCE_DESCRIPTOR));
1022 //platform_mmio_orig_len = MemoryDescriptor.u.Memory.Length;
1023 //MemoryDescriptor.u.Memory.Length = PAGE_SIZE;
1024 MemoryDescriptor.ShareDisposition = CmResourceShareShared;
1026 WdfIoResourceListRemove(ResourceList, j - offset);
1027 offset++;
1028 break;
1029 case CmResourceTypeInterrupt:
1030 //KdPrint((__DRIVER_NAME " Interrupt\n"));
1031 break;
1032 case CmResourceTypeDevicePrivate:
1033 //KdPrint((__DRIVER_NAME " Private\n"));
1034 break;
1035 default:
1036 //KdPrint((__DRIVER_NAME " Unknown Type (0x%x)\n", Descriptor->Type));
1037 break;
1041 status = STATUS_SUCCESS;
1043 KdPrint((__DRIVER_NAME " <-- FilterRemoveResourceRequirements\n"));
1045 return status;
1049 static NTSTATUS
1050 XenPCI_FilterAddResourceRequirements(WDFDEVICE Device, WDFIORESREQLIST RequirementsList)
1052 NTSTATUS status;
1053 WDFIORESLIST ResourceList;
1054 PIO_RESOURCE_DESCRIPTOR Descriptor;
1056 int i, j;
1058 KdPrint((__DRIVER_NAME " --> FilterAddResourceRequirements\n"));
1061 for (i = 0; i < WdfIoResourceRequirementsListGetCount(RequirementsList); i++)
1063 ResourceList = WdfIoResourceRequirementsListGetIoResList(RequirementsList, i);
1064 //KdPrint((__DRIVER_NAME " Resource List %d\n", i));
1065 //KdPrint((__DRIVER_NAME " %d resources in list\n", WdfIoResourceListGetCount(ResourceList)));
1066 WdfIoResourceListAppendDescriptor(ResourceList, &MemoryDescriptor);
1067 //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));
1068 //KdPrint((__DRIVER_NAME " Length %08X\n", MemoryDescriptor.u.Memory.Length));
1069 for (j = 0; j < WdfIoResourceListGetCount(ResourceList); j++)
1071 //KdPrint((__DRIVER_NAME " Resource %d\n", j));
1072 Descriptor = WdfIoResourceListGetDescriptor(ResourceList, j);
1074 switch (Descriptor->Type) {
1075 case CmResourceTypePort:
1076 //KdPrint((__DRIVER_NAME " Port\n"));
1077 break;
1078 case CmResourceTypeMemory:
1079 //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));
1080 //KdPrint((__DRIVER_NAME " Length %08X\n", Descriptor->u.Memory.Length));
1081 //KdPrint((__DRIVER_NAME " ShareDisposition %02X\n", Descriptor->ShareDisposition));
1082 //Descriptor->ShareDisposition = CmResourceShareShared;
1083 //memcpy(&MemoryDescriptor, Descriptor, sizeof(IO_RESOURCE_DESCRIPTOR));
1084 //platform_mmio_orig_len = MemoryDescriptor.u.Memory.Length;
1085 //MemoryDescriptor.u.Memory.Length = PAGE_SIZE;
1086 //WdfIoResourceListRemove(ResourceList, j);
1087 break;
1088 case CmResourceTypeInterrupt:
1089 //KdPrint((__DRIVER_NAME " Interrupt\n"));
1090 break;
1091 case CmResourceTypeDevicePrivate:
1092 //KdPrint((__DRIVER_NAME " Private\n"));
1093 break;
1094 default:
1095 //KdPrint((__DRIVER_NAME " Unknown Type (0x%x)\n", Descriptor->Type));
1096 break;
1100 status = STATUS_SUCCESS;
1102 //KdPrint((__DRIVER_NAME " <-- FilterAddResourceRequirements\n"));
1104 return status;
1107 static NTSTATUS
1108 XenPCI_RemoveAddedResources(WDFDEVICE Device, WDFCMRESLIST ResourcesRaw, WDFCMRESLIST ResourcesTranslated)
1110 //KdPrint((__DRIVER_NAME " --> RemoveAddedResources\n"));
1111 //KdPrint((__DRIVER_NAME " <-- RemoveAddedResources\n"));
1113 return STATUS_SUCCESS;
1116 */
1118 static NTSTATUS
1119 XenPCI_DeviceResourceRequirementsQuery(WDFDEVICE Device, WDFIORESREQLIST IoResourceRequirementsList)
1121 NTSTATUS status;
1122 WDFIORESLIST resourceList;
1123 IO_RESOURCE_DESCRIPTOR descriptor;
1124 PXENPCI_DEVICE_DATA xpdd = GetDeviceData(Device);
1126 //KdPrint((__DRIVER_NAME " --> DeviceResourceRequirementsQuery\n"));
1128 status = WdfIoResourceListCreate(IoResourceRequirementsList, WDF_NO_OBJECT_ATTRIBUTES, &resourceList);
1129 if (!NT_SUCCESS(status))
1130 return status;
1132 /*
1133 RtlZeroMemory(&descriptor, sizeof(descriptor));
1135 descriptor.Option = 0;
1136 descriptor.Type = CmResourceTypeInterrupt;
1137 descriptor.ShareDisposition = CmResourceShareDeviceExclusive;
1138 descriptor.Flags = CM_RESOURCE_MEMORY_READ_WRITE;
1139 descriptor.u.Interrupt.MinimumVector = 1024;
1140 descriptor.u.Interrupt.MaximumVector = 1024+255;
1142 //KdPrint((__DRIVER_NAME " MinimumVector = %d, MaximumVector = %d\n", descriptor.u.Interrupt.MinimumVector, descriptor.u.Interrupt.MaximumVector));
1144 status = WdfIoResourceListAppendDescriptor(resourceList, &descriptor);
1145 if (!NT_SUCCESS(status))
1146 return status;
1147 */
1149 RtlZeroMemory(&descriptor, sizeof(descriptor));
1151 descriptor.Option = 0;
1152 descriptor.Type = CmResourceTypeMemory;
1153 descriptor.ShareDisposition = CmResourceShareShared; //CmResourceShareDeviceExclusive;
1154 descriptor.Flags = CM_RESOURCE_MEMORY_READ_WRITE;
1155 descriptor.u.Memory.Length = PAGE_SIZE;
1156 descriptor.u.Memory.Alignment = PAGE_SIZE;
1157 descriptor.u.Memory.MinimumAddress.QuadPart
1158 = xpdd->platform_mmio_addr.QuadPart + PAGE_SIZE;
1159 descriptor.u.Memory.MaximumAddress.QuadPart
1160 = xpdd->platform_mmio_addr.QuadPart + xpdd->platform_mmio_len - 1;
1162 //KdPrint((__DRIVER_NAME " MinimumAddress = %08x, MaximumAddress = %08X\n", descriptor.u.Memory.MinimumAddress.LowPart, descriptor.u.Memory.MaximumAddress.LowPart));
1164 status = WdfIoResourceListAppendDescriptor(resourceList, &descriptor);
1165 if (!NT_SUCCESS(status))
1166 return status;
1168 status = WdfIoResourceRequirementsListAppendIoResList(IoResourceRequirementsList, resourceList);
1169 if (!NT_SUCCESS(status))
1170 return status;
1172 //KdPrint((__DRIVER_NAME " <-- DeviceResourceRequirementsQuery\n"));
1174 return status;