| #ifndef OPENSSL_CRYPTO_CPU_ARMV8_FEATURE_PARSING_H |
| #define OPENSSL_CRYPTO_CPU_ARMV8_FEATURE_PARSING_H |
| |
| #include <openssl/cpu.h> |
| #include <stdint.h> |
| |
| #include "internal.h" |
| |
| #if defined(OPENSSL_AARCH64) |
| |
| BSSL_NAMESPACE_BEGIN |
| namespace armcap { |
| |
| // Common field indices based on ARM architecture specification for |
| // ID_AA64ISAR0_EL1. These are indices (multiplied by 4 for the bit shift). |
| // Note: SHA3_FIELD_IDX 8 * 4 = 32 (ID_AA64ISAR0_EL1_SHA3_SHIFT value) |
| #define ID_AA64ISAR0_AES_FIELD_IDX 1 // Bits [7:4] |
| #define ID_AA64ISAR0_SHA1_FIELD_IDX 2 // Bits [11:8] |
| #define ID_AA64ISAR0_SHA2_FIELD_IDX 3 // Bits [15:12] |
| #define ID_AA64ISAR0_SHA3_FIELD_IDX 8 // Bits [35:32] |
| #define NBITS_ID_FIELD 4 |
| |
| // Helper function to extract a 4-bit field based on its index. |
| inline unsigned GetIDField(uint64_t reg, unsigned field_idx) { |
| // We mask with 0xf to ensure only the 4 relevant bits are returned. |
| return (reg >> (field_idx * NBITS_ID_FIELD)) & 0xf; |
| } |
| |
| // The core function that converts the raw ID_AA64ISAR0 register value |
| // into the OR'd capability flags (ARMV8_AES, ARMV8_SHA3, etc.). |
| inline uint32_t ParseISAR0Flags(uint64_t isar0) { |
| uint32_t armcap = 0; |
| // AES and PMULL check |
| unsigned aes = GetIDField(isar0, ID_AA64ISAR0_AES_FIELD_IDX); |
| if (aes > 0) { |
| armcap |= ARMV8_AES; |
| } |
| if (aes > 1) { |
| armcap |= ARMV8_PMULL; |
| } |
| // SHA1 check |
| unsigned sha1 = GetIDField(isar0, ID_AA64ISAR0_SHA1_FIELD_IDX); |
| if (sha1 > 0) { |
| armcap |= ARMV8_SHA1; |
| } |
| // SHA256 and SHA512 check |
| unsigned sha2 = GetIDField(isar0, ID_AA64ISAR0_SHA2_FIELD_IDX); |
| if (sha2 > 0) { |
| armcap |= ARMV8_SHA256; |
| } |
| if (sha2 > 1) { |
| armcap |= ARMV8_SHA512; |
| } |
| // SHA3 (EOR3) check |
| unsigned sha3 = GetIDField(isar0, ID_AA64ISAR0_SHA3_FIELD_IDX); |
| if (sha3 > 0) { |
| armcap |= ARMV8_SHA3; |
| } |
| return armcap; |
| } |
| |
| } // namespace armcap |
| BSSL_NAMESPACE_END |
| |
| #endif // OPENSSL_AARCH64 |
| |
| #endif // OPENSSL_CRYPTO_CPU_ARMV8_FEATURE_PARSING_H |