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