Add IntelFspWrapper to support boot EDKII on FSP bin.

Contributed-under: TianoCore Contribution Agreement 1.0

Signed off by: Jiewen Yao <jiewen.yao@intel.com>
Reviewed by: Ravi Rangarajan <ravi.p.rangarajan@intel.com>
Reviewed by: Maurice Ma <maurice.ma@intel.com>
Reviewed by: Giri Mudusuru <giri.p.mudusuru@intel.com>
Reviewed by: Liming Gao <liming.gao@intel.com>


git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15676 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
jyao1
2014-07-24 06:52:43 +00:00
committed by jyao1
parent 34717ef034
commit a33a2f6221
61 changed files with 6577 additions and 0 deletions

View File

@@ -0,0 +1,199 @@
/** @file
Locate the entry point for the PEI Core
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include <PiPei.h>
#include <Library/BaseLib.h>
#include <Library/PeCoffGetEntryPointLib.h>
#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;
}

View File

@@ -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.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "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;
}

View File

@@ -0,0 +1,38 @@
/** @file
This is PEIM header file.
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _FSP_INIT_PEI_H_
#define _FSP_INIT_PEI_H_
#include <PiPei.h>
#include <Library/PeimEntryPoint.h>
#include <Library/PeiServicesLib.h>
#include <Library/PeiServicesTablePointerLib.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/HobLib.h>
#include <Library/PcdLib.h>
#include <Library/FspPlatformInfoLib.h>
#include <Library/FspPlatformSecLib.h>
#include <Library/FspHobProcessLib.h>
#include <Library/FspApiLib.h>
#include <Ppi/FspInitDone.h>
#include <Ppi/EndOfPeiPhase.h>
extern EFI_PEI_NOTIFY_DESCRIPTOR mS3EndOfPeiNotifyDesc;
#endif

View File

@@ -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.<BR>
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php.
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
##
[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

View File

@@ -0,0 +1,86 @@
/** @file
In EndOfPei notify, it will call FspNotifyPhase API.
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "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;
}

View File

@@ -0,0 +1,57 @@
/** @file
Install FspInitDone PPI and GetFspHobList API.
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "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;
}

View File

@@ -0,0 +1,269 @@
/** @file
C functions in SEC
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "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 ;
}

View File

@@ -0,0 +1,116 @@
/** @file
Master header file for SecCore.
Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _SEC_CORE_H_
#define _SEC_CORE_H_
#include <PiPei.h>
#include <Ppi/TopOfTemporaryRam.h>
#include <Ppi/FspInitDone.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/PcdLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/FspPlatformSecLib.h>
#include <Library/FspPlatformInfoLib.h>
#include <Library/UefiCpuLib.h>
#include <Library/PeCoffGetEntryPointLib.h>
#include <Library/PeCoffExtraActionLib.h>
#include <Library/DebugAgentLib.h>
#include <FspApi.h>
#include <FspInfoHeader.h>
#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