Xiang Wang has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/36944 )
Change subject: arch/riscv: Fix cpu capabilities detection function ......................................................................
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);