5de93f294c287b1d7fb040cd259f36a348ea604c
1 // See LICENSE for license details.
5 #include "devicetree.h"
13 volatile bool ctrlc_pressed
= false;
14 static void handle_signal(int sig
)
19 signal(sig
, &handle_signal
);
22 sim_t::sim_t(const char* isa
, size_t nprocs
, size_t mem_mb
,
23 const std::vector
<std::string
>& args
)
24 : htif(new htif_isasim_t(this, args
)), procs(std::max(nprocs
, size_t(1))),
25 rtc(0), current_step(0), current_proc(0), debug(false)
27 signal(SIGINT
, &handle_signal
);
28 // allocate target machine's memory, shrinking it as necessary
29 // until the allocation succeeds
30 size_t memsz0
= (size_t)mem_mb
<< 20;
31 size_t quantum
= 1L << 20;
33 memsz0
= (size_t)((sizeof(size_t) == 8 ? 4096 : 2048) - 256) << 20;
36 while ((mem
= (char*)calloc(1, memsz
)) == NULL
)
37 memsz
= (size_t)(memsz
*0.9)/quantum
*quantum
;
40 fprintf(stderr
, "warning: only got %lu bytes of target mem (wanted %lu)\n",
41 (unsigned long)memsz
, (unsigned long)memsz0
);
43 debug_mmu
= new mmu_t(mem
, memsz
);
45 for (size_t i
= 0; i
< procs
.size(); i
++)
46 procs
[i
] = new processor_t(isa
, this, i
);
53 for (size_t i
= 0; i
< procs
.size(); i
++)
59 reg_t
sim_t::get_scr(int which
)
63 case 0: return procs
.size();
64 case 1: return memsz
>> 20;
72 set_procs_debug(true);
75 if (debug
|| ctrlc_pressed
)
80 return htif
->exit_code();
83 void sim_t::step(size_t n
)
85 for (size_t i
= 0, steps
= 0; i
< n
; i
+= steps
)
87 steps
= std::min(n
- i
, INTERLEAVE
- current_step
);
88 procs
[current_proc
]->step(steps
);
90 current_step
+= steps
;
91 if (current_step
== INTERLEAVE
)
94 procs
[current_proc
]->yield_load_reservation();
95 if (++current_proc
== procs
.size()) {
97 rtc
+= INTERLEAVE
/ INSNS_PER_RTC_TICK
;
105 bool sim_t::running()
107 for (size_t i
= 0; i
< procs
.size(); i
++)
108 if (procs
[i
]->running())
115 procs
[0]->state
.tohost
= 1;
120 void sim_t::set_debug(bool value
)
125 void sim_t::set_log(bool value
)
130 void sim_t::set_histogram(bool value
)
132 histogram_enabled
= value
;
133 for (size_t i
= 0; i
< procs
.size(); i
++) {
134 procs
[i
]->set_histogram(histogram_enabled
);
138 void sim_t::set_procs_debug(bool value
)
140 for (size_t i
=0; i
< procs
.size(); i
++)
141 procs
[i
]->set_debug(value
);
144 bool sim_t::mmio_load(reg_t addr
, size_t len
, uint8_t* bytes
)
146 if (addr
+ len
< addr
)
148 return bus
.load(addr
, len
, bytes
);
151 bool sim_t::mmio_store(reg_t addr
, size_t len
, const uint8_t* bytes
)
153 if (addr
+ len
< addr
)
155 return bus
.store(addr
, len
, bytes
);
158 void sim_t::make_device_tree()
161 size_t max_devtree_size
= procs
.size() * 4096; // sloppy upper bound
162 size_t cpu_size
= NCSR
* procs
[0]->max_xlen
/ 8;
163 reg_t cpu_addr
= memsz
+ max_devtree_size
;
167 dt
.add_prop("#address-cells", 2);
168 dt
.add_prop("#size-cells", 2);
169 dt
.add_prop("model", "Spike");
170 dt
.begin_node("memory@0");
171 dt
.add_prop("device_type", "memory");
172 dt
.add_reg({0, memsz
});
174 dt
.begin_node("cpus");
175 dt
.add_prop("#address-cells", 2);
176 dt
.add_prop("#size-cells", 2);
177 for (size_t i
= 0; i
< procs
.size(); i
++) {
178 sprintf(buf
, "cpu@%" PRIx64
, cpu_addr
);
180 dt
.add_prop("device_type", "cpu");
181 dt
.add_prop("compatible", "riscv");
182 dt
.add_prop("isa", procs
[i
]->isa_string
);
183 dt
.add_reg({cpu_addr
});
186 bus
.add_device(cpu_addr
, procs
[i
]);
187 cpu_addr
+= cpu_size
;
192 devicetree
.reset(new rom_device_t(dt
.finalize()));
193 bus
.add_device(memsz
, devicetree
.get());