diff options
author | Andrew Waterman <andrew@sifive.com> | 2022-08-08 20:00:43 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-08 20:00:43 -0700 |
commit | dd9bf0d3de2dccea483723f6e5f9cf8cfc2e05e1 (patch) | |
tree | 620a71cafcfe5b10b04bd1488a99b5dae786d3cd /riscv | |
parent | 5672c4a41ad7a9af011d385962c175a5a6012fd9 (diff) | |
parent | a7de776de66a1c1caea8d896e6ff51503b0a46bf (diff) | |
download | spike-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.cc | 50 | ||||
-rw-r--r-- | riscv/csrs.h | 6 | ||||
-rw-r--r-- | riscv/processor.cc | 2 |
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); |