From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wm1-f44.google.com (mail-wm1-f44.google.com [209.85.128.44]) (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 79B0D33D4EC for ; Tue, 28 Apr 2026 17:04:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.44 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777395895; cv=none; b=dgJrDCKa4TTouE5L8f0SKSp3soT/C5yiHKGsJEQPCoTXxSNqJwNbk8UlPFC2nZ1B1ppIwLoClMIpOCqdwJiFT3fNOe5ppFib4r2Vkf4+TO3DRs6kGie5wozIYXgJTEVCTSjivLN9oQs0yTinPCZAjFXIXxwvnxNwP+9qKF75f3Q= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777395895; c=relaxed/simple; bh=0D6wwLBEmcZRn1FIftyLFSafxOoirtG4uKGPSWKneDg=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=Ta65Afy1wHDcFflMjKGRjVf5gzKsa/PU/J7V9v4QcBg4ijX5Nrh6/LDPWjsbG6AuKucQUZ3sPGYsRzkFZH8kJoz+kDAzk3eIhuyTsnptz3pvUadO35/sjUFyhD6WEGQp9O9mlyeTqGLk2dTFgay62ewxmr+7I/SOu4WHcbaMUFc= 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.44 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-f44.google.com with SMTP id 5b1f17b1804b1-4891e86fabeso129768895e9.1 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=G0g2QOmzEvvp1oTjVgtVSAHoRFisQQkW1VSGFZDDOsVqF2cB7TsfeQZtMq5CihzISM wViwFAiYAyKeDyhIYioZeXmo0ImlQqZ8V5sB6e6V1fQGh/Fuib3LYvDOZrB6MCJln1gG OTqtzSjklDg9GfXK2+Sl3A3dWFBTszOm9OxmNO2UUBITXgdNvRF0edsMwAppnvYDSztJ bSZguTymRyZ6/50L9kx6XpG2RxRGbD/jYNrD2Hha2/CrhJK9wWfYujNqsNXmYQGmZFMD /KFZp8UikqXMjycSpZRtWIAvwJD8QiHxHMCPNePoXTnhCjBZ7tIBjvt/+veYo0A7PYfi yemw== X-Forwarded-Encrypted: i=1; AFNElJ+QIO0TCDMHV4BoSEK5Ht87XIzAxDT3oktDNVXlAP726Fl43lzLtxCpoiYVYVUemqpDUwRUpxuOpPn5Uv4=@vger.kernel.org X-Gm-Message-State: AOJu0Yw7uGYvlyY46LHZmm2QI0GO7xoqg9d5pm/RrlGElg0PL+CI9g4F Mo5S+qzSL4CiNPGAmkMpl1+ld3WhotlC8aPqt2Aj1E3ABf3ICHZ27j7Z X-Gm-Gg: AeBDiesIrOyud4ZnV2QzoB26iSGc0vpUU53lNPuObhMdiBEuJc7dHp5vUZv59LPbjGc r/TM7tts9IMxOhXOCTk5rrHDoVevj3LtZk6b9bDmV2MbKSu/Amhz+pNrOG2TrEHyMd4cucH2ZM1 Rqjulglg+OkoXrBE3SSvdcLc8D66s+alcQ05tTd8I8UJJQjGP36obRNecRFpPptKiQxDQgtV+iU qMIldW5O8ep0ePP/JGL3s3Lfy2BNqVUIWHu+vEKvpaozZeK7m5s8M/jGTsHuydMv1ieBM9Nh070 0ulja5H75uccAY3tLN2UaSTt36UOw+9QnQ44hECCKUDAQv/RyZnlRHNZbluRmDDIC6aau2PY/DT 3b7QMkGaWpUmXPYgVrCWVFsSM0Rvfz27pStP/qE79j60RNuM3KDcPdL09DdsGkXVrHOfGSl+Spy N6muGaH6jyZPvePNnfaq8Dy/eyTwLJi/7L0liQDcyswY1Hy5SAyj7JEHHpJZy1QLODX2oC3KVHO gzc+yks3T4/xByUMqs1Znb3PHs= 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-kernel@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