SMM ChildDispatch2 VS ChildDispatch

    UEFI 从 PI 1.1开始新增了SMM ChildDispatch2,和原本的ChildDispatch有诸多不同,现粗略列举以下四点。

    1. Protocol Install方式不同,ChildDispatch的protocol都是用BS->InstallProtocolInterface或BS->InstallMultiProtocolInterface安装,而ChildDispatch2的Protocol是用Smst2->SmmInstallProtocolInterface安装(Smst2也是从PI1.1新增的有别于Smst的Service,SmmInstallProtocolInterface就是Smst2提供的,Smst中没有这个函数,具体可以看EFI_SMM_SYSTEM_TABLE2和EFI_SMM_SYSTEM_TABLE的定义,或者参阅EFI spec2.3.1)

    2. 顺应上面的规则,既然install的方法不同,那么locate的方法也是不同的,ChildDispatch所Install的protocol要用BS->LocateProtocol来locate,ChildDispatch2的Protocol要用Smst2->SmmLocateProtocol来Locate,根本的原因是BS->InstallProtocolInterface和Smst2->SmmInstallProtocolInterface是把Protocol分别install到了自己所属的地方,所以这两种方式Install的protocol是无法用对方的LocateProtocol来locate的。

    3. ChildDispatch和ChildDispatch2的protocol的定义存在不同,以SWSMI dispatch举例来说,两个定义分别如下:

 

EFI_SMM_SW_DISPATCH_PROTOCOL :

typedef VOID (EFIAPI *EFI_SMM_SW_DISPATCH) (
	IN EFI_HANDLE					DispatchHandle,
	IN EFI_SMM_SW_DISPATCH_CONTEXT	*DispatchContext
);

typedef EFI_STATUS (EFIAPI *EFI_SMM_SW_REGISTER) (
	IN EFI_SMM_SW_DISPATCH_PROTOCOL	*This,
	IN EFI_SMM_SW_DISPATCH			DispatchFunction,
	IN EFI_SMM_SW_DISPATCH_CONTEXT	*DispatchContext,
	OUT EFI_HANDLE					*DispatchHandle
);

struct _EFI_SMM_SW_DISPATCH_PROTOCOL {
	EFI_SMM_SW_REGISTER		Register;
	EFI_SMM_SW_UNREGISTER	UnRegister;
	UINTN					MaximumSwiValue;
};

 

EFI_SMM_SW_DISPATCH2_PROTOCOL :

typedef EFI_STATUS (EFIAPI *EFI_SMM_HANDLER_ENTRY_POINT2) (
		IN EFI_HANDLE DispatchHandle,
		IN CONST VOID *Context OPTIONAL,
		IN OUT VOID *CommBuffer OPTIONAL,
		IN OUT UINTN *CommBufferSize OPTIONAL
);

typedef EFI_STATUS (EFIAPI *EFI_SMM_SW_REGISTER2)(
    IN  CONST EFI_SMM_SW_DISPATCH2_PROTOCOL  *This,
    IN        EFI_SMM_HANDLER_ENTRY_POINT2   DispatchFunction,
    IN  CONST EFI_SMM_SW_REGISTER_CONTEXT    *RegisterContext,
    OUT       EFI_HANDLE                     *DispatchHandle
);

struct _EFI_SMM_SW_DISPATCH2_PROTOCOL {
    EFI_SMM_SW_REGISTER2    Register;
    EFI_SMM_SW_UNREGISTER2  UnRegister;
    UINTN                   MaximumSwiValue;
};


    4. SMI Handler定义不同,从上面的两段代码的DispatchFunction可以看出,EFI_SMM_HANDLER_ENTRY_POINT2的Context定义变成了CONST VOID *,不是EFI_SMM_SW_DISPATCH的EFI_SMM_SW_DISPATCH_CONTEXT *,所以在Smi Handler里面如果要是用Context里面的数据,就要加上类型转换。还有不同的地方是EFI_SMM_HANDLER_ENTRY_POINT2新增加了两个参数,CommBuffer和CommBufferSize,所以SMI Handler的定义也要与之匹配。

    需要注意的地方是,由于新增了ChildDispatch2,所以BIOS code里面可能有ChildDispatch2,ChildDispatch,RC Dispatch三种SMM child dispatch共存,如果BIOS公司并没有处理好这三者的关系,就有可能存在SMI异常问题,这个时候可以着重看一下这三者的SmiDispatch函数是否存在问题,尤其是SmiClear的地方,因为这三者的执行是有顺序的,一般是ChildDispatch2,ChildDispatch,RC Dispatch,如果前一个Dispatch清除了本不应该被它清除的SMI,那么后面的dispatch就会有该执行的handler无法执行的问题,如果前一个Dispatch没有清除其本该清除SMI,后面的Dispatch就有可能判断异常,或者造成SMI一直重发问题。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值