Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

arm64: Track system support for mixed endian EL0

This patch keeps track of the mixed endian EL0 support across
the system and provides helper functions to export it. The status
is a boolean indicating whether all the CPUs on the system supports
mixed endian at EL0.

Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>

authored by

Suzuki K. Poulose and committed by
Catalin Marinas
04597a65 78d51e0b

+38
+2
arch/arm64/include/asm/cpufeature.h
··· 52 52 } 53 53 54 54 void check_local_cpu_errata(void); 55 + bool cpu_supports_mixed_endian_el0(void); 56 + bool system_supports_mixed_endian_el0(void); 55 57 56 58 #endif /* __ASSEMBLY__ */ 57 59
+14
arch/arm64/include/asm/cputype.h
··· 72 72 73 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 + 75 84 #ifndef __ASSEMBLY__ 76 85 77 86 /* ··· 113 104 return read_cpuid(CTR_EL0); 114 105 } 115 106 107 + static inline bool id_aa64mmfr0_mixed_endian_el0(u64 mmfr0) 108 + { 109 + return (ID_AA64MMFR0_BIGEND(mmfr0) == 0x1) || 110 + (ID_AA64MMFR0_BIGENDEL0(mmfr0) == 0x1); 111 + } 116 112 #endif /* __ASSEMBLY__ */ 117 113 118 114 #endif
+22
arch/arm64/kernel/cpuinfo.c
··· 35 35 */ 36 36 DEFINE_PER_CPU(struct cpuinfo_arm64, cpu_data); 37 37 static struct cpuinfo_arm64 boot_cpu_data; 38 + static bool mixed_endian_el0 = true; 38 39 39 40 static char *icache_policy_str[] = { 40 41 [ICACHE_POLICY_RESERVED] = "RESERVED/UNKNOWN", ··· 67 66 set_bit(ICACHEF_AIVIVT, &__icache_flags); 68 67 69 68 pr_info("Detected %s I-cache on CPU%d\n", icache_policy_str[l1ip], cpu); 69 + } 70 + 71 + bool cpu_supports_mixed_endian_el0(void) 72 + { 73 + return id_aa64mmfr0_mixed_endian_el0(read_cpuid(ID_AA64MMFR0_EL1)); 74 + } 75 + 76 + bool system_supports_mixed_endian_el0(void) 77 + { 78 + return mixed_endian_el0; 79 + } 80 + 81 + static void update_mixed_endian_el0_support(struct cpuinfo_arm64 *info) 82 + { 83 + mixed_endian_el0 &= id_aa64mmfr0_mixed_endian_el0(info->reg_id_aa64mmfr0); 84 + } 85 + 86 + static void update_cpu_features(struct cpuinfo_arm64 *info) 87 + { 88 + update_mixed_endian_el0_support(info); 70 89 } 71 90 72 91 static int check_reg_mask(char *name, u64 mask, u64 boot, u64 cur, int cpu) ··· 236 215 cpuinfo_detect_icache_policy(info); 237 216 238 217 check_local_cpu_errata(); 218 + update_cpu_features(info); 239 219 } 240 220 241 221 void cpuinfo_store_cpu(void)