aboutsummaryrefslogtreecommitdiff
path: root/arch/riscv64/kernel
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2023-07-31 22:24:29 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2023-07-31 22:24:29 +0300
commit6ad1b899ed93f8bc110cdec7a722c8740f9f8d66 (patch)
tree99fe36028ffc4583c59e77d03bea2ade7a6c5ace /arch/riscv64/kernel
parent3212707a9ab549119ad0ad6441a07fe774c99f3b (diff)
downloadkmi-6ad1b899ed93f8bc110cdec7a722c8740f9f8d66.tar.gz
kmi-6ad1b899ed93f8bc110cdec7a722c8740f9f8d66.zip
start working on irqs
Diffstat (limited to 'arch/riscv64/kernel')
-rw-r--r--arch/riscv64/kernel/entry.S22
-rw-r--r--arch/riscv64/kernel/irq.c66
2 files changed, 69 insertions, 19 deletions
diff --git a/arch/riscv64/kernel/entry.S b/arch/riscv64/kernel/entry.S
index 9d4d951..698dae7 100644
--- a/arch/riscv64/kernel/entry.S
+++ b/arch/riscv64/kernel/entry.S
@@ -62,15 +62,18 @@
sr t4, offsetof_t4(sp)
.endm
-.global handle_irq
-handle_irq:
+.global handle_trap
+handle_trap:
csrrw tp, CSR_SSCRATCH, tp
- bnez tp, continue_irq
- /* the exception came from the kernel, should probably handle but for
- * now just spin in place */
- 1: j 1b
+ bnez tp, continue_trap
+ /* the trap came from the kernel, should never happen so just panic
+ * and abort or whatever */
+ csrr a0, CSR_SEPC
+ csrr a1, CSR_STVAL
+ csrr a2, CSR_SCAUSE
+ call kernel_panic
-continue_irq:
+continue_trap:
sr sp, offsetof_tcbd(tp)
lr sp, offsetof_regs(tp)
addi sp, sp, -sizeof_registers
@@ -88,12 +91,15 @@ continue_irq:
/* load supervisor cause */
csrr t5, CSR_SCAUSE
/* interrupts fall through, exceptions jump */
+ /* (leading 1 means the value is interpreted as negative) */
bge t5, zero, handle_exception
save_regs
save_args
- /* TODO: handle interrupts */
+ mv t5, a0
+ call riscv_handle_interrupt
+
j _load_context
handle_exception:
diff --git a/arch/riscv64/kernel/irq.c b/arch/riscv64/kernel/irq.c
index 698a834..964401f 100644
--- a/arch/riscv64/kernel/irq.c
+++ b/arch/riscv64/kernel/irq.c
@@ -8,34 +8,78 @@
#include <kmi/attrs.h>
#include <kmi/debug.h>
-#include <arch/irq.h>
+#include <kmi/timer.h>
+#include <kmi/ipi.h>
+#include <kmi/irq.h>
#include "csr.h"
/** Defined in arch/riscv64/kernel/entry.S. */
-extern void handle_irq();
+extern void handle_trap();
-/** Called from arch/riscv64/kernel/entry.S. */
-void handle_sys_irq()
-{
-}
-
-void init_irq(void *fdt)
+void setup_irq(void *fdt)
{
UNUSED(fdt);
- csr_write(CSR_STVEC, &handle_irq);
+ csr_write(CSR_STVEC, &handle_trap);
long s = 0;
csr_read(CSR_SIE, s);
info("CSR_SIE: %lx\n", s);
}
+stat_t activate_irq(irq_t id)
+{
+ /** @todo implement plic */
+ return OK;
+}
+
+stat_t deactivate_irq(irq_t id)
+{
+ /** @todo implement plic */
+ return OK;
+}
+
/* very simple for now */
-void enable_irq()
+void enable_irqs()
{
csr_set(CSR_SSTATUS, CSR_SIE);
}
-void disable_irq()
+void disable_irqs()
{
csr_clear(CSR_SSTATUS, CSR_SIE);
}
+
+irq_t get_irq()
+{
+ /** @todo implement */
+ return 0;
+}
+
+/**
+ * Prints out a bug message about unknown interrupt cause.
+ *
+ * @param id ID of interrupt.
+ */
+static void riscv_unknown_interrupt(long id)
+{
+ bug("unknown interrupt: %llu\n", (unsigned long long)id);
+}
+
+/**
+ * Handle RISCV interrupt.
+ * Branches out to correct interrupt handler.
+ *
+ * @param id ID of interrupt, with interrupt bit still set.
+ */
+void riscv_handle_interrupt(long id)
+{
+ id = -id;
+
+ switch (id) {
+ /* I think */
+ case 1: handle_ipi(); break;
+ case 5: handle_timer(); break;
+ case 9: handle_irq(); break;
+ default: riscv_unknown_interrupt(id); break;
+ }
+}