mirror of
https://github.com/reactos/reactos.git
synced 2024-07-02 10:45:24 +00:00
Support mapping of video device memory into usermode - unfortunately this is not correctly supported by the memory manager yet.
svn path=/trunk/; revision=12207
This commit is contained in:
parent
5016bfecf7
commit
c37ff99746
|
@ -18,7 +18,7 @@
|
|||
* If not, write to the Free Software Foundation,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* $Id: resource.c,v 1.4 2004/10/15 22:48:43 gvg Exp $
|
||||
* $Id: resource.c,v 1.5 2004/12/18 22:14:38 blight Exp $
|
||||
*/
|
||||
|
||||
#include "videoprt.h"
|
||||
|
@ -34,7 +34,7 @@ IntVideoPortMapMemory(
|
|||
OUT VP_STATUS *Status)
|
||||
{
|
||||
PHYSICAL_ADDRESS TranslatedAddress;
|
||||
PVIDEO_PORT_ADDRESS_MAPPING AddressMapping;
|
||||
PVIDEO_PORT_ADDRESS_MAPPING AddressMapping = NULL;
|
||||
ULONG AddressSpace;
|
||||
PVOID MappedAddress;
|
||||
PLIST_ENTRY Entry;
|
||||
|
@ -62,17 +62,32 @@ IntVideoPortMapMemory(
|
|||
if (IoAddress.QuadPart == AddressMapping->IoAddress.QuadPart &&
|
||||
NumberOfUchars <= AddressMapping->NumberOfUchars)
|
||||
{
|
||||
AddressMapping->MappingCount++;
|
||||
if (Status)
|
||||
*Status = NO_ERROR;
|
||||
|
||||
return AddressMapping->MappedAddress;
|
||||
if ((InIoSpace & VIDEO_MEMORY_SPACE_USER_MODE) != 0 &&
|
||||
AddressMapping->MappedUserAddress != NULL)
|
||||
{
|
||||
AddressMapping->UserMappingCount++;
|
||||
if (Status)
|
||||
*Status = NO_ERROR;
|
||||
return AddressMapping->MappedUserAddress;
|
||||
}
|
||||
else if ((InIoSpace & VIDEO_MEMORY_SPACE_USER_MODE) == 0 &&
|
||||
AddressMapping->MappedUserAddress != NULL)
|
||||
{
|
||||
AddressMapping->MappingCount++;
|
||||
if (Status)
|
||||
*Status = NO_ERROR;
|
||||
return AddressMapping->MappedAddress;
|
||||
}
|
||||
break;
|
||||
}
|
||||
Entry = Entry->Flink;
|
||||
}
|
||||
if (Entry == &DeviceExtension->AddressMappingListHead)
|
||||
AddressMapping = NULL;
|
||||
}
|
||||
|
||||
AddressSpace = (ULONG)InIoSpace;
|
||||
AddressSpace &= ~VIDEO_MEMORY_SPACE_USER_MODE;
|
||||
if (HalTranslateBusAddress(
|
||||
DeviceExtension->AdapterInterfaceType,
|
||||
DeviceExtension->SystemIoBusNumber,
|
||||
|
@ -96,45 +111,109 @@ IntVideoPortMapMemory(
|
|||
return (PVOID)TranslatedAddress.u.LowPart;
|
||||
}
|
||||
|
||||
MappedAddress = MmMapIoSpace(
|
||||
TranslatedAddress,
|
||||
NumberOfUchars,
|
||||
MmNonCached);
|
||||
|
||||
if (MappedAddress)
|
||||
/* user space */
|
||||
if ((InIoSpace & VIDEO_MEMORY_SPACE_USER_MODE) != 0)
|
||||
{
|
||||
OBJECT_ATTRIBUTES ObjAttribs;
|
||||
UNICODE_STRING UnicodeString;
|
||||
HANDLE hMemObj;
|
||||
NTSTATUS NtStatus;
|
||||
SIZE_T Size;
|
||||
|
||||
RtlInitUnicodeString(&UnicodeString, L"\\Device\\PhysicalMemory");
|
||||
InitializeObjectAttributes(&ObjAttribs,
|
||||
&UnicodeString,
|
||||
OBJ_CASE_INSENSITIVE/* | OBJ_KERNEL_HANDLE*/,
|
||||
NULL, NULL);
|
||||
NtStatus = ZwOpenSection(&hMemObj, SECTION_ALL_ACCESS, &ObjAttribs);
|
||||
if (!NT_SUCCESS(NtStatus))
|
||||
{
|
||||
DPRINT("ZwOpenSection() failed! (0x%x)\n", NtStatus);
|
||||
if (Status)
|
||||
*Status = NO_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
Size = NumberOfUchars;
|
||||
MappedAddress = NULL;
|
||||
NtStatus = ZwMapViewOfSection(hMemObj,
|
||||
NtCurrentProcess(),
|
||||
&MappedAddress,
|
||||
0,
|
||||
NumberOfUchars,
|
||||
(PLARGE_INTEGER)(&TranslatedAddress),
|
||||
&Size,
|
||||
ViewUnmap,
|
||||
0,
|
||||
PAGE_READWRITE/* | PAGE_WRITECOMBINE*/);
|
||||
if (!NT_SUCCESS(NtStatus))
|
||||
{
|
||||
DPRINT("ZwMapViewOfSection() failed! (0x%x)\n", NtStatus);
|
||||
ZwClose(hMemObj);
|
||||
if (Status)
|
||||
*Status = NO_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
ZwClose(hMemObj);
|
||||
DPRINT("Mapped user address = 0x%08x\n", MappedAddress);
|
||||
}
|
||||
else /* kernel space */
|
||||
{
|
||||
MappedAddress = MmMapIoSpace(
|
||||
TranslatedAddress,
|
||||
NumberOfUchars,
|
||||
MmNonCached);
|
||||
}
|
||||
|
||||
if (MappedAddress != NULL)
|
||||
{
|
||||
BOOL InsertIntoList = FALSE;
|
||||
|
||||
if (Status)
|
||||
{
|
||||
*Status = NO_ERROR;
|
||||
}
|
||||
|
||||
AddressMapping = ExAllocatePoolWithTag(
|
||||
PagedPool,
|
||||
sizeof(VIDEO_PORT_ADDRESS_MAPPING),
|
||||
TAG_VIDEO_PORT);
|
||||
|
||||
if (AddressMapping == NULL)
|
||||
return MappedAddress;
|
||||
{
|
||||
AddressMapping = ExAllocatePoolWithTag(
|
||||
PagedPool,
|
||||
sizeof(VIDEO_PORT_ADDRESS_MAPPING),
|
||||
TAG_VIDEO_PORT);
|
||||
|
||||
AddressMapping->MappedAddress = MappedAddress;
|
||||
AddressMapping->NumberOfUchars = NumberOfUchars;
|
||||
AddressMapping->IoAddress = IoAddress;
|
||||
AddressMapping->SystemIoBusNumber = DeviceExtension->SystemIoBusNumber;
|
||||
AddressMapping->MappingCount = 1;
|
||||
if (AddressMapping == NULL)
|
||||
return MappedAddress;
|
||||
|
||||
InsertHeadList(
|
||||
&DeviceExtension->AddressMappingListHead,
|
||||
&AddressMapping->List);
|
||||
InsertIntoList = TRUE;
|
||||
RtlZeroMemory(AddressMapping, sizeof(VIDEO_PORT_ADDRESS_MAPPING));
|
||||
AddressMapping->NumberOfUchars = NumberOfUchars;
|
||||
AddressMapping->IoAddress = IoAddress;
|
||||
AddressMapping->SystemIoBusNumber = DeviceExtension->SystemIoBusNumber;
|
||||
}
|
||||
|
||||
if ((InIoSpace & VIDEO_MEMORY_SPACE_USER_MODE) != 0)
|
||||
{
|
||||
AddressMapping->MappedUserAddress = MappedAddress;
|
||||
AddressMapping->UserMappingCount = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
AddressMapping->MappedAddress = MappedAddress;
|
||||
AddressMapping->MappingCount = 1;
|
||||
}
|
||||
|
||||
if (InsertIntoList)
|
||||
{
|
||||
InsertHeadList(
|
||||
&DeviceExtension->AddressMappingListHead,
|
||||
&AddressMapping->List);
|
||||
}
|
||||
|
||||
return MappedAddress;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Status)
|
||||
*Status = NO_ERROR;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
if (Status)
|
||||
*Status = NO_ERROR;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VOID STDCALL
|
||||
|
@ -152,20 +231,40 @@ IntVideoPortUnmapMemory(
|
|||
Entry,
|
||||
VIDEO_PORT_ADDRESS_MAPPING,
|
||||
List);
|
||||
if (AddressMapping->MappedAddress == MappedAddress)
|
||||
if (AddressMapping->MappedUserAddress == MappedAddress)
|
||||
{
|
||||
ASSERT(AddressMapping->MappingCount >= 0);
|
||||
ASSERT(AddressMapping->UserMappingCount > 0);
|
||||
AddressMapping->UserMappingCount--;
|
||||
if (AddressMapping->UserMappingCount == 0)
|
||||
{
|
||||
ZwUnmapViewOfSection(NtCurrentProcess(),
|
||||
AddressMapping->MappedUserAddress);
|
||||
AddressMapping->MappedUserAddress = NULL;
|
||||
if (AddressMapping->MappingCount == 0)
|
||||
{
|
||||
RemoveEntryList(Entry);
|
||||
ExFreePool(AddressMapping);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (AddressMapping->MappedAddress == MappedAddress)
|
||||
{
|
||||
ASSERT(AddressMapping->MappingCount > 0);
|
||||
AddressMapping->MappingCount--;
|
||||
if (AddressMapping->MappingCount == 0)
|
||||
{
|
||||
MmUnmapIoSpace(
|
||||
AddressMapping->MappedAddress,
|
||||
AddressMapping->NumberOfUchars);
|
||||
RemoveEntryList(Entry);
|
||||
ExFreePool(AddressMapping);
|
||||
|
||||
return;
|
||||
AddressMapping->MappedAddress = NULL;
|
||||
if (AddressMapping->UserMappingCount == 0)
|
||||
{
|
||||
RemoveEntryList(Entry);
|
||||
ExFreePool(AddressMapping);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Entry = Entry->Flink;
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
* If not, write to the Free Software Foundation,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* $Id: videoprt.h,v 1.11 2004/10/23 23:43:23 ion Exp $
|
||||
* $Id: videoprt.h,v 1.12 2004/12/18 22:14:39 blight Exp $
|
||||
*/
|
||||
|
||||
#ifndef VIDEOPRT_H
|
||||
|
@ -51,10 +51,12 @@ typedef struct _VIDEO_PORT_ADDRESS_MAPPING
|
|||
{
|
||||
LIST_ENTRY List;
|
||||
PVOID MappedAddress;
|
||||
PVOID MappedUserAddress;
|
||||
ULONG NumberOfUchars;
|
||||
PHYSICAL_ADDRESS IoAddress;
|
||||
ULONG SystemIoBusNumber;
|
||||
UINT MappingCount;
|
||||
UINT UserMappingCount;
|
||||
} VIDEO_PORT_ADDRESS_MAPPING, *PVIDEO_PORT_ADDRESS_MAPPING;
|
||||
|
||||
typedef struct _VIDEO_PORT_DRIVER_EXTENSION
|
||||
|
|
Loading…
Reference in a new issue