Home | History | Annotate | Line # | Download | only in mips
cache_r4k.c revision 1.8
      1 /*	$NetBSD: cache_r4k.c,v 1.8 2003/07/15 02:43:37 lukem Exp $	*/
      2 
      3 /*
      4  * Copyright 2001 Wasabi Systems, Inc.
      5  * All rights reserved.
      6  *
      7  * Written by Jason R. Thorpe for Wasabi Systems, Inc.
      8  *
      9  * Redistribution and use in source and binary forms, with or without
     10  * modification, are permitted provided that the following conditions
     11  * are met:
     12  * 1. Redistributions of source code must retain the above copyright
     13  *    notice, this list of conditions and the following disclaimer.
     14  * 2. Redistributions in binary form must reproduce the above copyright
     15  *    notice, this list of conditions and the following disclaimer in the
     16  *    documentation and/or other materials provided with the distribution.
     17  * 3. All advertising materials mentioning features or use of this software
     18  *    must display the following acknowledgement:
     19  *	This product includes software developed for the NetBSD Project by
     20  *	Wasabi Systems, Inc.
     21  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
     22  *    or promote products derived from this software without specific prior
     23  *    written permission.
     24  *
     25  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
     26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     27  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     28  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
     29  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     30  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     33  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     35  * POSSIBILITY OF SUCH DAMAGE.
     36  */
     37 
     38 #include <sys/cdefs.h>
     39 __KERNEL_RCSID(0, "$NetBSD: cache_r4k.c,v 1.8 2003/07/15 02:43:37 lukem Exp $");
     40 
     41 #include <sys/param.h>
     42 
     43 #include <mips/cache.h>
     44 #include <mips/cache_r4k.h>
     45 
     46 /*
     47  * Cache operations for R4000/R4400-style caches:
     48  *
     49  *	- Direct-mapped
     50  *	- Write-back
     51  *	- Virtually indexed, physically tagged
     52  *
     53  * XXX Does not handle split secondary caches.
     54  */
     55 
     56 #define	round_line(x)		(((x) + 15) & ~15)
     57 #define	trunc_line(x)		((x) & ~15)
     58 
     59 __asm(".set mips3");
     60 
     61 void
     62 r4k_icache_sync_all_16(void)
     63 {
     64 	vaddr_t va = MIPS_PHYS_TO_KSEG0(0);
     65 	vaddr_t eva = va + mips_picache_size;
     66 
     67 	mips_dcache_wbinv_all();
     68 
     69 	__asm __volatile("sync");
     70 
     71 	while (va < eva) {
     72 		cache_r4k_op_32lines_16(va, CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
     73 		va += (32 * 16);
     74 	}
     75 }
     76 
     77 void
     78 r4k_icache_sync_range_16(vaddr_t va, vsize_t size)
     79 {
     80 	vaddr_t eva = round_line(va + size);
     81 
     82 	va = trunc_line(va);
     83 
     84 	mips_dcache_wb_range(va, (eva - va));
     85 
     86 	__asm __volatile("sync");
     87 
     88 	while ((eva - va) >= (32 * 16)) {
     89 		cache_r4k_op_32lines_16(va, CACHE_R4K_I|CACHEOP_R4K_HIT_INV);
     90 		va += (32 * 16);
     91 	}
     92 
     93 	while (va < eva) {
     94 		cache_op_r4k_line(va, CACHE_R4K_I|CACHEOP_R4K_HIT_INV);
     95 		va += 16;
     96 	}
     97 }
     98 
     99 void
    100 r4k_icache_sync_range_index_16(vaddr_t va, vsize_t size)
    101 {
    102 	vaddr_t eva, orig_va;
    103 
    104 	orig_va = va;
    105 
    106 	eva = round_line(va + size);
    107 	va = trunc_line(va);
    108 
    109 	mips_dcache_wbinv_range_index(va, (eva - va));
    110 
    111 	__asm __volatile("sync");
    112 
    113 	/*
    114 	 * Since we're doing Index ops, we expect to not be able
    115 	 * to access the address we've been given.  So, get the
    116 	 * bits that determine the cache index, and make a KSEG0
    117 	 * address out of them.
    118 	 */
    119 	va = MIPS_PHYS_TO_KSEG0(orig_va & mips_picache_way_mask);
    120 
    121 	eva = round_line(va + size);
    122 	va = trunc_line(va);
    123 
    124 	while ((eva - va) >= (32 * 16)) {
    125 		cache_r4k_op_32lines_16(va, CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
    126 		va += (32 * 16);
    127 	}
    128 
    129 	while (va < eva) {
    130 		cache_op_r4k_line(va, CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
    131 		va += 16;
    132 	}
    133 }
    134 
    135 void
    136 r4k_pdcache_wbinv_all_16(void)
    137 {
    138 	vaddr_t va = MIPS_PHYS_TO_KSEG0(0);
    139 	vaddr_t eva = va + mips_pdcache_size;
    140 
    141 	while (va < eva) {
    142 		cache_r4k_op_32lines_16(va,
    143 		    CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
    144 		va += (32 * 16);
    145 	}
    146 }
    147 
    148 void
    149 r4k_pdcache_wbinv_range_16(vaddr_t va, vsize_t size)
    150 {
    151 	vaddr_t eva = round_line(va + size);
    152 
    153 	va = trunc_line(va);
    154 
    155 	while ((eva - va) >= (32 * 16)) {
    156 		cache_r4k_op_32lines_16(va,
    157 		    CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV);
    158 		va += (32 * 16);
    159 	}
    160 
    161 	while (va < eva) {
    162 		cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV);
    163 		va += 16;
    164 	}
    165 }
    166 
    167 void
    168 r4k_pdcache_wbinv_range_index_16(vaddr_t va, vsize_t size)
    169 {
    170 	vaddr_t eva;
    171 
    172 	/*
    173 	 * Since we're doing Index ops, we expect to not be able
    174 	 * to access the address we've been given.  So, get the
    175 	 * bits that determine the cache index, and make a KSEG0
    176 	 * address out of them.
    177 	 */
    178 	va = MIPS_PHYS_TO_KSEG0(va & (mips_pdcache_size - 1));
    179 
    180 	eva = round_line(va + size);
    181 	va = trunc_line(va);
    182 
    183 	while ((eva - va) >= (32 * 16)) {
    184 		cache_r4k_op_32lines_16(va,
    185 		    CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
    186 		va += (32 * 16);
    187 	}
    188 
    189 	while (va < eva) {
    190 		cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
    191 		va += 16;
    192 	}
    193 }
    194 
    195 void
    196 r4k_pdcache_inv_range_16(vaddr_t va, vsize_t size)
    197 {
    198 	vaddr_t eva = round_line(va + size);
    199 
    200 	va = trunc_line(va);
    201 
    202 	while ((eva - va) >= (32 * 16)) {
    203 		cache_r4k_op_32lines_16(va, CACHE_R4K_D|CACHEOP_R4K_HIT_INV);
    204 		va += (32 * 16);
    205 	}
    206 
    207 	while (va < eva) {
    208 		cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_INV);
    209 		va += 16;
    210 	}
    211 }
    212 
    213 void
    214 r4k_pdcache_wb_range_16(vaddr_t va, vsize_t size)
    215 {
    216 	vaddr_t eva = round_line(va + size);
    217 
    218 	va = trunc_line(va);
    219 
    220 	while ((eva - va) >= (32 * 16)) {
    221 		cache_r4k_op_32lines_16(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB);
    222 		va += (32 * 16);
    223 	}
    224 
    225 	while (va < eva) {
    226 		cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB);
    227 		va += 16;
    228 	}
    229 }
    230 
    231 #undef round_line
    232 #undef trunc_line
    233 
    234 #define	round_line(x)		(((x) + 31) & ~31)
    235 #define	trunc_line(x)		((x) & ~31)
    236 
    237 void
    238 r4k_icache_sync_all_32(void)
    239 {
    240 	vaddr_t va = MIPS_PHYS_TO_KSEG0(0);
    241 	vaddr_t eva = va + mips_picache_size;
    242 
    243 	mips_dcache_wbinv_all();
    244 
    245 	__asm __volatile("sync");
    246 
    247 	while (va < eva) {
    248 		cache_r4k_op_32lines_32(va, CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
    249 		va += (32 * 32);
    250 	}
    251 }
    252 
    253 void
    254 r4k_icache_sync_range_32(vaddr_t va, vsize_t size)
    255 {
    256 	vaddr_t eva = round_line(va + size);
    257 
    258 	va = trunc_line(va);
    259 
    260 	mips_dcache_wb_range(va, (eva - va));
    261 
    262 	__asm __volatile("sync");
    263 
    264 	while ((eva - va) >= (32 * 32)) {
    265 		cache_r4k_op_32lines_32(va, CACHE_R4K_I|CACHEOP_R4K_HIT_INV);
    266 		va += (32 * 32);
    267 	}
    268 
    269 	while (va < eva) {
    270 		cache_op_r4k_line(va, CACHE_R4K_I|CACHEOP_R4K_HIT_INV);
    271 		va += 32;
    272 	}
    273 }
    274 
    275 void
    276 r4k_icache_sync_range_index_32(vaddr_t va, vsize_t size)
    277 {
    278 	vaddr_t eva;
    279 
    280 	eva = round_line(va + size);
    281 	va = trunc_line(va);
    282 
    283 	mips_dcache_wbinv_range_index(va, (eva - va));
    284 
    285 	__asm __volatile("sync");
    286 
    287 	/*
    288 	 * Since we're doing Index ops, we expect to not be able
    289 	 * to access the address we've been given.  So, get the
    290 	 * bits that determine the cache index, and make a KSEG0
    291 	 * address out of them.
    292 	 */
    293 	va = MIPS_PHYS_TO_KSEG0(va & mips_picache_way_mask);
    294 
    295 	eva = round_line(va + size);
    296 	va = trunc_line(va);
    297 
    298 	while ((eva - va) >= (32 * 32)) {
    299 		cache_r4k_op_32lines_32(va, CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
    300 		va += (32 * 32);
    301 	}
    302 
    303 	while (va < eva) {
    304 		cache_op_r4k_line(va, CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
    305 		va += 32;
    306 	}
    307 }
    308 
    309 void
    310 r4k_pdcache_wbinv_all_32(void)
    311 {
    312 	vaddr_t va = MIPS_PHYS_TO_KSEG0(0);
    313 	vaddr_t eva = va + mips_pdcache_size;
    314 
    315 	while (va < eva) {
    316 		cache_r4k_op_32lines_32(va,
    317 		    CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
    318 		va += (32 * 32);
    319 	}
    320 }
    321 
    322 void
    323 r4k_pdcache_wbinv_range_32(vaddr_t va, vsize_t size)
    324 {
    325 	vaddr_t eva = round_line(va + size);
    326 
    327 	va = trunc_line(va);
    328 
    329 	while ((eva - va) >= (32 * 32)) {
    330 		cache_r4k_op_32lines_32(va,
    331 		    CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV);
    332 		va += (32 * 32);
    333 	}
    334 
    335 	while (va < eva) {
    336 		cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV);
    337 		va += 32;
    338 	}
    339 }
    340 
    341 void
    342 r4k_pdcache_wbinv_range_index_32(vaddr_t va, vsize_t size)
    343 {
    344 	vaddr_t eva;
    345 
    346 	/*
    347 	 * Since we're doing Index ops, we expect to not be able
    348 	 * to access the address we've been given.  So, get the
    349 	 * bits that determine the cache index, and make a KSEG0
    350 	 * address out of them.
    351 	 */
    352 	va = MIPS_PHYS_TO_KSEG0(va & (mips_pdcache_size - 1));
    353 
    354 	eva = round_line(va + size);
    355 	va = trunc_line(va);
    356 
    357 	while ((eva - va) >= (32 * 32)) {
    358 		cache_r4k_op_32lines_32(va,
    359 		    CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
    360 		va += (32 * 32);
    361 	}
    362 
    363 	while (va < eva) {
    364 		cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
    365 		va += 32;
    366 	}
    367 }
    368 
    369 void
    370 r4k_pdcache_inv_range_32(vaddr_t va, vsize_t size)
    371 {
    372 	vaddr_t eva = round_line(va + size);
    373 
    374 	va = trunc_line(va);
    375 
    376 	while ((eva - va) >= (32 * 32)) {
    377 		cache_r4k_op_32lines_32(va, CACHE_R4K_D|CACHEOP_R4K_HIT_INV);
    378 		va += (32 * 32);
    379 	}
    380 
    381 	while (va < eva) {
    382 		cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_INV);
    383 		va += 32;
    384 	}
    385 }
    386 
    387 void
    388 r4k_pdcache_wb_range_32(vaddr_t va, vsize_t size)
    389 {
    390 	vaddr_t eva = round_line(va + size);
    391 
    392 	va = trunc_line(va);
    393 
    394 	while ((eva - va) >= (32 * 32)) {
    395 		cache_r4k_op_32lines_32(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB);
    396 		va += (32 * 32);
    397 	}
    398 
    399 	while (va < eva) {
    400 		cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB);
    401 		va += 32;
    402 	}
    403 }
    404 
    405 void
    406 r4k_sdcache_wbinv_all_32(void)
    407 {
    408 	vaddr_t va = MIPS_PHYS_TO_KSEG0(0);
    409 	vaddr_t eva = va + mips_sdcache_size;
    410 
    411 	while (va < eva) {
    412 		cache_r4k_op_32lines_32(va,
    413 		    CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
    414 		va += (32 * 32);
    415 	}
    416 }
    417 
    418 void
    419 r4k_sdcache_wbinv_range_32(vaddr_t va, vsize_t size)
    420 {
    421 	vaddr_t eva = round_line(va + size);
    422 
    423 	va = trunc_line(va);
    424 
    425 	while ((eva - va) >= (32 * 32)) {
    426 		cache_r4k_op_32lines_32(va,
    427 		    CACHE_R4K_SD|CACHEOP_R4K_HIT_WB_INV);
    428 		va += (32 * 32);
    429 	}
    430 
    431 	while (va < eva) {
    432 		cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB_INV);
    433 		va += 32;
    434 	}
    435 }
    436 
    437 void
    438 r4k_sdcache_wbinv_range_index_32(vaddr_t va, vsize_t size)
    439 {
    440 	vaddr_t eva;
    441 
    442 	/*
    443 	 * Since we're doing Index ops, we expect to not be able
    444 	 * to access the address we've been given.  So, get the
    445 	 * bits that determine the cache index, and make a KSEG0
    446 	 * address out of them.
    447 	 */
    448 	va = MIPS_PHYS_TO_KSEG0(va & (mips_sdcache_size - 1));
    449 
    450 	eva = round_line(va + size);
    451 	va = trunc_line(va);
    452 
    453 	while ((eva - va) >= (32 * 32)) {
    454 		cache_r4k_op_32lines_32(va,
    455 		    CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
    456 		va += (32 * 32);
    457 	}
    458 
    459 	while (va < eva) {
    460 		cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
    461 		va += 32;
    462 	}
    463 }
    464 
    465 void
    466 r4k_sdcache_inv_range_32(vaddr_t va, vsize_t size)
    467 {
    468 	vaddr_t eva = round_line(va + size);
    469 
    470 	va = trunc_line(va);
    471 
    472 	while ((eva - va) >= (32 * 32)) {
    473 		cache_r4k_op_32lines_32(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_INV);
    474 		va += (32 * 32);
    475 	}
    476 
    477 	while (va < eva) {
    478 		cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_INV);
    479 		va += 32;
    480 	}
    481 }
    482 
    483 void
    484 r4k_sdcache_wb_range_32(vaddr_t va, vsize_t size)
    485 {
    486 	vaddr_t eva = round_line(va + size);
    487 
    488 	va = trunc_line(va);
    489 
    490 	while ((eva - va) >= (32 * 32)) {
    491 		cache_r4k_op_32lines_32(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB);
    492 		va += (32 * 32);
    493 	}
    494 
    495 	while (va < eva) {
    496 		cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB);
    497 		va += 32;
    498 	}
    499 }
    500 
    501 #undef round_line
    502 #undef trunc_line
    503 
    504 #define	round_line(x)		(((x) + 127) & ~127)
    505 #define	trunc_line(x)		((x) & ~127)
    506 
    507 void
    508 r4k_sdcache_wbinv_all_128(void)
    509 {
    510 	vaddr_t va = MIPS_PHYS_TO_KSEG0(0);
    511 	vaddr_t eva = va + mips_sdcache_size;
    512 
    513 	while (va < eva) {
    514 		cache_r4k_op_32lines_128(va,
    515 		    CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
    516 		va += (32 * 128);
    517 	}
    518 }
    519 
    520 void
    521 r4k_sdcache_wbinv_range_128(vaddr_t va, vsize_t size)
    522 {
    523 	vaddr_t eva = round_line(va + size);
    524 
    525 	va = trunc_line(va);
    526 
    527 	while ((eva - va) >= (32 * 128)) {
    528 		cache_r4k_op_32lines_128(va,
    529 		    CACHE_R4K_SD|CACHEOP_R4K_HIT_WB_INV);
    530 		va += (32 * 128);
    531 	}
    532 
    533 	while (va < eva) {
    534 		cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB_INV);
    535 		va += 128;
    536 	}
    537 }
    538 
    539 void
    540 r4k_sdcache_wbinv_range_index_128(vaddr_t va, vsize_t size)
    541 {
    542 	vaddr_t eva;
    543 
    544 	/*
    545 	 * Since we're doing Index ops, we expect to not be able
    546 	 * to access the address we've been given.  So, get the
    547 	 * bits that determine the cache index, and make a KSEG0
    548 	 * address out of them.
    549 	 */
    550 	va = MIPS_PHYS_TO_KSEG0(va & (mips_sdcache_size - 1));
    551 
    552 	eva = round_line(va + size);
    553 	va = trunc_line(va);
    554 
    555 	while ((eva - va) >= (32 * 128)) {
    556 		cache_r4k_op_32lines_128(va,
    557 		    CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
    558 		va += (32 * 128);
    559 	}
    560 
    561 	while (va < eva) {
    562 		cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
    563 		va += 128;
    564 	}
    565 }
    566 
    567 void
    568 r4k_sdcache_inv_range_128(vaddr_t va, vsize_t size)
    569 {
    570 	vaddr_t eva = round_line(va + size);
    571 
    572 	va = trunc_line(va);
    573 
    574 	while ((eva - va) >= (32 * 128)) {
    575 		cache_r4k_op_32lines_128(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_INV);
    576 		va += (32 * 128);
    577 	}
    578 
    579 	while (va < eva) {
    580 		cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_INV);
    581 		va += 128;
    582 	}
    583 }
    584 
    585 void
    586 r4k_sdcache_wb_range_128(vaddr_t va, vsize_t size)
    587 {
    588 	vaddr_t eva = round_line(va + size);
    589 
    590 	va = trunc_line(va);
    591 
    592 	while ((eva - va) >= (32 * 128)) {
    593 		cache_r4k_op_32lines_128(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB);
    594 		va += (32 * 128);
    595 	}
    596 
    597 	while (va < eva) {
    598 		cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB);
    599 		va += 128;
    600 	}
    601 }
    602 
    603 #undef round_line
    604 #undef trunc_line
    605 
    606 #define	round_line(x)		(((x) + mips_sdcache_line_size - 1) & ~(mips_sdcache_line_size - 1))
    607 #define	trunc_line(x)		((x) & ~(mips_sdcache_line_size - 1))
    608 
    609 void
    610 r4k_sdcache_wbinv_all_generic(void)
    611 {
    612 	vaddr_t va = MIPS_PHYS_TO_KSEG0(0);
    613 	vaddr_t eva = va + mips_sdcache_size;
    614 	int line_size = mips_sdcache_line_size;
    615 
    616 	while (va < eva) {
    617 		cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
    618 		va += line_size;
    619 	}
    620 }
    621 
    622 void
    623 r4k_sdcache_wbinv_range_generic(vaddr_t va, vsize_t size)
    624 {
    625 	vaddr_t eva = round_line(va + size);
    626 	int line_size = mips_sdcache_line_size;
    627 
    628 	va = trunc_line(va);
    629 
    630 	while (va < eva) {
    631 		cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB_INV);
    632 		va += line_size;
    633 	}
    634 }
    635 
    636 void
    637 r4k_sdcache_wbinv_range_index_generic(vaddr_t va, vsize_t size)
    638 {
    639 	vaddr_t eva;
    640 	int line_size = mips_sdcache_line_size;
    641 
    642 	/*
    643 	 * Since we're doing Index ops, we expect to not be able
    644 	 * to access the address we've been given.  So, get the
    645 	 * bits that determine the cache index, and make a KSEG0
    646 	 * address out of them.
    647 	 */
    648 	va = MIPS_PHYS_TO_KSEG0(va & (mips_sdcache_size - 1));
    649 
    650 	eva = round_line(va + size);
    651 	va = trunc_line(va);
    652 
    653 	while (va < eva) {
    654 		cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
    655 		va += line_size;
    656 	}
    657 }
    658 
    659 void
    660 r4k_sdcache_inv_range_generic(vaddr_t va, vsize_t size)
    661 {
    662 	vaddr_t eva = round_line(va + size);
    663 	int line_size = mips_sdcache_line_size;
    664 
    665 	va = trunc_line(va);
    666 
    667 	while (va < eva) {
    668 		cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_INV);
    669 		va += line_size;
    670 	}
    671 }
    672 
    673 void
    674 r4k_sdcache_wb_range_generic(vaddr_t va, vsize_t size)
    675 {
    676 	vaddr_t eva = round_line(va + size);
    677 	int line_size = mips_sdcache_line_size;
    678 
    679 	va = trunc_line(va);
    680 
    681 	while (va < eva) {
    682 		cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB);
    683 		va += line_size;
    684 	}
    685 }
    686 
    687 #undef round_line
    688 #undef trunc_line
    689