forked from reactos/reactos
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[UEFI] Enable UEFI boot for i386 and amd64
Co-authored-by: Stanislav Motylkov <[email protected]> Co-authored-by: Hermès BÉLUSCA - MAÏTO <[email protected]>
- Loading branch information
1 parent
0c164f0
commit 2f4f722
Showing
9 changed files
with
409 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
#include <asm.inc> | ||
#include <arch/pc/x86common.h> | ||
#include <arch/pc/pcbios.h> | ||
|
||
EXTERN UefiServiceStack:QWORD | ||
EXTERN BasicStack:QWORD | ||
EXTERN ExecuteLoaderCleanly:PROC | ||
EXTERN UefiExitBootServices:PROC | ||
|
||
.code64 | ||
|
||
// void _exituefi(VOID) | ||
PUBLIC _exituefi | ||
_exituefi: | ||
/* Save non-volatile registers */ | ||
push rbp | ||
push rsi | ||
push rdi | ||
push rbx | ||
|
||
|
||
/* Save the old stack */ | ||
mov rbx, rsp | ||
|
||
/* Load the new stack */ | ||
xor rbp, rbp | ||
//mov rsp, qword ptr UefiServiceStack[rip] | ||
|
||
/* Call the entry routine, passing the parameters */ | ||
//mov rax, UefiExitBootServices[rip] | ||
call rax | ||
|
||
/* Retore old stack */ | ||
mov rsp, rbx | ||
|
||
/* Retore non-volatiles */ | ||
pop rbx | ||
pop rdi | ||
pop rsi | ||
pop rbp | ||
|
||
/* All done */ | ||
ret | ||
|
||
// void _changestack(VOID) | ||
PUBLIC _changestack | ||
_changestack: | ||
mov rax, rsp | ||
// mov rsp, BasicStack[rip] | ||
push rax | ||
// call ExecuteLoaderCleanly[rip] | ||
ret | ||
|
||
// void _changegdt(VOID) | ||
PUBLIC _changegdt | ||
_changegdt: | ||
#ifdef _USE_ML | ||
lgdt fword ptr [_gdtptr] | ||
#else | ||
lgdt cs:[_gdtptr] | ||
#endif | ||
ret | ||
|
||
.align 8 | ||
gdt: | ||
.word HEX(0000), HEX(0000), HEX(0000), HEX(0000) /* 00: NULL descriptor */ | ||
.word HEX(0000), HEX(0000), HEX(0000), HEX(0000) /* 08: */ | ||
.word HEX(0000), HEX(0000), HEX(9800), HEX(0020) /* 10: long mode CS */ | ||
.word HEX(FFFF), HEX(0000), HEX(F300), HEX(00CF) /* 18: long mode DS */ | ||
.word HEX(FFFF), HEX(0000), HEX(9E00), HEX(0000) /* 20: 16-bit real mode CS */ | ||
.word HEX(FFFF), HEX(0000), HEX(9200), HEX(0000) /* 28: 16-bit real mode DS */ | ||
.word HEX(FFFF), HEX(0000), HEX(9B00), HEX(00CF) /* 30: compat mode CS */ | ||
|
||
/* GDT table pointer */ | ||
_gdtptr: | ||
.word HEX(37) /* Limit */ | ||
#ifdef _USE_ML | ||
.quad gdt /* Base Address */ | ||
#else | ||
.long gdt, 0 /* Base Address */ | ||
#endif | ||
|
||
END |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
#include <asm.inc> | ||
#include <arch/pc/x86common.h> | ||
#include <arch/pc/pcbios.h> | ||
PUBLIC _gdtptr | ||
PUBLIC _i386idtptr | ||
PUBLIC __changestack | ||
PUBLIC __changegdt | ||
EXTERN _UefiServiceStack:DWORD | ||
EXTERN _i386Idt:DWORD | ||
EXTERN _ExecuteLoaderCleanly:PROC | ||
EXTERN _UefiExitBootServices:PROC | ||
EXTERN _BasicStack:DWORD | ||
.code32 | ||
|
||
// void __exituefi(VOID) | ||
PUBLIC __exituefi | ||
__exituefi: | ||
push ebp | ||
push esi | ||
push edi | ||
push ebx | ||
|
||
/* Save the old stack */ | ||
mov ebx, esp | ||
|
||
/* Load the new stack */ | ||
xor ebp, ebp | ||
mov esp, _UefiServiceStack | ||
|
||
/* Call the entry routine, passing the parameters */ | ||
call _UefiExitBootServices | ||
|
||
/* Retore old stack */ | ||
mov esp, ebx | ||
|
||
/* Retore non-volatiles */ | ||
pop ebx | ||
pop edi | ||
pop esi | ||
pop ebp | ||
|
||
|
||
/* All done */ | ||
ret | ||
|
||
// void __reloadsegment(VOID) | ||
PUBLIC __changestack | ||
__changestack: | ||
mov eax, esp | ||
mov esp, _BasicStack | ||
push eax | ||
call _ExecuteLoaderCleanly | ||
ret | ||
|
||
|
||
PUBLIC __changegdt | ||
__changegdt: | ||
#ifdef _USE_ML | ||
lgdt fword ptr [_gdtptr] | ||
#else | ||
lgdt cs:[_gdtptr] | ||
#endif | ||
/* Load the IDT */ | ||
#ifdef _USE_ML | ||
lidt fword ptr ds:[_i386idtptr] | ||
#else | ||
lidt _i386idtptr | ||
#endif | ||
ret | ||
|
||
.align 4 /* force 4-byte alignment */ | ||
gdt: | ||
/* NULL Descriptor */ | ||
.word HEX(0000) | ||
.word HEX(0000) | ||
.word HEX(0000) | ||
.word HEX(0000) | ||
|
||
/* 32-bit flat CS */ | ||
.word HEX(FFFF) | ||
.word HEX(0000) | ||
.word HEX(9A00) | ||
.word HEX(00CF) | ||
|
||
/* 32-bit flat DS */ | ||
.word HEX(FFFF) | ||
.word HEX(0000) | ||
.word HEX(9200) | ||
.word HEX(00CF) | ||
|
||
/* 16-bit real mode CS */ | ||
.word HEX(FFFF) | ||
.word HEX(0000) | ||
.word HEX(9E00) | ||
.word HEX(0000) | ||
|
||
/* 16-bit real mode DS */ | ||
.word HEX(FFFF) | ||
.word HEX(0000) | ||
.word HEX(9200) | ||
.word HEX(0000) | ||
|
||
/* GDT table pointer */ | ||
_gdtptr: | ||
.word HEX(27) /* Limit */ | ||
.long gdt, 0 /* Base Address */ | ||
|
||
_i386idtptr: | ||
.word 255 /* Limit */ | ||
.long _i386Idt /* Base Address */ | ||
END |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
/* | ||
* PROJECT: FreeLoader UEFI Support | ||
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) | ||
* PURPOSE: Hardware detection routines | ||
* COPYRIGHT: Copyright 2022 Justin Miller <[email protected]> | ||
*/ | ||
|
||
/* INCLUDES ******************************************************************/ | ||
|
||
#include <uefildr.h> | ||
|
||
#include <debug.h> | ||
DBG_DEFAULT_CHANNEL(WARNING); | ||
|
||
/* GLOBALS *******************************************************************/ | ||
|
||
extern EFI_SYSTEM_TABLE * GlobalSystemTable; | ||
extern EFI_HANDLE GlobalImageHandle; | ||
extern UCHAR PcBiosDiskCount; | ||
extern EFI_MEMORY_DESCRIPTOR* EfiMemoryMap; | ||
extern UINT32 FreeldrDescCount; | ||
|
||
BOOLEAN AcpiPresent = FALSE; | ||
|
||
/* FUNCTIONS *****************************************************************/ | ||
|
||
static | ||
PRSDP_DESCRIPTOR | ||
FindAcpiBios(VOID) | ||
{ | ||
UINTN i; | ||
RSDP_DESCRIPTOR* rsdp = NULL; | ||
EFI_GUID acpi2_guid = EFI_ACPI_20_TABLE_GUID; | ||
|
||
for (i = 0; i < GlobalSystemTable->NumberOfTableEntries; i++) | ||
{ | ||
if (!memcmp(&GlobalSystemTable->ConfigurationTable[i].VendorGuid, &acpi2_guid, sizeof(acpi2_guid))) | ||
{ | ||
rsdp = (RSDP_DESCRIPTOR*)GlobalSystemTable->ConfigurationTable[i].VendorTable; | ||
break; | ||
} | ||
} | ||
|
||
return rsdp; | ||
} | ||
|
||
VOID | ||
DetectAcpiBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber) | ||
{ | ||
PCONFIGURATION_COMPONENT_DATA BiosKey; | ||
PCM_PARTIAL_RESOURCE_LIST PartialResourceList; | ||
PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor; | ||
PRSDP_DESCRIPTOR Rsdp; | ||
PACPI_BIOS_DATA AcpiBiosData; | ||
ULONG TableSize; | ||
|
||
Rsdp = FindAcpiBios(); | ||
|
||
if (Rsdp) | ||
{ | ||
/* Set up the flag in the loader block */ | ||
AcpiPresent = TRUE; | ||
|
||
/* Calculate the table size */ | ||
TableSize = FreeldrDescCount * sizeof(BIOS_MEMORY_MAP) + | ||
sizeof(ACPI_BIOS_DATA) - sizeof(BIOS_MEMORY_MAP); | ||
|
||
/* Set 'Configuration Data' value */ | ||
PartialResourceList = FrLdrHeapAlloc(sizeof(CM_PARTIAL_RESOURCE_LIST) + | ||
TableSize, TAG_HW_RESOURCE_LIST); | ||
if (PartialResourceList == NULL) | ||
{ | ||
ERR("Failed to allocate resource descriptor\n"); | ||
return; | ||
} | ||
|
||
RtlZeroMemory(PartialResourceList, sizeof(CM_PARTIAL_RESOURCE_LIST) + TableSize); | ||
PartialResourceList->Version = 0; | ||
PartialResourceList->Revision = 0; | ||
PartialResourceList->Count = 1; | ||
|
||
PartialDescriptor = &PartialResourceList->PartialDescriptors[0]; | ||
PartialDescriptor->Type = CmResourceTypeDeviceSpecific; | ||
PartialDescriptor->ShareDisposition = CmResourceShareUndetermined; | ||
PartialDescriptor->u.DeviceSpecificData.DataSize = TableSize; | ||
|
||
/* Fill the table */ | ||
AcpiBiosData = (PACPI_BIOS_DATA)&PartialResourceList->PartialDescriptors[1]; | ||
|
||
if (Rsdp->revision > 0) | ||
{ | ||
TRACE("ACPI >1.0, using XSDT address\n"); | ||
AcpiBiosData->RSDTAddress.QuadPart = Rsdp->xsdt_physical_address; | ||
} | ||
else | ||
{ | ||
TRACE("ACPI 1.0, using RSDT address\n"); | ||
AcpiBiosData->RSDTAddress.LowPart = Rsdp->rsdt_physical_address; | ||
} | ||
|
||
AcpiBiosData->Count = FreeldrDescCount; | ||
memcpy(AcpiBiosData->MemoryMap, EfiMemoryMap, | ||
FreeldrDescCount * sizeof(BIOS_MEMORY_MAP)); | ||
|
||
TRACE("RSDT %p, data size %x\n", Rsdp->rsdt_physical_address, | ||
TableSize); | ||
|
||
/* Create new bus key */ | ||
FldrCreateComponentKey(SystemKey, | ||
AdapterClass, | ||
MultiFunctionAdapter, | ||
0x0, | ||
0x0, | ||
0xFFFFFFFF, | ||
"ACPI BIOS", | ||
PartialResourceList, | ||
sizeof(CM_PARTIAL_RESOURCE_LIST) + TableSize, | ||
&BiosKey); | ||
|
||
/* Increment bus number */ | ||
(*BusNumber)++; | ||
} | ||
} | ||
|
||
PCONFIGURATION_COMPONENT_DATA | ||
UefiHwDetect(VOID) | ||
{ | ||
PCONFIGURATION_COMPONENT_DATA SystemKey; | ||
ULONG BusNumber = 0; | ||
|
||
TRACE("DetectHardware()\n"); | ||
|
||
/* Create the 'System' key */ | ||
#if defined(_M_IX86) || defined(_M_AMD64) | ||
FldrCreateSystemKey(&SystemKey, "AT/AT COMPATIBLE"); | ||
#elif defined(_M_IA64) | ||
FldrCreateSystemKey(&SystemKey, "Intel Itanium processor family"); | ||
#elif defined(_M_ARM) || defined(_M_ARM64) | ||
FldrCreateSystemKey(&SystemKey, "ARM processor family"); | ||
#else | ||
#error Please define a system key for your architecture | ||
#endif | ||
|
||
/* Detect ACPI */ | ||
DetectAcpiBios(SystemKey, &BusNumber); | ||
|
||
TRACE("DetectHardware() Done\n"); | ||
return SystemKey; | ||
} |
Oops, something went wrong.