When build option ABOVE_4G_MEMORY is set to true, nothing will change and EDKII will use all available memory. Setting it to false will create memory type information HOB in payload entry, so that EDKII will reserve enough memory below 4G for EDKII modules. This option is useful for bootloaders that are not fully 64-bit aware such as Qubes R4.0.4 bootloader, Zorin and Proxmox. Cc: Guo Dong <guo.dong@intel.com> Cc: Ray Ni <ray.ni@intel.com> Cc: Maurice Ma <maurice.ma@intel.com> Cc: Benjamin You <benjamin.you@intel.com> Signed-off-by: Sean Rhodes <sean@starlabs.systems> Reviewed-by: Guo Dong <guo.dong@intel.com> Reviewed-by: Ray Ni <ray.ni@intel.com>
499 lines
16 KiB
C
499 lines
16 KiB
C
/** @file
|
|
|
|
Copyright (c) 2014 - 2021, Intel Corporation. All rights reserved.<BR>
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
|
|
**/
|
|
|
|
#include <Guid/MemoryTypeInformation.h>
|
|
#include "UefiPayloadEntry.h"
|
|
|
|
STATIC UINT32 mTopOfLowerUsableDram = 0;
|
|
|
|
EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = {
|
|
{ EfiACPIReclaimMemory, FixedPcdGet32 (PcdMemoryTypeEfiACPIReclaimMemory) },
|
|
{ EfiACPIMemoryNVS, FixedPcdGet32 (PcdMemoryTypeEfiACPIMemoryNVS) },
|
|
{ EfiReservedMemoryType, FixedPcdGet32 (PcdMemoryTypeEfiReservedMemoryType) },
|
|
{ EfiRuntimeServicesData, FixedPcdGet32 (PcdMemoryTypeEfiRuntimeServicesData) },
|
|
{ EfiRuntimeServicesCode, FixedPcdGet32 (PcdMemoryTypeEfiRuntimeServicesCode) },
|
|
{ EfiMaxMemoryType, 0 }
|
|
};
|
|
|
|
/**
|
|
Function to reserve memory below 4GB for EDKII Modules.
|
|
|
|
This causes the DXE to dispatch everything under 4GB and allows Operating
|
|
System's that require EFI_LOADED_IMAGE to be under 4GB to start.
|
|
e.g. Xen hypervisor used in Qubes.
|
|
**/
|
|
VOID
|
|
ForceModulesBelow4G (
|
|
VOID
|
|
)
|
|
{
|
|
DEBUG ((DEBUG_INFO, "Building hob to restrict memory resorces to below 4G.\n"));
|
|
|
|
//
|
|
// Create Memory Type Information HOB
|
|
//
|
|
BuildGuidDataHob (
|
|
&gEfiMemoryTypeInformationGuid,
|
|
mDefaultMemoryTypeInformation,
|
|
sizeof (mDefaultMemoryTypeInformation)
|
|
);
|
|
}
|
|
|
|
/**
|
|
Callback function to build resource descriptor HOB
|
|
|
|
This function build a HOB based on the memory map entry info.
|
|
It creates only EFI_RESOURCE_MEMORY_MAPPED_IO and EFI_RESOURCE_MEMORY_RESERVED
|
|
resources.
|
|
|
|
@param MemoryMapEntry Memory map entry info got from bootloader.
|
|
@param Params A pointer to ACPI_BOARD_INFO.
|
|
|
|
@retval EFI_SUCCESS Successfully build a HOB.
|
|
@retval EFI_INVALID_PARAMETER Invalid parameter provided.
|
|
**/
|
|
EFI_STATUS
|
|
MemInfoCallbackMmio (
|
|
IN MEMORY_MAP_ENTRY *MemoryMapEntry,
|
|
IN VOID *Params
|
|
)
|
|
{
|
|
EFI_PHYSICAL_ADDRESS Base;
|
|
EFI_RESOURCE_TYPE Type;
|
|
UINT64 Size;
|
|
EFI_RESOURCE_ATTRIBUTE_TYPE Attribue;
|
|
ACPI_BOARD_INFO *AcpiBoardInfo;
|
|
|
|
AcpiBoardInfo = (ACPI_BOARD_INFO *)Params;
|
|
if (AcpiBoardInfo == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
//
|
|
// Skip types already handled in MemInfoCallback
|
|
//
|
|
if ((MemoryMapEntry->Type == E820_RAM) || (MemoryMapEntry->Type == E820_ACPI)) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
if (MemoryMapEntry->Base == AcpiBoardInfo->PcieBaseAddress) {
|
|
//
|
|
// MMCONF is always MMIO
|
|
//
|
|
Type = EFI_RESOURCE_MEMORY_MAPPED_IO;
|
|
} else if (MemoryMapEntry->Base < mTopOfLowerUsableDram) {
|
|
//
|
|
// It's in DRAM and thus must be reserved
|
|
//
|
|
Type = EFI_RESOURCE_MEMORY_RESERVED;
|
|
} else if ((MemoryMapEntry->Base < 0x100000000ULL) && (MemoryMapEntry->Base >= mTopOfLowerUsableDram)) {
|
|
//
|
|
// It's not in DRAM, must be MMIO
|
|
//
|
|
Type = EFI_RESOURCE_MEMORY_MAPPED_IO;
|
|
} else {
|
|
Type = EFI_RESOURCE_MEMORY_RESERVED;
|
|
}
|
|
|
|
Base = MemoryMapEntry->Base;
|
|
Size = MemoryMapEntry->Size;
|
|
|
|
Attribue = EFI_RESOURCE_ATTRIBUTE_PRESENT |
|
|
EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
|
|
EFI_RESOURCE_ATTRIBUTE_TESTED |
|
|
EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
|
|
EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
|
|
EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
|
|
EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE;
|
|
|
|
BuildResourceDescriptorHob (Type, Attribue, (EFI_PHYSICAL_ADDRESS)Base, Size);
|
|
DEBUG ((DEBUG_INFO, "buildhob: base = 0x%lx, size = 0x%lx, type = 0x%x\n", Base, Size, Type));
|
|
|
|
if ((MemoryMapEntry->Type == E820_UNUSABLE) ||
|
|
(MemoryMapEntry->Type == E820_DISABLED))
|
|
{
|
|
BuildMemoryAllocationHob (Base, Size, EfiUnusableMemory);
|
|
} else if (MemoryMapEntry->Type == E820_PMEM) {
|
|
BuildMemoryAllocationHob (Base, Size, EfiPersistentMemory);
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Callback function to find TOLUD (Top of Lower Usable DRAM)
|
|
|
|
Estimate where TOLUD (Top of Lower Usable DRAM) resides. The exact position
|
|
would require platform specific code.
|
|
|
|
@param MemoryMapEntry Memory map entry info got from bootloader.
|
|
@param Params Not used for now.
|
|
|
|
@retval EFI_SUCCESS Successfully updated mTopOfLowerUsableDram.
|
|
**/
|
|
EFI_STATUS
|
|
FindToludCallback (
|
|
IN MEMORY_MAP_ENTRY *MemoryMapEntry,
|
|
IN VOID *Params
|
|
)
|
|
{
|
|
//
|
|
// This code assumes that the memory map on this x86 machine below 4GiB is continous
|
|
// until TOLUD. In addition it assumes that the bootloader provided memory tables have
|
|
// no "holes" and thus the first memory range not covered by e820 marks the end of
|
|
// usable DRAM. In addition it's assumed that every reserved memory region touching
|
|
// usable RAM is also covering DRAM, everything else that is marked reserved thus must be
|
|
// MMIO not detectable by bootloader/OS
|
|
//
|
|
|
|
//
|
|
// Skip memory types not RAM or reserved
|
|
//
|
|
if ((MemoryMapEntry->Type == E820_UNUSABLE) || (MemoryMapEntry->Type == E820_DISABLED) ||
|
|
(MemoryMapEntry->Type == E820_PMEM))
|
|
{
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
//
|
|
// Skip resources above 4GiB
|
|
//
|
|
if ((MemoryMapEntry->Base + MemoryMapEntry->Size) > 0x100000000ULL) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
if ((MemoryMapEntry->Type == E820_RAM) || (MemoryMapEntry->Type == E820_ACPI) ||
|
|
(MemoryMapEntry->Type == E820_NVS))
|
|
{
|
|
//
|
|
// It's usable DRAM. Update TOLUD.
|
|
//
|
|
if (mTopOfLowerUsableDram < (MemoryMapEntry->Base + MemoryMapEntry->Size)) {
|
|
mTopOfLowerUsableDram = (UINT32)(MemoryMapEntry->Base + MemoryMapEntry->Size);
|
|
}
|
|
} else {
|
|
//
|
|
// It might be 'reserved DRAM' or 'MMIO'.
|
|
//
|
|
// If it touches usable DRAM at Base assume it's DRAM as well,
|
|
// as it could be bootloader installed tables, TSEG, GTT, ...
|
|
//
|
|
if (mTopOfLowerUsableDram == MemoryMapEntry->Base) {
|
|
mTopOfLowerUsableDram = (UINT32)(MemoryMapEntry->Base + MemoryMapEntry->Size);
|
|
}
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Callback function to build resource descriptor HOB
|
|
|
|
This function build a HOB based on the memory map entry info.
|
|
Only add EFI_RESOURCE_SYSTEM_MEMORY.
|
|
|
|
@param MemoryMapEntry Memory map entry info got from bootloader.
|
|
@param Params Not used for now.
|
|
|
|
@retval RETURN_SUCCESS Successfully build a HOB.
|
|
**/
|
|
EFI_STATUS
|
|
MemInfoCallback (
|
|
IN MEMORY_MAP_ENTRY *MemoryMapEntry,
|
|
IN VOID *Params
|
|
)
|
|
{
|
|
EFI_PHYSICAL_ADDRESS Base;
|
|
EFI_RESOURCE_TYPE Type;
|
|
UINT64 Size;
|
|
EFI_RESOURCE_ATTRIBUTE_TYPE Attribue;
|
|
|
|
//
|
|
// Skip everything not known to be usable DRAM.
|
|
// It will be added later.
|
|
//
|
|
if ((MemoryMapEntry->Type != E820_RAM) && (MemoryMapEntry->Type != E820_ACPI) &&
|
|
(MemoryMapEntry->Type != E820_NVS))
|
|
{
|
|
return RETURN_SUCCESS;
|
|
}
|
|
|
|
Type = EFI_RESOURCE_SYSTEM_MEMORY;
|
|
Base = MemoryMapEntry->Base;
|
|
Size = MemoryMapEntry->Size;
|
|
|
|
Attribue = EFI_RESOURCE_ATTRIBUTE_PRESENT |
|
|
EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
|
|
EFI_RESOURCE_ATTRIBUTE_TESTED |
|
|
EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
|
|
EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
|
|
EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
|
|
EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE;
|
|
|
|
BuildResourceDescriptorHob (Type, Attribue, (EFI_PHYSICAL_ADDRESS)Base, Size);
|
|
DEBUG ((DEBUG_INFO, "buildhob: base = 0x%lx, size = 0x%lx, type = 0x%x\n", Base, Size, Type));
|
|
|
|
if (MemoryMapEntry->Type == E820_ACPI) {
|
|
BuildMemoryAllocationHob (Base, Size, EfiACPIReclaimMemory);
|
|
} else if (MemoryMapEntry->Type == E820_NVS) {
|
|
BuildMemoryAllocationHob (Base, Size, EfiACPIMemoryNVS);
|
|
}
|
|
|
|
return RETURN_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
It will build HOBs based on information from bootloaders.
|
|
|
|
@retval EFI_SUCCESS If it completed successfully.
|
|
@retval Others If it failed to build required HOBs.
|
|
**/
|
|
EFI_STATUS
|
|
BuildHobFromBl (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
ACPI_BOARD_INFO *AcpiBoardInfo;
|
|
EFI_PEI_GRAPHICS_INFO_HOB GfxInfo;
|
|
EFI_PEI_GRAPHICS_INFO_HOB *NewGfxInfo;
|
|
EFI_PEI_GRAPHICS_DEVICE_INFO_HOB GfxDeviceInfo;
|
|
EFI_PEI_GRAPHICS_DEVICE_INFO_HOB *NewGfxDeviceInfo;
|
|
UNIVERSAL_PAYLOAD_SMBIOS_TABLE *SmBiosTableHob;
|
|
UNIVERSAL_PAYLOAD_ACPI_TABLE *AcpiTableHob;
|
|
|
|
//
|
|
// First find TOLUD
|
|
//
|
|
DEBUG ((DEBUG_INFO, "Guessing Top of Lower Usable DRAM:\n"));
|
|
Status = ParseMemoryInfo (FindToludCallback, NULL);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
DEBUG ((DEBUG_INFO, "Assuming TOLUD = 0x%x\n", mTopOfLowerUsableDram));
|
|
|
|
//
|
|
// Parse memory info and build memory HOBs for Usable RAM
|
|
//
|
|
DEBUG ((DEBUG_INFO, "Building ResourceDescriptorHobs for usable memory:\n"));
|
|
Status = ParseMemoryInfo (MemInfoCallback, NULL);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
//
|
|
// Create guid hob for frame buffer information
|
|
//
|
|
Status = ParseGfxInfo (&GfxInfo);
|
|
if (!EFI_ERROR (Status)) {
|
|
NewGfxInfo = BuildGuidHob (&gEfiGraphicsInfoHobGuid, sizeof (GfxInfo));
|
|
ASSERT (NewGfxInfo != NULL);
|
|
CopyMem (NewGfxInfo, &GfxInfo, sizeof (GfxInfo));
|
|
DEBUG ((DEBUG_INFO, "Created graphics info hob\n"));
|
|
}
|
|
|
|
Status = ParseGfxDeviceInfo (&GfxDeviceInfo);
|
|
if (!EFI_ERROR (Status)) {
|
|
NewGfxDeviceInfo = BuildGuidHob (&gEfiGraphicsDeviceInfoHobGuid, sizeof (GfxDeviceInfo));
|
|
ASSERT (NewGfxDeviceInfo != NULL);
|
|
CopyMem (NewGfxDeviceInfo, &GfxDeviceInfo, sizeof (GfxDeviceInfo));
|
|
DEBUG ((DEBUG_INFO, "Created graphics device info hob\n"));
|
|
}
|
|
|
|
//
|
|
// Creat SmBios table Hob
|
|
//
|
|
SmBiosTableHob = BuildGuidHob (&gUniversalPayloadSmbiosTableGuid, sizeof (UNIVERSAL_PAYLOAD_SMBIOS_TABLE));
|
|
ASSERT (SmBiosTableHob != NULL);
|
|
SmBiosTableHob->Header.Revision = UNIVERSAL_PAYLOAD_SMBIOS_TABLE_REVISION;
|
|
SmBiosTableHob->Header.Length = sizeof (UNIVERSAL_PAYLOAD_SMBIOS_TABLE);
|
|
DEBUG ((DEBUG_INFO, "Create smbios table gUniversalPayloadSmbiosTableGuid guid hob\n"));
|
|
Status = ParseSmbiosTable (SmBiosTableHob);
|
|
if (!EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "Detected Smbios Table at 0x%lx\n", SmBiosTableHob->SmBiosEntryPoint));
|
|
}
|
|
|
|
//
|
|
// Creat ACPI table Hob
|
|
//
|
|
AcpiTableHob = BuildGuidHob (&gUniversalPayloadAcpiTableGuid, sizeof (UNIVERSAL_PAYLOAD_ACPI_TABLE));
|
|
ASSERT (AcpiTableHob != NULL);
|
|
AcpiTableHob->Header.Revision = UNIVERSAL_PAYLOAD_ACPI_TABLE_REVISION;
|
|
AcpiTableHob->Header.Length = sizeof (UNIVERSAL_PAYLOAD_ACPI_TABLE);
|
|
DEBUG ((DEBUG_INFO, "Create ACPI table gUniversalPayloadAcpiTableGuid guid hob\n"));
|
|
Status = ParseAcpiTableInfo (AcpiTableHob);
|
|
if (!EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "Detected ACPI Table at 0x%lx\n", AcpiTableHob->Rsdp));
|
|
}
|
|
|
|
//
|
|
// Create guid hob for acpi board information
|
|
//
|
|
AcpiBoardInfo = BuildHobFromAcpi (AcpiTableHob->Rsdp);
|
|
ASSERT (AcpiBoardInfo != NULL);
|
|
|
|
//
|
|
// Parse memory info and build memory HOBs for reserved DRAM and MMIO
|
|
//
|
|
DEBUG ((DEBUG_INFO, "Building ResourceDescriptorHobs for reserved memory:\n"));
|
|
Status = ParseMemoryInfo (MemInfoCallbackMmio, AcpiBoardInfo);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
//
|
|
// Parse the misc info provided by bootloader
|
|
//
|
|
Status = ParseMiscInfo ();
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_WARN, "Error when parsing misc info, Status = %r\n", Status));
|
|
}
|
|
|
|
//
|
|
// Parse platform specific information.
|
|
//
|
|
Status = ParsePlatformInfo ();
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "Error when parsing platform info, Status = %r\n", Status));
|
|
return Status;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
This function will build some generic HOBs that doesn't depend on information from bootloaders.
|
|
|
|
**/
|
|
VOID
|
|
BuildGenericHob (
|
|
VOID
|
|
)
|
|
{
|
|
UINT32 RegEax;
|
|
UINT8 PhysicalAddressBits;
|
|
EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute;
|
|
|
|
// The UEFI payload FV
|
|
BuildMemoryAllocationHob (PcdGet32 (PcdPayloadFdMemBase), PcdGet32 (PcdPayloadFdMemSize), EfiBootServicesData);
|
|
|
|
//
|
|
// Build CPU memory space and IO space hob
|
|
//
|
|
AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
|
|
if (RegEax >= 0x80000008) {
|
|
AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
|
|
PhysicalAddressBits = (UINT8)RegEax;
|
|
} else {
|
|
PhysicalAddressBits = 36;
|
|
}
|
|
|
|
BuildCpuHob (PhysicalAddressBits, 16);
|
|
|
|
//
|
|
// Report Local APIC range, cause sbl HOB to be NULL, comment now
|
|
//
|
|
ResourceAttribute = (
|
|
EFI_RESOURCE_ATTRIBUTE_PRESENT |
|
|
EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
|
|
EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
|
|
EFI_RESOURCE_ATTRIBUTE_TESTED
|
|
);
|
|
BuildResourceDescriptorHob (EFI_RESOURCE_MEMORY_MAPPED_IO, ResourceAttribute, 0xFEC80000, SIZE_512KB);
|
|
BuildMemoryAllocationHob (0xFEC80000, SIZE_512KB, EfiMemoryMappedIO);
|
|
}
|
|
|
|
/**
|
|
Entry point to the C language phase of UEFI payload.
|
|
|
|
@param[in] BootloaderParameter The starting address of bootloader parameter block.
|
|
|
|
@retval It will not return if SUCCESS, and return error when passing bootloader parameter.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
_ModuleEntryPoint (
|
|
IN UINTN BootloaderParameter
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
PHYSICAL_ADDRESS DxeCoreEntryPoint;
|
|
UINTN MemBase;
|
|
UINTN HobMemBase;
|
|
UINTN HobMemTop;
|
|
EFI_PEI_HOB_POINTERS Hob;
|
|
SERIAL_PORT_INFO SerialPortInfo;
|
|
UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO *UniversalSerialPort;
|
|
|
|
Status = PcdSet64S (PcdBootloaderParameter, BootloaderParameter);
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
// Initialize floating point operating environment to be compliant with UEFI spec.
|
|
InitializeFloatingPointUnits ();
|
|
|
|
// HOB region is used for HOB and memory allocation for this module
|
|
MemBase = PcdGet32 (PcdPayloadFdMemBase);
|
|
HobMemBase = ALIGN_VALUE (MemBase + PcdGet32 (PcdPayloadFdMemSize), SIZE_1MB);
|
|
HobMemTop = HobMemBase + FixedPcdGet32 (PcdSystemMemoryUefiRegionSize);
|
|
|
|
HobConstructor ((VOID *)MemBase, (VOID *)HobMemTop, (VOID *)HobMemBase, (VOID *)HobMemTop);
|
|
|
|
//
|
|
// Build serial port info
|
|
//
|
|
Status = ParseSerialInfo (&SerialPortInfo);
|
|
if (!EFI_ERROR (Status)) {
|
|
UniversalSerialPort = BuildGuidHob (&gUniversalPayloadSerialPortInfoGuid, sizeof (UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO));
|
|
ASSERT (UniversalSerialPort != NULL);
|
|
UniversalSerialPort->Header.Revision = UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO_REVISION;
|
|
UniversalSerialPort->Header.Length = sizeof (UNIVERSAL_PAYLOAD_SERIAL_PORT_INFO);
|
|
UniversalSerialPort->UseMmio = (SerialPortInfo.Type == 1) ? FALSE : TRUE;
|
|
UniversalSerialPort->RegisterBase = SerialPortInfo.BaseAddr;
|
|
UniversalSerialPort->BaudRate = SerialPortInfo.Baud;
|
|
UniversalSerialPort->RegisterStride = (UINT8)SerialPortInfo.RegWidth;
|
|
}
|
|
|
|
// The library constructors might depend on serial port, so call it after serial port hob
|
|
ProcessLibraryConstructorList ();
|
|
DEBUG ((DEBUG_INFO, "sizeof(UINTN) = 0x%x\n", sizeof (UINTN)));
|
|
|
|
// Build HOB based on information from Bootloader
|
|
Status = BuildHobFromBl ();
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "BuildHobFromBl Status = %r\n", Status));
|
|
return Status;
|
|
}
|
|
|
|
// Build other HOBs required by DXE
|
|
BuildGenericHob ();
|
|
|
|
// Create a HOB to make resources for EDKII modules below 4G
|
|
if (!FixedPcdGetBool (PcdDispatchModuleAbove4GMemory)) {
|
|
ForceModulesBelow4G ();
|
|
}
|
|
|
|
// Load the DXE Core
|
|
Status = LoadDxeCore (&DxeCoreEntryPoint);
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
DEBUG ((DEBUG_INFO, "DxeCoreEntryPoint = 0x%lx\n", DxeCoreEntryPoint));
|
|
|
|
//
|
|
// Mask off all legacy 8259 interrupt sources
|
|
//
|
|
IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0xFF);
|
|
IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0xFF);
|
|
|
|
Hob.HandoffInformationTable = (EFI_HOB_HANDOFF_INFO_TABLE *)GetFirstHob (EFI_HOB_TYPE_HANDOFF);
|
|
HandOffToDxeCore (DxeCoreEntryPoint, Hob);
|
|
|
|
// Should not get here
|
|
CpuDeadLoop ();
|
|
return EFI_SUCCESS;
|
|
}
|