在li的crt0.s 中会定义中断的入口。例如如果是irq中断会调用arm_irq
_start:
b reset
b arm_undefined
b arm_syscall
b arm_prefetch_abort
b arm_data_abort
b arm_reserved
b arm_irq
b arm_fiq
在exception.s 中可见会调用platform_irq
FUNCTION(arm_irq)
/* XXX only deals with interrupting supervisor mode */
/* call into higher level code */
mov r0, sp /* iframe */
bl platform_irq
cmp r0, #0
blne thread_preempt
在Interrupts.c 中可以看platform_irq的实现
enum handler_return platform_irq(struct arm_iframe *frame)
{
// get the current vector
unsigned int vector = *REG32(PIC_CURRENT_NUM);
if (vector == 0xffffffff)
return INT_NO_RESCHEDULE;
// dprintf("platform_irq: spsr 0x%x, pc 0x%x, currthread %p, vector %d\n", frame->spsr, frame->pc, current_thread, vector);
// deliver the interrupt
enum handler_return ret;
ret = INT_NO_RESCHEDULE;
if (int_handler_table[vector].handler)
ret = int_handler_table[vector].handler(int_handler_table[vector].arg);
// dprintf("platform_irq: exit %d\n", ret);
return ret;
}
首先读取寄存器得到当前的irq number vector
然后看看init_handler_table中这个vector 中是否有对应的callbac
如果有的话,就调用这个callback
当platform_irq 返回是会根据当前的返回值来决定是否要进行
thread 切换
而handler中的callback 是调用register_int_handler 来添加的
void register_int_handler(unsigned int vector, int_handler handler, void *arg)
{
if (vector >= PIC_MAX_INT)
panic("register_int_handler: vector out of range %d\n", vector);
enter_critical_section();
int_handler_table[vector].handler = handler;
int_handler_table[vector].arg = arg;
exit_critical_section();
}
例如timer的中断处理函数就是platform_tick
void platform_init_timer(void)
{
register_int_handler(INT_PIT, &platform_tick, NULL);
}
_start:
b reset
b arm_undefined
b arm_syscall
b arm_prefetch_abort
b arm_data_abort
b arm_reserved
b arm_irq
b arm_fiq
在exception.s 中可见会调用platform_irq
FUNCTION(arm_irq)
/* XXX only deals with interrupting supervisor mode */
/* call into higher level code */
mov r0, sp /* iframe */
bl platform_irq
cmp r0, #0
blne thread_preempt
在Interrupts.c 中可以看platform_irq的实现
enum handler_return platform_irq(struct arm_iframe *frame)
{
// get the current vector
unsigned int vector = *REG32(PIC_CURRENT_NUM);
if (vector == 0xffffffff)
return INT_NO_RESCHEDULE;
// dprintf("platform_irq: spsr 0x%x, pc 0x%x, currthread %p, vector %d\n", frame->spsr, frame->pc, current_thread, vector);
// deliver the interrupt
enum handler_return ret;
ret = INT_NO_RESCHEDULE;
if (int_handler_table[vector].handler)
ret = int_handler_table[vector].handler(int_handler_table[vector].arg);
// dprintf("platform_irq: exit %d\n", ret);
return ret;
}
首先读取寄存器得到当前的irq number vector
然后看看init_handler_table中这个vector 中是否有对应的callbac
如果有的话,就调用这个callback
当platform_irq 返回是会根据当前的返回值来决定是否要进行
thread 切换
而handler中的callback 是调用register_int_handler 来添加的
void register_int_handler(unsigned int vector, int_handler handler, void *arg)
{
if (vector >= PIC_MAX_INT)
panic("register_int_handler: vector out of range %d\n", vector);
enter_critical_section();
int_handler_table[vector].handler = handler;
int_handler_table[vector].arg = arg;
exit_critical_section();
}
例如timer的中断处理函数就是platform_tick
void platform_init_timer(void)
{
register_int_handler(INT_PIT, &platform_tick, NULL);
}