summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAhmad Fatoum <a.fatoum@pengutronix.de>2021-04-27 22:23:04 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2021-05-10 09:18:40 +0200
commit6fd5711a111e8c7c4e6ea09d962b6885da09f86b (patch)
tree22b7cc54477502d5199b7caac5ddac8d3b6aa669
parent60b6da3b17214d0efb27d5b42e804aa641bf5ceb (diff)
downloadbarebox-6fd5711a111e8c7c4e6ea09d962b6885da09f86b.tar.gz
barebox-6fd5711a111e8c7c4e6ea09d962b6885da09f86b.tar.xz
RISC-V: add SBI based cpuinfo
SBI appeared to be especially useful to implement a generic console driver. However, SBI v0.2 removes these services without substitute. We might find other use for it later, but for now, add the bare minimum of querying the version of the running SBI implementation. The cpuinfo command is intentionally kept generic. It can later be extended to support CONFIG_RISCV_M_MODE as well. Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de> Link: https://lore.barebox.org/20210427202309.32077-7-a.fatoum@pengutronix.de Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
-rw-r--r--arch/riscv/include/asm/sbi.h32
-rw-r--r--arch/riscv/lib/Makefile2
-rw-r--r--arch/riscv/lib/cpuinfo.c45
-rw-r--r--arch/riscv/lib/sbi.c62
-rw-r--r--commands/Kconfig7
5 files changed, 142 insertions, 6 deletions
diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
index 99895d9c3b..ab1fc9a128 100644
--- a/arch/riscv/include/asm/sbi.h
+++ b/arch/riscv/include/asm/sbi.h
@@ -89,11 +89,32 @@ struct sbiret {
long value;
};
-void sbi_init(void);
-struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0,
- unsigned long arg1, unsigned long arg2,
- unsigned long arg3, unsigned long arg4,
- unsigned long arg5);
+static inline struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0,
+ unsigned long arg1, unsigned long arg2,
+ unsigned long arg3, unsigned long arg4,
+ unsigned long arg5)
+{
+ struct sbiret ret;
+
+ register uintptr_t a0 asm ("a0") = (uintptr_t)(arg0);
+ register uintptr_t a1 asm ("a1") = (uintptr_t)(arg1);
+ register uintptr_t a2 asm ("a2") = (uintptr_t)(arg2);
+ register uintptr_t a3 asm ("a3") = (uintptr_t)(arg3);
+ register uintptr_t a4 asm ("a4") = (uintptr_t)(arg4);
+ register uintptr_t a5 asm ("a5") = (uintptr_t)(arg5);
+ register uintptr_t a6 asm ("a6") = (uintptr_t)(fid);
+ register uintptr_t a7 asm ("a7") = (uintptr_t)(ext);
+ asm volatile ("ecall"
+ : "+r" (a0), "+r" (a1)
+ : "r" (a2), "r" (a3), "r" (a4), "r" (a5), "r" (a6), "r" (a7)
+ : "memory");
+ ret.error = a0;
+ ret.value = a1;
+
+ return ret;
+}
+
+long __sbi_base_ecall(int fid);
void sbi_console_putchar(int ch);
int sbi_console_getchar(void);
@@ -148,6 +169,5 @@ static inline unsigned long sbi_minor_version(void)
int sbi_err_map_linux_errno(int err);
#else /* CONFIG_RISCV_SBI */
static inline int sbi_remote_fence_i(const unsigned long *hart_mask) { return -1; }
-static inline void sbi_init(void) {}
#endif /* CONFIG_RISCV_SBI */
#endif /* _ASM_RISCV_SBI_H */
diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
index a4eaa1005d..49750d576a 100644
--- a/arch/riscv/lib/Makefile
+++ b/arch/riscv/lib/Makefile
@@ -6,3 +6,5 @@ obj-y += dtb.o
obj-pbl-y += sections.o setupc.o reloc.o sections.o runtime-offset.o
obj-$(CONFIG_HAS_ARCH_SJLJ) += setjmp.o longjmp.o
obj-$(CONFIG_RISCV_OPTIMZED_STRING_FUNCTIONS) += memcpy.o memset.o memmove.o
+obj-$(CONFIG_RISCV_SBI) += sbi.o
+obj-$(CONFIG_CMD_RISCV_CPUINFO) += cpuinfo.o
diff --git a/arch/riscv/lib/cpuinfo.c b/arch/riscv/lib/cpuinfo.c
new file mode 100644
index 0000000000..21b99a990a
--- /dev/null
+++ b/arch/riscv/lib/cpuinfo.c
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <common.h>
+#include <command.h>
+#include <asm/sbi.h>
+
+static const char *implementations[] = {
+ [0] = "\"Berkeley Boot Loader (BBL)\" ",
+ [1] = "\"OpenSBI\" ",
+ [2] = "\"Xvisor\" ",
+ [3] = "\"KVM\" ",
+ [4] = "\"RustSBI\" ",
+ [5] = "\"Diosix\" ",
+};
+
+static int do_cpuinfo(int argc, char *argv[])
+{
+ const char *implementation = "";
+ unsigned long impid;
+
+ printf("SBI specification v%lu.%lu detected\n",
+ sbi_major_version(), sbi_minor_version());
+
+ if (sbi_spec_is_0_1())
+ return 0;
+
+ impid = __sbi_base_ecall(SBI_EXT_BASE_GET_IMP_ID);
+ if (impid < ARRAY_SIZE(implementations))
+ implementation = implementations[impid];
+
+ printf("SBI implementation ID=0x%lx %sVersion=0x%lx\n",
+ impid, implementation, __sbi_base_ecall(SBI_EXT_BASE_GET_IMP_VERSION));
+
+ printf("SBI Machine VENDORID=0x%lx ARCHID=0x%lx MIMPID=0x%lx\n",
+ __sbi_base_ecall(SBI_EXT_BASE_GET_MVENDORID),
+ __sbi_base_ecall(SBI_EXT_BASE_GET_MARCHID),
+ __sbi_base_ecall(SBI_EXT_BASE_GET_MIMPID));
+
+ return 0;
+}
+
+BAREBOX_CMD_START(cpuinfo)
+ .cmd = do_cpuinfo,
+BAREBOX_CMD_DESC("show CPU information")
+BAREBOX_CMD_GROUP(CMD_GRP_INFO)
+ BAREBOX_CMD_END
diff --git a/arch/riscv/lib/sbi.c b/arch/riscv/lib/sbi.c
new file mode 100644
index 0000000000..973c9d9d0f
--- /dev/null
+++ b/arch/riscv/lib/sbi.c
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * SBI initialilization and all extension implementation.
+ *
+ * Copyright (c) 2020 Western Digital Corporation or its affiliates.
+ */
+
+#include <asm/sbi.h>
+#include <linux/export.h>
+#include <errno.h>
+#include <init.h>
+
+/* default SBI version is 0.1 */
+unsigned long sbi_spec_version = SBI_SPEC_VERSION_DEFAULT;
+EXPORT_SYMBOL(sbi_spec_version);
+
+int sbi_err_map_linux_errno(int err)
+{
+ switch (err) {
+ case SBI_SUCCESS:
+ return 0;
+ case SBI_ERR_DENIED:
+ return -EPERM;
+ case SBI_ERR_INVALID_PARAM:
+ return -EINVAL;
+ case SBI_ERR_INVALID_ADDRESS:
+ return -EFAULT;
+ case SBI_ERR_NOT_SUPPORTED:
+ case SBI_ERR_FAILURE:
+ default:
+ return -ENOTSUPP;
+ };
+}
+EXPORT_SYMBOL(sbi_err_map_linux_errno);
+
+long __sbi_base_ecall(int fid)
+{
+ struct sbiret ret;
+
+ ret = sbi_ecall(SBI_EXT_BASE, fid, 0, 0, 0, 0, 0, 0);
+ if (!ret.error)
+ return ret.value;
+ else
+ return sbi_err_map_linux_errno(ret.error);
+}
+
+static inline long sbi_get_spec_version(void)
+{
+ return __sbi_base_ecall(SBI_EXT_BASE_GET_SPEC_VERSION);
+}
+
+static int sbi_init(void)
+{
+ int ret;
+
+ ret = sbi_get_spec_version();
+ if (ret > 0)
+ sbi_spec_version = ret;
+ return 0;
+
+}
+core_initcall(sbi_init);
diff --git a/commands/Kconfig b/commands/Kconfig
index b3937fdd8d..5ae3cb3dd1 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -44,6 +44,13 @@ config CMD_ARM_CPUINFO
D-cache: 8192 bytes (linelen = 8)
Control register: M C W P D L I V RR DT IT U XP
+config CMD_RISCV_CPUINFO
+ bool "cpuinfo command"
+ default y
+ depends on RISCV_SBI
+ help
+ Show SBI info about RISC-V CPU
+
config CMD_DEVINFO
tristate
default y