aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/continuous-integration.yml4
-rw-r--r--.github/workflows/debug-smoke.yml2
-rw-r--r--ci-tests/testlib.c32
-rw-r--r--disasm/disasm.cc63
-rw-r--r--disasm/isa_parser.cc2
-rw-r--r--riscv/abstract_device.h12
-rw-r--r--riscv/cfg.cc21
-rw-r--r--riscv/cfg.h66
-rw-r--r--riscv/clint.cc5
-rw-r--r--riscv/csrs.cc16
-rw-r--r--riscv/csrs.h1
-rw-r--r--riscv/debug_module.cc143
-rw-r--r--riscv/debug_module.h32
-rw-r--r--riscv/encoding.h46
-rw-r--r--riscv/insns/fmvh_x_d.h2
-rw-r--r--riscv/insns/fmvp_d_x.h2
-rw-r--r--riscv/insns/mop_r_N.h2
-rw-r--r--riscv/insns/mop_rr_N.h2
-rw-r--r--riscv/isa_parser.h1
-rw-r--r--riscv/ns16550.cc2
-rw-r--r--riscv/plic.cc2
-rw-r--r--riscv/processor.cc12
-rw-r--r--riscv/remote_bitbang.cc1
-rw-r--r--riscv/remote_bitbang.h1
-rw-r--r--riscv/riscv.mk.in5
-rw-r--r--riscv/sim.cc12
-rw-r--r--riscv/sim.h2
-rw-r--r--spike_main/spike-log-parser.cc14
-rw-r--r--spike_main/spike.cc50
29 files changed, 354 insertions, 201 deletions
diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml
index 48ef2c1..ecb0a6c 100644
--- a/.github/workflows/continuous-integration.yml
+++ b/.github/workflows/continuous-integration.yml
@@ -29,7 +29,7 @@ jobs:
run: sudo xargs apt-get install -y < .github/workflows/apt-packages.txt
- run: |
- for commit in $(git rev-list origin/master..HEAD); do
+ for commit in $(git rev-list origin/master..HEAD | tac); do
git checkout $commit
echo "Checking commit $commit"
ci-tests/build-spike
@@ -49,7 +49,7 @@ jobs:
run: xargs brew install --overwrite < .github/workflows/brew-packages.txt
- run: |
- for commit in $(git rev-list origin/master..HEAD); do
+ for commit in $(git rev-list origin/master..HEAD | tail -r); do
git checkout $commit
echo "Checking commit $commit"
ci-tests/build-spike
diff --git a/.github/workflows/debug-smoke.yml b/.github/workflows/debug-smoke.yml
index 7c24d55..1ae54ab 100644
--- a/.github/workflows/debug-smoke.yml
+++ b/.github/workflows/debug-smoke.yml
@@ -25,7 +25,7 @@ jobs:
run: |
git clone --recurse-submodules https://github.com/riscv/riscv-openocd.git
cd riscv-openocd
- git checkout a495dd854ce2e857a583125a31527a47320ec6b9
+ git checkout d4c5d2657074613d429f57f60e939ca151ed4f32
- name: Build OpenOCD
run: |
diff --git a/ci-tests/testlib.c b/ci-tests/testlib.c
index 1fca4fa..5e39c1b 100644
--- a/ci-tests/testlib.c
+++ b/ci-tests/testlib.c
@@ -14,36 +14,12 @@ static std::vector<std::pair<reg_t, abstract_mem_t*>> make_mems(const std::vecto
int main()
{
- std::vector<mem_cfg_t> mem_cfg { mem_cfg_t(0x80000000, 0x10000000) };
- std::vector<size_t> hartids = {0};
- cfg_t cfg(std::make_pair(0, 0),
- nullptr,
- "rv64gcv",
- "MSU",
- "vlen:128,elen:64",
- false,
- endianness_little,
- 16,
- (1 << PMP_SHIFT),
- mem_cfg,
- hartids,
- false,
- 4);
- std::vector<const device_factory_t*> plugin_devices;
+ cfg_t cfg;
+ std::vector<device_factory_t*> plugin_devices;
std::vector<std::string> htif_args {"pk", "hello"};
- debug_module_config_t dm_config = {
- .progbufsize = 2,
- .max_sba_data_width = 0,
- .require_authentication = false,
- .abstract_rti = 0,
- .support_hasel = true,
- .support_abstract_csr_access = true,
- .support_abstract_fpr_access = true,
- .support_haltgroups = true,
- .support_impebreak = true
- };
+ debug_module_config_t dm_config;
std::vector<std::pair<reg_t, abstract_mem_t*>> mems =
- make_mems(cfg.mem_layout());
+ make_mems(cfg.mem_layout);
sim_t sim(&cfg, false,
mems,
plugin_devices,
diff --git a/disasm/disasm.cc b/disasm/disasm.cc
index 6917fa5..08571a2 100644
--- a/disasm/disasm.cc
+++ b/disasm/disasm.cc
@@ -2172,15 +2172,58 @@ void disassembler_t::add_instructions(const isa_parser_t* isa)
DEFINE_RTYPE(czero_nez);
}
+ if (isa->extension_enabled(EXT_ZIMOP)) {
+ DEFINE_R1TYPE(mop_r_0);
+ DEFINE_R1TYPE(mop_r_1);
+ DEFINE_R1TYPE(mop_r_2);
+ DEFINE_R1TYPE(mop_r_3);
+ DEFINE_R1TYPE(mop_r_4);
+ DEFINE_R1TYPE(mop_r_5);
+ DEFINE_R1TYPE(mop_r_6);
+ DEFINE_R1TYPE(mop_r_7);
+ DEFINE_R1TYPE(mop_r_8);
+ DEFINE_R1TYPE(mop_r_9);
+ DEFINE_R1TYPE(mop_r_10);
+ DEFINE_R1TYPE(mop_r_11);
+ DEFINE_R1TYPE(mop_r_12);
+ DEFINE_R1TYPE(mop_r_13);
+ DEFINE_R1TYPE(mop_r_14);
+ DEFINE_R1TYPE(mop_r_15);
+ DEFINE_R1TYPE(mop_r_16);
+ DEFINE_R1TYPE(mop_r_17);
+ DEFINE_R1TYPE(mop_r_18);
+ DEFINE_R1TYPE(mop_r_19);
+ DEFINE_R1TYPE(mop_r_20);
+ DEFINE_R1TYPE(mop_r_21);
+ DEFINE_R1TYPE(mop_r_22);
+ DEFINE_R1TYPE(mop_r_23);
+ DEFINE_R1TYPE(mop_r_24);
+ DEFINE_R1TYPE(mop_r_25);
+ DEFINE_R1TYPE(mop_r_26);
+ DEFINE_R1TYPE(mop_r_27);
+ DEFINE_R1TYPE(mop_r_28);
+ DEFINE_R1TYPE(mop_r_29);
+ DEFINE_R1TYPE(mop_r_30);
+ DEFINE_R1TYPE(mop_r_31);
+ DEFINE_RTYPE(mop_rr_0);
+ DEFINE_RTYPE(mop_rr_1);
+ DEFINE_RTYPE(mop_rr_2);
+ DEFINE_RTYPE(mop_rr_3);
+ DEFINE_RTYPE(mop_rr_4);
+ DEFINE_RTYPE(mop_rr_5);
+ DEFINE_RTYPE(mop_rr_6);
+ DEFINE_RTYPE(mop_rr_7);
+ }
+
if (isa->extension_enabled(EXT_ZCMOP)) {
- DISASM_INSN("c.mop.1", c_mop_1, 0, {});
- DISASM_INSN("c.mop.3", c_mop_3, 0, {});
- DISASM_INSN("c.mop.5", c_mop_5, 0, {});
- DISASM_INSN("c.mop.7", c_mop_7, 0, {});
- DISASM_INSN("c.mop.9", c_mop_9, 0, {});
- DISASM_INSN("c.mop.11", c_mop_11, 0, {});
- DISASM_INSN("c.mop.13", c_mop_13, 0, {});
- DISASM_INSN("c.mop.15", c_mop_15, 0, {});
+ DISASM_INSN("c.mop.1", c_mop_1, 0, {});
+ DISASM_INSN("c.mop.3", c_mop_3, 0, {});
+ DISASM_INSN("c.mop.5", c_mop_5, 0, {});
+ DISASM_INSN("c.mop.7", c_mop_7, 0, {});
+ DISASM_INSN("c.mop.9", c_mop_9, 0, {});
+ DISASM_INSN("c.mop.11", c_mop_11, 0, {});
+ DISASM_INSN("c.mop.13", c_mop_13, 0, {});
+ DISASM_INSN("c.mop.15", c_mop_15, 0, {});
}
if (isa->extension_enabled(EXT_ZKND) ||
@@ -2249,7 +2292,7 @@ void disassembler_t::add_instructions(const isa_parser_t* isa)
#define DISASM_VECTOR_VV_VX_VIU(name) \
DEFINE_VECTOR_VV(name##_vv); \
DEFINE_VECTOR_VX(name##_vx); \
- DEFINE_VECTOR_VIU(name##_vx)
+ DEFINE_VECTOR_VIU(name##_vi)
#define DISASM_VECTOR_VV_VX_VIU_ZIMM6(name) \
DEFINE_VECTOR_VV(name##_vv); \
DEFINE_VECTOR_VX(name##_vx); \
@@ -2347,7 +2390,7 @@ disassembler_t::disassembler_t(const isa_parser_t *isa)
// next-highest priority: other instructions in same base ISA
std::string fallback_isa_string = std::string("rv") + std::to_string(isa->get_max_xlen()) +
- "gqchv_zfh_zba_zbb_zbc_zbs_zcb_zicbom_zicboz_zicond_zkn_zkr_zks_svinval_zcmop";
+ "gqchv_zfh_zba_zbb_zbc_zbs_zcb_zicbom_zicboz_zicond_zkn_zkr_zks_svinval_zcmop_zimop";
isa_parser_t fallback_isa(fallback_isa_string.c_str(), DEFAULT_PRIV);
add_instructions(&fallback_isa);
diff --git a/disasm/isa_parser.cc b/disasm/isa_parser.cc
index ef51310..fa8cadd 100644
--- a/disasm/isa_parser.cc
+++ b/disasm/isa_parser.cc
@@ -294,6 +294,8 @@ isa_parser_t::isa_parser_t(const char* str, const char *priv)
extension_table[EXT_SSCSRIND] = true;
} else if (ext_str == "smcntrpmf") {
extension_table[EXT_SMCNTRPMF] = true;
+ } else if (ext_str == "zimop") {
+ extension_table[EXT_ZIMOP] = true;
} else if (ext_str == "zcmop") {
extension_table[EXT_ZCMOP] = true;
} else if (ext_str == "zalasr") {
diff --git a/riscv/abstract_device.h b/riscv/abstract_device.h
index c5c6415..d6097c1 100644
--- a/riscv/abstract_device.h
+++ b/riscv/abstract_device.h
@@ -8,6 +8,7 @@
#include <string>
#include <map>
#include <stdexcept>
+#include <vector>
class sim_t;
@@ -26,10 +27,15 @@ public:
virtual abstract_device_t* parse_from_fdt(const void* fdt, const sim_t* sim, reg_t* base) const = 0;
virtual std::string generate_dts(const sim_t* sim) const = 0;
virtual ~device_factory_t() {}
+ void set_sargs(std::vector<std::string> sargs) { this->sargs = sargs; }
+ std::vector<std::string> get_sargs() { return sargs; }
+
+protected:
+ std::vector<std::string> sargs;
};
// Type for holding all registered MMIO plugins by name.
-using mmio_device_map_t = std::map<std::string, const device_factory_t*>;
+using mmio_device_map_t = std::map<std::string, device_factory_t*>;
mmio_device_map_t& mmio_device_map();
@@ -40,8 +46,8 @@ mmio_device_map_t& mmio_device_map();
std::string str(#name); \
if (!mmio_device_map().emplace(str, this).second) throw std::runtime_error("Plugin \"" + str + "\" already registered"); \
}; \
- name##_t* parse_from_fdt(const void* fdt, const sim_t* sim, reg_t* base) const override { return parse(fdt, sim, base); } \
+ name##_t* parse_from_fdt(const void* fdt, const sim_t* sim, reg_t* base) const override { return parse(fdt, sim, base, sargs); } \
std::string generate_dts(const sim_t* sim) const override { return generate(sim); } \
- }; const device_factory_t *name##_factory = new name##_factory_t();
+ }; device_factory_t *name##_factory = new name##_factory_t();
#endif
diff --git a/riscv/cfg.cc b/riscv/cfg.cc
index 457aa92..d105eb5 100644
--- a/riscv/cfg.cc
+++ b/riscv/cfg.cc
@@ -3,6 +3,8 @@
#include "cfg.h"
#include "mmu.h"
#include "decode.h"
+#include "encoding.h"
+#include "platform.h"
mem_cfg_t::mem_cfg_t(reg_t base, reg_t size) : base(base), size(size)
{
@@ -25,3 +27,22 @@ bool mem_cfg_t::check_if_supported(reg_t base, reg_t size)
(size > 0) &&
((base + size > base) || (base + size == 0));
}
+
+cfg_t::cfg_t()
+{
+ // The default system configuration
+ initrd_bounds = std::make_pair((reg_t)0, (reg_t)0);
+ bootargs = nullptr;
+ isa = DEFAULT_ISA;
+ priv = DEFAULT_PRIV;
+ varch = DEFAULT_VARCH;
+ misaligned = false;
+ endianness = endianness_little;
+ pmpregions = 16;
+ pmpgranularity = (1 << PMP_SHIFT);
+ mem_layout = std::vector<mem_cfg_t>({mem_cfg_t(reg_t(DRAM_BASE), (size_t)2048 << 20)});
+ hartids = std::vector<size_t>({0});
+ explicit_hartids = false;
+ real_time_clint = false;
+ trigger_count = 4;
+}
diff --git a/riscv/cfg.h b/riscv/cfg.h
index 422c1ae..63465e6 100644
--- a/riscv/cfg.h
+++ b/riscv/cfg.h
@@ -61,52 +61,26 @@ private:
class cfg_t
{
public:
- cfg_t(std::pair<reg_t, reg_t> default_initrd_bounds,
- const char *default_bootargs,
- const char *default_isa, const char *default_priv,
- const char *default_varch,
- const bool default_misaligned,
- const endianness_t default_endianness,
- const reg_t default_pmpregions,
- const reg_t default_pmpgranularity,
- const std::vector<mem_cfg_t> &default_mem_layout,
- const std::vector<size_t> default_hartids,
- bool default_real_time_clint,
- const reg_t default_trigger_count)
- : initrd_bounds(default_initrd_bounds),
- bootargs(default_bootargs),
- isa(default_isa),
- priv(default_priv),
- varch(default_varch),
- misaligned(default_misaligned),
- endianness(default_endianness),
- pmpregions(default_pmpregions),
- pmpgranularity(default_pmpgranularity),
- mem_layout(default_mem_layout),
- hartids(default_hartids),
- explicit_hartids(false),
- real_time_clint(default_real_time_clint),
- trigger_count(default_trigger_count)
- {}
-
- cfg_arg_t<std::pair<reg_t, reg_t>> initrd_bounds;
- cfg_arg_t<const char *> bootargs;
- cfg_arg_t<const char *> isa;
- cfg_arg_t<const char *> priv;
- cfg_arg_t<const char *> varch;
- bool misaligned;
- endianness_t endianness;
- reg_t pmpregions;
- reg_t pmpgranularity;
- cfg_arg_t<std::vector<mem_cfg_t>> mem_layout;
- std::optional<reg_t> start_pc;
- cfg_arg_t<std::vector<size_t>> hartids;
- bool explicit_hartids;
- cfg_arg_t<bool> real_time_clint;
- reg_t trigger_count;
-
- size_t nprocs() const { return hartids().size(); }
- size_t max_hartid() const { return hartids().back(); }
+ cfg_t();
+
+ std::pair<reg_t, reg_t> initrd_bounds;
+ const char * bootargs;
+ const char * isa;
+ const char * priv;
+ const char * varch;
+ bool misaligned;
+ endianness_t endianness;
+ reg_t pmpregions;
+ reg_t pmpgranularity;
+ std::vector<mem_cfg_t> mem_layout;
+ std::optional<reg_t> start_pc;
+ std::vector<size_t> hartids;
+ bool explicit_hartids;
+ bool real_time_clint;
+ reg_t trigger_count;
+
+ size_t nprocs() const { return hartids.size(); }
+ size_t max_hartid() const { return hartids.back(); }
};
#endif
diff --git a/riscv/clint.cc b/riscv/clint.cc
index 908ccb6..7e7e89c 100644
--- a/riscv/clint.cc
+++ b/riscv/clint.cc
@@ -116,11 +116,12 @@ void clint_t::tick(reg_t rtc_ticks)
}
}
-clint_t* clint_parse_from_fdt(const void* fdt, const sim_t* sim, reg_t* base) {
+clint_t* clint_parse_from_fdt(const void* fdt, const sim_t* sim, reg_t* base,
+ const std::vector<std::string>& sargs) {
if (fdt_parse_clint(fdt, base, "riscv,clint0") == 0)
return new clint_t(sim,
sim->CPU_HZ / sim->INSNS_PER_RTC_TICK,
- sim->get_cfg().real_time_clint());
+ sim->get_cfg().real_time_clint);
else
return nullptr;
}
diff --git a/riscv/csrs.cc b/riscv/csrs.cc
index e3b5ad4..4783646 100644
--- a/riscv/csrs.cc
+++ b/riscv/csrs.cc
@@ -1304,10 +1304,10 @@ bool dcsr_csr_t::unlogged_write(const reg_t val) noexcept {
step = get_field(val, DCSR_STEP);
// TODO: ndreset and fullreset
ebreakm = get_field(val, DCSR_EBREAKM);
- ebreaks = get_field(val, DCSR_EBREAKS);
- ebreaku = get_field(val, DCSR_EBREAKU);
- ebreakvs = get_field(val, CSR_DCSR_EBREAKVS);
- ebreakvu = get_field(val, CSR_DCSR_EBREAKVU);
+ ebreaks = proc->extension_enabled('S') ? get_field(val, DCSR_EBREAKS) : false;
+ ebreaku = proc->extension_enabled('U') ? get_field(val, DCSR_EBREAKU) : false;
+ ebreakvs = proc->extension_enabled('H') ? get_field(val, CSR_DCSR_EBREAKVS) : false;
+ ebreakvu = proc->extension_enabled('H') ? get_field(val, CSR_DCSR_EBREAKVU) : false;
halt = get_field(val, DCSR_HALT);
v = proc->extension_enabled('H') ? get_field(val, CSR_DCSR_V) : false;
return true;
@@ -1535,7 +1535,7 @@ virtualized_stimecmp_csr_t::virtualized_stimecmp_csr_t(processor_t* const proc,
virtualized_csr_t(proc, orig, virt) {
}
-void virtualized_stimecmp_csr_t::verify_permissions(insn_t insn, bool write) const {
+void stimecmp_csr_t::verify_permissions(insn_t insn, bool write) const {
if (!(state->menvcfg->read() & MENVCFG_STCE)) {
// access to (v)stimecmp with MENVCFG.STCE = 0
if (state->prv < PRV_M)
@@ -1549,7 +1549,11 @@ void virtualized_stimecmp_csr_t::verify_permissions(insn_t insn, bool write) con
throw trap_virtual_instruction(insn.bits());
}
- virtualized_csr_t::verify_permissions(insn, write);
+ basic_csr_t::verify_permissions(insn, write);
+}
+
+void virtualized_stimecmp_csr_t::verify_permissions(insn_t insn, bool write) const {
+ orig_csr->verify_permissions(insn, write);
}
scountovf_csr_t::scountovf_csr_t(processor_t* const proc, const reg_t addr):
diff --git a/riscv/csrs.h b/riscv/csrs.h
index efa7f10..887749a 100644
--- a/riscv/csrs.h
+++ b/riscv/csrs.h
@@ -780,6 +780,7 @@ class senvcfg_csr_t final: public envcfg_csr_t {
class stimecmp_csr_t: public basic_csr_t {
public:
stimecmp_csr_t(processor_t* const proc, const reg_t addr, const reg_t imask);
+ virtual void verify_permissions(insn_t insn, bool write) const override;
protected:
virtual bool unlogged_write(const reg_t val) noexcept override;
private:
diff --git a/riscv/debug_module.cc b/riscv/debug_module.cc
index e9aef1a..5d49605 100644
--- a/riscv/debug_module.cc
+++ b/riscv/debug_module.cc
@@ -43,7 +43,8 @@ debug_module_t::debug_module_t(simif_t *sim, const debug_module_config_t &config
// them because I'm too lazy to add the code to just ignore accesses.
hart_state(1 << field_width(sim->get_cfg().max_hartid() + 1)),
hart_array_mask(sim->get_cfg().max_hartid() + 1),
- rti_remaining(0)
+ rti_remaining(0),
+ sb_read_wait(0), sb_write_wait(0)
{
D(fprintf(stderr, "debug_data_start=0x%x\n", debug_data_start));
D(fprintf(stderr, "debug_progbuf_start=0x%x\n", debug_progbuf_start));
@@ -297,6 +298,24 @@ void debug_module_t::sb_autoincrement()
sbaddress[3] += carry;
}
+bool debug_module_t::sb_busy() const
+{
+ return sb_read_wait > 0 || sb_write_wait > 0;
+}
+
+void debug_module_t::sb_read_start()
+{
+ if (sb_busy() || sbcs.sbbusyerror) {
+ if (!sbcs.sbbusyerror)
+ D(fprintf(stderr, "Set sbbusyerror because read start while busy\n"));
+ sbcs.sbbusyerror = true;
+ return;
+ }
+ /* Insert artificial delay, so debuggers can test how they handle that
+ * sbbusyerror being set. */
+ sb_read_wait = 20;
+}
+
void debug_module_t::sb_read()
{
reg_t address = ((uint64_t) sbaddress[1] << 32) | sbaddress[0];
@@ -314,11 +333,25 @@ void debug_module_t::sb_read()
} else {
sbcs.error = 3;
}
+ D(fprintf(stderr, "sb_read() 0x%x @ 0x%lx\n", sbdata[0], address));
} catch (const mem_trap_t& ) {
sbcs.error = 2;
}
}
+void debug_module_t::sb_write_start()
+{
+ if (sb_busy() || sbcs.sbbusyerror) {
+ if (!sbcs.sbbusyerror)
+ D(fprintf(stderr, "Set sbbusyerror because write start while busy\n"));
+ sbcs.sbbusyerror = true;
+ return;
+ }
+ /* Insert artificial delay, so debuggers can test how they handle that
+ * sbbusyerror being set. */
+ sb_write_wait = 20;
+}
+
void debug_module_t::sb_write()
{
reg_t address = ((uint64_t) sbaddress[1] << 32) | sbaddress[0];
@@ -481,7 +514,7 @@ bool debug_module_t::dmi_read(unsigned address, uint32_t *value)
unsigned base = hawindowsel * 32;
for (unsigned i = 0; i < 32; i++) {
unsigned n = base + i;
- if (n < sim->get_cfg().nprocs() && hart_array_mask[sim->get_cfg().hartids()[n]]) {
+ if (n < sim->get_cfg().nprocs() && hart_array_mask[sim->get_cfg().hartids[n]]) {
result |= 1 << i;
}
}
@@ -494,6 +527,8 @@ bool debug_module_t::dmi_read(unsigned address, uint32_t *value)
result = set_field(result, DM_SBCS_SBAUTOINCREMENT, sbcs.autoincrement);
result = set_field(result, DM_SBCS_SBREADONDATA, sbcs.readondata);
result = set_field(result, DM_SBCS_SBERROR, sbcs.error);
+ result = set_field(result, DM_SBCS_SBBUSY, sb_busy());
+ result = set_field(result, DM_SBCS_SBBUSYERROR, sbcs.sbbusyerror);
result = set_field(result, DM_SBCS_SBASIZE, sbcs.asize);
result = set_field(result, DM_SBCS_SBACCESS128, sbcs.access128);
result = set_field(result, DM_SBCS_SBACCESS64, sbcs.access64);
@@ -515,23 +550,31 @@ bool debug_module_t::dmi_read(unsigned address, uint32_t *value)
break;
case DM_SBDATA0:
result = sbdata[0];
- if (sbcs.error == 0) {
+ if (sb_busy()) {
+ sbcs.sbbusyerror = true;
+ } else if (sbcs.error == 0) {
if (sbcs.readondata) {
- sb_read();
- }
- if (sbcs.error == 0) {
- sb_autoincrement();
+ sb_read_start();
}
}
break;
case DM_SBDATA1:
result = sbdata[1];
+ if (sb_busy()) {
+ sbcs.sbbusyerror = true;
+ }
break;
case DM_SBDATA2:
result = sbdata[2];
+ if (sb_busy()) {
+ sbcs.sbbusyerror = true;
+ }
break;
case DM_SBDATA3:
result = sbdata[3];
+ if (sb_busy()) {
+ sbcs.sbbusyerror = true;
+ }
break;
case DM_AUTHDATA:
result = challenge;
@@ -563,6 +606,24 @@ void debug_module_t::run_test_idle()
if (rti_remaining == 0 && abstractcs.busy && abstract_command_completed) {
abstractcs.busy = false;
}
+ if (sb_read_wait > 0) {
+ sb_read_wait--;
+ if (sb_read_wait == 0) {
+ sb_read();
+ if (sbcs.error == 0) {
+ sb_autoincrement();
+ }
+ }
+ }
+ if (sb_write_wait > 0) {
+ sb_write_wait--;
+ if (sb_write_wait == 0) {
+ sb_write();
+ if (sbcs.error == 0) {
+ sb_autoincrement();
+ }
+ }
+ }
}
static bool is_fpu_reg(unsigned regno)
@@ -855,7 +916,7 @@ bool debug_module_t::dmi_write(unsigned address, uint32_t value)
for (unsigned i = 0; i < 32; i++) {
unsigned n = base + i;
if (n < sim->get_cfg().nprocs()) {
- hart_array_mask[sim->get_cfg().hartids()[n]] = (value >> i) & 1;
+ hart_array_mask[sim->get_cfg().hartids[n]] = (value >> i) & 1;
}
}
}
@@ -877,40 +938,54 @@ bool debug_module_t::dmi_write(unsigned address, uint32_t value)
sbcs.autoincrement = get_field(value, DM_SBCS_SBAUTOINCREMENT);
sbcs.readondata = get_field(value, DM_SBCS_SBREADONDATA);
sbcs.error &= ~get_field(value, DM_SBCS_SBERROR);
+ if (get_field(value, DM_SBCS_SBBUSYERROR))
+ sbcs.sbbusyerror = false;
return true;
case DM_SBADDRESS0:
- sbaddress[0] = value;
- if (sbcs.error == 0 && sbcs.readonaddr) {
- sb_read();
- sb_autoincrement();
- }
- return true;
case DM_SBADDRESS1:
- sbaddress[1] = value;
- return true;
case DM_SBADDRESS2:
- sbaddress[2] = value;
- return true;
case DM_SBADDRESS3:
- sbaddress[3] = value;
- return true;
case DM_SBDATA0:
- sbdata[0] = value;
- if (sbcs.error == 0) {
- sb_write();
- if (sbcs.error == 0) {
- sb_autoincrement();
- }
- }
- return true;
case DM_SBDATA1:
- sbdata[1] = value;
- return true;
case DM_SBDATA2:
- sbdata[2] = value;
- return true;
case DM_SBDATA3:
- sbdata[3] = value;
+ /* These all set busyerror if already busy. */
+ if (sb_busy()) {
+ sbcs.sbbusyerror = true;
+ } else {
+ switch (address) {
+ case DM_SBADDRESS0:
+ sbaddress[0] = value;
+ if (sbcs.error == 0 && sbcs.readonaddr) {
+ sb_read_start();
+ }
+ return true;
+ case DM_SBADDRESS1:
+ sbaddress[1] = value;
+ return true;
+ case DM_SBADDRESS2:
+ sbaddress[2] = value;
+ return true;
+ case DM_SBADDRESS3:
+ sbaddress[3] = value;
+ return true;
+ case DM_SBDATA0:
+ sbdata[0] = value;
+ if (sbcs.error == 0) {
+ sb_write_start();
+ }
+ return true;
+ case DM_SBDATA1:
+ sbdata[1] = value;
+ return true;
+ case DM_SBDATA2:
+ sbdata[2] = value;
+ return true;
+ case DM_SBDATA3:
+ sbdata[3] = value;
+ return true;
+ }
+ }
return true;
case DM_AUTHDATA:
D(fprintf(stderr, "debug authentication: got 0x%x; 0x%x unlocks\n", value,
@@ -955,5 +1030,5 @@ hart_debug_state_t& debug_module_t::selected_hart_state()
size_t debug_module_t::selected_hart_id() const
{
- return sim->get_cfg().hartids().at(dmcontrol.hartsel);
+ return sim->get_cfg().hartids.at(dmcontrol.hartsel);
}
diff --git a/riscv/debug_module.h b/riscv/debug_module.h
index 73bb7fa..bca29b2 100644
--- a/riscv/debug_module.h
+++ b/riscv/debug_module.h
@@ -14,15 +14,15 @@ class processor_t;
typedef struct {
// Size of program_buffer in 32-bit words, as exposed to the rest of the
// world.
- unsigned progbufsize;
- unsigned max_sba_data_width;
- bool require_authentication;
- unsigned abstract_rti;
- bool support_hasel;
- bool support_abstract_csr_access;
- bool support_abstract_fpr_access;
- bool support_haltgroups;
- bool support_impebreak;
+ unsigned progbufsize = 2;
+ unsigned max_sba_data_width = 0;
+ bool require_authentication = false;
+ unsigned abstract_rti = 0;
+ bool support_hasel = true;
+ bool support_abstract_csr_access = true;
+ bool support_abstract_fpr_access = true;
+ bool support_haltgroups = true;
+ bool support_impebreak = true;
} debug_module_config_t;
typedef struct {
@@ -89,6 +89,7 @@ typedef struct {
bool access32;
bool access16;
bool access8;
+ bool sbbusyerror;
} sbcs_t;
typedef struct {
@@ -157,8 +158,19 @@ class debug_module_t : public abstract_device_t
uint32_t read32(uint8_t *rom, unsigned int index);
void sb_autoincrement();
+
+ /* Start a system bus access. (It could be instantaneous, but to help test
+ * OpenOCD a delay can be added.) */
+ void sb_read_start();
+ void sb_write_start();
+
+ /* Actually read/write. */
void sb_read();
void sb_write();
+
+ /* Return true iff a system bus access is in progress. */
+ bool sb_busy() const;
+
unsigned sb_access_bits();
dmcontrol_t dmcontrol;
@@ -191,6 +203,8 @@ class debug_module_t : public abstract_device_t
* available. Otherwise it is unavailable. */
bool hart_available_state[2];
bool hart_available(unsigned hart_id) const;
+
+ unsigned sb_read_wait, sb_write_wait;
};
#endif
diff --git a/riscv/encoding.h b/riscv/encoding.h
index 81d829c..78318a6 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 (37413c8)
+ * https://github.com/riscv/riscv-opcodes (61d2ef4)
*/
#ifndef RISCV_CSR_ENCODING_H
@@ -29,6 +29,7 @@
#define MSTATUS_TVM 0x00100000
#define MSTATUS_TW 0x00200000
#define MSTATUS_TSR 0x00400000
+#define MSTATUS_SPELP 0x00800000
#define MSTATUS32_SD 0x80000000
#define MSTATUS_UXL 0x0000000300000000
#define MSTATUS_SXL 0x0000000C00000000
@@ -36,6 +37,7 @@
#define MSTATUS_MBE 0x0000002000000000
#define MSTATUS_GVA 0x0000004000000000
#define MSTATUS_MPV 0x0000008000000000
+#define MSTATUS_MPELP 0x0000020000000000
#define MSTATUS64_SD 0x8000000000000000
#define MSTATUSH_SBE 0x00000010
@@ -54,6 +56,7 @@
#define SSTATUS_XS 0x00018000
#define SSTATUS_SUM 0x00040000
#define SSTATUS_MXR 0x00080000
+#define SSTATUS_SPELP 0x00800000
#define SSTATUS32_SD 0x80000000
#define SSTATUS_UXL 0x0000000300000000
#define SSTATUS64_SD 0x8000000000000000
@@ -79,6 +82,7 @@
#define DCSR_XDEBUGVER (3U<<30)
#define DCSR_NDRESET (1<<29)
#define DCSR_FULLRESET (1<<28)
+#define DCSR_PELP (1<<18)
#define DCSR_EBREAKM (1<<15)
#define DCSR_EBREAKH (1<<14)
#define DCSR_EBREAKS (1<<13)
@@ -157,6 +161,8 @@
#define SIP_STIP MIP_STIP
#define MENVCFG_FIOM 0x00000001
+#define MENVCFG_LPE 0x00000004
+#define MENVCFG_SSE 0x00000008
#define MENVCFG_CBIE 0x00000030
#define MENVCFG_CBCFE 0x00000040
#define MENVCFG_CBZE 0x00000080
@@ -195,6 +201,8 @@
#define MHPMEVENTH_OF 0x80000000
#define HENVCFG_FIOM 0x00000001
+#define HENVCFG_LPE 0x00000004
+#define HENVCFG_SSE 0x00000008
#define HENVCFG_CBIE 0x00000030
#define HENVCFG_CBCFE 0x00000040
#define HENVCFG_CBZE 0x00000080
@@ -230,6 +238,8 @@
#define HSTATEENH_SSTATEEN 0x80000000
#define SENVCFG_FIOM 0x00000001
+#define SENVCFG_LPE 0x00000004
+#define SENVCFG_SSE 0x00000008
#define SENVCFG_CBIE 0x00000030
#define SENVCFG_CBCFE 0x00000040
#define SENVCFG_CBZE 0x00000080
@@ -243,6 +253,7 @@
#define MSECCFG_RLB 0x00000004
#define MSECCFG_USEED 0x00000100
#define MSECCFG_SSEED 0x00000200
+#define MSECCFG_MLPE 0x00000400
/* jvt fields */
#define JVT_MODE 0x3F
@@ -682,6 +693,10 @@
#define MASK_C_SRAI 0xec03
#define MATCH_C_SRLI 0x8001
#define MASK_C_SRLI 0xec03
+#define MATCH_C_SSPOPCHK_X5 0x6281
+#define MASK_C_SSPOPCHK_X5 0xffff
+#define MATCH_C_SSPUSH_X1 0x6081
+#define MASK_C_SSPUSH_X1 0xffff
#define MATCH_C_SUB 0x8c01
#define MASK_C_SUB 0xfc63
#define MATCH_C_SUBW 0x9c01
@@ -1990,6 +2005,20 @@
#define MASK_SROIW 0xfe00707f
#define MATCH_SROW 0x2000503b
#define MASK_SROW 0xfe00707f
+#define MATCH_SSAMOSWAP_D 0x4800302f
+#define MASK_SSAMOSWAP_D 0xf800707f
+#define MATCH_SSAMOSWAP_W 0x4800202f
+#define MASK_SSAMOSWAP_W 0xf800707f
+#define MATCH_SSPOPCHK_X1 0xcdc0c073
+#define MASK_SSPOPCHK_X1 0xffffffff
+#define MATCH_SSPOPCHK_X5 0xcdc2c073
+#define MASK_SSPOPCHK_X5 0xffffffff
+#define MATCH_SSPUSH_X1 0xce104073
+#define MASK_SSPUSH_X1 0xffffffff
+#define MATCH_SSPUSH_X5 0xce504073
+#define MASK_SSPUSH_X5 0xffffffff
+#define MATCH_SSRDP 0xcdc04073
+#define MASK_SSRDP 0xfffff07f
#define MATCH_STAS16 0xf4002077
#define MASK_STAS16 0xfe00707f
#define MATCH_STAS32 0xf0002077
@@ -3102,6 +3131,7 @@
#define CSR_VXSAT 0x9
#define CSR_VXRM 0xa
#define CSR_VCSR 0xf
+#define CSR_SSP 0x11
#define CSR_SEED 0x15
#define CSR_JVT 0x17
#define CSR_CYCLE 0xc00
@@ -3560,6 +3590,8 @@
#define CAUSE_FETCH_PAGE_FAULT 0xc
#define CAUSE_LOAD_PAGE_FAULT 0xd
#define CAUSE_STORE_PAGE_FAULT 0xf
+#define CAUSE_SOFTWARE_CHECK_FAULT 0x12
+#define CAUSE_HARDWARE_ERROR_FAULT 0x13
#define CAUSE_FETCH_GUEST_PAGE_FAULT 0x14
#define CAUSE_LOAD_GUEST_PAGE_FAULT 0x15
#define CAUSE_VIRTUAL_INSTRUCTION 0x16
@@ -3823,6 +3855,8 @@ DECLARE_INSN(c_sq, MATCH_C_SQ, MASK_C_SQ)
DECLARE_INSN(c_sqsp, MATCH_C_SQSP, MASK_C_SQSP)
DECLARE_INSN(c_srai, MATCH_C_SRAI, MASK_C_SRAI)
DECLARE_INSN(c_srli, MATCH_C_SRLI, MASK_C_SRLI)
+DECLARE_INSN(c_sspopchk_x5, MATCH_C_SSPOPCHK_X5, MASK_C_SSPOPCHK_X5)
+DECLARE_INSN(c_sspush_x1, MATCH_C_SSPUSH_X1, MASK_C_SSPUSH_X1)
DECLARE_INSN(c_sub, MATCH_C_SUB, MASK_C_SUB)
DECLARE_INSN(c_subw, MATCH_C_SUBW, MASK_C_SUBW)
DECLARE_INSN(c_sw, MATCH_C_SW, MASK_C_SW)
@@ -4477,6 +4511,13 @@ DECLARE_INSN(sro, MATCH_SRO, MASK_SRO)
DECLARE_INSN(sroi, MATCH_SROI, MASK_SROI)
DECLARE_INSN(sroiw, MATCH_SROIW, MASK_SROIW)
DECLARE_INSN(srow, MATCH_SROW, MASK_SROW)
+DECLARE_INSN(ssamoswap_d, MATCH_SSAMOSWAP_D, MASK_SSAMOSWAP_D)
+DECLARE_INSN(ssamoswap_w, MATCH_SSAMOSWAP_W, MASK_SSAMOSWAP_W)
+DECLARE_INSN(sspopchk_x1, MATCH_SSPOPCHK_X1, MASK_SSPOPCHK_X1)
+DECLARE_INSN(sspopchk_x5, MATCH_SSPOPCHK_X5, MASK_SSPOPCHK_X5)
+DECLARE_INSN(sspush_x1, MATCH_SSPUSH_X1, MASK_SSPUSH_X1)
+DECLARE_INSN(sspush_x5, MATCH_SSPUSH_X5, MASK_SSPUSH_X5)
+DECLARE_INSN(ssrdp, MATCH_SSRDP, MASK_SSRDP)
DECLARE_INSN(stas16, MATCH_STAS16, MASK_STAS16)
DECLARE_INSN(stas32, MATCH_STAS32, MASK_STAS32)
DECLARE_INSN(stsa16, MATCH_STSA16, MASK_STSA16)
@@ -5038,6 +5079,7 @@ DECLARE_CSR(vstart, CSR_VSTART)
DECLARE_CSR(vxsat, CSR_VXSAT)
DECLARE_CSR(vxrm, CSR_VXRM)
DECLARE_CSR(vcsr, CSR_VCSR)
+DECLARE_CSR(ssp, CSR_SSP)
DECLARE_CSR(seed, CSR_SEED)
DECLARE_CSR(jvt, CSR_JVT)
DECLARE_CSR(cycle, CSR_CYCLE)
@@ -5497,6 +5539,8 @@ DECLARE_CAUSE("machine_ecall", CAUSE_MACHINE_ECALL)
DECLARE_CAUSE("fetch page fault", CAUSE_FETCH_PAGE_FAULT)
DECLARE_CAUSE("load page fault", CAUSE_LOAD_PAGE_FAULT)
DECLARE_CAUSE("store page fault", CAUSE_STORE_PAGE_FAULT)
+DECLARE_CAUSE("software check fault", CAUSE_SOFTWARE_CHECK_FAULT)
+DECLARE_CAUSE("hardware error fault", CAUSE_HARDWARE_ERROR_FAULT)
DECLARE_CAUSE("fetch guest page fault", CAUSE_FETCH_GUEST_PAGE_FAULT)
DECLARE_CAUSE("load guest page fault", CAUSE_LOAD_GUEST_PAGE_FAULT)
DECLARE_CAUSE("virtual instruction", CAUSE_VIRTUAL_INSTRUCTION)
diff --git a/riscv/insns/fmvh_x_d.h b/riscv/insns/fmvh_x_d.h
index 961ad76..28abb60 100644
--- a/riscv/insns/fmvh_x_d.h
+++ b/riscv/insns/fmvh_x_d.h
@@ -4,4 +4,4 @@ require_extension(EXT_ZFA);
require_fp;
ui64_f64 ui;
ui.f = FRS1_D;
-WRITE_RD(ui.ui >> 32);
+WRITE_RD(sext32(ui.ui >> 32));
diff --git a/riscv/insns/fmvp_d_x.h b/riscv/insns/fmvp_d_x.h
index f95cfe9..95d786a 100644
--- a/riscv/insns/fmvp_d_x.h
+++ b/riscv/insns/fmvp_d_x.h
@@ -4,5 +4,5 @@ require_extension(EXT_ZFA);
require_fp;
ui64_f64 ui;
ui.ui = ((uint64_t)RS2) << 32;
-ui.ui |= RS1;
+ui.ui |= zext32(RS1);
WRITE_FRD_D(f64(ui.ui));
diff --git a/riscv/insns/mop_r_N.h b/riscv/insns/mop_r_N.h
new file mode 100644
index 0000000..fa2687e
--- /dev/null
+++ b/riscv/insns/mop_r_N.h
@@ -0,0 +1,2 @@
+require_extension(EXT_ZIMOP);
+WRITE_RD(0);
diff --git a/riscv/insns/mop_rr_N.h b/riscv/insns/mop_rr_N.h
new file mode 100644
index 0000000..fa2687e
--- /dev/null
+++ b/riscv/insns/mop_rr_N.h
@@ -0,0 +1,2 @@
+require_extension(EXT_ZIMOP);
+WRITE_RD(0);
diff --git a/riscv/isa_parser.h b/riscv/isa_parser.h
index a84b6fe..7773ba5 100644
--- a/riscv/isa_parser.h
+++ b/riscv/isa_parser.h
@@ -81,6 +81,7 @@ typedef enum {
EXT_SMCSRIND,
EXT_SSCSRIND,
EXT_SMCNTRPMF,
+ EXT_ZIMOP,
EXT_ZCMOP,
EXT_ZALASR,
NUM_ISA_EXTENSIONS
diff --git a/riscv/ns16550.cc b/riscv/ns16550.cc
index dabe3a9..a74aa74 100644
--- a/riscv/ns16550.cc
+++ b/riscv/ns16550.cc
@@ -341,7 +341,7 @@ std::string ns16550_generate_dts(const sim_t* sim)
return s.str();
}
-ns16550_t* ns16550_parse_from_fdt(const void* fdt, const sim_t* sim, reg_t* base)
+ns16550_t* ns16550_parse_from_fdt(const void* fdt, const sim_t* sim, reg_t* base, const std::vector<std::string>& sargs)
{
uint32_t ns16550_shift, ns16550_io_width, ns16550_int_id;
if (fdt_parse_ns16550(fdt, base,
diff --git a/riscv/plic.cc b/riscv/plic.cc
index 1aa5852..57c37c5 100644
--- a/riscv/plic.cc
+++ b/riscv/plic.cc
@@ -415,7 +415,7 @@ std::string plic_generate_dts(const sim_t* sim)
return s.str();
}
-plic_t* plic_parse_from_fdt(const void* fdt, const sim_t* sim, reg_t* base)
+plic_t* plic_parse_from_fdt(const void* fdt, const sim_t* sim, reg_t* base, const std::vector<std::string>& sargs)
{
uint32_t plic_ndev;
if (fdt_parse_plic(fdt, base, &plic_ndev, "riscv,plic0") == 0)
diff --git a/riscv/processor.cc b/riscv/processor.cc
index 0ac6e67..1bb1fc9 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -54,7 +54,7 @@ processor_t::processor_t(const isa_parser_t *isa, const cfg_t *cfg,
}
#endif
- parse_varch_string(cfg->varch());
+ parse_varch_string(cfg->varch);
register_base_instructions();
mmu = new mmu_t(sim, cfg->endianness, this);
@@ -535,14 +535,14 @@ void state_t::reset(processor_t* const proc, reg_t max_isa)
// 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)) {
+ csr_t_p miselect = std::make_shared<basic_csr_t>(proc, CSR_MISELECT, 0);
+ csrmap[CSR_MISELECT] = miselect;
+
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) {
@@ -552,9 +552,9 @@ void state_t::reset(processor_t* const proc, reg_t max_isa)
}
if (proc->extension_enabled_const(EXT_SSCSRIND)) {
- vsiselect = std::make_shared<basic_csr_t>(proc, CSR_VSISELECT, 0);
+ csr_t_p 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);
+ csr_t_p 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 };
diff --git a/riscv/remote_bitbang.cc b/riscv/remote_bitbang.cc
index 8453e85..182b371 100644
--- a/riscv/remote_bitbang.cc
+++ b/riscv/remote_bitbang.cc
@@ -106,7 +106,6 @@ void remote_bitbang_t::tick()
void remote_bitbang_t::execute_commands()
{
- static char send_buf[buf_size];
unsigned total_processed = 0;
bool quit = false;
bool in_rti = tap->state() == RUN_TEST_IDLE;
diff --git a/riscv/remote_bitbang.h b/riscv/remote_bitbang.h
index 1db4d55..b5b73bf 100644
--- a/riscv/remote_bitbang.h
+++ b/riscv/remote_bitbang.h
@@ -22,6 +22,7 @@ private:
int client_fd;
static const ssize_t buf_size = 64 * 1024;
+ char send_buf[buf_size];
char recv_buf[buf_size];
ssize_t recv_start, recv_end;
diff --git a/riscv/riscv.mk.in b/riscv/riscv.mk.in
index 76c2ed7..04747c9 100644
--- a/riscv/riscv.mk.in
+++ b/riscv/riscv.mk.in
@@ -1388,6 +1388,10 @@ riscv_insn_ext_zvksh = \
vsm3c_vi \
vsm3me_vv \
+riscv_insn_ext_zimop = \
+ mop_r_N \
+ mop_rr_N \
+
riscv_insn_ext_zvk = \
$(riscv_insn_ext_zvbb) \
$(riscv_insn_ext_zvbc) \
@@ -1426,6 +1430,7 @@ riscv_insn_list = \
$(riscv_insn_priv) \
$(riscv_insn_smrnmi) \
$(riscv_insn_svinval) \
+ $(riscv_insn_ext_zimop) \
riscv_gen_srcs = $(addsuffix .cc,$(riscv_insn_list))
diff --git a/riscv/sim.cc b/riscv/sim.cc
index d75de46..57e9630 100644
--- a/riscv/sim.cc
+++ b/riscv/sim.cc
@@ -38,7 +38,7 @@ extern device_factory_t* ns16550_factory;
sim_t::sim_t(const cfg_t *cfg, bool halted,
std::vector<std::pair<reg_t, abstract_mem_t*>> mems,
- std::vector<const device_factory_t*> plugin_device_factories,
+ std::vector<device_factory_t*> plugin_device_factories,
const std::vector<std::string>& args,
const debug_module_config_t &dm_config,
const char *log_path,
@@ -46,7 +46,7 @@ sim_t::sim_t(const cfg_t *cfg, bool halted,
bool socket_enabled,
FILE *cmd_file) // needed for command line option --cmd
: htif_t(args),
- isa(cfg->isa(), cfg->priv()),
+ isa(cfg->isa, cfg->priv),
cfg(cfg),
mems(mems),
procs(std::max(cfg->nprocs(), size_t(1))),
@@ -99,9 +99,9 @@ sim_t::sim_t(const cfg_t *cfg, bool halted,
debug_mmu = new mmu_t(this, cfg->endianness, NULL);
for (size_t i = 0; i < cfg->nprocs(); i++) {
- procs[i] = new processor_t(&isa, cfg, this, cfg->hartids()[i], halted,
+ procs[i] = new processor_t(&isa, cfg, this, cfg->hartids[i], halted,
log_file.get(), sout_);
- harts[cfg->hartids()[i]] = procs[i];
+ harts[cfg->hartids[i]] = procs[i];
}
// When running without using a dtb, skip the fdt-based configuration steps
@@ -134,13 +134,13 @@ sim_t::sim_t(const cfg_t *cfg, bool halted,
strstream << fin.rdbuf();
dtb = strstream.str();
} else {
- std::pair<reg_t, reg_t> initrd_bounds = cfg->initrd_bounds();
+ std::pair<reg_t, reg_t> initrd_bounds = cfg->initrd_bounds;
std::string device_nodes;
for (const device_factory_t *factory : device_factories)
device_nodes.append(factory->generate_dts(this));
dts = make_dts(INSNS_PER_RTC_TICK, CPU_HZ,
initrd_bounds.first, initrd_bounds.second,
- cfg->bootargs(), cfg->pmpregions, cfg->pmpgranularity,
+ cfg->bootargs, cfg->pmpregions, cfg->pmpgranularity,
procs, mems, device_nodes);
dtb = dts_compile(dts);
}
diff --git a/riscv/sim.h b/riscv/sim.h
index 2455263..efe5f83 100644
--- a/riscv/sim.h
+++ b/riscv/sim.h
@@ -27,7 +27,7 @@ class sim_t : public htif_t, public simif_t
public:
sim_t(const cfg_t *cfg, bool halted,
std::vector<std::pair<reg_t, abstract_mem_t*>> mems,
- std::vector<const device_factory_t*> plugin_device_factories,
+ std::vector<device_factory_t*> plugin_device_factories,
const std::vector<std::string>& args,
const debug_module_config_t &dm_config, const char *log_path,
bool dtb_enabled, const char *dtb_file,
diff --git a/spike_main/spike-log-parser.cc b/spike_main/spike-log-parser.cc
index 6ac4ab0..a054e95 100644
--- a/spike_main/spike-log-parser.cc
+++ b/spike_main/spike-log-parser.cc
@@ -28,19 +28,7 @@ int main(int UNUSED argc, char** argv)
parser.option(0, "isa", 1, [&](const char* s){isa_string = s;});
parser.parse(argv);
- cfg_t cfg(/*default_initrd_bounds=*/std::make_pair((reg_t)0, (reg_t)0),
- /*default_bootargs=*/nullptr,
- /*default_isa=*/DEFAULT_ISA,
- /*default_priv=*/DEFAULT_PRIV,
- /*default_varch=*/DEFAULT_VARCH,
- /*default_misaligned=*/false,
- /*default_endianness*/endianness_little,
- /*default_pmpregions=*/16,
- /*default_pmpgranularity=*/(1 << PMP_SHIFT),
- /*default_mem_layout=*/std::vector<mem_cfg_t>(),
- /*default_hartids=*/std::vector<size_t>(),
- /*default_real_time_clint=*/false,
- /*default_trigger_count=*/4);
+ cfg_t cfg;
isa_parser_t isa(isa_string, DEFAULT_PRIV);
processor_t p(&isa, &cfg, 0, 0, false, nullptr, cerr);
diff --git a/spike_main/spike.cc b/spike_main/spike.cc
index 8fd9104..b5a1ce4 100644
--- a/spike_main/spike.cc
+++ b/spike_main/spike.cc
@@ -10,6 +10,7 @@
#include "extension.h"
#include <dlfcn.h>
#include <fesvr/option_parser.h>
+#include <stdexcept>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
@@ -18,6 +19,7 @@
#include <fstream>
#include <limits>
#include <cinttypes>
+#include <sstream>
#include "../VERSION"
static void help(int exit_code = 1)
@@ -332,7 +334,7 @@ int main(int argc, char** argv)
bool dtb_enabled = true;
const char* kernel = NULL;
reg_t kernel_offset, kernel_size;
- std::vector<const device_factory_t*> plugin_device_factories;
+ std::vector<device_factory_t*> plugin_device_factories;
std::unique_ptr<icache_sim_t> ic;
std::unique_ptr<dcache_sim_t> dc;
std::unique_ptr<cache_sim_t> l2;
@@ -346,38 +348,30 @@ int main(int argc, char** argv)
bool use_rbb = false;
unsigned dmi_rti = 0;
reg_t blocksz = 64;
- debug_module_config_t dm_config = {
- .progbufsize = 2,
- .max_sba_data_width = 0,
- .require_authentication = false,
- .abstract_rti = 0,
- .support_hasel = true,
- .support_abstract_csr_access = true,
- .support_abstract_fpr_access = true,
- .support_haltgroups = true,
- .support_impebreak = true
- };
+ debug_module_config_t dm_config;
cfg_arg_t<size_t> nprocs(1);
- cfg_t cfg(/*default_initrd_bounds=*/std::make_pair((reg_t)0, (reg_t)0),
- /*default_bootargs=*/nullptr,
- /*default_isa=*/DEFAULT_ISA,
- /*default_priv=*/DEFAULT_PRIV,
- /*default_varch=*/DEFAULT_VARCH,
- /*default_misaligned=*/false,
- /*default_endianness*/endianness_little,
- /*default_pmpregions=*/16,
- /*default_pmpgranularity=*/(1 << PMP_SHIFT),
- /*default_mem_layout=*/parse_mem_layout("2048"),
- /*default_hartids=*/std::vector<size_t>(),
- /*default_real_time_clint=*/false,
- /*default_trigger_count=*/4);
+ cfg_t cfg;
auto const device_parser = [&plugin_device_factories](const char *s) {
- const std::string name(s);
+ const std::string device_args(s);
+ std::vector<std::string> parsed_args;
+ std::stringstream sstr(device_args);
+ while (sstr.good()) {
+ std::string substr;
+ getline(sstr, substr, ',');
+ parsed_args.push_back(substr);
+ }
+ if (parsed_args.empty()) throw std::runtime_error("Plugin argument is empty.");
+
+ const std::string name = parsed_args[0];
if (name.empty()) throw std::runtime_error("Plugin name is empty.");
+
auto it = mmio_device_map().find(name);
if (it == mmio_device_map().end()) throw std::runtime_error("Plugin \"" + name + "\" not found in loaded extlibs.");
+
+ parsed_args.erase(parsed_args.begin());
+ it->second->set_sargs(parsed_args);
plugin_device_factories.push_back(it->second);
};
@@ -477,10 +471,10 @@ int main(int argc, char** argv)
help();
std::vector<std::pair<reg_t, abstract_mem_t*>> mems =
- make_mems(cfg.mem_layout());
+ make_mems(cfg.mem_layout);
if (kernel && check_file_exists(kernel)) {
- const char *isa = cfg.isa();
+ const char *isa = cfg.isa;
kernel_size = get_file_size(kernel);
if (isa[2] == '6' && isa[3] == '4')
kernel_offset = 0x200000;