- Get rid of the MmGlobalKernelPageDirectory hack. It's not going to be used on amd64. Instead set up a total of 256 (1MB) shared PDPs in the PML4.

- Partly implement phase 1 of MmArmInitSystem
- Fix MiPteToAddress
- Fix MmSystemRangeStart

svn path=/branches/ros-amd64-bringup/; revision=44174
This commit is contained in:
Timo Kreuzer
2009-11-15 16:10:52 +00:00
parent 36c73e8aee
commit 5eb72addd0
3 changed files with 172 additions and 94 deletions
+29 -4
View File
@@ -14,15 +14,15 @@
#define HYPER_SPACE_END 0xFFFFF77FFFFFFFFFULL
#define MI_SESSION_VIEW_END (PVOID)0xFFFFF97FFF000000ULL
#define MI_SESSION_SPACE_END (PVOID)0xFFFFF98000000000ULL
#define MI_SYSTEM_PTE_START (PVOID)0xFFFFFAA000000000ULL
#define MI_PAGED_POOL_START (PVOID)0xFFFFFA8000000000ULL
#define MI_NON_PAGED_SYSTEM_START_MIN 0xFFFFFAA000000000ULL
#define MI_NONPAGED_POOL_END (PVOID)0xFFFFFAE000000000ULL
#define MI_DEBUG_MAPPING (PVOID)0xFFFFFFFF80000000ULL // FIXME
#define MI_HIGHEST_SYSTEM_ADDRESS (PVOID)0xFFFFFFFFFFFFFFFFULL
#define MI_NUMBER_SYSTEM_PTES 22000
PULONG64
FORCEINLINE
@@ -68,7 +68,16 @@ MiAddressToPte(PVOID Address)
}
/* Convert a PTE into a corresponding address */
#define MiPteToAddress(PTE) ((PVOID)((ULONG64)(PTE) << 9))
PVOID
FORCEINLINE
MiPteToAddress(PMMPTE Pte)
{
/* Use signed math */
LONG64 Temp = (LONG64)Pte;
Temp <<= 25;
Temp >>= 16;
return (PVOID)Temp;
}
//#define ADDR_TO_PAGE_TABLE(v) (((ULONG)(v)) / (1024 * PAGE_SIZE))
//#define ADDR_TO_PDE_OFFSET(v) ((((ULONG)(v)) / (1024 * PAGE_SIZE)))
@@ -79,6 +88,22 @@ MiAddressToPte(PVOID Address)
#define VAtoPDI(va) ((((ULONG64)va) >> PDI_SHIFT) & 0x1FF)
#define VAtoPTI(va) ((((ULONG64)va) >> PTI_SHIFT) & 0x1FF)
/* We don't use these hacks */
VOID
FORCEINLINE
MmUpdatePageDir(PEPROCESS Process, PVOID Address, ULONG Size)
{
/* Nothing to do */
}
VOID
FORCEINLINE
MmInitGlobalKernelPageDirectory(VOID)
{
/* Nothing to do */
}
/// MIARM.H
/* Easy accessing PFN in PTE */
+143 -9
View File
@@ -5,12 +5,13 @@
* PURPOSE: Memory Manager Initialization for amd64
*
* PROGRAMMERS: Timo kreuzer ([email protected])
* ReactOS Portable Systems Group
*/
/* INCLUDES ***************************************************************/
#include <ntoskrnl.h>
#define NDEBUG
//#define NDEBUG
#include <debug.h>
#include "../ARM3/miarm.h"
@@ -21,7 +22,7 @@ extern PMMPTE MmDebugPte;
ULONG64 MmUserProbeAddress = 0x7FFFFFF0000ULL;
PVOID MmHighestUserAddress = (PVOID)0x7FFFFFEFFFFULL;
PVOID MmSystemRangeStart = (PVOID)KSEG0_BASE; // FFFF080000000000
PVOID MmSystemRangeStart = (PVOID)0xFFFF080000000000ULL;
/* Size of session view, pool, and image */
ULONG64 MmSessionSize = MI_SESSION_SIZE;
@@ -346,7 +347,7 @@ MiArmInitializeMemoryLayout(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
MmSystemViewSize);
/* Use the default */
MmNumberOfSystemPtes = 22000;
MmNumberOfSystemPtes = MI_NUMBER_SYSTEM_PTES;
ASSERT(MiSessionViewEnd <= MiSessionImageStart);
ASSERT(MmSessionBase <= MiSessionPoolStart);
@@ -357,6 +358,7 @@ MiArmInitializePageTable()
{
ULONG64 PageFrameOffset;
PMMPTE Pte, StartPte, EndPte;
MMPTE TmpPte;
/* Get current directory base */
PageFrameOffset = ((PMMPTE)PXE_SELFMAP)->u.Hard.PageFrameNumber << PAGE_SHIFT;
@@ -366,22 +368,54 @@ MiArmInitializePageTable()
PsGetCurrentProcess()->Pcb.DirectoryTableBase[0] = PageFrameOffset;
/* HACK: don't use freeldr debug print anymore */
FrLdrDbgPrint = NoDbgPrint;
// FrLdrDbgPrint = NoDbgPrint;
/* Clear user mode mappings in PML4 */
StartPte = MiAddressToPxe(0);
EndPte = MiAddressToPxe(MmHighestUserAddress);
/* Loop the user mode PXEs */
for (Pte = StartPte; Pte <= EndPte; Pte++)
{
/* Zero the pte */
Pte->u.Long = 0;
/* Zero the PXE */
// Pte->u.Long = 0;
}
/* Setup a template PTE */
TmpPte.u.Long = 0;
TmpPte.u.Flush.Valid = 1;
TmpPte.u.Flush.Write = 1;
HyperTemplatePte = TmpPte;
/* Create PDPTs (1MB total) for shared system address space */
StartPte = MiAddressToPxe(MmSystemRangeStart);
EndPte = MiAddressToPxe(MI_HIGHEST_SYSTEM_ADDRESS);
/* Loop the system space PXEs */
for (Pte = StartPte; Pte <= EndPte; Pte++)
{
/* Is the PXE already valid? */
if (!Pte->u.Hard.Valid)
{
/* It's not Initialize it, creating a PDPT. */
TmpPte.u.Flush.PageFrameNumber = MxGetNextPage(1);
*Pte = TmpPte;
/* Zero the page. The PXE is the PTE for the PDPT. */
RtlZeroMemory(MiPteToAddress(Pte), PAGE_SIZE);
}
}
/* Flush the TLB */
KeFlushCurrentTb();
/* Setup debug mapping pte */
/* Setup the mapping PTEs */
MmFirstReservedMappingPte = MxGetPte((PVOID)MI_MAPPING_RANGE_START);
MmFirstReservedMappingPte->u.Hard.PageFrameNumber = MI_HYPERSPACE_PTES;
MmLastReservedMappingPte = MiAddressToPte((PVOID)MI_MAPPING_RANGE_END);
/* Setup debug mapping PTE */
MmDebugPte = MxGetPte(MI_DEBUG_MAPPING);
}
@@ -500,13 +534,85 @@ MiArmPrepareNonPagedPool()
MxGetPte(Address)->u.Long = 0;
}
//DPRINT1("MmNonPagedPoolStart = %p, Pte=%p \n", MmNonPagedPoolStart, MiAddressToPte(MmNonPagedPoolStart));
/* Sanity check */
ASSERT(MiAddressToPte(MmNonPagedSystemStart) <
MiAddressToPte(MmNonPagedPoolExpansionStart));
}
PPHYSICAL_MEMORY_DESCRIPTOR
NTAPI
MmInitializeMemoryLimits(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
IN PBOOLEAN IncludeType)
{
UNIMPLEMENTED;
return 0;
}
VOID
NTAPI
MiBuildPhysicalMemoryBlock(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
BOOLEAN IncludeType[LoaderMaximum];
PPHYSICAL_MEMORY_RUN Run;
PULONG Bitmap;
ULONG Size, i;
/* Instantiate memory that we don't consider RAM/usable */
for (i = 0; i < LoaderMaximum; i++) IncludeType[i] = TRUE;
IncludeType[LoaderBad] = FALSE;
IncludeType[LoaderFirmwarePermanent] = FALSE;
IncludeType[LoaderSpecialMemory] = FALSE;
IncludeType[LoaderBBTMemory] = FALSE;
/* Build the physical memory block */
MmPhysicalMemoryBlock = MmInitializeMemoryLimits(LoaderBlock, IncludeType);
/* Calculate size for the PFN bitmap */
Size = (MmHighestPhysicalPage + sizeof(ULONG)) / sizeof(ULONG);
/* Allocate the PFN bitmap */
Bitmap = ExAllocatePoolWithTag(NonPagedPool, Size, ' mM');
if (!Bitmap)
{
/* This is critical */
KeBugCheckEx(INSTALL_MORE_MEMORY,
MmNumberOfPhysicalPages,
MmLowestPhysicalPage,
MmHighestPhysicalPage,
0x101);
}
/* Initialize it and clear all the bits to begin with */
RtlInitializeBitMap(&MiPfnBitMap, Bitmap, MmHighestPhysicalPage + 1);
RtlClearAllBits(&MiPfnBitMap);
/* Loop physical memory runs */
for (i = 0; i < MmPhysicalMemoryBlock->NumberOfRuns; i++)
{
/* Get the run */
Run = &MmPhysicalMemoryBlock->Run[i];
DPRINT("PHYSICAL RAM [0x%08p to 0x%08p]\n",
Run->BasePage << PAGE_SHIFT,
(Run->BasePage + Run->PageCount) << PAGE_SHIFT);
/* Make sure it has pages inside it */
if (Run->PageCount)
{
/* Set the bits in the PFN bitmap */
RtlSetBits(&MiPfnBitMap, Run->BasePage, Run->PageCount);
}
}
}
VOID
NTAPI
MiBuildPagedPool(VOID)
{
UNIMPLEMENTED;
}
NTSTATUS
NTAPI
MmArmInitSystem(IN ULONG Phase,
@@ -543,11 +649,39 @@ MmArmInitSystem(IN ULONG Phase,
}
else if (Phase == 1)
{
PMMPTE Pte;
ULONG OldCount;
PPHYSICAL_MEMORY_RUN Run;
__debugbreak();
/* The PFN database was created, restore the free descriptor */
*MxFreeDescriptor = MxOldFreeDescriptor;
ASSERT(FALSE);
__debugbreak();
/* Initialize the nonpaged pool */
InitializePool(NonPagedPool, 0);
#if 0
/* Create the system PTE space */
Pte = MiAddressToPte(MI_SYSTEM_PTE_START);
MiInitializeSystemPtes(Pte, MmNumberOfSystemPtes, SystemPteSpace);
/* Reserve system PTEs for zeroing PTEs and clear them */
MiFirstReservedZeroingPte = MiReserveSystemPtes(MI_ZERO_PTES,
SystemPteSpace);
RtlZeroMemory(MiFirstReservedZeroingPte, MI_ZERO_PTES * sizeof(MMPTE));
/* Set the counter to maximum */
MiFirstReservedZeroingPte->u.Hard.PageFrameNumber = MI_ZERO_PTES - 1;
#endif
/* Build the physical memory block */
MiBuildPhysicalMemoryBlock(LoaderBlock);
/* Size up paged pool and build the shadow system page directory */
MiBuildPagedPool();
}
return STATUS_SUCCESS;
-81
View File
@@ -22,9 +22,6 @@ extern MMPTE HyperTemplatePte;
/* GLOBALS *****************************************************************/
ULONG64 MmGlobalKernelPageDirectory[512];
ULONG Ke386GlobalPagesEnabled = 0;
/* PRIVATE FUNCTIONS *******************************************************/
@@ -434,84 +431,6 @@ MmCreateVirtualMapping(PEPROCESS Process,
return STATUS_UNSUCCESSFUL;
}
VOID
NTAPI
MmUpdatePageDir(PEPROCESS Process, PVOID Address, ULONG Size)
{
ULONG StartIndex, EndIndex, Index;
PMMPTE Pte;
/* Sanity check */
if (Address < MmSystemRangeStart)
{
KeBugCheck(0);
}
/* Get pointer to the page directory to update */
if (Process && Process != PsGetCurrentProcess())
{
// Pte = MmCreateHyperspaceMapping(PTE_TO_PFN(Process->Pcb.DirectoryTableBase[0]));
}
else
{
Pte = (PMMPTE)PXE_BASE;
}
/* Update PML4 entries */
StartIndex = VAtoPXI(Address);
EndIndex = VAtoPXI((ULONG64)Address + Size - 1);
for (Index = StartIndex; Index <= EndIndex; Index++)
{
if (Index != VAtoPXI(PXE_BASE))
{
InterlockedCompareExchange64(&Pte[Index].u.Long,
MmGlobalKernelPageDirectory[Index],
0);
if (!MiIsHyperspaceAddress(Pte))
__invlpg((PVOID)((ULONG64)Index * PAGE_SIZE));
}
}
if (MiIsHyperspaceAddress(Pte))
MmDeleteHyperspaceMapping((PVOID)PAGE_ROUND_DOWN(Pte));
}
VOID
INIT_FUNCTION
NTAPI
MmInitGlobalKernelPageDirectory(VOID)
{
PULONG64 CurrentPageDirectory = (PULONG64)PXE_BASE;
MMPTE Pte;
ULONG i;
/* Setup template pte */
HyperTemplatePte.u.Long = 0;
HyperTemplatePte.u.Hard.Valid = 1;
HyperTemplatePte.u.Hard.Write = 1;
HyperTemplatePte.u.Hard.Dirty = 1;
HyperTemplatePte.u.Hard.Accessed = 1;
if (Ke386GlobalPagesEnabled)
HyperTemplatePte.u.Hard.Global = 1;
for (i = VAtoPXI(MmSystemRangeStart); i < 512; i++)
{
if ((i < VAtoPXI(PTE_BASE) || i > VAtoPXI(PTE_TOP)) &&
(i < VAtoPXI(HYPER_SPACE) || i > VAtoPXI(HYPER_SPACE_END)) &&
MmGlobalKernelPageDirectory[i] == 0 &&
CurrentPageDirectory[i] != 0)
{
Pte.u.Long = CurrentPageDirectory[i];
if (Ke386GlobalPagesEnabled)
{
Pte.u.Hard.Global = 1;
CurrentPageDirectory[i] = Pte.u.Hard.Global;
}
MmGlobalKernelPageDirectory[i] = Pte.u.Hard.Global;
}
}
}
NTSTATUS
NTAPI
MmInitializeHandBuiltProcess(IN PEPROCESS Process,