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 UINT8 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 UINT8 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 ASSERT (TempPtr != NULL);
497 CopyMem (
498 TempPtr,
499 PpiListPointer->PpiPtrs,
500 sizeof (PEI_PPI_LIST_POINTERS) * PpiListPointer->MaxCount
501 );
502 PpiListPointer->PpiPtrs = TempPtr;
503 PpiListPointer->MaxCount = PpiListPointer->MaxCount + PPI_GROWTH_STEP;
504 }
505
506 DEBUG ((DEBUG_INFO, "Install PPI: %g\n", PpiList->Guid));
507 PpiListPointer->PpiPtrs[Index].Ppi = (EFI_PEI_PPI_DESCRIPTOR *)PpiList;
508 Index++;
509 PpiListPointer->CurrentCount++;
510
511 if (Single) {
512 //
513 // Only single entry in the PpiList.
514 //
515 break;
516 } else if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) ==
517 EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST)
518 {
519 //
520 // Continue until the end of the PPI List.
521 //
522 break;
523 }
524
525 //
526 // Go to the next descriptor.
527 //
528 PpiList++;
529 }
530
531 //
532 // Process any callback level notifies for newly installed PPIs.
533 //
535 PrivateData,
536 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
537 LastCount,
538 PpiListPointer->CurrentCount,
539 0,
540 PrivateData->PpiData.CallbackNotifyList.CurrentCount
541 );
542
543 return EFI_SUCCESS;
544}
545
562EFIAPI
564 IN CONST EFI_PEI_SERVICES **PeiServices,
566 )
567{
568 return InternalPeiInstallPpi (PeiServices, PpiList, FALSE);
569}
570
589EFIAPI
591 IN CONST EFI_PEI_SERVICES **PeiServices,
594 )
595{
596 PEI_CORE_INSTANCE *PrivateData;
597 UINTN Index;
598
599 if ((OldPpi == NULL) || (NewPpi == NULL)) {
600 return EFI_INVALID_PARAMETER;
601 }
602
603 if ((NewPpi->Flags & EFI_PEI_PPI_DESCRIPTOR_PPI) == 0) {
604 return EFI_INVALID_PARAMETER;
605 }
606
607 PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
608
609 //
610 // Find the old PPI instance in the database. If we can not find it,
611 // return the EFI_NOT_FOUND error.
612 //
613 for (Index = 0; Index < PrivateData->PpiData.PpiList.CurrentCount; Index++) {
614 if (OldPpi == PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi) {
615 break;
616 }
617 }
618
619 if (Index == PrivateData->PpiData.PpiList.CurrentCount) {
620 return EFI_NOT_FOUND;
621 }
622
623 //
624 // Replace the old PPI with the new one.
625 //
626 DEBUG ((DEBUG_INFO, "Reinstall PPI: %g\n", NewPpi->Guid));
627 PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi = (EFI_PEI_PPI_DESCRIPTOR *)NewPpi;
628
629 //
630 // Process any callback level notifies for the newly installed PPI.
631 //
633 PrivateData,
634 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
635 Index,
636 Index+1,
637 0,
638 PrivateData->PpiData.CallbackNotifyList.CurrentCount
639 );
640
641 return EFI_SUCCESS;
642}
643
661EFIAPI
663 IN CONST EFI_PEI_SERVICES **PeiServices,
664 IN CONST EFI_GUID *Guid,
665 IN UINTN Instance,
666 IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor,
667 IN OUT VOID **Ppi
668 )
669{
670 PEI_CORE_INSTANCE *PrivateData;
671 UINTN Index;
672 EFI_GUID *CheckGuid;
673 EFI_PEI_PPI_DESCRIPTOR *TempPtr;
674
675 PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
676
677 //
678 // Search the data base for the matching instance of the GUIDed PPI.
679 //
680 for (Index = 0; Index < PrivateData->PpiData.PpiList.CurrentCount; Index++) {
681 TempPtr = PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi;
682 CheckGuid = TempPtr->Guid;
683
684 //
685 // Don't use CompareGuid function here for performance reasons.
686 // Instead we compare the GUID as INT32 at a time and branch
687 // on the first failed comparison.
688 //
689 if ((((INT32 *)Guid)[0] == ((INT32 *)CheckGuid)[0]) &&
690 (((INT32 *)Guid)[1] == ((INT32 *)CheckGuid)[1]) &&
691 (((INT32 *)Guid)[2] == ((INT32 *)CheckGuid)[2]) &&
692 (((INT32 *)Guid)[3] == ((INT32 *)CheckGuid)[3]))
693 {
694 if (Instance == 0) {
695 if (PpiDescriptor != NULL) {
696 *PpiDescriptor = TempPtr;
697 }
698
699 if (Ppi != NULL) {
700 *Ppi = TempPtr->Ppi;
701 }
702
703 return EFI_SUCCESS;
704 }
705
706 Instance--;
707 }
708 }
709
710 return EFI_NOT_FOUND;
711}
712
732 IN CONST EFI_PEI_SERVICES **PeiServices,
734 IN BOOLEAN Single
735 )
736{
737 PEI_CORE_INSTANCE *PrivateData;
738 PEI_CALLBACK_NOTIFY_LIST *CallbackNotifyListPointer;
739 UINTN CallbackNotifyIndex;
740 UINTN LastCallbackNotifyCount;
741 PEI_DISPATCH_NOTIFY_LIST *DispatchNotifyListPointer;
742 UINTN DispatchNotifyIndex;
743 UINTN LastDispatchNotifyCount;
744 VOID *TempPtr;
745
746 if (NotifyList == NULL) {
747 return EFI_INVALID_PARAMETER;
748 }
749
750 PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
751
752 CallbackNotifyListPointer = &PrivateData->PpiData.CallbackNotifyList;
753 CallbackNotifyIndex = CallbackNotifyListPointer->CurrentCount;
754 LastCallbackNotifyCount = CallbackNotifyIndex;
755
756 DispatchNotifyListPointer = &PrivateData->PpiData.DispatchNotifyList;
757 DispatchNotifyIndex = DispatchNotifyListPointer->CurrentCount;
758 LastDispatchNotifyCount = DispatchNotifyIndex;
759
760 //
761 // This is loop installs all Notify descriptors in the NotifyList. It is
762 // terminated by the EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST being set in the last
763 // EFI_PEI_NOTIFY_DESCRIPTOR in the list.
764 //
765
766 for ( ; ;) {
767 //
768 // If some of the PPI data is invalid restore original Notify PPI database value
769 //
770 if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_TYPES) == 0) {
771 CallbackNotifyListPointer->CurrentCount = LastCallbackNotifyCount;
772 DispatchNotifyListPointer->CurrentCount = LastDispatchNotifyCount;
773 DEBUG ((DEBUG_ERROR, "ERROR -> NotifyPpi: %g %p\n", NotifyList->Guid, NotifyList->Notify));
774 return EFI_INVALID_PARAMETER;
775 }
776
777 if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK) != 0) {
778 if (CallbackNotifyIndex >= CallbackNotifyListPointer->MaxCount) {
779 //
780 // Run out of room, grow the buffer.
781 //
782 TempPtr = AllocateZeroPool (
783 sizeof (PEI_PPI_LIST_POINTERS) * (CallbackNotifyListPointer->MaxCount + CALLBACK_NOTIFY_GROWTH_STEP)
784 );
785 ASSERT (TempPtr != NULL);
786 CopyMem (
787 TempPtr,
788 CallbackNotifyListPointer->NotifyPtrs,
789 sizeof (PEI_PPI_LIST_POINTERS) * CallbackNotifyListPointer->MaxCount
790 );
791 CallbackNotifyListPointer->NotifyPtrs = TempPtr;
792 CallbackNotifyListPointer->MaxCount = CallbackNotifyListPointer->MaxCount + CALLBACK_NOTIFY_GROWTH_STEP;
793 }
794
795 CallbackNotifyListPointer->NotifyPtrs[CallbackNotifyIndex].Notify = (EFI_PEI_NOTIFY_DESCRIPTOR *)NotifyList;
796 CallbackNotifyIndex++;
797 CallbackNotifyListPointer->CurrentCount++;
798 } else {
799 if (DispatchNotifyIndex >= DispatchNotifyListPointer->MaxCount) {
800 //
801 // Run out of room, grow the buffer.
802 //
803 TempPtr = AllocateZeroPool (
804 sizeof (PEI_PPI_LIST_POINTERS) * (DispatchNotifyListPointer->MaxCount + DISPATCH_NOTIFY_GROWTH_STEP)
805 );
806 ASSERT (TempPtr != NULL);
807 CopyMem (
808 TempPtr,
809 DispatchNotifyListPointer->NotifyPtrs,
810 sizeof (PEI_PPI_LIST_POINTERS) * DispatchNotifyListPointer->MaxCount
811 );
812 DispatchNotifyListPointer->NotifyPtrs = TempPtr;
813 DispatchNotifyListPointer->MaxCount = DispatchNotifyListPointer->MaxCount + DISPATCH_NOTIFY_GROWTH_STEP;
814 }
815
816 DispatchNotifyListPointer->NotifyPtrs[DispatchNotifyIndex].Notify = (EFI_PEI_NOTIFY_DESCRIPTOR *)NotifyList;
817 DispatchNotifyIndex++;
818 DispatchNotifyListPointer->CurrentCount++;
819 }
820
821 DEBUG ((DEBUG_INFO, "Register PPI Notify: %g\n", NotifyList->Guid));
822
823 if (Single) {
824 //
825 // Only single entry in the NotifyList.
826 //
827 break;
828 } else if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) ==
829 EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST)
830 {
831 //
832 // Continue until the end of the Notify List.
833 //
834 break;
835 }
836
837 //
838 // Go to the next descriptor.
839 //
840 NotifyList++;
841 }
842
843 //
844 // Process any callback level notifies for all previously installed PPIs.
845 //
847 PrivateData,
848 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
849 0,
850 PrivateData->PpiData.PpiList.CurrentCount,
851 LastCallbackNotifyCount,
852 CallbackNotifyListPointer->CurrentCount
853 );
854
855 return EFI_SUCCESS;
856}
857
873EFIAPI
875 IN CONST EFI_PEI_SERVICES **PeiServices,
877 )
878{
879 return InternalPeiNotifyPpi (PeiServices, NotifyList, FALSE);
880}
881
889VOID
891 IN PEI_CORE_INSTANCE *PrivateData
892 )
893{
894 UINTN TempValue;
895
896 while (TRUE) {
897 //
898 // Check if the PEIM that was just dispatched resulted in any
899 // Notifies getting installed. If so, go process any dispatch
900 // level Notifies that match the previously installed PPIs.
901 // Use "while" instead of "if" since ProcessNotify can modify
902 // DispatchNotifyList.CurrentCount (with NotifyPpi) so we have
903 // to iterate until the same.
904 //
905 while (PrivateData->PpiData.DispatchNotifyList.LastDispatchedCount != PrivateData->PpiData.DispatchNotifyList.CurrentCount) {
906 TempValue = PrivateData->PpiData.DispatchNotifyList.CurrentCount;
908 PrivateData,
909 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH,
910 0,
911 PrivateData->PpiData.PpiList.LastDispatchedCount,
912 PrivateData->PpiData.DispatchNotifyList.LastDispatchedCount,
913 PrivateData->PpiData.DispatchNotifyList.CurrentCount
914 );
915 PrivateData->PpiData.DispatchNotifyList.LastDispatchedCount = TempValue;
916 }
917
918 //
919 // Check if the PEIM that was just dispatched resulted in any
920 // PPIs getting installed. If so, go process any dispatch
921 // level Notifies that match the installed PPIs.
922 // Use "while" instead of "if" since ProcessNotify can modify
923 // PpiList.CurrentCount (with InstallPpi) so we have to iterate
924 // until the same.
925 //
926 while (PrivateData->PpiData.PpiList.LastDispatchedCount != PrivateData->PpiData.PpiList.CurrentCount) {
927 TempValue = PrivateData->PpiData.PpiList.CurrentCount;
929 PrivateData,
930 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH,
931 PrivateData->PpiData.PpiList.LastDispatchedCount,
932 PrivateData->PpiData.PpiList.CurrentCount,
933 0,
934 PrivateData->PpiData.DispatchNotifyList.LastDispatchedCount
935 );
936 PrivateData->PpiData.PpiList.LastDispatchedCount = TempValue;
937 }
938
939 if (PrivateData->PpiData.DispatchNotifyList.LastDispatchedCount == PrivateData->PpiData.DispatchNotifyList.CurrentCount) {
940 break;
941 }
942 }
943
944 return;
945}
946
959VOID
961 IN PEI_CORE_INSTANCE *PrivateData,
962 IN UINTN NotifyType,
963 IN INTN InstallStartIndex,
964 IN INTN InstallStopIndex,
965 IN INTN NotifyStartIndex,
966 IN INTN NotifyStopIndex
967 )
968{
969 INTN Index1;
970 INTN Index2;
971 EFI_GUID *SearchGuid;
972 EFI_GUID *CheckGuid;
973 EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor;
974
975 for (Index1 = NotifyStartIndex; Index1 < NotifyStopIndex; Index1++) {
976 if (NotifyType == EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK) {
977 NotifyDescriptor = PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index1].Notify;
978 } else {
979 NotifyDescriptor = PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index1].Notify;
980 }
981
982 CheckGuid = NotifyDescriptor->Guid;
983
984 for (Index2 = InstallStartIndex; Index2 < InstallStopIndex; Index2++) {
985 SearchGuid = PrivateData->PpiData.PpiList.PpiPtrs[Index2].Ppi->Guid;
986 //
987 // Don't use CompareGuid function here for performance reasons.
988 // Instead we compare the GUID as INT32 at a time and branch
989 // on the first failed comparison.
990 //
991 if ((((INT32 *)SearchGuid)[0] == ((INT32 *)CheckGuid)[0]) &&
992 (((INT32 *)SearchGuid)[1] == ((INT32 *)CheckGuid)[1]) &&
993 (((INT32 *)SearchGuid)[2] == ((INT32 *)CheckGuid)[2]) &&
994 (((INT32 *)SearchGuid)[3] == ((INT32 *)CheckGuid)[3]))
995 {
996 DEBUG ((
997 DEBUG_INFO,
998 "Notify: PPI Guid: %g, Peim notify entry point: %p\n",
999 SearchGuid,
1000 NotifyDescriptor->Notify
1001 ));
1002 NotifyDescriptor->Notify (
1004 NotifyDescriptor,
1005 (PrivateData->PpiData.PpiList.PpiPtrs[Index2].Ppi)->Ppi
1006 );
1007 }
1008 }
1009 }
1010}
1011
1020VOID
1022 IN CONST EFI_PEI_SERVICES **PeiServices,
1024 )
1025{
1026 EFI_STATUS Status;
1027 EFI_SEC_HOB_DATA_PPI *SecHobDataPpi;
1028 EFI_HOB_GENERIC_HEADER *SecHobList;
1029
1030 for ( ; ;) {
1031 if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_TYPES) != 0) {
1032 //
1033 // It is a notification PPI.
1034 //
1035 Status = InternalPeiNotifyPpi (PeiServices, (CONST EFI_PEI_NOTIFY_DESCRIPTOR *)PpiList, TRUE);
1036 ASSERT_EFI_ERROR (Status);
1037 } else {
1038 //
1039 // It is a normal PPI.
1040 //
1041 Status = InternalPeiInstallPpi (PeiServices, PpiList, TRUE);
1042 ASSERT_EFI_ERROR (Status);
1043 }
1044
1045 if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) == EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) {
1046 //
1047 // Continue until the end of the PPI List.
1048 //
1049 break;
1050 }
1051
1052 PpiList++;
1053 }
1054
1055 //
1056 // If the EFI_SEC_HOB_DATA_PPI is in the list of PPIs passed to the PEI entry point,
1057 // the PEI Foundation will call the GetHobs() member function and install all HOBs
1058 // returned into the HOB list. It does this after installing all PPIs passed from SEC
1059 // into the PPI database and before dispatching any PEIMs.
1060 //
1061 Status = PeiLocatePpi (PeiServices, &gEfiSecHobDataPpiGuid, 0, NULL, (VOID **)&SecHobDataPpi);
1062 if (!EFI_ERROR (Status)) {
1063 Status = SecHobDataPpi->GetHobs (SecHobDataPpi, &SecHobList);
1064 if (!EFI_ERROR (Status)) {
1065 Status = PeiInstallSecHobData (PeiServices, SecHobList);
1066 ASSERT_EFI_ERROR (Status);
1067 }
1068 }
1069}
1070
1079VOID
1081 IN PEI_CORE_INSTANCE *PrivateData,
1082 IN PEI_CORE_FV_HANDLE *CoreFvHandle
1083 )
1084{
1086 EFI_PHYSICAL_ADDRESS OrgImageBase;
1087 EFI_PHYSICAL_ADDRESS MigratedImageBase;
1088 UINTN PeiCoreModuleSize;
1089 EFI_PEI_FILE_HANDLE PeiCoreFileHandle;
1090 VOID *PeiCoreImageBase;
1091 VOID *PeiCoreEntryPoint;
1092 EFI_STATUS Status;
1093
1094 PeiCoreFileHandle = NULL;
1095
1096 //
1097 // Find the PEI Core in the BFV in temporary memory.
1098 //
1099 Status = CoreFvHandle->FvPpi->FindFileByType (
1100 CoreFvHandle->FvPpi,
1101 EFI_FV_FILETYPE_PEI_CORE,
1102 CoreFvHandle->FvHandle,
1103 &PeiCoreFileHandle
1104 );
1105 ASSERT_EFI_ERROR (Status);
1106
1107 if (!EFI_ERROR (Status)) {
1108 Status = CoreFvHandle->FvPpi->GetFileInfo (CoreFvHandle->FvPpi, PeiCoreFileHandle, &FileInfo);
1109 ASSERT_EFI_ERROR (Status);
1110
1111 Status = PeiGetPe32Data (PeiCoreFileHandle, &PeiCoreImageBase);
1112 ASSERT_EFI_ERROR (Status);
1113
1114 //
1115 // Find PEI Core EntryPoint in the BFV in temporary memory.
1116 //
1117 Status = PeCoffLoaderGetEntryPoint ((VOID *)(UINTN)PeiCoreImageBase, &PeiCoreEntryPoint);
1118 ASSERT_EFI_ERROR (Status);
1119
1120 OrgImageBase = (UINTN)PeiCoreImageBase;
1121 MigratedImageBase = (UINTN)_ModuleEntryPoint - ((UINTN)PeiCoreEntryPoint - (UINTN)PeiCoreImageBase);
1122
1123 //
1124 // Size of loaded PEI_CORE in permanent memory.
1125 //
1126 PeiCoreModuleSize = (UINTN)FileInfo.BufferSize - ((UINTN)OrgImageBase - (UINTN)FileInfo.Buffer);
1127
1128 //
1129 // Migrate PEI_CORE PPI pointers from temporary memory to newly
1130 // installed PEI_CORE in permanent memory.
1131 //
1132 ConvertPpiPointersFv (PrivateData, (UINTN)OrgImageBase, (UINTN)MigratedImageBase, PeiCoreModuleSize);
1133 }
1134}
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:132
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#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:462
#define DEBUG_CODE_BEGIN()
Definition: DebugLib.h:564
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define DEBUG_CODE_END()
Definition: DebugLib.h:578
#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:662
VOID ConvertPeiCorePpiPointers(IN PEI_CORE_INSTANCE *PrivateData, IN PEI_CORE_FV_HANDLE *CoreFvHandle)
Definition: Ppi.c:1080
EFI_STATUS InternalPeiNotifyPpi(IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_NOTIFY_DESCRIPTOR *NotifyList, IN BOOLEAN Single)
Definition: Ppi.c:731
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:960
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:563
VOID ProcessDispatchNotifyList(IN PEI_CORE_INSTANCE *PrivateData)
Definition: Ppi.c:890
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:590
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:1021
EFI_STATUS EFIAPI PeiNotifyPpi(IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_PEI_NOTIFY_DESCRIPTOR *NotifyList)
Definition: Ppi.c:874
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