1 /* $NetBSD: cache_tx39.c,v 1.9 2021/11/06 06:49:02 msaitoh 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/cdefs.h> 39 __KERNEL_RCSID(0, "$NetBSD: cache_tx39.c,v 1.9 2021/11/06 06:49:02 msaitoh Exp $"); 40 41 #include <sys/param.h> 42 43 #include <mips/cache.h> 44 #include <mips/cache_tx39.h> 45 #include <mips/locore.h> 46 47 /* 48 * Cache operations for TX3900/TX3920-style caches: 49 * 50 * - I-cache direct-mapped (TX3900) or 2-way set-associative (TX3920) 51 * - D-cache 2-way set-associative 52 * - Write-through (TX3900, TX3920) or write-back (TX3920) 53 * - Physically indexed, physically tagged 54 * 55 * XXX THIS IS NOT YET COMPLETE. 56 */ 57 58 #define round_line(x) (((x) + 15) & ~15) 59 #define trunc_line(x) ((x) & ~15) 60 61 void 62 tx3900_icache_sync_all_16(void) 63 { 64 65 tx3900_icache_do_inv_index_16(MIPS_PHYS_TO_KSEG0(0), 66 MIPS_PHYS_TO_KSEG0(mips_cache_info.mci_picache_size)); 67 } 68 69 void 70 tx3900_icache_sync_range_16(register_t va, vsize_t size) 71 { 72 vaddr_t eva = round_line(va + size); 73 74 va = trunc_line(va); 75 76 if ((eva - va) >= mips_cache_info.mci_picache_size) { 77 /* Just hit the whole thing. */ 78 va = MIPS_PHYS_TO_KSEG0(0); 79 eva = MIPS_PHYS_TO_KSEG0(mips_cache_info.mci_picache_size); 80 } 81 82 tx3900_icache_do_inv_index_16(va, eva); 83 } 84 85 #undef round_line 86 #undef trunc_line 87 88 #define round_line(x) (((x) + 3) & ~3) 89 #define trunc_line(x) ((x) & ~3) 90 91 static int tx3900_dummy_buffer[R3900_C_SIZE_MAX / sizeof(int)]; 92 93 void 94 tx3900_pdcache_wbinv_all_4(void) 95 { 96 vaddr_t va = MIPS_PHYS_TO_KSEG0(0); 97 vaddr_t eva = va + mips_cache_info.mci_pdcache_size; 98 volatile int *p; 99 100 /* 101 * No Index Invalidate for the TX3900 -- have to execute a 102 * series of load instructions from the dummy buffer, instead. 103 */ 104 105 p = tx3900_dummy_buffer; 106 while (va < eva) { 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 (void) *p++; (void) *p++; (void) *p++; (void) *p++; 113 (void) *p++; (void) *p++; (void) *p++; (void) *p++; 114 (void) *p++; (void) *p++; (void) *p++; (void) *p++; 115 va += (32 * 4); 116 } 117 } 118 119 void 120 tx3900_pdcache_inv_range_4(register_t va, vsize_t size) 121 { 122 vaddr_t eva = round_line(va + size); 123 124 va = trunc_line(va); 125 126 while ((eva - va) >= (32 * 4)) { 127 cache_tx39_op_32lines_4(va, 128 CACHE_TX39_D|CACHEOP_TX3900_HIT_INV); 129 va += (32 * 4); 130 }; 131 132 while (va < eva) { 133 cache_op_tx39_line(va, CACHE_TX39_D|CACHEOP_TX3900_HIT_INV); 134 va += 4; 135 } 136 } 137 138 void 139 tx3900_pdcache_wb_range_4(register_t va, vsize_t size) 140 { 141 142 /* Cache is write-through. */ 143 } 144 145 #undef round_line 146 #undef trunc_line 147 148 #define round_line(x) (((x) + 15) & ~15) 149 #define trunc_line(x) ((x) & ~15) 150 151 void 152 tx3920_icache_sync_all_16wb(void) 153 { 154 155 mips_dcache_wbinv_all(); 156 157 __asm volatile(".set push; .set mips2; sync; .set pop"); 158 159 tx3920_icache_do_inv_16(MIPS_PHYS_TO_KSEG0(0), 160 MIPS_PHYS_TO_KSEG0(mips_cache_info.mci_picache_size)); 161 } 162 163 void 164 tx3920_icache_sync_range_16wt(register_t va, vsize_t size) 165 { 166 vaddr_t eva = round_line(va + size); 167 168 va = trunc_line(va); 169 170 tx3920_icache_do_inv_16(va, eva); 171 } 172 173 void 174 tx3920_icache_sync_range_16wb(register_t va, vsize_t size) 175 { 176 vaddr_t eva = round_line(va + size); 177 178 va = trunc_line(va); 179 180 mips_dcache_wb_range(va, (eva - va)); 181 182 __asm volatile(".set push; .set mips2; sync; .set pop"); 183 184 tx3920_icache_do_inv_16(va, eva); 185 } 186 187 void 188 tx3920_pdcache_wbinv_all_16wt(void) 189 { 190 vaddr_t va = MIPS_PHYS_TO_KSEG0(0); 191 vaddr_t eva = va + mips_cache_info.mci_pdcache_size; 192 193 /* 194 * Since we're hitting the whole thing, we don't have to 195 * worry about the 2 different "ways". 196 */ 197 198 while (va < eva) { 199 cache_tx39_op_32lines_16(va, 200 CACHE_TX39_D|CACHEOP_TX3920_INDEX_INV); 201 va += (32 * 16); 202 } 203 } 204 205 void 206 tx3920_pdcache_wbinv_all_16wb(void) 207 { 208 vaddr_t va = MIPS_PHYS_TO_KSEG0(0); 209 vaddr_t eva = va + mips_cache_info.mci_pdcache_size; 210 211 /* 212 * Since we're hitting the whole thing, we don't have to 213 * worry about the 2 different "ways". 214 */ 215 216 while (va < eva) { 217 cache_tx39_op_32lines_16(va, 218 CACHE_TX39_D|CACHEOP_TX3920_INDEX_WB_INV); 219 va += (32 * 16); 220 } 221 } 222 223 void 224 tx3920_pdcache_wbinv_range_16wb(register_t va, vsize_t size) 225 { 226 vaddr_t eva = round_line(va + size); 227 228 va = trunc_line(va); 229 230 while ((eva - va) >= (32 * 16)) { 231 cache_tx39_op_32lines_16(va, 232 CACHE_TX39_D|CACHEOP_TX3920_HIT_WB_INV); 233 va += (32 * 16); 234 } 235 236 while (va < eva) { 237 cache_op_tx39_line(va, CACHE_TX39_D|CACHEOP_TX3920_HIT_WB_INV); 238 va += 16; 239 } 240 } 241 242 void 243 tx3920_pdcache_inv_range_16(register_t va, vsize_t size) 244 { 245 vaddr_t eva = round_line(va + size); 246 247 va = trunc_line(va); 248 249 while ((eva - va) >= (32 * 16)) { 250 cache_tx39_op_32lines_16(va, 251 CACHE_TX39_D|CACHEOP_TX3920_HIT_INV); 252 va += (32 * 16); 253 } 254 255 while (va < eva) { 256 cache_op_tx39_line(va, CACHE_TX39_D|CACHEOP_TX3920_HIT_INV); 257 va += 16; 258 } 259 } 260 261 void 262 tx3920_pdcache_wb_range_16wt(register_t va, vsize_t size) 263 { 264 265 /* Cache is write-through. */ 266 } 267 268 void 269 tx3920_pdcache_wb_range_16wb(register_t va, vsize_t size) 270 { 271 vaddr_t eva = round_line(va + size); 272 273 va = trunc_line(va); 274 275 while ((eva - va) >= (32 * 16)) { 276 cache_tx39_op_32lines_16(va, 277 CACHE_TX39_D|CACHEOP_TX3920_HIT_WB); 278 va += (32 * 16); 279 } 280 281 while (va < eva) { 282 cache_op_tx39_line(va, CACHE_TX39_D|CACHEOP_TX3920_HIT_WB); 283 va += 16; 284 } 285 } 286