EFI基本概念之PPI

1 基本概念及用法

PPI是一个PEIM和另一个PEIM沟通的桥梁,它通过PPI描述符来描述其特性。PPI描述符是一个数据结构。

 

这个数据结构定义如下:

typedef struct {

  UINTN    Flags;

  EFI_GUID *Guid;

  VOID     *Ppi;

}EFI_PEI_PPI_DESCRIPTOR;

    Flags描述了PPI的特征。

    Guid是这个PPI的名字。

    Ppi是service的实体,这个是PPI的真正意义。

   

    既然称其为桥梁,那么就有桥梁的两端。桥梁两端的作用是,一端作为生产者,Install PPI,另一端作为消费者,使用Locate PPI,并且使用它。下面来看一个实例:

1.1  生产者

在UDK2014\MyWorkSpace\MdeModulePkg\Core\DxeIplPeim\DxeLoad.c

EFI_STATUS

EFIAPI

PeimInitializeDxeIpl (

  IN       EFI_PEI_FILE_HANDLE  FileHandle,

  IN CONSTEFI_PEI_SERVICES     **PeiServices

  )

{

   

    Status =PeiServicesInstallPpi (mPpiList);

   

}

分析:PeimInitializeDxeIpl是Dxeload Pei模块的入口,在此函数中PeiServicesInstallPpi(mPpiList)将mPpiList中所有PPI描述符注册到PPIdatabase中。

mPpiList定义如下:

CONSTEFI_PEI_PPI_DESCRIPTOR mPpiList[] = {

  {

    EFI_PEI_PPI_DESCRIPTOR_PPI,

    &gEfiDxeIplPpiGuid,

    (VOID *) &mDxeIplPpi

  },

  {

    (EFI_PEI_PPI_DESCRIPTOR_PPI |EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),

    &gEfiPeiDecompressPpiGuid,

    (VOID *) &mDecompressPpi

  }

};

这个mPpiList数组包含两个PPI描述符。其中第一个Ppi描述符是加载Dxe core用的。

其定义为:

CONST EFI_DXE_IPL_PPImDxeIplPpi = {

  DxeLoadCore

};

1.2  消费者

在UDK2014\MyWorkSpace\MdeModulePkg\Core\Pei\PeiMain\PeiMain.c

Status = PeiServicesLocatePpi (

             &gEfiDxeIplPpiGuid,

             0,

             NULL,

             (VOID **)&TempPtr.DxeIpl

        );

通过此,可找到mDxeIplPpi,然后调用DxeLoadCore进而进入了DXE阶段。

 

2. PPI服务函数

    PeiServicesInstallPpi()的真正执行者是InstallPpi(PeiServices, PpiList)

    PeiServicesLocatePpi()的真正执行者是LocatePpi(PeiServices, Guid, Instance, PpiDescriptor, Ppi)

    这两个是PPI最基本的服务函数。下面解读一下其原型。

 

2.1 PeiInstallPpi

EFI_STATUS

EFIAPI

PeiInstallPpi (

  IN CONSTEFI_PEI_SERVICES        **PeiServices,

  IN CONSTEFI_PEI_PPI_DESCRIPTOR  *PpiList

  )

{

    Step1,由PeiSerivces参数找到PEI Core实例,并找到PPI Database的空闲节点。

    Step2,如果PPIDatabase已满,则退出。

    Step3,如果PPI描述符的Flags标志无EFI_PEI_PPI_DESCRIPTOR_PPI属性,则退出。

    Step4,将PpiList的第一个PPI描述符注册到PPI DataBase中。

    Step5,如果此PPI描述符的Flags有EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST属性,则注册结束,执行Step6,否则跳到Step2。

    Step6,如果新注册的PPI描述符,有其相同GUID的NOTIFY PPI被注册过,则调用其NotifyPPI函数。

}

 

 

 

2.2 PeiLocatePpi

EFI_STATUS

EFIAPI

PeiLocatePpi (

  IN CONSTEFI_PEI_SERVICES        **PeiServices,

  IN CONSTEFI_GUID                *Guid,

  IN UINTN                         Instance,

  IN OUTEFI_PEI_PPI_DESCRIPTOR   **PpiDescriptor,

  IN OUT VOID                      **Ppi

  )

{

    Step1,根据PeiServices找到PEI Core实例

    Step2,在注册过的PPI描述符中,找到描述符Guid与参数中Guid相匹配的PPI描述符项。根据Instance,确定找第几个PPI描述符。如果PpiDescriptor不为空,则将PPI描述符赋给PpiDescriptor;如果Ppi不为空,则将PPI描述符的Ppi字段赋给该Ppi参数。

    Step3,如果Step2有找到相应的PPI,返回成功标志;否则返回没找到标志。

}

  • 8
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值