IRQ和中断

from:IRQ和中断


中断是提高计算机性能和吞吐性的一种设计,在没有中断的时候,每个设备都要等待其他设备,造成资源浪费,所以中断是一个非常有用的。中断中,IRQ和PIC是基础,具体可以看中断的维基百科。

虽然中断可以提高计算机处理性能,但过于密集的中断请求和响应反而会影响系统性能。这种情况下称为中断风暴。

每个能够发出中断请求的硬件设备控制器都有一条名为IRQ(Interrupt ReQuest)的输出线。复杂的设备有多条IRQ线,例如PCI卡可能使用多达4条的IRQ线。所有的IRQ线都与一个名为可编程中断控制器(Programmable Interrupt Controller,PIC)的硬件电路的输入引脚相连,可变成中断控制器执行下面的动作:

  1. 监视IRQ线,检查产生的信号,如果有两条或两条以上的IRQ线上产生信号,就选择引脚编号较小的IRQ线。

  2. 如果一个引发信号出现在IRQ线上,就做相应的处理。

PIC对一个引发在IRQ线上的信号做如下处理:

  1. 把接收到的引发信号转换成对应的向量。

  2. 把这个向量存放在中断控制器的一个I/O端口,从而允许CPU通过数据总线读此向量。

  3. 把引发信号发送到处理器的INTR引脚,即产生了一个中断。

  4. 等待,直到CPU通过把这个中断信号写进可编程中断控制器的一个I/O端口来确认它,当这种情况发生时,清INTR线。

  5. 返回第一步循环处理。

IRQ线总是从0开始顺序编号的,因此,第一条IRQ线通常表示成IRQ0,与IRQn关联的Intel的缺省向量是n+32。正如前面所说,通过向中断控制器端口发布和式的指令,就可以修改IRQ和向量之间的映射。

可以有选择地禁止每条IRQ线,因此,可以对PIC编程从而禁止IRQ,也就是说,可以高速PIC停止对给定的IRQ线发布中断,或者激活它们。禁止的中断是丢失不了的,它们一旦被激活,PIC就又把它们发送到CPU,这个特点被大多数中断处理程序使用,因为这允许中断处理程序逐次地处理同一类型的IRQ。

有选择地激活或禁止IRQ线不同于可屏蔽中断的全局屏蔽和非屏蔽。当eflags寄存器的IF标志被清0时,由PIC发布的每个可屏蔽中断都由CPU暂时忽略。clisti汇编指令分别清除和设置该标志位。

传统的PIC是由两片8259A风格的外部芯片以『级联』的方式连接在一起的,每个芯片可以处理多达8个不同的IRQ输入线,因为从PIC的INT输出线连接到主PIC的IRQ2引脚,因此,可用IRQ线的个数限制为15。

高级可编程中断控制器


以前的描述仅仅涉及为单处理器系统涉及的PIC,如果系统只有一个单独的CPU,那么主PIC的输出线以直接了当的方式连接到CPU的INTR引脚。然而,如果系统中包含两个或者多个CPU,那么这种方式不再有效。

为了充分发挥SMP体系结构的并行性,能够把中断传递给系统中的每个CPU就非常重要,因此Intel从Pentiun III引入了一种名为I/O高级可编程控制器的新组件,用以代替老式的可编程中断控制器。新近的主板为了支持以前的操作都包括两种芯片,此外80x86微处理器当前所有的CPU都含有一个本地的APIC,每个本地APIC都有32位寄存器,一个内部时钟,一个本地定时设备以及为本地APIC中断保留的两条额外的IRQ线LINT0和LINT1,所有本地APIC都连接到一个外部I/O APIC,形成一个多APIC系统。
system

多APIC系统

上图是一个多APIC系统的结构,一条APIC总线把『前端』的I/O APIC连接到本地APIC。来自设备的IRQ线连接到I/O APIC,因此,相对于本地APIC,I/O APIC起路由器的作用。I/O APIC的组成为:

  1. 一组24条的IRQ线。

  2. 一张24项的中断重定向表。

  3. 可编程寄存器。

  4. 通过APIC总线发送和接收APIC信息的一个信息单元。

与8259A的IRQ引脚不同,中断优先级并不与引脚号相关联,中断重定向表中的每一项都可以被单独编程以指明中断向量和优先级、目标处理器以及选择处理器的方式。重定向表中的信息用于把每个外部IRQ信号转换成一条消息,然后通过APIC总线发给一个或多个APIC单元。

来自外部硬件设备的中断请求以两种方式在可用CPU之间分发:

  1. 静态分发,IRQ信号传递给重定向表和相应项中所列出的本地APIC,中断立即传递给一个特定的CPU或一组CPU,也可以通过广播的方式发送给所有CPU。

  2. 动态分发,如果处理器正在执行最低优先级的进程,IRQ信号就传递给这种处理器的本地APIC,每个本地APIC都有一个可编程任务优先级寄存器TPR,TPR用来计算当前运行进程的优先级。

如果两个或多个CPU共享最低优先级,就利用仲裁技术在这些CPU之间分配负荷,在本地APIC的仲裁优先级寄存器中,给每个CPU都分配一个0~15范围内的值,其中0最低,15最高。

每当中断传递给一个CPU时,其相应的仲裁优先级就自动设置为0,而其他的每个CPU的仲裁优先级都增加1,当仲裁优先级寄存器大于15时,就把它置为获胜CPU的前一个仲裁优先级加1的值。因此中断以轮转方式在CPU之间分发,具有相同的任务优先级。

除了在处理器之间分发中断外,多APIC系统还允许CPU产生处理器间中断。当一个CPU希望把一个中断发送给另一个CPU时,它就在自己本地APIC的中断指令寄存器中存放这个中断向量和目标本地APIC的标识符,然后通过APIC总线向目标本地APIC发送一条消息,从而向自己的CPU发出一个相应的中断。

处理器之间的中断简称IPI,时SMP体系结构定义非常重要的一部分,并由Linux有效地用来在CPU之间交换信息。

目前大部分处理器系统都包含一个I/O APIC芯片,可以用以下两种方式对这种芯片进行配置。

  1. 作为一种标准8259A方式地外部PIC连接到CPU,本地APIC被禁止,两条LINT0和LINT1本地IRQ线分别配置为INTR和NMI引脚。

  2. 作为一种标准外部I/O APIC,本地APIC被激活,且所有地外部中断都通过I/O APIC接收。