
Hi Bin,
On Mon, 2018-09-10 at 21:54 -0700, Bin Meng wrote:
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
Changes in v2: None
arch/riscv/Makefile | 1 + arch/riscv/cpu/Makefile | 5 ++ arch/riscv/cpu/cpu.c | 49 +++++++++++++++++ arch/riscv/include/asm/csr.h | 124 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 179 insertions(+) create mode 100644 arch/riscv/cpu/Makefile create mode 100644 arch/riscv/cpu/cpu.c create mode 100644 arch/riscv/include/asm/csr.h
diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile index 084888a..af432e1 100644 --- a/arch/riscv/Makefile +++ b/arch/riscv/Makefile @@ -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 index 0000000..63de163 --- /dev/null +++ b/arch/riscv/cpu/Makefile @@ -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 index 0000000..ae57fb8 --- /dev/null +++ b/arch/riscv/cpu/cpu.c @@ -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';
Why are you not using the ISA string "riscv,isa" from the device tree? This way, the code is not limited to machine mode and we do not have update it if the set of extensions to check for changes.
Thanks, Lukas
- 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 index 0000000..50fccea --- /dev/null +++ b/arch/riscv/include/asm/csr.h @@ -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 */