diff options
author | Andrew Waterman <andrew@sifive.com> | 2023-07-25 15:19:53 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-07-25 15:19:53 -0700 |
commit | 60c08b1ea5e3d96a97c235db87d472a7cfb2611b (patch) | |
tree | afc79314b2e7cb6d46225ef75fa97115b0fbe010 /riscv/csrs.cc | |
parent | 4d0171931c4e8f03d9038da98eb4003789b1ac4c (diff) | |
parent | bc5842f94517c5fa760409cf8c956bbc7c37ead5 (diff) | |
download | spike-60c08b1ea5e3d96a97c235db87d472a7cfb2611b.zip spike-60c08b1ea5e3d96a97c235db87d472a7cfb2611b.tar.gz spike-60c08b1ea5e3d96a97c235db87d472a7cfb2611b.tar.bz2 |
Merge pull request #1383 from rivosinc/sscrind_feature
Add Smcsrind / Sscsrind support
Diffstat (limited to 'riscv/csrs.cc')
-rw-r--r-- | riscv/csrs.cc | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/riscv/csrs.cc b/riscv/csrs.cc index 34c03a5..9849ea2 100644 --- a/riscv/csrs.cc +++ b/riscv/csrs.cc @@ -1587,3 +1587,65 @@ void jvt_csr_t::verify_permissions(insn_t insn, bool write) const { } } } + +virtualized_indirect_csr_t::virtualized_indirect_csr_t(processor_t* const proc, csr_t_p orig, csr_t_p virt): + virtualized_csr_t(proc, orig, virt) { +} + +void virtualized_indirect_csr_t::verify_permissions(insn_t insn, bool write) const { + virtualized_csr_t::verify_permissions(insn, write); + if (state->v) + virt_csr->verify_permissions(insn, write); + else + orig_csr->verify_permissions(insn, write); +} + +sscsrind_reg_csr_t::sscsrind_reg_csr_t(processor_t* const proc, const reg_t addr, csr_t_p iselect) : + csr_t(proc, addr), + iselect(iselect) { +} + +void sscsrind_reg_csr_t::verify_permissions(insn_t insn, bool write) const { + // Don't call base verify_permission for VS registers remapped to S-mode + if (insn.csr() == address) + csr_t::verify_permissions(insn, write); + + csr_t_p proxy_csr = get_reg(); + if (proxy_csr == nullptr) { + if (!state->v) { + throw trap_illegal_instruction(insn.bits()); + } else { + throw trap_virtual_instruction(insn.bits()); + } + } + proxy_csr->verify_permissions(insn, write); +} + + +reg_t sscsrind_reg_csr_t::read() const noexcept { + csr_t_p target_csr = get_reg(); + if (target_csr != nullptr) { + return target_csr->read(); + } + return 0; +} + +bool sscsrind_reg_csr_t::unlogged_write(const reg_t val) noexcept { + csr_t_p proxy_csr = get_reg(); + if (proxy_csr != nullptr) { + proxy_csr->write(val); + } + return false; +} + +// Returns the actual CSR that maps to value in *siselect or nullptr if no mapping exists +csr_t_p sscsrind_reg_csr_t::get_reg() const noexcept { + auto proxy = ireg_proxy; + auto isel = iselect->read(); + auto it = proxy.find(isel); + return it != proxy.end() ? it->second : nullptr; +} + +void sscsrind_reg_csr_t::add_ireg_proxy(const reg_t iselect_value, csr_t_p csr) { + ireg_proxy[iselect_value] = csr; +} |