From d835b4958c8392488e774560d3b72b20240d544d Mon Sep 17 00:00:00 2001 From: Tamas Zsoldos Date: Fri, 11 Oct 2019 11:02:00 +0200 Subject: [PATCH] Update features for AArch64. Add all missing features up to Linux v5.0. Features added: evtstrm, atomics, fphp, asimdhp, cpuid, asimdrdm, jscvt, fcma, lrcpc, dcpop, sha3, sm3, sm4, asimddp, sha512, sve, asimdfhm, dit, uscat, ilrcpc, flagm, ssbs, sb, paca, pacg. --- include/cpuinfo_aarch64.h | 64 +++++++++++++++++--- include/internal/hwcaps.h | 25 ++++++++ src/cpuinfo_aarch64.c | 114 ++++++++++++++++++++++++++++++++--- test/cpuinfo_aarch64_test.cc | 51 ++++++++++++++++ 4 files changed, 240 insertions(+), 14 deletions(-) diff --git a/include/cpuinfo_aarch64.h b/include/cpuinfo_aarch64.h index cd3a676..5a7532e 100644 --- a/include/cpuinfo_aarch64.h +++ b/include/cpuinfo_aarch64.h @@ -21,13 +21,38 @@ CPU_FEATURES_START_CPP_NAMESPACE typedef struct { - int fp : 1; // Floating-point. - int asimd : 1; // Advanced SIMD. - int aes : 1; // Hardware-accelerated Advanced Encryption Standard. - int pmull : 1; // Polynomial multiply long. - int sha1 : 1; // Hardware-accelerated SHA1. - int sha2 : 1; // Hardware-accelerated SHA2-256. - int crc32 : 1; // Hardware-accelerated CRC-32. + int fp : 1; // Floating-point. + int asimd : 1; // Advanced SIMD. + int evtstrm : 1; // Generic timer generated events. + int aes : 1; // Hardware-accelerated Advanced Encryption Standard. + int pmull : 1; // Polynomial multiply long. + int sha1 : 1; // Hardware-accelerated SHA1. + int sha2 : 1; // Hardware-accelerated SHA2-256. + int crc32 : 1; // Hardware-accelerated CRC-32. + int atomics : 1; // Armv8.1 atomic instructions. + int fphp : 1; // Half-precision floating point support. + int asimdhp : 1; // Advanced SIMD half-precision support. + int cpuid : 1; // Access to certain ID registers. + int asimdrdm : 1; // Rounding Double Multiply Accumulate/Subtract. + int jscvt : 1; // Support for JavaScript conversion. + int fcma : 1; // Floating point complex numbers. + int lrcpc : 1; // Support for weaker release consistency. + int dcpop : 1; // Data persistence writeback. + int sha3 : 1; // Hardware-accelerated SHA3. + int sm3 : 1; // Hardware-accelerated SM3. + int sm4 : 1; // Hardware-accelerated SM4. + int asimddp : 1; // Dot product instruction. + int sha512 : 1; // Hardware-accelerated SHA512. + int sve : 1; // Scalable Vector Extension. + int asimdfhm : 1; // Additional half-precision instructions. + int dit : 1; // Data independent timing. + int uscat : 1; // Unaligned atomics support. + int ilrcpc : 1; // Additional support for weaker release consistency. + int flagm : 1; // Flag manipulation instructions. + int ssbs : 1; // Speculative Store Bypass Safe PSTATE bit. + int sb : 1; // Speculation barrier. + int paca : 1; // Address authentication. + int pacg : 1; // Generic authentication. // Make sure to update Aarch64FeaturesEnum below if you add a field here. } Aarch64Features; @@ -48,11 +73,36 @@ Aarch64Info GetAarch64Info(void); typedef enum { AARCH64_FP, AARCH64_ASIMD, + AARCH64_EVTSTRM, AARCH64_AES, AARCH64_PMULL, AARCH64_SHA1, AARCH64_SHA2, AARCH64_CRC32, + AARCH64_ATOMICS, + AARCH64_FPHP, + AARCH64_ASIMDHP, + AARCH64_CPUID, + AARCH64_ASIMDRDM, + AARCH64_JSCVT, + AARCH64_FCMA, + AARCH64_LRCPC, + AARCH64_DCPOP, + AARCH64_SHA3, + AARCH64_SM3, + AARCH64_SM4, + AARCH64_ASIMDDP, + AARCH64_SHA512, + AARCH64_SVE, + AARCH64_ASIMDFHM, + AARCH64_DIT, + AARCH64_USCAT, + AARCH64_ILRCPC, + AARCH64_FLAGM, + AARCH64_SSBS, + AARCH64_SB, + AARCH64_PACA, + AARCH64_PACG, AARCH64_LAST_, } Aarch64FeaturesEnum; diff --git a/include/internal/hwcaps.h b/include/internal/hwcaps.h index 06a0f60..eb54f5c 100644 --- a/include/internal/hwcaps.h +++ b/include/internal/hwcaps.h @@ -28,11 +28,36 @@ CPU_FEATURES_START_CPP_NAMESPACE // http://elixir.free-electrons.com/linux/latest/source/arch/arm64/include/uapi/asm/hwcap.h #define AARCH64_HWCAP_FP (1UL << 0) #define AARCH64_HWCAP_ASIMD (1UL << 1) +#define AARCH64_HWCAP_EVTSTRM (1UL << 2) #define AARCH64_HWCAP_AES (1UL << 3) #define AARCH64_HWCAP_PMULL (1UL << 4) #define AARCH64_HWCAP_SHA1 (1UL << 5) #define AARCH64_HWCAP_SHA2 (1UL << 6) #define AARCH64_HWCAP_CRC32 (1UL << 7) +#define AARCH64_HWCAP_ATOMICS (1UL << 8) +#define AARCH64_HWCAP_FPHP (1UL << 9) +#define AARCH64_HWCAP_ASIMDHP (1UL << 10) +#define AARCH64_HWCAP_CPUID (1UL << 11) +#define AARCH64_HWCAP_ASIMDRDM (1UL << 12) +#define AARCH64_HWCAP_JSCVT (1UL << 13) +#define AARCH64_HWCAP_FCMA (1UL << 14) +#define AARCH64_HWCAP_LRCPC (1UL << 15) +#define AARCH64_HWCAP_DCPOP (1UL << 16) +#define AARCH64_HWCAP_SHA3 (1UL << 17) +#define AARCH64_HWCAP_SM3 (1UL << 18) +#define AARCH64_HWCAP_SM4 (1UL << 19) +#define AARCH64_HWCAP_ASIMDDP (1UL << 20) +#define AARCH64_HWCAP_SHA512 (1UL << 21) +#define AARCH64_HWCAP_SVE (1UL << 22) +#define AARCH64_HWCAP_ASIMDFHM (1UL << 23) +#define AARCH64_HWCAP_DIT (1UL << 24) +#define AARCH64_HWCAP_USCAT (1UL << 25) +#define AARCH64_HWCAP_ILRCPC (1UL << 26) +#define AARCH64_HWCAP_FLAGM (1UL << 27) +#define AARCH64_HWCAP_SSBS (1UL << 28) +#define AARCH64_HWCAP_SB (1UL << 29) +#define AARCH64_HWCAP_PACA (1UL << 30) +#define AARCH64_HWCAP_PACG (1UL << 31) // http://elixir.free-electrons.com/linux/latest/source/arch/arm/include/uapi/asm/hwcap.h #define ARM_HWCAP_SWP (1UL << 0) diff --git a/src/cpuinfo_aarch64.c b/src/cpuinfo_aarch64.c index 26a07d3..3a04bf6 100644 --- a/src/cpuinfo_aarch64.c +++ b/src/cpuinfo_aarch64.c @@ -25,20 +25,70 @@ DECLARE_SETTER(Aarch64Features, fp) DECLARE_SETTER(Aarch64Features, asimd) +DECLARE_SETTER(Aarch64Features, evtstrm) DECLARE_SETTER(Aarch64Features, aes) DECLARE_SETTER(Aarch64Features, pmull) DECLARE_SETTER(Aarch64Features, sha1) DECLARE_SETTER(Aarch64Features, sha2) DECLARE_SETTER(Aarch64Features, crc32) +DECLARE_SETTER(Aarch64Features, atomics) +DECLARE_SETTER(Aarch64Features, fphp) +DECLARE_SETTER(Aarch64Features, asimdhp) +DECLARE_SETTER(Aarch64Features, cpuid) +DECLARE_SETTER(Aarch64Features, asimdrdm) +DECLARE_SETTER(Aarch64Features, jscvt) +DECLARE_SETTER(Aarch64Features, fcma) +DECLARE_SETTER(Aarch64Features, lrcpc) +DECLARE_SETTER(Aarch64Features, dcpop) +DECLARE_SETTER(Aarch64Features, sha3) +DECLARE_SETTER(Aarch64Features, sm3) +DECLARE_SETTER(Aarch64Features, sm4) +DECLARE_SETTER(Aarch64Features, asimddp) +DECLARE_SETTER(Aarch64Features, sha512) +DECLARE_SETTER(Aarch64Features, sve) +DECLARE_SETTER(Aarch64Features, asimdfhm) +DECLARE_SETTER(Aarch64Features, dit) +DECLARE_SETTER(Aarch64Features, uscat) +DECLARE_SETTER(Aarch64Features, ilrcpc) +DECLARE_SETTER(Aarch64Features, flagm) +DECLARE_SETTER(Aarch64Features, ssbs) +DECLARE_SETTER(Aarch64Features, sb) +DECLARE_SETTER(Aarch64Features, paca) +DECLARE_SETTER(Aarch64Features, pacg) static const CapabilityConfig kConfigs[] = { - [AARCH64_FP] = {{AARCH64_HWCAP_FP, 0}, "fp", &set_fp}, // - [AARCH64_ASIMD] = {{AARCH64_HWCAP_ASIMD, 0}, "asimd", &set_asimd}, // - [AARCH64_AES] = {{AARCH64_HWCAP_AES, 0}, "aes", &set_aes}, // - [AARCH64_PMULL] = {{AARCH64_HWCAP_PMULL, 0}, "pmull", &set_pmull}, // - [AARCH64_SHA1] = {{AARCH64_HWCAP_SHA1, 0}, "sha1", &set_sha1}, // - [AARCH64_SHA2] = {{AARCH64_HWCAP_SHA2, 0}, "sha2", &set_sha2}, // - [AARCH64_CRC32] {{AARCH64_HWCAP_CRC32, 0}, "crc32", &set_crc32}, // + [AARCH64_FP] = {{AARCH64_HWCAP_FP, 0}, "fp", &set_fp}, + [AARCH64_ASIMD] = {{AARCH64_HWCAP_ASIMD, 0}, "asimd", &set_asimd}, + [AARCH64_EVTSTRM] = {{AARCH64_HWCAP_EVTSTRM, 0}, "evtstrm", &set_evtstrm}, + [AARCH64_AES] = {{AARCH64_HWCAP_AES, 0}, "aes", &set_aes}, + [AARCH64_PMULL] = {{AARCH64_HWCAP_PMULL, 0}, "pmull", &set_pmull}, + [AARCH64_SHA1] = {{AARCH64_HWCAP_SHA1, 0}, "sha1", &set_sha1}, + [AARCH64_SHA2] = {{AARCH64_HWCAP_SHA2, 0}, "sha2", &set_sha2}, + [AARCH64_CRC32] = {{AARCH64_HWCAP_CRC32, 0}, "crc32", &set_crc32}, + [AARCH64_ATOMICS] = {{AARCH64_HWCAP_ATOMICS, 0}, "atomics", &set_atomics}, + [AARCH64_FPHP] = {{AARCH64_HWCAP_FPHP, 0}, "fphp", &set_fphp}, + [AARCH64_ASIMDHP] = {{AARCH64_HWCAP_ASIMDHP, 0}, "asimdhp", &set_asimdhp}, + [AARCH64_CPUID] = {{AARCH64_HWCAP_CPUID, 0}, "cpuid", &set_cpuid}, + [AARCH64_ASIMDRDM] = {{AARCH64_HWCAP_ASIMDRDM, 0}, "asimdrdm", &set_asimdrdm}, + [AARCH64_JSCVT] = {{AARCH64_HWCAP_JSCVT, 0}, "jscvt", &set_jscvt}, + [AARCH64_FCMA] = {{AARCH64_HWCAP_FCMA, 0}, "fcma", &set_fcma}, + [AARCH64_LRCPC] = {{AARCH64_HWCAP_LRCPC, 0}, "lrcpc", &set_lrcpc}, + [AARCH64_DCPOP] = {{AARCH64_HWCAP_DCPOP, 0}, "dcpop", &set_dcpop}, + [AARCH64_SHA3] = {{AARCH64_HWCAP_SHA3, 0}, "sha3", &set_sha3}, + [AARCH64_SM3] = {{AARCH64_HWCAP_SM3, 0}, "sm3", &set_sm3}, + [AARCH64_SM4] = {{AARCH64_HWCAP_SM4, 0}, "sm4", &set_sm4}, + [AARCH64_ASIMDDP] = {{AARCH64_HWCAP_ASIMDDP, 0}, "asimddp", &set_asimddp}, + [AARCH64_SHA512] = {{AARCH64_HWCAP_SHA512, 0}, "sha512", &set_sha512}, + [AARCH64_SVE] = {{AARCH64_HWCAP_SVE, 0}, "sve", &set_sve}, + [AARCH64_ASIMDFHM] = {{AARCH64_HWCAP_ASIMDFHM, 0}, "asimdfhm", &set_asimdfhm}, + [AARCH64_DIT] = {{AARCH64_HWCAP_DIT, 0}, "dit", &set_dit}, + [AARCH64_USCAT] = {{AARCH64_HWCAP_USCAT, 0}, "uscat", &set_uscat}, + [AARCH64_ILRCPC] = {{AARCH64_HWCAP_ILRCPC, 0}, "ilrcpc", &set_ilrcpc}, + [AARCH64_FLAGM] = {{AARCH64_HWCAP_FLAGM, 0}, "flagm", &set_flagm}, + [AARCH64_SSBS] = {{AARCH64_HWCAP_SSBS, 0}, "ssbs", &set_ssbs}, + [AARCH64_SB] = {{AARCH64_HWCAP_SB, 0}, "sb", &set_sb}, + [AARCH64_PACA] = {{AARCH64_HWCAP_PACA, 0}, "paca", &set_paca}, + [AARCH64_PACG] = {{AARCH64_HWCAP_PACG, 0}, "pacg", &set_pacg}, }; static const size_t kConfigsSize = sizeof(kConfigs) / sizeof(CapabilityConfig); @@ -105,6 +155,8 @@ int GetAarch64FeaturesEnumValue(const Aarch64Features* features, return features->fp; case AARCH64_ASIMD: return features->asimd; + case AARCH64_EVTSTRM: + return features->evtstrm; case AARCH64_AES: return features->aes; case AARCH64_PMULL: @@ -115,6 +167,54 @@ int GetAarch64FeaturesEnumValue(const Aarch64Features* features, return features->sha2; case AARCH64_CRC32: return features->crc32; + case AARCH64_ATOMICS: + return features->atomics; + case AARCH64_FPHP: + return features->fphp; + case AARCH64_ASIMDHP: + return features->asimdhp; + case AARCH64_CPUID: + return features->cpuid; + case AARCH64_ASIMDRDM: + return features->asimdrdm; + case AARCH64_JSCVT: + return features->jscvt; + case AARCH64_FCMA: + return features->fcma; + case AARCH64_LRCPC: + return features->lrcpc; + case AARCH64_DCPOP: + return features->dcpop; + case AARCH64_SHA3: + return features->sha3; + case AARCH64_SM3: + return features->sm3; + case AARCH64_SM4: + return features->sm4; + case AARCH64_ASIMDDP: + return features->asimddp; + case AARCH64_SHA512: + return features->sha512; + case AARCH64_SVE: + return features->sve; + case AARCH64_ASIMDFHM: + return features->asimdfhm; + case AARCH64_DIT: + return features->dit; + case AARCH64_USCAT: + return features->uscat; + case AARCH64_ILRCPC: + return features->ilrcpc; + case AARCH64_FLAGM: + return features->flagm; + case AARCH64_SSBS: + return features->ssbs; + case AARCH64_SB: + return features->sb; + case AARCH64_PACA: + return features->paca; + case AARCH64_PACG: + return features->pacg; case AARCH64_LAST_: break; } diff --git a/test/cpuinfo_aarch64_test.cc b/test/cpuinfo_aarch64_test.cc index bdb4d17..e208d35 100644 --- a/test/cpuinfo_aarch64_test.cc +++ b/test/cpuinfo_aarch64_test.cc @@ -29,11 +29,36 @@ TEST(CpuinfoAarch64Test, FromHardwareCap) { const auto info = GetAarch64Info(); EXPECT_TRUE(info.features.fp); EXPECT_FALSE(info.features.asimd); + EXPECT_FALSE(info.features.evtstrm); EXPECT_TRUE(info.features.aes); EXPECT_FALSE(info.features.pmull); EXPECT_FALSE(info.features.sha1); EXPECT_FALSE(info.features.sha2); EXPECT_FALSE(info.features.crc32); + EXPECT_FALSE(info.features.atomics); + EXPECT_FALSE(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_FALSE(info.features.sha3); + EXPECT_FALSE(info.features.sm3); + EXPECT_FALSE(info.features.sm4); + EXPECT_FALSE(info.features.asimddp); + EXPECT_FALSE(info.features.sha512); + EXPECT_FALSE(info.features.sve); + EXPECT_FALSE(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); } TEST(CpuinfoAarch64Test, ARMCortexA53) { @@ -63,11 +88,37 @@ CPU revision : 3)"); EXPECT_TRUE(info.features.fp); EXPECT_TRUE(info.features.asimd); + EXPECT_TRUE(info.features.evtstrm); EXPECT_TRUE(info.features.aes); EXPECT_TRUE(info.features.pmull); EXPECT_TRUE(info.features.sha1); EXPECT_TRUE(info.features.sha2); EXPECT_TRUE(info.features.crc32); + + EXPECT_FALSE(info.features.atomics); + EXPECT_FALSE(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_FALSE(info.features.sha3); + EXPECT_FALSE(info.features.sm3); + EXPECT_FALSE(info.features.sm4); + EXPECT_FALSE(info.features.asimddp); + EXPECT_FALSE(info.features.sha512); + EXPECT_FALSE(info.features.sve); + EXPECT_FALSE(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); } } // namespace