From: Andrew Waterman Date: Sun, 5 Jul 2015 23:47:20 +0000 (-0700) Subject: New machine-mode timer facility X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=48faf847c28cebfe864c543498a9aaff2feb0fd3;p=riscv-isa-sim.git New machine-mode timer facility --- diff --git a/riscv/encoding.h b/riscv/encoding.h index a95f463..f9f4bfb 100644 --- a/riscv/encoding.h +++ b/riscv/encoding.h @@ -567,7 +567,6 @@ #define CSR_SSTATUS 0x100 #define CSR_STVEC 0x101 #define CSR_SIE 0x104 -#define CSR_STIMECMP 0x121 #define CSR_SSCRATCH 0x140 #define CSR_SEPC 0x141 #define CSR_SIP 0x144 @@ -606,6 +605,7 @@ #define CSR_INSTRETHW 0x982 #define CSR_STIMEH 0xd81 #define CSR_STIMEHW 0xa81 +#define CSR_MTIMECMPH 0x361 #define CSR_MTIMEH 0x741 #define CAUSE_MISALIGNED_FETCH 0x0 #define CAUSE_FAULT_FETCH 0x1 @@ -840,7 +840,6 @@ DECLARE_CSR(uarch15, CSR_UARCH15) DECLARE_CSR(sstatus, CSR_SSTATUS) DECLARE_CSR(stvec, CSR_STVEC) DECLARE_CSR(sie, CSR_SIE) -DECLARE_CSR(stimecmp, CSR_STIMECMP) DECLARE_CSR(sscratch, CSR_SSCRATCH) DECLARE_CSR(sepc, CSR_SEPC) DECLARE_CSR(sip, CSR_SIP) @@ -879,6 +878,7 @@ DECLARE_CSR(timehw, CSR_TIMEHW) DECLARE_CSR(instrethw, CSR_INSTRETHW) DECLARE_CSR(stimeh, CSR_STIMEH) DECLARE_CSR(stimehw, CSR_STIMEHW) +DECLARE_CSR(mtimecmph, CSR_MTIMECMPH) DECLARE_CSR(mtimeh, CSR_MTIMEH) #endif #ifdef DECLARE_CAUSE @@ -908,7 +908,6 @@ DECLARE_CAUSE("uarch15", CAUSE_UARCH15) DECLARE_CAUSE("sstatus", CAUSE_SSTATUS) DECLARE_CAUSE("stvec", CAUSE_STVEC) DECLARE_CAUSE("sie", CAUSE_SIE) -DECLARE_CAUSE("stimecmp", CAUSE_STIMECMP) DECLARE_CAUSE("sscratch", CAUSE_SSCRATCH) DECLARE_CAUSE("sepc", CAUSE_SEPC) DECLARE_CAUSE("sip", CAUSE_SIP) @@ -947,5 +946,6 @@ DECLARE_CAUSE("timehw", CAUSE_TIMEHW) DECLARE_CAUSE("instrethw", CAUSE_INSTRETHW) DECLARE_CAUSE("stimeh", CAUSE_STIMEH) DECLARE_CAUSE("stimehw", CAUSE_STIMEHW) +DECLARE_CAUSE("mtimecmph", CAUSE_MTIMECMPH) DECLARE_CAUSE("mtimeh", CAUSE_MTIMEH) #endif diff --git a/riscv/processor.cc b/riscv/processor.cc index cf6790a..69a63f0 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -151,6 +151,9 @@ void processor_t::take_interrupt() if (interrupts & MIP_MSIP) raise_interrupt(IRQ_SOFT); + if (interrupts & MIP_MTIP) + raise_interrupt(IRQ_TIMER); + if (state.fromhost != 0) raise_interrupt(IRQ_HOST); } @@ -204,11 +207,8 @@ static reg_t execute_insn(processor_t* p, reg_t pc, insn_fetch_t fetch) void processor_t::check_timer() { - // this assumes the rtc doesn't change asynchronously during step(), - if (state.stimecmp >= (uint32_t)state.prev_rtc - && state.stimecmp < (uint32_t)sim->rtc) - state.mip |= MIP_STIP; - state.prev_rtc = sim->rtc; + if (sim->rtc >= state.mtimecmp) + state.mip |= MIP_MTIP; } void processor_t::step(size_t n) @@ -427,12 +427,12 @@ void processor_t::set_csr(int which, reg_t val) break; } case CSR_MIP: { - reg_t mask = MIP_SSIP | MIP_MSIP; + reg_t mask = MIP_SSIP | MIP_MSIP | MIP_STIP; state.mip = (state.mip & ~mask) | (val & mask); break; } case CSR_MIE: { - reg_t mask = MIP_SSIP | MIP_MSIP | MIP_STIP; + reg_t mask = MIP_SSIP | MIP_MSIP | MIP_STIP | MIP_MTIP; state.mie = (state.mie & ~mask) | (val & mask); break; } @@ -458,16 +458,16 @@ void processor_t::set_csr(int which, reg_t val) } case CSR_SEPC: state.sepc = val; break; case CSR_STVEC: state.stvec = val & ~3; break; - case CSR_STIMECMP: - state.mip &= ~MIP_STIP; - state.stimecmp = val; - break; case CSR_SPTBR: state.sptbr = zext_xlen(val & -PGSIZE); break; case CSR_SSCRATCH: state.sscratch = val; break; case CSR_MEPC: state.mepc = val; break; case CSR_MSCRATCH: state.mscratch = val; break; case CSR_MCAUSE: state.mcause = val; break; case CSR_MBADADDR: state.mbadaddr = val; break; + case CSR_MTIMECMP: + state.mip &= ~MIP_MTIP; + state.mtimecmp = val; + break; case CSR_SEND_IPI: sim->send_ipi(val); break; case CSR_MTOHOST: if (state.tohost == 0) @@ -541,7 +541,6 @@ reg_t processor_t::get_csr(int which) case CSR_SEPC: return state.sepc; case CSR_SBADADDR: return state.sbadaddr; case CSR_STVEC: return state.stvec; - case CSR_STIMECMP: return state.stimecmp; case CSR_SCAUSE: if (max_xlen > xlen) return state.scause | ((state.scause >> (max_xlen-1)) << (xlen-1)); @@ -556,6 +555,7 @@ reg_t processor_t::get_csr(int which) case CSR_MSCRATCH: return state.mscratch; case CSR_MCAUSE: return state.mcause; case CSR_MBADADDR: return state.mbadaddr; + case CSR_MTIMECMP: return state.mtimecmp; case CSR_MCPUID: return cpuid; case CSR_MIMPID: return IMPL_ROCKET; case CSR_MHARTID: return id; diff --git a/riscv/processor.h b/riscv/processor.h index 134c0a1..6af7887 100644 --- a/riscv/processor.h +++ b/riscv/processor.h @@ -43,6 +43,7 @@ struct state_t reg_t mstatus; reg_t mepc; reg_t mbadaddr; + reg_t mtimecmp; reg_t mscratch; reg_t mcause; reg_t minstret; @@ -58,8 +59,6 @@ struct state_t reg_t suinstret_delta; reg_t tohost; reg_t fromhost; - reg_t prev_rtc; - uint32_t stimecmp; uint32_t fflags; uint32_t frm; bool serialized; // whether timer CSRs are in a well-defined state