Search This Blog

Tuesday, November 1, 2011

Trigger SMI to Do CpuIo Cause System Hangs Up Under Windows

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);
}

1 comment:

  1. This solution is wrong too, :) You should use gSmst->SmmIo

    ReplyDelete