diff options
author | Tom Rini <trini@konsulko.com> | 2018-12-21 13:36:08 -0500 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2018-12-21 13:36:08 -0500 |
commit | 328e3f8a706931e1a8f76adfdc015ad76cbeb83c (patch) | |
tree | b88b5eb9c3135640bc44262229cc70f4a0e6acdc /arch | |
parent | 1f2e948d6d53f77a2ddb2dde3531b0d5bc2815ad (diff) | |
parent | 368ff57805b03bebf99e97e703ce07aec721bc71 (diff) |
Merge git://git.denx.de/u-boot-riscv
- Add DM drivers to support RISC-V CPU and timer, plus some bug fixes.
- Support SiFive UART
- Rename ax25-ae350 defconfig
Diffstat (limited to 'arch')
-rw-r--r-- | arch/riscv/Kconfig | 60 | ||||
-rw-r--r-- | arch/riscv/Makefile | 9 | ||||
-rw-r--r-- | arch/riscv/cpu/Makefile | 2 | ||||
-rw-r--r-- | arch/riscv/cpu/ax25/Kconfig | 17 | ||||
-rw-r--r-- | arch/riscv/cpu/ax25/cache.c | 12 | ||||
-rw-r--r-- | arch/riscv/cpu/cpu.c | 98 | ||||
-rw-r--r-- | arch/riscv/cpu/mtrap.S | 103 | ||||
-rw-r--r-- | arch/riscv/cpu/qemu/Kconfig | 12 | ||||
-rw-r--r-- | arch/riscv/cpu/qemu/cpu.c | 14 | ||||
-rw-r--r-- | arch/riscv/cpu/start.S | 93 | ||||
-rw-r--r-- | arch/riscv/dts/ae350.dts | 229 | ||||
-rw-r--r-- | arch/riscv/include/asm/csr.h | 16 | ||||
-rw-r--r-- | arch/riscv/include/asm/encoding.h | 236 | ||||
-rw-r--r-- | arch/riscv/include/asm/global_data.h | 4 | ||||
-rw-r--r-- | arch/riscv/include/asm/syscon.h | 19 | ||||
-rw-r--r-- | arch/riscv/lib/Makefile | 2 | ||||
-rw-r--r-- | arch/riscv/lib/asm-offsets.c | 19 | ||||
-rw-r--r-- | arch/riscv/lib/bootm.c | 2 | ||||
-rw-r--r-- | arch/riscv/lib/interrupts.c | 62 | ||||
-rw-r--r-- | arch/riscv/lib/rdtime.c | 38 | ||||
-rw-r--r-- | arch/riscv/lib/sifive_clint.c | 84 |
21 files changed, 726 insertions, 405 deletions
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 732a357a99..c45e4d73a8 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 @@ -44,6 +45,40 @@ 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 + +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 @@ -55,15 +90,30 @@ 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 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. + +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. + +config SYS_MALLOC_F_LEN + default 0x1000 + endmenu diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile index 55d7c6550e..0b80eb8d86 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) diff --git a/arch/riscv/cpu/Makefile b/arch/riscv/cpu/Makefile index 2cc6757fcf..6bf6f911c6 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/ax25/Kconfig b/arch/riscv/cpu/ax25/Kconfig index 6c7022f0f5..e9dbca2fae 100644 --- a/arch/riscv/cpu/ax25/Kconfig +++ b/arch/riscv/cpu/ax25/Kconfig @@ -1,7 +1,14 @@ 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. + +if RISCV_NDS + +config RISCV_NDS_CACHE + bool "AndeStar V5 families specific cache support" + help + Provide Andes Technology AndeStar V5 families specific cache support. + +endif diff --git a/arch/riscv/cpu/ax25/cache.c b/arch/riscv/cpu/ax25/cache.c index 6600ac2fac..8d6ae170b8 100644 --- a/arch/riscv/cpu/ax25/cache.c +++ b/arch/riscv/cpu/ax25/cache.c @@ -9,7 +9,7 @@ void icache_enable(void) { #ifndef CONFIG_SYS_ICACHE_OFF -#ifdef CONFIG_RISCV_NDS +#ifdef CONFIG_RISCV_NDS_CACHE asm volatile ( "csrr t1, mcache_ctl\n\t" "ori t0, t1, 0x1\n\t" @@ -22,7 +22,7 @@ void icache_enable(void) void icache_disable(void) { #ifndef CONFIG_SYS_ICACHE_OFF -#ifdef CONFIG_RISCV_NDS +#ifdef CONFIG_RISCV_NDS_CACHE asm volatile ( "fence.i\n\t" "csrr t1, mcache_ctl\n\t" @@ -36,7 +36,7 @@ void icache_disable(void) void dcache_enable(void) { #ifndef CONFIG_SYS_DCACHE_OFF -#ifdef CONFIG_RISCV_NDS +#ifdef CONFIG_RISCV_NDS_CACHE asm volatile ( "csrr t1, mcache_ctl\n\t" "ori t0, t1, 0x2\n\t" @@ -49,7 +49,7 @@ void dcache_enable(void) void dcache_disable(void) { #ifndef CONFIG_SYS_DCACHE_OFF -#ifdef CONFIG_RISCV_NDS +#ifdef CONFIG_RISCV_NDS_CACHE asm volatile ( "fence\n\t" "csrr t1, mcache_ctl\n\t" @@ -64,7 +64,7 @@ int icache_status(void) { int ret = 0; -#ifdef CONFIG_RISCV_NDS +#ifdef CONFIG_RISCV_NDS_CACHE asm volatile ( "csrr t1, mcache_ctl\n\t" "andi %0, t1, 0x01\n\t" @@ -81,7 +81,7 @@ int dcache_status(void) { int ret = 0; -#ifdef CONFIG_RISCV_NDS +#ifdef CONFIG_RISCV_NDS_CACHE asm volatile ( "csrr t1, mcache_ctl\n\t" "andi %0, t1, 0x02\n\t" diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c index d9f820c44c..e662140427 100644 --- a/arch/riscv/cpu/cpu.c +++ b/arch/riscv/cpu/cpu.c @@ -4,7 +4,12 @@ */ #include <common.h> +#include <cpu.h> +#include <dm.h> +#include <log.h> #include <asm/csr.h> +#include <asm/encoding.h> +#include <dm/uclass-internal.h> /* * prior_stage_fdt_address must be stored in the data section since it is used @@ -12,44 +17,79 @@ */ phys_addr_t prior_stage_fdt_address __attribute__((section(".data"))); -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) { +#ifdef CONFIG_CPU + struct udevice *dev; + char desc[32]; + + uclass_find_first_device(UCLASS_CPU, &dev); + if (!dev) { + debug("unable to find the RISC-V cpu device\n"); + return false; + } + if (!cpu_get_desc(dev, desc, sizeof(desc))) { + /* skip the first 4 characters (rv32|rv64) */ + if (strchr(desc + 4, ext)) + return true; + } + + return false; +#else /* !CONFIG_CPU */ +#ifdef CONFIG_RISCV_MMODE return csr_read(misa) & (1 << (ext - 'a')); +#else /* !CONFIG_RISCV_MMODE */ +#warning "There is no way to determine the available extensions in S-mode." +#warning "Please convert your board to use the RISC-V CPU driver." + return false; +#endif /* CONFIG_RISCV_MMODE */ +#endif /* CONFIG_CPU */ +} + +static int riscv_cpu_probe(void) +{ +#ifdef CONFIG_CPU + 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); +#endif + + return 0; } -int print_cpuinfo(void) +int arch_cpu_init_dm(void) { - char name[32]; - char *s = name; - int bit; + int ret; + + ret = riscv_cpu_probe(); + if (ret) + return ret; - s += sprintf(name, "rv"); - bit = csr_read(misa) >> (sizeof(long) * 8 - 2); - s += sprintf(s, isa_bits[bit]); + /* Enable FPU */ + if (supports_extension('d') || supports_extension('f')) { + csr_set(MODE_PREFIX(status), MSTATUS_FS); + csr_write(fcsr, 0); + } - 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'; + if (CONFIG_IS_ENABLED(RISCV_MMODE)) { + /* + * Enable perf counters for cycle, time, + * and instret counters only + */ + csr_write(mcounteren, GENMASK(2, 0)); - printf("CPU: %s\n", name); + /* Disable paging */ + if (supports_extension('s')) + csr_write(satp, 0); + } return 0; } + +int arch_early_init_r(void) +{ + return riscv_cpu_probe(); +} diff --git a/arch/riscv/cpu/mtrap.S b/arch/riscv/cpu/mtrap.S new file mode 100644 index 0000000000..407ecfa9c0 --- /dev/null +++ b/arch/riscv/cpu/mtrap.S @@ -0,0 +1,103 @@ +/* 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 + + LREG x1, 1 * 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) + LREG x2, 2 * REGBYTES(sp) + addi sp, sp, 32 * REGBYTES + MODE_PREFIX(ret) diff --git a/arch/riscv/cpu/qemu/Kconfig b/arch/riscv/cpu/qemu/Kconfig new file mode 100644 index 0000000000..f48751e6de --- /dev/null +++ b/arch/riscv/cpu/qemu/Kconfig @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com> + +config QEMU_RISCV + bool + select ARCH_EARLY_INIT_R + imply CPU + imply CPU_RISCV + imply RISCV_TIMER + imply SIFIVE_CLINT if RISCV_MMODE + imply CMD_CPU diff --git a/arch/riscv/cpu/qemu/cpu.c b/arch/riscv/cpu/qemu/cpu.c index 25d97d0b41..ad2950ce40 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, +}; diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S index 64246a4e09..81ea52b170 100644 --- a/arch/riscv/cpu/start.S +++ b/arch/riscv/cpu/start.S @@ -14,6 +14,7 @@ #include <common.h> #include <elf.h> #include <asm/encoding.h> +#include <generated/asm-offsets.h> #ifdef CONFIG_32BIT #define LREG lw @@ -70,6 +71,9 @@ call_board_init_f_0: jal board_init_f_init_reserve + /* save the boot hart id to global_data */ + SREG s0, GD_BOOT_HART(gp) + mv a0, zero /* a0 <-- boot_flags = 0 */ la t5, board_init_f jr t5 /* jump to board_init_f() */ @@ -198,92 +202,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) diff --git a/arch/riscv/dts/ae350.dts b/arch/riscv/dts/ae350.dts deleted file mode 100644 index e48c298645..0000000000 --- a/arch/riscv/dts/ae350.dts +++ /dev/null @@ -1,229 +0,0 @@ -/dts-v1/; - -/ { - #address-cells = <2>; - #size-cells = <2>; - compatible = "andestech,ax25"; - model = "andestech,ax25"; - - aliases { - uart0 = &serial0; - spi0 = &spi; - }; - - chosen { - bootargs = "console=ttyS0,38400n8 debug loglevel=7"; - stdout-path = "uart0:38400n8"; - }; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - timebase-frequency = <60000000>; - CPU0: cpu@0 { - device_type = "cpu"; - reg = <0>; - status = "okay"; - compatible = "riscv"; - riscv,isa = "rv64imafdc"; - mmu-type = "riscv,sv39"; - clock-frequency = <60000000>; - d-cache-size = <0x8000>; - d-cache-line-size = <32>; - CPU0_intc: interrupt-controller { - #interrupt-cells = <1>; - interrupt-controller; - compatible = "riscv,cpu-intc"; - }; - }; - }; - - memory@0 { - device_type = "memory"; - reg = <0x0 0x00000000 0x0 0x40000000>; - }; - - soc { - #address-cells = <2>; - #size-cells = <2>; - compatible = "andestech,riscv-ae350-soc"; - ranges; - - plic0: interrupt-controller@e4000000 { - compatible = "riscv,plic0"; - #address-cells = <2>; - #interrupt-cells = <2>; - interrupt-controller; - reg = <0x0 0xe4000000 0x0 0x2000000>; - riscv,ndev=<71>; - interrupts-extended = <&CPU0_intc 11 &CPU0_intc 9>; - }; - - plic1: interrupt-controller@e6400000 { - compatible = "riscv,plic1"; - #address-cells = <2>; - #interrupt-cells = <2>; - interrupt-controller; - reg = <0x0 0xe6400000 0x0 0x400000>; - riscv,ndev=<1>; - interrupts-extended = <&CPU0_intc 3>; - }; - - plmt0@e6000000 { - compatible = "riscv,plmt0"; - interrupts-extended = <&CPU0_intc 7>; - reg = <0x0 0xe6000000 0x0 0x100000>; - }; - }; - - spiclk: virt_100mhz { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <100000000>; - }; - - timer0: timer@f0400000 { - compatible = "andestech,atcpit100"; - reg = <0x0 0xf0400000 0x0 0x1000>; - clock-frequency = <60000000>; - interrupts = <3 4>; - interrupt-parent = <&plic0>; - }; - - serial0: serial@f0300000 { - compatible = "andestech,uart16550", "ns16550a"; - reg = <0x0 0xf0300000 0x0 0x1000>; - interrupts = <9 4>; - clock-frequency = <19660800>; - reg-shift = <2>; - reg-offset = <32>; - no-loopback-test = <1>; - interrupt-parent = <&plic0>; - }; - - mac0: mac@e0100000 { - compatible = "andestech,atmac100"; - reg = <0x0 0xe0100000 0x0 0x1000>; - interrupts = <19 4>; - interrupt-parent = <&plic0>; - }; - - mmc0: mmc@f0e00000 { - compatible = "andestech,atfsdc010"; - max-frequency = <100000000>; - clock-freq-min-max = <400000 100000000>; - fifo-depth = <0x10>; - reg = <0x0 0xf0e00000 0x0 0x1000>; - interrupts = <18 4>; - cap-sd-highspeed; - interrupt-parent = <&plic0>; - }; - - dma0: dma@f0c00000 { - compatible = "andestech,atcdmac300"; - reg = <0x0 0xf0c00000 0x0 0x1000>; - interrupts = <10 4 64 4 65 4 66 4 67 4 68 4 69 4 70 4 71 4>; - dma-channels = <8>; - interrupt-parent = <&plic0>; - }; - - lcd0: lcd@e0200000 { - compatible = "andestech,atflcdc100"; - reg = <0x0 0xe0200000 0x0 0x1000>; - interrupts = <20 4>; - interrupt-parent = <&plic0>; - }; - - smc0: smc@e0400000 { - compatible = "andestech,atfsmc020"; - reg = <0x0 0xe0400000 0x0 0x1000>; - }; - - snd0: snd@f0d00000 { - compatible = "andestech,atfac97"; - reg = <0x0 0xf0d00000 0x0 0x1000>; - interrupts = <17 4>; - interrupt-parent = <&plic0>; - }; - - virtio_mmio@fe007000 { - interrupts = <0x17 0x4>; - interrupt-parent = <0x2>; - reg = <0x0 0xfe007000 0x0 0x1000>; - compatible = "virtio,mmio"; - }; - - virtio_mmio@fe006000 { - interrupts = <0x16 0x4>; - interrupt-parent = <0x2>; - reg = <0x0 0xfe006000 0x0 0x1000>; - compatible = "virtio,mmio"; - }; - - virtio_mmio@fe005000 { - interrupts = <0x15 0x4>; - interrupt-parent = <0x2>; - reg = <0x0 0xfe005000 0x0 0x1000>; - compatible = "virtio,mmio"; - }; - - virtio_mmio@fe004000 { - interrupts = <0x14 0x4>; - interrupt-parent = <0x2>; - reg = <0x0 0xfe004000 0x0 0x1000>; - compatible = "virtio,mmio"; - }; - - virtio_mmio@fe003000 { - interrupts = <0x13 0x4>; - interrupt-parent = <0x2>; - reg = <0x0 0xfe003000 0x0 0x1000>; - compatible = "virtio,mmio"; - }; - - virtio_mmio@fe002000 { - interrupts = <0x12 0x4>; - interrupt-parent = <0x2>; - reg = <0x0 0xfe002000 0x0 0x1000>; - compatible = "virtio,mmio"; - }; - - virtio_mmio@fe001000 { - interrupts = <0x11 0x4>; - interrupt-parent = <0x2>; - reg = <0x0 0xfe001000 0x0 0x1000>; - compatible = "virtio,mmio"; - }; - - virtio_mmio@fe000000 { - interrupts = <0x10 0x4>; - interrupt-parent = <0x2>; - reg = <0x0 0xfe000000 0x0 0x1000>; - compatible = "virtio,mmio"; - }; - - nor@0,0 { - compatible = "cfi-flash"; - reg = <0x0 0x88000000 0x0 0x1000>; - bank-width = <2>; - device-width = <1>; - }; - - spi: spi@f0b00000 { - compatible = "andestech,atcspi200"; - reg = <0x0 0xf0b00000 0x0 0x1000>; - #address-cells = <1>; - #size-cells = <0>; - num-cs = <1>; - clocks = <&spiclk>; - interrupts = <4 4>; - interrupt-parent = <&plic0>; - flash@0 { - compatible = "spi-flash"; - spi-max-frequency = <50000000>; - reg = <0>; - spi-cpol; - spi-cpha; - }; - }; -}; diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h index 29624fdbb5..86136f542c 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"); \ }) diff --git a/arch/riscv/include/asm/encoding.h b/arch/riscv/include/asm/encoding.h index 97cf906aa6..772668c74e 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 @@ -152,6 +167,227 @@ #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_SEDELEG 0x102 +#define CSR_SIDELEG 0x103 +#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 */ diff --git a/arch/riscv/include/asm/global_data.h b/arch/riscv/include/asm/global_data.h index 4d5d623725..a3a342c6e1 100644 --- a/arch/riscv/include/asm/global_data.h +++ b/arch/riscv/include/asm/global_data.h @@ -12,6 +12,10 @@ /* Architecture-specific global data */ struct arch_global_data { + long boot_hart; /* boot hart id */ +#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 0000000000..d311ee6b45 --- /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 b58db89752..edfa61690c 100644 --- a/arch/riscv/lib/Makefile +++ b/arch/riscv/lib/Makefile @@ -9,6 +9,8 @@ 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 obj-y += setjmp.o diff --git a/arch/riscv/lib/asm-offsets.c b/arch/riscv/lib/asm-offsets.c new file mode 100644 index 0000000000..e0b71f5691 --- /dev/null +++ b/arch/riscv/lib/asm-offsets.c @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com> + * + * From arch/x86/lib/asm-offsets.c + * + * This program is used to generate definitions needed by + * assembly language modules. + */ + +#include <common.h> +#include <linux/kbuild.h> + +int main(void) +{ + DEFINE(GD_BOOT_HART, offsetof(gd_t, arch.boot_hart)); + + return 0; +} diff --git a/arch/riscv/lib/bootm.c b/arch/riscv/lib/bootm.c index 124aeefff8..60b32cca81 100644 --- a/arch/riscv/lib/bootm.c +++ b/arch/riscv/lib/bootm.c @@ -93,7 +93,7 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) if (!fake) { if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) - kernel(csr_read(mhartid), images->ft_addr); + kernel(gd->arch.boot_hart, images->ft_addr); } } diff --git a/arch/riscv/lib/interrupts.c b/arch/riscv/lib/interrupts.c index 3aff006977..e185933b01 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(); -} diff --git a/arch/riscv/lib/rdtime.c b/arch/riscv/lib/rdtime.c new file mode 100644 index 0000000000..e128d7fce6 --- /dev/null +++ b/arch/riscv/lib/rdtime.c @@ -0,0 +1,38 @@ +// 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 */ +int riscv_get_time(u64 *time) +{ +#ifdef CONFIG_64BIT + u64 n; + + __asm__ __volatile__ ( + "rdtime %0" + : "=r" (n)); + + *time = 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)); + + *time = ((u64)hi << 32) | lo; +#endif + + return 0; +} diff --git a/arch/riscv/lib/sifive_clint.c b/arch/riscv/lib/sifive_clint.c new file mode 100644 index 0000000000..d24e0d585b --- /dev/null +++ b/arch/riscv/lib/sifive_clint.c @@ -0,0 +1,84 @@ +// 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; + +#define CLINT_BASE_GET(void) \ + do { \ + long *ret; \ + \ + if (!gd->arch.clint) { \ + ret = syscon_get_first_range(RISCV_SYSCON_CLINT); \ + if (IS_ERR(ret)) \ + return PTR_ERR(ret); \ + gd->arch.clint = ret; \ + } \ + } while (0) + +int riscv_get_time(u64 *time) +{ + CLINT_BASE_GET(); + + *time = readq((void __iomem *)MTIME_REG(gd->arch.clint)); + + return 0; +} + +int riscv_set_timecmp(int hart, u64 cmp) +{ + CLINT_BASE_GET(); + + writeq(cmp, (void __iomem *)MTIMECMP_REG(gd->arch.clint, hart)); + + return 0; +} + +int riscv_send_ipi(int hart) +{ + CLINT_BASE_GET(); + + writel(1, (void __iomem *)MSIP_REG(gd->arch.clint, hart)); + + return 0; +} + +int riscv_clear_ipi(int hart) +{ + CLINT_BASE_GET(); + + writel(0, (void __iomem *)MSIP_REG(gd->arch.clint, hart)); + + return 0; +} + +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, +}; |