summaryrefslogtreecommitdiffstats
path: root/UefiPayloadPkg/BlSupportPei/BlSupportPei.c
diff options
context:
space:
mode:
Diffstat (limited to 'UefiPayloadPkg/BlSupportPei/BlSupportPei.c')
-rw-r--r--UefiPayloadPkg/BlSupportPei/BlSupportPei.c566
1 files changed, 566 insertions, 0 deletions
diff --git a/UefiPayloadPkg/BlSupportPei/BlSupportPei.c b/UefiPayloadPkg/BlSupportPei/BlSupportPei.c
new file mode 100644
index 0000000000..90433b609f
--- /dev/null
+++ b/UefiPayloadPkg/BlSupportPei/BlSupportPei.c
@@ -0,0 +1,566 @@
+/** @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;
+ 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++) {
+ if (*(UINT32 *)(UINTN)(Entry32[Idx]) == EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) {
+ Fadt = (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)(UINTN)(Entry32[Idx]);
+ DEBUG ((DEBUG_INFO, "Found Fadt in Rsdt\n"));
+ }
+
+ if (*(UINT32 *)(UINTN)(Entry32[Idx]) == 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 *)(UINTN)(Entry32[Idx]);
+ 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++) {
+ if (*(UINT32 *)(UINTN)(Entry64[Idx]) == EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) {
+ Fadt = (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)(UINTN)(Entry64[Idx]);
+ DEBUG ((DEBUG_INFO, "Found Fadt in Xsdt\n"));
+ }
+
+ if (*(UINT32 *)(UINTN)(Entry64[Idx]) == 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 *)(UINTN)(Entry32[Idx]);
+ 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;
+}
+