2009-03-10 00:31:14 +00:00
|
|
|
/*
|
|
|
|
* PROJECT: ReactOS Kernel
|
|
|
|
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
2009-06-23 07:32:43 +00:00
|
|
|
* FILE: ntoskrnl/mm/ARM3/hypermap.c
|
2009-06-27 03:00:35 +00:00
|
|
|
* PURPOSE: ARM Memory Manager Hyperspace Mapping Functionality
|
2009-03-10 00:31:14 +00:00
|
|
|
* PROGRAMMERS: ReactOS Portable Systems Group
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* INCLUDES *******************************************************************/
|
|
|
|
|
|
|
|
#include <ntoskrnl.h>
|
|
|
|
#define NDEBUG
|
|
|
|
#include <debug.h>
|
|
|
|
|
2009-06-27 03:00:35 +00:00
|
|
|
#define MODULE_INVOLVED_IN_ARM3
|
2014-11-10 16:26:55 +00:00
|
|
|
#include <mm/ARM3/miarm.h>
|
2009-06-27 03:00:35 +00:00
|
|
|
|
2009-03-10 00:31:14 +00:00
|
|
|
/* GLOBALS ********************************************************************/
|
|
|
|
|
2009-06-23 06:39:10 +00:00
|
|
|
PMMPTE MmFirstReservedMappingPte, MmLastReservedMappingPte;
|
2009-06-23 07:32:43 +00:00
|
|
|
PMMPTE MiFirstReservedZeroingPte;
|
2009-03-10 00:31:14 +00:00
|
|
|
MMPTE HyperTemplatePte;
|
|
|
|
|
|
|
|
/* PRIVATE FUNCTIONS **********************************************************/
|
|
|
|
|
|
|
|
PVOID
|
|
|
|
NTAPI
|
2021-04-07 21:26:44 +00:00
|
|
|
MiMapPageInHyperSpace(IN PEPROCESS Process,
|
|
|
|
IN PFN_NUMBER Page,
|
|
|
|
IN PKIRQL OldIrql)
|
2009-03-10 00:31:14 +00:00
|
|
|
{
|
|
|
|
MMPTE TempPte;
|
|
|
|
PMMPTE PointerPte;
|
|
|
|
PFN_NUMBER Offset;
|
2009-03-29 19:32:37 +00:00
|
|
|
|
2009-06-23 07:32:43 +00:00
|
|
|
//
|
2009-07-26 08:20:29 +00:00
|
|
|
// Never accept page 0 or non-physical pages
|
2009-06-23 07:32:43 +00:00
|
|
|
//
|
2009-03-10 00:31:14 +00:00
|
|
|
ASSERT(Page != 0);
|
2009-07-26 08:20:29 +00:00
|
|
|
ASSERT(MiGetPfnEntry(Page) != NULL);
|
2009-03-29 19:32:37 +00:00
|
|
|
|
2009-06-23 07:32:43 +00:00
|
|
|
//
|
|
|
|
// Build the PTE
|
|
|
|
//
|
2015-10-15 01:49:26 +00:00
|
|
|
TempPte = ValidKernelPteLocal;
|
2009-03-10 00:31:14 +00:00
|
|
|
TempPte.u.Hard.PageFrameNumber = Page;
|
2009-03-29 19:32:37 +00:00
|
|
|
|
2009-06-23 07:32:43 +00:00
|
|
|
//
|
|
|
|
// Pick the first hyperspace PTE
|
|
|
|
//
|
2009-03-10 00:31:14 +00:00
|
|
|
PointerPte = MmFirstReservedMappingPte;
|
|
|
|
|
2009-06-23 07:32:43 +00:00
|
|
|
//
|
|
|
|
// Acquire the hyperlock
|
|
|
|
//
|
2009-03-10 00:31:14 +00:00
|
|
|
ASSERT(Process == PsGetCurrentProcess());
|
2021-04-07 21:26:44 +00:00
|
|
|
KeAcquireSpinLock(&Process->HyperSpaceLock, OldIrql);
|
2009-03-29 19:32:37 +00:00
|
|
|
|
2009-06-23 07:32:43 +00:00
|
|
|
//
|
|
|
|
// Now get the first free PTE
|
|
|
|
//
|
2009-03-10 00:31:14 +00:00
|
|
|
Offset = PFN_FROM_PTE(PointerPte);
|
|
|
|
if (!Offset)
|
|
|
|
{
|
2009-06-23 07:32:43 +00:00
|
|
|
//
|
|
|
|
// Reset the PTEs
|
|
|
|
//
|
2009-03-10 00:31:14 +00:00
|
|
|
Offset = MI_HYPERSPACE_PTES;
|
|
|
|
KeFlushProcessTb();
|
|
|
|
}
|
2009-03-29 19:32:37 +00:00
|
|
|
|
2009-06-23 07:32:43 +00:00
|
|
|
//
|
|
|
|
// Prepare the next PTE
|
|
|
|
//
|
2009-03-10 00:31:14 +00:00
|
|
|
PointerPte->u.Hard.PageFrameNumber = Offset - 1;
|
2009-03-29 19:32:37 +00:00
|
|
|
|
2009-06-23 07:32:43 +00:00
|
|
|
//
|
|
|
|
// Write the current PTE
|
|
|
|
//
|
2009-03-10 00:31:14 +00:00
|
|
|
PointerPte += Offset;
|
2010-06-06 18:45:46 +00:00
|
|
|
MI_WRITE_VALID_PTE(PointerPte, TempPte);
|
2009-03-29 19:32:37 +00:00
|
|
|
|
2009-06-23 07:32:43 +00:00
|
|
|
//
|
|
|
|
// Return the address
|
|
|
|
//
|
|
|
|
return MiPteToAddress(PointerPte);
|
2009-03-10 00:31:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
2021-04-07 21:26:44 +00:00
|
|
|
MiUnmapPageInHyperSpace(IN PEPROCESS Process,
|
|
|
|
IN PVOID Address,
|
|
|
|
IN KIRQL OldIrql)
|
2009-03-10 00:31:14 +00:00
|
|
|
{
|
|
|
|
ASSERT(Process == PsGetCurrentProcess());
|
|
|
|
|
2009-06-23 07:32:43 +00:00
|
|
|
//
|
|
|
|
// Blow away the mapping
|
|
|
|
//
|
2009-03-10 00:31:14 +00:00
|
|
|
MiAddressToPte(Address)->u.Long = 0;
|
2009-03-29 19:32:37 +00:00
|
|
|
|
2009-06-23 07:32:43 +00:00
|
|
|
//
|
|
|
|
// Release the hyperlock
|
|
|
|
//
|
2009-03-15 02:05:40 +00:00
|
|
|
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
|
2021-04-07 21:26:44 +00:00
|
|
|
KeReleaseSpinLock(&Process->HyperSpaceLock, OldIrql);
|
2009-03-10 00:31:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
PVOID
|
|
|
|
NTAPI
|
2011-12-19 18:44:47 +00:00
|
|
|
MiMapPagesInZeroSpace(IN PMMPFN Pfn1,
|
|
|
|
IN PFN_NUMBER NumberOfPages)
|
2009-03-10 00:31:14 +00:00
|
|
|
{
|
|
|
|
MMPTE TempPte;
|
|
|
|
PMMPTE PointerPte;
|
2009-06-23 09:34:45 +00:00
|
|
|
PFN_NUMBER Offset, PageFrameIndex;
|
2009-03-14 01:20:18 +00:00
|
|
|
|
2009-06-23 07:32:43 +00:00
|
|
|
//
|
2009-06-23 09:34:45 +00:00
|
|
|
// Sanity checks
|
2009-06-23 07:32:43 +00:00
|
|
|
//
|
2010-09-27 21:58:54 +00:00
|
|
|
ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
|
2009-06-23 09:34:45 +00:00
|
|
|
ASSERT(NumberOfPages != 0);
|
2017-11-04 13:08:56 +00:00
|
|
|
ASSERT(NumberOfPages <= MI_ZERO_PTES);
|
2010-12-26 15:23:03 +00:00
|
|
|
|
2009-06-23 09:34:45 +00:00
|
|
|
//
|
|
|
|
// Pick the first zeroing PTE
|
|
|
|
//
|
|
|
|
PointerPte = MiFirstReservedZeroingPte;
|
2009-03-14 01:20:18 +00:00
|
|
|
|
2009-06-23 07:32:43 +00:00
|
|
|
//
|
2009-06-23 09:34:45 +00:00
|
|
|
// Now get the first free PTE
|
|
|
|
//
|
|
|
|
Offset = PFN_FROM_PTE(PointerPte);
|
|
|
|
if (NumberOfPages > Offset)
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// Reset the PTEs
|
|
|
|
//
|
2017-11-04 13:08:56 +00:00
|
|
|
Offset = MI_ZERO_PTES;
|
2009-06-23 09:34:45 +00:00
|
|
|
PointerPte->u.Hard.PageFrameNumber = Offset;
|
|
|
|
KeFlushProcessTb();
|
|
|
|
}
|
2010-12-26 15:23:03 +00:00
|
|
|
|
2009-06-23 09:34:45 +00:00
|
|
|
//
|
|
|
|
// Prepare the next PTE
|
2009-06-23 07:32:43 +00:00
|
|
|
//
|
2009-06-23 09:34:45 +00:00
|
|
|
PointerPte->u.Hard.PageFrameNumber = Offset - NumberOfPages;
|
2010-12-26 15:23:03 +00:00
|
|
|
|
2010-09-27 21:58:54 +00:00
|
|
|
/* Choose the correct PTE to use, and which template */
|
2009-06-23 09:34:45 +00:00
|
|
|
PointerPte += (Offset + 1);
|
2010-02-10 13:56:54 +00:00
|
|
|
TempPte = ValidKernelPte;
|
2010-12-26 15:23:03 +00:00
|
|
|
|
2021-08-02 16:48:07 +00:00
|
|
|
/* Disable cache. Write through */
|
|
|
|
MI_PAGE_DISABLE_CACHE(&TempPte);
|
|
|
|
MI_PAGE_WRITE_THROUGH(&TempPte);
|
|
|
|
|
2010-09-27 21:58:54 +00:00
|
|
|
/* Make sure the list isn't empty and loop it */
|
|
|
|
ASSERT(Pfn1 != (PVOID)LIST_HEAD);
|
|
|
|
while (Pfn1 != (PVOID)LIST_HEAD)
|
2009-06-23 09:34:45 +00:00
|
|
|
{
|
2010-09-27 21:58:54 +00:00
|
|
|
/* Get the page index for this PFN */
|
|
|
|
PageFrameIndex = MiGetPfnEntryIndex(Pfn1);
|
2010-12-26 15:23:03 +00:00
|
|
|
|
2009-06-23 09:34:45 +00:00
|
|
|
//
|
|
|
|
// Write the PFN
|
|
|
|
//
|
|
|
|
TempPte.u.Hard.PageFrameNumber = PageFrameIndex;
|
2010-12-26 15:23:03 +00:00
|
|
|
|
2009-06-23 09:34:45 +00:00
|
|
|
//
|
|
|
|
// Set the correct PTE to write to, and set its new value
|
|
|
|
//
|
|
|
|
PointerPte--;
|
2010-06-06 18:45:46 +00:00
|
|
|
MI_WRITE_VALID_PTE(PointerPte, TempPte);
|
2010-12-26 15:23:03 +00:00
|
|
|
|
2010-09-27 21:58:54 +00:00
|
|
|
/* Move to the next PFN */
|
|
|
|
Pfn1 = (PMMPFN)Pfn1->u1.Flink;
|
|
|
|
}
|
2010-12-26 15:23:03 +00:00
|
|
|
|
2009-06-23 07:32:43 +00:00
|
|
|
//
|
2009-06-23 09:34:45 +00:00
|
|
|
// Return the address
|
2009-06-23 07:32:43 +00:00
|
|
|
//
|
2009-06-23 09:34:45 +00:00
|
|
|
return MiPteToAddress(PointerPte);
|
|
|
|
}
|
2009-03-14 01:20:18 +00:00
|
|
|
|
2009-06-23 09:34:45 +00:00
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
MiUnmapPagesInZeroSpace(IN PVOID VirtualAddress,
|
|
|
|
IN PFN_NUMBER NumberOfPages)
|
|
|
|
{
|
|
|
|
PMMPTE PointerPte;
|
2010-12-26 15:23:03 +00:00
|
|
|
|
2009-06-23 07:32:43 +00:00
|
|
|
//
|
2009-06-23 09:34:45 +00:00
|
|
|
// Sanity checks
|
2009-06-23 07:32:43 +00:00
|
|
|
//
|
2010-09-27 21:58:54 +00:00
|
|
|
ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
|
2009-06-23 09:34:45 +00:00
|
|
|
ASSERT (NumberOfPages != 0);
|
2017-11-04 13:08:56 +00:00
|
|
|
ASSERT(NumberOfPages <= MI_ZERO_PTES);
|
2010-12-26 15:23:03 +00:00
|
|
|
|
2009-06-23 07:32:43 +00:00
|
|
|
//
|
2009-06-23 09:34:45 +00:00
|
|
|
// Get the first PTE for the mapped zero VA
|
2009-06-23 07:32:43 +00:00
|
|
|
//
|
2009-06-23 09:34:45 +00:00
|
|
|
PointerPte = MiAddressToPte(VirtualAddress);
|
2009-03-14 01:20:18 +00:00
|
|
|
|
2009-06-23 07:32:43 +00:00
|
|
|
//
|
2009-06-23 09:34:45 +00:00
|
|
|
// Blow away the mapped zero PTEs
|
2009-06-23 07:32:43 +00:00
|
|
|
//
|
2009-06-23 09:34:45 +00:00
|
|
|
RtlZeroMemory(PointerPte, NumberOfPages * sizeof(MMPTE));
|
2009-03-10 00:31:14 +00:00
|
|
|
}
|
2009-06-23 09:34:45 +00:00
|
|
|
|