一文看懂GICv3 - 知乎
MADT和SRAT,IORT表关联性比较强。
MADT/APIC表:
=====================================================================================MADT表=================
[000h 0000 4] Signature : "APIC" [Multiple APIC Description Table (MADT)]
[004h 0004 4] Table Length : 00002AC4
[008h 0008 1] Revision : 05
[009h 0009 1] Checksum : 16
[00Ah 0010 6] Oem ID : "PHYLTD"
[010h 0016 8] Oem Table ID : "PHYTAPIC"
[018h 0024 4] Oem Revision : 00010000
[01Ch 0028 4] Asl Compiler ID : "ARMH"
[020h 0032 4] Asl Compiler Revision : 00010000
[024h 0036 4] Local Apic Address : 00000000
[028h 0040 4] Flags (decoded below) : 00000000
PC-AT Compatibility : 0
=======================================================上面的是表的header,下面是表内容
[02Ch 0044 1] Subtable Type : 0B [Generic Interrupt Controller]
[02Dh 0045 1] Length : 50
[02Eh 0046 2] Reserved : 0000
[030h 0048 4] CPU Interface Number : 00000000
[034h 0052 4] Processor UID : 00000000
[038h 0056 4] Flags (decoded below) : 00000001
Processor Enabled : 1
Performance Interrupt Trigger Mode : 0
Virtual GIC Interrupt Trigger Mode : 0
[03Ch 0060 4] Parking Protocol Version : 00000000
[040h 0064 4] Performance Interrupt : 00000017
[044h 0068 8] Parked Address : 0000000000000000
[04Ch 0076 8] Base Address : 0000000000000000
[054h 0084 8] Virtual GIC Base Address : 0000000000000000
[05Ch 0092 8] Hypervisor GIC Base Address : 0000000000000000
[064h 0100 4] Virtual GIC Interrupt : 00000019
[068h 0104 8] Redistributor Base Address : 00000000220C0000
[070h 0112 8] ARM MPIDR : 0000000000000000 //cpu的id,mpidr
[078h 0120 1] Efficiency Class : 00
[079h 0121 1] Reserved : 00
[07Ah 0122 2] SPE Overflow Interrupt : 0000
.......总共128个核,每个一个Generic Interrupt Controller
====================================================================下面是一个Distributor
[282Ch 10284 1] Subtable Type : 0C [Generic Interrupt Distributor]
[282Dh 10285 1] Length : 18
[282Eh 10286 2] Reserved : 0000
[2830h 10288 4] Local GIC Hardware ID : 00000000
[2834h 10292 8] Base Address : 0000000022000000
[283Ch 10300 4] Interrupt Base : 00000000
[2840h 10304 1] Version : 03
[2841h 10305 3] Reserved : 000000
====================================================================下面是32个GIT/ITS 用于MSI中断
[2844h 10308 1] Subtable Type : 0F [Generic Interrupt Translator]
[2845h 10309 1] Length : 14
[2846h 10310 2] Reserved : 0000
[2848h 10312 4] Translation ID : 00000000
[284Ch 10316 8] Base Address : 0000000022040000
[2854h 10324 4] Reserved : 00000000
[2858h 10328 1] Subtable Type : 0F [Generic Interrupt Translator]
[2859h 10329 1] Length : 14
[285Ah 10330 2] Reserved : 0000
[285Ch 10332 4] Translation ID : 00000001 //转换表的id,会在IORT表中的Identifiers 引用到,用来确定某个its地址转换表。
[2860h 10336 8] Base Address : 0000000022060000
[2868h 10344 4] Reserved : 00000000
.....
SRAT资源表:
===================================================================SRAT表=================================
000h 0000 4] Signature : "SRAT" [System Resource Affinity Table]
[004h 0004 4] Table Length : 00000D58
[008h 0008 1] Revision : 03
[009h 0009 1] Checksum : B5
[00Ah 0010 6] Oem ID : "PHYLTD"
[010h 0016 8] Oem Table ID : "PHYTSRAT"
[018h 0024 4] Oem Revision : 00010000
[01Ch 0028 4] Asl Compiler ID : "ARMH"
[020h 0032 4] Asl Compiler Revision : 00010000
[024h 0036 4] Table Revision : 00000001
[028h 0040 8] Reserved : 0000000000000000
========================================================== 128个 [GICC Affinity] PXM :
[030h 0048 1] Subtable Type : 03 [GICC Affinity]
[031h 0049 1] Length : 12
[032h 0050 4] Proximity Domain : 00000000 //一个numa/node/die的id 8个core共享一个id
[036h 0054 4] Acpi Processor UID : 00000000
[03Ah 0058 4] Flags (decoded below) : 00000001
Enabled : 1
[03Eh 0062 4] Clock Domain : 00000000
.....
==========================================================32个 [GIC ITS Affinity]
[930h 2352 1] Subtable Type : 04 [GIC ITS Affinity]
[931h 2353 1] Length : 0C
[932h 2354 4] Proximity Domain : 00000000 //一个numa/node/die 的id 2个its共享一个id,一个its供4个core
[936h 2358 2] Reserved : 0000
[938h 2360 4] ITS ID : 00000000 //和IORT的ITS类型的Identifiers,MADT表的[Generic Interrupt Translator]的Translation Id 关联。
.....
=======================================================-=N个[Memory Affinity] ,描述numa内存信息,因为是分散的,没有一定多少个。
[AD8h 2776 1] Subtable Type : 01 [Memory Affinity]
[AD9h 2777 1] Length : 28
[ADAh 2778 4] Proximity Domain : 00000000 //一个numa/node/die ,描述当前物理内存的起始地址属于那个节点
[ADEh 2782 2] Reserved1 : 0000
[AE0h 2784 8] Base Address : 0000010000000000
[AE8h 2792 8] Address Length : 0000000F80000000
[AF0h 2800 4] Reserved2 : 00000000
[AF4h 2804 4] Flags (decoded below) : 00000001
Enabled : 1
Hot Pluggable : 0
Non-Volatile : 0
[AF8h 2808 8] Reserved3 : 0000000000000000
.....
IORT表:
[000h 0000 4] Signature : "IORT" [IO Remapping Table]
[004h 0004 4] Table Length : 00000C6C
[008h 0008 1] Revision : 00
[009h 0009 1] Checksum : 6B
[00Ah 0010 6] Oem ID : "PHYLTD"
[010h 0016 8] Oem Table ID : "PHYTIORT"
[018h 0024 4] Oem Revision : 00010000
[01Ch 0028 4] Asl Compiler ID : "PHYT"
[020h 0032 4] Asl Compiler Revision : 00010000
[024h 0036 4] Node Count : 00000040
[028h 0040 4] Node Offset : 00000030
[02Ch 0044 4] Reserved : 00000000
[030h 0048 1] Type : 00 //ACPI_IORT_NODE_ITS_GROUP
[031h 0049 2] Length : 0018
[033h 0051 1] Revision : 00
[034h 0052 4] Reserved : 00000000
[038h 0056 4] Mapping Count : 00000000
[03Ch 0060 4] Mapping Offset : 00000000
[040h 0064 4] ItsCount : 00000001
[044h 0068 4] Identifiers : 00000000 //和MADT表的[Generic Interrupt Translator] translation id值 ,SRAT表的[GIC ITS Affinity]的 ITS ID
....总共32个,参考MADT表。
===================================================================================smmuv3
[76Ch 1900 1] Type : 04 //ACPI_IORT_NODE_SMMU_V3
[76Dh 1901 2] Length : 0044
[76Fh 1903 1] Revision : 02
[770h 1904 4] Reserved : 00000000
[774h 1908 4] Mapping Count : 00000000
[778h 1912 4] Mapping Offset : 00000044
[77Ch 1916 8] Base Address : 000000003BC00000
[784h 1924 4] Flags (decoded below) : 00000009
COHACC Override : 1
HTTU Override : 0
Proximity Domain Valid : 1
[788h 1928 4] Reserved : 00000000
[78Ch 1932 8] VATOS Address : 0000000000000000
[794h 1940 4] Model : 00000000
[798h 1944 4] Event GSIV : 00000052
[79Ch 1948 4] PRI GSIV : 00000078
[7A0h 1952 4] GERR GSIV : 00000077
[7A4h 1956 4] Sync GSIV : 00000051
[7A8h 1960 4] Proximity Domain : 00000000 //一个numa/die/node一个。其下面的设备使用这个smmuv3设备来进行地址转换
[7ACh 1964 4] Device ID Mapping Index : 00000000
代码入口:
IRQCHIP_ACPI_DECLARE(gic_v3, ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR,
acpi_validate_gic_table, ACPI_MADT_GIC_VERSION_V3,
gic_acpi_init);
上面是解析ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR 类型:
相关数据结构:
static struct
{
void __iomem *dist_base; //Distributor的基地址
struct redist_region *redist_regs; //这里会为每个core分配一个,保存每个core的redistributor的基地址信息
u32 nr_redist_regions;
bool single_redist;
int enabled_rdists;
u32 maint_irq;
int maint_irq_mode;
phys_addr_t vcpu_base;
} acpi_data __initdata; //保存解析的acpi数据
struct rdists { //保存Redistributor信息。rdist是_percpu。
struct {
raw_spinlock_t rd_lock;
void __iomem *rd_base;
struct page *pend_page;
phys_addr_t phys_base;
bool lpi_enabled;
cpumask_t *vpe_table_mask;
void *vpe_l1_base;
} __percpu *rdist;
phys_addr_t prop_table_pa;
void *prop_table_va;
u64 flags;
u32 gicd_typer;
u32 gicd_typer2;
bool has_vlpis;
bool has_rvpeid;
bool has_direct_lpi;
bool has_vpend_valid_dirty;
};
struct gic_chip_data { //gic控制器。Distributor信息
struct fwnode_handle *fwnode;
void __iomem *dist_base;
struct redist_region *redist_regions;
struct rdists rdists;
struct irq_domain *domain;
u64 redist_stride;
u32 nr_redist_regions;
u64 flags;
bool has_rss;
unsigned int ppi_nr;
struct partition_desc **ppi_descs;
};
static struct gic_chip_data gic_data __read_mostly;
流程:
acpi_validate_gic_table
count = gic_acpi_count_gicr_regions();//统计多少个[Generic Interrupt Controller],也是redistributor给的个数
acpi_data.nr_redist_regions = count;
gic_acpi_init
acpi_data.dist_base = ioremap(dist->base_address,ACPI_GICV3_DIST_MEM_SIZE); //解析Distributor 基地址
gic_acpi_collect_gicr_base //解析出每个Redistributor的地址。总共128个,保存在acpi_data.redist_regs。
gic_init_bases //填充gic_chip_data 结构体。包括per_cpu的rdists信息。也是redistributor的基地址等信息,是per-cpu的、
{ gic_data.rdists.XXX = //填充。赋值等。
.....
irq_domain_update_bus_token(gic_data.domain, DOMAIN_BUS_WIRED);
set_handle_irq(gic_handle_irq);
gic_update_rdist_properties();
gic_dist_init(); //初始化Distributor
gic_cpu_init();
{ gic_populate_rdist //通过gic_iterate_rdists(__gic_populate_rdist) 循环配置每个Redistributor
gic_enable_redist
gic_cpu_sys_reg_init
}
gic_smp_init();
{gic_starting_cpu //cpuhp_setup_state_nocalls其它core 运行
gic_cpu_init //初始化当前core
its_cpu_init
__irq_domain_alloc_irqs //提前分配8个SGI中断irq/irq_desc ,主要是IPI核之间通信用
set_smp_ipi_range //request_percpu_irq 申请IPIX
}
gic_cpu_pm_init();
if (gic_dist_supports_lpis()) {
its_init(handle, &gic_data.rdists, gic_data.domain); //lpi消息是基于地址的,通过its来管理
its_init //irq-gic-v3-its.c
its_acpi_probe
acpi_table_parse_srat_its //解析SRAT表的 [GIC ITS Affinity]
acpi_tab le_parse_madt(ACPI_MADT_TYPE_GENERIC_TRANSLATOR,gic_acpi_parse_madt_its,0) //解析MADT/APIC表 [Generic Interrupt Translator]
its_probe_one
its_cpu_init();
} else {
if (IS_ENABLED(CONFIG_ARM_GIC_V2M))
gicv2m_init(handle, gic_data.domain);
}
gic_enable_nmi_support();
}
domain层级关系:
开启CONFIG_GENERIC_IRQ_DEBUGFS内核选项
[root@localhost ~]# ls /sys/kernel/debug/irq/domains/
default irqchip@0x0000000029a00000-1 irqchip@0x0000000029a20000-3 irqchip@0x0000000029a20000-4 irqchip@0x0000000029a20000-5 irqchip@0x0000000029a20000-7
[root@localhost ~]# cd /sys/kernel/debug/irq/domains/
[root@localhost domains]# ls
default irqchip@0x0000000029a00000-1 irqchip@0x0000000029a20000-3 irqchip@0x0000000029a20000-4 irqchip@0x0000000029a20000-5 irqchip@0x0000000029a20000-7
[root@localhost domains]# cat *
name: irqchip@0x0000000029a00000-1 //Distributor 的 domain
size: 0
mapped: 69
flags: 0x00000003
name: irqchip@0x0000000029a20000-3 //最底层MSI的domain
size: 0
mapped: 27
flags: 0x00000013
parent: irqchip@0x0000000029a20000-5 //父节点 Generic Interrupt Translator] ,地址是一样的。
name: irqchip@0x0000000029a20000-5
size: 0
mapped: 27
flags: 0x00000023
parent: irqchip@0x0000000029a00000-1 //最上层是Distributor 的 domain
name: irqchip@0x0000000029a00000-1
size: 0
mapped: 69
flags: 0x00000003
name: irqchip@0x0000000029a20000-4
size: 0
mapped: 0
flags: 0x00000013
parent: irqchip@0x0000000029a20000-5
name: irqchip@0x0000000029a20000-5
size: 0
mapped: 27
flags: 0x00000023
parent: irqchip@0x0000000029a00000-1
name: irqchip@0x0000000029a00000-1
size: 0
mapped: 69
flags: 0x00000003
name: irqchip@0x0000000029a20000-5
size: 0
mapped: 27
flags: 0x00000023
parent: irqchip@0x0000000029a00000-1
name: irqchip@0x0000000029a00000-1
size: 0
mapped: 69
flags: 0x00000003
name: irqchip@0x0000000029a20000-7
size: 0
mapped: 0
flags: 0x00000013
parent: irqchip@0x0000000029a20000-5
name: irqchip@0x0000000029a20000-5
size: 0
mapped: 27
flags: 0x00000023
parent: irqchip@0x0000000029a00000-1
name: irqchip@0x0000000029a00000-1
size: 0
mapped: 69
flags: 0x00000003