X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=riscv%2Fsim.cc;h=66bebb3b8cbf7bffe61ddba9fd226cf63bd9a7bc;hb=784e9891af88db221b57bdffbea74d1c6bf99971;hp=6d98d8e122e8b776f4e6f58865f7229a91ef34eb;hpb=d58ee30d172f6848edb1b3b225cc90c2143dc750;p=riscv-isa-sim.git diff --git a/riscv/sim.cc b/riscv/sim.cc index 6d98d8e..66bebb3 100644 --- a/riscv/sim.cc +++ b/riscv/sim.cc @@ -1,61 +1,61 @@ +// See LICENSE for license details. + #include "sim.h" #include "htif.h" -#include #include #include #include -#include +#include +#include +#include -#ifdef __linux__ -# define mmap mmap64 -#endif +volatile bool ctrlc_pressed = false; +static void handle_signal(int sig) +{ + if (ctrlc_pressed) + exit(-1); + ctrlc_pressed = true; + signal(sig, &handle_signal); +} -sim_t::sim_t(int _nprocs, int mem_mb, const std::vector& args) - : htif(new htif_isasim_t(this, args)), - procs(_nprocs) +sim_t::sim_t(const char* isa, size_t nprocs, size_t mem_mb, + const std::vector& args) + : htif(new htif_isasim_t(this, args)), procs(std::max(nprocs, size_t(1))), + rtc(0), current_step(0), current_proc(0), debug(false) { + signal(SIGINT, &handle_signal); // allocate target machine's memory, shrinking it as necessary // until the allocation succeeds size_t memsz0 = (size_t)mem_mb << 20; + size_t quantum = 1L << 20; if (memsz0 == 0) memsz0 = 1L << (sizeof(size_t) == 8 ? 32 : 30); - size_t quantum = std::max(PGSIZE, (reg_t)sysconf(_SC_PAGESIZE)); - memsz0 = memsz0/quantum*quantum; - memsz = memsz0; - mem = (char*)mmap(NULL, memsz, PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0); + while ((mem = (char*)calloc(1, memsz)) == NULL) + memsz = memsz*10/11/quantum*quantum; - if(mem == MAP_FAILED) - { - while(mem == MAP_FAILED && (memsz = memsz*10/11/quantum*quantum)) - mem = (char*)mmap(NULL, memsz, PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0); - assert(mem != MAP_FAILED); + if (memsz != memsz0) fprintf(stderr, "warning: only got %lu bytes of target mem (wanted %lu)\n", (unsigned long)memsz, (unsigned long)memsz0); - } - mmu = new mmu_t(mem, memsz); + debug_mmu = new mmu_t(mem, memsz); - for(size_t i = 0; i < num_cores(); i++) - procs[i] = new processor_t(this, new mmu_t(mem, memsz), i); + for (size_t i = 0; i < procs.size(); i++) + procs[i] = new processor_t(isa, this, i); } sim_t::~sim_t() { - for(size_t i = 0; i < num_cores(); i++) - { - mmu_t* pmmu = &procs[i]->mmu; + for (size_t i = 0; i < procs.size(); i++) delete procs[i]; - delete pmmu; - } - delete mmu; - munmap(mem, memsz); + delete debug_mmu; + free(mem); } void sim_t::send_ipi(reg_t who) { - if(who < num_cores()) + if (who < procs.size()) procs[who]->deliver_ipi(); } @@ -63,29 +63,84 @@ reg_t sim_t::get_scr(int which) { switch (which) { - case 0: return num_cores(); + case 0: return procs.size(); case 1: return memsz >> 20; default: return -1; } } -void sim_t::run(bool debug) +int sim_t::run() { - while (!htif->done()) + if (!debug && log) + set_procs_debug(true); + while (htif->tick()) { - if(!debug) - step_all(10000, 1000, false); - else + if (debug || ctrlc_pressed) interactive(); + else + step(INTERLEAVE); } + return htif->exit_code(); } -void sim_t::step_all(size_t n, size_t interleave, bool noisy) +void sim_t::step(size_t n) { - htif->tick(); - for(size_t j = 0; j < n; j+=interleave) + for (size_t i = 0, steps = 0; i < n; i += steps) { - for(int i = 0; i < (int)num_cores(); i++) - procs[i]->step(interleave,noisy); + steps = std::min(n - i, INTERLEAVE - current_step); + procs[current_proc]->step(steps); + + current_step += steps; + if (current_step == INTERLEAVE) + { + current_step = 0; + procs[current_proc]->yield_load_reservation(); + if (++current_proc == procs.size()) { + current_proc = 0; + rtc += INTERLEAVE / INSNS_PER_RTC_TICK; + } + + htif->tick(); + } + } +} + +bool sim_t::running() +{ + for (size_t i = 0; i < procs.size(); i++) + if (procs[i]->running()) + return true; + return false; +} + +void sim_t::stop() +{ + procs[0]->state.tohost = 1; + while (htif->tick()) + ; +} + +void sim_t::set_debug(bool value) +{ + debug = value; +} + +void sim_t::set_log(bool value) +{ + log = value; +} + +void sim_t::set_histogram(bool value) +{ + histogram_enabled = value; + for (size_t i = 0; i < procs.size(); i++) { + procs[i]->set_histogram(histogram_enabled); } } + +void sim_t::set_procs_debug(bool value) +{ + for (size_t i=0; i< procs.size(); i++) + procs[i]->set_debug(value); +} +