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}/efiutils.cc
${XTLDR_SOURCE_DIR}/globals.cc
${XTLDR_SOURCE_DIR}/hardware.cc
${XTLDR_SOURCE_DIR}/memory.cc
${XTLDR_SOURCE_DIR}/protocol.cc
${XTLDR_SOURCE_DIR}/shell.cc

View File

@@ -25,7 +25,7 @@
*/
XTCDECL
EFI_STATUS
BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR SelfMapAddress)
{
PLIST_ENTRY ListEntry, ModulesList, ModulesListEntry;
@@ -35,7 +35,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
EFI_STATUS Status;
/* Allocate pages for the Page Map */
Status = BlAllocateMemoryPages(AllocateAnyPages, 1, &Address);
Status = AllocatePages(AllocateAnyPages, 1, &Address);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure */
@@ -47,7 +47,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
RTL::Memory::ZeroMemory(PageMap->PtePointer, EFI_PAGE_SIZE);
/* Add page mapping itself to memory mapping */
Status = BlpSelfMapPml(PageMap, SelfMapAddress);
Status = Memory::SelfMapPml(PageMap, SelfMapAddress);
if(Status != STATUS_EFI_SUCCESS)
{
/* PML mapping failed */
@@ -55,7 +55,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
}
/* 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);
if(Status != STATUS_EFI_SUCCESS)
{
@@ -64,7 +64,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
}
/* Get list of XTLDR modules */
ModulesList = BlGetModulesList();
ModulesList = Protocol::GetModulesList();
ModulesListEntry = ModulesList->Flink;
while(ModulesListEntry != ModulesList)
{
@@ -72,7 +72,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
ModuleInfo = CONTAIN_RECORD(ModulesListEntry, XTBL_MODULE_INFO, Flink);
/* Map module code */
Status = BlMapVirtualMemory(PageMap, ModuleInfo->ModuleBase, ModuleInfo->ModuleBase,
Status = MapVirtualMemory(PageMap, ModuleInfo->ModuleBase, ModuleInfo->ModuleBase,
EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary);
/* Check if mapping succeeded */
@@ -90,7 +90,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
if(BlpStatus.LoaderBase && BlpStatus.LoaderSize)
{
/* 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);
if(Status != STATUS_EFI_SUCCESS)
{
@@ -105,7 +105,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
}
/* 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;
while(ListEntry != &PageMap->MemoryMap)
{
@@ -116,11 +116,11 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
if(Mapping->VirtualAddress)
{
/* 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);
/* Map memory */
Status = BlMapPage(PageMap, (UINT_PTR)Mapping->VirtualAddress,
Status = MapPage(PageMap, (UINT_PTR)Mapping->VirtualAddress,
(UINT_PTR)Mapping->PhysicalAddress, Mapping->NumberOfPages);
if(Status != STATUS_EFI_SUCCESS)
{
@@ -137,6 +137,81 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
return STATUS_EFI_SUCCESS;
}
/**
* Returns next level of the Page Table.
*
* @param PageMap
* Supplies a pointer to the page mapping structure.
*
* @param PageTable
* Supplies a pointer to the current Page Table.
*
* @param Entry
* Supplies an index of the current Page Table entry.
*
* @param NextPageTable
* Supplies a pointer to the memory area where the next Page Table level is returned.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
Memory::GetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
IN PVOID PageTable,
IN SIZE_T Entry,
OUT PVOID *NextPageTable)
{
EFI_PHYSICAL_ADDRESS Address;
ULONGLONG PmlPointer = 0;
PHARDWARE_PTE PmlTable;
EFI_STATUS Status;
PmlTable = (PHARDWARE_PTE)PageTable;
/* Check if this is a valid table */
if(PmlTable[Entry].Valid)
{
/* Get PML pointer */
PmlPointer = PmlTable[Entry].PageFrameNumber;
PmlPointer <<= EFI_PAGE_SHIFT;
}
else
{
/* Allocate pages for new PML entry */
Status = AllocatePages(AllocateAnyPages, 1, &Address);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure */
return Status;
}
/* Add new memory mapping */
Status = MapVirtualMemory(PageMap, NULLPTR, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory mapping failure */
return Status;
}
/* Fill allocated memory with zeros */
RTL::Memory::ZeroMemory((PVOID)(ULONGLONG)Address, EFI_PAGE_SIZE);
/* Set paging entry settings */
PmlTable[Entry].PageFrameNumber = Address / EFI_PAGE_SIZE;
PmlTable[Entry].Valid = 1;
PmlTable[Entry].Writable = 1;
PmlPointer = (ULONGLONG)Address;
}
/* Set next Page Map Level (PML) */
*NextPageTable = (PVOID)(ULONGLONG)PmlPointer;
/* Return success */
return STATUS_EFI_SUCCESS;
}
/**
* Does the actual virtual memory mapping.
*
@@ -158,7 +233,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
*/
XTCDECL
EFI_STATUS
BlMapPage(IN PXTBL_PAGE_MAPPING PageMap,
Memory::MapPage(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR VirtualAddress,
IN ULONG_PTR PhysicalAddress,
IN ULONG NumberOfPages)
@@ -189,7 +264,7 @@ BlMapPage(IN PXTBL_PAGE_MAPPING PageMap,
Pml5 = PageMap->PtePointer;
/* Get PML4 */
Status = BlpGetNextPageTable(PageMap, Pml5, Pml5Entry, &Pml4);
Status = GetNextPageTable(PageMap, Pml5, Pml5Entry, &Pml4);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory mapping failure */
@@ -203,7 +278,7 @@ BlMapPage(IN PXTBL_PAGE_MAPPING PageMap,
}
/* Get PML3 */
Status = BlpGetNextPageTable(PageMap, Pml4, Pml4Entry, &Pml3);
Status = GetNextPageTable(PageMap, Pml4, Pml4Entry, &Pml3);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory mapping failure */
@@ -211,7 +286,7 @@ BlMapPage(IN PXTBL_PAGE_MAPPING PageMap,
}
/* Get PML 2 */
Status = BlpGetNextPageTable(PageMap, Pml3, Pml3Entry, &Pml2);
Status = GetNextPageTable(PageMap, Pml3, Pml3Entry, &Pml2);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory mapping failure */
@@ -219,7 +294,7 @@ BlMapPage(IN PXTBL_PAGE_MAPPING PageMap,
}
/* Get PML1 */
Status = BlpGetNextPageTable(PageMap, Pml2, Pml2Entry, &Pml1);
Status = GetNextPageTable(PageMap, Pml2, Pml2Entry, &Pml1);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory mapping failure */
@@ -245,81 +320,6 @@ BlMapPage(IN PXTBL_PAGE_MAPPING PageMap,
return STATUS_EFI_SUCCESS;
}
/**
* Returns next level of the Page Table.
*
* @param PageMap
* Supplies a pointer to the page mapping structure.
*
* @param PageTable
* Supplies a pointer to the current Page Table.
*
* @param Entry
* Supplies an index of the current Page Table entry.
*
* @param NextPageTable
* Supplies a pointer to the memory area where the next Page Table level is returned.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
IN PVOID PageTable,
IN SIZE_T Entry,
OUT PVOID *NextPageTable)
{
EFI_PHYSICAL_ADDRESS Address;
ULONGLONG PmlPointer = 0;
PHARDWARE_PTE PmlTable;
EFI_STATUS Status;
PmlTable = (PHARDWARE_PTE)PageTable;
/* Check if this is a valid table */
if(PmlTable[Entry].Valid)
{
/* Get PML pointer */
PmlPointer = PmlTable[Entry].PageFrameNumber;
PmlPointer <<= EFI_PAGE_SHIFT;
}
else
{
/* Allocate pages for new PML entry */
Status = BlAllocateMemoryPages(AllocateAnyPages, 1, &Address);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure */
return Status;
}
/* Add new memory mapping */
Status = BlMapVirtualMemory(PageMap, NULLPTR, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory mapping failure */
return Status;
}
/* Fill allocated memory with zeros */
RTL::Memory::ZeroMemory((PVOID)(ULONGLONG)Address, EFI_PAGE_SIZE);
/* Set paging entry settings */
PmlTable[Entry].PageFrameNumber = Address / EFI_PAGE_SIZE;
PmlTable[Entry].Valid = 1;
PmlTable[Entry].Writable = 1;
PmlPointer = (ULONGLONG)Address;
}
/* Set next Page Map Level (PML) */
*NextPageTable = (PVOID)(ULONGLONG)PmlPointer;
/* Return success */
return STATUS_EFI_SUCCESS;
}
/**
* Creates a recursive self mapping for all PML levels.
*
@@ -335,7 +335,7 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
*/
XTCDECL
EFI_STATUS
BlpSelfMapPml(IN PXTBL_PAGE_MAPPING PageMap,
Memory::SelfMapPml(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR SelfMapAddress)
{
PHARDWARE_PTE PmlBase;

View File

@@ -22,7 +22,7 @@
*/
XTCDECL
EFI_STATUS
BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
Memory::BuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR SelfMapAddress)
{
PLIST_ENTRY ListEntry, ModulesList, ModulesListEntry;
@@ -36,7 +36,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
if(PageMap->PageMapLevel == 3)
{
/* 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)
{
/* 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);
/* Allocate 4 pages for the Page Directories (PDs) */
Status = BlAllocateMemoryPages(AllocateAnyPages, 4, &DirectoryAddress);
Status = AllocatePages(AllocateAnyPages, 4, &DirectoryAddress);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failed, cannot proceed with page map creation */
@@ -70,7 +70,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
else
{
/* 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)
{
/* 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 */
Status = BlpSelfMapPml(PageMap, SelfMapAddress);
Status = SelfMapPml(PageMap, SelfMapAddress);
if(Status != STATUS_EFI_SUCCESS)
{
/* PML mapping failed */
@@ -91,7 +91,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
}
/* 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);
if(Status != STATUS_EFI_SUCCESS)
{
@@ -100,7 +100,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
}
/* Get list of XTLDR modules */
ModulesList = BlGetModulesList();
ModulesList = Protocol::GetModulesList();
ModulesListEntry = ModulesList->Flink;
while(ModulesListEntry != ModulesList)
{
@@ -108,7 +108,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
ModuleInfo = CONTAIN_RECORD(ModulesListEntry, XTBL_MODULE_INFO, Flink);
/* Map module code */
Status = BlMapVirtualMemory(PageMap, ModuleInfo->ModuleBase, ModuleInfo->ModuleBase,
Status = MapVirtualMemory(PageMap, ModuleInfo->ModuleBase, ModuleInfo->ModuleBase,
EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary);
/* Check if mapping succeeded */
@@ -126,7 +126,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
if(BlpStatus.LoaderBase && BlpStatus.LoaderSize)
{
/* 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);
if(Status != STATUS_EFI_SUCCESS)
{
@@ -141,7 +141,7 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
}
/* 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;
while(ListEntry != &PageMap->MemoryMap)
{
@@ -152,11 +152,11 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
if(Mapping->VirtualAddress)
{
/* 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);
/* Map memory */
Status = BlMapPage(PageMap, (UINT_PTR)Mapping->VirtualAddress,
Status = MapPage(PageMap, (UINT_PTR)Mapping->VirtualAddress,
(UINT_PTR)Mapping->PhysicalAddress, Mapping->NumberOfPages);
if(Status != STATUS_EFI_SUCCESS)
{
@@ -173,116 +173,6 @@ BlBuildPageMap(IN PXTBL_PAGE_MAPPING PageMap,
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.
*
@@ -304,7 +194,7 @@ BlMapPage(IN PXTBL_PAGE_MAPPING PageMap,
*/
XTCDECL
EFI_STATUS
BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
Memory::GetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
IN PVOID PageTable,
IN SIZE_T Entry,
OUT PVOID *NextPageTable)
@@ -349,7 +239,7 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
else
{
/* Allocate pages for new PML entry */
Status = BlAllocateMemoryPages(AllocateAnyPages, 1, &Address);
Status = AllocatePages(AllocateAnyPages, 1, &Address);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure */
@@ -357,7 +247,7 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
}
/* 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)
{
/* Memory mapping failure */
@@ -396,6 +286,116 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
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.
*
@@ -411,7 +411,7 @@ BlpGetNextPageTable(IN PXTBL_PAGE_MAPPING PageMap,
*/
XTCDECL
EFI_STATUS
BlpSelfMapPml(IN PXTBL_PAGE_MAPPING PageMap,
Memory::SelfMapPml(IN PXTBL_PAGE_MAPPING PageMap,
IN ULONG_PTR SelfMapAddress)
{
PHARDWARE_LEGACY_PTE LegacyPml;

View File

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

View File

@@ -10,6 +10,39 @@
#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.
*
@@ -28,7 +61,7 @@
*/
XTCDECL
EFI_STATUS
BlGetBootOptionValue(IN PLIST_ENTRY Options,
Configuration::GetBootOptionValue(IN PLIST_ENTRY Options,
IN PCWSTR OptionName,
OUT PWCHAR *OptionValue)
{
@@ -57,11 +90,11 @@ BlGetBootOptionValue(IN PLIST_ENTRY Options,
ValueLength = RTL::WideString::WideStringLength(ConfigEntry->Value, 0);
/* 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)
{
/* 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;
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
* Specifies the configuration key to return its boolean representation.
* @param OptionsArray
* 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
*/
XTCDECL
BOOLEAN
BlGetConfigBooleanValue(IN PCWSTR ConfigName)
VOID
Configuration::GetEditableOptions(OUT PCWSTR **OptionsArray,
OUT PULONG OptionsCount)
{
PWCHAR Value;
ULONG Count = 0;
/* Get config value */
BlGetConfigValue(ConfigName, &Value);
/* Return a pointer to the global array of editable options */
*OptionsArray = BlpEditableConfigOptions;
/* 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)
/* Calculate the number of elements in the array */
while(BlpEditableConfigOptions[Count])
{
/* This option is enabled */
return TRUE;
Count++;
}
/* Return FALSE by default */
return FALSE;
/* Return the number of elements */
*OptionsCount = Count;
}
/**
@@ -127,7 +160,7 @@ BlGetConfigBooleanValue(IN PCWSTR ConfigName)
*/
XTCDECL
EFI_STATUS
BlGetConfigValue(IN PCWSTR ConfigName,
Configuration::GetValue(IN PCWSTR ConfigName,
OUT PWCHAR *ConfigValue)
{
PXTBL_CONFIG_ENTRY ConfigEntry;
@@ -156,11 +189,11 @@ BlGetConfigValue(IN PCWSTR ConfigName,
ValueLength = RTL::WideString::WideStringLength(ConfigEntry->Value, 0);
/* 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)
{
/* 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;
}
@@ -179,226 +212,6 @@ BlGetConfigValue(IN PCWSTR ConfigName,
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.
*
@@ -408,7 +221,7 @@ BlSetConfigValue(IN PCWSTR ConfigName,
*/
XTCDECL
EFI_STATUS
BlpLoadConfiguration()
Configuration::LoadConfiguration()
{
PLIST_ENTRY SectionListEntry;
EFI_STATUS Status;
@@ -418,27 +231,27 @@ BlpLoadConfiguration()
RTL::LinkedList::InitializeListHead(&BlpConfigSections);
/* 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)
{
/* 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 */
if(Status != STATUS_EFI_SUCCESS)
{
/* 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;
}
/* Parse configuration data */
Status = BlpParseConfigFile(ConfigData, &BlpConfigSections);
Status = ParseConfigFile(ConfigData, &BlpConfigSections);
if(Status != STATUS_EFI_SUCCESS)
{
/* 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;
}
@@ -453,7 +266,7 @@ BlpLoadConfiguration()
if(RTL::WideString::CompareWideStringInsensitive(Section->SectionName, L"XTLDR", 5) == 0)
{
/* Update global configuration */
BlpUpdateConfiguration(&Section->Options);
UpdateConfiguration(&Section->Options);
/* Remove XTLDR section from the list */
RTL::LinkedList::RemoveEntryList(SectionListEntry);
@@ -480,7 +293,7 @@ BlpLoadConfiguration()
*/
XTCDECL
EFI_STATUS
BlpParseCommandLine(VOID)
Configuration::ParseCommandLine(VOID)
{
EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
PEFI_LOADED_IMAGE_PROTOCOL LoadedImage;
@@ -546,15 +359,15 @@ BlpParseCommandLine(VOID)
}
/* 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)
{
/* 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)
{
/* 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)
@@ -577,7 +390,7 @@ BlpParseCommandLine(VOID)
}
/* Update global configuration */
BlpUpdateConfiguration(&Config);
UpdateConfiguration(&Config);
}
}
@@ -600,7 +413,7 @@ BlpParseCommandLine(VOID)
*/
XTCDECL
EFI_STATUS
BlpParseConfigFile(IN CONST PCHAR RawConfig,
Configuration::ParseConfigFile(IN CONST PCHAR RawConfig,
OUT PLIST_ENTRY Configuration)
{
SIZE_T SectionLength, KeyLength, ValueLength;
@@ -667,11 +480,11 @@ BlpParseConfigFile(IN CONST PCHAR RawConfig,
SectionLength = RTL::String::StringLength(SectionName, 0);
/* 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)
{
/* 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)
{
@@ -740,15 +553,15 @@ BlpParseConfigFile(IN CONST PCHAR RawConfig,
ValueLength = RTL::String::StringLength(Value, 0);
/* 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)
{
/* 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)
{
/* 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)
@@ -802,7 +615,7 @@ BlpParseConfigFile(IN CONST PCHAR RawConfig,
*/
XTCDECL
EFI_STATUS
BlpReadConfigFile(IN PCWSTR ConfigDirectory,
Configuration::ReadConfigFile(IN PCWSTR ConfigDirectory,
IN PCWSTR ConfigFile,
OUT PCHAR *ConfigData)
{
@@ -812,7 +625,7 @@ BlpReadConfigFile(IN PCWSTR ConfigDirectory,
SIZE_T FileSize;
/* Open EFI volume */
Status = BlOpenVolume(NULLPTR, &DiskHandle, &FsHandle);
Status = Volume::OpenVolume(NULLPTR, &DiskHandle, &FsHandle);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to open a volume */
@@ -827,21 +640,209 @@ BlpReadConfigFile(IN PCWSTR ConfigDirectory,
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to open directory */
BlCloseVolume(&DiskHandle);
Volume::CloseVolume(&DiskHandle);
return Status;
}
/* Read configuration file and close directory */
Status = BlReadFile(DirHandle, ConfigFile, (PVOID *)ConfigData, &FileSize);
Status = Volume::ReadFile(DirHandle, ConfigFile, (PVOID *)ConfigData, &FileSize);
DirHandle->Close(DirHandle);
/* Close EFI volume */
BlCloseVolume(&DiskHandle);
Volume::CloseVolume(&DiskHandle);
/* Return read 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.
*
@@ -854,7 +855,7 @@ BlpReadConfigFile(IN PCWSTR ConfigDirectory,
*/
XTCDECL
VOID
BlpUpdateConfiguration(IN PLIST_ENTRY NewConfig)
Configuration::UpdateConfiguration(IN PLIST_ENTRY NewConfig)
{
PXTBL_CONFIG_ENTRY ConfigEntry;
PWCHAR ConfigValue;
@@ -871,7 +872,7 @@ BlpUpdateConfiguration(IN PLIST_ENTRY NewConfig)
NextListEntry = ConfigListEntry->Flink;
/* Make sure config entry does not exist yet */
BlGetConfigValue(ConfigEntry->Name, &ConfigValue);
GetValue(ConfigEntry->Name, &ConfigValue);
if(ConfigValue == NULLPTR)
{
/* Remove new config entry from input list and put it into global config list */

View File

@@ -21,19 +21,19 @@
*/
XTCDECL
VOID
BlClearConsoleLine(IN ULONGLONG LineNo)
Console::ClearLine(IN ULONGLONG LineNo)
{
UINT_PTR Index, ResX, ResY;
/* Query console mode */
BlQueryConsoleMode(&ResX, &ResY);
QueryMode(&ResX, &ResY);
/* Set cursor position and clear line */
BlSetCursorPosition(0, LineNo);
SetCursorPosition(0, LineNo);
for(Index = 0; Index < ResX; Index++)
{
/* Clear line */
BlConsoleWrite(L" ");
Write(L" ");
}
}
@@ -46,7 +46,7 @@ BlClearConsoleLine(IN ULONGLONG LineNo)
*/
XTCDECL
VOID
BlClearConsoleScreen()
Console::ClearScreen()
{
/* Clear screen */
EfiSystemTable->ConOut->ClearScreen(EfiSystemTable->ConOut);
@@ -61,7 +61,7 @@ BlClearConsoleScreen()
*/
XTCDECL
VOID
BlDisableConsoleCursor()
Console::DisableCursor()
{
EfiSystemTable->ConOut->EnableCursor(EfiSystemTable->ConOut, FALSE);
}
@@ -75,11 +75,41 @@ BlDisableConsoleCursor()
*/
XTCDECL
VOID
BlEnableConsoleCursor()
Console::EnableCursor()
{
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.
*
@@ -95,15 +125,15 @@ BlEnableConsoleCursor()
*/
XTCDECL
VOID
BlConsolePrint(IN PCWSTR Format,
Console::Print(IN PCWSTR Format,
IN ...)
{
RTL_PRINT_CONTEXT ConsolePrintContext, SerialPrintContext;
VA_LIST Arguments;
/* Initialise the print contexts */
ConsolePrintContext.WriteWideCharacter = BlpConsolePutChar;
SerialPrintContext.WriteWideCharacter = BlpDebugPutChar;
ConsolePrintContext.WriteWideCharacter = PutChar;
SerialPrintContext.WriteWideCharacter = Debug::PutChar;
/* Initialise the va_list */
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
* The string to be displayed.
* @param Character
* 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
*/
XTCDECL
VOID
BlConsoleWrite(IN PCWSTR String)
XTSTATUS
Console::PutChar(IN WCHAR Character)
{
EfiSystemTable->ConOut->OutputString(EfiSystemTable->ConOut, (PWSTR)String);
}
WCHAR Buffer[2];
/**
* This routine initializes the EFI console.
*
* @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)
/* Check if character is a newline ('\n') */
if(Character == L'\n')
{
/* Set console mode to 0, which is standard, 80x25 text mode */
BlSetConsoleMode(0);
/* Print carriage return ('\r') as well */
PutChar(L'\r');
}
/* Clear screen and enable cursor */
BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY);
BlClearConsoleScreen();
BlEnableConsoleCursor();
/* Write character to the screen console */
Buffer[0] = Character;
Buffer[1] = 0;
EfiSystemTable->ConOut->OutputString(EfiSystemTable->ConOut, Buffer);
/* Return success */
return STATUS_SUCCESS;
}
/**
@@ -188,7 +203,7 @@ BlInitializeConsole()
*/
XTCDECL
VOID
BlQueryConsoleMode(OUT PUINT_PTR ResX,
Console::QueryMode(OUT PUINT_PTR ResX,
OUT PUINT_PTR ResY)
{
EfiSystemTable->ConOut->QueryMode(EfiSystemTable->ConOut, EfiSystemTable->ConOut->Mode->Mode, ResX, ResY);
@@ -206,7 +221,7 @@ BlQueryConsoleMode(OUT PUINT_PTR ResX,
*/
XTCDECL
VOID
BlReadKeyStroke(OUT PEFI_INPUT_KEY Key)
Console::ReadKeyStroke(OUT PEFI_INPUT_KEY Key)
{
EfiSystemTable->ConIn->ReadKeyStroke(EfiSystemTable->ConIn, Key);
}
@@ -220,7 +235,7 @@ BlReadKeyStroke(OUT PEFI_INPUT_KEY Key)
*/
XTCDECL
VOID
BlResetConsoleInputBuffer()
Console::ResetInputBuffer()
{
EfiSystemTable->ConIn->Reset(EfiSystemTable->ConIn, FALSE);
}
@@ -237,28 +252,11 @@ BlResetConsoleInputBuffer()
*/
XTCDECL
VOID
BlSetConsoleAttributes(IN ULONGLONG Attributes)
Console::SetAttributes(IN ULONGLONG 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.
*
@@ -274,40 +272,42 @@ BlSetConsoleMode(IN ULONGLONG Mode)
*/
XTCDECL
VOID
BlSetCursorPosition(IN ULONGLONG PosX,
Console::SetCursorPosition(IN ULONGLONG PosX,
IN ULONGLONG 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
* The integer promotion of the character to be written.
* @param Mode
* Supplies a text mode number to set.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
XTSTATUS
BlpConsolePutChar(IN WCHAR Character)
EFI_STATUS
Console::SetMode(IN ULONGLONG Mode)
{
WCHAR Buffer[2];
/* Check if character is a newline ('\n') */
if(Character == L'\n')
{
/* Print carriage return ('\r') as well */
BlpConsolePutChar(L'\r');
}
/* Write character to the screen console */
Buffer[0] = Character;
Buffer[1] = 0;
EfiSystemTable->ConOut->OutputString(EfiSystemTable->ConOut, Buffer);
/* Return success */
return STATUS_SUCCESS;
return EfiSystemTable->ConOut->SetMode(EfiSystemTable->ConOut, Mode);
}
/**
* Displays the string on the device at the current cursor location.
*
* @param String
* The string to be displayed.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
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.
*
* @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.
* 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
XTSTATUS
BlpDebugPutChar(IN WCHAR Character)
EFI_STATUS
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 */
Buffer[0] = Character;
Buffer[1] = 0;
return HL::ComPort::WriteComPort(&BlpStatus.SerialPort, Buffer[0]);
/* Allocate memory for single EFI_HANDLE, what should be enough in most cases */
PciHandleSize = sizeof(EFI_HANDLE);
Status = Memory::AllocatePool(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 */
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
EFI_STATUS
BlpInitializeDebugConsole()
Debug::InitializeDebugConsole()
{
ULONG PortAddress, PortNumber, BaudRate;
PWCHAR DebugConfiguration, DebugPort, LastPort;
@@ -102,7 +132,7 @@ BlpInitializeDebugConsole()
BaudRate = 0;
/* 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 */
if(DebugConfiguration && BlpStatus.DebugPort == 0)
@@ -178,8 +208,8 @@ BlpInitializeDebugConsole()
else
{
/* Unsupported debug port specified */
BlConsolePrint(L"ERROR: Unsupported debug port ('%S') specified\n", DebugPort);
BlSleepExecution(3000);
Console::Print(L"ERROR: Unsupported debug port ('%S') specified\n", DebugPort);
EfiUtils::SleepExecution(3000);
}
/* Take next debug port */
@@ -190,7 +220,7 @@ BlpInitializeDebugConsole()
if(BlpStatus.DebugPort & XTBL_DEBUGPORT_SERIAL)
{
/* Try to initialize COM port */
Status = BlpInitializeSerialPort(PortNumber, PortAddress, BaudRate);
Status = InitializeSerialPort(PortNumber, PortAddress, BaudRate);
if(Status != STATUS_EFI_SUCCESS)
{
/* Remove serial debug port, as COM port initialization failed and return */
@@ -222,7 +252,7 @@ BlpInitializeDebugConsole()
*/
XTCDECL
EFI_STATUS
BlpInitializeSerialPort(IN ULONG PortNumber,
Debug::InitializeSerialPort(IN ULONG PortNumber,
IN ULONG PortAddress,
IN ULONG BaudRate)
{
@@ -248,12 +278,12 @@ BlpInitializeSerialPort(IN ULONG PortNumber,
/* Set custom port address based on the port number and print debug message */
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
{
/* 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 */
@@ -263,11 +293,11 @@ BlpInitializeSerialPort(IN ULONG PortNumber,
if(Status == STATUS_NOT_FOUND && PortAddress)
{
/* This might be PCI(E) serial controller, try to activate I/O space access first */
EfiStatus = BlpActivateSerialIOController();
EfiStatus = ActivateSerialIOController();
if(EfiStatus == STATUS_EFI_SUCCESS)
{
/* 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);
}
}
@@ -282,3 +312,75 @@ BlpInitializeSerialPort(IN ULONG PortNumber,
/* Return 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
EFI_STATUS
BlEnterFirmwareSetup()
EfiUtils::EnterFirmwareSetup()
{
EFI_GUID Guid = EFI_GLOBAL_VARIABLE_GUID;
PULONGLONG SetupSupport = NULLPTR;
@@ -26,27 +26,27 @@ BlEnterFirmwareSetup()
EFI_STATUS Status;
/* 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))
{
/* 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)
{
BlFreeMemoryPool((PVOID)SetupSupport);
Memory::FreePool((PVOID)SetupSupport);
}
return STATUS_EFI_UNSUPPORTED;
}
BlFreeMemoryPool((PVOID)SetupSupport);
Memory::FreePool((PVOID)SetupSupport);
/* Get the value of OsIndications variable */
Indications = 0;
Status = BlGetEfiVariable(&Guid, L"OsIndications", (PVOID*)&Indications);
Status = GetEfiVariable(&Guid, L"OsIndications", (PVOID*)&Indications);
/* Enable FW setup on next boot */
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)
{
/* Failed to update OsIndications variable */
@@ -54,7 +54,7 @@ BlEnterFirmwareSetup()
}
/* Reboot into firmware setup */
BlRebootSystem();
RebootSystem();
/* Must not reach this point, just make the compiler happy */
return STATUS_EFI_SUCCESS;
@@ -69,7 +69,7 @@ BlEnterFirmwareSetup()
*/
XTCDECL
EFI_STATUS
BlExitBootServices()
EfiUtils::ExitBootServices()
{
PEFI_MEMORY_MAP MemoryMap;
EFI_STATUS Status;
@@ -79,11 +79,11 @@ BlExitBootServices()
BlpStatus.BootServices = FALSE;
/* 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)
{
/* 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;
}
@@ -95,7 +95,7 @@ BlExitBootServices()
while(Counter > 0)
{
/* Get memory map each time as it can change between two calls */
Status = BlGetMemoryMap(MemoryMap);
Status = Memory::GetMemoryMap(MemoryMap);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to get new memory map */
@@ -132,7 +132,7 @@ BlExitBootServices()
*/
XTCDECL
EFI_STATUS
BlGetConfigurationTable(IN PEFI_GUID TableGuid,
EfiUtils::GetConfigurationTable(IN PEFI_GUID TableGuid,
OUT PVOID *Table)
{
SIZE_T Index;
@@ -172,7 +172,7 @@ BlGetConfigurationTable(IN PEFI_GUID TableGuid,
*/
XTCDECL
EFI_STATUS
BlGetEfiVariable(IN PEFI_GUID Vendor,
EfiUtils::GetEfiVariable(IN PEFI_GUID Vendor,
IN PCWSTR VariableName,
OUT PVOID *VariableValue)
{
@@ -182,7 +182,7 @@ BlGetEfiVariable(IN PEFI_GUID Vendor,
/* Allocate a buffer for storing a variable's value */
Size = EFI_MAXIMUM_VARIABLE_SIZE * sizeof(PWCHAR);
Status = BlAllocateMemoryPool(Size, (PVOID*)&Buffer);
Status = Memory::AllocatePool(Size, (PVOID*)&Buffer);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure */
@@ -216,7 +216,7 @@ BlGetEfiVariable(IN PEFI_GUID Vendor,
*/
XTCDECL
ULONGLONG
BlGetRandomValue(IN OUT PULONGLONG RNGBuffer)
EfiUtils::GetRandomValue(IN OUT PULONGLONG RNGBuffer)
{
/* Recalculate RNG buffer with XORSHIFT */
*RNGBuffer ^= *RNGBuffer >> 12;
@@ -236,7 +236,7 @@ BlGetRandomValue(IN OUT PULONGLONG RNGBuffer)
*/
XTCDECL
INT_PTR
BlGetSecureBootStatus()
EfiUtils::GetSecureBootStatus()
{
EFI_GUID VarGuid = EFI_GLOBAL_VARIABLE_GUID;
INT_PTR SecureBootStatus = 0;
@@ -272,7 +272,7 @@ BlGetSecureBootStatus()
*/
XTCDECL
EFI_STATUS
BlInitializeEntropy(PULONGLONG RNGBuffer)
EfiUtils::InitializeEntropy(PULONGLONG RNGBuffer)
{
EFI_GUID RngGuid = EFI_RNG_PROTOCOL_GUID;
PEFI_RNG_PROTOCOL Rng;
@@ -325,7 +325,7 @@ BlInitializeEntropy(PULONGLONG RNGBuffer)
*/
XTCDECL
EFI_STATUS
BlLoadEfiImage(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
EfiUtils::LoadEfiImage(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
IN PVOID ImageData,
IN SIZE_T ImageSize,
OUT PEFI_HANDLE ImageHandle)
@@ -343,7 +343,7 @@ BlLoadEfiImage(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
*/
XTCDECL
EFI_STATUS
BlRebootSystem()
EfiUtils::RebootSystem()
{
/* Reboot machine */
return EfiSystemTable->RuntimeServices->ResetSystem(EfiResetCold, STATUS_EFI_SUCCESS, 0, NULLPTR);
@@ -370,7 +370,7 @@ BlRebootSystem()
*/
XTCDECL
EFI_STATUS
BlSetEfiVariable(IN PEFI_GUID Vendor,
EfiUtils::SetEfiVariable(IN PEFI_GUID Vendor,
IN PCWSTR VariableName,
IN PVOID VariableValue,
IN UINT_PTR Size)
@@ -391,7 +391,7 @@ BlSetEfiVariable(IN PEFI_GUID Vendor,
*/
XTCDECL
EFI_STATUS
BlShutdownSystem()
EfiUtils::ShutdownSystem()
{
/* Shutdown machine */
return EfiSystemTable->RuntimeServices->ResetSystem(EfiResetShutdown, STATUS_EFI_SUCCESS, 0, NULLPTR);
@@ -409,7 +409,7 @@ BlShutdownSystem()
*/
XTCDECL
VOID
BlSleepExecution(IN ULONG_PTR Milliseconds)
EfiUtils::SleepExecution(IN ULONG_PTR Milliseconds)
{
EfiSystemTable->BootServices->Stall(Milliseconds * 1000);
}
@@ -426,7 +426,7 @@ BlSleepExecution(IN ULONG_PTR Milliseconds)
*/
XTCDECL
EFI_STATUS
BlStartEfiImage(IN EFI_HANDLE ImageHandle)
EfiUtils::StartEfiImage(IN EFI_HANDLE ImageHandle)
{
return EfiSystemTable->BootServices->StartImage(ImageHandle, NULLPTR, NULLPTR);
}
@@ -449,7 +449,7 @@ BlStartEfiImage(IN EFI_HANDLE ImageHandle)
*/
XTCDECL
EFI_STATUS
BlWaitForEfiEvent(IN UINT_PTR NumberOfEvents,
EfiUtils::WaitForEfiEvent(IN UINT_PTR NumberOfEvents,
IN PEFI_EVENT Event,
OUT PUINT_PTR 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>
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 */
XTCDECL
EFI_STATUS

View File

@@ -24,7 +24,7 @@
*/
XTCDECL
EFI_STATUS
BlAllocateMemoryPages(IN EFI_ALLOCATE_TYPE AllocationType,
Memory::AllocatePages(IN EFI_ALLOCATE_TYPE AllocationType,
IN ULONGLONG NumberOfPages,
OUT PEFI_PHYSICAL_ADDRESS Memory)
{
@@ -46,7 +46,7 @@ BlAllocateMemoryPages(IN EFI_ALLOCATE_TYPE AllocationType,
*/
XTCDECL
EFI_STATUS
BlAllocateMemoryPool(IN UINT_PTR Size,
Memory::AllocatePool(IN UINT_PTR Size,
OUT PVOID *Memory)
{
/* Allocate pool */
@@ -68,7 +68,7 @@ BlAllocateMemoryPool(IN UINT_PTR Size,
*/
XTCDECL
EFI_STATUS
BlFreeMemoryPages(IN ULONGLONG NumberOfPages,
Memory::FreePages(IN ULONGLONG NumberOfPages,
IN EFI_PHYSICAL_ADDRESS Memory)
{
return EfiSystemTable->BootServices->FreePages(Memory, NumberOfPages);
@@ -86,12 +86,60 @@ BlFreeMemoryPages(IN ULONGLONG NumberOfPages,
*/
XTCDECL
EFI_STATUS
BlFreeMemoryPool(IN PVOID Memory)
Memory::FreePool(IN PVOID Memory)
{
/* Free pool */
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.
*
@@ -107,7 +155,7 @@ BlFreeMemoryPool(IN PVOID Memory)
*/
XTCDECL
VOID
BlGetMappingsCount(IN PXTBL_PAGE_MAPPING PageMap,
Memory::GetMappingsCount(IN PXTBL_PAGE_MAPPING PageMap,
OUT PULONG NumberOfMappings)
{
/* Return number of mappings */
@@ -126,7 +174,7 @@ BlGetMappingsCount(IN PXTBL_PAGE_MAPPING PageMap,
*/
XTCDECL
EFI_STATUS
BlGetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap)
Memory::GetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap)
{
EFI_STATUS Status;
@@ -155,14 +203,14 @@ BlGetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap)
if(MemoryMap->Map)
{
/* Free allocated memory */
BlFreeMemoryPool(MemoryMap->Map);
FreePool(MemoryMap->Map);
}
return Status;
}
/* Allocate the desired amount of memory */
MemoryMap->MapSize += 2 * MemoryMap->DescriptorSize;
BlAllocateMemoryPool(MemoryMap->MapSize, (PVOID *)&MemoryMap->Map);
AllocatePool(MemoryMap->MapSize, (PVOID *)&MemoryMap->Map);
}
while(Status == STATUS_EFI_BUFFER_TOO_SMALL);
@@ -192,7 +240,7 @@ BlGetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap)
*/
XTCDECL
PVOID
BlGetVirtualAddress(IN PXTBL_PAGE_MAPPING PageMap,
Memory::GetVirtualAddress(IN PXTBL_PAGE_MAPPING PageMap,
IN PVOID PhysicalAddress)
{
PXTBL_MEMORY_MAPPING Mapping;
@@ -243,7 +291,7 @@ BlGetVirtualAddress(IN PXTBL_PAGE_MAPPING PageMap,
*/
XTCDECL
VOID
BlInitializePageMap(OUT PXTBL_PAGE_MAPPING PageMap,
Memory::InitializePageMap(OUT PXTBL_PAGE_MAPPING PageMap,
IN SHORT PageMapLevel,
IN PAGE_SIZE PageSize)
{
@@ -274,7 +322,7 @@ BlInitializePageMap(OUT PXTBL_PAGE_MAPPING PageMap,
*/
XTCDECL
EFI_STATUS
BlMapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
Memory::MapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
IN OUT PVOID *MemoryMapAddress,
IN PBL_GET_MEMTYPE_ROUTINE GetMemoryTypeRoutine)
{
@@ -293,15 +341,15 @@ BlMapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
if(GetMemoryTypeRoutine == NULLPTR)
{
/* Use default memory type routine */
GetMemoryTypeRoutine = BlpGetLoaderMemoryType;
GetMemoryTypeRoutine = GetLoaderMemoryType;
}
/* 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));
/* Get EFI memory map */
Status = BlGetMemoryMap(MemoryMap);
Status = GetMemoryMap(MemoryMap);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to get EFI memory map */
@@ -352,13 +400,13 @@ BlMapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
if(MemoryType == LoaderFirmwareTemporary)
{
/* Map EFI firmware code */
Status = BlMapVirtualMemory(PageMap, (PVOID)Descriptor->PhysicalStart,
Status = MapVirtualMemory(PageMap, (PVOID)Descriptor->PhysicalStart,
(PVOID)Descriptor->PhysicalStart, Descriptor->NumberOfPages, MemoryType);
}
else if(MemoryType != LoaderFree)
{
/* Add any non-free memory mapping */
Status = BlMapVirtualMemory(PageMap, VirtualAddress, (PVOID)Descriptor->PhysicalStart,
Status = MapVirtualMemory(PageMap, VirtualAddress, (PVOID)Descriptor->PhysicalStart,
Descriptor->NumberOfPages, MemoryType);
/* Calculate next valid virtual address */
@@ -367,7 +415,7 @@ BlMapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
else
{
/* Map all other memory as loader free */
Status = BlMapVirtualMemory(PageMap, NULLPTR, (PVOID)Descriptor->PhysicalStart,
Status = MapVirtualMemory(PageMap, NULLPTR, (PVOID)Descriptor->PhysicalStart,
Descriptor->NumberOfPages, LoaderFree);
}
@@ -384,7 +432,7 @@ BlMapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
}
/* 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)
{
/* Mapping failed */
@@ -392,7 +440,7 @@ BlMapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
}
/* 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)
{
/* Mapping failed */
@@ -428,7 +476,7 @@ BlMapEfiMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
*/
XTCDECL
EFI_STATUS
BlMapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
Memory::MapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
IN PVOID VirtualAddress,
IN PVOID PhysicalAddress,
IN ULONGLONG NumberOfPages,
@@ -441,7 +489,7 @@ BlMapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
EFI_STATUS Status;
/* 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)
{
/* Memory allocation failure */
@@ -491,7 +539,7 @@ BlMapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
if(NumberOfMappedPages > 0)
{
/* 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)
{
/* Memory allocation failure */
@@ -527,7 +575,7 @@ BlMapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
if(NumberOfMappedPages > 0)
{
/* 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)
{
/* 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 */
RTL::LinkedList::RemoveEntryList(&Mapping2->ListEntry);
Status = BlFreeMemoryPool(Mapping2);
Status = FreePool(Mapping2);
ListEntry = MappingListEntry;
/* Go to the next mapping */
@@ -609,7 +657,7 @@ BlMapVirtualMemory(IN OUT PXTBL_PAGE_MAPPING PageMap,
*/
XTCDECL
PVOID
BlPhysicalAddressToVirtual(IN PVOID PhysicalAddress,
Memory::PhysicalAddressToVirtual(IN PVOID PhysicalAddress,
IN PVOID PhysicalBase,
IN PVOID VirtualBase)
{
@@ -638,7 +686,7 @@ BlPhysicalAddressToVirtual(IN PVOID PhysicalAddress,
*/
XTCDECL
EFI_STATUS
BlPhysicalListToVirtual(IN PXTBL_PAGE_MAPPING PageMap,
Memory::PhysicalListToVirtual(IN PXTBL_PAGE_MAPPING PageMap,
IN OUT PLIST_ENTRY ListHead,
IN PVOID PhysicalBase,
IN PVOID VirtualBase)
@@ -663,12 +711,12 @@ BlPhysicalListToVirtual(IN PXTBL_PAGE_MAPPING PageMap,
if(ListEntry->Blink == ListHead)
{
/* Find virtual address of list head */
ListEntry->Blink = (PLIST_ENTRY)BlGetVirtualAddress(PageMap, ListEntry->Blink);
ListEntry->Blink = (PLIST_ENTRY)GetVirtualAddress(PageMap, ListEntry->Blink);
}
else
{
/* 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)
{
@@ -678,7 +726,7 @@ BlPhysicalListToVirtual(IN PXTBL_PAGE_MAPPING PageMap,
else
{
/* 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*/
@@ -686,57 +734,9 @@ BlPhysicalListToVirtual(IN PXTBL_PAGE_MAPPING PageMap,
}
/* Convert list head */
ListHead->Blink = (PLIST_ENTRY)BlPhysicalAddressToVirtual(ListHead->Blink, (PVOID)PhysicalBase, VirtualBase);
ListHead->Flink = (PLIST_ENTRY)BlPhysicalAddressToVirtual(ListHead->Flink, (PVOID)PhysicalBase, VirtualBase);
ListHead->Blink = (PLIST_ENTRY)PhysicalAddressToVirtual(ListHead->Blink, (PVOID)PhysicalBase, VirtualBase);
ListHead->Flink = (PLIST_ENTRY)PhysicalAddressToVirtual(ListHead->Flink, (PVOID)PhysicalBase, VirtualBase);
/* Return success */
return STATUS_EFI_SUCCESS;
}
/**
* 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;
/* 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))
{
/* RSDP not found or checksum mismatch */
@@ -260,7 +260,7 @@ Acpi::GetSMBiosTable(OUT PVOID *SmBiosTable)
EFI_STATUS Status;
/* 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))
{
/* SMBIOS not found or checksum mismatch */
@@ -292,7 +292,7 @@ Acpi::GetSMBios3Table(OUT PVOID *SmBiosTable)
EFI_STATUS Status;
/* 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))
{
/* SMBIOS3 not found or checksum mismatch */
@@ -324,7 +324,7 @@ Acpi::GetXsdpTable(OUT PVOID *AcpiTable)
PVOID XsdpTable;
/* 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))
{
/* XSDP not found or checksum mismatch */

View File

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

View File

@@ -90,7 +90,7 @@ ChainLoader::BootSystem(IN PXTBL_BOOT_PARAMETERS Parameters)
MemoryDevicePath[1].Header.SubType = EFI_END_ENTIRE_DP;
/* Load EFI image */
Status = XtLdrProtocol->Util.LoadEfiImage((PEFI_DEVICE_PATH_PROTOCOL)MemoryDevicePath,
Status = XtLdrProtocol->Utils.LoadEfiImage((PEFI_DEVICE_PATH_PROTOCOL)MemoryDevicePath,
LoaderData, LoaderSize, &LoaderHandle);
if(Status != STATUS_EFI_SUCCESS)
{
@@ -121,7 +121,7 @@ ChainLoader::BootSystem(IN PXTBL_BOOT_PARAMETERS Parameters)
LoadedImage->DeviceHandle = DiskHandle;
/* 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 */
if((CpuRegisters.Ecx & CPUID_FEATURES_ECX_LA57) &&
!(XtLdrProtocol->BootUtil.GetBooleanParameter(Parameters, L"NOXPA")))
!(XtLdrProtocol->BootUtils.GetBooleanParameter(Parameters, L"NOXPA")))
{
/* Enable LA57 (PML5) */
return 5;
@@ -98,7 +98,7 @@ Xtos::EnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
if(PageMap->PageMapLevel == 5)
{
/* Get the trampoline code information */
XtLdrProtocol->BootUtil.GetTrampolineInformation(TrampolineEnableXpa, &TrampolineCode, &TrampolineSize);
XtLdrProtocol->BootUtils.GetTrampolineInformation(TrampolineEnableXpa, &TrampolineCode, &TrampolineSize);
if(TrampolineCode == NULLPTR || TrampolineSize == 0)
{
/* Failed to get trampoline information */
@@ -125,7 +125,7 @@ Xtos::EnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
/* Exit EFI Boot Services */
XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n");
Status = XtLdrProtocol->Util.ExitBootServices();
Status = XtLdrProtocol->Utils.ExitBootServices();
if(Status != STATUS_EFI_SUCCESS)
{
/* 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 */
if((CpuRegisters.Edx & CPUID_FEATURES_EDX_PAE) &&
!(XtLdrProtocol->BootUtil.GetBooleanParameter(Parameters, L"NOXPA")))
!(XtLdrProtocol->BootUtils.GetBooleanParameter(Parameters, L"NOXPA")))
{
/* Enable PAE (PML3) */
return 3;
@@ -80,7 +80,7 @@ Xtos::EnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
/* Exit EFI Boot Services */
XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n");
Status = XtLdrProtocol->Util.ExitBootServices();
Status = XtLdrProtocol->Utils.ExitBootServices();
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to exit boot services */

View File

@@ -24,7 +24,7 @@
*/
XTCDECL
EFI_STATUS
BlCloseProtocol(IN PEFI_HANDLE Handle,
Protocol::CloseProtocol(IN PEFI_HANDLE Handle,
IN PEFI_GUID ProtocolGuid)
{
return EfiSystemTable->BootServices->CloseProtocol(Handle, ProtocolGuid, EfiImageHandle, NULLPTR);
@@ -45,7 +45,7 @@ BlCloseProtocol(IN PEFI_HANDLE Handle,
*/
XTCDECL
EFI_STATUS
BlFindBootProtocol(IN PCWSTR SystemType,
Protocol::FindBootProtocol(IN PCWSTR SystemType,
OUT PEFI_GUID BootProtocolGuid)
{
PXTBL_KNOWN_BOOT_PROTOCOL ProtocolEntry;
@@ -84,7 +84,7 @@ BlFindBootProtocol(IN PCWSTR SystemType,
*/
XTCDECL
PLIST_ENTRY
BlGetModulesList()
Protocol::GetModulesList()
{
/* Return a pointer to a list of all loaded modules */
return &BlpLoadedModules;
@@ -105,7 +105,7 @@ BlGetModulesList()
*/
XTCDECL
EFI_STATUS
BlInstallProtocol(IN PVOID Interface,
Protocol::InstallProtocol(IN PVOID Interface,
IN PEFI_GUID Guid)
{
EFI_HANDLE Handle = NULLPTR;
@@ -114,6 +114,157 @@ BlInstallProtocol(IN PVOID 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.
*
@@ -126,7 +277,7 @@ BlInstallProtocol(IN PVOID Interface,
*/
XTCDECL
EFI_STATUS
BlLoadModule(IN PWCHAR ModuleName)
Protocol::LoadModule(IN PWCHAR ModuleName)
{
EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
PLIST_ENTRY DepsListEntry, ModuleListEntry;
@@ -155,7 +306,7 @@ BlLoadModule(IN PWCHAR ModuleName)
if(RTL::WideString::CompareWideStringInsensitive(ModuleInfo->ModuleName, ModuleName, 0) == 0)
{
/* 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;
}
@@ -164,14 +315,14 @@ BlLoadModule(IN PWCHAR ModuleName)
}
/* Print debug message */
BlDebugPrint(L"Loading module '%S' ...\n", ModuleName);
Debug::Print(L"Loading module '%S' ...\n", ModuleName);
/* Set module path */
RTL::Memory::CopyMemory(ModuleFileName, ModuleName, (RTL::WideString::WideStringLength(ModuleName, 0) + 1) * sizeof(WCHAR));
RTL::WideString::ConcatenateWideString(ModuleFileName, (PWCHAR)L".EFI", 0);
/* Open EFI volume */
Status = BlOpenVolume(NULLPTR, &DiskHandle, &FsHandle);
Status = Volume::OpenVolume(NULLPTR, &DiskHandle, &FsHandle);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to open a volume */
@@ -193,14 +344,14 @@ BlLoadModule(IN PWCHAR ModuleName)
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to open directory */
BlCloseVolume(&DiskHandle);
Volume::CloseVolume(&DiskHandle);
return Status;
}
/* 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);
BlCloseVolume(&DiskHandle);
Volume::CloseVolume(&DiskHandle);
/* Make sure module file was read successfully */
if(Status != STATUS_EFI_SUCCESS)
@@ -210,7 +361,7 @@ BlLoadModule(IN PWCHAR ModuleName)
}
/* 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)
{
/* Failed to allocate memory */
@@ -247,7 +398,7 @@ BlLoadModule(IN PWCHAR ModuleName)
SectionData = (PWCHAR)((PUCHAR)ModuleData + SectionHeader[SectionIndex].PointerToRawData);
/* Get module information */
Status = BlpGetModuleInformation(SectionData, SectionHeader[SectionIndex].SizeOfRawData, ModuleInfo);
Status = GetModuleInformation(SectionData, SectionHeader[SectionIndex].SizeOfRawData, ModuleInfo);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to read module information */
@@ -271,12 +422,12 @@ BlLoadModule(IN PWCHAR ModuleName)
}
/* Load dependency module */
BlDebugPrint(L"Module '%S' requires '%S' ...\n", ModuleName, ModuleDependency->ModuleName);
Status = BlLoadModule(ModuleDependency->ModuleName);
Debug::Print(L"Module '%S' requires '%S' ...\n", ModuleName, ModuleDependency->ModuleName);
Status = LoadModule(ModuleDependency->ModuleName);
if(Status != STATUS_EFI_SUCCESS)
{
/* 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;
}
@@ -298,20 +449,20 @@ BlLoadModule(IN PWCHAR ModuleName)
ModuleDevicePath[1].Header.SubType = EFI_END_ENTIRE_DP;
/* Load EFI image */
BlDebugPrint(L"Starting module '%S' ...\n", ModuleName);
Status = BlLoadEfiImage((PEFI_DEVICE_PATH_PROTOCOL)ModuleDevicePath, ModuleData, ModuleSize, &ModuleHandle);
Debug::Print(L"Starting module '%S' ...\n", ModuleName);
Status = EfiUtils::LoadEfiImage((PEFI_DEVICE_PATH_PROTOCOL)ModuleDevicePath, ModuleData, ModuleSize, &ModuleHandle);
if(Status != STATUS_EFI_SUCCESS)
{
/* Check if caused by secure boot */
if(Status == STATUS_EFI_ACCESS_DENIED && BlpStatus.SecureBoot >= 1)
{
/* 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
{
/* 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 */
@@ -324,7 +475,7 @@ BlLoadModule(IN PWCHAR ModuleName)
if(Status != STATUS_EFI_SUCCESS)
{
/* 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;
}
@@ -332,7 +483,7 @@ BlLoadModule(IN PWCHAR ModuleName)
if(LoadedImage->ImageCodeType != EfiBootServicesCode)
{
/* 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 */
EfiSystemTable->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULLPTR);
@@ -349,11 +500,11 @@ BlLoadModule(IN PWCHAR ModuleName)
EfiSystemTable->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULLPTR);
/* Start EFI image */
Status = BlStartEfiImage(ModuleHandle);
Status = EfiUtils::StartEfiImage(ModuleHandle);
if(Status != STATUS_EFI_SUCCESS)
{
/* 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;
}
@@ -376,7 +527,7 @@ BlLoadModule(IN PWCHAR ModuleName)
*/
XTCDECL
EFI_STATUS
BlLoadModules(IN PWCHAR ModulesList)
Protocol::LoadModules(IN PWCHAR ModulesList)
{
PWCHAR LastModule, Module;
EFI_STATUS ReturnStatus, Status;
@@ -392,11 +543,11 @@ BlLoadModules(IN PWCHAR ModulesList)
/* Iterate over all arguments passed to boot loader */
while(Module != NULLPTR)
{
Status = BlLoadModule(Module);
Status = LoadModule(Module);
if(Status != STATUS_EFI_SUCCESS)
{
/* 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;
}
@@ -427,7 +578,7 @@ BlLoadModules(IN PWCHAR ModulesList)
*/
XTCDECL
EFI_STATUS
BlLocateProtocolHandles(OUT PEFI_HANDLE *Handles,
Protocol::LocateProtocolHandles(OUT PEFI_HANDLE *Handles,
OUT PUINT_PTR Count,
IN PEFI_GUID ProtocolGuid)
{
@@ -452,7 +603,7 @@ BlLocateProtocolHandles(OUT PEFI_HANDLE *Handles,
*/
XTCDECL
EFI_STATUS
BlOpenProtocol(OUT PEFI_HANDLE Handle,
Protocol::OpenProtocol(OUT PEFI_HANDLE Handle,
OUT PVOID *ProtocolHandler,
IN PEFI_GUID ProtocolGuid)
{
@@ -462,7 +613,7 @@ BlOpenProtocol(OUT PEFI_HANDLE Handle,
UINT Index;
/* Try to locate the handles */
Status = BlLocateProtocolHandles(&Handles, &Count, ProtocolGuid);
Status = LocateProtocolHandles(&Handles, &Count, ProtocolGuid);
if(Status != STATUS_EFI_SUCCESS)
{
/* Unable to get handles */
@@ -476,7 +627,7 @@ BlOpenProtocol(OUT PEFI_HANDLE Handle,
for(Index = 0; Index < Count; Index++)
{
/* Try to open protocol */
Status = BlOpenProtocolHandle(Handles[Index], ProtocolHandler, ProtocolGuid);
Status = OpenProtocolHandle(Handles[Index], ProtocolHandler, ProtocolGuid);
/* Check if successfully opened the loader protocol */
if(Status == STATUS_EFI_SUCCESS)
@@ -520,7 +671,7 @@ BlOpenProtocol(OUT PEFI_HANDLE Handle,
*/
XTCDECL
EFI_STATUS
BlOpenProtocolHandle(IN EFI_HANDLE Handle,
Protocol::OpenProtocolHandle(IN EFI_HANDLE Handle,
OUT PVOID *ProtocolHandler,
IN PEFI_GUID ProtocolGuid)
{
@@ -540,7 +691,7 @@ BlOpenProtocolHandle(IN EFI_HANDLE Handle,
*/
XTCDECL
VOID
BlRegisterBootMenu(IN PVOID BootMenuRoutine)
Protocol::RegisterBootMenu(IN PVOID BootMenuRoutine)
{
/* Set boot menu routine */
BlpStatus.BootMenu = (PBL_XT_BOOT_MENU)BootMenuRoutine;
@@ -561,7 +712,7 @@ BlRegisterBootMenu(IN PVOID BootMenuRoutine)
*/
XTCDECL
EFI_STATUS
BlRegisterBootProtocol(IN PCWSTR SystemType,
Protocol::RegisterBootProtocol(IN PCWSTR SystemType,
IN PEFI_GUID BootProtocolGuid)
{
PXTBL_KNOWN_BOOT_PROTOCOL ProtocolEntry;
@@ -586,7 +737,7 @@ BlRegisterBootProtocol(IN PCWSTR SystemType,
}
/* 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)
{
/* Memory allocation failure */
@@ -620,7 +771,7 @@ BlRegisterBootProtocol(IN PCWSTR SystemType,
*/
XTCDECL
EFI_STATUS
BlpGetModuleInformation(IN PWCHAR SectionData,
Protocol::GetModuleInformation(IN PWCHAR SectionData,
IN ULONG SectionSize,
OUT PXTBL_MODULE_INFO ModuleInfo)
{
@@ -636,7 +787,7 @@ BlpGetModuleInformation(IN PWCHAR SectionData,
RTL::LinkedList::InitializeListHead(&ModuleInfo->Dependencies);
/* Get information strings from '.modinfo' section */
Status = BlpGetModuleInfoStrings(SectionData, SectionSize, &Strings, &Count);
Status = GetModuleInfoStrings(SectionData, SectionSize, &Strings, &Count);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to get information strings */
@@ -664,7 +815,7 @@ BlpGetModuleInformation(IN PWCHAR SectionData,
if(RTL::WideString::CompareWideString(Key, L"author", 6) == 0)
{
/* 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)
{
/* Memory allocation failure */
@@ -692,7 +843,7 @@ BlpGetModuleInformation(IN PWCHAR SectionData,
while(Dependency != NULLPTR)
{
/* 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)
{
/* Memory allocation failure */
@@ -739,7 +890,7 @@ BlpGetModuleInformation(IN PWCHAR SectionData,
*/
XTCDECL
EFI_STATUS
BlpGetModuleInfoStrings(IN PWCHAR SectionData,
Protocol::GetModuleInfoStrings(IN PWCHAR SectionData,
IN ULONG SectionSize,
OUT PWCHAR **ModInfo,
OUT PULONG InfoCount)
@@ -801,7 +952,7 @@ BlpGetModuleInfoStrings(IN PWCHAR SectionData,
}
/* 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)
{
/* Failed to allocate memory */
@@ -858,42 +1009,42 @@ BlpGetModuleInfoStrings(IN PWCHAR SectionData,
*/
XTCDECL
EFI_STATUS
BlpInstallXtLoaderProtocol()
Protocol::InstallXtLoaderProtocol()
{
EFI_GUID Guid = XT_BOOT_LOADER_PROTOCOL_GUID;
/* Set all routines available via loader protocol */
BlpLdrProtocol.Boot.FindProtocol = BlFindBootProtocol;
BlpLdrProtocol.Boot.InitializeMenuList = BlInitializeBootMenuList;
BlpLdrProtocol.Boot.InvokeProtocol = BlInvokeBootProtocol;
BlpLdrProtocol.Boot.RegisterMenu = BlRegisterBootMenu;
BlpLdrProtocol.Boot.RegisterProtocol = BlRegisterBootProtocol;
BlpLdrProtocol.BootUtil.GetBooleanParameter = BlGetBooleanParameter;
BlpLdrProtocol.BootUtil.GetTrampolineInformation = AR::ProcSup::GetTrampolineInformation;
BlpLdrProtocol.Config.GetBooleanValue = BlGetConfigBooleanValue;
BlpLdrProtocol.Config.GetBootOptionValue = BlGetBootOptionValue;
BlpLdrProtocol.Config.GetEditableOptions = BlGetEditableOptions;
BlpLdrProtocol.Config.GetValue = BlGetConfigValue;
BlpLdrProtocol.Config.SetBootOptionValue = BlSetBootOptionValue;
BlpLdrProtocol.Console.ClearLine = BlClearConsoleLine;
BlpLdrProtocol.Console.ClearScreen = BlClearConsoleScreen;
BlpLdrProtocol.Console.DisableCursor = BlDisableConsoleCursor;
BlpLdrProtocol.Console.EnableCursor = BlEnableConsoleCursor;
BlpLdrProtocol.Console.Print = BlConsolePrint;
BlpLdrProtocol.Console.QueryMode = BlQueryConsoleMode;
BlpLdrProtocol.Console.ReadKeyStroke = BlReadKeyStroke;
BlpLdrProtocol.Console.ResetInputBuffer = BlResetConsoleInputBuffer;
BlpLdrProtocol.Console.SetAttributes = BlSetConsoleAttributes;
BlpLdrProtocol.Console.SetCursorPosition = BlSetCursorPosition;
BlpLdrProtocol.Console.Write = BlConsoleWrite;
BlpLdrProtocol.Boot.FindProtocol = FindBootProtocol;
BlpLdrProtocol.Boot.InitializeMenuList = XtLoader::InitializeBootMenuList;
BlpLdrProtocol.Boot.InvokeProtocol = InvokeBootProtocol;
BlpLdrProtocol.Boot.RegisterMenu = RegisterBootMenu;
BlpLdrProtocol.Boot.RegisterProtocol = RegisterBootProtocol;
BlpLdrProtocol.BootUtils.GetBooleanParameter = BootUtils::GetBooleanParameter;
BlpLdrProtocol.BootUtils.GetTrampolineInformation = AR::ProcSup::GetTrampolineInformation;
BlpLdrProtocol.Config.GetBooleanValue = Configuration::GetBooleanValue;
BlpLdrProtocol.Config.GetBootOptionValue = Configuration::GetBootOptionValue;
BlpLdrProtocol.Config.GetEditableOptions = Configuration::GetEditableOptions;
BlpLdrProtocol.Config.GetValue = Configuration::GetValue;
BlpLdrProtocol.Config.SetBootOptionValue = Configuration::SetBootOptionValue;
BlpLdrProtocol.Console.ClearLine = Console::ClearLine;
BlpLdrProtocol.Console.ClearScreen = Console::ClearScreen;
BlpLdrProtocol.Console.DisableCursor = Console::DisableCursor;
BlpLdrProtocol.Console.EnableCursor = Console::EnableCursor;
BlpLdrProtocol.Console.Print = Console::Print;
BlpLdrProtocol.Console.QueryMode = Console::QueryMode;
BlpLdrProtocol.Console.ReadKeyStroke = Console::ReadKeyStroke;
BlpLdrProtocol.Console.ResetInputBuffer = Console::ResetInputBuffer;
BlpLdrProtocol.Console.SetAttributes = Console::SetAttributes;
BlpLdrProtocol.Console.SetCursorPosition = Console::SetCursorPosition;
BlpLdrProtocol.Console.Write = Console::Write;
BlpLdrProtocol.Cpu.CpuId = AR::CpuFunc::CpuId;
BlpLdrProtocol.Cpu.ReadControlRegister = AR::CpuFunc::ReadControlRegister;
BlpLdrProtocol.Cpu.ReadModelSpecificRegister = AR::CpuFunc::ReadModelSpecificRegister;
BlpLdrProtocol.Cpu.WriteControlRegister = AR::CpuFunc::WriteControlRegister;
BlpLdrProtocol.Debug.Print = BlDebugPrint;
BlpLdrProtocol.Disk.CloseVolume = BlCloseVolume;
BlpLdrProtocol.Disk.OpenVolume = BlOpenVolume;
BlpLdrProtocol.Disk.ReadFile = BlReadFile;
BlpLdrProtocol.Debug.Print = Debug::Print;
BlpLdrProtocol.Disk.CloseVolume = Volume::CloseVolume;
BlpLdrProtocol.Disk.OpenVolume = Volume::OpenVolume;
BlpLdrProtocol.Disk.ReadFile = Volume::ReadFile;
BlpLdrProtocol.IoPort.Read8 = HL::IoPort::ReadPort8;
BlpLdrProtocol.IoPort.Read16 = HL::IoPort::ReadPort16;
BlpLdrProtocol.IoPort.Read32 = HL::IoPort::ReadPort32;
@@ -904,54 +1055,54 @@ BlpInstallXtLoaderProtocol()
BlpLdrProtocol.LinkedList.InsertHead = RTL::LinkedList::InsertHeadList;
BlpLdrProtocol.LinkedList.InsertTail = RTL::LinkedList::InsertTailList;
BlpLdrProtocol.LinkedList.RemoveEntry = RTL::LinkedList::RemoveEntryList;
BlpLdrProtocol.Memory.AllocatePages = BlAllocateMemoryPages;
BlpLdrProtocol.Memory.AllocatePool = BlAllocateMemoryPool;
BlpLdrProtocol.Memory.BuildPageMap = BlBuildPageMap;
BlpLdrProtocol.Memory.AllocatePages = Memory::AllocatePages;
BlpLdrProtocol.Memory.AllocatePool = Memory::AllocatePool;
BlpLdrProtocol.Memory.BuildPageMap = Memory::BuildPageMap;
BlpLdrProtocol.Memory.CompareMemory = RTL::Memory::CompareMemory;
BlpLdrProtocol.Memory.CopyMemory = RTL::Memory::CopyMemory;
BlpLdrProtocol.Memory.FreePages = BlFreeMemoryPages;
BlpLdrProtocol.Memory.FreePool = BlFreeMemoryPool;
BlpLdrProtocol.Memory.GetMappingsCount = BlGetMappingsCount;
BlpLdrProtocol.Memory.GetMemoryMap = BlGetMemoryMap;
BlpLdrProtocol.Memory.GetVirtualAddress = BlGetVirtualAddress;
BlpLdrProtocol.Memory.InitializePageMap = BlInitializePageMap;
BlpLdrProtocol.Memory.MapEfiMemory = BlMapEfiMemory;
BlpLdrProtocol.Memory.MapPage = BlMapPage;
BlpLdrProtocol.Memory.MapVirtualMemory = BlMapVirtualMemory;
BlpLdrProtocol.Memory.FreePages = Memory::FreePages;
BlpLdrProtocol.Memory.FreePool = Memory::FreePool;
BlpLdrProtocol.Memory.GetMappingsCount = Memory::GetMappingsCount;
BlpLdrProtocol.Memory.GetMemoryMap = Memory::GetMemoryMap;
BlpLdrProtocol.Memory.GetVirtualAddress = Memory::GetVirtualAddress;
BlpLdrProtocol.Memory.InitializePageMap = Memory::InitializePageMap;
BlpLdrProtocol.Memory.MapEfiMemory = Memory::MapEfiMemory;
BlpLdrProtocol.Memory.MapPage = Memory::MapPage;
BlpLdrProtocol.Memory.MapVirtualMemory = Memory::MapVirtualMemory;
BlpLdrProtocol.Memory.MoveMemory = RTL::Memory::MoveMemory;
BlpLdrProtocol.Memory.PhysicalAddressToVirtual = BlPhysicalAddressToVirtual;
BlpLdrProtocol.Memory.PhysicalListToVirtual = BlPhysicalListToVirtual;
BlpLdrProtocol.Memory.PhysicalAddressToVirtual = Memory::PhysicalAddressToVirtual;
BlpLdrProtocol.Memory.PhysicalListToVirtual = Memory::PhysicalListToVirtual;
BlpLdrProtocol.Memory.SetMemory = RTL::Memory::SetMemory;
BlpLdrProtocol.Memory.ZeroMemory = RTL::Memory::ZeroMemory;
BlpLdrProtocol.Protocol.Close = BlCloseProtocol;
BlpLdrProtocol.Protocol.GetModulesList = BlGetModulesList;
BlpLdrProtocol.Protocol.Install = BlInstallProtocol;
BlpLdrProtocol.Protocol.LocateHandles = BlLocateProtocolHandles;
BlpLdrProtocol.Protocol.Open = BlOpenProtocol;
BlpLdrProtocol.Protocol.OpenHandle = BlOpenProtocolHandle;
BlpLdrProtocol.Protocol.Close = CloseProtocol;
BlpLdrProtocol.Protocol.GetModulesList = GetModulesList;
BlpLdrProtocol.Protocol.Install = InstallProtocol;
BlpLdrProtocol.Protocol.LocateHandles = LocateProtocolHandles;
BlpLdrProtocol.Protocol.Open = OpenProtocol;
BlpLdrProtocol.Protocol.OpenHandle = OpenProtocolHandle;
BlpLdrProtocol.String.Compare = RTL::String::CompareString;
BlpLdrProtocol.String.Length = RTL::String::StringLength;
BlpLdrProtocol.String.ToWideString = RTL::String::StringToWideString;
BlpLdrProtocol.String.Trim = RTL::String::TrimString;
BlpLdrProtocol.Tui.DisplayErrorDialog = BlDisplayErrorDialog;
BlpLdrProtocol.Tui.DisplayInfoDialog = BlDisplayInfoDialog;
BlpLdrProtocol.Tui.DisplayInputDialog = BlDisplayInputDialog;
BlpLdrProtocol.Tui.DisplayProgressDialog = BlDisplayProgressDialog;
BlpLdrProtocol.Tui.UpdateProgressBar = BlUpdateProgressBar;
BlpLdrProtocol.Util.EnterFirmwareSetup = BlEnterFirmwareSetup;
BlpLdrProtocol.Util.ExitBootServices = BlExitBootServices;
BlpLdrProtocol.Util.GetConfigurationTable = BlGetConfigurationTable;
BlpLdrProtocol.Util.GetEfiVariable = BlGetEfiVariable;
BlpLdrProtocol.Util.GetRandomValue = BlGetRandomValue;
BlpLdrProtocol.Util.GetSecureBootStatus = BlGetSecureBootStatus;
BlpLdrProtocol.Util.InitializeEntropy = BlInitializeEntropy;
BlpLdrProtocol.Util.LoadEfiImage = BlLoadEfiImage;
BlpLdrProtocol.Util.RebootSystem = BlRebootSystem;
BlpLdrProtocol.Util.SetEfiVariable = BlSetEfiVariable;
BlpLdrProtocol.Util.ShutdownSystem = BlShutdownSystem;
BlpLdrProtocol.Util.SleepExecution = BlSleepExecution;
BlpLdrProtocol.Util.StartEfiImage = BlStartEfiImage;
BlpLdrProtocol.Util.WaitForEfiEvent = BlWaitForEfiEvent;
BlpLdrProtocol.Tui.DisplayErrorDialog = TextUi::DisplayErrorDialog;
BlpLdrProtocol.Tui.DisplayInfoDialog = TextUi::DisplayInfoDialog;
BlpLdrProtocol.Tui.DisplayInputDialog = TextUi::DisplayInputDialog;
BlpLdrProtocol.Tui.DisplayProgressDialog = TextUi::DisplayProgressDialog;
BlpLdrProtocol.Tui.UpdateProgressBar = TextUi::UpdateProgressBar;
BlpLdrProtocol.Utils.EnterFirmwareSetup = EfiUtils::EnterFirmwareSetup;
BlpLdrProtocol.Utils.ExitBootServices = EfiUtils::ExitBootServices;
BlpLdrProtocol.Utils.GetConfigurationTable = EfiUtils::GetConfigurationTable;
BlpLdrProtocol.Utils.GetEfiVariable = EfiUtils::GetEfiVariable;
BlpLdrProtocol.Utils.GetRandomValue = EfiUtils::GetRandomValue;
BlpLdrProtocol.Utils.GetSecureBootStatus = EfiUtils::GetSecureBootStatus;
BlpLdrProtocol.Utils.InitializeEntropy = EfiUtils::InitializeEntropy;
BlpLdrProtocol.Utils.LoadEfiImage = EfiUtils::LoadEfiImage;
BlpLdrProtocol.Utils.RebootSystem = EfiUtils::RebootSystem;
BlpLdrProtocol.Utils.SetEfiVariable = EfiUtils::SetEfiVariable;
BlpLdrProtocol.Utils.ShutdownSystem = EfiUtils::ShutdownSystem;
BlpLdrProtocol.Utils.SleepExecution = EfiUtils::SleepExecution;
BlpLdrProtocol.Utils.StartEfiImage = EfiUtils::StartEfiImage;
BlpLdrProtocol.Utils.WaitForEfiEvent = EfiUtils::WaitForEfiEvent;
BlpLdrProtocol.WideString.Compare = RTL::WideString::CompareWideString;
BlpLdrProtocol.WideString.CompareInsensitive = RTL::WideString::CompareWideStringInsensitive;
BlpLdrProtocol.WideString.Concatenate = RTL::WideString::ConcatenateWideString;
@@ -960,6 +1111,6 @@ BlpInstallXtLoaderProtocol()
BlpLdrProtocol.WideString.Tokenize = RTL::WideString::TokenizeWideString;
/* Register XTLDR loader protocol */
BlDebugPrint(L"Registering XT loader protocol\n");
return BlInstallProtocol(&BlpLdrProtocol, &Guid);
Debug::Print(L"Registering XT loader protocol\n");
return InstallProtocol(&BlpLdrProtocol, &Guid);
}

View File

@@ -18,13 +18,13 @@
*/
XTCDECL
VOID
BlStartLoaderShell()
Shell::StartLoaderShell()
{
/* Initialize console */
BlInitializeConsole();
Console::InitializeConsole();
/* Print prompt */
BlpPrintShellPrompt();
PrintPrompt();
for(;;);
}
@@ -37,14 +37,14 @@ BlStartLoaderShell()
*/
XTCDECL
VOID
BlpPrintShellPrompt()
Shell::PrintPrompt()
{
/* Set prompt color */
BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_YELLOW);
Console::SetAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_YELLOW);
/* Print prompt */
BlConsolePrint(L"XTLDR> ");
Console::Print(L"XTLDR> ");
/* 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
EFI_STATUS
BlCloseVolume(IN PEFI_HANDLE VolumeHandle)
Volume::CloseVolume(IN PEFI_HANDLE VolumeHandle)
{
EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
@@ -46,7 +46,7 @@ BlCloseVolume(IN PEFI_HANDLE VolumeHandle)
*/
XTCDECL
EFI_STATUS
BlEnumerateBlockDevices()
Volume::EnumerateBlockDevices()
{
EFI_GUID LoadedImageProtocolGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
EFI_GUID BlockIoGuid = EFI_BLOCK_IO_PROTOCOL_GUID;
@@ -72,7 +72,7 @@ BlEnumerateBlockDevices()
if(Status != STATUS_EFI_SUCCESS)
{
/* 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;
}
@@ -84,10 +84,10 @@ BlEnumerateBlockDevices()
RTL::LinkedList::InitializeListHead(&EfiBlockDevices);
/* Discover EFI block devices and store them in linked list */
Status = BlpDiscoverEfiBlockDevices(&BlockDevices);
Status = DiscoverEfiBlockDevices(&BlockDevices);
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;
}
@@ -100,11 +100,11 @@ BlEnumerateBlockDevices()
PartitionGuid = NULLPTR;
/* Find last node */
Status = BlpFindLastBlockDeviceNode(BlockDeviceData->DevicePath, &LastNode);
Status = FindLastBlockDeviceNode(BlockDeviceData->DevicePath, &LastNode);
if(Status != STATUS_EFI_SUCCESS)
{
/* 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;
continue;
}
@@ -113,10 +113,10 @@ BlEnumerateBlockDevices()
DriveType = XTBL_BOOT_DEVICE_UNKNOWN;
/* 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 */
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;
continue;
}
@@ -125,7 +125,7 @@ BlEnumerateBlockDevices()
if(!BlockDeviceData->BlockIo->Media)
{
/* 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;
continue;
}
@@ -144,7 +144,7 @@ BlEnumerateBlockDevices()
PartitionNumber = 0;
/* 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);
}
}
@@ -159,7 +159,7 @@ BlEnumerateBlockDevices()
PartitionNumber = 0;
/* 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);
}
else if(LastNode->Type == EFI_MEDIA_DEVICE_PATH && LastNode->SubType == EFI_MEDIA_HARDDRIVE_DP)
@@ -175,7 +175,7 @@ BlEnumerateBlockDevices()
if(BootDeviceHandle != NULLPTR)
{
/* Allocate memory for device path */
DevicePath = BlpDuplicateDevicePath(BlockDeviceData->DevicePath);
DevicePath = DuplicateDevicePath(BlockDeviceData->DevicePath);
if(DevicePath != NULLPTR)
{
/* Check if this is the boot device */
@@ -190,7 +190,7 @@ BlEnumerateBlockDevices()
}
/* 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",
DriveNumber, PartitionNumber, HDPath->MBRType,
PartitionGuid, HDPath->PartitionSize * Media->BlockSize,
@@ -204,7 +204,7 @@ BlEnumerateBlockDevices()
PartitionNumber = 0;
/* 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);
}
@@ -212,15 +212,15 @@ BlEnumerateBlockDevices()
if(DriveType != XTBL_BOOT_DEVICE_UNKNOWN)
{
/* 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)
{
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;
}
/* Initialize block device */
BlockDevice->DevicePath = BlpDuplicateDevicePath(BlockDeviceData->DevicePath);
BlockDevice->DevicePath = DuplicateDevicePath(BlockDeviceData->DevicePath);
BlockDevice->DriveType = DriveType;
BlockDevice->DriveNumber = DriveNumber;
BlockDevice->PartitionNumber = PartitionNumber;
@@ -256,7 +256,7 @@ BlEnumerateBlockDevices()
*/
XTCDECL
EFI_STATUS
BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle,
Volume::FindDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle,
IN CONST PWCHAR FileSystemPath,
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);
/* 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);
if(Status != STATUS_EFI_SUCCESS)
{
@@ -337,7 +337,7 @@ BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle,
*/
XTCDECL
EFI_STATUS
BlGetEfiPath(IN PWCHAR SystemPath,
Volume::GetEfiPath(IN PWCHAR SystemPath,
OUT PWCHAR *EfiPath)
{
SIZE_T Index, PathLength;
@@ -347,11 +347,11 @@ BlGetEfiPath(IN PWCHAR SystemPath,
PathLength = RTL::WideString::WideStringLength(SystemPath, 0);
/* 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)
{
/* 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;
}
@@ -390,7 +390,7 @@ BlGetEfiPath(IN PWCHAR SystemPath,
*/
XTCDECL
EFI_STATUS
BlGetVolumeDevicePath(IN PWCHAR SystemPath,
Volume::GetDevicePath(IN PWCHAR SystemPath,
OUT PEFI_DEVICE_PATH_PROTOCOL *DevicePath,
OUT PWCHAR *ArcName,
OUT PWCHAR *Path)
@@ -429,13 +429,13 @@ BlGetVolumeDevicePath(IN PWCHAR SystemPath,
if(PathLength == GUID_STRING_LENGTH)
{
/* 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;
}
else if(PathLength == PARTUUID_STRING_LENGTH)
{
/* 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;
}
else
@@ -447,14 +447,14 @@ BlGetVolumeDevicePath(IN PWCHAR SystemPath,
else
{
/* 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 */
if(Status != STATUS_EFI_SUCCESS)
{
/* 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;
}
@@ -492,7 +492,7 @@ BlGetVolumeDevicePath(IN PWCHAR SystemPath,
if(*DevicePath == NULLPTR)
{
/* 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);
return STATUS_EFI_NOT_FOUND;
}
@@ -519,7 +519,7 @@ BlGetVolumeDevicePath(IN PWCHAR SystemPath,
*/
XTCDECL
EFI_STATUS
BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
Volume::OpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
OUT PEFI_HANDLE DiskHandle,
OUT PEFI_FILE_HANDLE *FsHandle)
{
@@ -563,7 +563,7 @@ BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to open the filesystem protocol, close volume */
BlCloseVolume(DiskHandle);
CloseVolume(DiskHandle);
return Status;
}
@@ -572,7 +572,7 @@ BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to open the filesystem, close volume */
BlCloseVolume(DiskHandle);
CloseVolume(DiskHandle);
return Status;
}
@@ -601,7 +601,7 @@ BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
*/
XTCDECL
EFI_STATUS
BlReadFile(IN PEFI_FILE_HANDLE DirHandle,
Volume::ReadFile(IN PEFI_FILE_HANDLE DirHandle,
IN PCWSTR FileName,
OUT PVOID *FileData,
OUT PSIZE_T FileSize)
@@ -626,7 +626,7 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle,
ReadSize = sizeof(EFI_FILE_INFO) + 32;
/* Allocate necessary amount of memory */
Status = BlAllocateMemoryPool(ReadSize, (PVOID *)&FileInfo);
Status = Memory::AllocatePool(ReadSize, (PVOID *)&FileInfo);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure */
@@ -639,8 +639,8 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle,
if(Status == STATUS_EFI_BUFFER_TOO_SMALL)
{
/* Buffer is too small, but EFI tells the required size, so reallocate */
BlFreeMemoryPool(&FileInfo);
Status = BlAllocateMemoryPool(ReadSize, (PVOID *)&FileInfo);
Memory::FreePool(&FileInfo);
Status = Memory::AllocatePool(ReadSize, (PVOID *)&FileInfo);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure */
@@ -657,7 +657,7 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle,
{
/* Unable to get file information */
FileHandle->Close(FileHandle);
BlFreeMemoryPool(&FileInfo);
Memory::FreePool(&FileInfo);
return Status;
}
@@ -666,12 +666,12 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle,
Pages = EFI_SIZE_TO_PAGES(FileInfo->FileSize);
/* Allocate pages */
Status = BlAllocateMemoryPages(AllocateAnyPages, Pages, &Address);
Status = Memory::AllocatePages(AllocateAnyPages, Pages, &Address);
if(Status != STATUS_EFI_SUCCESS)
{
/* Pages allocation failure */
FileHandle->Close(FileHandle);
BlFreeMemoryPool(&FileInfo);
Memory::FreePool(&FileInfo);
return Status;
}
@@ -686,14 +686,14 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle,
{
/* Failed to read data */
FileHandle->Close(FileHandle);
BlFreeMemoryPool(&FileInfo);
BlFreeMemoryPages(Pages, (EFI_PHYSICAL_ADDRESS)(UINT_PTR)*FileData);
Memory::FreePool(&FileInfo);
Memory::FreePages(Pages, (EFI_PHYSICAL_ADDRESS)(UINT_PTR)*FileData);
return Status;
}
/* Close handle and free memory */
FileHandle->Close(FileHandle);
BlFreeMemoryPool(FileInfo);
Memory::FreePool(FileInfo);
/* Return success */
return STATUS_EFI_SUCCESS;
@@ -711,7 +711,7 @@ BlReadFile(IN PEFI_FILE_HANDLE DirHandle,
*/
XTCDECL
EFI_STATUS
BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices)
Volume::DiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices)
{
EFI_GUID DevicePathGuid = EFI_DEVICE_PATH_PROTOCOL_GUID;
EFI_GUID IoGuid = EFI_BLOCK_IO_PROTOCOL_GUID;
@@ -723,11 +723,11 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices)
EFI_STATUS Status;
/* 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)
{
/* 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;
}
@@ -735,15 +735,15 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices)
for(Index = 0; Index < HandlesCount; Index++)
{
/* 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 */
Io = NULLPTR;
Status = BlOpenProtocolHandle(Handles[Index], (PVOID *)&Io, &IoGuid);
Status = Protocol::OpenProtocolHandle(Handles[Index], (PVOID *)&Io, &IoGuid);
if(Status != STATUS_EFI_SUCCESS || Io == NULLPTR)
{
/* 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;
}
@@ -751,7 +751,7 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices)
if(Io->Media && Io->Media->BlockSize == 1 && Io->Media->MediaId == 0x69505845U)
{
/* 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;
}
@@ -761,17 +761,17 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices)
if(Status != STATUS_EFI_SUCCESS || DevicePath == NULLPTR)
{
/* 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);
continue;
}
/* Allocate memory for block device */
Status = BlAllocateMemoryPool(sizeof(*BlockDevice), (PVOID *)&BlockDevice);
Status = Memory::AllocatePool(sizeof(*BlockDevice), (PVOID *)&BlockDevice);
if(Status != STATUS_EFI_SUCCESS)
{
/* 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], &IoGuid, EfiImageHandle, NULLPTR);
return Status;
@@ -784,7 +784,7 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices)
}
/* Free handles buffer */
BlFreeMemoryPool(Handles);
Memory::FreePool(Handles);
/* Return success */
return STATUS_EFI_SUCCESS;
@@ -814,7 +814,7 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices)
*/
XTCDECL
EFI_STATUS
BlpDissectVolumeArcPath(IN PWCHAR SystemPath,
Volume::DissectArcPath(IN PWCHAR SystemPath,
OUT PWCHAR *ArcName,
OUT PWCHAR *Path,
OUT PUSHORT DriveType,
@@ -954,7 +954,7 @@ BlpDissectVolumeArcPath(IN PWCHAR SystemPath,
/* Store ARC name if possible */
if(ArcName)
{
BlAllocateMemoryPool(ArcLength * sizeof(WCHAR), (PVOID *)&LocalArcName);
Memory::AllocatePool(ArcLength * sizeof(WCHAR), (PVOID *)&LocalArcName);
RTL::Memory::CopyMemory(LocalArcName, SystemPath, ArcLength * sizeof(WCHAR));
LocalArcName[ArcLength] = '\0';
*ArcName = LocalArcName;
@@ -976,7 +976,7 @@ BlpDissectVolumeArcPath(IN PWCHAR SystemPath,
*/
XTCDECL
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 DevicePathClone;
@@ -1012,11 +1012,11 @@ BlpDuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath)
}
/* Allocate memory for the new device path */
Status = BlAllocateMemoryPool(Length, (PVOID *)&DevicePathClone);
Status = Memory::AllocatePool(Length, (PVOID *)&DevicePathClone);
if(Status != STATUS_EFI_SUCCESS)
{
/* 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;
}
@@ -1042,7 +1042,7 @@ BlpDuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath)
*/
XTCDECL
EFI_STATUS
BlpFindLastBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
Volume::FindLastBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
OUT PEFI_DEVICE_PATH_PROTOCOL *LastNode)
{
PEFI_DEVICE_PATH_PROTOCOL EndNode, NextNode;
@@ -1088,7 +1088,7 @@ BlpFindLastBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
*/
XTCDECL
BOOLEAN
BlpFindParentBlockDevice(IN PLIST_ENTRY BlockDevices,
Volume::FindParentBlockDevice(IN PLIST_ENTRY BlockDevices,
IN PEFI_BLOCK_DEVICE_DATA ChildNode,
OUT PEFI_BLOCK_DEVICE_DATA *ParentNode)
{

View File

@@ -18,7 +18,7 @@
*/
XTCDECL
VOID
BlInitializeBootLoader()
XtLoader::InitializeBootLoader()
{
EFI_GUID LipGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
PEFI_LOADED_IMAGE_PROTOCOL LoadedImage;
@@ -29,10 +29,10 @@ BlInitializeBootLoader()
BlpStatus.BootServices = TRUE;
/* Initialize console */
BlInitializeConsole();
Console::InitializeConsole();
/* 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 */
RTL::LinkedList::InitializeListHead(&BlpBootProtocols);
@@ -40,10 +40,10 @@ BlInitializeBootLoader()
RTL::LinkedList::InitializeListHead(&BlpLoadedModules);
/* Store SecureBoot status */
BlpStatus.SecureBoot = BlGetSecureBootStatus();
BlpStatus.SecureBoot = EfiUtils::GetSecureBootStatus();
/* Attempt to open EFI LoadedImage protocol */
Status = BlOpenProtocol(&Handle, (PVOID *)&LoadedImage, &LipGuid);
Status = Protocol::OpenProtocol(&Handle, (PVOID *)&LoadedImage, &LipGuid);
if(Status == STATUS_EFI_SUCCESS)
{
/* Store boot loader image base and size */
@@ -54,7 +54,7 @@ BlInitializeBootLoader()
if(DEBUG)
{
/* 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"Image Base Address : %P\n"
L"Image Base Size : 0x%lX\n"
@@ -66,11 +66,11 @@ BlInitializeBootLoader()
LoadedImage->ImageSize,
LoadedImage->Revision,
BlpStatus.SecureBoot);
BlSleepExecution(3000);
EfiUtils::SleepExecution(3000);
}
/* Close EFI LoadedImage protocol */
BlCloseProtocol(&Handle, &LipGuid);
Protocol::CloseProtocol(&Handle, &LipGuid);
}
}
@@ -92,7 +92,7 @@ BlInitializeBootLoader()
*/
XTCDECL
EFI_STATUS
BlInitializeBootMenuList(IN ULONG MaxNameLength,
XtLoader::InitializeBootMenuList(IN ULONG MaxNameLength,
OUT PXTBL_BOOTMENU_ITEM *MenuEntries,
OUT PULONG EntriesCount,
OUT PULONG DefaultId)
@@ -111,13 +111,13 @@ BlInitializeBootMenuList(IN ULONG MaxNameLength,
NumberOfEntries = 0;
/* Get default menu entry from configuration */
BlGetConfigValue(L"DEFAULT", &DefaultMenuEntry);
Configuration::GetValue(L"DEFAULT", &DefaultMenuEntry);
/* 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 */
Status = BlGetEfiVariable(&VendorGuid, L"XtLdrLastBootOS", (PVOID*)&LastBooted);
Status = EfiUtils::GetEfiVariable(&VendorGuid, L"XtLdrLastBootOS", (PVOID*)&LastBooted);
if(Status == STATUS_EFI_SUCCESS)
{
/* 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 */
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)
{
/* Memory allocation failure */
@@ -189,7 +189,7 @@ BlInitializeBootMenuList(IN ULONG MaxNameLength,
if(NameLength > MaxNameLength)
{
/* 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)
{
/* Memory allocation failure */
@@ -224,157 +224,6 @@ BlInitializeBootMenuList(IN ULONG MaxNameLength,
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.
*
@@ -401,43 +250,43 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle,
EfiSystemTable = SystemTable;
/* Initialize XTLDR and */
BlInitializeBootLoader();
XtLoader::InitializeBootLoader();
/* Parse configuration options passed from UEFI shell */
Status = BlpParseCommandLine();
Status = Configuration::ParseCommandLine();
if(Status != STATUS_EFI_SUCCESS)
{
/* 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 */
if(DEBUG)
{
Status = BlpInitializeDebugConsole();
Status = Debug::InitializeDebugConsole();
if(Status != STATUS_EFI_SUCCESS)
{
/* 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 */
Status = BlpLoadConfiguration();
Status = Configuration::LoadConfiguration();
if(Status != STATUS_EFI_SUCCESS)
{
/* 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 */
if(DEBUG)
{
Status = BlpInitializeDebugConsole();
Status = Debug::InitializeDebugConsole();
if(Status != STATUS_EFI_SUCCESS)
{
/* 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)
{
/* 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 */
Status = BlpInstallXtLoaderProtocol();
Status = Protocol::InstallXtLoaderProtocol();
if(Status != STATUS_EFI_SUCCESS)
{
/* 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;
}
/* Load all necessary modules */
BlGetConfigValue(L"MODULES", &Modules);
Status = BlLoadModules(Modules);
Configuration::GetValue(L"MODULES", &Modules);
Status = Protocol::LoadModules(Modules);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to load modules */
BlDebugPrint(L"ERROR: Failed to load XTLDR modules (Status Code: 0x%zX)\n", Status);
BlDisplayErrorDialog(L"XTLDR", L"Failed to load some XTLDR modules.");
Debug::Print(L"ERROR: Failed to load XTLDR modules (Status Code: 0x%zX)\n", Status);
TextUi::DisplayErrorDialog(L"XTLDR", L"Failed to load some XTLDR modules.");
}
/* Discover and enumerate EFI block devices */
Status = BlEnumerateBlockDevices();
Status = Volume::EnumerateBlockDevices();
if(Status != STATUS_EFI_SUCCESS)
{
/* 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;
}
@@ -489,11 +338,11 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle,
else
{
/* Display default boot menu */
BlDisplayBootMenu();
TextUi::DisplayBootMenu();
}
/* Fallback to shell, if boot menu returned */
BlStartLoaderShell();
Shell::StartLoaderShell();
}
/* This point should be never reached, if this happen return error code */