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