diff options
author | Jerry Zhao <jerryz123@berkeley.edu> | 2024-06-30 14:55:46 -0700 |
---|---|---|
committer | Jerry Zhao <jerryz123@berkeley.edu> | 2024-06-30 14:55:46 -0700 |
commit | 433c16c542ad784a81640c8a9568f135ec0afcb2 (patch) | |
tree | 8b59421df2342061391393542227d1e9bbf5bf61 | |
parent | 0681949269b4b26239c42c621be7b5cb1cf299bf (diff) | |
download | spike-dts_parsing.zip spike-dts_parsing.tar.gz spike-dts_parsing.tar.bz2 |
Support parsing procs fully from DTSdts_parsing
-rw-r--r-- | riscv/dts.cc | 41 | ||||
-rw-r--r-- | riscv/dts.h | 2 | ||||
-rw-r--r-- | riscv/sim.cc | 61 |
3 files changed, 81 insertions, 23 deletions
diff --git a/riscv/dts.cc b/riscv/dts.cc index a195257..7f50dd8 100644 --- a/riscv/dts.cc +++ b/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; +} diff --git a/riscv/dts.h b/riscv/dts.h index 93a0b15..d58093b 100644 --- a/riscv/dts.h +++ b/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 diff --git a/riscv/sim.cc b/riscv/sim.cc index 1c1f65a..37f676c 100644 --- a/riscv/sim.cc +++ b/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); - for (size_t i = 0; i < cfg->nprocs(); i++) { - procs[i] = new processor_t(cfg->isa, cfg->priv, - cfg, this, cfg->hartids[i], halted, - log_file.get(), sout_); - harts[cfg->hartids[i]] = procs[i]; - } - // When running without using a dtb, skip the fdt-based configuration steps - if (!dtb_enabled) return; + if (!dtb_enabled) { + for (size_t i = 0; i < cfg->nprocs(); i++) { + procs.push_back(new processor_t(cfg->isa, cfg->priv, + cfg, this, cfg->hartids[i], halted, + log_file.get(), sout_)); + harts[cfg->hartids[i]] = procs[i]; + 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() |