一、 编写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服务
1. 使用IO
Demo3
IoWrite8 (0xB2, CSDN_SW_SMI_NO);
2. 使用SmmCommunication
访问SMM
Demo4
Status = SmmCommunication->Communicate(SmmCommunication, CommBuffer, &CommSize);