From aa474963936aed8cb61a30cfffa8ba5657c461f4 Mon Sep 17 00:00:00 2001 From: "Andrew C. Morrow" Date: Thu, 9 Dec 2021 12:15:56 -0500 Subject: [PATCH] WT-8497 Initial riscv64 support (#7269) Initial riscv64 support --- SConstruct | 1 + build_posix/configure.ac.in | 4 ++ cmake/configs/base.cmake | 1 + cmake/configs/riscv64/linux/config.cmake | 24 +++++++++ cmake/helpers.cmake | 2 + .../toolchains/riscv64/linux/plat_clang.cmake | 15 ++++++ cmake/toolchains/riscv64/linux/plat_gcc.cmake | 11 +++++ dist/filelist | 1 + dist/prototypes.py | 2 + dist/s_string.ok | 3 ++ src/checksum/riscv64/crc32-riscv64.c | 49 +++++++++++++++++++ src/docs/arch-fs-os.dox | 4 +- src/docs/spell.ok | 1 + src/include/gcc.h | 38 ++++++++++++++ 14 files changed, 154 insertions(+), 2 deletions(-) create mode 100644 cmake/configs/riscv64/linux/config.cmake create mode 100644 cmake/toolchains/riscv64/linux/plat_clang.cmake create mode 100644 cmake/toolchains/riscv64/linux/plat_gcc.cmake mode change 100644 => 100755 dist/prototypes.py create mode 100644 src/checksum/riscv64/crc32-riscv64.c diff --git a/SConstruct b/SConstruct index 6d971e22e98..35968868be5 100644 --- a/SConstruct +++ b/SConstruct @@ -253,6 +253,7 @@ condition_map = { 'ARM64_HOST' : False, 'POSIX_HOST' : env['PLATFORM'] == 'posix', 'POWERPC_HOST' : False, + 'RISCV64_HOST' : False, 'WINDOWS_HOST' : env['PLATFORM'] == 'win32', 'X86_HOST' : True, 'ZSERIES_HOST' : False, diff --git a/build_posix/configure.ac.in b/build_posix/configure.ac.in index c4b63ef92e5..9968763a210 100644 --- a/build_posix/configure.ac.in +++ b/build_posix/configure.ac.in @@ -64,6 +64,10 @@ AS_CASE([$host_cpu], [s390x*], [wt_cv_zseries="yes"], [wt_cv_zseries="no"]) AM_CONDITIONAL([ZSERIES_HOST], [test "$wt_cv_zseries" = "yes"]) +AS_CASE([$host_cpu], + [riscv64*], [wt_cv_riscv64="yes"], + [wt_cv_riscv64="no"]) +AM_CONDITIONAL([RISCV64_HOST], [test "$wt_cv_riscv64" = "yes"]) AS_CASE([$host_cpu], [aarch64*], [wt_cv_arm64="yes"], [wt_cv_arm64="no"]) diff --git a/cmake/configs/base.cmake b/cmake/configs/base.cmake index 48b0cddf005..6f77ebcd632 100644 --- a/cmake/configs/base.cmake +++ b/cmake/configs/base.cmake @@ -18,6 +18,7 @@ config_choice( "aarch64;WT_AARCH64;" "ppc64le;WT_PPC64;" "s390x;WT_S390X;" + "riscv64;WT_RISCV64;" ) config_choice( diff --git a/cmake/configs/riscv64/linux/config.cmake b/cmake/configs/riscv64/linux/config.cmake new file mode 100644 index 00000000000..d6d25cf2603 --- /dev/null +++ b/cmake/configs/riscv64/linux/config.cmake @@ -0,0 +1,24 @@ +# +# Public Domain 2014-present MongoDB, Inc. +# Public Domain 2008-2014 WiredTiger, Inc. +# All rights reserved. +# +# See the file LICENSE for redistribution information +# +include(CheckCCompilerFlag) + +set(WT_ARCH "riscv64" CACHE STRING "") +set(WT_OS "linux" CACHE STRING "") +set(WT_POSIX ON CACHE BOOL "") + +# Linux requires '_GNU_SOURCE' to be defined for access to GNU/Linux extension functions +# e.g. Access to O_DIRECT on Linux. Append this macro to our compiler flags for Linux-based +# builds. +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_GNU_SOURCE" CACHE STRING "" FORCE) + +# Linux requires buffers aligned to 4KB boundaries for O_DIRECT to work. +set(WT_BUFFER_ALIGNMENT_DEFAULT "4096" CACHE STRING "") + +# See https://www.sifive.com/blog/all-aboard-part-1-compiler-args +# for background on the `rv64imafdc` and `lp64d` arguments here. +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=rv64imafdc -mabi=lp64d" CACHE STRING "" FORCE) diff --git a/cmake/helpers.cmake b/cmake/helpers.cmake index dba701f386a..8d656a1c920 100644 --- a/cmake/helpers.cmake +++ b/cmake/helpers.cmake @@ -610,6 +610,8 @@ function(parse_filelist_source filelist output_var) set(arch_host "POWERPC_HOST") elseif(WT_S390X) set(arch_host "ZSERIES_HOST") + elseif(WT_RISCV64) + set(arch_host "RISCV64_HOST") endif() # Determine platform host for our filelist parse. if(WT_POSIX) diff --git a/cmake/toolchains/riscv64/linux/plat_clang.cmake b/cmake/toolchains/riscv64/linux/plat_clang.cmake new file mode 100644 index 00000000000..febc5a4479e --- /dev/null +++ b/cmake/toolchains/riscv64/linux/plat_clang.cmake @@ -0,0 +1,15 @@ +# +# Public Domain 2014-present MongoDB, Inc. +# Public Domain 2008-2014 WiredTiger, Inc. +# All rights reserved. +# +# See the file LICENSE for redistribution information. +# + +if(CMAKE_CROSSCOMPILING) + set(TRIPLE_TARGET "riscv64-unknown-linux-gnu") + set(CROSS_COMPILER_PREFIX ${TRIPLE_TARGET}-) + set(CMAKE_C_COMPILER_TARGET "${TRIPLE_TARGET}") + set(CMAKE_CXX_COMPILER_TARGET "${TRIPLE_TARGET}") + set(CMAKE_ASM_COMPILER_TARGET "${TRIPLE_TARGET}") +endif() diff --git a/cmake/toolchains/riscv64/linux/plat_gcc.cmake b/cmake/toolchains/riscv64/linux/plat_gcc.cmake new file mode 100644 index 00000000000..3d0f3352aef --- /dev/null +++ b/cmake/toolchains/riscv64/linux/plat_gcc.cmake @@ -0,0 +1,11 @@ +# +# Public Domain 2014-present MongoDB, Inc. +# Public Domain 2008-2014 WiredTiger, Inc. +# All rights reserved. +# +# See the file LICENSE for redistribution information. +# + +if(CMAKE_CROSSCOMPILING) + set(CROSS_COMPILER_PREFIX "riscv64-linux-gnu-") +endif() diff --git a/dist/filelist b/dist/filelist index 42351fdac84..4bd1fa04e71 100644 --- a/dist/filelist +++ b/dist/filelist @@ -50,6 +50,7 @@ src/btree/row_srch.c src/checksum/arm64/crc32-arm64.c ARM64_HOST src/checksum/power8/crc32.sx POWERPC_HOST src/checksum/power8/crc32_wrapper.c POWERPC_HOST +src/checksum/riscv64/crc32-riscv64.c RISCV64_HOST src/checksum/software/checksum.c src/checksum/x86/crc32-x86-alt.c X86_HOST src/checksum/x86/crc32-x86.c X86_HOST diff --git a/dist/prototypes.py b/dist/prototypes.py old mode 100644 new mode 100755 index 3c380c8a3e1..286c9b9de06 --- a/dist/prototypes.py +++ b/dist/prototypes.py @@ -60,6 +60,8 @@ def prototypes_extern(): continue if fnmatch.fnmatch(name, '*/checksum/power8/*'): continue + if fnmatch.fnmatch(name, '*/checksum/riscv64/*'): + continue if fnmatch.fnmatch(name, '*/checksum/zseries/*'): continue if fnmatch.fnmatch(name, '*/os_posix/*'): diff --git a/dist/s_string.ok b/dist/s_string.ok index 53c5de22674..692d5c40592 100644 --- a/dist/s_string.ok +++ b/dist/s_string.ok @@ -1297,6 +1297,7 @@ ret retp revint rf +risc rle rmw rng @@ -1309,6 +1310,7 @@ rts ru run's runtime +rw rwlock sH sHQ @@ -1566,6 +1568,7 @@ zSeries zalloc zf zfree +zihintpause zlib zlib's zseries diff --git a/src/checksum/riscv64/crc32-riscv64.c b/src/checksum/riscv64/crc32-riscv64.c new file mode 100644 index 00000000000..538fa682656 --- /dev/null +++ b/src/checksum/riscv64/crc32-riscv64.c @@ -0,0 +1,49 @@ +/*- + * Public Domain 2014-present MongoDB, Inc. + * Public Domain 2008-2014 WiredTiger, Inc. + * + * This is free and unencumbered software released into the public domain. + * + * Anyone is free to copy, modify, publish, use, compile, sell, or + * distribute this software, either in source code form or as a compiled + * binary, for any purpose, commercial or non-commercial, and by any + * means. + * + * In jurisdictions that recognize copyright laws, the author or authors + * of this software dedicate any and all copyright interest in the + * software to the public domain. We make this dedication for the benefit + * of the public at large and to the detriment of our heirs and + * successors. We intend this dedication to be an overt act of + * relinquishment in perpetuity of all present and future rights to this + * software under copyright law. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include + +extern uint32_t __wt_checksum_sw(const void *chunk, size_t len); + +#if defined(__GNUC__) +extern uint32_t (*wiredtiger_crc32c_func(void))(const void *, size_t) + __attribute__((visibility("default"))); +#else +extern uint32_t (*wiredtiger_crc32c_func(void))(const void *, size_t); +#endif + +/* + * wiredtiger_crc32c_func -- + * WiredTiger: detect CRC hardware and return the checksum function. + */ +uint32_t (*wiredtiger_crc32c_func(void))(const void *, size_t) +{ + return (__wt_checksum_sw); +} diff --git a/src/docs/arch-fs-os.dox b/src/docs/arch-fs-os.dox index e9e71dc9f14..eb31f7a8905 100644 --- a/src/docs/arch-fs-os.dox +++ b/src/docs/arch-fs-os.dox @@ -56,6 +56,6 @@ is mainly used for non-critical functionalities such as writing verbose messages writing to WiredTiger statistics logs. @section filesystem_usage Multiple System Architecture Support -WiredTiger supports x86_64, i386, mips, ppc, aarch64, s390x, and sparc system architectures -which are found in gcc.h. +WiredTiger supports x86_64, i386, mips, ppc, aarch64, s390x, riscv64 and sparc system +architectures which are found in gcc.h. */ diff --git a/src/docs/spell.ok b/src/docs/spell.ok index 6b19f9c50b2..ff023ea226d 100644 --- a/src/docs/spell.ok +++ b/src/docs/spell.ok @@ -562,6 +562,7 @@ req rerequests ret rf +riscv rmw ro rotn diff --git a/src/include/gcc.h b/src/include/gcc.h index 16241a02b87..249d0d8bdae 100644 --- a/src/include/gcc.h +++ b/src/include/gcc.h @@ -280,6 +280,44 @@ WT_ATOMIC_FUNC(size, size_t, size_t *vp, size_t v) __asm__ volatile("" ::: "memory"); \ } while (0) +#elif defined(__riscv) && (__riscv_xlen == 64) + +/* + * There is a `pause` instruction which has been recently adopted for RISC-V but it does not appear + * that compilers support it yet. See: + * + * https://riscv.org/announcements/2021/02/ + * risc-v-international-unveils-fast-track-architecture- + * extension-process-and-ratifies-zihintpause-extension + * + * Once compiler support is ready, this can and should be replaced with `pause` to enable more + * efficient spin locks. + */ +#define WT_PAUSE() __asm__ volatile("nop" ::: "memory") + +/* + * The RISC-V fence instruction is documented here: + * + * https://five-embeddev.com/riscv-isa-manual/latest/memory.html#sec:mm:fence + * + * On RISC-V, the fence instruction takes explicit flags that indicate the predecessor and successor + * sets. Based on the file comment description of WT_READ_BARRIER and WT_WRITE_BARRIER, those + * barriers only synchronize read/read and write/write respectively. The predecessor and successor + * sets here are selected to match that description. + */ +#define WT_FULL_BARRIER() \ + do { \ + __asm__ volatile("fence rw, rw" ::: "memory"); \ + } while (0) +#define WT_READ_BARRIER() \ + do { \ + __asm__ volatile("fence r, r" ::: "memory"); \ + } while (0) +#define WT_WRITE_BARRIER() \ + do { \ + __asm__ volatile("fence w, w" ::: "memory"); \ + } while (0) + #else #error "No write barrier implementation for this hardware" #endif