中断 INTX 》MSI 》MSI-X

本文详细解释了CPU如何通过中断处理各种硬件事件,从传统的INTX中断到MSI和MSI-X的升级,探讨了中断控制器、中断请求流程、IDT和中断向量表的作用,以及MSI的连续中断限制和MSI-X的突破。还介绍了Linux和Windows下的实践操作,如查看中断统计和设置中断亲和性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简单来说,CPU正忙着做自己的事情,这时硬件(例如键盘按下)触发了一个电信号,该信号通过中断线传给中断控制器,中断控制器接收到这个信号,向CPU发送一个信号,申请CPU执行刚才的硬件操作, 然后在执行后向中断控制器发送信号,告知它已被处理。

中断演进 : INTX -》MSI -》 MSI-X

先说 INTX:

如下一个CPU图:

标记为红色的两个引脚是 80386 处理器为中断保留的两个引脚。其中 INTR 是可屏蔽的中断输入端口,NMI 是不可屏蔽的中断输入端口。

问:如何将中断输入到处理器?    外部设备那么多,但 cpu 只有一个输入引脚?

那就需要用到中断控制器了

可编程中断控制器 (PIC)如下:

IR0-IR7:负责连接外部设备,中断输入。

D0-d7:连接系统总线的数据线,数据输入,对应上面CPU d0-d31。

INT:中断请求信号,输出,连接CPU INTR。

通常,8259A芯片是两级级联,总共可以连接8 x 8=64个外围设备。

连接拓扑如下:

中断处理过程

当键盘发生中断事件时。此事件通过 IRQ1 中断线通知主PIC。经过一些内部判断和处理后,主PIC通过int向CPU侧的“INT”发送电信号。执行当前指令后,CPU检查“INT”中是否有信号,表示有中断请求。然后它检查如果 EFLAGS 不为零,表示当前允许处理中断,就向 pic 的“INTA”发送信号,告诉它发送该中断的“vector number”。在接收到信号后,该向量通过d0-d7引脚将中断编号发送到CPU。CPU 获取此编号后,可以从 IDT 中找到中断服务例程 (ISR) 进行处理。执行后,向 i8259a 发送 “INTA” 信号,表示它已经完成了刚才的请求。

IDT 中断向量表,或者叫门描述符,对应了各个中断号的处理函数,大概如下的形式:

32

Intr_deal_function_32

33

Intr_deal_function_33

34

Intr_deal_function_34

35

35

IDTR 寄存器保留 IDT 表的基址

中断编号 +32 = 中断向量 Linux

中断编号 +48 = 中断向量 Win

再说MSI:

INTX 最多支持 64 个中断,随着中断数量的增加,芯片组引脚不够用,因此引入了 MSI。

英文:Message Signaled Interrupt

MSI 允许设备将一小段数据(消息数据)写入指定的 MMIO 地址(消息地址),然后芯片组生成中断给 CPU

配置空间如下:

Capability ID = 0x5

Message Control bit :

Bit-0   : MSI enable

Bit1-3 : the number of interrupts supported,4^xx

Bit4-6 : the number of interrupts enabled, 4^xx

Bit7      : 1=64-bit address structure ,0=32-bit

Bit8      : 1=support mask , 0= not support

Why is only 32 interrupts supported?

Why it require a continuous interrupt number?

常常看到MSI单设备支持32个中断,为什么呢,从上图可以看到

MASK BIT就只有32位,所以只能支持32个中断。

Bit4-6来看,enable的中断只能是1,4,8,16,32,并不能指定1 3 5这样的enable方式,

所以msi支持的中断号必须是连续的。

Message Address

Message Address :当中断来临时,PCIE将消息数据写入此地址

Message Address格式如图

Address Format : 0xFEEx-xxxx

Destination Id :    target cpu id

RH :                      0= sent to the specify cpu; 1= select one from the all CPUs

DM :                     0= physical cpu; 1= virtual cpu

当我们把数据写给0FEEXXXX的时候,实际上是写给LAPIC的,所以当我们写地址的时候,会触发CPU中断。

Linux系统上面可以尝试一下操作:

MSI  Message Data

Message Data :存放MSI消息使用的数据。

Message Data和Message Address由系统在计算机启动时就已经配置好了。

Message Data格式如下:

Bit0-7 : 此 8 位字段包含与消息关联的中断向量。取值范围从 010H 到 0FEH。

Trigger Mode :0=表示边缘敏感。1=表示电平敏感。

Bit8-10 : Delivery Mode,This 3-bit field specifies how the interrupt receipt is handled.

0= Fixed Mode

1= Lowest Priority

10= System Management Interrupt or SMI

100=NMI

最后是MSI-X:

MSI 要求中断数是连续的,现在单个设备 32 个中断也不够用,所以引入了 MSI-X。

MSI-X 不要求中断数是连续的,单个设备支持 2048 个中断。

MSI-X 如何支持 2048 中断?

配置空间如下:

Message Control

Bit0-10 : Table size, 2^10=Max 2048 interrupts

Bit14 : 1 = Mask all interrupt 

MSI-x table offset : the offset over bar

Table BIR : the number of the bar

MSI-x 信息记录到BAR上面,每个中断会在BAR上有一条记录,中断信息在BAR上的记录的样子如下:

每个中断都使用单独的“消息地址”字段和“消息数据”字段。

一些实践性操作

Linux下小实验:

Watch ‘cat /proc/interrupts’

设置亲和性:

Windows 中断亲和性

注册表中配置:

windows亲和性工具:

Interrupt_Affinity_Policy_Tool

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luopandeng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值