[PATCH v1] lib:platform: Add support for specify coldboot harts in DT for generic.

Xiang W wxjstz at 126.com
Tue Jan 30 02:41:27 PST 2024


在 2024-01-27星期六的 14:05 +0800,Cheng Yang写道:
> Added support for the generic platform to specify the set of coldboot
> hart in DT. If not specified in DT, all harts are allowed to coldboot
> as before.
> 
> The functions related to sbi_hartmask are not available before coldboot,
> so I used bitmap, and added a new bitmap_test() function to test whether
> a certain bit of the bitmap is set.
> 
> Signed-off-by: Cheng Yang <yangcheng.work at foxmail.com>
> ---
>  include/sbi/sbi_bitmap.h    |  5 +++
>  lib/utils/fdt/fdt_fixup.c   | 18 ++++++++++
>  platform/generic/platform.c | 71 ++++++++++++++++++++++++++++++++++++-
>  3 files changed, 93 insertions(+), 1 deletion(-)
> 
> diff --git a/include/sbi/sbi_bitmap.h b/include/sbi/sbi_bitmap.h
> index 4f0ebb6..354476c 100644
> --- a/include/sbi/sbi_bitmap.h
> +++ b/include/sbi/sbi_bitmap.h
> @@ -62,6 +62,11 @@ static inline void bitmap_zero(unsigned long *dst, int nbits)
>  	}
>  }
>  
> +static inline int bitmap_test(unsigned long *bmap, int bit)
> +{
> +	return __test_bit(bit, bmap);
> +}
> +
>  static inline void bitmap_zero_except(unsigned long *dst,
>  				      int exception, int nbits)
>  {
> diff --git a/lib/utils/fdt/fdt_fixup.c b/lib/utils/fdt/fdt_fixup.c
> index 5fc7673..0d0df2c 100644
> --- a/lib/utils/fdt/fdt_fixup.c
> +++ b/lib/utils/fdt/fdt_fixup.c
> @@ -385,6 +385,22 @@ int fdt_reserved_memory_fixup(void *fdt)
>  	return 0;
>  }
>  
> +void fdt_config_fixup(void *fdt) {
> +	int chosen_offset, config_offset;
> +
> +	chosen_offset = fdt_path_offset(fdt, "/chosen");
> +	if (chosen_offset < 0) {
> +		return;
> +	}
There is only one statement, Remove brackets
> +
> +	config_offset = fdt_node_offset_by_compatible(fdt, chosen_offset, "opensbi,config");
> +	if (chosen_offset < 0) {
> +		return;
> +	}
the same as above
> +
> +	fdt_nop_node(fdt, config_offset);
> +}
> +
>  void fdt_fixups(void *fdt)
>  {
>  	fdt_aplic_fixup(fdt);
> @@ -398,4 +414,6 @@ void fdt_fixups(void *fdt)
>  #ifndef CONFIG_FDT_FIXUPS_PRESERVE_PMU_NODE
>  	fdt_pmu_fixup(fdt);
>  #endif
> +
> +	fdt_config_fixup(fdt);
>  }
> diff --git a/platform/generic/platform.c b/platform/generic/platform.c
> index bfd7d31..edd4050 100644
> --- a/platform/generic/platform.c
> +++ b/platform/generic/platform.c
> @@ -73,6 +73,66 @@ extern struct sbi_platform platform;
>  static bool platform_has_mlevel_imsic = false;
>  static u32 generic_hart_index2id[SBI_HARTMASK_MAX_BITS] = { 0 };
>  
> +DECLARE_BITMAP(generic_coldboot_harts, SBI_HARTMASK_MAX_BITS);
> +
> +/*
> + * The fw_platform_coldboot_init() function is called by fw_platform_init() 
> + * function to initialize the cold boot harts allowed by the generic platform
> + * according to the DT property "cold-boot-harts" in "/chosen/opensbi-config" 
> + * DT node. If there is no "cold-boot-harts" in DT, all harts will be allowed.
> + */
> +static void fw_platform_coldboot_init(void *fdt)
> +{
> +	int chosen_offset, config_offset, cpu_offset, len, err;
> +	u32 val32;
> +	const u32 *val;
> +
> +	bitmap_zero(generic_coldboot_harts, SBI_HARTMASK_MAX_BITS);
> +
> +	chosen_offset = fdt_path_offset(fdt, "/chosen");
> +	if (chosen_offset < 0) {
> +		goto default_config;
> +	}
the same as above
> +
> +	config_offset = fdt_node_offset_by_compatible(fdt, chosen_offset, "opensbi,config");
> +	if (config_offset < 0) {
> +		goto default_config;
> +	}
the same as above
> +
> +	val = fdt_getprop(fdt, config_offset, "cold-boot-harts", &len);
> +	len = len / sizeof(u32);
> +	if (val && len) {
> +		for (int i = 0; i < len; i++) {
> +			cpu_offset = fdt_node_offset_by_phandle(fdt,
> +							fdt32_to_cpu(val[i]));
> +			if (cpu_offset < 0) {
> +				goto default_config;
> +			}
the same as above
> +
> +			err = fdt_parse_hart_id(fdt, cpu_offset, &val32);
> +			if (err) {
> +				goto default_config;
> +			}
the same as above
> +
> +			if (!fdt_node_is_enabled(fdt, cpu_offset))
> +				continue;
> +
> +			for (int i = 0; i < platform.hart_count; i++) {
> +				if (val32 == generic_hart_index2id[i]) {
> +					bitmap_set(generic_coldboot_harts, i, 1);
> +				}
the same as above
> +			}
> +
> +		}
> +	}
> +
> +	return;
> +
> +default_config:
> +	bitmap_fill(generic_coldboot_harts, SBI_HARTMASK_MAX_BITS);
> +	return;
> +}
> +
>  /*
>   * The fw_platform_init() function is called very early on the boot HART
>   * OpenSBI reference firmwares so that platform specific code get chance
> @@ -133,6 +193,8 @@ unsigned long fw_platform_init(unsigned long arg0, unsigned long arg1,
>  	platform.heap_size = fw_platform_calculate_heap_size(hart_count);
>  	platform_has_mlevel_imsic = fdt_check_imsic_mlevel(fdt);
>  
> +	fw_platform_coldboot_init(fdt);
> +
>  	/* Return original FDT pointer */
>  	return arg1;
>  
> @@ -146,7 +208,14 @@ static bool generic_cold_boot_allowed(u32 hartid)
>  	if (generic_plat && generic_plat->cold_boot_allowed)
>  		return generic_plat->cold_boot_allowed(
>  						hartid, generic_plat_match);
> -	return true;
> +
> +	for (int i = 0; i < platform.hart_count; i++) {
> +		if (hartid == generic_hart_index2id[i]) {
> +			return bitmap_test(generic_coldboot_harts, i);
> +		}
the same as above

otherwise, look good to me.

Reviewed-by: Xiang W <wxjstz at 126.com>
> +	}
> +
> +	return false;
>  }
>  
>  static int generic_nascent_init(void)
> -- 
> 2.34.1
> 
> 




More information about the opensbi mailing list