mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Helge Deller <deller@gmx.de>
To: "Thomas Weißschuh" <linux@weissschuh.net>,
	"James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>,
	"Willy Tarreau" <w@1wt.eu>,
	"John David Anglin" <dave.anglin@bell.net>
Cc: linux-kernel@vger.kernel.org, linux-parisc@vger.kernel.org
Subject: Re: [PATCH 3/3] tools/nolibc: add support for 32-bit parisc
Date: Tue, 7 Apr 2026 19:33:05 +0200	[thread overview]
Message-ID: <0fad3d18-72fa-4d99-b9ac-477964fdd654@gmx.de> (raw)
In-Reply-To: <20260407-nolibc-hppa-v1-3-f70b4509c44a@weissschuh.net>

On 4/7/26 18:37, Thomas Weißschuh wrote:
> Extend nolibc to target the 32-bit parisc architecture.
> 64-bit is not yet supported.

Adding 64-bit would be very cool.
Dave Anglin is currently working on adding 64-bit userspace support
to gcc/glibc (dynamic loader), but that takes some time.
In the meantime a 64-bit nolibc would be cool for testing.

Helge

  
> Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
> ---
>   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    |   4 +-
>   5 files changed, 190 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..5918f45132bb
> --- /dev/null
> +++ b/tools/include/nolibc/arch-parisc.h
> @@ -0,0 +1,178 @@
> +/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
> +/*
> + * parisc/hppa (32 and 64) specific definitions for NOLIBC
> + * Copyright (C) 2026 Thomas Weißschuh <linux@weissschuh.net>
> + */
> +
> +#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
> + *   - 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.
> + */
> +
> +#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"
> +	);
> +	__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=%)"

Does it make sense to use the qemu "-nographic" option for parisc (and some other architectures) ?
That way everything runs much faster on the text console, and (at least) for parisc you don't need the "console=ttyS0" entry.

>   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
>   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 3917cfb8fdc4..981a680cebfb 100755
> --- a/tools/testing/selftests/nolibc/run-tests.sh
> +++ b/tools/testing/selftests/nolibc/run-tests.sh
> @@ -28,6 +28,7 @@ all_archs=(
>   	sparc32 sparc64
>   	m68k
>   	sh4
> +	parisc32
>   )
>   archs="${all_archs[@]}"
>   
> @@ -116,6 +117,7 @@ crosstool_arch() {
>   	s390*) echo s390;;
>   	sparc*) echo sparc64;;
>   	x32*) echo x86_64;;
> +	parisc32) echo hppa;;
>   	*) echo "$1";;
>   	esac
>   }
> @@ -185,7 +187,7 @@ test_arch() {
>   			exit 1
>   	esac
>   	printf '%-15s' "$arch:"
> -	if [ "$arch" = "m68k" -o "$arch" = "sh4" ] && [ "$llvm" = "1" ]; then
> +	if [ "$arch" = "m68k" -o "$arch" = "sh4" -o "$arch" = "parisc32" ] && [ "$llvm" = "1" ]; then
>   		echo "Unsupported configuration"
>   		return
>   	fi
> 


  reply	other threads:[~2026-04-07 17:33 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-07 16:37 [PATCH 0/3] " Thomas Weißschuh
2026-04-07 16:37 ` [PATCH 1/3] parisc: Makefile: use the regular compiler to build a native 32-bit vDSO Thomas Weißschuh
2026-04-07 17:14   ` Helge Deller
2026-04-07 18:06     ` Thomas Weißschuh
2026-04-07 19:27       ` Helge Deller
2026-04-07 20:20         ` Helge Deller
2026-04-07 21:27           ` Thomas Weißschuh
2026-04-07 22:33             ` Helge Deller
2026-04-07 16:37 ` [PATCH 2/3] selftests/nolibc: avoid function pointer comparisons Thomas Weißschuh
2026-04-07 17:20   ` Helge Deller
2026-04-07 18:11     ` Thomas Weißschuh
2026-04-07 16:37 ` [PATCH 3/3] tools/nolibc: add support for 32-bit parisc Thomas Weißschuh
2026-04-07 17:33   ` Helge Deller [this message]
2026-04-07 18:14     ` Thomas Weißschuh
2026-04-07 18:40       ` Helge Deller
2026-04-07 18:50         ` Thomas Weißschuh

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=0fad3d18-72fa-4d99-b9ac-477964fdd654@gmx.de \
    --to=deller@gmx.de \
    --cc=James.Bottomley@HansenPartnership.com \
    --cc=dave.anglin@bell.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-parisc@vger.kernel.org \
    --cc=linux@weissschuh.net \
    --cc=w@1wt.eu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®