Author: tkreuzer
Date: Sun Jul 25 12:00:26 2010
New Revision: 48249
URL:
http://svn.reactos.org/svn/reactos?rev=48249&view=rev
Log:
[NTOSKRNL]
- Fix MiAddressToPti and implement MiAddressToPxi for amd64
- Replace #error with DPRINT and ASSERT(FALSE) in MiInitializeLargePageSupport
- Implement amd64 specific MmCreateProcessAddressSpace
- Add MmProtectToPteMask for amd64 (copied from x86)
- Remove amd64 version of MmInitializeHandBuiltProcess
Modified:
trunk/reactos/ntoskrnl/include/internal/amd64/mm.h
trunk/reactos/ntoskrnl/mm/ARM3/largepag.c
trunk/reactos/ntoskrnl/mm/ARM3/procsup.c
trunk/reactos/ntoskrnl/mm/amd64/page.c
Modified: trunk/reactos/ntoskrnl/include/internal/amd64/mm.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/amd64/mm.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/amd64/mm.h [iso-8859-1] Sun Jul 25 12:00:26
2010
@@ -108,12 +108,17 @@
FORCEINLINE
MiAddressToPti(PVOID Address)
{
- ULONG64 Pti = (ULONG64)Address >> PTI_SHIFT;
- Pti &= PTI_MASK_AMD64;
- return Pti;
-}
-
-#define MiAddressToPteOffset(x) MiAddressToPti(x)
+ return ((((ULONG64)Address) >> PTI_SHIFT) & 0x1FF);
+}
+#define MiAddressToPteOffset(x) MiAddressToPti(x) // FIXME: bad name
+
+ULONG
+FORCEINLINE
+MiAddressToPxi(PVOID Address)
+{
+ return ((((ULONG64)Address) >> PXI_SHIFT) & 0x1FF);
+}
+
/* Convert a PTE into a corresponding address */
PVOID
Modified: trunk/reactos/ntoskrnl/mm/ARM3/largepag.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/largepag.…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/largepag.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/largepag.c [iso-8859-1] Sun Jul 25 12:00:26 2010
@@ -34,7 +34,8 @@
MiInitializeLargePageSupport(VOID)
{
#if _MI_PAGING_LEVELS > 2
-#error "PAE/x64 Not Implemented"
+ DPRINT1("PAE/x64 Not Implemented\n");
+ ASSERT(FALSE);
#else
/* Initialize the large-page hyperspace PTE used for initial mapping */
MiLargePageHyperPte = MiReserveSystemPtes(1, SystemPteSpace);
Modified: trunk/reactos/ntoskrnl/mm/ARM3/procsup.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/procsup.c…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/procsup.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/procsup.c [iso-8859-1] Sun Jul 25 12:00:26 2010
@@ -1040,6 +1040,7 @@
return STATUS_SUCCESS;
}
+#ifdef _M_IX86
/* FIXME: Evaluate ways to make this portable yet arch-specific */
BOOLEAN
NTAPI
@@ -1131,6 +1132,7 @@
MiReleaseSystemPtes(PointerPte, 1, SystemPteSpace);
return TRUE;
}
+#endif
VOID
NTAPI
Modified: trunk/reactos/ntoskrnl/mm/amd64/page.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/amd64/page.c?r…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/amd64/page.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/amd64/page.c [iso-8859-1] Sun Jul 25 12:00:26 2010
@@ -5,6 +5,7 @@
* PURPOSE: Low level memory managment manipulation
*
* PROGRAMMER: Timo Kreuzer (timo.kreuzer(a)reactos.org)
+ * ReactOS Portable Systems Group
*/
/* INCLUDES ***************************************************************/
@@ -12,6 +13,7 @@
#include <ntoskrnl.h>
#define NDEBUG
#include <debug.h>
+#include "../ARM3/miarm.h"
#undef InterlockedExchangePte
#define InterlockedExchangePte(pte1, pte2) \
@@ -25,6 +27,55 @@
/* GLOBALS *****************************************************************/
+const
+ULONG
+MmProtectToPteMask[32] =
+{
+ //
+ // These are the base MM_ protection flags
+ //
+ 0,
+ PTE_READONLY | PTE_ENABLE_CACHE,
+ PTE_EXECUTE | PTE_ENABLE_CACHE,
+ PTE_EXECUTE_READ | PTE_ENABLE_CACHE,
+ PTE_READWRITE | PTE_ENABLE_CACHE,
+ PTE_WRITECOPY | PTE_ENABLE_CACHE,
+ PTE_EXECUTE_READWRITE | PTE_ENABLE_CACHE,
+ PTE_EXECUTE_WRITECOPY | PTE_ENABLE_CACHE,
+ //
+ // These OR in the MM_NOCACHE flag
+ //
+ 0,
+ PTE_READONLY | PTE_DISABLE_CACHE,
+ PTE_EXECUTE | PTE_DISABLE_CACHE,
+ PTE_EXECUTE_READ | PTE_DISABLE_CACHE,
+ PTE_READWRITE | PTE_DISABLE_CACHE,
+ PTE_WRITECOPY | PTE_DISABLE_CACHE,
+ PTE_EXECUTE_READWRITE | PTE_DISABLE_CACHE,
+ PTE_EXECUTE_WRITECOPY | PTE_DISABLE_CACHE,
+ //
+ // These OR in the MM_DECOMMIT flag, which doesn't seem supported on x86/64/ARM
+ //
+ 0,
+ PTE_READONLY | PTE_ENABLE_CACHE,
+ PTE_EXECUTE | PTE_ENABLE_CACHE,
+ PTE_EXECUTE_READ | PTE_ENABLE_CACHE,
+ PTE_READWRITE | PTE_ENABLE_CACHE,
+ PTE_WRITECOPY | PTE_ENABLE_CACHE,
+ PTE_EXECUTE_READWRITE | PTE_ENABLE_CACHE,
+ PTE_EXECUTE_WRITECOPY | PTE_ENABLE_CACHE,
+ //
+ // These OR in the MM_NOACCESS flag, which seems to enable WriteCombining?
+ //
+ 0,
+ PTE_READONLY | PTE_WRITECOMBINED_CACHE,
+ PTE_EXECUTE | PTE_WRITECOMBINED_CACHE,
+ PTE_EXECUTE_READ | PTE_WRITECOMBINED_CACHE,
+ PTE_READWRITE | PTE_WRITECOMBINED_CACHE,
+ PTE_WRITECOPY | PTE_WRITECOMBINED_CACHE,
+ PTE_EXECUTE_READWRITE | PTE_WRITECOMBINED_CACHE,
+ PTE_EXECUTE_WRITECOPY | PTE_WRITECOMBINED_CACHE,
+};
/* PRIVATE FUNCTIONS *******************************************************/
@@ -489,34 +540,95 @@
return MmCreateVirtualMappingUnsafe(Process, Address, Protect, Pages, PageCount);
}
-NTSTATUS
-NTAPI
-MmInitializeHandBuiltProcess(IN PEPROCESS Process,
- IN PULONG_PTR DirectoryTableBase)
-{
- /* Share the directory base with the idle process */
- DirectoryTableBase[0] = PsGetCurrentProcess()->Pcb.DirectoryTableBase[0];
- DirectoryTableBase[1] = PsGetCurrentProcess()->Pcb.DirectoryTableBase[1];
-
- /* Initialize the Addresss Space */
- KeInitializeGuardedMutex(&Process->AddressCreationLock);
- Process->Vm.WorkingSetExpansionLinks.Flink = NULL;
- ASSERT(Process->VadRoot.NumberGenericTableElements == 0);
- Process->VadRoot.BalancedRoot.u1.Parent = &Process->VadRoot.BalancedRoot;
-
- /* The process now has an address space */
- Process->HasAddressSpace = TRUE;
- return STATUS_SUCCESS;
-}
-
BOOLEAN
NTAPI
MmCreateProcessAddressSpace(IN ULONG MinWs,
IN PEPROCESS Process,
- IN PULONG_PTR DirectoryTableBase)
-{
- UNIMPLEMENTED;
- return 0;
+ OUT PULONG_PTR DirectoryTableBase)
+{
+ KIRQL OldIrql;
+ PFN_NUMBER TableBasePfn, HyperPfn;
+ PMMPTE PointerPte;
+ MMPTE TempPte, PdePte;
+ ULONG TableIndex;
+ PMMPTE SystemTable;
+
+ /* No page colors yet */
+ Process->NextPageColor = 0;
+
+ /* Setup the hyperspace lock */
+ KeInitializeSpinLock(&Process->HyperSpaceLock);
+
+ /* Lock PFN database */
+ OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+
+ /* Get a page for the table base and for hyperspace */
+ TableBasePfn = MiRemoveAnyPage(0);
+ HyperPfn = MiRemoveAnyPage(0);
+
+ /* Release PFN lock */
+ KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+
+ /* Zero both pages */
+ MiZeroPhysicalPage(TableBasePfn);
+ MiZeroPhysicalPage(HyperPfn);
+
+ /* Set the base directory pointers */
+ DirectoryTableBase[0] = TableBasePfn << PAGE_SHIFT;
+ DirectoryTableBase[1] = HyperPfn << PAGE_SHIFT;
+
+ /* Make sure we don't already have a page directory setup */
+ ASSERT(Process->Pcb.DirectoryTableBase[0] == 0);
+
+ /* Insert us into the Mm process list */
+ InsertTailList(&MmProcessList, &Process->MmProcessLinks);
+
+ /* Get a PTE to map the page directory */
+ PointerPte = MiReserveSystemPtes(1, SystemPteSpace);
+ ASSERT(PointerPte != NULL);
+
+ /* Build it */
+ MI_MAKE_HARDWARE_PTE_KERNEL(&PdePte,
+ PointerPte,
+ MM_READWRITE,
+ TableBasePfn);
+
+ /* Set it dirty and map it */
+ PdePte.u.Hard.Dirty = TRUE;
+ MI_WRITE_VALID_PTE(PointerPte, PdePte);
+
+ /* Now get the page directory (which we'll double map, so call it a page table
*/
+ SystemTable = MiPteToAddress(PointerPte);
+
+ /* Copy all the kernel mappings */
+ TableIndex = MiAddressToPxi(MmSystemRangeStart);
+
+ RtlCopyMemory(&SystemTable[TableIndex],
+ MiAddressToPxe(MmSystemRangeStart),
+ PAGE_SIZE - TableIndex * sizeof(MMPTE));
+
+ /* Now write the PTE/PDE entry for hyperspace itself */
+ TempPte = ValidKernelPte;
+ TempPte.u.Hard.PageFrameNumber = HyperPfn;
+ TableIndex = MiAddressToPxi(HYPER_SPACE);
+ SystemTable[TableIndex] = TempPte;
+
+ /* Sanity check */
+ ASSERT(MiAddressToPxi(MmHyperSpaceEnd) > TableIndex);
+
+ /* Now do the x86 trick of making the PDE a page table itself */
+ TableIndex = MiAddressToPxi(PTE_BASE);
+ TempPte.u.Hard.PageFrameNumber = TableBasePfn;
+ SystemTable[TableIndex] = TempPte;
+
+ /* Let go of the system PTE */
+ MiReleaseSystemPtes(PointerPte, 1, SystemPteSpace);
+
+ /* Switch to phase 1 initialization */
+ ASSERT(Process->AddressSpaceInitialized == 0);
+ Process->AddressSpaceInitialized = 1;
+
+ return TRUE;
}
/* EOF */