新聞中心

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

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

        作者: 時(shí)間:2012-09-01 來(lái)源:網(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中定義。此時(shí)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)過(guò)程,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 @判斷中斷號(hào),通過(guò)R0返回,3.5節(jié)有實(shí)現(xiàn)過(guò)程

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

        1002:

        @@ exit here, Z flag unset if IRQ

        .endm

        3.6 asm_do_IRQ實(shí)現(xiàn)過(guò)程,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ù)中斷號(hào)找到對(duì)應(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();//沒(méi)做什么特別的工作,可以跳過(guò)不看

        desc_handle_irq(irq, desc);// 根據(jù)中斷號(hào)和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)識(shí)。那么這個(gè)標(biāo)識(shí)的含義如何理解呢?

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

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

        #ifdef __cplusplus

        #define CPP_ASMLINKAGE extern "C"

        #else

        #define CPP_ASMLINKAGE

        #endif

        #ifndef asmlinkage//如果以前沒(méi)有定義asmlinkage

        #define asmlinkage CPP_ASMLINKAGE

        #endif

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

        但對(duì)于X86處理器的中是這樣定義的:

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


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

        評(píng)論


        相關(guān)推薦

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

        關(guān)閉
        主站蜘蛛池模板: 天全县| 江达县| 克拉玛依市| 越西县| 井陉县| 林口县| 莱芜市| 潼关县| 宣汉县| 麻江县| 来宾市| 长葛市| 慈利县| 鄱阳县| 靖宇县| 拉孜县| 怀集县| 虎林市| 吴堡县| 谷城县| 陵水| 化州市| 阿拉尔市| 田林县| 三明市| 晴隆县| 鄂尔多斯市| 防城港市| 大城县| 洛宁县| 万宁市| 聂拉木县| 集贤县| 黄浦区| 平顶山市| 古丈县| 富民县| 万州区| 上思县| 沾化县| 长兴县|