[U-Boot] [PATCH 05/19] riscv: Add a SYSCON driver for Core Local Interruptor

Philipp Tomsich philipp.tomsich at theobroma-systems.com
Thu Dec 6 14:33:42 UTC 2018



> On 13.11.2018, at 09:21, Bin Meng <bmeng.cn at gmail.com> wrote:
> 
> This adds U-Boot syscon driver for RISC-V Core Local Interruptor
> (CLINT). The CLINT block holds memory-mapped control and status
> registers associated with software and timer interrupts.
> 
> 3 APIs are provided for U-Boot to implement Supervisor Binary
> Interface (SBI) as defined by the RISC-V privileged architecture
> spec v1.10.
> 
> Signed-off-by: Bin Meng <bmeng.cn at gmail.com>
> ---
> 
> arch/riscv/Kconfig             |  8 +++++
> arch/riscv/include/asm/clint.h | 24 +++++++++++++++
> arch/riscv/lib/Makefile        |  1 +
> arch/riscv/lib/clint.c         | 69 ++++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 102 insertions(+)
> create mode 100644 arch/riscv/include/asm/clint.h
> create mode 100644 arch/riscv/lib/clint.c
> 
> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> index a37e895..abfc083 100644
> --- a/arch/riscv/Kconfig
> +++ b/arch/riscv/Kconfig
> @@ -73,4 +73,12 @@ config 32BIT
> config 64BIT
> 	bool
> 
> +config RISCV_CLINT
> +	bool "Support Core Local Interruptor (CLINT)"
> +	select REGMAP
> +	select SYSCON
> +	help
> +	  The CLINT block holds memory-mapped control and status registers
> +	  associated with software and timer interrupts.
> +
> endmenu
> diff --git a/arch/riscv/include/asm/clint.h b/arch/riscv/include/asm/clint.h
> new file mode 100644
> index 0000000..1c6024f
> --- /dev/null
> +++ b/arch/riscv/include/asm/clint.h
> @@ -0,0 +1,24 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (C) 2018, Bin Meng <bmeng.cn at gmail.com>
> + */
> +
> +#ifndef _ASM_RISCV_CLINT_H
> +#define _ASM_RISCV_CLINT_H
> +
> +/*
> + * System controllers in a RISC-V system
> + *
> + * So far only Core Local Interruptor (CLINT) is defined. If new system
> + * controller is added, we may need move the defines to somewhere else.
> + */
> +enum {
> +	RISCV_NONE,
> +	RISCV_SYSCON_CLINT,	/* Core Local Interruptor (CLINT) */
> +};
> +
> +void riscv_send_ipi(int hart);
> +void riscv_set_timecmp(int hart, u64 cmp);
> +u64 riscv_get_time(void);
> +
> +#endif /* _ASM_RISCV_CLINT_H */
> diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
> index b58db89..b5a77c2 100644
> --- a/arch/riscv/lib/Makefile
> +++ b/arch/riscv/lib/Makefile
> @@ -9,6 +9,7 @@
> obj-$(CONFIG_CMD_BOOTM) += bootm.o
> obj-$(CONFIG_CMD_GO) += boot.o
> obj-y	+= cache.o
> +obj-$(CONFIG_RISCV_CLINT) += clint.o
> obj-y	+= interrupts.o
> obj-y	+= reset.o
> obj-y   += setjmp.o
> diff --git a/arch/riscv/lib/clint.c b/arch/riscv/lib/clint.c
> new file mode 100644
> index 0000000..369aa1d
> --- /dev/null
> +++ b/arch/riscv/lib/clint.c
> @@ -0,0 +1,69 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2018, Bin Meng <bmeng.cn at gmail.com>
> + *
> + * U-Boot syscon driver for RISC-V Core Local Interruptor (CLINT)
> + * The CLINT block holds memory-mapped control and status registers
> + * associated with software and timer interrupts.
> + */
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <regmap.h>
> +#include <syscon.h>
> +#include <asm/clint.h>
> +#include <asm/io.h>
> +
> +/* MSIP registers */
> +#define MSIP_REG(base, hart)		((ulong)(base) + (hart) * 4)
> +/* Timer compare register */
> +#define MTIMECMP_REG(base, hart)	((ulong)(base) + 0x4000 + (hart) * 8)
> +/* Timer register */
> +#define MTIME_REG(base)			((ulong)(base) + 0xbff8)
> +
> +static void __iomem *clint_base;
> +
> +/*
> + * The following 3 APIs are used to implement Supervisor Binary Interface (SBI)
> + * as defined by the RISC-V privileged architecture spec v1.10.
> + *
> + * For performance reasons we don't want to get the CLINT register base via
> + * syscon_get_first_range() each time we enter in those functions, instead
> + * the base address was saved to a global variable during the clint driver
> + * probe phase, so that we can use it directly.
> + */
> +
> +void riscv_send_ipi(int hart)
> +{
> +	writel(1, (void __iomem *)MSIP_REG(clint_base, hart));
> +}
> +
> +void riscv_set_timecmp(int hart, u64 cmp)
> +{
> +	writeq(cmp, (void __iomem *)MTIMECMP_REG(clint_base, hart));
> +}
> +
> +u64 riscv_get_time(void)
> +{
> +	return readq((void __iomem *)MTIME_REG(clint_base));
> +}
> +
> +static int clint_probe(struct udevice *dev)
> +{
> +	clint_base = syscon_get_first_range(RISCV_SYSCON_CLINT);
> +
> +	return 0;
> +}
> +
> +static const struct udevice_id clint_ids[] = {
> +	{ .compatible = "riscv,clint0", .data = RISCV_SYSCON_CLINT },
> +	{ }
> +};
> +
> +U_BOOT_DRIVER(riscv_clint) = {
> +	.name		= "riscv_clint",
> +	.id		= UCLASS_SYSCON,

Wouldn’t a separate UCLASS be more appropriate?

> +	.of_match	= clint_ids,
> +	.probe		= clint_probe,
> +	.flags		= DM_FLAG_PRE_RELOC,
> +};
> -- 
> 2.7.4
> 
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> https://lists.denx.de/listinfo/u-boot



More information about the U-Boot mailing list