[U-Boot] [PATCH 08/12] riscv: Add a helper routine to print CPU information

Auer, Lukas lukas.auer at aisec.fraunhofer.de
Mon Sep 3 21:42:17 UTC 2018


On Thu, 2018-08-30 at 00: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 at gmail.com>
> ---
> 
>  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 at 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 at 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
> 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 */

The RISC-V arch already has functions for accessing CSRs in encoding.h.
I don't think it makes sense to keep both versions. I would tend
towards keeping this version since this allows us to just sync with the
Linux kernel if there are any changes.

Thanks,
Lukas




More information about the U-Boot mailing list