diff options
Diffstat (limited to 'arch/arm/kernel/setup.c')
| -rw-r--r-- | arch/arm/kernel/setup.c | 49 | 
1 files changed, 32 insertions, 17 deletions
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index e55408e96559..6c777e908a24 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -246,12 +246,9 @@ static int __get_cpu_architecture(void)  		if (cpu_arch)  			cpu_arch += CPU_ARCH_ARMv3;  	} else if ((read_cpuid_id() & 0x000f0000) == 0x000f0000) { -		unsigned int mmfr0; -  		/* Revised CPUID format. Read the Memory Model Feature  		 * Register 0 and check for VMSAv7 or PMSAv7 */ -		asm("mrc	p15, 0, %0, c0, c1, 4" -		    : "=r" (mmfr0)); +		unsigned int mmfr0 = read_cpuid_ext(CPUID_EXT_MMFR0);  		if ((mmfr0 & 0x0000000f) >= 0x00000003 ||  		    (mmfr0 & 0x000000f0) >= 0x00000030)  			cpu_arch = CPU_ARCH_ARMv7; @@ -375,30 +372,48 @@ void __init early_print(const char *str, ...)  static void __init cpuid_init_hwcaps(void)  { -	unsigned int divide_instrs, vmsa; +	int block; +	u32 isar5;  	if (cpu_architecture() < CPU_ARCH_ARMv7)  		return; -	divide_instrs = (read_cpuid_ext(CPUID_EXT_ISAR0) & 0x0f000000) >> 24; - -	switch (divide_instrs) { -	case 2: +	block = cpuid_feature_extract(CPUID_EXT_ISAR0, 24); +	if (block >= 2)  		elf_hwcap |= HWCAP_IDIVA; -	case 1: +	if (block >= 1)  		elf_hwcap |= HWCAP_IDIVT; -	}  	/* LPAE implies atomic ldrd/strd instructions */ -	vmsa = (read_cpuid_ext(CPUID_EXT_MMFR0) & 0xf) >> 0; -	if (vmsa >= 5) +	block = cpuid_feature_extract(CPUID_EXT_MMFR0, 0); +	if (block >= 5)  		elf_hwcap |= HWCAP_LPAE; + +	/* check for supported v8 Crypto instructions */ +	isar5 = read_cpuid_ext(CPUID_EXT_ISAR5); + +	block = cpuid_feature_extract_field(isar5, 4); +	if (block >= 2) +		elf_hwcap2 |= HWCAP2_PMULL; +	if (block >= 1) +		elf_hwcap2 |= HWCAP2_AES; + +	block = cpuid_feature_extract_field(isar5, 8); +	if (block >= 1) +		elf_hwcap2 |= HWCAP2_SHA1; + +	block = cpuid_feature_extract_field(isar5, 12); +	if (block >= 1) +		elf_hwcap2 |= HWCAP2_SHA2; + +	block = cpuid_feature_extract_field(isar5, 16); +	if (block >= 1) +		elf_hwcap2 |= HWCAP2_CRC32;  }  static void __init elf_hwcap_fixup(void)  {  	unsigned id = read_cpuid_id(); -	unsigned sync_prim;  	/*  	 * HWCAP_TLS is available only on 1136 r1p0 and later, @@ -419,9 +434,9 @@ static void __init elf_hwcap_fixup(void)  	 * avoid advertising SWP; it may not be atomic with  	 * multiprocessing cores.  	 */ -	sync_prim = ((read_cpuid_ext(CPUID_EXT_ISAR3) >> 8) & 0xf0) | -		    ((read_cpuid_ext(CPUID_EXT_ISAR4) >> 20) & 0x0f); -	if (sync_prim >= 0x13) +	if (cpuid_feature_extract(CPUID_EXT_ISAR3, 12) > 1 || +	    (cpuid_feature_extract(CPUID_EXT_ISAR3, 12) == 1 && +	     cpuid_feature_extract(CPUID_EXT_ISAR3, 20) >= 3))  		elf_hwcap &= ~HWCAP_SWP;  }  |