summaryrefslogtreecommitdiff
path: root/CorebootModulePkg/CorebootModulePkg/CbSupportPei/CbSupportPei.c
diff options
context:
space:
mode:
Diffstat (limited to 'CorebootModulePkg/CorebootModulePkg/CbSupportPei/CbSupportPei.c')
-rw-r--r--CorebootModulePkg/CorebootModulePkg/CbSupportPei/CbSupportPei.c380
1 files changed, 380 insertions, 0 deletions
diff --git a/CorebootModulePkg/CorebootModulePkg/CbSupportPei/CbSupportPei.c b/CorebootModulePkg/CorebootModulePkg/CbSupportPei/CbSupportPei.c
new file mode 100644
index 000000000..d51553dbc
--- /dev/null
+++ b/CorebootModulePkg/CorebootModulePkg/CbSupportPei/CbSupportPei.c
@@ -0,0 +1,380 @@
+/** @file
+ This PEIM will parse coreboot table in memory and report resource information into pei core.
+ This file contains the main entrypoint of the PEIM.
+
+Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#include "CbSupportPei.h"
+
+EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = {
+ { EfiACPIReclaimMemory, 0x008 },
+ { EfiACPIMemoryNVS, 0x004 },
+ { EfiReservedMemoryType, 0x004 },
+ { EfiRuntimeServicesData, 0x080 },
+ { EfiRuntimeServicesCode, 0x080 },
+ { EfiMaxMemoryType, 0 }
+};
+
+EFI_PEI_PPI_DESCRIPTOR mPpiBootMode[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gEfiPeiMasterBootModePpiGuid,
+ NULL
+ }
+};
+
+/**
+ 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 FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ Install FvInfo PPI and create fv hobs for remained fvs
+
+**/
+VOID
+CbPeiReportRemainedFvs (
+ 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((EFI_D_ERROR, "Found one valid fv : 0x%x.\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;
+ }
+}
+
+/**
+ 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
+CbPeiEntryPoint (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+ UINT64 LowMemorySize, HighMemorySize;
+ UINT64 PeiMemSize = SIZE_64MB; // 64 MB
+ EFI_PHYSICAL_ADDRESS PeiMemBase = 0;
+ UINT32 RegEax;
+ UINT8 PhysicalAddressBits;
+ VOID* pCbHeader;
+ VOID* pAcpiTable;
+ UINT32 AcpiTableSize;
+ VOID* pSmbiosTable;
+ UINT32 SmbiosTableSize;
+ SYSTEM_TABLE_INFO* pSystemTableInfo;
+ FRAME_BUFFER_INFO FbInfo;
+ FRAME_BUFFER_INFO* pFbInfo;
+ ACPI_BOARD_INFO* pAcpiBoardInfo;
+ UINTN PmCtrlRegBase, PmTimerRegBase, ResetRegAddress, ResetValue;
+
+ LowMemorySize = 0;
+ HighMemorySize = 0;
+
+ Status = CbParseMemoryInfo (&LowMemorySize, &HighMemorySize);
+ if (EFI_ERROR(Status))
+ return Status;
+
+ DEBUG((EFI_D_ERROR, "LowMemorySize: 0x%x.\n", LowMemorySize));
+ DEBUG((EFI_D_ERROR, "HighMemorySize: 0x%x.\n", HighMemorySize));
+
+ ASSERT (LowMemorySize > 0);
+
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_SYSTEM_MEMORY,
+ (
+ 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)(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)
+ );
+
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_SYSTEM_MEMORY,
+ (
+ 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)(0x100000),
+ (UINT64) (LowMemorySize - 0x100000)
+ );
+
+ if (HighMemorySize > 0) {
+ 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)(0x100000000),
+ HighMemorySize
+ );
+ }
+
+ //
+ // Should be 64k aligned
+ //
+ PeiMemBase = (LowMemorySize - PeiMemSize) & (~(BASE_64KB - 1));
+
+ DEBUG((EFI_D_ERROR, "PeiMemBase: 0x%x.\n", PeiMemBase));
+ DEBUG((EFI_D_ERROR, "PeiMemSize: 0x%x.\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
+ //
+ CbPeiReportRemainedFvs ();
+
+ 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);
+
+ //
+ // Set pcd to save the upper coreboot header in case the dxecore will
+ // erase 0~4k memory
+ //
+ pCbHeader = NULL;
+ if ((CbParseGetCbHeader (1, &pCbHeader) == RETURN_SUCCESS)
+ && ((UINTN)pCbHeader > BASE_4KB)) {
+ DEBUG((EFI_D_ERROR, "Actual Coreboot header: 0x%x.\n", (UINTN)pCbHeader));
+ PcdSet32 (PcdCbHeaderPointer, (UINT32)(UINTN)pCbHeader);
+ }
+
+ //
+ // Create guid hob for system tables like acpi table and smbios table
+ //
+ pAcpiTable = NULL;
+ AcpiTableSize = 0;
+ pSmbiosTable = NULL;
+ SmbiosTableSize = 0;
+ Status = CbParseAcpiTable (&pAcpiTable, &AcpiTableSize);
+ if (EFI_ERROR (Status)) {
+ // ACPI table is oblidgible
+ DEBUG ((EFI_D_ERROR, "Failed to find the required acpi table\n"));
+ ASSERT (FALSE);
+ }
+ CbParseSmbiosTable (&pSmbiosTable, &SmbiosTableSize);
+
+ pSystemTableInfo = NULL;
+ pSystemTableInfo = BuildGuidHob (&gUefiSystemTableInfoGuid, sizeof (SYSTEM_TABLE_INFO));
+ ASSERT (pSystemTableInfo != NULL);
+ pSystemTableInfo->AcpiTableBase = (UINT64) (UINTN)pAcpiTable;
+ pSystemTableInfo->AcpiTableSize = AcpiTableSize;
+ pSystemTableInfo->SmbiosTableBase = (UINT64) (UINTN)pSmbiosTable;
+ pSystemTableInfo->SmbiosTableSize = SmbiosTableSize;
+ DEBUG ((EFI_D_ERROR, "Detected Acpi Table at 0x%x, length 0x%x\n", (UINTN)pSystemTableInfo->AcpiTableBase, pSystemTableInfo->AcpiTableSize));
+ DEBUG ((EFI_D_ERROR, "Detected Smbios Table at 0x%x, length 0x%x\n", (UINTN)pSystemTableInfo->SmbiosTableBase, pSystemTableInfo->SmbiosTableSize));
+ DEBUG ((EFI_D_ERROR, "Create system table info guid hob\n"));
+
+ //
+ // Create guid hob for acpi board information
+ //
+ Status = CbParseFadtInfo (&PmCtrlRegBase, &PmTimerRegBase, &ResetRegAddress, &ResetValue);
+ ASSERT_EFI_ERROR (Status);
+ pAcpiBoardInfo = NULL;
+ pAcpiBoardInfo = BuildGuidHob (&gUefiAcpiBoardInfoGuid, sizeof (ACPI_BOARD_INFO));
+ ASSERT (pAcpiBoardInfo != NULL);
+ pAcpiBoardInfo->PmCtrlRegBase = (UINT64)PmCtrlRegBase;
+ pAcpiBoardInfo->PmTimerRegBase = (UINT64)PmTimerRegBase;
+ pAcpiBoardInfo->ResetRegAddress = (UINT64)ResetRegAddress;
+ pAcpiBoardInfo->ResetValue = (UINT8)ResetValue;
+ DEBUG ((EFI_D_ERROR, "Create acpi board info guid hob\n"));
+
+ //
+ // Create guid hob for frame buffer information
+ //
+ ZeroMem (&FbInfo, sizeof (FRAME_BUFFER_INFO));
+ Status = CbParseFbInfo (&FbInfo);
+ if (!EFI_ERROR (Status)) {
+ pFbInfo = BuildGuidHob (&gUefiFrameBufferInfoGuid, sizeof (FRAME_BUFFER_INFO));
+ ASSERT (pSystemTableInfo != NULL);
+ CopyMem (pFbInfo, &FbInfo, sizeof (FRAME_BUFFER_INFO));
+ DEBUG ((EFI_D_ERROR, "Create frame buffer info guid hob\n"));
+ }
+
+ return EFI_SUCCESS;
+}
+