⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ppi.c

📁 EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是EFI BIOS源代码中的与平台无关部分的代码
💻 C
📖 第 1 页 / 共 2 页
字号:
  PeiServices   - Pointer to the PEI Service Table
  Guid          - Pointer to GUID of the PPI.
  Instance      - Instance Number to discover.
  PpiDescriptor - Pointer to reference the found descriptor. If not NULL,
                returns a pointer to the descriptor (includes flags, etc)
  Ppi           - Pointer to reference the found PPI

Returns:

  Status -  EFI_SUCCESS   if the PPI is in the database           
            EFI_NOT_FOUND if the PPI is not in the database
--*/
{
  PEI_CORE_INSTANCE   *PrivateData;
  INTN                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.PpiListEnd; Index++) {
    TempPtr = PrivateData->PpiData.PpiListPtrs[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;
}


EFI_STATUS
EFIAPI
PeiNotifyPpi (
  IN EFI_PEI_SERVICES           **PeiServices,
  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyList
  )
/*++

Routine Description:

  Install a notification for a given PPI.

Arguments:

  PeiServices - Pointer to the PEI Service Table
  NotifyList  - Pointer to list of Descriptors to notify upon.

Returns:

  Status - EFI_SUCCESS           if successful
           EFI_OUT_OF_RESOURCES  if no space in the database
           EFI_INVALID_PARAMETER if not a good decriptor

--*/
{
  PEI_CORE_INSTANCE                *PrivateData;
  INTN                             Index;
  INTN                             NotifyIndex;
  INTN                             LastCallbackNotify;
  EFI_PEI_NOTIFY_DESCRIPTOR        *NotifyPtr;
  UINTN                            NotifyDispatchCount;


  NotifyDispatchCount = 0;

  if (NotifyList == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);

  Index = PrivateData->PpiData.NotifyListEnd;
  LastCallbackNotify = Index;

  //
  // 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 (;;) {
    //
    // Since PpiData is used for NotifyList and InstallList, max resource
    // is reached if the Install reaches the PpiList
    //
    if (Index == PrivateData->PpiData.PpiListEnd - 1) {
      return  EFI_OUT_OF_RESOURCES;
    }
    
    //
    // If some of the PPI data is invalid restore original Notify PPI database value
    //
    if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_TYPES) == 0) {
        PrivateData->PpiData.NotifyListEnd = LastCallbackNotify;
        PEI_DEBUG((PeiServices, EFI_D_INFO, "ERROR -> InstallNotify: %g %x\n", NotifyList->Guid, NotifyList->Notify));
      return  EFI_INVALID_PARAMETER;
    }
     
    if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH) != 0) {
      NotifyDispatchCount ++; 
    }        
    
    PrivateData->PpiData.PpiListPtrs[Index].Notify = NotifyList;      
   
    PrivateData->PpiData.NotifyListEnd--;
    PEI_DEBUG((PeiServices, EFI_D_INFO, "Register PPI Notify: %g\n", NotifyList->Guid));
    if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) ==
        EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) {
      break;
    }
    //
    // Go the next descriptor. Remember the NotifyList moves down.
    //
    NotifyList++;
    Index--;
  }
 
  //
  // If there is Dispatch Notify PPI installed put them on the bottom 
  //
  if (NotifyDispatchCount > 0) {
    for (NotifyIndex = LastCallbackNotify; NotifyIndex > PrivateData->PpiData.NotifyListEnd; NotifyIndex--) {             
      if ((PrivateData->PpiData.PpiListPtrs[NotifyIndex].Notify->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH) != 0) {
        NotifyPtr = PrivateData->PpiData.PpiListPtrs[NotifyIndex].Notify;
        
        for (Index = NotifyIndex; Index < PrivateData->PpiData.DispatchListEnd; Index++){
          PrivateData->PpiData.PpiListPtrs[Index].Notify = PrivateData->PpiData.PpiListPtrs[Index + 1].Notify;
        }
        PrivateData->PpiData.PpiListPtrs[Index].Notify = NotifyPtr;
        PrivateData->PpiData.DispatchListEnd--;                
      }
    }
    
    LastCallbackNotify -= NotifyDispatchCount;        
  }
  
  //
  // Dispatch any callback level notifies for all previously installed PPIs.
  //
  DispatchNotify (
    PeiServices,
    EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
    0,
    PrivateData->PpiData.PpiListEnd,
    LastCallbackNotify,
    PrivateData->PpiData.NotifyListEnd
    );
  
  
  return  EFI_SUCCESS;
}


VOID
ProcessNotifyList (
  IN EFI_PEI_SERVICES    **PeiServices
  )
/*++

Routine Description:

  Process the Notify List at dispatch level.

Arguments:

  PeiServices - Pointer to the PEI Service Table

Returns:

--*/

{
  PEI_CORE_INSTANCE       *PrivateData;
  INTN                    TempValue;

  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);

 
  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 previouly installed PPIs.
    // Use "while" instead of "if" since DispatchNotify can modify 
    // DispatchListEnd (with NotifyPpi) so we have to iterate until the same.
    //
    while (PrivateData->PpiData.LastDispatchedNotify != PrivateData->PpiData.DispatchListEnd) {
      TempValue = PrivateData->PpiData.DispatchListEnd;
      DispatchNotify (
        PeiServices,
        EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH,
        0,
        PrivateData->PpiData.LastDispatchedInstall,
        PrivateData->PpiData.LastDispatchedNotify,
        PrivateData->PpiData.DispatchListEnd
        );
      PrivateData->PpiData.LastDispatchedNotify = 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 DispatchNotify can modify 
    // PpiListEnd (with InstallPpi) so we have to iterate until the same.
    //
    while (PrivateData->PpiData.LastDispatchedInstall != PrivateData->PpiData.PpiListEnd) {
      TempValue = PrivateData->PpiData.PpiListEnd;
      DispatchNotify (
        PeiServices,
        EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH,
        PrivateData->PpiData.LastDispatchedInstall,
        PrivateData->PpiData.PpiListEnd,
        MAX_PPI_DESCRIPTORS-1,
        PrivateData->PpiData.DispatchListEnd
        );
      PrivateData->PpiData.LastDispatchedInstall = TempValue;
    }
    
    if (PrivateData->PpiData.LastDispatchedNotify == PrivateData->PpiData.DispatchListEnd) {
      break;
    }
  } 
  return;
}

VOID
DispatchNotify (
  IN EFI_PEI_SERVICES    **PeiServices,
  IN UINTN               NotifyType,
  IN INTN                InstallStartIndex,
  IN INTN                InstallStopIndex,
  IN INTN                NotifyStartIndex,
  IN INTN                NotifyStopIndex
  )
/*++

Routine Description:

  Dispatch notifications.

Arguments:

  PeiServices         - Pointer to the PEI Service Table
  NotifyType          - Type of notify to fire.
  InstallStartIndex   - Install Beginning index.
  InstallStopIndex    - Install Ending index.
  NotifyStartIndex    - Notify Beginning index.
  NotifyStopIndex    - Notify Ending index.

Returns:  None

--*/

{
  PEI_CORE_INSTANCE       *PrivateData;
  INTN                   Index1;
  INTN                   Index2;
  EFI_GUID                *SearchGuid;
  EFI_GUID                *CheckGuid;
  EFI_PEI_NOTIFY_DESCRIPTOR   *NotifyDescriptor;

  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);

  //
  // Remember that Installs moves up and Notifies moves down.
  //
  for (Index1 = NotifyStartIndex; Index1 > NotifyStopIndex; Index1--) {
    NotifyDescriptor = PrivateData->PpiData.PpiListPtrs[Index1].Notify;

    CheckGuid = NotifyDescriptor->Guid;

    for (Index2 = InstallStartIndex; Index2 < InstallStopIndex; Index2++) {
      SearchGuid = PrivateData->PpiData.PpiListPtrs[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])) {
        PEI_DEBUG (
          (
            PeiServices, 
            EFI_D_INFO, 
            "Notify: PPI Guid: %g, Peim notify entry point: %x\n", 
            SearchGuid, 
            NotifyDescriptor->Notify
          )
        );
        NotifyDescriptor->Notify (
                            PeiServices,
                            NotifyDescriptor,
                            (PrivateData->PpiData.PpiListPtrs[Index2].Ppi)->Ppi
                            );
      }
    }
  }

  return;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -