上一期内容我们介绍了eSPI Spec中所定义Perpheral Channel的相关内容,这一期将继续探索eSPI Spec中Run-time Flash Access Channel的相关内容。还是和上一期内容一样,先不着急介绍具体的Bus Protocol,本期内容只是从原理和作用上阐述Flash Channel在x86 chipset与eSPI Slave之前所起的作用。
先抛出一个概念,eSPI Flash Channel解决的是如何让Chipset和eSPI Slave实时共享SPI Flash的问题。之前我们提过,eSPI所能涵盖的device包括BMC/EC/SuperIO和80 Port Debug Card,在这其中,80 Port Debug Card 自不必说,Super IO逻辑都纯硬件实现的,无须FW插手控制,所以也没有使用Flash的需求。EC的内部一般都运行着一颗类似于8051的MCU,而BMC基本都是采用ARM做为控制内核,二者都需要FW配合才能正常工作,有能力也有需求去访问Flash,所以针对Flash Channel所能涵盖的eSPI Slave仅限于EC和BMC。
我们先来讨论一下通常情况下EC/BMC的Flash应用场景,下图所示是一个Notebook的Chipset与EC的连接简图:
如上图所示,PCH(全称Platform Controller Hub,在Intel Chipset中负责Legacy南桥相关事物)和EC Chip ITE8502上各自都挂了一颗SPI Flash。从功能上来讲,PCH的那颗Flash用于存放BIOS和Chipset FW(比如ME),EC那颗Flash用于存放自己启动和运转所需的EC FW。BMC的情况也是类似,Server Chipset和BMC最起码都需要各自挂一块Flash,用于存在BIOS和BMC FW。
开篇的时候我们说过:eSPI Flash Channel解决的是如何让Chipset和eSPI Slave实时共享SPI Flash的问题。通过刚才上面的描述,大家可能会以为这里的实时共享,是让Chipset和EC/BMC共用一块Flash,把BIOS和EC/BMC FW放进同一颗Flash里。这样子理解不能说不对,但是也不能说对。事实上,存放EC/BMC FW的那块Flash并不在eSPI Spec讨论的范畴之内。这也是很容易就能想通的,EC/BMC依赖FW进行启动和运转,一旦遭到破坏,整个部件就无法正常使用了,放任Chipset和EC/BMC自己访问这颗Flash,既没有意义,又存在风险,何必呢?
既然不是放EC/BMC FW那块Flash,那么这里所谓实时共享的就是放BIOS这颗Flash了。Chipset对这颗Flash的需求还是存放BIOS和Chipset FW,而EC/BMC这边的需求就不尽相同了。就拿BMC来说,在IPMI Spec中为其定义了一个叫做Non-volatile Storage的部件,如下:
按照定义,系统日志/传感器数据和FRU信息(可替换部件的信息,比如插了多少根内存条,挂了多少块硬盘)都会存储到这个Non-volatile Storage。这样的话,除了载有BMC FW的那块Flash,BMC还需要另外一块Flash充当这个Non-volatile Storage的角色。EC也是差不多的道理,在某种情况下EC可能需要一块额外的Flash存放一些非易失的数据。
eSPI BUS的Flash Channel为Chipset和EC/BMC提供了一条可以实时共享Flash部件的通路。根据这颗被共享的Flash挂在eSPI Master Side(Chipset)还是eSPI Slave Side(EC/BMC),eSPI Spec将Flash Channel的工作模式划分为Master Attached Flash Sharing和Slave Attached Flash Sharing。
Master Attached Flash Sharing
在这种工作模式下,被共享的Flash是挂载在eSPI Master Side,也就是Chipset这边。这里有一点容易让人混淆,这里使用的措辞是挂载在eSPI Master Side,而不是直接挂载在eSPI Master下面。如果这是一块SPI Flash,那它应该挂在Chipset的SPI Controller下面,不存在一种叫做eSPI Flash的东西,可以直接挂在eSPI Master下面,eSPI Protocol里也没有相关command可以直接用来Read/Write/Erase Flash。明确了这一点,我们可以来看看Master Attached Flash Sharing Mode下的Flash操作了
上图所示是一种较为常见的方案,共享Flash挂在Chipset的SPI Controller下面,走SPI协议和Chipset进行交互,EC/BMC/SIO等挂在eSPI Controller下面,走eSPI协议和Chipset进行交互。
Chipset需要进行Flash访问的时候,直接打Cycle到SPI Controller上,然后SPI Controller再把相关的Read/Write/Erase Command打到SPI BUS上;
EC/BMC想进行Flash访问的时候,显示通过eSPI BUS向eSPI Master发起Flash Channel Cycle,然后eSPI Master向SPI Controller发起数据请求,SPI Controller收到后,再把相关请求转换成对应的Read/Write/Erase Command打到SPI BUS。从Flash那边拿到的数据还是需要通过SPI Controller传递给eSPI Master,然后eSPI Master再通过eSPI Flash Channel的Cycle传回给EC/BMC。
还有一种不常见的方案,如下图,Flash和EC/BMC共享同一组CLK和DATA引脚,通过各自独占的CSn片选信号做区分。eSPI Spec本来就复用了SPI的时序和电气规范,这样的连接形式给人一种SPI Flash可以直接挂在eSPI Master下的错觉。但是二者在协议层是迥然不同的两种协议,是不能完全Pin to Pin兼容的。
真实情况用下图描述应该更为便于理解些,虽然Flash和EC/BMC从物理上共用了同一组CLK/DATA引脚,但是从本质上来说,Flash还是通过下图绿色实线加CS1#的通路走SPI协议和SPI Controller进行交互,而EC/BMC是先通过蓝色实线加CS2#向eSPI Master发出Flash Channel Cycle,然后eSPI Master再走红色实线向SPI Controller发出数据请求。可以看到虽然从外部引脚看来,Flash和EC/BMC使用的是同一条BUS,但是二者在协议层走的完全不同的两条路径。在这里给大家留一个小问题,上期内容提到的Perpheral Channel,在下图的这种连接方案中走的是哪条路径呢?
由于上述的这种共享CLK/DATA引脚的方案需要添加逻辑进行SPI/eSPI协议的路由,所以并不常见,但是拿来帮我们理解Flash Channel却是个十分和恰当的案例。如果您对于SPI/eSPI两者之间关系还是十分困惑的话,还请多多研读上面的内容。
Slave Attached Flash Sharing
这种模式是针对Server平台的,所以这里的Slave Attached指的是被共享的这块Flash挂在BMC Side。还是跟我们刚才强调的那样,这里的挂在BMC side,指的是挂在BMC的SPI Controller下,而不是直接挂在BMC的eSPI 相关的控制逻辑下,如下图所示:
当BMC想进行Flash访问的时候,直接向自己的SPI Controller下发指令,然后SPI Controller把对应Read/Write/Erase打到图中的BMC SPI BUS上。
当Chipset想进行Flash访问的时候,先向Chipset的SPI Controller下发指令,然后Chipset SPI Controller向Chipset eSPI Master发起数据请求,Chipset eSPI Master收到后,把相关数据请求转化对应的eSPI Flash Channel Cycle打到eSPI BUS上,BMC里面eSPI Slave看到eSPI BUS上的Flash Channel Cycle,会再向BMC SPI Controller发起数据请求,然后是BMC SPI Controller把请求转换成Read/Write/Erase command打到BMC SPI BUS上,共享Flash看到comand后再把数据原路传给BMC SPI Controller-->BMC eSPI Slave-->Chipset eSPI Master-->Chipset SPI Controller。
自此,关于eSPI Flash Channel的概念性介绍就此结束了,由于作者水平有限,如果有任何错误和疑问,还请联系[email protected]。
本期内容结束了,我们下期再见~
更多内容请见我的公众号:第五位面壁者