]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Core/Pei/PeiMain/PeiMain.c
1) If PeiLoadImage fails, the section extraction PPI or Decompress PPI may not be...
[mirror_edk2.git] / MdeModulePkg / Core / Pei / PeiMain / PeiMain.c
1 /*++
2
3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 PeiMain.c
15
16 Abstract:
17
18 Pei Core Main Entry Point
19
20 Revision History
21
22 --*/
23
24 #include <PeiMain.h>
25
26 //
27 //CAR is filled with this initial value during SEC phase
28 //
29 #define INIT_CAR_VALUE 0x5AA55AA5
30
31 static EFI_PEI_PPI_DESCRIPTOR mMemoryDiscoveredPpi = {
32 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
33 &gEfiPeiMemoryDiscoveredPpiGuid,
34 NULL
35 };
36
37 //
38 // Pei Core Module Variables
39 //
40 //
41 static EFI_PEI_SERVICES mPS = {
42 {
43 PEI_SERVICES_SIGNATURE,
44 PEI_SERVICES_REVISION,
45 sizeof (EFI_PEI_SERVICES),
46 0,
47 0
48 },
49 PeiInstallPpi,
50 PeiReInstallPpi,
51 PeiLocatePpi,
52 PeiNotifyPpi,
53
54 PeiGetBootMode,
55 PeiSetBootMode,
56
57 PeiGetHobList,
58 PeiCreateHob,
59
60 PeiFvFindNextVolume,
61 PeiFfsFindNextFile,
62 PeiFfsFindSectionData,
63
64 PeiInstallPeiMemory,
65 PeiAllocatePages,
66 PeiAllocatePool,
67 (EFI_PEI_COPY_MEM)CopyMem,
68 (EFI_PEI_SET_MEM)SetMem,
69
70 PeiReportStatusCode,
71 PeiResetSystem,
72
73 NULL,
74 NULL,
75
76 PeiFfsFindFileByName,
77 PeiFfsGetFileInfo,
78 PeiFfsGetVolumeInfo,
79 PeiRegisterForShadow
80 };
81
82 EFI_STATUS
83 EFIAPI
84 PeiCore (
85 IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
86 IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList,
87 IN VOID *Data
88 )
89 /*++
90
91 Routine Description:
92
93 The entry routine to Pei Core, invoked by PeiMain during transition
94 from SEC to PEI. After switching stack in the PEI core, it will restart
95 with the old core data.
96
97 Arguments:
98
99 SecCoreData - Points to a data structure containing information about the PEI core's operating
100 environment, such as the size and location of temporary RAM, the stack location and
101 the BFV location.
102 PpiList - Points to a list of one or more PPI descriptors to be installed initially by the PEI core.
103 An empty PPI list consists of a single descriptor with the end-tag
104 EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST. As part of its initialization
105 phase, the PEI Foundation will add these SEC-hosted PPIs to its PPI database such
106 that both the PEI Foundation and any modules can leverage the associated service
107 calls and/or code in these early PPIs
108 Data - Pointer to old core data that is used to initialize the
109 core's data areas.
110
111 Returns:
112
113 This function never returns
114 EFI_NOT_FOUND - Never reach
115
116 --*/
117 {
118 PEI_CORE_INSTANCE PrivateData;
119 EFI_STATUS Status;
120 PEI_CORE_TEMP_POINTERS TempPtr;
121 UINT64 mTick;
122 PEI_CORE_INSTANCE *OldCoreData;
123 EFI_PEI_CPU_IO_PPI *CpuIo;
124 EFI_PEI_PCI_CFG2_PPI *PciCfg;
125 UINT64 SecPlatformInfoRecordSize;
126 EFI_SEC_PLATFORM_INFORMATION_PPI *SecPlatformInfoPpi;
127 EFI_SEC_PLATFORM_INFORMATION_RECORD *SecPlatformInfoRecord;
128
129 mTick = 0;
130 OldCoreData = (PEI_CORE_INSTANCE *) Data;
131
132 if (PerformanceMeasurementEnabled()) {
133 if (OldCoreData == NULL) {
134 mTick = GetPerformanceCounter ();
135 }
136 }
137
138 if (OldCoreData != NULL) {
139 CopyMem (&PrivateData, OldCoreData, sizeof (PEI_CORE_INSTANCE));
140
141 CpuIo = (VOID*)PrivateData.ServiceTableShadow.CpuIo;
142 PciCfg = (VOID*)PrivateData.ServiceTableShadow.PciCfg;
143
144 CopyMem (&PrivateData.ServiceTableShadow, &mPS, sizeof (mPS));
145
146 PrivateData.ServiceTableShadow.CpuIo = CpuIo;
147 PrivateData.ServiceTableShadow.PciCfg = PciCfg;
148 } else {
149 ZeroMem (&PrivateData, sizeof (PEI_CORE_INSTANCE));
150 PrivateData.Signature = PEI_CORE_HANDLE_SIGNATURE;
151 CopyMem (&PrivateData.ServiceTableShadow, &mPS, sizeof (mPS));
152 }
153
154 PrivateData.PS = &PrivateData.ServiceTableShadow;
155
156 //
157 // Initialize libraries that the PeiCore is linked against
158 // BUGBUG: The FileHandle is passed in as NULL. Do we look it up or remove it from the lib init?
159 //
160 ProcessLibraryConstructorList (NULL, &PrivateData.PS);
161
162 InitializeMemoryServices (&PrivateData, SecCoreData, OldCoreData);
163
164 InitializePpiServices (&PrivateData, OldCoreData);
165
166 //
167 // Save PeiServicePointer so that it can be retrieved anywhere.
168 //
169 SetPeiServicesTablePointer(&PrivateData.PS);
170
171 if (OldCoreData != NULL) {
172
173 PERF_END (NULL,"PreMem", NULL, 0);
174 PERF_START (NULL,"PostMem", NULL, 0);
175
176 //
177 // The following code dumps out interesting cache as RAM usage information
178 // so we can keep tabs on how the cache as RAM is being utilized. The
179 // DEBUG_CODE_BEGIN macro is used to prevent this code from being compiled
180 // on a debug build.
181 //
182 DEBUG_CODE_BEGIN ();
183 UINTN *StackPointer;
184 UINTN StackValue;
185
186 StackValue = INIT_CAR_VALUE;
187 for (StackPointer = (UINTN *) OldCoreData->TopOfCarHeap;
188 ((UINTN) StackPointer < ((UINTN) OldCoreData->MaxTopOfCarHeap))
189 && StackValue == INIT_CAR_VALUE;
190 StackPointer++) {
191 StackValue = *StackPointer;
192 }
193
194 DEBUG ((EFI_D_INFO, "Total Cache as RAM: %d bytes.\n", OldCoreData->SizeOfCacheAsRam));
195 DEBUG ((EFI_D_INFO, " CAR stack ever used: %d bytes.\n",
196 ((UINTN) OldCoreData->MaxTopOfCarHeap - (UINTN) StackPointer)
197 ));
198 DEBUG ((EFI_D_INFO, " CAR heap used: %d bytes.\n",
199 ((UINTN) OldCoreData->HobList.HandoffInformationTable->EfiFreeMemoryBottom -
200 (UINTN) OldCoreData->HobList.Raw)
201 ));
202 DEBUG_CODE_END ();
203
204 //
205 // Alert any listeners that there is permanent memory available
206 //
207
208 PERF_START (NULL,"DisMem", NULL, 0);
209 Status = PeiServicesInstallPpi (&mMemoryDiscoveredPpi);
210 PERF_END (NULL,"DisMem", NULL, 0);
211
212 } else {
213
214 //
215 // Report Status Code EFI_SW_PC_INIT
216 //
217 REPORT_STATUS_CODE (
218 EFI_PROGRESS_CODE,
219 EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT
220 );
221
222 PERF_START (NULL,"PEI", NULL, mTick);
223 //
224 // If first pass, start performance measurement.
225 //
226 PERF_START (NULL,"PreMem", NULL, mTick);
227
228 //
229 // If SEC provided any PPI services to PEI, install them.
230 //
231 if (PpiList != NULL) {
232 Status = PeiServicesInstallPpi (PpiList);
233 ASSERT_EFI_ERROR (Status);
234
235 //
236 // PI spec Vol 1, 7.3.1 specifies that this same information reported by EFI_SEC_PLATFORM_INFORMATION_PPI
237 // will be placed in a GUIDed HOB with the PPI GUID as the HOB GUID for HOB consumer phase.
238 //
239 Status = PeiServicesLocatePpi (
240 &gEfiSecPlatformInformationPpiGuid,
241 0,
242 NULL,
243 (VOID **) &SecPlatformInfoPpi
244 );
245 if (!EFI_ERROR (Status)) {
246 SecPlatformInfoRecord = AllocateZeroPool (sizeof(*SecPlatformInfoRecord));
247 ASSERT (SecPlatformInfoRecord != NULL);
248
249 SecPlatformInfoRecordSize = sizeof(*SecPlatformInfoRecord);
250
251 Status = SecPlatformInfoPpi->PlatformInformation (
252 (CONST EFI_PEI_SERVICES **) GetPeiServicesTablePointer (),
253 &SecPlatformInfoRecordSize,
254 SecPlatformInfoRecord
255 );
256
257 if (!EFI_ERROR (Status)) {
258 BuildGuidDataHob (
259 &gEfiSecPlatformInformationPpiGuid,
260 SecPlatformInfoRecord,
261 sizeof (*SecPlatformInfoRecord)
262 );
263 }
264 }
265 }
266 }
267
268 InitializeSecurityServices (&PrivateData.PS, OldCoreData);
269
270 InitializeDispatcherData (&PrivateData, OldCoreData, SecCoreData);
271
272 //
273 // Install Pei Load File PPI.
274 //
275 InitializeImageServices (&PrivateData, OldCoreData);
276
277 //
278 // Call PEIM dispatcher
279 //
280 PeiDispatcher (SecCoreData, &PrivateData);
281
282 //
283 // Check if InstallPeiMemory service was called.
284 //
285 ASSERT(PrivateData.PeiMemoryInstalled == TRUE);
286
287 PERF_END (NULL, "PostMem", NULL, 0);
288
289 Status = PeiServicesLocatePpi (
290 &gEfiDxeIplPpiGuid,
291 0,
292 NULL,
293 (VOID **)&TempPtr.DxeIpl
294 );
295 ASSERT_EFI_ERROR (Status);
296
297 DEBUG ((EFI_D_INFO, "DXE IPL Entry\n"));
298 Status = TempPtr.DxeIpl->Entry (
299 TempPtr.DxeIpl,
300 &PrivateData.PS,
301 PrivateData.HobList
302 );
303
304 ASSERT_EFI_ERROR (Status);
305
306 return EFI_NOT_FOUND;
307 }
308
309