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