这篇文章是基于Linux-Kernel-ARM64体系中断系统架构跟踪的第一个扩展。
很多内容都出自于GICv3 and GICv4 Software Overview。
中断控制器
中断控制器在系统中的位置:
GIC硬件配置
GIC硬件可以分为三部分:GICD,GICR和GICC。
GIC规范中定义了4类中断类型:SGI(0-15), PPI(16-31), SPI(32-1029)和LPI(8192-~)。
其中GICD主要管理SPI类型的中断,包括使能/不使能、优先级、路由到哪个GICR、边沿触发还是水平触发和SPI中断状态等;
GICR主要管理SGI、PPI和LPI类型的中断,包括使能/不使能、优先级、边沿触发还是水平触发、中断状态等;
GICC主要管理中断处理控制、ack、deack、PE中断mask等。
如果脱离kernel,GIC的配置主要围绕GIC和PE来配置:
GICD:
路由使能:GICD_CTLR ARE
分发使能:GICD_CTLR EnabledGrp0GICC:
使能系统访问: ICC_SRE_ELn
优先级: ICC_PMR_EL1, ICC_BPRn_EL1
EOI模式: ICC_CTRL_EL1
中断使能: ICC_IGRPEN0_EL1PE:
中断向量设置: VBAR_EL1
Kernel中GIC使能
初始化
GIC首先是一个中断控制器,自然要实现irq_chip
:gic_eoimode1_chip
,
同时也需要创建irq_domain
来分配irq_desc
,就要实现irq_domain_ops
:gic_irq_domain_ops
。
另外GIC硬件初始化的部分在probe的时候, 通过gic_init_base
实现上面讲的硬件配置部分,具体在:
gic_init_base->
gic_dist_init: gicd 配置,默认配置所有中断都路由到boot core
gic_cpu_init: gicc 配置
中断分配
各种类型的中断分配在gic_irq_domain.gic_irq_domain_alloc
中实现。
这一块只是从ACPI表格、DTS表格读取hwirq配置和virq的关系而已。
msix_capability_init->
pci_msi_setup_msi_irqs->
msi_domain_alloc_irqs->
irq_domain_alloc_irqs_hierarchy->
irq_domain_alloc_irqs_parenet->
gic_irq_domain_alloc
irq_create_fwspec_mapping->
irq_domain_alloc_irqs->
__irq_domain_alloc_irqs->
irq_domain_alloc_irqs_hierarchy->
gic_irq_domain_alloc
中断路由配置
request_irq->
request_threaded_irq->
__setup_irq->
irq_startup->
irq_setup_affinity->
msi_domain_set_affinity->
irq_chip_set_affinity_parent->
gic_set_affinity
irq_set_affinity*->
irq_do_set_affinity->
msi_domain_set_affinity->
irq_chip_set_affinity_parent->
gic_set_affinity
中断响应
el1_irq->
gic_handle_irq->
gic_read_iar
handle_domain_irq->
generic->handle_irq->
handle->
gic_eoi_irq