From 2fc7774edf917ad8e0e42f655542b05f62aa50c8 Mon Sep 17 00:00:00 2001 From: David Abdurachmanov Date: Sun, 5 May 2019 15:32:55 +0300 Subject: [PATCH] Update to 2019.07 RC1 Signed-off-by: David Abdurachmanov --- uboot-riscv-apr8-smp.patch | 1863 ------------------------------------ uboot-tools.spec | 11 +- 2 files changed, 6 insertions(+), 1868 deletions(-) delete mode 100644 uboot-riscv-apr8-smp.patch diff --git a/uboot-riscv-apr8-smp.patch b/uboot-riscv-apr8-smp.patch deleted file mode 100644 index e95c585..0000000 --- a/uboot-riscv-apr8-smp.patch +++ /dev/null @@ -1,1863 +0,0 @@ -From fa33f08fd657b8568ede929df8a79bd113e9c5b1 Mon Sep 17 00:00:00 2001 -From: Lukas Auer -Date: Sun, 17 Mar 2019 19:28:32 +0100 -Subject: [PATCH 01/18] riscv: add infrastructure for calling functions on - other harts - -Harts on RISC-V boot independently, U-Boot is responsible for managing -them. Functions are called on other harts with smp_call_function(), -which sends inter-processor interrupts (IPIs) to all other available -harts. Available harts are those marked as available in the device tree -and present in the available_harts mask stored in global data. The -available_harts mask is used to register all harts that have entered -U-Boot. Functions are specified with their address and two function -arguments (argument 2 and 3). The first function argument is always the -hart ID of the hart calling the function. On the other harts, the IPI -interrupt handler handle_ipi() must be called on software interrupts to -handle the request and call the specified function. - -Functions are stored in the ipi_data data structure. Every hart has its -own data structure in global data. While this is not required at the -moment (all harts are expected to boot Linux), this does allow future -expansion, where other harts may be used for monitoring or other tasks. - -Signed-off-by: Lukas Auer -Reviewed-by: Anup Patel -Reviewed-by: Bin Meng -Tested-by: Bin Meng ---- - arch/riscv/Kconfig | 19 +++++ - arch/riscv/include/asm/global_data.h | 6 ++ - arch/riscv/include/asm/smp.h | 53 ++++++++++++ - arch/riscv/lib/Makefile | 1 + - arch/riscv/lib/smp.c | 118 +++++++++++++++++++++++++++ - 5 files changed, 197 insertions(+) - create mode 100644 arch/riscv/include/asm/smp.h - create mode 100644 arch/riscv/lib/smp.c - -diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig -index 36512a8995..4d7a115569 100644 ---- a/arch/riscv/Kconfig -+++ b/arch/riscv/Kconfig -@@ -120,4 +120,23 @@ config RISCV_RDTIME - config SYS_MALLOC_F_LEN - default 0x1000 - -+config SMP -+ bool "Symmetric Multi-Processing" -+ help -+ This enables support for systems with more than one CPU. If -+ you say N here, U-Boot will run on single and multiprocessor -+ machines, but will use only one CPU of a multiprocessor -+ machine. If you say Y here, U-Boot will run on many, but not -+ all, single processor machines. -+ -+config NR_CPUS -+ int "Maximum number of CPUs (2-32)" -+ range 2 32 -+ depends on SMP -+ default 8 -+ help -+ On multiprocessor machines, U-Boot sets up a stack for each CPU. -+ Stack memory is pre-allocated. U-Boot must therefore know the -+ maximum number of CPUs that may be present. -+ - endmenu -diff --git a/arch/riscv/include/asm/global_data.h b/arch/riscv/include/asm/global_data.h -index a3a342c6e1..80e3165e39 100644 ---- a/arch/riscv/include/asm/global_data.h -+++ b/arch/riscv/include/asm/global_data.h -@@ -10,12 +10,18 @@ - #ifndef __ASM_GBL_DATA_H - #define __ASM_GBL_DATA_H - -+#include -+ - /* 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 -+#ifdef CONFIG_SMP -+ struct ipi_data ipi[CONFIG_NR_CPUS]; -+#endif -+ ulong available_harts; - }; - - #include -diff --git a/arch/riscv/include/asm/smp.h b/arch/riscv/include/asm/smp.h -new file mode 100644 -index 0000000000..bc863fdbaf ---- /dev/null -+++ b/arch/riscv/include/asm/smp.h -@@ -0,0 +1,53 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2019 Fraunhofer AISEC, -+ * Lukas Auer -+ */ -+ -+#ifndef _ASM_RISCV_SMP_H -+#define _ASM_RISCV_SMP_H -+ -+/** -+ * struct ipi_data - Inter-processor interrupt (IPI) data structure -+ * -+ * IPIs are used for SMP support to communicate to other harts what function to -+ * call. Functions are in the form -+ * void (*addr)(ulong hart, ulong arg0, ulong arg1). -+ * -+ * The function address and the two arguments, arg0 and arg1, are stored in the -+ * IPI data structure. The hart ID is inserted by the hart handling the IPI and -+ * calling the function. -+ * -+ * @addr: Address of function -+ * @arg0: First argument of function -+ * @arg1: Second argument of function -+ */ -+struct ipi_data { -+ ulong addr; -+ ulong arg0; -+ ulong arg1; -+}; -+ -+/** -+ * handle_ipi() - interrupt handler for software interrupts -+ * -+ * The IPI interrupt handler must be called to handle software interrupts. It -+ * calls the function specified in the hart's IPI data structure. -+ * -+ * @hart: Hart ID of the current hart -+ */ -+void handle_ipi(ulong hart); -+ -+/** -+ * smp_call_function() - Call a function on all other harts -+ * -+ * Send IPIs with the specified function call to all harts. -+ * -+ * @addr: Address of function -+ * @arg0: First argument of function -+ * @arg1: Second argument of function -+ * @return 0 if OK, -ve on error -+ */ -+int smp_call_function(ulong addr, ulong arg0, ulong arg1); -+ -+#endif -diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile -index edfa61690c..19370f9749 100644 ---- a/arch/riscv/lib/Makefile -+++ b/arch/riscv/lib/Makefile -@@ -14,6 +14,7 @@ obj-$(CONFIG_SIFIVE_CLINT) += sifive_clint.o - obj-y += interrupts.o - obj-y += reset.o - obj-y += setjmp.o -+obj-$(CONFIG_SMP) += smp.o - - # For building EFI apps - CFLAGS_$(EFI_CRT0) := $(CFLAGS_EFI) -diff --git a/arch/riscv/lib/smp.c b/arch/riscv/lib/smp.c -new file mode 100644 -index 0000000000..caa292ccd2 ---- /dev/null -+++ b/arch/riscv/lib/smp.c -@@ -0,0 +1,118 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * Copyright (C) 2019 Fraunhofer AISEC, -+ * Lukas Auer -+ */ -+ -+#include -+#include -+#include -+#include -+ -+DECLARE_GLOBAL_DATA_PTR; -+ -+/** -+ * riscv_send_ipi() - Send inter-processor interrupt (IPI) -+ * -+ * Platform code must provide this function. -+ * -+ * @hart: Hart ID of receiving hart -+ * @return 0 if OK, -ve on error -+ */ -+extern int riscv_send_ipi(int hart); -+ -+/** -+ * riscv_clear_ipi() - Clear inter-processor interrupt (IPI) -+ * -+ * Platform code must provide this function. -+ * -+ * @hart: Hart ID of hart to be cleared -+ * @return 0 if OK, -ve on error -+ */ -+extern int riscv_clear_ipi(int hart); -+ -+static int send_ipi_many(struct ipi_data *ipi) -+{ -+ ofnode node, cpus; -+ u32 reg; -+ int ret; -+ -+ cpus = ofnode_path("/cpus"); -+ if (!ofnode_valid(cpus)) { -+ pr_err("Can't find cpus node!\n"); -+ return -EINVAL; -+ } -+ -+ ofnode_for_each_subnode(node, cpus) { -+ /* skip if hart is marked as not available in the device tree */ -+ if (!ofnode_is_available(node)) -+ continue; -+ -+ /* read hart ID of CPU */ -+ ret = ofnode_read_u32(node, "reg", ®); -+ if (ret) -+ continue; -+ -+ /* skip if it is the hart we are running on */ -+ if (reg == gd->arch.boot_hart) -+ continue; -+ -+ if (reg >= CONFIG_NR_CPUS) { -+ pr_err("Hart ID %d is out of range, increase CONFIG_NR_CPUS\n", -+ reg); -+ continue; -+ } -+ -+ /* skip if hart is not available */ -+ if (!(gd->arch.available_harts & (1 << reg))) -+ continue; -+ -+ gd->arch.ipi[reg].addr = ipi->addr; -+ gd->arch.ipi[reg].arg0 = ipi->arg0; -+ gd->arch.ipi[reg].arg1 = ipi->arg1; -+ -+ ret = riscv_send_ipi(reg); -+ if (ret) { -+ pr_err("Cannot send IPI to hart %d\n", reg); -+ return ret; -+ } -+ } -+ -+ return 0; -+} -+ -+void handle_ipi(ulong hart) -+{ -+ int ret; -+ void (*smp_function)(ulong hart, ulong arg0, ulong arg1); -+ -+ if (hart >= CONFIG_NR_CPUS) -+ return; -+ -+ ret = riscv_clear_ipi(hart); -+ if (ret) { -+ pr_err("Cannot clear IPI of hart %ld\n", hart); -+ return; -+ } -+ -+ __smp_mb(); -+ -+ smp_function = (void (*)(ulong, ulong, ulong))gd->arch.ipi[hart].addr; -+ invalidate_icache_all(); -+ -+ smp_function(hart, gd->arch.ipi[hart].arg0, gd->arch.ipi[hart].arg1); -+} -+ -+int smp_call_function(ulong addr, ulong arg0, ulong arg1) -+{ -+ int ret = 0; -+ struct ipi_data ipi; -+ -+ ipi.addr = addr; -+ ipi.arg0 = arg0; -+ ipi.arg1 = arg1; -+ -+ ret = send_ipi_many(&ipi); -+ -+ return ret; -+} --- -2.20.1 - - -From 34a0626fc344f51cd768efecdd52628b677fb9a8 Mon Sep 17 00:00:00 2001 -From: Lukas Auer -Date: Sun, 17 Mar 2019 19:28:33 +0100 -Subject: [PATCH 02/18] riscv: import the supervisor binary interface header - file - -Import the supervisor binary interface (SBI) header file from Linux -(arch/riscv/include/asm/sbi.h). The last change to it was in commit -6d60b6ee0c97 ("RISC-V: Device, timer, IRQs, and the SBI"). - -Signed-off-by: Lukas Auer -Reviewed-by: Anup Patel -Reviewed-by: Bin Meng -Reviewed-by: Atish Patra ---- - arch/riscv/include/asm/sbi.h | 94 ++++++++++++++++++++++++++++++++++++ - 1 file changed, 94 insertions(+) - create mode 100644 arch/riscv/include/asm/sbi.h - -diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h -new file mode 100644 -index 0000000000..ced57defdd ---- /dev/null -+++ b/arch/riscv/include/asm/sbi.h -@@ -0,0 +1,94 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2015 Regents of the University of California -+ * -+ * Taken from Linux arch/riscv/include/asm/sbi.h -+ */ -+ -+#ifndef _ASM_RISCV_SBI_H -+#define _ASM_RISCV_SBI_H -+ -+#include -+ -+#define SBI_SET_TIMER 0 -+#define SBI_CONSOLE_PUTCHAR 1 -+#define SBI_CONSOLE_GETCHAR 2 -+#define SBI_CLEAR_IPI 3 -+#define SBI_SEND_IPI 4 -+#define SBI_REMOTE_FENCE_I 5 -+#define SBI_REMOTE_SFENCE_VMA 6 -+#define SBI_REMOTE_SFENCE_VMA_ASID 7 -+#define SBI_SHUTDOWN 8 -+ -+#define SBI_CALL(which, arg0, arg1, arg2) ({ \ -+ register uintptr_t a0 asm ("a0") = (uintptr_t)(arg0); \ -+ register uintptr_t a1 asm ("a1") = (uintptr_t)(arg1); \ -+ register uintptr_t a2 asm ("a2") = (uintptr_t)(arg2); \ -+ register uintptr_t a7 asm ("a7") = (uintptr_t)(which); \ -+ asm volatile ("ecall" \ -+ : "+r" (a0) \ -+ : "r" (a1), "r" (a2), "r" (a7) \ -+ : "memory"); \ -+ a0; \ -+}) -+ -+/* Lazy implementations until SBI is finalized */ -+#define SBI_CALL_0(which) SBI_CALL(which, 0, 0, 0) -+#define SBI_CALL_1(which, arg0) SBI_CALL(which, arg0, 0, 0) -+#define SBI_CALL_2(which, arg0, arg1) SBI_CALL(which, arg0, arg1, 0) -+ -+static inline void sbi_console_putchar(int ch) -+{ -+ SBI_CALL_1(SBI_CONSOLE_PUTCHAR, ch); -+} -+ -+static inline int sbi_console_getchar(void) -+{ -+ return SBI_CALL_0(SBI_CONSOLE_GETCHAR); -+} -+ -+static inline void sbi_set_timer(uint64_t stime_value) -+{ -+#if __riscv_xlen == 32 -+ SBI_CALL_2(SBI_SET_TIMER, stime_value, stime_value >> 32); -+#else -+ SBI_CALL_1(SBI_SET_TIMER, stime_value); -+#endif -+} -+ -+static inline void sbi_shutdown(void) -+{ -+ SBI_CALL_0(SBI_SHUTDOWN); -+} -+ -+static inline void sbi_clear_ipi(void) -+{ -+ SBI_CALL_0(SBI_CLEAR_IPI); -+} -+ -+static inline void sbi_send_ipi(const unsigned long *hart_mask) -+{ -+ SBI_CALL_1(SBI_SEND_IPI, hart_mask); -+} -+ -+static inline void sbi_remote_fence_i(const unsigned long *hart_mask) -+{ -+ SBI_CALL_1(SBI_REMOTE_FENCE_I, hart_mask); -+} -+ -+static inline void sbi_remote_sfence_vma(const unsigned long *hart_mask, -+ unsigned long start, -+ unsigned long size) -+{ -+ SBI_CALL_1(SBI_REMOTE_SFENCE_VMA, hart_mask); -+} -+ -+static inline void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask, -+ unsigned long start, -+ unsigned long size, -+ unsigned long asid) -+{ -+ SBI_CALL_1(SBI_REMOTE_SFENCE_VMA_ASID, hart_mask); -+} -+ -+#endif --- -2.20.1 - - -From f152febb2a97696f7c7e6df46bf585cfc962a835 Mon Sep 17 00:00:00 2001 -From: Lukas Auer -Date: Sun, 17 Mar 2019 19:28:34 +0100 -Subject: [PATCH 03/18] riscv: implement IPI platform functions using SBI - -The supervisor binary interface (SBI) provides the necessary functions -to implement the platform IPI functions riscv_send_ipi() and -riscv_clear_ipi(). Use it to implement them. - -This adds support for inter-processor interrupts (IPIs) on RISC-V CPUs -running in supervisor mode. Support for machine mode is already -available for CPUs that include the SiFive CLINT. - -Signed-off-by: Lukas Auer -Reviewed-by: Anup Patel -Reviewed-by: Bin Meng -Reviewed-by: Atish Patra -Tested-by: Bin Meng ---- - arch/riscv/Kconfig | 5 +++++ - arch/riscv/lib/Makefile | 1 + - arch/riscv/lib/sbi_ipi.c | 25 +++++++++++++++++++++++++ - 3 files changed, 31 insertions(+) - create mode 100644 arch/riscv/lib/sbi_ipi.c - -diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig -index 4d7a115569..9da609b33b 100644 ---- a/arch/riscv/Kconfig -+++ b/arch/riscv/Kconfig -@@ -139,4 +139,9 @@ config NR_CPUS - Stack memory is pre-allocated. U-Boot must therefore know the - maximum number of CPUs that may be present. - -+config SBI_IPI -+ bool -+ default y if RISCV_SMODE -+ depends on SMP -+ - endmenu -diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile -index 19370f9749..35dbf643e4 100644 ---- a/arch/riscv/lib/Makefile -+++ b/arch/riscv/lib/Makefile -@@ -13,6 +13,7 @@ obj-$(CONFIG_RISCV_RDTIME) += rdtime.o - obj-$(CONFIG_SIFIVE_CLINT) += sifive_clint.o - obj-y += interrupts.o - obj-y += reset.o -+obj-$(CONFIG_SBI_IPI) += sbi_ipi.o - obj-y += setjmp.o - obj-$(CONFIG_SMP) += smp.o - -diff --git a/arch/riscv/lib/sbi_ipi.c b/arch/riscv/lib/sbi_ipi.c -new file mode 100644 -index 0000000000..170346da68 ---- /dev/null -+++ b/arch/riscv/lib/sbi_ipi.c -@@ -0,0 +1,25 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * Copyright (C) 2019 Fraunhofer AISEC, -+ * Lukas Auer -+ */ -+ -+#include -+#include -+ -+int riscv_send_ipi(int hart) -+{ -+ ulong mask; -+ -+ mask = 1UL << hart; -+ sbi_send_ipi(&mask); -+ -+ return 0; -+} -+ -+int riscv_clear_ipi(int hart) -+{ -+ sbi_clear_ipi(); -+ -+ return 0; -+} --- -2.20.1 - - -From 2503ccc55ff2031ae2ff476fb06f666e6d1c7a64 Mon Sep 17 00:00:00 2001 -From: Lukas Auer -Date: Sun, 17 Mar 2019 19:28:35 +0100 -Subject: [PATCH 04/18] riscv: delay initialization of caches and debug UART - -Move the initialization of the caches and the debug UART until after -board_init_f_init_reserve. This is in preparation for SMP support, where -code prior to this point will be executed by all harts. This ensures -that initialization will only be performed once on the main hart running -U-Boot. - -Signed-off-by: Lukas Auer -Reviewed-by: Anup Patel -Reviewed-by: Bin Meng ---- - arch/riscv/cpu/start.S | 16 ++++++++-------- - 1 file changed, 8 insertions(+), 8 deletions(-) - -diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S -index 81ea52b170..a30f6f7194 100644 ---- a/arch/riscv/cpu/start.S -+++ b/arch/riscv/cpu/start.S -@@ -45,10 +45,6 @@ _start: - /* mask all interrupts */ - csrw MODE_PREFIX(ie), zero - -- /* Enable cache */ -- jal icache_enable -- jal dcache_enable -- - /* - * Set stackpointer in internal/ex RAM to call board_init_f - */ -@@ -57,10 +53,6 @@ call_board_init_f: - li t1, CONFIG_SYS_INIT_SP_ADDR - and sp, t1, t0 /* force 16 byte alignment */ - --#ifdef CONFIG_DEBUG_UART -- jal debug_uart_init --#endif -- - call_board_init_f_0: - mv a0, sp - jal board_init_f_alloc_reserve -@@ -74,6 +66,14 @@ call_board_init_f_0: - /* save the boot hart id to global_data */ - SREG s0, GD_BOOT_HART(gp) - -+ /* Enable cache */ -+ jal icache_enable -+ jal dcache_enable -+ -+#ifdef CONFIG_DEBUG_UART -+ jal debug_uart_init -+#endif -+ - mv a0, zero /* a0 <-- boot_flags = 0 */ - la t5, board_init_f - jr t5 /* jump to board_init_f() */ --- -2.20.1 - - -From 1446b26f7652124f0e3e98c348cdbc4fc55eb0cb Mon Sep 17 00:00:00 2001 -From: Lukas Auer -Date: Sun, 17 Mar 2019 19:28:36 +0100 -Subject: [PATCH 05/18] riscv: save hart ID in register tp instead of s0 - -The hart ID passed by the previous boot stage is currently stored in -register s0. If we divert the control flow inside a function, which is -required as part of multi-hart support, the function epilog may not be -called, clobbering register s0. Save the hart ID in the unallocatable -register tp instead to protect the hart ID. - -Signed-off-by: Lukas Auer -Reviewed-by: Bin Meng -Reviewed-by: Rick Chen -Reviewed-by: Anup Patel ---- - arch/riscv/cpu/start.S | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S -index a30f6f7194..bcc0ff696d 100644 ---- a/arch/riscv/cpu/start.S -+++ b/arch/riscv/cpu/start.S -@@ -36,7 +36,7 @@ - .globl _start - _start: - /* save hart id and dtb pointer */ -- mv s0, a0 -+ mv tp, a0 - mv s1, a1 - - la t0, trap_entry -@@ -64,7 +64,7 @@ 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) -+ SREG tp, GD_BOOT_HART(gp) - - /* Enable cache */ - jal icache_enable --- -2.20.1 - - -From 3dea63c8445b25eb3de471410bbafcf54c9f0e9b Mon Sep 17 00:00:00 2001 -From: Lukas Auer -Date: Sun, 17 Mar 2019 19:28:37 +0100 -Subject: [PATCH 06/18] riscv: add support for multi-hart systems - -On RISC-V, all harts boot independently. To be able to run on a -multi-hart system, U-Boot must be extended with the functionality to -manage all harts in the system. All harts entering U-Boot are registered -in the available_harts mask stored in global data. A hart lottery system -as used in the Linux kernel selects the hart U-Boot runs on. All other -harts are halted. U-Boot can delegate functions to them using -smp_call_function(). - -Every hart has a valid pointer to the global data structure and a 8KiB -stack by default. The stack size is set with CONFIG_STACK_SIZE_SHIFT. - -Signed-off-by: Lukas Auer -Reviewed-by: Anup Patel -Reviewed-by: Bin Meng -Tested-by: Bin Meng ---- - arch/riscv/Kconfig | 4 ++ - arch/riscv/cpu/cpu.c | 9 ++- - arch/riscv/cpu/start.S | 134 ++++++++++++++++++++++++++++++++++- - arch/riscv/include/asm/csr.h | 1 + - arch/riscv/lib/asm-offsets.c | 1 + - 5 files changed, 147 insertions(+), 2 deletions(-) - -diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig -index 9da609b33b..3a4470daf3 100644 ---- a/arch/riscv/Kconfig -+++ b/arch/riscv/Kconfig -@@ -144,4 +144,8 @@ config SBI_IPI - default y if RISCV_SMODE - depends on SMP - -+config STACK_SIZE_SHIFT -+ int -+ default 13 -+ - endmenu -diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c -index e662140427..c32de8a4c3 100644 ---- a/arch/riscv/cpu/cpu.c -+++ b/arch/riscv/cpu/cpu.c -@@ -12,10 +12,17 @@ - #include - - /* -- * prior_stage_fdt_address must be stored in the data section since it is used -+ * The variables here must be stored in the data section since they are used - * before the bss section is available. - */ - phys_addr_t prior_stage_fdt_address __attribute__((section(".data"))); -+u32 hart_lottery __attribute__((section(".data"))) = 0; -+ -+/* -+ * The main hart running U-Boot has acquired available_harts_lock until it has -+ * finished initialization of global data. -+ */ -+u32 available_harts_lock = 1; - - static inline bool supports_extension(char ext) - { -diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S -index bcc0ff696d..f55b8cbc37 100644 ---- a/arch/riscv/cpu/start.S -+++ b/arch/riscv/cpu/start.S -@@ -13,6 +13,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -45,6 +46,23 @@ _start: - /* mask all interrupts */ - csrw MODE_PREFIX(ie), zero - -+#ifdef CONFIG_SMP -+ /* check if hart is within range */ -+ /* tp: hart id */ -+ li t0, CONFIG_NR_CPUS -+ bge tp, t0, hart_out_of_bounds_loop -+#endif -+ -+#ifdef CONFIG_SMP -+ /* set xSIE bit to receive IPIs */ -+#ifdef CONFIG_RISCV_MMODE -+ li t0, MIE_MSIE -+#else -+ li t0, SIE_SSIE -+#endif -+ csrs MODE_PREFIX(ie), t0 -+#endif -+ - /* - * Set stackpointer in internal/ex RAM to call board_init_f - */ -@@ -56,7 +74,30 @@ call_board_init_f: - call_board_init_f_0: - mv a0, sp - jal board_init_f_alloc_reserve -+ -+ /* -+ * Set global data pointer here for all harts, uninitialized at this -+ * point. -+ */ -+ mv gp, a0 -+ -+ /* setup stack */ -+#ifdef CONFIG_SMP -+ /* tp: hart id */ -+ slli t0, tp, CONFIG_STACK_SIZE_SHIFT -+ sub sp, a0, t0 -+#else - mv sp, a0 -+#endif -+ -+ /* -+ * Pick hart to initialize global data and run U-Boot. The other harts -+ * wait for initialization to complete. -+ */ -+ la t0, hart_lottery -+ li s2, 1 -+ amoswap.w s2, t1, 0(t0) -+ bnez s2, wait_for_gd_init - - la t0, prior_stage_fdt_address - SREG s1, 0(t0) -@@ -66,6 +107,33 @@ call_board_init_f_0: - /* save the boot hart id to global_data */ - SREG tp, GD_BOOT_HART(gp) - -+ la t0, available_harts_lock -+ fence rw, w -+ amoswap.w zero, zero, 0(t0) -+ -+wait_for_gd_init: -+ la t0, available_harts_lock -+ li t1, 1 -+1: amoswap.w t1, t1, 0(t0) -+ fence r, rw -+ bnez t1, 1b -+ -+ /* register available harts in the available_harts mask */ -+ li t1, 1 -+ sll t1, t1, tp -+ LREG t2, GD_AVAILABLE_HARTS(gp) -+ or t2, t2, t1 -+ SREG t2, GD_AVAILABLE_HARTS(gp) -+ -+ fence rw, w -+ amoswap.w zero, zero, 0(t0) -+ -+ /* -+ * Continue on hart lottery winner, others branch to -+ * secondary_hart_loop. -+ */ -+ bnez s2, secondary_hart_loop -+ - /* Enable cache */ - jal icache_enable - jal dcache_enable -@@ -95,7 +163,14 @@ relocate_code: - *Set up the stack - */ - stack_setup: -+#ifdef CONFIG_SMP -+ /* tp: hart id */ -+ slli t0, tp, CONFIG_STACK_SIZE_SHIFT -+ sub sp, s2, t0 -+#else - mv sp, s2 -+#endif -+ - la t0, _start - sub t6, s4, t0 /* t6 <- relocation offset */ - beq t0, s4, clear_bss /* skip relocation */ -@@ -175,13 +250,30 @@ clear_bss: - add t0, t0, t6 /* t0 <- rel __bss_start in RAM */ - la t1, __bss_end /* t1 <- rel __bss_end in FLASH */ - add t1, t1, t6 /* t1 <- rel __bss_end in RAM */ -- beq t0, t1, call_board_init_r -+ beq t0, t1, relocate_secondary_harts - - clbss_l: - SREG zero, 0(t0) /* clear loop... */ - addi t0, t0, REGBYTES - bne t0, t1, clbss_l - -+relocate_secondary_harts: -+#ifdef CONFIG_SMP -+ /* send relocation IPI */ -+ la t0, secondary_hart_relocate -+ add a0, t0, t6 -+ -+ /* store relocation offset */ -+ mv s5, t6 -+ -+ mv a1, s2 -+ mv a2, s3 -+ jal smp_call_function -+ -+ /* restore relocation offset */ -+ mv t6, s5 -+#endif -+ - /* - * We are done. Do not return, instead branch to second part of board - * initialization, now running from RAM. -@@ -202,3 +294,43 @@ call_board_init_r: - * jump to it ... - */ - jr t4 /* jump to board_init_r() */ -+ -+#ifdef CONFIG_SMP -+hart_out_of_bounds_loop: -+ /* Harts in this loop are out of bounds, increase CONFIG_NR_CPUS. */ -+ wfi -+ j hart_out_of_bounds_loop -+#endif -+ -+#ifdef CONFIG_SMP -+/* SMP relocation entry */ -+secondary_hart_relocate: -+ /* a1: new sp */ -+ /* a2: new gd */ -+ /* tp: hart id */ -+ -+ /* setup stack */ -+ slli t0, tp, CONFIG_STACK_SIZE_SHIFT -+ sub sp, a1, t0 -+ -+ /* update global data pointer */ -+ mv gp, a2 -+#endif -+ -+secondary_hart_loop: -+ wfi -+ -+#ifdef CONFIG_SMP -+ csrr t0, MODE_PREFIX(ip) -+#ifdef CONFIG_RISCV_MMODE -+ andi t0, t0, MIE_MSIE -+#else -+ andi t0, t0, SIE_SSIE -+#endif -+ beqz t0, secondary_hart_loop -+ -+ mv a0, tp -+ jal handle_ipi -+#endif -+ -+ j secondary_hart_loop -diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h -index 86136f542c..644e6baa15 100644 ---- a/arch/riscv/include/asm/csr.h -+++ b/arch/riscv/include/asm/csr.h -@@ -46,6 +46,7 @@ - #endif - - /* Interrupt Enable and Interrupt Pending flags */ -+#define MIE_MSIE _AC(0x00000008, UL) /* Software Interrupt Enable */ - #define SIE_SSIE _AC(0x00000002, UL) /* Software Interrupt Enable */ - #define SIE_STIE _AC(0x00000020, UL) /* Timer Interrupt Enable */ - -diff --git a/arch/riscv/lib/asm-offsets.c b/arch/riscv/lib/asm-offsets.c -index e0b71f5691..f998402bd1 100644 ---- a/arch/riscv/lib/asm-offsets.c -+++ b/arch/riscv/lib/asm-offsets.c -@@ -14,6 +14,7 @@ - int main(void) - { - DEFINE(GD_BOOT_HART, offsetof(gd_t, arch.boot_hart)); -+ DEFINE(GD_AVAILABLE_HARTS, offsetof(gd_t, arch.available_harts)); - - return 0; - } --- -2.20.1 - - -From f28ad250e6ef95ca58490b4e8651749d4f7e5c06 Mon Sep 17 00:00:00 2001 -From: Lukas Auer -Date: Sun, 17 Mar 2019 19:28:38 +0100 -Subject: [PATCH 07/18] riscv: boot images passed to bootm on all harts - -Signed-off-by: Lukas Auer -Reviewed-by: Anup Patel -Reviewed-by: Bin Meng -Tested-by: Bin Meng ---- - arch/riscv/lib/bootm.c | 13 ++++++++++++- - 1 file changed, 12 insertions(+), 1 deletion(-) - -diff --git a/arch/riscv/lib/bootm.c b/arch/riscv/lib/bootm.c -index f36b8702ef..efbd3e23e7 100644 ---- a/arch/riscv/lib/bootm.c -+++ b/arch/riscv/lib/bootm.c -@@ -13,6 +13,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -81,6 +82,9 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) - { - void (*kernel)(ulong hart, void *dtb); - int fake = (flag & BOOTM_STATE_OS_FAKE_GO); -+#ifdef CONFIG_SMP -+ int ret; -+#endif - - kernel = (void (*)(ulong, void *))images->ep; - -@@ -92,8 +96,15 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) - announce_and_cleanup(fake); - - if (!fake) { -- if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) -+ if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) { -+#ifdef CONFIG_SMP -+ ret = smp_call_function(images->ep, -+ (ulong)images->ft_addr, 0); -+ if (ret) -+ hang(); -+#endif - kernel(gd->arch.boot_hart, images->ft_addr); -+ } - } - } - --- -2.20.1 - - -From e04324025275dee6e3e9a968c8d12e98c9b47567 Mon Sep 17 00:00:00 2001 -From: Lukas Auer -Date: Sun, 17 Mar 2019 19:28:39 +0100 -Subject: [PATCH 08/18] riscv: do not rely on hart ID passed by previous boot - stage - -RISC-V U-Boot expects the hart ID to be passed to it via register a0 by -the previous boot stage. Machine mode firmware such as BBL and OpenSBI -do this when starting their payload (U-Boot) in supervisor mode. If -U-Boot is running in machine mode, this task must be handled by the boot -ROM. Explicitly populate register a0 with the hart ID from the mhartid -CSR to avoid possible problems on RISC-V processors with a boot ROM that -does not handle this task. - -Suggested-by: Rick Chen -Signed-off-by: Lukas Auer -Reviewed-by: Anup Patel -Reviewed-by: Atish Patra -Reviewed-by: Bin Meng -Tested-by: Bin Meng -Reviewed-by: Rick Chen -Tested-by: Rick Chen ---- - arch/riscv/cpu/start.S | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S -index f55b8cbc37..5ac899b141 100644 ---- a/arch/riscv/cpu/start.S -+++ b/arch/riscv/cpu/start.S -@@ -36,6 +36,10 @@ - .section .text - .globl _start - _start: -+#ifdef CONFIG_RISCV_MMODE -+ csrr a0, mhartid -+#endif -+ - /* save hart id and dtb pointer */ - mv tp, a0 - mv s1, a1 --- -2.20.1 - - -From 8ac39e2974d9f1395969a500e692f45717c4ccf2 Mon Sep 17 00:00:00 2001 -From: Lukas Auer -Date: Sun, 17 Mar 2019 19:28:40 +0100 -Subject: [PATCH 09/18] riscv: hang if relocation of secondary harts fails - -Print an error message and hang if smp_call_function() returns an error, -indicating that relocation of the secondary harts has failed. - -Signed-off-by: Lukas Auer -Reviewed-by: Bin Meng -Tested-by: Bin Meng -Reviewed-by: Anup Patel ---- - arch/riscv/cpu/start.S | 13 ++++++++++++- - 1 file changed, 12 insertions(+), 1 deletion(-) - -diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S -index 5ac899b141..a4433fbd6b 100644 ---- a/arch/riscv/cpu/start.S -+++ b/arch/riscv/cpu/start.S -@@ -33,6 +33,10 @@ - #define SYM_SIZE 0x18 - #endif - -+.section .data -+secondary_harts_relocation_error: -+ .ascii "Relocation of secondary harts has failed, error %d\n" -+ - .section .text - .globl _start - _start: -@@ -274,8 +278,15 @@ relocate_secondary_harts: - mv a2, s3 - jal smp_call_function - -+ /* hang if relocation of secondary harts has failed */ -+ beqz a0, 1f -+ mv a1, a0 -+ la a0, secondary_harts_relocation_error -+ jal printf -+ jal hang -+ - /* restore relocation offset */ -- mv t6, s5 -+1: mv t6, s5 - #endif - - /* --- -2.20.1 - - -From 0ed93a8c59d7c100241390d912329e3e45382977 Mon Sep 17 00:00:00 2001 -From: Lukas Auer -Date: Sun, 17 Mar 2019 19:28:41 +0100 -Subject: [PATCH 10/18] riscv: fu540: enable SMP - -Signed-off-by: Lukas Auer -Reviewed-by: Anup Patel -Reviewed-by: Bin Meng ---- - board/sifive/fu540/Kconfig | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/board/sifive/fu540/Kconfig b/board/sifive/fu540/Kconfig -index 6be3d88144..f46437901d 100644 ---- a/board/sifive/fu540/Kconfig -+++ b/board/sifive/fu540/Kconfig -@@ -38,5 +38,6 @@ config BOARD_SPECIFIC_OPTIONS # dummy - imply PHY_LIB - imply PHY_MSCC - imply SIFIVE_SERIAL -+ imply SMP - - endif --- -2.20.1 - - -From d0a8fd3e4d2a5ab19b8f2d27d40dacb4942ba5a4 Mon Sep 17 00:00:00 2001 -From: Lukas Auer -Date: Sun, 17 Mar 2019 19:28:42 +0100 -Subject: [PATCH 11/18] riscv: qemu: enable SMP - -Signed-off-by: Lukas Auer -Reviewed-by: Anup Patel -Reviewed-by: Bin Meng -Tested-by: Bin Meng ---- - board/emulation/qemu-riscv/Kconfig | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/board/emulation/qemu-riscv/Kconfig b/board/emulation/qemu-riscv/Kconfig -index 88d07d568e..cf057e7de6 100644 ---- a/board/emulation/qemu-riscv/Kconfig -+++ b/board/emulation/qemu-riscv/Kconfig -@@ -34,5 +34,6 @@ config BOARD_SPECIFIC_OPTIONS # dummy - imply BOARD_LATE_INIT - imply OF_BOARD_SETUP - imply SIFIVE_SERIAL -+ imply SMP - - endif --- -2.20.1 - - -From 0d389468e2144f3ba3bdbc566c05c0c05dc14fc6 Mon Sep 17 00:00:00 2001 -From: Rick Chen -Date: Tue, 2 Apr 2019 15:56:39 +0800 -Subject: [PATCH 12/18] riscv: Add a SYSCON driver for Andestech's PLIC - -The Platform-Level Interrupt Controller (PLIC) -block holds memory-mapped claim and pending registers -associated with software interrupt. It is required -for handling IPI. - -Signed-off-by: Rick Chen -Cc: Greentime Hu -Reviewed-by: Bin Meng -Reviewed-by: Lukas Auer ---- - arch/riscv/Kconfig | 9 +++ - arch/riscv/include/asm/global_data.h | 3 + - arch/riscv/include/asm/syscon.h | 3 +- - arch/riscv/lib/Makefile | 1 + - arch/riscv/lib/andes_plic.c | 113 +++++++++++++++++++++++++++ - 5 files changed, 127 insertions(+), 2 deletions(-) - create mode 100644 arch/riscv/lib/andes_plic.c - -diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig -index 3a4470daf3..511768befc 100644 ---- a/arch/riscv/Kconfig -+++ b/arch/riscv/Kconfig -@@ -109,6 +109,15 @@ config SIFIVE_CLINT - The SiFive CLINT block holds memory-mapped control and status registers - associated with software and timer interrupts. - -+config ANDES_PLIC -+ bool -+ depends on RISCV_MMODE -+ select REGMAP -+ select SYSCON -+ help -+ The Andes PLIC block holds memory-mapped claim and pending registers -+ associated with software interrupt. -+ - config RISCV_RDTIME - bool - default y if RISCV_SMODE -diff --git a/arch/riscv/include/asm/global_data.h b/arch/riscv/include/asm/global_data.h -index 80e3165e39..b86791094b 100644 ---- a/arch/riscv/include/asm/global_data.h -+++ b/arch/riscv/include/asm/global_data.h -@@ -18,6 +18,9 @@ struct arch_global_data { - #ifdef CONFIG_SIFIVE_CLINT - void __iomem *clint; /* clint base address */ - #endif -+#ifdef CONFIG_ANDES_PLIC -+ void __iomem *plic; /* plic base address */ -+#endif - #ifdef CONFIG_SMP - struct ipi_data ipi[CONFIG_NR_CPUS]; - #endif -diff --git a/arch/riscv/include/asm/syscon.h b/arch/riscv/include/asm/syscon.h -index d311ee6b45..a086208261 100644 ---- a/arch/riscv/include/asm/syscon.h -+++ b/arch/riscv/include/asm/syscon.h -@@ -8,12 +8,11 @@ - - /* - * 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) */ -+ RISCV_SYSCON_PLIC, /* Platform Level Interrupt Controller (PLIC) */ - }; - - #endif /* _ASM_SYSCON_H */ -diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile -index 35dbf643e4..1bf554bad5 100644 ---- a/arch/riscv/lib/Makefile -+++ b/arch/riscv/lib/Makefile -@@ -11,6 +11,7 @@ obj-$(CONFIG_CMD_GO) += boot.o - obj-y += cache.o - obj-$(CONFIG_RISCV_RDTIME) += rdtime.o - obj-$(CONFIG_SIFIVE_CLINT) += sifive_clint.o -+obj-$(CONFIG_ANDES_PLIC) += andes_plic.o - obj-y += interrupts.o - obj-y += reset.o - obj-$(CONFIG_SBI_IPI) += sbi_ipi.o -diff --git a/arch/riscv/lib/andes_plic.c b/arch/riscv/lib/andes_plic.c -new file mode 100644 -index 0000000000..2ffe49ac90 ---- /dev/null -+++ b/arch/riscv/lib/andes_plic.c -@@ -0,0 +1,113 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * Copyright (C) 2019, Rick Chen -+ * -+ * U-Boot syscon driver for Andes's Platform Level Interrupt Controller (PLIC). -+ * The PLIC block holds memory-mapped claim and pending registers -+ * associated with software interrupt. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* pending register */ -+#define PENDING_REG(base, hart) ((ulong)(base) + 0x1000 + (hart) * 8) -+/* enable register */ -+#define ENABLE_REG(base, hart) ((ulong)(base) + 0x2000 + (hart) * 0x80) -+/* claim register */ -+#define CLAIM_REG(base, hart) ((ulong)(base) + 0x200004 + (hart) * 0x1000) -+ -+#define ENABLE_HART_IPI (0x80808080) -+#define SEND_IPI_TO_HART(hart) (0x80 >> (hart)) -+ -+DECLARE_GLOBAL_DATA_PTR; -+static int init_plic(void); -+ -+#define PLIC_BASE_GET(void) \ -+ do { \ -+ long *ret; \ -+ \ -+ if (!gd->arch.plic) { \ -+ ret = syscon_get_first_range(RISCV_SYSCON_PLIC); \ -+ if (IS_ERR(ret)) \ -+ return PTR_ERR(ret); \ -+ gd->arch.plic = ret; \ -+ init_plic(); \ -+ } \ -+ } while (0) -+ -+static int enable_ipi(int harts) -+{ -+ int i; -+ int en = ENABLE_HART_IPI; -+ -+ for (i = 0; i < harts; i++) { -+ en = en >> i; -+ writel(en, (void __iomem *)ENABLE_REG(gd->arch.plic, i)); -+ } -+ -+ return 0; -+} -+ -+static int init_plic(void) -+{ -+ struct udevice *dev; -+ int ret; -+ -+ ret = uclass_find_first_device(UCLASS_CPU, &dev); -+ if (ret) -+ return ret; -+ -+ if (ret == 0 && dev) { -+ ret = cpu_get_count(dev); -+ if (ret < 0) -+ return ret; -+ -+ enable_ipi(ret); -+ return 0; -+ } -+ -+ return -ENODEV; -+} -+ -+int riscv_send_ipi(int hart) -+{ -+ PLIC_BASE_GET(); -+ -+ writel(SEND_IPI_TO_HART(hart), -+ (void __iomem *)PENDING_REG(gd->arch.plic, gd->arch.boot_hart)); -+ -+ return 0; -+} -+ -+int riscv_clear_ipi(int hart) -+{ -+ u32 source_id; -+ -+ PLIC_BASE_GET(); -+ -+ source_id = readl((void __iomem *)CLAIM_REG(gd->arch.plic, hart)); -+ writel(source_id, (void __iomem *)CLAIM_REG(gd->arch.plic, hart)); -+ -+ return 0; -+} -+ -+static const struct udevice_id andes_plic_ids[] = { -+ { .compatible = "riscv,plic1", .data = RISCV_SYSCON_PLIC }, -+ { } -+}; -+ -+U_BOOT_DRIVER(andes_plic) = { -+ .name = "andes_plic", -+ .id = UCLASS_SYSCON, -+ .of_match = andes_plic_ids, -+ .flags = DM_FLAG_PRE_RELOC, -+}; --- -2.20.1 - - -From a1f24875c346a1bf8940b793a27364631d9aabf7 Mon Sep 17 00:00:00 2001 -From: Rick Chen -Date: Tue, 2 Apr 2019 15:56:40 +0800 -Subject: [PATCH 13/18] riscv: Add a SYSCON driver for Andestech's PLMT - -The platform-Level Machine Timer (PLMT) block -holds memory-mapped mtime register associated -with timer tick. - -This driver implements the riscv_get_time() which -is required by the generic RISC-V timer driver. - -Signed-off-by: Rick Chen -Cc: Greentime Hu -Reviewed-by: Bin Meng -Reviewed-by: Lukas Auer ---- - arch/riscv/Kconfig | 9 +++++ - arch/riscv/include/asm/global_data.h | 3 ++ - arch/riscv/include/asm/syscon.h | 1 + - arch/riscv/lib/Makefile | 1 + - arch/riscv/lib/andes_plmt.c | 53 ++++++++++++++++++++++++++++ - 5 files changed, 67 insertions(+) - create mode 100644 arch/riscv/lib/andes_plmt.c - -diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig -index 511768befc..ae8ff7b765 100644 ---- a/arch/riscv/Kconfig -+++ b/arch/riscv/Kconfig -@@ -118,6 +118,15 @@ config ANDES_PLIC - The Andes PLIC block holds memory-mapped claim and pending registers - associated with software interrupt. - -+config ANDES_PLMT -+ bool -+ depends on RISCV_MMODE -+ select REGMAP -+ select SYSCON -+ help -+ The Andes PLMT block holds memory-mapped mtime register -+ associated with timer tick. -+ - config RISCV_RDTIME - bool - default y if RISCV_SMODE -diff --git a/arch/riscv/include/asm/global_data.h b/arch/riscv/include/asm/global_data.h -index b86791094b..dffcd45bf0 100644 ---- a/arch/riscv/include/asm/global_data.h -+++ b/arch/riscv/include/asm/global_data.h -@@ -21,6 +21,9 @@ struct arch_global_data { - #ifdef CONFIG_ANDES_PLIC - void __iomem *plic; /* plic base address */ - #endif -+#ifdef CONFIG_ANDES_PLMT -+ void __iomem *plmt; /* plmt base address */ -+#endif - #ifdef CONFIG_SMP - struct ipi_data ipi[CONFIG_NR_CPUS]; - #endif -diff --git a/arch/riscv/include/asm/syscon.h b/arch/riscv/include/asm/syscon.h -index a086208261..26a008ca59 100644 ---- a/arch/riscv/include/asm/syscon.h -+++ b/arch/riscv/include/asm/syscon.h -@@ -13,6 +13,7 @@ enum { - RISCV_NONE, - RISCV_SYSCON_CLINT, /* Core Local Interruptor (CLINT) */ - RISCV_SYSCON_PLIC, /* Platform Level Interrupt Controller (PLIC) */ -+ RISCV_SYSCON_PLMT, /* Platform Level Machine Timer (PLMT) */ - }; - - #endif /* _ASM_SYSCON_H */ -diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile -index 1bf554bad5..1c332db436 100644 ---- a/arch/riscv/lib/Makefile -+++ b/arch/riscv/lib/Makefile -@@ -12,6 +12,7 @@ obj-y += cache.o - obj-$(CONFIG_RISCV_RDTIME) += rdtime.o - obj-$(CONFIG_SIFIVE_CLINT) += sifive_clint.o - obj-$(CONFIG_ANDES_PLIC) += andes_plic.o -+obj-$(CONFIG_ANDES_PLMT) += andes_plmt.o - obj-y += interrupts.o - obj-y += reset.o - obj-$(CONFIG_SBI_IPI) += sbi_ipi.o -diff --git a/arch/riscv/lib/andes_plmt.c b/arch/riscv/lib/andes_plmt.c -new file mode 100644 -index 0000000000..84f4607500 ---- /dev/null -+++ b/arch/riscv/lib/andes_plmt.c -@@ -0,0 +1,53 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * Copyright (C) 2019, Rick Chen -+ * -+ * U-Boot syscon driver for Andes's Platform Level Machine Timer (PLMT). -+ * The PLMT block holds memory-mapped mtime register -+ * associated with timer tick. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* mtime register */ -+#define MTIME_REG(base) ((ulong)(base)) -+ -+DECLARE_GLOBAL_DATA_PTR; -+ -+#define PLMT_BASE_GET(void) \ -+ do { \ -+ long *ret; \ -+ \ -+ if (!gd->arch.plmt) { \ -+ ret = syscon_get_first_range(RISCV_SYSCON_PLMT); \ -+ if (IS_ERR(ret)) \ -+ return PTR_ERR(ret); \ -+ gd->arch.plmt = ret; \ -+ } \ -+ } while (0) -+ -+int riscv_get_time(u64 *time) -+{ -+ PLMT_BASE_GET(); -+ -+ *time = readq((void __iomem *)MTIME_REG(gd->arch.plmt)); -+ -+ return 0; -+} -+ -+static const struct udevice_id andes_plmt_ids[] = { -+ { .compatible = "riscv,plmt0", .data = RISCV_SYSCON_PLMT }, -+ { } -+}; -+ -+U_BOOT_DRIVER(andes_plmt) = { -+ .name = "andes_plmt", -+ .id = UCLASS_SYSCON, -+ .of_match = andes_plmt_ids, -+ .flags = DM_FLAG_PRE_RELOC, -+}; --- -2.20.1 - - -From 8848474c5e9093ac27f6b7cc8be156629c7d0bad Mon Sep 17 00:00:00 2001 -From: Rick Chen -Date: Tue, 2 Apr 2019 15:56:41 +0800 -Subject: [PATCH 14/18] riscv: ax25: Add platform-specific Kconfig options - -Add ax25 RISC-V platform-specific Kconfig options, -to include CPU and timer drivers. Also disable -ATCPIT100 SoC timer and replace by PLMT. - -Signed-off-by: Rick Chen -Cc: Greentime Hu -Reviewed-by: Bin Meng -Reviewed-by: Lukas Auer ---- - arch/riscv/cpu/ax25/Kconfig | 6 ++++++ - configs/ae350_rv32_defconfig | 1 - - configs/ae350_rv64_defconfig | 1 - - 3 files changed, 6 insertions(+), 2 deletions(-) - -diff --git a/arch/riscv/cpu/ax25/Kconfig b/arch/riscv/cpu/ax25/Kconfig -index e9dbca2fae..68bd4e9419 100644 ---- a/arch/riscv/cpu/ax25/Kconfig -+++ b/arch/riscv/cpu/ax25/Kconfig -@@ -1,5 +1,11 @@ - config RISCV_NDS - bool -+ select ARCH_EARLY_INIT_R -+ imply CPU -+ imply CPU_RISCV -+ imply RISCV_TIMER -+ imply ANDES_PLIC if RISCV_MMODE -+ imply ANDES_PLMT if RISCV_MMODE - help - Run U-Boot on AndeStar V5 platforms and use some specific features - which are provided by Andes Technology AndeStar V5 families. -diff --git a/configs/ae350_rv32_defconfig b/configs/ae350_rv32_defconfig -index 6e0be88d7c..f02945599f 100644 ---- a/configs/ae350_rv32_defconfig -+++ b/configs/ae350_rv32_defconfig -@@ -34,4 +34,3 @@ CONFIG_BAUDRATE=38400 - CONFIG_SYS_NS16550=y - CONFIG_SPI=y - CONFIG_ATCSPI200_SPI=y --CONFIG_ATCPIT100_TIMER=y -diff --git a/configs/ae350_rv64_defconfig b/configs/ae350_rv64_defconfig -index b472a76d17..98635a2ff9 100644 ---- a/configs/ae350_rv64_defconfig -+++ b/configs/ae350_rv64_defconfig -@@ -35,4 +35,3 @@ CONFIG_BAUDRATE=38400 - CONFIG_SYS_NS16550=y - CONFIG_SPI=y - CONFIG_ATCSPI200_SPI=y --CONFIG_ATCPIT100_TIMER=y --- -2.20.1 - - -From dda00ae4ef357233a72c74e6c02d27b70c844422 Mon Sep 17 00:00:00 2001 -From: Rick Chen -Date: Tue, 2 Apr 2019 15:56:42 +0800 -Subject: [PATCH 15/18] riscv: ax25: Andes specific cache shall only support in - M-mode - -Limit the cache configuration only can be supported in M mode. -It can not be manipulated in S mode. - -Signed-off-by: Rick Chen -Cc: Greentime Hu -Reviewed-by: Bin Meng -Reviewed-by: Lukas Auer ---- - arch/riscv/cpu/ax25/Kconfig | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/riscv/cpu/ax25/Kconfig b/arch/riscv/cpu/ax25/Kconfig -index 68bd4e9419..6b4b92e692 100644 ---- a/arch/riscv/cpu/ax25/Kconfig -+++ b/arch/riscv/cpu/ax25/Kconfig -@@ -14,6 +14,7 @@ if RISCV_NDS - - config RISCV_NDS_CACHE - bool "AndeStar V5 families specific cache support" -+ depends on RISCV_MMODE - help - Provide Andes Technology AndeStar V5 families specific cache support. - --- -2.20.1 - - -From a1ce531ab24b1ef5e69dbf29ecbfc6898b454ec1 Mon Sep 17 00:00:00 2001 -From: Rick Chen -Date: Tue, 2 Apr 2019 15:56:43 +0800 -Subject: [PATCH 16/18] riscv: dts: ae350 support SMP - -Signed-off-by: Rick Chen -Cc: Greentime Hu -Reviewed-by: Bin Meng -Reviewed-by: Lukas Auer ---- - arch/riscv/dts/ae350_32.dts | 81 +++++++++++++++++++++++++++---------- - arch/riscv/dts/ae350_64.dts | 81 +++++++++++++++++++++++++++---------- - 2 files changed, 118 insertions(+), 44 deletions(-) - -diff --git a/arch/riscv/dts/ae350_32.dts b/arch/riscv/dts/ae350_32.dts -index 0679827313..2ec01a5ce7 100644 ---- a/arch/riscv/dts/ae350_32.dts -+++ b/arch/riscv/dts/ae350_32.dts -@@ -26,16 +26,49 @@ - status = "okay"; - compatible = "riscv"; - riscv,isa = "rv32imafdc"; -+ riscv,priv-major = <1>; -+ riscv,priv-minor = <10>; - mmu-type = "riscv,sv32"; - clock-frequency = <60000000>; -+ i-cache-size = <0x8000>; -+ i-cache-line-size = <32>; - d-cache-size = <0x8000>; - d-cache-line-size = <32>; -+ next-level-cache = <&L2>; - CPU0_intc: interrupt-controller { - #interrupt-cells = <1>; - interrupt-controller; - compatible = "riscv,cpu-intc"; - }; - }; -+ CPU1: cpu@1 { -+ device_type = "cpu"; -+ reg = <1>; -+ status = "okay"; -+ compatible = "riscv"; -+ riscv,isa = "rv32imafdc"; -+ riscv,priv-major = <1>; -+ riscv,priv-minor = <10>; -+ mmu-type = "riscv,sv32"; -+ clock-frequency = <60000000>; -+ i-cache-size = <0x8000>; -+ i-cache-line-size = <32>; -+ d-cache-size = <0x8000>; -+ d-cache-line-size = <32>; -+ next-level-cache = <&L2>; -+ CPU1_intc: interrupt-controller { -+ #interrupt-cells = <1>; -+ interrupt-controller; -+ compatible = "riscv,cpu-intc"; -+ }; -+ }; -+ -+ L2: l2-cache@e0500000 { -+ compatible = "cache"; -+ cache-level = <2>; -+ cache-size = <0x40000>; -+ reg = <0x0 0xe0500000 0x0 0x40000>; -+ }; - }; - - memory@0 { -@@ -46,32 +79,32 @@ - soc { - #address-cells = <1>; - #size-cells = <1>; -- compatible = "andestech,riscv-ae350-soc"; -+ compatible = "simple-bus"; - ranges; - -- plic0: interrupt-controller@e4000000 { -- compatible = "riscv,plic0"; -- #address-cells = <1>; -- #interrupt-cells = <1>; -- interrupt-controller; -- reg = <0xe4000000 0x2000000>; -- riscv,ndev=<71>; -- interrupts-extended = <&CPU0_intc 11 &CPU0_intc 9>; -- }; -+ plic0: interrupt-controller@e4000000 { -+ compatible = "riscv,plic0"; -+ #address-cells = <1>; -+ #interrupt-cells = <1>; -+ interrupt-controller; -+ reg = <0xe4000000 0x2000000>; -+ riscv,ndev=<71>; -+ interrupts-extended = <&CPU0_intc 11 &CPU0_intc 9 &CPU1_intc 11 &CPU1_intc 9>; -+ }; - -- plic1: interrupt-controller@e6400000 { -- compatible = "riscv,plic1"; -- #address-cells = <1>; -- #interrupt-cells = <1>; -- interrupt-controller; -- reg = <0xe6400000 0x400000>; -- riscv,ndev=<1>; -- interrupts-extended = <&CPU0_intc 3>; -- }; -+ plic1: interrupt-controller@e6400000 { -+ compatible = "riscv,plic1"; -+ #address-cells = <1>; -+ #interrupt-cells = <1>; -+ interrupt-controller; -+ reg = <0xe6400000 0x400000>; -+ riscv,ndev=<2>; -+ interrupts-extended = <&CPU0_intc 3 &CPU1_intc 3>; -+ }; - -- plmt0@e6000000 { -- compatible = "riscv,plmt0"; -- interrupts-extended = <&CPU0_intc 7>; -+ plmt0@e6000000 { -+ compatible = "riscv,plmt0"; -+ interrupts-extended = <&CPU0_intc 7 &CPU1_intc 7>; - reg = <0xe6000000 0x100000>; - }; - }; -@@ -146,6 +179,10 @@ - interrupt-parent = <&plic0>; - }; - -+ pmu { -+ compatible = "riscv,base-pmu"; -+ }; -+ - virtio_mmio@fe007000 { - interrupts = <0x17 0x4>; - interrupt-parent = <0x2>; -diff --git a/arch/riscv/dts/ae350_64.dts b/arch/riscv/dts/ae350_64.dts -index e48c298645..cde5cdeff8 100644 ---- a/arch/riscv/dts/ae350_64.dts -+++ b/arch/riscv/dts/ae350_64.dts -@@ -26,16 +26,49 @@ - status = "okay"; - compatible = "riscv"; - riscv,isa = "rv64imafdc"; -+ riscv,priv-major = <1>; -+ riscv,priv-minor = <10>; - mmu-type = "riscv,sv39"; - clock-frequency = <60000000>; -+ i-cache-size = <0x8000>; -+ i-cache-line-size = <32>; - d-cache-size = <0x8000>; - d-cache-line-size = <32>; -+ next-level-cache = <&L2>; - CPU0_intc: interrupt-controller { - #interrupt-cells = <1>; - interrupt-controller; - compatible = "riscv,cpu-intc"; - }; - }; -+ CPU1: cpu@1 { -+ device_type = "cpu"; -+ reg = <1>; -+ status = "okay"; -+ compatible = "riscv"; -+ riscv,isa = "rv64imafdc"; -+ riscv,priv-major = <1>; -+ riscv,priv-minor = <10>; -+ mmu-type = "riscv,sv39"; -+ clock-frequency = <60000000>; -+ i-cache-size = <0x8000>; -+ i-cache-line-size = <32>; -+ d-cache-size = <0x8000>; -+ d-cache-line-size = <32>; -+ next-level-cache = <&L2>; -+ CPU1_intc: interrupt-controller { -+ #interrupt-cells = <1>; -+ interrupt-controller; -+ compatible = "riscv,cpu-intc"; -+ }; -+ }; -+ -+ L2: l2-cache@e0500000 { -+ compatible = "cache"; -+ cache-level = <2>; -+ cache-size = <0x40000>; -+ reg = <0x0 0xe0500000 0x0 0x40000>; -+ }; - }; - - memory@0 { -@@ -46,32 +79,32 @@ - soc { - #address-cells = <2>; - #size-cells = <2>; -- compatible = "andestech,riscv-ae350-soc"; -+ compatible = "simple-bus"; - 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>; -- }; -+ 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 &CPU1_intc 11 &CPU1_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>; -- }; -+ plic1: interrupt-controller@e6400000 { -+ compatible = "riscv,plic1"; -+ #address-cells = <2>; -+ #interrupt-cells = <2>; -+ interrupt-controller; -+ reg = <0x0 0xe6400000 0x0 0x400000>; -+ riscv,ndev=<2>; -+ interrupts-extended = <&CPU0_intc 3 &CPU1_intc 3>; -+ }; - -- plmt0@e6000000 { -- compatible = "riscv,plmt0"; -- interrupts-extended = <&CPU0_intc 7>; -+ plmt0@e6000000 { -+ compatible = "riscv,plmt0"; -+ interrupts-extended = <&CPU0_intc 7 &CPU1_intc 7>; - reg = <0x0 0xe6000000 0x0 0x100000>; - }; - }; -@@ -146,6 +179,10 @@ - interrupt-parent = <&plic0>; - }; - -+ pmu { -+ compatible = "riscv,base-pmu"; -+ }; -+ - virtio_mmio@fe007000 { - interrupts = <0x17 0x4>; - interrupt-parent = <0x2>; --- -2.20.1 - - -From 076b845893f3bb59dfad80b012d28191c19e2f7b Mon Sep 17 00:00:00 2001 -From: Rick Chen -Date: Tue, 2 Apr 2019 15:56:44 +0800 -Subject: [PATCH 17/18] riscv: ae350: enable SMP - -Signed-off-by: Rick Chen -Cc: Greentime Hu -Reviewed-by: Bin Meng -Reviewed-by: Lukas Auer ---- - board/AndesTech/ax25-ae350/Kconfig | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/board/AndesTech/ax25-ae350/Kconfig b/board/AndesTech/ax25-ae350/Kconfig -index 44cb302f70..5e682b679d 100644 ---- a/board/AndesTech/ax25-ae350/Kconfig -+++ b/board/AndesTech/ax25-ae350/Kconfig -@@ -24,5 +24,6 @@ config ENV_OFFSET - config BOARD_SPECIFIC_OPTIONS # dummy - def_bool y - select RISCV_NDS -+ imply SMP - - endif --- -2.20.1 - - -From 48b90d9db5d32e587901c4f33175488dd20fe0a5 Mon Sep 17 00:00:00 2001 -From: Rick Chen -Date: Wed, 3 Apr 2019 10:43:37 +0800 -Subject: [PATCH 18/18] riscv: dts: fix CONFIG_DEFAULT_DEVICE_TREE failure - -It occurs since commit 27cb7300ffda -("Ensure device tree DTS is compiled"). - -More details can refer to -89c2b5c02049aea746b1edee0b4e1d8519dec2f4 -ARM: fix arch/arm/dts/Makefile - -Signed-off-by: Rick Chen -Cc: Greentime Hu -Reviewed-by: Bin Meng -Reviewed-by: Lukas Auer ---- - arch/riscv/dts/Makefile | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/arch/riscv/dts/Makefile b/arch/riscv/dts/Makefile -index b400defb38..f9cd606a9a 100644 ---- a/arch/riscv/dts/Makefile -+++ b/arch/riscv/dts/Makefile -@@ -1,5 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0+ - -+dtb-$(CONFIG_TARGET_AX25_AE350) += ae350_32.dtb ae350_64.dtb -+ - targets += $(dtb-y) - - DTC_FLAGS += -R 4 -p 0x1000 --- -2.20.1 - diff --git a/uboot-tools.spec b/uboot-tools.spec index 382fa4a..0ee3909 100644 --- a/uboot-tools.spec +++ b/uboot-tools.spec @@ -1,8 +1,8 @@ -#global candidate rc4 +%global candidate rc1 Name: uboot-tools -Version: 2019.04 -Release: 2%{?candidate:.%{candidate}}.0.riscv64%{?dist} +Version: 2019.07 +Release: 0.1%{?candidate:.%{candidate}}.0.riscv64%{?dist} Summary: U-Boot utilities License: GPLv2+ BSD LGPL-2.1+ LGPL-2.0+ URL: http://www.denx.de/wiki/U-Boot @@ -35,8 +35,6 @@ Patch17: arm-tegra-defaine-fdtfile-for-all-devices.patch # RISC-V (riscv64) Patch30: u-boot-2019.04-rc4-riscv.patch -# See: https://lists.denx.de/pipermail/u-boot/2019-April/364281.html -Patch31: uboot-riscv-apr8-smp.patch BuildRequires: bc BuildRequires: dtc @@ -357,6 +355,9 @@ cp -p board/warp7/README builds/docs/README.warp7 %endif %changelog +* Sun May 05 2019 David Abdurachmanov 2019.07-0.1.0.riscv64 +- Update to 2019.07 RC 1 + * Sun May 05 2019 David Abdurachmanov 2019.04-2.0.riscv64 - Apply pull request which incl. SMP support See: https://lists.denx.de/pipermail/u-boot/2019-April/364281.html