ver0.1
前言
上一篇文章我们介绍了GIC支持的中断类型,敲黑板哈,这都是历年的必考真题,基础中的基础。SPI、PPI、SGI、LPI就这么四种类型,大家一定要熟练掌握,这也是我们进一步研究GIC工作原理和了解它内部结构的基础。就比如我们今天要介绍的GIC的核心组件,里面很多概念都需要前面的文章进行铺垫,我们才敢落笔。所以大家还是先看看前序的的文章找找感觉:
(1) [V-02] 虚拟化基础-CPU架构(基于AArch64)
(2) [A-25]ARMv8/v9-GIC的系统架构(中断的硬件基础)
(3) [A-26]ARMv8/v9-GIC的中断类型
本文的内容掌握之后,你就会从更高的视角去看待中断相关的编程,那就是轻松加愉快。还是要掌握硬件以及硬件的工作原理,这个对于码农来说,真的很重要。以Linux为例,中断控制器GIC的驱动代码,神已经给大家写好了。因此,更多的时候,我们只需要会配置就行了,那么这个配置也是有门槛,这也就是本文的主旨,希望能够帮助大家入门GIC。
正文
1.1 GIC编程
GIC的编程主要的目的就是对GIC的控制器进行配置,我们来看一下手册中的描述。
This section describes what happens when an interrupt occurs: how the interrupt is routed to a PE, how interrupts are prioritized against each other, and what happens at the end of the interrupt。
核心的目的就是对GIC这个总线上的Master进行控制,在中断发生以后,按照我们的意图进行中断处理。具体可以归纳为要做三件事情:
(1) 中断路由:来自外设的中断、总线上其他Master的中断、PE-Coer内部的核间中断,GIC都要负责规划一个路径把这个中断的请求路由到一个具体的PE-Core处理。
(2) 中断优先级:中断信号的发生是随机就像这个世界一样充满了不确定性,很有可能事情都赶一起了,一堆的中断信号按照路由策略同时或者想个很短的周期都发送给了一个PE-Core进行处理,此时的PE-Core就需要策略做出决策:到底要先响应哪个中断请求,或者是否要打断当前的中断响应流程(响应中断的上下文,GIC控制器的状态,这个一般需要RichOS参与做管控)。
(3) 中断处理:这部分就是涉及到ARM的Exception处理流程了,因为中断在ARM的体系下归属异常模型中的异步异常类型,这个需要RichOS深度参与,并在中断执行结束的时候和GIC要好好唠唠,并根据中断的响应情况将GIC设置成正确的状态,不耽误下一个中断请求的响应。
中断的三件大事都离不开对GIC的配置和驱动,因此还是要回到我们的GIC的硬件模型,看一下GIC内部具体提供什么组件来办成中断相关的事情,如图1-1所示。
通过上图可以看到,GIC编程的接口主要就是三大块:Distributor Interface、Redistributor Interface、CPU Interface。既然是编程接口,肯定就是码农的的活了,那这些码农工作的场景入口的代码入口在哪里,如图1-2所示。
上面的编程接口其实是依托于GIC这个控制器的核心组件,谁是有源的,树是有根的,我们还是要从源头聊起,看看硬件和软件如何产生联系。
1.2 Distributor
1.2.1 GIC-Distributor(GICD) 系统架构
先来看一下Distributor长什么样子(注意不同版本之间的GIC以及GIC最终实现方式会有差异),如图1-3所示。
看一下手册中对Distributor的描述:
The Distributor is the main hub of the GIC and it implements most of the GICv4.1 architecture including:
• Programming, forwarding, and prioritization of SPIs.
• Caching and forwarding of LPIs.
• SGI routing and forwarding.
• vSGI forwarding and routing, when the GIC is configured to support GICv4.1.
• Management and control of vPEs and residency, when the GIC is configured to support GICv4.1.
• Programming interface for all registers, apart from GITS_TRANSLATER.
• Power control of cores and Redistributors.
结合图1-3,我们对Distributor做一下总结:
(1) GICD是一个HUB,是一个重要的中转节点,在一个GIC的系统架构中是唯一的。
(2) 在SOC的架构层面可以通过系统一致性总线和PE-Cores进行IO地址空间的层面的通信。
(3) 收集SPI、SGI、LPI、vSGI类型的中断信号,并经过GCI(Redistributor)进行二次分发。
(4) 支持通过对自身内部寄存器的编程。
这里提到了一种新的中断类型vSGI,这部分涉及到中断虚拟化的相关内容,我们后面会专门规划文章讨论。LPI和ITS又联系紧密,属于比较新的中断模型,也会在后面专门讨论。
1.2.2 GICD编程模型
我们看一下手册中对GICD的支持的可编程Feature的描述:
The Distributor registers are memory-mapped and used to configure SPIs. The Distributor provides a programming interface for:
• Interrupt prioritization and distribution of SPIs
• Enable and disable SPIs
• Set the priority level of each SPI
• Route information for each SPI
• Set each SPI to be level-sensitive or edge-triggered
• Generate message-signaled SPIs
• Control the active and pending state of SPIs
• Determine the programmer’s model that is used in each Security state: affinity routing or legacy.
总结一下GICD和核心能力:
(1) GICD内部的寄存器通过VMSA的内存空间映射接受PE-Core上的驱动程序的配置。
(2) 可以对中断请求进行路由控制,这路由控制不仅是硬件通路层面的控制知道对应的PE-Core处理,还包括软件层面的PE-Core层面执行状态响应中断的处理控制,相当于软件层面的路由。
(3) 可以对中断请求进行优先级控制。
(4) 这里面提到的level-sensitive 和edge-triggered涉及到中断状态机管理的内容,我们会在后续文章讨论中断处理的过程中进行讨论。
通过对GICD的编程能力的分析,可以看出GICD内部的寄存器启动了关键性作用,这里我们只截图一部分如图1-4所示。
前面我们已经和大家聊过了,一些中断信号支持通过SOC总线用消息的方式传递GICD,那么自然配置的方式也所有不同,如图1-5所示。
寄存器的详细作用,这里我们不展开讨论了,大家抓住上面的主线就可以了,涉及到具体的编程场景会查询手册就可以了。这里主要还是为了后面文章做一下铺垫。(看了很多大神写得文章,大家写得都很好、很透,但是感觉过于繁琐了。)
1.3 Redistributors(GIC Cluster Interface)
1.3.1 Redistributors(GCI) 系统架构
先来看一下Redistributors(新版本称为GCI)长什么样子(注意不同版本之间的GIC以及GIC最终实现方式会有差异),如图1-6所示。
看一下手册中对GCI的描述:
The GIC Cluster Interface (GCI) is responsible for PPIs and SGIs that are associated with its related cluster or group of cores.
The GCI performs the following functions:
• Maintaining the SGI and PPI programming.
• Monitoring, and if necessary, synchronizing the PPI wires.
• Prioritizing SGIs, PPIs, and any other interrupts(SPI/LPI) that are sent from the Distributor, and forwarding them to the core.
• Maintaining the GIC Stream protocol and communicating with the cluster. The GIC Stream Protocol Validator (GSPV) corrects any errors in the GIC Stream transfers. The GSPV supports mixed criticality systems where some processors might not have an ASIL-D rating.
我们结合图1-6对GCI的核心功能做一下归纳:
(1) GCI的上游有Distributor和来自产生PPI类型中断的设备,同时还可以接受PE-Core反向输入的SGI类型中断。
(2) GCI是GIC系统中离PE-Cores最近的模块了,每个PE-Core都会有一个Redistributor为它服务。
(3) GCI主配置的中断类型是SGI和PPI,但是会转发SPI和LPI到对应的PE-Core。
1.3.2 GCI编程模型
下面我们看一下手册中对GCI(Redistributor)可编程Feature的描述:
There is one Redistributor per connected core. The Redistributors provide a programming interface to:
• Enable and disable SGIs and PPIs
• Set the priority level of SGIs and PPIs
• Set each PPI to be level-sensitive or edge-triggered
• Assign each SGI and PPI to an interrupt group
• Control the state of SGIs and PPIs
• Control the base address for the data structures in memory that support the associated interrupt properties and pending state for LPIs.
• Provide power management support for the connected PE
总结一下GCI的核心能力:
(1) 可以使能SGI和PPI类型的中断。
(2) 可以配置SCI和PPI类型中断的优先级。
(3) 可以维护SGI和PPI类型中断的状态。
(4) 讲SGI类型中断回环给Distributor进行路由选择。
GCI的编程能力也是通过对GIC内部的寄存器配置从而达到目的的,如图1-7所示。
同样这里我们也不展开讨论,用到了大家知道从手册中去查询就行,后面的文章我们会穿插介绍一些具体的寄存器的用法。
1.4 CPU Interfaces
CPU的Interfaces就不是离这PE-Core近的GIC控制器组件,那就是在一起的好兄弟,是PE-Core忠诚的信使,如图1-8所示。
我们看下手册中对CPU-IF编程Feature的描述:
Each core contains a CPU interface, which are system registers that are used during interrupt handling. The CPU interfaces provide a programming interface to:
• Provide general control and configuration to enable interrupt handling
• Acknowledge an interrupt
• Perform a priority drop and deactivation of interrupts
• Set an interrupt priority mask for the PE
• Define the preemption policy for the PE
• Determine the highest priority pending interrupt for the PE
我们总结如下:
(1) 每个PE-Core都有独立的GIC-CPU 接口,这些接口也是通过寄存器进行配置,所不同的是这些寄存器不是位于GIC内部,而是位于CPU内部,属于系统寄存器。
(2) 通过配置GIC-CPU接口可以实现中断优先级、强制策略的控制。
(3) 通过配置GIC-CPU接口可以反向想GIC输出信号,使GIC可以维护当前中断信号的状态切换。
GIC-CPU-IF的寄存器属于系统寄存器,这个就和GIC其他组件的寄存器有着明显的区别了,大家都不在一本手册上,如图1-9所示。
系统寄存器直接通过访问寄存器指令就可以操作,而GIC其他寄存也就是属于CPU外部寄存器的指令要经过总线,属于访问设备地址空间,两者访问速度那可是差了好几个量级。这种设计,其实很好理解,一切都是为了效率,离得近自然控制起来就比较方便。关于GIC-CPU-IF就聊这么多,不展开了讨论了,重要的内容我们后面会单独提炼成文。
结语
本文我们介绍了GIC的核心组件,Distributor、Redistributor、CPU-IF的系统架构、编程模型、作用、以及相关的寄存器集合。这些内容的介绍都是为我们后续介绍的中断课题打下基础,目的还是让大家对硬件有起码的感觉,我们再简述他们的核心思想才能心里有底。这就跟搞对象式样的,其实大多数人都是外貌协会的,都是先看着顺眼,才有进一步探索心灵美的欲望,哈哈哈。谢谢大家,请保持关注。
Reference
[00] <Armv8-A-virtualization.pdf>
[01] <DEN0024A_v8_architecture_PG.pdf>
[02] <learn_the_architecture_aarch64_exception_model.pdf>
[03] <corelink_gic_720ae_generic_interrupt_controller_trm.pdf>
[04] <arm_generic_interrupt_controller_v3_and_v4_virtualization_guide.pdf>
[05] <learn_the_architecture_generic_interrupt_controller_v3_and_v4_lpis.pdf>
[06] <80-ARM-GIC-wx0005_Arm-gicv3_v4学习这一篇就够了.pdf>
[07] <80-ARM-GIC-wx0003_ARM架构Generic-Interrupt-Controller-GIC之Distributor和CPU-interface.pdf>
[08] <80-ARM-GIC-HK0001-一文搞懂GICv3中断控制器的工作原理.pdf>
[09] <80-ARM-GIC-wx0001_ARM-gicv3_gicv4的总结-基础篇.pdf>
[10] <80-ARM-INT-yk0001_万字长文玩转中断:从硬件看中断之GIC.pdf>
[11] <learn_the_architecture_generic_timer.pdf>
[12] <80-LX-INT-yk0001_吐血整理-肝翻Linux中断所有知识点.pdf>
Glossary
GIC - Generic Interrupt Controller
SCMI - System Control and Management Interface (SCMI)
ACPI - Advanced Configuration and Power Interface (ACPI)
PSCI - Power State Coordination Interface (PSCI)
UEFI - Unified Extensible Firmware Interface (UEFI)
UART - Universal Asynchronous Receiver/Transmitter
SPI - Shared Peripheral Interrupt
PPI - Private Peripheral Interrupt
SGI - Software Generated Interrupts
MPAM - Memory System Resource Partitioning and Monitoring
LPI - Locality-specific Peripheral Interrupt (LPI)
PE - Processing Element
MSI - message-signaled interrupts (MSI)
IAR - Interrupt Acknowledge Registers
EOIR - End of Interrupt Registers
IRM - Interrupt Routing Mode
ITS - Interrupt Translation Service
ITT - Interrupt Translation Tables
vPE -virtual processing element
IPI - inter-processor interrupts
IRI - Interrupt Routing Infrastructure
EOI - End of interrupt
GSPV - GIC Stream Protocol Validator