diff options
Diffstat (limited to 'arch/arm/kernel/setup.c')
-rw-r--r-- | arch/arm/kernel/setup.c | 44 |
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 | ||
373 | static void __init cpuid_init_hwcaps(void) | 373 | static 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 | ||
395 | static void __init elf_hwcap_fixup(void) | 414 | static 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 | ||