ARMv8-中断处理接口
2017-05-16 16:22
393 查看
不考虑EL2和EL3,IRQ处理分两种情况:用户态发生的中断和内核态发生的中断,相应的中断处理接口分别为:
el1_irq
el0_irq
以内核态el1发生的irq为例:
irq_handler也是一个伪指令宏操作:
handle_arch_irq 在arch/arm64/kernel/irq.c设置:
根据不同的中断控制器会设置不同的处理接口,通过在驱动控制器设置,代码在drivers/irqchip/,以irq-gic.c(通用中断控制器)为例,设置set_handle_irq(gic_handle_irq):
el1_irq
el0_irq
以内核态el1发生的irq为例:
358 .align 6 359 el1_irq: 360 kernel_entry 1 //压栈,保存上下文; 361 enable_dbg 362 #ifdef CONFIG_TRACE_IRQFLAGS 363 bl trace_hardirqs_off 364 #endif 365 366 irq_handler /*调用中断处理默认函数*/ 367 368 #ifdef CONFIG_PREEMPT 369 get_thread_info tsk 370 ldr w24, [tsk, #TI_PREEMPT] // get preempt count 371 cbnz w24, 1f // preempt count != 0 372 ldr x0, [tsk, #TI_FLAGS] // get flags 373 tbz x0, #TIF_NEED_RESCHED, 1f // needs rescheduling? 374 bl el1_preempt 375 1: 376 #endif 377 #ifdef CONFIG_TRACE_IRQFLAGS 378 bl trace_hardirqs_on 379 #endif 380 kernel_exit 1 381 ENDPROC(el1_irq)
irq_handler也是一个伪指令宏操作:
187 /* 188 * Interrupt handling. 189 */ 190 .macro irq_handler 191 adrp x1, handle_arch_irq //把handle_arch_irq地址放到x1, handle_arch_irq是一个指针; 192 ldr x1, [x1, #:lo12:handle_arch_irq]//取出指针所指向的值; 193 mov x0, sp 194 blr x1 //跳转到handle_arch_irq 195 .endm
handle_arch_irq 在arch/arm64/kernel/irq.c设置:
45 void __init set_handle_irq(void (*handle_irq)(struct pt_regs *)) 46 { 47 if (handle_arch_irq) 48 return; 49 50 handle_arch_irq = handle_irq; 51 }
根据不同的中断控制器会设置不同的处理接口,通过在驱动控制器设置,代码在drivers/irqchip/,以irq-gic.c(通用中断控制器)为例,设置set_handle_irq(gic_handle_irq):
437 static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) 438 { 439 u32 irqstat, irqnr; 440 struct gic_chip_data *gic = &gic_data[0]; 441 void __iomem *cpu_base = gic_data_cpu_base(gic); 442 443 do { 444 irqstat = readl_relaxed_no_log(cpu_base + GIC_CPU_INTACK); 445 irqnr = irqstat & GICC_IAR_INT_ID_MASK; 446 447 if (likely(irqnr > 15 && irqnr < 1021)) { 448 uncached_logk(LOGK_IRQ, (void *)(uintptr_t)irqnr); 449 handle_domain_irq(gic->domain, irqnr, regs);//根据中断号调用相应的中断处理函数; 450 continue; 451 } 452 if (irqnr < 16) { 453 writel_relaxed_no_log(irqstat, cpu_base + GIC_CPU_EOI); 454 uncached_logk(LOGK_IRQ, (void *)(uintptr_t)irqnr); 455 #ifdef CONFIG_SMP 456 handle_IPI(irqnr, regs); 457 #endif 458 continue; 459 } 460 break; 461 } while (1); 462 }
相关文章推荐
- 中断处理程序里不能操作I2C操作接口
- zynq7000 中断系统及在UCOSIII中的中断处理接口
- WinCE中断处理过程
- 处理Windows 95的长文件名中断详解
- 理解操作系统对中断的处理
- Hibernate中使用Criteria接口的Projections类处理聚合结果
- Windows/Linux/Solaris 软中断处理机制
- 利用VC和ADO接口编写一个dll模块实现对数据库数据的处理
- Linux C 函数参考(接口处理)
- 深入浅出Linux设备驱动编程--设备驱动中的中断处理
- 利用VC和ADO接口编写一个dll模块实现对数据库数据的处理
- PC机高号中断编程8259初始化及中断服务程序处理(Turbo C例程)
- 在Windows CE增加自定义中断处理
- 理解操作系统对中断的处理
- ARM处理器中断处理的编程实现
- 保护模式下的8259A芯片编程及中断处理探究(上)(Version 0.02)
- (原创)网络处理的软中断机制分析
- PC机高号中断编程8259初始化及中断服务程序处理
- eCos学习笔记之中断处理代码分析