[PATCH v2 0/3] riscv: Fix build against binutils 2.38

Compiling for RISC-V with binutils 2.38 and binutils 2.37 requires different build flags. This is fixed by Alexandre Ghiti's patch. But building qemu-riscv32*_defconfig fails due to missing implementations of __ashldi3, __lshrdi3. Add these functions and a unit test for them.
Alexandre Ghiti (1): riscv: Fix build against binutils 2.38
Heinrich Schuchardt (2): riscv: implement __ashldi3, __lshrdi3 test: test bit shift operations on RISC-V
arch/riscv/Makefile | 11 ++++++- arch/riscv/lib/Makefile | 1 + arch/riscv/lib/bitops.S | 15 +++++++++ test/lib/Makefile | 2 ++ test/lib/bitops.c | 71 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 arch/riscv/lib/bitops.S create mode 100644 test/lib/bitops.c

On 32bit RISC-V calls to __ashrdi3 and __lshrdi3 are generated. These functions are normally provided by glibc but U-Boot is freestanding and needs its own implementation.
Signed-off-by: Heinrich Schuchardt heinrich.schuchardt@canonical.com --- v2: new patch --- arch/riscv/lib/Makefile | 1 + arch/riscv/lib/bitops.S | 15 +++++++++++++++ 2 files changed, 16 insertions(+) create mode 100644 arch/riscv/lib/bitops.S
diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile index 06020fcc2a..cfd7a47f65 100644 --- a/arch/riscv/lib/Makefile +++ b/arch/riscv/lib/Makefile @@ -6,6 +6,7 @@ # Copyright (C) 2017 Andes Technology Corporation # Rick Chen, Andes Technology Corporation rick@andestech.com
+obj-y += bitops.o obj-$(CONFIG_CMD_BOOTM) += bootm.o obj-$(CONFIG_CMD_BOOTI) += bootm.o image.o obj-$(CONFIG_CMD_GO) += boot.o diff --git a/arch/riscv/lib/bitops.S b/arch/riscv/lib/bitops.S new file mode 100644 index 0000000000..a2a1ab2376 --- /dev/null +++ b/arch/riscv/lib/bitops.S @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#include <config.h> +#include <linux/linkage.h> + +.pushsection .text.rvbitops, "ax" +ENTRY(__ashldi3) + sll a0, a0, a1 + ret +ENDPROC(__ashldi3) + +ENTRY(__lshrdi3) + srl a0, a0, a1 + ret +ENDPROC(__lshrdi3)

On Okt 01 2022, Heinrich Schuchardt wrote:
On 32bit RISC-V calls to __ashrdi3 and __lshrdi3 are generated. These functions are normally provided by glibc but U-Boot is freestanding
They are defined by libgcc, not glibc.

From: Alexandre Ghiti alexandre.ghiti@canonical.com
The following description is copied from the equivalent patch for the Linux Kernel proposed by Aurelien Jarno:
From version 2.38, binutils default to ISA spec version 20191213. This
means that the csr read/write (csrr*/csrw*) instructions and fence.i instruction has separated from the `I` extension, become two standalone extensions: Zicsr and Zifencei. As the kernel uses those instruction, this causes the following build failure:
arch/riscv/cpu/mtrap.S: Assembler messages: arch/riscv/cpu/mtrap.S:65: Error: unrecognized opcode `csrr a0,scause' arch/riscv/cpu/mtrap.S:66: Error: unrecognized opcode `csrr a1,sepc' arch/riscv/cpu/mtrap.S:67: Error: unrecognized opcode `csrr a2,stval' arch/riscv/cpu/mtrap.S:70: Error: unrecognized opcode `csrw sepc,a0'
Signed-off-by: Alexandre Ghiti alexandre.ghiti@canonical.com Reviewed-by: Bin Meng bmeng.cn@gmail.com Tested-by: Heinrich Schuchardt heinrich.schuchardt@canonical.com Tested-by: Heiko Stuebner heiko@sntech.de Tested-by: Christian Stewart christian@paral.in --- v2: no change --- arch/riscv/Makefile | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile index 0b80eb8d86..53d1194ffb 100644 --- a/arch/riscv/Makefile +++ b/arch/riscv/Makefile @@ -24,7 +24,16 @@ ifeq ($(CONFIG_CMODEL_MEDANY),y) CMODEL = medany endif
-ARCH_FLAGS = -march=$(ARCH_BASE)$(ARCH_A)$(ARCH_C) -mabi=$(ABI) \ +RISCV_MARCH = $(ARCH_BASE)$(ARCH_A)$(ARCH_C) + +# Newer binutils versions default to ISA spec version 20191213 which moves some +# instructions from the I extension to the Zicsr and Zifencei extensions. +toolchain-need-zicsr-zifencei := $(call cc-option-yn, -mabi=$(ABI) -march=$(RISCV_MARCH)_zicsr_zifencei) +ifeq ($(toolchain-need-zicsr-zifencei),y) + RISCV_MARCH := $(RISCV_MARCH)_zicsr_zifencei +endif + +ARCH_FLAGS = -march=$(RISCV_MARCH) -mabi=$(ABI) \ -mcmodel=$(CMODEL)
PLATFORM_CPPFLAGS += $(ARCH_FLAGS)

Add unit tests for library functions __ashldi3() and __lshrdi3).
Signed-off-by: Heinrich Schuchardt heinrich.schuchardt@canonical.com --- v2: new patch --- test/lib/Makefile | 2 ++ test/lib/bitops.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 test/lib/bitops.c
diff --git a/test/lib/Makefile b/test/lib/Makefile index 7e7922fe3b..ade934dab7 100644 --- a/test/lib/Makefile +++ b/test/lib/Makefile @@ -2,7 +2,9 @@ # # (C) Copyright 2018 # Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc + ifeq ($(CONFIG_SPL_BUILD),) +obj-$(CONFIG_RISCV) += bitops.o obj-y += cmd_ut_lib.o obj-y += abuf.o obj-$(CONFIG_EFI_LOADER) += efi_device_path.o diff --git a/test/lib/bitops.c b/test/lib/bitops.c new file mode 100644 index 0000000000..14813c34b5 --- /dev/null +++ b/test/lib/bitops.c @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include <test/lib.h> +#include <test/test.h> +#include <test/ut.h> + +long __ashldi3(long a, int b); +long __lshrdi3(long a, int b); + +/** + * lib_ashldi3() - unit test for __ashldi3() + * + * @uts: unit test state + * Return: 0 = success, 1 = failure + */ +static int lib_ashldi3(struct unit_test_state *uts) +{ + long actual, expected, val; + int bits = 4; + + switch (sizeof(long)) { + case 8: + val = (long)0xf6fa765251b9a6c7; + expected = (long)0x6fa765251b9a6c70; + break; + case 4: + val = 0x51b9a6c7; + expected = 0x1b9a6c70; + break; + default: + ut_assert(false); + } + + actual = __ashldi3(val, bits); + ut_asserteq(expected, actual); + + return 0; +} +LIB_TEST(lib_ashldi3, 0); + +/** + * lib_lshrdi3() - unit test for __lshrdi3() + * + * @uts: unit test state + * Return: 0 = success, 1 = failure + */ +static int lib_lshrdi3(struct unit_test_state *uts) +{ + long actual, expected, val; + int bits = 4; + + switch (sizeof(long)) { + case 8: + val = (long)0xf6fa765251b9a6c7; + expected = (long)0x0f6fa765251b9a6c; + break; + case 4: + val = 0x51b9a6c7; + expected = 0x051b9a6c; + break; + default: + ut_assert(false); + } + + actual = __lshrdi3(val, bits); + ut_asserteq(expected, actual); + + return 0; +} +LIB_TEST(lib_lshrdi3, 0);
participants (2)
-
Andreas Schwab
-
Heinrich Schuchardt