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
27 EFI_STATUS_CODE_DATA DataHeader
;
29 } PEIM_FILE_HANDLE_EXTENDED_DATA
;
32 DiscoverPeimsAndOrderWithApriori (
33 IN PEI_CORE_INSTANCE
*Private
,
34 IN EFI_PEI_FV_HANDLE VolumeHandle
40 Discover all Peims and optional Apriori file in one FV. There is at most one
41 Apriori file in one FV.
45 Private - Pointer to the private data passed in from caller
46 VolumeHandle - Fv handle.
54 EFI_PEI_FV_HANDLE FileHandle
;
55 EFI_PEI_FILE_HANDLE AprioriFileHandle
;
62 EFI_PEI_FV_HANDLE TempFileHandles
[FixedPcdGet32 (PcdPeiCoreMaxPeimPerFv
)];
63 EFI_GUID FileGuid
[FixedPcdGet32 (PcdPeiCoreMaxPeimPerFv
)];
66 // Walk the FV and find all the PEIMs and the Apriori file.
68 AprioriFileHandle
= NULL
;
69 Private
->CurrentFvFileHandles
[0] = NULL
;
74 // If the current Fv has been scanned, directly get its cachable record.
76 if (Private
->Fv
[Private
->CurrentPeimFvCount
].ScanFv
) {
77 CopyMem (Private
->CurrentFvFileHandles
, Private
->Fv
[Private
->CurrentPeimFvCount
].FvFileHandles
, sizeof (Private
->CurrentFvFileHandles
));
82 // Go ahead to scan this Fv, and cache FileHandles within it.
84 for (PeimCount
= 0; PeimCount
< FixedPcdGet32 (PcdPeiCoreMaxPeimPerFv
); PeimCount
++) {
85 Status
= PeiFindFileEx (
88 PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE
,
92 if (Status
!= EFI_SUCCESS
) {
96 Private
->CurrentFvFileHandles
[PeimCount
] = FileHandle
;
99 Private
->AprioriCount
= 0;
100 if (AprioriFileHandle
!= NULL
) {
102 // Read the Apriori file
104 Status
= PeiServicesFfsFindSectionData (EFI_SECTION_RAW
, AprioriFileHandle
, (VOID
**) &Apriori
);
105 if (!EFI_ERROR (Status
)) {
107 // Calculate the number of PEIMs in the A Priori list
109 Private
->AprioriCount
= *(UINT32
*)(((EFI_FFS_FILE_HEADER
*)AprioriFileHandle
)->Size
) & 0x00FFFFFF;
110 Private
->AprioriCount
-= sizeof (EFI_FFS_FILE_HEADER
) - sizeof (EFI_COMMON_SECTION_HEADER
);
111 Private
->AprioriCount
/= sizeof (EFI_GUID
);
113 SetMem (FileGuid
, sizeof (FileGuid
), 0);
114 for (Index
= 0; Index
< PeimCount
; Index
++) {
116 // Make an array of file name guids that matches the FileHandle array so we can convert
117 // quickly from file name to file handle
119 CopyMem (&FileGuid
[Index
], &((EFI_FFS_FILE_HEADER
*)Private
->CurrentFvFileHandles
[Index
])->Name
,sizeof(EFI_GUID
));
123 // Walk through FileGuid array to find out who is invalid PEIM guid in Apriori file.
124 // Add avalible PEIMs in Apriori file into TempFileHandles array at first.
127 for (Index
= 0; Index2
< Private
->AprioriCount
; Index
++) {
128 while (Index2
< Private
->AprioriCount
) {
129 Guid
= ScanGuid (FileGuid
, PeimCount
* sizeof (EFI_GUID
), &Apriori
[Index2
++]);
137 PeimIndex
= ((UINTN
)Guid
- (UINTN
)&FileGuid
[0])/sizeof (EFI_GUID
);
138 TempFileHandles
[Index
] = Private
->CurrentFvFileHandles
[PeimIndex
];
141 // Since we have copied the file handle we can remove it from this list.
143 Private
->CurrentFvFileHandles
[PeimIndex
] = NULL
;
147 // Update valid Aprioricount
149 Private
->AprioriCount
= Index
;
152 // Add in any PEIMs not in the Apriori file
154 for (;Index
< PeimCount
; Index
++) {
155 for (Index2
= 0; Index2
< PeimCount
; Index2
++) {
156 if (Private
->CurrentFvFileHandles
[Index2
] != NULL
) {
157 TempFileHandles
[Index
] = Private
->CurrentFvFileHandles
[Index2
];
158 Private
->CurrentFvFileHandles
[Index2
] = NULL
;
164 //Index the end of array contains re-range Pei moudle.
166 TempFileHandles
[Index
] = NULL
;
169 // Private->CurrentFvFileHandles is currently in PEIM in the FV order.
170 // We need to update it to start with files in the A Priori list and
171 // then the remaining files in PEIM order.
173 CopyMem (Private
->CurrentFvFileHandles
, TempFileHandles
, sizeof (Private
->CurrentFvFileHandles
));
177 // Cache the current Fv File Handle. So that we don't have to scan the Fv again.
178 // Instead, we can retrieve the file handles within this Fv from cachable data.
180 Private
->Fv
[Private
->CurrentPeimFvCount
].ScanFv
= TRUE
;
181 CopyMem (Private
->Fv
[Private
->CurrentPeimFvCount
].FvFileHandles
, Private
->CurrentFvFileHandles
, sizeof (Private
->CurrentFvFileHandles
));
187 EFI_PEI_SERVICES
**PeiServices
,
188 PEI_CORE_INSTANCE
*PrivateInMem
191 EFI_PEI_FILE_HANDLE PeiCoreFileHandle
;
192 EFI_PHYSICAL_ADDRESS EntryPoint
;
194 UINT32 AuthenticationState
;
196 PeiCoreFileHandle
= NULL
;
199 // Find the PEI Core in the BFV
201 Status
= PeiFindFileEx (
202 (EFI_PEI_FV_HANDLE
)PrivateInMem
->Fv
[0].FvHeader
,
204 EFI_FV_FILETYPE_PEI_CORE
,
208 ASSERT_EFI_ERROR (Status
);
211 // Shadow PEI Core into memory so it will run faster
213 Status
= PeiLoadImage (
215 *((EFI_PEI_FILE_HANDLE
*)&PeiCoreFileHandle
),
219 ASSERT_EFI_ERROR (Status
);
221 return (VOID
*) ((UINTN
) EntryPoint
+ (UINTN
) PeiCore
- (UINTN
) _ModuleEntryPoint
);
226 IN CONST EFI_SEC_PEI_HAND_OFF
*SecCoreData
,
227 IN PEI_CORE_INSTANCE
*Private
234 Conduct PEIM dispatch.
238 SecCoreData - Points to a data structure containing information about the PEI core's operating
239 environment, such as the size and location of temporary RAM, the stack location and
241 PrivateData - Pointer to the private data passed in from caller
242 DispatchData - Pointer to PEI_CORE_DISPATCH_DATA data.
246 EFI_SUCCESS - Successfully dispatched PEIM.
247 EFI_NOT_FOUND - The dispatch failed.
254 EFI_PEI_SERVICES
**PeiServices
;
255 EFI_PEI_FV_HANDLE VolumeHandle
;
256 //EFI_PHYSICAL_ADDRESS PeiCoreFileHandle;
257 EFI_PEI_FILE_HANDLE PeimFileHandle
;
260 UINT32 AuthenticationState
;
261 EFI_PHYSICAL_ADDRESS EntryPoint
;
262 EFI_PEIM_ENTRY_POINT2 PeimEntryPoint
;
263 BOOLEAN PeimNeedingDispatch
;
264 BOOLEAN PeimDispatchOnThisPass
;
265 UINTN SaveCurrentPeimCount
;
266 UINTN SaveCurrentFvCount
;
267 EFI_PEI_FILE_HANDLE SaveCurrentFileHandle
;
268 PEIM_FILE_HANDLE_EXTENDED_DATA ExtendedData
;
269 EFI_PHYSICAL_ADDRESS NewPermenentMemoryBase
;
270 TEMPORARY_RAM_SUPPORT_PPI
*TemporaryRamSupportPpi
;
271 EFI_HOB_HANDOFF_INFO_TABLE
*OldHandOffTable
;
272 EFI_HOB_HANDOFF_INFO_TABLE
*NewHandOffTable
;
274 PEI_CORE_INSTANCE
*PrivateInMem
;
275 UINT64 NewPeiStackSize
;
276 UINT64 OldPeiStackSize
;
278 EFI_FV_FILE_INFO FvFileInfo
;
279 UINTN OldCheckingTop
;
280 UINTN OldCheckingBottom
;
283 PeiServices
= &Private
->PS
;
284 PeimEntryPoint
= NULL
;
285 PeimFileHandle
= NULL
;
288 if ((Private
->PeiMemoryInstalled
) && (Private
->HobList
.HandoffInformationTable
->BootMode
!= BOOT_ON_S3_RESUME
)) {
290 // Once real memory is available, shadow the RegisterForShadow modules. And meanwhile
291 // update the modules' status from PEIM_STATE_REGISITER_FOR_SHADOW to PEIM_STATE_DONE.
293 SaveCurrentPeimCount
= Private
->CurrentPeimCount
;
294 SaveCurrentFvCount
= Private
->CurrentPeimFvCount
;
295 SaveCurrentFileHandle
= Private
->CurrentFileHandle
;
297 for (Index1
= 0; Index1
<= SaveCurrentFvCount
; Index1
++) {
298 for (Index2
= 0; (Index2
< FixedPcdGet32 (PcdPeiCoreMaxPeimPerFv
)) && (Private
->Fv
[Index1
].FvFileHandles
[Index2
] != NULL
); Index2
++) {
299 if (Private
->Fv
[Index1
].PeimState
[Index2
] == PEIM_STATE_REGISITER_FOR_SHADOW
) {
300 PeimFileHandle
= Private
->Fv
[Index1
].FvFileHandles
[Index2
];
301 Status
= PeiLoadImage (
307 if (Status
== EFI_SUCCESS
) {
309 // PEIM_STATE_REGISITER_FOR_SHADOW move to PEIM_STATE_DONE
311 Private
->Fv
[Index1
].PeimState
[Index2
]++;
312 Private
->CurrentFileHandle
= PeimFileHandle
;
313 Private
->CurrentPeimFvCount
= Index1
;
314 Private
->CurrentPeimCount
= Index2
;
316 // Call the PEIM entry point
318 PeimEntryPoint
= (EFI_PEIM_ENTRY_POINT2
)(UINTN
)EntryPoint
;
320 PERF_START (0, "PEIM", NULL
, 0);
321 PeimEntryPoint(PeimFileHandle
, (const EFI_PEI_SERVICES
**) &Private
->PS
);
322 PERF_END (0, "PEIM", NULL
, 0);
326 // Process the Notify list and dispatch any notifies for
327 // newly installed PPIs.
329 ProcessNotifyList (Private
);
333 Private
->CurrentFileHandle
= SaveCurrentFileHandle
;
334 Private
->CurrentPeimFvCount
= SaveCurrentFvCount
;
335 Private
->CurrentPeimCount
= SaveCurrentPeimCount
;
339 // This is the main dispatch loop. It will search known FVs for PEIMs and
340 // attempt to dispatch them. If any PEIM gets dispatched through a single
341 // pass of the dispatcher, it will start over from the Bfv again to see
342 // if any new PEIMs dependencies got satisfied. With a well ordered
343 // FV where PEIMs are found in the order their dependencies are also
344 // satisfied, this dipatcher should run only once.
347 PeimNeedingDispatch
= FALSE
;
348 PeimDispatchOnThisPass
= FALSE
;
350 for (FvCount
= Private
->CurrentPeimFvCount
; FvCount
< Private
->FvCount
; FvCount
++) {
351 Private
->CurrentPeimFvCount
= FvCount
;
352 VolumeHandle
= Private
->Fv
[FvCount
].FvHeader
;
354 if (Private
->CurrentPeimCount
== 0) {
356 // When going through each FV, at first, search Apriori file to
357 // reorder all PEIMs to ensure the PEIMs in Apriori file to get
358 // dispatch at first.
360 DiscoverPeimsAndOrderWithApriori (Private
, VolumeHandle
);
364 // Start to dispatch all modules within the current Fv.
366 for (PeimCount
= Private
->CurrentPeimCount
;
367 (PeimCount
< FixedPcdGet32 (PcdPeiCoreMaxPeimPerFv
)) && (Private
->CurrentFvFileHandles
[PeimCount
] != NULL
);
369 Private
->CurrentPeimCount
= PeimCount
;
370 PeimFileHandle
= Private
->CurrentFileHandle
= Private
->CurrentFvFileHandles
[PeimCount
];
372 if (Private
->Fv
[FvCount
].PeimState
[PeimCount
] == PEIM_STATE_NOT_DISPATCHED
) {
373 if (!DepexSatisfied (Private
, PeimFileHandle
, PeimCount
)) {
374 PeimNeedingDispatch
= TRUE
;
376 Status
= PeiFfsGetFileInfo (PeimFileHandle
, &FvFileInfo
);
377 ASSERT_EFI_ERROR (Status
);
378 if (FvFileInfo
.FileType
== EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
) {
380 // For Fv type file, Produce new FV PPI and FV hob
382 Status
= ProcessFvFile (PeiServices
, PeimFileHandle
, &AuthenticationState
);
385 // For PEIM driver, Load its entry point
387 Status
= PeiLoadImage (
395 if ((Status
== EFI_SUCCESS
)) {
397 // The PEIM has its dependencies satisfied, and its entry point
398 // has been found, so invoke it.
400 PERF_START (0, "PEIM", NULL
, 0);
402 ExtendedData
.Handle
= (EFI_HANDLE
)PeimFileHandle
;
404 REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
406 FixedPcdGet32(PcdStatusCodeValuePeimDispatch
),
407 (VOID
*)(&ExtendedData
),
408 sizeof (ExtendedData
)
411 Status
= VerifyPeim (Private
, VolumeHandle
, PeimFileHandle
);
412 if (Status
!= EFI_SECURITY_VIOLATION
&& (AuthenticationState
== 0)) {
414 // PEIM_STATE_NOT_DISPATCHED move to PEIM_STATE_DISPATCHED
416 Private
->Fv
[FvCount
].PeimState
[PeimCount
]++;
418 if (FvFileInfo
.FileType
!= EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
) {
420 // Call the PEIM entry point for PEIM driver
422 PeimEntryPoint
= (EFI_PEIM_ENTRY_POINT2
)(UINTN
)EntryPoint
;
423 PeimEntryPoint (PeimFileHandle
, (const EFI_PEI_SERVICES
**) PeiServices
);
426 PeimDispatchOnThisPass
= TRUE
;
429 REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
431 FixedPcdGet32(PcdStatusCodeValuePeimDispatch
),
432 (VOID
*)(&ExtendedData
),
433 sizeof (ExtendedData
)
435 PERF_END (0, "PEIM", NULL
, 0);
439 if (Private
->SwitchStackSignal
) {
442 // Reserve the size of new stack at bottom of physical memory
444 OldPeiStackSize
= Private
->StackSize
;
445 NewPeiStackSize
= (RShiftU64 (Private
->PhysicalMemoryLength
, 1) + EFI_PAGE_MASK
) & ~EFI_PAGE_MASK
;
446 if (FixedPcdGet32(PcdPeiCoreMaxPeiStackSize
) > (UINT32
) NewPeiStackSize
) {
447 Private
->StackSize
= NewPeiStackSize
;
449 Private
->StackSize
= FixedPcdGet32(PcdPeiCoreMaxPeiStackSize
);
453 // In theory, the size of new stack in permenent memory should large than
454 // size of old stack in temporary memory.
455 // But if new stack is smaller than the size of old stack, we also reserve
456 // the size of old stack at bottom of permenent memory.
459 if (Private
->StackSize
> OldPeiStackSize
) {
460 StackGap
= Private
->StackSize
- OldPeiStackSize
;
464 // Update HandOffHob for new installed permenent memory
466 OldHandOffTable
= Private
->HobList
.HandoffInformationTable
;
467 OldCheckingBottom
= (UINTN
)OldHandOffTable
;
468 OldCheckingTop
= (UINTN
)(OldCheckingBottom
+ SecCoreData
->TemporaryRamSize
);
471 // The whole temporary memory will be migrated to physical memory.
472 // CAUTION: The new base is computed accounding to gap of new stack.
474 NewPermenentMemoryBase
= Private
->PhysicalMemoryBegin
+ StackGap
;
475 Offset
= (UINTN
) NewPermenentMemoryBase
- (UINTN
) SecCoreData
->TemporaryRamBase
;
476 NewHandOffTable
= (EFI_HOB_HANDOFF_INFO_TABLE
*)((UINTN
)OldHandOffTable
+ Offset
);
477 PrivateInMem
= (PEI_CORE_INSTANCE
*)((UINTN
) (VOID
*) Private
+ Offset
);
480 // TemporaryRamSupportPpi is produced by platform's SEC
482 Status
= PeiLocatePpi (
483 (CONST EFI_PEI_SERVICES
**) PeiServices
,
484 &gEfiTemporaryRamSupportPpiGuid
,
487 (VOID
**)&TemporaryRamSupportPpi
491 if (!EFI_ERROR (Status
)) {
492 TemporaryRamSupportPpi
->TemporaryRamMigration (
493 (CONST EFI_PEI_SERVICES
**) PeiServices
,
494 (EFI_PHYSICAL_ADDRESS
)(UINTN
) SecCoreData
->TemporaryRamBase
,
495 (EFI_PHYSICAL_ADDRESS
)(UINTN
) NewPermenentMemoryBase
,
496 SecCoreData
->TemporaryRamSize
501 (VOID
*)(UINTN
) NewPermenentMemoryBase
,
502 SecCoreData
->TemporaryRamBase
,
503 SecCoreData
->TemporaryRamSize
510 // Fixup the PeiCore's private data
512 PrivateInMem
->PS
= &PrivateInMem
->ServiceTableShadow
;
513 PrivateInMem
->CpuIo
= &PrivateInMem
->ServiceTableShadow
.CpuIo
;
514 PrivateInMem
->HobList
.Raw
= (VOID
*) ((UINTN
) PrivateInMem
->HobList
.Raw
+ Offset
);
515 PrivateInMem
->StackBase
= (EFI_PHYSICAL_ADDRESS
)(((UINTN
)PrivateInMem
->PhysicalMemoryBegin
+ EFI_PAGE_MASK
) & ~EFI_PAGE_MASK
);
517 PeiServices
= &PrivateInMem
->PS
;
520 // Fixup for PeiService's address
522 SetPeiServicesTablePointer(PeiServices
);
525 // Update HandOffHob for new installed permenent memory
527 NewHandOffTable
->EfiEndOfHobList
=
528 (EFI_PHYSICAL_ADDRESS
)(VOID
*)((UINTN
) NewHandOffTable
->EfiEndOfHobList
+ Offset
);
529 NewHandOffTable
->EfiMemoryTop
= PrivateInMem
->PhysicalMemoryBegin
+
530 PrivateInMem
->PhysicalMemoryLength
;
531 NewHandOffTable
->EfiMemoryBottom
= PrivateInMem
->PhysicalMemoryBegin
;
532 NewHandOffTable
->EfiFreeMemoryTop
= PrivateInMem
->FreePhysicalMemoryTop
;
533 NewHandOffTable
->EfiFreeMemoryBottom
= NewHandOffTable
->EfiEndOfHobList
+
534 sizeof (EFI_HOB_GENERIC_HEADER
);
537 // We need convert the PPI desciptor's pointer
539 ConvertPpiPointers ((CONST EFI_PEI_SERVICES
**)PeiServices
,
544 DEBUG ((EFI_D_INFO
, "Stack Hob: BaseAddress=0x%X Length=0x%X\n",
545 (UINTN
)PrivateInMem
->StackBase
,
546 PrivateInMem
->StackSize
));
547 BuildStackHob (PrivateInMem
->StackBase
, PrivateInMem
->StackSize
);
550 // After the whole temporary memory is migrated, then we can allocate page in
553 PrivateInMem
->PeiMemoryInstalled
= TRUE
;
556 // Make sure we don't retry the same PEIM that added memory
558 PrivateInMem
->CurrentPeimCount
++;
561 // Shadow PEI Core. When permanent memory is avaiable, shadow
562 // PEI Core and PEIMs to get high performance.
564 //PeiCoreFileHandle = 0;
566 // Find the PEI Core in the BFV
568 //Status = PeiFindFileEx (
569 // (EFI_PEI_FV_HANDLE)PrivateInMem->Fv[0].FvHeader,
571 // EFI_FV_FILETYPE_PEI_CORE,
572 // (EFI_PEI_FILE_HANDLE*)&PeiCoreFileHandle,
575 //ASSERT_EFI_ERROR (Status);
578 // Shadow PEI Core into memory so it will run faster
580 //Status = PeiLoadImage (
582 // *((EFI_PEI_FILE_HANDLE*)&PeiCoreFileHandle),
584 // &AuthenticationState
586 //ASSERT_EFI_ERROR (Status);
588 //PrivateInMem->ShadowedPeiCore = (VOID*) ((UINTN) EntryPoint +
590 // (UINTN) _ModuleEntryPoint);
591 PrivateInMem
->ShadowedPeiCore
= ShadowPeiCore (
596 // Process the Notify list and dispatch any notifies for
597 // newly installed PPIs.
599 ProcessNotifyList (PrivateInMem
);
604 PeiCore (SecCoreData
, NULL
, PrivateInMem
);
606 //((PEI_CORE_ENTRY_POINT) (UINTN) PrivateInMem->ShadowedPeiCore) (
613 // Code should not come here
615 ASSERT_EFI_ERROR(FALSE
);
619 // Process the Notify list and dispatch any notifies for
620 // newly installed PPIs.
622 ProcessNotifyList (Private
);
624 if ((Private
->PeiMemoryInstalled
) && (Private
->Fv
[FvCount
].PeimState
[PeimCount
] == PEIM_STATE_REGISITER_FOR_SHADOW
) && \
625 (Private
->HobList
.HandoffInformationTable
->BootMode
!= BOOT_ON_S3_RESUME
)) {
627 // If memory is availble we shadow images by default for performance reasons.
628 // We call the entry point a 2nd time so the module knows it's shadowed.
630 //PERF_START (PeiServices, L"PEIM", PeimFileHandle, 0);
631 PeimEntryPoint (PeimFileHandle
, (const EFI_PEI_SERVICES
**) PeiServices
);
632 //PERF_END (PeiServices, L"PEIM", PeimFileHandle, 0);
635 // PEIM_STATE_REGISITER_FOR_SHADOW move to PEIM_STATE_DONE
637 Private
->Fv
[FvCount
].PeimState
[PeimCount
]++;
640 // Process the Notify list and dispatch any notifies for
641 // newly installed PPIs.
643 ProcessNotifyList (Private
);
650 // We set to NULL here to optimize the 2nd entry to this routine after
651 // memory is found. This reprevents rescanning of the FV. We set to
652 // NULL here so we start at the begining of the next FV
654 Private
->CurrentFileHandle
= NULL
;
655 Private
->CurrentPeimCount
= 0;
657 // Before walking through the next FV,Private->CurrentFvFileHandles[]should set to NULL
659 SetMem (Private
->CurrentFvFileHandles
, sizeof (Private
->CurrentFvFileHandles
), 0);
663 // Before making another pass, we should set Private->CurrentPeimFvCount =0 to go
664 // through all the FV.
666 Private
->CurrentPeimFvCount
= 0;
669 // PeimNeedingDispatch being TRUE means we found a PEIM that did not get
670 // dispatched. So we need to make another pass
672 // PeimDispatchOnThisPass being TRUE means we dispatched a PEIM on this
673 // pass. If we did not dispatch a PEIM there is no point in trying again
674 // as it will fail the next time too (nothing has changed).
676 } while (PeimNeedingDispatch
&& PeimDispatchOnThisPass
);
681 InitializeDispatcherData (
682 IN PEI_CORE_INSTANCE
*PrivateData
,
683 IN PEI_CORE_INSTANCE
*OldCoreData
,
684 IN CONST EFI_SEC_PEI_HAND_OFF
*SecCoreData
690 Initialize the Dispatcher's data members
694 PeiServices - The PEI core services table.
695 OldCoreData - Pointer to old core data (before switching stack).
696 NULL if being run in non-permament memory mode.
697 SecCoreData - Points to a data structure containing information about the PEI core's operating
698 environment, such as the size and location of temporary RAM, the stack location and
707 if (OldCoreData
== NULL
) {
708 PeiInitializeFv (PrivateData
, SecCoreData
);
717 IN PEI_CORE_INSTANCE
*Private
,
718 IN EFI_PEI_FILE_HANDLE FileHandle
,
725 This routine parses the Dependency Expression, if available, and
726 decides if the module can be executed.
729 PeiServices - The PEI Service Table
730 CurrentPeimAddress - Address of the PEIM Firmware File under investigation
733 TRUE - Can be dispatched
734 FALSE - Cannot be dispatched
741 if (PeimCount
< Private
->AprioriCount
) {
743 // If its in the A priori file then we set Depex to TRUE
749 // Depex section not in the encapsulated section.
751 Status
= PeiServicesFfsFindSectionData (
752 EFI_SECTION_PEI_DEPEX
,
757 if (EFI_ERROR (Status
)) {
759 // If there is no DEPEX, assume the module can be executed
765 // Evaluate a given DEPEX
767 return PeimDispatchReadiness (&Private
->PS
, DepexData
);
771 This routine enable a PEIM to register itself to shadow when PEI Foundation
772 discovery permanent memory.
774 @param FileHandle File handle of a PEIM.
776 @retval EFI_NOT_FOUND The file handle doesn't point to PEIM itself.
777 @retval EFI_ALREADY_STARTED Indicate that the PEIM has been registered itself.
778 @retval EFI_SUCCESS Successfully to register itself.
783 PeiRegisterForShadow (
784 IN EFI_PEI_FILE_HANDLE FileHandle
787 PEI_CORE_INSTANCE
*Private
;
788 Private
= PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());
790 if (Private
->CurrentFileHandle
!= FileHandle
) {
792 // The FileHandle must be for the current PEIM
794 return EFI_NOT_FOUND
;
797 if (Private
->Fv
[Private
->CurrentPeimFvCount
].PeimState
[Private
->CurrentPeimCount
] >= PEIM_STATE_REGISITER_FOR_SHADOW
) {
799 // If the PEIM has already entered the PEIM_STATE_REGISTER_FOR_SHADOW or PEIM_STATE_DONE then it's already been started
801 return EFI_ALREADY_STARTED
;
804 Private
->Fv
[Private
->CurrentPeimFvCount
].PeimState
[Private
->CurrentPeimCount
] = PEIM_STATE_REGISITER_FOR_SHADOW
;
812 Get Fv image from the FV type file, then install FV INFO ppi, Build FV hob.
814 @param PeiServices Pointer to the PEI Core Services Table.
815 @param FileHandle File handle of a Fv type file.
816 @param AuthenticationState Pointer to attestation authentication state of image.
819 @retval EFI_NOT_FOUND FV image can't be found.
820 @retval EFI_SUCCESS Successfully to process it.
825 IN EFI_PEI_SERVICES
**PeiServices
,
826 IN EFI_PEI_FILE_HANDLE FvFileHandle
,
827 OUT UINT32
*AuthenticationState
831 EFI_PEI_FV_HANDLE FvImageHandle
;
832 EFI_FV_INFO FvImageInfo
;
835 EFI_PEI_HOB_POINTERS HobFv2
;
838 *AuthenticationState
= 0;
841 // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already
844 HobFv2
.Raw
= GetHobList ();
845 while ((HobFv2
.Raw
= GetNextHob (EFI_HOB_TYPE_FV2
, HobFv2
.Raw
)) != NULL
) {
846 if (CompareGuid (&(((EFI_FFS_FILE_HEADER
*)FvFileHandle
)->Name
), &HobFv2
.FirmwareVolume2
->FileName
)) {
848 // this FILE has been dispatched, it will not be dispatched again.
852 HobFv2
.Raw
= GET_NEXT_HOB (HobFv2
);
856 // Find FvImage in FvFile
858 Status
= PeiFfsFindSectionData (
859 (CONST EFI_PEI_SERVICES
**) PeiServices
,
860 EFI_SECTION_FIRMWARE_VOLUME_IMAGE
,
862 (VOID
**)&FvImageHandle
865 if (EFI_ERROR (Status
)) {
869 // Collect FvImage Info.
871 Status
= PeiFfsGetVolumeInfo (FvImageHandle
, &FvImageInfo
);
872 ASSERT_EFI_ERROR (Status
);
874 // FvAlignment must be more than 8 bytes required by FvHeader structure.
876 FvAlignment
= 1 << ((FvImageInfo
.FvAttributes
& EFI_FVB2_ALIGNMENT
) >> 16);
877 if (FvAlignment
< 8) {
883 if ((UINTN
) FvImageInfo
.FvStart
% FvAlignment
!= 0) {
884 FvBuffer
= AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINT32
) FvImageInfo
.FvSize
), FvAlignment
);
885 if (FvBuffer
== NULL
) {
886 return EFI_OUT_OF_RESOURCES
;
888 CopyMem (FvBuffer
, FvImageInfo
.FvStart
, (UINTN
) FvImageInfo
.FvSize
);
890 // Update FvImageInfo after reload FvImage to new aligned memory
892 PeiFfsGetVolumeInfo ((EFI_PEI_FV_HANDLE
) FvBuffer
, &FvImageInfo
);
896 // Install FvPpi and Build FvHob
898 PiLibInstallFvInfoPpi (
901 (UINT32
) FvImageInfo
.FvSize
,
902 &(FvImageInfo
.FvName
),
903 &(((EFI_FFS_FILE_HEADER
*)FvFileHandle
)->Name
)
907 // Inform HOB consumer phase, i.e. DXE core, the existance of this FV
910 (EFI_PHYSICAL_ADDRESS
) (UINTN
) FvImageInfo
.FvStart
,
914 // Makes the encapsulated volume show up in DXE phase to skip processing of
915 // encapsulated file again.
918 (EFI_PHYSICAL_ADDRESS
) (UINTN
) FvImageInfo
.FvStart
,
921 &(((EFI_FFS_FILE_HEADER
*)FvFileHandle
)->Name
)