Refactor bootloader code into C++ classes
Some checks failed
Builds / ExectOS (amd64, debug) (push) Failing after 29s
Builds / ExectOS (amd64, release) (push) Failing after 27s
Builds / ExectOS (i686, debug) (push) Failing after 22s
Builds / ExectOS (i686, release) (push) Failing after 21s

This commit is contained in:
2025-09-20 18:47:36 +02:00
parent 08a9a0273f
commit c041457799
21 changed files with 2031 additions and 1739 deletions

View File

@@ -22,7 +22,6 @@ list(APPEND XTLDR_SOURCE
${XTLDR_SOURCE_DIR}/debug.cc ${XTLDR_SOURCE_DIR}/debug.cc
${XTLDR_SOURCE_DIR}/efiutils.cc ${XTLDR_SOURCE_DIR}/efiutils.cc
${XTLDR_SOURCE_DIR}/globals.cc ${XTLDR_SOURCE_DIR}/globals.cc
${XTLDR_SOURCE_DIR}/hardware.cc
${XTLDR_SOURCE_DIR}/memory.cc ${XTLDR_SOURCE_DIR}/memory.cc
${XTLDR_SOURCE_DIR}/protocol.cc ${XTLDR_SOURCE_DIR}/protocol.cc
${XTLDR_SOURCE_DIR}/shell.cc ${XTLDR_SOURCE_DIR}/shell.cc

View File

@@ -25,8 +25,8 @@
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR SelfMapAddress) IN ULONG_PTR SelfMapAddress)
{ {
PLIST_ENTRY ListEntry, ModulesList, ModulesListEntry; PLIST_ENTRY ListEntry, ModulesList, ModulesListEntry;
PXTBL_MEMORY_MAPPING Mapping; PXTBL_MEMORY_MAPPING Mapping;
@@ -35,7 +35,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
EFI_STATUS Status; EFI_STATUS Status;
/* Allocate pages for the Page Map */ /* Allocate pages for the Page Map */
Status = BlAllocateMemoryPages(AllocateAnyPages, 1, &Address); Status = AllocatePages(AllocateAnyPages, 1, &Address);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure */ /* Memory allocation failure */
@@ -47,7 +47,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
RTL::Memory::ZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE); RTL::Memory::ZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE);
/* Add page mapping itself to memory mapping */ /* Add page mapping itself to memory mapping */
Status = BlpSelfMapPml(PageMap, SelfMapAddress); Status = Memory::SelfMapPml(PageMap, SelfMapAddress);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* PML mapping failed */ /* PML mapping failed */
@@ -55,8 +55,8 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
} }
/* Map the trampoline code area */ /* Map the trampoline code area */
Status = BlMapVirtualMemory(PageMap, (PVOID)MM_TRAMPOLINE_ADDRESS,(PVOID)MM_TRAMPOLINE_ADDRESS, Status = MapVirtualMemory(PageMap, (PVOID)MM_TRAMPOLINE_ADDRESS,(PVOID)MM_TRAMPOLINE_ADDRESS,
1, LoaderFirmwareTemporary); 1, LoaderFirmwareTemporary);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Mapping trampoline code failed */ /* Mapping trampoline code failed */
@@ -64,7 +64,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
} }
/* Get list of XTLDR modules */ /* Get list of XTLDR modules */
ModulesList = BlGetModulesList(); ModulesList = Protocol::GetModulesList();
ModulesListEntry = ModulesList->Flink; ModulesListEntry = ModulesList->Flink;
while(ModulesListEntry != ModulesList) while(ModulesListEntry != ModulesList)
{ {
@@ -72,8 +72,8 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
ModuleInfo = CONTAIN_RECORD(ModulesListEntry, XTBL_MODULE_INFO, Flink); ModuleInfo = CONTAIN_RECORD(ModulesListEntry, XTBL_MODULE_INFO, Flink);
/* Map module code */ /* Map module code */
Status = BlMapVirtualMemory(PageMap, ModuleInfo->ModuleBase, ModuleInfo->ModuleBase, Status = MapVirtualMemory(PageMap, ModuleInfo->ModuleBase, ModuleInfo->ModuleBase,
EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary); EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary);
/* Check if mapping succeeded */ /* Check if mapping succeeded */
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
@@ -90,8 +90,8 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
if(BlpStatus.LoaderBase && BlpStatus.LoaderSize) if(BlpStatus.LoaderBase && BlpStatus.LoaderSize)
{ {
/* Map boot loader code as well */ /* Map boot loader code as well */
Status = BlMapVirtualMemory(PageMap, BlpStatus.LoaderBase, BlpStatus.LoaderBase, Status = MapVirtualMemory(PageMap, BlpStatus.LoaderBase, BlpStatus.LoaderBase,
EFI_SIZE_TO_PAGES(BlpStatus.LoaderSize), LoaderFirmwareTemporary); EFI_SIZE_TO_PAGES(BlpStatus.LoaderSize), LoaderFirmwareTemporary);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Mapping boot loader code failed */ /* Mapping boot loader code failed */
@@ -105,7 +105,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
} }
/* Iterate through and map all the mappings*/ /* Iterate through and map all the mappings*/
BlDebugPrint(L"Mapping and dumping EFI memory:\n"); Debug::Print(L"Mapping and dumping EFI memory:\n");
ListEntry = PageMap->MemoryMap.Flink; ListEntry = PageMap->MemoryMap.Flink;
while(ListEntry != &PageMap->MemoryMap) while(ListEntry != &PageMap->MemoryMap)
{ {
@@ -116,12 +116,12 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
if(Mapping->VirtualAddress) if(Mapping->VirtualAddress)
{ {
/* Dump memory mapping */ /* Dump memory mapping */
BlDebugPrint(L" Type=%02lu, PhysicalBase=%.16P, VirtualBase=%.16P, Pages=%llu\n", Mapping->MemoryType, Debug::Print(L" Type=%02lu, PhysicalBase=%.16P, VirtualBase=%.16P, Pages=%llu\n", Mapping->MemoryType,
Mapping->PhysicalAddress, Mapping->VirtualAddress, Mapping->NumberOfPages); Mapping->PhysicalAddress, Mapping->VirtualAddress, Mapping->NumberOfPages);
/* Map memory */ /* Map memory */
Status = BlMapPage(PageMap, (UINT_PTR)Mapping->VirtualAddress, Status = MapPage(PageMap, (UINT_PTR)Mapping->VirtualAddress,
(UINT_PTR)Mapping->PhysicalAddress, Mapping->NumberOfPages); (UINT_PTR)Mapping->PhysicalAddress, Mapping->NumberOfPages);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory mapping failed */ /* Memory mapping failed */
@@ -137,114 +137,6 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
} }
/**
* Does the actual virtual memory mapping.
*
* @param PageMap
* Supplies a pointer to the page mapping structure.
*
* @param VirtualAddress
* Supplies a virtual address of the mapping.
*
* @param PhysicalAddress
* Supplies a physical address of the mapping.
*
* @param NumberOfPages
* Supplies a number of the pages of the mapping.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
BlMapPage(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR VirtualAddress,
IN ULONG_PTR PhysicalAddress,
IN ULONG NumberOfPages)
{
PVOID Pml1, Pml2, Pml3, Pml4, Pml5;
SIZE_T Pml1Entry, Pml2Entry, Pml3Entry, Pml4Entry, Pml5Entry;
PHARDWARE_PTE PmlTable;
SIZE_T PageFrameNumber;
EFI_STATUS Status;
/* Set the Page Frame Number (PFN) */
PageFrameNumber = PhysicalAddress >> EFI_PAGE_SHIFT;
/* Do the recursive mapping */
while(NumberOfPages > 0)
{
/* Calculate the indices in the various Page Tables from the virtual address */
Pml5Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_P5I_SHIFT)) >> MM_P5I_SHIFT;
Pml4Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PXI_SHIFT)) >> MM_PXI_SHIFT;
Pml3Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PPI_SHIFT)) >> MM_PPI_SHIFT;
Pml2Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PDI_SHIFT)) >> MM_PDI_SHIFT;
Pml1Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PTI_SHIFT)) >> MM_PTI_SHIFT;
/* Check page map level */
if(PageMap->PageMapLevel == 5)
{
/* Five level Page Map */
Pml5 = PageMap->PtePointer;
/* Get PML4 */
Status = BlpGetNextPageTable(PageMap, Pml5, Pml5Entry, &Pml4);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory mapping failure */
return Status;
}
}
else
{
/* Four level Page Map */
Pml4 = PageMap->PtePointer;
}
/* Get PML3 */
Status = BlpGetNextPageTable(PageMap, Pml4, Pml4Entry, &Pml3);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory mapping failure */
return Status;
}
/* Get PML 2 */
Status = BlpGetNextPageTable(PageMap, Pml3, Pml3Entry, &Pml2);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory mapping failure */
return Status;
}
/* Get PML1 */
Status = BlpGetNextPageTable(PageMap, Pml2, Pml2Entry, &Pml1);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory mapping failure */
return Status;
}
/* Set paging entry settings */
PmlTable = (PHARDWARE_PTE)Pml1;
RTL::Memory::ZeroMemory(&PmlTable[Pml1Entry], sizeof(HARDWARE_PTE));
PmlTable[Pml1Entry].PageFrameNumber = PageFrameNumber;
PmlTable[Pml1Entry].Valid = 1;
PmlTable[Pml1Entry].Writable = 1;
/* Take next virtual address and PFN */
VirtualAddress += EFI_PAGE_SIZE;
PageFrameNumber++;
/* Decrease number of pages left */
NumberOfPages--;
}
/* Return success */
return STATUS_EFI_SUCCESS;
}
/** /**
* Returns next level of the Page Table. * Returns next level of the Page Table.
* *
@@ -266,10 +158,10 @@ BlMapPage(IN PXTBL_PAGE_MAPPING PageMap,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap, Memory::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)
{ {
EFI_PHYSICAL_ADDRESS Address; EFI_PHYSICAL_ADDRESS Address;
ULONGLONG PmlPointer = 0; ULONGLONG PmlPointer = 0;
@@ -288,7 +180,7 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
else else
{ {
/* Allocate pages for new PML entry */ /* Allocate pages for new PML entry */
Status = BlAllocateMemoryPages(AllocateAnyPages, 1, &Address); Status = AllocatePages(AllocateAnyPages, 1, &Address);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure */ /* Memory allocation failure */
@@ -296,7 +188,7 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
} }
/* Add new memory mapping */ /* Add new memory mapping */
Status = BlMapVirtualMemory(PageMap, NULLPTR, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData); Status = MapVirtualMemory(PageMap, NULLPTR, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory mapping failure */ /* Memory mapping failure */
@@ -320,6 +212,114 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
} }
/**
* Does the actual virtual memory mapping.
*
* @param PageMap
* Supplies a pointer to the page mapping structure.
*
* @param VirtualAddress
* Supplies a virtual address of the mapping.
*
* @param PhysicalAddress
* Supplies a physical address of the mapping.
*
* @param NumberOfPages
* Supplies a number of the pages of the mapping.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
Memory::MapPage(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR VirtualAddress,
IN ULONG_PTR PhysicalAddress,
IN ULONG NumberOfPages)
{
PVOID Pml1, Pml2, Pml3, Pml4, Pml5;
SIZE_T Pml1Entry, Pml2Entry, Pml3Entry, Pml4Entry, Pml5Entry;
PHARDWARE_PTE PmlTable;
SIZE_T PageFrameNumber;
EFI_STATUS Status;
/* Set the Page Frame Number (PFN) */
PageFrameNumber = PhysicalAddress >> EFI_PAGE_SHIFT;
/* Do the recursive mapping */
while(NumberOfPages > 0)
{
/* Calculate the indices in the various Page Tables from the virtual address */
Pml5Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_P5I_SHIFT)) >> MM_P5I_SHIFT;
Pml4Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PXI_SHIFT)) >> MM_PXI_SHIFT;
Pml3Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PPI_SHIFT)) >> MM_PPI_SHIFT;
Pml2Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PDI_SHIFT)) >> MM_PDI_SHIFT;
Pml1Entry = (VirtualAddress & ((ULONGLONG)0x1FF << MM_PTI_SHIFT)) >> MM_PTI_SHIFT;
/* Check page map level */
if(PageMap->PageMapLevel == 5)
{
/* Five level Page Map */
Pml5 = PageMap->PtePointer;
/* Get PML4 */
Status = GetNextPageTable(PageMap, Pml5, Pml5Entry, &Pml4);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory mapping failure */
return Status;
}
}
else
{
/* Four level Page Map */
Pml4 = PageMap->PtePointer;
}
/* Get PML3 */
Status = GetNextPageTable(PageMap, Pml4, Pml4Entry, &Pml3);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory mapping failure */
return Status;
}
/* Get PML 2 */
Status = GetNextPageTable(PageMap, Pml3, Pml3Entry, &Pml2);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory mapping failure */
return Status;
}
/* Get PML1 */
Status = GetNextPageTable(PageMap, Pml2, Pml2Entry, &Pml1);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory mapping failure */
return Status;
}
/* Set paging entry settings */
PmlTable = (PHARDWARE_PTE)Pml1;
RTL::Memory::ZeroMemory(&PmlTable[Pml1Entry], sizeof(HARDWARE_PTE));
PmlTable[Pml1Entry].PageFrameNumber = PageFrameNumber;
PmlTable[Pml1Entry].Valid = 1;
PmlTable[Pml1Entry].Writable = 1;
/* Take next virtual address and PFN */
VirtualAddress += EFI_PAGE_SIZE;
PageFrameNumber++;
/* Decrease number of pages left */
NumberOfPages--;
}
/* Return success */
return STATUS_EFI_SUCCESS;
}
/** /**
* Creates a recursive self mapping for all PML levels. * Creates a recursive self mapping for all PML levels.
* *
@@ -335,8 +335,8 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlpSelfMapPml(IN PXTBL_PAGE_MAPPING PageMap, Memory::SelfMapPml(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR SelfMapAddress) IN ULONG_PTR SelfMapAddress)
{ {
PHARDWARE_PTE PmlBase; PHARDWARE_PTE PmlBase;
ULONGLONG PmlIndex; ULONGLONG PmlIndex;

View File

@@ -22,8 +22,8 @@
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap, Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR SelfMapAddress) IN ULONG_PTR SelfMapAddress)
{ {
PLIST_ENTRY ListEntry, ModulesList, ModulesListEntry; PLIST_ENTRY ListEntry, ModulesList, ModulesListEntry;
EFI_PHYSICAL_ADDRESS Address, DirectoryAddress; EFI_PHYSICAL_ADDRESS Address, DirectoryAddress;
@@ -36,7 +36,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
if(PageMap->PageMapLevel == 3) if(PageMap->PageMapLevel == 3)
{ {
/* Allocate a page for the 3-level page map structure (PAE enabled) */ /* Allocate a page for the 3-level page map structure (PAE enabled) */
Status = BlAllocateMemoryPages(AllocateAnyPages, 1, &Address); Status = AllocatePages(AllocateAnyPages, 1, &Address);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failed, cannot proceed with page map creation */ /* Memory allocation failed, cannot proceed with page map creation */
@@ -48,7 +48,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
RTL::Memory::ZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE); RTL::Memory::ZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE);
/* Allocate 4 pages for the Page Directories (PDs) */ /* Allocate 4 pages for the Page Directories (PDs) */
Status = BlAllocateMemoryPages(AllocateAnyPages, 4, &DirectoryAddress); Status = AllocatePages(AllocateAnyPages, 4, &DirectoryAddress);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failed, cannot proceed with page map creation */ /* Memory allocation failed, cannot proceed with page map creation */
@@ -70,7 +70,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
else else
{ {
/* Allocate a page for the 2-level page map structure (PAE disabled) */ /* Allocate a page for the 2-level page map structure (PAE disabled) */
Status = BlAllocateMemoryPages(AllocateAnyPages, 1, &Address); Status = AllocatePages(AllocateAnyPages, 1, &Address);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failed, cannot proceed with page map creation */ /* Memory allocation failed, cannot proceed with page map creation */
@@ -83,7 +83,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
} }
/* Add page mapping itself to memory mapping */ /* Add page mapping itself to memory mapping */
Status = BlpSelfMapPml(PageMap, SelfMapAddress); Status = SelfMapPml(PageMap, SelfMapAddress);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* PML mapping failed */ /* PML mapping failed */
@@ -91,8 +91,8 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
} }
/* Map the trampoline code area */ /* Map the trampoline code area */
Status = BlMapVirtualMemory(PageMap, (PVOID)MM_TRAMPOLINE_ADDRESS,(PVOID)MM_TRAMPOLINE_ADDRESS, Status = MapVirtualMemory(PageMap, (PVOID)MM_TRAMPOLINE_ADDRESS,(PVOID)MM_TRAMPOLINE_ADDRESS,
1, LoaderFirmwareTemporary); 1, LoaderFirmwareTemporary);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Mapping trampoline code failed */ /* Mapping trampoline code failed */
@@ -100,7 +100,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
} }
/* Get list of XTLDR modules */ /* Get list of XTLDR modules */
ModulesList = BlGetModulesList(); ModulesList = Protocol::GetModulesList();
ModulesListEntry = ModulesList->Flink; ModulesListEntry = ModulesList->Flink;
while(ModulesListEntry != ModulesList) while(ModulesListEntry != ModulesList)
{ {
@@ -108,8 +108,8 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
ModuleInfo = CONTAIN_RECORD(ModulesListEntry, XTBL_MODULE_INFO, Flink); ModuleInfo = CONTAIN_RECORD(ModulesListEntry, XTBL_MODULE_INFO, Flink);
/* Map module code */ /* Map module code */
Status = BlMapVirtualMemory(PageMap, ModuleInfo->ModuleBase, ModuleInfo->ModuleBase, Status = MapVirtualMemory(PageMap, ModuleInfo->ModuleBase, ModuleInfo->ModuleBase,
EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary); EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary);
/* Check if mapping succeeded */ /* Check if mapping succeeded */
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
@@ -126,8 +126,8 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
if(BlpStatus.LoaderBase && BlpStatus.LoaderSize) if(BlpStatus.LoaderBase && BlpStatus.LoaderSize)
{ {
/* Map boot loader code as well */ /* Map boot loader code as well */
Status = BlMapVirtualMemory(PageMap, BlpStatus.LoaderBase, BlpStatus.LoaderBase, Status = MapVirtualMemory(PageMap, BlpStatus.LoaderBase, BlpStatus.LoaderBase,
EFI_SIZE_TO_PAGES(BlpStatus.LoaderSize), LoaderFirmwareTemporary); EFI_SIZE_TO_PAGES(BlpStatus.LoaderSize), LoaderFirmwareTemporary);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Mapping boot loader code failed */ /* Mapping boot loader code failed */
@@ -141,7 +141,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
} }
/* Iterate through and map all the mappings*/ /* Iterate through and map all the mappings*/
BlDebugPrint(L"Mapping and dumping EFI memory:\n"); Debug::Print(L"Mapping and dumping EFI memory:\n");
ListEntry = PageMap->MemoryMap.Flink; ListEntry = PageMap->MemoryMap.Flink;
while(ListEntry != &PageMap->MemoryMap) while(ListEntry != &PageMap->MemoryMap)
{ {
@@ -152,12 +152,12 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
if(Mapping->VirtualAddress) if(Mapping->VirtualAddress)
{ {
/* Dump memory mapping */ /* Dump memory mapping */
BlDebugPrint(L" Type=%02lu, PhysicalBase=%.8P, VirtualBase=%.8P, Pages=%llu\n", Mapping->MemoryType, Debug::Print(L" Type=%02lu, PhysicalBase=%.8P, VirtualBase=%.8P, Pages=%llu\n", Mapping->MemoryType,
Mapping->PhysicalAddress, Mapping->VirtualAddress, Mapping->NumberOfPages); Mapping->PhysicalAddress, Mapping->VirtualAddress, Mapping->NumberOfPages);
/* Map memory */ /* Map memory */
Status = BlMapPage(PageMap, (UINT_PTR)Mapping->VirtualAddress, Status = MapPage(PageMap, (UINT_PTR)Mapping->VirtualAddress,
(UINT_PTR)Mapping->PhysicalAddress, Mapping->NumberOfPages); (UINT_PTR)Mapping->PhysicalAddress, Mapping->NumberOfPages);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory mapping failed */ /* Memory mapping failed */
@@ -173,116 +173,6 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
} }
/**
* Does the actual virtual memory mapping.
*
* @param PageMap
* Supplies a pointer to the page mapping structure.
*
* @param VirtualAddress
* Supplies a virtual address of the mapping.
*
* @param PhysicalAddress
* Supplies a physical address of the mapping.
*
* @param NumberOfPages
* Supplies a number of the pages of the mapping.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
BlMapPage(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR VirtualAddress,
IN ULONG_PTR PhysicalAddress,
IN ULONG NumberOfPages)
{
SIZE_T PageFrameNumber;
PVOID Pml1, Pml2, Pml3;
SIZE_T Pml1Entry, Pml2Entry, Pml3Entry;
PHARDWARE_LEGACY_PTE LegacyPmlTable;
PHARDWARE_MODERN_PTE PmlTable;
EFI_STATUS Status;
/* Set the Page Frame Number (PFN) */
PageFrameNumber = PhysicalAddress >> EFI_PAGE_SHIFT;
/* Map all requested pages */
while(NumberOfPages > 0)
{
/* Check the paging mode to use the correct page table structure */
if(PageMap->PageMapLevel == 3)
{
/* Calculate the indices for PAE page tables */
Pml3Entry = (VirtualAddress >> 30) & 0x3;
Pml2Entry = (VirtualAddress >> 21) & 0x1FF;
Pml1Entry = (VirtualAddress >> 12) & 0x1FF;
/* Get Page Directory Pointer Table (PML3) */
Pml3 = PageMap->PtePointer;
/* Get Page Directory (PML2) */
Status = BlpGetNextPageTable(PageMap, Pml3, Pml3Entry, &Pml2);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to get the Page Table, abort mapping */
return Status;
}
/* Get Page Table (PML1) */
Status = BlpGetNextPageTable(PageMap, Pml2, Pml2Entry, &Pml1);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to get the Page Table, abort mapping */
return Status;
}
/* Set the 64-bit PTE entry */
PmlTable = (PHARDWARE_MODERN_PTE)Pml1;
RTL::Memory::ZeroMemory(&PmlTable[Pml1Entry], sizeof(HARDWARE_MODERN_PTE));
PmlTable[Pml1Entry].PageFrameNumber = PageFrameNumber;
PmlTable[Pml1Entry].Valid = 1;
PmlTable[Pml1Entry].Writable = 1;
}
else
{
/* Calculate the indices for non-PAE page tables */
Pml2Entry = (VirtualAddress >> 22) & 0x3FF;
Pml1Entry = (VirtualAddress >> 12) & 0x3FF;
/* Get Page Directory (PML2) */
Pml2 = PageMap->PtePointer;
/* Get Page Table (PML1) */
Status = BlpGetNextPageTable(PageMap, Pml2, Pml2Entry, &Pml1);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to get the Page Table, abort mapping */
return Status;
}
/* Set the 32-bit PTE entry */
LegacyPmlTable = (PHARDWARE_LEGACY_PTE)Pml1;
RTL::Memory::ZeroMemory(&LegacyPmlTable[Pml1Entry], sizeof(HARDWARE_LEGACY_PTE));
LegacyPmlTable[Pml1Entry].PageFrameNumber = (UINT32)PageFrameNumber;
LegacyPmlTable[Pml1Entry].Valid = 1;
LegacyPmlTable[Pml1Entry].Writable = 1;
}
/* Take next virtual address and PFN */
VirtualAddress += EFI_PAGE_SIZE;
PageFrameNumber++;
/* Decrease number of pages left */
NumberOfPages--;
}
/* Return success */
return STATUS_EFI_SUCCESS;
}
/** /**
* Returns next level of the Page Table. * Returns next level of the Page Table.
* *
@@ -304,10 +194,10 @@ BlMapPage(IN PXTBL_PAGE_MAPPING PageMap,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap, Memory::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)
{ {
EFI_PHYSICAL_ADDRESS Address; EFI_PHYSICAL_ADDRESS Address;
ULONGLONG PmlPointer = 0; ULONGLONG PmlPointer = 0;
@@ -349,7 +239,7 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
else else
{ {
/* Allocate pages for new PML entry */ /* Allocate pages for new PML entry */
Status = BlAllocateMemoryPages(AllocateAnyPages, 1, &Address); Status = AllocatePages(AllocateAnyPages, 1, &Address);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure */ /* Memory allocation failure */
@@ -357,7 +247,7 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
} }
/* Add new memory mapping */ /* Add new memory mapping */
Status = BlMapVirtualMemory(PageMap, NULLPTR, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData); Status = MapVirtualMemory(PageMap, NULLPTR, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory mapping failure */ /* Memory mapping failure */
@@ -396,6 +286,116 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
} }
/**
* Does the actual virtual memory mapping.
*
* @param PageMap
* Supplies a pointer to the page mapping structure.
*
* @param VirtualAddress
* Supplies a virtual address of the mapping.
*
* @param PhysicalAddress
* Supplies a physical address of the mapping.
*
* @param NumberOfPages
* Supplies a number of the pages of the mapping.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
Memory::MapPage(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR VirtualAddress,
IN ULONG_PTR PhysicalAddress,
IN ULONG NumberOfPages)
{
SIZE_T PageFrameNumber;
PVOID Pml1, Pml2, Pml3;
SIZE_T Pml1Entry, Pml2Entry, Pml3Entry;
PHARDWARE_LEGACY_PTE LegacyPmlTable;
PHARDWARE_MODERN_PTE PmlTable;
EFI_STATUS Status;
/* Set the Page Frame Number (PFN) */
PageFrameNumber = PhysicalAddress >> EFI_PAGE_SHIFT;
/* Map all requested pages */
while(NumberOfPages > 0)
{
/* Check the paging mode to use the correct page table structure */
if(PageMap->PageMapLevel == 3)
{
/* Calculate the indices for PAE page tables */
Pml3Entry = (VirtualAddress >> 30) & 0x3;
Pml2Entry = (VirtualAddress >> 21) & 0x1FF;
Pml1Entry = (VirtualAddress >> 12) & 0x1FF;
/* Get Page Directory Pointer Table (PML3) */
Pml3 = PageMap->PtePointer;
/* Get Page Directory (PML2) */
Status = GetNextPageTable(PageMap, Pml3, Pml3Entry, &Pml2);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to get the Page Table, abort mapping */
return Status;
}
/* Get Page Table (PML1) */
Status = GetNextPageTable(PageMap, Pml2, Pml2Entry, &Pml1);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to get the Page Table, abort mapping */
return Status;
}
/* Set the 64-bit PTE entry */
PmlTable = (PHARDWARE_MODERN_PTE)Pml1;
RTL::Memory::ZeroMemory(&PmlTable[Pml1Entry], sizeof(HARDWARE_MODERN_PTE));
PmlTable[Pml1Entry].PageFrameNumber = PageFrameNumber;
PmlTable[Pml1Entry].Valid = 1;
PmlTable[Pml1Entry].Writable = 1;
}
else
{
/* Calculate the indices for non-PAE page tables */
Pml2Entry = (VirtualAddress >> 22) & 0x3FF;
Pml1Entry = (VirtualAddress >> 12) & 0x3FF;
/* Get Page Directory (PML2) */
Pml2 = PageMap->PtePointer;
/* Get Page Table (PML1) */
Status = GetNextPageTable(PageMap, Pml2, Pml2Entry, &Pml1);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to get the Page Table, abort mapping */
return Status;
}
/* Set the 32-bit PTE entry */
LegacyPmlTable = (PHARDWARE_LEGACY_PTE)Pml1;
RTL::Memory::ZeroMemory(&LegacyPmlTable[Pml1Entry], sizeof(HARDWARE_LEGACY_PTE));
LegacyPmlTable[Pml1Entry].PageFrameNumber = (UINT32)PageFrameNumber;
LegacyPmlTable[Pml1Entry].Valid = 1;
LegacyPmlTable[Pml1Entry].Writable = 1;
}
/* Take next virtual address and PFN */
VirtualAddress += EFI_PAGE_SIZE;
PageFrameNumber++;
/* Decrease number of pages left */
NumberOfPages--;
}
/* Return success */
return STATUS_EFI_SUCCESS;
}
/** /**
* Creates a recursive self mapping for all PML levels. * Creates a recursive self mapping for all PML levels.
* *
@@ -411,8 +411,8 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlpSelfMapPml(IN PXTBL_PAGE_MAPPING PageMap, Memory::SelfMapPml(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR SelfMapAddress) IN ULONG_PTR SelfMapAddress)
{ {
PHARDWARE_LEGACY_PTE LegacyPml; PHARDWARE_LEGACY_PTE LegacyPml;
PHARDWARE_MODERN_PTE Pml; PHARDWARE_MODERN_PTE Pml;

View File

@@ -24,8 +24,8 @@
*/ */
XTCDECL XTCDECL
BOOLEAN BOOLEAN
BlGetBooleanParameter(IN PCWSTR Parameters, BootUtils::GetBooleanParameter(IN PCWSTR Parameters,
IN PCWSTR Needle) IN PCWSTR Needle)
{ {
PCWSTR CurrentPosition, TokenEnd, TokenStart; PCWSTR CurrentPosition, TokenEnd, TokenStart;
SIZE_T NeedleLength, TokenLength; SIZE_T NeedleLength, TokenLength;

View File

@@ -10,6 +10,39 @@
#include <xtldr.hh> #include <xtldr.hh>
/**
* Returns a boolean value of the specified configuration key.
*
* @param ConfigName
* Specifies the configuration key to return its boolean representation.
*
* @return This routine returns a boolean representation of the configuration value.
*
* @since XT 1.0
*/
XTCDECL
BOOLEAN
Configuration::GetBooleanValue(IN PCWSTR ConfigName)
{
PWCHAR Value;
/* Get config value */
GetValue(ConfigName, &Value);
/* Check if option is enabled */
if(RTL::WideString::CompareWideStringInsensitive(Value, L"ENABLED", 0) == 0 ||
RTL::WideString::CompareWideStringInsensitive(Value, L"ON", 0) == 0 ||
RTL::WideString::CompareWideStringInsensitive(Value, L"TRUE", 0) == 0 ||
RTL::WideString::CompareWideStringInsensitive(Value, L"YES", 0) == 0)
{
/* This option is enabled */
return TRUE;
}
/* Return FALSE by default */
return FALSE;
}
/** /**
* @brief Retrieves the value of a specific OS boot option from a list. * @brief Retrieves the value of a specific OS boot option from a list.
* *
@@ -28,9 +61,9 @@
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlGetBootOptionValue(IN PLIST_ENTRY Options, Configuration::GetBootOptionValue(IN PLIST_ENTRY Options,
IN PCWSTR OptionName, IN PCWSTR OptionName,
OUT PWCHAR *OptionValue) OUT PWCHAR *OptionValue)
{ {
PXTBL_CONFIG_ENTRY ConfigEntry; PXTBL_CONFIG_ENTRY ConfigEntry;
PLIST_ENTRY ConfigList; PLIST_ENTRY ConfigList;
@@ -57,11 +90,11 @@ BlGetBootOptionValue(IN PLIST_ENTRY Options,
ValueLength = RTL::WideString::WideStringLength(ConfigEntry->Value, 0); ValueLength = RTL::WideString::WideStringLength(ConfigEntry->Value, 0);
/* Allocate memory for the output value string */ /* Allocate memory for the output value string */
Status = BlAllocateMemoryPool((ValueLength + 1) * sizeof(WCHAR), (PVOID *)OptionValue); Status = Memory::AllocatePool((ValueLength + 1) * sizeof(WCHAR), (PVOID *)OptionValue);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure, print debug message and return status code */ /* Memory allocation failure, print debug message and return status code */
BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status); Debug::Print(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status);
*OptionValue = NULLPTR; *OptionValue = NULLPTR;
return Status; return Status;
} }
@@ -83,36 +116,36 @@ BlGetBootOptionValue(IN PLIST_ENTRY Options,
} }
/** /**
* Returns a boolean value of the specified configuration key. * Retrieves the list of user-editable boot options.
* *
* @param ConfigName * @param OptionsArray
* Specifies the configuration key to return its boolean representation. * A pointer to a variable that will receive the pointer to the array of editable option names.
* *
* @return This routine returns a boolean representation of the configuration value. * @param OptionsCount
* A pointer to a variable that will be updated with the number of elements in the OptionsArray.
*
* @return This routine does not return any value.
* *
* @since XT 1.0 * @since XT 1.0
*/ */
XTCDECL XTCDECL
BOOLEAN VOID
BlGetConfigBooleanValue(IN PCWSTR ConfigName) Configuration::GetEditableOptions(OUT PCWSTR **OptionsArray,
OUT PULONG OptionsCount)
{ {
PWCHAR Value; ULONG Count = 0;
/* Get config value */ /* Return a pointer to the global array of editable options */
BlGetConfigValue(ConfigName, &Value); *OptionsArray = BlpEditableConfigOptions;
/* Check if option is enabled */ /* Calculate the number of elements in the array */
if(RTL::WideString::CompareWideStringInsensitive(Value, L"ENABLED", 0) == 0 || while(BlpEditableConfigOptions[Count])
RTL::WideString::CompareWideStringInsensitive(Value, L"ON", 0) == 0 ||
RTL::WideString::CompareWideStringInsensitive(Value, L"TRUE", 0) == 0 ||
RTL::WideString::CompareWideStringInsensitive(Value, L"YES", 0) == 0)
{ {
/* This option is enabled */ Count++;
return TRUE;
} }
/* Return FALSE by default */ /* Return the number of elements */
return FALSE; *OptionsCount = Count;
} }
/** /**
@@ -127,8 +160,8 @@ BlGetConfigBooleanValue(IN PCWSTR ConfigName)
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlGetConfigValue(IN PCWSTR ConfigName, Configuration::GetValue(IN PCWSTR ConfigName,
OUT PWCHAR *ConfigValue) OUT PWCHAR *ConfigValue)
{ {
PXTBL_CONFIG_ENTRY ConfigEntry; PXTBL_CONFIG_ENTRY ConfigEntry;
PLIST_ENTRY ConfigListEntry; PLIST_ENTRY ConfigListEntry;
@@ -156,11 +189,11 @@ BlGetConfigValue(IN PCWSTR ConfigName,
ValueLength = RTL::WideString::WideStringLength(ConfigEntry->Value, 0); ValueLength = RTL::WideString::WideStringLength(ConfigEntry->Value, 0);
/* Allocate memory for value */ /* Allocate memory for value */
Status = BlAllocateMemoryPool((ValueLength + 1) * sizeof(WCHAR), (PVOID *)&Value); Status = Memory::AllocatePool((ValueLength + 1) * sizeof(WCHAR), (PVOID *)&Value);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure, return NULLPTR */ /* Memory allocation failure, return NULLPTR */
BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status); Debug::Print(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status);
return Status; return Status;
} }
@@ -179,226 +212,6 @@ BlGetConfigValue(IN PCWSTR ConfigName,
return STATUS_EFI_NOT_FOUND; return STATUS_EFI_NOT_FOUND;
} }
/**
* Retrieves the list of user-editable boot options.
*
* @param OptionsArray
* A pointer to a variable that will receive the pointer to the array of editable option names.
*
* @param OptionsCount
* A pointer to a variable that will be updated with the number of elements in the OptionsArray.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
BlGetEditableOptions(OUT PCWSTR **OptionsArray,
OUT PULONG OptionsCount)
{
ULONG Count = 0;
/* Return a pointer to the global array of editable options */
*OptionsArray = BlpEditableConfigOptions;
/* Calculate the number of elements in the array */
while(BlpEditableConfigOptions[Count])
{
Count++;
}
/* Return the number of elements */
*OptionsCount = Count;
}
/**
* Sets the value of a specific OS boot option in a list, or adds it if it doesn't exist.
*
* @param Options
* A pointer to the head of a list of XTBL_CONFIG_ENTRY structures.
*
* @param OptionName
* A pointer to a wide string that contains the name of the boot option to set.
*
* @param OptionValue
* A pointer to a wide string that contains the new value for the boot option.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
BlSetBootOptionValue(IN PLIST_ENTRY Options,
IN PCWSTR OptionName,
IN PCWSTR OptionValue)
{
PXTBL_CONFIG_ENTRY ConfigEntry;
PLIST_ENTRY ConfigList;
ULONG Length;
EFI_STATUS Status;
/* Get the length of the option name we are looking for */
Length = RTL::WideString::WideStringLength(OptionName, 0);
/* Start iterating from the first entry in the options list */
ConfigList = Options->Flink;
while(ConfigList != Options)
{
/* Get the container record for the current config entry */
ConfigEntry = CONTAIN_RECORD(ConfigList, XTBL_CONFIG_ENTRY, Flink);
/* Compare the current entry's name with the requested option name */
if(RTL::WideString::CompareWideStringInsensitive(ConfigEntry->Name, OptionName, Length) == 0)
{
/* Found the option, get its length */
Length = RTL::WideString::WideStringLength(OptionValue, 0);
/* Reallocate memory for the new value */
Status = BlFreeMemoryPool(ConfigEntry->Value);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to free memory, return status code */
return Status;
}
/* Allocate new memory for the updated value */
Status = BlAllocateMemoryPool((Length + 1) * sizeof(WCHAR), (PVOID *)&ConfigEntry->Value);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure, print debug message and return status code */
BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n", Status);
return Status;
}
/* Copy the value and NULL-terminate the new string */
RTL::Memory::CopyMemory(ConfigEntry->Value, OptionValue, Length * sizeof(WCHAR));
ConfigEntry->Value[Length] = L'\0';
return STATUS_EFI_SUCCESS;
}
/* Move to the next entry in the list */
ConfigList = ConfigList->Flink;
}
/* Option not found, allocate memory for the new one */
Status = BlAllocateMemoryPool(sizeof(XTBL_CONFIG_ENTRY), (PVOID *)&ConfigEntry);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure, print debug message and return status code */
BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n", Status);
return Status;
}
/* Allocate memory for the option name */
Length = RTL::WideString::WideStringLength(OptionName, 0);
Status = BlAllocateMemoryPool((Length + 1) * sizeof(WCHAR), (PVOID *)&ConfigEntry->Name);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure, print debug message and return status code */
BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n", Status);
BlFreeMemoryPool(ConfigEntry);
return Status;
}
/* Copy the option name and NULL-terminate the new string */
RTL::Memory::CopyMemory(ConfigEntry->Name, OptionName, Length * sizeof(WCHAR));
ConfigEntry->Name[Length] = L'\0';
/* Allocate memory for the option value */
Length = RTL::WideString::WideStringLength(OptionValue, 0);
Status = BlAllocateMemoryPool((Length + 1) * sizeof(WCHAR), (PVOID *)&ConfigEntry->Value);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure, print debug message and return status code */
BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n", Status);
BlFreeMemoryPool(ConfigEntry->Name);
BlFreeMemoryPool(ConfigEntry);
return Status;
}
/* Copy the value and NULL-terminate the new string */
RTL::Memory::CopyMemory(ConfigEntry->Value, OptionValue, Length * sizeof(WCHAR));
ConfigEntry->Value[Length] = L'\0';
/* Insert the new config entry at the end of the options list */
RTL::LinkedList::InsertTailList(Options, &ConfigEntry->Flink);
/* Return success */
return STATUS_EFI_SUCCESS;
}
/**
* Updates existing configuration value.
*
* @param ConfigName
* Specifies the configuration key to update.
*
* @param ConfigValue
* Specifies the new configuration value.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
BlSetConfigValue(IN PCWSTR ConfigName,
IN PCWSTR ConfigValue)
{
PXTBL_CONFIG_ENTRY ConfigEntry;
PLIST_ENTRY ConfigListEntry;
EFI_STATUS Status;
SIZE_T Length;
/* Get config entry name length */
Length = RTL::WideString::WideStringLength(ConfigName, 0);
/* Iterate through config entries */
ConfigListEntry = BlpConfig.Flink;
while(ConfigListEntry != &BlpConfig)
{
/* Get config entry */
ConfigEntry = CONTAIN_RECORD(ConfigListEntry, XTBL_CONFIG_ENTRY, Flink);
/* Check if requested configuration found */
if(RTL::WideString::CompareWideStringInsensitive(ConfigEntry->Name, ConfigName, Length) == 0)
{
/* Check new config value length */
Length = RTL::WideString::WideStringLength(ConfigValue, 0);
/* Reallocate memory for new config value */
Status = BlFreeMemoryPool(ConfigEntry->Value);
if(Status == STATUS_EFI_SUCCESS)
{
/* Successfully freed memory, allocate a new pool */
Status = BlAllocateMemoryPool((Length + 1) * sizeof(WCHAR), (PVOID *)&ConfigEntry->Value);
}
/* Check memory reallocation status */
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to reallocate memory */
return Status;
}
/* Update config value */
RTL::Memory::CopyMemory(ConfigEntry->Value, ConfigValue, Length * sizeof(WCHAR));
ConfigEntry->Value[Length] = L'\0';
/* Return success */
return STATUS_EFI_SUCCESS;
}
/* Move to the next config entry */
ConfigListEntry = ConfigListEntry->Flink;
}
/* Config entry not found */
return STATUS_EFI_NOT_FOUND;
}
/** /**
* Loads and parses XTLDR configuration file. * Loads and parses XTLDR configuration file.
* *
@@ -408,7 +221,7 @@ BlSetConfigValue(IN PCWSTR ConfigName,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlpLoadConfiguration() Configuration::LoadConfiguration()
{ {
PLIST_ENTRY SectionListEntry; PLIST_ENTRY SectionListEntry;
EFI_STATUS Status; EFI_STATUS Status;
@@ -418,27 +231,27 @@ BlpLoadConfiguration()
RTL::LinkedList::InitializeListHead(&BlpConfigSections); RTL::LinkedList::InitializeListHead(&BlpConfigSections);
/* Read data from configuration file */ /* Read data from configuration file */
Status = BlpReadConfigFile(XTBL_LOADER_DIRECTORY_PATH, L"XTLDR.INI", &ConfigData); Status = ReadConfigFile(XTBL_LOADER_DIRECTORY_PATH, L"XTLDR.INI", &ConfigData);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to read config file, try with architecture specific directory */ /* Failed to read config file, try with architecture specific directory */
Status = BlpReadConfigFile(XTBL_ARCH_LOADER_DIRECTORY_PATH, L"XTLDR.INI", &ConfigData); Status = ReadConfigFile(XTBL_ARCH_LOADER_DIRECTORY_PATH, L"XTLDR.INI", &ConfigData);
} }
/* Check if configuration was read successfully */ /* Check if configuration was read successfully */
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to load configuration */ /* Failed to load configuration */
BlDebugPrint(L"Failed to load FS0:/EFI/BOOT/XTLDR/XTLDR.INI configuration file (Status Code: 0x%zX)\n", Status); Debug::Print(L"Failed to load FS0:/EFI/BOOT/XTLDR/XTLDR.INI configuration file (Status Code: 0x%zX)\n", Status);
return Status; return Status;
} }
/* Parse configuration data */ /* Parse configuration data */
Status = BlpParseConfigFile(ConfigData, &BlpConfigSections); Status = ParseConfigFile(ConfigData, &BlpConfigSections);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to parse configuration */ /* Failed to parse configuration */
BlDebugPrint(L"Failed to parse FS0:/EFI/BOOT/XTLDR/XTLDR.INI configuration file (Status Code: 0x%zX)\n", Status); Debug::Print(L"Failed to parse FS0:/EFI/BOOT/XTLDR/XTLDR.INI configuration file (Status Code: 0x%zX)\n", Status);
return Status; return Status;
} }
@@ -453,7 +266,7 @@ BlpLoadConfiguration()
if(RTL::WideString::CompareWideStringInsensitive(Section->SectionName, L"XTLDR", 5) == 0) if(RTL::WideString::CompareWideStringInsensitive(Section->SectionName, L"XTLDR", 5) == 0)
{ {
/* Update global configuration */ /* Update global configuration */
BlpUpdateConfiguration(&Section->Options); UpdateConfiguration(&Section->Options);
/* Remove XTLDR section from the list */ /* Remove XTLDR section from the list */
RTL::LinkedList::RemoveEntryList(SectionListEntry); RTL::LinkedList::RemoveEntryList(SectionListEntry);
@@ -480,7 +293,7 @@ BlpLoadConfiguration()
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlpParseCommandLine(VOID) Configuration::ParseCommandLine(VOID)
{ {
EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
PEFI_LOADED_IMAGE_PROTOCOL LoadedImage; PEFI_LOADED_IMAGE_PROTOCOL LoadedImage;
@@ -546,15 +359,15 @@ BlpParseCommandLine(VOID)
} }
/* Allocate memory for new option */ /* Allocate memory for new option */
Status = BlAllocateMemoryPool(sizeof(XTBL_CONFIG_ENTRY), (PVOID*)&Option); Status = Memory::AllocatePool(sizeof(XTBL_CONFIG_ENTRY), (PVOID*)&Option);
if(Status == STATUS_EFI_SUCCESS) if(Status == STATUS_EFI_SUCCESS)
{ {
/* Allocate more memory for option name */ /* Allocate more memory for option name */
Status = BlAllocateMemoryPool(sizeof(WCHAR) * (KeyLength + 1), (PVOID*)&Option->Name); Status = Memory::AllocatePool(sizeof(WCHAR) * (KeyLength + 1), (PVOID*)&Option->Name);
if(Status == STATUS_EFI_SUCCESS) if(Status == STATUS_EFI_SUCCESS)
{ {
/* Allocate even more memory for option value */ /* Allocate even more memory for option value */
Status = BlAllocateMemoryPool(sizeof(WCHAR) * (ValueLength + 1), (PVOID*)&Option->Value); Status = Memory::AllocatePool(sizeof(WCHAR) * (ValueLength + 1), (PVOID*)&Option->Value);
} }
} }
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
@@ -577,7 +390,7 @@ BlpParseCommandLine(VOID)
} }
/* Update global configuration */ /* Update global configuration */
BlpUpdateConfiguration(&Config); UpdateConfiguration(&Config);
} }
} }
@@ -600,8 +413,8 @@ BlpParseCommandLine(VOID)
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlpParseConfigFile(IN CONST PCHAR RawConfig, Configuration::ParseConfigFile(IN CONST PCHAR RawConfig,
OUT PLIST_ENTRY Configuration) OUT PLIST_ENTRY Configuration)
{ {
SIZE_T SectionLength, KeyLength, ValueLength; SIZE_T SectionLength, KeyLength, ValueLength;
PCHAR InputData, Key, SectionName, Value; PCHAR InputData, Key, SectionName, Value;
@@ -667,11 +480,11 @@ BlpParseConfigFile(IN CONST PCHAR RawConfig,
SectionLength = RTL::String::StringLength(SectionName, 0); SectionLength = RTL::String::StringLength(SectionName, 0);
/* Allocate memory for new section */ /* Allocate memory for new section */
Status = BlAllocateMemoryPool(sizeof(XTBL_CONFIG_SECTION), (PVOID*)&Section); Status = Memory::AllocatePool(sizeof(XTBL_CONFIG_SECTION), (PVOID*)&Section);
if(Status == STATUS_EFI_SUCCESS) if(Status == STATUS_EFI_SUCCESS)
{ {
/* Allocate more memory for section name */ /* Allocate more memory for section name */
Status = BlAllocateMemoryPool(sizeof(WCHAR) * (SectionLength + 1), (PVOID*)&Section->SectionName); Status = Memory::AllocatePool(sizeof(WCHAR) * (SectionLength + 1), (PVOID*)&Section->SectionName);
} }
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
@@ -740,15 +553,15 @@ BlpParseConfigFile(IN CONST PCHAR RawConfig,
ValueLength = RTL::String::StringLength(Value, 0); ValueLength = RTL::String::StringLength(Value, 0);
/* Allocate memory for new option */ /* Allocate memory for new option */
Status = BlAllocateMemoryPool(sizeof(XTBL_CONFIG_ENTRY), (PVOID*)&Option); Status = Memory::AllocatePool(sizeof(XTBL_CONFIG_ENTRY), (PVOID*)&Option);
if(Status == STATUS_EFI_SUCCESS) if(Status == STATUS_EFI_SUCCESS)
{ {
/* Allocate more memory for option name */ /* Allocate more memory for option name */
Status = BlAllocateMemoryPool(sizeof(WCHAR) * (KeyLength + 1), (PVOID*)&Option->Name); Status = Memory::AllocatePool(sizeof(WCHAR) * (KeyLength + 1), (PVOID*)&Option->Name);
if(Status == STATUS_EFI_SUCCESS) if(Status == STATUS_EFI_SUCCESS)
{ {
/* Allocate even more memory for option value */ /* Allocate even more memory for option value */
Status = BlAllocateMemoryPool(sizeof(WCHAR) * (ValueLength + 1), (PVOID*)&Option->Value); Status = Memory::AllocatePool(sizeof(WCHAR) * (ValueLength + 1), (PVOID*)&Option->Value);
} }
} }
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
@@ -802,9 +615,9 @@ BlpParseConfigFile(IN CONST PCHAR RawConfig,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlpReadConfigFile(IN PCWSTR ConfigDirectory, Configuration::ReadConfigFile(IN PCWSTR ConfigDirectory,
IN PCWSTR ConfigFile, IN PCWSTR ConfigFile,
OUT PCHAR *ConfigData) OUT PCHAR *ConfigData)
{ {
PEFI_FILE_HANDLE DirHandle, FsHandle; PEFI_FILE_HANDLE DirHandle, FsHandle;
EFI_HANDLE DiskHandle; EFI_HANDLE DiskHandle;
@@ -812,7 +625,7 @@ BlpReadConfigFile(IN PCWSTR ConfigDirectory,
SIZE_T FileSize; SIZE_T FileSize;
/* Open EFI volume */ /* Open EFI volume */
Status = BlOpenVolume(NULLPTR, &DiskHandle, &FsHandle); Status = Volume::OpenVolume(NULLPTR, &DiskHandle, &FsHandle);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to open a volume */ /* Failed to open a volume */
@@ -827,21 +640,209 @@ BlpReadConfigFile(IN PCWSTR ConfigDirectory,
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to open directory */ /* Failed to open directory */
BlCloseVolume(&DiskHandle); Volume::CloseVolume(&DiskHandle);
return Status; return Status;
} }
/* Read configuration file and close directory */ /* Read configuration file and close directory */
Status = BlReadFile(DirHandle, ConfigFile, (PVOID *)ConfigData, &FileSize); Status = Volume::ReadFile(DirHandle, ConfigFile, (PVOID *)ConfigData, &FileSize);
DirHandle->Close(DirHandle); DirHandle->Close(DirHandle);
/* Close EFI volume */ /* Close EFI volume */
BlCloseVolume(&DiskHandle); Volume::CloseVolume(&DiskHandle);
/* Return read status */ /* Return read status */
return Status; return Status;
} }
/**
* Sets the value of a specific OS boot option in a list, or adds it if it doesn't exist.
*
* @param Options
* A pointer to the head of a list of XTBL_CONFIG_ENTRY structures.
*
* @param OptionName
* A pointer to a wide string that contains the name of the boot option to set.
*
* @param OptionValue
* A pointer to a wide string that contains the new value for the boot option.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
Configuration::SetBootOptionValue(IN PLIST_ENTRY Options,
IN PCWSTR OptionName,
IN PCWSTR OptionValue)
{
PXTBL_CONFIG_ENTRY ConfigEntry;
PLIST_ENTRY ConfigList;
ULONG Length;
EFI_STATUS Status;
/* Get the length of the option name we are looking for */
Length = RTL::WideString::WideStringLength(OptionName, 0);
/* Start iterating from the first entry in the options list */
ConfigList = Options->Flink;
while(ConfigList != Options)
{
/* Get the container record for the current config entry */
ConfigEntry = CONTAIN_RECORD(ConfigList, XTBL_CONFIG_ENTRY, Flink);
/* Compare the current entry's name with the requested option name */
if(RTL::WideString::CompareWideStringInsensitive(ConfigEntry->Name, OptionName, Length) == 0)
{
/* Found the option, get its length */
Length = RTL::WideString::WideStringLength(OptionValue, 0);
/* Reallocate memory for the new value */
Status = Memory::FreePool(ConfigEntry->Value);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to free memory, return status code */
return Status;
}
/* Allocate new memory for the updated value */
Status = Memory::AllocatePool((Length + 1) * sizeof(WCHAR), (PVOID *)&ConfigEntry->Value);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure, print debug message and return status code */
Debug::Print(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n", Status);
return Status;
}
/* Copy the value and NULL-terminate the new string */
RTL::Memory::CopyMemory(ConfigEntry->Value, OptionValue, Length * sizeof(WCHAR));
ConfigEntry->Value[Length] = L'\0';
return STATUS_EFI_SUCCESS;
}
/* Move to the next entry in the list */
ConfigList = ConfigList->Flink;
}
/* Option not found, allocate memory for the new one */
Status = Memory::AllocatePool(sizeof(XTBL_CONFIG_ENTRY), (PVOID *)&ConfigEntry);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure, print debug message and return status code */
Debug::Print(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n", Status);
return Status;
}
/* Allocate memory for the option name */
Length = RTL::WideString::WideStringLength(OptionName, 0);
Status = Memory::AllocatePool((Length + 1) * sizeof(WCHAR), (PVOID *)&ConfigEntry->Name);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure, print debug message and return status code */
Debug::Print(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n", Status);
Memory::FreePool(ConfigEntry);
return Status;
}
/* Copy the option name and NULL-terminate the new string */
RTL::Memory::CopyMemory(ConfigEntry->Name, OptionName, Length * sizeof(WCHAR));
ConfigEntry->Name[Length] = L'\0';
/* Allocate memory for the option value */
Length = RTL::WideString::WideStringLength(OptionValue, 0);
Status = Memory::AllocatePool((Length + 1) * sizeof(WCHAR), (PVOID *)&ConfigEntry->Value);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure, print debug message and return status code */
Debug::Print(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\\n", Status);
Memory::FreePool(ConfigEntry->Name);
Memory::FreePool(ConfigEntry);
return Status;
}
/* Copy the value and NULL-terminate the new string */
RTL::Memory::CopyMemory(ConfigEntry->Value, OptionValue, Length * sizeof(WCHAR));
ConfigEntry->Value[Length] = L'\0';
/* Insert the new config entry at the end of the options list */
RTL::LinkedList::InsertTailList(Options, &ConfigEntry->Flink);
/* Return success */
return STATUS_EFI_SUCCESS;
}
/**
* Updates existing configuration value.
*
* @param ConfigName
* Specifies the configuration key to update.
*
* @param ConfigValue
* Specifies the new configuration value.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
Configuration::SetValue(IN PCWSTR ConfigName,
IN PCWSTR ConfigValue)
{
PXTBL_CONFIG_ENTRY ConfigEntry;
PLIST_ENTRY ConfigListEntry;
EFI_STATUS Status;
SIZE_T Length;
/* Get config entry name length */
Length = RTL::WideString::WideStringLength(ConfigName, 0);
/* Iterate through config entries */
ConfigListEntry = BlpConfig.Flink;
while(ConfigListEntry != &BlpConfig)
{
/* Get config entry */
ConfigEntry = CONTAIN_RECORD(ConfigListEntry, XTBL_CONFIG_ENTRY, Flink);
/* Check if requested configuration found */
if(RTL::WideString::CompareWideStringInsensitive(ConfigEntry->Name, ConfigName, Length) == 0)
{
/* Check new config value length */
Length = RTL::WideString::WideStringLength(ConfigValue, 0);
/* Reallocate memory for new config value */
Status = Memory::FreePool(ConfigEntry->Value);
if(Status == STATUS_EFI_SUCCESS)
{
/* Successfully freed memory, allocate a new pool */
Status = Memory::AllocatePool((Length + 1) * sizeof(WCHAR), (PVOID *)&ConfigEntry->Value);
}
/* Check memory reallocation status */
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to reallocate memory */
return Status;
}
/* Update config value */
RTL::Memory::CopyMemory(ConfigEntry->Value, ConfigValue, Length * sizeof(WCHAR));
ConfigEntry->Value[Length] = L'\0';
/* Return success */
return STATUS_EFI_SUCCESS;
}
/* Move to the next config entry */
ConfigListEntry = ConfigListEntry->Flink;
}
/* Config entry not found */
return STATUS_EFI_NOT_FOUND;
}
/** /**
* Adds new XTLDR configuration entries to the global configuration list. Existing entries are not overwritten. * Adds new XTLDR configuration entries to the global configuration list. Existing entries are not overwritten.
* *
@@ -854,7 +855,7 @@ BlpReadConfigFile(IN PCWSTR ConfigDirectory,
*/ */
XTCDECL XTCDECL
VOID VOID
BlpUpdateConfiguration(IN PLIST_ENTRY NewConfig) Configuration::UpdateConfiguration(IN PLIST_ENTRY NewConfig)
{ {
PXTBL_CONFIG_ENTRY ConfigEntry; PXTBL_CONFIG_ENTRY ConfigEntry;
PWCHAR ConfigValue; PWCHAR ConfigValue;
@@ -871,7 +872,7 @@ BlpUpdateConfiguration(IN PLIST_ENTRY NewConfig)
NextListEntry = ConfigListEntry->Flink; NextListEntry = ConfigListEntry->Flink;
/* Make sure config entry does not exist yet */ /* Make sure config entry does not exist yet */
BlGetConfigValue(ConfigEntry->Name, &ConfigValue); GetValue(ConfigEntry->Name, &ConfigValue);
if(ConfigValue == NULLPTR) if(ConfigValue == NULLPTR)
{ {
/* Remove new config entry from input list and put it into global config list */ /* Remove new config entry from input list and put it into global config list */

View File

@@ -21,19 +21,19 @@
*/ */
XTCDECL XTCDECL
VOID VOID
BlClearConsoleLine(IN ULONGLONG LineNo) Console::ClearLine(IN ULONGLONG LineNo)
{ {
UINT_PTR Index, ResX, ResY; UINT_PTR Index, ResX, ResY;
/* Query console mode */ /* Query console mode */
BlQueryConsoleMode(&ResX, &ResY); QueryMode(&ResX, &ResY);
/* Set cursor position and clear line */ /* Set cursor position and clear line */
BlSetCursorPosition(0, LineNo); SetCursorPosition(0, LineNo);
for(Index = 0; Index < ResX; Index++) for(Index = 0; Index < ResX; Index++)
{ {
/* Clear line */ /* Clear line */
BlConsoleWrite(L" "); Write(L" ");
} }
} }
@@ -46,7 +46,7 @@ BlClearConsoleLine(IN ULONGLONG LineNo)
*/ */
XTCDECL XTCDECL
VOID VOID
BlClearConsoleScreen() Console::ClearScreen()
{ {
/* Clear screen */ /* Clear screen */
EfiSystemTable->ConOut->ClearScreen(EfiSystemTable->ConOut); EfiSystemTable->ConOut->ClearScreen(EfiSystemTable->ConOut);
@@ -61,7 +61,7 @@ BlClearConsoleScreen()
*/ */
XTCDECL XTCDECL
VOID VOID
BlDisableConsoleCursor() Console::DisableCursor()
{ {
EfiSystemTable->ConOut->EnableCursor(EfiSystemTable->ConOut, FALSE); EfiSystemTable->ConOut->EnableCursor(EfiSystemTable->ConOut, FALSE);
} }
@@ -75,11 +75,41 @@ BlDisableConsoleCursor()
*/ */
XTCDECL XTCDECL
VOID VOID
BlEnableConsoleCursor() Console::EnableCursor()
{ {
EfiSystemTable->ConOut->EnableCursor(EfiSystemTable->ConOut, TRUE); EfiSystemTable->ConOut->EnableCursor(EfiSystemTable->ConOut, TRUE);
} }
/**
* This routine initializes the EFI console.
*
* @return This routine returns status code.
*
* @since XT 1.0
*/
XTCDECL
VOID
Console::InitializeConsole()
{
/* Clear console buffers */
EfiSystemTable->ConIn->Reset(EfiSystemTable->ConIn, TRUE);
EfiSystemTable->ConOut->Reset(EfiSystemTable->ConOut, TRUE);
EfiSystemTable->StdErr->Reset(EfiSystemTable->StdErr, TRUE);
/* Make sure that current console mode is 80x25 characters, as some broken EFI implementations might
* set different mode that do not fit on the screen, causing a text to be displayed offscreen */
if(EfiSystemTable->ConOut->Mode->Mode != 0)
{
/* Set console mode to 0, which is standard, 80x25 text mode */
SetMode(0);
}
/* Clear screen and enable cursor */
SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY);
ClearScreen();
EnableCursor();
}
/** /**
* This routine formats the input string and prints it out to the stdout and serial console. * This routine formats the input string and prints it out to the stdout and serial console.
* *
@@ -95,15 +125,15 @@ BlEnableConsoleCursor()
*/ */
XTCDECL XTCDECL
VOID VOID
BlConsolePrint(IN PCWSTR Format, Console::Print(IN PCWSTR Format,
IN ...) IN ...)
{ {
RTL_PRINT_CONTEXT ConsolePrintContext, SerialPrintContext; RTL_PRINT_CONTEXT ConsolePrintContext, SerialPrintContext;
VA_LIST Arguments; VA_LIST Arguments;
/* Initialise the print contexts */ /* Initialise the print contexts */
ConsolePrintContext.WriteWideCharacter = BlpConsolePutChar; ConsolePrintContext.WriteWideCharacter = PutChar;
SerialPrintContext.WriteWideCharacter = BlpDebugPutChar; SerialPrintContext.WriteWideCharacter = Debug::PutChar;
/* Initialise the va_list */ /* Initialise the va_list */
VA_START(Arguments, Format); VA_START(Arguments, Format);
@@ -127,50 +157,35 @@ BlConsolePrint(IN PCWSTR Format,
} }
/** /**
* Displays the string on the device at the current cursor location. * Writes a character to the default EFI console.
* *
* @param String * @param Character
* The string to be displayed. * The integer promotion of the character to be written.
* *
* @return This routine does not return any value. * @return This routine returns a status code.
* *
* @since XT 1.0 * @since XT 1.0
*/ */
XTCDECL XTCDECL
VOID XTSTATUS
BlConsoleWrite(IN PCWSTR String) Console::PutChar(IN WCHAR Character)
{ {
EfiSystemTable->ConOut->OutputString(EfiSystemTable->ConOut, (PWSTR)String); WCHAR Buffer[2];
}
/** /* Check if character is a newline ('\n') */
* This routine initializes the EFI console. if(Character == L'\n')
*
* @return This routine returns status code.
*
* @since XT 1.0
*/
XTCDECL
VOID
BlInitializeConsole()
{
/* Clear console buffers */
EfiSystemTable->ConIn->Reset(EfiSystemTable->ConIn, TRUE);
EfiSystemTable->ConOut->Reset(EfiSystemTable->ConOut, TRUE);
EfiSystemTable->StdErr->Reset(EfiSystemTable->StdErr, TRUE);
/* Make sure that current console mode is 80x25 characters, as some broken EFI implementations might
* set different mode that do not fit on the screen, causing a text to be displayed offscreen */
if(EfiSystemTable->ConOut->Mode->Mode != 0)
{ {
/* Set console mode to 0, which is standard, 80x25 text mode */ /* Print carriage return ('\r') as well */
BlSetConsoleMode(0); PutChar(L'\r');
} }
/* Clear screen and enable cursor */ /* Write character to the screen console */
BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); Buffer[0] = Character;
BlClearConsoleScreen(); Buffer[1] = 0;
BlEnableConsoleCursor(); EfiSystemTable->ConOut->OutputString(EfiSystemTable->ConOut, Buffer);
/* Return success */
return STATUS_SUCCESS;
} }
/** /**
@@ -188,7 +203,7 @@ BlInitializeConsole()
*/ */
XTCDECL XTCDECL
VOID VOID
BlQueryConsoleMode(OUT PUINT_PTR ResX, Console::QueryMode(OUT PUINT_PTR ResX,
OUT PUINT_PTR ResY) OUT PUINT_PTR ResY)
{ {
EfiSystemTable->ConOut->QueryMode(EfiSystemTable->ConOut, EfiSystemTable->ConOut->Mode->Mode, ResX, ResY); EfiSystemTable->ConOut->QueryMode(EfiSystemTable->ConOut, EfiSystemTable->ConOut->Mode->Mode, ResX, ResY);
@@ -206,7 +221,7 @@ BlQueryConsoleMode(OUT PUINT_PTR ResX,
*/ */
XTCDECL XTCDECL
VOID VOID
BlReadKeyStroke(OUT PEFI_INPUT_KEY Key) Console::ReadKeyStroke(OUT PEFI_INPUT_KEY Key)
{ {
EfiSystemTable->ConIn->ReadKeyStroke(EfiSystemTable->ConIn, Key); EfiSystemTable->ConIn->ReadKeyStroke(EfiSystemTable->ConIn, Key);
} }
@@ -220,7 +235,7 @@ BlReadKeyStroke(OUT PEFI_INPUT_KEY Key)
*/ */
XTCDECL XTCDECL
VOID VOID
BlResetConsoleInputBuffer() Console::ResetInputBuffer()
{ {
EfiSystemTable->ConIn->Reset(EfiSystemTable->ConIn, FALSE); EfiSystemTable->ConIn->Reset(EfiSystemTable->ConIn, FALSE);
} }
@@ -237,28 +252,11 @@ BlResetConsoleInputBuffer()
*/ */
XTCDECL XTCDECL
VOID VOID
BlSetConsoleAttributes(IN ULONGLONG Attributes) Console::SetAttributes(IN ULONGLONG Attributes)
{ {
EfiSystemTable->ConOut->SetAttribute(EfiSystemTable->ConOut, Attributes); EfiSystemTable->ConOut->SetAttribute(EfiSystemTable->ConOut, Attributes);
} }
/**
* Sets the output console device to the requested mode.
*
* @param Mode
* Supplies a text mode number to set.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
BlSetConsoleMode(IN ULONGLONG Mode)
{
return EfiSystemTable->ConOut->SetMode(EfiSystemTable->ConOut, Mode);
}
/** /**
* Sets new coordinates of the console cursor position. * Sets new coordinates of the console cursor position.
* *
@@ -274,40 +272,42 @@ BlSetConsoleMode(IN ULONGLONG Mode)
*/ */
XTCDECL XTCDECL
VOID VOID
BlSetCursorPosition(IN ULONGLONG PosX, Console::SetCursorPosition(IN ULONGLONG PosX,
IN ULONGLONG PosY) IN ULONGLONG PosY)
{ {
EfiSystemTable->ConOut->SetCursorPosition(EfiSystemTable->ConOut, PosX, PosY); EfiSystemTable->ConOut->SetCursorPosition(EfiSystemTable->ConOut, PosX, PosY);
} }
/** /**
* Writes a character to the default EFI console. * Sets the output console device to the requested mode.
* *
* @param Character * @param Mode
* The integer promotion of the character to be written. * Supplies a text mode number to set.
* *
* @return This routine returns a status code. * @return This routine returns a status code.
* *
* @since XT 1.0 * @since XT 1.0
*/ */
XTCDECL XTCDECL
XTSTATUS EFI_STATUS
BlpConsolePutChar(IN WCHAR Character) Console::SetMode(IN ULONGLONG Mode)
{ {
WCHAR Buffer[2]; return EfiSystemTable->ConOut->SetMode(EfiSystemTable->ConOut, Mode);
}
/* Check if character is a newline ('\n') */
if(Character == L'\n') /**
{ * Displays the string on the device at the current cursor location.
/* Print carriage return ('\r') as well */ *
BlpConsolePutChar(L'\r'); * @param String
} * The string to be displayed.
*
/* Write character to the screen console */ * @return This routine does not return any value.
Buffer[0] = Character; *
Buffer[1] = 0; * @since XT 1.0
EfiSystemTable->ConOut->OutputString(EfiSystemTable->ConOut, Buffer); */
XTCDECL
/* Return success */ VOID
return STATUS_SUCCESS; Console::Write(IN PCWSTR String)
{
EfiSystemTable->ConOut->OutputString(EfiSystemTable->ConOut, (PWSTR)String);
} }

View File

@@ -10,75 +10,105 @@
/** /**
* This routine formats the input string and prints it out to the debug ports. * Enables I/O space access to all serial controllers found on the PCI(E) root bridge.
*
* @param Format
* The formatted string that is to be written to the output.
*
* @param ...
* Depending on the format string, this routine might expect a sequence of additional arguments.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
BlDebugPrint(IN PCWSTR Format,
IN ...)
{
RTL_PRINT_CONTEXT ConsolePrintContext, SerialPrintContext;
VA_LIST Arguments;
/* Check if debugging enabled and if EFI serial port is fully initialized */
if(DEBUG)
{
/* Initialize the print contexts */
ConsolePrintContext.WriteWideCharacter = BlpConsolePutChar;
SerialPrintContext.WriteWideCharacter = BlpDebugPutChar;
/* Initialise the va_list */
VA_START(Arguments, Format);
/* Check if serial debug port is enabled */
if((BlpStatus.DebugPort & XTBL_DEBUGPORT_SERIAL) && (BlpStatus.SerialPort.Flags & COMPORT_FLAG_INIT))
{
/* Format and print the string to the serial console */
RTL::WideString::FormatWideString(&SerialPrintContext, (PWCHAR)Format, Arguments);
}
/* Check if screen debug port is enabled and Boot Services are still available */
if((BlpStatus.DebugPort & XTBL_DEBUGPORT_SCREEN) && (BlpStatus.BootServices == TRUE))
{
/* Format and print the string to the screen */
RTL::WideString::FormatWideString(&ConsolePrintContext, (PWCHAR)Format, Arguments);
}
/* Clean up the va_list */
VA_END(Arguments);
}
}
/**
* Writes a character to the serial console.
*
* @param Character
* The integer promotion of the character to be written.
* *
* @return This routine returns a status code. * @return This routine returns a status code.
* *
* @since XT 1.0 * @since XT 1.0
*/ */
XTCDECL XTCDECL
XTSTATUS EFI_STATUS
BlpDebugPutChar(IN WCHAR Character) Debug::ActivateSerialIOController()
{ {
WCHAR Buffer[2]; EFI_GUID PciGuid = EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID;
PEFI_PCI_ROOT_BRIDGE_IO_PROTOCOL PciDev;
USHORT Bus, Device, Function, Command;
UINT_PTR Index, PciHandleSize;
PEFI_HANDLE PciHandle = NULLPTR;
PCI_COMMON_HEADER PciHeader;
EFI_STATUS Status;
ULONGLONG Address;
/* Write character to the serial console */ /* Allocate memory for single EFI_HANDLE, what should be enough in most cases */
Buffer[0] = Character; PciHandleSize = sizeof(EFI_HANDLE);
Buffer[1] = 0; Status = Memory::AllocatePool(PciHandleSize, (PVOID*)&PciHandle);
return HL::ComPort::WriteComPort(&BlpStatus.SerialPort, Buffer[0]); if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure */
return Status;
}
/* Get all instances of PciRootBridgeIo */
Status = EfiSystemTable->BootServices->LocateHandle(ByProtocol, &PciGuid, NULLPTR, &PciHandleSize, PciHandle);
if(Status == STATUS_EFI_BUFFER_TOO_SMALL)
{
/* Reallocate more memory as requested by UEFI */
Memory::FreePool(PciHandle);
Status = Memory::AllocatePool(PciHandleSize, (PVOID*)&PciHandle);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory reallocation failure */
return Status;
}
/* Second attempt to get instances of PciRootBridgeIo */
Status = EfiSystemTable->BootServices->LocateHandle(ByProtocol, &PciGuid, NULLPTR, &PciHandleSize, PciHandle);
}
/* Make sure successfully obtained PciRootBridgeIo instances */
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to get PciRootBridgeIo instances */
return Status;
}
/* Enumerate all devices for each handle, which decides a segment and a bus number range */
for(Index = 0; Index < (PciHandleSize / sizeof(EFI_HANDLE)); Index++)
{
/* Get inferface from the protocol */
Status = EfiSystemTable->BootServices->HandleProtocol(PciHandle[Index], &PciGuid, (PVOID*)&PciDev);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to get interface */
return Status;
}
/* Enumerate whole PCI bridge */
for(Bus = 0; Bus <= PCI_MAX_BRIDGE_NUMBER; Bus++)
{
/* Enumerate all devices for each bus */
for(Device = 0; Device < PCI_MAX_DEVICES; Device++)
{
/* Enumerate all functions for each devices */
for(Function = 0; Function < PCI_MAX_FUNCTION; Function++)
{
/* Read configuration space */
Address = ((ULONGLONG)((((UINT_PTR) Bus) << 24) + (((UINT_PTR) Device) << 16) +
(((UINT_PTR) Function) << 8) + ((UINT_PTR) 0)));
PciDev->Pci.Read(PciDev, EfiPciIoWidthUint32, Address, sizeof (PciHeader) / sizeof (UINT), &PciHeader);
/* Check if device exists */
if(PciHeader.VendorId == PCI_INVALID_VENDORID)
{
/* Skip non-existen device */
continue;
}
/* Check if device is serial controller or multiport serial controller */
if(PciHeader.BaseClass == 0x07 && (PciHeader.SubClass == 0x00 || PciHeader.SubClass == 0x02))
{
/* Enable I/O space access */
Address |= 0x4;
Command = PCI_ENABLE_IO_SPACE;
Status = PciDev->Pci.Write(PciDev, EfiPciIoWidthUint16, Address, 1, &Command);
}
}
}
}
}
/* Return SUCCESS */
return STATUS_EFI_SUCCESS;
} }
/** /**
@@ -90,7 +120,7 @@ BlpDebugPutChar(IN WCHAR Character)
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlpInitializeDebugConsole() Debug::InitializeDebugConsole()
{ {
ULONG PortAddress, PortNumber, BaudRate; ULONG PortAddress, PortNumber, BaudRate;
PWCHAR DebugConfiguration, DebugPort, LastPort; PWCHAR DebugConfiguration, DebugPort, LastPort;
@@ -102,7 +132,7 @@ BlpInitializeDebugConsole()
BaudRate = 0; BaudRate = 0;
/* Get debug configuration */ /* Get debug configuration */
BlGetConfigValue(L"DEBUG", &DebugConfiguration); Configuration::GetValue(L"DEBUG", &DebugConfiguration);
/* Make sure any debug options are provided and debug console is not initialized yet */ /* Make sure any debug options are provided and debug console is not initialized yet */
if(DebugConfiguration && BlpStatus.DebugPort == 0) if(DebugConfiguration && BlpStatus.DebugPort == 0)
@@ -178,8 +208,8 @@ BlpInitializeDebugConsole()
else else
{ {
/* Unsupported debug port specified */ /* Unsupported debug port specified */
BlConsolePrint(L"ERROR: Unsupported debug port ('%S') specified\n", DebugPort); Console::Print(L"ERROR: Unsupported debug port ('%S') specified\n", DebugPort);
BlSleepExecution(3000); EfiUtils::SleepExecution(3000);
} }
/* Take next debug port */ /* Take next debug port */
@@ -190,7 +220,7 @@ BlpInitializeDebugConsole()
if(BlpStatus.DebugPort & XTBL_DEBUGPORT_SERIAL) if(BlpStatus.DebugPort & XTBL_DEBUGPORT_SERIAL)
{ {
/* Try to initialize COM port */ /* Try to initialize COM port */
Status = BlpInitializeSerialPort(PortNumber, PortAddress, BaudRate); Status = InitializeSerialPort(PortNumber, PortAddress, BaudRate);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Remove serial debug port, as COM port initialization failed and return */ /* Remove serial debug port, as COM port initialization failed and return */
@@ -222,9 +252,9 @@ BlpInitializeDebugConsole()
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlpInitializeSerialPort(IN ULONG PortNumber, Debug::InitializeSerialPort(IN ULONG PortNumber,
IN ULONG PortAddress, IN ULONG PortAddress,
IN ULONG BaudRate) IN ULONG BaudRate)
{ {
EFI_STATUS EfiStatus; EFI_STATUS EfiStatus;
XTSTATUS Status; XTSTATUS Status;
@@ -248,12 +278,12 @@ BlpInitializeSerialPort(IN ULONG PortNumber,
/* Set custom port address based on the port number and print debug message */ /* Set custom port address based on the port number and print debug message */
PortAddress = BlComPortList[PortNumber - 1]; PortAddress = BlComPortList[PortNumber - 1];
BlConsolePrint(L"Initializing serial console at port COM%d\n", PortNumber); Console::Print(L"Initializing serial console at port COM%d\n", PortNumber);
} }
else else
{ {
/* Custom port address supplied, print debug message */ /* Custom port address supplied, print debug message */
BlConsolePrint(L"Initializing serial console at COM port address: 0x%lX\n", PortAddress); Console::Print(L"Initializing serial console at COM port address: 0x%lX\n", PortAddress);
} }
/* Initialize COM port */ /* Initialize COM port */
@@ -263,11 +293,11 @@ BlpInitializeSerialPort(IN ULONG PortNumber,
if(Status == STATUS_NOT_FOUND && PortAddress) if(Status == STATUS_NOT_FOUND && PortAddress)
{ {
/* This might be PCI(E) serial controller, try to activate I/O space access first */ /* This might be PCI(E) serial controller, try to activate I/O space access first */
EfiStatus = BlpActivateSerialIOController(); EfiStatus = ActivateSerialIOController();
if(EfiStatus == STATUS_EFI_SUCCESS) if(EfiStatus == STATUS_EFI_SUCCESS)
{ {
/* Try to reinitialize COM port */ /* Try to reinitialize COM port */
BlConsolePrint(L"Enabled I/O space access for all PCI(E) serial controllers found\n"); Console::Print(L"Enabled I/O space access for all PCI(E) serial controllers found\n");
Status = HL::ComPort::InitializeComPort(&BlpStatus.SerialPort, (PUCHAR)UlongToPtr(PortAddress), BaudRate); Status = HL::ComPort::InitializeComPort(&BlpStatus.SerialPort, (PUCHAR)UlongToPtr(PortAddress), BaudRate);
} }
} }
@@ -282,3 +312,75 @@ BlpInitializeSerialPort(IN ULONG PortNumber,
/* Return success */ /* Return success */
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
} }
/**
* This routine formats the input string and prints it out to the debug ports.
*
* @param Format
* The formatted string that is to be written to the output.
*
* @param ...
* Depending on the format string, this routine might expect a sequence of additional arguments.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
Debug::Print(IN PCWSTR Format,
IN ...)
{
RTL_PRINT_CONTEXT ConsolePrintContext, SerialPrintContext;
VA_LIST Arguments;
/* Check if debugging enabled and if EFI serial port is fully initialized */
if(DEBUG)
{
/* Initialize the print contexts */
ConsolePrintContext.WriteWideCharacter = Console::PutChar;
SerialPrintContext.WriteWideCharacter = PutChar;
/* Initialise the va_list */
VA_START(Arguments, Format);
/* Check if serial debug port is enabled */
if((BlpStatus.DebugPort & XTBL_DEBUGPORT_SERIAL) && (BlpStatus.SerialPort.Flags & COMPORT_FLAG_INIT))
{
/* Format and print the string to the serial console */
RTL::WideString::FormatWideString(&SerialPrintContext, (PWCHAR)Format, Arguments);
}
/* Check if screen debug port is enabled and Boot Services are still available */
if((BlpStatus.DebugPort & XTBL_DEBUGPORT_SCREEN) && (BlpStatus.BootServices == TRUE))
{
/* Format and print the string to the screen */
RTL::WideString::FormatWideString(&ConsolePrintContext, (PWCHAR)Format, Arguments);
}
/* Clean up the va_list */
VA_END(Arguments);
}
}
/**
* Writes a character to the serial console.
*
* @param Character
* The integer promotion of the character to be written.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
XTSTATUS
Debug::PutChar(IN WCHAR Character)
{
WCHAR Buffer[2];
/* Write character to the serial console */
Buffer[0] = Character;
Buffer[1] = 0;
return HL::ComPort::WriteComPort(&BlpStatus.SerialPort, Buffer[0]);
}

View File

@@ -18,7 +18,7 @@
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlEnterFirmwareSetup() EfiUtils::EnterFirmwareSetup()
{ {
EFI_GUID Guid = EFI_GLOBAL_VARIABLE_GUID; EFI_GUID Guid = EFI_GLOBAL_VARIABLE_GUID;
PULONGLONG SetupSupport = NULLPTR; PULONGLONG SetupSupport = NULLPTR;
@@ -26,27 +26,27 @@ BlEnterFirmwareSetup()
EFI_STATUS Status; EFI_STATUS Status;
/* Check if booting into firmware interface is supported */ /* Check if booting into firmware interface is supported */
Status = BlGetEfiVariable(&Guid, L"OsIndicationsSupported", (PVOID*)&SetupSupport); Status = GetEfiVariable(&Guid, L"OsIndicationsSupported", (PVOID*)&SetupSupport);
if(Status != STATUS_EFI_SUCCESS || !(*SetupSupport & EFI_OS_INDICATIONS_BOOT_TO_FW_UI)) if(Status != STATUS_EFI_SUCCESS || !(*SetupSupport & EFI_OS_INDICATIONS_BOOT_TO_FW_UI))
{ {
/* Reboot into firmware setup is not supported */ /* Reboot into firmware setup is not supported */
BlDebugPrint(L"WARNING: Reboot into firmware setup interface not supported\n"); Debug::Print(L"WARNING: Reboot into firmware setup interface not supported\n");
if(SetupSupport) if(SetupSupport)
{ {
BlFreeMemoryPool((PVOID)SetupSupport); Memory::FreePool((PVOID)SetupSupport);
} }
return STATUS_EFI_UNSUPPORTED; return STATUS_EFI_UNSUPPORTED;
} }
BlFreeMemoryPool((PVOID)SetupSupport); Memory::FreePool((PVOID)SetupSupport);
/* Get the value of OsIndications variable */ /* Get the value of OsIndications variable */
Indications = 0; Indications = 0;
Status = BlGetEfiVariable(&Guid, L"OsIndications", (PVOID*)&Indications); Status = GetEfiVariable(&Guid, L"OsIndications", (PVOID*)&Indications);
/* Enable FW setup on next boot */ /* Enable FW setup on next boot */
Indications |= EFI_OS_INDICATIONS_BOOT_TO_FW_UI; Indications |= EFI_OS_INDICATIONS_BOOT_TO_FW_UI;
Status = BlSetEfiVariable(&Guid, L"OsIndications", (PVOID)&Indications, sizeof(Indications)); Status = SetEfiVariable(&Guid, L"OsIndications", (PVOID)&Indications, sizeof(Indications));
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to update OsIndications variable */ /* Failed to update OsIndications variable */
@@ -54,7 +54,7 @@ BlEnterFirmwareSetup()
} }
/* Reboot into firmware setup */ /* Reboot into firmware setup */
BlRebootSystem(); RebootSystem();
/* Must not reach this point, just make the compiler happy */ /* Must not reach this point, just make the compiler happy */
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
@@ -69,7 +69,7 @@ BlEnterFirmwareSetup()
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlExitBootServices() EfiUtils::ExitBootServices()
{ {
PEFI_MEMORY_MAP MemoryMap; PEFI_MEMORY_MAP MemoryMap;
EFI_STATUS Status; EFI_STATUS Status;
@@ -79,11 +79,11 @@ BlExitBootServices()
BlpStatus.BootServices = FALSE; BlpStatus.BootServices = FALSE;
/* Allocate buffer for EFI memory map */ /* Allocate buffer for EFI memory map */
Status = BlAllocateMemoryPool(sizeof(EFI_MEMORY_MAP), (PVOID*)&MemoryMap); Status = Memory::AllocatePool(sizeof(EFI_MEMORY_MAP), (PVOID*)&MemoryMap);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure */ /* Memory allocation failure */
BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status); Debug::Print(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status);
return Status; return Status;
} }
@@ -95,7 +95,7 @@ BlExitBootServices()
while(Counter > 0) while(Counter > 0)
{ {
/* Get memory map each time as it can change between two calls */ /* Get memory map each time as it can change between two calls */
Status = BlGetMemoryMap(MemoryMap); Status = Memory::GetMemoryMap(MemoryMap);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to get new memory map */ /* Failed to get new memory map */
@@ -132,8 +132,8 @@ BlExitBootServices()
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlGetConfigurationTable(IN PEFI_GUID TableGuid, EfiUtils::GetConfigurationTable(IN PEFI_GUID TableGuid,
OUT PVOID *Table) OUT PVOID *Table)
{ {
SIZE_T Index; SIZE_T Index;
@@ -172,9 +172,9 @@ BlGetConfigurationTable(IN PEFI_GUID TableGuid,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlGetEfiVariable(IN PEFI_GUID Vendor, EfiUtils::GetEfiVariable(IN PEFI_GUID Vendor,
IN PCWSTR VariableName, IN PCWSTR VariableName,
OUT PVOID *VariableValue) OUT PVOID *VariableValue)
{ {
EFI_STATUS Status; EFI_STATUS Status;
PVOID Buffer; PVOID Buffer;
@@ -182,7 +182,7 @@ BlGetEfiVariable(IN PEFI_GUID Vendor,
/* Allocate a buffer for storing a variable's value */ /* Allocate a buffer for storing a variable's value */
Size = EFI_MAXIMUM_VARIABLE_SIZE * sizeof(PWCHAR); Size = EFI_MAXIMUM_VARIABLE_SIZE * sizeof(PWCHAR);
Status = BlAllocateMemoryPool(Size, (PVOID*)&Buffer); Status = Memory::AllocatePool(Size, (PVOID*)&Buffer);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure */ /* Memory allocation failure */
@@ -216,7 +216,7 @@ BlGetEfiVariable(IN PEFI_GUID Vendor,
*/ */
XTCDECL XTCDECL
ULONGLONG ULONGLONG
BlGetRandomValue(IN OUT PULONGLONG RNGBuffer) EfiUtils::GetRandomValue(IN OUT PULONGLONG RNGBuffer)
{ {
/* Recalculate RNG buffer with XORSHIFT */ /* Recalculate RNG buffer with XORSHIFT */
*RNGBuffer ^= *RNGBuffer >> 12; *RNGBuffer ^= *RNGBuffer >> 12;
@@ -236,7 +236,7 @@ BlGetRandomValue(IN OUT PULONGLONG RNGBuffer)
*/ */
XTCDECL XTCDECL
INT_PTR INT_PTR
BlGetSecureBootStatus() EfiUtils::GetSecureBootStatus()
{ {
EFI_GUID VarGuid = EFI_GLOBAL_VARIABLE_GUID; EFI_GUID VarGuid = EFI_GLOBAL_VARIABLE_GUID;
INT_PTR SecureBootStatus = 0; INT_PTR SecureBootStatus = 0;
@@ -272,7 +272,7 @@ BlGetSecureBootStatus()
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlInitializeEntropy(PULONGLONG RNGBuffer) EfiUtils::InitializeEntropy(PULONGLONG RNGBuffer)
{ {
EFI_GUID RngGuid = EFI_RNG_PROTOCOL_GUID; EFI_GUID RngGuid = EFI_RNG_PROTOCOL_GUID;
PEFI_RNG_PROTOCOL Rng; PEFI_RNG_PROTOCOL Rng;
@@ -325,10 +325,10 @@ BlInitializeEntropy(PULONGLONG RNGBuffer)
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlLoadEfiImage(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, EfiUtils::LoadEfiImage(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
IN PVOID ImageData, IN PVOID ImageData,
IN SIZE_T ImageSize, IN SIZE_T ImageSize,
OUT PEFI_HANDLE ImageHandle) OUT PEFI_HANDLE ImageHandle)
{ {
/* Load EFI image */ /* Load EFI image */
return EfiSystemTable->BootServices->LoadImage(FALSE, EfiImageHandle, DevicePath, ImageData, ImageSize, ImageHandle); return EfiSystemTable->BootServices->LoadImage(FALSE, EfiImageHandle, DevicePath, ImageData, ImageSize, ImageHandle);
@@ -343,7 +343,7 @@ BlLoadEfiImage(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlRebootSystem() EfiUtils::RebootSystem()
{ {
/* Reboot machine */ /* Reboot machine */
return EfiSystemTable->RuntimeServices->ResetSystem(EfiResetCold, STATUS_EFI_SUCCESS, 0, NULLPTR); return EfiSystemTable->RuntimeServices->ResetSystem(EfiResetCold, STATUS_EFI_SUCCESS, 0, NULLPTR);
@@ -370,10 +370,10 @@ BlRebootSystem()
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlSetEfiVariable(IN PEFI_GUID Vendor, EfiUtils::SetEfiVariable(IN PEFI_GUID Vendor,
IN PCWSTR VariableName, IN PCWSTR VariableName,
IN PVOID VariableValue, IN PVOID VariableValue,
IN UINT_PTR Size) IN UINT_PTR Size)
{ {
ULONG Attributes; ULONG Attributes;
@@ -391,7 +391,7 @@ BlSetEfiVariable(IN PEFI_GUID Vendor,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlShutdownSystem() EfiUtils::ShutdownSystem()
{ {
/* Shutdown machine */ /* Shutdown machine */
return EfiSystemTable->RuntimeServices->ResetSystem(EfiResetShutdown, STATUS_EFI_SUCCESS, 0, NULLPTR); return EfiSystemTable->RuntimeServices->ResetSystem(EfiResetShutdown, STATUS_EFI_SUCCESS, 0, NULLPTR);
@@ -409,7 +409,7 @@ BlShutdownSystem()
*/ */
XTCDECL XTCDECL
VOID VOID
BlSleepExecution(IN ULONG_PTR Milliseconds) EfiUtils::SleepExecution(IN ULONG_PTR Milliseconds)
{ {
EfiSystemTable->BootServices->Stall(Milliseconds * 1000); EfiSystemTable->BootServices->Stall(Milliseconds * 1000);
} }
@@ -426,7 +426,7 @@ BlSleepExecution(IN ULONG_PTR Milliseconds)
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlStartEfiImage(IN EFI_HANDLE ImageHandle) EfiUtils::StartEfiImage(IN EFI_HANDLE ImageHandle)
{ {
return EfiSystemTable->BootServices->StartImage(ImageHandle, NULLPTR, NULLPTR); return EfiSystemTable->BootServices->StartImage(ImageHandle, NULLPTR, NULLPTR);
} }
@@ -449,9 +449,9 @@ BlStartEfiImage(IN EFI_HANDLE ImageHandle)
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlWaitForEfiEvent(IN UINT_PTR NumberOfEvents, EfiUtils::WaitForEfiEvent(IN UINT_PTR NumberOfEvents,
IN PEFI_EVENT Event, IN PEFI_EVENT Event,
OUT PUINT_PTR Index) OUT PUINT_PTR Index)
{ {
return EfiSystemTable->BootServices->WaitForEvent(NumberOfEvents, Event, Index); return EfiSystemTable->BootServices->WaitForEvent(NumberOfEvents, Event, Index);
} }

View File

@@ -1,112 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/hardware.cc
* DESCRIPTION: EFI hardware support for XT Boot Loader
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtldr.hh>
/**
* Enables I/O space access to all serial controllers found on the PCI(E) root bridge.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
BlpActivateSerialIOController()
{
EFI_GUID PciGuid = EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID;
PEFI_PCI_ROOT_BRIDGE_IO_PROTOCOL PciDev;
USHORT Bus, Device, Function, Command;
UINT_PTR Index, PciHandleSize;
PEFI_HANDLE PciHandle = NULLPTR;
PCI_COMMON_HEADER PciHeader;
EFI_STATUS Status;
ULONGLONG Address;
/* Allocate memory for single EFI_HANDLE, what should be enough in most cases */
PciHandleSize = sizeof(EFI_HANDLE);
Status = BlAllocateMemoryPool(PciHandleSize, (PVOID*)&PciHandle);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure */
return Status;
}
/* Get all instances of PciRootBridgeIo */
Status = EfiSystemTable->BootServices->LocateHandle(ByProtocol, &PciGuid, NULLPTR, &PciHandleSize, PciHandle);
if(Status == STATUS_EFI_BUFFER_TOO_SMALL)
{
/* Reallocate more memory as requested by UEFI */
BlFreeMemoryPool(PciHandle);
Status = BlAllocateMemoryPool(PciHandleSize, (PVOID*)&PciHandle);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory reallocation failure */
return Status;
}
/* Second attempt to get instances of PciRootBridgeIo */
Status = EfiSystemTable->BootServices->LocateHandle(ByProtocol, &PciGuid, NULLPTR, &PciHandleSize, PciHandle);
}
/* Make sure successfully obtained PciRootBridgeIo instances */
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to get PciRootBridgeIo instances */
return Status;
}
/* Enumerate all devices for each handle, which decides a segment and a bus number range */
for(Index = 0; Index < (PciHandleSize / sizeof(EFI_HANDLE)); Index++)
{
/* Get inferface from the protocol */
Status = EfiSystemTable->BootServices->HandleProtocol(PciHandle[Index], &PciGuid, (PVOID*)&PciDev);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to get interface */
return Status;
}
/* Enumerate whole PCI bridge */
for(Bus = 0; Bus <= PCI_MAX_BRIDGE_NUMBER; Bus++)
{
/* Enumerate all devices for each bus */
for(Device = 0; Device < PCI_MAX_DEVICES; Device++)
{
/* Enumerate all functions for each devices */
for(Function = 0; Function < PCI_MAX_FUNCTION; Function++)
{
/* Read configuration space */
Address = ((ULONGLONG)((((UINT_PTR) Bus) << 24) + (((UINT_PTR) Device) << 16) +
(((UINT_PTR) Function) << 8) + ((UINT_PTR) 0)));
PciDev->Pci.Read(PciDev, EfiPciIoWidthUint32, Address, sizeof (PciHeader) / sizeof (UINT), &PciHeader);
/* Check if device exists */
if(PciHeader.VendorId == PCI_INVALID_VENDORID)
{
/* Skip non-existen device */
continue;
}
/* Check if device is serial controller or multiport serial controller */
if(PciHeader.BaseClass == 0x07 && (PciHeader.SubClass == 0x00 || PciHeader.SubClass == 0x02))
{
/* Enable I/O space access */
Address |= 0x4;
Command = PCI_ENABLE_IO_SPACE;
Status = PciDev->Pci.Write(PciDev, EfiPciIoWidthUint16, Address, 1, &Command);
}
}
}
}
}
/* Return SUCCESS */
return STATUS_EFI_SUCCESS;
}

View File

@@ -16,6 +16,308 @@
#include <globals.hh> #include <globals.hh>
class BootUtils
{
public:
STATIC XTCDECL BOOLEAN GetBooleanParameter(IN PCWSTR Parameters,
IN PCWSTR Needle);
};
class Configuration
{
public:
STATIC XTCDECL BOOLEAN GetBooleanValue(IN PCWSTR ConfigName);
STATIC XTCDECL EFI_STATUS GetBootOptionValue(IN PLIST_ENTRY Options,
IN PCWSTR OptionName,
OUT PWCHAR *OptionValue);
STATIC XTCDECL VOID GetEditableOptions(OUT PCWSTR **OptionsArray,
OUT PULONG OptionsCount);
STATIC XTCDECL EFI_STATUS GetValue(IN PCWSTR ConfigName,
OUT PWCHAR *ConfigValue);
STATIC XTCDECL EFI_STATUS LoadConfiguration();
STATIC XTCDECL EFI_STATUS ParseCommandLine();
STATIC XTCDECL EFI_STATUS SetBootOptionValue(IN PLIST_ENTRY Options,
IN PCWSTR OptionName,
IN PCWSTR OptionValue);
private:
STATIC XTCDECL EFI_STATUS ParseConfigFile(IN CONST PCHAR RawConfig,
OUT PLIST_ENTRY Configuration);
STATIC XTCDECL EFI_STATUS ReadConfigFile(IN PCWSTR ConfigDirectory,
IN PCWSTR ConfigFile,
OUT PCHAR *ConfigData);
STATIC XTCDECL EFI_STATUS SetValue(IN PCWSTR ConfigName,
IN PCWSTR ConfigValue);
STATIC XTCDECL VOID UpdateConfiguration(IN PLIST_ENTRY NewConfig);
};
class Console
{
public:
STATIC XTCDECL VOID ClearLine(IN ULONGLONG LineNo);
STATIC XTCDECL VOID ClearScreen();
STATIC XTCDECL VOID DisableCursor();
STATIC XTCDECL VOID EnableCursor();
STATIC XTCDECL VOID InitializeConsole();
STATIC XTCDECL VOID Print(IN PCWSTR Format,
IN ...);
STATIC XTCDECL XTSTATUS PutChar(IN WCHAR Character);
STATIC XTCDECL VOID QueryMode(OUT PUINT_PTR ResX,
OUT PUINT_PTR ResY);
STATIC XTCDECL VOID ReadKeyStroke(OUT PEFI_INPUT_KEY Key);
STATIC XTCDECL VOID ResetInputBuffer();
STATIC XTCDECL VOID SetAttributes(IN ULONGLONG Attributes);
STATIC XTCDECL VOID SetCursorPosition(IN ULONGLONG PosX,
IN ULONGLONG PosY);
STATIC XTCDECL VOID Write(IN PCWSTR String);
private:
STATIC XTCDECL EFI_STATUS SetMode(IN ULONGLONG Mode);
};
class Debug
{
public:
STATIC XTCDECL EFI_STATUS InitializeDebugConsole();
STATIC XTCDECL VOID Print(IN PCWSTR Format,
IN ...);
STATIC XTCDECL XTSTATUS PutChar(IN WCHAR Character);
private:
STATIC XTCDECL EFI_STATUS ActivateSerialIOController();
STATIC XTCDECL EFI_STATUS InitializeSerialPort(IN ULONG PortNumber,
IN ULONG PortAddress,
IN ULONG BaudRate);
};
class EfiUtils
{
public:
STATIC XTCDECL EFI_STATUS EnterFirmwareSetup();
STATIC XTCDECL EFI_STATUS ExitBootServices();
STATIC XTCDECL EFI_STATUS GetConfigurationTable(IN PEFI_GUID TableGuid,
OUT PVOID *Table);
STATIC XTCDECL EFI_STATUS GetEfiVariable(IN PEFI_GUID Vendor,
IN PCWSTR VariableName,
OUT PVOID *VariableValue);
STATIC XTCDECL ULONGLONG GetRandomValue(IN OUT PULONGLONG RNGBuffer);
STATIC XTCDECL INT_PTR GetSecureBootStatus();
STATIC XTCDECL EFI_STATUS InitializeEntropy(PULONGLONG RNGBuffer);
STATIC XTCDECL EFI_STATUS LoadEfiImage(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
IN PVOID ImageData,
IN SIZE_T ImageSize,
OUT PEFI_HANDLE ImageHandle);
STATIC XTCDECL EFI_STATUS RebootSystem();
STATIC XTCDECL EFI_STATUS SetEfiVariable(IN PEFI_GUID Vendor,
IN PCWSTR VariableName,
IN PVOID VariableValue,
IN UINT_PTR Size);
STATIC XTCDECL EFI_STATUS ShutdownSystem();
STATIC XTCDECL VOID SleepExecution(IN ULONG_PTR Milliseconds);
STATIC XTCDECL EFI_STATUS StartEfiImage(IN EFI_HANDLE ImageHandle);
STATIC XTCDECL EFI_STATUS WaitForEfiEvent(IN UINT_PTR NumberOfEvents,
IN PEFI_EVENT Event,
OUT PUINT_PTR Index);
};
class Memory
{
public:
STATIC XTCDECL EFI_STATUS AllocatePages(IN EFI_ALLOCATE_TYPE AllocationType,
IN ULONGLONG NumberOfPages,
OUT PEFI_PHYSICAL_ADDRESS Memory);
STATIC XTCDECL EFI_STATUS AllocatePool(IN UINT_PTR Size,
OUT PVOID *Memory);
STATIC XTCDECL EFI_STATUS BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR SelfMapAddress);
STATIC XTCDECL EFI_STATUS FreePages(IN ULONGLONG NumberOfPages,
IN EFI_PHYSICAL_ADDRESS Memory);
STATIC XTCDECL EFI_STATUS FreePool(IN PVOID Memory);
STATIC XTCDECL VOID GetMappingsCount(IN PXTBL_PAGE_MAPPING PageMap,
OUT PULONG NumberOfMappings);
STATIC XTCDECL EFI_STATUS GetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap);
STATIC XTCDECL PVOID GetVirtualAddress(IN PXTBL_PAGE_MAPPING PageMap,
IN PVOID PhysicalAddress);
STATIC XTCDECL VOID InitializePageMap(OUT PXTBL_PAGE_MAPPING PageMap,
IN SHORT PageMapLevel,
IN PAGE_SIZE PageSize);
STATIC XTCDECL EFI_STATUS MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
IN OUT PVOID *MemoryMapAddress,
IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine);
STATIC XTCDECL EFI_STATUS MapPage(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR VirtualAddress,
IN ULONG_PTR PhysicalAddress,
IN ULONG NumberOfPages);
STATIC XTCDECL EFI_STATUS MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
IN PVOID VirtualAddress,
IN PVOID PhysicalAddress,
IN ULONGLONG NumberOfPages,
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:
STATIC XTCDECL LOADER_MEMORY_TYPE GetLoaderMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType);
STATIC XTCDECL EFI_STATUS GetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
IN PVOID PageTable,
IN SIZE_T Entry,
OUT PVOID *NextPageTable);
STATIC XTCDECL EFI_STATUS SelfMapPml(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR SelfMapAddress);
};
class Protocol
{
public:
STATIC XTCDECL EFI_STATUS CloseProtocol(IN PEFI_HANDLE Handle,
IN PEFI_GUID ProtocolGuid);
STATIC XTCDECL EFI_STATUS FindBootProtocol(IN PCWSTR SystemType,
OUT PEFI_GUID BootProtocolGuid);
STATIC XTCDECL PLIST_ENTRY GetModulesList();
STATIC XTCDECL EFI_STATUS InstallProtocol(IN PVOID Interface,
IN PEFI_GUID Guid);
STATIC XTCDECL EFI_STATUS InvokeBootProtocol(IN PWCHAR ShortName,
IN PLIST_ENTRY OptionsList);
STATIC XTCDECL EFI_STATUS LoadModule(IN PWCHAR ModuleName);
STATIC XTCDECL EFI_STATUS LoadModules(IN PWCHAR ModulesList);
STATIC XTCDECL EFI_STATUS LocateProtocolHandles(OUT PEFI_HANDLE *Handles,
OUT PUINT_PTR Count,
IN PEFI_GUID ProtocolGuid);
STATIC XTCDECL EFI_STATUS OpenProtocol(OUT PEFI_HANDLE Handle,
OUT PVOID *ProtocolHandler,
IN PEFI_GUID ProtocolGuid);
STATIC XTCDECL EFI_STATUS OpenProtocolHandle(IN EFI_HANDLE Handle,
OUT PVOID *ProtocolHandler,
IN PEFI_GUID ProtocolGuid);
STATIC XTCDECL VOID RegisterBootMenu(IN PVOID BootMenuRoutine);
STATIC XTCDECL EFI_STATUS RegisterBootProtocol(IN PCWSTR SystemType,
IN PEFI_GUID BootProtocolGuid);
STATIC XTCDECL EFI_STATUS InstallXtLoaderProtocol();
private:
STATIC XTCDECL EFI_STATUS GetModuleInformation(IN PWCHAR SectionData,
IN ULONG SectionSize,
OUT PXTBL_MODULE_INFO ModuleInfo);
STATIC XTCDECL EFI_STATUS GetModuleInfoStrings(IN PWCHAR SectionData,
IN ULONG SectionSize,
OUT PWCHAR **ModInfo,
OUT PULONG InfoCount);
};
class Shell
{
public:
STATIC XTCDECL VOID StartLoaderShell();
private:
STATIC XTCDECL VOID PrintPrompt();
};
class TextUi
{
public:
STATIC XTCDECL VOID DisplayBootMenu();
STATIC XTCDECL VOID DisplayErrorDialog(IN PCWSTR Caption,
IN PCWSTR Message);
STATIC XTCDECL VOID DisplayInfoDialog(IN PCWSTR Caption,
IN PCWSTR Message);
STATIC XTCDECL VOID DisplayInputDialog(IN PCWSTR Caption,
IN PCWSTR Message,
IN OUT PWCHAR *InputFieldText);
STATIC XTCDECL XTBL_DIALOG_HANDLE DisplayProgressDialog(IN PCWSTR Caption,
IN PCWSTR Message,
IN UCHAR Percentage);
STATIC XTCDECL VOID UpdateProgressBar(IN PXTBL_DIALOG_HANDLE Handle,
IN PCWSTR Message,
IN UCHAR Percentage);
private:
STATIC XTCDECL VOID DetermineDialogBoxSize(IN OUT PXTBL_DIALOG_HANDLE Handle,
IN PCWSTR Message);
STATIC XTCDECL VOID DisplayEditMenu(IN PXTBL_BOOTMENU_ITEM MenuEntry);
STATIC XTCDECL VOID DrawBootMenu(OUT PXTBL_DIALOG_HANDLE Handle);
STATIC XTCDECL VOID DrawBootMenuEntry(IN PXTBL_DIALOG_HANDLE Handle,
IN PWCHAR MenuEntry,
IN UINT Position,
IN BOOLEAN Highlighted);
STATIC XTCDECL VOID DrawDialogBox(IN OUT PXTBL_DIALOG_HANDLE Handle,
IN PCWSTR Caption,
IN PCWSTR Message);
STATIC XTCDECL VOID DrawButton(IN PXTBL_DIALOG_HANDLE Handle);
STATIC XTCDECL VOID DrawInputField(IN PXTBL_DIALOG_HANDLE Handle,
IN PWCHAR InputFieldText);
STATIC XTCDECL VOID DrawMessage(IN PXTBL_DIALOG_HANDLE Handle,
IN PCWSTR Message);
STATIC XTCDECL VOID DrawProgressBar(IN PXTBL_DIALOG_HANDLE Handle,
IN UCHAR Percentage);
STATIC XTCDECL VOID DrawEditMenu(OUT PXTBL_DIALOG_HANDLE Handle);
STATIC XTCDECL EFI_STATUS DrawEditMenuEntry(IN PXTBL_DIALOG_HANDLE Handle,
IN PCWSTR OptionName,
IN PCWSTR OptionValue,
IN UINT Position,
IN BOOLEAN Highlighted);
};
class Volume
{
public:
STATIC XTCDECL EFI_STATUS CloseVolume(IN PEFI_HANDLE VolumeHandle);
STATIC XTCDECL EFI_STATUS EnumerateBlockDevices();
STATIC XTCDECL EFI_STATUS FindDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle,
IN CONST PWCHAR FileSystemPath,
OUT PEFI_DEVICE_PATH_PROTOCOL* DevicePath);
STATIC XTCDECL EFI_STATUS GetEfiPath(IN PWCHAR SystemPath,
OUT PWCHAR *EfiPath);
STATIC XTCDECL EFI_STATUS GetDevicePath(IN PWCHAR SystemPath,
OUT PEFI_DEVICE_PATH_PROTOCOL *DevicePath,
OUT PWCHAR *ArcName,
OUT PWCHAR *Path);
STATIC XTCDECL EFI_STATUS OpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
OUT PEFI_HANDLE DiskHandle,
OUT PEFI_FILE_HANDLE *FsHandle);
STATIC XTCDECL EFI_STATUS ReadFile(IN PEFI_FILE_HANDLE DirHandle,
IN PCWSTR FileName,
OUT PVOID *FileData,
OUT PSIZE_T FileSize);
private:
STATIC XTCDECL EFI_STATUS DiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices);
STATIC XTCDECL EFI_STATUS DissectArcPath(IN PWCHAR SystemPath,
OUT PWCHAR *ArcName,
OUT PWCHAR *Path,
OUT PUSHORT DriveType,
OUT PULONG DriveNumber,
OUT PULONG PartNumber);
STATIC XTCDECL PEFI_DEVICE_PATH_PROTOCOL DuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath);
STATIC XTCDECL EFI_STATUS FindLastBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
OUT PEFI_DEVICE_PATH_PROTOCOL *LastNode);
STATIC XTCDECL BOOLEAN FindParentBlockDevice(IN PLIST_ENTRY BlockDevices,
IN PEFI_BLOCK_DEVICE_DATA ChildNode,
OUT PEFI_BLOCK_DEVICE_DATA *ParentNode);
};
class XtLoader
{
public:
STATIC XTCDECL VOID InitializeBootLoader();
STATIC XTCDECL EFI_STATUS InitializeBootMenuList(IN ULONG MaxNameLength,
OUT PXTBL_BOOTMENU_ITEM *MenuEntries,
OUT PULONG EntriesCount,
OUT PULONG DefaultId);
};
/* XTLDR routines forward references */ /* XTLDR routines forward references */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS

View File

@@ -24,7 +24,7 @@
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlAllocateMemoryPages(IN EFI_ALLOCATE_TYPE AllocationType, Memory::AllocatePages(IN EFI_ALLOCATE_TYPE AllocationType,
IN ULONGLONG NumberOfPages, IN ULONGLONG NumberOfPages,
OUT PEFI_PHYSICAL_ADDRESS Memory) OUT PEFI_PHYSICAL_ADDRESS Memory)
{ {
@@ -46,7 +46,7 @@ BlAllocateMemoryPages(IN EFI_ALLOCATE_TYPE AllocationType,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlAllocateMemoryPool(IN UINT_PTR Size, Memory::AllocatePool(IN UINT_PTR Size,
OUT PVOID *Memory) OUT PVOID *Memory)
{ {
/* Allocate pool */ /* Allocate pool */
@@ -68,7 +68,7 @@ BlAllocateMemoryPool(IN UINT_PTR Size,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlFreeMemoryPages(IN ULONGLONG NumberOfPages, Memory::FreePages(IN ULONGLONG NumberOfPages,
IN EFI_PHYSICAL_ADDRESS Memory) IN EFI_PHYSICAL_ADDRESS Memory)
{ {
return EfiSystemTable->BootServices->FreePages(Memory, NumberOfPages); return EfiSystemTable->BootServices->FreePages(Memory, NumberOfPages);
@@ -86,12 +86,60 @@ BlFreeMemoryPages(IN ULONGLONG NumberOfPages,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlFreeMemoryPool(IN PVOID Memory) Memory::FreePool(IN PVOID Memory)
{ {
/* Free pool */ /* Free pool */
return EfiSystemTable->BootServices->FreePool(Memory); return EfiSystemTable->BootServices->FreePool(Memory);
} }
/**
* Converts EFI memory type to XTLDR memory type.
*
* @param EfiMemoryType
* Specifies EFI memory type.
*
* @return This routine returns a mapped XTLDR memory type.
*
* @since XT 1.0
*/
XTCDECL
LOADER_MEMORY_TYPE
Memory::GetLoaderMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType)
{
LOADER_MEMORY_TYPE MemoryType;
/* Check EFI memory type and convert to XTLDR 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 EfiBootServicesData:
case EfiLoaderCode:
case EfiLoaderData:
MemoryType = LoaderFirmwareTemporary;
break;
case EfiUnusableMemory:
MemoryType = LoaderBad;
break;
default:
MemoryType = LoaderFree;
break;
}
/* Return XTLDR memory type */
return MemoryType;
}
/** /**
* Returns the number of mappings in the page mapping structure. * Returns the number of mappings in the page mapping structure.
* *
@@ -107,8 +155,8 @@ BlFreeMemoryPool(IN PVOID Memory)
*/ */
XTCDECL XTCDECL
VOID VOID
BlGetMappingsCount(IN PXTBL_PAGE_MAPPING PageMap, Memory::GetMappingsCount(IN PXTBL_PAGE_MAPPING PageMap,
OUT PULONG NumberOfMappings) OUT PULONG NumberOfMappings)
{ {
/* Return number of mappings */ /* Return number of mappings */
*NumberOfMappings = PageMap->MapSize; *NumberOfMappings = PageMap->MapSize;
@@ -126,7 +174,7 @@ BlGetMappingsCount(IN PXTBL_PAGE_MAPPING PageMap,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlGetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap) Memory::GetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap)
{ {
EFI_STATUS Status; EFI_STATUS Status;
@@ -155,14 +203,14 @@ BlGetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap)
if(MemoryMap->Map) if(MemoryMap->Map)
{ {
/* Free allocated memory */ /* Free allocated memory */
BlFreeMemoryPool(MemoryMap->Map); FreePool(MemoryMap->Map);
} }
return Status; return Status;
} }
/* Allocate the desired amount of memory */ /* Allocate the desired amount of memory */
MemoryMap->MapSize += 2 * MemoryMap->DescriptorSize; MemoryMap->MapSize += 2 * MemoryMap->DescriptorSize;
BlAllocateMemoryPool(MemoryMap->MapSize, (PVOID *)&MemoryMap->Map); AllocatePool(MemoryMap->MapSize, (PVOID *)&MemoryMap->Map);
} }
while(Status == STATUS_EFI_BUFFER_TOO_SMALL); while(Status == STATUS_EFI_BUFFER_TOO_SMALL);
@@ -192,8 +240,8 @@ BlGetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap)
*/ */
XTCDECL XTCDECL
PVOID PVOID
BlGetVirtualAddress(IN PXTBL_PAGE_MAPPING PageMap, Memory::GetVirtualAddress(IN PXTBL_PAGE_MAPPING PageMap,
IN PVOID PhysicalAddress) IN PVOID PhysicalAddress)
{ {
PXTBL_MEMORY_MAPPING Mapping; PXTBL_MEMORY_MAPPING Mapping;
PLIST_ENTRY ListEntry; PLIST_ENTRY ListEntry;
@@ -243,9 +291,9 @@ BlGetVirtualAddress(IN PXTBL_PAGE_MAPPING PageMap,
*/ */
XTCDECL XTCDECL
VOID VOID
BlInitializePageMap(OUT PXTBL_PAGE_MAPPING PageMap, Memory::InitializePageMap(OUT PXTBL_PAGE_MAPPING PageMap,
IN SHORT PageMapLevel, IN SHORT PageMapLevel,
IN PAGE_SIZE PageSize) IN PAGE_SIZE PageSize)
{ {
/* Initialize memory mappings */ /* Initialize memory mappings */
RTL::LinkedList::InitializeListHead(&PageMap->MemoryMap); RTL::LinkedList::InitializeListHead(&PageMap->MemoryMap);
@@ -274,9 +322,9 @@ BlInitializePageMap(OUT PXTBL_PAGE_MAPPING PageMap,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlMapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
IN OUT PVOID *MemoryMapAddress, IN OUT PVOID *MemoryMapAddress,
IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine) IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine)
{ {
PEFI_MEMORY_DESCRIPTOR Descriptor; PEFI_MEMORY_DESCRIPTOR Descriptor;
LOADER_MEMORY_TYPE MemoryType; LOADER_MEMORY_TYPE MemoryType;
@@ -293,15 +341,15 @@ BlMapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
if(GetMemoryTypeRoutine == NULLPTR) if(GetMemoryTypeRoutine == NULLPTR)
{ {
/* Use default memory type routine */ /* Use default memory type routine */
GetMemoryTypeRoutine = BlpGetLoaderMemoryType; GetMemoryTypeRoutine = GetLoaderMemoryType;
} }
/* Allocate and zero-fill buffer for EFI memory map */ /* Allocate and zero-fill buffer for EFI memory map */
BlAllocateMemoryPool(sizeof(EFI_MEMORY_MAP), (PVOID*)&MemoryMap); AllocatePool(sizeof(EFI_MEMORY_MAP), (PVOID*)&MemoryMap);
RTL::Memory::ZeroMemory(MemoryMap, sizeof(EFI_MEMORY_MAP)); RTL::Memory::ZeroMemory(MemoryMap, sizeof(EFI_MEMORY_MAP));
/* Get EFI memory map */ /* Get EFI memory map */
Status = BlGetMemoryMap(MemoryMap); Status = GetMemoryMap(MemoryMap);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to get EFI memory map */ /* Failed to get EFI memory map */
@@ -352,14 +400,14 @@ BlMapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
if(MemoryType == LoaderFirmwareTemporary) if(MemoryType == LoaderFirmwareTemporary)
{ {
/* Map EFI firmware code */ /* Map EFI firmware code */
Status = BlMapVirtualMemory(PageMap, (PVOID)Descriptor->PhysicalStart, Status = MapVirtualMemory(PageMap, (PVOID)Descriptor->PhysicalStart,
(PVOID)Descriptor->PhysicalStart, Descriptor->NumberOfPages, MemoryType); (PVOID)Descriptor->PhysicalStart, Descriptor->NumberOfPages, MemoryType);
} }
else if(MemoryType != LoaderFree) else if(MemoryType != LoaderFree)
{ {
/* Add any non-free memory mapping */ /* Add any non-free memory mapping */
Status = BlMapVirtualMemory(PageMap, VirtualAddress, (PVOID)Descriptor->PhysicalStart, Status = MapVirtualMemory(PageMap, VirtualAddress, (PVOID)Descriptor->PhysicalStart,
Descriptor->NumberOfPages, MemoryType); Descriptor->NumberOfPages, MemoryType);
/* Calculate next valid virtual address */ /* Calculate next valid virtual address */
VirtualAddress += Descriptor->NumberOfPages * EFI_PAGE_SIZE; VirtualAddress += Descriptor->NumberOfPages * EFI_PAGE_SIZE;
@@ -367,8 +415,8 @@ BlMapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
else else
{ {
/* Map all other memory as loader free */ /* Map all other memory as loader free */
Status = BlMapVirtualMemory(PageMap, NULLPTR, (PVOID)Descriptor->PhysicalStart, Status = MapVirtualMemory(PageMap, NULLPTR, (PVOID)Descriptor->PhysicalStart,
Descriptor->NumberOfPages, LoaderFree); Descriptor->NumberOfPages, LoaderFree);
} }
/* Make sure memory mapping succeeded */ /* Make sure memory mapping succeeded */
@@ -384,7 +432,7 @@ BlMapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
} }
/* Always map first page */ /* Always map first page */
Status = BlMapVirtualMemory(PageMap, NULLPTR, (PVOID)0, 1, LoaderFirmwarePermanent); Status = MapVirtualMemory(PageMap, NULLPTR, (PVOID)0, 1, LoaderFirmwarePermanent);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Mapping failed */ /* Mapping failed */
@@ -392,7 +440,7 @@ BlMapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
} }
/* Map BIOS ROM and VRAM */ /* Map BIOS ROM and VRAM */
Status = BlMapVirtualMemory(PageMap, NULLPTR, (PVOID)0xA0000, 0x60, LoaderFirmwarePermanent); Status = MapVirtualMemory(PageMap, NULLPTR, (PVOID)0xA0000, 0x60, LoaderFirmwarePermanent);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Mapping failed */ /* Mapping failed */
@@ -428,11 +476,11 @@ BlMapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlMapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap, Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
IN PVOID VirtualAddress, IN PVOID VirtualAddress,
IN PVOID PhysicalAddress, IN PVOID PhysicalAddress,
IN ULONGLONG NumberOfPages, IN ULONGLONG NumberOfPages,
IN LOADER_MEMORY_TYPE MemoryType) IN LOADER_MEMORY_TYPE MemoryType)
{ {
PXTBL_MEMORY_MAPPING Mapping1, Mapping2, Mapping3; PXTBL_MEMORY_MAPPING Mapping1, Mapping2, Mapping3;
PVOID PhysicalAddressEnd, PhysicalAddress2End; PVOID PhysicalAddressEnd, PhysicalAddress2End;
@@ -441,7 +489,7 @@ BlMapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
EFI_STATUS Status; EFI_STATUS Status;
/* Allocate memory for new mapping */ /* Allocate memory for new mapping */
Status = BlAllocateMemoryPool(sizeof(XTBL_MEMORY_MAPPING), (PVOID *)&Mapping1); Status = AllocatePool(sizeof(XTBL_MEMORY_MAPPING), (PVOID *)&Mapping1);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure */ /* Memory allocation failure */
@@ -491,7 +539,7 @@ BlMapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
if(NumberOfMappedPages > 0) if(NumberOfMappedPages > 0)
{ {
/* Pages associated to the mapping, allocate memory for it */ /* Pages associated to the mapping, allocate memory for it */
Status = BlAllocateMemoryPool(sizeof(XTBL_MEMORY_MAPPING), (PVOID*)&Mapping3); Status = AllocatePool(sizeof(XTBL_MEMORY_MAPPING), (PVOID*)&Mapping3);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure */ /* Memory allocation failure */
@@ -527,7 +575,7 @@ BlMapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
if(NumberOfMappedPages > 0) if(NumberOfMappedPages > 0)
{ {
/* Pages associated to the mapping, allocate memory for it */ /* Pages associated to the mapping, allocate memory for it */
Status = BlAllocateMemoryPool(sizeof(XTBL_MEMORY_MAPPING), (PVOID*)&Mapping3); Status = AllocatePool(sizeof(XTBL_MEMORY_MAPPING), (PVOID*)&Mapping3);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure */ /* Memory allocation failure */
@@ -564,7 +612,7 @@ BlMapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
/* Remove mapping from the list and free up it's memory */ /* Remove mapping from the list and free up it's memory */
RTL::LinkedList::RemoveEntryList(&Mapping2->ListEntry); RTL::LinkedList::RemoveEntryList(&Mapping2->ListEntry);
Status = BlFreeMemoryPool(Mapping2); Status = FreePool(Mapping2);
ListEntry = MappingListEntry; ListEntry = MappingListEntry;
/* Go to the next mapping */ /* Go to the next mapping */
@@ -609,9 +657,9 @@ BlMapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
*/ */
XTCDECL XTCDECL
PVOID PVOID
BlPhysicalAddressToVirtual(IN PVOID PhysicalAddress, Memory::PhysicalAddressToVirtual(IN PVOID PhysicalAddress,
IN PVOID PhysicalBase, IN PVOID PhysicalBase,
IN PVOID VirtualBase) IN PVOID VirtualBase)
{ {
/* Convert physical address to virtual address */ /* Convert physical address to virtual address */
return (PUCHAR)VirtualBase + ((PUCHAR)PhysicalAddress - (PUCHAR)PhysicalBase); return (PUCHAR)VirtualBase + ((PUCHAR)PhysicalAddress - (PUCHAR)PhysicalBase);
@@ -638,10 +686,10 @@ BlPhysicalAddressToVirtual(IN PVOID PhysicalAddress,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlPhysicalListToVirtual(IN PXTBL_PAGE_MAPPING PageMap, Memory::PhysicalListToVirtual(IN PXTBL_PAGE_MAPPING PageMap,
IN OUT PLIST_ENTRY ListHead, IN OUT PLIST_ENTRY ListHead,
IN PVOID PhysicalBase, IN PVOID PhysicalBase,
IN PVOID VirtualBase) IN PVOID VirtualBase)
{ {
PLIST_ENTRY ListEntry, NextEntry; PLIST_ENTRY ListEntry, NextEntry;
@@ -663,12 +711,12 @@ BlPhysicalListToVirtual(IN PXTBL_PAGE_MAPPING PageMap,
if(ListEntry->Blink == ListHead) if(ListEntry->Blink == ListHead)
{ {
/* Find virtual address of list head */ /* Find virtual address of list head */
ListEntry->Blink = (PLIST_ENTRY)BlGetVirtualAddress(PageMap, ListEntry->Blink); ListEntry->Blink = (PLIST_ENTRY)GetVirtualAddress(PageMap, ListEntry->Blink);
} }
else else
{ {
/* Convert list entry */ /* Convert list entry */
ListEntry->Blink = (PLIST_ENTRY)BlPhysicalAddressToVirtual(ListEntry->Blink, (PVOID)PhysicalBase, VirtualBase); ListEntry->Blink = (PLIST_ENTRY)PhysicalAddressToVirtual(ListEntry->Blink, (PVOID)PhysicalBase, VirtualBase);
} }
if(ListEntry->Flink == ListHead) if(ListEntry->Flink == ListHead)
{ {
@@ -678,7 +726,7 @@ BlPhysicalListToVirtual(IN PXTBL_PAGE_MAPPING PageMap,
else else
{ {
/* Convert list entry */ /* Convert list entry */
ListEntry->Flink = (PLIST_ENTRY)BlPhysicalAddressToVirtual(ListEntry->Flink, (PVOID)PhysicalBase, VirtualBase); ListEntry->Flink = (PLIST_ENTRY)PhysicalAddressToVirtual(ListEntry->Flink, (PVOID)PhysicalBase, VirtualBase);
} }
/* Get to the next element*/ /* Get to the next element*/
@@ -686,57 +734,9 @@ BlPhysicalListToVirtual(IN PXTBL_PAGE_MAPPING PageMap,
} }
/* Convert list head */ /* Convert list head */
ListHead->Blink = (PLIST_ENTRY)BlPhysicalAddressToVirtual(ListHead->Blink, (PVOID)PhysicalBase, VirtualBase); ListHead->Blink = (PLIST_ENTRY)PhysicalAddressToVirtual(ListHead->Blink, (PVOID)PhysicalBase, VirtualBase);
ListHead->Flink = (PLIST_ENTRY)BlPhysicalAddressToVirtual(ListHead->Flink, (PVOID)PhysicalBase, VirtualBase); ListHead->Flink = (PLIST_ENTRY)PhysicalAddressToVirtual(ListHead->Flink, (PVOID)PhysicalBase, VirtualBase);
/* Return success */ /* Return success */
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
} }
/**
* Converts EFI memory type to XTLDR memory type.
*
* @param EfiMemoryType
* Specifies EFI memory type.
*
* @return This routine returns a mapped XTLDR memory type.
*
* @since XT 1.0
*/
XTCDECL
LOADER_MEMORY_TYPE
BlpGetLoaderMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType)
{
LOADER_MEMORY_TYPE MemoryType;
/* Check EFI memory type and convert to XTLDR 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 EfiBootServicesData:
case EfiLoaderCode:
case EfiLoaderData:
MemoryType = LoaderFirmwareTemporary;
break;
case EfiUnusableMemory:
MemoryType = LoaderBad;
break;
default:
MemoryType = LoaderFree;
break;
}
/* Return XTLDR memory type */
return MemoryType;
}

View File

@@ -228,7 +228,7 @@ Acpi::GetRsdpTable(OUT PVOID *AcpiTable)
PVOID RsdpTable; PVOID RsdpTable;
/* Get RSDP (ACPI 1.0) table from system configuration tables */ /* Get RSDP (ACPI 1.0) table from system configuration tables */
Status = XtLdrProtocol->Util.GetConfigurationTable(&AcpiGuid, &RsdpTable); Status = XtLdrProtocol->Utils.GetConfigurationTable(&AcpiGuid, &RsdpTable);
if(Status != STATUS_EFI_SUCCESS || !ValidateAcpiTable(RsdpTable, 20)) if(Status != STATUS_EFI_SUCCESS || !ValidateAcpiTable(RsdpTable, 20))
{ {
/* RSDP not found or checksum mismatch */ /* RSDP not found or checksum mismatch */
@@ -260,7 +260,7 @@ Acpi::GetSMBiosTable(OUT PVOID *SmBiosTable)
EFI_STATUS Status; EFI_STATUS Status;
/* Get SMBIOS table from system configuration tables */ /* Get SMBIOS table from system configuration tables */
Status = XtLdrProtocol->Util.GetConfigurationTable(&SmBiosGuid, (PVOID*)&SmBios); Status = XtLdrProtocol->Utils.GetConfigurationTable(&SmBiosGuid, (PVOID*)&SmBios);
if(Status != STATUS_EFI_SUCCESS || !ValidateAcpiTable(SmBios, SmBios->Length)) if(Status != STATUS_EFI_SUCCESS || !ValidateAcpiTable(SmBios, SmBios->Length))
{ {
/* SMBIOS not found or checksum mismatch */ /* SMBIOS not found or checksum mismatch */
@@ -292,7 +292,7 @@ Acpi::GetSMBios3Table(OUT PVOID *SmBiosTable)
EFI_STATUS Status; EFI_STATUS Status;
/* Get SMBIOS3 table from system configuration tables */ /* Get SMBIOS3 table from system configuration tables */
Status = XtLdrProtocol->Util.GetConfigurationTable(&SmBios3Guid, (PVOID*)&SmBios); Status = XtLdrProtocol->Utils.GetConfigurationTable(&SmBios3Guid, (PVOID*)&SmBios);
if(Status != STATUS_EFI_SUCCESS || !ValidateAcpiTable(SmBios, SmBios->Length)) if(Status != STATUS_EFI_SUCCESS || !ValidateAcpiTable(SmBios, SmBios->Length))
{ {
/* SMBIOS3 not found or checksum mismatch */ /* SMBIOS3 not found or checksum mismatch */
@@ -324,7 +324,7 @@ Acpi::GetXsdpTable(OUT PVOID *AcpiTable)
PVOID XsdpTable; PVOID XsdpTable;
/* Get XSDP (ACPI 2.0) from system configuration tables */ /* Get XSDP (ACPI 2.0) from system configuration tables */
Status = XtLdrProtocol->Util.GetConfigurationTable(&AcpiGuid, &XsdpTable); Status = XtLdrProtocol->Utils.GetConfigurationTable(&AcpiGuid, &XsdpTable);
if(Status != STATUS_EFI_SUCCESS || !ValidateAcpiTable(XsdpTable, 36)) if(Status != STATUS_EFI_SUCCESS || !ValidateAcpiTable(XsdpTable, 36))
{ {
/* XSDP not found or checksum mismatch */ /* XSDP not found or checksum mismatch */

View File

@@ -167,7 +167,7 @@ Beep::PlayTune(IN PWCHAR Arguments)
} }
/* Wait for duration time */ /* Wait for duration time */
XtLdrProtocol->Util.SleepExecution(60000 * Duration / Tempo); XtLdrProtocol->Utils.SleepExecution(60000 * Duration / Tempo);
/* Reset pitch and duration */ /* Reset pitch and duration */
Pitch = -1; Pitch = -1;

View File

@@ -90,8 +90,8 @@ ChainLoader::BootSystem(IN PXTBL_BOOT_PARAMETERS Parameters)
MemoryDevicePath[1].Header.SubType = EFI_END_ENTIRE_DP; MemoryDevicePath[1].Header.SubType = EFI_END_ENTIRE_DP;
/* Load EFI image */ /* Load EFI image */
Status = XtLdrProtocol->Util.LoadEfiImage((PEFI_DEVICE_PATH_PROTOCOL)MemoryDevicePath, Status = XtLdrProtocol->Utils.LoadEfiImage((PEFI_DEVICE_PATH_PROTOCOL)MemoryDevicePath,
LoaderData, LoaderSize, &LoaderHandle); LoaderData, LoaderSize, &LoaderHandle);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to chainload EFI binary, return error code */ /* Failed to chainload EFI binary, return error code */
@@ -121,7 +121,7 @@ ChainLoader::BootSystem(IN PXTBL_BOOT_PARAMETERS Parameters)
LoadedImage->DeviceHandle = DiskHandle; LoadedImage->DeviceHandle = DiskHandle;
/* Chainload EFI image */ /* Chainload EFI image */
return XtLdrProtocol->Util.StartEfiImage(LoaderHandle); return XtLdrProtocol->Utils.StartEfiImage(LoaderHandle);
} }
/** /**

View File

@@ -45,7 +45,7 @@ Xtos::DeterminePagingLevel(IN CONST PWCHAR Parameters)
/* Check if eXtended Physical Addressing (XPA) is enabled and if LA57 is supported by the CPU */ /* Check if eXtended Physical Addressing (XPA) is enabled and if LA57 is supported by the CPU */
if((CpuRegisters.Ecx & CPUID_FEATURES_ECX_LA57) && if((CpuRegisters.Ecx & CPUID_FEATURES_ECX_LA57) &&
!(XtLdrProtocol->BootUtil.GetBooleanParameter(Parameters, L"NOXPA"))) !(XtLdrProtocol->BootUtils.GetBooleanParameter(Parameters, L"NOXPA")))
{ {
/* Enable LA57 (PML5) */ /* Enable LA57 (PML5) */
return 5; return 5;
@@ -98,7 +98,7 @@ Xtos::EnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
if(PageMap->PageMapLevel == 5) if(PageMap->PageMapLevel == 5)
{ {
/* Get the trampoline code information */ /* Get the trampoline code information */
XtLdrProtocol->BootUtil.GetTrampolineInformation(TrampolineEnableXpa, &TrampolineCode, &TrampolineSize); XtLdrProtocol->BootUtils.GetTrampolineInformation(TrampolineEnableXpa, &TrampolineCode, &TrampolineSize);
if(TrampolineCode == NULLPTR || TrampolineSize == 0) if(TrampolineCode == NULLPTR || TrampolineSize == 0)
{ {
/* Failed to get trampoline information */ /* Failed to get trampoline information */
@@ -125,7 +125,7 @@ Xtos::EnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
/* Exit EFI Boot Services */ /* Exit EFI Boot Services */
XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n"); XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n");
Status = XtLdrProtocol->Util.ExitBootServices(); Status = XtLdrProtocol->Utils.ExitBootServices();
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to exit boot services */ /* Failed to exit boot services */

View File

@@ -34,7 +34,7 @@ Xtos::DeterminePagingLevel(IN CONST PWCHAR Parameters)
/* Check if eXtended Physical Addressing (XPA) is enabled and if PAE is supported by the CPU */ /* Check if eXtended Physical Addressing (XPA) is enabled and if PAE is supported by the CPU */
if((CpuRegisters.Edx & CPUID_FEATURES_EDX_PAE) && if((CpuRegisters.Edx & CPUID_FEATURES_EDX_PAE) &&
!(XtLdrProtocol->BootUtil.GetBooleanParameter(Parameters, L"NOXPA"))) !(XtLdrProtocol->BootUtils.GetBooleanParameter(Parameters, L"NOXPA")))
{ {
/* Enable PAE (PML3) */ /* Enable PAE (PML3) */
return 3; return 3;
@@ -80,7 +80,7 @@ Xtos::EnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
/* Exit EFI Boot Services */ /* Exit EFI Boot Services */
XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n"); XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n");
Status = XtLdrProtocol->Util.ExitBootServices(); Status = XtLdrProtocol->Utils.ExitBootServices();
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to exit boot services */ /* Failed to exit boot services */

View File

@@ -24,8 +24,8 @@
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlCloseProtocol(IN PEFI_HANDLE Handle, Protocol::CloseProtocol(IN PEFI_HANDLE Handle,
IN PEFI_GUID ProtocolGuid) IN PEFI_GUID ProtocolGuid)
{ {
return EfiSystemTable->BootServices->CloseProtocol(Handle, ProtocolGuid, EfiImageHandle, NULLPTR); return EfiSystemTable->BootServices->CloseProtocol(Handle, ProtocolGuid, EfiImageHandle, NULLPTR);
} }
@@ -45,8 +45,8 @@ BlCloseProtocol(IN PEFI_HANDLE Handle,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlFindBootProtocol(IN PCWSTR SystemType, Protocol::FindBootProtocol(IN PCWSTR SystemType,
OUT PEFI_GUID BootProtocolGuid) OUT PEFI_GUID BootProtocolGuid)
{ {
PXTBL_KNOWN_BOOT_PROTOCOL ProtocolEntry; PXTBL_KNOWN_BOOT_PROTOCOL ProtocolEntry;
PLIST_ENTRY ProtocolListEntry; PLIST_ENTRY ProtocolListEntry;
@@ -84,7 +84,7 @@ BlFindBootProtocol(IN PCWSTR SystemType,
*/ */
XTCDECL XTCDECL
PLIST_ENTRY PLIST_ENTRY
BlGetModulesList() Protocol::GetModulesList()
{ {
/* Return a pointer to a list of all loaded modules */ /* Return a pointer to a list of all loaded modules */
return &BlpLoadedModules; return &BlpLoadedModules;
@@ -105,8 +105,8 @@ BlGetModulesList()
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlInstallProtocol(IN PVOID Interface, Protocol::InstallProtocol(IN PVOID Interface,
IN PEFI_GUID Guid) IN PEFI_GUID Guid)
{ {
EFI_HANDLE Handle = NULLPTR; EFI_HANDLE Handle = NULLPTR;
@@ -114,6 +114,157 @@ BlInstallProtocol(IN PVOID Interface,
return EfiSystemTable->BootServices->InstallProtocolInterface(&Handle, Guid, EFI_NATIVE_INTERFACE, Interface); return EfiSystemTable->BootServices->InstallProtocolInterface(&Handle, Guid, EFI_NATIVE_INTERFACE, Interface);
} }
/**
* Loads all necessary modules and invokes boot protocol.
*
* @param ShortName
* Supplies a pointer to a short name of the chosen boot menu entry.
*
* @param OptionsList
* Supplies a pointer to list of options associated with chosen boot menu entry.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
Protocol::InvokeBootProtocol(IN PWCHAR ShortName,
IN PLIST_ENTRY OptionsList)
{
EFI_GUID VendorGuid = XT_BOOT_LOADER_PROTOCOL_GUID;
XTBL_BOOT_PARAMETERS BootParameters;
PXTBL_BOOT_PROTOCOL BootProtocol;
PLIST_ENTRY OptionsListEntry;
PXTBL_CONFIG_ENTRY Option;
EFI_GUID BootProtocolGuid;
SIZE_T ModuleListLength;
PWCHAR ModulesList;
EFI_HANDLE Handle;
EFI_STATUS Status;
/* Initialize boot parameters and a list of modules */
RTL::Memory::ZeroMemory(&BootParameters, sizeof(XTBL_BOOT_PARAMETERS));
ModulesList = NULLPTR;
/* Iterate through all options provided by boot menu entry and propagate boot parameters */
OptionsListEntry = OptionsList->Flink;
while(OptionsListEntry != OptionsList)
{
/* Get option */
Option = CONTAIN_RECORD(OptionsListEntry, XTBL_CONFIG_ENTRY, Flink);
/* Look for boot protocol and modules list */
if(RTL::WideString::CompareWideStringInsensitive(Option->Name, L"BOOTMODULES", 0) == 0)
{
/* Check a length of modules list */
ModuleListLength = RTL::WideString::WideStringLength(Option->Value, 0);
Status = Memory::AllocatePool(sizeof(WCHAR) * (ModuleListLength + 1), (PVOID *)&ModulesList);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to allocate memory, print error message and return status code */
Debug::Print(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status);
return STATUS_EFI_OUT_OF_RESOURCES;
}
/* Make a copy of modules list */
RTL::Memory::CopyMemory(ModulesList, Option->Value, sizeof(WCHAR) * (ModuleListLength + 1));
}
else if(RTL::WideString::CompareWideStringInsensitive(Option->Name, L"SYSTEMTYPE", 0) == 0)
{
/* Boot protocol found */
BootParameters.SystemType = Option->Value;
}
else if(RTL::WideString::CompareWideStringInsensitive(Option->Name, L"SYSTEMPATH", 0) == 0)
{
/* System path found, get volume device path */
Status = Volume::GetDevicePath(Option->Value, &BootParameters.DevicePath,
&BootParameters.ArcName, &BootParameters.SystemPath);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to find volume */
Debug::Print(L"ERROR: Failed to find volume device path (Status Code: 0x%zX)\n", Status);
return Status;
}
/* Get EFI compatible system path */
Status = Volume::GetEfiPath(BootParameters.SystemPath, &BootParameters.EfiPath);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to get EFI path */
Debug::Print(L"ERROR: Failed to get EFI path (Status Code: 0x%zX)\n", Status);
return Status;
}
}
else if(RTL::WideString::CompareWideStringInsensitive(Option->Name, L"KERNELFILE", 0) == 0)
{
/* Kernel file name found */
BootParameters.KernelFile = Option->Value;
}
else if(RTL::WideString::CompareWideStringInsensitive(Option->Name, L"INITRDFILE", 0) == 0)
{
/* Initrd file name found */
BootParameters.InitrdFile = Option->Value;
}
else if(RTL::WideString::CompareWideStringInsensitive(Option->Name, L"HALFILE", 0) == 0)
{
/* Hal file name found */
BootParameters.HalFile = Option->Value;
}
else if(RTL::WideString::CompareWideStringInsensitive(Option->Name, L"PARAMETERS", 0) == 0)
{
/* Kernel parameters found */
BootParameters.Parameters = Option->Value;
}
/* Move to the next option entry */
OptionsListEntry = OptionsListEntry->Flink;
}
/* Load all necessary modules */
Status = LoadModules(ModulesList);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to load modules, print error message and return status code */
Debug::Print(L"ERROR: Failed to load XTLDR modules (Status Code: 0x%zX)\n", Status);
return STATUS_EFI_NOT_READY;
}
/* Attempt to get boot protocol GUID */
Status = FindBootProtocol(BootParameters.SystemType, &BootProtocolGuid);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to get boot protocol GUID */
Debug::Print(L"ERROR: Unable to find appropriate boot protocol (Status Code: 0x%zX)\n", Status);
return STATUS_EFI_UNSUPPORTED;
}
/* Open boot protocol */
Status = OpenProtocol(&Handle, (PVOID *)&BootProtocol, &BootProtocolGuid);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to open boot protocol */
Debug::Print(L"ERROR: Failed to open boot protocol (Status Code: 0x%zX)\n", Status);
return Status;
}
/* Check if chosen operating system should be saved */
if(Configuration::GetBooleanValue(L"KEEPLASTBOOT"))
{
/* Save chosen operating system in NVRAM */
Status = EfiUtils::SetEfiVariable(&VendorGuid, L"XtLdrLastBootOS", (PVOID)ShortName, RTL::WideString::WideStringLength(ShortName, 0) * sizeof(WCHAR));
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to save chosen Operating System */
Debug::Print(L"WARNING: Failed to save chosen Operating System in NVRAM (Status Code: 0x%zX)\n", Status);
}
}
/* Boot Operating System */
return BootProtocol->BootSystem(&BootParameters);
}
/** /**
* Loads a specified XTLDR module from disk. * Loads a specified XTLDR module from disk.
* *
@@ -126,7 +277,7 @@ BlInstallProtocol(IN PVOID Interface,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlLoadModule(IN PWCHAR ModuleName) Protocol::LoadModule(IN PWCHAR ModuleName)
{ {
EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
PLIST_ENTRY DepsListEntry, ModuleListEntry; PLIST_ENTRY DepsListEntry, ModuleListEntry;
@@ -155,7 +306,7 @@ BlLoadModule(IN PWCHAR ModuleName)
if(RTL::WideString::CompareWideStringInsensitive(ModuleInfo->ModuleName, ModuleName, 0) == 0) if(RTL::WideString::CompareWideStringInsensitive(ModuleInfo->ModuleName, ModuleName, 0) == 0)
{ {
/* Module already loaded */ /* Module already loaded */
BlDebugPrint(L"WARNING: Module '%S' already loaded!\n", ModuleName); Debug::Print(L"WARNING: Module '%S' already loaded!\n", ModuleName);
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
} }
@@ -164,14 +315,14 @@ BlLoadModule(IN PWCHAR ModuleName)
} }
/* Print debug message */ /* Print debug message */
BlDebugPrint(L"Loading module '%S' ...\n", ModuleName); Debug::Print(L"Loading module '%S' ...\n", ModuleName);
/* Set module path */ /* Set module path */
RTL::Memory::CopyMemory(ModuleFileName, ModuleName, (RTL::WideString::WideStringLength(ModuleName, 0) + 1) * sizeof(WCHAR)); RTL::Memory::CopyMemory(ModuleFileName, ModuleName, (RTL::WideString::WideStringLength(ModuleName, 0) + 1) * sizeof(WCHAR));
RTL::WideString::ConcatenateWideString(ModuleFileName, (PWCHAR)L".EFI", 0); RTL::WideString::ConcatenateWideString(ModuleFileName, (PWCHAR)L".EFI", 0);
/* Open EFI volume */ /* Open EFI volume */
Status = BlOpenVolume(NULLPTR, &DiskHandle, &FsHandle); Status = Volume::OpenVolume(NULLPTR, &DiskHandle, &FsHandle);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to open a volume */ /* Failed to open a volume */
@@ -193,14 +344,14 @@ BlLoadModule(IN PWCHAR ModuleName)
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to open directory */ /* Failed to open directory */
BlCloseVolume(&DiskHandle); Volume::CloseVolume(&DiskHandle);
return Status; return Status;
} }
/* Read module file from disk and close directory and EFI volume */ /* Read module file from disk and close directory and EFI volume */
Status = BlReadFile(DirHandle, ModuleFileName, &ModuleData, &ModuleSize); Status = Volume::ReadFile(DirHandle, ModuleFileName, &ModuleData, &ModuleSize);
DirHandle->Close(DirHandle); DirHandle->Close(DirHandle);
BlCloseVolume(&DiskHandle); Volume::CloseVolume(&DiskHandle);
/* Make sure module file was read successfully */ /* Make sure module file was read successfully */
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
@@ -210,7 +361,7 @@ BlLoadModule(IN PWCHAR ModuleName)
} }
/* Allocate memory for module information block */ /* Allocate memory for module information block */
Status = BlAllocateMemoryPool(sizeof(XTBL_MODULE_INFO), (PVOID*)&ModuleInfo); Status = Memory::AllocatePool(sizeof(XTBL_MODULE_INFO), (PVOID*)&ModuleInfo);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to allocate memory */ /* Failed to allocate memory */
@@ -247,7 +398,7 @@ BlLoadModule(IN PWCHAR ModuleName)
SectionData = (PWCHAR)((PUCHAR)ModuleData + SectionHeader[SectionIndex].PointerToRawData); SectionData = (PWCHAR)((PUCHAR)ModuleData + SectionHeader[SectionIndex].PointerToRawData);
/* Get module information */ /* Get module information */
Status = BlpGetModuleInformation(SectionData, SectionHeader[SectionIndex].SizeOfRawData, ModuleInfo); Status = GetModuleInformation(SectionData, SectionHeader[SectionIndex].SizeOfRawData, ModuleInfo);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to read module information */ /* Failed to read module information */
@@ -271,12 +422,12 @@ BlLoadModule(IN PWCHAR ModuleName)
} }
/* Load dependency module */ /* Load dependency module */
BlDebugPrint(L"Module '%S' requires '%S' ...\n", ModuleName, ModuleDependency->ModuleName); Debug::Print(L"Module '%S' requires '%S' ...\n", ModuleName, ModuleDependency->ModuleName);
Status = BlLoadModule(ModuleDependency->ModuleName); Status = LoadModule(ModuleDependency->ModuleName);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to load module, print error message and return status code */ /* Failed to load module, print error message and return status code */
BlDebugPrint(L"Failed to load dependency module '%S' (Status Code: 0x%zX)\n", ModuleDependency->ModuleName, Status); Debug::Print(L"Failed to load dependency module '%S' (Status Code: 0x%zX)\n", ModuleDependency->ModuleName, Status);
return STATUS_EFI_UNSUPPORTED; return STATUS_EFI_UNSUPPORTED;
} }
@@ -298,20 +449,20 @@ BlLoadModule(IN PWCHAR ModuleName)
ModuleDevicePath[1].Header.SubType = EFI_END_ENTIRE_DP; ModuleDevicePath[1].Header.SubType = EFI_END_ENTIRE_DP;
/* Load EFI image */ /* Load EFI image */
BlDebugPrint(L"Starting module '%S' ...\n", ModuleName); Debug::Print(L"Starting module '%S' ...\n", ModuleName);
Status = BlLoadEfiImage((PEFI_DEVICE_PATH_PROTOCOL)ModuleDevicePath, ModuleData, ModuleSize, &ModuleHandle); Status = EfiUtils::LoadEfiImage((PEFI_DEVICE_PATH_PROTOCOL)ModuleDevicePath, ModuleData, ModuleSize, &ModuleHandle);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Check if caused by secure boot */ /* Check if caused by secure boot */
if(Status == STATUS_EFI_ACCESS_DENIED && BlpStatus.SecureBoot >= 1) if(Status == STATUS_EFI_ACCESS_DENIED && BlpStatus.SecureBoot >= 1)
{ {
/* SecureBoot signature validation failed */ /* SecureBoot signature validation failed */
BlDebugPrint(L"ERROR: SecureBoot signature validation failed, module '%S' will not be loaded\n", ModuleName); Debug::Print(L"ERROR: SecureBoot signature validation failed, module '%S' will not be loaded\n", ModuleName);
} }
else else
{ {
/* Failed to load module */ /* Failed to load module */
BlDebugPrint(L"ERROR: Unable to load module '%S' (Status Code: 0x%zX)\n", ModuleName, Status); Debug::Print(L"ERROR: Unable to load module '%S' (Status Code: 0x%zX)\n", ModuleName, Status);
} }
/* Return error status code */ /* Return error status code */
@@ -324,7 +475,7 @@ BlLoadModule(IN PWCHAR ModuleName)
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to open LoadedImage protocol */ /* Failed to open LoadedImage protocol */
BlDebugPrint(L"ERROR: Unable to access module interface (Status Code: 0x%zX)\n", Status); Debug::Print(L"ERROR: Unable to access module interface (Status Code: 0x%zX)\n", Status);
return Status; return Status;
} }
@@ -332,7 +483,7 @@ BlLoadModule(IN PWCHAR ModuleName)
if(LoadedImage->ImageCodeType != EfiBootServicesCode) if(LoadedImage->ImageCodeType != EfiBootServicesCode)
{ {
/* Different type set, probably 'runtime driver', refuse to load it */ /* Different type set, probably 'runtime driver', refuse to load it */
BlDebugPrint(L"ERROR: Loaded module is not a boot system driver\n"); Debug::Print(L"ERROR: Loaded module is not a boot system driver\n");
/* Close protocol and skip module */ /* Close protocol and skip module */
EfiSystemTable->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULLPTR); EfiSystemTable->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULLPTR);
@@ -349,11 +500,11 @@ BlLoadModule(IN PWCHAR ModuleName)
EfiSystemTable->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULLPTR); EfiSystemTable->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULLPTR);
/* Start EFI image */ /* Start EFI image */
Status = BlStartEfiImage(ModuleHandle); Status = EfiUtils::StartEfiImage(ModuleHandle);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to start module image */ /* Failed to start module image */
BlDebugPrint(L"ERROR: Failed to start module '%S' (Status Code: 0x%zX)\n", ModuleName, Status); Debug::Print(L"ERROR: Failed to start module '%S' (Status Code: 0x%zX)\n", ModuleName, Status);
return Status; return Status;
} }
@@ -376,7 +527,7 @@ BlLoadModule(IN PWCHAR ModuleName)
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlLoadModules(IN PWCHAR ModulesList) Protocol::LoadModules(IN PWCHAR ModulesList)
{ {
PWCHAR LastModule, Module; PWCHAR LastModule, Module;
EFI_STATUS ReturnStatus, Status; EFI_STATUS ReturnStatus, Status;
@@ -392,11 +543,11 @@ BlLoadModules(IN PWCHAR ModulesList)
/* Iterate over all arguments passed to boot loader */ /* Iterate over all arguments passed to boot loader */
while(Module != NULLPTR) while(Module != NULLPTR)
{ {
Status = BlLoadModule(Module); Status = LoadModule(Module);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to load module, print error message and set new return value */ /* Failed to load module, print error message and set new return value */
BlDebugPrint(L"ERROR: Failed to load module '%S' (Status Code: 0x%zX)\n", Module, Status); Debug::Print(L"ERROR: Failed to load module '%S' (Status Code: 0x%zX)\n", Module, Status);
ReturnStatus = STATUS_EFI_LOAD_ERROR; ReturnStatus = STATUS_EFI_LOAD_ERROR;
} }
@@ -427,9 +578,9 @@ BlLoadModules(IN PWCHAR ModulesList)
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlLocateProtocolHandles(OUT PEFI_HANDLE *Handles, Protocol::LocateProtocolHandles(OUT PEFI_HANDLE *Handles,
OUT PUINT_PTR Count, OUT PUINT_PTR Count,
IN PEFI_GUID ProtocolGuid) IN PEFI_GUID ProtocolGuid)
{ {
return EfiSystemTable->BootServices->LocateHandleBuffer(ByProtocol, ProtocolGuid, NULLPTR, Count, Handles); return EfiSystemTable->BootServices->LocateHandleBuffer(ByProtocol, ProtocolGuid, NULLPTR, Count, Handles);
} }
@@ -452,9 +603,9 @@ BlLocateProtocolHandles(OUT PEFI_HANDLE *Handles,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlOpenProtocol(OUT PEFI_HANDLE Handle, Protocol::OpenProtocol(OUT PEFI_HANDLE Handle,
OUT PVOID *ProtocolHandler, OUT PVOID *ProtocolHandler,
IN PEFI_GUID ProtocolGuid) IN PEFI_GUID ProtocolGuid)
{ {
PEFI_HANDLE Handles = NULLPTR; PEFI_HANDLE Handles = NULLPTR;
EFI_STATUS Status; EFI_STATUS Status;
@@ -462,7 +613,7 @@ BlOpenProtocol(OUT PEFI_HANDLE Handle,
UINT Index; UINT Index;
/* Try to locate the handles */ /* Try to locate the handles */
Status = BlLocateProtocolHandles(&Handles, &Count, ProtocolGuid); Status = LocateProtocolHandles(&Handles, &Count, ProtocolGuid);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Unable to get handles */ /* Unable to get handles */
@@ -476,7 +627,7 @@ BlOpenProtocol(OUT PEFI_HANDLE Handle,
for(Index = 0; Index < Count; Index++) for(Index = 0; Index < Count; Index++)
{ {
/* Try to open protocol */ /* Try to open protocol */
Status = BlOpenProtocolHandle(Handles[Index], ProtocolHandler, ProtocolGuid); Status = OpenProtocolHandle(Handles[Index], ProtocolHandler, ProtocolGuid);
/* Check if successfully opened the loader protocol */ /* Check if successfully opened the loader protocol */
if(Status == STATUS_EFI_SUCCESS) if(Status == STATUS_EFI_SUCCESS)
@@ -520,9 +671,9 @@ BlOpenProtocol(OUT PEFI_HANDLE Handle,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlOpenProtocolHandle(IN EFI_HANDLE Handle, Protocol::OpenProtocolHandle(IN EFI_HANDLE Handle,
OUT PVOID *ProtocolHandler, OUT PVOID *ProtocolHandler,
IN PEFI_GUID ProtocolGuid) IN PEFI_GUID ProtocolGuid)
{ {
return EfiSystemTable->BootServices->OpenProtocol(Handle, ProtocolGuid, ProtocolHandler, EfiImageHandle, return EfiSystemTable->BootServices->OpenProtocol(Handle, ProtocolGuid, ProtocolHandler, EfiImageHandle,
NULLPTR, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL); NULLPTR, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
@@ -540,7 +691,7 @@ BlOpenProtocolHandle(IN EFI_HANDLE Handle,
*/ */
XTCDECL XTCDECL
VOID VOID
BlRegisterBootMenu(IN PVOID BootMenuRoutine) Protocol::RegisterBootMenu(IN PVOID BootMenuRoutine)
{ {
/* Set boot menu routine */ /* Set boot menu routine */
BlpStatus.BootMenu = (PBL_XT_BOOT_MENU)BootMenuRoutine; BlpStatus.BootMenu = (PBL_XT_BOOT_MENU)BootMenuRoutine;
@@ -561,8 +712,8 @@ BlRegisterBootMenu(IN PVOID BootMenuRoutine)
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlRegisterBootProtocol(IN PCWSTR SystemType, Protocol::RegisterBootProtocol(IN PCWSTR SystemType,
IN PEFI_GUID BootProtocolGuid) IN PEFI_GUID BootProtocolGuid)
{ {
PXTBL_KNOWN_BOOT_PROTOCOL ProtocolEntry; PXTBL_KNOWN_BOOT_PROTOCOL ProtocolEntry;
PLIST_ENTRY ProtocolListEntry; PLIST_ENTRY ProtocolListEntry;
@@ -586,7 +737,7 @@ BlRegisterBootProtocol(IN PCWSTR SystemType,
} }
/* Create new boot protocol entry */ /* Create new boot protocol entry */
Status = BlAllocateMemoryPool(sizeof(XTBL_BOOT_PROTOCOL), (PVOID *)&ProtocolEntry); Status = Memory::AllocatePool(sizeof(XTBL_BOOT_PROTOCOL), (PVOID *)&ProtocolEntry);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure */ /* Memory allocation failure */
@@ -620,9 +771,9 @@ BlRegisterBootProtocol(IN PCWSTR SystemType,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlpGetModuleInformation(IN PWCHAR SectionData, Protocol::GetModuleInformation(IN PWCHAR SectionData,
IN ULONG SectionSize, IN ULONG SectionSize,
OUT PXTBL_MODULE_INFO ModuleInfo) OUT PXTBL_MODULE_INFO ModuleInfo)
{ {
PXTBL_MODULE_DEPS ModuleDependencies; PXTBL_MODULE_DEPS ModuleDependencies;
PXTBL_MODULE_AUTHORS ModuleAuthors; PXTBL_MODULE_AUTHORS ModuleAuthors;
@@ -636,7 +787,7 @@ BlpGetModuleInformation(IN PWCHAR SectionData,
RTL::LinkedList::InitializeListHead(&ModuleInfo->Dependencies); RTL::LinkedList::InitializeListHead(&ModuleInfo->Dependencies);
/* Get information strings from '.modinfo' section */ /* Get information strings from '.modinfo' section */
Status = BlpGetModuleInfoStrings(SectionData, SectionSize, &Strings, &Count); Status = GetModuleInfoStrings(SectionData, SectionSize, &Strings, &Count);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to get information strings */ /* Failed to get information strings */
@@ -664,7 +815,7 @@ BlpGetModuleInformation(IN PWCHAR SectionData,
if(RTL::WideString::CompareWideString(Key, L"author", 6) == 0) if(RTL::WideString::CompareWideString(Key, L"author", 6) == 0)
{ {
/* Allocate memory for module author */ /* Allocate memory for module author */
Status = BlAllocateMemoryPool(sizeof(XTBL_MODULE_AUTHORS), (PVOID*)&ModuleAuthors); Status = Memory::AllocatePool(sizeof(XTBL_MODULE_AUTHORS), (PVOID*)&ModuleAuthors);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure */ /* Memory allocation failure */
@@ -692,7 +843,7 @@ BlpGetModuleInformation(IN PWCHAR SectionData,
while(Dependency != NULLPTR) while(Dependency != NULLPTR)
{ {
/* Allocate memory for module dependency */ /* Allocate memory for module dependency */
Status = BlAllocateMemoryPool(sizeof(XTBL_MODULE_DEPS), (PVOID*)&ModuleDependencies); Status = Memory::AllocatePool(sizeof(XTBL_MODULE_DEPS), (PVOID*)&ModuleDependencies);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure */ /* Memory allocation failure */
@@ -739,10 +890,10 @@ BlpGetModuleInformation(IN PWCHAR SectionData,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlpGetModuleInfoStrings(IN PWCHAR SectionData, Protocol::GetModuleInfoStrings(IN PWCHAR SectionData,
IN ULONG SectionSize, IN ULONG SectionSize,
OUT PWCHAR **ModInfo, OUT PWCHAR **ModInfo,
OUT PULONG InfoCount) OUT PULONG InfoCount)
{ {
ULONG Count, Index, ArrayIndex; ULONG Count, Index, ArrayIndex;
PCWSTR InfoStrings; PCWSTR InfoStrings;
@@ -801,7 +952,7 @@ BlpGetModuleInfoStrings(IN PWCHAR SectionData,
} }
/* Allocate memory for the pointer array and the string data */ /* Allocate memory for the pointer array and the string data */
Status = BlAllocateMemoryPool(sizeof(PWCHAR) * (Count + 1) + (DataSize + 1) * sizeof(WCHAR), (PVOID *)&Array); Status = Memory::AllocatePool(sizeof(PWCHAR) * (Count + 1) + (DataSize + 1) * sizeof(WCHAR), (PVOID *)&Array);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to allocate memory */ /* Failed to allocate memory */
@@ -858,42 +1009,42 @@ BlpGetModuleInfoStrings(IN PWCHAR SectionData,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlpInstallXtLoaderProtocol() Protocol::InstallXtLoaderProtocol()
{ {
EFI_GUID Guid = XT_BOOT_LOADER_PROTOCOL_GUID; EFI_GUID Guid = XT_BOOT_LOADER_PROTOCOL_GUID;
/* Set all routines available via loader protocol */ /* Set all routines available via loader protocol */
BlpLdrProtocol.Boot.FindProtocol = BlFindBootProtocol; BlpLdrProtocol.Boot.FindProtocol = FindBootProtocol;
BlpLdrProtocol.Boot.InitializeMenuList = BlInitializeBootMenuList; BlpLdrProtocol.Boot.InitializeMenuList = XtLoader::InitializeBootMenuList;
BlpLdrProtocol.Boot.InvokeProtocol = BlInvokeBootProtocol; BlpLdrProtocol.Boot.InvokeProtocol = InvokeBootProtocol;
BlpLdrProtocol.Boot.RegisterMenu = BlRegisterBootMenu; BlpLdrProtocol.Boot.RegisterMenu = RegisterBootMenu;
BlpLdrProtocol.Boot.RegisterProtocol = BlRegisterBootProtocol; BlpLdrProtocol.Boot.RegisterProtocol = RegisterBootProtocol;
BlpLdrProtocol.BootUtil.GetBooleanParameter = BlGetBooleanParameter; BlpLdrProtocol.BootUtils.GetBooleanParameter = BootUtils::GetBooleanParameter;
BlpLdrProtocol.BootUtil.GetTrampolineInformation = AR::ProcSup::GetTrampolineInformation; BlpLdrProtocol.BootUtils.GetTrampolineInformation = AR::ProcSup::GetTrampolineInformation;
BlpLdrProtocol.Config.GetBooleanValue = BlGetConfigBooleanValue; BlpLdrProtocol.Config.GetBooleanValue = Configuration::GetBooleanValue;
BlpLdrProtocol.Config.GetBootOptionValue = BlGetBootOptionValue; BlpLdrProtocol.Config.GetBootOptionValue = Configuration::GetBootOptionValue;
BlpLdrProtocol.Config.GetEditableOptions = BlGetEditableOptions; BlpLdrProtocol.Config.GetEditableOptions = Configuration::GetEditableOptions;
BlpLdrProtocol.Config.GetValue = BlGetConfigValue; BlpLdrProtocol.Config.GetValue = Configuration::GetValue;
BlpLdrProtocol.Config.SetBootOptionValue = BlSetBootOptionValue; BlpLdrProtocol.Config.SetBootOptionValue = Configuration::SetBootOptionValue;
BlpLdrProtocol.Console.ClearLine = BlClearConsoleLine; BlpLdrProtocol.Console.ClearLine = Console::ClearLine;
BlpLdrProtocol.Console.ClearScreen = BlClearConsoleScreen; BlpLdrProtocol.Console.ClearScreen = Console::ClearScreen;
BlpLdrProtocol.Console.DisableCursor = BlDisableConsoleCursor; BlpLdrProtocol.Console.DisableCursor = Console::DisableCursor;
BlpLdrProtocol.Console.EnableCursor = BlEnableConsoleCursor; BlpLdrProtocol.Console.EnableCursor = Console::EnableCursor;
BlpLdrProtocol.Console.Print = BlConsolePrint; BlpLdrProtocol.Console.Print = Console::Print;
BlpLdrProtocol.Console.QueryMode = BlQueryConsoleMode; BlpLdrProtocol.Console.QueryMode = Console::QueryMode;
BlpLdrProtocol.Console.ReadKeyStroke = BlReadKeyStroke; BlpLdrProtocol.Console.ReadKeyStroke = Console::ReadKeyStroke;
BlpLdrProtocol.Console.ResetInputBuffer = BlResetConsoleInputBuffer; BlpLdrProtocol.Console.ResetInputBuffer = Console::ResetInputBuffer;
BlpLdrProtocol.Console.SetAttributes = BlSetConsoleAttributes; BlpLdrProtocol.Console.SetAttributes = Console::SetAttributes;
BlpLdrProtocol.Console.SetCursorPosition = BlSetCursorPosition; BlpLdrProtocol.Console.SetCursorPosition = Console::SetCursorPosition;
BlpLdrProtocol.Console.Write = BlConsoleWrite; BlpLdrProtocol.Console.Write = Console::Write;
BlpLdrProtocol.Cpu.CpuId = AR::CpuFunc::CpuId; BlpLdrProtocol.Cpu.CpuId = AR::CpuFunc::CpuId;
BlpLdrProtocol.Cpu.ReadControlRegister = AR::CpuFunc::ReadControlRegister; BlpLdrProtocol.Cpu.ReadControlRegister = AR::CpuFunc::ReadControlRegister;
BlpLdrProtocol.Cpu.ReadModelSpecificRegister = AR::CpuFunc::ReadModelSpecificRegister; BlpLdrProtocol.Cpu.ReadModelSpecificRegister = AR::CpuFunc::ReadModelSpecificRegister;
BlpLdrProtocol.Cpu.WriteControlRegister = AR::CpuFunc::WriteControlRegister; BlpLdrProtocol.Cpu.WriteControlRegister = AR::CpuFunc::WriteControlRegister;
BlpLdrProtocol.Debug.Print = BlDebugPrint; BlpLdrProtocol.Debug.Print = Debug::Print;
BlpLdrProtocol.Disk.CloseVolume = BlCloseVolume; BlpLdrProtocol.Disk.CloseVolume = Volume::CloseVolume;
BlpLdrProtocol.Disk.OpenVolume = BlOpenVolume; BlpLdrProtocol.Disk.OpenVolume = Volume::OpenVolume;
BlpLdrProtocol.Disk.ReadFile = BlReadFile; BlpLdrProtocol.Disk.ReadFile = Volume::ReadFile;
BlpLdrProtocol.IoPort.Read8 = HL::IoPort::ReadPort8; BlpLdrProtocol.IoPort.Read8 = HL::IoPort::ReadPort8;
BlpLdrProtocol.IoPort.Read16 = HL::IoPort::ReadPort16; BlpLdrProtocol.IoPort.Read16 = HL::IoPort::ReadPort16;
BlpLdrProtocol.IoPort.Read32 = HL::IoPort::ReadPort32; BlpLdrProtocol.IoPort.Read32 = HL::IoPort::ReadPort32;
@@ -904,54 +1055,54 @@ BlpInstallXtLoaderProtocol()
BlpLdrProtocol.LinkedList.InsertHead = RTL::LinkedList::InsertHeadList; BlpLdrProtocol.LinkedList.InsertHead = RTL::LinkedList::InsertHeadList;
BlpLdrProtocol.LinkedList.InsertTail = RTL::LinkedList::InsertTailList; BlpLdrProtocol.LinkedList.InsertTail = RTL::LinkedList::InsertTailList;
BlpLdrProtocol.LinkedList.RemoveEntry = RTL::LinkedList::RemoveEntryList; BlpLdrProtocol.LinkedList.RemoveEntry = RTL::LinkedList::RemoveEntryList;
BlpLdrProtocol.Memory.AllocatePages = BlAllocateMemoryPages; BlpLdrProtocol.Memory.AllocatePages = Memory::AllocatePages;
BlpLdrProtocol.Memory.AllocatePool = BlAllocateMemoryPool; BlpLdrProtocol.Memory.AllocatePool = Memory::AllocatePool;
BlpLdrProtocol.Memory.BuildPageMap = BlBuildPageMap; BlpLdrProtocol.Memory.BuildPageMap = Memory::BuildPageMap;
BlpLdrProtocol.Memory.CompareMemory = RTL::Memory::CompareMemory; BlpLdrProtocol.Memory.CompareMemory = RTL::Memory::CompareMemory;
BlpLdrProtocol.Memory.CopyMemory = RTL::Memory::CopyMemory; BlpLdrProtocol.Memory.CopyMemory = RTL::Memory::CopyMemory;
BlpLdrProtocol.Memory.FreePages = BlFreeMemoryPages; BlpLdrProtocol.Memory.FreePages = Memory::FreePages;
BlpLdrProtocol.Memory.FreePool = BlFreeMemoryPool; BlpLdrProtocol.Memory.FreePool = Memory::FreePool;
BlpLdrProtocol.Memory.GetMappingsCount = BlGetMappingsCount; BlpLdrProtocol.Memory.GetMappingsCount = Memory::GetMappingsCount;
BlpLdrProtocol.Memory.GetMemoryMap = BlGetMemoryMap; BlpLdrProtocol.Memory.GetMemoryMap = Memory::GetMemoryMap;
BlpLdrProtocol.Memory.GetVirtualAddress = BlGetVirtualAddress; BlpLdrProtocol.Memory.GetVirtualAddress = Memory::GetVirtualAddress;
BlpLdrProtocol.Memory.InitializePageMap = BlInitializePageMap; BlpLdrProtocol.Memory.InitializePageMap = Memory::InitializePageMap;
BlpLdrProtocol.Memory.MapEfiMemory = BlMapEfiMemory; BlpLdrProtocol.Memory.MapEfiMemory = Memory::MapEfiMemory;
BlpLdrProtocol.Memory.MapPage = BlMapPage; BlpLdrProtocol.Memory.MapPage = Memory::MapPage;
BlpLdrProtocol.Memory.MapVirtualMemory = BlMapVirtualMemory; BlpLdrProtocol.Memory.MapVirtualMemory = Memory::MapVirtualMemory;
BlpLdrProtocol.Memory.MoveMemory = RTL::Memory::MoveMemory; BlpLdrProtocol.Memory.MoveMemory = RTL::Memory::MoveMemory;
BlpLdrProtocol.Memory.PhysicalAddressToVirtual = BlPhysicalAddressToVirtual; BlpLdrProtocol.Memory.PhysicalAddressToVirtual = Memory::PhysicalAddressToVirtual;
BlpLdrProtocol.Memory.PhysicalListToVirtual = BlPhysicalListToVirtual; BlpLdrProtocol.Memory.PhysicalListToVirtual = Memory::PhysicalListToVirtual;
BlpLdrProtocol.Memory.SetMemory = RTL::Memory::SetMemory; BlpLdrProtocol.Memory.SetMemory = RTL::Memory::SetMemory;
BlpLdrProtocol.Memory.ZeroMemory = RTL::Memory::ZeroMemory; BlpLdrProtocol.Memory.ZeroMemory = RTL::Memory::ZeroMemory;
BlpLdrProtocol.Protocol.Close = BlCloseProtocol; BlpLdrProtocol.Protocol.Close = CloseProtocol;
BlpLdrProtocol.Protocol.GetModulesList = BlGetModulesList; BlpLdrProtocol.Protocol.GetModulesList = GetModulesList;
BlpLdrProtocol.Protocol.Install = BlInstallProtocol; BlpLdrProtocol.Protocol.Install = InstallProtocol;
BlpLdrProtocol.Protocol.LocateHandles = BlLocateProtocolHandles; BlpLdrProtocol.Protocol.LocateHandles = LocateProtocolHandles;
BlpLdrProtocol.Protocol.Open = BlOpenProtocol; BlpLdrProtocol.Protocol.Open = OpenProtocol;
BlpLdrProtocol.Protocol.OpenHandle = BlOpenProtocolHandle; BlpLdrProtocol.Protocol.OpenHandle = OpenProtocolHandle;
BlpLdrProtocol.String.Compare = RTL::String::CompareString; BlpLdrProtocol.String.Compare = RTL::String::CompareString;
BlpLdrProtocol.String.Length = RTL::String::StringLength; BlpLdrProtocol.String.Length = RTL::String::StringLength;
BlpLdrProtocol.String.ToWideString = RTL::String::StringToWideString; BlpLdrProtocol.String.ToWideString = RTL::String::StringToWideString;
BlpLdrProtocol.String.Trim = RTL::String::TrimString; BlpLdrProtocol.String.Trim = RTL::String::TrimString;
BlpLdrProtocol.Tui.DisplayErrorDialog = BlDisplayErrorDialog; BlpLdrProtocol.Tui.DisplayErrorDialog = TextUi::DisplayErrorDialog;
BlpLdrProtocol.Tui.DisplayInfoDialog = BlDisplayInfoDialog; BlpLdrProtocol.Tui.DisplayInfoDialog = TextUi::DisplayInfoDialog;
BlpLdrProtocol.Tui.DisplayInputDialog = BlDisplayInputDialog; BlpLdrProtocol.Tui.DisplayInputDialog = TextUi::DisplayInputDialog;
BlpLdrProtocol.Tui.DisplayProgressDialog = BlDisplayProgressDialog; BlpLdrProtocol.Tui.DisplayProgressDialog = TextUi::DisplayProgressDialog;
BlpLdrProtocol.Tui.UpdateProgressBar = BlUpdateProgressBar; BlpLdrProtocol.Tui.UpdateProgressBar = TextUi::UpdateProgressBar;
BlpLdrProtocol.Util.EnterFirmwareSetup = BlEnterFirmwareSetup; BlpLdrProtocol.Utils.EnterFirmwareSetup = EfiUtils::EnterFirmwareSetup;
BlpLdrProtocol.Util.ExitBootServices = BlExitBootServices; BlpLdrProtocol.Utils.ExitBootServices = EfiUtils::ExitBootServices;
BlpLdrProtocol.Util.GetConfigurationTable = BlGetConfigurationTable; BlpLdrProtocol.Utils.GetConfigurationTable = EfiUtils::GetConfigurationTable;
BlpLdrProtocol.Util.GetEfiVariable = BlGetEfiVariable; BlpLdrProtocol.Utils.GetEfiVariable = EfiUtils::GetEfiVariable;
BlpLdrProtocol.Util.GetRandomValue = BlGetRandomValue; BlpLdrProtocol.Utils.GetRandomValue = EfiUtils::GetRandomValue;
BlpLdrProtocol.Util.GetSecureBootStatus = BlGetSecureBootStatus; BlpLdrProtocol.Utils.GetSecureBootStatus = EfiUtils::GetSecureBootStatus;
BlpLdrProtocol.Util.InitializeEntropy = BlInitializeEntropy; BlpLdrProtocol.Utils.InitializeEntropy = EfiUtils::InitializeEntropy;
BlpLdrProtocol.Util.LoadEfiImage = BlLoadEfiImage; BlpLdrProtocol.Utils.LoadEfiImage = EfiUtils::LoadEfiImage;
BlpLdrProtocol.Util.RebootSystem = BlRebootSystem; BlpLdrProtocol.Utils.RebootSystem = EfiUtils::RebootSystem;
BlpLdrProtocol.Util.SetEfiVariable = BlSetEfiVariable; BlpLdrProtocol.Utils.SetEfiVariable = EfiUtils::SetEfiVariable;
BlpLdrProtocol.Util.ShutdownSystem = BlShutdownSystem; BlpLdrProtocol.Utils.ShutdownSystem = EfiUtils::ShutdownSystem;
BlpLdrProtocol.Util.SleepExecution = BlSleepExecution; BlpLdrProtocol.Utils.SleepExecution = EfiUtils::SleepExecution;
BlpLdrProtocol.Util.StartEfiImage = BlStartEfiImage; BlpLdrProtocol.Utils.StartEfiImage = EfiUtils::StartEfiImage;
BlpLdrProtocol.Util.WaitForEfiEvent = BlWaitForEfiEvent; BlpLdrProtocol.Utils.WaitForEfiEvent = EfiUtils::WaitForEfiEvent;
BlpLdrProtocol.WideString.Compare = RTL::WideString::CompareWideString; BlpLdrProtocol.WideString.Compare = RTL::WideString::CompareWideString;
BlpLdrProtocol.WideString.CompareInsensitive = RTL::WideString::CompareWideStringInsensitive; BlpLdrProtocol.WideString.CompareInsensitive = RTL::WideString::CompareWideStringInsensitive;
BlpLdrProtocol.WideString.Concatenate = RTL::WideString::ConcatenateWideString; BlpLdrProtocol.WideString.Concatenate = RTL::WideString::ConcatenateWideString;
@@ -960,6 +1111,6 @@ BlpInstallXtLoaderProtocol()
BlpLdrProtocol.WideString.Tokenize = RTL::WideString::TokenizeWideString; BlpLdrProtocol.WideString.Tokenize = RTL::WideString::TokenizeWideString;
/* Register XTLDR loader protocol */ /* Register XTLDR loader protocol */
BlDebugPrint(L"Registering XT loader protocol\n"); Debug::Print(L"Registering XT loader protocol\n");
return BlInstallProtocol(&BlpLdrProtocol, &Guid); return InstallProtocol(&BlpLdrProtocol, &Guid);
} }

View File

@@ -18,13 +18,13 @@
*/ */
XTCDECL XTCDECL
VOID VOID
BlStartLoaderShell() Shell::StartLoaderShell()
{ {
/* Initialize console */ /* Initialize console */
BlInitializeConsole(); Console::InitializeConsole();
/* Print prompt */ /* Print prompt */
BlpPrintShellPrompt(); PrintPrompt();
for(;;); for(;;);
} }
@@ -37,14 +37,14 @@ BlStartLoaderShell()
*/ */
XTCDECL XTCDECL
VOID VOID
BlpPrintShellPrompt() Shell::PrintPrompt()
{ {
/* Set prompt color */ /* Set prompt color */
BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_YELLOW); Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_YELLOW);
/* Print prompt */ /* Print prompt */
BlConsolePrint(L"XTLDR> "); Console::Print(L"XTLDR> ");
/* Reset standard shell colors */ /* Reset standard shell colors */
BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY); Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY);
} }

File diff suppressed because it is too large Load Diff

View File

@@ -22,7 +22,7 @@
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlCloseVolume(IN PEFI_HANDLE VolumeHandle) Volume::CloseVolume(IN PEFI_HANDLE VolumeHandle)
{ {
EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
@@ -46,7 +46,7 @@ BlCloseVolume(IN PEFI_HANDLE VolumeHandle)
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlEnumerateBlockDevices() Volume::EnumerateBlockDevices()
{ {
EFI_GUID LoadedImageProtocolGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; EFI_GUID LoadedImageProtocolGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
EFI_GUID BlockIoGuid = EFI_BLOCK_IO_PROTOCOL_GUID; EFI_GUID BlockIoGuid = EFI_BLOCK_IO_PROTOCOL_GUID;
@@ -72,7 +72,7 @@ BlEnumerateBlockDevices()
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to get boot device handle */ /* Failed to get boot device handle */
BlDebugPrint(L"ERROR: Failed to get boot device handle (Status Code: 0x%zX)\n", Status); Debug::Print(L"ERROR: Failed to get boot device handle (Status Code: 0x%zX)\n", Status);
return Status; return Status;
} }
@@ -84,10 +84,10 @@ BlEnumerateBlockDevices()
RTL::LinkedList::InitializeListHead(&EfiBlockDevices); RTL::LinkedList::InitializeListHead(&EfiBlockDevices);
/* Discover EFI block devices and store them in linked list */ /* Discover EFI block devices and store them in linked list */
Status = BlpDiscoverEfiBlockDevices(&BlockDevices); Status = DiscoverEfiBlockDevices(&BlockDevices);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
BlDebugPrint(L"ERROR: Failed to discover EFI block devices (Status Code: 0x%zX)\n", Status); Debug::Print(L"ERROR: Failed to discover EFI block devices (Status Code: 0x%zX)\n", Status);
return Status; return Status;
} }
@@ -100,11 +100,11 @@ BlEnumerateBlockDevices()
PartitionGuid = NULLPTR; PartitionGuid = NULLPTR;
/* Find last node */ /* Find last node */
Status = BlpFindLastBlockDeviceNode(BlockDeviceData->DevicePath, &LastNode); Status = FindLastBlockDeviceNode(BlockDeviceData->DevicePath, &LastNode);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Skip this device if its last node cannot be found, as it is required for classification */ /* Skip this device if its last node cannot be found, as it is required for classification */
BlDebugPrint(L"WARNING: Block device last node not found\n"); Debug::Print(L"WARNING: Block device last node not found\n");
ListEntry = ListEntry->Flink; ListEntry = ListEntry->Flink;
continue; continue;
} }
@@ -113,10 +113,10 @@ BlEnumerateBlockDevices()
DriveType = XTBL_BOOT_DEVICE_UNKNOWN; DriveType = XTBL_BOOT_DEVICE_UNKNOWN;
/* Locate the parent for this block device to ensure it is not an orphaned entry */ /* Locate the parent for this block device to ensure it is not an orphaned entry */
if(!BlpFindParentBlockDevice(&BlockDevices, BlockDeviceData, &ParentNode)) if(!FindParentBlockDevice(&BlockDevices, BlockDeviceData, &ParentNode))
{ {
/* Orphaned device found. Log a warning and skip it as it cannot be properly classified */ /* Orphaned device found. Log a warning and skip it as it cannot be properly classified */
BlDebugPrint(L"WARNING: No parent device found, skipping orphaned media device path\n"); Debug::Print(L"WARNING: No parent device found, skipping orphaned media device path\n");
ListEntry = ListEntry->Flink; ListEntry = ListEntry->Flink;
continue; continue;
} }
@@ -125,7 +125,7 @@ BlEnumerateBlockDevices()
if(!BlockDeviceData->BlockIo->Media) if(!BlockDeviceData->BlockIo->Media)
{ {
/* The device is unusable without media info, log a warning and skip it */ /* The device is unusable without media info, log a warning and skip it */
BlDebugPrint(L"WARNING: Block device is missing media information\n"); Debug::Print(L"WARNING: Block device is missing media information\n");
ListEntry = ListEntry->Flink; ListEntry = ListEntry->Flink;
continue; continue;
} }
@@ -144,7 +144,7 @@ BlEnumerateBlockDevices()
PartitionNumber = 0; PartitionNumber = 0;
/* Print debug message */ /* Print debug message */
BlDebugPrint(L"Found Floppy Disk (DiskNumber: %lu, MediaPresent: %u, RO: %u)\n", Debug::Print(L"Found Floppy Disk (DiskNumber: %lu, MediaPresent: %u, RO: %u)\n",
DriveNumber, Media->MediaPresent, Media->ReadOnly); DriveNumber, Media->MediaPresent, Media->ReadOnly);
} }
} }
@@ -159,7 +159,7 @@ BlEnumerateBlockDevices()
PartitionNumber = 0; PartitionNumber = 0;
/* Print debug message */ /* Print debug message */
BlDebugPrint(L"Found CD-ROM drive (DriveNumber: %lu, MediaPresent: %u, RemovableMedia: %u, RO: %u)\n", Debug::Print(L"Found CD-ROM drive (DriveNumber: %lu, MediaPresent: %u, RemovableMedia: %u, RO: %u)\n",
DriveNumber, Media->MediaPresent, Media->RemovableMedia, Media->ReadOnly); DriveNumber, Media->MediaPresent, Media->RemovableMedia, Media->ReadOnly);
} }
else if(LastNode->Type == EFI_MEDIA_DEVICE_PATH && LastNode->SubType == EFI_MEDIA_HARDDRIVE_DP) else if(LastNode->Type == EFI_MEDIA_DEVICE_PATH && LastNode->SubType == EFI_MEDIA_HARDDRIVE_DP)
@@ -175,7 +175,7 @@ BlEnumerateBlockDevices()
if(BootDeviceHandle != NULLPTR) if(BootDeviceHandle != NULLPTR)
{ {
/* Allocate memory for device path */ /* Allocate memory for device path */
DevicePath = BlpDuplicateDevicePath(BlockDeviceData->DevicePath); DevicePath = DuplicateDevicePath(BlockDeviceData->DevicePath);
if(DevicePath != NULLPTR) if(DevicePath != NULLPTR)
{ {
/* Check if this is the boot device */ /* Check if this is the boot device */
@@ -190,7 +190,7 @@ BlEnumerateBlockDevices()
} }
/* Print debug message */ /* Print debug message */
BlDebugPrint(L"Found Hard Disk partition (DiskNumber: %lu, PartNumber: %lu, " Debug::Print(L"Found Hard Disk partition (DiskNumber: %lu, PartNumber: %lu, "
L"MBRType: %u, GUID: {%V}, PartSize: %lluB) %S\n", L"MBRType: %u, GUID: {%V}, PartSize: %lluB) %S\n",
DriveNumber, PartitionNumber, HDPath->MBRType, DriveNumber, PartitionNumber, HDPath->MBRType,
PartitionGuid, HDPath->PartitionSize * Media->BlockSize, PartitionGuid, HDPath->PartitionSize * Media->BlockSize,
@@ -204,7 +204,7 @@ BlEnumerateBlockDevices()
PartitionNumber = 0; PartitionNumber = 0;
/* Print debug message */ /* Print debug message */
BlDebugPrint(L"Found RAM Disk (DiskNumber: %lu, MediaPresent: %u)\n", Debug::Print(L"Found RAM Disk (DiskNumber: %lu, MediaPresent: %u)\n",
DriveNumber, Media->MediaPresent); DriveNumber, Media->MediaPresent);
} }
@@ -212,15 +212,15 @@ BlEnumerateBlockDevices()
if(DriveType != XTBL_BOOT_DEVICE_UNKNOWN) if(DriveType != XTBL_BOOT_DEVICE_UNKNOWN)
{ {
/* Allocate memory for block device */ /* Allocate memory for block device */
Status = BlAllocateMemoryPool(sizeof(EFI_BLOCK_DEVICE), (PVOID *)&BlockDevice); Status = Memory::AllocatePool(sizeof(EFI_BLOCK_DEVICE), (PVOID *)&BlockDevice);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
BlDebugPrint(L"ERROR: Failed to allocate memory pool for block device (Status Code: 0x%zX)\n", Status); Debug::Print(L"ERROR: Failed to allocate memory pool for block device (Status Code: 0x%zX)\n", Status);
return STATUS_EFI_OUT_OF_RESOURCES; return STATUS_EFI_OUT_OF_RESOURCES;
} }
/* Initialize block device */ /* Initialize block device */
BlockDevice->DevicePath = BlpDuplicateDevicePath(BlockDeviceData->DevicePath); BlockDevice->DevicePath = DuplicateDevicePath(BlockDeviceData->DevicePath);
BlockDevice->DriveType = DriveType; BlockDevice->DriveType = DriveType;
BlockDevice->DriveNumber = DriveNumber; BlockDevice->DriveNumber = DriveNumber;
BlockDevice->PartitionNumber = PartitionNumber; BlockDevice->PartitionNumber = PartitionNumber;
@@ -256,7 +256,7 @@ BlEnumerateBlockDevices()
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle, Volume::FindDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle,
IN CONST PWCHAR FileSystemPath, IN CONST PWCHAR FileSystemPath,
OUT PEFI_DEVICE_PATH_PROTOCOL* DevicePath) OUT PEFI_DEVICE_PATH_PROTOCOL* DevicePath)
{ {
@@ -294,7 +294,7 @@ BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle,
FsPathLength = RTL::WideString::WideStringLength(FileSystemPath, 0) * sizeof(WCHAR); FsPathLength = RTL::WideString::WideStringLength(FileSystemPath, 0) * sizeof(WCHAR);
/* Allocate memory pool for device path */ /* Allocate memory pool for device path */
Status = BlAllocateMemoryPool(FsPathLength + DevicePathLength + sizeof(EFI_DEVICE_PATH_PROTOCOL), Status = Memory::AllocatePool(FsPathLength + DevicePathLength + sizeof(EFI_DEVICE_PATH_PROTOCOL),
(PVOID *)DevicePath); (PVOID *)DevicePath);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
@@ -337,8 +337,8 @@ BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlGetEfiPath(IN PWCHAR SystemPath, Volume::GetEfiPath(IN PWCHAR SystemPath,
OUT PWCHAR *EfiPath) OUT PWCHAR *EfiPath)
{ {
SIZE_T Index, PathLength; SIZE_T Index, PathLength;
EFI_STATUS Status; EFI_STATUS Status;
@@ -347,11 +347,11 @@ BlGetEfiPath(IN PWCHAR SystemPath,
PathLength = RTL::WideString::WideStringLength(SystemPath, 0); PathLength = RTL::WideString::WideStringLength(SystemPath, 0);
/* Allocate memory for storing EFI path */ /* Allocate memory for storing EFI path */
Status = BlAllocateMemoryPool(sizeof(WCHAR) * (PathLength + 1), (PVOID *)EfiPath); Status = Memory::AllocatePool(sizeof(WCHAR) * (PathLength + 1), (PVOID *)EfiPath);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to allocate memory, print error message and return status code */ /* Failed to allocate memory, print error message and return status code */
BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status); Debug::Print(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status);
return STATUS_EFI_OUT_OF_RESOURCES; return STATUS_EFI_OUT_OF_RESOURCES;
} }
@@ -390,7 +390,7 @@ BlGetEfiPath(IN PWCHAR SystemPath,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlGetVolumeDevicePath(IN PWCHAR SystemPath, Volume::GetDevicePath(IN PWCHAR SystemPath,
OUT PEFI_DEVICE_PATH_PROTOCOL *DevicePath, OUT PEFI_DEVICE_PATH_PROTOCOL *DevicePath,
OUT PWCHAR *ArcName, OUT PWCHAR *ArcName,
OUT PWCHAR *Path) OUT PWCHAR *Path)
@@ -429,13 +429,13 @@ BlGetVolumeDevicePath(IN PWCHAR SystemPath,
if(PathLength == GUID_STRING_LENGTH) if(PathLength == GUID_STRING_LENGTH)
{ {
/* This is EFI GUID */ /* This is EFI GUID */
BlDebugPrint(L"WARNING: EFI/GPT GUID in system path is not supported\n"); Debug::Print(L"WARNING: EFI/GPT GUID in system path is not supported\n");
return STATUS_EFI_UNSUPPORTED; return STATUS_EFI_UNSUPPORTED;
} }
else if(PathLength == PARTUUID_STRING_LENGTH) else if(PathLength == PARTUUID_STRING_LENGTH)
{ {
/* This is MBR UUID */ /* This is MBR UUID */
BlDebugPrint(L"WARNING: MBR partition UUID in system path is not supported\n"); Debug::Print(L"WARNING: MBR partition UUID in system path is not supported\n");
return STATUS_EFI_UNSUPPORTED; return STATUS_EFI_UNSUPPORTED;
} }
else else
@@ -447,14 +447,14 @@ BlGetVolumeDevicePath(IN PWCHAR SystemPath,
else else
{ {
/* Defaults to ARC path, dissect it */ /* Defaults to ARC path, dissect it */
Status = BlpDissectVolumeArcPath(SystemPath, ArcName, Path, &DriveType, &DriveNumber, &PartNumber); Status = DissectArcPath(SystemPath, ArcName, Path, &DriveType, &DriveNumber, &PartNumber);
} }
/* Check if volume path parsed successfully */ /* Check if volume path parsed successfully */
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to parse system path */ /* Failed to parse system path */
BlDebugPrint(L"ERROR: Failed to parse system path: '%s' (Status Code: 0x%zX)\n", SystemPath, Status); Debug::Print(L"ERROR: Failed to parse system path: '%s' (Status Code: 0x%zX)\n", SystemPath, Status);
return Status; return Status;
} }
@@ -492,7 +492,7 @@ BlGetVolumeDevicePath(IN PWCHAR SystemPath,
if(*DevicePath == NULLPTR) if(*DevicePath == NULLPTR)
{ {
/* Volume not found */ /* Volume not found */
BlDebugPrint(L"ERROR: Volume (DriveType: %u, DriveNumber: %lu, PartNumber: %lu) not found\n", Debug::Print(L"ERROR: Volume (DriveType: %u, DriveNumber: %lu, PartNumber: %lu) not found\n",
DriveType, DriveNumber, PartNumber); DriveType, DriveNumber, PartNumber);
return STATUS_EFI_NOT_FOUND; return STATUS_EFI_NOT_FOUND;
} }
@@ -519,9 +519,9 @@ BlGetVolumeDevicePath(IN PWCHAR SystemPath,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, Volume::OpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
OUT PEFI_HANDLE DiskHandle, OUT PEFI_HANDLE DiskHandle,
OUT PEFI_FILE_HANDLE *FsHandle) OUT PEFI_FILE_HANDLE *FsHandle)
{ {
EFI_GUID SFSGuid = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID; EFI_GUID SFSGuid = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
@@ -563,7 +563,7 @@ BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to open the filesystem protocol, close volume */ /* Failed to open the filesystem protocol, close volume */
BlCloseVolume(DiskHandle); CloseVolume(DiskHandle);
return Status; return Status;
} }
@@ -572,7 +572,7 @@ BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to open the filesystem, close volume */ /* Failed to open the filesystem, close volume */
BlCloseVolume(DiskHandle); CloseVolume(DiskHandle);
return Status; return Status;
} }
@@ -601,10 +601,10 @@ BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlReadFile(IN PEFI_FILE_HANDLE DirHandle, Volume::ReadFile(IN PEFI_FILE_HANDLE DirHandle,
IN PCWSTR FileName, IN PCWSTR FileName,
OUT PVOID *FileData, OUT PVOID *FileData,
OUT PSIZE_T FileSize) OUT PSIZE_T FileSize)
{ {
EFI_GUID FileInfoGuid = EFI_FILE_INFO_PROTOCOL_GUID; EFI_GUID FileInfoGuid = EFI_FILE_INFO_PROTOCOL_GUID;
EFI_PHYSICAL_ADDRESS Address; EFI_PHYSICAL_ADDRESS Address;
@@ -626,7 +626,7 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle,
ReadSize = sizeof(EFI_FILE_INFO) + 32; ReadSize = sizeof(EFI_FILE_INFO) + 32;
/* Allocate necessary amount of memory */ /* Allocate necessary amount of memory */
Status = BlAllocateMemoryPool(ReadSize, (PVOID *)&FileInfo); Status = Memory::AllocatePool(ReadSize, (PVOID *)&FileInfo);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure */ /* Memory allocation failure */
@@ -639,8 +639,8 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle,
if(Status == STATUS_EFI_BUFFER_TOO_SMALL) if(Status == STATUS_EFI_BUFFER_TOO_SMALL)
{ {
/* Buffer is too small, but EFI tells the required size, so reallocate */ /* Buffer is too small, but EFI tells the required size, so reallocate */
BlFreeMemoryPool(&FileInfo); Memory::FreePool(&FileInfo);
Status = BlAllocateMemoryPool(ReadSize, (PVOID *)&FileInfo); Status = Memory::AllocatePool(ReadSize, (PVOID *)&FileInfo);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure */ /* Memory allocation failure */
@@ -657,7 +657,7 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle,
{ {
/* Unable to get file information */ /* Unable to get file information */
FileHandle->Close(FileHandle); FileHandle->Close(FileHandle);
BlFreeMemoryPool(&FileInfo); Memory::FreePool(&FileInfo);
return Status; return Status;
} }
@@ -666,12 +666,12 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle,
Pages = EFI_SIZE_TO_PAGES(FileInfo->FileSize); Pages = EFI_SIZE_TO_PAGES(FileInfo->FileSize);
/* Allocate pages */ /* Allocate pages */
Status = BlAllocateMemoryPages(AllocateAnyPages, Pages, &Address); Status = Memory::AllocatePages(AllocateAnyPages, Pages, &Address);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Pages allocation failure */ /* Pages allocation failure */
FileHandle->Close(FileHandle); FileHandle->Close(FileHandle);
BlFreeMemoryPool(&FileInfo); Memory::FreePool(&FileInfo);
return Status; return Status;
} }
@@ -686,14 +686,14 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle,
{ {
/* Failed to read data */ /* Failed to read data */
FileHandle->Close(FileHandle); FileHandle->Close(FileHandle);
BlFreeMemoryPool(&FileInfo); Memory::FreePool(&FileInfo);
BlFreeMemoryPages(Pages, (EFI_PHYSICAL_ADDRESS)(UINT_PTR)*FileData); Memory::FreePages(Pages, (EFI_PHYSICAL_ADDRESS)(UINT_PTR)*FileData);
return Status; return Status;
} }
/* Close handle and free memory */ /* Close handle and free memory */
FileHandle->Close(FileHandle); FileHandle->Close(FileHandle);
BlFreeMemoryPool(FileInfo); Memory::FreePool(FileInfo);
/* Return success */ /* Return success */
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
@@ -711,7 +711,7 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle,
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices) Volume::DiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices)
{ {
EFI_GUID DevicePathGuid = EFI_DEVICE_PATH_PROTOCOL_GUID; EFI_GUID DevicePathGuid = EFI_DEVICE_PATH_PROTOCOL_GUID;
EFI_GUID IoGuid = EFI_BLOCK_IO_PROTOCOL_GUID; EFI_GUID IoGuid = EFI_BLOCK_IO_PROTOCOL_GUID;
@@ -723,11 +723,11 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices)
EFI_STATUS Status; EFI_STATUS Status;
/* Locate handles which support the disk I/O interface */ /* Locate handles which support the disk I/O interface */
Status = BlLocateProtocolHandles(&Handles, &HandlesCount, &IoGuid); Status = Protocol::LocateProtocolHandles(&Handles, &HandlesCount, &IoGuid);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to locate handles */ /* Failed to locate handles */
BlDebugPrint(L"ERROR: Failed to locate block devices handles (Status Code: 0x%zX)\n", Status); Debug::Print(L"ERROR: Failed to locate block devices handles (Status Code: 0x%zX)\n", Status);
return Status; return Status;
} }
@@ -735,15 +735,15 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices)
for(Index = 0; Index < HandlesCount; Index++) for(Index = 0; Index < HandlesCount; Index++)
{ {
/* Print debug message */ /* Print debug message */
BlDebugPrint(L"Opening %lu block device from %lu discovered\n", Index + 1, HandlesCount); Debug::Print(L"Opening %lu block device from %lu discovered\n", Index + 1, HandlesCount);
/* Open I/O protocol for given handle */ /* Open I/O protocol for given handle */
Io = NULLPTR; Io = NULLPTR;
Status = BlOpenProtocolHandle(Handles[Index], (PVOID *)&Io, &IoGuid); Status = Protocol::OpenProtocolHandle(Handles[Index], (PVOID *)&Io, &IoGuid);
if(Status != STATUS_EFI_SUCCESS || Io == NULLPTR) if(Status != STATUS_EFI_SUCCESS || Io == NULLPTR)
{ {
/* Failed to open I/O protocol, skip it */ /* Failed to open I/O protocol, skip it */
BlDebugPrint(L"WARNING: Failed to open EFI Block I/O protocol (Status Code: 0x%zX)\n", Status); Debug::Print(L"WARNING: Failed to open EFI Block I/O protocol (Status Code: 0x%zX)\n", Status);
continue; continue;
} }
@@ -751,7 +751,7 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices)
if(Io->Media && Io->Media->BlockSize == 1 && Io->Media->MediaId == 0x69505845U) if(Io->Media && Io->Media->BlockSize == 1 && Io->Media->MediaId == 0x69505845U)
{ {
/* Skip stub as it is non-functional */ /* Skip stub as it is non-functional */
BlDebugPrint(L"WARNING: Skipping iPXE stub block I/O protocol"); Debug::Print(L"WARNING: Skipping iPXE stub block I/O protocol");
continue; continue;
} }
@@ -761,17 +761,17 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices)
if(Status != STATUS_EFI_SUCCESS || DevicePath == NULLPTR) if(Status != STATUS_EFI_SUCCESS || DevicePath == NULLPTR)
{ {
/* Device failed to handle DP protocol */ /* Device failed to handle DP protocol */
BlDebugPrint(L"WARNING: Unable to open DevicePath protocol (Status Code: 0x%zX)\n", Status); Debug::Print(L"WARNING: Unable to open DevicePath protocol (Status Code: 0x%zX)\n", Status);
EfiSystemTable->BootServices->CloseProtocol(Handles[Index], &IoGuid, EfiImageHandle, NULLPTR); EfiSystemTable->BootServices->CloseProtocol(Handles[Index], &IoGuid, EfiImageHandle, NULLPTR);
continue; continue;
} }
/* Allocate memory for block device */ /* Allocate memory for block device */
Status = BlAllocateMemoryPool(sizeof(*BlockDevice), (PVOID *)&BlockDevice); Status = Memory::AllocatePool(sizeof(*BlockDevice), (PVOID *)&BlockDevice);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure */ /* Memory allocation failure */
BlDebugPrint(L"ERROR: Failed to allocate memory pool for block device (Status Code: 0x%zX)\n", Status); Debug::Print(L"ERROR: Failed to allocate memory pool for block device (Status Code: 0x%zX)\n", Status);
EfiSystemTable->BootServices->CloseProtocol(Handles[Index], &DevicePathGuid, EfiImageHandle, NULLPTR); EfiSystemTable->BootServices->CloseProtocol(Handles[Index], &DevicePathGuid, EfiImageHandle, NULLPTR);
EfiSystemTable->BootServices->CloseProtocol(Handles[Index], &IoGuid, EfiImageHandle, NULLPTR); EfiSystemTable->BootServices->CloseProtocol(Handles[Index], &IoGuid, EfiImageHandle, NULLPTR);
return Status; return Status;
@@ -784,7 +784,7 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices)
} }
/* Free handles buffer */ /* Free handles buffer */
BlFreeMemoryPool(Handles); Memory::FreePool(Handles);
/* Return success */ /* Return success */
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
@@ -814,12 +814,12 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices)
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlpDissectVolumeArcPath(IN PWCHAR SystemPath, Volume::DissectArcPath(IN PWCHAR SystemPath,
OUT PWCHAR *ArcName, OUT PWCHAR *ArcName,
OUT PWCHAR *Path, OUT PWCHAR *Path,
OUT PUSHORT DriveType, OUT PUSHORT DriveType,
OUT PULONG DriveNumber, OUT PULONG DriveNumber,
OUT PULONG PartNumber) OUT PULONG PartNumber)
{ {
PWCHAR ArcPath, LocalArcName; PWCHAR ArcPath, LocalArcName;
ULONG ArcLength = 0; ULONG ArcLength = 0;
@@ -954,7 +954,7 @@ BlpDissectVolumeArcPath(IN PWCHAR SystemPath,
/* Store ARC name if possible */ /* Store ARC name if possible */
if(ArcName) if(ArcName)
{ {
BlAllocateMemoryPool(ArcLength * sizeof(WCHAR), (PVOID *)&LocalArcName); Memory::AllocatePool(ArcLength * sizeof(WCHAR), (PVOID *)&LocalArcName);
RTL::Memory::CopyMemory(LocalArcName, SystemPath, ArcLength * sizeof(WCHAR)); RTL::Memory::CopyMemory(LocalArcName, SystemPath, ArcLength * sizeof(WCHAR));
LocalArcName[ArcLength] = '\0'; LocalArcName[ArcLength] = '\0';
*ArcName = LocalArcName; *ArcName = LocalArcName;
@@ -976,7 +976,7 @@ BlpDissectVolumeArcPath(IN PWCHAR SystemPath,
*/ */
XTCDECL XTCDECL
PEFI_DEVICE_PATH_PROTOCOL PEFI_DEVICE_PATH_PROTOCOL
BlpDuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath) Volume::DuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath)
{ {
PEFI_DEVICE_PATH_PROTOCOL DevicePathNode; PEFI_DEVICE_PATH_PROTOCOL DevicePathNode;
PEFI_DEVICE_PATH_PROTOCOL DevicePathClone; PEFI_DEVICE_PATH_PROTOCOL DevicePathClone;
@@ -1012,11 +1012,11 @@ BlpDuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath)
} }
/* Allocate memory for the new device path */ /* Allocate memory for the new device path */
Status = BlAllocateMemoryPool(Length, (PVOID *)&DevicePathClone); Status = Memory::AllocatePool(Length, (PVOID *)&DevicePathClone);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to allocate memory */ /* Failed to allocate memory */
BlDebugPrint(L"ERROR: Failed to allocate memory pool for device path duplicate (Status Code: 0x%zX)\n", Status); Debug::Print(L"ERROR: Failed to allocate memory pool for device path duplicate (Status Code: 0x%zX)\n", Status);
return NULLPTR; return NULLPTR;
} }
@@ -1042,8 +1042,8 @@ BlpDuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath)
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlpFindLastBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, Volume::FindLastBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
OUT PEFI_DEVICE_PATH_PROTOCOL *LastNode) OUT PEFI_DEVICE_PATH_PROTOCOL *LastNode)
{ {
PEFI_DEVICE_PATH_PROTOCOL EndNode, NextNode; PEFI_DEVICE_PATH_PROTOCOL EndNode, NextNode;
@@ -1088,9 +1088,9 @@ BlpFindLastBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
*/ */
XTCDECL XTCDECL
BOOLEAN BOOLEAN
BlpFindParentBlockDevice(IN PLIST_ENTRY BlockDevices, Volume::FindParentBlockDevice(IN PLIST_ENTRY BlockDevices,
IN PEFI_BLOCK_DEVICE_DATA ChildNode, IN PEFI_BLOCK_DEVICE_DATA ChildNode,
OUT PEFI_BLOCK_DEVICE_DATA *ParentNode) OUT PEFI_BLOCK_DEVICE_DATA *ParentNode)
{ {
PEFI_DEVICE_PATH_PROTOCOL ChildDevicePath, ParentDevicePath; PEFI_DEVICE_PATH_PROTOCOL ChildDevicePath, ParentDevicePath;
PEFI_BLOCK_DEVICE_DATA BlockDeviceData; PEFI_BLOCK_DEVICE_DATA BlockDeviceData;

View File

@@ -18,7 +18,7 @@
*/ */
XTCDECL XTCDECL
VOID VOID
BlInitializeBootLoader() XtLoader::InitializeBootLoader()
{ {
EFI_GUID LipGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID; EFI_GUID LipGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
PEFI_LOADED_IMAGE_PROTOCOL LoadedImage; PEFI_LOADED_IMAGE_PROTOCOL LoadedImage;
@@ -29,10 +29,10 @@ BlInitializeBootLoader()
BlpStatus.BootServices = TRUE; BlpStatus.BootServices = TRUE;
/* Initialize console */ /* Initialize console */
BlInitializeConsole(); Console::InitializeConsole();
/* Print XTLDR version */ /* Print XTLDR version */
BlConsolePrint(L"XTLDR boot loader v%s\n", XTOS_VERSION); Console::Print(L"XTLDR boot loader v%s\n", XTOS_VERSION);
/* Initialize XTLDR configuration linked lists */ /* Initialize XTLDR configuration linked lists */
RTL::LinkedList::InitializeListHead(&BlpBootProtocols); RTL::LinkedList::InitializeListHead(&BlpBootProtocols);
@@ -40,10 +40,10 @@ BlInitializeBootLoader()
RTL::LinkedList::InitializeListHead(&BlpLoadedModules); RTL::LinkedList::InitializeListHead(&BlpLoadedModules);
/* Store SecureBoot status */ /* Store SecureBoot status */
BlpStatus.SecureBoot = BlGetSecureBootStatus(); BlpStatus.SecureBoot = EfiUtils::GetSecureBootStatus();
/* Attempt to open EFI LoadedImage protocol */ /* Attempt to open EFI LoadedImage protocol */
Status = BlOpenProtocol(&Handle, (PVOID *)&LoadedImage, &LipGuid); Status = Protocol::OpenProtocol(&Handle, (PVOID *)&LoadedImage, &LipGuid);
if(Status == STATUS_EFI_SUCCESS) if(Status == STATUS_EFI_SUCCESS)
{ {
/* Store boot loader image base and size */ /* Store boot loader image base and size */
@@ -54,7 +54,7 @@ BlInitializeBootLoader()
if(DEBUG) if(DEBUG)
{ {
/* Protocol opened successfully, print useful debug information */ /* Protocol opened successfully, print useful debug information */
BlConsolePrint(L"\n---------- BOOTLOADER DEBUG ----------\n" Console::Print(L"\n---------- BOOTLOADER DEBUG ----------\n"
L"Pointer Size : %d\n" L"Pointer Size : %d\n"
L"Image Base Address : %P\n" L"Image Base Address : %P\n"
L"Image Base Size : 0x%lX\n" L"Image Base Size : 0x%lX\n"
@@ -66,11 +66,11 @@ BlInitializeBootLoader()
LoadedImage->ImageSize, LoadedImage->ImageSize,
LoadedImage->Revision, LoadedImage->Revision,
BlpStatus.SecureBoot); BlpStatus.SecureBoot);
BlSleepExecution(3000); EfiUtils::SleepExecution(3000);
} }
/* Close EFI LoadedImage protocol */ /* Close EFI LoadedImage protocol */
BlCloseProtocol(&Handle, &LipGuid); Protocol::CloseProtocol(&Handle, &LipGuid);
} }
} }
@@ -92,10 +92,10 @@ BlInitializeBootLoader()
*/ */
XTCDECL XTCDECL
EFI_STATUS EFI_STATUS
BlInitializeBootMenuList(IN ULONG MaxNameLength, XtLoader::InitializeBootMenuList(IN ULONG MaxNameLength,
OUT PXTBL_BOOTMENU_ITEM *MenuEntries, OUT PXTBL_BOOTMENU_ITEM *MenuEntries,
OUT PULONG EntriesCount, OUT PULONG EntriesCount,
OUT PULONG DefaultId) OUT PULONG DefaultId)
{ {
EFI_GUID VendorGuid = XT_BOOT_LOADER_PROTOCOL_GUID; EFI_GUID VendorGuid = XT_BOOT_LOADER_PROTOCOL_GUID;
PWCHAR DefaultMenuEntry, LastBooted, MenuEntryName, VisibleName; PWCHAR DefaultMenuEntry, LastBooted, MenuEntryName, VisibleName;
@@ -111,13 +111,13 @@ BlInitializeBootMenuList(IN ULONG MaxNameLength,
NumberOfEntries = 0; NumberOfEntries = 0;
/* Get default menu entry from configuration */ /* Get default menu entry from configuration */
BlGetConfigValue(L"DEFAULT", &DefaultMenuEntry); Configuration::GetValue(L"DEFAULT", &DefaultMenuEntry);
/* Check if configuration allows to use last booted OS */ /* Check if configuration allows to use last booted OS */
if(BlGetConfigBooleanValue(L"KEEPLASTBOOT")) if(Configuration::GetBooleanValue(L"KEEPLASTBOOT"))
{ {
/* Attempt to get last booted Operating System from NVRAM */ /* Attempt to get last booted Operating System from NVRAM */
Status = BlGetEfiVariable(&VendorGuid, L"XtLdrLastBootOS", (PVOID*)&LastBooted); Status = EfiUtils::GetEfiVariable(&VendorGuid, L"XtLdrLastBootOS", (PVOID*)&LastBooted);
if(Status == STATUS_EFI_SUCCESS) if(Status == STATUS_EFI_SUCCESS)
{ {
/* Set default menu entry to last booted OS */ /* Set default menu entry to last booted OS */
@@ -135,7 +135,7 @@ BlInitializeBootMenuList(IN ULONG MaxNameLength,
} }
/* Allocate memory for the OS list depending on the item count */ /* Allocate memory for the OS list depending on the item count */
Status = BlAllocateMemoryPool(NumberOfEntries * sizeof(XTBL_BOOTMENU_ITEM), (PVOID*)&OsList); Status = Memory::AllocatePool(NumberOfEntries * sizeof(XTBL_BOOTMENU_ITEM), (PVOID*)&OsList);
if(Status != STATUS_EFI_SUCCESS || !OsList) if(Status != STATUS_EFI_SUCCESS || !OsList)
{ {
/* Memory allocation failure */ /* Memory allocation failure */
@@ -189,7 +189,7 @@ BlInitializeBootMenuList(IN ULONG MaxNameLength,
if(NameLength > MaxNameLength) if(NameLength > MaxNameLength)
{ {
/* Menu entry name is too long, allocate memory for shorter name visible in the boot menu */ /* Menu entry name is too long, allocate memory for shorter name visible in the boot menu */
Status = BlAllocateMemoryPool((MaxNameLength + 1) * sizeof(WCHAR), (PVOID*)&VisibleName); Status = Memory::AllocatePool((MaxNameLength + 1) * sizeof(WCHAR), (PVOID*)&VisibleName);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Memory allocation failure */ /* Memory allocation failure */
@@ -224,157 +224,6 @@ BlInitializeBootMenuList(IN ULONG MaxNameLength,
return STATUS_EFI_SUCCESS; return STATUS_EFI_SUCCESS;
} }
/**
* Loads all necessary modules and invokes boot protocol.
*
* @param ShortName
* Supplies a pointer to a short name of the chosen boot menu entry.
*
* @param OptionsList
* Supplies a pointer to list of options associated with chosen boot menu entry.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
BlInvokeBootProtocol(IN PWCHAR ShortName,
IN PLIST_ENTRY OptionsList)
{
EFI_GUID VendorGuid = XT_BOOT_LOADER_PROTOCOL_GUID;
XTBL_BOOT_PARAMETERS BootParameters;
PXTBL_BOOT_PROTOCOL BootProtocol;
PLIST_ENTRY OptionsListEntry;
PXTBL_CONFIG_ENTRY Option;
EFI_GUID BootProtocolGuid;
SIZE_T ModuleListLength;
PWCHAR ModulesList;
EFI_HANDLE Handle;
EFI_STATUS Status;
/* Initialize boot parameters and a list of modules */
RTL::Memory::ZeroMemory(&BootParameters, sizeof(XTBL_BOOT_PARAMETERS));
ModulesList = NULLPTR;
/* Iterate through all options provided by boot menu entry and propagate boot parameters */
OptionsListEntry = OptionsList->Flink;
while(OptionsListEntry != OptionsList)
{
/* Get option */
Option = CONTAIN_RECORD(OptionsListEntry, XTBL_CONFIG_ENTRY, Flink);
/* Look for boot protocol and modules list */
if(RTL::WideString::CompareWideStringInsensitive(Option->Name, L"BOOTMODULES", 0) == 0)
{
/* Check a length of modules list */
ModuleListLength = RTL::WideString::WideStringLength(Option->Value, 0);
Status = BlAllocateMemoryPool(sizeof(WCHAR) * (ModuleListLength + 1), (PVOID *)&ModulesList);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to allocate memory, print error message and return status code */
BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%zX)\n", Status);
return STATUS_EFI_OUT_OF_RESOURCES;
}
/* Make a copy of modules list */
RTL::Memory::CopyMemory(ModulesList, Option->Value, sizeof(WCHAR) * (ModuleListLength + 1));
}
else if(RTL::WideString::CompareWideStringInsensitive(Option->Name, L"SYSTEMTYPE", 0) == 0)
{
/* Boot protocol found */
BootParameters.SystemType = Option->Value;
}
else if(RTL::WideString::CompareWideStringInsensitive(Option->Name, L"SYSTEMPATH", 0) == 0)
{
/* System path found, get volume device path */
Status = BlGetVolumeDevicePath(Option->Value, &BootParameters.DevicePath,
&BootParameters.ArcName, &BootParameters.SystemPath);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to find volume */
BlDebugPrint(L"ERROR: Failed to find volume device path (Status Code: 0x%zX)\n", Status);
return Status;
}
/* Get EFI compatible system path */
Status = BlGetEfiPath(BootParameters.SystemPath, &BootParameters.EfiPath);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to get EFI path */
BlDebugPrint(L"ERROR: Failed to get EFI path (Status Code: 0x%zX)\n", Status);
return Status;
}
}
else if(RTL::WideString::CompareWideStringInsensitive(Option->Name, L"KERNELFILE", 0) == 0)
{
/* Kernel file name found */
BootParameters.KernelFile = Option->Value;
}
else if(RTL::WideString::CompareWideStringInsensitive(Option->Name, L"INITRDFILE", 0) == 0)
{
/* Initrd file name found */
BootParameters.InitrdFile = Option->Value;
}
else if(RTL::WideString::CompareWideStringInsensitive(Option->Name, L"HALFILE", 0) == 0)
{
/* Hal file name found */
BootParameters.HalFile = Option->Value;
}
else if(RTL::WideString::CompareWideStringInsensitive(Option->Name, L"PARAMETERS", 0) == 0)
{
/* Kernel parameters found */
BootParameters.Parameters = Option->Value;
}
/* Move to the next option entry */
OptionsListEntry = OptionsListEntry->Flink;
}
/* Load all necessary modules */
Status = BlLoadModules(ModulesList);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to load modules, print error message and return status code */
BlDebugPrint(L"ERROR: Failed to load XTLDR modules (Status Code: 0x%zX)\n", Status);
return STATUS_EFI_NOT_READY;
}
/* Attempt to get boot protocol GUID */
Status = BlFindBootProtocol(BootParameters.SystemType, &BootProtocolGuid);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to get boot protocol GUID */
BlDebugPrint(L"ERROR: Unable to find appropriate boot protocol (Status Code: 0x%zX)\n", Status);
return STATUS_EFI_UNSUPPORTED;
}
/* Open boot protocol */
Status = BlOpenProtocol(&Handle, (PVOID *)&BootProtocol, &BootProtocolGuid);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to open boot protocol */
BlDebugPrint(L"ERROR: Failed to open boot protocol (Status Code: 0x%zX)\n", Status);
return Status;
}
/* Check if chosen operating system should be saved */
if(BlGetConfigBooleanValue(L"KEEPLASTBOOT"))
{
/* Save chosen operating system in NVRAM */
Status = BlSetEfiVariable(&VendorGuid, L"XtLdrLastBootOS", (PVOID)ShortName, RTL::WideString::WideStringLength(ShortName, 0) * sizeof(WCHAR));
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to save chosen Operating System */
BlDebugPrint(L"WARNING: Failed to save chosen Operating System in NVRAM (Status Code: 0x%zX)\n", Status);
}
}
/* Boot Operating System */
return BootProtocol->BootSystem(&BootParameters);
}
/** /**
* This routine is the entry point of the XT EFI boot loader. * This routine is the entry point of the XT EFI boot loader.
* *
@@ -401,43 +250,43 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle,
EfiSystemTable = SystemTable; EfiSystemTable = SystemTable;
/* Initialize XTLDR and */ /* Initialize XTLDR and */
BlInitializeBootLoader(); XtLoader::InitializeBootLoader();
/* Parse configuration options passed from UEFI shell */ /* Parse configuration options passed from UEFI shell */
Status = BlpParseCommandLine(); Status = Configuration::ParseCommandLine();
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to parse command line options */ /* Failed to parse command line options */
BlDisplayErrorDialog(L"XTLDR", L"Failed to parse command line parameters."); TextUi::DisplayErrorDialog(L"XTLDR", L"Failed to parse command line parameters.");
} }
/* Attempt to early initialize debug console */ /* Attempt to early initialize debug console */
if(DEBUG) if(DEBUG)
{ {
Status = BlpInitializeDebugConsole(); Status = Debug::InitializeDebugConsole();
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Initialization failed, notify user on stdout */ /* Initialization failed, notify user on stdout */
BlDisplayErrorDialog(L"XTLDR", L"Failed to initialize debug console."); TextUi::DisplayErrorDialog(L"XTLDR", L"Failed to initialize debug console.");
} }
} }
/* Load XTLDR configuration file */ /* Load XTLDR configuration file */
Status = BlpLoadConfiguration(); Status = Configuration::LoadConfiguration();
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to load/parse config file */ /* Failed to load/parse config file */
BlDisplayErrorDialog(L"XTLDR", L"Failed to load and parse configuration file "); TextUi::DisplayErrorDialog(L"XTLDR", L"Failed to load and parse configuration file ");
} }
/* Reinitialize debug console if it was not initialized earlier */ /* Reinitialize debug console if it was not initialized earlier */
if(DEBUG) if(DEBUG)
{ {
Status = BlpInitializeDebugConsole(); Status = Debug::InitializeDebugConsole();
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Initialization failed, notify user on stdout */ /* Initialization failed, notify user on stdout */
BlDisplayErrorDialog(L"XTLDR", L"Failed to initialize debug console."); TextUi::DisplayErrorDialog(L"XTLDR", L"Failed to initialize debug console.");
} }
} }
@@ -446,34 +295,34 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle,
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to disable the timer, print message */ /* Failed to disable the timer, print message */
BlDebugPrint(L"WARNING: Failed to disable watchdog timer (Status Code: 0x%zX)\n", Status); Debug::Print(L"WARNING: Failed to disable watchdog timer (Status Code: 0x%zX)\n", Status);
} }
/* Install loader protocol */ /* Install loader protocol */
Status = BlpInstallXtLoaderProtocol(); Status = Protocol::InstallXtLoaderProtocol();
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to register loader protocol */ /* Failed to register loader protocol */
BlDebugPrint(L"ERROR: Failed to register XTLDR loader protocol (Status Code: 0x%zX)\n", Status); Debug::Print(L"ERROR: Failed to register XTLDR loader protocol (Status Code: 0x%zX)\n", Status);
return Status; return Status;
} }
/* Load all necessary modules */ /* Load all necessary modules */
BlGetConfigValue(L"MODULES", &Modules); Configuration::GetValue(L"MODULES", &Modules);
Status = BlLoadModules(Modules); Status = Protocol::LoadModules(Modules);
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to load modules */ /* Failed to load modules */
BlDebugPrint(L"ERROR: Failed to load XTLDR modules (Status Code: 0x%zX)\n", Status); Debug::Print(L"ERROR: Failed to load XTLDR modules (Status Code: 0x%zX)\n", Status);
BlDisplayErrorDialog(L"XTLDR", L"Failed to load some XTLDR modules."); TextUi::DisplayErrorDialog(L"XTLDR", L"Failed to load some XTLDR modules.");
} }
/* Discover and enumerate EFI block devices */ /* Discover and enumerate EFI block devices */
Status = BlEnumerateBlockDevices(); Status = Volume::EnumerateBlockDevices();
if(Status != STATUS_EFI_SUCCESS) if(Status != STATUS_EFI_SUCCESS)
{ {
/* Failed to enumerate block devices */ /* Failed to enumerate block devices */
BlDebugPrint(L"ERROR: Failed to discover and enumerate block devices (Status Code: 0x%zX)\n", Status); Debug::Print(L"ERROR: Failed to discover and enumerate block devices (Status Code: 0x%zX)\n", Status);
return Status; return Status;
} }
@@ -489,11 +338,11 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle,
else else
{ {
/* Display default boot menu */ /* Display default boot menu */
BlDisplayBootMenu(); TextUi::DisplayBootMenu();
} }
/* Fallback to shell, if boot menu returned */ /* Fallback to shell, if boot menu returned */
BlStartLoaderShell(); Shell::StartLoaderShell();
} }
/* This point should be never reached, if this happen return error code */ /* This point should be never reached, if this happen return error code */