Compare commits
4 Commits
memmgr
...
xtldr_pml_
| Author | SHA1 | Date | |
|---|---|---|---|
|
368c8ee5b2
|
|||
|
c71d58b737
|
|||
|
b692fe4cef
|
|||
|
21b3b269a7
|
@@ -28,13 +28,12 @@ EFI_STATUS
|
||||
Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
IN ULONG_PTR SelfMapAddress)
|
||||
{
|
||||
PLIST_ENTRY ListEntry, ModulesList, ModulesListEntry;
|
||||
PXTBL_MEMORY_MAPPING Mapping;
|
||||
PLIST_ENTRY ModulesList, ModulesListEntry;
|
||||
PXTBL_MODULE_INFO ModuleInfo;
|
||||
EFI_PHYSICAL_ADDRESS Address;
|
||||
PVOID LoaderBase;
|
||||
ULONGLONG LoaderSize;
|
||||
EFI_STATUS Status;
|
||||
PVOID LoaderBase;
|
||||
|
||||
/* Allocate pages for the Page Map */
|
||||
Status = AllocatePages(AllocateAnyPages, 1, &Address);
|
||||
@@ -117,6 +116,28 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
return STATUS_EFI_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates through the memory map and physically maps all virtual addresses to page tables.
|
||||
*
|
||||
* @param PageMap
|
||||
* Supplies a pointer to the page mapping structure.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Memory::CommitPageMap(IN PXTBL_PAGE_MAPPING PageMap)
|
||||
{
|
||||
PXTBL_MEMORY_MAPPING Mapping;
|
||||
PLIST_ENTRY ListEntry;
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Iterate through and map all the mappings*/
|
||||
Debug::Print(L"Mapping and dumping EFI memory:\n");
|
||||
ListEntry = PageMap->MemoryMap.Flink;
|
||||
|
||||
@@ -25,13 +25,12 @@ EFI_STATUS
|
||||
Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
IN ULONG_PTR SelfMapAddress)
|
||||
{
|
||||
PLIST_ENTRY ListEntry, ModulesList, ModulesListEntry;
|
||||
EFI_PHYSICAL_ADDRESS Address, DirectoryAddress;
|
||||
PLIST_ENTRY ModulesList, ModulesListEntry;
|
||||
PXTBL_MODULE_INFO ModuleInfo;
|
||||
PXTBL_MEMORY_MAPPING Mapping;
|
||||
PVOID LoaderBase;
|
||||
ULONGLONG LoaderSize;
|
||||
EFI_STATUS Status;
|
||||
PVOID LoaderBase;
|
||||
ULONG Index;
|
||||
|
||||
/* Check the page map level to determine which paging structure to create */
|
||||
@@ -45,6 +44,14 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Add new memory mapping for the page map itself */
|
||||
Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory mapping failure */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Assign the allocated page to the page map and zero it out */
|
||||
PageMap->PtePointer = (PVOID)(UINT_PTR)Address;
|
||||
RTL::Memory::ZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE);
|
||||
@@ -57,6 +64,14 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Add new memory mapping for the Page Directories (PDs) */
|
||||
Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, DirectoryAddress, 4, LoaderMemoryData);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory mapping failure */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Zero-fill the allocated memory for the Page Directories */
|
||||
RTL::Memory::ZeroMemory((PVOID)DirectoryAddress, EFI_PAGE_SIZE * 4);
|
||||
|
||||
@@ -79,6 +94,14 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Add new memory mapping for the page map itself */
|
||||
Status = MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory mapping failure */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Assign the allocated page to the page map and zero it out */
|
||||
PageMap->PtePointer = (PVOID)(UINT_PTR)Address;
|
||||
RTL::Memory::ZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE);
|
||||
@@ -144,6 +167,28 @@ Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
return STATUS_EFI_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates through the memory map and physically maps all virtual addresses to page tables.
|
||||
*
|
||||
* @param PageMap
|
||||
* Supplies a pointer to the page mapping structure.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Memory::CommitPageMap(IN PXTBL_PAGE_MAPPING PageMap)
|
||||
{
|
||||
PXTBL_MEMORY_MAPPING Mapping;
|
||||
PLIST_ENTRY ListEntry;
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Iterate through and map all the mappings*/
|
||||
Debug::Print(L"Mapping and dumping EFI memory:\n");
|
||||
ListEntry = PageMap->MemoryMap.Flink;
|
||||
|
||||
@@ -165,6 +165,7 @@ class Memory
|
||||
OUT PVOID *Memory);
|
||||
STATIC XTCDECL EFI_STATUS BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
IN ULONG_PTR SelfMapAddress);
|
||||
STATIC XTCDECL EFI_STATUS CommitPageMap(IN PXTBL_PAGE_MAPPING PageMap);
|
||||
STATIC XTCDECL EFI_STATUS FreePages(IN ULONGLONG NumberOfPages,
|
||||
IN EFI_PHYSICAL_ADDRESS Memory);
|
||||
STATIC XTCDECL EFI_STATUS FreePool(IN PVOID Memory);
|
||||
|
||||
@@ -10,6 +10,34 @@
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Xtos::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Build page map */
|
||||
Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, (PageMap->PageMapLevel > 4) ? MM_P5E_LA57_BASE : MM_PXE_BASE);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to build page map */
|
||||
XtLdrProtocol->Debug.Print(L"Failed to build page map (Status code: %zX)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Map memory for hardware layer */
|
||||
Status = MapHardwareMemoryPool(PageMap);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to map memory for hardware layer */
|
||||
XtLdrProtocol->Debug.Print(L"Failed to map memory for hardware leyer (Status code: %zX)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the appropriate EFI memory mapping strategy for the AMD64 architecture.
|
||||
*
|
||||
@@ -91,24 +119,6 @@ Xtos::EnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
|
||||
ULONG_PTR TrampolineSize;
|
||||
PVOID TrampolineCode;
|
||||
|
||||
/* Build page map */
|
||||
Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, (PageMap->PageMapLevel > 4) ? MM_P5E_LA57_BASE : MM_PXE_BASE);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to build page map */
|
||||
XtLdrProtocol->Debug.Print(L"Failed to build page map (Status code: %zX)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Map memory for hardware layer */
|
||||
Status = MapHardwareMemoryPool(PageMap);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to map memory for hardware layer */
|
||||
XtLdrProtocol->Debug.Print(L"Failed to map memory for hardware leyer (Status code: %zX)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Check the configured page map level to set the LA57 state accordingly */
|
||||
if(PageMap->PageMapLevel == 5)
|
||||
{
|
||||
@@ -188,6 +198,7 @@ Xtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
|
||||
PHARDWARE_PTE P5eBase, PdeBase, PpeBase, PxeBase;
|
||||
EFI_PHYSICAL_ADDRESS Address;
|
||||
EFI_STATUS Status;
|
||||
ULONG Index;
|
||||
|
||||
if(PageMap->PageMapLevel == 5)
|
||||
{
|
||||
@@ -205,6 +216,9 @@ Xtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Map hardware memory */
|
||||
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
|
||||
|
||||
/* Zero fill memory used by P5E */
|
||||
XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
|
||||
|
||||
@@ -239,6 +253,9 @@ Xtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Map hardware memory */
|
||||
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
|
||||
|
||||
/* Zero fill memory used by PXE */
|
||||
XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
|
||||
|
||||
@@ -267,6 +284,9 @@ Xtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Map hardware memory */
|
||||
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
|
||||
|
||||
/* Zero fill memory used by PPE */
|
||||
XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
|
||||
|
||||
@@ -285,7 +305,7 @@ Xtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
|
||||
}
|
||||
|
||||
/* Loop through 2 PDE entries */
|
||||
for(UINT Index = 0 ; Index < 2 ; Index++)
|
||||
for(Index = 0 ; Index < 2 ; Index++)
|
||||
{
|
||||
/* Check if PDE entry already exists */
|
||||
if(!PdeBase[((MM_HARDWARE_VA_START >> MM_PDI_SHIFT) & 0x1FF) + Index].Valid)
|
||||
@@ -298,6 +318,9 @@ Xtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Map hardware memory */
|
||||
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
|
||||
|
||||
/* Zero fill memory used by PDE */
|
||||
XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
|
||||
|
||||
|
||||
@@ -9,6 +9,47 @@
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Xtos::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap)
|
||||
{
|
||||
ULONG_PTR SelfMapAddress;
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Initialize self map address */
|
||||
if(PageMap->PageMapLevel == 3)
|
||||
{
|
||||
/* For PML3 (PAE) use PTE base address */
|
||||
SelfMapAddress = MM_PTE_BASE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* For PML2 (PAE disabled) use legacy PDE base address */
|
||||
SelfMapAddress = MM_PDE_LEGACY_BASE;
|
||||
}
|
||||
|
||||
/* Build page map */
|
||||
Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, SelfMapAddress);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to build page map */
|
||||
XtLdrProtocol->Debug.Print(L"Failed to build page map (Status code: %zX)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Map memory for hardware layer */
|
||||
Status = MapHardwareMemoryPool(PageMap);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to map memory for hardware layer */
|
||||
XtLdrProtocol->Debug.Print(L"Failed to map memory for hardware layer (Status code: %zX)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the appropriate EFI memory mapping strategy for the i686 architecture.
|
||||
*
|
||||
@@ -74,37 +115,6 @@ EFI_STATUS
|
||||
Xtos::EnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
ULONG_PTR SelfMapAddress;
|
||||
|
||||
/* Initialize self map address */
|
||||
if(PageMap->PageMapLevel == 3)
|
||||
{
|
||||
/* For PML3 (PAE) use PTE base address */
|
||||
SelfMapAddress = MM_PTE_BASE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* For PML2 (PAE disabled) use legacy PDE base address */
|
||||
SelfMapAddress = MM_PDE_LEGACY_BASE;
|
||||
}
|
||||
|
||||
/* Build page map */
|
||||
Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, SelfMapAddress);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to build page map */
|
||||
XtLdrProtocol->Debug.Print(L"Failed to build page map (Status code: %zX)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Map memory for hardware layer */
|
||||
Status = MapHardwareMemoryPool(PageMap);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to map memory for hardware layer */
|
||||
XtLdrProtocol->Debug.Print(L"Failed to map memory for hardware layer (Status code: %zX)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Exit EFI Boot Services */
|
||||
XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n");
|
||||
@@ -173,6 +183,9 @@ Xtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
|
||||
/* Zero fill allocated memory */
|
||||
XtLdrProtocol->Memory.ZeroMemory((PVOID)Address, EFI_PAGE_SIZE);
|
||||
|
||||
/* Map hardware memory */
|
||||
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)NULLPTR, Address, 1, LoaderMemoryData);
|
||||
|
||||
/* Check if PAE is enabled (3-level paging) */
|
||||
if(PageMap->PageMapLevel == 3)
|
||||
{
|
||||
|
||||
@@ -38,6 +38,7 @@ class Xtos
|
||||
IN PVOID PhysicalAddress,
|
||||
IN UINT NumberOfPages,
|
||||
IN LOADER_MEMORY_TYPE MemoryType);
|
||||
STATIC XTCDECL EFI_STATUS BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap);
|
||||
STATIC XTCDECL LOADER_MEMORY_TYPE ConvertEfiMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType);
|
||||
STATIC XTCDECL BOOLEAN DetermineMappingStrategy();
|
||||
STATIC XTCDECL ULONG DeterminePagingLevel(IN CONST PWCHAR Parameters);
|
||||
@@ -47,10 +48,13 @@ class Xtos
|
||||
IN PULONG_PTR FrameBufferSize,
|
||||
IN PXTBL_FRAMEBUFFER_MODE_INFORMATION FrameBufferModeInfo);
|
||||
STATIC XTCDECL EFI_STATUS GetMemoryDescriptorList(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
IN PVOID *VirtualAddress,
|
||||
IN EFI_PHYSICAL_ADDRESS PhysicalBase,
|
||||
IN PVOID VirtualBase,
|
||||
OUT PLIST_ENTRY MemoryDescriptorList);
|
||||
STATIC XTCDECL EFI_STATUS GetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
IN PVOID *VirtualAddress,
|
||||
IN EFI_PHYSICAL_ADDRESS PhysicalBase,
|
||||
IN PVOID VirtualBase,
|
||||
IN PVOID FrameBufferVirtualBase,
|
||||
OUT PLIST_ENTRY SystemResourcesList);
|
||||
STATIC XTCDECL EFI_STATUS GetVirtualAddress(IN PLIST_ENTRY MemoryMappings,
|
||||
IN PVOID PhysicalAddress,
|
||||
|
||||
@@ -191,38 +191,16 @@ Xtos::GetDisplayInformation(OUT PSYSTEM_RESOURCE_FRAMEBUFFER FrameBufferResource
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Xtos::GetMemoryDescriptorList(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
IN PVOID *VirtualAddress,
|
||||
IN EFI_PHYSICAL_ADDRESS PhysicalBase,
|
||||
IN PVOID VirtualBase,
|
||||
OUT PLIST_ENTRY MemoryDescriptorList)
|
||||
{
|
||||
PLOADER_MEMORY_DESCRIPTOR Descriptor;
|
||||
PXTBL_MEMORY_MAPPING MemoryMapping;
|
||||
EFI_PHYSICAL_ADDRESS Address;
|
||||
PLIST_ENTRY ListEntry;
|
||||
EFI_STATUS Status;
|
||||
ULONGLONG Pages;
|
||||
|
||||
/* Calculate the number of pages required to store the memory descriptor array */
|
||||
Pages = (ULONGLONG)EFI_SIZE_TO_PAGES((PageMap->MapSize + 1) * sizeof(LOADER_MEMORY_DESCRIPTOR));
|
||||
|
||||
/* Allocate physical pages to hold the memory descriptor list */
|
||||
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, Pages, &Address);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Page allocation failed, return the status code */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Create a virtual memory mapping for the allocated descriptor buffer */
|
||||
Status = XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)*VirtualAddress, Address, Pages, LoaderMemoryData);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Release the allocated pages as the virtual mapping failed and return status code */
|
||||
XtLdrProtocol->Memory.FreePages(Address, Pages);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Initialize the descriptor pointer to the start of the allocated physical buffer */
|
||||
Descriptor = (PLOADER_MEMORY_DESCRIPTOR)Address;
|
||||
Descriptor = (PLOADER_MEMORY_DESCRIPTOR)PhysicalBase;
|
||||
|
||||
/* Get the first entry from the internal boot loader memory map */
|
||||
ListEntry = PageMap->MemoryMap.Flink;
|
||||
@@ -247,17 +225,18 @@ Xtos::GetMemoryDescriptorList(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
}
|
||||
|
||||
/* Convert all physical link pointers in the list to their corresponding virtual addresses */
|
||||
XtLdrProtocol->Memory.PhysicalListToVirtual(PageMap, MemoryDescriptorList, (PVOID)Address, *VirtualAddress);
|
||||
XtLdrProtocol->Memory.PhysicalListToVirtual(PageMap, MemoryDescriptorList, (PVOID)PhysicalBase, VirtualBase);
|
||||
|
||||
/* Advance the virtual address pointer to the next available free region and return success */
|
||||
*VirtualAddress = (PUINT8)*VirtualAddress + (Pages * EFI_PAGE_SIZE);
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Xtos::GetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
IN PVOID *VirtualAddress,
|
||||
IN EFI_PHYSICAL_ADDRESS PhysicalBase,
|
||||
IN PVOID VirtualBase,
|
||||
IN PVOID FrameBufferVirtualBase,
|
||||
OUT PLIST_ENTRY SystemResourcesList)
|
||||
{
|
||||
XTSTATUS Status;
|
||||
@@ -268,39 +247,18 @@ Xtos::GetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
PXTBL_FRAMEBUFFER_PROTOCOL FrameBufProtocol;
|
||||
XTBL_FRAMEBUFFER_MODE_INFORMATION FbModeInfo;
|
||||
EFI_PHYSICAL_ADDRESS FbAddress;
|
||||
EFI_PHYSICAL_ADDRESS OriginalPhysicalBase;
|
||||
ULONG_PTR FbSize;
|
||||
UINT FrameBufferPages;
|
||||
PSYSTEM_RESOURCE_FRAMEBUFFER FrameBufferResource;
|
||||
PSYSTEM_RESOURCE_ACPI AcpiResource;
|
||||
ULONGLONG Pages;
|
||||
EFI_PHYSICAL_ADDRESS Address;
|
||||
PVOID PhysicalBase, VirtualBase;
|
||||
|
||||
Pages = (ULONGLONG)EFI_SIZE_TO_PAGES(sizeof(SYSTEM_RESOURCE_ACPI) + sizeof(SYSTEM_RESOURCE_FRAMEBUFFER));
|
||||
|
||||
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, Pages, &Address);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
Status = XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)*VirtualAddress, Address, Pages, LoaderFirmwarePermanent);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
XtLdrProtocol->Memory.FreePages(Address, Pages);
|
||||
return Status;
|
||||
}
|
||||
|
||||
PhysicalBase = (PVOID)Address;
|
||||
VirtualBase = *VirtualAddress;
|
||||
|
||||
/* Calculate next valid virtual address */
|
||||
*VirtualAddress = (PUINT8)*VirtualAddress + (Pages * EFI_PAGE_SIZE);
|
||||
|
||||
AcpiResource = (PSYSTEM_RESOURCE_ACPI)Address;
|
||||
/* Save original physical base */
|
||||
OriginalPhysicalBase = PhysicalBase;
|
||||
|
||||
AcpiResource = (PSYSTEM_RESOURCE_ACPI)PhysicalBase;
|
||||
XtLdrProtocol->Memory.ZeroMemory(AcpiResource, sizeof(SYSTEM_RESOURCE_ACPI));
|
||||
|
||||
/* Load FrameBuffer protocol */
|
||||
/* Load ACPI protocol */
|
||||
Status = XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID*)&AcpiProtocol, &AcpiGuid);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
@@ -319,13 +277,11 @@ Xtos::GetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
|
||||
XtLdrProtocol->LinkedList.InsertTail(SystemResourcesList, &AcpiResource->Header.ListEntry);
|
||||
|
||||
/* Close FrameBuffer protocol */
|
||||
XtLdrProtocol->Protocol.Close(&ProtocolHandle, &FrameBufGuid);
|
||||
|
||||
Address = Address + sizeof(SYSTEM_RESOURCE_ACPI);
|
||||
|
||||
FrameBufferResource = (PSYSTEM_RESOURCE_FRAMEBUFFER)Address;
|
||||
/* Close ACPI protocol */
|
||||
XtLdrProtocol->Protocol.Close(&ProtocolHandle, &AcpiGuid);
|
||||
|
||||
PhysicalBase = PhysicalBase + sizeof(SYSTEM_RESOURCE_ACPI);
|
||||
FrameBufferResource = (PSYSTEM_RESOURCE_FRAMEBUFFER)PhysicalBase;
|
||||
XtLdrProtocol->Memory.ZeroMemory(FrameBufferResource, sizeof(SYSTEM_RESOURCE_FRAMEBUFFER));
|
||||
|
||||
/* Load FrameBuffer protocol */
|
||||
@@ -346,26 +302,16 @@ Xtos::GetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Calculate pages needed to map framebuffer */
|
||||
FrameBufferPages = EFI_SIZE_TO_PAGES(FbSize);
|
||||
|
||||
/* Rewrite framebuffer address by using virtual address */
|
||||
FrameBufferResource->Header.VirtualAddress = *VirtualAddress;
|
||||
|
||||
/* Map frame buffer memory */
|
||||
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)FrameBufferResource->Header.VirtualAddress,
|
||||
(ULONGLONG)FrameBufferResource->Header.PhysicalAddress,
|
||||
FrameBufferPages, LoaderFirmwarePermanent);
|
||||
|
||||
/* Close FrameBuffer protocol */
|
||||
/* Assign the pre-mapped virtual address to the resource block */
|
||||
FrameBufferResource->Header.VirtualAddress = FrameBufferVirtualBase;
|
||||
XtLdrProtocol->Protocol.Close(&ProtocolHandle, &FrameBufGuid);
|
||||
|
||||
*VirtualAddress = (PUINT8)*VirtualAddress + (FrameBufferPages * EFI_PAGE_SIZE);
|
||||
|
||||
XtLdrProtocol->LinkedList.InsertTail(SystemResourcesList, &FrameBufferResource->Header.ListEntry);
|
||||
|
||||
XtLdrProtocol->Memory.PhysicalListToVirtual(PageMap, SystemResourcesList, PhysicalBase, VirtualBase);
|
||||
/* Convert list pointers to virtual */
|
||||
XtLdrProtocol->Memory.PhysicalListToVirtual(PageMap, SystemResourcesList, (PVOID)OriginalPhysicalBase, VirtualBase);
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -426,34 +372,97 @@ Xtos::InitializeApicBase(IN PXTBL_PAGE_MAPPING PageMap)
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
Xtos::InitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
IN PVOID *VirtualAddress,
|
||||
IN OUT PVOID *VirtualAddress,
|
||||
IN PXTBL_BOOT_PARAMETERS Parameters)
|
||||
{
|
||||
EFI_PHYSICAL_ADDRESS FbPhysicalAddress, PhysicalBlock, PhysicalDescriptor, PhysicalResources;
|
||||
PVOID FbVirtualAddress, VirtualBlock, VirtualResources, VirtualDescriptor;
|
||||
UINT BlockPages, DescriptorPages, FbPages, ParametersSize, ResourcesPages;
|
||||
XTBL_FRAMEBUFFER_MODE_INFORMATION FbModeInfo;
|
||||
PXTBL_FRAMEBUFFER_PROTOCOL FrameBufProtocol;
|
||||
PKERNEL_INITIALIZATION_BLOCK LoaderBlock;
|
||||
EFI_PHYSICAL_ADDRESS Address;
|
||||
EFI_HANDLE ProtocolHandle;
|
||||
EFI_STATUS Status;
|
||||
UINT BlockPages;
|
||||
UINT ParametersSize;
|
||||
ULONG_PTR FbSize;
|
||||
|
||||
EFI_GUID FrameBufGuid = XT_FRAMEBUFFER_PROTOCOL_GUID;
|
||||
|
||||
/* Initialize Framebuffer information */
|
||||
FbPhysicalAddress = 0;
|
||||
FbSize = 0;
|
||||
FbVirtualAddress = NULLPTR;
|
||||
FbPages = 0;
|
||||
|
||||
/* Calculate size of parameters */
|
||||
ParametersSize = (XtLdrProtocol->WideString.Length(Parameters->Parameters, 0) + 1) * sizeof(WCHAR);
|
||||
|
||||
/* Calculate number of pages needed for initialization block */
|
||||
BlockPages = EFI_SIZE_TO_PAGES(sizeof(KERNEL_INITIALIZATION_BLOCK) + ParametersSize);
|
||||
ResourcesPages = EFI_SIZE_TO_PAGES(sizeof(SYSTEM_RESOURCE_ACPI) + sizeof(SYSTEM_RESOURCE_FRAMEBUFFER));
|
||||
|
||||
/* Allocate memory for kernel initialization block */
|
||||
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, BlockPages, &Address);
|
||||
/* Query Framebuffer size for allocation */
|
||||
if(XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID*)&FrameBufProtocol, &FrameBufGuid) == STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Get FrameBuffer information */
|
||||
FrameBufProtocol->GetDisplayInformation(&FbPhysicalAddress, &FbSize, &FbModeInfo);
|
||||
XtLdrProtocol->Protocol.Close(&ProtocolHandle, &FrameBufGuid);
|
||||
}
|
||||
FbPages = EFI_SIZE_TO_PAGES(FbSize);
|
||||
|
||||
/* Calculate number of pages needed for memory descriptor list */
|
||||
DescriptorPages = EFI_SIZE_TO_PAGES(PageMap->MapSize * sizeof(LOADER_MEMORY_DESCRIPTOR));
|
||||
|
||||
/* Allocate memory for the kernel initialization block and boot parameters */
|
||||
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, BlockPages, &PhysicalBlock);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory allocation failure */
|
||||
/* Memory allocation failure, return status code */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Initialize and zero-fill kernel initialization block */
|
||||
LoaderBlock = (PKERNEL_INITIALIZATION_BLOCK)(UINT_PTR)Address;
|
||||
XtLdrProtocol->Memory.ZeroMemory(LoaderBlock, sizeof(KERNEL_INITIALIZATION_BLOCK) + ParametersSize);
|
||||
/* Allocate memory for the system resources data structures */
|
||||
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, ResourcesPages, &PhysicalResources);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory allocation failure, return status code */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Allocate memory for the memory descriptor list */
|
||||
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAnyPages, DescriptorPages, &PhysicalDescriptor);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory allocation failure, return status code */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Map the Kernel Initialization Block into virtual memory and advance the virtual address pointer */
|
||||
VirtualBlock = *VirtualAddress;
|
||||
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)VirtualBlock, PhysicalBlock, BlockPages, LoaderSystemBlock);
|
||||
*VirtualAddress = (PUINT8)*VirtualAddress + (BlockPages * EFI_PAGE_SIZE);
|
||||
|
||||
/* Map the system resources physical memory into virtual address space and update the allocation pointer */
|
||||
VirtualResources = *VirtualAddress;
|
||||
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)VirtualResources, PhysicalResources, ResourcesPages, LoaderFirmwarePermanent);
|
||||
*VirtualAddress = (PUINT8)*VirtualAddress + (ResourcesPages * EFI_PAGE_SIZE);
|
||||
|
||||
/* Check if a framebuffer was detected and requires memory mapping */
|
||||
if(FbPages > 0)
|
||||
{
|
||||
/* Map the framebuffer physical memory range into virtual address space */
|
||||
FbVirtualAddress = *VirtualAddress;
|
||||
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)FbVirtualAddress, FbPhysicalAddress, FbPages, LoaderFirmwarePermanent);
|
||||
*VirtualAddress = (PUINT8)*VirtualAddress + (FbPages * EFI_PAGE_SIZE);
|
||||
}
|
||||
|
||||
/* Map the allocated physical memory for memory descriptors into the virtual address space */
|
||||
VirtualDescriptor = *VirtualAddress;
|
||||
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)VirtualDescriptor, PhysicalDescriptor, DescriptorPages, LoaderMemoryData);
|
||||
*VirtualAddress = (PUINT8)*VirtualAddress + (DescriptorPages * EFI_PAGE_SIZE);
|
||||
|
||||
/* Set basic loader block properties */
|
||||
XtLdrProtocol->Memory.ZeroMemory((PVOID)PhysicalBlock, sizeof(KERNEL_INITIALIZATION_BLOCK) + ParametersSize);
|
||||
LoaderBlock = (PKERNEL_INITIALIZATION_BLOCK)PhysicalBlock;
|
||||
LoaderBlock->BlockSize = sizeof(KERNEL_INITIALIZATION_BLOCK);
|
||||
LoaderBlock->BlockVersion = INITIALIZATION_BLOCK_VERSION;
|
||||
LoaderBlock->ProtocolVersion = BOOT_PROTOCOL_VERSION;
|
||||
@@ -467,24 +476,30 @@ Xtos::InitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap,
|
||||
LoaderBlock->FirmwareInformation.EfiFirmware.EfiRuntimeServices = NULLPTR;
|
||||
|
||||
/* Copy parameters to kernel initialization block */
|
||||
LoaderBlock->KernelParameters = (PWCHAR)((UINT_PTR)*VirtualAddress + sizeof(KERNEL_INITIALIZATION_BLOCK));
|
||||
LoaderBlock->KernelParameters = (PWCHAR)((UINT_PTR)VirtualBlock + sizeof(KERNEL_INITIALIZATION_BLOCK));
|
||||
XtLdrProtocol->Memory.CopyMemory((PVOID)((UINT_PTR)LoaderBlock + sizeof(KERNEL_INITIALIZATION_BLOCK)),
|
||||
Parameters->Parameters,
|
||||
ParametersSize);
|
||||
Parameters->Parameters, ParametersSize);
|
||||
|
||||
/* Map kernel initialization block */
|
||||
XtLdrProtocol->Memory.MapVirtualMemory(PageMap, (ULONGLONG)*VirtualAddress, (ULONGLONG)LoaderBlock,
|
||||
BlockPages, LoaderSystemBlock);
|
||||
|
||||
/* Calculate next valid virtual address */
|
||||
*VirtualAddress = (PUINT8)*VirtualAddress + (BlockPages * EFI_PAGE_SIZE);
|
||||
/* Commit mappings */
|
||||
XtLdrProtocol->Memory.CommitPageMap(PageMap);
|
||||
|
||||
/* Initialize system resources list */
|
||||
XtLdrProtocol->LinkedList.InitializeHead(&LoaderBlock->SystemResourcesListHead);
|
||||
GetSystemResourcesList(PageMap, VirtualAddress, &LoaderBlock->SystemResourcesListHead);
|
||||
Status = GetSystemResourcesList(PageMap, PhysicalResources, VirtualResources, FbVirtualAddress, &LoaderBlock->SystemResourcesListHead);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to initialize system resources list, return status code */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Initialize memory descriptor list */
|
||||
XtLdrProtocol->LinkedList.InitializeHead(&LoaderBlock->MemoryDescriptorListHead);
|
||||
GetMemoryDescriptorList(PageMap, VirtualAddress, &LoaderBlock->MemoryDescriptorListHead);
|
||||
Status = GetMemoryDescriptorList(PageMap, PhysicalDescriptor, VirtualDescriptor, &LoaderBlock->MemoryDescriptorListHead);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to initialize memory descriptor list, return status code */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Set boot image size */
|
||||
LoaderBlock->BootImageSize = (PFN_NUMBER)(((ULONGLONG)*VirtualAddress - KSEG0_BASE) / EFI_PAGE_SIZE);
|
||||
@@ -702,6 +717,14 @@ Xtos::RunBootSequence(IN PEFI_FILE_HANDLE BootDir,
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Build page map */
|
||||
Status = BuildPageMap(&PageMap);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
XtLdrProtocol->Debug.Print(L"Failed to build page map (Status code: %zX)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Store virtual address of kernel initialization block for future kernel call */
|
||||
KernelParameters = (PKERNEL_INITIALIZATION_BLOCK)VirtualAddress;
|
||||
|
||||
|
||||
@@ -1054,6 +1054,7 @@ Protocol::InstallXtLoaderProtocol()
|
||||
LoaderProtocol.Memory.AllocatePages = Memory::AllocatePages;
|
||||
LoaderProtocol.Memory.AllocatePool = Memory::AllocatePool;
|
||||
LoaderProtocol.Memory.BuildPageMap = Memory::BuildPageMap;
|
||||
LoaderProtocol.Memory.CommitPageMap = Memory::CommitPageMap;
|
||||
LoaderProtocol.Memory.CompareMemory = RTL::Memory::CompareMemory;
|
||||
LoaderProtocol.Memory.CopyMemory = RTL::Memory::CopyMemory;
|
||||
LoaderProtocol.Memory.FreePages = Memory::FreePages;
|
||||
|
||||
@@ -51,6 +51,7 @@ typedef EFI_STATUS (XTCDECL *PBL_BOOTMENU_INITIALIZE_OS_LIST)(IN ULONG MaxNameLe
|
||||
typedef BOOLEAN (XTCDECL *PBL_BOOTUTILS_GET_BOOLEAN_PARAMETER)(IN PCWSTR Parameters, IN PCWSTR Needle);
|
||||
typedef VOID (XTAPI *PBL_BOOTUTILS_GET_TRAMPOLINE_INFORMATION)(IN TRAMPOLINE_TYPE TrampolineType, OUT PVOID *TrampolineCode, OUT PULONG_PTR TrampolineSize);
|
||||
typedef EFI_STATUS (XTCDECL *PBL_BUILD_PAGE_MAP)(IN PXTBL_PAGE_MAPPING PageMap, IN ULONG_PTR SelfMapAddress);
|
||||
typedef EFI_STATUS (XTCDECL *PBL_COMMIT_PAGE_MAP)(IN PXTBL_PAGE_MAPPING PageMap);
|
||||
typedef EFI_STATUS (XTCDECL *PBL_CLOSE_VOLUME)(IN PEFI_HANDLE VolumeHandle);
|
||||
typedef VOID (XTCDECL *PBL_CLEAR_CONSOLE_LINE)(IN ULONGLONG LineNo);
|
||||
typedef BOOLEAN (XTCDECL *PBL_CPU_CPUID)(IN OUT PCPUID_REGISTERS Registers);
|
||||
@@ -449,6 +450,7 @@ typedef struct _XTBL_LOADER_PROTOCOL
|
||||
PBL_ALLOCATE_PAGES AllocatePages;
|
||||
PBL_ALLOCATE_POOL AllocatePool;
|
||||
PBL_BUILD_PAGE_MAP BuildPageMap;
|
||||
PBL_COMMIT_PAGE_MAP CommitPageMap;
|
||||
PBL_COMPARE_MEMORY CompareMemory;
|
||||
PBL_COPY_MEMORY CopyMemory;
|
||||
PBL_FREE_PAGES FreePages;
|
||||
|
||||
Reference in New Issue
Block a user