diff options
| author | Kimplul <kimi.h.kuparinen@gmail.com> | 2023-07-31 22:24:29 +0300 |
|---|---|---|
| committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2023-07-31 22:24:29 +0300 |
| commit | 6ad1b899ed93f8bc110cdec7a722c8740f9f8d66 (patch) | |
| tree | 99fe36028ffc4583c59e77d03bea2ade7a6c5ace /arch | |
| parent | 3212707a9ab549119ad0ad6441a07fe774c99f3b (diff) | |
| download | kmi-6ad1b899ed93f8bc110cdec7a722c8740f9f8d66.tar.gz kmi-6ad1b899ed93f8bc110cdec7a722c8740f9f8d66.zip | |
start working on irqs
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/riscv64/kernel/entry.S | 22 | ||||
| -rw-r--r-- | arch/riscv64/kernel/irq.c | 66 |
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; + } +} |
