xref: /src/sys/crypto/openssl/arm_arch.h (revision e6c8997a8958c7aaec8e266d2eeefbfaa137e218)
1 /*
2  * Copyright 2011-2024 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9 
10 #ifndef OSSL_CRYPTO_ARM_ARCH_H
11 #define OSSL_CRYPTO_ARM_ARCH_H
12 
13 #if !defined(__ARM_ARCH__)
14 #if defined(__CC_ARM)
15 #define __ARM_ARCH__ __TARGET_ARCH_ARM
16 #if defined(__BIG_ENDIAN)
17 #define __ARMEB__
18 #else
19 #define __ARMEL__
20 #endif
21 #elif defined(__GNUC__)
22 #if defined(__aarch64__)
23 #define __ARM_ARCH__ 8
24 /*
25  * Why doesn't gcc define __ARM_ARCH__? Instead it defines
26  * bunch of below macros. See all_architectures[] table in
27  * gcc/config/arm/arm.c. On a side note it defines
28  * __ARMEL__/__ARMEB__ for little-/big-endian.
29  */
30 #elif defined(__ARM_ARCH)
31 #define __ARM_ARCH__ __ARM_ARCH
32 #elif defined(__ARM_ARCH_8A__)
33 #define __ARM_ARCH__ 8
34 #elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
35 #define __ARM_ARCH__ 7
36 #elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6M__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__)
37 #define __ARM_ARCH__ 6
38 #elif defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_5TEJ__)
39 #define __ARM_ARCH__ 5
40 #elif defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__)
41 #define __ARM_ARCH__ 4
42 #else
43 #error "unsupported ARM architecture"
44 #endif
45 #elif defined(__ARM_ARCH)
46 #define __ARM_ARCH__ __ARM_ARCH
47 #endif
48 #endif
49 
50 #if !defined(__ARM_MAX_ARCH__)
51 #define __ARM_MAX_ARCH__ __ARM_ARCH__
52 #endif
53 
54 #if __ARM_MAX_ARCH__ < __ARM_ARCH__
55 #error "__ARM_MAX_ARCH__ can't be less than __ARM_ARCH__"
56 #elif __ARM_MAX_ARCH__ != __ARM_ARCH__
57 #if __ARM_ARCH__ < 7 && __ARM_MAX_ARCH__ >= 7 && defined(__ARMEB__)
58 #error "can't build universal big-endian binary"
59 #endif
60 #endif
61 
62 #ifndef __ASSEMBLER__
63 extern unsigned int OPENSSL_armcap_P;
64 extern unsigned int OPENSSL_arm_midr;
65 extern unsigned int OPENSSL_armv8_rsa_neonized;
66 #endif
67 
68 #define ARMV7_NEON (1 << 0)
69 #define ARMV7_TICK (1 << 1)
70 #define ARMV8_AES (1 << 2)
71 #define ARMV8_SHA1 (1 << 3)
72 #define ARMV8_SHA256 (1 << 4)
73 #define ARMV8_PMULL (1 << 5)
74 #define ARMV8_SHA512 (1 << 6)
75 #define ARMV8_CPUID (1 << 7)
76 #define ARMV8_RNG (1 << 8)
77 #define ARMV8_SM3 (1 << 9)
78 #define ARMV8_SM4 (1 << 10)
79 #define ARMV8_SHA3 (1 << 11)
80 #define ARMV8_UNROLL8_EOR3 (1 << 12)
81 #define ARMV8_SVE (1 << 13)
82 #define ARMV8_SVE2 (1 << 14)
83 #define ARMV8_HAVE_SHA3_AND_WORTH_USING (1 << 15)
84 #define ARMV8_UNROLL12_EOR3 (1 << 16)
85 
86 /*
87  * MIDR_EL1 system register
88  *
89  * 63___ _ ___32_31___ _ ___24_23_____20_19_____16_15__ _ __4_3_______0
90  * |            |             |         |         |          |        |
91  * |RES0        | Implementer | Variant | Arch    | PartNum  |Revision|
92  * |____ _ _____|_____ _ _____|_________|_______ _|____ _ ___|________|
93  *
94  */
95 
96 #define ARM_CPU_IMP_ARM 0x41
97 #define HISI_CPU_IMP 0x48
98 #define ARM_CPU_IMP_APPLE 0x61
99 #define ARM_CPU_IMP_MICROSOFT 0x6D
100 #define ARM_CPU_IMP_AMPERE 0xC0
101 
102 #define ARM_CPU_PART_CORTEX_A72 0xD08
103 #define ARM_CPU_PART_N1 0xD0C
104 #define ARM_CPU_PART_V1 0xD40
105 #define ARM_CPU_PART_N2 0xD49
106 #define HISI_CPU_PART_KP920 0xD01
107 #define ARM_CPU_PART_V2 0xD4F
108 
109 #define APPLE_CPU_PART_M1_ICESTORM 0x022
110 #define APPLE_CPU_PART_M1_FIRESTORM 0x023
111 #define APPLE_CPU_PART_M1_ICESTORM_PRO 0x024
112 #define APPLE_CPU_PART_M1_FIRESTORM_PRO 0x025
113 #define APPLE_CPU_PART_M1_ICESTORM_MAX 0x028
114 #define APPLE_CPU_PART_M1_FIRESTORM_MAX 0x029
115 #define APPLE_CPU_PART_M2_BLIZZARD 0x032
116 #define APPLE_CPU_PART_M2_AVALANCHE 0x033
117 #define APPLE_CPU_PART_M2_BLIZZARD_PRO 0x034
118 #define APPLE_CPU_PART_M2_AVALANCHE_PRO 0x035
119 #define APPLE_CPU_PART_M2_BLIZZARD_MAX 0x038
120 #define APPLE_CPU_PART_M2_AVALANCHE_MAX 0x039
121 
122 #define MICROSOFT_CPU_PART_COBALT_100 0xD49
123 
124 #define MIDR_PARTNUM_SHIFT 4
125 #define MIDR_PARTNUM_MASK (0xfffU << MIDR_PARTNUM_SHIFT)
126 #define MIDR_PARTNUM(midr) \
127     (((midr) & MIDR_PARTNUM_MASK) >> MIDR_PARTNUM_SHIFT)
128 
129 #define MIDR_IMPLEMENTER_SHIFT 24
130 #define MIDR_IMPLEMENTER_MASK (0xffU << MIDR_IMPLEMENTER_SHIFT)
131 #define MIDR_IMPLEMENTER(midr) \
132     (((midr) & MIDR_IMPLEMENTER_MASK) >> MIDR_IMPLEMENTER_SHIFT)
133 
134 #define MIDR_ARCHITECTURE_SHIFT 16
135 #define MIDR_ARCHITECTURE_MASK (0xfU << MIDR_ARCHITECTURE_SHIFT)
136 #define MIDR_ARCHITECTURE(midr) \
137     (((midr) & MIDR_ARCHITECTURE_MASK) >> MIDR_ARCHITECTURE_SHIFT)
138 
139 #define MIDR_CPU_MODEL_MASK \
140     (MIDR_IMPLEMENTER_MASK | MIDR_PARTNUM_MASK | MIDR_ARCHITECTURE_MASK)
141 
142 #define MIDR_CPU_MODEL(imp, partnum) \
143     (((imp) << MIDR_IMPLEMENTER_SHIFT) | (0xfU << MIDR_ARCHITECTURE_SHIFT) | ((partnum) << MIDR_PARTNUM_SHIFT))
144 
145 #define MIDR_IS_CPU_MODEL(midr, imp, partnum) \
146     (((midr) & MIDR_CPU_MODEL_MASK) == MIDR_CPU_MODEL(imp, partnum))
147 
148 #if defined(__ASSEMBLER__)
149 
150 /*
151  * Support macros for
152  *   - Armv8.3-A Pointer Authentication and
153  *   - Armv8.5-A Branch Target Identification
154  * features which require emitting a .note.gnu.property section with the
155  * appropriate architecture-dependent feature bits set.
156  * Read more: "ELF for the Arm® 64-bit Architecture"
157  */
158 
159 #if defined(__ARM_FEATURE_BTI_DEFAULT) && __ARM_FEATURE_BTI_DEFAULT == 1
160 #define GNU_PROPERTY_AARCH64_BTI (1 << 0) /* Has Branch Target Identification */
161 #define AARCH64_VALID_CALL_TARGET hint #34 /* BTI 'c' */
162 #else
163 #define GNU_PROPERTY_AARCH64_BTI 0 /* No Branch Target Identification */
164 #define AARCH64_VALID_CALL_TARGET
165 #endif
166 
167 #if defined(__ARM_FEATURE_PAC_DEFAULT) && (__ARM_FEATURE_PAC_DEFAULT & 1) == 1 /* Signed with A-key */
168 #define GNU_PROPERTY_AARCH64_POINTER_AUTH \
169     (1 << 1) /* Has Pointer Authentication */
170 #define AARCH64_SIGN_LINK_REGISTER hint #25 /* PACIASP */
171 #define AARCH64_VALIDATE_LINK_REGISTER hint #29 /* AUTIASP */
172 #elif defined(__ARM_FEATURE_PAC_DEFAULT) && (__ARM_FEATURE_PAC_DEFAULT & 2) == 2 /* Signed with B-key */
173 #define GNU_PROPERTY_AARCH64_POINTER_AUTH \
174     (1 << 1) /* Has Pointer Authentication */
175 #define AARCH64_SIGN_LINK_REGISTER hint #27 /* PACIBSP */
176 #define AARCH64_VALIDATE_LINK_REGISTER hint #31 /* AUTIBSP */
177 #else
178 #define GNU_PROPERTY_AARCH64_POINTER_AUTH 0 /* No Pointer Authentication */
179 #if GNU_PROPERTY_AARCH64_BTI != 0
180 #define AARCH64_SIGN_LINK_REGISTER AARCH64_VALID_CALL_TARGET
181 #else
182 #define AARCH64_SIGN_LINK_REGISTER
183 #endif
184 #define AARCH64_VALIDATE_LINK_REGISTER
185 #endif
186 
187 #if GNU_PROPERTY_AARCH64_POINTER_AUTH != 0 || GNU_PROPERTY_AARCH64_BTI != 0
188 /* clang-format off */
189 .pushsection .note.gnu.property, "a";
190 /* clang-format on */
191 .balign 8;
192 .long 4;
193 .long 0x10;
194 .long 0x5;
195 .asciz "GNU";
196 .long 0xc0000000; /* GNU_PROPERTY_AARCH64_FEATURE_1_AND */
197 .long 4;
198 .long(GNU_PROPERTY_AARCH64_POINTER_AUTH | GNU_PROPERTY_AARCH64_BTI);
199 .long 0;
200 .popsection;
201 #endif
202 
203 #endif /* defined __ASSEMBLER__ */
204 
205 #define IS_CPU_SUPPORT_UNROLL8_EOR3() \
206     (OPENSSL_armcap_P & ARMV8_UNROLL8_EOR3)
207 
208 #endif
209