(This patch is unrelated to the rest of this series; its purpose is to enable building the UefiPayloadPkg DSC files with GCC.) When building "UefiPayloadPkg/UefiPayloadPkgIa32.dsc" with GCC48 for the DEBUG target, the compiler reports that "Entry32" may be used uninitialized in ParseAcpiInfo(), in the XSDT branch. Code inspection proves the compiler right. In the XSDT branch, the code from the RSDT branch must have been duplicated, and "Entry32" references were replaced with "Entry64" -- except where "MmCfgHdr" is assigned. Fix this bug by introducing a helper variable called "Signature", so that we have to refer to "Entry32" or "Entry64" only once per loop body. Cc: Benjamin You <benjamin.you@intel.com> Cc: Guo Dong <guo.dong@intel.com> Cc: Maurice Ma <maurice.ma@intel.com> Signed-off-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Guo Dong <guo.dong@intel.com> Reviewed-by: Philippe Mathieu-Daude <philmd@redhat.com>
570 lines
18 KiB
C
570 lines
18 KiB
C
/** @file
|
|
This PEIM will parse bootloader information and report resource information into pei core.
|
|
This file contains the main entrypoint of the PEIM.
|
|
|
|
Copyright (c) 2014 - 2019, Intel Corporation. All rights reserved.<BR>
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
|
|
**/
|
|
#include "BlSupportPei.h"
|
|
|
|
#define LEGACY_8259_MASK_REGISTER_MASTER 0x21
|
|
#define LEGACY_8259_MASK_REGISTER_SLAVE 0xA1
|
|
|
|
EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = {
|
|
{ EfiACPIReclaimMemory, FixedPcdGet32 (PcdMemoryTypeEfiACPIReclaimMemory) },
|
|
{ EfiACPIMemoryNVS, FixedPcdGet32 (PcdMemoryTypeEfiACPIMemoryNVS) },
|
|
{ EfiReservedMemoryType, FixedPcdGet32 (PcdMemoryTypeEfiReservedMemoryType) },
|
|
{ EfiRuntimeServicesData, FixedPcdGet32 (PcdMemoryTypeEfiRuntimeServicesData) },
|
|
{ EfiRuntimeServicesCode, FixedPcdGet32 (PcdMemoryTypeEfiRuntimeServicesCode) },
|
|
{ EfiMaxMemoryType, 0 }
|
|
};
|
|
|
|
EFI_PEI_PPI_DESCRIPTOR mPpiBootMode[] = {
|
|
{
|
|
EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
|
|
&gEfiPeiMasterBootModePpiGuid,
|
|
NULL
|
|
}
|
|
};
|
|
|
|
EFI_PEI_GRAPHICS_DEVICE_INFO_HOB mDefaultGraphicsDeviceInfo = {
|
|
MAX_UINT16, MAX_UINT16, MAX_UINT16, MAX_UINT16, MAX_UINT8, MAX_UINT8
|
|
};
|
|
|
|
/**
|
|
Create memory mapped io resource hob.
|
|
|
|
@param MmioBase Base address of the memory mapped io range
|
|
@param MmioSize Length of the memory mapped io range
|
|
|
|
**/
|
|
VOID
|
|
BuildMemoryMappedIoRangeHob (
|
|
EFI_PHYSICAL_ADDRESS MmioBase,
|
|
UINT64 MmioSize
|
|
)
|
|
{
|
|
BuildResourceDescriptorHob (
|
|
EFI_RESOURCE_MEMORY_MAPPED_IO,
|
|
(EFI_RESOURCE_ATTRIBUTE_PRESENT |
|
|
EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
|
|
EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
|
|
EFI_RESOURCE_ATTRIBUTE_TESTED),
|
|
MmioBase,
|
|
MmioSize
|
|
);
|
|
|
|
BuildMemoryAllocationHob (
|
|
MmioBase,
|
|
MmioSize,
|
|
EfiMemoryMappedIO
|
|
);
|
|
}
|
|
|
|
/**
|
|
Check the integrity of firmware volume header
|
|
|
|
@param[in] FwVolHeader A pointer to a firmware volume header
|
|
|
|
@retval TRUE The firmware volume is consistent
|
|
@retval FALSE The firmware volume has corrupted.
|
|
|
|
**/
|
|
STATIC
|
|
BOOLEAN
|
|
IsFvHeaderValid (
|
|
IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader
|
|
)
|
|
{
|
|
UINT16 Checksum;
|
|
|
|
// Skip nv storage fv
|
|
if (CompareMem (&FwVolHeader->FileSystemGuid, &gEfiFirmwareFileSystem2Guid, sizeof(EFI_GUID)) != 0 ) {
|
|
return FALSE;
|
|
}
|
|
|
|
if ( (FwVolHeader->Revision != EFI_FVH_REVISION) ||
|
|
(FwVolHeader->Signature != EFI_FVH_SIGNATURE) ||
|
|
(FwVolHeader->FvLength == ((UINTN) -1)) ||
|
|
((FwVolHeader->HeaderLength & 0x01 ) !=0) ) {
|
|
return FALSE;
|
|
}
|
|
|
|
Checksum = CalculateCheckSum16 ((UINT16 *) FwVolHeader, FwVolHeader->HeaderLength);
|
|
if (Checksum != 0) {
|
|
DEBUG (( DEBUG_ERROR,
|
|
"ERROR - Invalid Firmware Volume Header Checksum, change 0x%04x to 0x%04x\r\n",
|
|
FwVolHeader->Checksum,
|
|
(UINT16)( Checksum + FwVolHeader->Checksum )));
|
|
return TRUE; //FALSE; Need update UEFI build tool when patching entrypoin @start of fd.
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/**
|
|
Install FvInfo PPI and create fv hobs for remained fvs
|
|
|
|
**/
|
|
VOID
|
|
PeiReportRemainedFvs (
|
|
VOID
|
|
)
|
|
{
|
|
UINT8* TempPtr;
|
|
UINT8* EndPtr;
|
|
|
|
TempPtr = (UINT8* )(UINTN) PcdGet32 (PcdPayloadFdMemBase);
|
|
EndPtr = (UINT8* )(UINTN) (PcdGet32 (PcdPayloadFdMemBase) + PcdGet32 (PcdPayloadFdMemSize));
|
|
|
|
for (;TempPtr < EndPtr;) {
|
|
if (IsFvHeaderValid ((EFI_FIRMWARE_VOLUME_HEADER* )TempPtr)) {
|
|
if (TempPtr != (UINT8* )(UINTN) PcdGet32 (PcdPayloadFdMemBase)) {
|
|
// Skip the PEI FV
|
|
DEBUG((DEBUG_INFO, "Found one valid fv : 0x%lx.\n", TempPtr, ((EFI_FIRMWARE_VOLUME_HEADER* )TempPtr)->FvLength));
|
|
|
|
PeiServicesInstallFvInfoPpi (
|
|
NULL,
|
|
(VOID *) (UINTN) TempPtr,
|
|
(UINT32) (UINTN) ((EFI_FIRMWARE_VOLUME_HEADER* )TempPtr)->FvLength,
|
|
NULL,
|
|
NULL
|
|
);
|
|
BuildFvHob ((EFI_PHYSICAL_ADDRESS)(UINTN) TempPtr, ((EFI_FIRMWARE_VOLUME_HEADER* )TempPtr)->FvLength);
|
|
}
|
|
}
|
|
TempPtr += ((EFI_FIRMWARE_VOLUME_HEADER* )TempPtr)->FvLength;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
Find the board related info from ACPI table
|
|
|
|
@param AcpiTableBase ACPI table start address in memory
|
|
@param AcpiBoardInfo Pointer to the acpi board info strucutre
|
|
|
|
@retval RETURN_SUCCESS Successfully find out all the required information.
|
|
@retval RETURN_NOT_FOUND Failed to find the required info.
|
|
|
|
**/
|
|
RETURN_STATUS
|
|
ParseAcpiInfo (
|
|
IN UINT64 AcpiTableBase,
|
|
OUT ACPI_BOARD_INFO *AcpiBoardInfo
|
|
)
|
|
{
|
|
EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp;
|
|
EFI_ACPI_DESCRIPTION_HEADER *Rsdt;
|
|
UINT32 *Entry32;
|
|
UINTN Entry32Num;
|
|
EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt;
|
|
EFI_ACPI_DESCRIPTION_HEADER *Xsdt;
|
|
UINT64 *Entry64;
|
|
UINTN Entry64Num;
|
|
UINTN Idx;
|
|
UINT32 *Signature;
|
|
EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER *MmCfgHdr;
|
|
EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE *MmCfgBase;
|
|
|
|
Rsdp = (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)(UINTN)AcpiTableBase;
|
|
DEBUG ((DEBUG_INFO, "Rsdp at 0x%p\n", Rsdp));
|
|
DEBUG ((DEBUG_INFO, "Rsdt at 0x%x, Xsdt at 0x%lx\n", Rsdp->RsdtAddress, Rsdp->XsdtAddress));
|
|
|
|
//
|
|
// Search Rsdt First
|
|
//
|
|
Fadt = NULL;
|
|
MmCfgHdr = NULL;
|
|
Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)(Rsdp->RsdtAddress);
|
|
if (Rsdt != NULL) {
|
|
Entry32 = (UINT32 *)(Rsdt + 1);
|
|
Entry32Num = (Rsdt->Length - sizeof(EFI_ACPI_DESCRIPTION_HEADER)) >> 2;
|
|
for (Idx = 0; Idx < Entry32Num; Idx++) {
|
|
Signature = (UINT32 *)(UINTN)Entry32[Idx];
|
|
if (*Signature == EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) {
|
|
Fadt = (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)Signature;
|
|
DEBUG ((DEBUG_INFO, "Found Fadt in Rsdt\n"));
|
|
}
|
|
|
|
if (*Signature == EFI_ACPI_5_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE) {
|
|
MmCfgHdr = (EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER *)Signature;
|
|
DEBUG ((DEBUG_INFO, "Found MM config address in Rsdt\n"));
|
|
}
|
|
|
|
if ((Fadt != NULL) && (MmCfgHdr != NULL)) {
|
|
goto Done;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Search Xsdt Second
|
|
//
|
|
Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)(Rsdp->XsdtAddress);
|
|
if (Xsdt != NULL) {
|
|
Entry64 = (UINT64 *)(Xsdt + 1);
|
|
Entry64Num = (Xsdt->Length - sizeof(EFI_ACPI_DESCRIPTION_HEADER)) >> 3;
|
|
for (Idx = 0; Idx < Entry64Num; Idx++) {
|
|
Signature = (UINT32 *)(UINTN)Entry64[Idx];
|
|
if (*Signature == EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) {
|
|
Fadt = (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)Signature;
|
|
DEBUG ((DEBUG_INFO, "Found Fadt in Xsdt\n"));
|
|
}
|
|
|
|
if (*Signature == EFI_ACPI_5_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE) {
|
|
MmCfgHdr = (EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER *)Signature;
|
|
DEBUG ((DEBUG_INFO, "Found MM config address in Xsdt\n"));
|
|
}
|
|
|
|
if ((Fadt != NULL) && (MmCfgHdr != NULL)) {
|
|
goto Done;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (Fadt == NULL) {
|
|
return RETURN_NOT_FOUND;
|
|
}
|
|
|
|
Done:
|
|
|
|
AcpiBoardInfo->PmCtrlRegBase = Fadt->Pm1aCntBlk;
|
|
AcpiBoardInfo->PmTimerRegBase = Fadt->PmTmrBlk;
|
|
AcpiBoardInfo->ResetRegAddress = Fadt->ResetReg.Address;
|
|
AcpiBoardInfo->ResetValue = Fadt->ResetValue;
|
|
AcpiBoardInfo->PmEvtBase = Fadt->Pm1aEvtBlk;
|
|
AcpiBoardInfo->PmGpeEnBase = Fadt->Gpe0Blk + Fadt->Gpe0BlkLen / 2;
|
|
|
|
if (MmCfgHdr != NULL) {
|
|
MmCfgBase = (EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE *)((UINT8*) MmCfgHdr + sizeof (*MmCfgHdr));
|
|
AcpiBoardInfo->PcieBaseAddress = MmCfgBase->BaseAddress;
|
|
} else {
|
|
AcpiBoardInfo->PcieBaseAddress = 0;
|
|
}
|
|
DEBUG ((DEBUG_INFO, "PmCtrl Reg 0x%lx\n", AcpiBoardInfo->PmCtrlRegBase));
|
|
DEBUG ((DEBUG_INFO, "PmTimer Reg 0x%lx\n", AcpiBoardInfo->PmTimerRegBase));
|
|
DEBUG ((DEBUG_INFO, "Reset Reg 0x%lx\n", AcpiBoardInfo->ResetRegAddress));
|
|
DEBUG ((DEBUG_INFO, "Reset Value 0x%x\n", AcpiBoardInfo->ResetValue));
|
|
DEBUG ((DEBUG_INFO, "PmEvt Reg 0x%lx\n", AcpiBoardInfo->PmEvtBase));
|
|
DEBUG ((DEBUG_INFO, "PmGpeEn Reg 0x%lx\n", AcpiBoardInfo->PmGpeEnBase));
|
|
DEBUG ((DEBUG_INFO, "PcieBaseAddr 0x%lx\n", AcpiBoardInfo->PcieBaseAddress));
|
|
|
|
//
|
|
// Verify values for proper operation
|
|
//
|
|
ASSERT(Fadt->Pm1aCntBlk != 0);
|
|
ASSERT(Fadt->PmTmrBlk != 0);
|
|
ASSERT(Fadt->ResetReg.Address != 0);
|
|
ASSERT(Fadt->Pm1aEvtBlk != 0);
|
|
ASSERT(Fadt->Gpe0Blk != 0);
|
|
|
|
DEBUG_CODE_BEGIN ();
|
|
BOOLEAN SciEnabled;
|
|
|
|
//
|
|
// Check the consistency of SCI enabling
|
|
//
|
|
|
|
//
|
|
// Get SCI_EN value
|
|
//
|
|
if (Fadt->Pm1CntLen == 4) {
|
|
SciEnabled = (IoRead32 (Fadt->Pm1aCntBlk) & BIT0)? TRUE : FALSE;
|
|
} else {
|
|
//
|
|
// if (Pm1CntLen == 2), use 16 bit IO read;
|
|
// if (Pm1CntLen != 2 && Pm1CntLen != 4), use 16 bit IO read as a fallback
|
|
//
|
|
SciEnabled = (IoRead16 (Fadt->Pm1aCntBlk) & BIT0)? TRUE : FALSE;
|
|
}
|
|
|
|
if (!(Fadt->Flags & EFI_ACPI_5_0_HW_REDUCED_ACPI) &&
|
|
(Fadt->SmiCmd == 0) &&
|
|
!SciEnabled) {
|
|
//
|
|
// The ACPI enabling status is inconsistent: SCI is not enabled but ACPI
|
|
// table does not provide a means to enable it through FADT->SmiCmd
|
|
//
|
|
DEBUG ((DEBUG_ERROR, "ERROR: The ACPI enabling status is inconsistent: SCI is not"
|
|
" enabled but the ACPI table does not provide a means to enable it through FADT->SmiCmd."
|
|
" This may cause issues in OS.\n"));
|
|
}
|
|
DEBUG_CODE_END ();
|
|
|
|
return RETURN_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
MemInfoCallback (
|
|
IN MEMROY_MAP_ENTRY *MemoryMapEntry,
|
|
IN VOID *Params
|
|
)
|
|
{
|
|
PAYLOAD_MEM_INFO *MemInfo;
|
|
UINTN Attribue;
|
|
EFI_PHYSICAL_ADDRESS Base;
|
|
EFI_RESOURCE_TYPE Type;
|
|
UINT64 Size;
|
|
UINT32 SystemLowMemTop;
|
|
|
|
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;
|
|
|
|
MemInfo = (PAYLOAD_MEM_INFO *)Params;
|
|
Type = (MemoryMapEntry->Type == 1) ? EFI_RESOURCE_SYSTEM_MEMORY : EFI_RESOURCE_MEMORY_RESERVED;
|
|
Base = MemoryMapEntry->Base;
|
|
Size = MemoryMapEntry->Size;
|
|
|
|
if ((Base < 0x100000) && ((Base + Size) > 0x100000)) {
|
|
Size -= (0x100000 - Base);
|
|
Base = 0x100000;
|
|
}
|
|
|
|
if (Base >= 0x100000) {
|
|
if (Type == EFI_RESOURCE_SYSTEM_MEMORY) {
|
|
if (Base < 0x100000000ULL) {
|
|
MemInfo->UsableLowMemTop = (UINT32)(Base + Size);
|
|
} else {
|
|
Attribue &= ~EFI_RESOURCE_ATTRIBUTE_TESTED;
|
|
}
|
|
BuildResourceDescriptorHob (
|
|
EFI_RESOURCE_SYSTEM_MEMORY,
|
|
Attribue,
|
|
(EFI_PHYSICAL_ADDRESS)Base,
|
|
Size
|
|
);
|
|
} else if (Type == EFI_RESOURCE_MEMORY_RESERVED) {
|
|
BuildResourceDescriptorHob (
|
|
EFI_RESOURCE_MEMORY_RESERVED,
|
|
Attribue,
|
|
(EFI_PHYSICAL_ADDRESS)Base,
|
|
Size
|
|
);
|
|
if (Base < 0x100000000ULL) {
|
|
SystemLowMemTop = ((UINT32)(Base + Size) + 0x0FFFFFFF) & 0xF0000000;
|
|
if (SystemLowMemTop > MemInfo->SystemLowMemTop) {
|
|
MemInfo->SystemLowMemTop = SystemLowMemTop;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
This is the entrypoint of PEIM
|
|
|
|
@param FileHandle Handle of the file being invoked.
|
|
@param PeiServices Describes the list of possible PEI Services.
|
|
|
|
@retval EFI_SUCCESS if it completed successfully.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
BlPeiEntryPoint (
|
|
IN EFI_PEI_FILE_HANDLE FileHandle,
|
|
IN CONST EFI_PEI_SERVICES **PeiServices
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT64 LowMemorySize;
|
|
UINT64 PeiMemSize = SIZE_64MB;
|
|
EFI_PHYSICAL_ADDRESS PeiMemBase = 0;
|
|
UINT32 RegEax;
|
|
UINT8 PhysicalAddressBits;
|
|
PAYLOAD_MEM_INFO PldMemInfo;
|
|
SYSTEM_TABLE_INFO SysTableInfo;
|
|
SYSTEM_TABLE_INFO *NewSysTableInfo;
|
|
ACPI_BOARD_INFO AcpiBoardInfo;
|
|
ACPI_BOARD_INFO *NewAcpiBoardInfo;
|
|
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;
|
|
|
|
|
|
//
|
|
// Report lower 640KB of RAM. Attribute EFI_RESOURCE_ATTRIBUTE_TESTED
|
|
// is intentionally omitted to prevent erasing of the coreboot header
|
|
// record before it is processed by ParseMemoryInfo.
|
|
//
|
|
BuildResourceDescriptorHob (
|
|
EFI_RESOURCE_SYSTEM_MEMORY,
|
|
(
|
|
EFI_RESOURCE_ATTRIBUTE_PRESENT |
|
|
EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
|
|
EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
|
|
EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
|
|
EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
|
|
EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
|
|
),
|
|
(EFI_PHYSICAL_ADDRESS)(0),
|
|
(UINT64)(0xA0000)
|
|
);
|
|
|
|
BuildResourceDescriptorHob (
|
|
EFI_RESOURCE_MEMORY_RESERVED,
|
|
(
|
|
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
|
|
),
|
|
(EFI_PHYSICAL_ADDRESS)(0xA0000),
|
|
(UINT64)(0x60000)
|
|
);
|
|
|
|
|
|
//
|
|
// Parse memory info
|
|
//
|
|
ZeroMem (&PldMemInfo, sizeof(PldMemInfo));
|
|
Status = ParseMemoryInfo (MemInfoCallback, &PldMemInfo);
|
|
if (EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
|
|
//
|
|
// Install memory
|
|
//
|
|
LowMemorySize = PldMemInfo.UsableLowMemTop;
|
|
PeiMemBase = (LowMemorySize - PeiMemSize) & (~(BASE_64KB - 1));
|
|
DEBUG ((DEBUG_INFO, "Low memory 0x%lx\n", LowMemorySize));
|
|
DEBUG ((DEBUG_INFO, "SystemLowMemTop 0x%x\n", PldMemInfo.SystemLowMemTop));
|
|
DEBUG ((DEBUG_INFO, "PeiMemBase: 0x%lx.\n", PeiMemBase));
|
|
DEBUG ((DEBUG_INFO, "PeiMemSize: 0x%lx.\n", PeiMemSize));
|
|
Status = PeiServicesInstallPeiMemory (PeiMemBase, PeiMemSize);
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
//
|
|
// Set cache on the physical memory
|
|
//
|
|
MtrrSetMemoryAttribute (BASE_1MB, LowMemorySize - BASE_1MB, CacheWriteBack);
|
|
MtrrSetMemoryAttribute (0, 0xA0000, CacheWriteBack);
|
|
|
|
//
|
|
// Create Memory Type Information HOB
|
|
//
|
|
BuildGuidDataHob (
|
|
&gEfiMemoryTypeInformationGuid,
|
|
mDefaultMemoryTypeInformation,
|
|
sizeof(mDefaultMemoryTypeInformation)
|
|
);
|
|
|
|
//
|
|
// Create Fv hob
|
|
//
|
|
PeiReportRemainedFvs ();
|
|
|
|
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;
|
|
}
|
|
|
|
//
|
|
// Create a CPU hand-off information
|
|
//
|
|
BuildCpuHob (PhysicalAddressBits, 16);
|
|
|
|
//
|
|
// Report Local APIC range
|
|
//
|
|
BuildMemoryMappedIoRangeHob (0xFEC80000, SIZE_512KB);
|
|
|
|
//
|
|
// Boot mode
|
|
//
|
|
Status = PeiServicesSetBootMode (BOOT_WITH_FULL_CONFIGURATION);
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
Status = PeiServicesInstallPpi (mPpiBootMode);
|
|
ASSERT_EFI_ERROR (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"));
|
|
}
|
|
|
|
|
|
//
|
|
// Create guid hob for system tables like acpi table and smbios table
|
|
//
|
|
Status = ParseSystemTable(&SysTableInfo);
|
|
ASSERT_EFI_ERROR (Status);
|
|
if (!EFI_ERROR (Status)) {
|
|
NewSysTableInfo = BuildGuidHob (&gUefiSystemTableInfoGuid, sizeof (SYSTEM_TABLE_INFO));
|
|
ASSERT (NewSysTableInfo != NULL);
|
|
CopyMem (NewSysTableInfo, &SysTableInfo, sizeof (SYSTEM_TABLE_INFO));
|
|
DEBUG ((DEBUG_INFO, "Detected Acpi Table at 0x%lx, length 0x%x\n", SysTableInfo.AcpiTableBase, SysTableInfo.AcpiTableSize));
|
|
DEBUG ((DEBUG_INFO, "Detected Smbios Table at 0x%lx, length 0x%x\n", SysTableInfo.SmbiosTableBase, SysTableInfo.SmbiosTableSize));
|
|
}
|
|
|
|
//
|
|
// Create guid hob for acpi board information
|
|
//
|
|
Status = ParseAcpiInfo (SysTableInfo.AcpiTableBase, &AcpiBoardInfo);
|
|
ASSERT_EFI_ERROR (Status);
|
|
if (!EFI_ERROR (Status)) {
|
|
NewAcpiBoardInfo = BuildGuidHob (&gUefiAcpiBoardInfoGuid, sizeof (ACPI_BOARD_INFO));
|
|
ASSERT (NewAcpiBoardInfo != NULL);
|
|
CopyMem (NewAcpiBoardInfo, &AcpiBoardInfo, sizeof (ACPI_BOARD_INFO));
|
|
DEBUG ((DEBUG_INFO, "Create acpi board info guid hob\n"));
|
|
}
|
|
|
|
//
|
|
// Parse platform specific information.
|
|
//
|
|
Status = ParsePlatformInfo ();
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "Error when parsing platform info, Status = %r\n", Status));
|
|
return Status;
|
|
}
|
|
|
|
//
|
|
// Mask off all legacy 8259 interrupt sources
|
|
//
|
|
IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0xFF);
|
|
IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0xFF);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|