[PATCH 4/4] ARM: use proper helper while extracting cpu features

Vladimir Murzin vladimir.murzin at arm.com
Tue Jan 26 01:23:43 PST 2016


Update current users of cpu feature helpers to use the proper helper
depends on how feature bits should be handled. We follow the arm64
scheme [1] (slightly rephrased):

We have three types of fields:

a) A precise value or a value from which you derive some precise
   value.
b) Fields defining the presence of a feature (1, 2, 3). These would
   always be positive since the absence of such feature would mean a
   value of 0
c) Fields defining the absence of a feature by setting 0xf. These are
   usually fields that were initial RAZ and turned to -1.

So we can treat (a) and (b) as unsigned permanently and (c) as as
signed,

[1] https://lkml.org/lkml/2015/11/19/549

Signed-off-by: Vladimir Murzin <vladimir.murzin at arm.com>
---
 arch/arm/include/asm/smp_plat.h |    4 ++--
 arch/arm/kernel/setup.c         |   34 ++++++++++++++++++++--------------
 arch/arm/kernel/thumbee.c       |    4 +---
 arch/arm/mm/mmu.c               |    2 +-
 4 files changed, 24 insertions(+), 20 deletions(-)

diff --git a/arch/arm/include/asm/smp_plat.h b/arch/arm/include/asm/smp_plat.h
index f908071..03bbe02 100644
--- a/arch/arm/include/asm/smp_plat.h
+++ b/arch/arm/include/asm/smp_plat.h
@@ -49,7 +49,7 @@ static inline int tlb_ops_need_broadcast(void)
 	if (!is_smp())
 		return 0;
 
-	return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 2;
+	return cpuid_feature_extract_unsigned(CPUID_EXT_MMFR3, 12) < 2;
 }
 #endif
 
@@ -61,7 +61,7 @@ static inline int cache_ops_need_broadcast(void)
 	if (!is_smp())
 		return 0;
 
-	return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 1;
+	return cpuid_feature_extract_unsigned(CPUID_EXT_MMFR3, 12) < 1;
 }
 #endif
 
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index fde041b..e696553 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -257,11 +257,15 @@ static int __get_cpu_architecture(void)
 		/* Revised CPUID format. Read the Memory Model Feature
 		 * Register 0 and check for VMSAv7 or PMSAv7 */
 		unsigned int mmfr0 = read_cpuid_ext(CPUID_EXT_MMFR0);
-		if ((mmfr0 & 0x0000000f) >= 0x00000003 ||
-		    (mmfr0 & 0x000000f0) >= 0x00000030)
+		unsigned int block;
+#ifdef CONFIG_MMU
+		block = cpuid_feature_extract_unsigned_field(mmfr0, 0);
+#else
+		block = cpuid_feature_extract_unsigned_field(mmfr0, 4);
+#endif
+		if (mmfr0 >= 3)
 			cpu_arch = CPU_ARCH_ARMv7;
-		else if ((mmfr0 & 0x0000000f) == 0x00000002 ||
-			 (mmfr0 & 0x000000f0) == 0x00000020)
+		else if (mmfr0 == 2)
 			cpu_arch = CPU_ARCH_ARMv6;
 		else
 			cpu_arch = CPU_ARCH_UNKNOWN;
@@ -446,41 +450,41 @@ static inline void patch_aeabi_idiv(void) { }
 
 static void __init cpuid_init_hwcaps(void)
 {
-	int block;
+	unsigned int block;
 	u32 isar5;
 
 	if (cpu_architecture() < CPU_ARCH_ARMv7)
 		return;
 
-	block = cpuid_feature_extract(CPUID_EXT_ISAR0, 24);
+	block = cpuid_feature_extract_unsigned(CPUID_EXT_ISAR0, 24);
 	if (block >= 2)
 		elf_hwcap |= HWCAP_IDIVA;
 	if (block >= 1)
 		elf_hwcap |= HWCAP_IDIVT;
 
 	/* LPAE implies atomic ldrd/strd instructions */
-	block = cpuid_feature_extract(CPUID_EXT_MMFR0, 0);
+	block = cpuid_feature_extract_unsigned(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);
+	block = cpuid_feature_extract_unsigned_field(isar5, 4);
 	if (block >= 2)
 		elf_hwcap2 |= HWCAP2_PMULL;
 	if (block >= 1)
 		elf_hwcap2 |= HWCAP2_AES;
 
-	block = cpuid_feature_extract_field(isar5, 8);
+	block = cpuid_feature_extract_unsigned_field(isar5, 8);
 	if (block >= 1)
 		elf_hwcap2 |= HWCAP2_SHA1;
 
-	block = cpuid_feature_extract_field(isar5, 12);
+	block = cpuid_feature_extract_unsigned_field(isar5, 12);
 	if (block >= 1)
 		elf_hwcap2 |= HWCAP2_SHA2;
 
-	block = cpuid_feature_extract_field(isar5, 16);
+	block = cpuid_feature_extract_unsigned_field(isar5, 16);
 	if (block >= 1)
 		elf_hwcap2 |= HWCAP2_CRC32;
 }
@@ -488,6 +492,7 @@ static void __init cpuid_init_hwcaps(void)
 static void __init elf_hwcap_fixup(void)
 {
 	unsigned id = read_cpuid_id();
+	unsigned int block;
 
 	/*
 	 * HWCAP_TLS is available only on 1136 r1p0 and later,
@@ -508,9 +513,10 @@ static void __init elf_hwcap_fixup(void)
 	 * avoid advertising SWP; it may not be atomic with
 	 * multiprocessing cores.
 	 */
-	if (cpuid_feature_extract(CPUID_EXT_ISAR3, 12) > 1 ||
-	    (cpuid_feature_extract(CPUID_EXT_ISAR3, 12) == 1 &&
-	     cpuid_feature_extract(CPUID_EXT_ISAR4, 20) >= 3))
+	block = cpuid_feature_extract_unsigned(CPUID_EXT_ISAR3, 12);
+
+	if (block > 1 || (block == 1 &&
+	    cpuid_feature_extract_unsigned(CPUID_EXT_ISAR4, 20) >= 3))
 		elf_hwcap &= ~HWCAP_SWP;
 }
 
diff --git a/arch/arm/kernel/thumbee.c b/arch/arm/kernel/thumbee.c
index 8ff8dbf..b5cac80 100644
--- a/arch/arm/kernel/thumbee.c
+++ b/arch/arm/kernel/thumbee.c
@@ -62,14 +62,12 @@ static struct notifier_block thumbee_notifier_block = {
 
 static int __init thumbee_init(void)
 {
-	unsigned long pfr0;
 	unsigned int cpu_arch = cpu_architecture();
 
 	if (cpu_arch < CPU_ARCH_ARMv7)
 		return 0;
 
-	pfr0 = read_cpuid_ext(CPUID_EXT_PFR0);
-	if ((pfr0 & 0x0000f000) != 0x00001000)
+	if (cpuid_feature_extract_unsigned(CPUID_EXT_PFR0, 12) != 1)
 		return 0;
 
 	pr_info("ThumbEE CPU extension supported.\n");
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 434d76f..06723a9 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -572,7 +572,7 @@ static void __init build_mem_type_table(void)
 	 * in the Short-descriptor translation table format descriptors.
 	 */
 	if (cpu_arch == CPU_ARCH_ARMv7 &&
-		(read_cpuid_ext(CPUID_EXT_MMFR0) & 0xF) >= 4) {
+		(cpuid_feature_extract_unsigned(CPUID_EXT_MMFR0, 0) >= 4)) {
 		user_pmd_table |= PMD_PXNTABLE;
 	}
 #endif
-- 
1.7.9.5




More information about the linux-arm-kernel mailing list