From 5ea64b456b1a27ae046f23d632a968a7583bb9eb Mon Sep 17 00:00:00 2001 From: "Fangming.Fang" Date: Tue, 28 Apr 2020 02:33:50 +0000 Subject: [PATCH] Read MIDR_EL1 system register on aarch64 MIDR_EL1 system register exposes microarchitecture information so that people can make micro-arch related optimization such as exposing as much instruction level parallelism as possible. MIDR_EL1 register can be read only if HWCAP_CPUID feature is supported. Change-Id: Iabb8a36c5d31b184dba6399f378598058d394d4e Reviewed-by: Paul Dale Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/11744) --- crypto/arm64cpuid.pl | 7 +++++++ crypto/arm_arch.h | 44 ++++++++++++++++++++++++++++++++++++++++++++ crypto/armcap.c | 11 +++++++++++ 3 files changed, 62 insertions(+) diff --git a/crypto/arm64cpuid.pl b/crypto/arm64cpuid.pl index 0eadcc43f2b..ac76dd449f3 100755 --- a/crypto/arm64cpuid.pl +++ b/crypto/arm64cpuid.pl @@ -81,6 +81,13 @@ _armv8_sha512_probe: ret .size _armv8_sha512_probe,.-_armv8_sha512_probe +.globl _armv8_cpuid_probe +.type _armv8_cpuid_probe,%function +_armv8_cpuid_probe: + mrs x0, midr_el1 + ret +.size _armv8_cpuid_probe,.-_armv8_cpuid_probe + .globl OPENSSL_cleanse .type OPENSSL_cleanse,%function .align 5 diff --git a/crypto/arm_arch.h b/crypto/arm_arch.h index 2d279d64595..d98154bddb7 100644 --- a/crypto/arm_arch.h +++ b/crypto/arm_arch.h @@ -71,6 +71,7 @@ # ifndef __ASSEMBLER__ extern unsigned int OPENSSL_armcap_P; +extern unsigned int OPENSSL_arm_midr; # endif # define ARMV7_NEON (1<<0) @@ -80,5 +81,48 @@ extern unsigned int OPENSSL_armcap_P; # define ARMV8_SHA256 (1<<4) # define ARMV8_PMULL (1<<5) # define ARMV8_SHA512 (1<<6) +# define ARMV8_CPUID (1<<7) +/* + * MIDR_EL1 system register + * + * 63___ _ ___32_31___ _ ___24_23_____20_19_____16_15__ _ __4_3_______0 + * | | | | | | | + * |RES0 | Implementer | Variant | Arch | PartNum |Revision| + * |____ _ _____|_____ _ _____|_________|_______ _|____ _ ___|________| + * + */ + +# define ARM_CPU_IMP_ARM 0x41 + +# define ARM_CPU_PART_CORTEX_A72 0xD08 +# define ARM_CPU_PART_N1 0xD0C + +# define MIDR_PARTNUM_SHIFT 4 +# define MIDR_PARTNUM_MASK (0xfff << MIDR_PARTNUM_SHIFT) +# define MIDR_PARTNUM(midr) \ + (((midr) & MIDR_PARTNUM_MASK) >> MIDR_PARTNUM_SHIFT) + +# define MIDR_IMPLEMENTER_SHIFT 24 +# define MIDR_IMPLEMENTER_MASK (0xff << MIDR_IMPLEMENTER_SHIFT) +# define MIDR_IMPLEMENTER(midr) \ + (((midr) & MIDR_IMPLEMENTER_MASK) >> MIDR_IMPLEMENTER_SHIFT) + +# define MIDR_ARCHITECTURE_SHIFT 16 +# define MIDR_ARCHITECTURE_MASK (0xf << MIDR_ARCHITECTURE_SHIFT) +# define MIDR_ARCHITECTURE(midr) \ + (((midr) & MIDR_ARCHITECTURE_MASK) >> MIDR_ARCHITECTURE_SHIFT) + +# define MIDR_CPU_MODEL_MASK \ + (MIDR_IMPLEMENTER_MASK | \ + MIDR_PARTNUM_MASK | \ + MIDR_ARCHITECTURE_MASK) + +# define MIDR_CPU_MODEL(imp, partnum) \ + (((imp) << MIDR_IMPLEMENTER_SHIFT) | \ + (0xf << MIDR_ARCHITECTURE_SHIFT) | \ + ((partnum) << MIDR_PARTNUM_SHIFT)) + +# define MIDR_IS_CPU_MODEL(midr, imp, partnum) \ + (((midr) & MIDR_CPU_MODEL_MASK) == MIDR_CPU_MODEL(imp, partnum)) #endif diff --git a/crypto/armcap.c b/crypto/armcap.c index 70d2719ba75..7bd82f8ebc4 100644 --- a/crypto/armcap.c +++ b/crypto/armcap.c @@ -18,6 +18,7 @@ #include "arm_arch.h" unsigned int OPENSSL_armcap_P = 0; +unsigned int OPENSSL_arm_midr = 0; #if __ARM_MAX_ARCH__<7 void OPENSSL_cpuid_setup(void) @@ -48,6 +49,7 @@ void _armv8_sha256_probe(void); void _armv8_pmull_probe(void); # ifdef __aarch64__ void _armv8_sha512_probe(void); +unsigned int _armv8_cpuid_probe(void); # endif uint32_t _armv7_tick(void); @@ -95,6 +97,7 @@ void OPENSSL_cpuid_setup(void) __attribute__ ((constructor)); # define HWCAP_CE_PMULL (1 << 4) # define HWCAP_CE_SHA1 (1 << 5) # define HWCAP_CE_SHA256 (1 << 6) +# define HWCAP_CPUID (1 << 11) # define HWCAP_CE_SHA512 (1 << 21) # endif @@ -155,6 +158,9 @@ void OPENSSL_cpuid_setup(void) # ifdef __aarch64__ if (hwcap & HWCAP_CE_SHA512) OPENSSL_armcap_P |= ARMV8_SHA512; + + if (hwcap & HWCAP_CPUID) + OPENSSL_armcap_P |= ARMV8_CPUID; # endif } # endif @@ -210,5 +216,10 @@ void OPENSSL_cpuid_setup(void) sigaction(SIGILL, &ill_oact, NULL); sigprocmask(SIG_SETMASK, &oset, NULL); + +# ifdef __aarch64__ + if (OPENSSL_armcap_P & ARMV8_CPUID) + OPENSSL_arm_midr = _armv8_cpuid_probe(); +# endif } #endif -- 2.47.2