那些年呆哥错过的PCIe Reset

原创内容,转载请注明:  [http://www.ssdfans.com]  谢谢!

阿呆在成为呆哥前,也有过青春年少,不仅有错过的大雨,还有错过的PCIe Reset。

PCIe是个博大精深的协议,跟Reset相关的术语就有好些:Cold Reset, Warm Reset, Hot Reset, Conventional Reset, Function Level Reset, Fundamental Reset, Non-Fundamental Reset

一开始面对这么多概念,阿呆心里其实是拒绝的。牛人都有特殊能力,蛋博士的能力是化神奇为腐朽,透过现象看本质。

阿呆的特点是提纲挈领,快速从一大堆概念中理出头绪:

第一步,呆哥先整理这些个Reset之间的关系:

这些Reset之间是从属关系, 总线规定了两个复位方式:Conventional Reset和FLR(Function Level Reset),而Conventional Reset由进一步分为两大类:Fundamental Reset和Non-Fundamental Reset。Fundamental Reset方式包括Cold和Warm Reset方式,可以将PCIe将设备中的绝大多数内部寄存器和内部状态都恢复成初始值;而Non-Fundamental Reset方式为Hot Reset方式。

看到下面这张表,有没有感觉好一点?

1.Conventional Reset

1.1 Fundamental Reset

1.1.1 Cold Reset

1.1.2 Warm Reset

1.2 Non-Fundamental Reset

1.2.1 Hot Reset

2. Function Level Reset

   

 

第二步,呆哥要搞明白每种Reset具体干什么,实现方式以及对Device的影响;

Fundamental Reset:由硬件控制,会重启整个Device,包括:重新初始化所有的State Machine,所有的硬件逻辑,Port State和configuration register。

当然,也有Fundamental Reset搞不定的情况,就是那些某些Register里的某些属性为”Sticky”的Field,跟蛋博士一样坚强,除非完全断电,否则任你如何Reset这些Field的值一直不变。

这些Field在Debug的时候非常有用,特别是那些需要Reset Link的 情况,比如在link reset以后还能保存之前的错误状态,这个对那些对自己有要求的FW以及上层应用来说,是极好的。

Fundamental Reset一般发生在整个系统Reset的时候(比如你重启电脑),但是也可以只针对某个Device做Fundamental Reset。

Fundamental Reset有两种:

  • Cold Reset: Power Off/On Device的Vcc (Vaux一直在)
  • Warm Reset (Optional): 保持Vcc的情况下由系统触发,比如改变系统的电源管理状态可能会触发Device的warm reset,PCIe协议没有定义具体如何触发Warm Reset的,而是把决定权交给系统。

有两种方法对一块PCIe Device做Fundamental Reset:

  • 系统这边发PERST# (PCIe Express Reset)信号给Device;
    • 以下图为例
    • 一个系统上电时,主电源稳定以后会有”Power Good”信号
    • 这时ICH就会发PERST# 信号给下面挂的PCIe SSD
    • 如果系统重启,Power Good信号的变化会触发PERST# 的Assert和De-Assert,就可以实现PCIe Device的Cold Reset
    • 如果系统可以提供Power Good信号以外的方法触发PERST#,就可以实现Warm Reset
    • PERST#信号会发送给所有PCIe Device,Device可以选择使用这个信号,也可以不理它
  • 如果这块PCIe Device不支持PERST#信号,那上电时他会自动进行Fundamental Reset;
    • 那些特例独行,选择不理睬PERST#信号的Device,必须能自己触发Fundamental Reset
    • 比如,侦测到3.3V后就触发Reset (当Device发现供电超过其标准电压时,也必须触发Reset)

Hot Reset:通过Assert TS1的Symbol 5的Bit [0] 实现:

PCIe Device收到两个连续的带Hot Reset的TS1 后,经过2ms的timeout:

  • LTSSM经过Recovery和Hot Reset State,最终停在Detect State (Link training的初始状态)
  • Device所有的State Machine,所有的硬件逻辑,Port State和configuration register(Sticky bit 除外)全部回到初始值

当PCIe Device出现问题时,可以通过软件触发Hot Reset使其恢复,具体方法如下:

对 RC的Bridge Control Register Bit[6] – Secondary Bus Reset写’1’。

  • RC会开始发带Hot Reset的TS1
  • 2ms后Device会进入Hot Reset状态,此时LTSSM的状态变化是  L0 -> RCVRY -> HOTRESET
  • 将RC的Bridge Control Register Bit[6] – Secondary Bus Reset清零, Device的LTSSM的状态变化HOTRESET -> DETECT
  • 重新开始LTSSM进行Link Training

注:这个我觉得有点像SATA里面Host端通过Trigger OOB去修复Link上的一些问题

软件还可以通过设置Device的Link Control Register [2] – link disable bit 把Device disable掉。

 

当Device的Link Disable bit被置上以后,会进入LTSSM Recovery State,开始向RC发送带Disable bit的TS1(这个动作只能由EP发起,RC端这个bit是reserve的)。

RC端收到这样的TS1以后,其物理层会发送LinkUp=0的信号给链路层,之后所有的Lane都会进入Electrical Idle。2ms timeout以后,RC会进入LTSSM Detect mode,但是Device会一直停留在LTSSM的Disable状态,等待重出江湖的那一天。

 

FLR (Function Level Reset):PCIe Link就像一条大马路,上面可以跑各种各种的车,这些车就是不同的Function。如果某个Function出了问题,当然可以通过Reset整个Link的方式来解决,不过细腻的呆哥当然不会采取这种方法,他会使用Function Level Reset,哪里不舒服点哪里。并不是所有的Device都支持FLR,需要检查Device Capabilities Register[28]进行确认。

如果Device支持 FLR,那么软件就可以通过Device Control Register的[15]来进行Function Reset了

FLR会把对应Function的内部状态,寄存器重置,但是以下寄存器不会受到影响:

  • Sticky bits – cold reset和warm reset都拿他们没辙
  • HwIint类型的寄存器。在PCIe设备中,有效配置寄存器的属性为HwIint,这些寄存器的值由芯片的配置引脚决定,后者上电复位后从EEPROM中获取。Cold和Warm Reset可以复位这些寄存器,然后从EEPROM中从新获取数据,但是使用FLR方式不能复位这些寄存器。
  • 一些特殊的配置寄存器,比如Captured Power, ASPM Control, Max_Payload_Size或者Virtual Channel
  • FLR不会改变Device的LTSSM状态

 

FLR的时间:

协议规定一个Function的Reset需要在100ms内完成。但是软件在启动FLR前,要注意是否有还没完成的CplD,遇到这种情况,要么等这些CplD完成再开始FLR,要么启动FLR以后等100ms以后再重新初始化这个Function。这种情况如果不处理好,可能会导致data corruption: 前一批事物要求的数据因为FLR的影响被误传给了后一批事物。

要避免这种情况,阿呆建议这么做:

  • 确保其他软件在FLR期间不会访问这个Function
  • 把Command register清空,让Function一个人想静静
  • Polling Device Status Register [5] – Transactions Pending bit直到被Clear – 代表没有未完成的CplD,或者等待到Completion Timeout 的时间,如果Completion Timeout没有被Enable,等100ms

  • 初始化FLR然后等100ms
  • 重新配置Function并Enable

 

在FLR过程中:

  • 这个Function对外不能被使用
  • 不能保留之前的任何可以被读取的信息(比如内部的Memory需要被清零或者改写)
  • 回复要求FLR的Cfg Request,并开始FLR
  • 对于发进来的TLP可以回复UC (Unexpected Completion)或者直接丢掉
  • FLR应该在100ms之内完成,但是其后的初始化还需要花一些时间,在初始化过程中如果收到Cfg Request,可以回复CRS (Configuration Retry Status)

 

快结束了,听阿呆总结一下Reset退出时的那些事:

  • 从Reset状态退出后,必须在20ms内开始 Link Training;
  • 软件需要给Link充分的时间完成Link Training和初始化,至少等上100ms才能开始发送Cfg Request ;
  • 如果软件等了100ms开始发Cfg Request,但是Device还没初始化完成,Device会回复CRS;
  • 这时RC可以选择重发Cfg Request或者上报CPU说Device还没准备好;
  • Device最多可以有1s时间(从PCI那继承来的),之后必须能够正常工作,否则System/RC则可以认为Device挂了;

 

分类目录 未分类.
扫一扫二维码或者微信搜索公众号ssdfans关注(添加朋友->点最下面的公众号->搜索ssdfans),可以经常看到SSD技术和产业的文章(SSD Fans只推送干货)。
ssdfans微信群介绍
技术讨论群 覆盖2000多位中国和世界华人圈SSD以及存储技术精英
固件、软件、测试群 固件、软件和测试技术讨论
异构计算群 讨论人工智能和GPU、FPGA、CPU异构计算
ASIC-FPGA群 芯片和FPGA硬件技术讨论群
闪存器件群 NAND、3D XPoint等固态存储介质技术讨论
企业级 企业级SSD、企业级存储
销售群 全国SSD供应商都在这里,砍砍价,会比某东便宜20%
工作求职群 存储行业换工作,发招聘,要关注各大公司招聘信息,赶快来
高管群 各大SSD相关存储公司高管和创始人、投资人

想加入这些群,请微信扫描下面二维码,或搜索nanoarchplus,加阿呆为微信好友,介绍你的昵称-单位-职务,注明群名,拉你进群。SSD业界需要什么帮助,也可以找阿呆聊。