LPC相关知识

LPC(Low Pin Count)接口时Intel推出的一种低IO数目的外设接口,用于连接SuperIO、Flash等LPC设备

操作说明:

使用LPC功能前,需要先配置相关PAD服用寄存器,将对应PAD配置到对应LPC功能上,才可使用LPC功能:

1、判断想要访问设备的接口访问类型,然后通过APB接口地址的设备类型寄存器发送对应的IO、FIRMWARE Memory、Memory、DMA请求。

2、通过nu_serirq_config[31]判断是4字节读取还是单字节读取。

首先获取LPC的基地址,如基地址为0x000_20000000

再去查看寄存器,以下面的代码为例子:

    MmioWrite32(0x27ffffcc, 1);
    MmioWrite32(0x27ffffe8, 0x80000000);
    MmioWrite32(0x27ffffd8, 0);
    MmioWrite32(0x27ffffd4, 0);

第一个偏移地址写1,具体可以参考LPC协议文档

主要是BIT3-BIT0:

000为IO read,001为IO write,010为memory read......

第二个偏移地址写值0x80000000,也就是上文说的nu_serirq_config[31],描述如下:

配置寄存器(bit31:针对读数据每次读4 bytes数据使能标志(1’b1:读1byte); bit1~0:起始周期配置(2’b11:8;2’b10:6;否则4,默认4 clk), bit2:串行中断模式配置默认连续模式 默认为连续模式), bit3~4:支持的串行中断设备数量(2‘b01 代表32 否则16默认16)

 第三个中断屏蔽寄存器,第四个为配置启动周期寄存器

写完上面的,咱们就可以通过LPC进行IO读写操作了,以EC与BIOS通信为例

EC提供256字节的可被系统读写的RAM空间,EC的资源在该RAM空间映射,通过访问对应偏移(0x00~0xFF),即可操作对应的资源。了解EC的特别是ITE的,都清楚62、66端口,如果BIOS想要获取EC寄存器中的值,那么需要在基地址的基础上再加上62、66

比如:

#define LPC_MEM_BASE    0x20000000
#define EC_COMMAND_PORT 0x66 | LPC_MEM_BASE
#define EC_DATA_PORT    0x62 | LPC_MEM_BASE

后续EC读写代码如下:

#include <Base.h>
#include <Library/BaseLib.h>
#include <Library/IoLib.h>
#include <Library/EcLib.h>
#include <Library/DebugLib.h>
#include <Library/TimerLib.h>


EFI_STATUS
EcIbFree ()
{
  EFI_STATUS    Status = EFI_SUCCESS;
  UINTN         Count  = 10000;
  UINT8         Data;

  do {
    Data = MmioRead8(EC_COMMAND_PORT);
    if ((Data & EC_IBF) == 0) {
      break;
    }
    MicroSecondDelay (1000);
    Count --;
  } while (Count);

  if (Count == 0) {
    Status = EFI_TIMEOUT;
  }

  return Status;
}

EFI_STATUS
EcObFull()
{
  EFI_STATUS    Status = EFI_SUCCESS;
  UINTN         Count  = 10000;
  UINT8         Data;
  
  do {
    Data = MmioRead8(EC_COMMAND_PORT);
    if (Data & EC_OBF) {
      break;
    }
    MicroSecondDelay (1000);
    Count --;
  } while (Count);

  if (Count == 0) {
    Status = EFI_TIMEOUT;
  }

  return Status;
}


EFI_STATUS
EcWriteCmd (
  UINT8    cmd
)
{
  while((MmioRead8(EC_COMMAND_PORT)) & EC_OBF) {
    MmioRead8(EC_DATA_PORT);
  }

  EcIbFree();
  MmioWrite8(EC_COMMAND_PORT, cmd);
  EcIbFree();
  return EFI_SUCCESS;
}


EFI_STATUS
EcWriteData (
  UINT8    data
)
{
  EcIbFree();
  MmioWrite8(EC_DATA_PORT, data);
  EcIbFree();
  return EFI_SUCCESS;
}


EFI_STATUS
EcReadData (
  UINT8   *pData
)
{

  if (EFI_ERROR(EcObFull())) 
    return EFI_DEVICE_ERROR;
    
  *pData=MmioRead8(EC_DATA_PORT);
  return EFI_SUCCESS;
}

EFI_STATUS
EcReadMem (
  UINT8  Index,
  UINT8  *Data
)
{
  UINT8  cmd = 0x80;
  EcWriteCmd (cmd);
  EcWriteData(Index);
  EcReadData(Data);
  return EFI_SUCCESS;
}

EFI_STATUS
EcWriteMem (
  UINT8  Index,
  UINT8  Data
)
{
  UINT8  cmd = 0x81;
  EcWriteCmd (cmd);
  EcWriteData(Index);
  EcWriteData(Data);
  return EFI_SUCCESS;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值