1#ifndef __ASM_ARM_CPUTYPE_H 2#define __ASM_ARM_CPUTYPE_H 3 4#include <linux/stringify.h> 5#include <linux/kernel.h> 6 7#define CPUID_ID 0 8#define CPUID_CACHETYPE 1 9#define CPUID_TCM 2 10#define CPUID_TLBTYPE 3 11#define CPUID_MPUIR 4 12#define CPUID_MPIDR 5 13#define CPUID_REVIDR 6 14 15#ifdef CONFIG_CPU_V7M 16#define CPUID_EXT_PFR0 0x40 17#define CPUID_EXT_PFR1 0x44 18#define CPUID_EXT_DFR0 0x48 19#define CPUID_EXT_AFR0 0x4c 20#define CPUID_EXT_MMFR0 0x50 21#define CPUID_EXT_MMFR1 0x54 22#define CPUID_EXT_MMFR2 0x58 23#define CPUID_EXT_MMFR3 0x5c 24#define CPUID_EXT_ISAR0 0x60 25#define CPUID_EXT_ISAR1 0x64 26#define CPUID_EXT_ISAR2 0x68 27#define CPUID_EXT_ISAR3 0x6c 28#define CPUID_EXT_ISAR4 0x70 29#define CPUID_EXT_ISAR5 0x74 30#else 31#define CPUID_EXT_PFR0 "c1, 0" 32#define CPUID_EXT_PFR1 "c1, 1" 33#define CPUID_EXT_DFR0 "c1, 2" 34#define CPUID_EXT_AFR0 "c1, 3" 35#define CPUID_EXT_MMFR0 "c1, 4" 36#define CPUID_EXT_MMFR1 "c1, 5" 37#define CPUID_EXT_MMFR2 "c1, 6" 38#define CPUID_EXT_MMFR3 "c1, 7" 39#define CPUID_EXT_ISAR0 "c2, 0" 40#define CPUID_EXT_ISAR1 "c2, 1" 41#define CPUID_EXT_ISAR2 "c2, 2" 42#define CPUID_EXT_ISAR3 "c2, 3" 43#define CPUID_EXT_ISAR4 "c2, 4" 44#define CPUID_EXT_ISAR5 "c2, 5" 45#endif 46 47#define MPIDR_SMP_BITMASK (0x3 << 30) 48#define MPIDR_SMP_VALUE (0x2 << 30) 49 50#define MPIDR_MT_BITMASK (0x1 << 24) 51 52#define MPIDR_HWID_BITMASK 0xFFFFFF 53 54#define MPIDR_INVALID (~MPIDR_HWID_BITMASK) 55 56#define MPIDR_LEVEL_BITS 8 57#define MPIDR_LEVEL_MASK ((1 << MPIDR_LEVEL_BITS) - 1) 58 59#define MPIDR_AFFINITY_LEVEL(mpidr, level) \ 60 ((mpidr >> (MPIDR_LEVEL_BITS * level)) & MPIDR_LEVEL_MASK) 61 62#define ARM_CPU_IMP_ARM 0x41 63#define ARM_CPU_IMP_INTEL 0x69 64 65/* ARM implemented processors */ 66#define ARM_CPU_PART_ARM1136 0x4100b360 67#define ARM_CPU_PART_ARM1156 0x4100b560 68#define ARM_CPU_PART_ARM1176 0x4100b760 69#define ARM_CPU_PART_ARM11MPCORE 0x4100b020 70#define ARM_CPU_PART_CORTEX_A8 0x4100c080 71#define ARM_CPU_PART_CORTEX_A9 0x4100c090 72#define ARM_CPU_PART_CORTEX_A5 0x4100c050 73#define ARM_CPU_PART_CORTEX_A7 0x4100c070 74#define ARM_CPU_PART_CORTEX_A12 0x4100c0d0 75#define ARM_CPU_PART_CORTEX_A17 0x4100c0e0 76#define ARM_CPU_PART_CORTEX_A15 0x4100c0f0 77#define ARM_CPU_PART_MASK 0xff00fff0 78 79#define ARM_CPU_XSCALE_ARCH_MASK 0xe000 80#define ARM_CPU_XSCALE_ARCH_V1 0x2000 81#define ARM_CPU_XSCALE_ARCH_V2 0x4000 82#define ARM_CPU_XSCALE_ARCH_V3 0x6000 83 84extern unsigned int processor_id; 85 86#ifdef CONFIG_CPU_CP15 87#define read_cpuid(reg) \ 88 ({ \ 89 unsigned int __val; \ 90 asm("mrc p15, 0, %0, c0, c0, " __stringify(reg) \ 91 : "=r" (__val) \ 92 : \ 93 : "cc"); \ 94 __val; \ 95 }) 96 97/* 98 * The memory clobber prevents gcc 4.5 from reordering the mrc before 99 * any is_smp() tests, which can cause undefined instruction aborts on 100 * ARM1136 r0 due to the missing extended CP15 registers. 101 */ 102#define read_cpuid_ext(ext_reg) \ 103 ({ \ 104 unsigned int __val; \ 105 asm("mrc p15, 0, %0, c0, " ext_reg \ 106 : "=r" (__val) \ 107 : \ 108 : "memory"); \ 109 __val; \ 110 }) 111 112#elif defined(CONFIG_CPU_V7M) 113 114#include <asm/io.h> 115#include <asm/v7m.h> 116 117#define read_cpuid(reg) \ 118 ({ \ 119 WARN_ON_ONCE(1); \ 120 0; \ 121 }) 122 123static inline unsigned int __attribute_const__ read_cpuid_ext(unsigned offset) 124{ 125 return readl(BASEADDR_V7M_SCB + offset); 126} 127 128#else /* ifdef CONFIG_CPU_CP15 / elif defined (CONFIG_CPU_V7M) */ 129 130/* 131 * read_cpuid and read_cpuid_ext should only ever be called on machines that 132 * have cp15 so warn on other usages. 133 */ 134#define read_cpuid(reg) \ 135 ({ \ 136 WARN_ON_ONCE(1); \ 137 0; \ 138 }) 139 140#define read_cpuid_ext(reg) read_cpuid(reg) 141 142#endif /* ifdef CONFIG_CPU_CP15 / else */ 143 144#ifdef CONFIG_CPU_CP15 145/* 146 * The CPU ID never changes at run time, so we might as well tell the 147 * compiler that it's constant. Use this function to read the CPU ID 148 * rather than directly reading processor_id or read_cpuid() directly. 149 */ 150static inline unsigned int __attribute_const__ read_cpuid_id(void) 151{ 152 return read_cpuid(CPUID_ID); 153} 154 155#elif defined(CONFIG_CPU_V7M) 156 157static inline unsigned int __attribute_const__ read_cpuid_id(void) 158{ 159 return readl(BASEADDR_V7M_SCB + V7M_SCB_CPUID); 160} 161 162#else /* ifdef CONFIG_CPU_CP15 / elif defined(CONFIG_CPU_V7M) */ 163 164static inline unsigned int __attribute_const__ read_cpuid_id(void) 165{ 166 return processor_id; 167} 168 169#endif /* ifdef CONFIG_CPU_CP15 / else */ 170 171static inline unsigned int __attribute_const__ read_cpuid_implementor(void) 172{ 173 return (read_cpuid_id() & 0xFF000000) >> 24; 174} 175 176/* 177 * The CPU part number is meaningless without referring to the CPU 178 * implementer: implementers are free to define their own part numbers 179 * which are permitted to clash with other implementer part numbers. 180 */ 181static inline unsigned int __attribute_const__ read_cpuid_part(void) 182{ 183 return read_cpuid_id() & ARM_CPU_PART_MASK; 184} 185 186static inline unsigned int __attribute_const__ __deprecated read_cpuid_part_number(void) 187{ 188 return read_cpuid_id() & 0xFFF0; 189} 190 191static inline unsigned int __attribute_const__ xscale_cpu_arch_version(void) 192{ 193 return read_cpuid_id() & ARM_CPU_XSCALE_ARCH_MASK; 194} 195 196static inline unsigned int __attribute_const__ read_cpuid_cachetype(void) 197{ 198 return read_cpuid(CPUID_CACHETYPE); 199} 200 201static inline unsigned int __attribute_const__ read_cpuid_tcmstatus(void) 202{ 203 return read_cpuid(CPUID_TCM); 204} 205 206static inline unsigned int __attribute_const__ read_cpuid_mpidr(void) 207{ 208 return read_cpuid(CPUID_MPIDR); 209} 210 211/* 212 * Intel's XScale3 core supports some v6 features (supersections, L2) 213 * but advertises itself as v5 as it does not support the v6 ISA. For 214 * this reason, we need a way to explicitly test for this type of CPU. 215 */ 216#ifndef CONFIG_CPU_XSC3 217#define cpu_is_xsc3() 0 218#else 219static inline int cpu_is_xsc3(void) 220{ 221 unsigned int id; 222 id = read_cpuid_id() & 0xffffe000; 223 /* It covers both Intel ID and Marvell ID */ 224 if ((id == 0x69056000) || (id == 0x56056000)) 225 return 1; 226 227 return 0; 228} 229#endif 230 231#if !defined(CONFIG_CPU_XSCALE) && !defined(CONFIG_CPU_XSC3) 232#define cpu_is_xscale() 0 233#else 234#define cpu_is_xscale() 1 235#endif 236 237/* 238 * Marvell's PJ4 and PJ4B cores are based on V7 version, 239 * but require a specical sequence for enabling coprocessors. 240 * For this reason, we need a way to distinguish them. 241 */ 242#if defined(CONFIG_CPU_PJ4) || defined(CONFIG_CPU_PJ4B) 243static inline int cpu_is_pj4(void) 244{ 245 unsigned int id; 246 247 id = read_cpuid_id(); 248 if ((id & 0xff0fff00) == 0x560f5800) 249 return 1; 250 251 return 0; 252} 253#else 254#define cpu_is_pj4() 0 255#endif 256 257static inline int __attribute_const__ cpuid_feature_extract_field(u32 features, 258 int field) 259{ 260 int feature = (features >> field) & 15; 261 262 /* feature registers are signed values */ 263 if (feature > 8) 264 feature -= 16; 265 266 return feature; 267} 268 269#define cpuid_feature_extract(reg, field) \ 270 cpuid_feature_extract_field(read_cpuid_ext(reg), field) 271 272#endif 273