ARM GIC介绍之二

连接"arm GIC介绍之一",我们补充对应的GIC 寄存器描述,和主要的用法说明,仅供参考。 

3 . GIC_V3寄存器介绍

我们把完整的图放在这里:


 从这里看到,GIC分为3个主要的部分,要完成其作用,而且给用户进行预先配置的方法,GIC就提供了一组寄存器,这些寄存器的设计就是围绕着这些主要的功能来实现的。

3.1 Distributor Registers

在前面介绍过,Distributor主要完成对应的IRQ状态的记录,对应的IRQ分发,那么围绕这样的功能,对应的寄存器主要有:

这里面有Distributor控制寄存器,控制Distributor使能和关闭,以及对应的具体IRQ的状态寄存器,比如GICD_ISACTIVER,这里记录某一个IRQ是否ACTIVE,还有逻辑功能寄存器,比如GICD_IPRIORITY,这里记录对应

IRQ的优先级别。这些都以GICD_*为前缀打头。我们来仔细说明。

GICD_CTLR

这个是GICD_CTLR寄存器,名字和对应的位功能来看是对Distributor控制使能,比如BIT_1,就是使能GROUP_1,

并且是NON-SECURE,如果是LINUX系统,就是KERNEL空间。一般来说对这个寄存器每个位都是打开的。BIT_31是等待回应,当配置对应寄存器了,写入到硬件,需要生效,那么可以读取这个位来看是否已经写入配置信息并生效。ARE是对应的AFFINITY,其实就是分配到哪个具体的CPU,我们在ROUTER寄存器说明时候来补充。

GICD_TYPER

这个是GICD_TYPER寄存器,其主要作用是获取SOC平台厂商提供的GIC的具体信息,现在一般提供信息是该GIC能够支持最多多少个IRQ硬件中断源。

ITLinesNumber:

SPI numbers in specification, butthis should include (SGI, PPI actually)

比如我们现在X20平台上都出来并且换算出来ITLinesNumber: 0xb,那么每个数字表示有32个IRQ      

12* 32-1= 383 IRQ numbers.

支持384个IRQ,从0到383,为最大数字。

最大支持

(0x1f+1)*32-1 =1023 

1024个中断,这个GIC现在通用的说明是一致的,如果不考虑LPI的话。

GICD_IGROUP&GICD_IGRPMODR

这两个在一起使用,一个IRQ对应一个BIT的GICD_IGROUP,以及一个BIT的GICD_IGRPMODR。

所以如果支持384个IRQ,那么真个GIC就需要384个BIT来表示384个GICD_IGRPMODR,同理其它对应的

以BIT方式表示的也是如此。

这两个结合起来表示某个具体的IRQ应该送到哪个Ex,是安全域还是非安全域,现在一般只支持3个,如上图表示。

GICD_IROUTER

这个寄存器的名字不好理解,其实,如果我们修改下GICD_TARGET,这样,就容易理解了。简单来说,该寄存器控制一个IRQ发到哪个CPU进行处理。在现在的ARM中,cpu的拓扑结构用AFFINITY来表示。

CPU以CLUSTER为单位进行管理,比如X20上有10个CPU,其中4个小核为一个CLUSTER_2,另外4个CPU

为CLUSTER_1,两个大核为CLUSTER_0,这样有利于对CPU的上电,频率等管理控制,尤其是CPU在OFF时候,当一个CLUSTER里面的CPU都OFF了,那么就以CLUSTER为单位把对用的电压给关闭或做其它处理,时钟进行对应的GATE,当然这只是考虑的部分因素,这部分需要参考Big.Little进行参考。我们在这里需要知道对应的管理结构,或者说

拓扑结构就可以了,在ARM中有对应MIPDR寄存器表示对应的CPU处于哪个SYSTEM,哪个CLUSTER,以及在CLUSTER里面的对应的编号,如图中的右上角说明。

所以,对于一个IRQ,需要知道发送给哪个CPU处理,就靠GICD_IROUTER里面的信息来决策。

现在一般只使用AFFINITY 0~2,如果系统过于复杂,可能使用到AFFINITY 3,BIT 31其实是个特殊开关,如果设置1,那么来了一个IRQ,这个IRQ就给所有的CPU发送在1*N模型中,一个IRQ可以发送给多个CPU但是只能由其中一个处理,至于是具体哪个CPU先发现并处理,并通知其它CPU,这个在ARM的文档中说明是自定义实现,也就是SOC厂商可以在硬件上自己决策使用具体的策略和方式,这里不说明,另外一个原因目前无法获取到具体SOC厂商在这块的具体策略和实现方法的细节。另外一个是软件上可以进行处理互斥,保证当前CPU处理一个IRQ,另外的CPU不处理。另外一个模型是N*N,也就是一个IRQ信号可以发送给多个CPU,这多个CPU都可以处理,现在大多厂商没有采取这种方式。而是用前者。

如果BIT 31没有设置为1,那么具体发送到哪个CPU就由AFFINITY 0/1/2来决定了,具体的对应关系见图中不同颜色的连接线。

GICD_IPRIORITYR

优先级寄存器

对于IRQ,如果只有一个到来,送给CPU处理,这个比较简单。但是实际情况远比这种场景复杂,比如某一个中断在PENDING状态,等CPU处理,这个时候来了另外一个IRQ,而这个IRQ的紧迫性更高,实际上我们想打断之前的等待流程,让这个新的IRQ插队,那么就需要给不同IRQ设置不同优先级,来表示对用的处理优先级。

在现在的GIC_V3中,一个IRQ优先级可以从0到255,用8个BIT来表示,见上图中红色圈出来的部分,所以一个32位的寄存器,其实可以表示4个IRQ的优先级。那么数字越小,级别越高,0表示最高,255最低,我们图中给出例子。

IRQ_34的优先级别值为0b:10100000,IRQ_33的优先级别值为0b:10100001,IRQ_34的值比IRQ_33小1,所以级别就高。

但是在实际中,我们不需要这么多的级别范围255,我们需要32个级别,或者64个级别就可以了,这就需要对级别LEVEL进行优化,可以忽略其低位的BIT,现在使用的X20上每个LEVEL的STEP是8,忽略低3位,这是ARM寄存器设计的写入忽略原则,以及读取为0原则。途中右下部分,我们做的简单实验,对优先级寄存器里面写入0b:11111111,但是都出来的是0b:11111000,也就是最低3位被忽略了。那么LEVEL_0是从0~7,LEVEL_1是从8~15,

所以:原先IRQ_34的优先级别值为0b:10100000,IRQ_33的优先级别值为0b:10100001,IRQ_34的值比IRQ_33小1,

但是实际能够配置到寄存器里面的值都是0b:10100000。优先级别是一样的。总的原则不变,还是值低的优先级高。所以设置时候需要使用者注意。

GICD_SGIR

这个寄存器作用是产生软件IRQ,现在GIC_V3以及之后的版本,放到CPU INTERFACE侧,这里先提示下。

3.2Redistributor Registers

对于Redistributor对应的寄存器,以GICR*为前缀打头。这里面涉及到的一部分是功能和开关寄存器,比如GICR_TYPER,GICR_CTLR。另外有针对SGI和PPI的状态优先级寄存器,由于GIC_V3后这32个IRQ的状态和对应的设置挪到Redistributor,所以增加了对应的GICR_ISACTIVER, GICR_IGROUPER0等,作用和Distributor里面对应的SPI(IRQ)寄存器一样,这里不重复,我们只说明几个特殊的寄存器,来解释Redistributor里特殊的功能。

 GICR_CTLR

因为是每个CPU都对应一个Redistributor,所以这些寄存器上面的大多数设置都对应单个CUP,比如DPG0,表示对应的CPU是否要接受送到G0的中断,同理DPG1NS,DPG1S,这些并不影响其它CPU接受并在安全域和非安全域处理对应的中断。

UWP这个其实是个Distributor通信状态的确认,这在不同芯片厂商是自己定义的,比如使用一组硬件上的信号来表示不同的状态,从一般的使用者层面来说感知不到具体的两者之间的通信交互,所以大多数开发者可以不关心这个位的设置。

 

GICR_TYPER

GICR_TYPER提供了对应的Redistributor信息,比如是否支持PLPIS,VLPIS,这些可能大家都用不到,可以先不用去管它。其中processor number,并且之前介绍的复杂的AFFINITY管理方式关闭后,从看到的资料理解上来说,可以直接用这里面编号来作为目标CPU,比如这里的编号15,就表示第16个CPU。目前这个寄存器我们没有看到对应的使用,都是默认使能的。

GICR_WAKER

在介绍这个寄存器之前,我们介绍下WAKE UP方式。

举个例子,当设置IRQ_100这个中断固定发送到CPU_N上处理之后,实际中来个一个对应的中断信号,而CPU_N在之前因为无任务处理,进入了省电模式,其对应的TIMER被GATED,对应的电压也被POWER DOMAIN给处理降低了或者关闭了。而新的架构(GIC_V3)后CPU INTERFACE以及对应的寄存器部分都和CPU在同一个电压DOMAIN中,那么,这个时后明显是不能把IRQ直接发送到CPU INTERFACE侧,然后再给CPU的IRQ信号线发送信号的。那么Redistributor就需要发送一个Signal wakerequest,请求对应的POWERDOMAIN CONTROLLER先把电压给加上,TIMER给开启,CPU和对应的INTERFACE能够工作,这个时候再发送IRQ信号给其处理。这就是WAKER的开关作用。

ChildrenAsleep是读取出来的,其中的值表示1的话,说明不能发送IRQ,对应的INTERFACE休眠,发了对方也不会理会的,0就是相反作用,这个一般是读信息,不写,使用者可以读出来为0的就表示可以和这个CPU正常交互。

ProcessorSleep,就是我们介绍的WAKER方式,如果为0,表示设置CPU没有处于低电模式,1表示处于进入模式或处于低电。可以发送WakeRequest信号。

其实,这两个定义看起来比较模糊,并不明确,在ARM的资料上介绍的话那么是提到设计的理念,也就是唤醒后再处理,具体实现时候,还是IMPDEF,也就似乎IMPLEMENTED DEFINE,芯片厂家自己定义实现。

我们看下具体使用:

其实这里代码实现很简洁,),那么设置对应PROCESSO不管CPU是否处于低电模式(这里第一次开启,一般是出于低电RSLEEP为0,以后就可以发送WAKE REQUEST去唤起,这应该会有硬件信号去唤醒INTERFACE,等待一段时间之后查看CHILDRENASLEEP来判断INTERFACE是否已经唤醒起来了。

以上介绍Redistributor对应的寄存器。

3.3 CPU Interface


说到INTERFACE,我们看下一个IRQ的流程:

当IRQ100到来,其中断优先级别为0xA0,如果优先级别不冲突,那么久经过Redistributor,送到对应的CPU Interface侧,和GIC_PMR寄存器里面设定的门槛优先级比较。高于对应的优先级,那么和正在处理的IRQ的优先级GIC_RPR寄存器值比较,也高于正在处理的IRQ,那么就抢断,如果没有正在处理的IRQ,那就不存在抢断。IRQ放到GIC_IAR寄存器里面,产生一个电信号给CPU的IRQ_input引脚, CPU读取GIC_IAR里面的中断号,并处理,之后向GIC_EOI寄存器里面写入IRQ,表示IRQ处理结束。

至此,一个中断处理完成。

那么这里面就涉及到了CPU Interface侧的对应的寄存器,我们主要列举如下:

分别介绍。

CPU Interface  对应的寄存器以GICC*为前缀。

 

GICC_CTLR


这个寄存器功能简单,控制FIQ/IRQ的BYPASS,并且EOI的配置。这个有点特殊,按照一般的解释,当IRQ由CPU处理完后,向GICC_EOIR里面写入IRQ号时候,那么表示中断流程完成,同时,状态要变成DE-ACTIVE,注意,是自动变成。但是EOIMODE这个配置有意思,可以决定这个“自动”的变化,如果取消“自动变为DE-ACTIVE”,那么需要使用者向GICC_DIR里面写入,这样才能把一个IRQ的最终状态变为DE-ATCIVE。目前看,这个没有使用到,也不需要手动写入GICC_DIR,从流程的逻辑性来看,这个手动写入具体用在什么样的特殊场景,还没有看到,也是个疑惑的地方。

 

GICC_PMR


这个寄存器从字面看,简单理解,中断只有优先级比这里面设置的高,才能继续向CPU侧传递,其中级别也是优化后的,只用32个LEVEL表示。之前在描述Distributor不再重复说明。

 

GICC_RPR


这个存器记录正在处理的IRQ的优先级别,主要是用来中断抢占使用的.

正常情况下,我们看上图,低电平表示中断在处理,当IRQ_A和IRQ_B两个中断到来,先后处理即可。并不会产生冲突,即使IRQ_B的优先级别更高。


即使说,当IRQ_A先到来在PENDING状态并且已经送到CPUINTERFACE侧等待CPU确认并处理,我们如果关闭抢占的话,这个时候IRQ_B到来,也不会造成一项,IRQ_B优先级别再高也得等待之前的IRQ_A处理后再进行处理。

那么,如果抢占打开了,怎样呢?GICC_RPR就是用来做这样的信息记录和比较的。


IRQ_A先到来,并且优先级高于GICC_PMR,那么得到处理,此时GICC_RPR里面的优先级从默认的0XFF变为对应的优先级,假如是0XB0;那么处理中,IRQ_B到来,优先级别也满足GICC_PMR的要求,并且值0XA0,高于GICC_RPR里面记录的IRQ_A的优先级,那么就抢占处理,执行IRQ_B对应的服务,结束之后,再继续完成对应的IRQ_A的服务。如果IRQ_A也服务完成了,那么GICC_RPR里面恢复成默认的OXFF值。

GICC_IAR

 

GICC_IAR寄存器,里面记录着等待处理的中断号,CPU从这里面读取获知到来的硬件中断号,并处理,随机对应的GIC中记录的IRQ状态从PENDING变为ACTIVE或者PENDING& ACTIVE。

GICC_SGI

SGI产生软件IRQ。

INITD表示对应IRQ号,这里一般从IRQ0到IRQ15。

IRM 为0时候,需要依靠TARGETLIST来确定目标CPU,如果为1的时候,那么就是广播发送,但是不给自身发送软中断。

TARGETLIST这里不在重复说明,只是注意,TARGETLIST里面只是表示在一个具体的CLUSTER里面的CPU编号,CLUSTER号由AFF1表示,这个TARGETLIST相当于AFF0。

在使用时候也比较简单:


在系统INIT时候,图左侧红色框内,会使用set_smp_cross_call来注册系统的IPI消息发送函数,这里是gic_raise_softirq,那么右侧红色框内,发送一个特定IPI消息时候,当调用到__smp_cross_all时候就会链到绿色线所指的gic_raise_softirq,来产生一个IPI消息(SGI),见下面代码。

GICC_EOIR

最后介绍EOI,这个之前提到过,中断处理完成,写入对应的终端号,表示IRQ处理结束,IRQ状态变为DE-ACTIVE。


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: "Linux ARM GIC 中断流程" 是指在 ARM 架构的 Linux 操作系统中,使用 Generic Interrupt Controller(GIC)处理器来管理系统中各种中断的流程。它负责将来自不同设备和外部事件的中断请求,分派给适当的处理程序来处理,并确保系统按顺序执行这些处理程序。中断处理是系统中一个重要的组成部分,它允许设备和软件互相通信,并提高了系统的稳定性和可靠性。 ### 回答2: Linux是一个非常流行的开源操作系统,可以在不同架构的计算机上运行。ARM架构是一种广泛使用的嵌入式系统架构,因此,许多嵌入式设备都使用Linux作为其操作系统。在ARM架构上,通常会使用GIC(通用中断控制器)来管理中断,这个过程可以分为中断触发、CPU响应和中断处理三个部分。 中断触发是指中断信号从设备到达GIC的过程。当一个设备需要发送一个中断时,它会向GIC发送一个中断请求信号,并指定中断号,这个中断号是唯一的,用于区分不同的中断。GIC会根据中断号去查找到这个中断对应的中断控制器,进而把这个请求传递给指定的CPU。 CPU响应是指CPU接收到中断请求信号后的响应过程。当GIC把中断请求传递给CPU时,CPU需要检查是否允许这个中断请求,也就是检查中断屏蔽寄存器(Interrupt Mask Register)。如果这个中断请求已被屏蔽,则CPU不会响应,否则,它会设置自己的中断挂起寄存器(Interrupt Pending Register),告诉GIC它已经准备好去处理这个中断。 中断处理是指CPU执行中断处理程序,处理具体的中断。当CPU设置了它的中断挂起寄存器后,GIC会向CPU发送一个中断信号。CPU会暂停当前的进程,并把当前的上下文信息(比如,寄存器值)保存到内存中。之后,CPU会跳转到中断处理程序(Interrupt Service Routine),开始执行具体的中断处理代码。中断处理程序完成后,CPU会从内存中恢复之前保存的上下文信息,并恢复之前进程的执行。 总的来说,ARM架构上的Linux操作系统通常使用GIC来管理中断,其中包括中断触发、CPU响应和中断处理三个方面。这个流程对于保证系统的稳定性和快速响应非常重要。 ### 回答3: 在ARM架构的Linux系统中,GIC(Generic Interrupt Controller)被用来管理中断。当发生中断时,GIC会将中断信号发送到CPU,然后CPU会停止当前的进程并处理该中断。 GIC的中断流程如下: 1. 报告中断:设备或其他外部事件引发中断信号,设备向GIC发送中断信号,GIC会产生一个中断源标识符,然后将其发给CPU。 2. 响应中断:CPU根据中断源标识符查询GIC,查看中断请求的优先级和处理器状态,如果中断请求的优先级高于当前中断处理器,那么CPU会中止当前进程,执行中断处理程序。 3. 中断处理:中断处理程序会读取设备状态,进行相应的操作,处理完成后会发出一个中断信号,通知GIC中断已被处理。 4. 中断结束:GIC收到来自设备的中断完成信号后,将中断源标识符置为未激活状态。 在这个流程中,GIC起到了一种路由的作用,将中断信号从设备传输到CPU,同时根据中断请求的优先级来优先处理高优先级的中断。这样就可以保证系统的稳定性和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值