<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > linux-2.6.26內(nèi)核中ARM中斷實(shí)現(xiàn)詳解

          linux-2.6.26內(nèi)核中ARM中斷實(shí)現(xiàn)詳解

          作者: 時間:2012-09-01 來源:網(wǎng)絡(luò) 收藏

          @

          @ r2 - lr_, already fixed up for correct return/restart

          @ r3 - spsr_

          @ r4 - orig_r0 (see pt_regs definition in ptrace.h)

          @

          @ Also, separately save sp_usr and lr_usr

          @

          stmia r0, {r2 - r4}

          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

          上面的這段代碼主要在填充結(jié)構(gòu)體pt_regs ,這里提到的struct pt_regs,在include/asm/ptrace.h中定義。此時sp指向struct pt_regs。

          struct pt_regs {

          long uregs[18];

          };

          #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]

          3.4 irq_handler的實(shí)現(xiàn)過程,archarmkernelentry-armv.S

          .macro irq_handler

          get_irqnr_preamble r5, lr

          @在include/asm/arch-s3c2410/entry-macro.s中定義了宏get_irqnr_preamble為空操作,什么都不做

          1: get_irqnr_and_base r0, r6, r5, lr @判斷中斷號,通過R0返回,3.5節(jié)有實(shí)現(xiàn)過程

          movne r1, sp

          @

          @ routine called with r0 = irq number, r1 = struct pt_regs *

          @

          adrne lr, 1b

          bne asm_do_IRQ @進(jìn)入中斷處理。

          ……

          .endm

          3.5 get_irqnr_and_base中斷號判斷過程,include/asm/arch-s3c2410/entry-macro.s

          .macro get_irqnr_and_base, irqnr, irqstat, base, tmp

          mov base, #S3C24XX_VA_IRQ

          @@ try the interrupt offset register, since it is there

          ldr irqstat, [ base, #INTPND ]

          teq irqstat, #0

          beq 1002f

          ldr irqnr, [ base, #INTOFFSET ] @通過判斷INTOFFSET寄存器得到中斷位置

          mov tmp, #1

          tst irqstat, tmp, lsl irqnr

          bne 1001f

          @@ the number specified is not a valid irq, so try

          @@ 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 @加上中斷號的基準(zhǔn)數(shù)值,得到最終的中斷號,注意:此時沒有考慮子中斷的具體情況,(子中斷的問題后面會有講解)。IRQ_EINT0在include/asm/arch-s3c2410/irqs.h中定義.從這里可以看出,中斷號的具體值是有平臺相關(guān)的代碼決定的,和硬件中斷掛起寄存器中的中斷號是不等的。

          1002:

          @@ exit here, Z flag unset if IRQ

          .endm

          3.6 asm_do_IRQ實(shí)現(xiàn)過程,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;//根據(jù)中斷號找到對應(yīng)的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);// 根據(jù)中斷號和desc進(jìn)入中斷處理

          /* AT91 specific workaround */

          irq_finish(irq);

          irq_exit();

          set_irq_regs(old_regs);

          }

          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標(biāo)識。那么這個標(biāo)識的含義如何理解呢?

          該符號定義在kernel/include//linkage.h中,如下所示:

          #include //各個具體處理器在此文件中定義asmlinkage

          #ifdef __cplusplus

          #define CPP_ASMLINKAGE extern "C"

          #else

          #define CPP_ASMLINKAGE

          #endif

          #ifndef asmlinkage//如果以前沒有定義asmlinkage

          #define asmlinkage CPP_ASMLINKAGE

          #endif

          對于ARM處理器的,沒有定義asmlinkage,所以沒有意義(不要以為參數(shù)是從堆棧傳遞的,對于ARM平臺來說還是符合ATPCS過程調(diào)用標(biāo)準(zhǔn),通過寄存器傳遞的)。

          但對于X86處理器的中是這樣定義的:

          linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)


          關(guān)鍵詞: linux 內(nèi)核 ARM中斷

          評論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();