Intel SDM 之 APIC [1]

转自https://zhuanlan.zhihu.com/p/678581983
0. 目录

  1. 垫话

  2. 前言

  3. local and I/O APIC 概述[10.1]

  4. 系统总线及 APIC 总线[10.2]

  5. Intel 82489DX external APIC, APIC, xAPIC 及 x2APIC[10.3]

  6. local APIC[10.4]

6.1 local APIC 架构图[10.4.1]

6.2 local APIC 检测[10.4.2]

6.3 使能/禁能 local APIC[10.4.3]

6.4 local APIC 状态及位置[10.4.4]

6.5 local APIC 寄存器的重定位[10.4.5]

6.6 local APIC ID[10.4.6]

6.7 local APIC 状态[10.4.7]

6.7.1 上电或重启后的 local APIC 状态[10.4.7.1]

6.7.2 被软件禁能后的 local APIC 状态[10.4.7.2]

6.7.3 INIT reset 后的 local APIC 状态(“wait-for-SIPI” 状态)[10.4.7.3]

6.7.4 接收到 INIT-deassert IPI 后的 local APIC 状态[10.4.7.4]

6.8 local APIC 版本寄存器[10.4.8]

  1. 垫话
    本文乃 Intel SDM “Chapter 10 Advanced Programmable Interrupt Controller(APIC)” 一章的翻译。

要点概述:

local APIC 的中断源分为内部和外部:内部中断源(CPU 中断引脚直连设备、APIC timer、 IPI 等)的投递由 LVT 定义,外部中断源中断由 I/O APIC 投递过来。
I/O APIC 是芯片组的一部分(也就是南桥之上、CPU package 之外)。APIC 架构下,I/O APIC 与 local APIC 通过 APIC 总线互联,xAPIC 架构下通过系统总线互联,x2APIC 主要是对 xAPIC 做了一些寄存器字长的扩展。
番外:8259 接在 I/O APIC 上,正因如此,操作系统若想要用古早的 PIT 定时器做系统 tick,必须广播。
2. 前言
Advanced Programmable Interrupt Controller(APIC),本文简称 local APIC。

APIC 主要干两件事:

从处理器的中断管脚(pin)、内部中断源及外部 I/O APIC(或其他外部中断控制器)上接受中断,并将中断发送给处理这些中断的处理器。
在多处理器(MP)系统中,其接受系统总线上其他核的核间中断(interprocessor interrupt,IPI),并发送给其他逻辑处理器。IPI 消息用于在处理器之间发送中断,或执行系统功能(比如,启动一个处理器,或在处理器之间分发任务,译者注:典型如 linux 的 smp call 及 smp boot-up)。
外部 I/O APIC 是 Intel 系统芯片组的一部分。其基本功能是从系统及相关 I/O 设备接受外部中断事件,并以中断消息的形式投递给 local APIC。在 MP 系统中,I/O APIC 还提供了一种机制,可以将外部中断投送给所选处理器或处理器组的 local APIC。

本章概述 local APIC 及其编程接口,并描述了 local APIC 与 I/O APIC 间接口的大图。

  1. local and I/O APIC 概述[10.1]
    每个 local APIC 包含一组 APIC 寄存器(Table 10-1),以及控制中断投递及 IPI 消息生成的附属硬件。APIC 寄存器是 memory mapped 的,可以通过 MOV 指令操作。

local APIC 可以从如下源接收中断:

locally connected I/O 设备:这类设备通过处理器的本地中断管脚(LINT0 及 LINT1)直连到处理器,通过边沿或电平触发中断。I/O 设备也可以连接到 8259 型中断控制器,后者又通过本地中断引脚连接到处理器。
externally connected I/O 设备:这类设备连接到一个 I/O APIC 的中断输入管脚上,并通过边沿或电平触发中断。这些中断以 I/O 中断消息的形式,从 I/O APIC 发送给一到多个处理器。
Inter-processor interrupts(核间中断,IPIs):一个 Intel 64 或 IA-32 处理器可通过 IPI 机制来中断系统总线上的其他某个或一组处理器。IPIs 可用来实现 software self-interrupts、interrupt forwarding 或抢占调度(译者注:linux 开启内核抢占时,可在中断上下文返回时,做抢占调度,IPIs 可以用来向另外一个核发送中断,进而触发此抢占调度机制,内核 smp_send_reschedule《[调度 1] 调度相关的元问题》)。
APIC timer 生成的中断:local APIC timer 在计数达到目标值时,会向所属处理器发送一个本地中断(Section 10.5.4,“APIC Timer”)。
performance monitoring counter 中断:performance-monitoring counter 溢出的时候,可向所属处理器发送一个中断(Section 18.6.3.5.8, “Generating an Interrupt on Overflow”)。
thermal sensor 中断:温度传感器可向所属处理器发送中断(Section 14.8.2, “Thermal Monitor”)。
APIC 内部错误中断:local APIC 出现错误时(比如尝试访问未实现的寄存器),APIC 可向所属处理器发送一个中断(Section 10.5.3, “Error Handling”)。
处理器 LINT0、LINT1 管脚、APIC timer、performance-monitoring counters、thermal sensor 及 APIC 内部错误 detector,被称为内部中断源。从内部中断源接收到中断时,local APIC 将遵循由一组被称为 local vector table 或 LVT 的 APIC 寄存器所定义的投递协议,将中断投递给处理器核(Section 10.5.1, “Local Vector Table”)。每个本地中断源在 local vector table 中占据一个 entry,其为每个中断源建立了一个中断投递协议。举例来说,如果要将 LINT1 引脚用作 NMI 引脚,则 local vector table 中的 LINT1 entry 应该被配置为向处理器核投递一个 vector number 2(NMI 中断)的中断。

local APIC 通过 IPI 消息处理机制来处理另外两个中断源(externally connected I/O 设备及 IPIs)。

一个处理器可以通过对其 local APIC 中的 interrupt command register(ICR)(Section 10.6.1, “Interrupt Command Register(ICR)”)进行编程来触发 IPIs。对 ICR 的写入会在系统总线(Pentium 4 及 Intel Xeon 处理器)或 APIC 总线(Pentium 及 P6 family 处理器)上生成一个 IPI 消息。Section 10.2,“System Bus Vs. APIC Bus”。

IPI 可以被发送至系统中的其他处理器,或者发给触发 IPIs 的处理器(self-interrupts)。目标处理器接收到 IPI 消息后,其 local APIC 会自动处理该消息(利用消息中包含的诸如 vector number 及 trigger mode 信息)。Section 10.6,“Issuing Interprocessor Interrupts”详述了 local APIC IPI 消息的发送及接收机制。

local APIC 还可以通过 I/O APIC 接收来自 externally connected 设备的中断(Figure 10-1)。I/O APIC 负责接收来自系统硬件及 I/O 设备产生的中断,并将其转发至 local APIC。

在这里插入图片描述

I/O APIC 中的各引脚可以被编程以产生一个指定的中断 vector。I/O APIC 还有一个“virtual wire mode”,支持与一个标准 8259A 型的外部中断控制器通信。注意,local APIC 可以被禁能(Section 10.4.3, “Enabling or Disabling the Local APIC”)。这允许所属处理器可以直接从一个 8259A 中断控制器接收中断。

local APIC 及 I/O APIC 都是为 MP 系统设计的(Figure 10-2 与 10-3)。每个 local APIC 处理来自 I/O APIC 的中断、来自系统总线上处理器的 IPIs,以及 self-generated interrupts。中断还可以通过处理器的 local interrupt 引脚投递给处理器;但是,在 MP 系统上一般用不到。
在这里插入图片描述

IPI 机制在 MP 系统中通常被用来向系统总线上的处理器发送 fixed 中断(指定 vector number 的中断)或特定用途的中断。具体来说,一个 local APIC 可以使用一个 IPI 来向其他处理器发送一个 fixed 中断以获取服务。特定用途的中断(包括 NMI,INIT,SMI 以及 SIPI IPIs)支持系统总线上的一到多个处理器进行 boot-up 及控制。

  1. 系统总线及 APIC 总线[10.2]
    对于 P6 family 及 Pentium 处理器来说,I/O APIC 与 local APICs 之间通过 3 根线的内部 APIC 总线(Figure 10-3)来通信。local APIC 还会通过 APIC 总线来收发 IPIs。APIC 总线及其消息对软件是不可见的,而且并不是 architectural 的(译者注:意思就是 implementation specific 的)。

从 Pentium 4 以及 Intel Xeon 处理器开始,I/O APIC 与 APICs(使用 xAPIC 架构)之间通过系统总线通信(Figure 10-2)。I/O APIC 通过 Intel 芯片组中的 bridge 硬件来向系统总线上的处理器发送中断请求。bridge 硬件生成发往 local APICs 的中断消息。local APICs 之间的 IPIs 直接通过系统总线来传递。

  1. Intel 82489DX external APIC, APIC, xAPIC 及 x2APIC[10.3]
    P6 family 及 Pentium 处理器中的 local APIC,是 Intel 82489DX external APIC 架构的子集。Section 22.27.1,“Software Visible Differences Between the Local APIC and the 82489DX”。

Pentium 4 及 Xeon 处理器中使用的 APIC 架构(xAPIC 架构)是 P6 family 处理器中 APIC 架构的一个扩展。APIC 与 xAPIC 架构之间主要的区别在于,xAPIC 架构下,local APICs 与 I/O APIC 之间通过系统总线通信;APIC 架构下,二者是通过 APIC 总线来通信的(Section 10.2, “System Bus Vs. APIC Bus”)。另外,一些 APIC 架构特性在 xAPIC 架构中被扩展或修改了,这些扩展及修改在 Section 10.4 至 Section 10.10 章节。

xAPIC 的基本操作模式为 xAPIC mode。x2APIC 架构是 xAPIC 架构的扩展,主要是对处理器寻址能力进行了增强。x2APIC 架构提供了对 xAPIC 架构的向后兼容,并为未来 Intel 平台提供了向前扩展性。新模式(x2APIC mode)下的扩展及修改见 Section 10.12。

  1. local APIC[10.4]
    以下章节描述 local APIC 的架构,以及如何检测、识别并决定其状态。如何对 local APIC 进行编程,见 Section 10.5.1, “Local Vector Table”,以及 Section 10.6.1, “Interrupt Command Register(ICR)”。

6.1 local APIC 架构图[10.4.1]
Figure 10-4 是 local APIC 功能组件大图。软件通过读写 local APIC 的寄存器来操作之。APIC 的寄存器是处理器物理地址空间中 4KB 的 memory-mapped 区域,起始地址是 FEE0 0000H。若要正确地进行 APIC 操作,该地址空间必须被映射到 uncacheable(UC) 属性的内存区域上。

系统总线上 Intel 64 或 IA-32 处理器中的 APIC 寄存器,在 MP 系统配置中,其初始状态都是被映射到同一个 4KB 物理地址空间区域。软件可以选择将每个 local APIC 的 APIC 寄存器映射更改(重定位)至不同的 4KB 区域。Section 10.4.5, “Relocating the Local APIC Registers” 描述了怎么重定位 APIC 寄存器的基地址。

在支持 x2APIC 架构(CPUID.01H:ECX[32] = 1)的处理器上,local APIC 同时支持 xAPIC 模式以及(如果软件使能了的话)x2APIC 模式。x2APIC 提供了扩展的处理器寻址能力(Section 10.12)。

在这里插入图片描述
local APIC 编程相关的唯一 MSR 是 IA32_APIC_BASE MSR(Section 10.4.3, “Enabling or Disabling the Local APIC”)。其他寄存器都是 MMIO。

6.2 local APIC 检测[10.4.2]
从 P6 family 开始,通过 CPUID 指令检测是否存在片上 local APIC。EAX 寄存器指定操作码 1 的 CPUID,EDX 中的 bit 9 表征是否存在 local APIC。

6.3 使能/禁能 local APIC[10.4.3]
local APIC 的使能与禁能有两种方式:

通过 IA32_APIC_BASE MSR(MSR 地址 1BH,Figure 10-5) 中的 APIC 全局使能/禁能位。
通过 spurious-interrupt(伪中断)vector 寄存器中的 APIC 使能/禁能位(Figure 10-23)。
对于 Pentium 处理器,在启动及重启阶段可使用 APICEN 引脚(与 PICD1 引脚共享)来禁能 local APIC。

注意,LVT 中每个 entry 都有一个 mask bit,用来限制来自所选本地中断源(LINT0 和 LINT1 引脚,APIC timer,performance-monitoring counters,thermal sensor 和/或 APIC 内部错误 detector)的中断被投递至处理器。

6.4 local APIC 状态及位置[10.4.4]
local APIC 的状态及位置,通过 IA32_APIC_BASE MSR(Figure 10-5)获取。

在这里插入图片描述
6.5 local APIC 寄存器的重定位[10.4.5]
Pentium 4,Intel Xeon 及 P6 family 处理器支持通过修改 IA32_APIC_BASE MSR 中的基地址域,将 APIC 寄存器起始地址从 FEE0 0000H 重定位至其他物理地址。APIC 架构的这一扩展,旨在帮助解决系统内存映射冲突的问题,允许 MP 系统中的每个处理器将它们的 APIC 寄存器映射至不同的物理内存地址。

6.6 local APIC ID[10.4.6]
上电启动后硬件会为每个 local APIC 分配一个独一无二的 APIC ID。硬件依据系统拓扑以及 socket 、cluster 的位置信息编码(Figure 8-2 及 Section 8.9.1 “Hierarchical Mapping of Shared Resources”)来给 APIC ID 赋值。

MP 系统下,local APIC ID 还被 BIOS 及 OS 用作处理器的 ID。有些处理器允许软件修改 APIC ID。但是软件对 APIC ID 的修改能力是处理器 model specific 的。正因如此,OS 软件应当避免写 APIC ID 寄存器。返回的 EBX 的 bits 31-24(以 EAX 操作数为 1 执行 CPUID 指令)为初始 APIC ID(取决于平台的初始化)。即使软件修改了 local APIC ID 寄存器的值,该结论依然成立(译者注:也就是 CPUID 的返回值,与 local APIC ID 寄存器的值无关)。

处理器通过采样 A11# 和 A12# 引脚以及 BR0# 到 BR3# 引脚(Pentium 4、Intel Xeon 以及 P6 family 处理器)以及 BE0# 到 BE3# 引脚(Pentium 处理器)来接受硬件为其赋予的 APIC ID。从这些引脚获取的 APIC ID 将被存到 local APIC ID 寄存器中的 APIC ID 域(Figure 10-6),并作为处理器的初始 APIC ID。

在这里插入图片描述
对于 P6 family 及 Pentium 处理器,local APIC ID 寄存器中的 local APIC ID 域为 4 bits。0H 至 EH 的编码可用来唯一标识连到 APIC 总线上的 15 个不同的处理器。对于 Pentium 4 及 Intel Xeon 处理器,xAPIC 将 local APIC ID 域扩展至 8 bits,可用来最多标识系统中 255 个处理器(译者注:0xFF 用来做广播)。

6.7 local APIC 状态[10.4.7]
本节讨论,在上电或重启、被软件禁能 local APIC、INIT reset 以及接收到 INIT-deassert 消息之后,local APIC 及其寄存器的状态。

x2APIC 引入了 32 bit ID;见 Section 10.12。

6.7.1 上电或重启后的 local APIC 状态[10.4.7.1]
略。

6.7.2 被软件禁能后的 local APIC 状态[10.4.7.2]
略。

6.7.3 INIT reset 后的 local APIC 状态(“wait-for-SIPI” 状态)[10.4.7.3]
略。

6.7.4 接收到 INIT-deassert IPI 后的 local APIC 状态[10.4.7.4]

6.8 local APIC 版本寄存器[10.4.8]
local APIC 包含一个硬件版本寄存器。软件可借此识别 APIC 版本(Figure 10-7)。另外,此寄存器指定了一个具体实现下,local vector table(LVT) 中 entry 的数量。

APIC 版本寄存器包含如下域:

Version:local APIC 的版本。0XH 82489DX 独立APIC;10H - 15H 集成 APIC;其他值保留。
Max LVT Entry:LVT entry 数减 1。对于 Pentium 4 及 Intel Xeon 处理器(有 6 个 LVT entry),其值为 5;对于 P6 family 处理器(有 5 个 LVT entry),其值为 4;对于 Pentium 处理器(有 4 个 LVT entry),其值为 3。对于基于 Nahalem 及 onward Intel 微码的处理器(有 7 个 LVT entry),其值为 6。
Supress EOI-broadcasts:表征软件是否可以通过设置 Spurious Interrupt Vector Register 的 bit 12 来限制 EOI 消息的广播;见 Section 10.8.5 及 Section 10.9。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值