diff --git a/lib/CPUs/MIPS/bsp/examples/xcpt.c b/lib/CPUs/MIPS/bsp/examples/xcpt.c index 5b71693..a6eca43 100644 --- a/lib/CPUs/MIPS/bsp/examples/xcpt.c +++ b/lib/CPUs/MIPS/bsp/examples/xcpt.c @@ -7,7 +7,9 @@ #include "xcpt.h" #include "irq.h" -char *_xcpt_code_str[32] = +static fp_xcpt_t g_xcpt_handler[MAX_NUM_XCPT] = {NULL}; + +char *_xcpt_code_str[MAX_NUM_XCPT] = { "Int", "Mod", "TLBL", "TLBS", "AdEL", "AdES", "IBE", "DBE", "Sys", "Bp", "RI", "CpU", "Ov", "Tr", "NCD/VCEI", "MC/FPE", @@ -15,22 +17,20 @@ char *_xcpt_code_str[32] = "Res(24)", "Res(25)", "Res(26)", "Res(27)", "Res(28)", "Res(29)", "Res(30)", "VCED" }; -#define PRINT_REG(tag_str, reg) \ - sputs(tag_str); \ - print_word(reg); \ - sputs(" "); - -int _xcpt_default_dispatch(struct xcptcontext * xcp) +void xcpt_register(int xcpt_num, fp_xcpt_t fp) { - return 1; + if ((xcpt_num >= Mod) && (xcpt_num <= VCED)) + g_xcpt_handler[xcpt_num] = fp; + } int _xcpt_dispatch(struct xcptcontext * xcp) { - int xcpt_code, result; + int xcpt_code, result, i; xcpt_code = ((0xFF & xcp->cr) >> 2); + result = XCPT_ERR_NOTHANDLED; switch(xcpt_code) { case Int: @@ -38,10 +38,12 @@ int _xcpt_dispatch(struct xcptcontext * xcp) break; default: - result = _xcpt_default_dispatch(xcp); + if (g_xcpt_handler[xcpt_code]) + { + result = (g_xcpt_handler[xcpt_code])(xcp); + } break; } - return result; } @@ -52,7 +54,7 @@ int _xcpt_deliver(struct xcptcontext * _xcp) volatile int *pInstr; /* This function gets called by the low-level exception handler. */ - if (_xcpt_dispatch(_xcp)) + if (_xcpt_dispatch(_xcp) == XCPT_ERR_NOTHANDLED) { sputs("\n"); PRINT_REG(" Status : ", _xcp->sr); diff --git a/lib/CPUs/MIPS/bsp/examples/xcpt.h b/lib/CPUs/MIPS/bsp/examples/xcpt.h index 8b42ace..7ffde6e 100644 --- a/lib/CPUs/MIPS/bsp/examples/xcpt.h +++ b/lib/CPUs/MIPS/bsp/examples/xcpt.h @@ -1,6 +1,9 @@ #ifndef XCPT_H #define XCPT_H +#define MAX_NUM_XCPT 32 +#define XCPT_ERR_NOTHANDLED 0x80000000 + typedef enum { Int = 0, Mod = 1, TLBL = 2, TLBS = 3, AdEL = 4, AdES = 5, @@ -31,4 +34,16 @@ typedef struct xcptcontext } EXCEPTION_CONTEXT; +typedef int (*fp_xcpt_t)(struct xcptcontext * xcp); + +#define PRINT_REG(tag_str, reg) \ + sputs(tag_str); \ + print_word(reg); \ + sputs(" "); + + + +// Public functions +void xcpt_register(int xcpt_num, fp_xcpt_t fp); + #endif // XCPT_H