Home | History | Annotate | Line # | Download | only in arm
      1 /*	$NetBSD: cpufunc.c,v 1.185 2022/12/22 06:58:07 ryo 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  * arm11 support code Copyright (c) 2007 Microsoft
      9  * cortexa8 support code Copyright (c) 2008 3am Software Foundry
     10  * cortexa8 improvements Copyright (c) Goeran Weinholt
     11  * Copyright (c) 1997 Mark Brinicombe.
     12  * Copyright (c) 1997 Causality Limited
     13  * All rights reserved.
     14  *
     15  * Redistribution and use in source and binary forms, with or without
     16  * modification, are permitted provided that the following conditions
     17  * are met:
     18  * 1. Redistributions of source code must retain the above copyright
     19  *    notice, this list of conditions and the following disclaimer.
     20  * 2. Redistributions in binary form must reproduce the above copyright
     21  *    notice, this list of conditions and the following disclaimer in the
     22  *    documentation and/or other materials provided with the distribution.
     23  * 3. All advertising materials mentioning features or use of this software
     24  *    must display the following acknowledgement:
     25  *	This product includes software developed by Causality Limited.
     26  * 4. The name of Causality Limited may not be used to endorse or promote
     27  *    products derived from this software without specific prior written
     28  *    permission.
     29  *
     30  * THIS SOFTWARE IS PROVIDED BY CAUSALITY LIMITED ``AS IS'' AND ANY EXPRESS
     31  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     32  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     33  * DISCLAIMED. IN NO EVENT SHALL CAUSALITY LIMITED BE LIABLE FOR ANY DIRECT,
     34  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     35  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     36  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     37  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     38  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     39  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     40  * SUCH DAMAGE.
     41  *
     42  * RiscBSD kernel project
     43  *
     44  * cpufuncs.c
     45  *
     46  * C functions for supporting CPU / MMU / TLB specific operations.
     47  *
     48  * Created	: 30/01/97
     49  */
     50 
     51 #include <sys/cdefs.h>
     52 __KERNEL_RCSID(0, "$NetBSD: cpufunc.c,v 1.185 2022/12/22 06:58:07 ryo Exp $");
     53 
     54 #include "opt_arm_start.h"
     55 #include "opt_compat_netbsd.h"
     56 #include "opt_cpuoptions.h"
     57 #include "opt_cputypes.h"
     58 #include "opt_multiprocessor.h"
     59 
     60 #include <sys/types.h>
     61 #include <sys/param.h>
     62 #include <sys/systm.h>
     63 #include <machine/cpu.h>
     64 #include <machine/bootconfig.h>
     65 #include <arch/arm/arm/disassem.h>
     66 
     67 #include <uvm/uvm.h>
     68 
     69 #include <arm/cpufunc_proto.h>
     70 #include <arm/cpuconf.h>
     71 #include <arm/locore.h>
     72 
     73 #ifdef CPU_XSCALE_80200
     74 #include <arm/xscale/i80200reg.h>
     75 #include <arm/xscale/i80200var.h>
     76 #endif
     77 
     78 #ifdef CPU_XSCALE_80321
     79 #include <arm/xscale/i80321reg.h>
     80 #include <arm/xscale/i80321var.h>
     81 #endif
     82 
     83 #ifdef CPU_XSCALE_IXP425
     84 #include <arm/xscale/ixp425reg.h>
     85 #include <arm/xscale/ixp425var.h>
     86 #endif
     87 
     88 #if defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321)
     89 #include <arm/xscale/xscalereg.h>
     90 #endif
     91 
     92 #if defined(CPU_PJ4B)
     93 #include "opt_mvsoc.h"
     94 #include <machine/bus_defs.h>
     95 #if defined(ARMADAXP)
     96 #include <arm/marvell/armadaxpreg.h>
     97 #include <arm/marvell/armadaxpvar.h>
     98 #endif
     99 #endif
    100 
    101 #if defined(CPU_ARMV7) && (defined(CPU_ARMV6) || defined(CPU_PRE_ARMV6))
    102 bool cpu_armv7_p;
    103 #endif
    104 
    105 #if defined(CPU_ARMV6) && (defined(CPU_ARMV7) || defined(CPU_PRE_ARMV6))
    106 bool cpu_armv6_p;
    107 #endif
    108 
    109 
    110 /* PRIMARY CACHE VARIABLES */
    111 #if (ARM_MMU_V6 + ARM_MMU_V7) != 0
    112 u_int	arm_cache_prefer_mask;
    113 #endif
    114 struct	arm_cache_info arm_pcache;
    115 struct	arm_cache_info arm_scache;
    116 
    117 u_int	arm_dcache_align;
    118 u_int	arm_dcache_align_mask;
    119 
    120 // Define a TTB value that can never be used.
    121 uint32_t cpu_ttb = ~0;
    122 
    123 /* 1 == use cpu_sleep(), 0 == don't */
    124 int cpu_do_powersave;
    125 
    126 #ifdef CPU_ARM6
    127 struct cpu_functions arm6_cpufuncs = {
    128 	/* CPU functions */
    129 
    130 	.cf_id			= cpufunc_id,
    131 	.cf_cpwait		= cpufunc_nullop,
    132 
    133 	/* MMU functions */
    134 
    135 	.cf_control		= cpufunc_control,
    136 	.cf_domains		= cpufunc_domains,
    137 	.cf_setttb		= arm67_setttb,
    138 	.cf_faultstatus		= cpufunc_faultstatus,
    139 	.cf_faultaddress	= cpufunc_faultaddress,
    140 
    141 	/* TLB functions */
    142 
    143 	.cf_tlb_flushID		= arm67_tlb_flush,
    144 	.cf_tlb_flushID_SE	= arm67_tlb_purge,
    145 	.cf_tlb_flushI		= arm67_tlb_flush,
    146 	.cf_tlb_flushI_SE	= arm67_tlb_purge,
    147 	.cf_tlb_flushD		= arm67_tlb_flush,
    148 	.cf_tlb_flushD_SE	= arm67_tlb_purge,
    149 
    150 	/* Cache operations */
    151 
    152 	.cf_icache_sync_all	= cpufunc_nullop,
    153 	.cf_icache_sync_range	= (void *) cpufunc_nullop,
    154 
    155 	.cf_dcache_wbinv_all	= arm67_cache_flush,
    156 	.cf_dcache_wbinv_range	= (void *)arm67_cache_flush,
    157 	.cf_dcache_inv_range	= (void *)arm67_cache_flush,
    158 	.cf_dcache_wb_range	= (void *)cpufunc_nullop,
    159 
    160 	.cf_sdcache_wbinv_range	= (void *)cpufunc_nullop,
    161 	.cf_sdcache_inv_range	= (void *)cpufunc_nullop,
    162 	.cf_sdcache_wb_range	= (void *)cpufunc_nullop,
    163 
    164 	.cf_idcache_wbinv_all	= arm67_cache_flush,
    165 	.cf_idcache_wbinv_range	= (void *)arm67_cache_flush,
    166 
    167 	/* Other functions */
    168 
    169 	.cf_flush_prefetchbuf	= cpufunc_nullop,
    170 	.cf_drain_writebuf	= cpufunc_nullop,
    171 	.cf_flush_brnchtgt_C	= cpufunc_nullop,
    172 	.cf_flush_brnchtgt_E	= (void *)cpufunc_nullop,
    173 
    174 	.cf_sleep		= (void *)cpufunc_nullop,
    175 
    176 	/* Soft functions */
    177 
    178 #ifdef ARM6_LATE_ABORT
    179 	.cf_dataabt_fixup	= late_abort_fixup,
    180 #else
    181 	.cf_dataabt_fixup	= early_abort_fixup,
    182 #endif
    183 	.cf_prefetchabt_fixup	= cpufunc_null_fixup,
    184 
    185 	.cf_context_switch	= arm67_context_switch,
    186 
    187 	.cf_setup		= arm6_setup
    188 
    189 };
    190 #endif	/* CPU_ARM6 */
    191 
    192 #ifdef CPU_ARM7
    193 struct cpu_functions arm7_cpufuncs = {
    194 	/* CPU functions */
    195 
    196 	.cf_id			= cpufunc_id,
    197 	.cf_cpwait		= cpufunc_nullop,
    198 
    199 	/* MMU functions */
    200 
    201 	.cf_control		= cpufunc_control,
    202 	.cf_domains		= cpufunc_domains,
    203 	.cf_setttb		= arm67_setttb,
    204 	.cf_faultstatus		= cpufunc_faultstatus,
    205 	.cf_faultaddress	= cpufunc_faultaddress,
    206 
    207 	/* TLB functions */
    208 
    209 	.cf_tlb_flushID		= arm67_tlb_flush,
    210 	.cf_tlb_flushID_SE	= arm67_tlb_purge,
    211 	.cf_tlb_flushI		= arm67_tlb_flush,
    212 	.cf_tlb_flushI_SE	= arm67_tlb_purge,
    213 	.cf_tlb_flushD		= arm67_tlb_flush,
    214 	.cf_tlb_flushD_SE	= arm67_tlb_purge,
    215 
    216 	/* Cache operations */
    217 
    218 	.cf_icache_sync_all	= cpufunc_nullop,
    219 	.cf_icache_sync_range	= (void *)cpufunc_nullop,
    220 
    221 	.cf_dcache_wbinv_all	= arm67_cache_flush,
    222 	.cf_dcache_wbinv_range	= (void *)arm67_cache_flush,
    223 	.cf_dcache_inv_range	= (void *)arm67_cache_flush,
    224 	.cf_dcache_wb_range	= (void *)cpufunc_nullop,
    225 
    226 	.cf_sdcache_wbinv_range	= (void *)cpufunc_nullop,
    227 	.cf_sdcache_inv_range	= (void *)cpufunc_nullop,
    228 	.cf_sdcache_wb_range	= (void *)cpufunc_nullop,
    229 
    230 	.cf_idcache_wbinv_all	= arm67_cache_flush,
    231 	.cf_idcache_wbinv_range	= (void *)arm67_cache_flush,
    232 
    233 	/* Other functions */
    234 
    235 	.cf_flush_prefetchbuf	= cpufunc_nullop,
    236 	.cf_drain_writebuf	= cpufunc_nullop,
    237 	.cf_flush_brnchtgt_C	= cpufunc_nullop,
    238 	.cf_flush_brnchtgt_E	= (void *)cpufunc_nullop,
    239 
    240 	.cf_sleep		= (void *)cpufunc_nullop,
    241 
    242 	/* Soft functions */
    243 
    244 	.cf_dataabt_fixup	= late_abort_fixup,
    245 	.cf_prefetchabt_fixup	= cpufunc_null_fixup,
    246 
    247 	.cf_context_switch	= arm67_context_switch,
    248 
    249 	.cf_setup		= arm7_setup
    250 
    251 };
    252 #endif	/* CPU_ARM7 */
    253 
    254 #ifdef CPU_ARM7TDMI
    255 struct cpu_functions arm7tdmi_cpufuncs = {
    256 	/* CPU functions */
    257 
    258 	.cf_id			= cpufunc_id,
    259 	.cf_cpwait		= cpufunc_nullop,
    260 
    261 	/* MMU functions */
    262 
    263 	.cf_control		= cpufunc_control,
    264 	.cf_domains		= cpufunc_domains,
    265 	.cf_setttb		= arm7tdmi_setttb,
    266 	.cf_faultstatus		= cpufunc_faultstatus,
    267 	.cf_faultaddress	= cpufunc_faultaddress,
    268 
    269 	/* TLB functions */
    270 
    271 	.cf_tlb_flushID		= arm7tdmi_tlb_flushID,
    272 	.cf_tlb_flushID_SE	= arm7tdmi_tlb_flushID_SE,
    273 	.cf_tlb_flushI		= arm7tdmi_tlb_flushID,
    274 	.cf_tlb_flushI_SE	= arm7tdmi_tlb_flushID_SE,
    275 	.cf_tlb_flushD		= arm7tdmi_tlb_flushID,
    276 	.cf_tlb_flushD_SE	= arm7tdmi_tlb_flushID_SE,
    277 
    278 	/* Cache operations */
    279 
    280 	.cf_icache_sync_all	= cpufunc_nullop,
    281 	.cf_icache_sync_range	= (void *)cpufunc_nullop,
    282 
    283 	.cf_dcache_wbinv_all	= arm7tdmi_cache_flushID,
    284 	.cf_dcache_wbinv_range	= (void *)arm7tdmi_cache_flushID,
    285 	.cf_dcache_inv_range	= (void *)arm7tdmi_cache_flushID,
    286 	.cf_dcache_wb_range	= (void *)cpufunc_nullop,
    287 
    288 	.cf_sdcache_wbinv_range	= (void *)cpufunc_nullop,
    289 	.cf_sdcache_inv_range	= (void *)cpufunc_nullop,
    290 	.cf_sdcache_wb_range	= (void *)cpufunc_nullop,
    291 
    292 	.cf_idcache_wbinv_all	= arm7tdmi_cache_flushID,
    293 	.cf_idcache_wbinv_range	= (void *)arm7tdmi_cache_flushID,
    294 
    295 	/* Other functions */
    296 
    297 	.cf_flush_prefetchbuf	= cpufunc_nullop,
    298 	.cf_drain_writebuf	= cpufunc_nullop,
    299 	.cf_flush_brnchtgt_C	= cpufunc_nullop,
    300 	.cf_flush_brnchtgt_E	= (void *)cpufunc_nullop,
    301 
    302 	.cf_sleep		= (void *)cpufunc_nullop,
    303 
    304 	/* Soft functions */
    305 
    306 	.cf_dataabt_fixup	= late_abort_fixup,
    307 	.cf_prefetchabt_fixup	= cpufunc_null_fixup,
    308 
    309 	.cf_context_switch	= arm7tdmi_context_switch,
    310 
    311 	.cf_setup		= arm7tdmi_setup
    312 
    313 };
    314 #endif	/* CPU_ARM7TDMI */
    315 
    316 #ifdef CPU_ARM8
    317 struct cpu_functions arm8_cpufuncs = {
    318 	/* CPU functions */
    319 
    320 	.cf_id			= cpufunc_id,
    321 	.cf_cpwait		= cpufunc_nullop,
    322 
    323 	/* MMU functions */
    324 
    325 	.cf_control		= cpufunc_control,
    326 	.cf_domains		= cpufunc_domains,
    327 	.cf_setttb		= arm8_setttb,
    328 	.cf_faultstatus		= cpufunc_faultstatus,
    329 	.cf_faultaddress	= cpufunc_faultaddress,
    330 
    331 	/* TLB functions */
    332 
    333 	.cf_tlb_flushID		= arm8_tlb_flushID,
    334 	.cf_tlb_flushID_SE	= arm8_tlb_flushID_SE,
    335 	.cf_tlb_flushI		= arm8_tlb_flushID,
    336 	.cf_tlb_flushI_SE	= arm8_tlb_flushID_SE,
    337 	.cf_tlb_flushD		= arm8_tlb_flushID,
    338 	.cf_tlb_flushD_SE	= arm8_tlb_flushID_SE,
    339 
    340 	/* Cache operations */
    341 
    342 	.cf_icache_sync_all	= cpufunc_nullop,
    343 	.cf_icache_sync_range	= (void *)cpufunc_nullop,
    344 
    345 	.cf_dcache_wbinv_all	= arm8_cache_purgeID,
    346 	.cf_dcache_wbinv_range	= (void *)arm8_cache_purgeID,
    347 /*XXX*/	.cf_dcache_inv_range	= (void *)arm8_cache_purgeID,
    348 	.cf_dcache_wb_range	= (void *)arm8_cache_cleanID,
    349 
    350 	.cf_sdcache_wbinv_range	= (void *)cpufunc_nullop,
    351 	.cf_sdcache_inv_range	= (void *)cpufunc_nullop,
    352 	.cf_sdcache_wb_range	= (void *)cpufunc_nullop,
    353 
    354 	.cf_idcache_wbinv_all	= arm8_cache_purgeID,
    355 	.cf_idcache_wbinv_range = (void *)arm8_cache_purgeID,
    356 
    357 	/* Other functions */
    358 
    359 	.cf_flush_prefetchbuf	= cpufunc_nullop,
    360 	.cf_drain_writebuf	= cpufunc_nullop,
    361 	.cf_flush_brnchtgt_C	= cpufunc_nullop,
    362 	.cf_flush_brnchtgt_E	= (void *)cpufunc_nullop,
    363 
    364 	.cf_sleep		= (void *)cpufunc_nullop,
    365 
    366 	/* Soft functions */
    367 
    368 	.cf_dataabt_fixup	= cpufunc_null_fixup,
    369 	.cf_prefetchabt_fixup	= cpufunc_null_fixup,
    370 
    371 	.cf_context_switch	= arm8_context_switch,
    372 
    373 	.cf_setup		= arm8_setup
    374 };
    375 #endif	/* CPU_ARM8 */
    376 
    377 #ifdef CPU_ARM9
    378 struct cpu_functions arm9_cpufuncs = {
    379 	/* CPU functions */
    380 
    381 	.cf_id			= cpufunc_id,
    382 	.cf_cpwait		= cpufunc_nullop,
    383 
    384 	/* MMU functions */
    385 
    386 	.cf_control		= cpufunc_control,
    387 	.cf_domains		= cpufunc_domains,
    388 	.cf_setttb		= arm9_setttb,
    389 	.cf_faultstatus		= cpufunc_faultstatus,
    390 	.cf_faultaddress	= cpufunc_faultaddress,
    391 
    392 	/* TLB functions */
    393 
    394 	.cf_tlb_flushID		= armv4_tlb_flushID,
    395 	.cf_tlb_flushID_SE	= arm9_tlb_flushID_SE,
    396 	.cf_tlb_flushI		= armv4_tlb_flushI,
    397 	.cf_tlb_flushI_SE	= (void *)armv4_tlb_flushI,
    398 	.cf_tlb_flushD		= armv4_tlb_flushD,
    399 	.cf_tlb_flushD_SE	= armv4_tlb_flushD_SE,
    400 
    401 	/* Cache operations */
    402 
    403 	.cf_icache_sync_all	= arm9_icache_sync_all,
    404 	.cf_icache_sync_range	= arm9_icache_sync_range,
    405 
    406 	.cf_dcache_wbinv_all	= arm9_dcache_wbinv_all,
    407 	.cf_dcache_wbinv_range	= arm9_dcache_wbinv_range,
    408 /*XXX*/	.cf_dcache_inv_range	= arm9_dcache_wbinv_range,
    409 	.cf_dcache_wb_range	= arm9_dcache_wb_range,
    410 
    411 	.cf_sdcache_wbinv_range	= (void *)cpufunc_nullop,
    412 	.cf_sdcache_inv_range	= (void *)cpufunc_nullop,
    413 	.cf_sdcache_wb_range	= (void *)cpufunc_nullop,
    414 
    415 	.cf_idcache_wbinv_all	= arm9_idcache_wbinv_all,
    416 	.cf_idcache_wbinv_range = arm9_idcache_wbinv_range,
    417 
    418 	/* Other functions */
    419 
    420 	.cf_flush_prefetchbuf	= cpufunc_nullop,
    421 	.cf_drain_writebuf	= armv4_drain_writebuf,
    422 	.cf_flush_brnchtgt_C	= cpufunc_nullop,
    423 	.cf_flush_brnchtgt_E	= (void *)cpufunc_nullop,
    424 
    425 	.cf_sleep		= (void *)cpufunc_nullop,
    426 
    427 	/* Soft functions */
    428 
    429 	.cf_dataabt_fixup	= cpufunc_null_fixup,
    430 	.cf_prefetchabt_fixup	= cpufunc_null_fixup,
    431 
    432 	.cf_context_switch	= arm9_context_switch,
    433 
    434 	.cf_setup		= arm9_setup
    435 
    436 };
    437 #endif /* CPU_ARM9 */
    438 
    439 #if defined(CPU_ARM9E) || defined(CPU_ARM10)
    440 struct cpu_functions armv5_ec_cpufuncs = {
    441 	/* CPU functions */
    442 
    443 	.cf_id			= cpufunc_id,
    444 	.cf_cpwait		= cpufunc_nullop,
    445 
    446 	/* MMU functions */
    447 
    448 	.cf_control		= cpufunc_control,
    449 	.cf_domains		= cpufunc_domains,
    450 	.cf_setttb		= armv5_ec_setttb,
    451 	.cf_faultstatus		= cpufunc_faultstatus,
    452 	.cf_faultaddress	= cpufunc_faultaddress,
    453 
    454 	/* TLB functions */
    455 
    456 	.cf_tlb_flushID		= armv4_tlb_flushID,
    457 	.cf_tlb_flushID_SE	= arm10_tlb_flushID_SE,
    458 	.cf_tlb_flushI		= armv4_tlb_flushI,
    459 	.cf_tlb_flushI_SE	= arm10_tlb_flushI_SE,
    460 	.cf_tlb_flushD		= armv4_tlb_flushD,
    461 	.cf_tlb_flushD_SE	= armv4_tlb_flushD_SE,
    462 
    463 	/* Cache operations */
    464 
    465 	.cf_icache_sync_all	= armv5_ec_icache_sync_all,
    466 	.cf_icache_sync_range	= armv5_ec_icache_sync_range,
    467 
    468 	.cf_dcache_wbinv_all	= armv5_ec_dcache_wbinv_all,
    469 	.cf_dcache_wbinv_range	= armv5_ec_dcache_wbinv_range,
    470 /*XXX*/	.cf_dcache_inv_range	= armv5_ec_dcache_wbinv_range,
    471 	.cf_dcache_wb_range	= armv5_ec_dcache_wb_range,
    472 
    473 	.cf_sdcache_wbinv_range	= (void *)cpufunc_nullop,
    474 	.cf_sdcache_inv_range	= (void *)cpufunc_nullop,
    475 	.cf_sdcache_wb_range	= (void *)cpufunc_nullop,
    476 
    477 	.cf_idcache_wbinv_all	= armv5_ec_idcache_wbinv_all,
    478 	.cf_idcache_wbinv_range = armv5_ec_idcache_wbinv_range,
    479 
    480 	/* Other functions */
    481 
    482 	.cf_flush_prefetchbuf	= cpufunc_nullop,
    483 	.cf_drain_writebuf	= armv4_drain_writebuf,
    484 	.cf_flush_brnchtgt_C	= cpufunc_nullop,
    485 	.cf_flush_brnchtgt_E	= (void *)cpufunc_nullop,
    486 
    487 	.cf_sleep		= (void *)cpufunc_nullop,
    488 
    489 	/* Soft functions */
    490 
    491 	.cf_dataabt_fixup	= cpufunc_null_fixup,
    492 	.cf_prefetchabt_fixup	= cpufunc_null_fixup,
    493 
    494 	.cf_context_switch	= arm10_context_switch,
    495 
    496 	.cf_setup		= arm10_setup
    497 
    498 };
    499 #endif /* CPU_ARM9E || CPU_ARM10 */
    500 
    501 #ifdef CPU_ARM10
    502 struct cpu_functions arm10_cpufuncs = {
    503 	/* CPU functions */
    504 
    505 	.cf_id			= cpufunc_id,
    506 	.cf_cpwait		= cpufunc_nullop,
    507 
    508 	/* MMU functions */
    509 
    510 	.cf_control		= cpufunc_control,
    511 	.cf_domains		= cpufunc_domains,
    512 	.cf_setttb		= armv5_setttb,
    513 	.cf_faultstatus		= cpufunc_faultstatus,
    514 	.cf_faultaddress	= cpufunc_faultaddress,
    515 
    516 	/* TLB functions */
    517 
    518 	.cf_tlb_flushID		= armv4_tlb_flushID,
    519 	.cf_tlb_flushID_SE	= arm10_tlb_flushID_SE,
    520 	.cf_tlb_flushI		= armv4_tlb_flushI,
    521 	.cf_tlb_flushI_SE	= arm10_tlb_flushI_SE,
    522 	.cf_tlb_flushD		= armv4_tlb_flushD,
    523 	.cf_tlb_flushD_SE	= armv4_tlb_flushD_SE,
    524 
    525 	/* Cache operations */
    526 
    527 	.cf_icache_sync_all	= armv5_icache_sync_all,
    528 	.cf_icache_sync_range	= armv5_icache_sync_range,
    529 
    530 	.cf_dcache_wbinv_all	= armv5_dcache_wbinv_all,
    531 	.cf_dcache_wbinv_range	= armv5_dcache_wbinv_range,
    532 /*XXX*/	.cf_dcache_inv_range	= armv5_dcache_wbinv_range,
    533 	.cf_dcache_wb_range	= armv5_dcache_wb_range,
    534 
    535 	.cf_sdcache_wbinv_range	= (void *)cpufunc_nullop,
    536 	.cf_sdcache_inv_range	= (void *)cpufunc_nullop,
    537 	.cf_sdcache_wb_range	= (void *)cpufunc_nullop,
    538 
    539 	.cf_idcache_wbinv_all	= armv5_idcache_wbinv_all,
    540 	.cf_idcache_wbinv_range = armv5_idcache_wbinv_range,
    541 
    542 	/* Other functions */
    543 
    544 	.cf_flush_prefetchbuf	= cpufunc_nullop,
    545 	.cf_drain_writebuf	= armv4_drain_writebuf,
    546 	.cf_flush_brnchtgt_C	= cpufunc_nullop,
    547 	.cf_flush_brnchtgt_E	= (void *)cpufunc_nullop,
    548 
    549 	.cf_sleep		= (void *)cpufunc_nullop,
    550 
    551 	/* Soft functions */
    552 
    553 	.cf_dataabt_fixup	= cpufunc_null_fixup,
    554 	.cf_prefetchabt_fixup	= cpufunc_null_fixup,
    555 
    556 	.cf_context_switch	= arm10_context_switch,
    557 
    558 	.cf_setup		= arm10_setup
    559 
    560 };
    561 #endif /* CPU_ARM10 */
    562 
    563 #ifdef CPU_ARM11
    564 struct cpu_functions arm11_cpufuncs = {
    565 	/* CPU functions */
    566 
    567 	.cf_id			= cpufunc_id,
    568 	.cf_cpwait		= cpufunc_nullop,
    569 
    570 	/* MMU functions */
    571 
    572 	.cf_control		= cpufunc_control,
    573 	.cf_domains		= cpufunc_domains,
    574 	.cf_setttb		= arm11_setttb,
    575 	.cf_faultstatus		= cpufunc_faultstatus,
    576 	.cf_faultaddress	= cpufunc_faultaddress,
    577 
    578 	/* TLB functions */
    579 
    580 	.cf_tlb_flushID		= arm11_tlb_flushID,
    581 	.cf_tlb_flushID_SE	= arm11_tlb_flushID_SE,
    582 	.cf_tlb_flushI		= arm11_tlb_flushI,
    583 	.cf_tlb_flushI_SE	= arm11_tlb_flushI_SE,
    584 	.cf_tlb_flushD		= arm11_tlb_flushD,
    585 	.cf_tlb_flushD_SE	= arm11_tlb_flushD_SE,
    586 
    587 	/* Cache operations */
    588 
    589 	.cf_icache_sync_all	= armv6_icache_sync_all,
    590 	.cf_icache_sync_range	= armv6_icache_sync_range,
    591 
    592 	.cf_dcache_wbinv_all	= armv6_dcache_wbinv_all,
    593 	.cf_dcache_wbinv_range	= armv6_dcache_wbinv_range,
    594 	.cf_dcache_inv_range	= armv6_dcache_inv_range,
    595 	.cf_dcache_wb_range	= armv6_dcache_wb_range,
    596 
    597 	.cf_sdcache_wbinv_range	= (void *)cpufunc_nullop,
    598 	.cf_sdcache_inv_range	= (void *)cpufunc_nullop,
    599 	.cf_sdcache_wb_range	= (void *)cpufunc_nullop,
    600 
    601 	.cf_idcache_wbinv_all	= armv6_idcache_wbinv_all,
    602 	.cf_idcache_wbinv_range = armv6_idcache_wbinv_range,
    603 
    604 	/* Other functions */
    605 
    606 	.cf_flush_prefetchbuf	= cpufunc_nullop,
    607 	.cf_drain_writebuf	= arm11_drain_writebuf,
    608 	.cf_flush_brnchtgt_C	= cpufunc_nullop,
    609 	.cf_flush_brnchtgt_E	= (void *)cpufunc_nullop,
    610 
    611 	.cf_sleep		= arm11_sleep,
    612 
    613 	/* Soft functions */
    614 
    615 	.cf_dataabt_fixup	= cpufunc_null_fixup,
    616 	.cf_prefetchabt_fixup	= cpufunc_null_fixup,
    617 
    618 	.cf_context_switch	= arm11_context_switch,
    619 
    620 	.cf_setup		= arm11_setup
    621 
    622 };
    623 #endif /* CPU_ARM11 */
    624 
    625 #ifdef CPU_ARM1136
    626 struct cpu_functions arm1136_cpufuncs = {
    627 	/* CPU functions */
    628 
    629 	.cf_id			= cpufunc_id,
    630 	.cf_cpwait		= cpufunc_nullop,
    631 
    632 	/* MMU functions */
    633 
    634 	.cf_control		= cpufunc_control,
    635 	.cf_domains		= cpufunc_domains,
    636 	.cf_setttb		= arm11_setttb,
    637 	.cf_faultstatus		= cpufunc_faultstatus,
    638 	.cf_faultaddress	= cpufunc_faultaddress,
    639 
    640 	/* TLB functions */
    641 
    642 	.cf_tlb_flushID		= arm11_tlb_flushID,
    643 	.cf_tlb_flushID_SE	= arm11_tlb_flushID_SE,
    644 	.cf_tlb_flushI		= arm11_tlb_flushI,
    645 	.cf_tlb_flushI_SE	= arm11_tlb_flushI_SE,
    646 	.cf_tlb_flushD		= arm11_tlb_flushD,
    647 	.cf_tlb_flushD_SE	= arm11_tlb_flushD_SE,
    648 
    649 	/* Cache operations */
    650 
    651 	.cf_icache_sync_all	= arm11x6_icache_sync_all,	/* 411920 */
    652 	.cf_icache_sync_range	= arm11x6_icache_sync_range,	/* 371025 */
    653 
    654 	.cf_dcache_wbinv_all	= arm11x6_dcache_wbinv_all,	/* 411920 */
    655 	.cf_dcache_wbinv_range	= armv6_dcache_wbinv_range,
    656 	.cf_dcache_inv_range	= armv6_dcache_inv_range,
    657 	.cf_dcache_wb_range	= armv6_dcache_wb_range,
    658 
    659 	.cf_sdcache_wbinv_range	= (void *)cpufunc_nullop,
    660 	.cf_sdcache_inv_range	= (void *)cpufunc_nullop,
    661 	.cf_sdcache_wb_range	= (void *)cpufunc_nullop,
    662 
    663 	.cf_idcache_wbinv_all	= arm11x6_idcache_wbinv_all,	/* 411920 */
    664 	.cf_idcache_wbinv_range = arm11x6_idcache_wbinv_range,	/* 371025 */
    665 
    666 	/* Other functions */
    667 
    668 	.cf_flush_prefetchbuf	= arm11x6_flush_prefetchbuf,
    669 	.cf_drain_writebuf	= arm11_drain_writebuf,
    670 	.cf_flush_brnchtgt_C	= cpufunc_nullop,
    671 	.cf_flush_brnchtgt_E	= (void *)cpufunc_nullop,
    672 
    673 	.cf_sleep		= arm11_sleep,	/* arm1136_sleep_rev0 */
    674 
    675 	/* Soft functions */
    676 
    677 	.cf_dataabt_fixup	= cpufunc_null_fixup,
    678 	.cf_prefetchabt_fixup	= cpufunc_null_fixup,
    679 
    680 	.cf_context_switch	= arm11_context_switch,
    681 
    682 	.cf_setup		= arm11x6_setup
    683 
    684 };
    685 #endif /* CPU_ARM1136 */
    686 
    687 #ifdef CPU_ARM1176
    688 struct cpu_functions arm1176_cpufuncs = {
    689 	/* CPU functions */
    690 
    691 	.cf_id			= cpufunc_id,
    692 	.cf_cpwait		= cpufunc_nullop,
    693 
    694 	/* MMU functions */
    695 
    696 	.cf_control		= cpufunc_control,
    697 	.cf_domains		= cpufunc_domains,
    698 	.cf_setttb		= arm11_setttb,
    699 	.cf_faultstatus		= cpufunc_faultstatus,
    700 	.cf_faultaddress	= cpufunc_faultaddress,
    701 
    702 	/* TLB functions */
    703 
    704 	.cf_tlb_flushID		= arm11_tlb_flushID,
    705 	.cf_tlb_flushID_SE	= arm11_tlb_flushID_SE,
    706 	.cf_tlb_flushI		= arm11_tlb_flushI,
    707 	.cf_tlb_flushI_SE	= arm11_tlb_flushI_SE,
    708 	.cf_tlb_flushD		= arm11_tlb_flushD,
    709 	.cf_tlb_flushD_SE	= arm11_tlb_flushD_SE,
    710 
    711 	/* Cache operations */
    712 
    713 	.cf_icache_sync_all	= arm11x6_icache_sync_all,	/* 415045 */
    714 	.cf_icache_sync_range	= arm11x6_icache_sync_range,	/* 371367 */
    715 
    716 	.cf_dcache_wbinv_all	= arm11x6_dcache_wbinv_all,	/* 415045 */
    717 	.cf_dcache_wbinv_range	= armv6_dcache_wbinv_range,
    718 	.cf_dcache_inv_range	= armv6_dcache_inv_range,
    719 	.cf_dcache_wb_range	= armv6_dcache_wb_range,
    720 
    721 	.cf_sdcache_wbinv_range	= (void *)cpufunc_nullop,
    722 	.cf_sdcache_inv_range	= (void *)cpufunc_nullop,
    723 	.cf_sdcache_wb_range	= (void *)cpufunc_nullop,
    724 
    725 	.cf_idcache_wbinv_all	= arm11x6_idcache_wbinv_all,	/* 415045 */
    726 	.cf_idcache_wbinv_range = arm11x6_idcache_wbinv_range,	/* 371367 */
    727 
    728 	/* Other functions */
    729 
    730 	.cf_flush_prefetchbuf	= arm11x6_flush_prefetchbuf,
    731 	.cf_drain_writebuf	= arm11_drain_writebuf,
    732 	.cf_flush_brnchtgt_C	= cpufunc_nullop,
    733 	.cf_flush_brnchtgt_E	= (void *)cpufunc_nullop,
    734 
    735 	.cf_sleep		= arm11x6_sleep,		/* no ref. */
    736 
    737 	/* Soft functions */
    738 
    739 	.cf_dataabt_fixup	= cpufunc_null_fixup,
    740 	.cf_prefetchabt_fixup	= cpufunc_null_fixup,
    741 
    742 	.cf_context_switch	= arm11_context_switch,
    743 
    744 	.cf_setup		= arm11x6_setup
    745 
    746 };
    747 #endif /* CPU_ARM1176 */
    748 
    749 
    750 #ifdef CPU_ARM11MPCORE
    751 struct cpu_functions arm11mpcore_cpufuncs = {
    752 	/* CPU functions */
    753 
    754 	.cf_id			= cpufunc_id,
    755 	.cf_cpwait		= cpufunc_nullop,
    756 
    757 	/* MMU functions */
    758 
    759 	.cf_control		= cpufunc_control,
    760 	.cf_domains		= cpufunc_domains,
    761 	.cf_setttb		= arm11_setttb,
    762 	.cf_faultstatus		= cpufunc_faultstatus,
    763 	.cf_faultaddress	= cpufunc_faultaddress,
    764 
    765 	/* TLB functions */
    766 
    767 	.cf_tlb_flushID		= arm11_tlb_flushID,
    768 	.cf_tlb_flushID_SE	= arm11_tlb_flushID_SE,
    769 	.cf_tlb_flushI		= arm11_tlb_flushI,
    770 	.cf_tlb_flushI_SE	= arm11_tlb_flushI_SE,
    771 	.cf_tlb_flushD		= arm11_tlb_flushD,
    772 	.cf_tlb_flushD_SE	= arm11_tlb_flushD_SE,
    773 
    774 	/* Cache operations */
    775 
    776 	.cf_icache_sync_all	= armv6_icache_sync_all,
    777 	.cf_icache_sync_range	= armv5_icache_sync_range,
    778 
    779 	.cf_dcache_wbinv_all	= armv6_dcache_wbinv_all,
    780 	.cf_dcache_wbinv_range	= armv5_dcache_wbinv_range,
    781 	.cf_dcache_inv_range	= armv5_dcache_inv_range,
    782 	.cf_dcache_wb_range	= armv5_dcache_wb_range,
    783 
    784 	.cf_sdcache_wbinv_range	= (void *)cpufunc_nullop,
    785 	.cf_sdcache_inv_range	= (void *)cpufunc_nullop,
    786 	.cf_sdcache_wb_range	= (void *)cpufunc_nullop,
    787 
    788 	.cf_idcache_wbinv_all	= armv6_idcache_wbinv_all,
    789 	.cf_idcache_wbinv_range = armv5_idcache_wbinv_range,
    790 
    791 	/* Other functions */
    792 
    793 	.cf_flush_prefetchbuf	= cpufunc_nullop,
    794 	.cf_drain_writebuf	= arm11_drain_writebuf,
    795 	.cf_flush_brnchtgt_C	= cpufunc_nullop,
    796 	.cf_flush_brnchtgt_E	= (void *)cpufunc_nullop,
    797 
    798 	.cf_sleep		= arm11_sleep,
    799 
    800 	/* Soft functions */
    801 
    802 	.cf_dataabt_fixup	= cpufunc_null_fixup,
    803 	.cf_prefetchabt_fixup	= cpufunc_null_fixup,
    804 
    805 	.cf_context_switch	= arm11_context_switch,
    806 
    807 	.cf_setup		= arm11mpcore_setup
    808 
    809 };
    810 #endif /* CPU_ARM11MPCORE */
    811 
    812 #ifdef CPU_SA110
    813 struct cpu_functions sa110_cpufuncs = {
    814 	/* CPU functions */
    815 
    816 	.cf_id			= cpufunc_id,
    817 	.cf_cpwait		= cpufunc_nullop,
    818 
    819 	/* MMU functions */
    820 
    821 	.cf_control		= cpufunc_control,
    822 	.cf_domains		= cpufunc_domains,
    823 	.cf_setttb		= sa1_setttb,
    824 	.cf_faultstatus		= cpufunc_faultstatus,
    825 	.cf_faultaddress	= cpufunc_faultaddress,
    826 
    827 	/* TLB functions */
    828 
    829 	.cf_tlb_flushID		= armv4_tlb_flushID,
    830 	.cf_tlb_flushID_SE	= sa1_tlb_flushID_SE,
    831 	.cf_tlb_flushI		= armv4_tlb_flushI,
    832 	.cf_tlb_flushI_SE	= (void *)armv4_tlb_flushI,
    833 	.cf_tlb_flushD		= armv4_tlb_flushD,
    834 	.cf_tlb_flushD_SE	= armv4_tlb_flushD_SE,
    835 
    836 	/* Cache operations */
    837 
    838 	.cf_icache_sync_all	= sa1_cache_syncI,
    839 	.cf_icache_sync_range	= sa1_cache_syncI_rng,
    840 
    841 	.cf_dcache_wbinv_all	= sa1_cache_purgeD,
    842 	.cf_dcache_wbinv_range	= sa1_cache_purgeD_rng,
    843 /*XXX*/	.cf_dcache_inv_range	= sa1_cache_purgeD_rng,
    844 	.cf_dcache_wb_range	= sa1_cache_cleanD_rng,
    845 
    846 	.cf_sdcache_wbinv_range	= (void *)cpufunc_nullop,
    847 	.cf_sdcache_inv_range	= (void *)cpufunc_nullop,
    848 	.cf_sdcache_wb_range	= (void *)cpufunc_nullop,
    849 
    850 	.cf_idcache_wbinv_all	= sa1_cache_purgeID,
    851 	.cf_idcache_wbinv_range	= sa1_cache_purgeID_rng,
    852 
    853 	/* Other functions */
    854 
    855 	.cf_flush_prefetchbuf	= cpufunc_nullop,
    856 	.cf_drain_writebuf	= armv4_drain_writebuf,
    857 	.cf_flush_brnchtgt_C	= cpufunc_nullop,
    858 	.cf_flush_brnchtgt_E	= (void *)cpufunc_nullop,
    859 
    860 	.cf_sleep		= (void *)cpufunc_nullop,
    861 
    862 	/* Soft functions */
    863 
    864 	.cf_dataabt_fixup	= cpufunc_null_fixup,
    865 	.cf_prefetchabt_fixup	= cpufunc_null_fixup,
    866 
    867 	.cf_context_switch	= sa110_context_switch,
    868 
    869 	.cf_setup		= sa110_setup
    870 };
    871 #endif	/* CPU_SA110 */
    872 
    873 #if defined(CPU_SA1100) || defined(CPU_SA1110)
    874 struct cpu_functions sa11x0_cpufuncs = {
    875 	/* CPU functions */
    876 
    877 	.cf_id			= cpufunc_id,
    878 	.cf_cpwait		= cpufunc_nullop,
    879 
    880 	/* MMU functions */
    881 
    882 	.cf_control		= cpufunc_control,
    883 	.cf_domains		= cpufunc_domains,
    884 	.cf_setttb		= sa1_setttb,
    885 	.cf_faultstatus		= cpufunc_faultstatus,
    886 	.cf_faultaddress	= cpufunc_faultaddress,
    887 
    888 	/* TLB functions */
    889 
    890 	.cf_tlb_flushID		= armv4_tlb_flushID,
    891 	.cf_tlb_flushID_SE	= sa1_tlb_flushID_SE,
    892 	.cf_tlb_flushI		= armv4_tlb_flushI,
    893 	.cf_tlb_flushI_SE	= (void *)armv4_tlb_flushI,
    894 	.cf_tlb_flushD		= armv4_tlb_flushD,
    895 	.cf_tlb_flushD_SE	= armv4_tlb_flushD_SE,
    896 
    897 	/* Cache operations */
    898 
    899 	.cf_icache_sync_all	= sa1_cache_syncI,
    900 	.cf_icache_sync_range	= sa1_cache_syncI_rng,
    901 
    902 	.cf_dcache_wbinv_all	= sa1_cache_purgeD,
    903 	.cf_dcache_wbinv_range	= sa1_cache_purgeD_rng,
    904 /*XXX*/	.cf_dcache_inv_range	= sa1_cache_purgeD_rng,
    905 	.cf_dcache_wb_range	= sa1_cache_cleanD_rng,
    906 
    907 	.cf_sdcache_wbinv_range	= (void *)cpufunc_nullop,
    908 	.cf_sdcache_inv_range	= (void *)cpufunc_nullop,
    909 	.cf_sdcache_wb_range	= (void *)cpufunc_nullop,
    910 
    911 	.cf_idcache_wbinv_all	= sa1_cache_purgeID,
    912 	.cf_idcache_wbinv_range	= sa1_cache_purgeID_rng,
    913 
    914 	/* Other functions */
    915 
    916 	.cf_flush_prefetchbuf	= sa11x0_drain_readbuf,
    917 	.cf_drain_writebuf	= armv4_drain_writebuf,
    918 	.cf_flush_brnchtgt_C	= cpufunc_nullop,
    919 	.cf_flush_brnchtgt_E	= (void *)cpufunc_nullop,
    920 
    921 	.cf_sleep		= sa11x0_cpu_sleep,
    922 
    923 	/* Soft functions */
    924 
    925 	.cf_dataabt_fixup	= cpufunc_null_fixup,
    926 	.cf_prefetchabt_fixup	= cpufunc_null_fixup,
    927 
    928 	.cf_context_switch	= sa11x0_context_switch,
    929 
    930 	.cf_setup		= sa11x0_setup
    931 };
    932 #endif	/* CPU_SA1100 || CPU_SA1110 */
    933 
    934 #if defined(CPU_FA526)
    935 struct cpu_functions fa526_cpufuncs = {
    936 	/* CPU functions */
    937 
    938 	.cf_id			= cpufunc_id,
    939 	.cf_cpwait		= cpufunc_nullop,
    940 
    941 	/* MMU functions */
    942 
    943 	.cf_control		= cpufunc_control,
    944 	.cf_domains		= cpufunc_domains,
    945 	.cf_setttb		= fa526_setttb,
    946 	.cf_faultstatus		= cpufunc_faultstatus,
    947 	.cf_faultaddress	= cpufunc_faultaddress,
    948 
    949 	/* TLB functions */
    950 
    951 	.cf_tlb_flushID		= armv4_tlb_flushID,
    952 	.cf_tlb_flushID_SE	= fa526_tlb_flushID_SE,
    953 	.cf_tlb_flushI		= armv4_tlb_flushI,
    954 	.cf_tlb_flushI_SE	= fa526_tlb_flushI_SE,
    955 	.cf_tlb_flushD		= armv4_tlb_flushD,
    956 	.cf_tlb_flushD_SE	= armv4_tlb_flushD_SE,
    957 
    958 	/* Cache operations */
    959 
    960 	.cf_icache_sync_all	= fa526_icache_sync_all,
    961 	.cf_icache_sync_range	= fa526_icache_sync_range,
    962 
    963 	.cf_dcache_wbinv_all	= fa526_dcache_wbinv_all,
    964 	.cf_dcache_wbinv_range	= fa526_dcache_wbinv_range,
    965 	.cf_dcache_inv_range	= fa526_dcache_inv_range,
    966 	.cf_dcache_wb_range	= fa526_dcache_wb_range,
    967 
    968 	.cf_sdcache_wbinv_range	= (void *)cpufunc_nullop,
    969 	.cf_sdcache_inv_range	= (void *)cpufunc_nullop,
    970 	.cf_sdcache_wb_range	= (void *)cpufunc_nullop,
    971 
    972 	.cf_idcache_wbinv_all	= fa526_idcache_wbinv_all,
    973 	.cf_idcache_wbinv_range	= fa526_idcache_wbinv_range,
    974 
    975 	/* Other functions */
    976 
    977 	.cf_flush_prefetchbuf	= fa526_flush_prefetchbuf,
    978 	.cf_drain_writebuf	= armv4_drain_writebuf,
    979 	.cf_flush_brnchtgt_C	= cpufunc_nullop,
    980 	.cf_flush_brnchtgt_E	= fa526_flush_brnchtgt_E,
    981 
    982 	.cf_sleep		= fa526_cpu_sleep,
    983 
    984 	/* Soft functions */
    985 
    986 	.cf_dataabt_fixup	= cpufunc_null_fixup,
    987 	.cf_prefetchabt_fixup	= cpufunc_null_fixup,
    988 
    989 	.cf_context_switch	= fa526_context_switch,
    990 
    991 	.cf_setup		= fa526_setup
    992 };
    993 #endif	/* CPU_FA526 */
    994 
    995 #ifdef CPU_IXP12X0
    996 struct cpu_functions ixp12x0_cpufuncs = {
    997 	/* CPU functions */
    998 
    999 	.cf_id			= cpufunc_id,
   1000 	.cf_cpwait		= cpufunc_nullop,
   1001 
   1002 	/* MMU functions */
   1003 
   1004 	.cf_control		= cpufunc_control,
   1005 	.cf_domains		= cpufunc_domains,
   1006 	.cf_setttb		= sa1_setttb,
   1007 	.cf_faultstatus		= cpufunc_faultstatus,
   1008 	.cf_faultaddress	= cpufunc_faultaddress,
   1009 
   1010 	/* TLB functions */
   1011 
   1012 	.cf_tlb_flushID		= armv4_tlb_flushID,
   1013 	.cf_tlb_flushID_SE	= sa1_tlb_flushID_SE,
   1014 	.cf_tlb_flushI		= armv4_tlb_flushI,
   1015 	.cf_tlb_flushI_SE	= (void *)armv4_tlb_flushI,
   1016 	.cf_tlb_flushD		= armv4_tlb_flushD,
   1017 	.cf_tlb_flushD_SE	= armv4_tlb_flushD_SE,
   1018 
   1019 	/* Cache operations */
   1020 
   1021 	.cf_icache_sync_all	= sa1_cache_syncI,
   1022 	.cf_icache_sync_range	= sa1_cache_syncI_rng,
   1023 
   1024 	.cf_dcache_wbinv_all	= sa1_cache_purgeD,
   1025 	.cf_dcache_wbinv_range	= sa1_cache_purgeD_rng,
   1026 /*XXX*/	.cf_dcache_inv_range	= sa1_cache_purgeD_rng,
   1027 	.cf_dcache_wb_range	= sa1_cache_cleanD_rng,
   1028 
   1029 	.cf_sdcache_wbinv_range	= (void *)cpufunc_nullop,
   1030 	.cf_sdcache_inv_range	= (void *)cpufunc_nullop,
   1031 	.cf_sdcache_wb_range	= (void *)cpufunc_nullop,
   1032 
   1033 	.cf_idcache_wbinv_all	= sa1_cache_purgeID,
   1034 	.cf_idcache_wbinv_range	= sa1_cache_purgeID_rng,
   1035 
   1036 	/* Other functions */
   1037 
   1038 	.cf_flush_prefetchbuf	= ixp12x0_drain_readbuf,
   1039 	.cf_drain_writebuf	= armv4_drain_writebuf,
   1040 	.cf_flush_brnchtgt_C	= cpufunc_nullop,
   1041 	.cf_flush_brnchtgt_E	= (void *)cpufunc_nullop,
   1042 
   1043 	.cf_sleep		= (void *)cpufunc_nullop,
   1044 
   1045 	/* Soft functions */
   1046 
   1047 	.cf_dataabt_fixup	= cpufunc_null_fixup,
   1048 	.cf_prefetchabt_fixup	= cpufunc_null_fixup,
   1049 
   1050 	.cf_context_switch	= ixp12x0_context_switch,
   1051 
   1052 	.cf_setup		= ixp12x0_setup
   1053 };
   1054 #endif	/* CPU_IXP12X0 */
   1055 
   1056 #if defined(CPU_XSCALE)
   1057 struct cpu_functions xscale_cpufuncs = {
   1058 	/* CPU functions */
   1059 
   1060 	.cf_id			= cpufunc_id,
   1061 	.cf_cpwait		= xscale_cpwait,
   1062 
   1063 	/* MMU functions */
   1064 
   1065 	.cf_control		= xscale_control,
   1066 	.cf_domains		= cpufunc_domains,
   1067 	.cf_setttb		= xscale_setttb,
   1068 	.cf_faultstatus		= cpufunc_faultstatus,
   1069 	.cf_faultaddress	= cpufunc_faultaddress,
   1070 
   1071 	/* TLB functions */
   1072 
   1073 	.cf_tlb_flushID		= armv4_tlb_flushID,
   1074 	.cf_tlb_flushID_SE	= xscale_tlb_flushID_SE,
   1075 	.cf_tlb_flushI		= armv4_tlb_flushI,
   1076 	.cf_tlb_flushI_SE	= (void *)armv4_tlb_flushI,
   1077 	.cf_tlb_flushD		= armv4_tlb_flushD,
   1078 	.cf_tlb_flushD_SE	= armv4_tlb_flushD_SE,
   1079 
   1080 	/* Cache operations */
   1081 
   1082 	.cf_icache_sync_all	= xscale_cache_syncI,
   1083 	.cf_icache_sync_range	= xscale_cache_syncI_rng,
   1084 
   1085 	.cf_dcache_wbinv_all	= xscale_cache_purgeD,
   1086 	.cf_dcache_wbinv_range	= xscale_cache_purgeD_rng,
   1087 	.cf_dcache_inv_range	= xscale_cache_flushD_rng,
   1088 	.cf_dcache_wb_range	= xscale_cache_cleanD_rng,
   1089 
   1090 	.cf_sdcache_wbinv_range	= (void *)cpufunc_nullop,
   1091 	.cf_sdcache_inv_range	= (void *)cpufunc_nullop,
   1092 	.cf_sdcache_wb_range	= (void *)cpufunc_nullop,
   1093 
   1094 	.cf_idcache_wbinv_all	= xscale_cache_purgeID,
   1095 	.cf_idcache_wbinv_range = xscale_cache_purgeID_rng,
   1096 
   1097 	/* Other functions */
   1098 
   1099 	.cf_flush_prefetchbuf	= cpufunc_nullop,
   1100 	.cf_drain_writebuf	= armv4_drain_writebuf,
   1101 	.cf_flush_brnchtgt_C	= cpufunc_nullop,
   1102 	.cf_flush_brnchtgt_E	= (void *)cpufunc_nullop,
   1103 
   1104 	.cf_sleep		= xscale_cpu_sleep,
   1105 
   1106 	/* Soft functions */
   1107 
   1108 	.cf_dataabt_fixup	= cpufunc_null_fixup,
   1109 	.cf_prefetchabt_fixup	= cpufunc_null_fixup,
   1110 
   1111 	.cf_context_switch	= xscale_context_switch,
   1112 
   1113 	.cf_setup		= xscale_setup
   1114 };
   1115 #endif /* CPU_XSCALE */
   1116 
   1117 #if defined(CPU_ARMV7)
   1118 struct cpu_functions armv7_cpufuncs = {
   1119 	/* CPU functions */
   1120 
   1121 	.cf_id			= cpufunc_id,
   1122 	.cf_cpwait		= cpufunc_nullop,
   1123 
   1124 	/* MMU functions */
   1125 
   1126 	.cf_control		= cpufunc_control,
   1127 	.cf_domains		= cpufunc_domains,
   1128 	.cf_setttb		= armv7_setttb,
   1129 	.cf_faultstatus		= cpufunc_faultstatus,
   1130 	.cf_faultaddress	= cpufunc_faultaddress,
   1131 
   1132 	/* TLB functions */
   1133 
   1134 	.cf_tlb_flushID		= armv7up_tlb_flushID,
   1135 	.cf_tlb_flushID_SE	= armv7up_tlb_flushID_SE,
   1136 	.cf_tlb_flushI		= armv7up_tlb_flushI,
   1137 	.cf_tlb_flushI_SE	= armv7up_tlb_flushI_SE,
   1138 	.cf_tlb_flushD		= armv7up_tlb_flushD,
   1139 	.cf_tlb_flushD_SE	= armv7up_tlb_flushD_SE,
   1140 
   1141 	/* Cache operations */
   1142 
   1143 	.cf_icache_sync_all	= armv7_icache_sync_all,
   1144 	.cf_dcache_wbinv_all	= armv7_dcache_wbinv_all,
   1145 
   1146 	.cf_dcache_inv_range	= armv7_dcache_inv_range,
   1147 	.cf_dcache_wb_range	= armv7_dcache_wb_range,
   1148 	.cf_dcache_wbinv_range	= armv7_dcache_wbinv_range,
   1149 
   1150 	.cf_sdcache_wbinv_range	= (void *)cpufunc_nullop,
   1151 	.cf_sdcache_inv_range	= (void *)cpufunc_nullop,
   1152 	.cf_sdcache_wb_range	= (void *)cpufunc_nullop,
   1153 
   1154 	.cf_icache_sync_range	= armv7_icache_sync_range,
   1155 	.cf_idcache_wbinv_range = armv7_idcache_wbinv_range,
   1156 
   1157 
   1158 	.cf_idcache_wbinv_all	= armv7_idcache_wbinv_all,
   1159 
   1160 	/* Other functions */
   1161 
   1162 	.cf_flush_prefetchbuf	= cpufunc_nullop,
   1163 	.cf_drain_writebuf	= armv7_drain_writebuf,
   1164 	.cf_flush_brnchtgt_C	= cpufunc_nullop,
   1165 	.cf_flush_brnchtgt_E	= (void *)cpufunc_nullop,
   1166 
   1167 	.cf_sleep		= armv7_cpu_sleep,
   1168 
   1169 	/* Soft functions */
   1170 
   1171 	.cf_dataabt_fixup	= cpufunc_null_fixup,
   1172 	.cf_prefetchabt_fixup	= cpufunc_null_fixup,
   1173 
   1174 	.cf_context_switch	= armv7_context_switch,
   1175 
   1176 	.cf_setup		= armv7_setup
   1177 
   1178 };
   1179 #endif /* CPU_ARMV7 */
   1180 
   1181 #ifdef CPU_PJ4B
   1182 struct cpu_functions pj4bv7_cpufuncs = {
   1183 	/* CPU functions */
   1184 
   1185 	.cf_id			= cpufunc_id,
   1186 	.cf_cpwait		= armv7_drain_writebuf,
   1187 
   1188 	/* MMU functions */
   1189 
   1190 	.cf_control		= cpufunc_control,
   1191 	.cf_domains		= cpufunc_domains,
   1192 	.cf_setttb		= armv7_setttb,
   1193 	.cf_faultstatus		= cpufunc_faultstatus,
   1194 	.cf_faultaddress	= cpufunc_faultaddress,
   1195 
   1196 	/* TLB functions */
   1197 
   1198 	.cf_tlb_flushID		= armv7up_tlb_flushID,
   1199 	.cf_tlb_flushID_SE	= armv7up_tlb_flushID_SE,
   1200 	.cf_tlb_flushI		= armv7up_tlb_flushID,
   1201 	.cf_tlb_flushI_SE	= armv7up_tlb_flushID_SE,
   1202 	.cf_tlb_flushD		= armv7up_tlb_flushID,
   1203 	.cf_tlb_flushD_SE	= armv7up_tlb_flushID_SE,
   1204 
   1205 	/* Cache operations (see also pj4bv7_setup) */
   1206 	.cf_icache_sync_all	= armv7_idcache_wbinv_all,
   1207 	.cf_icache_sync_range	= armv7_icache_sync_range,
   1208 
   1209 	.cf_dcache_wbinv_all	= armv7_dcache_wbinv_all,
   1210 	.cf_dcache_wbinv_range	= armv7_dcache_wbinv_range,
   1211 	.cf_dcache_inv_range	= armv7_dcache_inv_range,
   1212 	.cf_dcache_wb_range	= armv7_dcache_wb_range,
   1213 
   1214 	.cf_sdcache_wbinv_range	= (void *)cpufunc_nullop,
   1215 	.cf_sdcache_inv_range	= (void *)cpufunc_nullop,
   1216 	.cf_sdcache_wb_range	= (void *)cpufunc_nullop,
   1217 
   1218 	.cf_idcache_wbinv_all	= armv7_idcache_wbinv_all,
   1219 	.cf_idcache_wbinv_range	= armv7_idcache_wbinv_range,
   1220 
   1221 	/* Other functions */
   1222 
   1223 	.cf_flush_prefetchbuf	= cpufunc_nullop,
   1224 	.cf_drain_writebuf	= armv7_drain_writebuf,
   1225 	.cf_flush_brnchtgt_C	= cpufunc_nullop,
   1226 	.cf_flush_brnchtgt_E	= (void *)cpufunc_nullop,
   1227 
   1228 	.cf_sleep		= pj4b_cpu_sleep,
   1229 
   1230 	/* Soft functions */
   1231 
   1232 	.cf_dataabt_fixup	= cpufunc_null_fixup,
   1233 	.cf_prefetchabt_fixup	= cpufunc_null_fixup,
   1234 
   1235 	.cf_context_switch	= armv7_context_switch,
   1236 
   1237 	.cf_setup		= pj4bv7_setup
   1238 };
   1239 #endif /* CPU_PJ4B */
   1240 
   1241 #ifdef CPU_SHEEVA
   1242 struct cpu_functions sheeva_cpufuncs = {
   1243 	/* CPU functions */
   1244 
   1245 	.cf_id			= cpufunc_id,
   1246 	.cf_cpwait		= cpufunc_nullop,
   1247 
   1248 	/* MMU functions */
   1249 
   1250 	.cf_control		= cpufunc_control,
   1251 	.cf_domains		= cpufunc_domains,
   1252 	.cf_setttb		= armv5_ec_setttb,
   1253 	.cf_faultstatus		= cpufunc_faultstatus,
   1254 	.cf_faultaddress	= cpufunc_faultaddress,
   1255 
   1256 	/* TLB functions */
   1257 
   1258 	.cf_tlb_flushID		= armv4_tlb_flushID,
   1259 	.cf_tlb_flushID_SE	= arm10_tlb_flushID_SE,
   1260 	.cf_tlb_flushI		= armv4_tlb_flushI,
   1261 	.cf_tlb_flushI_SE	= arm10_tlb_flushI_SE,
   1262 	.cf_tlb_flushD		= armv4_tlb_flushD,
   1263 	.cf_tlb_flushD_SE	= armv4_tlb_flushD_SE,
   1264 
   1265 	/* Cache operations */
   1266 
   1267 	.cf_icache_sync_all	= armv5_ec_icache_sync_all,
   1268 	.cf_icache_sync_range	= armv5_ec_icache_sync_range,
   1269 
   1270 	.cf_dcache_wbinv_all	= armv5_ec_dcache_wbinv_all,
   1271 	.cf_dcache_wbinv_range	= sheeva_dcache_wbinv_range,
   1272 	.cf_dcache_inv_range	= sheeva_dcache_inv_range,
   1273 	.cf_dcache_wb_range	= sheeva_dcache_wb_range,
   1274 
   1275 	.cf_sdcache_wbinv_range	= (void *)cpufunc_nullop,
   1276 	.cf_sdcache_inv_range	= (void *)cpufunc_nullop,
   1277 	.cf_sdcache_wb_range	= (void *)cpufunc_nullop,
   1278 
   1279 	.cf_idcache_wbinv_all	= armv5_ec_idcache_wbinv_all,
   1280 	.cf_idcache_wbinv_range = sheeva_idcache_wbinv_range,
   1281 
   1282 	/* Other functions */
   1283 
   1284 	.cf_flush_prefetchbuf	= cpufunc_nullop,
   1285 	.cf_drain_writebuf	= armv4_drain_writebuf,
   1286 	.cf_flush_brnchtgt_C	= cpufunc_nullop,
   1287 	.cf_flush_brnchtgt_E	= (void *)cpufunc_nullop,
   1288 
   1289 	.cf_sleep		= (void *)sheeva_cpu_sleep,
   1290 
   1291 	/* Soft functions */
   1292 
   1293 	.cf_dataabt_fixup	= cpufunc_null_fixup,
   1294 	.cf_prefetchabt_fixup	= cpufunc_null_fixup,
   1295 
   1296 	.cf_context_switch	= arm10_context_switch,
   1297 
   1298 	.cf_setup		= sheeva_setup
   1299 };
   1300 #endif /* CPU_SHEEVA */
   1301 
   1302 
   1303 /*
   1304  * Global constants also used by locore.s
   1305  */
   1306 
   1307 struct cpu_functions cpufuncs;
   1308 u_int cputype;
   1309 
   1310 #if defined(CPU_ARM7TDMI) || defined(CPU_ARM8) || defined(CPU_ARM9) || \
   1311     defined(CPU_ARM9E) || defined(CPU_ARM10) || defined(CPU_FA526) || \
   1312     defined(CPU_SHEEVA) || \
   1313     defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \
   1314     defined(__CPU_XSCALE_PXA2XX) || defined(CPU_XSCALE_IXP425) || \
   1315     defined(CPU_ARMV6) || defined(CPU_ARMV7)
   1316 static void get_cachetype_cp15(void);
   1317 
   1318 /* Additional cache information local to this file.  Log2 of some of the
   1319    above numbers.  */
   1320 static int	arm_dcache_log2_nsets;
   1321 static int	arm_dcache_log2_assoc;
   1322 static int	arm_dcache_log2_linesize;
   1323 
   1324 #if (ARM_MMU_V6 + ARM_MMU_V7) > 0
   1325 static inline u_int
   1326 get_cachesize_cp15(int cssr)
   1327 {
   1328 #if defined(CPU_ARMV7)
   1329 	__asm volatile(".arch\tarmv7a");
   1330 
   1331 	armreg_csselr_write(cssr);
   1332 	isb();			 /* sync to the new cssr */
   1333 
   1334 #else
   1335 	__asm volatile("mcr p15, 1, %0, c0, c0, 2" :: "r" (cssr) : "memory");
   1336 #endif
   1337 	return armreg_ccsidr_read();
   1338 }
   1339 #endif
   1340 
   1341 #if (ARM_MMU_V6 + ARM_MMU_V7) > 0
   1342 static void
   1343 get_cacheinfo_clidr(struct arm_cache_info *info, u_int level, u_int clidr)
   1344 {
   1345 	u_int csid;
   1346 
   1347 	if (clidr & 6) {
   1348 		csid = get_cachesize_cp15(level << 1); /* select dcache values */
   1349 		info->dcache_sets = CPU_CSID_NUMSETS(csid) + 1;
   1350 		info->dcache_ways = CPU_CSID_ASSOC(csid) + 1;
   1351 		info->dcache_line_size = 1U << (CPU_CSID_LEN(csid) + 4);
   1352 		info->dcache_way_size =
   1353 		    info->dcache_line_size * info->dcache_sets;
   1354 		info->dcache_size = info->dcache_way_size * info->dcache_ways;
   1355 
   1356 		if (level == 0) {
   1357 			arm_dcache_log2_assoc = CPU_CSID_ASSOC(csid) + 1;
   1358 			arm_dcache_log2_linesize = CPU_CSID_LEN(csid) + 4;
   1359 			arm_dcache_log2_nsets =
   1360 			    31 - __builtin_clz(info->dcache_sets*2-1);
   1361 		}
   1362 	}
   1363 
   1364 	info->cache_unified = (clidr == 4);
   1365 
   1366 	if (level > 0) {
   1367 		info->dcache_type = CACHE_TYPE_PIPT;
   1368 		info->icache_type = CACHE_TYPE_PIPT;
   1369 	}
   1370 
   1371 	if (info->cache_unified) {
   1372 		info->icache_ways = info->dcache_ways;
   1373 		info->icache_line_size = info->dcache_line_size;
   1374 		info->icache_way_size = info->dcache_way_size;
   1375 		info->icache_size = info->dcache_size;
   1376 	} else {
   1377 		csid = get_cachesize_cp15((level << 1)|CPU_CSSR_InD); /* select icache values */
   1378 		info->icache_sets = CPU_CSID_NUMSETS(csid) + 1;
   1379 		info->icache_ways = CPU_CSID_ASSOC(csid) + 1;
   1380 		info->icache_line_size = 1U << (CPU_CSID_LEN(csid) + 4);
   1381 		info->icache_way_size = info->icache_line_size * info->icache_sets;
   1382 		info->icache_size = info->icache_way_size * info->icache_ways;
   1383 	}
   1384 	if (level == 0
   1385 	    && info->dcache_way_size <= PAGE_SIZE
   1386 	    && info->icache_way_size <= PAGE_SIZE) {
   1387 		arm_cache_prefer_mask = 0;
   1388 	}
   1389 }
   1390 #endif /* (ARM_MMU_V6 + ARM_MMU_V7) > 0 */
   1391 
   1392 static void
   1393 get_cachetype_cp15(void)
   1394 {
   1395 	u_int ctype, isize, dsize;
   1396 	u_int multiplier;
   1397 
   1398 	ctype = armreg_ctr_read();
   1399 
   1400 	/*
   1401 	 * ...and thus spake the ARM ARM:
   1402 	 *
   1403 	 * If an <opcode2> value corresponding to an unimplemented or
   1404 	 * reserved ID register is encountered, the System Control
   1405 	 * processor returns the value of the main ID register.
   1406 	 */
   1407 	if (ctype == cpu_idnum())
   1408 		goto out;
   1409 
   1410 #if (ARM_MMU_V6 + ARM_MMU_V7) > 0
   1411 	if (CPU_CT_FORMAT(ctype) == 4) {
   1412 		u_int clidr = armreg_clidr_read();
   1413 
   1414 		if (CPU_CT4_L1IPOLICY(ctype) == CPU_CT4_L1_PIPT) {
   1415 			arm_pcache.icache_type = CACHE_TYPE_PIPT;
   1416 		} else {
   1417 			arm_pcache.icache_type = CACHE_TYPE_VIPT;
   1418 			arm_cache_prefer_mask = PAGE_SIZE;
   1419 		}
   1420 #ifdef CPU_CORTEX
   1421 		if (CPU_ID_CORTEX_P(cpu_idnum())) {
   1422 			arm_pcache.dcache_type = CACHE_TYPE_PIPT;
   1423 		} else
   1424 #endif
   1425 		{
   1426 			arm_pcache.dcache_type = CACHE_TYPE_VIPT;
   1427 		}
   1428 		arm_pcache.cache_type = CPU_CT_CTYPE_WB14;
   1429 
   1430 		get_cacheinfo_clidr(&arm_pcache, 0, clidr & 7);
   1431 		arm_dcache_align = arm_pcache.dcache_line_size;
   1432 		clidr >>= 3;
   1433 		if (clidr & 7) {
   1434 			get_cacheinfo_clidr(&arm_scache, 1, clidr & 7);
   1435 			if (arm_scache.dcache_line_size < arm_dcache_align)
   1436 				arm_dcache_align = arm_scache.dcache_line_size;
   1437 		}
   1438 		/*
   1439 		 * The pmap cleans an entire way for an exec page so
   1440 		 * we don't care that it's VIPT anymore.
   1441 		 */
   1442 		if (arm_pcache.dcache_type == CACHE_TYPE_PIPT) {
   1443 			arm_cache_prefer_mask = 0;
   1444 		}
   1445 		goto out;
   1446 	}
   1447 #endif /* ARM_MMU_V6 + ARM_MMU_V7 > 0 */
   1448 
   1449 	if ((ctype & CPU_CT_S) == 0)
   1450 		arm_pcache.cache_unified = 1;
   1451 
   1452 	/*
   1453 	 * If you want to know how this code works, go read the ARM ARM.
   1454 	 */
   1455 
   1456 	arm_pcache.cache_type = CPU_CT_CTYPE(ctype);
   1457 
   1458 	if (arm_pcache.cache_unified == 0) {
   1459 		isize = CPU_CT_ISIZE(ctype);
   1460 		multiplier = (isize & CPU_CT_xSIZE_M) ? 3 : 2;
   1461 		arm_pcache.icache_line_size = 1U << (CPU_CT_xSIZE_LEN(isize) + 3);
   1462 		if (CPU_CT_xSIZE_ASSOC(isize) == 0) {
   1463 			if (isize & CPU_CT_xSIZE_M)
   1464 				arm_pcache.icache_line_size = 0; /* not present */
   1465 			else
   1466 				arm_pcache.icache_ways = 1;
   1467 		} else {
   1468 			arm_pcache.icache_ways = multiplier <<
   1469 			    (CPU_CT_xSIZE_ASSOC(isize) - 1);
   1470 #if (ARM_MMU_V6 + ARM_MMU_V7) > 0
   1471 			arm_pcache.icache_type = CACHE_TYPE_VIPT;
   1472 			if (CPU_CT_xSIZE_P & isize)
   1473 				arm_cache_prefer_mask |=
   1474 				    __BIT(9 + CPU_CT_xSIZE_SIZE(isize)
   1475 					  - CPU_CT_xSIZE_ASSOC(isize))
   1476 				    - PAGE_SIZE;
   1477 #endif
   1478 		}
   1479 		arm_pcache.icache_size = multiplier << (CPU_CT_xSIZE_SIZE(isize) + 8);
   1480 		arm_pcache.icache_way_size =
   1481 		    __BIT(9 + CPU_CT_xSIZE_SIZE(isize) - CPU_CT_xSIZE_ASSOC(isize));
   1482 	}
   1483 
   1484 	dsize = CPU_CT_DSIZE(ctype);
   1485 	multiplier = (dsize & CPU_CT_xSIZE_M) ? 3 : 2;
   1486 	arm_pcache.dcache_line_size = 1U << (CPU_CT_xSIZE_LEN(dsize) + 3);
   1487 	if (CPU_CT_xSIZE_ASSOC(dsize) == 0) {
   1488 		if (dsize & CPU_CT_xSIZE_M)
   1489 			arm_pcache.dcache_line_size = 0; /* not present */
   1490 		else
   1491 			arm_pcache.dcache_ways = 1;
   1492 	} else {
   1493 		arm_pcache.dcache_ways = multiplier <<
   1494 		    (CPU_CT_xSIZE_ASSOC(dsize) - 1);
   1495 #if (ARM_MMU_V6) > 0
   1496 		arm_pcache.dcache_type = CACHE_TYPE_VIPT;
   1497 		if ((CPU_CT_xSIZE_P & dsize)
   1498 		    && CPU_ID_ARM11_P(curcpu()->ci_arm_cpuid)) {
   1499 			arm_cache_prefer_mask |=
   1500 			    __BIT(9 + CPU_CT_xSIZE_SIZE(dsize)
   1501 				  - CPU_CT_xSIZE_ASSOC(dsize)) - PAGE_SIZE;
   1502 		}
   1503 #endif
   1504 	}
   1505 	arm_pcache.dcache_size = multiplier << (CPU_CT_xSIZE_SIZE(dsize) + 8);
   1506 	arm_pcache.dcache_way_size =
   1507 	    __BIT(9 + CPU_CT_xSIZE_SIZE(dsize) - CPU_CT_xSIZE_ASSOC(dsize));
   1508 
   1509 	arm_dcache_align = arm_pcache.dcache_line_size;
   1510 
   1511 	arm_dcache_log2_assoc = CPU_CT_xSIZE_ASSOC(dsize) + multiplier - 2;
   1512 	arm_dcache_log2_linesize = CPU_CT_xSIZE_LEN(dsize) + 3;
   1513 	arm_dcache_log2_nsets = 6 + CPU_CT_xSIZE_SIZE(dsize) -
   1514 	    CPU_CT_xSIZE_ASSOC(dsize) - CPU_CT_xSIZE_LEN(dsize);
   1515 
   1516  out:
   1517 	KASSERTMSG(arm_dcache_align <= CACHE_LINE_SIZE,
   1518 	    "arm_dcache_align=%u CACHE_LINE_SIZE=%u",
   1519 	    arm_dcache_align, CACHE_LINE_SIZE);
   1520 	arm_dcache_align_mask = arm_dcache_align - 1;
   1521 }
   1522 #endif /* ARM7TDMI || ARM8 || ARM9 || XSCALE */
   1523 
   1524 #if defined(CPU_ARM6) || defined(CPU_ARM7) || defined(CPU_SA110) || \
   1525     defined(CPU_SA1100) || defined(CPU_SA1110) || defined(CPU_IXP12X0)
   1526 /* Cache information for CPUs without cache type registers. */
   1527 struct cachetab {
   1528 	uint32_t ct_cpuid;
   1529 	int	ct_pcache_type;
   1530 	int	ct_pcache_unified;
   1531 	int	ct_pdcache_size;
   1532 	int	ct_pdcache_line_size;
   1533 	int	ct_pdcache_ways;
   1534 	int	ct_picache_size;
   1535 	int	ct_picache_line_size;
   1536 	int	ct_picache_ways;
   1537 };
   1538 
   1539 struct cachetab cachetab[] = {
   1540     /* cpuid,           cache type,       u,  dsiz, ls, wy,  isiz, ls, wy */
   1541     { CPU_ID_ARM2,      0,                1,     0,  0,  0,     0,  0,  0 },
   1542     { CPU_ID_ARM250,    0,                1,     0,  0,  0,     0,  0,  0 },
   1543     { CPU_ID_ARM3,      CPU_CT_CTYPE_WT,  1,  4096, 16, 64,     0,  0,  0 },
   1544     { CPU_ID_ARM610,	CPU_CT_CTYPE_WT,  1,  4096, 16, 64,     0,  0,  0 },
   1545     { CPU_ID_ARM710,    CPU_CT_CTYPE_WT,  1,  8192, 32,  4,     0,  0,  0 },
   1546     { CPU_ID_ARM7500,   CPU_CT_CTYPE_WT,  1,  4096, 16,  4,     0,  0,  0 },
   1547     { CPU_ID_ARM710A,   CPU_CT_CTYPE_WT,  1,  8192, 16,  4,     0,  0,  0 },
   1548     { CPU_ID_ARM7500FE, CPU_CT_CTYPE_WT,  1,  4096, 16,  4,     0,  0,  0 },
   1549     /* XXX is this type right for SA-1? */
   1550     { CPU_ID_SA110,	CPU_CT_CTYPE_WB1, 0, 16384, 32, 32, 16384, 32, 32 },
   1551     { CPU_ID_SA1100,	CPU_CT_CTYPE_WB1, 0,  8192, 32, 32, 16384, 32, 32 },
   1552     { CPU_ID_SA1110,	CPU_CT_CTYPE_WB1, 0,  8192, 32, 32, 16384, 32, 32 },
   1553     { CPU_ID_IXP1200,	CPU_CT_CTYPE_WB1, 0, 16384, 32, 32, 16384, 32, 32 }, /* XXX */
   1554     { 0, 0, 0, 0, 0, 0, 0, 0}
   1555 };
   1556 
   1557 static void get_cachetype_table(void);
   1558 
   1559 static void
   1560 get_cachetype_table(void)
   1561 {
   1562 	int i;
   1563 	uint32_t cpuid = cpu_idnum();
   1564 
   1565 	for (i = 0; cachetab[i].ct_cpuid != 0; i++) {
   1566 		if (cachetab[i].ct_cpuid == (cpuid & CPU_ID_CPU_MASK)) {
   1567 			arm_pcache.cache_type = cachetab[i].ct_pcache_type;
   1568 			arm_pcache.cache_unified = cachetab[i].ct_pcache_unified;
   1569 			arm_pcache.dcache_size = cachetab[i].ct_pdcache_size;
   1570 			arm_pcache.dcache_line_size =
   1571 			    cachetab[i].ct_pdcache_line_size;
   1572 			arm_pcache.dcache_ways = cachetab[i].ct_pdcache_ways;
   1573 			if (arm_pcache.dcache_ways) {
   1574 				arm_pcache.dcache_way_size =
   1575 				    arm_pcache.dcache_line_size
   1576 				    / arm_pcache.dcache_ways;
   1577 			}
   1578 			arm_pcache.icache_size = cachetab[i].ct_picache_size;
   1579 			arm_pcache.icache_line_size =
   1580 			    cachetab[i].ct_picache_line_size;
   1581 			arm_pcache.icache_ways = cachetab[i].ct_picache_ways;
   1582 			if (arm_pcache.icache_ways) {
   1583 				arm_pcache.icache_way_size =
   1584 				    arm_pcache.icache_line_size
   1585 				    / arm_pcache.icache_ways;
   1586 			}
   1587 		}
   1588 	}
   1589 
   1590 	arm_dcache_align = arm_pcache.dcache_line_size;
   1591 	arm_dcache_align_mask = arm_dcache_align - 1;
   1592 }
   1593 
   1594 #endif /* ARM6 || ARM7 || SA110 || SA1100 || SA1111 || IXP12X0 */
   1595 
   1596 
   1597 #if defined(CPU_CORTEX) || defined(CPU_PJ4B)
   1598 static inline void
   1599 set_cpufuncs_mpfixup(void)
   1600 {
   1601 #ifdef MULTIPROCESSOR
   1602 	/* If MP extensions are present, patch in MP TLB ops */
   1603 	const uint32_t mpidr = armreg_mpidr_read();
   1604 	if ((mpidr & (MPIDR_MP|MPIDR_U)) == MPIDR_MP) {
   1605 		cpufuncs.cf_tlb_flushID = armv7mp_tlb_flushID;
   1606 		cpufuncs.cf_tlb_flushID_SE = armv7mp_tlb_flushID_SE;
   1607 		cpufuncs.cf_tlb_flushI = armv7mp_tlb_flushI;
   1608 		cpufuncs.cf_tlb_flushI_SE = armv7mp_tlb_flushI_SE;
   1609 		cpufuncs.cf_tlb_flushD = armv7mp_tlb_flushD;
   1610 		cpufuncs.cf_tlb_flushD_SE = armv7mp_tlb_flushD_SE;
   1611 	}
   1612 #endif
   1613 }
   1614 #endif
   1615 
   1616 /*
   1617  * Cannot panic here as we may not have a console yet ...
   1618  */
   1619 
   1620 int
   1621 set_cpufuncs(void)
   1622 {
   1623 	if (cputype == 0) {
   1624 		cputype = cpufunc_id();
   1625 		cputype &= CPU_ID_CPU_MASK;
   1626 	}
   1627 
   1628 	/*
   1629 	 * NOTE: cpu_do_powersave defaults to off.  If we encounter a
   1630 	 * CPU type where we want to use it by default, then we set it.
   1631 	 */
   1632 #ifdef CPU_ARM6
   1633 	if ((cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_ARM_LTD &&
   1634 	    (cputype & 0x00000f00) == 0x00000600) {
   1635 		cpufuncs = arm6_cpufuncs;
   1636 		get_cachetype_table();
   1637 		pmap_pte_init_generic();
   1638 		return 0;
   1639 	}
   1640 #endif	/* CPU_ARM6 */
   1641 #ifdef CPU_ARM7
   1642 	if ((cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_ARM_LTD &&
   1643 	    CPU_ID_IS7(cputype) &&
   1644 	    (cputype & CPU_ID_7ARCH_MASK) == CPU_ID_7ARCH_V3) {
   1645 		cpufuncs = arm7_cpufuncs;
   1646 		get_cachetype_table();
   1647 		pmap_pte_init_generic();
   1648 		return 0;
   1649 	}
   1650 #endif	/* CPU_ARM7 */
   1651 #ifdef CPU_ARM7TDMI
   1652 	if ((cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_ARM_LTD &&
   1653 	    CPU_ID_IS7(cputype) &&
   1654 	    (cputype & CPU_ID_7ARCH_MASK) == CPU_ID_7ARCH_V4T) {
   1655 		cpufuncs = arm7tdmi_cpufuncs;
   1656 		get_cachetype_cp15();
   1657 		pmap_pte_init_generic();
   1658 		return 0;
   1659 	}
   1660 #endif
   1661 #ifdef CPU_ARM8
   1662 	if ((cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_ARM_LTD &&
   1663 	    (cputype & 0x0000f000) == 0x00008000) {
   1664 		cpufuncs = arm8_cpufuncs;
   1665 		get_cachetype_cp15();
   1666 		pmap_pte_init_arm8();
   1667 		return 0;
   1668 	}
   1669 #endif	/* CPU_ARM8 */
   1670 #ifdef CPU_ARM9
   1671 	if (((cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_ARM_LTD ||
   1672 	     (cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_TI) &&
   1673 	    (cputype & 0x0000f000) == 0x00009000) {
   1674 		cpufuncs = arm9_cpufuncs;
   1675 		get_cachetype_cp15();
   1676 		arm9_dcache_sets_inc = 1U << arm_dcache_log2_linesize;
   1677 		arm9_dcache_sets_max =
   1678 		    (1U << (arm_dcache_log2_linesize + arm_dcache_log2_nsets)) -
   1679 		    arm9_dcache_sets_inc;
   1680 		arm9_dcache_index_inc = 1U << (32 - arm_dcache_log2_assoc);
   1681 		arm9_dcache_index_max = 0U - arm9_dcache_index_inc;
   1682 #ifdef	ARM9_CACHE_WRITE_THROUGH
   1683 		pmap_pte_init_arm9();
   1684 #else
   1685 		pmap_pte_init_generic();
   1686 #endif
   1687 		return 0;
   1688 	}
   1689 #endif /* CPU_ARM9 */
   1690 #if defined(CPU_ARM9E) || defined(CPU_ARM10)
   1691 	if (cputype == CPU_ID_ARM926EJS ||
   1692 	    cputype == CPU_ID_ARM1026EJS) {
   1693 		cpufuncs = armv5_ec_cpufuncs;
   1694 		get_cachetype_cp15();
   1695 		pmap_pte_init_generic();
   1696 		return 0;
   1697 	}
   1698 #endif /* CPU_ARM9E || CPU_ARM10 */
   1699 #if defined(CPU_SHEEVA)
   1700 	if (cputype == CPU_ID_MV88SV131 ||
   1701 	    cputype == CPU_ID_MV88FR571_VD) {
   1702 		cpufuncs = sheeva_cpufuncs;
   1703 		get_cachetype_cp15();
   1704 		pmap_pte_init_generic();
   1705 		cpu_do_powersave = 1;			/* Enable powersave */
   1706 		return 0;
   1707 	}
   1708 #endif /* CPU_SHEEVA */
   1709 #ifdef CPU_ARM10
   1710 	if (/* cputype == CPU_ID_ARM1020T || */
   1711 	    cputype == CPU_ID_ARM1020E) {
   1712 		/*
   1713 		 * Select write-through cacheing (this isn't really an
   1714 		 * option on ARM1020T).
   1715 		 */
   1716 		cpufuncs = arm10_cpufuncs;
   1717 		get_cachetype_cp15();
   1718 		armv5_dcache_sets_inc = 1U << arm_dcache_log2_linesize;
   1719 		armv5_dcache_sets_max =
   1720 		    (1U << (arm_dcache_log2_linesize + arm_dcache_log2_nsets)) -
   1721 		    armv5_dcache_sets_inc;
   1722 		armv5_dcache_index_inc = 1U << (32 - arm_dcache_log2_assoc);
   1723 		armv5_dcache_index_max = 0U - armv5_dcache_index_inc;
   1724 		pmap_pte_init_generic();
   1725 		return 0;
   1726 	}
   1727 #endif /* CPU_ARM10 */
   1728 
   1729 
   1730 #if defined(CPU_ARM11MPCORE)
   1731 	if (cputype == CPU_ID_ARM11MPCORE) {
   1732 		cpufuncs = arm11mpcore_cpufuncs;
   1733 #if defined(CPU_ARMV7) || defined(CPU_PRE_ARMV6)
   1734 		cpu_armv6_p = true;
   1735 #endif
   1736 		get_cachetype_cp15();
   1737 		armv5_dcache_sets_inc = 1U << arm_dcache_log2_linesize;
   1738 		armv5_dcache_sets_max = (1U << (arm_dcache_log2_linesize +
   1739 			arm_dcache_log2_nsets)) - armv5_dcache_sets_inc;
   1740 		armv5_dcache_index_inc = 1U << (32 - arm_dcache_log2_assoc);
   1741 		armv5_dcache_index_max = 0U - armv5_dcache_index_inc;
   1742 		cpu_do_powersave = 1;			/* Enable powersave */
   1743 		pmap_pte_init_arm11mpcore();
   1744 		if (arm_cache_prefer_mask)
   1745 			uvmexp.ncolors = (arm_cache_prefer_mask >> PGSHIFT) + 1;
   1746 
   1747 		return 0;
   1748 
   1749 	}
   1750 #endif	/* CPU_ARM11MPCORE */
   1751 
   1752 #if defined(CPU_ARM11)
   1753 	if (cputype == CPU_ID_ARM1136JS ||
   1754 	    cputype == CPU_ID_ARM1136JSR1 ||
   1755 	    cputype == CPU_ID_ARM1176JZS) {
   1756 		cpufuncs = arm11_cpufuncs;
   1757 #if defined(CPU_ARM1136)
   1758 		if (cputype == CPU_ID_ARM1136JS ||
   1759 		    cputype == CPU_ID_ARM1136JSR1) {
   1760 			cpufuncs = arm1136_cpufuncs;
   1761 			if (cputype == CPU_ID_ARM1136JS)
   1762 				cpufuncs.cf_sleep = arm1136_sleep_rev0;
   1763 		}
   1764 #endif
   1765 #if defined(CPU_ARM1176)
   1766 		if (cputype == CPU_ID_ARM1176JZS) {
   1767 			cpufuncs = arm1176_cpufuncs;
   1768 		}
   1769 #endif
   1770 #if defined(CPU_ARMV7) || defined(CPU_PRE_ARMV6)
   1771 		cpu_armv6_p = true;
   1772 #endif
   1773 		cpu_do_powersave = 1;			/* Enable powersave */
   1774 		get_cachetype_cp15();
   1775 #ifdef ARM11_CACHE_WRITE_THROUGH
   1776 		pmap_pte_init_arm11();
   1777 #else
   1778 		pmap_pte_init_armv6();
   1779 #endif
   1780 		if (arm_cache_prefer_mask)
   1781 			uvmexp.ncolors = (arm_cache_prefer_mask >> PGSHIFT) + 1;
   1782 
   1783 		/*
   1784 		 * Start and reset the PMC Cycle Counter.
   1785 		 */
   1786 		armreg_pmcrv6_write(ARM11_PMCCTL_E | ARM11_PMCCTL_P | ARM11_PMCCTL_C);
   1787 		return 0;
   1788 	}
   1789 #endif /* CPU_ARM11 */
   1790 #ifdef CPU_SA110
   1791 	if (cputype == CPU_ID_SA110) {
   1792 		cpufuncs = sa110_cpufuncs;
   1793 		get_cachetype_table();
   1794 		pmap_pte_init_sa1();
   1795 		return 0;
   1796 	}
   1797 #endif	/* CPU_SA110 */
   1798 #ifdef CPU_SA1100
   1799 	if (cputype == CPU_ID_SA1100) {
   1800 		cpufuncs = sa11x0_cpufuncs;
   1801 		get_cachetype_table();
   1802 		pmap_pte_init_sa1();
   1803 
   1804 		/* Use powersave on this CPU. */
   1805 		cpu_do_powersave = 1;
   1806 
   1807 		return 0;
   1808 	}
   1809 #endif	/* CPU_SA1100 */
   1810 #ifdef CPU_SA1110
   1811 	if (cputype == CPU_ID_SA1110) {
   1812 		cpufuncs = sa11x0_cpufuncs;
   1813 		get_cachetype_table();
   1814 		pmap_pte_init_sa1();
   1815 
   1816 		/* Use powersave on this CPU. */
   1817 		cpu_do_powersave = 1;
   1818 
   1819 		return 0;
   1820 	}
   1821 #endif	/* CPU_SA1110 */
   1822 #ifdef CPU_FA526
   1823 	if (cputype == CPU_ID_FA526) {
   1824 		cpufuncs = fa526_cpufuncs;
   1825 		get_cachetype_cp15();
   1826 		pmap_pte_init_generic();
   1827 
   1828 		/* Use powersave on this CPU. */
   1829 		cpu_do_powersave = 1;
   1830 
   1831 		return 0;
   1832 	}
   1833 #endif	/* CPU_FA526 */
   1834 #ifdef CPU_IXP12X0
   1835 	if (cputype == CPU_ID_IXP1200) {
   1836 		cpufuncs = ixp12x0_cpufuncs;
   1837 		get_cachetype_table();
   1838 		pmap_pte_init_sa1();
   1839 		return 0;
   1840 	}
   1841 #endif  /* CPU_IXP12X0 */
   1842 #ifdef CPU_XSCALE_80200
   1843 	if (cputype == CPU_ID_80200) {
   1844 		int rev = cpufunc_id() & CPU_ID_REVISION_MASK;
   1845 
   1846 		i80200_icu_init();
   1847 
   1848 		/*
   1849 		 * Reset the Performance Monitoring Unit to a
   1850 		 * pristine state:
   1851 		 *	- CCNT, PMN0, PMN1 reset to 0
   1852 		 *	- overflow indications cleared
   1853 		 *	- all counters disabled
   1854 		 */
   1855 		__asm volatile("mcr p14, 0, %0, c0, c0, 0"
   1856 			:
   1857 			: "r" (PMNC_P|PMNC_C|PMNC_PMN0_IF|PMNC_PMN1_IF|
   1858 			       PMNC_CC_IF));
   1859 
   1860 #if defined(XSCALE_CCLKCFG)
   1861 		/*
   1862 		 * Crank CCLKCFG to maximum legal value.
   1863 		 */
   1864 		__asm volatile ("mcr p14, 0, %0, c6, c0, 0"
   1865 			:
   1866 			: "r" (XSCALE_CCLKCFG));
   1867 #endif
   1868 
   1869 		/*
   1870 		 * XXX Disable ECC in the Bus Controller Unit; we
   1871 		 * don't really support it, yet.  Clear any pending
   1872 		 * error indications.
   1873 		 */
   1874 		__asm volatile("mcr p13, 0, %0, c0, c1, 0"
   1875 			:
   1876 			: "r" (BCUCTL_E0|BCUCTL_E1|BCUCTL_EV));
   1877 
   1878 		cpufuncs = xscale_cpufuncs;
   1879 
   1880 		/*
   1881 		 * i80200 errata: Step-A0 and A1 have a bug where
   1882 		 * D$ dirty bits are not cleared on "invalidate by
   1883 		 * address".
   1884 		 *
   1885 		 * Workaround: Clean cache line before invalidating.
   1886 		 */
   1887 		if (rev == 0 || rev == 1)
   1888 			cpufuncs.cf_dcache_inv_range = xscale_cache_purgeD_rng;
   1889 
   1890 		get_cachetype_cp15();
   1891 		pmap_pte_init_xscale();
   1892 		return 0;
   1893 	}
   1894 #endif /* CPU_XSCALE_80200 */
   1895 #ifdef CPU_XSCALE_80321
   1896 	if (cputype == CPU_ID_80321_400 || cputype == CPU_ID_80321_600 ||
   1897 	    cputype == CPU_ID_80321_400_B0 || cputype == CPU_ID_80321_600_B0 ||
   1898 	    cputype == CPU_ID_80219_400 || cputype == CPU_ID_80219_600) {
   1899 		i80321_icu_init();
   1900 
   1901 		/*
   1902 		 * Reset the Performance Monitoring Unit to a
   1903 		 * pristine state:
   1904 		 *	- CCNT, PMN0, PMN1 reset to 0
   1905 		 *	- overflow indications cleared
   1906 		 *	- all counters disabled
   1907 		 */
   1908 		__asm volatile("mcr p14, 0, %0, c0, c0, 0"
   1909 			:
   1910 			: "r" (PMNC_P|PMNC_C|PMNC_PMN0_IF|PMNC_PMN1_IF|
   1911 			       PMNC_CC_IF));
   1912 
   1913 		cpufuncs = xscale_cpufuncs;
   1914 
   1915 		get_cachetype_cp15();
   1916 		pmap_pte_init_xscale();
   1917 		return 0;
   1918 	}
   1919 #endif /* CPU_XSCALE_80321 */
   1920 #ifdef __CPU_XSCALE_PXA2XX
   1921 	/* ignore core revision to test PXA2xx CPUs */
   1922 	if ((cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA27X ||
   1923 	    (cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA250 ||
   1924 	    (cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA210) {
   1925 
   1926 		cpufuncs = xscale_cpufuncs;
   1927 
   1928 		get_cachetype_cp15();
   1929 		pmap_pte_init_xscale();
   1930 
   1931 		/* Use powersave on this CPU. */
   1932 		cpu_do_powersave = 1;
   1933 
   1934 		return 0;
   1935 	}
   1936 #endif /* __CPU_XSCALE_PXA2XX */
   1937 #ifdef CPU_XSCALE_IXP425
   1938 	if (cputype == CPU_ID_IXP425_533 || cputype == CPU_ID_IXP425_400 ||
   1939 	    cputype == CPU_ID_IXP425_266) {
   1940 		ixp425_icu_init();
   1941 
   1942 		cpufuncs = xscale_cpufuncs;
   1943 
   1944 		get_cachetype_cp15();
   1945 		pmap_pte_init_xscale();
   1946 
   1947 		return 0;
   1948 	}
   1949 #endif /* CPU_XSCALE_IXP425 */
   1950 #if defined(CPU_CORTEX)
   1951 	if (CPU_ID_CORTEX_P(cputype)) {
   1952 		cpufuncs = armv7_cpufuncs;
   1953 		set_cpufuncs_mpfixup();
   1954 		cpu_do_powersave = 1;			/* Enable powersave */
   1955 #if defined(CPU_ARMV6) || defined(CPU_PRE_ARMV6)
   1956 		cpu_armv7_p = true;
   1957 #endif
   1958 		get_cachetype_cp15();
   1959 		pmap_pte_init_armv7();
   1960 		if (arm_cache_prefer_mask)
   1961 			uvmexp.ncolors = (arm_cache_prefer_mask >> PGSHIFT) + 1;
   1962 
   1963 		/*
   1964 		 * Start and reset the PMC Cycle Counter.
   1965 		 */
   1966 		armreg_pmcr_write(ARM11_PMCCTL_E | ARM11_PMCCTL_P | ARM11_PMCCTL_C);
   1967 		armreg_pmintenclr_write(PMINTEN_C | PMINTEN_P);
   1968 		armreg_pmcntenset_write(CORTEX_CNTENS_C);
   1969 		return 0;
   1970 	}
   1971 #endif /* CPU_CORTEX */
   1972 
   1973 #if defined(CPU_PJ4B)
   1974 	if ((cputype == CPU_ID_MV88SV581X_V6 ||
   1975 	    cputype == CPU_ID_MV88SV581X_V7 ||
   1976 	    cputype == CPU_ID_MV88SV584X_V7 ||
   1977 	    cputype == CPU_ID_ARM_88SV581X_V6 ||
   1978 	    cputype == CPU_ID_ARM_88SV581X_V7) &&
   1979 	    (armreg_pfr0_read() & ARM_PFR0_THUMBEE_MASK)) {
   1980 		cpufuncs = pj4bv7_cpufuncs;
   1981 		set_cpufuncs_mpfixup();
   1982 #if defined(CPU_ARMV6) || defined(CPU_PRE_ARMV6)
   1983 		cpu_armv7_p = true;
   1984 #endif
   1985 		get_cachetype_cp15();
   1986 		pmap_pte_init_armv7();
   1987 		return 0;
   1988 	}
   1989 #endif /* CPU_PJ4B */
   1990 
   1991 	/*
   1992 	 * Bzzzz. And the answer was ...
   1993 	 */
   1994 	panic("No support for this CPU type (%08x) in kernel", cputype);
   1995 	return ARCHITECTURE_NOT_PRESENT;
   1996 }
   1997 
   1998 /*
   1999  * Fixup routines for data and prefetch aborts.
   2000  *
   2001  * Several compile time symbols are used
   2002  *
   2003  * DEBUG_FAULT_CORRECTION - Print debugging information during the
   2004  * correction of registers after a fault.
   2005  * ARM6_LATE_ABORT - ARM6 supports both early and late aborts
   2006  * when defined should use late aborts
   2007  */
   2008 
   2009 
   2010 /*
   2011  * Null abort fixup routine.
   2012  * For use when no fixup is required.
   2013  */
   2014 int
   2015 cpufunc_null_fixup(void *arg)
   2016 {
   2017 	return(ABORT_FIXUP_OK);
   2018 }
   2019 
   2020 
   2021 #if defined(CPU_ARM6) || defined(CPU_ARM7) || defined(CPU_ARM7TDMI)
   2022 
   2023 #ifdef DEBUG_FAULT_CORRECTION
   2024 #define DFC_PRINTF(x)		printf x
   2025 #define DFC_DISASSEMBLE(x)	disassemble(x)
   2026 #else
   2027 #define DFC_PRINTF(x)		/* nothing */
   2028 #define DFC_DISASSEMBLE(x)	/* nothing */
   2029 #endif
   2030 
   2031 /*
   2032  * "Early" data abort fixup.
   2033  *
   2034  * For ARM2, ARM2as, ARM3 and ARM6 (in early-abort mode).  Also used
   2035  * indirectly by ARM6 (in late-abort mode) and ARM7[TDMI].
   2036  *
   2037  * In early aborts, we may have to fix up LDM, STM, LDC and STC.
   2038  */
   2039 int
   2040 early_abort_fixup(void *arg)
   2041 {
   2042 	trapframe_t *frame = arg;
   2043 	u_int fault_pc;
   2044 	u_int fault_instruction;
   2045 	int saved_lr = 0;
   2046 
   2047 	if ((frame->tf_spsr & PSR_MODE) == PSR_SVC32_MODE) {
   2048 
   2049 		/* Ok an abort in SVC mode */
   2050 
   2051 		/*
   2052 		 * Copy the SVC r14 into the usr r14 - The usr r14 is garbage
   2053 		 * as the fault happened in svc mode but we need it in the
   2054 		 * usr slot so we can treat the registers as an array of ints
   2055 		 * during fixing.
   2056 		 * NOTE: This PC is in the position but writeback is not
   2057 		 * allowed on r15.
   2058 		 * Doing it like this is more efficient than trapping this
   2059 		 * case in all possible locations in the following fixup code.
   2060 		 */
   2061 
   2062 		saved_lr = frame->tf_usr_lr;
   2063 		frame->tf_usr_lr = frame->tf_svc_lr;
   2064 
   2065 		/*
   2066 		 * Note the trapframe does not have the SVC r13 so a fault
   2067 		 * from an instruction with writeback to r13 in SVC mode is
   2068 		 * not allowed. This should not happen as the kstack is
   2069 		 * always valid.
   2070 		 */
   2071 	}
   2072 
   2073 	/* Get fault address and status from the CPU */
   2074 
   2075 	fault_pc = frame->tf_pc;
   2076 	fault_instruction = *((volatile unsigned int *)fault_pc);
   2077 
   2078 	/* Decode the fault instruction and fix the registers as needed */
   2079 
   2080 	if ((fault_instruction & 0x0e000000) == 0x08000000) {
   2081 		int base;
   2082 		int loop;
   2083 		int count;
   2084 		int *registers = &frame->tf_r0;
   2085 
   2086 		DFC_PRINTF(("LDM/STM\n"));
   2087 		DFC_DISASSEMBLE(fault_pc);
   2088 		if (fault_instruction & (1 << 21)) {
   2089 			DFC_PRINTF(("This instruction must be corrected\n"));
   2090 			base = (fault_instruction >> 16) & 0x0f;
   2091 			if (base == 15)
   2092 				return ABORT_FIXUP_FAILED;
   2093 			/* Count registers transferred */
   2094 			count = 0;
   2095 			for (loop = 0; loop < 16; ++loop) {
   2096 				if (fault_instruction & (1<<loop))
   2097 					++count;
   2098 			}
   2099 			DFC_PRINTF(("%d registers used\n", count));
   2100 			DFC_PRINTF(("Corrected r%d by %d bytes ",
   2101 				       base, count * 4));
   2102 			if (fault_instruction & (1 << 23)) {
   2103 				DFC_PRINTF(("down\n"));
   2104 				registers[base] -= count * 4;
   2105 			} else {
   2106 				DFC_PRINTF(("up\n"));
   2107 				registers[base] += count * 4;
   2108 			}
   2109 		}
   2110 	} else if ((fault_instruction & 0x0e000000) == 0x0c000000) {
   2111 		int base;
   2112 		int offset;
   2113 		int *registers = &frame->tf_r0;
   2114 
   2115 		/* REGISTER CORRECTION IS REQUIRED FOR THESE INSTRUCTIONS */
   2116 
   2117 		DFC_DISASSEMBLE(fault_pc);
   2118 
   2119 		/* Only need to fix registers if write back is turned on */
   2120 
   2121 		if ((fault_instruction & (1 << 21)) != 0) {
   2122 			base = (fault_instruction >> 16) & 0x0f;
   2123 			if (base == 13 &&
   2124 			    (frame->tf_spsr & PSR_MODE) == PSR_SVC32_MODE)
   2125 				return ABORT_FIXUP_FAILED;
   2126 			if (base == 15)
   2127 				return ABORT_FIXUP_FAILED;
   2128 
   2129 			offset = (fault_instruction & 0xff) << 2;
   2130 			DFC_PRINTF(("r%d=%08x\n", base, registers[base]));
   2131 			if ((fault_instruction & (1 << 23)) != 0)
   2132 				offset = -offset;
   2133 			registers[base] += offset;
   2134 			DFC_PRINTF(("r%d=%08x\n", base, registers[base]));
   2135 		}
   2136 	}
   2137 
   2138 	if ((frame->tf_spsr & PSR_MODE) == PSR_SVC32_MODE) {
   2139 
   2140 		/* Ok an abort in SVC mode */
   2141 
   2142 		/*
   2143 		 * Copy the SVC r14 into the usr r14 - The usr r14 is garbage
   2144 		 * as the fault happened in svc mode but we need it in the
   2145 		 * usr slot so we can treat the registers as an array of ints
   2146 		 * during fixing.
   2147 		 * NOTE: This PC is in the position but writeback is not
   2148 		 * allowed on r15.
   2149 		 * Doing it like this is more efficient than trapping this
   2150 		 * case in all possible locations in the prior fixup code.
   2151 		 */
   2152 
   2153 		frame->tf_svc_lr = frame->tf_usr_lr;
   2154 		frame->tf_usr_lr = saved_lr;
   2155 
   2156 		/*
   2157 		 * Note the trapframe does not have the SVC r13 so a fault
   2158 		 * from an instruction with writeback to r13 in SVC mode is
   2159 		 * not allowed. This should not happen as the kstack is
   2160 		 * always valid.
   2161 		 */
   2162 	}
   2163 
   2164 	return(ABORT_FIXUP_OK);
   2165 }
   2166 #endif	/* CPU_ARM6/7 */
   2167 
   2168 
   2169 #if (defined(CPU_ARM6) && defined(ARM6_LATE_ABORT)) || defined(CPU_ARM7) || \
   2170 	defined(CPU_ARM7TDMI)
   2171 /*
   2172  * "Late" (base updated) data abort fixup
   2173  *
   2174  * For ARM6 (in late-abort mode) and ARM7.
   2175  *
   2176  * In this model, all data-transfer instructions need fixing up.  We defer
   2177  * LDM, STM, LDC and STC fixup to the early-abort handler.
   2178  */
   2179 int
   2180 late_abort_fixup(void *arg)
   2181 {
   2182 	trapframe_t *frame = arg;
   2183 	u_int fault_pc;
   2184 	u_int fault_instruction;
   2185 	int saved_lr = 0;
   2186 
   2187 	if ((frame->tf_spsr & PSR_MODE) == PSR_SVC32_MODE) {
   2188 
   2189 		/* Ok an abort in SVC mode */
   2190 
   2191 		/*
   2192 		 * Copy the SVC r14 into the usr r14 - The usr r14 is garbage
   2193 		 * as the fault happened in svc mode but we need it in the
   2194 		 * usr slot so we can treat the registers as an array of ints
   2195 		 * during fixing.
   2196 		 * NOTE: This PC is in the position but writeback is not
   2197 		 * allowed on r15.
   2198 		 * Doing it like this is more efficient than trapping this
   2199 		 * case in all possible locations in the following fixup code.
   2200 		 */
   2201 
   2202 		saved_lr = frame->tf_usr_lr;
   2203 		frame->tf_usr_lr = frame->tf_svc_lr;
   2204 
   2205 		/*
   2206 		 * Note the trapframe does not have the SVC r13 so a fault
   2207 		 * from an instruction with writeback to r13 in SVC mode is
   2208 		 * not allowed. This should not happen as the kstack is
   2209 		 * always valid.
   2210 		 */
   2211 	}
   2212 
   2213 	/* Get fault address and status from the CPU */
   2214 
   2215 	fault_pc = frame->tf_pc;
   2216 	fault_instruction = *((volatile unsigned int *)fault_pc);
   2217 
   2218 	/* Decode the fault instruction and fix the registers as needed */
   2219 
   2220 	/* Was is a swap instruction ? */
   2221 
   2222 	if ((fault_instruction & 0x0fb00ff0) == 0x01000090) {
   2223 		DFC_DISASSEMBLE(fault_pc);
   2224 	} else if ((fault_instruction & 0x0c000000) == 0x04000000) {
   2225 
   2226 		/* Was is a ldr/str instruction */
   2227 		/* This is for late abort only */
   2228 
   2229 		int base;
   2230 		int offset;
   2231 		int *registers = &frame->tf_r0;
   2232 
   2233 		DFC_DISASSEMBLE(fault_pc);
   2234 
   2235 		/* This is for late abort only */
   2236 
   2237 		if ((fault_instruction & (1 << 24)) == 0
   2238 		    || (fault_instruction & (1 << 21)) != 0) {
   2239 			/* postindexed ldr/str with no writeback */
   2240 
   2241 			base = (fault_instruction >> 16) & 0x0f;
   2242 			if (base == 13 &&
   2243 			    (frame->tf_spsr & PSR_MODE) == PSR_SVC32_MODE)
   2244 				return ABORT_FIXUP_FAILED;
   2245 			if (base == 15)
   2246 				return ABORT_FIXUP_FAILED;
   2247 			DFC_PRINTF(("late abt fix: r%d=%08x : ",
   2248 				       base, registers[base]));
   2249 			if ((fault_instruction & (1 << 25)) == 0) {
   2250 				/* Immediate offset - easy */
   2251 
   2252 				offset = fault_instruction & 0xfff;
   2253 				if ((fault_instruction & (1 << 23)))
   2254 					offset = -offset;
   2255 				registers[base] += offset;
   2256 				DFC_PRINTF(("imm=%08x ", offset));
   2257 			} else {
   2258 				/* offset is a shifted register */
   2259 				int shift;
   2260 
   2261 				offset = fault_instruction & 0x0f;
   2262 				if (offset == base)
   2263 					return ABORT_FIXUP_FAILED;
   2264 
   2265 				/*
   2266 				 * Register offset - hard we have to
   2267 				 * cope with shifts !
   2268 				 */
   2269 				offset = registers[offset];
   2270 
   2271 				if ((fault_instruction & (1 << 4)) == 0)
   2272 					/* shift with amount */
   2273 					shift = (fault_instruction >> 7) & 0x1f;
   2274 				else {
   2275 					/* shift with register */
   2276 					if ((fault_instruction & (1 << 7)) != 0)
   2277 						/* undefined for now so bail out */
   2278 						return ABORT_FIXUP_FAILED;
   2279 					shift = ((fault_instruction >> 8) & 0xf);
   2280 					if (base == shift)
   2281 						return ABORT_FIXUP_FAILED;
   2282 					DFC_PRINTF(("shift reg=%d ", shift));
   2283 					shift = registers[shift];
   2284 				}
   2285 				DFC_PRINTF(("shift=%08x ", shift));
   2286 				switch (((fault_instruction >> 5) & 0x3)) {
   2287 				case 0 : /* Logical left */
   2288 					offset = (int)(((u_int)offset) << shift);
   2289 					break;
   2290 				case 1 : /* Logical Right */
   2291 					if (shift == 0) shift = 32;
   2292 					offset = (int)(((u_int)offset) >> shift);
   2293 					break;
   2294 				case 2 : /* Arithmetic Right */
   2295 					if (shift == 0) shift = 32;
   2296 					offset = (int)(((int)offset) >> shift);
   2297 					break;
   2298 				case 3 : /* Rotate right (rol or rxx) */
   2299 					return ABORT_FIXUP_FAILED;
   2300 					break;
   2301 				}
   2302 
   2303 				DFC_PRINTF(("abt: fixed LDR/STR with "
   2304 					       "register offset\n"));
   2305 				if ((fault_instruction & (1 << 23)))
   2306 					offset = -offset;
   2307 				DFC_PRINTF(("offset=%08x ", offset));
   2308 				registers[base] += offset;
   2309 			}
   2310 			DFC_PRINTF(("r%d=%08x\n", base, registers[base]));
   2311 		}
   2312 	}
   2313 
   2314 	if ((frame->tf_spsr & PSR_MODE) == PSR_SVC32_MODE) {
   2315 
   2316 		/* Ok an abort in SVC mode */
   2317 
   2318 		/*
   2319 		 * Copy the SVC r14 into the usr r14 - The usr r14 is garbage
   2320 		 * as the fault happened in svc mode but we need it in the
   2321 		 * usr slot so we can treat the registers as an array of ints
   2322 		 * during fixing.
   2323 		 * NOTE: This PC is in the position but writeback is not
   2324 		 * allowed on r15.
   2325 		 * Doing it like this is more efficient than trapping this
   2326 		 * case in all possible locations in the prior fixup code.
   2327 		 */
   2328 
   2329 		frame->tf_svc_lr = frame->tf_usr_lr;
   2330 		frame->tf_usr_lr = saved_lr;
   2331 
   2332 		/*
   2333 		 * Note the trapframe does not have the SVC r13 so a fault
   2334 		 * from an instruction with writeback to r13 in SVC mode is
   2335 		 * not allowed. This should not happen as the kstack is
   2336 		 * always valid.
   2337 		 */
   2338 	}
   2339 
   2340 	/*
   2341 	 * Now let the early-abort fixup routine have a go, in case it
   2342 	 * was an LDM, STM, LDC or STC that faulted.
   2343 	 */
   2344 
   2345 	return early_abort_fixup(arg);
   2346 }
   2347 #endif	/* CPU_ARM6(LATE)/7/7TDMI */
   2348 
   2349 /*
   2350  * CPU Setup code
   2351  */
   2352 
   2353 #if defined(CPU_ARM6) || defined(CPU_ARM7) || defined(CPU_ARM7TDMI) || \
   2354 	defined(CPU_ARM8) || defined (CPU_ARM9) || defined (CPU_ARM9E) || \
   2355 	defined(CPU_SA110) || defined(CPU_SA1100) || defined(CPU_SA1110) || \
   2356 	defined(CPU_FA526) || \
   2357 	defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \
   2358 	defined(__CPU_XSCALE_PXA2XX) || defined(CPU_XSCALE_IXP425) || \
   2359 	defined(CPU_ARM10) || defined(CPU_SHEEVA) || \
   2360 	defined(CPU_ARMV6) || defined(CPU_ARMV7)
   2361 
   2362 #define IGN	0
   2363 #define OR	1
   2364 #define BIC	2
   2365 
   2366 struct cpu_option {
   2367 	const char *co_name;
   2368 	int	co_falseop;
   2369 	int	co_trueop;
   2370 	int	co_value;
   2371 };
   2372 
   2373 static u_int parse_cpu_options(char *, struct cpu_option *, u_int);
   2374 
   2375 static u_int __noasan
   2376 parse_cpu_options(char *args, struct cpu_option *optlist, u_int cpuctrl)
   2377 {
   2378 	int integer;
   2379 
   2380 	if (args == NULL)
   2381 		return(cpuctrl);
   2382 
   2383 	while (optlist->co_name) {
   2384 		if (get_bootconf_option(args, optlist->co_name,
   2385 		    BOOTOPT_TYPE_BOOLEAN, &integer)) {
   2386 			if (integer) {
   2387 				if (optlist->co_trueop == OR)
   2388 					cpuctrl |= optlist->co_value;
   2389 				else if (optlist->co_trueop == BIC)
   2390 					cpuctrl &= ~optlist->co_value;
   2391 			} else {
   2392 				if (optlist->co_falseop == OR)
   2393 					cpuctrl |= optlist->co_value;
   2394 				else if (optlist->co_falseop == BIC)
   2395 					cpuctrl &= ~optlist->co_value;
   2396 			}
   2397 		}
   2398 		++optlist;
   2399 	}
   2400 	return(cpuctrl);
   2401 }
   2402 #endif /* CPU_ARM6 || CPU_ARM7 || CPU_ARM7TDMI || CPU_ARM8 || CPU_SA110 */
   2403 
   2404 #if defined (CPU_ARM6) || defined(CPU_ARM7) || defined(CPU_ARM7TDMI) \
   2405 	|| defined(CPU_ARM8)
   2406 struct cpu_option arm678_options[] = {
   2407 #ifdef COMPAT_12
   2408 	{ "nocache",		IGN, BIC, CPU_CONTROL_IDC_ENABLE },
   2409 	{ "nowritebuf",		IGN, BIC, CPU_CONTROL_WBUF_ENABLE },
   2410 #endif	/* COMPAT_12 */
   2411 	{ "cpu.cache",		BIC, OR,  CPU_CONTROL_IDC_ENABLE },
   2412 	{ "cpu.nocache",	OR,  BIC, CPU_CONTROL_IDC_ENABLE },
   2413 	{ "cpu.writebuf",	BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
   2414 	{ "cpu.nowritebuf",	OR,  BIC, CPU_CONTROL_WBUF_ENABLE },
   2415 	{ NULL,			IGN, IGN, 0 }
   2416 };
   2417 
   2418 #endif	/* CPU_ARM6 || CPU_ARM7 || CPU_ARM7TDMI || CPU_ARM8 */
   2419 
   2420 #ifdef CPU_ARM6
   2421 struct cpu_option arm6_options[] = {
   2422 	{ "arm6.cache",		BIC, OR,  CPU_CONTROL_IDC_ENABLE },
   2423 	{ "arm6.nocache",	OR,  BIC, CPU_CONTROL_IDC_ENABLE },
   2424 	{ "arm6.writebuf",	BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
   2425 	{ "arm6.nowritebuf",	OR,  BIC, CPU_CONTROL_WBUF_ENABLE },
   2426 	{ NULL,			IGN, IGN, 0 }
   2427 };
   2428 
   2429 void
   2430 arm6_setup(char *args)
   2431 {
   2432 
   2433 	/* Set up default control registers bits */
   2434 	int cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
   2435 		 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
   2436 		 | CPU_CONTROL_IDC_ENABLE | CPU_CONTROL_WBUF_ENABLE;
   2437 #if 0
   2438 	int cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
   2439 		 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
   2440 		 | CPU_CONTROL_IDC_ENABLE | CPU_CONTROL_WBUF_ENABLE
   2441 		 | CPU_CONTROL_ROM_ENABLE | CPU_CONTROL_BEND_ENABLE
   2442 		 | CPU_CONTROL_AFLT_ENABLE;
   2443 #endif
   2444 
   2445 #ifdef ARM6_LATE_ABORT
   2446 	cpuctrl |= CPU_CONTROL_LABT_ENABLE;
   2447 #endif	/* ARM6_LATE_ABORT */
   2448 
   2449 #ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
   2450 	cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
   2451 #endif
   2452 
   2453 	cpuctrl = parse_cpu_options(args, arm678_options, cpuctrl);
   2454 	cpuctrl = parse_cpu_options(args, arm6_options, cpuctrl);
   2455 
   2456 #ifdef __ARMEB__
   2457 	cpuctrl |= CPU_CONTROL_BEND_ENABLE;
   2458 #endif
   2459 
   2460 	/* Clear out the cache */
   2461 	cpu_idcache_wbinv_all();
   2462 
   2463 	/* Set the control register */
   2464 	cpu_control(0xffffffff, cpuctrl);
   2465 }
   2466 #endif	/* CPU_ARM6 */
   2467 
   2468 #ifdef CPU_ARM7
   2469 struct cpu_option arm7_options[] = {
   2470 	{ "arm7.cache",		BIC, OR,  CPU_CONTROL_IDC_ENABLE },
   2471 	{ "arm7.nocache",	OR,  BIC, CPU_CONTROL_IDC_ENABLE },
   2472 	{ "arm7.writebuf",	BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
   2473 	{ "arm7.nowritebuf",	OR,  BIC, CPU_CONTROL_WBUF_ENABLE },
   2474 #ifdef COMPAT_12
   2475 	{ "fpaclk2",		BIC, OR,  CPU_CONTROL_CPCLK },
   2476 #endif	/* COMPAT_12 */
   2477 	{ "arm700.fpaclk",	BIC, OR,  CPU_CONTROL_CPCLK },
   2478 	{ NULL,			IGN, IGN, 0 }
   2479 };
   2480 
   2481 void
   2482 arm7_setup(char *args)
   2483 {
   2484 
   2485 	int cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
   2486 		 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
   2487 		 | CPU_CONTROL_IDC_ENABLE | CPU_CONTROL_WBUF_ENABLE;
   2488 #if 0
   2489 	int cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
   2490 		 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
   2491 		 | CPU_CONTROL_IDC_ENABLE | CPU_CONTROL_WBUF_ENABLE
   2492 		 | CPU_CONTROL_CPCLK | CPU_CONTROL_LABT_ENABLE
   2493 		 | CPU_CONTROL_ROM_ENABLE | CPU_CONTROL_BEND_ENABLE
   2494 		 | CPU_CONTROL_AFLT_ENABLE;
   2495 #endif
   2496 
   2497 #ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
   2498 	cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
   2499 #endif
   2500 
   2501 	cpuctrl = parse_cpu_options(args, arm678_options, cpuctrl);
   2502 	cpuctrl = parse_cpu_options(args, arm7_options, cpuctrl);
   2503 
   2504 #ifdef __ARMEB__
   2505 	cpuctrl |= CPU_CONTROL_BEND_ENABLE;
   2506 #endif
   2507 
   2508 	/* Clear out the cache */
   2509 	cpu_idcache_wbinv_all();
   2510 
   2511 	/* Set the control register */
   2512 	cpu_control(0xffffffff, cpuctrl);
   2513 }
   2514 #endif	/* CPU_ARM7 */
   2515 
   2516 #ifdef CPU_ARM7TDMI
   2517 struct cpu_option arm7tdmi_options[] = {
   2518 	{ "arm7.cache",		BIC, OR,  CPU_CONTROL_IDC_ENABLE },
   2519 	{ "arm7.nocache",	OR,  BIC, CPU_CONTROL_IDC_ENABLE },
   2520 	{ "arm7.writebuf",	BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
   2521 	{ "arm7.nowritebuf",	OR,  BIC, CPU_CONTROL_WBUF_ENABLE },
   2522 #ifdef COMPAT_12
   2523 	{ "fpaclk2",		BIC, OR,  CPU_CONTROL_CPCLK },
   2524 #endif	/* COMPAT_12 */
   2525 	{ "arm700.fpaclk",	BIC, OR,  CPU_CONTROL_CPCLK },
   2526 	{ NULL,			IGN, IGN, 0 }
   2527 };
   2528 
   2529 void
   2530 arm7tdmi_setup(char *args)
   2531 {
   2532 	int cpuctrl;
   2533 
   2534 	cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
   2535 		 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
   2536 		 | CPU_CONTROL_IDC_ENABLE | CPU_CONTROL_WBUF_ENABLE;
   2537 
   2538 	cpuctrl = parse_cpu_options(args, arm678_options, cpuctrl);
   2539 	cpuctrl = parse_cpu_options(args, arm7tdmi_options, cpuctrl);
   2540 
   2541 #ifdef __ARMEB__
   2542 	cpuctrl |= CPU_CONTROL_BEND_ENABLE;
   2543 #endif
   2544 
   2545 	/* Clear out the cache */
   2546 	cpu_idcache_wbinv_all();
   2547 
   2548 	/* Set the control register */
   2549 	cpu_control(0xffffffff, cpuctrl);
   2550 }
   2551 #endif	/* CPU_ARM7TDMI */
   2552 
   2553 #ifdef CPU_ARM8
   2554 struct cpu_option arm8_options[] = {
   2555 	{ "arm8.cache",		BIC, OR,  CPU_CONTROL_IDC_ENABLE },
   2556 	{ "arm8.nocache",	OR,  BIC, CPU_CONTROL_IDC_ENABLE },
   2557 	{ "arm8.writebuf",	BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
   2558 	{ "arm8.nowritebuf",	OR,  BIC, CPU_CONTROL_WBUF_ENABLE },
   2559 #ifdef COMPAT_12
   2560 	{ "branchpredict", 	BIC, OR,  CPU_CONTROL_BPRD_ENABLE },
   2561 #endif	/* COMPAT_12 */
   2562 	{ "cpu.branchpredict", 	BIC, OR,  CPU_CONTROL_BPRD_ENABLE },
   2563 	{ "arm8.branchpredict",	BIC, OR,  CPU_CONTROL_BPRD_ENABLE },
   2564 	{ NULL,			IGN, IGN, 0 }
   2565 };
   2566 
   2567 void
   2568 arm8_setup(char *args)
   2569 {
   2570 	int integer;
   2571 	int clocktest;
   2572 	int setclock = 0;
   2573 
   2574 	int cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
   2575 		 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
   2576 		 | CPU_CONTROL_IDC_ENABLE | CPU_CONTROL_WBUF_ENABLE;
   2577 #if 0
   2578 	int cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
   2579 		 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
   2580 		 | CPU_CONTROL_IDC_ENABLE | CPU_CONTROL_WBUF_ENABLE
   2581 		 | CPU_CONTROL_BPRD_ENABLE | CPU_CONTROL_ROM_ENABLE
   2582 		 | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE;
   2583 #endif
   2584 
   2585 #ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
   2586 	cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
   2587 #endif
   2588 
   2589 	cpuctrl = parse_cpu_options(args, arm678_options, cpuctrl);
   2590 	cpuctrl = parse_cpu_options(args, arm8_options, cpuctrl);
   2591 
   2592 #ifdef __ARMEB__
   2593 	cpuctrl |= CPU_CONTROL_BEND_ENABLE;
   2594 #endif
   2595 
   2596 	/* Get clock configuration */
   2597 	clocktest = arm8_clock_config(0, 0) & 0x0f;
   2598 
   2599 	/* Special ARM8 clock and test configuration */
   2600 	if (get_bootconf_option(args, "arm8.clock.reset", BOOTOPT_TYPE_BOOLEAN, &integer)) {
   2601 		clocktest = 0;
   2602 		setclock = 1;
   2603 	}
   2604 	if (get_bootconf_option(args, "arm8.clock.dynamic", BOOTOPT_TYPE_BOOLEAN, &integer)) {
   2605 		if (integer)
   2606 			clocktest |= 0x01;
   2607 		else
   2608 			clocktest &= ~(0x01);
   2609 		setclock = 1;
   2610 	}
   2611 	if (get_bootconf_option(args, "arm8.clock.sync", BOOTOPT_TYPE_BOOLEAN, &integer)) {
   2612 		if (integer)
   2613 			clocktest |= 0x02;
   2614 		else
   2615 			clocktest &= ~(0x02);
   2616 		setclock = 1;
   2617 	}
   2618 	if (get_bootconf_option(args, "arm8.clock.fast", BOOTOPT_TYPE_BININT, &integer)) {
   2619 		clocktest = (clocktest & ~0xc0) | (integer & 3) << 2;
   2620 		setclock = 1;
   2621 	}
   2622 	if (get_bootconf_option(args, "arm8.test", BOOTOPT_TYPE_BININT, &integer)) {
   2623 		clocktest |= (integer & 7) << 5;
   2624 		setclock = 1;
   2625 	}
   2626 
   2627 	/* Clear out the cache */
   2628 	cpu_idcache_wbinv_all();
   2629 
   2630 	/* Set the control register */
   2631 	cpu_control(0xffffffff, cpuctrl);
   2632 
   2633 	/* Set the clock/test register */
   2634 	if (setclock)
   2635 		arm8_clock_config(0x7f, clocktest);
   2636 }
   2637 #endif	/* CPU_ARM8 */
   2638 
   2639 #ifdef CPU_ARM9
   2640 struct cpu_option arm9_options[] = {
   2641 	{ "cpu.cache",		BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
   2642 	{ "cpu.nocache",	OR,  BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
   2643 	{ "arm9.cache",	BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
   2644 	{ "arm9.icache",	BIC, OR,  CPU_CONTROL_IC_ENABLE },
   2645 	{ "arm9.dcache",	BIC, OR,  CPU_CONTROL_DC_ENABLE },
   2646 	{ "cpu.writebuf",	BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
   2647 	{ "cpu.nowritebuf",	OR,  BIC, CPU_CONTROL_WBUF_ENABLE },
   2648 	{ "arm9.writebuf",	BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
   2649 	{ NULL,			IGN, IGN, 0 }
   2650 };
   2651 
   2652 void
   2653 arm9_setup(char *args)
   2654 {
   2655 
   2656 	int cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
   2657 	    | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
   2658 	    | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
   2659 	    | CPU_CONTROL_WBUF_ENABLE;
   2660 	int cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
   2661 		 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
   2662 		 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
   2663 		 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE
   2664 		 | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE
   2665 		 | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_VECRELOC
   2666 		 | CPU_CONTROL_ROUNDROBIN;
   2667 
   2668 #ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
   2669 	cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
   2670 #endif
   2671 
   2672 	cpuctrl = parse_cpu_options(args, arm9_options, cpuctrl);
   2673 
   2674 #ifdef __ARMEB__
   2675 	cpuctrl |= CPU_CONTROL_BEND_ENABLE;
   2676 #endif
   2677 
   2678 #ifndef ARM_HAS_VBAR
   2679 	if (vector_page == ARM_VECTORS_HIGH)
   2680 		cpuctrl |= CPU_CONTROL_VECRELOC;
   2681 #endif
   2682 
   2683 	/* Clear out the cache */
   2684 	cpu_idcache_wbinv_all();
   2685 
   2686 	/* Set the control register */
   2687 	cpu_control(cpuctrlmask, cpuctrl);
   2688 
   2689 }
   2690 #endif	/* CPU_ARM9 */
   2691 
   2692 #if defined(CPU_ARM9E) || defined(CPU_ARM10)
   2693 struct cpu_option arm10_options[] = {
   2694 	{ "cpu.cache",		BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
   2695 	{ "cpu.nocache",	OR,  BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
   2696 	{ "arm10.cache",	BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
   2697 	{ "arm10.icache",	BIC, OR,  CPU_CONTROL_IC_ENABLE },
   2698 	{ "arm10.dcache",	BIC, OR,  CPU_CONTROL_DC_ENABLE },
   2699 	{ "cpu.writebuf",	BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
   2700 	{ "cpu.nowritebuf",	OR,  BIC, CPU_CONTROL_WBUF_ENABLE },
   2701 	{ "arm10.writebuf",	BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
   2702 	{ NULL,			IGN, IGN, 0 }
   2703 };
   2704 
   2705 void
   2706 arm10_setup(char *args)
   2707 {
   2708 
   2709 	int cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_SYST_ENABLE
   2710 	    | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
   2711 	    | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_BPRD_ENABLE;
   2712 #if 0
   2713 	int cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_SYST_ENABLE
   2714 	    | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
   2715 	    | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE
   2716 	    | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE
   2717 	    | CPU_CONTROL_BPRD_ENABLE | CPU_CONTROL_VECRELOC
   2718 	    | CPU_CONTROL_ROUNDROBIN | CPU_CONTROL_CPCLK;
   2719 #endif
   2720 
   2721 #ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
   2722 	cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
   2723 #endif
   2724 
   2725 	cpuctrl = parse_cpu_options(args, arm10_options, cpuctrl);
   2726 
   2727 #ifdef __ARMEB__
   2728 	cpuctrl |= CPU_CONTROL_BEND_ENABLE;
   2729 #endif
   2730 
   2731 #ifndef ARM_HAS_VBAR
   2732 	if (vector_page == ARM_VECTORS_HIGH)
   2733 		cpuctrl |= CPU_CONTROL_VECRELOC;
   2734 #endif
   2735 
   2736 	/* Clear out the cache */
   2737 	cpu_idcache_wbinv_all();
   2738 
   2739 	/* Now really make sure they are clean.  */
   2740 	__asm volatile ("mcr\tp15, 0, r0, c7, c7, 0" : : );
   2741 
   2742 	/* Set the control register */
   2743 	cpu_control(0xffffffff, cpuctrl);
   2744 
   2745 	/* And again. */
   2746 	cpu_idcache_wbinv_all();
   2747 }
   2748 #endif	/* CPU_ARM9E || CPU_ARM10 */
   2749 
   2750 #if defined(CPU_ARM11)
   2751 struct cpu_option arm11_options[] = {
   2752 	{ "cpu.cache",		BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
   2753 	{ "cpu.nocache",	OR,  BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
   2754 	{ "arm11.cache",	BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
   2755 	{ "arm11.icache",	BIC, OR,  CPU_CONTROL_IC_ENABLE },
   2756 	{ "arm11.dcache",	BIC, OR,  CPU_CONTROL_DC_ENABLE },
   2757 	{ "cpu.branchpredict", 	BIC, OR,  CPU_CONTROL_BPRD_ENABLE },
   2758 	{ "arm11.branchpredict", BIC, OR,  CPU_CONTROL_BPRD_ENABLE },
   2759 	{ NULL,			IGN, IGN, 0 }
   2760 };
   2761 
   2762 void
   2763 arm11_setup(char *args)
   2764 {
   2765 
   2766 	int cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_SYST_ENABLE
   2767 #ifdef ARM_MMU_EXTENDED
   2768 	    | CPU_CONTROL_XP_ENABLE
   2769 #endif
   2770 	    | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
   2771 	    /* | CPU_CONTROL_BPRD_ENABLE */;
   2772 
   2773 #ifdef __ARMEB__
   2774 	cpuctrl |= CPU_CONTROL_EX_BEND;
   2775 #endif
   2776 
   2777 	int cpuctrlmask = cpuctrl
   2778 	    | CPU_CONTROL_ROM_ENABLE | CPU_CONTROL_BPRD_ENABLE
   2779 	    | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE
   2780 	    | CPU_CONTROL_ROUNDROBIN | CPU_CONTROL_CPCLK
   2781 	    | CPU_CONTROL_VECRELOC;
   2782 
   2783 #ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
   2784 	cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
   2785 #endif
   2786 
   2787 	cpuctrl = parse_cpu_options(args, arm11_options, cpuctrl);
   2788 
   2789 #ifndef ARM_HAS_VBAR
   2790 	if (vector_page == ARM_VECTORS_HIGH)
   2791 		cpuctrl |= CPU_CONTROL_VECRELOC;
   2792 #endif
   2793 
   2794 	/* Clear out the cache */
   2795 	cpu_idcache_wbinv_all();
   2796 
   2797 	/* Now really make sure they are clean.  */
   2798 	__asm volatile ("mcr\tp15, 0, r0, c7, c7, 0" : : );
   2799 
   2800 	/* Allow detection code to find the VFP if it's fitted.  */
   2801 	armreg_cpacr_write(0x0fffffff);
   2802 
   2803 	/* Set the control register */
   2804 	cpu_control(cpuctrlmask, cpuctrl);
   2805 
   2806 	/* And again. */
   2807 	cpu_idcache_wbinv_all();
   2808 }
   2809 #endif	/* CPU_ARM11 */
   2810 
   2811 #if defined(CPU_ARM11MPCORE)
   2812 
   2813 void
   2814 arm11mpcore_setup(char *args)
   2815 {
   2816 
   2817 	int cpuctrl = CPU_CONTROL_IC_ENABLE
   2818 	    | CPU_CONTROL_DC_ENABLE
   2819 #ifdef ARM_MMU_EXTENDED
   2820 	    | CPU_CONTROL_XP_ENABLE
   2821 #endif
   2822 	    | CPU_CONTROL_BPRD_ENABLE ;
   2823 
   2824 #ifdef __ARMEB__
   2825 	cpuctrl |= CPU_CONTROL_EX_BEND;
   2826 #endif
   2827 
   2828 	int cpuctrlmask = cpuctrl
   2829 	    | CPU_CONTROL_AFLT_ENABLE
   2830 	    | CPU_CONTROL_VECRELOC;
   2831 
   2832 #ifdef	ARM11MPCORE_MMU_COMPAT
   2833 	/* XXX: S and R? */
   2834 #endif
   2835 
   2836 #ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
   2837 	cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
   2838 #endif
   2839 
   2840 	cpuctrl = parse_cpu_options(args, arm11_options, cpuctrl);
   2841 
   2842 #ifndef ARM_HAS_VBAR
   2843 	if (vector_page == ARM_VECTORS_HIGH)
   2844 		cpuctrl |= CPU_CONTROL_VECRELOC;
   2845 #endif
   2846 
   2847 	/* Clear out the cache */
   2848 	cpu_idcache_wbinv_all();
   2849 
   2850 	/* Now really make sure they are clean.  */
   2851 	__asm volatile ("mcr\tp15, 0, r0, c7, c7, 0" : : );
   2852 
   2853 	/* Allow detection code to find the VFP if it's fitted.  */
   2854 	armreg_cpacr_write(0x0fffffff);
   2855 
   2856 	/* Set the control register */
   2857 	cpu_control(cpuctrlmask, cpuctrl);
   2858 
   2859 	/* And again. */
   2860 	cpu_idcache_wbinv_all();
   2861 }
   2862 #endif	/* CPU_ARM11MPCORE */
   2863 
   2864 #ifdef CPU_PJ4B
   2865 void
   2866 pj4bv7_setup(char *args)
   2867 {
   2868 	int cpuctrl;
   2869 
   2870 	pj4b_config();
   2871 
   2872 	cpuctrl = CPU_CONTROL_MMU_ENABLE;
   2873 #ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
   2874 	cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
   2875 #else
   2876 	cpuctrl |= CPU_CONTROL_UNAL_ENABLE;
   2877 #endif
   2878 	cpuctrl |= CPU_CONTROL_DC_ENABLE;
   2879 	cpuctrl |= CPU_CONTROL_IC_ENABLE;
   2880 	cpuctrl |= (0xf << 3);
   2881 	cpuctrl |= CPU_CONTROL_BPRD_ENABLE;
   2882 	cpuctrl |= (0x5 << 16);
   2883 	cpuctrl |= CPU_CONTROL_XP_ENABLE;
   2884 
   2885 #ifndef ARM_HAS_VBAR
   2886 	if (vector_page == ARM_VECTORS_HIGH)
   2887 		cpuctrl |= CPU_CONTROL_VECRELOC;
   2888 #endif
   2889 
   2890 #ifdef L2CACHE_ENABLE
   2891 	/* Setup L2 cache */
   2892 	arm_scache.cache_type = CPU_CT_CTYPE_WT;
   2893 	arm_scache.cache_unified = 1;
   2894 	arm_scache.dcache_type = arm_scache.icache_type = CACHE_TYPE_PIPT;
   2895 	arm_scache.dcache_size = arm_scache.icache_size = ARMADAXP_L2_SIZE;
   2896 	arm_scache.dcache_ways = arm_scache.icache_ways = ARMADAXP_L2_WAYS;
   2897 	arm_scache.dcache_way_size = arm_scache.icache_way_size =
   2898 	    ARMADAXP_L2_WAY_SIZE;
   2899 	arm_scache.dcache_line_size = arm_scache.icache_line_size =
   2900 	    ARMADAXP_L2_LINE_SIZE;
   2901 	arm_scache.dcache_sets = arm_scache.icache_sets =
   2902 	    ARMADAXP_L2_SETS;
   2903 
   2904 	cpufuncs.cf_sdcache_wbinv_range	= armadaxp_sdcache_wbinv_range;
   2905 	cpufuncs.cf_sdcache_inv_range	= armadaxp_sdcache_inv_range;
   2906 	cpufuncs.cf_sdcache_wb_range	= armadaxp_sdcache_wb_range;
   2907 #endif
   2908 
   2909 #ifdef AURORA_IO_CACHE_COHERENCY
   2910 	/* use AMBA and I/O Coherency Fabric to maintain cache */
   2911 	cpufuncs.cf_dcache_wbinv_range	= pj4b_dcache_cfu_wbinv_range;
   2912 	cpufuncs.cf_dcache_inv_range	= pj4b_dcache_cfu_inv_range;
   2913 	cpufuncs.cf_dcache_wb_range	= pj4b_dcache_cfu_wb_range;
   2914 
   2915 	cpufuncs.cf_sdcache_wbinv_range	= (void *)cpufunc_nullop;
   2916 	cpufuncs.cf_sdcache_inv_range	= (void *)cpufunc_nullop;
   2917 	cpufuncs.cf_sdcache_wb_range	= (void *)cpufunc_nullop;
   2918 #endif
   2919 
   2920 	/* Clear out the cache */
   2921 	cpu_idcache_wbinv_all();
   2922 
   2923 	/* Set the control register */
   2924 	cpu_control(0xffffffff, cpuctrl);
   2925 
   2926 	/* And again. */
   2927 	cpu_idcache_wbinv_all();
   2928 #ifdef L2CACHE_ENABLE
   2929 	armadaxp_sdcache_wbinv_all();
   2930 #endif
   2931 }
   2932 #endif /* CPU_PJ4B */
   2933 
   2934 #if defined(CPU_ARMV7)
   2935 struct cpu_option armv7_options[] = {
   2936     { "cpu.cache",      BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
   2937     { "cpu.nocache",    OR,  BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
   2938     { "armv7.cache",    BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
   2939     { "armv7.icache",   BIC, OR,  CPU_CONTROL_IC_ENABLE },
   2940     { "armv7.dcache",   BIC, OR,  CPU_CONTROL_DC_ENABLE },
   2941     { NULL, 		IGN, IGN, 0}
   2942 };
   2943 
   2944 void
   2945 armv7_setup(char *args)
   2946 {
   2947 	int cpuctrl =
   2948 	    CPU_CONTROL_MMU_ENABLE |
   2949 	    CPU_CONTROL_IC_ENABLE |
   2950 	    CPU_CONTROL_DC_ENABLE |
   2951 	    CPU_CONTROL_BPRD_ENABLE |
   2952 	    CPU_CONTROL_UNAL_ENABLE |
   2953 	    0;
   2954 #ifdef __ARMEB__
   2955 	cpuctrl |= CPU_CONTROL_EX_BEND;
   2956 #endif
   2957 #ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
   2958 	cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
   2959 #endif
   2960 #ifdef ARM_MMU_EXTENDED
   2961 	cpuctrl |= CPU_CONTROL_XP_ENABLE;
   2962 #endif
   2963 
   2964 	int cpuctrlmask = cpuctrl |
   2965 	    CPU_CONTROL_EX_BEND |
   2966 	    CPU_CONTROL_AFLT_ENABLE |
   2967 	    CPU_CONTROL_TR_ENABLE |
   2968 	    CPU_CONTROL_VECRELOC |
   2969 	    CPU_CONTROL_XP_ENABLE |
   2970 	    0;
   2971 
   2972 	cpuctrl = parse_cpu_options(args, armv7_options, cpuctrl);
   2973 
   2974 #ifndef ARM_HAS_VBAR
   2975 	if (vector_page == ARM_VECTORS_HIGH)
   2976 		cpuctrl |= CPU_CONTROL_VECRELOC;
   2977 #endif
   2978 
   2979 #ifdef __HAVE_GENERIC_START
   2980 	const u_int lcputype = cpufunc_id();
   2981 	int actlr_set = 0;
   2982 	int actlr_clr = 0;
   2983 
   2984 	if (CPU_ID_CORTEX_A5_P(lcputype)) {
   2985 		/*
   2986 		 * Disable exclusive L1/L2 cache control
   2987 		 * Enable SMP mode
   2988 		 * Enable Cache and TLB maintenance broadcast
   2989 		 */
   2990 		actlr_clr = CORTEXA5_ACTLR_EXCL;
   2991 		actlr_set = CORTEXA5_ACTLR_SMP | CORTEXA5_ACTLR_FW;
   2992 	} else if (CPU_ID_CORTEX_A7_P(lcputype)) {
   2993 #ifdef MULTIPROCESSOR
   2994 		actlr_set |= CORTEXA7_ACTLR_SMP;
   2995 #endif
   2996 	} else if (CPU_ID_CORTEX_A8_P(lcputype)) {
   2997 		actlr_set = CORTEXA8_ACTLR_L2EN;
   2998 		actlr_clr = CORTEXA8_ACTLR_L1ALIAS;
   2999 	} else if (CPU_ID_CORTEX_A9_P(lcputype)) {
   3000 		actlr_set =
   3001 		    CORTEXA9_AUXCTL_FW |
   3002 		    CORTEXA9_AUXCTL_L2PE |	// Not in FreeBSD
   3003 		    CORTEXA9_AUXCTL_SMP |
   3004 		    0;
   3005 	} else if (CPU_ID_CORTEX_A15_P(lcputype)) {
   3006 		actlr_set =
   3007 		    CORTEXA15_ACTLR_SMP |
   3008 		    CORTEXA15_ACTLR_SDEH |
   3009 		    0;
   3010 	} else if (CPU_ID_CORTEX_A12_P(lcputype) ||
   3011 		   CPU_ID_CORTEX_A17_P(lcputype)) {
   3012 		actlr_set = CORTEXA17_ACTLR_SMP;
   3013 		uint32_t diagset = 0;
   3014 		const uint16_t varrev =
   3015 		   __SHIFTIN(__SHIFTOUT(lcputype, CPU_ID_VARIANT_MASK), __BITS(7,4)) |
   3016 		   __SHIFTIN(__SHIFTOUT(lcputype, CPU_ID_REVISION_MASK), __BITS(3,0)) |
   3017 		   0;
   3018 		/* Errata 852421 exists upto r1p2 */
   3019 		if (varrev < 0x12) {
   3020 			diagset |= __BIT(24);
   3021 		}
   3022 		/* Errata 852423 exists upto r1p2 */
   3023 		if (varrev < 0x12) {
   3024 			diagset |= __BIT(12);
   3025 		}
   3026 		/* Errata 857272 */
   3027 		diagset |= __BITS(11,10);
   3028 
   3029 		const uint32_t dgnctlr1 = armreg_dgnctlr1_read();
   3030 		armreg_dgnctlr1_write(dgnctlr1 | diagset);
   3031 	} else if (CPU_ID_CORTEX_A53_P(lcputype)) {
   3032 	} else if (CPU_ID_CORTEX_A57_P(lcputype)) {
   3033 	} else if (CPU_ID_CORTEX_A72_P(lcputype)) {
   3034 	}
   3035 
   3036 	uint32_t actlr = armreg_auxctl_read();
   3037 	actlr &= ~actlr_clr;
   3038 	actlr |= actlr_set;
   3039 
   3040 	armreg_auxctl_write(actlr);
   3041 
   3042 	/* Set the control register - does dsb; isb */
   3043 	cpu_control(cpuctrlmask, cpuctrl);
   3044 
   3045 	/* does tlb and branch predictor flush, and dsb; isb */
   3046 	cpu_tlb_flushID();
   3047 #else
   3048 	/* Set the control register - does dsb; isb */
   3049 	cpu_control(cpuctrlmask, cpuctrl);
   3050 #endif
   3051 
   3052 }
   3053 #endif /* CPU_ARMV7 */
   3054 
   3055 
   3056 #if defined(CPU_ARM1136) || defined(CPU_ARM1176)
   3057 void
   3058 arm11x6_setup(char *args)
   3059 {
   3060 	int cpuctrl, cpuctrl_wax;
   3061 	uint32_t auxctrl;
   3062 	uint32_t sbz=0;
   3063 	uint32_t cpuid;
   3064 
   3065 	cpuid = cpu_idnum();
   3066 
   3067 	cpuctrl =
   3068 		CPU_CONTROL_MMU_ENABLE  |
   3069 		CPU_CONTROL_DC_ENABLE   |
   3070 		CPU_CONTROL_WBUF_ENABLE |
   3071 		CPU_CONTROL_32BP_ENABLE |
   3072 		CPU_CONTROL_32BD_ENABLE |
   3073 		CPU_CONTROL_LABT_ENABLE |
   3074 		CPU_CONTROL_UNAL_ENABLE |
   3075 #ifdef ARM_MMU_EXTENDED
   3076 		CPU_CONTROL_XP_ENABLE   |
   3077 #else
   3078 		CPU_CONTROL_SYST_ENABLE |
   3079 #endif
   3080 		CPU_CONTROL_IC_ENABLE;
   3081 
   3082 #ifdef __ARMEB__
   3083 	cpuctrl |= CPU_CONTROL_EX_BEND;
   3084 #endif
   3085 
   3086 	/*
   3087 	 * "write as existing" bits
   3088 	 * inverse of this is mask
   3089 	 */
   3090 	cpuctrl_wax =
   3091 		(3 << 30) |
   3092 		(1 << 29) |
   3093 		(1 << 28) |
   3094 		(3 << 26) |
   3095 		(3 << 19) |
   3096 		(1 << 17);
   3097 
   3098 #ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
   3099 	cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
   3100 #endif
   3101 
   3102 	cpuctrl = parse_cpu_options(args, arm11_options, cpuctrl);
   3103 
   3104 #ifndef ARM_HAS_VBAR
   3105 	if (vector_page == ARM_VECTORS_HIGH)
   3106 		cpuctrl |= CPU_CONTROL_VECRELOC;
   3107 #endif
   3108 
   3109 	auxctrl = armreg_auxctl_read();
   3110 	/*
   3111 	 * This options enables the workaround for the 364296 ARM1136
   3112 	 * r0pX errata (possible cache data corruption with
   3113 	 * hit-under-miss enabled). It sets the undocumented bit 31 in
   3114 	 * the auxiliary control register and the FI bit in the control
   3115 	 * register, thus disabling hit-under-miss without putting the
   3116 	 * processor into full low interrupt latency mode. ARM11MPCore
   3117 	 * is not affected.
   3118 	 */
   3119 	if ((cpuid & CPU_ID_CPU_MASK) == CPU_ID_ARM1136JS) { /* ARM1136JSr0pX */
   3120 		cpuctrl |= CPU_CONTROL_FI_ENABLE;
   3121 		auxctrl |= ARM1136_AUXCTL_PFI;
   3122 	}
   3123 
   3124 	/*
   3125 	 * This enables the workaround for the following ARM1176 r0pX
   3126 	 * errata.
   3127 	 *
   3128 	 * 394601: In low interrupt latency configuration, interrupted clean
   3129 	 * and invalidate operation may not clean dirty data.
   3130 	 *
   3131 	 * 716151: Clean Data Cache line by MVA can corrupt subsequent
   3132 	 * stores to the same cache line.
   3133 	 *
   3134 	 * 714068: Prefetch Instruction Cache Line or Invalidate Instruction
   3135 	 * Cache Line by MVA can cause deadlock.
   3136 	 */
   3137 	if ((cpuid & CPU_ID_CPU_MASK) == CPU_ID_ARM1176JZS) { /* ARM1176JZSr0 */
   3138 		/* 394601 and 716151 */
   3139 		cpuctrl |= CPU_CONTROL_FI_ENABLE;
   3140 		auxctrl |= ARM1176_AUXCTL_FIO;
   3141 
   3142 		/* 714068 */
   3143 		auxctrl |= ARM1176_AUXCTL_PHD;
   3144 	}
   3145 
   3146 	/* Clear out the cache */
   3147 	cpu_idcache_wbinv_all();
   3148 
   3149 	/* Now really make sure they are clean.  */
   3150 	__asm volatile ("mcr\tp15, 0, %0, c7, c7, 0" : : "r"(sbz));
   3151 
   3152 	/* Allow detection code to find the VFP if it's fitted.  */
   3153 	armreg_cpacr_write(0x0fffffff);
   3154 
   3155 	/* Set the control register */
   3156 	cpu_control(~cpuctrl_wax, cpuctrl);
   3157 
   3158 	/* Update auxctlr */
   3159 	armreg_auxctl_write(auxctrl);
   3160 
   3161 	/* And again. */
   3162 	cpu_idcache_wbinv_all();
   3163 }
   3164 #endif	/* CPU_ARM1136 || CPU_ARM1176 */
   3165 
   3166 #ifdef CPU_SA110
   3167 struct cpu_option sa110_options[] = {
   3168 #ifdef COMPAT_12
   3169 	{ "nocache",		IGN, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
   3170 	{ "nowritebuf",		IGN, BIC, CPU_CONTROL_WBUF_ENABLE },
   3171 #endif	/* COMPAT_12 */
   3172 	{ "cpu.cache",		BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
   3173 	{ "cpu.nocache",	OR,  BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
   3174 	{ "sa110.cache",	BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
   3175 	{ "sa110.icache",	BIC, OR,  CPU_CONTROL_IC_ENABLE },
   3176 	{ "sa110.dcache",	BIC, OR,  CPU_CONTROL_DC_ENABLE },
   3177 	{ "cpu.writebuf",	BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
   3178 	{ "cpu.nowritebuf",	OR,  BIC, CPU_CONTROL_WBUF_ENABLE },
   3179 	{ "sa110.writebuf",	BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
   3180 	{ NULL,			IGN, IGN, 0 }
   3181 };
   3182 
   3183 void
   3184 sa110_setup(char *args)
   3185 {
   3186 	int cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
   3187 		 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
   3188 		 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
   3189 		 | CPU_CONTROL_WBUF_ENABLE;
   3190 #if 0
   3191 	int cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
   3192 		 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
   3193 		 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
   3194 		 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE
   3195 		 | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE
   3196 		 | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_BPRD_ENABLE
   3197 		 | CPU_CONTROL_CPCLK;
   3198 #endif
   3199 
   3200 #ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
   3201 	cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
   3202 #endif
   3203 
   3204 	cpuctrl = parse_cpu_options(args, sa110_options, cpuctrl);
   3205 
   3206 #ifdef __ARMEB__
   3207 	cpuctrl |= CPU_CONTROL_BEND_ENABLE;
   3208 #endif
   3209 
   3210 #ifndef ARM_HAS_VBAR
   3211 	if (vector_page == ARM_VECTORS_HIGH)
   3212 		cpuctrl |= CPU_CONTROL_VECRELOC;
   3213 #endif
   3214 
   3215 	/* Clear out the cache */
   3216 	cpu_idcache_wbinv_all();
   3217 
   3218 	/* Set the control register */
   3219 #if 0
   3220 	cpu_control(cpuctrlmask, cpuctrl);
   3221 #endif
   3222 	cpu_control(0xffffffff, cpuctrl);
   3223 
   3224 	/*
   3225 	 * enable clockswitching, note that this doesn't read or write to r0,
   3226 	 * r0 is just to make it valid asm
   3227 	 */
   3228 	__asm volatile ("mcr p15, 0, r0, c15, c1, 2");
   3229 }
   3230 #endif	/* CPU_SA110 */
   3231 
   3232 #if defined(CPU_SA1100) || defined(CPU_SA1110)
   3233 struct cpu_option sa11x0_options[] = {
   3234 #ifdef COMPAT_12
   3235 	{ "nocache",		IGN, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
   3236 	{ "nowritebuf",		IGN, BIC, CPU_CONTROL_WBUF_ENABLE },
   3237 #endif	/* COMPAT_12 */
   3238 	{ "cpu.cache",		BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
   3239 	{ "cpu.nocache",	OR,  BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
   3240 	{ "sa11x0.cache",	BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
   3241 	{ "sa11x0.icache",	BIC, OR,  CPU_CONTROL_IC_ENABLE },
   3242 	{ "sa11x0.dcache",	BIC, OR,  CPU_CONTROL_DC_ENABLE },
   3243 	{ "cpu.writebuf",	BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
   3244 	{ "cpu.nowritebuf",	OR,  BIC, CPU_CONTROL_WBUF_ENABLE },
   3245 	{ "sa11x0.writebuf",	BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
   3246 	{ NULL,			IGN, IGN, 0 }
   3247 };
   3248 
   3249 void
   3250 sa11x0_setup(char *args)
   3251 {
   3252 
   3253 	int cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
   3254 		 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
   3255 		 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
   3256 		 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE;
   3257 #if 0
   3258 	int cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
   3259 		 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
   3260 		 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
   3261 		 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE
   3262 		 | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE
   3263 		 | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_BPRD_ENABLE
   3264 		 | CPU_CONTROL_CPCLK | CPU_CONTROL_VECRELOC;
   3265 #endif
   3266 
   3267 #ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
   3268 	cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
   3269 #endif
   3270 
   3271 	cpuctrl = parse_cpu_options(args, sa11x0_options, cpuctrl);
   3272 
   3273 #ifdef __ARMEB__
   3274 	cpuctrl |= CPU_CONTROL_BEND_ENABLE;
   3275 #endif
   3276 
   3277 #ifndef ARM_HAS_VBAR
   3278 	if (vector_page == ARM_VECTORS_HIGH)
   3279 		cpuctrl |= CPU_CONTROL_VECRELOC;
   3280 #endif
   3281 
   3282 	/* Clear out the cache */
   3283 	cpu_idcache_wbinv_all();
   3284 
   3285 	/* Set the control register */
   3286 	cpu_control(0xffffffff, cpuctrl);
   3287 }
   3288 #endif	/* CPU_SA1100 || CPU_SA1110 */
   3289 
   3290 #if defined(CPU_FA526)
   3291 struct cpu_option fa526_options[] = {
   3292 #ifdef COMPAT_12
   3293 	{ "nocache",		IGN, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
   3294 	{ "nowritebuf",		IGN, BIC, CPU_CONTROL_WBUF_ENABLE },
   3295 #endif	/* COMPAT_12 */
   3296 	{ "cpu.cache",		BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
   3297 	{ "cpu.nocache",	OR,  BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
   3298 	{ "cpu.writebuf",	BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
   3299 	{ "cpu.nowritebuf",	OR,  BIC, CPU_CONTROL_WBUF_ENABLE },
   3300 	{ NULL,			IGN, IGN, 0 }
   3301 };
   3302 
   3303 void
   3304 fa526_setup(char *args)
   3305 {
   3306 
   3307 	int cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
   3308 		 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
   3309 		 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
   3310 		 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE;
   3311 #if 0
   3312 	int cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
   3313 		 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
   3314 		 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
   3315 		 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE
   3316 		 | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE
   3317 		 | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_BPRD_ENABLE
   3318 		 | CPU_CONTROL_CPCLK | CPU_CONTROL_VECRELOC;
   3319 #endif
   3320 
   3321 #ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
   3322 	cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
   3323 #endif
   3324 
   3325 	cpuctrl = parse_cpu_options(args, fa526_options, cpuctrl);
   3326 
   3327 #ifdef __ARMEB__
   3328 	cpuctrl |= CPU_CONTROL_BEND_ENABLE;
   3329 #endif
   3330 
   3331 #ifndef ARM_HAS_VBAR
   3332 	if (vector_page == ARM_VECTORS_HIGH)
   3333 		cpuctrl |= CPU_CONTROL_VECRELOC;
   3334 #endif
   3335 
   3336 	/* Clear out the cache */
   3337 	cpu_idcache_wbinv_all();
   3338 
   3339 	/* Set the control register */
   3340 	cpu_control(0xffffffff, cpuctrl);
   3341 }
   3342 #endif	/* CPU_FA526 */
   3343 
   3344 #if defined(CPU_IXP12X0)
   3345 struct cpu_option ixp12x0_options[] = {
   3346 	{ "cpu.cache",		BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
   3347 	{ "cpu.nocache",	OR,  BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
   3348 	{ "ixp12x0.cache",	BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
   3349 	{ "ixp12x0.icache",	BIC, OR,  CPU_CONTROL_IC_ENABLE },
   3350 	{ "ixp12x0.dcache",	BIC, OR,  CPU_CONTROL_DC_ENABLE },
   3351 	{ "cpu.writebuf",	BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
   3352 	{ "cpu.nowritebuf",	OR,  BIC, CPU_CONTROL_WBUF_ENABLE },
   3353 	{ "ixp12x0.writebuf",	BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
   3354 	{ NULL,			IGN, IGN, 0 }
   3355 };
   3356 
   3357 void
   3358 ixp12x0_setup(char *args)
   3359 {
   3360 
   3361 	int cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_DC_ENABLE
   3362 		 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_SYST_ENABLE
   3363 		 | CPU_CONTROL_IC_ENABLE;
   3364 
   3365 	int cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_AFLT_ENABLE
   3366 		 | CPU_CONTROL_DC_ENABLE | CPU_CONTROL_WBUF_ENABLE
   3367 		 | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_SYST_ENABLE
   3368 		 | CPU_CONTROL_ROM_ENABLE | CPU_CONTROL_IC_ENABLE
   3369 		 | CPU_CONTROL_VECRELOC;
   3370 
   3371 #ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
   3372 	cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
   3373 #endif
   3374 
   3375 	cpuctrl = parse_cpu_options(args, ixp12x0_options, cpuctrl);
   3376 
   3377 #ifdef __ARMEB__
   3378 	cpuctrl |= CPU_CONTROL_BEND_ENABLE;
   3379 #endif
   3380 
   3381 #ifndef ARM_HAS_VBAR
   3382 	if (vector_page == ARM_VECTORS_HIGH)
   3383 		cpuctrl |= CPU_CONTROL_VECRELOC;
   3384 #endif
   3385 
   3386 	/* Clear out the cache */
   3387 	cpu_idcache_wbinv_all();
   3388 
   3389 	/* Set the control register */
   3390 	/* cpu_control(0xffffffff, cpuctrl); */
   3391 	cpu_control(cpuctrlmask, cpuctrl);
   3392 }
   3393 #endif /* CPU_IXP12X0 */
   3394 
   3395 #if defined(CPU_XSCALE)
   3396 struct cpu_option xscale_options[] = {
   3397 #ifdef COMPAT_12
   3398 	{ "branchpredict", 	BIC, OR,  CPU_CONTROL_BPRD_ENABLE },
   3399 	{ "nocache",		IGN, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
   3400 #endif	/* COMPAT_12 */
   3401 	{ "cpu.branchpredict", 	BIC, OR,  CPU_CONTROL_BPRD_ENABLE },
   3402 	{ "cpu.cache",		BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
   3403 	{ "cpu.nocache",	OR,  BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
   3404 	{ "xscale.branchpredict", BIC, OR,  CPU_CONTROL_BPRD_ENABLE },
   3405 	{ "xscale.cache",	BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
   3406 	{ "xscale.icache",	BIC, OR,  CPU_CONTROL_IC_ENABLE },
   3407 	{ "xscale.dcache",	BIC, OR,  CPU_CONTROL_DC_ENABLE },
   3408 	{ NULL,			IGN, IGN, 0 }
   3409 };
   3410 
   3411 void
   3412 xscale_setup(char *args)
   3413 {
   3414 	uint32_t auxctl;
   3415 
   3416 	/*
   3417 	 * The XScale Write Buffer is always enabled.  Our option
   3418 	 * is to enable/disable coalescing.  Note that bits 6:3
   3419 	 * must always be enabled.
   3420 	 */
   3421 
   3422 	int cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
   3423 		 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
   3424 		 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
   3425 		 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE
   3426 		 | CPU_CONTROL_BPRD_ENABLE;
   3427 #if 0
   3428 	int cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
   3429 		 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
   3430 		 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
   3431 		 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE
   3432 		 | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE
   3433 		 | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_BPRD_ENABLE
   3434 		 | CPU_CONTROL_CPCLK | CPU_CONTROL_VECRELOC;
   3435 #endif
   3436 
   3437 #ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
   3438 	cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
   3439 #endif
   3440 
   3441 	cpuctrl = parse_cpu_options(args, xscale_options, cpuctrl);
   3442 
   3443 #ifdef __ARMEB__
   3444 	cpuctrl |= CPU_CONTROL_BEND_ENABLE;
   3445 #endif
   3446 
   3447 #ifndef ARM_HAS_VBAR
   3448 	if (vector_page == ARM_VECTORS_HIGH)
   3449 		cpuctrl |= CPU_CONTROL_VECRELOC;
   3450 #endif
   3451 
   3452 	/* Clear out the cache */
   3453 	cpu_idcache_wbinv_all();
   3454 
   3455 	/*
   3456 	 * Set the control register.  Note that bits 6:3 must always
   3457 	 * be set to 1.
   3458 	 */
   3459 #if 0
   3460 	cpu_control(cpuctrlmask, cpuctrl);
   3461 #endif
   3462 	cpu_control(0xffffffff, cpuctrl);
   3463 
   3464 	/* Make sure write coalescing is turned on */
   3465 	auxctl = armreg_auxctl_read();
   3466 #ifdef XSCALE_NO_COALESCE_WRITES
   3467 	auxctl |= XSCALE_AUXCTL_K;
   3468 #else
   3469 	auxctl &= ~XSCALE_AUXCTL_K;
   3470 #endif
   3471 	armreg_auxctl_write(auxctl);
   3472 }
   3473 #endif	/* CPU_XSCALE */
   3474 
   3475 #if defined(CPU_SHEEVA)
   3476 struct cpu_option sheeva_options[] = {
   3477 	{ "cpu.cache",		BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
   3478 	{ "cpu.nocache",	OR,  BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
   3479 	{ "sheeva.cache",	BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
   3480 	{ "sheeva.icache",	BIC, OR,  CPU_CONTROL_IC_ENABLE },
   3481 	{ "sheeva.dcache",	BIC, OR,  CPU_CONTROL_DC_ENABLE },
   3482 	{ "cpu.writebuf",	BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
   3483 	{ "cpu.nowritebuf",	OR,  BIC, CPU_CONTROL_WBUF_ENABLE },
   3484 	{ "sheeva.writebuf",	BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
   3485 	{ NULL,			IGN, IGN, 0 }
   3486 };
   3487 
   3488 void
   3489 sheeva_setup(char *args)
   3490 {
   3491 	int cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_SYST_ENABLE
   3492 	    | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
   3493 	    | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_BPRD_ENABLE;
   3494 #if 0
   3495 	int cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_SYST_ENABLE
   3496 	    | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
   3497 	    | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE
   3498 	    | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE
   3499 	    | CPU_CONTROL_BPRD_ENABLE
   3500 	    | CPU_CONTROL_ROUNDROBIN | CPU_CONTROL_CPCLK;
   3501 #endif
   3502 
   3503 #ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
   3504 	cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
   3505 #endif
   3506 
   3507 	cpuctrl = parse_cpu_options(args, sheeva_options, cpuctrl);
   3508 
   3509 	/* Enable DCache Streaming Switch and Write Allocate */
   3510 	uint32_t sheeva_ext = armreg_sheeva_xctrl_read();
   3511 
   3512 	sheeva_ext |= FC_DCACHE_STREAM_EN | FC_WR_ALLOC_EN;
   3513 #ifdef SHEEVA_L2_CACHE
   3514 	sheeva_ext |= FC_L2CACHE_EN;
   3515 	sheeva_ext &= ~FC_L2_PREF_DIS;
   3516 #endif
   3517 
   3518 	armreg_sheeva_xctrl_write(sheeva_ext);
   3519 
   3520 #ifdef SHEEVA_L2_CACHE
   3521 #ifndef SHEEVA_L2_CACHE_WT
   3522 	arm_scache.cache_type = CPU_CT_CTYPE_WB2;
   3523 #elif CPU_CT_CTYPE_WT != 0
   3524 	arm_scache.cache_type = CPU_CT_CTYPE_WT;
   3525 #endif
   3526 	arm_scache.cache_unified = 1;
   3527 	arm_scache.dcache_type = arm_scache.icache_type = CACHE_TYPE_PIPT;
   3528 	arm_scache.dcache_size = arm_scache.icache_size = 256*1024;
   3529 	arm_scache.dcache_ways = arm_scache.icache_ways = 4;
   3530 	arm_scache.dcache_way_size = arm_scache.icache_way_size =
   3531 	    arm_scache.dcache_size / arm_scache.dcache_ways;
   3532 	arm_scache.dcache_line_size = arm_scache.icache_line_size = 32;
   3533 	arm_scache.dcache_sets = arm_scache.icache_sets =
   3534 	    arm_scache.dcache_way_size / arm_scache.dcache_line_size;
   3535 
   3536 	cpufuncs.cf_sdcache_wb_range = sheeva_sdcache_wb_range;
   3537 	cpufuncs.cf_sdcache_inv_range = sheeva_sdcache_inv_range;
   3538 	cpufuncs.cf_sdcache_wbinv_range = sheeva_sdcache_wbinv_range;
   3539 #endif /* SHEEVA_L2_CACHE */
   3540 
   3541 #ifdef __ARMEB__
   3542 	cpuctrl |= CPU_CONTROL_BEND_ENABLE;
   3543 #endif
   3544 
   3545 #ifndef ARM_HAS_VBAR
   3546 	if (vector_page == ARM_VECTORS_HIGH)
   3547 		cpuctrl |= CPU_CONTROL_VECRELOC;
   3548 #endif
   3549 
   3550 	/* Clear out the cache */
   3551 	cpu_idcache_wbinv_all();
   3552 
   3553 	/* Now really make sure they are clean.  */
   3554 	__asm volatile ("mcr\tp15, 0, r0, c7, c7, 0" : : );
   3555 
   3556 	/* Set the control register */
   3557 	cpu_control(0xffffffff, cpuctrl);
   3558 
   3559 	/* And again. */
   3560 	cpu_idcache_wbinv_all();
   3561 #ifdef SHEEVA_L2_CACHE
   3562 	sheeva_sdcache_wbinv_all();
   3563 #endif
   3564 }
   3565 #endif	/* CPU_SHEEVA */
   3566 
   3567 bool
   3568 cpu_gtmr_exists_p(void)
   3569 {
   3570 	return armreg_pfr1_read() & ARM_PFR1_GTIMER_MASK;
   3571 }
   3572 
   3573 u_int
   3574 cpu_clusterid(void)
   3575 {
   3576 	return __SHIFTOUT(armreg_mpidr_read(), MPIDR_AFF1);
   3577 }
   3578 
   3579 bool
   3580 cpu_earlydevice_va_p(void)
   3581 {
   3582 	const bool mmu_enabled_p =
   3583 	    armreg_sctlr_read() & CPU_CONTROL_MMU_ENABLE;
   3584 
   3585 	if (!mmu_enabled_p)
   3586 		return false;
   3587 
   3588 	/* Don't access cpu_ttb unless the mmu is enabled */
   3589 	const bool cpul1pt_p =
   3590 	    ((armreg_ttbr_read() & -L1_TABLE_SIZE) == cpu_ttb) ||
   3591 	    ((armreg_ttbr1_read() & -L1_TABLE_SIZE) == cpu_ttb);
   3592 
   3593 	return cpul1pt_p;
   3594 }
   3595