From fce4ecd92cf137d479c0dc97461bec3512e9c98d Mon Sep 17 00:00:00 2001 From: Maurice Ma Date: Tue, 31 Mar 2015 01:06:23 +0000 Subject: [PATCH] Pkg-Module: CorebootModulePkg Initial coreboot UEFI payload code check in. It provides UEFI services on top of coreboot that allows UEFI OS boot. CorebootModulePkg is the source code package of coreboot support modules that will be used to parse the coreboot tables and report memory/io resources. It supports the following features: - Support Unified Extensible Firmware Interface (UEFI) specification 2.4. - Support Platform Initialization(PI) specification 1.3. - Support execution as a coreboot payload. - Support USB 3.0 - Support SATA/ATA devices. - Support EFI aware OS boot. The following features are not supported currently and have not been validated: - GCC Tool Chains - SMM Execution Environment - Security Boot It was tested on a Intel Bay Trail CRB platform. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Maurice Ma Reviewed-by: Prince Agyeman git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17084 6f19259b-4bc3-4df7-8a09-765794883524 --- CorebootModulePkg/CbSupportDxe/CbSupportDxe.c | 199 ++++++ CorebootModulePkg/CbSupportDxe/CbSupportDxe.h | 35 ++ .../CbSupportDxe/CbSupportDxe.inf | 59 ++ CorebootModulePkg/CbSupportPei/CbSupportPei.c | 380 ++++++++++++ CorebootModulePkg/CbSupportPei/CbSupportPei.h | 40 ++ .../CbSupportPei/CbSupportPei.inf | 72 +++ CorebootModulePkg/CorebootModulePkg.dec | 59 ++ CorebootModulePkg/Include/Coreboot.h | 219 +++++++ .../Include/Guid/AcpiBoardInfoGuid.h | 30 + .../Include/Guid/FrameBufferInfoGuid.h | 40 ++ .../Include/Guid/SystemTableInfoGuid.h | 30 + .../Include/Library/CbParseLib.h | 154 +++++ .../Library/CbParseLib/CbParseLib.c | 567 ++++++++++++++++++ .../Library/CbParseLib/CbParseLib.inf | 44 ++ CorebootModulePkg/SecCore/FindPeiCore.c | 199 ++++++ CorebootModulePkg/SecCore/Ia32/SecEntry.S | 74 +++ CorebootModulePkg/SecCore/Ia32/SecEntry.asm | 78 +++ CorebootModulePkg/SecCore/Ia32/Stack.S | 78 +++ CorebootModulePkg/SecCore/Ia32/Stack.asm | 82 +++ CorebootModulePkg/SecCore/SecCore.inf | 64 ++ CorebootModulePkg/SecCore/SecMain.c | 291 +++++++++ CorebootModulePkg/SecCore/SecMain.h | 134 +++++ 22 files changed, 2928 insertions(+) create mode 100644 CorebootModulePkg/CbSupportDxe/CbSupportDxe.c create mode 100644 CorebootModulePkg/CbSupportDxe/CbSupportDxe.h create mode 100644 CorebootModulePkg/CbSupportDxe/CbSupportDxe.inf create mode 100644 CorebootModulePkg/CbSupportPei/CbSupportPei.c create mode 100644 CorebootModulePkg/CbSupportPei/CbSupportPei.h create mode 100644 CorebootModulePkg/CbSupportPei/CbSupportPei.inf create mode 100644 CorebootModulePkg/CorebootModulePkg.dec create mode 100644 CorebootModulePkg/Include/Coreboot.h create mode 100644 CorebootModulePkg/Include/Guid/AcpiBoardInfoGuid.h create mode 100644 CorebootModulePkg/Include/Guid/FrameBufferInfoGuid.h create mode 100644 CorebootModulePkg/Include/Guid/SystemTableInfoGuid.h create mode 100644 CorebootModulePkg/Include/Library/CbParseLib.h create mode 100644 CorebootModulePkg/Library/CbParseLib/CbParseLib.c create mode 100644 CorebootModulePkg/Library/CbParseLib/CbParseLib.inf create mode 100644 CorebootModulePkg/SecCore/FindPeiCore.c create mode 100644 CorebootModulePkg/SecCore/Ia32/SecEntry.S create mode 100644 CorebootModulePkg/SecCore/Ia32/SecEntry.asm create mode 100644 CorebootModulePkg/SecCore/Ia32/Stack.S create mode 100644 CorebootModulePkg/SecCore/Ia32/Stack.asm create mode 100644 CorebootModulePkg/SecCore/SecCore.inf create mode 100644 CorebootModulePkg/SecCore/SecMain.c create mode 100644 CorebootModulePkg/SecCore/SecMain.h diff --git a/CorebootModulePkg/CbSupportDxe/CbSupportDxe.c b/CorebootModulePkg/CbSupportDxe/CbSupportDxe.c new file mode 100644 index 0000000000..1b3e74a525 --- /dev/null +++ b/CorebootModulePkg/CbSupportDxe/CbSupportDxe.c @@ -0,0 +1,199 @@ +/** @file + This driver will report some MMIO/IO resources to dxe core, extract smbios and acpi + tables from coreboot and install. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ 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 "CbSupportDxe.h" + +UINTN mPmCtrlReg = 0; +/** + Reserve MMIO/IO resource in GCD + + @param IsMMIO Flag of whether it is mmio resource or io resource. + @param GcdType Type of the space. + @param BaseAddress Base address of the space. + @param Length Length of the space. + @param Alignment Align with 2^Alignment + @param ImageHandle Handle for the image of this driver. + + @retval EFI_SUCCESS Reserve successful +**/ +EFI_STATUS +CbReserveResourceInGcd ( + IN BOOLEAN IsMMIO, + IN UINTN GcdType, + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINTN Alignment, + IN EFI_HANDLE ImageHandle + ) +{ + EFI_STATUS Status; + + if (IsMMIO) { + Status = gDS->AddMemorySpace ( + GcdType, + BaseAddress, + Length, + EFI_MEMORY_UC + ); + if (EFI_ERROR (Status)) { + DEBUG (( + EFI_D_ERROR, + "Failed to add memory space :0x%x 0x%x\n", + BaseAddress, + Length + )); + } + ASSERT_EFI_ERROR (Status); + Status = gDS->AllocateMemorySpace ( + EfiGcdAllocateAddress, + GcdType, + Alignment, + Length, + &BaseAddress, + ImageHandle, + NULL + ); + ASSERT_EFI_ERROR (Status); + } else { + Status = gDS->AddIoSpace ( + GcdType, + BaseAddress, + Length + ); + ASSERT_EFI_ERROR (Status); + Status = gDS->AllocateIoSpace ( + EfiGcdAllocateAddress, + GcdType, + Alignment, + Length, + &BaseAddress, + ImageHandle, + NULL + ); + ASSERT_EFI_ERROR (Status); + } + return Status; +} + +/** + Notification function of EVT_GROUP_READY_TO_BOOT event group. + + This is a notification function registered on EVT_GROUP_READY_TO_BOOT event group. + When the Boot Manager is about to load and execute a boot option, it reclaims variable + storage if free size is below the threshold. + + @param Event Event whose notification function is being invoked. + @param Context Pointer to the notification function's context. + +**/ +VOID +OnReadyToBoot ( + EFI_EVENT Event, + VOID *Context + ) +{ + // + // Enable SCI + // + IoOr16 (mPmCtrlReg, BIT0); + + DEBUG ((EFI_D_ERROR, "Enable SCI bit at 0x%x before boot\n", mPmCtrlReg)); +} + +/** + Main entry for the Coreboot Support DXE module. + + @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The entry point is executed successfully. + @retval other Some error occurs when executing this entry point. + +**/ +EFI_STATUS +CbDxeEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_EVENT ReadyToBootEvent; + EFI_HOB_GUID_TYPE *GuidHob; + SYSTEM_TABLE_INFO *pSystemTableInfo; + ACPI_BOARD_INFO *pAcpiBoardInfo; + + Status = EFI_SUCCESS; + // + // Report MMIO/IO Resources + // + Status = CbReserveResourceInGcd (TRUE, EfiGcdMemoryTypeMemoryMappedIo, 0xFEE00000, SIZE_1MB, 0, SystemTable); // LAPIC + ASSERT_EFI_ERROR (Status); + + Status = CbReserveResourceInGcd (TRUE, EfiGcdMemoryTypeMemoryMappedIo, 0xFEC00000, SIZE_4KB, 0, SystemTable); // IOAPIC + ASSERT_EFI_ERROR (Status); + + Status = CbReserveResourceInGcd (TRUE, EfiGcdMemoryTypeMemoryMappedIo, 0xFED00000, SIZE_1KB, 0, SystemTable); // HPET + ASSERT_EFI_ERROR (Status); + + // + // Find the system table information guid hob + // + GuidHob = GetFirstGuidHob (&gUefiSystemTableInfoGuid); + ASSERT (GuidHob != NULL); + pSystemTableInfo = (SYSTEM_TABLE_INFO *)GET_GUID_HOB_DATA (GuidHob); + + // + // Install Acpi Table + // + if (pSystemTableInfo->AcpiTableBase != 0 && pSystemTableInfo->AcpiTableSize != 0) { + DEBUG ((EFI_D_ERROR, "Install Acpi Table at 0x%x, length 0x%x\n", (UINTN)pSystemTableInfo->AcpiTableBase, pSystemTableInfo->AcpiTableSize)); + Status = gBS->InstallConfigurationTable (&gEfiAcpiTableGuid, (VOID *)(UINTN)pSystemTableInfo->AcpiTableBase); + ASSERT_EFI_ERROR (Status); + } + + // + // Install Smbios Table + // + if (pSystemTableInfo->SmbiosTableBase != 0 && pSystemTableInfo->SmbiosTableSize != 0) { + DEBUG ((EFI_D_ERROR, "Install Smbios Table at 0x%x, length 0x%x\n", (UINTN)pSystemTableInfo->SmbiosTableBase, pSystemTableInfo->SmbiosTableSize)); + Status = gBS->InstallConfigurationTable (&gEfiSmbiosTableGuid, (VOID *)(UINTN)pSystemTableInfo->SmbiosTableBase); + ASSERT_EFI_ERROR (Status); + } + + // + // Find the acpi board information guid hob + // + GuidHob = GetFirstGuidHob (&gUefiAcpiBoardInfoGuid); + ASSERT (GuidHob != NULL); + pAcpiBoardInfo = (ACPI_BOARD_INFO *)GET_GUID_HOB_DATA (GuidHob); + + mPmCtrlReg = (UINTN)pAcpiBoardInfo->PmCtrlRegBase; + DEBUG ((EFI_D_ERROR, "PmCtrlReg at 0x%x\n", mPmCtrlReg)); + + // + // Register callback on the ready to boot event + // in order to enable SCI + // + ReadyToBootEvent = NULL; + Status = EfiCreateEventReadyToBootEx ( + TPL_CALLBACK, + OnReadyToBoot, + NULL, + &ReadyToBootEvent + ); + ASSERT_EFI_ERROR (Status); + + return EFI_SUCCESS; +} + diff --git a/CorebootModulePkg/CbSupportDxe/CbSupportDxe.h b/CorebootModulePkg/CbSupportDxe/CbSupportDxe.h new file mode 100644 index 0000000000..bace2728e6 --- /dev/null +++ b/CorebootModulePkg/CbSupportDxe/CbSupportDxe.h @@ -0,0 +1,35 @@ +/** @file + The header file of Coreboot Support DXE. + +Copyright (c) 2014, Intel Corporation. All rights reserved.
+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. + +**/ +#ifndef __DXE_COREBOOT_SUPPORT_H__ +#define __DXE_COREBOOT_SUPPORT_H__ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#endif diff --git a/CorebootModulePkg/CbSupportDxe/CbSupportDxe.inf b/CorebootModulePkg/CbSupportDxe/CbSupportDxe.inf new file mode 100644 index 0000000000..c92db8ded4 --- /dev/null +++ b/CorebootModulePkg/CbSupportDxe/CbSupportDxe.inf @@ -0,0 +1,59 @@ +## @file +# Coreboot Support DXE Module +# +# Report some MMIO/IO resources to dxe core, extract smbios and acpi tables from coreboot and install. +# +# Copyright (c) 2014, Intel Corporation. All rights reserved.
+# +# 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. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = CbSupportDxe + FILE_GUID = C68DAA4E-7AB5-41e8-A91D-5954421053F3 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = CbDxeEntryPoint + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources] + CbSupportDxe.c + CbSupportDxe.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + IntelFrameworkPkg/IntelFrameworkPkg.dec + IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec + CorebootModulePkg/CorebootModulePkg.dec + +[LibraryClasses] + UefiDriverEntryPoint + UefiBootServicesTableLib + DxeServicesTableLib + DebugLib + BaseMemoryLib + UefiLib + IoLib + HobLib + +[Guids] + gEfiAcpiTableGuid + gEfiSmbiosTableGuid + gUefiSystemTableInfoGuid + gUefiAcpiBoardInfoGuid + +[Depex] + TRUE diff --git a/CorebootModulePkg/CbSupportPei/CbSupportPei.c b/CorebootModulePkg/CbSupportPei/CbSupportPei.c new file mode 100644 index 0000000000..d51553dbc6 --- /dev/null +++ b/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.
+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; +} + diff --git a/CorebootModulePkg/CbSupportPei/CbSupportPei.h b/CorebootModulePkg/CbSupportPei/CbSupportPei.h new file mode 100644 index 0000000000..544838523b --- /dev/null +++ b/CorebootModulePkg/CbSupportPei/CbSupportPei.h @@ -0,0 +1,40 @@ +/** @file + The header file of Coreboot Support PEIM. + +Copyright (c) 2014, Intel Corporation. All rights reserved.
+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. + +**/ + + +#ifndef __PEI_COREBOOT_SUPPORT_H__ +#define __PEI_COREBOOT_SUPPORT_H__ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#endif diff --git a/CorebootModulePkg/CbSupportPei/CbSupportPei.inf b/CorebootModulePkg/CbSupportPei/CbSupportPei.inf new file mode 100644 index 0000000000..9328151554 --- /dev/null +++ b/CorebootModulePkg/CbSupportPei/CbSupportPei.inf @@ -0,0 +1,72 @@ +## @file +# Coreboot Support PEI Module +# +# Parses coreboot table in memory and report resource information into pei core. It will install +# the memory as required. +# +# Copyright (c) 2014, Intel Corporation. All rights reserved.
+# +# 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. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = CbSupportPeim + FILE_GUID = 352C6AF8-315B-4bd6-B04F-31D4ED1EBE57 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + ENTRY_POINT = CbPeiEntryPoint + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + CbSupportPei.c + CbSupportPei.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + IntelFrameworkPkg/IntelFrameworkPkg.dec + IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec + CorebootModulePkg/CorebootModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[LibraryClasses] + PeimEntryPoint + PeiServicesLib + BaseLib + BaseMemoryLib + DebugLib + HobLib + PcdLib + CbParseLib + MtrrLib + +[Guids] + gEfiSmmPeiSmramMemoryReserveGuid + gEfiMemoryTypeInformationGuid + gEfiFirmwareFileSystem2Guid + gUefiSystemTableInfoGuid + gUefiFrameBufferInfoGuid + gUefiAcpiBoardInfoGuid + +[Ppis] + gEfiPeiMasterBootModePpiGuid + +[Pcd] + gUefiCorebootModulePkgTokenSpaceGuid.PcdPayloadFdMemBase + gUefiCorebootModulePkgTokenSpaceGuid.PcdPayloadFdMemSize + gUefiCorebootModulePkgTokenSpaceGuid.PcdCbHeaderPointer + +[Depex] + TRUE \ No newline at end of file diff --git a/CorebootModulePkg/CorebootModulePkg.dec b/CorebootModulePkg/CorebootModulePkg.dec new file mode 100644 index 0000000000..4b97f9f249 --- /dev/null +++ b/CorebootModulePkg/CorebootModulePkg.dec @@ -0,0 +1,59 @@ +## @file +# Coreboot Support Package +# +# Provides drivers and definitions to support coreboot in EDKII bios. +# +# Copyright (c) 2014, Intel Corporation. All rights reserved.
+# This program and the accompanying materials are licensed and made available under +# the terms and conditions of the BSD License that 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. +# +## + +[Defines] + DEC_SPECIFICATION = 0x00010005 + PACKAGE_NAME = CorebootModulePkg + PACKAGE_GUID = DE1750CE-FEE7-4dd1-8E9C-B7B8BAEBCF4F + PACKAGE_VERSION = 0.1 + +[Includes] + Include + +[LibraryClasses] + CbParseLib|Include/Library/CbParseLib.h + +[Guids] + # + ## Defines the token space for the Coreboot Module Package PCDs. + # + gUefiCorebootModulePkgTokenSpaceGuid = {0xe6ff49a0, 0x15df, 0x48fd, {0x9a, 0xcf, 0xd7, 0xdc, 0x27, 0x1b, 0x39, 0xd5}} + gUefiSystemTableInfoGuid = {0x16c8a6d0, 0xfe8a, 0x4082, {0xa2, 0x8, 0xcf, 0x89, 0xc4, 0x29, 0x4, 0x33}} + gUefiFrameBufferInfoGuid = {0xdc2cd8bd, 0x402c, 0x4dc4, {0x9b, 0xe0, 0xc, 0x43, 0x2b, 0x7, 0xfa, 0x34}} + gUefiAcpiBoardInfoGuid = {0xad3d31b, 0xb3d8, 0x4506, {0xae, 0x71, 0x2e, 0xf1, 0x10, 0x6, 0xd9, 0xf}} + + +[Ppis] + +[Protocols] + + +################################################################################ +# +# PCD Declarations section - list of all PCDs Declared by this Package +# Only this package should be providing the +# declaration, other packages should not. +# +################################################################################ +[PcdsFixedAtBuild, PcdsPatchableInModule] +## Indicates the base address of the payload binary in memory +gUefiCorebootModulePkgTokenSpaceGuid.PcdPayloadFdMemBase|0|UINT32|0x10000001 +## Provides the size of the payload binary in memory +gUefiCorebootModulePkgTokenSpaceGuid.PcdPayloadFdMemSize|0|UINT32|0x10000002 + +[PcdsDynamicEx] +gUefiCorebootModulePkgTokenSpaceGuid.PcdCbHeaderPointer|0|UINT32|0x10000003 + diff --git a/CorebootModulePkg/Include/Coreboot.h b/CorebootModulePkg/Include/Coreboot.h new file mode 100644 index 0000000000..7bec1f3d6f --- /dev/null +++ b/CorebootModulePkg/Include/Coreboot.h @@ -0,0 +1,219 @@ +/** @file + Coreboot PEI module include file. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ 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. + +**/ + +/* + * This file is part of the libpayload project. + * + * Copyright (C) 2008 Advanced Micro Devices, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +#ifndef _COREBOOT_PEI_H_INCLUDED_ +#define _COREBOOT_PEI_H_INCLUDED_ + +#pragma warning( disable : 4200 ) + +#define DYN_CBMEM_ALIGN_SIZE (4096) + +struct cbmem_entry { + UINT32 magic; + UINT32 start; + UINT32 size; + UINT32 id; +}; + +struct cbmem_root { + UINT32 max_entries; + UINT32 num_entries; + UINT32 locked; + UINT32 size; + struct cbmem_entry entries[0]; +}; + +struct cbuint64 { + UINT32 lo; + UINT32 hi; +}; + +#define CB_HEADER_SIGNATURE 0x4F49424C + +struct cb_header { + UINT32 signature; + UINT32 header_bytes; + UINT32 header_checksum; + UINT32 table_bytes; + UINT32 table_checksum; + UINT32 table_entries; +}; + +struct cb_record { + UINT32 tag; + UINT32 size; +}; + +#define CB_TAG_UNUSED 0x0000 +#define CB_TAG_MEMORY 0x0001 + +struct cb_memory_range { + struct cbuint64 start; + struct cbuint64 size; + UINT32 type; +}; + +#define CB_MEM_RAM 1 +#define CB_MEM_RESERVED 2 +#define CB_MEM_ACPI 3 +#define CB_MEM_NVS 4 +#define CB_MEM_UNUSABLE 5 +#define CB_MEM_VENDOR_RSVD 6 +#define CB_MEM_TABLE 16 + +struct cb_memory { + UINT32 tag; + UINT32 size; + struct cb_memory_range map[0]; +}; + +#define CB_TAG_MAINBOARD 0x0003 + +struct cb_mainboard { + UINT32 tag; + UINT32 size; + UINT8 vendor_idx; + UINT8 part_number_idx; + UINT8 strings[0]; +}; +#define CB_TAG_VERSION 0x0004 +#define CB_TAG_EXTRA_VERSION 0x0005 +#define CB_TAG_BUILD 0x0006 +#define CB_TAG_COMPILE_TIME 0x0007 +#define CB_TAG_COMPILE_BY 0x0008 +#define CB_TAG_COMPILE_HOST 0x0009 +#define CB_TAG_COMPILE_DOMAIN 0x000a +#define CB_TAG_COMPILER 0x000b +#define CB_TAG_LINKER 0x000c +#define CB_TAG_ASSEMBLER 0x000d + +struct cb_string { + UINT32 tag; + UINT32 size; + UINT8 string[0]; +}; + +#define CB_TAG_SERIAL 0x000f + +struct cb_serial { + UINT32 tag; + UINT32 size; +#define CB_SERIAL_TYPE_IO_MAPPED 1 +#define CB_SERIAL_TYPE_MEMORY_MAPPED 2 + UINT32 type; + UINT32 baseaddr; + UINT32 baud; +}; + +#define CB_TAG_CONSOLE 0x00010 + +struct cb_console { + UINT32 tag; + UINT32 size; + UINT16 type; +}; + +#define CB_TAG_CONSOLE_SERIAL8250 0 +#define CB_TAG_CONSOLE_VGA 1 // OBSOLETE +#define CB_TAG_CONSOLE_BTEXT 2 // OBSOLETE +#define CB_TAG_CONSOLE_LOGBUF 3 +#define CB_TAG_CONSOLE_SROM 4 // OBSOLETE +#define CB_TAG_CONSOLE_EHCI 5 + +#define CB_TAG_FORWARD 0x00011 + +struct cb_forward { + UINT32 tag; + UINT32 size; + UINT64 forward; +}; + +#define CB_TAG_FRAMEBUFFER 0x0012 +struct cb_framebuffer { + UINT32 tag; + UINT32 size; + + UINT64 physical_address; + UINT32 x_resolution; + UINT32 y_resolution; + UINT32 bytes_per_line; + UINT8 bits_per_pixel; + UINT8 red_mask_pos; + UINT8 red_mask_size; + UINT8 green_mask_pos; + UINT8 green_mask_size; + UINT8 blue_mask_pos; + UINT8 blue_mask_size; + UINT8 reserved_mask_pos; + UINT8 reserved_mask_size; +}; + +#define CB_TAG_VDAT 0x0015 +struct cb_vdat { + UINT32 tag; + UINT32 size; /* size of the entire entry */ + UINT64 vdat_addr; + UINT32 vdat_size; +}; + +#define CB_TAG_TIMESTAMPS 0x0016 +#define CB_TAG_CBMEM_CONSOLE 0x0017 +#define CB_TAG_MRC_CACHE 0x0018 +struct cb_cbmem_tab { + UINT32 tag; + UINT32 size; + UINT64 cbmem_tab; +}; + +/* Helpful macros */ + +#define MEM_RANGE_COUNT(_rec) \ + (((_rec)->size - sizeof(*(_rec))) / sizeof((_rec)->map[0])) + +#define MEM_RANGE_PTR(_rec, _idx) \ + (void *)(((UINT8 *) (_rec)) + sizeof(*(_rec)) \ + + (sizeof((_rec)->map[0]) * (_idx))) + + +#endif // _COREBOOT_PEI_H_INCLUDED_ diff --git a/CorebootModulePkg/Include/Guid/AcpiBoardInfoGuid.h b/CorebootModulePkg/Include/Guid/AcpiBoardInfoGuid.h new file mode 100644 index 0000000000..66ebffef2d --- /dev/null +++ b/CorebootModulePkg/Include/Guid/AcpiBoardInfoGuid.h @@ -0,0 +1,30 @@ +/** @file + This file defines the hob structure for board related information from acpi table + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ 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. + +**/ + +#ifndef __ACPI_BOARD_INFO_GUID_H__ +#define __ACPI_BOARD_INFO_GUID_H__ + +/// +/// Board information GUID +/// +extern EFI_GUID gUefiAcpiBoardInfoGuid; + +typedef struct { + UINT64 PmCtrlRegBase; + UINT64 PmTimerRegBase; + UINT64 ResetRegAddress; + UINT8 ResetValue; +} ACPI_BOARD_INFO; + +#endif diff --git a/CorebootModulePkg/Include/Guid/FrameBufferInfoGuid.h b/CorebootModulePkg/Include/Guid/FrameBufferInfoGuid.h new file mode 100644 index 0000000000..be5ca49abc --- /dev/null +++ b/CorebootModulePkg/Include/Guid/FrameBufferInfoGuid.h @@ -0,0 +1,40 @@ +/** @file + This file defines the hob structure for frame buffer device. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ 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. + +**/ + +#ifndef __FRAME_BUFFER_INFO_GUID_H__ +#define __FRAME_BUFFER_INFO_GUID_H__ + +/// +/// Frame Buffer Information GUID +/// +extern EFI_GUID gUefiFrameBufferInfoGuid; + +typedef struct { + UINT8 Position; // Position of the color + UINT8 Mask; // The number of bits expressed as a mask +} COLOR_PLACEMENT; + +typedef struct { + UINT64 LinearFrameBuffer; + UINT32 HorizontalResolution; + UINT32 VerticalResolution; + UINT32 BitsPerPixel; + UINT16 BytesPerScanLine; + COLOR_PLACEMENT Red; + COLOR_PLACEMENT Green; + COLOR_PLACEMENT Blue; + COLOR_PLACEMENT Reserved; +} FRAME_BUFFER_INFO; + +#endif diff --git a/CorebootModulePkg/Include/Guid/SystemTableInfoGuid.h b/CorebootModulePkg/Include/Guid/SystemTableInfoGuid.h new file mode 100644 index 0000000000..5147645911 --- /dev/null +++ b/CorebootModulePkg/Include/Guid/SystemTableInfoGuid.h @@ -0,0 +1,30 @@ +/** @file + This file defines the hob structure for system tables like ACPI, SMBIOS tables. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ 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. + +**/ + +#ifndef __SYSTEM_TABLE_INFO_GUID_H__ +#define __SYSTEM_TABLE_INFO_GUID_H__ + +/// +/// System Table Information GUID +/// +extern EFI_GUID gUefiSystemTableInfoGuid; + +typedef struct { + UINT64 AcpiTableBase; + UINT32 AcpiTableSize; + UINT64 SmbiosTableBase; + UINT32 SmbiosTableSize; +} SYSTEM_TABLE_INFO; + +#endif diff --git a/CorebootModulePkg/Include/Library/CbParseLib.h b/CorebootModulePkg/Include/Library/CbParseLib.h new file mode 100644 index 0000000000..36727d3f58 --- /dev/null +++ b/CorebootModulePkg/Include/Library/CbParseLib.h @@ -0,0 +1,154 @@ +/** @file + This library will parse the coreboot table in memory and extract those required + information. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ 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 + +/** + Acquire the memory information from the coreboot table in memory. + + @param pLowMemorySize Pointer to the variable of low memory size + @param pHighMemorySize Pointer to the variable of high memory size + + @retval RETURN_SUCCESS Successfully find out the memory information. + @retval RETURN_INVALID_PARAMETER Invalid input parameters. + @retval RETURN_NOT_FOUND Failed to find the memory information. + +**/ +RETURN_STATUS +CbParseMemoryInfo ( + IN UINT64* pLowMemorySize, + IN UINT64* pHighMemorySize + ); + +/** + Acquire the coreboot memory table with the given table id + + @param TableId Table id to be searched + @param pMemTable Pointer to the base address of the memory table + @param pMemTableSize Pointer to the size of the memory table + + @retval RETURN_SUCCESS Successfully find out the memory table. + @retval RETURN_INVALID_PARAMETER Invalid input parameters. + @retval RETURN_NOT_FOUND Failed to find the memory table. + +**/ +RETURN_STATUS +CbParseCbMemTable ( + IN UINT32 TableId, + IN VOID** pMemTable, + IN UINT32* pMemTableSize + ); + +/** + Acquire the acpi table from coreboot + + @param pMemTable Pointer to the base address of the memory table + @param pMemTableSize Pointer to the size of the memory table + + @retval RETURN_SUCCESS Successfully find out the memory table. + @retval RETURN_INVALID_PARAMETER Invalid input parameters. + @retval RETURN_NOT_FOUND Failed to find the memory table. + +**/ +RETURN_STATUS +CbParseAcpiTable ( + IN VOID** pMemTable, + IN UINT32* pMemTableSize + ); + +/** + Acquire the smbios table from coreboot + + @param pMemTable Pointer to the base address of the memory table + @param pMemTableSize Pointer to the size of the memory table + + @retval RETURN_SUCCESS Successfully find out the memory table. + @retval RETURN_INVALID_PARAMETER Invalid input parameters. + @retval RETURN_NOT_FOUND Failed to find the memory table. + +**/ +RETURN_STATUS +CbParseSmbiosTable ( + IN VOID** pMemTable, + IN UINT32* pMemTableSize + ); + +/** + Find the required fadt information + + @param pPmCtrlReg Pointer to the address of power management control register + @param pPmTimerReg Pointer to the address of power management timer register + @param pResetReg Pointer to the address of system reset register + @param pResetValue Pointer to the value to be writen to the system reset register + + @retval RETURN_SUCCESS Successfully find out all the required fadt information. + @retval RETURN_NOT_FOUND Failed to find the fadt table. + +**/ +RETURN_STATUS +CbParseFadtInfo ( + IN UINTN* pPmCtrlReg, + IN UINTN* pPmTimerReg, + IN UINTN* pResetReg, + IN UINTN* pResetValue + ); + +/** + Find the serial port information + + @param pRegBase Pointer to the base address of serial port registers + @param pRegAccessType Pointer to the access type of serial port registers + @param pBaudrate Pointer to the serial port baudrate + + @retval RETURN_SUCCESS Successfully find the serial port information. + @retval RETURN_NOT_FOUND Failed to find the serial port information . + +**/ +RETURN_STATUS +CbParseSerialInfo ( + IN UINT32* pRegBase, + IN UINT32* pRegAccessType, + IN UINT32* pBaudrate + ); + +/** + Search for the coreboot table header + + @param Level Level of the search depth + @param HeaderPtr Pointer to the pointer of coreboot table header + + @retval RETURN_SUCCESS Successfully find the coreboot table header . + @retval RETURN_NOT_FOUND Failed to find the coreboot table header . + +**/ +RETURN_STATUS +CbParseGetCbHeader ( + IN UINTN Level, + IN VOID** HeaderPtr + ); + +/** + Find the video frame buffer information + + @param pFbInfo Pointer to the FRAME_BUFFER_INFO structure + + @retval RETURN_SUCCESS Successfully find the video frame buffer information. + @retval RETURN_NOT_FOUND Failed to find the video frame buffer information . + +**/ +RETURN_STATUS +CbParseFbInfo ( + IN FRAME_BUFFER_INFO* pFbInfo + ); + diff --git a/CorebootModulePkg/Library/CbParseLib/CbParseLib.c b/CorebootModulePkg/Library/CbParseLib/CbParseLib.c new file mode 100644 index 0000000000..5535fdcdd5 --- /dev/null +++ b/CorebootModulePkg/Library/CbParseLib/CbParseLib.c @@ -0,0 +1,567 @@ +/** @file + This library will parse the coreboot table in memory and extract those required + information. + + Copyright (c) 2014, Intel Corporation. All rights reserved.
+ 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 +#include +#include +#include +#include +#include + +#include + +#include "Coreboot.h" + +/* Helpful inlines */ + +static UINT64 cb_unpack64(struct cbuint64 val) +{ + return (((UINT64) val.hi) << 32) | val.lo; +} + +static const char *cb_mb_vendor_string(const struct cb_mainboard *cbm) +{ + return (char *)(cbm->strings + cbm->vendor_idx); +} + +static const char *cb_mb_part_string(const struct cb_mainboard *cbm) +{ + return (char *)(cbm->strings + cbm->part_number_idx); +} + +UINT16 +CbCheckSum16 ( + IN UINT16 *Buffer, + IN UINTN Length + ) +{ + UINT32 Sum, TmpValue; + UINTN Idx; + UINT8 *TmpPtr; + + Sum = 0; + TmpPtr = (UINT8 *)Buffer; + for(Idx = 0; Idx < Length; Idx++) { + TmpValue = TmpPtr[Idx]; + if (Idx % 2 == 1) { + TmpValue <<= 8; + } + + Sum += TmpValue; + + // Wrap + if (Sum >= 0x10000) { + Sum = (Sum + (Sum >> 16)) & 0xFFFF; + } + } + + return (UINT16)((~Sum) & 0xFFFF); +} + +VOID * +FindCbTag ( + IN VOID *Start, + IN UINT32 Tag + ) +{ + struct cb_header *Header; + struct cb_record *Record; + UINT8 *TmpPtr; + UINT8 *TagPtr; + UINTN Idx; + UINT16 CheckSum; + + Header = NULL; + TmpPtr = (UINT8 *)Start; + for (Idx = 0; Idx < 4096; Idx += 16, TmpPtr += 16) { + Header = (struct cb_header *)TmpPtr; + if (Header->signature == CB_HEADER_SIGNATURE) { + break; + } + } + + if (Idx >= 4096) + return NULL; + + if (Header == NULL || !Header->table_bytes) + return NULL; + + // + // Check the checksum of the coreboot table header + // + CheckSum = CbCheckSum16 ((UINT16 *)Header, sizeof (*Header)); + if (CheckSum != 0) { + DEBUG ((EFI_D_ERROR, "Invalid coreboot table header checksum\n")); + return NULL; + } + + CheckSum = CbCheckSum16 ((UINT16 *)(TmpPtr + sizeof (*Header)), Header->table_bytes); + if (CheckSum != Header->table_checksum) { + DEBUG ((EFI_D_ERROR, "Incorrect checksum of all the coreboot table entries\n")); + return NULL; + } + + TagPtr = NULL; + TmpPtr += Header->header_bytes; + for (Idx = 0; Idx < Header->table_entries; Idx++) { + Record = (struct cb_record *)TmpPtr; + if (Record->tag == CB_TAG_FORWARD) { + TmpPtr = (VOID *)(UINTN)((struct cb_forward *)(UINTN)Record)->forward; + if (Tag == CB_TAG_FORWARD) + return TmpPtr; + else + return FindCbTag (TmpPtr, Tag); + } + if (Record->tag == Tag) { + TagPtr = TmpPtr; + break; + } + TmpPtr += Record->size; + } + + return TagPtr; +} + +RETURN_STATUS +FindCbMemTable ( + struct cbmem_root *root, + IN UINT32 TableId, + IN VOID** pMemTable, + IN UINT32* pMemTableSize +) +{ + UINTN Idx; + + if ((!root) || (!pMemTable)) + return RETURN_INVALID_PARAMETER; + + for (Idx = 0; Idx < root->num_entries; Idx++) { + if (root->entries[Idx].id == TableId) { + *pMemTable = (VOID *) (UINTN)root->entries[Idx].start; + if (pMemTableSize) + *pMemTableSize = root->entries[Idx].size; + + DEBUG ((EFI_D_ERROR, "Find CbMemTable Id 0x%x, base 0x%x, size 0x%x\n", TableId, *pMemTable, *pMemTableSize)); + return RETURN_SUCCESS; + } + } + + return RETURN_NOT_FOUND; +} + + +/** + Acquire the memory information from the coreboot table in memory. + + @param pLowMemorySize Pointer to the variable of low memory size + @param pHighMemorySize Pointer to the variable of high memory size + + @retval RETURN_SUCCESS Successfully find out the memory information. + @retval RETURN_INVALID_PARAMETER Invalid input parameters. + @retval RETURN_NOT_FOUND Failed to find the memory information. + +**/ +RETURN_STATUS +CbParseMemoryInfo ( + IN UINT64* pLowMemorySize, + IN UINT64* pHighMemorySize + ) +{ + struct cb_memory* rec; + struct cb_memory_range* Range; + UINT64 Start; + UINT64 Size; + UINTN Index; + + if ((!pLowMemorySize) || (!pHighMemorySize)) + return RETURN_INVALID_PARAMETER; + + // + // Get the coreboot memory table + // + rec = (struct cb_memory *)FindCbTag (0, CB_TAG_MEMORY); + if (!rec) + rec = (struct cb_memory *)FindCbTag ((VOID *)(UINTN)PcdGet32 (PcdCbHeaderPointer), CB_TAG_MEMORY); + + if (!rec) + return RETURN_NOT_FOUND; + + *pLowMemorySize = 0; + *pHighMemorySize = 0; + + for (Index = 0; Index < MEM_RANGE_COUNT(rec); Index++) { + Range = MEM_RANGE_PTR(rec, Index); + Start = cb_unpack64(Range->start); + Size = cb_unpack64(Range->size); + DEBUG ((EFI_D_ERROR, "%d. %016lx - %016lx [%02x]\n", + Index, Start, Start + Size - 1, Range->type)); + + if (Range->type != CB_MEM_RAM) { + continue; + } + + if (Start + Size < 0x100000000ULL) { + *pLowMemorySize = Start + Size; + } else { + *pHighMemorySize = Start + Size - 0x100000000ULL; + } + } + + DEBUG ((EFI_D_ERROR, "Low memory 0x%x, High Memory 0x%x\n", *pLowMemorySize, *pHighMemorySize)); + + return RETURN_SUCCESS; +} + + +/** + Acquire the coreboot memory table with the given table id + + @param TableId Table id to be searched + @param pMemTable Pointer to the base address of the memory table + @param pMemTableSize Pointer to the size of the memory table + + @retval RETURN_SUCCESS Successfully find out the memory table. + @retval RETURN_INVALID_PARAMETER Invalid input parameters. + @retval RETURN_NOT_FOUND Failed to find the memory table. + +**/ +RETURN_STATUS +CbParseCbMemTable ( + IN UINT32 TableId, + IN VOID** pMemTable, + IN UINT32* pMemTableSize + ) +{ + struct cb_memory* rec; + struct cb_memory_range* Range; + UINT64 Start; + UINT64 Size; + UINTN Index; + + if (!pMemTable) + return RETURN_INVALID_PARAMETER; + + *pMemTable = NULL; + + // + // Get the coreboot memory table + // + rec = (struct cb_memory *)FindCbTag (0, CB_TAG_MEMORY); + if (!rec) + rec = (struct cb_memory *)FindCbTag ((VOID *)(UINTN)PcdGet32 (PcdCbHeaderPointer), CB_TAG_MEMORY); + + if (!rec) + return RETURN_NOT_FOUND; + + for (Index = 0; Index < MEM_RANGE_COUNT(rec); Index++) { + Range = MEM_RANGE_PTR(rec, Index); + Start = cb_unpack64(Range->start); + Size = cb_unpack64(Range->size); + + if ((Range->type == CB_MEM_TABLE) && (Start > 0x1000)) { + if (FindCbMemTable ((struct cbmem_root *)(UINTN)(Start + Size - DYN_CBMEM_ALIGN_SIZE), TableId, pMemTable, pMemTableSize) == RETURN_SUCCESS) + return RETURN_SUCCESS; + } + } + + return RETURN_NOT_FOUND; +} + + +/** + Acquire the acpi table from coreboot + + @param pMemTable Pointer to the base address of the memory table + @param pMemTableSize Pointer to the size of the memory table + + @retval RETURN_SUCCESS Successfully find out the memory table. + @retval RETURN_INVALID_PARAMETER Invalid input parameters. + @retval RETURN_NOT_FOUND Failed to find the memory table. + +**/ +RETURN_STATUS +CbParseAcpiTable ( + IN VOID** pMemTable, + IN UINT32* pMemTableSize + ) +{ + return CbParseCbMemTable (SIGNATURE_32 ('I', 'P', 'C', 'A'), pMemTable, pMemTableSize); +} + +/** + Acquire the smbios table from coreboot + + @param pMemTable Pointer to the base address of the memory table + @param pMemTableSize Pointer to the size of the memory table + + @retval RETURN_SUCCESS Successfully find out the memory table. + @retval RETURN_INVALID_PARAMETER Invalid input parameters. + @retval RETURN_NOT_FOUND Failed to find the memory table. + +**/ +RETURN_STATUS +CbParseSmbiosTable ( + IN VOID** pMemTable, + IN UINT32* pMemTableSize + ) +{ + return CbParseCbMemTable (SIGNATURE_32 ('T', 'B', 'M', 'S'), pMemTable, pMemTableSize); +} + +/** + Find the required fadt information + + @param pPmCtrlReg Pointer to the address of power management control register + @param pPmTimerReg Pointer to the address of power management timer register + @param pResetReg Pointer to the address of system reset register + @param pResetValue Pointer to the value to be writen to the system reset register + + @retval RETURN_SUCCESS Successfully find out all the required fadt information. + @retval RETURN_NOT_FOUND Failed to find the fadt table. + +**/ +RETURN_STATUS +CbParseFadtInfo ( + IN UINTN* pPmCtrlReg, + IN UINTN* pPmTimerReg, + IN UINTN* pResetReg, + IN UINTN* pResetValue + ) +{ + 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; + RETURN_STATUS Status; + + Rsdp = NULL; + Status = RETURN_SUCCESS; + + Status = CbParseAcpiTable (&Rsdp, NULL); + if (RETURN_ERROR(Status)) + return Status; + + if (!Rsdp) + return RETURN_NOT_FOUND; + + DEBUG ((EFI_D_ERROR, "Find Rsdp at 0x%x\n", Rsdp)); + DEBUG ((EFI_D_ERROR, "Find Rsdt 0x%x, Xsdt 0x%x\n", Rsdp->RsdtAddress, Rsdp->XsdtAddress)); + + // + // Search Rsdt First + // + 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]); + if (pPmCtrlReg) + *pPmCtrlReg = Fadt->Pm1aCntBlk; + DEBUG ((EFI_D_ERROR, "PmCtrl Reg 0x%x\n", Fadt->Pm1aCntBlk)); + + if (pPmTimerReg) + *pPmTimerReg = Fadt->PmTmrBlk; + DEBUG ((EFI_D_ERROR, "PmTimer Reg 0x%x\n", Fadt->PmTmrBlk)); + + if (pResetReg) + *pResetReg = (UINTN)Fadt->ResetReg.Address; + DEBUG ((EFI_D_ERROR, "Reset Reg 0x%x\n", Fadt->ResetReg.Address)); + + if (pResetValue) + *pResetValue = Fadt->ResetValue; + DEBUG ((EFI_D_ERROR, "Reset Value 0x%x\n", Fadt->ResetValue)); + + return RETURN_SUCCESS; + } + } + } + + // + // 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]); + if (pPmCtrlReg) + *pPmCtrlReg = Fadt->Pm1aCntBlk; + DEBUG ((EFI_D_ERROR, "PmCtrl Reg 0x%x\n", Fadt->Pm1aCntBlk)); + + if (pPmTimerReg) + *pPmTimerReg = Fadt->PmTmrBlk; + DEBUG ((EFI_D_ERROR, "PmTimer Reg 0x%x\n", Fadt->PmTmrBlk)); + + if (pResetReg) + *pResetReg = (UINTN)Fadt->ResetReg.Address; + DEBUG ((EFI_D_ERROR, "Reset Reg 0x%x\n", Fadt->ResetReg.Address)); + + if (pResetValue) + *pResetValue = Fadt->ResetValue; + DEBUG ((EFI_D_ERROR, "Reset Value 0x%x\n", Fadt->ResetValue)); + + return RETURN_SUCCESS; + } + } + } + + return RETURN_NOT_FOUND; +} + +/** + Find the serial port information + + @param pRegBase Pointer to the base address of serial port registers + @param pRegAccessType Pointer to the access type of serial port registers + @param pBaudrate Pointer to the serial port baudrate + + @retval RETURN_SUCCESS Successfully find the serial port information. + @retval RETURN_NOT_FOUND Failed to find the serial port information . + +**/ +RETURN_STATUS +CbParseSerialInfo ( + IN UINT32* pRegBase, + IN UINT32* pRegAccessType, + IN UINT32* pBaudrate + ) +{ + struct cb_serial* CbSerial; + + CbSerial = FindCbTag (0, CB_TAG_SERIAL); + if (!CbSerial) + CbSerial = FindCbTag ((VOID *)(UINTN)PcdGet32 (PcdCbHeaderPointer), CB_TAG_SERIAL); + + if (!CbSerial) + return RETURN_NOT_FOUND; + + if (pRegBase) + *pRegBase = CbSerial->baseaddr; + + if (pRegAccessType) + *pRegAccessType = CbSerial->type; + + if (pBaudrate) + *pBaudrate = CbSerial->baud; + + return RETURN_SUCCESS; +} + +/** + Search for the coreboot table header + + @param Level Level of the search depth + @param HeaderPtr Pointer to the pointer of coreboot table header + + @retval RETURN_SUCCESS Successfully find the coreboot table header . + @retval RETURN_NOT_FOUND Failed to find the coreboot table header . + +**/ +RETURN_STATUS +CbParseGetCbHeader ( + IN UINTN Level, + IN VOID** HeaderPtr + ) +{ + UINTN Index; + VOID* TempPtr; + + if (!HeaderPtr) + return RETURN_NOT_FOUND; + + TempPtr = NULL; + for (Index = 0; Index < Level; Index++) { + TempPtr = FindCbTag (TempPtr, CB_TAG_FORWARD); + if (!TempPtr) + break; + } + + if ((Index >= Level) && (TempPtr != NULL)) { + *HeaderPtr = TempPtr; + return RETURN_SUCCESS; + } + + return RETURN_NOT_FOUND; +} + +/** + Find the video frame buffer information + + @param pFbInfo Pointer to the FRAME_BUFFER_INFO structure + + @retval RETURN_SUCCESS Successfully find the video frame buffer information. + @retval RETURN_NOT_FOUND Failed to find the video frame buffer information . + +**/ +RETURN_STATUS +CbParseFbInfo ( + IN FRAME_BUFFER_INFO* pFbInfo + ) +{ + struct cb_framebuffer* CbFbRec; + + if (!pFbInfo) + return RETURN_INVALID_PARAMETER; + + CbFbRec = FindCbTag (0, CB_TAG_FRAMEBUFFER); + if (!CbFbRec) + CbFbRec = FindCbTag ((VOID *)(UINTN)PcdGet32 (PcdCbHeaderPointer), CB_TAG_FRAMEBUFFER); + + if (!CbFbRec) + return RETURN_NOT_FOUND; + + DEBUG ((EFI_D_ERROR, "Found coreboot video frame buffer information\n")); + DEBUG ((EFI_D_ERROR, "physical_address: 0x%x\n", CbFbRec->physical_address)); + DEBUG ((EFI_D_ERROR, "x_resolution: 0x%x\n", CbFbRec->x_resolution)); + DEBUG ((EFI_D_ERROR, "y_resolution: 0x%x\n", CbFbRec->y_resolution)); + DEBUG ((EFI_D_ERROR, "bits_per_pixel: 0x%x\n", CbFbRec->bits_per_pixel)); + DEBUG ((EFI_D_ERROR, "bytes_per_line: 0x%x\n", CbFbRec->bytes_per_line)); + + DEBUG ((EFI_D_ERROR, "red_mask_size: 0x%x\n", CbFbRec->red_mask_size)); + DEBUG ((EFI_D_ERROR, "red_mask_pos: 0x%x\n", CbFbRec->red_mask_pos)); + DEBUG ((EFI_D_ERROR, "green_mask_size: 0x%x\n", CbFbRec->green_mask_size)); + DEBUG ((EFI_D_ERROR, "green_mask_pos: 0x%x\n", CbFbRec->green_mask_pos)); + DEBUG ((EFI_D_ERROR, "blue_mask_size: 0x%x\n", CbFbRec->blue_mask_size)); + DEBUG ((EFI_D_ERROR, "blue_mask_pos: 0x%x\n", CbFbRec->blue_mask_pos)); + DEBUG ((EFI_D_ERROR, "reserved_mask_size: 0x%x\n", CbFbRec->reserved_mask_size)); + DEBUG ((EFI_D_ERROR, "reserved_mask_pos: 0x%x\n", CbFbRec->reserved_mask_pos)); + + pFbInfo->LinearFrameBuffer = CbFbRec->physical_address; + pFbInfo->HorizontalResolution = CbFbRec->x_resolution; + pFbInfo->VerticalResolution = CbFbRec->y_resolution; + pFbInfo->BitsPerPixel = CbFbRec->bits_per_pixel; + pFbInfo->BytesPerScanLine = (UINT16)CbFbRec->bytes_per_line; + pFbInfo->Red.Mask = (1 << CbFbRec->red_mask_size) - 1; + pFbInfo->Red.Position = CbFbRec->red_mask_pos; + pFbInfo->Green.Mask = (1 << CbFbRec->green_mask_size) - 1; + pFbInfo->Green.Position = CbFbRec->green_mask_pos; + pFbInfo->Blue.Mask = (1 << CbFbRec->blue_mask_size) - 1; + pFbInfo->Blue.Position = CbFbRec->blue_mask_pos; + pFbInfo->Reserved.Mask = (1 << CbFbRec->reserved_mask_size) - 1; + pFbInfo->Reserved.Position = CbFbRec->reserved_mask_pos; + + return RETURN_SUCCESS; +} + + diff --git a/CorebootModulePkg/Library/CbParseLib/CbParseLib.inf b/CorebootModulePkg/Library/CbParseLib/CbParseLib.inf new file mode 100644 index 0000000000..d7146a415b --- /dev/null +++ b/CorebootModulePkg/Library/CbParseLib/CbParseLib.inf @@ -0,0 +1,44 @@ +## @file +# Coreboot Table Parse Library. +# +# Copyright (c) 2014, Intel Corporation. All rights reserved.
+# 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. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = CbParseLib + FILE_GUID = 49EDFC9E-5945-4386-9C0B-C9B60CD45BB1 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = CbParseLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + CbParseLib.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + CorebootModulePkg/CorebootModulePkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + PcdLib + +[Pcd] + gUefiCorebootModulePkgTokenSpaceGuid.PcdCbHeaderPointer \ No newline at end of file diff --git a/CorebootModulePkg/SecCore/FindPeiCore.c b/CorebootModulePkg/SecCore/FindPeiCore.c new file mode 100644 index 0000000000..4ce032e72d --- /dev/null +++ b/CorebootModulePkg/SecCore/FindPeiCore.c @@ -0,0 +1,199 @@ +/** @file + Locate the entry point for the PEI Core + +Copyright (c) 2013, Intel Corporation. All rights reserved.
+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 +#include +#include + +#include "SecMain.h" + +/** + Find core image base. + + @param BootFirmwareVolumePtr Point to the boot firmware volume. + @param SecCoreImageBase The base address of the SEC core image. + @param PeiCoreImageBase The base address of the PEI core image. + +**/ +EFI_STATUS +EFIAPI +FindImageBase ( + IN EFI_FIRMWARE_VOLUME_HEADER *BootFirmwareVolumePtr, + OUT EFI_PHYSICAL_ADDRESS *SecCoreImageBase, + OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase + ) +{ + EFI_PHYSICAL_ADDRESS CurrentAddress; + EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume; + EFI_FFS_FILE_HEADER *File; + UINT32 Size; + EFI_PHYSICAL_ADDRESS EndOfFile; + EFI_COMMON_SECTION_HEADER *Section; + EFI_PHYSICAL_ADDRESS EndOfSection; + + *SecCoreImageBase = 0; + *PeiCoreImageBase = 0; + + CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) BootFirmwareVolumePtr; + EndOfFirmwareVolume = CurrentAddress + BootFirmwareVolumePtr->FvLength; + + // + // Loop through the FFS files in the Boot Firmware Volume + // + for (EndOfFile = CurrentAddress + BootFirmwareVolumePtr->HeaderLength; ; ) { + + CurrentAddress = (EndOfFile + 7) & 0xfffffffffffffff8ULL; + if (CurrentAddress > EndOfFirmwareVolume) { + return EFI_NOT_FOUND; + } + + File = (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress; + if (IS_FFS_FILE2 (File)) { + Size = FFS_FILE2_SIZE (File); + if (Size <= 0x00FFFFFF) { + return EFI_NOT_FOUND; + } + } else { + Size = FFS_FILE_SIZE (File); + if (Size < sizeof (EFI_FFS_FILE_HEADER)) { + return EFI_NOT_FOUND; + } + } + + EndOfFile = CurrentAddress + Size; + if (EndOfFile > EndOfFirmwareVolume) { + return EFI_NOT_FOUND; + } + + // + // Look for SEC Core / PEI Core files + // + if (File->Type != EFI_FV_FILETYPE_SECURITY_CORE && + File->Type != EFI_FV_FILETYPE_PEI_CORE) { + continue; + } + + // + // Loop through the FFS file sections within the FFS file + // + if (IS_FFS_FILE2 (File)) { + EndOfSection = (EFI_PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) File + sizeof (EFI_FFS_FILE_HEADER2)); + } else { + EndOfSection = (EFI_PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) File + sizeof (EFI_FFS_FILE_HEADER)); + } + for (;;) { + CurrentAddress = (EndOfSection + 3) & 0xfffffffffffffffcULL; + Section = (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress; + + if (IS_SECTION2 (Section)) { + Size = SECTION2_SIZE (Section); + if (Size <= 0x00FFFFFF) { + return EFI_NOT_FOUND; + } + } else { + Size = SECTION_SIZE (Section); + if (Size < sizeof (EFI_COMMON_SECTION_HEADER)) { + return EFI_NOT_FOUND; + } + } + + EndOfSection = CurrentAddress + Size; + if (EndOfSection > EndOfFile) { + return EFI_NOT_FOUND; + } + + // + // Look for executable sections + // + if (Section->Type == EFI_SECTION_PE32 || Section->Type == EFI_SECTION_TE) { + if (File->Type == EFI_FV_FILETYPE_SECURITY_CORE) { + if (IS_SECTION2 (Section)) { + *SecCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER2)); + } else { + *SecCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER)); + } + } else { + if (IS_SECTION2 (Section)) { + *PeiCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER2)); + } else { + *PeiCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER)); + } + } + break; + } + } + + // + // Both SEC Core and PEI Core images found + // + if (*SecCoreImageBase != 0 && *PeiCoreImageBase != 0) { + return EFI_SUCCESS; + } + } +} + +/** + Find and return Pei Core entry point. + + It also find SEC and PEI Core file debug inforamtion. It will report them if + remote debug is enabled. + + @param BootFirmwareVolumePtr Point to the boot firmware volume. + @param PeiCoreEntryPoint The entry point of the PEI core. + +**/ +VOID +EFIAPI +FindAndReportEntryPoints ( + IN EFI_FIRMWARE_VOLUME_HEADER *BootFirmwareVolumePtr, + OUT EFI_PEI_CORE_ENTRY_POINT *PeiCoreEntryPoint + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS SecCoreImageBase; + EFI_PHYSICAL_ADDRESS PeiCoreImageBase; + PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + + // + // Find SEC Core and PEI Core image base + // + Status = FindImageBase (BootFirmwareVolumePtr, &SecCoreImageBase, &PeiCoreImageBase); + ASSERT_EFI_ERROR (Status); + + ZeroMem ((VOID *) &ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT)); + // + // Report SEC Core debug information when remote debug is enabled + // + ImageContext.ImageAddress = SecCoreImageBase; + ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageContext.ImageAddress); + PeCoffLoaderRelocateImageExtraAction (&ImageContext); + + // + // Report PEI Core debug information when remote debug is enabled + // + ImageContext.ImageAddress = PeiCoreImageBase; + ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageContext.ImageAddress); + PeCoffLoaderRelocateImageExtraAction (&ImageContext); + + // + // Find PEI Core entry point + // + Status = PeCoffLoaderGetEntryPoint ((VOID *) (UINTN) PeiCoreImageBase, (VOID**) PeiCoreEntryPoint); + if (EFI_ERROR (Status)) { + *PeiCoreEntryPoint = 0; + } + + return; +} + diff --git a/CorebootModulePkg/SecCore/Ia32/SecEntry.S b/CorebootModulePkg/SecCore/Ia32/SecEntry.S new file mode 100644 index 0000000000..7133a9edb7 --- /dev/null +++ b/CorebootModulePkg/SecCore/Ia32/SecEntry.S @@ -0,0 +1,74 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2013, Intel Corporation. All rights reserved.
+# 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. +# +# Module Name: +# +# SecEntry.S +# +# Abstract: +# +# This is the code that begins in protected mode. +# It will transfer the control to pei core. +# +#------------------------------------------------------------------------------ + +ASM_GLOBAL ASM_PFX(SecStartup) + +# Pcds +ASM_GLOBAL ASM_PFX(PcdGet32 (PcdPayloadFdMemBase)) + +# +# SecCore Entry Point +# +# Processor is in flat protected mode +# +# @param[in] EAX Initial value of the EAX register (BIST: Built-in Self Test) +# @param[in] DI 'BP': boot-strap processor, or 'AP': application processor +# @param[in] EBP Pointer to the start of the Boot Firmware Volume +# +# @return None This routine does not return +# +ASM_GLOBAL ASM_PFX(_ModuleEntryPoint) +ASM_PFX(_ModuleEntryPoint): + # + # Disable all the interrupts + # + cli + + # + # Construct the temporary memory at 0x80000, length 0x10000 + # + movl ($BASE_512KB + $SIZE_64KB), %esp + + # + # Pass BFV into the PEI Core + # + pushl ASM_PFX(PcdGet32 (PcdPayloadFdMemBase)) + + # + # Pass stack base into the PEI Core + # + pushl $BASE_512KB + + # + # Pass stack size into the PEI Core + # + pushl $SIZE_64KB + + # + # Pass Control into the PEI Core + # + call SecStartup + + # + # Never return to here + # + jmp . diff --git a/CorebootModulePkg/SecCore/Ia32/SecEntry.asm b/CorebootModulePkg/SecCore/Ia32/SecEntry.asm new file mode 100644 index 0000000000..e3c2eac852 --- /dev/null +++ b/CorebootModulePkg/SecCore/Ia32/SecEntry.asm @@ -0,0 +1,78 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2013, Intel Corporation. All rights reserved.
+; 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. +; +; Module Name: +; +; SecEntry.asm +; +; Abstract: +; +; This is the code that begins in protected mode. +; It will transfer the control to pei core. +; +;------------------------------------------------------------------------------ +#include + +.686p +.xmm +.model small, c + +EXTRN SecStartup:NEAR + +; Pcds +EXTRN PcdGet32 (PcdPayloadFdMemBase):DWORD + + .code + +; +; SecCore Entry Point +; +; Processor is in flat protected mode +; +; @param[in] EAX Initial value of the EAX register (BIST: Built-in Self Test) +; @param[in] DI 'BP': boot-strap processor, or 'AP': application processor +; @param[in] EBP Pointer to the start of the Boot Firmware Volume +; +; @return None This routine does not return +; + +_ModuleEntryPoint PROC PUBLIC + ; + ; Disable all the interrupts + ; + cli + ; + ; Construct the temporary memory at 0x80000, length 0x10000 + ; + mov esp, (BASE_512KB + SIZE_64KB) + + ; + ; Pass BFV into the PEI Core + ; + push PcdGet32 (PcdPayloadFdMemBase) + + ; + ; Pass stack base into the PEI Core + ; + push BASE_512KB + + ; + ; Pass stack size into the PEI Core + ; + push SIZE_64KB + + ; + ; Pass Control into the PEI Core + ; + call SecStartup +_ModuleEntryPoint ENDP + +END diff --git a/CorebootModulePkg/SecCore/Ia32/Stack.S b/CorebootModulePkg/SecCore/Ia32/Stack.S new file mode 100644 index 0000000000..cd492404a0 --- /dev/null +++ b/CorebootModulePkg/SecCore/Ia32/Stack.S @@ -0,0 +1,78 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2013, Intel Corporation. All rights reserved.
+# 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. +# +# Abstract: +# +# Switch the stack from temporary memory to permenent memory. +# +#------------------------------------------------------------------------------ + + +#------------------------------------------------------------------------------ +# VOID +# EFIAPI +# SecSwitchStack ( +# UINT32 TemporaryMemoryBase, +# UINT32 PermenentMemoryBase +# )# +#------------------------------------------------------------------------------ +ASM_GLOBAL ASM_PFX (SecSwitchStack) +ASM_PFX(SecSwitchStack): + # + # Save standard registers so they can be used to change stack + # + pushl %eax + pushl %ebx + pushl %ecx + pushl %edx + + # + # !!CAUTION!! this function address's is pushed into stack after + # migration of whole temporary memory, so need save it to permenent + # memory at first! + # + movl 20(%esp), %ebx # Save the first parameter + movl 24(%esp), %ecx # Save the second parameter + + # + # Save this function's return address into permenent memory at first. + # Then, Fixup the esp point to permenent memory + # + movl %esp, %eax + subl %ebx, %eax + addl %ecx, %eax + movl 0(%esp), %edx # copy pushed register's value to permenent memory + movl %edx, 0(%eax) + movl 4(%esp), %edx + movl %edx, 4(%eax) + movl 8(%esp), %edx + movl %edx, 8(%eax) + movl 12(%esp), %edx + movl %edx, 12(%eax) + movl 16(%esp), %edx # Update this function's return address into permenent memory + movl %edx, 16(%eax) + movl %eax, %esp # From now, esp is pointed to permenent memory + + # + # Fixup the ebp point to permenent memory + # + movl %ebp, %eax + subl %ebx, %eax + addl %ecx, %eax + movl %eax, %ebp # From now, ebp is pointed to permenent memory + + popl %edx + popl %ecx + popl %ebx + popl %eax + ret + + diff --git a/CorebootModulePkg/SecCore/Ia32/Stack.asm b/CorebootModulePkg/SecCore/Ia32/Stack.asm new file mode 100644 index 0000000000..9d1ed153e1 --- /dev/null +++ b/CorebootModulePkg/SecCore/Ia32/Stack.asm @@ -0,0 +1,82 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2013, Intel Corporation. All rights reserved.
+; 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. +; +; Abstract: +; +; Switch the stack from temporary memory to permenent memory. +; +;------------------------------------------------------------------------------ + + .586p + .model flat,C + .code + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; SecSwitchStack ( +; UINT32 TemporaryMemoryBase, +; UINT32 PermenentMemoryBase +; ); +;------------------------------------------------------------------------------ +SecSwitchStack PROC + ; + ; Save three register: eax, ebx, ecx + ; + push eax + push ebx + push ecx + push edx + + ; + ; !!CAUTION!! this function address's is pushed into stack after + ; migration of whole temporary memory, so need save it to permenent + ; memory at first! + ; + + mov ebx, [esp + 20] ; Save the first parameter + mov ecx, [esp + 24] ; Save the second parameter + + ; + ; Save this function's return address into permenent memory at first. + ; Then, Fixup the esp point to permenent memory + ; + mov eax, esp + sub eax, ebx + add eax, ecx + mov edx, dword ptr [esp] ; copy pushed register's value to permenent memory + mov dword ptr [eax], edx + mov edx, dword ptr [esp + 4] + mov dword ptr [eax + 4], edx + mov edx, dword ptr [esp + 8] + mov dword ptr [eax + 8], edx + mov edx, dword ptr [esp + 12] + mov dword ptr [eax + 12], edx + mov edx, dword ptr [esp + 16] ; Update this function's return address into permenent memory + mov dword ptr [eax + 16], edx + mov esp, eax ; From now, esp is pointed to permenent memory + + ; + ; Fixup the ebp point to permenent memory + ; + mov eax, ebp + sub eax, ebx + add eax, ecx + mov ebp, eax ; From now, ebp is pointed to permenent memory + + pop edx + pop ecx + pop ebx + pop eax + ret +SecSwitchStack ENDP + + END diff --git a/CorebootModulePkg/SecCore/SecCore.inf b/CorebootModulePkg/SecCore/SecCore.inf new file mode 100644 index 0000000000..f8468f4c24 --- /dev/null +++ b/CorebootModulePkg/SecCore/SecCore.inf @@ -0,0 +1,64 @@ +## @file +# This is the first module taking control from the coreboot. +# +# Copyright (c) 2013, Intel Corporation. All rights reserved.
+# +# 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. +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = SecCore + FILE_GUID = BA7BE337-6CFB-4dbb-B26C-21EC2FC16073 + MODULE_TYPE = SEC + VERSION_STRING = 1.0 + + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources] + SecMain.c + SecMain.h + FindPeiCore.c + +[Sources.IA32] + Ia32/Stack.asm | MSFT + Ia32/Stack.S | GCC + Ia32/SecEntry.asm | MSFT + Ia32/SecEntry.S | GCC + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + CorebootModulePkg/CorebootModulePkg.dec + +[LibraryClasses] + BaseMemoryLib + DebugLib + BaseLib + PcdLib + DebugAgentLib + UefiCpuLib + PeCoffGetEntryPointLib + PeCoffExtraActionLib + +[Ppis] + gEfiSecPlatformInformationPpiGuid # PPI ALWAYS_PRODUCED + gEfiTemporaryRamSupportPpiGuid # PPI ALWAYS_PRODUCED + +[Pcd] + gUefiCorebootModulePkgTokenSpaceGuid.PcdPayloadFdMemBase + gUefiCorebootModulePkgTokenSpaceGuid.PcdPayloadFdMemSize + diff --git a/CorebootModulePkg/SecCore/SecMain.c b/CorebootModulePkg/SecCore/SecMain.c new file mode 100644 index 0000000000..7ce0463d98 --- /dev/null +++ b/CorebootModulePkg/SecCore/SecMain.c @@ -0,0 +1,291 @@ +/** @file + C funtions in SEC + +Copyright (c) 2013, Intel Corporation. All rights reserved.
+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 "SecMain.h" + +EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI gSecTemporaryRamSupportPpi = { + SecTemporaryRamSupport +}; + +EFI_PEI_PPI_DESCRIPTOR mPeiSecPlatformInformationPpi[] = { + { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiTemporaryRamSupportPpiGuid, + &gSecTemporaryRamSupportPpi + } +}; + +// +// These are IDT entries pointing to 10:FFFFFFE4h. +// +UINT64 mIdtEntryTemplate = 0xffff8e000010ffe4ULL; + +/** + Caller provided function to be invoked at the end of InitializeDebugAgent(). + + Entry point to the C language phase of SEC. After the SEC assembly + code has initialized some temporary memory and set up the stack, + the control is transferred to this function. + + @param[in] Context The first input parameter of InitializeDebugAgent(). + +**/ +VOID +EFIAPI +SecStartupPhase2( + IN VOID *Context + ); + + +/** + + Entry point to the C language phase of SEC. After the SEC assembly + code has initialized some temporary memory and set up the stack, + the control is transferred to this function. + + + @param SizeOfRam Size of the temporary memory available for use. + @param TempRamBase Base address of tempory ram + @param BootFirmwareVolume Base address of the Boot Firmware Volume. +**/ +VOID +EFIAPI +SecStartup ( + IN UINT32 SizeOfRam, + IN UINT32 TempRamBase, + IN VOID *BootFirmwareVolume + ) +{ + EFI_SEC_PEI_HAND_OFF SecCoreData; + IA32_DESCRIPTOR IdtDescriptor; + SEC_IDT_TABLE IdtTableInStack; + UINT32 Index; + UINT32 PeiStackSize; + + PeiStackSize = (SizeOfRam >> 1); + + ASSERT (PeiStackSize < SizeOfRam); + + // + // Process all libraries constructor function linked to SecCore. + // + ProcessLibraryConstructorList (); + + // + // Initialize floating point operating environment + // to be compliant with UEFI spec. + // + InitializeFloatingPointUnits (); + + + // |-------------------|----> + // |Idt Table | + // |-------------------| + // |PeiService Pointer | PeiStackSize + // |-------------------| + // | | + // | Stack | + // |-------------------|----> + // | | + // | | + // | Heap | PeiTemporayRamSize + // | | + // | | + // |-------------------|----> TempRamBase + + IdtTableInStack.PeiService = 0; + for (Index = 0; Index < SEC_IDT_ENTRY_COUNT; Index ++) { + CopyMem ((VOID*)&IdtTableInStack.IdtTable[Index], (VOID*)&mIdtEntryTemplate, sizeof (UINT64)); + } + + IdtDescriptor.Base = (UINTN) &IdtTableInStack.IdtTable; + IdtDescriptor.Limit = (UINT16)(sizeof (IdtTableInStack.IdtTable) - 1); + + AsmWriteIdtr (&IdtDescriptor); + + // + // Update the base address and length of Pei temporary memory + // + SecCoreData.DataSize = (UINT16) sizeof (EFI_SEC_PEI_HAND_OFF); + SecCoreData.BootFirmwareVolumeBase = BootFirmwareVolume; + SecCoreData.BootFirmwareVolumeSize = (UINTN)(0x100000000ULL - (UINTN) BootFirmwareVolume); + SecCoreData.TemporaryRamBase = (VOID*)(UINTN) TempRamBase; + SecCoreData.TemporaryRamSize = SizeOfRam; + SecCoreData.PeiTemporaryRamBase = SecCoreData.TemporaryRamBase; + SecCoreData.PeiTemporaryRamSize = SizeOfRam - PeiStackSize; + SecCoreData.StackBase = (VOID*)(UINTN)(TempRamBase + SecCoreData.PeiTemporaryRamSize); + SecCoreData.StackSize = PeiStackSize; + + // + // Initialize Debug Agent to support source level debug in SEC/PEI phases before memory ready. + // + InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC, &SecCoreData, SecStartupPhase2); + +} + +/** + Caller provided function to be invoked at the end of InitializeDebugAgent(). + + Entry point to the C language phase of SEC. After the SEC assembly + code has initialized some temporary memory and set up the stack, + the control is transferred to this function. + + @param[in] Context The first input parameter of InitializeDebugAgent(). + +**/ +VOID +EFIAPI +SecStartupPhase2( + IN VOID *Context + ) +{ + EFI_SEC_PEI_HAND_OFF *SecCoreData; + EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint; + + SecCoreData = (EFI_SEC_PEI_HAND_OFF *) Context; + // + // Find Pei Core entry point. It will report SEC and Pei Core debug information if remote debug + // is enabled. + // + FindAndReportEntryPoints ((EFI_FIRMWARE_VOLUME_HEADER *) SecCoreData->BootFirmwareVolumeBase, &PeiCoreEntryPoint); + if (PeiCoreEntryPoint == NULL) + { + CpuDeadLoop (); + } + + // + // Transfer the control to the PEI core + // + ASSERT (PeiCoreEntryPoint != NULL); + (*PeiCoreEntryPoint) (SecCoreData, (EFI_PEI_PPI_DESCRIPTOR *)&mPeiSecPlatformInformationPpi); + + // + // Should not come here. + // + return ; +} + +/** + This service of the TEMPORARY_RAM_SUPPORT_PPI that migrates temporary RAM into + permanent memory. + + @param PeiServices Pointer to the PEI Services Table. + @param TemporaryMemoryBase Source Address in temporary memory from which the SEC or PEIM will copy the + Temporary RAM contents. + @param PermanentMemoryBase Destination Address in permanent memory into which the SEC or PEIM will copy the + Temporary RAM contents. + @param CopySize Amount of memory to migrate from temporary to permanent memory. + + @retval EFI_SUCCESS The data was successfully returned. + @retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize > TemporaryMemoryBase when + TemporaryMemoryBase > PermanentMemoryBase. + +**/ +EFI_STATUS +EFIAPI +SecTemporaryRamSupport ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase, + IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase, + IN UINTN CopySize + ) +{ + IA32_DESCRIPTOR IdtDescriptor; + VOID* OldHeap; + VOID* NewHeap; + VOID* OldStack; + VOID* NewStack; + DEBUG_AGENT_CONTEXT_POSTMEM_SEC DebugAgentContext; + BOOLEAN OldStatus; + UINTN PeiStackSize; + + PeiStackSize = (CopySize >> 1); + + ASSERT (PeiStackSize < CopySize); + + // + // |-------------------|----> + // | Stack | PeiStackSize + // |-------------------|----> + // | Heap | PeiTemporayRamSize + // |-------------------|----> TempRamBase + // + // |-------------------|----> + // | Heap | PeiTemporayRamSize + // |-------------------|----> + // | Stack | PeiStackSize + // |-------------------|----> PermanentMemoryBase + // + + OldHeap = (VOID*)(UINTN)TemporaryMemoryBase; + NewHeap = (VOID*)((UINTN)PermanentMemoryBase + PeiStackSize); + + OldStack = (VOID*)((UINTN)TemporaryMemoryBase + CopySize - PeiStackSize); + NewStack = (VOID*)(UINTN)PermanentMemoryBase; + + DebugAgentContext.HeapMigrateOffset = (UINTN)NewHeap - (UINTN)OldHeap; + DebugAgentContext.StackMigrateOffset = (UINTN)NewStack - (UINTN)OldStack; + + OldStatus = SaveAndSetDebugTimerInterrupt (FALSE); + // + // Initialize Debug Agent to support source level debug in PEI phase after memory ready. + // It will build HOB and fix up the pointer in IDT table. + // + InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, (VOID *) &DebugAgentContext, NULL); + + // + // Migrate Heap + // + CopyMem (NewHeap, OldHeap, CopySize - PeiStackSize); + + // + // Migrate Stack + // + CopyMem (NewStack, OldStack, PeiStackSize); + + + // + // We need *not* fix the return address because currently, + // The PeiCore is executed in flash. + // + + // + // Rebase IDT table in permanent memory + // + AsmReadIdtr (&IdtDescriptor); + IdtDescriptor.Base = IdtDescriptor.Base - (UINTN)OldStack + (UINTN)NewStack; + + AsmWriteIdtr (&IdtDescriptor); + + + // + // Program MTRR + // + + // + // SecSwitchStack function must be invoked after the memory migration + // immediatly, also we need fixup the stack change caused by new call into + // permenent memory. + // + SecSwitchStack ( + (UINT32) (UINTN) OldStack, + (UINT32) (UINTN) NewStack + ); + + SaveAndSetDebugTimerInterrupt (OldStatus); + + return EFI_SUCCESS; +} + diff --git a/CorebootModulePkg/SecCore/SecMain.h b/CorebootModulePkg/SecCore/SecMain.h new file mode 100644 index 0000000000..7bc991ab5f --- /dev/null +++ b/CorebootModulePkg/SecCore/SecMain.h @@ -0,0 +1,134 @@ +/** @file + Master header file for SecCore. + +Copyright (c) 2013, Intel Corporation. All rights reserved.
+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. + +**/ + +#ifndef _SEC_CORE_H_ +#define _SEC_CORE_H_ + + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + + +#define SEC_IDT_ENTRY_COUNT 34 + +typedef struct _SEC_IDT_TABLE { + // + // Reserved 8 bytes preceding IDT to store EFI_PEI_SERVICES**, since IDT base + // address should be 8-byte alignment. + // Note: For IA32, only the 4 bytes immediately preceding IDT is used to store + // EFI_PEI_SERVICES** + // + UINT64 PeiService; + UINT64 IdtTable[SEC_IDT_ENTRY_COUNT]; +} SEC_IDT_TABLE; + +/** + Switch the stack in the temporary memory to the one in the permanent memory. + + This function must be invoked after the memory migration immediately. The relative + position of the stack in the temporary and permanent memory is same. + + @param TemporaryMemoryBase Base address of the temporary memory. + @param PermenentMemoryBase Base address of the permanent memory. +**/ +VOID +EFIAPI +SecSwitchStack ( + UINT32 TemporaryMemoryBase, + UINT32 PermenentMemoryBase + ); + +/** + This service of the TEMPORARY_RAM_SUPPORT_PPI that migrates temporary RAM into + permanent memory. + + @param PeiServices Pointer to the PEI Services Table. + @param TemporaryMemoryBase Source Address in temporary memory from which the SEC or PEIM will copy the + Temporary RAM contents. + @param PermanentMemoryBase Destination Address in permanent memory into which the SEC or PEIM will copy the + Temporary RAM contents. + @param CopySize Amount of memory to migrate from temporary to permanent memory. + + @retval EFI_SUCCESS The data was successfully returned. + @retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize > TemporaryMemoryBase when + TemporaryMemoryBase > PermanentMemoryBase. + +**/ +EFI_STATUS +EFIAPI +SecTemporaryRamSupport ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase, + IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase, + IN UINTN CopySize + ); + +/** + Entry point to the C language phase of SEC. After the SEC assembly + code has initialized some temporary memory and set up the stack, + the control is transferred to this function. + + @param SizeOfRam Size of the temporary memory available for use. + @param TempRamBase Base address of tempory ram + @param BootFirmwareVolume Base address of the Boot Firmware Volume. +**/ +VOID +EFIAPI +SecStartup ( + IN UINT32 SizeOfRam, + IN UINT32 TempRamBase, + IN VOID *BootFirmwareVolume + ); + +/** + Find and return Pei Core entry point. + + It also find SEC and PEI Core file debug inforamtion. It will report them if + remote debug is enabled. + + @param BootFirmwareVolumePtr Point to the boot firmware volume. + @param PeiCoreEntryPoint Point to the PEI core entry point. + +**/ +VOID +EFIAPI +FindAndReportEntryPoints ( + IN EFI_FIRMWARE_VOLUME_HEADER *BootFirmwareVolumePtr, + OUT EFI_PEI_CORE_ENTRY_POINT *PeiCoreEntryPoint + ); + +/** + Autogenerated function that calls the library constructors for all of the module's + dependent libraries. This function must be called by the SEC Core once a stack has + been established. + +**/ +VOID +EFIAPI +ProcessLibraryConstructorList ( + VOID + ); + +#endif -- 2.39.2