From: Heiko Stuebner Date: Wed, 11 May 2022 19:29:11 +0000 (+0200) Subject: riscv: allow different stages with alternatives X-Git-Tag: v6.1-rc5~1204^2~10^2~10 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d14ca1f8d3039970e812fec1f01e7b46b62cc5fc;p=platform%2Fkernel%2Flinux-starfive.git riscv: allow different stages with alternatives Future features may need to be applied at a different time during boot, so allow defining stages for alternatives and handling them differently depending on the stage. Also make the alternatives-location more flexible so that future stages may provide their own location. Signed-off-by: Heiko Stuebner Reviewed-by: Philipp Tomsich Link: https://lore.kernel.org/r/20220511192921.2223629-3-heiko@sntech.de Signed-off-by: Palmer Dabbelt --- diff --git a/arch/riscv/errata/sifive/errata.c b/arch/riscv/errata/sifive/errata.c index f5e5ae7..4fe03ac 100644 --- a/arch/riscv/errata/sifive/errata.c +++ b/arch/riscv/errata/sifive/errata.c @@ -80,7 +80,8 @@ static void __init warn_miss_errata(u32 miss_errata) } void __init sifive_errata_patch_func(struct alt_entry *begin, struct alt_entry *end, - unsigned long archid, unsigned long impid) + unsigned long archid, unsigned long impid, + unsigned int stage) { struct alt_entry *alt; u32 cpu_req_errata = sifive_errata_probe(archid, impid); diff --git a/arch/riscv/include/asm/alternative.h b/arch/riscv/include/asm/alternative.h index 7b42bce..0ff5506 100644 --- a/arch/riscv/include/asm/alternative.h +++ b/arch/riscv/include/asm/alternative.h @@ -19,6 +19,8 @@ #include #include +#define RISCV_ALTERNATIVES_BOOT 0 /* alternatives applied during regular boot */ + void __init apply_boot_alternatives(void); struct alt_entry { @@ -35,7 +37,8 @@ struct errata_checkfunc_id { }; void sifive_errata_patch_func(struct alt_entry *begin, struct alt_entry *end, - unsigned long archid, unsigned long impid); + unsigned long archid, unsigned long impid, + unsigned int stage); #else /* CONFIG_RISCV_ALTERNATIVE */ diff --git a/arch/riscv/kernel/alternative.c b/arch/riscv/kernel/alternative.c index e8b4a0f..02db62f 100644 --- a/arch/riscv/kernel/alternative.c +++ b/arch/riscv/kernel/alternative.c @@ -22,8 +22,8 @@ static struct cpu_manufacturer_info_t { } cpu_mfr_info; static void (*vendor_patch_func)(struct alt_entry *begin, struct alt_entry *end, - unsigned long archid, - unsigned long impid) __initdata; + unsigned long archid, unsigned long impid, + unsigned int stage) __initdata; static inline void __init riscv_fill_cpu_mfr_info(void) { @@ -58,6 +58,18 @@ static void __init init_alternative(void) * a feature detect on the boot CPU). No need to worry about other CPUs * here. */ +static void __init _apply_alternatives(struct alt_entry *begin, + struct alt_entry *end, + unsigned int stage) +{ + if (!vendor_patch_func) + return; + + vendor_patch_func(begin, end, + cpu_mfr_info.arch_id, cpu_mfr_info.imp_id, + stage); +} + void __init apply_boot_alternatives(void) { /* If called on non-boot cpu things could go wrong */ @@ -65,11 +77,7 @@ void __init apply_boot_alternatives(void) init_alternative(); - if (!vendor_patch_func) - return; - - vendor_patch_func((struct alt_entry *)__alt_start, - (struct alt_entry *)__alt_end, - cpu_mfr_info.arch_id, cpu_mfr_info.imp_id); + _apply_alternatives((struct alt_entry *)__alt_start, + (struct alt_entry *)__alt_end, + RISCV_ALTERNATIVES_BOOT); } -