diff options
author | Suzuki K. Poulose <suzuki.poulose@arm.com> | 2015-10-19 09:24:42 -0400 |
---|---|---|
committer | Catalin Marinas <catalin.marinas@arm.com> | 2015-10-21 10:33:51 -0400 |
commit | cdcf817b7e4b62b935d8797f7d07ea0b97760884 (patch) | |
tree | 8e3ed4836f814c10fb8d8786d03f275424b8307d | |
parent | 9cdf8ec4a86b9310111f741bbaf11df9120e0482 (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.h | 2 | ||||
-rw-r--r-- | arch/arm64/include/asm/cpufeature.h | 7 | ||||
-rw-r--r-- | arch/arm64/include/asm/cputype.h | 15 | ||||
-rw-r--r-- | arch/arm64/include/asm/sysreg.h | 2 | ||||
-rw-r--r-- | arch/arm64/kernel/cpufeature.c | 22 | ||||
-rw-r--r-- | arch/arm64/kernel/cpuinfo.c | 21 |
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); | |||
63 | void cpuinfo_store_cpu(void); | 63 | void cpuinfo_store_cpu(void); |
64 | void __init cpuinfo_store_boot_cpu(void); | 64 | void __init cpuinfo_store_boot_cpu(void); |
65 | 65 | ||
66 | void 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 | ||
85 | static 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 | |||
84 | void __init setup_cpu_features(void); | 91 | void __init setup_cpu_features(void); |
85 | 92 | ||
86 | void check_cpu_capabilities(const struct arm64_cpu_capabilities *caps, | 93 | void 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 | |||
116 | static 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 | ||
27 | static bool mixed_endian_el0 = true; | ||
26 | unsigned long elf_hwcap __read_mostly; | 28 | unsigned long elf_hwcap __read_mostly; |
27 | EXPORT_SYMBOL_GPL(elf_hwcap); | 29 | EXPORT_SYMBOL_GPL(elf_hwcap); |
28 | 30 | ||
@@ -41,6 +43,26 @@ unsigned int compat_elf_hwcap2 __read_mostly; | |||
41 | DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS); | 43 | DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS); |
42 | 44 | ||
43 | 45 | ||
46 | bool cpu_supports_mixed_endian_el0(void) | ||
47 | { | ||
48 | return id_aa64mmfr0_mixed_endian_el0(read_cpuid(ID_AA64MMFR0_EL1)); | ||
49 | } | ||
50 | |||
51 | bool system_supports_mixed_endian_el0(void) | ||
52 | { | ||
53 | return mixed_endian_el0; | ||
54 | } | ||
55 | |||
56 | static 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 | |||
61 | void update_cpu_features(struct cpuinfo_arm64 *info) | ||
62 | { | ||
63 | update_mixed_endian_el0_support(info); | ||
64 | } | ||
65 | |||
44 | static bool | 66 | static bool |
45 | feature_matches(u64 reg, const struct arm64_cpu_capabilities *entry) | 67 | feature_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 | */ |
36 | DEFINE_PER_CPU(struct cpuinfo_arm64, cpu_data); | 36 | DEFINE_PER_CPU(struct cpuinfo_arm64, cpu_data); |
37 | static struct cpuinfo_arm64 boot_cpu_data; | 37 | static struct cpuinfo_arm64 boot_cpu_data; |
38 | static bool mixed_endian_el0 = true; | ||
39 | 38 | ||
40 | static char *icache_policy_str[] = { | 39 | static 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 | ||
72 | bool cpu_supports_mixed_endian_el0(void) | ||
73 | { | ||
74 | return id_aa64mmfr0_mixed_endian_el0(read_cpuid(ID_AA64MMFR0_EL1)); | ||
75 | } | ||
76 | |||
77 | bool system_supports_mixed_endian_el0(void) | ||
78 | { | ||
79 | return mixed_endian_el0; | ||
80 | } | ||
81 | |||
82 | static 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 | |||
87 | static void update_cpu_features(struct cpuinfo_arm64 *info) | ||
88 | { | ||
89 | update_mixed_endian_el0_support(info); | ||
90 | } | ||
91 | |||
92 | static int check_reg_mask(char *name, u64 mask, u64 boot, u64 cur, int cpu) | 71 | static 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)) |