Xiang Wang has uploaded this change for review.
arch/riscv: Fix cpu capabilities detection function
On some platforms, misa may not be implemented. On such a platform,
reading misa will get zero. At this time, soc is required to
implement a non-standard method to detect the soc function.
This modification add interfaces for non-standard function.
The MXL field of misa is always at the highest two bits, whether it
is a 32-bit 64-bit or a 128-bit machine. Therefore, this modification
fixes the use of a fixed offset to detect the machine length.
Change-Id: Id24f77bf21ef0c7c300faa477d67294d093eeecc
Signed-off-by: Xiang Wang <merle@hardenedlinux.org>
---
M src/arch/riscv/Makefile.inc
A src/arch/riscv/cpu.c
M src/arch/riscv/include/arch/cpu.h
3 files changed, 87 insertions(+), 3 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/44/36944/1
diff --git a/src/arch/riscv/Makefile.inc b/src/arch/riscv/Makefile.inc
index 0038523..0679be73 100644
--- a/src/arch/riscv/Makefile.inc
+++ b/src/arch/riscv/Makefile.inc
@@ -60,6 +60,7 @@
bootblock-y += trap_util.S
bootblock-y += trap_handler.c
bootblock-y += fp_asm.S
+bootblock-y += cpu.c
bootblock-y += misaligned.c
bootblock-y += sbi.c
bootblock-y += mcall.c
@@ -100,6 +101,7 @@
romstage-y += boot.c
romstage-y += romstage.c
romstage-y += misc.c
+romstage-y += cpu.c
romstage-$(ARCH_RISCV_PMP) += pmp.c
romstage-y += smp.c
romstage-y += \
@@ -137,6 +139,7 @@
ramstage-y += trap_util.S
ramstage-y += trap_handler.c
ramstage-y += fp_asm.S
+ramstage-y += cpu.c
ramstage-y += misaligned.c
ramstage-y += sbi.c
ramstage-y += virtual_memory.c
diff --git a/src/arch/riscv/cpu.c b/src/arch/riscv/cpu.c
new file mode 100644
index 0000000..69556f3
--- /dev/null
+++ b/src/arch/riscv/cpu.c
@@ -0,0 +1,27 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2012 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <arch/cpu.h>
+
+
+__weak int soc_supports_extension(char ext)
+{
+ return 0;
+}
+
+__weak int soc_machine_xlen(void)
+{
+ return -1;
+}
diff --git a/src/arch/riscv/include/arch/cpu.h b/src/arch/riscv/include/arch/cpu.h
index c62199e..72a8a69 100644
--- a/src/arch/riscv/include/arch/cpu.h
+++ b/src/arch/riscv/include/arch/cpu.h
@@ -18,6 +18,7 @@
#include <arch/encoding.h>
#include <device/device.h>
+#include <commonlib/compiler.h>
#define asmlinkage
@@ -42,15 +43,68 @@
uint8_t riscv_model;
};
+/* If the SOC does not implement misa, the read misa will be zero.
+ * Such SOC requires a non-standard mechanism to detect ISA extensions.
+ * If the soc does not implement misa, implement this function.
+ * */
+int soc_supports_extension(char ext);
+
static inline int supports_extension(char ext)
{
- return read_csr(misa) & (1 << (ext - 'A'));
+ uintptr_t isa = read_csr(misa);
+ if (isa)
+ return isa & (1 << (ext - 'A'));
+ else
+ return soc_supports_extension(ext);
}
+/* If the SOC does not implement misa, the read misa will be zero.
+ * Such SOC requires a non-standard mechanism to detect machine XLEN.
+ * If the soc does not implement misa, implement this function.
+ * */
+int soc_machine_xlen(void);
+
static inline int machine_xlen(void)
{
- int mxl = (read_csr(misa) >> (__riscv_xlen - 2)) & 3;
- return (1 << mxl) * 16;
+ int r;
+ asm (
+ "csrr t0, misa\n\t"
+ "bnez t0, 1f\n\t"
+ "call soc_machine_xlen\n\t"
+ "j 2f\n"
+ "1:\n\t"
+ "srli t1, t0, 30\n\t"
+ "srli t1, t1, 32\n\t"
+ "srli t1, t1, 32\n\t"
+ "srli t1, t1, 32\n\t"
+ "andi t1, t1, 3\n\t"
+ "li t2, 3\n\t"
+ "bne t1, t2, 1f\n\t"
+ "li %0, 128\n\t"
+ "j 2f\n"
+ "1:\n\t"
+ "srli t1, t0, 30\n\t"
+ "srli t1, t1, 32\n\t"
+ "andi t1, t1, 3\n\t"
+ "li t2, 2\n\t"
+ "bne t1, t2, 1f\n\t"
+ "li %0, 64\n\t"
+ "j 2f\n"
+ "1:\n\t"
+ "srli t1, t0, 30\n\t"
+ "andi t1, t1, 3\n\t"
+ "li t2, 1\n\t"
+ "bne t1, t2, 1f\n\t"
+ "li %0, 32\n\t"
+ "j 2f\n"
+ "1:\n\t"
+ "li %0, -1\n"
+ "2:"
+ : "=r"(r)
+ :
+ : "t0", "t1", "t2", "ra"
+ );
+ return r;
}
struct cpu_info *cpu_info(void);
To view, visit change 36944. To unsubscribe, or for help writing mail filters, visit settings.