Some work on Mm initialization, added a call to HalInitializeBios, so we have a mapped bios now.

svn path=/branches/ros-amd64-bringup/; revision=44982
This commit is contained in:
Timo Kreuzer 2010-01-06 22:53:31 +00:00
parent ef9b8f7942
commit 042bc809cf

View file

@ -1,5 +1,5 @@
/* /*
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: GPL, See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/amd64/init.c * FILE: ntoskrnl/mm/amd64/init.c
* PURPOSE: Memory Manager Initialization for amd64 * PURPOSE: Memory Manager Initialization for amd64
@ -20,6 +20,10 @@
extern PMMPTE MmDebugPte; extern PMMPTE MmDebugPte;
#endif #endif
VOID
NTAPI
HalInitializeBios(ULONG Unknown, PLOADER_PARAMETER_BLOCK LoaderBlock);
/* GLOBALS *****************************************************************/ /* GLOBALS *****************************************************************/
/* Sizes */ /* Sizes */
@ -76,15 +80,16 @@ ULONG64 MxPfnSizeInBytes;
PMEMORY_ALLOCATION_DESCRIPTOR MxFreeDescriptor; PMEMORY_ALLOCATION_DESCRIPTOR MxFreeDescriptor;
MEMORY_ALLOCATION_DESCRIPTOR MxOldFreeDescriptor; MEMORY_ALLOCATION_DESCRIPTOR MxOldFreeDescriptor;
ULONG MiNumberDescriptors = 0; ULONG MiNumberDescriptors = 0;
PFN_NUMBER MiSystemPages = 0;
BOOLEAN MiIncludeType[LoaderMaximum]; BOOLEAN MiIncludeType[LoaderMaximum];
PFN_NUMBER MxFreePageBase; PFN_NUMBER MxFreePageBase;
ULONG64 MxFreePageCount = 0; ULONG64 MxFreePageCount = 0;
ULONG MxPhase = 0;
PFN_NUMBER MmSystemPageDirectory; PFN_NUMBER MmSystemPageDirectory;
PFN_NUMBER MmSizeOfPagedPoolInPages = MI_MIN_INIT_PAGED_POOLSIZE / PAGE_SIZE; PFN_NUMBER MmSizeOfPagedPoolInPages = MI_MIN_INIT_PAGED_POOLSIZE / PAGE_SIZE;
BOOLEAN MiPfnsInitialized = FALSE;
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
@ -98,7 +103,7 @@ VOID
NTAPI NTAPI
MiEvaluateMemoryDescriptors(IN PLOADER_PARAMETER_BLOCK LoaderBlock) MiEvaluateMemoryDescriptors(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{ {
PMEMORY_ALLOCATION_DESCRIPTOR MdBlock; PMEMORY_ALLOCATION_DESCRIPTOR Descriptor;
PLIST_ENTRY ListEntry; PLIST_ENTRY ListEntry;
PFN_NUMBER LastPage; PFN_NUMBER LastPage;
ULONG i; ULONG i;
@ -120,31 +125,31 @@ MiEvaluateMemoryDescriptors(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
ListEntry = ListEntry->Flink) ListEntry = ListEntry->Flink)
{ {
/* Get the memory descriptor */ /* Get the memory descriptor */
MdBlock = CONTAINING_RECORD(ListEntry, Descriptor = CONTAINING_RECORD(ListEntry,
MEMORY_ALLOCATION_DESCRIPTOR, MEMORY_ALLOCATION_DESCRIPTOR,
ListEntry); ListEntry);
/* Count it */ /* Count it */
MiNumberDescriptors++; MiNumberDescriptors++;
/* Skip pages that are not part of the PFN database */ /* Skip pages that are not part of the PFN database */
if (!MiIncludeType[MdBlock->MemoryType]) if (!MiIncludeType[Descriptor->MemoryType])
{ {
continue; continue;
} }
/* Add this to the total of pages */ /* Add this to the total of pages */
MmNumberOfPhysicalPages += MdBlock->PageCount; MmNumberOfPhysicalPages += Descriptor->PageCount;
/* Check if this is the new lowest page */ /* Check if this is the new lowest page */
if (MdBlock->BasePage < MmLowestPhysicalPage) if (Descriptor->BasePage < MmLowestPhysicalPage)
{ {
/* Update the lowest page */ /* Update the lowest page */
MmLowestPhysicalPage = MdBlock->BasePage; MmLowestPhysicalPage = Descriptor->BasePage;
} }
/* Check if this is the new highest page */ /* Check if this is the new highest page */
LastPage = MdBlock->BasePage + MdBlock->PageCount - 1; LastPage = Descriptor->BasePage + Descriptor->PageCount - 1;
if (LastPage > MmHighestPhysicalPage) if (LastPage > MmHighestPhysicalPage)
{ {
/* Update the highest page */ /* Update the highest page */
@ -152,29 +157,39 @@ MiEvaluateMemoryDescriptors(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
} }
/* Check if this is currently free memory */ /* Check if this is currently free memory */
if ((MdBlock->MemoryType == LoaderFree) || if ((Descriptor->MemoryType == LoaderFree) ||
(MdBlock->MemoryType == LoaderLoadedProgram) || (Descriptor->MemoryType == LoaderLoadedProgram) ||
(MdBlock->MemoryType == LoaderFirmwareTemporary) || (Descriptor->MemoryType == LoaderFirmwareTemporary) ||
(MdBlock->MemoryType == LoaderOsloaderStack)) (Descriptor->MemoryType == LoaderOsloaderStack))
{ {
/* Check if this is the largest memory descriptor */ /* Check if this is the largest memory descriptor */
if (MdBlock->PageCount > MxFreePageCount) if (Descriptor->PageCount > MxFreePageCount)
{ {
/* For now, it is */ /* For now, it is */
MxFreeDescriptor = MdBlock; MxFreeDescriptor = Descriptor;
MxFreePageBase = MdBlock->BasePage; MxFreePageBase = Descriptor->BasePage;
MxFreePageCount = MdBlock->PageCount; MxFreePageCount = Descriptor->PageCount;
} }
} }
else
{
/* Add it to the amount of system used pages */
MiSystemPages += Descriptor->PageCount;
}
} }
} }
PFN_NUMBER PFN_NUMBER
NTAPI NTAPI
MxAllocEarlyPage() MiEarlyAllocPage()
{ {
PFN_NUMBER Pfn; PFN_NUMBER Pfn;
if (MiPfnsInitialized)
{
return MmAllocPage(MC_SYSTEM, 0);
}
/* Make sure we have enough pages */ /* Make sure we have enough pages */
if (!MxFreePageCount) if (!MxFreePageCount)
{ {
@ -193,13 +208,6 @@ MxAllocEarlyPage()
return Pfn; return Pfn;
} }
PFN_NUMBER
NTAPI
MxAllocPage()
{
return (MxPhase == 0) ? MxAllocEarlyPage() : MmAllocPage(MC_SYSTEM, 0);
}
PMMPTE PMMPTE
NTAPI NTAPI
MxGetPte(PVOID Address) MxGetPte(PVOID Address)
@ -217,8 +225,11 @@ MxGetPte(PVOID Address)
if (!Pte->u.Hard.Valid) if (!Pte->u.Hard.Valid)
{ {
/* It's not valid, map it! */ /* It's not valid, map it! */
TmplPte.u.Hard.PageFrameNumber = MxAllocPage(); TmplPte.u.Hard.PageFrameNumber = MiEarlyAllocPage();
*Pte = TmplPte; *Pte = TmplPte;
/* Zero the page */
RtlZeroMemory(MiPteToAddress(Pte), PAGE_SIZE);
} }
/* Get a pointer to the PPE */ /* Get a pointer to the PPE */
@ -226,8 +237,11 @@ MxGetPte(PVOID Address)
if (!Pte->u.Hard.Valid) if (!Pte->u.Hard.Valid)
{ {
/* It's not valid, map it! */ /* It's not valid, map it! */
TmplPte.u.Hard.PageFrameNumber = MxAllocPage(); TmplPte.u.Hard.PageFrameNumber = MiEarlyAllocPage();
*Pte = TmplPte; *Pte = TmplPte;
/* Zero the page */
RtlZeroMemory(MiPteToAddress(Pte), PAGE_SIZE);
} }
/* Get a pointer to the PDE */ /* Get a pointer to the PDE */
@ -235,8 +249,11 @@ MxGetPte(PVOID Address)
if (!Pte->u.Hard.Valid) if (!Pte->u.Hard.Valid)
{ {
/* It's not valid, map it! */ /* It's not valid, map it! */
TmplPte.u.Hard.PageFrameNumber = MxAllocPage(); TmplPte.u.Hard.PageFrameNumber = MiEarlyAllocPage();
*Pte = TmplPte; *Pte = TmplPte;
/* Zero the page */
RtlZeroMemory(MiPteToAddress(Pte), PAGE_SIZE);
} }
/* Get a pointer to the PTE */ /* Get a pointer to the PTE */
@ -254,7 +271,7 @@ MxMapPage(PVOID Address)
TmplPte.u.Long = 0; TmplPte.u.Long = 0;
TmplPte.u.Flush.Valid = 1; TmplPte.u.Flush.Valid = 1;
TmplPte.u.Flush.Write = 1; TmplPte.u.Flush.Write = 1;
TmplPte.u.Hard.PageFrameNumber = MxAllocPage(); TmplPte.u.Hard.PageFrameNumber = MiEarlyAllocPage();
/* Get the PTE for that page */ /* Get the PTE for that page */
Pte = MxGetPte(Address); Pte = MxGetPte(Address);
@ -281,7 +298,7 @@ VOID
NTAPI NTAPI
MiPreparePfnDatabse(IN PLOADER_PARAMETER_BLOCK LoaderBlock) MiPreparePfnDatabse(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{ {
PMEMORY_ALLOCATION_DESCRIPTOR MdBlock; PMEMORY_ALLOCATION_DESCRIPTOR Descriptor;
PLIST_ENTRY ListEntry; PLIST_ENTRY ListEntry;
PUCHAR Page, FirstPage; PUCHAR Page, FirstPage;
SIZE_T Size; SIZE_T Size;
@ -299,16 +316,16 @@ MiPreparePfnDatabse(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
ListEntry = ListEntry->Flink) ListEntry = ListEntry->Flink)
{ {
/* Get the memory descriptor */ /* Get the memory descriptor */
MdBlock = CONTAINING_RECORD(ListEntry, Descriptor = CONTAINING_RECORD(ListEntry,
MEMORY_ALLOCATION_DESCRIPTOR, MEMORY_ALLOCATION_DESCRIPTOR,
ListEntry); ListEntry);
/* Skip pages that are not part of the PFN database */ /* Skip pages that are not part of the PFN database */
if (MiIncludeType[MdBlock->MemoryType]) if (MiIncludeType[Descriptor->MemoryType])
{ {
/* Get the base and size of this pfn database entry */ /* Get the base and size of this pfn database entry */
FirstPage = PAGE_ALIGN(&MmPfnDatabase[MdBlock->BasePage]); FirstPage = PAGE_ALIGN(&MmPfnDatabase[Descriptor->BasePage]);
Size = ROUND_TO_PAGES(MdBlock->PageCount * sizeof(MMPFN)); Size = ROUND_TO_PAGES(Descriptor->PageCount * sizeof(MMPFN));
/* Loop the pages of this Pfn database entry */ /* Loop the pages of this Pfn database entry */
for (Page = FirstPage; Page < FirstPage + Size; Page += PAGE_SIZE) for (Page = FirstPage; Page < FirstPage + Size; Page += PAGE_SIZE)
@ -318,6 +335,7 @@ MiPreparePfnDatabse(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{ {
/* It's not, map it now */ /* It's not, map it now */
MxMapPage(Page); MxMapPage(Page);
RtlZeroMemory(Page, PAGE_SIZE);
} }
} }
@ -384,6 +402,9 @@ MiInitializePageTable()
__writecr4(__readcr4() | CR4_PGE); __writecr4(__readcr4() | CR4_PGE);
ASSERT(__readcr4() & CR4_PGE); ASSERT(__readcr4() & CR4_PGE);
/* Enable no execute */
__writemsr(X86_MSR_EFER, __readmsr(X86_MSR_EFER) | EFER_NXE);
/* Loop the user mode PXEs */ /* Loop the user mode PXEs */
for (Pte = MiAddressToPxe(0); for (Pte = MiAddressToPxe(0);
Pte <= MiAddressToPxe(MmHighestUserAddress); Pte <= MiAddressToPxe(MmHighestUserAddress);
@ -414,7 +435,7 @@ MiInitializePageTable()
if (!Pte->u.Hard.Valid) if (!Pte->u.Hard.Valid)
{ {
/* It's not Initialize it */ /* It's not Initialize it */
TmplPte.u.Flush.PageFrameNumber = MxAllocPage(); TmplPte.u.Flush.PageFrameNumber = MiEarlyAllocPage(0);
*Pte = TmplPte; *Pte = TmplPte;
/* Zero the page. The PXE is the PTE for the PDPT. */ /* Zero the page. The PXE is the PTE for the PDPT. */
@ -593,7 +614,7 @@ NTAPI
MiBuildPhysicalMemoryBlock(IN PLOADER_PARAMETER_BLOCK LoaderBlock) MiBuildPhysicalMemoryBlock(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{ {
PPHYSICAL_MEMORY_DESCRIPTOR Buffer; PPHYSICAL_MEMORY_DESCRIPTOR Buffer;
PMEMORY_ALLOCATION_DESCRIPTOR MdBlock; PMEMORY_ALLOCATION_DESCRIPTOR Descriptor;
PLIST_ENTRY ListEntry; PLIST_ENTRY ListEntry;
PFN_NUMBER NextPage = -1; PFN_NUMBER NextPage = -1;
PULONG Bitmap; PULONG Bitmap;
@ -632,35 +653,35 @@ MiBuildPhysicalMemoryBlock(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
ListEntry = ListEntry->Flink) ListEntry = ListEntry->Flink)
{ {
/* Get the memory descriptor */ /* Get the memory descriptor */
MdBlock = CONTAINING_RECORD(ListEntry, Descriptor = CONTAINING_RECORD(ListEntry,
MEMORY_ALLOCATION_DESCRIPTOR, MEMORY_ALLOCATION_DESCRIPTOR,
ListEntry); ListEntry);
/* Skip pages that are not part of the PFN database */ /* Skip pages that are not part of the PFN database */
if (!MiIncludeType[MdBlock->MemoryType]) if (!MiIncludeType[Descriptor->MemoryType])
{ {
continue; continue;
} }
/* Does the memory block begin where the last ended? */ /* Does the memory block begin where the last ended? */
if (MdBlock->BasePage == NextPage) if (Descriptor->BasePage == NextPage)
{ {
/* Add it to the current run */ /* Add it to the current run */
Buffer->Run[Runs - 1].PageCount += MdBlock->PageCount; Buffer->Run[Runs - 1].PageCount += Descriptor->PageCount;
} }
else else
{ {
/* Create a new run */ /* Create a new run */
Runs++; Runs++;
Buffer->Run[Runs - 1].BasePage = MdBlock->BasePage; Buffer->Run[Runs - 1].BasePage = Descriptor->BasePage;
Buffer->Run[Runs - 1].PageCount = MdBlock->PageCount; Buffer->Run[Runs - 1].PageCount = Descriptor->PageCount;
} }
/* Set the bits in the PFN bitmap */ /* Set the bits in the PFN bitmap */
RtlSetBits(&MiPfnBitMap, MdBlock->BasePage, MdBlock->PageCount); RtlSetBits(&MiPfnBitMap, Descriptor->BasePage, Descriptor->PageCount);
/* Set the next page */ /* Set the next page */
NextPage = MdBlock->BasePage + MdBlock->PageCount; NextPage = Descriptor->BasePage + Descriptor->PageCount;
} }
// FIXME: allocate a buffer of better size // FIXME: allocate a buffer of better size
@ -728,14 +749,14 @@ MiBuildPagedPool(VOID)
if (!Pte->u.Flush.Valid) if (!Pte->u.Flush.Valid)
{ {
/* Map it! */ /* Map it! */
TmplPte.u.Flush.PageFrameNumber = MxAllocPage(); TmplPte.u.Flush.PageFrameNumber = MiEarlyAllocPage();
*Pte = TmplPte; *Pte = TmplPte;
} }
} }
/* Create and map the first PTE for paged pool */ /* Create and map the first PTE for paged pool */
Pte = MxGetPte(MmPagedPoolStart); Pte = MxGetPte(MmPagedPoolStart);
TmplPte.u.Flush.PageFrameNumber = MxAllocPage(); TmplPte.u.Flush.PageFrameNumber = MiEarlyAllocPage();
*Pte = TmplPte; *Pte = TmplPte;
/* Save the first and last paged pool PTE */ /* Save the first and last paged pool PTE */
@ -801,9 +822,15 @@ MmArmInitSystem(IN ULONG Phase,
{ {
if (Phase == 0) if (Phase == 0)
{ {
/* Parse memory descriptors */ MmBootImageSize = KeLoaderBlock->Extension->LoaderPagesSpanned * PAGE_SIZE;
MmBootImageSize = ROUND_UP(MmBootImageSize, PAGE_SIZE);
/* Parse memory descriptors, find free pages */
MiEvaluateMemoryDescriptors(LoaderBlock); MiEvaluateMemoryDescriptors(LoaderBlock);
/* Start PFN database at hardcoded address */
MmPfnDatabase = MI_PFN_DATABASE;
/* Prepare PFN database mappings */ /* Prepare PFN database mappings */
MiPreparePfnDatabse(LoaderBlock); MiPreparePfnDatabse(LoaderBlock);
@ -824,8 +851,8 @@ MmArmInitSystem(IN ULONG Phase,
/* The PFN database was created, restore the free descriptor */ /* The PFN database was created, restore the free descriptor */
*MxFreeDescriptor = MxOldFreeDescriptor; *MxFreeDescriptor = MxOldFreeDescriptor;
/* Switch to phase 1 */ /* The pfn database is ready now */
MxPhase = 1; MiPfnsInitialized = TRUE;
/* Initialize the nonpaged pool */ /* Initialize the nonpaged pool */
MiBuildNonPagedPool(); MiBuildNonPagedPool();
@ -838,6 +865,14 @@ MmArmInitSystem(IN ULONG Phase,
/* Size up paged pool and build the shadow system page directory */ /* Size up paged pool and build the shadow system page directory */
MiBuildPagedPool(); MiBuildPagedPool();
// This is the old stuff:
MmPagedPoolBase = (PVOID)((PCHAR)MmPagedPoolEnd + 1);
MmPagedPoolSize = MM_PAGED_POOL_SIZE;
ASSERT((PCHAR)MmPagedPoolBase + MmPagedPoolSize < (PCHAR)MmNonPagedSystemStart);
HalInitializeBios(0, LoaderBlock);
} }
return STATUS_SUCCESS; return STATUS_SUCCESS;