2 EFI PEI Core PPI services
4 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
13 Migrate Pointer from the temporary memory to PEI installed memory.
15 @param Pointer Pointer to the Pointer needs to be converted.
16 @param TempBottom Base of old temporary memory
17 @param TempTop Top of old temporary memory
18 @param Offset Offset of new memory to old temporary memory.
19 @param OffsetPositive Positive flag of Offset value.
24 IN OUT VOID
**Pointer
,
28 IN BOOLEAN OffsetPositive
31 if (((UINTN
) *Pointer
< TempTop
) &&
32 ((UINTN
) *Pointer
>= TempBottom
)) {
34 *Pointer
= (VOID
*) ((UINTN
) *Pointer
+ Offset
);
36 *Pointer
= (VOID
*) ((UINTN
) *Pointer
- Offset
);
43 Migrate Pointer in ranges of the temporary memory to PEI installed memory.
45 @param SecCoreData Points to a data structure containing SEC to PEI handoff data, such as the size
46 and location of temporary RAM, the stack location and the BFV location.
47 @param PrivateData Pointer to PeiCore's private data structure.
48 @param Pointer Pointer to the Pointer needs to be converted.
52 ConvertPointerInRanges (
53 IN CONST EFI_SEC_PEI_HAND_OFF
*SecCoreData
,
54 IN PEI_CORE_INSTANCE
*PrivateData
,
60 if (PrivateData
->MemoryPages
.Size
!= 0) {
62 // Convert PPI pointer in old memory pages
63 // It needs to be done before Convert PPI pointer in old Heap
67 (UINTN
)PrivateData
->MemoryPages
.Base
,
68 (UINTN
)PrivateData
->MemoryPages
.Base
+ PrivateData
->MemoryPages
.Size
,
69 PrivateData
->MemoryPages
.Offset
,
70 PrivateData
->MemoryPages
.OffsetPositive
75 // Convert PPI pointer in old Heap
79 (UINTN
)SecCoreData
->PeiTemporaryRamBase
,
80 (UINTN
)SecCoreData
->PeiTemporaryRamBase
+ SecCoreData
->PeiTemporaryRamSize
,
81 PrivateData
->HeapOffset
,
82 PrivateData
->HeapOffsetPositive
86 // Convert PPI pointer in old Stack
90 (UINTN
)SecCoreData
->StackBase
,
91 (UINTN
)SecCoreData
->StackBase
+ SecCoreData
->StackSize
,
92 PrivateData
->StackOffset
,
93 PrivateData
->StackOffsetPositive
97 // Convert PPI pointer in old TempRam Hole
99 for (IndexHole
= 0; IndexHole
< HOLE_MAX_NUMBER
; IndexHole
++) {
100 if (PrivateData
->HoleData
[IndexHole
].Size
== 0) {
106 (UINTN
)PrivateData
->HoleData
[IndexHole
].Base
,
107 (UINTN
)PrivateData
->HoleData
[IndexHole
].Base
+ PrivateData
->HoleData
[IndexHole
].Size
,
108 PrivateData
->HoleData
[IndexHole
].Offset
,
109 PrivateData
->HoleData
[IndexHole
].OffsetPositive
116 Migrate Single PPI Pointer from the temporary memory to PEI installed memory.
118 @param SecCoreData Points to a data structure containing SEC to PEI handoff data, such as the size
119 and location of temporary RAM, the stack location and the BFV location.
120 @param PrivateData Pointer to PeiCore's private data structure.
121 @param PpiPointer Pointer to Ppi
125 ConvertSinglePpiPointer (
126 IN CONST EFI_SEC_PEI_HAND_OFF
*SecCoreData
,
127 IN PEI_CORE_INSTANCE
*PrivateData
,
128 IN PEI_PPI_LIST_POINTERS
*PpiPointer
132 // 1. Convert the pointer to the PPI descriptor from the old TempRam
133 // to the relocated physical memory.
134 // It (for the pointer to the PPI descriptor) needs to be done before 2 (for
135 // the pointer to the GUID) and 3 (for the pointer to the PPI interface structure).
137 ConvertPointerInRanges (SecCoreData
, PrivateData
, &PpiPointer
->Raw
);
139 // 2. Convert the pointer to the GUID in the PPI or NOTIFY descriptor
140 // from the old TempRam to the relocated physical memory.
142 ConvertPointerInRanges (SecCoreData
, PrivateData
, (VOID
**) &PpiPointer
->Ppi
->Guid
);
144 // 3. Convert the pointer to the PPI interface structure in the PPI descriptor
145 // from the old TempRam to the relocated physical memory.
147 ConvertPointerInRanges (SecCoreData
, PrivateData
, (VOID
**) &PpiPointer
->Ppi
->Ppi
);
152 Migrate PPI Pointers from the temporary memory to PEI installed memory.
154 @param SecCoreData Points to a data structure containing SEC to PEI handoff data, such as the size
155 and location of temporary RAM, the stack location and the BFV location.
156 @param PrivateData Pointer to PeiCore's private data structure.
161 IN CONST EFI_SEC_PEI_HAND_OFF
*SecCoreData
,
162 IN PEI_CORE_INSTANCE
*PrivateData
168 // Convert normal PPIs.
170 for (Index
= 0; Index
< PrivateData
->PpiData
.PpiList
.CurrentCount
; Index
++) {
171 ConvertSinglePpiPointer (
174 &PrivateData
->PpiData
.PpiList
.PpiPtrs
[Index
]
179 // Convert Callback Notification PPIs.
181 for (Index
= 0; Index
< PrivateData
->PpiData
.CallbackNotifyList
.CurrentCount
; Index
++) {
182 ConvertSinglePpiPointer (
185 &PrivateData
->PpiData
.CallbackNotifyList
.NotifyPtrs
[Index
]
190 // Convert Dispatch Notification PPIs.
192 for (Index
= 0; Index
< PrivateData
->PpiData
.DispatchNotifyList
.CurrentCount
; Index
++) {
193 ConvertSinglePpiPointer (
196 &PrivateData
->PpiData
.DispatchNotifyList
.NotifyPtrs
[Index
]
203 This function installs an interface in the PEI PPI database by GUID.
204 The purpose of the service is to publish an interface that other parties
205 can use to call additional PEIMs.
207 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
208 @param PpiList Pointer to a list of PEI PPI Descriptors.
209 @param Single TRUE if only single entry in the PpiList.
210 FALSE if the PpiList is ended with an entry which has the
211 EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST flag set in its Flags field.
213 @retval EFI_SUCCESS if all PPIs in PpiList are successfully installed.
214 @retval EFI_INVALID_PARAMETER if PpiList is NULL pointer
215 if any PPI in PpiList is not valid
216 @retval EFI_OUT_OF_RESOURCES if there is no more memory resource to install PPI
220 InternalPeiInstallPpi (
221 IN CONST EFI_PEI_SERVICES
**PeiServices
,
222 IN CONST EFI_PEI_PPI_DESCRIPTOR
*PpiList
,
226 PEI_CORE_INSTANCE
*PrivateData
;
227 PEI_PPI_LIST
*PpiListPointer
;
232 if (PpiList
== NULL
) {
233 return EFI_INVALID_PARAMETER
;
236 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices
);
238 PpiListPointer
= &PrivateData
->PpiData
.PpiList
;
239 Index
= PpiListPointer
->CurrentCount
;
243 // This is loop installs all PPI descriptors in the PpiList. It is terminated
244 // by the EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST being set in the last
245 // EFI_PEI_PPI_DESCRIPTOR in the list.
250 // Check if it is a valid PPI.
251 // If not, rollback list to exclude all in this list.
252 // Try to indicate which item failed.
254 if ((PpiList
->Flags
& EFI_PEI_PPI_DESCRIPTOR_PPI
) == 0) {
255 PpiListPointer
->CurrentCount
= LastCount
;
256 DEBUG((EFI_D_ERROR
, "ERROR -> InstallPpi: %g %p\n", PpiList
->Guid
, PpiList
->Ppi
));
257 return EFI_INVALID_PARAMETER
;
260 if (Index
>= PpiListPointer
->MaxCount
) {
262 // Run out of room, grow the buffer.
264 TempPtr
= AllocateZeroPool (
265 sizeof (PEI_PPI_LIST_POINTERS
) * (PpiListPointer
->MaxCount
+ PPI_GROWTH_STEP
)
267 ASSERT (TempPtr
!= NULL
);
270 PpiListPointer
->PpiPtrs
,
271 sizeof (PEI_PPI_LIST_POINTERS
) * PpiListPointer
->MaxCount
273 PpiListPointer
->PpiPtrs
= TempPtr
;
274 PpiListPointer
->MaxCount
= PpiListPointer
->MaxCount
+ PPI_GROWTH_STEP
;
277 DEBUG((EFI_D_INFO
, "Install PPI: %g\n", PpiList
->Guid
));
278 PpiListPointer
->PpiPtrs
[Index
].Ppi
= (EFI_PEI_PPI_DESCRIPTOR
*) PpiList
;
280 PpiListPointer
->CurrentCount
++;
284 // Only single entry in the PpiList.
287 } else if ((PpiList
->Flags
& EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
) ==
288 EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
) {
290 // Continue until the end of the PPI List.
295 // Go to the next descriptor.
301 // Process any callback level notifies for newly installed PPIs.
305 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
,
307 PpiListPointer
->CurrentCount
,
309 PrivateData
->PpiData
.CallbackNotifyList
.CurrentCount
317 This function installs an interface in the PEI PPI database by GUID.
318 The purpose of the service is to publish an interface that other parties
319 can use to call additional PEIMs.
321 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
322 @param PpiList Pointer to a list of PEI PPI Descriptors.
324 @retval EFI_SUCCESS if all PPIs in PpiList are successfully installed.
325 @retval EFI_INVALID_PARAMETER if PpiList is NULL pointer
326 if any PPI in PpiList is not valid
327 @retval EFI_OUT_OF_RESOURCES if there is no more memory resource to install PPI
333 IN CONST EFI_PEI_SERVICES
**PeiServices
,
334 IN CONST EFI_PEI_PPI_DESCRIPTOR
*PpiList
337 return InternalPeiInstallPpi (PeiServices
, PpiList
, FALSE
);
342 This function reinstalls an interface in the PEI PPI database by GUID.
343 The purpose of the service is to publish an interface that other parties can
344 use to replace an interface of the same name in the protocol database with a
347 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
348 @param OldPpi Pointer to the old PEI PPI Descriptors.
349 @param NewPpi Pointer to the new PEI PPI Descriptors.
351 @retval EFI_SUCCESS if the operation was successful
352 @retval EFI_INVALID_PARAMETER if OldPpi or NewPpi is NULL
353 @retval EFI_INVALID_PARAMETER if NewPpi is not valid
354 @retval EFI_NOT_FOUND if the PPI was not in the database
360 IN CONST EFI_PEI_SERVICES
**PeiServices
,
361 IN CONST EFI_PEI_PPI_DESCRIPTOR
*OldPpi
,
362 IN CONST EFI_PEI_PPI_DESCRIPTOR
*NewPpi
365 PEI_CORE_INSTANCE
*PrivateData
;
369 if ((OldPpi
== NULL
) || (NewPpi
== NULL
)) {
370 return EFI_INVALID_PARAMETER
;
373 if ((NewPpi
->Flags
& EFI_PEI_PPI_DESCRIPTOR_PPI
) == 0) {
374 return EFI_INVALID_PARAMETER
;
377 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices
);
380 // Find the old PPI instance in the database. If we can not find it,
381 // return the EFI_NOT_FOUND error.
383 for (Index
= 0; Index
< PrivateData
->PpiData
.PpiList
.CurrentCount
; Index
++) {
384 if (OldPpi
== PrivateData
->PpiData
.PpiList
.PpiPtrs
[Index
].Ppi
) {
388 if (Index
== PrivateData
->PpiData
.PpiList
.CurrentCount
) {
389 return EFI_NOT_FOUND
;
393 // Replace the old PPI with the new one.
395 DEBUG((EFI_D_INFO
, "Reinstall PPI: %g\n", NewPpi
->Guid
));
396 PrivateData
->PpiData
.PpiList
.PpiPtrs
[Index
].Ppi
= (EFI_PEI_PPI_DESCRIPTOR
*) NewPpi
;
399 // Process any callback level notifies for the newly installed PPI.
403 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
,
407 PrivateData
->PpiData
.CallbackNotifyList
.CurrentCount
415 Locate a given named PPI.
418 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
419 @param Guid Pointer to GUID of the PPI.
420 @param Instance Instance Number to discover.
421 @param PpiDescriptor Pointer to reference the found descriptor. If not NULL,
422 returns a pointer to the descriptor (includes flags, etc)
423 @param Ppi Pointer to reference the found PPI
425 @retval EFI_SUCCESS if the PPI is in the database
426 @retval EFI_NOT_FOUND if the PPI is not in the database
432 IN CONST EFI_PEI_SERVICES
**PeiServices
,
433 IN CONST EFI_GUID
*Guid
,
435 IN OUT EFI_PEI_PPI_DESCRIPTOR
**PpiDescriptor
,
439 PEI_CORE_INSTANCE
*PrivateData
;
442 EFI_PEI_PPI_DESCRIPTOR
*TempPtr
;
445 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices
);
448 // Search the data base for the matching instance of the GUIDed PPI.
450 for (Index
= 0; Index
< PrivateData
->PpiData
.PpiList
.CurrentCount
; Index
++) {
451 TempPtr
= PrivateData
->PpiData
.PpiList
.PpiPtrs
[Index
].Ppi
;
452 CheckGuid
= TempPtr
->Guid
;
455 // Don't use CompareGuid function here for performance reasons.
456 // Instead we compare the GUID as INT32 at a time and branch
457 // on the first failed comparison.
459 if ((((INT32
*)Guid
)[0] == ((INT32
*)CheckGuid
)[0]) &&
460 (((INT32
*)Guid
)[1] == ((INT32
*)CheckGuid
)[1]) &&
461 (((INT32
*)Guid
)[2] == ((INT32
*)CheckGuid
)[2]) &&
462 (((INT32
*)Guid
)[3] == ((INT32
*)CheckGuid
)[3])) {
465 if (PpiDescriptor
!= NULL
) {
466 *PpiDescriptor
= TempPtr
;
480 return EFI_NOT_FOUND
;
485 This function installs a notification service to be called back when a given
486 interface is installed or reinstalled. The purpose of the service is to publish
487 an interface that other parties can use to call additional PPIs that may materialize later.
489 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
490 @param NotifyList Pointer to list of Descriptors to notify upon.
491 @param Single TRUE if only single entry in the NotifyList.
492 FALSE if the NotifyList is ended with an entry which has the
493 EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST flag set in its Flags field.
495 @retval EFI_SUCCESS if successful
496 @retval EFI_OUT_OF_RESOURCES if no space in the database
497 @retval EFI_INVALID_PARAMETER if not a good descriptor
501 InternalPeiNotifyPpi (
502 IN CONST EFI_PEI_SERVICES
**PeiServices
,
503 IN CONST EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyList
,
507 PEI_CORE_INSTANCE
*PrivateData
;
508 PEI_CALLBACK_NOTIFY_LIST
*CallbackNotifyListPointer
;
509 UINTN CallbackNotifyIndex
;
510 UINTN LastCallbackNotifyCount
;
511 PEI_DISPATCH_NOTIFY_LIST
*DispatchNotifyListPointer
;
512 UINTN DispatchNotifyIndex
;
513 UINTN LastDispatchNotifyCount
;
516 if (NotifyList
== NULL
) {
517 return EFI_INVALID_PARAMETER
;
520 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices
);
522 CallbackNotifyListPointer
= &PrivateData
->PpiData
.CallbackNotifyList
;
523 CallbackNotifyIndex
= CallbackNotifyListPointer
->CurrentCount
;
524 LastCallbackNotifyCount
= CallbackNotifyIndex
;
526 DispatchNotifyListPointer
= &PrivateData
->PpiData
.DispatchNotifyList
;
527 DispatchNotifyIndex
= DispatchNotifyListPointer
->CurrentCount
;
528 LastDispatchNotifyCount
= DispatchNotifyIndex
;
531 // This is loop installs all Notify descriptors in the NotifyList. It is
532 // terminated by the EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST being set in the last
533 // EFI_PEI_NOTIFY_DESCRIPTOR in the list.
538 // If some of the PPI data is invalid restore original Notify PPI database value
540 if ((NotifyList
->Flags
& EFI_PEI_PPI_DESCRIPTOR_NOTIFY_TYPES
) == 0) {
541 CallbackNotifyListPointer
->CurrentCount
= LastCallbackNotifyCount
;
542 DispatchNotifyListPointer
->CurrentCount
= LastDispatchNotifyCount
;
543 DEBUG((DEBUG_ERROR
, "ERROR -> NotifyPpi: %g %p\n", NotifyList
->Guid
, NotifyList
->Notify
));
544 return EFI_INVALID_PARAMETER
;
547 if ((NotifyList
->Flags
& EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
) != 0) {
548 if (CallbackNotifyIndex
>= CallbackNotifyListPointer
->MaxCount
) {
550 // Run out of room, grow the buffer.
552 TempPtr
= AllocateZeroPool (
553 sizeof (PEI_PPI_LIST_POINTERS
) * (CallbackNotifyListPointer
->MaxCount
+ CALLBACK_NOTIFY_GROWTH_STEP
)
555 ASSERT (TempPtr
!= NULL
);
558 CallbackNotifyListPointer
->NotifyPtrs
,
559 sizeof (PEI_PPI_LIST_POINTERS
) * CallbackNotifyListPointer
->MaxCount
561 CallbackNotifyListPointer
->NotifyPtrs
= TempPtr
;
562 CallbackNotifyListPointer
->MaxCount
= CallbackNotifyListPointer
->MaxCount
+ CALLBACK_NOTIFY_GROWTH_STEP
;
564 CallbackNotifyListPointer
->NotifyPtrs
[CallbackNotifyIndex
].Notify
= (EFI_PEI_NOTIFY_DESCRIPTOR
*) NotifyList
;
565 CallbackNotifyIndex
++;
566 CallbackNotifyListPointer
->CurrentCount
++;
568 if (DispatchNotifyIndex
>= DispatchNotifyListPointer
->MaxCount
) {
570 // Run out of room, grow the buffer.
572 TempPtr
= AllocateZeroPool (
573 sizeof (PEI_PPI_LIST_POINTERS
) * (DispatchNotifyListPointer
->MaxCount
+ DISPATCH_NOTIFY_GROWTH_STEP
)
575 ASSERT (TempPtr
!= NULL
);
578 DispatchNotifyListPointer
->NotifyPtrs
,
579 sizeof (PEI_PPI_LIST_POINTERS
) * DispatchNotifyListPointer
->MaxCount
581 DispatchNotifyListPointer
->NotifyPtrs
= TempPtr
;
582 DispatchNotifyListPointer
->MaxCount
= DispatchNotifyListPointer
->MaxCount
+ DISPATCH_NOTIFY_GROWTH_STEP
;
584 DispatchNotifyListPointer
->NotifyPtrs
[DispatchNotifyIndex
].Notify
= (EFI_PEI_NOTIFY_DESCRIPTOR
*) NotifyList
;
585 DispatchNotifyIndex
++;
586 DispatchNotifyListPointer
->CurrentCount
++;
589 DEBUG((EFI_D_INFO
, "Register PPI Notify: %g\n", NotifyList
->Guid
));
593 // Only single entry in the NotifyList.
596 } else if ((NotifyList
->Flags
& EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
) ==
597 EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
) {
599 // Continue until the end of the Notify List.
604 // Go to the next descriptor.
610 // Process any callback level notifies for all previously installed PPIs.
614 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
,
616 PrivateData
->PpiData
.PpiList
.CurrentCount
,
617 LastCallbackNotifyCount
,
618 CallbackNotifyListPointer
->CurrentCount
626 This function installs a notification service to be called back when a given
627 interface is installed or reinstalled. The purpose of the service is to publish
628 an interface that other parties can use to call additional PPIs that may materialize later.
630 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
631 @param NotifyList Pointer to list of Descriptors to notify upon.
633 @retval EFI_SUCCESS if successful
634 @retval EFI_OUT_OF_RESOURCES if no space in the database
635 @retval EFI_INVALID_PARAMETER if not a good descriptor
641 IN CONST EFI_PEI_SERVICES
**PeiServices
,
642 IN CONST EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyList
645 return InternalPeiNotifyPpi (PeiServices
, NotifyList
, FALSE
);
650 Process the Notify List at dispatch level.
652 @param PrivateData PeiCore's private data structure.
656 ProcessDispatchNotifyList (
657 IN PEI_CORE_INSTANCE
*PrivateData
664 // Check if the PEIM that was just dispatched resulted in any
665 // Notifies getting installed. If so, go process any dispatch
666 // level Notifies that match the previouly installed PPIs.
667 // Use "while" instead of "if" since ProcessNotify can modify
668 // DispatchNotifyList.CurrentCount (with NotifyPpi) so we have
669 // to iterate until the same.
671 while (PrivateData
->PpiData
.DispatchNotifyList
.LastDispatchedCount
!= PrivateData
->PpiData
.DispatchNotifyList
.CurrentCount
) {
672 TempValue
= PrivateData
->PpiData
.DispatchNotifyList
.CurrentCount
;
675 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH
,
677 PrivateData
->PpiData
.PpiList
.LastDispatchedCount
,
678 PrivateData
->PpiData
.DispatchNotifyList
.LastDispatchedCount
,
679 PrivateData
->PpiData
.DispatchNotifyList
.CurrentCount
681 PrivateData
->PpiData
.DispatchNotifyList
.LastDispatchedCount
= TempValue
;
685 // Check if the PEIM that was just dispatched resulted in any
686 // PPIs getting installed. If so, go process any dispatch
687 // level Notifies that match the installed PPIs.
688 // Use "while" instead of "if" since ProcessNotify can modify
689 // PpiList.CurrentCount (with InstallPpi) so we have to iterate
692 while (PrivateData
->PpiData
.PpiList
.LastDispatchedCount
!= PrivateData
->PpiData
.PpiList
.CurrentCount
) {
693 TempValue
= PrivateData
->PpiData
.PpiList
.CurrentCount
;
696 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH
,
697 PrivateData
->PpiData
.PpiList
.LastDispatchedCount
,
698 PrivateData
->PpiData
.PpiList
.CurrentCount
,
700 PrivateData
->PpiData
.DispatchNotifyList
.LastDispatchedCount
702 PrivateData
->PpiData
.PpiList
.LastDispatchedCount
= TempValue
;
705 if (PrivateData
->PpiData
.DispatchNotifyList
.LastDispatchedCount
== PrivateData
->PpiData
.DispatchNotifyList
.CurrentCount
) {
714 Process notifications.
716 @param PrivateData PeiCore's private data structure
717 @param NotifyType Type of notify to fire.
718 @param InstallStartIndex Install Beginning index.
719 @param InstallStopIndex Install Ending index.
720 @param NotifyStartIndex Notify Beginning index.
721 @param NotifyStopIndex Notify Ending index.
726 IN PEI_CORE_INSTANCE
*PrivateData
,
728 IN INTN InstallStartIndex
,
729 IN INTN InstallStopIndex
,
730 IN INTN NotifyStartIndex
,
731 IN INTN NotifyStopIndex
736 EFI_GUID
*SearchGuid
;
738 EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
;
740 for (Index1
= NotifyStartIndex
; Index1
< NotifyStopIndex
; Index1
++) {
741 if (NotifyType
== EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
) {
742 NotifyDescriptor
= PrivateData
->PpiData
.CallbackNotifyList
.NotifyPtrs
[Index1
].Notify
;
744 NotifyDescriptor
= PrivateData
->PpiData
.DispatchNotifyList
.NotifyPtrs
[Index1
].Notify
;
747 CheckGuid
= NotifyDescriptor
->Guid
;
749 for (Index2
= InstallStartIndex
; Index2
< InstallStopIndex
; Index2
++) {
750 SearchGuid
= PrivateData
->PpiData
.PpiList
.PpiPtrs
[Index2
].Ppi
->Guid
;
752 // Don't use CompareGuid function here for performance reasons.
753 // Instead we compare the GUID as INT32 at a time and branch
754 // on the first failed comparison.
756 if ((((INT32
*)SearchGuid
)[0] == ((INT32
*)CheckGuid
)[0]) &&
757 (((INT32
*)SearchGuid
)[1] == ((INT32
*)CheckGuid
)[1]) &&
758 (((INT32
*)SearchGuid
)[2] == ((INT32
*)CheckGuid
)[2]) &&
759 (((INT32
*)SearchGuid
)[3] == ((INT32
*)CheckGuid
)[3])) {
760 DEBUG ((EFI_D_INFO
, "Notify: PPI Guid: %g, Peim notify entry point: %p\n",
762 NotifyDescriptor
->Notify
764 NotifyDescriptor
->Notify (
765 (EFI_PEI_SERVICES
**) GetPeiServicesTablePointer (),
767 (PrivateData
->PpiData
.PpiList
.PpiPtrs
[Index2
].Ppi
)->Ppi
775 Process PpiList from SEC phase.
777 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
778 @param PpiList Points to a list of one or more PPI descriptors to be installed initially by the PEI core.
779 These PPI's will be installed and/or immediately signaled if they are notification type.
783 ProcessPpiListFromSec (
784 IN CONST EFI_PEI_SERVICES
**PeiServices
,
785 IN CONST EFI_PEI_PPI_DESCRIPTOR
*PpiList
789 EFI_SEC_HOB_DATA_PPI
*SecHobDataPpi
;
790 EFI_HOB_GENERIC_HEADER
*SecHobList
;
793 if ((PpiList
->Flags
& EFI_PEI_PPI_DESCRIPTOR_NOTIFY_TYPES
) != 0) {
795 // It is a notification PPI.
797 Status
= InternalPeiNotifyPpi (PeiServices
, (CONST EFI_PEI_NOTIFY_DESCRIPTOR
*) PpiList
, TRUE
);
798 ASSERT_EFI_ERROR (Status
);
801 // It is a normal PPI.
803 Status
= InternalPeiInstallPpi (PeiServices
, PpiList
, TRUE
);
804 ASSERT_EFI_ERROR (Status
);
807 if ((PpiList
->Flags
& EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
) == EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
) {
809 // Continue until the end of the PPI List.
818 // If the EFI_SEC_HOB_DATA_PPI is in the list of PPIs passed to the PEI entry point,
819 // the PEI Foundation will call the GetHobs() member function and install all HOBs
820 // returned into the HOB list. It does this after installing all PPIs passed from SEC
821 // into the PPI database and before dispatching any PEIMs.
823 Status
= PeiLocatePpi (PeiServices
, &gEfiSecHobDataPpiGuid
, 0, NULL
, (VOID
**) &SecHobDataPpi
);
824 if (!EFI_ERROR (Status
)) {
825 Status
= SecHobDataPpi
->GetHobs (SecHobDataPpi
, &SecHobList
);
826 if (!EFI_ERROR (Status
)) {
827 Status
= PeiInstallSecHobData (PeiServices
, SecHobList
);
828 ASSERT_EFI_ERROR (Status
);