[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20241227135832.188256-1-arikalo@gmail.com>
Date: Fri, 27 Dec 2024 14:58:32 +0100
From: Aleksandar Rikalo <arikalo@...il.com>
To: linux-riscv@...ts.infradead.org
Cc: Paul Walmsley <paul.walmsley@...ive.com>,
Palmer Dabbelt <palmer@...belt.com>,
Albert Ou <aou@...s.berkeley.edu>,
Andrew Jones <ajones@...tanamicro.com>,
Christoph Müllner <christoph.muellner@...ll.eu>,
Aleksandar Rikalo <arikalo@...il.com>,
linux-kernel@...r.kernel.org,
Djordje Todorovic <djordje.todorovic@...cgroup.com>
Subject: [PATCH v2] riscv: Fix the PAUSE Opcode for MIPS P8700.
From: Djordje Todorovic <djordje.todorovic@...cgroup.com>
The riscv MIPS P8700 uses a different opcode for PAUSE.
It is a ‘hint’ encoding of the SLLI instruction, with rd=0, rs1=0 and
imm=5. It will behave as a NOP instruction if no additional behavior
beyond that of SLLI is implemented.
Add ERRATA_MIPS and ERRATA_MIPS_P8700_PAUSE_OPCODE configs.
Handle errata for MIPS CPUs.
Signed-off-by: Djordje Todorovic <djordje.todorovic@...cgroup.com>
Signed-off-by: Aleksandar Rikalo <arikalo@...il.com>
Signed-off-by: Raj Vishwanathan4 <rvishwanathan@...s.com>
---
arch/riscv/Kconfig.errata | 22 +++++++++++++++++
arch/riscv/errata/Makefile | 1 +
arch/riscv/errata/mips/Makefile | 5 ++++
arch/riscv/errata/mips/errata.c | 33 ++++++++++++++++++++++++++
arch/riscv/include/asm/alternative.h | 3 +++
arch/riscv/include/asm/vendorid_list.h | 1 +
arch/riscv/kernel/alternative.c | 5 ++++
7 files changed, 70 insertions(+)
create mode 100644 arch/riscv/errata/mips/Makefile
create mode 100644 arch/riscv/errata/mips/errata.c
diff --git a/arch/riscv/Kconfig.errata b/arch/riscv/Kconfig.errata
index 2acc7d876e1f..99c75fece8b9 100644
--- a/arch/riscv/Kconfig.errata
+++ b/arch/riscv/Kconfig.errata
@@ -21,6 +21,28 @@ config ERRATA_ANDES_CMO
If you don't know what to do here, say "Y".
+config ERRATA_MIPS
+ bool "MIPS errata"
+ depends on RISCV_ALTERNATIVE
+ help
+ All MIPS errata Kconfig depend on this Kconfig. Disabling
+ this Kconfig will disable all MIPS errata. Please say "Y"
+ here if your platform uses MIPS CPU cores.
+
+ Otherwise, please say "N" here to avoid unnecessary overhead.
+
+config ERRATA_MIPS_P8700_PAUSE_OPCODE
+ bool "Fix the PAUSE Opcode for MIPS P8700"
+ depends on ERRATA_MIPS && 64BIT
+ help
+ The RISCV MIPS P8700 uses a different opcode for PAUSE.
+ It is a 'hint' encoding of the SLLI instruction,
+ with rd=0, rs1=0 and imm=5. It will behave as a NOP
+ instruction if no additional behavior beyond that of
+ SLLI is implemented.
+
+ If you are not using the P8700 processor, say N.
+
config ERRATA_SIFIVE
bool "SiFive errata"
depends on RISCV_ALTERNATIVE
diff --git a/arch/riscv/errata/Makefile b/arch/riscv/errata/Makefile
index f0da9d7b39c3..156cafb338c1 100644
--- a/arch/riscv/errata/Makefile
+++ b/arch/riscv/errata/Makefile
@@ -9,5 +9,6 @@ endif
endif
obj-$(CONFIG_ERRATA_ANDES) += andes/
+obj-$(CONFIG_ERRATA_MIPS) += mips/
obj-$(CONFIG_ERRATA_SIFIVE) += sifive/
obj-$(CONFIG_ERRATA_THEAD) += thead/
diff --git a/arch/riscv/errata/mips/Makefile b/arch/riscv/errata/mips/Makefile
new file mode 100644
index 000000000000..6278c389b801
--- /dev/null
+++ b/arch/riscv/errata/mips/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/mips/errata.c b/arch/riscv/errata/mips/errata.c
new file mode 100644
index 000000000000..7affc590ded5
--- /dev/null
+++ b/arch/riscv/errata/mips/errata.c
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2024 MIPS.
+ */
+
+#include <linux/memory.h>
+#include <linux/module.h>
+
+#include <asm/alternative.h>
+#include <asm/cacheflush.h>
+#include <asm/errata_list.h>
+#include <asm/text-patching.h>
+#include <asm/processor.h>
+#include <asm/sbi.h>
+#include <asm/vendorid_list.h>
+#include <asm/vendor_extensions.h>
+
+void __init_or_module mips_errata_patch_func(struct alt_entry *begin,
+ struct alt_entry *end,
+ unsigned long archid,
+ unsigned long impid,
+ unsigned int stage)
+{
+ if (!IS_ENABLED(CONFIG_ERRATA_MIPS))
+ return;
+
+ if (!IS_ENABLED(CONFIG_ERRATA_MIPS_P8700_PAUSE_OPCODE))
+ return;
+
+ asm volatile(ALTERNATIVE(".4byte 0x1000000f", ".4byte 0x00501013",
+ MIPS_VENDOR_ID, 0, /* patch_id */
+ CONFIG_ERRATA_MIPS_P8700_PAUSE_OPCODE));
+}
diff --git a/arch/riscv/include/asm/alternative.h b/arch/riscv/include/asm/alternative.h
index 3c2b59b25017..bc3ada8190a9 100644
--- a/arch/riscv/include/asm/alternative.h
+++ b/arch/riscv/include/asm/alternative.h
@@ -48,6 +48,9 @@ struct alt_entry {
void andes_errata_patch_func(struct alt_entry *begin, struct alt_entry *end,
unsigned long archid, unsigned long impid,
unsigned int stage);
+void mips_errata_patch_func(struct alt_entry *begin, struct alt_entry *end,
+ unsigned long archid, unsigned long impid,
+ unsigned int stage);
void sifive_errata_patch_func(struct alt_entry *begin, struct alt_entry *end,
unsigned long archid, unsigned long impid,
unsigned int stage);
diff --git a/arch/riscv/include/asm/vendorid_list.h b/arch/riscv/include/asm/vendorid_list.h
index 2f2bb0c84f9a..55d979a7a7c2 100644
--- a/arch/riscv/include/asm/vendorid_list.h
+++ b/arch/riscv/include/asm/vendorid_list.h
@@ -8,5 +8,6 @@
#define ANDES_VENDOR_ID 0x31e
#define SIFIVE_VENDOR_ID 0x489
#define THEAD_VENDOR_ID 0x5b7
+#define MIPS_VENDOR_ID 0x127
#endif
diff --git a/arch/riscv/kernel/alternative.c b/arch/riscv/kernel/alternative.c
index 7eb3cb1215c6..7642704c7f18 100644
--- a/arch/riscv/kernel/alternative.c
+++ b/arch/riscv/kernel/alternative.c
@@ -47,6 +47,11 @@ static void riscv_fill_cpu_mfr_info(struct cpu_manufacturer_info_t *cpu_mfr_info
cpu_mfr_info->patch_func = andes_errata_patch_func;
break;
#endif
+#ifdef CONFIG_ERRATA_MIPS
+ case MIPS_VENDOR_ID:
+ cpu_mfr_info->patch_func = mips_errata_patch_func;
+ break;
+#endif
#ifdef CONFIG_ERRATA_SIFIVE
case SIFIVE_VENDOR_ID:
cpu_mfr_info->patch_func = sifive_errata_patch_func;
--
2.25.1
Powered by blists - more mailing lists