Extract MapDescriptor logic and simplify memory mapping API
This commit is contained in:
@@ -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);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user