出于向下兼容的需要,PCIe完全继承了PCI的所有的中断特性(包括INTx,MSI/MSIx)。但是与PCI不同的是,PCIe使用串行总线尽量减少pin的使用,所以对于INTX类型的中断,它没有使用sideband pin的方式而是使用Message传递中断。另外对于PCI, MSI/MSIX是可选的但是PCIe设备必须支持MSI/MSIx的中断请求机制,可以不支持INTx中断消息。

INTx 中断:

在详细介绍PCIe的中断机制之前,我们先来回顾一下PCI时代传统的中断处理过程。下图是一个典型使用PCI设备的单处理器的系统。在这个系统中设备通过INTA#产生中断,INTA#链接到南桥PIC的IRQ上,PIC再通过INTR连接到CPU上。在这样的一个系统中,中断的传递流程如下所示:

  1. 设备通过连接到中断控制器PIC的INTA#请求中断,通常PIC有15个IRQ和1个INTR,它收到中断请求以后,它会拉INTR通知CPU有中断在等待处理中。
  2. CPU检测到INTR的信号以后,它会需要知道对应的中断向量,所以它会发一个中断响应命令给PIC。
  3. PIC 返回一个当前等待中最高优先级中断请求的8位的中断向量,该向量是由之前的系统软件设置的。
  4. CPU 按照中断向量找到对应的中断处理程序。
  5. 执行该中断处理程序并告诉设备释放INTx#信号线,程序返回到之前被中断的任务继续执行。

PCI spec 2.3在Command Register中引入了一个新的Interrupt Disable bit用来控制中断的enable和disable,该bit只会控制INTx类型的中断,不会影响MSIx。另外在Configuration Status Register加了一个Interrupt Status bit用来反应中断的状。

在PCI总线中,设备的INTx pin最终要连接到中断控制器的IRQ pin。通常在一个系统中会有多个设备,而且我们还可以通过桥扩展多个设备。这种情况下设备的INTx和中断控制器的连接方式要妥善的处理已达到负载均衡的目的。如下图的一个系统中,共有3个PCI插槽这些PCI插槽与中断控制器的IRQ_PINx引脚 (分别为IRQW#、IRQX#、IRQY#和IRQZ#)可以按照下图所示的拓扑结构进行连接。

PCI插槽 A、B、C 的 INTA#、INTB# 和 INTC# 信号将分散连接到中断控制器的 IRQW#、IRQX#和IRQY#信号,而所有INTD#信号将共享一个IRQZ#信号。采用这种连接方式时,整个处理器系统使用的中断请求信号,其负载较为均衡。而且这种连接方式保证了每一个插槽的INTA#信号都与一根独立的IRQx#信号对应,从而提高了PCI插槽中断请求的效率。在一个处理器系统中,多数PCI设备仅使用INTA#信号,很少使用INTB#和INTC#信号,而INTD#信号更是极少使用。在PCI总线中,PCI设备配置空间的Interrupt Pin寄存器记录该设备究竟使用哪个 INTx 信号。

x86处理器系统还经常使用PCI桥进行PCI总线扩展,扩展出来的PCI总线还可能挂接一些PCI插槽,这些插槽上INTx#信号仍然需要处理。PCI桥规范并没有要求桥片传递其下PCI设备的中断请求。事实上多数PCI桥也没有为下游PCI总线提供中断引脚INTx#,管理其下游总线的PCI设备。但是PCI桥规范推荐使用下面的表建立下游PCI设备的INTx信号与上游PCI总线INTx信号之间的映射关系。

我们举例说明该表的含义。在PCI桥下游总线上的PCI设备,如果其设备号为0,那么这个设备的INTA#引脚将和PCI总线的INTA#引脚相连;如果其设备号为1,其INTA#引脚将和PCI总线的INTB#引脚相连;如果其设备号为2,其INTA#引脚将和PCI总线的INTC#引脚相连;如果其设备号为3,其INTA#引脚将和PCI总线的INTD#引脚相连。在x86处理器系统中,由BIOS通过APCI _PRT (PCI Routing Table)记录PCI总线的INTA~D#信号与中断控制器之间的映射关系,保存这个映射关系的数据结构也被称为中断路由表。大多数BIOS使用表中的映射关系,这也是绝大多数BIOS支持的方式。如果在一个x86处理器系统中,PCI桥下游总线的PCI设备使用的中断映射关系与此不同,那么系统软件程序员需要改动BIOS中的中断路由表。BIOS初始化代码根据中断路由表中的信息,可以将PCI设备使用的中断向量号写入到该PCI设备配置空间的Interrupt Line 寄存器中。

Name(AR00, Package()
{// SD Host #0 - eMMCPackage() {0x0010FFFF, 0, 0, 16 },// SD Host #1 - SDIOPackage() {0x0011FFFF, 0, 0, 17 },// SD Host #2 - SD CardPackage() {0x0012FFFF, 0, 0, 18 },
})Name(PRSA, ResourceTemplate()         // Link name: LNKA
{IRQ(Level, ActiveLow, Shared, LLKA) {3,4,5,6,10,11,12,14,15}
})
Alias(PRSA,PRSB)      // Link name: LNKB
Alias(PRSA,PRSC)      // Link name: LNKC
Alias(PRSA,PRSD)      // Link name: LNKDName(PR00, Package()
{// SD Host #0 - eMMCPackage() {0x0010FFFF, 0, LNKA, 0 },// SD Host #1 - SDIOPackage() {0x0011FFFF, 0, LNKB, 0 },// SD Host #2 - SD CardPackage() {0x0012FFFF, 0, LNKC, 0 },
}Method(_PRT,0)
{If(PICM) {Return(AR00)} // APIC modeReturn (PR00) // PIC Mode
} // end _PRT

_PRT method中的资源的描述格式如上表所示 Source Index指的是对应的IOAPIC的pin。 PCIe 虽然继承了PCI所有的中断类型,但是PCIe很少使用INTx,主要使用的MSIx去传递中断,INTx的存在主要是因为有些老的PCI设备通过PCIe to PCI bridge接入到PCIe总线中。因为PCIe并没有INTx的边带信号,所以它使用的基于Message的中断传递。其中Assert_INTx消息表示INTx信号的下降沿。Dessert_INTx消息表示INTx信号的上升沿, 当一个Assert_INTx消息发出来,对应中断状态寄存器也会被设置起来。

INTx的消息格式如下所示:

PCIe桥下面的设备和总线的map关系和PCI类似

下图是一个简单的例子。3:0:0 Assert_INTA 消息因为它的设备号是0,所以2:1:0收到之后还是使用INTA,但是会讲ReqID改为2:1:0;因为2:1:0的设备号是1,所以1:0:0收到的消息会转化为 Assert_INTB (ReqID 1:0:0); 1:0:0接下来会把消息送给中断控制器。

MSI/MSI-X中断

PCIe的MSI/MSI-X继承自PCI,这个新的机制的引入同样是为了消除INTx的边带信号,而且可以更加合理的使用PCIe总线的序。目前绝大多数的PCIe设备使用MSI/MSI-X中断机制提交中断请求。MSI和MSI-X基本原理相同。MSI最多支持32个中断,而且要求中断向量连续。MSI-X可以支持更多的中断请求而且不要求中断向量连续。MSI/MSI-X本质上是一种Memory Write。PCIe设备中包含两个Capability结构,一个MSI另一个是MSI-X。MSI Cap ID是0x05,MSI有4种Capability组合,32位和64位的Message结构,32位和64位带中断Masking的结构。

我们可以通过Message Control Register控制MSI的开启和关闭以及是否支持64bit、是否支持多个消息,Masking等。

在X86系统中PCIe设备使用的Message Address 字段仍然保存PCI总线域的地址格式:

  1. 第31~20位,存放FSB Interrupts存储器空间的基地址,其值为0xFEE。当PCIe设备对0xFEEX-XXXX这段“PCI总线域”的地址空间进行写操作时,桥片会将会首先进行“PCI总线域”到 “存储器域”的地址转换,之后将这个写操作翻译为系统总线的Interrupt Message总线事务,从而向CPU内核提交中断请求。
  2. Destination ID字段保存目标CPU的ID号,目标CPU的ID与该字段相等时,目标CPU将接收这个Interrupt Message。系统总线Interrupt Message总线事务可以向不同的CPU提交 中断请求。
  3. RH(Redirection Hint Indication)位为0时,表示Interrupt Message将直接发向与Destination ID字段相同的目标CPU;如果RH为1时,将使能中断转发功能。
  4. DM(Destination Mode)位表示在传递优先权最低的中断请求时,Destination ID字段是否被翻译为Logical或者Physical APIC ID。在x86处理器中APIC ID有三种模式,分别为 Physical、Logical和Cluster ID模式。
  5. 如果RH位为1且DM位为0时,Destination ID字段使用Physical模式;如果RH位为1且DM位为1,Destination ID字段使用Logical模式;如果RH位为0,DM位将被忽略。

Message Data字段的格式如下图所示:

  1. Trigger Mode字段为0b0x时,PCIe设备使用边沿触发方式申请中断;为0b10时使用低电平触发方式;为0b11时使用高电平触发方式。MSI/MSI-X中断请求使用边沿触发方式,但是 系统总线 Interrupt Message总线事务还支持Legacy INTx中断请求方式,因此在Message Data字段中仍然支持电平触发方式。但是对于PCIe设备而言,该字段为0b0x。
  2. Vector字段表示这个中断请求使用的中断向量。系统总线Interrupt Message总线事务在提交中断请求的同时,将中断向量也通知给处理器。因此使用系统总线Interrupt
    Message总线事务时,处理器不需要使用中断响应周期通过读取中断控制器获得中断向量号。
  3. Delivery Mode字段表示如何处理来自PCIe设备的中断请求。
    a. 该字段为0b000时,表示使用“Fixed Mode”方式。此时这个中断请求将被Destination ID字段指定的CPU处理。
    b. 该字段为0b001时,表示使用“Lowest Priority”方式。此时这个中断请求将被优先权最低的CPU处理。当使用“Fixed Mode”和“Lowest Priority”方式时,如果Vector字段有 效,CPU接收到这个中断请求之后,将使用Vector字段指定的中断向量处理这些中断请求;而当Delivery Mode字段为其他值时,Message Data字段中所包含的Vector字段效。
    c. 该字段为0b010时,表示使用SMI方式传递中断请求,而且必须使用边沿触发,此时Vector字段必须为0。这个中断请求将被Destination ID字段指定的CPU处理。
    d. 该字段为0b100时,表示使用NMI方式传递中断请求,而且必须使用边沿触发,此时Vector字段和Trigger字段的内容将被忽略。这个中断请求将被Destination ID字段指定的 CPU处理。
    e. 该字段为0b101时,表示使用INIT方式传递中断请求,Vector字段和Trigger字段的内容将被忽略。这个中断请求将被Destination ID字段指定的CPU处理。
    f. 该字段为0b111时,表示使用INTR信号传递中断请求且使用边沿触发。此时MSI中断信息首先传递给中断控制器,然后中断控制器在通过INTR信号向CPU传递中断请求,之后CPU 在通过中断响应周期获得中断向量。

为了能够使用MSI, 系统软件(BIOS)在启动的时候要做一些基本的配置。

  1. 首先BIOS枚举所有的PCI兼容的设备。
  2. 发现设备以后软件读取Capabilities list指针找到MSI CAP的位置。
  3. 软件读取设备的消息控制寄存器的Mulitple Message Capable栏位获得设备支持的消息数量以及是否支持64bit消息地址。然后使能对应的enable bit。
  4. 软件分配base message data pattern以及Message Address。
  5. 最后使能MSI enable bit并关闭其它的中断选项。

MSI内存写传输数据包格式如下:

MSI-X的Capability 结构如下所示:

MSI-X支持多达2048个中断向量,但是MSI-X的相关寄存器在配置空间中占用的空间却更小。这是因为中断向量通过在BIR指向的mmio地址处。

中断消息向量表格式如下:

Pending bit Array格式如下:

使用MSI传递中断请求的过程:

  1. PCIe 设备在发送 MSI/MSI-X中断请求之前,系统软件需要合理设置PCIe设备MSI/MSI-X Capability 寄存器,使 Message Address寄存器的值为0xFEExx00y,同时合理地设置 Message Data寄存器Vector字段。
  2. PCIe设备提交MSI/MSI-X中断请求时,需要向0xFEExx00y地址写Message Data寄存器中包含的数据,并以存储器写TLP的形式发送到RC。当桥片收到这个TLP后,发现这个TLP的目 的地址在系统总线Interrupts存储器空间中,则将PCIe总线的存储器写请求转换为系统总线Interrupt Message总线事务,并在系统总线上广播。
  3. 系统总线上的CPU,根据APIC ID信息,选择是否接收这个Interrupt Message总线事务,并进入中断状态,之后该CPU将直接从这个总线事务中获得中断向量号,执行相应的中断服 务例程,而不需要从APIC中断控制器获得中断向量。

Refer:

1. PciTree.asl

2. 《PCI Express Technology》

3. 《PCI Express 体系结构导读》

32 配置引脚中断_PCIe的中断机制相关推荐

  1. FPGA的配置引脚以及配置过程

    FPGA配置基本介绍 与CPLD不同,FPGA是基于门阵列方式为用户提供可编程资源的,其内部逻辑结构的形成是由配置数据决定的.FPGA的配置方式分为主动式和被动式. 1配置引脚 FPGA的配置引脚可分 ...

  2. 中断/gic代码导读:在哪里配置安全中断的?

    思考:在哪里配置安全中断的? 在哪里配置中断的G0.G1NS.G1S分组的? 1.optee 在optee中有一段默认的配置,将0-7配置成G1NS,8-15配置成G1S,16-31配置成G1NS,3 ...

  3. ABOV单片机外部引脚中断EINT实现讲解及示例代码-[MC96F6332D]

    一.准备工作 1.KEIL C51编译环境 2.CodeGen8 代码生成器 3.MC96F6332D 开发板 4.USB-OCD II仿真器 二.生成外部引脚中断的代码 1.在CodeGen8 代码 ...

  4. stm32之配置串口中断服务函数

    在学习51单片机的时候,配置串口中断服务函数,只需要查看串口中断的中断号,然后在编写中断服务函数的时候,在函数名后面加上中断号.而在stm32中,中断的数量较多,对于中断的管理也会稍微复杂一点,而且中 ...

  5. STM32 GPIO 引脚中断号重复问题的分析

    前言 最近翻出一块[火牛STM32F103]的开发板,在配置[Joystick]与[普通按键]的中断后,发现[Joystick]的一个引脚中断无法触发 GPIO 中断 STM32F103 系列,大部分 ...

  6. 【Aurix系列学习】TC264D最小系统搭建—基本配置引脚

    目录 1. 测试引脚 2. 调试引脚 3. 复位/NMI引脚 /PORST引脚 /ESRx引脚 4. 电源引脚 初始引脚的配置是TC264D单片机的重点,这一块的配置关系到单片机能否正常上电并可靠运行 ...

  7. 扩展中断控制器8259实验_PCIe的中断机制

    出于向下兼容的需要,PCIe完全继承了PCI的所有的中断特性(包括INTx,MSI/MSIx).但是与PCI不同的是,PCIe使用串行总线尽量减少pin的使用,所以对于INTX类型的中断,它没有使用s ...

  8. 32获取外部中断状态_Linux中断一网打尽(1) — 中断及其初始化

    1 中断是什么 既然叫中断, 那我们首先就会想到这个中断是中断谁?想一想计算机最核心的部分是什么?没错, CPU, 计算机上绝大部分的计算都在CPU中完成,因此这个中断也就是中断CPU当前的运行,让C ...

  9. CC2530 输入输出配置、中断配置、时钟、串口配置

    CC2530中文数据手册 IO口,I就是input,O是output,芯片io口输入是外面信号传输到芯片.输出是芯片内部传输信号到其他器件. 如何配置管脚的输入.输出状态? 参考 以配置LED灯为例, ...

最新文章

  1. 大数据学习,涉及的知识点
  2. centos7.6+vim8.1
  3. python怎样实现封装_python封装对象实现时间效果
  4. VTK:图片之ImageOrder
  5. iOS之深入解析UmbrellaFramework的封装与应用
  6. 移动端输入框弹出键盘控制
  7. 看到一个沙粒世界:再一次你好世界
  8. JMS Helloworld
  9. But how to do it? How to avoid direct competition with giants?
  10. 【java学习之路】(javaWeb【后端】篇)004.Thymeleaf
  11. python装饰器详解 带参数-python中的装饰器详解
  12. List集合排序总结
  13. JLink和JFlash使用方法笔记
  14. BZOJ4134 ljw和lzr的hack比赛
  15. 琢磨事琢磨人琢磨钱,成大事也!
  16. Efficient Net
  17. 为什么要处理自然语言? | NLP基础
  18. 生产库,查询库和测试库的区别
  19. RANSAC与其改进
  20. rk3588 驱动调试记录

热门文章

  1. oracle 字典表查询
  2. IIS7的FTP出错: 451 No mapping for the unicode character exists in the target multi-byte code page
  3. SequoiaDB 系列源码分析调整
  4. python爬虫抖音音浪_【Python爬虫】抖音去水印
  5. 拦截器和过滤器区别_新手能看懂的(Interceptor)和(Filter)区别与使用!
  6. 亚马逊出的平板电脑_亚马逊推出新款平板电脑,售价90美元
  7. 武汉大学计算机学院c404,985录取名单(武大)!武大不歧视!80分政治复习路线图!最新调剂信息!...
  8. 左边任务栏_Windows10 系统桌面底部的任务栏在侧边了怎么还原
  9. python中的ch表示什么_材料符号里面的 CH表示什么意思 : ( )
  10. python的django框架是干嘛的_Django框架在Python开发很重要为什么?