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