mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2024-12-15 04:30:33 +00:00
Merge branch 'next' into ssr
This commit is contained in:
commit
06315477c3
7
AUTHORS
7
AUTHORS
@ -17,13 +17,13 @@ Contact Information
|
||||
|
||||
CTTC Homepage
|
||||
----------------------------
|
||||
http://www.cttc.cat
|
||||
https://www.cttc.cat
|
||||
|
||||
|
||||
Mailing List
|
||||
----------------------------
|
||||
gnss-sdr-developers@lists.sourceforge.net
|
||||
https://lists.sourceforge.net/lists/listinfo/gnss-sdr-developers
|
||||
https://sourceforge.net/projects/gnss-sdr/lists/gnss-sdr-developers
|
||||
|
||||
|
||||
Email
|
||||
@ -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>
|
||||
|
@ -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"
|
||||
|
@ -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 "")
|
||||
|
23
README.md
23
README.md
@ -170,6 +170,9 @@ Please note that the required files from `libgtest-dev` were moved to
|
||||
again to `libgtest-dev` in Debian 10 "buster" and Ubuntu 18.10 "cosmic" (and
|
||||
above).
|
||||
|
||||
Since Ubuntu 21.04 Hirsute / Debian 11, the package `libcpu-features-dev` is
|
||||
also required.
|
||||
|
||||
**Note for Ubuntu 14.04 LTS "trusty" users:** you will need to build from source
|
||||
and install GNU Radio manually, as explained below, since GNSS-SDR requires
|
||||
`gnuradio-dev` >= 3.7.3, and Ubuntu 14.04 came with 3.7.2. Install all the
|
||||
@ -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ández-Prades, J. Arribas, P. Closas, C. Avilés, and L.
|
||||
Esteve,
|
||||
[GNSS-SDR: an open source tool for researchers and developers](http://www.cttc.es/publication/gnss-sdr-an-open-source-tool-for-researchers-and-developers/),
|
||||
[GNSS-SDR: an open source tool for researchers and developers](https://www.researchgate.net/publication/233380791_GNSS-SDR_An_open_source_tool_for_researchers_and_developers),
|
||||
in Proceedings of the 24th International Technical Meeting of The Satellite
|
||||
Division of the Institute of Navigation (ION GNSS), Portland, Oregon, Sept.
|
||||
19-23, 2011, pp. 780-794.
|
||||
|
@ -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()
|
||||
|
91
cmake/Modules/FindCPUFEATURES.cmake
Normal file
91
cmake/Modules/FindCPUFEATURES.cmake
Normal 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)
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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]
|
||||
|
||||
|
@ -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/
|
||||
|
||||
|
||||
|
||||
## [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
|
||||
|
@ -584,10 +584,10 @@ but if you distribute the code, it has to remain under GPL.
|
||||
If you use GNSS-SDR to produce a research paper or Thesis, we would appreciate
|
||||
if you reference any of these articles to credit the GNSS-SDR project:
|
||||
|
||||
\li \anchor Navitec2012 C. Fernández-Prades, J. Arribas, L. Esteve, D. Pubill, P. Closas, <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á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ècnica de Catalunya, Barcelona, Spain, June 2012.
|
||||
\li C. Fernández-Prades, J. Arribas, P. Closas, C. Avilé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ández-Prades, C. Avilé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ández-Prades, J. Arribas, P. Closas, C. Avilé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ández-Prades, C. Avilé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:
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -32,8 +32,6 @@ namespace own = std;
|
||||
namespace own = gsl;
|
||||
#endif
|
||||
|
||||
using google::LogMessage;
|
||||
|
||||
BeidouB3iPcpsAcquisition::BeidouB3iPcpsAcquisition(
|
||||
const ConfigurationInterface* configuration,
|
||||
const std::string& role,
|
||||
|
@ -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";
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -203,4 +203,4 @@ by Carles Fernández-Prades and Javier Arribas. This software is released
|
||||
under the GNU General Public License version 3, see the file COPYING.
|
||||
|
||||
This project is managed by
|
||||
[Centre Tecnològic de Telecomunicacions de Catalunya](http://www.cttc.es "CTTC webpage").
|
||||
[Centre Tecnològic de Telecomunicacions de Catalunya](https://www.cttc.cat "CTTC webpage").
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
```
|
||||
|
@ -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 ""
|
||||
|
@ -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_
|
||||
|
@ -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_
|
||||
|
||||
|
@ -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_
|
||||
|
||||
|
@ -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_
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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_
|
||||
|
@ -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_
|
||||
|
||||
|
@ -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_
|
||||
|
||||
|
@ -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_
|
||||
|
@ -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_
|
||||
|
@ -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_
|
||||
|
@ -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_
|
||||
|
@ -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}"
|
||||
|
@ -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
|
||||
|
@ -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];
|
||||
}
|
@ -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];
|
||||
}
|
@ -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];
|
||||
}
|
@ -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];
|
||||
}
|
@ -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
|
@ -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_
|
@ -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;
|
||||
}
|
@ -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
|
||||
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
File diff suppressed because it is too large
Load Diff
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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)
|
||||
|
@ -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()
|
||||
|
@ -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)");
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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';
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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_;
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
134
src/algorithms/signal_source/libs/fpga_dma.cc
Normal file
134
src/algorithms/signal_source/libs/fpga_dma.cc
Normal 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
|
||||
}
|
101
src/algorithms/signal_source/libs/fpga_dma.h
Normal file
101
src/algorithms/signal_source/libs/fpga_dma.h
Normal 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
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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]
|
||||
|
@ -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;
|
||||
|
@ -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]
|
||||
|
@ -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;
|
||||
|
@ -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]
|
||||
|
@ -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;
|
||||
|
@ -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]
|
||||
|
@ -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;
|
||||
|
@ -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";
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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";
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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";
|
||||
|
@ -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
@ -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_ */
|
@ -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);
|
||||
}
|
||||
}
|
@ -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_ */
|
@ -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 */
|
@ -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_ */
|
@ -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
@ -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;
|
||||
}
|
@ -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_ */
|
@ -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_ */
|
@ -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_ */
|
@ -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
Loading…
Reference in New Issue
Block a user