linux-2.6.26内核ARM中断实现过程详解(2)(2)

2019-08-29 20:08

@@ and work it out for ourselves mov \\irqnr, #0 @@ start here @@ work out which irq (if any) we got movs \\tmp, \\irqstat, lsl#16 addeq \\irqnr, \\irqnr, #16

moveq \\irqstat, \\irqstat, lsr#16 tst \\irqstat, #0xff

addeq \\irqnr, \\irqnr, #8

moveq \\irqstat, \\irqstat, lsr#8 tst \\irqstat, #0xf

addeq \\irqnr, \\irqnr, #4

moveq \\irqstat, \\irqstat, lsr#4 tst \\irqstat, #0x3

addeq \\irqnr, \\irqnr, #2

moveq \\irqstat, \\irqstat, lsr#2 tst \\irqstat, #0x1

addeq \\irqnr, \\irqnr, #1 @@ we have the value 1001:

adds \\irqnr, \\irqnr, #IRQ_EINT0 @加上中断号的基准数值,得到最终的中断号,注意:此时没有考虑子中断的具体情况,(子中断的问题后面会有讲解)。IRQ_EINT0在include/asm/arch-s3c2410/irqs.h中定义.从这里可以看出,中断号的具体值是有平台相关的代码决定的,和硬件中断挂起寄存器中的中断号是不等的。 1002:

@@ exit here, Z flag unset if IRQ .endm

3.6 asm_do_IRQ实现过程,arch/arm/kernel/irq.c

asmlinkage void __exception asm_do_IRQ(unsigned int irq, struct pt_regs *regs) {

struct pt_regs *old_regs = set_irq_regs(regs);

struct irq_desc *desc = irq_desc + irq;//根据中断号找到对应的irq_desc /*

* Some hardware gives randomly wrong interrupts. Rather * than crashing, do something sensible. */

if (irq >= NR_IRQS)

desc = &bad_irq_desc;

irq_enter();//没做什么特别的工作,可以跳过不看

desc_handle_irq(irq, desc);// 根据中断号和desc进入中断处理 /* AT91 specific workaround */ irq_finish(irq); irq_exit();

set_irq_regs(old_regs);

6

}

static inline void desc_handle_irq(unsigned int irq, struct irq_desc *desc) {

desc->handle_irq(irq, desc);//中断处理 }

上述asmlinkage void __exception asm_do_IRQ(unsigned int irq, struct pt_regs *regs)使用了asmlinkage标识。那么这个标识的含义如何理解呢?

该符号定义在kernel/include/linux/linkage.h中,如下所示:

#include //各个具体处理器在此文件中定义asmlinkage #ifdef __cplusplus

#define CPP_ASMLINKAGE extern \#else

#define CPP_ASMLINKAGE #endif

#ifndef asmlinkage//如果以前没有定义asmlinkage #define asmlinkage CPP_ASMLINKAGE #endif

对于ARM处理器的,没有定义asmlinkage,所以没有意义(不要以为参数是从堆栈传递的,对于ARM平台来说还是符合ATPCS过程调用标准,通过寄存器传递的)。

但对于X86处理器的中是这样定义的:

#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0))) 表示函数的参数传递是通过堆栈完成的。

3.7 描述3.3节中的ret_to_user 中断返回过程,/arch/arm/kernel/entry-common.S 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

7

add sp, sp, #S_FRAME_SIZE - S_PC

movs pc, lr @ return & move spsr_svc into cpsr

第三章主要跟踪了从中断发生到调用到对应中断号的desc->handle_irq(irq, desc)中断函数的过程。后面的章节还会继续讲解后面的内容。

8


linux-2.6.26内核ARM中断实现过程详解(2)(2).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:5跨20米简支空心板梁毕业设计

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: