#include "hwtimer.h" #include "riscv-traps.h" #include #include #include #include #if __riscv_xlen == 64 #define INTERRUPT_BIT 0x8000000000000000ull #else #define INTERRUPT_BIT 0x80000000ull #endif #define OS_IS_INTERRUPT(mcause) (mcause & INTERRUPT_BIT) #define OS_IS_TICK_INT(mcause) (mcause == (0x7 | INTERRUPT_BIT)) #define OS_IS_SOFT_INT(mcause) (mcause == (0x3 | INTERRUPT_BIT)) #define OS_IS_EXT_INT(mcause) (mcause == (0xb | INTERRUPT_BIT)) extern void _tx_timer_interrupt(void); extern uintptr_t exception(uintptr_t mcause, uintptr_t mepc, uintptr_t mtval); void (*irq_handler[__riscv_xlen])(); int register_irq_handler(unsigned irq_num, void (*handler)()) { if(irq_num<__riscv_xlen){ irq_handler[irq_num] = handler; return 1; } return 0; } void trap_handler(uintptr_t mcause, uintptr_t mepc, uintptr_t mtval) { if(OS_IS_INTERRUPT(mcause)) { unsigned irq_id = mcause&(__riscv_xlen-1); switch(irq_id){ case RISCV_INT_MTI: #ifdef NX_DEBUG printf("Timer interrupt being handled (pc=%lx)\n", mepc); #endif hwtimer_handler(); _tx_timer_interrupt(); break; case RISCV_INT_MEI: puts("[INTERRUPT]: handler ext irq error!\n"); while(1) ; break; default: if(irq_handler[irq_id]) irq_handler[irq_id](); else { printf("[INTERRUPT]: Unkown Interrupt %d!!\n", mcause&0xff); puts("[INTERRUPT]: now can't deal with the interrupt!\n"); while(1) ; } } } else { exception( mcause, mepc, mtval); } }