Browse Source

Merge pull request #2199 from nabudahab/master

Add support for per-hart start PCs (--pcs)
pull/2288/head
Andrew Waterman 2 weeks ago
committed by GitHub
parent
commit
632777d371
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 21
      riscv/cfg.cc
  2. 17
      riscv/cfg.h
  3. 21
      riscv/sim.cc
  4. 21
      spike_main/spike.cc

21
riscv/cfg.cc

@ -48,3 +48,24 @@ cfg_t::cfg_t()
trigger_count = 4;
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 "decode.h"
#include <cassert>
#include <map>
class abstract_sim_if_t;
typedef enum {
@ -59,6 +60,20 @@ private:
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
{
public:
@ -72,7 +87,7 @@ public:
reg_t pmpregions;
reg_t pmpgranularity;
std::vector<mem_cfg_t> mem_layout;
std::optional<reg_t> start_pc;
start_pc_t start_pc;
std::vector<size_t> hartids;
bool explicit_hartids;
bool real_time_clint;

21
riscv/sim.cc

@ -106,6 +106,14 @@ sim_t::sim_t(const cfg_t *cfg, bool halted,
log_file.get(), sout_));
harts[cfg->hartids[i]] = procs[i];
}
for (auto& x : 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;
} // otherwise, generate the procs by parsing the DTS
@ -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()
@ -380,7 +394,7 @@ void sim_t::set_rom()
{
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] = {
0x297, // auipc t0,0x0
@ -499,4 +513,9 @@ endianness_t sim_t::get_target_endianness() const
void sim_t::proc_reset(unsigned 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 <cinttypes>
#include <sstream>
#include <map>
#include "../VERSION"
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, " --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, " --pcs=<H:A,...> Override start PC for specific hart\n"); //This will bypass the built-in boot ROM
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, " --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(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, "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){
cfg.hartids = parse_hartids(s);
cfg.explicit_hartids = true;

Loading…
Cancel
Save