IRQ中断处理流程
基于Linux2.6.30.4分析IRQ中断的处理流程。
1.中断入口
/* arch/arm/kenel/entry-armv.S*/
b vector_irq + stubs_offset
2.vector_irq
vector_stub 宏展开即为vector_irq, 参考Linux异常体系之vector_stub宏解析。
/*
* Interrupt dispatcher
*/
vector_stub irq, IRQ_MODE, .long __irq_usr @ (USR_26 / USR_32)
.long __irq_invalid @ (FIQ_26 / FIQ_32)
.long __irq_invalid @ (IRQ_26 / IRQ_32)
.long __irq_svc @ (SVC_26 / SVC_32)
3.__irq_user
__irq_usr:
usr_entry /*3.1*/
kuser_cmpxchg_check #ifdef CONFIG_TRACE_IRQFLAGS
bl trace_hardirqs_off
#endif
get_thread_info tsk /*3.2*/ #ifdef CONFIG_PREEMPT
/*
*r8<--old preempt_count
*r7<--preempt_count+1
*preempt_count<--r7
*/
ldr r8, [tsk, #TI_PREEMPT] @ get preempt count
add r7, r8, # @ increment it
str r7, [tsk, #TI_PREEMPT]
#endif irq_handler /*3.3*/
#ifdef CONFIG_PREEMPT
/*
*r0<--new preempt_count
*preempt<--old preempt_count
*/
ldr r0, [tsk, #TI_PREEMPT]
str r8, [tsk, #TI_PREEMPT]
teq r0, r7
strne r0, [r0, -r0]
#endif #ifdef CONFIG_TRACE_IRQFLAGS
bl trace_hardirqs_on
#endif mov why, #
b ret_to_user /*3.4*/
UNWIND(.fnend )
ENDPROC(__irq_usr)
3.1__user_entry
.macro usr_entry
UNWIND(.fnstart )
UNWIND(.cantunwind ) @ don't unwind the user space
/* DEFINE(S_FRAME_SIZE, sizeof(struct pt_regs));*/
sub sp, sp, #S_FRAME_SIZE /**/
stmib sp, {r1 - r12} ldmia r0, {r1 - r3}
add r0, sp, #S_PC @ here for interlock avoidance
mov r4, #- @ "" "" "" "" str r1, [sp] @ save the "real" r0 copied
@ from the exception stack @
@ We are now ready to fill in the remaining blanks on the stack:
@
@ r2 - lr_<exception>, already fixed up for correct return/restart
@ r3 - spsr_<exception>
@ r4 - orig_r0 (see pt_regs definition in ptrace.h)
@
@ Also, separately save sp_usr and lr_usr
@
stmia r0, {r2 - r4}
/*“^”符号表示访问user mode的寄存器*/
stmdb r0, {sp, lr}^ @
@ Enable the alignment trap while in kernel mode
@
alignment_trap r0 @
@ Clear FP to mark the first stack frame
@
zero_fp
.endm
这里面用到pt_regs结构保存栈上的数据,8字节对齐
/*
* This struct defines the way the registers are stored on the
* stack during a system call. Note that sizeof(struct pt_regs)
* has to be a multiple of 8.
*/
struct pt_regs {
long uregs[];
};
与之相关的宏定义如下
DEFINE(S_FRAME_SIZE, sizeof(struct pt_regs)); DEFINE(S_R0, offsetof(struct pt_regs, ARM_r0));
DEFINE(S_R1, offsetof(struct pt_regs, ARM_r1));
DEFINE(S_R2, offsetof(struct pt_regs, ARM_r2));
DEFINE(S_R3, offsetof(struct pt_regs, ARM_r3));
DEFINE(S_R4, offsetof(struct pt_regs, ARM_r4));
DEFINE(S_R5, offsetof(struct pt_regs, ARM_r5));
DEFINE(S_R6, offsetof(struct pt_regs, ARM_r6));
DEFINE(S_R7, offsetof(struct pt_regs, ARM_r7));
DEFINE(S_R8, offsetof(struct pt_regs, ARM_r8));
DEFINE(S_R9, offsetof(struct pt_regs, ARM_r9));
DEFINE(S_R10, offsetof(struct pt_regs, ARM_r10));
DEFINE(S_FP, offsetof(struct pt_regs, ARM_fp));
DEFINE(S_IP, offsetof(struct pt_regs, ARM_ip));
DEFINE(S_SP, offsetof(struct pt_regs, ARM_sp));
DEFINE(S_LR, offsetof(struct pt_regs, ARM_lr));
DEFINE(S_PC, offsetof(struct pt_regs, ARM_pc));
DEFINE(S_PSR, offsetof(struct pt_regs, ARM_cpsr));
DEFINE(S_OLD_R0, offsetof(struct pt_regs, ARM_ORIG_r0)); #define ARM_cpsr uregs[16]
#define ARM_pc uregs[15]
#define ARM_lr uregs[14]
#define ARM_sp uregs[13]
#define ARM_ip uregs[12]
#define ARM_fp uregs[11]
#define ARM_r10 uregs[10]
#define ARM_r9 uregs[9]
#define ARM_r8 uregs[8]
#define ARM_r7 uregs[7]
#define ARM_r6 uregs[6]
#define ARM_r5 uregs[5]
#define ARM_r4 uregs[4]
#define ARM_r3 uregs[3]
#define ARM_r2 uregs[2]
#define ARM_r1 uregs[1]
#define ARM_r0 uregs[0]
#define ARM_ORIG_r0 uregs[17]
macos
3.2 get_thread_info tsk
tsk即r9寄存器的别名,内核中为寄存器声明的别名如下
/*
* These are the registers used in the syscall handler, and allow us to
* have in theory up to 7 arguments to a function - r0 to r6.
*
* r7 is reserved for the system call number for thumb mode.
*
* Note that tbl == why is intentional.
*
* We must set at least "tsk" and "why" when calling ret_with_reschedule.
*/
scno .req r7 @ syscall number
tbl .req r8 @ syscall table pointer
why .req r8 @ Linux syscall (!= )
tsk .req r9 @ current thread_info
get_thread_info tsk的作用是获取sp地址保存在tsk(r9)中,即r9中保存当前任务的thread_info结构的地址。
.macro get_thread_info, rd
mov \rd, sp, lsr # /*获取sp地址*/
mov \rd, \rd, lsl # /*8KBytes对齐*/
.endm
3.3 irq_handler
irq_handler函数调用分析以后再写。
/*
* Interrupt handling. Preserves r7, r8, r9
*/
.macro irq_handler
get_irqnr_preamble r5, lr
: get_irqnr_and_base r0, r6, r5, lr
movne r1, sp
@
@ routine called with r0 = irq number, r1 = struct pt_regs *
@
adrne lr, 1b
bne asm_do_IRQ #ifdef CONFIG_SMP
/*
* XXX
*
* this macro assumes that irqstat (r6) and base (r5) are
* preserved from get_irqnr_and_base above
*/
test_for_ipi r0, r6, r5, lr
movne r0, sp
adrne lr, 1b
bne do_IPI #ifdef CONFIG_LOCAL_TIMERS
test_for_ltirq r0, r6, r5, lr
movne r0, sp
adrne lr, 1b
bne do_local_timer
#endif
#endif .endm
3.4 ret_to_user
ret_to_user函数调用分析以后再写。
/*
* "slow" syscall return path. "why" tells us if this was a real syscall.
*/
ENTRY(ret_to_user)
ret_slow_syscall:
disable_irq @ disable interrupts
ldr r1, [tsk, #TI_FLAGS]
tst r1, #_TIF_WORK_MASK
bne work_pending
no_work_pending:
/* perform architecture specific actions before user return */
arch_ret_to_user r1, lr @ slow_restore_user_regs
ldr r1, [sp, #S_PSR] @ get calling cpsr
ldr lr, [sp, #S_PC]! @ get pc
msr spsr_cxsf, r1 @ save in spsr_svc
ldmdb sp, {r0 - lr}^ @ get calling r0 - lr
mov r0, r0
add sp, sp, #S_FRAME_SIZE - S_PC
movs pc, lr @ return & move spsr_svc into cpsr
ENDPROC(ret_to_user)
IRQ中断处理流程的更多相关文章
- bootloader启动代码init.s解析----IRQ中断处理函数
bootloader启动代码init.s解析----IRQ中断处理函数 init.s源代码如下: ;///////////////////////////////////////////// ;opt ...
- 【原创】中断子系统-ARM GPIO中断处理流程
目录 第一部分 GIC中断控制器的注册 1. GIC驱动分析 2.GIC驱动流程分析 第二部分 device node转化为platform_device 第三部分:platform_device注册 ...
- Exynos4412 中断处理流程详解
Linux 中,当外设触发中断后,大体处理流程如下: a -- 具体CPU architecture相关的模块会进行现场保护,然后调用machine driver对应的中断处理handler; b - ...
- 中断处理流程,ok6410
中断处理流程 CPU在工作的过程中,经常需要与外设进行交互,交互的方式包括”轮询方式”,”中断方式”. 1.轮询方式: CPU不断地查询设备的状态.该方式实现比较简单,但CPU利用率很低,不适合多任务 ...
- Linux 简单按键中断处理流程
中断处理程序中不能延时.休眠之类的,一定要最快速.高效的执行完. // 功能:申请中断 // 参数1:中断号码,通过宏 IRA_EINT(x) 获取 // 参数2:中断的处理函数,填函数名 // 参数 ...
- ATMEL精妙的IRQ中断处理过程
A: 从栈地址开始,栈顶为AT91SAM7S64的16K片内RAM尽头0x00204000IRQ_STACK_SIZE = 3*8*4FIQ_STACK_SIZE = 0x004ABT_STACK_S ...
- 专题2-通过按键玩中断\第1课-中断处理流程深度剖析-lesson1
中断概念 1.中断生命周期 串口先产生一个事件,该事件传送到中断控制器里面,中断控制器会进行相应过滤,能通过过滤,那么就交给CPU去处理. 2.中断源 2440芯片手册 6410芯片手册 3.中断过滤 ...
- Linux中断处理流程
http://blog.csdn.net/dianhuiren/article/details/7468956
- Linux中断处理体系结构分析
Linux中断处理体系结构分析(一) 异常,就是可以打断CPU正常运行流程的一些事情,比如外部中断.未定义指令.试图修改只读的数据.执行swi指令(Software Interrupt Instruc ...
随机推荐
- Python入门小练习
Python入门小练习 001 备份文件 Python入门小练习 002 批量下载网页链接中的图片 Python入门小练习 003 利用cookielib模拟登录获取账户信息
- Ubuntu使用实录
在实验室的电脑上重新配置了Linux开发环境,使用的是Ubuntu 14.04.5 LTS. 在开发中遇到的问题甚多,一一记录如下: 1.切换为root身份 先给root用户设定密码,然后进行切换 s ...
- 捕获异常try-catch-finally
异常分类 try-carch-finally出现规则 return关键字的使用 finally中慎用return,虽然语法上没错,但是由于finally的强制执行,影响逻辑上需要return的值 pa ...
- 解决 openSUSE 中 Sublime Text 3 的中文显示和输入问题
测试环境 系统版本:openSUSE Leap 42.2 桌面环境:KDE Plasma 5输入法:fcitx-rime (中州韵) 见周围用 Windows 和 macOS 的小伙伴几乎都在用简单强 ...
- 【aspnetcore】在asp.net core中配置使用AutoMapper
网上使用AutoMapper的文章很多,就不多说了.这里主要记录一下怎么在项目中配置和使用. 首先是从NuGet获取AutoMapper. 在Startup.cs文件中注册AutoMapper服务 p ...
- 前端之CSS盒模型介绍
css盒模型 css盒模型是css的基石,盒模型由content(主体内容),padding(补白,填充),border(边框),margin(外间距); 1.content: width:数值+单位 ...
- 利用js日期控件重构WEB功能
开发需求:网页中的日期部门(注册页面和查询条件)都用js日期控件重写 页面一:更新员工页面 empUpdate.jsp 中增加 onfocus 事件 入职日期:<input id="h ...
- iphone之打开pdf、doc、xls文件用UIWebView
//文件名字及类型 NSString *path=[[NSBundle mainBundle]pathForResource:@"xls1" ofType:@"xls&q ...
- hadoop ssh 问题WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
0.0.0.0: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@0.0.0.0: @ WARNING: REMOTE HO ...
- 在hibernate框架中配置显示sql语句
使用Hibernate的框架开发时,可在Hibernate.cfg.xml中加上 <property name="hibernate.show_sql">true< ...