Linux APIC 详细分析

现代的APIC

APIC虽号称现代,但也出现10几年了,PC机市场总是很晚才能接触到新的技术,前面说了,我的T42用的还是PIC呢。APIC相较于PIC来说,最大的优点是能适用于MP平台,当然,管脚多是它另一个优点。APIC由两部分组成,一个称为LAPICLocal APIC,本地高级中断控制器),一个称为IOAPICI/O APCII/O高级中断控制器)。前者位于CPU中,在MP平台,每个CPU都有一个自己的LAPIC。后者通常位于南桥上,像PIC一样,连接各个产生中断的设备。在一个典型的具有多个处理器的PC平台,通常有一个IOAPIC和多个LAPIC,它们相互配合,形成一个中断的分发网络,图1-3显示了这个典型的情况:

 

1-3 APIC模式(摘自《深入理解Linux内核》)

图中的中断控制器通信总线,是IOAPICLAPIC通信的桥梁,在IntelP6架构和Pentium系列CPU中,它是一条单独的APIC总线。时代在进步,Pentium4Xeon系列CPU出现后,APIC Bus已经不存在,系统的前端总线代替了它。

1.2.1 IOAPIC

话分两头,让我们先来看看IOAPIC。和PIC对比,IOAPIC最大的作用在于中断分发。根据其内部的PRTProgrammable Redirection Table)表,IOAPIC可以格式化出一条中断消息,发送给某个CPULAPIC,由LAPIC通知CPU进行处理。目前典型的IOAPIC具有24个中断管脚,每个管脚对应一个RTERedirection Table EntryPRT表项)。与PIC不同的是,IOAPIC的管脚没有优先级,也就是说,连接在管脚上的设备是平等的。但这并不意味着APIC系统中没有硬件优先级。设备的中断优先级由它对应的vector决定,APIC将优先级控制的功能放到了LAPIC中,我们在后面会看到。

要搞清楚IOAPIC是怎么工作的,PRT表是关键,下表列出了RTE的格式:

Bit

描述

63:56

Destination Field,目的字段,R/W(可读写)。根据Destination Filed(见下)值的不同,该字段值的意义不同,它有两个意义:

Physical ModeDestination Mode0时): 其值为APIC ID,用于标识一个唯一的APIC

Logical ModeDestination Mode1时):其值根据LAPIC的不同配置,代表一组CPU(具体见LAPIC相关内容)

55:17

Reserved,预留未用。

16

Interrupt Mask,中断屏蔽位,R/W。置一时,对应的中断管脚被屏蔽,这时产生的中断将被忽略。清零时,对应管脚产生的中断被发送至LAPIC

15

Trigger Mode,触发模式,R/W。指明该管脚的的中断由什么方式触发。

1Level,电平触发

2Edge,边沿触发

14

Remote IRR,远程IRRRO(只读)。只对level触发的中断有效,当该中断是edge触发时,该值代表的意义未定义。

当中断是level触发时,LAPIC接收了该中断,该位置一,LAPICEOI时,该位清零。

13

Interrupt Input Pin PolarityINTPOL),中断管脚的极性,R/W。指定该管脚的有效电平是高电平还是低电平。

0:高电平

1:低电平

12

Delivery Status,传送状态,RO

0IDEL,当前没有中断

1Send PendingIOAPIC已经收到该中断,但由于某种原因该中断还未发送给LAPIC

笔者:某种原因,例如IOAPIC没有竞争到总线

11

Destination Mode,目的地模式,R/W

0Physical Mode,解释见Destination Field

1Logical Mode,同上

10:8

Delivery Mode,传送模式,R/W。用于指定该中断以何种方式发送给目的APIC,各种模式需要和相应的触发方式配合。可选的模式如下,字段相应的值以二进制表示:

Fixed 000b,发送给Destination Filed列出的所有CPUleveledge触发均可。

Lowest Priority001b,发送给Destination Filed列出的CPU中,优先级最低的CPUCPU的优先级见LAPIC相关内容)。Leveledge均可

SMI010bSystem Management Interrupt,系统管理中断。只能为edge触发,并且vector字段写0

NMI100bNone Mask Interrupt,不可屏蔽中断。发送给Destination Field列出的所有CPUVector字段值被忽略。NMIedge触发,Trigger Mode字段中的值对NMI无影响,但建议配置成edge

INIT101b,发送给Destination Filed列出的所有CPULAPIC收到后执行INIT中断(详细信息参考相关CPU specINIT中断一节)。触发模式同NMI

ExtINT111b,发送给Destination Filed列出的所有CPUCPU收到该中断后,认为这是一个PIC发送的中断请求,并回应INTA信号(该INTA脚连接到的是与该管脚相连的PIC上,而非IOAPIC上)

笔者:ExtINT用于PIC接在APIC上的情况,见后面的Virtual Wire Mode

7:0

Interrupt Vector,中断向量,R/W。指定该中断对应的vector,范围从10hFEhx86架构前16vector被系统预留,见后面相关内容)

1-1 RTE格式

IOAPIC某个管脚接收到中断信号后,会根据该管脚对应的RTE,格式化出一条中断消息,发送给某个CPULAPIC。从上表我们可以看出,该消息包含了一个中断的所有信息。

题外话 —— Remote IRR有什么用?

Bluesky_jxc同学曾经问我为啥Remote IRRedge触发无用?我说可能是实现相关吧。嗯,通常解释不清楚的问题都可以推到实现相关的头上。这个问题可以画3个等号:“Remote IRR有何用?” == “为什么edge触发不用Remote IRR” == “为什么level触发的EOI要广播到所有IOAPIC

这确实是个实现问题,Intel公司的P.K.Nizar等人在《Multi-Processor Computer System With Interrupt Controllers Providing Remote Reading》中论述了这个问题。这是一篇讲早期APIC系统电路设计的文章,那时还不叫APIC,而是MPICMulti-PIC),扯远了。

Remote IRR实际应该叫“Monitor Remote IRR”,用于监控对应中断管脚的状态。它与中断管脚INTIN#以异或的逻辑驱动IOAPIC的消息单元。异或结果为1时,发送消息。消息分两种:level-assertlevel-deassert。当Remote IRR0INTIN#1,发送level-assert消息,LAPIC收到后将IRR对应bit置一。Remote IRR1INTIN#0,发送level-deassert消息,LAPIC收到后将IRR对应bit清零。

Remote IRR还可以保证level触发中断共享情况下,CPU服务完所有中断。

举个例子,有两个PCI设备(Dev ADev B)共享一个中断管脚INTIN1Dev A先把管脚拉至有效电平(INTIN11),Dev B在一段时间后也同样动作(此时Dev A仍然在有效电平)。当INTIN10跳变到1时,其对应的Remote IRR bit0IOAPIC发送Level Assert消息通知中断发生,Remote IRR1。当CPU处理完Dev A的中断后,发送EOIIOAPIC。此时Remote IRR0,由于Dev B的中断还没处理,INTIN1仍然为1,故又一条中断消息产生。在所有中断处理完后,INTIN10Remote IRR1,发送level-deassert消息,LAPIC清零IRR对应bit。此时INTIN1对应的中断全部处理完。在LAPICDev BEOI时,Remote IRR清零。当CPU正在处理中断时,INT11Remote IRR1,没有中断消息。

对于edge触发中断,由于中断管脚不会一直处于有效电平,故不需要Remote IRREOI广播的原因,上面的论述已有暗示,不废话了。

你可能感兴趣的:(linux,vector,table,System,平台,linux内核)