Browse Source

Merge pull request #1721 from abejgonzalez/dts_parsing

Enable more configuration using the DTB
pull/1759/head
Andrew Waterman 2 years ago
committed by GitHub
parent
commit
fdd2570fc4
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 149
      riscv/dts.cc
  2. 10
      riscv/dts.h
  3. 19
      riscv/interactive.cc
  4. 39
      riscv/processor.cc
  5. 9
      riscv/processor.h
  6. 102
      riscv/sim.cc
  7. 1
      riscv/sim.h
  8. 2
      spike_main/spike-log-parser.cc

149
riscv/dts.cc

@ -13,14 +13,17 @@
#include <sys/types.h>
std::string make_dts(size_t insns_per_rtc_tick, size_t cpu_hz,
reg_t initrd_start, reg_t initrd_end,
const char* bootargs,
size_t pmpregions,
size_t pmpgranularity,
std::vector<processor_t*> procs,
const cfg_t* cfg,
std::vector<std::pair<reg_t, abstract_mem_t*>> mems,
std::string device_nodes)
{
reg_t initrd_start = cfg->initrd_bounds.first;
reg_t initrd_end = cfg->initrd_bounds.second;
const char* bootargs = cfg->bootargs;
reg_t pmpregions = cfg->pmpregions;
reg_t pmpgranularity = cfg->pmpgranularity;
isa_parser_t isa(cfg->isa, cfg->priv);
std::stringstream s;
s << std::dec <<
"/dts-v1/;\n"
@ -54,14 +57,14 @@ std::string make_dts(size_t insns_per_rtc_tick, size_t cpu_hz,
" #address-cells = <1>;\n"
" #size-cells = <0>;\n"
" timebase-frequency = <" << (cpu_hz/insns_per_rtc_tick) << ">;\n";
for (size_t i = 0; i < procs.size(); i++) {
for (size_t i = 0; i < cfg->nprocs(); i++) {
s << " CPU" << i << ": cpu@" << i << " {\n"
" device_type = \"cpu\";\n"
" reg = <" << i << ">;\n"
" reg = <" << cfg->hartids[i] << ">;\n"
" status = \"okay\";\n"
" compatible = \"riscv\";\n"
" riscv,isa = \"" << procs[i]->get_isa().get_isa_string() << "\";\n"
" mmu-type = \"riscv," << (procs[i]->get_isa().get_max_xlen() <= 32 ? "sv32" : "sv57") << "\";\n"
" riscv,isa = \"" << isa.get_isa_string() << "\";\n"
" mmu-type = \"riscv," << (isa.get_max_xlen() <= 32 ? "sv32" : "sv57") << "\";\n"
" riscv,pmpregions = <" << pmpregions << ">;\n"
" riscv,pmpgranularity = <" << pmpgranularity << ">;\n"
" clock-frequency = <" << cpu_hz << ">;\n"
@ -96,86 +99,91 @@ std::string make_dts(size_t insns_per_rtc_tick, size_t cpu_hz,
return s.str();
}
std::string dts_compile(const std::string& dts)
std::string dtc_compile(const std::string& dtc_input, const std::string& input_type, const std::string& output_type)
{
// Convert the DTS to DTB
int dts_pipe[2];
pid_t dts_pid;
if (input_type == output_type)
std::cerr << "Must have differing {in,out}put types for running " DTC << std::endl;
if (!((input_type == "dts" && output_type == "dtb") || (input_type == "dtb" && output_type == "dts")))
std::cerr << "Invalid {in,out}put types for running " DTC ": Must convert from 'dts' to 'dtb' (or vice versa)" << std::endl;
int dtc_input_pipe[2];
pid_t dtc_input_pid;
fflush(NULL); // flush stdout/stderr before forking
if (pipe(dts_pipe) != 0 || (dts_pid = fork()) < 0) {
std::cerr << "Failed to fork dts child: " << strerror(errno) << std::endl;
if (pipe(dtc_input_pipe) != 0 || (dtc_input_pid = fork()) < 0) {
std::cerr << "Failed to fork dtc_input child: " << strerror(errno) << std::endl;
exit(1);
}
// Child process to output dts
if (dts_pid == 0) {
close(dts_pipe[0]);
int step, len = dts.length();
const char *buf = dts.c_str();
// Child process to output dtc_input
if (dtc_input_pid == 0) {
close(dtc_input_pipe[0]);
int step, len = dtc_input.length();
const char *buf = dtc_input.c_str();
for (int done = 0; done < len; done += step) {
step = write(dts_pipe[1], buf+done, len-done);
step = write(dtc_input_pipe[1], buf+done, len-done);
if (step == -1) {
std::cerr << "Failed to write dts: " << strerror(errno) << std::endl;
std::cerr << "Failed to write dtc_input: " << strerror(errno) << std::endl;
exit(1);
}
}
close(dts_pipe[1]);
close(dtc_input_pipe[1]);
exit(0);
}
pid_t dtb_pid;
int dtb_pipe[2];
if (pipe(dtb_pipe) != 0 || (dtb_pid = fork()) < 0) {
std::cerr << "Failed to fork dtb child: " << strerror(errno) << std::endl;
pid_t dtc_output_pid;
int dtc_output_pipe[2];
if (pipe(dtc_output_pipe) != 0 || (dtc_output_pid = fork()) < 0) {
std::cerr << "Failed to fork dtc_output child: " << strerror(errno) << std::endl;
exit(1);
}
// Child process to output dtb
if (dtb_pid == 0) {
dup2(dts_pipe[0], 0);
dup2(dtb_pipe[1], 1);
close(dts_pipe[0]);
close(dts_pipe[1]);
close(dtb_pipe[0]);
close(dtb_pipe[1]);
execlp(DTC, DTC, "-O", "dtb", (char *)0);
// Child process to output dtc_output
if (dtc_output_pid == 0) {
dup2(dtc_input_pipe[0], 0);
dup2(dtc_output_pipe[1], 1);
close(dtc_input_pipe[0]);
close(dtc_input_pipe[1]);
close(dtc_output_pipe[0]);
close(dtc_output_pipe[1]);
execlp(DTC, DTC, "-O", output_type.c_str(), "-I", input_type.c_str(), (char *)0);
std::cerr << "Failed to run " DTC ": " << strerror(errno) << std::endl;
exit(1);
}
close(dts_pipe[1]);
close(dts_pipe[0]);
close(dtb_pipe[1]);
close(dtc_input_pipe[1]);
close(dtc_input_pipe[0]);
close(dtc_output_pipe[1]);
// Read-out dtb
std::stringstream dtb;
// Read-out dtc_output
std::stringstream dtc_output;
int got;
char buf[4096];
while ((got = read(dtb_pipe[0], buf, sizeof(buf))) > 0) {
dtb.write(buf, got);
while ((got = read(dtc_output_pipe[0], buf, sizeof(buf))) > 0) {
dtc_output.write(buf, got);
}
if (got == -1) {
std::cerr << "Failed to read dtb: " << strerror(errno) << std::endl;
std::cerr << "Failed to read dtc_output: " << strerror(errno) << std::endl;
exit(1);
}
close(dtb_pipe[0]);
close(dtc_output_pipe[0]);
// Reap children
int status;
waitpid(dts_pid, &status, 0);
waitpid(dtc_input_pid, &status, 0);
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
std::cerr << "Child dts process failed" << std::endl;
std::cerr << "Child dtc_input process failed" << std::endl;
exit(1);
}
waitpid(dtb_pid, &status, 0);
waitpid(dtc_output_pid, &status, 0);
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
std::cerr << "Child dtb process failed" << std::endl;
std::cerr << "Child dtc_output process failed" << std::endl;
exit(1);
}
return dtb.str();
return dtc_output.str();
}
int fdt_get_node_addr_size(const void *fdt, int node, reg_t *addr,
@ -386,3 +394,44 @@ int fdt_parse_mmu_type(const void *fdt, int cpu_offset, const char **mmu_type)
return 0;
}
int fdt_parse_isa(const void *fdt, int cpu_offset, const char **isa)
{
assert(isa);
int len, rc;
const void *prop;
if ((rc = check_cpu_node(fdt, cpu_offset)) < 0)
return rc;
prop = fdt_getprop(fdt, cpu_offset, "riscv,isa", &len);
if (!prop || !len)
return -EINVAL;
*isa = (const char *)prop;
return 0;
}
int fdt_parse_hartid(const void *fdt, int cpu_offset, uint32_t *hartid)
{
int len, rc;
const void *prop;
const fdt32_t *val;
if ((rc = check_cpu_node(fdt, cpu_offset)) < 0)
return rc;
val = (fdt32_t*) fdt_getprop(fdt, cpu_offset, "reg", &len);
if (!val || len < (int) sizeof(fdt32_t))
return -EINVAL;
if (len > (int) sizeof(fdt32_t))
val++;
if (hartid)
*hartid = fdt32_to_cpu(*val);
return 0;
}

10
riscv/dts.h

@ -7,15 +7,11 @@
#include <string>
std::string make_dts(size_t insns_per_rtc_tick, size_t cpu_hz,
reg_t initrd_start, reg_t initrd_end,
const char* bootargs,
size_t pmpregions,
size_t pmpgranularity,
std::vector<processor_t*> procs,
const cfg_t* cfg,
std::vector<std::pair<reg_t, abstract_mem_t*>> mems,
std::string device_nodes);
std::string dts_compile(const std::string& dts);
std::string dtc_compile(const std::string& dtc_input, const std::string& input_type, const std::string& output_type);
int fdt_get_node_addr_size(const void *fdt, int node, reg_t *addr,
unsigned long *size, const char *field);
@ -33,4 +29,6 @@ int fdt_parse_ns16550(const void *fdt, reg_t *ns16550_addr,
int fdt_parse_pmp_num(const void *fdt, int cpu_offset, reg_t *pmp_num);
int fdt_parse_pmp_alignment(const void *fdt, int cpu_offset, reg_t *pmp_align);
int fdt_parse_mmu_type(const void *fdt, int cpu_offset, const char **mmu_type);
int fdt_parse_isa(const void *fdt, int cpu_offset, const char **isa_str);
int fdt_parse_hartid(const void *fdt, int cpu_offset, uint32_t *hartid);
#endif

19
riscv/interactive.cc

@ -342,8 +342,10 @@ void sim_t::interactive()
(this->*funcs[cmd])(cmd, args);
else
out << "Unknown command " << cmd << std::endl;
} catch(trap_t& t) {
} catch(trap_interactive& t) {
out << "Bad or missing arguments for command " << cmd << std::endl;
} catch(trap_t& t){
out << "Received trap: " << t.name() << std::endl;
}
#ifdef HAVE_BOOST_ASIO
if (socketif)
@ -473,15 +475,9 @@ void sim_t::interactive_insn(const std::string& cmd, const std::vector<std::stri
int max_xlen = p->get_isa().get_max_xlen();
std::ostream out(sout_.rdbuf());
try
{
insn_t insn(get_insn(args));
out << std::hex << std::setfill('0') << "0x" << std::setw(max_xlen/4)
<< zext(insn.bits(), max_xlen) << " " << p->get_disassembler()->disassemble(insn) << std::endl;
}
catch (trap_t& t) {
out << "Unable to obtain insn due to " << t.name() << std::endl;
}
insn_t insn(get_insn(args)); // ensure this is outside of ostream to not pollute output on non-interactive trap
out << std::hex << std::setfill('0') << "0x" << std::setw(max_xlen/4)
<< zext(insn.bits(), max_xlen) << " " << p->get_disassembler()->disassemble(insn) << std::endl;
}
void sim_t::interactive_priv(const std::string& cmd, const std::vector<std::string>& args)
@ -717,8 +713,9 @@ void sim_t::interactive_mem(const std::string& cmd, const std::vector<std::strin
int max_xlen = procs[0]->get_isa().get_max_xlen();
std::ostream out(sout_.rdbuf());
reg_t mem_val = get_mem(args); // ensure this is outside of ostream to not pollute output on non-interactive trap
out << std::hex << "0x" << std::setfill('0') << std::setw(max_xlen/4)
<< zext(get_mem(args), max_xlen) << std::endl;
<< zext(mem_val, max_xlen) << std::endl;
}
void sim_t::interactive_str(const std::string& cmd, const std::vector<std::string>& args)

39
riscv/processor.cc

@ -30,49 +30,50 @@
#undef STATE
#define STATE state
processor_t::processor_t(const isa_parser_t *isa, const cfg_t *cfg,
processor_t::processor_t(const char* isa_str, const char* priv_str,
const cfg_t *cfg,
simif_t* sim, uint32_t id, bool halt_on_reset,
FILE* log_file, std::ostream& sout_)
: debug(false), halt_request(HR_NONE), isa(isa), cfg(cfg), sim(sim), id(id), xlen(0),
: debug(false), halt_request(HR_NONE), isa(isa_str, priv_str), cfg(cfg), 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),
in_wfi(false), check_triggers_icount(false),
impl_table(256, false), extension_enable_table(isa->get_extension_table()),
impl_table(256, false), extension_enable_table(isa.get_extension_table()),
last_pc(1), executions(1), TM(cfg->trigger_count)
{
VU.p = this;
TM.proc = this;
#ifndef HAVE_INT128
if (isa->has_any_vector()) {
if (isa.has_any_vector()) {
fprintf(stderr, "V extension is not supported on platforms without __int128 type\n");
abort();
}
if (isa->extension_enabled(EXT_ZACAS) && isa->get_max_xlen() == 64) {
if (isa.extension_enabled(EXT_ZACAS) && isa.get_max_xlen() == 64) {
fprintf(stderr, "Zacas extension is not supported on 64-bit platforms without __int128 type\n");
abort();
}
#endif
VU.VLEN = isa->get_vlen();
VU.ELEN = isa->get_elen();
VU.vlenb = isa->get_vlen() / 8;
VU.VLEN = isa.get_vlen();
VU.ELEN = isa.get_elen();
VU.vlenb = isa.get_vlen() / 8;
VU.vstart_alu = 0;
register_base_instructions();
mmu = new mmu_t(sim, cfg->endianness, this);
disassembler = new disassembler_t(isa);
for (auto e : isa->get_extensions())
disassembler = new disassembler_t(&isa);
for (auto e : isa.get_extensions())
register_extension(find_extension(e.c_str())());
set_pmp_granularity(cfg->pmpgranularity);
set_pmp_num(cfg->pmpregions);
if (isa->get_max_xlen() == 32)
if (isa.get_max_xlen() == 32)
set_mmu_capability(IMPL_MMU_SV32);
else if (isa->get_max_xlen() == 64)
else if (isa.get_max_xlen() == 64)
set_mmu_capability(IMPL_MMU_SV57);
set_impl(IMPL_MMU_ASID, true);
@ -575,8 +576,8 @@ void processor_t::enable_log_commits()
void processor_t::reset()
{
xlen = isa->get_max_xlen();
state.reset(this, isa->get_max_isa());
xlen = isa.get_max_xlen();
state.reset(this, isa.get_max_isa());
state.dcsr->halt = halt_on_reset;
halt_on_reset = false;
if (any_vector_extensions())
@ -724,7 +725,7 @@ void processor_t::take_interrupt(reg_t pending_interrupts)
abort();
if (check_triggers_icount) TM.detect_icount_match();
throw trap_t(((reg_t)1 << (isa->get_max_xlen() - 1)) | ctz(enabled_interrupts));
throw trap_t(((reg_t)1 << (isa.get_max_xlen() - 1)) | ctz(enabled_interrupts));
}
}
@ -796,7 +797,7 @@ 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();
unsigned max_xlen = isa.get_max_xlen();
if (debug) {
std::stringstream s; // first put everything in a string, later send it to output
@ -974,7 +975,7 @@ void processor_t::disasm(insn_t insn)
<< ": Executed " << executions << " times" << std::endl;
}
unsigned max_xlen = isa->get_max_xlen();
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)
@ -993,7 +994,7 @@ void processor_t::disasm(insn_t insn)
int processor_t::paddr_bits()
{
unsigned max_xlen = isa->get_max_xlen();
unsigned max_xlen = isa.get_max_xlen();
assert(xlen == max_xlen);
return max_xlen == 64 ? 50 : 34;
}
@ -1120,7 +1121,7 @@ void processor_t::register_base_instructions()
// add overlapping instructions first, in order
#define DECLARE_OVERLAP_INSN(name, ext) \
name##_overlapping = true; \
if (isa->extension_enabled(ext)) \
if (isa.extension_enabled(ext)) \
register_base_insn((insn_desc_t) { \
name##_match, \
name##_mask, \

9
riscv/processor.h

@ -237,12 +237,13 @@ class opcode_cache_entry_t {
class processor_t : public abstract_device_t
{
public:
processor_t(const isa_parser_t *isa, const cfg_t* cfg,
processor_t(const char* isa_str, const char* priv_str,
const cfg_t* cfg,
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; }
const isa_parser_t &get_isa() { return isa; }
const cfg_t &get_cfg() { return *cfg; }
void set_debug(bool value);
@ -304,7 +305,7 @@ public:
void set_extension_enable(unsigned char ext, bool enable) {
assert(!extension_assumed_const[ext]);
extension_dynamic[ext] = true;
extension_enable_table[ext] = enable && isa->extension_enabled(ext);
extension_enable_table[ext] = enable && isa.extension_enabled(ext);
}
void set_impl(uint8_t impl, bool val) { impl_table[impl] = val; }
bool supports_impl(uint8_t impl) const {
@ -363,7 +364,7 @@ public:
void check_if_lpad_required();
private:
const isa_parser_t * const isa;
const isa_parser_t isa;
const cfg_t * const cfg;
simif_t* sim;

102
riscv/sim.cc

@ -46,10 +46,8 @@ 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),
cfg(cfg),
mems(mems),
procs(std::max(cfg->nprocs(), size_t(1))),
dtb_enabled(dtb_enabled),
log_file(log_path),
cmd_file(cmd_file),
@ -98,14 +96,16 @@ 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,
log_file.get(), sout_);
harts[cfg->hartids[i]] = procs[i];
}
// When running without using a dtb, skip the fdt-based configuration steps
if (!dtb_enabled) return;
if (!dtb_enabled) {
for (size_t i = 0; i < cfg->nprocs(); i++) {
procs.push_back(new processor_t(cfg->isa, cfg->priv,
cfg, this, cfg->hartids[i], halted,
log_file.get(), sout_));
harts[cfg->hartids[i]] = procs[i];
return;
}
} // otherwise, generate the procs by parsing the DTS
// Only make a CLINT (Core-Local INTerrupt controller) and PLIC (Platform-
// Level-Interrupt-Controller) if they are specified in the device tree
@ -133,6 +133,7 @@ sim_t::sim_t(const cfg_t *cfg, bool halted,
std::stringstream strstream;
strstream << fin.rdbuf();
dtb = strstream.str();
dts = dtc_compile(dtb, "dtb", "dts");
} else {
std::pair<reg_t, reg_t> initrd_bounds = cfg->initrd_bounds;
std::string device_nodes;
@ -141,11 +142,8 @@ sim_t::sim_t(const cfg_t *cfg, bool halted,
const std::vector<std::string>& sargs = factory_sargs.second;
device_nodes.append(factory->generate_dts(this, sargs));
}
dts = make_dts(INSNS_PER_RTC_TICK, CPU_HZ,
initrd_bounds.first, initrd_bounds.second,
cfg->bootargs, cfg->pmpregions, cfg->pmpgranularity,
procs, mems, device_nodes);
dtb = dts_compile(dts);
dts = make_dts(INSNS_PER_RTC_TICK, CPU_HZ, cfg, mems, device_nodes);
dtb = dtc_compile(dts, "dts", "dtb");
}
int fdt_code = fdt_check_header(dtb.c_str());
@ -162,24 +160,7 @@ sim_t::sim_t(const cfg_t *cfg, bool halted,
void *fdt = (void *)dtb.c_str();
for (size_t i = 0; i < device_factories.size(); i++) {
const device_factory_t* factory = device_factories[i].first;
const std::vector<std::string>& sargs = device_factories[i].second;
reg_t device_base = 0;
abstract_device_t* device = factory->parse_from_fdt(fdt, this, &device_base, sargs);
if (device) {
assert(device_base);
std::shared_ptr<abstract_device_t> dev_ptr(device);
add_device(device_base, dev_ptr);
if (i == 0) // clint_factory
clint = std::static_pointer_cast<clint_t>(dev_ptr);
else if (i == 1) // plic_factory
plic = std::static_pointer_cast<plic_t>(dev_ptr);
}
}
//per core attribute
// per core attribute
int cpu_offset = 0, cpu_map_offset, rc;
size_t cpu_idx = 0;
cpu_offset = fdt_get_offset(fdt, "/cpus");
@ -193,10 +174,33 @@ sim_t::sim_t(const cfg_t *cfg, bool halted,
if (!(cpu_map_offset < 0) && cpu_offset == cpu_map_offset)
continue;
if (cpu_idx >= nprocs())
break;
if (cpu_idx != procs.size()) {
std::cerr << "Spike only supports contiguous CPU IDs in the DTS" << std::endl;
exit(1);
}
//handle pmp
// handle isa string
const char* isa_str;
rc = fdt_parse_isa(fdt, cpu_offset, &isa_str);
if (rc != 0) {
std::cerr << "core (" << cpu_idx << ") has an invalid or missing 'riscv,isa'\n";
exit(1);
}
// handle hartid
uint32_t hartid;
rc = fdt_parse_hartid(fdt, cpu_offset, &hartid);
if (rc != 0) {
std::cerr << "core (" << cpu_idx << ") has an invalid or missing `reg` (hartid)\n";
exit(1);
}
procs.push_back(new processor_t(isa_str, DEFAULT_PRIV,
cfg, this, hartid, halted,
log_file.get(), sout_));
harts[hartid] = procs[cpu_idx];
// handle pmp
reg_t pmp_num, pmp_granularity;
if (fdt_parse_pmp_num(fdt, cpu_offset, &pmp_num) != 0)
pmp_num = 0;
@ -206,7 +210,7 @@ sim_t::sim_t(const cfg_t *cfg, bool halted,
procs[cpu_idx]->set_pmp_granularity(pmp_granularity);
}
//handle mmu-type
// handle mmu-type
const char *mmu_type;
rc = fdt_parse_mmu_type(fdt, cpu_offset, &mmu_type);
if (rc == 0) {
@ -220,7 +224,7 @@ sim_t::sim_t(const cfg_t *cfg, bool halted,
} else if (strncmp(mmu_type, "riscv,sv57", strlen("riscv,sv57")) == 0) {
procs[cpu_idx]->set_mmu_capability(IMPL_MMU_SV57);
} else if (strncmp(mmu_type, "riscv,sbare", strlen("riscv,sbare")) == 0) {
//has been set in the beginning
// has been set in the beginning
} else {
std::cerr << "core ("
<< cpu_idx
@ -235,12 +239,22 @@ sim_t::sim_t(const cfg_t *cfg, bool halted,
cpu_idx++;
}
if (cpu_idx != nprocs()) {
std::cerr << "core number in dts ("
<< cpu_idx
<< ") doesn't match it in command line ("
<< nprocs() << ").\n";
exit(1);
// must be located after procs/harts are set (devices might use sim_t get_* member functions)
for (size_t i = 0; i < device_factories.size(); i++) {
const device_factory_t* factory = device_factories[i].first;
const std::vector<std::string>& sargs = device_factories[i].second;
reg_t device_base = 0;
abstract_device_t* device = factory->parse_from_fdt(fdt, this, &device_base, sargs);
if (device) {
assert(device_base);
std::shared_ptr<abstract_device_t> dev_ptr(device);
add_device(device_base, dev_ptr);
if (i == 0) // clint_factory
clint = std::static_pointer_cast<clint_t>(dev_ptr);
else if (i == 1) // plic_factory
plic = std::static_pointer_cast<plic_t>(dev_ptr);
}
}
}
@ -256,7 +270,7 @@ int sim_t::run()
if (!debug && log)
set_procs_debug(true);
htif_t::set_expected_xlen(isa.get_max_xlen());
htif_t::set_expected_xlen(harts[0]->get_isa().get_max_xlen());
// htif_t::run() will repeatedly call back into sim_t::idle(), each
// invocation of which will advance target time

1
riscv/sim.h

@ -69,7 +69,6 @@ public:
static const size_t CPU_HZ = 1000000000; // 1GHz CPU
private:
isa_parser_t isa;
const cfg_t * const cfg;
std::vector<std::pair<reg_t, abstract_mem_t*>> mems;
std::vector<processor_t*> procs;

2
spike_main/spike-log-parser.cc

@ -31,7 +31,7 @@ int main(int UNUSED argc, char** argv)
cfg_t cfg;
isa_parser_t isa(isa_string, DEFAULT_PRIV);
processor_t p(&isa, &cfg, 0, 0, false, nullptr, cerr);
processor_t p(isa_string, DEFAULT_PRIV, &cfg, 0, 0, false, nullptr, cerr);
if (extension) {
p.register_extension(extension());
}

Loading…
Cancel
Save