Allow allocating aligned, contiguous memory

svn path=/trunk/; revision=1650
This commit is contained in:
David Welch 2001-02-28 18:23:32 +00:00
parent 327980fe31
commit 80ec0821f8
3 changed files with 60 additions and 42 deletions

View file

@ -364,7 +364,8 @@ NTSTATUS
MmCreatePhysicalMemorySection(VOID); MmCreatePhysicalMemorySection(VOID);
PVOID PVOID
MmGetContinuousPages(ULONG NumberOfBytes, MmGetContinuousPages(ULONG NumberOfBytes,
PHYSICAL_ADDRESS HighestAcceptableAddress); PHYSICAL_ADDRESS HighestAcceptableAddress,
ULONG Alignment);
#define MM_PHYSICAL_PAGE_MPW_PENDING (0x8) #define MM_PHYSICAL_PAGE_MPW_PENDING (0x8)

View file

@ -1,4 +1,4 @@
/* $Id: cont.c,v 1.7 2001/02/10 22:51:10 dwelch Exp $ /* $Id: cont.c,v 1.8 2001/02/28 18:23:32 dwelch Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -30,6 +30,51 @@ MmFreeContinuousPage(PVOID Context, PVOID Address)
} }
} }
PVOID STDCALL
MmAllocateContiguousAlignedMemory(IN ULONG NumberOfBytes,
IN PHYSICAL_ADDRESS HighestAcceptableAddress,
IN ULONG Alignment)
{
PMEMORY_AREA MArea;
NTSTATUS Status;
PVOID BaseAddress;
PVOID PBase;
ULONG i;
Status = MmCreateMemoryArea(NULL,
MmGetKernelAddressSpace(),
MEMORY_AREA_CONTINUOUS_MEMORY,
&BaseAddress,
NumberOfBytes,
0,
&MArea);
if (!NT_SUCCESS(Status))
{
return(NULL);
}
PBase = MmGetContinuousPages(NumberOfBytes,
HighestAcceptableAddress,
Alignment);
if (PBase == NULL)
{
MmFreeMemoryArea(MmGetKernelAddressSpace(),
BaseAddress,
0,
NULL,
NULL);
return(NULL);
}
for (i = 0; i < (PAGE_ROUND_UP(NumberOfBytes) / 4096); i++)
{
MmCreateVirtualMapping(NULL,
BaseAddress + (i * 4096),
PAGE_EXECUTE_READWRITE | PAGE_SYSTEM,
(ULONG)(PBase + (i * 4096)));
}
return(BaseAddress);
}
/********************************************************************** /**********************************************************************
* NAME EXPORTED * NAME EXPORTED
* MmAllocateContiguousMemory@12 * MmAllocateContiguousMemory@12
@ -60,43 +105,9 @@ PVOID STDCALL
MmAllocateContiguousMemory (IN ULONG NumberOfBytes, MmAllocateContiguousMemory (IN ULONG NumberOfBytes,
IN PHYSICAL_ADDRESS HighestAcceptableAddress) IN PHYSICAL_ADDRESS HighestAcceptableAddress)
{ {
PMEMORY_AREA MArea; return(MmAllocateContiguousAlignedMemory(NumberOfBytes,
NTSTATUS Status; HighestAcceptableAddress,
PVOID BaseAddress; PAGESIZE));
PVOID PBase;
ULONG i;
Status = MmCreateMemoryArea(NULL,
MmGetKernelAddressSpace(),
MEMORY_AREA_CONTINUOUS_MEMORY,
&BaseAddress,
NumberOfBytes,
0,
&MArea);
if (!NT_SUCCESS(Status))
{
return(NULL);
}
PBase = MmGetContinuousPages(NumberOfBytes,
HighestAcceptableAddress);
if (PBase == NULL)
{
MmFreeMemoryArea(MmGetKernelAddressSpace(),
BaseAddress,
0,
NULL,
NULL);
return(NULL);
}
for (i = 0; i < (PAGE_ROUND_UP(NumberOfBytes) / 4096); i++)
{
MmCreateVirtualMapping(NULL,
BaseAddress + (i * 4096),
PAGE_EXECUTE_READWRITE | PAGE_SYSTEM,
(ULONG)(PBase + (i * 4096)));
}
return(BaseAddress);
} }

View file

@ -50,7 +50,8 @@ static LIST_ENTRY BiosPageListHead;
PVOID PVOID
MmGetContinuousPages(ULONG NumberOfBytes, MmGetContinuousPages(ULONG NumberOfBytes,
PHYSICAL_ADDRESS HighestAcceptableAddress) PHYSICAL_ADDRESS HighestAcceptableAddress,
ULONG Alignment)
{ {
ULONG NrPages; ULONG NrPages;
ULONG i; ULONG i;
@ -64,7 +65,7 @@ MmGetContinuousPages(ULONG NumberOfBytes,
start = -1; start = -1;
length = 0; length = 0;
for (i = 0; i < (HighestAcceptableAddress.QuadPart / PAGESIZE); i++) for (i = 0; i < (HighestAcceptableAddress.QuadPart / PAGESIZE); )
{ {
if (MmPageArray[i].Flags & MM_PHYSICAL_PAGE_FREE) if (MmPageArray[i].Flags & MM_PHYSICAL_PAGE_FREE)
{ {
@ -77,6 +78,7 @@ MmGetContinuousPages(ULONG NumberOfBytes,
{ {
length++; length++;
} }
i++;
if (length == NrPages) if (length == NrPages)
{ {
break; break;
@ -85,9 +87,13 @@ MmGetContinuousPages(ULONG NumberOfBytes,
else if (start != -1) else if (start != -1)
{ {
start = -1; start = -1;
/*
* Fast forward to the base of the next aligned region
*/
i = i + (Alignment / PAGESIZE);
} }
} }
if (start == -1) if (start == -1 || length != NrPages)
{ {
KeReleaseSpinLock(&PageListLock, oldIrql); KeReleaseSpinLock(&PageListLock, oldIrql);
return(NULL); return(NULL);