aboutsummaryrefslogtreecommitdiff
path: root/riscv/csrs.cc
diff options
context:
space:
mode:
authorAtul Khare <atulkhare@rivosinc.com>2023-07-11 13:31:12 -0700
committerAtul Khare <atulkhare@rivosinc.com>2023-07-19 14:22:51 -0700
commitbc5842f94517c5fa760409cf8c956bbc7c37ead5 (patch)
tree154d45f3f98f71f79162ed9390a9bb031d62d65d /riscv/csrs.cc
parenta6bc48b95e4c7cbf4e6f70315d884b1fe0a06d7f (diff)
downloadspike-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.cc62
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;
+}