Author: ros-arm-bringup
Date: Sun Jul 27 14:52:41 2008
New Revision: 34857
URL:
http://svn.reactos.org/svn/reactos?rev=34857&view=rev
Log:
- Major cleanup, refactoring, and bugfixing of ARM Mm code in preparation for user-mode
support.
- Sync the code a lot closer to its x86 counterpart, still more work to be done.
- Very soon, it should be possible to share upward of 50% of the new ARM code with the x86
version of React as well and unify the implementations.
Modified:
trunk/reactos/ntoskrnl/include/internal/arm/mm.h
trunk/reactos/ntoskrnl/mm/arm/stubs.c
Modified: trunk/reactos/ntoskrnl/include/internal/arm/mm.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/arm/mm.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/arm/mm.h [iso-8859-1] Sun Jul 27 14:52:41
2008
@@ -147,4 +147,23 @@
ManagerDomain
} ARM_DOMAIN;
+//
+// Take 0x80812345 and extract:
+// PTE_BASE[0x808][0x12]
+//
+#define MiGetPteAddress(x) \
+ (PMMPTE)(PTE_BASE + \
+ (((ULONG)(x) >> 20) << 12) + \
+ ((((ULONG)(x) >> 12) & 0xFF) << 2))
+
+#define MiGetPdeAddress(x) \
+ (PMMPTE)(PDE_BASE + \
+ (((ULONG)(x) >> 20) << 2))
+
+#define MiGetPdeOffset(x) (((ULONG)(x)) >> 22)
+
+#define PTE_BASE 0xC0000000
+#define PDE_BASE 0xC1000000
+#define HYPER_SPACE ((PVOID)0xC1100000)
+
#endif
Modified: trunk/reactos/ntoskrnl/mm/arm/stubs.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/arm/stubs.c?re…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/arm/stubs.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/arm/stubs.c [iso-8859-1] Sun Jul 27 14:52:41 2008
@@ -14,37 +14,255 @@
/* GLOBALS ********************************************************************/
-#undef UNIMPLEMENTED
-#define UNIMPLEMENTED \
-{ \
- DPRINT1("[ARM Mm Bringup]: %s is unimplemented!\n", __FUNCTION__); \
- while (TRUE); \
-}
-
-//
-// Take 0x80812345 and extract:
-// PTE_BASE[0x808][0x12]
-//
-#define MiGetPteAddress(x) \
- (PMMPTE)(PTE_BASE + (((ULONG)(x) >> 20) << 12) + ((((ULONG)(x) >>
12) & 0xFF) << 2))
-
-#define MiGetPdeAddress(x) \
- (PMMPTE)(PDE_BASE + (((ULONG)(x) >> 20) << 2))
-
-#define MiGetPdeOffset(x) (((ULONG)(x)) >> 22)
-
-#define PTE_BASE 0xC0000000
-#define PDE_BASE 0xC1000000
-#define HYPER_SPACE ((PVOID)0xC1100000)
-
ULONG MmGlobalKernelPageDirectory[1024];
MMPTE MiArmTemplatePte, MiArmTemplatePde;
-VOID
-KiFlushSingleTb(IN BOOLEAN Invalid,
- IN PVOID Virtual);
-
-/* FUNCTIONS ******************************************************************/
+/* PRIVATE FUNCTIONS **********************************************************/
+
+BOOLEAN
+NTAPI
+MiUnmapPageTable(IN PMMPTE PointerPde)
+{
+ //
+ // Check if this address belongs to the kernel
+ //
+ if (((ULONG_PTR)PointerPde > PDE_BASE) ||
+ ((ULONG_PTR)PointerPde < (PDE_BASE + 1024*1024)))
+ {
+ //
+ // Nothing to do
+ //
+ return TRUE;
+ }
+
+ //
+ // FIXME-USER: Shouldn't get here yet
+ //
+ ASSERT(FALSE);
+ return FALSE;
+}
+
+VOID
+NTAPI
+MiFlushTlb(IN PMMPTE PointerPte,
+ IN PVOID Address)
+{
+ //
+ // Make sure the PTE is valid, and unmap the pagetable if user-mode
+ //
+ if (((PointerPte) && (MiUnmapPageTable(PointerPte))) ||
+ (Address >= MmSystemRangeStart))
+ {
+ //
+ // Invalidate this page
+ //
+ KeArmInvalidateTlbEntry(Address);
+ }
+}
+
+PMMPTE
+NTAPI
+MiGetPageTableForProcess(IN PEPROCESS Process,
+ IN PVOID Address,
+ IN BOOLEAN Create)
+{
+ ULONG PdeOffset;
+ PMMPTE PointerPde;
+ MMPTE Pte;
+ NTSTATUS Status;
+ PFN_NUMBER Pfn;
+
+ //
+ // Check if this is a user-mode, non-kernel or non-current address
+ //
+ if ((Address < MmSystemRangeStart) &&
+ (Process) &&
+ (Process != PsGetCurrentProcess()))
+ {
+ //
+ // FIXME-USER: No user-mode memory support
+ //
+ ASSERT(FALSE);
+ }
+
+ //
+ // Get the PDE
+ //
+ PointerPde = MiGetPdeAddress(Address);
+ if (PointerPde->u.Hard.L1.Fault.Type == FaultPte)
+ {
+ //
+ // Invalid PDE, is this a kernel address?
+ //
+ if (Address >= MmSystemRangeStart)
+ {
+ //
+ // Does it exist in the kernel page directory?
+ //
+ PdeOffset = MiGetPdeOffset(Address);
+ if (MmGlobalKernelPageDirectory[PdeOffset] == 0)
+ {
+ //
+ // It doesn't. Is this a create operation? If not, fail
+ //
+ if (Create == FALSE) return NULL;
+
+ //
+ // THIS WHOLE PATH IS TODO
+ //
+ ASSERT(FALSE);
+
+ //
+ // Allocate a non paged pool page for the PDE
+ //
+ Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn);
+ if (!NT_SUCCESS(Status)) return NULL;
+
+ //
+ // Make the entry valid
+ //
+ Pte.u.Hard.AsUlong = 0xDEADBEEF;
+
+ //
+ // Save it
+ //
+ MmGlobalKernelPageDirectory[PdeOffset] = Pte.u.Hard.AsUlong;
+ }
+
+ //
+ // Now set the actual PDE
+ //
+ PointerPde = (PMMPTE)&MmGlobalKernelPageDirectory[PdeOffset];
+ }
+ else
+ {
+ //
+ // Is this a create operation? If not, fail
+ //
+ if (Create == FALSE) return NULL;
+
+ //
+ // THIS WHOLE PATH IS TODO
+ //
+ ASSERT(FALSE);
+
+ //
+ // Allocate a non paged pool page for the PDE
+ //
+ Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn);
+ if (!NT_SUCCESS(Status)) return NULL;
+
+ //
+ // Make the entry valid
+ //
+ Pte.u.Hard.AsUlong = 0xDEADBEEF;
+
+ //
+ // Set it
+ //
+ *PointerPde = Pte;
+ }
+ }
+
+ //
+ // Return the PTE
+ //
+ return MiGetPteAddress(Address);
+}
+
+MMPTE
+NTAPI
+MiGetPageEntryForProcess(IN PEPROCESS Process,
+ IN PVOID Address)
+{
+ PMMPTE PointerPte;
+ MMPTE Pte;
+ Pte.u.Hard.AsUlong = 0;
+
+ //
+ // Get the PTE
+ //
+ PointerPte = MiGetPageTableForProcess(Process, Address, FALSE);
+ if (PointerPte)
+ {
+ //
+ // Capture the PTE value and unmap the page table
+ //
+ Pte = *PointerPte;
+ MiUnmapPageTable(PointerPte);
+ }
+
+ //
+ // Return the PTE value
+ //
+ return Pte;
+}
+
+VOID
+NTAPI
+MmDeletePageTable(IN PEPROCESS Process,
+ IN PVOID Address)
+{
+ PMMPTE PointerPde;
+
+ //
+ // Not valid for kernel addresses
+ //
+ DPRINT("MmDeletePageTable(%p, %p)\n", Process, Address);
+ ASSERT(Address < MmSystemRangeStart);
+
+ //
+ // Check if this is for a different process
+ //
+ if ((Process) && (Process != PsGetCurrentProcess()))
+ {
+ //
+ // FIXME-USER: Need to attach to the process
+ //
+ ASSERT(FALSE);
+ }
+
+ //
+ // Get the PDE
+ //
+ PointerPde = MiGetPdeAddress(Address);
+
+ //
+ // On ARM, we use a section mapping for the original low-memory mapping
+ //
+ if ((Address) || (PointerPde->u.Hard.L1.Section.Type != SectionPte))
+ {
+ //
+ // Make sure it's valid
+ //
+ ASSERT(PointerPde->u.Hard.L1.Coarse.Type == CoarsePte);
+ }
+
+ //
+ // Clear the PDE
+ //
+ PointerPde->u.Hard.AsUlong = 0;
+ ASSERT(PointerPde->u.Hard.L1.Fault.Type == FaultPte);
+
+ //
+ // Invalidate the TLB entry
+ //
+ MiFlushTlb(PointerPde, MiAddressToPte(Address));
+}
+
+BOOLEAN
+NTAPI
+MmCreateProcessAddressSpace(IN ULONG MinWs,
+ IN PEPROCESS Process,
+ IN PLARGE_INTEGER DirectoryTableBase)
+{
+ //
+ // FIXME-USER: Need to create address space
+ //
+ UNIMPLEMENTED;
+ while (TRUE);
+ return 0;
+}
VOID
NTAPI
@@ -63,9 +281,10 @@
Mmi386ReleaseMmInfo(IN PEPROCESS Process)
{
//
- // TODO
+ // FIXME-USER: Need to delete address space
//
UNIMPLEMENTED;
+ while (TRUE);
return 0;
}
@@ -92,121 +311,13 @@
}
PULONG
+NTAPI
MmGetPageDirectory(VOID)
{
//
// Return the TTB
//
return (PULONG)KeArmTranslationTableRegisterGet().AsUlong;
-}
-
-
-BOOLEAN
-NTAPI
-MmCreateProcessAddressSpace(IN ULONG MinWs,
- IN PEPROCESS Process,
- IN PLARGE_INTEGER DirectoryTableBase)
-{
- //
- // TODO
- //
- UNIMPLEMENTED;
- return 0;
-}
-
-VOID
-NTAPI
-MmDeletePageTable(IN PEPROCESS Process,
- IN PVOID Address)
-{
- PMMPTE PointerPde;
-
- //
- // Not valid for kernel addresses
- //
- DPRINT("MmDeletePageTable(%p, %p)\n", Process, Address);
- ASSERT(Address < MmSystemRangeStart);
-
- //
- // Check if this is for a different process
- //
- if ((Process) && (Process != PsGetCurrentProcess()))
- {
- //
- // TODO
- //
- UNIMPLEMENTED;
- return;
- }
-
- //
- // Get the PDE
- //
- PointerPde = MiGetPdeAddress(Address);
-
- //
- // On ARM, we use a section mapping for the original low-memory mapping
- //
- if ((Address) || (PointerPde->u.Hard.L1.Section.Type != SectionPte))
- {
- //
- // Make sure it's valid
- //
- ASSERT(PointerPde->u.Hard.L1.Coarse.Type == CoarsePte);
- }
-
- //
- // Clear the PDE
- //
- PointerPde->u.Hard.AsUlong = 0;
- ASSERT(PointerPde->u.Hard.L1.Fault.Type == FaultPte);
-
- //
- // Invalidate the TLB entry
- //
- KiFlushSingleTb(TRUE, Address);
-}
-
-PFN_TYPE
-NTAPI
-MmGetPfnForProcess(IN PEPROCESS Process,
- IN PVOID Address)
-{
- PMMPTE Pte;
-
- //
- // Check if this is for a different process
- //
- if ((Process) && (Process != PsGetCurrentProcess()))
- {
- //
- // TODO
- //
- UNIMPLEMENTED;
- return 0;
- }
-
- //
- // Get the PDE
- //
- Pte = MiGetPdeAddress(Address);
- if (Pte->u.Hard.L1.Fault.Type != FaultPte)
- {
- //
- // Get the PTE
- //
- Pte = MiGetPteAddress(Address);
- }
-
- //
- // If PTE is invalid, return 0
- //
- if (Pte->u.Hard.L2.Fault.Type == FaultPte) return 0;
-
- //
- // Return PFN
- //
- return Pte->u.Hard.L2.Small.BaseAddress;
}
VOID
@@ -220,186 +331,7 @@
// TODO
//
UNIMPLEMENTED;
-}
-
-VOID
-NTAPI
-MmRawDeleteVirtualMapping(IN PVOID Address)
-{
- PMMPTE PointerPte, PointerPde;
-
- //
- // Get the PDE
- //
- PointerPde = MiGetPdeAddress(Address);
- if (PointerPde->u.Hard.L1.Fault.Type == FaultPte) return;
-
- //
- // Get the PTE
- //
- PointerPte = MiGetPteAddress(Address);
- ASSERT(PointerPte->u.Hard.L2.Small.Type == SmallPte);
-
- //
- // Destroy the PTE
- //
- PointerPte->u.Hard.AsUlong = 0;
- ASSERT(PointerPte->u.Hard.L2.Fault.Type == FaultPte);
-
- //
- // Flush the TLB
- //
- KiFlushSingleTb(TRUE, Address);
-}
-
-VOID
-NTAPI
-MmDeleteVirtualMapping(IN PEPROCESS Process,
- IN PVOID Address,
- IN BOOLEAN FreePage,
- OUT PBOOLEAN WasDirty,
- OUT PPFN_TYPE Page)
-{
- PMMPTE PointerPte, PointerPde;
- MMPTE Pte;
-
- //
- // Check if this is for a different process
- //
- if ((Process) && (Process != PsGetCurrentProcess()))
- {
- //
- // TODO
- //
- UNIMPLEMENTED;
- return;
- }
-
- //
- // Get the PDE
- //
- PointerPde = MiGetPdeAddress(Address);
- if (PointerPde->u.Hard.L1.Fault.Type == FaultPte)
- {
- //
- // Invalid PDE
- //
- if (WasDirty) *WasDirty = FALSE;
- if (Page) *Page = 0;
- return;
- }
-
- //
- // Get the PTE
- //
- PointerPte = MiGetPteAddress(Address);
- if (PointerPte->u.Hard.L1.Fault.Type == FaultPte)
- {
- //
- // Invalid PTE
- //
- if (WasDirty) *WasDirty = FALSE;
- if (Page) *Page = 0;
- return;
- }
-
- //
- // Save the PTE
- //
- Pte = *PointerPte;
- ASSERT(PointerPte->u.Hard.L2.Small.Type == SmallPte);
-
- //
- // Destroy the PTE
- //
- PointerPte->u.Hard.AsUlong = 0;
- ASSERT(PointerPte->u.Hard.L2.Fault.Type == FaultPte);
-
- //
- // Flush the TLB
- //
- KiFlushSingleTb(TRUE, Address);
-
- //
- // Check if the PTE was valid
- //
- if (Pte.u.Hard.L2.Fault.Type != FaultPte)
- {
- //
- // Mark the page as unmapped
- //
- MmMarkPageUnmapped(Pte.u.Hard.L2.Small.BaseAddress);
- }
- else
- {
- //
- // Make it sane
- //
- Pte.u.Hard.L2.Small.BaseAddress = 0;
- }
-
- //
- // Check if this was our page, and valid
- //
- if ((FreePage) && (Pte.u.Hard.L2.Fault.Type != FaultPte))
- {
- //
- // Release it
- //
- MmReleasePageMemoryConsumer(MC_NPPOOL, Pte.u.Hard.L2.Small.BaseAddress);
- }
-
- //
- // Return if the page was dirty
- //
- if (WasDirty) *WasDirty = TRUE; // LIE!!!
- if (Page) *Page = Pte.u.Hard.L2.Small.BaseAddress;
-}
-
-VOID
-NTAPI
-MmDeletePageFileMapping(IN PEPROCESS Process,
- IN PVOID Address,
- IN SWAPENTRY *SwapEntry)
-{
- //
- // TODO
- //
- UNIMPLEMENTED;
-}
-
-BOOLEAN
-NTAPI
-MmIsDirtyPage(IN PEPROCESS Process,
- IN PVOID Address)
-{
- //
- // TODO
- //
- UNIMPLEMENTED;
- return 0;
-}
-
-VOID
-NTAPI
-MmSetCleanPage(IN PEPROCESS Process,
- IN PVOID Address)
-{
- //
- // TODO
- //
- UNIMPLEMENTED;
-}
-
-VOID
-NTAPI
-MmSetDirtyPage(IN PEPROCESS Process,
- IN PVOID Address)
-{
- //
- // TODO
- //
- UNIMPLEMENTED;
+ while (TRUE);
}
VOID
@@ -411,80 +343,7 @@
// TODO
//
UNIMPLEMENTED;
-}
-
-BOOLEAN
-NTAPI
-MmIsPagePresent(IN PEPROCESS Process,
- IN PVOID Address)
-{
- PMMPTE Pte;
-
- //
- // Check if this is for a different process
- //
- if ((Process) && (Process != PsGetCurrentProcess()))
- {
- //
- // TODO
- //
- UNIMPLEMENTED;
- return 0;
- }
-
- //
- // Get the PDE
- //
- Pte = MiGetPdeAddress(Address);
- if (Pte->u.Hard.L1.Fault.Type != FaultPte)
- {
- //
- // Get the PTE
- //
- Pte = MiGetPteAddress(Address);
- }
-
- //
- // Return whether or not it's valid
- //
- return (Pte->u.Hard.L1.Fault.Type != FaultPte);
-}
-
-BOOLEAN
-NTAPI
-MmIsPageSwapEntry(IN PEPROCESS Process,
- IN PVOID Address)
-{
- PMMPTE Pte;
-
- //
- // Check if this is for a different process
- //
- if ((Process) && (Process != PsGetCurrentProcess()))
- {
- //
- // TODO
- //
- UNIMPLEMENTED;
- return 0;
- }
-
- //
- // Get the PDE
- //
- Pte = MiGetPdeAddress(Address);
- if (Pte->u.Hard.L1.Fault.Type != FaultPte)
- {
- //
- // Get the PTE
- //
- Pte = MiGetPteAddress(Address);
- }
-
- //
- // Return whether or not it's valid
- //
- return ((Pte->u.Hard.L2.Fault.Type == FaultPte) &&
(Pte->u.Hard.AsUlong));
+ while (TRUE);
}
NTSTATUS
@@ -501,13 +360,13 @@
PFN_NUMBER Pfn;
DPRINT("[KMAP]: %p %d\n", Address, PageCount);
//ASSERT(Address >= MmSystemRangeStart);
-
+
//
// Get our templates
//
TempPte = MiArmTemplatePte;
TempPde = MiArmTemplatePde;
-
+
//
// Check if we have PDEs for this region
//
@@ -547,7 +406,7 @@
// Write the PFN of the PDE
//
TempPte.u.Hard.L2.Small.BaseAddress = Pfn;
-
+
//
// Write the PTE
//
@@ -573,7 +432,7 @@
// Mark it as mapped
//
if (MarkAsMapped) MmMarkPageMapped(*Pages);
-
+
//
// Set the PFN
//
@@ -597,20 +456,6 @@
//
return STATUS_SUCCESS;
}
-
-NTSTATUS
-NTAPI
-MmCreatePageFileMapping(IN PEPROCESS Process,
- IN PVOID Address,
- IN SWAPENTRY SwapEntry)
-{
- //
- // TODO
- //
- UNIMPLEMENTED;
- return 0;
-}
-
NTSTATUS
NTAPI
@@ -653,9 +498,9 @@
}
//
- // TODO
- //
- UNIMPLEMENTED;
+ // FIXME-USER: Support user-mode mappings
+ //
+ ASSERT(FALSE);
return 0;
}
@@ -668,7 +513,7 @@
IN ULONG PageCount)
{
ULONG i;
-
+
//
// Loop each page
//
@@ -690,76 +535,114 @@
PageCount);
}
-ULONG
-NTAPI
-MmGetPageProtect(IN PEPROCESS Process,
- IN PVOID Address)
-{
- //
- // We don't enforce any protection on the pages -- they are all RWX
- //
- return PAGE_READWRITE;
-}
-
-VOID
-NTAPI
-MmSetPageProtect(IN PEPROCESS Process,
- IN PVOID Address,
- IN ULONG Protection)
-{
- //
- // We don't enforce any protection on the pages -- they are all RWX
- //
- return;
-}
-
-/*
- * @implemented
- */
-PHYSICAL_ADDRESS
-NTAPI
-MmGetPhysicalAddress(IN PVOID Address)
-{
- PHYSICAL_ADDRESS PhysicalAddress = {{0}};
+VOID
+NTAPI
+MmRawDeleteVirtualMapping(IN PVOID Address)
+{
PMMPTE PointerPte;
-
- //
- // Early boot PCR check
- //
- if (Address == PCR)
- {
- //
- // ARM Hack while we still use a section PTE
- //
- PointerPte = MiGetPdeAddress(PCR);
- ASSERT(PointerPte->u.Hard.L1.Section.Type == SectionPte);
- PhysicalAddress.QuadPart = PointerPte->u.Hard.L1.Section.BaseAddress;
- PhysicalAddress.QuadPart <<= CPT_SHIFT;
- PhysicalAddress.LowPart += BYTE_OFFSET(Address);
- return PhysicalAddress;
- }
//
// Get the PTE
//
- PointerPte = MiGetPteAddress(Address);
+ PointerPte = MiGetPageTableForProcess(NULL, Address, FALSE);
+ if ((PointerPte) && (PointerPte->u.Hard.L2.Fault.Type != FaultPte))
+ {
+ //
+ // Destroy it
+ //
+ PointerPte->u.Hard.AsUlong = 0;
+
+ //
+ // Flush the TLB
+ //
+ MiFlushTlb(PointerPte, Address);
+ }
+}
+
+VOID
+NTAPI
+MmDeleteVirtualMapping(IN PEPROCESS Process,
+ IN PVOID Address,
+ IN BOOLEAN FreePage,
+ OUT PBOOLEAN WasDirty,
+ OUT PPFN_TYPE Page)
+{
+ PMMPTE PointerPte;
+ MMPTE Pte;
+
+ //
+ // Get the PTE
+ //
+ PointerPte = MiGetPageTableForProcess(NULL, Address, FALSE);
+ if (!PointerPte)
+ {
+ //
+ // Invalid PDE
+ //
+ if (WasDirty) *WasDirty = FALSE;
+ if (Page) *Page = 0;
+ return;
+ }
+
+ //
+ // Save the PTE
+ //
+ Pte = *PointerPte;
if (PointerPte->u.Hard.L1.Fault.Type == FaultPte)
{
//
- // Invalid address
- //
- DPRINT1("Address invalid: %p\n", Address);
- return PhysicalAddress;
- }
-
- //
- // Return the information
- //
- ASSERT(PointerPte->u.Hard.L2.Small.Type == SmallPte);
- PhysicalAddress.QuadPart = PointerPte->u.Hard.L2.Small.BaseAddress;
- PhysicalAddress.QuadPart <<= PAGE_SHIFT;
- PhysicalAddress.LowPart += BYTE_OFFSET(Address);
- return PhysicalAddress;
+ // Invalid PTE
+ //
+ if (WasDirty) *WasDirty = FALSE;
+ if (Page) *Page = 0;
+ return;
+ }
+
+ //
+ // Destroy the PTE
+ //
+ PointerPte->u.Hard.AsUlong = 0;
+ ASSERT(PointerPte->u.Hard.L2.Fault.Type == FaultPte);
+
+ //
+ // Flush the TLB
+ //
+ MiFlushTlb(PointerPte, Address);
+
+ //
+ // Check if the PTE was valid
+ //
+ if (Pte.u.Hard.L2.Fault.Type != FaultPte)
+ {
+ //
+ // Mark the page as unmapped
+ //
+ MmMarkPageUnmapped(Pte.u.Hard.L2.Small.BaseAddress);
+ }
+ else
+ {
+ //
+ // Make it sane
+ //
+ Pte.u.Hard.L2.Small.BaseAddress = 0;
+ }
+
+ //
+ // Check if this was our page, and valid
+ //
+ if ((FreePage) && (Pte.u.Hard.L2.Fault.Type != FaultPte))
+ {
+ //
+ // Release it
+ //
+ MmReleasePageMemoryConsumer(MC_NPPOOL, Pte.u.Hard.L2.Small.BaseAddress);
+ }
+
+ //
+ // Return if the page was dirty
+ //
+ if (WasDirty) *WasDirty = TRUE; // LIE!!!
+ if (Page) *Page = Pte.u.Hard.L2.Small.BaseAddress;
}
PVOID
@@ -769,7 +652,7 @@
PMMPTE PointerPte, FirstPte, LastPte;
MMPTE TempPte;
PVOID Address;
-
+
//
// Loop hyperspace PTEs (1MB)
//
@@ -807,12 +690,12 @@
ASSERT(PointerPte->u.Hard.L2.Fault.Type == FaultPte);
ASSERT(TempPte.u.Hard.L2.Small.Type == SmallPte);
*PointerPte = TempPte;
-
+
//
// Return the address
//
Address = HYPER_SPACE + ((PointerPte - FirstPte) * PAGE_SIZE);
- KiFlushSingleTb(FALSE, Address);
+ KeArmInvalidateTlbEntry(Address);
DPRINT("[HMAP]: %p %lx\n", Address, Page);
return Address;
}
@@ -845,8 +728,153 @@
//
// Flush the TLB entry and return the PFN
//
- KiFlushSingleTb(TRUE, Address);
+ KeArmInvalidateTlbEntry(Address);
return Pfn;
+}
+
+VOID
+NTAPI
+MmDeletePageFileMapping(IN PEPROCESS Process,
+ IN PVOID Address,
+ IN SWAPENTRY *SwapEntry)
+{
+ //
+ // TODO
+ //
+ UNIMPLEMENTED;
+ while (TRUE);
+}
+
+NTSTATUS
+NTAPI
+MmCreatePageFileMapping(IN PEPROCESS Process,
+ IN PVOID Address,
+ IN SWAPENTRY SwapEntry)
+{
+ //
+ // TODO
+ //
+ UNIMPLEMENTED;
+ while (TRUE);
+ return 0;
+}
+
+PFN_TYPE
+NTAPI
+MmGetPfnForProcess(IN PEPROCESS Process,
+ IN PVOID Address)
+{
+ MMPTE Pte;
+
+ //
+ // Get the PTE
+ //
+ Pte = MiGetPageEntryForProcess(Process, Address);
+ if (Pte.u.Hard.L2.Fault.Type == FaultPte) return 0;
+
+ //
+ // Return PFN
+ //
+ return Pte.u.Hard.L2.Small.BaseAddress;
+}
+
+ULONG
+NTAPI
+MiGetUserPageDirectoryCount(VOID)
+{
+ //
+ // Return the index
+ //
+ return MiGetPdeOffset(MmSystemRangeStart);
+}
+
+BOOLEAN
+NTAPI
+MmIsDirtyPage(IN PEPROCESS Process,
+ IN PVOID Address)
+{
+ //
+ // TODO
+ //
+ UNIMPLEMENTED;
+ while (TRUE);
+ return 0;
+}
+
+VOID
+NTAPI
+MmSetCleanPage(IN PEPROCESS Process,
+ IN PVOID Address)
+{
+ //
+ // TODO
+ //
+ UNIMPLEMENTED;
+ while (TRUE);
+}
+
+VOID
+NTAPI
+MmSetDirtyPage(IN PEPROCESS Process,
+ IN PVOID Address)
+{
+ //
+ // TODO
+ //
+ UNIMPLEMENTED;
+ while (TRUE);
+}
+
+BOOLEAN
+NTAPI
+MmIsPagePresent(IN PEPROCESS Process,
+ IN PVOID Address)
+{
+ //
+ // Fault PTEs are 0, which is FALSE (non-present)
+ //
+ return MiGetPageEntryForProcess(Process, Address).u.Hard.L2.Fault.Type;
+}
+
+BOOLEAN
+NTAPI
+MmIsPageSwapEntry(IN PEPROCESS Process,
+ IN PVOID Address)
+{
+ MMPTE Pte;
+
+ //
+ // Get the PTE
+ //
+ Pte = MiGetPageEntryForProcess(Process, Address);
+
+ //
+ // Make sure it's valid, but faulting
+ //
+ return (Pte.u.Hard.L2.Fault.Type == FaultPte) && (Pte.u.Hard.AsUlong);
+}
+
+ULONG
+NTAPI
+MmGetPageProtect(IN PEPROCESS Process,
+ IN PVOID Address)
+{
+ //
+ // We don't enforce any protection on the pages -- they are all RWX
+ //
+ return PAGE_READWRITE;
+}
+
+VOID
+NTAPI
+MmSetPageProtect(IN PEPROCESS Process,
+ IN PVOID Address,
+ IN ULONG Protection)
+{
+ //
+ // We don't enforce any protection on the pages -- they are all RWX
+ //
+ return;
}
VOID
@@ -862,7 +890,7 @@
//
MiArmTemplatePte = *MiGetPteAddress(0x80000000);
MiArmTemplatePde = *MiGetPdeAddress(0x80000000);
-
+
//
// Loop the 2GB of address space which belong to the kernel
//
@@ -884,16 +912,6 @@
}
}
-ULONG
-NTAPI
-MiGetUserPageDirectoryCount(VOID)
-{
- //
- // Return the index
- //
- return MiGetPdeOffset(MmSystemRangeStart);
-}
-
VOID
NTAPI
MiInitPageDirectoryMap(VOID)
@@ -902,7 +920,7 @@
PHYSICAL_ADDRESS BoundaryAddressMultiple;
PVOID BaseAddress;
NTSTATUS Status;
-
+
//
// Create memory area for the PTE area
//
@@ -918,7 +936,7 @@
0,
BoundaryAddressMultiple);
ASSERT(NT_SUCCESS(Status));
-
+
//
// Create memory area for the PDE area
//
@@ -949,3 +967,60 @@
BoundaryAddressMultiple);
ASSERT(NT_SUCCESS(Status));
}
+
+/* PUBLIC FUNCTIONS ***********************************************************/
+
+/*
+ * @implemented
+ */
+PHYSICAL_ADDRESS
+NTAPI
+MmGetPhysicalAddress(IN PVOID Address)
+{
+ PHYSICAL_ADDRESS PhysicalAddress;
+ MMPTE Pte;
+
+ //
+ // Early boot PCR check
+ //
+ if (Address == PCR)
+ {
+ //
+ // ARM Hack while we still use a section PTE
+ //
+ PMMPTE PointerPte;
+ PointerPte = MiGetPdeAddress(PCR);
+ ASSERT(PointerPte->u.Hard.L1.Section.Type == SectionPte);
+ PhysicalAddress.QuadPart = PointerPte->u.Hard.L1.Section.BaseAddress;
+ PhysicalAddress.QuadPart <<= CPT_SHIFT;
+ PhysicalAddress.LowPart += BYTE_OFFSET(Address);
+ return PhysicalAddress;
+ }
+
+ //
+ // Get the PTE
+ //
+ Pte = MiGetPageEntryForProcess(NULL, Address);
+ if ((Pte.u.Hard.AsUlong) && (Pte.u.Hard.L2.Fault.Type != FaultPte))
+ {
+ //
+ // Return the information
+ //
+ ASSERT(Pte.u.Hard.L2.Small.Type == SmallPte);
+ PhysicalAddress.QuadPart = Pte.u.Hard.L2.Small.BaseAddress;
+ PhysicalAddress.QuadPart <<= PAGE_SHIFT;
+ PhysicalAddress.LowPart += BYTE_OFFSET(Address);
+ }
+ else
+ {
+ //
+ // Invalid or unmapped
+ //
+ PhysicalAddress.QuadPart = 0;
+ }
+
+ //
+ // Return the physical address
+ //
+ return PhysicalAddress;
+}