From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wm1-f54.google.com (mail-wm1-f54.google.com [209.85.128.54]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 79C3433DED1 for ; Tue, 28 Apr 2026 17:04:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.54 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777395894; cv=none; b=rQPyBWhB8dVVSJ9pJd6/e4lKxTl5v/lnjauwzeZZ71UEasAOA5ITnnyE7MfnDcKg4Bun3qJ8Ttis4bCnowiPjYKuwfr3/Kk5Wze9ajI4M1gnzc+XYzOydd9tRg0tcjAxQUvI9TwtLnvVntzWEX/tcKeKbDzVIjfzRD0mzOFv9iU= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777395894; c=relaxed/simple; bh=0D6wwLBEmcZRn1FIftyLFSafxOoirtG4uKGPSWKneDg=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=VOHrZopi80KQYWFCrE2iFe/k9jAGTxMCYjdukkAiDudyeQcAkGoV/u50eAnEgL6QaCkLM2iw2uXwGniLIv6b5454UOI1XI7pJ1fUv99AQNKxCcgMv9voK1/F1HScRxrAR65FJb5bUWFU37XyTk3/x4ZYSNB+MyT6ffZGMD/0P1c= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=M2joUQ1j; arc=none smtp.client-ip=209.85.128.54 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="M2joUQ1j" Received: by mail-wm1-f54.google.com with SMTP id 5b1f17b1804b1-488ab2db91aso164836755e9.3 for ; Tue, 28 Apr 2026 10:04:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1777395891; x=1778000691; darn=vger.kernel.org; h=in-reply-to:content-transfer-encoding:content-disposition :mime-version:references:message-id:subject:cc:to:from:date:from:to :cc:subject:date:message-id:reply-to; bh=a1bDO+sWe21X7RAqGro8jUaFFbf6/LIVjWDJcl9bwX4=; b=M2joUQ1j9zJytzsrZ+KskBpeRRtwPd47qr0i3FETyDr/gv2/j+NJ6Fzn90iaymymrn xceNiPduPl/UE6Ii210xciRjwbV5v0gPvZq9Ms+KE95VDY91drccrATN26j32J9P8dvN EAAGFwpIhAuwJaGgTAVz6s1t1jJtSS4jl2H+tuCpgSJrR48iECs3E2APIIcVKVqoBh72 ITnUwV5QEyGPOunzopxxSgi+nXeQty+Wdkw/lC75fhGRCzJ9oUR1GASFa0loW9UivKuc v+zoYdk4WEVxX2tpFJEhOQyCX7euufeCuH3/sW5bFlv6eD/Xei3S454bc7MmK25BeOet hwxA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777395891; x=1778000691; h=in-reply-to:content-transfer-encoding:content-disposition :mime-version:references:message-id:subject:cc:to:from:date:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=a1bDO+sWe21X7RAqGro8jUaFFbf6/LIVjWDJcl9bwX4=; b=lhapajS6eCfPeNBppNcNCB+KhptjRITj/+5go1Pgl5CTJuJleyyDEYZ8vIx9loCr6M s4zckM7r/3XfSKkTH0XdtUFj1lsjHs3FfON4TP/dERh+KN70kb3mPfo8V/5Xguwa2Hqd 716OQWp8kSlpjfotJYFQq69G5jspFCHbWyh49rwQ2cG9RBXH8NrcUPSMlrekdfOGAzU4 c8GaO9lGwUAk5TIdojQjwRUDEj0rJ51xK+BBokaotHGy22eHgVvAhGqAGrTi0ge/sxb5 pwy7TVDfrk4paWuuLLy4kVr51F+pDEkVDy5Vo17VGXMuJKNkWIzOcbNc5MVqrgbLO3Qn RYcA== X-Forwarded-Encrypted: i=1; AFNElJ91vkeCuBT5cthqww6Ihlk2vZ8S8IKs3iyAvOzM0lk7Wd6ywh3tNozvHOW3jvVYQmBZswLKh/ctPpYjYmwPLA==@vger.kernel.org X-Gm-Message-State: AOJu0Yx8X23zGcmon2ZvVVK6dfiQ5+m5AJ+uw09ayU1EkR50IcAfrimC fy86LNEqN4roiFHV2bl+TYV9RFVOKxvl852BFEzEApIWS46yUfLfJgKu X-Gm-Gg: AeBDiesQ6EYBGw4qZwXdCX0qcQQSdx51qWkuu8Emo07E3dlF4TRuXczObtBZ8bP/HhJ AZcEieguarGAPH6UTK0CEvPuapcfloDYQq4dWduk80X54Aj3gn118Fh/1zVv4xnr77GrVpXpcrO W2CJcIDindmLntVS9czK/vQdbmD0xp8ZCkDYl3991vlG72BXgoY0rm1yKv4krgHXbkBmoLjIvKO oiVblZVd/dXlEFr7CEZpqTHferpyifhFrDFpj8Kn9g3Fi1vwfMDQ3I6hDWz0XAqj4uRIgpme8MU th32qvXYcrjAuFLASm08aNKpyjJ2UGkQEq+f18uSUk2NhxmbfIKLHhr+RXg49UQ6+1dM67LRkhd ygm4s/V+bRRXzxL8go/w9GBL8+XhkNM0/lrpCKs1XNdhU1fk/FlbLpy0n9tnmfGQgsmJmGa64sH nC4NSEOeOqshYpz4bHjDBzLilKNUMmaEBFW3Ar28nSPP8lhBcZXtrFLl4FL/F1aJIcmjamCzFb9 vL3gaNI43tGdZatBnh/cTMPj/w= X-Received: by 2002:a05:600c:c087:b0:48a:563c:c8c5 with SMTP id 5b1f17b1804b1-48a7b51943bmr6470435e9.8.1777395890398; Tue, 28 Apr 2026 10:04:50 -0700 (PDT) Received: from localhost (brnt-04-b2-v4wan-170138-cust2432.vm7.cable.virginm.net. [94.175.9.129]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-48a7b564c53sm6296885e9.7.2026.04.28.10.04.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 28 Apr 2026 10:04:48 -0700 (PDT) Date: Tue, 28 Apr 2026 18:04:47 +0100 From: Stafford Horne To: Thomas =?iso-8859-1?Q?Wei=DFschuh?= Cc: Willy Tarreau , Jonas Bonn , Stefan Kristiansson , linux-openrisc@vger.kernel.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH] tools/nolibc: add support for OpenRISC / or1k Message-ID: References: <20260428-nolibc-openrisc-v1-1-33b399054af6@weissschuh.net> Precedence: bulk X-Mailing-List: linux-openrisc@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <20260428-nolibc-openrisc-v1-1-33b399054af6@weissschuh.net> On Tue, Apr 28, 2026 at 05:48:51PM +0200, Thomas Weißschuh wrote: > Add support for OpenRISC / or1k to nolibc. > > _start() uses the same wrapper construct as in arch-sh.h. > libgcc is necessary as OpenRISC is missing 64-bit multiplication. There are a few minor issues with this patch. Could you give any background for this? What are you working on? Just getting more coverage in the test suite? Do you have any results for or1k, considering one of the issues I highlighted before I am not sure this will compile as is. > Signed-off-by: Thomas Weißschuh > --- > tools/include/nolibc/Makefile | 2 +- > tools/include/nolibc/arch-openrisc.h | 176 +++++++++++++++++++++++++ > tools/include/nolibc/arch.h | 2 + > tools/testing/selftests/nolibc/Makefile.nolibc | 5 + > tools/testing/selftests/nolibc/run-tests.sh | 4 +- > 5 files changed, 187 insertions(+), 2 deletions(-) > > diff --git a/tools/include/nolibc/Makefile b/tools/include/nolibc/Makefile > index 872c318f50d4..2cb4d610fe53 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 openrisc powerpc riscv s390 sh sparc x86 > arch_files := arch.h $(addsuffix .h, $(addprefix arch-, $(architectures))) > all_files := \ > alloca.h \ > diff --git a/tools/include/nolibc/arch-openrisc.h b/tools/include/nolibc/arch-openrisc.h > new file mode 100644 > index 000000000000..de2df1715504 > --- /dev/null > +++ b/tools/include/nolibc/arch-openrisc.h > @@ -0,0 +1,176 @@ > +/* SPDX-License-Identifier: LGPL-2.1 OR MIT */ > +/* > + * openrisc specific definitions for NOLIBC > + * Copyright (C) 2026 Thomas Weißschuh > + */ > + > +#ifndef _NOLIBC_ARCH_OPENRISC_H > +#define _NOLIBC_ARCH_OPENRISC_H > + > +#include "compiler.h" > +#include "crt.h" > + > +/* > + * Syscalls for SuperH: > + * - syscall number is passed in r11 > + * - arguments are in r3, r4, r5, r6, r7, r8 > + * - the system call is performed by calling l.sys 1 > + * - syscall return value is in r11 > + */ > + > +#define _NOLIBC_SYSCALL_CLOBBERLIST \ > + "r12", "r13", "r15", "r17", "r19", "r21", "r23", "r25", "r27", "r29", "r31", "memory" > + > +#define __nolibc_syscall0(num) \ > +({ \ > + register long _num __asm__ ("r11") = (num); \ > + register long _ret __asm__ ("r11"); \ > + \ > + __asm__ volatile ( \ > + "l.sys 1\n" \ > + "l.nop\n" \ We do not need l.nop for l.sys instructions. They do not have a delay-slot line branches. > + : "=r"(_ret) \ > + : "r"(_num) \ > + : "r3", "r4", "r5", "r6", "r7", "r8", \ > + _NOLIBC_SYSCALL_CLOBBERLIST \ > + ); \ > + _ret; \ > +}) > + > +#define __nolibc_syscall1(num, arg1) \ > +({ \ > + register long _num __asm__ ("r11") = (num); \ > + register long _ret __asm__ ("r11"); \ > + register long _arg1 __asm__ ("r3") = (long)(arg1); \ > + \ > + __asm__ volatile ( \ > + "l.sys 1\n" \ > + "l.nop\n" \ > + : "=r"(_ret) \ > + : "r"(_num), "r"(_arg1) \ > + : "r4", "r5", "r6", "r7", "r8", _NOLIBC_SYSCALL_CLOBBERLIST \ > + ); \ > + _ret; \ > +}) > + > +#define __nolibc_syscall2(num, arg1, arg2) \ > +({ \ > + register long _num __asm__ ("r11") = (num); \ > + register long _ret __asm__ ("r11"); \ > + register long _arg1 __asm__ ("r3") = (long)(arg1); \ > + register long _arg2 __asm__ ("r4") = (long)(arg2); \ > + \ > + __asm__ volatile ( \ > + "l.sys 1\n" \ > + "l.nop\n" \ > + : "=r"(_ret) \ > + : "r"(_num), "r"(_arg1), "r"(_arg2) \ > + : "r5", "r6", "r7", "r8", _NOLIBC_SYSCALL_CLOBBERLIST \ > + ); \ > + _ret; \ > +}) > + > +#define __nolibc_syscall3(num, arg1, arg2, arg3) \ > +({ \ > + register long _num __asm__ ("r11") = (num); \ > + register long _ret __asm__ ("r11"); \ > + register long _arg1 __asm__ ("r3") = (long)(arg1); \ > + register long _arg2 __asm__ ("r4") = (long)(arg2); \ > + register long _arg3 __asm__ ("r5") = (long)(arg3); \ > + \ > + __asm__ volatile ( \ > + "l.sys 1\n" \ > + "l.nop\n" \ > + : "=r"(_ret) \ > + : "r"(_num), "r"(_arg1), "r"(_arg2), "r"(_arg3) \ > + : "r6", "r7", "r8", _NOLIBC_SYSCALL_CLOBBERLIST \ > + ); \ > + _ret; \ > +}) > + > +#define __nolibc_syscall4(num, arg1, arg2, arg3, arg4) \ > +({ \ > + register long _num __asm__ ("r11") = (num); \ > + register long _ret __asm__ ("r11"); \ > + register long _arg1 __asm__ ("r3") = (long)(arg1); \ > + register long _arg2 __asm__ ("r4") = (long)(arg2); \ > + register long _arg3 __asm__ ("r5") = (long)(arg3); \ > + register long _arg4 __asm__ ("r6") = (long)(arg4); \ > + \ > + __asm__ volatile ( \ > + "l.sys 1\n" \ > + "l.nop\n" \ > + : "=r"(_ret) \ > + : "r"(_num), "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4) \ > + : "r7", "r8", _NOLIBC_SYSCALL_CLOBBERLIST \ > + ); \ > + _ret; \ > +}) > + > +#define __nolibc_syscall5(num, arg1, arg2, arg3, arg4, arg5) \ > +({ \ > + register long _num __asm__ ("r11") = (num); \ > + register long _ret __asm__ ("r11"); \ > + register long _arg1 __asm__ ("r3") = (long)(arg1); \ > + register long _arg2 __asm__ ("r4") = (long)(arg2); \ > + register long _arg3 __asm__ ("r5") = (long)(arg3); \ > + register long _arg4 __asm__ ("r6") = (long)(arg4); \ > + register long _arg5 __asm__ ("r7") = (long)(arg5); \ > + \ > + __asm__ volatile ( \ > + "l.sys 1\n" \ > + "l.nop\n" \ > + : "=r"(_ret) \ > + : "r"(_num), "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), \ > + "r"(_arg5) \ > + : "r8", _NOLIBC_SYSCALL_CLOBBERLIST \ > + ); \ > + _ret; \ > +}) > + > +#define __nolibc_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6) \ > +({ \ > + register long _num __asm__ ("r11") = (num); \ > + register long _ret __asm__ ("r11"); \ > + register long _arg1 __asm__ ("r3") = (long)(arg1); \ > + register long _arg2 __asm__ ("r4") = (long)(arg2); \ > + register long _arg3 __asm__ ("r5") = (long)(arg3); \ > + register long _arg4 __asm__ ("r6") = (long)(arg4); \ > + register long _arg5 __asm__ ("r7") = (long)(arg5); \ > + register long _arg6 __asm__ ("r8") = (long)(arg6); \ > + \ > + __asm__ volatile ( \ > + "l.sys 1\n" \ > + "l.nop\n" \ > + : "=r"(_ret) \ > + : "r"(_num), "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), \ > + "r"(_arg5), "r"(_arg6) \ > + : _NOLIBC_SYSCALL_CLOBBERLIST \ > + ); \ > + _ret; \ > +}) > + > +#ifndef NOLIBC_NO_RUNTIME > +/* startup code */ > +void _start_wrapper(void); > +void __attribute__((weak,noreturn)) > +__nolibc_entrypoint __nolibc_no_stack_protector > +_start_wrapper(void) > +{ > + __asm__ volatile ( > + ".global _start\n" /* The C function will have a prologue, */ > + ".type _start, @function\n" /* corrupting "sp" */ > + ".weak _start\n" > + "_start:\n" > + > + "l.or r3,sp,sp\n" /* save stack pointer to 3, as arg1 of _start_c */ What is sp here? There is no sp alias in OpenRISC, should it be r1? Does this compile? > + "l.jal _start_c\n" /* transfer to c runtime */ > + "l.nop\n" The l.or can go in the delay slot. Also, preferrably we use spaces between args, and a space to indicate a delay slot e.g. "l.jal _start_c\n" "l.or r3, r1, r1\n" > + > + ".size _start, .-_start\n" > + ); > + __nolibc_entrypoint_epilogue(); > +} > +#endif /* NOLIBC_NO_RUNTIME */ > + > +#endif /* _NOLIBC_ARCH_OPENRISC_H */ > diff --git a/tools/include/nolibc/arch.h b/tools/include/nolibc/arch.h > index a3adaf433f2c..55009dcafe9e 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(__or1k__) > +#include "arch-openrisc.h" > #else > #error Unsupported Architecture > #endif > diff --git a/tools/testing/selftests/nolibc/Makefile.nolibc b/tools/testing/selftests/nolibc/Makefile.nolibc > index f30bc68470cc..91f5a284f4e6 100644 > --- a/tools/testing/selftests/nolibc/Makefile.nolibc > +++ b/tools/testing/selftests/nolibc/Makefile.nolibc > @@ -92,6 +92,7 @@ IMAGE_sparc32 = arch/sparc/boot/image > IMAGE_sparc64 = arch/sparc/boot/image > IMAGE_m68k = vmlinux > IMAGE_sh4 = arch/sh/boot/zImage > +IMAGE_openrisc = vmlinux > IMAGE = $(objtree)/$(IMAGE_$(XARCH)) > IMAGE_NAME = $(notdir $(IMAGE)) > > @@ -121,6 +122,7 @@ DEFCONFIG_sparc32 = sparc32_defconfig > DEFCONFIG_sparc64 = sparc64_defconfig > DEFCONFIG_m68k = virt_defconfig > DEFCONFIG_sh4 = rts7751r2dplus_defconfig > +DEFCONFIG_openrisc = virt_defconfig > DEFCONFIG = $(DEFCONFIG_$(XARCH)) > > EXTRACONFIG_x32 = -e CONFIG_X86_X32_ABI > @@ -159,6 +161,7 @@ QEMU_ARCH_sparc32 = sparc > QEMU_ARCH_sparc64 = sparc64 > QEMU_ARCH_m68k = m68k > QEMU_ARCH_sh4 = sh4 > +QEMU_ARCH_openrisc = or1k > QEMU_ARCH = $(QEMU_ARCH_$(XARCH)) > > QEMU_ARCH_USER_ppc64le = ppc64le > @@ -199,6 +202,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_openrisc = -M virt -m 512M -append "console=ttyS0 panic=-1 $(TEST:%=NOLIBC_TEST=%)" > QEMU_ARGS = -m 1G $(QEMU_ARGS_$(XARCH)) $(QEMU_ARGS_BIOS) $(QEMU_ARGS_EXTRA) > > # OUTPUT is only set when run from the main makefile, otherwise > @@ -233,6 +237,7 @@ CFLAGS_XARCH = $(CFLAGS_$(XARCH)) > endif > > LDLIBS_ppc = $(if $(LLVM),,-lgcc) > +LDLIBS_openrisc = $(if $(LLVM),,-lgcc) > LDLIBS = $(LDLIBS_$(XARCH)) > > include Makefile.include > diff --git a/tools/testing/selftests/nolibc/run-tests.sh b/tools/testing/selftests/nolibc/run-tests.sh > index cd439096fdf3..c25ee4be2df4 100755 > --- a/tools/testing/selftests/nolibc/run-tests.sh > +++ b/tools/testing/selftests/nolibc/run-tests.sh > @@ -21,6 +21,7 @@ all_archs=( > i386 x86_64 x32 > arm64 arm armthumb > mips32le mips32be mipsn32le mipsn32be mips64le mips64be > + openrisc > ppc ppc64 ppc64le > riscv32 riscv64 > s390x > @@ -107,6 +108,7 @@ crosstool_arch() { > case "$1" in > arm64) echo aarch64;; > armthumb) echo arm;; > + openrisc) echo or1k;; > ppc) echo powerpc;; > ppc64) echo powerpc64;; > ppc64le) echo powerpc64;; > @@ -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" = "openrisc" ] && [ "$llvm" = "1" ]; then > echo "Unsupported configuration" > return > fi The rest looks ok to me. Thanks, -Stafford