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