aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSuzuki K. Poulose <suzuki.poulose@arm.com>2015-10-19 09:24:42 -0400
committerCatalin Marinas <catalin.marinas@arm.com>2015-10-21 10:33:51 -0400
commitcdcf817b7e4b62b935d8797f7d07ea0b97760884 (patch)
tree8e3ed4836f814c10fb8d8786d03f275424b8307d
parent9cdf8ec4a86b9310111f741bbaf11df9120e0482 (diff)
arm64: Move mixed endian support detection
Move the mixed endian support detection code to cpufeature.c from cpuinfo.c. This also moves the update_cpu_features() used by mixed endian detection code, which will get more functionality. Also moves the ID register field shifts to asm/sysreg.h, where all the useful definitions will end up in later patches. Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com> Tested-by: Dave Martin <Dave.Martin@arm.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
-rw-r--r--arch/arm64/include/asm/cpu.h2
-rw-r--r--arch/arm64/include/asm/cpufeature.h7
-rw-r--r--arch/arm64/include/asm/cputype.h15
-rw-r--r--arch/arm64/include/asm/sysreg.h2
-rw-r--r--arch/arm64/kernel/cpufeature.c22
-rw-r--r--arch/arm64/kernel/cpuinfo.c21
6 files changed, 33 insertions, 36 deletions
diff --git a/arch/arm64/include/asm/cpu.h b/arch/arm64/include/asm/cpu.h
index 8e797b2fcc01..30db691b0b7e 100644
--- a/arch/arm64/include/asm/cpu.h
+++ b/arch/arm64/include/asm/cpu.h
@@ -63,4 +63,6 @@ DECLARE_PER_CPU(struct cpuinfo_arm64, cpu_data);
63void cpuinfo_store_cpu(void); 63void cpuinfo_store_cpu(void);
64void __init cpuinfo_store_boot_cpu(void); 64void __init cpuinfo_store_boot_cpu(void);
65 65
66void update_cpu_features(struct cpuinfo_arm64 *info);
67
66#endif /* __ASM_CPU_H */ 68#endif /* __ASM_CPU_H */
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index b7769f698a75..b5f313d42d79 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -10,6 +10,7 @@
10#define __ASM_CPUFEATURE_H 10#define __ASM_CPUFEATURE_H
11 11
12#include <asm/hwcap.h> 12#include <asm/hwcap.h>
13#include <asm/sysreg.h>
13 14
14/* 15/*
15 * In the arm64 world (as in the ARM world), elf_hwcap is used both internally 16 * In the arm64 world (as in the ARM world), elf_hwcap is used both internally
@@ -81,6 +82,12 @@ static inline int __attribute_const__ cpuid_feature_extract_field(u64 features,
81 return (s64)(features << (64 - 4 - field)) >> (64 - 4); 82 return (s64)(features << (64 - 4 - field)) >> (64 - 4);
82} 83}
83 84
85static inline bool id_aa64mmfr0_mixed_endian_el0(u64 mmfr0)
86{
87 return cpuid_feature_extract_field(mmfr0, ID_AA64MMFR0_BIGENDEL_SHIFT) == 0x1 ||
88 cpuid_feature_extract_field(mmfr0, ID_AA64MMFR0_BIGENDEL0_SHIFT) == 0x1;
89}
90
84void __init setup_cpu_features(void); 91void __init setup_cpu_features(void);
85 92
86void check_cpu_capabilities(const struct arm64_cpu_capabilities *caps, 93void check_cpu_capabilities(const struct arm64_cpu_capabilities *caps,
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index ee6403df9fe4..31678b2f295f 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -72,15 +72,6 @@
72 72
73#define APM_CPU_PART_POTENZA 0x000 73#define APM_CPU_PART_POTENZA 0x000
74 74
75#define ID_AA64MMFR0_BIGENDEL0_SHIFT 16
76#define ID_AA64MMFR0_BIGENDEL0_MASK (0xf << ID_AA64MMFR0_BIGENDEL0_SHIFT)
77#define ID_AA64MMFR0_BIGENDEL0(mmfr0) \
78 (((mmfr0) & ID_AA64MMFR0_BIGENDEL0_MASK) >> ID_AA64MMFR0_BIGENDEL0_SHIFT)
79#define ID_AA64MMFR0_BIGEND_SHIFT 8
80#define ID_AA64MMFR0_BIGEND_MASK (0xf << ID_AA64MMFR0_BIGEND_SHIFT)
81#define ID_AA64MMFR0_BIGEND(mmfr0) \
82 (((mmfr0) & ID_AA64MMFR0_BIGEND_MASK) >> ID_AA64MMFR0_BIGEND_SHIFT)
83
84#ifndef __ASSEMBLY__ 75#ifndef __ASSEMBLY__
85 76
86/* 77/*
@@ -112,12 +103,6 @@ static inline u32 __attribute_const__ read_cpuid_cachetype(void)
112{ 103{
113 return read_cpuid(CTR_EL0); 104 return read_cpuid(CTR_EL0);
114} 105}
115
116static inline bool id_aa64mmfr0_mixed_endian_el0(u64 mmfr0)
117{
118 return (ID_AA64MMFR0_BIGEND(mmfr0) == 0x1) ||
119 (ID_AA64MMFR0_BIGENDEL0(mmfr0) == 0x1);
120}
121#endif /* __ASSEMBLY__ */ 106#endif /* __ASSEMBLY__ */
122 107
123#endif 108#endif
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 4b57e1080538..061a2792179a 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -44,6 +44,8 @@
44#define SET_PSTATE_PAN(x) __inst_arm(0xd5000000 | REG_PSTATE_PAN_IMM |\ 44#define SET_PSTATE_PAN(x) __inst_arm(0xd5000000 | REG_PSTATE_PAN_IMM |\
45 (!!x)<<8 | 0x1f) 45 (!!x)<<8 | 0x1f)
46 46
47#define ID_AA64MMFR0_BIGENDEL0_SHIFT 16
48#define ID_AA64MMFR0_BIGENDEL_SHIFT 8
47 49
48#define ID_AA64MMFR0_TGRAN4_SHIFT 28 50#define ID_AA64MMFR0_TGRAN4_SHIFT 28
49#define ID_AA64MMFR0_TGRAN64_SHIFT 24 51#define ID_AA64MMFR0_TGRAN64_SHIFT 24
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index e49be15c7ff9..1ae8b24f334a 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -22,7 +22,9 @@
22#include <asm/cpu.h> 22#include <asm/cpu.h>
23#include <asm/cpufeature.h> 23#include <asm/cpufeature.h>
24#include <asm/processor.h> 24#include <asm/processor.h>
25#include <asm/sysreg.h>
25 26
27static bool mixed_endian_el0 = true;
26unsigned long elf_hwcap __read_mostly; 28unsigned long elf_hwcap __read_mostly;
27EXPORT_SYMBOL_GPL(elf_hwcap); 29EXPORT_SYMBOL_GPL(elf_hwcap);
28 30
@@ -41,6 +43,26 @@ unsigned int compat_elf_hwcap2 __read_mostly;
41DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS); 43DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS);
42 44
43 45
46bool cpu_supports_mixed_endian_el0(void)
47{
48 return id_aa64mmfr0_mixed_endian_el0(read_cpuid(ID_AA64MMFR0_EL1));
49}
50
51bool system_supports_mixed_endian_el0(void)
52{
53 return mixed_endian_el0;
54}
55
56static void update_mixed_endian_el0_support(struct cpuinfo_arm64 *info)
57{
58 mixed_endian_el0 &= id_aa64mmfr0_mixed_endian_el0(info->reg_id_aa64mmfr0);
59}
60
61void update_cpu_features(struct cpuinfo_arm64 *info)
62{
63 update_mixed_endian_el0_support(info);
64}
65
44static bool 66static bool
45feature_matches(u64 reg, const struct arm64_cpu_capabilities *entry) 67feature_matches(u64 reg, const struct arm64_cpu_capabilities *entry)
46{ 68{
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index 75d5a867e7fb..8307b336dc1f 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -35,7 +35,6 @@
35 */ 35 */
36DEFINE_PER_CPU(struct cpuinfo_arm64, cpu_data); 36DEFINE_PER_CPU(struct cpuinfo_arm64, cpu_data);
37static struct cpuinfo_arm64 boot_cpu_data; 37static struct cpuinfo_arm64 boot_cpu_data;
38static bool mixed_endian_el0 = true;
39 38
40static char *icache_policy_str[] = { 39static char *icache_policy_str[] = {
41 [ICACHE_POLICY_RESERVED] = "RESERVED/UNKNOWN", 40 [ICACHE_POLICY_RESERVED] = "RESERVED/UNKNOWN",
@@ -69,26 +68,6 @@ static void cpuinfo_detect_icache_policy(struct cpuinfo_arm64 *info)
69 pr_info("Detected %s I-cache on CPU%d\n", icache_policy_str[l1ip], cpu); 68 pr_info("Detected %s I-cache on CPU%d\n", icache_policy_str[l1ip], cpu);
70} 69}
71 70
72bool cpu_supports_mixed_endian_el0(void)
73{
74 return id_aa64mmfr0_mixed_endian_el0(read_cpuid(ID_AA64MMFR0_EL1));
75}
76
77bool system_supports_mixed_endian_el0(void)
78{
79 return mixed_endian_el0;
80}
81
82static void update_mixed_endian_el0_support(struct cpuinfo_arm64 *info)
83{
84 mixed_endian_el0 &= id_aa64mmfr0_mixed_endian_el0(info->reg_id_aa64mmfr0);
85}
86
87static void update_cpu_features(struct cpuinfo_arm64 *info)
88{
89 update_mixed_endian_el0_support(info);
90}
91
92static int check_reg_mask(char *name, u64 mask, u64 boot, u64 cur, int cpu) 71static int check_reg_mask(char *name, u64 mask, u64 boot, u64 cur, int cpu)
93{ 72{
94 if ((boot & mask) == (cur & mask)) 73 if ((boot & mask) == (cur & mask))