Intel x86架构之多处理器与APIC

注意:下文中已经指出手册中的对应页面和章节,请对照手册原文看,任何个人理解错误,请包涵。
一,以下内容来自(P25):3.6 Multiprocessor Interrupt Control
在多处理器系统上,中断通过APIC进行控制。下面将描述APIC架构和多处理器系统上的三种不同中断模型。

APIC基于分布式架构,中断控制功能有两个基本的功能组件,分别为本地单元(lapic)和I/O单元(io apic)。本地单元和I/O单元之间通过ICC总线进行通信。I/O单元类似于中断输入器,它通过ICC总线把中断分发到本地单元,而对应的本地单元就接收并处理对应的中断消息。

在多处理器系统上,每一个CPU都需要有一个对应的lapic吗,而根据总共的中断线数,需要一个或多个io apic。
Intel 82489DX APIC是一款离散式APIC的实现,与此相对,还有集中式APIC的实现。不管是老旧的离散式APIC,还是新近的集中式APIC,它们都包含有一个版本寄存器(version register),分别存储以数值0x和1x(其中x表示十六进制数据)。

为了更好的扩展,Intel APIC架构仅规定了APIC单元的编程接口,而ICC总线协议以及电气规格特性却是与具体实现相关联的。这意味着不同版本的APIC实现可以运行相同的二进制软件,但各个不同版本的APIC部件可能具有不同总线协议或电气规格特性的实现。在使用不同版本的APIC时需格外注意。

APIC架构被设计为可伸缩扩展。82489DX APIC有8bit的ID寄存器,可以表示最多255个APIC设备,此外,它的逻辑目标寄存器(Logical Destination register)可支持32bit,可以表示最多32个设备。对于小型系统实现,APIC ID寄存器可以缩减到最少4bit,而逻辑目标寄存器可以缩减到最少8bit。

为了保证所有APIC实现版本的软件兼容性,软件开发者最好遵循如下编程准则:
1,分配8bit的APIC ID号时需从零开始。
2,分配逻辑目标时从32bit寄存器的MSB开始。(MSB,最高有效位,一般是位于二进制数的最左侧,请参考http://en.wikipedia.org/wiki/Most_significant_bit)
3,将APIC的估算虚假向量(spurious vector)设置为xF,其中x为4bit的十六进制数据。

如下特性仅在集中式APIC上可用:
1,io apic中断输入信号极性(input signal polarity)可编程。
2,名为STARTUP IPI的新IPI中断被定义。

一般而言,在集中式APIC的系统上,操作系统必须使用STARTUP IPI来唤醒其它应用处理器(application processors),而在82489DX APIC的系统上,需使用INIT IPI来唤醒其它应用处理器。

二,以下内容来自(P26):3.6.2 Interrupt Modes
多处理器系统的三种不同中断模式:
1,PIC模式(PIC Mode):绕开所有APIC组件,强制系统使用单核模式。
2,虚线模式(Virtual Wire Mode):使用一个APIC作为虚拟线,其它同PIC模式。
3,对称I/O模式(Symmetric I/O Mode):系统启用多个处理器。

前两种模式提供PC/AT兼容,而第三种模式需实现在前面两种模式中任何一种的基础之上。一个多处理器系统以前面两种模式中任何一种启动,然后再切换到第三种模式,从而实现进入到多处理器模式下。

其它:
1,大多数较新的机器支持高级配置和电源接口(ACPI),而ACPI包含有MPS的功能,所以MPS逐步将被ACPI所取代。
2,不管是MPS还是ACPI,都是由BIOS程序根据当前机器硬件写好对应的条目,然后OS启动后读取这些条目进行初始化。

参考:
1,http://en.wikipedia.org/wiki/MultiProcessor_Specification
2,http://en.wikipedia.org/wiki/Advanced_Configuration_and_Power_Interface
3,http://en.wikipedia.org/wiki/Intel_APIC_Architecture
4,http://www.acpi.info/

转载请保留地址:http://www.lenky.info/archives/2013/04/2250 或 http://lenky.info/?p=2250

我是在处理一个网卡中断分发问题时看的这些内容,因为是外部中断到处理器的分发问题,因此我关注的重点是I/O APIC和外部设备中断,所以下面这部分内容以及接下来的两篇文章都是从手册里挑着看的。
全文来自Intel开发者手册:Intel? 64 and IA-32 Architectures Software Developer’s Manual Volume 3A System Programming Guide.pdf

注意:下文中已经指出手册中的对应页面和章节,请对照手册原文看,任何个人理解错误,请包涵。

一,以下内容来自(P459):CHAPTER 10 ADVANCED PROGRAMMABLE INTERRUPT CONTROLLER (APIC)
local APIC(后续简写为lapic)为处理器主要做两个事情:
1,接收来自内部(具体见后面的中断源介绍)或外部(比如I/O APIC或其它中断控制器)的中断,并把它们发送给cpu核心进行处理。

2,在多处理器系统(multiple processor (MP) systems)上,lapic用于发送和接收处理器间中断(即interprocessor
interrupt (IPI))信息。IPI可用于把中断分发到系统的多个处理器上,或执行一些系统级的功能。

I/O APIC(后续简写为io apic)属于Intel系统芯片组的一部分,它和外部I/O设备相连并把这些设备的I/O请求作为中断信息转达给lapic。在多处理器系统上,io apic可以将外部中断分发到某个或某组选定的处理器的lapic。

本章仅描述lapic的内容,关于io apic,请见参考1。

二,以下内容来自(P459):10.1 LOCAL AND I/O APIC OVERVIEW
每一个lapic都由一系列的APIC寄存器以及相关硬件组成,它们用于控制中断的投递和IPI信息的产生。APIC寄存器可以通过mov指令进行读/写操作。

lapic可接收以下来源的中断:
1,本地连接的I/O设备(Locally connected I/O devices):这些I/O设备要么直接连接到处理器的本地中断引脚(即LINT0和LINT1),要么是和与处理器的某个本地中断引脚相连的8259类型中断控制器相连。

2,外部连接的I/O设备(Externally connected I/O devices):这些I/O设备与io apic相连,因此设备中断通过io apic投递到一个或多个处理器进行处理。

3,IPI中断(Inter-processor interrupts (IPIs)):Intel 64或IA-32架构上的处理器可使用IPI机制通知系统总线上的另外一个或一组处理器,因此IPI可用来实现软件自我中断(software self-interrupts)、中断转发或抢占式调度。

4,APIC定时器产生中断(APIC timer generated interrupts):通过对lapic定时器进行编程,可以实现在指定时间到达时,向其关联的处理器发送一个本地中断。

5,性能监视计数器中断(Performance monitoring counter interrupts):P6、奔四和至强的处理器提供可在性能监视计数器溢出时,向其关联的处理器发送一个中断的能力。

6,热传感器中断(Thermal Sensor interrupts):奔四和至强的处理器提供可在触发热传感器时,向其关联的处理器发送一个中断的能力。

7,APIC内部错误中断(APIC internal error interrupts):可对APIC进行编程,当lapic内发生一个错误(比如尝试访问尚未实现的寄存器)时,向其关联的处理器发送一个中断。

上面所列中的1、4、5、6、7均被称为本地中断源(local interrupt sources)。当从本地中断源接收到一个中断时,lapic按照APIC的LVT(local vector table)寄存器设置的中断投递协议(interrupt delivery protocol)进行投递。LVT为每一个本地中断源都准备了一个单独的LVT条目,因此可以设置各自不同的特定投递协议。举个例子,如果引脚LINT1准备用来作为NMI中断源,那么LVT中对应LINT1的条目需设置中断向量号为2(即NMI中断)。

通过对lapic的ICR(interrupt command register)寄存器进行编程可使对应处理器产生IPI中断。对ICR进行写操作,就会导致产生一个IPI信息并发送到系统总线(system bus,奔四和至强)或APIC总线(APIC bus,奔腾和P6)。IPI可以被发送到系统的其它处理器或发送给自身(即self-interrupts)。

lapic同样接收来自外部连接设备的中断,这些中断通过io apic进行转交,即由io apic接收系统硬件和I/O设备产生的中断,并把它们作为中断信息转发给lapic。

可以对io apic的引脚进行单独编程,以实现当对应引脚被置位时产生某个特定的中断向量。io apic还有一个虚拟线模式(virtual wire mode)允许它与标准的8259A型外部中断控制器进行通信。由于lapic可以被关闭,因此处理器可以直接接收到8259A型中断控制器的中断。

lapic和io apic都是为多处理器系统而设计的,lapic处理来之io apic的中断,或来之其它处理器的IPI中断,或自身产生的中断。虽然中断同样可以通过本地中断引脚(local interrupt pins)投递到单独的处理器,但这种机制在多处理器系统上并不常用。

在多处理器系统上,IPI机制的典型应用是用来发送固定的中断(即特定向量号的中断)和为了特定的目的而中断系统总线上的处理器。举个例子,lapic可以使用IPI来转发某些固定的中断到其它处理器进行服务。特定目的的IPI(例如NMI、INIT、SMI和SIPI)允许系统总线上的一个或多个处理器执行系统级的启动和控制功能。

三,以下内容来自(P463):10.2 SYSTEM BUS VS. APIC BUS
在P6和奔腾处理器上,io apic和lapic通过3线APIC间总线(3-wire inter-APIC bus)进行通信。lapic同样也使用APIC总线进行IPI的发送与接收。APIC总线和APIC总线信息对软件来说是不可视的,并且没有规划架构。(应该是指lapic还只是属于Intel 82489DX外部APIC架构的一部分,而没有独立划分为一个架构)

而在奔四和至强处理器上,io apic和lapic通过系统总线进行通信,统一为xAPIC架构。io apic通过Intel芯片组的网桥硬件产生发往lapic的中断信息向系统上的处理器发送中断请求。lapic之间的IPI信息通过系统总线直接传送。

四,以下内容来自(P463):10.3 THE INTEL? 82489DX EXTERNAL APIC, THE APIC, THE XAPIC, AND THE X2APIC

在P6和早期奔腾处理器上,lapic只是属于Intel 82489DX外部APIC架构的一部分,而在奔四和至强处理器上,APIC架构得到了进一步的扩展而被称为xAPIC。APIC与xAPIC两种架构之间最大的不同在于xAPIC架构里lapic与io apic通过系统总线进行通信,而在APIC架构里,它们通过APIC总线通信。另外,APIC架构里的部分特征在xAPIC里得到了扩展或修改。

xAPIC的基本操作模式为xAPIC模式。xAPIC架构的进一步扩展为x2APIC架构,主要是提升了处理器寻址能力(processor address ability)。x2APIC架构提供向后兼容(即兼容xAPIC)和向前扩展(即未来Intel新平台)的能力。

五,以下内容来自(P470):10.4.6 Local APIC ID
在通电启动后,系统硬件就会为系统总线或APIC总线上的每一个lapic分配一个唯一的APIC ID号,而该APIC ID号是基于系统拓扑结构和SOCKET位置编码以及簇聚特征进行分配的。在多处理器系统上,lapic的ID号也被BIOS和OS用作处理器ID号。某些处理器允许软件修改APIC ID号,但具体怎么修改依赖于具体的处理器型号,正因为如此,OS软件应该避免去修改lapic ID寄存器。

在P6和奔腾处理器上,lapic的ID号只占4bit,可以用0x0-0xe表示APIC总线上的15个不同处理器。在奔四和至强处理器上,xAPIC将ID号扩展到8bit,因此可以表示最多255个不同的处理器。x2APIC将ID号扩展到32bit,其低8bit用于兼容xAPIC的ID号。

六,以下内容来自(P473):10.4.8 Local APIC Version Register
lapic有一个硬连线版本寄存器(hardwired version register),软件可以通过这个寄存器识别APIC版本。另外,这个寄存器还指定了LVT中的具体条目个数。
三个重要字段:
version(8bit):lapic的版本号。0x1x(前面的0x表示是16禁止,而第二个x表示任意数字)为Local APIC,比如奔四和至强处理器,则是0x14;0x0x为82489DX外部APIC。

Max LVT Entry(8bit):具体LVT条目个数减1。奔四和至强处理器,该值为5;P6处理器为4;奔腾处理器为3。

Suppress EOI-broadcasts(1bit):表示是否可通过软件置位伪中断向量寄存器(Spurious Interrupt Vector Register)第12bit的方式阻止EOI消息的广播。

七,以下内容来自(P474):10.5 HANDLING LOCAL INTERRUPTS
这一章主要描述lapic所提供的处理本地中断的能力,因为当前我不关注一块,所以暂且略过。如果是关注LVT时钟寄存器、温度监控寄存器、性能计数寄存器、LINT0寄存器、LINT1寄存器等,可以仔细看这一章内容。

八,以下内容来自(P484):10.6 ISSUING INTERPROCESSOR INTERRUPTS
这一章主要描述lapic所提供的通过软件方式触发IPI中断的能力,主要也就是ICR寄存器(interrupt command register)。
ICR寄存器有如下功能:
1,发送一个中断到另外一个处理器。
2,允许处理器转发一个它已收到但尚未处理的中断到另外一个处理器进行服务。
3,处理器发送一个中断给自己(self interrupt)。
4,传送特定的IPI(比如SIPI,即start-up IPI)到另外的处理器。

通过ICR寄存器产生的中断通过系统总线或APIC总线进行传送。处理器发送最低优先IPI(lowest priority IPI)的能力是与特定型号相关的,因此BIOS和OS软件需避免使用它。

九,以下内容来自(P490):10.6.2 Determining IPI Destination
IPI中断的接收者目标可以是系统总线上一个、一组或全部处理器。IPI的发送者通过如下APIC寄存器和寄存器内字段来指定中断接收者。
1,ICR寄存器:使用如下寄存器字段来指定IPI接收者。
Destination Mode:目标模式:选择目标模式,可以是physical或logical。
Destination Field:目标字段:如果是physical目标模式,那么该字段用于指定目标处理器的APIC ID号。如果是logical目标模式,那么该字段用于指定MDA(message destination address),而MDA被用来指定cluster聚类里的某一个或多个处理器。
Destination Shorthand:目标快速记法:用来指定全部处理器、除自己以外的全部处理器或自己这三种情况之一的简便快速方法。
Delivery mode, Lowest Priority:投递模式,最低优先:一种与具体架构相关的最低优先仲裁机制,用于在指定的一组处理器里选择一个目标处理器。因为这种机制与具体的CPU架构相关,因此应该避免在BIOS和OS里使用它。

2,Local destination register (LDR):配合logical目标模式中的MDA一起使用,用于选择目标处理器。

3,Destination format register (DFR):配合logical目标模式中的MDA一起使用,用于选择目标处理器。

十,以下内容来自(P491):10.6.2.1 Physical Destination Mode
在physical目标模式下,通过指定lapic ID号来选择目标处理器。对于奔四和至强处理器而言,这既可以是单一目标(lapic ID从00H到FEH),也可以是广播到所有APIC(lapic ID为FFH)。
MDA的28-31bit位为1的广播IPI(应该是接着上一句说的,即在奔四和至强处理器上,0FH不是广播地址,所以这里才说不被支持,后面会提到0FH是P6和奔腾处理器上的广播地址)或被初始化为最低优先投递模式的I/O子系统不被physical目标模式支持,所以软件(这个软件应该设置BIOS或OS)不能做这样的配置。对于任何非广播IPI或被初始化为最低优先投递模式的I/O子系统,软件必须保证中断地址里的目标APIC存在并且可以接收中断。
对于P6和奔腾处理器而言,单一目标的lapic ID从0H到0EH,广播到所有APIC为0FH。

注意:系统总线上可寻址的lapic个数可能会受到硬件的限制。

十一,以下内容来自(P491):10.6.2.2 Logical Destination Mode
在logical目标模式下,通过一个存在于ICR寄存器目标字段里的8bit消息目标地址(message destination address,MDA)来指定IPI目标。当接收到一个通过logical目标模式投递的IPI消息时,lapic将拿消息里的MDA与其LDR和DFR寄存器进行比较,以确定是否需要接受并处理这个IPI。不管是logical目标模式,还是配合最低优先投递模式的logical目标模式,软件都必须负责保证所有的lapic都能够被寻址到(例如如果有超过8个CPU,那么软件就不能设置使用平坦模式,因为它最多只能寻找8个CPU)。

寄存器Logical Destination Register (LDR):
地址:0FEE0 00D0H
重置后值:0000 0000H
字段:
24:31:Logical APIC ID,逻辑APIC ID。这个逻辑ID(logical APIC ID)不要和本地ID(local APIC ID)搞混。
0:23:Reserved,保留。

寄存器destination format register (DFR):
地址:0FEE0 00E0H
重置后值:FFFF FFFFH
字段:
28:31:model,选择flat(1111B)或cluster(0000B)之一。
0:27:保留,全1。

MDA地址可以按两种模式进行解释:
Flat Model:平坦模式。
DFR寄存器的28-31bit为全1。在这种模式下,通过设置每一个lapic的LDR寄存器的逻辑APIC ID字段的不同bit位,最多可以给8个(因为逻辑APIC ID字段只有8bit位)不同的lapic建立各自不同的逻辑APIC ID号。这样之后,通过设置MDA中的一个或多个bit位,可选择一个或多个目标lapic。每一个lapic把它的逻辑APIC ID与MDA进行位与操作,如果为真,则表示是目标lapic,因此接受并处理IPI消息。通过设置MDA为全1,即为广播消息到所有lapic。

Cluster Model:聚类模式。
DFR寄存器的28-31bit为全0。这种模式又支持两种基本目标方案:平坦聚类(flat cluster)和分层聚类(hierarchical cluster)
平坦聚类仅被P6和奔腾处理器支持,使用这种模式的话,会假定所有APIC都通过APIC总线相连。MDA的bit60-63包含目标聚类的编码地址,而bit56-59则用于指定目标聚类里的目标lapic(因为只有4bit,所以最多4个lapic)。先比较MDA的bit60-63与LDR的bit28-31,判断当前lapic是否属于目标聚类;然后比较MDA的bit56-59与LDR的bit24-27,判断当前lapic是否属于目标聚类里的目标lapic;总共可以有15个聚类(地址从0到14),并且每个聚类可以有4个lapic。
对于P6和奔腾处理器的lapic而言,由于APIC仲裁ID只支持15个APIC代理(agent),因此在这种模式下,支持的处理器总数也就限制在15以内。通过设置目标bit位为全1即可达到广播到所有lapic的目的,因为它可以保证匹配所有聚类和选中每个聚类里的所有apic。最低优先投递模式下的广播IPI或I/O子系统广播中断不被聚类模式支持,因此软件不要做这样的配置。

分层聚类可以被奔四、至强以及P6和奔腾处理器使用。在这种模式下,通过不相关联的系统总线或APIC总线把各种不同的平坦聚类连接起来形成一个分层网络。这种模式需要每一个聚类都有一个聚类管理器,它负责对系统总线或APIC总线上的消息进行处理。一个聚类可以包含最多4个代理。15个聚类管理器,每一个聚类管理器有4个代理,那么整个分层网络可以最多有60个APIC代理。值得注意的是:分层APIC网络需要一个不属于lapic或io apic单元的特殊的聚类管理器设备(special cluster manager device)。

参考:
1,Intel? 82093AA I/O Advanced Programmable Interrupt Controller (I/O APIC) Datasheet
http://www.intel.com/design/chipsets/datashts/290566.htm
Intel? 82093AA I/O Advanced Programmable Interrupt Controller (I/O APIC) Specification Update
http://www.intel.com/design/chipsets/specupdt/290710.htm

2,MultiProcessor Specification(http://download.intel.com/design/pentium/datashts/24201606.pdf)
Version 1.4
May 1997

转载请保留地址:http://www.lenky.info/archives/2013/04/2252 或 http://lenky.info/?p=2252

Published by

风君子

独自遨游何稽首 揭天掀地慰生平