1 /* $NetBSD: cache_mipsNN.c,v 1.10 2005/12/24 20:07:19 perry Exp $ */
4 * Copyright 2001 Wasabi Systems, Inc.
7 * Written by Jason R. Thorpe and Simon Burge for Wasabi Systems, Inc.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
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
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.
38 #include <sys/cdefs.h>
39 __FBSDID("$FreeBSD$");
41 #include <sys/types.h>
42 #include <sys/systm.h>
43 #include <sys/param.h>
45 #include <machine/cache.h>
46 #include <machine/cache_r4k.h>
47 #include <machine/cpuinfo.h>
49 #define round_line16(x) (((x) + 15) & ~15)
50 #define trunc_line16(x) ((x) & ~15)
52 #define round_line32(x) (((x) + 31) & ~31)
53 #define trunc_line32(x) ((x) & ~31)
55 #define round_line64(x) (((x) + 63) & ~63)
56 #define trunc_line64(x) ((x) & ~63)
58 #define round_line128(x) (((x) + 127) & ~127)
59 #define trunc_line128(x) ((x) & ~127)
79 #if defined(SB1250_PASS1)
80 #define SYNC __asm volatile("sync; sync")
81 #elif defined(CPU_NLM)
82 #define SYNC xlp_sync()
84 #define SYNC __asm volatile("sync")
87 #if defined(CPU_CNMIPS)
88 #define SYNCI mips_sync_icache();
89 #elif defined(CPU_NLM)
90 #define SYNCI xlp_sync()
96 * Exported variables for consumers like bus_dma code
98 int mips_picache_linesize;
99 int mips_pdcache_linesize;
100 int mips_sdcache_linesize;
101 int mips_dcache_max_linesize;
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;
117 mipsNN_cache_init(struct mips_cpuinfo * cpuinfo)
119 int flush_multiple_lines_per_way;
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) {
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.
128 flush_multiple_lines_per_way = 0;
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;
136 picache_stride = cpuinfo->l1.ic_nsets * cpuinfo->l1.ic_linesize;
137 picache_loopcount = cpuinfo->l1.ic_nways;
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;
144 pdcache_stride = PAGE_SIZE;
145 pdcache_loopcount = (cpuinfo->l1.dc_nsets * cpuinfo->l1.dc_linesize / PAGE_SIZE) *
146 cpuinfo->l1.dc_nways;
149 mips_picache_linesize = cpuinfo->l1.ic_linesize;
150 mips_pdcache_linesize = cpuinfo->l1.dc_linesize;
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;
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;
162 mips_sdcache_linesize = cpuinfo->l2.dc_linesize;
163 mips_dcache_max_linesize = MAX(mips_pdcache_linesize,
164 mips_sdcache_linesize);
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);
180 mipsNN_icache_sync_all_16(void)
184 va = MIPS_PHYS_TO_KSEG0(0);
185 eva = va + picache_size;
188 * Since we're hitting the whole thing, we don't have to
189 * worry about the N different "ways".
192 mips_intern_dcache_wbinv_all();
195 cache_r4k_op_32lines_16(va, CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
203 mipsNN_icache_sync_all_32(void)
207 va = MIPS_PHYS_TO_KSEG0(0);
208 eva = va + picache_size;
211 * Since we're hitting the whole thing, we don't have to
212 * worry about the N different "ways".
215 mips_intern_dcache_wbinv_all();
218 cache_r4k_op_32lines_32(va, CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
226 mipsNN_icache_sync_all_64(void)
230 va = MIPS_PHYS_TO_KSEG0(0);
231 eva = va + picache_size;
234 * Since we're hitting the whole thing, we don't have to
235 * worry about the N different "ways".
238 mips_intern_dcache_wbinv_all();
241 cache_r4k_op_32lines_64(va, CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
249 mipsNN_icache_sync_range_16(vm_offset_t va, vm_size_t size)
253 eva = round_line16(va + size);
254 va = trunc_line16(va);
256 mips_intern_dcache_wb_range(va, (eva - va));
258 while ((eva - va) >= (32 * 16)) {
259 cache_r4k_op_32lines_16(va, CACHE_R4K_I|CACHEOP_R4K_HIT_INV);
264 cache_op_r4k_line(va, CACHE_R4K_I|CACHEOP_R4K_HIT_INV);
272 mipsNN_icache_sync_range_32(vm_offset_t va, vm_size_t size)
276 eva = round_line32(va + size);
277 va = trunc_line32(va);
279 mips_intern_dcache_wb_range(va, (eva - va));
281 while ((eva - va) >= (32 * 32)) {
282 cache_r4k_op_32lines_32(va, CACHE_R4K_I|CACHEOP_R4K_HIT_INV);
287 cache_op_r4k_line(va, CACHE_R4K_I|CACHEOP_R4K_HIT_INV);
295 mipsNN_icache_sync_range_64(vm_offset_t va, vm_size_t size)
299 eva = round_line64(va + size);
300 va = trunc_line64(va);
302 mips_intern_dcache_wb_range(va, (eva - va));
304 while ((eva - va) >= (32 * 64)) {
305 cache_r4k_op_32lines_64(va, CACHE_R4K_I|CACHEOP_R4K_HIT_INV);
310 cache_op_r4k_line(va, CACHE_R4K_I|CACHEOP_R4K_HIT_INV);
318 mipsNN_icache_sync_range_index_16(vm_offset_t va, vm_size_t size)
320 vm_offset_t eva, tmpva;
321 int i, stride, loopcount;
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.
329 va = MIPS_PHYS_TO_KSEG0(va & picache_way_mask);
331 eva = round_line16(va + size);
332 va = trunc_line16(va);
335 * GCC generates better code in the loops if we reference local
336 * copies of these global variables.
338 stride = picache_stride;
339 loopcount = picache_loopcount;
341 mips_intern_dcache_wbinv_range_index(va, (eva - va));
343 while ((eva - va) >= (8 * 16)) {
345 for (i = 0; i < loopcount; i++, tmpva += stride)
346 cache_r4k_op_8lines_16(tmpva,
347 CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
353 for (i = 0; i < loopcount; i++, tmpva += stride)
354 cache_op_r4k_line(tmpva,
355 CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
361 mipsNN_icache_sync_range_index_32(vm_offset_t va, vm_size_t size)
363 vm_offset_t eva, tmpva;
364 int i, stride, loopcount;
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.
372 va = MIPS_PHYS_TO_KSEG0(va & picache_way_mask);
374 eva = round_line32(va + size);
375 va = trunc_line32(va);
378 * GCC generates better code in the loops if we reference local
379 * copies of these global variables.
381 stride = picache_stride;
382 loopcount = picache_loopcount;
384 mips_intern_dcache_wbinv_range_index(va, (eva - va));
386 while ((eva - va) >= (8 * 32)) {
388 for (i = 0; i < loopcount; i++, tmpva += stride)
389 cache_r4k_op_8lines_32(tmpva,
390 CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
396 for (i = 0; i < loopcount; i++, tmpva += stride)
397 cache_op_r4k_line(tmpva,
398 CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
404 mipsNN_icache_sync_range_index_64(vm_offset_t va, vm_size_t size)
406 vm_offset_t eva, tmpva;
407 int i, stride, loopcount;
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.
415 va = MIPS_PHYS_TO_KSEG0(va & picache_way_mask);
417 eva = round_line64(va + size);
418 va = trunc_line64(va);
421 * GCC generates better code in the loops if we reference local
422 * copies of these global variables.
424 stride = picache_stride;
425 loopcount = picache_loopcount;
427 mips_intern_dcache_wbinv_range_index(va, (eva - va));
429 while ((eva - va) >= (8 * 64)) {
431 for (i = 0; i < loopcount; i++, tmpva += stride)
432 cache_r4k_op_8lines_64(tmpva,
433 CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
439 for (i = 0; i < loopcount; i++, tmpva += stride)
440 cache_op_r4k_line(tmpva,
441 CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
447 mipsNN_pdcache_wbinv_all_16(void)
451 va = MIPS_PHYS_TO_KSEG0(0);
452 eva = va + pdcache_size;
455 * Since we're hitting the whole thing, we don't have to
456 * worry about the N different "ways".
460 cache_r4k_op_32lines_16(va,
461 CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
469 mipsNN_pdcache_wbinv_all_32(void)
473 va = MIPS_PHYS_TO_KSEG0(0);
474 eva = va + pdcache_size;
477 * Since we're hitting the whole thing, we don't have to
478 * worry about the N different "ways".
482 cache_r4k_op_32lines_32(va,
483 CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
491 mipsNN_pdcache_wbinv_all_64(void)
495 va = MIPS_PHYS_TO_KSEG0(0);
496 eva = va + pdcache_size;
499 * Since we're hitting the whole thing, we don't have to
500 * worry about the N different "ways".
504 cache_r4k_op_32lines_64(va,
505 CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
513 mipsNN_pdcache_wbinv_range_16(vm_offset_t va, vm_size_t size)
517 eva = round_line16(va + size);
518 va = trunc_line16(va);
520 while ((eva - va) >= (32 * 16)) {
521 cache_r4k_op_32lines_16(va,
522 CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV);
527 cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV);
535 mipsNN_pdcache_wbinv_range_32(vm_offset_t va, vm_size_t size)
539 eva = round_line32(va + size);
540 va = trunc_line32(va);
542 while ((eva - va) >= (32 * 32)) {
543 cache_r4k_op_32lines_32(va,
544 CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV);
549 cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV);
557 mipsNN_pdcache_wbinv_range_64(vm_offset_t va, vm_size_t size)
561 eva = round_line64(va + size);
562 va = trunc_line64(va);
564 while ((eva - va) >= (32 * 64)) {
565 cache_r4k_op_32lines_64(va,
566 CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV);
571 cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV);
579 mipsNN_pdcache_wbinv_range_index_16(vm_offset_t va, vm_size_t size)
581 vm_offset_t eva, tmpva;
582 int i, stride, loopcount;
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.
590 va = MIPS_PHYS_TO_KSEG0(va & pdcache_way_mask);
592 eva = round_line16(va + size);
593 va = trunc_line16(va);
596 * GCC generates better code in the loops if we reference local
597 * copies of these global variables.
599 stride = pdcache_stride;
600 loopcount = pdcache_loopcount;
602 while ((eva - va) >= (8 * 16)) {
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);
612 for (i = 0; i < loopcount; i++, tmpva += stride)
613 cache_op_r4k_line(tmpva,
614 CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
620 mipsNN_pdcache_wbinv_range_index_32(vm_offset_t va, vm_size_t size)
622 vm_offset_t eva, tmpva;
623 int i, stride, loopcount;
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.
631 va = MIPS_PHYS_TO_KSEG0(va & pdcache_way_mask);
633 eva = round_line32(va + size);
634 va = trunc_line32(va);
637 * GCC generates better code in the loops if we reference local
638 * copies of these global variables.
640 stride = pdcache_stride;
641 loopcount = pdcache_loopcount;
643 while ((eva - va) >= (8 * 32)) {
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);
653 for (i = 0; i < loopcount; i++, tmpva += stride)
654 cache_op_r4k_line(tmpva,
655 CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
661 mipsNN_pdcache_wbinv_range_index_64(vm_offset_t va, vm_size_t size)
663 vm_offset_t eva, tmpva;
664 int i, stride, loopcount;
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.
672 va = MIPS_PHYS_TO_KSEG0(va & pdcache_way_mask);
674 eva = round_line64(va + size);
675 va = trunc_line64(va);
678 * GCC generates better code in the loops if we reference local
679 * copies of these global variables.
681 stride = pdcache_stride;
682 loopcount = pdcache_loopcount;
684 while ((eva - va) >= (8 * 64)) {
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);
694 for (i = 0; i < loopcount; i++, tmpva += stride)
695 cache_op_r4k_line(tmpva,
696 CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
702 mipsNN_pdcache_inv_range_16(vm_offset_t va, vm_size_t size)
706 eva = round_line16(va + size);
707 va = trunc_line16(va);
709 while ((eva - va) >= (32 * 16)) {
710 cache_r4k_op_32lines_16(va, CACHE_R4K_D|CACHEOP_R4K_HIT_INV);
715 cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_INV);
723 mipsNN_pdcache_inv_range_32(vm_offset_t va, vm_size_t size)
727 eva = round_line32(va + size);
728 va = trunc_line32(va);
730 while ((eva - va) >= (32 * 32)) {
731 cache_r4k_op_32lines_32(va, CACHE_R4K_D|CACHEOP_R4K_HIT_INV);
736 cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_INV);
744 mipsNN_pdcache_inv_range_64(vm_offset_t va, vm_size_t size)
748 eva = round_line64(va + size);
749 va = trunc_line64(va);
751 while ((eva - va) >= (32 * 64)) {
752 cache_r4k_op_32lines_64(va, CACHE_R4K_D|CACHEOP_R4K_HIT_INV);
757 cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_INV);
765 mipsNN_pdcache_wb_range_16(vm_offset_t va, vm_size_t size)
769 eva = round_line16(va + size);
770 va = trunc_line16(va);
772 while ((eva - va) >= (32 * 16)) {
773 cache_r4k_op_32lines_16(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB);
778 cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB);
786 mipsNN_pdcache_wb_range_32(vm_offset_t va, vm_size_t size)
790 eva = round_line32(va + size);
791 va = trunc_line32(va);
793 while ((eva - va) >= (32 * 32)) {
794 cache_r4k_op_32lines_32(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB);
799 cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB);
807 mipsNN_pdcache_wb_range_64(vm_offset_t va, vm_size_t size)
811 eva = round_line64(va + size);
812 va = trunc_line64(va);
814 while ((eva - va) >= (32 * 64)) {
815 cache_r4k_op_32lines_64(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB);
820 cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB);
830 mipsNN_icache_sync_all_128(void)
836 mipsNN_icache_sync_range_128(vm_offset_t va, vm_size_t size)
842 mipsNN_icache_sync_range_index_128(vm_offset_t va, vm_size_t size)
848 mipsNN_pdcache_wbinv_all_128(void)
854 mipsNN_pdcache_wbinv_range_128(vm_offset_t va, vm_size_t size)
860 mipsNN_pdcache_wbinv_range_index_128(vm_offset_t va, vm_size_t size)
865 mipsNN_pdcache_inv_range_128(vm_offset_t va, vm_size_t size)
870 mipsNN_pdcache_wb_range_128(vm_offset_t va, vm_size_t size)
878 mipsNN_icache_sync_all_128(void)
882 va = MIPS_PHYS_TO_KSEG0(0);
883 eva = va + picache_size;
886 * Since we're hitting the whole thing, we don't have to
887 * worry about the N different "ways".
890 mips_intern_dcache_wbinv_all();
893 cache_r4k_op_32lines_128(va, CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
901 mipsNN_icache_sync_range_128(vm_offset_t va, vm_size_t size)
905 eva = round_line128(va + size);
906 va = trunc_line128(va);
908 mips_intern_dcache_wb_range(va, (eva - va));
910 while ((eva - va) >= (32 * 128)) {
911 cache_r4k_op_32lines_128(va, CACHE_R4K_I|CACHEOP_R4K_HIT_INV);
916 cache_op_r4k_line(va, CACHE_R4K_I|CACHEOP_R4K_HIT_INV);
924 mipsNN_icache_sync_range_index_128(vm_offset_t va, vm_size_t size)
926 vm_offset_t eva, tmpva;
927 int i, stride, loopcount;
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.
935 va = MIPS_PHYS_TO_KSEG0(va & picache_way_mask);
937 eva = round_line128(va + size);
938 va = trunc_line128(va);
941 * GCC generates better code in the loops if we reference local
942 * copies of these global variables.
944 stride = picache_stride;
945 loopcount = picache_loopcount;
947 mips_intern_dcache_wbinv_range_index(va, (eva - va));
949 while ((eva - va) >= (32 * 128)) {
951 for (i = 0; i < loopcount; i++, tmpva += stride)
952 cache_r4k_op_32lines_128(tmpva,
953 CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
959 for (i = 0; i < loopcount; i++, tmpva += stride)
960 cache_op_r4k_line(tmpva,
961 CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
967 mipsNN_pdcache_wbinv_all_128(void)
971 va = MIPS_PHYS_TO_KSEG0(0);
972 eva = va + pdcache_size;
975 * Since we're hitting the whole thing, we don't have to
976 * worry about the N different "ways".
980 cache_r4k_op_32lines_128(va,
981 CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
990 mipsNN_pdcache_wbinv_range_128(vm_offset_t va, vm_size_t size)
994 eva = round_line128(va + size);
995 va = trunc_line128(va);
997 while ((eva - va) >= (32 * 128)) {
998 cache_r4k_op_32lines_128(va,
999 CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV);
1004 cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV);
1012 mipsNN_pdcache_wbinv_range_index_128(vm_offset_t va, vm_size_t size)
1014 vm_offset_t eva, tmpva;
1015 int i, stride, loopcount;
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.
1023 va = MIPS_PHYS_TO_KSEG0(va & pdcache_way_mask);
1025 eva = round_line128(va + size);
1026 va = trunc_line128(va);
1029 * GCC generates better code in the loops if we reference local
1030 * copies of these global variables.
1032 stride = pdcache_stride;
1033 loopcount = pdcache_loopcount;
1035 while ((eva - va) >= (32 * 128)) {
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);
1045 for (i = 0; i < loopcount; i++, tmpva += stride)
1046 cache_op_r4k_line(tmpva,
1047 CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
1053 mipsNN_pdcache_inv_range_128(vm_offset_t va, vm_size_t size)
1057 eva = round_line128(va + size);
1058 va = trunc_line128(va);
1060 while ((eva - va) >= (32 * 128)) {
1061 cache_r4k_op_32lines_128(va, CACHE_R4K_D|CACHEOP_R4K_HIT_INV);
1066 cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_INV);
1074 mipsNN_pdcache_wb_range_128(vm_offset_t va, vm_size_t size)
1078 eva = round_line128(va + size);
1079 va = trunc_line128(va);
1081 while ((eva - va) >= (32 * 128)) {
1082 cache_r4k_op_32lines_128(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB);
1087 cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB);
1097 mipsNN_sdcache_wbinv_all_32(void)
1099 vm_offset_t va = MIPS_PHYS_TO_KSEG0(0);
1100 vm_offset_t eva = va + sdcache_size;
1103 cache_r4k_op_32lines_32(va,
1104 CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
1110 mipsNN_sdcache_wbinv_all_64(void)
1112 vm_offset_t va = MIPS_PHYS_TO_KSEG0(0);
1113 vm_offset_t eva = va + sdcache_size;
1116 cache_r4k_op_32lines_64(va,
1117 CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
1123 mipsNN_sdcache_wbinv_range_32(vm_offset_t va, vm_size_t size)
1125 vm_offset_t eva = round_line32(va + size);
1127 va = trunc_line32(va);
1129 while ((eva - va) >= (32 * 32)) {
1130 cache_r4k_op_32lines_32(va,
1131 CACHE_R4K_SD|CACHEOP_R4K_HIT_WB_INV);
1136 cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB_INV);
1142 mipsNN_sdcache_wbinv_range_64(vm_offset_t va, vm_size_t size)
1144 vm_offset_t eva = round_line64(va + size);
1146 va = trunc_line64(va);
1148 while ((eva - va) >= (32 * 64)) {
1149 cache_r4k_op_32lines_64(va,
1150 CACHE_R4K_SD|CACHEOP_R4K_HIT_WB_INV);
1155 cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB_INV);
1161 mipsNN_sdcache_wbinv_range_index_32(vm_offset_t va, vm_size_t size)
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.
1171 va = MIPS_PHYS_TO_KSEG0(va & (sdcache_size - 1));
1173 eva = round_line32(va + size);
1174 va = trunc_line32(va);
1176 while ((eva - va) >= (32 * 32)) {
1177 cache_r4k_op_32lines_32(va,
1178 CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
1183 cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
1189 mipsNN_sdcache_wbinv_range_index_64(vm_offset_t va, vm_size_t size)
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.
1199 va = MIPS_PHYS_TO_KSEG0(va & (sdcache_size - 1));
1201 eva = round_line64(va + size);
1202 va = trunc_line64(va);
1204 while ((eva - va) >= (32 * 64)) {
1205 cache_r4k_op_32lines_64(va,
1206 CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
1211 cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
1217 mipsNN_sdcache_inv_range_32(vm_offset_t va, vm_size_t size)
1219 vm_offset_t eva = round_line32(va + size);
1221 va = trunc_line32(va);
1223 while ((eva - va) >= (32 * 32)) {
1224 cache_r4k_op_32lines_32(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_INV);
1229 cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_INV);
1235 mipsNN_sdcache_inv_range_64(vm_offset_t va, vm_size_t size)
1237 vm_offset_t eva = round_line64(va + size);
1239 va = trunc_line64(va);
1241 while ((eva - va) >= (32 * 64)) {
1242 cache_r4k_op_32lines_64(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_INV);
1247 cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_INV);
1253 mipsNN_sdcache_wb_range_32(vm_offset_t va, vm_size_t size)
1255 vm_offset_t eva = round_line32(va + size);
1257 va = trunc_line32(va);
1259 while ((eva - va) >= (32 * 32)) {
1260 cache_r4k_op_32lines_32(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB);
1265 cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB);
1271 mipsNN_sdcache_wb_range_64(vm_offset_t va, vm_size_t size)
1273 vm_offset_t eva = round_line64(va + size);
1275 va = trunc_line64(va);
1277 while ((eva - va) >= (32 * 64)) {
1278 cache_r4k_op_32lines_64(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB);
1283 cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB);
1289 mipsNN_sdcache_wbinv_all_128(void)
1291 vm_offset_t va = MIPS_PHYS_TO_KSEG0(0);
1292 vm_offset_t eva = va + sdcache_size;
1295 cache_r4k_op_32lines_128(va,
1296 CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
1302 mipsNN_sdcache_wbinv_range_128(vm_offset_t va, vm_size_t size)
1304 vm_offset_t eva = round_line128(va + size);
1306 va = trunc_line128(va);
1308 while ((eva - va) >= (32 * 128)) {
1309 cache_r4k_op_32lines_128(va,
1310 CACHE_R4K_SD|CACHEOP_R4K_HIT_WB_INV);
1315 cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB_INV);
1321 mipsNN_sdcache_wbinv_range_index_128(vm_offset_t va, vm_size_t size)
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.
1331 va = MIPS_PHYS_TO_KSEG0(va & (sdcache_size - 1));
1333 eva = round_line128(va + size);
1334 va = trunc_line128(va);
1336 while ((eva - va) >= (32 * 128)) {
1337 cache_r4k_op_32lines_128(va,
1338 CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
1343 cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
1349 mipsNN_sdcache_inv_range_128(vm_offset_t va, vm_size_t size)
1351 vm_offset_t eva = round_line128(va + size);
1353 va = trunc_line128(va);
1355 while ((eva - va) >= (32 * 128)) {
1356 cache_r4k_op_32lines_128(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_INV);
1361 cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_INV);
1367 mipsNN_sdcache_wb_range_128(vm_offset_t va, vm_size_t size)
1369 vm_offset_t eva = round_line128(va + size);
1371 va = trunc_line128(va);
1373 while ((eva - va) >= (32 * 128)) {
1374 cache_r4k_op_32lines_128(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB);
1379 cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB);