系列文章目录
PCIe扫盲(一)
PCIe扫盲(二)
PCIe扫盲(三)
PCIe扫盲(四)
PCIe扫盲(五)
PCIe扫盲(六)
PCIe扫盲(七)
PCIe扫盲(八)
PCIe扫盲(九)
PCIe扫盲(10)
PCIe扫盲(11)
文章目录
- 系列文章目录
- 两种中断传递方式
- 中断机制介绍(INTx)
- 中断机制介绍(MSI)
- 中断机制介绍(MSI-X)
- 复位机制介绍(Fundamental & Hot)
- 复位机制介绍(FLR)
- 转载链接
两种中断传递方式
为了能够让一些优先级高的事务得到优先处理,PCI 总线支持外设中断用以提高总线性能。PCIe 总线继承了 PCI 总线的所有中断特性(包括 INTx 和 MSI/MSI-X),以兼容早期的一些 PCI 应用层软件。本次连载的文章只是简单的介绍 PCIe 中断的一些基本概念和特性,如需深入了解 PCI/PCIe 总线的中断内容,请参阅 PCI/PCI-X Spec 或者 Mindshare 的书籍(PCI System Architecture)。
PCI 总线最早采用的中断机制是 INTx ,这是基于边带信号的。后续的 PCI/PCI-X 版本,为了消除边带信号,降低系统的硬件设计复杂度,逐渐采用了 MSI/MSI-X(消息信号中断)的中断机制。
INTx 一般被称为传统的(Legacy)PCI 中断机制,每个 PCI 设备最多支持四个中断信号(边带信号,INTA#、INTB#、INTC# 和 INTD#)。一个简单的例子如下图所示:
也可以参考一下之前的文章(关于 INTx 的):PCI总线的中断和错误处理
MSI/MSI-X 是后续的 PCI/PCI-X 总线改进后的中断机制,其中 MSI-X(MSI-eXtented)是 PCI-X 中提出的升级版本。需要特别注意的是,MSI/MSI-X 与 PCIe 总线中的消息(Message)的概念完全不同!MSI/MSI-X 本质上是一种 Posted Memory Write 。
一个简单的例子如下图所示:
中断机制介绍(INTx)
一个简单的 PCI 总线 INTx 中断实现流程,如下图所示。
-
首先,PCI 设备通过 INTx 边带信号产生中断请求,经过中断控制器(Interrupt Controller,PIC)后,转换为 INTR 信号,并直接发送至 CPU ;
-
CPU 收到 INTR 信号置位后,意识到了中断请求的发生,但是此时并不知道是什么中断请求。于是通过一个特殊的指令来查询中断请求信息,该过程一般被称为中断应答(Interrupt Acknowledge);
-
该特殊指令被发送至 PIC 后,PIC 会返回一个 8bits 的中断向量(Interrupt Vector)值给 CPU 。该中断向量值与其发送的 INTR 请求是对应的;
-
CPU 收到来自 PIC 的中断向量值后,会去其 Memory 中的中断向量表(Interrupt Table)中查找对应的中断服务程序(Interrupt Service Routines,ISR)在 Memory 的位置;
-
然后 CPU 读取 ISR 程序,进而处理该中断。
上面的例子主要是基于早期的单核 CPU 设计的,并没有考虑到目前多核 CPU 的情况。因此,在后续的 PCI Spec 中,将 PIC 替换为 IO APIC(Advanced Programmed Interrupt Controller)。如下图所示:
实际上,在 PCIe 总线中,传统的中断机制(INTx)已经很少被使用,很多应用甚至直接将该功能禁止了。无论是在 PCI 总线(V2.3 及以后的版本),还是 PCIe 总线中,都可以通过配置空间中的配置命令寄存器(Configuration Command Register 来禁止 INTx 中断机制),如下图所示。不过,需要特别注意的是,虽然该 bit 的名称为中断禁止(Interrupt Disable),但是其只会影响 INTx,对 MSI/MSI-X 不会造成影响。因为 MSI/MSI-X 的使能(或禁止)是通过配置空间中的 MSI/MSI-X Capability Command Register 来实现的,并且一旦使能了 MSI/MSI-X,PCI 总线 / PCIe 总线便会自动地禁止 INTx 。
并且可以通过配置状态寄存器的中断状态(Interrupt Status)bit 来确定当前的中断状态,如下图所示:
INTx 相关的寄存器在配置空间的位置如下图所示,Interrupt Pin 和 Interrupt Line 分别定义了中断边带信号引脚号(INTA# ~ INTD#)和中断向量号(IRQ0 ~ IRQ255)。
然而,PCIe 总线继承了 PCI 总线的 INTx 中断机制,但是在实际的 PCIe 设备之间的中断信息传输中使用的并非边带信号 INTx ,而是基于消息(Message)的。其中 Assert_INTx 消息表示 INTx 信号的下降沿。Dessert_INTx 消息表示 INTx 信号的上升沿。当发送这两种消息时,PCIe 设备还会将配置空间的相关中断状态 bit 的值更新。对于 PCIe-PCI(X) 桥设备来说,会将接收到的来自 PCI/PCI-X 总线的 INTx 信号转换为消息,在往上级发送。一个简单的例子如下图所示:
INTx 消息的格式为:
桥设备中的 INTx 消息的类型与设备号的映射关系如下图所示:
对应的,一个简单的例子如下:
当多个设备使用同一个中断信号线时,只有先置位的设备会被中断控制器响应。但是该中断信号线,并不会因为其中一个设备的中断请求得到响应便被清除,而是会等到所有的发送请求的设备的中断请求都得到了响应之后。如下图所示:
中断机制介绍(MSI)
前面的文章中介绍过,MSI 本质上是一种 Memory Write,和 PCIe 总线中的 Message 概念半毛钱关系都没有。并且,MSI 的 Data Payload 也是固定的,始终为 1DW 。
由于 MSI 也是从 PCI 总线继承而来的,因此 MSI 相关的寄存器也存在于配置空间中的 PCI 兼容部分(前 256 个字节)。如下图所示,MSI 有四种类型:
其中 Capability ID 的值是只读的,05h 表示支持 MSI 功能。
Next Capability Pointer 也是只读的,其用于查找下一个 Capability Structure 的位置,其值为 00h 则表示到达 Linked List 的最后了。
Message Control Register 用于确定 MSI 的格式与支持的功能等信息,如下图所示:
具体描述如下:
Message Address Register:32-bit 最低两位固定为 0 ,使得该地址是 DW 对齐的。
当 Mask Bits 将相关的中断向量(Interrupt Vector)屏蔽后,该 MSI 将不会被发送。软件可以通过这种方式来使能或者禁止某些 MSI 的发送。如果相关中断向量没有被屏蔽,则如果发生了相关中断请求,这时 Pending Bits 中的相应 bit 则会被置位。一旦中断信息被发出,则该 bit 会立即被清零。
注:可能有的人会有疑惑了(无论是 Mindshare 的书,还是 PCI 的 Spec 都没有明确解释),因为 Mask Bits 和 Pending Bits 都只有 32 位,而 8 位的中断向量号最多可以表示 256 个!显然,32 位最多只能对应 32 个中断向量号,无法支持 256 个的。实际上,一般的系统不会支持 256 个中断向量号的,32 个就已经足够用了,所以并不用担心这个问题。
PCIe 设备会根据配置空间中的 MSI 请求信息,来创建 Memory Write TLP,来讲 MSI 信息发送出去。作为一种特殊的 TLP ,传递 MSI 的 TLP 需要遵循以下规则:
-
No Snoop 和 Relaxed Ordering bits 的值必须为 0
-
TLP 长度值必须为 01h
-
First BE 必须为 1111b
-
Last BE 必须为 0000b
-
地址是直接从配置空间中的响应位置复制过来的
如下图所示:
中断机制介绍(MSI-X)
PCI 总线自 3.0 版本开始支持 MSI-X 机制,对 MSI 做出了一些升级和改进,以克服 MSI 机制的三个主要的缺陷:
-
随着系统的发展,对于特定的大型应用,32 个中断向量不够用了(参考前一篇文章);
-
只有一个目标地址使得多核 CPU 情况下的,静态中断分配变得困难。如果能够使每个向量对应不同的唯一的地址,便会灵活很多;
-
某些应用中的中断优先级混乱问题。
有趣的是,MSI 只支持 32 个中断向量,而 MSI-X 支持多达 2048 个中断向量,但是 MSI-X 的相关寄存器在配置空间中占用的空间却更小。这是因为中断向量信息并不直接存储在这里,而是在一款特殊的 Memory(MIMO)中。并通过 BIR(Base address Indicator Register, or BAR Index Register)来确定其在 MIMO 中的具体位置。如下图所示:
Message Control 寄存器的具体描述如下:
MSI-X 查找表的示意图如下:
结构图如下:
类似的,Pending Bits 则位于另一个 Memory 中,其结构图如下:
注:无论是 MSI 还是 MSI-X,其本质上都是基于 Memory Write 的,因此也可能会产生错误。比如 PCIe 中的 ECRC 错误等。
复位机制介绍(Fundamental & Hot)
PCIe 总线中定义了四种复位名称:冷复位(Cold Reset)、暖复位(Warm Reset)、热复位(Hot Reset)和功能层复位(Function-Level Reset,FLR)。其中 FLR 是 PCIe Spec V2.0 加入的功能,因此一般把另外三种复位统称为传统的复位方式(Conventional Reset)。其中冷复位和暖复位是基于边带信号 PERST# 的,又被统称为基本的复位方式(Fundamental Reset)。
基本复位由硬件自动处理,会复位整个 PCIe 设备,初始化所有与状态机相关的硬件逻辑,端口状态以及配置空间中的配置寄存器等等。但是,也有一个例外,就是前面介绍 PCIe 错误报告机制的相关文章中提到过 Sticky(不受复位影响)的概念。这里指的不受复位影响的前提是,PCIe 设备的电源并未被完全切断。Sticky 这一功能有助于系统定位错误与分析错误起因。
基本复位中的冷复位(Cold Reset)指的是因为主电源断开后重新连接导致的复位。需要注意的是,即使主电源断开了,如果 PCIe 设备仍有辅助电源 Vaux 为其供电,该复位仍不会影响到 Sticky 的 bits 。
PCIe Spec 允许两种实现基本复位的方式。一是直接通过边带信号 PERST#(PCI Express Reset);二是不使用边带信号 PERST#,PCIe 设备在主电源被切断时,自行产生一个复位信号。一个简单的例子如下图所示:
暖复位(Warm Rest)是可选的,指的是在不关闭主电源的情况下,产生的复位。然而,PCIe Spec 并未明确规定暖复位的产生机制,因此,如何产生暖复位完全是由系统设计者决定的。
热复位(Hot Reset)是一种 In-band 复位,其并不使用边带信号。PCIe 设备通过向其链路(Link)相邻的设备发送数个 TS1 Ordered Set(其中第五个字符的 bit0 为 1 ),如下图所示。这些 TS1OS 在所有的通道(Lane)上同时发送,并持续 2ms 左右。
注:关于 Ordered Set 以及 LTSSM 等相关内容,请参考前面介绍链路初始化与训练的相关文章。
主要注意的是,如果 Switch 的 Upstream 端口收到了热复位,则会将其广播至所有的 Downstream 端口,并复位其自己。如果 PCIe 设备的 Downstream 端口接收到热复位,则只需要复位其自己即可。
当 PCIe 设备接收到热复位后,LTSSM 会进入 Recovery and Hot Reset 状态,然后返回到 Detect 状态,并重新开始链路初始化训练。其该 PCIe 设备的所有状态机,硬件逻辑,端口状态和配置空间中的寄存器(除了 Sticky bits)都将被初始化值默认状态。
软件可以通过向桥设备的,特定端口的配置空间中的二级总线复位(Secondary Bus Reset)bit 先写 0 再写 1 ,来产生热复位,如下图所示:
需要注意的是,如果软件设置的是 Switch 的 Upstream 端口的二级总线复位 bit,则该 Switch 会往其所有的 Downstream 端口广播热复位信号。而 PCIe-to-PCI 桥则会将接收到的热复位信号转换为 PRST# 置位,发送给 PCI 设备。
二级总线复位(Secondary Bus Reset)bit 在配置空间的位置如下图所示:
PCIe Spec 还允许软件禁止某个链路(Link),强制使其进入电气空闲状态(Electrical Idle)。如果将某个链路禁止,则该链路所有的下游 PCIe 设备都将收到链路禁止信号(通过 TS1OS,如下图所示)。
复位机制介绍(FLR)
PCIe 总线自 V2.0 加入了功能层复位(Function Level Reset,FLR)的功能。该功能主要针对的是支持多个功能的 PCIe 设备(Multi-Fun PCIe Device),可以实现只对特定的 Function 复位,而其他的 Function 不受影响。当然,该功能是可选的,并非强制的,软件可以通过查询配置空间中的设备功能寄存器(Device Capability Register)来查询该 PCIe 设备是否支持 FLR 。如下图所示:
并可以通过设备控制寄存器(Device Control Register)中的将 Initiate Function Level Reset bit 置 1,来产生 FLR 。
FLR 只复位对应 Function 的内部状态和寄存器(使其暂时不变化,Making it quiescent),但是并不影响 Sticky bits、有硬件初始化的值(Hardware-initialized bits)和链路专用寄存器(比如 Captured Power,ASPM Control、Max Payload Size 以及 VC 等寄存器)。如果该设备在 FLR 前,发出了 Assert INTx 中断消息,必须在开始 FLR 之前再发出对应的 Deassert INTx 消息,除非该 INTx 已经被与其他 Function 共享了。当收到 FLR 后,该 Function 的所有的其他功能都应被立即停止(Required to cease)。
此外,PCIe Spec 还明确给出了 FLR 的完成时间应在 100ms 以内。
PCIe Spec 还明确规定了,当某个 Function 处于 FLR 状态时的一些特性:
-
该 Function 不能有任何与外界通信的(外部)接口;
-
该 Function 必须将任何软件可读取的状态(可能包括加密信息等)打乱。换句话说,任何内部存储都必须被清零或者随机化;
-
该 Function 必须可以被另一个 Diver 配置为一般模式;
-
该 Function 必须为其收到的包含有 FLR 信息的配置写(Configuration Write)返回一个 Completion,然后再进行 FLR 操作。
在进入 FLR 状态后,还需要:
-
该 Function 接收到的任何请求都应该被直接丢弃,且不登记(Logging),也不报错误。但是 FC Credits 必须要被更新,以维持链路的正常操作;
-
该 Function 接收到的任何 Completion 都应该被当做 Unexpected Completions,然后直接丢弃,且不登记,也不报错。
转载链接
- 两种中断传递方式
- 中断机制介绍(INTx)
- 中断机制介绍(MSI)
- 中断机制介绍(MSI-X)
- 复位机制介绍(Fundamental & Hot)
☆