Extract MapDescriptor logic and simplify memory mapping API
All checks were successful
Builds / ExectOS (i686, release) (push) Successful in 29s
Builds / ExectOS (amd64, release) (push) Successful in 32s
Builds / ExectOS (amd64, debug) (push) Successful in 41s
Builds / ExectOS (i686, debug) (push) Successful in 39s

This commit is contained in:
2026-01-12 22:46:04 +01:00
parent 34c33a3b53
commit 15edd98242
4 changed files with 73 additions and 60 deletions

View File

@@ -168,6 +168,7 @@ class Memory
STATIC XTCDECL EFI_STATUS FreePages(IN ULONGLONG NumberOfPages, STATIC XTCDECL EFI_STATUS FreePages(IN ULONGLONG NumberOfPages,
IN EFI_PHYSICAL_ADDRESS Memory); IN EFI_PHYSICAL_ADDRESS Memory);
STATIC XTCDECL EFI_STATUS FreePool(IN PVOID Memory); STATIC XTCDECL EFI_STATUS FreePool(IN PVOID Memory);
STATIC XTCDECL LOADER_MEMORY_TYPE GetLoaderMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType);
STATIC XTCDECL VOID GetMappingsCount(IN PXTBL_PAGE_MAPPING PageMap, STATIC XTCDECL VOID GetMappingsCount(IN PXTBL_PAGE_MAPPING PageMap,
OUT PULONG NumberOfMappings); OUT PULONG NumberOfMappings);
STATIC XTCDECL EFI_STATUS GetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap); STATIC XTCDECL EFI_STATUS GetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap);
@@ -177,8 +178,7 @@ class Memory
IN SHORT PageMapLevel, IN SHORT PageMapLevel,
IN PAGE_SIZE PageSize); IN PAGE_SIZE PageSize);
STATIC XTCDECL EFI_STATUS MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, STATIC XTCDECL EFI_STATUS MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
IN OUT PVOID *MemoryMapAddress, IN ULONG_PTR BaseAddress);
IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine);
STATIC XTCDECL EFI_STATUS MapPage(IN PXTBL_PAGE_MAPPING PageMap, STATIC XTCDECL EFI_STATUS MapPage(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONGLONG VirtualAddress, IN ULONGLONG VirtualAddress,
IN ULONGLONG PhysicalAddress, IN ULONGLONG PhysicalAddress,
@@ -188,20 +188,15 @@ class Memory
IN ULONGLONG PhysicalAddress, IN ULONGLONG PhysicalAddress,
IN ULONGLONG NumberOfPages, IN ULONGLONG NumberOfPages,
IN LOADER_MEMORY_TYPE MemoryType); IN LOADER_MEMORY_TYPE MemoryType);
STATIC XTCDECL PVOID PhysicalAddressToVirtual(IN PVOID PhysicalAddress,
IN PVOID PhysicalBase,
IN PVOID VirtualBase);
STATIC XTCDECL EFI_STATUS PhysicalListToVirtual(IN PXTBL_PAGE_MAPPING PageMap,
IN OUT PLIST_ENTRY ListHead,
IN PVOID PhysicalBase,
IN PVOID VirtualBase);
private: private:
STATIC XTCDECL LOADER_MEMORY_TYPE GetLoaderMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType);
STATIC XTCDECL EFI_STATUS GetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap, STATIC XTCDECL EFI_STATUS GetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
IN PVOID PageTable, IN PVOID PageTable,
IN SIZE_T Entry, IN SIZE_T Entry,
OUT PVOID *NextPageTable); OUT PVOID *NextPageTable);
STATIC XTCDECL EFI_STATUS MapDescriptor(IN OUT PXTBL_PAGE_MAPPING PageMap,
IN PEFI_MEMORY_DESCRIPTOR Descriptor,
IN ULONG_PTR BaseAddress);
STATIC XTCDECL EFI_STATUS SelfMapPml(IN PXTBL_PAGE_MAPPING PageMap, STATIC XTCDECL EFI_STATUS SelfMapPml(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR SelfMapAddress); IN ULONG_PTR SelfMapAddress);
}; };

View File

@@ -4,6 +4,7 @@
* FILE: xtldr/memory.cc * FILE: xtldr/memory.cc
* DESCRIPTION: XT Boot Loader memory management * DESCRIPTION: XT Boot Loader memory management
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
* Aiken Harris <harraiken91@gmail.com>
*/ */
#include <xtldr.hh> #include <xtldr.hh>
@@ -308,17 +309,69 @@ Memory::InitializePageMap(OUT PXTBL_PAGE_MAPPING PageMap,
PageMap->PageSize = PageSize; PageMap->PageSize = PageSize;
} }
/**
* Maps memory descriptor to the page mapping structure.
*
* @param PageMap
* Supplies a pointer to the page mapping structure.
*
* @param Descriptor
* Supplies a pointer to EFI memory descriptor, which will be mapped.
*
* @param BaseAddress
* Supplies a base address, where EFI memory will be mapped.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
Memory::MapDescriptor(IN OUT PXTBL_PAGE_MAPPING PageMap,
IN PEFI_MEMORY_DESCRIPTOR Descriptor,
IN ULONG_PTR BaseAddress)
{
LOADER_MEMORY_TYPE MemoryType;
/* Skip EFI reserved memory */
if(Descriptor->Type == EfiReservedMemoryType)
{
/* Skip EFI reserved memory */
return STATUS_EFI_SUCCESS;
}
/* Convert EFI memory type into XTLDR memory type */
MemoryType = Memory::GetLoaderMemoryType((EFI_MEMORY_TYPE)Descriptor->Type);
/* Do memory mappings depending on memory type */
if(MemoryType == LoaderFirmwareTemporary)
{
/* Map EFI firmware code */
return Memory::MapVirtualMemory(PageMap, Descriptor->PhysicalStart,
Descriptor->PhysicalStart, Descriptor->NumberOfPages, MemoryType);
}
else if(MemoryType != LoaderFree)
{
/* Add any non-free memory mappings based on provided base address */
return Memory::MapVirtualMemory(PageMap, (BaseAddress | Descriptor->PhysicalStart), Descriptor->PhysicalStart,
Descriptor->NumberOfPages, MemoryType);
}
else
{
/* Map all other memory as loader free */
return Memory::MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Descriptor->PhysicalStart,
Descriptor->NumberOfPages, LoaderFree);
}
}
/** /**
* Adds EFI memory mapping to the page mapping structure. * Adds EFI memory mapping to the page mapping structure.
* *
* @param PageMap * @param PageMap
* Supplies a pointer to the page mapping structure. * Supplies a pointer to the page mapping structure.
* *
* @param MemoryMapAddress * @param BaseAddress
* Supplies a virtual address, where EFI memory will be mapped. * Supplies a base address, where EFI memory will be mapped.
*
* @param GetMemoryTypeRoutine
* Supplies a pointer to the routine which will be used to match EFI memory type to the OS memory type.
* *
* @return This routine returns a status code. * @return This routine returns a status code.
* *
@@ -327,11 +380,9 @@ Memory::InitializePageMap(OUT PXTBL_PAGE_MAPPING PageMap,
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
IN OUT PVOID *MemoryMapAddress, IN ULONG_PTR BaseAddress)
IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine)
{ {
PEFI_MEMORY_DESCRIPTOR Descriptor; PEFI_MEMORY_DESCRIPTOR Descriptor;
LOADER_MEMORY_TYPE MemoryType;
PEFI_MEMORY_MAP MemoryMap; PEFI_MEMORY_MAP MemoryMap;
SIZE_T DescriptorCount; SIZE_T DescriptorCount;
ULONGLONG MaxAddress; ULONGLONG MaxAddress;
@@ -372,7 +423,7 @@ Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
/* Check page map level */ /* Check page map level */
if(PageMap->PageMapLevel == 2 || PageMap->PageMapLevel == 3) if(PageMap->PageMapLevel == 2 || PageMap->PageMapLevel == 3)
{ {
/* Check if physical address starts beyond 4GB */ /* Check if physical address starts beyond limit */
if(Descriptor->PhysicalStart > MaxAddress) if(Descriptor->PhysicalStart > MaxAddress)
{ {
/* Go to the next descriptor */ /* Go to the next descriptor */
@@ -383,50 +434,18 @@ Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
/* Check if memory descriptor exceeds the lowest physical page */ /* Check if memory descriptor exceeds the lowest physical page */
if(Descriptor->PhysicalStart + (Descriptor->NumberOfPages << EFI_PAGE_SHIFT) > MaxAddress) if(Descriptor->PhysicalStart + (Descriptor->NumberOfPages << EFI_PAGE_SHIFT) > MaxAddress)
{ {
/* Truncate memory descriptor to the 4GB */ /* Truncate memory descriptor to maximum supported address */
Descriptor->NumberOfPages = (((ULONGLONG)MaxAddress) - Descriptor->PhysicalStart) >> EFI_PAGE_SHIFT; Descriptor->NumberOfPages = (((ULONGLONG)MaxAddress) - Descriptor->PhysicalStart) >> EFI_PAGE_SHIFT;
} }
} }
{ /* Map this descriptor and make sure it succeeded */
/* Skip EFI reserved memory */ Status = MapDescriptor(PageMap, Descriptor, BaseAddress);
if(Descriptor->Type == EfiReservedMemoryType)
{
/* Go to the next descriptor */
Descriptor = (PEFI_MEMORY_DESCRIPTOR)((PUCHAR)Descriptor + MemoryMap->DescriptorSize);
continue;
}
/* Convert EFI memory type into XTLDR memory type */
MemoryType = GetLoaderMemoryType((EFI_MEMORY_TYPE)Descriptor->Type);
/* Do memory mappings depending on memory type */
if(MemoryType == LoaderFirmwareTemporary)
{
/* Map EFI firmware code */
Status = MapVirtualMemory(PageMap, Descriptor->PhysicalStart,
Descriptor->PhysicalStart, Descriptor->NumberOfPages, MemoryType);
}
else if(MemoryType != LoaderFree)
{
/* Add any non-free memory mapping */
Status = MapVirtualMemory(PageMap, KSEG0_BASE + Descriptor->PhysicalStart, Descriptor->PhysicalStart,
Descriptor->NumberOfPages, MemoryType);
}
else
{
/* Map all other memory as loader free */
Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Descriptor->PhysicalStart,
Descriptor->NumberOfPages, LoaderFree);
}
/* Make sure memory mapping succeeded */
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Mapping failed */ /* Mapping failed */
return Status; return Status;
} }
}
/* Grab next descriptor */ /* Grab next descriptor */
Descriptor = (PEFI_MEMORY_DESCRIPTOR)((PUCHAR)Descriptor + MemoryMap->DescriptorSize); Descriptor = (PEFI_MEMORY_DESCRIPTOR)((PUCHAR)Descriptor + MemoryMap->DescriptorSize);

View File

@@ -762,8 +762,7 @@ Xtos::RunBootSequence(IN PEFI_FILE_HANDLE BootDir,
/* Initialize virtual memory mappings */ /* Initialize virtual memory mappings */
XtLdrProtocol->Memory.InitializePageMap(&PageMap, DeterminePagingLevel(Parameters->Parameters), Size4K); XtLdrProtocol->Memory.InitializePageMap(&PageMap, DeterminePagingLevel(Parameters->Parameters), Size4K);
PVOID VirtualMemoryArea = (PVOID)KSEG0_BASE; Status = XtLdrProtocol->Memory.MapEfiMemory(&PageMap, KSEG0_BASE);
Status = XtLdrProtocol->Memory.MapEfiMemory(&PageMap, &VirtualMemoryArea, NULLPTR);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
return Status; return Status;

View File

@@ -100,7 +100,7 @@ typedef VOID (XTCDECL *PBL_LLIST_INITIALIZE_HEAD)(IN PLIST_ENTRY ListHead);
typedef VOID (XTCDECL *PBL_LLIST_INSERT_HEAD)(IN OUT PLIST_ENTRY ListHead, IN PLIST_ENTRY Entry); typedef VOID (XTCDECL *PBL_LLIST_INSERT_HEAD)(IN OUT PLIST_ENTRY ListHead, IN PLIST_ENTRY Entry);
typedef VOID (XTCDECL *PBL_LLIST_INSERT_TAIL)(IN OUT PLIST_ENTRY ListHead, IN PLIST_ENTRY Entry); typedef VOID (XTCDECL *PBL_LLIST_INSERT_TAIL)(IN OUT PLIST_ENTRY ListHead, IN PLIST_ENTRY Entry);
typedef VOID (XTCDECL *PBL_LLIST_REMOVE_ENTRY)(IN PLIST_ENTRY Entry); typedef VOID (XTCDECL *PBL_LLIST_REMOVE_ENTRY)(IN PLIST_ENTRY Entry);
typedef EFI_STATUS (XTCDECL *PBL_MAP_EFI_MEMORY)(IN OUT PXTBL_PAGE_MAPPING PageMap, IN OUT PVOID *MemoryMapAddress, IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine); typedef EFI_STATUS (XTCDECL *PBL_MAP_EFI_MEMORY)(IN OUT PXTBL_PAGE_MAPPING PageMap, IN ULONG_PTR BaseAddress);
typedef EFI_STATUS (XTCDECL *PBL_MAP_PAGE)(IN PXTBL_PAGE_MAPPING PageMap, IN ULONGLONG VirtualAddress, IN ULONGLONG PhysicalAddress, IN ULONGLONG NumberOfPages); typedef EFI_STATUS (XTCDECL *PBL_MAP_PAGE)(IN PXTBL_PAGE_MAPPING PageMap, IN ULONGLONG VirtualAddress, IN ULONGLONG PhysicalAddress, IN ULONGLONG NumberOfPages);
typedef EFI_STATUS (XTCDECL *PBL_MAP_VIRTUAL_MEMORY)(IN OUT PXTBL_PAGE_MAPPING PageMap, IN ULONGLONG VirtualAddress, IN ULONGLONG PhysicalAddress, IN ULONGLONG NumberOfPages, IN LOADER_MEMORY_TYPE MemoryType); typedef EFI_STATUS (XTCDECL *PBL_MAP_VIRTUAL_MEMORY)(IN OUT PXTBL_PAGE_MAPPING PageMap, IN ULONGLONG VirtualAddress, IN ULONGLONG PhysicalAddress, IN ULONGLONG NumberOfPages, IN LOADER_MEMORY_TYPE MemoryType);
typedef VOID (XTAPI *PBL_MOVE_MEMORY)(IN OUT PVOID Destination, IN PCVOID Source, IN SIZE_T Length); typedef VOID (XTAPI *PBL_MOVE_MEMORY)(IN OUT PVOID Destination, IN PCVOID Source, IN SIZE_T Length);