From cd3468cde5987ccfea4516ba5aabf18beb64641b Mon Sep 17 00:00:00 2001 From: Zihao Yu Date: Sun, 15 Sep 2019 15:21:10 +0800 Subject: [PATCH] riscv64,clint: add machine timer interrupt * fix the cause number, the interrupt bit should set with 0x8000000000000000, instead of 0x80000000 --- src/device/device.c | 5 +++++ src/isa/riscv64/clint.c | 12 ++++++++++++ src/isa/riscv64/exec/system.c | 2 +- src/isa/riscv64/intr.c | 21 +++++++++++++++------ 4 files changed, 33 insertions(+), 7 deletions(-) diff --git a/src/device/device.c b/src/device/device.c index b02d06c3..eeb738ba 100644 --- a/src/device/device.c +++ b/src/device/device.c @@ -23,6 +23,11 @@ void send_key(uint8_t, bool); static void timer_sig_handler(int signum) { timer_intr(); +#ifdef __ISA_riscv64__ + extern void clint_intr(void); + clint_intr(); +#endif + device_update_flag = true; int ret = setitimer(ITIMER_VIRTUAL, &it, NULL); diff --git a/src/isa/riscv64/clint.c b/src/isa/riscv64/clint.c index b402a8bc..ebf0d1e3 100644 --- a/src/isa/riscv64/clint.c +++ b/src/isa/riscv64/clint.c @@ -2,9 +2,21 @@ #include "device/map.h" #define CLINT_MMIO 0x2000000 +#define CLINT_MTIMECMP (0x4000 / sizeof(clint_base[0])) +#define CLINT_MTIME (0xBFF8 / sizeof(clint_base[0])) static uint64_t *clint_base = NULL; +void clint_intr(void) { + if (nemu_state.state == NEMU_RUNNING) { + clint_base[CLINT_MTIME] += 0x800; + } +} + +bool clint_query_intr(void) { + return clint_base[CLINT_MTIME] >= clint_base[CLINT_MTIMECMP]; +} + void init_clint(void) { clint_base = (void *)new_space(0x10000); add_mmio_map("clint", CLINT_MMIO, (void *)clint_base, 0x10000, NULL); diff --git a/src/isa/riscv64/exec/system.c b/src/isa/riscv64/exec/system.c index adb7549d..764433e1 100644 --- a/src/isa/riscv64/exec/system.c +++ b/src/isa/riscv64/exec/system.c @@ -34,7 +34,7 @@ make_EHelper(csrrc) { print_asm_template3("csrrc"); } -extern void raise_intr(uint32_t NO, vaddr_t epc); +extern void raise_intr(word_t NO, vaddr_t epc); make_EHelper(priv) { uint32_t type = decinfo.isa.instr.csr; diff --git a/src/isa/riscv64/intr.c b/src/isa/riscv64/intr.c index 288bff55..b6feec80 100644 --- a/src/isa/riscv64/intr.c +++ b/src/isa/riscv64/intr.c @@ -1,7 +1,9 @@ #include "rtl/rtl.h" #include "csr.h" -void raise_intr(uint32_t NO, vaddr_t epc) { +#define INTR_BIT (1ULL << 63) + +void raise_intr(word_t NO, vaddr_t epc) { /* TODO: Trigger an interrupt/exception with ``NO''. * That is, use ``NO'' to index the IDT. */ @@ -15,11 +17,18 @@ void raise_intr(uint32_t NO, vaddr_t epc) { } bool isa_query_intr(void) { - if (cpu.INTR && mstatus->mie) { - cpu.INTR = false; - // machine external interrupt - raise_intr(0x8000000b, cpu.pc); - return true; + extern bool clint_query_intr(void); + if (mstatus->mie) { + //if (cpu.INTR) { + // cpu.INTR = false; + // // machine external interrupt + // raise_intr(0xb | INTR_BIT, cpu.pc); + //} + if (clint_query_intr() && mie->mtie) { + // machine timer interrupt + raise_intr(0x7 | INTR_BIT, cpu.pc); + return true; + } } return false; } -- GitLab