diff options
author | Atul Khare <atulkhare@rivosinc.com> | 2023-07-11 13:31:12 -0700 |
---|---|---|
committer | Atul Khare <atulkhare@rivosinc.com> | 2023-07-19 14:22:51 -0700 |
commit | bc5842f94517c5fa760409cf8c956bbc7c37ead5 (patch) | |
tree | 154d45f3f98f71f79162ed9390a9bb031d62d65d /riscv/csrs.cc | |
parent | a6bc48b95e4c7cbf4e6f70315d884b1fe0a06d7f (diff) | |
download | spike-bc5842f94517c5fa760409cf8c956bbc7c37ead5.zip spike-bc5842f94517c5fa760409cf8c956bbc7c37ead5.tar.gz spike-bc5842f94517c5fa760409cf8c956bbc7c37ead5.tar.bz2 |
Add Smcsrind/Sscsrind support
This adds the following CSRs:
miselect (0x350), mireg (0x351), mireg2/3 (0x352, 0x353),
mireg4-6 (0x355 - 0x357), siselect (0x150), sireg (0x151),
sireg2/3 (0x152, 0x153), sireg4-6 (0x155 - 0x157), vsiselect (0x250),
vsireg (0x251), mireg2/3 (0x252, 0x253), vsireg4-6 (0x255 - 0x257).
Presently, attempts to read / write from ireg? registers will fail, and
future extensions will provide proxy CSR mappings for the respective
?ireg CSRs.
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 7ea07d1..4d1e546 100644 --- a/riscv/csrs.cc +++ b/riscv/csrs.cc @@ -1574,3 +1574,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; +} |