aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/setup.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/kernel/setup.c')
-rw-r--r--arch/arm/kernel/setup.c44
1 files changed, 31 insertions, 13 deletions
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 1d60bebea4b8..6c777e908a24 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -372,30 +372,48 @@ void __init early_print(const char *str, ...)
372 372
373static void __init cpuid_init_hwcaps(void) 373static void __init cpuid_init_hwcaps(void)
374{ 374{
375 unsigned int divide_instrs, vmsa; 375 int block;
376 u32 isar5;
376 377
377 if (cpu_architecture() < CPU_ARCH_ARMv7) 378 if (cpu_architecture() < CPU_ARCH_ARMv7)
378 return; 379 return;
379 380
380 divide_instrs = (read_cpuid_ext(CPUID_EXT_ISAR0) & 0x0f000000) >> 24; 381 block = cpuid_feature_extract(CPUID_EXT_ISAR0, 24);
381 382 if (block >= 2)
382 switch (divide_instrs) {
383 case 2:
384 elf_hwcap |= HWCAP_IDIVA; 383 elf_hwcap |= HWCAP_IDIVA;
385 case 1: 384 if (block >= 1)
386 elf_hwcap |= HWCAP_IDIVT; 385 elf_hwcap |= HWCAP_IDIVT;
387 }
388 386
389 /* LPAE implies atomic ldrd/strd instructions */ 387 /* LPAE implies atomic ldrd/strd instructions */
390 vmsa = (read_cpuid_ext(CPUID_EXT_MMFR0) & 0xf) >> 0; 388 block = cpuid_feature_extract(CPUID_EXT_MMFR0, 0);
391 if (vmsa >= 5) 389 if (block >= 5)
392 elf_hwcap |= HWCAP_LPAE; 390 elf_hwcap |= HWCAP_LPAE;
391
392 /* check for supported v8 Crypto instructions */
393 isar5 = read_cpuid_ext(CPUID_EXT_ISAR5);
394
395 block = cpuid_feature_extract_field(isar5, 4);
396 if (block >= 2)
397 elf_hwcap2 |= HWCAP2_PMULL;
398 if (block >= 1)
399 elf_hwcap2 |= HWCAP2_AES;
400
401 block = cpuid_feature_extract_field(isar5, 8);
402 if (block >= 1)
403 elf_hwcap2 |= HWCAP2_SHA1;
404
405 block = cpuid_feature_extract_field(isar5, 12);
406 if (block >= 1)
407 elf_hwcap2 |= HWCAP2_SHA2;
408
409 block = cpuid_feature_extract_field(isar5, 16);
410 if (block >= 1)
411 elf_hwcap2 |= HWCAP2_CRC32;
393} 412}
394 413
395static void __init elf_hwcap_fixup(void) 414static void __init elf_hwcap_fixup(void)
396{ 415{
397 unsigned id = read_cpuid_id(); 416 unsigned id = read_cpuid_id();
398 unsigned sync_prim;
399 417
400 /* 418 /*
401 * HWCAP_TLS is available only on 1136 r1p0 and later, 419 * HWCAP_TLS is available only on 1136 r1p0 and later,
@@ -416,9 +434,9 @@ static void __init elf_hwcap_fixup(void)
416 * avoid advertising SWP; it may not be atomic with 434 * avoid advertising SWP; it may not be atomic with
417 * multiprocessing cores. 435 * multiprocessing cores.
418 */ 436 */
419 sync_prim = ((read_cpuid_ext(CPUID_EXT_ISAR3) >> 8) & 0xf0) | 437 if (cpuid_feature_extract(CPUID_EXT_ISAR3, 12) > 1 ||
420 ((read_cpuid_ext(CPUID_EXT_ISAR4) >> 20) & 0x0f); 438 (cpuid_feature_extract(CPUID_EXT_ISAR3, 12) == 1 &&
421 if (sync_prim >= 0x13) 439 cpuid_feature_extract(CPUID_EXT_ISAR3, 20) >= 3))
422 elf_hwcap &= ~HWCAP_SWP; 440 elf_hwcap &= ~HWCAP_SWP;
423} 441}
424 442