1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-12-14 20:20:35 +00:00

Merge branch 'next' into ssr

This commit is contained in:
Carles Fernandez 2022-05-12 17:05:57 +02:00
commit 06315477c3
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
----------------------------
http://www.cttc.cat
https://www.cttc.cat
Mailing List
----------------------------
gnss-sdr-developers@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/gnss-sdr-developers
https://sourceforge.net/projects/gnss-sdr/lists/gnss-sdr-developers
Email
@ -61,7 +61,8 @@ Marc Sales marcsales92@gmail.com Contributor
Piyush Gupta piyush04111999@gmail.com Contributor
Rodrigo Muñoz rodrigo.munoz@proteinlab.cl Contributor
Stefan van der Linden spvdlinden@gmail.com Contributor
Will Silberman wsilberm@google.com Contributor
Carlos Paniego carpanie@hotmail.com Artwork
# 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
family-names: Schindehette
given-names: Josh
- alias: orlando017
email: wsilberm@google.com
family-names: Silberman
given-names: Will
- email: tonetto.dev@gmail.com
family-names: Tonetto
given-names: Leonardo
@ -101,7 +105,7 @@ authors:
family-names: "van der Linden"
given-names: Stefan
cff-version: "1.2.0"
date-released: "2022-02-15"
date-released: "2022-04-20"
identifiers:
- description: "The concept DOI of the work. This is a DOI always pointing to the latest stable release."
type: doi
@ -325,4 +329,4 @@ repository-code: "https://github.com/gnss-sdr/gnss-sdr"
title: GNSS-SDR
type: software
url: "https://gnss-sdr.org"
version: "0.0.16"
version: "0.0.17"

View File

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

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
above).
Since Ubuntu 21.04 Hirsute / Debian 11, the package `libcpu-features-dev` is
also required.
**Note for Ubuntu 14.04 LTS "trusty" users:** you will need to build from source
and install GNU Radio manually, as explained below, since GNSS-SDR requires
`gnuradio-dev` >= 3.7.3, and Ubuntu 14.04 came with 3.7.2. Install all the
@ -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 zypper install lapack-devel blas-devel # For OpenSUSE
$ sudo pacman -S blas lapack # For Arch Linux
$ wget https://sourceforge.net/projects/arma/files/armadillo-10.8.0.tar.xz
$ tar xvfz armadillo-10.8.0.tar.xz
$ cd armadillo-10.8.0
$ wget https://sourceforge.net/projects/arma/files/armadillo-11.0.1.tar.xz
$ tar xvfz armadillo-11.0.1.tar.xz
$ cd armadillo-11.0.1
$ cmake .
$ make
$ 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:
```
$ wget https://github.com/tbeu/matio/releases/download/v1.5.22/matio-1.5.22.tar.gz
$ tar xvfz matio-1.5.22.tar.gz
$ cd matio-1.5.22
$ wget https://github.com/tbeu/matio/releases/download/v1.5.23/matio-1.5.23.tar.gz
$ tar xvfz matio-1.5.23.tar.gz
$ cd matio-1.5.23
$ ./configure
$ make
$ sudo make install
@ -493,9 +496,9 @@ $ sudo apt-get install autoconf automake libtool curl make g++ unzip
and then:
```
$ wget https://github.com/protocolbuffers/protobuf/releases/download/v3.19.4/protobuf-cpp-3.19.4.tar.gz
$ tar xvfz protobuf-cpp-3.19.4.tar.gz
$ cd protobuf-3.19.4
$ wget https://github.com/protocolbuffers/protobuf/releases/download/v3.20.1/protobuf-cpp-3.20.1.tar.gz
$ tar xvfz protobuf-cpp-3.20.1.tar.gz
$ cd protobuf-3.20.1
$ ./autogen.sh
$ ./configure
$ 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.
Esteve,
[GNSS-SDR: an open source tool for researchers and developers](http://www.cttc.es/publication/gnss-sdr-an-open-source-tool-for-researchers-and-developers/),
[GNSS-SDR: an open source tool for researchers and developers](https://www.researchgate.net/publication/233380791_GNSS-SDR_An_open_source_tool_for_researchers_and_developers),
in Proceedings of the 24th International Technical Meeting of The Satellite
Division of the Institute of Navigation (ION GNSS), Portland, Oregon, Sept.
19-23, 2011, pp. 780-794.

View File

@ -20,11 +20,13 @@ if(DEFINED ENV{BLAS_ROOT})
endif()
find_library(BLAS_LIBRARIES
libblas.dylib
NAMES libblas.dylib libopenblas.dylib
PATHS
${BLAS_ROOT_USER_DEFINED}
${BLAS_ROOT_USER_DEFINED}/lapack
/opt/local/lib/lapack
/opt/local/lib/
/usr/local/opt/lapack/lib
/usr/local/lib
NO_DEFAULT_PATH
NO_SYSTEM_ENVIRONMENT_PATH
NO_CMAKE_ENVIRONMENT_PATH
@ -34,6 +36,7 @@ find_library(BLAS_LIBRARIES
if(BLAS_LIBRARIES)
set(BLAS_FOUND TRUE)
message(STATUS "BLAS library found at ${BLAS_LIBRARIES}")
endif()
@ -41,9 +44,9 @@ find_library(LAPACK_LIBRARIES
liblapack.dylib
PATHS
${BLAS_ROOT_USER_DEFINED}
${BLAS_ROOT_USER_DEFINED}/lapack
/opt/local/lib/lapack
/usr/local/opt/lapack/lib
/usr/local/lib
NO_DEFAULT_PATH
NO_SYSTEM_ENVIRONMENT_PATH
NO_CMAKE_ENVIRONMENT_PATH
@ -53,4 +56,5 @@ find_library(LAPACK_LIBRARIES
if(LAPACK_LIBRARIES)
set(LAPACK_FOUND TRUE)
message(STATUS "LAPACK library found at ${LAPACK_LIBRARIES}")
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 ##################
;internal_fs_sps: Internal signal sampling frequency after the signal conditioning stage [sps].
;FOR USE GNSS-SDR WITH RTLSDR DONGLES USER MUST SET THE CALIBRATED SAMPLE RATE HERE
; i.e. using front-end-cal as reported here:http://www.cttc.es/publication/turning-a-television-into-a-gnss-receiver/
; i.e. using front-end-cal as reported here: https://www.researchgate.net/publication/257137427_Turning_a_Television_into_a_GNSS_Receiver
GNSS-SDR.internal_fs_sps=4000000
GNSS-SDR.use_acquisition_resampler=true
@ -143,4 +143,4 @@ PVT.nmea_dump_devname=/dev/pts/4
PVT.dump=false
PVT.flag_rtcm_server=true
PVT.flag_rtcm_tty_port=false
PVT.rtcm_dump_devname=/dev/pts/1
PVT.rtcm_dump_devname=/dev/pts/1

View File

@ -12,7 +12,8 @@
;######### GLOBAL OPTIONS ##################
;internal_fs_sps: Internal signal sampling frequency after the signal conditioning stage [samples per second].
;FOR USE GNSS-SDR WITH RTLSDR DONGLES USER MUST SET THE CALIBRATED SAMPLE RATE HERE
; i.e. using front-end-cal as reported here:http://www.cttc.es/publication/turning-a-television-into-a-gnss-receiver/
; i.e. using front-end-cal as reported here: https://www.researchgate.net/publication/257137427_Turning_a_Television_into_a_GNSS_Receiver
; i.e. using front-end-cal as reported here: https://www.researchgate.net/publication/257137427_Turning_a_Television_into_a_GNSS_Receiver
GNSS-SDR.internal_fs_sps=1200000
@ -80,7 +81,7 @@ InputFilter.grid_density=16
;#The following options are used only in Freq_Xlating_Fir_Filter implementation.
;#InputFilter.IF is the intermediate frequency (in Hz) shifted down to zero Hz
;FOR USE GNSS-SDR WITH RTLSDR DONGLES USER MUST SET THE CALIBRATED SAMPLE RATE HERE
; i.e. using front-end-cal as reported here:http://www.cttc.es/publication/turning-a-television-into-a-gnss-receiver/
; i.e. using front-end-cal as reported here: https://www.researchgate.net/publication/257137427_Turning_a_Television_into_a_GNSS_Receiver
InputFilter.sampling_frequency=1200000
InputFilter.IF=80558

View File

@ -12,7 +12,7 @@
;######### GLOBAL OPTIONS ##################
;internal_fs_sps: Internal signal sampling frequency after the signal conditioning stage [samples per second].
;FOR USE GNSS-SDR WITH RTLSDR DONGLES USER MUST SET THE CALIBRATED SAMPLE RATE HERE
; i.e. using front-end-cal as reported here:http://www.cttc.es/publication/turning-a-television-into-a-gnss-receiver/
; i.e. using front-end-cal as reported here: https://www.researchgate.net/publication/257137427_Turning_a_Television_into_a_GNSS_Receiver
GNSS-SDR.internal_fs_sps=1999898
@ -34,7 +34,7 @@ GNSS-SDR.SUPL_CI=0x31b0
SignalSource.implementation=Osmosdr_Signal_Source
SignalSource.item_type=gr_complex
; FOR USE GNSS-SDR WITH RTLSDR DONGLES USER MUST SET THE CALIBRATED SAMPLE RATE HERE
; i.e. using front-end-cal as reported here:http://www.cttc.es/publication/turning-a-television-into-a-gnss-receiver/
; i.e. using front-end-cal as reported here: https://www.researchgate.net/publication/257137427_Turning_a_Television_into_a_GNSS_Receiver
SignalSource.sampling_frequency=2000000
SignalSource.freq=1575420000
SignalSource.gain=40
@ -88,7 +88,7 @@ InputFilter.band2_error=1.0
InputFilter.filter_type=bandpass
InputFilter.grid_density=16
;FOR USE GNSS-SDR WITH RTLSDR DONGLES USER MUST SET THE CALIBRATED SAMPLE RATE HERE
; i.e. using front-end-cal as reported here:http://www.cttc.es/publication/turning-a-television-into-a-gnss-receiver/
; i.e. using front-end-cal as reported here: https://www.researchgate.net/publication/257137427_Turning_a_Television_into_a_GNSS_Receiver
InputFilter.sampling_frequency=1999898
InputFilter.IF=80558 ; IF deviation due to front-end LO inaccuracies [Hz]

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)
### 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:
- Compute PVT solutions when using GPS L5 signals even if the satellite is
reported as not healthy in the CNAV message.
### Improvements in Portability:
- Updated `cpu_features` library to v0.7.0. The building option
`ENABLE_OWN_CPUFEATURES` has been replaced by `ENABLE_CPUFEATURES`, defaulting
to `ON`.
- Fixed building against GNU Radio v3.10.2.0.
### Improvements in Reliability:
- 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
https://gnss-sdr.org/design-forces/
@ -922,8 +960,7 @@ features and bug fixes:
- Improvements in the RTCM server stability.
- Improvements in the correctness of generated RINEX files.
- The receiver can read and make use of Galileo almanac XML files published by
the European GNSS Service Centre at
https://www.gsc-europa.eu/system-status/almanac-data
the European GNSS Service Centre at https://www.gsc-europa.eu/product-almanacs
- Own-defined XML schemas for navigation data published at
https://github.com/gnss-sdr/gnss-sdr/tree/next/docs/xml-schemas
- Added program `rinex2assist` to convert RINEX navigation files into XML files

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 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 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, 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, 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="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:

View File

@ -32,7 +32,7 @@ The crystal oscillator that ships with the RTL2832U family devices exhibits limi
\.TP
Example of configuration file available at: ${prefix}/share/gnss\-sdr/conf/front\-end\-cal.conf, where ${prefix}$ uses to be /usr or /usr/local. This will be the configuration file used by default if the \fB\-config_file\fR option is not set.
\.TP
[1] C. Fernandez\-Prades, J. Arribas, P. Closas, \fITurning a Television into a GNSS Receiver\fR, in Proceedings of ION GNSS+, 15\-16 September 2013, Nashville, Tennessee (USA). A draft copy is freely available at http://www.cttc.es/publication/turning\-a\-television\-into\-a\-gnss\-receiver/
[1] C. Fernandez\-Prades, J. Arribas, P. Closas, \fITurning a Television into a GNSS Receiver\fR, in Proceedings of ION GNSS+, 15\-16 September 2013, Nashville, Tennessee (USA). A draft copy is freely available at https://www.researchgate.net/publication/257137427_Turning_a_Television_into_a_GNSS_Receiver
\.TP
Check https://gnss\-sdr.org for more information.
.SH BUGS
@ -40,4 +40,4 @@ No known bugs.
.SH AUTHOR
Javier Arribas (javier.arribas@cttc.es)
\.TP
This software has been developed at CTTC (Centre Tecnologic de Telecomunicacions de Catalunya, http://www.cttc.es) with contributions from around the world.
This software has been developed at CTTC (Centre Tecnologic de Telecomunicacions de Catalunya, https://www.cttc.cat) with contributions from around the world.

View File

@ -2,7 +2,7 @@
.\" SPDX-License-Identifier: GPL-3.0-or-later
.\" SPDX-FileCopyrightText: Carles Fernandez-Prades <carles.fernandez(at)cttc.es>
.\" Contact carles.fernandez@cttc.es to correct errors or typos.
.TH gnss\-sdr 1 "15 Feb 2022" "0.0.16" "gnss\-sdr man page"
.TH gnss\-sdr 1 "20 Apr 2022" "0.0.17" "gnss\-sdr man page"
.SH NAME
\fBgnss\-sdr\fR \- GNSS Software Defined Receiver.
.SH SYNOPSIS
@ -78,4 +78,4 @@ Please report bugs at https://github.com/gnss-sdr/gnss-sdr/issues
.SH AUTHOR
Carles Fernandez\-Prades (carles.fernandez@cttc.es)
\.TP
This software package has been developed at CTTC (Centre Tecnologic de Telecomunicacions de Catalunya, http://www.cttc.es) with contributions from around the world.
This software package has been developed at CTTC (Centre Tecnologic de Telecomunicacions de Catalunya, https://www.cttc.cat) with contributions from around the world.

View File

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

View File

@ -101,7 +101,7 @@ void Fpga_Acquisition::open_device()
LOG(WARNING) << "Cannot open deviceio" << d_device_name;
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));
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()
{
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";
}

View File

@ -142,7 +142,7 @@ public:
private:
// 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 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

View File

@ -8,7 +8,7 @@
########################################################################
# Project setup
########################################################################
cmake_minimum_required(VERSION 2.8.12...3.22)
cmake_minimum_required(VERSION 2.8.12...3.23)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
endif()
@ -209,7 +209,7 @@ message(STATUS "Build type set to ${CMAKE_BUILD_TYPE}.")
set(VERSION_INFO_MAJOR_VERSION 0)
set(VERSION_INFO_MINOR_VERSION 0)
set(VERSION_INFO_MAINT_VERSION 16)
set(VERSION_INFO_MAINT_VERSION 17)
include(VolkGnsssdrVersion) # setup version info
@ -250,44 +250,43 @@ endif()
########################################################################
# cpu_features
option(ENABLE_OWN_CPUFEATURES "Force the building of the cpu_features library even if it is already installed" OFF)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^cortex")
set(CMAKE_SYSTEM_PROCESSOR arm-${CMAKE_SYSTEM_PROCESSOR})
endif()
set(SUPPORTED_CPU_FEATURES_ARCH FALSE)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips")
set(SUPPORTED_CPU_FEATURES_ARCH TRUE)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(^aarch64)|(arm64)")
set(SUPPORTED_CPU_FEATURES_ARCH TRUE)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm")
set(SUPPORTED_CPU_FEATURES_ARCH TRUE)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(x86_64)|(AMD64|amd64)|(^i.86$)")
set(SUPPORTED_CPU_FEATURES_ARCH TRUE)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)")
set(SUPPORTED_CPU_FEATURES_ARCH TRUE)
# cpu_features - sensible defaults, user settable option
if(CMAKE_SYSTEM_PROCESSOR MATCHES
"(^mips)|(^arm)|(^aarch64)|(x86_64)|(AMD64|amd64)|(^i.86$)|(^powerpc)|(^ppc)")
option(VOLK_CPU_FEATURES "volk-gnsssdr uses cpu_features" ON)
else()
option(VOLK_CPU_FEATURES "volk-gnsssdr uses cpu_features" OFF)
endif()
if(CMAKE_VERSION VERSION_GREATER 3.0 AND SUPPORTED_CPU_FEATURES_ARCH)
set(CMAKE_POSITION_INDEPENDENT_CODE ON CACHE BOOL
"Build cpu_features with Position Independent Code (PIC)."
FORCE
)
if(CMAKE_VERSION VERSION_GREATER 3.0 AND VOLK_CPU_FEATURES)
find_package(CPUFEATURES)
set(USE_CPU_FEATURES ON)
set(BUILD_SHARED_LIBS_SAVED "${BUILD_SHARED_LIBS}")
set(BUILD_SHARED_LIBS OFF)
if(NOT ENABLE_OWN_CPUFEATURES)
find_package(CPUFEATURES QUIET)
endif()
if(CPUFEATURES_FOUND)
message(STATUS "Found CpuFeatures: (found version ${CPUFEATURES_VERSION})")
else()
if(NOT CPUFEATURES_FOUND)
message(STATUS "Building volk-gnsssdr with cpu_features")
set(BUILD_TESTING OFF CACHE BOOL "Build cpu_features without tests." FORCE)
set(BUILD_PIC ON CACHE BOOL
"Build cpu_features with Position Independent Code (PIC)."
FORCE
)
set(CMAKE_POSITION_INDEPENDENT_CODE ON CACHE BOOL
"Build cpu_features with Position Independent Code (PIC)."
FORCE
)
set(BUILD_SHARED_LIBS_SAVED "${BUILD_SHARED_LIBS}")
set(BUILD_SHARED_LIBS OFF)
add_subdirectory(cpu_features)
set(BUILD_SHARED_LIBS "${BUILD_SHARED_LIBS_SAVED}")
endif()
set(BUILD_SHARED_LIBS "${BUILD_SHARED_LIBS_SAVED}")
else()
message(STATUS "Building volk-gnsssdr without cpu_features")
endif()
# Python
include(VolkPython) # sets PYTHON_EXECUTABLE
volk_python_check_module("python >= 2.7" sys "sys.version.split()[0] >= '2.7'" PYTHON_MIN_VER_FOUND)

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.
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_LINK_LIBRARIES "${CPUFEATURES_LIBRARIES}"
)
add_library(cpu_features ALIAS CpuFeature::cpu_features)
endif()
mark_as_advanced(CPUFEATURES_LIBRARIES)

View File

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

View File

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

View File

@ -9,7 +9,7 @@ if(POLICY CMP0077)
cmake_policy(SET CMP0077 NEW)
endif()
project(CpuFeatures VERSION 0.6.0 LANGUAGES C)
project(CpuFeatures VERSION 0.7.0 LANGUAGES C)
set(CMAKE_C_STANDARD 99)
if(CMAKE_VERSION LESS "3.1")
@ -23,9 +23,6 @@ if(NOT CMAKE_BUILD_TYPE)
FORCE)
endif()
# BUILD_TESTING is a standard CMake variable, but we declare it here to make it
# prominent in the GUI.
option(BUILD_TESTING "Enable test (depends on googletest)." OFF)
# BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to make
# it prominent in the GUI.
# cpu_features uses bit-fields which are - to some extends - implementation-defined (see https://en.cppreference.com/w/c/language/bit_field).
@ -61,7 +58,7 @@ set(PROCESSOR_IS_POWER FALSE)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips")
set(PROCESSOR_IS_MIPS TRUE)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(^aarch64)|(arm64)")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64|arm64)")
set(PROCESSOR_IS_AARCH64 TRUE)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm")
set(PROCESSOR_IS_ARM TRUE)
@ -74,22 +71,19 @@ endif()
macro(add_cpu_features_headers_and_sources HDRS_LIST_NAME SRCS_LIST_NAME)
list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpu_features_macros.h)
list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpu_features_cache_info.h)
file(GLOB IMPL_SOURCES CONFIGURE_DEPENDS "${PROJECT_SOURCE_DIR}/src/impl_*.c")
list(APPEND ${SRCS_LIST_NAME} ${IMPL_SOURCES})
if(PROCESSOR_IS_MIPS)
list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_mips.h)
list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/src/cpuinfo_mips.c)
elseif(PROCESSOR_IS_ARM)
list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_arm.h)
list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/src/cpuinfo_arm.c)
elseif(PROCESSOR_IS_AARCH64)
list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_aarch64.h)
list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/src/cpuinfo_aarch64.c)
elseif(PROCESSOR_IS_X86)
list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_x86.h)
list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/internal/cpuid_x86.h)
list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/src/cpuinfo_x86.c)
elseif(PROCESSOR_IS_POWER)
list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_ppc.h)
list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/src/cpuinfo_ppc.c)
else()
message(FATAL_ERROR "Unsupported architectures ${CMAKE_SYSTEM_PROCESSOR}")
endif()
@ -147,8 +141,10 @@ target_link_libraries(cpu_features PUBLIC ${CMAKE_DL_LIBS})
target_include_directories(cpu_features
PUBLIC $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/cpu_features>
)
if(APPLE AND (PROCESSOR_IS_X86 OR PROCESSOR_IS_AARCH64))
target_compile_definitions(cpu_features PRIVATE HAVE_SYSCTLBYNAME)
if(PROCESSOR_IS_X86)
if(APPLE)
target_compile_definitions(cpu_features PRIVATE HAVE_SYSCTLBYNAME)
endif()
endif()
add_library(CpuFeature::cpu_features ALIAS cpu_features)

View File

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

View File

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

View File

@ -1,7 +1,6 @@
// SPDX-FileCopyrightText: 2017 Google LLC
// SPDX-License-Identifier: Apache-2.0
#ifndef CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_
#define CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_
@ -29,7 +28,7 @@
#define CPU_FEATURES_ARCH_ARM
#endif
#if (defined(__aarch64__) || (defined(__APPLE__) && defined(__arm64__)))
#if defined(__aarch64__)
#define CPU_FEATURES_ARCH_AARCH64
#endif
@ -57,24 +56,33 @@
// Os
////////////////////////////////////////////////////////////////////////////////
#if defined(__linux__)
#define CPU_FEATURES_OS_LINUX_OR_ANDROID
#if (defined(__freebsd__) || defined(__FreeBSD__))
#define CPU_FEATURES_OS_FREEBSD
#endif
#if defined(__ANDROID__)
#define CPU_FEATURES_OS_ANDROID
#endif
#if defined(__linux__) && !defined(CPU_FEATURES_OS_FREEBSD) && \
!defined(CPU_FEATURES_OS_ANDROID)
#define CPU_FEATURES_OS_LINUX
#endif
#if (defined(_WIN64) || defined(_WIN32))
#define CPU_FEATURES_OS_WINDOWS
#endif
#if (defined(__apple__) || defined(__APPLE__) || defined(__MACH__))
#define CPU_FEATURES_OS_DARWIN
// From https://stackoverflow.com/a/49560690
#include "TargetConditionals.h"
#if defined(TARGET_OS_OSX)
#define CPU_FEATURES_OS_MACOS
#endif
#if defined(TARGET_OS_IPHONE)
// This is set for any non-Mac Apple products (IOS, TV, WATCH)
#define CPU_FEATURES_OS_IPHONE
#endif
#if (defined(__freebsd__) || defined(__FreeBSD__))
#define CPU_FEATURES_OS_FREEBSD
#endif
////////////////////////////////////////////////////////////////////////////////
@ -215,11 +223,18 @@
// Communicates to the compiler that the block is unreachable
#if defined(CPU_FEATURES_COMPILER_CLANG) || defined(CPU_FEATURES_COMPILER_GCC)
#define UNREACHABLE() __builtin_unreachable()
#define CPU_FEATURES_UNREACHABLE() __builtin_unreachable()
#elif defined(CPU_FEATURES_COMPILER_MSC)
#define UNREACHABLE() __assume(0)
#define CPU_FEATURES_UNREACHABLE() __assume(0)
#else
#define UNREACHABLE()
#define CPU_FEATURES_UNREACHABLE()
#endif
// Communicates to the compiler that the function is now deprecated
#if defined(CPU_FEATURES_COMPILER_CLANG) || defined(CPU_FEATURES_COMPILER_GCC)
#define CPU_FEATURES_DEPRECATED(message) __attribute__((deprecated(message)))
#else
#define CPU_FEATURES_DEPRECATED(message)
#endif
#endif // CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_

View File

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

View File

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

View File

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

View File

@ -1,7 +1,6 @@
// SPDX-FileCopyrightText: 2017 Google LLC
// SPDX-License-Identifier: Apache-2.0
#ifndef CPU_FEATURES_INCLUDE_CPUINFO_PPC_H_
#define CPU_FEATURES_INCLUDE_CPUINFO_PPC_H_
@ -62,7 +61,6 @@ typedef struct
PPCFeatures features;
} PPCInfo;
// This function is guaranteed to be malloc, memset and memcpy free.
PPCInfo GetPPCInfo(void);
typedef struct
@ -113,7 +111,7 @@ typedef enum
PPC_ARCH_2_06, /* ISA 2.06 - POWER7 */
PPC_HAS_VSX, /* Vector-scalar extension */
PPC_PSERIES_PERFMON_COMPAT, /* Set of backwards compatibile performance
monitoring events */
monitoring events */
PPC_TRUE_LE,
PPC_PPC_LE,
PPC_ARCH_2_07, /* ISA 2.07 - POWER8 */

View File

@ -1,7 +1,6 @@
// SPDX-FileCopyrightText: 2017 Google LLC
// SPDX-License-Identifier: Apache-2.0
#ifndef CPU_FEATURES_INCLUDE_CPUINFO_X86_H_
#define CPU_FEATURES_INCLUDE_CPUINFO_X86_H_
@ -14,6 +13,8 @@ CPU_FEATURES_START_CPP_NAMESPACE
#define CPU_FEATURES_VENDOR_GENUINE_INTEL "GenuineIntel"
#define CPU_FEATURES_VENDOR_AUTHENTIC_AMD "AuthenticAMD"
#define CPU_FEATURES_VENDOR_HYGON_GENUINE "HygonGenuine"
#define CPU_FEATURES_VENDOR_CENTAUR_HAULS "CentaurHauls"
#define CPU_FEATURES_VENDOR_SHANGHAI " Shanghai "
// See https://en.wikipedia.org/wiki/CPUID for a list of x86 cpu features.
// The field names are based on the short name provided in the wikipedia tables.
@ -94,56 +95,70 @@ typedef struct
int family;
int model;
int stepping;
char vendor[13]; // 0 terminated string
char vendor[13]; // 0 terminated string
char brand_string[49]; // 0 terminated string
} X86Info;
// Calls cpuid and returns an initialized X86info.
// This function is guaranteed to be malloc, memset and memcpy free.
X86Info GetX86Info(void);
// Returns cache hierarchy informations.
// Can call cpuid multiple times.
// Only works on Intel CPU at the moment.
// This function is guaranteed to be malloc, memset and memcpy free.
CacheInfo GetX86CacheInfo(void);
typedef enum
{
X86_UNKNOWN,
INTEL_CORE, // CORE
INTEL_PNR, // PENRYN
INTEL_NHM, // NEHALEM
INTEL_ATOM_BNL, // BONNELL
INTEL_WSM, // WESTMERE
INTEL_SNB, // SANDYBRIDGE
INTEL_IVB, // IVYBRIDGE
INTEL_ATOM_SMT, // SILVERMONT
INTEL_HSW, // HASWELL
INTEL_BDW, // BROADWELL
INTEL_SKL, // SKYLAKE
INTEL_ATOM_GMT, // GOLDMONT
INTEL_KBL, // KABY LAKE
INTEL_CFL, // COFFEE LAKE
INTEL_WHL, // WHISKEY LAKE
INTEL_CNL, // CANNON LAKE
INTEL_ICL, // ICE LAKE
INTEL_TGL, // TIGER LAKE
INTEL_SPR, // SAPPHIRE RAPIDS
AMD_HAMMER, // K8 HAMMER
AMD_K10, // K10
AMD_K11, // K11
AMD_K12, // K12
AMD_BOBCAT, // K14 BOBCAT
AMD_PILEDRIVER, // K15 PILEDRIVER
AMD_STREAMROLLER, // K15 STREAMROLLER
AMD_EXCAVATOR, // K15 EXCAVATOR
AMD_BULLDOZER, // K15 BULLDOZER
AMD_JAGUAR, // K16 JAGUAR
AMD_PUMA, // K16 PUMA
AMD_ZEN, // K17 ZEN
AMD_ZEN_PLUS, // K17 ZEN+
AMD_ZEN2, // K17 ZEN 2
AMD_ZEN3, // K19 ZEN 3
ZHAOXIN_ZHANGJIANG, // ZhangJiang
ZHAOXIN_WUDAOKOU, // WuDaoKou
ZHAOXIN_LUJIAZUI, // LuJiaZui
ZHAOXIN_YONGFENG, // YongFeng
INTEL_80486, // 80486
INTEL_P5, // P5
INTEL_LAKEMONT, // LAKEMONT
INTEL_CORE, // CORE
INTEL_PNR, // PENRYN
INTEL_NHM, // NEHALEM
INTEL_ATOM_BNL, // BONNELL
INTEL_WSM, // WESTMERE
INTEL_SNB, // SANDYBRIDGE
INTEL_IVB, // IVYBRIDGE
INTEL_ATOM_SMT, // SILVERMONT
INTEL_HSW, // HASWELL
INTEL_BDW, // BROADWELL
INTEL_SKL, // SKYLAKE
INTEL_ATOM_GMT, // GOLDMONT
INTEL_KBL, // KABY LAKE
INTEL_CFL, // COFFEE LAKE
INTEL_WHL, // WHISKEY LAKE
INTEL_CNL, // CANNON LAKE
INTEL_ICL, // ICE LAKE
INTEL_TGL, // TIGER LAKE
INTEL_SPR, // SAPPHIRE RAPIDS
INTEL_ADL, // ALDER LAKE
INTEL_RCL, // ROCKET LAKE
INTEL_KNIGHTS_M, // KNIGHTS MILL
INTEL_KNIGHTS_L, // KNIGHTS LANDING
INTEL_KNIGHTS_F, // KNIGHTS FERRY
INTEL_KNIGHTS_C, // KNIGHTS CORNER
INTEL_NETBURST, // NETBURST
AMD_HAMMER, // K8 HAMMER
AMD_K10, // K10
AMD_K11, // K11
AMD_K12, // K12
AMD_BOBCAT, // K14 BOBCAT
AMD_PILEDRIVER, // K15 PILEDRIVER
AMD_STREAMROLLER, // K15 STREAMROLLER
AMD_EXCAVATOR, // K15 EXCAVATOR
AMD_BULLDOZER, // K15 BULLDOZER
AMD_JAGUAR, // K16 JAGUAR
AMD_PUMA, // K16 PUMA
AMD_ZEN, // K17 ZEN
AMD_ZEN_PLUS, // K17 ZEN+
AMD_ZEN2, // K17 ZEN 2
AMD_ZEN3, // K19 ZEN 3
X86_MICROARCHITECTURE_LAST_,
} X86Microarchitecture;
// Returns the underlying microarchitecture by looking at X86Info's vendor,
@ -153,7 +168,7 @@ X86Microarchitecture GetX86Microarchitecture(const X86Info* info);
// Calls cpuid and fills the brand_string.
// - brand_string *must* be of size 49 (beware of array decaying).
// - brand_string will be zero terminated.
// - This function calls memcpy.
CPU_FEATURES_DEPRECATED("brand_string is now embedded in X86Info by default")
void FillX86BrandString(char brand_string[49]);
////////////////////////////////////////////////////////////////////////////////
@ -237,4 +252,4 @@ CPU_FEATURES_END_CPP_NAMESPACE
#error "Including cpuinfo_x86.h from a non-x86 target."
#endif
#endif // CPU_FEATURES_INCLUDE_CPUINFO_X86_H
#endif // CPU_FEATURES_INCLUDE_CPUINFO_X86_H_

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -3,210 +3,365 @@
# SPDX-FileCopyrightText: 2017 Google LLC
# SPDX-License-Identifier: Apache-2.0
readonly SCRIPT_FOLDER=$(cd -P -- "$(dirname -- "$0")" && pwd -P)
readonly PROJECT_FOLDER="${SCRIPT_FOLDER}/.."
readonly ARCHIVE_FOLDER=~/cpu_features_archives
readonly QEMU_INSTALL=${ARCHIVE_FOLDER}/qemu
readonly DEFAULT_CMAKE_ARGS=" -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON"
set -eo pipefail
function extract() {
echo "Extracting ${1}..."
case $1 in
*.tar.bz2) tar xjf "$1" ;;
*.tar.xz) tar xJf "$1" ;;
*.tar.gz) tar xzf "$1" ;;
*)
echo "don't know how to extract '$1'..."
>&2 echo "don't know how to extract '$1'..."
exit 1
esac
}
function unpackifnotexists() {
mkdir -p "${ARCHIVE_FOLDER}"
cd "${ARCHIVE_FOLDER}" || exit
local URL=$1
local RELATIVE_FOLDER=$2
local DESTINATION="${ARCHIVE_FOLDER}/${RELATIVE_FOLDER}"
function unpack() {
mkdir -p "${ARCHIVE_DIR}"
cd "${ARCHIVE_DIR}" || exit 2
local -r URL=$1
local -r RELATIVE_DIR=$2
local -r DESTINATION="${ARCHIVE_DIR}/${RELATIVE_DIR}"
if [[ ! -d "${DESTINATION}" ]] ; then
local ARCHIVE_NAME=$(echo ${URL} | sed 's/.*\///')
test -f "${ARCHIVE_NAME}" || wget -q "${URL}"
echo "Downloading ${URL}..."
local -r ARCHIVE_NAME=$(basename "${URL}")
test -f "${ARCHIVE_NAME}" || wget --no-verbose "${URL}"
extract "${ARCHIVE_NAME}"
rm -f "${ARCHIVE_NAME}"
fi
}
function installqemuifneeded() {
local VERSION=${QEMU_VERSION:=2.11.1}
local ARCHES=${QEMU_ARCHES:=arm aarch64 i386 x86_64 mips mipsel mips64 mips64el}
local TARGETS=${QEMU_TARGETS:=$(echo "$ARCHES" | sed 's#$# #;s#\([^ ]*\) #\1-linux-user #g')}
function install_qemu() {
if [[ "${QEMU_ARCH}" == "DISABLED" ]]; then
>&2 echo 'QEMU is disabled !'
return 0
fi
local -r QEMU_VERSION=${QEMU_VERSION:=5.2.0}
local -r QEMU_TARGET=${QEMU_ARCH}-linux-user
if echo "${VERSION} ${TARGETS}" | cmp --silent ${QEMU_INSTALL}/.build -; then
echo "qemu ${VERSION} up to date!"
if echo "${QEMU_VERSION} ${QEMU_TARGET}" | cmp --silent "${QEMU_INSTALL}/.build" -; then
echo "qemu ${QEMU_VERSION} up to date!"
return 0
fi
echo "VERSION: ${VERSION}"
echo "TARGETS: ${TARGETS}"
echo "QEMU_VERSION: ${QEMU_VERSION}"
echo "QEMU_TARGET: ${QEMU_TARGET}"
rm -rf ${QEMU_INSTALL}
rm -rf "${QEMU_INSTALL}"
# Checking for a tarball before downloading makes testing easier :-)
local QEMU_URL="http://wiki.qemu-project.org/download/qemu-${VERSION}.tar.xz"
local QEMU_FOLDER="qemu-${VERSION}"
unpackifnotexists ${QEMU_URL} ${QEMU_FOLDER}
cd ${QEMU_FOLDER} || exit
local -r QEMU_URL="http://wiki.qemu-project.org/download/qemu-${QEMU_VERSION}.tar.xz"
local -r QEMU_DIR="qemu-${QEMU_VERSION}"
unpack ${QEMU_URL} ${QEMU_DIR}
cd ${QEMU_DIR} || exit 2
# Qemu (meson based build) depends on: pkgconf, libglib2.0, python3, ninja
./configure \
--prefix="${QEMU_INSTALL}" \
--target-list="${TARGETS}" \
--disable-docs \
--disable-sdl \
--disable-gtk \
--disable-gnutls \
--disable-gcrypt \
--disable-nettle \
--target-list="${QEMU_TARGET}" \
--audio-drv-list= \
--disable-brlapi \
--disable-curl \
--disable-curses \
--static
--disable-docs \
--disable-gcrypt \
--disable-gnutls \
--disable-gtk \
--disable-libnfs \
--disable-libssh \
--disable-nettle \
--disable-opengl \
--disable-sdl \
--disable-virglrenderer \
--disable-vte \
--enable-modules
make -j4
# --static Not supported on Archlinux
# so we use --enable-modules
# wrapper on ninja
make -j8
make install
echo "$VERSION $TARGETS" > ${QEMU_INSTALL}/.build
echo "$QEMU_VERSION $QEMU_TARGET" > "${QEMU_INSTALL}/.build"
}
function assert_defined(){
local VALUE=${1}
: "${VALUE?"${1} needs to be defined"}"
if [[ -z "${!1}" ]]; then
>&2 echo "Variable '${1}' must be defined"
exit 1
fi
}
function integrate() {
cd "${PROJECT_FOLDER}"
case "${OS}" in
"Windows_NT") CMAKE_BUILD_ARGS="--config Debug --target ALL_BUILD"
CMAKE_TEST_FILES="${BUILD_DIR}/test/Debug/*_test.exe"
DEMO=${BUILD_DIR}/Debug/list_cpu_features.exe
;;
*) CMAKE_BUILD_ARGS="--target all"
CMAKE_TEST_FILES="${BUILD_DIR}/test/*_test"
DEMO=${BUILD_DIR}/list_cpu_features
;;
esac
# Generating CMake configuration
cmake -H. -B"${BUILD_DIR}" ${DEFAULT_CMAKE_ARGS} "${CMAKE_ADDITIONAL_ARGS[@]}" -G"${CMAKE_GENERATOR:-Unix Makefiles}"
# Building
cmake --build "${BUILD_DIR}" ${CMAKE_BUILD_ARGS}
# Running tests if needed
if [[ "${QEMU_ARCH}" == "DISABLED" ]]; then
return
fi
RUN_CMD=""
if [[ -n "${QEMU_ARCH}" ]]; then
installqemuifneeded
RUN_CMD="${QEMU_INSTALL}/bin/qemu-${QEMU_ARCH} ${QEMU_ARGS[@]}"
fi
for test_binary in ${CMAKE_TEST_FILES}; do
${RUN_CMD} ${test_binary}
done
${RUN_CMD} ${DEMO}
function clean_build() {
# Cleanup previous build
rm -rf "${BUILD_DIR}"
mkdir -p "${BUILD_DIR}"
}
function expand_linaro_config() {
assert_defined TARGET
local LINARO_ROOT_URL=https://releases.linaro.org/components/toolchain/binaries/7.2-2017.11
#ref: https://releases.linaro.org/components/toolchain/binaries/
local -r LINARO_VERSION=7.5-2019.12
local -r LINARO_ROOT_URL=https://releases.linaro.org/components/toolchain/binaries/${LINARO_VERSION}
local GCC_URL=${LINARO_ROOT_URL}/${TARGET}/gcc-linaro-7.2.1-2017.11-x86_64_${TARGET}.tar.xz
local GCC_RELATIVE_FOLDER="gcc-linaro-7.2.1-2017.11-x86_64_${TARGET}"
unpackifnotexists "${GCC_URL}" "${GCC_RELATIVE_FOLDER}"
local -r GCC_VERSION=7.5.0-2019.12
local -r GCC_URL=${LINARO_ROOT_URL}/${TARGET}/gcc-linaro-${GCC_VERSION}-x86_64_${TARGET}.tar.xz
local -r GCC_RELATIVE_DIR="gcc-linaro-${GCC_VERSION}-x86_64_${TARGET}"
unpack "${GCC_URL}" "${GCC_RELATIVE_DIR}"
local SYSROOT_URL=${LINARO_ROOT_URL}/${TARGET}/sysroot-glibc-linaro-2.25-2017.11-${TARGET}.tar.xz
local SYSROOT_RELATIVE_FOLDER=sysroot-glibc-linaro-2.25-2017.11-${TARGET}
unpackifnotexists "${SYSROOT_URL}" "${SYSROOT_RELATIVE_FOLDER}"
local -r SYSROOT_VERSION=2.25-2019.12
local -r SYSROOT_URL=${LINARO_ROOT_URL}/${TARGET}/sysroot-glibc-linaro-${SYSROOT_VERSION}-${TARGET}.tar.xz
local -r SYSROOT_RELATIVE_DIR=sysroot-glibc-linaro-${SYSROOT_VERSION}-${TARGET}
unpack "${SYSROOT_URL}" "${SYSROOT_RELATIVE_DIR}"
local SYSROOT_FOLDER=${ARCHIVE_FOLDER}/${SYSROOT_RELATIVE_FOLDER}
local GCC_FOLDER=${ARCHIVE_FOLDER}/${GCC_RELATIVE_FOLDER}
local -r SYSROOT_DIR=${ARCHIVE_DIR}/${SYSROOT_RELATIVE_DIR}
local -r STAGING_DIR=${ARCHIVE_DIR}/${SYSROOT_RELATIVE_DIR}-stage
local -r GCC_DIR=${ARCHIVE_DIR}/${GCC_RELATIVE_DIR}
CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_SYSTEM_NAME=Linux)
CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_SYSTEM_PROCESSOR=${TARGET})
# Write a Toolchain file
# note: This is manadatory to use a file in order to have the CMake variable
# 'CMAKE_CROSSCOMPILING' set to TRUE.
# ref: https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html#cross-compiling-for-linux
cat >"$TOOLCHAIN_FILE" <<EOL
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR ${TARGET})
CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_SYSROOT=${SYSROOT_FOLDER})
CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_C_COMPILER=${GCC_FOLDER}/bin/${TARGET}-gcc)
CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_CXX_COMPILER=${GCC_FOLDER}/bin/${TARGET}-g++)
set(CMAKE_SYSROOT ${SYSROOT_DIR})
set(CMAKE_STAGING_PREFIX ${STAGING_DIR})
CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER)
CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY)
CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ONLY)
set(tools ${GCC_DIR})
set(CMAKE_C_COMPILER \${tools}/bin/${TARGET}-gcc)
set(CMAKE_CXX_COMPILER \${tools}/bin/${TARGET}-g++)
QEMU_ARGS+=(-L ${SYSROOT_FOLDER})
QEMU_ARGS+=(-E LD_LIBRARY_PATH=/lib)
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}" )
QEMU_ARGS+=( -E LD_LIBRARY_PATH=/lib )
}
function expand_codescape_config() {
assert_defined TARGET
local DATE=2017.10-08
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 GCC_URL=${CODESCAPE_URL}
local GCC_RELATIVE_FOLDER="mips-mti-linux-gnu/${DATE}"
unpackifnotexists "${GCC_URL}" "${GCC_RELATIVE_FOLDER}"
# ref: https://codescape.mips.com/components/toolchain/2020.06-01/downloads.html
# ref: https://codescape.mips.com/components/toolchain/2019.02-04/downloads.html
local -r DATE=2020.06-01
#local -r DATE=2019.02-04
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
#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 LIBC_FOLDER_SUFFIX=""
local LIBC_DIR_SUFFIX=""
local FLAVOUR=""
case "${TARGET}" in
"mips32") MIPS_FLAGS="-EB -mabi=32"; FLAVOUR="mips-r2-hard"; LIBC_FOLDER_SUFFIX="lib" ;;
"mips32el") MIPS_FLAGS="-EL -mabi=32"; FLAVOUR="mipsel-r2-hard"; LIBC_FOLDER_SUFFIX="lib" ;;
"mips64") MIPS_FLAGS="-EB -mabi=64"; FLAVOUR="mips-r2-hard"; LIBC_FOLDER_SUFFIX="lib64" ;;
"mips64el") MIPS_FLAGS="-EL -mabi=64"; FLAVOUR="mipsel-r2-hard"; LIBC_FOLDER_SUFFIX="lib64" ;;
*) echo 'unknown mips platform'; exit 1;;
"mips32")
MIPS_FLAGS="-EB -mips32r6 -mabi=32"
FLAVOUR="mips-r6-hard"
#MIPS_FLAGS="-EB -mips32r2 -mabi=32"
#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
local -r SYSROOT_DIR=${GCC_DIR}/sysroot
local -r STAGING_DIR=${SYSROOT_DIR}-stage
CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_FIND_ROOT_PATH=${GCC_FOLDER})
CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_SYSTEM_NAME=Linux)
CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_SYSTEM_PROCESSOR=${TARGET})
CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_C_COMPILER=mips-mti-linux-gnu-gcc)
CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_CXX_COMPILER=mips-mti-linux-gnu-g++)
CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_C_COMPILER_ARG1="${MIPS_FLAGS}")
CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_CXX_COMPILER_ARG1="${MIPS_FLAGS}")
# Write a Toolchain file
# note: This is manadatory to use a file in order to have the CMake variable
# 'CMAKE_CROSSCOMPILING' set to TRUE.
# ref: https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html#cross-compiling-for-linux
cat >"${TOOLCHAIN_FILE}" <<EOL
set(CMAKE_SYSTEM_NAME Linux)
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.
if [[ "${CONTINUOUS_INTEGRATION}" = "true" ]]; then
for folder in ${GCC_FOLDER}/sysroot/*; do
if [[ "${folder}" != "${SYSROOT_FOLDER}" ]]; then
rm -rf ${folder}
fi
done
fi
set(tools ${GCC_DIR})
local LIBC_FOLDER=${GCC_FOLDER}/mips-mti-linux-gnu/lib/${FLAVOUR}/${LIBC_FOLDER_SUFFIX}
QEMU_ARGS+=(-L ${SYSROOT_FOLDER})
QEMU_ARGS+=(-E LD_PRELOAD=${LIBC_FOLDER}/libstdc++.so.6:${LIBC_FOLDER}/libgcc_s.so.1)
set(CMAKE_C_COMPILER \${tools}/bin/mips-mti-linux-gnu-gcc)
#set(CMAKE_C_COMPILER \${tools}/bin/mips-img-linux-gnu-gcc)
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() {
assert_defined PROJECT_FOLDER
function build() {
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
BUILD_DIR="${PROJECT_FOLDER}/cmake_build/${TARGET}"
mkdir -p "${BUILD_DIR}"
declare -r PROJECT_DIR="$(cd -P -- "$(dirname -- "$0")/.." && pwd -P)"
declare -r ARCHIVE_DIR="${PROJECT_DIR}/build_cross/archives"
declare -r BUILD_DIR="${PROJECT_DIR}/build_cross/${TARGET}"
declare -r TOOLCHAIN_FILE=${ARCHIVE_DIR}/toolchain_${TARGET}.cmake
declare -a CONFIG_NAMES=()
declare -a QEMU_ARGS=()
echo "Target: '${TARGET}'"
echo "Project dir: '${PROJECT_DIR}'"
echo "Archive dir: '${ARCHIVE_DIR}'"
echo "Build dir: '${BUILD_DIR}'"
echo "toolchain file: '${TOOLCHAIN_FILE}'"
declare -a CMAKE_DEFAULT_ARGS=( -G ${CMAKE_GENERATOR:-"Ninja"} )
declare -a CMAKE_ADDITIONAL_ARGS=()
case ${TOOLCHAIN} in
LINARO) expand_linaro_config ;;
CODESCAPE) expand_codescape_config ;;
NATIVE) QEMU_ARCH="" ;;
*) echo "Unknown toolchain '${TOOLCHAIN}'..."; exit 1;;
declare -a QEMU_ARGS=()
case ${TARGET} in
x86_64)
declare -r QEMU_ARCH=x86_64 ;;
arm-linux-gnueabihf | armv8l-linux-gnueabihf | arm-linux-gnueabi)
expand_linaro_config
declare -r QEMU_ARCH=arm ;;
armeb-linux-gnueabihf | armeb-linux-gnueabi)
expand_linaro_config
declare -r QEMU_ARCH=DISABLED ;;
aarch64-linux-gnu)
expand_linaro_config
declare -r QEMU_ARCH=aarch64 ;;
aarch64_be-linux-gnu)
expand_linaro_config
declare -r QEMU_ARCH=DISABLED ;;
mips32)
expand_codescape_config
declare -r QEMU_ARCH=mips ;;
mips32el)
expand_codescape_config
declare -r QEMU_ARCH=mipsel ;;
mips64)
expand_codescape_config
declare -r QEMU_ARCH=mips64 ;;
mips64el)
expand_codescape_config
declare -r QEMU_ARCH=mips64el ;;
*)
>&2 echo "Unknown TARGET '${TARGET}'..."
exit 1 ;;
esac
declare -r QEMU_INSTALL=${ARCHIVE_DIR}/qemu-${QEMU_ARCH}
case ${1} in
toolchain)
exit ;;
build)
build ;;
qemu)
install_qemu ;;
test)
run_test ;;
*)
build
run_test ;;
esac
integrate
}
if [ "${CONTINUOUS_INTEGRATION}" = "true" ]; then
QEMU_ARCHES=${QEMU_ARCH}
expand_environment_and_integrate
fi
main "${1:-all}"

View File

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

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)
// On Android we probe the system's C library for a 'getauxval' function and
// call it if it exits, or return 0 for failure. This function is available
// since API level 20.
//
// This code does *NOT* check for '__ANDROID_API__ >= 20' to support the edge
// case where some NDK developers use headers for a platform that is newer than
// the one really targetted by their application. This is typically done to use
// newer native APIs only when running on more recent Android versions, and
// requires careful symbol management.
// since API level 18.
//
// Note that getauxval() can't really be re-implemented here, because its
// implementation does not parse /proc/self/auxv. Instead it depends on values

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-License-Identifier: Apache-2.0
#include "cpu_features_macros.h"
#ifdef CPU_FEATURES_ARCH_ARM
#if defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID)
#include "cpuinfo_arm.h"
////////////////////////////////////////////////////////////////////////////////
// Definitions for introspection.
////////////////////////////////////////////////////////////////////////////////
#define INTROSPECTION_TABLE \
LINE(ARM_SWP, swp, "swp", ARM_HWCAP_SWP, 0) \
LINE(ARM_HALF, half, "half", ARM_HWCAP_HALF, 0) \
LINE(ARM_THUMB, thumb, "thumb", ARM_HWCAP_THUMB, 0) \
LINE(ARM_26BIT, _26bit, "26bit", ARM_HWCAP_26BIT, 0) \
LINE(ARM_FASTMULT, fastmult, "fastmult", ARM_HWCAP_FAST_MULT, 0) \
LINE(ARM_FPA, fpa, "fpa", ARM_HWCAP_FPA, 0) \
LINE(ARM_VFP, vfp, "vfp", ARM_HWCAP_VFP, 0) \
LINE(ARM_EDSP, edsp, "edsp", ARM_HWCAP_EDSP, 0) \
LINE(ARM_JAVA, java, "java", ARM_HWCAP_JAVA, 0) \
LINE(ARM_IWMMXT, iwmmxt, "iwmmxt", ARM_HWCAP_IWMMXT, 0) \
LINE(ARM_CRUNCH, crunch, "crunch", ARM_HWCAP_CRUNCH, 0) \
LINE(ARM_THUMBEE, thumbee, "thumbee", ARM_HWCAP_THUMBEE, 0) \
LINE(ARM_NEON, neon, "neon", ARM_HWCAP_NEON, 0) \
LINE(ARM_VFPV3, vfpv3, "vfpv3", ARM_HWCAP_VFPV3, 0) \
LINE(ARM_VFPV3D16, vfpv3d16, "vfpv3d16", ARM_HWCAP_VFPV3D16, 0) \
LINE(ARM_TLS, tls, "tls", ARM_HWCAP_TLS, 0) \
LINE(ARM_VFPV4, vfpv4, "vfpv4", ARM_HWCAP_VFPV4, 0) \
LINE(ARM_IDIVA, idiva, "idiva", ARM_HWCAP_IDIVA, 0) \
LINE(ARM_IDIVT, idivt, "idivt", ARM_HWCAP_IDIVT, 0) \
LINE(ARM_VFPD32, vfpd32, "vfpd32", ARM_HWCAP_VFPD32, 0) \
LINE(ARM_LPAE, lpae, "lpae", ARM_HWCAP_LPAE, 0) \
LINE(ARM_EVTSTRM, evtstrm, "evtstrm", ARM_HWCAP_EVTSTRM, 0) \
LINE(ARM_AES, aes, "aes", 0, ARM_HWCAP2_AES) \
LINE(ARM_PMULL, pmull, "pmull", 0, ARM_HWCAP2_PMULL) \
LINE(ARM_SHA1, sha1, "sha1", 0, ARM_HWCAP2_SHA1) \
LINE(ARM_SHA2, sha2, "sha2", 0, ARM_HWCAP2_SHA2) \
LINE(ARM_CRC32, crc32, "crc32", 0, ARM_HWCAP2_CRC32)
#define INTROSPECTION_PREFIX Arm
#define INTROSPECTION_ENUM_PREFIX ARM
#include "define_introspection_and_hwcaps.inl"
////////////////////////////////////////////////////////////////////////////////
// Implementation.
////////////////////////////////////////////////////////////////////////////////
#include "internal/bit_utils.h"
#include "internal/filesystem.h"
#include "internal/hwcaps.h"
#include "internal/stack_line_reader.h"
#include "internal/string_view.h"
#include <assert.h>
#include <ctype.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"
#include <stdbool.h>
typedef struct
{
@ -155,13 +166,15 @@ static void FixErrors(ArmInfo* const info,
// https://crbug.com/341598.
info->features.neon = false;
break;
case 0x510006F2:
case 0x510006F3:
// The Nexus 4 (Qualcomm Krait) kernel configuration forgets to report
// IDIV support.
}
// Some Qualcomm Krait kernels forget to report IDIV support.
// https://github.com/torvalds/linux/commit/120ecfafabec382c4feb79ff159ef42a39b6d33b
if (info->implementer == 0x51 && info->architecture == 7 &&
(info->part == 0x4d || info->part == 0x6f))
{
info->features.idiva = true;
info->features.idivt = true;
break;
}
// Propagate cpu features.
@ -217,18 +230,5 @@ ArmInfo GetArmInfo(void)
return info;
}
////////////////////////////////////////////////////////////////////////////////
// Introspection functions
int GetArmFeaturesEnumValue(const ArmFeatures* features,
ArmFeaturesEnum value)
{
if (value >= ARM_LAST_) return false;
return kGetters[value](features);
}
const char* GetArmFeaturesEnumName(ArmFeaturesEnum value)
{
if (value >= ARM_LAST_) return "unknown feature";
return kCpuInfoFlags[value];
}
#endif // defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID)
#endif // CPU_FEATURES_ARCH_ARM

View File

@ -1,21 +1,32 @@
// SPDX-FileCopyrightText: 2017 Google LLC
// SPDX-License-Identifier: Apache-2.0
#include "cpu_features_macros.h"
#ifdef CPU_FEATURES_ARCH_MIPS
#if defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID)
#include "cpuinfo_mips.h"
////////////////////////////////////////////////////////////////////////////////
// Definitions for introspection.
////////////////////////////////////////////////////////////////////////////////
#define INTROSPECTION_TABLE \
LINE(MIPS_MSA, msa, "msa", MIPS_HWCAP_MSA, 0) \
LINE(MIPS_EVA, eva, "eva", 0, 0) \
LINE(MIPS_R6, r6, "r6", MIPS_HWCAP_R6, 0)
#define INTROSPECTION_PREFIX Mips
#define INTROSPECTION_ENUM_PREFIX MIPS
#include "define_introspection_and_hwcaps.inl"
////////////////////////////////////////////////////////////////////////////////
// Implementation.
////////////////////////////////////////////////////////////////////////////////
#include "internal/filesystem.h"
#include "internal/hwcaps.h"
#include "internal/stack_line_reader.h"
#include "internal/string_view.h"
#include <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,
MipsFeatures* const features)
@ -75,18 +86,5 @@ MipsInfo GetMipsInfo(void)
return info;
}
////////////////////////////////////////////////////////////////////////////////
// Introspection functions
int GetMipsFeaturesEnumValue(const MipsFeatures* features,
MipsFeaturesEnum value)
{
if (value >= MIPS_LAST_) return false;
return kGetters[value](features);
}
const char* GetMipsFeaturesEnumName(MipsFeaturesEnum value)
{
if (value >= MIPS_LAST_) return "unknown feature";
return kCpuInfoFlags[value];
}
#endif // defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID)
#endif // CPU_FEATURES_ARCH_MIPS

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
// This program dumps current host data to the standard output.
@ -363,7 +363,7 @@ static Node* GetCacheTypeString(CacheType cache_type)
case CPU_FEATURE_CACHE_PREFETCH:
return CreateConstantString("prefetch");
}
UNREACHABLE();
CPU_FEATURES_UNREACHABLE();
}
static void AddCacheInfo(Node* root, const CacheInfo* cache_info)

View File

@ -50,7 +50,13 @@ add_test(NAME stack_line_reader_test COMMAND stack_line_reader_test)
##------------------------------------------------------------------------------
## cpuinfo_x86_test
if(PROCESSOR_IS_X86)
add_executable(cpuinfo_x86_test cpuinfo_x86_test.cc ../src/cpuinfo_x86.c)
add_executable(cpuinfo_x86_test
cpuinfo_x86_test.cc
../src/impl_x86_freebsd.c
../src/impl_x86_linux_or_android.c
../src/impl_x86_macos.c
../src/impl_x86_windows.c
)
target_compile_definitions(cpuinfo_x86_test PUBLIC CPU_FEATURES_MOCK_CPUID_X86)
if(APPLE)
target_compile_definitions(cpuinfo_x86_test PRIVATE HAVE_SYSCTLBYNAME)
@ -61,32 +67,28 @@ endif()
##------------------------------------------------------------------------------
## cpuinfo_arm_test
if(PROCESSOR_IS_ARM)
add_executable(cpuinfo_arm_test cpuinfo_arm_test.cc ../src/cpuinfo_arm.c)
add_executable(cpuinfo_arm_test cpuinfo_arm_test.cc ../src/impl_arm_linux_or_android.c)
target_link_libraries(cpuinfo_arm_test all_libraries)
add_test(NAME cpuinfo_arm_test COMMAND cpuinfo_arm_test)
endif()
##------------------------------------------------------------------------------
## cpuinfo_aarch64_test
if(PROCESSOR_IS_AARCH64)
add_executable(cpuinfo_aarch64_test cpuinfo_aarch64_test.cc ../src/cpuinfo_aarch64.c)
if(APPLE)
target_compile_definitions(cpuinfo_aarch64_test PUBLIC CPU_FEATURES_MOCK_CPUID_ARM64)
target_compile_definitions(cpuinfo_aarch64_test PRIVATE HAVE_SYSCTLBYNAME)
endif()
add_executable(cpuinfo_aarch64_test cpuinfo_aarch64_test.cc ../src/impl_aarch64_linux_or_android.c)
target_link_libraries(cpuinfo_aarch64_test all_libraries)
add_test(NAME cpuinfo_aarch64_test COMMAND cpuinfo_aarch64_test)
endif()
##------------------------------------------------------------------------------
## cpuinfo_mips_test
if(PROCESSOR_IS_MIPS)
add_executable(cpuinfo_mips_test cpuinfo_mips_test.cc ../src/cpuinfo_mips.c)
add_executable(cpuinfo_mips_test cpuinfo_mips_test.cc ../src/impl_mips_linux_or_android.c)
target_link_libraries(cpuinfo_mips_test all_libraries)
add_test(NAME cpuinfo_mips_test COMMAND cpuinfo_mips_test)
endif()
##------------------------------------------------------------------------------
## cpuinfo_ppc_test
if(PROCESSOR_IS_POWER)
add_executable(cpuinfo_ppc_test cpuinfo_ppc_test.cc ../src/cpuinfo_ppc.c)
add_executable(cpuinfo_ppc_test cpuinfo_ppc_test.cc ../src/impl_ppc_linux.c)
target_link_libraries(cpuinfo_ppc_test all_libraries)
add_test(NAME cpuinfo_ppc_test COMMAND cpuinfo_ppc_test)
endif()

View File

@ -103,7 +103,6 @@ CPU architecture: 7
CPU variant : 0x0
CPU part : 0xb76
CPU revision : 7
Hardware : BCM2835
Revision : 9000c1
Serial : 000000006cd946f3)");
@ -156,7 +155,6 @@ CPU architecture: 7
CPU variant : 0x4
CPU part : 0xc09
CPU revision : 1
processor : 1
model name : ARMv7 Processor rev 1 (v7l)
BogoMIPS : 50.00
@ -166,7 +164,6 @@ CPU architecture: 7
CPU variant : 0x4
CPU part : 0xc09
CPU revision : 1
Hardware : Marvell Armada 380/385 (Device Tree)
Revision : 0000
Serial : 0000000000000000)");
@ -221,7 +218,6 @@ CPU architecture: 7
CPU variant : 0x0
CPU part : 0xb76
CPU revision : 6
Hardware : SPICA
Revision : 0020
Serial : 33323613546d00ec )");
@ -267,17 +263,14 @@ TEST(CpuinfoArmTest, InvalidNeon)
R"(Processor: ARMv7 Processory rev 0 (v71)
processor: 0
BogoMIPS: 13.50
Processor: 1
BogoMIPS: 13.50
Features: swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt
CPU implementer : 0x51
CPU architecture: 7
CPU variant: 0x1
CPU part: 0x04d
CPU revision: 0
Hardware: SAMSUNG M2
Revision: 0010
Serial: 00001e030000354e)");
@ -324,6 +317,25 @@ CPU revision : 3)");
EXPECT_EQ(GetArmCpuId(&info), 0x510006f3);
}
// The 2013 Nexus 7 (Qualcomm Krait) kernel configuration forgets to report IDIV
// support.
TEST(CpuinfoArmTest, Nexus7_2013_0x511006f0)
{
ResetHwcaps();
auto& fs = GetEmptyFilesystem();
fs.CreateFile("/proc/cpuinfo",
R"(CPU implementer : 0x51
CPU architecture: 7
CPU variant : 0x1
CPU part : 0x06f
CPU revision : 0)");
const auto info = GetArmInfo();
EXPECT_TRUE(info.features.idiva);
EXPECT_TRUE(info.features.idivt);
EXPECT_EQ(GetArmCpuId(&info), 0x511006f0);
}
// The emulator-specific Android 4.2 kernel fails to report support for the
// 32-bit ARM IDIV instruction. Technically, this is a feature of the virtual
// CPU implemented by the emulator.
@ -340,7 +352,6 @@ CPU architecture: 7
CPU variant : 0x0
CPU part : 0xc08
CPU revision : 0
Hardware : Goldfish
Revision : 0000
Serial : 0000000000000000)");

View File

@ -16,6 +16,7 @@
namespace cpu_features
{
class FakeCpu
{
public:
@ -41,7 +42,7 @@ public:
xcr0_eax_ = os_backups_extended_registers ? -1 : 0;
}
#if defined(CPU_FEATURES_OS_DARWIN)
#if defined(CPU_FEATURES_OS_MACOS)
bool GetDarwinSysCtlByName(std::string name) const
{
return darwin_sysctlbyname_.count(name);
@ -51,7 +52,7 @@ public:
{
darwin_sysctlbyname_.insert(name);
}
#endif // CPU_FEATURES_OS_DARWIN
#endif // CPU_FEATURES_OS_MACOS
#if defined(CPU_FEATURES_OS_WINDOWS)
bool GetWindowsIsProcessorFeaturePresent(DWORD ProcessorFeature)
@ -67,9 +68,9 @@ public:
private:
std::map<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_;
#endif // CPU_FEATURES_OS_DARWIN
#endif // CPU_FEATURES_OS_MACOS
#if defined(CPU_FEATURES_OS_WINDOWS)
std::set<DWORD> windows_isprocessorfeaturepresent_;
#endif // CPU_FEATURES_OS_WINDOWS
@ -91,12 +92,12 @@ extern "C" Leaf GetCpuidLeaf(uint32_t leaf_id, int ecx)
extern "C" uint32_t GetXCR0Eax(void) { return cpu().GetXCR0Eax(); }
#if defined(CPU_FEATURES_OS_DARWIN)
#if defined(CPU_FEATURES_OS_MACOS)
extern "C" bool GetDarwinSysCtlByName(const char* name)
{
return cpu().GetDarwinSysCtlByName(name);
}
#endif // CPU_FEATURES_OS_DARWIN
#endif // CPU_FEATURES_OS_MACOS
#if defined(CPU_FEATURES_OS_WINDOWS)
extern "C" bool GetWindowsIsProcessorFeaturePresent(DWORD ProcessorFeature)
@ -107,6 +108,7 @@ extern "C" bool GetWindowsIsProcessorFeaturePresent(DWORD ProcessorFeature)
namespace
{
class CpuidX86Test : public ::testing::Test
{
protected:
@ -430,6 +432,8 @@ TEST_F(CpuidX86Test, AMD_K15_EXCAVATOR_STONEY_RIDGE)
EXPECT_STREQ(info.vendor, "AuthenticAMD");
EXPECT_EQ(info.family, 0x15);
EXPECT_EQ(info.model, 0x70);
EXPECT_STREQ(info.brand_string,
"AMD A9-9410 RADEON R5, 5 COMPUTE CORES 2C+3G ");
EXPECT_EQ(GetX86Microarchitecture(&info),
X86Microarchitecture::AMD_EXCAVATOR);
@ -456,6 +460,8 @@ TEST_F(CpuidX86Test, AMD_K15_PILEDRIVER_ABU_DHABI)
EXPECT_STREQ(info.vendor, "AuthenticAMD");
EXPECT_EQ(info.family, 0x15);
EXPECT_EQ(info.model, 0x02);
EXPECT_STREQ(info.brand_string,
"AMD Opteron(tm) Processor 6376 ");
EXPECT_EQ(GetX86Microarchitecture(&info),
X86Microarchitecture::AMD_PILEDRIVER);
@ -531,6 +537,8 @@ TEST_F(CpuidX86Test, AMD_K15_BULLDOZER_INTERLAGOS)
EXPECT_STREQ(info.vendor, "AuthenticAMD");
EXPECT_EQ(info.family, 0x15);
EXPECT_EQ(info.model, 0x01);
EXPECT_STREQ(info.brand_string,
"AMD Opteron(TM) Processor 6238 ");
EXPECT_EQ(GetX86Microarchitecture(&info),
X86Microarchitecture::AMD_BULLDOZER);
@ -559,6 +567,8 @@ TEST_F(CpuidX86Test, AMD_K15_STREAMROLLER_GODAVARI)
EXPECT_EQ(info.family, 0x15);
EXPECT_EQ(info.model, 0x38);
EXPECT_EQ(info.stepping, 0x01);
EXPECT_STREQ(info.brand_string,
"AMD A8-7670K Radeon R7, 10 Compute Cores 4C+6G ");
EXPECT_EQ(GetX86Microarchitecture(&info),
X86Microarchitecture::AMD_STREAMROLLER);
@ -585,6 +595,8 @@ TEST_F(CpuidX86Test, AMD_K16_JAGUAR_KABINI)
EXPECT_STREQ(info.vendor, "AuthenticAMD");
EXPECT_EQ(info.family, 0x16);
EXPECT_EQ(info.model, 0x00);
EXPECT_STREQ(info.brand_string,
"AMD A4-5000 APU with Radeon(TM) HD Graphics ");
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_JAGUAR);
char brand_string[49];
@ -610,6 +622,8 @@ TEST_F(CpuidX86Test, AMD_K16_PUMA_BEEMA)
EXPECT_STREQ(info.vendor, "AuthenticAMD");
EXPECT_EQ(info.family, 0x16);
EXPECT_EQ(info.model, 0x30);
EXPECT_STREQ(info.brand_string,
"AMD A6-6310 APU with AMD Radeon R4 Graphics ");
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_PUMA);
char brand_string[49];
@ -635,6 +649,8 @@ TEST_F(CpuidX86Test, AMD_K17_ZEN_DALI)
EXPECT_STREQ(info.vendor, "AuthenticAMD");
EXPECT_EQ(info.family, 0x17);
EXPECT_EQ(info.model, 0x20);
EXPECT_STREQ(info.brand_string,
"AMD 3020e with Radeon Graphics ");
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN);
char brand_string[49];
@ -660,6 +676,8 @@ TEST_F(CpuidX86Test, AMD_K17_ZEN_PLUS_PINNACLE_RIDGE)
EXPECT_STREQ(info.vendor, "AuthenticAMD");
EXPECT_EQ(info.family, 0x17);
EXPECT_EQ(info.model, 0x08);
EXPECT_STREQ(info.brand_string,
"AMD Ryzen 7 2700X Eight-Core Processor ");
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN_PLUS);
char brand_string[49];
@ -685,6 +703,7 @@ TEST_F(CpuidX86Test, AMD_K17_ZEN2_XBOX_SERIES_X)
EXPECT_STREQ(info.vendor, "AuthenticAMD");
EXPECT_EQ(info.family, 0x17);
EXPECT_EQ(info.model, 0x47);
EXPECT_STREQ(info.brand_string, "AMD 4700S 8-Core Processor Desktop Kit");
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN2);
char brand_string[49];
@ -710,6 +729,8 @@ TEST_F(CpuidX86Test, AMD_K18_ZEN_DHYANA)
EXPECT_STREQ(info.vendor, "HygonGenuine");
EXPECT_EQ(info.family, 0x18);
EXPECT_EQ(info.model, 0x00);
EXPECT_STREQ(info.brand_string,
"Hygon C86 3185 8-core Processor ");
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN);
char brand_string[49];
@ -784,6 +805,8 @@ TEST_F(CpuidX86Test, AMD_K19_ZEN3_VERMEER)
EXPECT_STREQ(info.vendor, "AuthenticAMD");
EXPECT_EQ(info.family, 0x19);
EXPECT_EQ(info.model, 0x21);
EXPECT_STREQ(info.brand_string,
"AMD Ryzen 9 5900X 12-Core Processor ");
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN3);
char brand_string[49];
@ -800,7 +823,7 @@ TEST_F(CpuidX86Test, Nehalem)
cpu().SetWindowsIsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE);
cpu().SetWindowsIsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE);
cpu().SetWindowsIsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE);
#elif defined(CPU_FEATURES_OS_DARWIN)
#elif defined(CPU_FEATURES_OS_MACOS)
cpu().SetDarwinSysCtlByName("hw.optional.sse");
cpu().SetDarwinSysCtlByName("hw.optional.sse2");
cpu().SetDarwinSysCtlByName("hw.optional.sse3");
@ -817,10 +840,10 @@ FreeBSD is a registered trademark of The FreeBSD Foundation.
Features2=0x5eda2203<SSE3,PCLMULQDQ,SSSE3,CX16,PCID,SSE4.1,SSE4.2,MOVBE,POPCNT,AESNI,XSAVE,OSXSAVE,RDRAND>
real memory = 2147418112 (2047 MB)
)");
#elif defined(CPU_FEATURES_OS_LINUX_OR_ANDROID)
#elif defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID)
auto& fs = GetEmptyFilesystem();
fs.CreateFile("/proc/cpuinfo", R"(processor :
flags : fpu mmx sse sse2 sse3 ssse3 sse4_1 sse4_2
flags : fpu mmx sse sse2 pni ssse3 sse4_1 sse4_2
)");
#endif
cpu().SetLeaves({
@ -856,6 +879,8 @@ flags : fpu mmx sse sse2 sse3 ssse3 sse4_1 sse4_2
EXPECT_EQ(info.family, 0x06);
EXPECT_EQ(info.model, 0x1A);
EXPECT_EQ(info.stepping, 0x02);
EXPECT_STREQ(info.brand_string,
"Genuine Intel(R) CPU @ 0000 @ 1.87GHz");
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_NHM);
char brand_string[49];
@ -883,7 +908,7 @@ TEST_F(CpuidX86Test, Atom)
cpu().SetWindowsIsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE);
cpu().SetWindowsIsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE);
cpu().SetWindowsIsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE);
#elif defined(CPU_FEATURES_OS_DARWIN)
#elif defined(CPU_FEATURES_OS_MACOS)
cpu().SetDarwinSysCtlByName("hw.optional.sse");
cpu().SetDarwinSysCtlByName("hw.optional.sse2");
cpu().SetDarwinSysCtlByName("hw.optional.sse3");
@ -900,10 +925,10 @@ FreeBSD is a registered trademark of The FreeBSD Foundation.
Features2=0x5eda2203<SSE3,PCLMULQDQ,SSSE3,CX16,PCID,SSE4.1,SSE4.2,MOVBE,POPCNT,AESNI,XSAVE,OSXSAVE,RDRAND>
real memory = 2147418112 (2047 MB)
)");
#elif defined(CPU_FEATURES_OS_LINUX_OR_ANDROID)
#elif defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID)
auto& fs = GetEmptyFilesystem();
fs.CreateFile("/proc/cpuinfo", R"(
flags : fpu mmx sse sse2 sse3 ssse3 sse4_1 sse4_2
flags : fpu mmx sse sse2 pni ssse3 sse4_1 sse4_2
)");
#endif
cpu().SetLeaves({
@ -938,6 +963,8 @@ flags : fpu mmx sse sse2 sse3 ssse3 sse4_1 sse4_2
EXPECT_EQ(info.family, 0x06);
EXPECT_EQ(info.model, 0x37);
EXPECT_EQ(info.stepping, 0x03);
EXPECT_STREQ(info.brand_string,
" Intel(R) Celeron(R) CPU J1900 @ 1.99GHz");
EXPECT_EQ(GetX86Microarchitecture(&info),
X86Microarchitecture::INTEL_ATOM_SMT);
@ -1017,7 +1044,7 @@ TEST_F(CpuidX86Test, P3)
cpu().SetOsBackupsExtendedRegisters(false);
#if defined(CPU_FEATURES_OS_WINDOWS)
cpu().SetWindowsIsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE);
#elif defined(CPU_FEATURES_OS_DARWIN)
#elif defined(CPU_FEATURES_OS_MACOS)
cpu().SetDarwinSysCtlByName("hw.optional.sse");
#elif defined(CPU_FEATURES_OS_FREEBSD)
auto& fs = GetEmptyFilesystem();
@ -1028,7 +1055,7 @@ FreeBSD is a registered trademark of The FreeBSD Foundation.
Features=0x1783fbff<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)
)");
#elif defined(CPU_FEATURES_OS_LINUX_OR_ANDROID)
#elif defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID)
auto& fs = GetEmptyFilesystem();
fs.CreateFile("/proc/cpuinfo", R"(
flags : fpu mmx sse
@ -1046,6 +1073,7 @@ flags : fpu mmx sse
EXPECT_EQ(info.family, 0x06);
EXPECT_EQ(info.model, 0x07);
EXPECT_EQ(info.stepping, 0x03);
EXPECT_STREQ(info.brand_string, "");
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::X86_UNKNOWN);
char brand_string[49];
@ -1065,6 +1093,95 @@ flags : fpu mmx sse
#endif // !defined(CPU_FEATURES_OS_WINDOWS)
}
// https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel0000480_486_CPUID.txt
TEST_F(CpuidX86Test, INTEL_80486)
{
cpu().SetLeaves({
{{0x00000000, 0}, Leaf{0x00000001, 0x756E6547, 0x6C65746E, 0x49656E69}},
{{0x00000001, 0}, Leaf{0x00000480, 0x00000000, 0x00000000, 0x00000003}},
});
const auto info = GetX86Info();
EXPECT_STREQ(info.vendor, "GenuineIntel");
EXPECT_EQ(info.family, 0x04);
EXPECT_EQ(info.model, 0x08);
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_80486);
}
// https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel0000526_P54C_CPUID.txt
TEST_F(CpuidX86Test, INTEL_P54C)
{
cpu().SetLeaves({
{{0x00000000, 0}, Leaf{0x00000001, 0x756E6547, 0x6C65746E, 0x49656E69}},
{{0x00000001, 0}, Leaf{0x00000525, 0x00000000, 0x00000000, 0x000001BF}},
});
const auto info = GetX86Info();
EXPECT_STREQ(info.vendor, "GenuineIntel");
EXPECT_EQ(info.family, 0x05);
EXPECT_EQ(info.model, 0x02);
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_P5);
}
// https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel0000590_Lakemont_CPUID2.txt
TEST_F(CpuidX86Test, INTEL_LAKEMONT)
{
cpu().SetLeaves({
{{0x00000000, 0}, Leaf{0x00000002, 0x756E6547, 0x6c65746E, 0x49656E69}},
{{0x00000001, 0}, Leaf{0x00000590, 0x00000000, 0x00010200, 0x8000237B}},
});
const auto info = GetX86Info();
EXPECT_STREQ(info.vendor, "GenuineIntel");
EXPECT_EQ(info.family, 0x05);
EXPECT_EQ(info.model, 0x09);
EXPECT_EQ(GetX86Microarchitecture(&info),
X86Microarchitecture::INTEL_LAKEMONT);
}
// https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel0050670_KnightsLanding_CPUID.txt
TEST_F(CpuidX86Test, INTEL_KNIGHTS_LANDING)
{
cpu().SetLeaves({
{{0x00000000, 0}, Leaf{0x0000000D, 0x756E6547, 0x6C65746E, 0x49656E69}},
{{0x00000001, 0}, Leaf{0x00050670, 0x02FF0800, 0x7FF8F3BF, 0xBFEBFBFF}},
});
const auto info = GetX86Info();
EXPECT_STREQ(info.vendor, "GenuineIntel");
EXPECT_EQ(info.family, 0x06);
EXPECT_EQ(info.model, 0x57);
EXPECT_EQ(GetX86Microarchitecture(&info),
X86Microarchitecture::INTEL_KNIGHTS_L);
}
// https://github.com/google/cpu_features/issues/200
// http://users.atw.hu/instlatx64/GenuineIntel/GenuineIntel00206F2_Eagleton_CPUID.txt
#if defined(CPU_FEATURES_OS_WINDOWS)
TEST_F(CpuidX86Test, WIN_INTEL_WESTMERE_EX)
{
cpu().SetLeaves({
{{0x00000000, 0}, Leaf{0x0000000B, 0x756E6547, 0x6C65746E, 0x49656E69}},
{{0x00000001, 0}, Leaf{0x000206F2, 0x00400800, 0x02BEE3FF, 0xBFEBFBFF}},
});
const auto info = GetX86Info();
EXPECT_EQ(info.family, 0x06);
EXPECT_EQ(info.model, 0x2F);
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_WSM);
#if (_WIN32_WINNT < 0x0601) // before Win7
EXPECT_FALSE(info.features.ssse3);
EXPECT_FALSE(info.features.sse4_1);
EXPECT_FALSE(info.features.sse4_2);
#else
EXPECT_TRUE(info.features.ssse3);
EXPECT_TRUE(info.features.sse4_1);
EXPECT_TRUE(info.features.sse4_2);
#endif
}
#endif // CPU_FEATURES_OS_WINDOWS
// TODO(user): test what happens when xsave/osxsave are not present.
// TODO(user): test what happens when xmm/ymm/zmm os support are not
// present.

View File

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

View File

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

View File

@ -56,6 +56,7 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con
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)),
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_rx2_(configuration->property(role + ".gain_rx1", default_manual_gain_rx2)),
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
if (FLAGS_signal_source != "-")
{
filename0 = FLAGS_signal_source;
filename0_ = FLAGS_signal_source;
}
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 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
// 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;
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
* 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;
if (file.is_open())
@ -182,13 +188,13 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con
}
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;
return;
}
std::streamsize ss = std::cout.precision();
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);
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
}
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;
if (file.is_open())
@ -210,13 +216,13 @@ Ad9361FpgaSignalSource::Ad9361FpgaSignalSource(const ConfigurationInterface *con
}
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;
return;
}
std::streamsize ss = std::cout.precision();
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);
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]";
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
{
DLOG(INFO) << "File source filename rx1 " << filename0;
DLOG(INFO) << "File source filename rx2 " << filename1;
DLOG(INFO) << "File source filename rx1 " << filename0_;
DLOG(INFO) << "File source filename rx2 " << filename1_;
}
DLOG(INFO) << "Samples " << samples_;
DLOG(INFO) << "Sampling frequency " << sample_rate_;
@ -521,39 +527,43 @@ Ad9361FpgaSignalSource::~Ad9361FpgaSignalSource()
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;
infile1.exceptions(std::ifstream::failbit | std::ifstream::badbit);
// FPGA DMA control
dma_fpga = std::make_shared<Fpga_DMA>();
// open the files
try
{
infile1.open(filename0, std::ios::binary);
infile1.open(filename0_, std::ios::binary);
}
catch (const std::ifstream::failure &e)
{
std::cerr << "Exception opening file " << filename0 << '\n';
std::cerr << "Exception opening file " << filename0_ << '\n';
// stop the receiver
queue->push(pmt::make_any(command_event_make(200, 0)));
return;
}
std::ifstream infile2;
if (!filename1.empty())
if (!filename1_.empty())
{
infile2.exceptions(std::ifstream::failbit | std::ifstream::badbit);
try
{
infile2.open(filename1, std::ios::binary);
infile2.open(filename1_, std::ios::binary);
}
catch (const std::ifstream::failure &e)
{
std::cerr << "Exception opening file " << filename1 << '\n';
std::cerr << "Exception opening file " << filename1_ << '\n';
// stop the receiver
queue->push(pmt::make_any(command_event_make(200, 0)));
return;
@ -568,13 +578,13 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const
}
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
queue->push(pmt::make_any(command_event_make(200, 0)));
return;
}
if (!filename1.empty())
if (!filename1_.empty())
{
try
{
@ -582,7 +592,7 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const
}
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
queue->push(pmt::make_any(command_event_make(200, 0)));
return;
@ -590,38 +600,21 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const
}
// rx signal vectors
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
std::vector<int8_t> input_samples(sample_block_size * 2); // complex samples
// 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
bool run_DMA = true;
int num_transferred_bytes;
// Open DMA device
int tx_fd = open("/dev/loop_tx", O_WRONLY);
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)
if (dma_fpga->DMA_open())
{
std::cerr << "Cannot open loop device\n";
// stop the receiver
queue->push(pmt::make_any(command_event_make(200, 0)));
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
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.
for (int index0 = 0; index0 < (nread_elements); index0 += 2)
{
input_samples_dma[dma_index + (2 - dma_buff_offset_pos)] = 0;
input_samples_dma[dma_index + 1 + (2 - dma_buff_offset_pos)] = 0;
(*dma_buffer)[dma_index + (2 - dma_buff_offset_pos)] = 0;
(*dma_buffer)[dma_index + 1 + (2 - dma_buff_offset_pos)] = 0;
dma_index += 4;
}
}
@ -656,7 +649,7 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const
}
catch (const std::ifstream::failure &e)
{
std::cerr << "Exception reading file " << filename0 << '\n';
std::cerr << "Exception reading file " << filename0_ << '\n';
break;
}
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)
{
// 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];
input_samples_dma[dma_index + 1 + dma_buff_offset_pos] = input_samples[index0 + 1];
(*dma_buffer)[dma_index + dma_buff_offset_pos] = input_samples[index0];
(*dma_buffer)[dma_index + 1 + dma_buff_offset_pos] = input_samples[index0 + 1];
dma_index += 4;
}
@ -687,7 +680,7 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const
}
catch (const std::ifstream::failure &e)
{
std::cerr << "Exception reading file " << filename1 << '\n';
std::cerr << "Exception reading file " << filename1_ << '\n';
break;
}
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)
{
// filename2 is never the L1 band
input_samples_dma[dma_index] = input_samples[index0];
input_samples_dma[dma_index + 1] = input_samples[index0 + 1];
(*dma_buffer)[dma_index] = input_samples[index0];
(*dma_buffer)[dma_index + 1] = input_samples[index0 + 1];
dma_index += 4;
}
}
if (nread_elements > 0)
{
num_transferred_bytes = 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)
if (dma_fpga->DMA_write(nread_elements * 2))
{
std::cerr << "Error: DMA could not send all the required samples\n";
break;
}
// Throttle the DMA
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)
{
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;
}
@ -748,11 +738,11 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const
}
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;
}
if (!filename1.empty())
if (!filename1_.empty())
{
try
{
@ -760,7 +750,7 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const
}
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;
}
@ -770,7 +760,7 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const
}
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;
}
}
@ -789,18 +779,17 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const
lock.unlock();
}
if (close(tx_fd) < 0)
if (dma_fpga->DMA_close())
{
std::cerr << "Error closing loop device " << '\n';
}
try
{
infile1.close();
}
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)
@ -811,7 +800,7 @@ void Ad9361FpgaSignalSource::run_DMA_process(const std::string &filename0, const
}
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 "fpga_buffer_monitor.h"
#include "fpga_dma.h"
#include "fpga_dynamic_bit_selection.h"
#include "fpga_switch.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_rf_port_select = std::string("A_BALANCED");
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_manual_gain_rx1 = 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_dynamic_bit_selection> dynamic_bit_selection_fpga;
std::shared_ptr<Fpga_buffer_monitor> buffer_monitor_fpga;
std::shared_ptr<Fpga_DMA> dma_fpga;
std::mutex dma_mutex;
std::mutex dynamic_bit_selection_mutex;
@ -118,8 +121,8 @@ private:
std::string filter_file_;
std::string filter_source_;
std::string filter_filename_;
std::string filename0;
std::string filename1;
std::string filename0_;
std::string filename1_;
double rf_gain_rx1_;
double rf_gain_rx2_;

View File

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

View File

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

View File

@ -21,6 +21,7 @@
#include "configuration_interface.h"
#include "gnss_sdr_string_literals.h"
#include "gnss_sdr_valve.h"
#include <boost/exception/diagnostic_information.hpp>
#include <glog/logging.h>
#include <cstdint>
#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_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_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} fpga_dma.cc)
set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} fpga_dma.h)
endif()
set(SIGNAL_SOURCE_LIB_SOURCES

View File

@ -61,7 +61,7 @@ public:
void check_buffer_overflow_and_monitor_buffer_status();
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 num_sapmples_per_buffer_element = 2;
// 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);
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_FPGA = 4; // Number of bits after the bit selection

View File

@ -54,7 +54,7 @@ public:
void set_switch_position(int32_t switch_position);
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 MAX_LENGTH_DEVICEIO_NAME = 50;

View File

@ -29,8 +29,6 @@
#include <glog/logging.h>
#include <array>
using google::LogMessage;
BeidouB3iDllPllTracking::BeidouB3iDllPllTracking(
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)

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_carrier_doppler_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_acc_carrier_phase_cycles(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 ##########################################################
// 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_carrier_doppler_old_hz = d_carrier_doppler_hz;
d_carrier_frequency_old_hz = d_carrier_frequency_hz;
// Carrier discriminator filter
// NOTICE: The carrier loop filter includes the Carrier Doppler accumulator, as described in Kaplan
// 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]
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
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 discriminator
@ -716,12 +717,12 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __at
// ################### PLL COMMANDS #################################################
// 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;
// UPDATE ACCUMULATED CARRIER PHASE
CORRECTED_INTEGRATION_TIME_S = (static_cast<double>(d_correlation_length_samples) / static_cast<double>(d_fs_in));
// 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 #################################################
// 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_carrier_doppler_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_acc_carrier_phase_cycles;
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_carrier_doppler_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_acc_carrier_phase_cycles(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 ##########################################################
// 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_carrier_doppler_old_hz = d_carrier_doppler_hz;
d_carrier_frequency_old_hz = d_carrier_frequency_hz;
// Carrier discriminator filter
// NOTICE: The carrier loop filter includes the Carrier Doppler accumulator, as described in Kaplan
// 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]
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
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 discriminator
@ -716,12 +717,12 @@ int glonass_l1_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __at
// ################### PLL COMMANDS #################################################
// 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;
// UPDATE ACCUMULATED CARRIER PHASE
CORRECTED_INTEGRATION_TIME_S = (static_cast<double>(d_correlation_length_samples) / static_cast<double>(d_fs_in));
// 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 #################################################
// 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_carrier_doppler_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_acc_carrier_phase_cycles;
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_carrier_doppler_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_acc_carrier_phase_cycles(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 ##########################################################
// 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_carrier_doppler_old_hz = d_carrier_doppler_hz;
d_carrier_frequency_old_hz = d_carrier_frequency_hz;
// Carrier discriminator filter
// NOTICE: The carrier loop filter includes the Carrier Doppler accumulator, as described in Kaplan
// 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]
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
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 discriminator
@ -714,12 +715,12 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_cc::general_work(int noutput_items __at
//################### PLL COMMANDS #################################################
// 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;
// UPDATE ACCUMULATED CARRIER PHASE
CORRECTED_INTEGRATION_TIME_S = (static_cast<double>(d_correlation_length_samples) / static_cast<double>(d_fs_in));
// 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 #################################################
// 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_carrier_doppler_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_acc_carrier_phase_cycles;
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_carrier_doppler_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_acc_carrier_phase_cycles(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 ##########################################################
// 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_carrier_doppler_old_hz = d_carrier_doppler_hz;
d_carrier_frequency_old_hz = d_carrier_frequency_hz;
// Carrier discriminator filter
// NOTICE: The carrier loop filter includes the Carrier Doppler accumulator, as described in Kaplan
// 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]
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
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 discriminator
@ -713,12 +714,12 @@ int glonass_l2_ca_dll_pll_c_aid_tracking_sc::general_work(int noutput_items __at
// ################### PLL COMMANDS #################################################
// 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;
// UPDATE ACCUMULATED CARRIER PHASE
CORRECTED_INTEGRATION_TIME_S = (static_cast<double>(d_correlation_length_samples) / static_cast<double>(d_fs_in));
// 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 #################################################
// 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_carrier_doppler_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_acc_carrier_phase_cycles;
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;
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));
if (d_map_base == reinterpret_cast<void *>(-1))
@ -402,7 +402,7 @@ void Fpga_Multicorrelator_8sc::unlock_channel()
void Fpga_Multicorrelator_8sc::close_device()
{
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";
}

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 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 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 local_code_fpga_clear_address_counter = 0x10000000;
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;
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));
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
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";
}

View File

@ -49,7 +49,7 @@ public:
private:
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)
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)
{
// Maybe the file is from https://www.gsc-europa.eu/system-status/almanac-data ?
// Maybe the file is from https://www.gsc-europa.eu/product-almanacs ?
return this->read_gal_almanac_from_gsa(file_name);
}
LOG(INFO) << "Loaded Galileo almanac map data with " << this->gal_almanac_map.size() << " satellites";

View File

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