diff options
-rw-r--r-- | riscv/dts.cc | 53 | ||||
-rw-r--r-- | riscv/dts.h | 6 | ||||
-rw-r--r-- | riscv/sim.cc | 25 |
3 files changed, 46 insertions, 38 deletions
diff --git a/riscv/dts.cc b/riscv/dts.cc index 9469e3f..93e72f3 100644 --- a/riscv/dts.cc +++ b/riscv/dts.cc @@ -225,6 +225,24 @@ static int fdt_get_node_addr_size(void *fdt, int node, reg_t *addr, return 0; } +static int check_cpu_node(void *fdt, int cpu_offset) +{ + int len; + const void *prop; + + if (!fdt || cpu_offset < 0) + return -EINVAL; + + prop = fdt_getprop(fdt, cpu_offset, "device_type", &len); + if (!prop || !len) + return -EINVAL; + if (strncmp ((char *)prop, "cpu", strlen ("cpu"))) + return -EINVAL; + + return 0; +} + + int fdt_get_offset(void *fdt, const char *field) { return fdt_path_offset(fdt, field); @@ -256,15 +274,14 @@ int fdt_parse_clint(void *fdt, reg_t *clint_addr, return 0; } -int fdt_parse_pmp_num(void *fdt, reg_t *pmp_num, const char *compatible) +int fdt_parse_pmp_num(void *fdt, int cpu_offset, reg_t *pmp_num) { - int nodeoffset, rc; + int rc; - nodeoffset = fdt_node_offset_by_compatible(fdt, -1, compatible); - if (nodeoffset < 0) - return nodeoffset; + if ((rc = check_cpu_node(fdt, cpu_offset)) < 0) + return rc; - rc = fdt_get_node_addr_size(fdt, nodeoffset, pmp_num, NULL, + rc = fdt_get_node_addr_size(fdt, cpu_offset, pmp_num, NULL, "riscv,pmpregions"); if (rc < 0 || !pmp_num) return -ENODEV; @@ -272,16 +289,14 @@ int fdt_parse_pmp_num(void *fdt, reg_t *pmp_num, const char *compatible) return 0; } -int fdt_parse_pmp_alignment(void *fdt, reg_t *pmp_align, - const char *compatible) +int fdt_parse_pmp_alignment(void *fdt, int cpu_offset, reg_t *pmp_align) { - int nodeoffset, rc; + int rc; - nodeoffset = fdt_node_offset_by_compatible(fdt, -1, compatible); - if (nodeoffset < 0) - return nodeoffset; + if ((rc = check_cpu_node(fdt, cpu_offset)) < 0) + return rc; - rc = fdt_get_node_addr_size(fdt, nodeoffset, pmp_align, NULL, + rc = fdt_get_node_addr_size(fdt, cpu_offset, pmp_align, NULL, "riscv,pmpgranularity"); if (rc < 0 || !pmp_align) return -ENODEV; @@ -291,17 +306,11 @@ int fdt_parse_pmp_alignment(void *fdt, reg_t *pmp_align, int fdt_parse_mmu_type(void *fdt, int cpu_offset, char *mmu_type) { - int len; + int len, rc; const void *prop; - if (!fdt || cpu_offset < 0) - return -EINVAL; - - prop = fdt_getprop(fdt, cpu_offset, "device_type", &len); - if (!prop || !len) - return -EINVAL; - if (strncmp ((char *)prop, "cpu", strlen ("cpu"))) - return -EINVAL; + if ((rc = check_cpu_node(fdt, cpu_offset)) < 0) + return rc; prop = fdt_getprop(fdt, cpu_offset, "mmu-type", &len); if (!prop || !len) diff --git a/riscv/dts.h b/riscv/dts.h index 69dcb31..090bb7c 100644 --- a/riscv/dts.h +++ b/riscv/dts.h @@ -20,9 +20,7 @@ int fdt_get_next_subnode(void *fdt, int node); int fdt_parse_clint(void *fdt, reg_t *clint_addr, const char *compatible); -int fdt_parse_pmp_num(void *fdt, reg_t *pmp_num, - const char *compatible); -int fdt_parse_pmp_alignment(void *fdt, reg_t *pmp_align, - const char *compatible); +int fdt_parse_pmp_num(void *fdt, int cpu_offset, reg_t *pmp_num); +int fdt_parse_pmp_alignment(void *fdt, int cpu_offset, reg_t *pmp_align); int fdt_parse_mmu_type(void *fdt, int cpu_offset, char *mmu_type); #endif diff --git a/riscv/sim.cc b/riscv/sim.cc index 13329f4..20895d6 100644 --- a/riscv/sim.cc +++ b/riscv/sim.cc @@ -83,26 +83,17 @@ sim_t::sim_t(const char* isa, const char* priv, const char* varch, make_dtb(); + void *fdt = (void *)dtb.c_str(); //handle clic clint.reset(new clint_t(procs, CPU_HZ / INSNS_PER_RTC_TICK, real_time_clint)); reg_t clint_base; - if (fdt_parse_clint((void *)dtb.c_str(), &clint_base, "riscv,clint0")) { + if (fdt_parse_clint(fdt, &clint_base, "riscv,clint0")) { bus.add_device(CLINT_BASE, clint.get()); } else { bus.add_device(clint_base, clint.get()); } - //handle pmp - for (size_t i = 0; i < nprocs; i++) { - reg_t pmp_num = 0, pmp_granularity = 0; - fdt_parse_pmp_num((void *)dtb.c_str(), &pmp_num, "riscv"); - fdt_parse_pmp_alignment((void *)dtb.c_str(), &pmp_granularity, "riscv"); - - procs[i]->set_pmp_num(pmp_num); - procs[i]->set_pmp_granularity(pmp_granularity); - } - - void *fdt = (void *)dtb.c_str(); + //per core attribute int cpu_offset = 0, rc; size_t cpu_idx = 0; cpu_offset = fdt_get_offset(fdt, "/cpus"); @@ -115,6 +106,16 @@ sim_t::sim_t(const char* isa, const char* priv, const char* varch, if (cpu_idx >= nprocs) break; + //handle pmp + reg_t pmp_num = 0, pmp_granularity = 0; + if (fdt_parse_pmp_num(fdt, cpu_offset, &pmp_num) == 0) { + procs[cpu_idx]->set_pmp_num(pmp_num); + } + + if (fdt_parse_pmp_alignment(fdt, cpu_offset, &pmp_granularity) == 0) { + procs[cpu_idx]->set_pmp_granularity(pmp_granularity); + } + //handle mmu-type char mmu_type[256] = ""; rc = fdt_parse_mmu_type(fdt, cpu_offset, mmu_type); |