]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/mips/mips/cache_mipsNN.c
Merge bmake-20170510
[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_line64(x)         (((x) + 63) & ~63)
56 #define trunc_line64(x)         ((x) & ~63)
57
58 #define round_line128(x)        (((x) + 127) & ~127)
59 #define trunc_line128(x)        ((x) & ~127)
60
61 #if defined(CPU_NLM)
62 static __inline void
63 xlp_sync(void)
64 {
65         __asm __volatile (
66             ".set push              \n"
67             ".set noreorder         \n"
68             ".set mips64            \n"
69             "dla    $8, 1f          \n"
70             "/* jr.hb $8 */         \n"
71             ".word 0x1000408        \n"
72             "nop                    \n"
73          "1: nop                    \n"
74             ".set pop               \n"
75             : : : "$8");
76 }
77 #endif
78
79 #if defined(SB1250_PASS1)
80 #define SYNC    __asm volatile("sync; sync")
81 #elif defined(CPU_NLM)
82 #define SYNC    xlp_sync()
83 #else
84 #define SYNC    __asm volatile("sync")
85 #endif
86
87 #if defined(CPU_CNMIPS)
88 #define SYNCI  mips_sync_icache();
89 #elif defined(CPU_NLM)
90 #define SYNCI   xlp_sync()
91 #else
92 #define SYNCI
93 #endif
94
95 /*
96  * Exported variables for consumers like bus_dma code
97  */
98 int mips_picache_linesize;
99 int mips_pdcache_linesize;
100 int mips_sdcache_linesize;
101 int mips_dcache_max_linesize;
102
103 static int picache_size;
104 static int picache_stride;
105 static int picache_loopcount;
106 static int picache_way_mask;
107 static int pdcache_size;
108 static int pdcache_stride;
109 static int pdcache_loopcount;
110 static int pdcache_way_mask;
111 static int sdcache_size;
112 static int sdcache_stride;
113 static int sdcache_loopcount;
114 static int sdcache_way_mask;
115
116 void
117 mipsNN_cache_init(struct mips_cpuinfo * cpuinfo)
118 {
119         int flush_multiple_lines_per_way;
120
121         flush_multiple_lines_per_way = cpuinfo->l1.ic_nsets * cpuinfo->l1.ic_linesize * cpuinfo->l1.ic_linesize > PAGE_SIZE;
122         if (cpuinfo->icache_virtual) {
123                 /*
124                  * With a virtual Icache we don't need to flush
125                  * multiples of the page size with index ops; we just
126                  * need to flush one pages' worth.
127                  */
128                 flush_multiple_lines_per_way = 0;
129         }
130
131         if (flush_multiple_lines_per_way) {
132                 picache_stride = PAGE_SIZE;
133                 picache_loopcount = (cpuinfo->l1.ic_nsets * cpuinfo->l1.ic_linesize / PAGE_SIZE) *
134                     cpuinfo->l1.ic_nways;
135         } else {
136                 picache_stride = cpuinfo->l1.ic_nsets * cpuinfo->l1.ic_linesize;
137                 picache_loopcount = cpuinfo->l1.ic_nways;
138         }
139
140         if (cpuinfo->l1.dc_nsets * cpuinfo->l1.dc_linesize < PAGE_SIZE) {
141                 pdcache_stride = cpuinfo->l1.dc_nsets * cpuinfo->l1.dc_linesize;
142                 pdcache_loopcount = cpuinfo->l1.dc_nways;
143         } else {
144                 pdcache_stride = PAGE_SIZE;
145                 pdcache_loopcount = (cpuinfo->l1.dc_nsets * cpuinfo->l1.dc_linesize / PAGE_SIZE) *
146                     cpuinfo->l1.dc_nways;
147         }
148
149         mips_picache_linesize = cpuinfo->l1.ic_linesize;
150         mips_pdcache_linesize = cpuinfo->l1.dc_linesize;
151
152         picache_size = cpuinfo->l1.ic_size;
153         picache_way_mask = cpuinfo->l1.ic_nways - 1;
154         pdcache_size = cpuinfo->l1.dc_size;
155         pdcache_way_mask = cpuinfo->l1.dc_nways - 1;
156
157         sdcache_stride = cpuinfo->l2.dc_nsets * cpuinfo->l2.dc_linesize;
158         sdcache_loopcount = cpuinfo->l2.dc_nways;
159         sdcache_size = cpuinfo->l2.dc_size;
160         sdcache_way_mask = cpuinfo->l2.dc_nways - 1;
161
162         mips_sdcache_linesize = cpuinfo->l2.dc_linesize;
163         mips_dcache_max_linesize = MAX(mips_pdcache_linesize,
164             mips_sdcache_linesize);
165
166 #define CACHE_DEBUG
167 #ifdef CACHE_DEBUG
168         printf("Cache info:\n");
169         if (cpuinfo->icache_virtual)
170                 printf("  icache is virtual\n");
171         printf("  picache_stride    = %d\n", picache_stride);
172         printf("  picache_loopcount = %d\n", picache_loopcount);
173         printf("  pdcache_stride    = %d\n", pdcache_stride);
174         printf("  pdcache_loopcount = %d\n", pdcache_loopcount);
175         printf("  max line size     = %d\n", mips_dcache_max_linesize);
176 #endif
177 }
178
179 void
180 mipsNN_icache_sync_all_16(void)
181 {
182         vm_offset_t va, eva;
183
184         va = MIPS_PHYS_TO_KSEG0(0);
185         eva = va + picache_size;
186
187         /*
188          * Since we're hitting the whole thing, we don't have to
189          * worry about the N different "ways".
190          */
191
192         mips_intern_dcache_wbinv_all();
193
194         while (va < eva) {
195                 cache_r4k_op_32lines_16(va, CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
196                 va += (32 * 16);
197         }
198
199         SYNC;
200 }
201
202 void
203 mipsNN_icache_sync_all_32(void)
204 {
205         vm_offset_t va, eva;
206
207         va = MIPS_PHYS_TO_KSEG0(0);
208         eva = va + picache_size;
209
210         /*
211          * Since we're hitting the whole thing, we don't have to
212          * worry about the N different "ways".
213          */
214
215         mips_intern_dcache_wbinv_all();
216
217         while (va < eva) {
218                 cache_r4k_op_32lines_32(va, CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
219                 va += (32 * 32);
220         }
221
222         SYNC;
223 }
224
225 void
226 mipsNN_icache_sync_all_64(void)
227 {
228         vm_offset_t va, eva;
229
230         va = MIPS_PHYS_TO_KSEG0(0);
231         eva = va + picache_size;
232
233         /*
234          * Since we're hitting the whole thing, we don't have to
235          * worry about the N different "ways".
236          */
237
238         mips_intern_dcache_wbinv_all();
239
240         while (va < eva) {
241                 cache_r4k_op_32lines_64(va, CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
242                 va += (32 * 64);
243         }
244
245         SYNC;
246 }
247
248 void
249 mipsNN_icache_sync_range_16(vm_offset_t va, vm_size_t size)
250 {
251         vm_offset_t eva;
252
253         eva = round_line16(va + size);
254         va = trunc_line16(va);
255
256         mips_intern_dcache_wb_range(va, (eva - va));
257
258         while ((eva - va) >= (32 * 16)) {
259                 cache_r4k_op_32lines_16(va, CACHE_R4K_I|CACHEOP_R4K_HIT_INV);
260                 va += (32 * 16);
261         }
262
263         while (va < eva) {
264                 cache_op_r4k_line(va, CACHE_R4K_I|CACHEOP_R4K_HIT_INV);
265                 va += 16;
266         }
267
268         SYNC;
269 }
270
271 void
272 mipsNN_icache_sync_range_32(vm_offset_t va, vm_size_t size)
273 {
274         vm_offset_t eva;
275
276         eva = round_line32(va + size);
277         va = trunc_line32(va);
278
279         mips_intern_dcache_wb_range(va, (eva - va));
280
281         while ((eva - va) >= (32 * 32)) {
282                 cache_r4k_op_32lines_32(va, CACHE_R4K_I|CACHEOP_R4K_HIT_INV);
283                 va += (32 * 32);
284         }
285
286         while (va < eva) {
287                 cache_op_r4k_line(va, CACHE_R4K_I|CACHEOP_R4K_HIT_INV);
288                 va += 32;
289         }
290
291         SYNC;
292 }
293
294 void
295 mipsNN_icache_sync_range_64(vm_offset_t va, vm_size_t size)
296 {
297         vm_offset_t eva;
298
299         eva = round_line64(va + size);
300         va = trunc_line64(va);
301
302         mips_intern_dcache_wb_range(va, (eva - va));
303
304         while ((eva - va) >= (32 * 64)) {
305                 cache_r4k_op_32lines_64(va, CACHE_R4K_I|CACHEOP_R4K_HIT_INV);
306                 va += (32 * 64);
307         }
308
309         while (va < eva) {
310                 cache_op_r4k_line(va, CACHE_R4K_I|CACHEOP_R4K_HIT_INV);
311                 va += 64;
312         }
313
314         SYNC;
315 }
316
317 void
318 mipsNN_icache_sync_range_index_16(vm_offset_t va, vm_size_t size)
319 {
320         vm_offset_t eva, tmpva;
321         int i, stride, loopcount;
322
323         /*
324          * Since we're doing Index ops, we expect to not be able
325          * to access the address we've been given.  So, get the
326          * bits that determine the cache index, and make a KSEG0
327          * address out of them.
328          */
329         va = MIPS_PHYS_TO_KSEG0(va & picache_way_mask);
330
331         eva = round_line16(va + size);
332         va = trunc_line16(va);
333
334         /*
335          * GCC generates better code in the loops if we reference local
336          * copies of these global variables.
337          */
338         stride = picache_stride;
339         loopcount = picache_loopcount;
340
341         mips_intern_dcache_wbinv_range_index(va, (eva - va));
342
343         while ((eva - va) >= (8 * 16)) {
344                 tmpva = va;
345                 for (i = 0; i < loopcount; i++, tmpva += stride)
346                         cache_r4k_op_8lines_16(tmpva,
347                             CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
348                 va += 8 * 16;
349         }
350
351         while (va < eva) {
352                 tmpva = va;
353                 for (i = 0; i < loopcount; i++, tmpva += stride)
354                         cache_op_r4k_line(tmpva,
355                             CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
356                 va += 16;
357         }
358 }
359
360 void
361 mipsNN_icache_sync_range_index_32(vm_offset_t va, vm_size_t size)
362 {
363         vm_offset_t eva, tmpva;
364         int i, stride, loopcount;
365
366         /*
367          * Since we're doing Index ops, we expect to not be able
368          * to access the address we've been given.  So, get the
369          * bits that determine the cache index, and make a KSEG0
370          * address out of them.
371          */
372         va = MIPS_PHYS_TO_KSEG0(va & picache_way_mask);
373
374         eva = round_line32(va + size);
375         va = trunc_line32(va);
376
377         /*
378          * GCC generates better code in the loops if we reference local
379          * copies of these global variables.
380          */
381         stride = picache_stride;
382         loopcount = picache_loopcount;
383
384         mips_intern_dcache_wbinv_range_index(va, (eva - va));
385
386         while ((eva - va) >= (8 * 32)) {
387                 tmpva = va;
388                 for (i = 0; i < loopcount; i++, tmpva += stride)
389                         cache_r4k_op_8lines_32(tmpva,
390                             CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
391                 va += 8 * 32;
392         }
393
394         while (va < eva) {
395                 tmpva = va;
396                 for (i = 0; i < loopcount; i++, tmpva += stride)
397                         cache_op_r4k_line(tmpva,
398                             CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
399                 va += 32;
400         }
401 }
402
403 void
404 mipsNN_icache_sync_range_index_64(vm_offset_t va, vm_size_t size)
405 {
406         vm_offset_t eva, tmpva;
407         int i, stride, loopcount;
408
409         /*
410          * Since we're doing Index ops, we expect to not be able
411          * to access the address we've been given.  So, get the
412          * bits that determine the cache index, and make a KSEG0
413          * address out of them.
414          */
415         va = MIPS_PHYS_TO_KSEG0(va & picache_way_mask);
416
417         eva = round_line64(va + size);
418         va = trunc_line64(va);
419
420         /*
421          * GCC generates better code in the loops if we reference local
422          * copies of these global variables.
423          */
424         stride = picache_stride;
425         loopcount = picache_loopcount;
426
427         mips_intern_dcache_wbinv_range_index(va, (eva - va));
428
429         while ((eva - va) >= (8 * 64)) {
430                 tmpva = va;
431                 for (i = 0; i < loopcount; i++, tmpva += stride)
432                         cache_r4k_op_8lines_64(tmpva,
433                             CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
434                 va += 8 * 64;
435         }
436
437         while (va < eva) {
438                 tmpva = va;
439                 for (i = 0; i < loopcount; i++, tmpva += stride)
440                         cache_op_r4k_line(tmpva,
441                             CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
442                 va += 64;
443         }
444 }
445
446 void
447 mipsNN_pdcache_wbinv_all_16(void)
448 {
449         vm_offset_t va, eva;
450
451         va = MIPS_PHYS_TO_KSEG0(0);
452         eva = va + pdcache_size;
453
454         /*
455          * Since we're hitting the whole thing, we don't have to
456          * worry about the N different "ways".
457          */
458
459         while (va < eva) {
460                 cache_r4k_op_32lines_16(va,
461                     CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
462                 va += (32 * 16);
463         }
464
465         SYNC;
466 }
467
468 void
469 mipsNN_pdcache_wbinv_all_32(void)
470 {
471         vm_offset_t va, eva;
472
473         va = MIPS_PHYS_TO_KSEG0(0);
474         eva = va + pdcache_size;
475
476         /*
477          * Since we're hitting the whole thing, we don't have to
478          * worry about the N different "ways".
479          */
480
481         while (va < eva) {
482                 cache_r4k_op_32lines_32(va,
483                     CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
484                 va += (32 * 32);
485         }
486
487         SYNC;
488 }
489
490 void
491 mipsNN_pdcache_wbinv_all_64(void)
492 {
493         vm_offset_t va, eva;
494
495         va = MIPS_PHYS_TO_KSEG0(0);
496         eva = va + pdcache_size;
497
498         /*
499          * Since we're hitting the whole thing, we don't have to
500          * worry about the N different "ways".
501          */
502
503         while (va < eva) {
504                 cache_r4k_op_32lines_64(va,
505                     CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
506                 va += (32 * 64);
507         }
508
509         SYNC;
510 }
511
512 void
513 mipsNN_pdcache_wbinv_range_16(vm_offset_t va, vm_size_t size)
514 {
515         vm_offset_t eva;
516
517         eva = round_line16(va + size);
518         va = trunc_line16(va);
519
520         while ((eva - va) >= (32 * 16)) {
521                 cache_r4k_op_32lines_16(va,
522                     CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV);
523                 va += (32 * 16);
524         }
525
526         while (va < eva) {
527                 cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV);
528                 va += 16;
529         }
530
531         SYNC;
532 }
533
534 void
535 mipsNN_pdcache_wbinv_range_32(vm_offset_t va, vm_size_t size)
536 {
537         vm_offset_t eva;
538
539         eva = round_line32(va + size);
540         va = trunc_line32(va);
541
542         while ((eva - va) >= (32 * 32)) {
543                 cache_r4k_op_32lines_32(va,
544                     CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV);
545                 va += (32 * 32);
546         }
547
548         while (va < eva) {
549                 cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV);
550                 va += 32;
551         }
552
553         SYNC;
554 }
555
556 void
557 mipsNN_pdcache_wbinv_range_64(vm_offset_t va, vm_size_t size)
558 {
559         vm_offset_t eva;
560
561         eva = round_line64(va + size);
562         va = trunc_line64(va);
563
564         while ((eva - va) >= (32 * 64)) {
565                 cache_r4k_op_32lines_64(va,
566                     CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV);
567                 va += (32 * 64);
568         }
569
570         while (va < eva) {
571                 cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV);
572                 va += 64;
573         }
574
575         SYNC;
576 }
577
578 void
579 mipsNN_pdcache_wbinv_range_index_16(vm_offset_t va, vm_size_t size)
580 {
581         vm_offset_t eva, tmpva;
582         int i, stride, loopcount;
583
584         /*
585          * Since we're doing Index ops, we expect to not be able
586          * to access the address we've been given.  So, get the
587          * bits that determine the cache index, and make a KSEG0
588          * address out of them.
589          */
590         va = MIPS_PHYS_TO_KSEG0(va & pdcache_way_mask);
591
592         eva = round_line16(va + size);
593         va = trunc_line16(va);
594
595         /*
596          * GCC generates better code in the loops if we reference local
597          * copies of these global variables.
598          */
599         stride = pdcache_stride;
600         loopcount = pdcache_loopcount;
601
602         while ((eva - va) >= (8 * 16)) {
603                 tmpva = va;
604                 for (i = 0; i < loopcount; i++, tmpva += stride)
605                         cache_r4k_op_8lines_16(tmpva,
606                             CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
607                 va += 8 * 16;
608         }
609
610         while (va < eva) {
611                 tmpva = va;
612                 for (i = 0; i < loopcount; i++, tmpva += stride)
613                         cache_op_r4k_line(tmpva,
614                             CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
615                 va += 16;
616         }
617 }
618
619 void
620 mipsNN_pdcache_wbinv_range_index_32(vm_offset_t va, vm_size_t size)
621 {
622         vm_offset_t eva, tmpva;
623         int i, stride, loopcount;
624
625         /*
626          * Since we're doing Index ops, we expect to not be able
627          * to access the address we've been given.  So, get the
628          * bits that determine the cache index, and make a KSEG0
629          * address out of them.
630          */
631         va = MIPS_PHYS_TO_KSEG0(va & pdcache_way_mask);
632
633         eva = round_line32(va + size);
634         va = trunc_line32(va);
635
636         /*
637          * GCC generates better code in the loops if we reference local
638          * copies of these global variables.
639          */
640         stride = pdcache_stride;
641         loopcount = pdcache_loopcount;
642
643         while ((eva - va) >= (8 * 32)) {
644                 tmpva = va;
645                 for (i = 0; i < loopcount; i++, tmpva += stride)
646                         cache_r4k_op_8lines_32(tmpva,
647                             CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
648                 va += 8 * 32;
649         }
650
651         while (va < eva) {
652                 tmpva = va;
653                 for (i = 0; i < loopcount; i++, tmpva += stride)
654                         cache_op_r4k_line(tmpva,
655                             CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
656                 va += 32;
657         }
658 }
659
660 void
661 mipsNN_pdcache_wbinv_range_index_64(vm_offset_t va, vm_size_t size)
662 {
663         vm_offset_t eva, tmpva;
664         int i, stride, loopcount;
665
666         /*
667          * Since we're doing Index ops, we expect to not be able
668          * to access the address we've been given.  So, get the
669          * bits that determine the cache index, and make a KSEG0
670          * address out of them.
671          */
672         va = MIPS_PHYS_TO_KSEG0(va & pdcache_way_mask);
673
674         eva = round_line64(va + size);
675         va = trunc_line64(va);
676
677         /*
678          * GCC generates better code in the loops if we reference local
679          * copies of these global variables.
680          */
681         stride = pdcache_stride;
682         loopcount = pdcache_loopcount;
683
684         while ((eva - va) >= (8 * 64)) {
685                 tmpva = va;
686                 for (i = 0; i < loopcount; i++, tmpva += stride)
687                         cache_r4k_op_8lines_64(tmpva,
688                             CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
689                 va += 8 * 64;
690         }
691
692         while (va < eva) {
693                 tmpva = va;
694                 for (i = 0; i < loopcount; i++, tmpva += stride)
695                         cache_op_r4k_line(tmpva,
696                             CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
697                 va += 64;
698         }
699 }
700  
701 void
702 mipsNN_pdcache_inv_range_16(vm_offset_t va, vm_size_t size)
703 {
704         vm_offset_t eva;
705
706         eva = round_line16(va + size);
707         va = trunc_line16(va);
708
709         while ((eva - va) >= (32 * 16)) {
710                 cache_r4k_op_32lines_16(va, CACHE_R4K_D|CACHEOP_R4K_HIT_INV);
711                 va += (32 * 16);
712         }
713
714         while (va < eva) {
715                 cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_INV);
716                 va += 16;
717         }
718
719         SYNC;
720 }
721
722 void
723 mipsNN_pdcache_inv_range_32(vm_offset_t va, vm_size_t size)
724 {
725         vm_offset_t eva;
726
727         eva = round_line32(va + size);
728         va = trunc_line32(va);
729
730         while ((eva - va) >= (32 * 32)) {
731                 cache_r4k_op_32lines_32(va, CACHE_R4K_D|CACHEOP_R4K_HIT_INV);
732                 va += (32 * 32);
733         }
734
735         while (va < eva) {
736                 cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_INV);
737                 va += 32;
738         }
739
740         SYNC;
741 }
742
743 void
744 mipsNN_pdcache_inv_range_64(vm_offset_t va, vm_size_t size)
745 {
746         vm_offset_t eva;
747
748         eva = round_line64(va + size);
749         va = trunc_line64(va);
750
751         while ((eva - va) >= (32 * 64)) {
752                 cache_r4k_op_32lines_64(va, CACHE_R4K_D|CACHEOP_R4K_HIT_INV);
753                 va += (32 * 64);
754         }
755
756         while (va < eva) {
757                 cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_INV);
758                 va += 64;
759         }
760
761         SYNC;
762 }
763
764 void
765 mipsNN_pdcache_wb_range_16(vm_offset_t va, vm_size_t size)
766 {
767         vm_offset_t eva;
768
769         eva = round_line16(va + size);
770         va = trunc_line16(va);
771
772         while ((eva - va) >= (32 * 16)) {
773                 cache_r4k_op_32lines_16(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB);
774                 va += (32 * 16);
775         }
776
777         while (va < eva) {
778                 cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB);
779                 va += 16;
780         }
781
782         SYNC;
783 }
784
785 void
786 mipsNN_pdcache_wb_range_32(vm_offset_t va, vm_size_t size)
787 {
788         vm_offset_t eva;
789
790         eva = round_line32(va + size);
791         va = trunc_line32(va);
792
793         while ((eva - va) >= (32 * 32)) {
794                 cache_r4k_op_32lines_32(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB);
795                 va += (32 * 32);
796         }
797
798         while (va < eva) {
799                 cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB);
800                 va += 32;
801         }
802
803         SYNC;
804 }
805
806 void
807 mipsNN_pdcache_wb_range_64(vm_offset_t va, vm_size_t size)
808 {
809         vm_offset_t eva;
810
811         eva = round_line64(va + size);
812         va = trunc_line64(va);
813
814         while ((eva - va) >= (32 * 64)) {
815                 cache_r4k_op_32lines_64(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB);
816                 va += (32 * 64);
817         }
818
819         while (va < eva) {
820                 cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB);
821                 va += 64;
822         }
823
824         SYNC;
825 }
826
827 #ifdef CPU_CNMIPS
828
829 void
830 mipsNN_icache_sync_all_128(void)
831 {
832         SYNCI
833 }
834
835 void
836 mipsNN_icache_sync_range_128(vm_offset_t va, vm_size_t size)
837 {
838         SYNC;
839 }
840
841 void
842 mipsNN_icache_sync_range_index_128(vm_offset_t va, vm_size_t size)
843 {
844 }
845
846
847 void
848 mipsNN_pdcache_wbinv_all_128(void)
849 {
850 }
851
852
853 void
854 mipsNN_pdcache_wbinv_range_128(vm_offset_t va, vm_size_t size)
855 {
856         SYNC;
857 }
858
859 void
860 mipsNN_pdcache_wbinv_range_index_128(vm_offset_t va, vm_size_t size)
861 {
862 }
863
864 void
865 mipsNN_pdcache_inv_range_128(vm_offset_t va, vm_size_t size)
866 {
867 }
868
869 void
870 mipsNN_pdcache_wb_range_128(vm_offset_t va, vm_size_t size)
871 {
872         SYNC;
873 }
874
875 #else
876
877 void
878 mipsNN_icache_sync_all_128(void)
879 {
880         vm_offset_t va, eva;
881
882         va = MIPS_PHYS_TO_KSEG0(0);
883         eva = va + picache_size;
884
885         /*
886          * Since we're hitting the whole thing, we don't have to
887          * worry about the N different "ways".
888          */
889
890         mips_intern_dcache_wbinv_all();
891
892         while (va < eva) {
893                 cache_r4k_op_32lines_128(va, CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
894                 va += (32 * 128);
895         }
896
897         SYNC;
898 }
899
900 void
901 mipsNN_icache_sync_range_128(vm_offset_t va, vm_size_t size)
902 {
903         vm_offset_t eva;
904
905         eva = round_line128(va + size);
906         va = trunc_line128(va);
907
908         mips_intern_dcache_wb_range(va, (eva - va));
909
910         while ((eva - va) >= (32 * 128)) {
911                 cache_r4k_op_32lines_128(va, CACHE_R4K_I|CACHEOP_R4K_HIT_INV);
912                 va += (32 * 128);
913         }
914
915         while (va < eva) {
916                 cache_op_r4k_line(va, CACHE_R4K_I|CACHEOP_R4K_HIT_INV);
917                 va += 128;
918         }
919
920         SYNC;
921 }
922
923 void
924 mipsNN_icache_sync_range_index_128(vm_offset_t va, vm_size_t size)
925 {
926         vm_offset_t eva, tmpva;
927         int i, stride, loopcount;
928
929         /*
930          * Since we're doing Index ops, we expect to not be able
931          * to access the address we've been given.  So, get the
932          * bits that determine the cache index, and make a KSEG0
933          * address out of them.
934          */
935         va = MIPS_PHYS_TO_KSEG0(va & picache_way_mask);
936
937         eva = round_line128(va + size);
938         va = trunc_line128(va);
939
940         /*
941          * GCC generates better code in the loops if we reference local
942          * copies of these global variables.
943          */
944         stride = picache_stride;
945         loopcount = picache_loopcount;
946
947         mips_intern_dcache_wbinv_range_index(va, (eva - va));
948
949         while ((eva - va) >= (32 * 128)) {
950                 tmpva = va;
951                 for (i = 0; i < loopcount; i++, tmpva += stride)
952                         cache_r4k_op_32lines_128(tmpva,
953                             CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
954                 va += 32 * 128;
955         }
956
957         while (va < eva) {
958                 tmpva = va;
959                 for (i = 0; i < loopcount; i++, tmpva += stride)
960                         cache_op_r4k_line(tmpva,
961                             CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
962                 va += 128;
963         }
964 }
965
966 void
967 mipsNN_pdcache_wbinv_all_128(void)
968 {
969         vm_offset_t va, eva;
970
971         va = MIPS_PHYS_TO_KSEG0(0);
972         eva = va + pdcache_size;
973
974         /*
975          * Since we're hitting the whole thing, we don't have to
976          * worry about the N different "ways".
977          */
978
979         while (va < eva) {
980                 cache_r4k_op_32lines_128(va,
981                     CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
982                 va += (32 * 128);
983         }
984
985         SYNC;
986 }
987
988
989 void
990 mipsNN_pdcache_wbinv_range_128(vm_offset_t va, vm_size_t size)
991 {
992         vm_offset_t eva;
993
994         eva = round_line128(va + size);
995         va = trunc_line128(va);
996
997         while ((eva - va) >= (32 * 128)) {
998                 cache_r4k_op_32lines_128(va,
999                     CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV);
1000                 va += (32 * 128);
1001         }
1002
1003         while (va < eva) {
1004                 cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV);
1005                 va += 128;
1006         }
1007
1008         SYNC;
1009 }
1010
1011 void
1012 mipsNN_pdcache_wbinv_range_index_128(vm_offset_t va, vm_size_t size)
1013 {
1014         vm_offset_t eva, tmpva;
1015         int i, stride, loopcount;
1016
1017         /*
1018          * Since we're doing Index ops, we expect to not be able
1019          * to access the address we've been given.  So, get the
1020          * bits that determine the cache index, and make a KSEG0
1021          * address out of them.
1022          */
1023         va = MIPS_PHYS_TO_KSEG0(va & pdcache_way_mask);
1024
1025         eva = round_line128(va + size);
1026         va = trunc_line128(va);
1027
1028         /*
1029          * GCC generates better code in the loops if we reference local
1030          * copies of these global variables.
1031          */
1032         stride = pdcache_stride;
1033         loopcount = pdcache_loopcount;
1034
1035         while ((eva - va) >= (32 * 128)) {
1036                 tmpva = va;
1037                 for (i = 0; i < loopcount; i++, tmpva += stride)
1038                         cache_r4k_op_32lines_128(tmpva,
1039                             CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
1040                 va += 32 * 128;
1041         }
1042
1043         while (va < eva) {
1044                 tmpva = va;
1045                 for (i = 0; i < loopcount; i++, tmpva += stride)
1046                         cache_op_r4k_line(tmpva,
1047                             CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
1048                 va += 128;
1049         }
1050 }
1051
1052 void
1053 mipsNN_pdcache_inv_range_128(vm_offset_t va, vm_size_t size)
1054 {
1055         vm_offset_t eva;
1056
1057         eva = round_line128(va + size);
1058         va = trunc_line128(va);
1059
1060         while ((eva - va) >= (32 * 128)) {
1061                 cache_r4k_op_32lines_128(va, CACHE_R4K_D|CACHEOP_R4K_HIT_INV);
1062                 va += (32 * 128);
1063         }
1064
1065         while (va < eva) {
1066                 cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_INV);
1067                 va += 128;
1068         }
1069
1070         SYNC;
1071 }
1072
1073 void
1074 mipsNN_pdcache_wb_range_128(vm_offset_t va, vm_size_t size)
1075 {
1076         vm_offset_t eva;
1077
1078         eva = round_line128(va + size);
1079         va = trunc_line128(va);
1080
1081         while ((eva - va) >= (32 * 128)) {
1082                 cache_r4k_op_32lines_128(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB);
1083                 va += (32 * 128);
1084         }
1085
1086         while (va < eva) {
1087                 cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB);
1088                 va += 128;
1089         }
1090
1091         SYNC;
1092 }
1093
1094 #endif
1095
1096 void
1097 mipsNN_sdcache_wbinv_all_32(void)
1098 {
1099         vm_offset_t va = MIPS_PHYS_TO_KSEG0(0);
1100         vm_offset_t eva = va + sdcache_size;
1101
1102         while (va < eva) {
1103                 cache_r4k_op_32lines_32(va,
1104                     CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
1105                 va += (32 * 32);
1106         }
1107 }
1108
1109 void
1110 mipsNN_sdcache_wbinv_all_64(void)
1111 {
1112         vm_offset_t va = MIPS_PHYS_TO_KSEG0(0);
1113         vm_offset_t eva = va + sdcache_size;
1114
1115         while (va < eva) {
1116                 cache_r4k_op_32lines_64(va,
1117                     CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
1118                 va += (32 * 64);
1119         }
1120 }
1121
1122 void
1123 mipsNN_sdcache_wbinv_range_32(vm_offset_t va, vm_size_t size)
1124 {
1125         vm_offset_t eva = round_line32(va + size);
1126
1127         va = trunc_line32(va);
1128
1129         while ((eva - va) >= (32 * 32)) {
1130                 cache_r4k_op_32lines_32(va,
1131                     CACHE_R4K_SD|CACHEOP_R4K_HIT_WB_INV);
1132                 va += (32 * 32);
1133         }
1134
1135         while (va < eva) {
1136                 cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB_INV);
1137                 va += 32;
1138         }
1139 }
1140
1141 void
1142 mipsNN_sdcache_wbinv_range_64(vm_offset_t va, vm_size_t size)
1143 {
1144         vm_offset_t eva = round_line64(va + size);
1145
1146         va = trunc_line64(va);
1147
1148         while ((eva - va) >= (32 * 64)) {
1149                 cache_r4k_op_32lines_64(va,
1150                     CACHE_R4K_SD|CACHEOP_R4K_HIT_WB_INV);
1151                 va += (32 * 64);
1152         }
1153
1154         while (va < eva) {
1155                 cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB_INV);
1156                 va += 64;
1157         }
1158 }
1159
1160 void
1161 mipsNN_sdcache_wbinv_range_index_32(vm_offset_t va, vm_size_t size)
1162 {
1163         vm_offset_t eva;
1164
1165         /*
1166          * Since we're doing Index ops, we expect to not be able
1167          * to access the address we've been given.  So, get the
1168          * bits that determine the cache index, and make a KSEG0
1169          * address out of them.
1170          */
1171         va = MIPS_PHYS_TO_KSEG0(va & (sdcache_size - 1));
1172
1173         eva = round_line32(va + size);
1174         va = trunc_line32(va);
1175
1176         while ((eva - va) >= (32 * 32)) {
1177                 cache_r4k_op_32lines_32(va,
1178                     CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
1179                 va += (32 * 32);
1180         }
1181
1182         while (va < eva) {
1183                 cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
1184                 va += 32;
1185         }
1186 }
1187
1188 void
1189 mipsNN_sdcache_wbinv_range_index_64(vm_offset_t va, vm_size_t size)
1190 {
1191         vm_offset_t eva;
1192
1193         /*
1194          * Since we're doing Index ops, we expect to not be able
1195          * to access the address we've been given.  So, get the
1196          * bits that determine the cache index, and make a KSEG0
1197          * address out of them.
1198          */
1199         va = MIPS_PHYS_TO_KSEG0(va & (sdcache_size - 1));
1200
1201         eva = round_line64(va + size);
1202         va = trunc_line64(va);
1203
1204         while ((eva - va) >= (32 * 64)) {
1205                 cache_r4k_op_32lines_64(va,
1206                     CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
1207                 va += (32 * 64);
1208         }
1209
1210         while (va < eva) {
1211                 cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
1212                 va += 64;
1213         }
1214 }
1215
1216 void
1217 mipsNN_sdcache_inv_range_32(vm_offset_t va, vm_size_t size)
1218 {
1219         vm_offset_t eva = round_line32(va + size);
1220
1221         va = trunc_line32(va);
1222
1223         while ((eva - va) >= (32 * 32)) {
1224                 cache_r4k_op_32lines_32(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_INV);
1225                 va += (32 * 32);
1226         }
1227
1228         while (va < eva) {
1229                 cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_INV);
1230                 va += 32;
1231         }
1232 }
1233
1234 void
1235 mipsNN_sdcache_inv_range_64(vm_offset_t va, vm_size_t size)
1236 {
1237         vm_offset_t eva = round_line64(va + size);
1238
1239         va = trunc_line64(va);
1240
1241         while ((eva - va) >= (32 * 64)) {
1242                 cache_r4k_op_32lines_64(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_INV);
1243                 va += (32 * 64);
1244         }
1245
1246         while (va < eva) {
1247                 cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_INV);
1248                 va += 64;
1249         }
1250 }
1251
1252 void
1253 mipsNN_sdcache_wb_range_32(vm_offset_t va, vm_size_t size)
1254 {
1255         vm_offset_t eva = round_line32(va + size);
1256
1257         va = trunc_line32(va);
1258
1259         while ((eva - va) >= (32 * 32)) {
1260                 cache_r4k_op_32lines_32(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB);
1261                 va += (32 * 32);
1262         }
1263
1264         while (va < eva) {
1265                 cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB);
1266                 va += 32;
1267         }
1268 }
1269
1270 void
1271 mipsNN_sdcache_wb_range_64(vm_offset_t va, vm_size_t size)
1272 {
1273         vm_offset_t eva = round_line64(va + size);
1274
1275         va = trunc_line64(va);
1276
1277         while ((eva - va) >= (32 * 64)) {
1278                 cache_r4k_op_32lines_64(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB);
1279                 va += (32 * 64);
1280         }
1281
1282         while (va < eva) {
1283                 cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB);
1284                 va += 64;
1285         }
1286 }
1287
1288 void
1289 mipsNN_sdcache_wbinv_all_128(void)
1290 {
1291         vm_offset_t va = MIPS_PHYS_TO_KSEG0(0);
1292         vm_offset_t eva = va + sdcache_size;
1293
1294         while (va < eva) {
1295                 cache_r4k_op_32lines_128(va,
1296                     CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
1297                 va += (32 * 128);
1298         }
1299 }
1300
1301 void
1302 mipsNN_sdcache_wbinv_range_128(vm_offset_t va, vm_size_t size)
1303 {
1304         vm_offset_t eva = round_line128(va + size);
1305
1306         va = trunc_line128(va);
1307
1308         while ((eva - va) >= (32 * 128)) {
1309                 cache_r4k_op_32lines_128(va,
1310                     CACHE_R4K_SD|CACHEOP_R4K_HIT_WB_INV);
1311                 va += (32 * 128);
1312         }
1313
1314         while (va < eva) {
1315                 cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB_INV);
1316                 va += 128;
1317         }
1318 }
1319
1320 void
1321 mipsNN_sdcache_wbinv_range_index_128(vm_offset_t va, vm_size_t size)
1322 {
1323         vm_offset_t eva;
1324
1325         /*
1326          * Since we're doing Index ops, we expect to not be able
1327          * to access the address we've been given.  So, get the
1328          * bits that determine the cache index, and make a KSEG0
1329          * address out of them.
1330          */
1331         va = MIPS_PHYS_TO_KSEG0(va & (sdcache_size - 1));
1332
1333         eva = round_line128(va + size);
1334         va = trunc_line128(va);
1335
1336         while ((eva - va) >= (32 * 128)) {
1337                 cache_r4k_op_32lines_128(va,
1338                     CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
1339                 va += (32 * 128);
1340         }
1341
1342         while (va < eva) {
1343                 cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
1344                 va += 128;
1345         }
1346 }
1347
1348 void
1349 mipsNN_sdcache_inv_range_128(vm_offset_t va, vm_size_t size)
1350 {
1351         vm_offset_t eva = round_line128(va + size);
1352
1353         va = trunc_line128(va);
1354
1355         while ((eva - va) >= (32 * 128)) {
1356                 cache_r4k_op_32lines_128(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_INV);
1357                 va += (32 * 128);
1358         }
1359
1360         while (va < eva) {
1361                 cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_INV);
1362                 va += 128;
1363         }
1364 }
1365
1366 void
1367 mipsNN_sdcache_wb_range_128(vm_offset_t va, vm_size_t size)
1368 {
1369         vm_offset_t eva = round_line128(va + size);
1370
1371         va = trunc_line128(va);
1372
1373         while ((eva - va) >= (32 * 128)) {
1374                 cache_r4k_op_32lines_128(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB);
1375                 va += (32 * 128);
1376         }
1377
1378         while (va < eva) {
1379                 cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB);
1380                 va += 128;
1381         }
1382 }