Home | History | Annotate | Line # | Download | only in mips
cache_r10k.c revision 1.2
      1 /*	$NetBSD: cache_r10k.c,v 1.2 2003/11/01 04:42:56 shin Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2003 Takao Shinohara.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     25  */
     26 
     27 /*
     28  * Copyright 2001 Wasabi Systems, Inc.
     29  * All rights reserved.
     30  *
     31  * Written by Jason R. Thorpe for Wasabi Systems, Inc.
     32  *
     33  * Redistribution and use in source and binary forms, with or without
     34  * modification, are permitted provided that the following conditions
     35  * are met:
     36  * 1. Redistributions of source code must retain the above copyright
     37  *    notice, this list of conditions and the following disclaimer.
     38  * 2. Redistributions in binary form must reproduce the above copyright
     39  *    notice, this list of conditions and the following disclaimer in the
     40  *    documentation and/or other materials provided with the distribution.
     41  * 3. All advertising materials mentioning features or use of this software
     42  *    must display the following acknowledgement:
     43  *	This product includes software developed for the NetBSD Project by
     44  *	Wasabi Systems, Inc.
     45  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
     46  *    or promote products derived from this software without specific prior
     47  *    written permission.
     48  *
     49  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
     50  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     51  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     52  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
     53  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     54  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     55  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     56  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     57  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     58  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     59  * POSSIBILITY OF SUCH DAMAGE.
     60  */
     61 
     62 #include <sys/param.h>
     63 
     64 #include <mips/cache.h>
     65 #include <mips/cache_r4k.h>
     66 #include <mips/cache_r10k.h>
     67 
     68 /*
     69  * Cache operations for R10000-style caches:
     70  *
     71  *	2-way, write-back
     72  *	primary cache: virtual index/physical tag
     73  *	secondary cache: physical index/physical tag
     74  */
     75 
     76 __asm(".set mips3");
     77 
     78 #define	round_line(x)	(((x) + 64 - 1) & ~(64 - 1))
     79 #define	trunc_line(x)	((x) & ~(64 - 1))
     80 
     81 void
     82 r10k_icache_sync_all(void)
     83 {
     84 	vaddr_t va = MIPS_PHYS_TO_KSEG0(0);
     85 	vaddr_t eva = va + mips_picache_way_size;
     86 
     87 	mips_dcache_wbinv_all();
     88 
     89 	__asm __volatile("sync");
     90 
     91 	while (va < eva) {
     92 		cache_op_r4k_line(va+0, CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
     93 		cache_op_r4k_line(va+1, CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
     94 		va += 64;
     95 	}
     96 }
     97 
     98 void
     99 r10k_icache_sync_range(vaddr_t va, vsize_t size)
    100 {
    101 	vaddr_t eva = round_line(va + size);
    102 
    103 	va = trunc_line(va);
    104 
    105 	mips_dcache_wb_range(va, (eva - va));
    106 
    107 	__asm __volatile("sync");
    108 
    109 	while (va < eva) {
    110 		cache_op_r4k_line(va, CACHE_R4K_I|CACHEOP_R4K_HIT_INV);
    111 		va += 64;
    112 	}
    113 }
    114 
    115 void
    116 r10k_icache_sync_range_index(vaddr_t va, vsize_t size)
    117 {
    118 	vaddr_t eva, orig_va;
    119 
    120 	orig_va = va;
    121 
    122 	eva = round_line(va + size);
    123 	va = trunc_line(va);
    124 
    125 	mips_dcache_wbinv_range_index(va, (eva - va));
    126 
    127 	__asm __volatile("sync");
    128 
    129 	/*
    130 	 * Since we're doing Index ops, we expect to not be able
    131 	 * to access the address we've been given.  So, get the
    132 	 * bits that determine the cache index, and make a KSEG0
    133 	 * address out of them.
    134 	 */
    135 	va = MIPS_PHYS_TO_KSEG0(orig_va & mips_picache_way_mask);
    136 
    137 	eva = round_line(va + size);
    138 	va = trunc_line(va);
    139 
    140 	while (va < eva) {
    141 		cache_op_r4k_line(va+0, CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
    142 		cache_op_r4k_line(va+1, CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
    143 		va += 64;
    144 	}
    145 }
    146 
    147 #undef round_line
    148 #undef trunc_line
    149 
    150 #define	round_line(x)	(((x) + 32 - 1) & ~(32 - 1))
    151 #define	trunc_line(x)	((x) & ~(32 - 1))
    152 
    153 void
    154 r10k_pdcache_wbinv_all(void)
    155 {
    156 	vaddr_t va = MIPS_PHYS_TO_KSEG0(0);
    157 	vaddr_t eva = va + mips_pdcache_way_size;
    158 
    159 	while (va < eva) {
    160 		cache_op_r4k_line(va+0, CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
    161 		cache_op_r4k_line(va+1, CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
    162 		va += 32;
    163 	}
    164 }
    165 
    166 void
    167 r10k_pdcache_wbinv_range(vaddr_t va, vsize_t size)
    168 {
    169 	vaddr_t eva = round_line(va + size);
    170 
    171 	va = trunc_line(va);
    172 
    173 	while (va < eva) {
    174 		cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV);
    175 		va += 32;
    176 	}
    177 }
    178 
    179 void
    180 r10k_pdcache_wbinv_range_index(vaddr_t va, vsize_t size)
    181 {
    182 	vaddr_t eva;
    183 
    184 	/*
    185 	 * Since we're doing Index ops, we expect to not be able
    186 	 * to access the address we've been given.  So, get the
    187 	 * bits that determine the cache index, and make a KSEG0
    188 	 * address out of them.
    189 	 */
    190 	va = MIPS_PHYS_TO_KSEG0(va & mips_pdcache_way_mask);
    191 
    192 	eva = round_line(va + size);
    193 	va = trunc_line(va);
    194 
    195 	while (va < eva) {
    196 		cache_op_r4k_line(va+0, CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
    197 		cache_op_r4k_line(va+1, CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
    198 		va += 32;
    199 	}
    200 }
    201 
    202 void
    203 r10k_pdcache_inv_range(vaddr_t va, vsize_t size)
    204 {
    205 	vaddr_t eva = round_line(va + size);
    206 
    207 	va = trunc_line(va);
    208 
    209 	while (va < eva) {
    210 		cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_INV);
    211 		va += 32;
    212 	}
    213 }
    214 
    215 void
    216 r10k_pdcache_wb_range(vaddr_t va, vsize_t size)
    217 {
    218 	vaddr_t eva = round_line(va + size);
    219 
    220 	va = trunc_line(va);
    221 
    222 	while (va < eva) {
    223 		/* R10000 does not support HitWriteBack operation */
    224 		cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV);
    225 		va += 32;
    226 	}
    227 }
    228 
    229 #undef round_line
    230 #undef trunc_line
    231 
    232 #define	round_line(x)	(((x) + mips_sdcache_line_size - 1) & ~(mips_sdcache_line_size - 1))
    233 #define	trunc_line(x)	((x) & ~(mips_sdcache_line_size - 1))
    234 
    235 void
    236 r10k_sdcache_wbinv_all(void)
    237 {
    238 	vaddr_t va = MIPS_PHYS_TO_KSEG0(0);
    239 	vaddr_t eva = va + mips_sdcache_way_size;
    240 	int line_size = mips_sdcache_line_size;
    241 
    242 	while (va < eva) {
    243 		cache_op_r4k_line(va+0, CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
    244 		cache_op_r4k_line(va+1, CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
    245 		va += line_size;
    246 	}
    247 }
    248 
    249 void
    250 r10k_sdcache_wbinv_range(vaddr_t va, vsize_t size)
    251 {
    252 	vaddr_t eva = round_line(va + size);
    253 	int line_size = mips_sdcache_line_size;
    254 
    255 	va = trunc_line(va);
    256 
    257 	while (va < eva) {
    258 		cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB_INV);
    259 		va += line_size;
    260 	}
    261 }
    262 
    263 void
    264 r10k_sdcache_wbinv_range_index(vaddr_t va, vsize_t size)
    265 {
    266 	vaddr_t eva;
    267 	int line_size = mips_sdcache_line_size;
    268 
    269 	/*
    270 	 * Since we're doing Index ops, we expect to not be able
    271 	 * to access the address we've been given.  So, get the
    272 	 * bits that determine the cache index, and make a KSEG0
    273 	 * address out of them.
    274 	 */
    275 	va = MIPS_PHYS_TO_KSEG0(va & mips_sdcache_way_mask);
    276 
    277 	eva = round_line(va + size);
    278 	va = trunc_line(va);
    279 
    280 	while (va < eva) {
    281 		cache_op_r4k_line(va+0, CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
    282 		cache_op_r4k_line(va+1, CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV);
    283 		va += line_size;
    284 	}
    285 }
    286 
    287 void
    288 r10k_sdcache_inv_range(vaddr_t va, vsize_t size)
    289 {
    290 	vaddr_t eva = round_line(va + size);
    291 	int line_size = mips_sdcache_line_size;
    292 
    293 	va = trunc_line(va);
    294 
    295 	while (va < eva) {
    296 		cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_INV);
    297 		va += line_size;
    298 	}
    299 }
    300 
    301 void
    302 r10k_sdcache_wb_range(vaddr_t va, vsize_t size)
    303 {
    304 	vaddr_t eva = round_line(va + size);
    305 	int line_size = mips_sdcache_line_size;
    306 
    307 	va = trunc_line(va);
    308 
    309 	while (va < eva) {
    310 		/* R10000 does not support HitWriteBack operation */
    311 		cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB_INV);
    312 		va += line_size;
    313 	}
    314 }
    315 
    316 #undef round_line
    317 #undef trunc_line
    318