From 5988bb9dbf6a22c7a14efa67094ac98ca0c965e8 Mon Sep 17 00:00:00 2001 From: Pragnesh Patel Date: Sat, 14 Mar 2020 19:12:28 +0530 Subject: [PATCH 01/14] riscv: ax25: cache: Remove SPL_RISCV_MMODE config check CONFIG_IS_ENABLED(FOO) will check FOO config option for U-Boot, SPL and TPL, so remove unnecessary CONFIG_IS_ENABLED() Signed-off-by: Pragnesh Patel Reviewed-by: Bin Meng --- arch/riscv/cpu/ax25/cache.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/riscv/cpu/ax25/cache.c b/arch/riscv/cpu/ax25/cache.c index 9f424198b4..9df629d23c 100644 --- a/arch/riscv/cpu/ax25/cache.c +++ b/arch/riscv/cpu/ax25/cache.c @@ -12,7 +12,7 @@ #include #ifdef CONFIG_RISCV_NDS_CACHE -#if CONFIG_IS_ENABLED(RISCV_MMODE) || CONFIG_IS_ENABLED(SPL_RISCV_MMODE) +#if CONFIG_IS_ENABLED(RISCV_MMODE) /* mcctlcommand */ #define CCTL_REG_MCCTLCOMMAND_NUM 0x7cc @@ -47,7 +47,7 @@ void flush_dcache_all(void) { #if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF) #ifdef CONFIG_RISCV_NDS_CACHE -#if CONFIG_IS_ENABLED(RISCV_MMODE) || CONFIG_IS_ENABLED(SPL_RISCV_MMODE) +#if CONFIG_IS_ENABLED(RISCV_MMODE) csr_write(CCTL_REG_MCCTLCOMMAND_NUM, CCTL_L1D_WBINVAL_ALL); #endif #endif @@ -68,7 +68,7 @@ void icache_enable(void) { #if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF) #ifdef CONFIG_RISCV_NDS_CACHE -#if CONFIG_IS_ENABLED(RISCV_MMODE) || CONFIG_IS_ENABLED(SPL_RISCV_MMODE) +#if CONFIG_IS_ENABLED(RISCV_MMODE) asm volatile ( "csrr t1, mcache_ctl\n\t" "ori t0, t1, 0x1\n\t" @@ -83,7 +83,7 @@ void icache_disable(void) { #if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF) #ifdef CONFIG_RISCV_NDS_CACHE -#if CONFIG_IS_ENABLED(RISCV_MMODE) || CONFIG_IS_ENABLED(SPL_RISCV_MMODE) +#if CONFIG_IS_ENABLED(RISCV_MMODE) asm volatile ( "fence.i\n\t" "csrr t1, mcache_ctl\n\t" @@ -99,7 +99,7 @@ void dcache_enable(void) { #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) #ifdef CONFIG_RISCV_NDS_CACHE -#if CONFIG_IS_ENABLED(RISCV_MMODE) || CONFIG_IS_ENABLED(SPL_RISCV_MMODE) +#if CONFIG_IS_ENABLED(RISCV_MMODE) asm volatile ( "csrr t1, mcache_ctl\n\t" "ori t0, t1, 0x2\n\t" @@ -117,7 +117,7 @@ void dcache_disable(void) { #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) #ifdef CONFIG_RISCV_NDS_CACHE -#if CONFIG_IS_ENABLED(RISCV_MMODE) || CONFIG_IS_ENABLED(SPL_RISCV_MMODE) +#if CONFIG_IS_ENABLED(RISCV_MMODE) csr_write(CCTL_REG_MCCTLCOMMAND_NUM, CCTL_L1D_WBINVAL_ALL); asm volatile ( "csrr t1, mcache_ctl\n\t" @@ -137,7 +137,7 @@ int icache_status(void) int ret = 0; #ifdef CONFIG_RISCV_NDS_CACHE -#if CONFIG_IS_ENABLED(RISCV_MMODE) || CONFIG_IS_ENABLED(SPL_RISCV_MMODE) +#if CONFIG_IS_ENABLED(RISCV_MMODE) asm volatile ( "csrr t1, mcache_ctl\n\t" "andi %0, t1, 0x01\n\t" @@ -156,7 +156,7 @@ int dcache_status(void) int ret = 0; #ifdef CONFIG_RISCV_NDS_CACHE -#if CONFIG_IS_ENABLED(RISCV_MMODE) || CONFIG_IS_ENABLED(SPL_RISCV_MMODE) +#if CONFIG_IS_ENABLED(RISCV_MMODE) asm volatile ( "csrr t1, mcache_ctl\n\t" "andi %0, t1, 0x02\n\t" From 846b6120140ae98ca88d245fb10955d3c6980603 Mon Sep 17 00:00:00 2001 From: Lukas Auer Date: Tue, 14 Apr 2020 23:24:46 +0200 Subject: [PATCH 02/14] Revert "riscv: qemu: clear kernel-start/-end in device tree as workaround for BBL" The commit was added as a workaround required in QEMU when using BBL as the supervisor binary interface (SBI) for Linux. We are now using OpenSBI to provide the SBI, the workaround is therefore not required anymore and can be removed. This reverts commit 897206c5cc5c6ac0dc2ab851044e42baada3785b. Signed-off-by: Lukas Auer Reviewed-by: Bin Meng --- board/emulation/qemu-riscv/Kconfig | 1 - board/emulation/qemu-riscv/qemu-riscv.c | 39 ------------------------- 2 files changed, 40 deletions(-) diff --git a/board/emulation/qemu-riscv/Kconfig b/board/emulation/qemu-riscv/Kconfig index 7ce12018e7..ad99b08b44 100644 --- a/board/emulation/qemu-riscv/Kconfig +++ b/board/emulation/qemu-riscv/Kconfig @@ -43,7 +43,6 @@ config BOARD_SPECIFIC_OPTIONS # dummy imply CMD_EXT4 imply CMD_FAT imply BOARD_LATE_INIT - imply OF_BOARD_SETUP imply SIFIVE_SERIAL imply SMP imply PCI diff --git a/board/emulation/qemu-riscv/qemu-riscv.c b/board/emulation/qemu-riscv/qemu-riscv.c index cbce5ffe6e..c3f96988b1 100644 --- a/board/emulation/qemu-riscv/qemu-riscv.c +++ b/board/emulation/qemu-riscv/qemu-riscv.c @@ -52,45 +52,6 @@ int board_late_init(void) return 0; } -/* - * QEMU specifies the location of Linux (supplied with the -kernel argument) - * in the device tree using the riscv,kernel-start and riscv,kernel-end - * properties. We currently rely on the SBI implementation of BBL to run - * Linux and therefore embed Linux as payload in BBL. This causes an issue, - * because BBL detects the kernel properties in the device tree and ignores - * the Linux payload as a result. To work around this issue, we clear the - * kernel properties before booting Linux. - * - * This workaround can be removed, once we do not require BBL for its SBI - * implementation anymore. - */ -int ft_board_setup(void *blob, bd_t *bd) -{ - int chosen_offset, ret; - - chosen_offset = fdt_path_offset(blob, "/chosen"); - if (chosen_offset < 0) - return 0; - -#ifdef CONFIG_ARCH_RV64I - ret = fdt_setprop_u64(blob, chosen_offset, "riscv,kernel-start", 0); -#else - ret = fdt_setprop_u32(blob, chosen_offset, "riscv,kernel-start", 0); -#endif - if (ret) - return ret; - -#ifdef CONFIG_ARCH_RV64I - ret = fdt_setprop_u64(blob, chosen_offset, "riscv,kernel-end", 0); -#else - ret = fdt_setprop_u32(blob, chosen_offset, "riscv,kernel-end", 0); -#endif - if (ret) - return ret; - - return 0; -} - #ifdef CONFIG_SPL u32 spl_boot_device(void) { From ed1475e2f46cec0dbde308a67576f9ea32b0287c Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 16 Apr 2020 08:09:28 -0700 Subject: [PATCH 03/14] riscv: qemu: Remove the simple-bus driver for the SoC node Prior to QEMU v3.1.0, QEMU generated the 'virt' SoC node with a "riscv-virtio-soc" compatible string, and a "simple-bus" driver was created to accommodate that special case in U-Boot. Starting from QEMU v3.1.0, the SoC node was set as a "simple-bus", hence the special simple-bus driver is no longer needed. Update the doc to mention the latest tested QEMU version 4.2.0. Signed-off-by: Bin Meng --- arch/riscv/cpu/generic/cpu.c | 14 -------------- doc/board/emulation/qemu-riscv.rst | 2 +- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/arch/riscv/cpu/generic/cpu.c b/arch/riscv/cpu/generic/cpu.c index c0a5288bdb..13a69ef0cc 100644 --- a/arch/riscv/cpu/generic/cpu.c +++ b/arch/riscv/cpu/generic/cpu.c @@ -4,7 +4,6 @@ */ #include -#include #include /* @@ -21,16 +20,3 @@ 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/doc/board/emulation/qemu-riscv.rst b/doc/board/emulation/qemu-riscv.rst index fe7505e201..c390006b31 100644 --- a/doc/board/emulation/qemu-riscv.rst +++ b/doc/board/emulation/qemu-riscv.rst @@ -56,7 +56,7 @@ For instructions on how to run U-Boot in supervisor mode on QEMU with OpenSBI, see the documentation available with OpenSBI: https://github.com/riscv/opensbi/blob/master/docs/platform/qemu_virt.md -These have been tested in QEMU 3.0.0. +These have been tested in QEMU 4.2.0. Running U-Boot SPL ------------------ From 84dc9d26908798c7e9ee5469965c16653593fde5 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 16 Apr 2020 08:09:29 -0700 Subject: [PATCH 04/14] riscv: Merge unnecessary SMP ifdefs in start.S Two consecutive SMP ifdefs blocks can be combined into one. Signed-off-by: Bin Meng Reviewed-by: Atish Patra --- arch/riscv/cpu/start.S | 4 ---- 1 file changed, 4 deletions(-) diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S index 6b3ff99c38..ecf0482635 100644 --- a/arch/riscv/cpu/start.S +++ b/arch/riscv/cpu/start.S @@ -58,9 +58,7 @@ _start: /* 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 */ #if CONFIG_IS_ENABLED(RISCV_MMODE) li t0, MIE_MSIE @@ -377,9 +375,7 @@ 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 */ From 191636e4489885d197e61ad34b48e8c76990735e Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 16 Apr 2020 08:09:30 -0700 Subject: [PATCH 05/14] riscv: Introduce SPL_SMP Kconfig option for U-Boot SPL With SBI v0.2 HSM extension, only a single hart need to boot and enter operating system. The booting hart can bring up secondary harts one by one afterwards. For U-Boot running in SPL, SMP can be turned on, while in U-Boot proper, SMP can be optionally turned off if using SBI v0.2 HSM. Introduce a new SPL_SMP Kconfig option to support this. Signed-off-by: Bin Meng Reviewed-by: Atish Patra --- arch/riscv/Kconfig | 13 ++++++++++++- arch/riscv/cpu/start.S | 14 +++++++------- arch/riscv/include/asm/global_data.h | 2 +- arch/riscv/lib/Makefile | 2 +- arch/riscv/lib/spl.c | 2 +- common/spl/spl_opensbi.c | 2 +- 6 files changed, 23 insertions(+), 12 deletions(-) diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 3061bf8863..5ef6849cce 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -200,10 +200,21 @@ config SMP machine. If you say Y here, U-Boot will run on many, but not all, single processor machines. +config SPL_SMP + bool "Symmetric Multi-Processing in SPL" + depends on SPL && SPL_RISCV_MMODE + default y + help + This enables support for systems with more than one CPU in SPL. + If you say N here, U-Boot SPL will run on single and multiprocessor + machines, but will use only one CPU of a multiprocessor + machine. If you say Y here, U-Boot SPL 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 + depends on SMP || SPL_SMP default 8 help On multiprocessor machines, U-Boot sets up a stack for each CPU. diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S index ecf0482635..fce098272f 100644 --- a/arch/riscv/cpu/start.S +++ b/arch/riscv/cpu/start.S @@ -53,7 +53,7 @@ _start: /* mask all interrupts */ csrw MODE_PREFIX(ie), zero -#ifdef CONFIG_SMP +#if CONFIG_IS_ENABLED(SMP) /* check if hart is within range */ /* tp: hart id */ li t0, CONFIG_NR_CPUS @@ -91,7 +91,7 @@ call_board_init_f_0: mv gp, a0 /* setup stack */ -#ifdef CONFIG_SMP +#if CONFIG_IS_ENABLED(SMP) /* tp: hart id */ slli t0, tp, CONFIG_STACK_SIZE_SHIFT sub sp, a0, t0 @@ -182,7 +182,7 @@ spl_stack_gd_setup: mv s0, a0 /* setup stack on main hart */ -#ifdef CONFIG_SMP +#if CONFIG_IS_ENABLED(SMP) /* tp: hart id */ slli t0, tp, CONFIG_STACK_SIZE_SHIFT sub sp, s0, t0 @@ -231,7 +231,7 @@ relocate_code: *Set up the stack */ stack_setup: -#ifdef CONFIG_SMP +#if CONFIG_IS_ENABLED(SMP) /* tp: hart id */ slli t0, tp, CONFIG_STACK_SIZE_SHIFT sub sp, s2, t0 @@ -326,7 +326,7 @@ clbss_l: blt t0, t1, clbss_l relocate_secondary_harts: -#ifdef CONFIG_SMP +#if CONFIG_IS_ENABLED(SMP) /* send relocation IPI */ la t0, secondary_hart_relocate add a0, t0, t6 @@ -370,7 +370,7 @@ call_board_init_r: */ jr t4 /* jump to board_init_r() */ -#ifdef CONFIG_SMP +#if CONFIG_IS_ENABLED(SMP) hart_out_of_bounds_loop: /* Harts in this loop are out of bounds, increase CONFIG_NR_CPUS. */ wfi @@ -393,7 +393,7 @@ secondary_hart_relocate: secondary_hart_loop: wfi -#ifdef CONFIG_SMP +#if CONFIG_IS_ENABLED(SMP) csrr t0, MODE_PREFIX(ip) #if CONFIG_IS_ENABLED(RISCV_MMODE) andi t0, t0, MIE_MSIE diff --git a/arch/riscv/include/asm/global_data.h b/arch/riscv/include/asm/global_data.h index b74bd7e738..72fb4b4d92 100644 --- a/arch/riscv/include/asm/global_data.h +++ b/arch/riscv/include/asm/global_data.h @@ -24,7 +24,7 @@ struct arch_global_data { #ifdef CONFIG_ANDES_PLMT void __iomem *plmt; /* plmt base address */ #endif -#ifdef CONFIG_SMP +#if CONFIG_IS_ENABLED(SMP) struct ipi_data ipi[CONFIG_NR_CPUS]; #endif #ifndef CONFIG_XIP diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile index adadbf4bcb..bd7b2c4d16 100644 --- a/arch/riscv/lib/Makefile +++ b/arch/riscv/lib/Makefile @@ -22,7 +22,7 @@ endif obj-y += interrupts.o obj-y += reset.o obj-y += setjmp.o -obj-$(CONFIG_SMP) += smp.o +obj-$(CONFIG_$(SPL_)SMP) += smp.o obj-$(CONFIG_SPL_BUILD) += spl.o # For building EFI apps diff --git a/arch/riscv/lib/spl.c b/arch/riscv/lib/spl.c index ae07bbe40a..4ca038b148 100644 --- a/arch/riscv/lib/spl.c +++ b/arch/riscv/lib/spl.c @@ -41,7 +41,7 @@ void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) invalidate_icache_all(); debug("image entry point: 0x%lX\n", spl_image->entry_point); -#ifdef CONFIG_SMP +#ifdef CONFIG_SPL_SMP ret = smp_call_function(spl_image->entry_point, (ulong)fdt_blob, 0, 0); if (ret) hang(); diff --git a/common/spl/spl_opensbi.c b/common/spl/spl_opensbi.c index a136073fdb..3519c34299 100644 --- a/common/spl/spl_opensbi.c +++ b/common/spl/spl_opensbi.c @@ -76,7 +76,7 @@ void spl_invoke_opensbi(struct spl_image_info *spl_image) opensbi_entry = (void (*)(ulong, ulong, ulong))spl_image->entry_point; invalidate_icache_all(); -#ifdef CONFIG_SMP +#ifdef CONFIG_SPL_SMP /* * Start OpenSBI on all secondary harts and wait for acknowledgment. * From 6fa022e8fc7fd180c05934e71d4b9351b549f5b7 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 16 Apr 2020 08:09:31 -0700 Subject: [PATCH 06/14] riscv: Add SMP Kconfig option dependency for U-Boot proper U-Boot proper running in S-mode only need SMP support when using SBI v0.1. With SBI v0.2 HSM extension, it does not need implement multicore boot in U-Boot proper. Signed-off-by: Bin Meng Reviewed-by: Atish Patra --- arch/riscv/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 5ef6849cce..a252cdbb71 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -193,6 +193,7 @@ config SYS_MALLOC_F_LEN config SMP bool "Symmetric Multi-Processing" + depends on SBI_V01 || !RISCV_SMODE help This enables support for systems with more than one CPU. If you say N here, U-Boot will run on single and multiprocessor From ff0fa6c1b31b6b48db7864dd01819842d6c02648 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 16 Apr 2020 08:09:32 -0700 Subject: [PATCH 07/14] riscv: Add Kconfig option for SBI v0.2 SBI v0.2 is more scalable and extendable to handle future needs for RISC-V supervisor interfaces. For example, with SBI v0.2 HSM extension, only a single hart need to boot and enter operating system. The booting hart can bring up secondary harts one by one afterwards. Signed-off-by: Bin Meng Reviewed-by: Atish Patra --- arch/riscv/Kconfig | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index a252cdbb71..c729871813 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -226,14 +226,32 @@ config SBI bool default y if RISCV_SMODE || SPL_RISCV_SMODE +choice + prompt "SBI support" + default SBI_V01 + config SBI_V01 bool "SBI v0.1 support" - default y depends on SBI help This config allows kernel to use SBI v0.1 APIs. This will be deprecated in future once legacy M-mode software are no longer in use. +config SBI_V02 + bool "SBI v0.2 support" + depends on SBI + help + This config allows kernel to use SBI v0.2 APIs. SBI v0.2 is more + scalable and extendable to handle future needs for RISC-V supervisor + interfaces. For example, with SBI v0.2 HSM extension, only a single + hart need to boot and enter operating system. The booting hart can + bring up secondary harts one by one afterwards. + + Choose this option if OpenSBI v0.7 or above release is used together + with U-Boot. + +endchoice + config SBI_IPI bool depends on SBI From fa16ec23bcc8c855106f055d6e552e4cc203a87d Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 16 Apr 2020 08:09:33 -0700 Subject: [PATCH 08/14] riscv: Make SBI v0.2 the default SBI version To work with latest OpenSBI release (v0.7 or above) that has the HSM extension support, select the SBI v0.2 support by default. Signed-off-by: Bin Meng Reviewed-by: Atish Patra --- arch/riscv/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index c729871813..fb5fe5afff 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -228,7 +228,7 @@ config SBI choice prompt "SBI support" - default SBI_V01 + default SBI_V02 config SBI_V01 bool "SBI v0.1 support" From 5370478d1c7afb8b2a8a0a00b31ff97c3a2c0451 Mon Sep 17 00:00:00 2001 From: Atish Patra Date: Tue, 21 Apr 2020 11:14:59 -0700 Subject: [PATCH 09/14] riscv: Add boot hartid to device tree Linux booting protocol mandates that register "a0" contains the hartid. However, U-Boot can not pass the hartid via a0 during standard UEFI protocol. DT nodes are commonly used to pass such information to the OS. Add a DT node under chosen node to indicate the boot hartid. EFI stub in Linux kernel will parse this node and pass it to the real kernel in "a0" before jumping to it. Signed-off-by: Atish Patra Reviewed-by: Rick Chen Reviewed-by: Bin Meng Tested-by: Heinrich Schuchardt Tested-by: Bin Meng --- arch/riscv/lib/bootm.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/arch/riscv/lib/bootm.c b/arch/riscv/lib/bootm.c index fad16901c5..87cadad501 100644 --- a/arch/riscv/lib/bootm.c +++ b/arch/riscv/lib/bootm.c @@ -28,6 +28,28 @@ __weak void board_quiesce_devices(void) int arch_fixup_fdt(void *blob) { +#ifdef CONFIG_EFI_LOADER + int err; + u32 size; + int chosen_offset; + + size = fdt_totalsize(blob); + err = fdt_open_into(blob, blob, size + 32); + if (err < 0) { + printf("Device Tree can't be expanded to accommodate new node"); + return err; + } + chosen_offset = fdt_path_offset(blob, "/chosen"); + if (chosen_offset < 0) { + err = fdt_add_subnode(blob, 0, "chosen"); + if (err < 0) { + printf("chosen node can not be added\n"); + return err; + } + } + /* Overwrite the boot-hartid as U-Boot is the last stage BL */ + fdt_setprop_u32(blob, chosen_offset, "boot-hartid", gd->arch.boot_hart); +#endif return 0; } From f614753c4b91bc3b56809773aeb17da10f1231a5 Mon Sep 17 00:00:00 2001 From: Atish Patra Date: Tue, 21 Apr 2020 11:15:00 -0700 Subject: [PATCH 10/14] fdtdec: Fix boundary check In U-Boot, the reserved memory end address is considered as a inclusive address. This notion is followed while adding a reserved memory node to the DT. For example: end_address = start_address + size - 1 Follow the same notion and fix the end address computation while checking for existing nodes. Signed-off-by: Atish Patra Reviewed-by: Bin Meng Tested-by: Bin Meng --- lib/fdtdec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 9ecfa2a2d7..460f0d250b 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -1311,7 +1311,8 @@ int fdtdec_add_reserved_memory(void *blob, const char *basename, continue; } - if (addr == carveout->start && (addr + size) == carveout->end) { + if (addr == carveout->start && (addr + size - 1) == + carveout->end) { if (phandlep) *phandlep = fdt_get_phandle(blob, node); return 0; From d4ea649f179a69edd2cf2dd96efb9337205eb015 Mon Sep 17 00:00:00 2001 From: Atish Patra Date: Tue, 21 Apr 2020 11:15:01 -0700 Subject: [PATCH 11/14] riscv: Provide a mechanism to fix DT for reserved memory In RISC-V, M-mode software can reserve physical memory regions by setting appropriate physical memory protection (PMP) csr. As the PMP csr are accessible only in M-mode, S-mode U-Boot can not read this configuration directly. However, M-mode software can pass this information via reserved-memory node in device tree so that S-mode software can access this information. This patch provides a framework to copy to the reserved-memory node from one DT to another. This will be used to update the DT used by U-Boot and the DT passed to the next stage OS. Signed-off-by: Atish Patra Reviewed-by: Bin Meng Tested-by: Bin Meng --- arch/riscv/cpu/start.S | 1 + arch/riscv/include/asm/global_data.h | 1 + arch/riscv/include/asm/u-boot-riscv.h | 2 + arch/riscv/lib/Makefile | 1 + arch/riscv/lib/asm-offsets.c | 1 + arch/riscv/lib/fdt_fixup.c | 102 ++++++++++++++++++++++++++ 6 files changed, 108 insertions(+) create mode 100644 arch/riscv/lib/fdt_fixup.c diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S index fce098272f..5f1c220e0c 100644 --- a/arch/riscv/cpu/start.S +++ b/arch/riscv/cpu/start.S @@ -119,6 +119,7 @@ call_board_init_f_0: jal board_init_f_init_reserve + SREG s1, GD_FIRMWARE_FDT_ADDR(gp) /* save the boot hart id to global_data */ SREG tp, GD_BOOT_HART(gp) diff --git a/arch/riscv/include/asm/global_data.h b/arch/riscv/include/asm/global_data.h index 72fb4b4d92..6c50149218 100644 --- a/arch/riscv/include/asm/global_data.h +++ b/arch/riscv/include/asm/global_data.h @@ -15,6 +15,7 @@ /* Architecture-specific global data */ struct arch_global_data { long boot_hart; /* boot hart id */ + phys_addr_t firmware_fdt_addr; #ifdef CONFIG_SIFIVE_CLINT void __iomem *clint; /* clint base address */ #endif diff --git a/arch/riscv/include/asm/u-boot-riscv.h b/arch/riscv/include/asm/u-boot-riscv.h index 49febd5881..543a1688db 100644 --- a/arch/riscv/include/asm/u-boot-riscv.h +++ b/arch/riscv/include/asm/u-boot-riscv.h @@ -17,5 +17,7 @@ int cleanup_before_linux(void); /* board/.../... */ int board_init(void); void board_quiesce_devices(void); +int riscv_board_reserved_mem_fixup(void *fdt); +int riscv_fdt_copy_resv_mem_node(const void *src_fdt, void *dest_fdt); #endif /* _U_BOOT_RISCV_H_ */ diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile index bd7b2c4d16..b5e93244e0 100644 --- a/arch/riscv/lib/Makefile +++ b/arch/riscv/lib/Makefile @@ -24,6 +24,7 @@ obj-y += reset.o obj-y += setjmp.o obj-$(CONFIG_$(SPL_)SMP) += smp.o obj-$(CONFIG_SPL_BUILD) += spl.o +obj-y += fdt_fixup.o # For building EFI apps CFLAGS_$(EFI_CRT0) := $(CFLAGS_EFI) diff --git a/arch/riscv/lib/asm-offsets.c b/arch/riscv/lib/asm-offsets.c index 4fa4fd3714..7301c1b98e 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_FIRMWARE_FDT_ADDR, offsetof(gd_t, arch.firmware_fdt_addr)); #ifndef CONFIG_XIP DEFINE(GD_AVAILABLE_HARTS, offsetof(gd_t, arch.available_harts)); #endif diff --git a/arch/riscv/lib/fdt_fixup.c b/arch/riscv/lib/fdt_fixup.c new file mode 100644 index 0000000000..1fce414909 --- /dev/null +++ b/arch/riscv/lib/fdt_fixup.c @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2020 Western Digital Corporation or its affiliates + * + */ + +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +/** + * riscv_fdt_copy_resv_mem_node() - Copy reserve memory node entry + * @src: Pointer to the source device tree from which reserved memory node + * needs to be copied. + * @dst: Pointer to the destination device tree to which reserved memory node + * needs to be copied. + * + * Return: 0 on success or if source doesn't have reserved memory node. + * Error if copy process failed. + */ +int riscv_fdt_copy_resv_mem_node(const void *src, void *dst) +{ + u32 phandle; + struct fdt_memory pmp_mem; + fdt_addr_t addr; + fdt_size_t size; + int offset, node, err, rmem_offset; + bool nomap = true; + char basename[32] = {0}; + int bname_len; + int max_len = sizeof(basename); + const char *name; + char *temp; + + offset = fdt_path_offset(src, "/reserved-memory"); + if (offset < 0) { + printf("No reserved memory region found in source FDT\n"); + return 0; + } + + fdt_for_each_subnode(node, src, offset) { + name = fdt_get_name(src, node, NULL); + + addr = fdtdec_get_addr_size_auto_noparent(src, node, + "reg", 0, &size, + false); + if (addr == FDT_ADDR_T_NONE) { + debug("failed to read address/size for %s\n", name); + continue; + } + strncpy(basename, name, max_len); + temp = strchr(basename, '@'); + if (temp) { + bname_len = strnlen(basename, max_len) - strnlen(temp, + max_len); + *(basename + bname_len) = '\0'; + } + pmp_mem.start = addr; + pmp_mem.end = addr + size - 1; + err = fdtdec_add_reserved_memory(dst, basename, &pmp_mem, + &phandle); + if (err < 0) { + printf("failed to add reserved memory: %d\n", err); + return err; + } + if (!fdt_getprop(src, node, "no-map", NULL)) + nomap = false; + if (nomap) { + rmem_offset = fdt_node_offset_by_phandle(dst, phandle); + fdt_setprop_empty(dst, rmem_offset, "no-map"); + } + } + + return 0; +} + +/** + * riscv_board_reserved_mem_fixup() - Fix up reserved memory node for a board + * @fdt: Pointer to the device tree in which reserved memory node needs to be + * added. + * + * In RISC-V, any board compiled with OF_SEPARATE needs to copy the reserved + * memory node from the device tree provided by the firmware to the device tree + * used by U-Boot. This is a common function that individual board fixup + * functions can invoke. + * + * Return: 0 on success or error otherwise. + */ +int riscv_board_reserved_mem_fixup(void *fdt) +{ + int err; + void *src_fdt_addr; + + src_fdt_addr = map_sysmem(gd->arch.firmware_fdt_addr, 0); + err = riscv_fdt_copy_resv_mem_node(src_fdt_addr, fdt); + if (err < 0) + return err; + + return 0; +} From 0cb27856d12ff1350996f93015972203b24387cc Mon Sep 17 00:00:00 2001 From: Atish Patra Date: Tue, 21 Apr 2020 11:15:02 -0700 Subject: [PATCH 12/14] riscv: Setup reserved-memory node for FU540 FU540 uses OF_SEPARATE instead of OF_PRIOR_STAGE. Enable OF_BOARD_FIXUP to update the DT with reserved-memory node. Signed-off-by: Atish Patra Reviewed-by: Bin Meng Tested-by: Bin Meng --- arch/riscv/lib/fdt_fixup.c | 15 +++++++++++++++ configs/sifive_fu540_defconfig | 1 + 2 files changed, 16 insertions(+) diff --git a/arch/riscv/lib/fdt_fixup.c b/arch/riscv/lib/fdt_fixup.c index 1fce414909..af12e484db 100644 --- a/arch/riscv/lib/fdt_fixup.c +++ b/arch/riscv/lib/fdt_fixup.c @@ -100,3 +100,18 @@ int riscv_board_reserved_mem_fixup(void *fdt) return 0; } + +#ifdef CONFIG_OF_BOARD_FIXUP +int board_fix_fdt(void *fdt) +{ + int err; + + err = riscv_board_reserved_mem_fixup(fdt); + if (err < 0) { + printf("failed to fixup DT for reserved memory: %d\n", err); + return err; + } + + return 0; +} +#endif diff --git a/configs/sifive_fu540_defconfig b/configs/sifive_fu540_defconfig index 6d61e6c960..f805aacc7a 100644 --- a/configs/sifive_fu540_defconfig +++ b/configs/sifive_fu540_defconfig @@ -9,6 +9,7 @@ CONFIG_FIT=y CONFIG_MISC_INIT_R=y CONFIG_DISPLAY_CPUINFO=y CONFIG_DISPLAY_BOARDINFO=y +CONFIG_OF_BOARD_FIXUP=y CONFIG_DEFAULT_DEVICE_TREE="hifive-unleashed-a00" CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_DM_MTD=y From 73d756fd224666e6fa029920f3aaf9cbfab71cb5 Mon Sep 17 00:00:00 2001 From: Atish Patra Date: Tue, 21 Apr 2020 11:15:03 -0700 Subject: [PATCH 13/14] riscv: Copy the reserved-memory nodes to final DT The DT used by U-Boot may be different from the DT being passed to the OS if the DT is loaded from external media such as network or mmc. In that case, the reserved-memory node needs to be copied to the DT passed to the OS. Signed-off-by: Atish Patra Reviewed-by: Bin Meng Tested-by: Bin Meng --- arch/riscv/lib/bootm.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/riscv/lib/bootm.c b/arch/riscv/lib/bootm.c index 87cadad501..8ff8db6bf5 100644 --- a/arch/riscv/lib/bootm.c +++ b/arch/riscv/lib/bootm.c @@ -28,8 +28,8 @@ __weak void board_quiesce_devices(void) int arch_fixup_fdt(void *blob) { -#ifdef CONFIG_EFI_LOADER int err; +#ifdef CONFIG_EFI_LOADER u32 size; int chosen_offset; @@ -50,6 +50,12 @@ int arch_fixup_fdt(void *blob) /* Overwrite the boot-hartid as U-Boot is the last stage BL */ fdt_setprop_u32(blob, chosen_offset, "boot-hartid", gd->arch.boot_hart); #endif + + /* Copy the reserved-memory node to the DT used by OS */ + err = riscv_fdt_copy_resv_mem_node(gd->fdt_blob, blob); + if (err < 0) + return err; + return 0; } From 177c53fe6c64d8656f5a647116a97047202c5455 Mon Sep 17 00:00:00 2001 From: Atish Patra Date: Tue, 21 Apr 2020 11:15:04 -0700 Subject: [PATCH 14/14] riscv: Move all fdt fixups together Keep all the fdt fixups together for better code management. Signed-off-by: Atish Patra Reviewed-by: Bin Meng --- arch/riscv/lib/bootm.c | 33 --------------------------------- arch/riscv/lib/fdt_fixup.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/arch/riscv/lib/bootm.c b/arch/riscv/lib/bootm.c index 8ff8db6bf5..0d06095da1 100644 --- a/arch/riscv/lib/bootm.c +++ b/arch/riscv/lib/bootm.c @@ -26,39 +26,6 @@ __weak void board_quiesce_devices(void) { } -int arch_fixup_fdt(void *blob) -{ - int err; -#ifdef CONFIG_EFI_LOADER - u32 size; - int chosen_offset; - - size = fdt_totalsize(blob); - err = fdt_open_into(blob, blob, size + 32); - if (err < 0) { - printf("Device Tree can't be expanded to accommodate new node"); - return err; - } - chosen_offset = fdt_path_offset(blob, "/chosen"); - if (chosen_offset < 0) { - err = fdt_add_subnode(blob, 0, "chosen"); - if (err < 0) { - printf("chosen node can not be added\n"); - return err; - } - } - /* Overwrite the boot-hartid as U-Boot is the last stage BL */ - fdt_setprop_u32(blob, chosen_offset, "boot-hartid", gd->arch.boot_hart); -#endif - - /* Copy the reserved-memory node to the DT used by OS */ - err = riscv_fdt_copy_resv_mem_node(gd->fdt_blob, blob); - if (err < 0) - return err; - - return 0; -} - /** * announce_and_cleanup() - Print message and prepare for kernel boot * diff --git a/arch/riscv/lib/fdt_fixup.c b/arch/riscv/lib/fdt_fixup.c index af12e484db..20e0759f13 100644 --- a/arch/riscv/lib/fdt_fixup.c +++ b/arch/riscv/lib/fdt_fixup.c @@ -115,3 +115,36 @@ int board_fix_fdt(void *fdt) return 0; } #endif + +int arch_fixup_fdt(void *blob) +{ + int err; +#ifdef CONFIG_EFI_LOADER + u32 size; + int chosen_offset; + + size = fdt_totalsize(blob); + err = fdt_open_into(blob, blob, size + 32); + if (err < 0) { + printf("Device Tree can't be expanded to accommodate new node"); + return err; + } + chosen_offset = fdt_path_offset(blob, "/chosen"); + if (chosen_offset < 0) { + err = fdt_add_subnode(blob, 0, "chosen"); + if (err < 0) { + printf("chosen node can not be added\n"); + return err; + } + } + /* Overwrite the boot-hartid as U-Boot is the last stage BL */ + fdt_setprop_u32(blob, chosen_offset, "boot-hartid", gd->arch.boot_hart); +#endif + + /* Copy the reserved-memory node to the DT used by OS */ + err = riscv_fdt_copy_resv_mem_node(gd->fdt_blob, blob); + if (err < 0) + return err; + + return 0; +}