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

📄 ppi.c

📁 EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是EFI BIOS源代码中的与平台无关部分的代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*++

Copyright (c) 2004 - 2005, Intel Corporation                                                         
All rights reserved. This program and the accompanying materials                          
are licensed and made available under the terms and conditions of the BSD License         
which accompanies this distribution.  The full text of the license may be found at        
http://opensource.org/licenses/bsd-license.php                                            
                                                                                          
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             

Module Name:

  Ppi.c

Abstract:

  EFI PEI Core PPI services

Revision History

--*/

#include "Tiano.h"
#include "PeiCore.h"
#include "PeiLib.h"

VOID
InitializePpiServices (
  IN EFI_PEI_SERVICES  **PeiServices,
  IN PEI_CORE_INSTANCE *OldCoreData
  )
/*++

Routine Description:

  Initialize PPI services.

Arguments:

  PeiServices - The PEI core services table.
  OldCoreData - Pointer to the PEI Core data.
                NULL if being run in non-permament memory mode.

Returns:
  Nothing

--*/
{
  PEI_CORE_INSTANCE                    *PrivateData;
  
  if (OldCoreData == NULL) {
    PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);

    PrivateData->PpiData.NotifyListEnd = MAX_PPI_DESCRIPTORS-1;
    PrivateData->PpiData.DispatchListEnd = MAX_PPI_DESCRIPTORS-1;
    PrivateData->PpiData.LastDispatchedNotify = MAX_PPI_DESCRIPTORS-1;
  }
 
  return;   
}

VOID
ConvertPpiPointers (
  IN EFI_PEI_SERVICES            **PeiServices,
  IN EFI_HOB_HANDOFF_INFO_TABLE  *OldHandOffHob,
  IN EFI_HOB_HANDOFF_INFO_TABLE  *NewHandOffHob
  )
/*++

Routine Description:

  Convert PPI pointers after the Hob list was migrated from the CAR stack
  to PEI installed memory.

Arguments:

  PeiServices   - The PEI core services table.
  OldHandOffHob - The old handoff HOB list.
  NewHandOffHob - The new handoff HOB list.

Returns:

  None.
    
--*/
{
  PEI_CORE_INSTANCE     *PrivateData;
  UINT8                 Index;
  PEI_PPI_LIST_POINTERS *PpiPointer;
  UINTN                 Fixup;

  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);

  Fixup = (UINTN)NewHandOffHob - (UINTN)OldHandOffHob;
  
  for (Index = 0; Index < MAX_PPI_DESCRIPTORS; Index++) {
    if (Index < PrivateData->PpiData.PpiListEnd ||
        Index > PrivateData->PpiData.NotifyListEnd) {
      PpiPointer = &PrivateData->PpiData.PpiListPtrs[Index];
      
      if (((UINTN)PpiPointer->Raw < (UINTN)OldHandOffHob->EfiFreeMemoryBottom) && 
          ((UINTN)PpiPointer->Raw >= (UINTN)OldHandOffHob)) {
        //
        // Convert the pointer to the PEIM descriptor from the old HOB heap
        // to the relocated HOB heap.
        //
        PpiPointer->Raw = (VOID *) ((UINTN)PpiPointer->Raw + Fixup);

        //
        // Only when the PEIM descriptor is in the old HOB should it be necessary
        // to try to convert the pointers in the PEIM descriptor
        //
        
        if (((UINTN)PpiPointer->Ppi->Guid < (UINTN)OldHandOffHob->EfiFreeMemoryBottom) && 
            ((UINTN)PpiPointer->Ppi->Guid >= (UINTN)OldHandOffHob)) {
          //
          // Convert the pointer to the GUID in the PPI or NOTIFY descriptor
          // from the old HOB heap to the relocated HOB heap.
          //
          PpiPointer->Ppi->Guid = (VOID *) ((UINTN)PpiPointer->Ppi->Guid + Fixup);
        }

        //
        // Assume that no code is located in the temporary memory, so the pointer to
        // the notification function in the NOTIFY descriptor needs not be converted.
        //
        if (Index < PrivateData->PpiData.PpiListEnd &&
            (UINTN)PpiPointer->Ppi->Ppi < (UINTN)OldHandOffHob->EfiFreeMemoryBottom &&
            (UINTN)PpiPointer->Ppi->Ppi >= (UINTN)OldHandOffHob) {
            //
            // Convert the pointer to the PPI interface structure in the PPI descriptor
            // from the old HOB heap to the relocated HOB heap.
            //
            PpiPointer->Ppi->Ppi = (VOID *) ((UINTN)PpiPointer->Ppi->Ppi+ Fixup);   
        }
      }
    }
  }
}


EFI_STATUS
EFIAPI
PeiInstallPpi (
  IN EFI_PEI_SERVICES        **PeiServices,
  IN EFI_PEI_PPI_DESCRIPTOR  *PpiList
  )
/*++

Routine Description:

  Install PPI services.

Arguments:

  PeiServices - Pointer to the PEI Service Table
  PpiList     - Pointer to a list of PEI PPI Descriptors.

Returns:

    EFI_SUCCESS             - if all PPIs in PpiList are successfully installed.
    EFI_INVALID_PARAMETER   - if PpiList is NULL pointer
    EFI_INVALID_PARAMETER   - if any PPI in PpiList is not valid
    EFI_OUT_OF_RESOURCES    - if there is no more memory resource to install PPI

--*/
{
  PEI_CORE_INSTANCE *PrivateData;
  INTN              Index;
  INTN              LastCallbackInstall;


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

  PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);

  Index = PrivateData->PpiData.PpiListEnd;
  LastCallbackInstall = 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 (;;) {
    //
    // Since PpiData is used for NotifyList and InstallList, max resource
    // is reached if the Install reaches the NotifyList
    //
    if (Index == PrivateData->PpiData.NotifyListEnd + 1) {
      return  EFI_OUT_OF_RESOURCES;
    }
    //
    // 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) {
      PrivateData->PpiData.PpiListEnd = LastCallbackInstall;
      PEI_DEBUG((PeiServices, EFI_D_INFO, "ERROR -> InstallPpi: %g %x\n", PpiList->Guid, PpiList->Ppi));
      return  EFI_INVALID_PARAMETER;
    } 

    PEI_DEBUG((PeiServices, EFI_D_INFO, "Install PPI: %g\n", PpiList->Guid)); 
    PrivateData->PpiData.PpiListPtrs[Index].Ppi = PpiList;    
    PrivateData->PpiData.PpiListEnd++;
    
    //
    // Continue until the end of the PPI List.
    //
    if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) ==  
        EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) {
      break;
    }
    PpiList++;
    Index++;
  }

  //
  // Dispatch any callback level notifies for newly installed PPIs.
  //
  DispatchNotify (
    PeiServices,
    EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
    LastCallbackInstall,
    PrivateData->PpiData.PpiListEnd,
    PrivateData->PpiData.DispatchListEnd,                 
    PrivateData->PpiData.NotifyListEnd
    );


  return EFI_SUCCESS;
}


EFI_STATUS
EFIAPI
PeiReInstallPpi (
  IN EFI_PEI_SERVICES        **PeiServices,
  IN EFI_PEI_PPI_DESCRIPTOR  *OldPpi,
  IN EFI_PEI_PPI_DESCRIPTOR  *NewPpi
  )
/*++

Routine Description:

  Re-Install PPI services.

Arguments:

  PeiServices - Pointer to the PEI Service Table
  OldPpi      - Pointer to the old PEI PPI Descriptors.
  NewPpi      - Pointer to the new PEI PPI Descriptors.

Returns:

  EFI_SUCCESS           - if the operation was successful
  EFI_INVALID_PARAMETER - if OldPpi or NewPpi is NULL
  EFI_INVALID_PARAMETER - if NewPpi is not valid
  EFI_NOT_FOUND         - if the PPI was not in the database

--*/
{
  PEI_CORE_INSTANCE   *PrivateData;
  INTN                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.PpiListEnd; Index++) {
    if (OldPpi == PrivateData->PpiData.PpiListPtrs[Index].Ppi) {
      break;
    }
  }
  if (Index == PrivateData->PpiData.PpiListEnd) {
    return EFI_NOT_FOUND;
  }

  //
  // Remove the old PPI from the database, add the new one.
  // 
  PEI_DEBUG((PeiServices, EFI_D_INFO, "Reinstall PPI: %g\n", NewPpi->Guid));
  PrivateData->PpiData.PpiListPtrs[Index].Ppi = NewPpi;

  //
  // Dispatch any callback level notifies for the newly installed PPI.
  //
  DispatchNotify (
    PeiServices,
    EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
    Index,
    Index+1,
    PrivateData->PpiData.DispatchListEnd,                 
    PrivateData->PpiData.NotifyListEnd
    );


  return EFI_SUCCESS;
}


EFI_STATUS
EFIAPI
PeiLocatePpi (
  IN EFI_PEI_SERVICES        **PeiServices,
  IN EFI_GUID                *Guid,
  IN UINTN                   Instance,
  IN OUT EFI_PEI_PPI_DESCRIPTOR  **PpiDescriptor,
  IN OUT VOID                **Ppi
  )
/*++

Routine Description:

  Locate a given named PPI.

Arguments:

⌨️ 快捷键说明

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