1 /* $NetBSD: cache_tx39.c,v 1.2 2001/11/14 18:26:23 thorpej Exp $ */ 2 3 /* 4 * Copyright 2001 Wasabi Systems, Inc. 5 * All rights reserved. 6 * 7 * Written by Jason R. Thorpe for Wasabi Systems, Inc. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed for the NetBSD Project by 20 * Wasabi Systems, Inc. 21 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 22 * or promote products derived from this software without specific prior 23 * written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 * POSSIBILITY OF SUCH DAMAGE. 36 */ 37 38 #include <sys/param.h> 39 40 #include <mips/cache.h> 41 #include <mips/cache_tx39.h> 42 #include <mips/locore.h> 43 44 /* 45 * Cache operations for TX3900/TX3920-style caches: 46 * 47 * - I-cache direct-mapped (TX3900) or 2-way set-associative (TX3920) 48 * - D-cache 2-way set-associative 49 * - Write-through (TX3900, TX3920) or write-back (TX3920) 50 * - Physically indexed, phyiscally tagged 51 * 52 * XXX THIS IS NOT YET COMPLETE. 53 */ 54 55 #define round_line(x) (((x) + 15) & ~15) 56 #define trunc_line(x) ((x) & ~15) 57 58 void 59 tx3900_icache_sync_all_16(void) 60 { 61 62 tx3900_icache_do_inv_index_16(MIPS_PHYS_TO_KSEG0(0), 63 MIPS_PHYS_TO_KSEG0(mips_picache_size)); 64 } 65 66 void 67 tx3900_icache_sync_range_16(vaddr_t va, vsize_t size) 68 { 69 vaddr_t eva = round_line(va + size); 70 71 va = trunc_line(va); 72 73 if ((eva - va) >= mips_picache_size) { 74 /* Just hit the whole thing. */ 75 va = MIPS_PHYS_TO_KSEG0(0); 76 eva = MIPS_PHYS_TO_KSEG0(mips_picache_size); 77 } 78 79 tx3900_icache_do_inv_index_16(va, eva); 80 } 81 82 #undef round_line 83 #undef trunc_line 84 85 #define round_line(x) (((x) + 3) & ~3) 86 #define trunc_line(x) ((x) & ~3) 87 88 static int tx3900_dummy_buffer[R3900_C_SIZE_MAX / sizeof(int)]; 89 90 void 91 tx3900_pdcache_wbinv_all_4(void) 92 { 93 vaddr_t va = MIPS_PHYS_TO_KSEG0(0); 94 vaddr_t eva = va + mips_pdcache_size; 95 __volatile int *p; 96 97 /* 98 * No Index Invalidate for the TX3900 -- have to execute a 99 * series of load instructions from the dummy buffer, instead. 100 */ 101 102 p = tx3900_dummy_buffer; 103 while (va < eva) { 104 (void) *p++; (void) *p++; (void) *p++; (void) *p++; 105 (void) *p++; (void) *p++; (void) *p++; (void) *p++; 106 (void) *p++; (void) *p++; (void) *p++; (void) *p++; 107 (void) *p++; (void) *p++; (void) *p++; (void) *p++; 108 (void) *p++; (void) *p++; (void) *p++; (void) *p++; 109 (void) *p++; (void) *p++; (void) *p++; (void) *p++; 110 (void) *p++; (void) *p++; (void) *p++; (void) *p++; 111 (void) *p++; (void) *p++; (void) *p++; (void) *p++; 112 va += (32 * 4); 113 } 114 } 115 116 void 117 tx3900_pdcache_inv_range_4(vaddr_t va, vsize_t size) 118 { 119 vaddr_t eva = round_line(va + size); 120 121 va = trunc_line(va); 122 123 while ((eva - va) >= (32 * 4)) { 124 cache_tx39_op_32lines_4(va, 125 CACHE_TX39_D|CACHEOP_TX3900_HIT_INV); 126 va += (32 * 4); 127 }; 128 129 while (va < eva) { 130 cache_op_tx39_line(va, CACHE_TX39_D|CACHEOP_TX3900_HIT_INV); 131 va += 4; 132 } 133 } 134 135 void 136 tx3900_pdcache_wb_range_4(vaddr_t va, vsize_t size) 137 { 138 139 /* Cache is write-through. */ 140 } 141 142 #undef round_line 143 #undef trunc_line 144 145 #define round_line(x) (((x) + 15) & ~15) 146 #define trunc_line(x) ((x) & ~15) 147 148 void 149 tx3920_icache_sync_all_16wb(void) 150 { 151 152 mips_dcache_wbinv_all(); 153 154 __asm __volatile("sync"); 155 156 tx3920_icache_do_inv_16(MIPS_PHYS_TO_KSEG0(0), 157 MIPS_PHYS_TO_KSEG0(mips_picache_size)); 158 } 159 160 void 161 tx3920_icache_sync_range_16wt(vaddr_t va, vsize_t size) 162 { 163 vaddr_t eva = round_line(va + size); 164 165 va = trunc_line(va); 166 167 tx3920_icache_do_inv_16(va, eva); 168 } 169 170 void 171 tx3920_icache_sync_range_16wb(vaddr_t va, vsize_t size) 172 { 173 vaddr_t eva = round_line(va + size); 174 175 va = trunc_line(va); 176 177 mips_dcache_wb_range(va, (eva - va)); 178 179 __asm __volatile("sync"); 180 181 tx3920_icache_do_inv_16(va, eva); 182 } 183 184 void 185 tx3920_pdcache_wbinv_all_16wt(void) 186 { 187 vaddr_t va = MIPS_PHYS_TO_KSEG0(0); 188 vaddr_t eva = va + mips_pdcache_size; 189 190 /* 191 * Since we're hitting the whole thing, we don't have to 192 * worry about the 2 different "ways". 193 */ 194 195 while (va < eva) { 196 cache_tx39_op_32lines_16(va, 197 CACHE_TX39_D|CACHEOP_TX3920_INDEX_INV); 198 va += (32 * 16); 199 } 200 } 201 202 void 203 tx3920_pdcache_wbinv_all_16wb(void) 204 { 205 vaddr_t va = MIPS_PHYS_TO_KSEG0(0); 206 vaddr_t eva = va + mips_pdcache_size; 207 208 /* 209 * Since we're hitting the whole thing, we don't have to 210 * worry about the 2 different "ways". 211 */ 212 213 while (va < eva) { 214 cache_tx39_op_32lines_16(va, 215 CACHE_TX39_D|CACHEOP_TX3920_INDEX_WB_INV); 216 va += (32 * 16); 217 } 218 } 219 220 void 221 tx3920_pdcache_wbinv_range_16wb(vaddr_t va, vsize_t size) 222 { 223 vaddr_t eva = round_line(va + size); 224 225 va = trunc_line(va); 226 227 while ((eva - va) >= (32 * 16)) { 228 cache_tx39_op_32lines_16(va, 229 CACHE_TX39_D|CACHEOP_TX3920_HIT_WB_INV); 230 va += (32 * 16); 231 } 232 233 while (va < eva) { 234 cache_op_tx39_line(va, CACHE_TX39_D|CACHEOP_TX3920_HIT_WB_INV); 235 va += 16; 236 } 237 } 238 239 void 240 tx3920_pdcache_inv_range_16(vaddr_t va, vsize_t size) 241 { 242 vaddr_t eva = round_line(va + size); 243 244 va = trunc_line(va); 245 246 while ((eva - va) >= (32 * 16)) { 247 cache_tx39_op_32lines_16(va, 248 CACHE_TX39_D|CACHEOP_TX3920_HIT_INV); 249 va += (32 * 16); 250 } 251 252 while (va < eva) { 253 cache_op_tx39_line(va, CACHE_TX39_D|CACHEOP_TX3920_HIT_INV); 254 va += 16; 255 } 256 } 257 258 void 259 tx3920_pdcache_wb_range_16wt(vaddr_t va, vsize_t size) 260 { 261 262 /* Cache is write-through. */ 263 } 264 265 void 266 tx3920_pdcache_wb_range_16wb(vaddr_t va, vsize_t size) 267 { 268 vaddr_t eva = round_line(va + size); 269 270 va = trunc_line(va); 271 272 while ((eva - va) >= (32 * 16)) { 273 cache_tx39_op_32lines_16(va, 274 CACHE_TX39_D|CACHEOP_TX3920_HIT_WB); 275 va += (32 * 16); 276 } 277 278 while (va < eva) { 279 cache_op_tx39_line(va, CACHE_TX39_D|CACHEOP_TX3920_HIT_WB); 280 va += 16; 281 } 282 } 283