1 /* $NetBSD: cache.c,v 1.11 2002/04/03 03:55:07 simonb Exp $ */ 2 3 /* 4 * Copyright 2001, 2002 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 /* 39 * Copyright 2000, 2001 40 * Broadcom Corporation. All rights reserved. 41 * 42 * This software is furnished under license and may be used and copied only 43 * in accordance with the following terms and conditions. Subject to these 44 * conditions, you may download, copy, install, use, modify and distribute 45 * modified or unmodified copies of this software in source and/or binary 46 * form. No title or ownership is transferred hereby. 47 * 48 * 1) Any source code used, modified or distributed must reproduce and 49 * retain this copyright notice and list of conditions as they appear in 50 * the source file. 51 * 52 * 2) No right is granted to use any trade name, trademark, or logo of 53 * Broadcom Corporation. Neither the "Broadcom Corporation" name nor any 54 * trademark or logo of Broadcom Corporation may be used to endorse or 55 * promote products derived from this software without the prior written 56 * permission of Broadcom Corporation. 57 * 58 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR IMPLIED 59 * WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF 60 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR 61 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM BE LIABLE 62 * FOR ANY DAMAGES WHATSOEVER, AND IN PARTICULAR, BROADCOM SHALL NOT BE 63 * LIABLE FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 64 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 65 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 66 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 67 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 68 * OR OTHERWISE), EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 69 */ 70 71 #include "opt_cputype.h" 72 73 #include <sys/param.h> 74 75 #include <uvm/uvm_extern.h> 76 77 #include <mips/cache.h> 78 #include <mips/locore.h> 79 80 #ifdef MIPS1 81 #include <mips/cache_r3k.h> 82 #endif 83 84 #ifdef MIPS3_PLUS 85 #include <mips/cache_r4k.h> /* includes r5k and greater */ 86 #endif 87 88 #if defined(MIPS32) || defined(MIPS64) 89 #include <mips/mipsNN.h> /* MIPS32/MIPS64 registers */ 90 #include <mips/cache_mipsNN.h> 91 #endif 92 93 /* PRIMARY CACHE VARIABLES */ 94 int mips_picache_size; 95 int mips_picache_line_size; 96 int mips_picache_ways; 97 int mips_picache_way_size; 98 int mips_picache_way_mask; 99 100 int mips_pdcache_size; /* and unified */ 101 int mips_pdcache_line_size; 102 int mips_pdcache_ways; 103 int mips_pdcache_way_size; 104 int mips_pdcache_way_mask; 105 int mips_pdcache_write_through; 106 107 int mips_pcache_unified; 108 109 /* SECONDARY CACHE VARIABLES */ 110 int mips_sicache_size; 111 int mips_sicache_line_size; 112 int mips_sicache_ways; 113 int mips_sicache_way_size; 114 int mips_sicache_way_mask; 115 116 int mips_sdcache_size; /* and unified */ 117 int mips_sdcache_line_size; 118 int mips_sdcache_ways; 119 int mips_sdcache_way_size; 120 int mips_sdcache_way_mask; 121 int mips_sdcache_write_through; 122 123 int mips_scache_unified; 124 125 /* TERTIARY CACHE VARIABLES */ 126 int mips_tcache_size; /* always unified */ 127 int mips_tcache_line_size; 128 int mips_tcache_ways; 129 int mips_tcache_way_size; 130 int mips_tcache_way_mask; 131 int mips_tcache_write_through; 132 133 /* 134 * These two variables inform the rest of the kernel about the 135 * size of the largest D-cache line present in the system. The 136 * mask can be used to determine if a region of memory is cache 137 * line size aligned. 138 * 139 * Whenever any code updates a data cache line size, it should 140 * call mips_dcache_compute_align() to recompute these values. 141 */ 142 int mips_dcache_align; 143 int mips_dcache_align_mask; 144 145 int mips_cache_alias_mask; /* for virtually-indexed caches */ 146 int mips_cache_prefer_mask; 147 148 struct mips_cache_ops mips_cache_ops; 149 150 #ifdef MIPS1 151 #ifdef ENABLE_MIPS_TX3900 152 #include <mips/cache_tx39.h> 153 void tx3900_get_cache_config(void); 154 void tx3920_get_cache_config(void); 155 void tx39_cache_config_write_through(void); 156 #endif /* ENABLE_MIPS_TX3900 */ 157 #endif /* MIPS1 */ 158 159 #if defined(MIPS3) || defined(MIPS4) 160 #ifdef MIPS3_5900 161 #include <mips/cache_r5900.h> 162 #endif /* MIPS3_5900 */ 163 void mips3_get_cache_config(int); 164 #endif /* MIPS3 || MIPS4 */ 165 166 #if defined(MIPS1) || defined(MIPS3) || defined(MIPS4) 167 static void mips_config_cache_prehistoric(void); 168 #endif 169 #if defined(MIPS32) || defined(MIPS64) 170 static void mips_config_cache_modern(void); 171 #endif 172 173 /* 174 * mips_dcache_compute_align: 175 * 176 * Compute the D-cache alignment values. 177 */ 178 void 179 mips_dcache_compute_align(void) 180 { 181 int align; 182 183 align = mips_pdcache_line_size; 184 185 if (mips_sdcache_line_size > align) 186 align = mips_sdcache_line_size; 187 188 if (mips_tcache_line_size > align) 189 align = mips_tcache_line_size; 190 191 mips_dcache_align = align; 192 mips_dcache_align_mask = align - 1; 193 } 194 195 /* 196 * mips_config_cache: 197 * 198 * Configure the cache for the system. 199 * 200 * XXX DOES NOT HANDLE SPLIT SECONDARY CACHES. 201 */ 202 void 203 mips_config_cache(void) 204 { 205 206 #if defined(MIPS1) || defined(MIPS3) || defined(MIPS4) 207 if (MIPS_PRID_CID(cpu_id) == MIPS_PRID_CID_PREHISTORIC) 208 mips_config_cache_prehistoric(); 209 #endif 210 #if defined(MIPS32) || defined(MIPS64) 211 if (MIPS_PRID_CID(cpu_id) != MIPS_PRID_CID_PREHISTORIC) 212 mips_config_cache_modern(); 213 #endif 214 215 #ifdef DIAGNOSTIC 216 /* Check that all cache ops are set up. */ 217 if (mips_picache_size || 1) { /* XXX- must have primary Icache */ 218 if (!mips_cache_ops.mco_icache_sync_all) 219 panic("no icache_sync_all cache op"); 220 if (!mips_cache_ops.mco_icache_sync_range) 221 panic("no icache_sync_range cache op"); 222 if (!mips_cache_ops.mco_icache_sync_range_index) 223 panic("no icache_sync_range_index cache op"); 224 } 225 if (mips_pdcache_size || 1) { /* XXX- must have primary Icache */ 226 if (!mips_cache_ops.mco_pdcache_wbinv_all) 227 panic("no pdcache_wbinv_all"); 228 if (!mips_cache_ops.mco_pdcache_wbinv_range) 229 panic("no pdcache_wbinv_range"); 230 if (!mips_cache_ops.mco_pdcache_wbinv_range_index) 231 panic("no pdcache_wbinv_range_index"); 232 if (!mips_cache_ops.mco_pdcache_inv_range) 233 panic("no pdcache_inv_range"); 234 if (!mips_cache_ops.mco_pdcache_wb_range) 235 panic("no pdcache_wb_range"); 236 } 237 if (mips_sdcache_size) { 238 if (!mips_cache_ops.mco_sdcache_wbinv_all) 239 panic("no sdcache_wbinv_all"); 240 if (!mips_cache_ops.mco_sdcache_wbinv_range) 241 panic("no sdcache_wbinv_range"); 242 if (!mips_cache_ops.mco_sdcache_wbinv_range_index) 243 panic("no sdcache_wbinv_range_index"); 244 if (!mips_cache_ops.mco_sdcache_inv_range) 245 panic("no sdcache_inv_range"); 246 if (!mips_cache_ops.mco_sdcache_wb_range) 247 panic("no sdcache_wb_range"); 248 } 249 #endif /* DIAGNOSTIC */ 250 } 251 252 #if defined(MIPS1) || defined(MIPS3) || defined(MIPS4) 253 /* 254 * XXX DOES NOT HANDLE SPLIT SECONDARY CACHES. 255 */ 256 void 257 mips_config_cache_prehistoric(void) 258 { 259 #if defined(MIPS3) || defined(MIPS4) 260 int csizebase = MIPS3_CONFIG_C_DEFBASE; 261 #endif 262 263 KASSERT(PAGE_SIZE != 0); 264 265 /* 266 * Configure primary caches. 267 */ 268 switch (MIPS_PRID_IMPL(cpu_id)) { 269 #ifdef MIPS1 270 case MIPS_R2000: 271 case MIPS_R3000: 272 mips_picache_size = r3k_picache_size(); 273 mips_pdcache_size = r3k_pdcache_size(); 274 275 mips_picache_line_size = 4; 276 mips_pdcache_line_size = 4; 277 278 mips_picache_ways = 1; 279 mips_pdcache_ways = 1; 280 281 mips_pdcache_write_through = 1; 282 283 mips_cache_ops.mco_icache_sync_all = 284 r3k_icache_sync_all; 285 mips_cache_ops.mco_icache_sync_range = 286 r3k_icache_sync_range; 287 mips_cache_ops.mco_icache_sync_range_index = 288 mips_cache_ops.mco_icache_sync_range; 289 290 mips_cache_ops.mco_pdcache_wbinv_all = 291 r3k_pdcache_wbinv_all; 292 mips_cache_ops.mco_pdcache_wbinv_range = 293 r3k_pdcache_inv_range; 294 mips_cache_ops.mco_pdcache_wbinv_range_index = 295 mips_cache_ops.mco_pdcache_wbinv_range; 296 mips_cache_ops.mco_pdcache_inv_range = 297 r3k_pdcache_inv_range; 298 mips_cache_ops.mco_pdcache_wb_range = 299 r3k_pdcache_wb_range; 300 301 uvmexp.ncolors = atop(mips_pdcache_size); 302 break; 303 304 #ifdef ENABLE_MIPS_TX3900 305 case MIPS_TX3900: 306 switch (MIPS_PRID_REV_MAJ(cpu_id)) { 307 case 1: /* TX3912 */ 308 mips_picache_ways = 1; 309 mips_picache_line_size = 16; 310 mips_pdcache_line_size = 4; 311 312 tx3900_get_cache_config(); 313 314 mips_pdcache_write_through = 1; 315 316 mips_cache_ops.mco_icache_sync_all = 317 tx3900_icache_sync_all_16; 318 mips_cache_ops.mco_icache_sync_range = 319 tx3900_icache_sync_range_16; 320 mips_cache_ops.mco_icache_sync_range_index = 321 tx3900_icache_sync_range_16; 322 323 mips_cache_ops.mco_pdcache_wbinv_all = 324 tx3900_pdcache_wbinv_all_4; 325 mips_cache_ops.mco_pdcache_wbinv_range = 326 tx3900_pdcache_inv_range_4; 327 mips_cache_ops.mco_pdcache_wbinv_range_index = 328 tx3900_pdcache_inv_range_4; 329 mips_cache_ops.mco_pdcache_inv_range = 330 tx3900_pdcache_inv_range_4; 331 mips_cache_ops.mco_pdcache_wb_range = 332 tx3900_pdcache_wb_range_4; 333 break; 334 335 case 3: /* TX3922 */ 336 mips_picache_ways = 2; 337 mips_picache_line_size = 16; 338 mips_pdcache_line_size = 16; 339 340 tx3920_get_cache_config(); 341 342 mips_cache_ops.mco_icache_sync_all = 343 mips_pdcache_write_through ? 344 tx3900_icache_sync_all_16 : 345 tx3920_icache_sync_all_16wb; 346 mips_cache_ops.mco_icache_sync_range = 347 mips_pdcache_write_through ? 348 tx3920_icache_sync_range_16wt : 349 tx3920_icache_sync_range_16wb; 350 mips_cache_ops.mco_icache_sync_range_index = 351 mips_cache_ops.mco_icache_sync_range; 352 353 mips_cache_ops.mco_pdcache_wbinv_all = 354 mips_pdcache_write_through ? 355 tx3920_pdcache_wbinv_all_16wt : 356 tx3920_pdcache_wbinv_all_16wb; 357 mips_cache_ops.mco_pdcache_wbinv_range = 358 mips_pdcache_write_through ? 359 tx3920_pdcache_inv_range_16 : 360 tx3920_pdcache_wbinv_range_16wb; 361 mips_cache_ops.mco_pdcache_wbinv_range_index = 362 mips_cache_ops.mco_pdcache_wbinv_range; 363 mips_cache_ops.mco_pdcache_inv_range = 364 tx3920_pdcache_inv_range_16; 365 mips_cache_ops.mco_pdcache_wb_range = 366 mips_pdcache_write_through ? 367 tx3920_pdcache_wb_range_16wt : 368 tx3920_pdcache_wb_range_16wb; 369 break; 370 371 default: 372 panic("mips_config_cache: unsupported TX3900"); 373 } 374 375 mips_pdcache_ways = 2; 376 tx3900_get_cache_config(); 377 /* change to write-through mode */ 378 tx39_cache_config_write_through(); 379 380 uvmexp.ncolors = atop(mips_pdcache_size) / mips_pdcache_ways; 381 break; 382 #endif /* ENABLE_MIPS_TX3900 */ 383 #endif /* MIPS1 */ 384 385 #if defined(MIPS3) || defined(MIPS4) 386 case MIPS_R4100: 387 /* 388 * R4100 (NEC VR series) revision number means: 389 * 390 * MIPS_PRID_REV_MAJ MIPS_PRID_REV_MIN 391 * VR4102 4 ? 392 * VR4111 5 ? 393 * VR4181 5 ? 394 * VR4121 6 ? 395 * VR4122 7 0 or 1 396 * VR4181A 7 3 < 397 * VR4131 8 ? 398 */ 399 /* Vr4131 has R4600 style 2-way set-associative cache */ 400 if (MIPS_PRID_REV_MAJ(cpu_id) == 8) 401 goto primary_cache_is_2way; 402 /* FALLTHROUGH */ 403 404 case MIPS_R4000: 405 case MIPS_R4300: 406 mips_picache_ways = 1; 407 mips_pdcache_ways = 1; 408 mips_sdcache_ways = 1; 409 410 mips3_get_cache_config(csizebase); 411 412 switch (mips_picache_line_size) { 413 case 16: 414 mips_cache_ops.mco_icache_sync_all = 415 r4k_icache_sync_all_16; 416 mips_cache_ops.mco_icache_sync_range = 417 r4k_icache_sync_range_16; 418 mips_cache_ops.mco_icache_sync_range_index = 419 r4k_icache_sync_range_index_16; 420 break; 421 422 case 32: 423 mips_cache_ops.mco_icache_sync_all = 424 r4k_icache_sync_all_32; 425 mips_cache_ops.mco_icache_sync_range = 426 r4k_icache_sync_range_32; 427 mips_cache_ops.mco_icache_sync_range_index = 428 r4k_icache_sync_range_index_32; 429 break; 430 431 default: 432 panic("r4k picache line size %d", 433 mips_picache_line_size); 434 } 435 436 switch (mips_pdcache_line_size) { 437 case 16: 438 mips_cache_ops.mco_pdcache_wbinv_all = 439 r4k_pdcache_wbinv_all_16; 440 mips_cache_ops.mco_pdcache_wbinv_range = 441 r4k_pdcache_wbinv_range_16; 442 mips_cache_ops.mco_pdcache_wbinv_range_index = 443 r4k_pdcache_wbinv_range_index_16; 444 mips_cache_ops.mco_pdcache_inv_range = 445 r4k_pdcache_inv_range_16; 446 mips_cache_ops.mco_pdcache_wb_range = 447 r4k_pdcache_wb_range_16; 448 break; 449 450 case 32: 451 mips_cache_ops.mco_pdcache_wbinv_all = 452 r4k_pdcache_wbinv_all_32; 453 mips_cache_ops.mco_pdcache_wbinv_range = 454 r4k_pdcache_wbinv_range_32; 455 mips_cache_ops.mco_pdcache_wbinv_range_index = 456 r4k_pdcache_wbinv_range_index_32; 457 mips_cache_ops.mco_pdcache_inv_range = 458 r4k_pdcache_inv_range_32; 459 mips_cache_ops.mco_pdcache_wb_range = 460 r4k_pdcache_wb_range_32; 461 break; 462 463 default: 464 panic("r4k pdcache line size %d", 465 mips_pdcache_line_size); 466 } 467 468 /* Virtually-indexed cache; no use for colors. */ 469 break; 470 471 case MIPS_R4600: 472 #ifdef ENABLE_MIPS_R4700 473 case MIPS_R4700: 474 #endif 475 #ifndef ENABLE_MIPS_R3NKK 476 case MIPS_R5000: 477 #endif 478 case MIPS_RM5200: 479 primary_cache_is_2way: 480 mips_picache_ways = 2; 481 mips_pdcache_ways = 2; 482 483 mips3_get_cache_config(csizebase); 484 485 switch (mips_picache_line_size) { 486 case 32: 487 mips_cache_ops.mco_icache_sync_all = 488 r5k_icache_sync_all_32; 489 mips_cache_ops.mco_icache_sync_range = 490 r5k_icache_sync_range_32; 491 mips_cache_ops.mco_icache_sync_range_index = 492 r5k_icache_sync_range_index_32; 493 break; 494 495 default: 496 panic("r5k picache line size %d", 497 mips_picache_line_size); 498 } 499 500 switch (mips_pdcache_line_size) { 501 case 16: 502 mips_cache_ops.mco_pdcache_wbinv_all = 503 r5k_pdcache_wbinv_all_16; 504 mips_cache_ops.mco_pdcache_wbinv_range = 505 r5k_pdcache_wbinv_range_16; 506 mips_cache_ops.mco_pdcache_wbinv_range_index = 507 r5k_pdcache_wbinv_range_index_16; 508 mips_cache_ops.mco_pdcache_inv_range = 509 r5k_pdcache_inv_range_16; 510 mips_cache_ops.mco_pdcache_wb_range = 511 r5k_pdcache_wb_range_16; 512 break; 513 514 case 32: 515 mips_cache_ops.mco_pdcache_wbinv_all = 516 r5k_pdcache_wbinv_all_32; 517 mips_cache_ops.mco_pdcache_wbinv_range = 518 r5k_pdcache_wbinv_range_32; 519 mips_cache_ops.mco_pdcache_wbinv_range_index = 520 r5k_pdcache_wbinv_range_index_32; 521 mips_cache_ops.mco_pdcache_inv_range = 522 r5k_pdcache_inv_range_32; 523 mips_cache_ops.mco_pdcache_wb_range = 524 r5k_pdcache_wb_range_32; 525 break; 526 527 default: 528 panic("r5k pdcache line size %d", 529 mips_pdcache_line_size); 530 } 531 532 /* 533 * Deal with R4600 chip bugs. 534 */ 535 if (MIPS_PRID_IMPL(cpu_id) == MIPS_R4600 && 536 MIPS_PRID_REV_MAJ(cpu_id) == 1) { 537 KASSERT(mips_pdcache_line_size == 32); 538 mips_cache_ops.mco_pdcache_wbinv_range = 539 r4600v1_pdcache_wbinv_range_32; 540 mips_cache_ops.mco_pdcache_inv_range = 541 r4600v1_pdcache_inv_range_32; 542 mips_cache_ops.mco_pdcache_wb_range = 543 r4600v1_pdcache_wb_range_32; 544 } else if (MIPS_PRID_IMPL(cpu_id) == MIPS_R4600 && 545 MIPS_PRID_REV_MAJ(cpu_id) == 2) { 546 KASSERT(mips_pdcache_line_size == 32); 547 mips_cache_ops.mco_pdcache_wbinv_range = 548 r4600v2_pdcache_wbinv_range_32; 549 mips_cache_ops.mco_pdcache_inv_range = 550 r4600v2_pdcache_inv_range_32; 551 mips_cache_ops.mco_pdcache_wb_range = 552 r4600v2_pdcache_wb_range_32; 553 } 554 555 /* 556 * Deal with VR4131 chip bugs. 557 */ 558 if (MIPS_PRID_IMPL(cpu_id) == MIPS_R4100 && 559 MIPS_PRID_REV_MAJ(cpu_id) == 8) { 560 KASSERT(mips_pdcache_line_size == 16); 561 mips_cache_ops.mco_pdcache_wbinv_range = 562 vr4131v1_pdcache_wbinv_range_16; 563 } 564 565 /* Virtually-indexed cache; no use for colors. */ 566 break; 567 #ifdef MIPS3_5900 568 case MIPS_R5900: 569 /* cache spec */ 570 mips_picache_ways = 2; 571 mips_pdcache_ways = 2; 572 mips_picache_size = CACHE_R5900_SIZE_I; 573 mips_picache_line_size = CACHE_R5900_LSIZE_I; 574 mips_pdcache_size = CACHE_R5900_SIZE_D; 575 mips_pdcache_line_size = CACHE_R5900_LSIZE_D; 576 mips_cache_alias_mask = 577 ((mips_pdcache_size / mips_pdcache_ways) - 1) & 578 ~(PAGE_SIZE - 1); 579 mips_cache_prefer_mask = 580 max(mips_pdcache_size, mips_picache_size) - 1; 581 /* cache ops */ 582 mips_cache_ops.mco_icache_sync_all = 583 r5900_icache_sync_all_64; 584 mips_cache_ops.mco_icache_sync_range = 585 r5900_icache_sync_range_64; 586 mips_cache_ops.mco_icache_sync_range_index = 587 r5900_icache_sync_range_index_64; 588 mips_cache_ops.mco_pdcache_wbinv_all = 589 r5900_pdcache_wbinv_all_64; 590 mips_cache_ops.mco_pdcache_wbinv_range = 591 r5900_pdcache_wbinv_range_64; 592 mips_cache_ops.mco_pdcache_wbinv_range_index = 593 r5900_pdcache_wbinv_range_index_64; 594 mips_cache_ops.mco_pdcache_inv_range = 595 r5900_pdcache_inv_range_64; 596 mips_cache_ops.mco_pdcache_wb_range = 597 r5900_pdcache_wb_range_64; 598 break; 599 #endif /* MIPS3_5900 */ 600 #endif /* MIPS3 || MIPS4 */ 601 602 default: 603 panic("can't handle primary cache on impl 0x%x\n", 604 MIPS_PRID_IMPL(cpu_id)); 605 } 606 607 /* 608 * Compute the "way mask" for each cache. 609 */ 610 if (mips_picache_size) { 611 KASSERT(mips_picache_ways != 0); 612 mips_picache_way_size = (mips_picache_size / mips_picache_ways); 613 mips_picache_way_mask = mips_picache_way_size - 1; 614 } 615 if (mips_pdcache_size) { 616 KASSERT(mips_pdcache_ways != 0); 617 mips_pdcache_way_size = (mips_pdcache_size / mips_pdcache_ways); 618 mips_pdcache_way_mask = mips_pdcache_way_size - 1; 619 } 620 621 mips_dcache_compute_align(); 622 623 if (mips_sdcache_line_size == 0) 624 return; 625 626 /* 627 * Configure the secondary cache. 628 */ 629 switch (MIPS_PRID_IMPL(cpu_id)) { 630 #if defined(MIPS3) || defined(MIPS4) 631 case MIPS_R4000: 632 /* 633 * R4000/R4400 always detects virtual alias as if 634 * primary cache size is 32KB. Actual primary cache size 635 * is ignored wrt VCED/VCEI. 636 */ 637 mips_cache_alias_mask = 638 (MIPS3_MAX_PCACHE_SIZE - 1) & ~(PAGE_SIZE - 1); 639 mips_cache_prefer_mask = MIPS3_MAX_PCACHE_SIZE - 1; 640 /* FALLTHROUGH */ 641 case MIPS_R4100: 642 case MIPS_R4300: 643 case MIPS_R4600: 644 #ifdef ENABLE_MIPS_R4700 645 case MIPS_R4700: 646 #endif 647 #ifndef ENABLE_MIPS_R3NKK 648 case MIPS_R5000: 649 #endif 650 case MIPS_RM5200: 651 switch (mips_sdcache_ways) { 652 case 1: 653 switch (mips_sdcache_line_size) { 654 case 32: 655 mips_cache_ops.mco_sdcache_wbinv_all = 656 r4k_sdcache_wbinv_all_32; 657 mips_cache_ops.mco_sdcache_wbinv_range = 658 r4k_sdcache_wbinv_range_32; 659 mips_cache_ops.mco_sdcache_wbinv_range_index = 660 r4k_sdcache_wbinv_range_index_32; 661 mips_cache_ops.mco_sdcache_inv_range = 662 r4k_sdcache_inv_range_32; 663 mips_cache_ops.mco_sdcache_wb_range = 664 r4k_sdcache_wb_range_32; 665 break; 666 667 case 16: 668 case 64: 669 mips_cache_ops.mco_sdcache_wbinv_all = 670 r4k_sdcache_wbinv_all_generic; 671 mips_cache_ops.mco_sdcache_wbinv_range = 672 r4k_sdcache_wbinv_range_generic; 673 mips_cache_ops.mco_sdcache_wbinv_range_index = 674 r4k_sdcache_wbinv_range_index_generic; 675 mips_cache_ops.mco_sdcache_inv_range = 676 r4k_sdcache_inv_range_generic; 677 mips_cache_ops.mco_sdcache_wb_range = 678 r4k_sdcache_wb_range_generic; 679 break; 680 681 case 128: 682 mips_cache_ops.mco_sdcache_wbinv_all = 683 r4k_sdcache_wbinv_all_128; 684 mips_cache_ops.mco_sdcache_wbinv_range = 685 r4k_sdcache_wbinv_range_128; 686 mips_cache_ops.mco_sdcache_wbinv_range_index = 687 r4k_sdcache_wbinv_range_index_128; 688 mips_cache_ops.mco_sdcache_inv_range = 689 r4k_sdcache_inv_range_128; 690 mips_cache_ops.mco_sdcache_wb_range = 691 r4k_sdcache_wb_range_128; 692 break; 693 694 default: 695 panic("r4k sdcache %d way line size %d\n", 696 mips_sdcache_ways, mips_sdcache_line_size); 697 } 698 break; 699 700 default: 701 panic("r4k sdcache %d way line size %d\n", 702 mips_sdcache_ways, mips_sdcache_line_size); 703 } 704 break; 705 #endif /* MIPS3 || MIPS4 */ 706 707 default: 708 panic("can't handle secondary cache on impl 0x%x\n", 709 MIPS_PRID_IMPL(cpu_id)); 710 } 711 712 /* 713 * Compute the "way mask" for each secondary cache. 714 */ 715 if (mips_sdcache_size) { 716 KASSERT(mips_sdcache_ways != 0); 717 mips_sdcache_way_size = (mips_sdcache_size / mips_sdcache_ways); 718 mips_sdcache_way_mask = mips_sdcache_way_size - 1; 719 } 720 721 mips_dcache_compute_align(); 722 } 723 724 #ifdef MIPS1 725 #ifdef ENABLE_MIPS_TX3900 726 /* 727 * tx3900_get_cache_config: 728 * 729 * Fetch cache size information for the TX3900. 730 */ 731 void 732 tx3900_get_cache_config(void) 733 { 734 uint32_t config; 735 736 config = tx3900_cp0_config_read(); 737 738 mips_picache_size = R3900_C_SIZE_MIN << 739 ((config & R3900_CONFIG_ICS_MASK) >> R3900_CONFIG_ICS_SHIFT); 740 741 mips_pdcache_size = R3900_C_SIZE_MIN << 742 ((config & R3900_CONFIG_DCS_MASK) >> R3900_CONFIG_DCS_SHIFT); 743 } 744 745 /* 746 * tx3920_get_cache_config: 747 * 748 * Fetch cache size information for the TX3920. 749 */ 750 void 751 tx3920_get_cache_config(void) 752 { 753 754 /* Size is the same as TX3900. */ 755 tx3900_get_cache_config(); 756 757 /* Now determine write-through/write-back mode. */ 758 if ((tx3900_cp0_config_read() & R3900_CONFIG_WBON) == 0) 759 mips_pdcache_write_through = 1; 760 } 761 762 /* 763 * tx39_cache_config_write_through: 764 * 765 * TX3922 write-through D-cache mode. 766 * for TX3912, no meaning. (no write-back mode) 767 */ 768 void 769 tx39_cache_config_write_through(void) 770 { 771 u_int32_t r; 772 773 mips_dcache_wbinv_all(); 774 775 __asm__ __volatile__("mfc0 %0, $3" : "=r"(r)); 776 r &= 0xffffdfff; 777 __asm__ __volatile__("mtc0 %0, $3" : : "r"(r)); 778 } 779 780 #endif /* ENABLE_MIPS_TX3900 */ 781 #endif /* MIPS1 */ 782 783 #if defined(MIPS3) || defined(MIPS4) 784 /* 785 * mips3_get_cache_config: 786 * 787 * Fetch the cache config information for a MIPS-3 or MIPS-4 788 * processor (virtually-indexed cache). 789 * 790 * NOTE: Fetching the size of the secondary cache is something 791 * that platform specific code has to do. We'd appreciate it 792 * if they initialized the size before now. 793 * 794 * ALSO NOTE: The number of ways in the cache must already be 795 * initialized. 796 */ 797 void 798 mips3_get_cache_config(int csizebase) 799 { 800 uint32_t config = mips3_cp0_config_read(); 801 802 mips_picache_size = MIPS3_CONFIG_CACHE_SIZE(config, 803 MIPS3_CONFIG_IC_MASK, csizebase, MIPS3_CONFIG_IC_SHIFT); 804 mips_picache_line_size = MIPS3_CONFIG_CACHE_L1_LSIZE(config, 805 MIPS3_CONFIG_IB); 806 807 mips_pdcache_size = MIPS3_CONFIG_CACHE_SIZE(config, 808 MIPS3_CONFIG_DC_MASK, csizebase, MIPS3_CONFIG_DC_SHIFT); 809 mips_pdcache_line_size = MIPS3_CONFIG_CACHE_L1_LSIZE(config, 810 MIPS3_CONFIG_DB); 811 812 mips_cache_alias_mask = 813 ((mips_pdcache_size / mips_pdcache_ways) - 1) & ~(PAGE_SIZE - 1); 814 mips_cache_prefer_mask = 815 max(mips_pdcache_size, mips_picache_size) - 1; 816 817 if ((config & MIPS3_CONFIG_SC) == 0) { 818 mips_sdcache_line_size = MIPS3_CONFIG_CACHE_L2_LSIZE(config); 819 if ((config & MIPS3_CONFIG_SS) == 0) 820 mips_scache_unified = 1; 821 } 822 } 823 #endif /* MIPS3 || MIPS4 */ 824 #endif /* MIPS1 || MIPS3 || MIPS4 */ 825 826 #if defined(MIPS32) || defined(MIPS64) 827 828 #ifdef MIPS_DISABLE_L1_CACHE 829 static void cache_noop(void); 830 static void cache_noop(void) {} 831 #endif 832 833 static void 834 mips_config_cache_modern(void) 835 { 836 /* MIPS32/MIPS64, use coprocessor 0 config registers */ 837 uint32_t cfg, cfg1; 838 839 cfg = mips3_cp0_config_read(); 840 cfg1 = mipsNN_cp0_config1_read(); 841 842 #ifdef MIPS_DISABLE_L1_CACHE 843 cfg1 &= ~MIPSNN_CFG1_IL_MASK; 844 cfg1 &= ~MIPSNN_CFG1_DL_MASK; 845 mipsNN_cp0_config1_write(cfg1); 846 #endif 847 848 /* figure out Dcache params. */ 849 switch (MIPSNN_GET(CFG1_DL, cfg1)) { 850 case MIPSNN_CFG1_DL_NONE: 851 mips_pdcache_line_size = mips_pdcache_way_size = 852 mips_pdcache_ways = 0; 853 break; 854 case MIPSNN_CFG1_DL_RSVD: 855 panic("reserved MIPS32/64 Dcache line size"); 856 break; 857 default: 858 if (MIPSNN_GET(CFG1_DS, cfg1) == MIPSNN_CFG1_DS_RSVD) 859 panic("reserved MIPS32/64 Dcache sets per way"); 860 mips_pdcache_line_size = MIPSNN_CFG1_DL(cfg1); 861 mips_pdcache_way_size = 862 mips_pdcache_line_size * MIPSNN_CFG1_DS(cfg1); 863 mips_pdcache_ways = MIPSNN_CFG1_DA(cfg1) + 1; 864 865 /* 866 * Compute the total size and "way mask" for the 867 * primary Icache. 868 */ 869 mips_pdcache_size = 870 mips_pdcache_way_size * mips_pdcache_ways; 871 mips_pdcache_way_mask = mips_pdcache_way_size - 1; 872 break; 873 } 874 875 /* figure out Icache params. */ 876 switch (MIPSNN_GET(CFG1_IL, cfg1)) { 877 case MIPSNN_CFG1_IL_NONE: 878 mips_picache_line_size = mips_picache_way_size = 879 mips_picache_ways = 0; 880 break; 881 case MIPSNN_CFG1_IL_RSVD: 882 panic("reserved MIPS32/64 Icache line size"); 883 break; 884 default: 885 if (MIPSNN_GET(CFG1_IS, cfg1) == MIPSNN_CFG1_IS_RSVD) 886 panic("reserved MIPS32/64 Icache sets per way"); 887 mips_picache_line_size = MIPSNN_CFG1_IL(cfg1); 888 mips_picache_way_size = 889 mips_picache_line_size * MIPSNN_CFG1_IS(cfg1); 890 mips_picache_ways = MIPSNN_CFG1_IA(cfg1) + 1; 891 892 /* 893 * Compute the total size and "way mask" for the 894 * primary Dcache. 895 */ 896 mips_picache_size = 897 mips_picache_way_size * mips_picache_ways; 898 mips_picache_way_mask = mips_picache_way_size - 1; 899 break; 900 } 901 902 #define CACHE_DEBUG 903 #ifdef CACHE_DEBUG 904 printf("MIPS32/64 params: cpu arch: %d\n", cpu_arch); 905 printf("MIPS32/64 params: TLB entries: %d\n", mips_num_tlb_entries); 906 if (mips_picache_line_size == 0) 907 printf("MIPS32/64 params: no Icache\n"); 908 else { 909 printf("MIPS32/64 params: Icache: line = %d, total = %d, " 910 "ways = %d\n", mips_picache_line_size, 911 mips_picache_way_size * mips_picache_ways, 912 mips_picache_ways); 913 printf("\t\t sets = %d\n", (mips_picache_way_size * 914 mips_picache_ways / mips_picache_line_size) / 915 mips_picache_ways); 916 } 917 if (mips_pdcache_line_size == 0) 918 printf("MIPS32/64 params: no Dcache\n"); 919 else { 920 printf("MIPS32/64 params: Dcache: line = %d, total = %d, " 921 "ways = %d\n", mips_pdcache_line_size, 922 mips_pdcache_way_size * mips_pdcache_ways, 923 mips_pdcache_ways); 924 printf("\t\t sets = %d\n", (mips_pdcache_way_size * 925 mips_pdcache_ways / mips_pdcache_line_size) / 926 mips_pdcache_ways); 927 } 928 #endif /* CACHE_DEBUG */ 929 930 switch (mips_picache_line_size) { 931 case 16: 932 mips_cache_ops.mco_icache_sync_all = mipsNN_icache_sync_all_16; 933 mips_cache_ops.mco_icache_sync_range = 934 mipsNN_icache_sync_range_16; 935 switch (mips_picache_ways) { 936 case 2: 937 mips_cache_ops.mco_icache_sync_range_index = 938 mipsNN_icache_sync_range_index_16_2way; 939 break; 940 case 4: 941 mips_cache_ops.mco_icache_sync_range_index = 942 mipsNN_icache_sync_range_index_16_4way; 943 break; 944 default: 945 panic("no %d-way Icache ops", mips_picache_ways); 946 } 947 break; 948 case 32: 949 mips_cache_ops.mco_icache_sync_all = mipsNN_icache_sync_all_32; 950 mips_cache_ops.mco_icache_sync_range = 951 mipsNN_icache_sync_range_32; 952 switch (mips_picache_ways) { 953 case 2: 954 mips_cache_ops.mco_icache_sync_range_index = 955 mipsNN_icache_sync_range_index_32_2way; 956 break; 957 case 4: 958 mips_cache_ops.mco_icache_sync_range_index = 959 mipsNN_icache_sync_range_index_32_4way; 960 break; 961 default: 962 panic("no %d-way Icache ops", mips_picache_ways); 963 } 964 break; 965 #ifdef MIPS_DISABLE_L1_CACHE 966 case 0: 967 mips_cache_ops.mco_icache_sync_all = (void *)cache_noop; 968 mips_cache_ops.mco_icache_sync_range = (void *)cache_noop; 969 mips_cache_ops.mco_icache_sync_range_index = (void *)cache_noop; 970 break; 971 #endif 972 default: 973 panic("no Icache ops for %d byte lines", 974 mips_picache_line_size); 975 } 976 977 switch (mips_pdcache_line_size) { 978 case 16: 979 mips_cache_ops.mco_pdcache_wbinv_all = 980 mipsNN_pdcache_wbinv_all_16; 981 mips_cache_ops.mco_pdcache_wbinv_range = 982 mipsNN_pdcache_wbinv_range_16; 983 switch (mips_pdcache_ways) { 984 case 2: 985 mips_cache_ops.mco_pdcache_wbinv_range_index = 986 mipsNN_pdcache_wbinv_range_index_16_2way; 987 break; 988 case 4: 989 mips_cache_ops.mco_pdcache_wbinv_range_index = 990 mipsNN_pdcache_wbinv_range_index_16_4way; 991 break; 992 default: 993 panic("no %d-way Dcache ops", mips_pdcache_ways); 994 } 995 mips_cache_ops.mco_pdcache_inv_range = 996 mipsNN_pdcache_inv_range_16; 997 mips_cache_ops.mco_pdcache_wb_range = 998 mipsNN_pdcache_wb_range_16; 999 break; 1000 case 32: 1001 mips_cache_ops.mco_pdcache_wbinv_all = 1002 mipsNN_pdcache_wbinv_all_32; 1003 mips_cache_ops.mco_pdcache_wbinv_range = 1004 mipsNN_pdcache_wbinv_range_32; 1005 switch (mips_pdcache_ways) { 1006 case 2: 1007 mips_cache_ops.mco_pdcache_wbinv_range_index = 1008 mipsNN_pdcache_wbinv_range_index_32_2way; 1009 break; 1010 case 4: 1011 mips_cache_ops.mco_pdcache_wbinv_range_index = 1012 mipsNN_pdcache_wbinv_range_index_32_4way; 1013 break; 1014 default: 1015 panic("no %d-way Dcache ops", mips_pdcache_ways); 1016 } 1017 mips_cache_ops.mco_pdcache_inv_range = 1018 mipsNN_pdcache_inv_range_32; 1019 mips_cache_ops.mco_pdcache_wb_range = 1020 mipsNN_pdcache_wb_range_32; 1021 break; 1022 #ifdef MIPS_DISABLE_L1_CACHE 1023 case 0: 1024 mips_cache_ops.mco_pdcache_wbinv_all = (void *)cache_noop; 1025 mips_cache_ops.mco_pdcache_wbinv_range = (void *)cache_noop; 1026 mips_cache_ops.mco_pdcache_wbinv_range_index = 1027 (void *)cache_noop; 1028 mips_cache_ops.mco_pdcache_inv_range = (void *)cache_noop; 1029 mips_cache_ops.mco_pdcache_wb_range = (void *)cache_noop; 1030 break; 1031 #endif 1032 default: 1033 panic("no Dcache ops for %d byte lines", 1034 mips_pdcache_line_size); 1035 } 1036 } 1037 #endif /* MIPS32 || MIPS64 */ 1038