REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the MdeModulePkg package Cc: Andrew Fish <afish@apple.com> Cc: Leif Lindholm <leif@nuviainc.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn>
		
			
				
	
	
		
			1135 lines
		
	
	
		
			37 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1135 lines
		
	
	
		
			37 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   EFI PEI Core PPI services
 | |
| 
 | |
| Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
 | |
| SPDX-License-Identifier: BSD-2-Clause-Patent
 | |
| 
 | |
| **/
 | |
| 
 | |
| #include "PeiMain.h"
 | |
| 
 | |
| /**
 | |
| 
 | |
|   Migrate Pointer from the temporary memory to PEI installed memory.
 | |
| 
 | |
|   @param Pointer         Pointer to the Pointer needs to be converted.
 | |
|   @param TempBottom      Base of old temporary memory
 | |
|   @param TempTop         Top of old temporary memory
 | |
|   @param Offset          Offset of new memory to old temporary memory.
 | |
|   @param OffsetPositive  Positive flag of Offset value.
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| ConvertPointer (
 | |
|   IN OUT VOID  **Pointer,
 | |
|   IN UINTN     TempBottom,
 | |
|   IN UINTN     TempTop,
 | |
|   IN UINTN     Offset,
 | |
|   IN BOOLEAN   OffsetPositive
 | |
|   )
 | |
| {
 | |
|   if (((UINTN)*Pointer < TempTop) &&
 | |
|       ((UINTN)*Pointer >= TempBottom))
 | |
|   {
 | |
|     if (OffsetPositive) {
 | |
|       *Pointer = (VOID *)((UINTN)*Pointer + Offset);
 | |
|     } else {
 | |
|       *Pointer = (VOID *)((UINTN)*Pointer - Offset);
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
| 
 | |
|   Migrate Pointer in ranges of the temporary memory to PEI installed memory.
 | |
| 
 | |
|   @param SecCoreData     Points to a data structure containing SEC to PEI handoff data, such as the size
 | |
|                          and location of temporary RAM, the stack location and the BFV location.
 | |
|   @param PrivateData     Pointer to PeiCore's private data structure.
 | |
|   @param Pointer         Pointer to the Pointer needs to be converted.
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| ConvertPointerInRanges (
 | |
|   IN CONST EFI_SEC_PEI_HAND_OFF  *SecCoreData,
 | |
|   IN PEI_CORE_INSTANCE           *PrivateData,
 | |
|   IN OUT VOID                    **Pointer
 | |
|   )
 | |
| {
 | |
|   UINT8  IndexHole;
 | |
| 
 | |
|   if (PrivateData->MemoryPages.Size != 0) {
 | |
|     //
 | |
|     // Convert PPI pointer in old memory pages
 | |
|     // It needs to be done before Convert PPI pointer in old Heap
 | |
|     //
 | |
|     ConvertPointer (
 | |
|       Pointer,
 | |
|       (UINTN)PrivateData->MemoryPages.Base,
 | |
|       (UINTN)PrivateData->MemoryPages.Base + PrivateData->MemoryPages.Size,
 | |
|       PrivateData->MemoryPages.Offset,
 | |
|       PrivateData->MemoryPages.OffsetPositive
 | |
|       );
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Convert PPI pointer in old Heap
 | |
|   //
 | |
|   ConvertPointer (
 | |
|     Pointer,
 | |
|     (UINTN)SecCoreData->PeiTemporaryRamBase,
 | |
|     (UINTN)SecCoreData->PeiTemporaryRamBase + SecCoreData->PeiTemporaryRamSize,
 | |
|     PrivateData->HeapOffset,
 | |
|     PrivateData->HeapOffsetPositive
 | |
|     );
 | |
| 
 | |
|   //
 | |
|   // Convert PPI pointer in old Stack
 | |
|   //
 | |
|   ConvertPointer (
 | |
|     Pointer,
 | |
|     (UINTN)SecCoreData->StackBase,
 | |
|     (UINTN)SecCoreData->StackBase + SecCoreData->StackSize,
 | |
|     PrivateData->StackOffset,
 | |
|     PrivateData->StackOffsetPositive
 | |
|     );
 | |
| 
 | |
|   //
 | |
|   // Convert PPI pointer in old TempRam Hole
 | |
|   //
 | |
|   for (IndexHole = 0; IndexHole < HOLE_MAX_NUMBER; IndexHole++) {
 | |
|     if (PrivateData->HoleData[IndexHole].Size == 0) {
 | |
|       continue;
 | |
|     }
 | |
| 
 | |
|     ConvertPointer (
 | |
|       Pointer,
 | |
|       (UINTN)PrivateData->HoleData[IndexHole].Base,
 | |
|       (UINTN)PrivateData->HoleData[IndexHole].Base + PrivateData->HoleData[IndexHole].Size,
 | |
|       PrivateData->HoleData[IndexHole].Offset,
 | |
|       PrivateData->HoleData[IndexHole].OffsetPositive
 | |
|       );
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
| 
 | |
|   Migrate Single PPI Pointer from the temporary memory to PEI installed memory.
 | |
| 
 | |
|   @param SecCoreData     Points to a data structure containing SEC to PEI handoff data, such as the size
 | |
|                          and location of temporary RAM, the stack location and the BFV location.
 | |
|   @param PrivateData     Pointer to PeiCore's private data structure.
 | |
|   @param PpiPointer      Pointer to Ppi
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| ConvertSinglePpiPointer (
 | |
|   IN CONST EFI_SEC_PEI_HAND_OFF  *SecCoreData,
 | |
|   IN PEI_CORE_INSTANCE           *PrivateData,
 | |
|   IN PEI_PPI_LIST_POINTERS       *PpiPointer
 | |
|   )
 | |
| {
 | |
|   //
 | |
|   // 1. Convert the pointer to the PPI descriptor from the old TempRam
 | |
|   //    to the relocated physical memory.
 | |
|   // It (for the pointer to the PPI descriptor) needs to be done before 2 (for
 | |
|   // the pointer to the GUID) and 3 (for the pointer to the PPI interface structure).
 | |
|   //
 | |
|   ConvertPointerInRanges (SecCoreData, PrivateData, &PpiPointer->Raw);
 | |
|   //
 | |
|   // 2. Convert the pointer to the GUID in the PPI or NOTIFY descriptor
 | |
|   //    from the old TempRam to the relocated physical memory.
 | |
|   //
 | |
|   ConvertPointerInRanges (SecCoreData, PrivateData, (VOID **)&PpiPointer->Ppi->Guid);
 | |
|   //
 | |
|   // 3. Convert the pointer to the PPI interface structure in the PPI descriptor
 | |
|   //    from the old TempRam to the relocated physical memory.
 | |
|   //
 | |
|   ConvertPointerInRanges (SecCoreData, PrivateData, (VOID **)&PpiPointer->Ppi->Ppi);
 | |
| }
 | |
| 
 | |
| /**
 | |
| 
 | |
|   Migrate PPI Pointers from the temporary memory to PEI installed memory.
 | |
| 
 | |
|   @param SecCoreData     Points to a data structure containing SEC to PEI handoff data, such as the size
 | |
|                          and location of temporary RAM, the stack location and the BFV location.
 | |
|   @param PrivateData     Pointer to PeiCore's private data structure.
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| ConvertPpiPointers (
 | |
|   IN CONST EFI_SEC_PEI_HAND_OFF  *SecCoreData,
 | |
|   IN PEI_CORE_INSTANCE           *PrivateData
 | |
|   )
 | |
| {
 | |
|   UINT8  Index;
 | |
| 
 | |
|   //
 | |
|   // Convert normal PPIs.
 | |
|   //
 | |
|   for (Index = 0; Index < PrivateData->PpiData.PpiList.CurrentCount; Index++) {
 | |
|     ConvertSinglePpiPointer (
 | |
|       SecCoreData,
 | |
|       PrivateData,
 | |
|       &PrivateData->PpiData.PpiList.PpiPtrs[Index]
 | |
|       );
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Convert Callback Notification PPIs.
 | |
|   //
 | |
|   for (Index = 0; Index < PrivateData->PpiData.CallbackNotifyList.CurrentCount; Index++) {
 | |
|     ConvertSinglePpiPointer (
 | |
|       SecCoreData,
 | |
|       PrivateData,
 | |
|       &PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index]
 | |
|       );
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Convert Dispatch Notification PPIs.
 | |
|   //
 | |
|   for (Index = 0; Index < PrivateData->PpiData.DispatchNotifyList.CurrentCount; Index++) {
 | |
|     ConvertSinglePpiPointer (
 | |
|       SecCoreData,
 | |
|       PrivateData,
 | |
|       &PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index]
 | |
|       );
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
| 
 | |
|   Migrate Notify Pointers inside an FV from temporary memory to permanent memory.
 | |
| 
 | |
|   @param PrivateData      Pointer to PeiCore's private data structure.
 | |
|   @param OrgFvHandle      Address of FV Handle in temporary memory.
 | |
|   @param FvHandle         Address of FV Handle in permanent memory.
 | |
|   @param FvSize           Size of the FV.
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| ConvertPpiPointersFv (
 | |
|   IN  PEI_CORE_INSTANCE  *PrivateData,
 | |
|   IN  UINTN              OrgFvHandle,
 | |
|   IN  UINTN              FvHandle,
 | |
|   IN  UINTN              FvSize
 | |
|   )
 | |
| {
 | |
|   UINT8                             Index;
 | |
|   UINTN                             Offset;
 | |
|   BOOLEAN                           OffsetPositive;
 | |
|   EFI_PEI_FIRMWARE_VOLUME_INFO_PPI  *FvInfoPpi;
 | |
|   UINT8                             GuidIndex;
 | |
|   EFI_GUID                          *Guid;
 | |
|   EFI_GUID                          *GuidCheckList[2];
 | |
| 
 | |
|   GuidCheckList[0] = &gEfiPeiFirmwareVolumeInfoPpiGuid;
 | |
|   GuidCheckList[1] = &gEfiPeiFirmwareVolumeInfo2PpiGuid;
 | |
| 
 | |
|   if (FvHandle > OrgFvHandle) {
 | |
|     OffsetPositive = TRUE;
 | |
|     Offset         = FvHandle - OrgFvHandle;
 | |
|   } else {
 | |
|     OffsetPositive = FALSE;
 | |
|     Offset         = OrgFvHandle - FvHandle;
 | |
|   }
 | |
| 
 | |
|   DEBUG ((DEBUG_VERBOSE, "Converting PPI pointers in FV.\n"));
 | |
|   DEBUG ((
 | |
|     DEBUG_VERBOSE,
 | |
|     "  OrgFvHandle at 0x%08x. FvHandle at 0x%08x. FvSize = 0x%x\n",
 | |
|     (UINTN)OrgFvHandle,
 | |
|     (UINTN)FvHandle,
 | |
|     FvSize
 | |
|     ));
 | |
|   DEBUG ((
 | |
|     DEBUG_VERBOSE,
 | |
|     "    OrgFvHandle range: 0x%08x - 0x%08x\n",
 | |
|     OrgFvHandle,
 | |
|     OrgFvHandle + FvSize
 | |
|     ));
 | |
| 
 | |
|   for (Index = 0; Index < PrivateData->PpiData.CallbackNotifyList.CurrentCount; Index++) {
 | |
|     ConvertPointer (
 | |
|       (VOID **)&PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index].Raw,
 | |
|       OrgFvHandle,
 | |
|       OrgFvHandle + FvSize,
 | |
|       Offset,
 | |
|       OffsetPositive
 | |
|       );
 | |
|     ConvertPointer (
 | |
|       (VOID **)&PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index].Notify->Guid,
 | |
|       OrgFvHandle,
 | |
|       OrgFvHandle + FvSize,
 | |
|       Offset,
 | |
|       OffsetPositive
 | |
|       );
 | |
|     ConvertPointer (
 | |
|       (VOID **)&PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index].Notify->Notify,
 | |
|       OrgFvHandle,
 | |
|       OrgFvHandle + FvSize,
 | |
|       Offset,
 | |
|       OffsetPositive
 | |
|       );
 | |
|   }
 | |
| 
 | |
|   for (Index = 0; Index < PrivateData->PpiData.DispatchNotifyList.CurrentCount; Index++) {
 | |
|     ConvertPointer (
 | |
|       (VOID **)&PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].Raw,
 | |
|       OrgFvHandle,
 | |
|       OrgFvHandle + FvSize,
 | |
|       Offset,
 | |
|       OffsetPositive
 | |
|       );
 | |
|     ConvertPointer (
 | |
|       (VOID **)&PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].Notify->Guid,
 | |
|       OrgFvHandle,
 | |
|       OrgFvHandle + FvSize,
 | |
|       Offset,
 | |
|       OffsetPositive
 | |
|       );
 | |
|     ConvertPointer (
 | |
|       (VOID **)&PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].Notify->Notify,
 | |
|       OrgFvHandle,
 | |
|       OrgFvHandle + FvSize,
 | |
|       Offset,
 | |
|       OffsetPositive
 | |
|       );
 | |
|   }
 | |
| 
 | |
|   for (Index = 0; Index < PrivateData->PpiData.PpiList.CurrentCount; Index++) {
 | |
|     ConvertPointer (
 | |
|       (VOID **)&PrivateData->PpiData.PpiList.PpiPtrs[Index].Raw,
 | |
|       OrgFvHandle,
 | |
|       OrgFvHandle + FvSize,
 | |
|       Offset,
 | |
|       OffsetPositive
 | |
|       );
 | |
|     ConvertPointer (
 | |
|       (VOID **)&PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi->Guid,
 | |
|       OrgFvHandle,
 | |
|       OrgFvHandle + FvSize,
 | |
|       Offset,
 | |
|       OffsetPositive
 | |
|       );
 | |
|     ConvertPointer (
 | |
|       (VOID **)&PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi->Ppi,
 | |
|       OrgFvHandle,
 | |
|       OrgFvHandle + FvSize,
 | |
|       Offset,
 | |
|       OffsetPositive
 | |
|       );
 | |
| 
 | |
|     Guid = PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi->Guid;
 | |
|     for (GuidIndex = 0; GuidIndex < ARRAY_SIZE (GuidCheckList); ++GuidIndex) {
 | |
|       //
 | |
|       // Don't use CompareGuid function here for performance reasons.
 | |
|       // Instead we compare the GUID as INT32 at a time and branch
 | |
|       // on the first failed comparison.
 | |
|       //
 | |
|       if ((((INT32 *)Guid)[0] == ((INT32 *)GuidCheckList[GuidIndex])[0]) &&
 | |
|           (((INT32 *)Guid)[1] == ((INT32 *)GuidCheckList[GuidIndex])[1]) &&
 | |
|           (((INT32 *)Guid)[2] == ((INT32 *)GuidCheckList[GuidIndex])[2]) &&
 | |
|           (((INT32 *)Guid)[3] == ((INT32 *)GuidCheckList[GuidIndex])[3]))
 | |
|       {
 | |
|         FvInfoPpi = PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi->Ppi;
 | |
|         DEBUG ((DEBUG_VERBOSE, "      FvInfo: %p -> ", FvInfoPpi->FvInfo));
 | |
|         if ((UINTN)FvInfoPpi->FvInfo == OrgFvHandle) {
 | |
|           ConvertPointer (
 | |
|             (VOID **)&FvInfoPpi->FvInfo,
 | |
|             OrgFvHandle,
 | |
|             OrgFvHandle + FvSize,
 | |
|             Offset,
 | |
|             OffsetPositive
 | |
|             );
 | |
|           DEBUG ((DEBUG_VERBOSE, "%p", FvInfoPpi->FvInfo));
 | |
|         }
 | |
| 
 | |
|         DEBUG ((DEBUG_VERBOSE, "\n"));
 | |
|         break;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
| 
 | |
|   Dumps the PPI lists to debug output.
 | |
| 
 | |
|   @param PrivateData     Points to PeiCore's private instance data.
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| DumpPpiList (
 | |
|   IN PEI_CORE_INSTANCE  *PrivateData
 | |
|   )
 | |
| {
 | |
|   DEBUG_CODE_BEGIN ();
 | |
|   UINTN  Index;
 | |
| 
 | |
|   if (PrivateData == NULL) {
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   for (Index = 0; Index < PrivateData->PpiData.CallbackNotifyList.CurrentCount; Index++) {
 | |
|     DEBUG ((
 | |
|       DEBUG_VERBOSE,
 | |
|       "CallbackNotify[%2d] {%g} at 0x%x (%a)\n",
 | |
|       Index,
 | |
|       PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index].Notify->Guid,
 | |
|       (UINTN)PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index].Raw,
 | |
|       (
 | |
|        !(
 | |
|          ((EFI_PHYSICAL_ADDRESS)(UINTN)PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index].Raw >= PrivateData->PhysicalMemoryBegin) &&
 | |
|          (((EFI_PHYSICAL_ADDRESS)((UINTN)PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index].Raw) + sizeof (EFI_PEI_NOTIFY_DESCRIPTOR)) < PrivateData->FreePhysicalMemoryTop)
 | |
|          )
 | |
|         ? "CAR" : "Post-Memory"
 | |
|       )
 | |
|       ));
 | |
|   }
 | |
| 
 | |
|   for (Index = 0; Index < PrivateData->PpiData.DispatchNotifyList.CurrentCount; Index++) {
 | |
|     DEBUG ((
 | |
|       DEBUG_VERBOSE,
 | |
|       "DispatchNotify[%2d] {%g} at 0x%x (%a)\n",
 | |
|       Index,
 | |
|       PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].Notify->Guid,
 | |
|       (UINTN)PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].Raw,
 | |
|       (
 | |
|        !(
 | |
|          ((EFI_PHYSICAL_ADDRESS)(UINTN)PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].Raw >= PrivateData->PhysicalMemoryBegin) &&
 | |
|          (((EFI_PHYSICAL_ADDRESS)((UINTN)PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].Raw) + sizeof (EFI_PEI_NOTIFY_DESCRIPTOR)) < PrivateData->FreePhysicalMemoryTop)
 | |
|          )
 | |
|       ? "CAR" : "Post-Memory"
 | |
|       )
 | |
|       ));
 | |
|   }
 | |
| 
 | |
|   for (Index = 0; Index < PrivateData->PpiData.PpiList.CurrentCount; Index++) {
 | |
|     DEBUG ((
 | |
|       DEBUG_VERBOSE,
 | |
|       "PPI[%2d] {%g} at 0x%x (%a)\n",
 | |
|       Index,
 | |
|       PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi->Guid,
 | |
|       (UINTN)PrivateData->PpiData.PpiList.PpiPtrs[Index].Raw,
 | |
|       (
 | |
|        !(
 | |
|          ((EFI_PHYSICAL_ADDRESS)(UINTN)PrivateData->PpiData.PpiList.PpiPtrs[Index].Raw >= PrivateData->PhysicalMemoryBegin) &&
 | |
|          (((EFI_PHYSICAL_ADDRESS)((UINTN)PrivateData->PpiData.PpiList.PpiPtrs[Index].Raw) + sizeof (EFI_PEI_PPI_DESCRIPTOR)) < PrivateData->FreePhysicalMemoryTop)
 | |
|          )
 | |
|       ? "CAR" : "Post-Memory"
 | |
|       )
 | |
|       ));
 | |
|   }
 | |
| 
 | |
|   DEBUG_CODE_END ();
 | |
| }
 | |
| 
 | |
| /**
 | |
| 
 | |
|   This function installs an interface in the PEI PPI database by GUID.
 | |
|   The purpose of the service is to publish an interface that other parties
 | |
|   can use to call additional PEIMs.
 | |
| 
 | |
|   @param PeiServices                An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
 | |
|   @param PpiList                    Pointer to a list of PEI PPI Descriptors.
 | |
|   @param Single                     TRUE if only single entry in the PpiList.
 | |
|                                     FALSE if the PpiList is ended with an entry which has the
 | |
|                                     EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST flag set in its Flags field.
 | |
| 
 | |
|   @retval EFI_SUCCESS              if all PPIs in PpiList are successfully installed.
 | |
|   @retval EFI_INVALID_PARAMETER    if PpiList is NULL pointer
 | |
|                                    if any PPI in PpiList is not valid
 | |
|   @retval EFI_OUT_OF_RESOURCES     if there is no more memory resource to install PPI
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| InternalPeiInstallPpi (
 | |
|   IN CONST EFI_PEI_SERVICES        **PeiServices,
 | |
|   IN CONST EFI_PEI_PPI_DESCRIPTOR  *PpiList,
 | |
|   IN BOOLEAN                       Single
 | |
|   )
 | |
| {
 | |
|   PEI_CORE_INSTANCE  *PrivateData;
 | |
|   PEI_PPI_LIST       *PpiListPointer;
 | |
|   UINTN              Index;
 | |
|   UINTN              LastCount;
 | |
|   VOID               *TempPtr;
 | |
| 
 | |
|   if (PpiList == NULL) {
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
 | |
| 
 | |
|   PpiListPointer = &PrivateData->PpiData.PpiList;
 | |
|   Index          = PpiListPointer->CurrentCount;
 | |
|   LastCount      = Index;
 | |
| 
 | |
|   //
 | |
|   // This is loop installs all PPI descriptors in the PpiList.  It is terminated
 | |
|   // by the EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST being set in the last
 | |
|   // EFI_PEI_PPI_DESCRIPTOR in the list.
 | |
|   //
 | |
| 
 | |
|   for ( ; ;) {
 | |
|     //
 | |
|     // Check if it is a valid PPI.
 | |
|     // If not, rollback list to exclude all in this list.
 | |
|     // Try to indicate which item failed.
 | |
|     //
 | |
|     if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_PPI) == 0) {
 | |
|       PpiListPointer->CurrentCount = LastCount;
 | |
|       DEBUG ((DEBUG_ERROR, "ERROR -> InstallPpi: %g %p\n", PpiList->Guid, PpiList->Ppi));
 | |
|       return EFI_INVALID_PARAMETER;
 | |
|     }
 | |
| 
 | |
|     if (Index >= PpiListPointer->MaxCount) {
 | |
|       //
 | |
|       // Run out of room, grow the buffer.
 | |
|       //
 | |
|       TempPtr = AllocateZeroPool (
 | |
|                   sizeof (PEI_PPI_LIST_POINTERS) * (PpiListPointer->MaxCount + PPI_GROWTH_STEP)
 | |
|                   );
 | |
|       ASSERT (TempPtr != NULL);
 | |
|       CopyMem (
 | |
|         TempPtr,
 | |
|         PpiListPointer->PpiPtrs,
 | |
|         sizeof (PEI_PPI_LIST_POINTERS) * PpiListPointer->MaxCount
 | |
|         );
 | |
|       PpiListPointer->PpiPtrs  = TempPtr;
 | |
|       PpiListPointer->MaxCount = PpiListPointer->MaxCount + PPI_GROWTH_STEP;
 | |
|     }
 | |
| 
 | |
|     DEBUG ((DEBUG_INFO, "Install PPI: %g\n", PpiList->Guid));
 | |
|     PpiListPointer->PpiPtrs[Index].Ppi = (EFI_PEI_PPI_DESCRIPTOR *)PpiList;
 | |
|     Index++;
 | |
|     PpiListPointer->CurrentCount++;
 | |
| 
 | |
|     if (Single) {
 | |
|       //
 | |
|       // Only single entry in the PpiList.
 | |
|       //
 | |
|       break;
 | |
|     } else if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) ==
 | |
|                EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST)
 | |
|     {
 | |
|       //
 | |
|       // Continue until the end of the PPI List.
 | |
|       //
 | |
|       break;
 | |
|     }
 | |
| 
 | |
|     //
 | |
|     // Go to the next descriptor.
 | |
|     //
 | |
|     PpiList++;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Process any callback level notifies for newly installed PPIs.
 | |
|   //
 | |
|   ProcessNotify (
 | |
|     PrivateData,
 | |
|     EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
 | |
|     LastCount,
 | |
|     PpiListPointer->CurrentCount,
 | |
|     0,
 | |
|     PrivateData->PpiData.CallbackNotifyList.CurrentCount
 | |
|     );
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /**
 | |
| 
 | |
|   This function installs an interface in the PEI PPI database by GUID.
 | |
|   The purpose of the service is to publish an interface that other parties
 | |
|   can use to call additional PEIMs.
 | |
| 
 | |
|   @param PeiServices                An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
 | |
|   @param PpiList                    Pointer to a list of PEI PPI Descriptors.
 | |
| 
 | |
|   @retval EFI_SUCCESS              if all PPIs in PpiList are successfully installed.
 | |
|   @retval EFI_INVALID_PARAMETER    if PpiList is NULL pointer
 | |
|                                    if any PPI in PpiList is not valid
 | |
|   @retval EFI_OUT_OF_RESOURCES     if there is no more memory resource to install PPI
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| PeiInstallPpi (
 | |
|   IN CONST EFI_PEI_SERVICES        **PeiServices,
 | |
|   IN CONST EFI_PEI_PPI_DESCRIPTOR  *PpiList
 | |
|   )
 | |
| {
 | |
|   return InternalPeiInstallPpi (PeiServices, PpiList, FALSE);
 | |
| }
 | |
| 
 | |
| /**
 | |
| 
 | |
|   This function reinstalls an interface in the PEI PPI database by GUID.
 | |
|   The purpose of the service is to publish an interface that other parties can
 | |
|   use to replace an interface of the same name in the protocol database with a
 | |
|   different interface.
 | |
| 
 | |
|   @param PeiServices            An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
 | |
|   @param OldPpi                 Pointer to the old PEI PPI Descriptors.
 | |
|   @param NewPpi                 Pointer to the new PEI PPI Descriptors.
 | |
| 
 | |
|   @retval EFI_SUCCESS           if the operation was successful
 | |
|   @retval EFI_INVALID_PARAMETER if OldPpi or NewPpi is NULL
 | |
|   @retval EFI_INVALID_PARAMETER if NewPpi is not valid
 | |
|   @retval EFI_NOT_FOUND         if the PPI was not in the database
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| PeiReInstallPpi (
 | |
|   IN CONST EFI_PEI_SERVICES        **PeiServices,
 | |
|   IN CONST EFI_PEI_PPI_DESCRIPTOR  *OldPpi,
 | |
|   IN CONST EFI_PEI_PPI_DESCRIPTOR  *NewPpi
 | |
|   )
 | |
| {
 | |
|   PEI_CORE_INSTANCE  *PrivateData;
 | |
|   UINTN              Index;
 | |
| 
 | |
|   if ((OldPpi == NULL) || (NewPpi == NULL)) {
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   if ((NewPpi->Flags & EFI_PEI_PPI_DESCRIPTOR_PPI) == 0) {
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
 | |
| 
 | |
|   //
 | |
|   // Find the old PPI instance in the database.  If we can not find it,
 | |
|   // return the EFI_NOT_FOUND error.
 | |
|   //
 | |
|   for (Index = 0; Index < PrivateData->PpiData.PpiList.CurrentCount; Index++) {
 | |
|     if (OldPpi == PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi) {
 | |
|       break;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (Index == PrivateData->PpiData.PpiList.CurrentCount) {
 | |
|     return EFI_NOT_FOUND;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Replace the old PPI with the new one.
 | |
|   //
 | |
|   DEBUG ((DEBUG_INFO, "Reinstall PPI: %g\n", NewPpi->Guid));
 | |
|   PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi = (EFI_PEI_PPI_DESCRIPTOR *)NewPpi;
 | |
| 
 | |
|   //
 | |
|   // Process any callback level notifies for the newly installed PPI.
 | |
|   //
 | |
|   ProcessNotify (
 | |
|     PrivateData,
 | |
|     EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
 | |
|     Index,
 | |
|     Index+1,
 | |
|     0,
 | |
|     PrivateData->PpiData.CallbackNotifyList.CurrentCount
 | |
|     );
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /**
 | |
| 
 | |
|   Locate a given named PPI.
 | |
| 
 | |
| 
 | |
|   @param PeiServices        An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
 | |
|   @param Guid               Pointer to GUID of the PPI.
 | |
|   @param Instance           Instance Number to discover.
 | |
|   @param PpiDescriptor      Pointer to reference the found descriptor. If not NULL,
 | |
|                             returns a pointer to the descriptor (includes flags, etc)
 | |
|   @param Ppi                Pointer to reference the found PPI
 | |
| 
 | |
|   @retval EFI_SUCCESS   if the PPI is in the database
 | |
|   @retval EFI_NOT_FOUND if the PPI is not in the database
 | |
| 
 | |
| **/
 | |
| 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
 | |
|   )
 | |
| {
 | |
|   PEI_CORE_INSTANCE       *PrivateData;
 | |
|   UINTN                   Index;
 | |
|   EFI_GUID                *CheckGuid;
 | |
|   EFI_PEI_PPI_DESCRIPTOR  *TempPtr;
 | |
| 
 | |
|   PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
 | |
| 
 | |
|   //
 | |
|   // Search the data base for the matching instance of the GUIDed PPI.
 | |
|   //
 | |
|   for (Index = 0; Index < PrivateData->PpiData.PpiList.CurrentCount; Index++) {
 | |
|     TempPtr   = PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi;
 | |
|     CheckGuid = TempPtr->Guid;
 | |
| 
 | |
|     //
 | |
|     // Don't use CompareGuid function here for performance reasons.
 | |
|     // Instead we compare the GUID as INT32 at a time and branch
 | |
|     // on the first failed comparison.
 | |
|     //
 | |
|     if ((((INT32 *)Guid)[0] == ((INT32 *)CheckGuid)[0]) &&
 | |
|         (((INT32 *)Guid)[1] == ((INT32 *)CheckGuid)[1]) &&
 | |
|         (((INT32 *)Guid)[2] == ((INT32 *)CheckGuid)[2]) &&
 | |
|         (((INT32 *)Guid)[3] == ((INT32 *)CheckGuid)[3]))
 | |
|     {
 | |
|       if (Instance == 0) {
 | |
|         if (PpiDescriptor != NULL) {
 | |
|           *PpiDescriptor = TempPtr;
 | |
|         }
 | |
| 
 | |
|         if (Ppi != NULL) {
 | |
|           *Ppi = TempPtr->Ppi;
 | |
|         }
 | |
| 
 | |
|         return EFI_SUCCESS;
 | |
|       }
 | |
| 
 | |
|       Instance--;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return EFI_NOT_FOUND;
 | |
| }
 | |
| 
 | |
| /**
 | |
| 
 | |
|   This function installs a notification service to be called back when a given
 | |
|   interface is installed or reinstalled. The purpose of the service is to publish
 | |
|   an interface that other parties can use to call additional PPIs that may materialize later.
 | |
| 
 | |
|   @param PeiServices        An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
 | |
|   @param NotifyList         Pointer to list of Descriptors to notify upon.
 | |
|   @param Single             TRUE if only single entry in the NotifyList.
 | |
|                             FALSE if the NotifyList is ended with an entry which has the
 | |
|                             EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST flag set in its Flags field.
 | |
| 
 | |
|   @retval EFI_SUCCESS           if successful
 | |
|   @retval EFI_OUT_OF_RESOURCES  if no space in the database
 | |
|   @retval EFI_INVALID_PARAMETER if not a good descriptor
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| InternalPeiNotifyPpi (
 | |
|   IN CONST EFI_PEI_SERVICES           **PeiServices,
 | |
|   IN CONST EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyList,
 | |
|   IN BOOLEAN                          Single
 | |
|   )
 | |
| {
 | |
|   PEI_CORE_INSTANCE         *PrivateData;
 | |
|   PEI_CALLBACK_NOTIFY_LIST  *CallbackNotifyListPointer;
 | |
|   UINTN                     CallbackNotifyIndex;
 | |
|   UINTN                     LastCallbackNotifyCount;
 | |
|   PEI_DISPATCH_NOTIFY_LIST  *DispatchNotifyListPointer;
 | |
|   UINTN                     DispatchNotifyIndex;
 | |
|   UINTN                     LastDispatchNotifyCount;
 | |
|   VOID                      *TempPtr;
 | |
| 
 | |
|   if (NotifyList == NULL) {
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
 | |
| 
 | |
|   CallbackNotifyListPointer = &PrivateData->PpiData.CallbackNotifyList;
 | |
|   CallbackNotifyIndex       = CallbackNotifyListPointer->CurrentCount;
 | |
|   LastCallbackNotifyCount   = CallbackNotifyIndex;
 | |
| 
 | |
|   DispatchNotifyListPointer = &PrivateData->PpiData.DispatchNotifyList;
 | |
|   DispatchNotifyIndex       = DispatchNotifyListPointer->CurrentCount;
 | |
|   LastDispatchNotifyCount   = DispatchNotifyIndex;
 | |
| 
 | |
|   //
 | |
|   // This is loop installs all Notify descriptors in the NotifyList.  It is
 | |
|   // terminated by the EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST being set in the last
 | |
|   // EFI_PEI_NOTIFY_DESCRIPTOR in the list.
 | |
|   //
 | |
| 
 | |
|   for ( ; ;) {
 | |
|     //
 | |
|     // If some of the PPI data is invalid restore original Notify PPI database value
 | |
|     //
 | |
|     if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_TYPES) == 0) {
 | |
|       CallbackNotifyListPointer->CurrentCount = LastCallbackNotifyCount;
 | |
|       DispatchNotifyListPointer->CurrentCount = LastDispatchNotifyCount;
 | |
|       DEBUG ((DEBUG_ERROR, "ERROR -> NotifyPpi: %g %p\n", NotifyList->Guid, NotifyList->Notify));
 | |
|       return EFI_INVALID_PARAMETER;
 | |
|     }
 | |
| 
 | |
|     if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK) != 0) {
 | |
|       if (CallbackNotifyIndex >= CallbackNotifyListPointer->MaxCount) {
 | |
|         //
 | |
|         // Run out of room, grow the buffer.
 | |
|         //
 | |
|         TempPtr = AllocateZeroPool (
 | |
|                     sizeof (PEI_PPI_LIST_POINTERS) * (CallbackNotifyListPointer->MaxCount + CALLBACK_NOTIFY_GROWTH_STEP)
 | |
|                     );
 | |
|         ASSERT (TempPtr != NULL);
 | |
|         CopyMem (
 | |
|           TempPtr,
 | |
|           CallbackNotifyListPointer->NotifyPtrs,
 | |
|           sizeof (PEI_PPI_LIST_POINTERS) * CallbackNotifyListPointer->MaxCount
 | |
|           );
 | |
|         CallbackNotifyListPointer->NotifyPtrs = TempPtr;
 | |
|         CallbackNotifyListPointer->MaxCount   = CallbackNotifyListPointer->MaxCount + CALLBACK_NOTIFY_GROWTH_STEP;
 | |
|       }
 | |
| 
 | |
|       CallbackNotifyListPointer->NotifyPtrs[CallbackNotifyIndex].Notify = (EFI_PEI_NOTIFY_DESCRIPTOR *)NotifyList;
 | |
|       CallbackNotifyIndex++;
 | |
|       CallbackNotifyListPointer->CurrentCount++;
 | |
|     } else {
 | |
|       if (DispatchNotifyIndex >= DispatchNotifyListPointer->MaxCount) {
 | |
|         //
 | |
|         // Run out of room, grow the buffer.
 | |
|         //
 | |
|         TempPtr = AllocateZeroPool (
 | |
|                     sizeof (PEI_PPI_LIST_POINTERS) * (DispatchNotifyListPointer->MaxCount + DISPATCH_NOTIFY_GROWTH_STEP)
 | |
|                     );
 | |
|         ASSERT (TempPtr != NULL);
 | |
|         CopyMem (
 | |
|           TempPtr,
 | |
|           DispatchNotifyListPointer->NotifyPtrs,
 | |
|           sizeof (PEI_PPI_LIST_POINTERS) * DispatchNotifyListPointer->MaxCount
 | |
|           );
 | |
|         DispatchNotifyListPointer->NotifyPtrs = TempPtr;
 | |
|         DispatchNotifyListPointer->MaxCount   = DispatchNotifyListPointer->MaxCount + DISPATCH_NOTIFY_GROWTH_STEP;
 | |
|       }
 | |
| 
 | |
|       DispatchNotifyListPointer->NotifyPtrs[DispatchNotifyIndex].Notify = (EFI_PEI_NOTIFY_DESCRIPTOR *)NotifyList;
 | |
|       DispatchNotifyIndex++;
 | |
|       DispatchNotifyListPointer->CurrentCount++;
 | |
|     }
 | |
| 
 | |
|     DEBUG ((DEBUG_INFO, "Register PPI Notify: %g\n", NotifyList->Guid));
 | |
| 
 | |
|     if (Single) {
 | |
|       //
 | |
|       // Only single entry in the NotifyList.
 | |
|       //
 | |
|       break;
 | |
|     } else if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) ==
 | |
|                EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST)
 | |
|     {
 | |
|       //
 | |
|       // Continue until the end of the Notify List.
 | |
|       //
 | |
|       break;
 | |
|     }
 | |
| 
 | |
|     //
 | |
|     // Go to the next descriptor.
 | |
|     //
 | |
|     NotifyList++;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Process any callback level notifies for all previously installed PPIs.
 | |
|   //
 | |
|   ProcessNotify (
 | |
|     PrivateData,
 | |
|     EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
 | |
|     0,
 | |
|     PrivateData->PpiData.PpiList.CurrentCount,
 | |
|     LastCallbackNotifyCount,
 | |
|     CallbackNotifyListPointer->CurrentCount
 | |
|     );
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /**
 | |
| 
 | |
|   This function installs a notification service to be called back when a given
 | |
|   interface is installed or reinstalled. The purpose of the service is to publish
 | |
|   an interface that other parties can use to call additional PPIs that may materialize later.
 | |
| 
 | |
|   @param PeiServices        An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
 | |
|   @param NotifyList         Pointer to list of Descriptors to notify upon.
 | |
| 
 | |
|   @retval EFI_SUCCESS           if successful
 | |
|   @retval EFI_OUT_OF_RESOURCES  if no space in the database
 | |
|   @retval EFI_INVALID_PARAMETER if not a good descriptor
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| PeiNotifyPpi (
 | |
|   IN CONST EFI_PEI_SERVICES           **PeiServices,
 | |
|   IN CONST EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyList
 | |
|   )
 | |
| {
 | |
|   return InternalPeiNotifyPpi (PeiServices, NotifyList, FALSE);
 | |
| }
 | |
| 
 | |
| /**
 | |
| 
 | |
|   Process the Notify List at dispatch level.
 | |
| 
 | |
|   @param PrivateData  PeiCore's private data structure.
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| ProcessDispatchNotifyList (
 | |
|   IN PEI_CORE_INSTANCE  *PrivateData
 | |
|   )
 | |
| {
 | |
|   UINTN  TempValue;
 | |
| 
 | |
|   while (TRUE) {
 | |
|     //
 | |
|     // Check if the PEIM that was just dispatched resulted in any
 | |
|     // Notifies getting installed.  If so, go process any dispatch
 | |
|     // level Notifies that match the previously installed PPIs.
 | |
|     // Use "while" instead of "if" since ProcessNotify can modify
 | |
|     // DispatchNotifyList.CurrentCount (with NotifyPpi) so we have
 | |
|     // to iterate until the same.
 | |
|     //
 | |
|     while (PrivateData->PpiData.DispatchNotifyList.LastDispatchedCount != PrivateData->PpiData.DispatchNotifyList.CurrentCount) {
 | |
|       TempValue = PrivateData->PpiData.DispatchNotifyList.CurrentCount;
 | |
|       ProcessNotify (
 | |
|         PrivateData,
 | |
|         EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH,
 | |
|         0,
 | |
|         PrivateData->PpiData.PpiList.LastDispatchedCount,
 | |
|         PrivateData->PpiData.DispatchNotifyList.LastDispatchedCount,
 | |
|         PrivateData->PpiData.DispatchNotifyList.CurrentCount
 | |
|         );
 | |
|       PrivateData->PpiData.DispatchNotifyList.LastDispatchedCount = TempValue;
 | |
|     }
 | |
| 
 | |
|     //
 | |
|     // Check if the PEIM that was just dispatched resulted in any
 | |
|     // PPIs getting installed.  If so, go process any dispatch
 | |
|     // level Notifies that match the installed PPIs.
 | |
|     // Use "while" instead of "if" since ProcessNotify can modify
 | |
|     // PpiList.CurrentCount (with InstallPpi) so we have to iterate
 | |
|     // until the same.
 | |
|     //
 | |
|     while (PrivateData->PpiData.PpiList.LastDispatchedCount != PrivateData->PpiData.PpiList.CurrentCount) {
 | |
|       TempValue = PrivateData->PpiData.PpiList.CurrentCount;
 | |
|       ProcessNotify (
 | |
|         PrivateData,
 | |
|         EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH,
 | |
|         PrivateData->PpiData.PpiList.LastDispatchedCount,
 | |
|         PrivateData->PpiData.PpiList.CurrentCount,
 | |
|         0,
 | |
|         PrivateData->PpiData.DispatchNotifyList.LastDispatchedCount
 | |
|         );
 | |
|       PrivateData->PpiData.PpiList.LastDispatchedCount = TempValue;
 | |
|     }
 | |
| 
 | |
|     if (PrivateData->PpiData.DispatchNotifyList.LastDispatchedCount == PrivateData->PpiData.DispatchNotifyList.CurrentCount) {
 | |
|       break;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return;
 | |
| }
 | |
| 
 | |
| /**
 | |
| 
 | |
|   Process notifications.
 | |
| 
 | |
|   @param PrivateData        PeiCore's private data structure
 | |
|   @param NotifyType         Type of notify to fire.
 | |
|   @param InstallStartIndex  Install Beginning index.
 | |
|   @param InstallStopIndex   Install Ending index.
 | |
|   @param NotifyStartIndex   Notify Beginning index.
 | |
|   @param NotifyStopIndex    Notify Ending index.
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| ProcessNotify (
 | |
|   IN PEI_CORE_INSTANCE  *PrivateData,
 | |
|   IN UINTN              NotifyType,
 | |
|   IN INTN               InstallStartIndex,
 | |
|   IN INTN               InstallStopIndex,
 | |
|   IN INTN               NotifyStartIndex,
 | |
|   IN INTN               NotifyStopIndex
 | |
|   )
 | |
| {
 | |
|   INTN                       Index1;
 | |
|   INTN                       Index2;
 | |
|   EFI_GUID                   *SearchGuid;
 | |
|   EFI_GUID                   *CheckGuid;
 | |
|   EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor;
 | |
| 
 | |
|   for (Index1 = NotifyStartIndex; Index1 < NotifyStopIndex; Index1++) {
 | |
|     if (NotifyType == EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK) {
 | |
|       NotifyDescriptor = PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index1].Notify;
 | |
|     } else {
 | |
|       NotifyDescriptor = PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index1].Notify;
 | |
|     }
 | |
| 
 | |
|     CheckGuid = NotifyDescriptor->Guid;
 | |
| 
 | |
|     for (Index2 = InstallStartIndex; Index2 < InstallStopIndex; Index2++) {
 | |
|       SearchGuid = PrivateData->PpiData.PpiList.PpiPtrs[Index2].Ppi->Guid;
 | |
|       //
 | |
|       // Don't use CompareGuid function here for performance reasons.
 | |
|       // Instead we compare the GUID as INT32 at a time and branch
 | |
|       // on the first failed comparison.
 | |
|       //
 | |
|       if ((((INT32 *)SearchGuid)[0] == ((INT32 *)CheckGuid)[0]) &&
 | |
|           (((INT32 *)SearchGuid)[1] == ((INT32 *)CheckGuid)[1]) &&
 | |
|           (((INT32 *)SearchGuid)[2] == ((INT32 *)CheckGuid)[2]) &&
 | |
|           (((INT32 *)SearchGuid)[3] == ((INT32 *)CheckGuid)[3]))
 | |
|       {
 | |
|         DEBUG ((
 | |
|           DEBUG_INFO,
 | |
|           "Notify: PPI Guid: %g, Peim notify entry point: %p\n",
 | |
|           SearchGuid,
 | |
|           NotifyDescriptor->Notify
 | |
|           ));
 | |
|         NotifyDescriptor->Notify (
 | |
|                             (EFI_PEI_SERVICES **)GetPeiServicesTablePointer (),
 | |
|                             NotifyDescriptor,
 | |
|                             (PrivateData->PpiData.PpiList.PpiPtrs[Index2].Ppi)->Ppi
 | |
|                             );
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Process PpiList from SEC phase.
 | |
| 
 | |
|   @param PeiServices    An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
 | |
|   @param PpiList        Points to a list of one or more PPI descriptors to be installed initially by the PEI core.
 | |
|                         These PPI's will be installed and/or immediately signaled if they are notification type.
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| ProcessPpiListFromSec (
 | |
|   IN CONST EFI_PEI_SERVICES        **PeiServices,
 | |
|   IN CONST EFI_PEI_PPI_DESCRIPTOR  *PpiList
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS              Status;
 | |
|   EFI_SEC_HOB_DATA_PPI    *SecHobDataPpi;
 | |
|   EFI_HOB_GENERIC_HEADER  *SecHobList;
 | |
| 
 | |
|   for ( ; ;) {
 | |
|     if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_TYPES) != 0) {
 | |
|       //
 | |
|       // It is a notification PPI.
 | |
|       //
 | |
|       Status = InternalPeiNotifyPpi (PeiServices, (CONST EFI_PEI_NOTIFY_DESCRIPTOR *)PpiList, TRUE);
 | |
|       ASSERT_EFI_ERROR (Status);
 | |
|     } else {
 | |
|       //
 | |
|       // It is a normal PPI.
 | |
|       //
 | |
|       Status = InternalPeiInstallPpi (PeiServices, PpiList, TRUE);
 | |
|       ASSERT_EFI_ERROR (Status);
 | |
|     }
 | |
| 
 | |
|     if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) == EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) {
 | |
|       //
 | |
|       // Continue until the end of the PPI List.
 | |
|       //
 | |
|       break;
 | |
|     }
 | |
| 
 | |
|     PpiList++;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // If the EFI_SEC_HOB_DATA_PPI is in the list of PPIs passed to the PEI entry point,
 | |
|   // the PEI Foundation will call the GetHobs() member function and install all HOBs
 | |
|   // returned into the HOB list. It does this after installing all PPIs passed from SEC
 | |
|   // into the PPI database and before dispatching any PEIMs.
 | |
|   //
 | |
|   Status = PeiLocatePpi (PeiServices, &gEfiSecHobDataPpiGuid, 0, NULL, (VOID **)&SecHobDataPpi);
 | |
|   if (!EFI_ERROR (Status)) {
 | |
|     Status = SecHobDataPpi->GetHobs (SecHobDataPpi, &SecHobList);
 | |
|     if (!EFI_ERROR (Status)) {
 | |
|       Status = PeiInstallSecHobData (PeiServices, SecHobList);
 | |
|       ASSERT_EFI_ERROR (Status);
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
| 
 | |
|   Migrate PPI Pointers of PEI_CORE from temporary memory to permanent memory.
 | |
| 
 | |
|   @param PrivateData      Pointer to PeiCore's private data structure.
 | |
|   @param CoreFvHandle     Address of PEI_CORE FV Handle in temporary memory.
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| ConvertPeiCorePpiPointers (
 | |
|   IN  PEI_CORE_INSTANCE   *PrivateData,
 | |
|   IN  PEI_CORE_FV_HANDLE  *CoreFvHandle
 | |
|   )
 | |
| {
 | |
|   EFI_FV_FILE_INFO      FileInfo;
 | |
|   EFI_PHYSICAL_ADDRESS  OrgImageBase;
 | |
|   EFI_PHYSICAL_ADDRESS  MigratedImageBase;
 | |
|   UINTN                 PeiCoreModuleSize;
 | |
|   EFI_PEI_FILE_HANDLE   PeiCoreFileHandle;
 | |
|   VOID                  *PeiCoreImageBase;
 | |
|   VOID                  *PeiCoreEntryPoint;
 | |
|   EFI_STATUS            Status;
 | |
| 
 | |
|   PeiCoreFileHandle = NULL;
 | |
| 
 | |
|   //
 | |
|   // Find the PEI Core in the BFV in temporary memory.
 | |
|   //
 | |
|   Status =  CoreFvHandle->FvPpi->FindFileByType (
 | |
|                                    CoreFvHandle->FvPpi,
 | |
|                                    EFI_FV_FILETYPE_PEI_CORE,
 | |
|                                    CoreFvHandle->FvHandle,
 | |
|                                    &PeiCoreFileHandle
 | |
|                                    );
 | |
|   ASSERT_EFI_ERROR (Status);
 | |
| 
 | |
|   if (!EFI_ERROR (Status)) {
 | |
|     Status = CoreFvHandle->FvPpi->GetFileInfo (CoreFvHandle->FvPpi, PeiCoreFileHandle, &FileInfo);
 | |
|     ASSERT_EFI_ERROR (Status);
 | |
| 
 | |
|     Status = PeiGetPe32Data (PeiCoreFileHandle, &PeiCoreImageBase);
 | |
|     ASSERT_EFI_ERROR (Status);
 | |
| 
 | |
|     //
 | |
|     // Find PEI Core EntryPoint in the BFV in temporary memory.
 | |
|     //
 | |
|     Status = PeCoffLoaderGetEntryPoint ((VOID *)(UINTN)PeiCoreImageBase, &PeiCoreEntryPoint);
 | |
|     ASSERT_EFI_ERROR (Status);
 | |
| 
 | |
|     OrgImageBase      = (UINTN)PeiCoreImageBase;
 | |
|     MigratedImageBase = (UINTN)_ModuleEntryPoint - ((UINTN)PeiCoreEntryPoint - (UINTN)PeiCoreImageBase);
 | |
| 
 | |
|     //
 | |
|     // Size of loaded PEI_CORE in permanent memory.
 | |
|     //
 | |
|     PeiCoreModuleSize = (UINTN)FileInfo.BufferSize - ((UINTN)OrgImageBase - (UINTN)FileInfo.Buffer);
 | |
| 
 | |
|     //
 | |
|     // Migrate PEI_CORE PPI pointers from temporary memory to newly
 | |
|     // installed PEI_CORE in permanent memory.
 | |
|     //
 | |
|     ConvertPpiPointersFv (PrivateData, (UINTN)OrgImageBase, (UINTN)MigratedImageBase, PeiCoreModuleSize);
 | |
|   }
 | |
| }
 |