UefiPayloadPkg: Enhance UEFI payload for coreboot and Slim Bootloader
[mirror_edk2.git] / UefiPayloadPkg / SecCore / FindPeiCore.c
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
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
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