• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
FindImageBase(IN EFI_FIRMWARE_VOLUME_HEADER * BootFirmwareVolumePtr,OUT EFI_PHYSICAL_ADDRESS * SecCoreImageBase,OUT EFI_PHYSICAL_ADDRESS * PeiCoreImageBase)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
FindAndReportEntryPoints(IN EFI_FIRMWARE_VOLUME_HEADER * BootFirmwareVolumePtr,OUT EFI_PEI_CORE_ENTRY_POINT * PeiCoreEntryPoint)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