]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - MdeModulePkg/Core/Pei/PeiMain/PeiMain.c
MdeModulePkg: Apply uncrustify changes
[mirror_edk2.git] / MdeModulePkg / Core / Pei / PeiMain / PeiMain.c
... / ...
CommitLineData
1/** @file\r
2 Pei Core Main Entry Point\r
3\r
4Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
5SPDX-License-Identifier: BSD-2-Clause-Patent\r
6\r
7**/\r
8\r
9#include "PeiMain.h"\r
10\r
11EFI_PEI_PPI_DESCRIPTOR mMemoryDiscoveredPpi = {\r
12 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
13 &gEfiPeiMemoryDiscoveredPpiGuid,\r
14 NULL\r
15};\r
16\r
17///\r
18/// Pei service instance\r
19///\r
20EFI_PEI_SERVICES gPs = {\r
21 {\r
22 PEI_SERVICES_SIGNATURE,\r
23 PEI_SERVICES_REVISION,\r
24 sizeof (EFI_PEI_SERVICES),\r
25 0,\r
26 0\r
27 },\r
28 PeiInstallPpi,\r
29 PeiReInstallPpi,\r
30 PeiLocatePpi,\r
31 PeiNotifyPpi,\r
32\r
33 PeiGetBootMode,\r
34 PeiSetBootMode,\r
35\r
36 PeiGetHobList,\r
37 PeiCreateHob,\r
38\r
39 PeiFfsFindNextVolume,\r
40 PeiFfsFindNextFile,\r
41 PeiFfsFindSectionData,\r
42\r
43 PeiInstallPeiMemory,\r
44 PeiAllocatePages,\r
45 PeiAllocatePool,\r
46 (EFI_PEI_COPY_MEM)CopyMem,\r
47 (EFI_PEI_SET_MEM)SetMem,\r
48\r
49 PeiReportStatusCode,\r
50 PeiResetSystem,\r
51\r
52 &gPeiDefaultCpuIoPpi,\r
53 &gPeiDefaultPciCfg2Ppi,\r
54\r
55 PeiFfsFindFileByName,\r
56 PeiFfsGetFileInfo,\r
57 PeiFfsGetVolumeInfo,\r
58 PeiRegisterForShadow,\r
59 PeiFfsFindSectionData3,\r
60 PeiFfsGetFileInfo2,\r
61 PeiResetSystem2,\r
62 PeiFreePages,\r
63};\r
64\r
65/**\r
66 Shadow PeiCore module from flash to installed memory.\r
67\r
68 @param PrivateData PeiCore's private data structure\r
69\r
70 @return PeiCore function address after shadowing.\r
71**/\r
72PEICORE_FUNCTION_POINTER\r
73ShadowPeiCore (\r
74 IN PEI_CORE_INSTANCE *PrivateData\r
75 )\r
76{\r
77 EFI_PEI_FILE_HANDLE PeiCoreFileHandle;\r
78 EFI_PHYSICAL_ADDRESS EntryPoint;\r
79 EFI_STATUS Status;\r
80 UINT32 AuthenticationState;\r
81 UINTN Index;\r
82 EFI_PEI_CORE_FV_LOCATION_PPI *PeiCoreFvLocationPpi;\r
83 UINTN PeiCoreFvIndex;\r
84\r
85 PeiCoreFileHandle = NULL;\r
86 //\r
87 // Default PeiCore is in BFV\r
88 //\r
89 PeiCoreFvIndex = 0;\r
90 //\r
91 // Find the PEI Core either from EFI_PEI_CORE_FV_LOCATION_PPI indicated FV or BFV\r
92 //\r
93 Status = PeiServicesLocatePpi (\r
94 &gEfiPeiCoreFvLocationPpiGuid,\r
95 0,\r
96 NULL,\r
97 (VOID **)&PeiCoreFvLocationPpi\r
98 );\r
99 if (!EFI_ERROR (Status) && (PeiCoreFvLocationPpi->PeiCoreFvLocation != NULL)) {\r
100 //\r
101 // If PeiCoreFvLocation present, the PEI Core should be found from indicated FV\r
102 //\r
103 for (Index = 0; Index < PrivateData->FvCount; Index++) {\r
104 if (PrivateData->Fv[Index].FvHandle == PeiCoreFvLocationPpi->PeiCoreFvLocation) {\r
105 PeiCoreFvIndex = Index;\r
106 break;\r
107 }\r
108 }\r
109\r
110 ASSERT (Index < PrivateData->FvCount);\r
111 }\r
112\r
113 //\r
114 // Find PEI Core from the given FV index\r
115 //\r
116 Status = PrivateData->Fv[PeiCoreFvIndex].FvPpi->FindFileByType (\r
117 PrivateData->Fv[PeiCoreFvIndex].FvPpi,\r
118 EFI_FV_FILETYPE_PEI_CORE,\r
119 PrivateData->Fv[PeiCoreFvIndex].FvHandle,\r
120 &PeiCoreFileHandle\r
121 );\r
122 ASSERT_EFI_ERROR (Status);\r
123\r
124 //\r
125 // Shadow PEI Core into memory so it will run faster\r
126 //\r
127 Status = PeiLoadImage (\r
128 GetPeiServicesTablePointer (),\r
129 *((EFI_PEI_FILE_HANDLE *)&PeiCoreFileHandle),\r
130 PEIM_STATE_REGISTER_FOR_SHADOW,\r
131 &EntryPoint,\r
132 &AuthenticationState\r
133 );\r
134 ASSERT_EFI_ERROR (Status);\r
135\r
136 //\r
137 // Compute the PeiCore's function address after shadowed PeiCore.\r
138 // _ModuleEntryPoint is PeiCore main function entry\r
139 //\r
140 return (PEICORE_FUNCTION_POINTER)((UINTN)EntryPoint + (UINTN)PeiCore - (UINTN)_ModuleEntryPoint);\r
141}\r
142\r
143/**\r
144 This routine is invoked by main entry of PeiMain module during transition\r
145 from SEC to PEI. After switching stack in the PEI core, it will restart\r
146 with the old core data.\r
147\r
148 @param SecCoreDataPtr Points to a data structure containing information about the PEI core's operating\r
149 environment, such as the size and location of temporary RAM, the stack location and\r
150 the BFV location.\r
151 @param PpiList Points to a list of one or more PPI descriptors to be installed initially by the PEI core.\r
152 An empty PPI list consists of a single descriptor with the end-tag\r
153 EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST. As part of its initialization\r
154 phase, the PEI Foundation will add these SEC-hosted PPIs to its PPI database such\r
155 that both the PEI Foundation and any modules can leverage the associated service\r
156 calls and/or code in these early PPIs\r
157 @param Data Pointer to old core data that is used to initialize the\r
158 core's data areas.\r
159 If NULL, it is first PeiCore entering.\r
160\r
161**/\r
162VOID\r
163EFIAPI\r
164PeiCore (\r
165 IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreDataPtr,\r
166 IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList,\r
167 IN VOID *Data\r
168 )\r
169{\r
170 PEI_CORE_INSTANCE PrivateData;\r
171 EFI_SEC_PEI_HAND_OFF *SecCoreData;\r
172 EFI_SEC_PEI_HAND_OFF NewSecCoreData;\r
173 EFI_STATUS Status;\r
174 PEI_CORE_TEMP_POINTERS TempPtr;\r
175 PEI_CORE_INSTANCE *OldCoreData;\r
176 EFI_PEI_CPU_IO_PPI *CpuIo;\r
177 EFI_PEI_PCI_CFG2_PPI *PciCfg;\r
178 EFI_HOB_HANDOFF_INFO_TABLE *HandoffInformationTable;\r
179 EFI_PEI_TEMPORARY_RAM_DONE_PPI *TemporaryRamDonePpi;\r
180 UINTN Index;\r
181\r
182 //\r
183 // Retrieve context passed into PEI Core\r
184 //\r
185 OldCoreData = (PEI_CORE_INSTANCE *)Data;\r
186 SecCoreData = (EFI_SEC_PEI_HAND_OFF *)SecCoreDataPtr;\r
187\r
188 //\r
189 // Perform PEI Core phase specific actions.\r
190 //\r
191 if (OldCoreData == NULL) {\r
192 //\r
193 // If OldCoreData is NULL, means current is the first entry into the PEI Core before memory is available.\r
194 //\r
195 ZeroMem (&PrivateData, sizeof (PEI_CORE_INSTANCE));\r
196 PrivateData.Signature = PEI_CORE_HANDLE_SIGNATURE;\r
197 CopyMem (&PrivateData.ServiceTableShadow, &gPs, sizeof (gPs));\r
198 } else {\r
199 //\r
200 // Memory is available to the PEI Core. See if the PEI Core has been shadowed to memory yet.\r
201 //\r
202 if (OldCoreData->ShadowedPeiCore == NULL) {\r
203 //\r
204 // Fixup the PeiCore's private data\r
205 //\r
206 OldCoreData->Ps = &OldCoreData->ServiceTableShadow;\r
207 OldCoreData->CpuIo = &OldCoreData->ServiceTableShadow.CpuIo;\r
208 if (OldCoreData->HeapOffsetPositive) {\r
209 OldCoreData->HobList.Raw = (VOID *)(OldCoreData->HobList.Raw + OldCoreData->HeapOffset);\r
210 if (OldCoreData->UnknownFvInfo != NULL) {\r
211 OldCoreData->UnknownFvInfo = (PEI_CORE_UNKNOW_FORMAT_FV_INFO *)((UINT8 *)OldCoreData->UnknownFvInfo + OldCoreData->HeapOffset);\r
212 }\r
213\r
214 if (OldCoreData->CurrentFvFileHandles != NULL) {\r
215 OldCoreData->CurrentFvFileHandles = (EFI_PEI_FILE_HANDLE *)((UINT8 *)OldCoreData->CurrentFvFileHandles + OldCoreData->HeapOffset);\r
216 }\r
217\r
218 if (OldCoreData->PpiData.PpiList.PpiPtrs != NULL) {\r
219 OldCoreData->PpiData.PpiList.PpiPtrs = (PEI_PPI_LIST_POINTERS *)((UINT8 *)OldCoreData->PpiData.PpiList.PpiPtrs + OldCoreData->HeapOffset);\r
220 }\r
221\r
222 if (OldCoreData->PpiData.CallbackNotifyList.NotifyPtrs != NULL) {\r
223 OldCoreData->PpiData.CallbackNotifyList.NotifyPtrs = (PEI_PPI_LIST_POINTERS *)((UINT8 *)OldCoreData->PpiData.CallbackNotifyList.NotifyPtrs + OldCoreData->HeapOffset);\r
224 }\r
225\r
226 if (OldCoreData->PpiData.DispatchNotifyList.NotifyPtrs != NULL) {\r
227 OldCoreData->PpiData.DispatchNotifyList.NotifyPtrs = (PEI_PPI_LIST_POINTERS *)((UINT8 *)OldCoreData->PpiData.DispatchNotifyList.NotifyPtrs + OldCoreData->HeapOffset);\r
228 }\r
229\r
230 OldCoreData->Fv = (PEI_CORE_FV_HANDLE *)((UINT8 *)OldCoreData->Fv + OldCoreData->HeapOffset);\r
231 for (Index = 0; Index < OldCoreData->FvCount; Index++) {\r
232 if (OldCoreData->Fv[Index].PeimState != NULL) {\r
233 OldCoreData->Fv[Index].PeimState = (UINT8 *)OldCoreData->Fv[Index].PeimState + OldCoreData->HeapOffset;\r
234 }\r
235\r
236 if (OldCoreData->Fv[Index].FvFileHandles != NULL) {\r
237 OldCoreData->Fv[Index].FvFileHandles = (EFI_PEI_FILE_HANDLE *)((UINT8 *)OldCoreData->Fv[Index].FvFileHandles + OldCoreData->HeapOffset);\r
238 }\r
239 }\r
240\r
241 OldCoreData->TempFileGuid = (EFI_GUID *)((UINT8 *)OldCoreData->TempFileGuid + OldCoreData->HeapOffset);\r
242 OldCoreData->TempFileHandles = (EFI_PEI_FILE_HANDLE *)((UINT8 *)OldCoreData->TempFileHandles + OldCoreData->HeapOffset);\r
243 } else {\r
244 OldCoreData->HobList.Raw = (VOID *)(OldCoreData->HobList.Raw - OldCoreData->HeapOffset);\r
245 if (OldCoreData->UnknownFvInfo != NULL) {\r
246 OldCoreData->UnknownFvInfo = (PEI_CORE_UNKNOW_FORMAT_FV_INFO *)((UINT8 *)OldCoreData->UnknownFvInfo - OldCoreData->HeapOffset);\r
247 }\r
248\r
249 if (OldCoreData->CurrentFvFileHandles != NULL) {\r
250 OldCoreData->CurrentFvFileHandles = (EFI_PEI_FILE_HANDLE *)((UINT8 *)OldCoreData->CurrentFvFileHandles - OldCoreData->HeapOffset);\r
251 }\r
252\r
253 if (OldCoreData->PpiData.PpiList.PpiPtrs != NULL) {\r
254 OldCoreData->PpiData.PpiList.PpiPtrs = (PEI_PPI_LIST_POINTERS *)((UINT8 *)OldCoreData->PpiData.PpiList.PpiPtrs - OldCoreData->HeapOffset);\r
255 }\r
256\r
257 if (OldCoreData->PpiData.CallbackNotifyList.NotifyPtrs != NULL) {\r
258 OldCoreData->PpiData.CallbackNotifyList.NotifyPtrs = (PEI_PPI_LIST_POINTERS *)((UINT8 *)OldCoreData->PpiData.CallbackNotifyList.NotifyPtrs - OldCoreData->HeapOffset);\r
259 }\r
260\r
261 if (OldCoreData->PpiData.DispatchNotifyList.NotifyPtrs != NULL) {\r
262 OldCoreData->PpiData.DispatchNotifyList.NotifyPtrs = (PEI_PPI_LIST_POINTERS *)((UINT8 *)OldCoreData->PpiData.DispatchNotifyList.NotifyPtrs - OldCoreData->HeapOffset);\r
263 }\r
264\r
265 OldCoreData->Fv = (PEI_CORE_FV_HANDLE *)((UINT8 *)OldCoreData->Fv - OldCoreData->HeapOffset);\r
266 for (Index = 0; Index < OldCoreData->FvCount; Index++) {\r
267 if (OldCoreData->Fv[Index].PeimState != NULL) {\r
268 OldCoreData->Fv[Index].PeimState = (UINT8 *)OldCoreData->Fv[Index].PeimState - OldCoreData->HeapOffset;\r
269 }\r
270\r
271 if (OldCoreData->Fv[Index].FvFileHandles != NULL) {\r
272 OldCoreData->Fv[Index].FvFileHandles = (EFI_PEI_FILE_HANDLE *)((UINT8 *)OldCoreData->Fv[Index].FvFileHandles - OldCoreData->HeapOffset);\r
273 }\r
274 }\r
275\r
276 OldCoreData->TempFileGuid = (EFI_GUID *)((UINT8 *)OldCoreData->TempFileGuid - OldCoreData->HeapOffset);\r
277 OldCoreData->TempFileHandles = (EFI_PEI_FILE_HANDLE *)((UINT8 *)OldCoreData->TempFileHandles - OldCoreData->HeapOffset);\r
278 }\r
279\r
280 //\r
281 // Fixup for PeiService's address\r
282 //\r
283 SetPeiServicesTablePointer ((CONST EFI_PEI_SERVICES **)&OldCoreData->Ps);\r
284\r
285 //\r
286 // Initialize libraries that the PEI Core is linked against\r
287 //\r
288 ProcessLibraryConstructorList (NULL, (CONST EFI_PEI_SERVICES **)&OldCoreData->Ps);\r
289\r
290 //\r
291 // Update HandOffHob for new installed permanent memory\r
292 //\r
293 HandoffInformationTable = OldCoreData->HobList.HandoffInformationTable;\r
294 if (OldCoreData->HeapOffsetPositive) {\r
295 HandoffInformationTable->EfiEndOfHobList = HandoffInformationTable->EfiEndOfHobList + OldCoreData->HeapOffset;\r
296 } else {\r
297 HandoffInformationTable->EfiEndOfHobList = HandoffInformationTable->EfiEndOfHobList - OldCoreData->HeapOffset;\r
298 }\r
299\r
300 HandoffInformationTable->EfiMemoryTop = OldCoreData->PhysicalMemoryBegin + OldCoreData->PhysicalMemoryLength;\r
301 HandoffInformationTable->EfiMemoryBottom = OldCoreData->PhysicalMemoryBegin;\r
302 HandoffInformationTable->EfiFreeMemoryTop = OldCoreData->FreePhysicalMemoryTop;\r
303 HandoffInformationTable->EfiFreeMemoryBottom = HandoffInformationTable->EfiEndOfHobList + sizeof (EFI_HOB_GENERIC_HEADER);\r
304\r
305 //\r
306 // We need convert MemoryBaseAddress in memory allocation HOBs\r
307 //\r
308 ConvertMemoryAllocationHobs (OldCoreData);\r
309\r
310 //\r
311 // We need convert the PPI descriptor's pointer\r
312 //\r
313 ConvertPpiPointers (SecCoreData, OldCoreData);\r
314\r
315 //\r
316 // After the whole temporary memory is migrated, then we can allocate page in\r
317 // permanent memory.\r
318 //\r
319 OldCoreData->PeiMemoryInstalled = TRUE;\r
320\r
321 //\r
322 // Indicate that PeiCore reenter\r
323 //\r
324 OldCoreData->PeimDispatcherReenter = TRUE;\r
325\r
326 if ((PcdGet64 (PcdLoadModuleAtFixAddressEnable) != 0) && (OldCoreData->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {\r
327 //\r
328 // if Loading Module at Fixed Address is enabled, allocate the PEI code memory range usage bit map array.\r
329 // Every bit in the array indicate the status of the corresponding memory page available or not\r
330 //\r
331 OldCoreData->PeiCodeMemoryRangeUsageBitMap = AllocateZeroPool (((PcdGet32 (PcdLoadFixAddressPeiCodePageNumber)>>6) + 1)*sizeof (UINT64));\r
332 }\r
333\r
334 //\r
335 // Shadow PEI Core. When permanent memory is available, shadow\r
336 // PEI Core and PEIMs to get high performance.\r
337 //\r
338 OldCoreData->ShadowedPeiCore = (PEICORE_FUNCTION_POINTER)(UINTN)PeiCore;\r
339 if (PcdGetBool (PcdMigrateTemporaryRamFirmwareVolumes) ||\r
340 ((HandoffInformationTable->BootMode == BOOT_ON_S3_RESUME) && PcdGetBool (PcdShadowPeimOnS3Boot)) ||\r
341 ((HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME) && PcdGetBool (PcdShadowPeimOnBoot)))\r
342 {\r
343 OldCoreData->ShadowedPeiCore = ShadowPeiCore (OldCoreData);\r
344 }\r
345\r
346 //\r
347 // PEI Core has now been shadowed to memory. Restart PEI Core in memory.\r
348 //\r
349 OldCoreData->ShadowedPeiCore (SecCoreData, PpiList, OldCoreData);\r
350\r
351 //\r
352 // Should never reach here.\r
353 //\r
354 ASSERT (FALSE);\r
355 CpuDeadLoop ();\r
356\r
357 UNREACHABLE ();\r
358 }\r
359\r
360 //\r
361 // Memory is available to the PEI Core and the PEI Core has been shadowed to memory.\r
362 //\r
363 CopyMem (&NewSecCoreData, SecCoreDataPtr, sizeof (NewSecCoreData));\r
364 SecCoreData = &NewSecCoreData;\r
365\r
366 CopyMem (&PrivateData, OldCoreData, sizeof (PrivateData));\r
367\r
368 CpuIo = (VOID *)PrivateData.ServiceTableShadow.CpuIo;\r
369 PciCfg = (VOID *)PrivateData.ServiceTableShadow.PciCfg;\r
370\r
371 CopyMem (&PrivateData.ServiceTableShadow, &gPs, sizeof (gPs));\r
372\r
373 PrivateData.ServiceTableShadow.CpuIo = CpuIo;\r
374 PrivateData.ServiceTableShadow.PciCfg = PciCfg;\r
375 }\r
376\r
377 //\r
378 // Cache a pointer to the PEI Services Table that is either in temporary memory or permanent memory\r
379 //\r
380 PrivateData.Ps = &PrivateData.ServiceTableShadow;\r
381\r
382 //\r
383 // Save PeiServicePointer so that it can be retrieved anywhere.\r
384 //\r
385 SetPeiServicesTablePointer ((CONST EFI_PEI_SERVICES **)&PrivateData.Ps);\r
386\r
387 //\r
388 // Initialize libraries that the PEI Core is linked against\r
389 //\r
390 ProcessLibraryConstructorList (NULL, (CONST EFI_PEI_SERVICES **)&PrivateData.Ps);\r
391\r
392 //\r
393 // Initialize PEI Core Services\r
394 //\r
395 InitializeMemoryServices (&PrivateData, SecCoreData, OldCoreData);\r
396\r
397 //\r
398 // Update performance measurements\r
399 //\r
400 if (OldCoreData == NULL) {\r
401 PERF_EVENT ("SEC"); // Means the end of SEC phase.\r
402\r
403 //\r
404 // If first pass, start performance measurement.\r
405 //\r
406 PERF_CROSSMODULE_BEGIN ("PEI");\r
407 PERF_INMODULE_BEGIN ("PreMem");\r
408 } else {\r
409 PERF_INMODULE_END ("PreMem");\r
410 PERF_INMODULE_BEGIN ("PostMem");\r
411 }\r
412\r
413 //\r
414 // Complete PEI Core Service initialization\r
415 //\r
416 InitializeSecurityServices (&PrivateData.Ps, OldCoreData);\r
417 InitializeDispatcherData (&PrivateData, OldCoreData, SecCoreData);\r
418 InitializeImageServices (&PrivateData, OldCoreData);\r
419\r
420 //\r
421 // Perform PEI Core Phase specific actions\r
422 //\r
423 if (OldCoreData == NULL) {\r
424 //\r
425 // Report Status Code EFI_SW_PC_INIT\r
426 //\r
427 REPORT_STATUS_CODE (\r
428 EFI_PROGRESS_CODE,\r
429 (EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT)\r
430 );\r
431\r
432 //\r
433 // If SEC provided the PpiList, process it.\r
434 //\r
435 if (PpiList != NULL) {\r
436 ProcessPpiListFromSec ((CONST EFI_PEI_SERVICES **)&PrivateData.Ps, PpiList);\r
437 }\r
438 } else {\r
439 if (PcdGetBool (PcdMigrateTemporaryRamFirmwareVolumes)) {\r
440 //\r
441 // When PcdMigrateTemporaryRamFirmwareVolumes is TRUE, alway shadow all\r
442 // PEIMs no matter the condition of PcdShadowPeimOnBoot and PcdShadowPeimOnS3Boot\r
443 //\r
444 DEBUG ((DEBUG_VERBOSE, "PPI lists before temporary RAM evacuation:\n"));\r
445 DumpPpiList (&PrivateData);\r
446\r
447 //\r
448 // Migrate installed content from Temporary RAM to Permanent RAM\r
449 //\r
450 EvacuateTempRam (&PrivateData, SecCoreData);\r
451\r
452 DEBUG ((DEBUG_VERBOSE, "PPI lists after temporary RAM evacuation:\n"));\r
453 DumpPpiList (&PrivateData);\r
454 }\r
455\r
456 //\r
457 // Try to locate Temporary RAM Done Ppi.\r
458 //\r
459 Status = PeiServicesLocatePpi (\r
460 &gEfiTemporaryRamDonePpiGuid,\r
461 0,\r
462 NULL,\r
463 (VOID **)&TemporaryRamDonePpi\r
464 );\r
465 if (!EFI_ERROR (Status)) {\r
466 //\r
467 // Disable the use of Temporary RAM after the transition from Temporary RAM to Permanent RAM is complete.\r
468 //\r
469 TemporaryRamDonePpi->TemporaryRamDone ();\r
470 }\r
471\r
472 //\r
473 // Alert any listeners that there is permanent memory available\r
474 //\r
475 PERF_INMODULE_BEGIN ("DisMem");\r
476 Status = PeiServicesInstallPpi (&mMemoryDiscoveredPpi);\r
477\r
478 //\r
479 // Process the Notify list and dispatch any notifies for the Memory Discovered PPI\r
480 //\r
481 ProcessDispatchNotifyList (&PrivateData);\r
482\r
483 PERF_INMODULE_END ("DisMem");\r
484 }\r
485\r
486 //\r
487 // Call PEIM dispatcher\r
488 //\r
489 PeiDispatcher (SecCoreData, &PrivateData);\r
490\r
491 if (PrivateData.HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME) {\r
492 //\r
493 // Check if InstallPeiMemory service was called on non-S3 resume boot path.\r
494 //\r
495 ASSERT (PrivateData.PeiMemoryInstalled == TRUE);\r
496 }\r
497\r
498 //\r
499 // Measure PEI Core execution time.\r
500 //\r
501 PERF_INMODULE_END ("PostMem");\r
502\r
503 //\r
504 // Lookup DXE IPL PPI\r
505 //\r
506 Status = PeiServicesLocatePpi (\r
507 &gEfiDxeIplPpiGuid,\r
508 0,\r
509 NULL,\r
510 (VOID **)&TempPtr.DxeIpl\r
511 );\r
512 ASSERT_EFI_ERROR (Status);\r
513\r
514 if (EFI_ERROR (Status)) {\r
515 //\r
516 // Report status code to indicate DXE IPL PPI could not be found.\r
517 //\r
518 REPORT_STATUS_CODE (\r
519 EFI_ERROR_CODE | EFI_ERROR_MAJOR,\r
520 (EFI_SOFTWARE_PEI_CORE | EFI_SW_PEI_CORE_EC_DXEIPL_NOT_FOUND)\r
521 );\r
522 CpuDeadLoop ();\r
523 }\r
524\r
525 //\r
526 // Enter DxeIpl to load Dxe core.\r
527 //\r
528 DEBUG ((DEBUG_INFO, "DXE IPL Entry\n"));\r
529 Status = TempPtr.DxeIpl->Entry (\r
530 TempPtr.DxeIpl,\r
531 &PrivateData.Ps,\r
532 PrivateData.HobList\r
533 );\r
534 //\r
535 // Should never reach here.\r
536 //\r
537 ASSERT_EFI_ERROR (Status);\r
538 CpuDeadLoop ();\r
539\r
540 UNREACHABLE ();\r
541}\r