1 /* 2 * xtensa/cacheattrasm.h -- assembler-specific CACHEATTR register related definitions 3 * that depend on CORE configuration 4 * 5 * This file is logically part of xtensa/coreasm.h (or perhaps xtensa/cacheasm.h), 6 * but is kept separate for modularity / compilation-performance. 7 */ 8 9 /* 10 * Copyright (c) 2001-2009 Tensilica Inc. 11 * 12 * Permission is hereby granted, free of charge, to any person obtaining 13 * a copy of this software and associated documentation files (the 14 * "Software"), to deal in the Software without restriction, including 15 * without limitation the rights to use, copy, modify, merge, publish, 16 * distribute, sublicense, and/or sell copies of the Software, and to 17 * permit persons to whom the Software is furnished to do so, subject to 18 * the following conditions: 19 * 20 * The above copyright notice and this permission notice shall be included 21 * in all copies or substantial portions of the Software. 22 * 23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 26 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 27 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 28 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 29 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 30 */ 31 32 #ifndef XTENSA_CACHEATTRASM_H 33 #define XTENSA_CACHEATTRASM_H 34 35 #include <xtensa/coreasm.h> 36 37 /* Determine whether cache attributes are controlled using eight 512MB entries: */ 38 #define XCHAL_CA_8X512 (XCHAL_HAVE_CACHEATTR || XCHAL_HAVE_MIMIC_CACHEATTR || XCHAL_HAVE_XLT_CACHEATTR \ 39 || (XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY)) 40 41 42 /* 43 * This header file defines assembler macros of the form: 44 * <x>cacheattr_<func> 45 * where: 46 * <x> is 'i', 'd' or absent for instruction, data 47 * or both caches; and 48 * <func> indicates the function of the macro. 49 * 50 * The following functions are defined: 51 * 52 * icacheattr_get 53 * Reads I-cache CACHEATTR into a2 (clobbers a3-a5). 54 * 55 * dcacheattr_get 56 * Reads D-cache CACHEATTR into a2 (clobbers a3-a5). 57 * (Note: for configs with a real CACHEATTR register, the 58 * above two macros are identical.) 59 * 60 * cacheattr_set 61 * Writes both I-cache and D-cache CACHEATTRs from a2 (a3-a8 clobbered). 62 * Works even when changing one's own code's attributes. 63 * 64 * icacheattr_is_enabled label 65 * Branches to \label if I-cache appears to have been enabled 66 * (eg. if CACHEATTR contains a cache-enabled attribute). 67 * (clobbers a2-a5,SAR) 68 * 69 * dcacheattr_is_enabled label 70 * Branches to \label if D-cache appears to have been enabled 71 * (eg. if CACHEATTR contains a cache-enabled attribute). 72 * (clobbers a2-a5,SAR) 73 * 74 * cacheattr_is_enabled label 75 * Branches to \label if either I-cache or D-cache appears to have been enabled 76 * (eg. if CACHEATTR contains a cache-enabled attribute). 77 * (clobbers a2-a5,SAR) 78 * 79 * The following macros are only defined under certain conditions: 80 * 81 * icacheattr_set (if XCHAL_HAVE_MIMIC_CACHEATTR || XCHAL_HAVE_XLT_CACHEATTR) 82 * Writes I-cache CACHEATTR from a2 (a3-a8 clobbered). 83 * 84 * dcacheattr_set (if XCHAL_HAVE_MIMIC_CACHEATTR || XCHAL_HAVE_XLT_CACHEATTR) 85 * Writes D-cache CACHEATTR from a2 (a3-a8 clobbered). 86 */ 87 88 89 90 /*************************** GENERIC -- ALL CACHES ***************************/ 91 92 /* 93 * _cacheattr_get 94 * 95 * (Internal macro.) 96 * Returns value of CACHEATTR register (or closest equivalent) in a2. 97 * 98 * Entry: 99 * (none) 100 * Exit: 101 * a2 value read from CACHEATTR 102 * a3-a5 clobbered (temporaries) 103 */ 104 .macro _cacheattr_get tlb 105 #if XCHAL_HAVE_CACHEATTR 106 rsr.cacheattr a2 107 #elif XCHAL_CA_8X512 108 // We have a config that "mimics" CACHEATTR using a simplified 109 // "MMU" composed of a single statically-mapped way. 110 // DTLB and ITLB are independent, so there's no single 111 // cache attribute that can describe both. So for now 112 // just return the DTLB state. 113 movi a5, 0xE0000000 114 movi a2, 0 115 movi a3, XCHAL_SPANNING_WAY 116 1: add a3, a3, a5 // next segment 117 r&tlb&1 a4, a3 // get PPN+CA of segment at 0xE0000000, 0xC0000000, ..., 0 118 dsync // interlock??? 119 slli a2, a2, 4 120 extui a4, a4, 0, 4 // extract CA 121 or a2, a2, a4 122 bgeui a3, 16, 1b 123 #else 124 // This macro isn't applicable to arbitrary MMU configurations. 125 // Just return zero. 126 movi a2, 0 127 #endif 128 .endm 129 130 .macro icacheattr_get 131 _cacheattr_get itlb 132 .endm 133 134 .macro dcacheattr_get 135 _cacheattr_get dtlb 136 .endm 137 138 139 /* Default (powerup/reset) value of CACHEATTR, 140 all BYPASS mode (ie. disabled/bypassed caches): */ 141 #if XCHAL_HAVE_PTP_MMU 142 # define XCHAL_CACHEATTR_ALL_BYPASS 0x33333333 143 #else 144 # define XCHAL_CACHEATTR_ALL_BYPASS 0x22222222 145 #endif 146 147 #if XCHAL_CA_8X512 148 149 #if XCHAL_HAVE_PTP_MMU 150 # define XCHAL_FCA_ENAMASK 0x0AA0 /* bitmap of fetch attributes that require enabled icache */ 151 # define XCHAL_LCA_ENAMASK 0x0FF0 /* bitmap of load attributes that require enabled dcache */ 152 # define XCHAL_SCA_ENAMASK 0x0CC0 /* bitmap of store attributes that require enabled dcache */ 153 #else 154 # define XCHAL_FCA_ENAMASK 0x003A /* bitmap of fetch attributes that require enabled icache */ 155 # define XCHAL_LCA_ENAMASK 0x0033 /* bitmap of load attributes that require enabled dcache */ 156 # define XCHAL_SCA_ENAMASK 0x0033 /* bitmap of store attributes that require enabled dcache */ 157 #endif 158 #define XCHAL_LSCA_ENAMASK (XCHAL_LCA_ENAMASK|XCHAL_SCA_ENAMASK) /* l/s attrs requiring enabled dcache */ 159 #define XCHAL_ALLCA_ENAMASK (XCHAL_FCA_ENAMASK|XCHAL_LSCA_ENAMASK) /* all attrs requiring enabled caches */ 160 161 /* 162 * _cacheattr_is_enabled 163 * 164 * (Internal macro.) 165 * Branches to \label if CACHEATTR in a2 indicates an enabled 166 * cache, using mask in a3. 167 * 168 * Parameters: 169 * label where to branch to if cache is enabled 170 * Entry: 171 * a2 contains CACHEATTR value used to determine whether 172 * caches are enabled 173 * a3 16-bit constant where each bit correspond to 174 * one of the 16 possible CA values (in a CACHEATTR mask); 175 * CA values that indicate the cache is enabled 176 * have their corresponding bit set in this mask 177 * (eg. use XCHAL_xCA_ENAMASK , above) 178 * Exit: 179 * a2,a4,a5 clobbered 180 * SAR clobbered 181 */ 182 .macro _cacheattr_is_enabled label 183 movi a4, 8 // loop 8 times 184 .Lcaife\@: 185 extui a5, a2, 0, 4 // get CA nibble 186 ssr a5 // index into mask according to CA... 187 srl a5, a3 // ...and get CA's mask bit in a5 bit 0 188 bbsi.l a5, 0, \label // if CA indicates cache enabled, jump to label 189 srli a2, a2, 4 // next nibble 190 addi a4, a4, -1 191 bnez a4, .Lcaife\@ // loop for each nibble 192 .endm 193 194 #else /* XCHAL_CA_8X512 */ 195 .macro _cacheattr_is_enabled label 196 j \label // macro not applicable, assume caches always enabled 197 .endm 198 #endif /* XCHAL_CA_8X512 */ 199 200 201 202 /* 203 * icacheattr_is_enabled 204 * 205 * Branches to \label if I-cache is enabled. 206 * 207 * Parameters: 208 * label where to branch to if icache is enabled 209 * Entry: 210 * (none) 211 * Exit: 212 * a2-a5, SAR clobbered (temporaries) 213 */ 214 .macro icacheattr_is_enabled label 215 #if XCHAL_CA_8X512 216 icacheattr_get 217 movi a3, XCHAL_FCA_ENAMASK 218 #endif 219 _cacheattr_is_enabled \label 220 .endm 221 222 /* 223 * dcacheattr_is_enabled 224 * 225 * Branches to \label if D-cache is enabled. 226 * 227 * Parameters: 228 * label where to branch to if dcache is enabled 229 * Entry: 230 * (none) 231 * Exit: 232 * a2-a5, SAR clobbered (temporaries) 233 */ 234 .macro dcacheattr_is_enabled label 235 #if XCHAL_CA_8X512 236 dcacheattr_get 237 movi a3, XCHAL_LSCA_ENAMASK 238 #endif 239 _cacheattr_is_enabled \label 240 .endm 241 242 /* 243 * cacheattr_is_enabled 244 * 245 * Branches to \label if either I-cache or D-cache is enabled. 246 * 247 * Parameters: 248 * label where to branch to if a cache is enabled 249 * Entry: 250 * (none) 251 * Exit: 252 * a2-a5, SAR clobbered (temporaries) 253 */ 254 .macro cacheattr_is_enabled label 255 #if XCHAL_HAVE_CACHEATTR 256 rsr.cacheattr a2 257 movi a3, XCHAL_ALLCA_ENAMASK 258 #elif XCHAL_CA_8X512 259 icacheattr_get 260 movi a3, XCHAL_FCA_ENAMASK 261 _cacheattr_is_enabled \label 262 dcacheattr_get 263 movi a3, XCHAL_LSCA_ENAMASK 264 #endif 265 _cacheattr_is_enabled \label 266 .endm 267 268 269 270 /* 271 * The ISA does not have a defined way to change the 272 * instruction cache attributes of the running code, 273 * ie. of the memory area that encloses the current PC. 274 * However, each micro-architecture (or class of 275 * configurations within a micro-architecture) 276 * provides a way to deal with this issue. 277 * 278 * Here are a few macros used to implement the relevant 279 * approach taken. 280 */ 281 282 #if XCHAL_CA_8X512 && !XCHAL_HAVE_CACHEATTR 283 // We have a config that "mimics" CACHEATTR using a simplified 284 // "MMU" composed of a single statically-mapped way. 285 286 /* 287 * icacheattr_set 288 * 289 * Entry: 290 * a2 cacheattr value to set 291 * Exit: 292 * a2 unchanged 293 * a3-a8 clobbered (temporaries) 294 */ 295 .macro icacheattr_set 296 297 movi a5, 0xE0000000 // mask of upper 3 bits 298 movi a6, 3f // PC where ITLB is set 299 movi a3, XCHAL_SPANNING_WAY // start at region 0 (0 .. 7) 300 mov a7, a2 // copy a2 so it doesn't get clobbered 301 and a6, a6, a5 // upper 3 bits of local PC area 302 j 3f 303 304 // Use micro-architecture specific method. 305 // The following 4-instruction sequence is aligned such that 306 // it all fits within a single I-cache line. Sixteen byte 307 // alignment is sufficient for this (using XCHAL_ICACHE_LINESIZE 308 // actually causes problems because that can be greater than 309 // the alignment of the reset vector, where this macro is often 310 // invoked, which would cause the linker to align the reset 311 // vector code away from the reset vector!!). 312 .begin no-transform 313 .align 16 /*XCHAL_ICACHE_LINESIZE*/ 314 1: witlb a4, a3 // write wired PTE (CA, no PPN) of 512MB segment to ITLB 315 isync 316 .end no-transform 317 nop 318 nop 319 320 sub a3, a3, a5 // next segment (add 0x20000000) 321 bltui a3, 16, 4f // done? 322 323 // Note that in the WITLB loop, we don't do any load/stores 324 // (may not be an issue here, but it is important in the DTLB case). 325 2: srli a7, a7, 4 // next CA 326 3: 327 # if XCHAL_HAVE_MIMIC_CACHEATTR 328 extui a4, a7, 0, 4 // extract CA to set 329 # else /* have translation, preserve it: */ 330 ritlb1 a8, a3 // get current PPN+CA of segment 331 //dsync // interlock??? 332 extui a4, a7, 0, 4 // extract CA to set 333 srli a8, a8, 4 // clear CA but keep PPN ... 334 slli a8, a8, 4 // ... 335 add a4, a4, a8 // combine new CA with PPN to preserve 336 # endif 337 beq a3, a6, 1b // current PC's region? if so, do it in a safe way 338 witlb a4, a3 // write wired PTE (CA [+PPN]) of 512MB segment to ITLB 339 sub a3, a3, a5 // next segment (add 0x20000000) 340 bgeui a3, 16, 2b 341 isync // make sure all ifetch changes take effect 342 4: 343 .endm // icacheattr_set 344 345 346 /* 347 * dcacheattr_set 348 * 349 * Entry: 350 * a2 cacheattr value to set 351 * Exit: 352 * a2 unchanged 353 * a3-a8 clobbered (temporaries) 354 */ 355 356 .macro dcacheattr_set 357 358 movi a5, 0xE0000000 // mask of upper 3 bits 359 movi a3, XCHAL_SPANNING_WAY // start at region 0 (0 .. 7) 360 mov a7, a2 // copy a2 so it doesn't get clobbered 361 // Note that in the WDTLB loop, we don't do any load/stores 362 2: // (including implicit l32r via movi) because it isn't safe. 363 # if XCHAL_HAVE_MIMIC_CACHEATTR 364 extui a4, a7, 0, 4 // extract CA to set 365 # else /* have translation, preserve it: */ 366 rdtlb1 a8, a3 // get current PPN+CA of segment 367 //dsync // interlock??? 368 extui a4, a7, 0, 4 // extract CA to set 369 srli a8, a8, 4 // clear CA but keep PPN ... 370 slli a8, a8, 4 // ... 371 add a4, a4, a8 // combine new CA with PPN to preserve 372 # endif 373 wdtlb a4, a3 // write wired PTE (CA [+PPN]) of 512MB segment to DTLB 374 sub a3, a3, a5 // next segment (add 0x20000000) 375 srli a7, a7, 4 // next CA 376 bgeui a3, 16, 2b 377 dsync // make sure all data path changes take effect 378 .endm // dcacheattr_set 379 380 #endif /* XCHAL_CA_8X512 && !XCHAL_HAVE_CACHEATTR */ 381 382 383 384 /* 385 * cacheattr_set 386 * 387 * Macro that sets the current CACHEATTR safely 388 * (both i and d) according to the current contents of a2. 389 * It works even when changing the cache attributes of 390 * the currently running code. 391 * 392 * Entry: 393 * a2 cacheattr value to set 394 * Exit: 395 * a2 unchanged 396 * a3-a8 clobbered (temporaries) 397 */ 398 .macro cacheattr_set 399 400 #if XCHAL_HAVE_CACHEATTR 401 # if XCHAL_ICACHE_LINESIZE < 4 402 // No i-cache, so can always safely write to CACHEATTR: 403 wsr.cacheattr a2 404 # else 405 // The Athens micro-architecture, when using the old 406 // exception architecture option (ie. with the CACHEATTR register) 407 // allows changing the cache attributes of the running code 408 // using the following exact sequence aligned to be within 409 // an instruction cache line. (NOTE: using XCHAL_ICACHE_LINESIZE 410 // alignment actually causes problems because that can be greater 411 // than the alignment of the reset vector, where this macro is often 412 // invoked, which would cause the linker to align the reset 413 // vector code away from the reset vector!!). 414 j 1f 415 .begin no-transform 416 .align 16 /*XCHAL_ICACHE_LINESIZE*/ // align to within an I-cache line 417 1: wsr.cacheattr a2 418 isync 419 .end no-transform 420 nop 421 nop 422 # endif 423 #elif XCHAL_CA_8X512 424 // DTLB and ITLB are independent, but to keep semantics 425 // of this macro we simply write to both. 426 icacheattr_set 427 dcacheattr_set 428 #else 429 // This macro isn't applicable to arbitrary MMU configurations. 430 // Do nothing in this case. 431 #endif 432 .endm 433 434 435 #endif /*XTENSA_CACHEATTRASM_H*/ 436 437