中断号和芯片中断引脚的关系

    技术2022-05-13  3

    一直以来搞不懂这个中断号的来历,总以为是中断控制器自己规定的一个号,但是最近在看了s3c2440的中断控制后才发现不是这么一回事.2440 的中断处理只能处理32个中断,但是其在内核中出现的中断号却有51,58等.而且它的外部中断INT4~7共享一个中断控制寄存器的一 位,INT8~23也是共享控制寄存器的一位.我就好奇了,它怎么区分这些中断呢?而且在内核代码中它又很清楚的区分了这些中断.如下面的代码 (2.6.13).

     

    " include/asm-arm/arch-s3c2410/irqs.h " ..... /* interrupts generated from the external interrupts sources */ # define   IRQ_EINT4       S3C2410_IRQ ( 32 )      /* 48 */ # define   IRQ_EINT5       S3C2410_IRQ ( 33 ) # define   IRQ_EINT6       S3C2410_IRQ ( 34 ) # define   IRQ_EINT7       S3C2410_IRQ ( 35 ) # define   IRQ_EINT8       S3C2410_IRQ ( 36 ) # define   IRQ_EINT9       S3C2410_IRQ ( 37 ) # define   IRQ_EINT10      S3C2410_IRQ ( 38 ) # define   IRQ_EINT11      S3C2410_IRQ ( 39 ) # define   IRQ_EINT12      S3C2410_IRQ ( 40 ) # define   IRQ_EINT13      S3C2410_IRQ ( 41 ) # define   IRQ_EINT14      S3C2410_IRQ ( 42 ) # define   IRQ_EINT15      S3C2410_IRQ ( 43 ) # define   IRQ_EINT16      S3C2410_IRQ ( 44 ) ....

    在看了N久之后才发现了其中的缘由: 在初始化的时候,在相关的启动代码中将这些中断源和中断号进行了一一的映射,然后再初始化irq_desc.而在执行中断的时候就根据中断控制器的一些状 态和控制寄存器来进行转换,将相应的中断源转换成中断号,再进行中断例程的执行.这里针对于2440的进行简单分析一下: 在”arch/arm/kernel/entry-armv.S” 的 irq_handler宏就是处理中断的,代码如下:

    /* * Interrupt handling.  Preserves r7, r8, r9 */ . macro   irq_handler 1 :      get_irqnr_and_base   r0 , r6 , r5 , lr   //而这里就是将中断源转换成相应中断号的一个宏,最后将中断号放到r0中 movne    r1 , sp @ @ routine   called with r0 = irq number , r1 = struct pt_regs * @ adrne    lr , 1 b bne      asm_do_IRQ //执行一般中断,函数原型:"arch/arm/kernel/irq.c" // asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs) //可以看出这里需要的参数有中断号和CPU发生中断时需要保存的寄存器   # ifdef   CONFIG_SMP /* * XXX * * this macro assumes that irqstat (r6) and base (r5) are * preserved from get_irqnr_and_base above */ test_for_ipi   r0 , r6 , r5 , lr movne    r0 , sp adrne    lr , 1 b bne      do_IPI     //执行CPU内部中断或是异常 # endif   . endm

    而对于中断源到中断号的转换宏get_irqnr_and_base这里要分析一下: 在”include/asm/arch/entry-macro.S” 中定义:

    . macro   get_irqnr_and_base , irqnr , irqstat , base , tmp //irqnr: 是用来存放最后的中断号的,也就是上面传递过来的r0 //irqstat: 用来存放中断状态的,即上面的r6 //base: 这个在这宏当中没有使用 //tmp:这个是用来存放中断控制器基地址的, //下面在获取个个控制寄存器值的时候都是在这个地址的基础之上加相应的值 mov      / tmp , # S3C24XX_VA_IRQ   //获取中断控制器基地址(是虚地址) ldr      / irqnr , [ / tmp , # 0x14   ]          @ get irq no 30000 : teq      / irqnr , # 4 teqne    / irqnr , # 5 beq      1002 f                            @ external   irq reg ..... //这里即是对EINT4~EINT23的中断号的映射, //RQ_EINT4是一个基本号,就是这个号和前面的中断号是断开的,其间这些中断号是预留给其它一些总线下的设备使用的. //而之后的中断号都是在这个号的基础上不断+1的,这里是其代码. mov      / irqnr , # IRQ_EINT4               @ start   extint nos mov      / irqstat , / irqstat , lsr # 4        @ ignore   bottom 4 bits 10021 : movs     / irqstat , / irqstat , lsr # 1 //这里是根据起中断状态再判断到底是那一个中断发生了 bcs      1004 f add      / irqnr , / irqnr , # 1 cmp      / irqnr , # IRQ_EINT23 ble      10021 b .....

    这里就完成了中断引脚和中断号的对应关系,哎,终于搞明白了!!!但是个个体系结构和中断控制器的映射方式应该是不一样的,这个只是真对于s3c2440来说的 这里就完成了


    最新回复(0)