forked from Mirrors/opensbi
		
	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_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;
 | 
			
		||||
 | 
			
		||||
		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",
 | 
			
		||||
					   "disabled");
 | 
			
		||||
 | 
			
		||||
		memset(cpu_node, 0, sizeof(cpu_node));
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user