@@ -48,7 +48,6 @@ sim_t::sim_t(const cfg_t *cfg, bool halted,
48
48
: htif_t (args),
49
49
cfg (cfg),
50
50
mems(mems),
51
- procs(std::max(cfg->nprocs (), size_t(1 ))),
52
51
dtb_enabled(dtb_enabled),
53
52
log_file(log_path),
54
53
cmd_file(cmd_file),
@@ -97,15 +96,16 @@ sim_t::sim_t(const cfg_t *cfg, bool halted,
97
96
98
97
debug_mmu = new mmu_t (this , cfg->endianness , NULL );
99
98
100
- for (size_t i = 0 ; i < cfg->nprocs (); i++) {
101
- procs[i] = new processor_t (cfg->isa , cfg->priv ,
102
- cfg, this , cfg->hartids [i], halted,
103
- log_file.get (), sout_);
104
- harts[cfg->hartids [i]] = procs[i];
105
- }
106
-
107
99
// When running without using a dtb, skip the fdt-based configuration steps
108
- if (!dtb_enabled) return ;
100
+ if (!dtb_enabled) {
101
+ for (size_t i = 0 ; i < cfg->nprocs (); i++) {
102
+ procs.push_back (new processor_t (cfg->isa , cfg->priv ,
103
+ cfg, this , cfg->hartids [i], halted,
104
+ log_file.get (), sout_));
105
+ harts[cfg->hartids [i]] = procs[i];
106
+ return ;
107
+ }
108
+ } // otherwise, generate the procs by parsing the DTS
109
109
110
110
// Only make a CLINT (Core-Local INTerrupt controller) and PLIC (Platform-
111
111
// Level-Interrupt-Controller) if they are specified in the device tree
@@ -159,24 +159,7 @@ sim_t::sim_t(const cfg_t *cfg, bool halted,
159
159
160
160
void *fdt = (void *)dtb.c_str ();
161
161
162
- for (size_t i = 0 ; i < device_factories.size (); i++) {
163
- const device_factory_t * factory = device_factories[i].first ;
164
- const std::vector<std::string>& sargs = device_factories[i].second ;
165
- reg_t device_base = 0 ;
166
- abstract_device_t * device = factory->parse_from_fdt (fdt, this , &device_base, sargs);
167
- if (device) {
168
- assert (device_base);
169
- std::shared_ptr<abstract_device_t > dev_ptr (device);
170
- add_device (device_base, dev_ptr);
171
-
172
- if (i == 0 ) // clint_factory
173
- clint = std::static_pointer_cast<clint_t >(dev_ptr);
174
- else if (i == 1 ) // plic_factory
175
- plic = std::static_pointer_cast<plic_t >(dev_ptr);
176
- }
177
- }
178
-
179
- // per core attribute
162
+ // per core attribute
180
163
int cpu_offset = 0 , cpu_map_offset, rc;
181
164
size_t cpu_idx = 0 ;
182
165
cpu_offset = fdt_get_offset (fdt, " /cpus" );
@@ -190,10 +173,33 @@ sim_t::sim_t(const cfg_t *cfg, bool halted,
190
173
if (!(cpu_map_offset < 0 ) && cpu_offset == cpu_map_offset)
191
174
continue ;
192
175
193
- if (cpu_idx >= nprocs ())
194
- break ;
176
+ if (cpu_idx != procs.size ()) {
177
+ std::cerr << " Spike only supports contiguous CPU IDs in the DTS" << std::endl;
178
+ exit (1 );
179
+ }
195
180
196
- // handle pmp
181
+ // handle isa string
182
+ const char * isa_str;
183
+ rc = fdt_parse_isa (fdt, cpu_offset, &isa_str);
184
+ if (rc != 0 ) {
185
+ std::cerr << " core (" << cpu_idx << " ) has an invalid or missing 'riscv,isa'\n " ;
186
+ exit (1 );
187
+ }
188
+
189
+ // handle hartid
190
+ uint32_t hartid;
191
+ rc = fdt_parse_hartid (fdt, cpu_offset, &hartid);
192
+ if (rc != 0 ) {
193
+ std::cerr << " core (" << cpu_idx << " ) has an invalid or missing `reg` (hartid)\n " ;
194
+ exit (1 );
195
+ }
196
+
197
+ procs.push_back (new processor_t (isa_str, DEFAULT_PRIV,
198
+ cfg, this , hartid, halted,
199
+ log_file.get (), sout_));
200
+ harts[hartid] = procs[cpu_idx];
201
+
202
+ // handle pmp
197
203
reg_t pmp_num, pmp_granularity;
198
204
if (fdt_parse_pmp_num (fdt, cpu_offset, &pmp_num) != 0 )
199
205
pmp_num = 0 ;
@@ -203,7 +209,7 @@ sim_t::sim_t(const cfg_t *cfg, bool halted,
203
209
procs[cpu_idx]->set_pmp_granularity (pmp_granularity);
204
210
}
205
211
206
- // handle mmu-type
212
+ // handle mmu-type
207
213
const char *mmu_type;
208
214
rc = fdt_parse_mmu_type (fdt, cpu_offset, &mmu_type);
209
215
if (rc == 0 ) {
@@ -217,7 +223,7 @@ sim_t::sim_t(const cfg_t *cfg, bool halted,
217
223
} else if (strncmp (mmu_type, " riscv,sv57" , strlen (" riscv,sv57" )) == 0 ) {
218
224
procs[cpu_idx]->set_mmu_capability (IMPL_MMU_SV57);
219
225
} else if (strncmp (mmu_type, " riscv,sbare" , strlen (" riscv,sbare" )) == 0 ) {
220
- // has been set in the beginning
226
+ // has been set in the beginning
221
227
} else {
222
228
std::cerr << " core ("
223
229
<< cpu_idx
@@ -232,12 +238,22 @@ sim_t::sim_t(const cfg_t *cfg, bool halted,
232
238
cpu_idx++;
233
239
}
234
240
235
- if (cpu_idx != nprocs ()) {
236
- std::cerr << " core number in dts ("
237
- << cpu_idx
238
- << " ) doesn't match it in command line ("
239
- << nprocs () << " ).\n " ;
240
- exit (1 );
241
+ // must be located after procs/harts are set (devices might use sim_t get_* member functions)
242
+ for (size_t i = 0 ; i < device_factories.size (); i++) {
243
+ const device_factory_t * factory = device_factories[i].first ;
244
+ const std::vector<std::string>& sargs = device_factories[i].second ;
245
+ reg_t device_base = 0 ;
246
+ abstract_device_t * device = factory->parse_from_fdt (fdt, this , &device_base, sargs);
247
+ if (device) {
248
+ assert (device_base);
249
+ std::shared_ptr<abstract_device_t > dev_ptr (device);
250
+ add_device (device_base, dev_ptr);
251
+
252
+ if (i == 0 ) // clint_factory
253
+ clint = std::static_pointer_cast<clint_t >(dev_ptr);
254
+ else if (i == 1 ) // plic_factory
255
+ plic = std::static_pointer_cast<plic_t >(dev_ptr);
256
+ }
241
257
}
242
258
}
243
259
0 commit comments