arm GIC介绍之一【转】
转自:https://blog.csdn.net/sunsissy/article/details/73791470
GIC是ARM架构中及其重要的部分,本文只在公开ARM对应资料基础上,以MTK开发板为基础整理。个人理解之后记录,巩固和加深认识,仅此而已,如果有错误,欢迎指出。
1. GIC的概述
看过SOC架构的同学知道,CPU接受外部的中断处理请求,并进行处理,其实是一个被动接受的过程,这样好处是既能
保证主任务的执行效率,又能及时获知外部的请求,从而处理重要的设备请求操作。
如图:
GIC的全称为general interrupt controller,主要作用可以归结为:
接受硬件中断信号,并进行简单处理,通过一定的设置策略,分给对应的CPU进行处理。
这样的图比较简单,可以看下在ARM完整的SOC结构中,其位置是什么样的:
这是ARM比较新的架构图,其中CORELINK CCI-500是片上互联总线,也就是AMBA,在这总线上面挂了不同的设备。比如NIC-400设备,这可以理解为network interface设备,在这个设备上使用者可以再连接其它需要的器件。那么cpu,也就是cortex-72(大核)和cortex-53(小核)也是挂在总线上。上接GIC-500,也就是我们说的中断控制器,这个图其实是逻辑上的,实际中,GIC-500也是有线连接到CCI-500上,通过CCI-500和cpu连接交互,ARM的Distributor应该是为表示cpu和GIC之间的关系,才将其逻辑图表示成大家看到的。详细的可以参考ARM的官方网站介绍。
2.硬件中断的分类和GIC的组成
2.1 GIC_V2的介绍
我们知道了GIC的大致用途,那么它包含了那些部分,如果工作的,有什么特殊的地方呢。
OK,我们一个一个来。先来看下GIC的大致组成结构:
这是经典的GIC V2图,实际上大家能看到的经典的图也是这个。
2.1.1中断源的分类
这里面把硬件中断源分为了3类:
SPI:这是shared peripheral interrupt , 这是常见的外部设备中断,也定义为共享中断,比如按键触发一个中断,手机触摸屏触发的中断,共享的意思是说
可以多个Cpu或者说Core处理,不限定特定的Cpu。一般定义的硬件中断号范围31~1019.
PPI:这里指的是private peripheral interrupt,16~31,私有中断,为什么这样说呢,这些中断一般是发送给特定的Cpu的,比如每个Cpu有自己对应的Physicaltimer,产生的中断信号就发送给这个特定的cpu进行处理。比如ARM_V8平台上的:
在设备上,cat /proc/interrupts可以看到:
SGI:这个中断有些同学遇到的比较少,software generatedinterrupt,软件出发产生的中断,中断号范围0~15,也就是最前的16个中断。如果在X86平台上做过开发工作的同学可能有影响,其实这就是相当于IPI,简单的说Cpu_1要给Cpu_2发送特定信息,比如时间同步,全局进程调度信息,就通过软件中断方式,目标Cpu接受到这样的中断信息,可以获取到信息是哪个Cpu发送过来的,具体的中断ID是哪个数字,从而找到对应处理方式进行处理。比如MTK上的:
2.1.2 GIC的组成
这是硬件中断的分类。
那么GIC控制器完成这样的中断信号收集和分发工作,也划分了几个功能部分,见上面第2个图。包含2个部分:
Distributor和CPU interface.
Distributor:
The Distributor block performs interruptprioritization anddistribution to the CPU interface
blocks that connect to the processors in the system. The Distributor blockregisters are identified by the GICD_ prefix
The Distributor provides a programminginterface for:
• Globally enabling the forwarding of interrupts to the CPU interfaces.
• Enabling or disabling eachinterrupt.
• Setting the priority level of each interrupt.
• Setting the target processor list of each interrupt.
• Setting each peripheral interrupt to be level-sensitive oredge-triggered.
• Setting each interrupt as either Group 0 or Group 1.
CPU Interface:
Each CPU interface block provides theinterface for a processorthat is connected to the GIC. Each CPUinterfaceprovides
a programming interface for:
• enabling the signaling of interrupt requests to the processor
• acknowledging an interrupt
• indicating completion of the processing of an interrupt
• setting an interrupt priority mask for the processor
• defining the preemption policy for the processor
• determiningthe highest priority pending interrupt for the processor .
这是其英文解释,其实总的来说:
Distributor,做为一个中断路由的设备,主要完成工作:
对整个中断控制器设备的使能等操作。
对每一个中断的优先级控制。
对每一个中断的触发方式设置。
对没一个中断的目标发送CPU进行设置,决定分发到哪个具体的CPU上进行处理。
对中断的去向,是到G0还是G1,这个是安全域的概念。我们后面补充GIC V3和V4的概念再展开说。
记录每个中断的状态,是否到来,是否处理中,是否处理完,是否在等待发送状态等等。
那么,CPUInterface主要工作是:
使能和发送一个具体的中断信号到特定对应的CPU上,
确认具体中断已经被CPU接受,处理,以及处理完成。
设置cpu能接受的中断的优先级别。以及对应的基于级别的中断抢断等处理。
所以,从第二个图来说。中断信号先到Distributor,然后根据设定目标CPU,送到CPU对应的Interface上,在这里仲裁是否优先级足够高,
是否可以抢断或者打断当前的终端处理等,如果可以,那么CPU Interface就发送一个物理的SIGNAL到CPU的IRQ接线上,CPU感知到中断信号,
从而转到中断模式进行处理。
那么途中带*号的IRQ和FIQ是什么意思呢?
FIQ是Fastinterrupt request,这是ARM上定义的一种中断处理方式,某些终端需要快速处理完成,在这种情况下,CPU会简化操作,然后退出中断。
那么从留向来说,途中是直接到CPU侧的,没有经过Distributor?
是的,我们说过,Distributor可以被使能,等各种操作,那么当其主功能暂时关闭了怎么办呢,这就又了BYPASS功能,一个已将IRQ直接绕过它,
送到CPU侧,在某些情况下这可以作为一个唤醒的信号源去WAKE UP 对应的CPU,或者可以设置成为X86上的NMI,也就是不可屏蔽中断来处理。
2.2 GIC_V3的介绍
在现在市面上看到的手机或者其它设备产品中,既有老的V2版本的中断控制器,也有比较新的V3结构的,而且是在不断向后演进,我们有必要依照新的V3的来说明,毕竟,这是后面的趋势,比如现在大家现在可以看到GIC_V4的介绍了。
好,我们切入正题,在之前介绍GIC_V2的基础上我们扩展下。
在上图中,我们在GIC_V3的基础上整理出这样的结构图,其实主题结构和V2是大致一样的,但是我们会发现,多了Redistributor这样的组件,这是为啥呢?另外,我也也看到cpuinterface移到GIC外面了,为啥这样表示逻辑图呢?多出来的LPI这个中断是做什么用的?
2.2.2 GIC中断
其实,LPI解释为LPI (Locality-specific Peripheral Interrupt)。
所有的中断类型可以分为:
SGI:software generated Interrupt
软件触发的中断,这个和之前解释的一致。
PPI:Private Peripheral Interrupt
私有中断类型,这个和之前解释的也是一致。但是PPI直接到Redistributor,绕过, 这是因为增加的Redistributor一个是为LPI需要,特殊的中断类型,既然PPI是各自CPU都有的,就没必要再经过之前的Distributor
来分发了,这样也导致了其中的寄存器等也做了修改。我们后面介绍寄存器时候再说明。
SPI:SharedPeripheral InterruptDistributor
共享外围硬件中断,这个也是和GIC_V2解释一样的ID32-ID1019。
但是,多了LPI(Locality-specific Peripheral Interrupt)
LPIs are new in GICv3, and they are different to the other types of
interruptin a number of ways . In particular, LPIs are always
message-based interrupts,and their configuration is held in tables in
memory rather than registers.
这是一个基于消息的中断类型,是ARM为后续的SERVER等产品做的扩展。
在传统的GIC流程中如上图,外围设备的中断触发线是引出到GIC上的,这样可以理解为一个物理的SIGNAL,比如一个高电平信号,边沿触发信号。
但是实际上在现在GIC_V3中,中断可以依照MESSAGEBASED方式来触发,外围设备的终端信号先到INTERCONNECT(AMBA总线),然后片上总线再给GIC发送一个消息,这个作为一个IRQ来源,这就是基于消息的中断的简单解释,当然这个需要总线,SOC等做调整适配,在这里我们不展开来说,有兴趣的同学可以看看CCI-500等总线如何定义信号灯细节的。
我们这样来表示下整个图:
从ITS是Interrupt Translate service,如果我们只看图右侧的部分,X86上经典的PCI总线,经过一系列转换发送一个中断到X86的CPU上,从而处理。那么现在我要直接把这部分搬到arm,由于体系架构不同,中断控制器逻辑和流程都不一样, X86对应APIC-IO 和Local APIC这样的终端控制逻辑。
但是我们可以这样来处理:
-
我们增加一个ITS,在这里定义好特定的消息,包含消息从哪里来的,比如PCI-ROOT,具体的设备编号,比如PCIe-endpoint对应的设备,可能是个音频设备,或者简单的按键,这都不是重点。关键是ITS可以根据定义好的配置,来把对PCI发来的中断消息进行转换,比如转换成IRQ_ID:8200终端
-
这样就可以发送到Redistributor上进行分发处理,和一般的IRQ类似,但是不经过Distributor,其中断也没有Pending状态,如果处理不过来丢失了那就丢失了,不会特别的关注。
从现在我们看到的资料来说,还没有看到LPI的具体应用,但是ARM已经在在很多方面为SERVER的架构做了调整,这也是其中一个,所以在这里会提示下,但不是我们介绍的重点。
2.2.2 GIC的组成
我们在上面图中,给出GIC_V3已经之后对应的逻辑图,从中可以看到几个部分:
Distributor
The Distributor registers arememory-mapped, and contain global settings that affect all PEs
connected to the interrupt controller. The Distributor provides a programminginterface for:
· Interrupt prioritization and distribution of SPIs.
· Enabling and disabling SPIs.
· Setting the priority level of each SPI.
· Routing information for each SPI.
· Setting each SPI to be level-sensitive or edge-triggered.
· Generating message-based SPIs.
· Controlling the active and pending state of SPIs.
· Controls to determine the programmers’ model that is used in each Securitystate (affinity routing or legacy).
CPU Interface
Each Redistributor is connected to aCPU interface. The CPU interface provides a programming interface for:
· General control and configuration to enable interrupt handling.
· Acknowledging an interrupt.
· Performing a priority drop and deactivation of interrupts.
· Setting an interrupt priority mask for the PE.
· Defining the preemption policy for the PE.
· Determining the highest priority pending interrupt for the PE
Redistribute (V3,V4)
For each connected PE there is aRedistributor. The Redistributors provides a programming interface for:
· Enabling and disabling SGIs and PPIs.
· Setting the priority level of SGIs and PPIs.
· Setting each PPI to be level-sensitive or edge-triggered.
· Assigning each SGI and PPI to an interrupt group.
· Controlling the state of SGIs and PPIs.
· Base address control for the data structures in memory that support theassociated interrupt properties and pending state for LPIs.
· Power management support for the connected PE.
其实之前对应的Distributor 和CPU Interface也还是一致的,但是Distributor不再处理PPI这样的中断,PPI直接送到Redistribute来处理,另外Redistribute也会处理LPI类型中断,其它逻辑上和我们之前介绍的是相似的,在这里不再重复。
2.3 IRQ生命周期
从GIC角度来说,一个中断可以分为几个阶段,对应不同的状态:
当GIC上配置的中断,配置好之后,没有其对应的中断到来,或者之前处理的中断已经完全结束了,这个可以表示为
Deactive状态或者Inactive,如果中断信号到来,GIC获取到了,这个时候要经过一系列的的判断,然后送给对应的CPU来处理,在CPU确认该中断并处理之前,状态是Pending,如果CPU获取到了该终端确认要处理了,那么久变为Active状态。这个时候,对应的GIC上终端信号线可能依旧有效,比如高电平触发的终端信号还没有被拉低,或者说又来一个同样的终端,那就是Activeand Pending。
2.4 IRQ Group
在ARM中,新的架构上引入了EX的概念,如果Ex0/1/2/3,以及安全域和非安全域,这个我会在补充个Topic:TRUSTZONE来说明,或者大家也查看资料来理解ARM的工作模式,比如FIQ/IRQ等传统模式。只是现在ARM淡化了这样模式,使用Ex,exception level 0/1/2/3,比如我们看到的ANDROID APP就是在Ex0,也就是USER空间,Ex1是我们常见的KERNEL空间。Ex2是对应的Hypervisor,虚拟化对应的空间,那么Ex3就是最好的权限和异常级别,这里可以由各个芯片厂家自己定义来添加对应的如ATF底层功能。
另外还在CPU上划分了SECURE 和NON-SECURE空间,这需要ARM对应的控制寄存器等来进行权限控制。
所以,IRQ的发到一个CPU上,还需要知道送到哪个Ex去处理,是送到KERNEL(Ex1)?还是安全域里面,这也在GIC里面进行配置,然后一个IRQ到来了才会往对应的寄存器里面发送。
OK,这概念比较抽象,我们在后面详细介绍GIC主要的寄存器和功能时候,会介绍,如果能理解对应的寄存器和作用,那么GIC的组成和功能也就明白了。
即将增加GIC介绍之二,寄存器说明......