Several changes to EFI memory mapping
All checks were successful
ci/woodpecker/push/build Pipeline was successful

* Move EFI memory type conversion to separate routine
 * Never map VRAM
 * Map only pages not exceeding the lowest physical page
This commit is contained in:
Rafal Kupiec 2022-12-19 22:50:03 +01:00
parent 6871291c9a
commit 7bcdd8562d
Signed by: belliash
GPG Key ID: 4E829243E0CFE6B4
2 changed files with 81 additions and 66 deletions

View File

@ -57,6 +57,9 @@ BlConsoleInitialize();
VOID VOID
BlConsolePutChar(IN USHORT Character); BlConsolePutChar(IN USHORT Character);
LOADER_MEMORY_TYPE
BlConvertEfiMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType);
VOID VOID
BlCreateStack(IN PVOID *StackPtr, BlCreateStack(IN PVOID *StackPtr,
IN ULONG StackSize, IN ULONG StackSize,

View File

@ -178,6 +178,51 @@ BlAddVirtualMemoryMapping(IN PLIST_ENTRY MemoryMappings,
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
} }
/**
* Converts an EFI memory type into an XTOS memory type.
*
* @param EfiMemoryType
* Supplies the EFI memory type.
*
* @return Returns a conversion of the memory type.
*
* @since XT 1.0
*/
LOADER_MEMORY_TYPE
BlConvertEfiMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType)
{
LOADER_MEMORY_TYPE MemoryType;
/* Check EFI memory type and convert to XTOS memory type */
switch(EfiMemoryType)
{
case EfiACPIMemoryNVS:
case EfiACPIReclaimMemory:
case EfiPalCode:
case EfiReservedMemoryType:
MemoryType = LoaderSpecialMemory;
break;
case EfiRuntimeServicesCode:
case EfiRuntimeServicesData:
case EfiMemoryMappedIO:
case EfiMemoryMappedIOPortSpace:
MemoryType = LoaderFirmwarePermanent;
break;
case EfiLoaderCode:
MemoryType = LoaderFirmwareTemporary;
break;
case EfiUnusableMemory:
MemoryType = LoaderBad;
break;
default:
MemoryType = LoaderFree;
break;
}
/* Return XTOS memory type */
return MemoryType;
}
/** /**
* This routine allocates one or more 4KB pages. * This routine allocates one or more 4KB pages.
* *
@ -353,12 +398,10 @@ BlInitializeVirtualMemory(IN OUT PLIST_ENTRY MemoryMappings,
LOADER_MEMORY_TYPE MemoryType; LOADER_MEMORY_TYPE MemoryType;
PUCHAR VirtualAddress; PUCHAR VirtualAddress;
EFI_STATUS Status; EFI_STATUS Status;
BOOLEAN MapVRam;
SIZE_T Index; SIZE_T Index;
/* Set initial VA and assume VRAM will be mapped */ /* Set initial virtual address */
VirtualAddress = *MemoryMapAddress; VirtualAddress = *MemoryMapAddress;
MapVRam = TRUE;
/* Get memory map */ /* Get memory map */
Status = BlGetMemoryMap(&MemoryMap, &MapKey, &DescriptorSize, &DescriptorCount); Status = BlGetMemoryMap(&MemoryMap, &MapKey, &DescriptorSize, &DescriptorCount);
@ -370,77 +413,46 @@ BlInitializeVirtualMemory(IN OUT PLIST_ENTRY MemoryMappings,
/* Iterate through all descriptors from memory map */ /* Iterate through all descriptors from memory map */
for(Index = 0; Index < DescriptorCount; Index++) for(Index = 0; Index < DescriptorCount; Index++)
{ {
/* Check memory type */
switch(MemoryMap->Type)
{
case EfiACPIMemoryNVS:
case EfiACPIReclaimMemory:
case EfiPalCode:
case EfiReservedMemoryType:
MemoryType = LoaderSpecialMemory;
break;
case EfiLoaderCode:
MemoryType = LoaderFirmwareTemporary;
break;
case EfiUnusableMemory:
MemoryType = LoaderBad;
break;
default:
MemoryType = LoaderFree;
break;
}
/* Do initial memory mappings */ /* Make sure descriptor does not go beyond lowest physical page */
if(MemoryType == LoaderFirmwareTemporary) if((MemoryMap->PhysicalStart + (MemoryMap->NumberOfPages * EFI_PAGE_SIZE)) <= (UINT_PTR)-1)
{ {
/* Map EFI firmware code */ /* Convert EFI memory type into XTOS memory type */
Status = BlAddVirtualMemoryMapping(MemoryMappings, (PVOID)MemoryMap->PhysicalStart, MemoryType = BlConvertEfiMemoryType(MemoryMap->Type);
(PVOID)MemoryMap->PhysicalStart, MemoryMap->NumberOfPages, MemoryType);
}
else if(MemoryType != LoaderFree)
{
/* Add non-free memory mapping */
Status = BlAddVirtualMemoryMapping(MemoryMappings, VirtualAddress,
(PVOID)MemoryMap->PhysicalStart, MemoryMap->NumberOfPages, MemoryType);
/* Calculate next valid virtual address */ /* Do memory mappings depending on memory type */
VirtualAddress += MemoryMap->NumberOfPages * EFI_PAGE_SIZE; if(MemoryType == LoaderFirmwareTemporary)
/* Check if VRAM should be as well mapped */
if((MemoryMap->PhysicalStart + (MemoryMap->NumberOfPages << EFI_PAGE_SHIFT) > 0xA0000) &&
(MemoryMap->PhysicalStart <= 0xA0000))
{ {
/* No need to map VRAM */ /* Map EFI firmware code */
MapVRam = FALSE; Status = BlAddVirtualMemoryMapping(MemoryMappings, (PVOID)MemoryMap->PhysicalStart,
(PVOID)MemoryMap->PhysicalStart, MemoryMap->NumberOfPages, MemoryType);
} }
} else if(MemoryType != LoaderFree)
else {
{ /* Add any non-free memory mapping */
/* Map all other memory as loader free */ Status = BlAddVirtualMemoryMapping(MemoryMappings, VirtualAddress,
Status = BlAddVirtualMemoryMapping(MemoryMappings, NULL, (PVOID)MemoryMap->PhysicalStart, (PVOID)MemoryMap->PhysicalStart, MemoryMap->NumberOfPages, MemoryType);
MemoryMap->NumberOfPages, LoaderFree);
}
/* Make sure memory mapping succeeded */ /* Calculate next valid virtual address */
if(Status != STATUS_EFI_SUCCESS) VirtualAddress += MemoryMap->NumberOfPages * EFI_PAGE_SIZE;
{
/* Mapping failed */
return Status;
}
/* Grab next descriptor */ }
MemoryMap = (PEFI_MEMORY_DESCRIPTOR)((PUCHAR)MemoryMap + DescriptorSize); else
} {
/* Map all other memory as loader free */
Status = BlAddVirtualMemoryMapping(MemoryMappings, NULL, (PVOID)MemoryMap->PhysicalStart,
MemoryMap->NumberOfPages, LoaderFree);
}
/* Check if VRAM should mapped */ /* Make sure memory mapping succeeded */
if(MapVRam) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Add VRAM mapping */ /* Mapping failed */
Status = BlAddVirtualMemoryMapping(MemoryMappings, NULL, (PVOID)0xA0000, 0x60, LoaderFirmwarePermanent); return Status;
if(Status != STATUS_EFI_SUCCESS) }
{
/* VRAM mapping failed */ /* Grab next descriptor */
return Status; MemoryMap = (PEFI_MEMORY_DESCRIPTOR)((PUCHAR)MemoryMap + DescriptorSize);
} }
} }