-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathcpuid.h
More file actions
153 lines (127 loc) · 5.63 KB
/
cpuid.h
File metadata and controls
153 lines (127 loc) · 5.63 KB
1
2
3
4
5
6
7
8
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/* cpuid.h
*
* Copyright (C) 2006-2025 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#ifndef WOLF_CRYPT_CPUID_H
#define WOLF_CRYPT_CPUID_H
#include <wolfssl/wolfcrypt/types.h>
#ifdef __cplusplus
extern "C" {
#endif
#if (defined(WOLFSSL_X86_64_BUILD) || defined(USE_INTEL_SPEEDUP) || \
defined(WOLFSSL_AESNI) || defined(WOLFSSL_SP_X86_64_ASM)) && \
!defined(WOLFSSL_NO_ASM)
#define HAVE_CPUID
#define HAVE_CPUID_INTEL
#endif
#if (defined(WOLFSSL_AARCH64_BUILD) || (defined(__aarch64__) && \
defined(WOLFSSL_ARMASM))) && !defined(WOLFSSL_NO_ASM)
#define HAVE_CPUID
#define HAVE_CPUID_AARCH64
#endif
#define WC_CPUID_INITIALIZER 0xffffffffU
typedef word32 cpuid_flags_t;
#if !defined(WOLFSSL_NO_ATOMICS) && !defined(SINGLE_THREADED)
typedef wolfSSL_Atomic_Uint cpuid_flags_atomic_t;
#define WC_CPUID_ATOMIC_INITIALIZER \
WOLFSSL_ATOMIC_INITIALIZER(WC_CPUID_INITIALIZER)
#else
typedef word32 cpuid_flags_atomic_t;
#define WC_CPUID_ATOMIC_INITIALIZER WC_CPUID_INITIALIZER
#endif
#ifdef HAVE_CPUID_INTEL
#define CPUID_AVX1 0x0001
#define CPUID_AVX2 0x0002
#define CPUID_RDRAND 0x0004
#define CPUID_RDSEED 0x0008
#define CPUID_BMI2 0x0010 /* MULX, RORX */
#define CPUID_AESNI 0x0020
#define CPUID_ADX 0x0040 /* ADCX, ADOX */
#define CPUID_MOVBE 0x0080 /* Move and byte swap */
#define CPUID_BMI1 0x0100 /* ANDN */
#define CPUID_SHA 0x0200 /* SHA-1 and SHA-256 instructions */
#define IS_INTEL_AVX1(f) (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_AVX1)
#define IS_INTEL_AVX2(f) (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_AVX2)
#define IS_INTEL_RDRAND(f) (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_RDRAND)
#define IS_INTEL_RDSEED(f) (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_RDSEED)
#define IS_INTEL_BMI2(f) (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_BMI2)
#define IS_INTEL_AESNI(f) (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_AESNI)
#define IS_INTEL_ADX(f) (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_ADX)
#define IS_INTEL_MOVBE(f) (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_MOVBE)
#define IS_INTEL_BMI1(f) (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_BMI1)
#define IS_INTEL_SHA(f) (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_SHA)
#elif defined(HAVE_CPUID_AARCH64)
#define CPUID_AES 0x0001 /* AES enc/dec */
#define CPUID_PMULL 0x0002 /* Carryless multiplication */
#define CPUID_SHA256 0x0004 /* SHA-256 digest */
#define CPUID_SHA512 0x0008 /* SHA-512 digest */
#define CPUID_RDM 0x0010 /* SQRDMLAH and SQRDMLSH */
#define CPUID_SHA3 0x0020 /* SHA-3 digest */
#define CPUID_SM3 0x0040 /* SM3 digest */
#define CPUID_SM4 0x0080 /* SM4 enc/dec */
#define CPUID_SB 0x0100 /* Speculation barrier */
#define IS_AARCH64_AES(f) (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_AES)
#define IS_AARCH64_PMULL(f) (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_PMULL)
#define IS_AARCH64_SHA256(f) (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_SHA256)
#define IS_AARCH64_SHA512(f) (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_SHA512)
#define IS_AARCH64_RDM(f) (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_RDM)
#define IS_AARCH64_SHA3(f) (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_SHA3)
#define IS_AARCH64_SM3(f) (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_SM3)
#define IS_AARCH64_SM4(f) (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_SM4)
#define IS_AARCH64_SB(f) (WOLFSSL_ATOMIC_COERCE_UINT(f) & CPUID_SB)
#endif
#ifdef HAVE_CPUID
cpuid_flags_t cpuid_get_flags(void);
/* Idempotent flag getter -- fast, but return value (whether updated) is not
* strictly reliable.
*/
static WC_INLINE int cpuid_get_flags_ex(cpuid_flags_t *flags) {
if (*flags == WC_CPUID_INITIALIZER) {
*flags = cpuid_get_flags();
return 1;
}
else
return 0;
}
/* Strictly race-free flag getter -- slow, but the return value is strictly
* accurate.
*/
static WC_INLINE int cpuid_get_flags_atomic(cpuid_flags_atomic_t *flags) {
if (WOLFSSL_ATOMIC_LOAD(*flags) == WC_CPUID_INITIALIZER) {
cpuid_flags_t old_cpuid_flags = WC_CPUID_INITIALIZER;
return wolfSSL_Atomic_Uint_CompareExchange
(flags, &old_cpuid_flags, cpuid_get_flags());
}
else
return 0;
}
/* Public APIs to modify flags. */
#ifdef WOLFSSL_API_PREFIX_MAP
#define cpuid_select_flags wc_cpuid_select_flags
#define cpuid_set_flag wc_cpuid_set_flag
#define cpuid_clear_flag wc_cpuid_clear_flag
#endif /* WOLFSSL_API_PREFIX_MAP */
WOLFSSL_API void cpuid_select_flags(cpuid_flags_t flags);
WOLFSSL_API void cpuid_set_flag(cpuid_flags_t flag);
WOLFSSL_API void cpuid_clear_flag(cpuid_flags_t flag);
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* WOLF_CRYPT_CPUID_H */