📄 resource.c
字号:
/*
* VideoPort driver
*
* Copyright (C) 2002 - 2005 ReactOS Team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; see the file COPYING.LIB.
* If not, write to the Free Software Foundation,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Id: resource.c 21844 2006-05-07 19:34:23Z ion $
*/
#include "videoprt.h"
/* PRIVATE FUNCTIONS **********************************************************/
NTSTATUS NTAPI
IntVideoPortMapPhysicalMemory(
IN HANDLE Process,
IN PHYSICAL_ADDRESS PhysicalAddress,
IN ULONG SizeInBytes,
IN ULONG Protect,
IN OUT PVOID *VirtualAddress OPTIONAL)
{
OBJECT_ATTRIBUTES ObjAttribs;
UNICODE_STRING UnicodeString;
HANDLE hMemObj;
NTSTATUS Status;
SIZE_T Size;
/* Initialize object attribs */
RtlInitUnicodeString(&UnicodeString, L"\\Device\\PhysicalMemory");
InitializeObjectAttributes(&ObjAttribs,
&UnicodeString,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL, NULL);
/* Open physical memory section */
Status = ZwOpenSection(&hMemObj, SECTION_ALL_ACCESS, &ObjAttribs);
if (!NT_SUCCESS(Status))
{
DPRINT("ZwOpenSection() failed! (0x%x)\n", Status);
return Status;
}
/* Map view of section */
Size = SizeInBytes;
Status = ZwMapViewOfSection(hMemObj,
Process,
VirtualAddress,
0,
Size,
(PLARGE_INTEGER)(&PhysicalAddress),
&Size,
ViewUnmap,
0,
Protect);
ZwClose(hMemObj);
if (!NT_SUCCESS(Status))
{
DPRINT("ZwMapViewOfSection() failed! (0x%x)\n", Status);
}
return Status;
}
PVOID NTAPI
IntVideoPortMapMemory(
IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension,
IN PHYSICAL_ADDRESS IoAddress,
IN ULONG NumberOfUchars,
IN UCHAR InIoSpace,
IN HANDLE ProcessHandle,
OUT VP_STATUS *Status)
{
PHYSICAL_ADDRESS TranslatedAddress;
PVIDEO_PORT_ADDRESS_MAPPING AddressMapping;
ULONG AddressSpace;
PVOID MappedAddress;
PLIST_ENTRY Entry;
DPRINT("- IoAddress: %lx\n", IoAddress.u.LowPart);
DPRINT("- NumberOfUchars: %lx\n", NumberOfUchars);
DPRINT("- InIoSpace: %x\n", InIoSpace);
InIoSpace &= ~VIDEO_MEMORY_SPACE_DENSE;
if ((InIoSpace & VIDEO_MEMORY_SPACE_P6CACHE) != 0)
{
DPRINT("VIDEO_MEMORY_SPACE_P6CACHE not supported, turning off\n");
InIoSpace &= ~VIDEO_MEMORY_SPACE_P6CACHE;
}
if (ProcessHandle != NULL && (InIoSpace & VIDEO_MEMORY_SPACE_USER_MODE) == 0)
{
DPRINT("ProcessHandle is not NULL (0x%x) but InIoSpace does not have "
"VIDEO_MEMORY_SPACE_USER_MODE set! Setting "
"VIDEO_MEMORY_SPACE_USER_MODE.\n",
ProcessHandle);
InIoSpace |= VIDEO_MEMORY_SPACE_USER_MODE;
}
else if (ProcessHandle == NULL && (InIoSpace & VIDEO_MEMORY_SPACE_USER_MODE) != 0)
{
DPRINT("ProcessHandle is NULL (0x%x) but InIoSpace does have "
"VIDEO_MEMORY_SPACE_USER_MODE set! Setting ProcessHandle "
"to NtCurrentProcess()\n",
ProcessHandle);
ProcessHandle = NtCurrentProcess();
}
if ((InIoSpace & VIDEO_MEMORY_SPACE_USER_MODE) == 0 &&
!IsListEmpty(&DeviceExtension->AddressMappingListHead))
{
Entry = DeviceExtension->AddressMappingListHead.Flink;
while (Entry != &DeviceExtension->AddressMappingListHead)
{
AddressMapping = CONTAINING_RECORD(
Entry,
VIDEO_PORT_ADDRESS_MAPPING,
List);
if (IoAddress.QuadPart == AddressMapping->IoAddress.QuadPart &&
NumberOfUchars <= AddressMapping->NumberOfUchars)
{
{
AddressMapping->MappingCount++;
if (Status)
*Status = NO_ERROR;
return AddressMapping->MappedAddress;
}
}
Entry = Entry->Flink;
}
}
AddressSpace = (ULONG)InIoSpace;
AddressSpace &= ~VIDEO_MEMORY_SPACE_USER_MODE;
if (HalTranslateBusAddress(
DeviceExtension->AdapterInterfaceType,
DeviceExtension->SystemIoBusNumber,
IoAddress,
&AddressSpace,
&TranslatedAddress) == FALSE)
{
if (Status)
*Status = ERROR_NOT_ENOUGH_MEMORY;
return NULL;
}
/* I/O space */
if (AddressSpace != 0)
{
ASSERT(0 == TranslatedAddress.u.HighPart);
if (Status)
*Status = NO_ERROR;
return (PVOID)TranslatedAddress.u.LowPart;
}
/* user space */
if ((InIoSpace & VIDEO_MEMORY_SPACE_USER_MODE) != 0)
{
NTSTATUS NtStatus;
MappedAddress = NULL;
NtStatus = IntVideoPortMapPhysicalMemory(ProcessHandle,
TranslatedAddress,
NumberOfUchars,
PAGE_READWRITE/* | PAGE_WRITECOMBINE*/,
&MappedAddress);
if (!NT_SUCCESS(NtStatus))
{
DPRINT("IntVideoPortMapPhysicalMemory() failed! (0x%x)\n", NtStatus);
if (Status)
*Status = NO_ERROR;
return NULL;
}
DPRINT("Mapped user address = 0x%08x\n", MappedAddress);
}
else /* kernel space */
{
MappedAddress = MmMapIoSpace(
TranslatedAddress,
NumberOfUchars,
MmNonCached);
}
if (MappedAddress != NULL)
{
if (Status)
{
*Status = NO_ERROR;
}
if ((InIoSpace & VIDEO_MEMORY_SPACE_USER_MODE) == 0)
{
AddressMapping = ExAllocatePoolWithTag(
PagedPool,
sizeof(VIDEO_PORT_ADDRESS_MAPPING),
TAG_VIDEO_PORT);
if (AddressMapping == NULL)
return MappedAddress;
RtlZeroMemory(AddressMapping, sizeof(VIDEO_PORT_ADDRESS_MAPPING));
AddressMapping->NumberOfUchars = NumberOfUchars;
AddressMapping->IoAddress = IoAddress;
AddressMapping->SystemIoBusNumber = DeviceExtension->SystemIoBusNumber;
AddressMapping->MappedAddress = MappedAddress;
AddressMapping->MappingCount = 1;
InsertHeadList(
&DeviceExtension->AddressMappingListHead,
&AddressMapping->List);
}
return MappedAddress;
}
if (Status)
*Status = NO_ERROR;
return NULL;
}
VOID NTAPI
IntVideoPortUnmapMemory(
IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension,
IN PVOID MappedAddress)
{
PVIDEO_PORT_ADDRESS_MAPPING AddressMapping;
PLIST_ENTRY Entry;
NTSTATUS Status;
Entry = DeviceExtension->AddressMappingListHead.Flink;
while (Entry != &DeviceExtension->AddressMappingListHead)
{
AddressMapping = CONTAINING_RECORD(
Entry,
VIDEO_PORT_ADDRESS_MAPPING,
List);
if (AddressMapping->MappedAddress == MappedAddress)
{
ASSERT(AddressMapping->MappingCount > 0);
AddressMapping->MappingCount--;
if (AddressMapping->MappingCount == 0)
{
MmUnmapIoSpace(
AddressMapping->MappedAddress,
AddressMapping->NumberOfUchars);
RemoveEntryList(Entry);
ExFreePool(AddressMapping);
}
return;
}
Entry = Entry->Flink;
}
/* If there was no kernelmode mapping for the given address found we assume
* that the given address is a usermode mapping and try to unmap it.
*
* FIXME: Is it ok to use NtCurrentProcess?
*/
Status = ZwUnmapViewOfSection(NtCurrentProcess(), MappedAddress);
if (!NT_SUCCESS(Status))
{
DPRINT1("Warning: Mapping for address 0x%x not found!\n", (ULONG)MappedAddress);
}
}
/* PUBLIC FUNCTIONS ***********************************************************/
/*
* @implemented
*/
PVOID NTAPI
VideoPortGetDeviceBase(
IN PVOID HwDeviceExtension,
IN PHYSICAL_ADDRESS IoAddress,
IN ULONG NumberOfUchars,
IN UCHAR InIoSpace)
{
DPRINT("VideoPortGetDeviceBase\n");
return IntVideoPortMapMemory(
VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension),
IoAddress,
NumberOfUchars,
InIoSpace,
NULL,
NULL);
}
/*
* @implemented
*/
VOID NTAPI
VideoPortFreeDeviceBase(
IN PVOID HwDeviceExtension,
IN PVOID MappedAddress)
{
DPRINT("VideoPortFreeDeviceBase\n");
IntVideoPortUnmapMemory(
VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension),
MappedAddress);
}
/*
* @unimplemented
*/
VP_STATUS NTAPI
VideoPortMapBankedMemory(
IN PVOID HwDeviceExtension,
IN PHYSICAL_ADDRESS PhysicalAddress,
IN PULONG Length,
IN PULONG InIoSpace,
OUT PVOID *VirtualAddress,
IN ULONG BankLength,
IN UCHAR ReadWriteBank,
IN PBANKED_SECTION_ROUTINE BankRoutine,
IN PVOID Context)
{
DPRINT("VideoPortMapBankedMemory\n");
UNIMPLEMENTED;
return ERROR_CALL_NOT_IMPLEMENTED;
}
/*
* @implemented
*/
VP_STATUS NTAPI
VideoPortMapMemory(
IN PVOID HwDeviceExtension,
IN PHYSICAL_ADDRESS PhysicalAddress,
IN PULONG Length,
IN PULONG InIoSpace,
OUT PVOID *VirtualAddress)
{
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
NTSTATUS Status;
DPRINT("VideoPortMapMemory\n");
DPRINT("- *VirtualAddress: 0x%x\n", *VirtualAddress);
DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
*VirtualAddress = IntVideoPortMapMemory(
DeviceExtension,
PhysicalAddress,
*Length,
*InIoSpace,
(HANDLE)*VirtualAddress,
&Status);
return Status;
}
/*
* @implemented
*/
VP_STATUS NTAPI
VideoPortUnmapMemory(
IN PVOID HwDeviceExtension,
IN PVOID VirtualAddress,
IN HANDLE ProcessHandle)
{
DPRINT("VideoPortFreeDeviceBase\n");
IntVideoPortUnmapMemory(
VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension),
VirtualAddress);
return NO_ERROR;
}
/*
* @implemented
*/
VP_STATUS NTAPI
VideoPortGetAccessRanges(
IN PVOID HwDeviceExtension,
IN ULONG NumRequestedResources,
IN PIO_RESOURCE_DESCRIPTOR RequestedResources OPTIONAL,
IN ULONG NumAccessRanges,
IN PVIDEO_ACCESS_RANGE AccessRanges,
IN PVOID VendorId,
IN PVOID DeviceId,
IN PULONG Slot)
{
PCI_SLOT_NUMBER PciSlotNumber;
ULONG FunctionNumber;
PCI_COMMON_CONFIG Config;
PCM_RESOURCE_LIST AllocatedResources;
NTSTATUS Status;
UINT AssignedCount;
CM_FULL_RESOURCE_DESCRIPTOR *FullList;
CM_PARTIAL_RESOURCE_DESCRIPTOR *Descriptor;
PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
USHORT VendorIdToFind;
USHORT DeviceIdToFind;
ULONG SlotIdToFind;
ULONG ReturnedLength;
DPRINT("VideoPortGetAccessRanges\n");
DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -