Implement MHARTID register

This commit is contained in:
Stanislaw Kaushanski 2020-09-04 15:37:21 +02:00
parent 886b8f5716
commit 969b408288
4 changed files with 30 additions and 23 deletions

View File

@ -43,9 +43,9 @@
#ifndef FMT_HEADER_ONLY #ifndef FMT_HEADER_ONLY
#define FMT_HEADER_ONLY #define FMT_HEADER_ONLY
#endif #endif
#include <fmt/format.h>
#include <array> #include <array>
#include <elfio/elfio.hpp> #include <elfio/elfio.hpp>
#include <fmt/format.h>
#include <iomanip> #include <iomanip>
#include <sstream> #include <sstream>
#include <type_traits> #include <type_traits>
@ -266,7 +266,7 @@ public:
trap_store_page_fault(uint64_t badaddr) trap_store_page_fault(uint64_t badaddr)
: trap_access(15 << 16, badaddr) {} : trap_access(15 << 16, badaddr) {}
}; };
} } // namespace
template <typename BASE> class riscv_hart_m_p : public BASE { template <typename BASE> class riscv_hart_m_p : public BASE {
public: public:
@ -392,6 +392,9 @@ public:
virtual uint64_t leave_trap(uint64_t flags) override; virtual uint64_t leave_trap(uint64_t flags) override;
void wait_until(uint64_t flags) override; void wait_until(uint64_t flags) override;
const reg_t& get_mhartid() const { return mhartid_reg; }
void set_mhartid(reg_t mhartid) { mhartid_reg = mhartid; };
void disass_output(uint64_t pc, const std::string instr) override { void disass_output(uint64_t pc, const std::string instr) override {
CLOG(INFO, disass) << fmt::format("0x{:016x} {:40} [p:{};s:0x{:x};c:{}]", CLOG(INFO, disass) << fmt::format("0x{:016x} {:40} [p:{};s:0x{:x};c:{}]",
pc, instr, lvl[this->reg.machine_state], (reg_t)state.mstatus, this->reg.icount); pc, instr, lvl[this->reg.machine_state], (reg_t)state.mstatus, this->reg.icount);
@ -464,6 +467,9 @@ private:
iss::status write_satp(unsigned addr, reg_t val); iss::status write_satp(unsigned addr, reg_t val);
iss::status read_fcsr(unsigned addr, reg_t &val); iss::status read_fcsr(unsigned addr, reg_t &val);
iss::status write_fcsr(unsigned addr, reg_t val); iss::status write_fcsr(unsigned addr, reg_t val);
iss::status read_hartid(unsigned addr, reg_t &val);
reg_t mhartid_reg{0xF};
protected: protected:
void check_interrupt(); void check_interrupt();
@ -507,14 +513,7 @@ riscv_hart_m_p<BASE>::riscv_hart_m_p()
csr_wr_cb[sie] = &riscv_hart_m_p<BASE>::write_ie; csr_wr_cb[sie] = &riscv_hart_m_p<BASE>::write_ie;
csr_rd_cb[uie] = &riscv_hart_m_p<BASE>::read_ie; csr_rd_cb[uie] = &riscv_hart_m_p<BASE>::read_ie;
csr_wr_cb[uie] = &riscv_hart_m_p<BASE>::write_ie; csr_wr_cb[uie] = &riscv_hart_m_p<BASE>::write_ie;
csr_rd_cb[satp] = &riscv_hart_m_p<BASE>::read_satp; csr_rd_cb[mhartid] = &riscv_hart_m_p<BASE>::read_hartid;
csr_wr_cb[satp] = &riscv_hart_m_p<BASE>::write_satp;
csr_rd_cb[fcsr] = &riscv_hart_m_p<BASE>::read_fcsr;
csr_wr_cb[fcsr] = &riscv_hart_m_p<BASE>::write_fcsr;
csr_rd_cb[fflags] = &riscv_hart_m_p<BASE>::read_fcsr;
csr_wr_cb[fflags] = &riscv_hart_m_p<BASE>::write_fcsr;
csr_rd_cb[frm] = &riscv_hart_m_p<BASE>::read_fcsr;
csr_wr_cb[frm] = &riscv_hart_m_p<BASE>::write_fcsr;
} }
template <typename BASE> std::pair<uint64_t, bool> riscv_hart_m_p<BASE>::load_file(std::string name, int type) { template <typename BASE> std::pair<uint64_t, bool> riscv_hart_m_p<BASE>::load_file(std::string name, int type) {
@ -838,6 +837,11 @@ template <typename BASE> iss::status riscv_hart_m_p<BASE>::read_ie(unsigned addr
return iss::Ok; return iss::Ok;
} }
template <typename BASE> iss::status riscv_hart_m_p<BASE>::read_hartid(unsigned addr, reg_t &val) {
val = mhartid_reg;
return iss::Ok;
}
template <typename BASE> iss::status riscv_hart_m_p<BASE>::write_ie(unsigned addr, reg_t val) { template <typename BASE> iss::status riscv_hart_m_p<BASE>::write_ie(unsigned addr, reg_t val) {
auto req_priv_lvl = (addr >> 8) & 0x3; auto req_priv_lvl = (addr >> 8) & 0x3;
auto mask = get_irq_mask(req_priv_lvl); auto mask = get_irq_mask(req_priv_lvl);
@ -1281,7 +1285,7 @@ template <typename BASE> void riscv_hart_m_p<BASE>::wait_until(uint64_t flags) {
this->fault_data = this->reg.PC; this->fault_data = this->reg.PC;
} }
} }
} } // namespace arch
} } // namespace iss
#endif /* _RISCV_CORE_H_ */ #endif /* _RISCV_CORE_H_ */

View File

@ -56,7 +56,7 @@ template <typename BASE> class riscv_hart_m_p;
namespace debugger { namespace debugger {
class target_adapter_if; class target_adapter_if;
} }
} } // namespace iss
namespace sysc { namespace sysc {
@ -103,6 +103,8 @@ public:
cci::cci_param<bool> dump_ir{"dump_ir", false}; cci::cci_param<bool> dump_ir{"dump_ir", false};
cci::cci_param<uint32_t> mhartid{"mhartid", 0};
core_complex(sc_core::sc_module_name name); core_complex(sc_core::sc_module_name name);
~core_complex(); ~core_complex();

View File

@ -84,7 +84,7 @@ int main(int argc, char *argv[]) {
("mem,m", po::value<std::string>(), "the memory input file") ("mem,m", po::value<std::string>(), "the memory input file")
("plugin,p", po::value<std::vector<std::string>>(), "plugin to activate") ("plugin,p", po::value<std::vector<std::string>>(), "plugin to activate")
("backend", po::value<std::string>()->default_value("tcc"), "the memory input file") ("backend", po::value<std::string>()->default_value("tcc"), "the memory input file")
("isa", po::value<std::string>()->default_value("rv32gc"), "isa to use for simulation"); ("isa", po::value<std::string>()->default_value("tgf02"), "isa to use for simulation");
// clang-format on // clang-format on
auto parsed = po::command_line_parser(argc, argv).options(desc).allow_unregistered().run(); auto parsed = po::command_line_parser(argc, argv).options(desc).allow_unregistered().run();
try { try {
@ -129,10 +129,12 @@ int main(int argc, char *argv[]) {
vm_ptr vm{nullptr}; vm_ptr vm{nullptr};
cpu_ptr cpu{nullptr}; cpu_ptr cpu{nullptr};
std::string isa_opt(clim["isa"].as<std::string>()); std::string isa_opt(clim["isa"].as<std::string>());
if (isa_opt=="tgf01") { if (isa_opt == "tgf01") {
std::tie(cpu, vm) = create_cpu<iss::arch::tgf01>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>()); std::tie(cpu, vm) =
} else if (isa_opt=="tgf02") { create_cpu<iss::arch::tgf01>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>());
std::tie(cpu, vm) = create_cpu<iss::arch::tgf02>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>()); } else if (isa_opt == "tgf02") {
std::tie(cpu, vm) =
create_cpu<iss::arch::tgf02>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>());
} else { } else {
LOG(ERROR) << "Illegal argument value for '--isa': " << clim["isa"].as<std::string>() << std::endl; LOG(ERROR) << "Illegal argument value for '--isa': " << clim["isa"].as<std::string>() << std::endl;
return 127; return 127;

View File

@ -40,8 +40,8 @@
#include "iss/iss.h" #include "iss/iss.h"
#include "iss/vm_types.h" #include "iss/vm_types.h"
#include "scc/report.h" #include "scc/report.h"
#include <sstream>
#include <iostream> #include <iostream>
#include <sstream>
#ifdef WITH_SCV #ifdef WITH_SCV
#include <array> #include <array>
@ -59,7 +59,6 @@ namespace {
iss::debugger::encoder_decoder encdec; iss::debugger::encoder_decoder encdec;
} }
//using core_type = iss::arch::rv32imac;
using core_type = iss::arch::tgf02; using core_type = iss::arch::tgf02;
namespace { namespace {
@ -95,9 +94,7 @@ public:
using base_type = arch::riscv_hart_m_p<core_type>; using base_type = arch::riscv_hart_m_p<core_type>;
using phys_addr_t = typename arch::traits<core_type>::phys_addr_t; using phys_addr_t = typename arch::traits<core_type>::phys_addr_t;
core_wrapper(core_complex *owner) core_wrapper(core_complex *owner)
: owner(owner) : owner(owner) { }
{
}
uint32_t get_mode() { return this->reg.machine_state; } uint32_t get_mode() { return this->reg.machine_state; }
@ -288,6 +285,8 @@ vm_ptr create_cpu(core_wrapper* cpu, std::string const& backend, unsigned gdb_po
void core_complex::before_end_of_elaboration() { void core_complex::before_end_of_elaboration() {
SCCDEBUG(SCMOD)<<"instantiating iss::arch::tgf with "<<backend.get_value()<<" backend"; SCCDEBUG(SCMOD)<<"instantiating iss::arch::tgf with "<<backend.get_value()<<" backend";
cpu = scc::make_unique<core_wrapper>(this); cpu = scc::make_unique<core_wrapper>(this);
cpu->set_mhartid(mhartid.get_value());
vm = create_cpu(cpu.get(), backend.get_value(), gdb_server_port.get_value()); vm = create_cpu(cpu.get(), backend.get_value(), gdb_server_port.get_value());
#ifdef WITH_SCV #ifdef WITH_SCV
vm->setDisassEnabled(enable_disass.get_value() || m_db != nullptr); vm->setDisassEnabled(enable_disass.get_value() || m_db != nullptr);