From a33a2f62218e6e49a25d63474b7fe423d8ee4b71 Mon Sep 17 00:00:00 2001 From: jyao1 Date: Thu, 24 Jul 2014 06:52:43 +0000 Subject: Add IntelFspWrapper to support boot EDKII on FSP bin. Contributed-under: TianoCore Contribution Agreement 1.0 Signed off by: Jiewen Yao Reviewed by: Ravi Rangarajan Reviewed by: Maurice Ma Reviewed by: Giri Mudusuru Reviewed by: Liming Gao git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15676 6f19259b-4bc3-4df7-8a09-765794883524 --- IntelFspWrapperPkg/FspInitPei/FindPeiCore.c | 199 ++++++++++++++++++ IntelFspWrapperPkg/FspInitPei/FspInitPei.c | 188 +++++++++++++++++ IntelFspWrapperPkg/FspInitPei/FspInitPei.h | 38 ++++ IntelFspWrapperPkg/FspInitPei/FspInitPei.inf | 81 ++++++++ IntelFspWrapperPkg/FspInitPei/FspNotifyS3.c | 86 ++++++++ IntelFspWrapperPkg/FspInitPei/SecFspInitDone.c | 57 ++++++ IntelFspWrapperPkg/FspInitPei/SecMain.c | 269 +++++++++++++++++++++++++ IntelFspWrapperPkg/FspInitPei/SecMain.h | 116 +++++++++++ 8 files changed, 1034 insertions(+) create mode 100644 IntelFspWrapperPkg/FspInitPei/FindPeiCore.c create mode 100644 IntelFspWrapperPkg/FspInitPei/FspInitPei.c create mode 100644 IntelFspWrapperPkg/FspInitPei/FspInitPei.h create mode 100644 IntelFspWrapperPkg/FspInitPei/FspInitPei.inf create mode 100644 IntelFspWrapperPkg/FspInitPei/FspNotifyS3.c create mode 100644 IntelFspWrapperPkg/FspInitPei/SecFspInitDone.c create mode 100644 IntelFspWrapperPkg/FspInitPei/SecMain.c create mode 100644 IntelFspWrapperPkg/FspInitPei/SecMain.h (limited to 'IntelFspWrapperPkg/FspInitPei') diff --git a/IntelFspWrapperPkg/FspInitPei/FindPeiCore.c b/IntelFspWrapperPkg/FspInitPei/FindPeiCore.c new file mode 100644 index 0000000000..ce003d056f --- /dev/null +++ b/IntelFspWrapperPkg/FspInitPei/FindPeiCore.c @@ -0,0 +1,199 @@ +/** @file + Locate the entry point for the PEI Core + + 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 "SecMain.h" + +/** + Find core image base. + + @param[in] BootFirmwareVolumePtr Point to the boot firmware volume. + @param[out] SecCoreImageBase The base address of the SEC core image. + @param[out] 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[in] BootFirmwareVolumePtr Point to the boot firmware volume. + @param[out] 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/IntelFspWrapperPkg/FspInitPei/FspInitPei.c b/IntelFspWrapperPkg/FspInitPei/FspInitPei.c new file mode 100644 index 0000000000..823f1bbef8 --- /dev/null +++ b/IntelFspWrapperPkg/FspInitPei/FspInitPei.c @@ -0,0 +1,188 @@ +/** @file + This PEIM will be invoked twice by pei core. In 1st entry, it will call FspInit API. + In 2nd entry, it will parse the hoblist from fsp and report them 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 "FspInitPei.h" + +/** + FSP Init continuation function. + Control will be returned to this callback function after FspInit API call. + + @param[in] Status Status of the FSP INIT API + @param[in] HobListPtr Pointer to the HOB data structure defined in the PI specification. + +**/ +VOID +ContinuationFunc ( + IN FSP_STATUS Status, + IN VOID *HobListPtr + ) +{ + EFI_BOOT_MODE BootMode; + UINT64 StackSize; + EFI_PHYSICAL_ADDRESS StackBase; + + DEBUG ((DEBUG_INFO, "ContinuationFunc - %r\n", Status)); + DEBUG ((DEBUG_INFO, "HobListPtr - 0x%x\n", HobListPtr)); + + if (Status != FSP_SUCCESS) { + CpuDeadLoop (); + } + + // + // Can not call any PeiServices + // + BootMode = GetBootMode (); + + GetStackInfo (BootMode, TRUE, &StackBase, &StackSize); + DEBUG ((DEBUG_INFO, "StackBase - 0x%x\n", StackBase)); + DEBUG ((DEBUG_INFO, "StackSize - 0x%x\n", StackSize)); + CallPeiCoreEntryPoint ( + HobListPtr, + (VOID *)(UINTN)StackBase, + (VOID *)(UINTN)(StackBase + StackSize) + ); +} + +/** + Call FspInit API. + + @param[in] FspHeader FSP header pointer. +**/ +VOID +SecFspInit ( + IN FSP_INFO_HEADER *FspHeader + ) +{ + FSP_INIT_PARAMS FspInitParams; + FSP_INIT_RT_COMMON_BUFFER FspRtBuffer; + UINT8 FspUpdRgn[FixedPcdGet32 (PcdMaxUpdRegionSize)]; + UINT32 UpdRegionSize; + EFI_BOOT_MODE BootMode; + UINT64 StackSize; + EFI_PHYSICAL_ADDRESS StackBase; + FSP_STATUS FspStatus; + + DEBUG ((DEBUG_INFO, "SecFspInit enter\n")); + + PeiServicesGetBootMode (&BootMode); + DEBUG ((DEBUG_INFO, "BootMode - 0x%x\n", BootMode)); + + GetStackInfo (BootMode, FALSE, &StackBase, &StackSize); + DEBUG ((DEBUG_INFO, "StackBase - 0x%x\n", StackBase)); + DEBUG ((DEBUG_INFO, "StackSize - 0x%x\n", StackSize)); + + ZeroMem (&FspRtBuffer, sizeof(FspRtBuffer)); + FspRtBuffer.StackTop = (UINT32 *)(UINTN)(StackBase + StackSize); + + FspRtBuffer.BootMode = BootMode; + + /* Platform override any UPD configs */ + UpdRegionSize = GetUpdRegionSize(); + DEBUG ((DEBUG_INFO, "UpdRegionSize - 0x%x\n", UpdRegionSize)); + DEBUG ((DEBUG_INFO, "sizeof(FspUpdRgn) - 0x%x\n", sizeof(FspUpdRgn))); + ASSERT(sizeof(FspUpdRgn) >= UpdRegionSize); + ZeroMem (FspUpdRgn, UpdRegionSize); + FspRtBuffer.UpdDataRgnPtr = UpdateFspUpdConfigs (FspUpdRgn); + + ZeroMem (&FspInitParams, sizeof(FspInitParams)); + FspInitParams.NvsBufferPtr = GetNvsBuffer (); + DEBUG ((DEBUG_INFO, "NvsBufferPtr - 0x%x\n", FspInitParams.NvsBufferPtr)); + FspInitParams.RtBufferPtr = (VOID *)&FspRtBuffer; + FspInitParams.ContinuationFunc = (CONTINUATION_PROC)ContinuationFunc; + + SaveSecContext (GetPeiServicesTablePointer ()); + + DEBUG ((DEBUG_INFO, "FspInitParams - 0x%x\n", &FspInitParams)); + DEBUG ((DEBUG_INFO, " NvsBufferPtr - 0x%x\n", FspInitParams.NvsBufferPtr)); + DEBUG ((DEBUG_INFO, " RtBufferPtr - 0x%x\n", FspInitParams.RtBufferPtr)); + DEBUG ((DEBUG_INFO, " StackTop - 0x%x\n", FspRtBuffer.StackTop)); + DEBUG ((DEBUG_INFO, " BootMode - 0x%x\n", FspRtBuffer.BootMode)); + DEBUG ((DEBUG_INFO, " UpdDataRgnPtr - 0x%x\n", FspRtBuffer.UpdDataRgnPtr)); + DEBUG ((DEBUG_INFO, " ContinuationFunc - 0x%x\n", FspInitParams.ContinuationFunc)); + + FspStatus = CallFspInit (FspHeader, &FspInitParams); + // + // Should never return + // + DEBUG((DEBUG_ERROR, "FSP Init failed, status: 0x%x\n", FspStatus)); + CpuDeadLoop (); +} + +/** + This is the entrypoint of PEIM + + @param[in] FileHandle Handle of the file being invoked. + @param[in] PeiServices Describes the list of possible PEI Services. + + @retval EFI_SUCCESS if it completed successfully. +**/ +EFI_STATUS +EFIAPI +FspPeiEntryPoint ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + FSP_INFO_HEADER *FspHeader; + EFI_STATUS Status; + FSP_INIT_DONE_PPI *FspInitDone; + VOID *FspHobList; + EFI_BOOT_MODE BootMode; + + DEBUG ((DEBUG_INFO, "FspPeiEntryPoint\n")); + + Status = PeiServicesLocatePpi ( + &gFspInitDonePpiGuid, + 0, + NULL, + (VOID **) &FspInitDone + ); + if (EFI_ERROR (Status)) { + // + // 1st entry + // + DEBUG ((DEBUG_INFO, "1st entry\n")); + FspHeader = FspFindFspHeader (PcdGet32 (PcdFlashFvFspBase)); + DEBUG ((DEBUG_INFO, "FspHeader - 0x%x\n", FspHeader)); + if (FspHeader == NULL) { + return EFI_DEVICE_ERROR; + } + + SecFspInit (FspHeader); + + // + // Never return here + // + CpuDeadLoop (); + } else { + // + // 2nd entry + // + DEBUG ((DEBUG_INFO, "2nd entry\n")); + Status = FspInitDone->GetFspHobList (PeiServices, FspInitDone, &FspHobList); + DEBUG ((DEBUG_INFO, "FspHobList - 0x%x\n", FspHobList)); + FspHobProcess (FspHobList); + + PeiServicesGetBootMode (&BootMode); + if (BootMode == BOOT_ON_S3_RESUME) { + Status = PeiServicesNotifyPpi (&mS3EndOfPeiNotifyDesc); + ASSERT_EFI_ERROR (Status); + } + } + + return EFI_SUCCESS; +} diff --git a/IntelFspWrapperPkg/FspInitPei/FspInitPei.h b/IntelFspWrapperPkg/FspInitPei/FspInitPei.h new file mode 100644 index 0000000000..5118cd04e3 --- /dev/null +++ b/IntelFspWrapperPkg/FspInitPei/FspInitPei.h @@ -0,0 +1,38 @@ +/** @file + This is PEIM header 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. + +**/ + +#ifndef _FSP_INIT_PEI_H_ +#define _FSP_INIT_PEI_H_ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +extern EFI_PEI_NOTIFY_DESCRIPTOR mS3EndOfPeiNotifyDesc; + +#endif diff --git a/IntelFspWrapperPkg/FspInitPei/FspInitPei.inf b/IntelFspWrapperPkg/FspInitPei/FspInitPei.inf new file mode 100644 index 0000000000..0efcf5e542 --- /dev/null +++ b/IntelFspWrapperPkg/FspInitPei/FspInitPei.inf @@ -0,0 +1,81 @@ +## @file +# FSP PEI Module +# +# This PEIM will be invoked twice by pei core. In 1st entry, it will call FspInit API. +# In 2nd entry, it will parse the hoblist from fsp and report them into pei core. +# including 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 = FspInitPeim + FILE_GUID = BC59E2E1-7492-4031-806E-C48DCCC3A026 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + ENTRY_POINT = FspPeiEntryPoint + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 +# + +[Sources] + FspInitPei.c + FspInitPei.h + FspNotifyS3.c + SecMain.c + SecMain.h + FindPeiCore.c + SecFspInitDone.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + IntelFspPkg/IntelFspPkg.dec + IntelFspWrapperPkg/IntelFspWrapperPkg.dec + +[LibraryClasses] + PeimEntryPoint + PeiServicesLib + PeiServicesTablePointerLib + BaseLib + BaseMemoryLib + DebugLib + HobLib + FspPlatformInfoLib + FspHobProcessLib + FspPlatformSecLib + DebugAgentLib + UefiCpuLib + PeCoffGetEntryPointLib + PeCoffExtraActionLib + FspApiLib + +[Ppis] + gTopOfTemporaryRamPpiGuid + gFspInitDonePpiGuid + gEfiEndOfPeiSignalPpiGuid + +[FixedPcd] + gFspWrapperTokenSpaceGuid.PcdSecCoreMaxPpiSupported + +[Pcd] + gFspWrapperTokenSpaceGuid.PcdPeiTemporaryRamStackSize + gFspWrapperTokenSpaceGuid.PcdFlashFvFspBase + gFspWrapperTokenSpaceGuid.PcdFlashFvFspSize + gFspWrapperTokenSpaceGuid.PcdMaxUpdRegionSize + +[Depex] + gEfiPeiMasterBootModePpiGuid diff --git a/IntelFspWrapperPkg/FspInitPei/FspNotifyS3.c b/IntelFspWrapperPkg/FspInitPei/FspNotifyS3.c new file mode 100644 index 0000000000..6fd2b77588 --- /dev/null +++ b/IntelFspWrapperPkg/FspInitPei/FspNotifyS3.c @@ -0,0 +1,86 @@ +/** @file + In EndOfPei notify, it will call FspNotifyPhase API. + + 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 "FspInitPei.h" + +/** + This function handles S3 resume task at the end of PEI + + @param[in] PeiServices Pointer to PEI Services Table. + @param[in] NotifyDesc Pointer to the descriptor for the Notification event that + caused this function to execute. + @param[in] Ppi Pointer to the PPI data associated with this function. + + @retval EFI_STATUS Always return EFI_SUCCESS +**/ +EFI_STATUS +EFIAPI +S3EndOfPeiNotify ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, + IN VOID *Ppi + ); + +EFI_PEI_NOTIFY_DESCRIPTOR mS3EndOfPeiNotifyDesc = { + (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiEndOfPeiSignalPpiGuid, + S3EndOfPeiNotify +}; + +/** + This function handles S3 resume task at the end of PEI + + @param[in] PeiServices Pointer to PEI Services Table. + @param[in] NotifyDesc Pointer to the descriptor for the Notification event that + caused this function to execute. + @param[in] Ppi Pointer to the PPI data associated with this function. + + @retval EFI_STATUS Always return EFI_SUCCESS +**/ +EFI_STATUS +EFIAPI +S3EndOfPeiNotify ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, + IN VOID *Ppi + ) +{ + NOTIFY_PHASE_PARAMS NotifyPhaseParams; + FSP_STATUS FspStatus; + FSP_INFO_HEADER *FspHeader; + + FspHeader = FspFindFspHeader (PcdGet32 (PcdFlashFvFspBase)); + if (FspHeader == NULL) { + return EFI_DEVICE_ERROR; + } + + NotifyPhaseParams.Phase = EnumInitPhaseAfterPciEnumeration; + FspStatus = CallFspNotifyPhase (FspHeader, &NotifyPhaseParams); + if (FspStatus != FSP_SUCCESS) { + DEBUG((DEBUG_ERROR, "FSP S3NotifyPhase AfterPciEnumeration failed, status: 0x%x\n", FspStatus)); + } else { + DEBUG((DEBUG_INFO, "FSP S3NotifyPhase AfterPciEnumeration Success.\n")); + } + + NotifyPhaseParams.Phase = EnumInitPhaseReadyToBoot; + FspStatus = CallFspNotifyPhase (FspHeader, &NotifyPhaseParams); + if (FspStatus != FSP_SUCCESS) { + DEBUG((DEBUG_ERROR, "FSP S3NotifyPhase ReadyToBoot failed, status: 0x%x\n", FspStatus)); + } else { + DEBUG((DEBUG_INFO, "FSP S3NotifyPhase ReadyToBoot Success.\n")); + } + + return EFI_SUCCESS; +} diff --git a/IntelFspWrapperPkg/FspInitPei/SecFspInitDone.c b/IntelFspWrapperPkg/FspInitPei/SecFspInitDone.c new file mode 100644 index 0000000000..e109694062 --- /dev/null +++ b/IntelFspWrapperPkg/FspInitPei/SecFspInitDone.c @@ -0,0 +1,57 @@ +/** @file + Install FspInitDone PPI and GetFspHobList API. + + 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 "SecMain.h" + +FSP_INIT_DONE_PPI gFspInitDonePpi = { + FspInitDoneGetFspHobList +}; + +/** + Return Hob list produced by FSP. + + @param[in] PeiServices The pointer to the PEI Services Table. + @param[in] This The pointer to this instance of this PPI. + @param[out] FspHobList The pointer to Hob list produced by FSP. + + @return EFI_SUCCESS FReturn Hob list produced by FSP successfully. +**/ +EFI_STATUS +EFIAPI +FspInitDoneGetFspHobList ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN FSP_INIT_DONE_PPI *This, + OUT VOID **FspHobList + ) +{ + VOID *TopOfTemporaryRamPpi; + EFI_STATUS Status; + + Status = (*PeiServices)->LocatePpi ( + PeiServices, + &gTopOfTemporaryRamPpiGuid, + 0, + NULL, + (VOID **) &TopOfTemporaryRamPpi + ); + if (EFI_ERROR (Status)) { + return EFI_NOT_FOUND; + } + + *FspHobList = (VOID *)(UINTN)(*(UINT32 *)((UINTN)TopOfTemporaryRamPpi - sizeof(UINT32))); + + return EFI_SUCCESS; +} + diff --git a/IntelFspWrapperPkg/FspInitPei/SecMain.c b/IntelFspWrapperPkg/FspInitPei/SecMain.c new file mode 100644 index 0000000000..10550e74de --- /dev/null +++ b/IntelFspWrapperPkg/FspInitPei/SecMain.c @@ -0,0 +1,269 @@ +/** @file + C functions in SEC + + 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 "SecMain.h" + +EFI_PEI_PPI_DESCRIPTOR mPeiSecMainPpi[] = { + { + EFI_PEI_PPI_DESCRIPTOR_PPI, + &gTopOfTemporaryRamPpiGuid, + NULL // To be patched later. + }, + { + EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, + &gFspInitDonePpiGuid, + &gFspInitDonePpi + }, +}; + +// +// 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[in] SizeOfRam Size of the temporary memory available for use. + @param[in] TempRamBase Base address of tempory ram + @param[in] 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 = PcdGet32 (PcdPeiTemporaryRamStackSize); + if (PeiStackSize == 0) { + PeiStackSize = (SizeOfRam >> 1); + } + + ASSERT (PeiStackSize < SizeOfRam); + + // + // Process all libraries constructor function linked to SecCore. + // + ProcessLibraryConstructorList (); + + DEBUG ((DEBUG_INFO, "FspPei - SecStartup\n")); + + // + // 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)(SIZE_4GB - (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; + + DEBUG ((DEBUG_INFO, "BootFirmwareVolumeBase - 0x%x\n", SecCoreData.BootFirmwareVolumeBase)); + DEBUG ((DEBUG_INFO, "BootFirmwareVolumeSize - 0x%x\n", SecCoreData.BootFirmwareVolumeSize)); + DEBUG ((DEBUG_INFO, "TemporaryRamBase - 0x%x\n", SecCoreData.TemporaryRamBase)); + DEBUG ((DEBUG_INFO, "TemporaryRamSize - 0x%x\n", SecCoreData.TemporaryRamSize)); + DEBUG ((DEBUG_INFO, "PeiTemporaryRamBase - 0x%x\n", SecCoreData.PeiTemporaryRamBase)); + DEBUG ((DEBUG_INFO, "PeiTemporaryRamSize - 0x%x\n", SecCoreData.PeiTemporaryRamSize)); + DEBUG ((DEBUG_INFO, "StackBase - 0x%x\n", SecCoreData.StackBase)); + DEBUG ((DEBUG_INFO, "StackSize - 0x%x\n", SecCoreData.StackSize)); + + // + // Initialize Debug Agent to support source level debug in SEC/PEI phases before memory ready. + // + InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC, &SecCoreData, SecStartupPhase2); + +} + +/** + This API patch the TopOfTemporaryRam value in SecPpiList. + + @param[in,out] SecPpiList PPI list to be patched. + @param[in] TopOfTemporaryRam The top of Temporary Ram. + +**/ +VOID +PatchTopOfTemporaryRamPpi ( + IN OUT EFI_PEI_PPI_DESCRIPTOR *SecPpiList, + IN VOID *TopOfTemporaryRam + ) +{ + SecPpiList[0].Ppi = TopOfTemporaryRam; +} + +/** + 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_PPI_DESCRIPTOR *PpiList; + UINT32 Index; + EFI_PEI_PPI_DESCRIPTOR LocalSecPpiList[sizeof(mPeiSecMainPpi)/sizeof(mPeiSecMainPpi[0])]; + EFI_PEI_PPI_DESCRIPTOR AllSecPpiList[FixedPcdGet32(PcdSecCoreMaxPpiSupported)]; + 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 (); + } + + CopyMem (LocalSecPpiList, mPeiSecMainPpi, sizeof(mPeiSecMainPpi)); + PatchTopOfTemporaryRamPpi (LocalSecPpiList, (VOID *)((UINTN)SecCoreData->TemporaryRamBase + SecCoreData->TemporaryRamSize)); + + // + // Perform platform specific initialization before entering PeiCore. + // + PpiList = SecPlatformMain (SecCoreData); + if (PpiList != NULL) { + // + // Remove the terminal flag from the terminal Ppi + // + CopyMem (AllSecPpiList, LocalSecPpiList, sizeof (LocalSecPpiList)); + for (Index = 0; Index < PcdGet32 (PcdSecCoreMaxPpiSupported); Index ++) { + if ((AllSecPpiList[Index].Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) == EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) { + break; + } + } + AllSecPpiList[Index].Flags = AllSecPpiList[Index].Flags & (~EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST); + + // + // Append the platform additional Ppi list + // + Index += 1; + while (Index < PcdGet32 (PcdSecCoreMaxPpiSupported) && + ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) != EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST)) { + CopyMem (&AllSecPpiList[Index], PpiList, sizeof (EFI_PEI_PPI_DESCRIPTOR)); + Index++; + PpiList++; + } + + // + // Check whether the total Ppis exceeds the max supported Ppi. + // + if (Index >= PcdGet32 (PcdSecCoreMaxPpiSupported)) { + // + // the total Ppi is larger than the supported Max + // PcdSecCoreMaxPpiSupported can be enlarged to solve it. + // + CpuDeadLoop (); + } else { + // + // Add the terminal Ppi + // + CopyMem (&AllSecPpiList[Index], PpiList, sizeof (EFI_PEI_PPI_DESCRIPTOR)); + } + + // + // Set PpiList to the total Ppi + // + PpiList = &AllSecPpiList[0]; + } else { + // + // No addition Ppi, PpiList directly point to the common Ppi list. + // + PpiList = &LocalSecPpiList[0]; + } + + // + // Transfer the control to the PEI core + // + ASSERT (PeiCoreEntryPoint != NULL); + (*PeiCoreEntryPoint) (SecCoreData, PpiList); + + // + // Should not come here. + // + return ; +} diff --git a/IntelFspWrapperPkg/FspInitPei/SecMain.h b/IntelFspWrapperPkg/FspInitPei/SecMain.h new file mode 100644 index 0000000000..fc203973da --- /dev/null +++ b/IntelFspWrapperPkg/FspInitPei/SecMain.h @@ -0,0 +1,116 @@ +/** @file + Master header file for SecCore. + + 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 _SEC_CORE_H_ +#define _SEC_CORE_H_ + + +#include + +#include +#include + +#include +#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; + +/** + 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] SizeOfRam Size of the temporary memory available for use. + @param[in] TempRamBase Base address of tempory ram + @param[in] 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[in] BootFirmwareVolumePtr Point to the boot firmware volume. + @param[out] 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 + ); + +/** + Return Hob list produced by FSP. + + @param[in] PeiServices The pointer to the PEI Services Table. + @param[in] This The pointer to this instance of this PPI. + @param[out] FspHobList The pointer to Hob list produced by FSP. + + @return EFI_SUCCESS FReturn Hob list produced by FSP successfully. +**/ +EFI_STATUS +EFIAPI +FspInitDoneGetFspHobList ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN FSP_INIT_DONE_PPI *This, + OUT VOID **FspHobList + ); + +extern FSP_INIT_DONE_PPI gFspInitDonePpi; + +#endif -- cgit v1.2.3