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
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.
18 EFI PEI Core dispatch services
26 #define INIT_CAR_VALUE 0x5AA55AA5
29 EFI_STATUS_CODE_DATA DataHeader
;
31 } PEIM_FILE_HANDLE_EXTENDED_DATA
;
34 DiscoverPeimsAndOrderWithApriori (
35 IN PEI_CORE_INSTANCE
*Private
,
36 IN EFI_PEI_FV_HANDLE VolumeHandle
42 Discover all Peims and optional Apriori file in one FV. There is at most one
43 Apriori file in one FV.
47 Private - Pointer to the private data passed in from caller
48 VolumeHandle - Fv handle.
56 EFI_PEI_FV_HANDLE FileHandle
;
57 EFI_PEI_FILE_HANDLE AprioriFileHandle
;
64 EFI_PEI_FV_HANDLE TempFileHandles
[FixedPcdGet32 (PcdPeiCoreMaxPeimPerFv
)];
65 EFI_GUID FileGuid
[FixedPcdGet32 (PcdPeiCoreMaxPeimPerFv
)];
68 // Walk the FV and find all the PEIMs and the Apriori file.
70 AprioriFileHandle
= NULL
;
71 Private
->CurrentFvFileHandles
[0] = NULL
;
76 // If the current Fv has been scanned, directly get its cachable record.
78 if (Private
->Fv
[Private
->CurrentPeimFvCount
].ScanFv
) {
79 CopyMem (Private
->CurrentFvFileHandles
, Private
->Fv
[Private
->CurrentPeimFvCount
].FvFileHandles
, sizeof (Private
->CurrentFvFileHandles
));
84 // Go ahead to scan this Fv, and cache FileHandles within it.
86 for (PeimCount
= 0; PeimCount
< FixedPcdGet32 (PcdPeiCoreMaxPeimPerFv
); PeimCount
++) {
87 Status
= PeiFindFileEx (
90 PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE
,
94 if (Status
!= EFI_SUCCESS
) {
98 Private
->CurrentFvFileHandles
[PeimCount
] = FileHandle
;
101 Private
->AprioriCount
= 0;
102 if (AprioriFileHandle
!= NULL
) {
104 // Read the Apriori file
106 Status
= PeiServicesFfsFindSectionData (EFI_SECTION_RAW
, AprioriFileHandle
, (VOID
**) &Apriori
);
107 if (!EFI_ERROR (Status
)) {
109 // Calculate the number of PEIMs in the A Priori list
111 Private
->AprioriCount
= *(UINT32
*)(((EFI_FFS_FILE_HEADER
*)AprioriFileHandle
)->Size
) & 0x00FFFFFF;
112 Private
->AprioriCount
-= sizeof (EFI_FFS_FILE_HEADER
) - sizeof (EFI_COMMON_SECTION_HEADER
);
113 Private
->AprioriCount
/= sizeof (EFI_GUID
);
115 SetMem (FileGuid
, sizeof (FileGuid
), 0);
116 for (Index
= 0; Index
< PeimCount
; Index
++) {
118 // Make an array of file name guids that matches the FileHandle array so we can convert
119 // quickly from file name to file handle
121 CopyMem (&FileGuid
[Index
], &((EFI_FFS_FILE_HEADER
*)Private
->CurrentFvFileHandles
[Index
])->Name
,sizeof(EFI_GUID
));
125 // Walk through FileGuid array to find out who is invalid PEIM guid in Apriori file.
126 // Add avalible PEIMs in Apriori file into TempFileHandles array at first.
129 for (Index
= 0; Index2
< Private
->AprioriCount
; Index
++) {
130 while (Index2
< Private
->AprioriCount
) {
131 Guid
= ScanGuid (FileGuid
, PeimCount
* sizeof (EFI_GUID
), &Apriori
[Index2
++]);
139 PeimIndex
= ((UINTN
)Guid
- (UINTN
)&FileGuid
[0])/sizeof (EFI_GUID
);
140 TempFileHandles
[Index
] = Private
->CurrentFvFileHandles
[PeimIndex
];
143 // Since we have copied the file handle we can remove it from this list.
145 Private
->CurrentFvFileHandles
[PeimIndex
] = NULL
;
149 // Update valid Aprioricount
151 Private
->AprioriCount
= Index
;
154 // Add in any PEIMs not in the Apriori file
156 for (;Index
< PeimCount
; Index
++) {
157 for (Index2
= 0; Index2
< PeimCount
; Index2
++) {
158 if (Private
->CurrentFvFileHandles
[Index2
] != NULL
) {
159 TempFileHandles
[Index
] = Private
->CurrentFvFileHandles
[Index2
];
160 Private
->CurrentFvFileHandles
[Index2
] = NULL
;
166 //Index the end of array contains re-range Pei moudle.
168 TempFileHandles
[Index
] = NULL
;
171 // Private->CurrentFvFileHandles is currently in PEIM in the FV order.
172 // We need to update it to start with files in the A Priori list and
173 // then the remaining files in PEIM order.
175 CopyMem (Private
->CurrentFvFileHandles
, TempFileHandles
, sizeof (Private
->CurrentFvFileHandles
));
179 // Cache the current Fv File Handle. So that we don't have to scan the Fv again.
180 // Instead, we can retrieve the file handles within this Fv from cachable data.
182 Private
->Fv
[Private
->CurrentPeimFvCount
].ScanFv
= TRUE
;
183 CopyMem (Private
->Fv
[Private
->CurrentPeimFvCount
].FvFileHandles
, Private
->CurrentFvFileHandles
, sizeof (Private
->CurrentFvFileHandles
));
189 EFI_PEI_SERVICES
**PeiServices
,
190 PEI_CORE_INSTANCE
*PrivateInMem
193 EFI_PEI_FILE_HANDLE PeiCoreFileHandle
;
194 EFI_PHYSICAL_ADDRESS EntryPoint
;
196 UINT32 AuthenticationState
;
198 PeiCoreFileHandle
= NULL
;
201 // Find the PEI Core in the BFV
203 Status
= PeiFindFileEx (
204 (EFI_PEI_FV_HANDLE
)PrivateInMem
->Fv
[0].FvHeader
,
206 EFI_FV_FILETYPE_PEI_CORE
,
210 ASSERT_EFI_ERROR (Status
);
213 // Shadow PEI Core into memory so it will run faster
215 Status
= PeiLoadImage (
217 *((EFI_PEI_FILE_HANDLE
*)&PeiCoreFileHandle
),
221 ASSERT_EFI_ERROR (Status
);
223 return (VOID
*) ((UINTN
) EntryPoint
+ (UINTN
) PeiCore
- (UINTN
) _ModuleEntryPoint
);
228 IN CONST EFI_SEC_PEI_HAND_OFF
*SecCoreData
,
229 IN PEI_CORE_INSTANCE
*Private
236 Conduct PEIM dispatch.
240 SecCoreData - Points to a data structure containing information about the PEI core's operating
241 environment, such as the size and location of temporary RAM, the stack location and
243 PrivateData - Pointer to the private data passed in from caller
244 DispatchData - Pointer to PEI_CORE_DISPATCH_DATA data.
248 EFI_SUCCESS - Successfully dispatched PEIM.
249 EFI_NOT_FOUND - The dispatch failed.
256 EFI_PEI_SERVICES
**PeiServices
;
257 EFI_PEI_FV_HANDLE VolumeHandle
;
258 EFI_PEI_FILE_HANDLE PeimFileHandle
;
261 UINT32 AuthenticationState
;
262 EFI_PHYSICAL_ADDRESS EntryPoint
;
263 EFI_PEIM_ENTRY_POINT2 PeimEntryPoint
;
264 BOOLEAN PeimNeedingDispatch
;
265 BOOLEAN PeimDispatchOnThisPass
;
266 UINTN SaveCurrentPeimCount
;
267 UINTN SaveCurrentFvCount
;
268 EFI_PEI_FILE_HANDLE SaveCurrentFileHandle
;
269 PEIM_FILE_HANDLE_EXTENDED_DATA ExtendedData
;
270 EFI_PHYSICAL_ADDRESS NewPermenentMemoryBase
;
271 TEMPORARY_RAM_SUPPORT_PPI
*TemporaryRamSupportPpi
;
272 EFI_HOB_HANDOFF_INFO_TABLE
*OldHandOffTable
;
273 EFI_HOB_HANDOFF_INFO_TABLE
*NewHandOffTable
;
275 PEI_CORE_INSTANCE
*PrivateInMem
;
276 UINT64 NewPeiStackSize
;
277 UINT64 OldPeiStackSize
;
279 EFI_FV_FILE_INFO FvFileInfo
;
280 UINTN OldCheckingTop
;
281 UINTN OldCheckingBottom
;
284 PeiServices
= &Private
->PS
;
285 PeimEntryPoint
= NULL
;
286 PeimFileHandle
= NULL
;
289 if ((Private
->PeiMemoryInstalled
) && (Private
->HobList
.HandoffInformationTable
->BootMode
!= BOOT_ON_S3_RESUME
)) {
291 // Once real memory is available, shadow the RegisterForShadow modules. And meanwhile
292 // update the modules' status from PEIM_STATE_REGISITER_FOR_SHADOW to PEIM_STATE_DONE.
294 SaveCurrentPeimCount
= Private
->CurrentPeimCount
;
295 SaveCurrentFvCount
= Private
->CurrentPeimFvCount
;
296 SaveCurrentFileHandle
= Private
->CurrentFileHandle
;
298 for (Index1
= 0; Index1
<= SaveCurrentFvCount
; Index1
++) {
299 for (Index2
= 0; (Index2
< FixedPcdGet32 (PcdPeiCoreMaxPeimPerFv
)) && (Private
->Fv
[Index1
].FvFileHandles
[Index2
] != NULL
); Index2
++) {
300 if (Private
->Fv
[Index1
].PeimState
[Index2
] == PEIM_STATE_REGISITER_FOR_SHADOW
) {
301 PeimFileHandle
= Private
->Fv
[Index1
].FvFileHandles
[Index2
];
302 Status
= PeiLoadImage (
308 if (Status
== EFI_SUCCESS
) {
310 // PEIM_STATE_REGISITER_FOR_SHADOW move to PEIM_STATE_DONE
312 Private
->Fv
[Index1
].PeimState
[Index2
]++;
313 Private
->CurrentFileHandle
= PeimFileHandle
;
314 Private
->CurrentPeimFvCount
= Index1
;
315 Private
->CurrentPeimCount
= Index2
;
317 // Call the PEIM entry point
319 PeimEntryPoint
= (EFI_PEIM_ENTRY_POINT2
)(UINTN
)EntryPoint
;
321 PERF_START (0, "PEIM", NULL
, 0);
322 PeimEntryPoint(PeimFileHandle
, (const EFI_PEI_SERVICES
**) &Private
->PS
);
323 PERF_END (0, "PEIM", NULL
, 0);
327 // Process the Notify list and dispatch any notifies for
328 // newly installed PPIs.
330 ProcessNotifyList (Private
);
334 Private
->CurrentFileHandle
= SaveCurrentFileHandle
;
335 Private
->CurrentPeimFvCount
= SaveCurrentFvCount
;
336 Private
->CurrentPeimCount
= SaveCurrentPeimCount
;
340 // This is the main dispatch loop. It will search known FVs for PEIMs and
341 // attempt to dispatch them. If any PEIM gets dispatched through a single
342 // pass of the dispatcher, it will start over from the Bfv again to see
343 // if any new PEIMs dependencies got satisfied. With a well ordered
344 // FV where PEIMs are found in the order their dependencies are also
345 // satisfied, this dipatcher should run only once.
348 PeimNeedingDispatch
= FALSE
;
349 PeimDispatchOnThisPass
= FALSE
;
351 for (FvCount
= Private
->CurrentPeimFvCount
; FvCount
< Private
->FvCount
; FvCount
++) {
352 Private
->CurrentPeimFvCount
= FvCount
;
353 VolumeHandle
= Private
->Fv
[FvCount
].FvHeader
;
355 if (Private
->CurrentPeimCount
== 0) {
357 // When going through each FV, at first, search Apriori file to
358 // reorder all PEIMs to ensure the PEIMs in Apriori file to get
359 // dispatch at first.
361 DiscoverPeimsAndOrderWithApriori (Private
, VolumeHandle
);
365 // Start to dispatch all modules within the current Fv.
367 for (PeimCount
= Private
->CurrentPeimCount
;
368 (PeimCount
< FixedPcdGet32 (PcdPeiCoreMaxPeimPerFv
)) && (Private
->CurrentFvFileHandles
[PeimCount
] != NULL
);
370 Private
->CurrentPeimCount
= PeimCount
;
371 PeimFileHandle
= Private
->CurrentFileHandle
= Private
->CurrentFvFileHandles
[PeimCount
];
373 if (Private
->Fv
[FvCount
].PeimState
[PeimCount
] == PEIM_STATE_NOT_DISPATCHED
) {
374 if (!DepexSatisfied (Private
, PeimFileHandle
, PeimCount
)) {
375 PeimNeedingDispatch
= TRUE
;
377 Status
= PeiFfsGetFileInfo (PeimFileHandle
, &FvFileInfo
);
378 ASSERT_EFI_ERROR (Status
);
379 if (FvFileInfo
.FileType
== EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
) {
381 // For Fv type file, Produce new FV PPI and FV hob
383 Status
= ProcessFvFile (PeiServices
, PeimFileHandle
, &AuthenticationState
);
386 // For PEIM driver, Load its entry point
388 Status
= PeiLoadImage (
396 if ((Status
== EFI_SUCCESS
)) {
398 // The PEIM has its dependencies satisfied, and its entry point
399 // has been found, so invoke it.
401 PERF_START (0, "PEIM", NULL
, 0);
403 ExtendedData
.Handle
= (EFI_HANDLE
)PeimFileHandle
;
405 REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
407 FixedPcdGet32(PcdStatusCodeValuePeimDispatch
),
408 (VOID
*)(&ExtendedData
),
409 sizeof (ExtendedData
)
412 Status
= VerifyPeim (Private
, VolumeHandle
, PeimFileHandle
);
413 if (Status
!= EFI_SECURITY_VIOLATION
&& (AuthenticationState
== 0)) {
415 // PEIM_STATE_NOT_DISPATCHED move to PEIM_STATE_DISPATCHED
417 Private
->Fv
[FvCount
].PeimState
[PeimCount
]++;
419 if (FvFileInfo
.FileType
!= EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
) {
421 // Call the PEIM entry point for PEIM driver
423 PeimEntryPoint
= (EFI_PEIM_ENTRY_POINT2
)(UINTN
)EntryPoint
;
424 PeimEntryPoint (PeimFileHandle
, (const EFI_PEI_SERVICES
**) PeiServices
);
427 PeimDispatchOnThisPass
= TRUE
;
430 REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
432 FixedPcdGet32(PcdStatusCodeValuePeimDispatch
),
433 (VOID
*)(&ExtendedData
),
434 sizeof (ExtendedData
)
436 PERF_END (0, "PEIM", NULL
, 0);
440 if (Private
->SwitchStackSignal
) {
442 // Before switch stack from CAR to permenent memory, caculate the heap and stack
443 // usage in temporary memory for debuging.
448 for (StackPointer
= (UINTN
*)SecCoreData
->StackBase
;
449 (StackPointer
< (UINTN
*)((UINTN
)SecCoreData
->StackBase
+ SecCoreData
->StackSize
)) \
450 && (*StackPointer
== INIT_CAR_VALUE
);
453 DEBUG ((EFI_D_INFO
, "Total Cache as RAM: %d bytes.\n", SecCoreData
->TemporaryRamSize
));
454 DEBUG ((EFI_D_INFO
, " CAR stack ever used: %d bytes.\n",
455 (SecCoreData
->StackSize
- ((UINTN
) StackPointer
- (UINTN
)SecCoreData
->StackBase
))
457 DEBUG ((EFI_D_INFO
, " CAR heap used: %d bytes.\n",
458 ((UINTN
) Private
->HobList
.HandoffInformationTable
->EfiFreeMemoryBottom
-
459 (UINTN
) Private
->HobList
.Raw
)
464 // Reserve the size of new stack at bottom of physical memory
466 OldPeiStackSize
= Private
->StackSize
;
467 NewPeiStackSize
= (RShiftU64 (Private
->PhysicalMemoryLength
, 1) + EFI_PAGE_MASK
) & ~EFI_PAGE_MASK
;
468 if (FixedPcdGet32(PcdPeiCoreMaxPeiStackSize
) > (UINT32
) NewPeiStackSize
) {
469 Private
->StackSize
= NewPeiStackSize
;
471 Private
->StackSize
= FixedPcdGet32(PcdPeiCoreMaxPeiStackSize
);
475 // In theory, the size of new stack in permenent memory should large than
476 // size of old stack in temporary memory.
477 // But if new stack is smaller than the size of old stack, we also reserve
478 // the size of old stack at bottom of permenent memory.
481 if (Private
->StackSize
> OldPeiStackSize
) {
482 StackGap
= Private
->StackSize
- OldPeiStackSize
;
486 // Update HandOffHob for new installed permenent memory
488 OldHandOffTable
= Private
->HobList
.HandoffInformationTable
;
489 OldCheckingBottom
= (UINTN
)OldHandOffTable
;
490 OldCheckingTop
= (UINTN
)(OldCheckingBottom
+ SecCoreData
->TemporaryRamSize
);
493 // The whole temporary memory will be migrated to physical memory.
494 // CAUTION: The new base is computed accounding to gap of new stack.
496 NewPermenentMemoryBase
= Private
->PhysicalMemoryBegin
+ StackGap
;
497 Offset
= (UINTN
) NewPermenentMemoryBase
- (UINTN
) SecCoreData
->TemporaryRamBase
;
498 NewHandOffTable
= (EFI_HOB_HANDOFF_INFO_TABLE
*)((UINTN
)OldHandOffTable
+ Offset
);
499 PrivateInMem
= (PEI_CORE_INSTANCE
*)((UINTN
) (VOID
*) Private
+ Offset
);
502 // TemporaryRamSupportPpi is produced by platform's SEC
504 Status
= PeiLocatePpi (
505 (CONST EFI_PEI_SERVICES
**) PeiServices
,
506 &gEfiTemporaryRamSupportPpiGuid
,
509 (VOID
**)&TemporaryRamSupportPpi
513 if (!EFI_ERROR (Status
)) {
514 TemporaryRamSupportPpi
->TemporaryRamMigration (
515 (CONST EFI_PEI_SERVICES
**) PeiServices
,
516 (EFI_PHYSICAL_ADDRESS
)(UINTN
) SecCoreData
->TemporaryRamBase
,
517 (EFI_PHYSICAL_ADDRESS
)(UINTN
) NewPermenentMemoryBase
,
518 SecCoreData
->TemporaryRamSize
523 (VOID
*)(UINTN
) NewPermenentMemoryBase
,
524 SecCoreData
->TemporaryRamBase
,
525 SecCoreData
->TemporaryRamSize
532 // Fixup the PeiCore's private data
534 PrivateInMem
->PS
= &PrivateInMem
->ServiceTableShadow
;
535 PrivateInMem
->CpuIo
= &PrivateInMem
->ServiceTableShadow
.CpuIo
;
536 PrivateInMem
->HobList
.Raw
= (VOID
*) ((UINTN
) PrivateInMem
->HobList
.Raw
+ Offset
);
537 PrivateInMem
->StackBase
= (EFI_PHYSICAL_ADDRESS
)(((UINTN
)PrivateInMem
->PhysicalMemoryBegin
+ EFI_PAGE_MASK
) & ~EFI_PAGE_MASK
);
539 PeiServices
= &PrivateInMem
->PS
;
542 // Fixup for PeiService's address
544 SetPeiServicesTablePointer(PeiServices
);
547 // Update HandOffHob for new installed permenent memory
549 NewHandOffTable
->EfiEndOfHobList
=
550 (EFI_PHYSICAL_ADDRESS
)(VOID
*)((UINTN
) NewHandOffTable
->EfiEndOfHobList
+ Offset
);
551 NewHandOffTable
->EfiMemoryTop
= PrivateInMem
->PhysicalMemoryBegin
+
552 PrivateInMem
->PhysicalMemoryLength
;
553 NewHandOffTable
->EfiMemoryBottom
= PrivateInMem
->PhysicalMemoryBegin
;
554 NewHandOffTable
->EfiFreeMemoryTop
= PrivateInMem
->FreePhysicalMemoryTop
;
555 NewHandOffTable
->EfiFreeMemoryBottom
= NewHandOffTable
->EfiEndOfHobList
+
556 sizeof (EFI_HOB_GENERIC_HEADER
);
559 // We need convert the PPI desciptor's pointer
561 ConvertPpiPointers ((CONST EFI_PEI_SERVICES
**)PeiServices
,
566 DEBUG ((EFI_D_INFO
, "Stack Hob: BaseAddress=0x%X Length=0x%X\n",
567 (UINTN
)PrivateInMem
->StackBase
,
568 PrivateInMem
->StackSize
));
569 BuildStackHob (PrivateInMem
->StackBase
, PrivateInMem
->StackSize
);
572 // After the whole temporary memory is migrated, then we can allocate page in
575 PrivateInMem
->PeiMemoryInstalled
= TRUE
;
578 // Make sure we don't retry the same PEIM that added memory
580 PrivateInMem
->CurrentPeimCount
++;
583 // Shadow PEI Core. When permanent memory is avaiable, shadow
584 // PEI Core and PEIMs to get high performance.
586 PrivateInMem
->ShadowedPeiCore
= ShadowPeiCore (
591 // Process the Notify list and dispatch any notifies for
592 // newly installed PPIs.
594 ProcessNotifyList (PrivateInMem
);
599 PeiCore (SecCoreData
, NULL
, PrivateInMem
);
602 // Code should not come here
604 ASSERT_EFI_ERROR(FALSE
);
608 // Process the Notify list and dispatch any notifies for
609 // newly installed PPIs.
611 ProcessNotifyList (Private
);
613 if ((Private
->PeiMemoryInstalled
) && (Private
->Fv
[FvCount
].PeimState
[PeimCount
] == PEIM_STATE_REGISITER_FOR_SHADOW
) && \
614 (Private
->HobList
.HandoffInformationTable
->BootMode
!= BOOT_ON_S3_RESUME
)) {
616 // If memory is availble we shadow images by default for performance reasons.
617 // We call the entry point a 2nd time so the module knows it's shadowed.
619 //PERF_START (PeiServices, L"PEIM", PeimFileHandle, 0);
620 PeimEntryPoint (PeimFileHandle
, (const EFI_PEI_SERVICES
**) PeiServices
);
621 //PERF_END (PeiServices, L"PEIM", PeimFileHandle, 0);
624 // PEIM_STATE_REGISITER_FOR_SHADOW move to PEIM_STATE_DONE
626 Private
->Fv
[FvCount
].PeimState
[PeimCount
]++;
629 // Process the Notify list and dispatch any notifies for
630 // newly installed PPIs.
632 ProcessNotifyList (Private
);
639 // We set to NULL here to optimize the 2nd entry to this routine after
640 // memory is found. This reprevents rescanning of the FV. We set to
641 // NULL here so we start at the begining of the next FV
643 Private
->CurrentFileHandle
= NULL
;
644 Private
->CurrentPeimCount
= 0;
646 // Before walking through the next FV,Private->CurrentFvFileHandles[]should set to NULL
648 SetMem (Private
->CurrentFvFileHandles
, sizeof (Private
->CurrentFvFileHandles
), 0);
652 // Before making another pass, we should set Private->CurrentPeimFvCount =0 to go
653 // through all the FV.
655 Private
->CurrentPeimFvCount
= 0;
658 // PeimNeedingDispatch being TRUE means we found a PEIM that did not get
659 // dispatched. So we need to make another pass
661 // PeimDispatchOnThisPass being TRUE means we dispatched a PEIM on this
662 // pass. If we did not dispatch a PEIM there is no point in trying again
663 // as it will fail the next time too (nothing has changed).
665 } while (PeimNeedingDispatch
&& PeimDispatchOnThisPass
);
670 InitializeDispatcherData (
671 IN PEI_CORE_INSTANCE
*PrivateData
,
672 IN PEI_CORE_INSTANCE
*OldCoreData
,
673 IN CONST EFI_SEC_PEI_HAND_OFF
*SecCoreData
679 Initialize the Dispatcher's data members
683 PeiServices - The PEI core services table.
684 OldCoreData - Pointer to old core data (before switching stack).
685 NULL if being run in non-permament memory mode.
686 SecCoreData - Points to a data structure containing information about the PEI core's operating
687 environment, such as the size and location of temporary RAM, the stack location and
696 if (OldCoreData
== NULL
) {
697 PeiInitializeFv (PrivateData
, SecCoreData
);
706 IN PEI_CORE_INSTANCE
*Private
,
707 IN EFI_PEI_FILE_HANDLE FileHandle
,
714 This routine parses the Dependency Expression, if available, and
715 decides if the module can be executed.
718 PeiServices - The PEI Service Table
719 CurrentPeimAddress - Address of the PEIM Firmware File under investigation
722 TRUE - Can be dispatched
723 FALSE - Cannot be dispatched
730 if (PeimCount
< Private
->AprioriCount
) {
732 // If its in the A priori file then we set Depex to TRUE
738 // Depex section not in the encapsulated section.
740 Status
= PeiServicesFfsFindSectionData (
741 EFI_SECTION_PEI_DEPEX
,
746 if (EFI_ERROR (Status
)) {
748 // If there is no DEPEX, assume the module can be executed
754 // Evaluate a given DEPEX
756 return PeimDispatchReadiness (&Private
->PS
, DepexData
);
760 This routine enable a PEIM to register itself to shadow when PEI Foundation
761 discovery permanent memory.
763 @param FileHandle File handle of a PEIM.
765 @retval EFI_NOT_FOUND The file handle doesn't point to PEIM itself.
766 @retval EFI_ALREADY_STARTED Indicate that the PEIM has been registered itself.
767 @retval EFI_SUCCESS Successfully to register itself.
772 PeiRegisterForShadow (
773 IN EFI_PEI_FILE_HANDLE FileHandle
776 PEI_CORE_INSTANCE
*Private
;
777 Private
= PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());
779 if (Private
->CurrentFileHandle
!= FileHandle
) {
781 // The FileHandle must be for the current PEIM
783 return EFI_NOT_FOUND
;
786 if (Private
->Fv
[Private
->CurrentPeimFvCount
].PeimState
[Private
->CurrentPeimCount
] >= PEIM_STATE_REGISITER_FOR_SHADOW
) {
788 // If the PEIM has already entered the PEIM_STATE_REGISTER_FOR_SHADOW or PEIM_STATE_DONE then it's already been started
790 return EFI_ALREADY_STARTED
;
793 Private
->Fv
[Private
->CurrentPeimFvCount
].PeimState
[Private
->CurrentPeimCount
] = PEIM_STATE_REGISITER_FOR_SHADOW
;
801 Get Fv image from the FV type file, then install FV INFO ppi, Build FV hob.
803 @param PeiServices Pointer to the PEI Core Services Table.
804 @param FileHandle File handle of a Fv type file.
805 @param AuthenticationState Pointer to attestation authentication state of image.
808 @retval EFI_NOT_FOUND FV image can't be found.
809 @retval EFI_SUCCESS Successfully to process it.
814 IN EFI_PEI_SERVICES
**PeiServices
,
815 IN EFI_PEI_FILE_HANDLE FvFileHandle
,
816 OUT UINT32
*AuthenticationState
820 EFI_PEI_FV_HANDLE FvImageHandle
;
821 EFI_FV_INFO FvImageInfo
;
824 EFI_PEI_HOB_POINTERS HobFv2
;
827 *AuthenticationState
= 0;
830 // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already
833 HobFv2
.Raw
= GetHobList ();
834 while ((HobFv2
.Raw
= GetNextHob (EFI_HOB_TYPE_FV2
, HobFv2
.Raw
)) != NULL
) {
835 if (CompareGuid (&(((EFI_FFS_FILE_HEADER
*)FvFileHandle
)->Name
), &HobFv2
.FirmwareVolume2
->FileName
)) {
837 // this FILE has been dispatched, it will not be dispatched again.
841 HobFv2
.Raw
= GET_NEXT_HOB (HobFv2
);
845 // Find FvImage in FvFile
847 Status
= PeiFfsFindSectionData (
848 (CONST EFI_PEI_SERVICES
**) PeiServices
,
849 EFI_SECTION_FIRMWARE_VOLUME_IMAGE
,
851 (VOID
**)&FvImageHandle
854 if (EFI_ERROR (Status
)) {
858 // Collect FvImage Info.
860 Status
= PeiFfsGetVolumeInfo (FvImageHandle
, &FvImageInfo
);
861 ASSERT_EFI_ERROR (Status
);
863 // FvAlignment must be more than 8 bytes required by FvHeader structure.
865 FvAlignment
= 1 << ((FvImageInfo
.FvAttributes
& EFI_FVB2_ALIGNMENT
) >> 16);
866 if (FvAlignment
< 8) {
872 if ((UINTN
) FvImageInfo
.FvStart
% FvAlignment
!= 0) {
873 FvBuffer
= AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINT32
) FvImageInfo
.FvSize
), FvAlignment
);
874 if (FvBuffer
== NULL
) {
875 return EFI_OUT_OF_RESOURCES
;
877 CopyMem (FvBuffer
, FvImageInfo
.FvStart
, (UINTN
) FvImageInfo
.FvSize
);
879 // Update FvImageInfo after reload FvImage to new aligned memory
881 PeiFfsGetVolumeInfo ((EFI_PEI_FV_HANDLE
) FvBuffer
, &FvImageInfo
);
885 // Install FvPpi and Build FvHob
887 PiLibInstallFvInfoPpi (
890 (UINT32
) FvImageInfo
.FvSize
,
891 &(FvImageInfo
.FvName
),
892 &(((EFI_FFS_FILE_HEADER
*)FvFileHandle
)->Name
)
896 // Inform HOB consumer phase, i.e. DXE core, the existance of this FV
899 (EFI_PHYSICAL_ADDRESS
) (UINTN
) FvImageInfo
.FvStart
,
903 // Makes the encapsulated volume show up in DXE phase to skip processing of
904 // encapsulated file again.
907 (EFI_PHYSICAL_ADDRESS
) (UINTN
) FvImageInfo
.FvStart
,
910 &(((EFI_FFS_FILE_HEADER
*)FvFileHandle
)->Name
)