4 * Copyright (C) 2002, 2003, 2004 ReactOS Team
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; see the file COPYING.LIB.
18 * If not, write to the Free Software Foundation,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 /* PRIVATE FUNCTIONS **********************************************************/
29 IntVideoPortMapMemory(
30 IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
,
31 IN PHYSICAL_ADDRESS IoAddress
,
32 IN ULONG NumberOfUchars
,
34 OUT VP_STATUS
*Status
)
36 PHYSICAL_ADDRESS TranslatedAddress
;
37 PVIDEO_PORT_ADDRESS_MAPPING AddressMapping
= NULL
;
42 DPRINT("- IoAddress: %lx\n", IoAddress
.u
.LowPart
);
43 DPRINT("- NumberOfUchars: %lx\n", NumberOfUchars
);
44 DPRINT("- InIoSpace: %x\n", InIoSpace
);
46 InIoSpace
&= ~VIDEO_MEMORY_SPACE_DENSE
;
47 if ((InIoSpace
& VIDEO_MEMORY_SPACE_P6CACHE
) != 0)
49 DPRINT("VIDEO_MEMORY_SPACE_P6CACHE not supported, turning off\n");
50 InIoSpace
&= ~VIDEO_MEMORY_SPACE_P6CACHE
;
53 if (!IsListEmpty(&DeviceExtension
->AddressMappingListHead
))
55 Entry
= DeviceExtension
->AddressMappingListHead
.Flink
;
56 while (Entry
!= &DeviceExtension
->AddressMappingListHead
)
58 AddressMapping
= CONTAINING_RECORD(
60 VIDEO_PORT_ADDRESS_MAPPING
,
62 if (IoAddress
.QuadPart
== AddressMapping
->IoAddress
.QuadPart
&&
63 NumberOfUchars
<= AddressMapping
->NumberOfUchars
)
65 if ((InIoSpace
& VIDEO_MEMORY_SPACE_USER_MODE
) != 0 &&
66 AddressMapping
->MappedUserAddress
!= NULL
)
68 AddressMapping
->UserMappingCount
++;
71 return AddressMapping
->MappedUserAddress
;
73 else if ((InIoSpace
& VIDEO_MEMORY_SPACE_USER_MODE
) == 0 &&
74 AddressMapping
->MappedUserAddress
!= NULL
)
76 AddressMapping
->MappingCount
++;
79 return AddressMapping
->MappedAddress
;
85 if (Entry
== &DeviceExtension
->AddressMappingListHead
)
86 AddressMapping
= NULL
;
89 AddressSpace
= (ULONG
)InIoSpace
;
90 AddressSpace
&= ~VIDEO_MEMORY_SPACE_USER_MODE
;
91 if (HalTranslateBusAddress(
92 DeviceExtension
->AdapterInterfaceType
,
93 DeviceExtension
->SystemIoBusNumber
,
96 &TranslatedAddress
) == FALSE
)
99 *Status
= ERROR_NOT_ENOUGH_MEMORY
;
105 if (AddressSpace
!= 0)
107 ASSERT(0 == TranslatedAddress
.u
.HighPart
);
111 return (PVOID
)TranslatedAddress
.u
.LowPart
;
115 if ((InIoSpace
& VIDEO_MEMORY_SPACE_USER_MODE
) != 0)
117 OBJECT_ATTRIBUTES ObjAttribs
;
118 UNICODE_STRING UnicodeString
;
123 RtlInitUnicodeString(&UnicodeString
, L
"\\Device\\PhysicalMemory");
124 InitializeObjectAttributes(&ObjAttribs
,
126 OBJ_CASE_INSENSITIVE
/* | OBJ_KERNEL_HANDLE*/,
128 NtStatus
= ZwOpenSection(&hMemObj
, SECTION_ALL_ACCESS
, &ObjAttribs
);
129 if (!NT_SUCCESS(NtStatus
))
131 DPRINT("ZwOpenSection() failed! (0x%x)\n", NtStatus
);
136 Size
= NumberOfUchars
;
137 MappedAddress
= NULL
;
138 NtStatus
= ZwMapViewOfSection(hMemObj
,
143 (PLARGE_INTEGER
)(&TranslatedAddress
),
147 PAGE_READWRITE
/* | PAGE_WRITECOMBINE*/);
148 if (!NT_SUCCESS(NtStatus
))
150 DPRINT("ZwMapViewOfSection() failed! (0x%x)\n", NtStatus
);
157 DPRINT("Mapped user address = 0x%08x\n", MappedAddress
);
159 else /* kernel space */
161 MappedAddress
= MmMapIoSpace(
167 if (MappedAddress
!= NULL
)
169 BOOL InsertIntoList
= FALSE
;
175 if (AddressMapping
== NULL
)
177 AddressMapping
= ExAllocatePoolWithTag(
179 sizeof(VIDEO_PORT_ADDRESS_MAPPING
),
182 if (AddressMapping
== NULL
)
183 return MappedAddress
;
185 InsertIntoList
= TRUE
;
186 RtlZeroMemory(AddressMapping
, sizeof(VIDEO_PORT_ADDRESS_MAPPING
));
187 AddressMapping
->NumberOfUchars
= NumberOfUchars
;
188 AddressMapping
->IoAddress
= IoAddress
;
189 AddressMapping
->SystemIoBusNumber
= DeviceExtension
->SystemIoBusNumber
;
192 if ((InIoSpace
& VIDEO_MEMORY_SPACE_USER_MODE
) != 0)
194 AddressMapping
->MappedUserAddress
= MappedAddress
;
195 AddressMapping
->UserMappingCount
= 1;
199 AddressMapping
->MappedAddress
= MappedAddress
;
200 AddressMapping
->MappingCount
= 1;
206 &DeviceExtension
->AddressMappingListHead
,
207 &AddressMapping
->List
);
210 return MappedAddress
;
220 IntVideoPortUnmapMemory(
221 IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
,
222 IN PVOID MappedAddress
)
224 PVIDEO_PORT_ADDRESS_MAPPING AddressMapping
;
227 Entry
= DeviceExtension
->AddressMappingListHead
.Flink
;
228 while (Entry
!= &DeviceExtension
->AddressMappingListHead
)
230 AddressMapping
= CONTAINING_RECORD(
232 VIDEO_PORT_ADDRESS_MAPPING
,
234 if (AddressMapping
->MappedUserAddress
== MappedAddress
)
236 ASSERT(AddressMapping
->UserMappingCount
> 0);
237 AddressMapping
->UserMappingCount
--;
238 if (AddressMapping
->UserMappingCount
== 0)
240 ZwUnmapViewOfSection(NtCurrentProcess(),
241 AddressMapping
->MappedUserAddress
);
242 AddressMapping
->MappedUserAddress
= NULL
;
243 if (AddressMapping
->MappingCount
== 0)
245 RemoveEntryList(Entry
);
246 ExFreePool(AddressMapping
);
251 else if (AddressMapping
->MappedAddress
== MappedAddress
)
253 ASSERT(AddressMapping
->MappingCount
> 0);
254 AddressMapping
->MappingCount
--;
255 if (AddressMapping
->MappingCount
== 0)
258 AddressMapping
->MappedAddress
,
259 AddressMapping
->NumberOfUchars
);
260 AddressMapping
->MappedAddress
= NULL
;
261 if (AddressMapping
->UserMappingCount
== 0)
263 RemoveEntryList(Entry
);
264 ExFreePool(AddressMapping
);
270 Entry
= Entry
->Flink
;
274 /* PUBLIC FUNCTIONS ***********************************************************/
281 VideoPortGetDeviceBase(
282 IN PVOID HwDeviceExtension
,
283 IN PHYSICAL_ADDRESS IoAddress
,
284 IN ULONG NumberOfUchars
,
287 DPRINT("VideoPortGetDeviceBase\n");
288 return IntVideoPortMapMemory(
289 VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
),
301 VideoPortFreeDeviceBase(
302 IN PVOID HwDeviceExtension
,
303 IN PVOID MappedAddress
)
305 DPRINT("VideoPortFreeDeviceBase\n");
306 IntVideoPortUnmapMemory(
307 VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
),
316 VideoPortMapBankedMemory(
317 IN PVOID HwDeviceExtension
,
318 IN PHYSICAL_ADDRESS PhysicalAddress
,
321 OUT PVOID
*VirtualAddress
,
323 IN UCHAR ReadWriteBank
,
324 IN PBANKED_SECTION_ROUTINE BankRoutine
,
327 DPRINT("VideoPortMapBankedMemory\n");
329 return ERROR_CALL_NOT_IMPLEMENTED
;
339 IN PVOID HwDeviceExtension
,
340 IN PHYSICAL_ADDRESS PhysicalAddress
,
343 OUT PVOID
*VirtualAddress
)
345 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
348 DPRINT("VideoPortMapMemory\n");
350 DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
351 *VirtualAddress
= IntVideoPortMapMemory(
366 VideoPortUnmapMemory(
367 IN PVOID HwDeviceExtension
,
368 IN PVOID VirtualAddress
,
369 IN HANDLE ProcessHandle
)
371 DPRINT("VideoPortFreeDeviceBase\n");
373 IntVideoPortUnmapMemory(
374 VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
),
385 VideoPortGetAccessRanges(
386 IN PVOID HwDeviceExtension
,
387 IN ULONG NumRequestedResources
,
388 IN PIO_RESOURCE_DESCRIPTOR RequestedResources OPTIONAL
,
389 IN ULONG NumAccessRanges
,
390 IN PVIDEO_ACCESS_RANGE AccessRanges
,
395 PCI_SLOT_NUMBER PciSlotNumber
;
396 ULONG FunctionNumber
;
397 PCI_COMMON_CONFIG Config
;
398 PCM_RESOURCE_LIST AllocatedResources
;
401 CM_FULL_RESOURCE_DESCRIPTOR
*FullList
;
402 CM_PARTIAL_RESOURCE_DESCRIPTOR
*Descriptor
;
403 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
404 USHORT VendorIdToFind
;
405 USHORT DeviceIdToFind
;
407 ULONG ReturnedLength
;
409 DPRINT("VideoPortGetAccessRanges\n");
411 DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
413 if (NumRequestedResources
== 0 &&
414 DeviceExtension
->AdapterInterfaceType
== PCIBus
)
416 if (DeviceExtension
->PhysicalDeviceObject
!= NULL
)
418 PciSlotNumber
.u
.AsULONG
= DeviceExtension
->SystemIoSlotNumber
;
420 ReturnedLength
= HalGetBusData(
422 DeviceExtension
->SystemIoBusNumber
,
423 PciSlotNumber
.u
.AsULONG
,
425 sizeof(PCI_COMMON_CONFIG
));
427 if (ReturnedLength
!= sizeof(PCI_COMMON_CONFIG
))
429 return ERROR_NO_SYSTEM_RESOURCES
;
434 VendorIdToFind
= VendorId
!= NULL
? *(PUSHORT
)VendorId
: 0;
435 DeviceIdToFind
= DeviceId
!= NULL
? *(PUSHORT
)DeviceId
: 0;
436 SlotIdToFind
= Slot
!= NULL
? *Slot
: 0;
437 PciSlotNumber
.u
.AsULONG
= SlotIdToFind
;
439 DPRINT("Looking for VendorId 0x%04x DeviceId 0x%04x\n",
440 VendorIdToFind
, DeviceIdToFind
);
443 * Search for the device id and vendor id on this bus.
446 for (FunctionNumber
= 0; FunctionNumber
< 8; FunctionNumber
++)
448 DPRINT("- Function number: %d\n", FunctionNumber
);
449 PciSlotNumber
.u
.bits
.FunctionNumber
= FunctionNumber
;
450 ReturnedLength
= HalGetBusData(
452 DeviceExtension
->SystemIoBusNumber
,
453 PciSlotNumber
.u
.AsULONG
,
455 sizeof(PCI_COMMON_CONFIG
));
456 DPRINT("- Length of data: %x\n", ReturnedLength
);
457 if (ReturnedLength
== sizeof(PCI_COMMON_CONFIG
))
459 DPRINT("- Slot 0x%02x (Device %d Function %d) VendorId 0x%04x "
461 PciSlotNumber
.u
.AsULONG
,
462 PciSlotNumber
.u
.bits
.DeviceNumber
,
463 PciSlotNumber
.u
.bits
.FunctionNumber
,
467 if ((VendorIdToFind
== 0 || Config
.VendorID
== VendorIdToFind
) &&
468 (DeviceIdToFind
== 0 || Config
.DeviceID
== DeviceIdToFind
))
475 if (FunctionNumber
== 8)
477 DPRINT("Didn't find device.\n");
478 return ERROR_DEV_NOT_EXIST
;
482 Status
= HalAssignSlotResources(
483 NULL
, NULL
, NULL
, NULL
,
484 DeviceExtension
->AdapterInterfaceType
,
485 DeviceExtension
->SystemIoBusNumber
,
486 PciSlotNumber
.u
.AsULONG
,
487 &AllocatedResources
);
489 if (!NT_SUCCESS(Status
))
495 for (FullList
= AllocatedResources
->List
;
496 FullList
< AllocatedResources
->List
+ AllocatedResources
->Count
;
499 ASSERT(FullList
->InterfaceType
== PCIBus
&&
500 FullList
->BusNumber
== DeviceExtension
->SystemIoBusNumber
&&
501 1 == FullList
->PartialResourceList
.Version
&&
502 1 == FullList
->PartialResourceList
.Revision
);
503 for (Descriptor
= FullList
->PartialResourceList
.PartialDescriptors
;
504 Descriptor
< FullList
->PartialResourceList
.PartialDescriptors
+ FullList
->PartialResourceList
.Count
;
507 if ((Descriptor
->Type
== CmResourceTypeMemory
||
508 Descriptor
->Type
== CmResourceTypePort
) &&
509 AssignedCount
>= NumAccessRanges
)
511 DPRINT1("Too many access ranges found\n");
512 ExFreePool(AllocatedResources
);
513 return ERROR_NO_SYSTEM_RESOURCES
;
515 if (Descriptor
->Type
== CmResourceTypeMemory
)
517 if (NumAccessRanges
<= AssignedCount
)
519 DPRINT1("Too many access ranges found\n");
520 ExFreePool(AllocatedResources
);
521 return ERROR_NO_SYSTEM_RESOURCES
;
523 DPRINT("Memory range starting at 0x%08x length 0x%08x\n",
524 Descriptor
->u
.Memory
.Start
.u
.LowPart
, Descriptor
->u
.Memory
.Length
);
525 AccessRanges
[AssignedCount
].RangeStart
= Descriptor
->u
.Memory
.Start
;
526 AccessRanges
[AssignedCount
].RangeLength
= Descriptor
->u
.Memory
.Length
;
527 AccessRanges
[AssignedCount
].RangeInIoSpace
= 0;
528 AccessRanges
[AssignedCount
].RangeVisible
= 0; /* FIXME: Just guessing */
529 AccessRanges
[AssignedCount
].RangeShareable
=
530 (Descriptor
->ShareDisposition
== CmResourceShareShared
);
533 else if (Descriptor
->Type
== CmResourceTypePort
)
535 DPRINT("Port range starting at 0x%04x length %d\n",
536 Descriptor
->u
.Memory
.Start
.u
.LowPart
, Descriptor
->u
.Memory
.Length
);
537 AccessRanges
[AssignedCount
].RangeStart
= Descriptor
->u
.Port
.Start
;
538 AccessRanges
[AssignedCount
].RangeLength
= Descriptor
->u
.Port
.Length
;
539 AccessRanges
[AssignedCount
].RangeInIoSpace
= 1;
540 AccessRanges
[AssignedCount
].RangeVisible
= 0; /* FIXME: Just guessing */
541 AccessRanges
[AssignedCount
].RangeShareable
= 0;
544 else if (Descriptor
->Type
== CmResourceTypeInterrupt
)
546 DeviceExtension
->InterruptLevel
= Descriptor
->u
.Interrupt
.Level
;
547 DeviceExtension
->InterruptVector
= Descriptor
->u
.Interrupt
.Vector
;
551 ExFreePool(AllocatedResources
);
566 VideoPortVerifyAccessRanges(
567 IN PVOID HwDeviceExtension
,
568 IN ULONG NumAccessRanges
,
569 IN PVIDEO_ACCESS_RANGE AccessRanges
)
571 DPRINT1("VideoPortVerifyAccessRanges not implemented\n");
580 VideoPortGetDeviceData(
581 IN PVOID HwDeviceExtension
,
582 IN VIDEO_DEVICE_DATA_TYPE DeviceDataType
,
583 IN PMINIPORT_QUERY_DEVICE_ROUTINE CallbackRoutine
,
586 DPRINT("VideoPortGetDeviceData\n");
588 return ERROR_CALL_NOT_IMPLEMENTED
;
596 VideoPortAllocatePool(
597 IN PVOID HwDeviceExtension
,
598 IN VP_POOL_TYPE PoolType
,
599 IN SIZE_T NumberOfBytes
,
602 DPRINT("VideoPortAllocatePool\n");
603 return ExAllocatePoolWithTag(PoolType
, NumberOfBytes
, Tag
);
612 IN PVOID HwDeviceExtension
,
623 VideoPortAllocateBuffer(
624 IN PVOID HwDeviceExtension
,
628 DPRINT("VideoPortAllocateBuffer\n");
629 *Buffer
= ExAllocatePool(PagedPool
, Size
);
630 return *Buffer
== NULL
? ERROR_NOT_ENOUGH_MEMORY
: NO_ERROR
;
638 VideoPortReleaseBuffer(
639 IN PVOID HwDeviceExtension
,
642 DPRINT("VideoPortReleaseBuffer\n");
652 IN PVOID HwDeviceExtension
,
653 IN PVOID BaseAddress
,
655 IN VP_LOCK_OPERATION Operation
)
657 DPRINT1("VideoPortLockBuffer: Unimplemented.\n");
666 VideoPortUnlockBuffer(
667 IN PVOID HwDeviceExtension
,
670 DPRINT1("VideoPortUnlockBuffer: Unimplemented.\n");
678 VideoPortSetTrappedEmulatorPorts(
679 IN PVOID HwDeviceExtension
,
680 IN ULONG NumAccessRanges
,
681 IN PVIDEO_ACCESS_RANGE AccessRange
)
683 DPRINT("VideoPortSetTrappedEmulatorPorts\n");
684 /* Should store the ranges in the device extension for use by ntvdm. */
694 IN PVOID HwDeviceExtension
,
695 IN BUS_DATA_TYPE BusDataType
,
701 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
703 DPRINT("VideoPortGetBusData\n");
705 DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
707 if (BusDataType
!= Cmos
)
709 /* Legacy vs. PnP behaviour */
710 if (DeviceExtension
->PhysicalDeviceObject
!= NULL
)
711 SlotNumber
= DeviceExtension
->SystemIoSlotNumber
;
714 return HalGetBusDataByOffset(
716 DeviceExtension
->SystemIoBusNumber
,
729 IN PVOID HwDeviceExtension
,
730 IN BUS_DATA_TYPE BusDataType
,
736 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
738 DPRINT("VideoPortSetBusData\n");
740 DeviceExtension
= VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension
);
742 if (BusDataType
!= Cmos
)
744 /* Legacy vs. PnP behaviour */
745 if (DeviceExtension
->PhysicalDeviceObject
!= NULL
)
746 SlotNumber
= DeviceExtension
->SystemIoSlotNumber
;
749 return HalSetBusDataByOffset(
751 DeviceExtension
->SystemIoBusNumber
,