前面的文章提到过,PCI总线中定义两个边带信号(PERR#和SERR#)来处理总线错误。其中PERR#主要对应的是普通数据奇偶校检错误(Parity Error),而SERR#主要对应的是系统错误(System Error)。具体如下:

·         普通的数据奇偶校检错误——通过PERR#报告

·         在多任务事务(Multi-task Transaction,又称为Special Cycles)时的奇偶校检错误——通过SERR#报告

·         地址和命令的奇偶校检错误——通过SERR#报告

·         其他错误——通过SERR#报告

一个简单的例子如下图所示:

PCIe作为一种高速串行总线,取消了PCI总线中的这两个边带信号,采用错误消息的方式来实现错误报告。但是,在软件层面上,PCIe仍是兼容PCI总线的,具体后面会详细描述。

在PCIe总线的错误报告机制中,有如下四个比较重要的概念:

·         错误检测(Error Detection):指的是检测某个错误是否存在的过程。

·         错误登记(Error Logging):指的是将相关寄存器(配置空间中的)的对应为置位,以等待软件中的相关错误处理程序来处理该错误。

·         错误报告(Error Reporting):通知系统某个(或多个)错误发生了。在PCIe总线中,发生错误的设备会通过错误消息(Error Message)逐级将错误信息发送至Root,Root接收到错误消息后,会产生对应的中断通知系统。

·         错误发送(Error Signaling):指的是通过发送错误消息(或者带有UR,CA的Completion和Poisoned TLP)来传递错误信息的过程。

注:带有UR,CA的Completion在前面的文章中介绍过,不熟悉的可以回顾一下。“Poisoned TLP”是PCIe总线错误报告机制中的Error Forwarding的方式,具体会在后面详细介绍。

PCIe总线Spec定义了两个错误报告等级。第一个为基本的(Baseline Capability),是所有PCIe设备都需要支持的功能。第二个是可选的,称之为高级错误报告(Advanced Error Reporting Capability)。

在基本的错误报告机制中,有两组相关的配置寄存器(配置空间中),分别为:

·         兼容PCI总线的寄存器(PCI-compatible Registers)

·         PCIe总线中新增的寄存器(PCI Express Capability Registers)

高级错误报告机制(AER)中,又使用了一组专用的配置寄存器(配置空间中)。借助AER可以获得更多的错误信息,有助于软件定位错误源和分析错误原因。

PCIe总线的错误可以分为(Correctable Errors)和不可校正错误(Uncorrectable Errors)。其中,可校正错误可以自动地被硬件识别并被自动的校正或恢复。而不可校正错误又被分为非致命的(Non-Fatal)和致命的(Fatal)。非致命的错误一般有设备驱动软件(Device Specific Software)直接处理,且链路(Link)可恢复,甚至链路上的数据有可能得到恢复(不丢失数据)。致命的错误只能由系统软件(System Software)处理,且一般需要进行复位等操作,因此链路上的数据必然会丢失。

PCIe总线有三种错误报告方式,分别是:

1.     Completions:通过Completion中的状态位向Request返回错误信息

2.     Poisoned Packet(又称为错误传递,Error Forwarding):告知接收端当前TLP的Data Payload已经被破坏

3.     Error Message(错误消息):向主机报告错误信息

错误消息的格式和对应的消息编码如下所示:

为了兼容PCI总线的错误报告机制(使用PERR#和SERR#),PCIe设备会自动将CA、UR和Poisoned TLP转换为对应的错误信息。具体这里就不详细介绍了,有兴趣的可以自行阅读PCIe Spec的相关章节。

PCIe设备的配置空间中的状态与控制寄存器如上图所示,通过这些寄存器可以使能(或禁止)通过错误消息(Error Message)发送错误报告、查询错误状态信息,以及链路训练和初始化状态等。

前面的文章介绍过,默认的错误分类如下表所示:

这些错误类型可以通过设备控制寄存器(Device Control Register)中的相关位,进行使能或者禁止:

也可以通过设备状态寄存器(Device Status Registers)相关位查询错误状态:

当然,当Root接收到错误消息后,怎么处理还要取决于Root Control Register的设置:

链路错误(Link Errors)一般发生在物理层与数据链路层通信的过程中。对于Downstream的设备,如果链路上发生了Fatal错误,此时,该设备并不能够向Root报告错误。这种情况下,需要Upstream设备向Root来报告错误。为了消除链路错误,一般需要对链路进行重新训练(Retrain)。如下图所示,在链路控制寄存器中,可以通过往Retrain Link这一位写1,来强制进行链路重训练。

当发起重训练请求后,软件可以检查链路状态寄存器(Link Status Register)中的Link Training位,来确认链路训练是否已经完成,如下图所示。当该位为1时,表明链路训练尚未完成(或者还没有开始),如果链路训练已经完成,硬件会自动将该位清零。

PCIe总线的错误登记与报告的流程图如下图所示:

posted on 2019-04-11 11:26  hammerqiu  阅读(10583)  评论(1编辑  收藏  举报