riscv: Add a helper routine to print CPU information
authorBin Meng <bmeng.cn@gmail.com>
Wed, 26 Sep 2018 13:55:14 +0000 (06:55 -0700)
committerAndes <uboot@andestech.com>
Wed, 3 Oct 2018 09:47:55 +0000 (17:47 +0800)
This adds a helper routine to print CPU information. Currently
it prints all the instruction set extensions that the processor
core supports.

Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
arch/riscv/Makefile
arch/riscv/cpu/Makefile [new file with mode: 0644]
arch/riscv/cpu/cpu.c [new file with mode: 0644]
arch/riscv/include/asm/csr.h [new file with mode: 0644]

index 084888ad8bf05141af49cb12e9d7d92db6917184..af432e16ff5df582613883e13873da7f4876dfe0 100644 (file)
@@ -5,5 +5,6 @@
 
 head-y := arch/riscv/cpu/$(CPU)/start.o
 
+libs-y += arch/riscv/cpu/
 libs-y += arch/riscv/cpu/$(CPU)/
 libs-y += arch/riscv/lib/
diff --git a/arch/riscv/cpu/Makefile b/arch/riscv/cpu/Makefile
new file mode 100644 (file)
index 0000000..63de163
--- /dev/null
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
+
+obj-y += cpu.o
diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c
new file mode 100644 (file)
index 0000000..ae57fb8
--- /dev/null
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
+ */
+
+#include <common.h>
+#include <asm/csr.h>
+
+enum {
+       ISA_INVALID = 0,
+       ISA_32BIT,
+       ISA_64BIT,
+       ISA_128BIT
+};
+
+static const char * const isa_bits[] = {
+       [ISA_INVALID] = NULL,
+       [ISA_32BIT]   = "32",
+       [ISA_64BIT]   = "64",
+       [ISA_128BIT]  = "128"
+};
+
+static inline bool supports_extension(char ext)
+{
+       return csr_read(misa) & (1 << (ext - 'a'));
+}
+
+int print_cpuinfo(void)
+{
+       char name[32];
+       char *s = name;
+       int bit;
+
+       s += sprintf(name, "rv");
+       bit = csr_read(misa) >> (sizeof(long) * 8 - 2);
+       s += sprintf(s, isa_bits[bit]);
+
+       supports_extension('i') ? *s++ = 'i' : 'r';
+       supports_extension('m') ? *s++ = 'm' : 'i';
+       supports_extension('a') ? *s++ = 'a' : 's';
+       supports_extension('f') ? *s++ = 'f' : 'c';
+       supports_extension('d') ? *s++ = 'd' : '-';
+       supports_extension('c') ? *s++ = 'c' : 'v';
+       *s++ = '\0';
+
+       printf("CPU:   %s\n", name);
+
+       return 0;
+}
diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
new file mode 100644 (file)
index 0000000..50fccea
--- /dev/null
@@ -0,0 +1,124 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2015 Regents of the University of California
+ *
+ * Taken from Linux arch/riscv/include/asm/csr.h
+ */
+
+#ifndef _ASM_RISCV_CSR_H
+#define _ASM_RISCV_CSR_H
+
+/* Status register flags */
+#define SR_SIE         _AC(0x00000002, UL) /* Supervisor Interrupt Enable */
+#define SR_SPIE                _AC(0x00000020, UL) /* Previous Supervisor IE */
+#define SR_SPP         _AC(0x00000100, UL) /* Previously Supervisor */
+#define SR_SUM         _AC(0x00040000, UL) /* Supervisor access User Memory */
+
+#define SR_FS          _AC(0x00006000, UL) /* Floating-point Status */
+#define SR_FS_OFF      _AC(0x00000000, UL)
+#define SR_FS_INITIAL  _AC(0x00002000, UL)
+#define SR_FS_CLEAN    _AC(0x00004000, UL)
+#define SR_FS_DIRTY    _AC(0x00006000, UL)
+
+#define SR_XS          _AC(0x00018000, UL) /* Extension Status */
+#define SR_XS_OFF      _AC(0x00000000, UL)
+#define SR_XS_INITIAL  _AC(0x00008000, UL)
+#define SR_XS_CLEAN    _AC(0x00010000, UL)
+#define SR_XS_DIRTY    _AC(0x00018000, UL)
+
+#ifndef CONFIG_64BIT
+#define SR_SD          _AC(0x80000000, UL) /* FS/XS dirty */
+#else
+#define SR_SD          _AC(0x8000000000000000, UL) /* FS/XS dirty */
+#endif
+
+/* SATP flags */
+#if __riscv_xlen == 32
+#define SATP_PPN       _AC(0x003FFFFF, UL)
+#define SATP_MODE_32   _AC(0x80000000, UL)
+#define SATP_MODE      SATP_MODE_32
+#else
+#define SATP_PPN       _AC(0x00000FFFFFFFFFFF, UL)
+#define SATP_MODE_39   _AC(0x8000000000000000, UL)
+#define SATP_MODE      SATP_MODE_39
+#endif
+
+/* Interrupt Enable and Interrupt Pending flags */
+#define SIE_SSIE       _AC(0x00000002, UL) /* Software Interrupt Enable */
+#define SIE_STIE       _AC(0x00000020, UL) /* Timer Interrupt Enable */
+
+#define EXC_INST_MISALIGNED    0
+#define EXC_INST_ACCESS                1
+#define EXC_BREAKPOINT         3
+#define EXC_LOAD_ACCESS                5
+#define EXC_STORE_ACCESS       7
+#define EXC_SYSCALL            8
+#define EXC_INST_PAGE_FAULT    12
+#define EXC_LOAD_PAGE_FAULT    13
+#define EXC_STORE_PAGE_FAULT   15
+
+#ifndef __ASSEMBLY__
+
+#define csr_swap(csr, val)                                     \
+({                                                             \
+       unsigned long __v = (unsigned long)(val);               \
+       __asm__ __volatile__ ("csrrw %0, " #csr ", %1"          \
+                             : "=r" (__v) : "rK" (__v)         \
+                             : "memory");                      \
+       __v;                                                    \
+})
+
+#define csr_read(csr)                                          \
+({                                                             \
+       register unsigned long __v;                             \
+       __asm__ __volatile__ ("csrr %0, " #csr                  \
+                             : "=r" (__v) :                    \
+                             : "memory");                      \
+       __v;                                                    \
+})
+
+#define csr_write(csr, val)                                    \
+({                                                             \
+       unsigned long __v = (unsigned long)(val);               \
+       __asm__ __volatile__ ("csrw " #csr ", %0"               \
+                             : : "rK" (__v)                    \
+                             : "memory");                      \
+})
+
+#define csr_read_set(csr, val)                                 \
+({                                                             \
+       unsigned long __v = (unsigned long)(val);               \
+       __asm__ __volatile__ ("csrrs %0, " #csr ", %1"          \
+                             : "=r" (__v) : "rK" (__v)         \
+                             : "memory");                      \
+       __v;                                                    \
+})
+
+#define csr_set(csr, val)                                      \
+({                                                             \
+       unsigned long __v = (unsigned long)(val);               \
+       __asm__ __volatile__ ("csrs " #csr ", %0"               \
+                             : : "rK" (__v)                    \
+                             : "memory");                      \
+})
+
+#define csr_read_clear(csr, val)                               \
+({                                                             \
+       unsigned long __v = (unsigned long)(val);               \
+       __asm__ __volatile__ ("csrrc %0, " #csr ", %1"          \
+                             : "=r" (__v) : "rK" (__v)         \
+                             : "memory");                      \
+       __v;                                                    \
+})
+
+#define csr_clear(csr, val)                                    \
+({                                                             \
+       unsigned long __v = (unsigned long)(val);               \
+       __asm__ __volatile__ ("csrc " #csr ", %0"               \
+                             : : "rK" (__v)                    \
+                             : "memory");                      \
+})
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_RISCV_CSR_H */