Refactor MMU for multi-paging support and add 5-Level paging #16

Open
harraiken wants to merge 35 commits from harraiken_mm into master
2 changed files with 46 additions and 14 deletions
Showing only changes of commit 1ef2560ef6 - Show all commits

View File

@ -43,14 +43,13 @@ XtpDeterminePagingLevel(IN CONST PWCHAR Parameters)
/* Query CPUID */ /* Query CPUID */
ArCpuId(&CpuRegisters); ArCpuId(&CpuRegisters);
// TODO: Uncomment the following code when LA57 support is implemented in the bootloader /* Check if eXtended Physical Addressing (XPA) is enabled and if LA57 is supported by the CPU */
// /* Check if eXtended Physical Addressing (XPA) is enabled and if LA57 is supported by the CPU */ if((CpuRegisters.Ecx & CPUID_FEATURES_ECX_LA57) &&
// if((CpuRegisters.Ecx & CPUID_FEATURES_ECX_LA57) && !(XtLdrProtocol->BootUtil.GetBooleanParameter(Parameters, L"NOXPA")))
// !(XtLdrProtocol->BootUtil.GetBooleanParameter(Parameters, L"NOXPA"))) {
// { /* Enable LA57 (PML5) */
// /* Enable LA57 (PML5) */ return 5;
// return 4; }
// }
} }
/* Disable LA57 and use PML4 by default */ /* Disable LA57 and use PML4 by default */
@ -213,6 +212,9 @@ EFI_STATUS
XtEnablePaging(IN PXTBL_PAGE_MAPPING PageMap) XtEnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
{ {
EFI_STATUS Status; EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS TrampolineAddress;
PXT_TRAMPOLINE_ENTRY TrampolineEntry;
ULONG_PTR TrampolineSize;
/* Build page map */ /* Build page map */
Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, (PageMap->PageMapLevel > 4) ? MM_P5E_LA57_BASE : MM_PXE_BASE); Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, (PageMap->PageMapLevel > 4) ? MM_P5E_LA57_BASE : MM_PXE_BASE);
@ -232,6 +234,29 @@ XtEnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
return Status; return Status;
} }
/* Check the configured page map level to set the LA57 state accordingly */
if(PageMap->PageMapLevel == 5)
{
/* Set the address of the trampoline code below 1MB */
TrampolineAddress = MM_TRAMPOLINE_ADDRESS;
/* Calculate the size of the trampoline code */
TrampolineSize = (ULONG_PTR)ArEnableExtendedPhysicalAddressingEnd - (ULONG_PTR)ArEnableExtendedPhysicalAddressing;
/* Allocate pages for the trampoline */
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAddress, EFI_SIZE_TO_PAGES(TrampolineSize), &TrampolineAddress);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to allocate memory for trampoline code */
XtLdrProtocol->Debug.Print(L"Failed to allocate memory for trampoline code (Status code: %zX)\n", Status);
return Status;
}
/* Set the trampoline entry point and copy its code into the allocated buffer */
TrampolineEntry = (PXT_TRAMPOLINE_ENTRY)(UINT_PTR)TrampolineAddress;
RtlCopyMemory(TrampolineEntry, ArEnableExtendedPhysicalAddressing, TrampolineSize);
}
/* Exit EFI Boot Services */ /* Exit EFI Boot Services */
XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n"); XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n");
Status = XtLdrProtocol->Util.ExitBootServices(); Status = XtLdrProtocol->Util.ExitBootServices();
@ -247,18 +272,19 @@ XtEnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
{ {
/* Enable Linear Address 57-bit (LA57) extension */ /* Enable Linear Address 57-bit (LA57) extension */
XtLdrProtocol->Debug.Print(L"Enabling Linear Address 57-bit (LA57)\n"); XtLdrProtocol->Debug.Print(L"Enabling Linear Address 57-bit (LA57)\n");
/* Execute the trampoline to enable LA57 and write PML5 to CR3 */
TrampolineEntry((UINT64)PageMap->PtePointer);
} }
else else
{ {
/* Disable Linear Address 57-bit (LA57) extension */ /* Disable Linear Address 57-bit (LA57) extension */
XtLdrProtocol->Debug.Print(L"Disabling Linear Address 57-bit (LA57)\n"); XtLdrProtocol->Debug.Print(L"Disabling Linear Address 57-bit (LA57)\n");
}
/* Write PML4 to CR3 */ /* Write PML4 to CR3 and enable paging */
ArWriteControlRegister(3, (UINT_PTR)PageMap->PtePointer); ArWriteControlRegister(3, (UINT_PTR)PageMap->PtePointer);
/* Enable paging */
ArWriteControlRegister(0, ArReadControlRegister(0) | CR0_PG); ArWriteControlRegister(0, ArReadControlRegister(0) | CR0_PG);
}
/* Return success */ /* Return success */
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;

View File

@ -29,9 +29,15 @@ typedef struct _XT_FRAMEBUFFER_PROTOCOL
/* EFI XT Loader Protocol */ /* EFI XT Loader Protocol */
EXTERN PXTBL_LOADER_PROTOCOL XtLdrProtocol; EXTERN PXTBL_LOADER_PROTOCOL XtLdrProtocol;
/* XTOS trampoline end address to calculate trampoline size */
EXTERN PVOID ArEnableExtendedPhysicalAddressingEnd[];
/* XTOS kernel entry point */ /* XTOS kernel entry point */
typedef VOID (XTAPI *PXT_ENTRY_POINT)(IN PKERNEL_INITIALIZATION_BLOCK BootParameters); typedef VOID (XTAPI *PXT_ENTRY_POINT)(IN PKERNEL_INITIALIZATION_BLOCK BootParameters);
/* XTOS trampoline entry point */
typedef VOID (*PXT_TRAMPOLINE_ENTRY)(UINT64 PageMap);
/* XTOS boot protocol related routines forward references */ /* XTOS boot protocol related routines forward references */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS