linux stm32mp157 GIC-V2 中断处理过程分析

cpp 复制代码
/* 
** 中断触发时,调用的 handle_arch_irq 入口地址。
** 因为此时,挂接的就是 gic_handle_irq 函数!gic_handle_irq 是个全局函数指针,
** static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
** 它是Linux内核中处理GIC中断的核心函数,响应来自GIC的中断请求,完成中断状态的读取、
** 确认(ACK)、处理(ISR调用)和结束(EOI)的完整生命周期。函数通过循环处理可能存在
** 的多个挂起中断。
** 形参 regs 是 long 类型的数组指针,用于保存CPU切换上下文时刻的CPU寄存器现场数据。
** ARM的GIC-V2架构手册内,对中断ID号段的类型划分如下:
**  0-15    软中断(SGI),核间私有;Software-generated interrupt (SGI) 。
**  16-31   外设私有中断(PPI),核间私有;Private Peripheral Interrupt (PPI) 。
**  32-1019 外设共享中断(SPI),核间共享;Shared Peripheral Interrupt (SPI) 。
**  1020-1023 当前仍被保留的中断编号。
** 
*/
static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
{
	u32 irqstat, irqnr;
	/* gic_data 是 struct gic_chip_data 类型的全局数组 */
	struct gic_chip_data *gic = &gic_data[0];
	void __iomem *cpu_base = gic_data_cpu_base(gic);

	/*
	** 多中断处理​:当多个中断同时到达时,GIC会通过优先级排序依次处理,直到无挂起中断。
	** 抢占限制​:Linux默认不启用中断抢占,当前中断处理完成后才会响应新中断。
	** RTOS几乎都是中断抢占的!
	*/
	do {
		/* 读取CPU接口的GICC_IAR(Interrupt Acknowledge Register),
		该操作会返回当前最高优先级的中断ID,并将该中断状态从Pending转为Active​。 */
		irqstat = readl_relaxed(cpu_base + GIC_CPU_INTACK);
		/* 获得硬中断ID:GICC_IAR_INT_ID_MASK用于过滤保留位,仅保留有效中断号(0-1019) */
		irqnr = irqstat & GICC_IAR_INT_ID_MASK;

		/* ​外设中断处理(PPI和SPI:16-1019)​ */
		if (likely(irqnr > 15 && irqnr < 1020)) {
			if (static_branch_likely(&supports_deactivate_key))
				/* EOI操作​:向GICC_EOIR寄存器写入中断ID,
				   通知GIC中断处理完成,状态从Active转为Inactive */
				writel_relaxed(irqstat, cpu_base + GIC_CPU_EOI);
			isb();
			/* 路由​对应的ISR:handle_domain_irq通过中断描述符表
			   (gic->domain)找到对应的中断处理函数(ISR)。 */
			handle_domain_irq(gic->domain, irqnr, regs);
			continue;
		}
		if (irqnr < 16) { /* 软中断处理(SGI:0-15)​ */
			writel_relaxed(irqstat, cpu_base + GIC_CPU_EOI);
			if (static_branch_likely(&supports_deactivate_key))
				writel_relaxed(irqstat, cpu_base + GIC_CPU_DEACTIVATE);
#ifdef CONFIG_SMP  /* 若支持多核CPU的协同处理 */
			/*
			 * Ensure any shared data written by the CPU sending
			 * the IPI is read after we've read the ACK register
			 * on the GIC.
			 *
			 * Pairs with the write barrier in gic_raise_softirq
			 */
			smp_rmb();
			handle_IPI(irqnr, regs);
#endif
			continue;
		}
		break;
	} while (1);
}

两条路线的对比

这两条路线,最终都执行到了__handle_domain_irq 函数这里来,但是他们传入的参数不同。

实际采纳的路线 gic_handle_irq:

默认路线:

所以得出结论,不支持domain路由机制的旧版本的 linux generic interrupt layer 正如2.6.25版本说的,这种legacy,只是为了向前兼容,会慢慢过度,直到被废弃。

GIC-V3 重要的新特性 Affinity routing

这个比较重要,硬件层面新增了许多实用的特性来支持linux这种操作系统里中断管理层的工作,互相配合,提升性能。 Affinity 有关于实时性的支持。 GIC-V2 不支持 Affinity ,是V3版本后引入的。

​​​​​​​

相关推荐
水饺编程13 分钟前
第2章:Linux 基础,解压缩【.tar.bz2】压缩包文件
linux·c语言·汇编
Zevalin爱灰灰21 分钟前
Linux入门第二部分(ARM裸机篇) 第二章 Cortex-A7 MPCore架构与ARM汇编基础
linux·汇编·arm开发·嵌入式
倔强的石头10627 分钟前
【Linux指南】进程通信系列(七):System V 信号量 —— 同步互斥的内核原语
linux·运维·服务器
GeW39 分钟前
从"补短板"到"强优势"Linux与数据库认证成为产业跃迁人才支点
linux·数据库
小李不想当小白1 小时前
BKP备份寄存器与RTC实时时钟(STM32标准库学习笔记)
笔记·stm32·单片机·嵌入式硬件·学习·嵌入式
Zw-awa3 小时前
串口命令如何从字符串长成协议:帧头、长度、校验和与状态机
stm32
PellyKoo3 小时前
【Ubuntu】GTX 1080 Ti 显卡占用为0但功率高达60W的排查与解决
linux·运维·ubuntu
Fruiticecake3 小时前
epoll 回显服务器是怎么工作的:从 accept 队列到就绪链表,以及它和 select / poll 的区别
linux
La Pulga3 小时前
【FreeRTOS源码学习笔记】链表的实现
数据结构·笔记·stm32·mcu·链表·嵌入式·freertos
承渊政道4 小时前
Linux网络学习【从NAT与代理服务理解网络转发、探索内网穿透原理、再到认识DNS与ICMP、最后动手部署并测试内网穿透】
linux·网络·学习·内网穿透·dns·nat