summaryrefslogtreecommitdiff
path: root/lib/utils/fdt
diff options
context:
space:
mode:
authorAnup Patel <anup.patel@wdc.com>2020-03-19 08:53:41 +0300
committerAnup Patel <anup@brainfault.org>2020-03-28 11:01:50 +0300
commit160c88535f07084051ebba97689fc4a7b2e9037c (patch)
tree593e42dc4a3165d5fcb8740f192be2ee4ebd631b /lib/utils/fdt
parent550ba88db1950d448f25cf71457ed89a91c401f7 (diff)
downloadopensbi-160c88535f07084051ebba97689fc4a7b2e9037c.tar.xz
lib: utils: Improve fdt_cpu_fixup() implementation
Currently, the fdt_cpu_fixup() implementation assumes: 1. We have one CPU DT for each HART under /cpus DT node 2. The CPU DT nodes are named sequentially (i.e cpu@0, cpu@1, ...) which is not true for discontinuous and sparse HART ids (i.e. cpu@0, cpu@4, cpu@5). Generally, CPU DT node are named based on HART id and not HART index If any of the above assumptions are violated then the fdt_cpu_fixup() will not work. This improves fdt_cpu_fixup() implementation and makes it independent of above assumptions. Signed-off-by: Anup Patel <anup.patel@wdc.com> Reviewed-by: Bin Meng <bmeng.cn@gmail.com> Reviewed-by: Atish Patra <atish.patra@wdc.com>
Diffstat (limited to 'lib/utils/fdt')
-rw-r--r--lib/utils/fdt/fdt_fixup.c35
1 files changed, 24 insertions, 11 deletions
diff --git a/lib/utils/fdt/fdt_fixup.c b/lib/utils/fdt/fdt_fixup.c
index b91e95f..d6e4cc1 100644
--- a/lib/utils/fdt/fdt_fixup.c
+++ b/lib/utils/fdt/fdt_fixup.c
@@ -12,30 +12,43 @@
#include <sbi/sbi_console.h>
#include <sbi/sbi_platform.h>
#include <sbi/sbi_scratch.h>
+#include <sbi/sbi_string.h>
void fdt_cpu_fixup(void *fdt)
{
struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
const struct sbi_platform *plat = sbi_platform_ptr(scratch);
- char cpu_node[32] = "";
- int cpu_offset;
- int err;
- u32 i;
+ int err, len, cpu_offset, cpus_offset;
+ const fdt32_t *val;
+ const void *prop;
+ u32 hartid;
err = fdt_open_into(fdt, fdt, fdt_totalsize(fdt) + 32);
if (err < 0)
return;
- /* assume hart ids are continuous */
- for (i = 0; i < sbi_platform_hart_count(plat); i++) {
- sbi_sprintf(cpu_node, "/cpus/cpu@%d", i);
- cpu_offset = fdt_path_offset(fdt, cpu_node);
+ cpus_offset = fdt_path_offset(fdt, "/cpus");
+ if (cpus_offset < 0)
+ return;
+
+ fdt_for_each_subnode(cpu_offset, fdt, cpus_offset) {
+ prop = fdt_getprop(fdt, cpu_offset, "device_type", &len);
+ if (!prop || !len)
+ continue;
+ if (sbi_strcmp(prop, "cpu"))
+ continue;
- if (sbi_platform_hart_invalid(plat, i))
+ val = fdt_getprop(fdt, cpu_offset, "reg", &len);
+ if (!val || len < sizeof(fdt32_t))
+ continue;
+
+ if (len > sizeof(fdt32_t))
+ val++;
+ hartid = fdt32_to_cpu(*val);
+
+ if (sbi_platform_hart_invalid(plat, hartid))
fdt_setprop_string(fdt, cpu_offset, "status",
"disabled");
-
- memset(cpu_node, 0, sizeof(cpu_node));
}
}