cpufunc.c revision 212825
1/* $NetBSD: cpufunc.c,v 1.65 2003/11/05 12:53:15 scw Exp $ */ 2 3/*- 4 * arm7tdmi support code Copyright (c) 2001 John Fremlin 5 * arm8 support code Copyright (c) 1997 ARM Limited 6 * arm8 support code Copyright (c) 1997 Causality Limited 7 * arm9 support code Copyright (C) 2001 ARM Ltd 8 * Copyright (c) 1997 Mark Brinicombe. 9 * Copyright (c) 1997 Causality Limited 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. All advertising materials mentioning features or use of this software 21 * must display the following acknowledgement: 22 * This product includes software developed by Causality Limited. 23 * 4. The name of Causality Limited may not be used to endorse or promote 24 * products derived from this software without specific prior written 25 * permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY CAUSALITY LIMITED ``AS IS'' AND ANY EXPRESS 28 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 29 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 30 * DISCLAIMED. IN NO EVENT SHALL CAUSALITY LIMITED BE LIABLE FOR ANY DIRECT, 31 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 32 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 33 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 * SUCH DAMAGE. 38 * 39 * RiscBSD kernel project 40 * 41 * cpufuncs.c 42 * 43 * C functions for supporting CPU / MMU / TLB specific operations. 44 * 45 * Created : 30/01/97 46 */ 47#include <sys/cdefs.h> 48__FBSDID("$FreeBSD: head/sys/arm/arm/cpufunc.c 212825 2010-09-18 16:57:05Z mav $"); 49 50#include <sys/param.h> 51#include <sys/systm.h> 52#include <sys/lock.h> 53#include <sys/mutex.h> 54#include <sys/bus.h> 55#include <machine/bus.h> 56#include <machine/cpu.h> 57#include <machine/disassem.h> 58 59#include <vm/vm.h> 60#include <vm/pmap.h> 61#include <vm/uma.h> 62 63#include <machine/cpuconf.h> 64#include <machine/cpufunc.h> 65#include <machine/bootconfig.h> 66 67#ifdef CPU_XSCALE_80200 68#include <arm/xscale/i80200/i80200reg.h> 69#include <arm/xscale/i80200/i80200var.h> 70#endif 71 72#if defined(CPU_XSCALE_80321) || defined(CPU_XSCALE_80219) 73#include <arm/xscale/i80321/i80321reg.h> 74#include <arm/xscale/i80321/i80321var.h> 75#endif 76 77#if defined(CPU_XSCALE_81342) 78#include <arm/xscale/i8134x/i81342reg.h> 79#endif 80 81#ifdef CPU_XSCALE_IXP425 82#include <arm/xscale/ixp425/ixp425reg.h> 83#include <arm/xscale/ixp425/ixp425var.h> 84#endif 85 86/* PRIMARY CACHE VARIABLES */ 87int arm_picache_size; 88int arm_picache_line_size; 89int arm_picache_ways; 90 91int arm_pdcache_size; /* and unified */ 92int arm_pdcache_line_size; 93int arm_pdcache_ways; 94 95int arm_pcache_type; 96int arm_pcache_unified; 97 98int arm_dcache_align; 99int arm_dcache_align_mask; 100 101/* 1 == use cpu_sleep(), 0 == don't */ 102int cpu_do_powersave; 103int ctrl; 104 105#ifdef CPU_ARM7TDMI 106struct cpu_functions arm7tdmi_cpufuncs = { 107 /* CPU functions */ 108 109 cpufunc_id, /* id */ 110 cpufunc_nullop, /* cpwait */ 111 112 /* MMU functions */ 113 114 cpufunc_control, /* control */ 115 cpufunc_domains, /* domain */ 116 arm7tdmi_setttb, /* setttb */ 117 cpufunc_faultstatus, /* faultstatus */ 118 cpufunc_faultaddress, /* faultaddress */ 119 120 /* TLB functions */ 121 122 arm7tdmi_tlb_flushID, /* tlb_flushID */ 123 arm7tdmi_tlb_flushID_SE, /* tlb_flushID_SE */ 124 arm7tdmi_tlb_flushID, /* tlb_flushI */ 125 arm7tdmi_tlb_flushID_SE, /* tlb_flushI_SE */ 126 arm7tdmi_tlb_flushID, /* tlb_flushD */ 127 arm7tdmi_tlb_flushID_SE, /* tlb_flushD_SE */ 128 129 /* Cache operations */ 130 131 cpufunc_nullop, /* icache_sync_all */ 132 (void *)cpufunc_nullop, /* icache_sync_range */ 133 134 arm7tdmi_cache_flushID, /* dcache_wbinv_all */ 135 (void *)arm7tdmi_cache_flushID, /* dcache_wbinv_range */ 136 (void *)arm7tdmi_cache_flushID, /* dcache_inv_range */ 137 (void *)cpufunc_nullop, /* dcache_wb_range */ 138 139 arm7tdmi_cache_flushID, /* idcache_wbinv_all */ 140 (void *)arm7tdmi_cache_flushID, /* idcache_wbinv_range */ 141 cpufunc_nullop, /* l2cache_wbinv_all */ 142 (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 143 (void *)cpufunc_nullop, /* l2cache_inv_range */ 144 (void *)cpufunc_nullop, /* l2cache_wb_range */ 145 146 /* Other functions */ 147 148 cpufunc_nullop, /* flush_prefetchbuf */ 149 cpufunc_nullop, /* drain_writebuf */ 150 cpufunc_nullop, /* flush_brnchtgt_C */ 151 (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 152 153 (void *)cpufunc_nullop, /* sleep */ 154 155 /* Soft functions */ 156 157 late_abort_fixup, /* dataabt_fixup */ 158 cpufunc_null_fixup, /* prefetchabt_fixup */ 159 160 arm7tdmi_context_switch, /* context_switch */ 161 162 arm7tdmi_setup /* cpu setup */ 163 164}; 165#endif /* CPU_ARM7TDMI */ 166 167#ifdef CPU_ARM8 168struct cpu_functions arm8_cpufuncs = { 169 /* CPU functions */ 170 171 cpufunc_id, /* id */ 172 cpufunc_nullop, /* cpwait */ 173 174 /* MMU functions */ 175 176 cpufunc_control, /* control */ 177 cpufunc_domains, /* domain */ 178 arm8_setttb, /* setttb */ 179 cpufunc_faultstatus, /* faultstatus */ 180 cpufunc_faultaddress, /* faultaddress */ 181 182 /* TLB functions */ 183 184 arm8_tlb_flushID, /* tlb_flushID */ 185 arm8_tlb_flushID_SE, /* tlb_flushID_SE */ 186 arm8_tlb_flushID, /* tlb_flushI */ 187 arm8_tlb_flushID_SE, /* tlb_flushI_SE */ 188 arm8_tlb_flushID, /* tlb_flushD */ 189 arm8_tlb_flushID_SE, /* tlb_flushD_SE */ 190 191 /* Cache operations */ 192 193 cpufunc_nullop, /* icache_sync_all */ 194 (void *)cpufunc_nullop, /* icache_sync_range */ 195 196 arm8_cache_purgeID, /* dcache_wbinv_all */ 197 (void *)arm8_cache_purgeID, /* dcache_wbinv_range */ 198/*XXX*/ (void *)arm8_cache_purgeID, /* dcache_inv_range */ 199 (void *)arm8_cache_cleanID, /* dcache_wb_range */ 200 201 arm8_cache_purgeID, /* idcache_wbinv_all */ 202 (void *)arm8_cache_purgeID, /* idcache_wbinv_range */ 203 cpufunc_nullop, /* l2cache_wbinv_all */ 204 (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 205 (void *)cpufunc_nullop, /* l2cache_inv_range */ 206 (void *)cpufunc_nullop, /* l2cache_wb_range */ 207 208 /* Other functions */ 209 210 cpufunc_nullop, /* flush_prefetchbuf */ 211 cpufunc_nullop, /* drain_writebuf */ 212 cpufunc_nullop, /* flush_brnchtgt_C */ 213 (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 214 215 (void *)cpufunc_nullop, /* sleep */ 216 217 /* Soft functions */ 218 219 cpufunc_null_fixup, /* dataabt_fixup */ 220 cpufunc_null_fixup, /* prefetchabt_fixup */ 221 222 arm8_context_switch, /* context_switch */ 223 224 arm8_setup /* cpu setup */ 225}; 226#endif /* CPU_ARM8 */ 227 228#ifdef CPU_ARM9 229struct cpu_functions arm9_cpufuncs = { 230 /* CPU functions */ 231 232 cpufunc_id, /* id */ 233 cpufunc_nullop, /* cpwait */ 234 235 /* MMU functions */ 236 237 cpufunc_control, /* control */ 238 cpufunc_domains, /* Domain */ 239 arm9_setttb, /* Setttb */ 240 cpufunc_faultstatus, /* Faultstatus */ 241 cpufunc_faultaddress, /* Faultaddress */ 242 243 /* TLB functions */ 244 245 armv4_tlb_flushID, /* tlb_flushID */ 246 arm9_tlb_flushID_SE, /* tlb_flushID_SE */ 247 armv4_tlb_flushI, /* tlb_flushI */ 248 (void *)armv4_tlb_flushI, /* tlb_flushI_SE */ 249 armv4_tlb_flushD, /* tlb_flushD */ 250 armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 251 252 /* Cache operations */ 253 254 arm9_icache_sync_all, /* icache_sync_all */ 255 arm9_icache_sync_range, /* icache_sync_range */ 256 257 arm9_dcache_wbinv_all, /* dcache_wbinv_all */ 258 arm9_dcache_wbinv_range, /* dcache_wbinv_range */ 259 arm9_dcache_inv_range, /* dcache_inv_range */ 260 arm9_dcache_wb_range, /* dcache_wb_range */ 261 262 arm9_idcache_wbinv_all, /* idcache_wbinv_all */ 263 arm9_idcache_wbinv_range, /* idcache_wbinv_range */ 264 cpufunc_nullop, /* l2cache_wbinv_all */ 265 (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 266 (void *)cpufunc_nullop, /* l2cache_inv_range */ 267 (void *)cpufunc_nullop, /* l2cache_wb_range */ 268 269 /* Other functions */ 270 271 cpufunc_nullop, /* flush_prefetchbuf */ 272 armv4_drain_writebuf, /* drain_writebuf */ 273 cpufunc_nullop, /* flush_brnchtgt_C */ 274 (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 275 276 (void *)cpufunc_nullop, /* sleep */ 277 278 /* Soft functions */ 279 280 cpufunc_null_fixup, /* dataabt_fixup */ 281 cpufunc_null_fixup, /* prefetchabt_fixup */ 282 283 arm9_context_switch, /* context_switch */ 284 285 arm9_setup /* cpu setup */ 286 287}; 288#endif /* CPU_ARM9 */ 289 290#if defined(CPU_ARM9E) || defined(CPU_ARM10) 291struct cpu_functions armv5_ec_cpufuncs = { 292 /* CPU functions */ 293 294 cpufunc_id, /* id */ 295 cpufunc_nullop, /* cpwait */ 296 297 /* MMU functions */ 298 299 cpufunc_control, /* control */ 300 cpufunc_domains, /* Domain */ 301 armv5_ec_setttb, /* Setttb */ 302 cpufunc_faultstatus, /* Faultstatus */ 303 cpufunc_faultaddress, /* Faultaddress */ 304 305 /* TLB functions */ 306 307 armv4_tlb_flushID, /* tlb_flushID */ 308 arm10_tlb_flushID_SE, /* tlb_flushID_SE */ 309 armv4_tlb_flushI, /* tlb_flushI */ 310 arm10_tlb_flushI_SE, /* tlb_flushI_SE */ 311 armv4_tlb_flushD, /* tlb_flushD */ 312 armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 313 314 /* Cache operations */ 315 316 armv5_ec_icache_sync_all, /* icache_sync_all */ 317 armv5_ec_icache_sync_range, /* icache_sync_range */ 318 319 armv5_ec_dcache_wbinv_all, /* dcache_wbinv_all */ 320 armv5_ec_dcache_wbinv_range, /* dcache_wbinv_range */ 321 armv5_ec_dcache_inv_range, /* dcache_inv_range */ 322 armv5_ec_dcache_wb_range, /* dcache_wb_range */ 323 324 armv5_ec_idcache_wbinv_all, /* idcache_wbinv_all */ 325 armv5_ec_idcache_wbinv_range, /* idcache_wbinv_range */ 326 327 cpufunc_nullop, /* l2cache_wbinv_all */ 328 (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 329 (void *)cpufunc_nullop, /* l2cache_inv_range */ 330 (void *)cpufunc_nullop, /* l2cache_wb_range */ 331 332 /* Other functions */ 333 334 cpufunc_nullop, /* flush_prefetchbuf */ 335 armv4_drain_writebuf, /* drain_writebuf */ 336 cpufunc_nullop, /* flush_brnchtgt_C */ 337 (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 338 339 (void *)cpufunc_nullop, /* sleep */ 340 341 /* Soft functions */ 342 343 cpufunc_null_fixup, /* dataabt_fixup */ 344 cpufunc_null_fixup, /* prefetchabt_fixup */ 345 346 arm10_context_switch, /* context_switch */ 347 348 arm10_setup /* cpu setup */ 349 350}; 351 352struct cpu_functions sheeva_cpufuncs = { 353 /* CPU functions */ 354 355 cpufunc_id, /* id */ 356 cpufunc_nullop, /* cpwait */ 357 358 /* MMU functions */ 359 360 cpufunc_control, /* control */ 361 cpufunc_domains, /* Domain */ 362 sheeva_setttb, /* Setttb */ 363 cpufunc_faultstatus, /* Faultstatus */ 364 cpufunc_faultaddress, /* Faultaddress */ 365 366 /* TLB functions */ 367 368 armv4_tlb_flushID, /* tlb_flushID */ 369 arm10_tlb_flushID_SE, /* tlb_flushID_SE */ 370 armv4_tlb_flushI, /* tlb_flushI */ 371 arm10_tlb_flushI_SE, /* tlb_flushI_SE */ 372 armv4_tlb_flushD, /* tlb_flushD */ 373 armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 374 375 /* Cache operations */ 376 377 armv5_ec_icache_sync_all, /* icache_sync_all */ 378 armv5_ec_icache_sync_range, /* icache_sync_range */ 379 380 armv5_ec_dcache_wbinv_all, /* dcache_wbinv_all */ 381 sheeva_dcache_wbinv_range, /* dcache_wbinv_range */ 382 sheeva_dcache_inv_range, /* dcache_inv_range */ 383 sheeva_dcache_wb_range, /* dcache_wb_range */ 384 385 armv5_ec_idcache_wbinv_all, /* idcache_wbinv_all */ 386 sheeva_idcache_wbinv_range, /* idcache_wbinv_all */ 387 388 sheeva_l2cache_wbinv_all, /* l2cache_wbinv_all */ 389 sheeva_l2cache_wbinv_range, /* l2cache_wbinv_range */ 390 sheeva_l2cache_inv_range, /* l2cache_inv_range */ 391 sheeva_l2cache_wb_range, /* l2cache_wb_range */ 392 393 /* Other functions */ 394 395 cpufunc_nullop, /* flush_prefetchbuf */ 396 armv4_drain_writebuf, /* drain_writebuf */ 397 cpufunc_nullop, /* flush_brnchtgt_C */ 398 (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 399 400 sheeva_cpu_sleep, /* sleep */ 401 402 /* Soft functions */ 403 404 cpufunc_null_fixup, /* dataabt_fixup */ 405 cpufunc_null_fixup, /* prefetchabt_fixup */ 406 407 arm10_context_switch, /* context_switch */ 408 409 arm10_setup /* cpu setup */ 410}; 411#endif /* CPU_ARM9E || CPU_ARM10 */ 412 413#ifdef CPU_ARM10 414struct cpu_functions arm10_cpufuncs = { 415 /* CPU functions */ 416 417 cpufunc_id, /* id */ 418 cpufunc_nullop, /* cpwait */ 419 420 /* MMU functions */ 421 422 cpufunc_control, /* control */ 423 cpufunc_domains, /* Domain */ 424 arm10_setttb, /* Setttb */ 425 cpufunc_faultstatus, /* Faultstatus */ 426 cpufunc_faultaddress, /* Faultaddress */ 427 428 /* TLB functions */ 429 430 armv4_tlb_flushID, /* tlb_flushID */ 431 arm10_tlb_flushID_SE, /* tlb_flushID_SE */ 432 armv4_tlb_flushI, /* tlb_flushI */ 433 arm10_tlb_flushI_SE, /* tlb_flushI_SE */ 434 armv4_tlb_flushD, /* tlb_flushD */ 435 armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 436 437 /* Cache operations */ 438 439 arm10_icache_sync_all, /* icache_sync_all */ 440 arm10_icache_sync_range, /* icache_sync_range */ 441 442 arm10_dcache_wbinv_all, /* dcache_wbinv_all */ 443 arm10_dcache_wbinv_range, /* dcache_wbinv_range */ 444 arm10_dcache_inv_range, /* dcache_inv_range */ 445 arm10_dcache_wb_range, /* dcache_wb_range */ 446 447 arm10_idcache_wbinv_all, /* idcache_wbinv_all */ 448 arm10_idcache_wbinv_range, /* idcache_wbinv_range */ 449 cpufunc_nullop, /* l2cache_wbinv_all */ 450 (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 451 (void *)cpufunc_nullop, /* l2cache_inv_range */ 452 (void *)cpufunc_nullop, /* l2cache_wb_range */ 453 454 /* Other functions */ 455 456 cpufunc_nullop, /* flush_prefetchbuf */ 457 armv4_drain_writebuf, /* drain_writebuf */ 458 cpufunc_nullop, /* flush_brnchtgt_C */ 459 (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 460 461 (void *)cpufunc_nullop, /* sleep */ 462 463 /* Soft functions */ 464 465 cpufunc_null_fixup, /* dataabt_fixup */ 466 cpufunc_null_fixup, /* prefetchabt_fixup */ 467 468 arm10_context_switch, /* context_switch */ 469 470 arm10_setup /* cpu setup */ 471 472}; 473#endif /* CPU_ARM10 */ 474 475#ifdef CPU_SA110 476struct cpu_functions sa110_cpufuncs = { 477 /* CPU functions */ 478 479 cpufunc_id, /* id */ 480 cpufunc_nullop, /* cpwait */ 481 482 /* MMU functions */ 483 484 cpufunc_control, /* control */ 485 cpufunc_domains, /* domain */ 486 sa1_setttb, /* setttb */ 487 cpufunc_faultstatus, /* faultstatus */ 488 cpufunc_faultaddress, /* faultaddress */ 489 490 /* TLB functions */ 491 492 armv4_tlb_flushID, /* tlb_flushID */ 493 sa1_tlb_flushID_SE, /* tlb_flushID_SE */ 494 armv4_tlb_flushI, /* tlb_flushI */ 495 (void *)armv4_tlb_flushI, /* tlb_flushI_SE */ 496 armv4_tlb_flushD, /* tlb_flushD */ 497 armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 498 499 /* Cache operations */ 500 501 sa1_cache_syncI, /* icache_sync_all */ 502 sa1_cache_syncI_rng, /* icache_sync_range */ 503 504 sa1_cache_purgeD, /* dcache_wbinv_all */ 505 sa1_cache_purgeD_rng, /* dcache_wbinv_range */ 506/*XXX*/ sa1_cache_purgeD_rng, /* dcache_inv_range */ 507 sa1_cache_cleanD_rng, /* dcache_wb_range */ 508 509 sa1_cache_purgeID, /* idcache_wbinv_all */ 510 sa1_cache_purgeID_rng, /* idcache_wbinv_range */ 511 cpufunc_nullop, /* l2cache_wbinv_all */ 512 (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 513 (void *)cpufunc_nullop, /* l2cache_inv_range */ 514 (void *)cpufunc_nullop, /* l2cache_wb_range */ 515 516 /* Other functions */ 517 518 cpufunc_nullop, /* flush_prefetchbuf */ 519 armv4_drain_writebuf, /* drain_writebuf */ 520 cpufunc_nullop, /* flush_brnchtgt_C */ 521 (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 522 523 (void *)cpufunc_nullop, /* sleep */ 524 525 /* Soft functions */ 526 527 cpufunc_null_fixup, /* dataabt_fixup */ 528 cpufunc_null_fixup, /* prefetchabt_fixup */ 529 530 sa110_context_switch, /* context_switch */ 531 532 sa110_setup /* cpu setup */ 533}; 534#endif /* CPU_SA110 */ 535 536#if defined(CPU_SA1100) || defined(CPU_SA1110) 537struct cpu_functions sa11x0_cpufuncs = { 538 /* CPU functions */ 539 540 cpufunc_id, /* id */ 541 cpufunc_nullop, /* cpwait */ 542 543 /* MMU functions */ 544 545 cpufunc_control, /* control */ 546 cpufunc_domains, /* domain */ 547 sa1_setttb, /* setttb */ 548 cpufunc_faultstatus, /* faultstatus */ 549 cpufunc_faultaddress, /* faultaddress */ 550 551 /* TLB functions */ 552 553 armv4_tlb_flushID, /* tlb_flushID */ 554 sa1_tlb_flushID_SE, /* tlb_flushID_SE */ 555 armv4_tlb_flushI, /* tlb_flushI */ 556 (void *)armv4_tlb_flushI, /* tlb_flushI_SE */ 557 armv4_tlb_flushD, /* tlb_flushD */ 558 armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 559 560 /* Cache operations */ 561 562 sa1_cache_syncI, /* icache_sync_all */ 563 sa1_cache_syncI_rng, /* icache_sync_range */ 564 565 sa1_cache_purgeD, /* dcache_wbinv_all */ 566 sa1_cache_purgeD_rng, /* dcache_wbinv_range */ 567/*XXX*/ sa1_cache_purgeD_rng, /* dcache_inv_range */ 568 sa1_cache_cleanD_rng, /* dcache_wb_range */ 569 570 sa1_cache_purgeID, /* idcache_wbinv_all */ 571 sa1_cache_purgeID_rng, /* idcache_wbinv_range */ 572 cpufunc_nullop, /* l2cache_wbinv_all */ 573 (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 574 (void *)cpufunc_nullop, /* l2cache_inv_range */ 575 (void *)cpufunc_nullop, /* l2cache_wb_range */ 576 577 /* Other functions */ 578 579 sa11x0_drain_readbuf, /* flush_prefetchbuf */ 580 armv4_drain_writebuf, /* drain_writebuf */ 581 cpufunc_nullop, /* flush_brnchtgt_C */ 582 (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 583 584 sa11x0_cpu_sleep, /* sleep */ 585 586 /* Soft functions */ 587 588 cpufunc_null_fixup, /* dataabt_fixup */ 589 cpufunc_null_fixup, /* prefetchabt_fixup */ 590 591 sa11x0_context_switch, /* context_switch */ 592 593 sa11x0_setup /* cpu setup */ 594}; 595#endif /* CPU_SA1100 || CPU_SA1110 */ 596 597#ifdef CPU_IXP12X0 598struct cpu_functions ixp12x0_cpufuncs = { 599 /* CPU functions */ 600 601 cpufunc_id, /* id */ 602 cpufunc_nullop, /* cpwait */ 603 604 /* MMU functions */ 605 606 cpufunc_control, /* control */ 607 cpufunc_domains, /* domain */ 608 sa1_setttb, /* setttb */ 609 cpufunc_faultstatus, /* faultstatus */ 610 cpufunc_faultaddress, /* faultaddress */ 611 612 /* TLB functions */ 613 614 armv4_tlb_flushID, /* tlb_flushID */ 615 sa1_tlb_flushID_SE, /* tlb_flushID_SE */ 616 armv4_tlb_flushI, /* tlb_flushI */ 617 (void *)armv4_tlb_flushI, /* tlb_flushI_SE */ 618 armv4_tlb_flushD, /* tlb_flushD */ 619 armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 620 621 /* Cache operations */ 622 623 sa1_cache_syncI, /* icache_sync_all */ 624 sa1_cache_syncI_rng, /* icache_sync_range */ 625 626 sa1_cache_purgeD, /* dcache_wbinv_all */ 627 sa1_cache_purgeD_rng, /* dcache_wbinv_range */ 628/*XXX*/ sa1_cache_purgeD_rng, /* dcache_inv_range */ 629 sa1_cache_cleanD_rng, /* dcache_wb_range */ 630 631 sa1_cache_purgeID, /* idcache_wbinv_all */ 632 sa1_cache_purgeID_rng, /* idcache_wbinv_range */ 633 cpufunc_nullop, /* l2cache_wbinv_all */ 634 (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 635 (void *)cpufunc_nullop, /* l2cache_inv_range */ 636 (void *)cpufunc_nullop, /* l2cache_wb_range */ 637 638 /* Other functions */ 639 640 ixp12x0_drain_readbuf, /* flush_prefetchbuf */ 641 armv4_drain_writebuf, /* drain_writebuf */ 642 cpufunc_nullop, /* flush_brnchtgt_C */ 643 (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 644 645 (void *)cpufunc_nullop, /* sleep */ 646 647 /* Soft functions */ 648 649 cpufunc_null_fixup, /* dataabt_fixup */ 650 cpufunc_null_fixup, /* prefetchabt_fixup */ 651 652 ixp12x0_context_switch, /* context_switch */ 653 654 ixp12x0_setup /* cpu setup */ 655}; 656#endif /* CPU_IXP12X0 */ 657 658#if defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \ 659 defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \ 660 defined(CPU_XSCALE_80219) 661 662struct cpu_functions xscale_cpufuncs = { 663 /* CPU functions */ 664 665 cpufunc_id, /* id */ 666 xscale_cpwait, /* cpwait */ 667 668 /* MMU functions */ 669 670 xscale_control, /* control */ 671 cpufunc_domains, /* domain */ 672 xscale_setttb, /* setttb */ 673 cpufunc_faultstatus, /* faultstatus */ 674 cpufunc_faultaddress, /* faultaddress */ 675 676 /* TLB functions */ 677 678 armv4_tlb_flushID, /* tlb_flushID */ 679 xscale_tlb_flushID_SE, /* tlb_flushID_SE */ 680 armv4_tlb_flushI, /* tlb_flushI */ 681 (void *)armv4_tlb_flushI, /* tlb_flushI_SE */ 682 armv4_tlb_flushD, /* tlb_flushD */ 683 armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 684 685 /* Cache operations */ 686 687 xscale_cache_syncI, /* icache_sync_all */ 688 xscale_cache_syncI_rng, /* icache_sync_range */ 689 690 xscale_cache_purgeD, /* dcache_wbinv_all */ 691 xscale_cache_purgeD_rng, /* dcache_wbinv_range */ 692 xscale_cache_flushD_rng, /* dcache_inv_range */ 693 xscale_cache_cleanD_rng, /* dcache_wb_range */ 694 695 xscale_cache_purgeID, /* idcache_wbinv_all */ 696 xscale_cache_purgeID_rng, /* idcache_wbinv_range */ 697 cpufunc_nullop, /* l2cache_wbinv_all */ 698 (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 699 (void *)cpufunc_nullop, /* l2cache_inv_range */ 700 (void *)cpufunc_nullop, /* l2cache_wb_range */ 701 702 /* Other functions */ 703 704 cpufunc_nullop, /* flush_prefetchbuf */ 705 armv4_drain_writebuf, /* drain_writebuf */ 706 cpufunc_nullop, /* flush_brnchtgt_C */ 707 (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 708 709 xscale_cpu_sleep, /* sleep */ 710 711 /* Soft functions */ 712 713 cpufunc_null_fixup, /* dataabt_fixup */ 714 cpufunc_null_fixup, /* prefetchabt_fixup */ 715 716 xscale_context_switch, /* context_switch */ 717 718 xscale_setup /* cpu setup */ 719}; 720#endif 721/* CPU_XSCALE_80200 || CPU_XSCALE_80321 || CPU_XSCALE_PXA2X0 || CPU_XSCALE_IXP425 722 CPU_XSCALE_80219 */ 723 724#ifdef CPU_XSCALE_81342 725struct cpu_functions xscalec3_cpufuncs = { 726 /* CPU functions */ 727 728 cpufunc_id, /* id */ 729 xscale_cpwait, /* cpwait */ 730 731 /* MMU functions */ 732 733 xscale_control, /* control */ 734 cpufunc_domains, /* domain */ 735 xscalec3_setttb, /* setttb */ 736 cpufunc_faultstatus, /* faultstatus */ 737 cpufunc_faultaddress, /* faultaddress */ 738 739 /* TLB functions */ 740 741 armv4_tlb_flushID, /* tlb_flushID */ 742 xscale_tlb_flushID_SE, /* tlb_flushID_SE */ 743 armv4_tlb_flushI, /* tlb_flushI */ 744 (void *)armv4_tlb_flushI, /* tlb_flushI_SE */ 745 armv4_tlb_flushD, /* tlb_flushD */ 746 armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 747 748 /* Cache operations */ 749 750 xscalec3_cache_syncI, /* icache_sync_all */ 751 xscalec3_cache_syncI_rng, /* icache_sync_range */ 752 753 xscalec3_cache_purgeD, /* dcache_wbinv_all */ 754 xscalec3_cache_purgeD_rng, /* dcache_wbinv_range */ 755 xscale_cache_flushD_rng, /* dcache_inv_range */ 756 xscalec3_cache_cleanD_rng, /* dcache_wb_range */ 757 758 xscalec3_cache_purgeID, /* idcache_wbinv_all */ 759 xscalec3_cache_purgeID_rng, /* idcache_wbinv_range */ 760 xscalec3_l2cache_purge, /* l2cache_wbinv_all */ 761 xscalec3_l2cache_purge_rng, /* l2cache_wbinv_range */ 762 xscalec3_l2cache_flush_rng, /* l2cache_inv_range */ 763 xscalec3_l2cache_clean_rng, /* l2cache_wb_range */ 764 765 /* Other functions */ 766 767 cpufunc_nullop, /* flush_prefetchbuf */ 768 armv4_drain_writebuf, /* drain_writebuf */ 769 cpufunc_nullop, /* flush_brnchtgt_C */ 770 (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 771 772 xscale_cpu_sleep, /* sleep */ 773 774 /* Soft functions */ 775 776 cpufunc_null_fixup, /* dataabt_fixup */ 777 cpufunc_null_fixup, /* prefetchabt_fixup */ 778 779 xscalec3_context_switch, /* context_switch */ 780 781 xscale_setup /* cpu setup */ 782}; 783#endif /* CPU_XSCALE_81342 */ 784 785 786#if defined(CPU_FA526) || defined(CPU_FA626TE) 787struct cpu_functions fa526_cpufuncs = { 788 /* CPU functions */ 789 790 cpufunc_id, /* id */ 791 cpufunc_nullop, /* cpwait */ 792 793 /* MMU functions */ 794 795 cpufunc_control, /* control */ 796 cpufunc_domains, /* domain */ 797 fa526_setttb, /* setttb */ 798 cpufunc_faultstatus, /* faultstatus */ 799 cpufunc_faultaddress, /* faultaddress */ 800 801 /* TLB functions */ 802 803 armv4_tlb_flushID, /* tlb_flushID */ 804 fa526_tlb_flushID_SE, /* tlb_flushID_SE */ 805 armv4_tlb_flushI, /* tlb_flushI */ 806 fa526_tlb_flushI_SE, /* tlb_flushI_SE */ 807 armv4_tlb_flushD, /* tlb_flushD */ 808 armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 809 810 /* Cache operations */ 811 812 fa526_icache_sync_all, /* icache_sync_all */ 813 fa526_icache_sync_range, /* icache_sync_range */ 814 815 fa526_dcache_wbinv_all, /* dcache_wbinv_all */ 816 fa526_dcache_wbinv_range, /* dcache_wbinv_range */ 817 fa526_dcache_inv_range, /* dcache_inv_range */ 818 fa526_dcache_wb_range, /* dcache_wb_range */ 819 820 fa526_idcache_wbinv_all, /* idcache_wbinv_all */ 821 fa526_idcache_wbinv_range, /* idcache_wbinv_range */ 822 cpufunc_nullop, /* l2cache_wbinv_all */ 823 (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 824 (void *)cpufunc_nullop, /* l2cache_inv_range */ 825 (void *)cpufunc_nullop, /* l2cache_wb_range */ 826 827 /* Other functions */ 828 829 fa526_flush_prefetchbuf, /* flush_prefetchbuf */ 830 armv4_drain_writebuf, /* drain_writebuf */ 831 cpufunc_nullop, /* flush_brnchtgt_C */ 832 fa526_flush_brnchtgt_E, /* flush_brnchtgt_E */ 833 834 fa526_cpu_sleep, /* sleep */ 835 836 /* Soft functions */ 837 838 cpufunc_null_fixup, /* dataabt_fixup */ 839 cpufunc_null_fixup, /* prefetchabt_fixup */ 840 841 fa526_context_switch, /* context_switch */ 842 843 fa526_setup /* cpu setup */ 844}; 845#endif /* CPU_FA526 || CPU_FA626TE */ 846 847 848/* 849 * Global constants also used by locore.s 850 */ 851 852struct cpu_functions cpufuncs; 853u_int cputype; 854u_int cpu_reset_needs_v4_MMU_disable; /* flag used in locore.s */ 855 856#if defined(CPU_ARM7TDMI) || defined(CPU_ARM8) || defined(CPU_ARM9) || \ 857 defined (CPU_ARM9E) || defined (CPU_ARM10) || \ 858 defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \ 859 defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \ 860 defined(CPU_FA526) || defined(CPU_FA626TE) || \ 861 defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342) 862 863static void get_cachetype_cp15(void); 864 865/* Additional cache information local to this file. Log2 of some of the 866 above numbers. */ 867static int arm_dcache_l2_nsets; 868static int arm_dcache_l2_assoc; 869static int arm_dcache_l2_linesize; 870 871static void 872get_cachetype_cp15() 873{ 874 u_int ctype, isize, dsize; 875 u_int multiplier; 876 877 __asm __volatile("mrc p15, 0, %0, c0, c0, 1" 878 : "=r" (ctype)); 879 880 /* 881 * ...and thus spake the ARM ARM: 882 * 883 * If an <opcode2> value corresponding to an unimplemented or 884 * reserved ID register is encountered, the System Control 885 * processor returns the value of the main ID register. 886 */ 887 if (ctype == cpufunc_id()) 888 goto out; 889 890 if ((ctype & CPU_CT_S) == 0) 891 arm_pcache_unified = 1; 892 893 /* 894 * If you want to know how this code works, go read the ARM ARM. 895 */ 896 897 arm_pcache_type = CPU_CT_CTYPE(ctype); 898 899 if (arm_pcache_unified == 0) { 900 isize = CPU_CT_ISIZE(ctype); 901 multiplier = (isize & CPU_CT_xSIZE_M) ? 3 : 2; 902 arm_picache_line_size = 1U << (CPU_CT_xSIZE_LEN(isize) + 3); 903 if (CPU_CT_xSIZE_ASSOC(isize) == 0) { 904 if (isize & CPU_CT_xSIZE_M) 905 arm_picache_line_size = 0; /* not present */ 906 else 907 arm_picache_ways = 1; 908 } else { 909 arm_picache_ways = multiplier << 910 (CPU_CT_xSIZE_ASSOC(isize) - 1); 911 } 912 arm_picache_size = multiplier << (CPU_CT_xSIZE_SIZE(isize) + 8); 913 } 914 915 dsize = CPU_CT_DSIZE(ctype); 916 multiplier = (dsize & CPU_CT_xSIZE_M) ? 3 : 2; 917 arm_pdcache_line_size = 1U << (CPU_CT_xSIZE_LEN(dsize) + 3); 918 if (CPU_CT_xSIZE_ASSOC(dsize) == 0) { 919 if (dsize & CPU_CT_xSIZE_M) 920 arm_pdcache_line_size = 0; /* not present */ 921 else 922 arm_pdcache_ways = 1; 923 } else { 924 arm_pdcache_ways = multiplier << 925 (CPU_CT_xSIZE_ASSOC(dsize) - 1); 926 } 927 arm_pdcache_size = multiplier << (CPU_CT_xSIZE_SIZE(dsize) + 8); 928 929 arm_dcache_align = arm_pdcache_line_size; 930 931 arm_dcache_l2_assoc = CPU_CT_xSIZE_ASSOC(dsize) + multiplier - 2; 932 arm_dcache_l2_linesize = CPU_CT_xSIZE_LEN(dsize) + 3; 933 arm_dcache_l2_nsets = 6 + CPU_CT_xSIZE_SIZE(dsize) - 934 CPU_CT_xSIZE_ASSOC(dsize) - CPU_CT_xSIZE_LEN(dsize); 935 936 out: 937 arm_dcache_align_mask = arm_dcache_align - 1; 938} 939#endif /* ARM7TDMI || ARM8 || ARM9 || XSCALE */ 940 941#if defined(CPU_SA110) || defined(CPU_SA1100) || defined(CPU_SA1110) || \ 942 defined(CPU_IXP12X0) 943/* Cache information for CPUs without cache type registers. */ 944struct cachetab { 945 u_int32_t ct_cpuid; 946 int ct_pcache_type; 947 int ct_pcache_unified; 948 int ct_pdcache_size; 949 int ct_pdcache_line_size; 950 int ct_pdcache_ways; 951 int ct_picache_size; 952 int ct_picache_line_size; 953 int ct_picache_ways; 954}; 955 956struct cachetab cachetab[] = { 957 /* cpuid, cache type, u, dsiz, ls, wy, isiz, ls, wy */ 958 /* XXX is this type right for SA-1? */ 959 { CPU_ID_SA110, CPU_CT_CTYPE_WB1, 0, 16384, 32, 32, 16384, 32, 32 }, 960 { CPU_ID_SA1100, CPU_CT_CTYPE_WB1, 0, 8192, 32, 32, 16384, 32, 32 }, 961 { CPU_ID_SA1110, CPU_CT_CTYPE_WB1, 0, 8192, 32, 32, 16384, 32, 32 }, 962 { CPU_ID_IXP1200, CPU_CT_CTYPE_WB1, 0, 16384, 32, 32, 16384, 32, 32 }, /* XXX */ 963 { 0, 0, 0, 0, 0, 0, 0, 0} 964}; 965 966static void get_cachetype_table(void); 967 968static void 969get_cachetype_table() 970{ 971 int i; 972 u_int32_t cpuid = cpufunc_id(); 973 974 for (i = 0; cachetab[i].ct_cpuid != 0; i++) { 975 if (cachetab[i].ct_cpuid == (cpuid & CPU_ID_CPU_MASK)) { 976 arm_pcache_type = cachetab[i].ct_pcache_type; 977 arm_pcache_unified = cachetab[i].ct_pcache_unified; 978 arm_pdcache_size = cachetab[i].ct_pdcache_size; 979 arm_pdcache_line_size = 980 cachetab[i].ct_pdcache_line_size; 981 arm_pdcache_ways = cachetab[i].ct_pdcache_ways; 982 arm_picache_size = cachetab[i].ct_picache_size; 983 arm_picache_line_size = 984 cachetab[i].ct_picache_line_size; 985 arm_picache_ways = cachetab[i].ct_picache_ways; 986 } 987 } 988 arm_dcache_align = arm_pdcache_line_size; 989 990 arm_dcache_align_mask = arm_dcache_align - 1; 991} 992 993#endif /* SA110 || SA1100 || SA1111 || IXP12X0 */ 994 995/* 996 * Cannot panic here as we may not have a console yet ... 997 */ 998 999int 1000set_cpufuncs() 1001{ 1002 cputype = cpufunc_id(); 1003 cputype &= CPU_ID_CPU_MASK; 1004 1005 /* 1006 * NOTE: cpu_do_powersave defaults to off. If we encounter a 1007 * CPU type where we want to use it by default, then we set it. 1008 */ 1009 1010#ifdef CPU_ARM7TDMI 1011 if ((cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_ARM_LTD && 1012 CPU_ID_IS7(cputype) && 1013 (cputype & CPU_ID_7ARCH_MASK) == CPU_ID_7ARCH_V4T) { 1014 cpufuncs = arm7tdmi_cpufuncs; 1015 cpu_reset_needs_v4_MMU_disable = 0; 1016 get_cachetype_cp15(); 1017 pmap_pte_init_generic(); 1018 goto out; 1019 } 1020#endif 1021#ifdef CPU_ARM8 1022 if ((cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_ARM_LTD && 1023 (cputype & 0x0000f000) == 0x00008000) { 1024 cpufuncs = arm8_cpufuncs; 1025 cpu_reset_needs_v4_MMU_disable = 0; /* XXX correct? */ 1026 get_cachetype_cp15(); 1027 pmap_pte_init_arm8(); 1028 goto out; 1029 } 1030#endif /* CPU_ARM8 */ 1031#ifdef CPU_ARM9 1032 if (((cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_ARM_LTD || 1033 (cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_TI) && 1034 (cputype & 0x0000f000) == 0x00009000) { 1035 cpufuncs = arm9_cpufuncs; 1036 cpu_reset_needs_v4_MMU_disable = 1; /* V4 or higher */ 1037 get_cachetype_cp15(); 1038 arm9_dcache_sets_inc = 1U << arm_dcache_l2_linesize; 1039 arm9_dcache_sets_max = (1U << (arm_dcache_l2_linesize + 1040 arm_dcache_l2_nsets)) - arm9_dcache_sets_inc; 1041 arm9_dcache_index_inc = 1U << (32 - arm_dcache_l2_assoc); 1042 arm9_dcache_index_max = 0U - arm9_dcache_index_inc; 1043#ifdef ARM9_CACHE_WRITE_THROUGH 1044 pmap_pte_init_arm9(); 1045#else 1046 pmap_pte_init_generic(); 1047#endif 1048 goto out; 1049 } 1050#endif /* CPU_ARM9 */ 1051#if defined(CPU_ARM9E) || defined(CPU_ARM10) 1052 if (cputype == CPU_ID_ARM926EJS || cputype == CPU_ID_ARM1026EJS || 1053 cputype == CPU_ID_MV88FR131 || cputype == CPU_ID_MV88FR571_VD || 1054 cputype == CPU_ID_MV88FR571_41) { 1055 if (cputype == CPU_ID_MV88FR131 || 1056 cputype == CPU_ID_MV88FR571_VD || 1057 cputype == CPU_ID_MV88FR571_41) { 1058 1059 cpufuncs = sheeva_cpufuncs; 1060 /* 1061 * Workaround for Marvell MV78100 CPU: Cache prefetch 1062 * mechanism may affect the cache coherency validity, 1063 * so it needs to be disabled. 1064 * 1065 * Refer to errata document MV-S501058-00C.pdf (p. 3.1 1066 * L2 Prefetching Mechanism) for details. 1067 */ 1068 if (cputype == CPU_ID_MV88FR571_VD || 1069 cputype == CPU_ID_MV88FR571_41) { 1070 sheeva_control_ext(0xffffffff, 1071 FC_DCACHE_STREAM_EN | FC_WR_ALLOC_EN | 1072 FC_BRANCH_TARG_BUF_DIS | FC_L2CACHE_EN | 1073 FC_L2_PREF_DIS); 1074 } else { 1075 sheeva_control_ext(0xffffffff, 1076 FC_DCACHE_STREAM_EN | FC_WR_ALLOC_EN | 1077 FC_BRANCH_TARG_BUF_DIS | FC_L2CACHE_EN); 1078 } 1079 1080 /* Use powersave on this CPU. */ 1081 cpu_do_powersave = 1; 1082 } else 1083 cpufuncs = armv5_ec_cpufuncs; 1084 1085 cpu_reset_needs_v4_MMU_disable = 1; /* V4 or higher */ 1086 get_cachetype_cp15(); 1087 pmap_pte_init_generic(); 1088 goto out; 1089 } 1090#endif /* CPU_ARM9E || CPU_ARM10 */ 1091#ifdef CPU_ARM10 1092 if (/* cputype == CPU_ID_ARM1020T || */ 1093 cputype == CPU_ID_ARM1020E) { 1094 /* 1095 * Select write-through cacheing (this isn't really an 1096 * option on ARM1020T). 1097 */ 1098 cpufuncs = arm10_cpufuncs; 1099 cpu_reset_needs_v4_MMU_disable = 1; /* V4 or higher */ 1100 get_cachetype_cp15(); 1101 arm10_dcache_sets_inc = 1U << arm_dcache_l2_linesize; 1102 arm10_dcache_sets_max = 1103 (1U << (arm_dcache_l2_linesize + arm_dcache_l2_nsets)) - 1104 arm10_dcache_sets_inc; 1105 arm10_dcache_index_inc = 1U << (32 - arm_dcache_l2_assoc); 1106 arm10_dcache_index_max = 0U - arm10_dcache_index_inc; 1107 pmap_pte_init_generic(); 1108 goto out; 1109 } 1110#endif /* CPU_ARM10 */ 1111#ifdef CPU_SA110 1112 if (cputype == CPU_ID_SA110) { 1113 cpufuncs = sa110_cpufuncs; 1114 cpu_reset_needs_v4_MMU_disable = 1; /* SA needs it */ 1115 get_cachetype_table(); 1116 pmap_pte_init_sa1(); 1117 goto out; 1118 } 1119#endif /* CPU_SA110 */ 1120#ifdef CPU_SA1100 1121 if (cputype == CPU_ID_SA1100) { 1122 cpufuncs = sa11x0_cpufuncs; 1123 cpu_reset_needs_v4_MMU_disable = 1; /* SA needs it */ 1124 get_cachetype_table(); 1125 pmap_pte_init_sa1(); 1126 /* Use powersave on this CPU. */ 1127 cpu_do_powersave = 1; 1128 1129 goto out; 1130 } 1131#endif /* CPU_SA1100 */ 1132#ifdef CPU_SA1110 1133 if (cputype == CPU_ID_SA1110) { 1134 cpufuncs = sa11x0_cpufuncs; 1135 cpu_reset_needs_v4_MMU_disable = 1; /* SA needs it */ 1136 get_cachetype_table(); 1137 pmap_pte_init_sa1(); 1138 /* Use powersave on this CPU. */ 1139 cpu_do_powersave = 1; 1140 1141 goto out; 1142 } 1143#endif /* CPU_SA1110 */ 1144#if defined(CPU_FA526) || defined(CPU_FA626TE) 1145 if (cputype == CPU_ID_FA526 || cputype == CPU_ID_FA626TE) { 1146 cpufuncs = fa526_cpufuncs; 1147 cpu_reset_needs_v4_MMU_disable = 1; /* SA needs it */ 1148 get_cachetype_cp15(); 1149 pmap_pte_init_generic(); 1150 1151 /* Use powersave on this CPU. */ 1152 cpu_do_powersave = 1; 1153 1154 goto out; 1155 } 1156#endif /* CPU_FA526 || CPU_FA626TE */ 1157#ifdef CPU_IXP12X0 1158 if (cputype == CPU_ID_IXP1200) { 1159 cpufuncs = ixp12x0_cpufuncs; 1160 cpu_reset_needs_v4_MMU_disable = 1; 1161 get_cachetype_table(); 1162 pmap_pte_init_sa1(); 1163 goto out; 1164 } 1165#endif /* CPU_IXP12X0 */ 1166#ifdef CPU_XSCALE_80200 1167 if (cputype == CPU_ID_80200) { 1168 int rev = cpufunc_id() & CPU_ID_REVISION_MASK; 1169 1170 i80200_icu_init(); 1171 1172#if defined(XSCALE_CCLKCFG) 1173 /* 1174 * Crank CCLKCFG to maximum legal value. 1175 */ 1176 __asm __volatile ("mcr p14, 0, %0, c6, c0, 0" 1177 : 1178 : "r" (XSCALE_CCLKCFG)); 1179#endif 1180 1181 /* 1182 * XXX Disable ECC in the Bus Controller Unit; we 1183 * don't really support it, yet. Clear any pending 1184 * error indications. 1185 */ 1186 __asm __volatile("mcr p13, 0, %0, c0, c1, 0" 1187 : 1188 : "r" (BCUCTL_E0|BCUCTL_E1|BCUCTL_EV)); 1189 1190 cpufuncs = xscale_cpufuncs; 1191 /* 1192 * i80200 errata: Step-A0 and A1 have a bug where 1193 * D$ dirty bits are not cleared on "invalidate by 1194 * address". 1195 * 1196 * Workaround: Clean cache line before invalidating. 1197 */ 1198 if (rev == 0 || rev == 1) 1199 cpufuncs.cf_dcache_inv_range = xscale_cache_purgeD_rng; 1200 1201 cpu_reset_needs_v4_MMU_disable = 1; /* XScale needs it */ 1202 get_cachetype_cp15(); 1203 pmap_pte_init_xscale(); 1204 goto out; 1205 } 1206#endif /* CPU_XSCALE_80200 */ 1207#if defined(CPU_XSCALE_80321) || defined(CPU_XSCALE_80219) 1208 if (cputype == CPU_ID_80321_400 || cputype == CPU_ID_80321_600 || 1209 cputype == CPU_ID_80321_400_B0 || cputype == CPU_ID_80321_600_B0 || 1210 cputype == CPU_ID_80219_400 || cputype == CPU_ID_80219_600) { 1211 cpufuncs = xscale_cpufuncs; 1212 cpu_reset_needs_v4_MMU_disable = 1; /* XScale needs it */ 1213 get_cachetype_cp15(); 1214 pmap_pte_init_xscale(); 1215 goto out; 1216 } 1217#endif /* CPU_XSCALE_80321 */ 1218 1219#if defined(CPU_XSCALE_81342) 1220 if (cputype == CPU_ID_81342) { 1221 cpufuncs = xscalec3_cpufuncs; 1222 cpu_reset_needs_v4_MMU_disable = 1; /* XScale needs it */ 1223 get_cachetype_cp15(); 1224 pmap_pte_init_xscale(); 1225 goto out; 1226 } 1227#endif /* CPU_XSCALE_81342 */ 1228#ifdef CPU_XSCALE_PXA2X0 1229 /* ignore core revision to test PXA2xx CPUs */ 1230 if ((cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA250 || 1231 (cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA27X || 1232 (cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA210) { 1233 1234 cpufuncs = xscale_cpufuncs; 1235 cpu_reset_needs_v4_MMU_disable = 1; /* XScale needs it */ 1236 get_cachetype_cp15(); 1237 pmap_pte_init_xscale(); 1238 1239 /* Use powersave on this CPU. */ 1240 cpu_do_powersave = 1; 1241 1242 goto out; 1243 } 1244#endif /* CPU_XSCALE_PXA2X0 */ 1245#ifdef CPU_XSCALE_IXP425 1246 if (cputype == CPU_ID_IXP425_533 || cputype == CPU_ID_IXP425_400 || 1247 cputype == CPU_ID_IXP425_266 || cputype == CPU_ID_IXP435) { 1248 1249 cpufuncs = xscale_cpufuncs; 1250 cpu_reset_needs_v4_MMU_disable = 1; /* XScale needs it */ 1251 get_cachetype_cp15(); 1252 pmap_pte_init_xscale(); 1253 1254 goto out; 1255 } 1256#endif /* CPU_XSCALE_IXP425 */ 1257 /* 1258 * Bzzzz. And the answer was ... 1259 */ 1260 panic("No support for this CPU type (%08x) in kernel", cputype); 1261 return(ARCHITECTURE_NOT_PRESENT); 1262out: 1263 uma_set_align(arm_dcache_align_mask); 1264 return (0); 1265} 1266 1267/* 1268 * Fixup routines for data and prefetch aborts. 1269 * 1270 * Several compile time symbols are used 1271 * 1272 * DEBUG_FAULT_CORRECTION - Print debugging information during the 1273 * correction of registers after a fault. 1274 * ARM6_LATE_ABORT - ARM6 supports both early and late aborts 1275 * when defined should use late aborts 1276 */ 1277 1278 1279/* 1280 * Null abort fixup routine. 1281 * For use when no fixup is required. 1282 */ 1283int 1284cpufunc_null_fixup(arg) 1285 void *arg; 1286{ 1287 return(ABORT_FIXUP_OK); 1288} 1289 1290 1291#if defined(CPU_ARM7TDMI) 1292 1293#ifdef DEBUG_FAULT_CORRECTION 1294#define DFC_PRINTF(x) printf x 1295#define DFC_DISASSEMBLE(x) disassemble(x) 1296#else 1297#define DFC_PRINTF(x) /* nothing */ 1298#define DFC_DISASSEMBLE(x) /* nothing */ 1299#endif 1300 1301/* 1302 * "Early" data abort fixup. 1303 * 1304 * For ARM2, ARM2as, ARM3 and ARM6 (in early-abort mode). Also used 1305 * indirectly by ARM6 (in late-abort mode) and ARM7[TDMI]. 1306 * 1307 * In early aborts, we may have to fix up LDM, STM, LDC and STC. 1308 */ 1309int 1310early_abort_fixup(arg) 1311 void *arg; 1312{ 1313 trapframe_t *frame = arg; 1314 u_int fault_pc; 1315 u_int fault_instruction; 1316 int saved_lr = 0; 1317 1318 if ((frame->tf_spsr & PSR_MODE) == PSR_SVC32_MODE) { 1319 1320 /* Ok an abort in SVC mode */ 1321 1322 /* 1323 * Copy the SVC r14 into the usr r14 - The usr r14 is garbage 1324 * as the fault happened in svc mode but we need it in the 1325 * usr slot so we can treat the registers as an array of ints 1326 * during fixing. 1327 * NOTE: This PC is in the position but writeback is not 1328 * allowed on r15. 1329 * Doing it like this is more efficient than trapping this 1330 * case in all possible locations in the following fixup code. 1331 */ 1332 1333 saved_lr = frame->tf_usr_lr; 1334 frame->tf_usr_lr = frame->tf_svc_lr; 1335 1336 /* 1337 * Note the trapframe does not have the SVC r13 so a fault 1338 * from an instruction with writeback to r13 in SVC mode is 1339 * not allowed. This should not happen as the kstack is 1340 * always valid. 1341 */ 1342 } 1343 1344 /* Get fault address and status from the CPU */ 1345 1346 fault_pc = frame->tf_pc; 1347 fault_instruction = *((volatile unsigned int *)fault_pc); 1348 1349 /* Decode the fault instruction and fix the registers as needed */ 1350 1351 if ((fault_instruction & 0x0e000000) == 0x08000000) { 1352 int base; 1353 int loop; 1354 int count; 1355 int *registers = &frame->tf_r0; 1356 1357 DFC_PRINTF(("LDM/STM\n")); 1358 DFC_DISASSEMBLE(fault_pc); 1359 if (fault_instruction & (1 << 21)) { 1360 DFC_PRINTF(("This instruction must be corrected\n")); 1361 base = (fault_instruction >> 16) & 0x0f; 1362 if (base == 15) 1363 return ABORT_FIXUP_FAILED; 1364 /* Count registers transferred */ 1365 count = 0; 1366 for (loop = 0; loop < 16; ++loop) { 1367 if (fault_instruction & (1<<loop)) 1368 ++count; 1369 } 1370 DFC_PRINTF(("%d registers used\n", count)); 1371 DFC_PRINTF(("Corrected r%d by %d bytes ", 1372 base, count * 4)); 1373 if (fault_instruction & (1 << 23)) { 1374 DFC_PRINTF(("down\n")); 1375 registers[base] -= count * 4; 1376 } else { 1377 DFC_PRINTF(("up\n")); 1378 registers[base] += count * 4; 1379 } 1380 } 1381 } else if ((fault_instruction & 0x0e000000) == 0x0c000000) { 1382 int base; 1383 int offset; 1384 int *registers = &frame->tf_r0; 1385 1386 /* REGISTER CORRECTION IS REQUIRED FOR THESE INSTRUCTIONS */ 1387 1388 DFC_DISASSEMBLE(fault_pc); 1389 1390 /* Only need to fix registers if write back is turned on */ 1391 1392 if ((fault_instruction & (1 << 21)) != 0) { 1393 base = (fault_instruction >> 16) & 0x0f; 1394 if (base == 13 && 1395 (frame->tf_spsr & PSR_MODE) == PSR_SVC32_MODE) 1396 return ABORT_FIXUP_FAILED; 1397 if (base == 15) 1398 return ABORT_FIXUP_FAILED; 1399 1400 offset = (fault_instruction & 0xff) << 2; 1401 DFC_PRINTF(("r%d=%08x\n", base, registers[base])); 1402 if ((fault_instruction & (1 << 23)) != 0) 1403 offset = -offset; 1404 registers[base] += offset; 1405 DFC_PRINTF(("r%d=%08x\n", base, registers[base])); 1406 } 1407 } else if ((fault_instruction & 0x0e000000) == 0x0c000000) 1408 return ABORT_FIXUP_FAILED; 1409 1410 if ((frame->tf_spsr & PSR_MODE) == PSR_SVC32_MODE) { 1411 1412 /* Ok an abort in SVC mode */ 1413 1414 /* 1415 * Copy the SVC r14 into the usr r14 - The usr r14 is garbage 1416 * as the fault happened in svc mode but we need it in the 1417 * usr slot so we can treat the registers as an array of ints 1418 * during fixing. 1419 * NOTE: This PC is in the position but writeback is not 1420 * allowed on r15. 1421 * Doing it like this is more efficient than trapping this 1422 * case in all possible locations in the prior fixup code. 1423 */ 1424 1425 frame->tf_svc_lr = frame->tf_usr_lr; 1426 frame->tf_usr_lr = saved_lr; 1427 1428 /* 1429 * Note the trapframe does not have the SVC r13 so a fault 1430 * from an instruction with writeback to r13 in SVC mode is 1431 * not allowed. This should not happen as the kstack is 1432 * always valid. 1433 */ 1434 } 1435 1436 return(ABORT_FIXUP_OK); 1437} 1438#endif /* CPU_ARM2/250/3/6/7 */ 1439 1440 1441#if defined(CPU_ARM7TDMI) 1442/* 1443 * "Late" (base updated) data abort fixup 1444 * 1445 * For ARM6 (in late-abort mode) and ARM7. 1446 * 1447 * In this model, all data-transfer instructions need fixing up. We defer 1448 * LDM, STM, LDC and STC fixup to the early-abort handler. 1449 */ 1450int 1451late_abort_fixup(arg) 1452 void *arg; 1453{ 1454 trapframe_t *frame = arg; 1455 u_int fault_pc; 1456 u_int fault_instruction; 1457 int saved_lr = 0; 1458 1459 if ((frame->tf_spsr & PSR_MODE) == PSR_SVC32_MODE) { 1460 1461 /* Ok an abort in SVC mode */ 1462 1463 /* 1464 * Copy the SVC r14 into the usr r14 - The usr r14 is garbage 1465 * as the fault happened in svc mode but we need it in the 1466 * usr slot so we can treat the registers as an array of ints 1467 * during fixing. 1468 * NOTE: This PC is in the position but writeback is not 1469 * allowed on r15. 1470 * Doing it like this is more efficient than trapping this 1471 * case in all possible locations in the following fixup code. 1472 */ 1473 1474 saved_lr = frame->tf_usr_lr; 1475 frame->tf_usr_lr = frame->tf_svc_lr; 1476 1477 /* 1478 * Note the trapframe does not have the SVC r13 so a fault 1479 * from an instruction with writeback to r13 in SVC mode is 1480 * not allowed. This should not happen as the kstack is 1481 * always valid. 1482 */ 1483 } 1484 1485 /* Get fault address and status from the CPU */ 1486 1487 fault_pc = frame->tf_pc; 1488 fault_instruction = *((volatile unsigned int *)fault_pc); 1489 1490 /* Decode the fault instruction and fix the registers as needed */ 1491 1492 /* Was is a swap instruction ? */ 1493 1494 if ((fault_instruction & 0x0fb00ff0) == 0x01000090) { 1495 DFC_DISASSEMBLE(fault_pc); 1496 } else if ((fault_instruction & 0x0c000000) == 0x04000000) { 1497 1498 /* Was is a ldr/str instruction */ 1499 /* This is for late abort only */ 1500 1501 int base; 1502 int offset; 1503 int *registers = &frame->tf_r0; 1504 1505 DFC_DISASSEMBLE(fault_pc); 1506 1507 /* This is for late abort only */ 1508 1509 if ((fault_instruction & (1 << 24)) == 0 1510 || (fault_instruction & (1 << 21)) != 0) { 1511 /* postindexed ldr/str with no writeback */ 1512 1513 base = (fault_instruction >> 16) & 0x0f; 1514 if (base == 13 && 1515 (frame->tf_spsr & PSR_MODE) == PSR_SVC32_MODE) 1516 return ABORT_FIXUP_FAILED; 1517 if (base == 15) 1518 return ABORT_FIXUP_FAILED; 1519 DFC_PRINTF(("late abt fix: r%d=%08x : ", 1520 base, registers[base])); 1521 if ((fault_instruction & (1 << 25)) == 0) { 1522 /* Immediate offset - easy */ 1523 1524 offset = fault_instruction & 0xfff; 1525 if ((fault_instruction & (1 << 23))) 1526 offset = -offset; 1527 registers[base] += offset; 1528 DFC_PRINTF(("imm=%08x ", offset)); 1529 } else { 1530 /* offset is a shifted register */ 1531 int shift; 1532 1533 offset = fault_instruction & 0x0f; 1534 if (offset == base) 1535 return ABORT_FIXUP_FAILED; 1536 1537 /* 1538 * Register offset - hard we have to 1539 * cope with shifts ! 1540 */ 1541 offset = registers[offset]; 1542 1543 if ((fault_instruction & (1 << 4)) == 0) 1544 /* shift with amount */ 1545 shift = (fault_instruction >> 7) & 0x1f; 1546 else { 1547 /* shift with register */ 1548 if ((fault_instruction & (1 << 7)) != 0) 1549 /* undefined for now so bail out */ 1550 return ABORT_FIXUP_FAILED; 1551 shift = ((fault_instruction >> 8) & 0xf); 1552 if (base == shift) 1553 return ABORT_FIXUP_FAILED; 1554 DFC_PRINTF(("shift reg=%d ", shift)); 1555 shift = registers[shift]; 1556 } 1557 DFC_PRINTF(("shift=%08x ", shift)); 1558 switch (((fault_instruction >> 5) & 0x3)) { 1559 case 0 : /* Logical left */ 1560 offset = (int)(((u_int)offset) << shift); 1561 break; 1562 case 1 : /* Logical Right */ 1563 if (shift == 0) shift = 32; 1564 offset = (int)(((u_int)offset) >> shift); 1565 break; 1566 case 2 : /* Arithmetic Right */ 1567 if (shift == 0) shift = 32; 1568 offset = (int)(((int)offset) >> shift); 1569 break; 1570 case 3 : /* Rotate right (rol or rxx) */ 1571 return ABORT_FIXUP_FAILED; 1572 break; 1573 } 1574 1575 DFC_PRINTF(("abt: fixed LDR/STR with " 1576 "register offset\n")); 1577 if ((fault_instruction & (1 << 23))) 1578 offset = -offset; 1579 DFC_PRINTF(("offset=%08x ", offset)); 1580 registers[base] += offset; 1581 } 1582 DFC_PRINTF(("r%d=%08x\n", base, registers[base])); 1583 } 1584 } 1585 1586 if ((frame->tf_spsr & PSR_MODE) == PSR_SVC32_MODE) { 1587 1588 /* Ok an abort in SVC mode */ 1589 1590 /* 1591 * Copy the SVC r14 into the usr r14 - The usr r14 is garbage 1592 * as the fault happened in svc mode but we need it in the 1593 * usr slot so we can treat the registers as an array of ints 1594 * during fixing. 1595 * NOTE: This PC is in the position but writeback is not 1596 * allowed on r15. 1597 * Doing it like this is more efficient than trapping this 1598 * case in all possible locations in the prior fixup code. 1599 */ 1600 1601 frame->tf_svc_lr = frame->tf_usr_lr; 1602 frame->tf_usr_lr = saved_lr; 1603 1604 /* 1605 * Note the trapframe does not have the SVC r13 so a fault 1606 * from an instruction with writeback to r13 in SVC mode is 1607 * not allowed. This should not happen as the kstack is 1608 * always valid. 1609 */ 1610 } 1611 1612 /* 1613 * Now let the early-abort fixup routine have a go, in case it 1614 * was an LDM, STM, LDC or STC that faulted. 1615 */ 1616 1617 return early_abort_fixup(arg); 1618} 1619#endif /* CPU_ARM7TDMI */ 1620 1621/* 1622 * CPU Setup code 1623 */ 1624 1625#if defined(CPU_ARM7TDMI) || defined(CPU_ARM8) || defined (CPU_ARM9) || \ 1626 defined(CPU_ARM9E) || \ 1627 defined(CPU_SA110) || defined(CPU_SA1100) || defined(CPU_SA1110) || \ 1628 defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \ 1629 defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \ 1630 defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342) || \ 1631 defined(CPU_ARM10) || defined(CPU_ARM11) || \ 1632 defined(CPU_FA526) || defined(CPU_FA626TE) 1633 1634#define IGN 0 1635#define OR 1 1636#define BIC 2 1637 1638struct cpu_option { 1639 char *co_name; 1640 int co_falseop; 1641 int co_trueop; 1642 int co_value; 1643}; 1644 1645static u_int parse_cpu_options(char *, struct cpu_option *, u_int); 1646 1647static u_int 1648parse_cpu_options(args, optlist, cpuctrl) 1649 char *args; 1650 struct cpu_option *optlist; 1651 u_int cpuctrl; 1652{ 1653 int integer; 1654 1655 if (args == NULL) 1656 return(cpuctrl); 1657 1658 while (optlist->co_name) { 1659 if (get_bootconf_option(args, optlist->co_name, 1660 BOOTOPT_TYPE_BOOLEAN, &integer)) { 1661 if (integer) { 1662 if (optlist->co_trueop == OR) 1663 cpuctrl |= optlist->co_value; 1664 else if (optlist->co_trueop == BIC) 1665 cpuctrl &= ~optlist->co_value; 1666 } else { 1667 if (optlist->co_falseop == OR) 1668 cpuctrl |= optlist->co_value; 1669 else if (optlist->co_falseop == BIC) 1670 cpuctrl &= ~optlist->co_value; 1671 } 1672 } 1673 ++optlist; 1674 } 1675 return(cpuctrl); 1676} 1677#endif /* CPU_ARM7TDMI || CPU_ARM8 || CPU_SA110 || XSCALE*/ 1678 1679#if defined(CPU_ARM7TDMI) || defined(CPU_ARM8) 1680struct cpu_option arm678_options[] = { 1681#ifdef COMPAT_12 1682 { "nocache", IGN, BIC, CPU_CONTROL_IDC_ENABLE }, 1683 { "nowritebuf", IGN, BIC, CPU_CONTROL_WBUF_ENABLE }, 1684#endif /* COMPAT_12 */ 1685 { "cpu.cache", BIC, OR, CPU_CONTROL_IDC_ENABLE }, 1686 { "cpu.nocache", OR, BIC, CPU_CONTROL_IDC_ENABLE }, 1687 { "cpu.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 1688 { "cpu.nowritebuf", OR, BIC, CPU_CONTROL_WBUF_ENABLE }, 1689 { NULL, IGN, IGN, 0 } 1690}; 1691 1692#endif /* CPU_ARM6 || CPU_ARM7 || CPU_ARM7TDMI || CPU_ARM8 */ 1693 1694#ifdef CPU_ARM7TDMI 1695struct cpu_option arm7tdmi_options[] = { 1696 { "arm7.cache", BIC, OR, CPU_CONTROL_IDC_ENABLE }, 1697 { "arm7.nocache", OR, BIC, CPU_CONTROL_IDC_ENABLE }, 1698 { "arm7.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 1699 { "arm7.nowritebuf", OR, BIC, CPU_CONTROL_WBUF_ENABLE }, 1700#ifdef COMPAT_12 1701 { "fpaclk2", BIC, OR, CPU_CONTROL_CPCLK }, 1702#endif /* COMPAT_12 */ 1703 { "arm700.fpaclk", BIC, OR, CPU_CONTROL_CPCLK }, 1704 { NULL, IGN, IGN, 0 } 1705}; 1706 1707void 1708arm7tdmi_setup(args) 1709 char *args; 1710{ 1711 int cpuctrl; 1712 1713 cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 1714 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 1715 | CPU_CONTROL_IDC_ENABLE | CPU_CONTROL_WBUF_ENABLE; 1716 1717 cpuctrl = parse_cpu_options(args, arm678_options, cpuctrl); 1718 cpuctrl = parse_cpu_options(args, arm7tdmi_options, cpuctrl); 1719 1720#ifdef __ARMEB__ 1721 cpuctrl |= CPU_CONTROL_BEND_ENABLE; 1722#endif 1723 1724 /* Clear out the cache */ 1725 cpu_idcache_wbinv_all(); 1726 1727 /* Set the control register */ 1728 ctrl = cpuctrl; 1729 cpu_control(0xffffffff, cpuctrl); 1730} 1731#endif /* CPU_ARM7TDMI */ 1732 1733#ifdef CPU_ARM8 1734struct cpu_option arm8_options[] = { 1735 { "arm8.cache", BIC, OR, CPU_CONTROL_IDC_ENABLE }, 1736 { "arm8.nocache", OR, BIC, CPU_CONTROL_IDC_ENABLE }, 1737 { "arm8.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 1738 { "arm8.nowritebuf", OR, BIC, CPU_CONTROL_WBUF_ENABLE }, 1739#ifdef COMPAT_12 1740 { "branchpredict", BIC, OR, CPU_CONTROL_BPRD_ENABLE }, 1741#endif /* COMPAT_12 */ 1742 { "cpu.branchpredict", BIC, OR, CPU_CONTROL_BPRD_ENABLE }, 1743 { "arm8.branchpredict", BIC, OR, CPU_CONTROL_BPRD_ENABLE }, 1744 { NULL, IGN, IGN, 0 } 1745}; 1746 1747void 1748arm8_setup(args) 1749 char *args; 1750{ 1751 int integer; 1752 int cpuctrl, cpuctrlmask; 1753 int clocktest; 1754 int setclock = 0; 1755 1756 cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 1757 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 1758 | CPU_CONTROL_IDC_ENABLE | CPU_CONTROL_WBUF_ENABLE; 1759 cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 1760 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 1761 | CPU_CONTROL_IDC_ENABLE | CPU_CONTROL_WBUF_ENABLE 1762 | CPU_CONTROL_BPRD_ENABLE | CPU_CONTROL_ROM_ENABLE 1763 | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE; 1764 1765#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 1766 cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 1767#endif 1768 1769 cpuctrl = parse_cpu_options(args, arm678_options, cpuctrl); 1770 cpuctrl = parse_cpu_options(args, arm8_options, cpuctrl); 1771 1772#ifdef __ARMEB__ 1773 cpuctrl |= CPU_CONTROL_BEND_ENABLE; 1774#endif 1775 1776 /* Get clock configuration */ 1777 clocktest = arm8_clock_config(0, 0) & 0x0f; 1778 1779 /* Special ARM8 clock and test configuration */ 1780 if (get_bootconf_option(args, "arm8.clock.reset", BOOTOPT_TYPE_BOOLEAN, &integer)) { 1781 clocktest = 0; 1782 setclock = 1; 1783 } 1784 if (get_bootconf_option(args, "arm8.clock.dynamic", BOOTOPT_TYPE_BOOLEAN, &integer)) { 1785 if (integer) 1786 clocktest |= 0x01; 1787 else 1788 clocktest &= ~(0x01); 1789 setclock = 1; 1790 } 1791 if (get_bootconf_option(args, "arm8.clock.sync", BOOTOPT_TYPE_BOOLEAN, &integer)) { 1792 if (integer) 1793 clocktest |= 0x02; 1794 else 1795 clocktest &= ~(0x02); 1796 setclock = 1; 1797 } 1798 if (get_bootconf_option(args, "arm8.clock.fast", BOOTOPT_TYPE_BININT, &integer)) { 1799 clocktest = (clocktest & ~0xc0) | (integer & 3) << 2; 1800 setclock = 1; 1801 } 1802 if (get_bootconf_option(args, "arm8.test", BOOTOPT_TYPE_BININT, &integer)) { 1803 clocktest |= (integer & 7) << 5; 1804 setclock = 1; 1805 } 1806 1807 /* Clear out the cache */ 1808 cpu_idcache_wbinv_all(); 1809 1810 /* Set the control register */ 1811 ctrl = cpuctrl; 1812 cpu_control(0xffffffff, cpuctrl); 1813 1814 /* Set the clock/test register */ 1815 if (setclock) 1816 arm8_clock_config(0x7f, clocktest); 1817} 1818#endif /* CPU_ARM8 */ 1819 1820#ifdef CPU_ARM9 1821struct cpu_option arm9_options[] = { 1822 { "cpu.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 1823 { "cpu.nocache", OR, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 1824 { "arm9.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 1825 { "arm9.icache", BIC, OR, CPU_CONTROL_IC_ENABLE }, 1826 { "arm9.dcache", BIC, OR, CPU_CONTROL_DC_ENABLE }, 1827 { "cpu.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 1828 { "cpu.nowritebuf", OR, BIC, CPU_CONTROL_WBUF_ENABLE }, 1829 { "arm9.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 1830 { NULL, IGN, IGN, 0 } 1831}; 1832 1833void 1834arm9_setup(args) 1835 char *args; 1836{ 1837 int cpuctrl, cpuctrlmask; 1838 1839 cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 1840 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 1841 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 1842 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE | 1843 CPU_CONTROL_ROUNDROBIN; 1844 cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 1845 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 1846 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 1847 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE 1848 | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE 1849 | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_VECRELOC 1850 | CPU_CONTROL_ROUNDROBIN; 1851 1852#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 1853 cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 1854#endif 1855 1856 cpuctrl = parse_cpu_options(args, arm9_options, cpuctrl); 1857 1858#ifdef __ARMEB__ 1859 cpuctrl |= CPU_CONTROL_BEND_ENABLE; 1860#endif 1861 if (vector_page == ARM_VECTORS_HIGH) 1862 cpuctrl |= CPU_CONTROL_VECRELOC; 1863 1864 /* Clear out the cache */ 1865 cpu_idcache_wbinv_all(); 1866 1867 /* Set the control register */ 1868 cpu_control(cpuctrlmask, cpuctrl); 1869 ctrl = cpuctrl; 1870 1871} 1872#endif /* CPU_ARM9 */ 1873 1874#if defined(CPU_ARM9E) || defined(CPU_ARM10) 1875struct cpu_option arm10_options[] = { 1876 { "cpu.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 1877 { "cpu.nocache", OR, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 1878 { "arm10.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 1879 { "arm10.icache", BIC, OR, CPU_CONTROL_IC_ENABLE }, 1880 { "arm10.dcache", BIC, OR, CPU_CONTROL_DC_ENABLE }, 1881 { "cpu.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 1882 { "cpu.nowritebuf", OR, BIC, CPU_CONTROL_WBUF_ENABLE }, 1883 { "arm10.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 1884 { NULL, IGN, IGN, 0 } 1885}; 1886 1887void 1888arm10_setup(args) 1889 char *args; 1890{ 1891 int cpuctrl, cpuctrlmask; 1892 1893 cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_SYST_ENABLE 1894 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 1895 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_BPRD_ENABLE; 1896 cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_SYST_ENABLE 1897 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 1898 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE 1899 | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE 1900 | CPU_CONTROL_BPRD_ENABLE 1901 | CPU_CONTROL_ROUNDROBIN | CPU_CONTROL_CPCLK; 1902 1903#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 1904 cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 1905#endif 1906 1907 cpuctrl = parse_cpu_options(args, arm10_options, cpuctrl); 1908 1909#ifdef __ARMEB__ 1910 cpuctrl |= CPU_CONTROL_BEND_ENABLE; 1911#endif 1912 1913 /* Clear out the cache */ 1914 cpu_idcache_wbinv_all(); 1915 1916 /* Now really make sure they are clean. */ 1917 __asm __volatile ("mcr\tp15, 0, r0, c7, c7, 0" : : ); 1918 1919 if (vector_page == ARM_VECTORS_HIGH) 1920 cpuctrl |= CPU_CONTROL_VECRELOC; 1921 1922 /* Set the control register */ 1923 ctrl = cpuctrl; 1924 cpu_control(0xffffffff, cpuctrl); 1925 1926 /* And again. */ 1927 cpu_idcache_wbinv_all(); 1928} 1929#endif /* CPU_ARM9E || CPU_ARM10 */ 1930 1931#ifdef CPU_ARM11 1932struct cpu_option arm11_options[] = { 1933 { "cpu.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 1934 { "cpu.nocache", OR, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 1935 { "arm11.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 1936 { "arm11.icache", BIC, OR, CPU_CONTROL_IC_ENABLE }, 1937 { "arm11.dcache", BIC, OR, CPU_CONTROL_DC_ENABLE }, 1938 { NULL, IGN, IGN, 0 } 1939}; 1940 1941void 1942arm11_setup(args) 1943 char *args; 1944{ 1945 int cpuctrl, cpuctrlmask; 1946 1947 cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_SYST_ENABLE 1948 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 1949 /* | CPU_CONTROL_BPRD_ENABLE */; 1950 cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_SYST_ENABLE 1951 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 1952 | CPU_CONTROL_ROM_ENABLE | CPU_CONTROL_BPRD_ENABLE 1953 | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE 1954 | CPU_CONTROL_ROUNDROBIN | CPU_CONTROL_CPCLK; 1955 1956#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 1957 cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 1958#endif 1959 1960 cpuctrl = parse_cpu_options(args, arm11_options, cpuctrl); 1961 1962#ifdef __ARMEB__ 1963 cpuctrl |= CPU_CONTROL_BEND_ENABLE; 1964#endif 1965 1966 /* Clear out the cache */ 1967 cpu_idcache_wbinv_all(); 1968 1969 /* Now really make sure they are clean. */ 1970 __asm __volatile ("mcr\tp15, 0, r0, c7, c7, 0" : : ); 1971 1972 /* Set the control register */ 1973 curcpu()->ci_ctrl = cpuctrl; 1974 cpu_control(0xffffffff, cpuctrl); 1975 1976 /* And again. */ 1977 cpu_idcache_wbinv_all(); 1978} 1979#endif /* CPU_ARM11 */ 1980 1981#ifdef CPU_SA110 1982struct cpu_option sa110_options[] = { 1983#ifdef COMPAT_12 1984 { "nocache", IGN, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 1985 { "nowritebuf", IGN, BIC, CPU_CONTROL_WBUF_ENABLE }, 1986#endif /* COMPAT_12 */ 1987 { "cpu.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 1988 { "cpu.nocache", OR, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 1989 { "sa110.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 1990 { "sa110.icache", BIC, OR, CPU_CONTROL_IC_ENABLE }, 1991 { "sa110.dcache", BIC, OR, CPU_CONTROL_DC_ENABLE }, 1992 { "cpu.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 1993 { "cpu.nowritebuf", OR, BIC, CPU_CONTROL_WBUF_ENABLE }, 1994 { "sa110.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 1995 { NULL, IGN, IGN, 0 } 1996}; 1997 1998void 1999sa110_setup(args) 2000 char *args; 2001{ 2002 int cpuctrl, cpuctrlmask; 2003 2004 cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 2005 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 2006 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 2007 | CPU_CONTROL_WBUF_ENABLE; 2008 cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 2009 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 2010 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 2011 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE 2012 | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE 2013 | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_BPRD_ENABLE 2014 | CPU_CONTROL_CPCLK; 2015 2016#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 2017 cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 2018#endif 2019 2020 cpuctrl = parse_cpu_options(args, sa110_options, cpuctrl); 2021 2022#ifdef __ARMEB__ 2023 cpuctrl |= CPU_CONTROL_BEND_ENABLE; 2024#endif 2025 2026 /* Clear out the cache */ 2027 cpu_idcache_wbinv_all(); 2028 2029 /* Set the control register */ 2030 ctrl = cpuctrl; 2031/* cpu_control(cpuctrlmask, cpuctrl);*/ 2032 cpu_control(0xffffffff, cpuctrl); 2033 2034 /* 2035 * enable clockswitching, note that this doesn't read or write to r0, 2036 * r0 is just to make it valid asm 2037 */ 2038 __asm ("mcr 15, 0, r0, c15, c1, 2"); 2039} 2040#endif /* CPU_SA110 */ 2041 2042#if defined(CPU_SA1100) || defined(CPU_SA1110) 2043struct cpu_option sa11x0_options[] = { 2044#ifdef COMPAT_12 2045 { "nocache", IGN, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2046 { "nowritebuf", IGN, BIC, CPU_CONTROL_WBUF_ENABLE }, 2047#endif /* COMPAT_12 */ 2048 { "cpu.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2049 { "cpu.nocache", OR, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2050 { "sa11x0.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2051 { "sa11x0.icache", BIC, OR, CPU_CONTROL_IC_ENABLE }, 2052 { "sa11x0.dcache", BIC, OR, CPU_CONTROL_DC_ENABLE }, 2053 { "cpu.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 2054 { "cpu.nowritebuf", OR, BIC, CPU_CONTROL_WBUF_ENABLE }, 2055 { "sa11x0.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 2056 { NULL, IGN, IGN, 0 } 2057}; 2058 2059void 2060sa11x0_setup(args) 2061 char *args; 2062{ 2063 int cpuctrl, cpuctrlmask; 2064 2065 cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 2066 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 2067 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 2068 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE; 2069 cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 2070 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 2071 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 2072 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE 2073 | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE 2074 | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_BPRD_ENABLE 2075 | CPU_CONTROL_CPCLK | CPU_CONTROL_VECRELOC; 2076 2077#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 2078 cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 2079#endif 2080 2081 2082 cpuctrl = parse_cpu_options(args, sa11x0_options, cpuctrl); 2083 2084#ifdef __ARMEB__ 2085 cpuctrl |= CPU_CONTROL_BEND_ENABLE; 2086#endif 2087 2088 if (vector_page == ARM_VECTORS_HIGH) 2089 cpuctrl |= CPU_CONTROL_VECRELOC; 2090 /* Clear out the cache */ 2091 cpu_idcache_wbinv_all(); 2092 /* Set the control register */ 2093 ctrl = cpuctrl; 2094 cpu_control(0xffffffff, cpuctrl); 2095} 2096#endif /* CPU_SA1100 || CPU_SA1110 */ 2097 2098#if defined(CPU_FA526) || defined(CPU_FA626TE) 2099struct cpu_option fa526_options[] = { 2100#ifdef COMPAT_12 2101 { "nocache", IGN, BIC, (CPU_CONTROL_IC_ENABLE | 2102 CPU_CONTROL_DC_ENABLE) }, 2103 { "nowritebuf", IGN, BIC, CPU_CONTROL_WBUF_ENABLE }, 2104#endif /* COMPAT_12 */ 2105 { "cpu.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | 2106 CPU_CONTROL_DC_ENABLE) }, 2107 { "cpu.nocache", OR, BIC, (CPU_CONTROL_IC_ENABLE | 2108 CPU_CONTROL_DC_ENABLE) }, 2109 { "cpu.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 2110 { "cpu.nowritebuf", OR, BIC, CPU_CONTROL_WBUF_ENABLE }, 2111 { NULL, IGN, IGN, 0 } 2112}; 2113 2114void 2115fa526_setup(char *args) 2116{ 2117 int cpuctrl, cpuctrlmask; 2118 2119 cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 2120 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 2121 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 2122 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE 2123 | CPU_CONTROL_BPRD_ENABLE; 2124 cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 2125 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 2126 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 2127 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE 2128 | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE 2129 | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_BPRD_ENABLE 2130 | CPU_CONTROL_CPCLK | CPU_CONTROL_VECRELOC; 2131 2132#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 2133 cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 2134#endif 2135 2136 cpuctrl = parse_cpu_options(args, fa526_options, cpuctrl); 2137 2138#ifdef __ARMEB__ 2139 cpuctrl |= CPU_CONTROL_BEND_ENABLE; 2140#endif 2141 2142 if (vector_page == ARM_VECTORS_HIGH) 2143 cpuctrl |= CPU_CONTROL_VECRELOC; 2144 2145 /* Clear out the cache */ 2146 cpu_idcache_wbinv_all(); 2147 2148 /* Set the control register */ 2149 ctrl = cpuctrl; 2150 cpu_control(0xffffffff, cpuctrl); 2151} 2152#endif /* CPU_FA526 || CPU_FA626TE */ 2153 2154 2155#if defined(CPU_IXP12X0) 2156struct cpu_option ixp12x0_options[] = { 2157 { "cpu.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2158 { "cpu.nocache", OR, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2159 { "ixp12x0.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2160 { "ixp12x0.icache", BIC, OR, CPU_CONTROL_IC_ENABLE }, 2161 { "ixp12x0.dcache", BIC, OR, CPU_CONTROL_DC_ENABLE }, 2162 { "cpu.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 2163 { "cpu.nowritebuf", OR, BIC, CPU_CONTROL_WBUF_ENABLE }, 2164 { "ixp12x0.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 2165 { NULL, IGN, IGN, 0 } 2166}; 2167 2168void 2169ixp12x0_setup(args) 2170 char *args; 2171{ 2172 int cpuctrl, cpuctrlmask; 2173 2174 2175 cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_DC_ENABLE 2176 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_SYST_ENABLE 2177 | CPU_CONTROL_IC_ENABLE; 2178 2179 cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_AFLT_ENABLE 2180 | CPU_CONTROL_DC_ENABLE | CPU_CONTROL_WBUF_ENABLE 2181 | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_SYST_ENABLE 2182 | CPU_CONTROL_ROM_ENABLE | CPU_CONTROL_IC_ENABLE 2183 | CPU_CONTROL_VECRELOC; 2184 2185#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 2186 cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 2187#endif 2188 2189 cpuctrl = parse_cpu_options(args, ixp12x0_options, cpuctrl); 2190 2191#ifdef __ARMEB__ 2192 cpuctrl |= CPU_CONTROL_BEND_ENABLE; 2193#endif 2194 2195 if (vector_page == ARM_VECTORS_HIGH) 2196 cpuctrl |= CPU_CONTROL_VECRELOC; 2197 2198 /* Clear out the cache */ 2199 cpu_idcache_wbinv_all(); 2200 2201 /* Set the control register */ 2202 ctrl = cpuctrl; 2203 /* cpu_control(0xffffffff, cpuctrl); */ 2204 cpu_control(cpuctrlmask, cpuctrl); 2205} 2206#endif /* CPU_IXP12X0 */ 2207 2208#if defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \ 2209 defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \ 2210 defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342) 2211struct cpu_option xscale_options[] = { 2212#ifdef COMPAT_12 2213 { "branchpredict", BIC, OR, CPU_CONTROL_BPRD_ENABLE }, 2214 { "nocache", IGN, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2215#endif /* COMPAT_12 */ 2216 { "cpu.branchpredict", BIC, OR, CPU_CONTROL_BPRD_ENABLE }, 2217 { "cpu.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2218 { "cpu.nocache", OR, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2219 { "xscale.branchpredict", BIC, OR, CPU_CONTROL_BPRD_ENABLE }, 2220 { "xscale.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2221 { "xscale.icache", BIC, OR, CPU_CONTROL_IC_ENABLE }, 2222 { "xscale.dcache", BIC, OR, CPU_CONTROL_DC_ENABLE }, 2223 { NULL, IGN, IGN, 0 } 2224}; 2225 2226void 2227xscale_setup(args) 2228 char *args; 2229{ 2230 uint32_t auxctl; 2231 int cpuctrl, cpuctrlmask; 2232 2233 /* 2234 * The XScale Write Buffer is always enabled. Our option 2235 * is to enable/disable coalescing. Note that bits 6:3 2236 * must always be enabled. 2237 */ 2238 2239 cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 2240 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 2241 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 2242 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE 2243 | CPU_CONTROL_BPRD_ENABLE; 2244 cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 2245 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 2246 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 2247 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE 2248 | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE 2249 | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_BPRD_ENABLE 2250 | CPU_CONTROL_CPCLK | CPU_CONTROL_VECRELOC | \ 2251 CPU_CONTROL_L2_ENABLE; 2252 2253#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 2254 cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 2255#endif 2256 2257 cpuctrl = parse_cpu_options(args, xscale_options, cpuctrl); 2258 2259#ifdef __ARMEB__ 2260 cpuctrl |= CPU_CONTROL_BEND_ENABLE; 2261#endif 2262 2263 if (vector_page == ARM_VECTORS_HIGH) 2264 cpuctrl |= CPU_CONTROL_VECRELOC; 2265#ifdef CPU_XSCALE_CORE3 2266 cpuctrl |= CPU_CONTROL_L2_ENABLE; 2267#endif 2268 2269 /* Clear out the cache */ 2270 cpu_idcache_wbinv_all(); 2271 2272 /* 2273 * Set the control register. Note that bits 6:3 must always 2274 * be set to 1. 2275 */ 2276 ctrl = cpuctrl; 2277/* cpu_control(cpuctrlmask, cpuctrl);*/ 2278 cpu_control(0xffffffff, cpuctrl); 2279 2280 /* Make sure write coalescing is turned on */ 2281 __asm __volatile("mrc p15, 0, %0, c1, c0, 1" 2282 : "=r" (auxctl)); 2283#ifdef XSCALE_NO_COALESCE_WRITES 2284 auxctl |= XSCALE_AUXCTL_K; 2285#else 2286 auxctl &= ~XSCALE_AUXCTL_K; 2287#endif 2288#ifdef CPU_XSCALE_CORE3 2289 auxctl |= XSCALE_AUXCTL_LLR; 2290 auxctl |= XSCALE_AUXCTL_MD_MASK; 2291#endif 2292 __asm __volatile("mcr p15, 0, %0, c1, c0, 1" 2293 : : "r" (auxctl)); 2294} 2295#endif /* CPU_XSCALE_80200 || CPU_XSCALE_80321 || CPU_XSCALE_PXA2X0 || CPU_XSCALE_IXP425 2296 CPU_XSCALE_80219 */ 2297