|
|
|
@ -220,6 +220,21 @@ static unsigned long atoul_nonzero_safe(const char* s) |
|
|
|
return res; |
|
|
|
} |
|
|
|
|
|
|
|
static std::vector<int> parse_hartids(const char *s) |
|
|
|
{ |
|
|
|
std::string const str(s); |
|
|
|
std::stringstream stream(str); |
|
|
|
std::vector<int> hartids; |
|
|
|
|
|
|
|
int n; |
|
|
|
while (stream >> n) { |
|
|
|
hartids.push_back(n); |
|
|
|
if (stream.peek() == ',') stream.ignore(); |
|
|
|
} |
|
|
|
|
|
|
|
return hartids; |
|
|
|
} |
|
|
|
|
|
|
|
int main(int argc, char** argv) |
|
|
|
{ |
|
|
|
bool debug = false; |
|
|
|
@ -229,10 +244,8 @@ int main(int argc, char** argv) |
|
|
|
bool socket = false; // command line option -s
|
|
|
|
bool dump_dts = false; |
|
|
|
bool dtb_enabled = true; |
|
|
|
bool real_time_clint = false; |
|
|
|
const char* kernel = NULL; |
|
|
|
reg_t kernel_offset, kernel_size; |
|
|
|
reg_t start_pc = reg_t(-1); |
|
|
|
std::vector<std::pair<reg_t, abstract_device_t*>> plugin_devices; |
|
|
|
std::unique_ptr<icache_sim_t> ic; |
|
|
|
std::unique_ptr<dcache_sim_t> dc; |
|
|
|
@ -242,7 +255,6 @@ int main(int argc, char** argv) |
|
|
|
const char *log_path = nullptr; |
|
|
|
std::vector<std::function<extension_t*()>> extensions; |
|
|
|
const char* initrd = NULL; |
|
|
|
const char* varch = DEFAULT_VARCH; |
|
|
|
const char* dtb_file = NULL; |
|
|
|
uint16_t rbb_port = 0; |
|
|
|
bool use_rbb = false; |
|
|
|
@ -258,25 +270,16 @@ int main(int argc, char** argv) |
|
|
|
.support_haltgroups = true, |
|
|
|
.support_impebreak = true |
|
|
|
}; |
|
|
|
std::vector<int> hartids; |
|
|
|
cfg_arg_t<size_t> nprocs(1); |
|
|
|
|
|
|
|
cfg_t cfg(/*default_initrd_bounds=*/std::make_pair((reg_t)0, (reg_t)0), |
|
|
|
/*default_bootargs=*/nullptr, |
|
|
|
/*default_nprocs=*/1, |
|
|
|
/*default_isa=*/DEFAULT_ISA, |
|
|
|
/*default_priv=*/DEFAULT_PRIV, |
|
|
|
/*default_mem_layout=*/parse_mem_layout("2048")); |
|
|
|
|
|
|
|
auto const hartids_parser = [&](const char *s) { |
|
|
|
std::string const str(s); |
|
|
|
std::stringstream stream(str); |
|
|
|
|
|
|
|
int n; |
|
|
|
while (stream >> n) |
|
|
|
{ |
|
|
|
hartids.push_back(n); |
|
|
|
if (stream.peek() == ',') stream.ignore(); |
|
|
|
} |
|
|
|
}; |
|
|
|
/*default_varch=*/DEFAULT_VARCH, |
|
|
|
/*default_mem_layout=*/parse_mem_layout("2048"), |
|
|
|
/*default_hartids=*/std::vector<int>(), |
|
|
|
/*default_real_time_clint=*/false); |
|
|
|
|
|
|
|
auto const device_parser = [&plugin_devices](const char *s) { |
|
|
|
const std::string str(s); |
|
|
|
@ -330,20 +333,23 @@ int main(int argc, char** argv) |
|
|
|
#ifdef HAVE_BOOST_ASIO |
|
|
|
parser.option('s', 0, 0, [&](const char* s){socket = true;}); |
|
|
|
#endif |
|
|
|
parser.option('p', 0, 1, [&](const char* s){cfg.nprocs = atoul_nonzero_safe(s);}); |
|
|
|
parser.option('p', 0, 1, [&](const char* s){nprocs = atoul_nonzero_safe(s);}); |
|
|
|
parser.option('m', 0, 1, [&](const char* s){cfg.mem_layout = parse_mem_layout(s);}); |
|
|
|
// I wanted to use --halted, but for some reason that doesn't work.
|
|
|
|
parser.option('H', 0, 0, [&](const char* 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){start_pc = strtoull(s, 0, 0);}); |
|
|
|
parser.option(0, "hartids", 1, hartids_parser); |
|
|
|
parser.option(0, "pc", 1, [&](const char* s){cfg.start_pc = strtoull(s, 0, 0);}); |
|
|
|
parser.option(0, "hartids", 1, [&](const char* s){ |
|
|
|
cfg.hartids = parse_hartids(s); |
|
|
|
cfg.explicit_hartids = true; |
|
|
|
}); |
|
|
|
parser.option(0, "ic", 1, [&](const char* s){ic.reset(new icache_sim_t(s));}); |
|
|
|
parser.option(0, "dc", 1, [&](const char* s){dc.reset(new dcache_sim_t(s));}); |
|
|
|
parser.option(0, "l2", 1, [&](const char* s){l2.reset(cache_sim_t::construct(s, "L2$"));}); |
|
|
|
parser.option(0, "log-cache-miss", 0, [&](const char* s){log_cache = true;}); |
|
|
|
parser.option(0, "isa", 1, [&](const char* s){cfg.isa = s;}); |
|
|
|
parser.option(0, "priv", 1, [&](const char* s){cfg.priv = s;}); |
|
|
|
parser.option(0, "varch", 1, [&](const char* s){varch = s;}); |
|
|
|
parser.option(0, "varch", 1, [&](const char* s){cfg.varch = s;}); |
|
|
|
parser.option(0, "device", 1, device_parser); |
|
|
|
parser.option(0, "extension", 1, [&](const char* s){extensions.push_back(find_extension(s));}); |
|
|
|
parser.option(0, "dump-dts", 0, [&](const char *s){dump_dts = true;}); |
|
|
|
@ -352,7 +358,7 @@ int main(int argc, char** argv) |
|
|
|
parser.option(0, "kernel", 1, [&](const char* s){kernel = s;}); |
|
|
|
parser.option(0, "initrd", 1, [&](const char* s){initrd = s;}); |
|
|
|
parser.option(0, "bootargs", 1, [&](const char* s){cfg.bootargs = s;}); |
|
|
|
parser.option(0, "real-time-clint", 0, [&](const char *s){real_time_clint = true;}); |
|
|
|
parser.option(0, "real-time-clint", 0, [&](const char *s){cfg.real_time_clint = true;}); |
|
|
|
parser.option(0, "extlib", 1, [&](const char *s){ |
|
|
|
void *lib = dlopen(s, RTLD_NOW | RTLD_GLOBAL); |
|
|
|
if (lib == NULL) { |
|
|
|
@ -456,9 +462,28 @@ int main(int argc, char** argv) |
|
|
|
} |
|
|
|
#endif |
|
|
|
|
|
|
|
sim_t s(&cfg, varch, halted, real_time_clint, |
|
|
|
start_pc, mems, plugin_devices, htif_args, |
|
|
|
std::move(hartids), dm_config, log_path, dtb_enabled, dtb_file, |
|
|
|
if (cfg.explicit_hartids) { |
|
|
|
if (nprocs.overridden() && (nprocs() != cfg.nprocs())) { |
|
|
|
std::cerr << "Number of specified hartids (" |
|
|
|
<< cfg.nprocs() |
|
|
|
<< ") doesn't match specified number of processors (" |
|
|
|
<< nprocs() << ").\n"; |
|
|
|
exit(1); |
|
|
|
} |
|
|
|
} else { |
|
|
|
// Set default set of hartids based on nprocs, but don't set the
|
|
|
|
// explicit_hartids flag (which means that downstream code can know that
|
|
|
|
// we've only set the number of harts, not explicitly chosen their IDs).
|
|
|
|
std::vector<int> default_hartids; |
|
|
|
default_hartids.reserve(nprocs()); |
|
|
|
for (size_t i = 0; i < nprocs(); ++i) { |
|
|
|
default_hartids.push_back(i); |
|
|
|
} |
|
|
|
cfg.hartids = default_hartids; |
|
|
|
} |
|
|
|
|
|
|
|
sim_t s(&cfg, halted, |
|
|
|
mems, plugin_devices, htif_args, dm_config, log_path, dtb_enabled, dtb_file, |
|
|
|
#ifdef HAVE_BOOST_ASIO |
|
|
|
io_service_ptr, acceptor_ptr, |
|
|
|
#endif |
|
|
|
|