Chinaunix首页 | 论坛 | 博客
  • 博客访问: 127696
  • 博文数量: 35
  • 博客积分: 2085
  • 博客等级: 大尉
  • 技术积分: 395
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-03 10:42
文章分类

全部博文(35)

文章存档

2012年(1)

2011年(3)

2010年(15)

2009年(8)

2008年(8)

我的朋友

分类: LINUX

2010-09-21 15:16:26


arch/arm/kernel/entry-armv.S

 447 .align 5
 448 __irq_usr:
 449     usr_entry @保存usr mode下的寄存器,有详细介绍。

 450     kuser_cmpxchg_check
 451
 452     get_thread_info tsk @通过将sp的低13位设为0获得task指针。
 453 #ifdef CONFIG_PREEMPT
 454     ldr r8, [tsk, #TI_PREEMPT] @ get preempt count
 455     add r7, r8, #1 @ increment it
 456     str r7, [tsk, #TI_PREEMPT]
 457 #endif
 458
 459    irq_handler  @irq处理函数,这个函数的核心,下面详细介绍。
 460 #ifdef CONFIG_PREEMPT
 461     ldr r0, [tsk, #TI_PREEMPT]
 462     str r8, [tsk, #TI_PREEMPT]
 463     teq r0, r7
 464 ARM( strne r0, [r0, -r0] )
 465 THUMB( movne r0, #0 )
 466 THUMB( strne r0, [r0] )
 467 #endif
 468 #ifdef CONFIG_TRACE_IRQFLAGS
 469     bl trace_hardirqs_on
 470 #endif
 471
 472 mov why, #0
 473 b ret_to_user
 474 UNWIND(.fnend )
 475 ENDPROC(__irq_usr)


L449     usr_entry
arch/arm/kernel/entry-armv.S

 360     .macro usr_entry
 361 UNWIND(.fnstart )

 362 UNWIND(.cantunwind ) @ do not unwind the user space

 363     sub sp, sp, #S_FRAME_SIZE
 364 ARM( stmib sp, {r1 - r12} )
 365 THUMB( stmia sp, {r0 - r12} )
 366
 367     ldmia r0, {r1 - r3}
 368     add r0, sp, #S_PC @ here for interlock avoidance
 369     mov r4, #-1 @ "" "" "" ""
 370
 371     str r1, [sp] @ save the "real" r0 copied
 372     @ from the exception stack
 373
 374     @
 375     @ We are now ready to fill in the remaining blanks on the stack:
 376     @
 377     @ r2 - lr_<exception>, already fixed up for correct return/restart
 378     @ r3 - spsr_<exception>
 379     @ r4 - orig_r0 (see pt_regs definition in ptrace.h)
 380     @
 381     @ Also, separately save sp_usr and lr_usr
 382     @
 383     stmia r0, {r2 - r4}
 384 ARM( stmdb r0, {sp, lr}^ )
 385 THUMB( store_user_sp_lr r0, r1, S_SP - S_PC )
 386
 387     @
 388     @ Enable the alignment trap while in kernel mode
 389     @
 390     alignment_trap r0
 391
 392     @
 393     @ Clear FP to mark the first stack frame
 394     @
 395     zero_fp
 396
 397     asm_trace_hardirqs_off
 398     .endm


L452     get_thread_info tsk
通过把寄存器sp的低13位置0获得task的指针。


L459    irq_handler
arch/arm/kernel/entry-armv.S

  28 /*
  29 * Interrupt handling. Preserves r7, r8, r9
  30 */
  31      .macro irq_handler
  32      get_irqnr_preamble r5, lr
  33 1:   get_irqnr_and_base r0, r6, r5, lr @获得irq number放在r0中
  34      movne r1, sp @如果r0(irq number)非0,将r1设为sp(struct pt_regs).这是为调用asm_do_IRQ()做准备,r0和r1是asm_do_IRQ()的两个参数。
  35      @
  36      @ routine called with r0 = irq number, r1 = struct pt_regs *
  37      @
  38      adrne lr, BSYM(1b) @设置asm_do_IRQ()的返回地址是1:。循环获得下一个irq number并调用asm_do_IRQ(),直到所有的irq number被处理完毕。
  39      bne asm_do_IRQ
  40
  41 #ifdef CONFIG_SMP
  42     /*
  43      * XXX
  44      *
  45      * this macro assumes that irqstat (r6) and base (r5) are
  46      * preserved from get_irqnr_and_base above
  47      */
  48     test_for_ipi r0, r6, r5, lr
  49     movne r0, sp
  50     adrne lr, BSYM(1b)
  51     bne do_IPI
  52
  53 #ifdef CONFIG_LOCAL_TIMERS
  54     test_for_ltirq r0, r6, r5, lr
  55     movne r0, sp
  56     adrne lr, BSYM(1b)
  57     bne do_local_timer
  58 #endif
  59 #endif
  60
  61     .endm


  L32      get_irqnr_preamble r5, lr
  L33 1:    get_irqnr_and_base r0, r6, r5, lr

这两个宏都是在arch/arm/mach-xxxxxxx/include/mach/entry-macro.S中定义。用来获得最高优先级的irq number.

 L39      bne asm_do_IRQ



100 /*
101 * do_IRQ handles all hardware IRQ's. Decoded IRQs should not
102 * come via this function. Instead, they should provide their
103 * own 'handler'
104 */

105 asmlinkage void __exception asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
106 {
107     struct pt_regs *old_regs = set_irq_regs(regs);
108
109     irq_enter();
110
111     /*
112      * Some hardware gives randomly wrong interrupts. Rather
113      * than crashing, do something sensible.
114      */

115     if (unlikely(irq >= NR_IRQS)) {
116          if (printk_ratelimit())
117               printk(KERN_WARNING "Bad IRQ%u\n", irq);
118         ack_bad_irq(irq);
119     } else {
120         generic_handle_irq(irq);
121     }
122
123     /* AT91 specific workaround */
124     irq_finish(irq);
125
126     irq_exit();
127     set_irq_regs(old_regs);
128 }


L120         generic_handle_irq(irq);

302 /*
303 * Architectures call this to let the generic IRQ layer
304 * handle an interrupt. If the descriptor is attached to an
305 * irqchip-style controller then we call the ->handle_irq() handler,
306 * and it calls __do_IRQ() if it's attached to an irqtype-style controller.
307 */

308 static inline void generic_handle_irq_desc(unsigned int irq, struct irq_desc *desc)
309 {
310 #ifdef CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ
311     desc->handle_irq(irq, desc);
312 #else
313     if (likely(desc->handle_irq))
314         desc->handle_irq(irq, desc);
315     else
316         __do_IRQ(irq); //如果未定义desc->handle_irq(),调用通过的irq处理函数__do_IRQ(irq).
317 #endif
318 }
319
320 static inline void generic_handle_irq(unsigned int irq)
321 {
322     generic_handle_irq_desc(irq, irq_to_desc(irq));
323 }


每个平台的irq及其handle_irq都是在平台目录的下的irq.c文件里设置的。
arch/arm/mach-comcerto/irq.c

168 void __init comcerto_irq_init(struct comcerto_irq_desc *irq_table, int size)
169 {
170     unsigned int irq;
171     int i;
172
173     spin_lock_init(&comcerto_irq_lock);
174
175     /* mask all interrupts */
176     __raw_writel(0, COMCERTO_INTC_CSP_IRQMASK_0);
177     __raw_writel(0, COMCERTO_INTC_CSP_IRQMASK_1);
178
179     for (i = 0; i < size; i++) {
180         irq = irq_table[i].num;
181
182         /* setup interrupt handler and priority */
183         if (irq < 32) {
184              /* All STATUS0 interrupts must be setup from the single table declared in comcerto-xxx.c
185              * file. Use description index as a priority.
186              */

187              comcerto_irq_priority_set(irq, irq_table[i].prio);
188              set_irq_chip(irq, &comcerto_irq_chip_0);
189         } else
191              set_irq_chip(irq, &comcerto_irq_chip_1);
192
193         if (irq_table[i].handler != NULL) {
194             set_irq_handler(irq, irq_table[i].handler);
195             set_irq_flags(irq, IRQF_VALID);
196         }
197     }
198 }


阅读(2164) | 评论(0) | 转发(0) |
0

上一篇:三个抄写员

下一篇:ret_to_user

给主人留下些什么吧!~~