Make a use of BlBuildPageMap()
All checks were successful
Builds / ExectOS (amd64) (push) Successful in 30s
Builds / ExectOS (i686) (push) Successful in 27s

This commit is contained in:
Rafal Kupiec 2024-01-22 15:20:22 +01:00
parent 0c3aee829a
commit af400920d0
Signed by: belliash
GPG Key ID: 4E829243E0CFE6B4
4 changed files with 10 additions and 243 deletions

View File

@ -30,94 +30,18 @@
*/
XTCDECL
EFI_STATUS
XtEnablePaging(IN PXTBL_PAGE_MAPPING PageMap,
IN PVOID VirtualAddress,
IN PEFI_LOADED_IMAGE_PROTOCOL ImageProtocol)
XtEnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
{
PLOADER_MEMORY_MAPPING Mapping;
EFI_PHYSICAL_ADDRESS Address;
PLIST_ENTRY ListEntry, ModulesList, ModulesListEntry;
PXTBL_MODULE_INFO ModuleInfo;
EFI_STATUS Status;
/* Allocate pages for PML4 */
Status = XtLdrProtocol->Memory.AllocatePages(1, &Address);
/* Build page map */
Status = XtLdrProtocol->Memory.BuildPageMap(PageMap);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure */
/* Failed to build page map */
return Status;
}
/* Assign and zero-fill memory used by page mappings */
PageMap->PtePointer = (PVOID)(UINT_PTR)Address;
RtlZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE);
/* Get list of XTLDR modules */
ModulesList = XtLdrProtocol->Protocol.GetModulesList();
ModulesListEntry = ModulesList->Flink;
while(ModulesListEntry != ModulesList)
{
/* Get module info */
ModuleInfo = CONTAIN_RECORD(ModulesListEntry, XTBL_MODULE_INFO, Flink);
/* Map module code */
Status = XtLdrProtocol->Memory.MapVirtualMemory(PageMap, ModuleInfo->ModuleBase, ModuleInfo->ModuleBase,
EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary);
if(Status != STATUS_EFI_SUCCESS)
{
/* Mapping module code failed */
return Status;
}
/* Get next module */
ModulesListEntry = ModulesListEntry->Flink;
}
/* Map XTLDR code */
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, ImageProtocol->ImageBase, ImageProtocol->ImageBase,
EFI_SIZE_TO_PAGES(ImageProtocol->ImageSize), LoaderFirmwareTemporary);
/* Add page mapping itself to memory mapping */
Status = XtLdrProtocol->Memory.MapVirtualMemory(PageMap, NULL, PageMap->PtePointer, 1, LoaderMemoryData);
if(Status != STATUS_EFI_SUCCESS)
{
/* Mapping PML4 failed */
return Status;
}
/* Iterate through and map all the mappings*/
XtLdrProtocol->Debug.Print(L"Mapping and dumping EFI memory:\n");
ListEntry = PageMap->MemoryMap.Flink;
while(ListEntry != &PageMap->MemoryMap)
{
/* Take mapping from the list */
Mapping = CONTAIN_RECORD(ListEntry, LOADER_MEMORY_MAPPING, ListEntry);
/* Check if virtual address is set */
if(Mapping->VirtualAddress)
{
/* Dump memory mapping */
XtLdrProtocol->Debug.Print(L" Type=%02lu, PhysicalBase=0x%016lx, VirtualBase=0x%016lx, Pages=%lu\n", Mapping->MemoryType,
Mapping->PhysicalAddress, Mapping->VirtualAddress, Mapping->NumberOfPages);
/* Map memory */
Status = XtLdrProtocol->Memory.MapPage(PageMap, (UINT_PTR)Mapping->VirtualAddress,
(UINT_PTR)Mapping->PhysicalAddress, Mapping->NumberOfPages);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory mapping failed */
return Status;
}
}
/* Take next element */
ListEntry = ListEntry->Flink;
}
/* Map zero page as well */
XtLdrProtocol->Memory.MapPage(PageMap, 0, 0, 1);
/* Exit EFI Boot Services */
XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n");
Status = XtLdrProtocol->Util.ExitBootServices();

View File

@ -30,20 +30,10 @@
*/
XTCDECL
EFI_STATUS
XtEnablePaging(IN PXTBL_PAGE_MAPPING PageMap,
IN PVOID VirtualAddress,
IN PEFI_LOADED_IMAGE_PROTOCOL ImageProtocol)
XtEnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
{
UINT_PTR PhysicalAddress, DescriptorCount;
EFI_PHYSICAL_ADDRESS Address, PDPTAddress = 0;
PCPUID_REGISTERS CpuRegisters = NULL;
PEFI_MEMORY_DESCRIPTOR Descriptor;
PLOADER_MEMORY_MAPPING Mapping;
PEFI_MEMORY_MAP MemoryMap;
PLIST_ENTRY ListEntry, ModulesList, ModulesListEntry;
PXTBL_MODULE_INFO ModuleInfo;
EFI_STATUS Status;
UINT Index;
/* Prepare CPUID registers */
CpuRegisters->Leaf = CPUID_GET_CPU_FEATURES;
@ -64,159 +54,14 @@ XtEnablePaging(IN PXTBL_PAGE_MAPPING PageMap,
return STATUS_EFI_UNSUPPORTED;
}
/* Allocate and zero-fill buffer for EFI memory map */
XtLdrProtocol->Memory.AllocatePool(sizeof(EFI_MEMORY_MAP), (PVOID*)&MemoryMap);
RtlZeroMemory(MemoryMap, sizeof(EFI_MEMORY_MAP));
/* Get EFI memory map */
Status = XtLdrProtocol->Memory.GetMemoryMap(MemoryMap);
/* Build page map */
Status = XtLdrProtocol->Memory.BuildPageMap(PageMap);
if(Status != STATUS_EFI_SUCCESS)
{
/* Unable to get memory map */
/* Failed to build page map */
return Status;
}
/* Calculate descriptors count and get first one */
Descriptor = MemoryMap->Map;
DescriptorCount = MemoryMap->MapSize / MemoryMap->DescriptorSize;
/* Calculate physical address based on KSEG0 base */
PhysicalAddress = (UINT_PTR)VirtualAddress - KSEG0_BASE;
/* Iterate over all descriptors from memory map to find satisfying address for PDPT */
for(Index = 0; Index < DescriptorCount; Index++)
{
/* Check descriptor if it can be used to store PDPT */
if((Descriptor->PhysicalStart + ((Descriptor->NumberOfPages - 1) * EFI_PAGE_SIZE) >= PhysicalAddress) &&
(Descriptor->Type == EfiConventionalMemory))
{
/* Use highest address possible */
if(PhysicalAddress >= Descriptor->PhysicalStart)
{
/* Use physical address */
PDPTAddress = PhysicalAddress;
}
else
{
/* Use descriptor physical start as PDPT address */
PDPTAddress = Descriptor->PhysicalStart;
}
/* Allocate pages for the PDPT address */
Status = XtLdrProtocol->Memory.AllocatePages(1, &PDPTAddress);
if(Status != STATUS_EFI_SUCCESS) {
return Status;
}
break;
}
/* Get next descriptor */
Descriptor = (EFI_MEMORY_DESCRIPTOR*)((UINT8*)Descriptor + MemoryMap->DescriptorSize);
}
/* Make sure PDPT address found */
if(PDPTAddress == 0)
{
/* No suitable area for PDPT found in EFI memory map */
return STATUS_EFI_NOT_FOUND;
}
/* Set virtual address based on new PDPT address mapped to KSEG0 base */
VirtualAddress = (PVOID)(UINT_PTR)(PDPTAddress + EFI_PAGE_SIZE + KSEG0_BASE);
/* Set base page frame number */
Address = 0x100000;
/* Allocate pages for the PFN */
Status = XtLdrProtocol->Memory.AllocatePages(4, &Address);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure */
return Status;
}
/* Set and zero memory used by page mappings and CR3 */
PageMap->PtePointer = (PVOID)(UINT_PTR)PDPTAddress;
RtlZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE);
RtlZeroMemory((PVOID)Address, EFI_PAGE_SIZE * 4);
/* Set the page directory into the PDPT and mark it present */
for(Index = 0; Index < 4; Index++)
{
/* Set paging entry settings */
((PHARDWARE_PTE)PageMap->PtePointer)[Index].PageFrameNumber = Address / EFI_PAGE_SIZE;
((PHARDWARE_PTE)PageMap->PtePointer)[Index].Valid = 1;
/* Next valid PFN address */
Address += EFI_PAGE_SIZE;
}
/* Get list of XTLDR modules */
ModulesList = XtLdrProtocol->Protocol.GetModulesList();
ModulesListEntry = ModulesList->Flink;
while(ModulesListEntry != ModulesList)
{
/* Get module info */
ModuleInfo = CONTAIN_RECORD(ModulesListEntry, XTBL_MODULE_INFO, Flink);
/* Map module code */
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, ModuleInfo->ModuleBase, ModuleInfo->ModuleBase,
EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary);
if(Status != STATUS_EFI_SUCCESS)
{
/* Mapping module code failed */
return Status;
}
/* Get next module */
ModulesListEntry = ModulesListEntry->Flink;
}
/* Map XTLDR code */
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, ImageProtocol->ImageBase, ImageProtocol->ImageBase,
EFI_SIZE_TO_PAGES(ImageProtocol->ImageSize), LoaderFirmwareTemporary);
/* Add page mapping itself to memory mapping */
Status = XtLdrProtocol->Memory.MapVirtualMemory(PageMap, NULL, PageMap->PtePointer, 1, LoaderMemoryData);
if(Status != STATUS_EFI_SUCCESS)
{
/* Mapping PD failed */
return Status;
}
/* Iterate through and map all the mappings */
XtLdrProtocol->Debug.Print(L"Mapping and dumping EFI memory:\n");
ListEntry = PageMap->MemoryMap.Flink;
while(ListEntry != &PageMap->MemoryMap)
{
/* Take mapping from the list */
Mapping = CONTAIN_RECORD(ListEntry, LOADER_MEMORY_MAPPING, ListEntry);
/* Check if virtual address is set */
if(Mapping->VirtualAddress)
{
/* Dump memory mapping */
XtLdrProtocol->Debug.Print(L" Type=%02lu, PhysicalBase=0x%08lx, VirtualBase=0x%08lx, Pages=%lu\n", Mapping->MemoryType,
Mapping->PhysicalAddress, Mapping->VirtualAddress, Mapping->NumberOfPages);
/* Map memory */
Status = XtLdrProtocol->Memory.MapPage(PageMap, (UINT_PTR)Mapping->VirtualAddress,
(UINT_PTR)Mapping->PhysicalAddress, Mapping->NumberOfPages);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory mapping failed */
return Status;
}
}
/* Take next element */
ListEntry = ListEntry->Flink;
}
/* Map zero page as well */
XtLdrProtocol->Memory.MapPage(PageMap, 0, 0, 1);
/* Exit EFI Boot Services */
XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n");
Status = XtLdrProtocol->Util.ExitBootServices();

View File

@ -51,9 +51,7 @@ XtConvertEfiMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType);
XTCDECL
EFI_STATUS
XtEnablePaging(IN PXTBL_PAGE_MAPPING PageMap,
IN PVOID VirtualAddress,
IN PEFI_LOADED_IMAGE_PROTOCOL ImageProtocol);
XtEnablePaging(IN PXTBL_PAGE_MAPPING PageMap);
XTCDECL
EFI_STATUS

View File

@ -247,7 +247,7 @@ XtpBootSequence(IN PEFI_FILE_HANDLE BootDir,
/* Enable paging */
XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID*)&ImageProtocol, &LoadedImageGuid);
Status = XtEnablePaging(&PageMap, VirtualAddress, ImageProtocol);
Status = XtEnablePaging(&PageMap);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to enable paging */