aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--riscv/csrs.cc54
-rw-r--r--riscv/csrs.h2
-rw-r--r--riscv/insns/vsm4r_vs.h2
-rw-r--r--riscv/processor.cc13
4 files changed, 41 insertions, 30 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 ec3c998..6fe64ab 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -303,9 +303,15 @@ bool processor_t::is_handled_in_vs()
void processor_t::take_interrupt(reg_t pending_interrupts)
{
- const reg_t s_pending_interrupts = state.nonvirtual_sip->read() & state.nonvirtual_sie->read();
- const reg_t vstopi = state.vstopi->read();
- const reg_t vs_pending_interrupt = vstopi ? (reg_t(1) << get_field(vstopi, MTOPI_IID)) : 0;
+ reg_t s_pending_interrupts = 0;
+ reg_t vstopi = 0;
+ reg_t vs_pending_interrupt = 0;
+
+ if (extension_enable_table[EXT_SSAIA]) {
+ s_pending_interrupts = state.nonvirtual_sip->read() & state.nonvirtual_sie->read();
+ vstopi = state.vstopi->read();
+ vs_pending_interrupt = vstopi ? (reg_t(1) << get_field(vstopi, MTOPI_IID)) : 0;
+ }
// Do nothing if no pending interrupts
if (!pending_interrupts && !s_pending_interrupts && !vs_pending_interrupt) {
@@ -441,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 {