[U-Boot] [PATCH v2 00/20] riscv: Adding RISC-V CPU and timer driver

This adds DM drivers to support RISC-V CPU and timer, plus some bug fixes.
This series is available at u-boot-x86/riscv-working for testing.
Changes in v2: - Use 'Hz' instead of 'HZ' - add DM_FLAG_PRE_RELOC flag to the simple-bus driver - pass NULL as the timer device to device_bind_with_driver_data() - remove the probe to syscon driver in the timer probe, to make the driver generic, and rely on platform codes to provide the API riscv_get_time(). - incorporated and reworked Anup's S-mode timer patch @ http://patchwork.ozlabs.org/patch/1006663/ - rename the driver name to sifive_clint - save the clint base address to arch specific global data to support pre-relocation stage - remove the probe routine - add riscv_clear_ipi() API - incorporated and reworked Anup's S-mode timer patch @ http://patchwork.ozlabs.org/patch/1006663/ - add CMD_CPU as well - move to arch/riscv/cpu/cpu.c - new patch to add indirect stringification to csr_xxx ops - use csr_set() to set MSTATUS_FS - only enabling the cycle, time, and instret counters - change to use satp - rebase on u-boot/master - drop the patch "riscv: Pass correct exception code to _exit_trap()" - drop the patch "riscv: Refactor handle_trap() a little for future extension" - drop the patch "riscv: Allow U-Boot to run on hart 0 only", and leave the SMP support to Lukas's future patch series
Anup Patel (2): riscv: Introduce a Kconfig option for machine mode riscv: Implement riscv_get_time() API using rdtime instruction
Bin Meng (17): dm: cpu: Add timebase frequency to the platdata riscv: qemu: Create a simple-bus driver for the soc node cpu: Add a RISC-V CPU driver timer: Add generic driver for RISC-V privileged architecture defined timer riscv: ax25: Hide the ax25-specific Kconfig option riscv: Add a SYSCON driver for SiFive's Core Local Interruptor riscv: qemu: Add platform-specific Kconfig options riscv: Enlarge the default SYS_MALLOC_F_LEN riscv: Probe cpus during boot riscv: Add CSR numbers riscv: Add exception codes for xcause register riscv: Add indirect stringification to csr_xxx ops riscv: Do some basic architecture level cpu initialization riscv: Move trap handler codes to mtrap.S riscv: Fix context restore before returning from trap handler riscv: Return to previous privilege level after trap handling riscv: Adjust the _exit_trap() position to come before handle_trap()
Lukas Auer (1): riscv: add Kconfig entries for the code model
arch/riscv/Kconfig | 60 ++++++++- arch/riscv/Makefile | 9 +- arch/riscv/cpu/Makefile | 2 +- arch/riscv/cpu/ax25/Kconfig | 8 +- arch/riscv/cpu/cpu.c | 33 +++++ arch/riscv/cpu/mtrap.S | 103 +++++++++++++++ arch/riscv/cpu/qemu/Kconfig | 12 ++ arch/riscv/cpu/qemu/cpu.c | 14 +++ arch/riscv/cpu/start.S | 89 ------------- arch/riscv/include/asm/csr.h | 16 +-- arch/riscv/include/asm/encoding.h | 234 +++++++++++++++++++++++++++++++++++ arch/riscv/include/asm/global_data.h | 3 + arch/riscv/include/asm/syscon.h | 19 +++ arch/riscv/lib/Makefile | 2 + arch/riscv/lib/interrupts.c | 62 +++++----- arch/riscv/lib/rdtime.c | 36 ++++++ arch/riscv/lib/sifive_clint.c | 68 ++++++++++ board/emulation/qemu-riscv/Kconfig | 1 + drivers/cpu/Kconfig | 6 + drivers/cpu/Makefile | 1 + drivers/cpu/riscv_cpu.c | 116 +++++++++++++++++ drivers/timer/Kconfig | 8 ++ drivers/timer/Makefile | 1 + drivers/timer/riscv_timer.c | 57 +++++++++ include/cpu.h | 3 + 25 files changed, 823 insertions(+), 140 deletions(-) create mode 100644 arch/riscv/cpu/mtrap.S create mode 100644 arch/riscv/cpu/qemu/Kconfig create mode 100644 arch/riscv/include/asm/syscon.h create mode 100644 arch/riscv/lib/rdtime.c create mode 100644 arch/riscv/lib/sifive_clint.c create mode 100644 drivers/cpu/riscv_cpu.c create mode 100644 drivers/timer/riscv_timer.c

From: Lukas Auer lukas.auer@aisec.fraunhofer.de
RISC-V has two code models, medium low (medlow) and medium any (medany). Medlow limits addressable memory to a single 2 GiB range between the absolute addresses -2 GiB and +2 GiB. Medany limits addressable memory to any single 2 GiB address range.
By default, medlow is selected for U-Boot on both 32-bit and 64-bit systems.
The -mcmodel compiler flag is selected according to the Kconfig configuration.
Signed-off-by: Lukas Auer lukas.auer@aisec.fraunhofer.de [bmeng: adjust to make medlow the default code model for U-Boot] Signed-off-by: Bin Meng bmeng.cn@gmail.com
---
Changes in v2: None
arch/riscv/Kconfig | 18 ++++++++++++++++++ arch/riscv/Makefile | 9 ++++++++- 2 files changed, 26 insertions(+), 1 deletion(-)
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 732a357..6d85ac9 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -44,6 +44,24 @@ config ARCH_RV64I
endchoice
+choice + prompt "Code Model" + default CMODEL_MEDLOW + +config CMODEL_MEDLOW + bool "medium low code model" + help + U-Boot and its statically defined symbols must lie within a single 2 GiB + address range and must lie between absolute addresses -2 GiB and +2 GiB. + +config CMODEL_MEDANY + bool "medium any code model" + help + U-Boot and its statically defined symbols must be within any single 2 GiB + address range. + +endchoice + config RISCV_ISA_C bool "Emit compressed instructions" default y diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile index 55d7c65..0b80eb8 100644 --- a/arch/riscv/Makefile +++ b/arch/riscv/Makefile @@ -17,8 +17,15 @@ endif ifeq ($(CONFIG_RISCV_ISA_C),y) ARCH_C = c endif +ifeq ($(CONFIG_CMODEL_MEDLOW),y) + CMODEL = medlow +endif +ifeq ($(CONFIG_CMODEL_MEDANY),y) + CMODEL = medany +endif
-ARCH_FLAGS = -march=$(ARCH_BASE)$(ARCH_A)$(ARCH_C) -mabi=$(ABI) +ARCH_FLAGS = -march=$(ARCH_BASE)$(ARCH_A)$(ARCH_C) -mabi=$(ABI) \ + -mcmodel=$(CMODEL)
PLATFORM_CPPFLAGS += $(ARCH_FLAGS) CFLAGS_EFI += $(ARCH_FLAGS)

This adds a timebase_freq member to the 'struct cpu_platdata', to hold the "timebase-frequency" value in the cpu or /cpus node.
Signed-off-by: Bin Meng bmeng.cn@gmail.com Reviewed-by: Simon Glass sjg@chromium.org Reviewed-by: Lukas Auer lukas.auer@aisec.fraunhofer.de
---
Changes in v2: - Use 'Hz' instead of 'HZ'
include/cpu.h | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/include/cpu.h b/include/cpu.h index 367c5f4..28dd48f 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -14,6 +14,8 @@ * @device_id: Driver-defined device identifier * @family: DMTF CPU Family identifier * @id: DMTF CPU Processor identifier + * @timebase_freq: the current frequency at which the cpu timer timebase + * registers are updated (in Hz) * * This can be accessed with dev_get_parent_platdata() for any UCLASS_CPU * device. @@ -24,6 +26,7 @@ struct cpu_platdata { ulong device_id; u16 family; u32 id[2]; + u32 timebase_freq; };
/* CPU features - mostly just a placeholder for now */

To enumerate devices on the /soc/ node, create a "simple-bus" driver to match "riscv-virtio-soc".
Signed-off-by: Bin Meng bmeng.cn@gmail.com Reviewed-by: Lukas Auer lukas.auer@aisec.fraunhofer.de
---
Changes in v2: - add DM_FLAG_PRE_RELOC flag to the simple-bus driver
arch/riscv/cpu/qemu/cpu.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
diff --git a/arch/riscv/cpu/qemu/cpu.c b/arch/riscv/cpu/qemu/cpu.c index 25d97d0..ad2950c 100644 --- a/arch/riscv/cpu/qemu/cpu.c +++ b/arch/riscv/cpu/qemu/cpu.c @@ -4,6 +4,7 @@ */
#include <common.h> +#include <dm.h>
/* * cleanup_before_linux() is called just before we call linux @@ -19,3 +20,16 @@ int cleanup_before_linux(void)
return 0; } + +/* To enumerate devices on the /soc/ node, create a "simple-bus" driver */ +static const struct udevice_id riscv_virtio_soc_ids[] = { + { .compatible = "riscv-virtio-soc" }, + { } +}; + +U_BOOT_DRIVER(riscv_virtio_soc) = { + .name = "riscv_virtio_soc", + .id = UCLASS_SIMPLE_BUS, + .of_match = riscv_virtio_soc_ids, + .flags = DM_FLAG_PRE_RELOC, +};

This adds a driver for RISC-V CPU. Note the driver will bind a RISC-V timer driver if "timebase-frequency" property is present in the device tree.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
---
Changes in v2: - pass NULL as the timer device to device_bind_with_driver_data()
drivers/cpu/Kconfig | 6 +++ drivers/cpu/Makefile | 1 + drivers/cpu/riscv_cpu.c | 116 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 123 insertions(+) create mode 100644 drivers/cpu/riscv_cpu.c
diff --git a/drivers/cpu/Kconfig b/drivers/cpu/Kconfig index d405200..3d5729f 100644 --- a/drivers/cpu/Kconfig +++ b/drivers/cpu/Kconfig @@ -13,3 +13,9 @@ config CPU_MPC83XX select CLK_MPC83XX help Support CPU cores for SoCs of the MPC83xx series. + +config CPU_RISCV + bool "Enable RISC-V CPU driver" + depends on CPU && RISCV + help + Support CPU cores for RISC-V architecture. diff --git a/drivers/cpu/Makefile b/drivers/cpu/Makefile index 858b037..be0300c 100644 --- a/drivers/cpu/Makefile +++ b/drivers/cpu/Makefile @@ -8,4 +8,5 @@ obj-$(CONFIG_CPU) += cpu-uclass.o
obj-$(CONFIG_ARCH_BMIPS) += bmips_cpu.o obj-$(CONFIG_CPU_MPC83XX) += mpc83xx_cpu.o +obj-$(CONFIG_CPU_RISCV) += riscv_cpu.o obj-$(CONFIG_SANDBOX) += cpu_sandbox.o diff --git a/drivers/cpu/riscv_cpu.c b/drivers/cpu/riscv_cpu.c new file mode 100644 index 0000000..5e15df5 --- /dev/null +++ b/drivers/cpu/riscv_cpu.c @@ -0,0 +1,116 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018, Bin Meng bmeng.cn@gmail.com + */ + +#include <common.h> +#include <cpu.h> +#include <dm.h> +#include <errno.h> +#include <dm/device-internal.h> +#include <dm/lists.h> + +static int riscv_cpu_get_desc(struct udevice *dev, char *buf, int size) +{ + const char *isa; + + isa = dev_read_string(dev, "riscv,isa"); + if (size < (strlen(isa) + 1)) + return -ENOSPC; + + strcpy(buf, isa); + + return 0; +} + +static int riscv_cpu_get_info(struct udevice *dev, struct cpu_info *info) +{ + const char *mmu; + + dev_read_u32(dev, "clock-frequency", (u32 *)&info->cpu_freq); + + mmu = dev_read_string(dev, "mmu-type"); + if (!mmu) + info->features |= BIT(CPU_FEAT_MMU); + + return 0; +} + +static int riscv_cpu_get_count(struct udevice *dev) +{ + ofnode node; + int num = 0; + + ofnode_for_each_subnode(node, dev_ofnode(dev->parent)) { + const char *device_type; + + device_type = ofnode_read_string(node, "device_type"); + if (!device_type) + continue; + if (strcmp(device_type, "cpu") == 0) + num++; + } + + return num; +} + +static int riscv_cpu_bind(struct udevice *dev) +{ + struct cpu_platdata *plat = dev_get_parent_platdata(dev); + struct driver *drv; + int ret; + + /* save the hart id */ + plat->cpu_id = dev_read_addr(dev); + + /* first examine the property in current cpu node */ + ret = dev_read_u32(dev, "timebase-frequency", &plat->timebase_freq); + /* if not found, then look at the parent /cpus node */ + if (ret) + dev_read_u32(dev->parent, "timebase-frequency", + &plat->timebase_freq); + + /* + * Bind riscv-timer driver on hart 0 + * + * We only instantiate one timer device which is enough for U-Boot. + * Pass the "timebase-frequency" value as the driver data for the + * timer device. + * + * Return value is not checked since it's possible that the timer + * driver is not included. + */ + if (!plat->cpu_id && plat->timebase_freq) { + drv = lists_driver_lookup_name("riscv_timer"); + if (!drv) { + debug("Cannot find the timer driver, not included?\n"); + return 0; + } + + device_bind_with_driver_data(dev, drv, "riscv_timer", + plat->timebase_freq, ofnode_null(), + NULL); + } + + return 0; +} + +static const struct cpu_ops riscv_cpu_ops = { + .get_desc = riscv_cpu_get_desc, + .get_info = riscv_cpu_get_info, + .get_count = riscv_cpu_get_count, +}; + +static const struct udevice_id riscv_cpu_ids[] = { + { .compatible = "riscv" }, + { } +}; + +U_BOOT_DRIVER(riscv_cpu) = { + .name = "riscv_cpu", + .id = UCLASS_CPU, + .of_match = riscv_cpu_ids, + .bind = riscv_cpu_bind, + .ops = &riscv_cpu_ops, + .flags = DM_FLAG_PRE_RELOC, +};

On Fri, 2018-12-07 at 06:14 -0800, Bin Meng wrote:
This adds a driver for RISC-V CPU. Note the driver will bind a RISC-V timer driver if "timebase-frequency" property is present in the device tree.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
Changes in v2:
- pass NULL as the timer device to device_bind_with_driver_data()
drivers/cpu/Kconfig | 6 +++ drivers/cpu/Makefile | 1 + drivers/cpu/riscv_cpu.c | 116 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 123 insertions(+) create mode 100644 drivers/cpu/riscv_cpu.c
Reviewed-by: Lukas Auer lukas.auer@aisec.fraunhofer.de

RISC-V privileged architecture v1.10 defines a real-time counter, exposed as a memory-mapped machine-mode register - mtime. mtime must run at constant frequency, and the platform must provide a mechanism for determining the timebase of mtime. The mtime register has a 64-bit precision on all RV32, RV64, and RV128 systems.
Different platform may have different implementation of the mtime block hence an API riscv_get_time() is required by this driver for platform codes to hide such implementation details. For example, on some platforms mtime is provided by the CLINT module, while on some other platforms a simple 'rdtime' can be used to get the timer counter.
With this timer driver the U-Boot timer functionalities like delay works correctly now.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
---
Changes in v2: - remove the probe to syscon driver in the timer probe, to make the driver generic, and rely on platform codes to provide the API riscv_get_time().
drivers/timer/Kconfig | 8 +++++++ drivers/timer/Makefile | 1 + drivers/timer/riscv_timer.c | 57 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+) create mode 100644 drivers/timer/riscv_timer.c
diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig index b0e6f32..8995979 100644 --- a/drivers/timer/Kconfig +++ b/drivers/timer/Kconfig @@ -126,6 +126,14 @@ config OMAP_TIMER help Select this to enable an timer for Omap devices.
+config RISCV_TIMER + bool "RISC-V timer support" + depends on RISCV && TIMER + select RISCV_CLINT + help + Select this to enable support for the timer as defined + by the RISC-V privileged architecture spec v1.10. + config ROCKCHIP_TIMER bool "Rockchip timer support" depends on TIMER diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile index c4fbab2..d0bf218 100644 --- a/drivers/timer/Makefile +++ b/drivers/timer/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_CADENCE_TTC_TIMER) += cadence-ttc.o obj-$(CONFIG_DESIGNWARE_APB_TIMER) += dw-apb-timer.o obj-$(CONFIG_MPC83XX_TIMER) += mpc83xx_timer.o obj-$(CONFIG_OMAP_TIMER) += omap-timer.o +obj-$(CONFIG_RISCV_TIMER) += riscv_timer.o obj-$(CONFIG_ROCKCHIP_TIMER) += rockchip_timer.o obj-$(CONFIG_SANDBOX_TIMER) += sandbox_timer.o obj-$(CONFIG_STI_TIMER) += sti-timer.o diff --git a/drivers/timer/riscv_timer.c b/drivers/timer/riscv_timer.c new file mode 100644 index 0000000..ef3bedc --- /dev/null +++ b/drivers/timer/riscv_timer.c @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018, Bin Meng bmeng.cn@gmail.com + * + * RISC-V privileged architecture defined generic timer driver + * + * This driver relies on RISC-V platform codes to provide the essential API + * riscv_get_time() which is supposed to return the timer counter as defined + * by the RISC-V privileged architecture spec v1.10. + * + * This driver can be used by both M-mode and S-mode. + */ + +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <timer.h> +#include <asm/io.h> + +/** + * riscv_get_time() - get the timer counter + * + * Platform codes should provide this API in order to make this driver function. + * + * @return: 64-bit timer counter as defined by the RISC-V privileged + * architecture spec v1.10. + */ +extern u64 riscv_get_time(void); + +static int riscv_timer_get_count(struct udevice *dev, u64 *count) +{ + *count = riscv_get_time(); + + return 0; +} + +static int riscv_timer_probe(struct udevice *dev) +{ + struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev); + + /* clock frequency was passed from the cpu driver as driver data */ + uc_priv->clock_rate = dev->driver_data; + + return 0; +} + +static const struct timer_ops riscv_timer_ops = { + .get_count = riscv_timer_get_count, +}; + +U_BOOT_DRIVER(riscv_timer) = { + .name = "riscv_timer", + .id = UCLASS_TIMER, + .probe = riscv_timer_probe, + .ops = &riscv_timer_ops, + .flags = DM_FLAG_PRE_RELOC, +};

Hi Bin,
On Fri, 2018-12-07 at 06:14 -0800, Bin Meng wrote:
RISC-V privileged architecture v1.10 defines a real-time counter, exposed as a memory-mapped machine-mode register - mtime. mtime must run at constant frequency, and the platform must provide a mechanism for determining the timebase of mtime. The mtime register has a 64-bit precision on all RV32, RV64, and RV128 systems.
Different platform may have different implementation of the mtime block hence an API riscv_get_time() is required by this driver for platform codes to hide such implementation details. For example, on some platforms mtime is provided by the CLINT module, while on some other platforms a simple 'rdtime' can be used to get the timer counter.
With this timer driver the U-Boot timer functionalities like delay works correctly now.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
Changes in v2:
- remove the probe to syscon driver in the timer probe, to make the driver generic, and rely on platform codes to provide the API riscv_get_time().
drivers/timer/Kconfig | 8 +++++++ drivers/timer/Makefile | 1 + drivers/timer/riscv_timer.c | 57 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+) create mode 100644 drivers/timer/riscv_timer.c
diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig index b0e6f32..8995979 100644 --- a/drivers/timer/Kconfig +++ b/drivers/timer/Kconfig @@ -126,6 +126,14 @@ config OMAP_TIMER help Select this to enable an timer for Omap devices.
+config RISCV_TIMER
- bool "RISC-V timer support"
- depends on RISCV && TIMER
- select RISCV_CLINT
Since we have one generic timer for RISC-V now, I don't think it makes sense to specifically select the CLINT here.
- help
Select this to enable support for the timer as defined
by the RISC-V privileged architecture spec v1.10.
nit: should we explicitly mention the version here? v1.11 will also include the mtime CSR, for example. This is not really important, just noticed it now.
Looks good otherwise.
Reviewed-by: Lukas Auer lukas.auer@aisec.fraunhofer.de
Thanks, Lukas
config ROCKCHIP_TIMER bool "Rockchip timer support" depends on TIMER diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile index c4fbab2..d0bf218 100644 --- a/drivers/timer/Makefile +++ b/drivers/timer/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_CADENCE_TTC_TIMER) += cadence- ttc.o obj-$(CONFIG_DESIGNWARE_APB_TIMER) += dw-apb-timer.o obj-$(CONFIG_MPC83XX_TIMER) += mpc83xx_timer.o obj-$(CONFIG_OMAP_TIMER) += omap-timer.o +obj-$(CONFIG_RISCV_TIMER) += riscv_timer.o obj-$(CONFIG_ROCKCHIP_TIMER) += rockchip_timer.o obj-$(CONFIG_SANDBOX_TIMER) += sandbox_timer.o obj-$(CONFIG_STI_TIMER) += sti-timer.o diff --git a/drivers/timer/riscv_timer.c b/drivers/timer/riscv_timer.c new file mode 100644 index 0000000..ef3bedc --- /dev/null +++ b/drivers/timer/riscv_timer.c @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- Copyright (C) 2018, Bin Meng bmeng.cn@gmail.com
- RISC-V privileged architecture defined generic timer driver
- This driver relies on RISC-V platform codes to provide the
essential API
- riscv_get_time() which is supposed to return the timer counter as
defined
- by the RISC-V privileged architecture spec v1.10.
- This driver can be used by both M-mode and S-mode.
- */
+#include <common.h> +#include <dm.h> +#include <errno.h> +#include <timer.h> +#include <asm/io.h>
+/**
- riscv_get_time() - get the timer counter
- Platform codes should provide this API in order to make this
driver function.
- @return: 64-bit timer counter as defined by the RISC-V
privileged
architecture spec v1.10.
- */
+extern u64 riscv_get_time(void);
+static int riscv_timer_get_count(struct udevice *dev, u64 *count) +{
- *count = riscv_get_time();
- return 0;
+}
+static int riscv_timer_probe(struct udevice *dev) +{
- struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
- /* clock frequency was passed from the cpu driver as driver
data */
- uc_priv->clock_rate = dev->driver_data;
- return 0;
+}
+static const struct timer_ops riscv_timer_ops = {
- .get_count = riscv_timer_get_count,
+};
+U_BOOT_DRIVER(riscv_timer) = {
- .name = "riscv_timer",
- .id = UCLASS_TIMER,
- .probe = riscv_timer_probe,
- .ops = &riscv_timer_ops,
- .flags = DM_FLAG_PRE_RELOC,
+};

Hi Lukas,
On Tue, Dec 11, 2018 at 7:17 AM Auer, Lukas lukas.auer@aisec.fraunhofer.de wrote:
Hi Bin,
On Fri, 2018-12-07 at 06:14 -0800, Bin Meng wrote:
RISC-V privileged architecture v1.10 defines a real-time counter, exposed as a memory-mapped machine-mode register - mtime. mtime must run at constant frequency, and the platform must provide a mechanism for determining the timebase of mtime. The mtime register has a 64-bit precision on all RV32, RV64, and RV128 systems.
Different platform may have different implementation of the mtime block hence an API riscv_get_time() is required by this driver for platform codes to hide such implementation details. For example, on some platforms mtime is provided by the CLINT module, while on some other platforms a simple 'rdtime' can be used to get the timer counter.
With this timer driver the U-Boot timer functionalities like delay works correctly now.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
Changes in v2:
- remove the probe to syscon driver in the timer probe, to make the driver generic, and rely on platform codes to provide the API riscv_get_time().
drivers/timer/Kconfig | 8 +++++++ drivers/timer/Makefile | 1 + drivers/timer/riscv_timer.c | 57 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+) create mode 100644 drivers/timer/riscv_timer.c
diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig index b0e6f32..8995979 100644 --- a/drivers/timer/Kconfig +++ b/drivers/timer/Kconfig @@ -126,6 +126,14 @@ config OMAP_TIMER help Select this to enable an timer for Omap devices.
+config RISCV_TIMER
bool "RISC-V timer support"
depends on RISCV && TIMER
select RISCV_CLINT
Since we have one generic timer for RISC-V now, I don't think it makes sense to specifically select the CLINT here.
Ah, yes!
help
Select this to enable support for the timer as defined
by the RISC-V privileged architecture spec v1.10.
nit: should we explicitly mention the version here? v1.11 will also include the mtime CSR, for example. This is not really important, just noticed it now.
OK, will remove it in v3.
Looks good otherwise.
Reviewed-by: Lukas Auer lukas.auer@aisec.fraunhofer.de
Regards, Bin

There is no need to expose RISCV_NDS to the Kconfig menu as it is an ax25-specific option.
Signed-off-by: Bin Meng bmeng.cn@gmail.com ---
Changes in v2: None
arch/riscv/cpu/ax25/Kconfig | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/arch/riscv/cpu/ax25/Kconfig b/arch/riscv/cpu/ax25/Kconfig index 6c7022f..5ff9e5c 100644 --- a/arch/riscv/cpu/ax25/Kconfig +++ b/arch/riscv/cpu/ax25/Kconfig @@ -1,7 +1,5 @@ config RISCV_NDS - bool "AndeStar V5 ISA support" - default n + bool help - Say Y here if you plan to run U-Boot on AndeStar v5 - platforms and use some specific features which are - provided by Andes Technology AndeStar V5 Families. + Run U-Boot on AndeStar v5 platforms and use some specific features + which are provided by Andes Technology AndeStar V5 Families.

On Fri, 2018-12-07 at 06:14 -0800, Bin Meng wrote:
There is no need to expose RISCV_NDS to the Kconfig menu as it is an ax25-specific option.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
Changes in v2: None
arch/riscv/cpu/ax25/Kconfig | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
Reviewed-by: Lukas Auer lukas.auer@aisec.fraunhofer.de

From: Anup Patel anup@brainfault.org
So far we have a Kconfig option for supervisor mode. This adds an option for the machine mode.
Signed-off-by: Anup Patel anup@brainfault.org Signed-off-by: Bin Meng bmeng.cn@gmail.com
---
Changes in v2: - incorporated and reworked Anup's S-mode timer patch @ http://patchwork.ozlabs.org/patch/1006663/
arch/riscv/Kconfig | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-)
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 6d85ac9..55c60e4 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -62,6 +62,22 @@ config CMODEL_MEDANY
endchoice
+choice + prompt "Run Mode" + default RISCV_MMODE + +config RISCV_MMODE + bool "Machine" + help + Choose this option to build U-Boot for RISC-V M-Mode. + +config RISCV_SMODE + bool "Supervisor" + help + Choose this option to build U-Boot for RISC-V S-Mode. + +endchoice + config RISCV_ISA_C bool "Emit compressed instructions" default y @@ -73,11 +89,6 @@ config RISCV_ISA_C config RISCV_ISA_A def_bool y
-config RISCV_SMODE - bool "Run in S-Mode" - help - Enable this option to build U-Boot for RISC-V S-Mode - config 32BIT bool

On Fri, 2018-12-07 at 06:14 -0800, Bin Meng wrote:
From: Anup Patel anup@brainfault.org
So far we have a Kconfig option for supervisor mode. This adds an option for the machine mode.
Signed-off-by: Anup Patel anup@brainfault.org Signed-off-by: Bin Meng bmeng.cn@gmail.com
Changes in v2:
- incorporated and reworked Anup's S-mode timer patch @ http://patchwork.ozlabs.org/patch/1006663/
arch/riscv/Kconfig | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-)
Reviewed-by: Lukas Auer lukas.auer@aisec.fraunhofer.de

This adds U-Boot syscon driver for SiFive's Core Local Interruptor (CLINT). The CLINT block holds memory-mapped control and status registers associated with software and timer interrupts.
This driver implements the riscv_get_time() API as required by the generic RISC-V timer driver, as well as some other APIs that are needed for handling IPI.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
---
Changes in v2: - rename the driver name to sifive_clint - save the clint base address to arch specific global data to support pre-relocation stage - remove the probe routine - add riscv_clear_ipi() API
arch/riscv/Kconfig | 9 +++++ arch/riscv/include/asm/global_data.h | 3 ++ arch/riscv/include/asm/syscon.h | 19 ++++++++++ arch/riscv/lib/Makefile | 1 + arch/riscv/lib/sifive_clint.c | 68 ++++++++++++++++++++++++++++++++++++ 5 files changed, 100 insertions(+) create mode 100644 arch/riscv/include/asm/syscon.h create mode 100644 arch/riscv/lib/sifive_clint.c
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 55c60e4..f513f52 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -95,4 +95,13 @@ config 32BIT config 64BIT bool
+config SIFIVE_CLINT + bool + depends on RISCV_MMODE + select REGMAP + select SYSCON + help + The SiFive CLINT block holds memory-mapped control and status registers + associated with software and timer interrupts. + endmenu diff --git a/arch/riscv/include/asm/global_data.h b/arch/riscv/include/asm/global_data.h index 4d5d623..46fcfab 100644 --- a/arch/riscv/include/asm/global_data.h +++ b/arch/riscv/include/asm/global_data.h @@ -12,6 +12,9 @@
/* Architecture-specific global data */ struct arch_global_data { +#ifdef CONFIG_SIFIVE_CLINT + void __iomem *clint; /* clint base address */ +#endif };
#include <asm-generic/global_data.h> diff --git a/arch/riscv/include/asm/syscon.h b/arch/riscv/include/asm/syscon.h new file mode 100644 index 0000000..d311ee6 --- /dev/null +++ b/arch/riscv/include/asm/syscon.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2018, Bin Meng bmeng.cn@gmail.com + */ + +#ifndef _ASM_SYSCON_H +#define _ASM_SYSCON_H + +/* + * System controllers in a RISC-V system + * + * So far only SiFive's Core Local Interruptor (CLINT) is defined. + */ +enum { + RISCV_NONE, + RISCV_SYSCON_CLINT, /* Core Local Interruptor (CLINT) */ +}; + +#endif /* _ASM_SYSCON_H */ diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile index b58db89..b13c876 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_SIFIVE_CLINT) += sifive_clint.o obj-y += interrupts.o obj-y += reset.o obj-y += setjmp.o diff --git a/arch/riscv/lib/sifive_clint.c b/arch/riscv/lib/sifive_clint.c new file mode 100644 index 0000000..2d4bfac --- /dev/null +++ b/arch/riscv/lib/sifive_clint.c @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018, Bin Meng bmeng.cn@gmail.com + * + * U-Boot syscon driver for SiFive's 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/io.h> +#include <asm/syscon.h> + +/* MSIP registers */ +#define MSIP_REG(base, hart) ((ulong)(base) + (hart) * 4) +/* mtime compare register */ +#define MTIMECMP_REG(base, hart) ((ulong)(base) + 0x4000 + (hart) * 8) +/* mtime register */ +#define MTIME_REG(base) ((ulong)(base) + 0xbff8) + +DECLARE_GLOBAL_DATA_PTR; + +u64 riscv_get_time(void) +{ + if (!gd->arch.clint) + gd->arch.clint = syscon_get_first_range(RISCV_SYSCON_CLINT); + + return readq((void __iomem *)MTIME_REG(gd->arch.clint)); +} + +void riscv_set_timecmp(int hart, u64 cmp) +{ + if (!gd->arch.clint) + gd->arch.clint = syscon_get_first_range(RISCV_SYSCON_CLINT); + + writeq(cmp, (void __iomem *)MTIMECMP_REG(gd->arch.clint, hart)); +} + +void riscv_send_ipi(int hart) +{ + if (!gd->arch.clint) + gd->arch.clint = syscon_get_first_range(RISCV_SYSCON_CLINT); + + writel(1, (void __iomem *)MSIP_REG(gd->arch.clint, hart)); +} + +void riscv_clear_ipi(int hart) +{ + if (!gd->arch.clint) + gd->arch.clint = syscon_get_first_range(RISCV_SYSCON_CLINT); + + writel(0, (void __iomem *)MSIP_REG(gd->arch.clint, hart)); +} + +static const struct udevice_id sifive_clint_ids[] = { + { .compatible = "riscv,clint0", .data = RISCV_SYSCON_CLINT }, + { } +}; + +U_BOOT_DRIVER(sifive_clint) = { + .name = "sifive_clint", + .id = UCLASS_SYSCON, + .of_match = sifive_clint_ids, + .flags = DM_FLAG_PRE_RELOC, +};

Hi Bin,
On Fri, 2018-12-07 at 06:14 -0800, Bin Meng wrote:
This adds U-Boot syscon driver for SiFive's Core Local Interruptor (CLINT). The CLINT block holds memory-mapped control and status registers associated with software and timer interrupts.
This driver implements the riscv_get_time() API as required by the generic RISC-V timer driver, as well as some other APIs that are needed for handling IPI.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
Changes in v2:
- rename the driver name to sifive_clint
- save the clint base address to arch specific global data to support pre-relocation stage
- remove the probe routine
- add riscv_clear_ipi() API
arch/riscv/Kconfig | 9 +++++ arch/riscv/include/asm/global_data.h | 3 ++ arch/riscv/include/asm/syscon.h | 19 ++++++++++ arch/riscv/lib/Makefile | 1 + arch/riscv/lib/sifive_clint.c | 68 ++++++++++++++++++++++++++++++++++++ 5 files changed, 100 insertions(+) create mode 100644 arch/riscv/include/asm/syscon.h create mode 100644 arch/riscv/lib/sifive_clint.c
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 55c60e4..f513f52 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -95,4 +95,13 @@ config 32BIT config 64BIT bool
+config SIFIVE_CLINT
- bool
- depends on RISCV_MMODE
- select REGMAP
- select SYSCON
- help
The SiFive CLINT block holds memory-mapped control and status
registers
associated with software and timer interrupts.
endmenu diff --git a/arch/riscv/include/asm/global_data.h b/arch/riscv/include/asm/global_data.h index 4d5d623..46fcfab 100644 --- a/arch/riscv/include/asm/global_data.h +++ b/arch/riscv/include/asm/global_data.h @@ -12,6 +12,9 @@
/* Architecture-specific global data */ struct arch_global_data { +#ifdef CONFIG_SIFIVE_CLINT
- void __iomem *clint; /* clint base address */
+#endif };
#include <asm-generic/global_data.h> diff --git a/arch/riscv/include/asm/syscon.h b/arch/riscv/include/asm/syscon.h new file mode 100644 index 0000000..d311ee6 --- /dev/null +++ b/arch/riscv/include/asm/syscon.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/*
- Copyright (C) 2018, Bin Meng bmeng.cn@gmail.com
- */
+#ifndef _ASM_SYSCON_H +#define _ASM_SYSCON_H
+/*
- System controllers in a RISC-V system
- So far only SiFive's Core Local Interruptor (CLINT) is defined.
- */
+enum {
- RISCV_NONE,
- RISCV_SYSCON_CLINT, /* Core Local Interruptor (CLINT) */
+};
+#endif /* _ASM_SYSCON_H */ diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile index b58db89..b13c876 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_SIFIVE_CLINT) += sifive_clint.o obj-y += interrupts.o obj-y += reset.o obj-y += setjmp.o diff --git a/arch/riscv/lib/sifive_clint.c b/arch/riscv/lib/sifive_clint.c new file mode 100644 index 0000000..2d4bfac --- /dev/null +++ b/arch/riscv/lib/sifive_clint.c @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- Copyright (C) 2018, Bin Meng bmeng.cn@gmail.com
- U-Boot syscon driver for SiFive's 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/io.h> +#include <asm/syscon.h>
+/* MSIP registers */ +#define MSIP_REG(base, hart) ((ulong)(base) + (hart) * 4) +/* mtime compare register */ +#define MTIMECMP_REG(base, hart) ((ulong)(base) + 0x4000 + (hart) * 8) +/* mtime register */ +#define MTIME_REG(base) ((ulong)(base) + 0xbff8)
+DECLARE_GLOBAL_DATA_PTR;
+u64 riscv_get_time(void) +{
- if (!gd->arch.clint)
gd->arch.clint =
syscon_get_first_range(RISCV_SYSCON_CLINT);
This should work, but it is probably better to add error handling here to detect if syscon_get_first_range has returned an error. The error could then be propagated in the function return value. Same thing in the functions below.
Thanks, Lukas
- return readq((void __iomem *)MTIME_REG(gd->arch.clint));
+}
+void riscv_set_timecmp(int hart, u64 cmp) +{
- if (!gd->arch.clint)
gd->arch.clint =
syscon_get_first_range(RISCV_SYSCON_CLINT);
- writeq(cmp, (void __iomem *)MTIMECMP_REG(gd->arch.clint,
hart)); +}
+void riscv_send_ipi(int hart) +{
- if (!gd->arch.clint)
gd->arch.clint =
syscon_get_first_range(RISCV_SYSCON_CLINT);
- writel(1, (void __iomem *)MSIP_REG(gd->arch.clint, hart));
+}
+void riscv_clear_ipi(int hart) +{
- if (!gd->arch.clint)
gd->arch.clint =
syscon_get_first_range(RISCV_SYSCON_CLINT);
- writel(0, (void __iomem *)MSIP_REG(gd->arch.clint, hart));
+}
+static const struct udevice_id sifive_clint_ids[] = {
- { .compatible = "riscv,clint0", .data = RISCV_SYSCON_CLINT },
- { }
+};
+U_BOOT_DRIVER(sifive_clint) = {
- .name = "sifive_clint",
- .id = UCLASS_SYSCON,
- .of_match = sifive_clint_ids,
- .flags = DM_FLAG_PRE_RELOC,
+};

From: Anup Patel anup@brainfault.org
This adds an implementation of riscv_get_time() API that is using rdtime instruction.
This is the case for S-mode U-Boot, and is useful for processors that support rdtime in M-mode too.
Signed-off-by: Anup Patel anup@brainfault.org Signed-off-by: Bin Meng bmeng.cn@gmail.com
---
Changes in v2: - incorporated and reworked Anup's S-mode timer patch @ http://patchwork.ozlabs.org/patch/1006663/
arch/riscv/Kconfig | 8 ++++++++ arch/riscv/lib/Makefile | 1 + arch/riscv/lib/rdtime.c | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 arch/riscv/lib/rdtime.c
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index f513f52..7dc6e3f 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -104,4 +104,12 @@ config SIFIVE_CLINT The SiFive CLINT block holds memory-mapped control and status registers associated with software and timer interrupts.
+config RISCV_RDTIME + bool + default y if RISCV_SMODE + help + The provides the riscv_get_time() API that is implemented using the + standard rdtime instruction. This is the case for S-mode U-Boot, and + is useful for processors that support rdtime in M-mode too. + endmenu diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile index b13c876..edfa616 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_RDTIME) += rdtime.o obj-$(CONFIG_SIFIVE_CLINT) += sifive_clint.o obj-y += interrupts.o obj-y += reset.o diff --git a/arch/riscv/lib/rdtime.c b/arch/riscv/lib/rdtime.c new file mode 100644 index 0000000..b16680f --- /dev/null +++ b/arch/riscv/lib/rdtime.c @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018, Anup Patel anup@brainfault.org + * Copyright (C) 2018, Bin Meng bmeng.cn@gmail.com + * + * The riscv_get_time() API implementation that is using the + * standard rdtime instruction. + */ + +#include <common.h> + +/* Implement the API required by RISC-V timer driver */ +u64 riscv_get_time(void) +{ +#ifdef CONFIG_64BIT + u64 n; + + __asm__ __volatile__ ( + "rdtime %0" + : "=r" (n)); + + return n; +#else + u32 lo, hi, tmp; + + __asm__ __volatile__ ( + "1:\n" + "rdtimeh %0\n" + "rdtime %1\n" + "rdtimeh %2\n" + "bne %0, %2, 1b" + : "=&r" (hi), "=&r" (lo), "=&r" (tmp)); + + return ((u64)hi << 32) | lo; +#endif +}

On Fri, 2018-12-07 at 06:14 -0800, Bin Meng wrote:
From: Anup Patel anup@brainfault.org
This adds an implementation of riscv_get_time() API that is using rdtime instruction.
This is the case for S-mode U-Boot, and is useful for processors that support rdtime in M-mode too.
Signed-off-by: Anup Patel anup@brainfault.org Signed-off-by: Bin Meng bmeng.cn@gmail.com
Changes in v2:
- incorporated and reworked Anup's S-mode timer patch @ http://patchwork.ozlabs.org/patch/1006663/
arch/riscv/Kconfig | 8 ++++++++ arch/riscv/lib/Makefile | 1 + arch/riscv/lib/rdtime.c | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 arch/riscv/lib/rdtime.c
Reviewed-by: Lukas Auer lukas.auer@aisec.fraunhofer.de

Add the QEMU RISC-V platform-specific Kconfig options, to include CPU and timer drivers.
Signed-off-by: Bin Meng bmeng.cn@gmail.com Reviewed-by: Lukas Auer lukas.auer@aisec.fraunhofer.de
---
Changes in v2: - add CMD_CPU as well
arch/riscv/Kconfig | 1 + arch/riscv/cpu/qemu/Kconfig | 11 +++++++++++ board/emulation/qemu-riscv/Kconfig | 1 + 3 files changed, 13 insertions(+) create mode 100644 arch/riscv/cpu/qemu/Kconfig
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 7dc6e3f..39ca2d8 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -22,6 +22,7 @@ source "board/emulation/qemu-riscv/Kconfig"
# platform-specific options below source "arch/riscv/cpu/ax25/Kconfig" +source "arch/riscv/cpu/qemu/Kconfig"
# architecture-specific options below
diff --git a/arch/riscv/cpu/qemu/Kconfig b/arch/riscv/cpu/qemu/Kconfig new file mode 100644 index 0000000..2e953e1 --- /dev/null +++ b/arch/riscv/cpu/qemu/Kconfig @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) 2018, Bin Meng bmeng.cn@gmail.com + +config QEMU_RISCV + bool + imply CPU + imply CPU_RISCV + imply RISCV_TIMER + imply SIFIVE_CLINT if RISCV_MMODE + imply CMD_CPU diff --git a/board/emulation/qemu-riscv/Kconfig b/board/emulation/qemu-riscv/Kconfig index 56bb533..ed005e5 100644 --- a/board/emulation/qemu-riscv/Kconfig +++ b/board/emulation/qemu-riscv/Kconfig @@ -18,6 +18,7 @@ config SYS_TEXT_BASE
config BOARD_SPECIFIC_OPTIONS # dummy def_bool y + select QEMU_RISCV imply SYS_NS16550 imply VIRTIO_MMIO imply VIRTIO_NET

Increase the heap size for the pre-relocation stage, so that CPU driver can be loaded.
Signed-off-by: Bin Meng bmeng.cn@gmail.com Reviewed-by: Lukas Auer lukas.auer@aisec.fraunhofer.de ---
Changes in v2: None
arch/riscv/Kconfig | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 39ca2d8..c45e4d7 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -113,4 +113,7 @@ config RISCV_RDTIME standard rdtime instruction. This is the case for S-mode U-Boot, and is useful for processors that support rdtime in M-mode too.
+config SYS_MALLOC_F_LEN + default 0x1000 + endmenu

This calls cpu_probe_all() to probe all available cpus.
Signed-off-by: Bin Meng bmeng.cn@gmail.com Reviewed-by: Lukas Auer lukas.auer@aisec.fraunhofer.de
---
Changes in v2: - move to arch/riscv/cpu/cpu.c
arch/riscv/cpu/cpu.c | 14 ++++++++++++++ arch/riscv/cpu/qemu/Kconfig | 1 + 2 files changed, 15 insertions(+)
diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c index d9f820c..3858e51 100644 --- a/arch/riscv/cpu/cpu.c +++ b/arch/riscv/cpu/cpu.c @@ -4,6 +4,8 @@ */
#include <common.h> +#include <cpu.h> +#include <log.h> #include <asm/csr.h>
/* @@ -53,3 +55,15 @@ int print_cpuinfo(void)
return 0; } + +int arch_early_init_r(void) +{ + int ret; + + /* probe cpus so that RISC-V timer can be bound */ + ret = cpu_probe_all(); + if (ret) + return log_msg_ret("RISC-V cpus probe failed\n", ret); + + return 0; +} diff --git a/arch/riscv/cpu/qemu/Kconfig b/arch/riscv/cpu/qemu/Kconfig index 2e953e1..f48751e 100644 --- a/arch/riscv/cpu/qemu/Kconfig +++ b/arch/riscv/cpu/qemu/Kconfig @@ -4,6 +4,7 @@
config QEMU_RISCV bool + select ARCH_EARLY_INIT_R imply CPU imply CPU_RISCV imply RISCV_TIMER

The standard RISC-V ISA sets aside a 12-bit encoding space for up to 4096 CSRs. This adds all known CSR numbers as defined in the RISC-V Privileged Architecture Version 1.10.
Signed-off-by: Bin Meng bmeng.cn@gmail.com ---
Changes in v2: None
arch/riscv/include/asm/encoding.h | 219 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 219 insertions(+)
diff --git a/arch/riscv/include/asm/encoding.h b/arch/riscv/include/asm/encoding.h index 97cf906..c910d5c 100644 --- a/arch/riscv/include/asm/encoding.h +++ b/arch/riscv/include/asm/encoding.h @@ -152,6 +152,225 @@ #define RISCV_PGSHIFT 12 #define RISCV_PGSIZE BIT(RISCV_PGSHIFT)
+/* CSR numbers */ +#define CSR_FFLAGS 0x1 +#define CSR_FRM 0x2 +#define CSR_FCSR 0x3 + +#define CSR_SSTATUS 0x100 +#define CSR_SIE 0x104 +#define CSR_STVEC 0x105 +#define CSR_SCOUNTEREN 0x106 +#define CSR_SSCRATCH 0x140 +#define CSR_SEPC 0x141 +#define CSR_SCAUSE 0x142 +#define CSR_STVAL 0x143 +#define CSR_SIP 0x144 +#define CSR_SATP 0x180 + +#define CSR_MSTATUS 0x300 +#define CSR_MISA 0x301 +#define CSR_MEDELEG 0x302 +#define CSR_MIDELEG 0x303 +#define CSR_MIE 0x304 +#define CSR_MTVEC 0x305 +#define CSR_MCOUNTEREN 0x306 +#define CSR_MHPMEVENT3 0x323 +#define CSR_MHPMEVENT4 0x324 +#define CSR_MHPMEVENT5 0x325 +#define CSR_MHPMEVENT6 0x326 +#define CSR_MHPMEVENT7 0x327 +#define CSR_MHPMEVENT8 0x328 +#define CSR_MHPMEVENT9 0x329 +#define CSR_MHPMEVENT10 0x32a +#define CSR_MHPMEVENT11 0x32b +#define CSR_MHPMEVENT12 0x32c +#define CSR_MHPMEVENT13 0x32d +#define CSR_MHPMEVENT14 0x32e +#define CSR_MHPMEVENT15 0x32f +#define CSR_MHPMEVENT16 0x330 +#define CSR_MHPMEVENT17 0x331 +#define CSR_MHPMEVENT18 0x332 +#define CSR_MHPMEVENT19 0x333 +#define CSR_MHPMEVENT20 0x334 +#define CSR_MHPMEVENT21 0x335 +#define CSR_MHPMEVENT22 0x336 +#define CSR_MHPMEVENT23 0x337 +#define CSR_MHPMEVENT24 0x338 +#define CSR_MHPMEVENT25 0x339 +#define CSR_MHPMEVENT26 0x33a +#define CSR_MHPMEVENT27 0x33b +#define CSR_MHPMEVENT28 0x33c +#define CSR_MHPMEVENT29 0x33d +#define CSR_MHPMEVENT30 0x33e +#define CSR_MHPMEVENT31 0x33f +#define CSR_MSCRATCH 0x340 +#define CSR_MEPC 0x341 +#define CSR_MCAUSE 0x342 +#define CSR_MTVAL 0x343 +#define CSR_MIP 0x344 +#define CSR_PMPCFG0 0x3a0 +#define CSR_PMPCFG1 0x3a1 +#define CSR_PMPCFG2 0x3a2 +#define CSR_PMPCFG3 0x3a3 +#define CSR_PMPADDR0 0x3b0 +#define CSR_PMPADDR1 0x3b1 +#define CSR_PMPADDR2 0x3b2 +#define CSR_PMPADDR3 0x3b3 +#define CSR_PMPADDR4 0x3b4 +#define CSR_PMPADDR5 0x3b5 +#define CSR_PMPADDR6 0x3b6 +#define CSR_PMPADDR7 0x3b7 +#define CSR_PMPADDR8 0x3b8 +#define CSR_PMPADDR9 0x3b9 +#define CSR_PMPADDR10 0x3ba +#define CSR_PMPADDR11 0x3bb +#define CSR_PMPADDR12 0x3bc +#define CSR_PMPADDR13 0x3bd +#define CSR_PMPADDR14 0x3be +#define CSR_PMPADDR15 0x3bf + +#define CSR_TSELECT 0x7a0 +#define CSR_TDATA1 0x7a1 +#define CSR_TDATA2 0x7a2 +#define CSR_TDATA3 0x7a3 +#define CSR_DCSR 0x7b0 +#define CSR_DPC 0x7b1 +#define CSR_DSCRATCH 0x7b2 + +#define CSR_MCYCLE 0xb00 +#define CSR_MINSTRET 0xb02 +#define CSR_MHPMCOUNTER3 0xb03 +#define CSR_MHPMCOUNTER4 0xb04 +#define CSR_MHPMCOUNTER5 0xb05 +#define CSR_MHPMCOUNTER6 0xb06 +#define CSR_MHPMCOUNTER7 0xb07 +#define CSR_MHPMCOUNTER8 0xb08 +#define CSR_MHPMCOUNTER9 0xb09 +#define CSR_MHPMCOUNTER10 0xb0a +#define CSR_MHPMCOUNTER11 0xb0b +#define CSR_MHPMCOUNTER12 0xb0c +#define CSR_MHPMCOUNTER13 0xb0d +#define CSR_MHPMCOUNTER14 0xb0e +#define CSR_MHPMCOUNTER15 0xb0f +#define CSR_MHPMCOUNTER16 0xb10 +#define CSR_MHPMCOUNTER17 0xb11 +#define CSR_MHPMCOUNTER18 0xb12 +#define CSR_MHPMCOUNTER19 0xb13 +#define CSR_MHPMCOUNTER20 0xb14 +#define CSR_MHPMCOUNTER21 0xb15 +#define CSR_MHPMCOUNTER22 0xb16 +#define CSR_MHPMCOUNTER23 0xb17 +#define CSR_MHPMCOUNTER24 0xb18 +#define CSR_MHPMCOUNTER25 0xb19 +#define CSR_MHPMCOUNTER26 0xb1a +#define CSR_MHPMCOUNTER27 0xb1b +#define CSR_MHPMCOUNTER28 0xb1c +#define CSR_MHPMCOUNTER29 0xb1d +#define CSR_MHPMCOUNTER30 0xb1e +#define CSR_MHPMCOUNTER31 0xb1f +#define CSR_MCYCLEH 0xb80 +#define CSR_MINSTRETH 0xb82 +#define CSR_MHPMCOUNTER3H 0xb83 +#define CSR_MHPMCOUNTER4H 0xb84 +#define CSR_MHPMCOUNTER5H 0xb85 +#define CSR_MHPMCOUNTER6H 0xb86 +#define CSR_MHPMCOUNTER7H 0xb87 +#define CSR_MHPMCOUNTER8H 0xb88 +#define CSR_MHPMCOUNTER9H 0xb89 +#define CSR_MHPMCOUNTER10H 0xb8a +#define CSR_MHPMCOUNTER11H 0xb8b +#define CSR_MHPMCOUNTER12H 0xb8c +#define CSR_MHPMCOUNTER13H 0xb8d +#define CSR_MHPMCOUNTER14H 0xb8e +#define CSR_MHPMCOUNTER15H 0xb8f +#define CSR_MHPMCOUNTER16H 0xb90 +#define CSR_MHPMCOUNTER17H 0xb91 +#define CSR_MHPMCOUNTER18H 0xb92 +#define CSR_MHPMCOUNTER19H 0xb93 +#define CSR_MHPMCOUNTER20H 0xb94 +#define CSR_MHPMCOUNTER21H 0xb95 +#define CSR_MHPMCOUNTER22H 0xb96 +#define CSR_MHPMCOUNTER23H 0xb97 +#define CSR_MHPMCOUNTER24H 0xb98 +#define CSR_MHPMCOUNTER25H 0xb99 +#define CSR_MHPMCOUNTER26H 0xb9a +#define CSR_MHPMCOUNTER27H 0xb9b +#define CSR_MHPMCOUNTER28H 0xb9c +#define CSR_MHPMCOUNTER29H 0xb9d +#define CSR_MHPMCOUNTER30H 0xb9e +#define CSR_MHPMCOUNTER31H 0xb9f + +#define CSR_CYCLE 0xc00 +#define CSR_TIME 0xc01 +#define CSR_INSTRET 0xc02 +#define CSR_HPMCOUNTER3 0xc03 +#define CSR_HPMCOUNTER4 0xc04 +#define CSR_HPMCOUNTER5 0xc05 +#define CSR_HPMCOUNTER6 0xc06 +#define CSR_HPMCOUNTER7 0xc07 +#define CSR_HPMCOUNTER8 0xc08 +#define CSR_HPMCOUNTER9 0xc09 +#define CSR_HPMCOUNTER10 0xc0a +#define CSR_HPMCOUNTER11 0xc0b +#define CSR_HPMCOUNTER12 0xc0c +#define CSR_HPMCOUNTER13 0xc0d +#define CSR_HPMCOUNTER14 0xc0e +#define CSR_HPMCOUNTER15 0xc0f +#define CSR_HPMCOUNTER16 0xc10 +#define CSR_HPMCOUNTER17 0xc11 +#define CSR_HPMCOUNTER18 0xc12 +#define CSR_HPMCOUNTER19 0xc13 +#define CSR_HPMCOUNTER20 0xc14 +#define CSR_HPMCOUNTER21 0xc15 +#define CSR_HPMCOUNTER22 0xc16 +#define CSR_HPMCOUNTER23 0xc17 +#define CSR_HPMCOUNTER24 0xc18 +#define CSR_HPMCOUNTER25 0xc19 +#define CSR_HPMCOUNTER26 0xc1a +#define CSR_HPMCOUNTER27 0xc1b +#define CSR_HPMCOUNTER28 0xc1c +#define CSR_HPMCOUNTER29 0xc1d +#define CSR_HPMCOUNTER30 0xc1e +#define CSR_HPMCOUNTER31 0xc1f +#define CSR_CYCLEH 0xc80 +#define CSR_TIMEH 0xc81 +#define CSR_INSTRETH 0xc82 +#define CSR_HPMCOUNTER3H 0xc83 +#define CSR_HPMCOUNTER4H 0xc84 +#define CSR_HPMCOUNTER5H 0xc85 +#define CSR_HPMCOUNTER6H 0xc86 +#define CSR_HPMCOUNTER7H 0xc87 +#define CSR_HPMCOUNTER8H 0xc88 +#define CSR_HPMCOUNTER9H 0xc89 +#define CSR_HPMCOUNTER10H 0xc8a +#define CSR_HPMCOUNTER11H 0xc8b +#define CSR_HPMCOUNTER12H 0xc8c +#define CSR_HPMCOUNTER13H 0xc8d +#define CSR_HPMCOUNTER14H 0xc8e +#define CSR_HPMCOUNTER15H 0xc8f +#define CSR_HPMCOUNTER16H 0xc90 +#define CSR_HPMCOUNTER17H 0xc91 +#define CSR_HPMCOUNTER18H 0xc92 +#define CSR_HPMCOUNTER19H 0xc93 +#define CSR_HPMCOUNTER20H 0xc94 +#define CSR_HPMCOUNTER21H 0xc95 +#define CSR_HPMCOUNTER22H 0xc96 +#define CSR_HPMCOUNTER23H 0xc97 +#define CSR_HPMCOUNTER24H 0xc98 +#define CSR_HPMCOUNTER25H 0xc99 +#define CSR_HPMCOUNTER26H 0xc9a +#define CSR_HPMCOUNTER27H 0xc9b +#define CSR_HPMCOUNTER28H 0xc9c +#define CSR_HPMCOUNTER29H 0xc9d +#define CSR_HPMCOUNTER30H 0xc9e +#define CSR_HPMCOUNTER31H 0xc9f + +#define CSR_MVENDORID 0xf11 +#define CSR_MARCHID 0xf12 +#define CSR_MIMPID 0xf13 +#define CSR_MHARTID 0xf14 + #endif /* __riscv */
#endif /* RISCV_CSR_ENCODING_H */

Hi Bin,
On Fri, 2018-12-07 at 06:14 -0800, Bin Meng wrote:
The standard RISC-V ISA sets aside a 12-bit encoding space for up to 4096 CSRs. This adds all known CSR numbers as defined in the RISC-V Privileged Architecture Version 1.10.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
Changes in v2: None
arch/riscv/include/asm/encoding.h | 219 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 219 insertions(+)
diff --git a/arch/riscv/include/asm/encoding.h b/arch/riscv/include/asm/encoding.h index 97cf906..c910d5c 100644 --- a/arch/riscv/include/asm/encoding.h +++ b/arch/riscv/include/asm/encoding.h @@ -152,6 +152,225 @@ #define RISCV_PGSHIFT 12 #define RISCV_PGSIZE BIT(RISCV_PGSHIFT)
+/* CSR numbers */ +#define CSR_FFLAGS 0x1 +#define CSR_FRM 0x2 +#define CSR_FCSR 0x3
+#define CSR_SSTATUS 0x100
sedeleg (0x102) and sideleg (0x103) are missing here.
The user-mode CSRs are also missing. Not sure if we should include them since I don't expect that we have to emulate them in machine mode.
Looks good otherwise. Reviewed-by: Lukas Auer lukas.auer@aisec.fraunhofer.de
Thanks, Lukas
+#define CSR_SIE 0x104 +#define CSR_STVEC 0x105 +#define CSR_SCOUNTEREN 0x106 +#define CSR_SSCRATCH 0x140 +#define CSR_SEPC 0x141 +#define CSR_SCAUSE 0x142 +#define CSR_STVAL 0x143 +#define CSR_SIP 0x144 +#define CSR_SATP 0x180
+#define CSR_MSTATUS 0x300 +#define CSR_MISA 0x301 +#define CSR_MEDELEG 0x302 +#define CSR_MIDELEG 0x303 +#define CSR_MIE 0x304 +#define CSR_MTVEC 0x305 +#define CSR_MCOUNTEREN 0x306 +#define CSR_MHPMEVENT3 0x323 +#define CSR_MHPMEVENT4 0x324 +#define CSR_MHPMEVENT5 0x325 +#define CSR_MHPMEVENT6 0x326 +#define CSR_MHPMEVENT7 0x327 +#define CSR_MHPMEVENT8 0x328 +#define CSR_MHPMEVENT9 0x329 +#define CSR_MHPMEVENT10 0x32a +#define CSR_MHPMEVENT11 0x32b +#define CSR_MHPMEVENT12 0x32c +#define CSR_MHPMEVENT13 0x32d +#define CSR_MHPMEVENT14 0x32e +#define CSR_MHPMEVENT15 0x32f +#define CSR_MHPMEVENT16 0x330 +#define CSR_MHPMEVENT17 0x331 +#define CSR_MHPMEVENT18 0x332 +#define CSR_MHPMEVENT19 0x333 +#define CSR_MHPMEVENT20 0x334 +#define CSR_MHPMEVENT21 0x335 +#define CSR_MHPMEVENT22 0x336 +#define CSR_MHPMEVENT23 0x337 +#define CSR_MHPMEVENT24 0x338 +#define CSR_MHPMEVENT25 0x339 +#define CSR_MHPMEVENT26 0x33a +#define CSR_MHPMEVENT27 0x33b +#define CSR_MHPMEVENT28 0x33c +#define CSR_MHPMEVENT29 0x33d +#define CSR_MHPMEVENT30 0x33e +#define CSR_MHPMEVENT31 0x33f +#define CSR_MSCRATCH 0x340 +#define CSR_MEPC 0x341 +#define CSR_MCAUSE 0x342 +#define CSR_MTVAL 0x343 +#define CSR_MIP 0x344 +#define CSR_PMPCFG0 0x3a0 +#define CSR_PMPCFG1 0x3a1 +#define CSR_PMPCFG2 0x3a2 +#define CSR_PMPCFG3 0x3a3 +#define CSR_PMPADDR0 0x3b0 +#define CSR_PMPADDR1 0x3b1 +#define CSR_PMPADDR2 0x3b2 +#define CSR_PMPADDR3 0x3b3 +#define CSR_PMPADDR4 0x3b4 +#define CSR_PMPADDR5 0x3b5 +#define CSR_PMPADDR6 0x3b6 +#define CSR_PMPADDR7 0x3b7 +#define CSR_PMPADDR8 0x3b8 +#define CSR_PMPADDR9 0x3b9 +#define CSR_PMPADDR10 0x3ba +#define CSR_PMPADDR11 0x3bb +#define CSR_PMPADDR12 0x3bc +#define CSR_PMPADDR13 0x3bd +#define CSR_PMPADDR14 0x3be +#define CSR_PMPADDR15 0x3bf
+#define CSR_TSELECT 0x7a0 +#define CSR_TDATA1 0x7a1 +#define CSR_TDATA2 0x7a2 +#define CSR_TDATA3 0x7a3 +#define CSR_DCSR 0x7b0 +#define CSR_DPC 0x7b1 +#define CSR_DSCRATCH 0x7b2
+#define CSR_MCYCLE 0xb00 +#define CSR_MINSTRET 0xb02 +#define CSR_MHPMCOUNTER3 0xb03 +#define CSR_MHPMCOUNTER4 0xb04 +#define CSR_MHPMCOUNTER5 0xb05 +#define CSR_MHPMCOUNTER6 0xb06 +#define CSR_MHPMCOUNTER7 0xb07 +#define CSR_MHPMCOUNTER8 0xb08 +#define CSR_MHPMCOUNTER9 0xb09 +#define CSR_MHPMCOUNTER10 0xb0a +#define CSR_MHPMCOUNTER11 0xb0b +#define CSR_MHPMCOUNTER12 0xb0c +#define CSR_MHPMCOUNTER13 0xb0d +#define CSR_MHPMCOUNTER14 0xb0e +#define CSR_MHPMCOUNTER15 0xb0f +#define CSR_MHPMCOUNTER16 0xb10 +#define CSR_MHPMCOUNTER17 0xb11 +#define CSR_MHPMCOUNTER18 0xb12 +#define CSR_MHPMCOUNTER19 0xb13 +#define CSR_MHPMCOUNTER20 0xb14 +#define CSR_MHPMCOUNTER21 0xb15 +#define CSR_MHPMCOUNTER22 0xb16 +#define CSR_MHPMCOUNTER23 0xb17 +#define CSR_MHPMCOUNTER24 0xb18 +#define CSR_MHPMCOUNTER25 0xb19 +#define CSR_MHPMCOUNTER26 0xb1a +#define CSR_MHPMCOUNTER27 0xb1b +#define CSR_MHPMCOUNTER28 0xb1c +#define CSR_MHPMCOUNTER29 0xb1d +#define CSR_MHPMCOUNTER30 0xb1e +#define CSR_MHPMCOUNTER31 0xb1f +#define CSR_MCYCLEH 0xb80 +#define CSR_MINSTRETH 0xb82 +#define CSR_MHPMCOUNTER3H 0xb83 +#define CSR_MHPMCOUNTER4H 0xb84 +#define CSR_MHPMCOUNTER5H 0xb85 +#define CSR_MHPMCOUNTER6H 0xb86 +#define CSR_MHPMCOUNTER7H 0xb87 +#define CSR_MHPMCOUNTER8H 0xb88 +#define CSR_MHPMCOUNTER9H 0xb89 +#define CSR_MHPMCOUNTER10H 0xb8a +#define CSR_MHPMCOUNTER11H 0xb8b +#define CSR_MHPMCOUNTER12H 0xb8c +#define CSR_MHPMCOUNTER13H 0xb8d +#define CSR_MHPMCOUNTER14H 0xb8e +#define CSR_MHPMCOUNTER15H 0xb8f +#define CSR_MHPMCOUNTER16H 0xb90 +#define CSR_MHPMCOUNTER17H 0xb91 +#define CSR_MHPMCOUNTER18H 0xb92 +#define CSR_MHPMCOUNTER19H 0xb93 +#define CSR_MHPMCOUNTER20H 0xb94 +#define CSR_MHPMCOUNTER21H 0xb95 +#define CSR_MHPMCOUNTER22H 0xb96 +#define CSR_MHPMCOUNTER23H 0xb97 +#define CSR_MHPMCOUNTER24H 0xb98 +#define CSR_MHPMCOUNTER25H 0xb99 +#define CSR_MHPMCOUNTER26H 0xb9a +#define CSR_MHPMCOUNTER27H 0xb9b +#define CSR_MHPMCOUNTER28H 0xb9c +#define CSR_MHPMCOUNTER29H 0xb9d +#define CSR_MHPMCOUNTER30H 0xb9e +#define CSR_MHPMCOUNTER31H 0xb9f
+#define CSR_CYCLE 0xc00 +#define CSR_TIME 0xc01 +#define CSR_INSTRET 0xc02 +#define CSR_HPMCOUNTER3 0xc03 +#define CSR_HPMCOUNTER4 0xc04 +#define CSR_HPMCOUNTER5 0xc05 +#define CSR_HPMCOUNTER6 0xc06 +#define CSR_HPMCOUNTER7 0xc07 +#define CSR_HPMCOUNTER8 0xc08 +#define CSR_HPMCOUNTER9 0xc09 +#define CSR_HPMCOUNTER10 0xc0a +#define CSR_HPMCOUNTER11 0xc0b +#define CSR_HPMCOUNTER12 0xc0c +#define CSR_HPMCOUNTER13 0xc0d +#define CSR_HPMCOUNTER14 0xc0e +#define CSR_HPMCOUNTER15 0xc0f +#define CSR_HPMCOUNTER16 0xc10 +#define CSR_HPMCOUNTER17 0xc11 +#define CSR_HPMCOUNTER18 0xc12 +#define CSR_HPMCOUNTER19 0xc13 +#define CSR_HPMCOUNTER20 0xc14 +#define CSR_HPMCOUNTER21 0xc15 +#define CSR_HPMCOUNTER22 0xc16 +#define CSR_HPMCOUNTER23 0xc17 +#define CSR_HPMCOUNTER24 0xc18 +#define CSR_HPMCOUNTER25 0xc19 +#define CSR_HPMCOUNTER26 0xc1a +#define CSR_HPMCOUNTER27 0xc1b +#define CSR_HPMCOUNTER28 0xc1c +#define CSR_HPMCOUNTER29 0xc1d +#define CSR_HPMCOUNTER30 0xc1e +#define CSR_HPMCOUNTER31 0xc1f +#define CSR_CYCLEH 0xc80 +#define CSR_TIMEH 0xc81 +#define CSR_INSTRETH 0xc82 +#define CSR_HPMCOUNTER3H 0xc83 +#define CSR_HPMCOUNTER4H 0xc84 +#define CSR_HPMCOUNTER5H 0xc85 +#define CSR_HPMCOUNTER6H 0xc86 +#define CSR_HPMCOUNTER7H 0xc87 +#define CSR_HPMCOUNTER8H 0xc88 +#define CSR_HPMCOUNTER9H 0xc89 +#define CSR_HPMCOUNTER10H 0xc8a +#define CSR_HPMCOUNTER11H 0xc8b +#define CSR_HPMCOUNTER12H 0xc8c +#define CSR_HPMCOUNTER13H 0xc8d +#define CSR_HPMCOUNTER14H 0xc8e +#define CSR_HPMCOUNTER15H 0xc8f +#define CSR_HPMCOUNTER16H 0xc90 +#define CSR_HPMCOUNTER17H 0xc91 +#define CSR_HPMCOUNTER18H 0xc92 +#define CSR_HPMCOUNTER19H 0xc93 +#define CSR_HPMCOUNTER20H 0xc94 +#define CSR_HPMCOUNTER21H 0xc95 +#define CSR_HPMCOUNTER22H 0xc96 +#define CSR_HPMCOUNTER23H 0xc97 +#define CSR_HPMCOUNTER24H 0xc98 +#define CSR_HPMCOUNTER25H 0xc99 +#define CSR_HPMCOUNTER26H 0xc9a +#define CSR_HPMCOUNTER27H 0xc9b +#define CSR_HPMCOUNTER28H 0xc9c +#define CSR_HPMCOUNTER29H 0xc9d +#define CSR_HPMCOUNTER30H 0xc9e +#define CSR_HPMCOUNTER31H 0xc9f
+#define CSR_MVENDORID 0xf11 +#define CSR_MARCHID 0xf12 +#define CSR_MIMPID 0xf13 +#define CSR_MHARTID 0xf14
#endif /* __riscv */
#endif /* RISCV_CSR_ENCODING_H */

This adds all exception codes in encoding.h.
Signed-off-by: Bin Meng bmeng.cn@gmail.com ---
Changes in v2: None
arch/riscv/include/asm/encoding.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
diff --git a/arch/riscv/include/asm/encoding.h b/arch/riscv/include/asm/encoding.h index c910d5c..e6d905a 100644 --- a/arch/riscv/include/asm/encoding.h +++ b/arch/riscv/include/asm/encoding.h @@ -85,6 +85,21 @@ #define IRQ_COP 12 #define IRQ_HOST 13
+#define CAUSE_MISALIGNED_FETCH 0 +#define CAUSE_FETCH_ACCESS 1 +#define CAUSE_ILLEGAL_INSTRUCTION 2 +#define CAUSE_BREAKPOINT 3 +#define CAUSE_MISALIGNED_LOAD 4 +#define CAUSE_LOAD_ACCESS 5 +#define CAUSE_MISALIGNED_STORE 6 +#define CAUSE_STORE_ACCESS 7 +#define CAUSE_USER_ECALL 8 +#define CAUSE_SUPERVISOR_ECALL 9 +#define CAUSE_MACHINE_ECALL 11 +#define CAUSE_FETCH_PAGE_FAULT 12 +#define CAUSE_LOAD_PAGE_FAULT 13 +#define CAUSE_STORE_PAGE_FAULT 15 + #define DEFAULT_RSTVEC 0x00001000 #define DEFAULT_NMIVEC 0x00001004 #define DEFAULT_MTVEC 0x00001010

On Fri, 2018-12-07 at 06:14 -0800, Bin Meng wrote:
This adds all exception codes in encoding.h.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
Changes in v2: None
arch/riscv/include/asm/encoding.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
Reviewed-by: Lukas Auer lukas.auer@aisec.fraunhofer.de

With current csr_xxx ops, we cannot pass a macro to parameter 'csr', hence we need add another level to allow the parameter to be a macro itself, aka indirect stringification.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
---
Changes in v2: - new patch to add indirect stringification to csr_xxx ops
arch/riscv/include/asm/csr.h | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h index 29624fd..86136f5 100644 --- a/arch/riscv/include/asm/csr.h +++ b/arch/riscv/include/asm/csr.h @@ -61,10 +61,12 @@
#ifndef __ASSEMBLY__
+#define xcsr(csr) #csr + #define csr_swap(csr, val) \ ({ \ unsigned long __v = (unsigned long)(val); \ - __asm__ __volatile__ ("csrrw %0, " #csr ", %1" \ + __asm__ __volatile__ ("csrrw %0, " xcsr(csr) ", %1" \ : "=r" (__v) : "rK" (__v) \ : "memory"); \ __v; \ @@ -73,7 +75,7 @@ #define csr_read(csr) \ ({ \ register unsigned long __v; \ - __asm__ __volatile__ ("csrr %0, " #csr \ + __asm__ __volatile__ ("csrr %0, " xcsr(csr) \ : "=r" (__v) : \ : "memory"); \ __v; \ @@ -82,7 +84,7 @@ #define csr_write(csr, val) \ ({ \ unsigned long __v = (unsigned long)(val); \ - __asm__ __volatile__ ("csrw " #csr ", %0" \ + __asm__ __volatile__ ("csrw " xcsr(csr) ", %0" \ : : "rK" (__v) \ : "memory"); \ }) @@ -90,7 +92,7 @@ #define csr_read_set(csr, val) \ ({ \ unsigned long __v = (unsigned long)(val); \ - __asm__ __volatile__ ("csrrs %0, " #csr ", %1" \ + __asm__ __volatile__ ("csrrs %0, " xcsr(csr) ", %1" \ : "=r" (__v) : "rK" (__v) \ : "memory"); \ __v; \ @@ -99,7 +101,7 @@ #define csr_set(csr, val) \ ({ \ unsigned long __v = (unsigned long)(val); \ - __asm__ __volatile__ ("csrs " #csr ", %0" \ + __asm__ __volatile__ ("csrs " xcsr(csr) ", %0" \ : : "rK" (__v) \ : "memory"); \ }) @@ -107,7 +109,7 @@ #define csr_read_clear(csr, val) \ ({ \ unsigned long __v = (unsigned long)(val); \ - __asm__ __volatile__ ("csrrc %0, " #csr ", %1" \ + __asm__ __volatile__ ("csrrc %0, " xcsr(csr) ", %1" \ : "=r" (__v) : "rK" (__v) \ : "memory"); \ __v; \ @@ -116,7 +118,7 @@ #define csr_clear(csr, val) \ ({ \ unsigned long __v = (unsigned long)(val); \ - __asm__ __volatile__ ("csrc " #csr ", %0" \ + __asm__ __volatile__ ("csrc " xcsr(csr) ", %0" \ : : "rK" (__v) \ : "memory"); \ })

On Fri, 2018-12-07 at 06:14 -0800, Bin Meng wrote:
With current csr_xxx ops, we cannot pass a macro to parameter 'csr', hence we need add another level to allow the parameter to be a macro itself, aka indirect stringification.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
Changes in v2:
- new patch to add indirect stringification to csr_xxx ops
arch/riscv/include/asm/csr.h | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
Reviewed-by: Lukas Auer lukas.auer@aisec.fraunhofer.de

Implement arch_cpu_init() to do some basic architecture level cpu initialization, like FPU enable, etc.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
---
Changes in v2: - use csr_set() to set MSTATUS_FS - only enabling the cycle, time, and instret counters - change to use satp
arch/riscv/cpu/cpu.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c index 3858e51..194799c 100644 --- a/arch/riscv/cpu/cpu.c +++ b/arch/riscv/cpu/cpu.c @@ -7,6 +7,7 @@ #include <cpu.h> #include <log.h> #include <asm/csr.h> +#include <asm/encoding.h>
/* * prior_stage_fdt_address must be stored in the data section since it is used @@ -67,3 +68,21 @@ int arch_early_init_r(void)
return 0; } + +int arch_cpu_init(void) +{ + /* Enable FPU */ + if (supports_extension('d') || supports_extension('f')) { + csr_set(MODE_PREFIX(status), MSTATUS_FS); + csr_write(fcsr, 0); + } + + /* Enable perf counters for cycle, time, and instret counters only */ + csr_write(MODE_PREFIX(counteren), GENMASK(2, 0)); + + /* Disable paging */ + if (supports_extension('s')) + csr_write(satp, 0); + + return 0; +}

Hi Bin,
On Fri, 2018-12-07 at 06:14 -0800, Bin Meng wrote:
Implement arch_cpu_init() to do some basic architecture level cpu initialization, like FPU enable, etc.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
Changes in v2:
- use csr_set() to set MSTATUS_FS
- only enabling the cycle, time, and instret counters
- change to use satp
arch/riscv/cpu/cpu.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c index 3858e51..194799c 100644 --- a/arch/riscv/cpu/cpu.c +++ b/arch/riscv/cpu/cpu.c @@ -7,6 +7,7 @@ #include <cpu.h> #include <log.h> #include <asm/csr.h> +#include <asm/encoding.h>
/*
- prior_stage_fdt_address must be stored in the data section since
it is used @@ -67,3 +68,21 @@ int arch_early_init_r(void)
return 0; }
+int arch_cpu_init(void) +{
- /* Enable FPU */
- if (supports_extension('d') || supports_extension('f')) {
supports_extension does not work when running in supervisor mode (unless BBL is patched). Can we maybe use the CPU driver here?
csr_set(MODE_PREFIX(status), MSTATUS_FS);
csr_write(fcsr, 0);
- }
- /* Enable perf counters for cycle, time, and instret counters
only */
- csr_write(MODE_PREFIX(counteren), GENMASK(2, 0));
I would tend to only enable this in mcounteren, so for the supervisor- mode. Linux can still enable the counters for user-mode if required.
- /* Disable paging */
- if (supports_extension('s'))
csr_write(satp, 0);
This should only be done, when running in machine mode. In supervisor mode this would cause issues if we have something other than an identity-mapping or paging disabled.
Thanks, Lukas
- return 0;
+}

Hi Lukas,
On Tue, Dec 11, 2018 at 8:01 AM Auer, Lukas lukas.auer@aisec.fraunhofer.de wrote:
Hi Bin,
On Fri, 2018-12-07 at 06:14 -0800, Bin Meng wrote:
Implement arch_cpu_init() to do some basic architecture level cpu initialization, like FPU enable, etc.
Signed-off-by: Bin Meng bmeng.cn@gmail.com
Changes in v2:
- use csr_set() to set MSTATUS_FS
- only enabling the cycle, time, and instret counters
- change to use satp
arch/riscv/cpu/cpu.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c index 3858e51..194799c 100644 --- a/arch/riscv/cpu/cpu.c +++ b/arch/riscv/cpu/cpu.c @@ -7,6 +7,7 @@ #include <cpu.h> #include <log.h> #include <asm/csr.h> +#include <asm/encoding.h>
/*
- prior_stage_fdt_address must be stored in the data section since
it is used @@ -67,3 +68,21 @@ int arch_early_init_r(void)
return 0;
}
+int arch_cpu_init(void) +{
/* Enable FPU */
if (supports_extension('d') || supports_extension('f')) {
supports_extension does not work when running in supervisor mode (unless BBL is patched). Can we maybe use the CPU driver here?
Yes, I think so. Will change to use info provided by the CPU driver in v3.
csr_set(MODE_PREFIX(status), MSTATUS_FS);
csr_write(fcsr, 0);
}
/* Enable perf counters for cycle, time, and instret counters
only */
csr_write(MODE_PREFIX(counteren), GENMASK(2, 0));
I would tend to only enable this in mcounteren, so for the supervisor- mode. Linux can still enable the counters for user-mode if required.
OK.
/* Disable paging */
if (supports_extension('s'))
csr_write(satp, 0);
This should only be done, when running in machine mode. In supervisor mode this would cause issues if we have something other than an identity-mapping or paging disabled.
I doubt we want to enable paging for S-mode U-Boot, but I am OK to do such in M-mode only.
Regards, Bin

Currently the M-mode trap handler codes are in start.S. For future extension, move them to a separate file mtrap.S.
Signed-off-by: Bin Meng bmeng.cn@gmail.com Reviewed-by: Lukas Auer lukas.auer@aisec.fraunhofer.de ---
Changes in v2: None
arch/riscv/cpu/Makefile | 2 +- arch/riscv/cpu/mtrap.S | 111 ++++++++++++++++++++++++++++++++++++++++++++++++ arch/riscv/cpu/start.S | 89 -------------------------------------- 3 files changed, 112 insertions(+), 90 deletions(-) create mode 100644 arch/riscv/cpu/mtrap.S
diff --git a/arch/riscv/cpu/Makefile b/arch/riscv/cpu/Makefile index 2cc6757..6bf6f91 100644 --- a/arch/riscv/cpu/Makefile +++ b/arch/riscv/cpu/Makefile @@ -4,4 +4,4 @@
extra-y = start.o
-obj-y += cpu.o +obj-y += cpu.o mtrap.o diff --git a/arch/riscv/cpu/mtrap.S b/arch/riscv/cpu/mtrap.S new file mode 100644 index 0000000..a5ad558 --- /dev/null +++ b/arch/riscv/cpu/mtrap.S @@ -0,0 +1,111 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * M-mode Trap Handler Code for RISC-V Core + * + * Copyright (c) 2017 Microsemi Corporation. + * Copyright (c) 2017 Padmarao Begari Padmarao.Begari@microsemi.com + * + * Copyright (C) 2017 Andes Technology Corporation + * Rick Chen, Andes Technology Corporation rick@andestech.com + * + * Copyright (C) 2018, Bin Meng bmeng.cn@gmail.com + */ + +#include <common.h> +#include <asm/encoding.h> + +#ifdef CONFIG_32BIT +#define LREG lw +#define SREG sw +#define REGBYTES 4 +#else +#define LREG ld +#define SREG sd +#define REGBYTES 8 +#endif + + .text + + /* trap entry */ + .align 2 + .global trap_entry +trap_entry: + addi sp, sp, -32 * REGBYTES + SREG x1, 1 * REGBYTES(sp) + SREG x2, 2 * REGBYTES(sp) + SREG x3, 3 * REGBYTES(sp) + SREG x4, 4 * REGBYTES(sp) + SREG x5, 5 * REGBYTES(sp) + SREG x6, 6 * REGBYTES(sp) + SREG x7, 7 * REGBYTES(sp) + SREG x8, 8 * REGBYTES(sp) + SREG x9, 9 * REGBYTES(sp) + SREG x10, 10 * REGBYTES(sp) + SREG x11, 11 * REGBYTES(sp) + SREG x12, 12 * REGBYTES(sp) + SREG x13, 13 * REGBYTES(sp) + SREG x14, 14 * REGBYTES(sp) + SREG x15, 15 * REGBYTES(sp) + SREG x16, 16 * REGBYTES(sp) + SREG x17, 17 * REGBYTES(sp) + SREG x18, 18 * REGBYTES(sp) + SREG x19, 19 * REGBYTES(sp) + SREG x20, 20 * REGBYTES(sp) + SREG x21, 21 * REGBYTES(sp) + SREG x22, 22 * REGBYTES(sp) + SREG x23, 23 * REGBYTES(sp) + SREG x24, 24 * REGBYTES(sp) + SREG x25, 25 * REGBYTES(sp) + SREG x26, 26 * REGBYTES(sp) + SREG x27, 27 * REGBYTES(sp) + SREG x28, 28 * REGBYTES(sp) + SREG x29, 29 * REGBYTES(sp) + SREG x30, 30 * REGBYTES(sp) + SREG x31, 31 * REGBYTES(sp) + csrr a0, MODE_PREFIX(cause) + csrr a1, MODE_PREFIX(epc) + mv a2, sp + jal handle_trap + csrw MODE_PREFIX(epc), a0 + +#ifdef CONFIG_RISCV_SMODE + /* Remain in S-mode after sret */ + li t0, SSTATUS_SPP +#else + /* Remain in M-mode after mret */ + li t0, MSTATUS_MPP +#endif + csrs MODE_PREFIX(status), t0 + LREG x1, 1 * REGBYTES(sp) + LREG x2, 2 * REGBYTES(sp) + LREG x3, 3 * REGBYTES(sp) + LREG x4, 4 * REGBYTES(sp) + LREG x5, 5 * REGBYTES(sp) + LREG x6, 6 * REGBYTES(sp) + LREG x7, 7 * REGBYTES(sp) + LREG x8, 8 * REGBYTES(sp) + LREG x9, 9 * REGBYTES(sp) + LREG x10, 10 * REGBYTES(sp) + LREG x11, 11 * REGBYTES(sp) + LREG x12, 12 * REGBYTES(sp) + LREG x13, 13 * REGBYTES(sp) + LREG x14, 14 * REGBYTES(sp) + LREG x15, 15 * REGBYTES(sp) + LREG x16, 16 * REGBYTES(sp) + LREG x17, 17 * REGBYTES(sp) + LREG x18, 18 * REGBYTES(sp) + LREG x19, 19 * REGBYTES(sp) + LREG x20, 20 * REGBYTES(sp) + LREG x21, 21 * REGBYTES(sp) + LREG x22, 22 * REGBYTES(sp) + LREG x23, 23 * REGBYTES(sp) + LREG x24, 24 * REGBYTES(sp) + LREG x25, 25 * REGBYTES(sp) + LREG x26, 26 * REGBYTES(sp) + LREG x27, 27 * REGBYTES(sp) + LREG x28, 28 * REGBYTES(sp) + LREG x29, 29 * REGBYTES(sp) + LREG x30, 30 * REGBYTES(sp) + LREG x31, 31 * REGBYTES(sp) + addi sp, sp, 32 * REGBYTES + MODE_PREFIX(ret) diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S index 64246a4..47c3bf0 100644 --- a/arch/riscv/cpu/start.S +++ b/arch/riscv/cpu/start.S @@ -198,92 +198,3 @@ call_board_init_r: * jump to it ... */ jr t4 /* jump to board_init_r() */ - -/* - * trap entry - */ -.align 2 -trap_entry: - addi sp, sp, -32*REGBYTES - SREG x1, 1*REGBYTES(sp) - SREG x2, 2*REGBYTES(sp) - SREG x3, 3*REGBYTES(sp) - SREG x4, 4*REGBYTES(sp) - SREG x5, 5*REGBYTES(sp) - SREG x6, 6*REGBYTES(sp) - SREG x7, 7*REGBYTES(sp) - SREG x8, 8*REGBYTES(sp) - SREG x9, 9*REGBYTES(sp) - SREG x10, 10*REGBYTES(sp) - SREG x11, 11*REGBYTES(sp) - SREG x12, 12*REGBYTES(sp) - SREG x13, 13*REGBYTES(sp) - SREG x14, 14*REGBYTES(sp) - SREG x15, 15*REGBYTES(sp) - SREG x16, 16*REGBYTES(sp) - SREG x17, 17*REGBYTES(sp) - SREG x18, 18*REGBYTES(sp) - SREG x19, 19*REGBYTES(sp) - SREG x20, 20*REGBYTES(sp) - SREG x21, 21*REGBYTES(sp) - SREG x22, 22*REGBYTES(sp) - SREG x23, 23*REGBYTES(sp) - SREG x24, 24*REGBYTES(sp) - SREG x25, 25*REGBYTES(sp) - SREG x26, 26*REGBYTES(sp) - SREG x27, 27*REGBYTES(sp) - SREG x28, 28*REGBYTES(sp) - SREG x29, 29*REGBYTES(sp) - SREG x30, 30*REGBYTES(sp) - SREG x31, 31*REGBYTES(sp) - csrr a0, MODE_PREFIX(cause) - csrr a1, MODE_PREFIX(epc) - mv a2, sp - jal handle_trap - csrw MODE_PREFIX(epc), a0 - -#ifdef CONFIG_RISCV_SMODE -/* - * Remain in S-mode after sret - */ - li t0, SSTATUS_SPP -#else -/* - * Remain in M-mode after mret - */ - li t0, MSTATUS_MPP -#endif - csrs MODE_PREFIX(status), t0 - LREG x1, 1*REGBYTES(sp) - LREG x2, 2*REGBYTES(sp) - LREG x3, 3*REGBYTES(sp) - LREG x4, 4*REGBYTES(sp) - LREG x5, 5*REGBYTES(sp) - LREG x6, 6*REGBYTES(sp) - LREG x7, 7*REGBYTES(sp) - LREG x8, 8*REGBYTES(sp) - LREG x9, 9*REGBYTES(sp) - LREG x10, 10*REGBYTES(sp) - LREG x11, 11*REGBYTES(sp) - LREG x12, 12*REGBYTES(sp) - LREG x13, 13*REGBYTES(sp) - LREG x14, 14*REGBYTES(sp) - LREG x15, 15*REGBYTES(sp) - LREG x16, 16*REGBYTES(sp) - LREG x17, 17*REGBYTES(sp) - LREG x18, 18*REGBYTES(sp) - LREG x19, 19*REGBYTES(sp) - LREG x20, 20*REGBYTES(sp) - LREG x21, 21*REGBYTES(sp) - LREG x22, 22*REGBYTES(sp) - LREG x23, 23*REGBYTES(sp) - LREG x24, 24*REGBYTES(sp) - LREG x25, 25*REGBYTES(sp) - LREG x26, 26*REGBYTES(sp) - LREG x27, 27*REGBYTES(sp) - LREG x28, 28*REGBYTES(sp) - LREG x29, 29*REGBYTES(sp) - LREG x30, 30*REGBYTES(sp) - LREG x31, 31*REGBYTES(sp) - addi sp, sp, 32*REGBYTES - MODE_PREFIX(ret)

sp cannot be loaded before restoring other registers.
Signed-off-by: Bin Meng bmeng.cn@gmail.com Reviewed-by: Lukas Auer lukas.auer@aisec.fraunhofer.de ---
Changes in v2: None
arch/riscv/cpu/mtrap.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/riscv/cpu/mtrap.S b/arch/riscv/cpu/mtrap.S index a5ad558..da307e4 100644 --- a/arch/riscv/cpu/mtrap.S +++ b/arch/riscv/cpu/mtrap.S @@ -77,7 +77,6 @@ trap_entry: #endif csrs MODE_PREFIX(status), t0 LREG x1, 1 * REGBYTES(sp) - LREG x2, 2 * REGBYTES(sp) LREG x3, 3 * REGBYTES(sp) LREG x4, 4 * REGBYTES(sp) LREG x5, 5 * REGBYTES(sp) @@ -107,5 +106,6 @@ trap_entry: LREG x29, 29 * REGBYTES(sp) LREG x30, 30 * REGBYTES(sp) LREG x31, 31 * REGBYTES(sp) + LREG x2, 2 * REGBYTES(sp) addi sp, sp, 32 * REGBYTES MODE_PREFIX(ret)

At present the trap handler returns to M-mode only. Change to returning to previous privilege level instead.
Signed-off-by: Bin Meng bmeng.cn@gmail.com Reviewed-by: Lukas Auer lukas.auer@aisec.fraunhofer.de ---
Changes in v2: None
arch/riscv/cpu/mtrap.S | 8 -------- 1 file changed, 8 deletions(-)
diff --git a/arch/riscv/cpu/mtrap.S b/arch/riscv/cpu/mtrap.S index da307e4..407ecfa 100644 --- a/arch/riscv/cpu/mtrap.S +++ b/arch/riscv/cpu/mtrap.S @@ -68,14 +68,6 @@ trap_entry: jal handle_trap csrw MODE_PREFIX(epc), a0
-#ifdef CONFIG_RISCV_SMODE - /* Remain in S-mode after sret */ - li t0, SSTATUS_SPP -#else - /* Remain in M-mode after mret */ - li t0, MSTATUS_MPP -#endif - csrs MODE_PREFIX(status), t0 LREG x1, 1 * REGBYTES(sp) LREG x3, 3 * REGBYTES(sp) LREG x4, 4 * REGBYTES(sp)

With this change, we can avoid a forward declaration.
Signed-off-by: Bin Meng bmeng.cn@gmail.com Reviewed-by: Lukas Auer lukas.auer@aisec.fraunhofer.de
---
Changes in v2: - rebase on u-boot/master - drop the patch "riscv: Pass correct exception code to _exit_trap()" - drop the patch "riscv: Refactor handle_trap() a little for future extension" - drop the patch "riscv: Allow U-Boot to run on hart 0 only", and leave the SMP support to Lukas's future patch series
arch/riscv/lib/interrupts.c | 62 ++++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 32 deletions(-)
diff --git a/arch/riscv/lib/interrupts.c b/arch/riscv/lib/interrupts.c index 3aff006..e185933 100644 --- a/arch/riscv/lib/interrupts.c +++ b/arch/riscv/lib/interrupts.c @@ -12,7 +12,36 @@ #include <asm/system.h> #include <asm/encoding.h>
-static void _exit_trap(ulong code, ulong epc, struct pt_regs *regs); +static void _exit_trap(ulong code, ulong epc, struct pt_regs *regs) +{ + static const char * const exception_code[] = { + "Instruction address misaligned", + "Instruction access fault", + "Illegal instruction", + "Breakpoint", + "Load address misaligned", + "Load access fault", + "Store/AMO address misaligned", + "Store/AMO access fault", + "Environment call from U-mode", + "Environment call from S-mode", + "Reserved", + "Environment call from M-mode", + "Instruction page fault", + "Load page fault", + "Reserved", + "Store/AMO page fault", + }; + + if (code < ARRAY_SIZE(exception_code)) { + printf("exception code: %ld , %s , epc %lx , ra %lx\n", + code, exception_code[code], epc, regs->ra); + } else { + printf("Reserved\n"); + } + + hang(); +}
int interrupt_init(void) { @@ -72,34 +101,3 @@ __attribute__((weak)) void external_interrupt(struct pt_regs *regs) __attribute__((weak)) void timer_interrupt(struct pt_regs *regs) { } - -static void _exit_trap(ulong code, ulong epc, struct pt_regs *regs) -{ - static const char * const exception_code[] = { - "Instruction address misaligned", - "Instruction access fault", - "Illegal instruction", - "Breakpoint", - "Load address misaligned", - "Load access fault", - "Store/AMO address misaligned", - "Store/AMO access fault", - "Environment call from U-mode", - "Environment call from S-mode", - "Reserved", - "Environment call from M-mode", - "Instruction page fault", - "Load page fault", - "Reserved", - "Store/AMO page fault", - }; - - if (code < ARRAY_SIZE(exception_code)) { - printf("exception code: %ld , %s , epc %lx , ra %lx\n", - code, exception_code[code], epc, regs->ra); - } else { - printf("Reserved\n"); - } - - hang(); -}
participants (2)
-
Auer, Lukas
-
Bin Meng