diff options
Diffstat (limited to 'interrupt/dispatch_clic.cpp')
-rw-r--r-- | interrupt/dispatch_clic.cpp | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/interrupt/dispatch_clic.cpp b/interrupt/dispatch_clic.cpp new file mode 100644 index 0000000..64e4bfc --- /dev/null +++ b/interrupt/dispatch_clic.cpp @@ -0,0 +1,25 @@ +#include "interrupt.h" + +extern interrupt::vector_t vectors_exception[]; +extern interrupt::vector_t vectors_clic[]; + +[[gnu::interrupt, gnu::aligned(64)]] +void riscv_interrupt_handler() { + uint32_t cause; + asm("csrr %0, mcause" : "=r"(cause)); + + uint32_t type = cause & 0x80000000; + uint32_t code = cause & 0x00000fff; + + if(type) { + vectors_clic[code](); + } else { + vectors_exception[code](); + } +} + +[[gnu::constructor(200)]] +void riscv_interrupt_init() { + asm volatile("csrw mtvec, %0" :: "r"(intptr_t(riscv_interrupt_handler) | 3)); + asm volatile("csrrsi x0, mstatus, (1 << 3)"); +} |