#include <ntoskrnl.h>
#define NDEBUG
#include <debug.h>
-#include "../ARM3/miarm.h"
+#include <mm/ARM3/miarm.h>
#if defined (ALLOC_PRAGMA)
#pragma alloc_text(INIT, MmInitGlobalKernelPageDirectory)
-#pragma alloc_text(INIT, MiInitPageDirectoryMap)
#endif
+#define ADDR_TO_PDE_OFFSET MiAddressToPdeOffset
+#define ADDR_TO_PAGE_TABLE(v) (((ULONG)(v)) / (1024 * PAGE_SIZE))
/* GLOBALS *****************************************************************/
#define PA_ACCESSED (1 << PA_BIT_ACCESSED)
#define PA_GLOBAL (1 << PA_BIT_GLOBAL)
-#define HYPERSPACE (0xc0400000)
-#define IS_HYPERSPACE(v) (((ULONG)(v) >= HYPERSPACE && (ULONG)(v) < HYPERSPACE + 0x400000))
+#define IS_HYPERSPACE(v) (((ULONG)(v) >= HYPER_SPACE && (ULONG)(v) <= HYPER_SPACE_END))
#define PTE_TO_PFN(X) ((X) >> PAGE_SHIFT)
#define PFN_TO_PTE(X) ((X) << PAGE_SHIFT)
-#if defined(__GNUC__)
-#define PTE_TO_PAGE(X) ((LARGE_INTEGER)(LONGLONG)(PAGE_MASK(X)))
-#else
-__inline LARGE_INTEGER PTE_TO_PAGE(ULONG npage)
-{
- LARGE_INTEGER dummy;
- dummy.QuadPart = (LONGLONG)(PAGE_MASK(npage));
- return dummy;
-}
-#endif
+#define PAGE_MASK(x) ((x)&(~0xfff))
const
ULONG
/* FUNCTIONS ***************************************************************/
-BOOLEAN MmUnmapPageTable(PULONG Pt);
+static BOOLEAN MmUnmapPageTable(PULONG Pt);
VOID
MiFlushTlb(PULONG Pt, PVOID Address)
return(Attributes);
}
-/* Taken from ARM3/pagfault.c */
-BOOLEAN
-FORCEINLINE
-MiSynchronizeSystemPde(PMMPDE PointerPde)
-{
- MMPDE SystemPde;
- ULONG Index;
-
- /* Get the Index from the PDE */
- Index = ((ULONG_PTR)PointerPde & (SYSTEM_PD_SIZE - 1)) / sizeof(MMPTE);
-
- /* Copy the PDE from the double-mapped system page directory */
- SystemPde = MmSystemPagePtes[Index];
- *PointerPde = SystemPde;
-
- /* Make sure we re-read the PDE and PTE */
- KeMemoryBarrierWithoutFence();
-
- /* Return, if we had success */
- return SystemPde.u.Hard.Valid != 0;
-}
-
NTSTATUS
NTAPI
MiDispatchFault(IN BOOLEAN StoreInstruction,
{
PMMPDE PdeBase;
ULONG PdeOffset = MiGetPdeOffset(Address);
-
+
/* Nobody but page fault should ask for creating the PDE,
* Which imples that Process is the current one */
ASSERT(Create == FALSE);
-
+
PdeBase = MmCreateHyperspaceMapping(PTE_TO_PFN(Process->Pcb.DirectoryTableBase[0]));
if (PdeBase == NULL)
{
PsGetCurrentProcess(),
NULL,
NULL);
+ DBG_UNREFERENCED_LOCAL_VARIABLE(Status);
ASSERT(KeAreAllApcsDisabled() == TRUE);
ASSERT(PointerPde->u.Hard.Valid == 1);
}
return Pt;
}
-BOOLEAN MmUnmapPageTable(PULONG Pt)
+static BOOLEAN MmUnmapPageTable(PULONG Pt)
{
if (!IS_HYPERSPACE(Pt))
{
VOID
NTAPI
-MmDisableVirtualMapping(PEPROCESS Process, PVOID Address, BOOLEAN* WasDirty, PPFN_NUMBER Page)
-/*
- * FUNCTION: Delete a virtual mapping
- */
-{
- BOOLEAN WasValid;
- ULONG Pte;
- PULONG Pt;
-
- Pt = MmGetPageTableForProcess(Process, Address, FALSE);
- if (Pt == NULL)
- {
- KeBugCheck(MEMORY_MANAGEMENT);
- }
-
- /*
- * Atomically disable the present bit and get the old value.
- */
- do
- {
- Pte = *Pt;
- } while (Pte != InterlockedCompareExchangePte(Pt, Pte & ~PA_PRESENT, Pte));
-
- MiFlushTlb(Pt, Address);
-
- WasValid = (Pte & PA_PRESENT);
- if (!WasValid)
- {
- KeBugCheck(MEMORY_MANAGEMENT);
- }
-
- /*
- * Return some information to the caller
- */
- if (WasDirty != NULL)
- {
- *WasDirty = Pte & PA_DIRTY;
- }
- if (Page != NULL)
- {
- *Page = PTE_TO_PFN(Pte);
- }
-}
-
-VOID
-NTAPI
-MmRawDeleteVirtualMapping(PVOID Address)
-{
- PULONG Pt;
-
- Pt = MmGetPageTableForProcess(NULL, Address, FALSE);
- if (Pt && *Pt)
- {
- /*
- * Set the entry to zero
- */
- InterlockedExchangePte(Pt, 0);
- MiFlushTlb(Pt, Address);
- }
-}
-
-VOID
-NTAPI
-MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOLEAN FreePage,
+MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address,
BOOLEAN* WasDirty, PPFN_NUMBER Page)
/*
* FUNCTION: Delete a virtual mapping
ULONG Pte;
PULONG Pt;
- DPRINT("MmDeleteVirtualMapping(%x, %x, %d, %x, %x)\n",
- Process, Address, FreePage, WasDirty, Page);
+ DPRINT("MmDeleteVirtualMapping(%p, %p, %p, %p)\n",
+ Process, Address, WasDirty, Page);
Pt = MmGetPageTableForProcess(Process, Address, FALSE);
}
Pfn = PTE_TO_PFN(Pte);
-
- if (FreePage)
- {
- MmReleasePageMemoryConsumer(MC_SYSTEM, Pfn);
- Pfn = 0;
- }
}
else
{
{
PMMPDE PointerPde = MiAddressToPde(Address);
PMMPTE PointerPte = MiAddressToPte(Address);
-
+
if (PointerPde->u.Hard.Valid == 0)
{
if(!MiSynchronizeSystemPde(PointerPde))
}
}
-VOID
-NTAPI
-MmEnableVirtualMapping(PEPROCESS Process, PVOID Address)
-{
- PULONG Pt;
- ULONG Pte;
-
- Pt = MmGetPageTableForProcess(Process, Address, FALSE);
- if (Pt == NULL)
- {
- //HACK to get DPH working, waiting for MM rewrite :-/
- //KeBugCheck(MEMORY_MANAGEMENT);
- return;
- }
-
- /* Do not mark a 0 page as present */
- if(0 == InterlockedCompareExchangePte(Pt, 0, 0))
- return;
-
- do
- {
- Pte = *Pt;
- } while (Pte != InterlockedCompareExchangePte(Pt, Pte | PA_PRESENT, Pte));
-
- /* We don't need to flush the TLB here because it
- * won't cache translations for non-present pages */
- MmUnmapPageTable(Pt);
-}
-
BOOLEAN
NTAPI
MmIsPagePresent(PEPROCESS Process, PVOID Address)
ULONG oldPdeOffset, PdeOffset;
PULONG Pt = NULL;
ULONG Pte;
- DPRINT("MmCreateVirtualMappingUnsafe(%x, %x, %x, %x (%x), %d)\n",
+ DPRINT("MmCreateVirtualMappingUnsafe(%p, %p, %lu, %p (%x), %lu)\n",
Process, Address, flProtect, Pages, *Pages, PageCount);
ASSERT(((ULONG_PTR)Address % PAGE_SIZE) == 0);
if (!(Attributes & PA_PRESENT) && Pages[i] != 0)
{
DPRINT1("Setting physical address but not allowing access at address "
- "0x%.8X with attributes %x/%x.\n",
+ "0x%p with attributes %x/%x.\n",
Addr, Attributes, flProtect);
KeBugCheck(MEMORY_MANAGEMENT);
}
/* There should not be anything valid here */
if (Pte != 0)
{
- DPRINT1("Bad PTE %lx\n", Pte);
+ DPRINT1("Bad PTE %lx at %p for %p + %lu\n", Pte, Pt, Address, i);
KeBugCheck(MEMORY_MANAGEMENT);
}
PULONG Pt;
ULONG Pte;
- DPRINT("MmSetPageProtect(Process %x Address %x flProtect %x)\n",
+ DPRINT("MmSetPageProtect(Process %p Address %p flProtect %x)\n",
Process, Address, flProtect);
Attributes = ProtectToPTE(flProtect);
MmUnmapPageTable(Pt);
}
-/*
- * @implemented
- */
-PHYSICAL_ADDRESS NTAPI
-MmGetPhysicalAddress(PVOID vaddr)
-/*
- * FUNCTION: Returns the physical address corresponding to a virtual address
- */
-{
- PHYSICAL_ADDRESS p;
- ULONG Pte;
-
- DPRINT("MmGetPhysicalAddress(vaddr %x)\n", vaddr);
- Pte = MmGetPageEntryForProcess(NULL, vaddr);
- if (Pte != 0 && (Pte & PA_PRESENT))
- {
- p.QuadPart = PAGE_MASK(Pte);
- p.u.LowPart |= (ULONG_PTR)vaddr & (PAGE_SIZE - 1);
- }
- else
- {
- p.QuadPart = 0;
- }
- return p;
-}
-
VOID
INIT_FUNCTION
NTAPI