UEFI学习(四)"/>
UEFI学习(四)
EC与SIO都可以通过4E/4F 2E/2F去访问特定的地址空间;
EC被访问的地址空间一般是0x400,默认是通过4E/4F访问;SIO默认是通过2E/2F访问,这个访问的通道在EC/SIO里面可以通过更改寄存器来更改;
图为SIO更改访问通道的寄存器:
既然知道了访问地址空间的通道是什么,接下来看Spec,查看通过通道访问的规范;
图中说明了寄存器的访问方式,需要先向2E写入,再从2F读取;
即:
//假设读的寄存器offset为0x01
IoWrite8(0x2E,0x01);
SIORead = IoRead8(0x2F);
因为0x2E/0x2F这两个通道地址我们需要经常用到,且有概率变更为4E/4F,所以可以定义一个宏定义,方便后续更改;
即:
#define SIO_Index 0x2E
#define SIO_Data 0x2FIoWrite8(SIO_Index,0x01);
SIORead = IoRead8(SIO_Data);
Spec中又提到,需要往写IO地址中写入两次0x87,进入扩展模式后,才能对数据进行更新;
退出扩展模式,需要往IO地址中写入0xAA;
即:
#define SIO_Index 0x2E
#define SIO_Data 0x2FIoWrite8(SIO_Index,0x87);
IoWrite8(SIO_Index,0x87);
IoWrite8(SIO_Index,0x01);
SIORead = IoRead8(SIO_Data);
IoWrite8(SIO_Index,0xAA);
访问SIO的方式已经知道了,接下来实际操作一下,用以上的code去访问并Print出SIO address的value;
我的code为:
//.inf
[Defines]INF_VERSION = 0x00010005BASE_NAME = SIOFILE_GUID = dd6c3ae0-296d-47d4-a491-d3c5b457059cMODULE_TYPE = UEFI_APPLICATIONVERSION_STRING = 1.0ENTRY_POINT = UefiMain[Sources]SIO.c[Packages]MdePkg/MdePkg.dec[LibraryClasses]UefiApplicationEntryPointUefiLibIoLib
//.h
#ifndef __SIO_H__
#define __SIO_H__#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Library/IoLib.h>extern UINTN ReadSIO(UINT8 offset);#endif //SIO_H
//.c
#include "SIO.h"#include "SIO.h"#define SIO_Index 0x2E
#define SIO_Data 0x2F#define SIO_Entry_EM 0x01
#define SIO_Break_EM 0x00EFI_STATUS
EFIAPI UefiMain (IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
{UINT8 SIO_ID_H;UINT8 SIO_ID_L;ExpansionMode(SIO_Entry_EM);SIO_ID_H = (UINT8)ReadSIO(0x20);SIO_ID_L = (UINT8)ReadSIO(0x21);ExpansionMode(SIO_Break_EM);Print(L"%x%x",SIO_ID_H,SIO_ID_L);return TRUE;
}UINTN ReadSIO(UINT8 offset)
{IoWrite8(SIO_Index,offset);return IoRead8(SIO_Data);
}UINTN ExpansionMode(UINT8 EMValue)
{if (EMValue == SIO_Entry_EM){IoWrite8(SIO_Index,0x87);IoWrite8(SIO_Index,0x87);}else if (EMValue == SIO_Break_EM){IoWrite8(SIO_Index,0xAA);}else {//return FALSE;}return TRUE;
}
code内读取的是EC Chip ID;
写SIO就直接调用IOWrite8,往Index里面写就行了,相对于读来说比较简单;
示例:
void WriteSIO(UINT8 offest,UINT8 value)
{IoWrite8(SIO_Index,offest);IoWrite8(SIO_Data,value);
}
下一篇继续说一下SIO的Read与Write中关于device和CONFIGURATION REGISTER的东西;
更多推荐
UEFI学习(四)
发布评论