Browse Source

Squashed PR 2199: Fix initialization bugs and merge conflicts with per-hart start PCs

pull/2199/head
nabudahab 2 months ago
parent
commit
c76d96d9cd
  1. 21
      riscv/cfg.cc
  2. 17
      riscv/cfg.h
  3. 27
      riscv/sim.cc
  4. 21
      spike_main/spike.cc

21
riscv/cfg.cc

@ -48,3 +48,24 @@ cfg_t::cfg_t()
trigger_count = 4; trigger_count = 4;
cache_blocksz = 64; cache_blocksz = 64;
} }
void start_pc_t::set_global(reg_t pc)
{
global_pc = pc;
}
void start_pc_t::set_override(size_t hart_id, reg_t pc)
{
hart_pcs[hart_id] = pc;
}
std::optional<reg_t> start_pc_t::get(size_t hart_id) const
{
auto it = hart_pcs.find(hart_id);
if (it != hart_pcs.end()) {
return it->second;
} else {
return global_pc;
}
}

17
riscv/cfg.h

@ -6,6 +6,7 @@
#include <vector> #include <vector>
#include "decode.h" #include "decode.h"
#include <cassert> #include <cassert>
#include <map>
class abstract_sim_if_t; class abstract_sim_if_t;
typedef enum { typedef enum {
@ -59,6 +60,20 @@ private:
reg_t size; reg_t size;
}; };
class start_pc_t
{
public:
void set_global(reg_t pc);
void set_override(size_t hart_id, reg_t pc);
std::optional<reg_t> get(size_t hart_id) const;
private:
std::optional<reg_t> global_pc;
std::map<size_t, reg_t> hart_pcs;
};
class cfg_t class cfg_t
{ {
public: public:
@ -72,7 +87,7 @@ public:
reg_t pmpregions; reg_t pmpregions;
reg_t pmpgranularity; reg_t pmpgranularity;
std::vector<mem_cfg_t> mem_layout; std::vector<mem_cfg_t> mem_layout;
std::optional<reg_t> start_pc; start_pc_t start_pc;
std::vector<size_t> hartids; std::vector<size_t> hartids;
bool explicit_hartids; bool explicit_hartids;
bool real_time_clint; bool real_time_clint;

27
riscv/sim.cc

@ -106,6 +106,14 @@ sim_t::sim_t(const cfg_t *cfg, bool halted,
log_file.get(), sout_)); log_file.get(), sout_));
harts[cfg->hartids[i]] = procs[i]; harts[cfg->hartids[i]] = procs[i];
} }
for (auto& x : this->mems) {
bus.add_device(x.first, x.second);
}
for (auto& pair : harts) {
if (auto pc = cfg->start_pc.get(pair.first)) {
pair.second->get_state()->pc = *pc;
}
}
return; return;
} // otherwise, generate the procs by parsing the DTS } // otherwise, generate the procs by parsing the DTS
@ -246,15 +254,15 @@ sim_t::sim_t(const cfg_t *cfg, bool halted,
dtb_discovery_plugin_device_factories.end()); dtb_discovery_plugin_device_factories.end());
//Remove default memories and use dtb discovered memories //Remove default memories and use dtb discovered memories
mems.clear(); this->mems.clear();
dtb_discovery::discover_memory_from_dtb(fdt, mems); dtb_discovery::discover_memory_from_dtb(fdt, this->mems);
} }
//clint, plic, ns16550 are always discovered via dtb, independently from the --dtb_discovery flag //clint, plic, ns16550 are always discovered via dtb, independently from the --dtb_discovery flag
device_factories.insert(device_factories.end(), device_factories.insert(device_factories.end(),
plugin_device_factories.begin(), plugin_device_factories.begin(),
plugin_device_factories.end()); plugin_device_factories.end());
for (auto& x : mems) for (auto& x : this->mems)
{ {
bus.add_device(x.first, x.second); bus.add_device(x.first, x.second);
} }
@ -281,6 +289,12 @@ sim_t::sim_t(const cfg_t *cfg, bool halted,
} }
} }
} }
for (auto& pair : harts) {
if (auto pc = cfg->start_pc.get(pair.first)) {
pair.second->get_state()->pc = *pc;
}
}
} }
sim_t::~sim_t() sim_t::~sim_t()
@ -380,7 +394,7 @@ void sim_t::set_rom()
{ {
const int reset_vec_size = 8; const int reset_vec_size = 8;
reg_t start_pc = cfg->start_pc.value_or(get_entry_point()); reg_t start_pc = cfg->start_pc.get(0).value_or(get_entry_point());
uint32_t reset_vec[reset_vec_size] = { uint32_t reset_vec[reset_vec_size] = {
0x297, // auipc t0,0x0 0x297, // auipc t0,0x0
@ -499,4 +513,9 @@ endianness_t sim_t::get_target_endianness() const
void sim_t::proc_reset(unsigned id) void sim_t::proc_reset(unsigned id)
{ {
debug_module.proc_reset(id); debug_module.proc_reset(id);
if (harts.count(id)) {
if (auto pc = cfg->start_pc.get(id)) {
harts[id]->get_state()->pc = *pc;
}
}
} }

21
spike_main/spike.cc

@ -20,6 +20,7 @@
#include <limits> #include <limits>
#include <cinttypes> #include <cinttypes>
#include <sstream> #include <sstream>
#include <map>
#include "../VERSION" #include "../VERSION"
static void help(int exit_code = 1) static void help(int exit_code = 1)
@ -46,6 +47,7 @@ static void help(int exit_code = 1)
fprintf(stderr, " --pmpgranularity=<n> PMP Granularity in bytes [default 4]\n"); fprintf(stderr, " --pmpgranularity=<n> PMP Granularity in bytes [default 4]\n");
fprintf(stderr, " --priv=<m|mu|msu> RISC-V privilege modes supported [default %s]\n", DEFAULT_PRIV); fprintf(stderr, " --priv=<m|mu|msu> RISC-V privilege modes supported [default %s]\n", DEFAULT_PRIV);
fprintf(stderr, " --pc=<address> Override ELF entry point\n"); fprintf(stderr, " --pc=<address> Override ELF entry point\n");
fprintf(stderr, " --pcs=<H:A,...> Override start PC for specific harts\n");
fprintf(stderr, " --hartids=<a,b,...> Explicitly specify hartids, default is 0,1,...\n"); fprintf(stderr, " --hartids=<a,b,...> Explicitly specify hartids, default is 0,1,...\n");
fprintf(stderr, " --ic=<S>:<W>:<B> Instantiate a cache model with S sets,\n"); fprintf(stderr, " --ic=<S>:<W>:<B> Instantiate a cache model with S sets,\n");
fprintf(stderr, " --dc=<S>:<W>:<B> W ways, and B-byte blocks (with S and\n"); fprintf(stderr, " --dc=<S>:<W>:<B> W ways, and B-byte blocks (with S and\n");
@ -383,7 +385,24 @@ int main(int argc, char** argv)
parser.option('m', 0, 1, [&](const char* s){cfg.mem_layout = parse_mem_layout(s); memory_option=true; }); parser.option('m', 0, 1, [&](const char* s){cfg.mem_layout = parse_mem_layout(s); memory_option=true; });
parser.option(0, "halted", 0, [&](const char UNUSED *s){halted = true;}); parser.option(0, "halted", 0, [&](const char UNUSED *s){halted = true;});
parser.option(0, "rbb-port", 1, [&](const char* s){use_rbb = true; rbb_port = atoul_safe(s);}); parser.option(0, "rbb-port", 1, [&](const char* s){use_rbb = true; rbb_port = atoul_safe(s);});
parser.option(0, "pc", 1, [&](const char* s){cfg.start_pc = strtoull(s, 0, 0);}); parser.option(0, "pc", 1, [&](const char* s){cfg.start_pc.set_global(strtoull(s, 0, 0));});
parser.option(0, "pcs", 1, [&](const char* s){
std::string arg(s);
std::stringstream ss(arg);
std::string pair;
while (std::getline(ss, pair, ',')) {
size_t delim = pair.find(':');
if (delim == std::string::npos) {
fprintf(stderr, "Error: --pcs format is hartid:addr,hartid:addr\n");
exit(1);
}
size_t hartid = std::strtoull(pair.substr(0, delim).c_str(), 0, 0);
reg_t addr = std::strtoull(pair.substr(delim+1).c_str(), 0, 0);
cfg.start_pc.set_override(hartid, addr);
}
});
parser.option(0, "hartids", 1, [&](const char* s){ parser.option(0, "hartids", 1, [&](const char* s){
cfg.hartids = parse_hartids(s); cfg.hartids = parse_hartids(s);
cfg.explicit_hartids = true; cfg.explicit_hartids = true;

Loading…
Cancel
Save