1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-07-02 09:53:15 +00:00

Merge branch 'next' into galileo-e6

This commit is contained in:
Carles Fernandez 2022-05-12 21:09:18 +02:00
commit 0804429f2c
No known key found for this signature in database
GPG Key ID: 4C583C52B0C3877D
210 changed files with 2745 additions and 17447 deletions

View File

@ -17,13 +17,13 @@ Contact Information
CTTC Homepage CTTC Homepage
---------------------------- ----------------------------
http://www.cttc.cat https://www.cttc.cat
Mailing List Mailing List
---------------------------- ----------------------------
gnss-sdr-developers@lists.sourceforge.net 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 Email
@ -61,7 +61,8 @@ Marc Sales marcsales92@gmail.com Contributor
Piyush Gupta piyush04111999@gmail.com Contributor Piyush Gupta piyush04111999@gmail.com Contributor
Rodrigo Muñoz rodrigo.munoz@proteinlab.cl Contributor Rodrigo Muñoz rodrigo.munoz@proteinlab.cl Contributor
Stefan van der Linden spvdlinden@gmail.com Contributor Stefan van der Linden spvdlinden@gmail.com Contributor
Will Silberman wsilberm@google.com Contributor
Carlos Paniego carpanie@hotmail.com Artwork Carlos Paniego carpanie@hotmail.com Artwork
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: 2011-2020 Carles Fernandez-Prades <carles.fernandez@cttc.es> # SPDX-FileCopyrightText: 2011-2022 Carles Fernandez-Prades <carles.fernandez@cttc.es>

View File

@ -93,6 +93,10 @@ authors:
email: jschindehette@geontech.com email: jschindehette@geontech.com
family-names: Schindehette family-names: Schindehette
given-names: Josh given-names: Josh
- alias: orlando017
email: wsilberm@google.com
family-names: Silberman
given-names: Will
- email: tonetto.dev@gmail.com - email: tonetto.dev@gmail.com
family-names: Tonetto family-names: Tonetto
given-names: Leonardo given-names: Leonardo
@ -101,7 +105,7 @@ authors:
family-names: "van der Linden" family-names: "van der Linden"
given-names: Stefan given-names: Stefan
cff-version: "1.2.0" cff-version: "1.2.0"
date-released: "2022-02-15" date-released: "2022-04-20"
identifiers: identifiers:
- description: "The concept DOI of the work. This is a DOI always pointing to the latest stable release." - description: "The concept DOI of the work. This is a DOI always pointing to the latest stable release."
type: doi type: doi
@ -325,4 +329,4 @@ repository-code: "https://github.com/gnss-sdr/gnss-sdr"
title: GNSS-SDR title: GNSS-SDR
type: software type: software
url: "https://gnss-sdr.org" url: "https://gnss-sdr.org"
version: "0.0.16" version: "0.0.17"

View File

@ -16,7 +16,7 @@ endif()
# Build type can still be overridden by setting -DCMAKE_BUILD_TYPE= # Build type can still be overridden by setting -DCMAKE_BUILD_TYPE=
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "") set(CMAKE_BUILD_TYPE "Release" CACHE STRING "")
cmake_minimum_required(VERSION 2.8.12...3.22) cmake_minimum_required(VERSION 2.8.12...3.23)
project(gnss-sdr CXX C) project(gnss-sdr CXX C)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules) list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules)
@ -101,7 +101,7 @@ option(ENABLE_SYSTEM_TESTING_EXTRA "Download external tools and build extra syst
option(ENABLE_GNSS_SIM_INSTALL "Enable the installation of gnss_sim on the fly" ON) option(ENABLE_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)) if(NOT (ENABLE_UNIT_TESTING_EXTRA OR ENABLE_SYSTEM_TESTING_EXTRA OR ENABLE_FPGA))
set(ENABLE_GNSS_SIM_INSTALL OFF) set(ENABLE_GNSS_SIM_INSTALL OFF)
@ -166,9 +166,9 @@ endif()
set(VERSION_INFO_MAJOR_VERSION 0) set(VERSION_INFO_MAJOR_VERSION 0)
set(VERSION_INFO_API_COMPAT 0) set(VERSION_INFO_API_COMPAT 0)
if(${THIS_IS_A_RELEASE}) if(${THIS_IS_A_RELEASE})
set(VERSION_INFO_MINOR_VERSION 16) set(VERSION_INFO_MINOR_VERSION 17)
else() else()
set(VERSION_INFO_MINOR_VERSION 16.git-${GIT_BRANCH}-${GIT_COMMIT_HASH}) set(VERSION_INFO_MINOR_VERSION 17.git-${GIT_BRANCH}-${GIT_COMMIT_HASH})
endif() endif()
set(VERSION ${VERSION_INFO_MAJOR_VERSION}.${VERSION_INFO_API_COMPAT}.${VERSION_INFO_MINOR_VERSION}) set(VERSION ${VERSION_INFO_MAJOR_VERSION}.${VERSION_INFO_API_COMPAT}.${VERSION_INFO_MINOR_VERSION})
@ -320,8 +320,8 @@ set(GNSSSDR_PROTOBUF_MIN_VERSION "3.0.0")
# Versions to download and build (but not installed) if not found # Versions to download and build (but not installed) if not found
################################################################################ ################################################################################
set(GNSSSDR_GFLAGS_LOCAL_VERSION "2.2.2") 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") set(GNSSSDR_ARMADILLO_LOCAL_VERSION "11.0.x")
if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0) OR 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)) (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0))
set(GNSSSDR_GTEST_LOCAL_VERSION "1.10.x") set(GNSSSDR_GTEST_LOCAL_VERSION "1.10.x")
@ -330,12 +330,16 @@ else()
endif() endif()
set(GNSSSDR_GNSS_SIM_LOCAL_VERSION "master") set(GNSSSDR_GNSS_SIM_LOCAL_VERSION "master")
set(GNSSSDR_GPSTK_LOCAL_VERSION "8.0.0") set(GNSSSDR_GPSTK_LOCAL_VERSION "8.0.0")
set(GNSSSDR_MATIO_LOCAL_VERSION "1.5.22") set(GNSSSDR_MATIO_LOCAL_VERSION "1.5.23")
set(GNSSSDR_PUGIXML_LOCAL_VERSION "1.12") set(GNSSSDR_PUGIXML_LOCAL_VERSION "1.12")
set(GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION "3.19.4") set(GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION "3.20.1")
set(GNSSSDR_BENCHMARK_LOCAL_VERSION "1.6.1") set(GNSSSDR_BENCHMARK_LOCAL_VERSION "1.6.1")
set(GNSSSDR_MATHJAX_EXTERNAL_VERSION "2.7.7") 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") if(CMAKE_VERSION VERSION_LESS "3.3")
set(GNSSSDR_GLOG_LOCAL_VERSION "0.4.0") # Fix for Debian 8 set(GNSSSDR_GLOG_LOCAL_VERSION "0.4.0") # Fix for Debian 8
endif() endif()
@ -1156,7 +1160,6 @@ if(NOT VOLKGNSSSDR_FOUND)
set(VOLK_GNSSSDR_CMAKE_ARGS ${VOLK_GNSSSDR_COMPILER} set(VOLK_GNSSSDR_CMAKE_ARGS ${VOLK_GNSSSDR_COMPILER}
-DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/volk_gnsssdr_module/install -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/volk_gnsssdr_module/install
-DENABLE_STATIC_LIBS=ON -DENABLE_STATIC_LIBS=ON
-DENABLE_OWN_CPUFEATURES=${ENABLE_OWN_CPUFEATURES}
-DENABLE_PROFILING=${ENABLE_PROFILING} -DENABLE_PROFILING=${ENABLE_PROFILING}
-DENABLE_ORC=${ORC_ENABLED} -DENABLE_ORC=${ORC_ENABLED}
${STRIP_VOLK_GNSSSDR_PROFILE} ${STRIP_VOLK_GNSSSDR_PROFILE}
@ -1193,15 +1196,8 @@ if(NOT VOLKGNSSSDR_FOUND)
endif() endif()
include(GNUInstallDirs) include(GNUInstallDirs)
set(SUPPORTED_CPU_FEATURES_ARCH FALSE) set(SUPPORTED_CPU_FEATURES_ARCH FALSE)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips") if(CMAKE_SYSTEM_PROCESSOR MATCHES
set(SUPPORTED_CPU_FEATURES_ARCH TRUE) "(^mips)|(^arm)|(^aarch64)|(x86_64)|(AMD64|amd64)|(^i.86$)|(^powerpc)|(^ppc)")
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)")
set(SUPPORTED_CPU_FEATURES_ARCH TRUE) set(SUPPORTED_CPU_FEATURES_ARCH TRUE)
endif() endif()
if(${CMAKE_INSTALL_LIBDIR} MATCHES lib64) if(${CMAKE_INSTALL_LIBDIR} MATCHES lib64)
@ -1227,22 +1223,27 @@ 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/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 ${CMAKE_BINARY_DIR}/volk_gnsssdr_module/install/bin/volk_gnsssdr_profile
) )
if(NOT ENABLE_OWN_CPUFEATURES) if(ENABLE_CPUFEATURES)
find_package(CpuFeatures QUIET) find_package(CPUFEATURES)
set_package_properties(CpuFeatures PROPERTIES set_package_properties(CPUFEATURES PROPERTIES
URL "https://github.com/google/cpu_features" URL "https://github.com/google/cpu_features"
PURPOSE "Used by the volk_gnsssdr library." PURPOSE "Used by the volk_gnsssdr library."
TYPE REQUIRED TYPE REQUIRED
) )
endif() endif()
if(CpuFeatures_FOUND) if(CPUFEATURES_FOUND)
message(STATUS "Found CpuFeatures: (found version ${CpuFeatures_VERSION})") 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})" DESCRIPTION "A cross platform C99 library to get CPU features at runtime (version: ${CPUFEATURES_VERSION})"
) )
else() else()
set_package_properties(CpuFeatures PROPERTIES set_package_properties(CPUFEATURES PROPERTIES
DESCRIPTION "A cross platform C99 library to get CPU features at runtime" DESCRIPTION "A cross platform C99 library to get CPU features at runtime"
)
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}'." PURPOSE "CpuFeatures will be built when doing '${CMAKE_MAKE_PROGRAM_PRETTY_NAME}'."
) )
set(VOLK_GNSSSDR_BUILD_BYPRODUCTS set(VOLK_GNSSSDR_BUILD_BYPRODUCTS
@ -1250,6 +1251,10 @@ if(NOT VOLKGNSSSDR_FOUND)
${CMAKE_BINARY_DIR}/volk_gnsssdr_module/install/${CMAKE_INSTALL_LIBDIR}/${CMAKE_FIND_LIBRARY_PREFIXES}cpu_features${CMAKE_STATIC_LIBRARY_SUFFIX} ${CMAKE_BINARY_DIR}/volk_gnsssdr_module/install/${CMAKE_INSTALL_LIBDIR}/${CMAKE_FIND_LIBRARY_PREFIXES}cpu_features${CMAKE_STATIC_LIBRARY_SUFFIX}
) )
endif() endif()
endif()
set(VOLK_GNSSSDR_CMAKE_ARGS ${VOLK_GNSSSDR_CMAKE_ARGS}
-DVOLK_CPU_FEATURES=${ENABLE_CPUFEATURES}
)
ExternalProject_Add(volk_gnsssdr_module ExternalProject_Add(volk_gnsssdr_module
PREFIX ${CMAKE_BINARY_DIR}/volk_gnsssdr_module PREFIX ${CMAKE_BINARY_DIR}/volk_gnsssdr_module
SOURCE_DIR ${CMAKE_SOURCE_DIR}/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr SOURCE_DIR ${CMAKE_SOURCE_DIR}/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr
@ -1265,6 +1270,10 @@ if(NOT VOLKGNSSSDR_FOUND)
INSTALL_DIR ${CMAKE_BINARY_DIR}/volk_gnsssdr_module/install INSTALL_DIR ${CMAKE_BINARY_DIR}/volk_gnsssdr_module/install
) )
else() else()
set(ENABLE_CPUFEATURES OFF)
set(VOLK_GNSSSDR_CMAKE_ARGS ${VOLK_GNSSSDR_CMAKE_ARGS}
-DVOLK_CPU_FEATURES=${ENABLE_CPUFEATURES}
)
ExternalProject_Add(volk_gnsssdr_module ExternalProject_Add(volk_gnsssdr_module
PREFIX ${CMAKE_BINARY_DIR}/volk_gnsssdr_module PREFIX ${CMAKE_BINARY_DIR}/volk_gnsssdr_module
SOURCE_DIR ${CMAKE_SOURCE_DIR}/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr SOURCE_DIR ${CMAKE_SOURCE_DIR}/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr
@ -1292,8 +1301,8 @@ if(NOT VOLKGNSSSDR_FOUND)
set_property(TARGET volk_gnsssdr PROPERTY IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/volk_gnsssdr_module/install/lib${VOLK_GNSSSDR_LIB_SUFFIX}/libvolk_gnsssdr${CMAKE_STATIC_LIBRARY_SUFFIX}) set_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_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}) set(VOLK_GNSSSDR_LIBRARIES volk_gnsssdr ${ORC_LIBRARIES_STATIC})
if(CpuFeatures_FOUND) if(CPUFEATURES_FOUND)
set(VOLK_GNSSSDR_LIBRARIES ${VOLK_GNSSSDR_LIBRARIES} CpuFeatures::cpu_features) set(VOLK_GNSSSDR_LIBRARIES ${VOLK_GNSSSDR_LIBRARIES} CpuFeature::cpu_features)
endif() endif()
if(NOT TARGET Volkgnsssdr::volkgnsssdr) if(NOT TARGET Volkgnsssdr::volkgnsssdr)
@ -1308,7 +1317,7 @@ if(NOT VOLKGNSSSDR_FOUND)
INTERFACE_LINK_LIBRARIES "${VOLK_GNSSSDR_LIBRARIES}" INTERFACE_LINK_LIBRARIES "${VOLK_GNSSSDR_LIBRARIES}"
) )
if(CMAKE_VERSION VERSION_GREATER 3.0 AND SUPPORTED_CPU_FEATURES_ARCH) 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 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} INTERFACE_LINK_LIBRARIES ${CMAKE_BINARY_DIR}/volk_gnsssdr_module/install/${CMAKE_INSTALL_LIBDIR}/${CMAKE_FIND_LIBRARY_PREFIXES}cpu_features${CMAKE_STATIC_LIBRARY_SUFFIX}
) )
@ -1338,7 +1347,6 @@ if(NOT VOLKGNSSSDR_FOUND)
PURPOSE "volk_gnsssdr will be built when doing '${CMAKE_MAKE_PROGRAM_PRETTY_NAME}'." PURPOSE "volk_gnsssdr will be built when doing '${CMAKE_MAKE_PROGRAM_PRETTY_NAME}'."
) )
else() else()
set(ENABLE_OWN_CPUFEATURES OFF)
set(ENABLE_ORC OFF) set(ENABLE_ORC OFF)
endif() endif()
@ -1674,9 +1682,12 @@ ${CMAKE_BINARY_DIR}/thirdparty/glog/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/configure
${CMAKE_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/${CMAKE_FIND_LIBRARY_PREFIXES}glogd${CMAKE_STATIC_LIBRARY_SUFFIX} ${CMAKE_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/${CMAKE_FIND_LIBRARY_PREFIXES}glogd${CMAKE_STATIC_LIBRARY_SUFFIX}
) )
endif() 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") set(PARALLEL_BUILD "--parallel 2")
endif() 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} ExternalProject_Add(glog-${GNSSSDR_GLOG_LOCAL_VERSION}
DEPENDS ${TARGET_GFLAGS} DEPENDS ${TARGET_GFLAGS}
PREFIX ${CMAKE_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION} PREFIX ${CMAKE_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}
@ -1689,6 +1700,7 @@ ${CMAKE_BINARY_DIR}/thirdparty/glog/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/configure
${GLOG_TOOLCHAIN_FILE} ${GLOG_TOOLCHAIN_FILE}
-DCMAKE_BUILD_TYPE=$<$<CONFIG:Debug>:Debug>$<$<CONFIG:Release>:Release>$<$<CONFIG:RelWithDebInfo>:RelWithDebInfo>$<$<CONFIG:MinSizeRel>:MinSizeRel>$<$<CONFIG:NoOptWithASM>:Debug>$<$<CONFIG:Coverage>:Debug>$<$<CONFIG:O2WithASM>:RelWithDebInfo>$<$<CONFIG:O3WithASM>:RelWithDebInfo>$<$<CONFIG:ASAN>:Debug> -DCMAKE_BUILD_TYPE=$<$<CONFIG:Debug>:Debug>$<$<CONFIG:Release>:Release>$<$<CONFIG:RelWithDebInfo>:RelWithDebInfo>$<$<CONFIG:MinSizeRel>:MinSizeRel>$<$<CONFIG:NoOptWithASM>:Debug>$<$<CONFIG:Coverage>:Debug>$<$<CONFIG:O2WithASM>:RelWithDebInfo>$<$<CONFIG:O3WithASM>:RelWithDebInfo>$<$<CONFIG:ASAN>:Debug>
-DBUILD_SHARED_LIBS=OFF -DBUILD_SHARED_LIBS=OFF
${GLOG_GTEST}
-DBUILD_TESTING=OFF -DBUILD_TESTING=OFF
BUILD_COMMAND "${GLOG_MAKE_PROGRAM} ${PARALLEL_BUILD}" BUILD_COMMAND "${GLOG_MAKE_PROGRAM} ${PARALLEL_BUILD}"
BUILD_BYPRODUCTS ${GLOG_BUILD_BYPRODUCTS} BUILD_BYPRODUCTS ${GLOG_BUILD_BYPRODUCTS}
@ -3353,7 +3365,7 @@ add_feature_info(ENABLE_GNSS_SIM_INSTALL ENABLE_GNSS_SIM_INSTALL "Enables downlo
add_feature_info(ENABLE_INSTALL_TESTS ENABLE_INSTALL_TESTS "Install test binaries when doing '${CMAKE_MAKE_PROGRAM_PRETTY_NAME} install'.") add_feature_info(ENABLE_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_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_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.") add_feature_info(Boost_USE_STATIC_LIBS Boost_USE_STATIC_LIBS "Use Boost static libraries.")
message(STATUS "") message(STATUS "")

View File

@ -170,6 +170,9 @@ Please note that the required files from `libgtest-dev` were moved to
again to `libgtest-dev` in Debian 10 "buster" and Ubuntu 18.10 "cosmic" (and again to `libgtest-dev` in Debian 10 "buster" and Ubuntu 18.10 "cosmic" (and
above). above).
Since Ubuntu 21.04 Hirsute / Debian 11, the package `libcpu-features-dev` is
also required.
**Note for Ubuntu 14.04 LTS "trusty" users:** you will need to build from source **Note for Ubuntu 14.04 LTS "trusty" users:** you will need to build from source
and install GNU Radio manually, as explained below, since GNSS-SDR requires and install GNU Radio manually, as explained below, since GNSS-SDR requires
`gnuradio-dev` >= 3.7.3, and Ubuntu 14.04 came with 3.7.2. Install all the `gnuradio-dev` >= 3.7.3, and Ubuntu 14.04 came with 3.7.2. Install all the
@ -378,9 +381,9 @@ $ sudo apt-get install libblas-dev liblapack-dev # For Debian/Ubuntu/Linux
$ sudo yum install lapack-devel blas-devel # For Fedora/CentOS/RHEL $ sudo yum install lapack-devel blas-devel # For Fedora/CentOS/RHEL
$ sudo zypper install lapack-devel blas-devel # For OpenSUSE $ sudo zypper install lapack-devel blas-devel # For OpenSUSE
$ sudo pacman -S blas lapack # For Arch Linux $ sudo pacman -S blas lapack # For Arch Linux
$ wget https://sourceforge.net/projects/arma/files/armadillo-10.8.0.tar.xz $ wget https://sourceforge.net/projects/arma/files/armadillo-11.0.1.tar.xz
$ tar xvfz armadillo-10.8.0.tar.xz $ tar xvfz armadillo-11.0.1.tar.xz
$ cd armadillo-10.8.0 $ cd armadillo-11.0.1
$ cmake . $ cmake .
$ make $ make
$ sudo make install $ sudo make install
@ -470,9 +473,9 @@ your GNU/Linux distribution, GNSS-SDR can also work well with OpenSSL.
#### Install [Matio](https://github.com/tbeu/matio "Matio's Homepage"), MATLAB MAT file I/O library: #### Install [Matio](https://github.com/tbeu/matio "Matio's Homepage"), MATLAB MAT file I/O library:
``` ```
$ wget https://github.com/tbeu/matio/releases/download/v1.5.22/matio-1.5.22.tar.gz $ wget https://github.com/tbeu/matio/releases/download/v1.5.23/matio-1.5.23.tar.gz
$ tar xvfz matio-1.5.22.tar.gz $ tar xvfz matio-1.5.23.tar.gz
$ cd matio-1.5.22 $ cd matio-1.5.23
$ ./configure $ ./configure
$ make $ make
$ sudo make install $ sudo make install
@ -493,9 +496,9 @@ $ sudo apt-get install autoconf automake libtool curl make g++ unzip
and then: and then:
``` ```
$ wget https://github.com/protocolbuffers/protobuf/releases/download/v3.19.4/protobuf-cpp-3.19.4.tar.gz $ wget https://github.com/protocolbuffers/protobuf/releases/download/v3.20.1/protobuf-cpp-3.20.1.tar.gz
$ tar xvfz protobuf-cpp-3.19.4.tar.gz $ tar xvfz protobuf-cpp-3.20.1.tar.gz
$ cd protobuf-3.19.4 $ cd protobuf-3.20.1
$ ./autogen.sh $ ./autogen.sh
$ ./configure $ ./configure
$ make $ make
@ -2128,7 +2131,7 @@ if you reference the following article to credit the GNSS-SDR project:
- C. Fern&aacute;ndez-Prades, J. Arribas, P. Closas, C. Avil&eacute;s, and L. - C. Fern&aacute;ndez-Prades, J. Arribas, P. Closas, C. Avil&eacute;s, and L.
Esteve, Esteve,
[GNSS-SDR: an open source tool for researchers and developers](http://www.cttc.es/publication/gnss-sdr-an-open-source-tool-for-researchers-and-developers/), [GNSS-SDR: an open source tool for researchers and developers](https://www.researchgate.net/publication/233380791_GNSS-SDR_An_open_source_tool_for_researchers_and_developers),
in Proceedings of the 24th International Technical Meeting of The Satellite in Proceedings of the 24th International Technical Meeting of The Satellite
Division of the Institute of Navigation (ION GNSS), Portland, Oregon, Sept. Division of the Institute of Navigation (ION GNSS), Portland, Oregon, Sept.
19-23, 2011, pp. 780-794. 19-23, 2011, pp. 780-794.

View File

@ -20,11 +20,13 @@ if(DEFINED ENV{BLAS_ROOT})
endif() endif()
find_library(BLAS_LIBRARIES find_library(BLAS_LIBRARIES
libblas.dylib NAMES libblas.dylib libopenblas.dylib
PATHS PATHS
${BLAS_ROOT_USER_DEFINED}
${BLAS_ROOT_USER_DEFINED}/lapack
/opt/local/lib/lapack /opt/local/lib/lapack
/opt/local/lib/
/usr/local/opt/lapack/lib /usr/local/opt/lapack/lib
/usr/local/lib
NO_DEFAULT_PATH NO_DEFAULT_PATH
NO_SYSTEM_ENVIRONMENT_PATH NO_SYSTEM_ENVIRONMENT_PATH
NO_CMAKE_ENVIRONMENT_PATH NO_CMAKE_ENVIRONMENT_PATH
@ -34,6 +36,7 @@ find_library(BLAS_LIBRARIES
if(BLAS_LIBRARIES) if(BLAS_LIBRARIES)
set(BLAS_FOUND TRUE) set(BLAS_FOUND TRUE)
message(STATUS "BLAS library found at ${BLAS_LIBRARIES}")
endif() endif()
@ -41,9 +44,9 @@ find_library(LAPACK_LIBRARIES
liblapack.dylib liblapack.dylib
PATHS PATHS
${BLAS_ROOT_USER_DEFINED} ${BLAS_ROOT_USER_DEFINED}
${BLAS_ROOT_USER_DEFINED}/lapack
/opt/local/lib/lapack /opt/local/lib/lapack
/usr/local/opt/lapack/lib /usr/local/opt/lapack/lib
/usr/local/lib
NO_DEFAULT_PATH NO_DEFAULT_PATH
NO_SYSTEM_ENVIRONMENT_PATH NO_SYSTEM_ENVIRONMENT_PATH
NO_CMAKE_ENVIRONMENT_PATH NO_CMAKE_ENVIRONMENT_PATH
@ -53,4 +56,5 @@ find_library(LAPACK_LIBRARIES
if(LAPACK_LIBRARIES) if(LAPACK_LIBRARIES)
set(LAPACK_FOUND TRUE) set(LAPACK_FOUND TRUE)
message(STATUS "LAPACK library found at ${LAPACK_LIBRARIES}")
endif() endif()

View File

@ -0,0 +1,91 @@
# GNSS-SDR is a Global Navigation Satellite System software-defined receiver.
# This file is part of GNSS-SDR.
#
# SPDX-FileCopyrightText: 2021 C. Fernandez-Prades cfernandez(at)cttc.es
# SPDX-License-Identifier: BSD-3-Clause
set(FPHSA_NAME_MISMATCHED ON)
find_library(CPUFEATURES_LIBRARIES
NAMES cpu_features
PATHS /usr/lib
/usr/lib64
/usr/lib/x86_64-linux-gnu
/usr/lib/i386-linux-gnu
/usr/lib/arm-linux-gnueabihf
/usr/lib/arm-linux-gnueabi
/usr/lib/aarch64-linux-gnu
/usr/lib/mipsel-linux-gnu
/usr/lib/mips-linux-gnu
/usr/lib/mips64el-linux-gnuabi64
/usr/lib/powerpc-linux-gnu
/usr/lib/powerpc64-linux-gnu
/usr/lib/powerpc64le-linux-gnu
/usr/lib/powerpc-linux-gnuspe
/usr/lib/hppa-linux-gnu
/usr/lib/s390x-linux-gnu
/usr/lib/i386-gnu
/usr/lib/hppa-linux-gnu
/usr/lib/x86_64-kfreebsd-gnu
/usr/lib/i386-kfreebsd-gnu
/usr/lib/m68k-linux-gnu
/usr/lib/sh4-linux-gnu
/usr/lib/sparc64-linux-gnu
/usr/lib/x86_64-linux-gnux32
/usr/lib/alpha-linux-gnu
/usr/lib/riscv64-linux-gnu
/usr/local/lib
/usr/local/lib64
/opt/local/lib
)
find_path(CPUFEATURES_INCLUDE_DIR cpu_features_macros.h
PATHS $ENV{CPUFEATURES_DIR}/include
$ENV{CPUFEATURES_DIR}
/usr/include
/usr/local/include
~/Library/Frameworks
/Library/Frameworks
/sw/include # Fink
/opt/local/include # MacPorts
/opt/csw/include # Blastwave
PATH_SUFFIXES cpu_features
)
if(CPUFEATURES_INCLUDE_DIR AND CPUFEATURES_LIBRARIES)
if(NOT PACKAGE_VERSION)
set(PACKAGE_VERSION "")
endif()
set(OLD_PACKAGE_VERSION ${PACKAGE_VERSION})
unset(PACKAGE_VERSION)
list(GET CPUFEATURES_LIBRARIES 0 FIRST_DIR)
get_filename_component(CPUFEATURES_LIBRARIES_PATH ${FIRST_DIR} DIRECTORY)
if(EXISTS ${CPUFEATURES_LIBRARIES_PATH}/cmake/CpuFeatures/CpuFeaturesConfigVersion.cmake)
include(${CPUFEATURES_LIBRARIES_PATH}/cmake/CpuFeatures/CpuFeaturesConfigVersion.cmake)
endif()
if(PACKAGE_VERSION)
set(CPUFEATURES_VERSION ${PACKAGE_VERSION})
else()
set(CPUFEATURES_VERSION "Unknown")
endif()
set(PACKAGE_VERSION ${OLD_PACKAGE_VERSION})
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(CPUFEATURES
DEFAULT_MSG
CPUFEATURES_LIBRARIES
CPUFEATURES_INCLUDE_DIR
)
if(CPUFEATURES_FOUND AND NOT TARGET CpuFeature::cpu_features)
add_library(CpuFeature::cpu_features STATIC IMPORTED)
set_target_properties(CpuFeature::cpu_features PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
IMPORTED_LOCATION "${CPUFEATURES_LIBRARIES}"
INTERFACE_INCLUDE_DIRECTORIES "${CPUFEATURES_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${CPUFEATURES_LIBRARIES}"
)
endif()
mark_as_advanced(CPUFEATURES_LIBRARIES)

View File

@ -12,7 +12,7 @@
;######### GLOBAL OPTIONS ################## ;######### GLOBAL OPTIONS ##################
;internal_fs_sps: Internal signal sampling frequency after the signal conditioning stage [sps]. ;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 ;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.internal_fs_sps=4000000
GNSS-SDR.use_acquisition_resampler=true GNSS-SDR.use_acquisition_resampler=true

View File

@ -12,7 +12,8 @@
;######### GLOBAL OPTIONS ################## ;######### GLOBAL OPTIONS ##################
;internal_fs_sps: Internal signal sampling frequency after the signal conditioning stage [samples per second]. ;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 ;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 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. ;#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 ;#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 ;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.sampling_frequency=1200000
InputFilter.IF=80558 InputFilter.IF=80558

View File

@ -12,7 +12,7 @@
;######### GLOBAL OPTIONS ################## ;######### GLOBAL OPTIONS ##################
;internal_fs_sps: Internal signal sampling frequency after the signal conditioning stage [samples per second]. ;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 ;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 GNSS-SDR.internal_fs_sps=1999898
@ -34,7 +34,7 @@ GNSS-SDR.SUPL_CI=0x31b0
SignalSource.implementation=Osmosdr_Signal_Source SignalSource.implementation=Osmosdr_Signal_Source
SignalSource.item_type=gr_complex SignalSource.item_type=gr_complex
; FOR USE GNSS-SDR WITH RTLSDR DONGLES USER MUST SET THE CALIBRATED SAMPLE RATE HERE ; 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.sampling_frequency=2000000
SignalSource.freq=1575420000 SignalSource.freq=1575420000
SignalSource.gain=40 SignalSource.gain=40
@ -88,7 +88,7 @@ InputFilter.band2_error=1.0
InputFilter.filter_type=bandpass InputFilter.filter_type=bandpass
InputFilter.grid_density=16 InputFilter.grid_density=16
;FOR USE GNSS-SDR WITH RTLSDR DONGLES USER MUST SET THE CALIBRATED SAMPLE RATE HERE ;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.sampling_frequency=1999898
InputFilter.IF=80558 ; IF deviation due to front-end LO inaccuracies [Hz] InputFilter.IF=80558 ; IF deviation due to front-end LO inaccuracies [Hz]

View File

@ -14,15 +14,53 @@ All notable changes to GNSS-SDR will be documented in this file.
## [Unreleased](https://github.com/gnss-sdr/gnss-sdr/tree/next) ## [Unreleased](https://github.com/gnss-sdr/gnss-sdr/tree/next)
### Improvements in Portability:
- Improved detection of the BLAS library under macOS / Macports (the `lapack`
port dependency installed with the `+openblas` variant does not install `blas`
but `openblas`, which is used as a replacement if `blas` is not found).
- Removed duplicated files in the Secure User Plane Location implementation,
which caused issues when linking with some compilers.
- Added support for Xilinx's Zynq UltraScale+ devices (requires the
`-DENABLE_FPGA=ON` building option).
### Improvements in Usability:
- Fixed large GLONASS velocity errors when using the
`GLONASS_L1_CA_DLL_PLL_C_Aid_Tracking` and
`GLONASS_L2_CA_DLL_PLL_C_Aid_Tracking` implementations.
See the definitions of concepts and metrics at
https://gnss-sdr.org/design-forces/
&nbsp;
## [GNSS-SDR v0.0.17](https://github.com/gnss-sdr/gnss-sdr/releases/tag/v0.0.17) - 2022-04-20
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.6473244.svg)](https://doi.org/10.5281/zenodo.6473244)
### Improvements in Availability: ### Improvements in Availability:
- Compute PVT solutions when using GPS L5 signals even if the satellite is - Compute PVT solutions when using GPS L5 signals even if the satellite is
reported as not healthy in the CNAV message. 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.0.
### Improvements in Reliability: ### Improvements in Reliability:
- Fix some defects detected by Coverity Scan 2021.12.1. - Fix some defects detected by Coverity Scan 2021.12.1.
### Improvements in Usability:
- Added a script at `src/utils/scripts/download-galileo-almanac.sh` that
downloads an XML file with the latest Galileo almanac published by the
European GNSS Service Centre at https://www.gsc-europa.eu/product-almanacs
See the definitions of concepts and metrics at See the definitions of concepts and metrics at
https://gnss-sdr.org/design-forces/ https://gnss-sdr.org/design-forces/
@ -922,8 +960,7 @@ features and bug fixes:
- Improvements in the RTCM server stability. - Improvements in the RTCM server stability.
- Improvements in the correctness of generated RINEX files. - Improvements in the correctness of generated RINEX files.
- The receiver can read and make use of Galileo almanac XML files published by - The receiver can read and make use of Galileo almanac XML files published by
the European GNSS Service Centre at the European GNSS Service Centre at https://www.gsc-europa.eu/product-almanacs
https://www.gsc-europa.eu/system-status/almanac-data
- Own-defined XML schemas for navigation data published at - Own-defined XML schemas for navigation data published at
https://github.com/gnss-sdr/gnss-sdr/tree/next/docs/xml-schemas https://github.com/gnss-sdr/gnss-sdr/tree/next/docs/xml-schemas
- Added program `rinex2assist` to convert RINEX navigation files into XML files - Added program `rinex2assist` to convert RINEX navigation files into XML files

View File

@ -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 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: if you reference any of these articles to credit the GNSS-SDR project:
\li \anchor Navitec2012 C. Fern&aacute;ndez-Prades, J. Arribas, L. Esteve, D. Pubill, P. Closas, <a href="http://www.cttc.es/publication/an-open-source-galileo-e1-software-receiver/" target="_blank"><i>An Open Source Galileo E1 Software Receiver</i></a>, in Proc. of the 6th ESA Workshop on Satellite Navigation Technologies (NAVITEC 2012), ESTEC, Noordwijk, The Netherlands, Dec. 2012. \li \anchor Navitec2012 C. Fern&aacute;ndez-Prades, J. Arribas, L. Esteve, D. Pubill, P. Closas, <a href="https://www.researchgate.net/publication/233859838_An_Open_Source_Galileo_E1_Software_Receiver/" target="_blank"><i>An Open Source Galileo E1 Software Receiver</i></a>, in Proc. of the 6th ESA Workshop on Satellite Navigation Technologies (NAVITEC 2012), ESTEC, Noordwijk, The Netherlands, Dec. 2012.
\li J. Arribas, <a href="https://theses.eurasip.org/theses/449/gnss-array-based-acquisition-theory-and/" target="_blank"><i>GNSS Array-based Acquisition: Theory and Implementation</i></a>, PhD Thesis, Universitat Polit&egrave;cnica de Catalunya, Barcelona, Spain, June 2012. \li J. Arribas, <a href="https://theses.eurasip.org/theses/449/gnss-array-based-acquisition-theory-and/" target="_blank"><i>GNSS Array-based Acquisition: Theory and Implementation</i></a>, PhD Thesis, Universitat Polit&egrave;cnica de Catalunya, Barcelona, Spain, June 2012.
\li C. Fern&aacute;ndez-Prades, J. Arribas, P. Closas, C. Avil&eacute;s, and L. Esteve, <a href="http://www.cttc.es/publication/gnss-sdr-an-open-source-tool-for-researchers-and-developers/" target="_blank"><i>GNSS-SDR: an open source tool for researchers and developers</i></a>, in Proc. of the ION GNSS 2011 Conference, Portland, Oregon, Sept. 19-23, 2011. \li C. Fern&aacute;ndez-Prades, J. Arribas, P. Closas, C. Avil&eacute;s, and L. Esteve, <a href="https://www.researchgate.net/publication/233380791_GNSS-SDR_An_open_source_tool_for_researchers_and_developers" target="_blank"><i>GNSS-SDR: an open source tool for researchers and developers</i></a>, in Proc. of the ION GNSS 2011 Conference, Portland, Oregon, Sept. 19-23, 2011.
\li C. Fern&aacute;ndez-Prades, C. Avil&eacute;s, L. Esteve, J. Arribas, and P. Closas, <a href="http://www.cttc.es/publication/design-patterns-for-gnss-software-receivers/" target="_blank"><i>Design patterns for GNSS software receivers</i></a>, 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&aacute;ndez-Prades, C. Avil&eacute;s, L. Esteve, J. Arribas, and P. Closas, <a href="https://www.researchgate.net/publication/228624103_Design_Patterns_for_GNSS_Software_Receivers" target="_blank"><i>Design patterns for GNSS software receivers</i></a>, 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: For LaTeX users, these are the BibTeX cites for your convenience:

View File

@ -32,7 +32,7 @@ The crystal oscillator that ships with the RTL2832U family devices exhibits limi
\.TP \.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. 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 \.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 \.TP
Check https://gnss\-sdr.org for more information. Check https://gnss\-sdr.org for more information.
.SH BUGS .SH BUGS
@ -40,4 +40,4 @@ No known bugs.
.SH AUTHOR .SH AUTHOR
Javier Arribas (javier.arribas@cttc.es) Javier Arribas (javier.arribas@cttc.es)
\.TP \.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.

View File

@ -2,7 +2,7 @@
.\" SPDX-License-Identifier: GPL-3.0-or-later .\" SPDX-License-Identifier: GPL-3.0-or-later
.\" SPDX-FileCopyrightText: Carles Fernandez-Prades <carles.fernandez(at)cttc.es> .\" SPDX-FileCopyrightText: Carles Fernandez-Prades <carles.fernandez(at)cttc.es>
.\" Contact carles.fernandez@cttc.es to correct errors or typos. .\" Contact carles.fernandez@cttc.es to correct errors or typos.
.TH gnss\-sdr 1 "15 Feb 2022" "0.0.16" "gnss\-sdr man page" .TH gnss\-sdr 1 "20 Apr 2022" "0.0.17" "gnss\-sdr man page"
.SH NAME .SH NAME
\fBgnss\-sdr\fR \- GNSS Software Defined Receiver. \fBgnss\-sdr\fR \- GNSS Software Defined Receiver.
.SH SYNOPSIS .SH SYNOPSIS
@ -78,4 +78,4 @@ Please report bugs at https://github.com/gnss-sdr/gnss-sdr/issues
.SH AUTHOR .SH AUTHOR
Carles Fernandez\-Prades (carles.fernandez@cttc.es) Carles Fernandez\-Prades (carles.fernandez@cttc.es)
\.TP \.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.

View File

@ -32,8 +32,6 @@ namespace own = std;
namespace own = gsl; namespace own = gsl;
#endif #endif
using google::LogMessage;
BeidouB3iPcpsAcquisition::BeidouB3iPcpsAcquisition( BeidouB3iPcpsAcquisition::BeidouB3iPcpsAcquisition(
const ConfigurationInterface* configuration, const ConfigurationInterface* configuration,
const std::string& role, const std::string& role,

View File

@ -101,7 +101,7 @@ void Fpga_Acquisition::open_device()
LOG(WARNING) << "Cannot open deviceio" << d_device_name; LOG(WARNING) << "Cannot open deviceio" << d_device_name;
std::cout << "Acq: cannot open deviceio" << d_device_name << '\n'; std::cout << "Acq: cannot open deviceio" << d_device_name << '\n';
} }
d_map_base = reinterpret_cast<volatile uint32_t *>(mmap(nullptr, PAGE_SIZE_DEFAULT, d_map_base = reinterpret_cast<volatile uint32_t *>(mmap(nullptr, FPGA_PAGE_SIZE,
PROT_READ | PROT_WRITE, MAP_SHARED, d_fd, 0)); PROT_READ | PROT_WRITE, MAP_SHARED, d_fd, 0));
if (d_map_base == reinterpret_cast<void *>(-1)) if (d_map_base == reinterpret_cast<void *>(-1))
@ -227,7 +227,7 @@ void Fpga_Acquisition::read_acquisition_results(uint32_t *max_index,
void Fpga_Acquisition::close_device() void Fpga_Acquisition::close_device()
{ {
auto *aux = const_cast<uint32_t *>(d_map_base); auto *aux = const_cast<uint32_t *>(d_map_base);
if (munmap(static_cast<void *>(aux), PAGE_SIZE_DEFAULT) == -1) if (munmap(static_cast<void *>(aux), FPGA_PAGE_SIZE) == -1)
{ {
std::cout << "Failed to unmap memory uio\n"; std::cout << "Failed to unmap memory uio\n";
} }

View File

@ -142,7 +142,7 @@ public:
private: private:
// FPGA register parameters // FPGA register parameters
static const uint32_t PAGE_SIZE_DEFAULT = 0x10000; // default page size for the multicorrelator memory map static const uint32_t FPGA_PAGE_SIZE = 0x1000; // default page size for the multicorrelator memory map
static const uint32_t LAUNCH_ACQUISITION = 1; // command to launch the acquisition process static const uint32_t LAUNCH_ACQUISITION = 1; // command to launch the acquisition process
static const uint32_t RESET_ACQUISITION = 2; // command to reset the acquisition and the FPGA Modules static const uint32_t RESET_ACQUISITION = 2; // command to reset the acquisition and the FPGA Modules
static const uint32_t STOP_ACQUISITION = 4; // command to stop the acquisition and the FPGA modules static const uint32_t STOP_ACQUISITION = 4; // command to stop the acquisition and the FPGA modules

View File

@ -8,7 +8,7 @@
######################################################################## ########################################################################
# Project setup # 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) if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release") set(CMAKE_BUILD_TYPE "Release")
endif() endif()
@ -209,7 +209,7 @@ message(STATUS "Build type set to ${CMAKE_BUILD_TYPE}.")
set(VERSION_INFO_MAJOR_VERSION 0) set(VERSION_INFO_MAJOR_VERSION 0)
set(VERSION_INFO_MINOR_VERSION 0) set(VERSION_INFO_MINOR_VERSION 0)
set(VERSION_INFO_MAINT_VERSION 16) set(VERSION_INFO_MAINT_VERSION 17)
include(VolkGnsssdrVersion) # setup version info include(VolkGnsssdrVersion) # setup version info
@ -250,44 +250,43 @@ endif()
######################################################################## ########################################################################
# cpu_features # 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") if(CMAKE_SYSTEM_PROCESSOR MATCHES "^cortex")
set(CMAKE_SYSTEM_PROCESSOR arm-${CMAKE_SYSTEM_PROCESSOR}) set(CMAKE_SYSTEM_PROCESSOR arm-${CMAKE_SYSTEM_PROCESSOR})
endif() endif()
set(SUPPORTED_CPU_FEATURES_ARCH FALSE) # cpu_features - sensible defaults, user settable option
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips") if(CMAKE_SYSTEM_PROCESSOR MATCHES
set(SUPPORTED_CPU_FEATURES_ARCH TRUE) "(^mips)|(^arm)|(^aarch64)|(x86_64)|(AMD64|amd64)|(^i.86$)|(^powerpc)|(^ppc)")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(^aarch64)|(arm64)") option(VOLK_CPU_FEATURES "volk-gnsssdr uses cpu_features" ON)
set(SUPPORTED_CPU_FEATURES_ARCH TRUE) else()
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm") option(VOLK_CPU_FEATURES "volk-gnsssdr uses cpu_features" OFF)
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)
endif() endif()
if(CMAKE_VERSION VERSION_GREATER 3.0 AND SUPPORTED_CPU_FEATURES_ARCH) if(CMAKE_VERSION VERSION_GREATER 3.0 AND VOLK_CPU_FEATURES)
find_package(CPUFEATURES)
set(USE_CPU_FEATURES ON)
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 set(CMAKE_POSITION_INDEPENDENT_CODE ON CACHE BOOL
"Build cpu_features with Position Independent Code (PIC)." "Build cpu_features with Position Independent Code (PIC)."
FORCE FORCE
) )
set(USE_CPU_FEATURES ON)
set(BUILD_SHARED_LIBS_SAVED "${BUILD_SHARED_LIBS}") set(BUILD_SHARED_LIBS_SAVED "${BUILD_SHARED_LIBS}")
set(BUILD_SHARED_LIBS OFF) 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()
add_subdirectory(cpu_features) add_subdirectory(cpu_features)
endif()
set(BUILD_SHARED_LIBS "${BUILD_SHARED_LIBS_SAVED}") set(BUILD_SHARED_LIBS "${BUILD_SHARED_LIBS_SAVED}")
endif()
else()
message(STATUS "Building volk-gnsssdr without cpu_features")
endif() endif()
# Python # Python
include(VolkPython) # sets PYTHON_EXECUTABLE include(VolkPython) # sets PYTHON_EXECUTABLE
volk_python_check_module("python >= 2.7" sys "sys.version.split()[0] >= '2.7'" PYTHON_MIN_VER_FOUND) volk_python_check_module("python >= 2.7" sys "sys.version.split()[0] >= '2.7'" PYTHON_MIN_VER_FOUND)

View File

@ -203,4 +203,4 @@ by Carles Fern&aacute;ndez-Prades and Javier Arribas. This software is released
under the GNU General Public License version 3, see the file COPYING. under the GNU General Public License version 3, see the file COPYING.
This project is managed by This project is managed by
[Centre Tecnol&ograve;gic de Telecomunicacions de Catalunya](http://www.cttc.es "CTTC webpage"). [Centre Tecnol&ograve;gic de Telecomunicacions de Catalunya](https://www.cttc.cat "CTTC webpage").

View File

@ -86,7 +86,6 @@ if(CPUFEATURES_FOUND AND NOT TARGET CpuFeature::cpu_features)
INTERFACE_INCLUDE_DIRECTORIES "${CPUFEATURES_INCLUDE_DIR}" INTERFACE_INCLUDE_DIRECTORIES "${CPUFEATURES_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${CPUFEATURES_LIBRARIES}" INTERFACE_LINK_LIBRARIES "${CPUFEATURES_LIBRARIES}"
) )
add_library(cpu_features ALIAS CpuFeature::cpu_features)
endif() endif()
mark_as_advanced(CPUFEATURES_LIBRARIES) mark_as_advanced(CPUFEATURES_LIBRARIES)

View File

@ -2,7 +2,7 @@
.\" SPDX-License-Identifier: GPL-3.0-or-later .\" SPDX-License-Identifier: GPL-3.0-or-later
.\" SPDX-FileCopyrightText: Carles Fernandez-Prades <carles.fernandez(at)cttc.es> .\" SPDX-FileCopyrightText: Carles Fernandez-Prades <carles.fernandez(at)cttc.es>
.\" Contact carles.fernandez@cttc.es to correct errors or typos. .\" Contact carles.fernandez@cttc.es to correct errors or typos.
.TH volk_gnsssdr\-config\-info 1 "15 Feb 2022" "0.0.16" "volk_gnsssdr\-config\-info man page" .TH volk_gnsssdr\-config\-info 1 "20 Apr 2022" "0.0.17" "volk_gnsssdr\-config\-info man page"
.SH NAME .SH NAME
\fBvolk_gnsssdr\-config\-info\fR \- Prints configuration information of libvolk_gnsssdr functions. \fBvolk_gnsssdr\-config\-info\fR \- Prints configuration information of libvolk_gnsssdr functions.
.SH SYNOPSIS .SH SYNOPSIS

View File

@ -2,7 +2,7 @@
.\" SPDX-License-Identifier: GPL-3.0-or-later .\" SPDX-License-Identifier: GPL-3.0-or-later
.\" SPDX-FileCopyrightText: Carles Fernandez-Prades <carles.fernandez(at)cttc.es> .\" SPDX-FileCopyrightText: Carles Fernandez-Prades <carles.fernandez(at)cttc.es>
.\" Contact carles.fernandez@cttc.es to correct errors or typos. .\" Contact carles.fernandez@cttc.es to correct errors or typos.
.TH volk_gnsssdr_profile 1 "15 Feb 2022" "0.0.16" "volk_gnsssdr_profile man page" .TH volk_gnsssdr_profile 1 "20 Apr 2022" "0.0.17" "volk_gnsssdr_profile man page"
.SH NAME .SH NAME
\fBvolk_gnsssdr_profile\fR \- Profiler application for libvolk_gnsssdr functions. \fBvolk_gnsssdr_profile\fR \- Profiler application for libvolk_gnsssdr functions.
.SH SYNOPSIS .SH SYNOPSIS

View File

@ -9,7 +9,7 @@ if(POLICY CMP0077)
cmake_policy(SET CMP0077 NEW) cmake_policy(SET CMP0077 NEW)
endif() endif()
project(CpuFeatures VERSION 0.6.0 LANGUAGES C) project(CpuFeatures VERSION 0.7.0 LANGUAGES C)
set(CMAKE_C_STANDARD 99) set(CMAKE_C_STANDARD 99)
if(CMAKE_VERSION LESS "3.1") if(CMAKE_VERSION LESS "3.1")
@ -23,9 +23,6 @@ if(NOT CMAKE_BUILD_TYPE)
FORCE) FORCE)
endif() 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 # BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to make
# it prominent in the GUI. # 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). # 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") if(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips")
set(PROCESSOR_IS_MIPS TRUE) set(PROCESSOR_IS_MIPS TRUE)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(^aarch64)|(arm64)") elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64|arm64)")
set(PROCESSOR_IS_AARCH64 TRUE) set(PROCESSOR_IS_AARCH64 TRUE)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm") elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm")
set(PROCESSOR_IS_ARM TRUE) set(PROCESSOR_IS_ARM TRUE)
@ -74,22 +71,19 @@ endif()
macro(add_cpu_features_headers_and_sources HDRS_LIST_NAME SRCS_LIST_NAME) 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_macros.h)
list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpu_features_cache_info.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) if(PROCESSOR_IS_MIPS)
list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_mips.h) 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) elseif(PROCESSOR_IS_ARM)
list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_arm.h) 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) elseif(PROCESSOR_IS_AARCH64)
list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_aarch64.h) 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) elseif(PROCESSOR_IS_X86)
list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_x86.h) 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}/include/internal/cpuid_x86.h)
list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/src/cpuinfo_x86.c)
elseif(PROCESSOR_IS_POWER) elseif(PROCESSOR_IS_POWER)
list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_ppc.h) 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() else()
message(FATAL_ERROR "Unsupported architectures ${CMAKE_SYSTEM_PROCESSOR}") message(FATAL_ERROR "Unsupported architectures ${CMAKE_SYSTEM_PROCESSOR}")
endif() endif()
@ -147,8 +141,10 @@ target_link_libraries(cpu_features PUBLIC ${CMAKE_DL_LIBS})
target_include_directories(cpu_features target_include_directories(cpu_features
PUBLIC $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/cpu_features> PUBLIC $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/cpu_features>
) )
if(APPLE AND (PROCESSOR_IS_X86 OR PROCESSOR_IS_AARCH64)) if(PROCESSOR_IS_X86)
if(APPLE)
target_compile_definitions(cpu_features PRIVATE HAVE_SYSCTLBYNAME) target_compile_definitions(cpu_features PRIVATE HAVE_SYSCTLBYNAME)
endif()
endif() endif()
add_library(CpuFeature::cpu_features ALIAS cpu_features) add_library(CpuFeature::cpu_features ALIAS cpu_features)

View File

@ -1,4 +1,4 @@
# CMake build instructions #CMake build instructions
<!-- prettier-ignore-start --> <!-- prettier-ignore-start -->
[comment]: # ( [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. cpu_features in a subdirectory of your project or as an embedded dependency.
This is similar to the recommended usage of the googletest framework ( 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 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 3- Add the `cpu_features` target to the `target_link_libraries()` section of
your executable or of your library. your executable or of your library.
## Enabling tests ## Disabling tests
CMake default options for cpu_features is Release built type with tests CMake default options for cpu_features is `Release` built type with tests
disabled. To enable testing set cmake `BUILD_TESTING` variable to `ON`, enabled. To disable testing set cmake `BUILD_TESTING` variable to `OFF`. e.g.
[.travis.yml](https://github.com/google/cpu_features/blob/master/.travis.yml)
and ```sh
[appveyor.yml](https://github.com/google/cpu_features/blob/master/appveyor.yml) cmake -S. -Bbuild -DBUILD_TESTING=OFF
have up to date examples. ```

View File

@ -8,7 +8,7 @@ project(googletest-download NONE)
include(ExternalProject) include(ExternalProject)
ExternalProject_Add(googletest ExternalProject_Add(googletest
GIT_REPOSITORY https://github.com/google/googletest.git GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG master GIT_TAG main
SOURCE_DIR "${CMAKE_BINARY_DIR}/googletest-src" SOURCE_DIR "${CMAKE_BINARY_DIR}/googletest-src"
BINARY_DIR "${CMAKE_BINARY_DIR}/googletest-build" BINARY_DIR "${CMAKE_BINARY_DIR}/googletest-build"
CONFIGURE_COMMAND "" CONFIGURE_COMMAND ""

View File

@ -1,7 +1,6 @@
// SPDX-FileCopyrightText: 2017 Google LLC // SPDX-FileCopyrightText: 2017 Google LLC
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
#ifndef CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_ #ifndef CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_
#define CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_ #define CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_
@ -29,7 +28,7 @@
#define CPU_FEATURES_ARCH_ARM #define CPU_FEATURES_ARCH_ARM
#endif #endif
#if (defined(__aarch64__) || (defined(__APPLE__) && defined(__arm64__))) #if defined(__aarch64__)
#define CPU_FEATURES_ARCH_AARCH64 #define CPU_FEATURES_ARCH_AARCH64
#endif #endif
@ -57,24 +56,33 @@
// Os // Os
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#if defined(__linux__) #if (defined(__freebsd__) || defined(__FreeBSD__))
#define CPU_FEATURES_OS_LINUX_OR_ANDROID #define CPU_FEATURES_OS_FREEBSD
#endif #endif
#if defined(__ANDROID__) #if defined(__ANDROID__)
#define CPU_FEATURES_OS_ANDROID #define CPU_FEATURES_OS_ANDROID
#endif #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)) #if (defined(_WIN64) || defined(_WIN32))
#define CPU_FEATURES_OS_WINDOWS #define CPU_FEATURES_OS_WINDOWS
#endif #endif
#if (defined(__apple__) || defined(__APPLE__) || defined(__MACH__)) #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 #endif
#if (defined(__freebsd__) || defined(__FreeBSD__))
#define CPU_FEATURES_OS_FREEBSD
#endif #endif
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -215,11 +223,18 @@
// Communicates to the compiler that the block is unreachable // Communicates to the compiler that the block is unreachable
#if defined(CPU_FEATURES_COMPILER_CLANG) || defined(CPU_FEATURES_COMPILER_GCC) #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) #elif defined(CPU_FEATURES_COMPILER_MSC)
#define UNREACHABLE() __assume(0) #define CPU_FEATURES_UNREACHABLE() __assume(0)
#else #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
#endif // CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_ #endif // CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_

View File

@ -1,7 +1,6 @@
// SPDX-FileCopyrightText: 2017 Google LLC // SPDX-FileCopyrightText: 2017 Google LLC
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
#ifndef CPU_FEATURES_INCLUDE_CPUINFO_AARCH64_H_ #ifndef CPU_FEATURES_INCLUDE_CPUINFO_AARCH64_H_
#define CPU_FEATURES_INCLUDE_CPUINFO_AARCH64_H_ #define CPU_FEATURES_INCLUDE_CPUINFO_AARCH64_H_

View File

@ -1,7 +1,6 @@
// SPDX-FileCopyrightText: 2017 Google LLC // SPDX-FileCopyrightText: 2017 Google LLC
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
#ifndef CPU_FEATURES_INCLUDE_CPUINFO_ARM_H_ #ifndef CPU_FEATURES_INCLUDE_CPUINFO_ARM_H_
#define CPU_FEATURES_INCLUDE_CPUINFO_ARM_H_ #define CPU_FEATURES_INCLUDE_CPUINFO_ARM_H_

View File

@ -1,7 +1,6 @@
// SPDX-FileCopyrightText: 2017 Google LLC // SPDX-FileCopyrightText: 2017 Google LLC
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
#ifndef CPU_FEATURES_INCLUDE_CPUINFO_MIPS_H_ #ifndef CPU_FEATURES_INCLUDE_CPUINFO_MIPS_H_
#define CPU_FEATURES_INCLUDE_CPUINFO_MIPS_H_ #define CPU_FEATURES_INCLUDE_CPUINFO_MIPS_H_

View File

@ -1,7 +1,6 @@
// SPDX-FileCopyrightText: 2017 Google LLC // SPDX-FileCopyrightText: 2017 Google LLC
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
#ifndef CPU_FEATURES_INCLUDE_CPUINFO_PPC_H_ #ifndef CPU_FEATURES_INCLUDE_CPUINFO_PPC_H_
#define CPU_FEATURES_INCLUDE_CPUINFO_PPC_H_ #define CPU_FEATURES_INCLUDE_CPUINFO_PPC_H_
@ -62,7 +61,6 @@ typedef struct
PPCFeatures features; PPCFeatures features;
} PPCInfo; } PPCInfo;
// This function is guaranteed to be malloc, memset and memcpy free.
PPCInfo GetPPCInfo(void); PPCInfo GetPPCInfo(void);
typedef struct typedef struct

View File

@ -1,7 +1,6 @@
// SPDX-FileCopyrightText: 2017 Google LLC // SPDX-FileCopyrightText: 2017 Google LLC
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
#ifndef CPU_FEATURES_INCLUDE_CPUINFO_X86_H_ #ifndef CPU_FEATURES_INCLUDE_CPUINFO_X86_H_
#define 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_GENUINE_INTEL "GenuineIntel"
#define CPU_FEATURES_VENDOR_AUTHENTIC_AMD "AuthenticAMD" #define CPU_FEATURES_VENDOR_AUTHENTIC_AMD "AuthenticAMD"
#define CPU_FEATURES_VENDOR_HYGON_GENUINE "HygonGenuine" #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. // 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. // The field names are based on the short name provided in the wikipedia tables.
@ -95,21 +96,27 @@ typedef struct
int model; int model;
int stepping; int stepping;
char vendor[13]; // 0 terminated string char vendor[13]; // 0 terminated string
char brand_string[49]; // 0 terminated string
} X86Info; } X86Info;
// Calls cpuid and returns an initialized X86info. // Calls cpuid and returns an initialized X86info.
// This function is guaranteed to be malloc, memset and memcpy free.
X86Info GetX86Info(void); X86Info GetX86Info(void);
// Returns cache hierarchy informations. // Returns cache hierarchy informations.
// Can call cpuid multiple times. // Can call cpuid multiple times.
// Only works on Intel CPU at the moment. // Only works on Intel CPU at the moment.
// This function is guaranteed to be malloc, memset and memcpy free.
CacheInfo GetX86CacheInfo(void); CacheInfo GetX86CacheInfo(void);
typedef enum typedef enum
{ {
X86_UNKNOWN, X86_UNKNOWN,
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_CORE, // CORE
INTEL_PNR, // PENRYN INTEL_PNR, // PENRYN
INTEL_NHM, // NEHALEM INTEL_NHM, // NEHALEM
@ -129,6 +136,13 @@ typedef enum
INTEL_ICL, // ICE LAKE INTEL_ICL, // ICE LAKE
INTEL_TGL, // TIGER LAKE INTEL_TGL, // TIGER LAKE
INTEL_SPR, // SAPPHIRE RAPIDS 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_HAMMER, // K8 HAMMER
AMD_K10, // K10 AMD_K10, // K10
AMD_K11, // K11 AMD_K11, // K11
@ -144,6 +158,7 @@ typedef enum
AMD_ZEN_PLUS, // K17 ZEN+ AMD_ZEN_PLUS, // K17 ZEN+
AMD_ZEN2, // K17 ZEN 2 AMD_ZEN2, // K17 ZEN 2
AMD_ZEN3, // K19 ZEN 3 AMD_ZEN3, // K19 ZEN 3
X86_MICROARCHITECTURE_LAST_,
} X86Microarchitecture; } X86Microarchitecture;
// Returns the underlying microarchitecture by looking at X86Info's vendor, // 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. // Calls cpuid and fills the brand_string.
// - brand_string *must* be of size 49 (beware of array decaying). // - brand_string *must* be of size 49 (beware of array decaying).
// - brand_string will be zero terminated. // - 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]); 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." #error "Including cpuinfo_x86.h from a non-x86 target."
#endif #endif
#endif // CPU_FEATURES_INCLUDE_CPUINFO_X86_H #endif // CPU_FEATURES_INCLUDE_CPUINFO_X86_H_

View File

@ -1,7 +1,6 @@
// SPDX-FileCopyrightText: 2017 Google LLC // SPDX-FileCopyrightText: 2017 Google LLC
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
#ifndef CPU_FEATURES_INCLUDE_INTERNAL_BIT_UTILS_H_ #ifndef CPU_FEATURES_INCLUDE_INTERNAL_BIT_UTILS_H_
#define CPU_FEATURES_INCLUDE_INTERNAL_BIT_UTILS_H_ #define CPU_FEATURES_INCLUDE_INTERNAL_BIT_UTILS_H_

View File

@ -1,7 +1,6 @@
// SPDX-FileCopyrightText: 2017 Google LLC // SPDX-FileCopyrightText: 2017 Google LLC
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
#ifndef CPU_FEATURES_INCLUDE_INTERNAL_CPUID_X86_H_ #ifndef CPU_FEATURES_INCLUDE_INTERNAL_CPUID_X86_H_
#define CPU_FEATURES_INCLUDE_INTERNAL_CPUID_X86_H_ #define CPU_FEATURES_INCLUDE_INTERNAL_CPUID_X86_H_

View File

@ -1,7 +1,6 @@
// SPDX-FileCopyrightText: 2017 Google LLC // SPDX-FileCopyrightText: 2017 Google LLC
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
// An interface for the filesystem that allows mocking the filesystem in // An interface for the filesystem that allows mocking the filesystem in
// unittests. // unittests.
#ifndef CPU_FEATURES_INCLUDE_INTERNAL_FILESYSTEM_H_ #ifndef CPU_FEATURES_INCLUDE_INTERNAL_FILESYSTEM_H_

View File

@ -1,7 +1,6 @@
// SPDX-FileCopyrightText: 2017 Google LLC // SPDX-FileCopyrightText: 2017 Google LLC
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
// Interface to retrieve hardware capabilities. It relies on Linux's getauxval // Interface to retrieve hardware capabilities. It relies on Linux's getauxval
// or `/proc/self/auxval` under the hood. // or `/proc/self/auxval` under the hood.
#ifndef CPU_FEATURES_INCLUDE_INTERNAL_HWCAPS_H_ #ifndef CPU_FEATURES_INCLUDE_INTERNAL_HWCAPS_H_

View File

@ -1,7 +1,6 @@
// SPDX-FileCopyrightText: 2017 Google LLC // SPDX-FileCopyrightText: 2017 Google LLC
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
// Reads a file line by line and stores the data on the stack. This allows // Reads a file line by line and stores the data on the stack. This allows
// parsing files in one go without allocating. // parsing files in one go without allocating.
#ifndef CPU_FEATURES_INCLUDE_INTERNAL_STACK_LINE_READER_H_ #ifndef CPU_FEATURES_INCLUDE_INTERNAL_STACK_LINE_READER_H_

View File

@ -1,7 +1,6 @@
// SPDX-FileCopyrightText: 2017 Google LLC // SPDX-FileCopyrightText: 2017 Google LLC
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
// A view over a piece of string. The view is not 0 terminated. // A view over a piece of string. The view is not 0 terminated.
#ifndef CPU_FEATURES_INCLUDE_INTERNAL_STRING_VIEW_H_ #ifndef CPU_FEATURES_INCLUDE_INTERNAL_STRING_VIEW_H_
#define CPU_FEATURES_INCLUDE_INTERNAL_STRING_VIEW_H_ #define CPU_FEATURES_INCLUDE_INTERNAL_STRING_VIEW_H_

View File

@ -3,210 +3,365 @@
# SPDX-FileCopyrightText: 2017 Google LLC # SPDX-FileCopyrightText: 2017 Google LLC
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
readonly SCRIPT_FOLDER=$(cd -P -- "$(dirname -- "$0")" && pwd -P) set -eo pipefail
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"
function extract() { function extract() {
echo "Extracting ${1}..."
case $1 in case $1 in
*.tar.bz2) tar xjf "$1" ;; *.tar.bz2) tar xjf "$1" ;;
*.tar.xz) tar xJf "$1" ;; *.tar.xz) tar xJf "$1" ;;
*.tar.gz) tar xzf "$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 exit 1
esac esac
} }
function unpackifnotexists() { function unpack() {
mkdir -p "${ARCHIVE_FOLDER}" mkdir -p "${ARCHIVE_DIR}"
cd "${ARCHIVE_FOLDER}" || exit cd "${ARCHIVE_DIR}" || exit 2
local URL=$1 local -r URL=$1
local RELATIVE_FOLDER=$2 local -r RELATIVE_DIR=$2
local DESTINATION="${ARCHIVE_FOLDER}/${RELATIVE_FOLDER}" local -r DESTINATION="${ARCHIVE_DIR}/${RELATIVE_DIR}"
if [[ ! -d "${DESTINATION}" ]] ; then if [[ ! -d "${DESTINATION}" ]] ; then
local ARCHIVE_NAME=$(echo ${URL} | sed 's/.*\///') echo "Downloading ${URL}..."
test -f "${ARCHIVE_NAME}" || wget -q "${URL}" local -r ARCHIVE_NAME=$(basename "${URL}")
test -f "${ARCHIVE_NAME}" || wget --no-verbose "${URL}"
extract "${ARCHIVE_NAME}" extract "${ARCHIVE_NAME}"
rm -f "${ARCHIVE_NAME}" rm -f "${ARCHIVE_NAME}"
fi fi
} }
function installqemuifneeded() { function install_qemu() {
local VERSION=${QEMU_VERSION:=2.11.1} if [[ "${QEMU_ARCH}" == "DISABLED" ]]; then
local ARCHES=${QEMU_ARCHES:=arm aarch64 i386 x86_64 mips mipsel mips64 mips64el} >&2 echo 'QEMU is disabled !'
local TARGETS=${QEMU_TARGETS:=$(echo "$ARCHES" | sed 's#$# #;s#\([^ ]*\) #\1-linux-user #g')} 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 if echo "${QEMU_VERSION} ${QEMU_TARGET}" | cmp --silent "${QEMU_INSTALL}/.build" -; then
echo "qemu ${VERSION} up to date!" echo "qemu ${QEMU_VERSION} up to date!"
return 0 return 0
fi fi
echo "VERSION: ${VERSION}" echo "QEMU_VERSION: ${QEMU_VERSION}"
echo "TARGETS: ${TARGETS}" echo "QEMU_TARGET: ${QEMU_TARGET}"
rm -rf ${QEMU_INSTALL} rm -rf "${QEMU_INSTALL}"
# Checking for a tarball before downloading makes testing easier :-) # Checking for a tarball before downloading makes testing easier :-)
local QEMU_URL="http://wiki.qemu-project.org/download/qemu-${VERSION}.tar.xz" local -r QEMU_URL="http://wiki.qemu-project.org/download/qemu-${QEMU_VERSION}.tar.xz"
local QEMU_FOLDER="qemu-${VERSION}" local -r QEMU_DIR="qemu-${QEMU_VERSION}"
unpackifnotexists ${QEMU_URL} ${QEMU_FOLDER} unpack ${QEMU_URL} ${QEMU_DIR}
cd ${QEMU_FOLDER} || exit cd ${QEMU_DIR} || exit 2
# Qemu (meson based build) depends on: pkgconf, libglib2.0, python3, ninja
./configure \ ./configure \
--prefix="${QEMU_INSTALL}" \ --prefix="${QEMU_INSTALL}" \
--target-list="${TARGETS}" \ --target-list="${QEMU_TARGET}" \
--disable-docs \ --audio-drv-list= \
--disable-sdl \ --disable-brlapi \
--disable-gtk \ --disable-curl \
--disable-gnutls \
--disable-gcrypt \
--disable-nettle \
--disable-curses \ --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 make install
echo "$VERSION $TARGETS" > ${QEMU_INSTALL}/.build echo "$QEMU_VERSION $QEMU_TARGET" > "${QEMU_INSTALL}/.build"
} }
function assert_defined(){ function assert_defined(){
local VALUE=${1} if [[ -z "${!1}" ]]; then
: "${VALUE?"${1} needs to be defined"}" >&2 echo "Variable '${1}' must be defined"
exit 1
fi
} }
function integrate() { function clean_build() {
cd "${PROJECT_FOLDER}" # Cleanup previous build
case "${OS}" in rm -rf "${BUILD_DIR}"
"Windows_NT") CMAKE_BUILD_ARGS="--config Debug --target ALL_BUILD" mkdir -p "${BUILD_DIR}"
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 expand_linaro_config() { function expand_linaro_config() {
assert_defined TARGET #ref: https://releases.linaro.org/components/toolchain/binaries/
local LINARO_ROOT_URL=https://releases.linaro.org/components/toolchain/binaries/7.2-2017.11 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 -r GCC_VERSION=7.5.0-2019.12
local GCC_RELATIVE_FOLDER="gcc-linaro-7.2.1-2017.11-x86_64_${TARGET}" local -r GCC_URL=${LINARO_ROOT_URL}/${TARGET}/gcc-linaro-${GCC_VERSION}-x86_64_${TARGET}.tar.xz
unpackifnotexists "${GCC_URL}" "${GCC_RELATIVE_FOLDER}" 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 -r SYSROOT_VERSION=2.25-2019.12
local SYSROOT_RELATIVE_FOLDER=sysroot-glibc-linaro-2.25-2017.11-${TARGET} local -r SYSROOT_URL=${LINARO_ROOT_URL}/${TARGET}/sysroot-glibc-linaro-${SYSROOT_VERSION}-${TARGET}.tar.xz
unpackifnotexists "${SYSROOT_URL}" "${SYSROOT_RELATIVE_FOLDER}" 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 -r SYSROOT_DIR=${ARCHIVE_DIR}/${SYSROOT_RELATIVE_DIR}
local GCC_FOLDER=${ARCHIVE_FOLDER}/${GCC_RELATIVE_FOLDER} 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) # Write a Toolchain file
CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_SYSTEM_PROCESSOR=${TARGET}) # 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" <<EOL
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR ${TARGET})
CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_SYSROOT=${SYSROOT_FOLDER}) set(CMAKE_SYSROOT ${SYSROOT_DIR})
CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_C_COMPILER=${GCC_FOLDER}/bin/${TARGET}-gcc) set(CMAKE_STAGING_PREFIX ${STAGING_DIR})
CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_CXX_COMPILER=${GCC_FOLDER}/bin/${TARGET}-g++)
CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER) set(tools ${GCC_DIR})
CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY) set(CMAKE_C_COMPILER \${tools}/bin/${TARGET}-gcc)
CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ONLY) set(CMAKE_CXX_COMPILER \${tools}/bin/${TARGET}-g++)
QEMU_ARGS+=(-L ${SYSROOT_FOLDER}) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
QEMU_ARGS+=(-E LD_LIBRARY_PATH=/lib) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
EOL
CMAKE_ADDITIONAL_ARGS+=( -DCMAKE_TOOLCHAIN_FILE="${TOOLCHAIN_FILE}" )
QEMU_ARGS+=( -L "${SYSROOT_DIR}" )
QEMU_ARGS+=( -E LD_LIBRARY_PATH=/lib )
} }
function expand_codescape_config() { function expand_codescape_config() {
assert_defined TARGET # ref: https://codescape.mips.com/components/toolchain/2020.06-01/downloads.html
local DATE=2017.10-08 # ref: https://codescape.mips.com/components/toolchain/2019.02-04/downloads.html
local CODESCAPE_URL=https://codescape.mips.com/components/toolchain/${DATE}/Codescape.GNU.Tools.Package.${DATE}.for.MIPS.MTI.Linux.CentOS-5.x86_64.tar.gz local -r DATE=2020.06-01
local GCC_URL=${CODESCAPE_URL} #local -r DATE=2019.02-04
local GCC_RELATIVE_FOLDER="mips-mti-linux-gnu/${DATE}" local -r CODESCAPE_URL=https://codescape.mips.com/components/toolchain/${DATE}/Codescape.GNU.Tools.Package.${DATE}.for.MIPS.MTI.Linux.CentOS-6.x86_64.tar.gz
unpackifnotexists "${GCC_URL}" "${GCC_RELATIVE_FOLDER}" #local -r CODESCAPE_URL=https://codescape.mips.com/components/toolchain/${DATE}/Codescape.GNU.Tools.Package.${DATE}.for.MIPS.IMG.Linux.CentOS-6.x86_64.tar.gz
local -r GCC_URL=${CODESCAPE_URL}
local -r GCC_RELATIVE_DIR="mips-mti-linux-gnu/${DATE}"
#local -r GCC_RELATIVE_DIR="mips-img-linux-gnu/${DATE}"
unpack "${GCC_URL}" "${GCC_RELATIVE_DIR}"
local GCC_FOLDER=${ARCHIVE_FOLDER}/${GCC_RELATIVE_FOLDER} local -r GCC_DIR=${ARCHIVE_DIR}/${GCC_RELATIVE_DIR}
local MIPS_FLAGS="" local MIPS_FLAGS=""
local LIBC_FOLDER_SUFFIX="" local LIBC_DIR_SUFFIX=""
local FLAVOUR="" local FLAVOUR=""
case "${TARGET}" in case "${TARGET}" in
"mips32") MIPS_FLAGS="-EB -mabi=32"; FLAVOUR="mips-r2-hard"; LIBC_FOLDER_SUFFIX="lib" ;; "mips32")
"mips32el") MIPS_FLAGS="-EL -mabi=32"; FLAVOUR="mipsel-r2-hard"; LIBC_FOLDER_SUFFIX="lib" ;; MIPS_FLAGS="-EB -mips32r6 -mabi=32"
"mips64") MIPS_FLAGS="-EB -mabi=64"; FLAVOUR="mips-r2-hard"; LIBC_FOLDER_SUFFIX="lib64" ;; FLAVOUR="mips-r6-hard"
"mips64el") MIPS_FLAGS="-EL -mabi=64"; FLAVOUR="mipsel-r2-hard"; LIBC_FOLDER_SUFFIX="lib64" ;; #MIPS_FLAGS="-EB -mips32r2 -mabi=32"
*) echo 'unknown mips platform'; exit 1;; #FLAVOUR="mips-r2-hard"
LIBC_DIR_SUFFIX="lib"
;;
"mips32el")
MIPS_FLAGS="-EL -mips32r6 -mabi=32"
FLAVOUR="mipsel-r6-hard"
#MIPS_FLAGS="-EL -mips32r2 -mabi=32"
#FLAVOUR="mipsel-r2-hard"
LIBC_DIR_SUFFIX="lib"
;;
"mips64")
MIPS_FLAGS="-EB -mips64r6 -mabi=64"
FLAVOUR="mips-r6-hard"
#FLAVOUR="mips-r2-hard"
LIBC_DIR_SUFFIX="lib64"
;;
"mips64el")
MIPS_FLAGS="-EL -mips64r6 -mabi=64"
FLAVOUR="mipsel-r6-hard"
#FLAVOUR="mipsel-r2-hard"
LIBC_DIR_SUFFIX="lib64"
;;
*)
>&2 echo 'unknown mips platform'
exit 1 ;;
esac esac
local -r SYSROOT_DIR=${GCC_DIR}/sysroot
local -r STAGING_DIR=${SYSROOT_DIR}-stage
CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_FIND_ROOT_PATH=${GCC_FOLDER}) # Write a Toolchain file
CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_SYSTEM_NAME=Linux) # note: This is manadatory to use a file in order to have the CMake variable
CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_SYSTEM_PROCESSOR=${TARGET}) # 'CMAKE_CROSSCOMPILING' set to TRUE.
CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_C_COMPILER=mips-mti-linux-gnu-gcc) # ref: https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html#cross-compiling-for-linux
CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_CXX_COMPILER=mips-mti-linux-gnu-g++) cat >"${TOOLCHAIN_FILE}" <<EOL
CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_C_COMPILER_ARG1="${MIPS_FLAGS}") set(CMAKE_SYSTEM_NAME Linux)
CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_CXX_COMPILER_ARG1="${MIPS_FLAGS}") set(CMAKE_SYSTEM_PROCESSOR ${TARGET})
local SYSROOT_FOLDER=${GCC_FOLDER}/sysroot/${FLAVOUR} set(CMAKE_SYSROOT ${SYSROOT_DIR})
set(CMAKE_STAGING_PREFIX ${STAGING_DIR})
# Keeping only the sysroot of interest to save on travis cache. set(tools ${GCC_DIR})
if [[ "${CONTINUOUS_INTEGRATION}" = "true" ]]; then
for folder in ${GCC_FOLDER}/sysroot/*; do
if [[ "${folder}" != "${SYSROOT_FOLDER}" ]]; then
rm -rf ${folder}
fi
done
fi
local LIBC_FOLDER=${GCC_FOLDER}/mips-mti-linux-gnu/lib/${FLAVOUR}/${LIBC_FOLDER_SUFFIX} set(CMAKE_C_COMPILER \${tools}/bin/mips-mti-linux-gnu-gcc)
QEMU_ARGS+=(-L ${SYSROOT_FOLDER}) #set(CMAKE_C_COMPILER \${tools}/bin/mips-img-linux-gnu-gcc)
QEMU_ARGS+=(-E LD_PRELOAD=${LIBC_FOLDER}/libstdc++.so.6:${LIBC_FOLDER}/libgcc_s.so.1) set(CMAKE_C_FLAGS "${MIPS_FLAGS}")
set(CMAKE_CXX_COMPILER \${tools}/bin/mips-mti-linux-gnu-g++)
#set(CMAKE_CXX_COMPILER \${tools}/bin/mips-img-linux-gnu-g++)
set(CMAKE_CXX_FLAGS "${MIPS_FLAGS}")
set(CMAKE_FIND_ROOT_PATH ${GCC_DIR})
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
EOL
CMAKE_ADDITIONAL_ARGS+=( -DCMAKE_TOOLCHAIN_FILE="${TOOLCHAIN_FILE}" )
QEMU_ARGS+=( -L "${SYSROOT_DIR}/${FLAVOUR}" )
local -r LIBC_DIR=${GCC_DIR}/mips-mti-linux-gnu/lib/${FLAVOUR}/${LIBC_DIR_SUFFIX}
#local -r LIBC_DIR=${GCC_DIR}/mips-img-linux-gnu/lib/${FLAVOUR}/${LIBC_DIR_SUFFIX}
QEMU_ARGS+=( -E LD_PRELOAD="${LIBC_DIR}/libstdc++.so.6:${LIBC_DIR}/libgcc_s.so.1" )
} }
function expand_environment_and_integrate() { function build() {
assert_defined PROJECT_FOLDER cd "${PROJECT_DIR}" || exit 2
set -x
clean_build
cmake -S. -B"${BUILD_DIR}" "${CMAKE_DEFAULT_ARGS[@]}" "${CMAKE_ADDITIONAL_ARGS[@]}"
cmake --build "${BUILD_DIR}" --target all -j8 -v
set +x
}
function run_test() {
assert_defined QEMU_ARCH
if [[ "${QEMU_ARCH}" == "DISABLED" ]]; then
>&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 assert_defined TARGET
BUILD_DIR="${PROJECT_FOLDER}/cmake_build/${TARGET}" declare -r PROJECT_DIR="$(cd -P -- "$(dirname -- "$0")/.." && pwd -P)"
mkdir -p "${BUILD_DIR}" 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=() echo "Target: '${TARGET}'"
declare -a QEMU_ARGS=()
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=() declare -a CMAKE_ADDITIONAL_ARGS=()
case ${TOOLCHAIN} in declare -a QEMU_ARGS=()
LINARO) expand_linaro_config ;; case ${TARGET} in
CODESCAPE) expand_codescape_config ;; x86_64)
NATIVE) QEMU_ARCH="" ;; declare -r QEMU_ARCH=x86_64 ;;
*) echo "Unknown toolchain '${TOOLCHAIN}'..."; exit 1;; 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 esac
integrate
} }
if [ "${CONTINUOUS_INTEGRATION}" = "true" ]; then main "${1:-all}"
QEMU_ARCHES=${QEMU_ARCH}
expand_environment_and_integrate
fi

View File

@ -3,85 +3,59 @@
# SPDX-FileCopyrightText: 2017 Google LLC # SPDX-FileCopyrightText: 2017 Google LLC
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
source "$(dirname -- "$0")"/run_integration.sh
# Toolchains for little-endian, 64-bit ARMv8 for GNU/Linux systems # Toolchains for little-endian, 64-bit ARMv8 for GNU/Linux systems
function set_aarch64-linux-gnu() { function set_aarch64-linux-gnu() {
TOOLCHAIN=LINARO export TARGET=aarch64-linux-gnu
TARGET=aarch64-linux-gnu
QEMU_ARCH=aarch64
} }
# Toolchains for little-endian, hard-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems # Toolchains for little-endian, hard-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems
function set_arm-linux-gnueabihf() { function set_arm-linux-gnueabihf() {
TOOLCHAIN=LINARO export TARGET=arm-linux-gnueabihf
TARGET=arm-linux-gnueabihf
QEMU_ARCH=arm
} }
# Toolchains for little-endian, 32-bit ARMv8 for GNU/Linux systems # Toolchains for little-endian, 32-bit ARMv8 for GNU/Linux systems
function set_armv8l-linux-gnueabihf() { function set_armv8l-linux-gnueabihf() {
TOOLCHAIN=LINARO export TARGET=armv8l-linux-gnueabihf
TARGET=armv8l-linux-gnueabihf
QEMU_ARCH=arm
} }
# Toolchains for little-endian, soft-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems # Toolchains for little-endian, soft-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems
function set_arm-linux-gnueabi() { function set_arm-linux-gnueabi() {
TOOLCHAIN=LINARO export TARGET=arm-linux-gnueabi
TARGET=arm-linux-gnueabi
QEMU_ARCH=arm
} }
# Toolchains for big-endian, 64-bit ARMv8 for GNU/Linux systems # Toolchains for big-endian, 64-bit ARMv8 for GNU/Linux systems
function set_aarch64_be-linux-gnu() { function set_aarch64_be-linux-gnu() {
TOOLCHAIN=LINARO export TARGET=aarch64_be-linux-gnu
TARGET=aarch64_be-linux-gnu
QEMU_ARCH=DISABLED
} }
# Toolchains for big-endian, hard-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems # Toolchains for big-endian, hard-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems
function set_armeb-linux-gnueabihf() { function set_armeb-linux-gnueabihf() {
TOOLCHAIN=LINARO export TARGET=armeb-linux-gnueabihf
TARGET=armeb-linux-gnueabihf
QEMU_ARCH=DISABLED
} }
# Toolchains for big-endian, soft-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems # Toolchains for big-endian, soft-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems
function set_armeb-linux-gnueabi() { function set_armeb-linux-gnueabi() {
TOOLCHAIN=LINARO export TARGET=armeb-linux-gnueabi
TARGET=armeb-linux-gnueabi
QEMU_ARCH=DISABLED
} }
function set_mips32() { function set_mips32() {
TOOLCHAIN=CODESCAPE export TARGET=mips32
TARGET=mips32
QEMU_ARCH=mips
} }
function set_mips32el() { function set_mips32el() {
TOOLCHAIN=CODESCAPE export TARGET=mips32el
TARGET=mips32el
QEMU_ARCH=mipsel
} }
function set_mips64() { function set_mips64() {
TOOLCHAIN=CODESCAPE export TARGET=mips64
TARGET=mips64
QEMU_ARCH=mips64
} }
function set_mips64el() { function set_mips64el() {
TOOLCHAIN=CODESCAPE export TARGET=mips64el
TARGET=mips64el
QEMU_ARCH=mips64el
} }
function set_native() { function set_x86_64() {
TOOLCHAIN=NATIVE export TARGET=x86_64
TARGET=native
QEMU_ARCH=""
} }
ENVIRONMENTS=" ENVIRONMENTS="
@ -96,14 +70,13 @@ ENVIRONMENTS="
set_mips32el set_mips32el
set_mips64 set_mips64
set_mips64el set_mips64el
set_native set_x86_64
" "
set -e set -e
CMAKE_GENERATOR="Ninja"
for SET_ENVIRONMENT in ${ENVIRONMENTS}; do for SET_ENVIRONMENT in ${ENVIRONMENTS}; do
echo "testing ${SET_ENVIRONMENT}"
${SET_ENVIRONMENT} ${SET_ENVIRONMENT}
expand_environment_and_integrate ./"$(dirname -- "$0")"/run_integration.sh
done done

View File

@ -0,0 +1,9 @@
// SPDX-FileCopyrightText: 2021 Google LLC
// SPDX-License-Identifier: Apache-2.0
#include <stddef.h>
static void copy(char *__restrict dst, const char *src, size_t count)
{
for (size_t i = 0; i < count; ++i) dst[i] = src[i];
}

View File

@ -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 <assert.h>
#include <ctype.h>
#if defined(CPU_FEATURES_OS_DARWIN)
#if !defined(HAVE_SYSCTLBYNAME)
#error "Darwin needs support for sysctlbyname"
#endif
#include <sys/sysctl.h>
#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];
}

View File

@ -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 <assert.h>
#include <stdbool.h>
#include <string.h>
// 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];
}

View File

@ -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 <stdbool.h>
#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];
}

View File

@ -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

View File

@ -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_

View File

@ -0,0 +1,12 @@
// SPDX-FileCopyrightText: 2021 Google LLC
// SPDX-License-Identifier: Apache-2.0
#include <stdbool.h>
#include <stddef.h>
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;
}

View File

@ -60,13 +60,7 @@ static unsigned long GetElfHwcapFromGetauxval(uint32_t hwcap_type)
#elif defined(HAVE_DLFCN_H) #elif defined(HAVE_DLFCN_H)
// On Android we probe the system's C library for a 'getauxval' function and // 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 // call it if it exits, or return 0 for failure. This function is available
// since API level 20. // since API level 18.
//
// 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.
// //
// Note that getauxval() can't really be re-implemented here, because its // Note that getauxval() can't really be re-implemented here, because its
// implementation does not parse /proc/self/auxv. Instead it depends on values // implementation does not parse /proc/self/auxv. Instead it depends on values

View File

@ -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 <stdbool.h>
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

View File

@ -1,47 +1,58 @@
// SPDX-FileCopyrightText: 2017 Google LLC // SPDX-FileCopyrightText: 2017 Google LLC
// SPDX-License-Identifier: Apache-2.0 // 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" #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/bit_utils.h"
#include "internal/filesystem.h" #include "internal/filesystem.h"
#include "internal/hwcaps.h"
#include "internal/stack_line_reader.h" #include "internal/stack_line_reader.h"
#include "internal/string_view.h" #include "internal/string_view.h"
#include <assert.h>
#include <ctype.h> #include <ctype.h>
#include <stdbool.h>
// 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"
typedef struct typedef struct
{ {
@ -155,13 +166,15 @@ static void FixErrors(ArmInfo* const info,
// https://crbug.com/341598. // https://crbug.com/341598.
info->features.neon = false; info->features.neon = false;
break; break;
case 0x510006F2: }
case 0x510006F3:
// The Nexus 4 (Qualcomm Krait) kernel configuration forgets to report // Some Qualcomm Krait kernels forget to report IDIV support.
// 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.idiva = true;
info->features.idivt = true; info->features.idivt = true;
break;
} }
// Propagate cpu features. // Propagate cpu features.
@ -217,18 +230,5 @@ ArmInfo GetArmInfo(void)
return info; return info;
} }
//////////////////////////////////////////////////////////////////////////////// #endif // defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID)
// Introspection functions #endif // CPU_FEATURES_ARCH_ARM
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];
}

View File

@ -1,21 +1,32 @@
// SPDX-FileCopyrightText: 2017 Google LLC // SPDX-FileCopyrightText: 2017 Google LLC
// SPDX-License-Identifier: Apache-2.0 // 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" #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/filesystem.h"
#include "internal/hwcaps.h" #include "internal/hwcaps.h"
#include "internal/stack_line_reader.h" #include "internal/stack_line_reader.h"
#include "internal/string_view.h" #include "internal/string_view.h"
#include <assert.h>
// 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, static bool HandleMipsLine(const LineResult result,
MipsFeatures* const features) MipsFeatures* const features)
@ -75,18 +86,5 @@ MipsInfo GetMipsInfo(void)
return info; return info;
} }
//////////////////////////////////////////////////////////////////////////////// #endif // defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID)
// Introspection functions #endif // CPU_FEATURES_ARCH_MIPS
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];
}

View File

@ -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 <stdbool.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;
}
#endif // CPU_FEATURES_OS_LINUX
#endif // CPU_FEATURES_ARCH_PPC

View File

@ -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<PSE36,MMX,FXSR,SSE,SSE2,HTT>"
// 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

View File

@ -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

View File

@ -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 <sys/sysctl.h>
#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

View File

@ -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 <windows.h> // 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

View File

@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2017 Google LLC // SPDX-FileCopyrightText: 2021 Google LLC
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
// This program dumps current host data to the standard output. // 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: case CPU_FEATURE_CACHE_PREFETCH:
return CreateConstantString("prefetch"); return CreateConstantString("prefetch");
} }
UNREACHABLE(); CPU_FEATURES_UNREACHABLE();
} }
static void AddCacheInfo(Node* root, const CacheInfo* cache_info) static void AddCacheInfo(Node* root, const CacheInfo* cache_info)

View File

@ -50,7 +50,13 @@ add_test(NAME stack_line_reader_test COMMAND stack_line_reader_test)
##------------------------------------------------------------------------------ ##------------------------------------------------------------------------------
## cpuinfo_x86_test ## cpuinfo_x86_test
if(PROCESSOR_IS_X86) 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) target_compile_definitions(cpuinfo_x86_test PUBLIC CPU_FEATURES_MOCK_CPUID_X86)
if(APPLE) if(APPLE)
target_compile_definitions(cpuinfo_x86_test PRIVATE HAVE_SYSCTLBYNAME) target_compile_definitions(cpuinfo_x86_test PRIVATE HAVE_SYSCTLBYNAME)
@ -61,32 +67,28 @@ endif()
##------------------------------------------------------------------------------ ##------------------------------------------------------------------------------
## cpuinfo_arm_test ## cpuinfo_arm_test
if(PROCESSOR_IS_ARM) 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) target_link_libraries(cpuinfo_arm_test all_libraries)
add_test(NAME cpuinfo_arm_test COMMAND cpuinfo_arm_test) add_test(NAME cpuinfo_arm_test COMMAND cpuinfo_arm_test)
endif() endif()
##------------------------------------------------------------------------------ ##------------------------------------------------------------------------------
## cpuinfo_aarch64_test ## cpuinfo_aarch64_test
if(PROCESSOR_IS_AARCH64) if(PROCESSOR_IS_AARCH64)
add_executable(cpuinfo_aarch64_test cpuinfo_aarch64_test.cc ../src/cpuinfo_aarch64.c) add_executable(cpuinfo_aarch64_test cpuinfo_aarch64_test.cc ../src/impl_aarch64_linux_or_android.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()
target_link_libraries(cpuinfo_aarch64_test all_libraries) target_link_libraries(cpuinfo_aarch64_test all_libraries)
add_test(NAME cpuinfo_aarch64_test COMMAND cpuinfo_aarch64_test) add_test(NAME cpuinfo_aarch64_test COMMAND cpuinfo_aarch64_test)
endif() endif()
##------------------------------------------------------------------------------ ##------------------------------------------------------------------------------
## cpuinfo_mips_test ## cpuinfo_mips_test
if(PROCESSOR_IS_MIPS) 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) target_link_libraries(cpuinfo_mips_test all_libraries)
add_test(NAME cpuinfo_mips_test COMMAND cpuinfo_mips_test) add_test(NAME cpuinfo_mips_test COMMAND cpuinfo_mips_test)
endif() endif()
##------------------------------------------------------------------------------ ##------------------------------------------------------------------------------
## cpuinfo_ppc_test ## cpuinfo_ppc_test
if(PROCESSOR_IS_POWER) 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) target_link_libraries(cpuinfo_ppc_test all_libraries)
add_test(NAME cpuinfo_ppc_test COMMAND cpuinfo_ppc_test) add_test(NAME cpuinfo_ppc_test COMMAND cpuinfo_ppc_test)
endif() endif()

View File

@ -103,7 +103,6 @@ CPU architecture: 7
CPU variant : 0x0 CPU variant : 0x0
CPU part : 0xb76 CPU part : 0xb76
CPU revision : 7 CPU revision : 7
Hardware : BCM2835 Hardware : BCM2835
Revision : 9000c1 Revision : 9000c1
Serial : 000000006cd946f3)"); Serial : 000000006cd946f3)");
@ -156,7 +155,6 @@ CPU architecture: 7
CPU variant : 0x4 CPU variant : 0x4
CPU part : 0xc09 CPU part : 0xc09
CPU revision : 1 CPU revision : 1
processor : 1 processor : 1
model name : ARMv7 Processor rev 1 (v7l) model name : ARMv7 Processor rev 1 (v7l)
BogoMIPS : 50.00 BogoMIPS : 50.00
@ -166,7 +164,6 @@ CPU architecture: 7
CPU variant : 0x4 CPU variant : 0x4
CPU part : 0xc09 CPU part : 0xc09
CPU revision : 1 CPU revision : 1
Hardware : Marvell Armada 380/385 (Device Tree) Hardware : Marvell Armada 380/385 (Device Tree)
Revision : 0000 Revision : 0000
Serial : 0000000000000000)"); Serial : 0000000000000000)");
@ -221,7 +218,6 @@ CPU architecture: 7
CPU variant : 0x0 CPU variant : 0x0
CPU part : 0xb76 CPU part : 0xb76
CPU revision : 6 CPU revision : 6
Hardware : SPICA Hardware : SPICA
Revision : 0020 Revision : 0020
Serial : 33323613546d00ec )"); Serial : 33323613546d00ec )");
@ -267,17 +263,14 @@ TEST(CpuinfoArmTest, InvalidNeon)
R"(Processor: ARMv7 Processory rev 0 (v71) R"(Processor: ARMv7 Processory rev 0 (v71)
processor: 0 processor: 0
BogoMIPS: 13.50 BogoMIPS: 13.50
Processor: 1 Processor: 1
BogoMIPS: 13.50 BogoMIPS: 13.50
Features: swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt Features: swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt
CPU implementer : 0x51 CPU implementer : 0x51
CPU architecture: 7 CPU architecture: 7
CPU variant: 0x1 CPU variant: 0x1
CPU part: 0x04d CPU part: 0x04d
CPU revision: 0 CPU revision: 0
Hardware: SAMSUNG M2 Hardware: SAMSUNG M2
Revision: 0010 Revision: 0010
Serial: 00001e030000354e)"); Serial: 00001e030000354e)");
@ -324,6 +317,25 @@ CPU revision : 3)");
EXPECT_EQ(GetArmCpuId(&info), 0x510006f3); 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 // 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 // 32-bit ARM IDIV instruction. Technically, this is a feature of the virtual
// CPU implemented by the emulator. // CPU implemented by the emulator.
@ -340,7 +352,6 @@ CPU architecture: 7
CPU variant : 0x0 CPU variant : 0x0
CPU part : 0xc08 CPU part : 0xc08
CPU revision : 0 CPU revision : 0
Hardware : Goldfish Hardware : Goldfish
Revision : 0000 Revision : 0000
Serial : 0000000000000000)"); Serial : 0000000000000000)");

View File

@ -16,6 +16,7 @@
namespace cpu_features namespace cpu_features
{ {
class FakeCpu class FakeCpu
{ {
public: public:
@ -41,7 +42,7 @@ public:
xcr0_eax_ = os_backups_extended_registers ? -1 : 0; 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 bool GetDarwinSysCtlByName(std::string name) const
{ {
return darwin_sysctlbyname_.count(name); return darwin_sysctlbyname_.count(name);
@ -51,7 +52,7 @@ public:
{ {
darwin_sysctlbyname_.insert(name); darwin_sysctlbyname_.insert(name);
} }
#endif // CPU_FEATURES_OS_DARWIN #endif // CPU_FEATURES_OS_MACOS
#if defined(CPU_FEATURES_OS_WINDOWS) #if defined(CPU_FEATURES_OS_WINDOWS)
bool GetWindowsIsProcessorFeaturePresent(DWORD ProcessorFeature) bool GetWindowsIsProcessorFeaturePresent(DWORD ProcessorFeature)
@ -67,9 +68,9 @@ public:
private: private:
std::map<std::pair<uint32_t, int>, Leaf> cpuid_leaves_; std::map<std::pair<uint32_t, int>, Leaf> cpuid_leaves_;
#if defined(CPU_FEATURES_OS_DARWIN) #if defined(CPU_FEATURES_OS_MACOS)
std::set<std::string> darwin_sysctlbyname_; std::set<std::string> darwin_sysctlbyname_;
#endif // CPU_FEATURES_OS_DARWIN #endif // CPU_FEATURES_OS_MACOS
#if defined(CPU_FEATURES_OS_WINDOWS) #if defined(CPU_FEATURES_OS_WINDOWS)
std::set<DWORD> windows_isprocessorfeaturepresent_; std::set<DWORD> windows_isprocessorfeaturepresent_;
#endif // CPU_FEATURES_OS_WINDOWS #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(); } 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) extern "C" bool GetDarwinSysCtlByName(const char* name)
{ {
return cpu().GetDarwinSysCtlByName(name); return cpu().GetDarwinSysCtlByName(name);
} }
#endif // CPU_FEATURES_OS_DARWIN #endif // CPU_FEATURES_OS_MACOS
#if defined(CPU_FEATURES_OS_WINDOWS) #if defined(CPU_FEATURES_OS_WINDOWS)
extern "C" bool GetWindowsIsProcessorFeaturePresent(DWORD ProcessorFeature) extern "C" bool GetWindowsIsProcessorFeaturePresent(DWORD ProcessorFeature)
@ -107,6 +108,7 @@ extern "C" bool GetWindowsIsProcessorFeaturePresent(DWORD ProcessorFeature)
namespace namespace
{ {
class CpuidX86Test : public ::testing::Test class CpuidX86Test : public ::testing::Test
{ {
protected: protected:
@ -430,6 +432,8 @@ TEST_F(CpuidX86Test, AMD_K15_EXCAVATOR_STONEY_RIDGE)
EXPECT_STREQ(info.vendor, "AuthenticAMD"); EXPECT_STREQ(info.vendor, "AuthenticAMD");
EXPECT_EQ(info.family, 0x15); EXPECT_EQ(info.family, 0x15);
EXPECT_EQ(info.model, 0x70); EXPECT_EQ(info.model, 0x70);
EXPECT_STREQ(info.brand_string,
"AMD A9-9410 RADEON R5, 5 COMPUTE CORES 2C+3G ");
EXPECT_EQ(GetX86Microarchitecture(&info), EXPECT_EQ(GetX86Microarchitecture(&info),
X86Microarchitecture::AMD_EXCAVATOR); X86Microarchitecture::AMD_EXCAVATOR);
@ -456,6 +460,8 @@ TEST_F(CpuidX86Test, AMD_K15_PILEDRIVER_ABU_DHABI)
EXPECT_STREQ(info.vendor, "AuthenticAMD"); EXPECT_STREQ(info.vendor, "AuthenticAMD");
EXPECT_EQ(info.family, 0x15); EXPECT_EQ(info.family, 0x15);
EXPECT_EQ(info.model, 0x02); EXPECT_EQ(info.model, 0x02);
EXPECT_STREQ(info.brand_string,
"AMD Opteron(tm) Processor 6376 ");
EXPECT_EQ(GetX86Microarchitecture(&info), EXPECT_EQ(GetX86Microarchitecture(&info),
X86Microarchitecture::AMD_PILEDRIVER); X86Microarchitecture::AMD_PILEDRIVER);
@ -531,6 +537,8 @@ TEST_F(CpuidX86Test, AMD_K15_BULLDOZER_INTERLAGOS)
EXPECT_STREQ(info.vendor, "AuthenticAMD"); EXPECT_STREQ(info.vendor, "AuthenticAMD");
EXPECT_EQ(info.family, 0x15); EXPECT_EQ(info.family, 0x15);
EXPECT_EQ(info.model, 0x01); EXPECT_EQ(info.model, 0x01);
EXPECT_STREQ(info.brand_string,
"AMD Opteron(TM) Processor 6238 ");
EXPECT_EQ(GetX86Microarchitecture(&info), EXPECT_EQ(GetX86Microarchitecture(&info),
X86Microarchitecture::AMD_BULLDOZER); X86Microarchitecture::AMD_BULLDOZER);
@ -559,6 +567,8 @@ TEST_F(CpuidX86Test, AMD_K15_STREAMROLLER_GODAVARI)
EXPECT_EQ(info.family, 0x15); EXPECT_EQ(info.family, 0x15);
EXPECT_EQ(info.model, 0x38); EXPECT_EQ(info.model, 0x38);
EXPECT_EQ(info.stepping, 0x01); EXPECT_EQ(info.stepping, 0x01);
EXPECT_STREQ(info.brand_string,
"AMD A8-7670K Radeon R7, 10 Compute Cores 4C+6G ");
EXPECT_EQ(GetX86Microarchitecture(&info), EXPECT_EQ(GetX86Microarchitecture(&info),
X86Microarchitecture::AMD_STREAMROLLER); X86Microarchitecture::AMD_STREAMROLLER);
@ -585,6 +595,8 @@ TEST_F(CpuidX86Test, AMD_K16_JAGUAR_KABINI)
EXPECT_STREQ(info.vendor, "AuthenticAMD"); EXPECT_STREQ(info.vendor, "AuthenticAMD");
EXPECT_EQ(info.family, 0x16); EXPECT_EQ(info.family, 0x16);
EXPECT_EQ(info.model, 0x00); 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); EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_JAGUAR);
char brand_string[49]; char brand_string[49];
@ -610,6 +622,8 @@ TEST_F(CpuidX86Test, AMD_K16_PUMA_BEEMA)
EXPECT_STREQ(info.vendor, "AuthenticAMD"); EXPECT_STREQ(info.vendor, "AuthenticAMD");
EXPECT_EQ(info.family, 0x16); EXPECT_EQ(info.family, 0x16);
EXPECT_EQ(info.model, 0x30); 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); EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_PUMA);
char brand_string[49]; char brand_string[49];
@ -635,6 +649,8 @@ TEST_F(CpuidX86Test, AMD_K17_ZEN_DALI)
EXPECT_STREQ(info.vendor, "AuthenticAMD"); EXPECT_STREQ(info.vendor, "AuthenticAMD");
EXPECT_EQ(info.family, 0x17); EXPECT_EQ(info.family, 0x17);
EXPECT_EQ(info.model, 0x20); EXPECT_EQ(info.model, 0x20);
EXPECT_STREQ(info.brand_string,
"AMD 3020e with Radeon Graphics ");
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN); EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN);
char brand_string[49]; char brand_string[49];
@ -660,6 +676,8 @@ TEST_F(CpuidX86Test, AMD_K17_ZEN_PLUS_PINNACLE_RIDGE)
EXPECT_STREQ(info.vendor, "AuthenticAMD"); EXPECT_STREQ(info.vendor, "AuthenticAMD");
EXPECT_EQ(info.family, 0x17); EXPECT_EQ(info.family, 0x17);
EXPECT_EQ(info.model, 0x08); 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); EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN_PLUS);
char brand_string[49]; char brand_string[49];
@ -685,6 +703,7 @@ TEST_F(CpuidX86Test, AMD_K17_ZEN2_XBOX_SERIES_X)
EXPECT_STREQ(info.vendor, "AuthenticAMD"); EXPECT_STREQ(info.vendor, "AuthenticAMD");
EXPECT_EQ(info.family, 0x17); EXPECT_EQ(info.family, 0x17);
EXPECT_EQ(info.model, 0x47); EXPECT_EQ(info.model, 0x47);
EXPECT_STREQ(info.brand_string, "AMD 4700S 8-Core Processor Desktop Kit");
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN2); EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN2);
char brand_string[49]; char brand_string[49];
@ -710,6 +729,8 @@ TEST_F(CpuidX86Test, AMD_K18_ZEN_DHYANA)
EXPECT_STREQ(info.vendor, "HygonGenuine"); EXPECT_STREQ(info.vendor, "HygonGenuine");
EXPECT_EQ(info.family, 0x18); EXPECT_EQ(info.family, 0x18);
EXPECT_EQ(info.model, 0x00); EXPECT_EQ(info.model, 0x00);
EXPECT_STREQ(info.brand_string,
"Hygon C86 3185 8-core Processor ");
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN); EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN);
char brand_string[49]; char brand_string[49];
@ -784,6 +805,8 @@ TEST_F(CpuidX86Test, AMD_K19_ZEN3_VERMEER)
EXPECT_STREQ(info.vendor, "AuthenticAMD"); EXPECT_STREQ(info.vendor, "AuthenticAMD");
EXPECT_EQ(info.family, 0x19); EXPECT_EQ(info.family, 0x19);
EXPECT_EQ(info.model, 0x21); EXPECT_EQ(info.model, 0x21);
EXPECT_STREQ(info.brand_string,
"AMD Ryzen 9 5900X 12-Core Processor ");
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN3); EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN3);
char brand_string[49]; char brand_string[49];
@ -800,7 +823,7 @@ TEST_F(CpuidX86Test, Nehalem)
cpu().SetWindowsIsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE); cpu().SetWindowsIsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE);
cpu().SetWindowsIsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE); cpu().SetWindowsIsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE);
cpu().SetWindowsIsProcessorFeaturePresent(PF_SSE3_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.sse");
cpu().SetDarwinSysCtlByName("hw.optional.sse2"); cpu().SetDarwinSysCtlByName("hw.optional.sse2");
cpu().SetDarwinSysCtlByName("hw.optional.sse3"); cpu().SetDarwinSysCtlByName("hw.optional.sse3");
@ -817,10 +840,10 @@ FreeBSD is a registered trademark of The FreeBSD Foundation.
Features2=0x5eda2203<SSE3,PCLMULQDQ,SSSE3,CX16,PCID,SSE4.1,SSE4.2,MOVBE,POPCNT,AESNI,XSAVE,OSXSAVE,RDRAND> Features2=0x5eda2203<SSE3,PCLMULQDQ,SSSE3,CX16,PCID,SSE4.1,SSE4.2,MOVBE,POPCNT,AESNI,XSAVE,OSXSAVE,RDRAND>
real memory = 2147418112 (2047 MB) 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(); auto& fs = GetEmptyFilesystem();
fs.CreateFile("/proc/cpuinfo", R"(processor : 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 #endif
cpu().SetLeaves({ 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.family, 0x06);
EXPECT_EQ(info.model, 0x1A); EXPECT_EQ(info.model, 0x1A);
EXPECT_EQ(info.stepping, 0x02); EXPECT_EQ(info.stepping, 0x02);
EXPECT_STREQ(info.brand_string,
"Genuine Intel(R) CPU @ 0000 @ 1.87GHz");
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_NHM); EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_NHM);
char brand_string[49]; char brand_string[49];
@ -883,7 +908,7 @@ TEST_F(CpuidX86Test, Atom)
cpu().SetWindowsIsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE); cpu().SetWindowsIsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE);
cpu().SetWindowsIsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE); cpu().SetWindowsIsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE);
cpu().SetWindowsIsProcessorFeaturePresent(PF_SSE3_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.sse");
cpu().SetDarwinSysCtlByName("hw.optional.sse2"); cpu().SetDarwinSysCtlByName("hw.optional.sse2");
cpu().SetDarwinSysCtlByName("hw.optional.sse3"); cpu().SetDarwinSysCtlByName("hw.optional.sse3");
@ -900,10 +925,10 @@ FreeBSD is a registered trademark of The FreeBSD Foundation.
Features2=0x5eda2203<SSE3,PCLMULQDQ,SSSE3,CX16,PCID,SSE4.1,SSE4.2,MOVBE,POPCNT,AESNI,XSAVE,OSXSAVE,RDRAND> Features2=0x5eda2203<SSE3,PCLMULQDQ,SSSE3,CX16,PCID,SSE4.1,SSE4.2,MOVBE,POPCNT,AESNI,XSAVE,OSXSAVE,RDRAND>
real memory = 2147418112 (2047 MB) 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(); auto& fs = GetEmptyFilesystem();
fs.CreateFile("/proc/cpuinfo", R"( 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 #endif
cpu().SetLeaves({ 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.family, 0x06);
EXPECT_EQ(info.model, 0x37); EXPECT_EQ(info.model, 0x37);
EXPECT_EQ(info.stepping, 0x03); EXPECT_EQ(info.stepping, 0x03);
EXPECT_STREQ(info.brand_string,
" Intel(R) Celeron(R) CPU J1900 @ 1.99GHz");
EXPECT_EQ(GetX86Microarchitecture(&info), EXPECT_EQ(GetX86Microarchitecture(&info),
X86Microarchitecture::INTEL_ATOM_SMT); X86Microarchitecture::INTEL_ATOM_SMT);
@ -1017,7 +1044,7 @@ TEST_F(CpuidX86Test, P3)
cpu().SetOsBackupsExtendedRegisters(false); cpu().SetOsBackupsExtendedRegisters(false);
#if defined(CPU_FEATURES_OS_WINDOWS) #if defined(CPU_FEATURES_OS_WINDOWS)
cpu().SetWindowsIsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE); cpu().SetWindowsIsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE);
#elif defined(CPU_FEATURES_OS_DARWIN) #elif defined(CPU_FEATURES_OS_MACOS)
cpu().SetDarwinSysCtlByName("hw.optional.sse"); cpu().SetDarwinSysCtlByName("hw.optional.sse");
#elif defined(CPU_FEATURES_OS_FREEBSD) #elif defined(CPU_FEATURES_OS_FREEBSD)
auto& fs = GetEmptyFilesystem(); auto& fs = GetEmptyFilesystem();
@ -1028,7 +1055,7 @@ FreeBSD is a registered trademark of The FreeBSD Foundation.
Features=0x1783fbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,MMX,FXSR,SSE> Features=0x1783fbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,MMX,FXSR,SSE>
real memory = 2147418112 (2047 MB) 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(); auto& fs = GetEmptyFilesystem();
fs.CreateFile("/proc/cpuinfo", R"( fs.CreateFile("/proc/cpuinfo", R"(
flags : fpu mmx sse flags : fpu mmx sse
@ -1046,6 +1073,7 @@ flags : fpu mmx sse
EXPECT_EQ(info.family, 0x06); EXPECT_EQ(info.family, 0x06);
EXPECT_EQ(info.model, 0x07); EXPECT_EQ(info.model, 0x07);
EXPECT_EQ(info.stepping, 0x03); EXPECT_EQ(info.stepping, 0x03);
EXPECT_STREQ(info.brand_string, "");
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::X86_UNKNOWN); EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::X86_UNKNOWN);
char brand_string[49]; char brand_string[49];
@ -1065,6 +1093,95 @@ flags : fpu mmx sse
#endif // !defined(CPU_FEATURES_OS_WINDOWS) #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 xsave/osxsave are not present.
// TODO(user): test what happens when xmm/ymm/zmm os support are not // TODO(user): test what happens when xmm/ymm/zmm os support are not
// present. // present.

View File

@ -532,10 +532,11 @@ if(NOT (CMAKE_GENERATOR STREQUAL Xcode))
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
) )
if(USE_CPU_FEATURES) 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 target_include_directories(volk_gnsssdr_obj
PRIVATE PRIVATE
$<TARGET_PROPERTY:CpuFeatures::cpu_features,INTERFACE_INCLUDE_DIRECTORIES> $<TARGET_PROPERTY:CpuFeature::cpu_features,INTERFACE_INCLUDE_DIRECTORIES>
) )
else() else()
target_include_directories(volk_gnsssdr_obj target_include_directories(volk_gnsssdr_obj
@ -548,6 +549,10 @@ if(NOT (CMAKE_GENERATOR STREQUAL Xcode))
if(NOT MSVC) if(NOT MSVC)
set_target_properties(volk_gnsssdr_obj PROPERTIES COMPILE_FLAGS "-fPIC") set_target_properties(volk_gnsssdr_obj PROPERTIES COMPILE_FLAGS "-fPIC")
endif() endif()
else()
if(USE_CPU_FEATURES)
set_source_files_properties(volk_gnsssdr_cpu.c PROPERTIES COMPILE_DEFINITIONS "VOLK_CPU_FEATURES=1")
endif()
endif() endif()
# Add dynamic library # Add dynamic library
@ -557,10 +562,10 @@ else()
add_library(volk_gnsssdr SHARED $<TARGET_OBJECTS:volk_gnsssdr_obj>) add_library(volk_gnsssdr SHARED $<TARGET_OBJECTS:volk_gnsssdr_obj>)
endif() endif()
if(USE_CPU_FEATURES) if(USE_CPU_FEATURES)
if(CpuFeatures_FOUND) if(CPUFEATURES_FOUND)
target_link_libraries(volk_gnsssdr target_link_libraries(volk_gnsssdr
PUBLIC ${volk_gnsssdr_libraries} PUBLIC ${volk_gnsssdr_libraries}
PRIVATE CpuFeatures::cpu_features PRIVATE CpuFeature::cpu_features
) )
else() else()
target_link_libraries(volk_gnsssdr target_link_libraries(volk_gnsssdr
@ -580,10 +585,10 @@ target_include_directories(volk_gnsssdr
PUBLIC $<INSTALL_INTERFACE:include> PUBLIC $<INSTALL_INTERFACE:include>
) )
if(USE_CPU_FEATURES) if(USE_CPU_FEATURES)
if(CpuFeatures_FOUND) if(CPUFEATURES_FOUND)
target_include_directories(volk_gnsssdr target_include_directories(volk_gnsssdr
PRIVATE PRIVATE
$<TARGET_PROPERTY:CpuFeatures::cpu_features,INTERFACE_INCLUDE_DIRECTORIES> $<TARGET_PROPERTY:CpuFeature::cpu_features,INTERFACE_INCLUDE_DIRECTORIES>
) )
else() else()
target_include_directories(volk_gnsssdr target_include_directories(volk_gnsssdr
@ -620,9 +625,9 @@ if(ENABLE_STATIC_LIBS)
endif() endif()
target_link_libraries(volk_gnsssdr_static PUBLIC ${volk_gnsssdr_libraries}) target_link_libraries(volk_gnsssdr_static PUBLIC ${volk_gnsssdr_libraries})
if(USE_CPU_FEATURES) if(USE_CPU_FEATURES)
if(CpuFeatures_FOUND) if(CPUFEATURES_FOUND)
target_link_libraries(volk_gnsssdr_static target_link_libraries(volk_gnsssdr_static
PRIVATE CpuFeatures::cpu_features PRIVATE CpuFeature::cpu_features
) )
else() else()
target_link_libraries(volk_gnsssdr_static target_link_libraries(volk_gnsssdr_static

View File

@ -14,6 +14,7 @@
#include <string.h> #include <string.h>
// clang-format on // clang-format on
#if defined(VOLK_CPU_FEATURES)
#include "cpu_features_macros.h" #include "cpu_features_macros.h"
#if defined(CPU_FEATURES_ARCH_X86) #if defined(CPU_FEATURES_ARCH_X86)
#include "cpuinfo_x86.h" #include "cpuinfo_x86.h"
@ -31,6 +32,7 @@
#if defined(__cplusplus) #if defined(__cplusplus)
using namespace cpu_features; using namespace cpu_features;
#endif #endif
#endif
struct VOLK_CPU volk_gnsssdr_cpu; struct VOLK_CPU volk_gnsssdr_cpu;

View File

@ -56,6 +56,7 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con
gain_mode_rx2_(configuration->property(role + ".gain_mode_rx2", default_gain_mode)), gain_mode_rx2_(configuration->property(role + ".gain_mode_rx2", default_gain_mode)),
rf_port_select_(configuration->property(role + ".rf_port_select", default_rf_port_select)), rf_port_select_(configuration->property(role + ".rf_port_select", default_rf_port_select)),
filter_filename_(configuration->property(role + ".filter_filename", filter_file_)), filter_filename_(configuration->property(role + ".filter_filename", filter_file_)),
filename0_(configuration->property(role + ".filename", empty_string)),
rf_gain_rx1_(configuration->property(role + ".gain_rx1", default_manual_gain_rx1)), rf_gain_rx1_(configuration->property(role + ".gain_rx1", default_manual_gain_rx1)),
rf_gain_rx2_(configuration->property(role + ".gain_rx1", default_manual_gain_rx2)), rf_gain_rx2_(configuration->property(role + ".gain_rx1", default_manual_gain_rx2)),
freq_(configuration->property(role + ".freq", static_cast<uint64_t>(GPS_L1_FREQ_HZ))), freq_(configuration->property(role + ".freq", static_cast<uint64_t>(GPS_L1_FREQ_HZ))),
@ -109,18 +110,23 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con
// override value with commandline flag, if present // override value with commandline flag, if present
if (FLAGS_signal_source != "-") if (FLAGS_signal_source != "-")
{ {
filename0 = FLAGS_signal_source; filename0_ = FLAGS_signal_source;
} }
if (FLAGS_s != "-") if (FLAGS_s != "-")
{ {
filename0 = FLAGS_s; filename0_ = FLAGS_s;
} }
if (filename0_.empty())
{
filename0_ = configuration->property(role + ".filename0", empty_string);
filename1_ = configuration->property(role + ".filename1", empty_string);
}
// if only one input file is specified in the configuration file then: // if only one input file is specified in the configuration file then:
// if there is at least one channel assigned to frequency band 1 then the DMA transfers the samples to the L1 frequency band channels // if there is at least one channel assigned to frequency band 1 then the DMA transfers the samples to the L1 frequency band channels
// otherwise the DMA transfers the samples to the L2/L5 frequency band channels // otherwise the DMA transfers the samples to the L2/L5 frequency band channels
// if more than one input file are specified then the DMA transfer the samples to both the L1 and the L2/L5 frequency channels. // if more than one input file are specified then the DMA transfer the samples to both the L1 and the L2/L5 frequency channels.
if (filename1.empty()) if (filename1_.empty())
{ {
num_freq_bands_ = 1; num_freq_bands_ = 1;
if (l1_band != 0) if (l1_band != 0)
@ -172,7 +178,7 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con
* A possible solution is to compute the file length in samples using file size, excluding the last 100 milliseconds, and enable always the * A possible solution is to compute the file length in samples using file size, excluding the last 100 milliseconds, and enable always the
* valve block * valve block
*/ */
std::ifstream file(filename0.c_str(), std::ios::in | std::ios::binary | std::ios::ate); std::ifstream file(filename0_.c_str(), std::ios::in | std::ios::binary | std::ios::ate);
std::ifstream::pos_type size; std::ifstream::pos_type size;
if (file.is_open()) if (file.is_open())
@ -182,13 +188,13 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con
} }
else else
{ {
std::cerr << "SignalSource: Unable to open the samples file " << filename0.c_str() << '\n'; std::cerr << "SignalSource: Unable to open the samples file " << filename0_.c_str() << '\n';
item_size_ = 0; item_size_ = 0;
return; return;
} }
std::streamsize ss = std::cout.precision(); std::streamsize ss = std::cout.precision();
std::cout << std::setprecision(16); std::cout << std::setprecision(16);
std::cout << "Processing file " << filename0 << ", which contains " << static_cast<double>(size) << " [bytes]\n"; std::cout << "Processing file " << filename0_ << ", which contains " << static_cast<double>(size) << " [bytes]\n";
std::cout.precision(ss); std::cout.precision(ss);
if (size > 0) if (size > 0)
@ -198,9 +204,9 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con
samples_ = floor(static_cast<double>(bytes_to_process) / static_cast<double>(item_size_) - ceil(0.002 * static_cast<double>(sample_rate_))); // process all the samples available in the file excluding at least the last 1 ms samples_ = floor(static_cast<double>(bytes_to_process) / static_cast<double>(item_size_) - ceil(0.002 * static_cast<double>(sample_rate_))); // process all the samples available in the file excluding at least the last 1 ms
} }
if (!filename1.empty()) if (!filename1_.empty())
{ {
std::ifstream file(filename1.c_str(), std::ios::in | std::ios::binary | std::ios::ate); std::ifstream file(filename1_.c_str(), std::ios::in | std::ios::binary | std::ios::ate);
std::ifstream::pos_type size; std::ifstream::pos_type size;
if (file.is_open()) if (file.is_open())
@ -210,13 +216,13 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con
} }
else else
{ {
std::cerr << "SignalSource: Unable to open the samples file " << filename1.c_str() << '\n'; std::cerr << "SignalSource: Unable to open the samples file " << filename1_.c_str() << '\n';
item_size_ = 0; item_size_ = 0;
return; return;
} }
std::streamsize ss = std::cout.precision(); std::streamsize ss = std::cout.precision();
std::cout << std::setprecision(16); std::cout << std::setprecision(16);
std::cout << "Processing file " << filename1 << ", which contains " << static_cast<double>(size) << " [bytes]\n"; std::cout << "Processing file " << filename1_ << ", which contains " << static_cast<double>(size) << " [bytes]\n";
std::cout.precision(ss); std::cout.precision(ss);
int64_t samples_rx2 = 0; int64_t samples_rx2 = 0;
@ -236,14 +242,14 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con
DLOG(INFO) << "Total number samples to be processed= " << samples_ << " GNSS signal duration= " << signal_duration_s << " [s]"; DLOG(INFO) << "Total number samples to be processed= " << samples_ << " GNSS signal duration= " << signal_duration_s << " [s]";
std::cout << "GNSS signal recorded time to be processed: " << signal_duration_s << " [s]\n"; std::cout << "GNSS signal recorded time to be processed: " << signal_duration_s << " [s]\n";
if (filename1.empty()) if (filename1_.empty())
{ {
DLOG(INFO) << "File source filename " << filename0; DLOG(INFO) << "File source filename " << filename0_;
} }
else else
{ {
DLOG(INFO) << "File source filename rx1 " << filename0; DLOG(INFO) << "File source filename rx1 " << filename0_;
DLOG(INFO) << "File source filename rx2 " << filename1; DLOG(INFO) << "File source filename rx2 " << filename1_;
} }
DLOG(INFO) << "Samples " << samples_; DLOG(INFO) << "Samples " << samples_;
DLOG(INFO) << "Sampling frequency " << sample_rate_; DLOG(INFO) << "Sampling frequency " << sample_rate_;
@ -521,39 +527,43 @@ Ad9361FpgaSignalSource::~Ad9361FpgaSignalSource()
void Ad9361FpgaSignalSource::start() void Ad9361FpgaSignalSource::start()
{ {
thread_file_to_dma = std::thread([&] { run_DMA_process(filename0, filename1, samples_to_skip_, item_size_, samples_, repeat_, dma_buff_offset_pos_, queue_); }); thread_file_to_dma = std::thread([&] { run_DMA_process(filename0_, filename1_, samples_to_skip_, item_size_, samples_, repeat_, dma_buff_offset_pos_, queue_); });
} }
void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const std::string &filename1, uint64_t &samples_to_skip, size_t &item_size, int64_t &samples, bool &repeat, uint32_t &dma_buff_offset_pos, Concurrent_Queue<pmt::pmt_t> *queue) void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0_, const std::string &filename1_, uint64_t &samples_to_skip, size_t &item_size, int64_t &samples, bool &repeat, uint32_t &dma_buff_offset_pos, Concurrent_Queue<pmt::pmt_t> *queue)
{ {
std::ifstream infile1; std::ifstream infile1;
infile1.exceptions(std::ifstream::failbit | std::ifstream::badbit); infile1.exceptions(std::ifstream::failbit | std::ifstream::badbit);
// FPGA DMA control
dma_fpga = std::make_shared<Fpga_DMA>();
// open the files // open the files
try try
{ {
infile1.open(filename0, std::ios::binary); infile1.open(filename0_, std::ios::binary);
} }
catch (const std::ifstream::failure &e) catch (const std::ifstream::failure &e)
{ {
std::cerr << "Exception opening file " << filename0 << '\n'; std::cerr << "Exception opening file " << filename0_ << '\n';
// stop the receiver // stop the receiver
queue->push(pmt::make_any(command_event_make(200, 0))); queue->push(pmt::make_any(command_event_make(200, 0)));
return; return;
} }
std::ifstream infile2; std::ifstream infile2;
if (!filename1.empty()) if (!filename1_.empty())
{ {
infile2.exceptions(std::ifstream::failbit | std::ifstream::badbit); infile2.exceptions(std::ifstream::failbit | std::ifstream::badbit);
try try
{ {
infile2.open(filename1, std::ios::binary); infile2.open(filename1_, std::ios::binary);
} }
catch (const std::ifstream::failure &e) catch (const std::ifstream::failure &e)
{ {
std::cerr << "Exception opening file " << filename1 << '\n'; std::cerr << "Exception opening file " << filename1_ << '\n';
// stop the receiver // stop the receiver
queue->push(pmt::make_any(command_event_make(200, 0))); queue->push(pmt::make_any(command_event_make(200, 0)));
return; return;
@ -568,13 +578,13 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const
} }
catch (const std::ifstream::failure &e) catch (const std::ifstream::failure &e)
{ {
std::cerr << "Exception skipping initial samples file " << filename0 << '\n'; std::cerr << "Exception skipping initial samples file " << filename0_ << '\n';
// stop the receiver // stop the receiver
queue->push(pmt::make_any(command_event_make(200, 0))); queue->push(pmt::make_any(command_event_make(200, 0)));
return; return;
} }
if (!filename1.empty()) if (!filename1_.empty())
{ {
try try
{ {
@ -582,7 +592,7 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const
} }
catch (const std::ifstream::failure &e) catch (const std::ifstream::failure &e)
{ {
std::cerr << "Exception skipping initial samples file " << filename1 << '\n'; std::cerr << "Exception skipping initial samples file " << filename1_ << '\n';
// stop the receiver // stop the receiver
queue->push(pmt::make_any(command_event_make(200, 0))); queue->push(pmt::make_any(command_event_make(200, 0)));
return; return;
@ -591,37 +601,20 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const
// rx signal vectors // rx signal vectors
std::vector<int8_t> input_samples(sample_block_size * 2); // complex samples std::vector<int8_t> input_samples(sample_block_size * 2); // complex samples
std::vector<int8_t> input_samples_dma(sample_block_size * 4); // complex samples, two frequency bands // pointer to DMA buffer
std::array<int8_t, BUFFER_SIZE> *dma_buffer;
int nread_elements = 0; // num bytes read from the file corresponding to frequency band 1 int nread_elements = 0; // num bytes read from the file corresponding to frequency band 1
bool run_DMA = true; bool run_DMA = true;
int num_transferred_bytes;
// Open DMA device // Open DMA device
int tx_fd = open("/dev/loop_tx", O_WRONLY); if (dma_fpga->DMA_open())
if (tx_fd < 0)
{
std::cerr << "Cannot open loop device\n";
// stop the receiver
queue->push(pmt::make_any(command_event_make(200, 0)));
return;
}
// note: a problem was identified with the DMA: when switching from tx to rx or rx to tx mode
// the DMA transmission may hang. This problem will be fixed soon.
// for the moment this problem can be avoided by closing and opening the DMA a second time
if (close(tx_fd) < 0)
{
std::cerr << "Error closing loop device " << '\n';
}
// open the DMA a second time
tx_fd = open("/dev/loop_tx", O_WRONLY);
if (tx_fd < 0)
{ {
std::cerr << "Cannot open loop device\n"; std::cerr << "Cannot open loop device\n";
// stop the receiver // stop the receiver
queue->push(pmt::make_any(command_event_make(200, 0))); queue->push(pmt::make_any(command_event_make(200, 0)));
return; return;
} }
dma_buffer = dma_fpga->get_buffer_address();
// if only one frequency band is used then clear the samples corresponding to the unused frequency band // if only one frequency band is used then clear the samples corresponding to the unused frequency band
uint32_t dma_index = 0; uint32_t dma_index = 0;
@ -630,8 +623,8 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const
// if only one file is enabled then clear the samples corresponding to the frequency band that is not used. // if only one file is enabled then clear the samples corresponding to the frequency band that is not used.
for (int index0 = 0; index0 < (nread_elements); index0 += 2) for (int index0 = 0; index0 < (nread_elements); index0 += 2)
{ {
input_samples_dma[dma_index + (2 - dma_buff_offset_pos)] = 0; (*dma_buffer)[dma_index + (2 - dma_buff_offset_pos)] = 0;
input_samples_dma[dma_index + 1 + (2 - dma_buff_offset_pos)] = 0; (*dma_buffer)[dma_index + 1 + (2 - dma_buff_offset_pos)] = 0;
dma_index += 4; dma_index += 4;
} }
} }
@ -656,7 +649,7 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const
} }
catch (const std::ifstream::failure &e) catch (const std::ifstream::failure &e)
{ {
std::cerr << "Exception reading file " << filename0 << '\n'; std::cerr << "Exception reading file " << filename0_ << '\n';
break; break;
} }
if (infile1) if (infile1)
@ -672,8 +665,8 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const
for (int index0 = 0; index0 < (nread_elements); index0 += 2) for (int index0 = 0; index0 < (nread_elements); index0 += 2)
{ {
// dma_buff_offset_pos is 1 for the L1 band and 0 for the other bands // dma_buff_offset_pos is 1 for the L1 band and 0 for the other bands
input_samples_dma[dma_index + dma_buff_offset_pos] = input_samples[index0]; (*dma_buffer)[dma_index + dma_buff_offset_pos] = input_samples[index0];
input_samples_dma[dma_index + 1 + dma_buff_offset_pos] = input_samples[index0 + 1]; (*dma_buffer)[dma_index + 1 + dma_buff_offset_pos] = input_samples[index0 + 1];
dma_index += 4; dma_index += 4;
} }
@ -687,7 +680,7 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const
} }
catch (const std::ifstream::failure &e) catch (const std::ifstream::failure &e)
{ {
std::cerr << "Exception reading file " << filename1 << '\n'; std::cerr << "Exception reading file " << filename1_ << '\n';
break; break;
} }
if (infile2) if (infile2)
@ -703,22 +696,19 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const
for (int index0 = 0; index0 < (nread_elements); index0 += 2) for (int index0 = 0; index0 < (nread_elements); index0 += 2)
{ {
// filename2 is never the L1 band // filename2 is never the L1 band
input_samples_dma[dma_index] = input_samples[index0]; (*dma_buffer)[dma_index] = input_samples[index0];
input_samples_dma[dma_index + 1] = input_samples[index0 + 1]; (*dma_buffer)[dma_index + 1] = input_samples[index0 + 1];
dma_index += 4; dma_index += 4;
} }
} }
if (nread_elements > 0) if (nread_elements > 0)
{ {
num_transferred_bytes = nread_elements * 2; if (dma_fpga->DMA_write(nread_elements * 2))
const int num_bytes_sent = write(tx_fd, input_samples_dma.data(), nread_elements * 2);
if (num_bytes_sent != num_transferred_bytes)
{ {
std::cerr << "Error: DMA could not send all the required samples\n"; std::cerr << "Error: DMA could not send all the required samples\n";
break; break;
} }
// Throttle the DMA // Throttle the DMA
std::this_thread::sleep_for(std::chrono::milliseconds(1)); std::this_thread::sleep_for(std::chrono::milliseconds(1));
} }
@ -736,7 +726,7 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const
} }
catch (const std::ifstream::failure &e) catch (const std::ifstream::failure &e)
{ {
std::cerr << "Exception resetting the position of the next byte to be extracted to zero " << filename0 << '\n'; std::cerr << "Exception resetting the position of the next byte to be extracted to zero " << filename0_ << '\n';
break; break;
} }
@ -748,11 +738,11 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const
} }
catch (const std::ifstream::failure &e) catch (const std::ifstream::failure &e)
{ {
std::cerr << "Exception skipping initial samples file " << filename0 << '\n'; std::cerr << "Exception skipping initial samples file " << filename0_ << '\n';
break; break;
} }
if (!filename1.empty()) if (!filename1_.empty())
{ {
try try
{ {
@ -760,7 +750,7 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const
} }
catch (const std::ifstream::failure &e) catch (const std::ifstream::failure &e)
{ {
std::cerr << "Exception setting the position of the next byte to be extracted to zero " << filename1 << '\n'; std::cerr << "Exception setting the position of the next byte to be extracted to zero " << filename1_ << '\n';
break; break;
} }
@ -770,7 +760,7 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const
} }
catch (const std::ifstream::failure &e) catch (const std::ifstream::failure &e)
{ {
std::cerr << "Exception skipping initial samples file " << filename1 << '\n'; std::cerr << "Exception skipping initial samples file " << filename1_ << '\n';
break; break;
} }
} }
@ -789,18 +779,17 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const
lock.unlock(); lock.unlock();
} }
if (close(tx_fd) < 0) if (dma_fpga->DMA_close())
{ {
std::cerr << "Error closing loop device " << '\n'; std::cerr << "Error closing loop device " << '\n';
} }
try try
{ {
infile1.close(); infile1.close();
} }
catch (const std::ifstream::failure &e) catch (const std::ifstream::failure &e)
{ {
std::cerr << "Exception closing file " << filename0 << '\n'; std::cerr << "Exception closing file " << filename0_ << '\n';
} }
if (num_freq_bands_ > 1) if (num_freq_bands_ > 1)
@ -811,7 +800,7 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const
} }
catch (const std::ifstream::failure &e) catch (const std::ifstream::failure &e)
{ {
std::cerr << "Exception closing file " << filename1 << '\n'; std::cerr << "Exception closing file " << filename1_ << '\n';
} }
} }

View File

@ -23,6 +23,7 @@
#include "concurrent_queue.h" #include "concurrent_queue.h"
#include "fpga_buffer_monitor.h" #include "fpga_buffer_monitor.h"
#include "fpga_dma.h"
#include "fpga_dynamic_bit_selection.h" #include "fpga_dynamic_bit_selection.h"
#include "fpga_switch.h" #include "fpga_switch.h"
#include "gnss_block_interface.h" #include "gnss_block_interface.h"
@ -71,6 +72,7 @@ private:
const std::string default_dump_filename = std::string("FPGA_buffer_monitor_dump.dat"); const std::string default_dump_filename = std::string("FPGA_buffer_monitor_dump.dat");
const std::string default_rf_port_select = std::string("A_BALANCED"); const std::string default_rf_port_select = std::string("A_BALANCED");
const std::string default_gain_mode = std::string("slow_attack"); const std::string default_gain_mode = std::string("slow_attack");
const std::string empty_string;
const double default_tx_attenuation_db = -10.0; const double default_tx_attenuation_db = -10.0;
const double default_manual_gain_rx1 = 64.0; const double default_manual_gain_rx1 = 64.0;
const double default_manual_gain_rx2 = 64.0; const double default_manual_gain_rx2 = 64.0;
@ -104,6 +106,7 @@ private:
std::shared_ptr<Fpga_Switch> switch_fpga; std::shared_ptr<Fpga_Switch> switch_fpga;
std::shared_ptr<Fpga_dynamic_bit_selection> dynamic_bit_selection_fpga; std::shared_ptr<Fpga_dynamic_bit_selection> dynamic_bit_selection_fpga;
std::shared_ptr<Fpga_buffer_monitor> buffer_monitor_fpga; std::shared_ptr<Fpga_buffer_monitor> buffer_monitor_fpga;
std::shared_ptr<Fpga_DMA> dma_fpga;
std::mutex dma_mutex; std::mutex dma_mutex;
std::mutex dynamic_bit_selection_mutex; std::mutex dynamic_bit_selection_mutex;
@ -118,8 +121,8 @@ private:
std::string filter_file_; std::string filter_file_;
std::string filter_source_; std::string filter_source_;
std::string filter_filename_; std::string filter_filename_;
std::string filename0; std::string filename0_;
std::string filename1; std::string filename1_;
double rf_gain_rx1_; double rf_gain_rx1_;
double rf_gain_rx2_; double rf_gain_rx2_;

View File

@ -19,6 +19,7 @@
#include "gnss_frequencies.h" #include "gnss_frequencies.h"
#include "gnss_sdr_string_literals.h" #include "gnss_sdr_string_literals.h"
#include "gnss_sdr_valve.h" #include "gnss_sdr_valve.h"
#include <boost/exception/diagnostic_information.hpp>
#include <glog/logging.h> #include <glog/logging.h>
#include <gnuradio/blocks/file_sink.h> #include <gnuradio/blocks/file_sink.h>
#include <iostream> #include <iostream>

View File

@ -20,6 +20,7 @@
#include "configuration_interface.h" #include "configuration_interface.h"
#include "gnss_sdr_string_literals.h" #include "gnss_sdr_string_literals.h"
#include "gnss_sdr_valve.h" #include "gnss_sdr_valve.h"
#include <boost/exception/diagnostic_information.hpp>
#include <glog/logging.h> #include <glog/logging.h>
#include <gnuradio/blocks/file_sink.h> #include <gnuradio/blocks/file_sink.h>
#include <iostream> #include <iostream>

View File

@ -21,6 +21,7 @@
#include "configuration_interface.h" #include "configuration_interface.h"
#include "gnss_sdr_string_literals.h" #include "gnss_sdr_string_literals.h"
#include "gnss_sdr_valve.h" #include "gnss_sdr_valve.h"
#include <boost/exception/diagnostic_information.hpp>
#include <glog/logging.h> #include <glog/logging.h>
#include <cstdint> #include <cstdint>
#include <iostream> #include <iostream>

View File

@ -19,6 +19,8 @@ if(ENABLE_FPGA OR ENABLE_AD9361)
set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} fpga_dynamic_bit_selection.h) set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} fpga_dynamic_bit_selection.h)
set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} fpga_buffer_monitor.cc) set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} fpga_buffer_monitor.cc)
set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} fpga_buffer_monitor.h) set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} fpga_buffer_monitor.h)
set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} fpga_dma.cc)
set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} fpga_dma.h)
endif() endif()
set(SIGNAL_SOURCE_LIB_SOURCES set(SIGNAL_SOURCE_LIB_SOURCES

View File

@ -61,7 +61,7 @@ public:
void check_buffer_overflow_and_monitor_buffer_status(); void check_buffer_overflow_and_monitor_buffer_status();
private: private:
static const size_t FPGA_PAGE_SIZE = 0x10000; static const size_t FPGA_PAGE_SIZE = 0x1000;
static const uint32_t test_register_writeval = 0x55AA; static const uint32_t test_register_writeval = 0x55AA;
static const uint32_t num_sapmples_per_buffer_element = 2; static const uint32_t num_sapmples_per_buffer_element = 2;
// write addresses // write addresses

View File

@ -0,0 +1,134 @@
/*!
* \file fpga_dma.cc
* \brief FPGA DMA control. This code is based in the Xilinx DMA proxy test application:
* https://github.com/Xilinx-Wiki-Projects/software-prototypes/tree/master/linux-user-space-dma/Software
* \author Marc Majoral, mmajoral(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 "fpga_dma.h"
#include <fcntl.h>
#include <iostream> // for std::cerr
#include <sys/ioctl.h> // for ioctl()
#include <sys/mman.h> // libraries used by the GIPO
#include <unistd.h>
int Fpga_DMA::DMA_open()
{
#if INTPTR_MAX == INT64_MAX // 64-bit processor architecture
tx_channel.fd = open("/dev/dma_proxy_tx", O_RDWR);
if (tx_channel.fd < 1)
{
return tx_channel.fd;
}
tx_channel.buf_ptr = (struct channel_buffer *)mmap(NULL, sizeof(struct channel_buffer) * TX_BUFFER_COUNT,
PROT_READ | PROT_WRITE, MAP_SHARED, tx_channel.fd, 0);
if (tx_channel.buf_ptr == MAP_FAILED)
{
std::cerr << "Failed to mmap DMA tx channel\n"
<< std::endl;
return -1;
}
#else // 32-bit processor architecture
tx_fd = open("/dev/loop_tx", O_WRONLY);
if (tx_fd < 1)
{
return tx_fd;
}
// note: a problem was identified with the DMA: when switching from tx to rx or rx to tx mode
// the DMA transmission may hang. This problem will be fixed soon.
// for the moment this problem can be avoided by closing and opening the DMA a second time
if (close(tx_fd) < 0)
{
std::cerr << "Error closing loop device " << '\n';
return -1;
}
// open the DMA a second time
tx_fd = open("/dev/loop_tx", O_WRONLY);
if (tx_fd < 1)
{
std::cerr << "Cannot open loop device\n";
// stop the receiver
return tx_fd;
}
#endif
return 0;
}
std::array<int8_t, BUFFER_SIZE> *Fpga_DMA::get_buffer_address(void)
{
#if INTPTR_MAX == INT64_MAX // 64-bit processor architecture
return &tx_channel.buf_ptr[0].buffer;
#else // 32-bit processor architecture
return &buffer;
#endif
}
int Fpga_DMA::DMA_write(int nbytes)
{
#if INTPTR_MAX == INT64_MAX // 64-bit processor architecture
int buffer_id = 0;
tx_channel.buf_ptr[0].length = nbytes;
// start DMA transfer
if (ioctl(tx_channel.fd, START_XFER, &buffer_id))
{
std::cerr << "Error starting tx DMA transfer " << '\n';
return -1;
}
// wait for completion of DMA transfer
if (ioctl(tx_channel.fd, FINISH_XFER, &buffer_id))
{
std::cerr << "Error detecting end of DMA transfer " << '\n';
return -1;
}
if (tx_channel.buf_ptr[buffer_id].status)
{
std::cerr << "Proxy DMA Tx transfer error " << '\n';
return -1;
}
#else // 32-bit processor architecture
const int num_bytes_sent = write(tx_fd, buffer.data(), nbytes);
if (num_bytes_sent != nbytes)
{
return -1;
}
#endif
return 0;
}
int Fpga_DMA::DMA_close()
{
#if INTPTR_MAX == INT64_MAX // 64-bit processor architecture
if (munmap(tx_channel.buf_ptr, sizeof(struct channel_buffer)))
{
std::cerr << "Failed to unmap DMA tx channel " << '\n';
return -1;
}
return close(tx_channel.fd);
#else // 32-bit processor architecture
return close(tx_fd);
#endif
}

View File

@ -0,0 +1,101 @@
/*!
* \file fpga_dma.h
* \brief FPGA DMA control. This code is based in the Xilinx DMA proxy test application:
* https://github.com/Xilinx-Wiki-Projects/software-prototypes/tree/master/linux-user-space-dma/Software
* \author Marc Majoral, mmajoral(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
*
* -----------------------------------------------------------------------------
*/
#ifndef GNSS_SDR_FPGA_DMA_H
#define GNSS_SDR_FPGA_DMA_H
#include <array> // for std::array
#include <cstdint> // for std::int8_t
#define BUFFER_SIZE (128 * 1024) /* must match driver exactly */
#if INTPTR_MAX == INT64_MAX // 64-bit processor architecture
#define TX_BUFFER_COUNT 1 /* app only, must be <= to the number in the driver */
#define FINISH_XFER _IOW('a', 'a', int32_t *)
#define START_XFER _IOW('a', 'b', int32_t *)
// channel buffer structure
struct channel_buffer
{
std::array<int8_t, BUFFER_SIZE> buffer;
enum proxy_status
{
PROXY_NO_ERROR = 0,
PROXY_BUSY = 1,
PROXY_TIMEOUT = 2,
PROXY_ERROR = 3
} status;
unsigned int length;
} __attribute__((aligned(1024))); /* 64 byte alignment required for DMA, but 1024 handy for viewing memory */
// internal DMA channel data structure
struct channel
{
struct channel_buffer *buf_ptr;
int fd;
};
#endif
/*!
* \brief Class that controls the switch DMA in the FPGA
*/
class Fpga_DMA
{
public:
/*!
* \brief Default constructor.
*/
Fpga_DMA() = default;
/*!
* \brief Default destructor.
*/
~Fpga_DMA() = default;
/*!
* \brief Open the DMA device driver.
*/
int DMA_open(void);
/*!
* \brief Obtain DMA buffer address.
*/
std::array<int8_t, BUFFER_SIZE> *get_buffer_address(void);
/*!
* \brief Transfer DMA data
*/
int DMA_write(int nbytes);
/*!
* \brief Close the DMA device driver
*/
int DMA_close(void);
private:
#if INTPTR_MAX == INT64_MAX // 64-bit processor architecture
channel tx_channel;
#else // 32-bit processor architecture
std::array<int8_t, BUFFER_SIZE> buffer;
int tx_fd;
#endif
};
#endif // GNSS_SDR_FPGA_DMA_H

View File

@ -56,7 +56,7 @@ public:
void bit_selection(void); void bit_selection(void);
private: private:
static const size_t FPGA_PAGE_SIZE = 0x10000; static const size_t FPGA_PAGE_SIZE = 0x1000;
static const uint32_t Num_bits_ADC = 12; // Number of bits in the ADC static const uint32_t Num_bits_ADC = 12; // Number of bits in the ADC
static const uint32_t Num_bits_FPGA = 4; // Number of bits after the bit selection static const uint32_t Num_bits_FPGA = 4; // Number of bits after the bit selection

View File

@ -54,7 +54,7 @@ public:
void set_switch_position(int32_t switch_position); void set_switch_position(int32_t switch_position);
private: private:
static const size_t FPGA_PAGE_SIZE = 0x10000; static const size_t FPGA_PAGE_SIZE = 0x1000;
static const uint32_t TEST_REGISTER_TRACK_WRITEVAL = 0x55AA; static const uint32_t TEST_REGISTER_TRACK_WRITEVAL = 0x55AA;
static const uint32_t MAX_LENGTH_DEVICEIO_NAME = 50; static const uint32_t MAX_LENGTH_DEVICEIO_NAME = 50;

View File

@ -29,8 +29,6 @@
#include <glog/logging.h> #include <glog/logging.h>
#include <array> #include <array>
using google::LogMessage;
BeidouB3iDllPllTracking::BeidouB3iDllPllTracking( BeidouB3iDllPllTracking::BeidouB3iDllPllTracking(
const ConfigurationInterface* configuration, const std::string& role, const ConfigurationInterface* configuration, const std::string& role,
unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams) unsigned int in_streams, unsigned int out_streams) : role_(role), in_streams_(in_streams), out_streams_(out_streams)

View File

@ -129,7 +129,7 @@ glonass_l1_ca_dll_pll_c_aid_tracking_cc::glonass_l1_ca_dll_pll_c_aid_tracking_cc
d_code_phase_step_chips(0.0), d_code_phase_step_chips(0.0),
d_carrier_doppler_hz(0.0), d_carrier_doppler_hz(0.0),
d_carrier_frequency_hz(0.0), d_carrier_frequency_hz(0.0),
d_carrier_doppler_old_hz(0.0), d_carrier_frequency_old_hz(0.0),
d_carrier_phase_step_rad(0.0), d_carrier_phase_step_rad(0.0),
d_acc_carrier_phase_cycles(0.0), d_acc_carrier_phase_cycles(0.0),
d_code_phase_samples(0.0), d_code_phase_samples(0.0),
@ -682,15 +682,16 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __at
// ################## PLL ########################################################## // ################## PLL ##########################################################
// Update PLL discriminator [rads/Ti -> Secs/Ti] // Update PLL discriminator [rads/Ti -> Secs/Ti]
d_carr_phase_error_secs_Ti = pll_cloop_two_quadrant_atan(d_correlator_outs[1]) / TWO_PI; // prompt output d_carr_phase_error_secs_Ti = pll_cloop_two_quadrant_atan(d_correlator_outs[1]) / TWO_PI; // prompt output
d_carrier_doppler_old_hz = d_carrier_doppler_hz; d_carrier_frequency_old_hz = d_carrier_frequency_hz;
// Carrier discriminator filter // Carrier discriminator filter
// NOTICE: The carrier loop filter includes the Carrier Doppler accumulator, as described in Kaplan // NOTICE: The carrier loop filter includes the Carrier Doppler accumulator, as described in Kaplan
// Input [s/Ti] -> output [Hz] // Input [s/Ti] -> output [Hz]
d_carrier_doppler_hz = d_carrier_loop_filter.get_carrier_error(0.0, static_cast<float>(d_carr_phase_error_secs_Ti), static_cast<float>(CURRENT_INTEGRATION_TIME_S)); d_carrier_frequency_hz = d_carrier_loop_filter.get_carrier_error(0.0, static_cast<float>(d_carr_phase_error_secs_Ti), static_cast<float>(CURRENT_INTEGRATION_TIME_S));
d_carrier_doppler_hz = d_carrier_frequency_hz - DFRQ1_GLO * GLONASS_PRN.at(d_acquisition_gnss_synchro->PRN);
// PLL to DLL assistance [Secs/Ti] // PLL to DLL assistance [Secs/Ti]
d_pll_to_dll_assist_secs_Ti = (d_carrier_doppler_hz * CURRENT_INTEGRATION_TIME_S) / d_glonass_freq_ch; d_pll_to_dll_assist_secs_Ti = (d_carrier_frequency_hz * CURRENT_INTEGRATION_TIME_S) / d_glonass_freq_ch;
// code Doppler frequency update // code Doppler frequency update
d_code_freq_chips = GLONASS_L1_CA_CODE_RATE_CPS + (((d_carrier_doppler_hz - d_carrier_doppler_old_hz) * GLONASS_L1_CA_CODE_RATE_CPS) / d_glonass_freq_ch); d_code_freq_chips = GLONASS_L1_CA_CODE_RATE_CPS + (((d_carrier_frequency_hz - d_carrier_frequency_old_hz) * GLONASS_L1_CA_CODE_RATE_CPS) / d_glonass_freq_ch);
// ################## DLL ########################################################## // ################## DLL ##########################################################
// DLL discriminator // DLL discriminator
@ -716,12 +717,12 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __at
// ################### PLL COMMANDS ################################################# // ################### PLL COMMANDS #################################################
// carrier phase step (NCO phase increment per sample) [rads/sample] // carrier phase step (NCO phase increment per sample) [rads/sample]
d_carrier_phase_step_rad = TWO_PI * d_carrier_doppler_hz / static_cast<double>(d_fs_in); d_carrier_phase_step_rad = TWO_PI * d_carrier_frequency_hz / static_cast<double>(d_fs_in);
d_acc_carrier_phase_cycles -= d_carrier_phase_step_rad * d_correlation_length_samples / TWO_PI; d_acc_carrier_phase_cycles -= d_carrier_phase_step_rad * d_correlation_length_samples / TWO_PI;
// UPDATE ACCUMULATED CARRIER PHASE // UPDATE ACCUMULATED CARRIER PHASE
CORRECTED_INTEGRATION_TIME_S = (static_cast<double>(d_correlation_length_samples) / static_cast<double>(d_fs_in)); CORRECTED_INTEGRATION_TIME_S = (static_cast<double>(d_correlation_length_samples) / static_cast<double>(d_fs_in));
// remnant carrier phase [rad] // remnant carrier phase [rad]
d_rem_carrier_phase_rad = fmod(d_rem_carrier_phase_rad + TWO_PI * d_carrier_doppler_hz * CORRECTED_INTEGRATION_TIME_S, TWO_PI); d_rem_carrier_phase_rad = fmod(d_rem_carrier_phase_rad + TWO_PI * d_carrier_frequency_hz * CORRECTED_INTEGRATION_TIME_S, TWO_PI);
// ################### DLL COMMANDS ################################################# // ################### DLL COMMANDS #################################################
// code phase step (Code resampler phase increment per sample) [chips/sample] // code phase step (Code resampler phase increment per sample) [chips/sample]

View File

@ -161,7 +161,7 @@ private:
double d_code_phase_step_chips; double d_code_phase_step_chips;
double d_carrier_doppler_hz; double d_carrier_doppler_hz;
double d_carrier_frequency_hz; double d_carrier_frequency_hz;
double d_carrier_doppler_old_hz; double d_carrier_frequency_old_hz;
double d_carrier_phase_step_rad; double d_carrier_phase_step_rad;
double d_acc_carrier_phase_cycles; double d_acc_carrier_phase_cycles;
double d_code_phase_samples; double d_code_phase_samples;

View File

@ -127,7 +127,7 @@ glonass_l1_ca_dll_pll_c_aid_tracking_sc::glonass_l1_ca_dll_pll_c_aid_tracking_sc
d_code_phase_step_chips(0.0), d_code_phase_step_chips(0.0),
d_carrier_doppler_hz(0.0), d_carrier_doppler_hz(0.0),
d_carrier_frequency_hz(0.0), d_carrier_frequency_hz(0.0),
d_carrier_doppler_old_hz(0.0), d_carrier_frequency_old_hz(0.0),
d_carrier_phase_step_rad(0.0), d_carrier_phase_step_rad(0.0),
d_acc_carrier_phase_cycles(0.0), d_acc_carrier_phase_cycles(0.0),
d_code_phase_samples(0.0), d_code_phase_samples(0.0),
@ -682,15 +682,16 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __at
// ################## PLL ########################################################## // ################## PLL ##########################################################
// Update PLL discriminator [rads/Ti -> Secs/Ti] // Update PLL discriminator [rads/Ti -> Secs/Ti]
d_carr_phase_error_secs_Ti = pll_cloop_two_quadrant_atan(std::complex<float>(d_correlator_outs_16sc[1].real(), d_correlator_outs_16sc[1].imag())) / TWO_PI; // prompt output d_carr_phase_error_secs_Ti = pll_cloop_two_quadrant_atan(std::complex<float>(d_correlator_outs_16sc[1].real(), d_correlator_outs_16sc[1].imag())) / TWO_PI; // prompt output
d_carrier_doppler_old_hz = d_carrier_doppler_hz; d_carrier_frequency_old_hz = d_carrier_frequency_hz;
// Carrier discriminator filter // Carrier discriminator filter
// NOTICE: The carrier loop filter includes the Carrier Doppler accumulator, as described in Kaplan // NOTICE: The carrier loop filter includes the Carrier Doppler accumulator, as described in Kaplan
// Input [s/Ti] -> output [Hz] // Input [s/Ti] -> output [Hz]
d_carrier_doppler_hz = d_carrier_loop_filter.get_carrier_error(0.0, static_cast<float>(d_carr_phase_error_secs_Ti), static_cast<float>(CURRENT_INTEGRATION_TIME_S)); d_carrier_frequency_hz = d_carrier_loop_filter.get_carrier_error(0.0, static_cast<float>(d_carr_phase_error_secs_Ti), static_cast<float>(CURRENT_INTEGRATION_TIME_S));
d_carrier_doppler_hz = d_carrier_frequency_hz - DFRQ1_GLO * GLONASS_PRN.at(d_acquisition_gnss_synchro->PRN);
// PLL to DLL assistance [Secs/Ti] // PLL to DLL assistance [Secs/Ti]
d_pll_to_dll_assist_secs_Ti = (d_carrier_doppler_hz * CURRENT_INTEGRATION_TIME_S) / d_glonass_freq_ch; d_pll_to_dll_assist_secs_Ti = (d_carrier_frequency_hz * CURRENT_INTEGRATION_TIME_S) / d_glonass_freq_ch;
// code Doppler frequency update // code Doppler frequency update
d_code_freq_chips = GLONASS_L1_CA_CODE_RATE_CPS + (((d_carrier_doppler_hz - d_carrier_doppler_old_hz) * GLONASS_L1_CA_CODE_RATE_CPS) / d_glonass_freq_ch); d_code_freq_chips = GLONASS_L1_CA_CODE_RATE_CPS + (((d_carrier_frequency_hz - d_carrier_frequency_old_hz) * GLONASS_L1_CA_CODE_RATE_CPS) / d_glonass_freq_ch);
// ################## DLL ########################################################## // ################## DLL ##########################################################
// DLL discriminator // DLL discriminator
@ -716,12 +717,12 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __at
// ################### PLL COMMANDS ################################################# // ################### PLL COMMANDS #################################################
// carrier phase step (NCO phase increment per sample) [rads/sample] // carrier phase step (NCO phase increment per sample) [rads/sample]
d_carrier_phase_step_rad = TWO_PI * d_carrier_doppler_hz / static_cast<double>(d_fs_in); d_carrier_phase_step_rad = TWO_PI * d_carrier_frequency_hz / static_cast<double>(d_fs_in);
d_acc_carrier_phase_cycles -= d_carrier_phase_step_rad * d_correlation_length_samples / TWO_PI; d_acc_carrier_phase_cycles -= d_carrier_phase_step_rad * d_correlation_length_samples / TWO_PI;
// UPDATE ACCUMULATED CARRIER PHASE // UPDATE ACCUMULATED CARRIER PHASE
CORRECTED_INTEGRATION_TIME_S = (static_cast<double>(d_correlation_length_samples) / static_cast<double>(d_fs_in)); CORRECTED_INTEGRATION_TIME_S = (static_cast<double>(d_correlation_length_samples) / static_cast<double>(d_fs_in));
// remnant carrier phase [rad] // remnant carrier phase [rad]
d_rem_carrier_phase_rad = fmod(d_rem_carrier_phase_rad + TWO_PI * d_carrier_doppler_hz * CORRECTED_INTEGRATION_TIME_S, TWO_PI); d_rem_carrier_phase_rad = fmod(d_rem_carrier_phase_rad + TWO_PI * d_carrier_frequency_hz * CORRECTED_INTEGRATION_TIME_S, TWO_PI);
// ################### DLL COMMANDS ################################################# // ################### DLL COMMANDS #################################################
// code phase step (Code resampler phase increment per sample) [chips/sample] // code phase step (Code resampler phase increment per sample) [chips/sample]

View File

@ -163,7 +163,7 @@ private:
double d_code_phase_step_chips; double d_code_phase_step_chips;
double d_carrier_doppler_hz; double d_carrier_doppler_hz;
double d_carrier_frequency_hz; double d_carrier_frequency_hz;
double d_carrier_doppler_old_hz; double d_carrier_frequency_old_hz;
double d_carrier_phase_step_rad; double d_carrier_phase_step_rad;
double d_acc_carrier_phase_cycles; double d_acc_carrier_phase_cycles;
double d_code_phase_samples; double d_code_phase_samples;

View File

@ -126,7 +126,7 @@ glonass_l2_ca_dll_pll_c_aid_tracking_cc::glonass_l2_ca_dll_pll_c_aid_tracking_cc
d_code_phase_step_chips(0.0), d_code_phase_step_chips(0.0),
d_carrier_doppler_hz(0.0), d_carrier_doppler_hz(0.0),
d_carrier_frequency_hz(0.0), d_carrier_frequency_hz(0.0),
d_carrier_doppler_old_hz(0.0), d_carrier_frequency_old_hz(0.0),
d_carrier_phase_step_rad(0.0), d_carrier_phase_step_rad(0.0),
d_acc_carrier_phase_cycles(0.0), d_acc_carrier_phase_cycles(0.0),
d_code_phase_samples(0.0), d_code_phase_samples(0.0),
@ -680,15 +680,16 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __at
// ################## PLL ########################################################## // ################## PLL ##########################################################
// Update PLL discriminator [rads/Ti -> Secs/Ti] // Update PLL discriminator [rads/Ti -> Secs/Ti]
d_carr_phase_error_secs_Ti = pll_cloop_two_quadrant_atan(d_correlator_outs[1]) / TWO_PI; // prompt output d_carr_phase_error_secs_Ti = pll_cloop_two_quadrant_atan(d_correlator_outs[1]) / TWO_PI; // prompt output
d_carrier_doppler_old_hz = d_carrier_doppler_hz; d_carrier_frequency_old_hz = d_carrier_frequency_hz;
// Carrier discriminator filter // Carrier discriminator filter
// NOTICE: The carrier loop filter includes the Carrier Doppler accumulator, as described in Kaplan // NOTICE: The carrier loop filter includes the Carrier Doppler accumulator, as described in Kaplan
// Input [s/Ti] -> output [Hz] // Input [s/Ti] -> output [Hz]
d_carrier_doppler_hz = d_carrier_loop_filter.get_carrier_error(0.0, static_cast<float>(d_carr_phase_error_secs_Ti), static_cast<float>(CURRENT_INTEGRATION_TIME_S)); d_carrier_frequency_hz = d_carrier_loop_filter.get_carrier_error(0.0, static_cast<float>(d_carr_phase_error_secs_Ti), static_cast<float>(CURRENT_INTEGRATION_TIME_S));
d_carrier_doppler_hz = d_carrier_frequency_hz - DFRQ2_GLO * GLONASS_PRN.at(d_acquisition_gnss_synchro->PRN);
// PLL to DLL assistance [Secs/Ti] // PLL to DLL assistance [Secs/Ti]
d_pll_to_dll_assist_secs_Ti = (d_carrier_doppler_hz * CURRENT_INTEGRATION_TIME_S) / d_glonass_freq_ch; d_pll_to_dll_assist_secs_Ti = (d_carrier_frequency_hz * CURRENT_INTEGRATION_TIME_S) / d_glonass_freq_ch;
// code Doppler frequency update // code Doppler frequency update
d_code_freq_chips = GLONASS_L2_CA_CODE_RATE_CPS + (((d_carrier_doppler_hz - d_carrier_doppler_old_hz) * GLONASS_L2_CA_CODE_RATE_CPS) / d_glonass_freq_ch); d_code_freq_chips = GLONASS_L2_CA_CODE_RATE_CPS + (((d_carrier_frequency_hz - d_carrier_frequency_old_hz) * GLONASS_L2_CA_CODE_RATE_CPS) / d_glonass_freq_ch);
// ################## DLL ########################################################## // ################## DLL ##########################################################
// DLL discriminator // DLL discriminator
@ -714,12 +715,12 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __at
//################### PLL COMMANDS ################################################# //################### PLL COMMANDS #################################################
// carrier phase step (NCO phase increment per sample) [rads/sample] // carrier phase step (NCO phase increment per sample) [rads/sample]
d_carrier_phase_step_rad = TWO_PI * d_carrier_doppler_hz / static_cast<double>(d_fs_in); d_carrier_phase_step_rad = TWO_PI * d_carrier_frequency_hz / static_cast<double>(d_fs_in);
d_acc_carrier_phase_cycles -= d_carrier_phase_step_rad * d_correlation_length_samples / TWO_PI; d_acc_carrier_phase_cycles -= d_carrier_phase_step_rad * d_correlation_length_samples / TWO_PI;
// UPDATE ACCUMULATED CARRIER PHASE // UPDATE ACCUMULATED CARRIER PHASE
CORRECTED_INTEGRATION_TIME_S = (static_cast<double>(d_correlation_length_samples) / static_cast<double>(d_fs_in)); CORRECTED_INTEGRATION_TIME_S = (static_cast<double>(d_correlation_length_samples) / static_cast<double>(d_fs_in));
// remnant carrier phase [rad] // remnant carrier phase [rad]
d_rem_carrier_phase_rad = fmod(d_rem_carrier_phase_rad + TWO_PI * d_carrier_doppler_hz * CORRECTED_INTEGRATION_TIME_S, TWO_PI); d_rem_carrier_phase_rad = fmod(d_rem_carrier_phase_rad + TWO_PI * d_carrier_frequency_hz * CORRECTED_INTEGRATION_TIME_S, TWO_PI);
//################### DLL COMMANDS ################################################# //################### DLL COMMANDS #################################################
// code phase step (Code resampler phase increment per sample) [chips/sample] // code phase step (Code resampler phase increment per sample) [chips/sample]

View File

@ -159,7 +159,7 @@ private:
double d_code_phase_step_chips; double d_code_phase_step_chips;
double d_carrier_doppler_hz; double d_carrier_doppler_hz;
double d_carrier_frequency_hz; double d_carrier_frequency_hz;
double d_carrier_doppler_old_hz; double d_carrier_frequency_old_hz;
double d_carrier_phase_step_rad; double d_carrier_phase_step_rad;
double d_acc_carrier_phase_cycles; double d_acc_carrier_phase_cycles;
double d_code_phase_samples; double d_code_phase_samples;

View File

@ -125,7 +125,7 @@ glonass_l2_ca_dll_pll_c_aid_tracking_sc::glonass_l2_ca_dll_pll_c_aid_tracking_sc
d_code_phase_step_chips(0.0), d_code_phase_step_chips(0.0),
d_carrier_doppler_hz(0.0), d_carrier_doppler_hz(0.0),
d_carrier_frequency_hz(0.0), d_carrier_frequency_hz(0.0),
d_carrier_doppler_old_hz(0.0), d_carrier_frequency_old_hz(0.0),
d_carrier_phase_step_rad(0.0), d_carrier_phase_step_rad(0.0),
d_acc_carrier_phase_cycles(0.0), d_acc_carrier_phase_cycles(0.0),
d_code_phase_samples(0.0), d_code_phase_samples(0.0),
@ -679,15 +679,16 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __at
// ################## PLL ########################################################## // ################## PLL ##########################################################
// Update PLL discriminator [rads/Ti -> Secs/Ti] // Update PLL discriminator [rads/Ti -> Secs/Ti]
d_carr_phase_error_secs_Ti = pll_cloop_two_quadrant_atan(std::complex<float>(d_correlator_outs_16sc[1].real(), d_correlator_outs_16sc[1].imag())) / TWO_PI; // prompt output d_carr_phase_error_secs_Ti = pll_cloop_two_quadrant_atan(std::complex<float>(d_correlator_outs_16sc[1].real(), d_correlator_outs_16sc[1].imag())) / TWO_PI; // prompt output
d_carrier_doppler_old_hz = d_carrier_doppler_hz; d_carrier_frequency_old_hz = d_carrier_frequency_hz;
// Carrier discriminator filter // Carrier discriminator filter
// NOTICE: The carrier loop filter includes the Carrier Doppler accumulator, as described in Kaplan // NOTICE: The carrier loop filter includes the Carrier Doppler accumulator, as described in Kaplan
// Input [s/Ti] -> output [Hz] // Input [s/Ti] -> output [Hz]
d_carrier_doppler_hz = d_carrier_loop_filter.get_carrier_error(0.0, static_cast<float>(d_carr_phase_error_secs_Ti), static_cast<float>(CURRENT_INTEGRATION_TIME_S)); d_carrier_frequency_hz = d_carrier_loop_filter.get_carrier_error(0.0, static_cast<float>(d_carr_phase_error_secs_Ti), static_cast<float>(CURRENT_INTEGRATION_TIME_S));
d_carrier_doppler_hz = d_carrier_frequency_hz - DFRQ2_GLO * GLONASS_PRN.at(d_acquisition_gnss_synchro->PRN);
// PLL to DLL assistance [Secs/Ti] // PLL to DLL assistance [Secs/Ti]
d_pll_to_dll_assist_secs_Ti = (d_carrier_doppler_hz * CURRENT_INTEGRATION_TIME_S) / d_glonass_freq_ch; d_pll_to_dll_assist_secs_Ti = (d_carrier_frequency_hz * CURRENT_INTEGRATION_TIME_S) / d_glonass_freq_ch;
// code Doppler frequency update // code Doppler frequency update
d_code_freq_chips = GLONASS_L2_CA_CODE_RATE_CPS + (((d_carrier_doppler_hz - d_carrier_doppler_old_hz) * GLONASS_L2_CA_CODE_RATE_CPS) / d_glonass_freq_ch); d_code_freq_chips = GLONASS_L2_CA_CODE_RATE_CPS + (((d_carrier_frequency_hz - d_carrier_frequency_old_hz) * GLONASS_L2_CA_CODE_RATE_CPS) / d_glonass_freq_ch);
// ################## DLL ########################################################## // ################## DLL ##########################################################
// DLL discriminator // DLL discriminator
@ -713,12 +714,12 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __at
// ################### PLL COMMANDS ################################################# // ################### PLL COMMANDS #################################################
// carrier phase step (NCO phase increment per sample) [rads/sample] // carrier phase step (NCO phase increment per sample) [rads/sample]
d_carrier_phase_step_rad = TWO_PI * d_carrier_doppler_hz / static_cast<double>(d_fs_in); d_carrier_phase_step_rad = TWO_PI * d_carrier_frequency_hz / static_cast<double>(d_fs_in);
d_acc_carrier_phase_cycles -= d_carrier_phase_step_rad * d_correlation_length_samples / TWO_PI; d_acc_carrier_phase_cycles -= d_carrier_phase_step_rad * d_correlation_length_samples / TWO_PI;
// UPDATE ACCUMULATED CARRIER PHASE // UPDATE ACCUMULATED CARRIER PHASE
CORRECTED_INTEGRATION_TIME_S = (static_cast<double>(d_correlation_length_samples) / static_cast<double>(d_fs_in)); CORRECTED_INTEGRATION_TIME_S = (static_cast<double>(d_correlation_length_samples) / static_cast<double>(d_fs_in));
// remnant carrier phase [rad] // remnant carrier phase [rad]
d_rem_carrier_phase_rad = fmod(d_rem_carrier_phase_rad + TWO_PI * d_carrier_doppler_hz * CORRECTED_INTEGRATION_TIME_S, TWO_PI); d_rem_carrier_phase_rad = fmod(d_rem_carrier_phase_rad + TWO_PI * d_carrier_frequency_hz * CORRECTED_INTEGRATION_TIME_S, TWO_PI);
// ################### DLL COMMANDS ################################################# // ################### DLL COMMANDS #################################################
// code phase step (Code resampler phase increment per sample) [chips/sample] // code phase step (Code resampler phase increment per sample) [chips/sample]

View File

@ -158,7 +158,7 @@ private:
double d_code_phase_step_chips; double d_code_phase_step_chips;
double d_carrier_doppler_hz; double d_carrier_doppler_hz;
double d_carrier_frequency_hz; double d_carrier_frequency_hz;
double d_carrier_doppler_old_hz; double d_carrier_frequency_old_hz;
double d_carrier_phase_step_rad; double d_carrier_phase_step_rad;
double d_acc_carrier_phase_cycles; double d_acc_carrier_phase_cycles;
double d_code_phase_samples; double d_code_phase_samples;

View File

@ -197,7 +197,7 @@ void Fpga_Multicorrelator_8sc::open_channel(const std::string &device_io_name, u
LOG(WARNING) << "Cannot open deviceio" << device_io_name; LOG(WARNING) << "Cannot open deviceio" << device_io_name;
std::cout << "Cannot open deviceio" << device_io_name << '\n'; std::cout << "Cannot open deviceio" << device_io_name << '\n';
} }
d_map_base = reinterpret_cast<volatile uint32_t *>(mmap(nullptr, page_size, d_map_base = reinterpret_cast<volatile uint32_t *>(mmap(nullptr, FPGA_PAGE_SIZE,
PROT_READ | PROT_WRITE, MAP_SHARED, d_device_descriptor, 0)); PROT_READ | PROT_WRITE, MAP_SHARED, d_device_descriptor, 0));
if (d_map_base == reinterpret_cast<void *>(-1)) if (d_map_base == reinterpret_cast<void *>(-1))
@ -402,7 +402,7 @@ void Fpga_Multicorrelator_8sc::unlock_channel()
void Fpga_Multicorrelator_8sc::close_device() void Fpga_Multicorrelator_8sc::close_device()
{ {
auto *aux = const_cast<uint32_t *>(d_map_base); auto *aux = const_cast<uint32_t *>(d_map_base);
if (munmap(static_cast<void *>(aux), page_size) == -1) if (munmap(static_cast<void *>(aux), FPGA_PAGE_SIZE) == -1)
{ {
std::cout << "Failed to unmap memory uio\n"; std::cout << "Failed to unmap memory uio\n";
} }

View File

@ -186,7 +186,7 @@ private:
static const uint32_t drop_samples = 1; // bit 0 of drop_samples_reg_addr static const uint32_t drop_samples = 1; // bit 0 of drop_samples_reg_addr
static const uint32_t enable_secondary_code = 2; // bit 1 of drop_samples_reg_addr static const uint32_t enable_secondary_code = 2; // bit 1 of drop_samples_reg_addr
static const uint32_t init_secondary_code_addresses = 4; // bit 2 of drop_samples_reg_addr static const uint32_t init_secondary_code_addresses = 4; // bit 2 of drop_samples_reg_addr
static const uint32_t page_size = 0x10000; static const uint32_t FPGA_PAGE_SIZE = 0x1000;
static const uint32_t max_code_resampler_counter = 1 << 31; // 2^(number of bits of precision of the code resampler) static const uint32_t max_code_resampler_counter = 1 << 31; // 2^(number of bits of precision of the code resampler)
static const uint32_t local_code_fpga_clear_address_counter = 0x10000000; static const uint32_t local_code_fpga_clear_address_counter = 0x10000000;
static const uint32_t test_register_track_writeval = 0x55AA; static const uint32_t test_register_track_writeval = 0x55AA;

View File

@ -146,7 +146,7 @@ void gnss_sdr_fpga_sample_counter::open_device()
LOG(WARNING) << "Cannot open deviceio" << device_io_name; LOG(WARNING) << "Cannot open deviceio" << device_io_name;
std::cout << "Counter-Intr: cannot open deviceio" << device_io_name << '\n'; std::cout << "Counter-Intr: cannot open deviceio" << device_io_name << '\n';
} }
map_base = reinterpret_cast<volatile uint32_t *>(mmap(nullptr, page_size, map_base = reinterpret_cast<volatile uint32_t *>(mmap(nullptr, FPGA_PAGE_SIZE,
PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)); PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));
if (map_base == reinterpret_cast<void *>(-1)) if (map_base == reinterpret_cast<void *>(-1))
@ -176,7 +176,7 @@ void gnss_sdr_fpga_sample_counter::close_device()
map_base[2] = 0; // disable the generation of the interrupt in the device map_base[2] = 0; // disable the generation of the interrupt in the device
auto *aux = const_cast<uint32_t *>(map_base); auto *aux = const_cast<uint32_t *>(map_base);
if (munmap(static_cast<void *>(aux), page_size) == -1) if (munmap(static_cast<void *>(aux), FPGA_PAGE_SIZE) == -1)
{ {
std::cout << "Failed to unmap memory uio\n"; std::cout << "Failed to unmap memory uio\n";
} }

View File

@ -49,7 +49,7 @@ public:
private: private:
const std::string device_name = "counter"; // UIO device name const std::string device_name = "counter"; // UIO device name
static const uint32_t page_size = 0x10000; // default page size for the multicorrelator memory map static const uint32_t FPGA_PAGE_SIZE = 0x1000; // default page size for the multicorrelator memory map
static const uint32_t test_reg_sanity_check = 0x55AA; // value to check the presence of the test register (to detect the hw) static const uint32_t test_reg_sanity_check = 0x55AA; // value to check the presence of the test register (to detect the hw)
friend gnss_sdr_fpga_sample_counter_sptr gnss_sdr_make_fpga_sample_counter(double _fs, int32_t _interval_ms); friend gnss_sdr_fpga_sample_counter_sptr gnss_sdr_make_fpga_sample_counter(double _fs, int32_t _interval_ms);

View File

@ -834,7 +834,7 @@ bool Gnss_Sdr_Supl_Client::load_gal_almanac_xml(const std::string& file_name)
} }
catch (std::exception& e) 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); return this->read_gal_almanac_from_gsa(file_name);
} }
LOG(INFO) << "Loaded Galileo almanac map data with " << this->gal_almanac_map.size() << " satellites"; LOG(INFO) << "Loaded Galileo almanac map data with " << this->gal_almanac_map.size() << " satellites";

View File

@ -4,14 +4,18 @@
# SPDX-FileCopyrightText: 2010-2020 C. Fernandez-Prades cfernandez(at)cttc.es # SPDX-FileCopyrightText: 2010-2020 C. Fernandez-Prades cfernandez(at)cttc.es
# SPDX-License-Identifier: BSD-3-Clause # SPDX-License-Identifier: BSD-3-Clause
file(GLOB ASN_RRLP_SOURCES "${CMAKE_SOURCE_DIR}/src/core/libs/supl/asn-rrlp/*.c") file(GLOB ASN_RRLP_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/asn-rrlp/*.c")
list(SORT ASN_RRLP_SOURCES) list(SORT ASN_RRLP_SOURCES)
file(GLOB ASN_RRLP_HEADERS "${CMAKE_SOURCE_DIR}/src/core/libs/supl/asn-rrlp/*.h") file(GLOB ASN_RRLP_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/asn-rrlp/*.h")
list(SORT ASN_RRLP_HEADERS) list(SORT ASN_RRLP_HEADERS)
file(GLOB ASN_SUPL_SOURCES "${CMAKE_SOURCE_DIR}/src/core/libs/supl/asn-supl/*.c") file(GLOB ASN_SUPL_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/asn-supl/*.c")
list(SORT ASN_SUPL_SOURCES) list(SORT ASN_SUPL_SOURCES)
file(GLOB ASN_SUPL_HEADERS "${CMAKE_SOURCE_DIR}/src/core/libs/supl/asn-supl/*.h") file(GLOB ASN_SUPL_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/asn-supl/*.h")
list(SORT ASN_SUPL_HEADERS) list(SORT ASN_SUPL_HEADERS)
file(GLOB ASN_TYPES_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/types/*.c")
list(SORT ASN_TYPES_SOURCES)
file(GLOB ASN_TYPES_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/types/*.h")
list(SORT ASN_TYPES_HEADERS)
if(USE_CMAKE_TARGET_SOURCES) if(USE_CMAKE_TARGET_SOURCES)
add_library(core_libs_supl STATIC) add_library(core_libs_supl STATIC)
@ -19,8 +23,10 @@ if(USE_CMAKE_TARGET_SOURCES)
PRIVATE PRIVATE
${ASN_RRLP_SOURCES} ${ASN_RRLP_SOURCES}
${ASN_SUPL_SOURCES} ${ASN_SUPL_SOURCES}
${ASN_TYPES_SOURCES}
${ASN_RRLP_HEADERS} ${ASN_RRLP_HEADERS}
${ASN_SUPL_HEADERS} ${ASN_SUPL_HEADERS}
${ASN_TYPES_HEADERS}
${CMAKE_CURRENT_LIST_DIR}/supl.c ${CMAKE_CURRENT_LIST_DIR}/supl.c
PUBLIC PUBLIC
${CMAKE_CURRENT_LIST_DIR}/supl.h ${CMAKE_CURRENT_LIST_DIR}/supl.h
@ -30,6 +36,7 @@ else()
STATIC STATIC
${ASN_RRLP_SOURCES} ${ASN_RRLP_SOURCES}
${ASN_SUPL_SOURCES} ${ASN_SUPL_SOURCES}
${ASN_TYPES_SOURCES}
supl.c supl.c
) )
endif() endif()
@ -53,11 +60,20 @@ target_include_directories(core_libs_supl
PUBLIC PUBLIC
${GNUTLS_INCLUDE_DIR} ${GNUTLS_INCLUDE_DIR}
${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_SOURCE_DIR}/src/core/libs/supl/asn-supl ${CMAKE_CURRENT_SOURCE_DIR}/asn-supl
${CMAKE_SOURCE_DIR}/src/core/libs/supl/asn-rrlp ${CMAKE_CURRENT_SOURCE_DIR}/asn-rrlp
${CMAKE_CURRENT_SOURCE_DIR}/types
) )
set_target_properties(core_libs_supl PROPERTIES set_property(TARGET core_libs_supl
LINKER_LANGUAGE C APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR};${CMAKE_SOURCE_DIR}/src/core/libs/supl/asn-supl;${CMAKE_SOURCE_DIR}/src/core/libs/supl/asn-rrlp;${GNUTLS_INCLUDE_DIR}" $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/asn-supl>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/asn-rrlp>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/types>
$<BUILD_INTERFACE:${GNUTLS_INCLUDE_DIR}>
)
set_property(TARGET core_libs_supl
APPEND PROPERTY LINKER_LANGUAGE C
) )

File diff suppressed because it is too large Load Diff

View File

@ -1,74 +0,0 @@
/*-
* SPDX-FileCopyrightText: (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
* SPDX-License-Identifier: BSD-1-Clause
*/
#ifndef _INTEGER_H
#define _INTEGER_H
#include <asn_application.h>
#include <asn_codecs_prim.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C"
{
#endif
typedef ASN__PRIMITIVE_TYPE_t INTEGER_t;
extern asn_TYPE_descriptor_t asn_DEF_INTEGER;
/* Map with <tag> to integer value association */
typedef struct asn_INTEGER_enum_map_s
{
int64_t nat_value; /* associated native integer value */
size_t enum_len; /* strlen("tag") */
const char *enum_name; /* "tag" */
} asn_INTEGER_enum_map_t;
/* This type describes an enumeration for INTEGER and ENUMERATED types */
typedef struct asn_INTEGER_specifics_s
{
asn_INTEGER_enum_map_t *value2enum; /* N -> "tag"; sorted by N */
unsigned int *enum2value; /* "tag" => N; sorted by tag */
int map_count; /* Elements in either map */
int extension; /* This map is extensible */
int strict_enumeration; /* Enumeration set is fixed */
int field_width; /* Size of native integer */
int field_unsigned; /* Signed=0, unsigned=1 */
} asn_INTEGER_specifics_t;
asn_struct_print_f INTEGER_print;
ber_type_decoder_f INTEGER_decode_ber;
der_type_encoder_f INTEGER_encode_der;
xer_type_decoder_f INTEGER_decode_xer;
xer_type_encoder_f INTEGER_encode_xer;
per_type_decoder_f INTEGER_decode_uper;
per_type_encoder_f INTEGER_encode_uper;
/***********************************
* Some handy conversion routines. *
***********************************/
/*
* Returns 0 if it was possible to convert, -1 otherwise.
* -1/EINVAL: Mandatory argument missing
* -1/ERANGE: Value encoded is out of range for long representation
* -1/ENOMEM: Memory allocation failed (in asn_long2INTEGER()).
*/
int asn_INTEGER2long(const INTEGER_t *i, int64_t *l);
int asn_INTEGER2ulong(const INTEGER_t *i, uint64_t *l);
int asn_long2INTEGER(INTEGER_t *i, int64_t l);
int asn_ulong2INTEGER(INTEGER_t *i, uint64_t l);
/*
* Convert the integer value into the corresponding enumeration map entry.
*/
const asn_INTEGER_enum_map_t *INTEGER_map_value2enum(
asn_INTEGER_specifics_t *specs, int64_t value);
#ifdef __cplusplus
}
#endif
#endif /* _INTEGER_H_ */

View File

@ -1,377 +0,0 @@
/*-
* SPDX-FileCopyrightText: (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
* SPDX-License-Identifier: BSD-1-Clause
*/
/*
* Read the NativeInteger.h for the explanation wrt. differences between
* INTEGER and NativeInteger.
* Basically, both are decoders and encoders of ASN.1 INTEGER type, but this
* implementation deals with the standard (machine-specific) representation
* of them instead of using the platform-independent buffer.
*/
#include <NativeInteger.h>
#include <asn_internal.h>
/*
* NativeInteger basic type description.
*/
static ber_tlv_tag_t asn_DEF_NativeInteger_tags[] = {
(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))};
asn_TYPE_descriptor_t asn_DEF_NativeInteger = {
"INTEGER", /* The ASN.1 type is still INTEGER */
"INTEGER",
NativeInteger_free,
NativeInteger_print,
asn_generic_no_constraint,
NativeInteger_decode_ber,
NativeInteger_encode_der,
NativeInteger_decode_xer,
NativeInteger_encode_xer,
NativeInteger_decode_uper, /* Unaligned PER decoder */
NativeInteger_encode_uper, /* Unaligned PER encoder */
0, /* Use generic outmost tag fetcher */
asn_DEF_NativeInteger_tags,
sizeof(asn_DEF_NativeInteger_tags) / sizeof(asn_DEF_NativeInteger_tags[0]),
asn_DEF_NativeInteger_tags, /* Same as above */
sizeof(asn_DEF_NativeInteger_tags) / sizeof(asn_DEF_NativeInteger_tags[0]),
0, /* No PER visible constraints */
0,
0, /* No members */
0 /* No specifics */
};
/*
* Decode INTEGER type.
*/
asn_dec_rval_t NativeInteger_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
asn_TYPE_descriptor_t *td,
void **nint_ptr, const void *buf_ptr,
size_t size, int tag_mode)
{
asn_INTEGER_specifics_t *specs = (asn_INTEGER_specifics_t *)td->specifics;
long *native = (long *)*nint_ptr;
asn_dec_rval_t rval;
ber_tlv_len_t length;
/*
* If the structure is not there, allocate it.
*/
if (native == NULL)
{
native = (long *)(*nint_ptr = CALLOC(1, sizeof(*native)));
if (native == NULL)
{
rval.code = RC_FAIL;
rval.consumed = 0;
return rval;
}
}
ASN_DEBUG("Decoding %s as INTEGER (tm=%d)", td->name, tag_mode);
/*
* Check tags.
*/
rval = ber_check_tags(opt_codec_ctx, td, 0, buf_ptr, size, tag_mode, 0,
&length, 0);
if (rval.code != RC_OK)
{
return rval;
}
ASN_DEBUG("%s length is %d bytes", td->name, (int)length);
/*
* Make sure we have this length.
*/
buf_ptr = ((const char *)buf_ptr) + rval.consumed;
size -= rval.consumed;
if (length > (ber_tlv_len_t)size)
{
rval.code = RC_WMORE;
rval.consumed = 0;
return rval;
}
/*
* ASN.1 encoded INTEGER: buf_ptr, length
* Fill the native, at the same time checking for overflow.
* If overflow occurred, return with RC_FAIL.
*/
{
INTEGER_t tmp;
union
{
const void *constbuf;
void *nonconstbuf;
} unconst_buf;
int64_t l;
unconst_buf.constbuf = buf_ptr;
tmp.buf = (uint8_t *)unconst_buf.nonconstbuf;
tmp.size = length;
if ((specs && specs->field_unsigned)
? asn_INTEGER2ulong(&tmp, (uint64_t *)&l)
: asn_INTEGER2long(&tmp, &l))
{
rval.code = RC_FAIL;
rval.consumed = 0;
return rval;
}
*native = l;
}
rval.code = RC_OK;
rval.consumed += length;
ASN_DEBUG("Took %ld/%ld bytes to encode %s (%ld)", (long)rval.consumed,
(long)length, td->name, *native);
return rval;
}
// clang-format off
/*
* Encode the NativeInteger using the standard INTEGER type DER encoder.
*/
asn_enc_rval_t NativeInteger_encode_der(asn_TYPE_descriptor_t *sd, void *ptr,
int tag_mode, ber_tlv_tag_t tag,
asn_app_consume_bytes_f *cb,
void *app_key)
{
uint64_t native = *(uint64_t *)ptr; /* Disable sign ext. */
asn_enc_rval_t erval;
INTEGER_t tmp;
#ifdef WORDS_BIGENDIAN /* Opportunistic optimization */
tmp.buf = (uint8_t *)&native;
tmp.size = sizeof(native);
#else /* Works even if WORDS_BIGENDIAN is not set where should've been */
uint8_t buf[sizeof(native)];
uint8_t *p;
/* Prepare a fake INTEGER */
for (p = buf + sizeof(buf) - 1; p >= buf; p--, native >>= 8)
{
*p = (uint8_t)native;
}
tmp.buf = buf;
tmp.size = sizeof(buf);
#endif /* WORDS_BIGENDIAN */
/* Encode fake INTEGER */
erval = INTEGER_encode_der(sd, &tmp, tag_mode, tag, cb, app_key);
if (erval.encoded == -1)
{
assert(erval.structure_ptr == &tmp);
erval.structure_ptr = ptr;
}
return erval;
}
// clang-format on
/*
* Decode the chunk of XML text encoding INTEGER.
*/
asn_dec_rval_t NativeInteger_decode_xer(asn_codec_ctx_t *opt_codec_ctx,
asn_TYPE_descriptor_t *td, void **sptr,
const char *opt_mname,
const void *buf_ptr, size_t size)
{
asn_INTEGER_specifics_t *specs = (asn_INTEGER_specifics_t *)td->specifics;
asn_dec_rval_t rval;
INTEGER_t st;
void *st_ptr = (void *)&st;
long *native = (long *)*sptr;
if (!native)
{
native = (long *)(*sptr = CALLOC(1, sizeof(*native)));
if (!native)
{
_ASN_DECODE_FAILED;
}
}
memset(&st, 0, sizeof(st));
rval = INTEGER_decode_xer(opt_codec_ctx, td, &st_ptr, opt_mname, buf_ptr,
size);
if (rval.code == RC_OK)
{
int64_t l;
if ((specs && specs->field_unsigned)
? asn_INTEGER2ulong(&st, (uint64_t *)&l)
: asn_INTEGER2long(&st, &l))
{
rval.code = RC_FAIL;
rval.consumed = 0;
}
else
{
*native = l;
}
}
else
{
/*
* Cannot restart from the middle;
* there is no place to save state in the native type.
* Request a continuation from the very beginning.
*/
rval.consumed = 0;
}
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &st);
return rval;
}
asn_enc_rval_t NativeInteger_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
int ilevel,
enum xer_encoder_flags_e flags,
asn_app_consume_bytes_f *cb,
void *app_key)
{
asn_INTEGER_specifics_t *specs = (asn_INTEGER_specifics_t *)td->specifics;
char scratch[32]; /* Enough for 64-bit int */
asn_enc_rval_t er;
const long *native = (const long *)sptr;
(void)ilevel;
(void)flags;
if (!native)
{
_ASN_ENCODE_FAILED;
}
er.encoded =
snprintf(scratch, sizeof(scratch),
(specs && specs->field_unsigned) ? "%lu" : "%ld", *native);
if (er.encoded <= 0 || (size_t)er.encoded >= sizeof(scratch) ||
cb(scratch, er.encoded, app_key) < 0)
{
_ASN_ENCODE_FAILED;
}
_ASN_ENCODED_OK(er);
}
asn_dec_rval_t NativeInteger_decode_uper(asn_codec_ctx_t *opt_codec_ctx,
asn_TYPE_descriptor_t *td,
asn_per_constraints_t *constraints,
void **sptr, asn_per_data_t *pd)
{
asn_INTEGER_specifics_t *specs = (asn_INTEGER_specifics_t *)td->specifics;
asn_dec_rval_t rval;
int64_t *native = (int64_t *)*sptr;
INTEGER_t tmpint;
void *tmpintptr = &tmpint;
(void)opt_codec_ctx;
ASN_DEBUG("Decoding NativeInteger %s (UPER)", td->name);
if (!native)
{
native = (int64_t *)(*sptr = CALLOC(1, sizeof(*native)));
if (!native)
{
_ASN_DECODE_FAILED;
}
}
memset(&tmpint, 0, sizeof tmpint);
rval = INTEGER_decode_uper(opt_codec_ctx, td, constraints, &tmpintptr, pd);
if (rval.code == RC_OK)
{
if ((specs && specs->field_unsigned)
? asn_INTEGER2ulong(&tmpint, (uint64_t *)native)
: asn_INTEGER2long(&tmpint, native))
{
rval.code = RC_FAIL;
}
else
{
ASN_DEBUG("NativeInteger %s got value %ld", td->name, *native);
}
}
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &tmpint);
return rval;
}
asn_enc_rval_t NativeInteger_encode_uper(asn_TYPE_descriptor_t *td,
asn_per_constraints_t *constraints,
void *sptr, asn_per_outp_t *po)
{
asn_INTEGER_specifics_t *specs = (asn_INTEGER_specifics_t *)td->specifics;
asn_enc_rval_t er;
long native;
INTEGER_t tmpint;
if (!sptr)
{
_ASN_ENCODE_FAILED;
}
native = *(long *)sptr;
ASN_DEBUG("Encoding NativeInteger %s %ld (UPER)", td->name, native);
memset(&tmpint, 0, sizeof(tmpint));
if ((specs && specs->field_unsigned) ? asn_ulong2INTEGER(&tmpint, native)
: asn_long2INTEGER(&tmpint, native))
{
_ASN_ENCODE_FAILED;
}
er = INTEGER_encode_uper(td, constraints, &tmpint, po);
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &tmpint);
return er;
}
/*
* INTEGER specific human-readable output.
*/
int NativeInteger_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
asn_app_consume_bytes_f *cb, void *app_key)
{
asn_INTEGER_specifics_t *specs = (asn_INTEGER_specifics_t *)td->specifics;
const long *native = (const long *)sptr;
char scratch[32]; /* Enough for 64-bit int */
int ret;
(void)td; /* Unused argument */
(void)ilevel; /* Unused argument */
if (native)
{
ret = snprintf(scratch, sizeof(scratch),
(specs && specs->field_unsigned) ? "%lu" : "%ld",
*native);
assert(ret > 0 && (size_t)ret < sizeof(scratch));
return (cb(scratch, ret, app_key) < 0) ? -1 : 0;
}
else
{
return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
}
}
void NativeInteger_free(asn_TYPE_descriptor_t *td, void *ptr, int contents_only)
{
if (!td || !ptr)
{
return;
}
ASN_DEBUG("Freeing %s as INTEGER (%d, %p, Native)", td->name, contents_only,
ptr);
if (!contents_only)
{
FREEMEM(ptr);
}
}

View File

@ -1,90 +0,0 @@
/*-
* SPDX-FileCopyrightText: (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
* SPDX-License-Identifier: BSD-1-Clause
*/
#ifndef _OCTET_STRING_H
#define _OCTET_STRING_H
#include <asn_application.h>
#ifdef __cplusplus
extern "C"
{
#endif
typedef struct OCTET_STRING
{
uint8_t *buf; /* Buffer with consecutive OCTET_STRING bits */
int size; /* Size of the buffer */
asn_struct_ctx_t _asn_ctx; /* Parsing across buffer boundaries */
} OCTET_STRING_t;
extern asn_TYPE_descriptor_t asn_DEF_OCTET_STRING;
asn_struct_free_f OCTET_STRING_free;
asn_struct_print_f OCTET_STRING_print;
asn_struct_print_f OCTET_STRING_print_utf8;
ber_type_decoder_f OCTET_STRING_decode_ber;
der_type_encoder_f OCTET_STRING_encode_der;
xer_type_decoder_f OCTET_STRING_decode_xer_hex; /* Hexadecimal */
xer_type_decoder_f OCTET_STRING_decode_xer_binary; /* 01010111010 */
xer_type_decoder_f OCTET_STRING_decode_xer_utf8; /* ASCII/UTF-8 */
xer_type_encoder_f OCTET_STRING_encode_xer;
xer_type_encoder_f OCTET_STRING_encode_xer_utf8;
per_type_decoder_f OCTET_STRING_decode_uper;
per_type_encoder_f OCTET_STRING_encode_uper;
/******************************
* Handy conversion routines. *
******************************/
/*
* This function clears the previous value of the OCTET STRING (if any)
* and then allocates a new memory with the specified content (str/size).
* If size = -1, the size of the original string will be determined
* using strlen(str).
* If str equals to NULL, the function will silently clear the
* current contents of the OCTET STRING.
* Returns 0 if it was possible to perform operation, -1 otherwise.
*/
int OCTET_STRING_fromBuf(OCTET_STRING_t *s, const char *str, int size);
/* Handy conversion from the C string into the OCTET STRING. */
#define OCTET_STRING_fromString(s, str) OCTET_STRING_fromBuf(s, str, -1)
/*
* Allocate and fill the new OCTET STRING and return a pointer to the newly
* allocated object. NULL is permitted in str: the function will just
* allocate empty OCTET STRING.
*/
OCTET_STRING_t *OCTET_STRING_new_fromBuf(asn_TYPE_descriptor_t *td,
const char *str, int size);
/****************************
* Internally useful stuff. *
****************************/
typedef struct asn_OCTET_STRING_specifics_s
{
/*
* Target structure description.
*/
int struct_size; /* Size of the structure */
int ctx_offset; /* Offset of the asn_struct_ctx_t member */
enum asn_OS_Subvariant
{
ASN_OSUBV_ANY, /* The open type (ANY) */
ASN_OSUBV_BIT, /* BIT STRING */
ASN_OSUBV_STR, /* String types, not {BMP,Universal}String */
ASN_OSUBV_U16, /* 16-bit character (BMPString) */
ASN_OSUBV_U32 /* 32-bit character (UniversalString) */
} subvariant;
} asn_OCTET_STRING_specifics_t;
#ifdef __cplusplus
}
#endif
#endif /* _OCTET_STRING_H_ */

View File

@ -1,54 +0,0 @@
/*-
* SPDX-FileCopyrightText: (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
* SPDX-License-Identifier: BSD-1-Clause
*/
#ifndef ASN_CODECS_PRIM_H
#define ASN_CODECS_PRIM_H
#include <asn_application.h>
#ifdef __cplusplus
extern "C"
{
#endif
typedef struct ASN__PRIMITIVE_TYPE_s
{
uint8_t *buf; /* Buffer with consecutive primitive encoding bytes */
int size; /* Size of the buffer */
} ASN__PRIMITIVE_TYPE_t; /* Do not use this type directly! */
asn_struct_free_f ASN__PRIMITIVE_TYPE_free;
ber_type_decoder_f ber_decode_primitive;
der_type_encoder_f der_encode_primitive;
/*
* A callback specification for the xer_decode_primitive() function below.
*/
enum xer_pbd_rval
{
XPBD_SYSTEM_FAILURE, /* System failure (memory shortage, etc) */
XPBD_DECODER_LIMIT, /* Hit some decoder limitation or deficiency */
XPBD_BROKEN_ENCODING, /* Encoding of a primitive body is broken */
XPBD_NOT_BODY_IGNORE, /* Not a body format, but safe to ignore */
XPBD_BODY_CONSUMED /* Body is recognized and consumed */
};
typedef enum xer_pbd_rval(xer_primitive_body_decoder_f)(
asn_TYPE_descriptor_t *td, void *struct_ptr, const void *chunk_buf,
size_t chunk_size);
/*
* Specific function to decode simple primitive types.
* Also see xer_decode_general() in xer_decoder.h
*/
asn_dec_rval_t xer_decode_primitive(
asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *type_descriptor,
void **struct_ptr, size_t struct_size, const char *opt_mname,
const void *buf_ptr, size_t size,
xer_primitive_body_decoder_f *prim_body_decoder);
#ifdef __cplusplus
}
#endif
#endif /* ASN_CODECS_PRIM_H */

View File

@ -1,65 +0,0 @@
/*-
* SPDX-FileCopyrightText: (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
* SPDX-License-Identifier: BSD-1-Clause
*/
#ifndef _BER_DECODER_H
#define _BER_DECODER_H
#include <asn_application.h>
#ifdef __cplusplus
extern "C"
{
#endif
struct asn_TYPE_descriptor_s; /* Forward declaration */
struct asn_codec_ctx_s; /* Forward declaration */
/*
* The BER decoder of any type.
* This function may be invoked directly from the application.
* The der_encode() function (der_encoder.h) is an opposite to ber_decode().
*/
asn_dec_rval_t ber_decode(
struct asn_codec_ctx_s *opt_codec_ctx,
struct asn_TYPE_descriptor_s *type_descriptor,
void **struct_ptr, /* Pointer to a target structure's pointer */
const void *buffer, /* Data to be decoded */
size_t size /* Size of that buffer */
);
/*
* Type of generic function which decodes the byte stream into the
* structure.
*/
typedef asn_dec_rval_t(ber_type_decoder_f)(
struct asn_codec_ctx_s *opt_codec_ctx,
struct asn_TYPE_descriptor_s *type_descriptor, void **struct_ptr,
const void *buf_ptr, size_t size, int tag_mode);
/*******************************
* INTERNALLY USEFUL FUNCTIONS *
*******************************/
/*
* Check that all tags correspond to the type definition (as given in head).
* On return, last_length would contain either a non-negative length of the
* value part of the last TLV, or the negative number of expected
* "end of content" sequences. The number may only be negative if the
* head->last_tag_form is non-zero.
*/
asn_dec_rval_t ber_check_tags(
struct asn_codec_ctx_s *opt_codec_ctx, /* codec options */
struct asn_TYPE_descriptor_s *type_descriptor,
asn_struct_ctx_t *opt_ctx, /* saved decoding context */
const void *ptr, size_t size,
int tag_mode, /* {-1,0,1}: IMPLICIT, no, EXPLICIT */
int last_tag_form, /* {-1,0:1}: any, primitive, constr */
ber_tlv_len_t *last_length, int *opt_tlv_form /* optional tag form */
);
#ifdef __cplusplus
}
#endif
#endif /* _BER_DECODER_H_ */

View File

@ -1,63 +0,0 @@
/*-
* SPDX-FileCopyrightText: (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
* SPDX-License-Identifier: BSD-1-Clause
*/
#ifndef _BER_TLV_TAG_H
#define _BER_TLV_TAG_H
#ifdef __cplusplus
extern "C"
{
#endif
enum asn_tag_class
{
ASN_TAG_CLASS_UNIVERSAL = 0, /* 0b00 */
ASN_TAG_CLASS_APPLICATION = 1, /* 0b01 */
ASN_TAG_CLASS_CONTEXT = 2, /* 0b10 */
ASN_TAG_CLASS_PRIVATE = 3 /* 0b11 */
};
typedef unsigned ber_tlv_tag_t; /* BER TAG from Tag-Length-Value */
/*
* Tag class is encoded together with tag value for optimization purposes.
*/
#define BER_TAG_CLASS(tag) ((tag)&0x3)
#define BER_TAG_VALUE(tag) ((tag) >> 2)
#define BER_TLV_CONSTRUCTED(tagptr) \
(((*(const uint8_t *)tagptr) & 0x20) ? 1 : 0)
#define BER_TAGS_EQUAL(tag1, tag2) ((tag1) == (tag2))
/*
* Several functions for printing the TAG in the canonical form
* (i.e. "[PRIVATE 0]").
* Return values correspond to their libc counterparts (if any).
*/
ssize_t ber_tlv_tag_snprint(ber_tlv_tag_t tag, char *buf, size_t buflen);
ssize_t ber_tlv_tag_fwrite(ber_tlv_tag_t tag, FILE *);
char *ber_tlv_tag_string(ber_tlv_tag_t tag);
/*
* This function tries to fetch the tag from the input stream.
* RETURN VALUES:
* 0: More data expected than bufptr contains.
* -1: Fatal error deciphering tag.
* >0: Number of bytes used from bufptr. tag_r will contain the tag.
*/
ssize_t ber_fetch_tag(const void *bufptr, size_t size,
ber_tlv_tag_t *tag_r);
/*
* This function serializes the tag (T from TLV) in BER format.
* It always returns number of bytes necessary to represent the tag,
* it is a caller's responsibility to check the return value
* against the supplied buffer's size.
*/
size_t ber_tlv_tag_serialize(ber_tlv_tag_t tag, void *bufptr, size_t size);
#ifdef __cplusplus
}
#endif
#endif /* _BER_TLV_TAG_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -1,108 +0,0 @@
/*-
* SPDX-FileCopyrightText: (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
* SPDX-License-Identifier: BSD-1-Clause
*/
// clang-format off
#include "asn_internal.h"
#include "constraints.h"
// clang-format on
int asn_generic_no_constraint(asn_TYPE_descriptor_t *type_descriptor,
const void *struct_ptr,
asn_app_constraint_failed_f *cb, void *key)
{
(void)type_descriptor; /* Unused argument */
(void)struct_ptr; /* Unused argument */
(void)cb; /* Unused argument */
(void)key; /* Unused argument */
/* Nothing to check */
return 0;
}
int asn_generic_unknown_constraint(asn_TYPE_descriptor_t *type_descriptor,
const void *struct_ptr,
asn_app_constraint_failed_f *cb, void *key)
{
(void)type_descriptor; /* Unused argument */
(void)struct_ptr; /* Unused argument */
(void)cb; /* Unused argument */
(void)key; /* Unused argument */
/* Unknown how to check */
return 0;
}
struct errbufDesc
{
asn_TYPE_descriptor_t *failed_type;
const void *failed_struct_ptr;
char *errbuf;
size_t errlen;
};
static void asn_i_ctfailcb(void *key, asn_TYPE_descriptor_t *td,
const void *sptr, const char *fmt, ...)
{
struct errbufDesc *arg = key;
va_list ap;
ssize_t vlen;
ssize_t maxlen;
arg->failed_type = td;
arg->failed_struct_ptr = sptr;
maxlen = arg->errlen;
if (maxlen <= 0)
{
return;
}
va_start(ap, fmt);
vlen = vsnprintf(arg->errbuf, maxlen, fmt, ap);
va_end(ap);
if (vlen >= maxlen)
{
arg->errbuf[maxlen - 1] = '\0'; /* Ensuring libc correctness */
arg->errlen = maxlen - 1; /* Not counting termination */
return;
}
else if (vlen >= 0)
{
arg->errbuf[vlen] = '\0'; /* Ensuring libc correctness */
arg->errlen = vlen; /* Not counting termination */
}
else
{
/*
* The libc on this system is broken.
*/
vlen = sizeof("<broken vsnprintf>") - 1;
maxlen--;
arg->errlen = vlen < maxlen ? vlen : maxlen;
memcpy(arg->errbuf, "<broken vsnprintf>", arg->errlen);
arg->errbuf[arg->errlen] = 0;
}
}
int asn_check_constraints(asn_TYPE_descriptor_t *type_descriptor,
const void *struct_ptr, char *errbuf, size_t *errlen)
{
struct errbufDesc arg;
int ret;
arg.failed_type = 0;
arg.failed_struct_ptr = 0;
arg.errbuf = errbuf;
arg.errlen = errlen ? *errlen : 0;
ret = type_descriptor->check_constraints(type_descriptor, struct_ptr,
asn_i_ctfailcb, &arg);
if (ret == -1 && errlen)
{
*errlen = arg.errlen;
}
return ret;
}

View File

@ -1,67 +0,0 @@
/*-
* SPDX-FileCopyrightText: (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
* SPDX-License-Identifier: BSD-1-Clause
*/
#ifndef _DER_ENCODER_H
#define _DER_ENCODER_H
#include <asn_application.h>
#ifdef __cplusplus
extern "C"
{
#endif
struct asn_TYPE_descriptor_s; /* Forward declaration */
/*
* The DER encoder of any type. May be invoked by the application.
* The ber_decode() function (ber_decoder.h) is an opposite of der_encode().
*/
asn_enc_rval_t der_encode(struct asn_TYPE_descriptor_s *type_descriptor,
void *struct_ptr, /* Structure to be encoded */
asn_app_consume_bytes_f *consume_bytes_cb,
void *app_key /* Arbitrary callback argument */
);
/* A variant of der_encode() which encodes data into the pre-allocated
* buffer */
asn_enc_rval_t der_encode_to_buffer(
struct asn_TYPE_descriptor_s *type_descriptor,
void *struct_ptr, /* Structure to be encoded */
void *buffer, /* Pre-allocated buffer */
size_t buffer_size /* Initial buffer size (maximum) */
);
/*
* Type of the generic DER encoder.
*/
typedef asn_enc_rval_t(der_type_encoder_f)(
struct asn_TYPE_descriptor_s *type_descriptor,
void *struct_ptr, /* Structure to be encoded */
int tag_mode, /* {-1,0,1}: IMPLICIT, no, EXPLICIT */
ber_tlv_tag_t tag,
asn_app_consume_bytes_f *consume_bytes_cb, /* Callback */
void *app_key /* Arbitrary callback argument */
);
/*******************************
* INTERNALLY USEFUL FUNCTIONS *
*******************************/
/*
* Write out leading TL[v] sequence according to the type definition.
*/
ssize_t der_write_tags(struct asn_TYPE_descriptor_s *type_descriptor,
size_t struct_length,
int tag_mode, /* {-1,0,1}: IMPLICIT, no, EXPLICIT */
int last_tag_form, /* {0,!0}: prim, constructed */
ber_tlv_tag_t tag,
asn_app_consume_bytes_f *consume_bytes_cb,
void *app_key);
#ifdef __cplusplus
}
#endif
#endif /* _DER_ENCODER_H_ */

View File

@ -1,59 +0,0 @@
/*-
* SPDX-FileCopyrightText: (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
* SPDX-License-Identifier: BSD-1-Clause
*/
#ifndef _PER_DECODER_H
#define _PER_DECODER_H
#include <asn_application.h>
#include <per_support.h>
#ifdef __cplusplus
extern "C"
{
#endif
struct asn_TYPE_descriptor_s; /* Forward declaration */
/*
* Unaligned PER decoder of a "complete encoding" as per X.691#10.1.
* On success, this call always returns (.consumed >= 1), as per
* X.691#10.1.3.
*/
asn_dec_rval_t uper_decode_complete(
struct asn_codec_ctx_s *opt_codec_ctx,
struct asn_TYPE_descriptor_s *type_descriptor, /* Type to decode */
void **struct_ptr, /* Pointer to a target structure's pointer */
const void *buffer, /* Data to be decoded */
size_t size /* Size of data buffer */
);
/*
* Unaligned PER decoder of any ASN.1 type. May be invoked by the
* application. WARNING: This call returns the number of BITS read from the
* stream. Beware.
*/
asn_dec_rval_t uper_decode(
struct asn_codec_ctx_s *opt_codec_ctx,
struct asn_TYPE_descriptor_s *type_descriptor, /* Type to decode */
void **struct_ptr, /* Pointer to a target structure's pointer */
const void *buffer, /* Data to be decoded */
size_t size, /* Size of data buffer */
int skip_bits, /* Number of unused leading bits, 0..7 */
int unused_bits /* Number of unused tailing bits, 0..7 */
);
/*
* Type of the type-specific PER decoder function.
*/
typedef asn_dec_rval_t(per_type_decoder_f)(
asn_codec_ctx_t *opt_codec_ctx,
struct asn_TYPE_descriptor_s *type_descriptor,
asn_per_constraints_t *constraints, void **struct_ptr,
asn_per_data_t *per_data);
#ifdef __cplusplus
}
#endif
#endif /* _PER_DECODER_H_ */

View File

@ -1,69 +0,0 @@
/*-
* SPDX-FileCopyrightText: (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
* SPDX-License-Identifier: BSD-1-Clause
*/
#ifndef _PER_ENCODER_H
#define _PER_ENCODER_H
#include <asn_application.h>
#include <per_support.h>
#ifdef __cplusplus
extern "C"
{
#endif
struct asn_TYPE_descriptor_s; /* Forward declaration */
/*
* Unaligned PER encoder of any ASN.1 type. May be invoked by the
* application. WARNING: This function returns the number of encoded bits in
* the .encoded field of the return value. Use the following formula to
* convert to bytes: bytes = ((.encoded + 7) / 8)
*/
asn_enc_rval_t uper_encode(
struct asn_TYPE_descriptor_s *type_descriptor,
void *struct_ptr, /* Structure to be encoded */
asn_app_consume_bytes_f *consume_bytes_cb, /* Data collector */
void *app_key /* Arbitrary callback argument */
);
/*
* A variant of uper_encode() which encodes data into the existing buffer
* WARNING: This function returns the number of encoded bits in the .encoded
* field of the return value.
*/
asn_enc_rval_t uper_encode_to_buffer(
struct asn_TYPE_descriptor_s *type_descriptor,
void *struct_ptr, /* Structure to be encoded */
void *buffer, /* Pre-allocated buffer */
size_t buffer_size /* Initial buffer size (max) */
);
/*
* A variant of uper_encode_to_buffer() which allocates buffer itself.
* Returns the number of bytes in the buffer or -1 in case of failure.
* WARNING: This function produces a "Production of the complete encoding",
* with length of at least one octet. Contrast this to precise bit-packing
* encoding of uper_encode() and uper_encode_to_buffer().
*/
ssize_t uper_encode_to_new_buffer(
struct asn_TYPE_descriptor_s *type_descriptor,
asn_per_constraints_t *constraints,
void *struct_ptr, /* Structure to be encoded */
void **buffer_r /* Buffer allocated and returned */
);
/*
* Type of the generic PER encoder function.
*/
typedef asn_enc_rval_t(per_type_encoder_f)(
struct asn_TYPE_descriptor_s *type_descriptor,
asn_per_constraints_t *constraints, void *struct_ptr,
asn_per_outp_t *per_output);
#ifdef __cplusplus
}
#endif
#endif /* _PER_ENCODER_H_ */

View File

@ -1,150 +0,0 @@
/*
* SPDX-FileCopyrightText: (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
* SPDX-License-Identifier: BSD-1-Clause
*/
#ifndef _PER_SUPPORT_H
#define _PER_SUPPORT_H
#include <asn_system.h> /* Platform-specific types */
#ifdef __cplusplus
extern "C"
{
#endif
/*
* Pre-computed PER constraints.
*/
typedef const struct asn_per_constraint_s
{
enum asn_per_constraint_flags
{
APC_UNCONSTRAINED = 0x0, /* No PER visible constraints */
APC_SEMI_CONSTRAINED = 0x1, /* Constrained at "lb" */
APC_CONSTRAINED = 0x2, /* Fully constrained */
APC_EXTENSIBLE = 0x4 /* May have extension */
} flags;
int range_bits; /* Full number of bits in the range */
int effective_bits; /* Effective bits */
long lower_bound; /* "lb" value */
long upper_bound; /* "ub" value */
} asn_per_constraint_t;
typedef const struct asn_per_constraints_s
{
struct asn_per_constraint_s value;
struct asn_per_constraint_s size;
int (*value2code)(unsigned int value);
int (*code2value)(unsigned int code);
} asn_per_constraints_t;
/*
* This structure describes a position inside an incoming PER bit stream.
*/
typedef struct asn_per_data_s
{
const uint8_t *buffer; /* Pointer to the octet stream */
size_t nboff; /* Bit offset to the meaningful bit */
size_t nbits; /* Number of bits in the stream */
size_t moved; /* Number of bits moved through this bit stream */
int (*refill)(struct asn_per_data_s *);
void *refill_key;
} asn_per_data_t;
/*
* Extract a small number of bits (<= 31) from the specified PER data
* pointer. This function returns -1 if the specified number of bits could
* not be extracted due to EOD or other conditions.
*/
int32_t per_get_few_bits(asn_per_data_t *per_data, int get_nbits);
/* Undo the immediately preceding "get_few_bits" operation */
void per_get_undo(asn_per_data_t *per_data, int get_nbits);
/*
* Extract a large number of bits from the specified PER data pointer.
* This function returns -1 if the specified number of bits could not be
* extracted due to EOD or other conditions.
*/
int per_get_many_bits(asn_per_data_t *pd, uint8_t *dst, int right_align,
int get_nbits);
/*
* Get the length "n" from the Unaligned PER stream.
*/
ssize_t uper_get_length(asn_per_data_t *pd, int effective_bound_bits,
int *repeat);
/*
* Get the normally small length "n".
*/
ssize_t uper_get_nslength(asn_per_data_t *pd);
/*
* Get the normally small non-negative whole number.
*/
ssize_t uper_get_nsnnwn(asn_per_data_t *pd);
/* X.691-2008/11, #11.5.6 */
int uper_get_constrained_whole_number(asn_per_data_t *pd, unsigned long *v,
int nbits);
/* Non-thread-safe debugging function, don't use it */
char *per_data_string(asn_per_data_t *pd);
/*
* This structure supports forming PER output.
*/
typedef struct asn_per_outp_s
{
uint8_t *buffer; /* Pointer into the (tmpspace) */
size_t nboff; /* Bit offset to the meaningful bit */
size_t nbits; /* Number of bits left in (tmpspace) */
uint8_t tmpspace[32]; /* Preliminary storage to hold data */
int (*outper)(const void *data, size_t size, void *op_key);
void *op_key; /* Key for (outper) data callback */
size_t flushed_bytes; /* Bytes already flushed through (outper) */
} asn_per_outp_t;
/* Output a small number of bits (<= 31) */
int per_put_few_bits(asn_per_outp_t *per_data, uint32_t bits, int obits);
/* Output a large number of bits */
int per_put_many_bits(asn_per_outp_t *po, const uint8_t *src,
int put_nbits);
/*
* Flush whole bytes (0 or more) through (outper) member.
* The least significant bits which are not used are guaranteed to be set to
* 0. Returns -1 if callback returns -1. Otherwise, 0.
*/
int per_put_aligned_flush(asn_per_outp_t *po);
/* X.691-2008/11, #11.5 */
int uper_put_constrained_whole_number_s(asn_per_outp_t *po, long v,
int nbits);
int uper_put_constrained_whole_number_u(asn_per_outp_t *po, unsigned long v,
int nbits);
/*
* Put the length "n" to the Unaligned PER stream.
* This function returns the number of units which may be flushed
* in the next units saving iteration.
*/
ssize_t uper_put_length(asn_per_outp_t *po, size_t whole_length);
/*
* Put the normally small length "n" to the Unaligned PER stream.
* Returns 0 or -1.
*/
int uper_put_nslength(asn_per_outp_t *po, size_t length);
/*
* Put the normally small non-negative whole number.
*/
int uper_put_nsnnwn(asn_per_outp_t *po, int n);
#ifdef __cplusplus
}
#endif
#endif /* _PER_SUPPORT_H_ */

Some files were not shown because too many files have changed in this diff Show More