|
@@ -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,12 +185,19 @@ 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)
|