diff --git a/AUTHORS b/AUTHORS index 3c484720c..c4f27951b 100644 --- a/AUTHORS +++ b/AUTHORS @@ -17,13 +17,13 @@ Contact Information CTTC Homepage ---------------------------- - http://www.cttc.cat + https://www.cttc.cat Mailing List ---------------------------- gnss-sdr-developers@lists.sourceforge.net - https://lists.sourceforge.net/lists/listinfo/gnss-sdr-developers + https://sourceforge.net/projects/gnss-sdr/lists/gnss-sdr-developers Email @@ -64,4 +64,4 @@ Stefan van der Linden spvdlinden@gmail.com Contributor Carlos Paniego carpanie@hotmail.com Artwork # SPDX-License-Identifier: GPL-3.0-or-later -# SPDX-FileCopyrightText: 2011-2020 Carles Fernandez-Prades +# SPDX-FileCopyrightText: 2011-2022 Carles Fernandez-Prades diff --git a/CITATION.cff b/CITATION.cff index 35e0246e6..67dc07817 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -1,7 +1,6 @@ # SPDX-License-Identifier: GPL-3.0-or-later # SPDX-FileCopyrightText: 2022 C. Fernandez-Prades carles.fernandez(at)cttc.es --- -abstract: "An open-source Global Navigation Satellite Systems software-defined receiver." authors: - affiliation: "Centre Tecnològic de Telecomunicacions de Catalunya (CTTC)" alias: carlesfernandez @@ -102,7 +101,7 @@ authors: family-names: "van der Linden" given-names: Stefan cff-version: "1.2.0" -date-released: "2022-02-14" +date-released: "2022-04-20" identifiers: - description: "The concept DOI of the work. This is a DOI always pointing to the latest stable release." type: doi @@ -326,4 +325,4 @@ repository-code: "https://github.com/gnss-sdr/gnss-sdr" title: GNSS-SDR type: software url: "https://gnss-sdr.org" -version: "0.0.16" +version: "0.0.17" diff --git a/CMakeLists.txt b/CMakeLists.txt index ceebcde7f..94e2ef39e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ endif() # Build type can still be overridden by setting -DCMAKE_BUILD_TYPE= set(CMAKE_BUILD_TYPE "Release" CACHE STRING "") -cmake_minimum_required(VERSION 2.8.12...3.22) +cmake_minimum_required(VERSION 2.8.12...3.23) project(gnss-sdr CXX C) list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules) @@ -101,7 +101,7 @@ option(ENABLE_SYSTEM_TESTING_EXTRA "Download external tools and build extra syst option(ENABLE_GNSS_SIM_INSTALL "Enable the installation of gnss_sim on the fly" ON) -option(ENABLE_OWN_CPUFEATURES "Force the building of the cpu_features library even if it is already installed" ON) +option(ENABLE_CPUFEATURES "Make use of the cpu_features library" ON) if(NOT (ENABLE_UNIT_TESTING_EXTRA OR ENABLE_SYSTEM_TESTING_EXTRA OR ENABLE_FPGA)) set(ENABLE_GNSS_SIM_INSTALL OFF) @@ -166,9 +166,9 @@ endif() set(VERSION_INFO_MAJOR_VERSION 0) set(VERSION_INFO_API_COMPAT 0) if(${THIS_IS_A_RELEASE}) - set(VERSION_INFO_MINOR_VERSION 16) + set(VERSION_INFO_MINOR_VERSION 17) else() - set(VERSION_INFO_MINOR_VERSION 16.git-${GIT_BRANCH}-${GIT_COMMIT_HASH}) + set(VERSION_INFO_MINOR_VERSION 17.git-${GIT_BRANCH}-${GIT_COMMIT_HASH}) endif() set(VERSION ${VERSION_INFO_MAJOR_VERSION}.${VERSION_INFO_API_COMPAT}.${VERSION_INFO_MINOR_VERSION}) @@ -320,7 +320,7 @@ set(GNSSSDR_PROTOBUF_MIN_VERSION "3.0.0") # Versions to download and build (but not installed) if not found ################################################################################ set(GNSSSDR_GFLAGS_LOCAL_VERSION "2.2.2") -set(GNSSSDR_GLOG_LOCAL_VERSION "0.5.0") +set(GNSSSDR_GLOG_LOCAL_VERSION "0.6.0") set(GNSSSDR_ARMADILLO_LOCAL_VERSION "10.8.x") if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0) OR (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)) @@ -330,12 +330,16 @@ else() endif() set(GNSSSDR_GNSS_SIM_LOCAL_VERSION "master") set(GNSSSDR_GPSTK_LOCAL_VERSION "8.0.0") -set(GNSSSDR_MATIO_LOCAL_VERSION "1.5.21") +set(GNSSSDR_MATIO_LOCAL_VERSION "1.5.23") set(GNSSSDR_PUGIXML_LOCAL_VERSION "1.12") -set(GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION "3.19.4") +set(GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION "3.20.0") set(GNSSSDR_BENCHMARK_LOCAL_VERSION "1.6.1") set(GNSSSDR_MATHJAX_EXTERNAL_VERSION "2.7.7") +if(CMAKE_VERSION VERSION_LESS "3.16") + set(GNSSSDR_GLOG_LOCAL_VERSION "0.5.0") +endif() + if(CMAKE_VERSION VERSION_LESS "3.3") set(GNSSSDR_GLOG_LOCAL_VERSION "0.4.0") # Fix for Debian 8 endif() @@ -1156,7 +1160,6 @@ if(NOT VOLKGNSSSDR_FOUND) set(VOLK_GNSSSDR_CMAKE_ARGS ${VOLK_GNSSSDR_COMPILER} -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/volk_gnsssdr_module/install -DENABLE_STATIC_LIBS=ON - -DENABLE_OWN_CPUFEATURES=${ENABLE_OWN_CPUFEATURES} -DENABLE_PROFILING=${ENABLE_PROFILING} -DENABLE_ORC=${ORC_ENABLED} ${STRIP_VOLK_GNSSSDR_PROFILE} @@ -1193,15 +1196,8 @@ if(NOT VOLKGNSSSDR_FOUND) endif() include(GNUInstallDirs) set(SUPPORTED_CPU_FEATURES_ARCH FALSE) - if(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips") - set(SUPPORTED_CPU_FEATURES_ARCH TRUE) - elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm") - set(SUPPORTED_CPU_FEATURES_ARCH TRUE) - elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^aarch64") - set(SUPPORTED_CPU_FEATURES_ARCH TRUE) - elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(x86_64)|(AMD64|amd64)|(^i.86$)") - set(SUPPORTED_CPU_FEATURES_ARCH TRUE) - elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)") + if(CMAKE_SYSTEM_PROCESSOR MATCHES + "(^mips)|(^arm)|(^aarch64)|(x86_64)|(AMD64|amd64)|(^i.86$)|(^powerpc)|(^ppc)") set(SUPPORTED_CPU_FEATURES_ARCH TRUE) endif() if(${CMAKE_INSTALL_LIBDIR} MATCHES lib64) @@ -1227,29 +1223,38 @@ if(NOT VOLKGNSSSDR_FOUND) ${CMAKE_BINARY_DIR}/volk_gnsssdr_module/install/lib${VOLK_GNSSSDR_LIB_SUFFIX}/${CMAKE_FIND_LIBRARY_PREFIXES}volk_gnsssdr${CMAKE_STATIC_LIBRARY_SUFFIX} ${CMAKE_BINARY_DIR}/volk_gnsssdr_module/install/bin/volk_gnsssdr_profile ) - if(NOT ENABLE_OWN_CPUFEATURES) - find_package(CpuFeatures QUIET) - set_package_properties(CpuFeatures PROPERTIES + if(ENABLE_CPUFEATURES) + find_package(CPUFEATURES) + set_package_properties(CPUFEATURES PROPERTIES URL "https://github.com/google/cpu_features" PURPOSE "Used by the volk_gnsssdr library." TYPE REQUIRED ) endif() - if(CpuFeatures_FOUND) - message(STATUS "Found CpuFeatures: (found version ${CpuFeatures_VERSION})") - set_package_properties(CpuFeatures PROPERTIES - DESCRIPTION "A cross platform C99 library to get CPU features at runtime (found: v${CpuFeatures_VERSION})" + if(CPUFEATURES_FOUND) + message(STATUS "Found CpuFeatures: (found version ${CPUFEATURES_VERSION})") + set_package_properties(CPUFEATURES PROPERTIES + DESCRIPTION "A cross platform C99 library to get CPU features at runtime (version: ${CPUFEATURES_VERSION})" ) else() - set_package_properties(CpuFeatures PROPERTIES + set_package_properties(CPUFEATURES PROPERTIES DESCRIPTION "A cross platform C99 library to get CPU features at runtime" - PURPOSE "CpuFeatures will be built when doing '${CMAKE_MAKE_PROGRAM_PRETTY_NAME}'." - ) - set(VOLK_GNSSSDR_BUILD_BYPRODUCTS - ${VOLK_GNSSSDR_BUILD_BYPRODUCTS} - ${CMAKE_BINARY_DIR}/volk_gnsssdr_module/install/${CMAKE_INSTALL_LIBDIR}/${CMAKE_FIND_LIBRARY_PREFIXES}cpu_features${CMAKE_STATIC_LIBRARY_SUFFIX} ) + if(VOLK_VERSION AND VOLK_VERSION VERSION_GREATER "2.3" AND VOLK_VERSION VERSION_LESS "2.5.2") # detect "hidden" cpu_features 0.6.0 + set(ENABLE_CPUFEATURES OFF) + else() + set_package_properties(CPUFEATURES PROPERTIES + PURPOSE "CpuFeatures will be built when doing '${CMAKE_MAKE_PROGRAM_PRETTY_NAME}'." + ) + set(VOLK_GNSSSDR_BUILD_BYPRODUCTS + ${VOLK_GNSSSDR_BUILD_BYPRODUCTS} + ${CMAKE_BINARY_DIR}/volk_gnsssdr_module/install/${CMAKE_INSTALL_LIBDIR}/${CMAKE_FIND_LIBRARY_PREFIXES}cpu_features${CMAKE_STATIC_LIBRARY_SUFFIX} + ) + endif() endif() + set(VOLK_GNSSSDR_CMAKE_ARGS ${VOLK_GNSSSDR_CMAKE_ARGS} + -DVOLK_CPU_FEATURES=${ENABLE_CPUFEATURES} + ) ExternalProject_Add(volk_gnsssdr_module PREFIX ${CMAKE_BINARY_DIR}/volk_gnsssdr_module SOURCE_DIR ${CMAKE_SOURCE_DIR}/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr @@ -1265,6 +1270,10 @@ if(NOT VOLKGNSSSDR_FOUND) INSTALL_DIR ${CMAKE_BINARY_DIR}/volk_gnsssdr_module/install ) else() + set(ENABLE_CPUFEATURES OFF) + set(VOLK_GNSSSDR_CMAKE_ARGS ${VOLK_GNSSSDR_CMAKE_ARGS} + -DVOLK_CPU_FEATURES=${ENABLE_CPUFEATURES} + ) ExternalProject_Add(volk_gnsssdr_module PREFIX ${CMAKE_BINARY_DIR}/volk_gnsssdr_module SOURCE_DIR ${CMAKE_SOURCE_DIR}/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr @@ -1292,8 +1301,8 @@ if(NOT VOLKGNSSSDR_FOUND) set_property(TARGET volk_gnsssdr PROPERTY IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/volk_gnsssdr_module/install/lib${VOLK_GNSSSDR_LIB_SUFFIX}/libvolk_gnsssdr${CMAKE_STATIC_LIBRARY_SUFFIX}) set(VOLK_GNSSSDR_INCLUDE_DIRS "${CMAKE_BINARY_DIR}/volk_gnsssdr_module/build/include/;${CMAKE_SOURCE_DIR}/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/include;${ORC_INCLUDE_DIRS}") set(VOLK_GNSSSDR_LIBRARIES volk_gnsssdr ${ORC_LIBRARIES_STATIC}) - if(CpuFeatures_FOUND) - set(VOLK_GNSSSDR_LIBRARIES ${VOLK_GNSSSDR_LIBRARIES} CpuFeatures::cpu_features) + if(CPUFEATURES_FOUND) + set(VOLK_GNSSSDR_LIBRARIES ${VOLK_GNSSSDR_LIBRARIES} CpuFeature::cpu_features) endif() if(NOT TARGET Volkgnsssdr::volkgnsssdr) @@ -1308,7 +1317,7 @@ if(NOT VOLKGNSSSDR_FOUND) INTERFACE_LINK_LIBRARIES "${VOLK_GNSSSDR_LIBRARIES}" ) if(CMAKE_VERSION VERSION_GREATER 3.0 AND SUPPORTED_CPU_FEATURES_ARCH) - if(NOT CpuFeatures_FOUND) + if(NOT CPUFEATURES_FOUND AND ENABLE_CPUFEATURES) set_target_properties(Volkgnsssdr::volkgnsssdr PROPERTIES INTERFACE_LINK_LIBRARIES ${CMAKE_BINARY_DIR}/volk_gnsssdr_module/install/${CMAKE_INSTALL_LIBDIR}/${CMAKE_FIND_LIBRARY_PREFIXES}cpu_features${CMAKE_STATIC_LIBRARY_SUFFIX} ) @@ -1338,7 +1347,6 @@ if(NOT VOLKGNSSSDR_FOUND) PURPOSE "volk_gnsssdr will be built when doing '${CMAKE_MAKE_PROGRAM_PRETTY_NAME}'." ) else() - set(ENABLE_OWN_CPUFEATURES OFF) set(ENABLE_ORC OFF) endif() @@ -1674,9 +1682,12 @@ ${CMAKE_BINARY_DIR}/thirdparty/glog/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/configure ${CMAKE_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/${CMAKE_FIND_LIBRARY_PREFIXES}glogd${CMAKE_STATIC_LIBRARY_SUFFIX} ) endif() - if((CMAKE_VERSION VERSION_GREATER 3.12.0) AND NOT (CMAKE_GENERATOR STREQUAL Xcode)) + if((CMAKE_VERSION VERSION_GREATER 3.12.0) AND NOT (CMAKE_GENERATOR STREQUAL Xcode) AND NOT CMAKE_CROSSCOMPILING) set(PARALLEL_BUILD "--parallel 2") endif() + if(GNSSSDR_GLOG_LOCAL_VERSION VERSION_GREATER 0.5.0) + set(GLOG_GTEST -DWITH_GTEST=FALSE) + endif() ExternalProject_Add(glog-${GNSSSDR_GLOG_LOCAL_VERSION} DEPENDS ${TARGET_GFLAGS} PREFIX ${CMAKE_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION} @@ -1689,6 +1700,7 @@ ${CMAKE_BINARY_DIR}/thirdparty/glog/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/configure ${GLOG_TOOLCHAIN_FILE} -DCMAKE_BUILD_TYPE=$<$:Debug>$<$:Release>$<$:RelWithDebInfo>$<$:MinSizeRel>$<$:Debug>$<$:Debug>$<$:RelWithDebInfo>$<$:RelWithDebInfo>$<$:Debug> -DBUILD_SHARED_LIBS=OFF + ${GLOG_GTEST} -DBUILD_TESTING=OFF BUILD_COMMAND "${GLOG_MAKE_PROGRAM} ${PARALLEL_BUILD}" BUILD_BYPRODUCTS ${GLOG_BUILD_BYPRODUCTS} @@ -3353,7 +3365,7 @@ add_feature_info(ENABLE_GNSS_SIM_INSTALL ENABLE_GNSS_SIM_INSTALL "Enables downlo add_feature_info(ENABLE_INSTALL_TESTS ENABLE_INSTALL_TESTS "Install test binaries when doing '${CMAKE_MAKE_PROGRAM_PRETTY_NAME} install'.") add_feature_info(ENABLE_BENCHMARKS ENABLE_BENCHMARKS "Enables building of code snippet benchmarks.") add_feature_info(ENABLE_EXTERNAL_MATHJAX ENABLE_EXTERNAL_MATHJAX "Use MathJax from an external CDN in HTML docs when doing '${CMAKE_MAKE_PROGRAM_PRETTY_NAME} doc'.") -add_feature_info(ENABLE_OWN_CPUFEATURES ENABLE_OWN_CPUFEATURES "Force building own local version of the cpu_features library, even if it is already installed.") +add_feature_info(ENABLE_CPUFEATURES ENABLE_CPUFEATURES "Make use of the cpu_features library.") add_feature_info(Boost_USE_STATIC_LIBS Boost_USE_STATIC_LIBS "Use Boost static libraries.") message(STATUS "") diff --git a/README.md b/README.md index 13904c1d8..a43d573bf 100644 --- a/README.md +++ b/README.md @@ -170,6 +170,9 @@ Please note that the required files from `libgtest-dev` were moved to again to `libgtest-dev` in Debian 10 "buster" and Ubuntu 18.10 "cosmic" (and above). +Since Ubuntu 21.04 Hirsute / Debian 11, the package `libcpu-features-dev` is +also required. + **Note for Ubuntu 14.04 LTS "trusty" users:** you will need to build from source and install GNU Radio manually, as explained below, since GNSS-SDR requires `gnuradio-dev` >= 3.7.3, and Ubuntu 14.04 came with 3.7.2. Install all the @@ -470,9 +473,9 @@ your GNU/Linux distribution, GNSS-SDR can also work well with OpenSSL. #### Install [Matio](https://github.com/tbeu/matio "Matio's Homepage"), MATLAB MAT file I/O library: ``` -$ wget https://github.com/tbeu/matio/releases/download/v1.5.21/matio-1.5.21.tar.gz -$ tar xvfz matio-1.5.21.tar.gz -$ cd matio-1.5.21 +$ wget https://github.com/tbeu/matio/releases/download/v1.5.23/matio-1.5.23.tar.gz +$ tar xvfz matio-1.5.23.tar.gz +$ cd matio-1.5.23 $ ./configure $ make $ sudo make install @@ -493,9 +496,9 @@ $ sudo apt-get install autoconf automake libtool curl make g++ unzip and then: ``` -$ wget https://github.com/protocolbuffers/protobuf/releases/download/v3.19.4/protobuf-cpp-3.19.4.tar.gz -$ tar xvfz protobuf-cpp-3.19.4.tar.gz -$ cd protobuf-3.19.4 +$ wget https://github.com/protocolbuffers/protobuf/releases/download/v3.20.0/protobuf-cpp-3.20.0.tar.gz +$ tar xvfz protobuf-cpp-3.20.0.tar.gz +$ cd protobuf-3.20.0 $ ./autogen.sh $ ./configure $ make @@ -2128,7 +2131,7 @@ if you reference the following article to credit the GNSS-SDR project: - C. Fernández-Prades, J. Arribas, P. Closas, C. Avilés, and L. Esteve, - [GNSS-SDR: an open source tool for researchers and developers](http://www.cttc.es/publication/gnss-sdr-an-open-source-tool-for-researchers-and-developers/), + [GNSS-SDR: an open source tool for researchers and developers](https://www.researchgate.net/publication/233380791_GNSS-SDR_An_open_source_tool_for_researchers_and_developers), in Proceedings of the 24th International Technical Meeting of The Satellite Division of the Institute of Navigation (ION GNSS), Portland, Oregon, Sept. 19-23, 2011, pp. 780-794. diff --git a/cmake/Modules/FindCPUFEATURES.cmake b/cmake/Modules/FindCPUFEATURES.cmake new file mode 100644 index 000000000..6f25e91d2 --- /dev/null +++ b/cmake/Modules/FindCPUFEATURES.cmake @@ -0,0 +1,91 @@ +# GNSS-SDR is a Global Navigation Satellite System software-defined receiver. +# This file is part of GNSS-SDR. +# +# SPDX-FileCopyrightText: 2021 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-License-Identifier: BSD-3-Clause + +set(FPHSA_NAME_MISMATCHED ON) + +find_library(CPUFEATURES_LIBRARIES + NAMES cpu_features + PATHS /usr/lib + /usr/lib64 + /usr/lib/x86_64-linux-gnu + /usr/lib/i386-linux-gnu + /usr/lib/arm-linux-gnueabihf + /usr/lib/arm-linux-gnueabi + /usr/lib/aarch64-linux-gnu + /usr/lib/mipsel-linux-gnu + /usr/lib/mips-linux-gnu + /usr/lib/mips64el-linux-gnuabi64 + /usr/lib/powerpc-linux-gnu + /usr/lib/powerpc64-linux-gnu + /usr/lib/powerpc64le-linux-gnu + /usr/lib/powerpc-linux-gnuspe + /usr/lib/hppa-linux-gnu + /usr/lib/s390x-linux-gnu + /usr/lib/i386-gnu + /usr/lib/hppa-linux-gnu + /usr/lib/x86_64-kfreebsd-gnu + /usr/lib/i386-kfreebsd-gnu + /usr/lib/m68k-linux-gnu + /usr/lib/sh4-linux-gnu + /usr/lib/sparc64-linux-gnu + /usr/lib/x86_64-linux-gnux32 + /usr/lib/alpha-linux-gnu + /usr/lib/riscv64-linux-gnu + /usr/local/lib + /usr/local/lib64 + /opt/local/lib +) + +find_path(CPUFEATURES_INCLUDE_DIR cpu_features_macros.h + PATHS $ENV{CPUFEATURES_DIR}/include + $ENV{CPUFEATURES_DIR} + /usr/include + /usr/local/include + ~/Library/Frameworks + /Library/Frameworks + /sw/include # Fink + /opt/local/include # MacPorts + /opt/csw/include # Blastwave + PATH_SUFFIXES cpu_features +) + +if(CPUFEATURES_INCLUDE_DIR AND CPUFEATURES_LIBRARIES) + if(NOT PACKAGE_VERSION) + set(PACKAGE_VERSION "") + endif() + set(OLD_PACKAGE_VERSION ${PACKAGE_VERSION}) + unset(PACKAGE_VERSION) + list(GET CPUFEATURES_LIBRARIES 0 FIRST_DIR) + get_filename_component(CPUFEATURES_LIBRARIES_PATH ${FIRST_DIR} DIRECTORY) + if(EXISTS ${CPUFEATURES_LIBRARIES_PATH}/cmake/CpuFeatures/CpuFeaturesConfigVersion.cmake) + include(${CPUFEATURES_LIBRARIES_PATH}/cmake/CpuFeatures/CpuFeaturesConfigVersion.cmake) + endif() + if(PACKAGE_VERSION) + set(CPUFEATURES_VERSION ${PACKAGE_VERSION}) + else() + set(CPUFEATURES_VERSION "Unknown") + endif() + set(PACKAGE_VERSION ${OLD_PACKAGE_VERSION}) +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(CPUFEATURES + DEFAULT_MSG + CPUFEATURES_LIBRARIES + CPUFEATURES_INCLUDE_DIR +) + +if(CPUFEATURES_FOUND AND NOT TARGET CpuFeature::cpu_features) + add_library(CpuFeature::cpu_features STATIC IMPORTED) + set_target_properties(CpuFeature::cpu_features PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES "C" + IMPORTED_LOCATION "${CPUFEATURES_LIBRARIES}" + INTERFACE_INCLUDE_DIRECTORIES "${CPUFEATURES_INCLUDE_DIR}" + INTERFACE_LINK_LIBRARIES "${CPUFEATURES_LIBRARIES}" + ) +endif() + +mark_as_advanced(CPUFEATURES_LIBRARIES) diff --git a/conf/gnss-sdr_GPS_L1_plutosdr_realtime.conf b/conf/gnss-sdr_GPS_L1_plutosdr_realtime.conf index adbe9855a..6b0de3745 100644 --- a/conf/gnss-sdr_GPS_L1_plutosdr_realtime.conf +++ b/conf/gnss-sdr_GPS_L1_plutosdr_realtime.conf @@ -12,7 +12,7 @@ ;######### GLOBAL OPTIONS ################## ;internal_fs_sps: Internal signal sampling frequency after the signal conditioning stage [sps]. ;FOR USE GNSS-SDR WITH RTLSDR DONGLES USER MUST SET THE CALIBRATED SAMPLE RATE HERE -; i.e. using front-end-cal as reported here:http://www.cttc.es/publication/turning-a-television-into-a-gnss-receiver/ +; i.e. using front-end-cal as reported here: https://www.researchgate.net/publication/257137427_Turning_a_Television_into_a_GNSS_Receiver GNSS-SDR.internal_fs_sps=4000000 GNSS-SDR.use_acquisition_resampler=true @@ -143,4 +143,4 @@ PVT.nmea_dump_devname=/dev/pts/4 PVT.dump=false PVT.flag_rtcm_server=true PVT.flag_rtcm_tty_port=false -PVT.rtcm_dump_devname=/dev/pts/1 \ No newline at end of file +PVT.rtcm_dump_devname=/dev/pts/1 diff --git a/conf/gnss-sdr_GPS_L1_rtl_tcp_realtime.conf b/conf/gnss-sdr_GPS_L1_rtl_tcp_realtime.conf index 64dc34808..6266ea924 100644 --- a/conf/gnss-sdr_GPS_L1_rtl_tcp_realtime.conf +++ b/conf/gnss-sdr_GPS_L1_rtl_tcp_realtime.conf @@ -12,7 +12,8 @@ ;######### GLOBAL OPTIONS ################## ;internal_fs_sps: Internal signal sampling frequency after the signal conditioning stage [samples per second]. ;FOR USE GNSS-SDR WITH RTLSDR DONGLES USER MUST SET THE CALIBRATED SAMPLE RATE HERE -; i.e. using front-end-cal as reported here:http://www.cttc.es/publication/turning-a-television-into-a-gnss-receiver/ +; i.e. using front-end-cal as reported here: https://www.researchgate.net/publication/257137427_Turning_a_Television_into_a_GNSS_Receiver +; i.e. using front-end-cal as reported here: https://www.researchgate.net/publication/257137427_Turning_a_Television_into_a_GNSS_Receiver GNSS-SDR.internal_fs_sps=1200000 @@ -80,7 +81,7 @@ InputFilter.grid_density=16 ;#The following options are used only in Freq_Xlating_Fir_Filter implementation. ;#InputFilter.IF is the intermediate frequency (in Hz) shifted down to zero Hz ;FOR USE GNSS-SDR WITH RTLSDR DONGLES USER MUST SET THE CALIBRATED SAMPLE RATE HERE -; i.e. using front-end-cal as reported here:http://www.cttc.es/publication/turning-a-television-into-a-gnss-receiver/ +; i.e. using front-end-cal as reported here: https://www.researchgate.net/publication/257137427_Turning_a_Television_into_a_GNSS_Receiver InputFilter.sampling_frequency=1200000 InputFilter.IF=80558 diff --git a/conf/gnss-sdr_GPS_L1_rtlsdr_realtime.conf b/conf/gnss-sdr_GPS_L1_rtlsdr_realtime.conf index 17b261526..3b51d2532 100644 --- a/conf/gnss-sdr_GPS_L1_rtlsdr_realtime.conf +++ b/conf/gnss-sdr_GPS_L1_rtlsdr_realtime.conf @@ -12,7 +12,7 @@ ;######### GLOBAL OPTIONS ################## ;internal_fs_sps: Internal signal sampling frequency after the signal conditioning stage [samples per second]. ;FOR USE GNSS-SDR WITH RTLSDR DONGLES USER MUST SET THE CALIBRATED SAMPLE RATE HERE -; i.e. using front-end-cal as reported here:http://www.cttc.es/publication/turning-a-television-into-a-gnss-receiver/ +; i.e. using front-end-cal as reported here: https://www.researchgate.net/publication/257137427_Turning_a_Television_into_a_GNSS_Receiver GNSS-SDR.internal_fs_sps=1999898 @@ -34,7 +34,7 @@ GNSS-SDR.SUPL_CI=0x31b0 SignalSource.implementation=Osmosdr_Signal_Source SignalSource.item_type=gr_complex ; FOR USE GNSS-SDR WITH RTLSDR DONGLES USER MUST SET THE CALIBRATED SAMPLE RATE HERE -; i.e. using front-end-cal as reported here:http://www.cttc.es/publication/turning-a-television-into-a-gnss-receiver/ +; i.e. using front-end-cal as reported here: https://www.researchgate.net/publication/257137427_Turning_a_Television_into_a_GNSS_Receiver SignalSource.sampling_frequency=2000000 SignalSource.freq=1575420000 SignalSource.gain=40 @@ -88,7 +88,7 @@ InputFilter.band2_error=1.0 InputFilter.filter_type=bandpass InputFilter.grid_density=16 ;FOR USE GNSS-SDR WITH RTLSDR DONGLES USER MUST SET THE CALIBRATED SAMPLE RATE HERE -; i.e. using front-end-cal as reported here:http://www.cttc.es/publication/turning-a-television-into-a-gnss-receiver/ +; i.e. using front-end-cal as reported here: https://www.researchgate.net/publication/257137427_Turning_a_Television_into_a_GNSS_Receiver InputFilter.sampling_frequency=1999898 InputFilter.IF=80558 ; IF deviation due to front-end LO inaccuracies [Hz] diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 77cc00563..339eb4b5e 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -12,8 +12,39 @@ SPDX-FileCopyrightText: 2011-2022 Carles Fernandez-Prades Volk, a Vector-Optimized Library of Kernels which provides an abstraction of optimized math routines targeting several SIMD processors, and, optionally, -\li GNU Radio modules for hardware interface (gr-uhd, gr-osmosdr, gr-iio), +\li GNU Radio modules for hardware interface (gr-uhd, gr-osmosdr, gr-iio), \li Benchmark, a library to benchmark code snippets, \li Gperftools, which provides fast, multi-threaded malloc() and performance analysis tools. @@ -584,10 +584,10 @@ but if you distribute the code, it has to remain under GPL. If you use GNSS-SDR to produce a research paper or Thesis, we would appreciate if you reference any of these articles to credit the GNSS-SDR project: -\li \anchor Navitec2012 C. Fernández-Prades, J. Arribas, L. Esteve, D. Pubill, P. Closas, An Open Source Galileo E1 Software Receiver, in Proc. of the 6th ESA Workshop on Satellite Navigation Technologies (NAVITEC 2012), ESTEC, Noordwijk, The Netherlands, Dec. 2012. +\li \anchor Navitec2012 C. Fernández-Prades, J. Arribas, L. Esteve, D. Pubill, P. Closas, An Open Source Galileo E1 Software Receiver, in Proc. of the 6th ESA Workshop on Satellite Navigation Technologies (NAVITEC 2012), ESTEC, Noordwijk, The Netherlands, Dec. 2012. \li J. Arribas, GNSS Array-based Acquisition: Theory and Implementation, PhD Thesis, Universitat Politècnica de Catalunya, Barcelona, Spain, June 2012. -\li C. Fernández-Prades, J. Arribas, P. Closas, C. Avilés, and L. Esteve, GNSS-SDR: an open source tool for researchers and developers, in Proc. of the ION GNSS 2011 Conference, Portland, Oregon, Sept. 19-23, 2011. -\li C. Fernández-Prades, C. Avilés, L. Esteve, J. Arribas, and P. Closas, Design patterns for GNSS software receivers, in Proc. of the 5th ESA Workshop on Satellite Navigation Technologies (NAVITEC'2010), ESTEC, Noordwijk, The Netherlands, Dec. 2010. DOI:10.1109/NAVITEC.2010.5707981 +\li C. Fernández-Prades, J. Arribas, P. Closas, C. Avilés, and L. Esteve, GNSS-SDR: an open source tool for researchers and developers, in Proc. of the ION GNSS 2011 Conference, Portland, Oregon, Sept. 19-23, 2011. +\li C. Fernández-Prades, C. Avilés, L. Esteve, J. Arribas, and P. Closas, Design patterns for GNSS software receivers, in Proc. of the 5th ESA Workshop on Satellite Navigation Technologies (NAVITEC'2010), ESTEC, Noordwijk, The Netherlands, Dec. 2010. DOI:10.1109/NAVITEC.2010.5707981 For LaTeX users, these are the BibTeX cites for your convenience: diff --git a/docs/manpage/front-end-cal-manpage b/docs/manpage/front-end-cal-manpage index 24de486f9..c2e300700 100644 --- a/docs/manpage/front-end-cal-manpage +++ b/docs/manpage/front-end-cal-manpage @@ -32,7 +32,7 @@ The crystal oscillator that ships with the RTL2832U family devices exhibits limi \.TP Example of configuration file available at: ${prefix}/share/gnss\-sdr/conf/front\-end\-cal.conf, where ${prefix}$ uses to be /usr or /usr/local. This will be the configuration file used by default if the \fB\-config_file\fR option is not set. \.TP -[1] C. Fernandez\-Prades, J. Arribas, P. Closas, \fITurning a Television into a GNSS Receiver\fR, in Proceedings of ION GNSS+, 15\-16 September 2013, Nashville, Tennessee (USA). A draft copy is freely available at http://www.cttc.es/publication/turning\-a\-television\-into\-a\-gnss\-receiver/ +[1] C. Fernandez\-Prades, J. Arribas, P. Closas, \fITurning a Television into a GNSS Receiver\fR, in Proceedings of ION GNSS+, 15\-16 September 2013, Nashville, Tennessee (USA). A draft copy is freely available at https://www.researchgate.net/publication/257137427_Turning_a_Television_into_a_GNSS_Receiver \.TP Check https://gnss\-sdr.org for more information. .SH BUGS @@ -40,4 +40,4 @@ No known bugs. .SH AUTHOR Javier Arribas (javier.arribas@cttc.es) \.TP -This software has been developed at CTTC (Centre Tecnologic de Telecomunicacions de Catalunya, http://www.cttc.es) with contributions from around the world. +This software has been developed at CTTC (Centre Tecnologic de Telecomunicacions de Catalunya, https://www.cttc.cat) with contributions from around the world. diff --git a/docs/manpage/gnss-sdr-manpage b/docs/manpage/gnss-sdr-manpage index f11304483..452fe8a28 100644 --- a/docs/manpage/gnss-sdr-manpage +++ b/docs/manpage/gnss-sdr-manpage @@ -2,7 +2,7 @@ .\" SPDX-License-Identifier: GPL-3.0-or-later .\" SPDX-FileCopyrightText: Carles Fernandez-Prades .\" Contact carles.fernandez@cttc.es to correct errors or typos. -.TH gnss\-sdr 1 "15 Feb 2022" "0.0.16" "gnss\-sdr man page" +.TH gnss\-sdr 1 "20 Apr 2022" "0.0.17" "gnss\-sdr man page" .SH NAME \fBgnss\-sdr\fR \- GNSS Software Defined Receiver. .SH SYNOPSIS @@ -78,4 +78,4 @@ Please report bugs at https://github.com/gnss-sdr/gnss-sdr/issues .SH AUTHOR Carles Fernandez\-Prades (carles.fernandez@cttc.es) \.TP -This software package has been developed at CTTC (Centre Tecnologic de Telecomunicacions de Catalunya, http://www.cttc.es) with contributions from around the world. +This software package has been developed at CTTC (Centre Tecnologic de Telecomunicacions de Catalunya, https://www.cttc.cat) with contributions from around the world. diff --git a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc index b9dfff0ab..6fb9a2510 100644 --- a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc +++ b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_gs.cc @@ -1254,8 +1254,9 @@ void rtklib_pvt_gs::msg_handler_telemetry(const pmt::pmt_t& msg) } if (gps_cnav_ephemeris->signal_health != 0) { - std::cout << TEXT_RED << "Satellite " << Gnss_Satellite(std::string("GPS"), gps_cnav_ephemeris->PRN) - << " is not healthy, not used for navigation" << TEXT_RESET << '\n'; + std::cout << "Satellite " << Gnss_Satellite(std::string("GPS"), gps_cnav_ephemeris->PRN) + << " does not report a healthy status in the CNAV message," + << " use PVT solutions at your own risk.\n"; } DLOG(INFO) << "New GPS CNAV ephemeris record has arrived "; } @@ -2023,7 +2024,7 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item if (tmp_eph_iter_cnav != d_internal_pvt_solver->gps_cnav_ephemeris_map.cend()) { const uint32_t prn_aux = tmp_eph_iter_cnav->second.PRN; - if ((prn_aux == in[i][epoch].PRN) && (((std::string(in[i][epoch].Signal) == std::string("2S")) || (std::string(in[i][epoch].Signal) == std::string("L5"))) && (tmp_eph_iter_cnav->second.signal_health == 0))) + if ((prn_aux == in[i][epoch].PRN) && (((std::string(in[i][epoch].Signal) == std::string("2S")) || (std::string(in[i][epoch].Signal) == std::string("L5"))))) { store_valid_observable = true; } @@ -2114,10 +2115,10 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item { const double Rx_clock_offset_s = d_internal_pvt_solver->get_time_offset_s(); - //**************** time tags **************** + // **************** time tags **************** if (d_enable_rx_clock_correction == false) // todo: currently only works if clock correction is disabled (computed clock offset is applied here) { - //************ Source TimeTag comparison with GNSS computed TOW ************* + // ************ Source TimeTag comparison with GNSS computed TOW ************* if (!d_TimeChannelTagTimestamps.empty()) { @@ -2151,7 +2152,7 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item } } } - //********************************************** + // ********************************************** if (fabs(Rx_clock_offset_s) * 1000.0 > d_max_obs_block_rx_clock_offset_ms) { diff --git a/src/algorithms/acquisition/gnuradio_blocks/galileo_pcps_8ms_acquisition_cc.cc b/src/algorithms/acquisition/gnuradio_blocks/galileo_pcps_8ms_acquisition_cc.cc index 85ad12ff1..b534f30f9 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/galileo_pcps_8ms_acquisition_cc.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/galileo_pcps_8ms_acquisition_cc.cc @@ -216,7 +216,7 @@ int galileo_pcps_8ms_acquisition_cc::general_work(int noutput_items, d_state = 1; } - d_sample_counter += static_cast(d_fft_size * ninput_items[0]); // sample counter + d_sample_counter += static_cast(d_fft_size) * ninput_items[0]; // sample counter consume_each(ninput_items[0]); break; @@ -368,7 +368,7 @@ int galileo_pcps_8ms_acquisition_cc::general_work(int noutput_items, d_active = false; d_state = 0; - d_sample_counter += d_fft_size * ninput_items[0]; // sample counter + d_sample_counter += static_cast(d_fft_size) * ninput_items[0]; // sample counter consume_each(ninput_items[0]); acquisition_message = 1; @@ -403,7 +403,7 @@ int galileo_pcps_8ms_acquisition_cc::general_work(int noutput_items, d_active = false; d_state = 0; - d_sample_counter += static_cast(d_fft_size * ninput_items[0]); // sample counter + d_sample_counter += static_cast(d_fft_size) * ninput_items[0]; // sample counter consume_each(ninput_items[0]); acquisition_message = 2; diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_cccwsr_acquisition_cc.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_cccwsr_acquisition_cc.cc index 47db3495a..47905fab9 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_cccwsr_acquisition_cc.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_cccwsr_acquisition_cc.cc @@ -226,7 +226,7 @@ int pcps_cccwsr_acquisition_cc::general_work(int noutput_items, d_state = 1; } - d_sample_counter += static_cast(d_fft_size * ninput_items[0]); // sample counter + d_sample_counter += static_cast(d_fft_size) * ninput_items[0]; // sample counter consume_each(ninput_items[0]); break; @@ -389,7 +389,7 @@ int pcps_cccwsr_acquisition_cc::general_work(int noutput_items, d_active = false; d_state = 0; - d_sample_counter += static_cast(d_fft_size * ninput_items[0]); // sample counter + d_sample_counter += static_cast(d_fft_size) * ninput_items[0]; // sample counter consume_each(ninput_items[0]); acquisition_message = 1; @@ -424,7 +424,7 @@ int pcps_cccwsr_acquisition_cc::general_work(int noutput_items, d_active = false; d_state = 0; - d_sample_counter += static_cast(d_fft_size * ninput_items[0]); // sample counter + d_sample_counter += static_cast(d_fft_size) * ninput_items[0]; // sample counter consume_each(ninput_items[0]); acquisition_message = 2; diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_opencl_acquisition_cc.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_opencl_acquisition_cc.cc index 8aacb315f..b55015d6a 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_opencl_acquisition_cc.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_opencl_acquisition_cc.cc @@ -680,7 +680,7 @@ int pcps_opencl_acquisition_cc::general_work(int noutput_items, d_state = 1; } - d_sample_counter += static_cast(d_fft_size * ninput_items[0]); // sample counter + d_sample_counter += static_cast(d_fft_size) * ninput_items[0]; // sample counter break; } @@ -710,7 +710,7 @@ int pcps_opencl_acquisition_cc::general_work(int noutput_items, { // We already have d_max_dwells consecutive blocks in the internal buffer, // just skip input blocks. - d_sample_counter += static_cast(d_fft_size * ninput_items[0]); + d_sample_counter += static_cast(d_fft_size) * ninput_items[0]; } // We create a new thread to process next block if the following @@ -754,7 +754,7 @@ int pcps_opencl_acquisition_cc::general_work(int noutput_items, d_active = false; d_state = 0; - d_sample_counter += static_cast(d_fft_size * ninput_items[0]); // sample counter + d_sample_counter += static_cast(d_fft_size) * ninput_items[0]; // sample counter acquisition_message = 1; this->message_port_pub(pmt::mp("events"), pmt::from_long(acquisition_message)); @@ -788,7 +788,7 @@ int pcps_opencl_acquisition_cc::general_work(int noutput_items, d_active = false; d_state = 0; - d_sample_counter += static_cast(d_fft_size * ninput_items[0]); // sample counter + d_sample_counter += static_cast(d_fft_size) * ninput_items[0]; // sample counter acquisition_message = 2; this->message_port_pub(pmt::mp("events"), pmt::from_long(acquisition_message)); diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_quicksync_acquisition_cc.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_quicksync_acquisition_cc.cc index 0463ef99f..5576a3f63 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_quicksync_acquisition_cc.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_quicksync_acquisition_cc.cc @@ -256,7 +256,7 @@ int pcps_quicksync_acquisition_cc::general_work(int noutput_items, d_state = 1; } - d_sample_counter += static_cast(d_sampled_ms * d_samples_per_ms * ninput_items[0]); // sample counter + d_sample_counter += static_cast(d_sampled_ms) * d_samples_per_ms * ninput_items[0]; // sample counter consume_each(ninput_items[0]); // DLOG(INFO) << "END CASE 0"; break; @@ -290,7 +290,7 @@ int pcps_quicksync_acquisition_cc::general_work(int noutput_items, d_test_statistics = 0.0; d_noise_floor_power = 0.0; - d_sample_counter += static_cast(d_sampled_ms * d_samples_per_ms); // sample counter + d_sample_counter += static_cast(d_sampled_ms) * d_samples_per_ms; // sample counter d_well_count++; @@ -495,7 +495,7 @@ int pcps_quicksync_acquisition_cc::general_work(int noutput_items, d_active = false; d_state = 0; - d_sample_counter += static_cast(d_sampled_ms * d_samples_per_ms * ninput_items[0]); // sample counter + d_sample_counter += static_cast(d_sampled_ms) * d_samples_per_ms * ninput_items[0]; // sample counter consume_each(ninput_items[0]); acquisition_message = 1; @@ -538,7 +538,7 @@ int pcps_quicksync_acquisition_cc::general_work(int noutput_items, d_active = false; d_state = 0; - d_sample_counter += static_cast(d_sampled_ms * d_samples_per_ms * ninput_items[0]); // sample counter + d_sample_counter += static_cast(d_sampled_ms) * d_samples_per_ms * ninput_items[0]; // sample counter consume_each(ninput_items[0]); acquisition_message = 2; diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_tong_acquisition_cc.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_tong_acquisition_cc.cc index b3c5c61a9..720bdf917 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_tong_acquisition_cc.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_tong_acquisition_cc.cc @@ -251,7 +251,7 @@ int pcps_tong_acquisition_cc::general_work(int noutput_items, d_state = 1; } - d_sample_counter += static_cast(d_fft_size * ninput_items[0]); // sample counter + d_sample_counter += static_cast(d_fft_size) * ninput_items[0]; // sample counter consume_each(ninput_items[0]); break; @@ -390,7 +390,7 @@ int pcps_tong_acquisition_cc::general_work(int noutput_items, d_active = false; d_state = 0; - d_sample_counter += static_cast(d_fft_size * ninput_items[0]); // sample counter + d_sample_counter += static_cast(d_fft_size) * ninput_items[0]; // sample counter consume_each(ninput_items[0]); acquisition_message = 1; @@ -425,7 +425,7 @@ int pcps_tong_acquisition_cc::general_work(int noutput_items, d_active = false; d_state = 0; - d_sample_counter += static_cast(d_fft_size * ninput_items[0]); // sample counter + d_sample_counter += static_cast(d_fft_size) * ninput_items[0]; // sample counter consume_each(ninput_items[0]); acquisition_message = 2; diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/CMakeLists.txt b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/CMakeLists.txt index bc0774e34..ea21b15d8 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/CMakeLists.txt +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/CMakeLists.txt @@ -8,7 +8,7 @@ ######################################################################## # Project setup ######################################################################## -cmake_minimum_required(VERSION 2.8.12...3.22) +cmake_minimum_required(VERSION 2.8.12...3.23) if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release") endif() @@ -209,7 +209,7 @@ message(STATUS "Build type set to ${CMAKE_BUILD_TYPE}.") set(VERSION_INFO_MAJOR_VERSION 0) set(VERSION_INFO_MINOR_VERSION 0) -set(VERSION_INFO_MAINT_VERSION 16) +set(VERSION_INFO_MAINT_VERSION 17) include(VolkGnsssdrVersion) # setup version info @@ -250,44 +250,43 @@ endif() ######################################################################## # cpu_features -option(ENABLE_OWN_CPUFEATURES "Force the building of the cpu_features library even if it is already installed" OFF) if(CMAKE_SYSTEM_PROCESSOR MATCHES "^cortex") set(CMAKE_SYSTEM_PROCESSOR arm-${CMAKE_SYSTEM_PROCESSOR}) endif() -set(SUPPORTED_CPU_FEATURES_ARCH FALSE) -if(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips") - set(SUPPORTED_CPU_FEATURES_ARCH TRUE) -elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(^aarch64)|(arm64)") - set(SUPPORTED_CPU_FEATURES_ARCH TRUE) -elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm") - set(SUPPORTED_CPU_FEATURES_ARCH TRUE) -elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(x86_64)|(AMD64|amd64)|(^i.86$)") - set(SUPPORTED_CPU_FEATURES_ARCH TRUE) -elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)") - set(SUPPORTED_CPU_FEATURES_ARCH TRUE) +# cpu_features - sensible defaults, user settable option +if(CMAKE_SYSTEM_PROCESSOR MATCHES + "(^mips)|(^arm)|(^aarch64)|(x86_64)|(AMD64|amd64)|(^i.86$)|(^powerpc)|(^ppc)") + option(VOLK_CPU_FEATURES "volk-gnsssdr uses cpu_features" ON) +else() + option(VOLK_CPU_FEATURES "volk-gnsssdr uses cpu_features" OFF) endif() -if(CMAKE_VERSION VERSION_GREATER 3.0 AND SUPPORTED_CPU_FEATURES_ARCH) - set(CMAKE_POSITION_INDEPENDENT_CODE ON CACHE BOOL - "Build cpu_features with Position Independent Code (PIC)." - FORCE - ) +if(CMAKE_VERSION VERSION_GREATER 3.0 AND VOLK_CPU_FEATURES) + find_package(CPUFEATURES) set(USE_CPU_FEATURES ON) - set(BUILD_SHARED_LIBS_SAVED "${BUILD_SHARED_LIBS}") - set(BUILD_SHARED_LIBS OFF) - if(NOT ENABLE_OWN_CPUFEATURES) - find_package(CPUFEATURES QUIET) - endif() - if(CPUFEATURES_FOUND) - message(STATUS "Found CpuFeatures: (found version ${CPUFEATURES_VERSION})") - else() + if(NOT CPUFEATURES_FOUND) + message(STATUS "Building volk-gnsssdr with cpu_features") + set(BUILD_TESTING OFF CACHE BOOL "Build cpu_features without tests." FORCE) + set(BUILD_PIC ON CACHE BOOL + "Build cpu_features with Position Independent Code (PIC)." + FORCE + ) + set(CMAKE_POSITION_INDEPENDENT_CODE ON CACHE BOOL + "Build cpu_features with Position Independent Code (PIC)." + FORCE + ) + set(BUILD_SHARED_LIBS_SAVED "${BUILD_SHARED_LIBS}") + set(BUILD_SHARED_LIBS OFF) add_subdirectory(cpu_features) + set(BUILD_SHARED_LIBS "${BUILD_SHARED_LIBS_SAVED}") endif() - set(BUILD_SHARED_LIBS "${BUILD_SHARED_LIBS_SAVED}") +else() + message(STATUS "Building volk-gnsssdr without cpu_features") endif() + # Python include(VolkPython) # sets PYTHON_EXECUTABLE volk_python_check_module("python >= 2.7" sys "sys.version.split()[0] >= '2.7'" PYTHON_MIN_VER_FOUND) diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/README.md b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/README.md index 9534f8feb..2bbf9ebd8 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/README.md +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/README.md @@ -203,4 +203,4 @@ by Carles Fernández-Prades and Javier Arribas. This software is released under the GNU General Public License version 3, see the file COPYING. This project is managed by -[Centre Tecnològic de Telecomunicacions de Catalunya](http://www.cttc.es "CTTC webpage"). +[Centre Tecnològic de Telecomunicacions de Catalunya](https://www.cttc.cat "CTTC webpage"). diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/FindCPUFEATURES.cmake b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/FindCPUFEATURES.cmake index 89936ee59..6f25e91d2 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/FindCPUFEATURES.cmake +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Modules/FindCPUFEATURES.cmake @@ -86,7 +86,6 @@ if(CPUFEATURES_FOUND AND NOT TARGET CpuFeature::cpu_features) INTERFACE_INCLUDE_DIRECTORIES "${CPUFEATURES_INCLUDE_DIR}" INTERFACE_LINK_LIBRARIES "${CPUFEATURES_LIBRARIES}" ) - add_library(cpu_features ALIAS CpuFeature::cpu_features) endif() mark_as_advanced(CPUFEATURES_LIBRARIES) diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Packaging/volk_gnsssdr-config-info-manpage b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Packaging/volk_gnsssdr-config-info-manpage index 97b1f6096..8bc4acadc 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Packaging/volk_gnsssdr-config-info-manpage +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Packaging/volk_gnsssdr-config-info-manpage @@ -2,7 +2,7 @@ .\" SPDX-License-Identifier: GPL-3.0-or-later .\" SPDX-FileCopyrightText: Carles Fernandez-Prades .\" Contact carles.fernandez@cttc.es to correct errors or typos. -.TH volk_gnsssdr\-config\-info 1 "15 Feb 2022" "0.0.16" "volk_gnsssdr\-config\-info man page" +.TH volk_gnsssdr\-config\-info 1 "20 Apr 2022" "0.0.17" "volk_gnsssdr\-config\-info man page" .SH NAME \fBvolk_gnsssdr\-config\-info\fR \- Prints configuration information of libvolk_gnsssdr functions. .SH SYNOPSIS diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Packaging/volk_gnsssdr_profile-manpage b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Packaging/volk_gnsssdr_profile-manpage index 3303347a1..6d20c2bda 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Packaging/volk_gnsssdr_profile-manpage +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cmake/Packaging/volk_gnsssdr_profile-manpage @@ -2,7 +2,7 @@ .\" SPDX-License-Identifier: GPL-3.0-or-later .\" SPDX-FileCopyrightText: Carles Fernandez-Prades .\" Contact carles.fernandez@cttc.es to correct errors or typos. -.TH volk_gnsssdr_profile 1 "15 Feb 2022" "0.0.16" "volk_gnsssdr_profile man page" +.TH volk_gnsssdr_profile 1 "20 Apr 2022" "0.0.17" "volk_gnsssdr_profile man page" .SH NAME \fBvolk_gnsssdr_profile\fR \- Profiler application for libvolk_gnsssdr functions. .SH SYNOPSIS diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/CMakeLists.txt b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/CMakeLists.txt index 9001f224d..2bda43927 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/CMakeLists.txt +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/CMakeLists.txt @@ -9,7 +9,7 @@ if(POLICY CMP0077) cmake_policy(SET CMP0077 NEW) endif() -project(CpuFeatures VERSION 0.6.0 LANGUAGES C) +project(CpuFeatures VERSION 0.7.0 LANGUAGES C) set(CMAKE_C_STANDARD 99) if(CMAKE_VERSION LESS "3.1") @@ -23,9 +23,6 @@ if(NOT CMAKE_BUILD_TYPE) FORCE) endif() -# BUILD_TESTING is a standard CMake variable, but we declare it here to make it -# prominent in the GUI. -option(BUILD_TESTING "Enable test (depends on googletest)." OFF) # BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to make # it prominent in the GUI. # cpu_features uses bit-fields which are - to some extends - implementation-defined (see https://en.cppreference.com/w/c/language/bit_field). @@ -61,7 +58,7 @@ set(PROCESSOR_IS_POWER FALSE) if(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips") set(PROCESSOR_IS_MIPS TRUE) -elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(^aarch64)|(arm64)") +elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64|arm64)") set(PROCESSOR_IS_AARCH64 TRUE) elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm") set(PROCESSOR_IS_ARM TRUE) @@ -74,22 +71,19 @@ endif() macro(add_cpu_features_headers_and_sources HDRS_LIST_NAME SRCS_LIST_NAME) list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpu_features_macros.h) list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpu_features_cache_info.h) + file(GLOB IMPL_SOURCES CONFIGURE_DEPENDS "${PROJECT_SOURCE_DIR}/src/impl_*.c") + list(APPEND ${SRCS_LIST_NAME} ${IMPL_SOURCES}) if(PROCESSOR_IS_MIPS) list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_mips.h) - list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/src/cpuinfo_mips.c) elseif(PROCESSOR_IS_ARM) list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_arm.h) - list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/src/cpuinfo_arm.c) elseif(PROCESSOR_IS_AARCH64) list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_aarch64.h) - list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/src/cpuinfo_aarch64.c) elseif(PROCESSOR_IS_X86) list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_x86.h) list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/internal/cpuid_x86.h) - list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/src/cpuinfo_x86.c) elseif(PROCESSOR_IS_POWER) list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_ppc.h) - list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/src/cpuinfo_ppc.c) else() message(FATAL_ERROR "Unsupported architectures ${CMAKE_SYSTEM_PROCESSOR}") endif() @@ -147,8 +141,10 @@ target_link_libraries(cpu_features PUBLIC ${CMAKE_DL_LIBS}) target_include_directories(cpu_features PUBLIC $ ) -if(APPLE AND (PROCESSOR_IS_X86 OR PROCESSOR_IS_AARCH64)) - target_compile_definitions(cpu_features PRIVATE HAVE_SYSCTLBYNAME) +if(PROCESSOR_IS_X86) + if(APPLE) + target_compile_definitions(cpu_features PRIVATE HAVE_SYSCTLBYNAME) + endif() endif() add_library(CpuFeature::cpu_features ALIAS cpu_features) diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/cmake/README.md b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/cmake/README.md index 51efb42b7..eaa400153 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/cmake/README.md +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/cmake/README.md @@ -1,4 +1,4 @@ -# CMake build instructions +#CMake build instructions [comment]: # ( @@ -16,7 +16,7 @@ For API / ABI compatibility reasons, it is recommended to build and use cpu_features in a subdirectory of your project or as an embedded dependency. This is similar to the recommended usage of the googletest framework ( -https://github.com/google/googletest/blob/master/googletest/README.md ) +https://github.com/google/googletest/blob/main/googletest/README.md ) Build and use step-by-step @@ -29,11 +29,11 @@ cpu_features directly and use the `cpu_features` target in your project. 3- Add the `cpu_features` target to the `target_link_libraries()` section of your executable or of your library. -## Enabling tests +## Disabling tests -CMake default options for cpu_features is Release built type with tests -disabled. To enable testing set cmake `BUILD_TESTING` variable to `ON`, -[.travis.yml](https://github.com/google/cpu_features/blob/master/.travis.yml) -and -[appveyor.yml](https://github.com/google/cpu_features/blob/master/appveyor.yml) -have up to date examples. +CMake default options for cpu_features is `Release` built type with tests +enabled. To disable testing set cmake `BUILD_TESTING` variable to `OFF`. e.g. + +```sh +cmake -S. -Bbuild -DBUILD_TESTING=OFF +``` diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/cmake/googletest.CMakeLists.txt.in b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/cmake/googletest.CMakeLists.txt.in index 66b17383e..0a0a6d2ad 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/cmake/googletest.CMakeLists.txt.in +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/cmake/googletest.CMakeLists.txt.in @@ -8,7 +8,7 @@ project(googletest-download NONE) include(ExternalProject) ExternalProject_Add(googletest GIT_REPOSITORY https://github.com/google/googletest.git - GIT_TAG master + GIT_TAG main SOURCE_DIR "${CMAKE_BINARY_DIR}/googletest-src" BINARY_DIR "${CMAKE_BINARY_DIR}/googletest-build" CONFIGURE_COMMAND "" diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpu_features_macros.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpu_features_macros.h index 78ecbdad1..e23a476eb 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpu_features_macros.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpu_features_macros.h @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2017 Google LLC // SPDX-License-Identifier: Apache-2.0 - #ifndef CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_ #define CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_ @@ -29,7 +28,7 @@ #define CPU_FEATURES_ARCH_ARM #endif -#if (defined(__aarch64__) || (defined(__APPLE__) && defined(__arm64__))) +#if defined(__aarch64__) #define CPU_FEATURES_ARCH_AARCH64 #endif @@ -57,24 +56,33 @@ // Os //////////////////////////////////////////////////////////////////////////////// -#if defined(__linux__) -#define CPU_FEATURES_OS_LINUX_OR_ANDROID +#if (defined(__freebsd__) || defined(__FreeBSD__)) +#define CPU_FEATURES_OS_FREEBSD #endif #if defined(__ANDROID__) #define CPU_FEATURES_OS_ANDROID #endif +#if defined(__linux__) && !defined(CPU_FEATURES_OS_FREEBSD) && \ + !defined(CPU_FEATURES_OS_ANDROID) +#define CPU_FEATURES_OS_LINUX +#endif + #if (defined(_WIN64) || defined(_WIN32)) #define CPU_FEATURES_OS_WINDOWS #endif #if (defined(__apple__) || defined(__APPLE__) || defined(__MACH__)) -#define CPU_FEATURES_OS_DARWIN +// From https://stackoverflow.com/a/49560690 +#include "TargetConditionals.h" +#if defined(TARGET_OS_OSX) +#define CPU_FEATURES_OS_MACOS +#endif +#if defined(TARGET_OS_IPHONE) +// This is set for any non-Mac Apple products (IOS, TV, WATCH) +#define CPU_FEATURES_OS_IPHONE #endif - -#if (defined(__freebsd__) || defined(__FreeBSD__)) -#define CPU_FEATURES_OS_FREEBSD #endif //////////////////////////////////////////////////////////////////////////////// @@ -215,11 +223,18 @@ // Communicates to the compiler that the block is unreachable #if defined(CPU_FEATURES_COMPILER_CLANG) || defined(CPU_FEATURES_COMPILER_GCC) -#define UNREACHABLE() __builtin_unreachable() +#define CPU_FEATURES_UNREACHABLE() __builtin_unreachable() #elif defined(CPU_FEATURES_COMPILER_MSC) -#define UNREACHABLE() __assume(0) +#define CPU_FEATURES_UNREACHABLE() __assume(0) #else -#define UNREACHABLE() +#define CPU_FEATURES_UNREACHABLE() +#endif + +// Communicates to the compiler that the function is now deprecated +#if defined(CPU_FEATURES_COMPILER_CLANG) || defined(CPU_FEATURES_COMPILER_GCC) +#define CPU_FEATURES_DEPRECATED(message) __attribute__((deprecated(message))) +#else +#define CPU_FEATURES_DEPRECATED(message) #endif #endif // CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_ diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_aarch64.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_aarch64.h index 34d258873..a18209f3a 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_aarch64.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_aarch64.h @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2017 Google LLC // SPDX-License-Identifier: Apache-2.0 - #ifndef CPU_FEATURES_INCLUDE_CPUINFO_AARCH64_H_ #define CPU_FEATURES_INCLUDE_CPUINFO_AARCH64_H_ diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_arm.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_arm.h index 0571fe7ee..4b73c572e 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_arm.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_arm.h @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2017 Google LLC // SPDX-License-Identifier: Apache-2.0 - #ifndef CPU_FEATURES_INCLUDE_CPUINFO_ARM_H_ #define CPU_FEATURES_INCLUDE_CPUINFO_ARM_H_ diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_mips.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_mips.h index c935e5a91..61e0299de 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_mips.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_mips.h @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2017 Google LLC // SPDX-License-Identifier: Apache-2.0 - #ifndef CPU_FEATURES_INCLUDE_CPUINFO_MIPS_H_ #define CPU_FEATURES_INCLUDE_CPUINFO_MIPS_H_ diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_ppc.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_ppc.h index f626eae53..455192aa8 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_ppc.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_ppc.h @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2017 Google LLC // SPDX-License-Identifier: Apache-2.0 - #ifndef CPU_FEATURES_INCLUDE_CPUINFO_PPC_H_ #define CPU_FEATURES_INCLUDE_CPUINFO_PPC_H_ @@ -62,7 +61,6 @@ typedef struct PPCFeatures features; } PPCInfo; -// This function is guaranteed to be malloc, memset and memcpy free. PPCInfo GetPPCInfo(void); typedef struct @@ -113,7 +111,7 @@ typedef enum PPC_ARCH_2_06, /* ISA 2.06 - POWER7 */ PPC_HAS_VSX, /* Vector-scalar extension */ PPC_PSERIES_PERFMON_COMPAT, /* Set of backwards compatibile performance - monitoring events */ + monitoring events */ PPC_TRUE_LE, PPC_PPC_LE, PPC_ARCH_2_07, /* ISA 2.07 - POWER8 */ diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_x86.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_x86.h index 9abde468c..d26de6e52 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_x86.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_x86.h @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2017 Google LLC // SPDX-License-Identifier: Apache-2.0 - #ifndef CPU_FEATURES_INCLUDE_CPUINFO_X86_H_ #define CPU_FEATURES_INCLUDE_CPUINFO_X86_H_ @@ -14,6 +13,8 @@ CPU_FEATURES_START_CPP_NAMESPACE #define CPU_FEATURES_VENDOR_GENUINE_INTEL "GenuineIntel" #define CPU_FEATURES_VENDOR_AUTHENTIC_AMD "AuthenticAMD" #define CPU_FEATURES_VENDOR_HYGON_GENUINE "HygonGenuine" +#define CPU_FEATURES_VENDOR_CENTAUR_HAULS "CentaurHauls" +#define CPU_FEATURES_VENDOR_SHANGHAI " Shanghai " // See https://en.wikipedia.org/wiki/CPUID for a list of x86 cpu features. // The field names are based on the short name provided in the wikipedia tables. @@ -94,56 +95,70 @@ typedef struct int family; int model; int stepping; - char vendor[13]; // 0 terminated string + char vendor[13]; // 0 terminated string + char brand_string[49]; // 0 terminated string } X86Info; // Calls cpuid and returns an initialized X86info. -// This function is guaranteed to be malloc, memset and memcpy free. X86Info GetX86Info(void); // Returns cache hierarchy informations. // Can call cpuid multiple times. // Only works on Intel CPU at the moment. -// This function is guaranteed to be malloc, memset and memcpy free. CacheInfo GetX86CacheInfo(void); typedef enum { X86_UNKNOWN, - INTEL_CORE, // CORE - INTEL_PNR, // PENRYN - INTEL_NHM, // NEHALEM - INTEL_ATOM_BNL, // BONNELL - INTEL_WSM, // WESTMERE - INTEL_SNB, // SANDYBRIDGE - INTEL_IVB, // IVYBRIDGE - INTEL_ATOM_SMT, // SILVERMONT - INTEL_HSW, // HASWELL - INTEL_BDW, // BROADWELL - INTEL_SKL, // SKYLAKE - INTEL_ATOM_GMT, // GOLDMONT - INTEL_KBL, // KABY LAKE - INTEL_CFL, // COFFEE LAKE - INTEL_WHL, // WHISKEY LAKE - INTEL_CNL, // CANNON LAKE - INTEL_ICL, // ICE LAKE - INTEL_TGL, // TIGER LAKE - INTEL_SPR, // SAPPHIRE RAPIDS - AMD_HAMMER, // K8 HAMMER - AMD_K10, // K10 - AMD_K11, // K11 - AMD_K12, // K12 - AMD_BOBCAT, // K14 BOBCAT - AMD_PILEDRIVER, // K15 PILEDRIVER - AMD_STREAMROLLER, // K15 STREAMROLLER - AMD_EXCAVATOR, // K15 EXCAVATOR - AMD_BULLDOZER, // K15 BULLDOZER - AMD_JAGUAR, // K16 JAGUAR - AMD_PUMA, // K16 PUMA - AMD_ZEN, // K17 ZEN - AMD_ZEN_PLUS, // K17 ZEN+ - AMD_ZEN2, // K17 ZEN 2 - AMD_ZEN3, // K19 ZEN 3 + ZHAOXIN_ZHANGJIANG, // ZhangJiang + ZHAOXIN_WUDAOKOU, // WuDaoKou + ZHAOXIN_LUJIAZUI, // LuJiaZui + ZHAOXIN_YONGFENG, // YongFeng + INTEL_80486, // 80486 + INTEL_P5, // P5 + INTEL_LAKEMONT, // LAKEMONT + INTEL_CORE, // CORE + INTEL_PNR, // PENRYN + INTEL_NHM, // NEHALEM + INTEL_ATOM_BNL, // BONNELL + INTEL_WSM, // WESTMERE + INTEL_SNB, // SANDYBRIDGE + INTEL_IVB, // IVYBRIDGE + INTEL_ATOM_SMT, // SILVERMONT + INTEL_HSW, // HASWELL + INTEL_BDW, // BROADWELL + INTEL_SKL, // SKYLAKE + INTEL_ATOM_GMT, // GOLDMONT + INTEL_KBL, // KABY LAKE + INTEL_CFL, // COFFEE LAKE + INTEL_WHL, // WHISKEY LAKE + INTEL_CNL, // CANNON LAKE + INTEL_ICL, // ICE LAKE + INTEL_TGL, // TIGER LAKE + INTEL_SPR, // SAPPHIRE RAPIDS + INTEL_ADL, // ALDER LAKE + INTEL_RCL, // ROCKET LAKE + INTEL_KNIGHTS_M, // KNIGHTS MILL + INTEL_KNIGHTS_L, // KNIGHTS LANDING + INTEL_KNIGHTS_F, // KNIGHTS FERRY + INTEL_KNIGHTS_C, // KNIGHTS CORNER + INTEL_NETBURST, // NETBURST + AMD_HAMMER, // K8 HAMMER + AMD_K10, // K10 + AMD_K11, // K11 + AMD_K12, // K12 + AMD_BOBCAT, // K14 BOBCAT + AMD_PILEDRIVER, // K15 PILEDRIVER + AMD_STREAMROLLER, // K15 STREAMROLLER + AMD_EXCAVATOR, // K15 EXCAVATOR + AMD_BULLDOZER, // K15 BULLDOZER + AMD_JAGUAR, // K16 JAGUAR + AMD_PUMA, // K16 PUMA + AMD_ZEN, // K17 ZEN + AMD_ZEN_PLUS, // K17 ZEN+ + AMD_ZEN2, // K17 ZEN 2 + AMD_ZEN3, // K19 ZEN 3 + X86_MICROARCHITECTURE_LAST_, } X86Microarchitecture; // Returns the underlying microarchitecture by looking at X86Info's vendor, @@ -153,7 +168,7 @@ X86Microarchitecture GetX86Microarchitecture(const X86Info* info); // Calls cpuid and fills the brand_string. // - brand_string *must* be of size 49 (beware of array decaying). // - brand_string will be zero terminated. -// - This function calls memcpy. +CPU_FEATURES_DEPRECATED("brand_string is now embedded in X86Info by default") void FillX86BrandString(char brand_string[49]); //////////////////////////////////////////////////////////////////////////////// @@ -237,4 +252,4 @@ CPU_FEATURES_END_CPP_NAMESPACE #error "Including cpuinfo_x86.h from a non-x86 target." #endif -#endif // CPU_FEATURES_INCLUDE_CPUINFO_X86_H +#endif // CPU_FEATURES_INCLUDE_CPUINFO_X86_H_ diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/bit_utils.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/bit_utils.h index 5957dd117..13f9334f5 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/bit_utils.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/bit_utils.h @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2017 Google LLC // SPDX-License-Identifier: Apache-2.0 - #ifndef CPU_FEATURES_INCLUDE_INTERNAL_BIT_UTILS_H_ #define CPU_FEATURES_INCLUDE_INTERNAL_BIT_UTILS_H_ diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/cpuid_x86.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/cpuid_x86.h index c675a9468..4f743147c 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/cpuid_x86.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/cpuid_x86.h @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2017 Google LLC // SPDX-License-Identifier: Apache-2.0 - #ifndef CPU_FEATURES_INCLUDE_INTERNAL_CPUID_X86_H_ #define CPU_FEATURES_INCLUDE_INTERNAL_CPUID_X86_H_ diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/filesystem.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/filesystem.h index f8593fd66..fb3f9a506 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/filesystem.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/filesystem.h @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2017 Google LLC // SPDX-License-Identifier: Apache-2.0 - // An interface for the filesystem that allows mocking the filesystem in // unittests. #ifndef CPU_FEATURES_INCLUDE_INTERNAL_FILESYSTEM_H_ diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/hwcaps.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/hwcaps.h index 8651b08a6..bb18a9a9e 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/hwcaps.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/hwcaps.h @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2017 Google LLC // SPDX-License-Identifier: Apache-2.0 - // Interface to retrieve hardware capabilities. It relies on Linux's getauxval // or `/proc/self/auxval` under the hood. #ifndef CPU_FEATURES_INCLUDE_INTERNAL_HWCAPS_H_ diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/stack_line_reader.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/stack_line_reader.h index d2099066e..6fb3016d5 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/stack_line_reader.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/stack_line_reader.h @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2017 Google LLC // SPDX-License-Identifier: Apache-2.0 - // Reads a file line by line and stores the data on the stack. This allows // parsing files in one go without allocating. #ifndef CPU_FEATURES_INCLUDE_INTERNAL_STACK_LINE_READER_H_ diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/string_view.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/string_view.h index b687da035..5100c789e 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/string_view.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/string_view.h @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2017 Google LLC // SPDX-License-Identifier: Apache-2.0 - // A view over a piece of string. The view is not 0 terminated. #ifndef CPU_FEATURES_INCLUDE_INTERNAL_STRING_VIEW_H_ #define CPU_FEATURES_INCLUDE_INTERNAL_STRING_VIEW_H_ diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/scripts/run_integration.sh b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/scripts/run_integration.sh index 5ea6d9888..967b7d734 100755 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/scripts/run_integration.sh +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/scripts/run_integration.sh @@ -3,210 +3,365 @@ # SPDX-FileCopyrightText: 2017 Google LLC # SPDX-License-Identifier: Apache-2.0 -readonly SCRIPT_FOLDER=$(cd -P -- "$(dirname -- "$0")" && pwd -P) -readonly PROJECT_FOLDER="${SCRIPT_FOLDER}/.." -readonly ARCHIVE_FOLDER=~/cpu_features_archives -readonly QEMU_INSTALL=${ARCHIVE_FOLDER}/qemu -readonly DEFAULT_CMAKE_ARGS=" -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON" +set -eo pipefail function extract() { + echo "Extracting ${1}..." case $1 in *.tar.bz2) tar xjf "$1" ;; *.tar.xz) tar xJf "$1" ;; *.tar.gz) tar xzf "$1" ;; *) - echo "don't know how to extract '$1'..." + >&2 echo "don't know how to extract '$1'..." exit 1 esac } -function unpackifnotexists() { - mkdir -p "${ARCHIVE_FOLDER}" - cd "${ARCHIVE_FOLDER}" || exit - local URL=$1 - local RELATIVE_FOLDER=$2 - local DESTINATION="${ARCHIVE_FOLDER}/${RELATIVE_FOLDER}" +function unpack() { + mkdir -p "${ARCHIVE_DIR}" + cd "${ARCHIVE_DIR}" || exit 2 + local -r URL=$1 + local -r RELATIVE_DIR=$2 + local -r DESTINATION="${ARCHIVE_DIR}/${RELATIVE_DIR}" if [[ ! -d "${DESTINATION}" ]] ; then - local ARCHIVE_NAME=$(echo ${URL} | sed 's/.*\///') - test -f "${ARCHIVE_NAME}" || wget -q "${URL}" + echo "Downloading ${URL}..." + local -r ARCHIVE_NAME=$(basename "${URL}") + test -f "${ARCHIVE_NAME}" || wget --no-verbose "${URL}" extract "${ARCHIVE_NAME}" rm -f "${ARCHIVE_NAME}" fi } -function installqemuifneeded() { - local VERSION=${QEMU_VERSION:=2.11.1} - local ARCHES=${QEMU_ARCHES:=arm aarch64 i386 x86_64 mips mipsel mips64 mips64el} - local TARGETS=${QEMU_TARGETS:=$(echo "$ARCHES" | sed 's#$# #;s#\([^ ]*\) #\1-linux-user #g')} +function install_qemu() { + if [[ "${QEMU_ARCH}" == "DISABLED" ]]; then + >&2 echo 'QEMU is disabled !' + return 0 + fi + local -r QEMU_VERSION=${QEMU_VERSION:=5.2.0} + local -r QEMU_TARGET=${QEMU_ARCH}-linux-user - if echo "${VERSION} ${TARGETS}" | cmp --silent ${QEMU_INSTALL}/.build -; then - echo "qemu ${VERSION} up to date!" + if echo "${QEMU_VERSION} ${QEMU_TARGET}" | cmp --silent "${QEMU_INSTALL}/.build" -; then + echo "qemu ${QEMU_VERSION} up to date!" return 0 fi - echo "VERSION: ${VERSION}" - echo "TARGETS: ${TARGETS}" + echo "QEMU_VERSION: ${QEMU_VERSION}" + echo "QEMU_TARGET: ${QEMU_TARGET}" - rm -rf ${QEMU_INSTALL} + rm -rf "${QEMU_INSTALL}" # Checking for a tarball before downloading makes testing easier :-) - local QEMU_URL="http://wiki.qemu-project.org/download/qemu-${VERSION}.tar.xz" - local QEMU_FOLDER="qemu-${VERSION}" - unpackifnotexists ${QEMU_URL} ${QEMU_FOLDER} - cd ${QEMU_FOLDER} || exit + local -r QEMU_URL="http://wiki.qemu-project.org/download/qemu-${QEMU_VERSION}.tar.xz" + local -r QEMU_DIR="qemu-${QEMU_VERSION}" + unpack ${QEMU_URL} ${QEMU_DIR} + cd ${QEMU_DIR} || exit 2 + # Qemu (meson based build) depends on: pkgconf, libglib2.0, python3, ninja ./configure \ --prefix="${QEMU_INSTALL}" \ - --target-list="${TARGETS}" \ - --disable-docs \ - --disable-sdl \ - --disable-gtk \ - --disable-gnutls \ - --disable-gcrypt \ - --disable-nettle \ + --target-list="${QEMU_TARGET}" \ + --audio-drv-list= \ + --disable-brlapi \ + --disable-curl \ --disable-curses \ - --static + --disable-docs \ + --disable-gcrypt \ + --disable-gnutls \ + --disable-gtk \ + --disable-libnfs \ + --disable-libssh \ + --disable-nettle \ + --disable-opengl \ + --disable-sdl \ + --disable-virglrenderer \ + --disable-vte \ + --enable-modules - make -j4 + # --static Not supported on Archlinux + # so we use --enable-modules + + # wrapper on ninja + make -j8 make install - echo "$VERSION $TARGETS" > ${QEMU_INSTALL}/.build + echo "$QEMU_VERSION $QEMU_TARGET" > "${QEMU_INSTALL}/.build" } function assert_defined(){ - local VALUE=${1} - : "${VALUE?"${1} needs to be defined"}" + if [[ -z "${!1}" ]]; then + >&2 echo "Variable '${1}' must be defined" + exit 1 + fi } -function integrate() { - cd "${PROJECT_FOLDER}" - case "${OS}" in - "Windows_NT") CMAKE_BUILD_ARGS="--config Debug --target ALL_BUILD" - CMAKE_TEST_FILES="${BUILD_DIR}/test/Debug/*_test.exe" - DEMO=${BUILD_DIR}/Debug/list_cpu_features.exe - ;; - *) CMAKE_BUILD_ARGS="--target all" - CMAKE_TEST_FILES="${BUILD_DIR}/test/*_test" - DEMO=${BUILD_DIR}/list_cpu_features - ;; - esac - - # Generating CMake configuration - cmake -H. -B"${BUILD_DIR}" ${DEFAULT_CMAKE_ARGS} "${CMAKE_ADDITIONAL_ARGS[@]}" -G"${CMAKE_GENERATOR:-Unix Makefiles}" - - # Building - cmake --build "${BUILD_DIR}" ${CMAKE_BUILD_ARGS} - - # Running tests if needed - if [[ "${QEMU_ARCH}" == "DISABLED" ]]; then - return - fi - RUN_CMD="" - if [[ -n "${QEMU_ARCH}" ]]; then - installqemuifneeded - RUN_CMD="${QEMU_INSTALL}/bin/qemu-${QEMU_ARCH} ${QEMU_ARGS[@]}" - fi - for test_binary in ${CMAKE_TEST_FILES}; do - ${RUN_CMD} ${test_binary} - done - ${RUN_CMD} ${DEMO} +function clean_build() { + # Cleanup previous build + rm -rf "${BUILD_DIR}" + mkdir -p "${BUILD_DIR}" } function expand_linaro_config() { - assert_defined TARGET - local LINARO_ROOT_URL=https://releases.linaro.org/components/toolchain/binaries/7.2-2017.11 + #ref: https://releases.linaro.org/components/toolchain/binaries/ + local -r LINARO_VERSION=7.5-2019.12 + local -r LINARO_ROOT_URL=https://releases.linaro.org/components/toolchain/binaries/${LINARO_VERSION} - local GCC_URL=${LINARO_ROOT_URL}/${TARGET}/gcc-linaro-7.2.1-2017.11-x86_64_${TARGET}.tar.xz - local GCC_RELATIVE_FOLDER="gcc-linaro-7.2.1-2017.11-x86_64_${TARGET}" - unpackifnotexists "${GCC_URL}" "${GCC_RELATIVE_FOLDER}" + local -r GCC_VERSION=7.5.0-2019.12 + local -r GCC_URL=${LINARO_ROOT_URL}/${TARGET}/gcc-linaro-${GCC_VERSION}-x86_64_${TARGET}.tar.xz + local -r GCC_RELATIVE_DIR="gcc-linaro-${GCC_VERSION}-x86_64_${TARGET}" + unpack "${GCC_URL}" "${GCC_RELATIVE_DIR}" - local SYSROOT_URL=${LINARO_ROOT_URL}/${TARGET}/sysroot-glibc-linaro-2.25-2017.11-${TARGET}.tar.xz - local SYSROOT_RELATIVE_FOLDER=sysroot-glibc-linaro-2.25-2017.11-${TARGET} - unpackifnotexists "${SYSROOT_URL}" "${SYSROOT_RELATIVE_FOLDER}" + local -r SYSROOT_VERSION=2.25-2019.12 + local -r SYSROOT_URL=${LINARO_ROOT_URL}/${TARGET}/sysroot-glibc-linaro-${SYSROOT_VERSION}-${TARGET}.tar.xz + local -r SYSROOT_RELATIVE_DIR=sysroot-glibc-linaro-${SYSROOT_VERSION}-${TARGET} + unpack "${SYSROOT_URL}" "${SYSROOT_RELATIVE_DIR}" - local SYSROOT_FOLDER=${ARCHIVE_FOLDER}/${SYSROOT_RELATIVE_FOLDER} - local GCC_FOLDER=${ARCHIVE_FOLDER}/${GCC_RELATIVE_FOLDER} + local -r SYSROOT_DIR=${ARCHIVE_DIR}/${SYSROOT_RELATIVE_DIR} + local -r STAGING_DIR=${ARCHIVE_DIR}/${SYSROOT_RELATIVE_DIR}-stage + local -r GCC_DIR=${ARCHIVE_DIR}/${GCC_RELATIVE_DIR} - CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_SYSTEM_NAME=Linux) - CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_SYSTEM_PROCESSOR=${TARGET}) + # Write a Toolchain file + # note: This is manadatory to use a file in order to have the CMake variable + # 'CMAKE_CROSSCOMPILING' set to TRUE. + # ref: https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html#cross-compiling-for-linux + cat >"$TOOLCHAIN_FILE" <&2 echo 'unknown mips platform' + exit 1 ;; esac + local -r SYSROOT_DIR=${GCC_DIR}/sysroot + local -r STAGING_DIR=${SYSROOT_DIR}-stage - CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_FIND_ROOT_PATH=${GCC_FOLDER}) - CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_SYSTEM_NAME=Linux) - CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_SYSTEM_PROCESSOR=${TARGET}) - CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_C_COMPILER=mips-mti-linux-gnu-gcc) - CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_CXX_COMPILER=mips-mti-linux-gnu-g++) - CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_C_COMPILER_ARG1="${MIPS_FLAGS}") - CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_CXX_COMPILER_ARG1="${MIPS_FLAGS}") + # Write a Toolchain file + # note: This is manadatory to use a file in order to have the CMake variable + # 'CMAKE_CROSSCOMPILING' set to TRUE. + # ref: https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html#cross-compiling-for-linux + cat >"${TOOLCHAIN_FILE}" <&2 echo "QEMU is disabled for ${TARGET}" + return + fi + install_qemu + RUN_CMD="${QEMU_INSTALL}/bin/qemu-${QEMU_ARCH} ${QEMU_ARGS[*]}" + + cd "${BUILD_DIR}" || exit 2 + set -x + for test_binary in "${BUILD_DIR}"/list_cpu_feature* ; do + ${RUN_CMD} "${test_binary}" + done + set +x +} + +function usage() { + local -r NAME=$(basename "$0") + echo -e "$NAME - Build using a cross toolchain. + +SYNOPSIS +\t$NAME [-h|--help] [toolchain|build|qemu|test|all] + +DESCRIPTION +\tCross compile using a cross toolchain. + +\tYou MUST define the following variables before running this script: +\t* TARGET: +\t\tx86_64 +\t\taarch64-linux-gnu aarch64_be-linux-gnu +\t\tarm-linux-gnueabihf armv8l-linux-gnueabihf arm-linux-gnueabi +\t\tarmeb-linux-gnueabihf armeb-linux-gnueabi +\t\tmips32 mips32el +\t\tmips64 mips64el + +OPTIONS +\t-h --help: show this help text +\ttoolchain: download, unpack toolchain and generate CMake toolchain file +\tbuild: toolchain + build the project using the toolchain file (note: remove previous build dir) +\tqemu: download, unpack and build qemu +\ttest: qemu + run all executable using qemu (note: don't build !) +\tall: build + test (default) + +EXAMPLES +* Using export: +export TARGET=aarch64-linux-gnu +$0 + +* One-liner: +TARGET=aarch64-linux-gnu $0" +} + +# Main +function main() { + case ${1} in + -h | --help) + usage; exit ;; + esac + assert_defined TARGET - BUILD_DIR="${PROJECT_FOLDER}/cmake_build/${TARGET}" - mkdir -p "${BUILD_DIR}" + declare -r PROJECT_DIR="$(cd -P -- "$(dirname -- "$0")/.." && pwd -P)" + declare -r ARCHIVE_DIR="${PROJECT_DIR}/build_cross/archives" + declare -r BUILD_DIR="${PROJECT_DIR}/build_cross/${TARGET}" + declare -r TOOLCHAIN_FILE=${ARCHIVE_DIR}/toolchain_${TARGET}.cmake - declare -a CONFIG_NAMES=() - declare -a QEMU_ARGS=() + echo "Target: '${TARGET}'" + + echo "Project dir: '${PROJECT_DIR}'" + echo "Archive dir: '${ARCHIVE_DIR}'" + echo "Build dir: '${BUILD_DIR}'" + echo "toolchain file: '${TOOLCHAIN_FILE}'" + + declare -a CMAKE_DEFAULT_ARGS=( -G ${CMAKE_GENERATOR:-"Ninja"} ) declare -a CMAKE_ADDITIONAL_ARGS=() - case ${TOOLCHAIN} in - LINARO) expand_linaro_config ;; - CODESCAPE) expand_codescape_config ;; - NATIVE) QEMU_ARCH="" ;; - *) echo "Unknown toolchain '${TOOLCHAIN}'..."; exit 1;; + declare -a QEMU_ARGS=() + case ${TARGET} in + x86_64) + declare -r QEMU_ARCH=x86_64 ;; + arm-linux-gnueabihf | armv8l-linux-gnueabihf | arm-linux-gnueabi) + expand_linaro_config + declare -r QEMU_ARCH=arm ;; + armeb-linux-gnueabihf | armeb-linux-gnueabi) + expand_linaro_config + declare -r QEMU_ARCH=DISABLED ;; + aarch64-linux-gnu) + expand_linaro_config + declare -r QEMU_ARCH=aarch64 ;; + aarch64_be-linux-gnu) + expand_linaro_config + declare -r QEMU_ARCH=DISABLED ;; + mips32) + expand_codescape_config + declare -r QEMU_ARCH=mips ;; + mips32el) + expand_codescape_config + declare -r QEMU_ARCH=mipsel ;; + mips64) + expand_codescape_config + declare -r QEMU_ARCH=mips64 ;; + mips64el) + expand_codescape_config + declare -r QEMU_ARCH=mips64el ;; + *) + >&2 echo "Unknown TARGET '${TARGET}'..." + exit 1 ;; + esac + declare -r QEMU_INSTALL=${ARCHIVE_DIR}/qemu-${QEMU_ARCH} + + case ${1} in + toolchain) + exit ;; + build) + build ;; + qemu) + install_qemu ;; + test) + run_test ;; + *) + build + run_test ;; esac - integrate } -if [ "${CONTINUOUS_INTEGRATION}" = "true" ]; then - QEMU_ARCHES=${QEMU_ARCH} - expand_environment_and_integrate -fi +main "${1:-all}" diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/scripts/test_integration.sh b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/scripts/test_integration.sh index 2256de59e..b58537d00 100755 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/scripts/test_integration.sh +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/scripts/test_integration.sh @@ -3,85 +3,59 @@ # SPDX-FileCopyrightText: 2017 Google LLC # SPDX-License-Identifier: Apache-2.0 -source "$(dirname -- "$0")"/run_integration.sh - # Toolchains for little-endian, 64-bit ARMv8 for GNU/Linux systems function set_aarch64-linux-gnu() { - TOOLCHAIN=LINARO - TARGET=aarch64-linux-gnu - QEMU_ARCH=aarch64 + export TARGET=aarch64-linux-gnu } # Toolchains for little-endian, hard-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems function set_arm-linux-gnueabihf() { - TOOLCHAIN=LINARO - TARGET=arm-linux-gnueabihf - QEMU_ARCH=arm + export TARGET=arm-linux-gnueabihf } # Toolchains for little-endian, 32-bit ARMv8 for GNU/Linux systems function set_armv8l-linux-gnueabihf() { - TOOLCHAIN=LINARO - TARGET=armv8l-linux-gnueabihf - QEMU_ARCH=arm + export TARGET=armv8l-linux-gnueabihf } # Toolchains for little-endian, soft-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems function set_arm-linux-gnueabi() { - TOOLCHAIN=LINARO - TARGET=arm-linux-gnueabi - QEMU_ARCH=arm + export TARGET=arm-linux-gnueabi } # Toolchains for big-endian, 64-bit ARMv8 for GNU/Linux systems function set_aarch64_be-linux-gnu() { - TOOLCHAIN=LINARO - TARGET=aarch64_be-linux-gnu - QEMU_ARCH=DISABLED + export TARGET=aarch64_be-linux-gnu } # Toolchains for big-endian, hard-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems function set_armeb-linux-gnueabihf() { - TOOLCHAIN=LINARO - TARGET=armeb-linux-gnueabihf - QEMU_ARCH=DISABLED + export TARGET=armeb-linux-gnueabihf } # Toolchains for big-endian, soft-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems function set_armeb-linux-gnueabi() { - TOOLCHAIN=LINARO - TARGET=armeb-linux-gnueabi - QEMU_ARCH=DISABLED + export TARGET=armeb-linux-gnueabi } function set_mips32() { - TOOLCHAIN=CODESCAPE - TARGET=mips32 - QEMU_ARCH=mips + export TARGET=mips32 } function set_mips32el() { - TOOLCHAIN=CODESCAPE - TARGET=mips32el - QEMU_ARCH=mipsel + export TARGET=mips32el } function set_mips64() { - TOOLCHAIN=CODESCAPE - TARGET=mips64 - QEMU_ARCH=mips64 + export TARGET=mips64 } function set_mips64el() { - TOOLCHAIN=CODESCAPE - TARGET=mips64el - QEMU_ARCH=mips64el + export TARGET=mips64el } -function set_native() { - TOOLCHAIN=NATIVE - TARGET=native - QEMU_ARCH="" +function set_x86_64() { + export TARGET=x86_64 } ENVIRONMENTS=" @@ -96,14 +70,13 @@ ENVIRONMENTS=" set_mips32el set_mips64 set_mips64el - set_native + set_x86_64 " set -e -CMAKE_GENERATOR="Ninja" - for SET_ENVIRONMENT in ${ENVIRONMENTS}; do + echo "testing ${SET_ENVIRONMENT}" ${SET_ENVIRONMENT} - expand_environment_and_integrate + ./"$(dirname -- "$0")"/run_integration.sh done diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/copy.inl b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/copy.inl new file mode 100644 index 000000000..e657e8ac6 --- /dev/null +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/copy.inl @@ -0,0 +1,9 @@ +// SPDX-FileCopyrightText: 2021 Google LLC +// SPDX-License-Identifier: Apache-2.0 + +#include + +static void copy(char *__restrict dst, const char *src, size_t count) +{ + for (size_t i = 0; i < count; ++i) dst[i] = src[i]; +} diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/cpuinfo_aarch64.c b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/cpuinfo_aarch64.c deleted file mode 100644 index da7972763..000000000 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/cpuinfo_aarch64.c +++ /dev/null @@ -1,210 +0,0 @@ -// SPDX-FileCopyrightText: 2017 Google LLC -// SPDX-License-Identifier: Apache-2.0 - -#include "cpuinfo_aarch64.h" -#include "internal/filesystem.h" -#include "internal/hwcaps.h" -#include "internal/stack_line_reader.h" -#include "internal/string_view.h" -#include -#include - -#if defined(CPU_FEATURES_OS_DARWIN) -#if !defined(HAVE_SYSCTLBYNAME) -#error "Darwin needs support for sysctlbyname" -#endif -#include - -#if defined(CPU_FEATURES_MOCK_CPUID_ARM64) -extern bool GetDarwinSysCtlByName(const char*); -extern int GetDarwinSysCtlByNameValue(const char*); -#else // CPU_FEATURES_MOCK_CPUID_ARM64 -static bool GetDarwinSysCtlByName(const char* name) -{ - int enabled; - size_t enabled_len = sizeof(enabled); - const int failure = sysctlbyname(name, &enabled, &enabled_len, NULL, 0); - return failure ? false : enabled; -} -static int GetDarwinSysCtlByNameValue(const char* name) -{ - int enabled; - size_t enabled_len = sizeof(enabled); - const int failure = sysctlbyname(name, &enabled, &enabled_len, NULL, 0); - return failure ? 0 : enabled; -} -#endif -#endif // CPU_FEATURES_OS_DARWIN - -// Generation of feature's getters/setters functions and kGetters, kSetters, -// kCpuInfoFlags and kHardwareCapabilities global tables. -#define DEFINE_TABLE_FEATURES \ - FEATURE(AARCH64_FP, fp, "fp", AARCH64_HWCAP_FP, 0) \ - FEATURE(AARCH64_ASIMD, asimd, "asimd", AARCH64_HWCAP_ASIMD, 0) \ - FEATURE(AARCH64_EVTSTRM, evtstrm, "evtstrm", AARCH64_HWCAP_EVTSTRM, 0) \ - FEATURE(AARCH64_AES, aes, "aes", AARCH64_HWCAP_AES, 0) \ - FEATURE(AARCH64_PMULL, pmull, "pmull", AARCH64_HWCAP_PMULL, 0) \ - FEATURE(AARCH64_SHA1, sha1, "sha1", AARCH64_HWCAP_SHA1, 0) \ - FEATURE(AARCH64_SHA2, sha2, "sha2", AARCH64_HWCAP_SHA2, 0) \ - FEATURE(AARCH64_CRC32, crc32, "crc32", AARCH64_HWCAP_CRC32, 0) \ - FEATURE(AARCH64_ATOMICS, atomics, "atomics", AARCH64_HWCAP_ATOMICS, 0) \ - FEATURE(AARCH64_FPHP, fphp, "fphp", AARCH64_HWCAP_FPHP, 0) \ - FEATURE(AARCH64_ASIMDHP, asimdhp, "asimdhp", AARCH64_HWCAP_ASIMDHP, 0) \ - FEATURE(AARCH64_CPUID, cpuid, "cpuid", AARCH64_HWCAP_CPUID, 0) \ - FEATURE(AARCH64_ASIMDRDM, asimdrdm, "asimdrdm", AARCH64_HWCAP_ASIMDRDM, 0) \ - FEATURE(AARCH64_JSCVT, jscvt, "jscvt", AARCH64_HWCAP_JSCVT, 0) \ - FEATURE(AARCH64_FCMA, fcma, "fcma", AARCH64_HWCAP_FCMA, 0) \ - FEATURE(AARCH64_LRCPC, lrcpc, "lrcpc", AARCH64_HWCAP_LRCPC, 0) \ - FEATURE(AARCH64_DCPOP, dcpop, "dcpop", AARCH64_HWCAP_DCPOP, 0) \ - FEATURE(AARCH64_SHA3, sha3, "sha3", AARCH64_HWCAP_SHA3, 0) \ - FEATURE(AARCH64_SM3, sm3, "sm3", AARCH64_HWCAP_SM3, 0) \ - FEATURE(AARCH64_SM4, sm4, "sm4", AARCH64_HWCAP_SM4, 0) \ - FEATURE(AARCH64_ASIMDDP, asimddp, "asimddp", AARCH64_HWCAP_ASIMDDP, 0) \ - FEATURE(AARCH64_SHA512, sha512, "sha512", AARCH64_HWCAP_SHA512, 0) \ - FEATURE(AARCH64_SVE, sve, "sve", AARCH64_HWCAP_SVE, 0) \ - FEATURE(AARCH64_ASIMDFHM, asimdfhm, "asimdfhm", AARCH64_HWCAP_ASIMDFHM, 0) \ - FEATURE(AARCH64_DIT, dit, "dit", AARCH64_HWCAP_DIT, 0) \ - FEATURE(AARCH64_USCAT, uscat, "uscat", AARCH64_HWCAP_USCAT, 0) \ - FEATURE(AARCH64_ILRCPC, ilrcpc, "ilrcpc", AARCH64_HWCAP_ILRCPC, 0) \ - FEATURE(AARCH64_FLAGM, flagm, "flagm", AARCH64_HWCAP_FLAGM, 0) \ - FEATURE(AARCH64_SSBS, ssbs, "ssbs", AARCH64_HWCAP_SSBS, 0) \ - FEATURE(AARCH64_SB, sb, "sb", AARCH64_HWCAP_SB, 0) \ - FEATURE(AARCH64_PACA, paca, "paca", AARCH64_HWCAP_PACA, 0) \ - FEATURE(AARCH64_PACG, pacg, "pacg", AARCH64_HWCAP_PACG, 0) \ - FEATURE(AARCH64_DCPODP, dcpodp, "dcpodp", 0, AARCH64_HWCAP2_DCPODP) \ - FEATURE(AARCH64_SVE2, sve2, "sve2", 0, AARCH64_HWCAP2_SVE2) \ - FEATURE(AARCH64_SVEAES, sveaes, "sveaes", 0, AARCH64_HWCAP2_SVEAES) \ - FEATURE(AARCH64_SVEPMULL, svepmull, "svepmull", 0, AARCH64_HWCAP2_SVEPMULL) \ - FEATURE(AARCH64_SVEBITPERM, svebitperm, "svebitperm", 0, \ - AARCH64_HWCAP2_SVEBITPERM) \ - FEATURE(AARCH64_SVESHA3, svesha3, "svesha3", 0, AARCH64_HWCAP2_SVESHA3) \ - FEATURE(AARCH64_SVESM4, svesm4, "svesm4", 0, AARCH64_HWCAP2_SVESM4) \ - FEATURE(AARCH64_FLAGM2, flagm2, "flagm2", 0, AARCH64_HWCAP2_FLAGM2) \ - FEATURE(AARCH64_FRINT, frint, "frint", 0, AARCH64_HWCAP2_FRINT) \ - FEATURE(AARCH64_SVEI8MM, svei8mm, "svei8mm", 0, AARCH64_HWCAP2_SVEI8MM) \ - FEATURE(AARCH64_SVEF32MM, svef32mm, "svef32mm", 0, AARCH64_HWCAP2_SVEF32MM) \ - FEATURE(AARCH64_SVEF64MM, svef64mm, "svef64mm", 0, AARCH64_HWCAP2_SVEF64MM) \ - FEATURE(AARCH64_SVEBF16, svebf16, "svebf16", 0, AARCH64_HWCAP2_SVEBF16) \ - FEATURE(AARCH64_I8MM, i8mm, "i8mm", 0, AARCH64_HWCAP2_I8MM) \ - FEATURE(AARCH64_BF16, bf16, "bf16", 0, AARCH64_HWCAP2_BF16) \ - FEATURE(AARCH64_DGH, dgh, "dgh", 0, AARCH64_HWCAP2_DGH) \ - FEATURE(AARCH64_RNG, rng, "rng", 0, AARCH64_HWCAP2_RNG) \ - FEATURE(AARCH64_BTI, bti, "bti", 0, AARCH64_HWCAP2_BTI) \ - FEATURE(AARCH64_MTE, mte, "mte", 0, AARCH64_HWCAP2_MTE) -#define DEFINE_TABLE_FEATURE_TYPE Aarch64Features -#include "define_tables.h" - -#if !defined(CPU_FEATURES_OS_DARWIN) - -static bool HandleAarch64Line(const LineResult result, - Aarch64Info* const info) -{ - StringView line = result.line; - StringView key, value; - if (CpuFeatures_StringView_GetAttributeKeyValue(line, &key, &value)) - { - if (CpuFeatures_StringView_IsEquals(key, str("Features"))) - { - for (size_t i = 0; i < AARCH64_LAST_; ++i) - { - kSetters[i](&info->features, CpuFeatures_StringView_HasWord( - value, kCpuInfoFlags[i], ' ')); - } - } - else if (CpuFeatures_StringView_IsEquals(key, str("CPU implementer"))) - { - info->implementer = CpuFeatures_StringView_ParsePositiveNumber(value); - } - else if (CpuFeatures_StringView_IsEquals(key, str("CPU variant"))) - { - info->variant = CpuFeatures_StringView_ParsePositiveNumber(value); - } - else if (CpuFeatures_StringView_IsEquals(key, str("CPU part"))) - { - info->part = CpuFeatures_StringView_ParsePositiveNumber(value); - } - else if (CpuFeatures_StringView_IsEquals(key, str("CPU revision"))) - { - info->revision = CpuFeatures_StringView_ParsePositiveNumber(value); - } - } - return !result.eof; -} - -static void FillProcCpuInfoData(Aarch64Info* const info) -{ - const int fd = CpuFeatures_OpenFile("/proc/cpuinfo"); - if (fd >= 0) - { - StackLineReader reader; - StackLineReader_Initialize(&reader, fd); - for (;;) - { - if (!HandleAarch64Line(StackLineReader_NextLine(&reader), info)) - { - break; - } - } - CpuFeatures_CloseFile(fd); - } -} - -#endif /* !CPU_FEATURES_OS_DARWIN */ - -static const Aarch64Info kEmptyAarch64Info; - -Aarch64Info GetAarch64Info(void) -{ - // capabilities are fetched from both getauxval and /proc/cpuinfo so we can - // have some information if the executable is sandboxed (aka no access to - // /proc/cpuinfo). - Aarch64Info info = kEmptyAarch64Info; - -#if defined(CPU_FEATURES_OS_DARWIN) - - // Handling Darwin platform through sysctlbyname - info.implementer = GetDarwinSysCtlByNameValue("hw.cputype"); - info.variant = GetDarwinSysCtlByNameValue("hw.cpusubtype"); - info.part = GetDarwinSysCtlByNameValue("hw.cpufamily"); - info.revision = GetDarwinSysCtlByNameValue("hw.cpusubfamily"); - - info.features.fp = GetDarwinSysCtlByName("hw.optional.floatingpoint"); - info.features.fphp = GetDarwinSysCtlByName("hw.optional.neon_hpfp"); - info.features.sha512 = GetDarwinSysCtlByName("hw.optional.armv8_2_sha512"); - info.features.atomics = GetDarwinSysCtlByName("hw.optional.armv8_1_atomics"); - info.features.asimdfhm = GetDarwinSysCtlByName("hw.optional.armv8_2_fhm"); - info.features.sha3 = GetDarwinSysCtlByName("hw.optional.armv8_2_sha3"); - info.features.crc32 = GetDarwinSysCtlByName("hw.optional.armv8_crc32"); - -#else - - FillProcCpuInfoData(&info); - const HardwareCapabilities hwcaps = CpuFeatures_GetHardwareCapabilities(); - for (size_t i = 0; i < AARCH64_LAST_; ++i) - { - if (CpuFeatures_IsHwCapsSet(kHardwareCapabilities[i], hwcaps)) - { - kSetters[i](&info.features, true); - } - } - -#endif - - return info; -} - -//////////////////////////////////////////////////////////////////////////////// -// Introspection functions - -int GetAarch64FeaturesEnumValue(const Aarch64Features* features, - Aarch64FeaturesEnum value) -{ - if (value >= AARCH64_LAST_) return false; - return kGetters[value](features); -} - -const char* GetAarch64FeaturesEnumName(Aarch64FeaturesEnum value) -{ - if (value >= AARCH64_LAST_) return "unknown feature"; - return kCpuInfoFlags[value]; -} diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/cpuinfo_ppc.c b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/cpuinfo_ppc.c deleted file mode 100644 index d2d68a437..000000000 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/cpuinfo_ppc.c +++ /dev/null @@ -1,175 +0,0 @@ -// SPDX-FileCopyrightText: 2018 IBM. -// SPDX-License-Identifier: Apache-2.0 - -#include "cpuinfo_ppc.h" -#include "internal/bit_utils.h" -#include "internal/filesystem.h" -#include "internal/hwcaps.h" -#include "internal/stack_line_reader.h" -#include "internal/string_view.h" -#include -#include -#include - -// Generation of feature's getters/setters functions and kGetters, kSetters, -// kCpuInfoFlags and kHardwareCapabilities global tables. -#define DEFINE_TABLE_FEATURES \ - FEATURE(PPC_32, ppc32, "ppc32", PPC_FEATURE_32, 0) \ - FEATURE(PPC_64, ppc64, "ppc64", PPC_FEATURE_64, 0) \ - FEATURE(PPC_601_INSTR, ppc601, "ppc601", PPC_FEATURE_601_INSTR, 0) \ - FEATURE(PPC_HAS_ALTIVEC, altivec, "altivec", PPC_FEATURE_HAS_ALTIVEC, 0) \ - FEATURE(PPC_HAS_FPU, fpu, "fpu", PPC_FEATURE_HAS_FPU, 0) \ - FEATURE(PPC_HAS_MMU, mmu, "mmu", PPC_FEATURE_HAS_MMU, 0) \ - FEATURE(PPC_HAS_4xxMAC, mac_4xx, "4xxmac", PPC_FEATURE_HAS_4xxMAC, 0) \ - FEATURE(PPC_UNIFIED_CACHE, unifiedcache, "ucache", \ - PPC_FEATURE_UNIFIED_CACHE, 0) \ - FEATURE(PPC_HAS_SPE, spe, "spe", PPC_FEATURE_HAS_SPE, 0) \ - FEATURE(PPC_HAS_EFP_SINGLE, efpsingle, "efpsingle", \ - PPC_FEATURE_HAS_EFP_SINGLE, 0) \ - FEATURE(PPC_HAS_EFP_DOUBLE, efpdouble, "efpdouble", \ - PPC_FEATURE_HAS_EFP_DOUBLE, 0) \ - FEATURE(PPC_NO_TB, no_tb, "notb", PPC_FEATURE_NO_TB, 0) \ - FEATURE(PPC_POWER4, power4, "power4", PPC_FEATURE_POWER4, 0) \ - FEATURE(PPC_POWER5, power5, "power5", PPC_FEATURE_POWER5, 0) \ - FEATURE(PPC_POWER5_PLUS, power5plus, "power5+", PPC_FEATURE_POWER5_PLUS, 0) \ - FEATURE(PPC_CELL, cell, "cellbe", PPC_FEATURE_CELL, 0) \ - FEATURE(PPC_BOOKE, booke, "booke", PPC_FEATURE_BOOKE, 0) \ - FEATURE(PPC_SMT, smt, "smt", PPC_FEATURE_SMT, 0) \ - FEATURE(PPC_ICACHE_SNOOP, icachesnoop, "ic_snoop", PPC_FEATURE_ICACHE_SNOOP, \ - 0) \ - FEATURE(PPC_ARCH_2_05, arch205, "arch_2_05", PPC_FEATURE_ARCH_2_05, 0) \ - FEATURE(PPC_PA6T, pa6t, "pa6t", PPC_FEATURE_PA6T, 0) \ - FEATURE(PPC_HAS_DFP, dfp, "dfp", PPC_FEATURE_HAS_DFP, 0) \ - FEATURE(PPC_POWER6_EXT, power6ext, "power6x", PPC_FEATURE_POWER6_EXT, 0) \ - FEATURE(PPC_ARCH_2_06, arch206, "arch_2_06", PPC_FEATURE_ARCH_2_06, 0) \ - FEATURE(PPC_HAS_VSX, vsx, "vsx", PPC_FEATURE_HAS_VSX, 0) \ - FEATURE(PPC_PSERIES_PERFMON_COMPAT, pseries_perfmon_compat, "archpmu", \ - PPC_FEATURE_PSERIES_PERFMON_COMPAT, 0) \ - FEATURE(PPC_TRUE_LE, truele, "true_le", PPC_FEATURE_TRUE_LE, 0) \ - FEATURE(PPC_PPC_LE, ppcle, "ppcle", PPC_FEATURE_PPC_LE, 0) \ - FEATURE(PPC_ARCH_2_07, arch207, "arch_2_07", 0, PPC_FEATURE2_ARCH_2_07) \ - FEATURE(PPC_HTM, htm, "htm", 0, PPC_FEATURE2_HTM) \ - FEATURE(PPC_DSCR, dscr, "dscr", 0, PPC_FEATURE2_DSCR) \ - FEATURE(PPC_EBB, ebb, "ebb", 0, PPC_FEATURE2_EBB) \ - FEATURE(PPC_ISEL, isel, "isel", 0, PPC_FEATURE2_ISEL) \ - FEATURE(PPC_TAR, tar, "tar", 0, PPC_FEATURE2_TAR) \ - FEATURE(PPC_VEC_CRYPTO, vcrypto, "vcrypto", 0, PPC_FEATURE2_VEC_CRYPTO) \ - FEATURE(PPC_HTM_NOSC, htm_nosc, "htm-nosc", 0, PPC_FEATURE2_HTM_NOSC) \ - FEATURE(PPC_ARCH_3_00, arch300, "arch_3_00", 0, PPC_FEATURE2_ARCH_3_00) \ - FEATURE(PPC_HAS_IEEE128, ieee128, "ieee128", 0, PPC_FEATURE2_HAS_IEEE128) \ - FEATURE(PPC_DARN, darn, "darn", 0, PPC_FEATURE2_DARN) \ - FEATURE(PPC_SCV, scv, "scv", 0, PPC_FEATURE2_SCV) \ - FEATURE(PPC_HTM_NO_SUSPEND, htm_no_suspend, "htm-no-suspend", 0, \ - PPC_FEATURE2_HTM_NO_SUSPEND) -#define DEFINE_TABLE_FEATURE_TYPE PPCFeatures -#include "define_tables.h" - -static bool HandlePPCLine(const LineResult result, - PPCPlatformStrings* const strings) -{ - StringView line = result.line; - StringView key, value; - if (CpuFeatures_StringView_GetAttributeKeyValue(line, &key, &value)) - { - if (CpuFeatures_StringView_HasWord(key, "platform", ' ')) - { - CpuFeatures_StringView_CopyString(value, strings->platform, - sizeof(strings->platform)); - } - else if (CpuFeatures_StringView_IsEquals(key, str("model"))) - { - CpuFeatures_StringView_CopyString(value, strings->model, - sizeof(strings->platform)); - } - else if (CpuFeatures_StringView_IsEquals(key, str("machine"))) - { - CpuFeatures_StringView_CopyString(value, strings->machine, - sizeof(strings->platform)); - } - else if (CpuFeatures_StringView_IsEquals(key, str("cpu"))) - { - CpuFeatures_StringView_CopyString(value, strings->cpu, - sizeof(strings->platform)); - } - } - return !result.eof; -} - -static void FillProcCpuInfoData(PPCPlatformStrings* const strings) -{ - const int fd = CpuFeatures_OpenFile("/proc/cpuinfo"); - if (fd >= 0) - { - StackLineReader reader; - StackLineReader_Initialize(&reader, fd); - for (;;) - { - if (!HandlePPCLine(StackLineReader_NextLine(&reader), strings)) - { - break; - } - } - CpuFeatures_CloseFile(fd); - } -} - -static const PPCInfo kEmptyPPCInfo; - -PPCInfo GetPPCInfo(void) -{ - /* - * On Power feature flags aren't currently in cpuinfo so we only look at - * the auxilary vector. - */ - PPCInfo info = kEmptyPPCInfo; - const HardwareCapabilities hwcaps = CpuFeatures_GetHardwareCapabilities(); - for (size_t i = 0; i < PPC_LAST_; ++i) - { - if (CpuFeatures_IsHwCapsSet(kHardwareCapabilities[i], hwcaps)) - { - kSetters[i](&info.features, true); - } - } - return info; -} - -static const PPCPlatformStrings kEmptyPPCPlatformStrings; - -PPCPlatformStrings GetPPCPlatformStrings(void) -{ - PPCPlatformStrings strings = kEmptyPPCPlatformStrings; - const char* platform = CpuFeatures_GetPlatformPointer(); - const char* base_platform = CpuFeatures_GetBasePlatformPointer(); - - FillProcCpuInfoData(&strings); - - if (platform != NULL) - { - CpuFeatures_StringView_CopyString(str(platform), strings.type.platform, - sizeof(strings.type.platform)); - } - if (base_platform != NULL) - { - CpuFeatures_StringView_CopyString(str(base_platform), - strings.type.base_platform, - sizeof(strings.type.base_platform)); - } - - return strings; -} - -//////////////////////////////////////////////////////////////////////////////// -// Introspection functions - -int GetPPCFeaturesEnumValue(const PPCFeatures* features, - PPCFeaturesEnum value) -{ - if (value >= PPC_LAST_) return false; - return kGetters[value](features); -} - -const char* GetPPCFeaturesEnumName(PPCFeaturesEnum value) -{ - if (value >= PPC_LAST_) return "unknown feature"; - return kCpuInfoFlags[value]; -} diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/define_introspection.inl b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/define_introspection.inl new file mode 100644 index 000000000..62a7b096c --- /dev/null +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/define_introspection.inl @@ -0,0 +1,79 @@ +// SPDX-FileCopyrightText: 2017 Google LLC +// SPDX-License-Identifier: Apache-2.0 + +#ifndef INTROSPECTION_PREFIX +#error "missing INTROSPECTION_PREFIX" +#endif +#ifndef INTROSPECTION_ENUM_PREFIX +#error "missing INTROSPECTION_ENUM_PREFIX" +#endif +#ifndef INTROSPECTION_TABLE +#error "missing INTROSPECTION_TABLE" +#endif + +#include + +#define STRINGIZE_(s) #s +#define STRINGIZE(s) STRINGIZE_(s) + +#define FEAT_TYPE_NAME__(X) X##Features +#define FEAT_TYPE_NAME_(X) FEAT_TYPE_NAME__(X) +#define FEAT_TYPE_NAME FEAT_TYPE_NAME_(INTROSPECTION_PREFIX) + +#define FEAT_ENUM_NAME__(X) X##FeaturesEnum +#define FEAT_ENUM_NAME_(X) FEAT_ENUM_NAME__(X) +#define FEAT_ENUM_NAME FEAT_ENUM_NAME_(INTROSPECTION_PREFIX) + +#define GET_FEAT_ENUM_VALUE__(X) Get##X##FeaturesEnumValue +#define GET_FEAT_ENUM_VALUE_(X) GET_FEAT_ENUM_VALUE__(X) +#define GET_FEAT_ENUM_VALUE GET_FEAT_ENUM_VALUE_(INTROSPECTION_PREFIX) + +#define GET_FEAT_ENUM_NAME__(X) Get##X##FeaturesEnumName +#define GET_FEAT_ENUM_NAME_(X) GET_FEAT_ENUM_NAME__(X) +#define GET_FEAT_ENUM_NAME GET_FEAT_ENUM_NAME_(INTROSPECTION_PREFIX) + +#define FEAT_ENUM_LAST__(X) X##_LAST_ +#define FEAT_ENUM_LAST_(X) FEAT_ENUM_LAST__(X) +#define FEAT_ENUM_LAST FEAT_ENUM_LAST_(INTROSPECTION_ENUM_PREFIX) + +// Generate individual getters and setters. +#define LINE(ENUM, NAME, A, B, C) \ + static void set_##ENUM(FEAT_TYPE_NAME* features, bool value) \ + { \ + features->NAME = value; \ + } \ + static int get_##ENUM(const FEAT_TYPE_NAME* features) \ + { \ + return features->NAME; \ + } +INTROSPECTION_TABLE +#undef LINE + +// Generate getters table +#define LINE(ENUM, NAME, A, B, C) [ENUM] = get_##ENUM, +static int (*const kGetters[])(const FEAT_TYPE_NAME*) = {INTROSPECTION_TABLE}; +#undef LINE + +// Generate setters table +#define LINE(ENUM, NAME, A, B, C) [ENUM] = set_##ENUM, +static void (*const kSetters[])(FEAT_TYPE_NAME*, bool) = {INTROSPECTION_TABLE}; +#undef LINE + +// Implements the `GetXXXFeaturesEnumValue` API. +int GET_FEAT_ENUM_VALUE(const FEAT_TYPE_NAME* features, FEAT_ENUM_NAME value) +{ + if (value >= FEAT_ENUM_LAST) return false; + return kGetters[value](features); +} + +// Generate feature name table. +#define LINE(ENUM, NAME, A, B, C) [ENUM] = STRINGIZE(NAME), +static const char* kFeatureNames[] = {INTROSPECTION_TABLE}; +#undef LINE + +// Implements the `GetXXXFeaturesEnumName` API. +const char* GET_FEAT_ENUM_NAME(FEAT_ENUM_NAME value) +{ + if (value >= FEAT_ENUM_LAST) return "unknown_feature"; + return kFeatureNames[value]; +} diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/define_introspection_and_hwcaps.inl b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/define_introspection_and_hwcaps.inl new file mode 100644 index 000000000..6a84c2bea --- /dev/null +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/define_introspection_and_hwcaps.inl @@ -0,0 +1,15 @@ +// SPDX-FileCopyrightText: 2017 Google LLC +// SPDX-License-Identifier: Apache-2.0 + +#include "internal/hwcaps.h" +#include "define_introspection.inl" + +#define LINE(ENUM, NAME, CPUINFO_FLAG, HWCAP, HWCAP2) \ + [ENUM] = (HardwareCapabilities){HWCAP, HWCAP2}, +static const HardwareCapabilities kHardwareCapabilities[] = { + INTROSPECTION_TABLE}; +#undef LINE + +#define LINE(ENUM, NAME, CPUINFO_FLAG, HWCAP, HWCAP2) [ENUM] = CPUINFO_FLAG, +static const char* kCpuInfoFlags[] = {INTROSPECTION_TABLE}; +#undef LINE diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/define_tables.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/define_tables.h deleted file mode 100644 index b0a069d34..000000000 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/define_tables.h +++ /dev/null @@ -1,58 +0,0 @@ -// SPDX-FileCopyrightText: 2017 Google LLC -// SPDX-License-Identifier: Apache-2.0 - -// The following preprocessor constants must be defined before including this -// file: -// - DEFINE_TABLE_FEATURE_TYPE, the underlying type (e.g. X86Features) -// - DEFINE_TABLE_FEATURES, the list of FEATURE macros to be inserted. - -// This file is to be included once per `cpuinfo_XXX.c` in order to construct -// feature getters and setters functions as well as several enum indexed tables -// from the db file. -// - `kGetters` a table of getters function pointers from feature enum to -// retrieve a feature, -// - `kSetters` a table of setters function pointers from feature enum to set a -// feature, -// - `kCpuInfoFlags` a table of strings from feature enum to /proc/cpuinfo -// flags, -// - `kHardwareCapabilities` a table of HardwareCapabilities structs indexed by -// their feature enum. - -#ifndef SRC_DEFINE_TABLES_H_ -#define SRC_DEFINE_TABLES_H_ - -#define FEATURE(ENUM, NAME, CPUINFO_FLAG, HWCAP, HWCAP2) [ENUM] = CPUINFO_FLAG, -static const char* kCpuInfoFlags[] = {DEFINE_TABLE_FEATURES}; -#undef FEATURE - -#ifndef DEFINE_TABLE_DONT_GENERATE_HWCAPS -#define FEATURE(ENUM, NAME, CPUINFO_FLAG, HWCAP, HWCAP2) \ - [ENUM] = (HardwareCapabilities){HWCAP, HWCAP2}, -static const HardwareCapabilities kHardwareCapabilities[] = { - DEFINE_TABLE_FEATURES}; -#undef FEATURE -#endif // DEFINE_TABLE_DONT_GENERATE_HWCAPS - -#define FEATURE(ENUM, NAME, CPUINFO_FLAG, HWCAP, HWCAP2) \ - static void set_##ENUM(DEFINE_TABLE_FEATURE_TYPE* features, bool value) \ - { \ - features->NAME = value; \ - } \ - static int get_##ENUM(const DEFINE_TABLE_FEATURE_TYPE* features) \ - { \ - return features->NAME; \ - } -DEFINE_TABLE_FEATURES -#undef FEATURE - -#define FEATURE(ENUM, NAME, CPUINFO_FLAG, HWCAP, HWCAP2) [ENUM] = set_##ENUM, -static void (*const kSetters[])(DEFINE_TABLE_FEATURE_TYPE*, - bool) = {DEFINE_TABLE_FEATURES}; -#undef FEATURE - -#define FEATURE(ENUM, NAME, CPUINFO_FLAG, HWCAP, HWCAP2) [ENUM] = get_##ENUM, -static int (*const kGetters[])(const DEFINE_TABLE_FEATURE_TYPE*) = { - DEFINE_TABLE_FEATURES}; -#undef FEATURE - -#endif // SRC_DEFINE_TABLES_H_ diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/equals.inl b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/equals.inl new file mode 100644 index 000000000..1936d7a71 --- /dev/null +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/equals.inl @@ -0,0 +1,12 @@ +// SPDX-FileCopyrightText: 2021 Google LLC +// SPDX-License-Identifier: Apache-2.0 + +#include +#include + +static bool equals(const char *lhs, const char *rhs, size_t count) +{ + for (size_t i = 0; i < count; ++i) + if (lhs[i] != rhs[i]) return false; + return true; +} diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/hwcaps.c b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/hwcaps.c index 111a4b84d..9a13d8b75 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/hwcaps.c +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/hwcaps.c @@ -60,13 +60,7 @@ static unsigned long GetElfHwcapFromGetauxval(uint32_t hwcap_type) #elif defined(HAVE_DLFCN_H) // On Android we probe the system's C library for a 'getauxval' function and // call it if it exits, or return 0 for failure. This function is available -// since API level 20. -// -// This code does *NOT* check for '__ANDROID_API__ >= 20' to support the edge -// case where some NDK developers use headers for a platform that is newer than -// the one really targetted by their application. This is typically done to use -// newer native APIs only when running on more recent Android versions, and -// requires careful symbol management. +// since API level 18. // // Note that getauxval() can't really be re-implemented here, because its // implementation does not parse /proc/self/auxv. Instead it depends on values diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_aarch64_linux_or_android.c b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_aarch64_linux_or_android.c new file mode 100644 index 000000000..fec374025 --- /dev/null +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_aarch64_linux_or_android.c @@ -0,0 +1,157 @@ +// SPDX-FileCopyrightText: 2017 Google LLC +// SPDX-License-Identifier: Apache-2.0 + +#include "cpu_features_macros.h" + +#ifdef CPU_FEATURES_ARCH_AARCH64 +#if defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID) + +#include "cpuinfo_aarch64.h" + +//////////////////////////////////////////////////////////////////////////////// +// Definitions for introspection. +//////////////////////////////////////////////////////////////////////////////// +#define INTROSPECTION_TABLE \ + LINE(AARCH64_FP, fp, "fp", AARCH64_HWCAP_FP, 0) \ + LINE(AARCH64_ASIMD, asimd, "asimd", AARCH64_HWCAP_ASIMD, 0) \ + LINE(AARCH64_EVTSTRM, evtstrm, "evtstrm", AARCH64_HWCAP_EVTSTRM, 0) \ + LINE(AARCH64_AES, aes, "aes", AARCH64_HWCAP_AES, 0) \ + LINE(AARCH64_PMULL, pmull, "pmull", AARCH64_HWCAP_PMULL, 0) \ + LINE(AARCH64_SHA1, sha1, "sha1", AARCH64_HWCAP_SHA1, 0) \ + LINE(AARCH64_SHA2, sha2, "sha2", AARCH64_HWCAP_SHA2, 0) \ + LINE(AARCH64_CRC32, crc32, "crc32", AARCH64_HWCAP_CRC32, 0) \ + LINE(AARCH64_ATOMICS, atomics, "atomics", AARCH64_HWCAP_ATOMICS, 0) \ + LINE(AARCH64_FPHP, fphp, "fphp", AARCH64_HWCAP_FPHP, 0) \ + LINE(AARCH64_ASIMDHP, asimdhp, "asimdhp", AARCH64_HWCAP_ASIMDHP, 0) \ + LINE(AARCH64_CPUID, cpuid, "cpuid", AARCH64_HWCAP_CPUID, 0) \ + LINE(AARCH64_ASIMDRDM, asimdrdm, "asimdrdm", AARCH64_HWCAP_ASIMDRDM, 0) \ + LINE(AARCH64_JSCVT, jscvt, "jscvt", AARCH64_HWCAP_JSCVT, 0) \ + LINE(AARCH64_FCMA, fcma, "fcma", AARCH64_HWCAP_FCMA, 0) \ + LINE(AARCH64_LRCPC, lrcpc, "lrcpc", AARCH64_HWCAP_LRCPC, 0) \ + LINE(AARCH64_DCPOP, dcpop, "dcpop", AARCH64_HWCAP_DCPOP, 0) \ + LINE(AARCH64_SHA3, sha3, "sha3", AARCH64_HWCAP_SHA3, 0) \ + LINE(AARCH64_SM3, sm3, "sm3", AARCH64_HWCAP_SM3, 0) \ + LINE(AARCH64_SM4, sm4, "sm4", AARCH64_HWCAP_SM4, 0) \ + LINE(AARCH64_ASIMDDP, asimddp, "asimddp", AARCH64_HWCAP_ASIMDDP, 0) \ + LINE(AARCH64_SHA512, sha512, "sha512", AARCH64_HWCAP_SHA512, 0) \ + LINE(AARCH64_SVE, sve, "sve", AARCH64_HWCAP_SVE, 0) \ + LINE(AARCH64_ASIMDFHM, asimdfhm, "asimdfhm", AARCH64_HWCAP_ASIMDFHM, 0) \ + LINE(AARCH64_DIT, dit, "dit", AARCH64_HWCAP_DIT, 0) \ + LINE(AARCH64_USCAT, uscat, "uscat", AARCH64_HWCAP_USCAT, 0) \ + LINE(AARCH64_ILRCPC, ilrcpc, "ilrcpc", AARCH64_HWCAP_ILRCPC, 0) \ + LINE(AARCH64_FLAGM, flagm, "flagm", AARCH64_HWCAP_FLAGM, 0) \ + LINE(AARCH64_SSBS, ssbs, "ssbs", AARCH64_HWCAP_SSBS, 0) \ + LINE(AARCH64_SB, sb, "sb", AARCH64_HWCAP_SB, 0) \ + LINE(AARCH64_PACA, paca, "paca", AARCH64_HWCAP_PACA, 0) \ + LINE(AARCH64_PACG, pacg, "pacg", AARCH64_HWCAP_PACG, 0) \ + LINE(AARCH64_DCPODP, dcpodp, "dcpodp", 0, AARCH64_HWCAP2_DCPODP) \ + LINE(AARCH64_SVE2, sve2, "sve2", 0, AARCH64_HWCAP2_SVE2) \ + LINE(AARCH64_SVEAES, sveaes, "sveaes", 0, AARCH64_HWCAP2_SVEAES) \ + LINE(AARCH64_SVEPMULL, svepmull, "svepmull", 0, AARCH64_HWCAP2_SVEPMULL) \ + LINE(AARCH64_SVEBITPERM, svebitperm, "svebitperm", 0, \ + AARCH64_HWCAP2_SVEBITPERM) \ + LINE(AARCH64_SVESHA3, svesha3, "svesha3", 0, AARCH64_HWCAP2_SVESHA3) \ + LINE(AARCH64_SVESM4, svesm4, "svesm4", 0, AARCH64_HWCAP2_SVESM4) \ + LINE(AARCH64_FLAGM2, flagm2, "flagm2", 0, AARCH64_HWCAP2_FLAGM2) \ + LINE(AARCH64_FRINT, frint, "frint", 0, AARCH64_HWCAP2_FRINT) \ + LINE(AARCH64_SVEI8MM, svei8mm, "svei8mm", 0, AARCH64_HWCAP2_SVEI8MM) \ + LINE(AARCH64_SVEF32MM, svef32mm, "svef32mm", 0, AARCH64_HWCAP2_SVEF32MM) \ + LINE(AARCH64_SVEF64MM, svef64mm, "svef64mm", 0, AARCH64_HWCAP2_SVEF64MM) \ + LINE(AARCH64_SVEBF16, svebf16, "svebf16", 0, AARCH64_HWCAP2_SVEBF16) \ + LINE(AARCH64_I8MM, i8mm, "i8mm", 0, AARCH64_HWCAP2_I8MM) \ + LINE(AARCH64_BF16, bf16, "bf16", 0, AARCH64_HWCAP2_BF16) \ + LINE(AARCH64_DGH, dgh, "dgh", 0, AARCH64_HWCAP2_DGH) \ + LINE(AARCH64_RNG, rng, "rng", 0, AARCH64_HWCAP2_RNG) \ + LINE(AARCH64_BTI, bti, "bti", 0, AARCH64_HWCAP2_BTI) \ + LINE(AARCH64_MTE, mte, "mte", 0, AARCH64_HWCAP2_MTE) +#define INTROSPECTION_PREFIX Aarch64 +#define INTROSPECTION_ENUM_PREFIX AARCH64 +#include "define_introspection_and_hwcaps.inl" + +//////////////////////////////////////////////////////////////////////////////// +// Implementation. +//////////////////////////////////////////////////////////////////////////////// + +#include "internal/bit_utils.h" +#include "internal/filesystem.h" +#include "internal/stack_line_reader.h" +#include "internal/string_view.h" +#include + +static bool HandleAarch64Line(const LineResult result, + Aarch64Info* const info) +{ + StringView line = result.line; + StringView key, value; + if (CpuFeatures_StringView_GetAttributeKeyValue(line, &key, &value)) + { + if (CpuFeatures_StringView_IsEquals(key, str("Features"))) + { + for (size_t i = 0; i < AARCH64_LAST_; ++i) + { + kSetters[i](&info->features, CpuFeatures_StringView_HasWord( + value, kCpuInfoFlags[i], ' ')); + } + } + else if (CpuFeatures_StringView_IsEquals(key, str("CPU implementer"))) + { + info->implementer = CpuFeatures_StringView_ParsePositiveNumber(value); + } + else if (CpuFeatures_StringView_IsEquals(key, str("CPU variant"))) + { + info->variant = CpuFeatures_StringView_ParsePositiveNumber(value); + } + else if (CpuFeatures_StringView_IsEquals(key, str("CPU part"))) + { + info->part = CpuFeatures_StringView_ParsePositiveNumber(value); + } + else if (CpuFeatures_StringView_IsEquals(key, str("CPU revision"))) + { + info->revision = CpuFeatures_StringView_ParsePositiveNumber(value); + } + } + return !result.eof; +} + +static void FillProcCpuInfoData(Aarch64Info* const info) +{ + const int fd = CpuFeatures_OpenFile("/proc/cpuinfo"); + if (fd >= 0) + { + StackLineReader reader; + StackLineReader_Initialize(&reader, fd); + for (;;) + { + if (!HandleAarch64Line(StackLineReader_NextLine(&reader), info)) + { + break; + } + } + CpuFeatures_CloseFile(fd); + } +} + +static const Aarch64Info kEmptyAarch64Info; + +Aarch64Info GetAarch64Info(void) +{ + // capabilities are fetched from both getauxval and /proc/cpuinfo so we can + // have some information if the executable is sandboxed (aka no access to + // /proc/cpuinfo). + Aarch64Info info = kEmptyAarch64Info; + + FillProcCpuInfoData(&info); + const HardwareCapabilities hwcaps = CpuFeatures_GetHardwareCapabilities(); + for (size_t i = 0; i < AARCH64_LAST_; ++i) + { + if (CpuFeatures_IsHwCapsSet(kHardwareCapabilities[i], hwcaps)) + { + kSetters[i](&info.features, true); + } + } + + return info; +} + +#endif // defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID) +#endif // CPU_FEATURES_ARCH_AARCH64 diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/cpuinfo_arm.c b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_arm_linux_or_android.c similarity index 69% rename from src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/cpuinfo_arm.c rename to src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_arm_linux_or_android.c index 69abe91f4..298120228 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/cpuinfo_arm.c +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_arm_linux_or_android.c @@ -1,47 +1,58 @@ // SPDX-FileCopyrightText: 2017 Google LLC // SPDX-License-Identifier: Apache-2.0 +#include "cpu_features_macros.h" + +#ifdef CPU_FEATURES_ARCH_ARM +#if defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID) + #include "cpuinfo_arm.h" + +//////////////////////////////////////////////////////////////////////////////// +// Definitions for introspection. +//////////////////////////////////////////////////////////////////////////////// +#define INTROSPECTION_TABLE \ + LINE(ARM_SWP, swp, "swp", ARM_HWCAP_SWP, 0) \ + LINE(ARM_HALF, half, "half", ARM_HWCAP_HALF, 0) \ + LINE(ARM_THUMB, thumb, "thumb", ARM_HWCAP_THUMB, 0) \ + LINE(ARM_26BIT, _26bit, "26bit", ARM_HWCAP_26BIT, 0) \ + LINE(ARM_FASTMULT, fastmult, "fastmult", ARM_HWCAP_FAST_MULT, 0) \ + LINE(ARM_FPA, fpa, "fpa", ARM_HWCAP_FPA, 0) \ + LINE(ARM_VFP, vfp, "vfp", ARM_HWCAP_VFP, 0) \ + LINE(ARM_EDSP, edsp, "edsp", ARM_HWCAP_EDSP, 0) \ + LINE(ARM_JAVA, java, "java", ARM_HWCAP_JAVA, 0) \ + LINE(ARM_IWMMXT, iwmmxt, "iwmmxt", ARM_HWCAP_IWMMXT, 0) \ + LINE(ARM_CRUNCH, crunch, "crunch", ARM_HWCAP_CRUNCH, 0) \ + LINE(ARM_THUMBEE, thumbee, "thumbee", ARM_HWCAP_THUMBEE, 0) \ + LINE(ARM_NEON, neon, "neon", ARM_HWCAP_NEON, 0) \ + LINE(ARM_VFPV3, vfpv3, "vfpv3", ARM_HWCAP_VFPV3, 0) \ + LINE(ARM_VFPV3D16, vfpv3d16, "vfpv3d16", ARM_HWCAP_VFPV3D16, 0) \ + LINE(ARM_TLS, tls, "tls", ARM_HWCAP_TLS, 0) \ + LINE(ARM_VFPV4, vfpv4, "vfpv4", ARM_HWCAP_VFPV4, 0) \ + LINE(ARM_IDIVA, idiva, "idiva", ARM_HWCAP_IDIVA, 0) \ + LINE(ARM_IDIVT, idivt, "idivt", ARM_HWCAP_IDIVT, 0) \ + LINE(ARM_VFPD32, vfpd32, "vfpd32", ARM_HWCAP_VFPD32, 0) \ + LINE(ARM_LPAE, lpae, "lpae", ARM_HWCAP_LPAE, 0) \ + LINE(ARM_EVTSTRM, evtstrm, "evtstrm", ARM_HWCAP_EVTSTRM, 0) \ + LINE(ARM_AES, aes, "aes", 0, ARM_HWCAP2_AES) \ + LINE(ARM_PMULL, pmull, "pmull", 0, ARM_HWCAP2_PMULL) \ + LINE(ARM_SHA1, sha1, "sha1", 0, ARM_HWCAP2_SHA1) \ + LINE(ARM_SHA2, sha2, "sha2", 0, ARM_HWCAP2_SHA2) \ + LINE(ARM_CRC32, crc32, "crc32", 0, ARM_HWCAP2_CRC32) +#define INTROSPECTION_PREFIX Arm +#define INTROSPECTION_ENUM_PREFIX ARM +#include "define_introspection_and_hwcaps.inl" + +//////////////////////////////////////////////////////////////////////////////// +// Implementation. +//////////////////////////////////////////////////////////////////////////////// + #include "internal/bit_utils.h" #include "internal/filesystem.h" -#include "internal/hwcaps.h" #include "internal/stack_line_reader.h" #include "internal/string_view.h" -#include #include - -// Generation of feature's getters/setters functions and kGetters, kSetters, -// kCpuInfoFlags and kHardwareCapabilities global tables. -#define DEFINE_TABLE_FEATURES \ - FEATURE(ARM_SWP, swp, "swp", ARM_HWCAP_SWP, 0) \ - FEATURE(ARM_HALF, half, "half", ARM_HWCAP_HALF, 0) \ - FEATURE(ARM_THUMB, thumb, "thumb", ARM_HWCAP_THUMB, 0) \ - FEATURE(ARM_26BIT, _26bit, "26bit", ARM_HWCAP_26BIT, 0) \ - FEATURE(ARM_FASTMULT, fastmult, "fastmult", ARM_HWCAP_FAST_MULT, 0) \ - FEATURE(ARM_FPA, fpa, "fpa", ARM_HWCAP_FPA, 0) \ - FEATURE(ARM_VFP, vfp, "vfp", ARM_HWCAP_VFP, 0) \ - FEATURE(ARM_EDSP, edsp, "edsp", ARM_HWCAP_EDSP, 0) \ - FEATURE(ARM_JAVA, java, "java", ARM_HWCAP_JAVA, 0) \ - FEATURE(ARM_IWMMXT, iwmmxt, "iwmmxt", ARM_HWCAP_IWMMXT, 0) \ - FEATURE(ARM_CRUNCH, crunch, "crunch", ARM_HWCAP_CRUNCH, 0) \ - FEATURE(ARM_THUMBEE, thumbee, "thumbee", ARM_HWCAP_THUMBEE, 0) \ - FEATURE(ARM_NEON, neon, "neon", ARM_HWCAP_NEON, 0) \ - FEATURE(ARM_VFPV3, vfpv3, "vfpv3", ARM_HWCAP_VFPV3, 0) \ - FEATURE(ARM_VFPV3D16, vfpv3d16, "vfpv3d16", ARM_HWCAP_VFPV3D16, 0) \ - FEATURE(ARM_TLS, tls, "tls", ARM_HWCAP_TLS, 0) \ - FEATURE(ARM_VFPV4, vfpv4, "vfpv4", ARM_HWCAP_VFPV4, 0) \ - FEATURE(ARM_IDIVA, idiva, "idiva", ARM_HWCAP_IDIVA, 0) \ - FEATURE(ARM_IDIVT, idivt, "idivt", ARM_HWCAP_IDIVT, 0) \ - FEATURE(ARM_VFPD32, vfpd32, "vfpd32", ARM_HWCAP_VFPD32, 0) \ - FEATURE(ARM_LPAE, lpae, "lpae", ARM_HWCAP_LPAE, 0) \ - FEATURE(ARM_EVTSTRM, evtstrm, "evtstrm", ARM_HWCAP_EVTSTRM, 0) \ - FEATURE(ARM_AES, aes, "aes", 0, ARM_HWCAP2_AES) \ - FEATURE(ARM_PMULL, pmull, "pmull", 0, ARM_HWCAP2_PMULL) \ - FEATURE(ARM_SHA1, sha1, "sha1", 0, ARM_HWCAP2_SHA1) \ - FEATURE(ARM_SHA2, sha2, "sha2", 0, ARM_HWCAP2_SHA2) \ - FEATURE(ARM_CRC32, crc32, "crc32", 0, ARM_HWCAP2_CRC32) -#define DEFINE_TABLE_FEATURE_TYPE ArmFeatures -#include "define_tables.h" +#include typedef struct { @@ -155,13 +166,15 @@ static void FixErrors(ArmInfo* const info, // https://crbug.com/341598. info->features.neon = false; break; - case 0x510006F2: - case 0x510006F3: - // The Nexus 4 (Qualcomm Krait) kernel configuration forgets to report - // IDIV support. + } + + // Some Qualcomm Krait kernels forget to report IDIV support. + // https://github.com/torvalds/linux/commit/120ecfafabec382c4feb79ff159ef42a39b6d33b + if (info->implementer == 0x51 && info->architecture == 7 && + (info->part == 0x4d || info->part == 0x6f)) + { info->features.idiva = true; info->features.idivt = true; - break; } // Propagate cpu features. @@ -217,18 +230,5 @@ ArmInfo GetArmInfo(void) return info; } -//////////////////////////////////////////////////////////////////////////////// -// Introspection functions - -int GetArmFeaturesEnumValue(const ArmFeatures* features, - ArmFeaturesEnum value) -{ - if (value >= ARM_LAST_) return false; - return kGetters[value](features); -} - -const char* GetArmFeaturesEnumName(ArmFeaturesEnum value) -{ - if (value >= ARM_LAST_) return "unknown feature"; - return kCpuInfoFlags[value]; -} +#endif // defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID) +#endif // CPU_FEATURES_ARCH_ARM diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/cpuinfo_mips.c b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_mips_linux_or_android.c similarity index 71% rename from src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/cpuinfo_mips.c rename to src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_mips_linux_or_android.c index 31794dc93..cb874ffc6 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/cpuinfo_mips.c +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_mips_linux_or_android.c @@ -1,21 +1,32 @@ // SPDX-FileCopyrightText: 2017 Google LLC // SPDX-License-Identifier: Apache-2.0 +#include "cpu_features_macros.h" + +#ifdef CPU_FEATURES_ARCH_MIPS +#if defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID) + #include "cpuinfo_mips.h" + +//////////////////////////////////////////////////////////////////////////////// +// Definitions for introspection. +//////////////////////////////////////////////////////////////////////////////// +#define INTROSPECTION_TABLE \ + LINE(MIPS_MSA, msa, "msa", MIPS_HWCAP_MSA, 0) \ + LINE(MIPS_EVA, eva, "eva", 0, 0) \ + LINE(MIPS_R6, r6, "r6", MIPS_HWCAP_R6, 0) +#define INTROSPECTION_PREFIX Mips +#define INTROSPECTION_ENUM_PREFIX MIPS +#include "define_introspection_and_hwcaps.inl" + +//////////////////////////////////////////////////////////////////////////////// +// Implementation. +//////////////////////////////////////////////////////////////////////////////// + #include "internal/filesystem.h" #include "internal/hwcaps.h" #include "internal/stack_line_reader.h" #include "internal/string_view.h" -#include - -// Generation of feature's getters/setters functions and kGetters, kSetters, -// kCpuInfoFlags and kHardwareCapabilities global tables. -#define DEFINE_TABLE_FEATURES \ - FEATURE(MIPS_MSA, msa, "msa", MIPS_HWCAP_MSA, 0) \ - FEATURE(MIPS_EVA, eva, "eva", 0, 0) \ - FEATURE(MIPS_R6, r6, "r6", MIPS_HWCAP_R6, 0) -#define DEFINE_TABLE_FEATURE_TYPE MipsFeatures -#include "define_tables.h" static bool HandleMipsLine(const LineResult result, MipsFeatures* const features) @@ -75,18 +86,5 @@ MipsInfo GetMipsInfo(void) return info; } -//////////////////////////////////////////////////////////////////////////////// -// Introspection functions - -int GetMipsFeaturesEnumValue(const MipsFeatures* features, - MipsFeaturesEnum value) -{ - if (value >= MIPS_LAST_) return false; - return kGetters[value](features); -} - -const char* GetMipsFeaturesEnumName(MipsFeaturesEnum value) -{ - if (value >= MIPS_LAST_) return "unknown feature"; - return kCpuInfoFlags[value]; -} +#endif // defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID) +#endif // CPU_FEATURES_ARCH_MIPS diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_ppc_linux.c b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_ppc_linux.c new file mode 100644 index 000000000..3303be405 --- /dev/null +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_ppc_linux.c @@ -0,0 +1,167 @@ +// SPDX-FileCopyrightText: 2017 Google LLC +// SPDX-License-Identifier: Apache-2.0 + +#include "cpu_features_macros.h" + +#ifdef CPU_FEATURES_ARCH_PPC +#ifdef CPU_FEATURES_OS_LINUX + +#include "cpuinfo_ppc.h" + +//////////////////////////////////////////////////////////////////////////////// +// Definitions for introspection. +//////////////////////////////////////////////////////////////////////////////// +#define INTROSPECTION_TABLE \ + LINE(PPC_32, ppc32, "ppc32", PPC_FEATURE_32, 0) \ + LINE(PPC_64, ppc64, "ppc64", PPC_FEATURE_64, 0) \ + LINE(PPC_601_INSTR, ppc601, "ppc601", PPC_FEATURE_601_INSTR, 0) \ + LINE(PPC_HAS_ALTIVEC, altivec, "altivec", PPC_FEATURE_HAS_ALTIVEC, 0) \ + LINE(PPC_HAS_FPU, fpu, "fpu", PPC_FEATURE_HAS_FPU, 0) \ + LINE(PPC_HAS_MMU, mmu, "mmu", PPC_FEATURE_HAS_MMU, 0) \ + LINE(PPC_HAS_4xxMAC, mac_4xx, "4xxmac", PPC_FEATURE_HAS_4xxMAC, 0) \ + LINE(PPC_UNIFIED_CACHE, unifiedcache, "ucache", PPC_FEATURE_UNIFIED_CACHE, \ + 0) \ + LINE(PPC_HAS_SPE, spe, "spe", PPC_FEATURE_HAS_SPE, 0) \ + LINE(PPC_HAS_EFP_SINGLE, efpsingle, "efpsingle", PPC_FEATURE_HAS_EFP_SINGLE, \ + 0) \ + LINE(PPC_HAS_EFP_DOUBLE, efpdouble, "efpdouble", PPC_FEATURE_HAS_EFP_DOUBLE, \ + 0) \ + LINE(PPC_NO_TB, no_tb, "notb", PPC_FEATURE_NO_TB, 0) \ + LINE(PPC_POWER4, power4, "power4", PPC_FEATURE_POWER4, 0) \ + LINE(PPC_POWER5, power5, "power5", PPC_FEATURE_POWER5, 0) \ + LINE(PPC_POWER5_PLUS, power5plus, "power5+", PPC_FEATURE_POWER5_PLUS, 0) \ + LINE(PPC_CELL, cell, "cellbe", PPC_FEATURE_CELL, 0) \ + LINE(PPC_BOOKE, booke, "booke", PPC_FEATURE_BOOKE, 0) \ + LINE(PPC_SMT, smt, "smt", PPC_FEATURE_SMT, 0) \ + LINE(PPC_ICACHE_SNOOP, icachesnoop, "ic_snoop", PPC_FEATURE_ICACHE_SNOOP, 0) \ + LINE(PPC_ARCH_2_05, arch205, "arch_2_05", PPC_FEATURE_ARCH_2_05, 0) \ + LINE(PPC_PA6T, pa6t, "pa6t", PPC_FEATURE_PA6T, 0) \ + LINE(PPC_HAS_DFP, dfp, "dfp", PPC_FEATURE_HAS_DFP, 0) \ + LINE(PPC_POWER6_EXT, power6ext, "power6x", PPC_FEATURE_POWER6_EXT, 0) \ + LINE(PPC_ARCH_2_06, arch206, "arch_2_06", PPC_FEATURE_ARCH_2_06, 0) \ + LINE(PPC_HAS_VSX, vsx, "vsx", PPC_FEATURE_HAS_VSX, 0) \ + LINE(PPC_PSERIES_PERFMON_COMPAT, pseries_perfmon_compat, "archpmu", \ + PPC_FEATURE_PSERIES_PERFMON_COMPAT, 0) \ + LINE(PPC_TRUE_LE, truele, "true_le", PPC_FEATURE_TRUE_LE, 0) \ + LINE(PPC_PPC_LE, ppcle, "ppcle", PPC_FEATURE_PPC_LE, 0) \ + LINE(PPC_ARCH_2_07, arch207, "arch_2_07", 0, PPC_FEATURE2_ARCH_2_07) \ + LINE(PPC_HTM, htm, "htm", 0, PPC_FEATURE2_HTM) \ + LINE(PPC_DSCR, dscr, "dscr", 0, PPC_FEATURE2_DSCR) \ + LINE(PPC_EBB, ebb, "ebb", 0, PPC_FEATURE2_EBB) \ + LINE(PPC_ISEL, isel, "isel", 0, PPC_FEATURE2_ISEL) \ + LINE(PPC_TAR, tar, "tar", 0, PPC_FEATURE2_TAR) \ + LINE(PPC_VEC_CRYPTO, vcrypto, "vcrypto", 0, PPC_FEATURE2_VEC_CRYPTO) \ + LINE(PPC_HTM_NOSC, htm_nosc, "htm-nosc", 0, PPC_FEATURE2_HTM_NOSC) \ + LINE(PPC_ARCH_3_00, arch300, "arch_3_00", 0, PPC_FEATURE2_ARCH_3_00) \ + LINE(PPC_HAS_IEEE128, ieee128, "ieee128", 0, PPC_FEATURE2_HAS_IEEE128) \ + LINE(PPC_DARN, darn, "darn", 0, PPC_FEATURE2_DARN) \ + LINE(PPC_SCV, scv, "scv", 0, PPC_FEATURE2_SCV) \ + LINE(PPC_HTM_NO_SUSPEND, htm_no_suspend, "htm-no-suspend", 0, \ + PPC_FEATURE2_HTM_NO_SUSPEND) +#define INTROSPECTION_PREFIX PPC +#define INTROSPECTION_ENUM_PREFIX PPC +#include "define_introspection_and_hwcaps.inl" + +//////////////////////////////////////////////////////////////////////////////// +// Implementation. +//////////////////////////////////////////////////////////////////////////////// + +#include "internal/bit_utils.h" +#include "internal/filesystem.h" +#include "internal/hwcaps.h" +#include "internal/stack_line_reader.h" +#include "internal/string_view.h" +#include + +static bool HandlePPCLine(const LineResult result, + PPCPlatformStrings* const strings) +{ + StringView line = result.line; + StringView key, value; + if (CpuFeatures_StringView_GetAttributeKeyValue(line, &key, &value)) + { + if (CpuFeatures_StringView_HasWord(key, "platform", ' ')) + { + CpuFeatures_StringView_CopyString(value, strings->platform, + sizeof(strings->platform)); + } + else if (CpuFeatures_StringView_IsEquals(key, str("model"))) + { + CpuFeatures_StringView_CopyString(value, strings->model, + sizeof(strings->platform)); + } + else if (CpuFeatures_StringView_IsEquals(key, str("machine"))) + { + CpuFeatures_StringView_CopyString(value, strings->machine, + sizeof(strings->platform)); + } + else if (CpuFeatures_StringView_IsEquals(key, str("cpu"))) + { + CpuFeatures_StringView_CopyString(value, strings->cpu, + sizeof(strings->platform)); + } + } + return !result.eof; +} + +static void FillProcCpuInfoData(PPCPlatformStrings* const strings) +{ + const int fd = CpuFeatures_OpenFile("/proc/cpuinfo"); + if (fd >= 0) + { + StackLineReader reader; + StackLineReader_Initialize(&reader, fd); + for (;;) + { + if (!HandlePPCLine(StackLineReader_NextLine(&reader), strings)) + { + break; + } + } + CpuFeatures_CloseFile(fd); + } +} + +static const PPCInfo kEmptyPPCInfo; + +PPCInfo GetPPCInfo(void) +{ + /* + * On Power feature flags aren't currently in cpuinfo so we only look at + * the auxilary vector. + */ + PPCInfo info = kEmptyPPCInfo; + const HardwareCapabilities hwcaps = CpuFeatures_GetHardwareCapabilities(); + for (size_t i = 0; i < PPC_LAST_; ++i) + { + if (CpuFeatures_IsHwCapsSet(kHardwareCapabilities[i], hwcaps)) + { + kSetters[i](&info.features, true); + } + } + return info; +} + +static const PPCPlatformStrings kEmptyPPCPlatformStrings; + +PPCPlatformStrings GetPPCPlatformStrings(void) +{ + PPCPlatformStrings strings = kEmptyPPCPlatformStrings; + const char* platform = CpuFeatures_GetPlatformPointer(); + const char* base_platform = CpuFeatures_GetBasePlatformPointer(); + + FillProcCpuInfoData(&strings); + + if (platform != NULL) + CpuFeatures_StringView_CopyString(str(platform), strings.type.platform, + sizeof(strings.type.platform)); + if (base_platform != NULL) + CpuFeatures_StringView_CopyString(str(base_platform), + strings.type.base_platform, + sizeof(strings.type.base_platform)); + + return strings; +} + +#endif // CPU_FEATURES_OS_LINUX +#endif // CPU_FEATURES_ARCH_PPC diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/cpuinfo_x86.c b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_x86__base_implementation.inl similarity index 75% rename from src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/cpuinfo_x86.c rename to src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_x86__base_implementation.inl index 43270fac8..56e6a82d6 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/cpuinfo_x86.c +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_x86__base_implementation.inl @@ -1,9 +1,11 @@ -// SPDX-FileCopyrightText: 2017 Google LLC +// SPDX-FileCopyrightText: 2017 Google LLC, 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "cpuinfo_x86.h" #include "internal/bit_utils.h" #include "internal/cpuid_x86.h" +#include "copy.inl" +#include "equals.inl" #include #include @@ -11,94 +13,6 @@ #error "Cannot compile cpuinfo_x86 on a non x86 platform." #endif -// Generation of feature's getters/setters functions and kGetters, kSetters, -// kCpuInfoFlags global tables. -#define DEFINE_TABLE_FEATURES \ - FEATURE(X86_FPU, fpu, "fpu", 0, 0) \ - FEATURE(X86_TSC, tsc, "tsc", 0, 0) \ - FEATURE(X86_CX8, cx8, "cx8", 0, 0) \ - FEATURE(X86_CLFSH, clfsh, "clfsh", 0, 0) \ - FEATURE(X86_MMX, mmx, "mmx", 0, 0) \ - FEATURE(X86_AES, aes, "aes", 0, 0) \ - FEATURE(X86_ERMS, erms, "erms", 0, 0) \ - FEATURE(X86_F16C, f16c, "f16c", 0, 0) \ - FEATURE(X86_FMA4, fma4, "fma4", 0, 0) \ - FEATURE(X86_FMA3, fma3, "fma3", 0, 0) \ - FEATURE(X86_VAES, vaes, "vaes", 0, 0) \ - FEATURE(X86_VPCLMULQDQ, vpclmulqdq, "vpclmulqdq", 0, 0) \ - FEATURE(X86_BMI1, bmi1, "bmi1", 0, 0) \ - FEATURE(X86_HLE, hle, "hle", 0, 0) \ - FEATURE(X86_BMI2, bmi2, "bmi2", 0, 0) \ - FEATURE(X86_RTM, rtm, "rtm", 0, 0) \ - FEATURE(X86_RDSEED, rdseed, "rdseed", 0, 0) \ - FEATURE(X86_CLFLUSHOPT, clflushopt, "clflushopt", 0, 0) \ - FEATURE(X86_CLWB, clwb, "clwb", 0, 0) \ - FEATURE(X86_SSE, sse, "sse", 0, 0) \ - FEATURE(X86_SSE2, sse2, "sse2", 0, 0) \ - FEATURE(X86_SSE3, sse3, "sse3", 0, 0) \ - FEATURE(X86_SSSE3, ssse3, "ssse3", 0, 0) \ - FEATURE(X86_SSE4_1, sse4_1, "sse4_1", 0, 0) \ - FEATURE(X86_SSE4_2, sse4_2, "sse4_2", 0, 0) \ - FEATURE(X86_SSE4A, sse4a, "sse4a", 0, 0) \ - FEATURE(X86_AVX, avx, "avx", 0, 0) \ - FEATURE(X86_AVX2, avx2, "avx2", 0, 0) \ - FEATURE(X86_AVX512F, avx512f, "avx512f", 0, 0) \ - FEATURE(X86_AVX512CD, avx512cd, "avx512cd", 0, 0) \ - FEATURE(X86_AVX512ER, avx512er, "avx512er", 0, 0) \ - FEATURE(X86_AVX512PF, avx512pf, "avx512pf", 0, 0) \ - FEATURE(X86_AVX512BW, avx512bw, "avx512bw", 0, 0) \ - FEATURE(X86_AVX512DQ, avx512dq, "avx512dq", 0, 0) \ - FEATURE(X86_AVX512VL, avx512vl, "avx512vl", 0, 0) \ - FEATURE(X86_AVX512IFMA, avx512ifma, "avx512ifma", 0, 0) \ - FEATURE(X86_AVX512VBMI, avx512vbmi, "avx512vbmi", 0, 0) \ - FEATURE(X86_AVX512VBMI2, avx512vbmi2, "avx512vbmi2", 0, 0) \ - FEATURE(X86_AVX512VNNI, avx512vnni, "avx512vnni", 0, 0) \ - FEATURE(X86_AVX512BITALG, avx512bitalg, "avx512bitalg", 0, 0) \ - FEATURE(X86_AVX512VPOPCNTDQ, avx512vpopcntdq, "avx512vpopcntdq", 0, 0) \ - FEATURE(X86_AVX512_4VNNIW, avx512_4vnniw, "avx512_4vnniw", 0, 0) \ - FEATURE(X86_AVX512_4VBMI2, avx512_4vbmi2, "avx512_4vbmi2", 0, 0) \ - FEATURE(X86_AVX512_SECOND_FMA, avx512_second_fma, "avx512_second_fma", 0, 0) \ - FEATURE(X86_AVX512_4FMAPS, avx512_4fmaps, "avx512_4fmaps", 0, 0) \ - FEATURE(X86_AVX512_BF16, avx512_bf16, "avx512_bf16", 0, 0) \ - FEATURE(X86_AVX512_VP2INTERSECT, avx512_vp2intersect, "avx512_vp2intersect", \ - 0, 0) \ - FEATURE(X86_AMX_BF16, amx_bf16, "amx_bf16", 0, 0) \ - FEATURE(X86_AMX_TILE, amx_tile, "amx_tile", 0, 0) \ - FEATURE(X86_AMX_INT8, amx_int8, "amx_int8", 0, 0) \ - FEATURE(X86_PCLMULQDQ, pclmulqdq, "pclmulqdq", 0, 0) \ - FEATURE(X86_SMX, smx, "smx", 0, 0) \ - FEATURE(X86_SGX, sgx, "sgx", 0, 0) \ - FEATURE(X86_CX16, cx16, "cx16", 0, 0) \ - FEATURE(X86_SHA, sha, "sha", 0, 0) \ - FEATURE(X86_POPCNT, popcnt, "popcnt", 0, 0) \ - FEATURE(X86_MOVBE, movbe, "movbe", 0, 0) \ - FEATURE(X86_RDRND, rdrnd, "rdrnd", 0, 0) \ - FEATURE(X86_DCA, dca, "dca", 0, 0) \ - FEATURE(X86_SS, ss, "ss", 0, 0) \ - FEATURE(X86_ADX, adx, "adx", 0, 0) -#define DEFINE_TABLE_FEATURE_TYPE X86Features -#define DEFINE_TABLE_DONT_GENERATE_HWCAPS -#include "define_tables.h" - -// The following includes are necessary to provide SSE detections on pre-AVX -// microarchitectures. -#if defined(CPU_FEATURES_OS_WINDOWS) -#include // IsProcessorFeaturePresent -#elif defined(CPU_FEATURES_OS_LINUX_OR_ANDROID) || \ - defined(CPU_FEATURES_OS_FREEBSD) -#include "internal/filesystem.h" // Needed to parse /proc/cpuinfo -#include "internal/stack_line_reader.h" // Needed to parse /proc/cpuinfo -#elif defined(CPU_FEATURES_OS_DARWIN) -#if !defined(HAVE_SYSCTLBYNAME) -#error "Darwin needs support for sysctlbyname" -#endif -#include -#else -#error "Unsupported OS" -#endif // CPU_FEATURES_OS - -#include "internal/string_view.h" - //////////////////////////////////////////////////////////////////////////////// // Definitions for CpuId and GetXCR0Eax. //////////////////////////////////////////////////////////////////////////////// @@ -120,8 +34,8 @@ uint32_t GetXCR0Eax(void) { uint32_t eax, edx; /* named form of xgetbv not supported on OSX, so must use byte form, see: - https://github.com/asmjit/asmjit/issues/78 - */ + https://github.com/asmjit/asmjit/issues/78 + */ __asm(".byte 0x0F, 0x01, 0xd0" : "=a"(eax), "=d"(edx) : "c"(0)); @@ -151,11 +65,6 @@ uint32_t GetXCR0Eax(void) { return (uint32_t)_xgetbv(0); } #error "Unsupported compiler, x86 cpuid requires either GCC, Clang or MSVC." #endif -static Leaf CpuId(uint32_t leaf_id) -{ - return GetCpuidLeaf(leaf_id, 0); -} - static const Leaf kEmptyLeaf; static Leaf SafeCpuIdEx(uint32_t max_cpuid_leaf, uint32_t leaf_id, int ecx) @@ -170,11 +79,49 @@ static Leaf SafeCpuIdEx(uint32_t max_cpuid_leaf, uint32_t leaf_id, int ecx) } } -static Leaf SafeCpuId(uint32_t max_cpuid_leaf, uint32_t leaf_id) +typedef struct { - return SafeCpuIdEx(max_cpuid_leaf, leaf_id, 0); + uint32_t max_cpuid_leaf; + Leaf leaf_0; // Root + Leaf leaf_1; // Family, Model, Stepping + Leaf leaf_2; // Intel cache info + features + Leaf leaf_7; // Features + Leaf leaf_7_1; // Features + uint32_t max_cpuid_leaf_ext; + Leaf leaf_80000000; // Root for extended leaves + Leaf leaf_80000001; // AMD features features and cache + Leaf leaf_80000002; // brand string + Leaf leaf_80000003; // brand string + Leaf leaf_80000004; // brand string +} Leaves; + +static Leaves ReadLeaves(void) +{ + const Leaf leaf_0 = GetCpuidLeaf(0, 0); + const uint32_t max_cpuid_leaf = leaf_0.eax; + const Leaf leaf_80000000 = GetCpuidLeaf(0x80000000, 0); + const uint32_t max_cpuid_leaf_ext = leaf_80000000.eax; + return (Leaves){ + .max_cpuid_leaf = max_cpuid_leaf, + .leaf_0 = leaf_0, + .leaf_1 = SafeCpuIdEx(max_cpuid_leaf, 0x00000001, 0), + .leaf_2 = SafeCpuIdEx(max_cpuid_leaf, 0x00000002, 0), + .leaf_7 = SafeCpuIdEx(max_cpuid_leaf, 0x00000007, 0), + .leaf_7_1 = SafeCpuIdEx(max_cpuid_leaf, 0x00000007, 1), + .max_cpuid_leaf_ext = max_cpuid_leaf_ext, + .leaf_80000000 = leaf_80000000, + .leaf_80000001 = SafeCpuIdEx(max_cpuid_leaf_ext, 0x80000001, 0), + .leaf_80000002 = SafeCpuIdEx(max_cpuid_leaf_ext, 0x80000002, 0), + .leaf_80000003 = SafeCpuIdEx(max_cpuid_leaf_ext, 0x80000003, 0), + .leaf_80000004 = SafeCpuIdEx(max_cpuid_leaf_ext, 0x80000004, 0), + }; } +//////////////////////////////////////////////////////////////////////////////// +// OS support +// TODO: Add documentation +//////////////////////////////////////////////////////////////////////////////// + #define MASK_XMM 0x2 #define MASK_YMM 0x4 #define MASK_MASKREG 0x20 @@ -202,7 +149,6 @@ static bool HasYmmOsXSave(uint32_t xcr0_eax) return HasMask(xcr0_eax, MASK_XMM | MASK_YMM); } -#if !defined(CPU_FEATURES_OS_DARWIN) // Checks that operating system saves and restores zmm registers during context // switches. static bool HasZmmOsXSave(uint32_t xcr0_eax) @@ -210,7 +156,6 @@ static bool HasZmmOsXSave(uint32_t xcr0_eax) return HasMask(xcr0_eax, MASK_XMM | MASK_YMM | MASK_MASKREG | MASK_ZMM0_15 | MASK_ZMM16_31); } -#endif // Checks that operating system saves and restores AMX/TMUL state during context // switches. @@ -220,37 +165,9 @@ static bool HasTmmOsXSave(uint32_t xcr0_eax) MASK_ZMM16_31 | MASK_XTILECFG | MASK_XTILEDATA); } -static bool HasSecondFMA(uint32_t model) -{ - // Skylake server - if (model == 0x55) - { - char proc_name[49] = {0}; - FillX86BrandString(proc_name); - // detect Xeon - if (proc_name[9] == 'X') - { - // detect Silver or Bronze - if (proc_name[17] == 'S' || proc_name[17] == 'B') return false; - // detect Gold 5_20 and below, except for Gold 53__ - if (proc_name[17] == 'G' && proc_name[22] == '5') - return ((proc_name[23] == '3') || - (proc_name[24] == '2' && proc_name[25] == '2')); - // detect Xeon W 210x - if (proc_name[17] == 'W' && proc_name[21] == '0') return false; - // detect Xeon D 2xxx - if (proc_name[17] == 'D' && proc_name[19] == '2' && proc_name[20] == '1') - return false; - } - return true; - } - // Cannon Lake client - if (model == 0x66) return false; - // Ice Lake client - if (model == 0x7d || model == 0x7e) return false; - // This is the right default... - return true; -} +//////////////////////////////////////////////////////////////////////////////// +// Vendor +//////////////////////////////////////////////////////////////////////////////// static void SetVendor(const Leaf leaf, char* const vendor) { @@ -270,9 +187,589 @@ static int IsVendor(const Leaf leaf, const char* const name) static int IsVendorByX86Info(const X86Info* info, const char* const name) { - return memcmp(info->vendor, name, sizeof(info->vendor)) == 0; + return equals(info->vendor, name, sizeof(info->vendor)); } +// TODO: Remove when deprecation period is over, +void FillX86BrandString(char brand_string[49]) +{ + const Leaves leaves = ReadLeaves(); + const Leaf packed[3] = { + leaves.leaf_80000002, + leaves.leaf_80000003, + leaves.leaf_80000004, + }; +#if __STDC_VERSION__ >= 201112L + _Static_assert(sizeof(packed) == 48, "Leaves must be packed"); +#endif + copy(brand_string, (const char*)(packed), 48); + brand_string[48] = '\0'; +} + +//////////////////////////////////////////////////////////////////////////////// +// CpuId +//////////////////////////////////////////////////////////////////////////////// + +static bool HasSecondFMA(const X86Info* info) +{ + // Skylake server + if (info->model == 0x55) + { + // detect Xeon + if (info->brand_string[9] == 'X') + { + // detect Silver or Bronze + if (info->brand_string[17] == 'S' || info->brand_string[17] == 'B') + return false; + // detect Gold 5_20 and below, except for Gold 53__ + if (info->brand_string[17] == 'G' && info->brand_string[22] == '5') + return ( + (info->brand_string[23] == '3') || + (info->brand_string[24] == '2' && info->brand_string[25] == '2')); + // detect Xeon W 210x + if (info->brand_string[17] == 'W' && info->brand_string[21] == '0') + return false; + // detect Xeon D 2xxx + if (info->brand_string[17] == 'D' && info->brand_string[19] == '2' && + info->brand_string[20] == '1') + return false; + } + return true; + } + // Cannon Lake client + if (info->model == 0x66) return false; + // Ice Lake client + if (info->model == 0x7d || info->model == 0x7e) return false; + // This is the right default... + return true; +} + +// Internal structure to hold the OS support for vector operations. +// Avoid to recompute them since each call to cpuid is ~100 cycles. +typedef struct +{ + bool sse_registers; + bool avx_registers; + bool avx512_registers; + bool amx_registers; +} OsPreserves; + +// These two functions have to be implemented by the OS, that is the file +// including this file. +static void OverrideOsPreserves(OsPreserves* os_preserves); +static void DetectFeaturesFromOs(X86Info* info, X86Features* features); + +// Reference https://en.wikipedia.org/wiki/CPUID. +static void ParseCpuId(const Leaves* leaves, X86Info* info, + OsPreserves* os_preserves) +{ + const Leaf leaf_1 = leaves->leaf_1; + const Leaf leaf_7 = leaves->leaf_7; + const Leaf leaf_7_1 = leaves->leaf_7_1; + + const bool have_xsave = IsBitSet(leaf_1.ecx, 26); + const bool have_osxsave = IsBitSet(leaf_1.ecx, 27); + const bool have_xcr0 = have_xsave && have_osxsave; + + const uint32_t family = ExtractBitRange(leaf_1.eax, 11, 8); + const uint32_t extended_family = ExtractBitRange(leaf_1.eax, 27, 20); + const uint32_t model = ExtractBitRange(leaf_1.eax, 7, 4); + const uint32_t extended_model = ExtractBitRange(leaf_1.eax, 19, 16); + + X86Features* const features = &info->features; + + // Fill Family, Model and Stepping. + info->family = extended_family + family; + info->model = (extended_model << 4) + model; + info->stepping = ExtractBitRange(leaf_1.eax, 3, 0); + + // Fill Brand String. + const Leaf packed[3] = { + leaves->leaf_80000002, + leaves->leaf_80000003, + leaves->leaf_80000004, + }; +#if __STDC_VERSION__ >= 201112L + _Static_assert(sizeof(packed) == 48, "Leaves must be packed"); +#endif + copy(info->brand_string, (const char*)(packed), 48); + info->brand_string[48] = '\0'; + + // Fill cpu features. + features->fpu = IsBitSet(leaf_1.edx, 0); + features->tsc = IsBitSet(leaf_1.edx, 4); + features->cx8 = IsBitSet(leaf_1.edx, 8); + features->clfsh = IsBitSet(leaf_1.edx, 19); + features->mmx = IsBitSet(leaf_1.edx, 23); + features->ss = IsBitSet(leaf_1.edx, 27); + features->pclmulqdq = IsBitSet(leaf_1.ecx, 1); + features->smx = IsBitSet(leaf_1.ecx, 6); + features->cx16 = IsBitSet(leaf_1.ecx, 13); + features->dca = IsBitSet(leaf_1.ecx, 18); + features->movbe = IsBitSet(leaf_1.ecx, 22); + features->popcnt = IsBitSet(leaf_1.ecx, 23); + features->aes = IsBitSet(leaf_1.ecx, 25); + features->f16c = IsBitSet(leaf_1.ecx, 29); + features->rdrnd = IsBitSet(leaf_1.ecx, 30); + features->sgx = IsBitSet(leaf_7.ebx, 2); + features->bmi1 = IsBitSet(leaf_7.ebx, 3); + features->hle = IsBitSet(leaf_7.ebx, 4); + features->bmi2 = IsBitSet(leaf_7.ebx, 8); + features->erms = IsBitSet(leaf_7.ebx, 9); + features->rtm = IsBitSet(leaf_7.ebx, 11); + features->rdseed = IsBitSet(leaf_7.ebx, 18); + features->clflushopt = IsBitSet(leaf_7.ebx, 23); + features->clwb = IsBitSet(leaf_7.ebx, 24); + features->sha = IsBitSet(leaf_7.ebx, 29); + features->vaes = IsBitSet(leaf_7.ecx, 9); + features->vpclmulqdq = IsBitSet(leaf_7.ecx, 10); + features->adx = IsBitSet(leaf_7.ebx, 19); + + ///////////////////////////////////////////////////////////////////////////// + // The following section is devoted to Vector Extensions. + ///////////////////////////////////////////////////////////////////////////// + + // CPU with AVX expose XCR0 which enables checking vector extensions OS + // support through cpuid. + if (have_xcr0) + { + // Here we rely exclusively on cpuid for both CPU and OS support of vector + // extensions. + const uint32_t xcr0_eax = GetXCR0Eax(); + os_preserves->sse_registers = HasXmmOsXSave(xcr0_eax); + os_preserves->avx_registers = HasYmmOsXSave(xcr0_eax); + os_preserves->avx512_registers = HasZmmOsXSave(xcr0_eax); + os_preserves->amx_registers = HasTmmOsXSave(xcr0_eax); + OverrideOsPreserves(os_preserves); + + if (os_preserves->sse_registers) + { + features->sse = IsBitSet(leaf_1.edx, 25); + features->sse2 = IsBitSet(leaf_1.edx, 26); + features->sse3 = IsBitSet(leaf_1.ecx, 0); + features->ssse3 = IsBitSet(leaf_1.ecx, 9); + features->sse4_1 = IsBitSet(leaf_1.ecx, 19); + features->sse4_2 = IsBitSet(leaf_1.ecx, 20); + } + if (os_preserves->avx_registers) + { + features->fma3 = IsBitSet(leaf_1.ecx, 12); + features->avx = IsBitSet(leaf_1.ecx, 28); + features->avx2 = IsBitSet(leaf_7.ebx, 5); + } + if (os_preserves->avx512_registers) + { + features->avx512f = IsBitSet(leaf_7.ebx, 16); + features->avx512cd = IsBitSet(leaf_7.ebx, 28); + features->avx512er = IsBitSet(leaf_7.ebx, 27); + features->avx512pf = IsBitSet(leaf_7.ebx, 26); + features->avx512bw = IsBitSet(leaf_7.ebx, 30); + features->avx512dq = IsBitSet(leaf_7.ebx, 17); + features->avx512vl = IsBitSet(leaf_7.ebx, 31); + features->avx512ifma = IsBitSet(leaf_7.ebx, 21); + features->avx512vbmi = IsBitSet(leaf_7.ecx, 1); + features->avx512vbmi2 = IsBitSet(leaf_7.ecx, 6); + features->avx512vnni = IsBitSet(leaf_7.ecx, 11); + features->avx512bitalg = IsBitSet(leaf_7.ecx, 12); + features->avx512vpopcntdq = IsBitSet(leaf_7.ecx, 14); + features->avx512_4vnniw = IsBitSet(leaf_7.edx, 2); + features->avx512_4vbmi2 = IsBitSet(leaf_7.edx, 3); + features->avx512_second_fma = HasSecondFMA(info); + features->avx512_4fmaps = IsBitSet(leaf_7.edx, 3); + features->avx512_bf16 = IsBitSet(leaf_7_1.eax, 5); + features->avx512_vp2intersect = IsBitSet(leaf_7.edx, 8); + } + if (os_preserves->amx_registers) + { + features->amx_bf16 = IsBitSet(leaf_7.edx, 22); + features->amx_tile = IsBitSet(leaf_7.edx, 24); + features->amx_int8 = IsBitSet(leaf_7.edx, 25); + } + } + else + { + // When XCR0 is not available (Atom based or older cpus) we need to defer to + // the OS via custom code. + DetectFeaturesFromOs(info, features); + // Now that we have queried the OS for SSE support, we report this back to + // os_preserves. This is needed in case of AMD CPU's to enable testing of + // sse4a (See ParseExtraAMDCpuId below). + if (features->sse) os_preserves->sse_registers = true; + } +} + +static void ParseExtraAMDCpuId(const Leaves* leaves, X86Info* info, + OsPreserves os_preserves) +{ + const Leaf leaf_80000001 = leaves->leaf_80000001; + + X86Features* const features = &info->features; + + if (os_preserves.sse_registers) + { + features->sse4a = IsBitSet(leaf_80000001.ecx, 6); + } + + if (os_preserves.avx_registers) + { + features->fma4 = IsBitSet(leaf_80000001.ecx, 16); + } +} + +static const X86Info kEmptyX86Info; +static const OsPreserves kEmptyOsPreserves; + +X86Info GetX86Info(void) +{ + X86Info info = kEmptyX86Info; + const Leaves leaves = ReadLeaves(); + const bool is_intel = + IsVendor(leaves.leaf_0, CPU_FEATURES_VENDOR_GENUINE_INTEL); + const bool is_amd = + IsVendor(leaves.leaf_0, CPU_FEATURES_VENDOR_AUTHENTIC_AMD); + const bool is_hygon = + IsVendor(leaves.leaf_0, CPU_FEATURES_VENDOR_HYGON_GENUINE); + const bool is_zhaoxin = + (IsVendor(leaves.leaf_0, CPU_FEATURES_VENDOR_CENTAUR_HAULS) || + IsVendor(leaves.leaf_0, CPU_FEATURES_VENDOR_SHANGHAI)); + SetVendor(leaves.leaf_0, info.vendor); + if (is_intel || is_amd || is_hygon || is_zhaoxin) + { + OsPreserves os_preserves = kEmptyOsPreserves; + ParseCpuId(&leaves, &info, &os_preserves); + if (is_amd || is_hygon) + { + ParseExtraAMDCpuId(&leaves, &info, os_preserves); + } + } + return info; +} + +//////////////////////////////////////////////////////////////////////////////// +// Microarchitecture +//////////////////////////////////////////////////////////////////////////////// + +#define CPUID(FAMILY, MODEL) ((((FAMILY)&0xFF) << 8) | ((MODEL)&0xFF)) + +X86Microarchitecture GetX86Microarchitecture(const X86Info* info) +{ + if (IsVendorByX86Info(info, CPU_FEATURES_VENDOR_GENUINE_INTEL)) + { + switch (CPUID(info->family, info->model)) + { + case CPUID(0x04, 0x01): + case CPUID(0x04, 0x02): + case CPUID(0x04, 0x03): + case CPUID(0x04, 0x04): + case CPUID(0x04, 0x05): + case CPUID(0x04, 0x07): + case CPUID(0x04, 0x08): + case CPUID(0x04, 0x09): + // https://en.wikichip.org/wiki/intel/microarchitectures/80486 + return INTEL_80486; + case CPUID(0x05, 0x01): + case CPUID(0x05, 0x02): + case CPUID(0x05, 0x04): + case CPUID(0x05, 0x07): + case CPUID(0x05, 0x08): + // https://en.wikichip.org/wiki/intel/microarchitectures/p5 + return INTEL_P5; + case CPUID(0x05, 0x09): + case CPUID(0x05, 0x0A): + // https://en.wikichip.org/wiki/intel/quark + return INTEL_LAKEMONT; + case CPUID(0x06, 0x1C): // Intel(R) Atom(TM) CPU 230 @ 1.60GHz + case CPUID(0x06, 0x35): + case CPUID(0x06, 0x36): + case CPUID(0x06, 0x70): // https://en.wikichip.org/wiki/intel/atom/230 + // https://en.wikipedia.org/wiki/Bonnell_(microarchitecture) + return INTEL_ATOM_BNL; + case CPUID(0x06, 0x37): + case CPUID(0x06, 0x4C): + // https://en.wikipedia.org/wiki/Silvermont + return INTEL_ATOM_SMT; + case CPUID(0x06, 0x5C): + // https://en.wikipedia.org/wiki/Goldmont + return INTEL_ATOM_GMT; + case CPUID(0x06, 0x0F): + case CPUID(0x06, 0x16): + // https://en.wikipedia.org/wiki/Intel_Core_(microarchitecture) + return INTEL_CORE; + case CPUID(0x06, 0x17): + case CPUID(0x06, 0x1D): + // https://en.wikipedia.org/wiki/Penryn_(microarchitecture) + return INTEL_PNR; + case CPUID(0x06, 0x1A): + case CPUID(0x06, 0x1E): + case CPUID(0x06, 0x1F): + case CPUID(0x06, 0x2E): + // https://en.wikipedia.org/wiki/Nehalem_(microarchitecture) + return INTEL_NHM; + case CPUID(0x06, 0x25): + case CPUID(0x06, 0x2C): + case CPUID(0x06, 0x2F): + // https://en.wikipedia.org/wiki/Westmere_(microarchitecture) + return INTEL_WSM; + case CPUID(0x06, 0x2A): + case CPUID(0x06, 0x2D): + // https://en.wikipedia.org/wiki/Sandy_Bridge#Models_and_steppings + return INTEL_SNB; + case CPUID(0x06, 0x3A): + case CPUID(0x06, 0x3E): + // https://en.wikipedia.org/wiki/Ivy_Bridge_(microarchitecture)#Models_and_steppings + return INTEL_IVB; + case CPUID(0x06, 0x3C): + case CPUID(0x06, 0x3F): + case CPUID(0x06, 0x45): + case CPUID(0x06, 0x46): + // https://en.wikipedia.org/wiki/Haswell_(microarchitecture) + return INTEL_HSW; + case CPUID(0x06, 0x3D): + case CPUID(0x06, 0x47): + case CPUID(0x06, 0x4F): + case CPUID(0x06, 0x56): + // https://en.wikipedia.org/wiki/Broadwell_(microarchitecture) + return INTEL_BDW; + case CPUID(0x06, 0x4E): + case CPUID(0x06, 0x55): + case CPUID(0x06, 0x5E): + // https://en.wikipedia.org/wiki/Skylake_(microarchitecture) + return INTEL_SKL; + case CPUID(0x06, 0x66): + // https://en.wikipedia.org/wiki/Cannon_Lake_(microarchitecture) + return INTEL_CNL; + case CPUID(0x06, 0x7D): // client + case CPUID(0x06, 0x7E): // client + case CPUID(0x06, 0x9D): // NNP-I + case CPUID(0x06, 0x6A): // server + case CPUID(0x06, 0x6C): // server + // https://en.wikipedia.org/wiki/Ice_Lake_(microprocessor) + return INTEL_ICL; + case CPUID(0x06, 0x8C): + case CPUID(0x06, 0x8D): + // https://en.wikipedia.org/wiki/Tiger_Lake_(microarchitecture) + return INTEL_TGL; + case CPUID(0x06, 0x8F): + // https://en.wikipedia.org/wiki/Sapphire_Rapids + return INTEL_SPR; + case CPUID(0x06, 0x8E): + switch (info->stepping) + { + case 9: + return INTEL_KBL; // https://en.wikipedia.org/wiki/Kaby_Lake + case 10: + return INTEL_CFL; // https://en.wikipedia.org/wiki/Coffee_Lake + case 11: + return INTEL_WHL; // https://en.wikipedia.org/wiki/Whiskey_Lake_(microarchitecture) + default: + return X86_UNKNOWN; + } + case CPUID(0x06, 0x9E): + if (info->stepping > 9) + { + // https://en.wikipedia.org/wiki/Coffee_Lake + return INTEL_CFL; + } + else + { + // https://en.wikipedia.org/wiki/Kaby_Lake + return INTEL_KBL; + } + case CPUID(0x06, 0x97): + case CPUID(0x06, 0x9A): + // https://en.wikichip.org/wiki/intel/microarchitectures/alder_lake + return INTEL_ADL; + case CPUID(0x06, 0xA7): + // https://en.wikichip.org/wiki/intel/microarchitectures/rocket_lake + return INTEL_RCL; + case CPUID(0x06, 0x85): + // https://en.wikichip.org/wiki/intel/microarchitectures/knights_mill + return INTEL_KNIGHTS_M; + case CPUID(0x06, 0x57): + // https://en.wikichip.org/wiki/intel/microarchitectures/knights_landing + return INTEL_KNIGHTS_L; + case CPUID(0x0B, 0x00): + // https://en.wikichip.org/wiki/intel/microarchitectures/knights_ferry + return INTEL_KNIGHTS_F; + case CPUID(0x0B, 0x01): + // https://en.wikichip.org/wiki/intel/microarchitectures/knights_corner + return INTEL_KNIGHTS_C; + case CPUID(0x0F, 0x01): + case CPUID(0x0F, 0x02): + case CPUID(0x0F, 0x03): + case CPUID(0x0F, 0x04): + case CPUID(0x0F, 0x06): + // https://en.wikichip.org/wiki/intel/microarchitectures/netburst + return INTEL_NETBURST; + default: + return X86_UNKNOWN; + } + } + if (IsVendorByX86Info(info, CPU_FEATURES_VENDOR_CENTAUR_HAULS)) + { + switch (CPUID(info->family, info->model)) + { + case CPUID(0x06, 0x0F): + case CPUID(0x06, 0x19): + // https://en.wikichip.org/wiki/zhaoxin/microarchitectures/zhangjiang + return ZHAOXIN_ZHANGJIANG; + case CPUID(0x07, 0x1B): + // https://en.wikichip.org/wiki/zhaoxin/microarchitectures/wudaokou + return ZHAOXIN_WUDAOKOU; + case CPUID(0x07, 0x3B): + // https://en.wikichip.org/wiki/zhaoxin/microarchitectures/lujiazui + return ZHAOXIN_LUJIAZUI; + case CPUID(0x07, 0x5B): + return ZHAOXIN_YONGFENG; + default: + return X86_UNKNOWN; + } + } + if (IsVendorByX86Info(info, CPU_FEATURES_VENDOR_SHANGHAI)) + { + switch (CPUID(info->family, info->model)) + { + case CPUID(0x06, 0x0F): + case CPUID(0x06, 0x19): + // https://en.wikichip.org/wiki/zhaoxin/microarchitectures/zhangjiang + return ZHAOXIN_ZHANGJIANG; + case CPUID(0x07, 0x1B): + // https://en.wikichip.org/wiki/zhaoxin/microarchitectures/wudaokou + return ZHAOXIN_WUDAOKOU; + case CPUID(0x07, 0x3B): + // https://en.wikichip.org/wiki/zhaoxin/microarchitectures/lujiazui + return ZHAOXIN_LUJIAZUI; + case CPUID(0x07, 0x5B): + return ZHAOXIN_YONGFENG; + default: + return X86_UNKNOWN; + } + } + if (IsVendorByX86Info(info, CPU_FEATURES_VENDOR_AUTHENTIC_AMD)) + { + switch (CPUID(info->family, info->model)) + { + // https://en.wikichip.org/wiki/amd/cpuid + case CPUID(0xF, 0x04): + case CPUID(0xF, 0x05): + case CPUID(0xF, 0x07): + case CPUID(0xF, 0x08): + case CPUID(0xF, 0x0C): + case CPUID(0xF, 0x0E): + case CPUID(0xF, 0x0F): + case CPUID(0xF, 0x14): + case CPUID(0xF, 0x15): + case CPUID(0xF, 0x17): + case CPUID(0xF, 0x18): + case CPUID(0xF, 0x1B): + case CPUID(0xF, 0x1C): + case CPUID(0xF, 0x1F): + case CPUID(0xF, 0x21): + case CPUID(0xF, 0x23): + case CPUID(0xF, 0x24): + case CPUID(0xF, 0x25): + case CPUID(0xF, 0x27): + case CPUID(0xF, 0x2B): + case CPUID(0xF, 0x2C): + case CPUID(0xF, 0x2F): + case CPUID(0xF, 0x41): + case CPUID(0xF, 0x43): + case CPUID(0xF, 0x48): + case CPUID(0xF, 0x4B): + case CPUID(0xF, 0x4C): + case CPUID(0xF, 0x4F): + case CPUID(0xF, 0x5D): + case CPUID(0xF, 0x5F): + case CPUID(0xF, 0x68): + case CPUID(0xF, 0x6B): + case CPUID(0xF, 0x6F): + case CPUID(0xF, 0x7F): + case CPUID(0xF, 0xC1): + return AMD_HAMMER; + case CPUID(0x10, 0x02): + case CPUID(0x10, 0x04): + case CPUID(0x10, 0x05): + case CPUID(0x10, 0x06): + case CPUID(0x10, 0x08): + case CPUID(0x10, 0x09): + case CPUID(0x10, 0x0A): + return AMD_K10; + case CPUID(0x11, 0x03): + // http://developer.amd.com/wordpress/media/2012/10/41788.pdf + return AMD_K11; + case CPUID(0x12, 0x01): + // https://www.amd.com/system/files/TechDocs/44739_12h_Rev_Gd.pdf + return AMD_K12; + case CPUID(0x14, 0x00): + case CPUID(0x14, 0x01): + case CPUID(0x14, 0x02): + // https://www.amd.com/system/files/TechDocs/47534_14h_Mod_00h-0Fh_Rev_Guide.pdf + return AMD_BOBCAT; + case CPUID(0x15, 0x01): + // https://en.wikichip.org/wiki/amd/microarchitectures/bulldozer + return AMD_BULLDOZER; + case CPUID(0x15, 0x02): + case CPUID(0x15, 0x11): + case CPUID(0x15, 0x13): + // https://en.wikichip.org/wiki/amd/microarchitectures/piledriver + return AMD_PILEDRIVER; + case CPUID(0x15, 0x30): + case CPUID(0x15, 0x38): + // https://en.wikichip.org/wiki/amd/microarchitectures/steamroller + return AMD_STREAMROLLER; + case CPUID(0x15, 0x60): + case CPUID(0x15, 0x65): + case CPUID(0x15, 0x70): + // https://en.wikichip.org/wiki/amd/microarchitectures/excavator + return AMD_EXCAVATOR; + case CPUID(0x16, 0x00): + return AMD_JAGUAR; + case CPUID(0x16, 0x30): + return AMD_PUMA; + case CPUID(0x17, 0x01): + case CPUID(0x17, 0x11): + case CPUID(0x17, 0x18): + case CPUID(0x17, 0x20): + // https://en.wikichip.org/wiki/amd/microarchitectures/zen + return AMD_ZEN; + case CPUID(0x17, 0x08): + // https://en.wikichip.org/wiki/amd/microarchitectures/zen%2B + return AMD_ZEN_PLUS; + case CPUID(0x17, 0x31): + case CPUID(0x17, 0x47): + case CPUID(0x17, 0x60): + case CPUID(0x17, 0x68): + case CPUID(0x17, 0x71): + case CPUID(0x17, 0x90): + case CPUID(0x17, 0x98): + // https://en.wikichip.org/wiki/amd/microarchitectures/zen_2 + return AMD_ZEN2; + case CPUID(0x19, 0x01): + case CPUID(0x19, 0x21): + case CPUID(0x19, 0x30): + case CPUID(0x19, 0x40): + case CPUID(0x19, 0x50): + // https://en.wikichip.org/wiki/amd/microarchitectures/zen_3 + return AMD_ZEN3; + default: + return X86_UNKNOWN; + } + } + if (IsVendorByX86Info(info, CPU_FEATURES_VENDOR_HYGON_GENUINE)) + { + switch (CPUID(info->family, info->model)) + { + case CPUID(0x18, 0x00): + return AMD_ZEN; + } + } + return X86_UNKNOWN; +} + +//////////////////////////////////////////////////////////////////////////////// +// CacheInfo +//////////////////////////////////////////////////////////////////////////////// + static const CacheLevelInfo kEmptyCacheLevelInfo; static CacheLevelInfo GetCacheLevelInfo(const uint32_t reg) @@ -1136,9 +1633,9 @@ static CacheLevelInfo GetCacheLevelInfo(const uint32_t reg) } // From https://www.felixcloutier.com/x86/cpuid#tbl-3-12 -static void ParseLeaf2(const int max_cpuid_leaf, CacheInfo* info) +static void ParseLeaf2(const Leaves* leaves, CacheInfo* info) { - Leaf leaf = SafeCpuId(max_cpuid_leaf, 2); + Leaf leaf = leaves->leaf_2; // The least-significant byte in register EAX (register AL) will always return // 01H. Software should ignore this value and not interpret it as an // informational descriptor. @@ -1154,7 +1651,7 @@ static void ParseLeaf2(const int max_cpuid_leaf, CacheInfo* info) #if __STDC_VERSION__ >= 201112L _Static_assert(sizeof(Leaf) == sizeof(data), "Leaf must be 16 bytes"); #endif - memcpy(&data, &leaf, sizeof(data)); + copy((char*)(data), (const char*)(&leaf), sizeof(data)); for (size_t i = 0; i < sizeof(data); ++i) { const uint8_t descriptor = data[i]; @@ -1208,666 +1705,156 @@ static void ParseCacheInfo(const int max_cpuid_leaf, uint32_t leaf_id, if (info.size > 0) *old_info = info; } -#if defined(CPU_FEATURES_OS_DARWIN) -#if defined(CPU_FEATURES_MOCK_CPUID_X86) -extern bool GetDarwinSysCtlByName(const char*); -#else // CPU_FEATURES_MOCK_CPUID_X86 -static bool GetDarwinSysCtlByName(const char* name) -{ - int enabled; - size_t enabled_len = sizeof(enabled); - const int failure = sysctlbyname(name, &enabled, &enabled_len, NULL, 0); - return failure ? false : enabled; -} -#endif -#endif // CPU_FEATURES_OS_DARWIN - -// Internal structure to hold the OS support for vector operations. -// Avoid to recompute them since each call to cpuid is ~100 cycles. -typedef struct -{ - bool sse_registers; - bool avx_registers; - bool avx512_registers; - bool amx_registers; -} OsPreserves; - -#if defined(CPU_FEATURES_OS_WINDOWS) -#if defined(CPU_FEATURES_MOCK_CPUID_X86) -extern bool GetWindowsIsProcessorFeaturePresent(DWORD); -#else // CPU_FEATURES_MOCK_CPUID_X86 -static bool GetWindowsIsProcessorFeaturePresent(DWORD ProcessorFeature) -{ - return IsProcessorFeaturePresent(ProcessorFeature); -} -#endif -#endif // CPU_FEATURES_OS_WINDOWS - -// Reference https://en.wikipedia.org/wiki/CPUID. -static void ParseCpuId(const uint32_t max_cpuid_leaf, X86Info* info, - OsPreserves* os_preserves) -{ - const Leaf leaf_1 = SafeCpuId(max_cpuid_leaf, 1); - const Leaf leaf_7 = SafeCpuId(max_cpuid_leaf, 7); - const Leaf leaf_7_1 = SafeCpuIdEx(max_cpuid_leaf, 7, 1); - - const bool have_xsave = IsBitSet(leaf_1.ecx, 26); - const bool have_osxsave = IsBitSet(leaf_1.ecx, 27); - const bool have_xcr0 = have_xsave && have_osxsave; - - const uint32_t family = ExtractBitRange(leaf_1.eax, 11, 8); - const uint32_t extended_family = ExtractBitRange(leaf_1.eax, 27, 20); - const uint32_t model = ExtractBitRange(leaf_1.eax, 7, 4); - const uint32_t extended_model = ExtractBitRange(leaf_1.eax, 19, 16); - - X86Features* const features = &info->features; - - info->family = extended_family + family; - info->model = (extended_model << 4) + model; - info->stepping = ExtractBitRange(leaf_1.eax, 3, 0); - - features->fpu = IsBitSet(leaf_1.edx, 0); - features->tsc = IsBitSet(leaf_1.edx, 4); - features->cx8 = IsBitSet(leaf_1.edx, 8); - features->clfsh = IsBitSet(leaf_1.edx, 19); - features->mmx = IsBitSet(leaf_1.edx, 23); - features->ss = IsBitSet(leaf_1.edx, 27); - features->pclmulqdq = IsBitSet(leaf_1.ecx, 1); - features->smx = IsBitSet(leaf_1.ecx, 6); - features->cx16 = IsBitSet(leaf_1.ecx, 13); - features->dca = IsBitSet(leaf_1.ecx, 18); - features->movbe = IsBitSet(leaf_1.ecx, 22); - features->popcnt = IsBitSet(leaf_1.ecx, 23); - features->aes = IsBitSet(leaf_1.ecx, 25); - features->f16c = IsBitSet(leaf_1.ecx, 29); - features->rdrnd = IsBitSet(leaf_1.ecx, 30); - features->sgx = IsBitSet(leaf_7.ebx, 2); - features->bmi1 = IsBitSet(leaf_7.ebx, 3); - features->hle = IsBitSet(leaf_7.ebx, 4); - features->bmi2 = IsBitSet(leaf_7.ebx, 8); - features->erms = IsBitSet(leaf_7.ebx, 9); - features->rtm = IsBitSet(leaf_7.ebx, 11); - features->rdseed = IsBitSet(leaf_7.ebx, 18); - features->clflushopt = IsBitSet(leaf_7.ebx, 23); - features->clwb = IsBitSet(leaf_7.ebx, 24); - features->sha = IsBitSet(leaf_7.ebx, 29); - features->vaes = IsBitSet(leaf_7.ecx, 9); - features->vpclmulqdq = IsBitSet(leaf_7.ecx, 10); - features->adx = IsBitSet(leaf_7.ebx, 19); - - ///////////////////////////////////////////////////////////////////////////// - // The following section is devoted to Vector Extensions. - ///////////////////////////////////////////////////////////////////////////// - - // CPU with AVX expose XCR0 which enables checking vector extensions OS - // support through cpuid. - if (have_xcr0) - { - // Here we rely exclusively on cpuid for both CPU and OS support of vector - // extensions. - const uint32_t xcr0_eax = GetXCR0Eax(); - os_preserves->sse_registers = HasXmmOsXSave(xcr0_eax); - os_preserves->avx_registers = HasYmmOsXSave(xcr0_eax); -#if defined(CPU_FEATURES_OS_DARWIN) - // On Darwin AVX512 support is On-demand. - // We have to query the OS instead of querying the Zmm save/restore state. - // https://github.com/apple/darwin-xnu/blob/8f02f2a044b9bb1ad951987ef5bab20ec9486310/osfmk/i386/fpu.c#L173-L199 - os_preserves->avx512_registers = - GetDarwinSysCtlByName("hw.optional.avx512f"); -#else - os_preserves->avx512_registers = HasZmmOsXSave(xcr0_eax); -#endif // CPU_FEATURES_OS_DARWIN - os_preserves->amx_registers = HasTmmOsXSave(xcr0_eax); - - if (os_preserves->sse_registers) - { - features->sse = IsBitSet(leaf_1.edx, 25); - features->sse2 = IsBitSet(leaf_1.edx, 26); - features->sse3 = IsBitSet(leaf_1.ecx, 0); - features->ssse3 = IsBitSet(leaf_1.ecx, 9); - features->sse4_1 = IsBitSet(leaf_1.ecx, 19); - features->sse4_2 = IsBitSet(leaf_1.ecx, 20); - } - if (os_preserves->avx_registers) - { - features->fma3 = IsBitSet(leaf_1.ecx, 12); - features->avx = IsBitSet(leaf_1.ecx, 28); - features->avx2 = IsBitSet(leaf_7.ebx, 5); - } - if (os_preserves->avx512_registers) - { - features->avx512f = IsBitSet(leaf_7.ebx, 16); - features->avx512cd = IsBitSet(leaf_7.ebx, 28); - features->avx512er = IsBitSet(leaf_7.ebx, 27); - features->avx512pf = IsBitSet(leaf_7.ebx, 26); - features->avx512bw = IsBitSet(leaf_7.ebx, 30); - features->avx512dq = IsBitSet(leaf_7.ebx, 17); - features->avx512vl = IsBitSet(leaf_7.ebx, 31); - features->avx512ifma = IsBitSet(leaf_7.ebx, 21); - features->avx512vbmi = IsBitSet(leaf_7.ecx, 1); - features->avx512vbmi2 = IsBitSet(leaf_7.ecx, 6); - features->avx512vnni = IsBitSet(leaf_7.ecx, 11); - features->avx512bitalg = IsBitSet(leaf_7.ecx, 12); - features->avx512vpopcntdq = IsBitSet(leaf_7.ecx, 14); - features->avx512_4vnniw = IsBitSet(leaf_7.edx, 2); - features->avx512_4vbmi2 = IsBitSet(leaf_7.edx, 3); - features->avx512_second_fma = HasSecondFMA(info->model); - features->avx512_4fmaps = IsBitSet(leaf_7.edx, 3); - features->avx512_bf16 = IsBitSet(leaf_7_1.eax, 5); - features->avx512_vp2intersect = IsBitSet(leaf_7.edx, 8); - } - if (os_preserves->amx_registers) - { - features->amx_bf16 = IsBitSet(leaf_7.edx, 22); - features->amx_tile = IsBitSet(leaf_7.edx, 24); - features->amx_int8 = IsBitSet(leaf_7.edx, 25); - } - } - else - { - // When XCR0 is not available (Atom based or older cpus) we need to defer to - // the OS via custom code. -#if defined(CPU_FEATURES_OS_WINDOWS) - // Handling Windows platform through IsProcessorFeaturePresent. - // https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-isprocessorfeaturepresent - features->sse = - GetWindowsIsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE); - features->sse2 = - GetWindowsIsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE); - features->sse3 = - GetWindowsIsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE); -#elif defined(CPU_FEATURES_OS_DARWIN) - // Handling Darwin platform through sysctlbyname. - features->sse = GetDarwinSysCtlByName("hw.optional.sse"); - features->sse2 = GetDarwinSysCtlByName("hw.optional.sse2"); - features->sse3 = GetDarwinSysCtlByName("hw.optional.sse3"); - features->ssse3 = GetDarwinSysCtlByName("hw.optional.supplementalsse3"); - features->sse4_1 = GetDarwinSysCtlByName("hw.optional.sse4_1"); - features->sse4_2 = GetDarwinSysCtlByName("hw.optional.sse4_2"); -#elif defined(CPU_FEATURES_OS_FREEBSD) - // Handling FreeBSD platform through parsing /var/run/dmesg.boot. - const int fd = CpuFeatures_OpenFile("/var/run/dmesg.boot"); - if (fd >= 0) - { - StackLineReader reader; - StackLineReader_Initialize(&reader, fd); - for (bool stop = false; !stop;) - { - const LineResult result = StackLineReader_NextLine(&reader); - if (result.eof) stop = true; - const StringView line = result.line; - if (!CpuFeatures_StringView_StartsWith(line, str(" Features"))) - continue; - // Lines of interests are of the following form: - // " Features=0x1783fbff" - // We first extract the comma separated values between angle brackets. - StringView csv = result.line; - int index = CpuFeatures_StringView_IndexOfChar(csv, '<'); - if (index >= 0) csv = CpuFeatures_StringView_PopFront(csv, index + 1); - if (csv.size > 0 && CpuFeatures_StringView_Back(csv) == '>') - csv = CpuFeatures_StringView_PopBack(csv, 1); - if (CpuFeatures_StringView_HasWord(csv, "SSE", ',')) - features->sse = true; - if (CpuFeatures_StringView_HasWord(csv, "SSE2", ',')) - features->sse2 = true; - if (CpuFeatures_StringView_HasWord(csv, "SSE3", ',')) - features->sse3 = true; - if (CpuFeatures_StringView_HasWord(csv, "SSSE3", ',')) - features->ssse3 = true; - if (CpuFeatures_StringView_HasWord(csv, "SSE4.1", ',')) - features->sse4_1 = true; - if (CpuFeatures_StringView_HasWord(csv, "SSE4.2", ',')) - features->sse4_2 = true; - } - CpuFeatures_CloseFile(fd); - } -#elif defined(CPU_FEATURES_OS_LINUX_OR_ANDROID) - // Handling Linux platform through /proc/cpuinfo. - const int fd = CpuFeatures_OpenFile("/proc/cpuinfo"); - if (fd >= 0) - { - StackLineReader reader; - StackLineReader_Initialize(&reader, fd); - for (bool stop = false; !stop;) - { - const LineResult result = StackLineReader_NextLine(&reader); - if (result.eof) stop = true; - const StringView line = result.line; - StringView key, value; - if (!CpuFeatures_StringView_GetAttributeKeyValue(line, &key, &value)) - continue; - if (!CpuFeatures_StringView_IsEquals(key, str("flags"))) continue; - features->sse = CpuFeatures_StringView_HasWord(value, "sse", ' '); - features->sse2 = CpuFeatures_StringView_HasWord(value, "sse2", ' '); - features->sse3 = CpuFeatures_StringView_HasWord(value, "pni", ' '); - features->ssse3 = CpuFeatures_StringView_HasWord(value, "ssse3", ' '); - features->sse4_1 = CpuFeatures_StringView_HasWord(value, "sse4_1", ' '); - features->sse4_2 = CpuFeatures_StringView_HasWord(value, "sse4_2", ' '); - break; - } - CpuFeatures_CloseFile(fd); - } -#else -#error "Unsupported fallback detection of SSE OS support." -#endif - // Now that we have queried the OS for SSE support, we report this back to - // os_preserves. This is needed in case of AMD CPU's to enable testing of - // sse4a (See ParseExtraAMDCpuId below). - if (features->sse) os_preserves->sse_registers = true; - } -} - -// Reference -// https://en.wikipedia.org/wiki/CPUID#EAX=80000000h:_Get_Highest_Extended_Function_Implemented. -static Leaf GetLeafByIdAMD(uint32_t leaf_id) -{ - uint32_t max_extended = CpuId(0x80000000).eax; - return SafeCpuId(max_extended, leaf_id); -} - -static void ParseExtraAMDCpuId(X86Info* info, OsPreserves os_preserves) -{ - const Leaf leaf_80000001 = GetLeafByIdAMD(0x80000001); - - X86Features* const features = &info->features; - - if (os_preserves.sse_registers) - { - features->sse4a = IsBitSet(leaf_80000001.ecx, 6); - } - - if (os_preserves.avx_registers) - { - features->fma4 = IsBitSet(leaf_80000001.ecx, 16); - } -} - -static const X86Info kEmptyX86Info; -static const OsPreserves kEmptyOsPreserves; - -X86Info GetX86Info(void) -{ - X86Info info = kEmptyX86Info; - const Leaf leaf_0 = CpuId(0); - const bool is_intel = IsVendor(leaf_0, CPU_FEATURES_VENDOR_GENUINE_INTEL); - const bool is_amd = IsVendor(leaf_0, CPU_FEATURES_VENDOR_AUTHENTIC_AMD); - const bool is_hygon = IsVendor(leaf_0, CPU_FEATURES_VENDOR_HYGON_GENUINE); - SetVendor(leaf_0, info.vendor); - if (is_intel || is_amd || is_hygon) - { - OsPreserves os_preserves = kEmptyOsPreserves; - const uint32_t max_cpuid_leaf = leaf_0.eax; - ParseCpuId(max_cpuid_leaf, &info, &os_preserves); - if (is_amd || is_hygon) - { - ParseExtraAMDCpuId(&info, os_preserves); - } - } - return info; -} - CacheInfo GetX86CacheInfo(void) { CacheInfo info = kEmptyCacheInfo; - const Leaf leaf_0 = CpuId(0); - if (IsVendor(leaf_0, CPU_FEATURES_VENDOR_GENUINE_INTEL)) + const Leaves leaves = ReadLeaves(); + if (IsVendor(leaves.leaf_0, CPU_FEATURES_VENDOR_GENUINE_INTEL) || + IsVendor(leaves.leaf_0, CPU_FEATURES_VENDOR_CENTAUR_HAULS) || + IsVendor(leaves.leaf_0, CPU_FEATURES_VENDOR_SHANGHAI)) { - ParseLeaf2(leaf_0.eax, &info); - ParseCacheInfo(leaf_0.eax, 4, &info); + ParseLeaf2(&leaves, &info); + ParseCacheInfo(leaves.max_cpuid_leaf, 4, &info); } - else if (IsVendor(leaf_0, CPU_FEATURES_VENDOR_AUTHENTIC_AMD) || - IsVendor(leaf_0, CPU_FEATURES_VENDOR_HYGON_GENUINE)) + else if (IsVendor(leaves.leaf_0, CPU_FEATURES_VENDOR_AUTHENTIC_AMD) || + IsVendor(leaves.leaf_0, CPU_FEATURES_VENDOR_HYGON_GENUINE)) { - const uint32_t max_ext = CpuId(0x80000000).eax; - const uint32_t cpuid_ext = SafeCpuId(max_ext, 0x80000001).ecx; - // If CPUID Fn8000_0001_ECX[TopologyExtensions]==0 // then CPUID Fn8000_0001_E[D,C,B,A]X is reserved. // https://www.amd.com/system/files/TechDocs/25481.pdf - if (IsBitSet(cpuid_ext, 22)) + if (IsBitSet(leaves.leaf_80000001.ecx, 22)) { - ParseCacheInfo(max_ext, 0x8000001D, &info); + ParseCacheInfo(leaves.max_cpuid_leaf_ext, 0x8000001D, &info); } } return info; } -#define CPUID(FAMILY, MODEL) ((((FAMILY)&0xFF) << 8) | ((MODEL)&0xFF)) - -X86Microarchitecture GetX86Microarchitecture(const X86Info* info) -{ - if (IsVendorByX86Info(info, CPU_FEATURES_VENDOR_GENUINE_INTEL)) - { - switch (CPUID(info->family, info->model)) - { - case CPUID(0x06, 0x1C): // Intel(R) Atom(TM) CPU 230 @ 1.60GHz - case CPUID(0x06, 0x35): - case CPUID(0x06, 0x36): - case CPUID(0x06, 0x70): // https://en.wikichip.org/wiki/intel/atom/230 - // https://en.wikipedia.org/wiki/Bonnell_(microarchitecture) - return INTEL_ATOM_BNL; - case CPUID(0x06, 0x37): - case CPUID(0x06, 0x4C): - // https://en.wikipedia.org/wiki/Silvermont - return INTEL_ATOM_SMT; - case CPUID(0x06, 0x5C): - // https://en.wikipedia.org/wiki/Goldmont - return INTEL_ATOM_GMT; - case CPUID(0x06, 0x0F): - case CPUID(0x06, 0x16): - // https://en.wikipedia.org/wiki/Intel_Core_(microarchitecture) - return INTEL_CORE; - case CPUID(0x06, 0x17): - case CPUID(0x06, 0x1D): - // https://en.wikipedia.org/wiki/Penryn_(microarchitecture) - return INTEL_PNR; - case CPUID(0x06, 0x1A): - case CPUID(0x06, 0x1E): - case CPUID(0x06, 0x1F): - case CPUID(0x06, 0x2E): - // https://en.wikipedia.org/wiki/Nehalem_(microarchitecture) - return INTEL_NHM; - case CPUID(0x06, 0x25): - case CPUID(0x06, 0x2C): - case CPUID(0x06, 0x2F): - // https://en.wikipedia.org/wiki/Westmere_(microarchitecture) - return INTEL_WSM; - case CPUID(0x06, 0x2A): - case CPUID(0x06, 0x2D): - // https://en.wikipedia.org/wiki/Sandy_Bridge#Models_and_steppings - return INTEL_SNB; - case CPUID(0x06, 0x3A): - case CPUID(0x06, 0x3E): - // https://en.wikipedia.org/wiki/Ivy_Bridge_(microarchitecture)#Models_and_steppings - return INTEL_IVB; - case CPUID(0x06, 0x3C): - case CPUID(0x06, 0x3F): - case CPUID(0x06, 0x45): - case CPUID(0x06, 0x46): - // https://en.wikipedia.org/wiki/Haswell_(microarchitecture) - return INTEL_HSW; - case CPUID(0x06, 0x3D): - case CPUID(0x06, 0x47): - case CPUID(0x06, 0x4F): - case CPUID(0x06, 0x56): - // https://en.wikipedia.org/wiki/Broadwell_(microarchitecture) - return INTEL_BDW; - case CPUID(0x06, 0x4E): - case CPUID(0x06, 0x55): - case CPUID(0x06, 0x5E): - // https://en.wikipedia.org/wiki/Skylake_(microarchitecture) - return INTEL_SKL; - case CPUID(0x06, 0x66): - // https://en.wikipedia.org/wiki/Cannon_Lake_(microarchitecture) - return INTEL_CNL; - case CPUID(0x06, 0x7D): // client - case CPUID(0x06, 0x7E): // client - case CPUID(0x06, 0x9D): // NNP-I - case CPUID(0x06, 0x6A): // server - case CPUID(0x06, 0x6C): // server - // https://en.wikipedia.org/wiki/Ice_Lake_(microprocessor) - return INTEL_ICL; - case CPUID(0x06, 0x8C): - case CPUID(0x06, 0x8D): - // https://en.wikipedia.org/wiki/Tiger_Lake_(microarchitecture) - return INTEL_TGL; - case CPUID(0x06, 0x8F): - // https://en.wikipedia.org/wiki/Sapphire_Rapids - return INTEL_SPR; - case CPUID(0x06, 0x8E): - switch (info->stepping) - { - case 9: - return INTEL_KBL; // https://en.wikipedia.org/wiki/Kaby_Lake - case 10: - return INTEL_CFL; // https://en.wikipedia.org/wiki/Coffee_Lake - case 11: - return INTEL_WHL; // https://en.wikipedia.org/wiki/Whiskey_Lake_(microarchitecture) - default: - return X86_UNKNOWN; - } - case CPUID(0x06, 0x9E): - if (info->stepping > 9) - { - // https://en.wikipedia.org/wiki/Coffee_Lake - return INTEL_CFL; - } - else - { - // https://en.wikipedia.org/wiki/Kaby_Lake - return INTEL_KBL; - } - default: - return X86_UNKNOWN; - } - } - if (IsVendorByX86Info(info, CPU_FEATURES_VENDOR_AUTHENTIC_AMD)) - { - switch (CPUID(info->family, info->model)) - { - // https://en.wikichip.org/wiki/amd/cpuid - case CPUID(0xF, 0x04): - case CPUID(0xF, 0x05): - case CPUID(0xF, 0x07): - case CPUID(0xF, 0x08): - case CPUID(0xF, 0x0C): - case CPUID(0xF, 0x0E): - case CPUID(0xF, 0x0F): - case CPUID(0xF, 0x14): - case CPUID(0xF, 0x15): - case CPUID(0xF, 0x17): - case CPUID(0xF, 0x18): - case CPUID(0xF, 0x1B): - case CPUID(0xF, 0x1C): - case CPUID(0xF, 0x1F): - case CPUID(0xF, 0x21): - case CPUID(0xF, 0x23): - case CPUID(0xF, 0x24): - case CPUID(0xF, 0x25): - case CPUID(0xF, 0x27): - case CPUID(0xF, 0x2B): - case CPUID(0xF, 0x2C): - case CPUID(0xF, 0x2F): - case CPUID(0xF, 0x41): - case CPUID(0xF, 0x43): - case CPUID(0xF, 0x48): - case CPUID(0xF, 0x4B): - case CPUID(0xF, 0x4C): - case CPUID(0xF, 0x4F): - case CPUID(0xF, 0x5D): - case CPUID(0xF, 0x5F): - case CPUID(0xF, 0x68): - case CPUID(0xF, 0x6B): - case CPUID(0xF, 0x6F): - case CPUID(0xF, 0x7F): - case CPUID(0xF, 0xC1): - return AMD_HAMMER; - case CPUID(0x10, 0x02): - case CPUID(0x10, 0x04): - case CPUID(0x10, 0x05): - case CPUID(0x10, 0x06): - case CPUID(0x10, 0x08): - case CPUID(0x10, 0x09): - case CPUID(0x10, 0x0A): - return AMD_K10; - case CPUID(0x11, 0x03): - // http://developer.amd.com/wordpress/media/2012/10/41788.pdf - return AMD_K11; - case CPUID(0x12, 0x01): - // https://www.amd.com/system/files/TechDocs/44739_12h_Rev_Gd.pdf - return AMD_K12; - case CPUID(0x14, 0x00): - case CPUID(0x14, 0x01): - case CPUID(0x14, 0x02): - // https://www.amd.com/system/files/TechDocs/47534_14h_Mod_00h-0Fh_Rev_Guide.pdf - return AMD_BOBCAT; - case CPUID(0x15, 0x01): - // https://en.wikichip.org/wiki/amd/microarchitectures/bulldozer - return AMD_BULLDOZER; - case CPUID(0x15, 0x02): - case CPUID(0x15, 0x11): - case CPUID(0x15, 0x13): - // https://en.wikichip.org/wiki/amd/microarchitectures/piledriver - return AMD_PILEDRIVER; - case CPUID(0x15, 0x30): - case CPUID(0x15, 0x38): - // https://en.wikichip.org/wiki/amd/microarchitectures/steamroller - return AMD_STREAMROLLER; - case CPUID(0x15, 0x60): - case CPUID(0x15, 0x65): - case CPUID(0x15, 0x70): - // https://en.wikichip.org/wiki/amd/microarchitectures/excavator - return AMD_EXCAVATOR; - case CPUID(0x16, 0x00): - return AMD_JAGUAR; - case CPUID(0x16, 0x30): - return AMD_PUMA; - case CPUID(0x17, 0x01): - case CPUID(0x17, 0x11): - case CPUID(0x17, 0x18): - case CPUID(0x17, 0x20): - // https://en.wikichip.org/wiki/amd/microarchitectures/zen - return AMD_ZEN; - case CPUID(0x17, 0x08): - // https://en.wikichip.org/wiki/amd/microarchitectures/zen%2B - return AMD_ZEN_PLUS; - case CPUID(0x17, 0x31): - case CPUID(0x17, 0x47): - case CPUID(0x17, 0x60): - case CPUID(0x17, 0x68): - case CPUID(0x17, 0x71): - case CPUID(0x17, 0x90): - case CPUID(0x17, 0x98): - // https://en.wikichip.org/wiki/amd/microarchitectures/zen_2 - return AMD_ZEN2; - case CPUID(0x19, 0x01): - case CPUID(0x19, 0x21): - case CPUID(0x19, 0x30): - case CPUID(0x19, 0x40): - case CPUID(0x19, 0x50): - // https://en.wikichip.org/wiki/amd/microarchitectures/zen_3 - return AMD_ZEN3; - default: - return X86_UNKNOWN; - } - } - if (IsVendorByX86Info(info, CPU_FEATURES_VENDOR_HYGON_GENUINE)) - { - switch (CPUID(info->family, info->model)) - { - case CPUID(0x18, 0x00): - return AMD_ZEN; - } - } - return X86_UNKNOWN; -} - -void FillX86BrandString(char brand_string[49]) -{ - const Leaf leaf_ext_0 = CpuId(0x80000000); - const uint32_t max_cpuid_leaf_ext = leaf_ext_0.eax; - const Leaf leaves[3] = { - SafeCpuId(max_cpuid_leaf_ext, 0x80000002), - SafeCpuId(max_cpuid_leaf_ext, 0x80000003), - SafeCpuId(max_cpuid_leaf_ext, 0x80000004), - }; -#if __STDC_VERSION__ >= 201112L - _Static_assert(sizeof(leaves) == 48, "Leaves must be packed"); -#endif - CpuFeatures_StringView_CopyString(view((const char*)leaves, sizeof(leaves)), - brand_string, 49); -} - //////////////////////////////////////////////////////////////////////////////// -// Introspection functions +// Definitions for introspection. +//////////////////////////////////////////////////////////////////////////////// +#define INTROSPECTION_TABLE \ + LINE(X86_FPU, fpu, , , ) \ + LINE(X86_TSC, tsc, , , ) \ + LINE(X86_CX8, cx8, , , ) \ + LINE(X86_CLFSH, clfsh, , , ) \ + LINE(X86_MMX, mmx, , , ) \ + LINE(X86_AES, aes, , , ) \ + LINE(X86_ERMS, erms, , , ) \ + LINE(X86_F16C, f16c, , , ) \ + LINE(X86_FMA4, fma4, , , ) \ + LINE(X86_FMA3, fma3, , , ) \ + LINE(X86_VAES, vaes, , , ) \ + LINE(X86_VPCLMULQDQ, vpclmulqdq, , , ) \ + LINE(X86_BMI1, bmi1, , , ) \ + LINE(X86_HLE, hle, , , ) \ + LINE(X86_BMI2, bmi2, , , ) \ + LINE(X86_RTM, rtm, , , ) \ + LINE(X86_RDSEED, rdseed, , , ) \ + LINE(X86_CLFLUSHOPT, clflushopt, , , ) \ + LINE(X86_CLWB, clwb, , , ) \ + LINE(X86_SSE, sse, , , ) \ + LINE(X86_SSE2, sse2, , , ) \ + LINE(X86_SSE3, sse3, , , ) \ + LINE(X86_SSSE3, ssse3, , , ) \ + LINE(X86_SSE4_1, sse4_1, , , ) \ + LINE(X86_SSE4_2, sse4_2, , , ) \ + LINE(X86_SSE4A, sse4a, , , ) \ + LINE(X86_AVX, avx, , , ) \ + LINE(X86_AVX2, avx2, , , ) \ + LINE(X86_AVX512F, avx512f, , , ) \ + LINE(X86_AVX512CD, avx512cd, , , ) \ + LINE(X86_AVX512ER, avx512er, , , ) \ + LINE(X86_AVX512PF, avx512pf, , , ) \ + LINE(X86_AVX512BW, avx512bw, , , ) \ + LINE(X86_AVX512DQ, avx512dq, , , ) \ + LINE(X86_AVX512VL, avx512vl, , , ) \ + LINE(X86_AVX512IFMA, avx512ifma, , , ) \ + LINE(X86_AVX512VBMI, avx512vbmi, , , ) \ + LINE(X86_AVX512VBMI2, avx512vbmi2, , , ) \ + LINE(X86_AVX512VNNI, avx512vnni, , , ) \ + LINE(X86_AVX512BITALG, avx512bitalg, , , ) \ + LINE(X86_AVX512VPOPCNTDQ, avx512vpopcntdq, , , ) \ + LINE(X86_AVX512_4VNNIW, avx512_4vnniw, , , ) \ + LINE(X86_AVX512_4VBMI2, avx512_4vbmi2, , , ) \ + LINE(X86_AVX512_SECOND_FMA, avx512_second_fma, , , ) \ + LINE(X86_AVX512_4FMAPS, avx512_4fmaps, , , ) \ + LINE(X86_AVX512_BF16, avx512_bf16, , , ) \ + LINE(X86_AVX512_VP2INTERSECT, avx512_vp2intersect, , , ) \ + LINE(X86_AMX_BF16, amx_bf16, , , ) \ + LINE(X86_AMX_TILE, amx_tile, , , ) \ + LINE(X86_AMX_INT8, amx_int8, , , ) \ + LINE(X86_PCLMULQDQ, pclmulqdq, , , ) \ + LINE(X86_SMX, smx, , , ) \ + LINE(X86_SGX, sgx, , , ) \ + LINE(X86_CX16, cx16, , , ) \ + LINE(X86_SHA, sha, , , ) \ + LINE(X86_POPCNT, popcnt, , , ) \ + LINE(X86_MOVBE, movbe, , , ) \ + LINE(X86_RDRND, rdrnd, , , ) \ + LINE(X86_DCA, dca, , , ) \ + LINE(X86_SS, ss, , , ) \ + LINE(X86_ADX, adx, , , ) +#define INTROSPECTION_PREFIX X86 +#define INTROSPECTION_ENUM_PREFIX X86 +#include "define_introspection.inl" -int GetX86FeaturesEnumValue(const X86Features* features, - X86FeaturesEnum value) -{ - if (value >= X86_LAST_) return false; - return kGetters[value](features); -} +#define X86_MICROARCHITECTURE_NAMES \ + LINE(X86_UNKNOWN) \ + LINE(ZHAOXIN_ZHANGJIANG) \ + LINE(ZHAOXIN_WUDAOKOU) \ + LINE(ZHAOXIN_LUJIAZUI) \ + LINE(ZHAOXIN_YONGFENG) \ + LINE(INTEL_80486) \ + LINE(INTEL_P5) \ + LINE(INTEL_LAKEMONT) \ + LINE(INTEL_CORE) \ + LINE(INTEL_PNR) \ + LINE(INTEL_NHM) \ + LINE(INTEL_ATOM_BNL) \ + LINE(INTEL_WSM) \ + LINE(INTEL_SNB) \ + LINE(INTEL_IVB) \ + LINE(INTEL_ATOM_SMT) \ + LINE(INTEL_HSW) \ + LINE(INTEL_BDW) \ + LINE(INTEL_SKL) \ + LINE(INTEL_ATOM_GMT) \ + LINE(INTEL_KBL) \ + LINE(INTEL_CFL) \ + LINE(INTEL_WHL) \ + LINE(INTEL_CNL) \ + LINE(INTEL_ICL) \ + LINE(INTEL_TGL) \ + LINE(INTEL_SPR) \ + LINE(INTEL_ADL) \ + LINE(INTEL_RCL) \ + LINE(INTEL_KNIGHTS_M) \ + LINE(INTEL_KNIGHTS_L) \ + LINE(INTEL_KNIGHTS_F) \ + LINE(INTEL_KNIGHTS_C) \ + LINE(INTEL_NETBURST) \ + LINE(AMD_HAMMER) \ + LINE(AMD_K10) \ + LINE(AMD_K11) \ + LINE(AMD_K12) \ + LINE(AMD_BOBCAT) \ + LINE(AMD_PILEDRIVER) \ + LINE(AMD_STREAMROLLER) \ + LINE(AMD_EXCAVATOR) \ + LINE(AMD_BULLDOZER) \ + LINE(AMD_JAGUAR) \ + LINE(AMD_PUMA) \ + LINE(AMD_ZEN) \ + LINE(AMD_ZEN_PLUS) \ + LINE(AMD_ZEN2) \ + LINE(AMD_ZEN3) -const char* GetX86FeaturesEnumName(X86FeaturesEnum value) +const char* GetX86MicroarchitectureName(X86Microarchitecture value) { - if (value >= X86_LAST_) return "unknown_feature"; - return kCpuInfoFlags[value]; -} - -const char* GetX86MicroarchitectureName(X86Microarchitecture uarch) -{ - switch (uarch) - { - case X86_UNKNOWN: - return "X86_UNKNOWN"; - case INTEL_CORE: - return "INTEL_CORE"; - case INTEL_PNR: - return "INTEL_PNR"; - case INTEL_NHM: - return "INTEL_NHM"; - case INTEL_ATOM_BNL: - return "INTEL_ATOM_BNL"; - case INTEL_WSM: - return "INTEL_WSM"; - case INTEL_SNB: - return "INTEL_SNB"; - case INTEL_IVB: - return "INTEL_IVB"; - case INTEL_ATOM_SMT: - return "INTEL_ATOM_SMT"; - case INTEL_HSW: - return "INTEL_HSW"; - case INTEL_BDW: - return "INTEL_BDW"; - case INTEL_SKL: - return "INTEL_SKL"; - case INTEL_ATOM_GMT: - return "INTEL_ATOM_GMT"; - case INTEL_KBL: - return "INTEL_KBL"; - case INTEL_CFL: - return "INTEL_CFL"; - case INTEL_WHL: - return "INTEL_WHL"; - case INTEL_CNL: - return "INTEL_CNL"; - case INTEL_ICL: - return "INTEL_ICL"; - case INTEL_TGL: - return "INTEL_TGL"; - case INTEL_SPR: - return "INTEL_SPR"; - case AMD_HAMMER: - return "AMD_HAMMER"; - case AMD_K10: - return "AMD_K10"; - case AMD_K11: - return "AMD_K11"; - case AMD_K12: - return "AMD_K12"; - case AMD_BOBCAT: - return "AMD_BOBCAT"; - case AMD_PILEDRIVER: - return "AMD_PILEDRIVER"; - case AMD_STREAMROLLER: - return "AMD_STREAMROLLER"; - case AMD_EXCAVATOR: - return "AMD_EXCAVATOR"; - case AMD_BULLDOZER: - return "AMD_BULLDOZER"; - case AMD_PUMA: - return "AMD_PUMA"; - case AMD_JAGUAR: - return "AMD_JAGUAR"; - case AMD_ZEN: - return "AMD_ZEN"; - case AMD_ZEN_PLUS: - return "AMD_ZEN_PLUS"; - case AMD_ZEN2: - return "AMD_ZEN2"; - case AMD_ZEN3: - return "AMD_ZEN3"; - } - return "unknown microarchitecture"; +#define LINE(ENUM) [ENUM] = STRINGIZE(ENUM), + static const char* kMicroarchitectureNames[] = {X86_MICROARCHITECTURE_NAMES}; +#undef LINE + if (value >= X86_MICROARCHITECTURE_LAST_) return "unknown microarchitecture"; + return kMicroarchitectureNames[value]; } diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_x86_freebsd.c b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_x86_freebsd.c new file mode 100644 index 000000000..6a684d8ad --- /dev/null +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_x86_freebsd.c @@ -0,0 +1,61 @@ +// SPDX-FileCopyrightText: 2017 Google LLC +// SPDX-License-Identifier: Apache-2.0 + +#include "cpu_features_macros.h" + +#ifdef CPU_FEATURES_ARCH_X86 +#ifdef CPU_FEATURES_OS_FREEBSD + +#include "impl_x86__base_implementation.inl" + +static void OverrideOsPreserves(OsPreserves* os_preserves) +{ + (void)os_preserves; + // No override +} + +#include "internal/filesystem.h" +#include "internal/stack_line_reader.h" +#include "internal/string_view.h" + +static void DetectFeaturesFromOs(X86Info* info, X86Features* features) +{ + (void)info; + // Handling FreeBSD platform through parsing /var/run/dmesg.boot. + const int fd = CpuFeatures_OpenFile("/var/run/dmesg.boot"); + if (fd >= 0) + { + StackLineReader reader; + StackLineReader_Initialize(&reader, fd); + for (bool stop = false; !stop;) + { + const LineResult result = StackLineReader_NextLine(&reader); + if (result.eof) stop = true; + const StringView line = result.line; + if (!CpuFeatures_StringView_StartsWith(line, str(" Features"))) continue; + // Lines of interests are of the following form: + // " Features=0x1783fbff" + // We first extract the comma separated values between angle brackets. + StringView csv = result.line; + int index = CpuFeatures_StringView_IndexOfChar(csv, '<'); + if (index >= 0) csv = CpuFeatures_StringView_PopFront(csv, index + 1); + if (csv.size > 0 && CpuFeatures_StringView_Back(csv) == '>') + csv = CpuFeatures_StringView_PopBack(csv, 1); + if (CpuFeatures_StringView_HasWord(csv, "SSE", ',')) features->sse = true; + if (CpuFeatures_StringView_HasWord(csv, "SSE2", ',')) + features->sse2 = true; + if (CpuFeatures_StringView_HasWord(csv, "SSE3", ',')) + features->sse3 = true; + if (CpuFeatures_StringView_HasWord(csv, "SSSE3", ',')) + features->ssse3 = true; + if (CpuFeatures_StringView_HasWord(csv, "SSE4.1", ',')) + features->sse4_1 = true; + if (CpuFeatures_StringView_HasWord(csv, "SSE4.2", ',')) + features->sse4_2 = true; + } + CpuFeatures_CloseFile(fd); + } +} + +#endif // CPU_FEATURES_OS_FREEBSD +#endif // CPU_FEATURES_ARCH_X86 diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_x86_linux_or_android.c b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_x86_linux_or_android.c new file mode 100644 index 000000000..7e9eb0a56 --- /dev/null +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_x86_linux_or_android.c @@ -0,0 +1,51 @@ +// SPDX-FileCopyrightText: 2017 Google LLC +// SPDX-License-Identifier: Apache-2.0 + +#include "cpu_features_macros.h" + +#ifdef CPU_FEATURES_ARCH_X86 +#if defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID) + +#include "impl_x86__base_implementation.inl" + +static void OverrideOsPreserves(OsPreserves* os_preserves) +{ + (void)os_preserves; + // No override +} + +#include "internal/filesystem.h" +#include "internal/stack_line_reader.h" +#include "internal/string_view.h" +static void DetectFeaturesFromOs(X86Info* info, X86Features* features) +{ + (void)info; + // Handling Linux platform through /proc/cpuinfo. + const int fd = CpuFeatures_OpenFile("/proc/cpuinfo"); + if (fd >= 0) + { + StackLineReader reader; + StackLineReader_Initialize(&reader, fd); + for (bool stop = false; !stop;) + { + const LineResult result = StackLineReader_NextLine(&reader); + if (result.eof) stop = true; + const StringView line = result.line; + StringView key, value; + if (!CpuFeatures_StringView_GetAttributeKeyValue(line, &key, &value)) + continue; + if (!CpuFeatures_StringView_IsEquals(key, str("flags"))) continue; + features->sse = CpuFeatures_StringView_HasWord(value, "sse", ' '); + features->sse2 = CpuFeatures_StringView_HasWord(value, "sse2", ' '); + features->sse3 = CpuFeatures_StringView_HasWord(value, "pni", ' '); + features->ssse3 = CpuFeatures_StringView_HasWord(value, "ssse3", ' '); + features->sse4_1 = CpuFeatures_StringView_HasWord(value, "sse4_1", ' '); + features->sse4_2 = CpuFeatures_StringView_HasWord(value, "sse4_2", ' '); + break; + } + CpuFeatures_CloseFile(fd); + } +} + +#endif // defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID) +#endif // CPU_FEATURES_ARCH_X86 diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_x86_macos.c b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_x86_macos.c new file mode 100644 index 000000000..aa3ed3dd0 --- /dev/null +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_x86_macos.c @@ -0,0 +1,49 @@ +// SPDX-FileCopyrightText: 2017 Google LLC +// SPDX-License-Identifier: Apache-2.0 + +#include "cpu_features_macros.h" + +#ifdef CPU_FEATURES_ARCH_X86 +#ifdef CPU_FEATURES_OS_MACOS + +#include "impl_x86__base_implementation.inl" + +#if !defined(HAVE_SYSCTLBYNAME) +#error "Darwin needs support for sysctlbyname" +#endif +#include + +#if defined(CPU_FEATURES_MOCK_CPUID_X86) +extern bool GetDarwinSysCtlByName(const char*); +#else // CPU_FEATURES_MOCK_CPUID_X86 +static bool GetDarwinSysCtlByName(const char* name) +{ + int enabled; + size_t enabled_len = sizeof(enabled); + const int failure = sysctlbyname(name, &enabled, &enabled_len, NULL, 0); + return failure ? false : enabled; +} +#endif + +static void OverrideOsPreserves(OsPreserves* os_preserves) +{ + // On Darwin AVX512 support is On-demand. + // We have to query the OS instead of querying the Zmm save/restore state. + // https://github.com/apple/darwin-xnu/blob/8f02f2a044b9bb1ad951987ef5bab20ec9486310/osfmk/i386/fpu.c#L173-L199 + os_preserves->avx512_registers = GetDarwinSysCtlByName("hw.optional.avx512f"); +} + +static void DetectFeaturesFromOs(X86Info* info, X86Features* features) +{ + (void)info; + // Handling Darwin platform through sysctlbyname. + features->sse = GetDarwinSysCtlByName("hw.optional.sse"); + features->sse2 = GetDarwinSysCtlByName("hw.optional.sse2"); + features->sse3 = GetDarwinSysCtlByName("hw.optional.sse3"); + features->ssse3 = GetDarwinSysCtlByName("hw.optional.supplementalsse3"); + features->sse4_1 = GetDarwinSysCtlByName("hw.optional.sse4_1"); + features->sse4_2 = GetDarwinSysCtlByName("hw.optional.sse4_2"); +} + +#endif // CPU_FEATURES_OS_MACOS +#endif // CPU_FEATURES_ARCH_X86 diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_x86_windows.c b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_x86_windows.c new file mode 100644 index 000000000..66d47c7be --- /dev/null +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_x86_windows.c @@ -0,0 +1,51 @@ +// SPDX-FileCopyrightText: 2017 Google LLC +// SPDX-License-Identifier: Apache-2.0 + +#include "cpu_features_macros.h" + +#ifdef CPU_FEATURES_ARCH_X86 +#ifdef CPU_FEATURES_OS_WINDOWS + +#include "impl_x86__base_implementation.inl" + +static void OverrideOsPreserves(OsPreserves* os_preserves) +{ + (void)os_preserves; + // No override +} + +#include // IsProcessorFeaturePresent + +#if defined(CPU_FEATURES_MOCK_CPUID_X86) +extern bool GetWindowsIsProcessorFeaturePresent(DWORD); +#else // CPU_FEATURES_MOCK_CPUID_X86 +static bool GetWindowsIsProcessorFeaturePresent(DWORD ProcessorFeature) +{ + return IsProcessorFeaturePresent(ProcessorFeature); +} +#endif + +static void DetectFeaturesFromOs(X86Info* info, X86Features* features) +{ + // Handling Windows platform through IsProcessorFeaturePresent. + // https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-isprocessorfeaturepresent + features->sse = + GetWindowsIsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE); + features->sse2 = + GetWindowsIsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE); + features->sse3 = + GetWindowsIsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE); + +// https://github.com/google/cpu_features/issues/200 +#if (_WIN32_WINNT >= 0x0601) // Win7+ + if (GetX86Microarchitecture(info) == INTEL_WSM) + { + features->ssse3 = true; + features->sse4_1 = true; + features->sse4_2 = true; + } +#endif +} + +#endif // CPU_FEATURES_OS_WINDOWS +#endif // CPU_FEATURES_ARCH_X86 diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/utils/list_cpu_features.c b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/utils/list_cpu_features.c index db72230c7..51a53a462 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/utils/list_cpu_features.c +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/utils/list_cpu_features.c @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2017 Google LLC +// SPDX-FileCopyrightText: 2021 Google LLC // SPDX-License-Identifier: Apache-2.0 // This program dumps current host data to the standard output. @@ -363,7 +363,7 @@ static Node* GetCacheTypeString(CacheType cache_type) case CPU_FEATURE_CACHE_PREFETCH: return CreateConstantString("prefetch"); } - UNREACHABLE(); + CPU_FEATURES_UNREACHABLE(); } static void AddCacheInfo(Node* root, const CacheInfo* cache_info) diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/CMakeLists.txt b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/CMakeLists.txt index 6f8f2f397..f5330653c 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/CMakeLists.txt +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/CMakeLists.txt @@ -50,7 +50,13 @@ add_test(NAME stack_line_reader_test COMMAND stack_line_reader_test) ##------------------------------------------------------------------------------ ## cpuinfo_x86_test if(PROCESSOR_IS_X86) - add_executable(cpuinfo_x86_test cpuinfo_x86_test.cc ../src/cpuinfo_x86.c) + add_executable(cpuinfo_x86_test + cpuinfo_x86_test.cc + ../src/impl_x86_freebsd.c + ../src/impl_x86_linux_or_android.c + ../src/impl_x86_macos.c + ../src/impl_x86_windows.c + ) target_compile_definitions(cpuinfo_x86_test PUBLIC CPU_FEATURES_MOCK_CPUID_X86) if(APPLE) target_compile_definitions(cpuinfo_x86_test PRIVATE HAVE_SYSCTLBYNAME) @@ -61,32 +67,28 @@ endif() ##------------------------------------------------------------------------------ ## cpuinfo_arm_test if(PROCESSOR_IS_ARM) - add_executable(cpuinfo_arm_test cpuinfo_arm_test.cc ../src/cpuinfo_arm.c) + add_executable(cpuinfo_arm_test cpuinfo_arm_test.cc ../src/impl_arm_linux_or_android.c) target_link_libraries(cpuinfo_arm_test all_libraries) add_test(NAME cpuinfo_arm_test COMMAND cpuinfo_arm_test) endif() ##------------------------------------------------------------------------------ ## cpuinfo_aarch64_test if(PROCESSOR_IS_AARCH64) - add_executable(cpuinfo_aarch64_test cpuinfo_aarch64_test.cc ../src/cpuinfo_aarch64.c) - if(APPLE) - target_compile_definitions(cpuinfo_aarch64_test PUBLIC CPU_FEATURES_MOCK_CPUID_ARM64) - target_compile_definitions(cpuinfo_aarch64_test PRIVATE HAVE_SYSCTLBYNAME) - endif() + add_executable(cpuinfo_aarch64_test cpuinfo_aarch64_test.cc ../src/impl_aarch64_linux_or_android.c) target_link_libraries(cpuinfo_aarch64_test all_libraries) add_test(NAME cpuinfo_aarch64_test COMMAND cpuinfo_aarch64_test) endif() ##------------------------------------------------------------------------------ ## cpuinfo_mips_test if(PROCESSOR_IS_MIPS) - add_executable(cpuinfo_mips_test cpuinfo_mips_test.cc ../src/cpuinfo_mips.c) + add_executable(cpuinfo_mips_test cpuinfo_mips_test.cc ../src/impl_mips_linux_or_android.c) target_link_libraries(cpuinfo_mips_test all_libraries) add_test(NAME cpuinfo_mips_test COMMAND cpuinfo_mips_test) endif() ##------------------------------------------------------------------------------ ## cpuinfo_ppc_test if(PROCESSOR_IS_POWER) - add_executable(cpuinfo_ppc_test cpuinfo_ppc_test.cc ../src/cpuinfo_ppc.c) + add_executable(cpuinfo_ppc_test cpuinfo_ppc_test.cc ../src/impl_ppc_linux.c) target_link_libraries(cpuinfo_ppc_test all_libraries) add_test(NAME cpuinfo_ppc_test COMMAND cpuinfo_ppc_test) endif() diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/cpuinfo_arm_test.cc b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/cpuinfo_arm_test.cc index 44676a6aa..735f8e123 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/cpuinfo_arm_test.cc +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/cpuinfo_arm_test.cc @@ -103,7 +103,6 @@ CPU architecture: 7 CPU variant : 0x0 CPU part : 0xb76 CPU revision : 7 - Hardware : BCM2835 Revision : 9000c1 Serial : 000000006cd946f3)"); @@ -156,7 +155,6 @@ CPU architecture: 7 CPU variant : 0x4 CPU part : 0xc09 CPU revision : 1 - processor : 1 model name : ARMv7 Processor rev 1 (v7l) BogoMIPS : 50.00 @@ -166,7 +164,6 @@ CPU architecture: 7 CPU variant : 0x4 CPU part : 0xc09 CPU revision : 1 - Hardware : Marvell Armada 380/385 (Device Tree) Revision : 0000 Serial : 0000000000000000)"); @@ -221,7 +218,6 @@ CPU architecture: 7 CPU variant : 0x0 CPU part : 0xb76 CPU revision : 6 - Hardware : SPICA Revision : 0020 Serial : 33323613546d00ec )"); @@ -267,17 +263,14 @@ TEST(CpuinfoArmTest, InvalidNeon) R"(Processor: ARMv7 Processory rev 0 (v71) processor: 0 BogoMIPS: 13.50 - Processor: 1 BogoMIPS: 13.50 - Features: swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt CPU implementer : 0x51 CPU architecture: 7 CPU variant: 0x1 CPU part: 0x04d CPU revision: 0 - Hardware: SAMSUNG M2 Revision: 0010 Serial: 00001e030000354e)"); @@ -324,6 +317,25 @@ CPU revision : 3)"); EXPECT_EQ(GetArmCpuId(&info), 0x510006f3); } +// The 2013 Nexus 7 (Qualcomm Krait) kernel configuration forgets to report IDIV +// support. +TEST(CpuinfoArmTest, Nexus7_2013_0x511006f0) +{ + ResetHwcaps(); + auto& fs = GetEmptyFilesystem(); + fs.CreateFile("/proc/cpuinfo", + R"(CPU implementer : 0x51 +CPU architecture: 7 +CPU variant : 0x1 +CPU part : 0x06f +CPU revision : 0)"); + const auto info = GetArmInfo(); + EXPECT_TRUE(info.features.idiva); + EXPECT_TRUE(info.features.idivt); + + EXPECT_EQ(GetArmCpuId(&info), 0x511006f0); +} + // The emulator-specific Android 4.2 kernel fails to report support for the // 32-bit ARM IDIV instruction. Technically, this is a feature of the virtual // CPU implemented by the emulator. @@ -340,7 +352,6 @@ CPU architecture: 7 CPU variant : 0x0 CPU part : 0xc08 CPU revision : 0 - Hardware : Goldfish Revision : 0000 Serial : 0000000000000000)"); diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/cpuinfo_x86_test.cc b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/cpuinfo_x86_test.cc index 4c242cf8b..fe3b07e64 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/cpuinfo_x86_test.cc +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/cpuinfo_x86_test.cc @@ -16,6 +16,7 @@ namespace cpu_features { + class FakeCpu { public: @@ -41,7 +42,7 @@ public: xcr0_eax_ = os_backups_extended_registers ? -1 : 0; } -#if defined(CPU_FEATURES_OS_DARWIN) +#if defined(CPU_FEATURES_OS_MACOS) bool GetDarwinSysCtlByName(std::string name) const { return darwin_sysctlbyname_.count(name); @@ -51,7 +52,7 @@ public: { darwin_sysctlbyname_.insert(name); } -#endif // CPU_FEATURES_OS_DARWIN +#endif // CPU_FEATURES_OS_MACOS #if defined(CPU_FEATURES_OS_WINDOWS) bool GetWindowsIsProcessorFeaturePresent(DWORD ProcessorFeature) @@ -67,9 +68,9 @@ public: private: std::map, Leaf> cpuid_leaves_; -#if defined(CPU_FEATURES_OS_DARWIN) +#if defined(CPU_FEATURES_OS_MACOS) std::set darwin_sysctlbyname_; -#endif // CPU_FEATURES_OS_DARWIN +#endif // CPU_FEATURES_OS_MACOS #if defined(CPU_FEATURES_OS_WINDOWS) std::set windows_isprocessorfeaturepresent_; #endif // CPU_FEATURES_OS_WINDOWS @@ -91,12 +92,12 @@ extern "C" Leaf GetCpuidLeaf(uint32_t leaf_id, int ecx) extern "C" uint32_t GetXCR0Eax(void) { return cpu().GetXCR0Eax(); } -#if defined(CPU_FEATURES_OS_DARWIN) +#if defined(CPU_FEATURES_OS_MACOS) extern "C" bool GetDarwinSysCtlByName(const char* name) { return cpu().GetDarwinSysCtlByName(name); } -#endif // CPU_FEATURES_OS_DARWIN +#endif // CPU_FEATURES_OS_MACOS #if defined(CPU_FEATURES_OS_WINDOWS) extern "C" bool GetWindowsIsProcessorFeaturePresent(DWORD ProcessorFeature) @@ -107,6 +108,7 @@ extern "C" bool GetWindowsIsProcessorFeaturePresent(DWORD ProcessorFeature) namespace { + class CpuidX86Test : public ::testing::Test { protected: @@ -430,6 +432,8 @@ TEST_F(CpuidX86Test, AMD_K15_EXCAVATOR_STONEY_RIDGE) EXPECT_STREQ(info.vendor, "AuthenticAMD"); EXPECT_EQ(info.family, 0x15); EXPECT_EQ(info.model, 0x70); + EXPECT_STREQ(info.brand_string, + "AMD A9-9410 RADEON R5, 5 COMPUTE CORES 2C+3G "); EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_EXCAVATOR); @@ -456,6 +460,8 @@ TEST_F(CpuidX86Test, AMD_K15_PILEDRIVER_ABU_DHABI) EXPECT_STREQ(info.vendor, "AuthenticAMD"); EXPECT_EQ(info.family, 0x15); EXPECT_EQ(info.model, 0x02); + EXPECT_STREQ(info.brand_string, + "AMD Opteron(tm) Processor 6376 "); EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_PILEDRIVER); @@ -531,6 +537,8 @@ TEST_F(CpuidX86Test, AMD_K15_BULLDOZER_INTERLAGOS) EXPECT_STREQ(info.vendor, "AuthenticAMD"); EXPECT_EQ(info.family, 0x15); EXPECT_EQ(info.model, 0x01); + EXPECT_STREQ(info.brand_string, + "AMD Opteron(TM) Processor 6238 "); EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_BULLDOZER); @@ -559,6 +567,8 @@ TEST_F(CpuidX86Test, AMD_K15_STREAMROLLER_GODAVARI) EXPECT_EQ(info.family, 0x15); EXPECT_EQ(info.model, 0x38); EXPECT_EQ(info.stepping, 0x01); + EXPECT_STREQ(info.brand_string, + "AMD A8-7670K Radeon R7, 10 Compute Cores 4C+6G "); EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_STREAMROLLER); @@ -585,6 +595,8 @@ TEST_F(CpuidX86Test, AMD_K16_JAGUAR_KABINI) EXPECT_STREQ(info.vendor, "AuthenticAMD"); EXPECT_EQ(info.family, 0x16); EXPECT_EQ(info.model, 0x00); + EXPECT_STREQ(info.brand_string, + "AMD A4-5000 APU with Radeon(TM) HD Graphics "); EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_JAGUAR); char brand_string[49]; @@ -610,6 +622,8 @@ TEST_F(CpuidX86Test, AMD_K16_PUMA_BEEMA) EXPECT_STREQ(info.vendor, "AuthenticAMD"); EXPECT_EQ(info.family, 0x16); EXPECT_EQ(info.model, 0x30); + EXPECT_STREQ(info.brand_string, + "AMD A6-6310 APU with AMD Radeon R4 Graphics "); EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_PUMA); char brand_string[49]; @@ -635,6 +649,8 @@ TEST_F(CpuidX86Test, AMD_K17_ZEN_DALI) EXPECT_STREQ(info.vendor, "AuthenticAMD"); EXPECT_EQ(info.family, 0x17); EXPECT_EQ(info.model, 0x20); + EXPECT_STREQ(info.brand_string, + "AMD 3020e with Radeon Graphics "); EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN); char brand_string[49]; @@ -660,6 +676,8 @@ TEST_F(CpuidX86Test, AMD_K17_ZEN_PLUS_PINNACLE_RIDGE) EXPECT_STREQ(info.vendor, "AuthenticAMD"); EXPECT_EQ(info.family, 0x17); EXPECT_EQ(info.model, 0x08); + EXPECT_STREQ(info.brand_string, + "AMD Ryzen 7 2700X Eight-Core Processor "); EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN_PLUS); char brand_string[49]; @@ -685,6 +703,7 @@ TEST_F(CpuidX86Test, AMD_K17_ZEN2_XBOX_SERIES_X) EXPECT_STREQ(info.vendor, "AuthenticAMD"); EXPECT_EQ(info.family, 0x17); EXPECT_EQ(info.model, 0x47); + EXPECT_STREQ(info.brand_string, "AMD 4700S 8-Core Processor Desktop Kit"); EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN2); char brand_string[49]; @@ -710,6 +729,8 @@ TEST_F(CpuidX86Test, AMD_K18_ZEN_DHYANA) EXPECT_STREQ(info.vendor, "HygonGenuine"); EXPECT_EQ(info.family, 0x18); EXPECT_EQ(info.model, 0x00); + EXPECT_STREQ(info.brand_string, + "Hygon C86 3185 8-core Processor "); EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN); char brand_string[49]; @@ -784,6 +805,8 @@ TEST_F(CpuidX86Test, AMD_K19_ZEN3_VERMEER) EXPECT_STREQ(info.vendor, "AuthenticAMD"); EXPECT_EQ(info.family, 0x19); EXPECT_EQ(info.model, 0x21); + EXPECT_STREQ(info.brand_string, + "AMD Ryzen 9 5900X 12-Core Processor "); EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN3); char brand_string[49]; @@ -800,7 +823,7 @@ TEST_F(CpuidX86Test, Nehalem) cpu().SetWindowsIsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE); cpu().SetWindowsIsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE); cpu().SetWindowsIsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE); -#elif defined(CPU_FEATURES_OS_DARWIN) +#elif defined(CPU_FEATURES_OS_MACOS) cpu().SetDarwinSysCtlByName("hw.optional.sse"); cpu().SetDarwinSysCtlByName("hw.optional.sse2"); cpu().SetDarwinSysCtlByName("hw.optional.sse3"); @@ -817,10 +840,10 @@ FreeBSD is a registered trademark of The FreeBSD Foundation. Features2=0x5eda2203 real memory = 2147418112 (2047 MB) )"); -#elif defined(CPU_FEATURES_OS_LINUX_OR_ANDROID) +#elif defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID) auto& fs = GetEmptyFilesystem(); fs.CreateFile("/proc/cpuinfo", R"(processor : -flags : fpu mmx sse sse2 sse3 ssse3 sse4_1 sse4_2 +flags : fpu mmx sse sse2 pni ssse3 sse4_1 sse4_2 )"); #endif cpu().SetLeaves({ @@ -856,6 +879,8 @@ flags : fpu mmx sse sse2 sse3 ssse3 sse4_1 sse4_2 EXPECT_EQ(info.family, 0x06); EXPECT_EQ(info.model, 0x1A); EXPECT_EQ(info.stepping, 0x02); + EXPECT_STREQ(info.brand_string, + "Genuine Intel(R) CPU @ 0000 @ 1.87GHz"); EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_NHM); char brand_string[49]; @@ -883,7 +908,7 @@ TEST_F(CpuidX86Test, Atom) cpu().SetWindowsIsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE); cpu().SetWindowsIsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE); cpu().SetWindowsIsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE); -#elif defined(CPU_FEATURES_OS_DARWIN) +#elif defined(CPU_FEATURES_OS_MACOS) cpu().SetDarwinSysCtlByName("hw.optional.sse"); cpu().SetDarwinSysCtlByName("hw.optional.sse2"); cpu().SetDarwinSysCtlByName("hw.optional.sse3"); @@ -900,10 +925,10 @@ FreeBSD is a registered trademark of The FreeBSD Foundation. Features2=0x5eda2203 real memory = 2147418112 (2047 MB) )"); -#elif defined(CPU_FEATURES_OS_LINUX_OR_ANDROID) +#elif defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID) auto& fs = GetEmptyFilesystem(); fs.CreateFile("/proc/cpuinfo", R"( -flags : fpu mmx sse sse2 sse3 ssse3 sse4_1 sse4_2 +flags : fpu mmx sse sse2 pni ssse3 sse4_1 sse4_2 )"); #endif cpu().SetLeaves({ @@ -938,6 +963,8 @@ flags : fpu mmx sse sse2 sse3 ssse3 sse4_1 sse4_2 EXPECT_EQ(info.family, 0x06); EXPECT_EQ(info.model, 0x37); EXPECT_EQ(info.stepping, 0x03); + EXPECT_STREQ(info.brand_string, + " Intel(R) Celeron(R) CPU J1900 @ 1.99GHz"); EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_ATOM_SMT); @@ -1017,7 +1044,7 @@ TEST_F(CpuidX86Test, P3) cpu().SetOsBackupsExtendedRegisters(false); #if defined(CPU_FEATURES_OS_WINDOWS) cpu().SetWindowsIsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE); -#elif defined(CPU_FEATURES_OS_DARWIN) +#elif defined(CPU_FEATURES_OS_MACOS) cpu().SetDarwinSysCtlByName("hw.optional.sse"); #elif defined(CPU_FEATURES_OS_FREEBSD) auto& fs = GetEmptyFilesystem(); @@ -1028,7 +1055,7 @@ FreeBSD is a registered trademark of The FreeBSD Foundation. Features=0x1783fbff real memory = 2147418112 (2047 MB) )"); -#elif defined(CPU_FEATURES_OS_LINUX_OR_ANDROID) +#elif defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID) auto& fs = GetEmptyFilesystem(); fs.CreateFile("/proc/cpuinfo", R"( flags : fpu mmx sse @@ -1046,6 +1073,7 @@ flags : fpu mmx sse EXPECT_EQ(info.family, 0x06); EXPECT_EQ(info.model, 0x07); EXPECT_EQ(info.stepping, 0x03); + EXPECT_STREQ(info.brand_string, ""); EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::X86_UNKNOWN); char brand_string[49]; @@ -1065,6 +1093,95 @@ flags : fpu mmx sse #endif // !defined(CPU_FEATURES_OS_WINDOWS) } +// https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel0000480_486_CPUID.txt +TEST_F(CpuidX86Test, INTEL_80486) +{ + cpu().SetLeaves({ + {{0x00000000, 0}, Leaf{0x00000001, 0x756E6547, 0x6C65746E, 0x49656E69}}, + {{0x00000001, 0}, Leaf{0x00000480, 0x00000000, 0x00000000, 0x00000003}}, + }); + const auto info = GetX86Info(); + + EXPECT_STREQ(info.vendor, "GenuineIntel"); + EXPECT_EQ(info.family, 0x04); + EXPECT_EQ(info.model, 0x08); + EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_80486); +} + +// https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel0000526_P54C_CPUID.txt +TEST_F(CpuidX86Test, INTEL_P54C) +{ + cpu().SetLeaves({ + {{0x00000000, 0}, Leaf{0x00000001, 0x756E6547, 0x6C65746E, 0x49656E69}}, + {{0x00000001, 0}, Leaf{0x00000525, 0x00000000, 0x00000000, 0x000001BF}}, + }); + const auto info = GetX86Info(); + + EXPECT_STREQ(info.vendor, "GenuineIntel"); + EXPECT_EQ(info.family, 0x05); + EXPECT_EQ(info.model, 0x02); + EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_P5); +} + +// https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel0000590_Lakemont_CPUID2.txt +TEST_F(CpuidX86Test, INTEL_LAKEMONT) +{ + cpu().SetLeaves({ + {{0x00000000, 0}, Leaf{0x00000002, 0x756E6547, 0x6c65746E, 0x49656E69}}, + {{0x00000001, 0}, Leaf{0x00000590, 0x00000000, 0x00010200, 0x8000237B}}, + }); + const auto info = GetX86Info(); + + EXPECT_STREQ(info.vendor, "GenuineIntel"); + EXPECT_EQ(info.family, 0x05); + EXPECT_EQ(info.model, 0x09); + EXPECT_EQ(GetX86Microarchitecture(&info), + X86Microarchitecture::INTEL_LAKEMONT); +} + +// https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel0050670_KnightsLanding_CPUID.txt +TEST_F(CpuidX86Test, INTEL_KNIGHTS_LANDING) +{ + cpu().SetLeaves({ + {{0x00000000, 0}, Leaf{0x0000000D, 0x756E6547, 0x6C65746E, 0x49656E69}}, + {{0x00000001, 0}, Leaf{0x00050670, 0x02FF0800, 0x7FF8F3BF, 0xBFEBFBFF}}, + }); + const auto info = GetX86Info(); + + EXPECT_STREQ(info.vendor, "GenuineIntel"); + EXPECT_EQ(info.family, 0x06); + EXPECT_EQ(info.model, 0x57); + EXPECT_EQ(GetX86Microarchitecture(&info), + X86Microarchitecture::INTEL_KNIGHTS_L); +} + +// https://github.com/google/cpu_features/issues/200 +// http://users.atw.hu/instlatx64/GenuineIntel/GenuineIntel00206F2_Eagleton_CPUID.txt +#if defined(CPU_FEATURES_OS_WINDOWS) +TEST_F(CpuidX86Test, WIN_INTEL_WESTMERE_EX) +{ + cpu().SetLeaves({ + {{0x00000000, 0}, Leaf{0x0000000B, 0x756E6547, 0x6C65746E, 0x49656E69}}, + {{0x00000001, 0}, Leaf{0x000206F2, 0x00400800, 0x02BEE3FF, 0xBFEBFBFF}}, + }); + const auto info = GetX86Info(); + + EXPECT_EQ(info.family, 0x06); + EXPECT_EQ(info.model, 0x2F); + EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_WSM); + +#if (_WIN32_WINNT < 0x0601) // before Win7 + EXPECT_FALSE(info.features.ssse3); + EXPECT_FALSE(info.features.sse4_1); + EXPECT_FALSE(info.features.sse4_2); +#else + EXPECT_TRUE(info.features.ssse3); + EXPECT_TRUE(info.features.sse4_1); + EXPECT_TRUE(info.features.sse4_2); +#endif +} +#endif // CPU_FEATURES_OS_WINDOWS + // TODO(user): test what happens when xsave/osxsave are not present. // TODO(user): test what happens when xmm/ymm/zmm os support are not // present. diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/CMakeLists.txt b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/CMakeLists.txt index 0d8244882..035c8038f 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/CMakeLists.txt +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/CMakeLists.txt @@ -532,10 +532,11 @@ if(NOT (CMAKE_GENERATOR STREQUAL Xcode)) PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ) if(USE_CPU_FEATURES) - if(CpuFeatures_FOUND) + set_source_files_properties(volk_gnsssdr_cpu.c PROPERTIES COMPILE_DEFINITIONS "VOLK_CPU_FEATURES=1") + if(CPUFEATURES_FOUND) target_include_directories(volk_gnsssdr_obj PRIVATE - $ + $ ) else() target_include_directories(volk_gnsssdr_obj @@ -548,6 +549,10 @@ if(NOT (CMAKE_GENERATOR STREQUAL Xcode)) if(NOT MSVC) set_target_properties(volk_gnsssdr_obj PROPERTIES COMPILE_FLAGS "-fPIC") endif() +else() + if(USE_CPU_FEATURES) + set_source_files_properties(volk_gnsssdr_cpu.c PROPERTIES COMPILE_DEFINITIONS "VOLK_CPU_FEATURES=1") + endif() endif() # Add dynamic library @@ -557,10 +562,10 @@ else() add_library(volk_gnsssdr SHARED $) endif() if(USE_CPU_FEATURES) - if(CpuFeatures_FOUND) + if(CPUFEATURES_FOUND) target_link_libraries(volk_gnsssdr PUBLIC ${volk_gnsssdr_libraries} - PRIVATE CpuFeatures::cpu_features + PRIVATE CpuFeature::cpu_features ) else() target_link_libraries(volk_gnsssdr @@ -580,10 +585,10 @@ target_include_directories(volk_gnsssdr PUBLIC $ ) if(USE_CPU_FEATURES) - if(CpuFeatures_FOUND) + if(CPUFEATURES_FOUND) target_include_directories(volk_gnsssdr PRIVATE - $ + $ ) else() target_include_directories(volk_gnsssdr @@ -620,9 +625,9 @@ if(ENABLE_STATIC_LIBS) endif() target_link_libraries(volk_gnsssdr_static PUBLIC ${volk_gnsssdr_libraries}) if(USE_CPU_FEATURES) - if(CpuFeatures_FOUND) + if(CPUFEATURES_FOUND) target_link_libraries(volk_gnsssdr_static - PRIVATE CpuFeatures::cpu_features + PRIVATE CpuFeature::cpu_features ) else() target_link_libraries(volk_gnsssdr_static diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/tmpl/volk_gnsssdr_cpu.tmpl.c b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/tmpl/volk_gnsssdr_cpu.tmpl.c index ace129dad..d0db27e89 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/tmpl/volk_gnsssdr_cpu.tmpl.c +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/tmpl/volk_gnsssdr_cpu.tmpl.c @@ -14,6 +14,7 @@ #include // clang-format on +#if defined(VOLK_CPU_FEATURES) #include "cpu_features_macros.h" #if defined(CPU_FEATURES_ARCH_X86) #include "cpuinfo_x86.h" @@ -31,6 +32,7 @@ #if defined(__cplusplus) using namespace cpu_features; #endif +#endif struct VOLK_CPU volk_gnsssdr_cpu; diff --git a/src/algorithms/signal_source/libs/rtl_tcp_dongle_info.cc b/src/algorithms/signal_source/libs/rtl_tcp_dongle_info.cc index 0dfcadb2a..a89963f95 100644 --- a/src/algorithms/signal_source/libs/rtl_tcp_dongle_info.cc +++ b/src/algorithms/signal_source/libs/rtl_tcp_dongle_info.cc @@ -33,11 +33,11 @@ boost::system::error_code Rtl_Tcp_Dongle_Info::read(boost::asio::ip::tcp::socket { boost::system::error_code ec; - unsigned char data[sizeof(char) * 4 + sizeof(uint32_t) * 2]; + std::vector data(sizeof(char) * 4 + sizeof(uint32_t) * 2); size_t received_bits = socket.receive(boost::asio::buffer(data), 0, ec); if (!ec && (received_bits > 0)) { - std::memcpy(magic_, data, 4); + std::memcpy(magic_, data.data(), 4); uint32_t type; std::memcpy(&type, &data[4], 4); diff --git a/src/algorithms/tracking/gnuradio_blocks/galileo_e1_tcp_connector_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/galileo_e1_tcp_connector_tracking_cc.cc index 03ee2f82c..7f6262d58 100644 --- a/src/algorithms/tracking/gnuradio_blocks/galileo_e1_tcp_connector_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/galileo_e1_tcp_connector_tracking_cc.cc @@ -178,8 +178,7 @@ void Galileo_E1_Tcp_Connector_Tracking_cc::start_tracking() d_carrier_doppler_hz = d_acq_carrier_doppler_hz; d_current_prn_length_samples = d_vector_length; - std::string sys_ = &d_acquisition_gnss_synchro->System; - sys = sys_.substr(0, 1); + sys = std::string(1, d_acquisition_gnss_synchro->System); // DEBUG OUTPUT std::cout << "Tracking of Galileo E1 signal started on channel " << d_channel << " for satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << '\n'; diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc index 04f88b999..e1fb1f44b 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_cc.cc @@ -263,8 +263,7 @@ void glonass_l1_ca_dll_pll_c_aid_tracking_cc::start_tracking() d_pll_to_dll_assist_secs_Ti = 0.0; d_code_phase_samples = d_acq_code_phase_samples; - const std::string sys_ = &d_acquisition_gnss_synchro->System; - sys = sys_.substr(0, 1); + sys = std::string(1, d_acquisition_gnss_synchro->System); d_acc_carrier_phase_initialized = false; // DEBUG OUTPUT diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc index 9162f7bcc..f8fbe3b56 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_c_aid_tracking_sc.cc @@ -263,8 +263,7 @@ void glonass_l1_ca_dll_pll_c_aid_tracking_sc::start_tracking() d_pll_to_dll_assist_secs_Ti = 0.0; d_code_phase_samples = d_acq_code_phase_samples; - const std::string sys_ = &d_acquisition_gnss_synchro->System; - sys = sys_.substr(0, 1); + sys = std::string(1, d_acquisition_gnss_synchro->System); d_acc_carrier_phase_initialized = false; // DEBUG OUTPUT diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.cc index 242469b0a..06f5914cd 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l1_ca_dll_pll_tracking_cc.cc @@ -205,8 +205,7 @@ void Glonass_L1_Ca_Dll_Pll_Tracking_cc::start_tracking() d_code_phase_samples = d_acq_code_phase_samples; - const std::string sys_ = &d_acquisition_gnss_synchro->System; - sys = sys_.substr(0, 1); + sys = std::string(1, d_acquisition_gnss_synchro->System); d_acc_carrier_phase_initialized = false; // DEBUG OUTPUT diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_cc.cc index 485b0d93f..16f1dbc58 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_cc.cc @@ -259,8 +259,7 @@ void glonass_l2_ca_dll_pll_c_aid_tracking_cc::start_tracking() d_pll_to_dll_assist_secs_Ti = 0.0; d_code_phase_samples = d_acq_code_phase_samples; - const std::string sys_ = &d_acquisition_gnss_synchro->System; - sys = sys_.substr(0, 1); + sys = std::string(1, d_acquisition_gnss_synchro->System); // DEBUG OUTPUT std::cout << "Tracking of GLONASS L2 C/A signal started on channel " << d_channel << " for satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << '\n'; diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_sc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_sc.cc index 5dfcb2d53..2f3e66890 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_sc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_c_aid_tracking_sc.cc @@ -260,8 +260,7 @@ void glonass_l2_ca_dll_pll_c_aid_tracking_sc::start_tracking() d_pll_to_dll_assist_secs_Ti = 0.0; d_code_phase_samples = d_acq_code_phase_samples; - const std::string sys_ = &d_acquisition_gnss_synchro->System; - sys = sys_.substr(0, 1); + sys = std::string(1, d_acquisition_gnss_synchro->System); // DEBUG OUTPUT std::cout << "Tracking of GLONASS L2 C/A signal started on channel " << d_channel << " for satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << '\n'; diff --git a/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_tracking_cc.cc index 0f3ae0abb..42041eec1 100644 --- a/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/glonass_l2_ca_dll_pll_tracking_cc.cc @@ -206,8 +206,7 @@ void Glonass_L2_Ca_Dll_Pll_Tracking_cc::start_tracking() d_code_phase_samples = d_acq_code_phase_samples; - const std::string sys_ = &d_acquisition_gnss_synchro->System; - sys = sys_.substr(0, 1); + sys = std::string(1, d_acquisition_gnss_synchro->System); // DEBUG OUTPUT std::cout << "Tracking of GLONASS L2 C/A signal started on channel " << d_channel << " for satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << '\n'; diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_gpu_cc.cc b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_gpu_cc.cc index 858244669..45d274b9f 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_gpu_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_dll_pll_tracking_gpu_cc.cc @@ -218,8 +218,7 @@ void Gps_L1_Ca_Dll_Pll_Tracking_GPU_cc::start_tracking() d_pll_to_dll_assist_secs_Ti = 0.0; d_code_phase_samples = d_acq_code_phase_samples; - const std::string sys_ = &d_acquisition_gnss_synchro->System; - sys = sys_.substr(0, 1); + sys = std::string(1, d_acquisition_gnss_synchro->System); // DEBUG OUTPUT std::cout << "Tracking of GPS L1 C/A signal started on channel " << d_channel << " for satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << '\n'; diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_kf_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_kf_tracking_cc.cc index f1fb20c82..560992b45 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_kf_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_kf_tracking_cc.cc @@ -302,8 +302,7 @@ void Gps_L1_Ca_Kf_Tracking_cc::start_tracking() d_code_phase_samples = d_acq_code_phase_samples; - std::string sys_ = &d_acquisition_gnss_synchro->System; - sys = sys_.substr(0, 1); + sys = std::string(1, d_acquisition_gnss_synchro->System); // DEBUG OUTPUT std::cout << "Tracking of GPS L1 C/A signal started on channel " << d_channel << " for satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << '\n'; diff --git a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_tcp_connector_tracking_cc.cc b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_tcp_connector_tracking_cc.cc index 7d964cdfe..06b2c262e 100644 --- a/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_tcp_connector_tracking_cc.cc +++ b/src/algorithms/tracking/gnuradio_blocks/gps_l1_ca_tcp_connector_tracking_cc.cc @@ -203,8 +203,7 @@ void Gps_L1_Ca_Tcp_Connector_Tracking_cc::start_tracking() d_code_phase_samples = d_acq_code_phase_samples; - std::string sys_ = &d_acquisition_gnss_synchro->System; - sys = sys_.substr(0, 1); + sys = std::string(1, d_acquisition_gnss_synchro->System); // DEBUG OUTPUT std::cout << "Tracking of GPS L1 C/A signal started on channel " << d_channel << " for satellite " << Gnss_Satellite(systemName[sys], d_acquisition_gnss_synchro->PRN) << '\n'; diff --git a/src/core/libs/gnss_sdr_supl_client.cc b/src/core/libs/gnss_sdr_supl_client.cc index 10dda2be4..e079b0a9f 100644 --- a/src/core/libs/gnss_sdr_supl_client.cc +++ b/src/core/libs/gnss_sdr_supl_client.cc @@ -19,6 +19,7 @@ #include "gnss_sdr_supl_client.h" #include "GPS_L1_CA.h" +#include "MATH_CONSTANTS.h" #include #include #include @@ -833,7 +834,7 @@ bool Gnss_Sdr_Supl_Client::load_gal_almanac_xml(const std::string& file_name) } catch (std::exception& e) { - // Maybe the file is from https://www.gsc-europa.eu/system-status/almanac-data ? + // Maybe the file is from https://www.gsc-europa.eu/product-almanacs ? return this->read_gal_almanac_from_gsa(file_name); } LOG(INFO) << "Loaded Galileo almanac map data with " << this->gal_almanac_map.size() << " satellites"; @@ -858,6 +859,7 @@ bool Gnss_Sdr_Supl_Client::read_gal_almanac_from_gsa(const std::string& file_nam Galileo_Almanac gal_alm; try { + const double sqrtAnominal = 5440.588203494; // square root of Galileo nominal orbit semi-major axis uint32_t prn = static_cast(std::stoi(almanac.child_value("SVID"))); gal_alm.PRN = prn; gal_alm.toa = std::stoi(almanac.child("almanac").child_value("t0a")); @@ -866,7 +868,7 @@ bool Gnss_Sdr_Supl_Client::read_gal_almanac_from_gsa(const std::string& file_nam gal_alm.delta_i = std::stod(almanac.child("almanac").child_value("deltai")); gal_alm.M_0 = std::stod(almanac.child("almanac").child_value("m0")); gal_alm.ecc = std::stod(almanac.child("almanac").child_value("ecc")); - gal_alm.sqrtA = std::stod(almanac.child("almanac").child_value("aSqRoot")); + gal_alm.sqrtA = std::stod(almanac.child("almanac").child_value("aSqRoot")) + sqrtAnominal; gal_alm.OMEGA_0 = std::stod(almanac.child("almanac").child_value("omega0")); gal_alm.omega = std::stod(almanac.child("almanac").child_value("w")); gal_alm.OMEGAdot = std::stod(almanac.child("almanac").child_value("omegaDot")); diff --git a/src/core/system_parameters/CMakeLists.txt b/src/core/system_parameters/CMakeLists.txt index e88306991..49d8fdb80 100644 --- a/src/core/system_parameters/CMakeLists.txt +++ b/src/core/system_parameters/CMakeLists.txt @@ -6,6 +6,7 @@ set(SYSTEM_PARAMETERS_SOURCES + gnss_almanac.cc gnss_ephemeris.cc gnss_satellite.cc gnss_signal.cc diff --git a/src/core/system_parameters/beidou_dnav_almanac.h b/src/core/system_parameters/beidou_dnav_almanac.h index 03610990f..6bf616fc6 100644 --- a/src/core/system_parameters/beidou_dnav_almanac.h +++ b/src/core/system_parameters/beidou_dnav_almanac.h @@ -36,7 +36,10 @@ public: /*! * Default constructor */ - Beidou_Dnav_Almanac() = default; + Beidou_Dnav_Almanac() + { + this->System = 'B'; + }; int SV_health{}; //!< SV Health diff --git a/src/core/system_parameters/galileo_almanac.h b/src/core/system_parameters/galileo_almanac.h index a76a3af66..9b65f84bd 100644 --- a/src/core/system_parameters/galileo_almanac.h +++ b/src/core/system_parameters/galileo_almanac.h @@ -36,7 +36,10 @@ public: /*! * Default constructor */ - Galileo_Almanac() = default; + Galileo_Almanac() + { + this->System = 'E'; + }; int32_t IODa{}; int32_t E5b_HS{}; diff --git a/src/core/system_parameters/gnss_almanac.cc b/src/core/system_parameters/gnss_almanac.cc new file mode 100644 index 000000000..923416832 --- /dev/null +++ b/src/core/system_parameters/gnss_almanac.cc @@ -0,0 +1,275 @@ +/*! + * \file gnss_almanac.cc + * \brief Base class for GNSS almanac storage + * \author Carles Fernandez, 2022. cfernandez(at)cttc.es + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2022 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#include "gnss_almanac.h" +#include "MATH_CONSTANTS.h" +#include "gnss_frequencies.h" +#include +#include +#include +#include +#include + +double Gnss_Almanac::check_t(double time) const +{ + const double half_week = 302400.0; // seconds + double corrTime = time; + if (time > half_week) + { + corrTime = time - 2.0 * half_week; + } + else if (time < -half_week) + { + corrTime = time + 2.0 * half_week; + } + return corrTime; +} + +double Gnss_Almanac::predicted_doppler(double rx_time_s, + double lat, + double lon, + double h, + double ve, + double vn, + double vu, + int band) const +{ + const double RE_WGS84 = 6378137.0; //!< earth semimajor axis (WGS84) (m) + const double FE_WGS84 = (1.0 / 298.257223563); //!< earth flattening (WGS84) + const double lat_rad = lat * D2R; + const double lon_rad = lon * D2R; + + const double sinp = sin(lat_rad); + const double cosp = cos(lat_rad); + const double sinl = sin(lon_rad); + const double cosl = cos(lon_rad); + + const double e2 = FE_WGS84 * (2.0 - FE_WGS84); + const double v = RE_WGS84 / std::sqrt(1.0 - e2 * sinp * sinp); + + // Position in EFEF + const std::vector pos_rx = {(v + h) * cosp * cosl, (v + h) * cosp * sinl, (v * (1.0 - e2) + h) * sinp}; + + // Velocity in EFEF + const double t = cosp * vu - sinp * vn; + const std::vector vel_rx = {cosl * t - sinl * ve, sinl * t + cosl * ve, sinp * vu + cosp * vn}; + + std::array sat_pos_vel = {0}; + satellitePosVelComputation(rx_time_s, sat_pos_vel); + const std::vector pos_sat = {sat_pos_vel[0], sat_pos_vel[1], sat_pos_vel[2]}; + const std::vector vel_sat = {sat_pos_vel[3], sat_pos_vel[4], sat_pos_vel[5]}; + + std::vector x_sr = pos_sat; + std::transform(x_sr.begin(), x_sr.end(), pos_rx.begin(), x_sr.begin(), std::minus()); // pos_sat - pos_rx + + const double norm_x_sr = std::sqrt(std::inner_product(x_sr.begin(), x_sr.end(), x_sr.begin(), 0.0)); // Euclidean norm + + std::vector v_sr = vel_sat; + std::transform(v_sr.begin(), v_sr.end(), vel_rx.begin(), v_sr.begin(), std::minus()); // vel_sat - vel_rx + + const double radial_vel = std::inner_product(v_sr.begin(), v_sr.end(), x_sr.begin(), 0.0) / norm_x_sr; + const double predicted_doppler_normalized = -(radial_vel / SPEED_OF_LIGHT_M_S); + double predicted_doppler = 0.0; + if (this->System == 'E') // Galileo + { + if (band == 1) + { + predicted_doppler = predicted_doppler_normalized * FREQ1; + } + else if (band == 5) + { + predicted_doppler = predicted_doppler_normalized * FREQ5; + } + else if (band == 6) + { + predicted_doppler = predicted_doppler_normalized * FREQ6; + } + else if (band == 7) + { + predicted_doppler = predicted_doppler_normalized * FREQ7; + } + else if (band == 8) + { + predicted_doppler = predicted_doppler_normalized * FREQ8; + } + else + { + predicted_doppler = 0.0; + } + } + else if (this->System == 'G') // GPS + { + if (band == 1) + { + predicted_doppler = predicted_doppler_normalized * FREQ1; + } + else if (band == 2) + { + predicted_doppler = predicted_doppler_normalized * FREQ2; + } + else if (band == 5) + { + predicted_doppler = predicted_doppler_normalized * FREQ5; + } + else + { + predicted_doppler = 0.0; + } + } + else if (this->System == 'B') // Beidou + { + if (band == 1) + { + predicted_doppler = predicted_doppler_normalized * FREQ1_BDS; + } + else if (band == 2) + { + predicted_doppler = predicted_doppler_normalized * FREQ2_BDS; + } + else if (band == 3) + { + predicted_doppler = predicted_doppler_normalized * FREQ3_BDS; + } + else + { + predicted_doppler = 0.0; + } + } + else + { + predicted_doppler = 0.0; + } + return predicted_doppler; +} + + +void Gnss_Almanac::satellitePosVelComputation(double transmitTime, std::array& pos_vel_dtr) const +{ + // Restore semi-major axis + const double a = this->sqrtA * this->sqrtA; + + // Computed mean motion + double n; + if (this->System == 'E') + { + n = sqrt(GALILEO_GM / (a * a * a)); + } + else if (this->System == 'B') + { + n = sqrt(BEIDOU_GM / (a * a * a)); + } + else + { + n = sqrt(GPS_GM / (a * a * a)); + } + + // Time from ephemeris reference epoch + const double tk = check_t(transmitTime - static_cast(this->toa)); + + // Mean anomaly + const double M = this->M_0 * GNSS_PI + n * tk; + + // Initial guess of eccentric anomaly + double E = M; + double E_old; + double dE; + + // --- Iteratively compute eccentric anomaly ------------------------------- + for (int32_t ii = 1; ii < 20; ii++) + { + E_old = E; + E = M + this->ecc * sin(E); + dE = fmod(E - E_old, 2.0 * GNSS_PI); + if (fabs(dE) < 1e-12) + { + // Necessary precision is reached, exit from the loop + break; + } + } + + const double sek = sin(E); + const double cek = cos(E); + const double OneMinusecosE = 1.0 - this->ecc * cek; + const double sq1e2 = sqrt(1.0 - this->ecc * this->ecc); + const double ekdot = n / OneMinusecosE; + + // Compute the true anomaly + const double tmp_Y = sq1e2 * sek; + const double tmp_X = cek - this->ecc; + const double nu = atan2(tmp_Y, tmp_X); + + // Compute angle phi (argument of Latitude) + const double phi = nu + this->omega * GNSS_PI; + + const double pkdot = sq1e2 * ekdot / OneMinusecosE; + + // Correct argument of latitude + const double suk = sin(phi); + const double cuk = cos(phi); + + // Correct radius + const double r = a * OneMinusecosE; + const double rkdot = a * this->ecc * sek * ekdot; + + // Correct inclination + double i; + if (this->System == 'E') + { + i = ((56.0 / 180.0) + this->delta_i) * GNSS_PI; + } + else + { + i = (0.3 + this->delta_i) * GNSS_PI; + } + + const double sik = sin(i); + const double cik = cos(i); + + // Compute the angle between the ascending node and the Greenwich meridian + double Omega; + double Omega_dot; + if (this->System == 'B') + { + Omega_dot = this->OMEGAdot * GNSS_PI - BEIDOU_OMEGA_EARTH_DOT; + Omega = this->OMEGA_0 * GNSS_PI + Omega_dot * tk - BEIDOU_OMEGA_EARTH_DOT * static_cast(this->toa); + } + else + { + Omega_dot = this->OMEGAdot * GNSS_PI - GNSS_OMEGA_EARTH_DOT; + Omega = this->OMEGA_0 * GNSS_PI + Omega_dot * tk - GNSS_OMEGA_EARTH_DOT * static_cast(this->toa); + } + + const double sok = sin(Omega); + const double cok = cos(Omega); + + // --- Compute satellite coordinates in Earth-fixed coordinates + const double xprime = r * cuk; + const double yprime = r * suk; + + pos_vel_dtr[0] = xprime * cok - yprime * cik * sok; + pos_vel_dtr[1] = xprime * sok + yprime * cik * cok; + pos_vel_dtr[2] = yprime * sik; + + // Satellite's velocity + const double xpkdot = rkdot * cuk - yprime * pkdot; + const double ypkdot = rkdot * suk + xprime * pkdot; + const double tmp = ypkdot * cik; + + pos_vel_dtr[3] = -Omega_dot * pos_vel_dtr[1] + xpkdot * cok - tmp * sok; + pos_vel_dtr[4] = Omega_dot * pos_vel_dtr[0] + xpkdot * sok + tmp * cok; + pos_vel_dtr[5] = ypkdot * sik; + pos_vel_dtr[6] = 0; +} diff --git a/src/core/system_parameters/gnss_almanac.h b/src/core/system_parameters/gnss_almanac.h index 2206f4acc..a8c265a80 100644 --- a/src/core/system_parameters/gnss_almanac.h +++ b/src/core/system_parameters/gnss_almanac.h @@ -18,6 +18,7 @@ #ifndef GNSS_SDR_GNSS_ALMANAC_H #define GNSS_SDR_GNSS_ALMANAC_H +#include #include /** \addtogroup Core @@ -37,6 +38,46 @@ public: */ Gnss_Almanac() = default; + /*! + * \brief Computes prediction of the Doppler shift for a given time and receiver's position and velocity. + * \f[ + * f_{d} = - \mathbf{v} \frac{\mathbf{x}^{T}}{\left| \mathbf{x} \right| } \frac{f_{L}}{c} + * \f] + * where: + * \f[ + * \mathbf{v} = \mathbf{v}_{sat} - \mathbf{v}_{rx} + * \f] + * \f[ + * \mathbf{x} = \mathbf{x}_{sat} - \mathbf{x}_{rx} + * \f] + * \f[ + * \left| \mathbf{x} \right| = \sqrt{\mathbf{x}\mathbf{x}^{T}} + * \f] + * + * @param[in] rx_time_s Time of Week in seconds + * @param[in] lat Receiver's latitude in degrees + * @param[in] lon Receiver's longitude in degrees + * @param[in] h Receiver's height in meters + * @param[in] ve Receiver's velocity in the East direction [m/s] + * @param[in] vn Receiver's velocity in the North direction [m/s] + * @param[in] vu Receiver's velocity in the Up direction [m/s] + * @param[in] band Signal band for which the Doppler will be computed + * (1: L1 C/A, E1B, BI1; 2: L2C, BI2; 3: BI3; 5: L5/E5a; 6: E6B; 7: E5b; 8: E5a+E5b) + */ + double predicted_doppler(double rx_time_s, + double lat, + double lon, + double h, + double ve, + double vn, + double vu, + int band) const; + + /*! + * \brief Computes satellite Position and Velocity, in ECEF, for a given time (expressed in seconds of week) + */ + void satellitePosVelComputation(double transmitTime, std::array& pos_vel_dtr) const; + uint32_t PRN{}; //!< SV PRN NUMBER double delta_i{}; //!< Inclination Angle at Reference Time (relative to i_0 = 0.30 semi-circles) int32_t toa{}; //!< Almanac data reference time of week [s] @@ -49,6 +90,11 @@ public: double OMEGAdot{}; //!< Rate of Right Ascension [semi-circles/s] double af0{}; //!< Coefficient 0 of code phase offset model [s] double af1{}; //!< Coefficient 1 of code phase offset model [s/s] + +protected: + char System{}; //!< Character ID of the GNSS system. 'G': GPS. 'E': Galileo. 'B': BeiDou +private: + double check_t(double time) const; }; diff --git a/src/core/system_parameters/gnss_ephemeris.cc b/src/core/system_parameters/gnss_ephemeris.cc index 101fbf63c..d95d14a28 100644 --- a/src/core/system_parameters/gnss_ephemeris.cc +++ b/src/core/system_parameters/gnss_ephemeris.cc @@ -17,10 +17,156 @@ #include "gnss_ephemeris.h" #include "MATH_CONSTANTS.h" +#include "gnss_frequencies.h" +#include #include +#include +#include +#include + + +double Gnss_Ephemeris::sv_clock_drift(double transmitTime) +{ + const double dt = check_t(transmitTime - this->toc); + this->dtr = sv_clock_relativistic_term(transmitTime); + this->satClkDrift = this->af0 + this->af1 * dt + this->af2 * (dt * dt) + this->dtr; + return this->satClkDrift; +} + + +double Gnss_Ephemeris::predicted_doppler(double rx_time_s, + double lat, + double lon, + double h, + double ve, + double vn, + double vu, + int band) const +{ + const double RE_WGS84 = 6378137.0; //!< earth semimajor axis (WGS84) (m) + const double FE_WGS84 = (1.0 / 298.257223563); //!< earth flattening (WGS84) + const double lat_rad = lat * D2R; + const double lon_rad = lon * D2R; + + const double sinp = sin(lat_rad); + const double cosp = cos(lat_rad); + const double sinl = sin(lon_rad); + const double cosl = cos(lon_rad); + + const double e2 = FE_WGS84 * (2.0 - FE_WGS84); + const double v = RE_WGS84 / std::sqrt(1.0 - e2 * sinp * sinp); + + // Position in EFEF + const std::vector pos_rx = {(v + h) * cosp * cosl, (v + h) * cosp * sinl, (v * (1.0 - e2) + h) * sinp}; + + // Velocity in EFEF + const double t = cosp * vu - sinp * vn; + const std::vector vel_rx = {cosl * t - sinl * ve, sinl * t + cosl * ve, sinp * vu + cosp * vn}; + + std::array sat_pos_vel = {0}; + satellitePosVelComputation(rx_time_s, sat_pos_vel); + const std::vector pos_sat = {sat_pos_vel[0], sat_pos_vel[1], sat_pos_vel[2]}; + const std::vector vel_sat = {sat_pos_vel[3], sat_pos_vel[4], sat_pos_vel[5]}; + + std::vector x_sr = pos_sat; + std::transform(x_sr.begin(), x_sr.end(), pos_rx.begin(), x_sr.begin(), std::minus()); // pos_sat - pos_rx + + const double norm_x_sr = std::sqrt(std::inner_product(x_sr.begin(), x_sr.end(), x_sr.begin(), 0.0)); // Euclidean norm + + std::vector v_sr = vel_sat; + std::transform(v_sr.begin(), v_sr.end(), vel_rx.begin(), v_sr.begin(), std::minus()); // vel_sat - vel_rx + + const double radial_vel = std::inner_product(v_sr.begin(), v_sr.end(), x_sr.begin(), 0.0) / norm_x_sr; + const double predicted_doppler_normalized = -(radial_vel / SPEED_OF_LIGHT_M_S); + double predicted_doppler = 0.0; + if (this->System == 'E') // Galileo + { + if (band == 1) + { + predicted_doppler = predicted_doppler_normalized * FREQ1; + } + else if (band == 5) + { + predicted_doppler = predicted_doppler_normalized * FREQ5; + } + else if (band == 6) + { + predicted_doppler = predicted_doppler_normalized * FREQ6; + } + else if (band == 7) + { + predicted_doppler = predicted_doppler_normalized * FREQ7; + } + else if (band == 8) + { + predicted_doppler = predicted_doppler_normalized * FREQ8; + } + else + { + predicted_doppler = 0.0; + } + } + else if (this->System == 'G') // GPS + { + if (band == 1) + { + predicted_doppler = predicted_doppler_normalized * FREQ1; + } + else if (band == 2) + { + predicted_doppler = predicted_doppler_normalized * FREQ2; + } + else if (band == 5) + { + predicted_doppler = predicted_doppler_normalized * FREQ5; + } + else + { + predicted_doppler = 0.0; + } + } + else if (this->System == 'B') // Beidou + { + if (band == 1) + { + predicted_doppler = predicted_doppler_normalized * FREQ1_BDS; + } + else if (band == 2) + { + predicted_doppler = predicted_doppler_normalized * FREQ2_BDS; + } + else if (band == 3) + { + predicted_doppler = predicted_doppler_normalized * FREQ3_BDS; + } + else + { + predicted_doppler = 0.0; + } + } + else + { + predicted_doppler = 0.0; + } + return predicted_doppler; +} void Gnss_Ephemeris::satellitePosition(double transmitTime) +{ + std::array pos_vel_dtr = {0}; + satellitePosVelComputation(transmitTime, pos_vel_dtr); + this->satpos_X = pos_vel_dtr[0]; + this->satpos_Y = pos_vel_dtr[1]; + this->satpos_Z = pos_vel_dtr[2]; + this->satvel_X = pos_vel_dtr[3]; + this->satvel_Y = pos_vel_dtr[4]; + this->satvel_Z = pos_vel_dtr[5]; + this->dtr = pos_vel_dtr[6]; +} + + +void Gnss_Ephemeris::satellitePosVelComputation(double transmitTime, std::array& pos_vel_dtr) const { // Restore semi-major axis const double a = this->sqrtA * this->sqrtA; @@ -47,10 +193,7 @@ void Gnss_Ephemeris::satellitePosition(double transmitTime) const double n = n0 + this->delta_n; // Mean anomaly - double M = this->M_0 + n * tk; - - // Reduce mean anomaly to between 0 and 2pi - M = fmod((M + 2.0 * GNSS_PI), (2.0 * GNSS_PI)); + const double M = this->M_0 + n * tk; // Initial guess of eccentric anomaly double E = M; @@ -82,10 +225,9 @@ void Gnss_Ephemeris::satellitePosition(double transmitTime) const double nu = atan2(tmp_Y, tmp_X); // Compute angle phi (argument of Latitude) - double phi = nu + this->omega; + const double phi = nu + this->omega; // Reduce phi to between 0 and 2*pi rad - phi = fmod((phi), (2.0 * GNSS_PI)); const double s2pk = sin(2.0 * phi); const double c2pk = cos(2.0 * phi); const double pkdot = sq1e2 * ekdot / OneMinusecosE; @@ -120,53 +262,59 @@ void Gnss_Ephemeris::satellitePosition(double transmitTime) Omega = this->OMEGA_0 + Omega_dot * tk - GNSS_OMEGA_EARTH_DOT * static_cast(this->toe); } - // Reduce to between 0 and 2*pi rad - Omega = fmod((Omega + 2.0 * GNSS_PI), (2.0 * GNSS_PI)); const double sok = sin(Omega); const double cok = cos(Omega); // --- Compute satellite coordinates in Earth-fixed coordinates const double xprime = r * cuk; const double yprime = r * suk; - this->satpos_X = xprime * cok - yprime * cik * sok; - this->satpos_Y = xprime * sok + yprime * cik * cok; // ********NOTE: in GALILEO ICD this expression is not correct because it has minus (- sin(u) * r * cos(i) * cos(Omega)) instead of plus - this->satpos_Z = yprime * sik; + + pos_vel_dtr[0] = xprime * cok - yprime * cik * sok; + pos_vel_dtr[1] = xprime * sok + yprime * cik * cok; // ********NOTE: in GALILEO ICD this expression is not correct because it has minus (- sin(u) * r * cos(i) * cos(Omega)) instead of plus + pos_vel_dtr[2] = yprime * sik; // Satellite's velocity. Can be useful for Vector Tracking loops const double xpkdot = rkdot * cuk - yprime * ukdot; const double ypkdot = rkdot * suk + xprime * ukdot; - const double tmp = ypkdot * cik - this->satpos_Z * ikdot; + const double tmp = ypkdot * cik - pos_vel_dtr[2] * ikdot; - this->satvel_X = -Omega_dot * this->satpos_Y + xpkdot * cok - tmp * sok; - this->satvel_Y = Omega_dot * this->satpos_X + xpkdot * sok + tmp * cok; - this->satvel_Z = yprime * cik * ikdot + ypkdot * sik; + pos_vel_dtr[3] = -Omega_dot * pos_vel_dtr[1] + xpkdot * cok - tmp * sok; + pos_vel_dtr[4] = Omega_dot * pos_vel_dtr[0] + xpkdot * sok + tmp * cok; + pos_vel_dtr[5] = yprime * cik * ikdot + ypkdot * sik; // Time from ephemeris reference clock tk = check_t(transmitTime - this->toc); - this->dtr = this->af0 + this->af1 * tk + this->af2 * tk * tk; + pos_vel_dtr[6] = this->af0 + this->af1 * tk + this->af2 * tk * tk; if (this->System == 'E') { - this->dtr -= 2.0 * sqrt(GALILEO_GM * a) * this->ecc * sek / (SPEED_OF_LIGHT_M_S * SPEED_OF_LIGHT_M_S); + pos_vel_dtr[6] -= 2.0 * sqrt(GALILEO_GM * a) * this->ecc * sek / (SPEED_OF_LIGHT_M_S * SPEED_OF_LIGHT_M_S); } else if (this->System == 'B') { - this->dtr -= 2.0 * sqrt(BEIDOU_GM * a) * this->ecc * sek / (SPEED_OF_LIGHT_M_S * SPEED_OF_LIGHT_M_S); + pos_vel_dtr[6] -= 2.0 * sqrt(BEIDOU_GM * a) * this->ecc * sek / (SPEED_OF_LIGHT_M_S * SPEED_OF_LIGHT_M_S); } else { - this->dtr -= 2.0 * sqrt(GPS_GM * a) * this->ecc * sek / (SPEED_OF_LIGHT_M_S * SPEED_OF_LIGHT_M_S); + pos_vel_dtr[6] -= 2.0 * sqrt(GPS_GM * a) * this->ecc * sek / (SPEED_OF_LIGHT_M_S * SPEED_OF_LIGHT_M_S); } } -double Gnss_Ephemeris::sv_clock_drift(double transmitTime) +double Gnss_Ephemeris::check_t(double time) const { - const double dt = check_t(transmitTime - this->toc); - this->dtr = sv_clock_relativistic_term(transmitTime); - this->satClkDrift = this->af0 + this->af1 * dt + this->af2 * (dt * dt) + this->dtr; - return this->satClkDrift; + const double half_week = 302400.0; // seconds + double corrTime = time; + if (time > half_week) + { + corrTime = time - 2.0 * half_week; + } + else if (time < -half_week) + { + corrTime = time + 2.0 * half_week; + } + return corrTime; } @@ -184,7 +332,7 @@ double Gnss_Ephemeris::sv_clock_relativistic_term(double transmitTime) const { n0 = sqrt(GALILEO_GM / (a * a * a)); } - else if (this->System == 'E') + else if (this->System == 'B') { n0 = sqrt(BEIDOU_GM / (a * a * a)); } @@ -198,9 +346,6 @@ double Gnss_Ephemeris::sv_clock_relativistic_term(double transmitTime) const // Mean anomaly const double M = this->M_0 + n * tk; - // Reduce mean anomaly to between 0 and 2pi - // M = fmod((M + 2.0 * GNSS_PI), (2.0 * GNSS_PI)); - // Initial guess of eccentric anomaly double E = M; double E_old; @@ -235,19 +380,3 @@ double Gnss_Ephemeris::sv_clock_relativistic_term(double transmitTime) const } return dtr_; } - - -double Gnss_Ephemeris::check_t(double time) const -{ - const double half_week = 302400.0; // seconds - double corrTime = time; - if (time > half_week) - { - corrTime = time - 2.0 * half_week; - } - else if (time < -half_week) - { - corrTime = time + 2.0 * half_week; - } - return corrTime; -} diff --git a/src/core/system_parameters/gnss_ephemeris.h b/src/core/system_parameters/gnss_ephemeris.h index 644f430d4..c3f9a8e78 100644 --- a/src/core/system_parameters/gnss_ephemeris.h +++ b/src/core/system_parameters/gnss_ephemeris.h @@ -19,6 +19,7 @@ #ifndef GNSS_SDR_GNSS_EPHEMERIS_H #define GNSS_SDR_GNSS_EPHEMERIS_H +#include #include /*! @@ -36,6 +37,34 @@ public: */ double sv_clock_drift(double transmitTime); + /*! + * \brief Computes prediction of the Doppler shift for a given time and receiver's position and velocity. + * \f[ + * f_{d} = - \mathbf{v} \frac{\mathbf{x}^{T}}{\left| \mathbf{x} \right| } \frac{f_{L}}{c} + * \f] + * where: + * \f[ + * \mathbf{v} = \mathbf{v}_{sat} - \mathbf{v}_{rx} + * \f] + * \f[ + * \mathbf{x} = \mathbf{x}_{sat} - \mathbf{x}_{rx} + * \f] + * \f[ + * \left| \mathbf{x} \right| = \sqrt{\mathbf{x}\mathbf{x}^{T}} + * \f] + * + * @param[in] rx_time_s Time of Week in seconds + * @param[in] lat Receiver's latitude in degrees + * @param[in] lon Receiver's longitude in degrees + * @param[in] h Receiver's height in meters + * @param[in] ve Receiver's velocity in the East direction [m/s] + * @param[in] vn Receiver's velocity in the North direction [m/s] + * @param[in] vu Receiver's velocity in the Up direction [m/s] + * @param[in] band Signal band for which the Doppler will be computed + * (1: L1 C/A, E1B, BI1; 2: L2C, BI2; 3: BI3; 5: L5/E5a; 6: E6B; 7: E5b; 8: E5a+E5b) + */ + double predicted_doppler(double rx_time_s, double lat, double lon, double h, double ve, double vn, double vu, int band) const; + void satellitePosition(double transmitTime); //!< Computes the ECEF SV coordinates and ECEF velocity uint32_t PRN{}; //!< SV ID @@ -83,6 +112,7 @@ protected: char System{}; //!< Character ID of the GNSS system. 'G': GPS. 'E': Galileo. 'B': BeiDou private: + void satellitePosVelComputation(double transmitTime, std::array& pos_vel_dtr) const; double check_t(double time) const; double sv_clock_relativistic_term(double transmitTime) const; }; diff --git a/src/core/system_parameters/gnss_satellite.cc b/src/core/system_parameters/gnss_satellite.cc index ff6af54dd..b2390c90c 100644 --- a/src/core/system_parameters/gnss_satellite.cc +++ b/src/core/system_parameters/gnss_satellite.cc @@ -525,7 +525,7 @@ std::string Gnss_Satellite::what_block(const std::string& system_, uint32_t PRN_ } if (system_ == "Galileo") { - // Check https://en.wikipedia.org/wiki/List_of_Galileo_satellites and https://www.gsc-europa.eu/system-status/Constellation-Information + // Check https://en.wikipedia.org/wiki/List_of_Galileo_satellites and https://www.gsc-europa.eu/system-service-status/constellation-information switch (PRN_) { case 1: diff --git a/src/core/system_parameters/gps_almanac.h b/src/core/system_parameters/gps_almanac.h index c03278841..9c0cce600 100644 --- a/src/core/system_parameters/gps_almanac.h +++ b/src/core/system_parameters/gps_almanac.h @@ -38,7 +38,10 @@ public: /*! * Default constructor */ - Gps_Almanac() = default; + Gps_Almanac() + { + this->System = 'G'; + }; int32_t SV_health{}; //!< SV Health int32_t AS_status{}; //!< Anti-Spoofing Flags and SV Configuration diff --git a/src/core/system_parameters/gps_navigation_message.cc b/src/core/system_parameters/gps_navigation_message.cc index e7c39e71a..1ea1a6f22 100644 --- a/src/core/system_parameters/gps_navigation_message.cc +++ b/src/core/system_parameters/gps_navigation_message.cc @@ -465,18 +465,6 @@ Gps_Ephemeris Gps_Navigation_Message::get_ephemeris() const ephemeris.alert_flag = b_alert_flag; ephemeris.antispoofing_flag = b_antispoofing_flag; - // These parameters are empty; can be computed later with - // ephemeris.sv_clock_drift(double transmitTime); - // ephemeris.satellitePosition(double transmitTime); - ephemeris.satClkDrift = d_satClkDrift; - ephemeris.dtr = d_dtr; - ephemeris.satpos_X = d_satpos_X; - ephemeris.satpos_Y = d_satpos_Y; - ephemeris.satpos_Z = d_satpos_Z; - ephemeris.satvel_X = d_satvel_X; - ephemeris.satvel_Y = d_satvel_Y; - ephemeris.satvel_Z = d_satvel_Z; - return ephemeris; } diff --git a/src/core/system_parameters/gps_navigation_message.h b/src/core/system_parameters/gps_navigation_message.h index efe18144e..1d239a8fa 100644 --- a/src/core/system_parameters/gps_navigation_message.h +++ b/src/core/system_parameters/gps_navigation_message.h @@ -195,22 +195,6 @@ private: int32_t i_Toa{}; // Almanac reference time [s] int32_t i_WN_A{}; // Modulo 256 of the GPS week number to which the almanac reference time (i_Toa) is referenced - // clock terms - // double d_master_clock{}; // GPS transmission time - - double d_dtr{}; // relativistic clock correction term - double d_satClkDrift{}; - - // satellite positions - double d_satpos_X{}; // Earth-fixed coordinate x of the satellite [m]. Intersection of the IERS Reference Meridian (IRM) and the plane passing through the origin and normal to the Z-axis. - double d_satpos_Y{}; // Earth-fixed coordinate y of the satellite [m]. Completes a right-handed, Earth-Centered, Earth-Fixed orthogonal coordinate system. - double d_satpos_Z{}; // Earth-fixed coordinate z of the satellite [m]. The direction of the IERS (International Earth Rotation and Reference Systems Service) Reference Pole (IRP). - - // Satellite velocity - double d_satvel_X{}; // Earth-fixed velocity coordinate x of the satellite [m] - double d_satvel_Y{}; // Earth-fixed velocity coordinate y of the satellite [m] - double d_satvel_Z{}; // Earth-fixed velocity coordinate z of the satellite [m] - // satellite identification info int32_t i_channel_ID{}; uint32_t i_satellite_PRN{}; diff --git a/src/main/main.cc b/src/main/main.cc index 05b84eed1..ecd81949c 100644 --- a/src/main/main.cc +++ b/src/main/main.cc @@ -18,7 +18,7 @@ */ #ifndef GNSS_SDR_VERSION -#define GNSS_SDR_VERSION "0.0.16" +#define GNSS_SDR_VERSION "0.0.17" #endif #ifndef GOOGLE_STRIP_LOG diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 0902fb510..d73362ad2 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -403,12 +403,12 @@ if(ENABLE_UNIT_TESTING_EXTRA OR ENABLE_SYSTEM_TESTING_EXTRA OR ENABLE_FPGA) -DCMAKE_C_STANDARD=11 -DCMAKE_C_EXTENSIONS=ON BUILD_COMMAND ${GPSTK_BUILD_COMMAND} ${GPSTK_PARALLEL_BUILD} - BUILD_BYPRODUCTS ${CMAKE_BINARY_DIR}/gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION}/install/${CMAKE_INSTALL_LIBDIR}/${CMAKE_FIND_LIBRARY_PREFIXES}gpstk${CMAKE_STATIC_LIBRARY_SUFFIX} + BUILD_BYPRODUCTS ${CMAKE_BINARY_DIR}/gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION}/install/lib/${CMAKE_FIND_LIBRARY_PREFIXES}gpstk${CMAKE_STATIC_LIBRARY_SUFFIX} UPDATE_COMMAND "" ) endif() set(GPSTK_INCLUDE_DIRS ${CMAKE_BINARY_DIR}/gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION}/install/include CACHE PATH "Local GPSTK headers") - set(GPSTK_LIBRARY ${CMAKE_BINARY_DIR}/gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION}/install/${CMAKE_INSTALL_LIBDIR}/${CMAKE_FIND_LIBRARY_PREFIXES}gpstk${CMAKE_STATIC_LIBRARY_SUFFIX}) + set(GPSTK_LIBRARY ${CMAKE_BINARY_DIR}/gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION}/install/lib/${CMAKE_FIND_LIBRARY_PREFIXES}gpstk${CMAKE_STATIC_LIBRARY_SUFFIX}) set(GPSTK_BINDIR ${CMAKE_BINARY_DIR}/gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION}/install/bin/) add_definitions(-DGPSTK_BINDIR="${GPSTK_BINDIR}") add_library(Gpstk::gpstk STATIC IMPORTED) diff --git a/src/tests/data/gpstk_static.patch b/src/tests/data/gpstk_static.patch index c8ed6de56..7acf49dbf 100644 --- a/src/tests/data/gpstk_static.patch +++ b/src/tests/data/gpstk_static.patch @@ -1,10 +1,10 @@ SPDX-License-Identifier: GPL-3.0-or-later SPDX-FileCopyrightText: 2020 Carles Fernandez-Prades ---- CMakeLists.txt 2020-10-25 10:06:26.000000000 +0100 -+++ CMakeLists.txt 2020-10-25 10:06:11.000000000 +0100 +--- CMakeLists.txt 2022-04-05 23:24:04.000000000 +0200 ++++ CMakeLists.txt 2022-04-05 23:29:02.000000000 +0200 @@ -77,7 +77,16 @@ - - + + include( BuildSetup.cmake ) - +set(STADYN "STATIC") @@ -20,3 +20,12 @@ SPDX-FileCopyrightText: 2020 Carles Fernandez-Prades #============================================================ # Core Library Target Files #============================================================ +@@ -160,7 +169,7 @@ + add_library( gpstk ${STADYN} ${GPSTK_SRC_FILES} ${GPSTK_INC_FILES} ) + + # GPSTk library install target +-install( TARGETS gpstk DESTINATION "${CMAKE_INSTALL_LIBDIR}" EXPORT "${EXPORT_TARGETS_FILENAME}" ) ++install( TARGETS gpstk DESTINATION lib EXPORT "${EXPORT_TARGETS_FILENAME}" ) + + # GPSTk header file install target (whether it is version dependent changes based on user flag) + install( FILES ${GPSTK_INC_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ) diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_8ms_ambiguous_acquisition_gsoc2013_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_8ms_ambiguous_acquisition_gsoc2013_test.cc index 9c0eb822e..d35add820 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_8ms_ambiguous_acquisition_gsoc2013_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_8ms_ambiguous_acquisition_gsoc2013_test.cc @@ -26,6 +26,7 @@ #include "in_memory_configuration.h" #include "signal_generator.h" #include "signal_generator_c.h" +#include #include #include #include diff --git a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_gsoc_test.cc b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_gsoc_test.cc index 1c0b3af42..1a3886d81 100644 --- a/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_gsoc_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/acquisition/galileo_e1_pcps_ambiguous_acquisition_gsoc_test.cc @@ -35,6 +35,7 @@ #include "gnss_signal.h" #include "gnss_synchro.h" #include "in_memory_configuration.h" +#include #include #include #include diff --git a/src/utils/front-end-cal/main.cc b/src/utils/front-end-cal/main.cc index 38ee8206c..42d7a7601 100644 --- a/src/utils/front-end-cal/main.cc +++ b/src/utils/front-end-cal/main.cc @@ -344,9 +344,9 @@ int main(int argc, char** argv) { std::cout << "Exception caught while capturing samples (bad lexical cast)\n"; } - catch (const boost::io::too_few_args& e) + catch (const std::exception& e) { - std::cout << "Exception caught while capturing samples (too few args)\n"; + std::cout << "Exception caught while capturing samples: " << e.what() << '\n'; } catch (...) { diff --git a/src/utils/rinex-tools/CMakeLists.txt b/src/utils/rinex-tools/CMakeLists.txt index 3b54880e0..e51c7dddb 100644 --- a/src/utils/rinex-tools/CMakeLists.txt +++ b/src/utils/rinex-tools/CMakeLists.txt @@ -10,7 +10,7 @@ if("${ARMADILLO_VERSION_STRING}" VERSION_GREATER "9.800" OR (NOT ARMADILLO_FOUND find_package(GPSTK QUIET) if(NOT GPSTK_FOUND OR ENABLE_OWN_GPSTK) include(GNUInstallDirs) - set(GPSTK_LIBRARY ${CMAKE_BINARY_DIR}/gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION}/install/${CMAKE_INSTALL_LIBDIR}/${CMAKE_FIND_LIBRARY_PREFIXES}gpstk${CMAKE_STATIC_LIBRARY_SUFFIX}) + set(GPSTK_LIBRARY ${CMAKE_BINARY_DIR}/gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION}/install/lib/${CMAKE_FIND_LIBRARY_PREFIXES}gpstk${CMAKE_STATIC_LIBRARY_SUFFIX}) set(GPSTK_INCLUDE_DIR ${CMAKE_BINARY_DIR}/gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION}/install/include) endif() @@ -55,19 +55,25 @@ if("${ARMADILLO_VERSION_STRING}" VERSION_GREATER "9.800" OR (NOT ARMADILLO_FOUND add_dependencies(obsdiff matio-${GNSSSDR_MATIO_LOCAL_VERSION}) endif() + if(NOT TARGET Gpstk::gpstk) + file(MAKE_DIRECTORY ${GPSTK_INCLUDE_DIR}/gpstk) + add_library(Gpstk::gpstk STATIC IMPORTED) + add_dependencies(Gpstk::gpstk gpstk-${GNSSSDR_GPSTK_LOCAL_VERSION}) + set_target_properties(Gpstk::gpstk PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES "CXX" + IMPORTED_LOCATION "${GPSTK_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${GPSTK_INCLUDE_DIR};${GPSTK_INCLUDE_DIR}/gpstk" + INTERFACE_LINK_LIBRARIES "${GPSTK_LIBRARY}" + ) + endif() + target_link_libraries(obsdiff PRIVATE Armadillo::armadillo Threads::Threads Gflags::gflags Matio::matio - ${GPSTK_LIBRARY} - ) - - target_include_directories(obsdiff - PRIVATE - ${GPSTK_INCLUDE_DIR}/gpstk - ${GPSTK_INCLUDE_DIR} + Gpstk::gpstk ) if(GPSTK_OLDER_THAN_8) diff --git a/src/utils/scripts/download-galileo-almanac.sh b/src/utils/scripts/download-galileo-almanac.sh new file mode 100755 index 000000000..1967a03a1 --- /dev/null +++ b/src/utils/scripts/download-galileo-almanac.sh @@ -0,0 +1,126 @@ +#!/bin/sh +# GNSS-SDR shell script that tries to download the latest Galileo Almanac file +# published by the European GNSS Service Centre. +# +# Usage: ./download-galileo-almanac.sh +# +# SPDX-FileCopyrightText: 2022 Carles Fernandez-Prades +# SPDX-License-Identifier: GPL-3.0-or-later + +if ! [ -x "$(command -v wget)" ]; then + echo "Please install wget before using this script." + exit 1 +fi + +help() +{ + echo "This script tries to download the most recent Galileo Almanac XML file" + echo "published by the European GNSS Service Centre." + echo "More info at https://www.gsc-europa.eu/product-almanacs" + echo "If today there is no published file, the script will look up to one week ago." + echo "" + echo "Usage:" + echo "./download-galileo-almanac.sh [OPTION]" + echo " Options:" + echo " -h, --help Prints this message" + echo " -r, --rename Gets latest Galileo Almanac XML file and saves it as gal_almanac.xml" + echo " -d, --date [date] Retrieves file for a specific date, with format YYYY-MM-DD" + echo " -rd [date] Retrieves file for a specific date, with format YYYY-MM-DD" + echo " and saves it as gal_almanac.xml" + echo "" + echo " Examples:" + echo " ./download-galileo-almanac.sh # Gets latest Galileo Almanac XML file" + echo " ./download-galileo-almanac.sh -r # Gets latest Galileo Almanac XML file, stores it as gal_almanac.xml" + echo " ./download-galileo-almanac.sh -d 2022-03-15 # Gets Galileo Almanac XML file for that day" + echo " ./download-galileo-almanac.sh -rd 2022-03-15 # Gets Galileo Almanac XML file for that day, stores it as gal_almanac.xml" +} + +if (([ "$1" = "-h" ]) || ([ "$1" = "--help" ])) ; then + help + exit 0 +fi + +RENAME="" +if (([ "$1" = "-r" ]) || ([ "$1" = "--rename" ])) ; then + RENAME=" -O gal_almanac.xml " +fi + +BASE_URL="https://www.gsc-europa.eu/sites/default/files/sites/all/files/" +YEAR=$(date '+%Y') +SPACING="-" +MONTH=$(date '+%m') +DAY=$(date '+%d') + +TERMINATION1="_0.xml" +TERMINATION2=".xml" + +COUNTER=1 +MAX_COUNTER=7 + +if (([ "$1" = "-d" ]) || ([ "$1" = "--date" ])) ; then + if wget "$BASE_URL$2$TERMINATION2" >/dev/null 2>&1 ; then + echo "Downloaded latest Galileo almanac from $BASE_URL$2$TERMINATION2" + exit 0 + else + echo "Couldn't find an XML file for that date." + exit 1 + fi +elif [ "$1" = "-rd" ] ; then + if wget -O gal_almanac.xml "$BASE_URL$2$TERMINATION2" >/dev/null 2>&1 ; then + echo "Downloaded latest Galileo almanac from $BASE_URL$2$TERMINATION2" + exit 0 + else + echo "Couldn't find an XML file for that date." + rm gal_almanac.xml + exit 1 + fi +else + echo "According to system time, today is $(date '+%Y-%m-%d'). Searching for the latest Galileo almanac ..." +fi + +lowercase() +{ + echo "$1" | sed "y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/" +} + +OS=`lowercase \`uname\`` + +date_before() +{ + if [ "$OS" = "darwin" ]; then + YEAR=$(date -v -"$COUNTER"d '+%Y') + MONTH=$(date -v -"$COUNTER"d '+%m') + DAY=$(date -v -"$COUNTER"d '+%d') + else + YEAR=$(date -d "$COUNTER day ago" '+%Y') + MONTH=$(date -d "$COUNTER day ago" '+%m') + DAY=$(date -d "$COUNTER day ago" '+%d') + fi + COUNTER=$(($COUNTER+1)) +} + + +try_download() +{ + while [ $COUNTER -le $MAX_COUNTER ] + do + url="$BASE_URL$YEAR$SPACING$MONTH$SPACING$DAY$TERMINATION2" + if wget $RENAME $url >/dev/null 2>&1 ; then + echo "Downloaded latest Galileo almanac from $url" + exit 0 + else + date_before + try_download + fi + done +} + + +url="$BASE_URL$YEAR$SPACING$MONTH$SPACING$DAY$TERMINATION1" +if wget $RENAME $url >/dev/null 2>&1 ; then + echo "Downloaded latest Galileo almanac from $url" +else + try_download + echo "Couldn't find a recent Galileo almanac." + exit 1 +fi