eSPI 通讯一般来说无需特别关注,因为通讯都是 PCH(eSPI_Master)和 EC(eSPI_Slave)硬件完成的,软件不参与。
但是实际开发中经常会遇到 SLP_S3/4 不拉高导致无法开机,8042键盘无功能,6266无法通信等问题。因此了解常见的通讯流程,分析抓取的 eSPI 通讯数据包,对异常定位有很大的帮助。
eSPI 初始化通讯
通用参数配置
eSPI_Master 第一步会读取 eSPI_Slave 的 0x08 寄存器获取 eSPI_Slave 所支持的通讯能力。有如下参数:
I/O Mode Support | Single I/O、Single and Dual I/O、Single and Quad I/O、Single, Dual and Quad I/O |
---|---|
Open Drain Alert# Supported | Open-drain Alert# |
Maximum Frequency Supported | 20、25、33、50、66MHz |
Channel Supported | Peripheral、Virtual Wire、OOB、Flash、platform specific channels |
接着 eSPI_Master 会在合适的时候写 eSPI_Slave 的 0x08 寄存器,以配置不同的通讯参数。如下表:
CRC Checking Enable |
---|
Response Modifier Enable |
Alert Mode Select |
I/O Mode Select |
Open Drain Alert# Select |
Operating Frequency Select |
Maximum WAIT STATE Allowed |
上图的配置参数中就选择了 Quad Mode IO、66MHz 通讯,图中也可以发现紧接着一笔数据通讯变成 66MHz、Quad IO mode。
通道参数配置
eSPI 支持4个 Channel,即 Peripheral(0x10)、Virtual wire(0x20)、OOB(0x30)、Flash(0x40)。
此处仅以 Peripheral Channel(0x10)配置为例。
通道参数配置,也遵循先读后写原则。即 eSPI_Master 先读取 eSPI_Slave 通道配置寄存器,然后再改写配置寄存器。
Peripheral Channel (0x10)涉及的参数如下表
Peripheral Channel Maximum Read Request Size | R/W |
---|---|
Peripheral Channel Maximum Payload Size | R/W |
Peripheral Channel Maximum Payload Size Supported | RO |
Bus Master Enable | R/W |
Peripheral Channel Ready | RO |
Peripheral Channel Enable | R/W |
eSPI_Master 读取 Peripheral Channel 0x10 寄存器,发现通道已经 Ready
即 Channel Ready=1。
eSPI_Master 写 Peripheral Channel 0x10 寄存器,写Channel Enable=1。
Virtual Wire 通讯
Virtual Wire Channel 包揽了 PCH 和 EC 之间所有的信号传递,包括 SCI、IRQ、SLP Signal。数据传递可以是 eSPI_Master 到 eSPI_Slave,也可以反向。
当然反向通信,需要 eSPI_Slave 先发起 Alert# 信号,等待 eSPI_Master 查询Status Reg,再根据状态发起不同的命令读取 eSPI_Slave 的数据。
Master 向 Slave 发送 pin status。
如上图,eSPI_Master 使用 PUT_VWIRW(04)命令,附带数据包,
向 eSPI_Slave 通知 PCH 虚拟引脚状态。
Length=03,即传递了 4组 Virtual Wire 信号。
index=02,Data=74,即传递了 System Event-2。
index=03,Data=30,即传递了 System Event-3。
index=41,Data=B9,即传递了 Platform Specific-41。
index=42,Data=31,即传递了 Platform Specific-41。
如下图是 System Event Virtual Wire 2 的数据解析。其他 System Event 解析一致。因此 Index=2,data=74,即表示 SLP_S3/4/5 有效,SLP_S3、SLP_S4 为低电平,SLP_S5 为高电平。
Slave 向 Master 发送 Signal status。
如上图,eSPI 通讯采用 Single IO,因此 Alert# 和 IO-1 复用。上图 IO-1 最开始的 230ns 即为 eSPI_Slave 发起的 Alert# 信号。
eSPI_Master 接到 Alert# 后,首先发送 GET_STATUS(25)命令,获取 eSPI_Slave 的状态,可以看到 SLave 端回复的 status 是 0x14F。
即表示 PC/NP/VWIRE/OOB buffer 都是空,BIT6 VWIRE_AVAIL 置位即表示有 Virtual Wire 需要 Master 端读取。
Master 发送 GET_VWIRE(05)命令读取 Virtual Wire 状态,Slave 端返回 System Event-5 的状态。index=5,data=99,即表示
SLAVE_BOOT_LOAD_DONE 和 SLAVE_BOOT_LOAD_STATUS 有效,同时置位,即表示 Slave 端成功完成了 Flash 的访问。
Slave 向 Master 发送 pin status。
如上图,就是 Slave 端向 Master 端发送 SCI 的数据包。
index=6,data=10,即表示 SCI 信号有效,同时拉低。
当然,等待 Master 端响应 SCI 后,Slave 必须发送一个 SCI 拉高的数据包。
Slave 向 Master 发送 IRQ。
IRQ 在 eSPI Virtual wire 里面划分为 Interrupt Event。占用 Virtual Wire Index 0和1。
如上图,Master 接到 Alert# 信号后,读取 Virtual 状态。Slave 返回 IRQ-1信号。index=00,data=81,即表示 IRQ-1 拉高(注意,此处 IRQ-1 是高触发)。IRQ-1 信号同样的需要 Slave 端再次发送数据包拉低。
Peripheral Channel IO 通讯
Keyboard 通讯
理解上述 IRQ-1 触发原理后,EC 端的键值发送就非常容易理解了。流程如下:
- 键盘按键按下后,EC 完成扫描以及转换过程,最终生成一个 ScanCode 写入 IO-60 数据寄存器。
- IO-60 的写入动作,会触发 EC 硬件自动发送一个 IRQ-1 通知 PCH,有键盘中断发生。
- PCH 识别到 IRQ-1 后,会读取 IO-64,查看 OBF 状态,以判断 IO-60 是否有数据需要读取。
- 紧接着 PCH 会读取 IO-60 获取 ScanCode。
键盘一次按键分为“Press” 和 “Release”,即按下和松开都会给 PCH 端发送一个 ScanCode。如下示例是 “A” 键操作,对应 ScanCode 是 1E 和 9E。
按键按下数据包。
按键松开数据包
Q_Event 通讯
EC 发送 Q_Event(A0)流程:
- EC 拉低 SCI,同时置位 66 寄存器的 BIT5,即 SCI_EVT。
- PCH 读取 66,发现 SCI_EVT 置位,发送 0x84 命令查询 Q_Event。
- EC 拉高 SCI,同时清除 66寄存器 BIT5。
- EC 处理 0x84 查询命令,把 Q_Event 队列第一个 num(A0) 写入 62 寄存器
- EC 拉低 SCI,置位 66寄存器 BIT0,即 OBF
- PCH 读取 66 ,发现 OBF 置位,读取 62 寄存器,获得 Q_Event Num(A0)。
- EC 拉高 SCI。
上述就是常见 eSPI 通讯数据包的分析。
-
寄存器
+关注
关注
31文章
5342浏览量
120297 -
SPI
+关注
关注
17文章
1706浏览量
91551 -
通讯
+关注
关注
9文章
902浏览量
34897 -
数据包
+关注
关注
0文章
261浏览量
24390
发布评论请先 登录
相关推荐
评论