GIC_V3寄存器介绍


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

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发送。在1N模型中,一个IRQ可以发送给多个CPU但是只能由其中一个处理,至于是具体哪个CPU先发现并处理,并通知其它CPU,这个在ARM的文档中说明是自定义实现,也就是SOC厂商可以在硬件上自己决策使用具体的策略和方式,这里不说明,另外一个原因目前无法获取到具体SOC厂商在这块的具体策略和实现方法的细节。另外一个是软件上可以进行处理互斥,保证当前CPU处理一个IRQ,另外的CPU不处理。另外一个模型是NN,也就是一个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是从07,LEVEL_1是从815,

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

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

GICD_SGIR

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

2、Redistributor 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,芯片厂家自己定义实现。

我们看下具体使用:

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

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

3、CPUInterface

说到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。

原文链接:https://blog.csdn.net/sunsissy/article/details/73842533

关于S3学习所涉及到的知识(四):GIC_V3寄存器介绍相关推荐

  1. 关于S3学习所涉及到的知识(一):per-CPU变量kernel syscore

    前言 终究是问题,在讲我们平时学习零散的知识用到一起.最近老师安排了一个任务,在实现这个任务的时候,发现除了一个bug.是关于atf中gic配置的.但是这个是在s3过程中配置. 之前也学习过这几个东西 ...

  2. 机器学习算法、深度学习算法涉及的数学知识

    微积分基础 导数的定义 左导数.右导数.可导函数 导数几何意义.物理意义 基本函数求导公式 四则运算法则 复合函数求导法则 神经网络激活函数的导函数求解 高阶导数 导数与函数单调性 极值定理 导数与函 ...

  3. 学习SLAM需要哪些预备知识?

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 编辑:3D视觉工坊 链接:https://www.zhihu.com/question/3518606 ...

  4. DataWhale第21期组队学习自然语言处理实践(知识图谱)task4— 用户输入->知识库的查询语句

    参考来源:https://github.com/datawhalechina/team-learning-nlp/blob/master/KnowledgeGraph_Basic/task04.md# ...

  5. 深度学习——keras教程系列基础知识

    大家好,本期我们将开始一个新的专题的写作,因为有一些小伙伴想了解一下深度学习框架Keras的知识,恰好本人也会一点这个知识,因此就开始尝试着写一写吧.本着和大家一起学习的态度,有什么写的不是很好的地方 ...

  6. 数字图像直方图处理涉及的数学知识介绍

    ☞ ░ 前往老猿Python博文目录 https://blog.csdn.net/LaoYuanPython ░ 一.引言 在数字图像直方图处理学习时,老猿发现相关内容涉及数学定积分.概率统计等相关的 ...

  7. 学习进销存管理系统知识

    学习进销存管理系统知识 电子商务的发展和市场竞争的加剧将企业推上了风口浪尖,中小企业除了积极迎接挑战之外,别无选择. 网络的兴起与电子商务的发展带来了时空界限的突破.贸易方式的变革和经济活动的革命, ...

  8. 学习一个新领域的知识的最佳方法和最快时间各是什么?

    Liu Cao ,「学习方法」是个伪命题 玉某人.冷峻.淡之 等人赞同 有个TED演讲简直是为这个问题量身订做的. The first 20 hours-How to learn Anything. ...

  9. 小白学习Flink系列--第一篇(知识图谱)

    小白学习Flink系列–第一篇(知识图谱) 如何学习Flink? ​ 对于一门计算机技术来说,如何快速学习上手呢?具体的逻辑是什么呢?我认为有以下几条 了解技术的应用场景 技术的基本概念,如何使用,以 ...

最新文章

  1. 【云周刊】第208期:阿里云MWC 2019发布7款重磅产品,助力全球企业迈向智能化...
  2. jQuery中 trigger() bind() 使用心得
  3. img disabled可以用什么替代_本特:马内不可替代,菲米是粘合剂,萨拉赫可以用姆巴佩桑乔替代...
  4. matlab中随机函数的具体使用方法
  5. postgresql定义访问ip与用户_Postgresql-12.1最新版本在线安装以及配置使用全流程
  6. ZetCode Spring 教程
  7. ★LeetCode(429)——N叉树的层序遍历(JavaScript)
  8. 解决“在eclipse中配置Tomcat时,出现Cannot create a server using the selected type的错误”的问题...
  9. 与一线Linux嵌入式开发工程师的对话
  10. r语言aggredate_R语言 分组计算,不止group_by
  11. golang使用Nsq
  12. Matlab数据可视化编程总结
  13. 植发搞笑图片_搞笑:终于找到原图了!像不像?
  14. 微信小程序怎么添加到主屏幕将微信小程序放到手机桌面?
  15. 测试化妆品真假软件,查询化妆品真伪的app叫什么
  16. cf游戏进不去计算机,cf更新之后进不去 穿越火线进不去解决方法
  17. CentOS7下Mantis安装与配置
  18. 单元节点和积分点有什么区别
  19. 处理window11无法连接网络共享打印机
  20. HTB靶场系列 Windows靶机 Granny靶机

热门文章

  1. 【Pygame实战】笑到颤抖的小游戏《不要停下来,八音符酱》,边撕边吼边泪奔
  2. 秒杀系统优化以及解决超卖问题
  3. python将object转换成日期型_python – Pandas:将dtype’object’转换为int
  4. FFmpeg源码分析:avdevice_register_all()注册设备
  5. Unity官方认证考试
  6. 安全知识主题趣味答题活动小程序
  7. STM32 IAR工程-Keil MDK转换详解
  8. 每天学一个 Linux 命令(67):nmap
  9. 支付宝小程序之蜻蜓设备刷脸核身获取手机号
  10. 转:智能手机Flash/DRAM选择、配置与价格大全