From 5e1d0059353a4756740df709f85c35ee86138ad6 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Wed, 17 Aug 2016 14:00:58 -0700 Subject: [PATCH] Allow mstatus.MPP to store bad values; instead, validate on MRET Either approach is legal, but this more closely matches Rocket. --- riscv/insns/dret.h | 5 +---- riscv/processor.cc | 13 ++++--------- riscv/processor.h | 1 - 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/riscv/insns/dret.h b/riscv/insns/dret.h index bef9ef2..35c19cb 100644 --- a/riscv/insns/dret.h +++ b/riscv/insns/dret.h @@ -1,9 +1,6 @@ require_privilege(PRV_M); set_pc_and_serialize(STATE.dpc); -/* The debug spec says we can't crash when prv is set to an invalid value. */ -if (p->validate_priv(STATE.dcsr.prv)) { - p->set_privilege(STATE.dcsr.prv); -} +p->set_privilege(STATE.dcsr.prv); /* We're not in Debug Mode anymore. */ STATE.dcsr.cause = 0; diff --git a/riscv/processor.cc b/riscv/processor.cc index 3576af3..0a7912b 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -179,14 +179,11 @@ void processor_t::take_interrupt() raise_interrupt(ctz(enabled_interrupts)); } -bool processor_t::validate_priv(reg_t priv) -{ - return priv == PRV_U || priv == PRV_S || priv == PRV_M; -} - void processor_t::set_privilege(reg_t prv) { - assert(validate_priv(prv)); + assert(prv <= PRV_M); + if (prv == PRV_H) + prv = PRV_U; mmu->flush_tlb(); state.prv = prv; } @@ -311,12 +308,10 @@ void processor_t::set_csr(int which, reg_t val) reg_t mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE | MSTATUS_SPP | MSTATUS_FS | MSTATUS_MPRV | MSTATUS_PUM - | MSTATUS_MXR | (ext ? MSTATUS_XS : 0); + | MSTATUS_MPP | MSTATUS_MXR | (ext ? MSTATUS_XS : 0); if (validate_vm(max_xlen, get_field(val, MSTATUS_VM))) mask |= MSTATUS_VM; - if (validate_priv(get_field(val, MSTATUS_MPP))) - mask |= MSTATUS_MPP; state.mstatus = (state.mstatus & ~mask) | (val & mask); diff --git a/riscv/processor.h b/riscv/processor.h index 4d0d5ab..090ebe7 100644 --- a/riscv/processor.h +++ b/riscv/processor.h @@ -118,7 +118,6 @@ public: if (ext >= 'a' && ext <= 'z') ext += 'A' - 'a'; return ext >= 'A' && ext <= 'Z' && ((isa >> (ext - 'A')) & 1); } - bool validate_priv(reg_t priv); void set_privilege(reg_t); void yield_load_reservation() { state.load_reservation = (reg_t)-1; } void update_histogram(reg_t pc); -- 2.30.2