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