aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <andrew@sifive.com>2023-07-25 15:19:53 -0700
committerGitHub <noreply@github.com>2023-07-25 15:19:53 -0700
commit60c08b1ea5e3d96a97c235db87d472a7cfb2611b (patch)
treeafc79314b2e7cb6d46225ef75fa97115b0fbe010
parent4d0171931c4e8f03d9038da98eb4003789b1ac4c (diff)
parentbc5842f94517c5fa760409cf8c956bbc7c37ead5 (diff)
downloadriscv-isa-sim-60c08b1ea5e3d96a97c235db87d472a7cfb2611b.zip
riscv-isa-sim-60c08b1ea5e3d96a97c235db87d472a7cfb2611b.tar.gz
riscv-isa-sim-60c08b1ea5e3d96a97c235db87d472a7cfb2611b.tar.bz2
Merge pull request #1383 from rivosinc/sscrind_feature
Add Smcsrind / Sscsrind support
-rw-r--r--disasm/isa_parser.cc4
-rw-r--r--riscv/csrs.cc62
-rw-r--r--riscv/csrs.h28
-rw-r--r--riscv/encoding.h32
-rw-r--r--riscv/isa_parser.h2
-rw-r--r--riscv/processor.cc40
6 files changed, 167 insertions, 1 deletions
diff --git a/disasm/isa_parser.cc b/disasm/isa_parser.cc
index c18a72d..f4d9da4 100644
--- a/disasm/isa_parser.cc
+++ b/disasm/isa_parser.cc
@@ -286,6 +286,10 @@ isa_parser_t::isa_parser_t(const char* str, const char *priv)
} else if (ext_str == "zvkt") {
} else if (ext_str == "sstc") {
extension_table[EXT_SSTC] = true;
+ } else if (ext_str == "smcsrind") {
+ extension_table[EXT_SMCSRIND] = true;
+ } else if (ext_str == "sscsrind") {
+ extension_table[EXT_SSCSRIND] = true;
} else if (ext_str[0] == 'x') {
extension_table['X'] = true;
if (ext_str.size() == 1) {
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;
+}
diff --git a/riscv/csrs.h b/riscv/csrs.h
index e483ea3..cf48673 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>
@@ -794,4 +798,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/encoding.h b/riscv/encoding.h
index db7b021..9666774 100644
--- a/riscv/encoding.h
+++ b/riscv/encoding.h
@@ -4,7 +4,7 @@
/*
* This file is auto-generated by running 'make' in
- * https://github.com/riscv/riscv-opcodes (3ca60c5)
+ * https://github.com/riscv/riscv-opcodes (be53d24)
*/
#ifndef RISCV_CSR_ENCODING_H
@@ -3059,6 +3059,11 @@
#define CSR_STIMECMP 0x14d
#define CSR_SISELECT 0x150
#define CSR_SIREG 0x151
+#define CSR_SIREG2 0x152
+#define CSR_SIREG3 0x153
+#define CSR_SIREG4 0x155
+#define CSR_SIREG5 0x156
+#define CSR_SIREG6 0x157
#define CSR_STOPEI 0x15c
#define CSR_SATP 0x180
#define CSR_SCONTEXT 0x5a8
@@ -3073,6 +3078,11 @@
#define CSR_VSTIMECMP 0x24d
#define CSR_VSISELECT 0x250
#define CSR_VSIREG 0x251
+#define CSR_VSIREG2 0x252
+#define CSR_VSIREG3 0x253
+#define CSR_VSIREG4 0x255
+#define CSR_VSIREG5 0x256
+#define CSR_VSIREG6 0x257
#define CSR_VSTOPEI 0x25c
#define CSR_VSATP 0x280
#define CSR_HSTATUS 0x600
@@ -3140,6 +3150,11 @@
#define CSR_MTVAL2 0x34b
#define CSR_MISELECT 0x350
#define CSR_MIREG 0x351
+#define CSR_MIREG2 0x352
+#define CSR_MIREG3 0x353
+#define CSR_MIREG4 0x355
+#define CSR_MIREG5 0x356
+#define CSR_MIREG6 0x357
#define CSR_MTOPEI 0x35c
#define CSR_PMPCFG0 0x3a0
#define CSR_PMPCFG1 0x3a1
@@ -4926,6 +4941,11 @@ DECLARE_CSR(sip, CSR_SIP)
DECLARE_CSR(stimecmp, CSR_STIMECMP)
DECLARE_CSR(siselect, CSR_SISELECT)
DECLARE_CSR(sireg, CSR_SIREG)
+DECLARE_CSR(sireg2, CSR_SIREG2)
+DECLARE_CSR(sireg3, CSR_SIREG3)
+DECLARE_CSR(sireg4, CSR_SIREG4)
+DECLARE_CSR(sireg5, CSR_SIREG5)
+DECLARE_CSR(sireg6, CSR_SIREG6)
DECLARE_CSR(stopei, CSR_STOPEI)
DECLARE_CSR(satp, CSR_SATP)
DECLARE_CSR(scontext, CSR_SCONTEXT)
@@ -4940,6 +4960,11 @@ DECLARE_CSR(vsip, CSR_VSIP)
DECLARE_CSR(vstimecmp, CSR_VSTIMECMP)
DECLARE_CSR(vsiselect, CSR_VSISELECT)
DECLARE_CSR(vsireg, CSR_VSIREG)
+DECLARE_CSR(vsireg2, CSR_VSIREG2)
+DECLARE_CSR(vsireg3, CSR_VSIREG3)
+DECLARE_CSR(vsireg4, CSR_VSIREG4)
+DECLARE_CSR(vsireg5, CSR_VSIREG5)
+DECLARE_CSR(vsireg6, CSR_VSIREG6)
DECLARE_CSR(vstopei, CSR_VSTOPEI)
DECLARE_CSR(vsatp, CSR_VSATP)
DECLARE_CSR(hstatus, CSR_HSTATUS)
@@ -5007,6 +5032,11 @@ DECLARE_CSR(mtinst, CSR_MTINST)
DECLARE_CSR(mtval2, CSR_MTVAL2)
DECLARE_CSR(miselect, CSR_MISELECT)
DECLARE_CSR(mireg, CSR_MIREG)
+DECLARE_CSR(mireg2, CSR_MIREG2)
+DECLARE_CSR(mireg3, CSR_MIREG3)
+DECLARE_CSR(mireg4, CSR_MIREG4)
+DECLARE_CSR(mireg5, CSR_MIREG5)
+DECLARE_CSR(mireg6, CSR_MIREG6)
DECLARE_CSR(mtopei, CSR_MTOPEI)
DECLARE_CSR(pmpcfg0, CSR_PMPCFG0)
DECLARE_CSR(pmpcfg1, CSR_PMPCFG1)
diff --git a/riscv/isa_parser.h b/riscv/isa_parser.h
index 335a42b..bba5a91 100644
--- a/riscv/isa_parser.h
+++ b/riscv/isa_parser.h
@@ -77,6 +77,8 @@ typedef enum {
EXT_SSTC,
EXT_ZACAS,
EXT_INTERNAL_ZFH_MOVE,
+ EXT_SMCSRIND,
+ EXT_SSCSRIND,
NUM_ISA_EXTENSIONS
} isa_extension_t;
diff --git a/riscv/processor.cc b/riscv/processor.cc
index 2f458bf..ff64f5a 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();