@@ -48,7 +48,6 @@ sim_t::sim_t(const cfg_t *cfg, bool halted,
4848 : htif_t (args),
4949 cfg (cfg),
5050 mems(mems),
51- procs(std::max(cfg->nprocs (), size_t(1 ))),
5251 dtb_enabled(dtb_enabled),
5352 log_file(log_path),
5453 cmd_file(cmd_file),
@@ -97,15 +96,16 @@ sim_t::sim_t(const cfg_t *cfg, bool halted,
9796
9897 debug_mmu = new mmu_t (this , cfg->endianness , NULL );
9998
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-
10799 // 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
109109
110110 // Only make a CLINT (Core-Local INTerrupt controller) and PLIC (Platform-
111111 // 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,
159159
160160 void *fdt = (void *)dtb.c_str ();
161161
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
180163 int cpu_offset = 0 , cpu_map_offset, rc;
181164 size_t cpu_idx = 0 ;
182165 cpu_offset = fdt_get_offset (fdt, " /cpus" );
@@ -190,10 +173,33 @@ sim_t::sim_t(const cfg_t *cfg, bool halted,
190173 if (!(cpu_map_offset < 0 ) && cpu_offset == cpu_map_offset)
191174 continue ;
192175
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+ }
195180
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
197203 reg_t pmp_num, pmp_granularity;
198204 if (fdt_parse_pmp_num (fdt, cpu_offset, &pmp_num) != 0 )
199205 pmp_num = 0 ;
@@ -203,7 +209,7 @@ sim_t::sim_t(const cfg_t *cfg, bool halted,
203209 procs[cpu_idx]->set_pmp_granularity (pmp_granularity);
204210 }
205211
206- // handle mmu-type
212+ // handle mmu-type
207213 const char *mmu_type;
208214 rc = fdt_parse_mmu_type (fdt, cpu_offset, &mmu_type);
209215 if (rc == 0 ) {
@@ -217,7 +223,7 @@ sim_t::sim_t(const cfg_t *cfg, bool halted,
217223 } else if (strncmp (mmu_type, " riscv,sv57" , strlen (" riscv,sv57" )) == 0 ) {
218224 procs[cpu_idx]->set_mmu_capability (IMPL_MMU_SV57);
219225 } 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
221227 } else {
222228 std::cerr << " core ("
223229 << cpu_idx
@@ -232,12 +238,22 @@ sim_t::sim_t(const cfg_t *cfg, bool halted,
232238 cpu_idx++;
233239 }
234240
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+ }
241257 }
242258}
243259
0 commit comments