cpufunc.c revision 278518
1/* $NetBSD: cpufunc.c,v 1.65 2003/11/05 12:53:15 scw Exp $ */ 2 3/*- 4 * arm9 support code Copyright (C) 2001 ARM Ltd 5 * Copyright (c) 1997 Mark Brinicombe. 6 * Copyright (c) 1997 Causality Limited 7 * All rights reserved. 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 by Causality Limited. 20 * 4. The name of Causality Limited may not be used to endorse or promote 21 * products derived from this software without specific prior written 22 * permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY CAUSALITY LIMITED ``AS IS'' AND ANY EXPRESS 25 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 26 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 27 * DISCLAIMED. IN NO EVENT SHALL CAUSALITY LIMITED BE LIABLE FOR ANY DIRECT, 28 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 29 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * RiscBSD kernel project 37 * 38 * cpufuncs.c 39 * 40 * C functions for supporting CPU / MMU / TLB specific operations. 41 * 42 * Created : 30/01/97 43 */ 44#include <sys/cdefs.h> 45__FBSDID("$FreeBSD: head/sys/arm/arm/cpufunc.c 278518 2015-02-10 14:11:23Z zbb $"); 46 47#include <sys/param.h> 48#include <sys/systm.h> 49#include <sys/lock.h> 50#include <sys/mutex.h> 51#include <sys/bus.h> 52#include <machine/bus.h> 53#include <machine/cpu.h> 54#include <machine/disassem.h> 55 56#include <vm/vm.h> 57#include <vm/pmap.h> 58#include <vm/uma.h> 59 60#include <machine/cpuconf.h> 61#include <machine/cpufunc.h> 62#include <machine/bootconfig.h> 63 64#ifdef CPU_XSCALE_80200 65#include <arm/xscale/i80200/i80200reg.h> 66#include <arm/xscale/i80200/i80200var.h> 67#endif 68 69#if defined(CPU_XSCALE_80321) || defined(CPU_XSCALE_80219) 70#include <arm/xscale/i80321/i80321reg.h> 71#include <arm/xscale/i80321/i80321var.h> 72#endif 73 74/* 75 * Some definitions in i81342reg.h clash with i80321reg.h. 76 * This only happens for the LINT kernel. As it happens, 77 * we don't need anything from i81342reg.h that we already 78 * got from somewhere else during a LINT compile. 79 */ 80#if defined(CPU_XSCALE_81342) && !defined(COMPILING_LINT) 81#include <arm/xscale/i8134x/i81342reg.h> 82#endif 83 84#ifdef CPU_XSCALE_IXP425 85#include <arm/xscale/ixp425/ixp425reg.h> 86#include <arm/xscale/ixp425/ixp425var.h> 87#endif 88 89/* PRIMARY CACHE VARIABLES */ 90int arm_picache_size; 91int arm_picache_line_size; 92int arm_picache_ways; 93 94int arm_pdcache_size; /* and unified */ 95int arm_pdcache_line_size; 96int arm_pdcache_ways; 97 98int arm_pcache_type; 99int arm_pcache_unified; 100 101int arm_dcache_align; 102int arm_dcache_align_mask; 103 104u_int arm_cache_level; 105u_int arm_cache_type[14]; 106u_int arm_cache_loc; 107 108/* 1 == use cpu_sleep(), 0 == don't */ 109int cpu_do_powersave; 110int ctrl; 111 112#ifdef CPU_ARM9 113struct cpu_functions arm9_cpufuncs = { 114 /* CPU functions */ 115 116 cpufunc_id, /* id */ 117 cpufunc_nullop, /* cpwait */ 118 119 /* MMU functions */ 120 121 cpufunc_control, /* control */ 122 cpufunc_domains, /* Domain */ 123 arm9_setttb, /* Setttb */ 124 cpufunc_faultstatus, /* Faultstatus */ 125 cpufunc_faultaddress, /* Faultaddress */ 126 127 /* TLB functions */ 128 129 armv4_tlb_flushID, /* tlb_flushID */ 130 arm9_tlb_flushID_SE, /* tlb_flushID_SE */ 131 armv4_tlb_flushI, /* tlb_flushI */ 132 (void *)armv4_tlb_flushI, /* tlb_flushI_SE */ 133 armv4_tlb_flushD, /* tlb_flushD */ 134 armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 135 136 /* Cache operations */ 137 138 arm9_icache_sync_all, /* icache_sync_all */ 139 arm9_icache_sync_range, /* icache_sync_range */ 140 141 arm9_dcache_wbinv_all, /* dcache_wbinv_all */ 142 arm9_dcache_wbinv_range, /* dcache_wbinv_range */ 143 arm9_dcache_inv_range, /* dcache_inv_range */ 144 arm9_dcache_wb_range, /* dcache_wb_range */ 145 146 armv4_idcache_inv_all, /* idcache_inv_all */ 147 arm9_idcache_wbinv_all, /* idcache_wbinv_all */ 148 arm9_idcache_wbinv_range, /* idcache_wbinv_range */ 149 cpufunc_nullop, /* l2cache_wbinv_all */ 150 (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 151 (void *)cpufunc_nullop, /* l2cache_inv_range */ 152 (void *)cpufunc_nullop, /* l2cache_wb_range */ 153 (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ 154 155 /* Other functions */ 156 157 cpufunc_nullop, /* flush_prefetchbuf */ 158 armv4_drain_writebuf, /* drain_writebuf */ 159 cpufunc_nullop, /* flush_brnchtgt_C */ 160 (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 161 162 (void *)cpufunc_nullop, /* sleep */ 163 164 /* Soft functions */ 165 166 cpufunc_null_fixup, /* dataabt_fixup */ 167 cpufunc_null_fixup, /* prefetchabt_fixup */ 168 169 arm9_context_switch, /* context_switch */ 170 171 arm9_setup /* cpu setup */ 172 173}; 174#endif /* CPU_ARM9 */ 175 176#if defined(CPU_ARM9E) || defined(CPU_ARM10) 177struct cpu_functions armv5_ec_cpufuncs = { 178 /* CPU functions */ 179 180 cpufunc_id, /* id */ 181 cpufunc_nullop, /* cpwait */ 182 183 /* MMU functions */ 184 185 cpufunc_control, /* control */ 186 cpufunc_domains, /* Domain */ 187 armv5_ec_setttb, /* Setttb */ 188 cpufunc_faultstatus, /* Faultstatus */ 189 cpufunc_faultaddress, /* Faultaddress */ 190 191 /* TLB functions */ 192 193 armv4_tlb_flushID, /* tlb_flushID */ 194 arm10_tlb_flushID_SE, /* tlb_flushID_SE */ 195 armv4_tlb_flushI, /* tlb_flushI */ 196 arm10_tlb_flushI_SE, /* tlb_flushI_SE */ 197 armv4_tlb_flushD, /* tlb_flushD */ 198 armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 199 200 /* Cache operations */ 201 202 armv5_ec_icache_sync_all, /* icache_sync_all */ 203 armv5_ec_icache_sync_range, /* icache_sync_range */ 204 205 armv5_ec_dcache_wbinv_all, /* dcache_wbinv_all */ 206 armv5_ec_dcache_wbinv_range, /* dcache_wbinv_range */ 207 armv5_ec_dcache_inv_range, /* dcache_inv_range */ 208 armv5_ec_dcache_wb_range, /* dcache_wb_range */ 209 210 armv4_idcache_inv_all, /* idcache_inv_all */ 211 armv5_ec_idcache_wbinv_all, /* idcache_wbinv_all */ 212 armv5_ec_idcache_wbinv_range, /* idcache_wbinv_range */ 213 214 cpufunc_nullop, /* l2cache_wbinv_all */ 215 (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 216 (void *)cpufunc_nullop, /* l2cache_inv_range */ 217 (void *)cpufunc_nullop, /* l2cache_wb_range */ 218 (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ 219 220 /* Other functions */ 221 222 cpufunc_nullop, /* flush_prefetchbuf */ 223 armv4_drain_writebuf, /* drain_writebuf */ 224 cpufunc_nullop, /* flush_brnchtgt_C */ 225 (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 226 227 (void *)cpufunc_nullop, /* sleep */ 228 229 /* Soft functions */ 230 231 cpufunc_null_fixup, /* dataabt_fixup */ 232 cpufunc_null_fixup, /* prefetchabt_fixup */ 233 234 arm10_context_switch, /* context_switch */ 235 236 arm10_setup /* cpu setup */ 237 238}; 239 240struct cpu_functions sheeva_cpufuncs = { 241 /* CPU functions */ 242 243 cpufunc_id, /* id */ 244 cpufunc_nullop, /* cpwait */ 245 246 /* MMU functions */ 247 248 cpufunc_control, /* control */ 249 cpufunc_domains, /* Domain */ 250 sheeva_setttb, /* Setttb */ 251 cpufunc_faultstatus, /* Faultstatus */ 252 cpufunc_faultaddress, /* Faultaddress */ 253 254 /* TLB functions */ 255 256 armv4_tlb_flushID, /* tlb_flushID */ 257 arm10_tlb_flushID_SE, /* tlb_flushID_SE */ 258 armv4_tlb_flushI, /* tlb_flushI */ 259 arm10_tlb_flushI_SE, /* tlb_flushI_SE */ 260 armv4_tlb_flushD, /* tlb_flushD */ 261 armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 262 263 /* Cache operations */ 264 265 armv5_ec_icache_sync_all, /* icache_sync_all */ 266 armv5_ec_icache_sync_range, /* icache_sync_range */ 267 268 armv5_ec_dcache_wbinv_all, /* dcache_wbinv_all */ 269 sheeva_dcache_wbinv_range, /* dcache_wbinv_range */ 270 sheeva_dcache_inv_range, /* dcache_inv_range */ 271 sheeva_dcache_wb_range, /* dcache_wb_range */ 272 273 armv4_idcache_inv_all, /* idcache_inv_all */ 274 armv5_ec_idcache_wbinv_all, /* idcache_wbinv_all */ 275 sheeva_idcache_wbinv_range, /* idcache_wbinv_all */ 276 277 sheeva_l2cache_wbinv_all, /* l2cache_wbinv_all */ 278 sheeva_l2cache_wbinv_range, /* l2cache_wbinv_range */ 279 sheeva_l2cache_inv_range, /* l2cache_inv_range */ 280 sheeva_l2cache_wb_range, /* l2cache_wb_range */ 281 (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ 282 283 /* Other functions */ 284 285 cpufunc_nullop, /* flush_prefetchbuf */ 286 armv4_drain_writebuf, /* drain_writebuf */ 287 cpufunc_nullop, /* flush_brnchtgt_C */ 288 (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 289 290 sheeva_cpu_sleep, /* sleep */ 291 292 /* Soft functions */ 293 294 cpufunc_null_fixup, /* dataabt_fixup */ 295 cpufunc_null_fixup, /* prefetchabt_fixup */ 296 297 arm10_context_switch, /* context_switch */ 298 299 arm10_setup /* cpu setup */ 300}; 301#endif /* CPU_ARM9E || CPU_ARM10 */ 302 303#ifdef CPU_ARM10 304struct cpu_functions arm10_cpufuncs = { 305 /* CPU functions */ 306 307 cpufunc_id, /* id */ 308 cpufunc_nullop, /* cpwait */ 309 310 /* MMU functions */ 311 312 cpufunc_control, /* control */ 313 cpufunc_domains, /* Domain */ 314 arm10_setttb, /* Setttb */ 315 cpufunc_faultstatus, /* Faultstatus */ 316 cpufunc_faultaddress, /* Faultaddress */ 317 318 /* TLB functions */ 319 320 armv4_tlb_flushID, /* tlb_flushID */ 321 arm10_tlb_flushID_SE, /* tlb_flushID_SE */ 322 armv4_tlb_flushI, /* tlb_flushI */ 323 arm10_tlb_flushI_SE, /* tlb_flushI_SE */ 324 armv4_tlb_flushD, /* tlb_flushD */ 325 armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 326 327 /* Cache operations */ 328 329 arm10_icache_sync_all, /* icache_sync_all */ 330 arm10_icache_sync_range, /* icache_sync_range */ 331 332 arm10_dcache_wbinv_all, /* dcache_wbinv_all */ 333 arm10_dcache_wbinv_range, /* dcache_wbinv_range */ 334 arm10_dcache_inv_range, /* dcache_inv_range */ 335 arm10_dcache_wb_range, /* dcache_wb_range */ 336 337 armv4_idcache_inv_all, /* idcache_inv_all */ 338 arm10_idcache_wbinv_all, /* idcache_wbinv_all */ 339 arm10_idcache_wbinv_range, /* idcache_wbinv_range */ 340 cpufunc_nullop, /* l2cache_wbinv_all */ 341 (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 342 (void *)cpufunc_nullop, /* l2cache_inv_range */ 343 (void *)cpufunc_nullop, /* l2cache_wb_range */ 344 (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ 345 346 /* Other functions */ 347 348 cpufunc_nullop, /* flush_prefetchbuf */ 349 armv4_drain_writebuf, /* drain_writebuf */ 350 cpufunc_nullop, /* flush_brnchtgt_C */ 351 (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 352 353 (void *)cpufunc_nullop, /* sleep */ 354 355 /* Soft functions */ 356 357 cpufunc_null_fixup, /* dataabt_fixup */ 358 cpufunc_null_fixup, /* prefetchabt_fixup */ 359 360 arm10_context_switch, /* context_switch */ 361 362 arm10_setup /* cpu setup */ 363 364}; 365#endif /* CPU_ARM10 */ 366 367#ifdef CPU_MV_PJ4B 368struct cpu_functions pj4bv7_cpufuncs = { 369 /* CPU functions */ 370 371 cpufunc_id, /* id */ 372 armv7_drain_writebuf, /* cpwait */ 373 374 /* MMU functions */ 375 376 cpufunc_control, /* control */ 377 cpufunc_domains, /* Domain */ 378 armv7_setttb, /* Setttb */ 379 cpufunc_faultstatus, /* Faultstatus */ 380 cpufunc_faultaddress, /* Faultaddress */ 381 382 /* TLB functions */ 383 384 armv7_tlb_flushID, /* tlb_flushID */ 385 armv7_tlb_flushID_SE, /* tlb_flushID_SE */ 386 armv7_tlb_flushID, /* tlb_flushI */ 387 armv7_tlb_flushID_SE, /* tlb_flushI_SE */ 388 armv7_tlb_flushID, /* tlb_flushD */ 389 armv7_tlb_flushID_SE, /* tlb_flushD_SE */ 390 391 /* Cache operations */ 392 armv7_idcache_wbinv_all, /* icache_sync_all */ 393 armv7_icache_sync_range, /* icache_sync_range */ 394 395 armv7_dcache_wbinv_all, /* dcache_wbinv_all */ 396 armv7_dcache_wbinv_range, /* dcache_wbinv_range */ 397 armv7_dcache_inv_range, /* dcache_inv_range */ 398 armv7_dcache_wb_range, /* dcache_wb_range */ 399 400 armv7_idcache_inv_all, /* idcache_inv_all */ 401 armv7_idcache_wbinv_all, /* idcache_wbinv_all */ 402 armv7_idcache_wbinv_range, /* idcache_wbinv_all */ 403 404 (void *)cpufunc_nullop, /* l2cache_wbinv_all */ 405 (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 406 (void *)cpufunc_nullop, /* l2cache_inv_range */ 407 (void *)cpufunc_nullop, /* l2cache_wb_range */ 408 (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ 409 410 /* Other functions */ 411 412 cpufunc_nullop, /* flush_prefetchbuf */ 413 armv7_drain_writebuf, /* drain_writebuf */ 414 cpufunc_nullop, /* flush_brnchtgt_C */ 415 (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 416 417 (void *)cpufunc_nullop, /* sleep */ 418 419 /* Soft functions */ 420 421 cpufunc_null_fixup, /* dataabt_fixup */ 422 cpufunc_null_fixup, /* prefetchabt_fixup */ 423 424 armv7_context_switch, /* context_switch */ 425 426 pj4bv7_setup /* cpu setup */ 427}; 428#endif /* CPU_MV_PJ4B */ 429 430#if defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \ 431 defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \ 432 defined(CPU_XSCALE_80219) 433 434struct cpu_functions xscale_cpufuncs = { 435 /* CPU functions */ 436 437 cpufunc_id, /* id */ 438 xscale_cpwait, /* cpwait */ 439 440 /* MMU functions */ 441 442 xscale_control, /* control */ 443 cpufunc_domains, /* domain */ 444 xscale_setttb, /* setttb */ 445 cpufunc_faultstatus, /* faultstatus */ 446 cpufunc_faultaddress, /* faultaddress */ 447 448 /* TLB functions */ 449 450 armv4_tlb_flushID, /* tlb_flushID */ 451 xscale_tlb_flushID_SE, /* tlb_flushID_SE */ 452 armv4_tlb_flushI, /* tlb_flushI */ 453 (void *)armv4_tlb_flushI, /* tlb_flushI_SE */ 454 armv4_tlb_flushD, /* tlb_flushD */ 455 armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 456 457 /* Cache operations */ 458 459 xscale_cache_syncI, /* icache_sync_all */ 460 xscale_cache_syncI_rng, /* icache_sync_range */ 461 462 xscale_cache_purgeD, /* dcache_wbinv_all */ 463 xscale_cache_purgeD_rng, /* dcache_wbinv_range */ 464 xscale_cache_flushD_rng, /* dcache_inv_range */ 465 xscale_cache_cleanD_rng, /* dcache_wb_range */ 466 467 xscale_cache_flushID, /* idcache_inv_all */ 468 xscale_cache_purgeID, /* idcache_wbinv_all */ 469 xscale_cache_purgeID_rng, /* idcache_wbinv_range */ 470 cpufunc_nullop, /* l2cache_wbinv_all */ 471 (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 472 (void *)cpufunc_nullop, /* l2cache_inv_range */ 473 (void *)cpufunc_nullop, /* l2cache_wb_range */ 474 (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ 475 476 /* Other functions */ 477 478 cpufunc_nullop, /* flush_prefetchbuf */ 479 armv4_drain_writebuf, /* drain_writebuf */ 480 cpufunc_nullop, /* flush_brnchtgt_C */ 481 (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 482 483 xscale_cpu_sleep, /* sleep */ 484 485 /* Soft functions */ 486 487 cpufunc_null_fixup, /* dataabt_fixup */ 488 cpufunc_null_fixup, /* prefetchabt_fixup */ 489 490 xscale_context_switch, /* context_switch */ 491 492 xscale_setup /* cpu setup */ 493}; 494#endif 495/* CPU_XSCALE_80200 || CPU_XSCALE_80321 || CPU_XSCALE_PXA2X0 || CPU_XSCALE_IXP425 496 CPU_XSCALE_80219 */ 497 498#ifdef CPU_XSCALE_81342 499struct cpu_functions xscalec3_cpufuncs = { 500 /* CPU functions */ 501 502 cpufunc_id, /* id */ 503 xscale_cpwait, /* cpwait */ 504 505 /* MMU functions */ 506 507 xscale_control, /* control */ 508 cpufunc_domains, /* domain */ 509 xscalec3_setttb, /* setttb */ 510 cpufunc_faultstatus, /* faultstatus */ 511 cpufunc_faultaddress, /* faultaddress */ 512 513 /* TLB functions */ 514 515 armv4_tlb_flushID, /* tlb_flushID */ 516 xscale_tlb_flushID_SE, /* tlb_flushID_SE */ 517 armv4_tlb_flushI, /* tlb_flushI */ 518 (void *)armv4_tlb_flushI, /* tlb_flushI_SE */ 519 armv4_tlb_flushD, /* tlb_flushD */ 520 armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 521 522 /* Cache operations */ 523 524 xscalec3_cache_syncI, /* icache_sync_all */ 525 xscalec3_cache_syncI_rng, /* icache_sync_range */ 526 527 xscalec3_cache_purgeD, /* dcache_wbinv_all */ 528 xscalec3_cache_purgeD_rng, /* dcache_wbinv_range */ 529 xscale_cache_flushD_rng, /* dcache_inv_range */ 530 xscalec3_cache_cleanD_rng, /* dcache_wb_range */ 531 532 xscale_cache_flushID, /* idcache_inv_all */ 533 xscalec3_cache_purgeID, /* idcache_wbinv_all */ 534 xscalec3_cache_purgeID_rng, /* idcache_wbinv_range */ 535 xscalec3_l2cache_purge, /* l2cache_wbinv_all */ 536 xscalec3_l2cache_purge_rng, /* l2cache_wbinv_range */ 537 xscalec3_l2cache_flush_rng, /* l2cache_inv_range */ 538 xscalec3_l2cache_clean_rng, /* l2cache_wb_range */ 539 (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ 540 541 /* Other functions */ 542 543 cpufunc_nullop, /* flush_prefetchbuf */ 544 armv4_drain_writebuf, /* drain_writebuf */ 545 cpufunc_nullop, /* flush_brnchtgt_C */ 546 (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 547 548 xscale_cpu_sleep, /* sleep */ 549 550 /* Soft functions */ 551 552 cpufunc_null_fixup, /* dataabt_fixup */ 553 cpufunc_null_fixup, /* prefetchabt_fixup */ 554 555 xscalec3_context_switch, /* context_switch */ 556 557 xscale_setup /* cpu setup */ 558}; 559#endif /* CPU_XSCALE_81342 */ 560 561 562#if defined(CPU_FA526) || defined(CPU_FA626TE) 563struct cpu_functions fa526_cpufuncs = { 564 /* CPU functions */ 565 566 cpufunc_id, /* id */ 567 cpufunc_nullop, /* cpwait */ 568 569 /* MMU functions */ 570 571 cpufunc_control, /* control */ 572 cpufunc_domains, /* domain */ 573 fa526_setttb, /* setttb */ 574 cpufunc_faultstatus, /* faultstatus */ 575 cpufunc_faultaddress, /* faultaddress */ 576 577 /* TLB functions */ 578 579 armv4_tlb_flushID, /* tlb_flushID */ 580 fa526_tlb_flushID_SE, /* tlb_flushID_SE */ 581 armv4_tlb_flushI, /* tlb_flushI */ 582 fa526_tlb_flushI_SE, /* tlb_flushI_SE */ 583 armv4_tlb_flushD, /* tlb_flushD */ 584 armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 585 586 /* Cache operations */ 587 588 fa526_icache_sync_all, /* icache_sync_all */ 589 fa526_icache_sync_range, /* icache_sync_range */ 590 591 fa526_dcache_wbinv_all, /* dcache_wbinv_all */ 592 fa526_dcache_wbinv_range, /* dcache_wbinv_range */ 593 fa526_dcache_inv_range, /* dcache_inv_range */ 594 fa526_dcache_wb_range, /* dcache_wb_range */ 595 596 armv4_idcache_inv_all, /* idcache_inv_all */ 597 fa526_idcache_wbinv_all, /* idcache_wbinv_all */ 598 fa526_idcache_wbinv_range, /* idcache_wbinv_range */ 599 cpufunc_nullop, /* l2cache_wbinv_all */ 600 (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 601 (void *)cpufunc_nullop, /* l2cache_inv_range */ 602 (void *)cpufunc_nullop, /* l2cache_wb_range */ 603 (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ 604 605 /* Other functions */ 606 607 fa526_flush_prefetchbuf, /* flush_prefetchbuf */ 608 armv4_drain_writebuf, /* drain_writebuf */ 609 cpufunc_nullop, /* flush_brnchtgt_C */ 610 fa526_flush_brnchtgt_E, /* flush_brnchtgt_E */ 611 612 fa526_cpu_sleep, /* sleep */ 613 614 /* Soft functions */ 615 616 cpufunc_null_fixup, /* dataabt_fixup */ 617 cpufunc_null_fixup, /* prefetchabt_fixup */ 618 619 fa526_context_switch, /* context_switch */ 620 621 fa526_setup /* cpu setup */ 622}; 623#endif /* CPU_FA526 || CPU_FA626TE */ 624 625#if defined(CPU_ARM1136) 626struct cpu_functions arm1136_cpufuncs = { 627 /* CPU functions */ 628 629 cpufunc_id, /* id */ 630 cpufunc_nullop, /* cpwait */ 631 632 /* MMU functions */ 633 634 cpufunc_control, /* control */ 635 cpufunc_domains, /* Domain */ 636 arm11x6_setttb, /* Setttb */ 637 cpufunc_faultstatus, /* Faultstatus */ 638 cpufunc_faultaddress, /* Faultaddress */ 639 640 /* TLB functions */ 641 642 arm11_tlb_flushID, /* tlb_flushID */ 643 arm11_tlb_flushID_SE, /* tlb_flushID_SE */ 644 arm11_tlb_flushI, /* tlb_flushI */ 645 arm11_tlb_flushI_SE, /* tlb_flushI_SE */ 646 arm11_tlb_flushD, /* tlb_flushD */ 647 arm11_tlb_flushD_SE, /* tlb_flushD_SE */ 648 649 /* Cache operations */ 650 651 arm11x6_icache_sync_all, /* icache_sync_all */ 652 arm11x6_icache_sync_range, /* icache_sync_range */ 653 654 arm11x6_dcache_wbinv_all, /* dcache_wbinv_all */ 655 armv6_dcache_wbinv_range, /* dcache_wbinv_range */ 656 armv6_dcache_inv_range, /* dcache_inv_range */ 657 armv6_dcache_wb_range, /* dcache_wb_range */ 658 659 armv6_idcache_inv_all, /* idcache_inv_all */ 660 arm11x6_idcache_wbinv_all, /* idcache_wbinv_all */ 661 arm11x6_idcache_wbinv_range, /* idcache_wbinv_range */ 662 663 (void *)cpufunc_nullop, /* l2cache_wbinv_all */ 664 (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 665 (void *)cpufunc_nullop, /* l2cache_inv_range */ 666 (void *)cpufunc_nullop, /* l2cache_wb_range */ 667 (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ 668 669 /* Other functions */ 670 671 arm11x6_flush_prefetchbuf, /* flush_prefetchbuf */ 672 arm11_drain_writebuf, /* drain_writebuf */ 673 cpufunc_nullop, /* flush_brnchtgt_C */ 674 (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 675 676 arm11_sleep, /* sleep */ 677 678 /* Soft functions */ 679 680 cpufunc_null_fixup, /* dataabt_fixup */ 681 cpufunc_null_fixup, /* prefetchabt_fixup */ 682 683 arm11_context_switch, /* context_switch */ 684 685 arm11x6_setup /* cpu setup */ 686}; 687#endif /* CPU_ARM1136 */ 688#if defined(CPU_ARM1176) 689struct cpu_functions arm1176_cpufuncs = { 690 /* CPU functions */ 691 692 cpufunc_id, /* id */ 693 cpufunc_nullop, /* cpwait */ 694 695 /* MMU functions */ 696 697 cpufunc_control, /* control */ 698 cpufunc_domains, /* Domain */ 699 arm11x6_setttb, /* Setttb */ 700 cpufunc_faultstatus, /* Faultstatus */ 701 cpufunc_faultaddress, /* Faultaddress */ 702 703 /* TLB functions */ 704 705 arm11_tlb_flushID, /* tlb_flushID */ 706 arm11_tlb_flushID_SE, /* tlb_flushID_SE */ 707 arm11_tlb_flushI, /* tlb_flushI */ 708 arm11_tlb_flushI_SE, /* tlb_flushI_SE */ 709 arm11_tlb_flushD, /* tlb_flushD */ 710 arm11_tlb_flushD_SE, /* tlb_flushD_SE */ 711 712 /* Cache operations */ 713 714 arm11x6_icache_sync_all, /* icache_sync_all */ 715 arm11x6_icache_sync_range, /* icache_sync_range */ 716 717 arm11x6_dcache_wbinv_all, /* dcache_wbinv_all */ 718 armv6_dcache_wbinv_range, /* dcache_wbinv_range */ 719 armv6_dcache_inv_range, /* dcache_inv_range */ 720 armv6_dcache_wb_range, /* dcache_wb_range */ 721 722 armv6_idcache_inv_all, /* idcache_inv_all */ 723 arm11x6_idcache_wbinv_all, /* idcache_wbinv_all */ 724 arm11x6_idcache_wbinv_range, /* idcache_wbinv_range */ 725 726 (void *)cpufunc_nullop, /* l2cache_wbinv_all */ 727 (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 728 (void *)cpufunc_nullop, /* l2cache_inv_range */ 729 (void *)cpufunc_nullop, /* l2cache_wb_range */ 730 (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ 731 732 /* Other functions */ 733 734 arm11x6_flush_prefetchbuf, /* flush_prefetchbuf */ 735 arm11_drain_writebuf, /* drain_writebuf */ 736 cpufunc_nullop, /* flush_brnchtgt_C */ 737 (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 738 739 arm11x6_sleep, /* sleep */ 740 741 /* Soft functions */ 742 743 cpufunc_null_fixup, /* dataabt_fixup */ 744 cpufunc_null_fixup, /* prefetchabt_fixup */ 745 746 arm11_context_switch, /* context_switch */ 747 748 arm11x6_setup /* cpu setup */ 749}; 750#endif /*CPU_ARM1176 */ 751 752#if defined(CPU_CORTEXA) || defined(CPU_KRAIT) 753struct cpu_functions cortexa_cpufuncs = { 754 /* CPU functions */ 755 756 cpufunc_id, /* id */ 757 cpufunc_nullop, /* cpwait */ 758 759 /* MMU functions */ 760 761 cpufunc_control, /* control */ 762 cpufunc_domains, /* Domain */ 763 armv7_setttb, /* Setttb */ 764 cpufunc_faultstatus, /* Faultstatus */ 765 cpufunc_faultaddress, /* Faultaddress */ 766 767 /* 768 * TLB functions. ARMv7 does all TLB ops based on a unified TLB model 769 * whether the hardware implements separate I+D or not, so we use the 770 * same 'ID' functions for all 3 variations. 771 */ 772 773 armv7_tlb_flushID, /* tlb_flushID */ 774 armv7_tlb_flushID_SE, /* tlb_flushID_SE */ 775 armv7_tlb_flushID, /* tlb_flushI */ 776 armv7_tlb_flushID_SE, /* tlb_flushI_SE */ 777 armv7_tlb_flushID, /* tlb_flushD */ 778 armv7_tlb_flushID_SE, /* tlb_flushD_SE */ 779 780 /* Cache operations */ 781 782 armv7_icache_sync_all, /* icache_sync_all */ 783 armv7_icache_sync_range, /* icache_sync_range */ 784 785 armv7_dcache_wbinv_all, /* dcache_wbinv_all */ 786 armv7_dcache_wbinv_range, /* dcache_wbinv_range */ 787 armv7_dcache_inv_range, /* dcache_inv_range */ 788 armv7_dcache_wb_range, /* dcache_wb_range */ 789 790 armv7_idcache_inv_all, /* idcache_inv_all */ 791 armv7_idcache_wbinv_all, /* idcache_wbinv_all */ 792 armv7_idcache_wbinv_range, /* idcache_wbinv_range */ 793 794 /* 795 * Note: For CPUs using the PL310 the L2 ops are filled in when the 796 * L2 cache controller is actually enabled. 797 */ 798 cpufunc_nullop, /* l2cache_wbinv_all */ 799 (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 800 (void *)cpufunc_nullop, /* l2cache_inv_range */ 801 (void *)cpufunc_nullop, /* l2cache_wb_range */ 802 (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ 803 804 /* Other functions */ 805 806 cpufunc_nullop, /* flush_prefetchbuf */ 807 armv7_drain_writebuf, /* drain_writebuf */ 808 cpufunc_nullop, /* flush_brnchtgt_C */ 809 (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 810 811 armv7_sleep, /* sleep */ 812 813 /* Soft functions */ 814 815 cpufunc_null_fixup, /* dataabt_fixup */ 816 cpufunc_null_fixup, /* prefetchabt_fixup */ 817 818 armv7_context_switch, /* context_switch */ 819 820 cortexa_setup /* cpu setup */ 821}; 822#endif /* CPU_CORTEXA */ 823 824/* 825 * Global constants also used by locore.s 826 */ 827 828struct cpu_functions cpufuncs; 829u_int cputype; 830u_int cpu_reset_needs_v4_MMU_disable; /* flag used in locore.s */ 831 832#if defined(CPU_ARM9) || \ 833 defined (CPU_ARM9E) || defined (CPU_ARM10) || defined (CPU_ARM1136) || \ 834 defined(CPU_ARM1176) || defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \ 835 defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \ 836 defined(CPU_FA526) || defined(CPU_FA626TE) || defined(CPU_MV_PJ4B) || \ 837 defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342) || \ 838 defined(CPU_CORTEXA) || defined(CPU_KRAIT) 839 840/* Global cache line sizes, use 32 as default */ 841int arm_dcache_min_line_size = 32; 842int arm_icache_min_line_size = 32; 843int arm_idcache_min_line_size = 32; 844 845static void get_cachetype_cp15(void); 846 847/* Additional cache information local to this file. Log2 of some of the 848 above numbers. */ 849static int arm_dcache_l2_nsets; 850static int arm_dcache_l2_assoc; 851static int arm_dcache_l2_linesize; 852 853static void 854get_cachetype_cp15() 855{ 856 u_int ctype, isize, dsize, cpuid; 857 u_int clevel, csize, i, sel; 858 u_int multiplier; 859 u_char type; 860 861 __asm __volatile("mrc p15, 0, %0, c0, c0, 1" 862 : "=r" (ctype)); 863 864 cpuid = cpufunc_id(); 865 /* 866 * ...and thus spake the ARM ARM: 867 * 868 * If an <opcode2> value corresponding to an unimplemented or 869 * reserved ID register is encountered, the System Control 870 * processor returns the value of the main ID register. 871 */ 872 if (ctype == cpuid) 873 goto out; 874 875 if (CPU_CT_FORMAT(ctype) == CPU_CT_ARMV7) { 876 /* Resolve minimal cache line sizes */ 877 arm_dcache_min_line_size = 1 << (CPU_CT_DMINLINE(ctype) + 2); 878 arm_icache_min_line_size = 1 << (CPU_CT_IMINLINE(ctype) + 2); 879 arm_idcache_min_line_size = 880 min(arm_icache_min_line_size, arm_dcache_min_line_size); 881 882 __asm __volatile("mrc p15, 1, %0, c0, c0, 1" 883 : "=r" (clevel)); 884 arm_cache_level = clevel; 885 arm_cache_loc = CPU_CLIDR_LOC(arm_cache_level); 886 i = 0; 887 while ((type = (clevel & 0x7)) && i < 7) { 888 if (type == CACHE_DCACHE || type == CACHE_UNI_CACHE || 889 type == CACHE_SEP_CACHE) { 890 sel = i << 1; 891 __asm __volatile("mcr p15, 2, %0, c0, c0, 0" 892 : : "r" (sel)); 893 __asm __volatile("mrc p15, 1, %0, c0, c0, 0" 894 : "=r" (csize)); 895 arm_cache_type[sel] = csize; 896 arm_dcache_align = 1 << 897 (CPUV7_CT_xSIZE_LEN(csize) + 4); 898 arm_dcache_align_mask = arm_dcache_align - 1; 899 } 900 if (type == CACHE_ICACHE || type == CACHE_SEP_CACHE) { 901 sel = (i << 1) | 1; 902 __asm __volatile("mcr p15, 2, %0, c0, c0, 0" 903 : : "r" (sel)); 904 __asm __volatile("mrc p15, 1, %0, c0, c0, 0" 905 : "=r" (csize)); 906 arm_cache_type[sel] = csize; 907 } 908 i++; 909 clevel >>= 3; 910 } 911 } else { 912 if ((ctype & CPU_CT_S) == 0) 913 arm_pcache_unified = 1; 914 915 /* 916 * If you want to know how this code works, go read the ARM ARM. 917 */ 918 919 arm_pcache_type = CPU_CT_CTYPE(ctype); 920 921 if (arm_pcache_unified == 0) { 922 isize = CPU_CT_ISIZE(ctype); 923 multiplier = (isize & CPU_CT_xSIZE_M) ? 3 : 2; 924 arm_picache_line_size = 1U << (CPU_CT_xSIZE_LEN(isize) + 3); 925 if (CPU_CT_xSIZE_ASSOC(isize) == 0) { 926 if (isize & CPU_CT_xSIZE_M) 927 arm_picache_line_size = 0; /* not present */ 928 else 929 arm_picache_ways = 1; 930 } else { 931 arm_picache_ways = multiplier << 932 (CPU_CT_xSIZE_ASSOC(isize) - 1); 933 } 934 arm_picache_size = multiplier << (CPU_CT_xSIZE_SIZE(isize) + 8); 935 } 936 937 dsize = CPU_CT_DSIZE(ctype); 938 multiplier = (dsize & CPU_CT_xSIZE_M) ? 3 : 2; 939 arm_pdcache_line_size = 1U << (CPU_CT_xSIZE_LEN(dsize) + 3); 940 if (CPU_CT_xSIZE_ASSOC(dsize) == 0) { 941 if (dsize & CPU_CT_xSIZE_M) 942 arm_pdcache_line_size = 0; /* not present */ 943 else 944 arm_pdcache_ways = 1; 945 } else { 946 arm_pdcache_ways = multiplier << 947 (CPU_CT_xSIZE_ASSOC(dsize) - 1); 948 } 949 arm_pdcache_size = multiplier << (CPU_CT_xSIZE_SIZE(dsize) + 8); 950 951 arm_dcache_align = arm_pdcache_line_size; 952 953 arm_dcache_l2_assoc = CPU_CT_xSIZE_ASSOC(dsize) + multiplier - 2; 954 arm_dcache_l2_linesize = CPU_CT_xSIZE_LEN(dsize) + 3; 955 arm_dcache_l2_nsets = 6 + CPU_CT_xSIZE_SIZE(dsize) - 956 CPU_CT_xSIZE_ASSOC(dsize) - CPU_CT_xSIZE_LEN(dsize); 957 958 out: 959 arm_dcache_align_mask = arm_dcache_align - 1; 960 } 961} 962#endif /* ARM9 || XSCALE */ 963 964/* 965 * Cannot panic here as we may not have a console yet ... 966 */ 967 968int 969set_cpufuncs() 970{ 971 cputype = cpufunc_id(); 972 cputype &= CPU_ID_CPU_MASK; 973 974 /* 975 * NOTE: cpu_do_powersave defaults to off. If we encounter a 976 * CPU type where we want to use it by default, then we set it. 977 */ 978 979#ifdef CPU_ARM9 980 if (((cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_ARM_LTD || 981 (cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_TI) && 982 (cputype & 0x0000f000) == 0x00009000) { 983 cpufuncs = arm9_cpufuncs; 984 cpu_reset_needs_v4_MMU_disable = 1; /* V4 or higher */ 985 get_cachetype_cp15(); 986 arm9_dcache_sets_inc = 1U << arm_dcache_l2_linesize; 987 arm9_dcache_sets_max = (1U << (arm_dcache_l2_linesize + 988 arm_dcache_l2_nsets)) - arm9_dcache_sets_inc; 989 arm9_dcache_index_inc = 1U << (32 - arm_dcache_l2_assoc); 990 arm9_dcache_index_max = 0U - arm9_dcache_index_inc; 991#ifdef ARM9_CACHE_WRITE_THROUGH 992 pmap_pte_init_arm9(); 993#else 994 pmap_pte_init_generic(); 995#endif 996 goto out; 997 } 998#endif /* CPU_ARM9 */ 999#if defined(CPU_ARM9E) || defined(CPU_ARM10) 1000 if (cputype == CPU_ID_MV88FR131 || cputype == CPU_ID_MV88FR571_VD || 1001 cputype == CPU_ID_MV88FR571_41) { 1002 uint32_t sheeva_ctrl; 1003 1004 sheeva_ctrl = (MV_DC_STREAM_ENABLE | MV_BTB_DISABLE | 1005 MV_L2_ENABLE); 1006 /* 1007 * Workaround for Marvell MV78100 CPU: Cache prefetch 1008 * mechanism may affect the cache coherency validity, 1009 * so it needs to be disabled. 1010 * 1011 * Refer to errata document MV-S501058-00C.pdf (p. 3.1 1012 * L2 Prefetching Mechanism) for details. 1013 */ 1014 if (cputype == CPU_ID_MV88FR571_VD || 1015 cputype == CPU_ID_MV88FR571_41) 1016 sheeva_ctrl |= MV_L2_PREFETCH_DISABLE; 1017 1018 sheeva_control_ext(0xffffffff & ~MV_WA_ENABLE, sheeva_ctrl); 1019 1020 cpufuncs = sheeva_cpufuncs; 1021 get_cachetype_cp15(); 1022 pmap_pte_init_generic(); 1023 goto out; 1024 } else if (cputype == CPU_ID_ARM926EJS || cputype == CPU_ID_ARM1026EJS) { 1025 cpufuncs = armv5_ec_cpufuncs; 1026 get_cachetype_cp15(); 1027 pmap_pte_init_generic(); 1028 goto out; 1029 } 1030#endif /* CPU_ARM9E || CPU_ARM10 */ 1031#ifdef CPU_ARM10 1032 if (/* cputype == CPU_ID_ARM1020T || */ 1033 cputype == CPU_ID_ARM1020E) { 1034 /* 1035 * Select write-through cacheing (this isn't really an 1036 * option on ARM1020T). 1037 */ 1038 cpufuncs = arm10_cpufuncs; 1039 cpu_reset_needs_v4_MMU_disable = 1; /* V4 or higher */ 1040 get_cachetype_cp15(); 1041 arm10_dcache_sets_inc = 1U << arm_dcache_l2_linesize; 1042 arm10_dcache_sets_max = 1043 (1U << (arm_dcache_l2_linesize + arm_dcache_l2_nsets)) - 1044 arm10_dcache_sets_inc; 1045 arm10_dcache_index_inc = 1U << (32 - arm_dcache_l2_assoc); 1046 arm10_dcache_index_max = 0U - arm10_dcache_index_inc; 1047 pmap_pte_init_generic(); 1048 goto out; 1049 } 1050#endif /* CPU_ARM10 */ 1051#if defined(CPU_ARM1136) || defined(CPU_ARM1176) 1052 if (cputype == CPU_ID_ARM1136JS 1053 || cputype == CPU_ID_ARM1136JSR1 1054 || cputype == CPU_ID_ARM1176JZS) { 1055#ifdef CPU_ARM1136 1056 if (cputype == CPU_ID_ARM1136JS 1057 || cputype == CPU_ID_ARM1136JSR1) 1058 cpufuncs = arm1136_cpufuncs; 1059#endif 1060#ifdef CPU_ARM1176 1061 if (cputype == CPU_ID_ARM1176JZS) 1062 cpufuncs = arm1176_cpufuncs; 1063#endif 1064 cpu_reset_needs_v4_MMU_disable = 1; /* V4 or higher */ 1065 get_cachetype_cp15(); 1066 1067 pmap_pte_init_mmu_v6(); 1068 1069 goto out; 1070 } 1071#endif /* CPU_ARM1136 || CPU_ARM1176 */ 1072#if defined(CPU_CORTEXA) || defined(CPU_KRAIT) 1073 if (cputype == CPU_ID_CORTEXA5 || 1074 cputype == CPU_ID_CORTEXA7 || 1075 cputype == CPU_ID_CORTEXA8R1 || 1076 cputype == CPU_ID_CORTEXA8R2 || 1077 cputype == CPU_ID_CORTEXA8R3 || 1078 cputype == CPU_ID_CORTEXA9R1 || 1079 cputype == CPU_ID_CORTEXA9R2 || 1080 cputype == CPU_ID_CORTEXA9R3 || 1081 cputype == CPU_ID_CORTEXA12R0 || 1082 cputype == CPU_ID_CORTEXA15R0 || 1083 cputype == CPU_ID_CORTEXA15R1 || 1084 cputype == CPU_ID_CORTEXA15R2 || 1085 cputype == CPU_ID_CORTEXA15R3 || 1086 cputype == CPU_ID_KRAIT ) { 1087 cpufuncs = cortexa_cpufuncs; 1088 cpu_reset_needs_v4_MMU_disable = 1; /* V4 or higher */ 1089 get_cachetype_cp15(); 1090 1091 pmap_pte_init_mmu_v6(); 1092 /* Use powersave on this CPU. */ 1093 cpu_do_powersave = 1; 1094 goto out; 1095 } 1096#endif /* CPU_CORTEXA */ 1097 1098#if defined(CPU_MV_PJ4B) 1099 if (cputype == CPU_ID_MV88SV581X_V7 || 1100 cputype == CPU_ID_MV88SV584X_V7 || 1101 cputype == CPU_ID_ARM_88SV581X_V7) { 1102 cpufuncs = pj4bv7_cpufuncs; 1103 get_cachetype_cp15(); 1104 pmap_pte_init_mmu_v6(); 1105 goto out; 1106 } 1107#endif /* CPU_MV_PJ4B */ 1108 1109#if defined(CPU_FA526) || defined(CPU_FA626TE) 1110 if (cputype == CPU_ID_FA526 || cputype == CPU_ID_FA626TE) { 1111 cpufuncs = fa526_cpufuncs; 1112 cpu_reset_needs_v4_MMU_disable = 1; /* SA needs it */ 1113 get_cachetype_cp15(); 1114 pmap_pte_init_generic(); 1115 1116 /* Use powersave on this CPU. */ 1117 cpu_do_powersave = 1; 1118 1119 goto out; 1120 } 1121#endif /* CPU_FA526 || CPU_FA626TE */ 1122 1123#ifdef CPU_XSCALE_80200 1124 if (cputype == CPU_ID_80200) { 1125 int rev = cpufunc_id() & CPU_ID_REVISION_MASK; 1126 1127 i80200_icu_init(); 1128 1129#if defined(XSCALE_CCLKCFG) 1130 /* 1131 * Crank CCLKCFG to maximum legal value. 1132 */ 1133 __asm __volatile ("mcr p14, 0, %0, c6, c0, 0" 1134 : 1135 : "r" (XSCALE_CCLKCFG)); 1136#endif 1137 1138 /* 1139 * XXX Disable ECC in the Bus Controller Unit; we 1140 * don't really support it, yet. Clear any pending 1141 * error indications. 1142 */ 1143 __asm __volatile("mcr p13, 0, %0, c0, c1, 0" 1144 : 1145 : "r" (BCUCTL_E0|BCUCTL_E1|BCUCTL_EV)); 1146 1147 cpufuncs = xscale_cpufuncs; 1148 /* 1149 * i80200 errata: Step-A0 and A1 have a bug where 1150 * D$ dirty bits are not cleared on "invalidate by 1151 * address". 1152 * 1153 * Workaround: Clean cache line before invalidating. 1154 */ 1155 if (rev == 0 || rev == 1) 1156 cpufuncs.cf_dcache_inv_range = xscale_cache_purgeD_rng; 1157 1158 cpu_reset_needs_v4_MMU_disable = 1; /* XScale needs it */ 1159 get_cachetype_cp15(); 1160 pmap_pte_init_xscale(); 1161 goto out; 1162 } 1163#endif /* CPU_XSCALE_80200 */ 1164#if defined(CPU_XSCALE_80321) || defined(CPU_XSCALE_80219) 1165 if (cputype == CPU_ID_80321_400 || cputype == CPU_ID_80321_600 || 1166 cputype == CPU_ID_80321_400_B0 || cputype == CPU_ID_80321_600_B0 || 1167 cputype == CPU_ID_80219_400 || cputype == CPU_ID_80219_600) { 1168 cpufuncs = xscale_cpufuncs; 1169 cpu_reset_needs_v4_MMU_disable = 1; /* XScale needs it */ 1170 get_cachetype_cp15(); 1171 pmap_pte_init_xscale(); 1172 goto out; 1173 } 1174#endif /* CPU_XSCALE_80321 */ 1175 1176#if defined(CPU_XSCALE_81342) 1177 if (cputype == CPU_ID_81342) { 1178 cpufuncs = xscalec3_cpufuncs; 1179 cpu_reset_needs_v4_MMU_disable = 1; /* XScale needs it */ 1180 get_cachetype_cp15(); 1181 pmap_pte_init_xscale(); 1182 goto out; 1183 } 1184#endif /* CPU_XSCALE_81342 */ 1185#ifdef CPU_XSCALE_PXA2X0 1186 /* ignore core revision to test PXA2xx CPUs */ 1187 if ((cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA250 || 1188 (cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA27X || 1189 (cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA210) { 1190 1191 cpufuncs = xscale_cpufuncs; 1192 cpu_reset_needs_v4_MMU_disable = 1; /* XScale needs it */ 1193 get_cachetype_cp15(); 1194 pmap_pte_init_xscale(); 1195 1196 /* Use powersave on this CPU. */ 1197 cpu_do_powersave = 1; 1198 1199 goto out; 1200 } 1201#endif /* CPU_XSCALE_PXA2X0 */ 1202#ifdef CPU_XSCALE_IXP425 1203 if (cputype == CPU_ID_IXP425_533 || cputype == CPU_ID_IXP425_400 || 1204 cputype == CPU_ID_IXP425_266 || cputype == CPU_ID_IXP435) { 1205 1206 cpufuncs = xscale_cpufuncs; 1207 cpu_reset_needs_v4_MMU_disable = 1; /* XScale needs it */ 1208 get_cachetype_cp15(); 1209 pmap_pte_init_xscale(); 1210 1211 goto out; 1212 } 1213#endif /* CPU_XSCALE_IXP425 */ 1214 /* 1215 * Bzzzz. And the answer was ... 1216 */ 1217 panic("No support for this CPU type (%08x) in kernel", cputype); 1218 return(ARCHITECTURE_NOT_PRESENT); 1219out: 1220 uma_set_align(arm_dcache_align_mask); 1221 return (0); 1222} 1223 1224/* 1225 * Fixup routines for data and prefetch aborts. 1226 * 1227 * Several compile time symbols are used 1228 * 1229 * DEBUG_FAULT_CORRECTION - Print debugging information during the 1230 * correction of registers after a fault. 1231 */ 1232 1233 1234/* 1235 * Null abort fixup routine. 1236 * For use when no fixup is required. 1237 */ 1238int 1239cpufunc_null_fixup(arg) 1240 void *arg; 1241{ 1242 return(ABORT_FIXUP_OK); 1243} 1244 1245/* 1246 * CPU Setup code 1247 */ 1248 1249#if defined (CPU_ARM9) || \ 1250 defined(CPU_ARM9E) || \ 1251 defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \ 1252 defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \ 1253 defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342) || \ 1254 defined(CPU_ARM10) || defined(CPU_ARM1136) || defined(CPU_ARM1176) ||\ 1255 defined(CPU_FA526) || defined(CPU_FA626TE) 1256 1257#define IGN 0 1258#define OR 1 1259#define BIC 2 1260 1261struct cpu_option { 1262 char *co_name; 1263 int co_falseop; 1264 int co_trueop; 1265 int co_value; 1266}; 1267 1268static u_int parse_cpu_options(char *, struct cpu_option *, u_int); 1269 1270static u_int 1271parse_cpu_options(args, optlist, cpuctrl) 1272 char *args; 1273 struct cpu_option *optlist; 1274 u_int cpuctrl; 1275{ 1276 int integer; 1277 1278 if (args == NULL) 1279 return(cpuctrl); 1280 1281 while (optlist->co_name) { 1282 if (get_bootconf_option(args, optlist->co_name, 1283 BOOTOPT_TYPE_BOOLEAN, &integer)) { 1284 if (integer) { 1285 if (optlist->co_trueop == OR) 1286 cpuctrl |= optlist->co_value; 1287 else if (optlist->co_trueop == BIC) 1288 cpuctrl &= ~optlist->co_value; 1289 } else { 1290 if (optlist->co_falseop == OR) 1291 cpuctrl |= optlist->co_value; 1292 else if (optlist->co_falseop == BIC) 1293 cpuctrl &= ~optlist->co_value; 1294 } 1295 } 1296 ++optlist; 1297 } 1298 return(cpuctrl); 1299} 1300#endif /* CPU_ARM9 || XSCALE*/ 1301 1302#ifdef CPU_ARM9 1303struct cpu_option arm9_options[] = { 1304 { "cpu.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 1305 { "cpu.nocache", OR, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 1306 { "arm9.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 1307 { "arm9.icache", BIC, OR, CPU_CONTROL_IC_ENABLE }, 1308 { "arm9.dcache", BIC, OR, CPU_CONTROL_DC_ENABLE }, 1309 { "cpu.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 1310 { "cpu.nowritebuf", OR, BIC, CPU_CONTROL_WBUF_ENABLE }, 1311 { "arm9.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 1312 { NULL, IGN, IGN, 0 } 1313}; 1314 1315void 1316arm9_setup(args) 1317 char *args; 1318{ 1319 int cpuctrl, cpuctrlmask; 1320 1321 cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 1322 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 1323 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 1324 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE | 1325 CPU_CONTROL_ROUNDROBIN; 1326 cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 1327 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 1328 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 1329 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE 1330 | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE 1331 | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_VECRELOC 1332 | CPU_CONTROL_ROUNDROBIN; 1333 1334#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 1335 cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 1336#endif 1337 1338 cpuctrl = parse_cpu_options(args, arm9_options, cpuctrl); 1339 1340#ifdef __ARMEB__ 1341 cpuctrl |= CPU_CONTROL_BEND_ENABLE; 1342#endif 1343 if (vector_page == ARM_VECTORS_HIGH) 1344 cpuctrl |= CPU_CONTROL_VECRELOC; 1345 1346 /* Clear out the cache */ 1347 cpu_idcache_wbinv_all(); 1348 1349 /* Set the control register */ 1350 cpu_control(cpuctrlmask, cpuctrl); 1351 ctrl = cpuctrl; 1352 1353} 1354#endif /* CPU_ARM9 */ 1355 1356#if defined(CPU_ARM9E) || defined(CPU_ARM10) 1357struct cpu_option arm10_options[] = { 1358 { "cpu.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 1359 { "cpu.nocache", OR, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 1360 { "arm10.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 1361 { "arm10.icache", BIC, OR, CPU_CONTROL_IC_ENABLE }, 1362 { "arm10.dcache", BIC, OR, CPU_CONTROL_DC_ENABLE }, 1363 { "cpu.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 1364 { "cpu.nowritebuf", OR, BIC, CPU_CONTROL_WBUF_ENABLE }, 1365 { "arm10.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 1366 { NULL, IGN, IGN, 0 } 1367}; 1368 1369void 1370arm10_setup(args) 1371 char *args; 1372{ 1373 int cpuctrl, cpuctrlmask; 1374 1375 cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_SYST_ENABLE 1376 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 1377 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_BPRD_ENABLE; 1378 cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_SYST_ENABLE 1379 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 1380 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE 1381 | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE 1382 | CPU_CONTROL_BPRD_ENABLE 1383 | CPU_CONTROL_ROUNDROBIN | CPU_CONTROL_CPCLK; 1384 1385#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 1386 cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 1387#endif 1388 1389 cpuctrl = parse_cpu_options(args, arm10_options, cpuctrl); 1390 1391#ifdef __ARMEB__ 1392 cpuctrl |= CPU_CONTROL_BEND_ENABLE; 1393#endif 1394 1395 /* Clear out the cache */ 1396 cpu_idcache_wbinv_all(); 1397 1398 /* Now really make sure they are clean. */ 1399 __asm __volatile ("mcr\tp15, 0, r0, c7, c7, 0" : : ); 1400 1401 if (vector_page == ARM_VECTORS_HIGH) 1402 cpuctrl |= CPU_CONTROL_VECRELOC; 1403 1404 /* Set the control register */ 1405 ctrl = cpuctrl; 1406 cpu_control(0xffffffff, cpuctrl); 1407 1408 /* And again. */ 1409 cpu_idcache_wbinv_all(); 1410} 1411#endif /* CPU_ARM9E || CPU_ARM10 */ 1412 1413#if defined(CPU_ARM1136) || defined(CPU_ARM1176) \ 1414 || defined(CPU_MV_PJ4B) \ 1415 || defined(CPU_CORTEXA) || defined(CPU_KRAIT) 1416static __inline void 1417cpu_scc_setup_ccnt(void) 1418{ 1419/* This is how you give userland access to the CCNT and PMCn 1420 * registers. 1421 * BEWARE! This gives write access also, which may not be what 1422 * you want! 1423 */ 1424#ifdef _PMC_USER_READ_WRITE_ 1425#if defined(CPU_ARM1136) || defined(CPU_ARM1176) 1426 /* Use the Secure User and Non-secure Access Validation Control Register 1427 * to allow userland access 1428 */ 1429 __asm volatile ("mcr p15, 0, %0, c15, c9, 0\n\t" 1430 : 1431 : "r"(0x00000001)); 1432#else 1433 /* Set PMUSERENR[0] to allow userland access */ 1434 __asm volatile ("mcr p15, 0, %0, c9, c14, 0\n\t" 1435 : 1436 : "r"(0x00000001)); 1437#endif 1438#endif 1439#if defined(CPU_ARM1136) || defined(CPU_ARM1176) 1440 /* Set PMCR[2,0] to enable counters and reset CCNT */ 1441 __asm volatile ("mcr p15, 0, %0, c15, c12, 0\n\t" 1442 : 1443 : "r"(0x00000005)); 1444#else 1445 /* Set up the PMCCNTR register as a cyclecounter: 1446 * Set PMINTENCLR to 0xFFFFFFFF to block interrupts 1447 * Set PMCR[2,0] to enable counters and reset CCNT 1448 * Set PMCNTENSET to 0x80000000 to enable CCNT */ 1449 __asm volatile ("mcr p15, 0, %0, c9, c14, 2\n\t" 1450 "mcr p15, 0, %1, c9, c12, 0\n\t" 1451 "mcr p15, 0, %2, c9, c12, 1\n\t" 1452 : 1453 : "r"(0xFFFFFFFF), 1454 "r"(0x00000005), 1455 "r"(0x80000000)); 1456#endif 1457} 1458#endif 1459 1460#if defined(CPU_ARM1136) || defined(CPU_ARM1176) 1461struct cpu_option arm11_options[] = { 1462 { "cpu.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 1463 { "cpu.nocache", OR, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 1464 { "arm11.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 1465 { "arm11.icache", BIC, OR, CPU_CONTROL_IC_ENABLE }, 1466 { "arm11.dcache", BIC, OR, CPU_CONTROL_DC_ENABLE }, 1467 { NULL, IGN, IGN, 0 } 1468}; 1469 1470void 1471arm11x6_setup(char *args) 1472{ 1473 int cpuctrl, cpuctrl_wax; 1474 uint32_t auxctrl, auxctrl_wax; 1475 uint32_t tmp, tmp2; 1476 uint32_t sbz=0; 1477 uint32_t cpuid; 1478 1479 cpuid = cpufunc_id(); 1480 1481 cpuctrl = 1482 CPU_CONTROL_MMU_ENABLE | 1483 CPU_CONTROL_DC_ENABLE | 1484 CPU_CONTROL_WBUF_ENABLE | 1485 CPU_CONTROL_32BP_ENABLE | 1486 CPU_CONTROL_32BD_ENABLE | 1487 CPU_CONTROL_LABT_ENABLE | 1488 CPU_CONTROL_SYST_ENABLE | 1489 CPU_CONTROL_IC_ENABLE; 1490 1491 /* 1492 * "write as existing" bits 1493 * inverse of this is mask 1494 */ 1495 cpuctrl_wax = 1496 (3 << 30) | /* SBZ */ 1497 (1 << 29) | /* FA */ 1498 (1 << 28) | /* TR */ 1499 (3 << 26) | /* SBZ */ 1500 (3 << 19) | /* SBZ */ 1501 (1 << 17); /* SBZ */ 1502 1503 cpuctrl |= CPU_CONTROL_BPRD_ENABLE; 1504 cpuctrl |= CPU_CONTROL_V6_EXTPAGE; 1505 1506 cpuctrl = parse_cpu_options(args, arm11_options, cpuctrl); 1507 1508#ifdef __ARMEB__ 1509 cpuctrl |= CPU_CONTROL_BEND_ENABLE; 1510#endif 1511 1512 if (vector_page == ARM_VECTORS_HIGH) 1513 cpuctrl |= CPU_CONTROL_VECRELOC; 1514 1515 auxctrl = 0; 1516 auxctrl_wax = ~0; 1517 /* 1518 * This options enables the workaround for the 364296 ARM1136 1519 * r0pX errata (possible cache data corruption with 1520 * hit-under-miss enabled). It sets the undocumented bit 31 in 1521 * the auxiliary control register and the FI bit in the control 1522 * register, thus disabling hit-under-miss without putting the 1523 * processor into full low interrupt latency mode. ARM11MPCore 1524 * is not affected. 1525 */ 1526 if ((cpuid & CPU_ID_CPU_MASK) == CPU_ID_ARM1136JS) { /* ARM1136JSr0pX */ 1527 cpuctrl |= CPU_CONTROL_FI_ENABLE; 1528 auxctrl = ARM1136_AUXCTL_PFI; 1529 auxctrl_wax = ~ARM1136_AUXCTL_PFI; 1530 } 1531 1532 /* 1533 * Enable an errata workaround 1534 */ 1535 if ((cpuid & CPU_ID_CPU_MASK) == CPU_ID_ARM1176JZS) { /* ARM1176JZSr0 */ 1536 auxctrl = ARM1176_AUXCTL_PHD; 1537 auxctrl_wax = ~ARM1176_AUXCTL_PHD; 1538 } 1539 1540 /* Clear out the cache */ 1541 cpu_idcache_wbinv_all(); 1542 1543 /* Now really make sure they are clean. */ 1544 __asm volatile ("mcr\tp15, 0, %0, c7, c7, 0" : : "r"(sbz)); 1545 1546 /* Allow detection code to find the VFP if it's fitted. */ 1547 __asm volatile ("mcr\tp15, 0, %0, c1, c0, 2" : : "r" (0x0fffffff)); 1548 1549 /* Set the control register */ 1550 ctrl = cpuctrl; 1551 cpu_control(~cpuctrl_wax, cpuctrl); 1552 1553 __asm volatile ("mrc p15, 0, %0, c1, c0, 1\n\t" 1554 "and %1, %0, %2\n\t" 1555 "orr %1, %1, %3\n\t" 1556 "teq %0, %1\n\t" 1557 "mcrne p15, 0, %1, c1, c0, 1\n\t" 1558 : "=r"(tmp), "=r"(tmp2) : 1559 "r"(auxctrl_wax), "r"(auxctrl)); 1560 1561 /* And again. */ 1562 cpu_idcache_wbinv_all(); 1563 1564 cpu_scc_setup_ccnt(); 1565} 1566#endif /* CPU_ARM1136 || CPU_ARM1176 */ 1567 1568#ifdef CPU_MV_PJ4B 1569void 1570pj4bv7_setup(args) 1571 char *args; 1572{ 1573 int cpuctrl; 1574 1575 pj4b_config(); 1576 1577 cpuctrl = CPU_CONTROL_MMU_ENABLE; 1578#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 1579 cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 1580#endif 1581 cpuctrl |= CPU_CONTROL_DC_ENABLE; 1582 cpuctrl |= (0xf << 3); 1583 cpuctrl |= CPU_CONTROL_BPRD_ENABLE; 1584 cpuctrl |= CPU_CONTROL_IC_ENABLE; 1585 if (vector_page == ARM_VECTORS_HIGH) 1586 cpuctrl |= CPU_CONTROL_VECRELOC; 1587 cpuctrl |= (0x5 << 16) | (1 < 22); 1588 cpuctrl |= CPU_CONTROL_V6_EXTPAGE; 1589 1590 /* Clear out the cache */ 1591 cpu_idcache_wbinv_all(); 1592 1593 /* Set the control register */ 1594 ctrl = cpuctrl; 1595 cpu_control(0xFFFFFFFF, cpuctrl); 1596 1597 /* And again. */ 1598 cpu_idcache_wbinv_all(); 1599 1600 cpu_scc_setup_ccnt(); 1601} 1602#endif /* CPU_MV_PJ4B */ 1603 1604#if defined(CPU_CORTEXA) || defined(CPU_KRAIT) 1605 1606void 1607cortexa_setup(char *args) 1608{ 1609 int cpuctrl, cpuctrlmask; 1610 1611 cpuctrlmask = CPU_CONTROL_MMU_ENABLE | /* MMU enable [0] */ 1612 CPU_CONTROL_AFLT_ENABLE | /* Alignment fault [1] */ 1613 CPU_CONTROL_DC_ENABLE | /* DCache enable [2] */ 1614 CPU_CONTROL_BPRD_ENABLE | /* Branch prediction [11] */ 1615 CPU_CONTROL_IC_ENABLE | /* ICache enable [12] */ 1616 CPU_CONTROL_VECRELOC; /* Vector relocation [13] */ 1617 1618 cpuctrl = CPU_CONTROL_MMU_ENABLE | 1619 CPU_CONTROL_IC_ENABLE | 1620 CPU_CONTROL_DC_ENABLE | 1621 CPU_CONTROL_BPRD_ENABLE; 1622 1623#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 1624 cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 1625#endif 1626 1627 /* Switch to big endian */ 1628#ifdef __ARMEB__ 1629 cpuctrl |= CPU_CONTROL_BEND_ENABLE; 1630#endif 1631 1632 /* Check if the vector page is at the high address (0xffff0000) */ 1633 if (vector_page == ARM_VECTORS_HIGH) 1634 cpuctrl |= CPU_CONTROL_VECRELOC; 1635 1636 /* Clear out the cache */ 1637 cpu_idcache_wbinv_all(); 1638 1639 /* Set the control register */ 1640 ctrl = cpuctrl; 1641 cpu_control(cpuctrlmask, cpuctrl); 1642 1643 /* And again. */ 1644 cpu_idcache_wbinv_all(); 1645#ifdef SMP 1646 armv7_auxctrl((1 << 6) | (1 << 0), (1 << 6) | (1 << 0)); /* Enable SMP + TLB broadcasting */ 1647#endif 1648 1649 cpu_scc_setup_ccnt(); 1650} 1651#endif /* CPU_CORTEXA */ 1652 1653#if defined(CPU_FA526) || defined(CPU_FA626TE) 1654struct cpu_option fa526_options[] = { 1655#ifdef COMPAT_12 1656 { "nocache", IGN, BIC, (CPU_CONTROL_IC_ENABLE | 1657 CPU_CONTROL_DC_ENABLE) }, 1658 { "nowritebuf", IGN, BIC, CPU_CONTROL_WBUF_ENABLE }, 1659#endif /* COMPAT_12 */ 1660 { "cpu.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | 1661 CPU_CONTROL_DC_ENABLE) }, 1662 { "cpu.nocache", OR, BIC, (CPU_CONTROL_IC_ENABLE | 1663 CPU_CONTROL_DC_ENABLE) }, 1664 { "cpu.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 1665 { "cpu.nowritebuf", OR, BIC, CPU_CONTROL_WBUF_ENABLE }, 1666 { NULL, IGN, IGN, 0 } 1667}; 1668 1669void 1670fa526_setup(char *args) 1671{ 1672 int cpuctrl, cpuctrlmask; 1673 1674 cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 1675 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 1676 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 1677 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE 1678 | CPU_CONTROL_BPRD_ENABLE; 1679 cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 1680 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 1681 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 1682 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE 1683 | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE 1684 | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_BPRD_ENABLE 1685 | CPU_CONTROL_CPCLK | CPU_CONTROL_VECRELOC; 1686 1687#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 1688 cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 1689#endif 1690 1691 cpuctrl = parse_cpu_options(args, fa526_options, cpuctrl); 1692 1693#ifdef __ARMEB__ 1694 cpuctrl |= CPU_CONTROL_BEND_ENABLE; 1695#endif 1696 1697 if (vector_page == ARM_VECTORS_HIGH) 1698 cpuctrl |= CPU_CONTROL_VECRELOC; 1699 1700 /* Clear out the cache */ 1701 cpu_idcache_wbinv_all(); 1702 1703 /* Set the control register */ 1704 ctrl = cpuctrl; 1705 cpu_control(0xffffffff, cpuctrl); 1706} 1707#endif /* CPU_FA526 || CPU_FA626TE */ 1708 1709#if defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \ 1710 defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \ 1711 defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342) 1712struct cpu_option xscale_options[] = { 1713#ifdef COMPAT_12 1714 { "branchpredict", BIC, OR, CPU_CONTROL_BPRD_ENABLE }, 1715 { "nocache", IGN, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 1716#endif /* COMPAT_12 */ 1717 { "cpu.branchpredict", BIC, OR, CPU_CONTROL_BPRD_ENABLE }, 1718 { "cpu.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 1719 { "cpu.nocache", OR, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 1720 { "xscale.branchpredict", BIC, OR, CPU_CONTROL_BPRD_ENABLE }, 1721 { "xscale.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 1722 { "xscale.icache", BIC, OR, CPU_CONTROL_IC_ENABLE }, 1723 { "xscale.dcache", BIC, OR, CPU_CONTROL_DC_ENABLE }, 1724 { NULL, IGN, IGN, 0 } 1725}; 1726 1727void 1728xscale_setup(args) 1729 char *args; 1730{ 1731 uint32_t auxctl; 1732 int cpuctrl, cpuctrlmask; 1733 1734 /* 1735 * The XScale Write Buffer is always enabled. Our option 1736 * is to enable/disable coalescing. Note that bits 6:3 1737 * must always be enabled. 1738 */ 1739 1740 cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 1741 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 1742 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 1743 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE 1744 | CPU_CONTROL_BPRD_ENABLE; 1745 cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 1746 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 1747 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 1748 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE 1749 | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE 1750 | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_BPRD_ENABLE 1751 | CPU_CONTROL_CPCLK | CPU_CONTROL_VECRELOC | \ 1752 CPU_CONTROL_L2_ENABLE; 1753 1754#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 1755 cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 1756#endif 1757 1758 cpuctrl = parse_cpu_options(args, xscale_options, cpuctrl); 1759 1760#ifdef __ARMEB__ 1761 cpuctrl |= CPU_CONTROL_BEND_ENABLE; 1762#endif 1763 1764 if (vector_page == ARM_VECTORS_HIGH) 1765 cpuctrl |= CPU_CONTROL_VECRELOC; 1766#ifdef CPU_XSCALE_CORE3 1767 cpuctrl |= CPU_CONTROL_L2_ENABLE; 1768#endif 1769 1770 /* Clear out the cache */ 1771 cpu_idcache_wbinv_all(); 1772 1773 /* 1774 * Set the control register. Note that bits 6:3 must always 1775 * be set to 1. 1776 */ 1777 ctrl = cpuctrl; 1778/* cpu_control(cpuctrlmask, cpuctrl);*/ 1779 cpu_control(0xffffffff, cpuctrl); 1780 1781 /* Make sure write coalescing is turned on */ 1782 __asm __volatile("mrc p15, 0, %0, c1, c0, 1" 1783 : "=r" (auxctl)); 1784#ifdef XSCALE_NO_COALESCE_WRITES 1785 auxctl |= XSCALE_AUXCTL_K; 1786#else 1787 auxctl &= ~XSCALE_AUXCTL_K; 1788#endif 1789#ifdef CPU_XSCALE_CORE3 1790 auxctl |= XSCALE_AUXCTL_LLR; 1791 auxctl |= XSCALE_AUXCTL_MD_MASK; 1792#endif 1793 __asm __volatile("mcr p15, 0, %0, c1, c0, 1" 1794 : : "r" (auxctl)); 1795} 1796#endif /* CPU_XSCALE_80200 || CPU_XSCALE_80321 || CPU_XSCALE_PXA2X0 || CPU_XSCALE_IXP425 1797 CPU_XSCALE_80219 */ 1798