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
;
39 DiscoverPeimsAndOrderWithApriori (
40 IN PEI_CORE_INSTANCE
*Private
,
41 IN EFI_PEI_FV_HANDLE VolumeHandle
47 Discover all Peims and optional Apriori file in one FV. There is at most one
48 Apriori file in one FV.
52 Private - Pointer to the private data passed in from caller
53 VolumeHandle - Fv handle.
61 EFI_PEI_FV_HANDLE FileHandle
;
62 EFI_PEI_FILE_HANDLE AprioriFileHandle
;
69 EFI_PEI_FV_HANDLE TempFileHandles
[FixedPcdGet32 (PcdPeiCoreMaxPeimPerFv
)];
70 EFI_GUID FileGuid
[FixedPcdGet32 (PcdPeiCoreMaxPeimPerFv
)];
73 // Walk the FV and find all the PEIMs and the Apriori file.
75 AprioriFileHandle
= NULL
;
76 Private
->CurrentFvFileHandles
[0] = NULL
;
81 // If the current Fv has been scanned, directly get its cachable record.
83 if (Private
->Fv
[Private
->CurrentPeimFvCount
].ScanFv
) {
84 CopyMem (Private
->CurrentFvFileHandles
, Private
->Fv
[Private
->CurrentPeimFvCount
].FvFileHandles
, sizeof (Private
->CurrentFvFileHandles
));
89 // Go ahead to scan this Fv, and cache FileHandles within it.
91 for (PeimCount
= 0; PeimCount
< FixedPcdGet32 (PcdPeiCoreMaxPeimPerFv
); PeimCount
++) {
92 Status
= PeiFindFileEx (
95 PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE
,
99 if (Status
!= EFI_SUCCESS
) {
103 Private
->CurrentFvFileHandles
[PeimCount
] = FileHandle
;
106 Private
->AprioriCount
= 0;
107 if (AprioriFileHandle
!= NULL
) {
109 // Read the Apriori file
111 Status
= PeiServicesFfsFindSectionData (EFI_SECTION_RAW
, AprioriFileHandle
, (VOID
**) &Apriori
);
112 if (!EFI_ERROR (Status
)) {
114 // Calculate the number of PEIMs in the A Priori list
116 Private
->AprioriCount
= *(UINT32
*)(((EFI_FFS_FILE_HEADER
*)AprioriFileHandle
)->Size
) & 0x00FFFFFF;
117 Private
->AprioriCount
-= sizeof (EFI_FFS_FILE_HEADER
) - sizeof (EFI_COMMON_SECTION_HEADER
);
118 Private
->AprioriCount
/= sizeof (EFI_GUID
);
120 SetMem (FileGuid
, sizeof (FileGuid
), 0);
121 for (Index
= 0; Index
< PeimCount
; Index
++) {
123 // Make an array of file name guids that matches the FileHandle array so we can convert
124 // quickly from file name to file handle
126 CopyMem (&FileGuid
[Index
], &((EFI_FFS_FILE_HEADER
*)Private
->CurrentFvFileHandles
[Index
])->Name
,sizeof(EFI_GUID
));
130 // Walk through FileGuid array to find out who is invalid PEIM guid in Apriori file.
131 // Add avalible PEIMs in Apriori file into TempFileHandles array at first.
134 for (Index
= 0; Index2
< Private
->AprioriCount
; Index
++) {
135 while (Index2
< Private
->AprioriCount
) {
136 Guid
= ScanGuid (FileGuid
, PeimCount
* sizeof (EFI_GUID
), &Apriori
[Index2
++]);
144 PeimIndex
= ((UINTN
)Guid
- (UINTN
)&FileGuid
[0])/sizeof (EFI_GUID
);
145 TempFileHandles
[Index
] = Private
->CurrentFvFileHandles
[PeimIndex
];
148 // Since we have copied the file handle we can remove it from this list.
150 Private
->CurrentFvFileHandles
[PeimIndex
] = NULL
;
154 // Update valid Aprioricount
156 Private
->AprioriCount
= Index
;
159 // Add in any PEIMs not in the Apriori file
161 for (;Index
< PeimCount
; Index
++) {
162 for (Index2
= 0; Index2
< PeimCount
; Index2
++) {
163 if (Private
->CurrentFvFileHandles
[Index2
] != NULL
) {
164 TempFileHandles
[Index
] = Private
->CurrentFvFileHandles
[Index2
];
165 Private
->CurrentFvFileHandles
[Index2
] = NULL
;
171 //Index the end of array contains re-range Pei moudle.
173 TempFileHandles
[Index
] = NULL
;
176 // Private->CurrentFvFileHandles is currently in PEIM in the FV order.
177 // We need to update it to start with files in the A Priori list and
178 // then the remaining files in PEIM order.
180 CopyMem (Private
->CurrentFvFileHandles
, TempFileHandles
, sizeof (Private
->CurrentFvFileHandles
));
184 // Cache the current Fv File Handle. So that we don't have to scan the Fv again.
185 // Instead, we can retrieve the file handles within this Fv from cachable data.
187 Private
->Fv
[Private
->CurrentPeimFvCount
].ScanFv
= TRUE
;
188 CopyMem (Private
->Fv
[Private
->CurrentPeimFvCount
].FvFileHandles
, Private
->CurrentFvFileHandles
, sizeof (Private
->CurrentFvFileHandles
));
194 IN CONST EFI_SEC_PEI_HAND_OFF
*SecCoreData
,
195 IN PEI_CORE_INSTANCE
*Private
202 Conduct PEIM dispatch.
206 SecCoreData - Points to a data structure containing information about the PEI core's operating
207 environment, such as the size and location of temporary RAM, the stack location and
209 PrivateData - Pointer to the private data passed in from caller
210 DispatchData - Pointer to PEI_CORE_DISPATCH_DATA data.
214 EFI_SUCCESS - Successfully dispatched PEIM.
215 EFI_NOT_FOUND - The dispatch failed.
222 EFI_PEI_SERVICES
**PeiServices
;
224 EFI_PEI_FV_HANDLE VolumeHandle
;
225 EFI_PEI_FILE_HANDLE PeiCoreFileHandle
;
226 EFI_PEI_FILE_HANDLE PeimFileHandle
;
229 UINT32 AuthenticationState
;
230 EFI_PHYSICAL_ADDRESS EntryPoint
;
231 EFI_PEIM_ENTRY_POINT2 PeimEntryPoint
;
232 BOOLEAN PeimNeedingDispatch
;
233 BOOLEAN PeimDispatchOnThisPass
;
234 UINTN SaveCurrentPeimCount
;
235 UINTN SaveCurrentFvCount
;
236 EFI_PEI_FILE_HANDLE SaveCurrentFileHandle
;
238 PEI_CORE_PARAMETERS PeiCoreParameters
;
239 PEIM_FILE_HANDLE_EXTENDED_DATA ExtendedData
;
240 EFI_FV_FILE_INFO FvFileInfo
;
243 PeiServices
= &Private
->PS
;
244 PeimEntryPoint
= NULL
;
245 PeimFileHandle
= NULL
;
248 if ((Private
->PeiMemoryInstalled
) && (Private
->HobList
.HandoffInformationTable
->BootMode
!= BOOT_ON_S3_RESUME
)) {
250 // Once real memory is available, shadow the RegisterForShadow modules. And meanwhile
251 // update the modules' status from PEIM_STATE_REGISITER_FOR_SHADOW to PEIM_STATE_DONE.
253 SaveCurrentPeimCount
= Private
->CurrentPeimCount
;
254 SaveCurrentFvCount
= Private
->CurrentPeimFvCount
;
255 SaveCurrentFileHandle
= Private
->CurrentFileHandle
;
257 for (Index1
= 0; Index1
<= SaveCurrentFvCount
; Index1
++) {
258 for (Index2
= 0; (Index2
< FixedPcdGet32 (PcdPeiCoreMaxPeimPerFv
)) && (Private
->Fv
[Index1
].FvFileHandles
[Index2
] != NULL
); Index2
++) {
259 if (Private
->Fv
[Index1
].PeimState
[Index2
] == PEIM_STATE_REGISITER_FOR_SHADOW
) {
260 PeimFileHandle
= Private
->Fv
[Index1
].FvFileHandles
[Index2
];
261 Status
= PeiLoadImage (
267 if (Status
== EFI_SUCCESS
) {
269 // PEIM_STATE_REGISITER_FOR_SHADOW move to PEIM_STATE_DONE
271 Private
->Fv
[Index1
].PeimState
[Index2
]++;
272 Private
->CurrentFileHandle
= PeimFileHandle
;
273 Private
->CurrentPeimFvCount
= Index1
;
274 Private
->CurrentPeimCount
= Index2
;
276 // Call the PEIM entry point
278 PeimEntryPoint
= (EFI_PEIM_ENTRY_POINT2
)(UINTN
)EntryPoint
;
280 PERF_START (0, "PEIM", NULL
, 0);
281 PeimEntryPoint(PeimFileHandle
, (const EFI_PEI_SERVICES
**) &Private
->PS
);
282 PERF_END (0, "PEIM", NULL
, 0);
286 // Process the Notify list and dispatch any notifies for
287 // newly installed PPIs.
289 ProcessNotifyList (Private
);
293 Private
->CurrentFileHandle
= SaveCurrentFileHandle
;
294 Private
->CurrentPeimFvCount
= SaveCurrentFvCount
;
295 Private
->CurrentPeimCount
= SaveCurrentPeimCount
;
299 // This is the main dispatch loop. It will search known FVs for PEIMs and
300 // attempt to dispatch them. If any PEIM gets dispatched through a single
301 // pass of the dispatcher, it will start over from the Bfv again to see
302 // if any new PEIMs dependencies got satisfied. With a well ordered
303 // FV where PEIMs are found in the order their dependencies are also
304 // satisfied, this dipatcher should run only once.
307 PeimNeedingDispatch
= FALSE
;
308 PeimDispatchOnThisPass
= FALSE
;
310 for (FvCount
= Private
->CurrentPeimFvCount
; FvCount
< Private
->FvCount
; FvCount
++) {
311 Private
->CurrentPeimFvCount
= FvCount
;
312 VolumeHandle
= Private
->Fv
[FvCount
].FvHeader
;
314 if (Private
->CurrentPeimCount
== 0) {
316 // When going through each FV, at first, search Apriori file to
317 // reorder all PEIMs to ensure the PEIMs in Apriori file to get
318 // dispatch at first.
320 DiscoverPeimsAndOrderWithApriori (Private
, VolumeHandle
);
324 // Start to dispatch all modules within the current Fv.
326 for (PeimCount
= Private
->CurrentPeimCount
;
327 (PeimCount
< FixedPcdGet32 (PcdPeiCoreMaxPeimPerFv
)) && (Private
->CurrentFvFileHandles
[PeimCount
] != NULL
);
329 Private
->CurrentPeimCount
= PeimCount
;
330 PeimFileHandle
= Private
->CurrentFileHandle
= Private
->CurrentFvFileHandles
[PeimCount
];
332 if (Private
->Fv
[FvCount
].PeimState
[PeimCount
] == PEIM_STATE_NOT_DISPATCHED
) {
333 if (!DepexSatisfied (Private
, PeimFileHandle
, PeimCount
)) {
334 PeimNeedingDispatch
= TRUE
;
336 Status
= PeiFfsGetFileInfo (PeimFileHandle
, &FvFileInfo
);
337 ASSERT_EFI_ERROR (Status
);
338 if (FvFileInfo
.FileType
== EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
) {
340 // For Fv type file, Produce new FV PPI and FV hob
342 Status
= ProcessFvFile (PeiServices
, PeimFileHandle
, &AuthenticationState
);
345 // For PEIM driver, Load its entry point
347 Status
= PeiLoadImage (
355 if ((Status
== EFI_SUCCESS
)) {
357 // The PEIM has its dependencies satisfied, and is processed.
359 PERF_START (0, "PEIM", NULL
, 0);
361 ExtendedData
.Handle
= (EFI_HANDLE
)PeimFileHandle
;
363 REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
365 FixedPcdGet32(PcdStatusCodeValuePeimDispatch
),
366 (VOID
*)(&ExtendedData
),
367 sizeof (ExtendedData
)
370 Status
= VerifyPeim (Private
, VolumeHandle
, PeimFileHandle
);
371 if (Status
!= EFI_SECURITY_VIOLATION
&& (AuthenticationState
== 0)) {
373 // PEIM_STATE_NOT_DISPATCHED move to PEIM_STATE_DISPATCHED
375 Private
->Fv
[FvCount
].PeimState
[PeimCount
]++;
377 if (FvFileInfo
.FileType
!= EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
) {
379 // Call the PEIM entry point for PEIM driver
381 PeimEntryPoint
= (EFI_PEIM_ENTRY_POINT2
)(UINTN
)EntryPoint
;
382 PeimEntryPoint (PeimFileHandle
, (const EFI_PEI_SERVICES
**) PeiServices
);
385 PeimDispatchOnThisPass
= TRUE
;
388 REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
390 FixedPcdGet32(PcdStatusCodeValuePeimDispatch
),
391 (VOID
*)(&ExtendedData
),
392 sizeof (ExtendedData
)
394 PERF_END (0, "PEIM", NULL
, 0);
398 // If PeiLoadImage fails, the section extraction PPI or Decompress PPI may not be ready,
399 // we flag that more Peims need to be dispatched.
401 PeimNeedingDispatch
= TRUE
;
405 // Process the Notify list and dispatch any notifies for
406 // newly installed PPIs.
408 ProcessNotifyList (Private
);
411 // If permanent memory was discovered and installed by this
412 // PEIM, shadow PEI Core and switch the stacks to the new memory.
414 if (Private
->SwitchStackSignal
) {
417 // Make sure we don't retry the same PEIM that added memory
419 Private
->CurrentPeimCount
++;
422 // Migrate IDT from CAR into real memory, so after stack switches to
423 // the new memory, the caller can get memory version PeiServiceTable.
425 MigrateIdtTable (PeiServices
);
428 // Since we are at dispatch level, only the Core's private data
429 // is preserved, nobody else should have any data on the stack.
430 // So we need to copy PEI core instance data to memory.
432 PrivateInMem
= AllocateCopyPool (sizeof (PEI_CORE_INSTANCE
), Private
);
433 ASSERT (PrivateInMem
!= NULL
);
436 // Shadow PEI Core. When permanent memory is avaiable, shadow
437 // PEI Core and PEIMs to get high performance.
439 PeiCoreFileHandle
= NULL
;
441 // Find the PEI Core in the BFV
443 Status
= PeiFindFileEx (
444 (EFI_PEI_FV_HANDLE
)Private
->Fv
[0].FvHeader
,
446 EFI_FV_FILETYPE_PEI_CORE
,
450 ASSERT_EFI_ERROR (Status
);
453 // Shadow PEI Core into memory so it will run faster
455 Status
= PeiLoadImage (PeiServices
, PeiCoreFileHandle
, &EntryPoint
, &AuthenticationState
);
456 ASSERT_EFI_ERROR (Status
);
459 // Switch to memory based stack and reenter PEI Core that has been
460 // shadowed to memory.
463 // Adjust the top of stack to be aligned at CPU_STACK_ALIGNMENT
465 TopOfStack
= (VOID
*)((UINTN
)Private
->StackBase
+ (UINTN
)Private
->StackSize
- CPU_STACK_ALIGNMENT
);
466 TopOfStack
= ALIGN_POINTER (TopOfStack
, CPU_STACK_ALIGNMENT
);
468 PeiCoreParameters
.SecCoreData
= SecCoreData
;
469 PeiCoreParameters
.PpiList
= NULL
;
470 PeiCoreParameters
.Data
= PrivateInMem
;
471 ASSERT (PeiCoreParameters
.Data
!= 0);
475 (VOID
*) ((UINTN
) EntryPoint
+ ((UINTN
) PeiCore
- (UINTN
) _ModuleEntryPoint
)),
476 (VOID
*) &PeiCoreParameters
,
478 (VOID
*)(UINTN
)Private
->StackBase
482 if ((Private
->PeiMemoryInstalled
) && (Private
->Fv
[FvCount
].PeimState
[PeimCount
] == PEIM_STATE_REGISITER_FOR_SHADOW
) && \
483 (Private
->HobList
.HandoffInformationTable
->BootMode
!= BOOT_ON_S3_RESUME
)) {
485 // If memory is availble we shadow images by default for performance reasons.
486 // We call the entry point a 2nd time so the module knows it's shadowed.
488 //PERF_START (PeiServices, L"PEIM", PeimFileHandle, 0);
489 PeimEntryPoint (PeimFileHandle
, (const EFI_PEI_SERVICES
**) PeiServices
);
490 //PERF_END (PeiServices, L"PEIM", PeimFileHandle, 0);
493 // PEIM_STATE_REGISITER_FOR_SHADOW move to PEIM_STATE_DONE
495 Private
->Fv
[FvCount
].PeimState
[PeimCount
]++;
498 // Process the Notify list and dispatch any notifies for
499 // newly installed PPIs.
501 ProcessNotifyList (Private
);
508 // We set to NULL here to optimize the 2nd entry to this routine after
509 // memory is found. This reprevents rescanning of the FV. We set to
510 // NULL here so we start at the begining of the next FV
512 Private
->CurrentFileHandle
= NULL
;
513 Private
->CurrentPeimCount
= 0;
515 // Before walking through the next FV,Private->CurrentFvFileHandles[]should set to NULL
517 SetMem (Private
->CurrentFvFileHandles
, sizeof (Private
->CurrentFvFileHandles
), 0);
521 // Before making another pass, we should set Private->CurrentPeimFvCount =0 to go
522 // through all the FV.
524 Private
->CurrentPeimFvCount
= 0;
527 // PeimNeedingDispatch being TRUE means we found a PEIM that did not get
528 // dispatched. So we need to make another pass
530 // PeimDispatchOnThisPass being TRUE means we dispatched a PEIM on this
531 // pass. If we did not dispatch a PEIM there is no point in trying again
532 // as it will fail the next time too (nothing has changed).
534 } while (PeimNeedingDispatch
&& PeimDispatchOnThisPass
);
539 InitializeDispatcherData (
540 IN PEI_CORE_INSTANCE
*PrivateData
,
541 IN PEI_CORE_INSTANCE
*OldCoreData
,
542 IN CONST EFI_SEC_PEI_HAND_OFF
*SecCoreData
548 Initialize the Dispatcher's data members
552 PeiServices - The PEI core services table.
553 OldCoreData - Pointer to old core data (before switching stack).
554 NULL if being run in non-permament memory mode.
555 SecCoreData - Points to a data structure containing information about the PEI core's operating
556 environment, such as the size and location of temporary RAM, the stack location and
565 if (OldCoreData
== NULL
) {
566 PeiInitializeFv (PrivateData
, SecCoreData
);
575 IN PEI_CORE_INSTANCE
*Private
,
576 IN EFI_PEI_FILE_HANDLE FileHandle
,
583 This routine parses the Dependency Expression, if available, and
584 decides if the module can be executed.
587 PeiServices - The PEI Service Table
588 CurrentPeimAddress - Address of the PEIM Firmware File under investigation
591 TRUE - Can be dispatched
592 FALSE - Cannot be dispatched
599 if (PeimCount
< Private
->AprioriCount
) {
601 // If its in the A priori file then we set Depex to TRUE
607 // Depex section not in the encapsulated section.
609 Status
= PeiServicesFfsFindSectionData (
610 EFI_SECTION_PEI_DEPEX
,
615 if (EFI_ERROR (Status
)) {
617 // If there is no DEPEX, assume the module can be executed
623 // Evaluate a given DEPEX
625 return PeimDispatchReadiness (&Private
->PS
, DepexData
);
629 This routine enable a PEIM to register itself to shadow when PEI Foundation
630 discovery permanent memory.
632 @param FileHandle File handle of a PEIM.
634 @retval EFI_NOT_FOUND The file handle doesn't point to PEIM itself.
635 @retval EFI_ALREADY_STARTED Indicate that the PEIM has been registered itself.
636 @retval EFI_SUCCESS Successfully to register itself.
641 PeiRegisterForShadow (
642 IN EFI_PEI_FILE_HANDLE FileHandle
645 PEI_CORE_INSTANCE
*Private
;
646 Private
= PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());
648 if (Private
->CurrentFileHandle
!= FileHandle
) {
650 // The FileHandle must be for the current PEIM
652 return EFI_NOT_FOUND
;
655 if (Private
->Fv
[Private
->CurrentPeimFvCount
].PeimState
[Private
->CurrentPeimCount
] >= PEIM_STATE_REGISITER_FOR_SHADOW
) {
657 // If the PEIM has already entered the PEIM_STATE_REGISTER_FOR_SHADOW or PEIM_STATE_DONE then it's already been started
659 return EFI_ALREADY_STARTED
;
662 Private
->Fv
[Private
->CurrentPeimFvCount
].PeimState
[Private
->CurrentPeimCount
] = PEIM_STATE_REGISITER_FOR_SHADOW
;
669 This routine invoke the PeiCore's entry in new stack environment.
671 @param Context1 The first context parameter is entry of PeiCore
672 @param Context2 The second context parameter is parameter structure point for PeiCore
682 PEI_CORE_ENTRY_POINT PeiCoreEntryPoint
;
683 PEI_CORE_PARAMETERS
*PeiCoreParameters
;
686 // Running on new stack in SEC Core
689 PeiCoreEntryPoint
= (PEI_CORE_ENTRY_POINT
) (UINTN
) Context1
;
690 PeiCoreParameters
= (PEI_CORE_PARAMETERS
*)Context2
;
693 // Call PEI Core using new stack
696 PeiCoreParameters
->SecCoreData
,
697 PeiCoreParameters
->PpiList
,
698 PeiCoreParameters
->Data
709 Get Fv image from the FV type file, then install FV INFO ppi, Build FV hob.
711 @param PeiServices Pointer to the PEI Core Services Table.
712 @param FileHandle File handle of a Fv type file.
713 @param AuthenticationState Pointer to attestation authentication state of image.
716 @retval EFI_NOT_FOUND FV image can't be found.
717 @retval EFI_SUCCESS Successfully to process it.
722 IN EFI_PEI_SERVICES
**PeiServices
,
723 IN EFI_PEI_FILE_HANDLE FvFileHandle
,
724 OUT UINT32
*AuthenticationState
728 EFI_PEI_FV_HANDLE FvImageHandle
;
729 EFI_FV_INFO FvImageInfo
;
732 EFI_PEI_HOB_POINTERS HobFv2
;
735 *AuthenticationState
= 0;
738 // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already
741 HobFv2
.Raw
= GetHobList ();
742 while ((HobFv2
.Raw
= GetNextHob (EFI_HOB_TYPE_FV2
, HobFv2
.Raw
)) != NULL
) {
743 if (CompareGuid (&(((EFI_FFS_FILE_HEADER
*)FvFileHandle
)->Name
), &HobFv2
.FirmwareVolume2
->FileName
)) {
745 // this FILE has been dispatched, it will not be dispatched again.
749 HobFv2
.Raw
= GET_NEXT_HOB (HobFv2
);
753 // Find FvImage in FvFile
755 Status
= PeiFfsFindSectionData (
756 (CONST EFI_PEI_SERVICES
**) PeiServices
,
757 EFI_SECTION_FIRMWARE_VOLUME_IMAGE
,
759 (VOID
**)&FvImageHandle
762 if (EFI_ERROR (Status
)) {
766 // Collect FvImage Info.
768 Status
= PeiFfsGetVolumeInfo (FvImageHandle
, &FvImageInfo
);
769 ASSERT_EFI_ERROR (Status
);
771 // FvAlignment must be more than 8 bytes required by FvHeader structure.
773 FvAlignment
= 1 << ((FvImageInfo
.FvAttributes
& EFI_FVB2_ALIGNMENT
) >> 16);
774 if (FvAlignment
< 8) {
780 if ((UINTN
) FvImageInfo
.FvStart
% FvAlignment
!= 0) {
781 FvBuffer
= AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINT32
) FvImageInfo
.FvSize
), FvAlignment
);
782 if (FvBuffer
== NULL
) {
783 return EFI_OUT_OF_RESOURCES
;
785 CopyMem (FvBuffer
, FvImageInfo
.FvStart
, (UINTN
) FvImageInfo
.FvSize
);
787 // Update FvImageInfo after reload FvImage to new aligned memory
789 PeiFfsGetVolumeInfo ((EFI_PEI_FV_HANDLE
) FvBuffer
, &FvImageInfo
);
793 // Install FvPpi and Build FvHob
795 PiLibInstallFvInfoPpi (
798 (UINT32
) FvImageInfo
.FvSize
,
799 &(FvImageInfo
.FvName
),
800 &(((EFI_FFS_FILE_HEADER
*)FvFileHandle
)->Name
)
804 // Inform HOB consumer phase, i.e. DXE core, the existance of this FV
807 (EFI_PHYSICAL_ADDRESS
) (UINTN
) FvImageInfo
.FvStart
,
811 // Makes the encapsulated volume show up in DXE phase to skip processing of
812 // encapsulated file again.
815 (EFI_PHYSICAL_ADDRESS
) (UINTN
) FvImageInfo
.FvStart
,
818 &(((EFI_FFS_FILE_HEADER
*)FvFileHandle
)->Name
)