1 // See LICENSE for license details.
16 sim_t::sim_t(size_t _nprocs
, size_t mem_mb
, const std::vector
<std::string
>& args
)
17 : htif(new htif_isasim_t(this, args
)),
18 procs(_nprocs
), current_step(0), current_proc(0), debug(false)
20 // allocate target machine's memory, shrinking it as necessary
21 // until the allocation succeeds
22 size_t memsz0
= (size_t)mem_mb
<< 20;
24 memsz0
= 1L << (sizeof(size_t) == 8 ? 32 : 30);
26 size_t quantum
= std::max(PGSIZE
, (reg_t
)sysconf(_SC_PAGESIZE
));
27 memsz0
= memsz0
/quantum
*quantum
;
30 mem
= (char*)mmap(NULL
, memsz
, PROT_WRITE
, MAP_PRIVATE
|MAP_ANON
, -1, 0);
34 while(mem
== MAP_FAILED
&& (memsz
= memsz
*10/11/quantum
*quantum
))
35 mem
= (char*)mmap(NULL
, memsz
, PROT_WRITE
, MAP_PRIVATE
|MAP_ANON
, -1, 0);
36 assert(mem
!= MAP_FAILED
);
37 fprintf(stderr
, "warning: only got %lu bytes of target mem (wanted %lu)\n",
38 (unsigned long)memsz
, (unsigned long)memsz0
);
41 mmu
= new mmu_t(mem
, memsz
);
45 for (size_t i
= 0; i
< _nprocs
; i
++)
46 procs
[i
] = new processor_t(this, new mmu_t(mem
, memsz
), i
);
51 for (size_t i
= 0; i
< procs
.size(); i
++)
53 mmu_t
* pmmu
= &procs
[i
]->mmu
;
61 void sim_t::send_ipi(reg_t who
)
63 if (who
< procs
.size())
64 procs
[who
]->deliver_ipi();
67 reg_t
sim_t::get_scr(int which
)
71 case 0: return procs
.size();
72 case 1: return memsz
>> 20;
84 step(INTERLEAVE
, false);
88 void sim_t::step(size_t n
, bool noisy
)
90 for (size_t i
= 0, steps
= 0; i
< n
; i
+= steps
)
96 steps
= std::min(n
- i
, INTERLEAVE
- current_step
);
97 procs
[current_proc
]->step(steps
, noisy
);
99 current_step
+= steps
;
100 if (current_step
== INTERLEAVE
)
103 procs
[current_proc
]->mmu
.yield_load_reservation();
104 if (++current_proc
== procs
.size())
110 bool sim_t::running()
112 for (size_t i
= 0; i
< procs
.size(); i
++)
113 if (procs
[i
]->running())
120 procs
[0]->tohost
= 1;
121 while (!htif
->done())