]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/mips/mips/cache_mipsNN.c
Update compiler-rt to trunk r224034. This brings a number of new
[FreeBSD/FreeBSD.git] / sys / mips / mips / cache_mipsNN.c
1 /*      $NetBSD: cache_mipsNN.c,v 1.10 2005/12/24 20:07:19 perry Exp $  */
2
3 /*
4  * Copyright 2001 Wasabi Systems, Inc.
5  * All rights reserved.
6  *
7  * Written by Jason R. Thorpe and Simon Burge 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 __FBSDID("$FreeBSD$");
40
41 #include <sys/types.h>
42 #include <sys/systm.h>
43 #include <sys/param.h>
44
45 #include <machine/cache.h>
46 #include <machine/cache_r4k.h>
47 #include <machine/cpuinfo.h>
48
49 #define round_line16(x)         (((x) + 15) & ~15)
50 #define trunc_line16(x)         ((x) & ~15)
51
52 #define round_line32(x)         (((x) + 31) & ~31)
53 #define trunc_line32(x)         ((x) & ~31)
54
55 #define round_line128(x)        (((x) + 127) & ~127)
56 #define trunc_line128(x)        ((x) & ~127)
57
58 #if defined(CPU_NLM)
59 static __inline void
60 xlp_sync(void)
61 {
62         __asm __volatile (
63             ".set push              \n"
64             ".set noreorder         \n"
65             ".set mips64            \n"
66             "dla    $8, 1f          \n"
67             "/* jr.hb $8 */         \n"
68             ".word 0x1000408        \n"
69             "nop                    \n"
70          "1: nop                    \n"
71             ".set pop               \n"
72             : : : "$8");
73 }
74 #endif
75
76 #if defined(SB1250_PASS1)
77 #define SYNC    __asm volatile("sync; sync")
78 #elif defined(CPU_NLM)
79 #define SYNC    xlp_sync()
80 #else
81 #define SYNC    __asm volatile("sync")
82 #endif
83
84 #if defined(CPU_CNMIPS)
85 #define SYNCI  mips_sync_icache();
86 #elif defined(CPU_NLM)
87 #define SYNCI   xlp_sync()
88 #else
89 #define SYNCI
90 #endif
91
92 /*
93  * Exported variables for consumers like bus_dma code
94  */
95 int mips_picache_linesize;
96 int mips_pdcache_linesize;
97
98 static int picache_size;
99 static int picache_stride;
100 static int picache_loopcount;
101 static int picache_way_mask;
102 static int pdcache_size;
103 static int pdcache_stride;
104 static int pdcache_loopcount;
105 static int pdcache_way_mask;
106 static int sdcache_size;
107 static int sdcache_stride;
108 static int sdcache_loopcount;
109 static int sdcache_way_mask;
110
111 void
112 mipsNN_cache_init(struct mips_cpuinfo * cpuinfo)
113 {
114         int flush_multiple_lines_per_way;
115
116         flush_multiple_lines_per_way = cpuinfo->l1.ic_nsets * cpuinfo->l1.ic_linesize * cpuinfo->l1.ic_linesize > PAGE_SIZE;
117         if (cpuinfo->icache_virtual) {
118                 /*
119                  * With a virtual Icache we don't need to flush
120                  * multiples of the page size with index ops; we just
121                  * need to flush one pages' worth.
122                  */
123                 flush_multiple_lines_per_way = 0;
124         }
125
126         if (flush_multiple_lines_per_way) {
127                 picache_stride = PAGE_SIZE;
128                 picache_loopcount = (cpuinfo->l1.ic_nsets * cpuinfo->l1.ic_linesize / PAGE_SIZE) *
129                     cpuinfo->l1.ic_nways;
130         } else {
131                 picache_stride = cpuinfo->l1.ic_nsets * cpuinfo->l1.ic_linesize;
132                 picache_loopcount = cpuinfo->l1.ic_nways;
133         }
134
135         if (cpuinfo->l1.dc_nsets * cpuinfo->l1.dc_linesize < PAGE_SIZE) {
136                 pdcache_stride = cpuinfo->l1.dc_nsets * cpuinfo->l1.dc_linesize;
137                 pdcache_loopcount = cpuinfo->l1.dc_nways;
138         } else {
139                 pdcache_stride = PAGE_SIZE;
140                 pdcache_loopcount = (cpuinfo->l1.dc_nsets * cpuinfo->l1.dc_linesize / PAGE_SIZE) *
141                     cpuinfo->l1.dc_nways;
142         }
143
144         mips_picache_linesize = cpuinfo->l1.ic_linesize;
145         mips_pdcache_linesize = cpuinfo->l1.dc_linesize;
146
147         picache_size = cpuinfo->l1.ic_size;
148         picache_way_mask = cpuinfo->l1.ic_nways - 1;
149         pdcache_size = cpuinfo->l1.dc_size;
150         pdcache_way_mask = cpuinfo->l1.dc_nways - 1;
151
152         sdcache_stride = cpuinfo->l2.dc_nsets * cpuinfo->l2.dc_linesize;
153         sdcache_loopcount = cpuinfo->l2.dc_nways;
154         sdcache_size = cpuinfo->l2.dc_size;
155         sdcache_way_mask = cpuinfo->l2.dc_nways - 1;
156
157 #define CACHE_DEBUG
158 #ifdef CACHE_DEBUG
159         printf("Cache info:\n");
160         if (cpuinfo->icache_virtual)
161                 printf("  icache is virtual\n");
162         printf("  picache_stride    = %d\n", picache_stride);
163         printf("  picache_loopcount = %d\n", picache_loopcount);
164         printf("  pdcache_stride    = %d\n", pdcache_stride);
165         printf("  pdcache_loopcount = %d\n", pdcache_loopcount);
166 #endif
167 }
168
169 void
170 mipsNN_icache_sync_all_16(void)
171 {
172         vm_offset_t va, eva;
173
174         va = MIPS_PHYS_TO_KSEG0(0);
175         eva = va + picache_size;
176
177         /*
178          * Since we're hitting the whole thing, we don't have to
179          * worry about the N different "ways".
180          */
181
182         mips_intern_dcache_wbinv_all();
183
184         while (va < eva) {
185                 cache_r4k_op_32lines_16(va, CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
186                 va += (32 * 16);
187         }
188
189         SYNC;
190 }
191
192 void
193 mipsNN_icache_sync_all_32(void)
194 {
195         vm_offset_t va, eva;
196
197         va = MIPS_PHYS_TO_KSEG0(0);
198         eva = va + picache_size;
199
200         /*
201          * Since we're hitting the whole thing, we don't have to
202          * worry about the N different "ways".
203          */
204
205         mips_intern_dcache_wbinv_all();
206
207         while (va < eva) {
208                 cache_r4k_op_32lines_32(va, CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
209                 va += (32 * 32);
210         }
211
212         SYNC;
213 }
214
215 void
216 mipsNN_icache_sync_range_16(vm_offset_t va, vm_size_t size)
217 {
218         vm_offset_t eva;
219
220         eva = round_line16(va + size);
221         va = trunc_line16(va);
222
223         mips_intern_dcache_wb_range(va, (eva - va));
224
225         while ((eva - va) >= (32 * 16)) {
226                 cache_r4k_op_32lines_16(va, CACHE_R4K_I|CACHEOP_R4K_HIT_INV);
227                 va += (32 * 16);
228         }
229
230         while (va < eva) {
231                 cache_op_r4k_line(va, CACHE_R4K_I|CACHEOP_R4K_HIT_INV);
232                 va += 16;
233         }
234
235         SYNC;
236 }
237
238 void
239 mipsNN_icache_sync_range_32(vm_offset_t va, vm_size_t size)
240 {
241         vm_offset_t eva;
242
243         eva = round_line32(va + size);
244         va = trunc_line32(va);
245
246         mips_intern_dcache_wb_range(va, (eva - va));
247
248         while ((eva - va) >= (32 * 32)) {
249                 cache_r4k_op_32lines_32(va, CACHE_R4K_I|CACHEOP_R4K_HIT_INV);
250                 va += (32 * 32);
251         }
252
253         while (va < eva) {
254                 cache_op_r4k_line(va, CACHE_R4K_I|CACHEOP_R4K_HIT_INV);
255                 va += 32;
256         }
257
258         SYNC;
259 }
260
261 void
262 mipsNN_icache_sync_range_index_16(vm_offset_t va, vm_size_t size)
263 {
264         vm_offset_t eva, tmpva;
265         int i, stride, loopcount;
266
267         /*
268          * Since we're doing Index ops, we expect to not be able
269          * to access the address we've been given.  So, get the
270          * bits that determine the cache index, and make a KSEG0
271          * address out of them.
272          */
273         va = MIPS_PHYS_TO_KSEG0(va & picache_way_mask);
274
275         eva = round_line16(va + size);
276         va = trunc_line16(va);
277
278         /*
279          * GCC generates better code in the loops if we reference local
280          * copies of these global variables.
281          */
282         stride = picache_stride;
283         loopcount = picache_loopcount;
284
285         mips_intern_dcache_wbinv_range_index(va, (eva - va));
286
287         while ((eva - va) >= (8 * 16)) {
288                 tmpva = va;
289                 for (i = 0; i < loopcount; i++, tmpva += stride)
290                         cache_r4k_op_8lines_16(tmpva,
291                             CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
292                 va += 8 * 16;
293         }
294
295         while (va < eva) {
296                 tmpva = va;
297                 for (i = 0; i < loopcount; i++, tmpva += stride)
298                         cache_op_r4k_line(tmpva,
299                             CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
300                 va += 16;
301         }
302 }
303
304 void
305 mipsNN_icache_sync_range_index_32(vm_offset_t va, vm_size_t size)
306 {
307         vm_offset_t eva, tmpva;
308         int i, stride, loopcount;
309
310         /*
311          * Since we're doing Index ops, we expect to not be able
312          * to access the address we've been given.  So, get the
313          * bits that determine the cache index, and make a KSEG0
314          * address out of them.
315          */
316         va = MIPS_PHYS_TO_KSEG0(va & picache_way_mask);
317
318         eva = round_line32(va + size);
319         va = trunc_line32(va);
320
321         /*
322          * GCC generates better code in the loops if we reference local
323          * copies of these global variables.
324          */
325         stride = picache_stride;
326         loopcount = picache_loopcount;
327
328         mips_intern_dcache_wbinv_range_index(va, (eva - va));
329
330         while ((eva - va) >= (8 * 32)) {
331                 tmpva = va;
332                 for (i = 0; i < loopcount; i++, tmpva += stride)
333                         cache_r4k_op_8lines_32(tmpva,
334                             CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
335                 va += 8 * 32;
336         }
337
338         while (va < eva) {
339                 tmpva = va;
340                 for (i = 0; i < loopcount; i++, tmpva += stride)
341                         cache_op_r4k_line(tmpva,
342                             CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
343                 va += 32;
344         }
345 }
346
347 void
348 mipsNN_pdcache_wbinv_all_16(void)
349 {
350         vm_offset_t va, eva;
351
352         va = MIPS_PHYS_TO_KSEG0(0);
353         eva = va + pdcache_size;
354
355         /*
356          * Since we're hitting the whole thing, we don't have to
357          * worry about the N different "ways".
358          */
359
360         while (va < eva) {
361                 cache_r4k_op_32lines_16(va,
362                     CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
363                 va += (32 * 16);
364         }
365
366         SYNC;
367 }
368
369 void
370 mipsNN_pdcache_wbinv_all_32(void)
371 {
372         vm_offset_t va, eva;
373
374         va = MIPS_PHYS_TO_KSEG0(0);
375         eva = va + pdcache_size;
376
377         /*
378          * Since we're hitting the whole thing, we don't have to
379          * worry about the N different "ways".
380          */
381
382         while (va < eva) {
383                 cache_r4k_op_32lines_32(va,
384                     CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
385                 va += (32 * 32);
386         }
387
388         SYNC;
389 }
390
391 void
392 mipsNN_pdcache_wbinv_range_16(vm_offset_t va, vm_size_t size)
393 {
394         vm_offset_t eva;
395
396         eva = round_line16(va + size);
397         va = trunc_line16(va);
398
399         while ((eva - va) >= (32 * 16)) {
400                 cache_r4k_op_32lines_16(va,
401                     CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV);
402                 va += (32 * 16);
403         }
404
405         while (va < eva) {
406                 cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV);
407                 va += 16;
408         }
409
410         SYNC;
411 }
412
413 void
414 mipsNN_pdcache_wbinv_range_32(vm_offset_t va, vm_size_t size)
415 {
416         vm_offset_t eva;
417
418         eva = round_line32(va + size);
419         va = trunc_line32(va);
420
421         while ((eva - va) >= (32 * 32)) {
422                 cache_r4k_op_32lines_32(va,
423                     CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV);
424                 va += (32 * 32);
425         }
426
427         while (va < eva) {
428                 cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV);
429                 va += 32;
430         }
431
432         SYNC;
433 }
434
435 void
436 mipsNN_pdcache_wbinv_range_index_16(vm_offset_t va, vm_size_t size)
437 {
438         vm_offset_t eva, tmpva;
439         int i, stride, loopcount;
440
441         /*
442          * Since we're doing Index ops, we expect to not be able
443          * to access the address we've been given.  So, get the
444          * bits that determine the cache index, and make a KSEG0
445          * address out of them.
446          */
447         va = MIPS_PHYS_TO_KSEG0(va & pdcache_way_mask);
448
449         eva = round_line16(va + size);
450         va = trunc_line16(va);
451
452         /*
453          * GCC generates better code in the loops if we reference local
454          * copies of these global variables.
455          */
456         stride = pdcache_stride;
457         loopcount = pdcache_loopcount;
458
459         while ((eva - va) >= (8 * 16)) {
460                 tmpva = va;
461                 for (i = 0; i < loopcount; i++, tmpva += stride)
462                         cache_r4k_op_8lines_16(tmpva,
463                             CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
464                 va += 8 * 16;
465         }
466
467         while (va < eva) {
468                 tmpva = va;
469                 for (i = 0; i < loopcount; i++, tmpva += stride)
470                         cache_op_r4k_line(tmpva,
471                             CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
472                 va += 16;
473         }
474 }
475
476 void
477 mipsNN_pdcache_wbinv_range_index_32(vm_offset_t va, vm_size_t size)
478 {
479         vm_offset_t eva, tmpva;
480         int i, stride, loopcount;
481
482         /*
483          * Since we're doing Index ops, we expect to not be able
484          * to access the address we've been given.  So, get the
485          * bits that determine the cache index, and make a KSEG0
486          * address out of them.
487          */
488         va = MIPS_PHYS_TO_KSEG0(va & pdcache_way_mask);
489
490         eva = round_line32(va + size);
491         va = trunc_line32(va);
492
493         /*
494          * GCC generates better code in the loops if we reference local
495          * copies of these global variables.
496          */
497         stride = pdcache_stride;
498         loopcount = pdcache_loopcount;
499
500         while ((eva - va) >= (8 * 32)) {
501                 tmpva = va;
502                 for (i = 0; i < loopcount; i++, tmpva += stride)
503                         cache_r4k_op_8lines_32(tmpva,
504                             CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
505                 va += 8 * 32;
506         }
507
508         while (va < eva) {
509                 tmpva = va;
510                 for (i = 0; i < loopcount; i++, tmpva += stride)
511                         cache_op_r4k_line(tmpva,
512                             CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
513                 va += 32;
514         }
515 }
516  
517 void
518 mipsNN_pdcache_inv_range_16(vm_offset_t va, vm_size_t size)
519 {
520         vm_offset_t eva;
521
522         eva = round_line16(va + size);
523         va = trunc_line16(va);
524
525         while ((eva - va) >= (32 * 16)) {
526                 cache_r4k_op_32lines_16(va, CACHE_R4K_D|CACHEOP_R4K_HIT_INV);
527                 va += (32 * 16);
528         }
529
530         while (va < eva) {
531                 cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_INV);
532                 va += 16;
533         }
534
535         SYNC;
536 }
537
538 void
539 mipsNN_pdcache_inv_range_32(vm_offset_t va, vm_size_t size)
540 {
541         vm_offset_t eva;
542
543         eva = round_line32(va + size);
544         va = trunc_line32(va);
545
546         while ((eva - va) >= (32 * 32)) {
547                 cache_r4k_op_32lines_32(va, CACHE_R4K_D|CACHEOP_R4K_HIT_INV);
548                 va += (32 * 32);
549         }
550
551         while (va < eva) {
552                 cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_INV);
553                 va += 32;
554         }
555
556         SYNC;
557 }
558
559 void
560 mipsNN_pdcache_wb_range_16(vm_offset_t va, vm_size_t size)
561 {
562         vm_offset_t eva;
563
564         eva = round_line16(va + size);
565         va = trunc_line16(va);
566
567         while ((eva - va) >= (32 * 16)) {
568                 cache_r4k_op_32lines_16(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB);
569                 va += (32 * 16);
570         }
571
572         while (va < eva) {
573                 cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB);
574                 va += 16;
575         }
576
577         SYNC;
578 }
579
580 void
581 mipsNN_pdcache_wb_range_32(vm_offset_t va, vm_size_t size)
582 {
583         vm_offset_t eva;
584
585         eva = round_line32(va + size);
586         va = trunc_line32(va);
587
588         while ((eva - va) >= (32 * 32)) {
589                 cache_r4k_op_32lines_32(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB);
590                 va += (32 * 32);
591         }
592
593         while (va < eva) {
594                 cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB);
595                 va += 32;
596         }
597
598         SYNC;
599 }
600
601
602 #ifdef CPU_CNMIPS
603
604 void
605 mipsNN_icache_sync_all_128(void)
606 {
607         SYNCI
608 }
609
610 void
611 mipsNN_icache_sync_range_128(vm_offset_t va, vm_size_t size)
612 {
613         SYNC;
614 }
615
616 void
617 mipsNN_icache_sync_range_index_128(vm_offset_t va, vm_size_t size)
618 {
619 }
620
621
622 void
623 mipsNN_pdcache_wbinv_all_128(void)
624 {
625 }
626
627
628 void
629 mipsNN_pdcache_wbinv_range_128(vm_offset_t va, vm_size_t size)
630 {
631         SYNC;
632 }
633
634 void
635 mipsNN_pdcache_wbinv_range_index_128(vm_offset_t va, vm_size_t size)
636 {
637 }
638
639 void
640 mipsNN_pdcache_inv_range_128(vm_offset_t va, vm_size_t size)
641 {
642 }
643
644 void
645 mipsNN_pdcache_wb_range_128(vm_offset_t va, vm_size_t size)
646 {
647         SYNC;
648 }
649
650 #endif
651
652 void
653 mipsNN_sdcache_wbinv_all_32(void)
654 {
655         vm_offset_t va = MIPS_PHYS_TO_KSEG0(0);
656         vm_offset_t eva = va + sdcache_size;
657
658         while (va < eva) {
659                 cache_r4k_op_32lines_32(va,
660                     CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
661                 va += (32 * 32);
662         }
663 }
664
665 void
666 mipsNN_sdcache_wbinv_range_32(vm_offset_t va, vm_size_t size)
667 {
668         vm_offset_t eva = round_line32(va + size);
669
670         va = trunc_line32(va);
671
672         while ((eva - va) >= (32 * 32)) {
673                 cache_r4k_op_32lines_32(va,
674                     CACHE_R4K_SD|CACHEOP_R4K_HIT_WB_INV);
675                 va += (32 * 32);
676         }
677
678         while (va < eva) {
679                 cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB_INV);
680                 va += 32;
681         }
682 }
683
684 void
685 mipsNN_sdcache_wbinv_range_index_32(vm_offset_t va, vm_size_t size)
686 {
687         vm_offset_t eva;
688
689         /*
690          * Since we're doing Index ops, we expect to not be able
691          * to access the address we've been given.  So, get the
692          * bits that determine the cache index, and make a KSEG0
693          * address out of them.
694          */
695         va = MIPS_PHYS_TO_KSEG0(va & (sdcache_size - 1));
696
697         eva = round_line32(va + size);
698         va = trunc_line32(va);
699
700         while ((eva - va) >= (32 * 32)) {
701                 cache_r4k_op_32lines_32(va,
702                     CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
703                 va += (32 * 32);
704         }
705
706         while (va < eva) {
707                 cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
708                 va += 32;
709         }
710 }
711
712 void
713 mipsNN_sdcache_inv_range_32(vm_offset_t va, vm_size_t size)
714 {
715         vm_offset_t eva = round_line32(va + size);
716
717         va = trunc_line32(va);
718
719         while ((eva - va) >= (32 * 32)) {
720                 cache_r4k_op_32lines_32(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_INV);
721                 va += (32 * 32);
722         }
723
724         while (va < eva) {
725                 cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_INV);
726                 va += 32;
727         }
728 }
729
730 void
731 mipsNN_sdcache_wb_range_32(vm_offset_t va, vm_size_t size)
732 {
733         vm_offset_t eva = round_line32(va + size);
734
735         va = trunc_line32(va);
736
737         while ((eva - va) >= (32 * 32)) {
738                 cache_r4k_op_32lines_32(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB);
739                 va += (32 * 32);
740         }
741
742         while (va < eva) {
743                 cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB);
744                 va += 32;
745         }
746 }
747
748 void
749 mipsNN_sdcache_wbinv_all_128(void)
750 {
751         vm_offset_t va = MIPS_PHYS_TO_KSEG0(0);
752         vm_offset_t eva = va + sdcache_size;
753
754         while (va < eva) {
755                 cache_r4k_op_32lines_128(va,
756                     CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
757                 va += (32 * 128);
758         }
759 }
760
761 void
762 mipsNN_sdcache_wbinv_range_128(vm_offset_t va, vm_size_t size)
763 {
764         vm_offset_t eva = round_line128(va + size);
765
766         va = trunc_line128(va);
767
768         while ((eva - va) >= (32 * 128)) {
769                 cache_r4k_op_32lines_128(va,
770                     CACHE_R4K_SD|CACHEOP_R4K_HIT_WB_INV);
771                 va += (32 * 128);
772         }
773
774         while (va < eva) {
775                 cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB_INV);
776                 va += 128;
777         }
778 }
779
780 void
781 mipsNN_sdcache_wbinv_range_index_128(vm_offset_t va, vm_size_t size)
782 {
783         vm_offset_t eva;
784
785         /*
786          * Since we're doing Index ops, we expect to not be able
787          * to access the address we've been given.  So, get the
788          * bits that determine the cache index, and make a KSEG0
789          * address out of them.
790          */
791         va = MIPS_PHYS_TO_KSEG0(va & (sdcache_size - 1));
792
793         eva = round_line128(va + size);
794         va = trunc_line128(va);
795
796         while ((eva - va) >= (32 * 128)) {
797                 cache_r4k_op_32lines_128(va,
798                     CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
799                 va += (32 * 128);
800         }
801
802         while (va < eva) {
803                 cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
804                 va += 128;
805         }
806 }
807
808 void
809 mipsNN_sdcache_inv_range_128(vm_offset_t va, vm_size_t size)
810 {
811         vm_offset_t eva = round_line128(va + size);
812
813         va = trunc_line128(va);
814
815         while ((eva - va) >= (32 * 128)) {
816                 cache_r4k_op_32lines_128(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_INV);
817                 va += (32 * 128);
818         }
819
820         while (va < eva) {
821                 cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_INV);
822                 va += 128;
823         }
824 }
825
826 void
827 mipsNN_sdcache_wb_range_128(vm_offset_t va, vm_size_t size)
828 {
829         vm_offset_t eva = round_line128(va + size);
830
831         va = trunc_line128(va);
832
833         while ((eva - va) >= (32 * 128)) {
834                 cache_r4k_op_32lines_128(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB);
835                 va += (32 * 128);
836         }
837
838         while (va < eva) {
839                 cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB);
840                 va += 128;
841         }
842 }