diff --git a/.github/workflows/citation.yml b/.github/workflows/citation.yml new file mode 100644 index 000000000..dbec9dd9d --- /dev/null +++ b/.github/workflows/citation.yml @@ -0,0 +1,40 @@ +# SPDX-License-Identifier: GPL-3.0-or-later +# SPDX-FileCopyrightText: 2022 Carles Fernandez-Prades +on: + push: + paths: + - CITATION.cff + workflow_dispatch: + pull_request: + paths: + - CITATION.cff + workflow_dispatch: + +name: CITATION.cff +jobs: + Validate-CITATION-cff: + runs-on: ubuntu-latest + name: Validate CITATION.cff + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + RSPM: "https://packagemanager.rstudio.com/cran/__linux__/focal/latest" + + steps: + - name: Checkout + uses: actions/checkout@v2 + + # This is needed for workflows running on + # ubuntu-20.04 or later + - name: Install V8 + if: runner.os == 'Linux' + run: | + sudo apt-get install -y libv8-dev + - name: Validate CITATION.cff + uses: dieghernan/cff-validator@main + + # Upload artifact + - uses: actions/upload-artifact@v2 + if: failure() + with: + name: citation-cff-errors + path: citation_cff_errors.md diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 8731d9a39..e5334141a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -2,7 +2,13 @@ # SPDX-FileCopyrightText: 2020 Carles Fernandez-Prades name: Simple CI -on: [push, pull_request] +on: + pull_request: + paths-ignore: + - '**/CITATION.cff' + push: + paths-ignore: + - '**/CITATION.cff' jobs: build-ubuntu: @@ -118,7 +124,7 @@ jobs: pip install mako - name: configure shell: powershell - run: cd build; cmake -G "Visual Studio 16 2019" ..\src\algorithms\libs\volk_gnsssdr_module\volk_gnsssdr + run: cd build; cmake -G "Visual Studio 17 2022" ..\src\algorithms\libs\volk_gnsssdr_module\volk_gnsssdr - name: build run: cmake --build build --config Release - name: test diff --git a/AUTHORS b/AUTHORS index 4d7536e6c..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 @@ -60,7 +60,8 @@ Marc Molina marc.molina.pena@gmail.com Contributor Marc Sales marcsales92@gmail.com Contributor Piyush Gupta piyush04111999@gmail.com Contributor Rodrigo Muñoz rodrigo.munoz@proteinlab.cl Contributor +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 new file mode 100644 index 000000000..f09da0438 --- /dev/null +++ b/CITATION.cff @@ -0,0 +1,328 @@ +# SPDX-License-Identifier: GPL-3.0-or-later +# SPDX-FileCopyrightText: 2022 C. Fernandez-Prades carles.fernandez(at)cttc.es +--- +authors: + - affiliation: "Centre Tecnològic de Telecomunicacions de Catalunya (CTTC)" + alias: carlesfernandez + email: carles.fernandez@cttc.es + family-names: "Fernández-Prades" + given-names: Carles + orcid: "https://orcid.org/0000-0002-9201-7007" + - affiliation: "Centre Tecnològic de Telecomunicacions de Catalunya (CTTC)" + alias: Arribas + email: javier.arribas@cttc.es + family-names: Arribas + given-names: Javier + orcid: "https://orcid.org/0000-0001-6346-3406" + - affiliation: "Centre Tecnològic de Telecomunicacions de Catalunya (CTTC)" + alias: mmajoral + email: marc.majoral@cttc.es + family-names: Majoral + given-names: Marc + orcid: "https://orcid.org/0000-0001-6161-6747" + - alias: Gastd + email: gabriel.araujo.5000@gmail.com + family-names: Araujo + given-names: Gabriel + - email: anthony.arnold@uqconnect.edu.au + family-names: Arnold + given-names: Anthony + - email: carlos.avilesr@googlemail.com + family-names: Avilés + given-names: Carlos + - alias: marabra + email: mara.branzanti@gmail.com + family-names: Branzanti + given-names: Mara + - alias: acebrianjuan + email: acebrianjuan@gmail.com + family-names: "Cebrián-Juan" + given-names: Álvaro + - email: a.cecilia.luque@gmail.com + family-names: "Cecilia-Luque" + given-names: Andrés + - alias: luis-esteve + email: luis@epsilon-formacion.com + family-names: Esteve + given-names: Luis + - email: fabra@ice.csic.es + family-names: Fabra + given-names: Fran + - email: daniel.co@bluewin.ch + family-names: Fehr + given-names: Daniel + - alias: piyush0411 + email: piyush04111999@gmail.com + family-names: Gupta + given-names: Piyush + - alias: glamountain + email: gerald@gece.neu.edu + family-names: LaMountain + given-names: Gerald + - alias: lenhart + email: malte.lenhart@mailbox.org + family-names: Lenhart + given-names: Malte + - alias: jwmelto + email: jim.melton@sncorp.com + family-names: Melton + given-names: Jim + - alias: dmiralles2009 + email: dmiralles2009@gmail.com + family-names: Miralles + given-names: Damian + orcid: "https://orcid.org/0000-0001-5820-9569" + - email: marc.molina.pena@gmail.com + family-names: Molina + given-names: Marc + - email: rodrigo.munoz@proteinlab.cl + family-names: Muñoz + given-names: Rodrigo + - alias: odrisci + email: cillian.odriscoll@gmail.com + family-names: "O'Driscoll" + given-names: Cillian + - affiliation: "Centre Tecnològic de Telecomunicacions de Catalunya (CTTC)" + email: david.pubill@cttc.cat + family-names: Pubill + given-names: David + - alias: antonioramosdet + family-names: Ramos + given-names: Antonio + - alias: jschindehette + email: jschindehette@geontech.com + family-names: Schindehette + given-names: Josh + - email: tonetto.dev@gmail.com + family-names: Tonetto + given-names: Leonardo + - alias: stefanlinden + email: spvdlinden@gmail.com + family-names: "van der Linden" + given-names: Stefan +cff-version: "1.2.0" +date-released: "2022-02-15" +identifiers: + - description: "The concept DOI of the work. This is a DOI always pointing to the latest stable release." + type: doi + value: 10.5281/zenodo.591700 +keywords: + - "Global Navigation Satellite System" + - GNSS + - "software radio" + - SDR + - GPS + - Galileo + - C++ +license: GPL-3.0-or-later +message: "If you use this software, please cite it using the metadata from this file." +references: + - authors: + - family-names: "Fernández-Prades" + given-names: Carles + - family-names: "Vilà-Valls" + given-names: Jordi + - family-names: Arribas + given-names: Javier + - family-names: Ramos + given-names: Antonio + doi: 10.1109/ACCESS.2018.2822835 + issue: 1 + journal: "IEEE Access" + pages: 13 + start: 20451 + end: 20463 + scope: "Discussion on reproducibility in GNSS signal processing." + title: "Continuous Reproducibility in GNSS Signal Processing." + type: article + volume: 6 + year: 2018 + - authors: + - family-names: "Fernández-Prades" + given-names: Carles + - family-names: "Lo Presti" + given-names: Letizia + - family-names: Falleti + given-names: Emanuela + doi: 10.1109/JPROC.2011.2158032 + issue: 11 + journal: "Proceedigs of the IEEE" + month: 11 + pages: 23 + start: 1882 + end: 1904 + scope: "General overview on GNSS receiver technology." + title: "Satellite Radiolocalization From GPS to GNSS and Beyond: Novel Technologies and Applications for Civil Mass Market." + type: article + volume: 99 + year: 2011 + - authors: + - family-names: "Fernández-Prades" + given-names: Carles + - family-names: Arribas + given-names: Javier + - family-names: Majoral + given-names: Marc + - family-names: Ramos + given-names: Antonio + - family-names: "Vilà-Valls" + given-names: Jordi + - family-names: Giordano + given-names: Pietro + conference: + name: "Proc. 9th ESA Workshop on Satellite Navigation Technologies and European Workshop on GNSS Signals and Signal Processing (NAVITEC)" + doi: 10.1109/NAVITEC.2018.8642697 + location: + name: "ESA/ESTEC, Noordwijk, Netherlands." + month: 12 + pages: 9 + scope: "Space applications of the software-defined GNSS embeded receiver." + title: "A Software-Defined Spaceborne GNSS Receiver." + type: conference-paper + year: 2018 + - authors: + - family-names: "Fernández-Prades" + given-names: Carles + - family-names: Pomar + given-names: Christian + - family-names: Arribas + given-names: Javier + - family-names: Fàbrega + given-names: "Josep Maria" + - family-names: "Vilà-Valls" + given-names: Jordi + - family-names: "Svaluto Moreolo" + given-names: Michela + - family-names: Casellas + given-names: Ramon + - family-names: Martínez + given-names: Ricardo + - family-names: Navarro + given-names: Mònica + - family-names: Vílchez + given-names: "Francisco Javier" + - family-names: Muñoz + given-names: Raul + - family-names: Vilalta + given-names: Ricard + - family-names: Nadal + given-names: Laia + - family-names: Mayoral + given-names: Arturo + conference: + name: "Proc. 30th Int. Tech. Meeting Sat. Div. Inst. Navig." + doi: 10.33012/2017.15234 + location: + name: "Portland, OR." + month: 9 + scope: "Introduction of the virtualized GNSS receiver." + pages: 20 + start: 3796 + end: 3815 + title: "A Cloud Optical Access Network for Virtualized GNSS Receivers" + type: conference-paper + year: 2017 + - authors: + - family-names: "Fernández-Prades" + given-names: Carles + - family-names: Arribas + given-names: Javier + - family-names: Closas + given-names: Pau + conference: + name: "Proc. 8th ESA Workshop on Satellite Navigation Technologies and European Workshop on GNSS Signals and Signal Processing (NAVITEC)" + doi: 10.1109/NAVITEC.2016.7931740 + location: + name: "ESA/ESTEC, Noordwijk, Netherlands." + month: 12 + pages: 9 + scope: "Discussion on testing methodologies for software-defined GNSS receivers." + title: "Assessment of Software-Defined GNSS Receivers" + type: conference-paper + year: 2016 + - authors: + - family-names: "Fernández-Prades" + given-names: Carles + - family-names: Arribas + given-names: Javier + - family-names: Closas + given-names: Pau + conference: + name: "Proc. 29th Int. Tech. Meeting Sat. Div. Inst. Navig." + doi: 10.33012/2016.14576 + location: + name: "Portland, OR." + month: 9 + pages: 18 + start: 44 + end: 61 + scope: "Analysis of software strategies for accelerating signal processing." + title: "Accelerating GNSS Software Receivers" + type: conference-paper + year: 2016 + - authors: + - family-names: "Fernández-Prades" + given-names: Carles + - family-names: Arribas + given-names: Javier + - family-names: Closas + given-names: Pau + - family-names: Avilés + given-names: Carlos + - family-names: Esteve + given-names: Luis + conference: + name: "Proc. 24th Int. Tech. Meeting Sat. Div. Inst. Navig." + location: + name: "Portland, OR." + month: 9 + pages: 15 + start: 780 + end: 794 + scope: "General description of the software architecture." + title: "GNSS-SDR: An Open Source Tool For Researchers and Developers" + type: conference-paper + year: 2011 + - authors: + - family-names: "Fernández-Prades" + given-names: Carles + - family-names: Avilés + given-names: Carlos + - family-names: Esteve + given-names: Luis + - family-names: Arribas + given-names: Javier + - family-names: Closas + given-names: Pau + conference: + name: "Proc. 5th ESA Workshop on Satellite Navigation Technologies and European Workshop on GNSS Signals and Signal Processing (NAVITEC)." + doi: 10.1109/NAVITEC.2010.5707981 + location: + name: "ESA/ESTEC, Noordwijk, Netherlands." + month: 12 + pages: 8 + scope: "Seminal work on GNSS-SDR and its software design patterns." + title: "Design patterns for GNSS software receivers" + type: conference-paper + year: 2010 + - authors: + - name: "The GNU Radio Project team" + doi: 10.5281/zenodo.2704343 + repository-code: "https://github.com/gnuradio/gnuradio" + scope: "Software dependency: the SDR framework." + title: "GNU Radio: The Free & Open Software Radio Ecosystem" + type: software + url: "https://www.gnuradio.org" + - authors: + - name: "The VOLK Project team" + doi: 10.5281/zenodo.3360942 + repository-code: "https://github.com/gnuradio/volk" + scope: "Software dependency: the portable SIMD library." + title: "VOLK: The Vector-Optimized Library of Kernels" + type: software + url: "https://www.libvolk.org" +repository-code: "https://github.com/gnss-sdr/gnss-sdr" +title: GNSS-SDR +type: software +url: "https://gnss-sdr.org" +version: "0.0.16" diff --git a/CMakeLists.txt b/CMakeLists.txt index 5aec88b89..12fe64611 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ # GNSS-SDR is a Global Navigation Satellite System software-defined receiver. # This file is part of GNSS-SDR. # -# SPDX-FileCopyrightText: 2010-2021 C. Fernandez-Prades cfernandez(at)cttc.es +# SPDX-FileCopyrightText: 2010-2022 C. Fernandez-Prades cfernandez(at)cttc.es # SPDX-License-Identifier: BSD-3-Clause ################################################################################ @@ -11,7 +11,12 @@ if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR}) message(FATAL_ERROR "Prevented in-tree build, it is bad practice.\nTry 'cd build && cmake ..' instead.") endif() -cmake_minimum_required(VERSION 2.8.12...3.22) +# Select the release build type by default to get optimization flags. +# This has to come before project() which otherwise initializes it. +# 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.23) project(gnss-sdr CXX C) list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules) @@ -96,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) @@ -161,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 15) + set(VERSION_INFO_MINOR_VERSION 16) else() - set(VERSION_INFO_MINOR_VERSION 15.git-${GIT_BRANCH}-${GIT_COMMIT_HASH}) + set(VERSION_INFO_MINOR_VERSION 16.git-${GIT_BRANCH}-${GIT_COMMIT_HASH}) endif() set(VERSION ${VERSION_INFO_MAJOR_VERSION}.${VERSION_INFO_API_COMPAT}.${VERSION_INFO_MINOR_VERSION}) @@ -219,19 +224,9 @@ include(GnsssdrBuildTypes) # - O2WithASM: -O2 -g -save-temps # - O3WithASM: -O3 -g -save-temps # - ASAN: -Wall -Wextra -g -O2 -fsanitize=address -fno-omit-frame-pointer -if(NOT CMAKE_BUILD_TYPE) - if(ENABLE_GPERFTOOLS OR ENABLE_GPROF) - set(CMAKE_BUILD_TYPE "RelWithDebInfo") - message(STATUS "Build type not specified: defaulting to RelWithDebInfo.") - else() - set(CMAKE_BUILD_TYPE "Release") - message(STATUS "Build type not specified: defaulting to Release.") - endif() -else() - message(STATUS "Build type set to ${CMAKE_BUILD_TYPE}.") -endif() gnsssdr_check_build_type(${CMAKE_BUILD_TYPE}) -set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "") +message(STATUS "Build type set to ${CMAKE_BUILD_TYPE}.") + if(NOT (${CMAKE_BUILD_TYPE} STREQUAL "Release")) set(ENABLE_STRIP OFF) endif() @@ -325,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)) @@ -335,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_PUGIXML_LOCAL_VERSION "1.11.4") -set(GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION "3.19.0") +set(GNSSSDR_MATIO_LOCAL_VERSION "1.5.23") +set(GNSSSDR_PUGIXML_LOCAL_VERSION "1.12") +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() @@ -1161,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} @@ -1198,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) @@ -1232,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) + if(CPUFEATURES_FOUND) message(STATUS "Found CpuFeatures: (found version ${CpuFeatures_VERSION})") - set_package_properties(CpuFeatures PROPERTIES + set_package_properties(CPUFEATURES PROPERTIES DESCRIPTION "A cross platform C99 library to get CPU features at runtime (found: v${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 @@ -1270,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 @@ -1297,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) @@ -1313,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} ) @@ -1343,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() @@ -1679,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} @@ -1694,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} @@ -3358,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/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index f141ea6e2..0e7424f06 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -16,8 +16,8 @@ We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, -nationality, personal appearance, race, religion, or sexual identity and -orientation. +nationality, personal appearance, race, caste, color, religion, or sexual +identity and orientation. We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community. @@ -64,13 +64,7 @@ This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed -representative at an online or offline event. This Code of Conduct applies both -within project spaces and in public spaces when an individual is representing -the project or its community. Examples of representing a project or community -include using an official project e-mail address, posting via an official social -media account, or acting as an appointed representative at an online or offline -event. Representation of a project may be further defined and clarified by -project maintainers. +representative at an online or offline event. ## Enforcement @@ -131,18 +125,18 @@ community. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], -version 2.0, available at -[https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][version]. +version 2.1, available at +[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. Community Impact Guidelines were inspired by [Mozilla's code of conduct -enforcement ladder][diversity]. +enforcement ladder][mozilla coc]. For answers to common questions about this code of conduct, see the FAQ at [https://www.contributor-covenant.org/faq][faq]. Translations are available at [https://www.contributor-covenant.org/translations][translations]. [homepage]: https://www.contributor-covenant.org -[diversity]: https://github.com/mozilla/diversity -[version]: https://www.contributor-covenant.org/version/2/0/code_of_conduct.html -[faq]: https://www.contributor-covenant.org/faq/ +[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html +[mozilla coc]: https://github.com/mozilla/diversity +[faq]: https://www.contributor-covenant.org/faq [translations]: https://www.contributor-covenant.org/translations diff --git a/README.md b/README.md index 0a5f6852d..9b4d63c5e 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ SPDX-FileCopyrightText: 2011-2021 Carles Fernandez-Prades internal clock -SignalSource.PPS_mode=false; //requires special gr-limesdr -SignalSource.limechannel_mode = 0; //ChannelMode must be A(0), B(1) or (A+B) MIMO(2)" +SignalSource.gain=50 ; 0-73 dB no AGC in LimeSDR +; SignalSource.analog_bw ; if not set, defaults to sample_rate/2 +; SignalSource.digital_bw ; if not set, defaults to 0 (disabled filter) +; SignalSource.limesdr_serial ; if not set, its automatic +SignalSource.antenna=2 ; None(0), LNAH(1), LNAL(2), LNAW(3), AUTO(255) +SignalSource.ext_clock_MHz=0 ; 0 -> internal clock +SignalSource.limechannel_mode=0 ; A(0), B(1) or (A+B) MIMO(2) SignalSource.samples=0 SignalSource.repeat=false SignalSource.dump=false -SignalSource.dump_filename=../data/signal_source.dat -SignalSource.enable_throttle_control=false +SignalSource.dump_filename=./captured_signal.dat SignalConditioner.implementation=Signal_Conditioner DataTypeAdapter.implementation=Pass_Through @@ -37,6 +32,7 @@ InputFilter.implementation=Pulse_Blanking_Filter ; <- Required in some locations InputFilter.pfa=0.001 InputFilter.segments_est=2500 Resampler.implementation=Pass_Through + ;######### CHANNELS GLOBAL CONFIG ############ Channels_1C.count=7 Channels_1B.count=0 @@ -44,30 +40,29 @@ Channels.in_acquisition=1 Channel.signal=1C -;######### ACQUISITION GLOBAL CONFIG ############ +;######### GPS L1 ACQUISITION CONFIG ############ Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition Acquisition_1C.item_type=gr_complex Acquisition_1C.coherent_integration_time_ms=1 -Acquisition_1C.use_CFAR_algorithm=false; -Acquisition_1C.threshold=2.4 -Acquisition_1C.doppler_max=6000 +Acquisition_1C.pfa=0.01 +Acquisition_1C.doppler_max=5000 Acquisition_1C.doppler_step=250 Acquisition_1C.dump=false Acquisition_1C.dump_filename=./acq_dump.dat -;######### GALILEO ACQUISITION CONFIG ############ +;######### GALILEO E1 ACQUISITION CONFIG ############ Acquisition_1B.implementation=Galileo_E1_PCPS_Ambiguous_Acquisition Acquisition_1B.item_type=gr_complex -Acquisition_1B.threshold=2.5 -Acquisition_1B.use_CFAR_algorithm=false +Acquisition_1B.coherent_integration_time_ms=4 +Acquisition_1B.pfa=0.01 Acquisition_1B.blocking=false -Acquisition_1B.doppler_max=6000 +Acquisition_1B.doppler_max=5000 Acquisition_1B.doppler_step=125 Acquisition_1B.dump=false Acquisition_1B.dump_filename=./acq_dump.dat -;######### TRACKING GLOBAL CONFIG ############ +;######### GPS L1 TRACKING CONFIG ############ Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking Tracking_1C.item_type=gr_complex Tracking_1C.dump=false @@ -81,7 +76,7 @@ Tracking_1C.order=3; Tracking_1C.early_late_space_chips=0.5; Tracking_1C.early_late_space_narrow_chips=0.5 -;######### TRACKING GALILEO CONFIG ############ +;######### GALILEO E1 TRACKING CONFIG ############ Tracking_1B.implementation=Galileo_E1_DLL_PLL_VEML_Tracking Tracking_1B.item_type=gr_complex Tracking_1B.pll_bw_hz=15.0; @@ -93,20 +88,22 @@ Tracking_1B.dll_bw_narrow_hz=0.5 Tracking_1B.extend_correlation_symbols=1 Tracking_1B.track_pilot=true Tracking_1B.enable_fll_pull_in=true; -;Tracking_1B.pull_in_time_s=60 +; Tracking_1B.pull_in_time_s=60 Tracking_1B.enable_fll_steady_state=false Tracking_1B.fll_bw_hz=10 Tracking_1B.dump=false Tracking_1B.dump_filename=tracking_ch_ -;######### TELEMETRY DECODER GPS CONFIG ############ +;######### TELEMETRY DECODER GPS L1 CONFIG ############ TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder TelemetryDecoder_1C.dump=false +;######### TELEMETRY DECODER Galileo E1 CONFIG ############ TelemetryDecoder_1B.implementation=Galileo_E1B_Telemetry_Decoder TelemetryDecoder_1B.dump=false + ;######### OBSERVABLES CONFIG ############ Observables.implementation=Hybrid_Observables Observables.dump=false 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 54e188f73..233c24312 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -4,7 +4,7 @@ SPDX-License-Identifier: GPL-3.0-or-later ) [comment]: # ( -SPDX-FileCopyrightText: 2011-2021 Carles Fernandez-Prades +SPDX-FileCopyrightText: 2011-2022 Carles Fernandez-Prades ) @@ -16,6 +16,33 @@ All notable changes to GNSS-SDR will be documented in this file. ### Improvements in Availability: +- Compute PVT solutions when using GPS L5 signals even if the satellite is + reported as not healthy in the CNAV message. + +### Improvements in Portability: + +- Updated `cpu_features` library to v0.7.0. The building option + `ENABLE_OWN_CPUFEATURES` has been replaced by `ENABLE_CPUFEATURES`, defaulting + to `ON`. +- Fixed building against GNU Radio v3.10.2 + +### Improvements in Reliability: + +- Fix some defects detected by Coverity Scan 2021.12.1. + +See the definitions of concepts and metrics at +https://gnss-sdr.org/design-forces/ + +  + +## [GNSS-SDR v0.0.16](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.16) - 2022-02-15 + +[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.6090349.svg)](https://doi.org/10.5281/zenodo.6090349) + +### Improvements in Availability: + +- Added the Galileo E5b receiving chain. The software is now able to compute PVT + solutions as a standalone Galileo E5b receiver. - Improved Time-To-First-Fix when using GPS L1 C/A signals, fixing a bug that was making the receiver to drop the satellite if the PLL got locked at 180 degrees, and making some optimizations on bit transition detection. @@ -40,14 +67,14 @@ All notable changes to GNSS-SDR will be documented in this file. memory management and source code readability. - Prefer initialization to assignment in constructors. This improves the readability of the code, could potentially increase performance, and allows - for easier detection of unused data members (see - https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md/#Rc-initialize). + for easier detection of unused data members (see the + [CppCoreGuidelines](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md/#Rc-initialize)). Added the `cppcoreguidelines-prefer-member-initializer` clang-tidy check to enforce this policy. - Non-functional change: Fixed formatting defects detected by clang-format 13.0. - Non-functional change: Simplified flow graph disconnection. -- Updated GSL implementation to v0.40.0. See - https://github.com/gsl-lite/gsl-lite/releases/tag/v0.40.0 +- Updated GSL implementation to v0.40.0. See the + [gsl-lite release](https://github.com/gsl-lite/gsl-lite/releases/tag/v0.40.0). - CI - `cpplint` job on GitHub: Added the `build/include_what_you_use` filter for early detection of missing includes. - CI - `clang-tidy` job on GitHub: More robust detection of LLVM paths installed @@ -56,11 +83,11 @@ All notable changes to GNSS-SDR will be documented in this file. ### Improvements in Portability: - Fixed building against the new API in the gr-iio component present in GNU - Radio v3.10.0.0-rc1. -- Fixed building against GNU Radio v3.10.0.0-rc1, which does not support the - C++20 standard. -- Fixed building against GNU Radio v3.10.0.0-rc1, which replaced - [log4cpp](http://log4cpp.sourceforge.net/) by + Radio v3.10.X.Y. +- Fixed building against GNU Radio v3.10.X.Y, which does not support the C++20 + standard. +- Fixed building against GNU Radio v3.10.X.Y, which replaced + [log4cpp](http://log4cpp.sourceforge.net/) by the [spdlog](https://github.com/gabime/spdlog) and [fmt](https://github.com/fmtlib/fmt) libraries. - Updated `cpu_features` library for improved processor detection. @@ -106,6 +133,10 @@ All notable changes to GNSS-SDR will be documented in this file. those requirements are not met in the configuration file. - Fixed program termination when using `File_Signal_Source` and extended integration times. +- The `Fifo_Signal_Source` Signal Source implementation learned to handle the + `ibyte` type. +- Added a `CITATION.cff` file. +- Updated version of the Contributor Covenant to version 2.1. See the definitions of concepts and metrics at https://gnss-sdr.org/design-forces/ @@ -114,6 +145,8 @@ https://gnss-sdr.org/design-forces/ ## [GNSS-SDR v0.0.15](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.15) - 2021-08-23 +[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.5242839.svg)](https://doi.org/10.5281/zenodo.5242839) + ### Improvements in Availability: - Added the reading of reduced clock and ephemeris data (CED) in the Galileo E1B @@ -238,6 +271,8 @@ https://gnss-sdr.org/design-forces/ ## [GNSS-SDR v0.0.14](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.14) - 2021-01-08 +[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.4428100.svg)](https://doi.org/10.5281/zenodo.4428100) + ### Improvements in Availability: - Fixed bug in acquisition detection when the configuration parameter @@ -347,6 +382,8 @@ https://gnss-sdr.org/design-forces/ ## [GNSS-SDR v0.0.13](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.13) - 2020-07-29 +[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.3965566.svg)](https://doi.org/10.5281/zenodo.3965566) + ### Improvements in Efficiency: - Faster internal handling of `Gnss_Synchro` objects by reducing the amount of @@ -461,6 +498,8 @@ https://gnss-sdr.org/design-forces/ ## [GNSS-SDR v0.0.12](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.12) - 2020-03-13 +[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.3709089.svg)](https://doi.org/10.5281/zenodo.3709089) + ### Improvements in Accuracy: - Improved accuracy of the C/N0 estimator. @@ -655,6 +694,8 @@ https://gnss-sdr.org/design-forces/ ## [GNSS-SDR v0.0.11](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.11) - 2019-08-04 +[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.3359989.svg)](https://doi.org/10.5281/zenodo.3359989) + This release has several improvements in different dimensions, addition of new features and bug fixes: @@ -808,6 +849,8 @@ https://gnss-sdr.org/design-forces/ ## [GNSS-SDR v0.0.10](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.10) - 2018-12-14 +[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.2279988.svg)](https://doi.org/10.5281/zenodo.2279988) + This release has several improvements in different dimensions, addition of new features and bug fixes: @@ -886,8 +929,7 @@ features and bug fixes: - Improvements in the RTCM server stability. - Improvements in the correctness of generated RINEX files. - The receiver can read and make use of Galileo almanac XML files published by - the European GNSS Service Centre at - https://www.gsc-europa.eu/system-status/almanac-data + the European GNSS Service Centre at https://www.gsc-europa.eu/product-almanacs - Own-defined XML schemas for navigation data published at https://github.com/gnss-sdr/gnss-sdr/tree/next/docs/xml-schemas - Added program `rinex2assist` to convert RINEX navigation files into XML files @@ -1040,7 +1082,7 @@ https://gnss-sdr.org/design-forces/ ## [GNSS-SDR v0.0.9](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.9) - 2017-02-13 -DOI: https://doi.org/10.5281/zenodo.291371 +[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.291371.svg)](https://doi.org/10.5281/zenodo.291371) This release has several improvements, addition of new features and bug fixes in many dimensions: @@ -1161,7 +1203,7 @@ https://gnss-sdr.org/design-forces/ ## [GNSS-SDR v0.0.8](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.8) - 2016-07-04 -DOI: https://doi.org/10.5281/zenodo.57022 +[![DOI](https://zenodo.org/badge/doi/10.5281/zenodo.57022.svg)](http://dx.doi.org/10.5281/zenodo.57022) This is a maintenance and bug fix release with no relevant new features with respect to v0.0.7. The main changes are: @@ -1187,7 +1229,7 @@ respect to v0.0.7. The main changes are: ## [GNSS-SDR v0.0.7](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.7) - 2016-05-15 -DOI: https://doi.org/10.5281/zenodo.51521 +[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.51521.svg)](https://doi.org/10.5281/zenodo.51521) This release has several improvements, addition of new features and bug fixes: @@ -1279,6 +1321,8 @@ This release has several improvements, addition of new features and bug fixes: ## [GNSS-SDR v0.0.6](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.6) - 2015-09-02 +[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.30104.svg)](https://doi.org/10.5281/zenodo.30104) + This release has several improvements and bug fixes: - Added initial support to multi-band, multi-source configurations (multiple @@ -1329,6 +1373,8 @@ This release has several improvements and bug fixes: ## [GNSS-SDR v0.0.5](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.5) - 2015-01-13 +[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.13920.svg)](https://doi.org/10.5281/zenodo.13920) + This release has several improvements and bug fixes: - Now GNSS-SDR can be installed on the system with the usual @@ -1356,6 +1402,8 @@ This release has several improvements and bug fixes: ## [GNSS-SDR v0.0.4](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.4) - 2014-09-08 +[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.11628.svg)](https://doi.org/10.5281/zenodo.11628) + This release has several improvements and bug fixes: - Added hybrid processing GPS L1 C/A and Galileo E1B, providing position fixes @@ -1393,6 +1441,8 @@ This release has several improvements and bug fixes: ## [GNSS-SDR v0.0.3](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.3) - 2014-06-30 +[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.10708.svg)](https://doi.org/10.5281/zenodo.10708) + This release has several improvements and bug fixes, completing the transition from Subversion to Git. The main changes are: diff --git a/docs/doxygen/other/main_page.dox b/docs/doxygen/other/main_page.dox index 28548550d..419cd9848 100644 --- a/docs/doxygen/other/main_page.dox +++ b/docs/doxygen/other/main_page.dox @@ -89,7 +89,7 @@ dependencies and build process. Mainly, it consists on installing 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 bbcc0623c..045c462cb 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 "23 Aug 2021" "0.0.15" "gnss\-sdr man page" +.TH gnss\-sdr 1 "15 Feb 2022" "0.0.16" "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 f0c039506..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 "; } @@ -1698,7 +1699,7 @@ void rtklib_pvt_gs::log_source_timetag_info(double RX_time_ns, double TAG_time_n } catch (const std::exception& e) { - std::cerr << "Problem writting at the log PVT timetag metadata file: " << e.what() << '\n'; + std::cerr << "Problem writing at the log PVT timetag metadata file: " << e.what() << '\n'; } } } @@ -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/PVT/libs/rinex_printer.h b/src/algorithms/PVT/libs/rinex_printer.h index 6ffeca87f..e0e68a780 100644 --- a/src/algorithms/PVT/libs/rinex_printer.h +++ b/src/algorithms/PVT/libs/rinex_printer.h @@ -98,7 +98,7 @@ public: * \brief Print RINEX annotation. If it is the first annotation, it also * prints the RINEX headers for navigation and observation files. If it is * not the first annotation, it only annotates the observation, and updates - * the navigation header if UTC data was not available when writting it for + * the navigation header if UTC data was not available when writing it for * the first time. The meaning of type_of_rx is as follows: * * type_of_rx | Signals diff --git a/src/algorithms/PVT/libs/rtklib_solver.cc b/src/algorithms/PVT/libs/rtklib_solver.cc index e239c2686..bfa3bd52b 100644 --- a/src/algorithms/PVT/libs/rtklib_solver.cc +++ b/src/algorithms/PVT/libs/rtklib_solver.cc @@ -406,6 +406,7 @@ bool Rtklib_Solver::get_PVT(const std::map &gnss_observables_ bool gps_dual_band = false; bool band1 = false; bool band2 = false; + bool gal_e5_is_e5b = false; for (gnss_observables_iter = gnss_observables_map.cbegin(); gnss_observables_iter != gnss_observables_map.cend(); ++gnss_observables_iter) @@ -468,7 +469,7 @@ bool Rtklib_Solver::get_PVT(const std::map &gnss_observables_ } // Galileo E5 - if (sig_ == "5X") + if ((sig_ == "5X") || (sig_ == "7X")) { // 1 Gal - find the ephemeris for the current GALILEO SV observation. The SV PRN ID is the map key galileo_ephemeris_iter = galileo_ephemeris_map.find(gnss_observables_iter->second.PRN); @@ -508,6 +509,10 @@ bool Rtklib_Solver::get_PVT(const std::map &gnss_observables_ { DLOG(INFO) << "No ephemeris data for SV " << gnss_observables_iter->second.PRN; } + if (sig_ == "7X") + { + gal_e5_is_e5b = true; + } } break; } @@ -874,7 +879,15 @@ bool Rtklib_Solver::get_PVT(const std::map &gnss_observables_ { for (int j = 0; j < NFREQ; j++) { - nav_data.lam[i][j] = satwavelen(i + 1, j, &nav_data); + if (j == 2 && gal_e5_is_e5b) + { + // frq = 4 corresponds to E5B in that function + nav_data.lam[i][j] = satwavelen(i + 1, 4, &nav_data); + } + else + { + nav_data.lam[i][j] = satwavelen(i + 1, j, &nav_data); + } } } 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/rtklib/rtklib_conversions.cc b/src/algorithms/libs/rtklib/rtklib_conversions.cc index e7a088941..45eacabcb 100644 --- a/src/algorithms/libs/rtklib/rtklib_conversions.cc +++ b/src/algorithms/libs/rtklib/rtklib_conversions.cc @@ -71,6 +71,10 @@ obsd_t insert_obs_to_rtklib(obsd_t& rtklib_obs, const Gnss_Synchro& gnss_synchro break; case 'E': rtklib_obs.sat = gnss_synchro.PRN + NSATGPS + NSATGLO; + if (sig_ == "7X") + { + rtklib_obs.code[band] = static_cast(CODE_L7X); + } break; case 'R': rtklib_obs.sat = gnss_synchro.PRN + NSATGPS; 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 80e8d283f..0405cdf2c 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 15) +set(VERSION_INFO_MAINT_VERSION 16) 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 94d3ca45e..97b1f6096 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 "23 Aug 2021" "0.0.15" "volk_gnsssdr\-config\-info man page" +.TH volk_gnsssdr\-config\-info 1 "15 Feb 2022" "0.0.16" "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 440fb492a..3303347a1 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 "23 Aug 2021" "0.0.15" "volk_gnsssdr_profile man page" +.TH volk_gnsssdr_profile 1 "15 Feb 2022" "0.0.16" "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 f7b79f54c..6a102773e 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() +{ + 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, "sse3", ' '); - 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/adapters/limesdr_signal_source.cc b/src/algorithms/signal_source/adapters/limesdr_signal_source.cc index 28b57716d..a8168bd82 100644 --- a/src/algorithms/signal_source/adapters/limesdr_signal_source.cc +++ b/src/algorithms/signal_source/adapters/limesdr_signal_source.cc @@ -19,6 +19,7 @@ #include "gnss_frequencies.h" #include "gnss_sdr_string_literals.h" #include "gnss_sdr_valve.h" +#include #include #include #include diff --git a/src/algorithms/signal_source/adapters/osmosdr_signal_source.cc b/src/algorithms/signal_source/adapters/osmosdr_signal_source.cc index bacc63f88..e8532d624 100644 --- a/src/algorithms/signal_source/adapters/osmosdr_signal_source.cc +++ b/src/algorithms/signal_source/adapters/osmosdr_signal_source.cc @@ -20,6 +20,7 @@ #include "configuration_interface.h" #include "gnss_sdr_string_literals.h" #include "gnss_sdr_valve.h" +#include #include #include #include diff --git a/src/algorithms/signal_source/adapters/rtl_tcp_signal_source.cc b/src/algorithms/signal_source/adapters/rtl_tcp_signal_source.cc index 5788b61b9..0c80eaaf7 100644 --- a/src/algorithms/signal_source/adapters/rtl_tcp_signal_source.cc +++ b/src/algorithms/signal_source/adapters/rtl_tcp_signal_source.cc @@ -21,6 +21,7 @@ #include "configuration_interface.h" #include "gnss_sdr_string_literals.h" #include "gnss_sdr_valve.h" +#include #include #include #include diff --git a/src/algorithms/signal_source/gnuradio_blocks/fifo_reader.cc b/src/algorithms/signal_source/gnuradio_blocks/fifo_reader.cc index 4eb7d53cf..583fe6810 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/fifo_reader.cc +++ b/src/algorithms/signal_source/gnuradio_blocks/fifo_reader.cc @@ -64,9 +64,14 @@ int FifoReader::work(int noutput_items, // ishort == int16_t items_retrieved = read_interleaved(noutput_items, output_items); } + else if (sample_type_ == "ibyte") // Does this also work with cbyte? + { + // ibyte == int8_t + items_retrieved = read_interleaved(noutput_items, output_items); + } else if (sample_type_ == "gr_complex") { - LOG(WARNING) << sample_type_ << " is not yet tested. Please consider removing this warning if tested successfully"; + // gr_complex == complex items_retrieved = read_gr_complex(noutput_items, output_items); } else @@ -80,6 +85,7 @@ int FifoReader::work(int noutput_items, return this->WORK_CALLED_PRODUCE; } + // read gr_complex items from fifo // this fct has duplicate code with the templated read_interleaved fct in header size_t FifoReader::read_gr_complex(int noutput_items, gr_vector_void_star &output_items) diff --git a/src/algorithms/signal_source/gnuradio_blocks/fifo_reader.h b/src/algorithms/signal_source/gnuradio_blocks/fifo_reader.h index 9e289ebf5..276970191 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/fifo_reader.h +++ b/src/algorithms/signal_source/gnuradio_blocks/fifo_reader.h @@ -51,8 +51,11 @@ private: FifoReader(const std::string &file_name, const std::string &sample_type); size_t read_gr_complex(int noutput_items, gr_vector_void_star &output_items); + //! function to read data out of FIFO which is stored as interleaved I/Q stream. //! template argument determines sample_type + // Note: template definition necessary in header file + // See also: https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file template size_t read_interleaved(int noutput_items, gr_vector_void_star &output_items) { @@ -61,15 +64,13 @@ private: { // TODO: try if performance increases if we copy larger chunks to vector. // how to read from stream: https://en.cppreference.com/w/cpp/io/basic_ifstream - std::array buffer; // gr_complex is 32bit = 4*char - fifo_.read(reinterpret_cast(&buffer[0]), buffer.size()); + std::array buffer; + fifo_.read(reinterpret_cast(buffer.data()), buffer.size()); if (fifo_.good()) { - Type real; - Type imag; - memcpy(&real, &buffer[0], sizeof(real)); - memcpy(&imag, &buffer[2], sizeof(imag)); - static_cast(output_items.at(0))[n] = gr_complex(real, imag); + auto real = reinterpret_cast(&buffer[0]); + auto imag = reinterpret_cast(&buffer[sizeof(Type)]); + static_cast(output_items[0])[n] = gr_complex(*real, *imag); items_retrieved++; } else if (fifo_.eof()) 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/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.cc index 75e20684e..8c259691f 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.cc @@ -662,30 +662,8 @@ int galileo_telemetry_decoder_gs::general_work(int noutput_items __attribute__(( d_band = current_symbol.Signal[0]; // add new symbol to the symbol queue - switch (d_frame_type) - { - case 1: // INAV - { - d_symbol_history.push_back(current_symbol.Prompt_I); - break; - } - case 2: // FNAV - { - d_symbol_history.push_back(current_symbol.Prompt_Q); - break; - } - case 3: // CNAV - { - d_symbol_history.push_back(current_symbol.Prompt_I); - break; - } - default: - { - LOG(WARNING) << "Frame type " << d_frame_type << " is not defined"; - d_symbol_history.push_back(current_symbol.Prompt_I); - break; - } - } + d_symbol_history.push_back(current_symbol.Prompt_I); + d_sample_counter++; // count for the processed symbols // Time Tags from signal source (optional feature) @@ -1025,18 +1003,18 @@ int galileo_telemetry_decoder_gs::general_work(int noutput_items __attribute__(( { d_TOW_at_current_symbol_ms += static_cast(GALILEO_FNAV_CODES_PER_SYMBOL * GALILEO_E5A_CODE_PERIOD_MS); } - if (d_enable_navdata_monitor && !d_nav_msg_packet.nav_message.empty()) - { - d_nav_msg_packet.system = std::string(1, current_symbol.System); - d_nav_msg_packet.signal = std::string(current_symbol.Signal); - d_nav_msg_packet.prn = static_cast(current_symbol.PRN); - d_nav_msg_packet.tow_at_current_symbol_ms = static_cast(d_TOW_at_current_symbol_ms); - const std::shared_ptr tmp_obj = std::make_shared(d_nav_msg_packet); - this->message_port_pub(pmt::mp("Nav_msg_from_TLM"), pmt::make_any(tmp_obj)); - d_nav_msg_packet.nav_message = ""; - } - break; } + if (d_enable_navdata_monitor && !d_nav_msg_packet.nav_message.empty()) + { + d_nav_msg_packet.system = std::string(1, current_symbol.System); + d_nav_msg_packet.signal = std::string(current_symbol.Signal); + d_nav_msg_packet.prn = static_cast(current_symbol.PRN); + d_nav_msg_packet.tow_at_current_symbol_ms = static_cast(d_TOW_at_current_symbol_ms); + const std::shared_ptr tmp_obj = std::make_shared(d_nav_msg_packet); + this->message_port_pub(pmt::mp("Nav_msg_from_TLM"), pmt::make_any(tmp_obj)); + d_nav_msg_packet.nav_message = ""; + } + break; } case 3: // CNAV { diff --git a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc index c1b6a69d5..81f56c3fc 100644 --- a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc +++ b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc @@ -305,6 +305,7 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) // remove data secondary code d_data_secondary_code_length = static_cast(GALILEO_E5A_I_SECONDARY_CODE_LENGTH); d_data_secondary_code_string = GALILEO_E5A_I_SECONDARY_CODE; + d_interchange_iq = true; } else { @@ -312,7 +313,6 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) d_secondary_code_length = static_cast(GALILEO_E5A_I_SECONDARY_CODE_LENGTH); d_secondary_code_string = GALILEO_E5A_I_SECONDARY_CODE; d_signal_pretty_name = d_signal_pretty_name + "I"; - d_interchange_iq = true; } } else if (d_signal_type == "7X") @@ -336,6 +336,7 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) // remove data secondary code d_data_secondary_code_length = static_cast(GALILEO_E5B_I_SECONDARY_CODE_LENGTH); d_data_secondary_code_string = GALILEO_E5B_I_SECONDARY_CODE; + d_interchange_iq = true; } else { @@ -343,7 +344,6 @@ dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) d_secondary_code_length = static_cast(GALILEO_E5B_I_SECONDARY_CODE_LENGTH); d_secondary_code_string = GALILEO_E5B_I_SECONDARY_CODE; d_signal_pretty_name = d_signal_pretty_name + "I"; - d_interchange_iq = true; } } else if (d_signal_type == "E6") diff --git a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.cc b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.cc index 63f409c23..5dfe72fe4 100644 --- a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.cc +++ b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking_fpga.cc @@ -303,7 +303,7 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(const Dll_Pll_Conf_Fpga & // remove data secondary code d_data_secondary_code_length = static_cast(GALILEO_E5A_I_SECONDARY_CODE_LENGTH); d_data_secondary_code_string = GALILEO_E5A_I_SECONDARY_CODE; - + d_interchange_iq = true; // the pilot secondary code depends on PRN and it is initialized later } else @@ -312,7 +312,6 @@ dll_pll_veml_tracking_fpga::dll_pll_veml_tracking_fpga(const Dll_Pll_Conf_Fpga & d_secondary_code_length = static_cast(GALILEO_E5A_I_SECONDARY_CODE_LENGTH); d_secondary_code_string = GALILEO_E5A_I_SECONDARY_CODE; d_signal_pretty_name = d_signal_pretty_name + "I"; - d_interchange_iq = true; } } else 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/algorithms/tracking/libs/CMakeLists.txt b/src/algorithms/tracking/libs/CMakeLists.txt index 24e6e73ca..b8e80cd37 100644 --- a/src/algorithms/tracking/libs/CMakeLists.txt +++ b/src/algorithms/tracking/libs/CMakeLists.txt @@ -89,6 +89,7 @@ target_link_libraries(tracking_libs PRIVATE gnss_sdr_flags Glog::glog + Gnuradio::runtime ) if(ENABLE_CUDA) diff --git a/src/algorithms/tracking/libs/tracking_discriminators.cc b/src/algorithms/tracking/libs/tracking_discriminators.cc index 39917c3a0..cc9a38c98 100644 --- a/src/algorithms/tracking/libs/tracking_discriminators.cc +++ b/src/algorithms/tracking/libs/tracking_discriminators.cc @@ -20,6 +20,7 @@ #include "tracking_discriminators.h" #include "MATH_CONSTANTS.h" +#include // All the outputs are in RADIANS @@ -53,7 +54,7 @@ double fll_four_quadrant_atan(gr_complex prompt_s1, gr_complex prompt_s2, double { const float dot = prompt_s1.real() * prompt_s2.real() + prompt_s1.imag() * prompt_s2.imag(); const float cross = prompt_s1.real() * prompt_s2.imag() - prompt_s2.real() * prompt_s1.imag(); - return std::atan2(cross, dot) / (t2 - t1); + return static_cast(gr::fast_atan2f(cross, dot) / (t2 - t1)); } @@ -84,7 +85,7 @@ double fll_diff_atan(gr_complex prompt_s1, gr_complex prompt_s2, double t1, doub */ double pll_four_quadrant_atan(gr_complex prompt_s1) { - return static_cast(std::atan2(prompt_s1.imag(), prompt_s1.real())); + return static_cast(gr::fast_atan2f(prompt_s1.imag(), prompt_s1.real())); } 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 544b7b444..05b84eed1 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.15" +#define GNSS_SDR_VERSION "0.0.16" #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/benchmarks/CMakeLists.txt b/src/tests/benchmarks/CMakeLists.txt index c5fddced7..680a616f5 100644 --- a/src/tests/benchmarks/CMakeLists.txt +++ b/src/tests/benchmarks/CMakeLists.txt @@ -102,6 +102,7 @@ add_benchmark(benchmark_copy) add_benchmark(benchmark_preamble core_system_parameters) add_benchmark(benchmark_detector core_system_parameters) add_benchmark(benchmark_reed_solomon core_system_parameters) +add_benchmark(benchmark_atan2 Gnuradio::runtime) if(has_std_plus_void) target_compile_definitions(benchmark_detector PRIVATE -DCOMPILER_HAS_STD_PLUS_VOID=1) diff --git a/src/tests/benchmarks/benchmark_atan2.cc b/src/tests/benchmarks/benchmark_atan2.cc new file mode 100644 index 000000000..0d64f0070 --- /dev/null +++ b/src/tests/benchmarks/benchmark_atan2.cc @@ -0,0 +1,65 @@ +/*! + * \file benchmark_atan2.cc + * \brief Benchmark for atan2 implementations + * \author Carles Fernandez-Prades, 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) 2022 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#include +#include +#include +#include + +void bm_std_atan2(benchmark::State& state) +{ + std::random_device rd; + std::default_random_engine e2(rd()); + std::uniform_real_distribution<> dist(-1.0, 1.0); + + float a = dist(e2); + float b = dist(e2); + float c; + while (state.KeepRunning()) + { + c = std::atan2(a, b); + } + if (c > 1.0) + { + // Avoid unused-but-set-variable warning + } +} + + +void bm_gr_fast_atan2f(benchmark::State& state) +{ + std::random_device rd; + std::default_random_engine e2(rd()); + std::uniform_real_distribution<> dist(-1.0, 1.0); + + float a = dist(e2); + float b = dist(e2); + float c; + while (state.KeepRunning()) + { + c = gr::fast_atan2f(a, b); + } + if (c > 1.0) + { + // Avoid unused-but-set-variable warning + } +} + +BENCHMARK(bm_std_atan2); +BENCHMARK(bm_gr_fast_atan2f); + +BENCHMARK_MAIN(); 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