The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/arm/arm/cpufunc.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 01ef9f67658e0f8cc25cd43d9a969e7a


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.