Home | History | Annotate | Download | only in FspInitPei
      1 /** @file
      2   Locate the entry point for the PEI Core
      3 
      4   Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
      5   This program and the accompanying materials
      6   are licensed and made available under the terms and conditions of the BSD License
      7   which accompanies this distribution.  The full text of the license may be found at
      8   http://opensource.org/licenses/bsd-license.php.
      9 
     10   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 #include <PiPei.h>
     16 #include <Library/BaseLib.h>
     17 #include <Library/PeCoffGetEntryPointLib.h>
     18 
     19 #include "SecMain.h"
     20 
     21 /**
     22   Find core image base.
     23 
     24   @param[in]  BootFirmwareVolumePtr    Point to the boot firmware volume.
     25   @param[out] SecCoreImageBase         The base address of the SEC core image.
     26   @param[out] PeiCoreImageBase         The base address of the PEI core image.
     27 
     28 **/
     29 EFI_STATUS
     30 EFIAPI
     31 FindImageBase (
     32   IN  EFI_FIRMWARE_VOLUME_HEADER       *BootFirmwareVolumePtr,
     33   OUT EFI_PHYSICAL_ADDRESS             *SecCoreImageBase,
     34   OUT EFI_PHYSICAL_ADDRESS             *PeiCoreImageBase
     35   )
     36 {
     37   EFI_PHYSICAL_ADDRESS        CurrentAddress;
     38   EFI_PHYSICAL_ADDRESS        EndOfFirmwareVolume;
     39   EFI_FFS_FILE_HEADER         *File;
     40   UINT32                      Size;
     41   EFI_PHYSICAL_ADDRESS        EndOfFile;
     42   EFI_COMMON_SECTION_HEADER   *Section;
     43   EFI_PHYSICAL_ADDRESS        EndOfSection;
     44 
     45   *SecCoreImageBase = 0;
     46   *PeiCoreImageBase = 0;
     47 
     48   CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) BootFirmwareVolumePtr;
     49   EndOfFirmwareVolume = CurrentAddress + BootFirmwareVolumePtr->FvLength;
     50 
     51   //
     52   // Loop through the FFS files in the Boot Firmware Volume
     53   //
     54   for (EndOfFile = CurrentAddress + BootFirmwareVolumePtr->HeaderLength; ; ) {
     55 
     56     CurrentAddress = (EndOfFile + 7) & 0xfffffffffffffff8ULL;
     57     if (CurrentAddress > EndOfFirmwareVolume) {
     58       return EFI_NOT_FOUND;
     59     }
     60 
     61     File = (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress;
     62     if (IS_FFS_FILE2 (File)) {
     63       Size = FFS_FILE2_SIZE (File);
     64       if (Size <= 0x00FFFFFF) {
     65         return EFI_NOT_FOUND;
     66       }
     67     } else {
     68       Size = FFS_FILE_SIZE (File);
     69       if (Size < sizeof (EFI_FFS_FILE_HEADER)) {
     70         return EFI_NOT_FOUND;
     71       }
     72     }
     73 
     74     EndOfFile = CurrentAddress + Size;
     75     if (EndOfFile > EndOfFirmwareVolume) {
     76       return EFI_NOT_FOUND;
     77     }
     78 
     79     //
     80     // Look for SEC Core / PEI Core files
     81     //
     82     if (File->Type != EFI_FV_FILETYPE_SECURITY_CORE &&
     83         File->Type != EFI_FV_FILETYPE_PEI_CORE) {
     84       continue;
     85     }
     86 
     87     //
     88     // Loop through the FFS file sections within the FFS file
     89     //
     90     if (IS_FFS_FILE2 (File)) {
     91       EndOfSection = (EFI_PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) File + sizeof (EFI_FFS_FILE_HEADER2));
     92     } else {
     93       EndOfSection = (EFI_PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) File + sizeof (EFI_FFS_FILE_HEADER));
     94     }
     95     for (;;) {
     96       CurrentAddress = (EndOfSection + 3) & 0xfffffffffffffffcULL;
     97       Section = (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress;
     98 
     99       if (IS_SECTION2 (Section)) {
    100         Size = SECTION2_SIZE (Section);
    101         if (Size <= 0x00FFFFFF) {
    102           return EFI_NOT_FOUND;
    103         }
    104       } else {
    105         Size = SECTION_SIZE (Section);
    106         if (Size < sizeof (EFI_COMMON_SECTION_HEADER)) {
    107           return EFI_NOT_FOUND;
    108         }
    109       }
    110 
    111       EndOfSection = CurrentAddress + Size;
    112       if (EndOfSection > EndOfFile) {
    113         return EFI_NOT_FOUND;
    114       }
    115 
    116       //
    117       // Look for executable sections
    118       //
    119       if (Section->Type == EFI_SECTION_PE32 || Section->Type == EFI_SECTION_TE) {
    120         if (File->Type == EFI_FV_FILETYPE_SECURITY_CORE) {
    121           if (IS_SECTION2 (Section)) {
    122             *SecCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER2));
    123           } else {
    124             *SecCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER));
    125           }
    126         } else {
    127           if (IS_SECTION2 (Section)) {
    128             *PeiCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER2));
    129           } else {
    130             *PeiCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) ((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER));
    131           }
    132         }
    133         break;
    134       }
    135     }
    136 
    137     //
    138     // Both SEC Core and PEI Core images found
    139     //
    140     if (*SecCoreImageBase != 0 && *PeiCoreImageBase != 0) {
    141       return EFI_SUCCESS;
    142     }
    143   }
    144 }
    145 
    146 /**
    147   Find and return Pei Core entry point.
    148 
    149   It also find SEC and PEI Core file debug information. It will report them if
    150   remote debug is enabled.
    151 
    152   @param[in]  BootFirmwareVolumePtr    Point to the boot firmware volume.
    153   @param[out] PeiCoreEntryPoint        The entry point of the PEI core.
    154 
    155 **/
    156 VOID
    157 EFIAPI
    158 FindAndReportEntryPoints (
    159   IN  EFI_FIRMWARE_VOLUME_HEADER       *BootFirmwareVolumePtr,
    160   OUT EFI_PEI_CORE_ENTRY_POINT         *PeiCoreEntryPoint
    161   )
    162 {
    163   EFI_STATUS                       Status;
    164   EFI_PHYSICAL_ADDRESS             SecCoreImageBase;
    165   EFI_PHYSICAL_ADDRESS             PeiCoreImageBase;
    166   PE_COFF_LOADER_IMAGE_CONTEXT     ImageContext;
    167 
    168   //
    169   // Find SEC Core and PEI Core image base
    170   //
    171   Status = FindImageBase (BootFirmwareVolumePtr, &SecCoreImageBase, &PeiCoreImageBase);
    172   ASSERT_EFI_ERROR (Status);
    173 
    174   ZeroMem ((VOID *) &ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT));
    175   //
    176   // Report SEC Core debug information when remote debug is enabled
    177   //
    178   ImageContext.ImageAddress = SecCoreImageBase;
    179   ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageContext.ImageAddress);
    180   PeCoffLoaderRelocateImageExtraAction (&ImageContext);
    181 
    182   //
    183   // Report PEI Core debug information when remote debug is enabled
    184   //
    185   ImageContext.ImageAddress = PeiCoreImageBase;
    186   ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageContext.ImageAddress);
    187   PeCoffLoaderRelocateImageExtraAction (&ImageContext);
    188 
    189   //
    190   // Find PEI Core entry point
    191   //
    192   Status = PeCoffLoaderGetEntryPoint ((VOID *) (UINTN) PeiCoreImageBase, (VOID**) PeiCoreEntryPoint);
    193   if (EFI_ERROR (Status)) {
    194     *PeiCoreEntryPoint = 0;
    195   }
    196 
    197   return;
    198 }
    199 
    200