diff --git a/.github/workflows/riscv64-qemu-test.yaml b/.github/workflows/riscv64-qemu-test.yaml new file mode 100644 index 00000000000..b2383534ff6 --- /dev/null +++ b/.github/workflows/riscv64-qemu-test.yaml @@ -0,0 +1,59 @@ +name: riscv64-qemu-test + +on: [pull_request] + +jobs: + test: + runs-on: ubuntu-latest + env: + riscv_gnu_toolchain_download_path: https://github.com/riscv-collab/riscv-gnu-toolchain/releases/download/2025.07.03/riscv64-glibc-ubuntu-24.04-gcc-nightly-2025.07.03-nightly.tar.xz + + steps: + - name: Install depencencies + run: | + sudo apt update + sudo apt install -y --no-install-recommends qemu-user qemu-user-static binfmt-support wget + wget ${riscv_gnu_toolchain_download_path} + tar -xvf riscv64-glibc-ubuntu-24.04-gcc-nightly-2025.07.03-nightly.tar.xz -C /opt + sed -i "s|libdir='/mnt/riscv/riscv64-unknown-linux-gnu/lib'|libdir='/opt/riscv/riscv64-unknown-linux-gnu/lib'|g" /opt/riscv/riscv64-unknown-linux-gnu/lib/libatomic.la + + - name: Checkout Open MPI + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Bootstrap Open MPI + run: | + ./autogen.pl + sed -i '/^func_exec_program_core ()/,/^}/ s/\/exec qemu-riscv64 -cpu rv64,v=true,vext_spec=v1.0,vlen=128 -L \/opt\/riscv\/sysroot/g' config/ltmain.sh + + - name: Config Open MPI + run: | + export PATH="/opt/riscv/bin:$PATH" + export LD_LIBRARY_PATH="/opt/riscv/lib:$LD_LIBRARY_PATH" + ./configure --prefix=/opt/riscv --host=riscv64-unknown-linux-gnu SYSROOT=/opt/riscv/sysroot CC=riscv64-unknown-linux-gnu-gcc LD=riscv64-unknown-linux-gnu-ld --disable-mpi-fortran --disable-sphinx LDFLAGS=-Wl,-rpath-link,/opt/riscv/lib CFLAGS="-march=rv64gcv" + + - name: Build Open MPI + run: | + export PATH="/opt/riscv/bin:$PATH" + export LD_LIBRARY_PATH="/opt/riscv/lib:$LD_LIBRARY_PATH" + sed -i 's/#define OPAL_HAVE_GCC_BUILTIN_CSWAP_INT128 1/#define OPAL_HAVE_GCC_BUILTIN_CSWAP_INT128 0/' ./opal/include/opal_config.h + make -j 8 + make install + + - name: Run testsuite + run: | + export PATH="/opt/riscv/bin:$PATH" + export LD_LIBRARY_PATH="/opt/riscv/lib:$LD_LIBRARY_PATH" + make check + + - name: Run Opal Timer + run: | + export QEMU_LD_PREFIX=/opt/riscv/sysroot + export PATH="/opt/riscv/bin:$PATH" + export LD_LIBRARY_PATH="/opt/riscv/lib:$LD_LIBRARY_PATH" + mkdir -p /opt/riscv/sysroot/proc/device-tree/cpus/ + touch /opt/riscv/sysroot/proc/device-tree/cpus/timebase-frequency + grep "bogomips" /proc/cpuinfo | head -n 1 | awk '{printf("%d", $3*500000)}' | perl -e 'print pack("N", )' > /opt/riscv/sysroot/proc/device-tree/cpus/timebase-frequency + cd test/util + qemu-riscv64 -cpu rv64,v=true,vext_spec=v1.0,vlen=128 /opt/riscv/bin/mpirun -n 1 ./opal_timer diff --git a/config/opal_config_asm.m4 b/config/opal_config_asm.m4 index 1a458e748f1..978c19a68ca 100644 --- a/config/opal_config_asm.m4 +++ b/config/opal_config_asm.m4 @@ -538,6 +538,9 @@ AC_DEFUN([OPAL_CHECK_INLINE_C_GCC],[ powerpc-*|powerpc64-*|powerpcle-*|powerpc64le-*|rs6000-*|ppc-*) opal_gcc_inline_assign='"1: li %0,0" : "=&r"(ret)' ;; + riscv64*) + opal_gcc_inline_assign='"li %0, 0" : "=&r"(ret)' + ;; esac AS_IF([test "$opal_gcc_inline_assign" != ""], diff --git a/opal/include/opal/sys/Makefile.am b/opal/include/opal/sys/Makefile.am index b56e909b376..d73dc914f8c 100644 --- a/opal/include/opal/sys/Makefile.am +++ b/opal/include/opal/sys/Makefile.am @@ -42,4 +42,5 @@ headers += \ include opal/sys/x86_64/Makefile.am include opal/sys/arm64/Makefile.am include opal/sys/powerpc/Makefile.am +include opal/sys/riscv64/Makefile.am include opal/sys/gcc_builtin/Makefile.am diff --git a/opal/include/opal/sys/riscv64/Makefile.am b/opal/include/opal/sys/riscv64/Makefile.am new file mode 100644 index 00000000000..57ded02ee74 --- /dev/null +++ b/opal/include/opal/sys/riscv64/Makefile.am @@ -0,0 +1,15 @@ +# +# Copyright (c) 2025 Software System Team, SANECHIPS. +# All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +# This makefile.am does not stand on its own - it is included from opal/include/Makefile.am + +headers += \ + opal/sys/riscv64/timer.h + diff --git a/opal/include/opal/sys/riscv64/timer.h b/opal/include/opal/sys/riscv64/timer.h new file mode 100644 index 00000000000..b9b11699a39 --- /dev/null +++ b/opal/include/opal/sys/riscv64/timer.h @@ -0,0 +1,34 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2025 Software System Team, SANECHIPS. + * All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef OPAL_SYS_ARCH_TIMER_H +#define OPAL_SYS_ARCH_TIMER_H 1 + +typedef uint64_t opal_timer_t; + +#if OPAL_C_GCC_INLINE_ASSEMBLY + +static inline opal_timer_t opal_sys_timer_get_cycles(void) +{ + opal_timer_t ret; + __asm__ __volatile__("fence.i"); + __asm__ __volatile__("fence r, r" ::: "memory"); + __asm__ __volatile__("rdtime %0" : "=r"(ret)); + + return ret; +} + +#define OPAL_HAVE_SYS_TIMER_GET_CYCLES 1 + +#endif /* OPAL_C_GCC_INLINE_ASSEMBLY */ + +#endif /* ! OPAL_SYS_ARCH_TIMER_H */ + diff --git a/opal/include/opal/sys/timer.h b/opal/include/opal/sys/timer.h index 3f63839a48c..6f9191ab4bd 100644 --- a/opal/include/opal/sys/timer.h +++ b/opal/include/opal/sys/timer.h @@ -63,6 +63,8 @@ BEGIN_C_DECLS # include "opal/sys/arm64/timer.h" #elif defined(PLATFORM_ARCH_POWERPC) # include "opal/sys/powerpc/timer.h" +#elif defined(PLATFORM_ARCH_RISCV) +# include "opal/sys/riscv64/timer.h" #endif #ifndef DOXYGEN diff --git a/opal/mca/timer/linux/configure.m4 b/opal/mca/timer/linux/configure.m4 index 5ec7b013872..a2639eaf9c8 100644 --- a/opal/mca/timer/linux/configure.m4 +++ b/opal/mca/timer/linux/configure.m4 @@ -47,7 +47,7 @@ AC_DEFUN([MCA_opal_timer_linux_CONFIG],[ [timer_linux_happy="no"])]) case "${host}" in - i?86-*linux*|x86_64*linux*|ia64-*linux*|powerpc-*linux*|powerpc64-*linux*|powerpc64le-*linux*|powerpcle-*linux*|sparc*-*linux*|aarch64-*linux*) + i?86-*linux*|x86_64*linux*|ia64-*linux*|powerpc-*linux*|powerpc64-*linux*|powerpc64le-*linux*|powerpcle-*linux*|sparc*-*linux*|aarch64-*linux*|riscv64-*linux*) AS_IF([test "$timer_linux_happy" = "yes"], [AS_IF([test -r "/proc/cpuinfo"], [timer_linux_happy="yes"], diff --git a/opal/mca/timer/linux/timer_linux_component.c b/opal/mca/timer/linux/timer_linux_component.c index 6c615cd412e..b2f3dd506bb 100644 --- a/opal/mca/timer/linux/timer_linux_component.c +++ b/opal/mca/timer/linux/timer_linux_component.c @@ -18,6 +18,8 @@ * Copyright (c) 2016 Broadcom Limited. All rights reserved. * Copyright (c) 2022 Amazon.com, Inc. or its affiliates. * All Rights reserved. + * Copyright (c) 2025 Software System Team, SANECHIPS. + * All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -29,6 +31,7 @@ #include #include +#include #include "opal/constants.h" #include "opal/mca/timer/base/base.h" @@ -177,6 +180,20 @@ static int opal_timer_linux_find_freq(void) } } +#if defined(PLATFORM_ARCH_RISCV) + if (0 == opal_timer_linux_freq) { + /* read timebase-frequency in device-tree */ + FILE *fp_rv = fopen("/proc/device-tree/cpus/timebase-frequency", "rb"); + if (NULL == fp_rv) { + return OPAL_ERR_IN_ERRNO; + } + if (1 == fread(&opal_timer_linux_freq, 4, 1, fp_rv)){ + opal_timer_linux_freq = ntohl(opal_timer_linux_freq); + } + fclose(fp_rv); + } +#endif + fclose(fp); /* convert the timer frequency to MHz to avoid an extra operation when diff --git a/test/util/Makefile.am b/test/util/Makefile.am index 99c1a4b224a..397eac9e2d6 100644 --- a/test/util/Makefile.am +++ b/test/util/Makefile.am @@ -43,7 +43,8 @@ check_PROGRAMS = \ opal_bit_ops \ opal_path_nfs \ opal_json \ - opal_sha256 + opal_sha256 \ + opal_timer TESTS = \ $(check_PROGRAMS) @@ -95,11 +96,11 @@ opal_path_nfs_DEPENDENCIES = $(opal_path_nfs_LDADD) # $(top_builddir)/test/support/libsupport.a #opal_os_path_DEPENDENCIES = $(opal_os_path_LDADD) -#opal_timer_SOURCES = opal_timer.c -#opal_timer_LDADD = \ -# $(top_builddir)/opal/lib@OPAL_LIB_NAME@.la \ -# $(top_builddir)/test/support/libsupport.a -#opal_timer_DEPENDENCIES = $(opal_timer_LDADD) +opal_timer_SOURCES = opal_timer.c +opal_timer_LDADD = \ + $(top_builddir)/opal/lib@OPAL_LIB_NAME@.la \ + $(top_builddir)/test/support/libsupport.a +opal_timer_DEPENDENCIES = $(opal_timer_LDADD) #orte_sys_info_SOURCES = orte_sys_info.c