uClinux for bf561中的中断处理(1):中断初始化

 
  
在uClinux初始化的过程中,就会配置好相应的中断向量表,并根据用户的配置来设置外部中断的优先级。
/* init/main.c */
asmlinkage void __init start_kernel(void)
{
       sort_main_extable();
       trap_init();
       rcu_init();
       init_IRQ();
       pidhash_init();
       init_timers();
       hrtimers_init();
       softirq_init();
       timekeeping_init();
       time_init();
}
其中的trap_init函数只是简单地设置了中断3(Exception)的中断向量(trap,汇编代码),实际上在后面的init_IRQ函数中又设置了一道。其作用是防止rcu_init出错时可以捕捉到。需要注意的是,此时uClinux还没有打开中断,即IMASK还是bf561复位以后的默认值,但是在复位后Exception中断默认是打开的,因此才有可能捕捉到rcu_init的异常。
init_IRQ是一个主要的中断初始化函数,包括中断向量的写入,中断优先级的配置等等。不过很奇怪的是,init_IRQ居然不处理中断1,即Reset中断!
bf561支持64个外部中断,后4个保留,其余60个可以通过宏来控制它们的优先级,这些宏的值可以介于[7-15]之间,uClinux将根据这60个值来配置SIC_IAR。
#define CONFIG_IRQ_PLL_WAKEUP         7
#define CONFIG_IRQ_DMA1_ERROR               7
#define CONFIG_IRQ_DMA2_ERROR               7
#define CONFIG_IRQ_IMDMA_ERROR            7
#define CONFIG_IRQ_PPI0_ERROR          7
#define CONFIG_IRQ_PPI1_ERROR          7
#define CONFIG_IRQ_SPORT0_ERROR            7
#define CONFIG_IRQ_SPORT1_ERROR            7
 
#define CONFIG_IRQ_SPI_ERROR            7
#define CONFIG_IRQ_UART_ERROR         7
#define CONFIG_IRQ_RESERVED_ERROR       7
#define CONFIG_IRQ_DMA1_0                 7
#define CONFIG_IRQ_DMA1_1                 7
#define CONFIG_IRQ_DMA1_2                 7
#define CONFIG_IRQ_DMA1_3                 7
#define CONFIG_IRQ_DMA1_4                 7
 
#define CONFIG_IRQ_DMA1_5                 7
#define CONFIG_IRQ_DMA1_6                 7
#define CONFIG_IRQ_DMA1_7                 7
#define CONFIG_IRQ_DMA1_8                 7
#define CONFIG_IRQ_DMA1_9                 7
#define CONFIG_IRQ_DMA1_10                7
#define CONFIG_IRQ_DMA1_11                7
#define CONFIG_IRQ_DMA2_0                 7
 
#define CONFIG_IRQ_DMA2_1                 7
#define CONFIG_IRQ_DMA2_2                 7
#define CONFIG_IRQ_DMA2_3                 7
#define CONFIG_IRQ_DMA2_4                 7
#define CONFIG_IRQ_DMA2_5                 7
#define CONFIG_IRQ_DMA2_6                 7
#define CONFIG_IRQ_DMA2_7                 7
#define CONFIG_IRQ_DMA2_8                 7
 
#define CONFIG_IRQ_DMA2_9                 7
#define CONFIG_IRQ_DMA2_10                7
#define CONFIG_IRQ_DMA2_11                7
#define CONFIG_IRQ_TIMER0                  7
#define CONFIG_IRQ_TIMER1                  7
#define CONFIG_IRQ_TIMER2                  7
#define CONFIG_IRQ_TIMER3                  7
#define CONFIG_IRQ_TIMER4                  7
 
#define CONFIG_IRQ_TIMER5                  7
#define CONFIG_IRQ_TIMER6                  7
#define CONFIG_IRQ_TIMER7                  7
#define CONFIG_IRQ_TIMER8                  7
#define CONFIG_IRQ_TIMER9                  7
#define CONFIG_IRQ_TIMER10                7
#define CONFIG_IRQ_TIMER11                7
#define CONFIG_IRQ_PROG0_INTA          7
 
#define CONFIG_IRQ_PROG0_INTB          7
#define CONFIG_IRQ_PROG1_INTA          7
#define CONFIG_IRQ_PROG1_INTB          7
#define CONFIG_IRQ_PROG2_INTA          7
#define CONFIG_IRQ_PROG2_INTB          7
#define CONFIG_IRQ_DMA1_WRRD0              7
#define CONFIG_IRQ_DMA1_WRRD1              7
#define CONFIG_IRQ_DMA2_WRRD0              7
 
#define CONFIG_IRQ_DMA2_WRRD1              7
#define CONFIG_IRQ_IMDMA_WRRD0            7
#define CONFIG_IRQ_IMDMA_WRRD1            7
#define CONFIG_IRQ_WDTIMER                     7
下表简要列出了各个中断处理的功能,如无特别说明,其入口均位于arch/blackfin/mach-common/interrupt.s文件中。
中断
入口
功能
EMU
evt_emulation
保存当前各寄存器的值
调用irq_panic输出这些值并终止运行
RST
未处理
 
NMI
evt_evt2
保存寄存器的值
调用asm_do_IRQ(arch/blackfin/mach-kernel/irqchip.c)
恢复寄存器的值并从发生异常的位置继续执行
EVX
trap
此入口代码位于arch/blackfin/mach-common/entry.s。
它将根据SEQSTAT_EXCAUSE寄存器中的异常原因调用_extable中提供的回调函数,在entry.s中定义了64个入口,主要是以下几个处理函数:
ex_syscall:/* 0x00 – Linux系统调用异常 */
ex_soft_bp:/* 0x01 – 软件断点异常 */
ex_trap_c:/* 所有未经特殊处理的异常都将由它处理 */
ex_spinlock:/* 0x04 - User Defined */
ex_single_step:/* 0x10 – 单步执行时中断异常 */
ex_dcplb:/* 0x23 – Data CPLB异常 */
ex_icplb:/* 0x2B - Instruction CPLB异常 */
Reserved
保留
 
IVHW
evt_ivhw
保存当前各寄存器的值
调用irq_panic输出这些值并终止运行
IVTMR
evt_timer
全部跳转到__common_int_entry,在此处保存各寄存器的值,然后调用do_irq,再调用return_from_int,最后恢复各寄存器的值并返回到中断之前的位置继续执行。
IVG7
evt_evt7
IVG8
evt_evt8
IVG9
evt_evt9
IVG10
evt_evt10
IVG11
evt_evt11
IVG12
evt_evt12
IVG13
evt_evt13
IVG14
evt14_softirq
此入口代码位于arch/blackfin/mach-common/entry.s。
它将IMASK保存到R0中,并将IMASK设置为0。然后返回到中断之前的位置继续执行。
IVG15
evt_system_call
保存当前各寄存器的值
调用system_call
恢复各寄存器的值并返回到中断之前的位置继续执行
 

你可能感兴趣的:(uClinux for bf561中的中断处理(1):中断初始化)