aboutsummaryrefslogtreecommitdiff
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
parenta6bc48b95e4c7cbf4e6f70315d884b1fe0a06d7f (diff)
downloadriscv-isa-sim-bc5842f94517c5fa760409cf8c956bbc7c37ead5.zip
riscv-isa-sim-bc5842f94517c5fa760409cf8c956bbc7c37ead5.tar.gz
riscv-isa-sim-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.
-rw-r--r--riscv/csrs.cc62
-rw-r--r--riscv/csrs.h28
-rw-r--r--riscv/processor.cc40
3 files changed, 130 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;
+}
diff --git a/riscv/csrs.h b/riscv/csrs.h
index 07d6d82..d28d124 100644
--- a/riscv/csrs.h
+++ b/riscv/csrs.h
@@ -6,8 +6,12 @@
#include "encoding.h"
// For reg_t:
#include "decode.h"
+// For std::unordered_map
+#include <unordered_map>
// For std::shared_ptr
#include <memory>
+// For std::optional
+#include <optional>
// For access_type:
#include "memtracer.h"
#include <cassert>
@@ -787,4 +791,28 @@ class jvt_csr_t: public basic_csr_t {
jvt_csr_t(processor_t* const proc, const reg_t addr, const reg_t init);
virtual void verify_permissions(insn_t insn, bool write) const override;
};
+
+// Sscsrind registers needs permissions checked
+// (the original virtualized_csr_t does not call verify_permission of the underlying CSRs)
+class virtualized_indirect_csr_t: public virtualized_csr_t {
+ public:
+ virtualized_indirect_csr_t(processor_t* const proc, csr_t_p orig, csr_t_p virt);
+ virtual void verify_permissions(insn_t insn, bool write) const override;
+};
+
+class sscsrind_reg_csr_t : public csr_t {
+ public:
+ typedef std::shared_ptr<sscsrind_reg_csr_t> sscsrind_reg_csr_t_p;
+ sscsrind_reg_csr_t(processor_t* const proc, const reg_t addr, csr_t_p iselect);
+ reg_t read() const noexcept override;
+ virtual void verify_permissions(insn_t insn, bool write) const override;
+ void add_ireg_proxy(const reg_t iselect_val, csr_t_p proxy_csr);
+ protected:
+ virtual bool unlogged_write(const reg_t val) noexcept override;
+ private:
+ csr_t_p iselect;
+ std::unordered_map<reg_t, csr_t_p> ireg_proxy;
+ csr_t_p get_reg() const noexcept;
+};
+
#endif
diff --git a/riscv/processor.cc b/riscv/processor.cc
index e81375a..c41b3cf 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -524,6 +524,46 @@ void state_t::reset(processor_t* const proc, reg_t max_isa)
if (proc->extension_enabled(EXT_ZCMT))
csrmap[CSR_JVT] = jvt = std::make_shared<jvt_csr_t>(proc, CSR_JVT, 0);
+
+ // Smcsrind / Sscsrind
+ csr_t_p miselect;
+ csr_t_p siselect;
+ csr_t_p vsiselect;
+ sscsrind_reg_csr_t::sscsrind_reg_csr_t_p mireg[6];
+ sscsrind_reg_csr_t::sscsrind_reg_csr_t_p sireg[6];
+ sscsrind_reg_csr_t::sscsrind_reg_csr_t_p vsireg[6];
+
+ if (proc->extension_enabled_const(EXT_SMCSRIND)) {
+ const reg_t mireg_csrs[] = { CSR_MIREG, CSR_MIREG2, CSR_MIREG3, CSR_MIREG4, CSR_MIREG5, CSR_MIREG6 };
+ auto i = 0;
+ for (auto csr : mireg_csrs) {
+ csrmap[csr] = mireg[i] = std::make_shared<sscsrind_reg_csr_t>(proc, csr, miselect);
+ i++;
+ }
+ }
+
+ if (proc->extension_enabled_const(EXT_SSCSRIND)) {
+ vsiselect = std::make_shared<basic_csr_t>(proc, CSR_VSISELECT, 0);
+ csrmap[CSR_VSISELECT] = vsiselect;
+ siselect = std::make_shared<basic_csr_t>(proc, CSR_SISELECT, 0);
+ csrmap[CSR_SISELECT] = std::make_shared<virtualized_csr_t>(proc, siselect, vsiselect);
+
+ const reg_t vsireg_csrs[] = { CSR_VSIREG, CSR_VSIREG2, CSR_VSIREG3, CSR_VSIREG4, CSR_VSIREG5, CSR_VSIREG6 };
+ auto i = 0;
+ for (auto csr : vsireg_csrs) {
+ csrmap[csr] = vsireg[i] = std::make_shared<sscsrind_reg_csr_t>(proc, csr, vsiselect);
+ i++;
+ }
+
+ const reg_t sireg_csrs[] = { CSR_SIREG, CSR_SIREG2, CSR_SIREG3, CSR_SIREG4, CSR_SIREG5, CSR_SIREG6 };
+ i = 0;
+ for (auto csr : sireg_csrs) {
+ sireg[i] = std::make_shared<sscsrind_reg_csr_t>(proc, csr, siselect);
+ csrmap[csr] = std::make_shared<virtualized_indirect_csr_t>(proc, sireg[i], vsireg[i]);
+ i++;
+ }
+ }
+
serialized = false;
log_reg_write.clear();