TianoCore EDK2 master
Loading...
Searching...
No Matches
Ppi.c
Go to the documentation of this file.
1
9#include "PeiMain.h"
10
22VOID
24 IN OUT VOID **Pointer,
25 IN UINTN TempBottom,
26 IN UINTN TempTop,
27 IN UINTN Offset,
28 IN BOOLEAN OffsetPositive
29 )
30{
31 if (((UINTN)*Pointer < TempTop) &&
32 ((UINTN)*Pointer >= TempBottom))
33 {
34 if (OffsetPositive) {
35 *Pointer = (VOID *)((UINTN)*Pointer + Offset);
36 } else {
37 *Pointer = (VOID *)((UINTN)*Pointer - Offset);
38 }
39 }
40}
41
52VOID
54 IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
55 IN PEI_CORE_INSTANCE *PrivateData,
56 IN OUT VOID **Pointer
57 )
58{
59 UINT8 IndexHole;
60
61 if (PrivateData->MemoryPages.Size != 0) {
62 //
63 // Convert PPI pointer in old memory pages
64 // It needs to be done before Convert PPI pointer in old Heap
65 //
67 Pointer,
68 (UINTN)PrivateData->MemoryPages.Base,
69 (UINTN)PrivateData->MemoryPages.Base + PrivateData->MemoryPages.Size,
70 PrivateData->MemoryPages.Offset,
71 PrivateData->MemoryPages.OffsetPositive
72 );
73 }
74
75 //
76 // Convert PPI pointer in old Heap
77 //
79 Pointer,
80 (UINTN)SecCoreData->PeiTemporaryRamBase,
81 (UINTN)SecCoreData->PeiTemporaryRamBase + SecCoreData->PeiTemporaryRamSize,
82 PrivateData->HeapOffset,
83 PrivateData->HeapOffsetPositive
84 );
85
86 //
87 // Convert PPI pointer in old Stack
88 //
90 Pointer,
91 (UINTN)SecCoreData->StackBase,
92 (UINTN)SecCoreData->StackBase + SecCoreData->StackSize,
93 PrivateData->StackOffset,
94 PrivateData->StackOffsetPositive
95 );
96
97 //
98 // Convert PPI pointer in old TempRam Hole
99 //
100 for (IndexHole = 0; IndexHole < HOLE_MAX_NUMBER; IndexHole++) {
101 if (PrivateData->HoleData[IndexHole].Size == 0) {
102 continue;
103 }
104
106 Pointer,
107 (UINTN)PrivateData->HoleData[IndexHole].Base,
108 (UINTN)PrivateData->HoleData[IndexHole].Base + PrivateData->HoleData[IndexHole].Size,
109 PrivateData->HoleData[IndexHole].Offset,
110 PrivateData->HoleData[IndexHole].OffsetPositive
111 );
112 }
113}
114
125VOID
127 IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
128 IN PEI_CORE_INSTANCE *PrivateData,
129 IN PEI_PPI_LIST_POINTERS *PpiPointer
130 )
131{
132 //
133 // 1. Convert the pointer to the PPI descriptor from the old TempRam
134 // to the relocated physical memory.
135 // It (for the pointer to the PPI descriptor) needs to be done before 2 (for
136 // the pointer to the GUID) and 3 (for the pointer to the PPI interface structure).
137 //
138 ConvertPointerInRanges (SecCoreData, PrivateData, &PpiPointer->Raw);
139 //
140 // 2. Convert the pointer to the GUID in the PPI or NOTIFY descriptor
141 // from the old TempRam to the relocated physical memory.
142 //
143 ConvertPointerInRanges (SecCoreData, PrivateData, (VOID **)&PpiPointer->Ppi->Guid);
144 //
145 // 3. Convert the pointer to the PPI interface structure in the PPI descriptor
146 // from the old TempRam to the relocated physical memory.
147 //
148 ConvertPointerInRanges (SecCoreData, PrivateData, (VOID **)&PpiPointer->Ppi->Ppi);
149}
150
160VOID
162 IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
163 IN PEI_CORE_INSTANCE *PrivateData
164 )
165{
166 UINTN Index;
167
168 //
169 // Convert normal PPIs.
170 //
171 for (Index = 0; Index < PrivateData->PpiData.PpiList.CurrentCount; Index++) {
173 SecCoreData,
174 PrivateData,
175 &PrivateData->PpiData.PpiList.PpiPtrs[Index]
176 );
177 }
178
179 //
180 // Convert Callback Notification PPIs.
181 //
182 for (Index = 0; Index < PrivateData->PpiData.CallbackNotifyList.CurrentCount; Index++) {
184 SecCoreData,
185 PrivateData,
186 &PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index]
187 );
188 }
189
190 //
191 // Convert Dispatch Notification PPIs.
192 //
193 for (Index = 0; Index < PrivateData->PpiData.DispatchNotifyList.CurrentCount; Index++) {
195 SecCoreData,
196 PrivateData,
197 &PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index]
198 );
199 }
200}
201
212VOID
214 IN PEI_CORE_INSTANCE *PrivateData,
215 IN UINTN OrgFvHandle,
216 IN UINTN FvHandle,
217 IN UINTN FvSize
218 )
219{
220 UINTN Index;
221 UINTN Offset;
222 BOOLEAN OffsetPositive;
224 UINT8 GuidIndex;
225 EFI_GUID *Guid;
226 EFI_GUID *GuidCheckList[2];
227
228 GuidCheckList[0] = &gEfiPeiFirmwareVolumeInfoPpiGuid;
229 GuidCheckList[1] = &gEfiPeiFirmwareVolumeInfo2PpiGuid;
230
231 if (FvHandle > OrgFvHandle) {
232 OffsetPositive = TRUE;
233 Offset = FvHandle - OrgFvHandle;
234 } else {
235 OffsetPositive = FALSE;
236 Offset = OrgFvHandle - FvHandle;
237 }
238
239 DEBUG ((DEBUG_VERBOSE, "Converting PPI pointers in FV.\n"));
240 DEBUG ((
241 DEBUG_VERBOSE,
242 " OrgFvHandle at 0x%08x. FvHandle at 0x%08x. FvSize = 0x%x\n",
243 (UINTN)OrgFvHandle,
244 (UINTN)FvHandle,
245 FvSize
246 ));
247 DEBUG ((
248 DEBUG_VERBOSE,
249 " OrgFvHandle range: 0x%08x - 0x%08x\n",
250 OrgFvHandle,
251 OrgFvHandle + FvSize
252 ));
253
254 for (Index = 0; Index < PrivateData->PpiData.CallbackNotifyList.CurrentCount; Index++) {
256 (VOID **)&PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index].Raw,
257 OrgFvHandle,
258 OrgFvHandle + FvSize,
259 Offset,
260 OffsetPositive
261 );
263 (VOID **)&PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index].Notify->Guid,
264 OrgFvHandle,
265 OrgFvHandle + FvSize,
266 Offset,
267 OffsetPositive
268 );
270 (VOID **)&PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index].Notify->Notify,
271 OrgFvHandle,
272 OrgFvHandle + FvSize,
273 Offset,
274 OffsetPositive
275 );
276 }
277
278 for (Index = 0; Index < PrivateData->PpiData.DispatchNotifyList.CurrentCount; Index++) {
280 (VOID **)&PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].Raw,
281 OrgFvHandle,
282 OrgFvHandle + FvSize,
283 Offset,
284 OffsetPositive
285 );
287 (VOID **)&PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].Notify->Guid,
288 OrgFvHandle,
289 OrgFvHandle + FvSize,
290 Offset,
291 OffsetPositive
292 );
294 (VOID **)&PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].Notify->Notify,
295 OrgFvHandle,
296 OrgFvHandle + FvSize,
297 Offset,
298 OffsetPositive
299 );
300 }
301
302 for (Index = 0; Index < PrivateData->PpiData.PpiList.CurrentCount; Index++) {
304 (VOID **)&PrivateData->PpiData.PpiList.PpiPtrs[Index].Raw,
305 OrgFvHandle,
306 OrgFvHandle + FvSize,
307 Offset,
308 OffsetPositive
309 );
311 (VOID **)&PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi->Guid,
312 OrgFvHandle,
313 OrgFvHandle + FvSize,
314 Offset,
315 OffsetPositive
316 );
318 (VOID **)&PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi->Ppi,
319 OrgFvHandle,
320 OrgFvHandle + FvSize,
321 Offset,
322 OffsetPositive
323 );
324
325 Guid = PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi->Guid;
326 for (GuidIndex = 0; GuidIndex < ARRAY_SIZE (GuidCheckList); ++GuidIndex) {
327 //
328 // Don't use CompareGuid function here for performance reasons.
329 // Instead we compare the GUID as INT32 at a time and branch
330 // on the first failed comparison.
331 //
332 if ((((INT32 *)Guid)[0] == ((INT32 *)GuidCheckList[GuidIndex])[0]) &&
333 (((INT32 *)Guid)[1] == ((INT32 *)GuidCheckList[GuidIndex])[1]) &&
334 (((INT32 *)Guid)[2] == ((INT32 *)GuidCheckList[GuidIndex])[2]) &&
335 (((INT32 *)Guid)[3] == ((INT32 *)GuidCheckList[GuidIndex])[3]))
336 {
337 FvInfoPpi = PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi->Ppi;
338 DEBUG ((DEBUG_VERBOSE, " FvInfo: %p -> ", FvInfoPpi->FvInfo));
339 if ((UINTN)FvInfoPpi->FvInfo == OrgFvHandle) {
341 (VOID **)&FvInfoPpi->FvInfo,
342 OrgFvHandle,
343 OrgFvHandle + FvSize,
344 Offset,
345 OffsetPositive
346 );
347 DEBUG ((DEBUG_VERBOSE, "%p", FvInfoPpi->FvInfo));
348 }
349
350 DEBUG ((DEBUG_VERBOSE, "\n"));
351 break;
352 }
353 }
354 }
355}
356
364VOID
366 IN PEI_CORE_INSTANCE *PrivateData
367 )
368{
370 UINTN Index;
371
372 if (PrivateData == NULL) {
373 return;
374 }
375
376 for (Index = 0; Index < PrivateData->PpiData.CallbackNotifyList.CurrentCount; Index++) {
377 DEBUG ((
378 DEBUG_VERBOSE,
379 "CallbackNotify[%2d] {%g} at 0x%x (%a)\n",
380 Index,
381 PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index].Notify->Guid,
382 (UINTN)PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index].Raw,
383 (
384 !(
385 ((EFI_PHYSICAL_ADDRESS)(UINTN)PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index].Raw >= PrivateData->PhysicalMemoryBegin) &&
386 (((EFI_PHYSICAL_ADDRESS)((UINTN)PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index].Raw) + sizeof (EFI_PEI_NOTIFY_DESCRIPTOR)) < PrivateData->FreePhysicalMemoryTop)
387 )
388 ? "CAR" : "Post-Memory"
389 )
390 ));
391 }
392
393 for (Index = 0; Index < PrivateData->PpiData.DispatchNotifyList.CurrentCount; Index++) {
394 DEBUG ((
395 DEBUG_VERBOSE,
396 "DispatchNotify[%2d] {%g} at 0x%x (%a)\n",
397 Index,
398 PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].Notify->Guid,
399 (UINTN)PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].Raw,
400 (
401 !(
402 ((EFI_PHYSICAL_ADDRESS)(UINTN)PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].Raw >= PrivateData->PhysicalMemoryBegin) &&
403 (((EFI_PHYSICAL_ADDRESS)((UINTN)PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].Raw) + sizeof (EFI_PEI_NOTIFY_DESCRIPTOR)) < PrivateData->FreePhysicalMemoryTop)
404 )
405 ? "CAR" : "Post-Memory"
406 )
407 ));
408 }
409
410 for (Index = 0; Index < PrivateData->PpiData.PpiList.CurrentCount; Index++) {
411 DEBUG ((
412 DEBUG_VERBOSE,
413 "PPI[%2d] {%g} at 0x%x (%a)\n",
414 Index,
415 PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi->Guid,
416 (UINTN)PrivateData->PpiData.PpiList.PpiPtrs[Index].Raw,
417 (
418 !(
419 ((EFI_PHYSICAL_ADDRESS)(UINTN)PrivateData->PpiData.PpiList.PpiPtrs[Index].Raw >= PrivateData->PhysicalMemoryBegin) &&
420 (((EFI_PHYSICAL_ADDRESS)((UINTN)PrivateData->PpiData.PpiList.PpiPtrs[Index].Raw) + sizeof (EFI_PEI_PPI_DESCRIPTOR)) < PrivateData->FreePhysicalMemoryTop)
421 )
422 ? "CAR" : "Post-Memory"
423 )
424 ));
425 }
426
428}
429
450 IN CONST EFI_PEI_SERVICES **PeiServices,
452 IN BOOLEAN Single
453 )
454{
455 PEI_CORE_INSTANCE *PrivateData;
456 PEI_PPI_LIST *PpiListPointer;
457 UINTN Index;
458 UINTN LastCount;
459 VOID *TempPtr;
460
461 if (PpiList == NULL) {
462 return EFI_INVALID_PARAMETER;
463 }
464
465 PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
466
467 PpiListPointer = &PrivateData->PpiData.PpiList;
468 Index = PpiListPointer->CurrentCount;
469 LastCount = Index;
470
471 //
472 // This is loop installs all PPI descriptors in the PpiList. It is terminated
473 // by the EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST being set in the last
474 // EFI_PEI_PPI_DESCRIPTOR in the list.
475 //
476
477 for ( ; ;) {
478 //
479 // Check if it is a valid PPI.
480 // If not, rollback list to exclude all in this list.
481 // Try to indicate which item failed.
482 //
483 if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_PPI) == 0) {
484 PpiListPointer->CurrentCount = LastCount;
485 DEBUG ((DEBUG_ERROR, "ERROR -> InstallPpi: %g %p\n", PpiList->Guid, PpiList->Ppi));
486 return EFI_INVALID_PARAMETER;
487 }
488
489 if (Index >= PpiListPointer->MaxCount) {
490 //
491 // Run out of room, grow the buffer.
492 //
493 TempPtr = AllocateZeroPool (
494 sizeof (PEI_PPI_LIST_POINTERS) * (PpiListPointer->MaxCount + PPI_GROWTH_STEP)
495 );
496 if (TempPtr == NULL) {
497 ASSERT (TempPtr != NULL);
498 return EFI_OUT_OF_RESOURCES;
499 }
500
501 CopyMem (
502 TempPtr,
503 PpiListPointer->PpiPtrs,
504 sizeof (PEI_PPI_LIST_POINTERS) * PpiListPointer->MaxCount
505 );
506 PpiListPointer->PpiPtrs = TempPtr;
507 PpiListPointer->MaxCount = PpiListPointer->MaxCount + PPI_GROWTH_STEP;
508 }
509
510 DEBUG ((DEBUG_INFO, "Install PPI: %g\n", PpiList->Guid));
511 PpiListPointer->PpiPtrs[Index].Ppi = (EFI_PEI_PPI_DESCRIPTOR *)PpiList;
512 Index++;
513 PpiListPointer->CurrentCount++;
514
515 if (Single) {
516 //
517 // Only single entry in the PpiList.
518 //
519 break;
520 } else if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) ==
521 EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST)
522 {
523 //
524 // Continue until the end of the PPI List.
525 //
526 break;
527 }
528
529 //
530 // Go to the next descriptor.
531 //
532 PpiList++;
533 }
534
535 //
536 // Process any callback level notifies for newly installed PPIs.
537 //
539 PrivateData,
540 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
541 LastCount,
542 PpiListPointer->CurrentCount,
543 0,
544 PrivateData->PpiData.CallbackNotifyList.CurrentCount
545 );
546
547 return EFI_SUCCESS;
548}
549
566EFIAPI
568 IN CONST EFI_PEI_SERVICES **PeiServices,
570 )
571{
572 return InternalPeiInstallPpi (PeiServices, PpiList, FALSE);
573}
574
593EFIAPI
595 IN CONST EFI_PEI_SERVICES **PeiServices,
598 )
599{
600 PEI_CORE_INSTANCE *PrivateData;
601 UINTN Index;
602
603 if ((OldPpi == NULL) || (NewPpi == NULL)) {
604 return EFI_INVALID_PARAMETER;
605 }
606
607 if ((NewPpi->Flags & EFI_PEI_PPI_DESCRIPTOR_PPI) == 0) {
608 return EFI_INVALID_PARAMETER;
609 }
610
611 PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
612
613 //
614 // Find the old PPI instance in the database. If we can not find it,
615 // return the EFI_NOT_FOUND error.
616 //
617 for (Index = 0; Index < PrivateData->PpiData.PpiList.CurrentCount; Index++) {
618 if (OldPpi == PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi) {
619 break;
620 }
621 }
622
623 if (Index == PrivateData->PpiData.PpiList.CurrentCount) {
624 return EFI_NOT_FOUND;
625 }
626
627 //
628 // Replace the old PPI with the new one.
629 //
630 DEBUG ((DEBUG_INFO, "Reinstall PPI: %g\n", NewPpi->Guid));
631 PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi = (EFI_PEI_PPI_DESCRIPTOR *)NewPpi;
632
633 //
634 // Process any callback level notifies for the newly installed PPI.
635 //
637 PrivateData,
638 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
639 Index,
640 Index+1,
641 0,
642 PrivateData->PpiData.CallbackNotifyList.CurrentCount
643 );
644
645 return EFI_SUCCESS;
646}
647
665EFIAPI
667 IN CONST EFI_PEI_SERVICES **PeiServices,
668 IN CONST EFI_GUID *Guid,
669 IN UINTN Instance,
670 IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor,
671 IN OUT VOID **Ppi
672 )
673{
674 PEI_CORE_INSTANCE *PrivateData;
675 UINTN Index;
676 EFI_GUID *CheckGuid;
677 EFI_PEI_PPI_DESCRIPTOR *TempPtr;
678
679 PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
680
681 //
682 // Search the data base for the matching instance of the GUIDed PPI.
683 //
684 for (Index = 0; Index < PrivateData->PpiData.PpiList.CurrentCount; Index++) {
685 TempPtr = PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi;
686 CheckGuid = TempPtr->Guid;
687
688 //
689 // Don't use CompareGuid function here for performance reasons.
690 // Instead we compare the GUID as INT32 at a time and branch
691 // on the first failed comparison.
692 //
693 if ((((INT32 *)Guid)[0] == ((INT32 *)CheckGuid)[0]) &&
694 (((INT32 *)Guid)[1] == ((INT32 *)CheckGuid)[1]) &&
695 (((INT32 *)Guid)[2] == ((INT32 *)CheckGuid)[2]) &&
696 (((INT32 *)Guid)[3] == ((INT32 *)CheckGuid)[3]))
697 {
698 if (Instance == 0) {
699 if (PpiDescriptor != NULL) {
700 *PpiDescriptor = TempPtr;
701 }
702
703 if (Ppi != NULL) {
704 *Ppi = TempPtr->Ppi;
705 }
706
707 return EFI_SUCCESS;
708 }
709
710 Instance--;
711 }
712 }
713
714 return EFI_NOT_FOUND;
715}
716
736 IN CONST EFI_PEI_SERVICES **PeiServices,
738 IN BOOLEAN Single
739 )
740{
741 PEI_CORE_INSTANCE *PrivateData;
742 PEI_CALLBACK_NOTIFY_LIST *CallbackNotifyListPointer;
743 UINTN CallbackNotifyIndex;
744 UINTN LastCallbackNotifyCount;
745 PEI_DISPATCH_NOTIFY_LIST *DispatchNotifyListPointer;
746 UINTN DispatchNotifyIndex;
747 UINTN LastDispatchNotifyCount;
748 VOID *TempPtr;
749
750 if (NotifyList == NULL) {
751 return EFI_INVALID_PARAMETER;
752 }
753
754 PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
755
756 CallbackNotifyListPointer = &PrivateData->PpiData.CallbackNotifyList;
757 CallbackNotifyIndex = CallbackNotifyListPointer->CurrentCount;
758 LastCallbackNotifyCount = CallbackNotifyIndex;
759
760 DispatchNotifyListPointer = &PrivateData->PpiData.DispatchNotifyList;
761 DispatchNotifyIndex = DispatchNotifyListPointer->CurrentCount;
762 LastDispatchNotifyCount = DispatchNotifyIndex;
763
764 //
765 // This is loop installs all Notify descriptors in the NotifyList. It is
766 // terminated by the EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST being set in the last
767 // EFI_PEI_NOTIFY_DESCRIPTOR in the list.
768 //
769
770 for ( ; ;) {
771 //
772 // If some of the PPI data is invalid restore original Notify PPI database value
773 //
774 if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_TYPES) == 0) {
775 CallbackNotifyListPointer->CurrentCount = LastCallbackNotifyCount;
776 DispatchNotifyListPointer->CurrentCount = LastDispatchNotifyCount;
777 DEBUG ((DEBUG_ERROR, "ERROR -> NotifyPpi: %g %p\n", NotifyList->Guid, NotifyList->Notify));
778 return EFI_INVALID_PARAMETER;
779 }
780
781 if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK) != 0) {
782 if (CallbackNotifyIndex >= CallbackNotifyListPointer->MaxCount) {
783 //
784 // Run out of room, grow the buffer.
785 //
786 TempPtr = AllocateZeroPool (
787 sizeof (PEI_PPI_LIST_POINTERS) * (CallbackNotifyListPointer->MaxCount + CALLBACK_NOTIFY_GROWTH_STEP)
788 );
789 if (TempPtr == NULL) {
790 ASSERT (TempPtr != NULL);
791 return EFI_OUT_OF_RESOURCES;
792 }
793
794 CopyMem (
795 TempPtr,
796 CallbackNotifyListPointer->NotifyPtrs,
797 sizeof (PEI_PPI_LIST_POINTERS) * CallbackNotifyListPointer->MaxCount
798 );
799 CallbackNotifyListPointer->NotifyPtrs = TempPtr;
800 CallbackNotifyListPointer->MaxCount = CallbackNotifyListPointer->MaxCount + CALLBACK_NOTIFY_GROWTH_STEP;
801 }
802
803 CallbackNotifyListPointer->NotifyPtrs[CallbackNotifyIndex].Notify = (EFI_PEI_NOTIFY_DESCRIPTOR *)NotifyList;
804 CallbackNotifyIndex++;
805 CallbackNotifyListPointer->CurrentCount++;
806 } else {
807 if (DispatchNotifyIndex >= DispatchNotifyListPointer->MaxCount) {
808 //
809 // Run out of room, grow the buffer.
810 //
811 TempPtr = AllocateZeroPool (
812 sizeof (PEI_PPI_LIST_POINTERS) * (DispatchNotifyListPointer->MaxCount + DISPATCH_NOTIFY_GROWTH_STEP)
813 );
814 if (TempPtr == NULL) {
815 ASSERT (TempPtr != NULL);
816 return EFI_OUT_OF_RESOURCES;
817 }
818
819 CopyMem (
820 TempPtr,
821 DispatchNotifyListPointer->NotifyPtrs,
822 sizeof (PEI_PPI_LIST_POINTERS) * DispatchNotifyListPointer->MaxCount
823 );
824 DispatchNotifyListPointer->NotifyPtrs = TempPtr;
825 DispatchNotifyListPointer->MaxCount = DispatchNotifyListPointer->MaxCount + DISPATCH_NOTIFY_GROWTH_STEP;
826 }
827
828 DispatchNotifyListPointer->NotifyPtrs[DispatchNotifyIndex].Notify = (EFI_PEI_NOTIFY_DESCRIPTOR *)NotifyList;
829 DispatchNotifyIndex++;
830 DispatchNotifyListPointer->CurrentCount++;
831 }
832
833 DEBUG ((DEBUG_INFO, "Register PPI Notify: %g\n", NotifyList->Guid));
834
835 if (Single) {
836 //
837 // Only single entry in the NotifyList.
838 //
839 break;
840 } else if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) ==
841 EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST)
842 {
843 //
844 // Continue until the end of the Notify List.
845 //
846 break;
847 }
848
849 //
850 // Go to the next descriptor.
851 //
852 NotifyList++;
853 }
854
855 //
856 // Process any callback level notifies for all previously installed PPIs.
857 //
859 PrivateData,
860 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
861 0,
862 PrivateData->PpiData.PpiList.CurrentCount,
863 LastCallbackNotifyCount,
864 CallbackNotifyListPointer->CurrentCount
865 );
866
867 return EFI_SUCCESS;
868}
869
885EFIAPI
887 IN CONST EFI_PEI_SERVICES **PeiServices,
889 )
890{
891 return InternalPeiNotifyPpi (PeiServices, NotifyList, FALSE);
892}
893
901VOID
903 IN PEI_CORE_INSTANCE *PrivateData
904 )
905{
906 UINTN TempValue;
907
908 while (TRUE) {
909 //
910 // Check if the PEIM that was just dispatched resulted in any
911 // Notifies getting installed. If so, go process any dispatch
912 // level Notifies that match the previously installed PPIs.
913 // Use "while" instead of "if" since ProcessNotify can modify
914 // DispatchNotifyList.CurrentCount (with NotifyPpi) so we have
915 // to iterate until the same.
916 //
917 while (PrivateData->PpiData.DispatchNotifyList.LastDispatchedCount != PrivateData->PpiData.DispatchNotifyList.CurrentCount) {
918 TempValue = PrivateData->PpiData.DispatchNotifyList.CurrentCount;
920 PrivateData,
921 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH,
922 0,
923 PrivateData->PpiData.PpiList.LastDispatchedCount,
924 PrivateData->PpiData.DispatchNotifyList.LastDispatchedCount,
925 PrivateData->PpiData.DispatchNotifyList.CurrentCount
926 );
927 PrivateData->PpiData.DispatchNotifyList.LastDispatchedCount = TempValue;
928 }
929
930 //
931 // Check if the PEIM that was just dispatched resulted in any
932 // PPIs getting installed. If so, go process any dispatch
933 // level Notifies that match the installed PPIs.
934 // Use "while" instead of "if" since ProcessNotify can modify
935 // PpiList.CurrentCount (with InstallPpi) so we have to iterate
936 // until the same.
937 //
938 while (PrivateData->PpiData.PpiList.LastDispatchedCount != PrivateData->PpiData.PpiList.CurrentCount) {
939 TempValue = PrivateData->PpiData.PpiList.CurrentCount;
941 PrivateData,
942 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH,
943 PrivateData->PpiData.PpiList.LastDispatchedCount,
944 PrivateData->PpiData.PpiList.CurrentCount,
945 0,
946 PrivateData->PpiData.DispatchNotifyList.LastDispatchedCount
947 );
948 PrivateData->PpiData.PpiList.LastDispatchedCount = TempValue;
949 }
950
951 if (PrivateData->PpiData.DispatchNotifyList.LastDispatchedCount == PrivateData->PpiData.DispatchNotifyList.CurrentCount) {
952 break;
953 }
954 }
955
956 return;
957}
958
971VOID
973 IN PEI_CORE_INSTANCE *PrivateData,
974 IN UINTN NotifyType,
975 IN INTN InstallStartIndex,
976 IN INTN InstallStopIndex,
977 IN INTN NotifyStartIndex,
978 IN INTN NotifyStopIndex
979 )
980{
981 INTN Index1;
982 INTN Index2;
983 EFI_GUID *SearchGuid;
984 EFI_GUID *CheckGuid;
985 EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor;
986
987 for (Index1 = NotifyStartIndex; Index1 < NotifyStopIndex; Index1++) {
988 if (NotifyType == EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK) {
989 NotifyDescriptor = PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index1].Notify;
990 } else {
991 NotifyDescriptor = PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index1].Notify;
992 }
993
994 CheckGuid = NotifyDescriptor->Guid;
995
996 for (Index2 = InstallStartIndex; Index2 < InstallStopIndex; Index2++) {
997 SearchGuid = PrivateData->PpiData.PpiList.PpiPtrs[Index2].Ppi->Guid;
998 //
999 // Don't use CompareGuid function here for performance reasons.
1000 // Instead we compare the GUID as INT32 at a time and branch
1001 // on the first failed comparison.
1002 //
1003 if ((((INT32 *)SearchGuid)[0] == ((INT32 *)CheckGuid)[0]) &&
1004 (((INT32 *)SearchGuid)[1] == ((INT32 *)CheckGuid)[1]) &&
1005 (((INT32 *)SearchGuid)[2] == ((INT32 *)CheckGuid)[2]) &&
1006 (((INT32 *)SearchGuid)[3] == ((INT32 *)CheckGuid)[3]))
1007 {
1008 DEBUG ((
1009 DEBUG_INFO,
1010 "Notify: PPI Guid: %g, Peim notify entry point: %p\n",
1011 SearchGuid,
1012 NotifyDescriptor->Notify
1013 ));
1014 NotifyDescriptor->Notify (
1016 NotifyDescriptor,
1017 (PrivateData->PpiData.PpiList.PpiPtrs[Index2].Ppi)->Ppi
1018 );
1019 }
1020 }
1021 }
1022}
1023
1032VOID
1034 IN CONST EFI_PEI_SERVICES **PeiServices,
1036 )
1037{
1038 EFI_STATUS Status;
1039 EFI_SEC_HOB_DATA_PPI *SecHobDataPpi;
1040 EFI_HOB_GENERIC_HEADER *SecHobList;
1041
1042 for ( ; ;) {
1043 if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_TYPES) != 0) {
1044 //
1045 // It is a notification PPI.
1046 //
1047 Status = InternalPeiNotifyPpi (PeiServices, (CONST EFI_PEI_NOTIFY_DESCRIPTOR *)PpiList, TRUE);
1048 ASSERT_EFI_ERROR (Status);
1049 } else {
1050 //
1051 // It is a normal PPI.
1052 //
1053 Status = InternalPeiInstallPpi (PeiServices, PpiList, TRUE);
1054 ASSERT_EFI_ERROR (Status);
1055 }
1056
1057 if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) == EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) {
1058 //
1059 // Continue until the end of the PPI List.
1060 //
1061 break;
1062 }
1063
1064 PpiList++;
1065 }
1066
1067 //
1068 // If the EFI_SEC_HOB_DATA_PPI is in the list of PPIs passed to the PEI entry point,
1069 // the PEI Foundation will call the GetHobs() member function and install all HOBs
1070 // returned into the HOB list. It does this after installing all PPIs passed from SEC
1071 // into the PPI database and before dispatching any PEIMs.
1072 //
1073 Status = PeiLocatePpi (PeiServices, &gEfiSecHobDataPpiGuid, 0, NULL, (VOID **)&SecHobDataPpi);
1074 if (!EFI_ERROR (Status)) {
1075 Status = SecHobDataPpi->GetHobs (SecHobDataPpi, &SecHobList);
1076 if (!EFI_ERROR (Status)) {
1077 Status = PeiInstallSecHobData (PeiServices, SecHobList);
1078 ASSERT_EFI_ERROR (Status);
1079 }
1080 }
1081}
1082
1091VOID
1093 IN PEI_CORE_INSTANCE *PrivateData,
1094 IN PEI_CORE_FV_HANDLE *CoreFvHandle
1095 )
1096{
1098 EFI_PHYSICAL_ADDRESS OrgImageBase;
1099 EFI_PHYSICAL_ADDRESS MigratedImageBase;
1100 UINTN PeiCoreModuleSize;
1101 EFI_PEI_FILE_HANDLE PeiCoreFileHandle;
1102 VOID *PeiCoreImageBase;
1103 VOID *PeiCoreEntryPoint;
1104 EFI_STATUS Status;
1105
1106 PeiCoreFileHandle = NULL;
1107
1108 //
1109 // Find the PEI Core in the BFV in temporary memory.
1110 //
1111 Status = CoreFvHandle->FvPpi->FindFileByType (
1112 CoreFvHandle->FvPpi,
1113 EFI_FV_FILETYPE_PEI_CORE,
1114 CoreFvHandle->FvHandle,
1115 &PeiCoreFileHandle
1116 );
1117 ASSERT_EFI_ERROR (Status);
1118
1119 if (!EFI_ERROR (Status)) {
1120 Status = CoreFvHandle->FvPpi->GetFileInfo (CoreFvHandle->FvPpi, PeiCoreFileHandle, &FileInfo);
1121 ASSERT_EFI_ERROR (Status);
1122
1123 Status = PeiGetPe32Data (PeiCoreFileHandle, &PeiCoreImageBase);
1124 ASSERT_EFI_ERROR (Status);
1125
1126 //
1127 // Find PEI Core EntryPoint in the BFV in temporary memory.
1128 //
1129 Status = PeCoffLoaderGetEntryPoint ((VOID *)(UINTN)PeiCoreImageBase, &PeiCoreEntryPoint);
1130 ASSERT_EFI_ERROR (Status);
1131
1132 OrgImageBase = (UINTN)PeiCoreImageBase;
1133 MigratedImageBase = (UINTN)_ModuleEntryPoint - ((UINTN)PeiCoreEntryPoint - (UINTN)PeiCoreImageBase);
1134
1135 //
1136 // Size of loaded PEI_CORE in permanent memory.
1137 //
1138 PeiCoreModuleSize = (UINTN)FileInfo.BufferSize - ((UINTN)OrgImageBase - (UINTN)FileInfo.Buffer);
1139
1140 //
1141 // Migrate PEI_CORE PPI pointers from temporary memory to newly
1142 // installed PEI_CORE in permanent memory.
1143 //
1144 ConvertPpiPointersFv (PrivateData, (UINTN)OrgImageBase, (UINTN)MigratedImageBase, PeiCoreModuleSize);
1145 }
1146}
UINT64 UINTN
INT64 INTN
CONST EFI_PEI_SERVICES **EFIAPI GetPeiServicesTablePointer(VOID)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
EFI_STATUS PeiGetPe32Data(IN EFI_PEI_FILE_HANDLE FileHandle, OUT VOID **Pe32Data)
Definition: Image.c:541
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
EFI_STATUS PeiInstallSecHobData(IN CONST EFI_PEI_SERVICES **PeiServices, IN EFI_HOB_GENERIC_HEADER *SecHobList)
Definition: Hob.c:128
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define VOID
Definition: Base.h:269
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define ARRAY_SIZE(Array)
Definition: Base.h:1393
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:463
#define DEBUG_CODE_BEGIN()
Definition: DebugLib.h:565
#define DEBUG(Expression)
Definition: DebugLib.h:435
#define DEBUG_CODE_END()
Definition: DebugLib.h:579
#define PPI_GROWTH_STEP
Definition: PeiMain.h:73
#define PEI_CORE_INSTANCE_FROM_PS_THIS(a)
Definition: PeiMain.h:343
VOID * EFI_PEI_FILE_HANDLE
Definition: PiPeiCis.h:26
EFI_STATUS EFIAPI PeiLocatePpi(IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_GUID *Guid, IN UINTN Instance, IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor, IN OUT VOID **Ppi)
Definition: Ppi.c:666
VOID ConvertPeiCorePpiPointers(IN PEI_CORE_INSTANCE *PrivateData, IN PEI_CORE_FV_HANDLE *CoreFvHandle)
Definition: Ppi.c:1092
EFI_STATUS InternalPeiNotifyPpi(IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_NOTIFY_DESCRIPTOR *NotifyList, IN BOOLEAN Single)
Definition: Ppi.c:735
VOID ProcessNotify(IN PEI_CORE_INSTANCE *PrivateData, IN UINTN NotifyType, IN INTN InstallStartIndex, IN INTN InstallStopIndex, IN INTN NotifyStartIndex, IN INTN NotifyStopIndex)
Definition: Ppi.c:972
VOID ConvertSinglePpiPointer(IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData, IN PEI_CORE_INSTANCE *PrivateData, IN PEI_PPI_LIST_POINTERS *PpiPointer)
Definition: Ppi.c:126
EFI_STATUS EFIAPI PeiInstallPpi(IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList)
Definition: Ppi.c:567
VOID ProcessDispatchNotifyList(IN PEI_CORE_INSTANCE *PrivateData)
Definition: Ppi.c:902
EFI_STATUS EFIAPI PeiReInstallPpi(IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_PPI_DESCRIPTOR *OldPpi, IN CONST EFI_PEI_PPI_DESCRIPTOR *NewPpi)
Definition: Ppi.c:594
VOID DumpPpiList(IN PEI_CORE_INSTANCE *PrivateData)
Definition: Ppi.c:365
VOID ConvertPpiPointersFv(IN PEI_CORE_INSTANCE *PrivateData, IN UINTN OrgFvHandle, IN UINTN FvHandle, IN UINTN FvSize)
Definition: Ppi.c:213
VOID ConvertPpiPointers(IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData, IN PEI_CORE_INSTANCE *PrivateData)
Definition: Ppi.c:161
VOID ProcessPpiListFromSec(IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList)
Definition: Ppi.c:1033
EFI_STATUS EFIAPI PeiNotifyPpi(IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_NOTIFY_DESCRIPTOR *NotifyList)
Definition: Ppi.c:886
EFI_STATUS InternalPeiInstallPpi(IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList, IN BOOLEAN Single)
Definition: Ppi.c:449
VOID ConvertPointer(IN OUT VOID **Pointer, IN UINTN TempBottom, IN UINTN TempTop, IN UINTN Offset, IN BOOLEAN OffsetPositive)
Definition: Ppi.c:23
VOID ConvertPointerInRanges(IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData, IN PEI_CORE_INSTANCE *PrivateData, IN OUT VOID **Pointer)
Definition: Ppi.c:53
EFI_FILE_INFO * FileInfo(IN EFI_FILE_HANDLE FHand)
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_PEIM_NOTIFY_ENTRY_POINT Notify
Definition: PiPeiCis.h:122
Definition: Base.h:213
PEI_PPI_LIST_POINTERS * NotifyPtrs
Definition: PeiMain.h:93
PEI_PPI_LIST_POINTERS * NotifyPtrs
Definition: PeiMain.h:103
PEI_CALLBACK_NOTIFY_LIST CallbackNotifyList
Definition: PeiMain.h:118
PEI_DISPATCH_NOTIFY_LIST DispatchNotifyList
Definition: PeiMain.h:122
PEI_PPI_LIST PpiList
Definition: PeiMain.h:114
PEI_PPI_LIST_POINTERS * PpiPtrs
Definition: PeiMain.h:84