diff options
-rw-r--r-- | riscv/csrs.cc | 4 | ||||
-rw-r--r-- | riscv/dts.cc | 4 | ||||
-rw-r--r-- | riscv/insns/vmv_x_s.h | 4 | ||||
-rw-r--r-- | riscv/interactive.cc | 8 | ||||
-rw-r--r-- | riscv/processor.cc | 27 | ||||
-rw-r--r-- | riscv/processor.h | 17 | ||||
-rw-r--r-- | riscv/sim.cc | 5 | ||||
-rw-r--r-- | riscv/sim.h | 1 | ||||
-rw-r--r-- | spike_main/spike-log-parser.cc | 7 |
9 files changed, 46 insertions, 31 deletions
diff --git a/riscv/csrs.cc b/riscv/csrs.cc index 44fd959..5e8c0ba 100644 --- a/riscv/csrs.cc +++ b/riscv/csrs.cc @@ -304,8 +304,8 @@ reg_t cause_csr_t::read() const noexcept { // When reading, the interrupt bit needs to adjust to xlen. Spike does // not generally support dynamic xlen, but this code was (partly) // there since at least 2015 (ea58df8 and c4350ef). - if (proc->get_max_xlen() > proc->get_xlen()) // Move interrupt bit to top of xlen - return val | ((val >> (proc->get_max_xlen()-1)) << (proc->get_xlen()-1)); + if (proc->get_isa().get_max_xlen() > proc->get_xlen()) // Move interrupt bit to top of xlen + return val | ((val >> (proc->get_isa().get_max_xlen()-1)) << (proc->get_xlen()-1)); return val; } diff --git a/riscv/dts.cc b/riscv/dts.cc index 09accf9..c86fc2f 100644 --- a/riscv/dts.cc +++ b/riscv/dts.cc @@ -55,8 +55,8 @@ std::string make_dts(size_t insns_per_rtc_tick, size_t cpu_hz, " reg = <" << i << ">;\n" " status = \"okay\";\n" " compatible = \"riscv\";\n" - " riscv,isa = \"" << procs[i]->get_isa_string() << "\";\n" - " mmu-type = \"riscv," << (procs[i]->get_max_xlen() <= 32 ? "sv32" : "sv48") << "\";\n" + " riscv,isa = \"" << procs[i]->get_isa().get_isa_string() << "\";\n" + " mmu-type = \"riscv," << (procs[i]->get_isa().get_max_xlen() <= 32 ? "sv32" : "sv48") << "\";\n" " riscv,pmpregions = <16>;\n" " riscv,pmpgranularity = <4>;\n" " clock-frequency = <" << cpu_hz << ">;\n" diff --git a/riscv/insns/vmv_x_s.h b/riscv/insns/vmv_x_s.h index 39752f9..f0e805b 100644 --- a/riscv/insns/vmv_x_s.h +++ b/riscv/insns/vmv_x_s.h @@ -1,7 +1,7 @@ // vmv_x_s: rd = vs2[rs1] require_vector(true); require(insn.v_vm() == 1); -uint64_t xmask = UINT64_MAX >> (64 - P.get_max_xlen()); +uint64_t xmask = UINT64_MAX >> (64 - P.get_isa().get_max_xlen()); reg_t rs1 = RS1; reg_t sew = P.VU.vsew; reg_t rs2_num = insn.rs2(); @@ -20,7 +20,7 @@ if (!(rs1 >= 0 && rs1 < (P.VU.get_vlen() / sew))) { WRITE_RD(P.VU.elt<int32_t>(rs2_num, rs1)); break; case e64: - if (P.get_max_xlen() <= sew) + if (P.get_isa().get_max_xlen() <= sew) WRITE_RD(P.VU.elt<uint64_t>(rs2_num, rs1) & xmask); else WRITE_RD(P.VU.elt<uint64_t>(rs2_num, rs1)); diff --git a/riscv/interactive.cc b/riscv/interactive.cc index 172cd33..88eb86b 100644 --- a/riscv/interactive.cc +++ b/riscv/interactive.cc @@ -273,7 +273,7 @@ void sim_t::interactive_pc(const std::string& cmd, const std::vector<std::string throw trap_interactive(); processor_t *p = get_core(args[0]); - int max_xlen = p->get_max_xlen(); + int max_xlen = p->get_isa().get_max_xlen(); std::ostream out(sout_.rdbuf()); out << std::hex << std::setfill('0') << "0x" << std::setw(max_xlen/4) @@ -379,7 +379,7 @@ void sim_t::interactive_reg(const std::string& cmd, const std::vector<std::strin throw trap_interactive(); processor_t *p = get_core(args[0]); - int max_xlen = p->get_max_xlen(); + int max_xlen = p->get_isa().get_max_xlen(); std::ostream out(sout_.rdbuf()); out << std::hex; @@ -481,7 +481,7 @@ reg_t sim_t::get_mem(const std::vector<std::string>& args) void sim_t::interactive_mem(const std::string& cmd, const std::vector<std::string>& args) { - int max_xlen = procs[0]->get_max_xlen(); + int max_xlen = procs[0]->get_isa().get_max_xlen(); std::ostream out(sout_.rdbuf()); out << std::hex << "0x" << std::setfill('0') << std::setw(max_xlen/4) @@ -541,7 +541,7 @@ void sim_t::interactive_until(const std::string& cmd, const std::vector<std::str throw trap_interactive(); // mask bits above max_xlen - int max_xlen = procs[strtol(args[1].c_str(),NULL,10)]->get_max_xlen(); + int max_xlen = procs[strtol(args[1].c_str(),NULL,10)]->get_isa().get_max_xlen(); if (max_xlen == 32) val &= 0xFFFFFFFF; std::vector<std::string> args2; diff --git a/riscv/processor.cc b/riscv/processor.cc index 438c989..dfb85da 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -23,10 +23,10 @@ #undef STATE #define STATE state -processor_t::processor_t(const char* isa, const char* priv, const char* varch, +processor_t::processor_t(isa_parser_t isa, const char* varch, simif_t* sim, uint32_t id, bool halt_on_reset, FILE* log_file, std::ostream& sout_) - : isa_parser_t(isa, priv), debug(false), halt_request(HR_NONE), sim(sim), id(id), xlen(0), + : debug(false), halt_request(HR_NONE), isa(isa), sim(sim), id(id), xlen(0), histogram_enabled(false), log_commits_enabled(false), log_file(log_file), sout_(sout_.rdbuf()), halt_on_reset(halt_on_reset), impl_table(256, false), last_pc(1), executions(1) @@ -45,16 +45,16 @@ processor_t::processor_t(const char* isa, const char* priv, const char* varch, register_base_instructions(); mmu = new mmu_t(sim, this); - disassembler = new disassembler_t(this); - for (auto e : isa_extensions) + disassembler = new disassembler_t(&isa); + for (auto e : isa.get_extensions()) register_extension(e.second); set_pmp_granularity(1 << PMP_SHIFT); set_pmp_num(state.max_pmp); - if (max_xlen == 32) + if (isa.get_max_xlen() == 32) set_mmu_capability(IMPL_MMU_SV32); - else if (max_xlen == 64) + else if (isa.get_max_xlen() == 64) set_mmu_capability(IMPL_MMU_SV48); reset(); @@ -355,7 +355,7 @@ isa_parser_t::isa_parser_t(const char* str, const char *priv) bad_isa_string(str, "single 'X' is not a proper name"); } else if (ext_str != "xdummy") { extension_t* x = find_extension(ext_str.substr(1).c_str())(); - if (!isa_extensions.insert(std::make_pair(x->name(), x)).second) { + if (!extensions.insert(std::make_pair(x->name(), x)).second) { fprintf(stderr, "extensions must have unique names (got two named \"%s\"!)\n", x->name()); abort(); } @@ -411,7 +411,7 @@ void state_t::reset(processor_t* const proc, reg_t max_isa) // This assumes xlen is always max_xlen, which is true today (see // mstatus_csr_t::unlogged_write()): - auto xlen = proc->get_max_xlen(); + auto xlen = proc->get_isa().get_max_xlen(); prv = PRV_M; v = false; @@ -716,8 +716,8 @@ void processor_t::enable_log_commits() void processor_t::reset() { - xlen = max_xlen; - state.reset(this, max_isa); + xlen = isa.get_max_xlen(); + state.reset(this, isa.get_max_isa()); state.dcsr->halt = halt_on_reset; halt_on_reset = false; VU.reset(); @@ -852,7 +852,7 @@ void processor_t::take_interrupt(reg_t pending_interrupts) else abort(); - throw trap_t(((reg_t)1 << (max_xlen-1)) | ctz(enabled_interrupts)); + throw trap_t(((reg_t)1 << (isa.get_max_xlen()-1)) | ctz(enabled_interrupts)); } } @@ -916,6 +916,8 @@ void processor_t::debug_output_log(std::stringstream *s) void processor_t::take_trap(trap_t& t, reg_t epc) { + unsigned max_xlen = isa.get_max_xlen(); + if (debug) { std::stringstream s; // first put everything in a string, later send it to output s << "core " << std::dec << std::setfill(' ') << std::setw(3) << id @@ -1039,6 +1041,8 @@ void processor_t::disasm(insn_t insn) << ": Executed " << executions << " times" << std::endl; } + unsigned max_xlen = isa.get_max_xlen(); + s << "core " << std::dec << std::setfill(' ') << std::setw(3) << id << std::hex << ": 0x" << std::setfill('0') << std::setw(max_xlen/4) << zext(state.pc, max_xlen) << " (0x" << std::setw(8) << bits << ") " @@ -1056,6 +1060,7 @@ void processor_t::disasm(insn_t insn) int processor_t::paddr_bits() { + unsigned max_xlen = isa.get_max_xlen(); assert(xlen == max_xlen); return max_xlen == 64 ? 50 : 34; } diff --git a/riscv/processor.h b/riscv/processor.h index 2fe5ede..3e9a743 100644 --- a/riscv/processor.h +++ b/riscv/processor.h @@ -322,23 +322,28 @@ public: else return extension_table[ext]; } + const std::unordered_map<std::string, extension_t*> & + get_extensions() const { return extensions; } + protected: unsigned max_xlen; reg_t max_isa; std::vector<bool> extension_table; std::string isa_string; - std::unordered_map<std::string, extension_t*> isa_extensions; + std::unordered_map<std::string, extension_t*> extensions; }; // this class represents one processor in a RISC-V machine. -class processor_t : public abstract_device_t, public isa_parser_t +class processor_t : public abstract_device_t { public: - processor_t(const char* isa, const char* priv, const char* varch, + processor_t(isa_parser_t isa, const char* varch, simif_t* sim, uint32_t id, bool halt_on_reset, FILE *log_file, std::ostream& sout_); // because of command line option --log and -s we need both ~processor_t(); + const isa_parser_t &get_isa() { return isa; } + void set_debug(bool value); void set_histogram(bool value); #ifdef RISCV_ENABLE_COMMITLOG @@ -374,7 +379,7 @@ public: if (ext >= 'A' && ext <= 'Z') return state.misa->extension_enabled(ext); else - return extension_table[ext]; + return isa.extension_enabled(ext); } // Is this extension enabled? and abort if this extension can // possibly be disabled dynamically. Useful for documenting @@ -383,7 +388,7 @@ public: if (ext >= 'A' && ext <= 'Z') return state.misa->extension_enabled_const(ext); else - return extension_table[ext]; // assume this can't change + return isa.extension_enabled(ext); // assume this can't change } void set_impl(uint8_t impl, bool val) { impl_table[impl] = val; } bool supports_impl(uint8_t impl) const { @@ -512,6 +517,8 @@ public: const char* get_symbol(uint64_t addr); private: + isa_parser_t isa; + simif_t* sim; mmu_t* mmu; // main memory is always accessed via the mmu std::unordered_map<std::string, extension_t*> custom_extensions; diff --git a/riscv/sim.cc b/riscv/sim.cc index 8648d5a..064a493 100644 --- a/riscv/sim.cc +++ b/riscv/sim.cc @@ -28,7 +28,7 @@ static void handle_signal(int sig) signal(sig, &handle_signal); } -sim_t::sim_t(const char* isa, const char* priv, const char* varch, +sim_t::sim_t(const char* isa_string, const char* priv, const char* varch, size_t nprocs, bool halted, bool real_time_clint, reg_t initrd_start, reg_t initrd_end, const char* bootargs, reg_t start_pc, std::vector<std::pair<reg_t, mem_t*>> mems, @@ -43,6 +43,7 @@ sim_t::sim_t(const char* isa, const char* priv, const char* varch, #endif FILE *cmd_file) // needed for command line option --cmd : htif_t(args), + isa(isa_string, priv), mems(mems), plugin_devices(plugin_devices), procs(std::max(nprocs, size_t(1))), @@ -91,7 +92,7 @@ sim_t::sim_t(const char* isa, const char* priv, const char* varch, for (size_t i = 0; i < nprocs; i++) { int hart_id = hartids.empty() ? i : hartids[i]; - procs[i] = new processor_t(isa, priv, varch, this, hart_id, halted, + procs[i] = new processor_t(isa, varch, this, hart_id, halted, log_file.get(), sout_); } diff --git a/riscv/sim.h b/riscv/sim.h index a425da4..518d75e 100644 --- a/riscv/sim.h +++ b/riscv/sim.h @@ -70,6 +70,7 @@ public: void proc_reset(unsigned id); private: + isa_parser_t isa; std::vector<std::pair<reg_t, mem_t*>> mems; std::vector<std::pair<reg_t, abstract_device_t*>> plugin_devices; mmu_t* debug_mmu; // debug port into main memory diff --git a/spike_main/spike-log-parser.cc b/spike_main/spike-log-parser.cc index 9481fb4..0a4442f 100644 --- a/spike_main/spike-log-parser.cc +++ b/spike_main/spike-log-parser.cc @@ -19,15 +19,16 @@ using namespace std; int main(int argc, char** argv) { string s; - const char* isa = DEFAULT_ISA; + const char* isa_string = DEFAULT_ISA; std::function<extension_t*()> extension; option_parser_t parser; parser.option(0, "extension", 1, [&](const char* s){extension = find_extension(s);}); - parser.option(0, "isa", 1, [&](const char* s){isa = s;}); + parser.option(0, "isa", 1, [&](const char* s){isa_string = s;}); parser.parse(argv); - processor_t p(isa, DEFAULT_PRIV, DEFAULT_VARCH, 0, 0, false, nullptr, cerr); + isa_parser_t isa(isa_string, DEFAULT_PRIV); + processor_t p(isa, DEFAULT_VARCH, 0, 0, false, nullptr, cerr); if (extension) { p.register_extension(extension()); } |