Skip to content

Commit f11bd7b

Browse files
jerryz123abejgonzalez
authored andcommitted
Support parsing procs fully from DTS
1 parent 6f4116d commit f11bd7b

File tree

3 files changed

+97
-38
lines changed

3 files changed

+97
-38
lines changed

riscv/dts.cc

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,3 +389,44 @@ int fdt_parse_mmu_type(const void *fdt, int cpu_offset, const char **mmu_type)
389389

390390
return 0;
391391
}
392+
393+
int fdt_parse_isa(const void *fdt, int cpu_offset, const char **isa)
394+
{
395+
assert(isa);
396+
397+
int len, rc;
398+
const void *prop;
399+
400+
if ((rc = check_cpu_node(fdt, cpu_offset)) < 0)
401+
return rc;
402+
403+
prop = fdt_getprop(fdt, cpu_offset, "riscv,isa", &len);
404+
if (!prop || !len)
405+
return -EINVAL;
406+
407+
*isa = (const char *)prop;
408+
409+
return 0;
410+
}
411+
412+
int fdt_parse_hartid(const void *fdt, int cpu_offset, uint32_t *hartid)
413+
{
414+
int len, rc;
415+
const void *prop;
416+
const fdt32_t *val;
417+
418+
if ((rc = check_cpu_node(fdt, cpu_offset)) < 0)
419+
return rc;
420+
421+
val = (fdt32_t*) fdt_getprop(fdt, cpu_offset, "reg", &len);
422+
if (!val || len < (int) sizeof(fdt32_t))
423+
return -EINVAL;
424+
425+
if (len > (int) sizeof(fdt32_t))
426+
val++;
427+
428+
if (hartid)
429+
*hartid = fdt32_to_cpu(*val);
430+
431+
return 0;
432+
}

riscv/dts.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,6 @@ int fdt_parse_ns16550(const void *fdt, reg_t *ns16550_addr,
2929
int fdt_parse_pmp_num(const void *fdt, int cpu_offset, reg_t *pmp_num);
3030
int fdt_parse_pmp_alignment(const void *fdt, int cpu_offset, reg_t *pmp_align);
3131
int fdt_parse_mmu_type(const void *fdt, int cpu_offset, const char **mmu_type);
32+
int fdt_parse_isa(const void *fdt, int cpu_offset, const char **isa_str);
33+
int fdt_parse_hartid(const void *fdt, int cpu_offset, uint32_t *hartid);
3234
#endif

riscv/sim.cc

Lines changed: 54 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)