Merge with next

This commit is contained in:
Javier Arribas 2021-07-30 15:42:29 +02:00
commit 29f59256be
62 changed files with 1239 additions and 395 deletions

View File

@ -11,7 +11,7 @@ if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
message(FATAL_ERROR "Prevented in-tree build, it is bad practice.\nTry 'cd build && cmake ..' instead.")
endif()
cmake_minimum_required(VERSION 2.8.12...3.20)
cmake_minimum_required(VERSION 2.8.12...3.21)
project(gnss-sdr CXX C)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules)
@ -323,7 +323,7 @@ set(GNSSSDR_PROTOBUF_MIN_VERSION "3.0.0")
################################################################################
set(GNSSSDR_GFLAGS_LOCAL_VERSION "2.2.2")
set(GNSSSDR_GLOG_LOCAL_VERSION "0.5.0")
set(GNSSSDR_ARMADILLO_LOCAL_VERSION "10.5.x")
set(GNSSSDR_ARMADILLO_LOCAL_VERSION "10.6.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")
@ -488,6 +488,10 @@ if(NOT (${CMAKE_SYSTEM_NAME} MATCHES "Darwin"))
include(TestForARM)
endif()
endif()
else()
if(CMAKE_SYSTEM_PROCESSOR MATCHES "(^aarch64)|(arm64)")
set(IS_ARM TRUE)
endif()
endif()
################################################################################
@ -633,6 +637,12 @@ if(NOT (GNURADIO_VERSION VERSION_LESS 3.8) AND LOG4CPP_READY_FOR_CXX17)
# UHD 4.0.0.0 still does not support C++20
if((NOT UHD_FOUND) OR (UHD_FOUND AND ("${UHD_VERSION}" VERSION_LESS 3.99)))
set(CMAKE_CXX_STANDARD 20)
if(CMAKE_VERSION VERSION_GREATER 3.20.99)
if(((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "11.0.0")) OR
((CMAKE_CXX_COMPILER_ID STREQUAL "Clang") AND NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "12.0")))
set(CMAKE_CXX_STANDARD 23)
endif()
endif()
endif()
endif()
set(CMAKE_CXX_STANDARD_REQUIRED ON)
@ -1462,7 +1472,9 @@ if(NOT GLOG_FOUND OR ${LOCAL_GFLAGS})
message(STATUS " glog v${GNSSSDR_GLOG_LOCAL_VERSION} will be downloaded, built, and statically linked automatically")
message(STATUS " when doing '${CMAKE_MAKE_PROGRAM_PRETTY_NAME}'.")
if(NOT ${LOCAL_GFLAGS})
add_library(gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} UNKNOWN IMPORTED)
if(NOT TARGET gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION})
add_library(gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} UNKNOWN IMPORTED)
endif()
set_property(TARGET gflags-${GNSSSDR_GFLAGS_LOCAL_VERSION} PROPERTY IMPORTED_LOCATION "${GFlags_LIBS}")
string(REPLACE /include "" GFLAGS_PREFIX_PATH ${GFlags_INCLUDE_DIRS})
else()
@ -1499,6 +1511,10 @@ if(NOT GLOG_FOUND OR ${LOCAL_GFLAGS})
set(GLOG_EXPORT_C_COMPILER "export CC=clang")
set(GLOG_EXPORT_CXX_COMPILER "export CXX=clang++")
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(GLOG_EXPORT_C_COMPILER "export CC=gcc")
set(GLOG_EXPORT_CXX_COMPILER "export CXX=g++")
endif()
file(WRITE ${CMAKE_BINARY_DIR}/glog-${GNSSSDR_GLOG_LOCAL_VERSION}/tmp/configure_with_gflags
"#!/bin/sh
export CPPFLAGS=-I${GFlags_INCLUDE_DIRS}
@ -3197,17 +3213,13 @@ if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND NOT WIN32)
endif()
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
if(NOT ENABLE_GENERIC_ARCH)
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
add_compile_options(-march=native)
else()
if(IS_ARM)
# ARM-specific options
if(NOT CMAKE_CROSSCOMPILING AND NOT CMAKE_TOOLCHAIN_FILE)
add_compile_options(-mcpu=native)
endif()
else()
add_compile_options(-march=native)
if(IS_ARM)
# ARM-specific options
if(NOT CMAKE_CROSSCOMPILING AND NOT CMAKE_TOOLCHAIN_FILE)
add_compile_options(-mcpu=native)
endif()
else()
add_compile_options(-march=native)
endif()
endif()
endif()

View File

@ -355,9 +355,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 http://sourceforge.net/projects/arma/files/armadillo-10.5.0.tar.xz
$ tar xvfz armadillo-10.5.0.tar.xz
$ cd armadillo-10.5.0
$ wget http://sourceforge.net/projects/arma/files/armadillo-10.6.1.tar.xz
$ tar xvfz armadillo-10.6.1.tar.xz
$ cd armadillo-10.6.1
$ cmake .
$ make
$ sudo make install

View File

@ -255,7 +255,7 @@ endif()
cmake_pop_check_state()
set(FILESYSTEM_FOUND ${_found} CACHE BOOL "TRUE if we can compile and link a program using std::filesystem" FORCE)
set(FILESYSTEM_FOUND ${_found})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(FILESYSTEM DEFAULT_MSG FILESYSTEM_FOUND)

View File

@ -50,6 +50,8 @@ All notable changes to GNSS-SDR will be documented in this file.
files make use of the new parameters' names.
- Update GSL implementation to 0.38.1. See
https://github.com/gsl-lite/gsl-lite/releases/tag/v0.38.1
- Update references to the latest GPS ICDs (IS-GPS-200M, IS-GPS-800H,
IS-GPS-705H) published in May, 2021.
### Improvements in Portability:
@ -60,6 +62,8 @@ All notable changes to GNSS-SDR will be documented in this file.
version of `volk_gnsssdr`. When this building option is set to `ON`, it forces
the building of the local version of the `cpu_features` library, regardless of
whether it is already installed or not.
- CMake's `<policy_max>` version bumped to 3.21. The minimum CMake version is
2.8.12.
- Fix building when using the Xcode generator, Xcode >= 12 and CMake >= 3.19.
- Fix building of FPGA blocks when linking against GNU Radio >= 3.9 and/or
Boost >= 1.74.
@ -67,6 +71,15 @@ All notable changes to GNSS-SDR will be documented in this file.
3.8.
- If the Matio library is not found, now it is configured and built by CMake
instead of using autotools.
- Added support for Apple M1 AArch64 architecture processor and for FreeBSD on
x86, improved AMD microarchitecture detection.
- CMake now selects the C++23 standard if the environment allows for it.
### Improvements in Reliability
- Check satellites' health status. If a satellite is marked as not healthy in
its navigation message, the corresponding observables are not used for
navigation.
### Improvements in Usability:
@ -98,7 +111,7 @@ All notable changes to GNSS-SDR will be documented in this file.
- Fix bug in searching for gr-iio when CMake was re-run several times with
different settings for the `-DENABLE_FMCOMMS2` or `-DENABLE_PLUTOSDR` building
options.
- Fix building when using UHD v4.0.0.0.
- Fix building when using UHD >= v4.0.0.0.
- Fix building for `-DENABLE_FMCOMMS2=ON` and/or `-DENABLE_PLUTOSDR=ON` when the
built-in gr-iio module introduced in GNU Radio 3.10 is found. This in-tree GNU
Radio module takes precedence over the gr-iio package provided at
@ -108,6 +121,8 @@ All notable changes to GNSS-SDR will be documented in this file.
- New global configuration parameter `GNSS-SDR.observable_interval_ms`, set by
default to 20 [ms], allows to control the internal rate at which computed
observables sets are processed (50 observables sets per second by default).
- Fix bug in the `Monitor.decimation_factor` parameter, which was not working
properly for other values than 1.
See the definitions of concepts and metrics at
https://gnss-sdr.org/design-forces/

View File

@ -12,9 +12,9 @@
All the current GPS Interface Control Documents can be downloaded from <a href="https://www.gps.gov" target="_blank">GPS.gov</a>, the official U.S. Government webpage for GPS.
\li GPS L1 and L2C: Global Positioning System Directorate, <a href="https://www.gps.gov/technical/icwg/IS-GPS-200L.pdf" target="_blank"><b>Interface Specification IS-GPS-200 Revision L</b></a>. May, 2020.
\li GPS L1C (available with first Block III launch): Global Positioning System Directorate, <a href="https://www.gps.gov/technical/icwg/IS-GPS-800G.pdf" target="_blank"><b>Interface Specification IS-GPS-800 Revision G</b></a>. May, 2020.
\li GPS L5 (first Block IIF satellite launched on May, 2010): Global Positioning System Directorate, <a href="https://www.gps.gov/technical/icwg/IS-GPS-705G.pdf" target="_blank"><b>Interface Specification IS-GPS-705 Revision G</b></a>. May, 2020.
\li GPS L1 and L2C: Global Positioning System Directorate, <a href="https://www.gps.gov/technical/icwg/IS-GPS-200M.pdf" target="_blank"><b>Interface Specification IS-GPS-200 Revision M</b></a>. May, 2021.
\li GPS L1C (available with first Block III launch): Global Positioning System Directorate, <a href="https://www.gps.gov/technical/icwg/IS-GPS-800H.pdf" target="_blank"><b>Interface Specification IS-GPS-800 Revision H</b></a>. May, 2021.
\li GPS L5 (first Block IIF satellite launched on May, 2010): Global Positioning System Directorate, <a href="https://www.gps.gov/technical/icwg/IS-GPS-705H.pdf" target="_blank"><b>Interface Specification IS-GPS-705 Revision H</b></a>. May, 2021.

View File

@ -62,7 +62,7 @@ and civilian users on a continuous, worldwide basis. Two GPS services are provid
the Precise Positioning Service (PPS), available primarily to the military of the United
States and its allies, and the Standard Positioning Service (SPS) open to civilian users.
\li <b>GPS L1</b>. Defined at <a href="https://www.gps.gov/technical/icwg/IS-GPS-200L.pdf" target="_blank"><b>Interface Specification IS-GPS-200 Revision L</b></a>, this band is centered at \f$f_{\text{GPS L1}}=1575.42\f$ MHz. The complex baseband transmitted signal can be written as
\li <b>GPS L1</b>. Defined at <a href="https://www.gps.gov/technical/icwg/IS-GPS-200M.pdf" target="_blank"><b>Interface Specification IS-GPS-200 Revision M</b></a>, this band is centered at \f$f_{\text{GPS L1}}=1575.42\f$ MHz. The complex baseband transmitted signal can be written as
\f{equation}{
s^{\text{(GPS L1)}}_{T}(t)=e_{L1I}(t) + j e_{L1Q}(t)~,
\f}
@ -76,12 +76,12 @@ s^{\text{(GPS L1)}}_{T}(t)=e_{L1I}(t) + j e_{L1Q}(t)~,
\f$L_{\text{P(Y)}}=6.1871 \cdot 10^{12}\f$, and \f$p(t)\f$ is a rectangular pulse of a chip-period duration centered at \f$t=0\f$ and filtered at the transmitter.
According to the chip rate, the binary phase-shift keying modulations in the equations above are denoted as BPSK(10) and BPSK(1), respectively. The precision P codes (named Y codes whenever
the anti-spoofing mode is activated, encrypting the code and thus denying non-U.S. military users) are sequences of \f$7\f$ days in length. Regarding the modernization plans for GPS, it
is worthwhile to mention that there is a new civilian-use signal planned, called L1C and defined at <a href="https://www.gps.gov/technical/icwg/IS-GPS-800G.pdf" target="_blank"><b>Interface Specification IS-GPS-800 Revision G</b></a>,
to be broadcast on the same L1 frequency that currently contains the C/A signal. The L1C will be available with first Block III launch, currently scheduled for 2013. The implementation will
provide C/A code to ensure backward compatibility.
is worthwhile to mention that there is a new civilian-use signal planned, called L1C and defined at <a href="https://www.gps.gov/technical/icwg/IS-GPS-800H.pdf" target="_blank"><b>Interface Specification IS-GPS-800 Revision H</b></a>,
to be broadcast on the same L1 frequency that currently contains the C/A signal. The L1C is available with first Block III launch. The implementation
provides C/A code to ensure backward compatibility.
\li <b>GPS L2C</b>. Defined at <a href="https://www.gps.gov/technical/icwg/IS-GPS-200L.pdf" target="_blank"><b>Interface Specification IS-GPS-200 Revision L</b></a>, is only available on
\li <b>GPS L2C</b>. Defined at <a href="https://www.gps.gov/technical/icwg/IS-GPS-200M.pdf" target="_blank"><b>Interface Specification IS-GPS-200 Revision M</b></a>, is only available on
Block IIR-M and subsequent satellite blocks. Centered at \f$f_{\text{GPS L2}}=1227.60\f$ MHz, the signal structure is the same than in (\ref{eq:GPSL1}), with the precision code in the In-phase
component, just as in (\ref{eq:L1CAI}) but with an optional presence of the navigation message \f$D_{\text{NAV}}\f$. For the Quadrature-phase component, three options are defined:
\f{align}{ e_{L2CQ}(t) =& \sum_{l=-\infty}^{\infty} D_{\text{CNAV}} \Big[ [l]_{10230} \Big] \oplus \left( C_{\text{CL}} \Big[ |l|_{L_{\text{CL}}} \Big] p_{\text{\tiny{1/2}}} \left( t - lT_{c,L2C} \right) + \right.\\ {} &+ \left. C_{\text{CM}} \Big[ |l|_{L_{\text{CM}}} \Big] p_{\text{\tiny{1/2}}}\left(t - \left(l+\frac{3}{4}\right)T_{c,L2C}\right) \right),\\
@ -94,7 +94,7 @@ component, just as in (\ref{eq:L1CAI}) but with an optional presence of the navi
data than the NAV data. It is transmitted at \f$25\f$ bps with forward error correction (FEC) encoding, resulting in \f$50\f$ sps.
\li <b>GPS L5</b>. The GPS L5 link, defined at <a href="https://www.gps.gov/technical/icwg/IS-GPS-705G.pdf" target="_blank"><b>Interface Specification IS-GPS-705 Revision G</b></a>, is only available
\li <b>GPS L5</b>. The GPS L5 link, defined at <a href="https://www.gps.gov/technical/icwg/IS-GPS-705H.pdf" target="_blank"><b>Interface Specification IS-GPS-705 Revision H</b></a>, is only available
in Block IIF (first satellite launched on May, 2010) and subsequent satellite blocks. Centered at \f$f_{\text{GPS L5}}=1176.45\f$ MHz, this signal in space can be written as:
\f{equation}{
s^{\text{(GPS L5)}}_{T}(t)=e_{L5I}(t) +j e_{L5Q}(t)~,

View File

@ -39,7 +39,7 @@ message GpsEphemeris {
// GPS-specific parameters
int32 code_on_L2 = 26; // If 1, P code ON in L2; if 2, C/A code ON in L2;
bool L2_P_data_flag = 27; // When true, indicates that the NAV data stream was commanded OFF on the P-code of the L2 channel
int32 SV_accuracy = 28; // User Range Accuracy (URA) index of the SV (reference paragraph 6.2.1) for the standard positioning service user (Ref 20.3.3.3.1.3 IS-GPS-200L)
int32 SV_accuracy = 28; // User Range Accuracy (URA) index of the SV (reference paragraph 6.2.1) for the standard positioning service user (Ref 20.3.3.3.1.3 IS-GPS-200M)
int32 SV_health = 29; // Satellite heath status
double TGD = 30; // Estimated Group Delay Differential: L1-L2 correction term only for the benefit of "L1 P(Y)" or "L2 P(Y)" s users [s]
int32 IODC = 31; // Issue of Data, Clock

View File

@ -32,6 +32,7 @@
#include "glonass_gnav_ephemeris.h"
#include "glonass_gnav_utc_model.h"
#include "gnss_frequencies.h"
#include "gnss_satellite.h"
#include "gnss_sdr_create_directory.h"
#include "gnss_sdr_filesystem.h"
#include "gnss_sdr_make_unique.h"
@ -137,7 +138,7 @@ rtklib_pvt_gs::rtklib_pvt_gs(uint32_t nchannels,
d_display_rate_ms = conf_.display_rate_ms;
d_report_rate_ms = 1000; // report every second PVT to gnss_synchro
d_dump = conf_.dump;
d_dump_mat = conf_.dump_mat and d_dump;
d_dump_mat = conf_.dump_mat && d_dump;
d_dump_filename = conf_.dump_filename;
std::string dump_ls_pvt_filename = conf_.dump_filename;
if (d_dump)
@ -259,7 +260,7 @@ rtklib_pvt_gs::rtklib_pvt_gs(uint32_t nchannels,
}
// initialize nmea_printer
d_nmea_output_file_enabled = (conf_.nmea_output_file_enabled or conf_.flag_nmea_tty_port);
d_nmea_output_file_enabled = (conf_.nmea_output_file_enabled || conf_.flag_nmea_tty_port);
d_nmea_rate_ms = conf_.nmea_rate_ms;
if (d_nmea_rate_ms == 0)
{
@ -277,7 +278,7 @@ rtklib_pvt_gs::rtklib_pvt_gs(uint32_t nchannels,
// initialize rtcm_printer
const std::string rtcm_dump_filename = d_dump_filename;
if (conf_.flag_rtcm_server or conf_.flag_rtcm_tty_port or conf_.rtcm_output_file_enabled)
if (conf_.flag_rtcm_server || conf_.flag_rtcm_tty_port || conf_.rtcm_output_file_enabled)
{
d_rtcm_printer = std::make_unique<Rtcm_Printer>(rtcm_dump_filename, conf_.rtcm_output_file_enabled, conf_.flag_rtcm_server, conf_.flag_rtcm_tty_port, conf_.rtcm_tcp_port, conf_.rtcm_station_id, conf_.rtcm_dump_devname, true, conf_.rtcm_output_file_path);
std::map<int, int> rtcm_msg_rate_ms = conf_.rtcm_msg_rate_ms;
@ -1146,6 +1147,11 @@ void rtklib_pvt_gs::msg_handler_telemetry(const pmt::pmt_t& msg)
{
d_user_pvt_solver->gps_ephemeris_map[gps_eph->PRN] = *gps_eph;
}
if (gps_eph->SV_health != 0)
{
std::cout << TEXT_RED << "Satellite " << Gnss_Satellite(std::string("GPS"), gps_eph->PRN)
<< " is not healthy, not used for navigation" << TEXT_RESET << '\n';
}
}
else if (msg_type_hash_code == d_gps_iono_sptr_type_hash_code)
{
@ -1201,6 +1207,11 @@ void rtklib_pvt_gs::msg_handler_telemetry(const pmt::pmt_t& msg)
{
d_user_pvt_solver->gps_cnav_ephemeris_map[gps_cnav_ephemeris->PRN] = *gps_cnav_ephemeris;
}
if (gps_cnav_ephemeris->signal_health != 0)
{
std::cout << TEXT_RED << "Satellite " << Gnss_Satellite(std::string("GPS"), gps_cnav_ephemeris->PRN)
<< " is not healthy, not used for navigation" << TEXT_RESET << '\n';
}
DLOG(INFO) << "New GPS CNAV ephemeris record has arrived ";
}
else if (msg_type_hash_code == d_gps_cnav_iono_sptr_type_hash_code)
@ -1280,6 +1291,13 @@ void rtklib_pvt_gs::msg_handler_telemetry(const pmt::pmt_t& msg)
{
d_user_pvt_solver->galileo_ephemeris_map[galileo_eph->PRN] = *galileo_eph;
}
if (((galileo_eph->E1B_HS != 0) || (galileo_eph->E1B_DVS == true)) ||
((galileo_eph->E5a_HS != 0) || (galileo_eph->E5a_DVS == true)) ||
((galileo_eph->E5b_HS != 0) || (galileo_eph->E5b_DVS == true)))
{
std::cout << TEXT_RED << "Satellite " << Gnss_Satellite(std::string("Galileo"), galileo_eph->PRN)
<< " is not healthy, not used for navigation" << TEXT_RESET << '\n';
}
}
else if (msg_type_hash_code == d_galileo_iono_sptr_type_hash_code)
{
@ -1455,6 +1473,11 @@ void rtklib_pvt_gs::msg_handler_telemetry(const pmt::pmt_t& msg)
{
d_user_pvt_solver->beidou_dnav_ephemeris_map[bds_dnav_eph->PRN] = *bds_dnav_eph;
}
if (bds_dnav_eph->SV_health != 0)
{
std::cout << TEXT_RED << "Satellite " << Gnss_Satellite(std::string("Beidou"), bds_dnav_eph->PRN)
<< " is not healthy, not used for navigation" << TEXT_RESET << '\n';
}
}
else if (msg_type_hash_code == d_beidou_dnav_iono_sptr_type_hash_code)
{
@ -1928,7 +1951,7 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item
if (tmp_eph_iter_gps != d_internal_pvt_solver->gps_ephemeris_map.cend())
{
const uint32_t prn_aux = tmp_eph_iter_gps->second.PRN;
if ((prn_aux == in[i][epoch].PRN) and (std::string(in[i][epoch].Signal) == "1C"))
if ((prn_aux == in[i][epoch].PRN) && (std::string(in[i][epoch].Signal) == std::string("1C")) && (tmp_eph_iter_gps->second.SV_health == 0))
{
store_valid_observable = true;
}
@ -1936,7 +1959,10 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item
if (tmp_eph_iter_gal != d_internal_pvt_solver->galileo_ephemeris_map.cend())
{
const uint32_t prn_aux = tmp_eph_iter_gal->second.PRN;
if ((prn_aux == in[i][epoch].PRN) and ((std::string(in[i][epoch].Signal) == "1B") or (std::string(in[i][epoch].Signal) == "5X") or (std::string(in[i][epoch].Signal) == "7X")))
if ((prn_aux == in[i][epoch].PRN) &&
(((std::string(in[i][epoch].Signal) == std::string("1B")) && (tmp_eph_iter_gal->second.E1B_DVS == false) && (tmp_eph_iter_gal->second.E1B_HS == 0)) ||
((std::string(in[i][epoch].Signal) == std::string("5X")) && (tmp_eph_iter_gal->second.E5a_DVS == false) && (tmp_eph_iter_gal->second.E5a_HS == 0)) ||
((std::string(in[i][epoch].Signal) == std::string("7X")) && (tmp_eph_iter_gal->second.E5b_DVS == false) && (tmp_eph_iter_gal->second.E5b_HS == 0))))
{
store_valid_observable = true;
}
@ -1944,7 +1970,7 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item
if (tmp_eph_iter_cnav != d_internal_pvt_solver->gps_cnav_ephemeris_map.cend())
{
const uint32_t prn_aux = tmp_eph_iter_cnav->second.PRN;
if ((prn_aux == in[i][epoch].PRN) and ((std::string(in[i][epoch].Signal) == "2S") or (std::string(in[i][epoch].Signal) == "L5")))
if ((prn_aux == in[i][epoch].PRN) && (((std::string(in[i][epoch].Signal) == std::string("2S")) || (std::string(in[i][epoch].Signal) == std::string("L5"))) && (tmp_eph_iter_cnav->second.signal_health == 0)))
{
store_valid_observable = true;
}
@ -1952,7 +1978,7 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item
if (tmp_eph_iter_glo_gnav != d_internal_pvt_solver->glonass_gnav_ephemeris_map.cend())
{
const uint32_t prn_aux = tmp_eph_iter_glo_gnav->second.PRN;
if ((prn_aux == in[i][epoch].PRN) and ((std::string(in[i][epoch].Signal) == "1G") or (std::string(in[i][epoch].Signal) == "2G")))
if ((prn_aux == in[i][epoch].PRN) && ((std::string(in[i][epoch].Signal) == std::string("1G")) || (std::string(in[i][epoch].Signal) == std::string("2G"))))
{
store_valid_observable = true;
}
@ -1960,7 +1986,7 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item
if (tmp_eph_iter_bds_dnav != d_internal_pvt_solver->beidou_dnav_ephemeris_map.cend())
{
const uint32_t prn_aux = tmp_eph_iter_bds_dnav->second.PRN;
if ((prn_aux == in[i][epoch].PRN) and ((std::string(in[i][epoch].Signal) == "B1") or (std::string(in[i][epoch].Signal) == "B3")))
if ((prn_aux == in[i][epoch].PRN) && (((std::string(in[i][epoch].Signal) == std::string("B1")) || (std::string(in[i][epoch].Signal) == std::string("B3"))) && (tmp_eph_iter_bds_dnav->second.SV_health == 0)))
{
store_valid_observable = true;
}
@ -2155,7 +2181,6 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item
initialize_and_apply_carrier_phase_offset();
const double Rx_clock_offset_s = d_user_pvt_solver->get_time_offset_s();
if (d_enable_rx_clock_correction == true and fabs(Rx_clock_offset_s) > 0.000001) // 1us !!
{
LOG(INFO) << "Warning: Rx clock offset at interpolated RX time: " << Rx_clock_offset_s * 1000.0 << "[ms]"
@ -2199,15 +2224,15 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item
}
}
// TODO: RTCM 1077, 1087 and 1097 are not used, so, disable the output rates
// if (current_RX_time_ms % d_rtcm_MT1077_rate_ms==0 and d_rtcm_MT1077_rate_ms != 0)
// if (current_RX_time_ms % d_rtcm_MT1077_rate_ms==0 && d_rtcm_MT1077_rate_ms != 0)
// {
// last_RTCM_1077_output_time = current_RX_time;
// }
// if (current_RX_time_ms % d_rtcm_MT1087_rate_ms==0 and d_rtcm_MT1087_rate_ms != 0)
// if (current_RX_time_ms % d_rtcm_MT1087_rate_ms==0 && d_rtcm_MT1087_rate_ms != 0)
// {
// last_RTCM_1087_output_time = current_RX_time;
// }
// if (current_RX_time_ms % d_rtcm_MT1097_rate_ms==0 and d_rtcm_MT1097_rate_ms != 0)
// if (current_RX_time_ms % d_rtcm_MT1097_rate_ms==0 && d_rtcm_MT1097_rate_ms != 0)
// {
// last_RTCM_1097_output_time = current_RX_time;
// }
@ -2301,7 +2326,7 @@ int rtklib_pvt_gs::work(int noutput_items, gr_vector_const_void_star& input_item
}
// DEBUG MESSAGE: Display position in console output
if (d_user_pvt_solver->is_valid_position() and flag_display_pvt)
if (d_user_pvt_solver->is_valid_position() && flag_display_pvt)
{
boost::posix_time::ptime time_solution;
std::string UTC_solution_str;

View File

@ -5083,7 +5083,7 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map<int32_t, Gps
if (gps_ephemeris_iter->second.satelliteBlock.at(gps_ephemeris_iter->second.PRN) == "IIA")
{
// Block II/IIA (Table 20-XI IS-GPS-200L )
// Block II/IIA (Table 20-XI IS-GPS-200M)
if ((gps_ephemeris_iter->second.IODC > 239) && (gps_ephemeris_iter->second.IODC < 248))
{
curve_fit_interval = 8;
@ -5113,9 +5113,9 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map<int32_t, Gps
if ((gps_ephemeris_iter->second.satelliteBlock.at(gps_ephemeris_iter->second.PRN) == "IIR") ||
(gps_ephemeris_iter->second.satelliteBlock.at(gps_ephemeris_iter->second.PRN) == "IIR-M") ||
(gps_ephemeris_iter->second.satelliteBlock.at(gps_ephemeris_iter->second.PRN) == "IIF") ||
(gps_ephemeris_iter->second.satelliteBlock.at(gps_ephemeris_iter->second.PRN) == "IIIA"))
(gps_ephemeris_iter->second.satelliteBlock.at(gps_ephemeris_iter->second.PRN) == "III"))
{
// Block IIR/IIR-M/IIF/IIIA (Table 20-XII IS-GPS-200L )
// Block IIR/IIR-M/IIF/III/IIIF (Table 20-XII IS-GPS-200M)
if ((gps_ephemeris_iter->second.IODC > 239) && (gps_ephemeris_iter->second.IODC < 248))
{
curve_fit_interval = 8;
@ -5202,7 +5202,7 @@ void Rinex_Printer::log_rinex_nav(std::fstream& out, const std::map<int32_t, Gps
line += std::string(5, ' ');
// If there is no IODE in CNAV, so we check if Toe in message Type 10, Toe in Message type 11 and Toc in message types 30-37.
// Whenever these three terms do not match, a data set cutover has occurred and new data must be collected.
// See IS-GPS-200L, p. 155
// See IS-GPS-200M, paragraph 20.3.3.4.1
if (!((gps_ephemeris_iter->second.toe1 == gps_ephemeris_iter->second.toe2) && (gps_ephemeris_iter->second.toe1 == gps_ephemeris_iter->second.toc))) // Toe1: Toe in message type 10, Toe2: Toe in message type 11
{
// Toe1: Toe in message type 10, Toe2: Toe in message type 11,

View File

@ -20,7 +20,7 @@
#include <array>
#include <cmath> // for sin, cos, sqrt, abs, pow
const double STRP_PI = 3.1415926535898; // Pi as defined in IS-GPS-200L
const double STRP_PI = 3.1415926535898; // Pi as defined in IS-GPS-200M, 30.3.3.1.3
arma::mat Skew_symmetric(const arma::vec &a)
{

View File

@ -1734,7 +1734,7 @@ double timediff(gtime_t t1, gtime_t t2)
*-----------------------------------------------------------------------------*/
double timediffweekcrossover(gtime_t t1, gtime_t t2)
{
// as stated in IS-GPS-200L table 20-IV footnote among other parts of the ICD,
// as stated in IS-GPS-200M table 20-IV footnote among other parts of the ICD,
// if tk=(t - toe) > 302400s then tk = tk - s
// if tk=(t - toe) < -302400s then tk = tk + 604800s
double tk = difftime(t1.time, t2.time) + t1.sec - t2.sec;

View File

@ -29,8 +29,8 @@
*
*
* References :
* [1] IS-GPS-200L, Navstar GPS Space Segment/Navigation User Interfaces,
* 7 March, 2006
* [1] IS-GPS-200M, Navstar GPS Space Segment/Navigation User Interfaces,
* May, 2021
* [2] RTCA/DO-229C, Minimum operational performanc standards for global
* positioning system/wide area augmentation system airborne equipment,
* RTCA inc, November 28, 2001

View File

@ -5,7 +5,14 @@
*.pyo
html/
build/
cmake_build/
cmake-build-*/
out/
.project
.cproject
.vagrant/
.vscode/
.vs/
*.swp
/.DS_Store
/gen/volk_gnsssdr_arch_defs.py

View File

@ -8,7 +8,7 @@
########################################################################
# Project setup
########################################################################
cmake_minimum_required(VERSION 2.8.12...3.20)
cmake_minimum_required(VERSION 2.8.12...3.21)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
endif()
@ -134,6 +134,12 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_CXX_STANDARD 17)
else()
set(CMAKE_CXX_STANDARD 20)
if(CMAKE_VERSION VERSION_GREATER 3.20.99)
if(((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "11.0.0")) OR
((CMAKE_CXX_COMPILER_ID STREQUAL "Clang") AND NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "12.0")))
set(CMAKE_CXX_STANDARD 23)
endif()
endif()
endif()
set(CMAKE_CXX_STANDARD_REQUIRED ON)
else()
@ -253,9 +259,9 @@ endif()
set(SUPPORTED_CPU_FEATURES_ARCH FALSE)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips")
set(SUPPORTED_CPU_FEATURES_ARCH TRUE)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(^aarch64)|(arm64)")
set(SUPPORTED_CPU_FEATURES_ARCH TRUE)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^aarch64")
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)

View File

@ -253,7 +253,7 @@ endif()
cmake_pop_check_state()
set(FILESYSTEM_FOUND ${_found} CACHE BOOL "TRUE if we can compile and link a program using std::filesystem" FORCE)
set(FILESYSTEM_FOUND ${_found})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(FILESYSTEM DEFAULT_MSG FILESYSTEM_FOUND)

View File

@ -41,6 +41,8 @@ if(GIT_FOUND)
OUTPUT_STRIP_TRAILING_WHITESPACE
)
endif()
# Sanitize branch name
string(REGEX REPLACE "[#!?&|/^$%*]" "_" GIT_BRANCH "${GIT_BRANCH}")
set(VOLK_GNSSSDR_GIT_BRANCH "${GIT_BRANCH}")
set(VOLK_GNSSSDR_GIT_HASH "${GIT_COMMIT_HASH}")
else()
@ -51,6 +53,8 @@ else()
endif()
if(GIT_BRANCH)
# Sanitize branch name
string(REGEX REPLACE "[#!?&|/^$%*]" "_" GIT_BRANCH "${GIT_BRANCH}")
set(VOLK_GNSSSDR_GIT_BRANCH "${GIT_BRANCH}")
else()
set(VOLK_GNSSSDR_GIT_BRANCH "unknown")

View File

@ -63,10 +63,10 @@ set(PROCESSOR_IS_POWER FALSE)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips")
set(PROCESSOR_IS_MIPS TRUE)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(^aarch64)|(arm64)")
set(PROCESSOR_IS_AARCH64 TRUE)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm")
set(PROCESSOR_IS_ARM TRUE)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^aarch64")
set(PROCESSOR_IS_AARCH64 TRUE)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(x86_64)|(AMD64|amd64)|(^i.86$)")
set(PROCESSOR_IS_X86 TRUE)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)")
@ -152,10 +152,8 @@ set_property(TARGET cpu_features PROPERTY POSITION_INDEPENDENT_CODE ${BUILD_PIC}
target_include_directories(cpu_features
PUBLIC $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/cpu_features>
)
if(PROCESSOR_IS_X86)
if(APPLE)
target_compile_definitions(cpu_features PRIVATE HAVE_SYSCTLBYNAME)
endif()
if(APPLE AND (PROCESSOR_IS_X86 OR PROCESSOR_IS_AARCH64))
target_compile_definitions(cpu_features PRIVATE HAVE_SYSCTLBYNAME)
endif()
add_library(CpuFeature::cpu_features ALIAS cpu_features)

View File

@ -157,13 +157,14 @@ flags : aes,avx,cx16,smx,sse4_1,sse4_2,ssse3
## What's supported
| | x86³ | ARM | AArch64 | MIPS⁴ | POWER |
| ------- | :--: | :-----: | :-----: | :---: | :---: |
| Android | yes² | yes¹ | yes¹ | yes¹ | N/A |
| iOS | N/A | not yet | not yet | N/A | N/A |
| Linux | yes² | yes¹ | yes¹ | yes¹ | yes¹ |
| MacOs | yes² | N/A | not yet | N/A | no |
| Windows | yes² | not yet | not yet | N/A | N/A |
| | x86³ | ARM | AArch64 | MIPS⁴ | POWER |
| ------- | :--: | :-----: | :-----: | :-----: | :-----: |
| Android | yes² | yes¹ | yes¹ | yes¹ | N/A |
| iOS | N/A | not yet | not yet | N/A | N/A |
| Linux | yes² | yes¹ | yes¹ | yes¹ | yes¹ |
| MacOS | yes² | N/A | yes² | N/A | no |
| Windows | yes² | not yet | not yet | N/A | N/A |
| FreeBSD | yes² | not yet | not yet | not yet | not yet |
1. **Features revealed from Linux.** We gather data from several sources
depending on availability:
@ -193,7 +194,7 @@ supporting Android and offers a drop in replacement of for the NDK's
## License
The cpu_features library is licensed under the terms of the Apache license. See
[LICENSE](LICENSE) for more information.
[LICENSE](https://www.apache.org/licenses/LICENSE-2.0.txt) for more information.
<a name="cmake"></a>

View File

@ -33,5 +33,7 @@ your executable or of your library.
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](../.travis.yml) and [appveyor.yml](../appveyor.yml) have up to
date examples.
[.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.

View File

@ -29,7 +29,7 @@
#define CPU_FEATURES_ARCH_ARM
#endif
#if defined(__aarch64__)
#if (defined(__aarch64__) || (defined(__APPLE__) && defined(__arm64__)))
#define CPU_FEATURES_ARCH_AARCH64
#endif
@ -73,6 +73,10 @@
#define CPU_FEATURES_OS_DARWIN
#endif
#if (defined(__freebsd__) || defined(__FreeBSD__))
#define CPU_FEATURES_OS_FREEBSD
#endif
////////////////////////////////////////////////////////////////////////////////
// Compilers
////////////////////////////////////////////////////////////////////////////////
@ -205,4 +209,17 @@
#endif // defined(__mips_msa)
#endif // defined(CPU_FEATURES_ARCH_MIPS)
////////////////////////////////////////////////////////////////////////////////
// Utils
////////////////////////////////////////////////////////////////////////////////
// Communicates to the compiler that the block is unreachable
#if defined(CPU_FEATURES_COMPILER_CLANG) || defined(CPU_FEATURES_COMPILER_GCC)
#define UNREACHABLE() __builtin_unreachable()
#elif defined(CPU_FEATURES_COMPILER_MSC)
#define UNREACHABLE() __assume(0)
#else
#define UNREACHABLE()
#endif
#endif // CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_

View File

@ -7,7 +7,6 @@
#include "cpu_features_cache_info.h"
#include "cpu_features_macros.h"
#include "internal/hwcaps.h"
CPU_FEATURES_START_CPP_NAMESPACE
@ -66,13 +65,19 @@ typedef struct
// This function is guaranteed to be malloc, memset and memcpy free.
PPCInfo GetPPCInfo(void);
typedef struct
{
char platform[64]; // 0 terminated string
char base_platform[64]; // 0 terminated string
} PPCPlatformTypeStrings;
typedef struct
{
char platform[64]; // 0 terminated string
char model[64]; // 0 terminated string
char machine[64]; // 0 terminated string
char cpu[64]; // 0 terminated string
PlatformType type;
PPCPlatformTypeStrings type;
} PPCPlatformStrings;
PPCPlatformStrings GetPPCPlatformStrings(void);

View File

@ -105,32 +105,40 @@ 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
AMD_K10, // K10
AMD_BOBCAT, // K14
AMD_BULLDOZER, // K15
AMD_JAGUAR, // K16
AMD_ZEN, // K17
AMD_ZEN3, // K19
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
} X86Microarchitecture;
// Returns the underlying microarchitecture by looking at X86Info's vendor,

View File

@ -161,17 +161,19 @@ typedef struct
unsigned long hwcaps2;
} HardwareCapabilities;
// Retrieves values from auxiliary vector for types AT_HWCAP and AT_HWCAP2.
// First tries to call getauxval(), if not available falls back to reading
// "/proc/self/auxv".
HardwareCapabilities CpuFeatures_GetHardwareCapabilities(void);
// Checks whether value for AT_HWCAP (or AT_HWCAP2) match hwcaps_mask.
bool CpuFeatures_IsHwCapsSet(const HardwareCapabilities hwcaps_mask,
const HardwareCapabilities hwcaps);
typedef struct
{
char platform[64]; // 0 terminated string
char base_platform[64]; // 0 terminated string
} PlatformType;
PlatformType CpuFeatures_GetPlatformType(void);
// Get pointer for the AT_PLATFORM type.
const char* CpuFeatures_GetPlatformPointer(void);
// Get pointer for the AT_BASE_PLATFORM type.
const char* CpuFeatures_GetBasePlatformPointer(void);
CPU_FEATURES_END_CPP_NAMESPACE

View File

@ -9,6 +9,33 @@
#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 \
@ -67,6 +94,8 @@
#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)
{
@ -120,6 +149,8 @@ static void FillProcCpuInfoData(Aarch64Info* const info)
}
}
#endif /* !CPU_FEATURES_OS_DARWIN */
static const Aarch64Info kEmptyAarch64Info;
Aarch64Info GetAarch64Info(void)
@ -129,6 +160,24 @@ Aarch64Info GetAarch64Info(void)
// /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)
@ -139,6 +188,8 @@ Aarch64Info GetAarch64Info(void)
}
}
#endif
return info;
}

View File

@ -137,9 +137,23 @@ static const PPCPlatformStrings kEmptyPPCPlatformStrings;
PPCPlatformStrings GetPPCPlatformStrings(void)
{
PPCPlatformStrings strings = kEmptyPPCPlatformStrings;
const char* platform = CpuFeatures_GetPlatformPointer();
const char* base_platform = CpuFeatures_GetBasePlatformPointer();
FillProcCpuInfoData(&strings);
strings.type = CpuFeatures_GetPlatformType();
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;
}

View File

@ -84,7 +84,8 @@
// microarchitectures.
#if defined(CPU_FEATURES_OS_WINDOWS)
#include <windows.h> // IsProcessorFeaturePresent
#elif defined(CPU_FEATURES_OS_LINUX_OR_ANDROID)
#elif defined(CPU_FEATURES_OS_LINUX_OR_ANDROID) || \
defined(CPU_FEATURES_OS_FREEBSD)
#include "internal/filesystem.h" // Needed to parse /proc/cpuinfo
#include "internal/stack_line_reader.h" // Needed to parse /proc/cpuinfo
#include "internal/string_view.h" // Needed to parse /proc/cpuinfo
@ -200,9 +201,9 @@ static bool HasYmmOsXSave(uint32_t xcr0_eax)
return HasMask(xcr0_eax, MASK_XMM | MASK_YMM);
}
#if !defined(CPU_FEATURES_OS_DARWIN)
// Checks that operating system saves and restores zmm registers during context
// switches.
#if !defined(CPU_FEATURES_OS_DARWIN)
static bool HasZmmOsXSave(uint32_t xcr0_eax)
{
return HasMask(xcr0_eax, MASK_XMM | MASK_YMM | MASK_MASKREG | MASK_ZMM0_15 |
@ -1205,45 +1206,11 @@ static bool GetDarwinSysCtlByName(const char* name)
// Avoid to recompute them since each call to cpuid is ~100 cycles.
typedef struct
{
bool have_sse_via_os;
bool have_sse_via_cpuid;
bool have_avx;
bool have_avx512;
bool have_amx;
} OsSupport;
static const OsSupport kEmptyOsSupport;
static OsSupport CheckOsSupport(const uint32_t max_cpuid_leaf)
{
const Leaf leaf_1 = SafeCpuId(max_cpuid_leaf, 1);
const bool have_xsave = IsBitSet(leaf_1.ecx, 26);
const bool have_osxsave = IsBitSet(leaf_1.ecx, 27);
const bool have_xcr0 = have_xsave && have_osxsave;
OsSupport os_support = kEmptyOsSupport;
if (have_xcr0)
{
// AVX capable cpu will expose XCR0.
const uint32_t xcr0_eax = GetXCR0Eax();
os_support.have_sse_via_cpuid = HasXmmOsXSave(xcr0_eax);
os_support.have_avx = HasYmmOsXSave(xcr0_eax);
#if defined(CPU_FEATURES_OS_DARWIN)
os_support.have_avx512 = GetDarwinSysCtlByName("hw.optional.avx512f");
#else
os_support.have_avx512 = HasZmmOsXSave(xcr0_eax);
#endif // CPU_FEATURES_OS_DARWIN
os_support.have_amx = HasTmmOsXSave(xcr0_eax);
}
else
{
// Atom based or older cpus need to ask the OS for sse support.
os_support.have_sse_via_os = true;
}
return os_support;
}
bool sse_registers;
bool avx_registers;
bool avx512_registers;
bool amx_registers;
} OsPreserves;
#if defined(CPU_FEATURES_OS_WINDOWS)
#if defined(CPU_FEATURES_MOCK_CPUID_X86)
@ -1256,66 +1223,18 @@ static bool GetWindowsIsProcessorFeaturePresent(DWORD ProcessorFeature)
#endif
#endif // CPU_FEATURES_OS_WINDOWS
static void DetectSseViaOs(X86Features* features)
{
#if defined(CPU_FEATURES_OS_WINDOWS)
// https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-isprocessorfeaturepresent
features->sse =
GetWindowsIsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE);
features->sse2 =
GetWindowsIsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE);
features->sse3 =
GetWindowsIsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE);
#elif defined(CPU_FEATURES_OS_DARWIN)
// Handling Darwin platform through sysctlbyname.
features->sse = GetDarwinSysCtlByName("hw.optional.sse");
features->sse2 = GetDarwinSysCtlByName("hw.optional.sse2");
features->sse3 = GetDarwinSysCtlByName("hw.optional.sse3");
features->ssse3 = GetDarwinSysCtlByName("hw.optional.supplementalsse3");
features->sse4_1 = GetDarwinSysCtlByName("hw.optional.sse4_1");
features->sse4_2 = GetDarwinSysCtlByName("hw.optional.sse4_2");
#elif defined(CPU_FEATURES_OS_LINUX_OR_ANDROID)
// Handling Linux platform through /proc/cpuinfo.
const int fd = CpuFeatures_OpenFile("/proc/cpuinfo");
if (fd >= 0)
{
StackLineReader reader;
StackLineReader_Initialize(&reader, fd);
for (;;)
{
const LineResult result = StackLineReader_NextLine(&reader);
const StringView line = result.line;
StringView key, value;
if (CpuFeatures_StringView_GetAttributeKeyValue(line, &key, &value))
{
if (CpuFeatures_StringView_IsEquals(key, str("flags")))
{
features->sse = CpuFeatures_StringView_HasWord(value, "sse");
features->sse2 = CpuFeatures_StringView_HasWord(value, "sse2");
features->sse3 = CpuFeatures_StringView_HasWord(value, "sse3");
features->ssse3 = CpuFeatures_StringView_HasWord(value, "ssse3");
features->sse4_1 = CpuFeatures_StringView_HasWord(value, "sse4_1");
features->sse4_2 = CpuFeatures_StringView_HasWord(value, "sse4_2");
break;
}
}
if (result.eof) break;
}
CpuFeatures_CloseFile(fd);
}
#else
#error "Unsupported fallback detection of SSE OS support."
#endif
}
// Reference https://en.wikipedia.org/wiki/CPUID.
static void ParseCpuId(const uint32_t max_cpuid_leaf,
const OsSupport os_support, X86Info* info)
static void ParseCpuId(const uint32_t max_cpuid_leaf, X86Info* info,
OsPreserves* os_preserves)
{
const Leaf leaf_1 = SafeCpuId(max_cpuid_leaf, 1);
const Leaf leaf_7 = SafeCpuId(max_cpuid_leaf, 7);
const Leaf leaf_7_1 = SafeCpuIdEx(max_cpuid_leaf, 7, 1);
const bool have_xsave = IsBitSet(leaf_1.ecx, 26);
const bool have_osxsave = IsBitSet(leaf_1.ecx, 27);
const bool have_xcr0 = have_xsave && have_osxsave;
const uint32_t family = ExtractBitRange(leaf_1.eax, 11, 8);
const uint32_t extended_family = ExtractBitRange(leaf_1.eax, 27, 20);
const uint32_t model = ExtractBitRange(leaf_1.eax, 7, 4);
@ -1356,61 +1275,182 @@ static void ParseCpuId(const uint32_t max_cpuid_leaf,
features->vpclmulqdq = IsBitSet(leaf_7.ecx, 10);
features->adx = IsBitSet(leaf_7.ebx, 19);
if (os_support.have_sse_via_os)
{
DetectSseViaOs(features);
}
else if (os_support.have_sse_via_cpuid)
{
features->sse = IsBitSet(leaf_1.edx, 25);
features->sse2 = IsBitSet(leaf_1.edx, 26);
features->sse3 = IsBitSet(leaf_1.ecx, 0);
features->ssse3 = IsBitSet(leaf_1.ecx, 9);
features->sse4_1 = IsBitSet(leaf_1.ecx, 19);
features->sse4_2 = IsBitSet(leaf_1.ecx, 20);
}
/////////////////////////////////////////////////////////////////////////////
// The following section is devoted to Vector Extensions.
/////////////////////////////////////////////////////////////////////////////
if (os_support.have_avx)
// CPU with AVX expose XCR0 which enables checking vector extensions OS
// support through cpuid.
if (have_xcr0)
{
features->fma3 = IsBitSet(leaf_1.ecx, 12);
features->avx = IsBitSet(leaf_1.ecx, 28);
features->avx2 = IsBitSet(leaf_7.ebx, 5);
}
// Here we rely exclusively on cpuid for both CPU and OS support of vector
// extensions.
const uint32_t xcr0_eax = GetXCR0Eax();
os_preserves->sse_registers = HasXmmOsXSave(xcr0_eax);
os_preserves->avx_registers = HasYmmOsXSave(xcr0_eax);
#if defined(CPU_FEATURES_OS_DARWIN)
// On Darwin AVX512 support is On-demand.
// We have to query the OS instead of querying the Zmm save/restore state.
// https://github.com/apple/darwin-xnu/blob/8f02f2a044b9bb1ad951987ef5bab20ec9486310/osfmk/i386/fpu.c#L173-L199
os_preserves->avx512_registers =
GetDarwinSysCtlByName("hw.optional.avx512f");
#else
os_preserves->avx512_registers = HasZmmOsXSave(xcr0_eax);
#endif // CPU_FEATURES_OS_DARWIN
os_preserves->amx_registers = HasTmmOsXSave(xcr0_eax);
if (os_support.have_avx512)
{
features->avx512f = IsBitSet(leaf_7.ebx, 16);
features->avx512cd = IsBitSet(leaf_7.ebx, 28);
features->avx512er = IsBitSet(leaf_7.ebx, 27);
features->avx512pf = IsBitSet(leaf_7.ebx, 26);
features->avx512bw = IsBitSet(leaf_7.ebx, 30);
features->avx512dq = IsBitSet(leaf_7.ebx, 17);
features->avx512vl = IsBitSet(leaf_7.ebx, 31);
features->avx512ifma = IsBitSet(leaf_7.ebx, 21);
features->avx512vbmi = IsBitSet(leaf_7.ecx, 1);
features->avx512vbmi2 = IsBitSet(leaf_7.ecx, 6);
features->avx512vnni = IsBitSet(leaf_7.ecx, 11);
features->avx512bitalg = IsBitSet(leaf_7.ecx, 12);
features->avx512vpopcntdq = IsBitSet(leaf_7.ecx, 14);
features->avx512_4vnniw = IsBitSet(leaf_7.edx, 2);
features->avx512_4vbmi2 = IsBitSet(leaf_7.edx, 3);
features->avx512_second_fma = HasSecondFMA(info->model);
features->avx512_4fmaps = IsBitSet(leaf_7.edx, 3);
features->avx512_bf16 = IsBitSet(leaf_7_1.eax, 5);
features->avx512_vp2intersect = IsBitSet(leaf_7.edx, 8);
if (os_preserves->sse_registers)
{
features->sse = IsBitSet(leaf_1.edx, 25);
features->sse2 = IsBitSet(leaf_1.edx, 26);
features->sse3 = IsBitSet(leaf_1.ecx, 0);
features->ssse3 = IsBitSet(leaf_1.ecx, 9);
features->sse4_1 = IsBitSet(leaf_1.ecx, 19);
features->sse4_2 = IsBitSet(leaf_1.ecx, 20);
}
if (os_preserves->avx_registers)
{
features->fma3 = IsBitSet(leaf_1.ecx, 12);
features->avx = IsBitSet(leaf_1.ecx, 28);
features->avx2 = IsBitSet(leaf_7.ebx, 5);
}
if (os_preserves->avx512_registers)
{
features->avx512f = IsBitSet(leaf_7.ebx, 16);
features->avx512cd = IsBitSet(leaf_7.ebx, 28);
features->avx512er = IsBitSet(leaf_7.ebx, 27);
features->avx512pf = IsBitSet(leaf_7.ebx, 26);
features->avx512bw = IsBitSet(leaf_7.ebx, 30);
features->avx512dq = IsBitSet(leaf_7.ebx, 17);
features->avx512vl = IsBitSet(leaf_7.ebx, 31);
features->avx512ifma = IsBitSet(leaf_7.ebx, 21);
features->avx512vbmi = IsBitSet(leaf_7.ecx, 1);
features->avx512vbmi2 = IsBitSet(leaf_7.ecx, 6);
features->avx512vnni = IsBitSet(leaf_7.ecx, 11);
features->avx512bitalg = IsBitSet(leaf_7.ecx, 12);
features->avx512vpopcntdq = IsBitSet(leaf_7.ecx, 14);
features->avx512_4vnniw = IsBitSet(leaf_7.edx, 2);
features->avx512_4vbmi2 = IsBitSet(leaf_7.edx, 3);
features->avx512_second_fma = HasSecondFMA(info->model);
features->avx512_4fmaps = IsBitSet(leaf_7.edx, 3);
features->avx512_bf16 = IsBitSet(leaf_7_1.eax, 5);
features->avx512_vp2intersect = IsBitSet(leaf_7.edx, 8);
}
if (os_preserves->amx_registers)
{
features->amx_bf16 = IsBitSet(leaf_7.edx, 22);
features->amx_tile = IsBitSet(leaf_7.edx, 24);
features->amx_int8 = IsBitSet(leaf_7.edx, 25);
}
}
if (os_support.have_amx)
else
{
features->amx_bf16 = IsBitSet(leaf_7.edx, 22);
features->amx_tile = IsBitSet(leaf_7.edx, 24);
features->amx_int8 = IsBitSet(leaf_7.edx, 25);
// When XCR0 is not available (Atom based or older cpus) we need to defer to
// the OS via custom code.
#if defined(CPU_FEATURES_OS_WINDOWS)
// Handling Windows platform through IsProcessorFeaturePresent.
// https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-isprocessorfeaturepresent
features->sse =
GetWindowsIsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE);
features->sse2 =
GetWindowsIsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE);
features->sse3 =
GetWindowsIsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE);
#elif defined(CPU_FEATURES_OS_DARWIN)
// Handling Darwin platform through sysctlbyname.
features->sse = GetDarwinSysCtlByName("hw.optional.sse");
features->sse2 = GetDarwinSysCtlByName("hw.optional.sse2");
features->sse3 = GetDarwinSysCtlByName("hw.optional.sse3");
features->ssse3 = GetDarwinSysCtlByName("hw.optional.supplementalsse3");
features->sse4_1 = GetDarwinSysCtlByName("hw.optional.sse4_1");
features->sse4_2 = GetDarwinSysCtlByName("hw.optional.sse4_2");
#elif defined(CPU_FEATURES_OS_FREEBSD)
// Handling FreeBSD platform through parsing /var/run/dmesg.boot.
const int fd = CpuFeatures_OpenFile("/var/run/dmesg.boot");
if (fd >= 0)
{
StackLineReader reader;
StackLineReader_Initialize(&reader, fd);
for (;;)
{
const LineResult result = StackLineReader_NextLine(&reader);
const StringView line = result.line;
const bool is_feature =
CpuFeatures_StringView_StartsWith(line, str(" Features="));
const bool is_feature2 =
CpuFeatures_StringView_StartsWith(line, str(" Features2="));
if (is_feature || is_feature2)
{
// Lines of interests are of the following form:
// " Features=0x1783fbff<PSE36,MMX,FXSR,SSE,SSE2,HTT>"
// We replace '<', '>' and ',' with space so we can search by
// whitespace separated word.
// TODO: Fix CpuFeatures_StringView_HasWord to allow for different
// separators.
for (size_t i = 0; i < line.size; ++i)
{
char* c = (char*)(&(line.ptr[i]));
if (*c == '<' || *c == '>' || *c == ',') *c = ' ';
}
if (is_feature)
{
features->sse = CpuFeatures_StringView_HasWord(line, "SSE");
features->sse2 = CpuFeatures_StringView_HasWord(line, "SSE2");
}
if (is_feature2)
{
features->sse3 = CpuFeatures_StringView_HasWord(line, "SSE3");
features->ssse3 = CpuFeatures_StringView_HasWord(line, "SSSE3");
features->sse4_1 = CpuFeatures_StringView_HasWord(line, "SSE4.1");
features->sse4_2 = CpuFeatures_StringView_HasWord(line, "SSE4.2");
}
}
if (result.eof) break;
}
CpuFeatures_CloseFile(fd);
}
#elif defined(CPU_FEATURES_OS_LINUX_OR_ANDROID)
// Handling Linux platform through /proc/cpuinfo.
const int fd = CpuFeatures_OpenFile("/proc/cpuinfo");
if (fd >= 0)
{
StackLineReader reader;
StackLineReader_Initialize(&reader, fd);
for (;;)
{
const LineResult result = StackLineReader_NextLine(&reader);
const StringView line = result.line;
StringView key, value;
if (CpuFeatures_StringView_GetAttributeKeyValue(line, &key, &value))
{
if (CpuFeatures_StringView_IsEquals(key, str("flags")))
{
features->sse = CpuFeatures_StringView_HasWord(value, "sse");
features->sse2 = CpuFeatures_StringView_HasWord(value, "sse2");
features->sse3 = CpuFeatures_StringView_HasWord(value, "sse3");
features->ssse3 = CpuFeatures_StringView_HasWord(value, "ssse3");
features->sse4_1 = CpuFeatures_StringView_HasWord(value, "sse4_1");
features->sse4_2 = CpuFeatures_StringView_HasWord(value, "sse4_2");
break;
}
}
if (result.eof) break;
}
CpuFeatures_CloseFile(fd);
}
#else
#error "Unsupported fallback detection of SSE OS support."
#endif
// Now that we have queried the OS for SSE support, we report this back to
// os_preserves. This is needed in case of AMD CPU's to enable testing of
// sse4a (See ParseExtraAMDCpuId below).
if (features->sse) os_preserves->sse_registers = true;
}
}
// Reference
// https://en.wikipedia.org/wiki/CPUID#EAX=80000000h:_Get_Highest_Extended_Function_Implemented.
static void ParseExtraAMDCpuId(X86Info* info, OsSupport os_support)
static void ParseExtraAMDCpuId(X86Info* info, OsPreserves os_preserves)
{
const Leaf leaf_80000000 = CpuId(0x80000000);
const uint32_t max_extended_cpuid_leaf = leaf_80000000.eax;
@ -1418,12 +1458,12 @@ static void ParseExtraAMDCpuId(X86Info* info, OsSupport os_support)
X86Features* const features = &info->features;
if (os_support.have_sse_via_cpuid)
if (os_preserves.sse_registers)
{
features->sse4a = IsBitSet(leaf_80000001.ecx, 6);
}
if (os_support.have_avx)
if (os_preserves.avx_registers)
{
features->fma4 = IsBitSet(leaf_80000001.ecx, 16);
}
@ -1431,6 +1471,7 @@ static void ParseExtraAMDCpuId(X86Info* info, OsSupport os_support)
static const X86Info kEmptyX86Info;
static const CacheInfo kEmptyCacheInfo;
static const OsPreserves kEmptyOsPreserves;
X86Info GetX86Info(void)
{
@ -1438,15 +1479,16 @@ X86Info GetX86Info(void)
const Leaf leaf_0 = CpuId(0);
const bool is_intel = IsVendor(leaf_0, "GenuineIntel");
const bool is_amd = IsVendor(leaf_0, "AuthenticAMD");
const bool is_hygon = IsVendor(leaf_0, "HygonGenuine");
SetVendor(leaf_0, info.vendor);
if (is_intel || is_amd)
if (is_intel || is_amd || is_hygon)
{
OsPreserves os_preserves = kEmptyOsPreserves;
const uint32_t max_cpuid_leaf = leaf_0.eax;
const OsSupport os_support = CheckOsSupport(max_cpuid_leaf);
ParseCpuId(max_cpuid_leaf, os_support, &info);
if (is_amd)
ParseCpuId(max_cpuid_leaf, &info, &os_preserves);
if (is_amd || is_hygon)
{
ParseExtraAMDCpuId(&info, os_support);
ParseExtraAMDCpuId(&info, os_preserves);
}
}
return info;
@ -1473,8 +1515,10 @@ X86Microarchitecture GetX86Microarchitecture(const X86Info* info)
{
switch (CPUID(info->family, info->model))
{
case CPUID(0x06, 0x1C): // Intel(R) Atom(TM) CPU 230 @ 1.60GHz
case CPUID(0x06, 0x35):
case CPUID(0x06, 0x36):
case CPUID(0x06, 0x70): // https://en.wikichip.org/wiki/intel/atom/230
// https://en.wikipedia.org/wiki/Bonnell_(microarchitecture)
return INTEL_ATOM_BNL;
case CPUID(0x06, 0x37):
@ -1574,27 +1618,122 @@ X86Microarchitecture GetX86Microarchitecture(const X86Info* info)
}
if (memcmp(info->vendor, "AuthenticAMD", sizeof(info->vendor)) == 0)
{
switch (info->family)
switch (CPUID(info->family, info->model))
{
// https://en.wikipedia.org/wiki/List_of_AMD_CPU_microarchitectures
case 0x0F:
// https://en.wikichip.org/wiki/amd/cpuid
case CPUID(0xF, 0x04):
case CPUID(0xF, 0x05):
case CPUID(0xF, 0x07):
case CPUID(0xF, 0x08):
case CPUID(0xF, 0x0C):
case CPUID(0xF, 0x0E):
case CPUID(0xF, 0x0F):
case CPUID(0xF, 0x14):
case CPUID(0xF, 0x15):
case CPUID(0xF, 0x17):
case CPUID(0xF, 0x18):
case CPUID(0xF, 0x1B):
case CPUID(0xF, 0x1C):
case CPUID(0xF, 0x1F):
case CPUID(0xF, 0x21):
case CPUID(0xF, 0x23):
case CPUID(0xF, 0x24):
case CPUID(0xF, 0x25):
case CPUID(0xF, 0x27):
case CPUID(0xF, 0x2B):
case CPUID(0xF, 0x2C):
case CPUID(0xF, 0x2F):
case CPUID(0xF, 0x41):
case CPUID(0xF, 0x43):
case CPUID(0xF, 0x48):
case CPUID(0xF, 0x4B):
case CPUID(0xF, 0x4C):
case CPUID(0xF, 0x4F):
case CPUID(0xF, 0x5D):
case CPUID(0xF, 0x5F):
case CPUID(0xF, 0x68):
case CPUID(0xF, 0x6B):
case CPUID(0xF, 0x6F):
case CPUID(0xF, 0x7F):
case CPUID(0xF, 0xC1):
return AMD_HAMMER;
case 0x10:
case CPUID(0x10, 0x02):
case CPUID(0x10, 0x04):
case CPUID(0x10, 0x05):
case CPUID(0x10, 0x06):
case CPUID(0x10, 0x08):
case CPUID(0x10, 0x09):
case CPUID(0x10, 0x0A):
return AMD_K10;
case 0x14:
case CPUID(0x11, 0x03):
// http://developer.amd.com/wordpress/media/2012/10/41788.pdf
return AMD_K11;
case CPUID(0x12, 0x01):
// https://www.amd.com/system/files/TechDocs/44739_12h_Rev_Gd.pdf
return AMD_K12;
case CPUID(0x14, 0x00):
case CPUID(0x14, 0x01):
case CPUID(0x14, 0x02):
// https://www.amd.com/system/files/TechDocs/47534_14h_Mod_00h-0Fh_Rev_Guide.pdf
return AMD_BOBCAT;
case 0x15:
case CPUID(0x15, 0x01):
// https://en.wikichip.org/wiki/amd/microarchitectures/bulldozer
return AMD_BULLDOZER;
case 0x16:
case CPUID(0x15, 0x02):
case CPUID(0x15, 0x11):
case CPUID(0x15, 0x13):
// https://en.wikichip.org/wiki/amd/microarchitectures/piledriver
return AMD_PILEDRIVER;
case CPUID(0x15, 0x30):
case CPUID(0x15, 0x38):
// https://en.wikichip.org/wiki/amd/microarchitectures/steamroller
return AMD_STREAMROLLER;
case CPUID(0x15, 0x60):
case CPUID(0x15, 0x65):
case CPUID(0x15, 0x70):
// https://en.wikichip.org/wiki/amd/microarchitectures/excavator
return AMD_EXCAVATOR;
case CPUID(0x16, 0x00):
return AMD_JAGUAR;
case 0x17:
case CPUID(0x16, 0x30):
return AMD_PUMA;
case CPUID(0x17, 0x01):
case CPUID(0x17, 0x11):
case CPUID(0x17, 0x18):
case CPUID(0x17, 0x20):
// https://en.wikichip.org/wiki/amd/microarchitectures/zen
return AMD_ZEN;
case 0x19:
case CPUID(0x17, 0x08):
// https://en.wikichip.org/wiki/amd/microarchitectures/zen%2B
return AMD_ZEN_PLUS;
case CPUID(0x17, 0x31):
case CPUID(0x17, 0x47):
case CPUID(0x17, 0x60):
case CPUID(0x17, 0x68):
case CPUID(0x17, 0x71):
case CPUID(0x17, 0x90):
case CPUID(0x17, 0x98):
// https://en.wikichip.org/wiki/amd/microarchitectures/zen_2
return AMD_ZEN2;
case CPUID(0x19, 0x01):
case CPUID(0x19, 0x21):
case CPUID(0x19, 0x30):
case CPUID(0x19, 0x40):
case CPUID(0x19, 0x50):
// https://en.wikichip.org/wiki/amd/microarchitectures/zen_3
return AMD_ZEN3;
default:
return X86_UNKNOWN;
}
}
if (memcmp(info->vendor, "HygonGenuine", sizeof(info->vendor)) == 0)
{
switch (CPUID(info->family, info->model))
{
case CPUID(0x18, 0x00):
return AMD_ZEN;
}
}
return X86_UNKNOWN;
}
@ -1681,14 +1820,30 @@ const char* GetX86MicroarchitectureName(X86Microarchitecture uarch)
return "AMD_HAMMER";
case AMD_K10:
return "AMD_K10";
case AMD_K11:
return "AMD_K11";
case AMD_K12:
return "AMD_K12";
case AMD_BOBCAT:
return "AMD_BOBCAT";
case AMD_PILEDRIVER:
return "AMD_PILEDRIVER";
case AMD_STREAMROLLER:
return "AMD_STREAMROLLER";
case AMD_EXCAVATOR:
return "AMD_EXCAVATOR";
case AMD_BULLDOZER:
return "AMD_BULLDOZER";
case AMD_PUMA:
return "AMD_PUMA";
case AMD_JAGUAR:
return "AMD_JAGUAR";
case AMD_ZEN:
return "AMD_ZEN";
case AMD_ZEN_PLUS:
return "AMD_ZEN_PLUS";
case AMD_ZEN2:
return "AMD_ZEN2";
case AMD_ZEN3:
return "AMD_ZEN3";
}

View File

@ -24,7 +24,8 @@ bool CpuFeatures_IsHwCapsSet(const HardwareCapabilities hwcaps_mask,
#ifdef CPU_FEATURES_TEST
// In test mode, hwcaps_for_testing will define the following functions.
HardwareCapabilities CpuFeatures_GetHardwareCapabilities(void);
PlatformType CpuFeatures_GetPlatformType(void);
const char* CpuFeatures_GetPlatformPointer(void);
const char* CpuFeatures_GetBasePlatformPointer(void);
#else
// Debug facilities
@ -170,21 +171,14 @@ HardwareCapabilities CpuFeatures_GetHardwareCapabilities(void)
return capabilities;
}
PlatformType kEmptyPlatformType;
PlatformType CpuFeatures_GetPlatformType(void)
const char *CpuFeatures_GetPlatformPointer(void)
{
PlatformType type = kEmptyPlatformType;
char *platform = (char *)GetHardwareCapabilitiesFor(AT_PLATFORM);
char *base_platform = (char *)GetHardwareCapabilitiesFor(AT_BASE_PLATFORM);
return (const char *)GetHardwareCapabilitiesFor(AT_PLATFORM);
}
if (platform != NULL)
CpuFeatures_StringView_CopyString(str(platform), type.platform,
sizeof(type.platform));
if (base_platform != NULL)
CpuFeatures_StringView_CopyString(str(base_platform), type.base_platform,
sizeof(type.base_platform));
return type;
const char *CpuFeatures_GetBasePlatformPointer(void)
{
return (const char *)GetHardwareCapabilitiesFor(AT_BASE_PLATFORM);
}
#endif // CPU_FEATURES_TEST

View File

@ -362,9 +362,8 @@ static Node* GetCacheTypeString(CacheType cache_type)
return CreateConstantString("stlb");
case CPU_FEATURE_CACHE_PREFETCH:
return CreateConstantString("prefetch");
default:
return CreateConstantString("null");
}
UNREACHABLE();
}
static void AddCacheInfo(Node* root, const CacheInfo* cache_info)

View File

@ -69,6 +69,10 @@ 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()
target_link_libraries(cpuinfo_aarch64_test all_libraries)
add_test(NAME cpuinfo_aarch64_test COMMAND cpuinfo_aarch64_test)
endif()

View File

@ -10,10 +10,134 @@ namespace cpu_features
{
namespace
{
void DisableHardwareCapabilities() { SetHardwareCapabilities(0, 0); }
#if defined(CPU_FEATURES_OS_DARWIN)
class FakeCpu
{
public:
bool GetDarwinSysCtlByName(std::string name) const
{
return darwin_sysctlbyname_.count(name);
}
int GetDarwinSysCtlByNameValue(std::string name) const
{
std::map<std::string, int>::const_iterator iter =
darwin_sysctlbynamevalue_.find(name);
if (iter != std::end(darwin_sysctlbynamevalue_))
{
return iter->second;
}
return 0;
}
void SetDarwinSysCtlByName(std::string name)
{
darwin_sysctlbyname_.insert(name);
}
void SetDarwinSysCtlByNameValue(std::string name, int value)
{
darwin_sysctlbynamevalue_[name] = value;
}
private:
std::set<std::string> darwin_sysctlbyname_;
std::map<std::string, int> darwin_sysctlbynamevalue_;
};
FakeCpu* g_fake_cpu = nullptr;
extern "C" bool GetDarwinSysCtlByName(const char* name)
{
return g_fake_cpu->GetDarwinSysCtlByName(name);
}
extern "C" int GetDarwinSysCtlByNameValue(const char* name)
{
return g_fake_cpu->GetDarwinSysCtlByNameValue(name);
}
class CpuinfoAarch64Test : public ::testing::Test
{
protected:
void SetUp() override { g_fake_cpu = new FakeCpu(); }
void TearDown() override { delete g_fake_cpu; }
};
TEST_F(CpuinfoAarch64Test, FromDarwinSysctlFromName)
{
g_fake_cpu->SetDarwinSysCtlByName("hw.optional.floatingpoint");
g_fake_cpu->SetDarwinSysCtlByName("hw.optional.neon");
g_fake_cpu->SetDarwinSysCtlByName("hw.optional.neon_hpfp");
g_fake_cpu->SetDarwinSysCtlByName("hw.optional.neon_fp16");
g_fake_cpu->SetDarwinSysCtlByName("hw.optional.armv8_1_atomics");
g_fake_cpu->SetDarwinSysCtlByName("hw.optional.armv8_crc32");
g_fake_cpu->SetDarwinSysCtlByName("hw.optional.armv8_2_fhm");
g_fake_cpu->SetDarwinSysCtlByName("hw.optional.armv8_2_sha512");
g_fake_cpu->SetDarwinSysCtlByName("hw.optional.armv8_2_sha3");
g_fake_cpu->SetDarwinSysCtlByName("hw.optional.amx_version");
g_fake_cpu->SetDarwinSysCtlByName("hw.optional.ucnormal_mem");
g_fake_cpu->SetDarwinSysCtlByName("hw.optional.arm64");
g_fake_cpu->SetDarwinSysCtlByNameValue("hw.cputype", 16777228);
g_fake_cpu->SetDarwinSysCtlByNameValue("hw.cpusubtype", 2);
g_fake_cpu->SetDarwinSysCtlByNameValue("hw.cpu64bit", 1);
g_fake_cpu->SetDarwinSysCtlByNameValue("hw.cpufamily", 458787763);
g_fake_cpu->SetDarwinSysCtlByNameValue("hw.cpusubfamily", 2);
const auto info = GetAarch64Info();
EXPECT_EQ(info.implementer, 0x100000C);
EXPECT_EQ(info.variant, 2);
EXPECT_EQ(info.part, 0x1B588BB3);
EXPECT_EQ(info.revision, 2);
EXPECT_TRUE(info.features.fp);
EXPECT_FALSE(info.features.asimd);
EXPECT_FALSE(info.features.evtstrm);
EXPECT_FALSE(info.features.aes);
EXPECT_FALSE(info.features.pmull);
EXPECT_FALSE(info.features.sha1);
EXPECT_FALSE(info.features.sha2);
EXPECT_TRUE(info.features.crc32);
EXPECT_TRUE(info.features.atomics);
EXPECT_TRUE(info.features.fphp);
EXPECT_FALSE(info.features.asimdhp);
EXPECT_FALSE(info.features.cpuid);
EXPECT_FALSE(info.features.asimdrdm);
EXPECT_FALSE(info.features.jscvt);
EXPECT_FALSE(info.features.fcma);
EXPECT_FALSE(info.features.lrcpc);
EXPECT_FALSE(info.features.dcpop);
EXPECT_TRUE(info.features.sha3);
EXPECT_FALSE(info.features.sm3);
EXPECT_FALSE(info.features.sm4);
EXPECT_FALSE(info.features.asimddp);
EXPECT_TRUE(info.features.sha512);
EXPECT_FALSE(info.features.sve);
EXPECT_TRUE(info.features.asimdfhm);
EXPECT_FALSE(info.features.dit);
EXPECT_FALSE(info.features.uscat);
EXPECT_FALSE(info.features.ilrcpc);
EXPECT_FALSE(info.features.flagm);
EXPECT_FALSE(info.features.ssbs);
EXPECT_FALSE(info.features.sb);
EXPECT_FALSE(info.features.paca);
EXPECT_FALSE(info.features.pacg);
}
#else
void DisableHardwareCapabilities()
{
SetHardwareCapabilities(0, 0);
}
TEST(CpuinfoAarch64Test, FromHardwareCap)
{
ResetHwcaps();
SetHardwareCapabilities(AARCH64_HWCAP_FP | AARCH64_HWCAP_AES, 0);
GetEmptyFilesystem(); // disabling /proc/cpuinfo
const auto info = GetAarch64Info();
@ -53,6 +177,7 @@ TEST(CpuinfoAarch64Test, FromHardwareCap)
TEST(CpuinfoAarch64Test, FromHardwareCap2)
{
ResetHwcaps();
SetHardwareCapabilities(AARCH64_HWCAP_FP,
AARCH64_HWCAP2_SVE2 | AARCH64_HWCAP2_BTI);
GetEmptyFilesystem(); // disabling /proc/cpuinfo
@ -82,7 +207,7 @@ TEST(CpuinfoAarch64Test, FromHardwareCap2)
TEST(CpuinfoAarch64Test, ARMCortexA53)
{
DisableHardwareCapabilities();
ResetHwcaps();
auto& fs = GetEmptyFilesystem();
fs.CreateFile("/proc/cpuinfo",
R"(Processor : AArch64 Processor rev 3 (aarch64)
@ -160,5 +285,7 @@ CPU revision : 3)");
EXPECT_FALSE(info.features.mte);
}
#endif
} // namespace
} // namespace cpu_features

View File

@ -10,10 +10,9 @@ namespace cpu_features
{
namespace
{
void DisableHardwareCapabilities() { SetHardwareCapabilities(0, 0); }
TEST(CpuinfoArmTest, FromHardwareCap)
{
ResetHwcaps();
SetHardwareCapabilities(ARM_HWCAP_NEON, ARM_HWCAP2_AES | ARM_HWCAP2_CRC32);
GetEmptyFilesystem(); // disabling /proc/cpuinfo
const auto info = GetArmInfo();
@ -43,7 +42,7 @@ TEST(CpuinfoArmTest, FromHardwareCap)
TEST(CpuinfoArmTest, ODroidFromCpuInfo)
{
DisableHardwareCapabilities();
ResetHwcaps();
auto& fs = GetEmptyFilesystem();
fs.CreateFile("/proc/cpuinfo", R"(processor : 0
model name : ARMv7 Processor rev 3 (v71)
@ -93,7 +92,7 @@ CPU revision : 3)");
// Linux test-case
TEST(CpuinfoArmTest, RaspberryPiZeroFromCpuInfo)
{
DisableHardwareCapabilities();
ResetHwcaps();
auto& fs = GetEmptyFilesystem();
fs.CreateFile("/proc/cpuinfo", R"(processor : 0
model name : ARMv6-compatible processor rev 7 (v6l)
@ -104,6 +103,7 @@ CPU architecture: 7
CPU variant : 0x0
CPU part : 0xb76
CPU revision : 7
Hardware : BCM2835
Revision : 9000c1
Serial : 000000006cd946f3)");
@ -145,7 +145,7 @@ Serial : 000000006cd946f3)");
TEST(CpuinfoArmTest, MarvellArmadaFromCpuInfo)
{
DisableHardwareCapabilities();
ResetHwcaps();
auto& fs = GetEmptyFilesystem();
fs.CreateFile("/proc/cpuinfo", R"(processor : 0
model name : ARMv7 Processor rev 1 (v7l)
@ -156,6 +156,7 @@ CPU architecture: 7
CPU variant : 0x4
CPU part : 0xc09
CPU revision : 1
processor : 1
model name : ARMv7 Processor rev 1 (v7l)
BogoMIPS : 50.00
@ -165,6 +166,7 @@ CPU architecture: 7
CPU variant : 0x4
CPU part : 0xc09
CPU revision : 1
Hardware : Marvell Armada 380/385 (Device Tree)
Revision : 0000
Serial : 0000000000000000)");
@ -208,7 +210,7 @@ Serial : 0000000000000000)");
// http://code.google.com/p/android/issues/detail?id=10812
TEST(CpuinfoArmTest, InvalidArmv7)
{
DisableHardwareCapabilities();
ResetHwcaps();
auto& fs = GetEmptyFilesystem();
fs.CreateFile("/proc/cpuinfo",
R"(Processor : ARMv6-compatible processor rev 6 (v6l)
@ -219,6 +221,7 @@ CPU architecture: 7
CPU variant : 0x0
CPU part : 0xb76
CPU revision : 6
Hardware : SPICA
Revision : 0020
Serial : 33323613546d00ec )");
@ -258,19 +261,23 @@ Serial : 33323613546d00ec )");
// https://crbug.com/341598.
TEST(CpuinfoArmTest, InvalidNeon)
{
ResetHwcaps();
auto& fs = GetEmptyFilesystem();
fs.CreateFile("/proc/cpuinfo",
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)");
@ -283,7 +290,7 @@ Serial: 00001e030000354e)");
// support.
TEST(CpuinfoArmTest, Nexus4_0x510006f2)
{
DisableHardwareCapabilities();
ResetHwcaps();
auto& fs = GetEmptyFilesystem();
fs.CreateFile("/proc/cpuinfo",
R"(CPU implementer : 0x51
@ -302,7 +309,7 @@ CPU revision : 2)");
// support.
TEST(CpuinfoArmTest, Nexus4_0x510006f3)
{
DisableHardwareCapabilities();
ResetHwcaps();
auto& fs = GetEmptyFilesystem();
fs.CreateFile("/proc/cpuinfo",
R"(CPU implementer : 0x51
@ -322,7 +329,7 @@ CPU revision : 3)");
// CPU implemented by the emulator.
TEST(CpuinfoArmTest, EmulatorSpecificIdiv)
{
DisableHardwareCapabilities();
ResetHwcaps();
auto& fs = GetEmptyFilesystem();
fs.CreateFile("/proc/cpuinfo",
R"(Processor : ARMv7 Processor rev 0 (v7l)
@ -333,6 +340,7 @@ CPU architecture: 7
CPU variant : 0x0
CPU part : 0xc08
CPU revision : 0
Hardware : Goldfish
Revision : 0000
Serial : 0000000000000000)");

View File

@ -12,10 +12,9 @@ namespace cpu_features
{
namespace
{
void DisableHardwareCapabilities() { SetHardwareCapabilities(0, 0); }
TEST(CpuinfoMipsTest, FromHardwareCapBoth)
{
ResetHwcaps();
SetHardwareCapabilities(MIPS_HWCAP_MSA | MIPS_HWCAP_R6, 0);
GetEmptyFilesystem(); // disabling /proc/cpuinfo
const auto info = GetMipsInfo();
@ -26,6 +25,7 @@ TEST(CpuinfoMipsTest, FromHardwareCapBoth)
TEST(CpuinfoMipsTest, FromHardwareCapOnlyOne)
{
ResetHwcaps();
SetHardwareCapabilities(MIPS_HWCAP_MSA, 0);
GetEmptyFilesystem(); // disabling /proc/cpuinfo
const auto info = GetMipsInfo();
@ -35,7 +35,7 @@ TEST(CpuinfoMipsTest, FromHardwareCapOnlyOne)
TEST(CpuinfoMipsTest, Ci40)
{
DisableHardwareCapabilities();
ResetHwcaps();
auto& fs = GetEmptyFilesystem();
fs.CreateFile("/proc/cpuinfo", R"(system type : IMG Pistachio SoC (B0)
machine : IMG Marduk Ci40 with cc2520
@ -64,7 +64,7 @@ VPE : 0
TEST(CpuinfoMipsTest, AR7161)
{
DisableHardwareCapabilities();
ResetHwcaps();
auto& fs = GetEmptyFilesystem();
fs.CreateFile("/proc/cpuinfo",
R"(system type : Atheros AR7161 rev 2
@ -91,7 +91,7 @@ VCEI exceptions : not available
TEST(CpuinfoMipsTest, Goldfish)
{
DisableHardwareCapabilities();
ResetHwcaps();
auto& fs = GetEmptyFilesystem();
fs.CreateFile("/proc/cpuinfo", R"(system type : MIPS-Goldfish
Hardware : goldfish

View File

@ -11,10 +11,9 @@ namespace cpu_features
{
namespace
{
void DisableHardwareCapabilities() { SetHardwareCapabilities(0, 0); }
TEST(CpustringsPPCTest, FromHardwareCap)
{
ResetHwcaps();
SetHardwareCapabilities(PPC_FEATURE_HAS_FPU | PPC_FEATURE_HAS_VSX,
PPC_FEATURE2_ARCH_3_00);
GetEmptyFilesystem(); // disabling /proc/cpuinfo
@ -31,22 +30,25 @@ TEST(CpustringsPPCTest, FromHardwareCap)
TEST(CpustringsPPCTest, Blade)
{
DisableHardwareCapabilities();
ResetHwcaps();
auto& fs = GetEmptyFilesystem();
fs.CreateFile("/proc/cpuinfo",
R"(processor : 14
cpu : POWER7 (architected), altivec supported
clock : 3000.000000MHz
revision : 2.1 (pvr 003f 0201)
processor : 15
cpu : POWER7 (architected), altivec supported
clock : 3000.000000MHz
revision : 2.1 (pvr 003f 0201)
timebase : 512000000
platform : pSeries
model : IBM,8406-70Y
machine : CHRP IBM,8406-70Y)");
SetPlatformTypes("power7", "power8");
SetPlatformPointer("power7");
SetBasePlatformPointer("power8");
const auto strings = GetPPCPlatformStrings();
ASSERT_STREQ(strings.platform, "pSeries");
ASSERT_STREQ(strings.model, "IBM,8406-70Y");
@ -58,17 +60,19 @@ machine : CHRP IBM,8406-70Y)");
TEST(CpustringsPPCTest, Firestone)
{
DisableHardwareCapabilities();
ResetHwcaps();
auto& fs = GetEmptyFilesystem();
fs.CreateFile("/proc/cpuinfo",
R"(processor : 126
cpu : POWER8 (raw), altivec supported
clock : 2061.000000MHz
revision : 2.0 (pvr 004d 0200)
processor : 127
cpu : POWER8 (raw), altivec supported
clock : 2061.000000MHz
revision : 2.0 (pvr 004d 0200)
timebase : 512000000
platform : PowerNV
model : 8335-GTA
@ -83,13 +87,14 @@ firmware : OPAL v3)");
TEST(CpustringsPPCTest, w8)
{
DisableHardwareCapabilities();
ResetHwcaps();
auto& fs = GetEmptyFilesystem();
fs.CreateFile("/proc/cpuinfo",
R"(processor : 143
cpu : POWER9, altivec supported
clock : 2300.000000MHz
revision : 2.2 (pvr 004e 1202)
timebase : 512000000
platform : PowerNV
model : 0000000000000000

View File

@ -304,8 +304,179 @@ TEST_F(CpuidX86Test, HSWCache)
EXPECT_EQ(info.levels[3].partitioning, 1);
}
// http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0200F30_K11_Griffin_CPUID.txt
TEST_F(CpuidX86Test, AMD_K11_GRIFFIN)
{
g_fake_cpu->SetLeaves({
{{0x00000000, 0}, Leaf{0x00000001, 0x68747541, 0x444D4163, 0x69746E65}},
{{0x00000001, 0}, Leaf{0x00200F30, 0x00020800, 0x00002001, 0x178BFBFF}},
{{0x80000000, 0}, Leaf{0x8000001A, 0x68747541, 0x444D4163, 0x69746E65}},
{{0x80000001, 0}, Leaf{0x00200F30, 0x20000000, 0x0000131F, 0xEBD3FBFF}},
});
const auto info = GetX86Info();
EXPECT_STREQ(info.vendor, "AuthenticAMD");
EXPECT_EQ(info.family, 0x11);
EXPECT_EQ(info.model, 0x03);
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_K11);
}
// http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0300F10_K12_Llano_CPUID.txt
TEST_F(CpuidX86Test, AMD_K12_LLANO)
{
g_fake_cpu->SetLeaves({
{{0x00000000, 0}, Leaf{0x00000006, 0x68747541, 0x444D4163, 0x69746E65}},
{{0x00000001, 0}, Leaf{0x00300F10, 0x00040800, 0x00802009, 0x178BFBFF}},
{{0x80000000, 0}, Leaf{0x8000001B, 0x68747541, 0x444D4163, 0x69746E65}},
{{0x80000001, 0}, Leaf{0x00300F10, 0x20002B31, 0x000037FF, 0xEFD3FBFF}},
});
const auto info = GetX86Info();
EXPECT_STREQ(info.vendor, "AuthenticAMD");
EXPECT_EQ(info.family, 0x12);
EXPECT_EQ(info.model, 0x01);
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_K12);
}
// http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0500F01_K14_Bobcat_CPUID.txt
TEST_F(CpuidX86Test, AMD_K14_BOBCAT_AMD0500F01)
{
g_fake_cpu->SetLeaves({
{{0x00000000, 0}, Leaf{0x00000006, 0x68747541, 0x444D4163, 0x69746E65}},
{{0x00000001, 0}, Leaf{0x00500F01, 0x00020800, 0x00802209, 0x178BFBFF}},
{{0x80000000, 0}, Leaf{0x8000001B, 0x68747541, 0x444D4163, 0x69746E65}},
{{0x80000001, 0}, Leaf{0x00500F01, 0x00000000, 0x000035FF, 0x2FD3FBFF}},
});
const auto info = GetX86Info();
EXPECT_STREQ(info.vendor, "AuthenticAMD");
EXPECT_EQ(info.family, 0x14);
EXPECT_EQ(info.model, 0x00);
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_BOBCAT);
}
// http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0500F10_K14_Bobcat_CPUID.txt
TEST_F(CpuidX86Test, AMD_K14_BOBCAT_AMD0500F10)
{
g_fake_cpu->SetLeaves({
{{0x00000000, 0}, Leaf{0x00000006, 0x68747541, 0x444D4163, 0x69746E65}},
{{0x00000001, 0}, Leaf{0x00500F10, 0x00020800, 0x00802209, 0x178BFBFF}},
{{0x00000002, 0}, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000000}},
{{0x00000003, 0}, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000000}},
{{0x00000005, 0}, Leaf{0x00000040, 0x00000040, 0x00000003, 0x00000000}},
{{0x00000006, 0}, Leaf{0x00000000, 0x00000000, 0x00000001, 0x00000000}},
{{0x80000000, 0}, Leaf{0x8000001B, 0x68747541, 0x444D4163, 0x69746E65}},
{{0x80000001, 0}, Leaf{0x00500F10, 0x00001242, 0x000035FF, 0x2FD3FBFF}},
{{0x80000002, 0}, Leaf{0x20444D41, 0x35332D45, 0x72502030, 0x7365636F}},
{{0x80000003, 0}, Leaf{0x00726F73, 0x00000000, 0x00000000, 0x00000000}},
{{0x80000004, 0}, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000000}},
{{0x80000005, 0}, Leaf{0xFF08FF08, 0xFF280000, 0x20080140, 0x20020140}},
});
const auto info = GetX86Info();
EXPECT_STREQ(info.vendor, "AuthenticAMD");
EXPECT_EQ(info.family, 0x14);
EXPECT_EQ(info.model, 0x01);
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_BOBCAT);
}
// http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0500F20_K14_Bobcat_CPUID.txt
TEST_F(CpuidX86Test, AMD_K14_BOBCAT_AMD0500F20)
{
g_fake_cpu->SetLeaves({
{{0x00000000, 0}, Leaf{0x00000006, 0x68747541, 0x444D4163, 0x69746E65}},
{{0x00000001, 0}, Leaf{0x00500F20, 0x00020800, 0x00802209, 0x178BFBFF}},
{{0x80000000, 0}, Leaf{0x8000001B, 0x68747541, 0x444D4163, 0x69746E65}},
{{0x80000001, 0}, Leaf{0x00500F20, 0x000012E9, 0x000035FF, 0x2FD3FBFF}},
});
const auto info = GetX86Info();
EXPECT_STREQ(info.vendor, "AuthenticAMD");
EXPECT_EQ(info.family, 0x14);
EXPECT_EQ(info.model, 0x02);
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_BOBCAT);
}
// http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0670F00_K15_StoneyRidge_CPUID.txt
TEST_F(CpuidX86Test, AMD_K15_EXCAVATOR_STONEY_RIDGE)
{
g_fake_cpu->SetLeaves({
{{0x00000000, 0}, Leaf{0x0000000D, 0x68747541, 0x444D4163, 0x69746E65}},
{{0x00000001, 0}, Leaf{0x00670F00, 0x00020800, 0x7ED8320B, 0x178BFBFF}},
{{0x00000007, 0}, Leaf{0x00000000, 0x000001A9, 0x00000000, 0x00000000}},
{{0x80000000, 0}, Leaf{0x8000001E, 0x68747541, 0x444D4163, 0x69746E65}},
{{0x80000001, 0}, Leaf{0x00670F00, 0x00000000, 0x2FABBFFF, 0x2FD3FBFF}},
{{0x80000002, 0}, Leaf{0x20444D41, 0x392D3941, 0x20303134, 0x45444152}},
{{0x80000003, 0}, Leaf{0x52204E4F, 0x35202C35, 0x4D4F4320, 0x45545550}},
{{0x80000004, 0}, Leaf{0x524F4320, 0x32205345, 0x47332B43, 0x00202020}},
});
const auto info = GetX86Info();
EXPECT_STREQ(info.vendor, "AuthenticAMD");
EXPECT_EQ(info.family, 0x15);
EXPECT_EQ(info.model, 0x70);
EXPECT_EQ(GetX86Microarchitecture(&info),
X86Microarchitecture::AMD_EXCAVATOR);
char brand_string[49];
FillX86BrandString(brand_string);
EXPECT_STREQ(brand_string, "AMD A9-9410 RADEON R5, 5 COMPUTE CORES 2C+3G ");
}
// http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0600F20_K15_AbuDhabi_CPUID0.txt
TEST_F(CpuidX86Test, AMD_K15_PILEDRIVER_ABU_DHABI)
{
g_fake_cpu->SetLeaves({
{{0x00000000, 0}, Leaf{0x0000000D, 0x68747541, 0x444D4163, 0x69746E65}},
{{0x00000001, 0}, Leaf{0x00600F20, 0x00100800, 0x3E98320B, 0x178BFBFF}},
{{0x00000007, 0}, Leaf{0x00000000, 0x00000008, 0x00000000, 0x00000000}},
{{0x80000000, 0}, Leaf{0x8000001E, 0x68747541, 0x444D4163, 0x69746E65}},
{{0x80000001, 0}, Leaf{0x00600F20, 0x30000000, 0x01EBBFFF, 0x2FD3FBFF}},
{{0x80000002, 0}, Leaf{0x20444D41, 0x6574704F, 0x286E6F72, 0x20296D74}},
{{0x80000003, 0}, Leaf{0x636F7250, 0x6F737365, 0x33362072, 0x20203637}},
{{0x80000004, 0}, Leaf{0x20202020, 0x20202020, 0x20202020, 0x00202020}},
});
const auto info = GetX86Info();
EXPECT_STREQ(info.vendor, "AuthenticAMD");
EXPECT_EQ(info.family, 0x15);
EXPECT_EQ(info.model, 0x02);
EXPECT_EQ(GetX86Microarchitecture(&info),
X86Microarchitecture::AMD_PILEDRIVER);
char brand_string[49];
FillX86BrandString(brand_string);
EXPECT_STREQ(brand_string, "AMD Opteron(tm) Processor 6376 ");
}
// http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0600F12_K15_Interlagos_CPUID3.txt
TEST_F(CpuidX86Test, AMD_K15_BULLDOZER_INTERLAGOS)
{
g_fake_cpu->SetLeaves({
{{0x00000000, 0}, Leaf{0x0000000D, 0x68747541, 0x444D4163, 0x69746E65}},
{{0x00000001, 0}, Leaf{0x00600F12, 0x000C0800, 0x1E98220B, 0x178BFBFF}},
{{0x00000007, 0}, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000000}},
{{0x80000000, 0}, Leaf{0x8000001E, 0x68747541, 0x444D4163, 0x69746E65}},
{{0x80000001, 0}, Leaf{0x00600F12, 0x30000000, 0x01C9BFFF, 0x2FD3FBFF}},
{{0x80000002, 0}, Leaf{0x20444D41, 0x6574704F, 0x286E6F72, 0x20294D54}},
{{0x80000003, 0}, Leaf{0x636F7250, 0x6F737365, 0x32362072, 0x20203833}},
{{0x80000004, 0}, Leaf{0x20202020, 0x20202020, 0x20202020, 0x00202020}},
});
const auto info = GetX86Info();
EXPECT_STREQ(info.vendor, "AuthenticAMD");
EXPECT_EQ(info.family, 0x15);
EXPECT_EQ(info.model, 0x01);
EXPECT_EQ(GetX86Microarchitecture(&info),
X86Microarchitecture::AMD_BULLDOZER);
char brand_string[49];
FillX86BrandString(brand_string);
EXPECT_STREQ(brand_string, "AMD Opteron(TM) Processor 6238 ");
}
// http://users.atw.hu/instlatx64/AuthenticAMD0630F81_K15_Godavari_CPUID.txt
TEST_F(CpuidX86Test, AMD_K15)
TEST_F(CpuidX86Test, AMD_K15_STREAMROLLER_GODAVARI)
{
g_fake_cpu->SetLeaves({
{{0x00000000, 0}, Leaf{0x0000000D, 0x68747541, 0x444D4163, 0x69746E65}},
@ -325,13 +496,188 @@ TEST_F(CpuidX86Test, AMD_K15)
EXPECT_EQ(info.model, 0x38);
EXPECT_EQ(info.stepping, 0x01);
EXPECT_EQ(GetX86Microarchitecture(&info),
X86Microarchitecture::AMD_BULLDOZER);
X86Microarchitecture::AMD_STREAMROLLER);
char brand_string[49];
FillX86BrandString(brand_string);
EXPECT_STREQ(brand_string, "AMD A8-7670K Radeon R7, 10 Compute Cores 4C+6G ");
}
// http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0700F01_K16_Kabini_CPUID.txt
TEST_F(CpuidX86Test, AMD_K16_JAGUAR_KABINI)
{
g_fake_cpu->SetLeaves({
{{0x00000000, 0}, Leaf{0x0000000D, 0x68747541, 0x444D4163, 0x69746E65}},
{{0x00000001, 0}, Leaf{0x00700F01, 0x00040800, 0x3ED8220B, 0x178BFBFF}},
{{0x00000007, 0}, Leaf{0x00000000, 0x00000008, 0x00000000, 0x00000000}},
{{0x80000000, 0}, Leaf{0x8000001E, 0x68747541, 0x444D4163, 0x69746E65}},
{{0x80000001, 0}, Leaf{0x00700F01, 0x00000000, 0x154037FF, 0x2FD3FBFF}},
{{0x80000002, 0}, Leaf{0x20444D41, 0x352D3441, 0x20303030, 0x20555041}},
{{0x80000003, 0}, Leaf{0x68746977, 0x64615220, 0x286E6F65, 0x20294D54}},
{{0x80000004, 0}, Leaf{0x47204448, 0x68706172, 0x20736369, 0x00202020}},
});
const auto info = GetX86Info();
EXPECT_STREQ(info.vendor, "AuthenticAMD");
EXPECT_EQ(info.family, 0x16);
EXPECT_EQ(info.model, 0x00);
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_JAGUAR);
char brand_string[49];
FillX86BrandString(brand_string);
EXPECT_STREQ(brand_string, "AMD A4-5000 APU with Radeon(TM) HD Graphics ");
}
// http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0730F01_K16_Beema_CPUID2.txt
TEST_F(CpuidX86Test, AMD_K16_PUMA_BEEMA)
{
g_fake_cpu->SetLeaves({
{{0x00000000, 0}, Leaf{0x0000000D, 0x68747541, 0x444D4163, 0x69746E65}},
{{0x00000001, 0}, Leaf{0x00730F01, 0x00040800, 0x7ED8220B, 0x178BFBFF}},
{{0x00000007, 0}, Leaf{0x00000000, 0x00000008, 0x00000000, 0x00000000}},
{{0x80000000, 0}, Leaf{0x8000001E, 0x68747541, 0x444D4163, 0x69746E65}},
{{0x80000001, 0}, Leaf{0x00730F01, 0x00000000, 0x1D4037FF, 0x2FD3FBFF}},
{{0x80000002, 0}, Leaf{0x20444D41, 0x362D3641, 0x20303133, 0x20555041}},
{{0x80000003, 0}, Leaf{0x68746977, 0x444D4120, 0x64615220, 0x206E6F65}},
{{0x80000004, 0}, Leaf{0x47203452, 0x68706172, 0x20736369, 0x00202020}},
});
const auto info = GetX86Info();
EXPECT_STREQ(info.vendor, "AuthenticAMD");
EXPECT_EQ(info.family, 0x16);
EXPECT_EQ(info.model, 0x30);
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_PUMA);
char brand_string[49];
FillX86BrandString(brand_string);
EXPECT_STREQ(brand_string, "AMD A6-6310 APU with AMD Radeon R4 Graphics ");
}
// http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0820F01_K17_Dali_CPUID.txt
TEST_F(CpuidX86Test, AMD_K17_ZEN_DALI)
{
g_fake_cpu->SetLeaves({
{{0x00000000, 0}, Leaf{0x0000000D, 0x68747541, 0x444D4163, 0x69746E65}},
{{0x00000001, 0}, Leaf{0x00820F01, 0x00020800, 0x7ED8320B, 0x178BFBFF}},
{{0x00000007, 0}, Leaf{0x00000000, 0x209C01A9, 0x00000000, 0x00000000}},
{{0x80000000, 0}, Leaf{0x8000001F, 0x68747541, 0x444D4163, 0x69746E65}},
{{0x80000001, 0}, Leaf{0x00820F01, 0x00000000, 0x35C233FF, 0x2FD3FBFF}},
{{0x80000002, 0}, Leaf{0x20444D41, 0x30323033, 0x69772065, 0x52206874}},
{{0x80000003, 0}, Leaf{0x6F656461, 0x7247206E, 0x69687061, 0x20207363}},
{{0x80000004, 0}, Leaf{0x20202020, 0x20202020, 0x20202020, 0x00202020}},
});
const auto info = GetX86Info();
EXPECT_STREQ(info.vendor, "AuthenticAMD");
EXPECT_EQ(info.family, 0x17);
EXPECT_EQ(info.model, 0x20);
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN);
char brand_string[49];
FillX86BrandString(brand_string);
EXPECT_STREQ(brand_string, "AMD 3020e with Radeon Graphics ");
}
// http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0800F82_K17_ZenP_CPUID.txt
TEST_F(CpuidX86Test, AMD_K17_ZEN_PLUS_PINNACLE_RIDGE)
{
g_fake_cpu->SetLeaves({
{{0x00000000, 0}, Leaf{0x0000000D, 0x68747541, 0x444D4163, 0x69746E65}},
{{0x00000001, 0}, Leaf{0x00800F82, 0x00100800, 0x7ED8320B, 0x178BFBFF}},
{{0x00000007, 0}, Leaf{0x00000000, 0x209C01A9, 0x00000000, 0x00000000}},
{{0x80000000, 0}, Leaf{0x8000001F, 0x68747541, 0x444D4163, 0x69746E65}},
{{0x80000001, 0}, Leaf{0x00800F82, 0x20000000, 0x35C233FF, 0x2FD3FBFF}},
{{0x80000002, 0}, Leaf{0x20444D41, 0x657A7952, 0x2037206E, 0x30303732}},
{{0x80000003, 0}, Leaf{0x69452058, 0x2D746867, 0x65726F43, 0x6F725020}},
{{0x80000004, 0}, Leaf{0x73736563, 0x2020726F, 0x20202020, 0x00202020}},
});
const auto info = GetX86Info();
EXPECT_STREQ(info.vendor, "AuthenticAMD");
EXPECT_EQ(info.family, 0x17);
EXPECT_EQ(info.model, 0x08);
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN_PLUS);
char brand_string[49];
FillX86BrandString(brand_string);
EXPECT_STREQ(brand_string, "AMD Ryzen 7 2700X Eight-Core Processor ");
}
// http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0840F70_K17_CPUID.txt
TEST_F(CpuidX86Test, AMD_K17_ZEN2_XBOX_SERIES_X)
{
g_fake_cpu->SetLeaves({
{{0x00000000, 0}, Leaf{0x00000010, 0x68747541, 0x444D4163, 0x69746E65}},
{{0x00000001, 0}, Leaf{0x00840F70, 0x00100800, 0x7ED8320B, 0x178BFBFF}},
{{0x00000007, 0}, Leaf{0x00000000, 0x219C91A9, 0x00400004, 0x00000000}},
{{0x80000000, 0}, Leaf{0x80000020, 0x68747541, 0x444D4163, 0x69746E65}},
{{0x80000001, 0}, Leaf{0x00840F70, 0x00000000, 0xF5C2B7FF, 0x2FD3FBFF}},
{{0x80000002, 0}, Leaf{0x20444D41, 0x30303734, 0x2D382053, 0x65726F43}},
{{0x80000003, 0}, Leaf{0x6F725020, 0x73736563, 0x4420726F, 0x746B7365}},
{{0x80000004, 0}, Leaf{0x4B20706F, 0x00007469, 0x00000000, 0x00000000}},
});
const auto info = GetX86Info();
EXPECT_STREQ(info.vendor, "AuthenticAMD");
EXPECT_EQ(info.family, 0x17);
EXPECT_EQ(info.model, 0x47);
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN2);
char brand_string[49];
FillX86BrandString(brand_string);
EXPECT_STREQ(brand_string, "AMD 4700S 8-Core Processor Desktop Kit");
}
// http://users.atw.hu/instlatx64/HygonGenuine/HygonGenuine0900F02_Hygon_CPUID3.txt
TEST_F(CpuidX86Test, AMD_K18_ZEN_DHYANA)
{
g_fake_cpu->SetLeaves({
{{0x00000000, 0}, Leaf{0x0000000D, 0x6F677948, 0x656E6975, 0x6E65476E}},
{{0x00000001, 0}, Leaf{0x00900F02, 0x00100800, 0x74D83209, 0x178BFBFF}},
{{0x00000007, 0}, Leaf{0x00000000, 0x009C01A9, 0x0040068C, 0x00000000}},
{{0x80000000, 0}, Leaf{0x8000001F, 0x6F677948, 0x656E6975, 0x6E65476E}},
{{0x80000001, 0}, Leaf{0x00900F02, 0x60000000, 0x35C233FF, 0x2FD3FBFF}},
{{0x80000002, 0}, Leaf{0x6F677948, 0x3843206E, 0x31332036, 0x20203538}},
{{0x80000003, 0}, Leaf{0x6F632D38, 0x50206572, 0x65636F72, 0x726F7373}},
{{0x80000004, 0}, Leaf{0x20202020, 0x20202020, 0x20202020, 0x00202020}},
});
const auto info = GetX86Info();
EXPECT_STREQ(info.vendor, "HygonGenuine");
EXPECT_EQ(info.family, 0x18);
EXPECT_EQ(info.model, 0x00);
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN);
char brand_string[49];
FillX86BrandString(brand_string);
EXPECT_STREQ(brand_string, "Hygon C86 3185 8-core Processor ");
}
// http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0A20F10_K19_Vermeer2_CPUID.txt
TEST_F(CpuidX86Test, AMD_K19_ZEN3_VERMEER)
{
g_fake_cpu->SetLeaves({
{{0x00000000, 0}, Leaf{0x00000010, 0x68747541, 0x444D4163, 0x69746E65}},
{{0x00000001, 0}, Leaf{0x00A20F10, 0x01180800, 0x7ED8320B, 0x178BFBFF}},
{{0x00000007, 0}, Leaf{0x00000000, 0x219C97A9, 0x0040068C, 0x00000000}},
{{0x80000000, 0}, Leaf{0x80000023, 0x68747541, 0x444D4163, 0x69746E65}},
{{0x80000001, 0}, Leaf{0x00A20F10, 0x20000000, 0x75C237FF, 0x2FD3FBFF}},
{{0x80000002, 0}, Leaf{0x20444D41, 0x657A7952, 0x2039206E, 0x30303935}},
{{0x80000003, 0}, Leaf{0x32312058, 0x726F432D, 0x72502065, 0x7365636F}},
{{0x80000004, 0}, Leaf{0x20726F73, 0x20202020, 0x20202020, 0x00202020}},
});
const auto info = GetX86Info();
EXPECT_STREQ(info.vendor, "AuthenticAMD");
EXPECT_EQ(info.family, 0x19);
EXPECT_EQ(info.model, 0x21);
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN3);
char brand_string[49];
FillX86BrandString(brand_string);
EXPECT_STREQ(brand_string, "AMD Ryzen 9 5900X 12-Core Processor ");
}
// https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel00106A1_Nehalem_CPUID.txt
TEST_F(CpuidX86Test, Nehalem)
{
@ -344,21 +690,29 @@ TEST_F(CpuidX86Test, Nehalem)
PF_XMMI64_INSTRUCTIONS_AVAILABLE);
g_fake_cpu->SetWindowsIsProcessorFeaturePresent(
PF_SSE3_INSTRUCTIONS_AVAILABLE);
#endif // CPU_FEATURES_OS_WINDOWS
#if defined(CPU_FEATURES_OS_DARWIN)
#elif defined(CPU_FEATURES_OS_DARWIN)
g_fake_cpu->SetDarwinSysCtlByName("hw.optional.sse");
g_fake_cpu->SetDarwinSysCtlByName("hw.optional.sse2");
g_fake_cpu->SetDarwinSysCtlByName("hw.optional.sse3");
g_fake_cpu->SetDarwinSysCtlByName("hw.optional.supplementalsse3");
g_fake_cpu->SetDarwinSysCtlByName("hw.optional.sse4_1");
g_fake_cpu->SetDarwinSysCtlByName("hw.optional.sse4_2");
#endif // CPU_FEATURES_OS_DARWIN
#if defined(CPU_FEATURES_OS_LINUX_OR_ANDROID)
#elif defined(CPU_FEATURES_OS_FREEBSD)
auto& fs = GetEmptyFilesystem();
fs.CreateFile("/var/run/dmesg.boot", R"(
---<<BOOT>>---
Copyright (c) 1992-2020 The FreeBSD Project.
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,SSE2,HTT>
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)
auto& fs = GetEmptyFilesystem();
fs.CreateFile("/proc/cpuinfo", R"(processor :
flags : fpu mmx sse sse2 sse3 ssse3 sse4_1 sse4_2
)");
#endif // CPU_FEATURES_OS_LINUX_OR_ANDROID
#endif
g_fake_cpu->SetLeaves({
{{0x00000000, 0}, Leaf{0x0000000B, 0x756E6547, 0x6C65746E, 0x49656E69}},
{{0x00000001, 0}, Leaf{0x000106A2, 0x00100800, 0x00BCE3BD, 0xBFEBFBFF}},
@ -401,13 +755,13 @@ flags : fpu mmx sse sse2 sse3 ssse3 sse4_1 sse4_2
EXPECT_TRUE(info.features.sse);
EXPECT_TRUE(info.features.sse2);
EXPECT_TRUE(info.features.sse3);
#ifndef CPU_FEATURES_OS_WINDOWS
#if !defined(CPU_FEATURES_OS_WINDOWS)
// Currently disabled on Windows as IsProcessorFeaturePresent do not support
// feature detection > sse3.
EXPECT_TRUE(info.features.ssse3);
EXPECT_TRUE(info.features.sse4_1);
EXPECT_TRUE(info.features.sse4_2);
#endif // CPU_FEATURES_OS_WINDOWS
#endif // !defined(CPU_FEATURES_OS_WINDOWS)
}
// https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel0030673_Silvermont3_CPUID.txt
@ -422,21 +776,29 @@ TEST_F(CpuidX86Test, Atom)
PF_XMMI64_INSTRUCTIONS_AVAILABLE);
g_fake_cpu->SetWindowsIsProcessorFeaturePresent(
PF_SSE3_INSTRUCTIONS_AVAILABLE);
#endif // CPU_FEATURES_OS_WINDOWS
#if defined(CPU_FEATURES_OS_DARWIN)
#elif defined(CPU_FEATURES_OS_DARWIN)
g_fake_cpu->SetDarwinSysCtlByName("hw.optional.sse");
g_fake_cpu->SetDarwinSysCtlByName("hw.optional.sse2");
g_fake_cpu->SetDarwinSysCtlByName("hw.optional.sse3");
g_fake_cpu->SetDarwinSysCtlByName("hw.optional.supplementalsse3");
g_fake_cpu->SetDarwinSysCtlByName("hw.optional.sse4_1");
g_fake_cpu->SetDarwinSysCtlByName("hw.optional.sse4_2");
#endif // CPU_FEATURES_OS_DARWIN
#if defined(CPU_FEATURES_OS_LINUX_OR_ANDROID)
#elif defined(CPU_FEATURES_OS_FREEBSD)
auto& fs = GetEmptyFilesystem();
fs.CreateFile("/var/run/dmesg.boot", R"(
---<<BOOT>>---
Copyright (c) 1992-2020 The FreeBSD Project.
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,SSE2,HTT>
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)
auto& fs = GetEmptyFilesystem();
fs.CreateFile("/proc/cpuinfo", R"(
flags : fpu mmx sse sse2 sse3 ssse3 sse4_1 sse4_2
)");
#endif // CPU_FEATURES_OS_LINUX_OR_ANDROID
#endif
g_fake_cpu->SetLeaves({
{{0x00000000, 0}, Leaf{0x0000000B, 0x756E6547, 0x6C65746E, 0x49656E69}},
{{0x00000001, 0}, Leaf{0x00030673, 0x00100800, 0x41D8E3BF, 0xBFEBFBFF}},
@ -479,13 +841,13 @@ flags : fpu mmx sse sse2 sse3 ssse3 sse4_1 sse4_2
EXPECT_TRUE(info.features.sse);
EXPECT_TRUE(info.features.sse2);
EXPECT_TRUE(info.features.sse3);
#ifndef CPU_FEATURES_OS_WINDOWS
#if !defined(CPU_FEATURES_OS_WINDOWS)
// Currently disabled on Windows as IsProcessorFeaturePresent do not support
// feature detection > sse3.
EXPECT_TRUE(info.features.ssse3);
EXPECT_TRUE(info.features.sse4_1);
EXPECT_TRUE(info.features.sse4_2);
#endif // CPU_FEATURES_OS_WINDOWS
#endif // !defined(CPU_FEATURES_OS_WINDOWS)
}
// https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel0000673_P3_KatmaiDP_CPUID.txt
@ -496,16 +858,23 @@ TEST_F(CpuidX86Test, P3)
#if defined(CPU_FEATURES_OS_WINDOWS)
g_fake_cpu->SetWindowsIsProcessorFeaturePresent(
PF_XMMI_INSTRUCTIONS_AVAILABLE);
#endif // CPU_FEATURES_OS_WINDOWS
#if defined(CPU_FEATURES_OS_DARWIN)
#elif defined(CPU_FEATURES_OS_DARWIN)
g_fake_cpu->SetDarwinSysCtlByName("hw.optional.sse");
#endif // CPU_FEATURES_OS_DARWIN
#if defined(CPU_FEATURES_OS_LINUX_OR_ANDROID)
#elif defined(CPU_FEATURES_OS_FREEBSD)
auto& fs = GetEmptyFilesystem();
fs.CreateFile("/var/run/dmesg.boot", R"(
---<<BOOT>>---
Copyright (c) 1992-2020 The FreeBSD Project.
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)
auto& fs = GetEmptyFilesystem();
fs.CreateFile("/proc/cpuinfo", R"(
flags : fpu mmx sse
)");
#endif // CPU_FEATURES_OS_LINUX_OR_ANDROID
#endif
g_fake_cpu->SetLeaves({
{{0x00000000, 0}, Leaf{0x00000003, 0x756E6547, 0x6C65746E, 0x49656E69}},
{{0x00000001, 0}, Leaf{0x00000673, 0x00000000, 0x00000000, 0x0387FBFF}},
@ -528,13 +897,13 @@ flags : fpu mmx sse
EXPECT_TRUE(info.features.sse);
EXPECT_FALSE(info.features.sse2);
EXPECT_FALSE(info.features.sse3);
#ifndef CPU_FEATURES_OS_WINDOWS
#if !defined(CPU_FEATURES_OS_WINDOWS)
// Currently disabled on Windows as IsProcessorFeaturePresent do not support
// feature detection > sse3.
EXPECT_FALSE(info.features.ssse3);
EXPECT_FALSE(info.features.sse4_1);
EXPECT_FALSE(info.features.sse4_2);
#endif // CPU_FEATURES_OS_WINDOWS
#endif // !defined(CPU_FEATURES_OS_WINDOWS)
}
// TODO(user): test what happens when xsave/osxsave are not present.

View File

@ -10,7 +10,8 @@ namespace cpu_features
namespace
{
static auto* const g_hardware_capabilities = new HardwareCapabilities();
static auto* const g_platform_types = new PlatformType();
static const char* g_platform_pointer = nullptr;
static const char* g_base_platform_pointer = nullptr;
} // namespace
void SetHardwareCapabilities(uint32_t hwcaps, uint32_t hwcaps2)
@ -18,20 +19,27 @@ void SetHardwareCapabilities(uint32_t hwcaps, uint32_t hwcaps2)
g_hardware_capabilities->hwcaps = hwcaps;
g_hardware_capabilities->hwcaps2 = hwcaps2;
}
void SetPlatformPointer(const char* string) { g_platform_pointer = string; }
void SetBasePlatformPointer(const char* string)
{
g_base_platform_pointer = string;
}
void ResetHwcaps()
{
SetHardwareCapabilities(0, 0);
SetPlatformPointer(nullptr);
SetBasePlatformPointer(nullptr);
}
HardwareCapabilities CpuFeatures_GetHardwareCapabilities(void)
{
return *g_hardware_capabilities;
}
void SetPlatformTypes(const char* platform, const char* base_platform)
const char* CpuFeatures_GetPlatformPointer(void) { return g_platform_pointer; }
const char* CpuFeatures_GetBasePlatformPointer(void)
{
CpuFeatures_StringView_CopyString(str(platform), g_platform_types->platform,
sizeof(g_platform_types->platform));
CpuFeatures_StringView_CopyString(str(base_platform),
g_platform_types->base_platform,
sizeof(g_platform_types->base_platform));
return g_base_platform_pointer;
}
PlatformType CpuFeatures_GetPlatformType(void) { return *g_platform_types; }
} // namespace cpu_features

View File

@ -9,7 +9,11 @@
namespace cpu_features
{
void SetHardwareCapabilities(uint32_t hwcaps, uint32_t hwcaps2);
void SetPlatformTypes(const char *platform, const char *base_platform);
void SetPlatformPointer(const char* string);
void SetBasePlatformPointer(const char* string);
// To be called before each test.
void ResetHwcaps();
} // namespace cpu_features

View File

@ -164,7 +164,7 @@ bool gps_l1_ca_telemetry_decoder_gs::gps_word_parityCheck(uint32_t gpsword)
{
// XOR as many bits in parallel as possible. The magic constants pick
// up bits which are to be XOR'ed together to implement the GPS parity
// check algorithm described in IS-GPS-200L. This avoids lengthy shift-
// check algorithm described in IS-GPS-200M. This avoids lengthy shift-
// and-xor loops.
const uint32_t d1 = gpsword & 0xFBFFBF00U;
const uint32_t d2 = my_rotl::rotl(gpsword, 1U) & 0x07FFBF01U;

View File

@ -47,7 +47,7 @@ gps_l1_ca_telemetry_decoder_gs_sptr gps_l1_ca_make_telemetry_decoder_gs(
const Tlm_Conf &conf);
/*!
* \brief This class implements a block that decodes the NAV data defined in IS-GPS-200L
* \brief This class implements a block that decodes the NAV data defined in IS-GPS-200M
*/
class gps_l1_ca_telemetry_decoder_gs : public gr::block
{

View File

@ -48,7 +48,7 @@ gps_l2c_telemetry_decoder_gs_sptr gps_l2c_make_telemetry_decoder_gs(
const Tlm_Conf &conf);
/*!
* \brief This class implements a block that decodes CNAV data defined in IS-GPS-200L
* \brief This class implements a block that decodes CNAV data defined in IS-GPS-200M
*/
class gps_l2c_telemetry_decoder_gs : public gr::block
{

View File

@ -624,6 +624,10 @@ void dll_pll_veml_tracking::msg_handler_telemetry_to_trk(const pmt::pmt_t &msg)
{
LOG(WARNING) << "msg_handler_telemetry_to_trk Bad any_cast: " << e.what();
}
catch (std::exception &ex)
{
LOG(WARNING) << "msg_handler_telemetry_to_trk Bad any_cast: " << ex.what();
}
}

View File

@ -52,6 +52,7 @@ gnss_synchro_monitor::gnss_synchro_monitor(int n_channels,
udp_sink_ptr = std::make_unique<Gnss_Synchro_Udp_Sink>(udp_addresses, udp_port, enable_protobuf);
}
void gnss_synchro_monitor::forecast(int noutput_items __attribute__((unused)), gr_vector_int& ninput_items_required)
{
for (int32_t channel_index = 0; channel_index < d_nchannels; channel_index++)
@ -61,6 +62,7 @@ void gnss_synchro_monitor::forecast(int noutput_items __attribute__((unused)), g
}
}
int gnss_synchro_monitor::general_work(int noutput_items __attribute__((unused)), gr_vector_int& ninput_items,
gr_vector_const_void_star& input_items, gr_vector_void_star& output_items __attribute__((unused)))
{
@ -84,10 +86,10 @@ int gnss_synchro_monitor::general_work(int noutput_items __attribute__((unused))
udp_sink_ptr->write_gnss_synchro(stocks);
// Reset count variable
count = 0;
// Consume the number of items for the input stream channel
consume(channel_index, ninput_items[channel_index]);
}
}
// Consume the number of items for the input stream channel
consume(channel_index, ninput_items[channel_index]);
}
// Not producing any outputs

View File

@ -240,7 +240,7 @@ const std::vector<int32_t> GLONASS_GNAV_CRC_P_INDEX{66, 67, 68, 69, 70, 71, 72,
const std::vector<int32_t> GLONASS_GNAV_CRC_Q_INDEX{9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85};
// GLONASS GNAV NAVIGATION MESSAGE STRUCTURE
// NAVIGATION MESSAGE FIELDS POSITIONS (from IS-GPS-200L Appendix II)
// NAVIGATION MESSAGE FIELDS POSITIONS
// FRAME 1-4
// COMMON FIELDS

View File

@ -30,7 +30,7 @@
// CNAV GPS NAVIGATION MESSAGE STRUCTURE
// NAVIGATION MESSAGE FIELDS POSITIONS (from IS-GPS-200L Appendix III)
// NAVIGATION MESSAGE FIELDS POSITIONS (from IS-GPS-200M Appendix III)
constexpr int32_t GPS_CNAV_DATA_PAGE_BITS = 300;
@ -159,8 +159,8 @@ constexpr int32_t CNAV_DN_LSB = 1;
const std::vector<std::pair<int32_t, int32_t> > CNAV_DELTA_TLSF({{218, 8}});
constexpr int32_t CNAV_DELTA_TLSF_LSB = 1;
constexpr double CNAV_A_REF = 26559710.0; // See IS-GPS-200L, pp. 161
constexpr double CNAV_OMEGA_DOT_REF = -2.6e-9; // semicircles / s, see IS-GPS-200L pp. 160
constexpr double CNAV_A_REF = 26559710.0; // [m] See IS-GPS-200M, Table 30-I.
constexpr double CNAV_OMEGA_DOT_REF = -2.6e-9; // [semicircles / s], see IS-GPS-200M, Table 30-I.
// TODO: Add more frames (Almanac, etc...)

View File

@ -73,7 +73,7 @@ constexpr char GPS_CA_PREAMBLE[9] = "10001011";
constexpr char GPS_CA_PREAMBLE_SYMBOLS_STR[161] = "1111111111111111111100000000000000000000000000000000000000000000000000000000000011111111111111111111000000000000000000001111111111111111111111111111111111111111";
// GPS NAVIGATION MESSAGE STRUCTURE
// NAVIGATION MESSAGE FIELDS POSITIONS (from IS-GPS-200L Appendix II)
// NAVIGATION MESSAGE FIELDS POSITIONS (from IS-GPS-200M Appendix II)
// SUBFRAME 1-5 (TLM and HOW)

View File

@ -28,8 +28,8 @@ constexpr double SPEED_OF_LIGHT_M_S = 299792458.0; //!< Speed of light in
constexpr double SPEED_OF_LIGHT_M_MS = 299792.4580; //!< Speed of light in vacuum [m/ms]
// Physical constants for GPS
constexpr double GPS_GM = 3.986005e14; //!< Universal gravitational constant times the mass of the Earth, [m^3/s^2] IS-GPS-200L, pag 96
constexpr double GPS_F = -4.442807633e-10; //!< Constant, [s/(m)^(1/2)], IS-GPS-200L, pag. 95
constexpr double GPS_GM = 3.986005e14; //!< Universal gravitational constant times the mass of the Earth, [m^3/s^2] IS-GPS-200M, 20.3.3.3.3.1
constexpr double GPS_F = -4.442807633e-10; //!< Constant, [s/(m)^(1/2)], IS-GPS-200M, 20.3.3.3.3.1
// Physical constants for Galileo
constexpr double GALILEO_GM = 3.986004418e14; //!< Geocentric gravitational constant[m^3/s^2], OS SIS ICD v2.0, pag. 44

View File

@ -44,7 +44,7 @@ public:
*/
Beidou_Dnav_Ephemeris();
int SV_accuracy{}; //!< User Range Accuracy (URA) index of the SV (reference paragraph 6.2.1) for the standard positioning service user (Ref 20.3.3.3.1.3 IS-GPS-200L)
int SV_accuracy{}; //!< User Range Accuracy (URA) index of the SV (reference paragraph 5.2.4.5) for the standard positioning service user
int SV_health{};
double TGD1{}; //!< Estimated Group Delay Differential on B1I [s]
double TGD2{}; //!< Estimated Group Delay Differential on B2I [s]

View File

@ -90,7 +90,6 @@ public:
/*!
* \brief Sets (\a d_satClkDrift)and returns the clock drift in seconds according to the User Algorithm for SV Clock Correction
* (IS-GPS-200L, 20.3.3.3.3.1)
*/
double sv_clock_drift(double transmitTime, double timeCorrUTC);
@ -169,7 +168,6 @@ private:
/*
* Accounts for the beginning or end of week crossover
*
* See paragraph 20.3.3.3.3.1 (IS-GPS-200L)
* \param[in] - time in seconds
* \param[out] - corrected time, in seconds
*/

View File

@ -32,7 +32,7 @@ public:
/*!
* \brief Sets (\a satClkDrift) and (\a dtr), and returns the clock drift in
* seconds according to the User Algorithm for SV Clock Correction
* (IS-GPS-200L, 20.3.3.3.3.1, and Galileo OS SIS ICD, 5.1.4).
* (IS-GPS-200M, 20.3.3.3.3.1, and Galileo OS SIS ICD, 5.1.4).
*/
double sv_clock_drift(double transmitTime);

View File

@ -321,7 +321,7 @@ std::string Gnss_Satellite::what_block(const std::string& system_, uint32_t PRN_
block_ = std::string("IIF"); // Plane E
break;
case 11:
block_ = std::string("IIR"); // Plane D
block_ = std::string("III"); // Plane D
break;
case 12:
block_ = std::string("IIR-M"); // Plane B
@ -330,7 +330,7 @@ std::string Gnss_Satellite::what_block(const std::string& system_, uint32_t PRN_
block_ = std::string("IIR"); // Plane F
break;
case 14:
block_ = std::string("Decommissioned"); // Plane F
block_ = std::string("III"); // Plane B
break;
case 15:
block_ = std::string("IIR-M"); // Plane F

View File

@ -28,9 +28,9 @@
/*!
* \brief This class is a storage for the GPS SV ALMANAC data as described in IS-GPS-200L
* \brief This class is a storage for the GPS SV ALMANAC data as described in IS-GPS-200M
*
* See https://www.gps.gov/technical/icwg/IS-GPS-200L.pdf Appendix II
* See https://www.gps.gov/technical/icwg/IS-GPS-200M.pdf Appendix II
*/
class Gps_Almanac : public Gnss_Almanac
{

View File

@ -30,9 +30,9 @@
/*!
* \brief This is a storage class for the GPS CNAV ephemeris data as described
* in IS-GPS-200L
* in IS-GPS-200M
*
* See https://www.gps.gov/technical/icwg/IS-GPS-200L.pdf Appendix III
* See https://www.gps.gov/technical/icwg/IS-GPS-200M.pdf Appendix III
*/
class Gps_CNAV_Ephemeris : public Gnss_Ephemeris
{
@ -49,8 +49,8 @@ public:
double Adot{}; //!< Change rate in semi-major axis
double delta_ndot{}; //!< Rate of mean motion difference from computed value
double delta_OMEGAdot{}; //!< Rate of Right Ascension difference [semi-circles/s]
int32_t toe1{}; //!< Ephemeris data reference time of week (Ref. 20.3.3.4.3 IS-GPS-200L) [s]
int32_t toe2{}; //!< Ephemeris data reference time of week (Ref. 20.3.3.4.3 IS-GPS-200L) [s]
int32_t toe1{}; //!< Ephemeris data reference time of week (Ref. 20.3.3.4.3 IS-GPS-200M) [s]
int32_t toe2{}; //!< Ephemeris data reference time of week (Ref. 20.3.3.4.3 IS-GPS-200M) [s]
int32_t signal_health{}; //!< Signal health (L1/L2/L5)
int32_t top{}; //!< Data predict time of week
int32_t URA{}; //!< ED Accuracy Index

View File

@ -27,9 +27,9 @@
/*!
* \brief This class is a storage for the GPS IONOSPHERIC data as described in IS-GPS-200L
* \brief This class is a storage for the GPS IONOSPHERIC data as described in IS-GPS-200M
*
* See https://www.gps.gov/technical/icwg/IS-GPS-200L.pdf Appendix III
* See https://www.gps.gov/technical/icwg/IS-GPS-200M.pdf Appendix III
*/
class Gps_CNAV_Iono : public Gps_Iono
{

View File

@ -1,8 +1,8 @@
/*!
* \file gps_cnav_navigation_message.cc
* \brief Implementation of a GPS CNAV Data message decoder as described in IS-GPS-200L
* \brief Implementation of a GPS CNAV Data message decoder as described in IS-GPS-200M
*
* See https://www.gps.gov/technical/icwg/IS-GPS-200L.pdf Appendix III
* See https://www.gps.gov/technical/icwg/IS-GPS-200M.pdf Appendix III
* \author Javier Arribas, 2015. jarribas(at)cttc.es
*
* -----------------------------------------------------------------------------

View File

@ -37,9 +37,9 @@
/*!
* \brief This class decodes a GPS CNAV Data message as described in IS-GPS-200L
* \brief This class decodes a GPS CNAV Data message as described in IS-GPS-200M
*
* See https://www.gps.gov/technical/icwg/IS-GPS-200L.pdf Appendix III
* See https://www.gps.gov/technical/icwg/IS-GPS-200M.pdf Appendix III
*/
class Gps_CNAV_Navigation_Message
{

View File

@ -27,9 +27,9 @@
/*!
* \brief This class is a storage for the GPS UTC MODEL data as described in in IS-GPS-200L
* \brief This class is a storage for the GPS UTC MODEL data as described in in IS-GPS-200M
*
* See https://www.gps.gov/technical/icwg/IS-GPS-200L.pdf Appendix III
* See https://www.gps.gov/technical/icwg/IS-GPS-200M.pdf Appendix III
*/
class Gps_CNAV_Utc_Model : public Gps_Utc_Model
{

View File

@ -2,7 +2,7 @@
* \file gps_ephemeris.cc
* \brief Interface of a GPS EPHEMERIS storage and orbital model functions
*
* See https://www.gps.gov/technical/icwg/IS-GPS-200L.pdf Appendix II
* See https://www.gps.gov/technical/icwg/IS-GPS-200M.pdf Appendix II
* \author Javier Arribas, 2013. jarribas(at)cttc.es
*
* -----------------------------------------------------------------------------

View File

@ -33,9 +33,9 @@
/*!
* \brief This class is a storage and orbital model functions for the GPS SV
* ephemeris data as described in IS-GPS-200L
* ephemeris data as described in IS-GPS-200M
*
* See https://www.gps.gov/technical/icwg/IS-GPS-200L.pdf Appendix II
* See https://www.gps.gov/technical/icwg/IS-GPS-200M.pdf Appendix II
*/
class Gps_Ephemeris : public Gnss_Ephemeris
{
@ -47,7 +47,7 @@ public:
int32_t code_on_L2{}; //!< If 1, P code ON in L2; if 2, C/A code ON in L2;
bool L2_P_data_flag{}; //!< When true, indicates that the NAV data stream was commanded OFF on the P-code of the L2 channel
int32_t SV_accuracy{}; //!< User Range Accuracy (URA) index of the SV (reference paragraph 6.2.1) for the standard positioning service user (Ref 20.3.3.3.1.3 IS-GPS-200L)
int32_t SV_accuracy{}; //!< User Range Accuracy (URA) index of the SV (reference paragraph 6.2.1) for the standard positioning service user (Ref 20.3.3.3.1.3 IS-GPS-200M)
int32_t SV_health{}; //!< Satellite heath status
double TGD{}; //!< Estimated Group Delay Differential: L1-L2 correction term only for the benefit of "L1 P(Y)" or "L2 P(Y)" s users [s]
int32_t IODC{}; //!< Issue of Data, Clock

View File

@ -28,9 +28,9 @@
/*!
* \brief This class is a storage for the GPS IONOSPHERIC data as described in IS-GPS-200L
* \brief This class is a storage for the GPS IONOSPHERIC data as described in IS-GPS-200M
*
* See https://www.gps.gov/technical/icwg/IS-GPS-200L.pdf Appendix II
* See https://www.gps.gov/technical/icwg/IS-GPS-200M.pdf Appendix II
*/
class Gps_Iono
{

View File

@ -1,9 +1,9 @@
/*!
* \file gps_navigation_message.cc
* \brief Implementation of a GPS NAV Data message decoder as described in IS-GPS-200L
* \brief Implementation of a GPS NAV Data message decoder as described in IS-GPS-200M
* \author Javier Arribas, 2011. jarribas(at)cttc.es
*
* See https://www.gps.gov/technical/icwg/IS-GPS-200L.pdf Appendix II
* See https://www.gps.gov/technical/icwg/IS-GPS-200M.pdf Appendix II
*
*
* -----------------------------------------------------------------------------
@ -135,7 +135,7 @@ int32_t Gps_Navigation_Message::subframe_decoder(char* subframe)
switch (subframe_ID)
{
// --- Decode the sub-frame id -----------------------------------------
// ICD (IS-GPS-200L Appendix II). https://www.gps.gov/technical/icwg/IS-GPS-200L.pdf
// ICD (IS-GPS-200M Appendix II). https://www.gps.gov/technical/icwg/IS-GPS-200M.pdf
case 1:
// --- It is subframe 1 -------------------------------------
// Compute the time of week (TOW) of the first sub-frames in the array ====
@ -233,7 +233,7 @@ int32_t Gps_Navigation_Message::subframe_decoder(char* subframe)
b_antispoofing_flag = read_navigation_bool(subframe_bits, ANTI_SPOOFING_FLAG);
SV_data_ID = static_cast<int32_t>(read_navigation_unsigned(subframe_bits, SV_DATA_ID));
SV_page = static_cast<int32_t>(read_navigation_unsigned(subframe_bits, SV_PAGE));
if (SV_page > 24 && SV_page < 33) // Page 4 (from Table 20-V. Data IDs and SV IDs in Subframes 4 and 5, IS-GPS-200L, page 110)
if (SV_page > 24 && SV_page < 33) // Page 4 (from Table 20-V. Data IDs and SV IDs in Subframes 4 and 5, IS-GPS-200M)
{
//! \TODO read almanac
if (SV_data_ID != 0)
@ -241,12 +241,12 @@ int32_t Gps_Navigation_Message::subframe_decoder(char* subframe)
}
}
if (SV_page == 52) // Page 13 (from Table 20-V. Data IDs and SV IDs in Subframes 4 and 5, IS-GPS-200L, page 110)
if (SV_page == 52) // Page 13 (from Table 20-V. Data IDs and SV IDs in Subframes 4 and 5, IS-GPS-200M)
{
//! \TODO read Estimated Range Deviation (ERD) values
}
if (SV_page == 56) // Page 18 (from Table 20-V. Data IDs and SV IDs in Subframes 4 and 5, IS-GPS-200L, page 110)
if (SV_page == 56) // Page 18 (from Table 20-V. Data IDs and SV IDs in Subframes 4 and 5, IS-GPS-200M)
{
// Page 18 - Ionospheric and UTC data
d_alpha0 = static_cast<double>(read_navigation_signed(subframe_bits, ALPHA_0));
@ -284,7 +284,7 @@ int32_t Gps_Navigation_Message::subframe_decoder(char* subframe)
// Reserved
}
if (SV_page == 63) // Page 25 (from Table 20-V. Data IDs and SV IDs in Subframes 4 and 5, IS-GPS-200L, page 110)
if (SV_page == 63) // Page 25 (from Table 20-V. Data IDs and SV IDs in Subframes 4 and 5, IS-GPS-200M)
{
// Page 25 Anti-Spoofing, SV config and almanac health (PRN: 25-32)
//! \TODO Read Anti-Spoofing, SV config
@ -317,7 +317,7 @@ int32_t Gps_Navigation_Message::subframe_decoder(char* subframe)
{
}
}
if (SV_page_5 == 51) // Page 25 (from Table 20-V. Data IDs and SV IDs in Subframes 4 and 5, IS-GPS-200L, page 110)
if (SV_page_5 == 51) // Page 25 (from Table 20-V. Data IDs and SV IDs in Subframes 4 and 5, IS-GPS-200M)
{
i_Toa = static_cast<int32_t>(read_navigation_unsigned(subframe_bits, T_OA));
i_Toa = i_Toa * T_OA_LSB;

View File

@ -38,9 +38,9 @@
/*!
* \brief This class decodes a GPS NAV Data message as described in IS-GPS-200L
* \brief This class decodes a GPS NAV Data message as described in IS-GPS-200M
*
* See https://www.gps.gov/technical/icwg/IS-GPS-200L.pdf Appendix II
* See https://www.gps.gov/technical/icwg/IS-GPS-200M.pdf Appendix II
*/
class Gps_Navigation_Message
{
@ -72,7 +72,7 @@ public:
/*!
* \brief Computes the Coordinated Universal Time (UTC) and
* returns it in [s] (IS-GPS-200L, 20.3.3.5.2.4)
* returns it in [s] (IS-GPS-200M, 20.3.3.5.2.4)
*/
double utc_time(const double gpstime_corrected) const;
@ -162,8 +162,8 @@ private:
double d_Cus{}; // Amplitude of the Sine Harmonic Correction Term to the Argument of Latitude [rad]
double d_sqrt_A{}; // Square Root of the Semi-Major Axis [sqrt(m)]
// broadcast orbit 3
int32_t d_Toe{}; // Ephemeris data reference time of week (Ref. 20.3.3.4.3 IS-GPS-200L) [s]
int32_t d_Toc{}; // clock data reference time (Ref. 20.3.3.3.3.1 IS-GPS-200L) [s]
int32_t d_Toe{}; // Ephemeris data reference time of week (Ref. 20.3.3.4.3 IS-GPS-200M) [s]
int32_t d_Toc{}; // clock data reference time (Ref. 20.3.3.3.3.1 IS-GPS-200M) [s]
double d_Cic{}; // Amplitude of the Cosine Harmonic Correction Term to the Angle of Inclination [rad]
double d_OMEGA0{}; // Longitude of Ascending Node of Orbit Plane at Weekly Epoch [semi-circles]
double d_Cis{}; // Amplitude of the Sine Harmonic Correction Term to the Angle of Inclination [rad]
@ -178,7 +178,7 @@ private:
int32_t i_GPS_week{}; // GPS week number, aka WN [week]
bool b_L2_P_data_flag{}; // When true, indicates that the NAV data stream was commanded OFF on the P-code of the L2 channel
// broadcast orbit 6
int32_t i_SV_accuracy{}; // User Range Accuracy (URA) index of the SV (reference paragraph 6.2.1) for the standard positioning service user (Ref 20.3.3.3.1.3 IS-GPS-200L)
int32_t i_SV_accuracy{}; // User Range Accuracy (URA) index of the SV (reference paragraph 6.2.1) for the standard positioning service user (Ref 20.3.3.3.1.3 IS-GPS-200M)
int32_t i_SV_health{};
double d_TGD{}; // Estimated Group Delay Differential: L1-L2 correction term only for the benefit of "L1 P(Y)" or "L2 P(Y)" s users [s]
int32_t d_IODC{}; // Issue of Data, Clock
@ -226,10 +226,10 @@ private:
double d_beta3{}; // Coefficient 3 of a cubic equation representing the period of the model [s(semi-circle)^3]
// UTC parameters
double d_A0{}; // Constant of a model that relates GPS and UTC time (ref. 20.3.3.5.2.4 IS-GPS-200L) [s]
double d_A1{}; // 1st order term of a model that relates GPS and UTC time (ref. 20.3.3.5.2.4 IS-GPS-200L) [s/s]
double d_A0{}; // Constant of a model that relates GPS and UTC time (ref. 20.3.3.5.2.4 IS-GPS-200M) [s]
double d_A1{}; // 1st order term of a model that relates GPS and UTC time (ref. 20.3.3.5.2.4 IS-GPS-200M) [s/s]
int32_t d_t_OT{}; // Reference time for UTC data (reference 20.3.4.5 and 20.3.3.5.2.4 IS-GPS-200L) [s]
int32_t d_t_OT{}; // Reference time for UTC data (reference 20.3.4.5 and 20.3.3.5.2.4 IS-GPS-200M) [s]
int32_t i_WN_T{}; // UTC reference week number [weeks]
int32_t d_DeltaT_LS{}; // delta time due to leap seconds [s]. Number of leap seconds since 6-Jan-1980 as transmitted by the GPS almanac.
int32_t i_WN_LSF{}; // Week number at the end of which the leap second becomes effective [weeks]

View File

@ -28,9 +28,9 @@
/*!
* \brief This class is a storage for the GPS UTC MODEL data as described in IS-GPS-200L
* \brief This class is a storage for the GPS UTC MODEL data as described in IS-GPS-200M
*
* See https://www.gps.gov/technical/icwg/IS-GPS-200L.pdf Appendix II
* See https://www.gps.gov/technical/icwg/IS-GPS-200M.pdf Appendix II
*/
class Gps_Utc_Model
{
@ -41,10 +41,10 @@ public:
Gps_Utc_Model() = default;
// UTC parameters
double A0{}; //!< Constant of a model that relates GPS and UTC time (ref. 20.3.3.5.2.4 IS-GPS-200L) [s]
double A1{}; //!< 1st order term of a model that relates GPS and UTC time (ref. 20.3.3.5.2.4 IS-GPS-200L) [s/s]
double A2{}; //!< 2nd order term of a model that relates GPS and UTC time (ref. 20.3.3.5.2.4 IS-GPS-200L) [s/s]
int32_t tot{}; //!< Reference time for UTC data (reference 20.3.4.5 and 20.3.3.5.2.4 IS-GPS-200L) [s]
double A0{}; //!< Constant of a model that relates GPS and UTC time (ref. 20.3.3.5.2.4 IS-GPS-200M) [s]
double A1{}; //!< 1st order term of a model that relates GPS and UTC time (ref. 20.3.3.5.2.4 IS-GPS-200M) [s/s]
double A2{}; //!< 2nd order term of a model that relates GPS and UTC time (ref. 20.3.3.5.2.4 IS-GPS-200M) [s/s]
int32_t tot{}; //!< Reference time for UTC data (reference 20.3.4.5 and 20.3.3.5.2.4 IS-GPS-200M) [s]
int32_t WN_T{}; //!< UTC reference week number [weeks]
int32_t DeltaT_LS{}; //!< Delta time due to leap seconds [s]. Number of leap seconds since 6-Jan-1980 as transmitted by the GPS almanac.
int32_t WN_LSF{}; //!< Week number at the end of which the leap second becomes effective [weeks]

View File

@ -86,7 +86,7 @@ macro(add_benchmark)
target_link_libraries(${ARGV0} PRIVATE benchmark::benchmark)
if(${ARGC} GREATER 1)
set(list_dependencies "${ARGN}")
list(REMOVE_AT list_dependencies 0 list_dependencies)
list(REMOVE_AT list_dependencies 0)
foreach(dependency IN LISTS list_dependencies)
target_link_libraries(${ARGV0} PRIVATE ${dependency})
endforeach()