summaryrefslogtreecommitdiff
path: root/interrupt/dispatch_riscv.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'interrupt/dispatch_riscv.cpp')
-rw-r--r--interrupt/dispatch_riscv.cpp24
1 files changed, 24 insertions, 0 deletions
diff --git a/interrupt/dispatch_riscv.cpp b/interrupt/dispatch_riscv.cpp
new file mode 100644
index 0000000..a91e95a
--- /dev/null
+++ b/interrupt/dispatch_riscv.cpp
@@ -0,0 +1,24 @@
+#include "interrupt.h"
+
+extern interrupt::vector_t vectors_exception[];
+extern interrupt::vector_t vectors_internal[];
+
+[[gnu::interrupt]]
+void riscv_interrupt_handler() {
+ uint32_t cause;
+ asm("csrr %0, mcause" : "=r"(cause));
+
+ uint32_t type = cause & 0x80000000;
+ uint32_t code = cause & 0x7fffffff;
+
+ if(type) {
+ vectors_internal[code]();
+ } else {
+ vectors_exception[code]();
+ }
+}
+
+[[gnu::constructor(200)]]
+void riscv_interrupt_init() {
+ asm volatile("csrw mtvec, %0" :: "r"(riscv_interrupt_handler));
+}