UEFI学习(四)

编程入门 行业动态 更新时间:2024-10-13 20:15:15

<a href=https://www.elefans.com/category/jswz/34/1737712.html style=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学习(四)

本文发布于:2024-03-13 05:53:50,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1733324.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:UEFI

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!