2 Locate the entry point for the PEI Core
4 Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include <Library/BaseLib.h>
18 #include <Library/BaseMemoryLib.h>
19 #include <Library/DebugLib.h>
20 #include <Library/ExtractGuidedSectionLib.h>
21 #include <Library/PcdLib.h>
22 #include <Library/PeCoffGetEntryPointLib.h>
28 Locates the main boot firmware volume.
30 @param[in,out] BootFv On input, the base of the BootFv
31 On output, the decompressed main firmware volume
33 @retval EFI_SUCCESS The main firmware volume was located and decompressed
34 @retval EFI_NOT_FOUND The main firmware volume was not found
39 IN OUT EFI_FIRMWARE_VOLUME_HEADER
**BootFv
42 EFI_FIRMWARE_VOLUME_HEADER
*Fv
;
46 ASSERT (((UINTN
) *BootFv
& EFI_PAGE_MASK
) == 0);
50 Distance
= (UINTN
) (*BootFv
)->FvLength
;
52 Fv
= (EFI_FIRMWARE_VOLUME_HEADER
*) ((UINT8
*) Fv
- EFI_PAGE_SIZE
);
53 Distance
+= EFI_PAGE_SIZE
;
54 if (Distance
> SIZE_32MB
) {
58 if (Fv
->Signature
!= EFI_FVH_SIGNATURE
) {
62 if ((UINTN
) Fv
->FvLength
> Distance
) {
74 Locates a section within a series of sections
75 with the specified section type.
77 @param[in] Sections The sections to search
78 @param[in] SizeOfSections Total size of all sections
79 @param[in] SectionType The section type to locate
80 @param[out] FoundSection The FFS section if found
82 @retval EFI_SUCCESS The file and section was found
83 @retval EFI_NOT_FOUND The file and section was not found
84 @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
88 FindFfsSectionInSections (
90 IN UINTN SizeOfSections
,
91 IN EFI_SECTION_TYPE SectionType
,
92 OUT EFI_COMMON_SECTION_HEADER
**FoundSection
95 EFI_PHYSICAL_ADDRESS CurrentAddress
;
97 EFI_PHYSICAL_ADDRESS EndOfSections
;
98 EFI_COMMON_SECTION_HEADER
*Section
;
99 EFI_PHYSICAL_ADDRESS EndOfSection
;
102 // Loop through the FFS file sections within the PEI Core FFS file
104 EndOfSection
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) Sections
;
105 EndOfSections
= EndOfSection
+ SizeOfSections
;
107 if (EndOfSection
== EndOfSections
) {
110 CurrentAddress
= (EndOfSection
+ 3) & ~(3ULL);
111 if (CurrentAddress
>= EndOfSections
) {
112 return EFI_VOLUME_CORRUPTED
;
115 Section
= (EFI_COMMON_SECTION_HEADER
*)(UINTN
) CurrentAddress
;
116 DEBUG ((EFI_D_INFO
, "Section->Type: 0x%x\n", Section
->Type
));
118 Size
= SECTION_SIZE (Section
);
119 if (Size
< sizeof (*Section
)) {
120 return EFI_VOLUME_CORRUPTED
;
123 EndOfSection
= CurrentAddress
+ Size
;
124 if (EndOfSection
> EndOfSections
) {
125 return EFI_VOLUME_CORRUPTED
;
129 // Look for the requested section type
131 if (Section
->Type
== SectionType
) {
132 *FoundSection
= Section
;
135 DEBUG ((EFI_D_INFO
, "Section->Type (0x%x) != SectionType (0x%x)\n", Section
->Type
, SectionType
));
138 return EFI_NOT_FOUND
;
143 Locates a FFS file with the specified file type and a section
144 within that file with the specified section type.
146 @param[in] Fv The firmware volume to search
147 @param[in] FileType The file type to locate
148 @param[in] SectionType The section type to locate
149 @param[out] FoundSection The FFS section if found
151 @retval EFI_SUCCESS The file and section was found
152 @retval EFI_NOT_FOUND The file and section was not found
153 @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
158 FindFfsFileAndSection (
159 IN EFI_FIRMWARE_VOLUME_HEADER
*Fv
,
160 IN EFI_FV_FILETYPE FileType
,
161 IN EFI_SECTION_TYPE SectionType
,
162 OUT EFI_COMMON_SECTION_HEADER
**FoundSection
166 EFI_PHYSICAL_ADDRESS CurrentAddress
;
167 EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume
;
168 EFI_FFS_FILE_HEADER
*File
;
170 EFI_PHYSICAL_ADDRESS EndOfFile
;
172 if (Fv
->Signature
!= EFI_FVH_SIGNATURE
) {
173 DEBUG ((EFI_D_INFO
, "FV at %p does not have FV header signature\n", Fv
));
174 return EFI_VOLUME_CORRUPTED
;
177 CurrentAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) Fv
;
178 EndOfFirmwareVolume
= CurrentAddress
+ Fv
->FvLength
;
181 // Loop through the FFS files in the Boot Firmware Volume
183 for (EndOfFile
= CurrentAddress
+ Fv
->HeaderLength
; ; ) {
185 CurrentAddress
= (EndOfFile
+ 7) & ~(7ULL);
186 if (CurrentAddress
> EndOfFirmwareVolume
) {
187 return EFI_VOLUME_CORRUPTED
;
190 File
= (EFI_FFS_FILE_HEADER
*)(UINTN
) CurrentAddress
;
191 Size
= *(UINT32
*) File
->Size
& 0xffffff;
192 if (Size
< (sizeof (*File
) + sizeof (EFI_COMMON_SECTION_HEADER
))) {
193 return EFI_VOLUME_CORRUPTED
;
195 DEBUG ((EFI_D_INFO
, "File->Type: 0x%x\n", File
->Type
));
197 EndOfFile
= CurrentAddress
+ Size
;
198 if (EndOfFile
> EndOfFirmwareVolume
) {
199 return EFI_VOLUME_CORRUPTED
;
203 // Look for the request file type
205 if (File
->Type
!= FileType
) {
206 DEBUG ((EFI_D_INFO
, "File->Type (0x%x) != FileType (0x%x)\n", File
->Type
, FileType
));
210 Status
= FindFfsSectionInSections (
212 (UINTN
) EndOfFile
- (UINTN
) (File
+ 1),
216 if (!EFI_ERROR (Status
) || (Status
== EFI_VOLUME_CORRUPTED
)) {
224 Locates the compressed main firmware volume and decompresses it.
226 @param[in,out] Fv On input, the firmware volume to search
227 On output, the decompressed main FV
229 @retval EFI_SUCCESS The file and section was found
230 @retval EFI_NOT_FOUND The file and section was not found
231 @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
237 IN OUT EFI_FIRMWARE_VOLUME_HEADER
**Fv
241 EFI_GUID_DEFINED_SECTION
*Section
;
242 UINT32 OutputBufferSize
;
243 UINT32 ScratchBufferSize
;
244 UINT16 SectionAttribute
;
245 UINT32 AuthenticationStatus
;
248 EFI_FIRMWARE_VOLUME_IMAGE_SECTION
*NewFvSection
;
249 EFI_FIRMWARE_VOLUME_HEADER
*NewFv
;
251 NewFvSection
= (EFI_FIRMWARE_VOLUME_IMAGE_SECTION
*) NULL
;
253 Status
= FindFfsFileAndSection (
255 EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
,
256 EFI_SECTION_GUID_DEFINED
,
257 (EFI_COMMON_SECTION_HEADER
**) &Section
259 if (EFI_ERROR (Status
)) {
260 DEBUG ((EFI_D_ERROR
, "Unable to find GUID defined section\n"));
264 Status
= ExtractGuidedSectionGetInfo (
270 if (EFI_ERROR (Status
)) {
271 DEBUG ((EFI_D_ERROR
, "Unable to GetInfo for GUIDed section\n"));
275 //PcdGet32 (PcdOvmfMemFvBase), PcdGet32 (PcdOvmfMemFvSize)
276 OutputBuffer
= (VOID
*) ((UINT8
*)(UINTN
) PcdGet32 (PcdOvmfMemFvBase
) + SIZE_1MB
);
277 ScratchBuffer
= ALIGN_POINTER ((UINT8
*) OutputBuffer
+ OutputBufferSize
, SIZE_1MB
);
278 Status
= ExtractGuidedSectionDecode (
282 &AuthenticationStatus
284 if (EFI_ERROR (Status
)) {
285 DEBUG ((EFI_D_ERROR
, "Error during GUID section decode\n"));
289 Status
= FindFfsSectionInSections (
292 EFI_SECTION_FIRMWARE_VOLUME_IMAGE
,
293 (EFI_COMMON_SECTION_HEADER
**) &NewFvSection
295 if (EFI_ERROR (Status
)) {
296 DEBUG ((EFI_D_ERROR
, "Unable to find FV image in extracted data\n"));
300 NewFv
= (EFI_FIRMWARE_VOLUME_HEADER
*)(UINTN
) PcdGet32 (PcdOvmfMemFvBase
);
301 CopyMem (NewFv
, (VOID
*) (NewFvSection
+ 1), PcdGet32 (PcdOvmfMemFvSize
));
303 if (NewFv
->Signature
!= EFI_FVH_SIGNATURE
) {
304 DEBUG ((EFI_D_ERROR
, "Extracted FV at %p does not have FV header signature\n", NewFv
));
306 return EFI_VOLUME_CORRUPTED
;
315 Locates the PEI Core entry point address
317 @param[in] Fv The firmware volume to search
318 @param[out] PeiCoreEntryPoint The entry point of the PEI Core image
320 @retval EFI_SUCCESS The file and section was found
321 @retval EFI_NOT_FOUND The file and section was not found
322 @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
327 FindPeiCoreEntryPointInFv (
328 IN EFI_FIRMWARE_VOLUME_HEADER
*Fv
,
329 OUT VOID
**PeiCoreEntryPoint
333 EFI_COMMON_SECTION_HEADER
*Section
;
335 Status
= FindFfsFileAndSection (
337 EFI_FV_FILETYPE_PEI_CORE
,
341 if (EFI_ERROR (Status
)) {
342 Status
= FindFfsFileAndSection (
344 EFI_FV_FILETYPE_PEI_CORE
,
348 if (EFI_ERROR (Status
)) {
349 DEBUG ((EFI_D_ERROR
, "Unable to find PEI Core image\n"));
354 return PeCoffLoaderGetEntryPoint ((VOID
*) (Section
+ 1), PeiCoreEntryPoint
);
359 Locates the PEI Core entry point address
361 @param[in,out] Fv The firmware volume to search
362 @param[out] PeiCoreEntryPoint The entry point of the PEI Core image
364 @retval EFI_SUCCESS The file and section was found
365 @retval EFI_NOT_FOUND The file and section was not found
366 @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
371 FindPeiCoreEntryPoint (
372 IN OUT EFI_FIRMWARE_VOLUME_HEADER
**BootFv
,
373 OUT VOID
**PeiCoreEntryPoint
376 *PeiCoreEntryPoint
= NULL
;
380 DecompressGuidedFv (BootFv
);
382 FindPeiCoreEntryPointInFv (*BootFv
, PeiCoreEntryPoint
);