reactos/reactos/ntoskrnl/mm/ARM3/hypermap.c

151 lines
3.1 KiB
C
Raw Normal View History

/*
* PROJECT: ReactOS Kernel
* LICENSE: BSD - See COPYING.ARM in the top level directory
* FILE: ntoskrnl/mm/ARM3/hypermap.c
* PURPOSE: Hyperspace Mapping Functionality
* PROGRAMMERS: ReactOS Portable Systems Group
*/
/* INCLUDES *******************************************************************/
#include <ntoskrnl.h>
#define NDEBUG
#include <debug.h>
/* GLOBALS ********************************************************************/
PMMPTE MmFirstReservedMappingPte, MmLastReservedMappingPte;
PMMPTE MiFirstReservedZeroingPte;
MMPTE HyperTemplatePte;
PEPROCESS HyperProcess;
KIRQL HyperIrql;
/* PRIVATE FUNCTIONS **********************************************************/
PVOID
NTAPI
MiMapPageInHyperSpace(IN PEPROCESS Process,
IN PFN_NUMBER Page,
IN PKIRQL OldIrql)
{
MMPTE TempPte;
PMMPTE PointerPte;
PFN_NUMBER Offset;
//
// Never accept page 0
//
ASSERT(Page != 0);
//
// Build the PTE
//
TempPte = HyperTemplatePte;
TempPte.u.Hard.PageFrameNumber = Page;
TempPte.u.Hard.Global = 0; // Hyperspace is local!
//
// Pick the first hyperspace PTE
//
PointerPte = MmFirstReservedMappingPte;
//
// Acquire the hyperlock
//
ASSERT(Process == PsGetCurrentProcess());
KeAcquireSpinLock(&Process->HyperSpaceLock, OldIrql);
//
// Now get the first free PTE
//
Offset = PFN_FROM_PTE(PointerPte);
if (!Offset)
{
//
// Reset the PTEs
//
Offset = MI_HYPERSPACE_PTES;
KeFlushProcessTb();
}
//
// Prepare the next PTE
//
PointerPte->u.Hard.PageFrameNumber = Offset - 1;
//
// Write the current PTE
//
PointerPte += Offset;
ASSERT(PointerPte->u.Hard.Valid == 0);
ASSERT(TempPte.u.Hard.Valid == 1);
*PointerPte = TempPte;
//
// Return the address
//
return MiPteToAddress(PointerPte);
}
VOID
NTAPI
MiUnmapPageInHyperSpace(IN PEPROCESS Process,
IN PVOID Address,
IN KIRQL OldIrql)
{
ASSERT(Process == PsGetCurrentProcess());
//
// Blow away the mapping
//
MiAddressToPte(Address)->u.Long = 0;
//
// Release the hyperlock
//
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
KeReleaseSpinLock(&Process->HyperSpaceLock, OldIrql);
}
PVOID
NTAPI
MiMapPageToZeroInHyperSpace(IN PFN_NUMBER Page)
{
MMPTE TempPte;
PMMPTE PointerPte;
PVOID Address;
//
// Never accept page 0
//
ASSERT(Page != 0);
//
// Build the PTE
//
TempPte = HyperTemplatePte;
TempPte.u.Hard.PageFrameNumber = Page;
//
// Get the Zero PTE and its address
//
PointerPte = MiAddressToPte(MI_ZERO_PTE);
Address = (PVOID)((ULONG_PTR)PointerPte << 10);
//
// Invalidate the old address
//
__invlpg(Address);
//
// Write the current PTE
//
TempPte.u.Hard.PageFrameNumber = Page;
*PointerPte = TempPte;
//
// Return the address
//
return Address;
}