Use new paging implementation

This commit is contained in:
2024-01-17 22:24:55 +01:00
parent 89c18bbce6
commit 0e4575b278
4 changed files with 49 additions and 317 deletions

View File

@@ -30,10 +30,9 @@
*/
XTCDECL
EFI_STATUS
XtEnablePaging(IN PLIST_ENTRY MemoryMappings,
XtEnablePaging(IN PXTBL_PAGE_MAPPING PageMap,
IN PVOID VirtualAddress,
IN PEFI_LOADED_IMAGE_PROTOCOL ImageProtocol,
IN PVOID *PtePointer)
IN PEFI_LOADED_IMAGE_PROTOCOL ImageProtocol)
{
PLOADER_MEMORY_MAPPING Mapping;
EFI_PHYSICAL_ADDRESS Address;
@@ -50,8 +49,8 @@ XtEnablePaging(IN PLIST_ENTRY MemoryMappings,
}
/* Assign and zero-fill memory used by page mappings */
*PtePointer = (PVOID)(UINT_PTR)Address;
RtlZeroMemory(*PtePointer, EFI_PAGE_SIZE);
PageMap->PtePointer = (PVOID)(UINT_PTR)Address;
RtlZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE);
/* Get list of XTLDR modules */
ModulesList = XtLdrProtocol->Protocol.GetModulesList();
@@ -62,7 +61,7 @@ XtEnablePaging(IN PLIST_ENTRY MemoryMappings,
ModuleInfo = CONTAIN_RECORD(ModulesListEntry, XTBL_MODULE_INFO, Flink);
/* Map module code */
Status = XtAddVirtualMemoryMapping(MemoryMappings, ModuleInfo->ModuleBase, ModuleInfo->ModuleBase,
Status = XtLdrProtocol->Memory.MapVirtualMemory(PageMap, ModuleInfo->ModuleBase, ModuleInfo->ModuleBase,
EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary);
if(Status != STATUS_EFI_SUCCESS)
@@ -76,11 +75,11 @@ XtEnablePaging(IN PLIST_ENTRY MemoryMappings,
}
/* Map XTLDR code */
XtAddVirtualMemoryMapping(MemoryMappings, ImageProtocol->ImageBase, ImageProtocol->ImageBase,
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, ImageProtocol->ImageBase, ImageProtocol->ImageBase,
EFI_SIZE_TO_PAGES(ImageProtocol->ImageSize), LoaderFirmwareTemporary);
/* Add page mapping itself to memory mapping */
Status = XtAddVirtualMemoryMapping(MemoryMappings, NULL, *PtePointer, 1, LoaderMemoryData);
Status = XtLdrProtocol->Memory.MapVirtualMemory(PageMap, NULL, PageMap->PtePointer, 1, LoaderMemoryData);
if(Status != STATUS_EFI_SUCCESS)
{
/* Mapping PML4 failed */
@@ -89,8 +88,8 @@ XtEnablePaging(IN PLIST_ENTRY MemoryMappings,
/* Iterate through and map all the mappings*/
XtLdrProtocol->Debug.Print(L"Mapping and dumping EFI memory:\n");
ListEntry = MemoryMappings->Flink;
while(ListEntry != MemoryMappings)
ListEntry = PageMap->MemoryMap.Flink;
while(ListEntry != &PageMap->MemoryMap)
{
/* Take mapping from the list */
Mapping = CONTAIN_RECORD(ListEntry, LOADER_MEMORY_MAPPING, ListEntry);
@@ -103,8 +102,8 @@ XtEnablePaging(IN PLIST_ENTRY MemoryMappings,
Mapping->PhysicalAddress, Mapping->VirtualAddress, Mapping->NumberOfPages);
/* Map memory */
Status = XtMapVirtualMemory(MemoryMappings, (UINT_PTR)Mapping->VirtualAddress,
(UINT_PTR)Mapping->PhysicalAddress, Mapping->NumberOfPages, PtePointer);
Status = XtLdrProtocol->Memory.MapPage(PageMap, (UINT_PTR)Mapping->VirtualAddress,
(UINT_PTR)Mapping->PhysicalAddress, Mapping->NumberOfPages);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory mapping failed */
@@ -117,7 +116,7 @@ XtEnablePaging(IN PLIST_ENTRY MemoryMappings,
}
/* Map zero page as well */
XtMapVirtualMemory(MemoryMappings, 0, 0, 1, PtePointer);
XtLdrProtocol->Memory.MapPage(PageMap, 0, 0, 1);
/* Exit EFI Boot Services */
XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n");
@@ -130,178 +129,7 @@ XtEnablePaging(IN PLIST_ENTRY MemoryMappings,
}
/* Write PML4 to CR3 */
ArWriteControlRegister(3, (UINT_PTR)*PtePointer);
/* Return success */
return STATUS_EFI_SUCCESS;
}
/**
* This routine does the actual virtual memory mapping.
*
* @param MemoryMappings
* Supplies a pointer to linked list containing all memory mappings.
*
* @param VirtualAddress
* Supplies a virtual address of the mapping.
*
* @param PhysicalAddress
* Supplies a physical address of the mapping.
*
* @param NumberOfPages
* Supplies a number of the pages of the mapping.
*
* @param PaeExtension
* Specifies whether Physical Address Extension (PAE) is supported by the hardware. Not used on AMD64.
*
* @param PtePointer
* Supplies a pointer to an array of pointers to page table entries.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
XtMapVirtualMemory(IN PLIST_ENTRY MemoryMappings,
IN UINT_PTR VirtualAddress,
IN UINT_PTR PhysicalAddress,
IN UINT NumberOfPages,
IN OUT PVOID *PtePointer)
{
PHARDWARE_PTE PageDirectoryPointTable, PageDirectory, PageTable;
UINT Pml4Index, PdpIndex, PdIndex, PtIndex;
EFI_PHYSICAL_ADDRESS Address;
UINT_PTR PageFrameNumber;
EFI_STATUS Status;
UINT64 Pointer;
/* Set the PFN */
PageFrameNumber = PhysicalAddress >> EFI_PAGE_SHIFT;
/* Do the recursive mapping */
while(NumberOfPages > 0)
{
/* Calculate indices from a virtual address */
Pml4Index = (VirtualAddress >> 39) & 0x1FF;
PdpIndex = (VirtualAddress >> 30) & 0x1FF;
PdIndex = (VirtualAddress >> 21) & 0x1FF;
PtIndex = (VirtualAddress >> 12) & 0x1FF;
/* Validate Page Map Level 4 (PML4) */
if(!((PHARDWARE_PTE)(*PtePointer))[Pml4Index].Valid)
{
/* Allocate pages for the PDPT */
Status = XtLdrProtocol->Memory.AllocatePages(1, &Address);
if (Status != STATUS_EFI_SUCCESS) {
/* Memory allocation failure */
return Status;
}
/* Add new memory mapping */
Status = XtAddVirtualMemoryMapping(MemoryMappings, NULL, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData);
if(Status != STATUS_EFI_SUCCESS) {
/* Memory mapping failed */
return Status;
}
/* Fill allocated memory with zeros */
RtlZeroMemory((PVOID)(UINT_PTR)Address, EFI_PAGE_SIZE);
/* Set paging entry settings */
((PHARDWARE_PTE)(*PtePointer))[Pml4Index].PageFrameNumber = Address / EFI_PAGE_SIZE;
((PHARDWARE_PTE)(*PtePointer))[Pml4Index].Valid = 1;
((PHARDWARE_PTE)(*PtePointer))[Pml4Index].Write = 1;
PageDirectoryPointTable = (PHARDWARE_PTE)(UINT_PTR)Address;
}
else
{
/* Find Page Directory Point Table (PDPT) */
Pointer = ((PHARDWARE_PTE)(*PtePointer))[Pml4Index].PageFrameNumber;
Pointer <<= EFI_PAGE_SHIFT;
PageDirectoryPointTable = (PHARDWARE_PTE)(UINT_PTR)Pointer;
}
/* Validate Page Directory Point Table (PDPT)*/
if(!PageDirectoryPointTable[PdpIndex].Valid)
{
/* Allocate pages for the PD */
Status = XtLdrProtocol->Memory.AllocatePages(1, &Address);
if (Status != STATUS_EFI_SUCCESS) {
/* Memory allocation failure */
return Status;
}
/* Add new memory mapping */
Status = XtAddVirtualMemoryMapping(MemoryMappings, NULL, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData);
if (Status != STATUS_EFI_SUCCESS) {
/* Memory mapping failed */
return Status;
}
/* Fill allocated memory with zeros */
RtlZeroMemory((PVOID)(UINT_PTR)Address, EFI_PAGE_SIZE);
/* Set paging entry settings */
PageDirectoryPointTable[PdpIndex].PageFrameNumber = Address / EFI_PAGE_SIZE;
PageDirectoryPointTable[PdpIndex].Valid = 1;
PageDirectoryPointTable[PdpIndex].Write = 1;
PageDirectory = (PHARDWARE_PTE)(UINT_PTR)Address;
}
else
{
/* Find Page Directory (PD) */
Pointer = PageDirectoryPointTable[PdpIndex].PageFrameNumber;
Pointer <<= EFI_PAGE_SHIFT;
PageDirectory = (PHARDWARE_PTE)(UINT_PTR)Pointer;
}
/* Validate Page Directory (PD)*/
if(!PageDirectory[PdIndex].Valid)
{
/* Allocate pages for the PT */
Status = XtLdrProtocol->Memory.AllocatePages(1, &Address);
if (Status != STATUS_EFI_SUCCESS) {
/* Memory allocation failure */
return Status;
}
/* Add new memory mapping */
Status = XtAddVirtualMemoryMapping(MemoryMappings, NULL, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData);
if (Status != STATUS_EFI_SUCCESS) {
/* Memory mapping failed */
return Status;
}
/* Fill allocated memory with zeros */
RtlZeroMemory((PVOID)(UINT_PTR)Address, EFI_PAGE_SIZE);
/* Set paging entry settings */
PageDirectory[PdIndex].PageFrameNumber = Address / EFI_PAGE_SIZE;
PageDirectory[PdIndex].Valid = 1;
PageDirectory[PdIndex].Write = 1;
PageTable = (PHARDWARE_PTE)(UINT_PTR)Address;
}
else
{
/* Find Page Table (PT) */
Pointer = PageDirectory[PdIndex].PageFrameNumber;
Pointer <<= EFI_PAGE_SHIFT;
PageTable = (PHARDWARE_PTE)(UINT_PTR)Pointer;
}
/* Set paging entry settings */
PageTable[PtIndex].PageFrameNumber = PageFrameNumber;
PageTable[PtIndex].Valid = 1;
PageTable[PtIndex].Write = 1;
/* Take next virtual address and PFN */
VirtualAddress += EFI_PAGE_SIZE;
PageFrameNumber++;
/* Decrease number of pages left */
NumberOfPages--;
}
ArWriteControlRegister(3, (UINT_PTR)PageMap->PtePointer);
/* Return success */
return STATUS_EFI_SUCCESS;