aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWill Deacon <will.deacon@arm.com>2015-07-27 11:55:32 -0400
committerWill Deacon <will.deacon@arm.com>2015-07-27 11:56:17 -0400
commit309585b0b931b291d0525b2830161ee76a2f23ff (patch)
treeb449b4ca476bca59533d554c5cd7c174ce15e24a
parent2e94da13790336eb3fd00fb5e97610dd9aebe213 (diff)
arm64: elf: use cpuid_feature_extract_field for hwcap detection
cpuid_feature_extract_field takes care of the fiddly ID register field sign-extension, so use that instead of rolling our own version. Signed-off-by: Will Deacon <will.deacon@arm.com>
-rw-r--r--arch/arm64/kernel/setup.c35
1 files changed, 15 insertions, 20 deletions
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index b2f9895ecf7b..be65ecc89e82 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -223,7 +223,8 @@ void __init up_late_init(void)
223 223
224static void __init setup_processor(void) 224static void __init setup_processor(void)
225{ 225{
226 u64 features, block; 226 u64 features;
227 s64 block;
227 u32 cwg; 228 u32 cwg;
228 int cls; 229 int cls;
229 230
@@ -253,8 +254,8 @@ static void __init setup_processor(void)
253 * for non-negative values. Negative values are reserved. 254 * for non-negative values. Negative values are reserved.
254 */ 255 */
255 features = read_cpuid(ID_AA64ISAR0_EL1); 256 features = read_cpuid(ID_AA64ISAR0_EL1);
256 block = (features >> 4) & 0xf; 257 block = cpuid_feature_extract_field(features, 4);
257 if (!(block & 0x8)) { 258 if (block > 0) {
258 switch (block) { 259 switch (block) {
259 default: 260 default:
260 case 2: 261 case 2:
@@ -266,20 +267,17 @@ static void __init setup_processor(void)
266 } 267 }
267 } 268 }
268 269
269 block = (features >> 8) & 0xf; 270 if (cpuid_feature_extract_field(features, 8) > 0)
270 if (block && !(block & 0x8))
271 elf_hwcap |= HWCAP_SHA1; 271 elf_hwcap |= HWCAP_SHA1;
272 272
273 block = (features >> 12) & 0xf; 273 if (cpuid_feature_extract_field(features, 12) > 0)
274 if (block && !(block & 0x8))
275 elf_hwcap |= HWCAP_SHA2; 274 elf_hwcap |= HWCAP_SHA2;
276 275
277 block = (features >> 16) & 0xf; 276 if (cpuid_feature_extract_field(features, 16) > 0)
278 if (block && !(block & 0x8))
279 elf_hwcap |= HWCAP_CRC32; 277 elf_hwcap |= HWCAP_CRC32;
280 278
281 block = (features >> 20) & 0xf; 279 block = cpuid_feature_extract_field(features, 20);
282 if (!(block & 0x8)) { 280 if (block > 0) {
283 switch (block) { 281 switch (block) {
284 default: 282 default:
285 case 2: 283 case 2:
@@ -294,11 +292,11 @@ static void __init setup_processor(void)
294#ifdef CONFIG_COMPAT 292#ifdef CONFIG_COMPAT
295 /* 293 /*
296 * ID_ISAR5_EL1 carries similar information as above, but pertaining to 294 * ID_ISAR5_EL1 carries similar information as above, but pertaining to
297 * the Aarch32 32-bit execution state. 295 * the AArch32 32-bit execution state.
298 */ 296 */
299 features = read_cpuid(ID_ISAR5_EL1); 297 features = read_cpuid(ID_ISAR5_EL1);
300 block = (features >> 4) & 0xf; 298 block = cpuid_feature_extract_field(features, 4);
301 if (!(block & 0x8)) { 299 if (block > 0) {
302 switch (block) { 300 switch (block) {
303 default: 301 default:
304 case 2: 302 case 2:
@@ -310,16 +308,13 @@ static void __init setup_processor(void)
310 } 308 }
311 } 309 }
312 310
313 block = (features >> 8) & 0xf; 311 if (cpuid_feature_extract_field(features, 8) > 0)
314 if (block && !(block & 0x8))
315 compat_elf_hwcap2 |= COMPAT_HWCAP2_SHA1; 312 compat_elf_hwcap2 |= COMPAT_HWCAP2_SHA1;
316 313
317 block = (features >> 12) & 0xf; 314 if (cpuid_feature_extract_field(features, 12) > 0)
318 if (block && !(block & 0x8))
319 compat_elf_hwcap2 |= COMPAT_HWCAP2_SHA2; 315 compat_elf_hwcap2 |= COMPAT_HWCAP2_SHA2;
320 316
321 block = (features >> 16) & 0xf; 317 if (cpuid_feature_extract_field(features, 16) > 0)
322 if (block && !(block & 0x8))
323 compat_elf_hwcap2 |= COMPAT_HWCAP2_CRC32; 318 compat_elf_hwcap2 |= COMPAT_HWCAP2_CRC32;
324#endif 319#endif
325} 320}