summaryrefslogtreecommitdiff
path: root/interrupt/dispatch_clic.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'interrupt/dispatch_clic.cpp')
-rw-r--r--interrupt/dispatch_clic.cpp25
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)");
+}