// See LICENSE for license details. #include "sim.h" #include "mmu.h" #include "gdbserver.h" #include "cachesim.h" #include "extension.h" #include #include #include #include #include #include #include static void help() { fprintf(stderr, "usage: spike [host options] [target options]\n"); fprintf(stderr, "Host Options:\n"); fprintf(stderr, " -p Simulate processors [default 1]\n"); fprintf(stderr, " -m Provide MiB of target memory [default 4096]\n"); fprintf(stderr, " -d Interactive debug mode\n"); fprintf(stderr, " -g Track histogram of PCs\n"); fprintf(stderr, " -l Generate a log of execution\n"); fprintf(stderr, " -h Print this help message\n"); fprintf(stderr, " -H Start halted, allowing a debugger to connect\n"); fprintf(stderr, " --isa= RISC-V ISA string [default %s]\n", DEFAULT_ISA); fprintf(stderr, " --ic=:: Instantiate a cache model with S sets,\n"); fprintf(stderr, " --dc=:: W ways, and B-byte blocks (with S and\n"); fprintf(stderr, " --l2=:: B both powers of 2).\n"); fprintf(stderr, " --extension= Specify RoCC Extension\n"); fprintf(stderr, " --extlib= Shared library to load\n"); fprintf(stderr, " --gdb-port= Listen on for gdb to connect\n"); fprintf(stderr, " --dump-dts Print device tree string and exit\n"); exit(1); } int main(int argc, char** argv) { bool debug = false; bool halted = false; bool histogram = false; bool log = false; bool dump_dts = false; size_t nprocs = 1; size_t mem_mb = 0; std::unique_ptr ic; std::unique_ptr dc; std::unique_ptr l2; std::function extension; const char* isa = DEFAULT_ISA; uint16_t gdb_port = 0; option_parser_t parser; parser.help(&help); parser.option('h', 0, 0, [&](const char* s){help();}); parser.option('d', 0, 0, [&](const char* s){debug = true;}); parser.option('g', 0, 0, [&](const char* s){histogram = true;}); parser.option('l', 0, 0, [&](const char* s){log = true;}); parser.option('p', 0, 1, [&](const char* s){nprocs = atoi(s);}); parser.option('m', 0, 1, [&](const char* s){mem_mb = atoi(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, "gdb-port", 1, [&](const char* s){gdb_port = atoi(s);}); 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, "isa", 1, [&](const char* s){isa = s;}); parser.option(0, "extension", 1, [&](const char* s){extension = find_extension(s);}); parser.option(0, "dump-dts", 0, [&](const char *s){dump_dts = true;}); parser.option(0, "extlib", 1, [&](const char *s){ void *lib = dlopen(s, RTLD_NOW | RTLD_GLOBAL); if (lib == NULL) { fprintf(stderr, "Unable to load extlib '%s': %s\n", s, dlerror()); exit(-1); } }); auto argv1 = parser.parse(argv); std::vector htif_args(argv1, (const char*const*)argv + argc); sim_t s(isa, nprocs, mem_mb, halted, htif_args); std::unique_ptr gdbserver; if (gdb_port) { gdbserver = std::unique_ptr(new gdbserver_t(gdb_port, &s)); s.set_gdbserver(&(*gdbserver)); } if (dump_dts) { printf("%s", s.get_dts()); return 0; } if (!*argv1) help(); if (ic && l2) ic->set_miss_handler(&*l2); if (dc && l2) dc->set_miss_handler(&*l2); for (size_t i = 0; i < nprocs; i++) { if (ic) s.get_core(i)->get_mmu()->register_memtracer(&*ic); if (dc) s.get_core(i)->get_mmu()->register_memtracer(&*dc); if (extension) s.get_core(i)->register_extension(extension()); } s.set_debug(debug); s.set_log(log); s.set_histogram(histogram); return s.run(); }