audk/UefiCpuPkg/SecCore/FindPeiCore.c

224 lines
6.4 KiB
C

/** @file
Locate the entry point for the PEI Core
Copyright (c) 2008 - 2019, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <PiPei.h>
#include "SecMain.h"
/**
Find core image base.
@param FirmwareVolumePtr Point to the firmware volume for finding core image.
@param FileType The FileType for searching, either SecCore or PeiCore.
@param CoreImageBase The base address of the core image.
**/
EFI_STATUS
EFIAPI
FindImageBase (
IN EFI_FIRMWARE_VOLUME_HEADER *FirmwareVolumePtr,
IN EFI_FV_FILETYPE FileType,
OUT EFI_PHYSICAL_ADDRESS *CoreImageBase,
OUT UINT32 *CoreImageSize
)
{
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;
*CoreImageBase = 0;
CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)FirmwareVolumePtr;
EndOfFirmwareVolume = CurrentAddress + FirmwareVolumePtr->FvLength;
//
// Loop through the FFS files in the Boot Firmware Volume
//
for (EndOfFile = CurrentAddress + FirmwareVolumePtr->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 particular Core file (either SEC Core or PEI Core)
//
if (File->Type != FileType) {
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) {
if (File->Type == FileType) {
if (IS_SECTION2 (Section)) {
*CoreImageBase = (PHYSICAL_ADDRESS)(UINTN)((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER2));
*CoreImageSize = Size - sizeof (EFI_COMMON_SECTION_HEADER2);
} else {
*CoreImageBase = (PHYSICAL_ADDRESS)(UINTN)((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER));
*CoreImageSize = Size - sizeof (EFI_COMMON_SECTION_HEADER);
}
}
break;
}
}
//
// Either SEC Core or PEI Core images found
//
if (*CoreImageBase != 0) {
return EFI_SUCCESS;
}
}
}
/**
Find and return Pei Core entry point.
It also find SEC and PEI Core file debug information. It will report them if
remote debug is enabled.
@param SecCoreFirmwareVolumePtr Point to the firmware volume for finding SecCore.
@param PeiCoreFirmwareVolumePtr Point to the firmware volume for finding PeiCore.
@param PeiCoreEntryPoint The entry point of the PEI core.
**/
VOID
EFIAPI
FindAndReportEntryPoints (
IN EFI_FIRMWARE_VOLUME_HEADER *SecCoreFirmwareVolumePtr,
IN EFI_FIRMWARE_VOLUME_HEADER *PeiCoreFirmwareVolumePtr,
OUT EFI_PEI_CORE_ENTRY_POINT *PeiCoreEntryPoint
)
{
EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS SecCoreImageBase;
UINT32 SecCoreImageSize;
EFI_PHYSICAL_ADDRESS PeiCoreImageBase;
UINT32 PeiCoreImageSize;
UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
//
// Find SEC Core image base
//
Status = FindImageBase (
SecCoreFirmwareVolumePtr,
EFI_FV_FILETYPE_SECURITY_CORE,
&SecCoreImageBase,
&SecCoreImageSize
);
ASSERT_EFI_ERROR (Status);
// FIXME: DEBUG-only
Status = UefiImageInitializeContext (
&ImageContext,
(VOID*) (UINTN) SecCoreImageBase,
SecCoreImageSize,
UEFI_IMAGE_SOURCE_FV,
UefiImageOriginFv
);
ASSERT_EFI_ERROR (Status);
Status = UefiImageLoadImageInplace (&ImageContext);
ASSERT_EFI_ERROR (Status);
//
// Report SEC Core debug information when remote debug is enabled
//
UefiImageLoaderRelocateImageExtraAction (&ImageContext);
//
// Find PEI Core image base
//
Status = FindImageBase (
PeiCoreFirmwareVolumePtr,
EFI_FV_FILETYPE_PEI_CORE,
&PeiCoreImageBase,
&PeiCoreImageSize
);
ASSERT_EFI_ERROR (Status);
Status = UefiImageInitializeContext (
&ImageContext,
(VOID*)(UINTN)PeiCoreImageBase,
PeiCoreImageSize,
UEFI_IMAGE_SOURCE_FV,
UefiImageOriginFv
);
ASSERT_EFI_ERROR (Status);
Status = UefiImageLoadImageInplace (&ImageContext);
ASSERT_EFI_ERROR (Status);
//
// Report PEI Core debug information when remote debug is enabled
//
UefiImageLoaderRelocateImageExtraAction (&ImageContext);
//
// Find PEI Core entry point
//
*PeiCoreEntryPoint = (EFI_PEI_CORE_ENTRY_POINT) (UINTN) (UefiImageLoaderGetImageEntryPoint (&ImageContext));
return;
}