2 EFI PEI Core PPI services
4 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 Initialize PPI services.
21 @param PrivateData Pointer to the PEI Core data.
22 @param OldCoreData Pointer to old PEI Core data.
23 NULL if being run in non-permament memory mode.
27 InitializePpiServices (
28 IN PEI_CORE_INSTANCE
*PrivateData
,
29 IN PEI_CORE_INSTANCE
*OldCoreData
32 if (OldCoreData
== NULL
) {
33 PrivateData
->PpiData
.NotifyListEnd
= PcdGet32 (PcdPeiCoreMaxPpiSupported
)-1;
34 PrivateData
->PpiData
.DispatchListEnd
= PcdGet32 (PcdPeiCoreMaxPpiSupported
)-1;
35 PrivateData
->PpiData
.LastDispatchedNotify
= PcdGet32 (PcdPeiCoreMaxPpiSupported
)-1;
41 Migrate Single PPI Pointer from the temporary memory to PEI installed memory.
43 @param PpiPointer Pointer to Ppi
44 @param TempBottom Base of old temporary memory
45 @param TempTop Top of old temporary memory
46 @param Offset Offset of new memory to old temporary memory.
47 @param OffsetPositive Positive flag of Offset value.
51 ConvertSinglePpiPointer (
52 IN PEI_PPI_LIST_POINTERS
*PpiPointer
,
56 IN BOOLEAN OffsetPositive
59 if (((UINTN
)PpiPointer
->Raw
< TempTop
) &&
60 ((UINTN
)PpiPointer
->Raw
>= TempBottom
)) {
62 // Convert the pointer to the PPI descriptor from the old TempRam
63 // to the relocated physical memory.
66 PpiPointer
->Raw
= (VOID
*) ((UINTN
)PpiPointer
->Raw
+ Offset
);
68 PpiPointer
->Raw
= (VOID
*) ((UINTN
)PpiPointer
->Raw
- Offset
);
72 // Only when the PEIM descriptor is in the old TempRam should it be necessary
73 // to try to convert the pointers in the PEIM descriptor
76 if (((UINTN
)PpiPointer
->Ppi
->Guid
< TempTop
) &&
77 ((UINTN
)PpiPointer
->Ppi
->Guid
>= TempBottom
)) {
79 // Convert the pointer to the GUID in the PPI or NOTIFY descriptor
80 // from the old TempRam to the relocated physical memory.
83 PpiPointer
->Ppi
->Guid
= (VOID
*) ((UINTN
)PpiPointer
->Ppi
->Guid
+ Offset
);
85 PpiPointer
->Ppi
->Guid
= (VOID
*) ((UINTN
)PpiPointer
->Ppi
->Guid
- Offset
);
90 // Convert the pointer to the PPI interface structure in the PPI descriptor
91 // from the old TempRam to the relocated physical memory.
93 if ((UINTN
)PpiPointer
->Ppi
->Ppi
< TempTop
&&
94 (UINTN
)PpiPointer
->Ppi
->Ppi
>= TempBottom
) {
96 PpiPointer
->Ppi
->Ppi
= (VOID
*) ((UINTN
)PpiPointer
->Ppi
->Ppi
+ Offset
);
98 PpiPointer
->Ppi
->Ppi
= (VOID
*) ((UINTN
)PpiPointer
->Ppi
->Ppi
- Offset
);
106 Migrate PPI Pointers from the temporary memory to PEI installed memory.
108 @param SecCoreData Points to a data structure containing SEC to PEI handoff data, such as the size
109 and location of temporary RAM, the stack location and the BFV location.
110 @param PrivateData Pointer to PeiCore's private data structure.
115 IN CONST EFI_SEC_PEI_HAND_OFF
*SecCoreData
,
116 IN PEI_CORE_INSTANCE
*PrivateData
122 for (Index
= 0; Index
< PcdGet32 (PcdPeiCoreMaxPpiSupported
); Index
++) {
123 if (Index
< PrivateData
->PpiData
.PpiListEnd
|| Index
> PrivateData
->PpiData
.NotifyListEnd
) {
124 if (PrivateData
->MemoryPages
.Size
!= 0) {
126 // Convert PPI pointer in old memory pages
127 // It needs to be done before Convert PPI pointer in old Heap
129 ConvertSinglePpiPointer (
130 &PrivateData
->PpiData
.PpiListPtrs
[Index
],
131 (UINTN
)PrivateData
->MemoryPages
.Base
,
132 (UINTN
)PrivateData
->MemoryPages
.Base
+ PrivateData
->MemoryPages
.Size
,
133 PrivateData
->MemoryPages
.Offset
,
134 PrivateData
->MemoryPages
.OffsetPositive
139 // Convert PPI pointer in old Heap
141 ConvertSinglePpiPointer (
142 &PrivateData
->PpiData
.PpiListPtrs
[Index
],
143 (UINTN
)SecCoreData
->PeiTemporaryRamBase
,
144 (UINTN
)SecCoreData
->PeiTemporaryRamBase
+ SecCoreData
->PeiTemporaryRamSize
,
145 PrivateData
->HeapOffset
,
146 PrivateData
->HeapOffsetPositive
150 // Convert PPI pointer in old Stack
152 ConvertSinglePpiPointer (
153 &PrivateData
->PpiData
.PpiListPtrs
[Index
],
154 (UINTN
)SecCoreData
->StackBase
,
155 (UINTN
)SecCoreData
->StackBase
+ SecCoreData
->StackSize
,
156 PrivateData
->StackOffset
,
157 PrivateData
->StackOffsetPositive
161 // Convert PPI pointer in old TempRam Hole
163 for (IndexHole
= 0; IndexHole
< HOLE_MAX_NUMBER
; IndexHole
++) {
164 if (PrivateData
->HoleData
[IndexHole
].Size
== 0) {
168 ConvertSinglePpiPointer (
169 &PrivateData
->PpiData
.PpiListPtrs
[Index
],
170 (UINTN
)PrivateData
->HoleData
[IndexHole
].Base
,
171 (UINTN
)PrivateData
->HoleData
[IndexHole
].Base
+ PrivateData
->HoleData
[IndexHole
].Size
,
172 PrivateData
->HoleData
[IndexHole
].Offset
,
173 PrivateData
->HoleData
[IndexHole
].OffsetPositive
182 This function installs an interface in the PEI PPI database by GUID.
183 The purpose of the service is to publish an interface that other parties
184 can use to call additional PEIMs.
186 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
187 @param PpiList Pointer to a list of PEI PPI Descriptors.
188 @param Single TRUE if only single entry in the PpiList.
189 FALSE if the PpiList is ended with an entry which has the
190 EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST flag set in its Flags field.
192 @retval EFI_SUCCESS if all PPIs in PpiList are successfully installed.
193 @retval EFI_INVALID_PARAMETER if PpiList is NULL pointer
194 if any PPI in PpiList is not valid
195 @retval EFI_OUT_OF_RESOURCES if there is no more memory resource to install PPI
199 InternalPeiInstallPpi (
200 IN CONST EFI_PEI_SERVICES
**PeiServices
,
201 IN CONST EFI_PEI_PPI_DESCRIPTOR
*PpiList
,
205 PEI_CORE_INSTANCE
*PrivateData
;
207 INTN LastCallbackInstall
;
210 if (PpiList
== NULL
) {
211 return EFI_INVALID_PARAMETER
;
214 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices
);
216 Index
= PrivateData
->PpiData
.PpiListEnd
;
217 LastCallbackInstall
= Index
;
220 // This is loop installs all PPI descriptors in the PpiList. It is terminated
221 // by the EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST being set in the last
222 // EFI_PEI_PPI_DESCRIPTOR in the list.
227 // Since PpiData is used for NotifyList and PpiList, max resource
228 // is reached if the Install reaches the NotifyList
229 // PcdPeiCoreMaxPpiSupported can be set to a larger value in DSC to satisfy more PPI requirement.
231 if (Index
== PrivateData
->PpiData
.NotifyListEnd
+ 1) {
232 return EFI_OUT_OF_RESOURCES
;
235 // Check if it is a valid PPI.
236 // If not, rollback list to exclude all in this list.
237 // Try to indicate which item failed.
239 if ((PpiList
->Flags
& EFI_PEI_PPI_DESCRIPTOR_PPI
) == 0) {
240 PrivateData
->PpiData
.PpiListEnd
= LastCallbackInstall
;
241 DEBUG((EFI_D_ERROR
, "ERROR -> InstallPpi: %g %p\n", PpiList
->Guid
, PpiList
->Ppi
));
242 return EFI_INVALID_PARAMETER
;
245 DEBUG((EFI_D_INFO
, "Install PPI: %g\n", PpiList
->Guid
));
246 PrivateData
->PpiData
.PpiListPtrs
[Index
].Ppi
= (EFI_PEI_PPI_DESCRIPTOR
*) PpiList
;
247 PrivateData
->PpiData
.PpiListEnd
++;
251 // Only single entry in the PpiList.
254 } else if ((PpiList
->Flags
& EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
) ==
255 EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
) {
257 // Continue until the end of the PPI List.
266 // Dispatch any callback level notifies for newly installed PPIs.
270 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
,
272 PrivateData
->PpiData
.PpiListEnd
,
273 PrivateData
->PpiData
.DispatchListEnd
,
274 PrivateData
->PpiData
.NotifyListEnd
283 This function installs an interface in the PEI PPI database by GUID.
284 The purpose of the service is to publish an interface that other parties
285 can use to call additional PEIMs.
287 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
288 @param PpiList Pointer to a list of PEI PPI Descriptors.
290 @retval EFI_SUCCESS if all PPIs in PpiList are successfully installed.
291 @retval EFI_INVALID_PARAMETER if PpiList is NULL pointer
292 if any PPI in PpiList is not valid
293 @retval EFI_OUT_OF_RESOURCES if there is no more memory resource to install PPI
299 IN CONST EFI_PEI_SERVICES
**PeiServices
,
300 IN CONST EFI_PEI_PPI_DESCRIPTOR
*PpiList
303 return InternalPeiInstallPpi (PeiServices
, PpiList
, FALSE
);
308 This function reinstalls an interface in the PEI PPI database by GUID.
309 The purpose of the service is to publish an interface that other parties can
310 use to replace an interface of the same name in the protocol database with a
313 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
314 @param OldPpi Pointer to the old PEI PPI Descriptors.
315 @param NewPpi Pointer to the new PEI PPI Descriptors.
317 @retval EFI_SUCCESS if the operation was successful
318 @retval EFI_INVALID_PARAMETER if OldPpi or NewPpi is NULL
319 @retval EFI_INVALID_PARAMETER if NewPpi is not valid
320 @retval EFI_NOT_FOUND if the PPI was not in the database
326 IN CONST EFI_PEI_SERVICES
**PeiServices
,
327 IN CONST EFI_PEI_PPI_DESCRIPTOR
*OldPpi
,
328 IN CONST EFI_PEI_PPI_DESCRIPTOR
*NewPpi
331 PEI_CORE_INSTANCE
*PrivateData
;
335 if ((OldPpi
== NULL
) || (NewPpi
== NULL
)) {
336 return EFI_INVALID_PARAMETER
;
339 if ((NewPpi
->Flags
& EFI_PEI_PPI_DESCRIPTOR_PPI
) == 0) {
340 return EFI_INVALID_PARAMETER
;
343 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices
);
346 // Find the old PPI instance in the database. If we can not find it,
347 // return the EFI_NOT_FOUND error.
349 for (Index
= 0; Index
< PrivateData
->PpiData
.PpiListEnd
; Index
++) {
350 if (OldPpi
== PrivateData
->PpiData
.PpiListPtrs
[Index
].Ppi
) {
354 if (Index
== PrivateData
->PpiData
.PpiListEnd
) {
355 return EFI_NOT_FOUND
;
359 // Remove the old PPI from the database, add the new one.
361 DEBUG((EFI_D_INFO
, "Reinstall PPI: %g\n", NewPpi
->Guid
));
362 ASSERT (Index
< (INTN
)(PcdGet32 (PcdPeiCoreMaxPpiSupported
)));
363 PrivateData
->PpiData
.PpiListPtrs
[Index
].Ppi
= (EFI_PEI_PPI_DESCRIPTOR
*) NewPpi
;
366 // Dispatch any callback level notifies for the newly installed PPI.
370 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
,
373 PrivateData
->PpiData
.DispatchListEnd
,
374 PrivateData
->PpiData
.NotifyListEnd
383 Locate a given named PPI.
386 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
387 @param Guid Pointer to GUID of the PPI.
388 @param Instance Instance Number to discover.
389 @param PpiDescriptor Pointer to reference the found descriptor. If not NULL,
390 returns a pointer to the descriptor (includes flags, etc)
391 @param Ppi Pointer to reference the found PPI
393 @retval EFI_SUCCESS if the PPI is in the database
394 @retval EFI_NOT_FOUND if the PPI is not in the database
400 IN CONST EFI_PEI_SERVICES
**PeiServices
,
401 IN CONST EFI_GUID
*Guid
,
403 IN OUT EFI_PEI_PPI_DESCRIPTOR
**PpiDescriptor
,
407 PEI_CORE_INSTANCE
*PrivateData
;
410 EFI_PEI_PPI_DESCRIPTOR
*TempPtr
;
413 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices
);
416 // Search the data base for the matching instance of the GUIDed PPI.
418 for (Index
= 0; Index
< PrivateData
->PpiData
.PpiListEnd
; Index
++) {
419 TempPtr
= PrivateData
->PpiData
.PpiListPtrs
[Index
].Ppi
;
420 CheckGuid
= TempPtr
->Guid
;
423 // Don't use CompareGuid function here for performance reasons.
424 // Instead we compare the GUID as INT32 at a time and branch
425 // on the first failed comparison.
427 if ((((INT32
*)Guid
)[0] == ((INT32
*)CheckGuid
)[0]) &&
428 (((INT32
*)Guid
)[1] == ((INT32
*)CheckGuid
)[1]) &&
429 (((INT32
*)Guid
)[2] == ((INT32
*)CheckGuid
)[2]) &&
430 (((INT32
*)Guid
)[3] == ((INT32
*)CheckGuid
)[3])) {
433 if (PpiDescriptor
!= NULL
) {
434 *PpiDescriptor
= TempPtr
;
448 return EFI_NOT_FOUND
;
453 This function installs a notification service to be called back when a given
454 interface is installed or reinstalled. The purpose of the service is to publish
455 an interface that other parties can use to call additional PPIs that may materialize later.
457 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
458 @param NotifyList Pointer to list of Descriptors to notify upon.
459 @param Single TRUE if only single entry in the NotifyList.
460 FALSE if the NotifyList is ended with an entry which has the
461 EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST flag set in its Flags field.
463 @retval EFI_SUCCESS if successful
464 @retval EFI_OUT_OF_RESOURCES if no space in the database
465 @retval EFI_INVALID_PARAMETER if not a good descriptor
469 InternalPeiNotifyPpi (
470 IN CONST EFI_PEI_SERVICES
**PeiServices
,
471 IN CONST EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyList
,
475 PEI_CORE_INSTANCE
*PrivateData
;
478 INTN LastCallbackNotify
;
479 EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyPtr
;
480 UINTN NotifyDispatchCount
;
483 NotifyDispatchCount
= 0;
485 if (NotifyList
== NULL
) {
486 return EFI_INVALID_PARAMETER
;
489 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices
);
491 Index
= PrivateData
->PpiData
.NotifyListEnd
;
492 LastCallbackNotify
= Index
;
495 // This is loop installs all Notify descriptors in the NotifyList. It is
496 // terminated by the EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST being set in the last
497 // EFI_PEI_NOTIFY_DESCRIPTOR in the list.
502 // Since PpiData is used for NotifyList and InstallList, max resource
503 // is reached if the Install reaches the PpiList
504 // PcdPeiCoreMaxPpiSupported can be set to a larger value in DSC to satisfy more Notify PPIs requirement.
506 if (Index
== PrivateData
->PpiData
.PpiListEnd
- 1) {
507 return EFI_OUT_OF_RESOURCES
;
511 // If some of the PPI data is invalid restore original Notify PPI database value
513 if ((NotifyList
->Flags
& EFI_PEI_PPI_DESCRIPTOR_NOTIFY_TYPES
) == 0) {
514 PrivateData
->PpiData
.NotifyListEnd
= LastCallbackNotify
;
515 DEBUG((EFI_D_ERROR
, "ERROR -> InstallNotify: %g %p\n", NotifyList
->Guid
, NotifyList
->Notify
));
516 return EFI_INVALID_PARAMETER
;
519 if ((NotifyList
->Flags
& EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH
) != 0) {
520 NotifyDispatchCount
++;
523 PrivateData
->PpiData
.PpiListPtrs
[Index
].Notify
= (EFI_PEI_NOTIFY_DESCRIPTOR
*) NotifyList
;
525 PrivateData
->PpiData
.NotifyListEnd
--;
526 DEBUG((EFI_D_INFO
, "Register PPI Notify: %g\n", NotifyList
->Guid
));
529 // Only single entry in the NotifyList.
532 } else if ((NotifyList
->Flags
& EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
) ==
533 EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
) {
535 // Continue until the end of the Notify List.
540 // Go the next descriptor. Remember the NotifyList moves down.
547 // If there is Dispatch Notify PPI installed put them on the bottom
549 if (NotifyDispatchCount
> 0) {
550 for (NotifyIndex
= LastCallbackNotify
; NotifyIndex
> PrivateData
->PpiData
.NotifyListEnd
; NotifyIndex
--) {
551 if ((PrivateData
->PpiData
.PpiListPtrs
[NotifyIndex
].Notify
->Flags
& EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH
) != 0) {
552 NotifyPtr
= PrivateData
->PpiData
.PpiListPtrs
[NotifyIndex
].Notify
;
554 for (Index
= NotifyIndex
; Index
< PrivateData
->PpiData
.DispatchListEnd
; Index
++){
555 PrivateData
->PpiData
.PpiListPtrs
[Index
].Notify
= PrivateData
->PpiData
.PpiListPtrs
[Index
+ 1].Notify
;
557 PrivateData
->PpiData
.PpiListPtrs
[Index
].Notify
= NotifyPtr
;
558 PrivateData
->PpiData
.DispatchListEnd
--;
562 LastCallbackNotify
-= NotifyDispatchCount
;
566 // Dispatch any callback level notifies for all previously installed PPIs.
570 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
,
572 PrivateData
->PpiData
.PpiListEnd
,
574 PrivateData
->PpiData
.NotifyListEnd
582 This function installs a notification service to be called back when a given
583 interface is installed or reinstalled. The purpose of the service is to publish
584 an interface that other parties can use to call additional PPIs that may materialize later.
586 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
587 @param NotifyList Pointer to list of Descriptors to notify upon.
589 @retval EFI_SUCCESS if successful
590 @retval EFI_OUT_OF_RESOURCES if no space in the database
591 @retval EFI_INVALID_PARAMETER if not a good descriptor
597 IN CONST EFI_PEI_SERVICES
**PeiServices
,
598 IN CONST EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyList
601 return InternalPeiNotifyPpi (PeiServices
, NotifyList
, FALSE
);
607 Process the Notify List at dispatch level.
609 @param PrivateData PeiCore's private data structure.
614 IN PEI_CORE_INSTANCE
*PrivateData
621 // Check if the PEIM that was just dispatched resulted in any
622 // Notifies getting installed. If so, go process any dispatch
623 // level Notifies that match the previouly installed PPIs.
624 // Use "while" instead of "if" since DispatchNotify can modify
625 // DispatchListEnd (with NotifyPpi) so we have to iterate until the same.
627 while (PrivateData
->PpiData
.LastDispatchedNotify
!= PrivateData
->PpiData
.DispatchListEnd
) {
628 TempValue
= PrivateData
->PpiData
.DispatchListEnd
;
631 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH
,
633 PrivateData
->PpiData
.LastDispatchedInstall
,
634 PrivateData
->PpiData
.LastDispatchedNotify
,
635 PrivateData
->PpiData
.DispatchListEnd
637 PrivateData
->PpiData
.LastDispatchedNotify
= TempValue
;
642 // Check if the PEIM that was just dispatched resulted in any
643 // PPIs getting installed. If so, go process any dispatch
644 // level Notifies that match the installed PPIs.
645 // Use "while" instead of "if" since DispatchNotify can modify
646 // PpiListEnd (with InstallPpi) so we have to iterate until the same.
648 while (PrivateData
->PpiData
.LastDispatchedInstall
!= PrivateData
->PpiData
.PpiListEnd
) {
649 TempValue
= PrivateData
->PpiData
.PpiListEnd
;
652 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH
,
653 PrivateData
->PpiData
.LastDispatchedInstall
,
654 PrivateData
->PpiData
.PpiListEnd
,
655 PcdGet32 (PcdPeiCoreMaxPpiSupported
)-1,
656 PrivateData
->PpiData
.DispatchListEnd
658 PrivateData
->PpiData
.LastDispatchedInstall
= TempValue
;
661 if (PrivateData
->PpiData
.LastDispatchedNotify
== PrivateData
->PpiData
.DispatchListEnd
) {
670 Dispatch notifications.
672 @param PrivateData PeiCore's private data structure
673 @param NotifyType Type of notify to fire.
674 @param InstallStartIndex Install Beginning index.
675 @param InstallStopIndex Install Ending index.
676 @param NotifyStartIndex Notify Beginning index.
677 @param NotifyStopIndex Notify Ending index.
682 IN PEI_CORE_INSTANCE
*PrivateData
,
684 IN INTN InstallStartIndex
,
685 IN INTN InstallStopIndex
,
686 IN INTN NotifyStartIndex
,
687 IN INTN NotifyStopIndex
692 EFI_GUID
*SearchGuid
;
694 EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
;
697 // Remember that Installs moves up and Notifies moves down.
699 for (Index1
= NotifyStartIndex
; Index1
> NotifyStopIndex
; Index1
--) {
700 NotifyDescriptor
= PrivateData
->PpiData
.PpiListPtrs
[Index1
].Notify
;
702 CheckGuid
= NotifyDescriptor
->Guid
;
704 for (Index2
= InstallStartIndex
; Index2
< InstallStopIndex
; Index2
++) {
705 SearchGuid
= PrivateData
->PpiData
.PpiListPtrs
[Index2
].Ppi
->Guid
;
707 // Don't use CompareGuid function here for performance reasons.
708 // Instead we compare the GUID as INT32 at a time and branch
709 // on the first failed comparison.
711 if ((((INT32
*)SearchGuid
)[0] == ((INT32
*)CheckGuid
)[0]) &&
712 (((INT32
*)SearchGuid
)[1] == ((INT32
*)CheckGuid
)[1]) &&
713 (((INT32
*)SearchGuid
)[2] == ((INT32
*)CheckGuid
)[2]) &&
714 (((INT32
*)SearchGuid
)[3] == ((INT32
*)CheckGuid
)[3])) {
715 DEBUG ((EFI_D_INFO
, "Notify: PPI Guid: %g, Peim notify entry point: %p\n",
717 NotifyDescriptor
->Notify
719 NotifyDescriptor
->Notify (
720 (EFI_PEI_SERVICES
**) GetPeiServicesTablePointer (),
722 (PrivateData
->PpiData
.PpiListPtrs
[Index2
].Ppi
)->Ppi
730 Process PpiList from SEC phase.
732 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
733 @param PpiList Points to a list of one or more PPI descriptors to be installed initially by the PEI core.
734 These PPI's will be installed and/or immediately signaled if they are notification type.
738 ProcessPpiListFromSec (
739 IN CONST EFI_PEI_SERVICES
**PeiServices
,
740 IN CONST EFI_PEI_PPI_DESCRIPTOR
*PpiList
744 EFI_SEC_HOB_DATA_PPI
*SecHobDataPpi
;
745 EFI_HOB_GENERIC_HEADER
*SecHobList
;
748 if ((PpiList
->Flags
& EFI_PEI_PPI_DESCRIPTOR_NOTIFY_TYPES
) != 0) {
750 // It is a notification PPI.
752 Status
= InternalPeiNotifyPpi (PeiServices
, (CONST EFI_PEI_NOTIFY_DESCRIPTOR
*) PpiList
, TRUE
);
753 ASSERT_EFI_ERROR (Status
);
756 // It is a normal PPI.
758 Status
= InternalPeiInstallPpi (PeiServices
, PpiList
, TRUE
);
759 ASSERT_EFI_ERROR (Status
);
762 if ((PpiList
->Flags
& EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
) == EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
) {
764 // Continue until the end of the PPI List.
773 // If the EFI_SEC_HOB_DATA_PPI is in the list of PPIs passed to the PEI entry point,
774 // the PEI Foundation will call the GetHobs() member function and install all HOBs
775 // returned into the HOB list. It does this after installing all PPIs passed from SEC
776 // into the PPI database and before dispatching any PEIMs.
778 Status
= PeiLocatePpi (PeiServices
, &gEfiSecHobDataPpiGuid
, 0, NULL
, (VOID
**) &SecHobDataPpi
);
779 if (!EFI_ERROR (Status
)) {
780 Status
= SecHobDataPpi
->GetHobs (SecHobDataPpi
, &SecHobList
);
781 if (!EFI_ERROR (Status
)) {
782 Status
= PeiInstallSecHobData (PeiServices
, SecHobList
);
783 ASSERT_EFI_ERROR (Status
);