diff --git a/src/arch/riscv/isa.cc b/src/arch/riscv/isa.cc index bda6b4581a..6dc0d01f05 100644 --- a/src/arch/riscv/isa.cc +++ b/src/arch/riscv/isa.cc @@ -47,6 +47,7 @@ #include "base/compiler.hh" #include "base/logging.hh" #include "base/trace.hh" +#include "base/types.hh" #include "cpu/base.hh" #include "debug/Checkpoint.hh" #include "debug/FloatRegs.hh" @@ -352,21 +353,21 @@ ISA::hpmCounterEnabled(int misc_reg) const int hpmcounter = misc_reg - MISCREG_CYCLE; if (hpmcounter < 0 || hpmcounter > 31) panic("Illegal HPM counter %d\n", hpmcounter); - int counteren; + RegVal counteren; switch (readMiscRegNoEffect(MISCREG_PRV)) { case PRV_M: return true; case PRV_S: - counteren = MISCREG_MCOUNTEREN; + counteren = miscRegFile[MISCREG_MCOUNTEREN]; break; case PRV_U: - counteren = MISCREG_SCOUNTEREN; + counteren = miscRegFile[MISCREG_SCOUNTEREN] & miscRegFile[MISCREG_MCOUNTEREN]; break; default: panic("Unknown privilege level %d\n", miscRegFile[MISCREG_PRV]); return false; } - return (miscRegFile[counteren] & (1ULL << (hpmcounter))) > 0; + return (counteren & (1ULL << (hpmcounter))) > 0; } RegVal @@ -571,14 +572,6 @@ ISA::setMiscReg(int misc_reg, RegVal val) } } else if ((v == 1) && (misc_reg == MISCREG_SEPC)) { setMiscRegNoEffect(MISCREG_VSEPC, val); - } else if (misc_reg == MISCREG_HCOUNTEREN) { - auto hcounter = readMiscRegNoEffect(MISCREG_HCOUNTEREN); - RegVal write_val = ((hcounter & ~(NEMU_COUNTER_MASK)) | (val & NEMU_COUNTER_MASK)); - setMiscRegNoEffect(MISCREG_HCOUNTEREN, write_val); - } else if (misc_reg == MISCREG_SCOUNTEREN) { - auto scounter = readMiscRegNoEffect(MISCREG_SCOUNTEREN); - RegVal write_val = ((scounter & ~(NEMU_COUNTER_MASK)) | (val & NEMU_COUNTER_MASK)); - setMiscRegNoEffect(MISCREG_SCOUNTEREN, write_val); } else if ((v == 1) && ((misc_reg == MISCREG_STVEC))) { setMiscRegNoEffect(MISCREG_VSTVEC, val & ~(0x2UL)); } else { @@ -620,6 +613,16 @@ ISA::setMiscReg(int misc_reg, RegVal val) setMiscRegNoEffect(misc_reg, val); } break; + case MISCREG_MCOUNTEREN: + case MISCREG_SCOUNTEREN: + case MISCREG_HCOUNTEREN: + { + auto xcounter = readMiscRegNoEffect(misc_reg); + // The lower 32 bits are writable + RegVal write_val = ((xcounter & ~(NEMU_COUNTER_MASK)) | (val & NEMU_COUNTER_MASK)); + setMiscRegNoEffect(misc_reg, write_val); + } + break; case MISCREG_PMPADDR00 ... MISCREG_PMPADDR15: { // PMP registers should only be modified in M mode diff --git a/src/arch/riscv/regs/misc.hh b/src/arch/riscv/regs/misc.hh index 759bfa0ac1..410f83af13 100644 --- a/src/arch/riscv/regs/misc.hh +++ b/src/arch/riscv/regs/misc.hh @@ -880,7 +880,7 @@ const uint64_t NEMU_SATP_MASK = NEMU_SATP_MODE_MASK |NEMU_SATP_ASID_MASK | NEMU_ const uint64_t NEMU_SSTATUS_WMASK = ((1 << 19) | (1 << 18) | (0x3 << 13) | (1 << 8) | (1 << 5) | (1 << 1) |(0x3 <<9)); const uint64_t NEMU_SSTATUS_RMASK = 0x80000003000de762UL; -const uint64_t NEMU_COUNTER_MASK = 0; +const uint64_t NEMU_COUNTER_MASK = 0xffffffffULL; const uint64_t NEMU_VS_MASK = ((1 << 10) | (1 << 6) | (1 << 2)); const uint64_t NEMU_HS_MASK = ((1 << 12) | NEMU_VS_MASK);