3 Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
9 #include "UefiPayloadEntry.h"
12 Allocate pages for code.
14 @param[in] Pages Number of pages to be allocated.
16 @return Allocated memory.
24 EFI_PEI_HOB_POINTERS Hob
;
26 Alloc
= AllocatePages (Pages
);
31 // find the HOB we just created, and change the type to EfiBootServicesCode
32 Hob
.Raw
= GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION
);
33 while (Hob
.Raw
!= NULL
) {
34 if (Hob
.MemoryAllocation
->AllocDescriptor
.MemoryBaseAddress
== (UINTN
)Alloc
) {
35 Hob
.MemoryAllocation
->AllocDescriptor
.MemoryType
= EfiBootServicesCode
;
39 Hob
.Raw
= GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION
, GET_NEXT_HOB (Hob
));
44 FreePages (Alloc
, Pages
);
49 Loads and relocates a PE/COFF image
51 @param[in] PeCoffImage Point to a Pe/Coff image.
52 @param[out] ImageAddress The image memory address after relocation.
53 @param[out] ImageSize The image size.
54 @param[out] EntryPoint The image entry point.
56 @return EFI_SUCCESS If the image is loaded and relocated successfully.
57 @return Others If the image failed to load or relocate.
62 OUT EFI_PHYSICAL_ADDRESS
*ImageAddress
,
63 OUT UINT64
*ImageSize
,
64 OUT EFI_PHYSICAL_ADDRESS
*EntryPoint
68 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext
;
71 ZeroMem (&ImageContext
, sizeof (ImageContext
));
73 ImageContext
.Handle
= PeCoffImage
;
74 ImageContext
.ImageRead
= PeCoffLoaderImageReadFromMemory
;
76 Status
= PeCoffLoaderGetImageInfo (&ImageContext
);
77 if (EFI_ERROR (Status
)) {
78 ASSERT_EFI_ERROR (Status
);
83 // Allocate Memory for the image
85 Buffer
= AllocateCodePages (EFI_SIZE_TO_PAGES ((UINT32
)ImageContext
.ImageSize
));
87 return EFI_OUT_OF_RESOURCES
;
90 ImageContext
.ImageAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)Buffer
;
93 // Load the image to our new buffer
95 Status
= PeCoffLoaderLoadImage (&ImageContext
);
96 if (EFI_ERROR (Status
)) {
97 ASSERT_EFI_ERROR (Status
);
102 // Relocate the image in our new buffer
104 Status
= PeCoffLoaderRelocateImage (&ImageContext
);
105 if (EFI_ERROR (Status
)) {
106 ASSERT_EFI_ERROR (Status
);
110 *ImageAddress
= ImageContext
.ImageAddress
;
111 *ImageSize
= ImageContext
.ImageSize
;
112 *EntryPoint
= ImageContext
.EntryPoint
;
118 This function searchs a given file type with a given Guid within a valid FV.
119 If input Guid is NULL, will locate the first section having the given file type
121 @param FvHeader A pointer to firmware volume header that contains the set of files
123 @param FileType File type to be searched.
124 @param Guid Will ignore if it is NULL.
125 @param FileHeader A pointer to the discovered file, if successful.
127 @retval EFI_SUCCESS Successfully found FileType
128 @retval EFI_NOT_FOUND File type can't be found.
131 FvFindFileByTypeGuid (
132 IN EFI_FIRMWARE_VOLUME_HEADER
*FvHeader
,
133 IN EFI_FV_FILETYPE FileType
,
134 IN EFI_GUID
*Guid OPTIONAL
,
135 OUT EFI_FFS_FILE_HEADER
**FileHeader
138 EFI_PHYSICAL_ADDRESS CurrentAddress
;
139 EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume
;
140 EFI_FFS_FILE_HEADER
*File
;
142 EFI_PHYSICAL_ADDRESS EndOfFile
;
144 CurrentAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)FvHeader
;
145 EndOfFirmwareVolume
= CurrentAddress
+ FvHeader
->FvLength
;
148 // Loop through the FFS files
150 for (EndOfFile
= CurrentAddress
+ FvHeader
->HeaderLength
; ; ) {
151 CurrentAddress
= (EndOfFile
+ 7) & 0xfffffffffffffff8ULL
;
152 if (CurrentAddress
> EndOfFirmwareVolume
) {
156 File
= (EFI_FFS_FILE_HEADER
*)(UINTN
)CurrentAddress
;
157 if (IS_FFS_FILE2 (File
)) {
158 Size
= FFS_FILE2_SIZE (File
);
159 if (Size
<= 0x00FFFFFF) {
163 Size
= FFS_FILE_SIZE (File
);
164 if (Size
< sizeof (EFI_FFS_FILE_HEADER
)) {
169 EndOfFile
= CurrentAddress
+ Size
;
170 if (EndOfFile
> EndOfFirmwareVolume
) {
175 // Look for file type
177 if (File
->Type
== FileType
) {
178 if ((Guid
== NULL
) || CompareGuid (&File
->Name
, Guid
)) {
185 return EFI_NOT_FOUND
;
189 This function searchs a given section type within a valid FFS file.
191 @param FileHeader A pointer to the file header that contains the set of sections to
193 @param SectionType The value of the section type to search.
194 @param SectionData A pointer to the discovered section, if successful.
196 @retval EFI_SUCCESS The section was found.
197 @retval EFI_NOT_FOUND The section was not found.
202 IN EFI_FFS_FILE_HEADER
*FileHeader
,
203 IN EFI_SECTION_TYPE SectionType
,
204 OUT VOID
**SectionData
208 EFI_COMMON_SECTION_HEADER
*Section
;
212 if (IS_FFS_FILE2 (FileHeader
)) {
213 FileSize
= FFS_FILE2_SIZE (FileHeader
);
215 FileSize
= FFS_FILE_SIZE (FileHeader
);
218 FileSize
-= sizeof (EFI_FFS_FILE_HEADER
);
220 Section
= (EFI_COMMON_SECTION_HEADER
*)(FileHeader
+ 1);
222 while (Index
< FileSize
) {
223 if (Section
->Type
== SectionType
) {
224 if (IS_SECTION2 (Section
)) {
225 *SectionData
= (VOID
*)((UINT8
*)Section
+ sizeof (EFI_COMMON_SECTION_HEADER2
));
227 *SectionData
= (VOID
*)((UINT8
*)Section
+ sizeof (EFI_COMMON_SECTION_HEADER
));
233 if (IS_SECTION2 (Section
)) {
234 SectionSize
= SECTION2_SIZE (Section
);
236 SectionSize
= SECTION_SIZE (Section
);
239 SectionSize
= GET_OCCUPIED_SIZE (SectionSize
, 4);
240 ASSERT (SectionSize
!= 0);
241 Index
+= SectionSize
;
243 Section
= (EFI_COMMON_SECTION_HEADER
*)((UINT8
*)Section
+ SectionSize
);
246 return EFI_NOT_FOUND
;
250 Find DXE core from FV and build DXE core HOBs.
252 @param[out] DxeCoreEntryPoint DXE core entry point
254 @retval EFI_SUCCESS If it completed successfully.
255 @retval EFI_NOT_FOUND If it failed to load DXE FV.
259 OUT PHYSICAL_ADDRESS
*DxeCoreEntryPoint
263 EFI_FIRMWARE_VOLUME_HEADER
*PayloadFv
;
264 EFI_FIRMWARE_VOLUME_HEADER
*DxeCoreFv
;
265 EFI_FFS_FILE_HEADER
*FileHeader
;
267 EFI_PHYSICAL_ADDRESS ImageAddress
;
270 PayloadFv
= (EFI_FIRMWARE_VOLUME_HEADER
*)(UINTN
)PcdGet32 (PcdPayloadFdMemBase
);
273 // DXE FV is inside Payload FV. Here find DXE FV from Payload FV
275 Status
= FvFindFileByTypeGuid (PayloadFv
, EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
, NULL
, &FileHeader
);
276 if (EFI_ERROR (Status
)) {
280 Status
= FileFindSection (FileHeader
, EFI_SECTION_FIRMWARE_VOLUME_IMAGE
, (VOID
**)&DxeCoreFv
);
281 if (EFI_ERROR (Status
)) {
286 // Report DXE FV to DXE core
288 BuildFvHob ((EFI_PHYSICAL_ADDRESS
)(UINTN
)DxeCoreFv
, DxeCoreFv
->FvLength
);
291 // Find DXE core file from DXE FV
293 Status
= FvFindFileByTypeGuid (DxeCoreFv
, EFI_FV_FILETYPE_DXE_CORE
, NULL
, &FileHeader
);
294 if (EFI_ERROR (Status
)) {
298 Status
= FileFindSection (FileHeader
, EFI_SECTION_PE32
, (VOID
**)&PeCoffImage
);
299 if (EFI_ERROR (Status
)) {
306 Status
= LoadPeCoffImage (PeCoffImage
, &ImageAddress
, &ImageSize
, DxeCoreEntryPoint
);
307 if (EFI_ERROR (Status
)) {
311 BuildModuleHob (&FileHeader
->Name
, ImageAddress
, EFI_SIZE_TO_PAGES ((UINT32
)ImageSize
) * EFI_PAGE_SIZE
, *DxeCoreEntryPoint
);
317 Find DXE core from FV and build DXE core HOBs.
319 @param[in] DxeFv The FV where to find the DXE core.
320 @param[out] DxeCoreEntryPoint DXE core entry point
322 @retval EFI_SUCCESS If it completed successfully.
323 @retval EFI_NOT_FOUND If it failed to load DXE FV.
326 UniversalLoadDxeCore (
327 IN EFI_FIRMWARE_VOLUME_HEADER
*DxeFv
,
328 OUT PHYSICAL_ADDRESS
*DxeCoreEntryPoint
332 EFI_FFS_FILE_HEADER
*FileHeader
;
334 EFI_PHYSICAL_ADDRESS ImageAddress
;
338 // Find DXE core file from DXE FV
340 Status
= FvFindFileByTypeGuid (DxeFv
, EFI_FV_FILETYPE_DXE_CORE
, NULL
, &FileHeader
);
341 if (EFI_ERROR (Status
)) {
345 Status
= FileFindSection (FileHeader
, EFI_SECTION_PE32
, (VOID
**)&PeCoffImage
);
346 if (EFI_ERROR (Status
)) {
353 Status
= LoadPeCoffImage (PeCoffImage
, &ImageAddress
, &ImageSize
, DxeCoreEntryPoint
);
354 if (EFI_ERROR (Status
)) {
358 BuildModuleHob (&FileHeader
->Name
, ImageAddress
, EFI_SIZE_TO_PAGES ((UINT32
)ImageSize
) * EFI_PAGE_SIZE
, *DxeCoreEntryPoint
);