- x86中断探测简介
中断控制器是连接设备和CPU的桥梁,一个设备产生中断后,需要经过中断控制器的转发,才能最终到达CPU。在UP(Uni-processor,单处理器)时代,x86主要使用的中断控制器为PIC(Programmable Interrupt Controller)。随着SMP(Symmetric Multiple Processor,对称多处理器)的流行,APIC(Advanced Programmable Interrupt Controller)已广为流行并将最终取代PIC。 操作系统通过表获取平台上硬件中断系统的信息,表是BIOS报告系统资源信息的通常方式。MP spec定义了MP table,ACPI规范定义了MADT(Multiple APIC Description Table)。虽然构建方式不一样,但是从OS看来两者大同小异,都支持LAPIC entry、I/O APIC entry,以及其他几个与之相关的entry。这些entry描述了平台APIC硬件的情况。 由于历史原因,SylixOS同样定义了一组符合MP spec的数据结构来管理平台硬件。ACPI被引入后,虽然汇报硬件资源的方式变了,但仍可以使用MP spec的数据结构管理。SylixOS的ACPI解析路径,实际上是使用了ACPI的方式读表,填充MP spec的数据结构。
- 技术实现
SylixOS中定义的MP spec结构体中,和中断相关如下所示: X86_MP_IOAPIC:对应MP spec的I/O APIC entry,如下所示。
typedef struct { /* MP Config Table Entry for IO APIC's */
UINT8 IOAPIC_ucEntryType; /* 2 identifies an IO APIC entry */
UINT8 IOAPIC_ucIoApicId; /* ID of this IO APIC */
UINT8 IOAPIC_ucIoApicVersion; /* Version of this IO APIC */
UINT8 IOAPIC_ucIoApicFlags; /* Usable or not */
UINT32 IOAPIC_uiIoApicBaseAddress;
/* Address of this IO APIC */
} X86_MP_IOAPIC;
X86_MP_INTERRUPT:对应MP spec的I/O interrupt entry,代表各个中断源(一个I/O APIC管脚连接一个中断源),如下所示。
typedef struct {
UINT8 INT_ucEntryType;
UINT8 INT_ucInterruptType;
UINT16 INT_usInterruptFlags;
UINT8 INT_ucSourceBusId;
UINT8 INT_ucSourceBusIrq;
UINT8 INT_ucDestApicId;
UINT8 INT_ucDestApicIntIn;
} X86_MP_INTERRUPT;
SylixOS将所有从MP spec以及ACPI探测出的数据全部保存在全局变量_G_pAcpiMpApicData中。其中中断源信息保存在该结构体成员MPAPIC_uiItLoc指定的地址中,共MPAPIC_uiItSize个。此外,全局变量_G_pX86MpApicInterruptTable同样保存了中断信息表的起始地址。 MP spec的相关代码在“libsylixos/SylixOS/arch/x86/mpconfig”目录中,ACPI规范的相关代码在“libsylixos/SylixOS/arch/x86/acpi”目录中。MP和ACPI实例的初始化接口如下所示。
#include "arch/x86/mpconfig/x86MpApic.h"
INT x86MpApicInstInit (VOID);
函数x86MpApicInstInit原型分析:
- 此函数成功返回ERROR_NONE,失败返回错误码;
SylixOS在x86MpApicInstInit函数中提供了4条中断探测路径,即MP spec路径、ACPI路径、用户自定义路径,以及非多核路径。目前系统默认启动选项为ACPI路径。
- 参考资料
《Interrupt in Linux》