mirror of
https://github.com/torvalds/linux.git
synced 2026-11-10 17:11:02 +01:00
riscv: Add support for early boot errata application on MIPS chips
MIPS errata implementation previously skipped early boot application entirely. Although the only currently existing MIPS erratum does not require this, amending this now should make any future addition easier to implement. This commit was based on the existing T-Head implementation. Suggested-by: Jesse Taube <jtaubepe@redhat.com> Link: https://lore.kernel.org/linux-riscv/CADRr4bcbD57hmR0XGgo8BjgNp4shEADOondZEtwscCJ9-nxXRQ@mail.gmail.com/ Signed-off-by: Aleksa Paunovic <aleksa.paunovic@htecgroup.com> Link: https://patch.msgid.link/20260810-p8700-early-boot-v1-1-5c4aa08d500f@htecgroup.com Signed-off-by: Paul Walmsley <pjw@kernel.org>
This commit is contained in:
parent
282f4a8aa9
commit
30755e71ab
|
|
@ -24,6 +24,7 @@ config ERRATA_ANDES_CMO
|
|||
config ERRATA_MIPS
|
||||
bool "MIPS errata"
|
||||
depends on RISCV_ALTERNATIVE
|
||||
select RISCV_ALTERNATIVE_EARLY
|
||||
help
|
||||
All MIPS errata Kconfig depend on this Kconfig. Disabling
|
||||
this Kconfig will disable all MIPS errata. Please say "Y"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,11 @@
|
|||
ifdef CONFIG_RISCV_ALTERNATIVE_EARLY
|
||||
CFLAGS_errata.o := -mcmodel=medany
|
||||
ifdef CONFIG_FTRACE
|
||||
CFLAGS_REMOVE_errata.o = $(CC_FLAGS_FTRACE)
|
||||
endif
|
||||
ifdef CONFIG_KASAN
|
||||
KASAN_SANITIZE_errata.o := n
|
||||
endif
|
||||
endif
|
||||
|
||||
obj-y += errata.o
|
||||
|
|
|
|||
|
|
@ -7,12 +7,13 @@
|
|||
#include <linux/module.h>
|
||||
#include <asm/text-patching.h>
|
||||
#include <asm/alternative.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/errata_list.h>
|
||||
#include <asm/vendorid_list.h>
|
||||
#include <asm/vendor_extensions.h>
|
||||
#include <asm/vendor_extensions/mips.h>
|
||||
|
||||
static inline bool errata_probe_pause(void)
|
||||
static inline bool errata_probe_pause(unsigned int stage)
|
||||
{
|
||||
if (!IS_ENABLED(CONFIG_ERRATA_MIPS_P8700_PAUSE_OPCODE))
|
||||
return false;
|
||||
|
|
@ -20,14 +21,17 @@ static inline bool errata_probe_pause(void)
|
|||
if (!riscv_isa_vendor_extension_available(MIPS_VENDOR_ID, XMIPSEXECTL))
|
||||
return false;
|
||||
|
||||
if (stage == RISCV_ALTERNATIVES_EARLY_BOOT)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static u32 mips_errata_probe(void)
|
||||
static u32 mips_errata_probe(unsigned int stage)
|
||||
{
|
||||
u32 cpu_req_errata = 0;
|
||||
|
||||
if (errata_probe_pause())
|
||||
if (errata_probe_pause(stage))
|
||||
cpu_req_errata |= BIT(ERRATA_MIPS_P8700_PAUSE_OPCODE);
|
||||
|
||||
return cpu_req_errata;
|
||||
|
|
@ -38,30 +42,34 @@ void mips_errata_patch_func(struct alt_entry *begin, struct alt_entry *end,
|
|||
unsigned int stage)
|
||||
{
|
||||
struct alt_entry *alt;
|
||||
u32 cpu_req_errata = mips_errata_probe();
|
||||
u32 cpu_req_errata = mips_errata_probe(stage);
|
||||
u32 tmp;
|
||||
void *oldptr, *altptr;
|
||||
|
||||
BUILD_BUG_ON(ERRATA_MIPS_NUMBER >= RISCV_VENDOR_EXT_ALTERNATIVES_BASE);
|
||||
|
||||
if (stage == RISCV_ALTERNATIVES_EARLY_BOOT)
|
||||
return;
|
||||
|
||||
for (alt = begin; alt < end; alt++) {
|
||||
if (alt->vendor_id != MIPS_VENDOR_ID)
|
||||
continue;
|
||||
|
||||
if (alt->patch_id >= ERRATA_MIPS_NUMBER) {
|
||||
WARN(1, "MIPS errata id:%d not in kernel errata list\n",
|
||||
alt->patch_id);
|
||||
if (alt->patch_id >= ERRATA_MIPS_NUMBER)
|
||||
continue;
|
||||
}
|
||||
|
||||
tmp = (1U << alt->patch_id);
|
||||
if (cpu_req_errata & tmp) {
|
||||
mutex_lock(&text_mutex);
|
||||
patch_text_nosync(ALT_OLD_PTR(alt), ALT_ALT_PTR(alt),
|
||||
alt->alt_len);
|
||||
mutex_unlock(&text_mutex);
|
||||
oldptr = ALT_OLD_PTR(alt);
|
||||
altptr = ALT_ALT_PTR(alt);
|
||||
|
||||
if (stage == RISCV_ALTERNATIVES_EARLY_BOOT) {
|
||||
memcpy(oldptr, altptr, alt->alt_len);
|
||||
} else {
|
||||
mutex_lock(&text_mutex);
|
||||
patch_text_nosync(oldptr, altptr, alt->alt_len);
|
||||
mutex_unlock(&text_mutex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (stage == RISCV_ALTERNATIVES_EARLY_BOOT)
|
||||
local_flush_icache_all();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user