[05/13] selftests/nolibc: riscv: customize makefile for rv32

Message ID 7adb27a7c56dd06d782710a5f684ea6263900f98.1684949268.git.falcon@tinylab.org
State New
Headers
Series tools/nolibc: riscv: Add full rv32 support |

Commit Message

Zhangjin Wu May 24, 2023, 5:50 p.m. UTC
  both riscv64 and riscv32 have the same ARCH value, it is riscv, the
default defconfig enables 64bit, to support riscv32, let's allow pass
"ARCH=riscv32" or "ARCH=riscv CONFIG_32BIT=1" to customize riscv32
setting.

Note: glibc >= 2.33 is required to avoid a bug of the old
bits/wordsize.h.

  /usr/riscv64-linux-gnu/include/bits/wordsize.h:28:3: error: #error "rv32i-based targets are not supported"
           28 | # error "rv32i-based targets are not supported"

This can not pass compile, several time64 syscalls are still missing.

Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
---
 tools/testing/selftests/nolibc/Makefile | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)
  

Comments

Thomas Weißschuh May 26, 2023, 6:57 a.m. UTC | #1
On 2023-05-25 01:50:57+0800, Zhangjin Wu wrote:
> both riscv64 and riscv32 have the same ARCH value, it is riscv, the
> default defconfig enables 64bit, to support riscv32, let's allow pass
> "ARCH=riscv32" or "ARCH=riscv CONFIG_32BIT=1" to customize riscv32
> setting.

What's the advantage of doing CONFIG_32BIT? For i386/x86_64, arm/arm64
it's not necessary either.
(Let's ignore the "x86" case)

If for riscv the "normal" version is riscv64 then adding a new "riscv32" that
works the same as the other architectures seems nicer and easier.
  
Zhangjin Wu May 26, 2023, 9:20 a.m. UTC | #2
Hi, Thomas

> On 2023-05-25 01:50:57+0800, Zhangjin Wu wrote:
> > both riscv64 and riscv32 have the same ARCH value, it is riscv, the
> > default defconfig enables 64bit, to support riscv32, let's allow pass
> > "ARCH=riscv32" or "ARCH=riscv CONFIG_32BIT=1" to customize riscv32
> > setting.
> 
> What's the advantage of doing CONFIG_32BIT? For i386/x86_64, arm/arm64
> it's not necessary either.
> (Let's ignore the "x86" case)
>

Very good question, thanks.

This requirement may happen on mips, loongarch and even powerpc too, both x86
and arm are just the 'exception'.

It is 'designed' as a temp flag/variable to specifiy that current arch is
riscv32, not riscv64, of course, we can use something like this or even
use a meaningless 't' variable:

    # Allow pass ARCH=riscv|riscv32|riscv64, riscv implies riscv64
    ifneq ($(findstring xriscv,x$(ARCH)),)
      riscv32 := $(if $(findstring riscv32x,$(ARCH)x),1)
      override ARCH := riscv
    endif

Using CONFIG_32BIT instead of riscv32 has some extra considerations:

* Using it in command line is a 'side effect', if it is a meaningless
  variable, we will not use it for we can not remember it, here use it as a
  choice, riscv32 is enough, we can simply remove this comment from the
  commit message.

* The architectures like riscv, mips, loongarch share the same source code tree
  between 32bit and 64bit and even 128bit in the future, x86 and arm just not
  do so.

  The ARCH specified here differs from the one to kernel make, we should
  provide a flag/variable or anther ARCH variant to show the
  difference, _ARCH or XARCH have been used in my local patch.

  CONFIG_32BIT is meaningful to reflect the difference, even for future,
  we can use the same thing CONFIG_64BIT, CONFIG_128BIT, so simply
  BITS=32, BITS=64, BITS=128, but that is hard to be used as a oneline
  condition statement (although we can use something like findstring).

      $(if $(findstring x32y,x$(BITS)y),something whatevever)

      v.s.

      $(if $(CONFIG_32BIT),something whatevever)

  If not use a tmp flag/variable, this works too, but duplicated :-)

      $(if $(findstring xriscv32y,x$(ARCH)y),something whatevever)

* We are able to auto detect this config from include/config/auto.conf,
  there will be something like CONFIG_32BIT=y there.

  we did use such auto detect logic in my local patch, but it has some
  issues if we want a riscv64 build after we did a riscv32 config if we
  only pass ARCH=riscv, so, I just removed that logic but reserved the
  pontential for future.

> If for riscv the "normal" version is riscv64 then adding a new "riscv32" that
> works the same as the other architectures seems nicer and easier.
> 

The complexity here is what just explained above: The ARCH specified
here differs from the one to kernel make.

It is ok to add riscv32 like the other architectures as following:

    ifeq ($(ARCH),riscv32)
      _ARCH := riscv
    else
      _ARCH := $(ARCH)
    endif

    IMAGE_riscv32 = arch/riscv/boot/Image
    DEFCONFIG_riscv32 = rv32_defconfig
    QEMU_ARCH_riscv32 = riscv32
    QEMU_ARGS_riscv32 = -M virt -append "console=ttyS0 panic=-1 $(TEST:%=NOLIBC_TEST=%)"
    CFLAGS_riscv32 = -march=rv32im -mabi=ilp32

And all of the other 'ARCH' variables passed to kernel 'make' should be
changed to $(_ARCH), include most of the core targets, like:

    sysroot/$(ARCH)/include:
	$(Q)rm -rf sysroot/$(ARCH) sysroot/sysroot
	$(QUIET_MKDIR)mkdir -p sysroot
	$(Q)$(MAKE) -C ../../../include/nolibc ARCH=$(_ARCH) OUTPUT=$(CURDIR)/sysroot/ headers_standalone
	$(Q)mv sysroot/sysroot sysroot/$(ARCH)

    defconfig:
    	$(Q)$(MAKE) -C $(srctree) ARCH=$(_ARCH) CC=$(CC) CROSS_COMPILE=$(CROSS_COMPILE) mrproper $(DEFCONFIG) prepare
    
    kernel: initramfs
    	$(Q)$(MAKE) -C $(srctree) ARCH=$(_ARCH) CC=$(CC) CROSS_COMPILE=$(CROSS_COMPILE) $(IMAGE_NAME) CONFIG_INITRAMFS_SOURCE=$(CURDIR)/initramfs
    
It is not that easier, it touched more source code and make things a
little complex, we must mixes the using of ARCH and _ARCH in the whole
Makefile and that is not comfortable and may introduce more complexity,
for example, we may be worry about if the directories should be named
with the new $(_ARCH) ;-)

And CONFIG_32BIT variable is better than riscv32, because, we can share this
meaningful variable among mips, loongarch in the future if their maintainers
want to add more variants support for such platforms, they will meet the same
requirement.

Thanks very much.

Best regards,
Zhangjin
  

Patch

diff --git a/tools/testing/selftests/nolibc/Makefile b/tools/testing/selftests/nolibc/Makefile
index 47c3c89092e4..9adc8944dd80 100644
--- a/tools/testing/selftests/nolibc/Makefile
+++ b/tools/testing/selftests/nolibc/Makefile
@@ -14,6 +14,12 @@  include $(srctree)/scripts/subarch.include
 ARCH = $(SUBARCH)
 endif
 
+# Allow pass ARCH=riscv|riscv32|riscv64, riscv implies riscv64
+ifneq ($(findstring xriscv,x$(ARCH)),)
+  CONFIG_32BIT := $(if $(findstring 32x,$(ARCH)x),1)
+  override ARCH := riscv
+endif
+
 # kernel image names by architecture
 IMAGE_i386       = arch/x86/boot/bzImage
 IMAGE_x86_64     = arch/x86/boot/bzImage
@@ -34,7 +40,7 @@  DEFCONFIG_x86        = defconfig
 DEFCONFIG_arm64      = defconfig
 DEFCONFIG_arm        = multi_v7_defconfig
 DEFCONFIG_mips       = malta_defconfig
-DEFCONFIG_riscv      = defconfig
+DEFCONFIG_riscv      = $(if $(CONFIG_32BIT),rv32_defconfig,defconfig)
 DEFCONFIG_s390       = defconfig
 DEFCONFIG_loongarch  = defconfig
 DEFCONFIG            = $(DEFCONFIG_$(ARCH))
@@ -49,7 +55,7 @@  QEMU_ARCH_x86        = x86_64
 QEMU_ARCH_arm64      = aarch64
 QEMU_ARCH_arm        = arm
 QEMU_ARCH_mips       = mipsel  # works with malta_defconfig
-QEMU_ARCH_riscv      = riscv64
+QEMU_ARCH_riscv      = $(if $(CONFIG_32BIT),riscv32,riscv64)
 QEMU_ARCH_s390       = s390x
 QEMU_ARCH_loongarch  = loongarch64
 QEMU_ARCH            = $(QEMU_ARCH_$(ARCH))
@@ -76,6 +82,7 @@  else
 Q=@
 endif
 
+CFLAGS_riscv = $(if $(CONFIG_32BIT),-march=rv32im -mabi=ilp32)
 CFLAGS_s390 = -m64
 CFLAGS_STACKPROTECTOR ?= $(call cc-option,-mstack-protector-guard=global $(call cc-option,-fstack-protector-all))
 CFLAGS  ?= -Os -fno-ident -fno-asynchronous-unwind-tables -std=c89 \