diff options
| author | guozhanxin <[email protected]> | 2021-07-12 10:14:20 +0800 |
|---|---|---|
| committer | guozhanxin <[email protected]> | 2021-07-12 10:14:20 +0800 |
| commit | 40e7d5a23df65c15bb7db53fe5f77e76701fd20d (patch) | |
| tree | 4973b28b01d289dd596a097a7560f26b810db771 /libcpu/arm/cortex-a/trap.c | |
| parent | ddc5c793a482fe44310bafe181802ad406fa1b29 (diff) | |
| parent | 5bae565f7f021ab13113fc0a9c67fc468d97de02 (diff) | |
Merge remote-tracking branch 'remotes/gitee/master'
Diffstat (limited to 'libcpu/arm/cortex-a/trap.c')
| -rw-r--r-- | libcpu/arm/cortex-a/trap.c | 94 |
1 files changed, 72 insertions, 22 deletions
diff --git a/libcpu/arm/cortex-a/trap.c b/libcpu/arm/cortex-a/trap.c index 3faa136677..b3efe31a64 100644 --- a/libcpu/arm/cortex-a/trap.c +++ b/libcpu/arm/cortex-a/trap.c @@ -35,6 +35,18 @@ void rt_hw_show_register(struct rt_hw_exp_stack *regs) rt_kprintf("cpsr:0x%08x\n", regs->cpsr); } +void (*rt_trap_hook)(struct rt_hw_exp_stack *regs, const char *ex, unsigned int exception_type); + +/** + * This function will set a hook function to trap handler. + * + * @param hook the hook function + */ +void rt_hw_trap_set_hook(void (*hook)(struct rt_hw_exp_stack *regs, const char *ex, unsigned int exception_type)) +{ + rt_trap_hook = hook; +} + /** * When comes across an instruction which it cannot handle, * it takes the undefined instruction trap. @@ -72,12 +84,20 @@ void rt_hw_trap_undef(struct rt_hw_exp_stack *regs) } } #endif - rt_kprintf("undefined instruction:\n"); - rt_hw_show_register(regs); + + if (rt_trap_hook == RT_NULL) + { + rt_kprintf("undefined instruction:\n"); + rt_hw_show_register(regs); #ifdef RT_USING_FINSH - list_thread(); + list_thread(); #endif - rt_hw_cpu_shutdown(); + rt_hw_cpu_shutdown(); + } + else + { + rt_trap_hook(regs, "undefined instruction", UND_EXCEPTION); + } } /** @@ -91,12 +111,19 @@ void rt_hw_trap_undef(struct rt_hw_exp_stack *regs) */ void rt_hw_trap_swi(struct rt_hw_exp_stack *regs) { - rt_kprintf("software interrupt:\n"); - rt_hw_show_register(regs); + if (rt_trap_hook == RT_NULL) + { + rt_kprintf("software interrupt:\n"); + rt_hw_show_register(regs); #ifdef RT_USING_FINSH - list_thread(); + list_thread(); #endif - rt_hw_cpu_shutdown(); + rt_hw_cpu_shutdown(); + } + else + { + rt_trap_hook(regs, "software instruction", SWI_EXCEPTION); + } } /** @@ -109,12 +136,19 @@ void rt_hw_trap_swi(struct rt_hw_exp_stack *regs) */ void rt_hw_trap_pabt(struct rt_hw_exp_stack *regs) { - rt_kprintf("prefetch abort:\n"); - rt_hw_show_register(regs); + if (rt_trap_hook == RT_NULL) + { + rt_kprintf("prefetch abort:\n"); + rt_hw_show_register(regs); #ifdef RT_USING_FINSH - list_thread(); + list_thread(); #endif - rt_hw_cpu_shutdown(); + rt_hw_cpu_shutdown(); + } + else + { + rt_trap_hook(regs, "prefetch abort", PABT_EXCEPTION); + } } /** @@ -127,12 +161,19 @@ void rt_hw_trap_pabt(struct rt_hw_exp_stack *regs) */ void rt_hw_trap_dabt(struct rt_hw_exp_stack *regs) { - rt_kprintf("data abort:"); - rt_hw_show_register(regs); + if (rt_trap_hook == RT_NULL) + { + rt_kprintf("data abort:"); + rt_hw_show_register(regs); #ifdef RT_USING_FINSH - list_thread(); + list_thread(); #endif - rt_hw_cpu_shutdown(); + rt_hw_cpu_shutdown(); + } + else + { + rt_trap_hook(regs, "data abort", DABT_EXCEPTION); + } } /** @@ -144,23 +185,32 @@ void rt_hw_trap_dabt(struct rt_hw_exp_stack *regs) */ void rt_hw_trap_resv(struct rt_hw_exp_stack *regs) { - rt_kprintf("reserved trap:\n"); - rt_hw_show_register(regs); + if (rt_trap_hook == RT_NULL) + { + rt_kprintf("reserved trap:\n"); + rt_hw_show_register(regs); #ifdef RT_USING_FINSH - list_thread(); + list_thread(); #endif - rt_hw_cpu_shutdown(); + rt_hw_cpu_shutdown(); + } + else + { + rt_trap_hook(regs, "reserved trap", RESV_EXCEPTION); + } } void rt_hw_trap_irq(void) { void *param; + int int_ack; int ir; rt_isr_handler_t isr_func; extern struct rt_irq_desc isr_table[]; - ir = rt_hw_interrupt_get_irq(); + int_ack = rt_hw_interrupt_get_irq(); + ir = int_ack & GIC_ACK_INTID_MASK; if (ir == 1023) { /* Spurious interrupt */ @@ -181,7 +231,7 @@ void rt_hw_trap_irq(void) } /* end of interrupt */ - rt_hw_interrupt_ack(ir); + rt_hw_interrupt_ack(int_ack); } void rt_hw_trap_fiq(void) |
