mirror of
https://github.com/reactos/reactos.git
synced 2025-01-01 03:54:02 +00:00
- Rewrite MmAllocateNonCachedMemory and MmFreeNonCachedMemory to use the new functionality present in ARM3.
- These functions now use the MDL routines to allocate their physical memory, since the constraints and requirements are identical as for a non-cached MDL mapping. - As for the virtual address space, it is guaranteed once again by System PTEs! - If it's not getting old already, optimizations to the System PTE code will, yet again, yield improvements here as well. - This is the last large kernel-facing memory allocator that needed updating to use System PTEs instead. - Only the pool allocator remains (which, for nonpaged pool, also uses System PTEs, present in the nonpaged pool expansion VA). - That effort will take significantly longer. svn path=/trunk/; revision=41708
This commit is contained in:
parent
bd27f08336
commit
f91f8ec7cf
3 changed files with 215 additions and 129 deletions
214
reactos/ntoskrnl/mm/ARM3/ncache.c
Normal file
214
reactos/ntoskrnl/mm/ARM3/ncache.c
Normal file
|
@ -0,0 +1,214 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Kernel
|
||||
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
||||
* FILE: ntoskrnl/mm/ARM3/ncache.c
|
||||
* PURPOSE: ARM Memory Manager Noncached Memory Allocator
|
||||
* PROGRAMMERS: ReactOS Portable Systems Group
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#include <ntoskrnl.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#line 15 "ARM³::NCACHE"
|
||||
#define MODULE_INVOLVED_IN_ARM3
|
||||
#include "../ARM3/miarm.h"
|
||||
|
||||
/* GLOBALS ********************************************************************/
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
PVOID
|
||||
NTAPI
|
||||
MmAllocateNonCachedMemory(IN ULONG NumberOfBytes)
|
||||
{
|
||||
PFN_NUMBER PageCount, MdlPageCount, PageFrameIndex;
|
||||
PHYSICAL_ADDRESS LowAddress, HighAddress, SkipBytes;
|
||||
MI_PFN_CACHE_ATTRIBUTE CacheAttribute;
|
||||
PMDL Mdl;
|
||||
PVOID BaseAddress;
|
||||
PPFN_NUMBER MdlPages;
|
||||
PMMPTE PointerPte;
|
||||
MMPTE TempPte;
|
||||
|
||||
//
|
||||
// Get the page count
|
||||
//
|
||||
ASSERT(NumberOfBytes != 0);
|
||||
PageCount = BYTES_TO_PAGES(NumberOfBytes);
|
||||
|
||||
//
|
||||
// Use the MDL allocator for simplicity, so setup the parameters
|
||||
//
|
||||
LowAddress.QuadPart = 0;
|
||||
HighAddress.QuadPart = -1;
|
||||
SkipBytes.QuadPart = 0;
|
||||
CacheAttribute = MiPlatformCacheAttributes[0][MmNonCached];
|
||||
|
||||
//
|
||||
// Now call the MDL allocator
|
||||
//
|
||||
Mdl = MiAllocatePagesForMdl(LowAddress,
|
||||
HighAddress,
|
||||
SkipBytes,
|
||||
NumberOfBytes,
|
||||
CacheAttribute,
|
||||
0);
|
||||
if (!Mdl) return NULL;
|
||||
|
||||
//
|
||||
// Get the MDL VA and check how many pages we got (could be partial)
|
||||
//
|
||||
BaseAddress = (PVOID)((ULONG_PTR)Mdl->StartVa + Mdl->ByteOffset);
|
||||
MdlPageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(BaseAddress, Mdl->ByteCount);
|
||||
if (PageCount != MdlPageCount)
|
||||
{
|
||||
//
|
||||
// Unlike MDLs, partial isn't okay for a noncached allocation, so fail
|
||||
//
|
||||
ASSERT(PageCount > MdlPageCount);
|
||||
MmFreePagesFromMdl(Mdl);
|
||||
ExFreePool(Mdl);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// Allocate system PTEs for the base address
|
||||
// We use an extra page to store the actual MDL pointer for the free later
|
||||
//
|
||||
PointerPte = MiReserveSystemPtes(PageCount + 1, SystemPteSpace);
|
||||
if (!PointerPte)
|
||||
{
|
||||
//
|
||||
// Out of memory...
|
||||
//
|
||||
MmFreePagesFromMdl(Mdl);
|
||||
ExFreePool(Mdl);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// Store the MDL pointer
|
||||
//
|
||||
*(PMDL*)PointerPte++ = Mdl;
|
||||
|
||||
//
|
||||
// Okay, now see what range we got
|
||||
//
|
||||
BaseAddress = MiPteToAddress(PointerPte);
|
||||
|
||||
//
|
||||
// This is our array of pages
|
||||
//
|
||||
MdlPages = (PPFN_NUMBER)(Mdl + 1);
|
||||
|
||||
//
|
||||
// Setup the template PTE
|
||||
//
|
||||
TempPte = HyperTemplatePte;
|
||||
|
||||
//
|
||||
// Now check what kind of caching we should use
|
||||
//
|
||||
switch (CacheAttribute)
|
||||
{
|
||||
case MiNonCached:
|
||||
|
||||
//
|
||||
// Disable caching
|
||||
//
|
||||
TempPte.u.Hard.CacheDisable = 1;
|
||||
TempPte.u.Hard.WriteThrough = 1;
|
||||
break;
|
||||
|
||||
case MiWriteCombined:
|
||||
|
||||
//
|
||||
// Enable write combining
|
||||
//
|
||||
TempPte.u.Hard.CacheDisable = 1;
|
||||
TempPte.u.Hard.WriteThrough = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
//
|
||||
// Nothing to do
|
||||
//
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Now loop the MDL pages
|
||||
//
|
||||
do
|
||||
{
|
||||
//
|
||||
// Get the PFN
|
||||
//
|
||||
PageFrameIndex = *MdlPages++;
|
||||
|
||||
//
|
||||
// Set the PFN in the page and write it
|
||||
//
|
||||
TempPte.u.Hard.PageFrameNumber = PageFrameIndex;
|
||||
ASSERT(PointerPte->u.Hard.Valid == 0);
|
||||
ASSERT(TempPte.u.Hard.Valid == 1);
|
||||
*PointerPte++ = TempPte;
|
||||
} while (--PageCount);
|
||||
|
||||
//
|
||||
// Return the base address
|
||||
//
|
||||
return BaseAddress;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
NTAPI
|
||||
MmFreeNonCachedMemory(IN PVOID BaseAddress,
|
||||
IN ULONG NumberOfBytes)
|
||||
{
|
||||
PMDL Mdl;
|
||||
PMMPTE PointerPte;
|
||||
PFN_NUMBER PageCount;
|
||||
|
||||
//
|
||||
// Sanity checks
|
||||
//
|
||||
ASSERT(NumberOfBytes != 0);
|
||||
ASSERT(PAGE_ALIGN(BaseAddress) == BaseAddress);
|
||||
|
||||
//
|
||||
// Get the page count
|
||||
//
|
||||
PageCount = BYTES_TO_PAGES(NumberOfBytes);
|
||||
|
||||
//
|
||||
// Get the first PTE
|
||||
//
|
||||
PointerPte = MiAddressToPte(BaseAddress);
|
||||
|
||||
//
|
||||
// Remember this is where we store the shadow MDL pointer
|
||||
//
|
||||
Mdl = *(PMDL*)(--PointerPte);
|
||||
|
||||
//
|
||||
// Kill the MDL (and underlying pages)
|
||||
//
|
||||
MmFreePagesFromMdl(Mdl);
|
||||
ExFreePool(Mdl);
|
||||
|
||||
//
|
||||
// Now free the system PTEs for the underlying VA
|
||||
//
|
||||
MiReleaseSystemPtes(PointerPte, PageCount + 1, SystemPteSpace);
|
||||
}
|
||||
|
||||
/* EOF */
|
|
@ -1,128 +0,0 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/mm/ncache.c
|
||||
* PURPOSE: Manages non-cached memory
|
||||
*
|
||||
* PROGRAMMERS: David Welch (welch@cwcom.net)
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <ntoskrnl.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* NAME EXPORTED
|
||||
* MmAllocateNonCachedMemory@4
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Allocates a virtual address range of noncached and cache
|
||||
* aligned memory.
|
||||
*
|
||||
* ARGUMENTS
|
||||
* NumberOfBytes
|
||||
* Size of region to allocate.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* The base address of the range on success;
|
||||
* NULL on failure.
|
||||
*
|
||||
* NOTE
|
||||
* Description taken from include/ddk/mmfuncs.h.
|
||||
* Code taken from ntoskrnl/mm/special.c.
|
||||
*
|
||||
* REVISIONS
|
||||
*
|
||||
* @implemented
|
||||
*/
|
||||
PVOID NTAPI
|
||||
MmAllocateNonCachedMemory(IN ULONG NumberOfBytes)
|
||||
{
|
||||
PVOID Result;
|
||||
MEMORY_AREA* marea;
|
||||
NTSTATUS Status;
|
||||
ULONG Protect = PAGE_READWRITE|PAGE_SYSTEM|PAGE_NOCACHE|PAGE_WRITETHROUGH;
|
||||
PHYSICAL_ADDRESS BoundaryAddressMultiple;
|
||||
|
||||
BoundaryAddressMultiple.QuadPart = 0;
|
||||
MmLockAddressSpace(MmGetKernelAddressSpace());
|
||||
Result = NULL;
|
||||
Status = MmCreateMemoryArea (MmGetKernelAddressSpace(),
|
||||
MEMORY_AREA_NO_CACHE,
|
||||
&Result,
|
||||
NumberOfBytes,
|
||||
Protect,
|
||||
&marea,
|
||||
FALSE,
|
||||
0,
|
||||
BoundaryAddressMultiple);
|
||||
MmUnlockAddressSpace(MmGetKernelAddressSpace());
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Allocating marea for noncached mem failed with Status "
|
||||
"0x%08X\n", Status);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Create a virtual mapping for this memory area */
|
||||
MmMapMemoryArea(Result, NumberOfBytes, MC_NPPOOL, Protect);
|
||||
|
||||
return ((PVOID)Result);
|
||||
}
|
||||
|
||||
static VOID
|
||||
MmFreeNonCachedPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
|
||||
PFN_TYPE Page, SWAPENTRY SwapEntry,
|
||||
BOOLEAN Dirty)
|
||||
{
|
||||
ASSERT(SwapEntry == 0);
|
||||
if (Page != 0)
|
||||
{
|
||||
MmReleasePageMemoryConsumer(MC_NPPOOL, Page);
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* NAME EXPORTED
|
||||
* MmFreeNonCachedMemory@8
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Releases a range of noncached memory allocated with
|
||||
* MmAllocateNonCachedMemory.
|
||||
*
|
||||
* ARGUMENTS
|
||||
* BaseAddress
|
||||
* Virtual address to be freed;
|
||||
*
|
||||
* NumberOfBytes
|
||||
* Size of the region to be freed.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* None.
|
||||
*
|
||||
* NOTE
|
||||
* Description taken from include/ddk/mmfuncs.h.
|
||||
* Code taken from ntoskrnl/mm/special.c.
|
||||
*
|
||||
* REVISIONS
|
||||
*
|
||||
* @implemented
|
||||
*/
|
||||
VOID NTAPI MmFreeNonCachedMemory (IN PVOID BaseAddress,
|
||||
IN ULONG NumberOfBytes)
|
||||
{
|
||||
MmLockAddressSpace(MmGetKernelAddressSpace());
|
||||
MmFreeMemoryAreaByPtr(MmGetKernelAddressSpace(),
|
||||
BaseAddress,
|
||||
MmFreeNonCachedPage,
|
||||
NULL);
|
||||
MmUnlockAddressSpace(MmGetKernelAddressSpace());
|
||||
}
|
||||
|
||||
/* EOF */
|
|
@ -367,6 +367,7 @@
|
|||
<file>init.c</file>
|
||||
<file>iosup.c</file>
|
||||
<file>mdlsup.c</file>
|
||||
<file>ncache.c</file>
|
||||
<file>pool.c</file>
|
||||
<file>procsup.c</file>
|
||||
<file>syspte.c</file>
|
||||
|
@ -380,7 +381,6 @@
|
|||
<file>mmsup.c</file>
|
||||
<file>mminit.c</file>
|
||||
<file>mpw.c</file>
|
||||
<file>ncache.c</file>
|
||||
<file>npool.c</file>
|
||||
<file>pagefile.c</file>
|
||||
<file>pageop.c</file>
|
||||
|
|
Loading…
Reference in a new issue