1 /* 2 * xtensa/cacheasm.h -- assembler-specific cache related definitions 3 * that depend on CORE configuration 4 * 5 * This file is logically part of xtensa/coreasm.h , 6 * but is kept separate for modularity / compilation-performance. 7 */ 8 9 /* 10 * Copyright (c) 2001-2014 Cadence Design Systems, 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_CACHEASM_H 33 #define XTENSA_CACHEASM_H 34 35 #include <xtensa/coreasm.h> 36 #include <xtensa/corebits.h> 37 #include <xtensa/xtensa-xer.h> 38 #include <xtensa/xtensa-versions.h> 39 40 /* 41 * This header file defines assembler macros of the form: 42 * <x>cache_<func> 43 * where <x> is 'i' or 'd' for instruction and data caches, 44 * and <func> indicates the function of the macro. 45 * 46 * The following functions <func> are defined, 47 * and apply only to the specified cache (I or D): 48 * 49 * reset 50 * Resets the cache. 51 * 52 * sync 53 * Makes sure any previous cache instructions have been completed; 54 * ie. makes sure any previous cache control operations 55 * have had full effect and been synchronized to memory. 56 * Eg. any invalidate completed [so as not to generate a hit], 57 * any writebacks or other pipelined writes written to memory, etc. 58 * 59 * invalidate_line (single cache line) 60 * invalidate_region (specified memory range) 61 * invalidate_all (entire cache) 62 * Invalidates all cache entries that cache 63 * data from the specified memory range. 64 * NOTE: locked entries are not invalidated. 65 * 66 * writeback_line (single cache line) 67 * writeback_region (specified memory range) 68 * writeback_all (entire cache) 69 * Writes back to memory all dirty cache entries 70 * that cache data from the specified memory range, 71 * and marks these entries as clean. 72 * NOTE: on some future implementations, this might 73 * also invalidate. 74 * NOTE: locked entries are written back, but never invalidated. 75 * NOTE: instruction caches never implement writeback. 76 * 77 * writeback_inv_line (single cache line) 78 * writeback_inv_region (specified memory range) 79 * writeback_inv_all (entire cache) 80 * Writes back to memory all dirty cache entries 81 * that cache data from the specified memory range, 82 * and invalidates these entries (including all clean 83 * cache entries that cache data from that range). 84 * NOTE: locked entries are written back but not invalidated. 85 * NOTE: instruction caches never implement writeback. 86 * 87 * lock_line (single cache line) 88 * lock_region (specified memory range) 89 * Prefetch and lock the specified memory range into cache. 90 * NOTE: if any part of the specified memory range cannot 91 * be locked, a Load/Store Error (for dcache) or Instruction 92 * Fetch Error (for icache) exception occurs. These macros don't 93 * do anything special (yet anyway) to handle this situation. 94 * 95 * unlock_line (single cache line) 96 * unlock_region (specified memory range) 97 * unlock_all (entire cache) 98 * Unlock cache entries that cache the specified memory range. 99 * Entries not already locked are unaffected. 100 * 101 * coherence_on 102 * coherence_off 103 * Turn off and on cache coherence 104 * 105 */ 106 107 108 109 /*************************** GENERIC -- ALL CACHES ***************************/ 110 111 112 /* 113 * The following macros assume the following cache size/parameter limits 114 * in the current Xtensa core implementation: 115 * cache size: 1024 bytes minimum 116 * line size: 16 - 64 bytes 117 * way count: 1 - 4 118 * 119 * Minimum entries per way (ie. per associativity) = 1024 / 64 / 4 = 4 120 * Hence the assumption that each loop can execute four cache instructions. 121 * 122 * Correspondingly, the offset range of instructions is assumed able to cover 123 * four lines, ie. offsets {0,1,2,3} * line_size are assumed valid for 124 * both hit and indexed cache instructions. Ie. these offsets are all 125 * valid: 0, 16, 32, 48, 64, 96, 128, 192 (for line sizes 16, 32, 64). 126 * This is true of all original cache instructions 127 * (dhi, ihi, dhwb, dhwbi, dii, iii) which have offsets 128 * of 0 to 1020 in multiples of 4 (ie. 8 bits shifted by 2). 129 * This is also true of subsequent cache instructions 130 * (dhu, ihu, diu, iiu, diwb, diwbi, dpfl, ipfl) which have offsets 131 * of 0 to 240 in multiples of 16 (ie. 4 bits shifted by 4). 132 * 133 * (Maximum cache size, currently 32k, doesn't affect the following macros. 134 * Cache ways > MMU min page size cause aliasing but that's another matter.) 135 */ 136 137 138 139 /* 140 * Macro to apply an 'indexed' cache instruction to the entire cache. 141 * 142 * Parameters: 143 * cainst instruction/ that takes an address register parameter 144 * and an offset parameter (in range 0 .. 3*linesize). 145 * size size of cache in bytes 146 * linesize size of cache line in bytes (always power-of-2) 147 * assoc_or1 number of associativities (ways/sets) in cache 148 * if all sets affected by cainst, 149 * or 1 if only one set (or not all sets) of the cache 150 * is affected by cainst (eg. DIWB or DIWBI [not yet ISA defined]). 151 * aa, ab unique address registers (temporaries). 152 * awb set to other than a0 if wb type of instruction 153 * loopokay 1 allows use of zero-overhead loops, 0 does not 154 * immrange range (max value) of cainst's immediate offset parameter, in bytes 155 * (NOTE: macro assumes immrange allows power-of-2 number of lines) 156 */ 157 158 .macro cache_index_all cainst, size, linesize, assoc_or1, aa, ab, loopokay, maxofs, awb=a0 159 160 // Number of indices in cache (lines per way): 161 .set .Lindices, (\size / (\linesize * \assoc_or1)) 162 // Number of indices processed per loop iteration (max 4): 163 .set .Lperloop, .Lindices 164 .ifgt .Lperloop - 4 165 .set .Lperloop, 4 166 .endif 167 // Also limit instructions per loop if cache line size exceeds immediate range: 168 .set .Lmaxperloop, (\maxofs / \linesize) + 1 169 .ifgt .Lperloop - .Lmaxperloop 170 .set .Lperloop, .Lmaxperloop 171 .endif 172 // Avoid addi of 128 which takes two instructions (addmi,addi): 173 .ifeq .Lperloop*\linesize - 128 174 .ifgt .Lperloop - 1 175 .set .Lperloop, .Lperloop / 2 176 .endif 177 .endif 178 179 // \size byte cache, \linesize byte lines, \assoc_or1 way(s) affected by each \cainst. 180 // XCHAL_ERRATUM_497 - don't execute using loop, to reduce the amount of added code 181 .ifne (\loopokay & XCHAL_HAVE_LOOPS && !XCHAL_ERRATUM_497) 182 183 movi \aa, .Lindices / .Lperloop // number of loop iterations 184 // Possible improvement: need only loop if \aa > 1 ; 185 // however \aa == 1 is highly unlikely. 186 movi \ab, 0 // to iterate over cache 187 loop \aa, .Lend_cachex\@ 188 .set .Li, 0 ; .rept .Lperloop 189 \cainst \ab, .Li*\linesize 190 .set .Li, .Li+1 ; .endr 191 addi \ab, \ab, .Lperloop*\linesize // move to next line 192 .Lend_cachex\@: 193 194 .else 195 196 movi \aa, (\size / \assoc_or1) 197 // Possible improvement: need only loop if \aa > 1 ; 198 // however \aa == 1 is highly unlikely. 199 movi \ab, 0 // to iterate over cache 200 .ifne ((\awb !=a0) & XCHAL_ERRATUM_497) // don't use awb if set to a0 201 movi \awb, 0 202 .endif 203 .Lstart_cachex\@: 204 .set .Li, 0 ; .rept .Lperloop 205 \cainst \ab, .Li*\linesize 206 .set .Li, .Li+1 ; .endr 207 .ifne ((\awb !=a0) & XCHAL_ERRATUM_497) // do memw after 8 cainst wb instructions 208 addi \awb, \awb, .Lperloop 209 blti \awb, 8, .Lstart_memw\@ 210 memw 211 movi \awb, 0 212 .Lstart_memw\@: 213 .endif 214 addi \ab, \ab, .Lperloop*\linesize // move to next line 215 bltu \ab, \aa, .Lstart_cachex\@ 216 .endif 217 218 .endm 219 220 221 /* 222 * Macro to apply a 'hit' cache instruction to a memory region, 223 * ie. to any cache entries that cache a specified portion (region) of memory. 224 * Takes care of the unaligned cases, ie. may apply to one 225 * more cache line than $asize / lineSize if $aaddr is not aligned. 226 * 227 * 228 * Parameters are: 229 * cainst instruction/macro that takes an address register parameter 230 * and an offset parameter (currently always zero) 231 * and generates a cache instruction (eg. "dhi", "dhwb", "ihi", etc.) 232 * linesize_log2 log2(size of cache line in bytes) 233 * addr register containing start address of region (clobbered) 234 * asize register containing size of the region in bytes (clobbered) 235 * askew unique register used as temporary 236 * awb unique register used as temporary for erratum 497. 237 * 238 * Note: A possible optimization to this macro is to apply the operation 239 * to the entire cache if the region exceeds the size of the cache 240 * by some empirically determined amount or factor. Some experimentation 241 * is required to determine the appropriate factors, which also need 242 * to be tunable if required. 243 */ 244 245 .macro cache_hit_region cainst, linesize_log2, addr, asize, askew, awb=a0 246 247 // Make \asize the number of iterations: 248 extui \askew, \addr, 0, \linesize_log2 // get unalignment amount of \addr 249 add \asize, \asize, \askew // ... and add it to \asize 250 addi \asize, \asize, (1 << \linesize_log2) - 1 // round up! 251 srli \asize, \asize, \linesize_log2 252 253 // Iterate over region: 254 .ifne ((\awb !=a0) & XCHAL_ERRATUM_497) // don't use awb if set to a0 255 movi \awb, 0 256 .endif 257 floopnez \asize, cacheh\@ 258 \cainst \addr, 0 259 .ifne ((\awb !=a0) & XCHAL_ERRATUM_497) // do memw after 8 cainst wb instructions 260 addi \awb, \awb, 1 261 blti \awb, 8, .Lstart_memw\@ 262 memw 263 movi \awb, 0 264 .Lstart_memw\@: 265 .endif 266 addi \addr, \addr, (1 << \linesize_log2) // move to next line 267 floopend \asize, cacheh\@ 268 .endm 269 270 271 272 273 274 /*************************** INSTRUCTION CACHE ***************************/ 275 276 277 /* 278 * Reset/initialize the instruction cache by simply invalidating it: 279 * (need to unlock first also, if cache locking implemented): 280 * 281 * Parameters: 282 * aa, ab unique address registers (temporaries) 283 */ 284 .macro icache_reset aa, ab, loopokay=0 285 icache_unlock_all \aa, \ab, \loopokay 286 icache_invalidate_all \aa, \ab, \loopokay 287 .endm 288 289 290 /* 291 * Synchronize after an instruction cache operation, 292 * to be sure everything is in sync with memory as to be 293 * expected following any previous instruction cache control operations. 294 * 295 * Even if a config doesn't have caches, an isync is still needed 296 * when instructions in any memory are modified, whether by a loader 297 * or self-modifying code. Therefore, this macro always produces 298 * an isync, whether or not an icache is present. 299 * 300 * Parameters are: 301 * ar an address register (temporary) (currently unused, but may be used in future) 302 */ 303 .macro icache_sync ar 304 isync 305 .endm 306 307 308 309 /* 310 * Invalidate a single line of the instruction cache. 311 * Parameters are: 312 * ar address register that contains (virtual) address to invalidate 313 * (may get clobbered in a future implementation, but not currently) 314 * offset (optional) offset to add to \ar to compute effective address to invalidate 315 * (note: some number of lsbits are ignored) 316 */ 317 .macro icache_invalidate_line ar, offset 318 #if XCHAL_ICACHE_SIZE > 0 319 ihi \ar, \offset // invalidate icache line 320 icache_sync \ar 321 #endif 322 .endm 323 324 325 326 327 /* 328 * Invalidate instruction cache entries that cache a specified portion of memory. 329 * Parameters are: 330 * astart start address (register gets clobbered) 331 * asize size of the region in bytes (register gets clobbered) 332 * ac unique register used as temporary 333 */ 334 .macro icache_invalidate_region astart, asize, ac 335 #if XCHAL_ICACHE_SIZE > 0 336 // Instruction cache region invalidation: 337 cache_hit_region ihi, XCHAL_ICACHE_LINEWIDTH, \astart, \asize, \ac 338 icache_sync \ac 339 // End of instruction cache region invalidation 340 #endif 341 .endm 342 343 344 345 /* 346 * Invalidate entire instruction cache. 347 * 348 * Parameters: 349 * aa, ab unique address registers (temporaries) 350 */ 351 .macro icache_invalidate_all aa, ab, loopokay=1 352 #if XCHAL_ICACHE_SIZE > 0 353 // Instruction cache invalidation: 354 cache_index_all iii, XCHAL_ICACHE_SIZE, XCHAL_ICACHE_LINESIZE, XCHAL_ICACHE_WAYS, \aa, \ab, \loopokay, 1020 355 icache_sync \aa 356 // End of instruction cache invalidation 357 #endif 358 .endm 359 360 361 362 /* 363 * Lock (prefetch & lock) a single line of the instruction cache. 364 * 365 * Parameters are: 366 * ar address register that contains (virtual) address to lock 367 * (may get clobbered in a future implementation, but not currently) 368 * offset offset to add to \ar to compute effective address to lock 369 * (note: some number of lsbits are ignored) 370 */ 371 .macro icache_lock_line ar, offset 372 #if XCHAL_ICACHE_SIZE > 0 && XCHAL_ICACHE_LINE_LOCKABLE 373 ipfl \ar, \offset /* prefetch and lock icache line */ 374 icache_sync \ar 375 #endif 376 .endm 377 378 379 380 /* 381 * Lock (prefetch & lock) a specified portion of memory into the instruction cache. 382 * Parameters are: 383 * astart start address (register gets clobbered) 384 * asize size of the region in bytes (register gets clobbered) 385 * ac unique register used as temporary 386 */ 387 .macro icache_lock_region astart, asize, ac 388 #if XCHAL_ICACHE_SIZE > 0 && XCHAL_ICACHE_LINE_LOCKABLE 389 // Instruction cache region lock: 390 cache_hit_region ipfl, XCHAL_ICACHE_LINEWIDTH, \astart, \asize, \ac 391 icache_sync \ac 392 // End of instruction cache region lock 393 #endif 394 .endm 395 396 397 398 /* 399 * Unlock a single line of the instruction cache. 400 * 401 * Parameters are: 402 * ar address register that contains (virtual) address to unlock 403 * (may get clobbered in a future implementation, but not currently) 404 * offset offset to add to \ar to compute effective address to unlock 405 * (note: some number of lsbits are ignored) 406 */ 407 .macro icache_unlock_line ar, offset 408 #if XCHAL_ICACHE_SIZE > 0 && XCHAL_ICACHE_LINE_LOCKABLE 409 ihu \ar, \offset /* unlock icache line */ 410 icache_sync \ar 411 #endif 412 .endm 413 414 415 416 /* 417 * Unlock a specified portion of memory from the instruction cache. 418 * Parameters are: 419 * astart start address (register gets clobbered) 420 * asize size of the region in bytes (register gets clobbered) 421 * ac unique register used as temporary 422 */ 423 .macro icache_unlock_region astart, asize, ac 424 #if XCHAL_ICACHE_SIZE > 0 && XCHAL_ICACHE_LINE_LOCKABLE 425 // Instruction cache region unlock: 426 cache_hit_region ihu, XCHAL_ICACHE_LINEWIDTH, \astart, \asize, \ac 427 icache_sync \ac 428 // End of instruction cache region unlock 429 #endif 430 .endm 431 432 433 434 /* 435 * Unlock entire instruction cache. 436 * 437 * Parameters: 438 * aa, ab unique address registers (temporaries) 439 */ 440 .macro icache_unlock_all aa, ab, loopokay=1 441 #if XCHAL_ICACHE_SIZE > 0 && XCHAL_ICACHE_LINE_LOCKABLE 442 // Instruction cache unlock: 443 cache_index_all iiu, XCHAL_ICACHE_SIZE, XCHAL_ICACHE_LINESIZE, 1, \aa, \ab, \loopokay, 240 444 icache_sync \aa 445 // End of instruction cache unlock 446 #endif 447 .endm 448 449 450 451 452 453 /*************************** DATA CACHE ***************************/ 454 455 456 457 /* 458 * Reset/initialize the data cache by simply invalidating it 459 * (need to unlock first also, if cache locking implemented): 460 * 461 * Parameters: 462 * aa, ab unique address registers (temporaries) 463 */ 464 .macro dcache_reset aa, ab, loopokay=0 465 dcache_unlock_all \aa, \ab, \loopokay 466 dcache_invalidate_all \aa, \ab, \loopokay 467 .endm 468 469 470 471 472 /* 473 * Synchronize after a data cache operation, 474 * to be sure everything is in sync with memory as to be 475 * expected following any previous data cache control operations. 476 * 477 * Parameters are: 478 * ar an address register (temporary) (currently unused, but may be used in future) 479 */ 480 .macro dcache_sync ar, wbtype=0 481 #if XCHAL_DCACHE_SIZE > 0 482 // No synchronization is needed. 483 // (memw may be desired e.g. after writeback operation to help ensure subsequent 484 // external accesses are seen to follow that writeback, however that's outside 485 // the scope of this macro) 486 487 //dsync 488 .ifne (\wbtype & XCHAL_ERRATUM_497) 489 memw 490 .endif 491 #endif 492 .endm 493 494 495 496 /* 497 * Turn on cache coherence. 498 * 499 * WARNING: for RE-201x.x and later hardware, any interrupt that tries 500 * to change MEMCTL will see its changes dropped if the interrupt comes 501 * in the middle of this routine. If this might be an issue, call this 502 * routine with interrupts disabled. 503 * 504 * Parameters are: 505 * ar,at two scratch address registers (both clobbered) 506 */ 507 .macro cache_coherence_on ar at 508 #if XCHAL_DCACHE_IS_COHERENT 509 # if XCHAL_HW_MIN_VERSION >= XTENSA_HWVERSION_RE_2012_0 510 /* Have MEMCTL. Enable snoop responses. */ 511 rsr.memctl \ar 512 movi \at, MEMCTL_SNOOP_EN 513 or \ar, \ar, \at 514 wsr.memctl \ar 515 # elif XCHAL_HAVE_EXTERN_REGS && XCHAL_HAVE_MX 516 /* Opt into coherence for MX (for backward compatibility / testing). */ 517 movi \ar, 1 518 movi \at, XER_CCON 519 wer \ar, \at 520 extw 521 # endif 522 #endif 523 .endm 524 525 526 527 /* 528 * Turn off cache coherence. 529 * 530 * NOTE: this is generally preceded by emptying the cache; 531 * see xthal_cache_coherence_optout() in hal/coherence.c for details. 532 * 533 * WARNING: for RE-201x.x and later hardware, any interrupt that tries 534 * to change MEMCTL will see its changes dropped if the interrupt comes 535 * in the middle of this routine. If this might be an issue, call this 536 * routine with interrupts disabled. 537 * 538 * Parameters are: 539 * ar,at two scratch address registers (both clobbered) 540 */ 541 .macro cache_coherence_off ar at 542 #if XCHAL_DCACHE_IS_COHERENT 543 # if XCHAL_HW_MIN_VERSION >= XTENSA_HWVERSION_RE_2012_0 544 /* Have MEMCTL. Disable snoop responses. */ 545 rsr.memctl \ar 546 movi \at, ~MEMCTL_SNOOP_EN 547 and \ar, \ar, \at 548 wsr.memctl \ar 549 # elif XCHAL_HAVE_EXTERN_REGS && XCHAL_HAVE_MX 550 /* Opt out of coherence, for MX (for backward compatibility / testing). */ 551 extw 552 movi \at, 0 553 movi \ar, XER_CCON 554 wer \at, \ar 555 extw 556 # endif 557 #endif 558 .endm 559 560 561 562 /* 563 * Synchronize after a data store operation, 564 * to be sure the stored data is completely off the processor 565 * (and assuming there is no buffering outside the processor, 566 * that the data is in memory). This may be required to 567 * ensure that the processor's write buffers are emptied. 568 * A MEMW followed by a read guarantees this, by definition. 569 * We also try to make sure the read itself completes. 570 * 571 * Parameters are: 572 * ar an address register (temporary) 573 */ 574 .macro write_sync ar 575 memw // ensure previous memory accesses are complete prior to subsequent memory accesses 576 l32i \ar, sp, 0 // completing this read ensures any previous write has completed, because of MEMW 577 //slot 578 add \ar, \ar, \ar // use the result of the read to help ensure the read completes (in future architectures) 579 .endm 580 581 582 /* 583 * Invalidate a single line of the data cache. 584 * Parameters are: 585 * ar address register that contains (virtual) address to invalidate 586 * (may get clobbered in a future implementation, but not currently) 587 * offset (optional) offset to add to \ar to compute effective address to invalidate 588 * (note: some number of lsbits are ignored) 589 */ 590 .macro dcache_invalidate_line ar, offset 591 #if XCHAL_DCACHE_SIZE > 0 592 dhi \ar, \offset 593 dcache_sync \ar 594 #endif 595 .endm 596 597 598 599 600 601 /* 602 * Invalidate data cache entries that cache a specified portion of memory. 603 * Parameters are: 604 * astart start address (register gets clobbered) 605 * asize size of the region in bytes (register gets clobbered) 606 * ac unique register used as temporary 607 */ 608 .macro dcache_invalidate_region astart, asize, ac 609 #if XCHAL_DCACHE_SIZE > 0 610 // Data cache region invalidation: 611 cache_hit_region dhi, XCHAL_DCACHE_LINEWIDTH, \astart, \asize, \ac 612 dcache_sync \ac 613 // End of data cache region invalidation 614 #endif 615 .endm 616 617 618 619 /* 620 * Invalidate entire data cache. 621 * 622 * Parameters: 623 * aa, ab unique address registers (temporaries) 624 */ 625 .macro dcache_invalidate_all aa, ab, loopokay=1 626 #if XCHAL_DCACHE_SIZE > 0 627 // Data cache invalidation: 628 cache_index_all dii, XCHAL_DCACHE_SIZE, XCHAL_DCACHE_LINESIZE, XCHAL_DCACHE_WAYS, \aa, \ab, \loopokay, 1020 629 dcache_sync \aa 630 // End of data cache invalidation 631 #endif 632 .endm 633 634 635 636 /* 637 * Writeback a single line of the data cache. 638 * Parameters are: 639 * ar address register that contains (virtual) address to writeback 640 * (may get clobbered in a future implementation, but not currently) 641 * offset offset to add to \ar to compute effective address to writeback 642 * (note: some number of lsbits are ignored) 643 */ 644 .macro dcache_writeback_line ar, offset 645 #if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_IS_WRITEBACK 646 dhwb \ar, \offset 647 dcache_sync \ar, wbtype=1 648 #endif 649 .endm 650 651 652 653 /* 654 * Writeback dirty data cache entries that cache a specified portion of memory. 655 * Parameters are: 656 * astart start address (register gets clobbered) 657 * asize size of the region in bytes (register gets clobbered) 658 * ac unique register used as temporary 659 */ 660 .macro dcache_writeback_region astart, asize, ac, awb 661 #if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_IS_WRITEBACK 662 // Data cache region writeback: 663 cache_hit_region dhwb, XCHAL_DCACHE_LINEWIDTH, \astart, \asize, \ac, \awb 664 dcache_sync \ac, wbtype=1 665 // End of data cache region writeback 666 #endif 667 .endm 668 669 670 671 /* 672 * Writeback entire data cache. 673 * Parameters: 674 * aa, ab unique address registers (temporaries) 675 */ 676 .macro dcache_writeback_all aa, ab, awb, loopokay=1 677 #if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_IS_WRITEBACK 678 // Data cache writeback: 679 cache_index_all diwb, XCHAL_DCACHE_SIZE, XCHAL_DCACHE_LINESIZE, 1, \aa, \ab, \loopokay, 240, \awb, 680 dcache_sync \aa, wbtype=1 681 // End of data cache writeback 682 #endif 683 .endm 684 685 686 687 /* 688 * Writeback and invalidate a single line of the data cache. 689 * Parameters are: 690 * ar address register that contains (virtual) address to writeback and invalidate 691 * (may get clobbered in a future implementation, but not currently) 692 * offset offset to add to \ar to compute effective address to writeback and invalidate 693 * (note: some number of lsbits are ignored) 694 */ 695 .macro dcache_writeback_inv_line ar, offset 696 #if XCHAL_DCACHE_SIZE > 0 697 dhwbi \ar, \offset /* writeback and invalidate dcache line */ 698 dcache_sync \ar, wbtype=1 699 #endif 700 .endm 701 702 703 704 /* 705 * Writeback and invalidate data cache entries that cache a specified portion of memory. 706 * Parameters are: 707 * astart start address (register gets clobbered) 708 * asize size of the region in bytes (register gets clobbered) 709 * ac unique register used as temporary 710 */ 711 .macro dcache_writeback_inv_region astart, asize, ac, awb 712 #if XCHAL_DCACHE_SIZE > 0 713 // Data cache region writeback and invalidate: 714 cache_hit_region dhwbi, XCHAL_DCACHE_LINEWIDTH, \astart, \asize, \ac, \awb 715 dcache_sync \ac, wbtype=1 716 // End of data cache region writeback and invalidate 717 #endif 718 .endm 719 720 721 722 /* 723 * Writeback and invalidate entire data cache. 724 * Parameters: 725 * aa, ab unique address registers (temporaries) 726 */ 727 .macro dcache_writeback_inv_all aa, ab, awb, loopokay=1 728 #if XCHAL_DCACHE_SIZE > 0 729 // Data cache writeback and invalidate: 730 #if XCHAL_DCACHE_IS_WRITEBACK 731 cache_index_all diwbi, XCHAL_DCACHE_SIZE, XCHAL_DCACHE_LINESIZE, 1, \aa, \ab, \loopokay, 240, \awb 732 dcache_sync \aa, wbtype=1 733 #else /*writeback*/ 734 // Data cache does not support writeback, so just invalidate: */ 735 dcache_invalidate_all \aa, \ab, \loopokay 736 #endif /*writeback*/ 737 // End of data cache writeback and invalidate 738 #endif 739 .endm 740 741 742 743 744 /* 745 * Lock (prefetch & lock) a single line of the data cache. 746 * 747 * Parameters are: 748 * ar address register that contains (virtual) address to lock 749 * (may get clobbered in a future implementation, but not currently) 750 * offset offset to add to \ar to compute effective address to lock 751 * (note: some number of lsbits are ignored) 752 */ 753 .macro dcache_lock_line ar, offset 754 #if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_LINE_LOCKABLE 755 dpfl \ar, \offset /* prefetch and lock dcache line */ 756 dcache_sync \ar 757 #endif 758 .endm 759 760 761 762 /* 763 * Lock (prefetch & lock) a specified portion of memory into the data cache. 764 * Parameters are: 765 * astart start address (register gets clobbered) 766 * asize size of the region in bytes (register gets clobbered) 767 * ac unique register used as temporary 768 */ 769 .macro dcache_lock_region astart, asize, ac 770 #if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_LINE_LOCKABLE 771 // Data cache region lock: 772 cache_hit_region dpfl, XCHAL_DCACHE_LINEWIDTH, \astart, \asize, \ac 773 dcache_sync \ac 774 // End of data cache region lock 775 #endif 776 .endm 777 778 779 780 /* 781 * Unlock a single line of the data cache. 782 * 783 * Parameters are: 784 * ar address register that contains (virtual) address to unlock 785 * (may get clobbered in a future implementation, but not currently) 786 * offset offset to add to \ar to compute effective address to unlock 787 * (note: some number of lsbits are ignored) 788 */ 789 .macro dcache_unlock_line ar, offset 790 #if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_LINE_LOCKABLE 791 dhu \ar, \offset /* unlock dcache line */ 792 dcache_sync \ar 793 #endif 794 .endm 795 796 797 798 /* 799 * Unlock a specified portion of memory from the data cache. 800 * Parameters are: 801 * astart start address (register gets clobbered) 802 * asize size of the region in bytes (register gets clobbered) 803 * ac unique register used as temporary 804 */ 805 .macro dcache_unlock_region astart, asize, ac 806 #if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_LINE_LOCKABLE 807 // Data cache region unlock: 808 cache_hit_region dhu, XCHAL_DCACHE_LINEWIDTH, \astart, \asize, \ac 809 dcache_sync \ac 810 // End of data cache region unlock 811 #endif 812 .endm 813 814 815 816 /* 817 * Unlock entire data cache. 818 * 819 * Parameters: 820 * aa, ab unique address registers (temporaries) 821 */ 822 .macro dcache_unlock_all aa, ab, loopokay=1 823 #if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_LINE_LOCKABLE 824 // Data cache unlock: 825 cache_index_all diu, XCHAL_DCACHE_SIZE, XCHAL_DCACHE_LINESIZE, 1, \aa, \ab, \loopokay, 240 826 dcache_sync \aa 827 // End of data cache unlock 828 #endif 829 .endm 830 831 832 833 /* 834 * Get the number of enabled icache ways. Note that this may 835 * be different from the value read from the MEMCTL register. 836 * 837 * Parameters: 838 * aa address register where value is returned 839 */ 840 .macro icache_get_ways aa 841 #if XCHAL_ICACHE_SIZE > 0 842 #if XCHAL_HAVE_ICACHE_DYN_WAYS 843 // Read from MEMCTL and shift/mask 844 rsr.memctl \aa 845 extui \aa, \aa, MEMCTL_ICWU_SHIFT, MEMCTL_ICWU_BITS 846 blti \aa, XCHAL_ICACHE_WAYS, .Licgw 847 movi \aa, XCHAL_ICACHE_WAYS 848 .Licgw: 849 #else 850 // All ways are always enabled 851 movi \aa, XCHAL_ICACHE_WAYS 852 #endif 853 #else 854 // No icache 855 movi \aa, 0 856 #endif 857 .endm 858 859 860 861 /* 862 * Set the number of enabled icache ways. 863 * 864 * Parameters: 865 * aa address register specifying number of ways (trashed) 866 * ab,ac address register for scratch use (trashed) 867 */ 868 .macro icache_set_ways aa, ab, ac 869 #if XCHAL_ICACHE_SIZE > 0 870 #if XCHAL_HAVE_ICACHE_DYN_WAYS 871 movi \ac, MEMCTL_ICWU_CLR_MASK // set up to clear bits 18-22 872 rsr.memctl \ab 873 and \ab, \ab, \ac 874 movi \ac, MEMCTL_INV_EN // set bit 23 875 slli \aa, \aa, MEMCTL_ICWU_SHIFT // move to right spot 876 or \ab, \ab, \aa 877 or \ab, \ab, \ac 878 wsr.memctl \ab 879 isync 880 #else 881 // All ways are always enabled 882 #endif 883 #else 884 // No icache 885 #endif 886 .endm 887 888 889 890 /* 891 * Get the number of enabled dcache ways. Note that this may 892 * be different from the value read from the MEMCTL register. 893 * 894 * Parameters: 895 * aa address register where value is returned 896 */ 897 .macro dcache_get_ways aa 898 #if XCHAL_DCACHE_SIZE > 0 899 #if XCHAL_HAVE_DCACHE_DYN_WAYS 900 // Read from MEMCTL and shift/mask 901 rsr.memctl \aa 902 extui \aa, \aa, MEMCTL_DCWU_SHIFT, MEMCTL_DCWU_BITS 903 blti \aa, XCHAL_DCACHE_WAYS, .Ldcgw 904 movi \aa, XCHAL_DCACHE_WAYS 905 .Ldcgw: 906 #else 907 // All ways are always enabled 908 movi \aa, XCHAL_DCACHE_WAYS 909 #endif 910 #else 911 // No dcache 912 movi \aa, 0 913 #endif 914 .endm 915 916 917 918 /* 919 * Set the number of enabled dcache ways. 920 * 921 * Parameters: 922 * aa address register specifying number of ways (trashed) 923 * ab,ac address register for scratch use (trashed) 924 */ 925 .macro dcache_set_ways aa, ab, ac 926 #if (XCHAL_DCACHE_SIZE > 0) && XCHAL_HAVE_DCACHE_DYN_WAYS 927 movi \ac, MEMCTL_DCWA_CLR_MASK // set up to clear bits 13-17 928 rsr.memctl \ab 929 and \ab, \ab, \ac // clear ways allocatable 930 slli \ac, \aa, MEMCTL_DCWA_SHIFT 931 or \ab, \ab, \ac // set ways allocatable 932 wsr.memctl \ab 933 #if XCHAL_DCACHE_IS_WRITEBACK 934 // Check if the way count is increasing or decreasing 935 extui \ac, \ab, MEMCTL_DCWU_SHIFT, MEMCTL_DCWU_BITS // bits 8-12 - ways in use 936 bge \aa, \ac, .Ldsw3 // equal or increasing 937 slli \ab, \aa, XCHAL_DCACHE_LINEWIDTH + XCHAL_DCACHE_SETWIDTH // start way number 938 slli \ac, \ac, XCHAL_DCACHE_LINEWIDTH + XCHAL_DCACHE_SETWIDTH // end way number 939 .Ldsw1: 940 diwbui.p \ab // auto-increments ab 941 bge \ab, \ac, .Ldsw2 942 beqz \ab, .Ldsw2 943 j .Ldsw1 944 .Ldsw2: 945 rsr.memctl \ab 946 #endif 947 .Ldsw3: 948 // No dirty data to write back, just set the new number of ways 949 movi \ac, MEMCTL_DCWU_CLR_MASK // set up to clear bits 8-12 950 and \ab, \ab, \ac // clear ways in use 951 movi \ac, MEMCTL_INV_EN 952 or \ab, \ab, \ac // set bit 23 953 slli \aa, \aa, MEMCTL_DCWU_SHIFT 954 or \ab, \ab, \aa // set ways in use 955 wsr.memctl \ab 956 #else 957 // No dcache or no way disable support 958 #endif 959 .endm 960 961 #endif /*XTENSA_CACHEASM_H*/ 962 963