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 //CAR is filled with this initial value during SEC phase
29 #define INIT_CAR_VALUE 0x5AA55AA5
32 EFI_STATUS_CODE_DATA DataHeader
;
34 } PEIM_FILE_HANDLE_EXTENDED_DATA
;
37 DiscoverPeimsAndOrderWithApriori (
38 IN PEI_CORE_INSTANCE
*Private
,
39 IN EFI_PEI_FV_HANDLE VolumeHandle
45 Discover all Peims and optional Apriori file in one FV. There is at most one
46 Apriori file in one FV.
50 Private - Pointer to the private data passed in from caller
51 VolumeHandle - Fv handle.
59 EFI_PEI_FV_HANDLE FileHandle
;
60 EFI_PEI_FILE_HANDLE AprioriFileHandle
;
67 EFI_PEI_FV_HANDLE TempFileHandles
[FixedPcdGet32 (PcdPeiCoreMaxPeimPerFv
)];
68 EFI_GUID FileGuid
[FixedPcdGet32 (PcdPeiCoreMaxPeimPerFv
)];
71 // Walk the FV and find all the PEIMs and the Apriori file.
73 AprioriFileHandle
= NULL
;
74 Private
->CurrentFvFileHandles
[0] = NULL
;
79 // If the current Fv has been scanned, directly get its cachable record.
81 if (Private
->Fv
[Private
->CurrentPeimFvCount
].ScanFv
) {
82 CopyMem (Private
->CurrentFvFileHandles
, Private
->Fv
[Private
->CurrentPeimFvCount
].FvFileHandles
, sizeof (Private
->CurrentFvFileHandles
));
87 // Go ahead to scan this Fv, and cache FileHandles within it.
89 for (PeimCount
= 0; PeimCount
< FixedPcdGet32 (PcdPeiCoreMaxPeimPerFv
); PeimCount
++) {
90 Status
= PeiFindFileEx (
93 PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE
,
97 if (Status
!= EFI_SUCCESS
) {
101 Private
->CurrentFvFileHandles
[PeimCount
] = FileHandle
;
104 Private
->AprioriCount
= 0;
105 if (AprioriFileHandle
!= NULL
) {
107 // Read the Apriori file
109 Status
= PeiServicesFfsFindSectionData (EFI_SECTION_RAW
, AprioriFileHandle
, (VOID
**) &Apriori
);
110 if (!EFI_ERROR (Status
)) {
112 // Calculate the number of PEIMs in the A Priori list
114 Private
->AprioriCount
= *(UINT32
*)(((EFI_FFS_FILE_HEADER
*)AprioriFileHandle
)->Size
) & 0x00FFFFFF;
115 Private
->AprioriCount
-= sizeof (EFI_FFS_FILE_HEADER
) - sizeof (EFI_COMMON_SECTION_HEADER
);
116 Private
->AprioriCount
/= sizeof (EFI_GUID
);
118 SetMem (FileGuid
, sizeof (FileGuid
), 0);
119 for (Index
= 0; Index
< PeimCount
; Index
++) {
121 // Make an array of file name guids that matches the FileHandle array so we can convert
122 // quickly from file name to file handle
124 CopyMem (&FileGuid
[Index
], &((EFI_FFS_FILE_HEADER
*)Private
->CurrentFvFileHandles
[Index
])->Name
,sizeof(EFI_GUID
));
128 // Walk through FileGuid array to find out who is invalid PEIM guid in Apriori file.
129 // Add avalible PEIMs in Apriori file into TempFileHandles array at first.
132 for (Index
= 0; Index2
< Private
->AprioriCount
; Index
++) {
133 while (Index2
< Private
->AprioriCount
) {
134 Guid
= ScanGuid (FileGuid
, PeimCount
* sizeof (EFI_GUID
), &Apriori
[Index2
++]);
142 PeimIndex
= ((UINTN
)Guid
- (UINTN
)&FileGuid
[0])/sizeof (EFI_GUID
);
143 TempFileHandles
[Index
] = Private
->CurrentFvFileHandles
[PeimIndex
];
146 // Since we have copied the file handle we can remove it from this list.
148 Private
->CurrentFvFileHandles
[PeimIndex
] = NULL
;
152 // Update valid Aprioricount
154 Private
->AprioriCount
= Index
;
157 // Add in any PEIMs not in the Apriori file
159 for (;Index
< PeimCount
; Index
++) {
160 for (Index2
= 0; Index2
< PeimCount
; Index2
++) {
161 if (Private
->CurrentFvFileHandles
[Index2
] != NULL
) {
162 TempFileHandles
[Index
] = Private
->CurrentFvFileHandles
[Index2
];
163 Private
->CurrentFvFileHandles
[Index2
] = NULL
;
169 //Index the end of array contains re-range Pei moudle.
171 TempFileHandles
[Index
] = NULL
;
174 // Private->CurrentFvFileHandles is currently in PEIM in the FV order.
175 // We need to update it to start with files in the A Priori list and
176 // then the remaining files in PEIM order.
178 CopyMem (Private
->CurrentFvFileHandles
, TempFileHandles
, sizeof (Private
->CurrentFvFileHandles
));
182 // Cache the current Fv File Handle. So that we don't have to scan the Fv again.
183 // Instead, we can retrieve the file handles within this Fv from cachable data.
185 Private
->Fv
[Private
->CurrentPeimFvCount
].ScanFv
= TRUE
;
186 CopyMem (Private
->Fv
[Private
->CurrentPeimFvCount
].FvFileHandles
, Private
->CurrentFvFileHandles
, sizeof (Private
->CurrentFvFileHandles
));
192 EFI_PEI_SERVICES
**PeiServices
,
193 PEI_CORE_INSTANCE
*PrivateInMem
196 EFI_PEI_FILE_HANDLE PeiCoreFileHandle
;
197 EFI_PHYSICAL_ADDRESS EntryPoint
;
199 UINT32 AuthenticationState
;
201 PeiCoreFileHandle
= NULL
;
204 // Find the PEI Core in the BFV
206 Status
= PeiFindFileEx (
207 (EFI_PEI_FV_HANDLE
)PrivateInMem
->Fv
[0].FvHeader
,
209 EFI_FV_FILETYPE_PEI_CORE
,
213 ASSERT_EFI_ERROR (Status
);
216 // Shadow PEI Core into memory so it will run faster
218 Status
= PeiLoadImage (
220 *((EFI_PEI_FILE_HANDLE
*)&PeiCoreFileHandle
),
224 ASSERT_EFI_ERROR (Status
);
226 return (VOID
*) ((UINTN
) EntryPoint
+ (UINTN
) PeiCore
- (UINTN
) _ModuleEntryPoint
);
231 IN CONST EFI_SEC_PEI_HAND_OFF
*SecCoreData
,
232 IN PEI_CORE_INSTANCE
*Private
239 Conduct PEIM dispatch.
243 SecCoreData - Points to a data structure containing information about the PEI core's operating
244 environment, such as the size and location of temporary RAM, the stack location and
246 PrivateData - Pointer to the private data passed in from caller
247 DispatchData - Pointer to PEI_CORE_DISPATCH_DATA data.
251 EFI_SUCCESS - Successfully dispatched PEIM.
252 EFI_NOT_FOUND - The dispatch failed.
259 EFI_PEI_SERVICES
**PeiServices
;
260 EFI_PEI_FV_HANDLE VolumeHandle
;
261 EFI_PEI_FILE_HANDLE PeimFileHandle
;
264 UINT32 AuthenticationState
;
265 EFI_PHYSICAL_ADDRESS EntryPoint
;
266 EFI_PEIM_ENTRY_POINT2 PeimEntryPoint
;
267 BOOLEAN PeimNeedingDispatch
;
268 BOOLEAN PeimDispatchOnThisPass
;
269 UINTN SaveCurrentPeimCount
;
270 UINTN SaveCurrentFvCount
;
271 EFI_PEI_FILE_HANDLE SaveCurrentFileHandle
;
272 PEIM_FILE_HANDLE_EXTENDED_DATA ExtendedData
;
273 EFI_PHYSICAL_ADDRESS NewPermenentMemoryBase
;
274 TEMPORARY_RAM_SUPPORT_PPI
*TemporaryRamSupportPpi
;
275 EFI_HOB_HANDOFF_INFO_TABLE
*OldHandOffTable
;
276 EFI_HOB_HANDOFF_INFO_TABLE
*NewHandOffTable
;
278 PEI_CORE_INSTANCE
*PrivateInMem
;
279 UINT64 NewPeiStackSize
;
280 UINT64 OldPeiStackSize
;
282 EFI_FV_FILE_INFO FvFileInfo
;
283 UINTN OldCheckingTop
;
284 UINTN OldCheckingBottom
;
287 PeiServices
= &Private
->PS
;
288 PeimEntryPoint
= NULL
;
289 PeimFileHandle
= NULL
;
292 if ((Private
->PeiMemoryInstalled
) && (Private
->HobList
.HandoffInformationTable
->BootMode
!= BOOT_ON_S3_RESUME
)) {
294 // Once real memory is available, shadow the RegisterForShadow modules. And meanwhile
295 // update the modules' status from PEIM_STATE_REGISITER_FOR_SHADOW to PEIM_STATE_DONE.
297 SaveCurrentPeimCount
= Private
->CurrentPeimCount
;
298 SaveCurrentFvCount
= Private
->CurrentPeimFvCount
;
299 SaveCurrentFileHandle
= Private
->CurrentFileHandle
;
301 for (Index1
= 0; Index1
<= SaveCurrentFvCount
; Index1
++) {
302 for (Index2
= 0; (Index2
< FixedPcdGet32 (PcdPeiCoreMaxPeimPerFv
)) && (Private
->Fv
[Index1
].FvFileHandles
[Index2
] != NULL
); Index2
++) {
303 if (Private
->Fv
[Index1
].PeimState
[Index2
] == PEIM_STATE_REGISITER_FOR_SHADOW
) {
304 PeimFileHandle
= Private
->Fv
[Index1
].FvFileHandles
[Index2
];
305 Status
= PeiLoadImage (
311 if (Status
== EFI_SUCCESS
) {
313 // PEIM_STATE_REGISITER_FOR_SHADOW move to PEIM_STATE_DONE
315 Private
->Fv
[Index1
].PeimState
[Index2
]++;
316 Private
->CurrentFileHandle
= PeimFileHandle
;
317 Private
->CurrentPeimFvCount
= Index1
;
318 Private
->CurrentPeimCount
= Index2
;
320 // Call the PEIM entry point
322 PeimEntryPoint
= (EFI_PEIM_ENTRY_POINT2
)(UINTN
)EntryPoint
;
324 PERF_START (0, "PEIM", NULL
, 0);
325 PeimEntryPoint(PeimFileHandle
, (const EFI_PEI_SERVICES
**) &Private
->PS
);
326 PERF_END (0, "PEIM", NULL
, 0);
330 // Process the Notify list and dispatch any notifies for
331 // newly installed PPIs.
333 ProcessNotifyList (Private
);
337 Private
->CurrentFileHandle
= SaveCurrentFileHandle
;
338 Private
->CurrentPeimFvCount
= SaveCurrentFvCount
;
339 Private
->CurrentPeimCount
= SaveCurrentPeimCount
;
343 // This is the main dispatch loop. It will search known FVs for PEIMs and
344 // attempt to dispatch them. If any PEIM gets dispatched through a single
345 // pass of the dispatcher, it will start over from the Bfv again to see
346 // if any new PEIMs dependencies got satisfied. With a well ordered
347 // FV where PEIMs are found in the order their dependencies are also
348 // satisfied, this dipatcher should run only once.
351 PeimNeedingDispatch
= FALSE
;
352 PeimDispatchOnThisPass
= FALSE
;
354 for (FvCount
= Private
->CurrentPeimFvCount
; FvCount
< Private
->FvCount
; FvCount
++) {
355 Private
->CurrentPeimFvCount
= FvCount
;
356 VolumeHandle
= Private
->Fv
[FvCount
].FvHeader
;
358 if (Private
->CurrentPeimCount
== 0) {
360 // When going through each FV, at first, search Apriori file to
361 // reorder all PEIMs to ensure the PEIMs in Apriori file to get
362 // dispatch at first.
364 DiscoverPeimsAndOrderWithApriori (Private
, VolumeHandle
);
368 // Start to dispatch all modules within the current Fv.
370 for (PeimCount
= Private
->CurrentPeimCount
;
371 (PeimCount
< FixedPcdGet32 (PcdPeiCoreMaxPeimPerFv
)) && (Private
->CurrentFvFileHandles
[PeimCount
] != NULL
);
373 Private
->CurrentPeimCount
= PeimCount
;
374 PeimFileHandle
= Private
->CurrentFileHandle
= Private
->CurrentFvFileHandles
[PeimCount
];
376 if (Private
->Fv
[FvCount
].PeimState
[PeimCount
] == PEIM_STATE_NOT_DISPATCHED
) {
377 if (!DepexSatisfied (Private
, PeimFileHandle
, PeimCount
)) {
378 PeimNeedingDispatch
= TRUE
;
380 Status
= PeiFfsGetFileInfo (PeimFileHandle
, &FvFileInfo
);
381 ASSERT_EFI_ERROR (Status
);
382 if (FvFileInfo
.FileType
== EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
) {
384 // For Fv type file, Produce new FV PPI and FV hob
386 Status
= ProcessFvFile (PeiServices
, PeimFileHandle
, &AuthenticationState
);
389 // For PEIM driver, Load its entry point
391 Status
= PeiLoadImage (
399 if ((Status
== EFI_SUCCESS
)) {
401 // The PEIM has its dependencies satisfied, and its entry point
402 // has been found, so invoke it.
404 PERF_START (0, "PEIM", NULL
, 0);
406 ExtendedData
.Handle
= (EFI_HANDLE
)PeimFileHandle
;
408 REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
410 FixedPcdGet32(PcdStatusCodeValuePeimDispatch
),
411 (VOID
*)(&ExtendedData
),
412 sizeof (ExtendedData
)
415 Status
= VerifyPeim (Private
, VolumeHandle
, PeimFileHandle
);
416 if (Status
!= EFI_SECURITY_VIOLATION
&& (AuthenticationState
== 0)) {
418 // PEIM_STATE_NOT_DISPATCHED move to PEIM_STATE_DISPATCHED
420 Private
->Fv
[FvCount
].PeimState
[PeimCount
]++;
422 if (FvFileInfo
.FileType
!= EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
) {
424 // Call the PEIM entry point for PEIM driver
426 PeimEntryPoint
= (EFI_PEIM_ENTRY_POINT2
)(UINTN
)EntryPoint
;
427 PeimEntryPoint (PeimFileHandle
, (const EFI_PEI_SERVICES
**) PeiServices
);
430 PeimDispatchOnThisPass
= TRUE
;
433 REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
435 FixedPcdGet32(PcdStatusCodeValuePeimDispatch
),
436 (VOID
*)(&ExtendedData
),
437 sizeof (ExtendedData
)
439 PERF_END (0, "PEIM", NULL
, 0);
443 if (Private
->SwitchStackSignal
) {
445 // Before switch stack from CAR to permenent memory, caculate the heap and stack
446 // usage in temporary memory for debuging.
449 UINT32
*StackPointer
;
451 for (StackPointer
= (UINT32
*)SecCoreData
->StackBase
;
452 (StackPointer
< (UINT32
*)((UINTN
)SecCoreData
->StackBase
+ SecCoreData
->StackSize
)) \
453 && (*StackPointer
== INIT_CAR_VALUE
);
456 DEBUG ((EFI_D_INFO
, "Total Cache as RAM: %d bytes.\n", SecCoreData
->TemporaryRamSize
));
457 DEBUG ((EFI_D_INFO
, " CAR stack ever used: %d bytes.\n",
458 (SecCoreData
->StackSize
- ((UINTN
) StackPointer
- (UINTN
)SecCoreData
->StackBase
))
460 DEBUG ((EFI_D_INFO
, " CAR heap used: %d bytes.\n",
461 ((UINTN
) Private
->HobList
.HandoffInformationTable
->EfiFreeMemoryBottom
-
462 (UINTN
) Private
->HobList
.Raw
)
467 // Reserve the size of new stack at bottom of physical memory
469 OldPeiStackSize
= Private
->StackSize
;
470 NewPeiStackSize
= (RShiftU64 (Private
->PhysicalMemoryLength
, 1) + EFI_PAGE_MASK
) & ~EFI_PAGE_MASK
;
471 if (FixedPcdGet32(PcdPeiCoreMaxPeiStackSize
) > (UINT32
) NewPeiStackSize
) {
472 Private
->StackSize
= NewPeiStackSize
;
474 Private
->StackSize
= FixedPcdGet32(PcdPeiCoreMaxPeiStackSize
);
478 // In theory, the size of new stack in permenent memory should large than
479 // size of old stack in temporary memory.
480 // But if new stack is smaller than the size of old stack, we also reserve
481 // the size of old stack at bottom of permenent memory.
484 if (Private
->StackSize
> OldPeiStackSize
) {
485 StackGap
= Private
->StackSize
- OldPeiStackSize
;
489 // Update HandOffHob for new installed permenent memory
491 OldHandOffTable
= Private
->HobList
.HandoffInformationTable
;
492 OldCheckingBottom
= (UINTN
)OldHandOffTable
;
493 OldCheckingTop
= (UINTN
)(OldCheckingBottom
+ SecCoreData
->TemporaryRamSize
);
496 // The whole temporary memory will be migrated to physical memory.
497 // CAUTION: The new base is computed accounding to gap of new stack.
499 NewPermenentMemoryBase
= Private
->PhysicalMemoryBegin
+ StackGap
;
500 Offset
= (UINTN
) NewPermenentMemoryBase
- (UINTN
) SecCoreData
->TemporaryRamBase
;
501 NewHandOffTable
= (EFI_HOB_HANDOFF_INFO_TABLE
*)((UINTN
)OldHandOffTable
+ Offset
);
502 PrivateInMem
= (PEI_CORE_INSTANCE
*)((UINTN
) (VOID
*) Private
+ Offset
);
505 // TemporaryRamSupportPpi is produced by platform's SEC
507 Status
= PeiLocatePpi (
508 (CONST EFI_PEI_SERVICES
**) PeiServices
,
509 &gEfiTemporaryRamSupportPpiGuid
,
512 (VOID
**)&TemporaryRamSupportPpi
516 if (!EFI_ERROR (Status
)) {
517 TemporaryRamSupportPpi
->TemporaryRamMigration (
518 (CONST EFI_PEI_SERVICES
**) PeiServices
,
519 (EFI_PHYSICAL_ADDRESS
)(UINTN
) SecCoreData
->TemporaryRamBase
,
520 (EFI_PHYSICAL_ADDRESS
)(UINTN
) NewPermenentMemoryBase
,
521 SecCoreData
->TemporaryRamSize
526 (VOID
*)(UINTN
) NewPermenentMemoryBase
,
527 SecCoreData
->TemporaryRamBase
,
528 SecCoreData
->TemporaryRamSize
535 // Fixup the PeiCore's private data
537 PrivateInMem
->PS
= &PrivateInMem
->ServiceTableShadow
;
538 PrivateInMem
->CpuIo
= &PrivateInMem
->ServiceTableShadow
.CpuIo
;
539 PrivateInMem
->HobList
.Raw
= (VOID
*) ((UINTN
) PrivateInMem
->HobList
.Raw
+ Offset
);
540 PrivateInMem
->StackBase
= (EFI_PHYSICAL_ADDRESS
)(((UINTN
)PrivateInMem
->PhysicalMemoryBegin
+ EFI_PAGE_MASK
) & ~EFI_PAGE_MASK
);
542 PeiServices
= &PrivateInMem
->PS
;
545 // Fixup for PeiService's address
547 SetPeiServicesTablePointer(PeiServices
);
550 // Update HandOffHob for new installed permenent memory
552 NewHandOffTable
->EfiEndOfHobList
=
553 (EFI_PHYSICAL_ADDRESS
)((UINTN
) NewHandOffTable
->EfiEndOfHobList
+ Offset
);
554 NewHandOffTable
->EfiMemoryTop
= PrivateInMem
->PhysicalMemoryBegin
+
555 PrivateInMem
->PhysicalMemoryLength
;
556 NewHandOffTable
->EfiMemoryBottom
= PrivateInMem
->PhysicalMemoryBegin
;
557 NewHandOffTable
->EfiFreeMemoryTop
= PrivateInMem
->FreePhysicalMemoryTop
;
558 NewHandOffTable
->EfiFreeMemoryBottom
= NewHandOffTable
->EfiEndOfHobList
+
559 sizeof (EFI_HOB_GENERIC_HEADER
);
562 // We need convert the PPI desciptor's pointer
564 ConvertPpiPointers ((CONST EFI_PEI_SERVICES
**)PeiServices
,
569 DEBUG ((EFI_D_INFO
, "Stack Hob: BaseAddress=0x%X Length=0x%X\n",
570 (UINTN
)PrivateInMem
->StackBase
,
571 PrivateInMem
->StackSize
));
572 BuildStackHob (PrivateInMem
->StackBase
, PrivateInMem
->StackSize
);
575 // After the whole temporary memory is migrated, then we can allocate page in
578 PrivateInMem
->PeiMemoryInstalled
= TRUE
;
581 // Make sure we don't retry the same PEIM that added memory
583 PrivateInMem
->CurrentPeimCount
++;
586 // Shadow PEI Core. When permanent memory is avaiable, shadow
587 // PEI Core and PEIMs to get high performance.
589 PrivateInMem
->ShadowedPeiCore
= ShadowPeiCore (
594 // Process the Notify list and dispatch any notifies for
595 // newly installed PPIs.
597 ProcessNotifyList (PrivateInMem
);
602 PeiCore (SecCoreData
, NULL
, PrivateInMem
);
605 // Code should not come here
607 ASSERT_EFI_ERROR(FALSE
);
611 // Process the Notify list and dispatch any notifies for
612 // newly installed PPIs.
614 ProcessNotifyList (Private
);
616 if ((Private
->PeiMemoryInstalled
) && (Private
->Fv
[FvCount
].PeimState
[PeimCount
] == PEIM_STATE_REGISITER_FOR_SHADOW
) && \
617 (Private
->HobList
.HandoffInformationTable
->BootMode
!= BOOT_ON_S3_RESUME
)) {
619 // If memory is availble we shadow images by default for performance reasons.
620 // We call the entry point a 2nd time so the module knows it's shadowed.
622 //PERF_START (PeiServices, L"PEIM", PeimFileHandle, 0);
623 PeimEntryPoint (PeimFileHandle
, (const EFI_PEI_SERVICES
**) PeiServices
);
624 //PERF_END (PeiServices, L"PEIM", PeimFileHandle, 0);
627 // PEIM_STATE_REGISITER_FOR_SHADOW move to PEIM_STATE_DONE
629 Private
->Fv
[FvCount
].PeimState
[PeimCount
]++;
632 // Process the Notify list and dispatch any notifies for
633 // newly installed PPIs.
635 ProcessNotifyList (Private
);
642 // We set to NULL here to optimize the 2nd entry to this routine after
643 // memory is found. This reprevents rescanning of the FV. We set to
644 // NULL here so we start at the begining of the next FV
646 Private
->CurrentFileHandle
= NULL
;
647 Private
->CurrentPeimCount
= 0;
649 // Before walking through the next FV,Private->CurrentFvFileHandles[]should set to NULL
651 SetMem (Private
->CurrentFvFileHandles
, sizeof (Private
->CurrentFvFileHandles
), 0);
655 // Before making another pass, we should set Private->CurrentPeimFvCount =0 to go
656 // through all the FV.
658 Private
->CurrentPeimFvCount
= 0;
661 // PeimNeedingDispatch being TRUE means we found a PEIM that did not get
662 // dispatched. So we need to make another pass
664 // PeimDispatchOnThisPass being TRUE means we dispatched a PEIM on this
665 // pass. If we did not dispatch a PEIM there is no point in trying again
666 // as it will fail the next time too (nothing has changed).
668 } while (PeimNeedingDispatch
&& PeimDispatchOnThisPass
);
673 InitializeDispatcherData (
674 IN PEI_CORE_INSTANCE
*PrivateData
,
675 IN PEI_CORE_INSTANCE
*OldCoreData
,
676 IN CONST EFI_SEC_PEI_HAND_OFF
*SecCoreData
682 Initialize the Dispatcher's data members
686 PeiServices - The PEI core services table.
687 OldCoreData - Pointer to old core data (before switching stack).
688 NULL if being run in non-permament memory mode.
689 SecCoreData - Points to a data structure containing information about the PEI core's operating
690 environment, such as the size and location of temporary RAM, the stack location and
699 if (OldCoreData
== NULL
) {
700 PeiInitializeFv (PrivateData
, SecCoreData
);
709 IN PEI_CORE_INSTANCE
*Private
,
710 IN EFI_PEI_FILE_HANDLE FileHandle
,
717 This routine parses the Dependency Expression, if available, and
718 decides if the module can be executed.
721 PeiServices - The PEI Service Table
722 CurrentPeimAddress - Address of the PEIM Firmware File under investigation
725 TRUE - Can be dispatched
726 FALSE - Cannot be dispatched
733 if (PeimCount
< Private
->AprioriCount
) {
735 // If its in the A priori file then we set Depex to TRUE
741 // Depex section not in the encapsulated section.
743 Status
= PeiServicesFfsFindSectionData (
744 EFI_SECTION_PEI_DEPEX
,
749 if (EFI_ERROR (Status
)) {
751 // If there is no DEPEX, assume the module can be executed
757 // Evaluate a given DEPEX
759 return PeimDispatchReadiness (&Private
->PS
, DepexData
);
763 This routine enable a PEIM to register itself to shadow when PEI Foundation
764 discovery permanent memory.
766 @param FileHandle File handle of a PEIM.
768 @retval EFI_NOT_FOUND The file handle doesn't point to PEIM itself.
769 @retval EFI_ALREADY_STARTED Indicate that the PEIM has been registered itself.
770 @retval EFI_SUCCESS Successfully to register itself.
775 PeiRegisterForShadow (
776 IN EFI_PEI_FILE_HANDLE FileHandle
779 PEI_CORE_INSTANCE
*Private
;
780 Private
= PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());
782 if (Private
->CurrentFileHandle
!= FileHandle
) {
784 // The FileHandle must be for the current PEIM
786 return EFI_NOT_FOUND
;
789 if (Private
->Fv
[Private
->CurrentPeimFvCount
].PeimState
[Private
->CurrentPeimCount
] >= PEIM_STATE_REGISITER_FOR_SHADOW
) {
791 // If the PEIM has already entered the PEIM_STATE_REGISTER_FOR_SHADOW or PEIM_STATE_DONE then it's already been started
793 return EFI_ALREADY_STARTED
;
796 Private
->Fv
[Private
->CurrentPeimFvCount
].PeimState
[Private
->CurrentPeimCount
] = PEIM_STATE_REGISITER_FOR_SHADOW
;
804 Get Fv image from the FV type file, then install FV INFO ppi, Build FV hob.
806 @param PeiServices Pointer to the PEI Core Services Table.
807 @param FileHandle File handle of a Fv type file.
808 @param AuthenticationState Pointer to attestation authentication state of image.
811 @retval EFI_NOT_FOUND FV image can't be found.
812 @retval EFI_SUCCESS Successfully to process it.
817 IN EFI_PEI_SERVICES
**PeiServices
,
818 IN EFI_PEI_FILE_HANDLE FvFileHandle
,
819 OUT UINT32
*AuthenticationState
823 EFI_PEI_FV_HANDLE FvImageHandle
;
824 EFI_FV_INFO FvImageInfo
;
827 EFI_PEI_HOB_POINTERS HobFv2
;
830 *AuthenticationState
= 0;
833 // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already
836 HobFv2
.Raw
= GetHobList ();
837 while ((HobFv2
.Raw
= GetNextHob (EFI_HOB_TYPE_FV2
, HobFv2
.Raw
)) != NULL
) {
838 if (CompareGuid (&(((EFI_FFS_FILE_HEADER
*)FvFileHandle
)->Name
), &HobFv2
.FirmwareVolume2
->FileName
)) {
840 // this FILE has been dispatched, it will not be dispatched again.
844 HobFv2
.Raw
= GET_NEXT_HOB (HobFv2
);
848 // Find FvImage in FvFile
850 Status
= PeiFfsFindSectionData (
851 (CONST EFI_PEI_SERVICES
**) PeiServices
,
852 EFI_SECTION_FIRMWARE_VOLUME_IMAGE
,
854 (VOID
**)&FvImageHandle
857 if (EFI_ERROR (Status
)) {
861 // Collect FvImage Info.
863 Status
= PeiFfsGetVolumeInfo (FvImageHandle
, &FvImageInfo
);
864 ASSERT_EFI_ERROR (Status
);
866 // FvAlignment must be more than 8 bytes required by FvHeader structure.
868 FvAlignment
= 1 << ((FvImageInfo
.FvAttributes
& EFI_FVB2_ALIGNMENT
) >> 16);
869 if (FvAlignment
< 8) {
875 if ((UINTN
) FvImageInfo
.FvStart
% FvAlignment
!= 0) {
876 FvBuffer
= AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINT32
) FvImageInfo
.FvSize
), FvAlignment
);
877 if (FvBuffer
== NULL
) {
878 return EFI_OUT_OF_RESOURCES
;
880 CopyMem (FvBuffer
, FvImageInfo
.FvStart
, (UINTN
) FvImageInfo
.FvSize
);
882 // Update FvImageInfo after reload FvImage to new aligned memory
884 PeiFfsGetVolumeInfo ((EFI_PEI_FV_HANDLE
) FvBuffer
, &FvImageInfo
);
888 // Install FvPpi and Build FvHob
890 PiLibInstallFvInfoPpi (
893 (UINT32
) FvImageInfo
.FvSize
,
894 &(FvImageInfo
.FvName
),
895 &(((EFI_FFS_FILE_HEADER
*)FvFileHandle
)->Name
)
899 // Inform HOB consumer phase, i.e. DXE core, the existance of this FV
902 (EFI_PHYSICAL_ADDRESS
) (UINTN
) FvImageInfo
.FvStart
,
906 // Makes the encapsulated volume show up in DXE phase to skip processing of
907 // encapsulated file again.
910 (EFI_PHYSICAL_ADDRESS
) (UINTN
) FvImageInfo
.FvStart
,
913 &(((EFI_FFS_FILE_HEADER
*)FvFileHandle
)->Name
)