aboutsummaryrefslogtreecommitdiff
path: root/riscv
diff options
context:
space:
mode:
authorAndrew Waterman <andrew@sifive.com>2022-08-08 20:00:43 -0700
committerGitHub <noreply@github.com>2022-08-08 20:00:43 -0700
commitdd9bf0d3de2dccea483723f6e5f9cf8cfc2e05e1 (patch)
tree620a71cafcfe5b10b04bd1488a99b5dae786d3cd /riscv
parent5672c4a41ad7a9af011d385962c175a5a6012fd9 (diff)
parenta7de776de66a1c1caea8d896e6ff51503b0a46bf (diff)
downloadspike-dd9bf0d3de2dccea483723f6e5f9cf8cfc2e05e1.zip
spike-dd9bf0d3de2dccea483723f6e5f9cf8cfc2e05e1.tar.gz
spike-dd9bf0d3de2dccea483723f6e5f9cf8cfc2e05e1.tar.bz2
Merge pull request #1059 from plctlab/plct-stateen-fix
add stateen related check to frm/fflags
Diffstat (limited to 'riscv')
-rw-r--r--riscv/csrs.cc50
-rw-r--r--riscv/csrs.h6
-rw-r--r--riscv/processor.cc2
3 files changed, 21 insertions, 37 deletions
diff --git a/riscv/csrs.cc b/riscv/csrs.cc
index 50cbfb3..3f487b4 100644
--- a/riscv/csrs.cc
+++ b/riscv/csrs.cc
@@ -1204,6 +1204,21 @@ void float_csr_t::verify_permissions(insn_t insn, bool write) const {
require_fp;
if (!proc->extension_enabled('F'))
throw trap_illegal_instruction(insn.bits());
+
+ if (proc->extension_enabled(EXT_SMSTATEEN) && proc->extension_enabled(EXT_ZFINX)) {
+ if ((state->prv < PRV_M) && !(state->mstateen[0]->read() & MSTATEEN0_FCSR))
+ throw trap_illegal_instruction(insn.bits());
+
+ if (state->v && !(state->hstateen[0]->read() & HSTATEEN0_FCSR))
+ throw trap_virtual_instruction(insn.bits());
+
+ if ((proc->extension_enabled('S') && state->prv < PRV_S) && !(state->sstateen[0]->read() & SSTATEEN0_FCSR)) {
+ if (state->v)
+ throw trap_virtual_instruction(insn.bits());
+ else
+ throw trap_illegal_instruction(insn.bits());
+ }
+ }
}
bool float_csr_t::unlogged_write(const reg_t val) noexcept {
@@ -1315,10 +1330,9 @@ bool hstateen_csr_t::unlogged_write(const reg_t val) noexcept {
}
void hstateen_csr_t::verify_permissions(insn_t insn, bool write) const {
- masked_csr_t::verify_permissions(insn, write);
-
if ((state->prv < PRV_M) && !(state->mstateen[index]->read() & MSTATEEN_HSTATEEN))
throw trap_illegal_instruction(insn.bits());
+ masked_csr_t::verify_permissions(insn, write);
}
// implement class sstateen_csr_t
@@ -1356,30 +1370,6 @@ void sstateen_csr_t::verify_permissions(insn_t insn, bool write) const {
throw trap_virtual_instruction(insn.bits());
}
-// implement class fcsr_csr_t
-fcsr_csr_t::fcsr_csr_t(processor_t* const proc, const reg_t addr, csr_t_p upper_csr, csr_t_p lower_csr, const unsigned upper_lsb):
- composite_csr_t(proc, addr, upper_csr, lower_csr, upper_lsb) {
-}
-
-void fcsr_csr_t::verify_permissions(insn_t insn, bool write) const {
- composite_csr_t::verify_permissions(insn, write);
-
- if (proc->extension_enabled(EXT_SMSTATEEN) && proc->extension_enabled(EXT_ZFINX)) {
- if ((state->prv < PRV_M) && !(state->mstateen[0]->read() & MSTATEEN0_FCSR))
- throw trap_illegal_instruction(insn.bits());
-
- if (state->v && !(state->hstateen[0]->read() & HSTATEEN0_FCSR))
- throw trap_virtual_instruction(insn.bits());
-
- if ((proc->extension_enabled('S') && state->prv < PRV_S) && !(state->sstateen[0]->read() & SSTATEEN0_FCSR)) {
- if (state->v)
- throw trap_virtual_instruction(insn.bits());
- else
- throw trap_illegal_instruction(insn.bits());
- }
- }
-}
-
// implement class senvcfg_csr_t
senvcfg_csr_t::senvcfg_csr_t(processor_t* const proc, const reg_t addr, const reg_t mask,
const reg_t init):
@@ -1387,8 +1377,6 @@ senvcfg_csr_t::senvcfg_csr_t(processor_t* const proc, const reg_t addr, const re
}
void senvcfg_csr_t::verify_permissions(insn_t insn, bool write) const {
- masked_csr_t::verify_permissions(insn, write);
-
if (proc->extension_enabled(EXT_SMSTATEEN)) {
if ((state->prv < PRV_M) && !(state->mstateen[0]->read() & MSTATEEN0_HENVCFG))
throw trap_illegal_instruction(insn.bits());
@@ -1396,15 +1384,17 @@ void senvcfg_csr_t::verify_permissions(insn_t insn, bool write) const {
if (state->v && !(state->hstateen[0]->read() & HSTATEEN0_SENVCFG))
throw trap_virtual_instruction(insn.bits());
}
-}
-void henvcfg_csr_t::verify_permissions(insn_t insn, bool write) const {
masked_csr_t::verify_permissions(insn, write);
+}
+void henvcfg_csr_t::verify_permissions(insn_t insn, bool write) const {
if (proc->extension_enabled(EXT_SMSTATEEN)) {
if ((state->prv < PRV_M) && !(state->mstateen[0]->read() & MSTATEEN0_HENVCFG))
throw trap_illegal_instruction(insn.bits());
}
+
+ masked_csr_t::verify_permissions(insn, write);
}
stimecmp_csr_t::stimecmp_csr_t(processor_t* const proc, const reg_t addr, const reg_t imask):
diff --git a/riscv/csrs.h b/riscv/csrs.h
index acd889c..85a4d50 100644
--- a/riscv/csrs.h
+++ b/riscv/csrs.h
@@ -718,12 +718,6 @@ class sstateen_csr_t: public hstateen_csr_t {
virtual bool unlogged_write(const reg_t val) noexcept override;
};
-class fcsr_csr_t: public composite_csr_t {
- public:
- fcsr_csr_t(processor_t* const proc, const reg_t addr, csr_t_p upper_csr, csr_t_p lower_csr, const unsigned upper_lsb);
- virtual void verify_permissions(insn_t insn, bool write) const override;
-};
-
class senvcfg_csr_t final: public masked_csr_t {
public:
senvcfg_csr_t(processor_t* const proc, const reg_t addr, const reg_t mask, const reg_t init);
diff --git a/riscv/processor.cc b/riscv/processor.cc
index 0389707..0325c51 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -393,7 +393,7 @@ void state_t::reset(processor_t* const proc, reg_t max_isa)
csrmap[CSR_FFLAGS] = fflags = std::make_shared<float_csr_t>(proc, CSR_FFLAGS, FSR_AEXC >> FSR_AEXC_SHIFT, 0);
csrmap[CSR_FRM] = frm = std::make_shared<float_csr_t>(proc, CSR_FRM, FSR_RD >> FSR_RD_SHIFT, 0);
assert(FSR_AEXC_SHIFT == 0); // composite_csr_t assumes fflags begins at bit 0
- csrmap[CSR_FCSR] = std::make_shared<fcsr_csr_t>(proc, CSR_FCSR, frm, fflags, FSR_RD_SHIFT);
+ csrmap[CSR_FCSR] = std::make_shared<composite_csr_t>(proc, CSR_FCSR, frm, fflags, FSR_RD_SHIFT);
csrmap[CSR_SEED] = std::make_shared<seed_csr_t>(proc, CSR_SEED);