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-03-10 00:31:14 +00:00
|
|
|
* PURPOSE: Hyperspace Mapping Functionality
|
|
|
|
* PROGRAMMERS: ReactOS Portable Systems Group
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* INCLUDES *******************************************************************/
|
|
|
|
|
|
|
|
#include <ntoskrnl.h>
|
|
|
|
#define NDEBUG
|
|
|
|
#include <debug.h>
|
|
|
|
|
|
|
|
/* 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;
|
|
|
|
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;
|
2009-03-29 19:32:37 +00:00
|
|
|
|
2009-06-23 07:32:43 +00:00
|
|
|
//
|
|
|
|
// Never accept page 0
|
|
|
|
//
|
2009-03-10 00:31:14 +00:00
|
|
|
ASSERT(Page != 0);
|
2009-03-29 19:32:37 +00:00
|
|
|
|
2009-06-23 07:32:43 +00:00
|
|
|
//
|
|
|
|
// Build the PTE
|
|
|
|
//
|
2009-03-10 00:31:14 +00:00
|
|
|
TempPte = HyperTemplatePte;
|
|
|
|
TempPte.u.Hard.PageFrameNumber = Page;
|
2009-06-23 07:32:43 +00:00
|
|
|
TempPte.u.Hard.Global = 0; // Hyperspace is local!
|
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());
|
2009-03-15 02:05:40 +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;
|
|
|
|
ASSERT(PointerPte->u.Hard.Valid == 0);
|
|
|
|
ASSERT(TempPte.u.Hard.Valid == 1);
|
|
|
|
*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
|
|
|
|
MiUnmapPageInHyperSpace(IN PEPROCESS Process,
|
|
|
|
IN PVOID Address,
|
|
|
|
IN KIRQL OldIrql)
|
|
|
|
{
|
|
|
|
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);
|
|
|
|
KeReleaseSpinLock(&Process->HyperSpaceLock, OldIrql);
|
2009-03-10 00:31:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
PVOID
|
|
|
|
NTAPI
|
2009-03-10 20:52:39 +00:00
|
|
|
MiMapPageToZeroInHyperSpace(IN PFN_NUMBER Page)
|
2009-03-10 00:31:14 +00:00
|
|
|
{
|
|
|
|
MMPTE TempPte;
|
|
|
|
PMMPTE PointerPte;
|
|
|
|
PVOID Address;
|
2009-03-14 01:20:18 +00:00
|
|
|
|
2009-06-23 07:32:43 +00:00
|
|
|
//
|
|
|
|
// Never accept page 0
|
|
|
|
//
|
2009-03-10 00:31:14 +00:00
|
|
|
ASSERT(Page != 0);
|
2009-03-14 01:20:18 +00:00
|
|
|
|
2009-06-23 07:32:43 +00:00
|
|
|
//
|
|
|
|
// Build the PTE
|
|
|
|
//
|
2009-03-10 00:31:14 +00:00
|
|
|
TempPte = HyperTemplatePte;
|
|
|
|
TempPte.u.Hard.PageFrameNumber = Page;
|
2009-03-14 01:20:18 +00:00
|
|
|
|
2009-06-23 07:32:43 +00:00
|
|
|
//
|
|
|
|
// Get the Zero PTE and its address
|
|
|
|
//
|
2009-03-15 01:23:47 +00:00
|
|
|
PointerPte = MiAddressToPte(MI_ZERO_PTE);
|
|
|
|
Address = (PVOID)((ULONG_PTR)PointerPte << 10);
|
2009-03-14 01:20:18 +00:00
|
|
|
|
2009-06-23 07:32:43 +00:00
|
|
|
//
|
|
|
|
// Invalidate the old address
|
|
|
|
//
|
2009-03-15 01:23:47 +00:00
|
|
|
__invlpg(Address);
|
2009-03-14 01:20:18 +00:00
|
|
|
|
2009-06-23 07:32:43 +00:00
|
|
|
//
|
|
|
|
// Write the current PTE
|
|
|
|
//
|
2009-03-15 01:23:47 +00:00
|
|
|
TempPte.u.Hard.PageFrameNumber = Page;
|
2009-03-10 00:31:14 +00:00
|
|
|
*PointerPte = TempPte;
|
2009-03-14 01:20:18 +00:00
|
|
|
|
2009-06-23 07:32:43 +00:00
|
|
|
//
|
|
|
|
// Return the address
|
|
|
|
//
|
2009-03-10 00:31:14 +00:00
|
|
|
return Address;
|
|
|
|
}
|