卷一 内核源代码分析 第二章 异常 2.2.3 Exynos4的中断体系 图书试读版-请勿转载

Linux GIC 的初始化 原创文章,转载请注明出处.Linux中断的初始化流程:Linux kernel的启动入口是start_kernel(), 在init/main.c中,start_kernel()中有一系列初始化操作,比如:boot_cpu_init(),setup_arch(&command_line),mm_init()等, 本文主要分析init_IRQ()__irqchip_of_table实际为静态... 阅读详情

作者 crosskernel@gmail.com


2.2.3 Exynos4的中断体系


三星,ARM处理器界的新王者,近年来抢先实现每一代ARM处理器,而且通过手机处理器与其庞大硬件产业链的有机整合成为Apple的最有力对手。
第一次将三星与高性能手机处理器联系起来的是其S5PV210,凭借超出同级处理器一倍的L2 Cache,S5PV210成为当时跑的最快的CA8 ARM。紧接着三星开始抢跑ARM界,在CA9时期,三星已经成为ARM处理器界的第一阵营,在CA15时期三星成为第一家先进ARM架构的实现者。
三星的ARM处理器成功背后的很大原因在于三星强大的产业链整合能力。在前端,三星手机的攻城略地保证了三星处理器出货量。在后端,三星的半导体工厂有比肩Intel的能力,总是可以以更先进的工艺的来降低功耗、节省成本。在市场大门开启的时候,三星的对手却要为处理器代工厂的工艺和良率伤透脑筋,为炫酷的LCD屏幕供货周期头疼,为了内存和EMMC的价格波动心惊胆战,而所有这些,三星集团的各个工厂数月之前都已经协调完毕,正按计划批量出货了。


本节分析exynos4的中断体系。


CPU0的GIC初始化工作从“void __init exynos4_init_irq(void)”开始:
void __init exynos4_init_irq(void)
{
int irq;


gic_bank_offset = soc_is_exynos4412() ? 0x4000 : 0x8000;
// S5P_VA_GIC_DIST是CPU0的GIC DIST基地址,S5P_VA_GIC_CPU是CPU0的GIC CPU interface 基地址
gic_init(0, IRQ_PPI_MCT_L, S5P_VA_GIC_DIST, S5P_VA_GIC_CPU);
…


}


void __init gic_init(unsigned int gic_nr, unsigned int irq_start,
void __iomem *dist_base, void __iomem *cpu_base)
{
struct gic_chip_data *gic;
int cpu;


…
    //GIC描述结构:struct gic_chip_data
gic = &gic_data[gic_nr];
//为每颗CPU分配放置DIST和CPU interface基地址的内存地址。
gic->dist_base = alloc_percpu(void __iomem *);
gic->cpu_base = alloc_percpu(void __iomem *);
…
    //先初始化CPU0的DIST和CPU interface基地址
for_each_possible_cpu(cpu) {
*per_cpu_ptr(gic->dist_base, cpu) = dist_base;
*per_cpu_ptr(gic->cpu_base, cpu) = cpu_base;
}


gic->irq_offset = (irq_start - 1) & ~31;


if (gic_nr == 0)
gic_cpu_base_addr = cpu_base;


    //DIST的初始化
gic_dist_init(gic, irq_start);
//CPU0的CPU interface基地址的内存
gic_cpu_init(gic);
}


/*所谓GIC dist的初始化,系统里只在CPU0进行,核心工作是配置GIC SPI中断(通常外围设备产生的中断)。*/
static void __init gic_dist_init(struct gic_chip_data *gic,
unsigned int irq_start)
{
unsigned int gic_irqs, irq_limit, i;
void __iomem *base = gic_data_dist_base(gic);
u32 cpumask = 1 << smp_processor_id();


//cpumask:每个8位的最低位都置1


cpumask |= cpumask << 8;
cpumask |= cpumask << 16;


writel_relaxed(0, base + GIC_DIST_CTRL);


/*
* Find out how many interrupts are supported.
* The GIC only supports up to 1020 interrupt sources.
*/
gic_irqs = readl_relaxed(base + GIC_DIST_CTR) & 0x1f;
gic_irqs = (gic_irqs + 1) * 32;
if (gic_irqs > 1020)
gic_irqs = 1020;


/*
* Set all global interrupts to be level triggered, active low.
*/
//先将SPI设置为电平触发


for (i = 32; i < gic_irqs; i += 16)
writel_relaxed(0, base + GIC_DIST_CONFIG + i * 4 / 16);


/*
* Set all global interrupts to this CPU only.
*/
//偏移量0x800-0x81C空间的每个BYTE指出了对应的中断分发到哪颗CPU上
//这里把所有的全局中断的分发方向都指向自己,这时只有CPU0可用。以后还可以使用
struct irq_chip的“int (*set_affinity)(unsigned int irq,const struct cpumask *dest);”函数将中断绑定到另外的CPU上。


for (i = 32; i < gic_irqs; i += 4)
writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4);


/*
* Set priority on all global interrupts.
*/
//0x400-0x7F8


for (i = 32; i < gic_irqs; i += 4)
writel_relaxed(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4);


/*
关闭除PPI 和SGIs 之外的中断
*/
for (i = 32; i < gic_irqs; i += 32)
writel_relaxed(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32);


/*
* Limit number of interrupts registered to the platform maximum
*/
irq_limit = gic->irq_offset + gic_irqs;
if (WARN_ON(irq_limit > NR_IRQS))
irq_limit = NR_IRQS;


/*
* Setup the Linux IRQ subsystem.
*/
//填充linux里generic中断分发数组
for (i = irq_start; i < irq_limit; i++) {
irq_set_chip_and_handler(i, &gic_chip, handle_fasteoi_irq);
irq_set_chip_data(i, gic);
set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
}


writel_relaxed(1, base + GIC_DIST_CTRL);
}


//CPU0的GIC cpu interface中断初始化,主要是PPI和SGI初始化,SGI是处理器间通信的重要手段
static void __cpuinit gic_cpu_init(struct gic_chip_data *gic)
{
void __iomem *dist_base = gic_data_dist_base(gic);
void __iomem *base = gic_data_cpu_base(gic);
int i;


/*
* Deal with the banked PPI and SGI interrupts - disable all
* PPI interrupts, ensure all SGI interrupts are enabled.
*/
//值得注意的是,这里PPI中断是被屏蔽的
writel_relaxed(0xffff0000, dist_base + GIC_DIST_ENABLE_CLEAR);
writel_relaxed(0x0000ffff, dist_base + GIC_DIST_ENABLE_SET);


/*
* Set priority on PPI and SGI interrupts
*/
for (i = 0; i < 32; i += 4)
writel_relaxed(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4 / 4);


writel_relaxed(0xf0, base + GIC_CPU_PRIMASK);
writel_relaxed(1, base + GIC_CPU_CTRL);
}


CPUX相关的GIC配置
CPUX不需要初始化GIC的SPI中断,所以CPUX相关的GIC初始化工作完成自身的GIC cpu interface中断初始化即可。值得关注是其执行流程:


asmlinkage void __cpuinit secondary_start_kernel(void)
{…
platform_secondary_init(cpu);
…}




void __cpuinit platform_secondary_init(unsigned int cpu)
{
//显然对于Exynos4x12处理器,CPUX的GIC DIST和CPU interface基地址的计算是:
CPU0的对应基地址+ 前面CPU占用的长度
void __iomem *dist_base = S5P_VA_GIC_DIST +
(gic_bank_offset * cpu);
void __iomem *cpu_base = S5P_VA_GIC_CPU +
(gic_bank_offset * cpu);



gic_secondary_init_base(0, dist_base, cpu_base);


…
}


void __cpuinit gic_secondary_init_base(unsigned int gic_nr,
      void __iomem *dist_base,
      void __iomem *cpu_base)
{
//先把基地址放到GIC描述结构里的数组里
if (dist_base)
*__this_cpu_ptr(gic_data[gic_nr].dist_base) = dist_base;
if (cpu_base)
*__this_cpu_ptr(gic_data[gic_nr].cpu_base) = cpu_base;
//CPUX的PPI SGI中断初始化,参见前面小节,不赘述
gic_cpu_init(&gic_data[gic_nr]);
}
Linux中断子系统(二)中断控制器GIC驱动分析 Linux中断子系统(二)中断控制器GIC驱动分析 备注:   1. Kernel版本:5.4   2. 使用工具:Source Insight 4.0   3. 参考博客: Linux中断子系统(一)中断控制器及驱动分析 吐血整理|肝翻Linux中断所有知识点 linux kernel的中断子系统之(七):GIC代码分析 设备信息添加 ARM平台的设备信息,都是通过Device Tree设备树来添加,下面就是一个中断控制器的设备树信息: gic: interrupt-controller@b00010 阅读详情

相关推荐

arm GIC介绍之三

GIC_V3 初始化设置 在GIC 介绍之一和二中,可以看到GIC的逻辑结构和硬件框架。 那么在初始化时候,需要将各个组件配置起来,Interrupt Controller中的Distributor,Redistributor,CPU Interface需要按照不同顺序配置。既然Distributor是所有CPU都可以对应的,那么这个只要在第一个CPU启动时配置就可以了,对于Redistribu

sunsissy的专栏 7980

IMX6ULL裸机学习(11)— 中断和GIC中断控制器

IMX6ULL裸机学习(11)— 中断和GIC 一、什么是GIC GIC即通用中断控制器( Generic Interrupt Controller),ARM 体系结构定义了通用中断控制器(GIC),该控制器包括一组用于管理单核或多核系统中的中断的硬件资源。 GIC 提供了内存映射寄存器,可用于管理中断源和行为,以及用于将中断路由到各个 CPU 核。它使软件能够屏蔽,启用和禁用来自各个中断源的中断,以对各个中断源进行优先级排序和生成软件触发中断。 如下图所示,对于各种中断都是通过GIC到达CPU的。另外

qq_38113006的博客 3742

开关电源补偿设计避坑手册:为什么你的Buck电路总在轻载时振荡?

本文深入剖析了Buck电路在轻载时发生振荡的根本原因,并提供了专业的补偿设计避坑指南。文章指出,轻载下输出滤波器Q值飙升、DCM模式切换导致的小信号模型剧变是主要诱因,并详细对比了Type II与Type III补偿网络在宽负载范围内的表现差异。通过结合LTspice仿真与工程实践,指导工程师如何优化补偿环路设计,确保电源从满载到空载的全程稳定。

hadoop5ranger的博客 677

Linux 中断 —— GIC 初始化

GIC-V2在 Linux 层的初始化分析 1、GIC 的 device node和GIC irq chip driver的匹配过程 (1)irq chip driver中的声明 在drivers\irqchip\irqchip.h文件中定义了 IRQCHIP_DECLARE : #define IRQCHIP_DECLARE(name, compat, fn) OF_DECL...

StephenZhou 4293

KTransformers安装笔记 利用docker安装KTransformers

KTransformers安装笔记 利用docker安装KTransformers

guoqingru0311的博客 1562

笔记——Oracle19c

Oracle阅读笔记

weixin_63819458的博客 1352

linux kernel的中断子系统之(七):GIC代码分析

linux kernel的中断子系统之(七):GIC代码分析 作者:linuxer 发布于:2014-9-4 19:59 分类:Linux内核分析 一、前言 GIC(Generic Interrupt Controller)是ARM公司提供的一个通用的中断控制器,其architecture specification目前有四个版本,V1~V4(V2最多支持8个ARM core,V3/V4

M_O_Bz的专栏 6599

VOSviewer文献可视化006:修改节点标签文字

由VOSviewer软件生成的可视化图形所显示的文字是小写的,有时候,我们希望其所显示的数据(如国家或作者的首字母等)能够以大写的方式呈现,这时可以进行对节点标签文字的修改操作,使图形显示我们想要的一个效果。

qq_41725964的博客 6153

linux 软件中断号,linux中断子系统:中断号的映射与维护

写在前沿:好久好久没有静下心来整理一些东西了,开始工作已有一个月,脑子里想整理的东西特别多。记录是一种很好的自我学习方式,静下来多思考多总结,三年的工作目标不能发生变化,作为职场菜鸟即将进入全世界半导体第一的Intel working,是机遇更是一种挑战,困难也是可想而知。脚踏实地、仰望星空,以结果为导向,以目标为准则,争取每天进步一点点。Linux内核版本:3.4.39一. linux中断子系统...

weixin_31887307的博客 882

Lumerical官方案例、FDTD时域有限差分法仿真学习(三)——环形谐振器(Ring resonator)之第一部分

环形谐振器教程的第 1 部分使用 MODE 来设计和仿真环形谐振器。 自由光谱范围 (FSR) 和品质因数 (Q 因数) 是这种面向片上通信应用的基于绝缘体上硅 (SOI) 波导设计的关键性能指标。

weixin_45719141的博客 3万+

基于matlab的阈值分割的车牌定位识别系统

车牌自动识别模块是现代社会智能交通系统(ITS)的重要组成部分,是图像处理和模式识别技术研究的热点,具有非常广泛的应用。车牌识别主要包括以下三个主要步骤:车牌区域定位、车牌字符分割、车牌字符识别。本案例通过对采集的车牌图像进行灰度变换、边缘检测、腐蚀及平滑等过程进行车牌图像预处理,并由此得到一种基于车牌颜色纹理特征的车牌定位方法,最终实现了车牌区域定位。车牌字符分割是为了方便后续对车牌字符进行匹配,从而对车牌进行识别。

在职AI算法工程师,擅长计算机视觉,YOLO目标检测、分割等,擅长web、pyqt界面可视化,好内容持续更新中,来这里跟大家一起学习,共同进步 973

Linux下触摸屏驱动程序分析

本文以Linux3.5--Exynos4412平台,分析触摸屏驱动核心内容。Linux下触摸屏驱动(以ft5x06_ts为例)需要了解如下知识: 1.  I2C协议 2.  Exynos4412处理器的I2C接口 3.  bus-dev-drv模型 4.  Linux下I2C总线驱动框架 6.  Linux下输入子系统 7.  Linux下中断处理 8.  Linux下工作队

fengel_cs的专栏 2800

华为FusionCompute之计算虚拟化

华为FusionCompute之虚拟化

jks212454的博客 2453

中断/gic代码导读:在哪里配置安全中断的?

思考:在哪里配置安全中断的? 在哪里配置中断的G0、NS-G1、S-G1分组的? optee 在optee中有一段默认的配置,将0-7配置成NS-G1,8-15配置成S-G1,16-31配置成NS-G1,32之后的也全部都是NS-G1 但是这段配置不一定会被调用,gic_init()由平台的main_init_gic()函数调用,在大多数的场景下,gic_init()是不会被调用的。 如下也只是列举了plat-rockchip平台对gic_init()的调用。 ATF ...

baron-周贺贺-代码改变世界ctw 651

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

拥抱 Qt4.6+(10) 用QtCreator开发ARM程序

Andrew Huang bluedrum@163.com     在QtCreator出来之前,ARM下的QT程序开发一般是用命令行开发,效率还是比较低。QtCreator出来后。可以简单用QtCreator来做全流程的开发的。   但是QtCreator不支持交叉调试。 这个可能是设计的没有考虑到。     1.QT的命令行开发模式     首先回顾一下命令行ARM开发模式,首先

894

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

基于ARM9的多功能硬盘MP3播放器的设计

很难给这个设计方案定义一个确切的名称,是硬盘MP3播放器,还是数码相机伴侣,还是是电子相框,甚至叫做移动硬盘?其实这几项功能这款设计方案都具备了。不过通常来说,作为MP3使用的频率更高一些,因此我们姑且还是将它称作多功能硬盘MP3播放器。 这 款多功能MP3播放器的核心是三星公司的S3C2410芯片。该芯片是基于ARM920T而开发的一款面向消费类电子产品的多功能SOC。除具备一般嵌入 式芯片所具

ruixj的专栏 1965

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

GIC驱动

本文以RK3288 GIC-400为例学习 kernel/driver/irqchip/irq-gic.c(GICV2版本驱动) gic再dts中的定义 rk3288.dtsi gic: interrupt-controller@ffc01000 { compatible = “arm,gic-400”; interrupt-controller; #interrupt-cells = <3>; #address-cells = <0>; reg = <0x0 0xff

layuetian2011的博客 463

irq-gic-v3.c之gic_of_init

irq-gic-v3.c的最后一句话是 736 IRQCHIP_DECLARE(gic_v3, "arm,gic-v3", gic_of_init); 有前面的博文可知会在start_kernel的是时候调用gic_of_init,我们来看看gic_of_init 到底做了什么事情. 我们会在dts文件中定义gic的hw register的地址。这个地址是物理地址. 652行得到这个地址后

jason的笔记 3131

GIC Interrupt Map --- Linux Kernel 实现赏析

1 : ID 分配 gic控制器最多支持 1020 个中断源, 支持多少,是soc 芯片设计时确定下来的 如 Altera cyclone 平台支持 256个中断源SPI 外设中断 (Shared Peripheral Interrupt) 32 ~ 1019先看一下中断控制器的初始化main.c ❶ /* 源头 : uboot最终会跳入这个坑里,唯有源头活水来,uboot现在都die了

500 1344

嵌入式项目2--QT学习笔记

近来想学着做一个上位机软件,因而好好学了学Qt,目标是为项目的板子做一个上位机通信的软件。学习教材《Qt Creator 快速入门》,第三版,霍亚飞编著,笔者学习是买的教材书,这样看着比较有感觉,并且以后也可以回头学习。与此同时,附上该教材代码分享: 链接: https://pan.baidu.com/s/1nuJNClb 密码: 6u3n,这样一来,上手较快,省下了很多时间。 ...

凡物加倍磨治,皆能变化气质 1428

linux gic驱动

GIC———-ARM Generic Interrupt Controller一、GIC简介: GIC是的ARM研发的一个通用的中断控制器,它在硬件上的实现形态分为两种: 一种是ARM体系中的半导体公司在研发自己的SOC的时候,向ARM公司购买GIC的IP,这些GIC的型号有:GIC-400,GIC-500等等。另一种形态是ARM vensor直接购买ARM公司已经集成了GIC的多核方案,比如C

程序猿Ricky的日常干货 5759

Linux kernel的中断子系统之(二):IRQ Domain介绍

Linux kernel的中断子系统之(二):IRQ Domain介绍 作者:linuxer 发布于:2014-8-19 18:46 分类:Linux内核分析 一、概述 在linux kernel中,我们使用下面两个ID来标识一个来自外设的中断: 1、IRQ number。CPU需要为每一个外设中断编号,我们称之IRQ Number。这个IRQ number是一个虚拟的interrup

M_O_Bz的专栏 4035

Exynos4412裸机开发系列教程--启动流程

看过前两篇教程的朋友,发现

XBOOT的专栏 6346

init_machine 在Kernel中被调用的过程

以tiny4412为例: arch/arm/mach-exynos/mach-tiny4412.c MACHINE_START(TINY4412, "TINY4412") /* Maintainer: FriendlyARM (www.arm9.net) */ .boot_params = S5P_PA_SDRAM + 0x100, .init_irq ...

weixin_33826609的博客 409

基于ARM开发信息采集系统

V4L2视频框架、温度PH传感器、舵机、摄像头的使用 可用于智能家居系统参考、智能鱼池信息采集系统设计等,其中内附源代码:

weixin_44925499的博客 324
上一篇: 卷一 内核源代码分析 第二章 异常 2.2.1 cortex A9多核处理器的中断控制器GIC---2.2.2 Mt6577的中断体系 图书试读版-请勿转载
下一篇: 卷一 内核源代码分析 第二章 异常 2.2.4 OMAP4的中断体系 图书试读版-请勿转载
crosskernel
博客等级 码龄18年 14粉丝 19原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值