diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index 86a767f..edc9130 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -46,7 +46,7 @@ typedef LONG (*PBL_GET_MEMTYPE_ROUTINE)(IN LONG EfiMemoryType); typedef EFI_STATUS (*PBL_ALLOCATE_PAGES)(IN ULONGLONG Size, OUT PEFI_PHYSICAL_ADDRESS Memory); typedef EFI_STATUS (*PBL_ALLOCATE_POOL)(IN UINT_PTR Size, OUT PVOID *Memory); typedef VOID (*PBL_BOOTMENU_INITIALIZE_OS_LIST)(OUT PXTBL_BOOTMENU_ITEM MenuEntries, OUT PULONG EntriesCount, OUT PULONG DefaultId); -typedef EFI_STATUS (*PBL_BUILD_PAGE_MAP)(IN PXTBL_PAGE_MAPPING PageMap); +typedef EFI_STATUS (*PBL_BUILD_PAGE_MAP)(IN PXTBL_PAGE_MAPPING PageMap, IN ULONG_PTR SelfMapAddress); typedef EFI_STATUS (*PBL_CLOSE_VOLUME)(IN PEFI_HANDLE VolumeHandle); typedef VOID (*PBL_CLEAR_CONSOLE_LINE)(IN ULONGLONG LineNo); typedef EFI_STATUS (*PBL_CLOSE_XT_PROTOCOL)(IN PEFI_HANDLE Handle, IN PEFI_GUID ProtocolGuid); diff --git a/xtldr/arch/amd64/memory.c b/xtldr/arch/amd64/memory.c index edd2a63..77df511 100644 --- a/xtldr/arch/amd64/memory.c +++ b/xtldr/arch/amd64/memory.c @@ -15,13 +15,17 @@ * @param PageMap * Supplies a pointer to the page mapping structure. * + * @param SelfMapAddress + * Supplies a virtual address of the page tables. + * * @return This routine returns a status code. * * @since XT 1.0 */ XTCDECL EFI_STATUS -BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap) +BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, + IN ULONG_PTR SelfMapAddress) { PLIST_ENTRY ListEntry, ModulesList, ModulesListEntry; PXTBL_MEMORY_MAPPING Mapping; @@ -42,7 +46,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap) RtlZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE); /* Add page mapping itself to memory mapping */ - Status = BlMapVirtualMemory(PageMap, NULL, PageMap->PtePointer, 1, LoaderMemoryData); + Status = BlpSelfMapPml(PageMap, SelfMapAddress); if(Status != STATUS_EFI_SUCCESS) { /* PML mapping failed */ @@ -227,3 +231,45 @@ BlMapPage(IN PXTBL_PAGE_MAPPING PageMap, /* Return success */ return STATUS_EFI_SUCCESS; } + +/** + * Creates a recursive self mapping for all PML levels. + * + * @param PageMap + * Supplies a pointer to the page mapping structure. + * + * @param SelfMapAddress + * Supplies a virtual address of the page tables. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +BlpSelfMapPml(IN PXTBL_PAGE_MAPPING PageMap, + IN ULONG_PTR SelfMapAddress) +{ + ULONGLONG PmlIndex; + + /* Check page map level */ + if(PageMap->PageMapLevel == 5) + { + /* Self-mapping for PML5 is not supported */ + BlDebugPrint(L"PML5 self-mapping not supported yet!\n"); + return STATUS_EFI_UNSUPPORTED; + } + else + { + /* Calculate PML index based on provided self map address */ + PmlIndex = (SelfMapAddress >> 39) & 0x1FF; + + /* Add self-mapping for PML4 */ + ((PHARDWARE_PTE)PageMap->PtePointer)[PmlIndex].PageFrameNumber = (UINT_PTR)PageMap->PtePointer / EFI_PAGE_SIZE; + ((PHARDWARE_PTE)PageMap->PtePointer)[PmlIndex].Valid = 1; + ((PHARDWARE_PTE)PageMap->PtePointer)[PmlIndex].Writable = 1; + } + + /* Return success */ + return STATUS_EFI_SUCCESS; +} diff --git a/xtldr/arch/i686/memory.c b/xtldr/arch/i686/memory.c index 2877e6d..ce7c6a0 100644 --- a/xtldr/arch/i686/memory.c +++ b/xtldr/arch/i686/memory.c @@ -21,7 +21,8 @@ */ XTCDECL EFI_STATUS -BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap) +BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, + IN ULONG_PTR SelfMapAddress) { PLIST_ENTRY ListEntry, ModulesList, ModulesListEntry; EFI_PHYSICAL_ADDRESS Address, DirectoryAddress; diff --git a/xtldr/includes/xtldr.h b/xtldr/includes/xtldr.h index cfca6da..215ce2b 100644 --- a/xtldr/includes/xtldr.h +++ b/xtldr/includes/xtldr.h @@ -28,7 +28,8 @@ BlAllocateMemoryPool(IN UINT_PTR Size, XTCDECL EFI_STATUS -BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap); +BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, + IN ULONG_PTR SelfMapAddress); XTCDECL VOID @@ -524,6 +525,11 @@ BlpReadConfigFile(IN CONST PWCHAR ConfigDirectory, IN CONST PWCHAR ConfigFile, OUT PCHAR *ConfigData); +XTCDECL +EFI_STATUS +BlpSelfMapPml(IN PXTBL_PAGE_MAPPING PageMap, + IN ULONG_PTR SelfMapAddress); + XTCDECL ULONGLONG BlpStringReadPadding(IN PUSHORT *Format); diff --git a/xtldr/modules/xtos_o/amd64/memory.c b/xtldr/modules/xtos_o/amd64/memory.c index 6b085a9..3d30786 100644 --- a/xtldr/modules/xtos_o/amd64/memory.c +++ b/xtldr/modules/xtos_o/amd64/memory.c @@ -35,7 +35,7 @@ XtEnablePaging(IN PXTBL_PAGE_MAPPING PageMap) EFI_STATUS Status; /* Build page map */ - Status = XtLdrProtocol->Memory.BuildPageMap(PageMap); + Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, 0xFFFFF6FB7DBED000); if(Status != STATUS_EFI_SUCCESS) { /* Failed to build page map */ diff --git a/xtldr/modules/xtos_o/i686/memory.c b/xtldr/modules/xtos_o/i686/memory.c index f8e4438..3e1e13c 100644 --- a/xtldr/modules/xtos_o/i686/memory.c +++ b/xtldr/modules/xtos_o/i686/memory.c @@ -55,7 +55,7 @@ XtEnablePaging(IN PXTBL_PAGE_MAPPING PageMap) } /* Build page map */ - Status = XtLdrProtocol->Memory.BuildPageMap(PageMap); + Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, 0); if(Status != STATUS_EFI_SUCCESS) { /* Failed to build page map */