Rollback bootloader memory management changes
This commit is contained in:
@@ -4,7 +4,6 @@
|
||||
* FILE: xtldr/memory.cc
|
||||
* DESCRIPTION: XT Boot Loader memory management
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
* Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <xtldr.hh>
|
||||
@@ -309,69 +308,17 @@ Memory::InitializePageMap(OUT PXTBL_PAGE_MAPPING PageMap,
|
||||
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.
|
||||
*
|
||||
* @param PageMap
|
||||
* Supplies a pointer to the page mapping structure.
|
||||
*
|
||||
* @param BaseAddress
|
||||
* Supplies a base address, where EFI memory will be mapped.
|
||||
* @param MemoryMapAddress
|
||||
* Supplies a virtual 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.
|
||||
*
|
||||
@@ -380,15 +327,27 @@ Memory::MapDescriptor(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
||||
IN ULONG_PTR BaseAddress)
|
||||
IN OUT PVOID *MemoryMapAddress,
|
||||
IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine)
|
||||
{
|
||||
ULONGLONG MaxAddress, VirtualAddress;
|
||||
PEFI_MEMORY_DESCRIPTOR Descriptor;
|
||||
LOADER_MEMORY_TYPE MemoryType;
|
||||
PEFI_MEMORY_MAP MemoryMap;
|
||||
SIZE_T DescriptorCount;
|
||||
ULONGLONG MaxAddress;
|
||||
EFI_STATUS Status;
|
||||
SIZE_T Index;
|
||||
|
||||
/* Set virtual address as specified in argument */
|
||||
VirtualAddress = (ULONGLONG)*MemoryMapAddress;
|
||||
|
||||
/* Check if custom memory type routine is specified */
|
||||
if(GetMemoryTypeRoutine == NULLPTR)
|
||||
{
|
||||
/* Use default memory type routine */
|
||||
GetMemoryTypeRoutine = GetLoaderMemoryType;
|
||||
}
|
||||
|
||||
/* Allocate and zero-fill buffer for EFI memory map */
|
||||
AllocatePool(sizeof(EFI_MEMORY_MAP), (PVOID*)&MemoryMap);
|
||||
RTL::Memory::ZeroMemory(MemoryMap, sizeof(EFI_MEMORY_MAP));
|
||||
@@ -434,17 +393,49 @@ Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
||||
/* Check if memory descriptor exceeds the lowest physical page */
|
||||
if(Descriptor->PhysicalStart + (Descriptor->NumberOfPages << EFI_PAGE_SHIFT) > MaxAddress)
|
||||
{
|
||||
/* Truncate memory descriptor to maximum supported address */
|
||||
/* Truncate memory descriptor to the lowest supported physical page */
|
||||
Descriptor->NumberOfPages = (((ULONGLONG)MaxAddress) - Descriptor->PhysicalStart) >> EFI_PAGE_SHIFT;
|
||||
}
|
||||
}
|
||||
|
||||
/* Map this descriptor and make sure it succeeded */
|
||||
Status = MapDescriptor(PageMap, Descriptor, BaseAddress);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Mapping failed */
|
||||
return Status;
|
||||
/* Skip EFI reserved memory */
|
||||
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 = GetMemoryTypeRoutine((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, VirtualAddress, 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)
|
||||
{
|
||||
/* Mapping failed */
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
/* Grab next descriptor */
|
||||
@@ -468,6 +459,7 @@ Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
||||
}
|
||||
|
||||
/* Store next valid virtual address and return success */
|
||||
*MemoryMapAddress = (PVOID)VirtualAddress;
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -657,3 +649,105 @@ Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts physical address to virtual address based on physical base and virtual base.
|
||||
*
|
||||
* @param PhysicalAddress
|
||||
* Specifies physical address that will be converted to virtual address.
|
||||
*
|
||||
* @param PhysicalBase
|
||||
* Supplies a physical base address.
|
||||
*
|
||||
* @param VirtualBase
|
||||
* Supplies a virtual base address.
|
||||
*
|
||||
* @return This routine returns a mapped virtual address.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
PVOID
|
||||
Memory::PhysicalAddressToVirtual(IN PVOID PhysicalAddress,
|
||||
IN PVOID PhysicalBase,
|
||||
IN PVOID VirtualBase)
|
||||
{
|
||||
/* Convert physical address to virtual address */
|
||||
return (PUCHAR)VirtualBase + ((PUCHAR)PhysicalAddress - (PUCHAR)PhysicalBase);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts whole linked list addressing from physical to virtual for future use after enabling paging.
|
||||
*
|
||||
* @param PageMap
|
||||
* Supplies a pointer to the page mapping structure.
|
||||
*
|
||||
* @param ListHead
|
||||
* Supplies a pointer to a structure that serves as the list header.
|
||||
*
|
||||
* @param PhysicalBase
|
||||
* Supplies a physical base address.
|
||||
*
|
||||
* @param VirtualBase
|
||||
* Supplies a virtual base address.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Memory::PhysicalListToVirtual(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
IN OUT PLIST_ENTRY ListHead,
|
||||
IN PVOID PhysicalBase,
|
||||
IN PVOID VirtualBase)
|
||||
{
|
||||
PLIST_ENTRY ListEntry, NextEntry;
|
||||
|
||||
/* Make sure list is properly initialized */
|
||||
if(ListHead->Flink == 0 || ListHead->Blink == 0)
|
||||
{
|
||||
/* List not initialized, return error code */
|
||||
return STATUS_EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* Iterate through all elements */
|
||||
ListEntry = ListHead->Flink;
|
||||
while(ListEntry != ListHead)
|
||||
{
|
||||
/* Save physical address of the next element */
|
||||
NextEntry = ListEntry->Flink;
|
||||
|
||||
/* Convert the address of this element to VirtualAddress */
|
||||
if(ListEntry->Blink == ListHead)
|
||||
{
|
||||
/* Find virtual address of list head */
|
||||
ListEntry->Blink = (PLIST_ENTRY)GetVirtualAddress(PageMap, ListEntry->Blink);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Convert list entry */
|
||||
ListEntry->Blink = (PLIST_ENTRY)PhysicalAddressToVirtual(ListEntry->Blink, (PVOID)PhysicalBase, VirtualBase);
|
||||
}
|
||||
if(ListEntry->Flink == ListHead)
|
||||
{
|
||||
/* Convert list head */
|
||||
ListEntry->Flink = ListHead->Flink->Blink;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Convert list entry */
|
||||
ListEntry->Flink = (PLIST_ENTRY)PhysicalAddressToVirtual(ListEntry->Flink, (PVOID)PhysicalBase, VirtualBase);
|
||||
}
|
||||
|
||||
/* Get to the next element*/
|
||||
ListEntry = NextEntry;
|
||||
}
|
||||
|
||||
/* Convert list head */
|
||||
ListHead->Blink = (PLIST_ENTRY)PhysicalAddressToVirtual(ListHead->Blink, (PVOID)PhysicalBase, VirtualBase);
|
||||
ListHead->Flink = (PLIST_ENTRY)PhysicalAddressToVirtual(ListHead->Flink, (PVOID)PhysicalBase, VirtualBase);
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user