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_SPARC64X 0x8a 51 #define SUN4V_CHIP_SPARC_SN 0x8b 52 #define SUN4V_CHIP_UNKNOWN 0xff 53 54 #ifndef __ASSEMBLY__ 55 56 enum ultra_tlb_layout { 57 spitfire = 0, 58 cheetah = 1, 59 cheetah_plus = 2, 60 hypervisor = 3, 61 }; 62 63 extern enum ultra_tlb_layout tlb_type; 64 65 extern int sun4v_chip_type; 66 67 extern int cheetah_pcache_forced_on; 68 void cheetah_enable_pcache(void); 69 70 #define sparc64_highest_locked_tlbent() \ 71 (tlb_type == spitfire ? \ 72 SPITFIRE_HIGHEST_LOCKED_TLBENT : \ 73 CHEETAH_HIGHEST_LOCKED_TLBENT) 74 75 extern int num_kernel_image_mappings; 76 77 /* The data cache is write through, so this just invalidates the 78 * specified line. 79 */ 80 static inline void spitfire_put_dcache_tag(unsigned long addr, unsigned long tag) 81 { 82 __asm__ __volatile__("stxa %0, [%1] %2\n\t" 83 "membar #Sync" 84 : /* No outputs */ 85 : "r" (tag), "r" (addr), "i" (ASI_DCACHE_TAG)); 86 } 87 88 /* The instruction cache lines are flushed with this, but note that 89 * this does not flush the pipeline. It is possible for a line to 90 * get flushed but stale instructions to still be in the pipeline, 91 * a flush instruction (to any address) is sufficient to handle 92 * this issue after the line is invalidated. 93 */ 94 static inline void spitfire_put_icache_tag(unsigned long addr, unsigned long tag) 95 { 96 __asm__ __volatile__("stxa %0, [%1] %2\n\t" 97 "membar #Sync" 98 : /* No outputs */ 99 : "r" (tag), "r" (addr), "i" (ASI_IC_TAG)); 100 } 101 102 static inline unsigned long spitfire_get_dtlb_data(int entry) 103 { 104 unsigned long data; 105 106 __asm__ __volatile__("ldxa [%1] %2, %0" 107 : "=r" (data) 108 : "r" (entry << 3), "i" (ASI_DTLB_DATA_ACCESS)); 109 110 /* Clear TTE diag bits. */ 111 data &= ~0x0003fe0000000000UL; 112 113 return data; 114 } 115 116 static inline unsigned long spitfire_get_dtlb_tag(int entry) 117 { 118 unsigned long tag; 119 120 __asm__ __volatile__("ldxa [%1] %2, %0" 121 : "=r" (tag) 122 : "r" (entry << 3), "i" (ASI_DTLB_TAG_READ)); 123 return tag; 124 } 125 126 static inline void spitfire_put_dtlb_data(int entry, unsigned long data) 127 { 128 __asm__ __volatile__("stxa %0, [%1] %2\n\t" 129 "membar #Sync" 130 : /* No outputs */ 131 : "r" (data), "r" (entry << 3), 132 "i" (ASI_DTLB_DATA_ACCESS)); 133 } 134 135 static inline unsigned long spitfire_get_itlb_data(int entry) 136 { 137 unsigned long data; 138 139 __asm__ __volatile__("ldxa [%1] %2, %0" 140 : "=r" (data) 141 : "r" (entry << 3), "i" (ASI_ITLB_DATA_ACCESS)); 142 143 /* Clear TTE diag bits. */ 144 data &= ~0x0003fe0000000000UL; 145 146 return data; 147 } 148 149 static inline unsigned long spitfire_get_itlb_tag(int entry) 150 { 151 unsigned long tag; 152 153 __asm__ __volatile__("ldxa [%1] %2, %0" 154 : "=r" (tag) 155 : "r" (entry << 3), "i" (ASI_ITLB_TAG_READ)); 156 return tag; 157 } 158 159 static inline void spitfire_put_itlb_data(int entry, unsigned long data) 160 { 161 __asm__ __volatile__("stxa %0, [%1] %2\n\t" 162 "membar #Sync" 163 : /* No outputs */ 164 : "r" (data), "r" (entry << 3), 165 "i" (ASI_ITLB_DATA_ACCESS)); 166 } 167 168 static inline void spitfire_flush_dtlb_nucleus_page(unsigned long page) 169 { 170 __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" 171 "membar #Sync" 172 : /* No outputs */ 173 : "r" (page | 0x20), "i" (ASI_DMMU_DEMAP)); 174 } 175 176 static inline void spitfire_flush_itlb_nucleus_page(unsigned long page) 177 { 178 __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" 179 "membar #Sync" 180 : /* No outputs */ 181 : "r" (page | 0x20), "i" (ASI_IMMU_DEMAP)); 182 } 183 184 /* Cheetah has "all non-locked" tlb flushes. */ 185 static inline void cheetah_flush_dtlb_all(void) 186 { 187 __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" 188 "membar #Sync" 189 : /* No outputs */ 190 : "r" (0x80), "i" (ASI_DMMU_DEMAP)); 191 } 192 193 static inline void cheetah_flush_itlb_all(void) 194 { 195 __asm__ __volatile__("stxa %%g0, [%0] %1\n\t" 196 "membar #Sync" 197 : /* No outputs */ 198 : "r" (0x80), "i" (ASI_IMMU_DEMAP)); 199 } 200 201 /* Cheetah has a 4-tlb layout so direct access is a bit different. 202 * The first two TLBs are fully assosciative, hold 16 entries, and are 203 * used only for locked and >8K sized translations. One exists for 204 * data accesses and one for instruction accesses. 205 * 206 * The third TLB is for data accesses to 8K non-locked translations, is 207 * 2 way assosciative, and holds 512 entries. The fourth TLB is for 208 * instruction accesses to 8K non-locked translations, is 2 way 209 * assosciative, and holds 128 entries. 210 * 211 * Cheetah has some bug where bogus data can be returned from 212 * ASI_{D,I}TLB_DATA_ACCESS loads, doing the load twice fixes 213 * the problem for me. -DaveM 214 */ 215 static inline unsigned long cheetah_get_ldtlb_data(int entry) 216 { 217 unsigned long data; 218 219 __asm__ __volatile__("ldxa [%1] %2, %%g0\n\t" 220 "ldxa [%1] %2, %0" 221 : "=r" (data) 222 : "r" ((0 << 16) | (entry << 3)), 223 "i" (ASI_DTLB_DATA_ACCESS)); 224 225 return data; 226 } 227 228 static inline unsigned long cheetah_get_litlb_data(int entry) 229 { 230 unsigned long data; 231 232 __asm__ __volatile__("ldxa [%1] %2, %%g0\n\t" 233 "ldxa [%1] %2, %0" 234 : "=r" (data) 235 : "r" ((0 << 16) | (entry << 3)), 236 "i" (ASI_ITLB_DATA_ACCESS)); 237 238 return data; 239 } 240 241 static inline unsigned long cheetah_get_ldtlb_tag(int entry) 242 { 243 unsigned long tag; 244 245 __asm__ __volatile__("ldxa [%1] %2, %0" 246 : "=r" (tag) 247 : "r" ((0 << 16) | (entry << 3)), 248 "i" (ASI_DTLB_TAG_READ)); 249 250 return tag; 251 } 252 253 static inline unsigned long cheetah_get_litlb_tag(int entry) 254 { 255 unsigned long tag; 256 257 __asm__ __volatile__("ldxa [%1] %2, %0" 258 : "=r" (tag) 259 : "r" ((0 << 16) | (entry << 3)), 260 "i" (ASI_ITLB_TAG_READ)); 261 262 return tag; 263 } 264 265 static inline void cheetah_put_ldtlb_data(int entry, unsigned long data) 266 { 267 __asm__ __volatile__("stxa %0, [%1] %2\n\t" 268 "membar #Sync" 269 : /* No outputs */ 270 : "r" (data), 271 "r" ((0 << 16) | (entry << 3)), 272 "i" (ASI_DTLB_DATA_ACCESS)); 273 } 274 275 static inline void cheetah_put_litlb_data(int entry, unsigned long data) 276 { 277 __asm__ __volatile__("stxa %0, [%1] %2\n\t" 278 "membar #Sync" 279 : /* No outputs */ 280 : "r" (data), 281 "r" ((0 << 16) | (entry << 3)), 282 "i" (ASI_ITLB_DATA_ACCESS)); 283 } 284 285 static inline unsigned long cheetah_get_dtlb_data(int entry, int tlb) 286 { 287 unsigned long data; 288 289 __asm__ __volatile__("ldxa [%1] %2, %%g0\n\t" 290 "ldxa [%1] %2, %0" 291 : "=r" (data) 292 : "r" ((tlb << 16) | (entry << 3)), "i" (ASI_DTLB_DATA_ACCESS)); 293 294 return data; 295 } 296 297 static inline unsigned long cheetah_get_dtlb_tag(int entry, int tlb) 298 { 299 unsigned long tag; 300 301 __asm__ __volatile__("ldxa [%1] %2, %0" 302 : "=r" (tag) 303 : "r" ((tlb << 16) | (entry << 3)), "i" (ASI_DTLB_TAG_READ)); 304 return tag; 305 } 306 307 static inline void cheetah_put_dtlb_data(int entry, unsigned long data, int tlb) 308 { 309 __asm__ __volatile__("stxa %0, [%1] %2\n\t" 310 "membar #Sync" 311 : /* No outputs */ 312 : "r" (data), 313 "r" ((tlb << 16) | (entry << 3)), 314 "i" (ASI_DTLB_DATA_ACCESS)); 315 } 316 317 static inline unsigned long cheetah_get_itlb_data(int entry) 318 { 319 unsigned long data; 320 321 __asm__ __volatile__("ldxa [%1] %2, %%g0\n\t" 322 "ldxa [%1] %2, %0" 323 : "=r" (data) 324 : "r" ((2 << 16) | (entry << 3)), 325 "i" (ASI_ITLB_DATA_ACCESS)); 326 327 return data; 328 } 329 330 static inline unsigned long cheetah_get_itlb_tag(int entry) 331 { 332 unsigned long tag; 333 334 __asm__ __volatile__("ldxa [%1] %2, %0" 335 : "=r" (tag) 336 : "r" ((2 << 16) | (entry << 3)), "i" (ASI_ITLB_TAG_READ)); 337 return tag; 338 } 339 340 static inline void cheetah_put_itlb_data(int entry, unsigned long data) 341 { 342 __asm__ __volatile__("stxa %0, [%1] %2\n\t" 343 "membar #Sync" 344 : /* No outputs */ 345 : "r" (data), "r" ((2 << 16) | (entry << 3)), 346 "i" (ASI_ITLB_DATA_ACCESS)); 347 } 348 349 #endif /* !(__ASSEMBLY__) */ 350 #endif /* CONFIG_SPARC64 */ 351 #endif /* !(_SPARC64_SPITFIRE_H) */ 352