Browse Source

Support parsing procs fully from DTS

dts_parsing
Jerry Zhao 2 years ago
parent
commit
433c16c542
  1. 41
      riscv/dts.cc
  2. 2
      riscv/dts.h
  3. 55
      riscv/sim.cc

41
riscv/dts.cc

@ -389,3 +389,44 @@ int fdt_parse_mmu_type(const void *fdt, int cpu_offset, const char **mmu_type)
return 0;
}
int fdt_parse_isa(const void *fdt, int cpu_offset, const char **isa)
{
assert(isa);
int len, rc;
const void *prop;
if ((rc = check_cpu_node(fdt, cpu_offset)) < 0)
return rc;
prop = fdt_getprop(fdt, cpu_offset, "riscv,isa", &len);
if (!prop || !len)
return -EINVAL;
*isa = (const char *)prop;
return 0;
}
int fdt_parse_hartid(const void *fdt, int cpu_offset, uint32_t *hartid)
{
int len, rc;
const void *prop;
const fdt32_t *val;
if ((rc = check_cpu_node(fdt, cpu_offset)) < 0)
return rc;
val = (fdt32_t*) fdt_getprop(fdt, cpu_offset, "reg", &len);
if (!val || len < (int) sizeof(fdt32_t))
return -EINVAL;
if (len > (int) sizeof(fdt32_t))
val++;
if (hartid)
*hartid = fdt32_to_cpu(*val);
return 0;
}

2
riscv/dts.h

@ -29,4 +29,6 @@ int fdt_parse_ns16550(const void *fdt, reg_t *ns16550_addr,
int fdt_parse_pmp_num(const void *fdt, int cpu_offset, reg_t *pmp_num);
int fdt_parse_pmp_alignment(const void *fdt, int cpu_offset, reg_t *pmp_align);
int fdt_parse_mmu_type(const void *fdt, int cpu_offset, const char **mmu_type);
int fdt_parse_isa(const void *fdt, int cpu_offset, const char **isa_str);
int fdt_parse_hartid(const void *fdt, int cpu_offset, uint32_t *hartid);
#endif

55
riscv/sim.cc

@ -48,7 +48,6 @@ sim_t::sim_t(const cfg_t *cfg, bool halted,
: htif_t(args),
cfg(cfg),
mems(mems),
procs(std::max(cfg->nprocs(), size_t(1))),
dtb_enabled(dtb_enabled),
log_file(log_path),
cmd_file(cmd_file),
@ -97,15 +96,16 @@ sim_t::sim_t(const cfg_t *cfg, bool halted,
debug_mmu = new mmu_t(this, cfg->endianness, NULL);
// When running without using a dtb, skip the fdt-based configuration steps
if (!dtb_enabled) {
for (size_t i = 0; i < cfg->nprocs(); i++) {
procs[i] = new processor_t(cfg->isa, cfg->priv,
procs.push_back(new processor_t(cfg->isa, cfg->priv,
cfg, this, cfg->hartids[i], halted,
log_file.get(), sout_);
log_file.get(), sout_));
harts[cfg->hartids[i]] = procs[i];
return;
}
// When running without using a dtb, skip the fdt-based configuration steps
if (!dtb_enabled) return;
} // otherwise, generate the procs by parsing the DTS
// Only make a CLINT (Core-Local INTerrupt controller) and PLIC (Platform-
// Level-Interrupt-Controller) if they are specified in the device tree
@ -176,7 +176,7 @@ sim_t::sim_t(const cfg_t *cfg, bool halted,
}
}
//per core attribute
// per core attribute
int cpu_offset = 0, cpu_map_offset, rc;
size_t cpu_idx = 0;
cpu_offset = fdt_get_offset(fdt, "/cpus");
@ -190,10 +190,33 @@ sim_t::sim_t(const cfg_t *cfg, bool halted,
if (!(cpu_map_offset < 0) && cpu_offset == cpu_map_offset)
continue;
if (cpu_idx >= nprocs())
break;
if (cpu_idx != procs.size()) {
std::cerr << "Spike only supports contiguous CPU IDs in the DTS" << std::endl;
exit(1);
}
// handle isa string
const char* isa_str;
rc = fdt_parse_isa(fdt, cpu_offset, &isa_str);
if (rc != 0) {
std::cerr << "core (" << cpu_idx << ") has an invalid or missing 'riscv,isa'\n";
exit(1);
}
//handle pmp
// handle hartid
uint32_t hartid;
rc = fdt_parse_hartid(fdt, cpu_offset, &hartid);
if (rc != 0) {
std::cerr << "core (" << cpu_idx << ") has an invalid or missing `reg` (hartid)\n";
exit(1);
}
procs.push_back(new processor_t(isa_str, DEFAULT_PRIV,
cfg, this, hartid, halted,
log_file.get(), sout_));
harts[hartid] = procs[cpu_idx];
// handle pmp
reg_t pmp_num, pmp_granularity;
if (fdt_parse_pmp_num(fdt, cpu_offset, &pmp_num) != 0)
pmp_num = 0;
@ -203,7 +226,7 @@ sim_t::sim_t(const cfg_t *cfg, bool halted,
procs[cpu_idx]->set_pmp_granularity(pmp_granularity);
}
//handle mmu-type
// handle mmu-type
const char *mmu_type;
rc = fdt_parse_mmu_type(fdt, cpu_offset, &mmu_type);
if (rc == 0) {
@ -217,7 +240,7 @@ sim_t::sim_t(const cfg_t *cfg, bool halted,
} else if (strncmp(mmu_type, "riscv,sv57", strlen("riscv,sv57")) == 0) {
procs[cpu_idx]->set_mmu_capability(IMPL_MMU_SV57);
} else if (strncmp(mmu_type, "riscv,sbare", strlen("riscv,sbare")) == 0) {
//has been set in the beginning
// has been set in the beginning
} else {
std::cerr << "core ("
<< cpu_idx
@ -231,14 +254,6 @@ sim_t::sim_t(const cfg_t *cfg, bool halted,
cpu_idx++;
}
if (cpu_idx != nprocs()) {
std::cerr << "core number in dts ("
<< cpu_idx
<< ") doesn't match it in command line ("
<< nprocs() << ").\n";
exit(1);
}
}
sim_t::~sim_t()

Loading…
Cancel
Save