We would like to use CpuIo protocol and must locate it first.
Status = gBS->LocateProtocol (&gEfiCpuIoProtocolGuid, NULL, &CpuIo);
There is a question here, system is entered windows that has exited boot service.
Therefore, we locate this protocol will cause system hangs up.
To avoid this, we should create a global variable to save the CpuIo pointer when system during POST phase.
EFI_CPU_IO_PROTOCOL *mCpuIo = NULL;
EFI_DRIVER_ENTRY_POINT (SctCpuIoPointSave)
EFI_STATUS
SctCpuIoPointSave (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
EFI_HANDLE Handle;
DxeInitializeDriverLib (ImageHandle, SystemTable);
//
// Locate CpuIo protocol.
//
Status = gBS->LocateProtocol ( &gEfiCpuIoProtocolGuid, NULL, &mCpuIo ) ;
return Status;
} // EnteyPoint.
Just need to call your function in SMI code to use CpuIo.
For example,
VOID
ShowPort80 (VOID)
{
EFI_STATUS Status ;
UINT8 Data ;
Data = 0x99;
Status = mCpuIo->Io.Write (
mCpuIo,
EfiCpuIoWidthUint8,
0x80,
1,
&Data);
ASSERT_EFI_ERROR (Status);
}
This solution is wrong too, :) You should use gSmst->SmmIo
ReplyDelete