mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2025-04-14 14:53:18 +00:00
Merge with next
This commit is contained in:
commit
29f59256be
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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/
|
||||
|
@ -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.
|
||||
|
||||
|
||||
|
||||
|
@ -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)~,
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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")
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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_
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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";
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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)");
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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...)
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
|
@ -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]
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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]
|
||||
|
@ -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]
|
||||
|
@ -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()
|
||||
|
Loading…
x
Reference in New Issue
Block a user