ARM GICv3中断控制器
changelog:
2019年02月17日 初稿
2020年03月1日 fix typos以及增加中断路由
1. 前言
GIC,Generic Interrupt Controller。是ARM公司提供的一个通用的中断控制器。主要作用为:
接受硬件中断信号,并经过一定处理后,分发给对应的CPU进行处理。
当前GIC 有四个版本,GIC v1~v4, 主要区别如下表:
本文主要介绍GIC v3控制器, 基于linux kernel 4.19.0。
2. GIC v3中断类别
GICv3定义了以下中断类型:
SPI (Shared Peripheral Interrupt)
公用的外部设备中断,也定义为共享中断。可以多个Cpu或者说Core处理,不限定特定的Cpu。比如按键触发一个中断,手机触摸屏触发的中断。
PPI (Private Peripheral Interrupt)
私有外设中断。这是每个核心私有的中断。PPI会送达到指定的CPU上,应用场景有CPU本地时钟。
SGI (Software Generated Interrupt)
软件触发的中断。软件可以通过写GICD_SGIR寄存器来触发一个中断事件,一般用于核间通信。
LPI (Locality-specific Peripheral Interrupt)
LPI是GICv3中的新特性,它们在很多方面与其他类型的中断不同。LPI始终是基于消息的中断,它们的配置保存在表中而不是寄存器。比如PCIe的MSI/MSI-x中断。
硬件中断号 | 中断类型 |
---|---|
0-15 | SGI |
16 - 31 | PPI |
32 - 1019 | SPI |
1020 - 1023 | 用于指示特殊情况的特殊中断 |
1024 - 8191 | Reservd |
8192 - MAX | LPI |
3. GIC v3组成
GICv3控制器由以下部分组成:
distributor: SPI中断的管理,将中断发送给redistributor
redistributor: PPI,SGI,LPI中断的管理,将中断发送给cpu interface
cpu interface: 传输中断给core
ITS: Interrupt Translation Service, 用来解析LPI中断
其中,cpu interface是实现在core内部的,distributor,redistributor,ITS是实现在gic内部的.
Distributor 详述
Distributor的主要的作用是检测各个interrupt source的状态,控制各个interrupt source的行为,分发各个interrupt source产生的中断事件分发到指定的一个或者多个CPU interface上。虽然Distributor可以管理多个interrupt source,但是它总是把优先级最高的那个interrupt请求送往CPU interface。
Distributor对中断的控制包括:
(1)中断enable或者disable的控制。Distributor对中断的控制分成两个级别。一个是全局中断的控制(GIC_DIST_CTRL)。一旦disable了全局的中断,那么任何的interrupt source产生的interrupt event都不会被传递到CPU interface。另外一个级别是对针对各个interrupt source进行控制(GIC_DIST_ENABLE_CLEAR),disable某一个interrupt source会导致该interrupt event不会分发到CPU interface,但不影响其他interrupt source产生interrupt event的分发。
(2)控制将当前优先级最高的中断事件分发到一个或者一组CPU interface。当一个中断事件分发到多个CPU interface的时候,GIC的内部逻辑应该保证只assert 一个CPU。
(3)优先级控制。
(4)interrupt属性设定。例如是level-sensitive还是edge-triggered
(5)interrupt group的设定
Distributor可以管理若干个interrupt source,这些interrupt source用ID来标识,我们称之interrupt ID。
Redistributor详述
对于每个连接的PE,都有一个Redistributor.
该block的主要功能包括:
(1)启用和禁用SGI和PPI。
(2)设置SGI和PPI的优先级。
(3)将每个PPI设置为电平触发或边缘触发。
(4)将每个SGI和PPI分配给中断组。
(5)控制SGI和PPI的状态。
(6)内存中数据结构的基址控制,支持LPI的相关中断属性和挂起状态。
(7)电源管理支持。
CPU interface详述
CPU interface这个block主要用于和process进行接口。
该block的主要功能包括:
(a)enable或者disable CPU interface向连接的CPU assert中断事件。对于ARM,CPU interface block和CPU之间的中断信号线是nIRQCPU和nFIQCPU。如果disable了中断,那么即便是Distributor分发了一个中断事件到CPU interface,但是也不会assert指定的nIRQ或者nFIQ通知processor。
(b)ackowledging中断。processor会向CPU interface block应答中断(应答当前优先级最高的那个中断),中断一旦被应答,Distributor就会把该中断的状态从pending状态修改成active或者pending and active(这是和该interrupt source的信号有关,例如如果是电平中断并且保持了该asserted电平,那么就是pending and active)。processor ack了中断之后,CPU interface就会deassert nIRQCPU和nFIQCPU信号线。
(c)中断处理完毕的通知。当interrupt handler处理完了一个中断的时候,会向写CPU interface的寄存器从而通知GIC CPU已经处理完该中断。做这个动作一方面是通知Distributor将中断状态修改为deactive,另外一方面,CPU interface会priority drop,从而允许其他的pending的interrupt向CPU提交。
(d)设定priority mask。通过priority mask,可以mask掉一些优先级比较低的中断,这些中断不会通知到CPU。
(e)设定preemption的策略
(f)在多个中断事件同时到来的时候,选择一个优先级最高的通知processor
3. 中断路由
gicv3使用hierarchy来标识一个具体的core, 如下图是一个4层的结构(aarch64)
<affinity level 3>.<affinity level 2>.<affinity level 1>.<affinity level 0> 组成一个PE的路由。
每一个core的affnity值可以通过MPDIR_EL1寄存器获取, 每一个affinity占用8bit.
配置对应core的MPIDR值,可以将中断路由到该core上。
各个affinity的定义是根据SOC自己的定义
比如可能affinity3代表socketid,affinity2 代表clusterid, affnity1代表coreid, affnity0代表thread id.
以gic 设置中断路由为例:
中断亲和性的设置的通用函数为irq_set_affinity, 具体调用如下:
+-> irq_set_affinity()...+-> irq_do_set_affinity()+-> chip->set_affnity()+->gic_set_affinity()
static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,bool force)
{/* If interrupt was enabled, disable it first */enabled = gic_peek_irq(d, GICD_ISENABLER); -------- (1)if (enabled)gic_mask_irq(d);reg = gic_dist_base(d) + GICD_IROUTER + (gic_irq(d) * 8);val = gic_mpidr_to_affinity(cpu_logical_map(cpu)); --------- (2)gic_write_irouter(val, reg); ------ (3)irq_data_update_effective_affinity(d, cpumask_of(cpu));return IRQ_SET_MASK_OK_DONE;
}
gic_set_affinity先判断当前中断是否使能,如果使能则disable掉该中断;
然后根据gic_mpidr_to_affinity函数获取需要绑定中断到对应core的路由,
static u64 gic_mpidr_to_affinity(unsigned long mpidr)
{u64 aff;aff = ((u64)MPIDR_AFFINITY_LEVEL(mpidr, 3) << 32 |MPIDR_AFFINITY_LEVEL(mpidr, 2) << 16 |MPIDR_AFFINITY_LEVEL(mpidr, 1) << 8 |MPIDR_AFFINITY_LEVEL(mpidr, 0));return aff;
}
aff 就是通过对应core的MPIDR_EL1寄存器获取affinity0~3的值,并组成一个新的32bit value;
最后将获取的value写进gic irouter寄存器并更新中断的亲和性配置。
4. 中断处理流程
从上图可以看出,中断处理可以分成两类:
(1)中断要通过distributor的中断流程
–>外设发起中断,发送给distributor
–>distributor将该中断,分发给合适的re-distributor
–>re-distributor将中断信息,发送给cpu interface。
–>cpu interface产生合适的中断异常给处理器
–>处理器接收该异常,并且软件处理该中断
它的中断状态机如下图所示
有四种中断状态:
中断状态 | 描述 |
---|---|
Inactive | 中断即没有Pending也没有Active |
Pending | 由于外设硬件产生了中断事件(或者软件触发)该中断事件已经通过硬件信号通知到GIC,等待GIC分配的那个CPU进行处理 |
Active | CPU已经应答(acknowledge)了该interrupt请求,并且正在处理中 |
Active and Pending | 当一个中断源处于Active状态的时候,同一中断源又触发了中断,进入pending状态 |
processor ack了一个中断后,该中断会被设定为active。当处理完成后,仍然要通知GIC,中断已经处理完毕了。这时候,如果没有pending的中断,GIC就会将该interrupt设定为inactive状态。操作GIC中的End of Interrupt Register可以完成end of interrupt事件通知。
(2)中断不通过distributor,比如LPI中断
外设发起中断,发送给ITS
–>ITS分析中断,决定将来发送的re-distributor
–>ITS将中断发送给合适的re-distributor
4. LPI
LPI是基于消息的中断。中断信息不在通过中断线进行传递,而是通过memory。
gic内部提供一个寄存器,当外设往这个地址写入数据时,就往gic发送了一个中断。
在soc系统中,外设想要发送中断给gic,是需要一根中断线的。如果现在一个外设,需要增加一个中断,那么就要增加一根中断线,然后连接到gic。这样就需要修改设计。而引入了LPI之后,当外设需要增加中断,只需要使用LPI方式,传输中断即可,不需要修改soc设计。
传统的GIC流程:
在传统的GIC流程中如上图,外围设备的中断触发线是引出到GIC上的,这样可以理解为一个物理的SIGNAL,比如一个高电平信号,边沿触发信号。
消息中断流程:
使用消息将中断从外设转发到中断控制器,无需每个中断源提供专用信号。 这样的一个好处是,可以减少中断线的个数。
在GICv3中,SPI可以是基于消息的中断,但LPI始终是基于消息的中断。
5.ITS
引入了LPI之后,gicv3中,还加入了ITS组件,interrupt translation service。ITS将接收到的LPI中断,进行解析,然后发送到对应的redistributor,再由redistributor将中断信息,发送给cpu interface。
外设,通过写GITS_TRANSLATER寄存器,发起LPI中断。写操作,给ITS提供2个信息:
EventID: 值保存在GITS_TRANSLATER寄存器中,表示外设发送中断的事件类型
DeviceID: 表示哪一个外设发起LPI中断。该值的传递,是实现自定义,例如,可以使用AXI的user信号来传递。
ITS将DeviceID和eventID,通过一系列查表,得到LPI中断号,再使用LPI中断号查表,得到该中断的目标cpu。
ITS将LPI中断号,LPI中断对应的目标cpu,发送给对应的redistributor。redistributor再将该中断信息,发送给CPU。
6.参考资料
GICv3_Software_Overview_Official_Release_B
ARM GICv3中断控制器相关推荐
- ARM通用中断控制器GIC之中断控制
在阅读本章之前,可以参考笔者之前关于GIC的一些描述: ARM通用中断控制器GIC(generic Interrupt Controller)简介 ARM架构Generic Interrupt Con ...
- ARM通用中断控制器GIC之中断处理简介
在阅读本章之前,可以参考笔者之前关于GIC的一些描述: ARM通用中断控制器GIC(generic Interrupt Controller)简介 ARM架构Generic Interrupt Con ...
- ARM GIC中断控制器介绍
1 GIC : Generic Interrupt Controller Distributor–detecting, disabling, prioritizing, directing inter ...
- ARM通用中断控制器GIC(generic Interrupt Controller)简介
参考文档: Documentation – Arm Developer ARM Generic Interrupt Controller Architecture Specification 目录 ...
- Linux 中断 —— ARM GIC 中断控制器
GIC(Generic Interrupt Controller)是ARM公司提供的一个通用的中断控制器,其architecture specification目前有四个版本,V1-V4(V2最多支持 ...
- ARM通用中断控制器GIC之中断处理状态机 Interrupt handling state machine
中断有四种状态:inactive,pending,active 和active and pending.而产生中断的方式有两种,一种是通过写pending寄存器,让中断进入pending状态,可以忽略 ...
- ARM GICv3 ITS介绍及代码分析
前言: 在ARM gicv3中断控制器,有提到过ITS的作用,本篇就ITS进行更详细的介绍以及分析linux 内核中ITS代码的实现. 本文基于linux 4.19,介绍DT方式初始化的ITS代码. ...
- ARM GICv3 GIC代码分析
前言 在前一篇博文(ARM GICv3中断控制器)中, 介绍了GIC的一些基本概念,本文主要分析了linux kernel中GIC v3中断控制器的代码(drivers/irqchip/irq-gic ...
- linux中断子系统 - 中断控制器的注册
文章系列 linux中断子系统 - 中断及执行流程 linux中断子系统 - 申请中断 linux中断子系统 - irq_desc的创建 linux中断子系统 - 中断控制器的注册 1. 前言 中断控 ...
最新文章
- 昵称到拼音php,php 汉字转换拼音程序_PHP教程
- 什么是PRD、MRD与BRD?
- 服务发现系统之consul入门
- 房价越高的地方资产越高?北京户均资产890万?
- TOP命令及参数解析
- Zabbix监控nginx status
- keras笔记-模型保存以及tensorboard的使用
- 中国联通5G-NR 900MHz基站设备技术白皮书(2022)
- 一周新闻纵览:谷歌浏览器信息泄露,出卖个人信息获利终落网,严查App偷窥乱象
- vue 下载文件的两种方法
- 一些嵌入式开发有用的github上的开源代码库
- 怎么恢复电脑的无线网服务器,电脑搜不到无线网络怎么恢复|电脑搜不到无线网络的恢复方法...
- 苹果开发者账号续费相关问题
- 声反馈系统:陷波型啸叫抑制器的啸叫检测方法大总结
- php导出word 模板,Laravel+phpword导出word
- 【Hadoop的初级理解】
- 【Photoshop CS5永久序列号】一次输入永久使用
- 税务会计实务【13】
- 黑名单电话自动拦截【Android】
- MySQL 无密码登录