mirror of
https://github.com/riscv-software-src/opensbi.git
synced 2025-08-24 23:41:23 +01:00
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>
This commit is contained in:
@@ -12,30 +12,43 @@
|
|||||||
#include <sbi/sbi_console.h>
|
#include <sbi/sbi_console.h>
|
||||||
#include <sbi/sbi_platform.h>
|
#include <sbi/sbi_platform.h>
|
||||||
#include <sbi/sbi_scratch.h>
|
#include <sbi/sbi_scratch.h>
|
||||||
|
#include <sbi/sbi_string.h>
|
||||||
|
|
||||||
void fdt_cpu_fixup(void *fdt)
|
void fdt_cpu_fixup(void *fdt)
|
||||||
{
|
{
|
||||||
struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
|
struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
|
||||||
const struct sbi_platform *plat = sbi_platform_ptr(scratch);
|
const struct sbi_platform *plat = sbi_platform_ptr(scratch);
|
||||||
char cpu_node[32] = "";
|
int err, len, cpu_offset, cpus_offset;
|
||||||
int cpu_offset;
|
const fdt32_t *val;
|
||||||
int err;
|
const void *prop;
|
||||||
u32 i;
|
u32 hartid;
|
||||||
|
|
||||||
err = fdt_open_into(fdt, fdt, fdt_totalsize(fdt) + 32);
|
err = fdt_open_into(fdt, fdt, fdt_totalsize(fdt) + 32);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* assume hart ids are continuous */
|
cpus_offset = fdt_path_offset(fdt, "/cpus");
|
||||||
for (i = 0; i < sbi_platform_hart_count(plat); i++) {
|
if (cpus_offset < 0)
|
||||||
sbi_sprintf(cpu_node, "/cpus/cpu@%d", i);
|
return;
|
||||||
cpu_offset = fdt_path_offset(fdt, cpu_node);
|
|
||||||
|
|
||||||
if (sbi_platform_hart_invalid(plat, i))
|
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;
|
||||||
|
|
||||||
|
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",
|
fdt_setprop_string(fdt, cpu_offset, "status",
|
||||||
"disabled");
|
"disabled");
|
||||||
|
|
||||||
memset(cpu_node, 0, sizeof(cpu_node));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user