1 /* spitfire.h: SpitFire/BlackBird/Cheetah inline MMU operations. 2 * 3 * Copyright (C) 1996 David S. Miller (davem@davemloft.net) 4 */ 5 6 #ifndef _SPARC64_SPITFIRE_H 7 #define _SPARC64_SPITFIRE_H 8 9 #ifdef CONFIG_SPARC64 10 11 #include <asm/asi.h> 12 13 /* The following register addresses are accessible via ASI_DMMU 14 * and ASI_IMMU, that is there is a distinct and unique copy of 15 * each these registers for each TLB. 16 */ 17 #define TSB_TAG_TARGET 0x0000000000000000 /* All chips */ 18 #define TLB_SFSR 0x0000000000000018 /* All chips */ 19 #define TSB_REG 0x0000000000000028 /* All chips */ 20 #define TLB_TAG_ACCESS 0x0000000000000030 /* All chips */ 21 #define VIRT_WATCHPOINT 0x0000000000000038 /* All chips */ 22 #define PHYS_WATCHPOINT 0x0000000000000040 /* All chips */ 23 #define TSB_EXTENSION_P 0x0000000000000048 /* Ultra-III and later */ 24 #define TSB_EXTENSION_S 0x0000000000000050 /* Ultra-III and later, D-TLB only */ 25 #define TSB_EXTENSION_N 0x0000000000000058 /* Ultra-III and later */ 26 #define TLB_TAG_ACCESS_EXT 0x0000000000000060 /* Ultra-III+ and later */ 27 28 /* These registers only exist as one entity, and are accessed 29 * via ASI_DMMU only. 30 */ 31 #define PRIMARY_CONTEXT 0x0000000000000008 32 #define SECONDARY_CONTEXT 0x0000000000000010 33 #define DMMU_SFAR 0x0000000000000020 34 #define VIRT_WATCHPOINT 0x0000000000000038 35 #define PHYS_WATCHPOINT 0x0000000000000040 36 37 #define SPITFIRE_HIGHEST_LOCKED_TLBENT (64 - 1) 38 #define CHEETAH_HIGHEST_LOCKED_TLBENT (16 - 1) 39 40 #define L1DCACHE_SIZE 0x4000 41 42 #define SUN4V_CHIP_INVALID 0x00 43 #define SUN4V_CHIP_NIAGARA1 0x01 44 #define SUN4V_CHIP_NIAGARA2 0x02 45 #define SUN4V_CHIP_NIAGARA3 0x03 46 #define SUN4V_CHIP_NIAGARA4 0x04 47 #define SUN4V_CHIP_NIAGARA5 0x05 48 #define SUN4V_CHIP_SPARC_M6 0x06 49 #define SUN4V_CHIP_SPARC_M7 0x07 50 #define SUN4V_CHIP_SPARC_M8 0x08 51 #define SUN4V_CHIP_SPARC64X 0x8a 52 #define SUN4V_CHIP_SPARC_SN 0x8b 53 #define SUN4V_CHIP_UNKNOWN 0xff 54 55 /* 56 * The following CPU_ID_xxx constants are used 57 * to identify the CPU type in the setup phase 58 * (see head_64.S) 59 */ 60 #define CPU_ID_NIAGARA1 ('1') 61 #define CPU_ID_NIAGARA2 ('2') 62 #define CPU_ID_NIAGARA3 ('3') 63 #define CPU_ID_NIAGARA4 ('4') 64 #define CPU_ID_NIAGARA5 ('5') 65 #define CPU_ID_M6 ('6') 66 #define CPU_ID_M7 ('7') 67 #define CPU_ID_M8 ('8') 68 #define CPU_ID_SONOMA1 ('N') 69 70 #ifndef __ASSEMBLY__ 71 72 enum ultra_tlb_layout { 73 spitfire = 0, 74 cheetah = 1, 75 cheetah_plus = 2, 76 hypervisor = 3, 77 }; 78 79 extern enum ultra_tlb_layout tlb_type; 80 81 extern int sun4v_chip_type; 82 83 extern int cheetah_pcache_forced_on; 84 void cheetah_enable_pcache(void); 85 86 #define sparc64_highest_locked_tlbent() \ 87 (tlb_type == spitfire ? \ 88 SPITFIRE_HIGHEST_LOCKED_TLBENT : \ 89 CHEETAH_HIGHEST_LOCKED_TLBENT) 90 91 extern int num_kernel_image_mappings; 92 93 /* The data cache is write through, so this just invalidates the 94 * specified line. 95 */ 96 static inline void spitfire_put_dcache_tag(unsigned long addr, unsigned long tag) 97 { 98 __asm__ __volatile__("stxa %0, [%1] %2\n\t" 99 "membar #Sync" 100 : /* No outputs */ 101 : "r" (tag), "r" (addr), "i" (ASI_DCACHE_TAG)); 102 } 103 104 /* The instruction cache lines are flushed with this, but note that 105 * this does not flush the pipeline. It is possible for a line to 106 * get flushed but stale instructions to still be in the pipeline, 107 * a flush instruction (to any address) is sufficient to handle 108 * this issue after the line is invalidated. 109 */ 110 static inline void spitfire_put_icache_tag(unsigned long addr, unsigned long tag) 111 { 112 __asm__ __volatile__("stxa %0, [%1] %2\n\t" 113 "membar #Sync" 114 : /* No outputs */ 115 : "r" (tag), "r" (addr), "i" (ASI_IC_TAG)); 116 } 117 118 static inline unsigned long spitfire_get_dtlb_data(int entry) 119 { 120 unsigned long data; 121 122 __asm__ __volatile__("ldxa [%1] %2, %0" 123 : "=r" (data) 124 : "r" (entry << 3), "i" (ASI_DTLB_DATA_ACCESS)); 125 126 /* Clear TTE diag bits. */ 127 data &= ~0x0003fe0000000000UL; 128 129 return data; 130 } 131 132 static inline unsigned long spitfire_get_dtlb_tag(int entry) 133 { 134 unsigned long tag; 135 136 __asm__ __volatile__("ldxa [%1] %2, %0" 137 : "=r" (tag) 138 : "r" (entry << 3), "i" (ASI_DTLB_TAG_READ)); 139 return tag; 140 } 141 142 static inline void spitfire_put_dtlb_data(int entry, unsigned long data) 143 { 144 __asm__ __volatile__("stxa %0, [%1] %2\n\t" 145 "membar #Sync" 146 : /* No outputs */ 147 : "r" (data), "r" (entry << 3), 148 "i" (ASI_DTLB_DATA_ACCESS)); 149 } 150 151 static inline unsigned long spitfire_get_itlb_data(int entry) 152 { 153 unsigned long data; 154 155 __asm__ __volatile__("ldxa [%1] %2, %0" 156 : "=r" (data) 157 : "r" (entry << 3), "i" (ASI_ITLB_DATA_ACCESS)); 158 159 /* Clear TTE diag bits. */ 160 data &= ~0x0003fe0000000000UL; 161 162 return data; 163 } 164 165 static inline unsigned long spitfire_get_itlb_tag(int entry) 166 { 167 unsigned long tag; 168 169 __asm__ __volatile__("ldxa [%1] %2, %0" 170 : "=r" (tag) 171 : "r" (entry << 3), "i" (ASI_ITLB_TAG_READ)); 172 return tag; 173 } 174 175 static inline void spitfire_put_itlb_data(int entry, unsigned long data) 176 { 177 __asm__ __volatile__("stxa %0, [%1] %2\n\t" 178 "membar #Sync" 179 : /* No outputs */ 180 : "r" (data), "r" (entry << 3), 181 "i" (ASI_ITLB_DATA_ACCESS)); 182 } 183 184 static inline void spitfire_flush_dtlb_nucleus_page(unsigned long page) 185 { 186 __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" 187 "membar #Sync" 188 : /* No outputs */ 189 : "r" (page | 0x20), "i" (ASI_DMMU_DEMAP)); 190 } 191 192 static inline void spitfire_flush_itlb_nucleus_page(unsigned long page) 193 { 194 __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" 195 "membar #Sync" 196 : /* No outputs */ 197 : "r" (page | 0x20), "i" (ASI_IMMU_DEMAP)); 198 } 199 200 /* Cheetah has "all non-locked" tlb flushes. */ 201 static inline void cheetah_flush_dtlb_all(void) 202 { 203 __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" 204 "membar #Sync" 205 : /* No outputs */ 206 : "r" (0x80), "i" (ASI_DMMU_DEMAP)); 207 } 208 209 static inline void cheetah_flush_itlb_all(void) 210 { 211 __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" 212 "membar #Sync" 213 : /* No outputs */ 214 : "r" (0x80), "i" (ASI_IMMU_DEMAP)); 215 } 216 217 /* Cheetah has a 4-tlb layout so direct access is a bit different. 218 * The first two TLBs are fully assosciative, hold 16 entries, and are 219 * used only for locked and >8K sized translations. One exists for 220 * data accesses and one for instruction accesses. 221 * 222 * The third TLB is for data accesses to 8K non-locked translations, is 223 * 2 way assosciative, and holds 512 entries. The fourth TLB is for 224 * instruction accesses to 8K non-locked translations, is 2 way 225 * assosciative, and holds 128 entries. 226 * 227 * Cheetah has some bug where bogus data can be returned from 228 * ASI_{D,I}TLB_DATA_ACCESS loads, doing the load twice fixes 229 * the problem for me. -DaveM 230 */ 231 static inline unsigned long cheetah_get_ldtlb_data(int entry) 232 { 233 unsigned long data; 234 235 __asm__ __volatile__("ldxa [%1] %2, %%g0\n\t" 236 "ldxa [%1] %2, %0" 237 : "=r" (data) 238 : "r" ((0 << 16) | (entry << 3)), 239 "i" (ASI_DTLB_DATA_ACCESS)); 240 241 return data; 242 } 243 244 static inline unsigned long cheetah_get_litlb_data(int entry) 245 { 246 unsigned long data; 247 248 __asm__ __volatile__("ldxa [%1] %2, %%g0\n\t" 249 "ldxa [%1] %2, %0" 250 : "=r" (data) 251 : "r" ((0 << 16) | (entry << 3)), 252 "i" (ASI_ITLB_DATA_ACCESS)); 253 254 return data; 255 } 256 257 static inline unsigned long cheetah_get_ldtlb_tag(int entry) 258 { 259 unsigned long tag; 260 261 __asm__ __volatile__("ldxa [%1] %2, %0" 262 : "=r" (tag) 263 : "r" ((0 << 16) | (entry << 3)), 264 "i" (ASI_DTLB_TAG_READ)); 265 266 return tag; 267 } 268 269 static inline unsigned long cheetah_get_litlb_tag(int entry) 270 { 271 unsigned long tag; 272 273 __asm__ __volatile__("ldxa [%1] %2, %0" 274 : "=r" (tag) 275 : "r" ((0 << 16) | (entry << 3)), 276 "i" (ASI_ITLB_TAG_READ)); 277 278 return tag; 279 } 280 281 static inline void cheetah_put_ldtlb_data(int entry, unsigned long data) 282 { 283 __asm__ __volatile__("stxa %0, [%1] %2\n\t" 284 "membar #Sync" 285 : /* No outputs */ 286 : "r" (data), 287 "r" ((0 << 16) | (entry << 3)), 288 "i" (ASI_DTLB_DATA_ACCESS)); 289 } 290 291 static inline void cheetah_put_litlb_data(int entry, unsigned long data) 292 { 293 __asm__ __volatile__("stxa %0, [%1] %2\n\t" 294 "membar #Sync" 295 : /* No outputs */ 296 : "r" (data), 297 "r" ((0 << 16) | (entry << 3)), 298 "i" (ASI_ITLB_DATA_ACCESS)); 299 } 300 301 static inline unsigned long cheetah_get_dtlb_data(int entry, int tlb) 302 { 303 unsigned long data; 304 305 __asm__ __volatile__("ldxa [%1] %2, %%g0\n\t" 306 "ldxa [%1] %2, %0" 307 : "=r" (data) 308 : "r" ((tlb << 16) | (entry << 3)), "i" (ASI_DTLB_DATA_ACCESS)); 309 310 return data; 311 } 312 313 static inline unsigned long cheetah_get_dtlb_tag(int entry, int tlb) 314 { 315 unsigned long tag; 316 317 __asm__ __volatile__("ldxa [%1] %2, %0" 318 : "=r" (tag) 319 : "r" ((tlb << 16) | (entry << 3)), "i" (ASI_DTLB_TAG_READ)); 320 return tag; 321 } 322 323 static inline void cheetah_put_dtlb_data(int entry, unsigned long data, int tlb) 324 { 325 __asm__ __volatile__("stxa %0, [%1] %2\n\t" 326 "membar #Sync" 327 : /* No outputs */ 328 : "r" (data), 329 "r" ((tlb << 16) | (entry << 3)), 330 "i" (ASI_DTLB_DATA_ACCESS)); 331 } 332 333 static inline unsigned long cheetah_get_itlb_data(int entry) 334 { 335 unsigned long data; 336 337 __asm__ __volatile__("ldxa [%1] %2, %%g0\n\t" 338 "ldxa [%1] %2, %0" 339 : "=r" (data) 340 : "r" ((2 << 16) | (entry << 3)), 341 "i" (ASI_ITLB_DATA_ACCESS)); 342 343 return data; 344 } 345 346 static inline unsigned long cheetah_get_itlb_tag(int entry) 347 { 348 unsigned long tag; 349 350 __asm__ __volatile__("ldxa [%1] %2, %0" 351 : "=r" (tag) 352 : "r" ((2 << 16) | (entry << 3)), "i" (ASI_ITLB_TAG_READ)); 353 return tag; 354 } 355 356 static inline void cheetah_put_itlb_data(int entry, unsigned long data) 357 { 358 __asm__ __volatile__("stxa %0, [%1] %2\n\t" 359 "membar #Sync" 360 : /* No outputs */ 361 : "r" (data), "r" ((2 << 16) | (entry << 3)), 362 "i" (ASI_ITLB_DATA_ACCESS)); 363 } 364 365 #endif /* !(__ASSEMBLY__) */ 366 #endif /* CONFIG_SPARC64 */ 367 #endif /* !(_SPARC64_SPITFIRE_H) */ 368