[PATCH v2 4/6] riscv: errata: Add init framework for picoheart errata
"Yicong Yang" <[email protected]> Tue, 28 Jul 2026 17:46:25 +0800
| Newsgroups | org.infradead.lists.linux-riscv |
|---|---|
| Message-ID | <[email protected]> |
Add init framework for handling upcoming picoheart erratas. Signed-off-by: Yicong Yang <[email protected]> --- arch/riscv/Kconfig.errata | 10 ++++ arch/riscv/errata/Makefile | 1 + arch/riscv/errata/picoheart/Makefile | 5 ++ arch/riscv/errata/picoheart/errata.c | 57 ++++++++++++++++++++ arch/riscv/include/asm/alternative.h | 3 ++ arch/riscv/include/asm/errata_list_vendors.h | 4 ++ arch/riscv/include/asm/vendorid_list.h | 1 + arch/riscv/kernel/alternative.c | 5 ++ 8 files changed, 86 insertions(+) create mode 100644 arch/riscv/errata/picoheart/Makefile create mode 100644 arch/riscv/errata/picoheart/errata.c diff --git a/arch/riscv/Kconfig.errata b/arch/riscv/Kconfig.errata index 3c945d086c7d..374d7fcf7936 100644 --- a/arch/riscv/Kconfig.errata +++ b/arch/riscv/Kconfig.errata @@ -154,4 +154,14 @@ config ERRATA_THEAD_GHOSTWRITE If you don't know what to do here, say "Y". +config ERRATA_PICOHEART + bool "Picoheart errata" + depends on RISCV_ALTERNATIVE + help + All Picoheart errata Kconfig depend on this Kconfig. Disabling + this Kconfig will disable all Picoheart errata. Please say "Y" + here if your platform uses Picoheart CPU cores. + + Otherwise, please say "N" here to avoid unnecessary overhead. + endmenu # "CPU errata selection" diff --git a/arch/riscv/errata/Makefile b/arch/riscv/errata/Makefile index 02a7a3335b1d..a36c5ce1ce7b 100644 --- a/arch/riscv/errata/Makefile +++ b/arch/riscv/errata/Makefile @@ -16,3 +16,4 @@ obj-$(CONFIG_ERRATA_ANDES) += andes/ obj-$(CONFIG_ERRATA_MIPS) += mips/ obj-$(CONFIG_ERRATA_SIFIVE) += sifive/ obj-$(CONFIG_ERRATA_THEAD) += thead/ +obj-$(CONFIG_ERRATA_PICOHEART) += picoheart/ diff --git a/arch/riscv/errata/picoheart/Makefile b/arch/riscv/errata/picoheart/Makefile new file mode 100644 index 000000000000..6278c389b801 --- /dev/null +++ b/arch/riscv/errata/picoheart/Makefile @@ -0,0 +1,5 @@ +ifdef CONFIG_RISCV_ALTERNATIVE_EARLY +CFLAGS_errata.o := -mcmodel=medany +endif + +obj-y += errata.o diff --git a/arch/riscv/errata/picoheart/errata.c b/arch/riscv/errata/picoheart/errata.c new file mode 100644 index 000000000000..53b690878f78 --- /dev/null +++ b/arch/riscv/errata/picoheart/errata.c @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2026 Picoheart (SG) Pte. Ltd. + * + * Author: Yicong Yang <[email protected]> + */ + +#include <linux/cacheflush.h> +#include <linux/cleanup.h> +#include <linux/kernel.h> +#include <linux/memory.h> +#include <linux/string.h> +#include <asm/alternative.h> +#include <asm/errata_list.h> +#include <asm/text-patching.h> +#include <asm/vendor_extensions.h> +#include <asm/vendorid_list.h> + +static u32 picoheart_errata_probe(unsigned int stage, unsigned long archid, + unsigned long impid) +{ + return 0; +} + +void picoheart_errata_patch_func(struct alt_entry *begin, struct alt_entry *end, + unsigned long archid, unsigned long impid, + unsigned int stage) +{ + u32 cpu_req_errata = picoheart_errata_probe(stage, archid, impid); + struct alt_entry *alt; + void *oldptr, *altptr; + u32 tmp; + + BUILD_BUG_ON(ERRATA_PICOHEART_NUMBER >= RISCV_VENDOR_EXT_ALTERNATIVES_BASE); + + for (alt = begin; alt < end; alt++) { + if (alt->vendor_id != PICOHEART_VENDOR_ID || + alt->patch_id >= ERRATA_PICOHEART_NUMBER) + continue; + + tmp = (1U << alt->patch_id); + if (cpu_req_errata & tmp) { + oldptr = ALT_OLD_PTR(alt); + altptr = ALT_ALT_PTR(alt); + + if (stage == RISCV_ALTERNATIVES_EARLY_BOOT) { + memcpy(oldptr, altptr, alt->alt_len); + } else { + guard(mutex)(&text_mutex); + patch_text_nosync(oldptr, altptr, alt->alt_len); + } + } + } + + if (stage == RISCV_ALTERNATIVES_EARLY_BOOT) + local_flush_icache_all(); +} diff --git a/arch/riscv/include/asm/alternative.h b/arch/riscv/include/asm/alternative.h index 8407d1d535b8..57298f21bb70 100644 --- a/arch/riscv/include/asm/alternative.h +++ b/arch/riscv/include/asm/alternative.h @@ -57,6 +57,9 @@ void sifive_errata_patch_func(struct alt_entry *begin, struct alt_entry *end, void thead_errata_patch_func(struct alt_entry *begin, struct alt_entry *end, unsigned long archid, unsigned long impid, unsigned int stage); +void picoheart_errata_patch_func(struct alt_entry *begin, struct alt_entry *end, + unsigned long archid, unsigned long impid, + unsigned int stage); void riscv_cpufeature_patch_func(struct alt_entry *begin, struct alt_entry *end, unsigned int stage); diff --git a/arch/riscv/include/asm/errata_list_vendors.h b/arch/riscv/include/asm/errata_list_vendors.h index ec7eba373437..958e4f4624f7 100644 --- a/arch/riscv/include/asm/errata_list_vendors.h +++ b/arch/riscv/include/asm/errata_list_vendors.h @@ -26,4 +26,8 @@ #define ERRATA_MIPS_NUMBER 1 #endif +#ifdef CONFIG_ERRATA_PICOHEART +#define ERRATA_PICOHEART_NUMBER 0 +#endif + #endif /* ASM_ERRATA_LIST_VENDORS_H */ diff --git a/arch/riscv/include/asm/vendorid_list.h b/arch/riscv/include/asm/vendorid_list.h index beaf9236dba7..dba770b8503c 100644 --- a/arch/riscv/include/asm/vendorid_list.h +++ b/arch/riscv/include/asm/vendorid_list.h @@ -10,6 +10,7 @@ #define MIPS_VENDOR_ID 0x127 #define SIFIVE_VENDOR_ID 0x489 #define THEAD_VENDOR_ID 0x5b7 +#define PICOHEART_VENDOR_ID 0x77d #define QEMU_VIRT_VENDOR_ID 0x000 #define QEMU_VIRT_IMPL_ID 0x000 diff --git a/arch/riscv/kernel/alternative.c b/arch/riscv/kernel/alternative.c index 104dc0862c5c..88639918ee7d 100644 --- a/arch/riscv/kernel/alternative.c +++ b/arch/riscv/kernel/alternative.c @@ -61,6 +61,11 @@ static void riscv_fill_cpu_mfr_info(struct cpu_manufacturer_info_t *cpu_mfr_info case THEAD_VENDOR_ID: cpu_mfr_info->patch_func = thead_errata_patch_func; break; +#endif +#ifdef CONFIG_ERRATA_PICOHEART + case PICOHEART_VENDOR_ID: + cpu_mfr_info->patch_func = picoheart_errata_patch_func; + break; #endif default: cpu_mfr_info->patch_func = NULL; -- 2.50.1 (Apple Git-155) _______________________________________________ linux-riscv mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-riscv