一、 编写SMM driver注册SMM服务
1. 使用SwDispatch
Demo1
EFI_STATUS
EFIAPI
CsdnSmiHandler (
IN EFI_HANDLE DispatchHandle,
IN CONST VOID *Context OPTIONAL,
IN OUT VOID *CommBuffer OPTIONAL,
IN OUT UINTN *CommBufferSize OPTIONAL
)
{
DEBUG((EFI_D_ERROR, "[CSDN] %a Enter\n", __FUNCTION__));
// 实现SMM服务
DEBUG((EFI_D_ERROR,"[CSDN] %a Exit\n", __FUNCTION__));
return EFI_SUCCESS;
}
Status = gSmst->SmmLocateProtocol(
&gEfiSmmSwDispatch2ProtocolGuid,
NULL,
(VOID **)&SwDispatch
);
SwContext.SwSmiInputValue = CSDN_SW_SMI_NO; //自定义SMI Number
ASSERT_EFI_ERROR(SwContext.SwSmiInputValue < SwDispatch->MaximumSwiValue);
Status = SwDispatch->Register(
SwDispatch,
CsdnSmiHandler,
&SwContext,
&SwSmiHandle
);
2. 使用gSmst->SmiHandlerRegister
Demo2
EFI_STATUS
EFIAPI
SmmCsdnSmiHandler (
IN EFI_HANDLE DispatchHandle,
IN CONST VOID *Context OPTIONAL,
IN OUT VOID *CommBuffer OPTIONAL,
IN OUT UINTN *CommBufferSize OPTIONAL
)
{
DEBUG((EFI_D_ERROR, "[CSDN] %a Enter\n", __FUNCTION__));
//可以将SMM RAM 内容copy回 communication buffer
DEBUG((EFI_D_ERROR,"[CSDN] %a Exit\n", __FUNCTION__));
return EFI_SUCCESS;
}
Status = gSmst->SmiHandlerRegister(
SmmCsdnSmiHandler,
&gCsdnSmmGuid,
&DispatchHandle
);
二、 触发SMM服务
IoWrite8 (0xB2, CSDN_SW_SMI_NO);
2. 使用SmmCommunication
访问SMM
Demo4
Status = SmmCommunication->Communicate(SmmCommunication, CommBuffer, &CommSize);