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/a... ============================================================================== --- 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?rev... ============================================================================== --- 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; +}