[PATCH] tools/nolibc: add 64-bit parisc support
Thomas Weißschuh <[email protected]>
| Newsgroups | org.kernel.vger.linux-parisc,org.kernel.vger.linux-kernel,org.kernel.vger.linux-kselftest |
|---|---|
| Message-ID | <[email protected]> |
Extend the existing parisc support to also handle 64-bit mode. Some peculiarities: * The nonstandard ftruncate64 system call requires a workaround. * The linker defaults to main() as entry point, which needs to be switched to _start() explicitly. * The linker defaults to dynamic linking, which needs to be disabled explicitly. * With the default -Os, gcc does not use 64-bit multiplication instructions, requiring libgcc. Use -O2 instead. * There is no qemu-user available. * CONFIG_COMPAT needs to be disabled to avoid build errors due to a missing 32-bit vDSO compiler. Signed-off-by: Thomas Weißschuh <[email protected]> --- tools/include/nolibc/arch-parisc.h | 26 +++++++++++++++++++++++--- tools/include/nolibc/stdlib.h | 2 +- tools/testing/selftests/nolibc/Makefile.nolibc | 5 +++++ tools/testing/selftests/nolibc/run-tests.sh | 7 ++++--- 4 files changed, 33 insertions(+), 7 deletions(-) diff --git a/tools/include/nolibc/arch-parisc.h b/tools/include/nolibc/arch-parisc.h index 417043ecbc53..fd0d1dccabf3 100644 --- a/tools/include/nolibc/arch-parisc.h +++ b/tools/include/nolibc/arch-parisc.h @@ -7,9 +7,7 @@ #ifndef _NOLIBC_ARCH_PARISC_H #define _NOLIBC_ARCH_PARISC_H -#if defined(__LP64__) -#error 64-bit not supported -#endif +#include <linux/unistd.h> #include "compiler.h" #include "crt.h" @@ -167,9 +165,15 @@ void __attribute__((weak, noreturn)) __nolibc_entrypoint __nolibc_no_stack_protector _start(void) { __asm__ volatile ( +#ifdef __LP64__ + ".import __gp\n" /* Set up the dp register */ + "ldil L%__gp, %dp\n" + "ldo R%__gp(%r27), %dp\n" +#else ".import $global$\n" /* Set up the dp register */ "ldil L%$global$, %dp\n" "ldo R%$global$(%r27), %dp\n" +#endif "b _start_c\n" /* Call _start_c, the load below is executed first */ @@ -182,4 +186,20 @@ void __attribute__((weak, noreturn)) __nolibc_entrypoint __nolibc_no_stack_prote } #endif /* NOLIBC_NO_RUNTIME */ +#ifdef __LP64__ +/* + * This override is normally only meant for 32-bit architectures. + * Put parisc 64-bit has __NR_ftruncate64, so this path is taken. + * Add an unused second argument to satisfy the calling convention. + */ +static __attribute__((unused)) +int _sys_ftruncate64(int fd, uint64_t length, uint64_t unused) +{ + (void)unused; + + return __nolibc_syscall2(__NR_ftruncate64, fd, length); +} +#define _sys_ftruncate64 _sys_ftruncate64 +#endif + #endif /* _NOLIBC_ARCH_PARISC_H */ diff --git a/tools/include/nolibc/stdlib.h b/tools/include/nolibc/stdlib.h index 1816c2368b68..6c3c620a04cf 100644 --- a/tools/include/nolibc/stdlib.h +++ b/tools/include/nolibc/stdlib.h @@ -230,7 +230,7 @@ int _nolibc_u64toa_base(uint64_t in, char *buffer, unsigned int base, uint64_t r /* Generate least significant digit first */ do { -#if defined(__SIZEOF_INT128__) && !defined(__mips__) && !defined(__sparc__) +#if defined(__SIZEOF_INT128__) && !defined(__mips__) && !defined(__sparc__) && !defined(__hppa__) q = ((unsigned __int128)in * recip) >> 64; #else uint64_t p = (uint32_t)in * (recip >> 32); diff --git a/tools/testing/selftests/nolibc/Makefile.nolibc b/tools/testing/selftests/nolibc/Makefile.nolibc index d8b71cbfc173..3ca473ec35ef 100644 --- a/tools/testing/selftests/nolibc/Makefile.nolibc +++ b/tools/testing/selftests/nolibc/Makefile.nolibc @@ -65,6 +65,7 @@ ARCH_sparc32 = sparc ARCH_sparc64 = sparc ARCH_sh4 = sh ARCH_parisc32 = parisc +ARCH_parisc64 = parisc64 ARCH := $(or $(ARCH_$(XARCH)),$(XARCH)) # kernel image names by architecture @@ -113,6 +114,7 @@ EXTRACONFIG_sparc32 = -e CONFIG_TMPFS EXTRACONFIG_m68k = -e CONFIG_BLK_DEV_INITRD EXTRACONFIG_sh4 = -e CONFIG_BLK_DEV_INITRD -e CONFIG_CMDLINE_FROM_BOOTLOADER EXTRACONFIG_alpha = -e CONFIG_BLK_DEV_INITRD +EXTRACONFIG_parisc64 = -d CONFIG_COMPAT EXTRACONFIG = $(EXTRACONFIG_$(XARCH)) # optional tests to run (default = all) @@ -134,6 +136,7 @@ QEMU_ARCH_loongarch = loongarch64 QEMU_ARCH_sparc32 = sparc QEMU_ARCH_openrisc = or1k QEMU_ARCH_parisc32 = hppa +QEMU_ARCH_parisc64 = hppa QEMU_ARCH = $(or $(QEMU_ARCH_$(XARCH)),$(XARCH)) QEMU_ARCH_USER_ppc64le = ppc64le @@ -175,6 +178,7 @@ QEMU_ARGS_m68k = -M virt -append "console=ttyGF0,115200 panic=-1 $(TEST:%= QEMU_ARGS_sh4 = -M r2d -serial file:/dev/stdout -append "console=ttySC1,115200 panic=-1 $(TEST:%=NOLIBC_TEST=%)" QEMU_ARGS_openrisc = -M virt -m 512M -append "console=ttyS0 panic=-1 $(TEST:%=NOLIBC_TEST=%)" QEMU_ARGS_parisc32 = -M B160L -append "console=ttyS0 panic=-1 $(TEST:%=NOLIBC_TEST=%)" +QEMU_ARGS_parisc64 = -M C3700 -append "console=ttyS0 panic=-1 $(TEST:%=NOLIBC_TEST=%)" QEMU_ARGS_alpha = -M clipper -append "console=ttyS0 panic=-1 $(TEST:%=NOLIBC_TEST=%)" QEMU_ARGS = -m 1G $(QEMU_ARGS_$(XARCH)) $(QEMU_ARGS_BIOS) $(QEMU_ARGS_EXTRA) @@ -193,6 +197,7 @@ CFLAGS_x32 = -mx32 CFLAGS_arm = -marm CFLAGS_armthumb = -mthumb -march=armv6t2 CFLAGS_parisc32 = -mfast-indirect-calls +CFLAGS_parisc64 = -Wl,--no-dynamic-linker -Wl,--entry=_start -O2 CFLAGS_ppc = -m32 -mbig-endian -mno-vsx $(call cc-option,-mmultiple) CFLAGS_ppc64 = -m64 -mbig-endian -mno-vsx $(call cc-option,-mmultiple) CFLAGS_ppc64le = -m64 -mlittle-endian -mno-vsx $(call cc-option,-mabi=elfv2) diff --git a/tools/testing/selftests/nolibc/run-tests.sh b/tools/testing/selftests/nolibc/run-tests.sh index 3da806e2b302..a50a47d9df2c 100755 --- a/tools/testing/selftests/nolibc/run-tests.sh +++ b/tools/testing/selftests/nolibc/run-tests.sh @@ -29,7 +29,7 @@ all_archs=( sparc32 sparc64 m68k sh4 - parisc32 + parisc32 parisc64 alpha hexagon ) @@ -122,6 +122,7 @@ crosstool_arch() { sparc*) echo sparc64;; x32*) echo x86_64;; parisc32) echo hppa;; + parisc64) echo hppa64;; *) echo "$1";; esac } @@ -206,11 +207,11 @@ test_arch() { exit 1 esac printf '%-15s' "$arch:" - if [ "$arch" = "m68k" -o "$arch" = "sh4" -o "$arch" = "openrisc" -o "$arch" = "parisc32" -o "$arch" = "alpha" ] && [ "$llvm" = "1" ]; then + if [ "$arch" = "m68k" -o "$arch" = "sh4" -o "$arch" = "openrisc" -o "$arch" = "parisc*" -o "$arch" = "alpha" ] && [ "$llvm" = "1" ]; then echo "Unsupported configuration" return fi - if [ "$arch" = "x32" ] && [ "$test_mode" = "user" ]; then + if [ "$arch" = "x32" -o "$arch" = "parisc64" ] && [ "$test_mode" = "user" ]; then echo "Unsupported configuration" return fi --- base-commit: 7f4233794df172ab1d286dc0fbd70da2cc837654 change-id: 20260407-nolibc-parisc64-3ca0547c2af9 Best regards, -- Thomas Weißschuh <[email protected]>