From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 426D63B95F6; Wed, 8 Apr 2026 22:15:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775686558; cv=none; b=Yie0yopUOkFNgQSTtcceYTegM4nt966ZC/eseLqQE6WRwzEjYGmp1WW6mrCJ6IIIOCZxM/f8bC0Ny3F9XG/iEKfXGbK+X3oZp/QtCkzPIThz36sX+s418pu6usfnIwMXbk9G06Ktmb6QYea4d7yJord8034D8ulQXE1RzskeM+0= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775686558; c=relaxed/simple; bh=LzcoftNwHznWMpp3niM08QmPU3gWbRJcspRmkILRoWI=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=OBx9MWXQWLhAK2TRy0h/+Fln7Igs+LSRfHi4ZJHbogztsPwNWP9/GKsrEw4B2SiBxWyfY4JpUEHIuAPYYcYTp4U5uqVA8CNPSoKCyTC9Ue9jOhgNEL6ELsBZ73J+jEmD6BynoIMjXkZIZzzt8GQ9qohkhvFwgcbOPtjnfClRGZ8= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=iGKK9rP4; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="iGKK9rP4" Received: by smtp.kernel.org (Postfix) with ESMTPSA id AEEA0C2BC9E; Wed, 8 Apr 2026 22:15:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1775686558; bh=LzcoftNwHznWMpp3niM08QmPU3gWbRJcspRmkILRoWI=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=iGKK9rP4D9Tvr3lqf3PfyOpNDND5TpFNBUsDhnYqUCvPENHYGezSJqTplMYWwKaGN iysALaUs7fWflUpL2bB3MWMATpDnUFuee0C4PdhrHsW13NJcOH94E2U44LgM2TO0Da wO1C9L88Lv7B6Sbl8JtpS4QCZbSyATvN26RJ3XU98L8/7SqkCLaBrujCkYzvnmX9bw wBOlXCVdiI9qcM+XHrIe9uV82FIdJH9wMDOYIqPnD5GIRQkbjZKiBkkfWlG8LoGAq/ oP06L+BDZOn7yExhJjUzM9lh8hbtNWkxOqJ336/0Ck8DIAdqwTPQq19Q0tSnnfp/f/ KirzI0exHI+2g== Date: Thu, 9 Apr 2026 00:15:54 +0200 From: Helge Deller To: Thomas =?iso-8859-15?Q?Wei=DFschuh?= Cc: Helge Deller , Willy Tarreau , linux-kernel@vger.kernel.org, linux-parisc@vger.kernel.org Subject: Re: [PATCH v3 2/2] tools/nolibc: add support for 32-bit parisc Message-ID: References: <20260408-nolibc-hppa-v3-0-961f3754b506@weissschuh.net> <20260408-nolibc-hppa-v3-2-961f3754b506@weissschuh.net> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-15 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <20260408-nolibc-hppa-v3-2-961f3754b506@weissschuh.net> Just some (untested) suggestions. Nothing critical: * Thomas Weißschuh : > Extend nolibc to target the 32-bit parisc architecture. > 64-bit is not yet supported. > > Signed-off-by: Thomas Weißschuh > --- > tools/include/nolibc/Makefile | 2 +- > tools/include/nolibc/arch-parisc.h | 178 +++++++++++++++++++++++++ > tools/include/nolibc/arch.h | 2 + > tools/testing/selftests/nolibc/Makefile.nolibc | 6 + > tools/testing/selftests/nolibc/run-tests.sh | 8 +- > 5 files changed, 194 insertions(+), 2 deletions(-) > > diff --git a/tools/include/nolibc/Makefile b/tools/include/nolibc/Makefile > index 7455097cff69..81187126bf93 100644 > --- a/tools/include/nolibc/Makefile > +++ b/tools/include/nolibc/Makefile > @@ -17,7 +17,7 @@ endif > # it defaults to this nolibc directory. > OUTPUT ?= $(CURDIR)/ > > -architectures := arm arm64 loongarch m68k mips powerpc riscv s390 sh sparc x86 > +architectures := arm arm64 loongarch m68k mips parisc powerpc riscv s390 sh sparc x86 > arch_files := arch.h $(addsuffix .h, $(addprefix arch-, $(architectures))) > all_files := \ > byteswap.h \ > diff --git a/tools/include/nolibc/arch-parisc.h b/tools/include/nolibc/arch-parisc.h > new file mode 100644 > index 000000000000..8580be5c9c58 > --- /dev/null > +++ b/tools/include/nolibc/arch-parisc.h > @@ -0,0 +1,178 @@ > +/* SPDX-License-Identifier: LGPL-2.1 OR MIT */ > +/* > + * parisc/hppa (32-bit) specific definitions for NOLIBC > + * Copyright (C) 2026 Thomas Weißschuh > + */ > + > +#ifndef _NOLIBC_ARCH_PARISC_H > +#define _NOLIBC_ARCH_PARISC_H > + > +#if defined(__LP64__) > +#error 64-bit not supported > +#endif > + > +#include "compiler.h" > +#include "crt.h" > + > +/* Syscalls for parisc : > + * - syscall number is passed in r20 > + * - arguments are in r26 to r21 > + * - the system call is performed by calling "ble 0x100(%sr2, %r0)", > + * the instruction after that is executed first, use it to load the number better: the instruction after that is in the delay slot and executed before the jump to 0x100 actually happens. > + * - syscall return comes in r28 > + * - the arguments are cast to long and assigned into the target > + * registers which are then simply passed as registers to the asm code, > + * so that we don't have to experience issues with register constraints. side-note: this is actually really tricky. I've seen cases, where the syscalls were not using the given registers, because the callers were too complicated and the compiler could not guarantee to actually use the given register. > + */ > + > +#define _NOLIBC_SYSCALL_CLOBBERLIST \ > + "memory", "%r1", "%r2", "%r4", "%r20", "%r29", "%r31" > + > +#define __nolibc_syscall0(num) \ > +({ \ > + register long _ret __asm__ ("r28"); \ > + \ > + __asm__ volatile ( \ > + "ble 0x100(%%sr2, %%r0)\n\t" \ > + "ldi %1, %%r20\n\t" \ > + : "=r"(_ret) \ > + : "i"(num) \ > + : _NOLIBC_SYSCALL_CLOBBERLIST \ > + ); \ > + _ret; \ > +}) > + > +#define __nolibc_syscall1(num, arg1) \ > +({ \ > + register long _ret __asm__ ("r28"); \ > + register long _arg1 __asm__ ("r26") = (long)(arg1); \ > + \ > + __asm__ volatile ( \ > + "ble 0x100(%%sr2, %%r0)\n\t" \ > + "ldi %2, %%r20\n\t" \ > + : "=r"(_ret), \ > + "+r"(_arg1) \ > + : "i"(num) \ > + : _NOLIBC_SYSCALL_CLOBBERLIST \ > + ); \ > + _ret; \ > +}) > + > +#define __nolibc_syscall2(num, arg1, arg2) \ > +({ \ > + register long _ret __asm__ ("r28"); \ > + register long _arg1 __asm__ ("r26") = (long)(arg1); \ > + register long _arg2 __asm__ ("r25") = (long)(arg2); \ > + \ > + __asm__ volatile ( \ > + "ble 0x100(%%sr2, %%r0)\n\t" \ > + "ldi %3, %%r20\n\t" \ > + : "=r"(_ret), \ > + "+r"(_arg1), "+r"(_arg2) \ > + : "i"(num) \ > + : _NOLIBC_SYSCALL_CLOBBERLIST \ > + ); \ > + _ret; \ > +}) > + > +#define __nolibc_syscall3(num, arg1, arg2, arg3) \ > +({ \ > + register long _ret __asm__ ("r28"); \ > + register long _arg1 __asm__ ("r26") = (long)(arg1); \ > + register long _arg2 __asm__ ("r25") = (long)(arg2); \ > + register long _arg3 __asm__ ("r24") = (long)(arg3); \ > + \ > + __asm__ volatile ( \ > + "ble 0x100(%%sr2, %%r0)\n\t" \ > + "ldi %4, %%r20\n\t" \ > + : "=r"(_ret), \ > + "+r"(_arg1), "+r"(_arg2), "+r"(_arg3) \ > + : "i"(num) \ > + : _NOLIBC_SYSCALL_CLOBBERLIST \ > + ); \ > + _ret; \ > +}) > + > +#define __nolibc_syscall4(num, arg1, arg2, arg3, arg4) \ > +({ \ > + register long _ret __asm__ ("r28"); \ > + register long _arg1 __asm__ ("r26") = (long)(arg1); \ > + register long _arg2 __asm__ ("r25") = (long)(arg2); \ > + register long _arg3 __asm__ ("r24") = (long)(arg3); \ > + register long _arg4 __asm__ ("r23") = (long)(arg4); \ > + \ > + __asm__ volatile ( \ > + "ble 0x100(%%sr2, %%r0)\n\t" \ > + "ldi %5, %%r20\n\t" \ > + : "=r"(_ret), \ > + "+r"(_arg1), "+r"(_arg2), "+r"(_arg3), "+r"(_arg4) \ > + : "i"(num) \ > + : _NOLIBC_SYSCALL_CLOBBERLIST \ > + ); \ > + _ret; \ > +}) > + > +#define __nolibc_syscall5(num, arg1, arg2, arg3, arg4, arg5) \ > +({ \ > + register long _ret __asm__ ("r28"); \ > + register long _arg1 __asm__ ("r26") = (long)(arg1); \ > + register long _arg2 __asm__ ("r25") = (long)(arg2); \ > + register long _arg3 __asm__ ("r24") = (long)(arg3); \ > + register long _arg4 __asm__ ("r23") = (long)(arg4); \ > + register long _arg5 __asm__ ("r22") = (long)(arg5); \ > + \ > + __asm__ volatile ( \ > + "ble 0x100(%%sr2, %%r0)\n\t" \ > + "ldi %6, %%r20\n\t" \ > + : "=r"(_ret), \ > + "+r"(_arg1), "+r"(_arg2), "+r"(_arg3), "+r"(_arg4), \ > + "+r"(_arg5) \ > + : "i"(num) \ > + : _NOLIBC_SYSCALL_CLOBBERLIST \ > + ); \ > + _ret; \ > +}) > + > +#define __nolibc_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \ > +({ \ > + register long _ret __asm__ ("r28"); \ > + register long _arg1 __asm__ ("r26") = (long)(arg1); \ > + register long _arg2 __asm__ ("r25") = (long)(arg2); \ > + register long _arg3 __asm__ ("r24") = (long)(arg3); \ > + register long _arg4 __asm__ ("r23") = (long)(arg4); \ > + register long _arg5 __asm__ ("r22") = (long)(arg5); \ > + register long _arg6 __asm__ ("r21") = (long)(arg6); \ > + \ > + __asm__ volatile ( \ > + "ble 0x100(%%sr2, %%r0)\n\t" \ > + "ldi %7, %%r20\n\t" \ > + : "=r"(_ret), \ > + "+r"(_arg1), "+r"(_arg2), "+r"(_arg3), "+r"(_arg4), \ > + "+r"(_arg5), "+r"(_arg6) \ > + : "i"(num) \ > + : _NOLIBC_SYSCALL_CLOBBERLIST \ > + ); \ > + _ret; \ > +}) > + > +#ifndef NOLIBC_NO_RUNTIME > +/* startup code */ > +void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _start(void) > +{ > + __asm__ volatile ( > + ".import $global$\n" /* Set up the dp register */ > + "ldil L%$global$, %dp\n" > + "ldo R%$global$(%r27), %dp\n" > + > + "ldo -4(%r24), %r26\n" /* The sp register is special on parisc. > + * r24 points to argv. Subtract 4 to get &argc. > + * Pass that as first argument to _start_c. > + */ > + > + "b,n _start_c\n" you can change that to "b _start_c\" (without ",n") and move it one line up before the "ldo -4..." instruction. It's a little bit faster". The ldo is then in the delay slot. > + ); > + __nolibc_entrypoint_epilogue(); > +} > +#endif /* NOLIBC_NO_RUNTIME */ > + > +#endif /* _NOLIBC_ARCH_PARISC_H */ > diff --git a/tools/include/nolibc/arch.h b/tools/include/nolibc/arch.h > index a3adaf433f2c..6dc45a78e972 100644 > --- a/tools/include/nolibc/arch.h > +++ b/tools/include/nolibc/arch.h > @@ -28,6 +28,8 @@ > #include "arch-m68k.h" > #elif defined(__sh__) > #include "arch-sh.h" > +#elif defined(__hppa__) > +#include "arch-parisc.h" > #else > #error Unsupported Architecture > #endif > diff --git a/tools/testing/selftests/nolibc/Makefile.nolibc b/tools/testing/selftests/nolibc/Makefile.nolibc > index f30bc68470cc..e9494f3cbc03 100644 > --- a/tools/testing/selftests/nolibc/Makefile.nolibc > +++ b/tools/testing/selftests/nolibc/Makefile.nolibc > @@ -64,6 +64,7 @@ ARCH_s390x = s390 > ARCH_sparc32 = sparc > ARCH_sparc64 = sparc > ARCH_sh4 = sh > +ARCH_parisc32 = parisc > ARCH := $(or $(ARCH_$(XARCH)),$(XARCH)) > > # kernel image names by architecture > @@ -92,6 +93,7 @@ IMAGE_sparc32 = arch/sparc/boot/image > IMAGE_sparc64 = arch/sparc/boot/image > IMAGE_m68k = vmlinux > IMAGE_sh4 = arch/sh/boot/zImage > +IMAGE_parisc32 = vmlinux > IMAGE = $(objtree)/$(IMAGE_$(XARCH)) > IMAGE_NAME = $(notdir $(IMAGE)) > > @@ -121,6 +123,7 @@ DEFCONFIG_sparc32 = sparc32_defconfig > DEFCONFIG_sparc64 = sparc64_defconfig > DEFCONFIG_m68k = virt_defconfig > DEFCONFIG_sh4 = rts7751r2dplus_defconfig > +DEFCONFIG_parisc32 = defconfig > DEFCONFIG = $(DEFCONFIG_$(XARCH)) > > EXTRACONFIG_x32 = -e CONFIG_X86_X32_ABI > @@ -159,6 +162,7 @@ QEMU_ARCH_sparc32 = sparc > QEMU_ARCH_sparc64 = sparc64 > QEMU_ARCH_m68k = m68k > QEMU_ARCH_sh4 = sh4 > +QEMU_ARCH_parisc32 = hppa > QEMU_ARCH = $(QEMU_ARCH_$(XARCH)) > > QEMU_ARCH_USER_ppc64le = ppc64le > @@ -199,6 +203,7 @@ QEMU_ARGS_sparc32 = -M SS-5 -m 256M -append "console=ttyS0,115200 panic=-1 $( > QEMU_ARGS_sparc64 = -M sun4u -append "console=ttyS0,115200 panic=-1 $(TEST:%=NOLIBC_TEST=%)" > QEMU_ARGS_m68k = -M virt -append "console=ttyGF0,115200 panic=-1 $(TEST:%=NOLIBC_TEST=%)" > QEMU_ARGS_sh4 = -M r2d -serial file:/dev/stdout -append "console=ttySC1,115200 panic=-1 $(TEST:%=NOLIBC_TEST=%)" > +QEMU_ARGS_parisc32 = -append "console=ttyS0 panic=-1 $(TEST:%=NOLIBC_TEST=%)" You could change that to (untested): QEMU_ARGS_parisc32 = -M B160L -append "panic=-1 $(TEST:%=NOLIBC_TEST=%)" -nographic > QEMU_ARGS = -m 1G $(QEMU_ARGS_$(XARCH)) $(QEMU_ARGS_BIOS) $(QEMU_ARGS_EXTRA) > > # OUTPUT is only set when run from the main makefile, otherwise > @@ -215,6 +220,7 @@ CFLAGS_i386 = $(call cc-option,-m32) > CFLAGS_x32 = -mx32 > CFLAGS_arm = -marm > CFLAGS_armthumb = -mthumb -march=armv6t2 > +CFLAGS_parisc32 = -mfast-indirect-calls would be good if we could go without this... But for the beginning it's ok. Helge