diff options
-rw-r--r-- | .github/workflows/continuous-integration.yml | 4 | ||||
-rw-r--r-- | .github/workflows/debug-smoke.yml | 2 | ||||
-rw-r--r-- | ci-tests/testlib.c | 32 | ||||
-rw-r--r-- | disasm/disasm.cc | 63 | ||||
-rw-r--r-- | disasm/isa_parser.cc | 2 | ||||
-rw-r--r-- | riscv/abstract_device.h | 12 | ||||
-rw-r--r-- | riscv/cfg.cc | 21 | ||||
-rw-r--r-- | riscv/cfg.h | 66 | ||||
-rw-r--r-- | riscv/clint.cc | 5 | ||||
-rw-r--r-- | riscv/csrs.cc | 16 | ||||
-rw-r--r-- | riscv/csrs.h | 1 | ||||
-rw-r--r-- | riscv/debug_module.cc | 143 | ||||
-rw-r--r-- | riscv/debug_module.h | 32 | ||||
-rw-r--r-- | riscv/encoding.h | 46 | ||||
-rw-r--r-- | riscv/insns/fmvh_x_d.h | 2 | ||||
-rw-r--r-- | riscv/insns/fmvp_d_x.h | 2 | ||||
-rw-r--r-- | riscv/insns/mop_r_N.h | 2 | ||||
-rw-r--r-- | riscv/insns/mop_rr_N.h | 2 | ||||
-rw-r--r-- | riscv/isa_parser.h | 1 | ||||
-rw-r--r-- | riscv/ns16550.cc | 2 | ||||
-rw-r--r-- | riscv/plic.cc | 2 | ||||
-rw-r--r-- | riscv/processor.cc | 12 | ||||
-rw-r--r-- | riscv/remote_bitbang.cc | 1 | ||||
-rw-r--r-- | riscv/remote_bitbang.h | 1 | ||||
-rw-r--r-- | riscv/riscv.mk.in | 5 | ||||
-rw-r--r-- | riscv/sim.cc | 12 | ||||
-rw-r--r-- | riscv/sim.h | 2 | ||||
-rw-r--r-- | spike_main/spike-log-parser.cc | 14 | ||||
-rw-r--r-- | spike_main/spike.cc | 50 |
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; |