From cb57811fbc726cb93da92c05cdfbb880a8c78c50 Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Wed, 10 Mar 2021 21:02:17 -0500 Subject: [PATCH 01/16] wdt: dw: Switch to using fls for log2 log_2_n_round_up is only found in arm. fls performs the same job and is generic. Signed-off-by: Sean Anderson Reviewed-by: Simon Glass --- drivers/watchdog/designware_wdt.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/watchdog/designware_wdt.c b/drivers/watchdog/designware_wdt.c index c020324973e..1f0c5a77c92 100644 --- a/drivers/watchdog/designware_wdt.c +++ b/drivers/watchdog/designware_wdt.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #define DW_WDT_CR 0x00 @@ -35,7 +34,7 @@ static int designware_wdt_settimeout(void __iomem *base, unsigned int clk_khz, signed int i; /* calculate the timeout range value */ - i = log_2_n_round_up(timeout * clk_khz) - 16; + i = fls(timeout * clk_khz - 1) - 16; i = clamp(i, 0, 15); writel(i | (i << 4), base + DW_WDT_TORR); From 7d8394366a3b1a8bcbc4ea3460ff5c0901335731 Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Wed, 10 Mar 2021 21:02:18 -0500 Subject: [PATCH 02/16] wdt: dw: Switch to if(CONFIG()) instead of using #if This is preferred over #if because the compiler can check syntax even if the feature is disabled. This cannot be used for CONFIG_CLK because CONFIG_DW_WDT_CLOCK_KHZ is not defined on all platforms. Signed-off-by: Sean Anderson Reviewed-by: Heinrich Schuchardt --- drivers/watchdog/designware_wdt.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/watchdog/designware_wdt.c b/drivers/watchdog/designware_wdt.c index 1f0c5a77c92..a65487d4f34 100644 --- a/drivers/watchdog/designware_wdt.c +++ b/drivers/watchdog/designware_wdt.c @@ -136,17 +136,17 @@ static int designware_wdt_probe(struct udevice *dev) priv->clk_khz = CONFIG_DW_WDT_CLOCK_KHZ; #endif -#if CONFIG_IS_ENABLED(DM_RESET) - struct reset_ctl_bulk resets; + if (CONFIG_IS_ENABLED(DM_RESET)) { + struct reset_ctl_bulk resets; - ret = reset_get_bulk(dev, &resets); - if (ret) - return ret; + ret = reset_get_bulk(dev, &resets); + if (ret) + return ret; - ret = reset_deassert_bulk(&resets); - if (ret) - return ret; -#endif + ret = reset_deassert_bulk(&resets); + if (ret) + return ret; + } /* reset to disable the watchdog */ return designware_wdt_stop(dev); From 4cb0ab4ebcffbeee93d9bdb4e8ee831e16bc8d2c Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Wed, 10 Mar 2021 21:02:19 -0500 Subject: [PATCH 03/16] wdt: dw: Enable the clock before using it The watchdog won't work if the clock isn't enabled. Fixes: cf89ef8d10f240554541c20b2e1bdcdd58d1d7e6 Signed-off-by: Sean Anderson Reviewed-by: Simon Glass --- drivers/watchdog/designware_wdt.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/watchdog/designware_wdt.c b/drivers/watchdog/designware_wdt.c index a65487d4f34..709a67fbc34 100644 --- a/drivers/watchdog/designware_wdt.c +++ b/drivers/watchdog/designware_wdt.c @@ -129,6 +129,10 @@ static int designware_wdt_probe(struct udevice *dev) if (ret) return ret; + ret = clk_enable(&clk); + if (ret) + return ret; + priv->clk_khz = clk_get_rate(&clk) / 1000; if (!priv->clk_khz) return -EINVAL; From 97bcdd28addde4233b6c53c03712eed5a807854c Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Wed, 10 Mar 2021 21:02:20 -0500 Subject: [PATCH 04/16] wdt: dw: Free the clock on error The clock subsystem requires that clk_free be called on clocks obtained via clk_get_*. Signed-off-by: Sean Anderson Reviewed-by: Simon Glass --- drivers/watchdog/designware_wdt.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/watchdog/designware_wdt.c b/drivers/watchdog/designware_wdt.c index 709a67fbc34..9e5487168cd 100644 --- a/drivers/watchdog/designware_wdt.c +++ b/drivers/watchdog/designware_wdt.c @@ -131,11 +131,13 @@ static int designware_wdt_probe(struct udevice *dev) ret = clk_enable(&clk); if (ret) - return ret; + goto err; priv->clk_khz = clk_get_rate(&clk) / 1000; - if (!priv->clk_khz) - return -EINVAL; + if (!priv->clk_khz) { + ret = -EINVAL; + goto err; + } #else priv->clk_khz = CONFIG_DW_WDT_CLOCK_KHZ; #endif @@ -145,15 +147,21 @@ static int designware_wdt_probe(struct udevice *dev) ret = reset_get_bulk(dev, &resets); if (ret) - return ret; + goto err; ret = reset_deassert_bulk(&resets); if (ret) - return ret; + goto err; } /* reset to disable the watchdog */ return designware_wdt_stop(dev); + +err: +#if CONFIG_IS_ENABLED(CLK) + clk_free(&clk); +#endif + return ret; } static const struct wdt_ops designware_wdt_ops = { From b0479d1bf14eace5b044f6d99e802fabd18109d0 Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Wed, 10 Mar 2021 21:02:21 -0500 Subject: [PATCH 05/16] riscv: Add watchdog bindings for the k210 This adds the necessary bindings. Most of them are already there. Signed-off-by: Sean Anderson Acked-by: Rick Chen --- arch/riscv/dts/k210.dtsi | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/riscv/dts/k210.dtsi b/arch/riscv/dts/k210.dtsi index 81b04018c63..0b79a296008 100644 --- a/arch/riscv/dts/k210.dtsi +++ b/arch/riscv/dts/k210.dtsi @@ -439,7 +439,6 @@ interrupts = <21>; clocks = <&sysclk K210_CLK_WDT0>; resets = <&sysrst K210_RST_WDT0>; - status = "disabled"; }; wdt1: watchdog@50410000 { From e3282b1bbae4e8558c2b85bf27560d12358ed25f Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Wed, 10 Mar 2021 21:02:22 -0500 Subject: [PATCH 06/16] riscv: Enable watchdog for the k210 This enables the necessary config options. Signed-off-by: Sean Anderson Reviewed-by: Simon Glass --- board/sipeed/maix/Kconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/board/sipeed/maix/Kconfig b/board/sipeed/maix/Kconfig index 2cdea8ea813..adf6abb5726 100644 --- a/board/sipeed/maix/Kconfig +++ b/board/sipeed/maix/Kconfig @@ -69,4 +69,6 @@ config BOARD_SPECIFIC_OPTIONS imply EFI_PARTITION imply CMD_PART imply CMD_FS_GENERIC + imply WDT + imply DESIGNWARE_WATCHDOG endif From 6eef9c9a23208c0def02b0ac50d93fce8f84587d Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Wed, 10 Mar 2021 20:51:31 -0500 Subject: [PATCH 07/16] riscv: Remove unused define in maix header This define was left over from a previous revision, and was never used. Signed-off-by: Sean Anderson Reviewed-by: Heinrich Schuchardt Reviewed-by: Bin Meng --- include/configs/sipeed-maix.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/configs/sipeed-maix.h b/include/configs/sipeed-maix.h index 08acb25075b..4c1ff98ec6e 100644 --- a/include/configs/sipeed-maix.h +++ b/include/configs/sipeed-maix.h @@ -18,9 +18,6 @@ /* Don't relocate into AI ram since it isn't set up yet */ #define CONFIG_SYS_SDRAM_SIZE (SZ_4M + SZ_2M) -/* For early init */ -#define K210_SYSCTL_BASE 0x50440000 - #ifndef CONFIG_EXTRA_ENV_SETTINGS #define CONFIG_EXTRA_ENV_SETTINGS \ "loadaddr=0x80060000\0" \ From be5c442a1557ec6b2ffd06538cb40562f5d19b47 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sat, 6 Mar 2021 08:20:32 +0000 Subject: [PATCH 08/16] configs: EXT4, FAT, hush shell, env on S-mode MAIX * enable storing the environment in the SPI flash * enable EXT4 and FAT file system * enable hush shell * run k210_bootcmd as default boot command Signed-off-by: Heinrich Schuchardt Reviewed-by: Sean Anderson --- configs/sipeed_maix_smode_defconfig | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/configs/sipeed_maix_smode_defconfig b/configs/sipeed_maix_smode_defconfig index 2516bb72582..c20c389cace 100644 --- a/configs/sipeed_maix_smode_defconfig +++ b/configs/sipeed_maix_smode_defconfig @@ -1,10 +1,21 @@ CONFIG_RISCV=y CONFIG_SYS_TEXT_BASE=0x80020000 +CONFIG_ENV_SIZE=0x1000 +CONFIG_ENV_OFFSET=0xfff000 +CONFIG_ENV_SECT_SIZE=0x1000 CONFIG_TARGET_SIPEED_MAIX=y CONFIG_ARCH_RV64I=y CONFIG_RISCV_SMODE=y CONFIG_STACK_SIZE=0x100000 +CONFIG_USE_BOOTCOMMAND=y +CONFIG_BOOTCOMMAND="run k210_bootcmd" +CONFIG_HUSH_PARSER=y +CONFIG_MTDIDS_DEFAULT="nor0=spi3:0" +CONFIG_MTDPARTS_DEFAULT="nor0:1M(u-boot),0x1000@0xfff000(env)" # CONFIG_NET is not set # CONFIG_INPUT is not set +CONFIG_SF_DEFAULT_BUS=3 # CONFIG_DM_ETH is not set +CONFIG_FS_EXT4=y +CONFIG_FS_FAT=y # CONFIG_EFI_UNICODE_CAPITALIZATION is not set From ae2d9506a36ce2a31b2865c7071e3d20aa633340 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 17 Mar 2021 11:10:58 +0800 Subject: [PATCH 09/16] riscv: sifive: Rename fu540 board to unleashed In preparation to add SiFive Unmatched board support, let's rename the existing fu540 board to unleashed. Signed-off-by: Bin Meng Reviewed-by: Leo Yu-Chi Liang --- arch/riscv/Kconfig | 6 +++--- arch/riscv/dts/Makefile | 2 +- board/sifive/{fu540 => unleashed}/Kconfig | 6 +++--- board/sifive/{fu540 => unleashed}/MAINTAINERS | 10 +++++----- board/sifive/{fu540 => unleashed}/Makefile | 2 +- board/sifive/{fu540 => unleashed}/spl.c | 0 board/sifive/{fu540/fu540.c => unleashed/unleashed.c} | 0 common/spl/Kconfig | 5 +++-- ...five_fu540_defconfig => sifive_unleashed_defconfig} | 2 +- doc/board/sifive/index.rst | 2 +- doc/board/sifive/{fu540.rst => unleashed.rst} | 0 drivers/ram/sifive/Kconfig | 2 +- drivers/reset/Kconfig | 2 +- include/configs/{sifive-fu540.h => sifive-unleashed.h} | 0 14 files changed, 20 insertions(+), 19 deletions(-) rename board/sifive/{fu540 => unleashed}/Kconfig (91%) rename board/sifive/{fu540 => unleashed}/MAINTAINERS (50%) rename board/sifive/{fu540 => unleashed}/Makefile (87%) rename board/sifive/{fu540 => unleashed}/spl.c (100%) rename board/sifive/{fu540/fu540.c => unleashed/unleashed.c} (100%) rename configs/{sifive_fu540_defconfig => sifive_unleashed_defconfig} (95%) rename doc/board/sifive/{fu540.rst => unleashed.rst} (100%) rename include/configs/{sifive-fu540.h => sifive-unleashed.h} (100%) diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 55eaee2da63..e8494c2a496 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -17,8 +17,8 @@ config TARGET_MICROCHIP_ICICLE config TARGET_QEMU_VIRT bool "Support QEMU Virt Board" -config TARGET_SIFIVE_FU540 - bool "Support SiFive FU540 Board" +config TARGET_SIFIVE_UNLEASHED + bool "Support SiFive Unleashed Board" config TARGET_SIPEED_MAIX bool "Support Sipeed Maix Board" @@ -55,7 +55,7 @@ config SPL_SYS_DCACHE_OFF source "board/AndesTech/ax25-ae350/Kconfig" source "board/emulation/qemu-riscv/Kconfig" source "board/microchip/mpfs_icicle/Kconfig" -source "board/sifive/fu540/Kconfig" +source "board/sifive/unleashed/Kconfig" source "board/sipeed/maix/Kconfig" # platform-specific options below diff --git a/arch/riscv/dts/Makefile b/arch/riscv/dts/Makefile index 01331b0aa19..8138d89d841 100644 --- a/arch/riscv/dts/Makefile +++ b/arch/riscv/dts/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0+ dtb-$(CONFIG_TARGET_AX25_AE350) += ae350_32.dtb ae350_64.dtb -dtb-$(CONFIG_TARGET_SIFIVE_FU540) += hifive-unleashed-a00.dtb +dtb-$(CONFIG_TARGET_SIFIVE_UNLEASHED) += hifive-unleashed-a00.dtb dtb-$(CONFIG_TARGET_SIPEED_MAIX) += k210-maix-bit.dtb dtb-$(CONFIG_TARGET_MICROCHIP_ICICLE) += microchip-mpfs-icicle-kit.dtb diff --git a/board/sifive/fu540/Kconfig b/board/sifive/unleashed/Kconfig similarity index 91% rename from board/sifive/fu540/Kconfig rename to board/sifive/unleashed/Kconfig index 64fdbd44b4a..dbffd59c98e 100644 --- a/board/sifive/fu540/Kconfig +++ b/board/sifive/unleashed/Kconfig @@ -1,7 +1,7 @@ -if TARGET_SIFIVE_FU540 +if TARGET_SIFIVE_UNLEASHED config SYS_BOARD - default "fu540" + default "unleashed" config SYS_VENDOR default "sifive" @@ -10,7 +10,7 @@ config SYS_CPU default "fu540" config SYS_CONFIG_NAME - default "sifive-fu540" + default "sifive-unleashed" config SYS_TEXT_BASE default 0x80200000 if SPL diff --git a/board/sifive/fu540/MAINTAINERS b/board/sifive/unleashed/MAINTAINERS similarity index 50% rename from board/sifive/fu540/MAINTAINERS rename to board/sifive/unleashed/MAINTAINERS index 27620727bd9..2ea00749cb5 100644 --- a/board/sifive/fu540/MAINTAINERS +++ b/board/sifive/unleashed/MAINTAINERS @@ -1,10 +1,10 @@ -SiFive FU540 BOARD +SiFive HiFive Unleashed BOARD M: Paul Walmsley M: Palmer Dabbelt M: Anup Patel M: Atish Patra S: Maintained -F: board/sifive/fu540/ -F: doc/board/sifive/fu540.rst -F: include/configs/sifive-fu540.h -F: configs/sifive_fu540_defconfig +F: board/sifive/unleashed/ +F: doc/board/sifive/unleashed.rst +F: include/configs/sifive-unleashed.h +F: configs/sifive_unleashed_defconfig diff --git a/board/sifive/fu540/Makefile b/board/sifive/unleashed/Makefile similarity index 87% rename from board/sifive/fu540/Makefile rename to board/sifive/unleashed/Makefile index b05e2f58078..5821679dd92 100644 --- a/board/sifive/fu540/Makefile +++ b/board/sifive/unleashed/Makefile @@ -2,7 +2,7 @@ # # Copyright (c) 2019 Western Digital Corporation or its affiliates. -obj-y += fu540.o +obj-y += unleashed.o ifdef CONFIG_SPL_BUILD obj-y += spl.o diff --git a/board/sifive/fu540/spl.c b/board/sifive/unleashed/spl.c similarity index 100% rename from board/sifive/fu540/spl.c rename to board/sifive/unleashed/spl.c diff --git a/board/sifive/fu540/fu540.c b/board/sifive/unleashed/unleashed.c similarity index 100% rename from board/sifive/fu540/fu540.c rename to board/sifive/unleashed/unleashed.c diff --git a/common/spl/Kconfig b/common/spl/Kconfig index 0711cbf9517..0f528f346f3 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -330,7 +330,8 @@ config SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR ARCH_MX6 || ARCH_MX7 || \ ARCH_ROCKCHIP || ARCH_MVEBU || ARCH_SOCFPGA || \ ARCH_AT91 || ARCH_ZYNQ || ARCH_KEYSTONE || OMAP34XX || \ - OMAP44XX || OMAP54XX || AM33XX || AM43XX || TARGET_SIFIVE_FU540 + OMAP44XX || OMAP54XX || AM33XX || AM43XX || \ + TARGET_SIFIVE_UNLEASHED help Use sector number for specifying U-Boot location on MMC/SD in raw mode. @@ -347,7 +348,7 @@ config SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR default 0x300 if ARCH_ZYNQ || ARCH_KEYSTONE || OMAP34XX || OMAP44XX || \ OMAP54XX || AM33XX || AM43XX || ARCH_K3 default 0x4000 if ARCH_ROCKCHIP - default 0x822 if TARGET_SIFIVE_FU540 + default 0x822 if TARGET_SIFIVE_UNLEASHED help Address on the MMC to load U-Boot from, when the MMC is being used in raw mode. Units: MMC sectors (1 sector = 512 bytes). diff --git a/configs/sifive_fu540_defconfig b/configs/sifive_unleashed_defconfig similarity index 95% rename from configs/sifive_fu540_defconfig rename to configs/sifive_unleashed_defconfig index cabd3b17782..62416a7c1d8 100644 --- a/configs/sifive_fu540_defconfig +++ b/configs/sifive_unleashed_defconfig @@ -8,7 +8,7 @@ CONFIG_SPL=y CONFIG_SPL_SPI_FLASH_SUPPORT=y CONFIG_SPL_SPI_SUPPORT=y CONFIG_DEFAULT_DEVICE_TREE="hifive-unleashed-a00" -CONFIG_TARGET_SIFIVE_FU540=y +CONFIG_TARGET_SIFIVE_UNLEASHED=y CONFIG_ARCH_RV64I=y CONFIG_RISCV_SMODE=y CONFIG_DISTRO_DEFAULTS=y diff --git a/doc/board/sifive/index.rst b/doc/board/sifive/index.rst index ad614c9bf2a..ed7eacfb54d 100644 --- a/doc/board/sifive/index.rst +++ b/doc/board/sifive/index.rst @@ -6,4 +6,4 @@ SiFive .. toctree:: :maxdepth: 2 - fu540 + unleashed diff --git a/doc/board/sifive/fu540.rst b/doc/board/sifive/unleashed.rst similarity index 100% rename from doc/board/sifive/fu540.rst rename to doc/board/sifive/unleashed.rst diff --git a/drivers/ram/sifive/Kconfig b/drivers/ram/sifive/Kconfig index 6aca22ab2ab..08de692e026 100644 --- a/drivers/ram/sifive/Kconfig +++ b/drivers/ram/sifive/Kconfig @@ -8,6 +8,6 @@ config RAM_SIFIVE config SIFIVE_FU540_DDR bool "SiFive FU540 DDR driver" depends on RAM_SIFIVE - default y if TARGET_SIFIVE_FU540 + default y if TARGET_SIFIVE_UNLEASHED help This enables DDR support for the platforms based on SiFive FU540 SoC. diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index f5b3f8826fb..019565f9796 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -166,7 +166,7 @@ config RESET_IPQ419 config RESET_SIFIVE bool "Reset Driver for SiFive SoC's" - depends on DM_RESET && CLK_SIFIVE_FU540_PRCI && TARGET_SIFIVE_FU540 + depends on DM_RESET && CLK_SIFIVE_FU540_PRCI && TARGET_SIFIVE_UNLEASHED default y help PRCI module within SiFive SoC's provides mechanism to reset diff --git a/include/configs/sifive-fu540.h b/include/configs/sifive-unleashed.h similarity index 100% rename from include/configs/sifive-fu540.h rename to include/configs/sifive-unleashed.h From a718e2aed52a135f7a6a8745a49e4f5bdff49ecf Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Tue, 23 Mar 2021 19:11:26 +0100 Subject: [PATCH 10/16] riscv: simplify longjmp The value returned by setjmp must be nonzero. If zero is passed as parameter it must be replaced by 1. This patch reduces the code size a bit. Signed-off-by: Heinrich Schuchardt Reviewed-by: Sean Anderson Reviewed-by: Leo Yu-Chi Liang --- arch/riscv/lib/setjmp.S | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/arch/riscv/lib/setjmp.S b/arch/riscv/lib/setjmp.S index 72bc9241f6a..99d6195827e 100644 --- a/arch/riscv/lib/setjmp.S +++ b/arch/riscv/lib/setjmp.S @@ -54,12 +54,8 @@ ENTRY(longjmp) LOAD_IDX(sp, 13) /* Move the return value in place, but return 1 if passed 0. */ - beq a1, zero, longjmp_1 - mv a0, a1 - ret - - longjmp_1: - li a0, 1 + seqz a0, a1 + add a0, a0, a1 ret ENDPROC(longjmp) .popsection From f709a0b6f9c986e2a921435d095fc498949b53fa Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Tue, 23 Mar 2021 19:11:27 +0100 Subject: [PATCH 11/16] test: unit test for longjmp Provide a unit test for the longjmp() library function Signed-off-by: Heinrich Schuchardt Acked-by: Sean Anderson --- test/lib/Makefile | 1 + test/lib/longjmp.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 test/lib/longjmp.c diff --git a/test/lib/Makefile b/test/lib/Makefile index 97c11e35a88..a30f615aa9c 100644 --- a/test/lib/Makefile +++ b/test/lib/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_EFI_LOADER) += efi_device_path.o obj-$(CONFIG_EFI_SECURE_BOOT) += efi_image_region.o obj-y += hexdump.o obj-y += lmb.o +obj-y += longjmp.o obj-$(CONFIG_CONSOLE_RECORD) += test_print.o obj-$(CONFIG_SSCANF) += sscanf.o obj-y += string.o diff --git a/test/lib/longjmp.c b/test/lib/longjmp.c new file mode 100644 index 00000000000..201367a5a3a --- /dev/null +++ b/test/lib/longjmp.c @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Test setjmp(), longjmp() + * + * Copyright (c) 2021, Heinrich Schuchardt + */ + +#include +#include +#include +#include +#include + +struct test_jmp_buf { + jmp_buf env; + int val; +}; + +/** + * test_longjmp() - test longjmp function + * + * @i is passed to longjmp. + * @i << 8 is set in the environment structure. + * + * @env: environment + * @i: value passed to longjmp() + */ +static noinline void test_longjmp(struct test_jmp_buf *env, int i) +{ + env->val = i << 8; + longjmp(env->env, i); +} + +/** + * test_setjmp() - test setjmp function + * + * setjmp() will return the value @i passed to longjmp() if @i is non-zero. + * For @i == 0 we expect return value 1. + * + * @i << 8 will be set by test_longjmp in the environment structure. + * This value can be used to check that the stack frame is restored. + * + * We return the XORed values to allow simply check both at once. + * + * @i: value passed to longjmp() + * Return: values return by longjmp() + */ +static int test_setjmp(int i) +{ + struct test_jmp_buf env; + int ret; + + env.val = -1; + ret = setjmp(env.env); + if (ret) + return ret ^ env.val; + test_longjmp(&env, i); + /* We should not arrive here */ + return 0x1000; +} + +static int lib_test_longjmp(struct unit_test_state *uts) +{ + int i; + + for (i = -3; i < 0; ++i) + ut_asserteq(i ^ (i << 8), test_setjmp(i)); + ut_asserteq(1, test_setjmp(0)); + for (i = 1; i < 4; ++i) + ut_asserteq(i ^ (i << 8), test_setjmp(i)); + return 0; +} +LIB_TEST(lib_test_longjmp, 0); From 8f0dc4cfd106edbb8f8efb4583b33ecd52610e6c Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sat, 27 Mar 2021 12:37:04 +0100 Subject: [PATCH 12/16] riscv: assembler versions of memcpy, memmove, memset Provide optimized versions of memcpy(), memmove(), memset() copied from the Linux kernel. Signed-off-by: Heinrich Schuchardt Reviewed-by: Leo Yu-Chi Liang --- arch/riscv/Kconfig | 78 ++++++++++++++++++++++ arch/riscv/include/asm/string.h | 38 +++++------ arch/riscv/lib/Makefile | 4 ++ arch/riscv/lib/memcpy.S | 108 ++++++++++++++++++++++++++++++ arch/riscv/lib/memmove.S | 64 ++++++++++++++++++ arch/riscv/lib/memset.S | 113 ++++++++++++++++++++++++++++++++ 6 files changed, 383 insertions(+), 22 deletions(-) create mode 100644 arch/riscv/lib/memcpy.S create mode 100644 arch/riscv/lib/memmove.S create mode 100644 arch/riscv/lib/memset.S diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index e8494c2a496..3f221dccdb3 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -271,4 +271,82 @@ config STACK_SIZE_SHIFT config OF_BOARD_FIXUP default y if OF_SEPARATE && RISCV_SMODE +config USE_ARCH_MEMCPY + bool "Use an assembly optimized implementation of memcpy" + default y + help + Enable the generation of an optimized version of memcpy. + Such an implementation may be faster under some conditions + but may increase the binary size. + +config SPL_USE_ARCH_MEMCPY + bool "Use an assembly optimized implementation of memcpy for SPL" + default y if USE_ARCH_MEMCPY + depends on SPL + help + Enable the generation of an optimized version of memcpy. + Such an implementation may be faster under some conditions + but may increase the binary size. + +config TPL_USE_ARCH_MEMCPY + bool "Use an assembly optimized implementation of memcpy for TPL" + default y if USE_ARCH_MEMCPY + depends on TPL + help + Enable the generation of an optimized version of memcpy. + Such an implementation may be faster under some conditions + but may increase the binary size. + +config USE_ARCH_MEMMOVE + bool "Use an assembly optimized implementation of memmove" + default y + help + Enable the generation of an optimized version of memmove. + Such an implementation may be faster under some conditions + but may increase the binary size. + +config SPL_USE_ARCH_MEMMOVE + bool "Use an assembly optimized implementation of memmove for SPL" + default y if USE_ARCH_MEMCPY + depends on SPL + help + Enable the generation of an optimized version of memmove. + Such an implementation may be faster under some conditions + but may increase the binary size. + +config TPL_USE_ARCH_MEMMOVE + bool "Use an assembly optimized implementation of memmove for TPL" + default y if USE_ARCH_MEMCPY + depends on TPL + help + Enable the generation of an optimized version of memmove. + Such an implementation may be faster under some conditions + but may increase the binary size. + +config USE_ARCH_MEMSET + bool "Use an assembly optimized implementation of memset" + default y + help + Enable the generation of an optimized version of memset. + Such an implementation may be faster under some conditions + but may increase the binary size. + +config SPL_USE_ARCH_MEMSET + bool "Use an assembly optimized implementation of memset for SPL" + default y if USE_ARCH_MEMSET + depends on SPL + help + Enable the generation of an optimized version of memset. + Such an implementation may be faster under some conditions + but may increase the binary size. + +config TPL_USE_ARCH_MEMSET + bool "Use an assembly optimized implementation of memset for TPL" + default y if USE_ARCH_MEMSET + depends on TPL + help + Enable the generation of an optimized version of memset. + Such an implementation may be faster under some conditions + but may increase the binary size. + endmenu diff --git a/arch/riscv/include/asm/string.h b/arch/riscv/include/asm/string.h index 0fc3424a2f1..7dee3e4c9f6 100644 --- a/arch/riscv/include/asm/string.h +++ b/arch/riscv/include/asm/string.h @@ -19,31 +19,25 @@ #undef __HAVE_ARCH_STRRCHR #undef __HAVE_ARCH_STRCHR -#undef __HAVE_ARCH_MEMCPY -#undef __HAVE_ARCH_MEMMOVE #undef __HAVE_ARCH_MEMCHR #undef __HAVE_ARCH_MEMZERO -#undef __HAVE_ARCH_MEMSET -#ifdef CONFIG_MARCO_MEMSET -#define memset(_p, _v, _n) \ - (typeof(_p) (p) = (_p); \ - typeof(_v) (v) = (_v); \ - typeof(_n) (n) = (_n); \ - { \ - if ((n) != 0) { \ - if (__builtin_constant_p((v)) && (v) == 0) \ - __memzero((p), (n)); \ - else \ - memset((p), (v), (n)); \ - } \ - (p); \ - }) - -#define memzero(_p, _n) \ - (typeof(_p) (p) = (_p); \ - typeof(_n) (n) = (_n); \ - { if ((n) != 0) __memzero((p), (n)); (p); }) +#undef __HAVE_ARCH_MEMCPY +#if CONFIG_IS_ENABLED(USE_ARCH_MEMCPY) +#define __HAVE_ARCH_MEMCPY #endif +extern void *memcpy(void *, const void *, __kernel_size_t); + +#undef __HAVE_ARCH_MEMMOVE +#if CONFIG_IS_ENABLED(USE_ARCH_MEMMOVE) +#define __HAVE_ARCH_MEMMOVE +#endif +extern void *memmove(void *, const void *, __kernel_size_t); + +#undef __HAVE_ARCH_MEMZERO +#if CONFIG_IS_ENABLED(USE_ARCH_MEMSET) +#define __HAVE_ARCH_MEMSET +#endif +extern void *memset(void *, int, __kernel_size_t); #endif /* __ASM_RISCV_STRING_H */ diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile index 12c14f20198..ff0677aa966 100644 --- a/arch/riscv/lib/Makefile +++ b/arch/riscv/lib/Makefile @@ -36,3 +36,7 @@ CFLAGS_REMOVE_$(EFI_RELOC) := $(CFLAGS_NON_EFI) extra-$(CONFIG_CMD_BOOTEFI_HELLO_COMPILE) += $(EFI_CRT0) $(EFI_RELOC) extra-$(CONFIG_CMD_BOOTEFI_SELFTEST) += $(EFI_CRT0) $(EFI_RELOC) extra-$(CONFIG_EFI) += $(EFI_CRT0) $(EFI_RELOC) + +obj-$(CONFIG_$(SPL_TPL_)USE_ARCH_MEMSET) += memset.o +obj-$(CONFIG_$(SPL_TPL_)USE_ARCH_MEMMOVE) += memmove.o +obj-$(CONFIG_$(SPL_TPL_)USE_ARCH_MEMCPY) += memcpy.o diff --git a/arch/riscv/lib/memcpy.S b/arch/riscv/lib/memcpy.S new file mode 100644 index 00000000000..51ab716253f --- /dev/null +++ b/arch/riscv/lib/memcpy.S @@ -0,0 +1,108 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2013 Regents of the University of California + */ + +#include +#include + +/* void *memcpy(void *, const void *, size_t) */ +ENTRY(__memcpy) +WEAK(memcpy) + move t6, a0 /* Preserve return value */ + + /* Defer to byte-oriented copy for small sizes */ + sltiu a3, a2, 128 + bnez a3, 4f + /* Use word-oriented copy only if low-order bits match */ + andi a3, t6, SZREG-1 + andi a4, a1, SZREG-1 + bne a3, a4, 4f + + beqz a3, 2f /* Skip if already aligned */ + /* + * Round to nearest double word-aligned address + * greater than or equal to start address + */ + andi a3, a1, ~(SZREG-1) + addi a3, a3, SZREG + /* Handle initial misalignment */ + sub a4, a3, a1 +1: + lb a5, 0(a1) + addi a1, a1, 1 + sb a5, 0(t6) + addi t6, t6, 1 + bltu a1, a3, 1b + sub a2, a2, a4 /* Update count */ + +2: + andi a4, a2, ~((16*SZREG)-1) + beqz a4, 4f + add a3, a1, a4 +3: + REG_L a4, 0(a1) + REG_L a5, SZREG(a1) + REG_L a6, 2*SZREG(a1) + REG_L a7, 3*SZREG(a1) + REG_L t0, 4*SZREG(a1) + REG_L t1, 5*SZREG(a1) + REG_L t2, 6*SZREG(a1) + REG_L t3, 7*SZREG(a1) + REG_L t4, 8*SZREG(a1) + REG_L t5, 9*SZREG(a1) + REG_S a4, 0(t6) + REG_S a5, SZREG(t6) + REG_S a6, 2*SZREG(t6) + REG_S a7, 3*SZREG(t6) + REG_S t0, 4*SZREG(t6) + REG_S t1, 5*SZREG(t6) + REG_S t2, 6*SZREG(t6) + REG_S t3, 7*SZREG(t6) + REG_S t4, 8*SZREG(t6) + REG_S t5, 9*SZREG(t6) + REG_L a4, 10*SZREG(a1) + REG_L a5, 11*SZREG(a1) + REG_L a6, 12*SZREG(a1) + REG_L a7, 13*SZREG(a1) + REG_L t0, 14*SZREG(a1) + REG_L t1, 15*SZREG(a1) + addi a1, a1, 16*SZREG + REG_S a4, 10*SZREG(t6) + REG_S a5, 11*SZREG(t6) + REG_S a6, 12*SZREG(t6) + REG_S a7, 13*SZREG(t6) + REG_S t0, 14*SZREG(t6) + REG_S t1, 15*SZREG(t6) + addi t6, t6, 16*SZREG + bltu a1, a3, 3b + andi a2, a2, (16*SZREG)-1 /* Update count */ + +4: + /* Handle trailing misalignment */ + beqz a2, 6f + add a3, a1, a2 + + /* Use word-oriented copy if co-aligned to word boundary */ + or a5, a1, t6 + or a5, a5, a3 + andi a5, a5, 3 + bnez a5, 5f +7: + lw a4, 0(a1) + addi a1, a1, 4 + sw a4, 0(t6) + addi t6, t6, 4 + bltu a1, a3, 7b + + ret + +5: + lb a4, 0(a1) + addi a1, a1, 1 + sb a4, 0(t6) + addi t6, t6, 1 + bltu a1, a3, 5b +6: + ret +END(__memcpy) diff --git a/arch/riscv/lib/memmove.S b/arch/riscv/lib/memmove.S new file mode 100644 index 00000000000..07d1d2152ba --- /dev/null +++ b/arch/riscv/lib/memmove.S @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#include +#include + +ENTRY(__memmove) +WEAK(memmove) + move t0, a0 + move t1, a1 + + beq a0, a1, exit_memcpy + beqz a2, exit_memcpy + srli t2, a2, 0x2 + + slt t3, a0, a1 + beqz t3, do_reverse + + andi a2, a2, 0x3 + li t4, 1 + beqz t2, byte_copy + +word_copy: + lw t3, 0(a1) + addi t2, t2, -1 + addi a1, a1, 4 + sw t3, 0(a0) + addi a0, a0, 4 + bnez t2, word_copy + beqz a2, exit_memcpy + j byte_copy + +do_reverse: + add a0, a0, a2 + add a1, a1, a2 + andi a2, a2, 0x3 + li t4, -1 + beqz t2, reverse_byte_copy + +reverse_word_copy: + addi a1, a1, -4 + addi t2, t2, -1 + lw t3, 0(a1) + addi a0, a0, -4 + sw t3, 0(a0) + bnez t2, reverse_word_copy + beqz a2, exit_memcpy + +reverse_byte_copy: + addi a0, a0, -1 + addi a1, a1, -1 + +byte_copy: + lb t3, 0(a1) + addi a2, a2, -1 + sb t3, 0(a0) + add a1, a1, t4 + add a0, a0, t4 + bnez a2, byte_copy + +exit_memcpy: + move a0, t0 + move a1, t1 + ret +END(__memmove) diff --git a/arch/riscv/lib/memset.S b/arch/riscv/lib/memset.S new file mode 100644 index 00000000000..34c5360c670 --- /dev/null +++ b/arch/riscv/lib/memset.S @@ -0,0 +1,113 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2013 Regents of the University of California + */ + + +#include +#include + +/* void *memset(void *, int, size_t) */ +ENTRY(__memset) +WEAK(memset) + move t0, a0 /* Preserve return value */ + + /* Defer to byte-oriented fill for small sizes */ + sltiu a3, a2, 16 + bnez a3, 4f + + /* + * Round to nearest XLEN-aligned address + * greater than or equal to start address + */ + addi a3, t0, SZREG-1 + andi a3, a3, ~(SZREG-1) + beq a3, t0, 2f /* Skip if already aligned */ + /* Handle initial misalignment */ + sub a4, a3, t0 +1: + sb a1, 0(t0) + addi t0, t0, 1 + bltu t0, a3, 1b + sub a2, a2, a4 /* Update count */ + +2: /* Duff's device with 32 XLEN stores per iteration */ + /* Broadcast value into all bytes */ + andi a1, a1, 0xff + slli a3, a1, 8 + or a1, a3, a1 + slli a3, a1, 16 + or a1, a3, a1 +#ifdef CONFIG_64BIT + slli a3, a1, 32 + or a1, a3, a1 +#endif + + /* Calculate end address */ + andi a4, a2, ~(SZREG-1) + add a3, t0, a4 + + andi a4, a4, 31*SZREG /* Calculate remainder */ + beqz a4, 3f /* Shortcut if no remainder */ + neg a4, a4 + addi a4, a4, 32*SZREG /* Calculate initial offset */ + + /* Adjust start address with offset */ + sub t0, t0, a4 + + /* Jump into loop body */ + /* Assumes 32-bit instruction lengths */ + la a5, 3f +#ifdef CONFIG_64BIT + srli a4, a4, 1 +#endif + add a5, a5, a4 + jr a5 +3: + REG_S a1, 0(t0) + REG_S a1, SZREG(t0) + REG_S a1, 2*SZREG(t0) + REG_S a1, 3*SZREG(t0) + REG_S a1, 4*SZREG(t0) + REG_S a1, 5*SZREG(t0) + REG_S a1, 6*SZREG(t0) + REG_S a1, 7*SZREG(t0) + REG_S a1, 8*SZREG(t0) + REG_S a1, 9*SZREG(t0) + REG_S a1, 10*SZREG(t0) + REG_S a1, 11*SZREG(t0) + REG_S a1, 12*SZREG(t0) + REG_S a1, 13*SZREG(t0) + REG_S a1, 14*SZREG(t0) + REG_S a1, 15*SZREG(t0) + REG_S a1, 16*SZREG(t0) + REG_S a1, 17*SZREG(t0) + REG_S a1, 18*SZREG(t0) + REG_S a1, 19*SZREG(t0) + REG_S a1, 20*SZREG(t0) + REG_S a1, 21*SZREG(t0) + REG_S a1, 22*SZREG(t0) + REG_S a1, 23*SZREG(t0) + REG_S a1, 24*SZREG(t0) + REG_S a1, 25*SZREG(t0) + REG_S a1, 26*SZREG(t0) + REG_S a1, 27*SZREG(t0) + REG_S a1, 28*SZREG(t0) + REG_S a1, 29*SZREG(t0) + REG_S a1, 30*SZREG(t0) + REG_S a1, 31*SZREG(t0) + addi t0, t0, 32*SZREG + bltu t0, a3, 3b + andi a2, a2, SZREG-1 /* Update count */ + +4: + /* Handle trailing misalignment */ + beqz a2, 6f + add a3, t0, a2 +5: + sb a1, 0(t0) + addi t0, t0, 1 + bltu t0, a3, 5b +6: + ret +END(__memset) From 9c02e50fa10982a9500503a0075307179d481388 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Sat, 27 Mar 2021 19:57:35 +0800 Subject: [PATCH 13/16] timer: sifive_clint: Support the official clint DT bindings Linux kernel commit a2770b57d083 ("dt-bindings: timer: Add CLINT bindings") adds the official DT bindings for CLINT, which uses "sifive,clint0" as the compatible string. "riscv,clint0" is now legacy and has to be kept for backward compatibility of legacy systems. Signed-off-by: Bin Meng Reviewed-by: Leo Yu-Chi Liang --- drivers/timer/sifive_clint_timer.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/timer/sifive_clint_timer.c b/drivers/timer/sifive_clint_timer.c index de7b4b95c9e..939b99d937d 100644 --- a/drivers/timer/sifive_clint_timer.c +++ b/drivers/timer/sifive_clint_timer.c @@ -54,6 +54,7 @@ static int sifive_clint_probe(struct udevice *dev) static const struct udevice_id sifive_clint_ids[] = { { .compatible = "riscv,clint0" }, + { .compatible = "sifive,clint0" }, { } }; From e9b62617fa7783b2eb2ab055bbb46035fd12167c Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 31 Mar 2021 15:24:48 +0800 Subject: [PATCH 14/16] riscv: mpfs-icicle-kit: Increase SYS_MALLOC_F_LEN The RISC-V architecture default value of CONFIG_SYS_MALLOC_F_LEN (0x1000) would not provide enough memory for devices like mpfs clock and ns16550 serial to bind well before relocation. Signed-off-by: Bin Meng Reviewed-by: Padmarao Begari Tested-by: Padmarao Begari --- configs/microchip_mpfs_icicle_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/microchip_mpfs_icicle_defconfig b/configs/microchip_mpfs_icicle_defconfig index 0c15c3bd38c..1cb29201b42 100644 --- a/configs/microchip_mpfs_icicle_defconfig +++ b/configs/microchip_mpfs_icicle_defconfig @@ -1,4 +1,5 @@ CONFIG_RISCV=y +CONFIG_SYS_MALLOC_F_LEN=0x2000 CONFIG_ENV_SIZE=0x2000 CONFIG_DEFAULT_DEVICE_TREE="microchip-mpfs-icicle-kit" CONFIG_TARGET_MICROCHIP_ICICLE=y From 53a97d22f1670f31794a2336d8fecaffeee7ffde Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 31 Mar 2021 15:24:49 +0800 Subject: [PATCH 15/16] clk: mpfs_clk: Enable DM_FLAG_PRE_RELOC flag This driver is needed in the pre-relocation phase as the serial driver depends on it. Signed-off-by: Bin Meng Reviewed-by: Padmarao Begari Tested-by: Padmarao Begari --- drivers/clk/microchip/mpfs_clk.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/microchip/mpfs_clk.c b/drivers/clk/microchip/mpfs_clk.c index 722c79b7c0e..05d7647206c 100644 --- a/drivers/clk/microchip/mpfs_clk.c +++ b/drivers/clk/microchip/mpfs_clk.c @@ -120,4 +120,5 @@ U_BOOT_DRIVER(mpfs_clk) = { .ops = &mpfs_clk_ops, .probe = mpfs_clk_probe, .priv_auto = sizeof(struct clk), + .flags = DM_FLAG_PRE_RELOC, }; From e7bb113cc4d03aeb573ff938a1d897d4b3ca99df Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Wed, 31 Mar 2021 15:24:50 +0800 Subject: [PATCH 16/16] riscv: dts: mpfs-icicle-kit: Drop 'clock-frequency' in the uart nodes The uart nodes already provide property for the driver to dynamically calculate the correct clock frequency. There is no need to keep the hard-coded property. Signed-off-by: Bin Meng Reviewed-by: Padmarao Begari Tested-by: Padmarao Begari --- arch/riscv/dts/microchip-mpfs-icicle-kit.dts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/arch/riscv/dts/microchip-mpfs-icicle-kit.dts b/arch/riscv/dts/microchip-mpfs-icicle-kit.dts index e2b9decc941..89c4cf5fb2b 100644 --- a/arch/riscv/dts/microchip-mpfs-icicle-kit.dts +++ b/arch/riscv/dts/microchip-mpfs-icicle-kit.dts @@ -232,7 +232,6 @@ reg-shift = <2>; interrupt-parent = <&plic>; interrupts = <90>; - clock-frequency = <150000000>; clocks = <&clkcfg CLK_MMUART0>; status = "okay"; }; @@ -294,7 +293,6 @@ reg-shift = <2>; interrupt-parent = <&plic>; interrupts = <91>; - clock-frequency = <150000000>; clocks = <&clkcfg CLK_MMUART1>; status = "okay"; }; @@ -305,7 +303,6 @@ reg-shift = <2>; interrupt-parent = <&plic>; interrupts = <92>; - clock-frequency = <150000000>; clocks = <&clkcfg CLK_MMUART2>; status = "okay"; }; @@ -316,7 +313,6 @@ reg-shift = <2>; interrupt-parent = <&plic>; interrupts = <93>; - clock-frequency = <150000000>; clocks = <&clkcfg CLK_MMUART3>; status = "okay"; };