在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

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

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

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

            @

            @ 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

            上面的這段代碼主要在填充結構體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的實現(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é)有實現(xiàn)過程

            movne r1, sp

            @

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

            @

            adrne lr, 1b

            bne asm_do_IRQ @進入中斷處理。

            ……

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

            1002:

            @@ exit here, Z flag unset if IRQ

            .endm

            3.6 asm_do_IRQ實現(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ù)中斷號找到對應的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進入中斷處理

            /* 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標識。那么這個標識的含義如何理解呢?

            該符號定義在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過程調用標準,通過寄存器傳遞的)。

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

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


            關鍵詞: linux 內核 ARM中斷

            評論


            相關推薦

            技術專區(qū)

            關閉