diff --git a/reactos/ntoskrnl/mm/ARM3/ncache.c b/reactos/ntoskrnl/mm/ARM3/ncache.c new file mode 100644 index 00000000000..97928eaa02c --- /dev/null +++ b/reactos/ntoskrnl/mm/ARM3/ncache.c @@ -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 +#define NDEBUG +#include + +#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 */ diff --git a/reactos/ntoskrnl/mm/ncache.c b/reactos/ntoskrnl/mm/ncache.c deleted file mode 100644 index fd6e1e7519a..00000000000 --- a/reactos/ntoskrnl/mm/ncache.c +++ /dev/null @@ -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 -#define NDEBUG -#include - -/* 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 */ diff --git a/reactos/ntoskrnl/ntoskrnl-generic.rbuild b/reactos/ntoskrnl/ntoskrnl-generic.rbuild index 58f416c5f94..75d60eb298a 100644 --- a/reactos/ntoskrnl/ntoskrnl-generic.rbuild +++ b/reactos/ntoskrnl/ntoskrnl-generic.rbuild @@ -367,6 +367,7 @@ init.c iosup.c mdlsup.c + ncache.c pool.c procsup.c syspte.c @@ -380,7 +381,6 @@ mmsup.c mminit.c mpw.c - ncache.c npool.c pagefile.c pageop.c