diff options
-rw-r--r-- | riscv/csrs.cc | 54 | ||||
-rw-r--r-- | riscv/csrs.h | 2 | ||||
-rw-r--r-- | riscv/insns/vsm4r_vs.h | 2 | ||||
-rw-r--r-- | riscv/processor.cc | 1 |
4 files changed, 32 insertions, 27 deletions
diff --git a/riscv/csrs.cc b/riscv/csrs.cc index d81cad5..49717e5 100644 --- a/riscv/csrs.cc +++ b/riscv/csrs.cc @@ -315,31 +315,31 @@ bool mseccfg_csr_t::get_sseed() const noexcept { } bool mseccfg_csr_t::unlogged_write(const reg_t val) noexcept { - if (proc->n_pmp == 0) - return false; - - // pmpcfg.L is 1 in any rule or entry (including disabled entries) - const bool pmplock_recorded = std::any_of(state->pmpaddr, state->pmpaddr + proc->n_pmp, - [](const pmpaddr_csr_t_p & c) { return c->is_locked(); } ); reg_t new_val = read(); - // When RLB is 0 and pmplock_recorded, RLB is locked to 0. - // Otherwise set the RLB bit according val - if (!(pmplock_recorded && (read() & MSECCFG_RLB) == 0)) { - new_val &= ~MSECCFG_RLB; - new_val |= (val & MSECCFG_RLB); - } + if (proc->n_pmp != 0) { + // pmpcfg.L is 1 in any rule or entry (including disabled entries) + const bool pmplock_recorded = std::any_of(state->pmpaddr, state->pmpaddr + proc->n_pmp, + [](const pmpaddr_csr_t_p & c) { return c->is_locked(); } ); - new_val |= (val & MSECCFG_MMWP); //MMWP is sticky - new_val |= (val & MSECCFG_MML); //MML is sticky + // When RLB is 0 and pmplock_recorded, RLB is locked to 0. + // Otherwise set the RLB bit according val + if (!(pmplock_recorded && (read() & MSECCFG_RLB) == 0)) { + new_val &= ~MSECCFG_RLB; + new_val |= (val & MSECCFG_RLB); + } + + new_val |= (val & MSECCFG_MMWP); //MMWP is sticky + new_val |= (val & MSECCFG_MML); //MML is sticky + + proc->get_mmu()->flush_tlb(); + } if (proc->extension_enabled(EXT_ZKR)) { uint64_t mask = MSECCFG_USEED | MSECCFG_SSEED; new_val = (new_val & ~mask) | (val & mask); } - proc->get_mmu()->flush_tlb(); - if (proc->extension_enabled(EXT_ZICFILP)) { new_val &= ~MSECCFG_MLPE; new_val |= (val & MSECCFG_MLPE); @@ -890,9 +890,11 @@ mip_proxy_csr_t::mip_proxy_csr_t(processor_t* const proc, const reg_t addr, gene void mip_proxy_csr_t::verify_permissions(insn_t insn, bool write) const { csr_t::verify_permissions(insn, write); - if ((state->csrmap[CSR_HVICTL]->read() & HVICTL_VTI) && - proc->extension_enabled('S') && state->v) - throw trap_virtual_instruction(insn.bits()); // VS-mode attempts to access sip when hvictl.VTI=1 + if (proc->extension_enabled_const(EXT_SSAIA) && proc->extension_enabled('H')) { + if ((state->csrmap[CSR_HVICTL]->read() & HVICTL_VTI) && + proc->extension_enabled('S') && state->v) + throw trap_virtual_instruction(insn.bits()); // VS-mode attempts to access sip when hvictl.VTI=1 + } } reg_t mip_proxy_csr_t::read() const noexcept { @@ -912,9 +914,11 @@ mie_proxy_csr_t::mie_proxy_csr_t(processor_t* const proc, const reg_t addr, gene void mie_proxy_csr_t::verify_permissions(insn_t insn, bool write) const { csr_t::verify_permissions(insn, write); - if ((state->csrmap[CSR_HVICTL]->read() & HVICTL_VTI) && - proc->extension_enabled('S') && state->v) - throw trap_virtual_instruction(insn.bits()); // VS-mode attempts to access sie when hvictl.VTI=1 + if (proc->extension_enabled_const(EXT_SSAIA) && proc->extension_enabled('H')) { + if ((state->csrmap[CSR_HVICTL]->read() & HVICTL_VTI) && + proc->extension_enabled('S') && state->v) + throw trap_virtual_instruction(insn.bits()); // VS-mode attempts to access sie when hvictl.VTI=1 + } } reg_t mie_proxy_csr_t::read() const noexcept { @@ -1731,8 +1735,10 @@ void stimecmp_csr_t::verify_permissions(insn_t insn, bool write) const { basic_csr_t::verify_permissions(insn, write); - if ((state->csrmap[CSR_HVICTL]->read() & HVICTL_VTI) && state->v && write) - throw trap_virtual_instruction(insn.bits()); + if (proc->extension_enabled_const(EXT_SSAIA) && proc->extension_enabled('H')) { + if ((state->csrmap[CSR_HVICTL]->read() & HVICTL_VTI) && state->v && write) + throw trap_virtual_instruction(insn.bits()); + } } virtualized_with_special_permission_csr_t::virtualized_with_special_permission_csr_t(processor_t* const proc, csr_t_p orig, csr_t_p virt): diff --git a/riscv/csrs.h b/riscv/csrs.h index 2f05ea2..97fd0f1 100644 --- a/riscv/csrs.h +++ b/riscv/csrs.h @@ -973,7 +973,7 @@ class inaccessible_csr_t: public csr_t { virtual void verify_permissions(insn_t insn, bool write) const override; reg_t read() const noexcept override { return 0; } protected: - bool unlogged_write(const reg_t val) noexcept override { return false; } + bool unlogged_write(const reg_t UNUSED val) noexcept override { return false; } }; class vstopi_csr_t: public csr_t { diff --git a/riscv/insns/vsm4r_vs.h b/riscv/insns/vsm4r_vs.h index 8bbf777..8db1050 100644 --- a/riscv/insns/vsm4r_vs.h +++ b/riscv/insns/vsm4r_vs.h @@ -2,8 +2,6 @@ #include "zvksed_ext_macros.h" -const uint32_t EGS = 4; - require_vsm4_constraints; require_align(insn.rd(), P.VU.vflmul); require_vs2_align_eglmul(128); diff --git a/riscv/processor.cc b/riscv/processor.cc index 5e608a9..6fe64ab 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -447,6 +447,7 @@ void processor_t::take_trap(trap_t& t, reg_t epc) bool supv_double_trap = false; if (interrupt) { vsdeleg = (curr_virt && state.prv <= PRV_S) ? state.hideleg->read() : 0; + vsdeleg >>= 1; hsdeleg = (state.prv <= PRV_S) ? (state.mideleg->read() | state.nonvirtual_sip->read()) : 0; bit &= ~((reg_t)1 << (max_xlen - 1)); } else { |