cpufunc.c revision 257217
1129198Scognet/* $NetBSD: cpufunc.c,v 1.65 2003/11/05 12:53:15 scw Exp $ */ 2129198Scognet 3139735Simp/*- 4129198Scognet * arm7tdmi support code Copyright (c) 2001 John Fremlin 5129198Scognet * arm8 support code Copyright (c) 1997 ARM Limited 6129198Scognet * arm8 support code Copyright (c) 1997 Causality Limited 7129198Scognet * arm9 support code Copyright (C) 2001 ARM Ltd 8129198Scognet * Copyright (c) 1997 Mark Brinicombe. 9129198Scognet * Copyright (c) 1997 Causality Limited 10129198Scognet * All rights reserved. 11129198Scognet * 12129198Scognet * Redistribution and use in source and binary forms, with or without 13129198Scognet * modification, are permitted provided that the following conditions 14129198Scognet * are met: 15129198Scognet * 1. Redistributions of source code must retain the above copyright 16129198Scognet * notice, this list of conditions and the following disclaimer. 17129198Scognet * 2. Redistributions in binary form must reproduce the above copyright 18129198Scognet * notice, this list of conditions and the following disclaimer in the 19129198Scognet * documentation and/or other materials provided with the distribution. 20129198Scognet * 3. All advertising materials mentioning features or use of this software 21129198Scognet * must display the following acknowledgement: 22129198Scognet * This product includes software developed by Causality Limited. 23129198Scognet * 4. The name of Causality Limited may not be used to endorse or promote 24129198Scognet * products derived from this software without specific prior written 25129198Scognet * permission. 26129198Scognet * 27129198Scognet * THIS SOFTWARE IS PROVIDED BY CAUSALITY LIMITED ``AS IS'' AND ANY EXPRESS 28129198Scognet * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 29129198Scognet * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 30129198Scognet * DISCLAIMED. IN NO EVENT SHALL CAUSALITY LIMITED BE LIABLE FOR ANY DIRECT, 31129198Scognet * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 32129198Scognet * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 33129198Scognet * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34129198Scognet * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35129198Scognet * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36129198Scognet * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37129198Scognet * SUCH DAMAGE. 38129198Scognet * 39129198Scognet * RiscBSD kernel project 40129198Scognet * 41129198Scognet * cpufuncs.c 42129198Scognet * 43129198Scognet * C functions for supporting CPU / MMU / TLB specific operations. 44129198Scognet * 45129198Scognet * Created : 30/01/97 46129198Scognet */ 47129198Scognet#include <sys/cdefs.h> 48129198Scognet__FBSDID("$FreeBSD: head/sys/arm/arm/cpufunc.c 257217 2013-10-27 17:09:23Z ian $"); 49129198Scognet 50129198Scognet#include <sys/param.h> 51129198Scognet#include <sys/systm.h> 52129198Scognet#include <sys/lock.h> 53129198Scognet#include <sys/mutex.h> 54132472Scognet#include <sys/bus.h> 55132472Scognet#include <machine/bus.h> 56129198Scognet#include <machine/cpu.h> 57129198Scognet#include <machine/disassem.h> 58129198Scognet 59129198Scognet#include <vm/vm.h> 60129198Scognet#include <vm/pmap.h> 61166655Scognet#include <vm/uma.h> 62129198Scognet 63129198Scognet#include <machine/cpuconf.h> 64129198Scognet#include <machine/cpufunc.h> 65129198Scognet#include <machine/bootconfig.h> 66129198Scognet 67129198Scognet#ifdef CPU_XSCALE_80200 68135646Scognet#include <arm/xscale/i80200/i80200reg.h> 69135646Scognet#include <arm/xscale/i80200/i80200var.h> 70129198Scognet#endif 71129198Scognet 72161592Scognet#if defined(CPU_XSCALE_80321) || defined(CPU_XSCALE_80219) 73135646Scognet#include <arm/xscale/i80321/i80321reg.h> 74135646Scognet#include <arm/xscale/i80321/i80321var.h> 75129198Scognet#endif 76129198Scognet 77243579Smarcel/* 78243579Smarcel * Some definitions in i81342reg.h clash with i80321reg.h. 79243579Smarcel * This only happens for the LINT kernel. As it happens, 80243579Smarcel * we don't need anything from i81342reg.h that we already 81243579Smarcel * got from somewhere else during a LINT compile. 82243579Smarcel */ 83243579Smarcel#if defined(CPU_XSCALE_81342) && !defined(COMPILING_LINT) 84164080Scognet#include <arm/xscale/i8134x/i81342reg.h> 85164080Scognet#endif 86164080Scognet 87129198Scognet#ifdef CPU_XSCALE_IXP425 88135646Scognet#include <arm/xscale/ixp425/ixp425reg.h> 89135646Scognet#include <arm/xscale/ixp425/ixp425var.h> 90129198Scognet#endif 91129198Scognet 92129198Scognet/* PRIMARY CACHE VARIABLES */ 93129198Scognetint arm_picache_size; 94129198Scognetint arm_picache_line_size; 95129198Scognetint arm_picache_ways; 96129198Scognet 97129198Scognetint arm_pdcache_size; /* and unified */ 98129198Scognetint arm_pdcache_line_size; 99129198Scognetint arm_pdcache_ways; 100129198Scognet 101129198Scognetint arm_pcache_type; 102129198Scognetint arm_pcache_unified; 103129198Scognet 104129198Scognetint arm_dcache_align; 105129198Scognetint arm_dcache_align_mask; 106129198Scognet 107239268Sgonzou_int arm_cache_level; 108239268Sgonzou_int arm_cache_type[14]; 109239268Sgonzou_int arm_cache_loc; 110239268Sgonzo 111129198Scognet/* 1 == use cpu_sleep(), 0 == don't */ 112129198Scognetint cpu_do_powersave; 113129198Scognetint ctrl; 114129198Scognet 115129198Scognet#ifdef CPU_ARM7TDMI 116129198Scognetstruct cpu_functions arm7tdmi_cpufuncs = { 117129198Scognet /* CPU functions */ 118129198Scognet 119129198Scognet cpufunc_id, /* id */ 120129198Scognet cpufunc_nullop, /* cpwait */ 121129198Scognet 122129198Scognet /* MMU functions */ 123129198Scognet 124129198Scognet cpufunc_control, /* control */ 125129198Scognet cpufunc_domains, /* domain */ 126129198Scognet arm7tdmi_setttb, /* setttb */ 127129198Scognet cpufunc_faultstatus, /* faultstatus */ 128129198Scognet cpufunc_faultaddress, /* faultaddress */ 129129198Scognet 130129198Scognet /* TLB functions */ 131129198Scognet 132129198Scognet arm7tdmi_tlb_flushID, /* tlb_flushID */ 133129198Scognet arm7tdmi_tlb_flushID_SE, /* tlb_flushID_SE */ 134129198Scognet arm7tdmi_tlb_flushID, /* tlb_flushI */ 135129198Scognet arm7tdmi_tlb_flushID_SE, /* tlb_flushI_SE */ 136129198Scognet arm7tdmi_tlb_flushID, /* tlb_flushD */ 137129198Scognet arm7tdmi_tlb_flushID_SE, /* tlb_flushD_SE */ 138129198Scognet 139129198Scognet /* Cache operations */ 140129198Scognet 141129198Scognet cpufunc_nullop, /* icache_sync_all */ 142129198Scognet (void *)cpufunc_nullop, /* icache_sync_range */ 143129198Scognet 144129198Scognet arm7tdmi_cache_flushID, /* dcache_wbinv_all */ 145129198Scognet (void *)arm7tdmi_cache_flushID, /* dcache_wbinv_range */ 146129198Scognet (void *)arm7tdmi_cache_flushID, /* dcache_inv_range */ 147129198Scognet (void *)cpufunc_nullop, /* dcache_wb_range */ 148129198Scognet 149129198Scognet arm7tdmi_cache_flushID, /* idcache_wbinv_all */ 150129198Scognet (void *)arm7tdmi_cache_flushID, /* idcache_wbinv_range */ 151171618Scognet cpufunc_nullop, /* l2cache_wbinv_all */ 152171781Scognet (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 153171781Scognet (void *)cpufunc_nullop, /* l2cache_inv_range */ 154171781Scognet (void *)cpufunc_nullop, /* l2cache_wb_range */ 155129198Scognet 156129198Scognet /* Other functions */ 157129198Scognet 158129198Scognet cpufunc_nullop, /* flush_prefetchbuf */ 159129198Scognet cpufunc_nullop, /* drain_writebuf */ 160129198Scognet cpufunc_nullop, /* flush_brnchtgt_C */ 161129198Scognet (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 162129198Scognet 163129198Scognet (void *)cpufunc_nullop, /* sleep */ 164129198Scognet 165129198Scognet /* Soft functions */ 166129198Scognet 167129198Scognet late_abort_fixup, /* dataabt_fixup */ 168129198Scognet cpufunc_null_fixup, /* prefetchabt_fixup */ 169129198Scognet 170129198Scognet arm7tdmi_context_switch, /* context_switch */ 171129198Scognet 172129198Scognet arm7tdmi_setup /* cpu setup */ 173129198Scognet 174129198Scognet}; 175129198Scognet#endif /* CPU_ARM7TDMI */ 176129198Scognet 177129198Scognet#ifdef CPU_ARM8 178129198Scognetstruct cpu_functions arm8_cpufuncs = { 179129198Scognet /* CPU functions */ 180129198Scognet 181129198Scognet cpufunc_id, /* id */ 182129198Scognet cpufunc_nullop, /* cpwait */ 183129198Scognet 184129198Scognet /* MMU functions */ 185129198Scognet 186129198Scognet cpufunc_control, /* control */ 187129198Scognet cpufunc_domains, /* domain */ 188129198Scognet arm8_setttb, /* setttb */ 189129198Scognet cpufunc_faultstatus, /* faultstatus */ 190129198Scognet cpufunc_faultaddress, /* faultaddress */ 191129198Scognet 192129198Scognet /* TLB functions */ 193129198Scognet 194129198Scognet arm8_tlb_flushID, /* tlb_flushID */ 195129198Scognet arm8_tlb_flushID_SE, /* tlb_flushID_SE */ 196129198Scognet arm8_tlb_flushID, /* tlb_flushI */ 197129198Scognet arm8_tlb_flushID_SE, /* tlb_flushI_SE */ 198129198Scognet arm8_tlb_flushID, /* tlb_flushD */ 199129198Scognet arm8_tlb_flushID_SE, /* tlb_flushD_SE */ 200129198Scognet 201129198Scognet /* Cache operations */ 202129198Scognet 203129198Scognet cpufunc_nullop, /* icache_sync_all */ 204129198Scognet (void *)cpufunc_nullop, /* icache_sync_range */ 205129198Scognet 206129198Scognet arm8_cache_purgeID, /* dcache_wbinv_all */ 207129198Scognet (void *)arm8_cache_purgeID, /* dcache_wbinv_range */ 208129198Scognet/*XXX*/ (void *)arm8_cache_purgeID, /* dcache_inv_range */ 209129198Scognet (void *)arm8_cache_cleanID, /* dcache_wb_range */ 210129198Scognet 211129198Scognet arm8_cache_purgeID, /* idcache_wbinv_all */ 212129198Scognet (void *)arm8_cache_purgeID, /* idcache_wbinv_range */ 213171618Scognet cpufunc_nullop, /* l2cache_wbinv_all */ 214171781Scognet (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 215171781Scognet (void *)cpufunc_nullop, /* l2cache_inv_range */ 216171781Scognet (void *)cpufunc_nullop, /* l2cache_wb_range */ 217129198Scognet 218129198Scognet /* Other functions */ 219129198Scognet 220129198Scognet cpufunc_nullop, /* flush_prefetchbuf */ 221129198Scognet cpufunc_nullop, /* drain_writebuf */ 222129198Scognet cpufunc_nullop, /* flush_brnchtgt_C */ 223129198Scognet (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 224129198Scognet 225129198Scognet (void *)cpufunc_nullop, /* sleep */ 226129198Scognet 227129198Scognet /* Soft functions */ 228129198Scognet 229129198Scognet cpufunc_null_fixup, /* dataabt_fixup */ 230129198Scognet cpufunc_null_fixup, /* prefetchabt_fixup */ 231129198Scognet 232129198Scognet arm8_context_switch, /* context_switch */ 233129198Scognet 234129198Scognet arm8_setup /* cpu setup */ 235236991Simp}; 236129198Scognet#endif /* CPU_ARM8 */ 237129198Scognet 238129198Scognet#ifdef CPU_ARM9 239129198Scognetstruct cpu_functions arm9_cpufuncs = { 240129198Scognet /* CPU functions */ 241129198Scognet 242129198Scognet cpufunc_id, /* id */ 243129198Scognet cpufunc_nullop, /* cpwait */ 244129198Scognet 245129198Scognet /* MMU functions */ 246129198Scognet 247129198Scognet cpufunc_control, /* control */ 248129198Scognet cpufunc_domains, /* Domain */ 249129198Scognet arm9_setttb, /* Setttb */ 250129198Scognet cpufunc_faultstatus, /* Faultstatus */ 251129198Scognet cpufunc_faultaddress, /* Faultaddress */ 252129198Scognet 253129198Scognet /* TLB functions */ 254129198Scognet 255129198Scognet armv4_tlb_flushID, /* tlb_flushID */ 256129198Scognet arm9_tlb_flushID_SE, /* tlb_flushID_SE */ 257129198Scognet armv4_tlb_flushI, /* tlb_flushI */ 258129198Scognet (void *)armv4_tlb_flushI, /* tlb_flushI_SE */ 259129198Scognet armv4_tlb_flushD, /* tlb_flushD */ 260129198Scognet armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 261129198Scognet 262129198Scognet /* Cache operations */ 263129198Scognet 264146605Scognet arm9_icache_sync_all, /* icache_sync_all */ 265146605Scognet arm9_icache_sync_range, /* icache_sync_range */ 266129198Scognet 267146605Scognet arm9_dcache_wbinv_all, /* dcache_wbinv_all */ 268146605Scognet arm9_dcache_wbinv_range, /* dcache_wbinv_range */ 269195798Sraj arm9_dcache_inv_range, /* dcache_inv_range */ 270146605Scognet arm9_dcache_wb_range, /* dcache_wb_range */ 271129198Scognet 272146605Scognet arm9_idcache_wbinv_all, /* idcache_wbinv_all */ 273146605Scognet arm9_idcache_wbinv_range, /* idcache_wbinv_range */ 274171618Scognet cpufunc_nullop, /* l2cache_wbinv_all */ 275171781Scognet (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 276171781Scognet (void *)cpufunc_nullop, /* l2cache_inv_range */ 277171781Scognet (void *)cpufunc_nullop, /* l2cache_wb_range */ 278129198Scognet 279129198Scognet /* Other functions */ 280129198Scognet 281129198Scognet cpufunc_nullop, /* flush_prefetchbuf */ 282129198Scognet armv4_drain_writebuf, /* drain_writebuf */ 283129198Scognet cpufunc_nullop, /* flush_brnchtgt_C */ 284129198Scognet (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 285129198Scognet 286129198Scognet (void *)cpufunc_nullop, /* sleep */ 287129198Scognet 288129198Scognet /* Soft functions */ 289129198Scognet 290129198Scognet cpufunc_null_fixup, /* dataabt_fixup */ 291129198Scognet cpufunc_null_fixup, /* prefetchabt_fixup */ 292129198Scognet 293129198Scognet arm9_context_switch, /* context_switch */ 294129198Scognet 295129198Scognet arm9_setup /* cpu setup */ 296129198Scognet 297129198Scognet}; 298129198Scognet#endif /* CPU_ARM9 */ 299129198Scognet 300172738Simp#if defined(CPU_ARM9E) || defined(CPU_ARM10) 301172738Simpstruct cpu_functions armv5_ec_cpufuncs = { 302172738Simp /* CPU functions */ 303172738Simp 304172738Simp cpufunc_id, /* id */ 305172738Simp cpufunc_nullop, /* cpwait */ 306172738Simp 307172738Simp /* MMU functions */ 308172738Simp 309172738Simp cpufunc_control, /* control */ 310172738Simp cpufunc_domains, /* Domain */ 311172738Simp armv5_ec_setttb, /* Setttb */ 312172738Simp cpufunc_faultstatus, /* Faultstatus */ 313172738Simp cpufunc_faultaddress, /* Faultaddress */ 314172738Simp 315172738Simp /* TLB functions */ 316172738Simp 317172738Simp armv4_tlb_flushID, /* tlb_flushID */ 318172738Simp arm10_tlb_flushID_SE, /* tlb_flushID_SE */ 319172738Simp armv4_tlb_flushI, /* tlb_flushI */ 320172738Simp arm10_tlb_flushI_SE, /* tlb_flushI_SE */ 321172738Simp armv4_tlb_flushD, /* tlb_flushD */ 322172738Simp armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 323172738Simp 324172738Simp /* Cache operations */ 325172738Simp 326172738Simp armv5_ec_icache_sync_all, /* icache_sync_all */ 327172738Simp armv5_ec_icache_sync_range, /* icache_sync_range */ 328172738Simp 329172738Simp armv5_ec_dcache_wbinv_all, /* dcache_wbinv_all */ 330172738Simp armv5_ec_dcache_wbinv_range, /* dcache_wbinv_range */ 331195798Sraj armv5_ec_dcache_inv_range, /* dcache_inv_range */ 332172738Simp armv5_ec_dcache_wb_range, /* dcache_wb_range */ 333172738Simp 334172738Simp armv5_ec_idcache_wbinv_all, /* idcache_wbinv_all */ 335172738Simp armv5_ec_idcache_wbinv_range, /* idcache_wbinv_range */ 336172738Simp 337173442Scognet cpufunc_nullop, /* l2cache_wbinv_all */ 338173442Scognet (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 339173442Scognet (void *)cpufunc_nullop, /* l2cache_inv_range */ 340173442Scognet (void *)cpufunc_nullop, /* l2cache_wb_range */ 341236991Simp 342172738Simp /* Other functions */ 343172738Simp 344172738Simp cpufunc_nullop, /* flush_prefetchbuf */ 345172738Simp armv4_drain_writebuf, /* drain_writebuf */ 346172738Simp cpufunc_nullop, /* flush_brnchtgt_C */ 347172738Simp (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 348172738Simp 349172738Simp (void *)cpufunc_nullop, /* sleep */ 350172738Simp 351172738Simp /* Soft functions */ 352172738Simp 353172738Simp cpufunc_null_fixup, /* dataabt_fixup */ 354172738Simp cpufunc_null_fixup, /* prefetchabt_fixup */ 355172738Simp 356172738Simp arm10_context_switch, /* context_switch */ 357172738Simp 358172738Simp arm10_setup /* cpu setup */ 359172738Simp 360172738Simp}; 361183835Sraj 362186933Srajstruct cpu_functions sheeva_cpufuncs = { 363183835Sraj /* CPU functions */ 364183835Sraj 365183835Sraj cpufunc_id, /* id */ 366183835Sraj cpufunc_nullop, /* cpwait */ 367183835Sraj 368183835Sraj /* MMU functions */ 369183835Sraj 370183835Sraj cpufunc_control, /* control */ 371183835Sraj cpufunc_domains, /* Domain */ 372186933Sraj sheeva_setttb, /* Setttb */ 373183835Sraj cpufunc_faultstatus, /* Faultstatus */ 374183835Sraj cpufunc_faultaddress, /* Faultaddress */ 375183835Sraj 376183835Sraj /* TLB functions */ 377183835Sraj 378183835Sraj armv4_tlb_flushID, /* tlb_flushID */ 379183835Sraj arm10_tlb_flushID_SE, /* tlb_flushID_SE */ 380183835Sraj armv4_tlb_flushI, /* tlb_flushI */ 381183835Sraj arm10_tlb_flushI_SE, /* tlb_flushI_SE */ 382183835Sraj armv4_tlb_flushD, /* tlb_flushD */ 383183835Sraj armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 384183835Sraj 385183835Sraj /* Cache operations */ 386183835Sraj 387183835Sraj armv5_ec_icache_sync_all, /* icache_sync_all */ 388183835Sraj armv5_ec_icache_sync_range, /* icache_sync_range */ 389183835Sraj 390183835Sraj armv5_ec_dcache_wbinv_all, /* dcache_wbinv_all */ 391186933Sraj sheeva_dcache_wbinv_range, /* dcache_wbinv_range */ 392186933Sraj sheeva_dcache_inv_range, /* dcache_inv_range */ 393186933Sraj sheeva_dcache_wb_range, /* dcache_wb_range */ 394183835Sraj 395183835Sraj armv5_ec_idcache_wbinv_all, /* idcache_wbinv_all */ 396186933Sraj sheeva_idcache_wbinv_range, /* idcache_wbinv_all */ 397183835Sraj 398186933Sraj sheeva_l2cache_wbinv_all, /* l2cache_wbinv_all */ 399186933Sraj sheeva_l2cache_wbinv_range, /* l2cache_wbinv_range */ 400186933Sraj sheeva_l2cache_inv_range, /* l2cache_inv_range */ 401186933Sraj sheeva_l2cache_wb_range, /* l2cache_wb_range */ 402183835Sraj 403183835Sraj /* Other functions */ 404183835Sraj 405183835Sraj cpufunc_nullop, /* flush_prefetchbuf */ 406183835Sraj armv4_drain_writebuf, /* drain_writebuf */ 407183835Sraj cpufunc_nullop, /* flush_brnchtgt_C */ 408183835Sraj (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 409183835Sraj 410212825Smav sheeva_cpu_sleep, /* sleep */ 411183835Sraj 412183835Sraj /* Soft functions */ 413183835Sraj 414183835Sraj cpufunc_null_fixup, /* dataabt_fixup */ 415183835Sraj cpufunc_null_fixup, /* prefetchabt_fixup */ 416183835Sraj 417183835Sraj arm10_context_switch, /* context_switch */ 418183835Sraj 419183835Sraj arm10_setup /* cpu setup */ 420183835Sraj}; 421172738Simp#endif /* CPU_ARM9E || CPU_ARM10 */ 422172738Simp 423129198Scognet#ifdef CPU_ARM10 424129198Scognetstruct cpu_functions arm10_cpufuncs = { 425129198Scognet /* CPU functions */ 426129198Scognet 427129198Scognet cpufunc_id, /* id */ 428129198Scognet cpufunc_nullop, /* cpwait */ 429129198Scognet 430129198Scognet /* MMU functions */ 431129198Scognet 432129198Scognet cpufunc_control, /* control */ 433129198Scognet cpufunc_domains, /* Domain */ 434129198Scognet arm10_setttb, /* Setttb */ 435129198Scognet cpufunc_faultstatus, /* Faultstatus */ 436129198Scognet cpufunc_faultaddress, /* Faultaddress */ 437129198Scognet 438129198Scognet /* TLB functions */ 439129198Scognet 440129198Scognet armv4_tlb_flushID, /* tlb_flushID */ 441129198Scognet arm10_tlb_flushID_SE, /* tlb_flushID_SE */ 442129198Scognet armv4_tlb_flushI, /* tlb_flushI */ 443129198Scognet arm10_tlb_flushI_SE, /* tlb_flushI_SE */ 444129198Scognet armv4_tlb_flushD, /* tlb_flushD */ 445129198Scognet armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 446129198Scognet 447129198Scognet /* Cache operations */ 448129198Scognet 449129198Scognet arm10_icache_sync_all, /* icache_sync_all */ 450129198Scognet arm10_icache_sync_range, /* icache_sync_range */ 451129198Scognet 452129198Scognet arm10_dcache_wbinv_all, /* dcache_wbinv_all */ 453129198Scognet arm10_dcache_wbinv_range, /* dcache_wbinv_range */ 454129198Scognet arm10_dcache_inv_range, /* dcache_inv_range */ 455129198Scognet arm10_dcache_wb_range, /* dcache_wb_range */ 456129198Scognet 457129198Scognet arm10_idcache_wbinv_all, /* idcache_wbinv_all */ 458129198Scognet arm10_idcache_wbinv_range, /* idcache_wbinv_range */ 459171618Scognet cpufunc_nullop, /* l2cache_wbinv_all */ 460171781Scognet (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 461171781Scognet (void *)cpufunc_nullop, /* l2cache_inv_range */ 462171781Scognet (void *)cpufunc_nullop, /* l2cache_wb_range */ 463129198Scognet 464129198Scognet /* Other functions */ 465129198Scognet 466129198Scognet cpufunc_nullop, /* flush_prefetchbuf */ 467129198Scognet armv4_drain_writebuf, /* drain_writebuf */ 468129198Scognet cpufunc_nullop, /* flush_brnchtgt_C */ 469129198Scognet (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 470129198Scognet 471129198Scognet (void *)cpufunc_nullop, /* sleep */ 472129198Scognet 473129198Scognet /* Soft functions */ 474129198Scognet 475129198Scognet cpufunc_null_fixup, /* dataabt_fixup */ 476129198Scognet cpufunc_null_fixup, /* prefetchabt_fixup */ 477129198Scognet 478129198Scognet arm10_context_switch, /* context_switch */ 479129198Scognet 480129198Scognet arm10_setup /* cpu setup */ 481129198Scognet 482129198Scognet}; 483129198Scognet#endif /* CPU_ARM10 */ 484129198Scognet 485239268Sgonzo#ifdef CPU_MV_PJ4B 486239268Sgonzostruct cpu_functions pj4bv7_cpufuncs = { 487239268Sgonzo /* CPU functions */ 488239268Sgonzo 489239268Sgonzo cpufunc_id, /* id */ 490239268Sgonzo arm11_drain_writebuf, /* cpwait */ 491239268Sgonzo 492239268Sgonzo /* MMU functions */ 493239268Sgonzo 494239268Sgonzo cpufunc_control, /* control */ 495239268Sgonzo cpufunc_domains, /* Domain */ 496239268Sgonzo pj4b_setttb, /* Setttb */ 497239268Sgonzo cpufunc_faultstatus, /* Faultstatus */ 498239268Sgonzo cpufunc_faultaddress, /* Faultaddress */ 499239268Sgonzo 500239268Sgonzo /* TLB functions */ 501239268Sgonzo 502239268Sgonzo armv7_tlb_flushID, /* tlb_flushID */ 503239268Sgonzo armv7_tlb_flushID_SE, /* tlb_flushID_SE */ 504239268Sgonzo armv7_tlb_flushID, /* tlb_flushI */ 505239268Sgonzo armv7_tlb_flushID_SE, /* tlb_flushI_SE */ 506239268Sgonzo armv7_tlb_flushID, /* tlb_flushD */ 507239268Sgonzo armv7_tlb_flushID_SE, /* tlb_flushD_SE */ 508239268Sgonzo 509239268Sgonzo /* Cache operations */ 510239268Sgonzo armv7_idcache_wbinv_all, /* icache_sync_all */ 511239268Sgonzo armv7_icache_sync_range, /* icache_sync_range */ 512239268Sgonzo 513239268Sgonzo armv7_dcache_wbinv_all, /* dcache_wbinv_all */ 514239268Sgonzo armv7_dcache_wbinv_range, /* dcache_wbinv_range */ 515239268Sgonzo armv7_dcache_inv_range, /* dcache_inv_range */ 516239268Sgonzo armv7_dcache_wb_range, /* dcache_wb_range */ 517239268Sgonzo 518239268Sgonzo armv7_idcache_wbinv_all, /* idcache_wbinv_all */ 519239268Sgonzo armv7_idcache_wbinv_range, /* idcache_wbinv_all */ 520239268Sgonzo 521239268Sgonzo (void *)cpufunc_nullop, /* l2cache_wbinv_all */ 522239268Sgonzo (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 523239268Sgonzo (void *)cpufunc_nullop, /* l2cache_inv_range */ 524239268Sgonzo (void *)cpufunc_nullop, /* l2cache_wb_range */ 525239268Sgonzo 526239268Sgonzo /* Other functions */ 527239268Sgonzo 528239268Sgonzo pj4b_drain_readbuf, /* flush_prefetchbuf */ 529239268Sgonzo arm11_drain_writebuf, /* drain_writebuf */ 530239268Sgonzo pj4b_flush_brnchtgt_all, /* flush_brnchtgt_C */ 531239268Sgonzo pj4b_flush_brnchtgt_va, /* flush_brnchtgt_E */ 532239268Sgonzo 533239268Sgonzo (void *)cpufunc_nullop, /* sleep */ 534239268Sgonzo 535239268Sgonzo /* Soft functions */ 536239268Sgonzo 537239268Sgonzo cpufunc_null_fixup, /* dataabt_fixup */ 538239268Sgonzo cpufunc_null_fixup, /* prefetchabt_fixup */ 539239268Sgonzo 540239268Sgonzo arm11_context_switch, /* context_switch */ 541239268Sgonzo 542239268Sgonzo pj4bv7_setup /* cpu setup */ 543239268Sgonzo}; 544239268Sgonzo 545239268Sgonzostruct cpu_functions pj4bv6_cpufuncs = { 546239268Sgonzo /* CPU functions */ 547239268Sgonzo 548239268Sgonzo cpufunc_id, /* id */ 549239268Sgonzo arm11_drain_writebuf, /* cpwait */ 550239268Sgonzo 551239268Sgonzo /* MMU functions */ 552239268Sgonzo 553239268Sgonzo cpufunc_control, /* control */ 554239268Sgonzo cpufunc_domains, /* Domain */ 555239268Sgonzo pj4b_setttb, /* Setttb */ 556239268Sgonzo cpufunc_faultstatus, /* Faultstatus */ 557239268Sgonzo cpufunc_faultaddress, /* Faultaddress */ 558239268Sgonzo 559239268Sgonzo /* TLB functions */ 560239268Sgonzo 561239268Sgonzo arm11_tlb_flushID, /* tlb_flushID */ 562239268Sgonzo arm11_tlb_flushID_SE, /* tlb_flushID_SE */ 563239268Sgonzo arm11_tlb_flushI, /* tlb_flushI */ 564239268Sgonzo arm11_tlb_flushI_SE, /* tlb_flushI_SE */ 565239268Sgonzo arm11_tlb_flushD, /* tlb_flushD */ 566239268Sgonzo arm11_tlb_flushD_SE, /* tlb_flushD_SE */ 567239268Sgonzo 568239268Sgonzo /* Cache operations */ 569239268Sgonzo armv6_icache_sync_all, /* icache_sync_all */ 570239268Sgonzo pj4b_icache_sync_range, /* icache_sync_range */ 571239268Sgonzo 572239268Sgonzo armv6_dcache_wbinv_all, /* dcache_wbinv_all */ 573239268Sgonzo pj4b_dcache_wbinv_range, /* dcache_wbinv_range */ 574239268Sgonzo pj4b_dcache_inv_range, /* dcache_inv_range */ 575239268Sgonzo pj4b_dcache_wb_range, /* dcache_wb_range */ 576239268Sgonzo 577239268Sgonzo armv6_idcache_wbinv_all, /* idcache_wbinv_all */ 578239268Sgonzo pj4b_idcache_wbinv_range, /* idcache_wbinv_all */ 579239268Sgonzo 580239268Sgonzo (void *)cpufunc_nullop, /* l2cache_wbinv_all */ 581239268Sgonzo (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 582239268Sgonzo (void *)cpufunc_nullop, /* l2cache_inv_range */ 583239268Sgonzo (void *)cpufunc_nullop, /* l2cache_wb_range */ 584239268Sgonzo 585239268Sgonzo /* Other functions */ 586239268Sgonzo 587239268Sgonzo pj4b_drain_readbuf, /* flush_prefetchbuf */ 588239268Sgonzo arm11_drain_writebuf, /* drain_writebuf */ 589239268Sgonzo pj4b_flush_brnchtgt_all, /* flush_brnchtgt_C */ 590239268Sgonzo pj4b_flush_brnchtgt_va, /* flush_brnchtgt_E */ 591239268Sgonzo 592239268Sgonzo (void *)cpufunc_nullop, /* sleep */ 593239268Sgonzo 594239268Sgonzo /* Soft functions */ 595239268Sgonzo 596239268Sgonzo cpufunc_null_fixup, /* dataabt_fixup */ 597239268Sgonzo cpufunc_null_fixup, /* prefetchabt_fixup */ 598239268Sgonzo 599239268Sgonzo arm11_context_switch, /* context_switch */ 600239268Sgonzo 601239268Sgonzo pj4bv6_setup /* cpu setup */ 602239268Sgonzo}; 603239268Sgonzo#endif /* CPU_MV_PJ4B */ 604239268Sgonzo 605129198Scognet#ifdef CPU_SA110 606129198Scognetstruct cpu_functions sa110_cpufuncs = { 607129198Scognet /* CPU functions */ 608129198Scognet 609129198Scognet cpufunc_id, /* id */ 610129198Scognet cpufunc_nullop, /* cpwait */ 611129198Scognet 612129198Scognet /* MMU functions */ 613129198Scognet 614129198Scognet cpufunc_control, /* control */ 615129198Scognet cpufunc_domains, /* domain */ 616129198Scognet sa1_setttb, /* setttb */ 617129198Scognet cpufunc_faultstatus, /* faultstatus */ 618129198Scognet cpufunc_faultaddress, /* faultaddress */ 619129198Scognet 620129198Scognet /* TLB functions */ 621129198Scognet 622129198Scognet armv4_tlb_flushID, /* tlb_flushID */ 623129198Scognet sa1_tlb_flushID_SE, /* tlb_flushID_SE */ 624129198Scognet armv4_tlb_flushI, /* tlb_flushI */ 625129198Scognet (void *)armv4_tlb_flushI, /* tlb_flushI_SE */ 626129198Scognet armv4_tlb_flushD, /* tlb_flushD */ 627129198Scognet armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 628129198Scognet 629129198Scognet /* Cache operations */ 630129198Scognet 631129198Scognet sa1_cache_syncI, /* icache_sync_all */ 632129198Scognet sa1_cache_syncI_rng, /* icache_sync_range */ 633129198Scognet 634129198Scognet sa1_cache_purgeD, /* dcache_wbinv_all */ 635129198Scognet sa1_cache_purgeD_rng, /* dcache_wbinv_range */ 636129198Scognet/*XXX*/ sa1_cache_purgeD_rng, /* dcache_inv_range */ 637129198Scognet sa1_cache_cleanD_rng, /* dcache_wb_range */ 638129198Scognet 639129198Scognet sa1_cache_purgeID, /* idcache_wbinv_all */ 640129198Scognet sa1_cache_purgeID_rng, /* idcache_wbinv_range */ 641171618Scognet cpufunc_nullop, /* l2cache_wbinv_all */ 642171781Scognet (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 643171781Scognet (void *)cpufunc_nullop, /* l2cache_inv_range */ 644171781Scognet (void *)cpufunc_nullop, /* l2cache_wb_range */ 645129198Scognet 646129198Scognet /* Other functions */ 647129198Scognet 648129198Scognet cpufunc_nullop, /* flush_prefetchbuf */ 649129198Scognet armv4_drain_writebuf, /* drain_writebuf */ 650129198Scognet cpufunc_nullop, /* flush_brnchtgt_C */ 651129198Scognet (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 652129198Scognet 653129198Scognet (void *)cpufunc_nullop, /* sleep */ 654129198Scognet 655129198Scognet /* Soft functions */ 656129198Scognet 657129198Scognet cpufunc_null_fixup, /* dataabt_fixup */ 658129198Scognet cpufunc_null_fixup, /* prefetchabt_fixup */ 659129198Scognet 660129198Scognet sa110_context_switch, /* context_switch */ 661129198Scognet 662129198Scognet sa110_setup /* cpu setup */ 663236991Simp}; 664129198Scognet#endif /* CPU_SA110 */ 665129198Scognet 666129198Scognet#if defined(CPU_SA1100) || defined(CPU_SA1110) 667129198Scognetstruct cpu_functions sa11x0_cpufuncs = { 668129198Scognet /* CPU functions */ 669129198Scognet 670129198Scognet cpufunc_id, /* id */ 671129198Scognet cpufunc_nullop, /* cpwait */ 672129198Scognet 673129198Scognet /* MMU functions */ 674129198Scognet 675129198Scognet cpufunc_control, /* control */ 676129198Scognet cpufunc_domains, /* domain */ 677129198Scognet sa1_setttb, /* setttb */ 678129198Scognet cpufunc_faultstatus, /* faultstatus */ 679129198Scognet cpufunc_faultaddress, /* faultaddress */ 680129198Scognet 681129198Scognet /* TLB functions */ 682129198Scognet 683129198Scognet armv4_tlb_flushID, /* tlb_flushID */ 684129198Scognet sa1_tlb_flushID_SE, /* tlb_flushID_SE */ 685129198Scognet armv4_tlb_flushI, /* tlb_flushI */ 686129198Scognet (void *)armv4_tlb_flushI, /* tlb_flushI_SE */ 687129198Scognet armv4_tlb_flushD, /* tlb_flushD */ 688129198Scognet armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 689129198Scognet 690129198Scognet /* Cache operations */ 691129198Scognet 692129198Scognet sa1_cache_syncI, /* icache_sync_all */ 693129198Scognet sa1_cache_syncI_rng, /* icache_sync_range */ 694129198Scognet 695129198Scognet sa1_cache_purgeD, /* dcache_wbinv_all */ 696129198Scognet sa1_cache_purgeD_rng, /* dcache_wbinv_range */ 697129198Scognet/*XXX*/ sa1_cache_purgeD_rng, /* dcache_inv_range */ 698129198Scognet sa1_cache_cleanD_rng, /* dcache_wb_range */ 699129198Scognet 700129198Scognet sa1_cache_purgeID, /* idcache_wbinv_all */ 701129198Scognet sa1_cache_purgeID_rng, /* idcache_wbinv_range */ 702171618Scognet cpufunc_nullop, /* l2cache_wbinv_all */ 703171781Scognet (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 704171781Scognet (void *)cpufunc_nullop, /* l2cache_inv_range */ 705171781Scognet (void *)cpufunc_nullop, /* l2cache_wb_range */ 706129198Scognet 707129198Scognet /* Other functions */ 708129198Scognet 709129198Scognet sa11x0_drain_readbuf, /* flush_prefetchbuf */ 710129198Scognet armv4_drain_writebuf, /* drain_writebuf */ 711129198Scognet cpufunc_nullop, /* flush_brnchtgt_C */ 712129198Scognet (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 713129198Scognet 714129198Scognet sa11x0_cpu_sleep, /* sleep */ 715129198Scognet 716129198Scognet /* Soft functions */ 717129198Scognet 718129198Scognet cpufunc_null_fixup, /* dataabt_fixup */ 719129198Scognet cpufunc_null_fixup, /* prefetchabt_fixup */ 720129198Scognet 721129198Scognet sa11x0_context_switch, /* context_switch */ 722129198Scognet 723129198Scognet sa11x0_setup /* cpu setup */ 724236991Simp}; 725129198Scognet#endif /* CPU_SA1100 || CPU_SA1110 */ 726129198Scognet 727129198Scognet#ifdef CPU_IXP12X0 728129198Scognetstruct cpu_functions ixp12x0_cpufuncs = { 729129198Scognet /* CPU functions */ 730129198Scognet 731129198Scognet cpufunc_id, /* id */ 732129198Scognet cpufunc_nullop, /* cpwait */ 733129198Scognet 734129198Scognet /* MMU functions */ 735129198Scognet 736129198Scognet cpufunc_control, /* control */ 737129198Scognet cpufunc_domains, /* domain */ 738129198Scognet sa1_setttb, /* setttb */ 739129198Scognet cpufunc_faultstatus, /* faultstatus */ 740129198Scognet cpufunc_faultaddress, /* faultaddress */ 741129198Scognet 742129198Scognet /* TLB functions */ 743129198Scognet 744129198Scognet armv4_tlb_flushID, /* tlb_flushID */ 745129198Scognet sa1_tlb_flushID_SE, /* tlb_flushID_SE */ 746129198Scognet armv4_tlb_flushI, /* tlb_flushI */ 747129198Scognet (void *)armv4_tlb_flushI, /* tlb_flushI_SE */ 748129198Scognet armv4_tlb_flushD, /* tlb_flushD */ 749129198Scognet armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 750129198Scognet 751129198Scognet /* Cache operations */ 752129198Scognet 753129198Scognet sa1_cache_syncI, /* icache_sync_all */ 754129198Scognet sa1_cache_syncI_rng, /* icache_sync_range */ 755129198Scognet 756129198Scognet sa1_cache_purgeD, /* dcache_wbinv_all */ 757129198Scognet sa1_cache_purgeD_rng, /* dcache_wbinv_range */ 758129198Scognet/*XXX*/ sa1_cache_purgeD_rng, /* dcache_inv_range */ 759129198Scognet sa1_cache_cleanD_rng, /* dcache_wb_range */ 760129198Scognet 761129198Scognet sa1_cache_purgeID, /* idcache_wbinv_all */ 762129198Scognet sa1_cache_purgeID_rng, /* idcache_wbinv_range */ 763171618Scognet cpufunc_nullop, /* l2cache_wbinv_all */ 764171781Scognet (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 765171781Scognet (void *)cpufunc_nullop, /* l2cache_inv_range */ 766171781Scognet (void *)cpufunc_nullop, /* l2cache_wb_range */ 767129198Scognet 768129198Scognet /* Other functions */ 769129198Scognet 770129198Scognet ixp12x0_drain_readbuf, /* flush_prefetchbuf */ 771129198Scognet armv4_drain_writebuf, /* drain_writebuf */ 772129198Scognet cpufunc_nullop, /* flush_brnchtgt_C */ 773129198Scognet (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 774129198Scognet 775129198Scognet (void *)cpufunc_nullop, /* sleep */ 776129198Scognet 777129198Scognet /* Soft functions */ 778129198Scognet 779129198Scognet cpufunc_null_fixup, /* dataabt_fixup */ 780129198Scognet cpufunc_null_fixup, /* prefetchabt_fixup */ 781129198Scognet 782129198Scognet ixp12x0_context_switch, /* context_switch */ 783129198Scognet 784129198Scognet ixp12x0_setup /* cpu setup */ 785236991Simp}; 786129198Scognet#endif /* CPU_IXP12X0 */ 787129198Scognet 788129198Scognet#if defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \ 789161592Scognet defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \ 790161592Scognet defined(CPU_XSCALE_80219) 791161592Scognet 792129198Scognetstruct cpu_functions xscale_cpufuncs = { 793129198Scognet /* CPU functions */ 794129198Scognet 795129198Scognet cpufunc_id, /* id */ 796129198Scognet xscale_cpwait, /* cpwait */ 797129198Scognet 798129198Scognet /* MMU functions */ 799129198Scognet 800129198Scognet xscale_control, /* control */ 801129198Scognet cpufunc_domains, /* domain */ 802129198Scognet xscale_setttb, /* setttb */ 803129198Scognet cpufunc_faultstatus, /* faultstatus */ 804129198Scognet cpufunc_faultaddress, /* faultaddress */ 805129198Scognet 806129198Scognet /* TLB functions */ 807129198Scognet 808129198Scognet armv4_tlb_flushID, /* tlb_flushID */ 809129198Scognet xscale_tlb_flushID_SE, /* tlb_flushID_SE */ 810129198Scognet armv4_tlb_flushI, /* tlb_flushI */ 811129198Scognet (void *)armv4_tlb_flushI, /* tlb_flushI_SE */ 812129198Scognet armv4_tlb_flushD, /* tlb_flushD */ 813129198Scognet armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 814129198Scognet 815129198Scognet /* Cache operations */ 816129198Scognet 817129198Scognet xscale_cache_syncI, /* icache_sync_all */ 818129198Scognet xscale_cache_syncI_rng, /* icache_sync_range */ 819129198Scognet 820129198Scognet xscale_cache_purgeD, /* dcache_wbinv_all */ 821129198Scognet xscale_cache_purgeD_rng, /* dcache_wbinv_range */ 822129198Scognet xscale_cache_flushD_rng, /* dcache_inv_range */ 823129198Scognet xscale_cache_cleanD_rng, /* dcache_wb_range */ 824129198Scognet 825129198Scognet xscale_cache_purgeID, /* idcache_wbinv_all */ 826129198Scognet xscale_cache_purgeID_rng, /* idcache_wbinv_range */ 827171618Scognet cpufunc_nullop, /* l2cache_wbinv_all */ 828171781Scognet (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 829171781Scognet (void *)cpufunc_nullop, /* l2cache_inv_range */ 830171781Scognet (void *)cpufunc_nullop, /* l2cache_wb_range */ 831129198Scognet 832129198Scognet /* Other functions */ 833129198Scognet 834129198Scognet cpufunc_nullop, /* flush_prefetchbuf */ 835129198Scognet armv4_drain_writebuf, /* drain_writebuf */ 836129198Scognet cpufunc_nullop, /* flush_brnchtgt_C */ 837129198Scognet (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 838129198Scognet 839129198Scognet xscale_cpu_sleep, /* sleep */ 840129198Scognet 841129198Scognet /* Soft functions */ 842129198Scognet 843129198Scognet cpufunc_null_fixup, /* dataabt_fixup */ 844129198Scognet cpufunc_null_fixup, /* prefetchabt_fixup */ 845129198Scognet 846129198Scognet xscale_context_switch, /* context_switch */ 847129198Scognet 848129198Scognet xscale_setup /* cpu setup */ 849129198Scognet}; 850129198Scognet#endif 851161592Scognet/* CPU_XSCALE_80200 || CPU_XSCALE_80321 || CPU_XSCALE_PXA2X0 || CPU_XSCALE_IXP425 852161592Scognet CPU_XSCALE_80219 */ 853129198Scognet 854164080Scognet#ifdef CPU_XSCALE_81342 855164080Scognetstruct cpu_functions xscalec3_cpufuncs = { 856164080Scognet /* CPU functions */ 857164080Scognet 858164080Scognet cpufunc_id, /* id */ 859164080Scognet xscale_cpwait, /* cpwait */ 860164080Scognet 861164080Scognet /* MMU functions */ 862164080Scognet 863164080Scognet xscale_control, /* control */ 864164080Scognet cpufunc_domains, /* domain */ 865164080Scognet xscalec3_setttb, /* setttb */ 866164080Scognet cpufunc_faultstatus, /* faultstatus */ 867164080Scognet cpufunc_faultaddress, /* faultaddress */ 868164080Scognet 869164080Scognet /* TLB functions */ 870164080Scognet 871164080Scognet armv4_tlb_flushID, /* tlb_flushID */ 872164080Scognet xscale_tlb_flushID_SE, /* tlb_flushID_SE */ 873164080Scognet armv4_tlb_flushI, /* tlb_flushI */ 874164080Scognet (void *)armv4_tlb_flushI, /* tlb_flushI_SE */ 875164080Scognet armv4_tlb_flushD, /* tlb_flushD */ 876164080Scognet armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 877164080Scognet 878164080Scognet /* Cache operations */ 879164080Scognet 880164080Scognet xscalec3_cache_syncI, /* icache_sync_all */ 881171618Scognet xscalec3_cache_syncI_rng, /* icache_sync_range */ 882164080Scognet 883164080Scognet xscalec3_cache_purgeD, /* dcache_wbinv_all */ 884164080Scognet xscalec3_cache_purgeD_rng, /* dcache_wbinv_range */ 885164080Scognet xscale_cache_flushD_rng, /* dcache_inv_range */ 886164080Scognet xscalec3_cache_cleanD_rng, /* dcache_wb_range */ 887164080Scognet 888171618Scognet xscalec3_cache_purgeID, /* idcache_wbinv_all */ 889164080Scognet xscalec3_cache_purgeID_rng, /* idcache_wbinv_range */ 890171618Scognet xscalec3_l2cache_purge, /* l2cache_wbinv_all */ 891171618Scognet xscalec3_l2cache_purge_rng, /* l2cache_wbinv_range */ 892171618Scognet xscalec3_l2cache_flush_rng, /* l2cache_inv_range */ 893171618Scognet xscalec3_l2cache_clean_rng, /* l2cache_wb_range */ 894164080Scognet 895164080Scognet /* Other functions */ 896164080Scognet 897164080Scognet cpufunc_nullop, /* flush_prefetchbuf */ 898164080Scognet armv4_drain_writebuf, /* drain_writebuf */ 899164080Scognet cpufunc_nullop, /* flush_brnchtgt_C */ 900164080Scognet (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 901164080Scognet 902164080Scognet xscale_cpu_sleep, /* sleep */ 903164080Scognet 904164080Scognet /* Soft functions */ 905164080Scognet 906164080Scognet cpufunc_null_fixup, /* dataabt_fixup */ 907164080Scognet cpufunc_null_fixup, /* prefetchabt_fixup */ 908164080Scognet 909164080Scognet xscalec3_context_switch, /* context_switch */ 910164080Scognet 911164080Scognet xscale_setup /* cpu setup */ 912164080Scognet}; 913164080Scognet#endif /* CPU_XSCALE_81342 */ 914201468Srpaulo 915201468Srpaulo 916207611Skevlo#if defined(CPU_FA526) || defined(CPU_FA626TE) 917201468Srpaulostruct cpu_functions fa526_cpufuncs = { 918201468Srpaulo /* CPU functions */ 919201468Srpaulo 920207611Skevlo cpufunc_id, /* id */ 921207611Skevlo cpufunc_nullop, /* cpwait */ 922201468Srpaulo 923201468Srpaulo /* MMU functions */ 924201468Srpaulo 925207611Skevlo cpufunc_control, /* control */ 926207611Skevlo cpufunc_domains, /* domain */ 927207611Skevlo fa526_setttb, /* setttb */ 928207611Skevlo cpufunc_faultstatus, /* faultstatus */ 929207611Skevlo cpufunc_faultaddress, /* faultaddress */ 930201468Srpaulo 931201468Srpaulo /* TLB functions */ 932201468Srpaulo 933207611Skevlo armv4_tlb_flushID, /* tlb_flushID */ 934207611Skevlo fa526_tlb_flushID_SE, /* tlb_flushID_SE */ 935207611Skevlo armv4_tlb_flushI, /* tlb_flushI */ 936207611Skevlo fa526_tlb_flushI_SE, /* tlb_flushI_SE */ 937207611Skevlo armv4_tlb_flushD, /* tlb_flushD */ 938207611Skevlo armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 939201468Srpaulo 940201468Srpaulo /* Cache operations */ 941201468Srpaulo 942207611Skevlo fa526_icache_sync_all, /* icache_sync_all */ 943207611Skevlo fa526_icache_sync_range, /* icache_sync_range */ 944201468Srpaulo 945207611Skevlo fa526_dcache_wbinv_all, /* dcache_wbinv_all */ 946207611Skevlo fa526_dcache_wbinv_range, /* dcache_wbinv_range */ 947207611Skevlo fa526_dcache_inv_range, /* dcache_inv_range */ 948207611Skevlo fa526_dcache_wb_range, /* dcache_wb_range */ 949201468Srpaulo 950207611Skevlo fa526_idcache_wbinv_all, /* idcache_wbinv_all */ 951207611Skevlo fa526_idcache_wbinv_range, /* idcache_wbinv_range */ 952207611Skevlo cpufunc_nullop, /* l2cache_wbinv_all */ 953207611Skevlo (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 954207611Skevlo (void *)cpufunc_nullop, /* l2cache_inv_range */ 955207611Skevlo (void *)cpufunc_nullop, /* l2cache_wb_range */ 956201468Srpaulo 957201468Srpaulo /* Other functions */ 958201468Srpaulo 959207611Skevlo fa526_flush_prefetchbuf, /* flush_prefetchbuf */ 960207611Skevlo armv4_drain_writebuf, /* drain_writebuf */ 961207611Skevlo cpufunc_nullop, /* flush_brnchtgt_C */ 962207611Skevlo fa526_flush_brnchtgt_E, /* flush_brnchtgt_E */ 963201468Srpaulo 964207611Skevlo fa526_cpu_sleep, /* sleep */ 965201468Srpaulo 966201468Srpaulo /* Soft functions */ 967201468Srpaulo 968207611Skevlo cpufunc_null_fixup, /* dataabt_fixup */ 969207611Skevlo cpufunc_null_fixup, /* prefetchabt_fixup */ 970201468Srpaulo 971207611Skevlo fa526_context_switch, /* context_switch */ 972201468Srpaulo 973207611Skevlo fa526_setup /* cpu setup */ 974236991Simp}; 975207611Skevlo#endif /* CPU_FA526 || CPU_FA626TE */ 976201468Srpaulo 977244480Sgonzo#if defined(CPU_ARM1136) 978244480Sgonzostruct cpu_functions arm1136_cpufuncs = { 979239701Sgonzo /* CPU functions */ 980239701Sgonzo 981239701Sgonzo cpufunc_id, /* id */ 982244480Sgonzo cpufunc_nullop, /* cpwait */ 983239701Sgonzo 984239701Sgonzo /* MMU functions */ 985239701Sgonzo 986239701Sgonzo cpufunc_control, /* control */ 987239701Sgonzo cpufunc_domains, /* Domain */ 988244480Sgonzo arm11x6_setttb, /* Setttb */ 989239701Sgonzo cpufunc_faultstatus, /* Faultstatus */ 990239701Sgonzo cpufunc_faultaddress, /* Faultaddress */ 991239701Sgonzo 992239701Sgonzo /* TLB functions */ 993239701Sgonzo 994239701Sgonzo arm11_tlb_flushID, /* tlb_flushID */ 995239701Sgonzo arm11_tlb_flushID_SE, /* tlb_flushID_SE */ 996239701Sgonzo arm11_tlb_flushI, /* tlb_flushI */ 997239701Sgonzo arm11_tlb_flushI_SE, /* tlb_flushI_SE */ 998239701Sgonzo arm11_tlb_flushD, /* tlb_flushD */ 999239701Sgonzo arm11_tlb_flushD_SE, /* tlb_flushD_SE */ 1000239701Sgonzo 1001239701Sgonzo /* Cache operations */ 1002239701Sgonzo 1003244480Sgonzo arm11x6_icache_sync_all, /* icache_sync_all */ 1004244480Sgonzo arm11x6_icache_sync_range, /* icache_sync_range */ 1005239701Sgonzo 1006244480Sgonzo arm11x6_dcache_wbinv_all, /* dcache_wbinv_all */ 1007239701Sgonzo armv6_dcache_wbinv_range, /* dcache_wbinv_range */ 1008239701Sgonzo armv6_dcache_inv_range, /* dcache_inv_range */ 1009239701Sgonzo armv6_dcache_wb_range, /* dcache_wb_range */ 1010239701Sgonzo 1011244480Sgonzo arm11x6_idcache_wbinv_all, /* idcache_wbinv_all */ 1012244480Sgonzo arm11x6_idcache_wbinv_range, /* idcache_wbinv_range */ 1013239701Sgonzo 1014244480Sgonzo (void *)cpufunc_nullop, /* l2cache_wbinv_all */ 1015239701Sgonzo (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 1016239701Sgonzo (void *)cpufunc_nullop, /* l2cache_inv_range */ 1017239701Sgonzo (void *)cpufunc_nullop, /* l2cache_wb_range */ 1018239701Sgonzo 1019239701Sgonzo /* Other functions */ 1020239701Sgonzo 1021244480Sgonzo arm11x6_flush_prefetchbuf, /* flush_prefetchbuf */ 1022239701Sgonzo arm11_drain_writebuf, /* drain_writebuf */ 1023239701Sgonzo cpufunc_nullop, /* flush_brnchtgt_C */ 1024239701Sgonzo (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 1025239701Sgonzo 1026244480Sgonzo arm11_sleep, /* sleep */ 1027239701Sgonzo 1028239701Sgonzo /* Soft functions */ 1029239701Sgonzo 1030239701Sgonzo cpufunc_null_fixup, /* dataabt_fixup */ 1031239701Sgonzo cpufunc_null_fixup, /* prefetchabt_fixup */ 1032239701Sgonzo 1033239701Sgonzo arm11_context_switch, /* context_switch */ 1034239701Sgonzo 1035244480Sgonzo arm11x6_setup /* cpu setup */ 1036239701Sgonzo}; 1037244480Sgonzo#endif /* CPU_ARM1136 */ 1038244480Sgonzo#if defined(CPU_ARM1176) 1039244480Sgonzostruct cpu_functions arm1176_cpufuncs = { 1040244480Sgonzo /* CPU functions */ 1041244480Sgonzo 1042244480Sgonzo cpufunc_id, /* id */ 1043244480Sgonzo cpufunc_nullop, /* cpwait */ 1044244480Sgonzo 1045244480Sgonzo /* MMU functions */ 1046244480Sgonzo 1047244480Sgonzo cpufunc_control, /* control */ 1048244480Sgonzo cpufunc_domains, /* Domain */ 1049244480Sgonzo arm11x6_setttb, /* Setttb */ 1050244480Sgonzo cpufunc_faultstatus, /* Faultstatus */ 1051244480Sgonzo cpufunc_faultaddress, /* Faultaddress */ 1052244480Sgonzo 1053244480Sgonzo /* TLB functions */ 1054244480Sgonzo 1055244480Sgonzo arm11_tlb_flushID, /* tlb_flushID */ 1056244480Sgonzo arm11_tlb_flushID_SE, /* tlb_flushID_SE */ 1057244480Sgonzo arm11_tlb_flushI, /* tlb_flushI */ 1058244480Sgonzo arm11_tlb_flushI_SE, /* tlb_flushI_SE */ 1059244480Sgonzo arm11_tlb_flushD, /* tlb_flushD */ 1060244480Sgonzo arm11_tlb_flushD_SE, /* tlb_flushD_SE */ 1061244480Sgonzo 1062244480Sgonzo /* Cache operations */ 1063244480Sgonzo 1064244480Sgonzo arm11x6_icache_sync_all, /* icache_sync_all */ 1065244480Sgonzo arm11x6_icache_sync_range, /* icache_sync_range */ 1066244480Sgonzo 1067244480Sgonzo arm11x6_dcache_wbinv_all, /* dcache_wbinv_all */ 1068244480Sgonzo armv6_dcache_wbinv_range, /* dcache_wbinv_range */ 1069244480Sgonzo armv6_dcache_inv_range, /* dcache_inv_range */ 1070244480Sgonzo armv6_dcache_wb_range, /* dcache_wb_range */ 1071244480Sgonzo 1072244480Sgonzo arm11x6_idcache_wbinv_all, /* idcache_wbinv_all */ 1073244480Sgonzo arm11x6_idcache_wbinv_range, /* idcache_wbinv_range */ 1074244480Sgonzo 1075244480Sgonzo (void *)cpufunc_nullop, /* l2cache_wbinv_all */ 1076244480Sgonzo (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 1077244480Sgonzo (void *)cpufunc_nullop, /* l2cache_inv_range */ 1078244480Sgonzo (void *)cpufunc_nullop, /* l2cache_wb_range */ 1079244480Sgonzo 1080244480Sgonzo /* Other functions */ 1081244480Sgonzo 1082244480Sgonzo arm11x6_flush_prefetchbuf, /* flush_prefetchbuf */ 1083244480Sgonzo arm11_drain_writebuf, /* drain_writebuf */ 1084244480Sgonzo cpufunc_nullop, /* flush_brnchtgt_C */ 1085244480Sgonzo (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 1086244480Sgonzo 1087244480Sgonzo arm11x6_sleep, /* sleep */ 1088244480Sgonzo 1089244480Sgonzo /* Soft functions */ 1090244480Sgonzo 1091244480Sgonzo cpufunc_null_fixup, /* dataabt_fixup */ 1092244480Sgonzo cpufunc_null_fixup, /* prefetchabt_fixup */ 1093244480Sgonzo 1094244480Sgonzo arm11_context_switch, /* context_switch */ 1095244480Sgonzo 1096244480Sgonzo arm11x6_setup /* cpu setup */ 1097244480Sgonzo}; 1098244480Sgonzo#endif /*CPU_ARM1176 */ 1099239701Sgonzo 1100239268Sgonzo#if defined(CPU_CORTEXA) 1101239268Sgonzostruct cpu_functions cortexa_cpufuncs = { 1102239268Sgonzo /* CPU functions */ 1103239268Sgonzo 1104239268Sgonzo cpufunc_id, /* id */ 1105239268Sgonzo cpufunc_nullop, /* cpwait */ 1106239268Sgonzo 1107239268Sgonzo /* MMU functions */ 1108239268Sgonzo 1109239268Sgonzo cpufunc_control, /* control */ 1110239268Sgonzo cpufunc_domains, /* Domain */ 1111239268Sgonzo armv7_setttb, /* Setttb */ 1112239268Sgonzo cpufunc_faultstatus, /* Faultstatus */ 1113239268Sgonzo cpufunc_faultaddress, /* Faultaddress */ 1114239268Sgonzo 1115239268Sgonzo /* TLB functions */ 1116239268Sgonzo 1117243024Scognet armv7_tlb_flushID, /* tlb_flushID */ 1118239268Sgonzo armv7_tlb_flushID_SE, /* tlb_flushID_SE */ 1119239268Sgonzo arm11_tlb_flushI, /* tlb_flushI */ 1120239268Sgonzo arm11_tlb_flushI_SE, /* tlb_flushI_SE */ 1121239268Sgonzo arm11_tlb_flushD, /* tlb_flushD */ 1122239268Sgonzo arm11_tlb_flushD_SE, /* tlb_flushD_SE */ 1123239268Sgonzo 1124239268Sgonzo /* Cache operations */ 1125239268Sgonzo 1126239268Sgonzo armv7_idcache_wbinv_all, /* icache_sync_all */ 1127239268Sgonzo armv7_icache_sync_range, /* icache_sync_range */ 1128239268Sgonzo 1129239268Sgonzo armv7_dcache_wbinv_all, /* dcache_wbinv_all */ 1130239268Sgonzo armv7_dcache_wbinv_range, /* dcache_wbinv_range */ 1131239268Sgonzo armv7_dcache_inv_range, /* dcache_inv_range */ 1132239268Sgonzo armv7_dcache_wb_range, /* dcache_wb_range */ 1133239268Sgonzo 1134239268Sgonzo armv7_idcache_wbinv_all, /* idcache_wbinv_all */ 1135239268Sgonzo armv7_idcache_wbinv_range, /* idcache_wbinv_range */ 1136239268Sgonzo 1137243026Scognet /* 1138243026Scognet * Note: For CPUs using the PL310 the L2 ops are filled in when the 1139239268Sgonzo * L2 cache controller is actually enabled. 1140239268Sgonzo */ 1141239268Sgonzo cpufunc_nullop, /* l2cache_wbinv_all */ 1142239268Sgonzo (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 1143239268Sgonzo (void *)cpufunc_nullop, /* l2cache_inv_range */ 1144239268Sgonzo (void *)cpufunc_nullop, /* l2cache_wb_range */ 1145239268Sgonzo 1146239268Sgonzo /* Other functions */ 1147239268Sgonzo 1148239268Sgonzo cpufunc_nullop, /* flush_prefetchbuf */ 1149245478Scognet armv7_drain_writebuf, /* drain_writebuf */ 1150239268Sgonzo cpufunc_nullop, /* flush_brnchtgt_C */ 1151239268Sgonzo (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 1152239268Sgonzo 1153239268Sgonzo arm11_sleep, /* sleep */ 1154239268Sgonzo 1155239268Sgonzo /* Soft functions */ 1156239268Sgonzo 1157239268Sgonzo cpufunc_null_fixup, /* dataabt_fixup */ 1158239268Sgonzo cpufunc_null_fixup, /* prefetchabt_fixup */ 1159239268Sgonzo 1160245478Scognet armv7_context_switch, /* context_switch */ 1161239268Sgonzo 1162239268Sgonzo cortexa_setup /* cpu setup */ 1163239268Sgonzo}; 1164239268Sgonzo#endif /* CPU_CORTEXA */ 1165201468Srpaulo 1166129198Scognet/* 1167129198Scognet * Global constants also used by locore.s 1168129198Scognet */ 1169129198Scognet 1170129198Scognetstruct cpu_functions cpufuncs; 1171129198Scognetu_int cputype; 1172129198Scognetu_int cpu_reset_needs_v4_MMU_disable; /* flag used in locore.s */ 1173129198Scognet 1174207611Skevlo#if defined(CPU_ARM7TDMI) || defined(CPU_ARM8) || defined(CPU_ARM9) || \ 1175244480Sgonzo defined (CPU_ARM9E) || defined (CPU_ARM10) || defined (CPU_ARM1136) || \ 1176244480Sgonzo defined(CPU_ARM1176) || defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \ 1177207611Skevlo defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \ 1178239268Sgonzo defined(CPU_FA526) || defined(CPU_FA626TE) || defined(CPU_MV_PJ4B) || \ 1179239268Sgonzo defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342) || \ 1180239268Sgonzo defined(CPU_CORTEXA) 1181161592Scognet 1182137498Strhodesstatic void get_cachetype_cp15(void); 1183129198Scognet 1184129198Scognet/* Additional cache information local to this file. Log2 of some of the 1185129198Scognet above numbers. */ 1186129198Scognetstatic int arm_dcache_l2_nsets; 1187129198Scognetstatic int arm_dcache_l2_assoc; 1188129198Scognetstatic int arm_dcache_l2_linesize; 1189129198Scognet 1190129198Scognetstatic void 1191129198Scognetget_cachetype_cp15() 1192129198Scognet{ 1193239268Sgonzo u_int ctype, isize, dsize, cpuid; 1194239268Sgonzo u_int clevel, csize, i, sel; 1195129198Scognet u_int multiplier; 1196239268Sgonzo u_char type; 1197129198Scognet 1198129198Scognet __asm __volatile("mrc p15, 0, %0, c0, c0, 1" 1199129198Scognet : "=r" (ctype)); 1200129198Scognet 1201239268Sgonzo cpuid = cpufunc_id(); 1202129198Scognet /* 1203129198Scognet * ...and thus spake the ARM ARM: 1204129198Scognet * 1205129198Scognet * If an <opcode2> value corresponding to an unimplemented or 1206129198Scognet * reserved ID register is encountered, the System Control 1207129198Scognet * processor returns the value of the main ID register. 1208129198Scognet */ 1209239268Sgonzo if (ctype == cpuid) 1210129198Scognet goto out; 1211129198Scognet 1212239268Sgonzo if (CPU_CT_FORMAT(ctype) == CPU_CT_ARMV7) { 1213239268Sgonzo __asm __volatile("mrc p15, 1, %0, c0, c0, 1" 1214239268Sgonzo : "=r" (clevel)); 1215239268Sgonzo arm_cache_level = clevel; 1216239268Sgonzo arm_cache_loc = CPU_CLIDR_LOC(arm_cache_level); 1217239268Sgonzo i = 0; 1218239268Sgonzo while ((type = (clevel & 0x7)) && i < 7) { 1219239268Sgonzo if (type == CACHE_DCACHE || type == CACHE_UNI_CACHE || 1220239268Sgonzo type == CACHE_SEP_CACHE) { 1221239268Sgonzo sel = i << 1; 1222239268Sgonzo __asm __volatile("mcr p15, 2, %0, c0, c0, 0" 1223239268Sgonzo : : "r" (sel)); 1224239268Sgonzo __asm __volatile("mrc p15, 1, %0, c0, c0, 0" 1225239268Sgonzo : "=r" (csize)); 1226239268Sgonzo arm_cache_type[sel] = csize; 1227239268Sgonzo arm_dcache_align = 1 << 1228239268Sgonzo (CPUV7_CT_xSIZE_LEN(csize) + 4); 1229239268Sgonzo arm_dcache_align_mask = arm_dcache_align - 1; 1230239268Sgonzo } 1231239268Sgonzo if (type == CACHE_ICACHE || type == CACHE_SEP_CACHE) { 1232239268Sgonzo sel = (i << 1) | 1; 1233239268Sgonzo __asm __volatile("mcr p15, 2, %0, c0, c0, 0" 1234239268Sgonzo : : "r" (sel)); 1235239268Sgonzo __asm __volatile("mrc p15, 1, %0, c0, c0, 0" 1236239268Sgonzo : "=r" (csize)); 1237239268Sgonzo arm_cache_type[sel] = csize; 1238239268Sgonzo } 1239239268Sgonzo i++; 1240239268Sgonzo clevel >>= 3; 1241239268Sgonzo } 1242239268Sgonzo } else { 1243239268Sgonzo if ((ctype & CPU_CT_S) == 0) 1244239268Sgonzo arm_pcache_unified = 1; 1245129198Scognet 1246239268Sgonzo /* 1247239268Sgonzo * If you want to know how this code works, go read the ARM ARM. 1248239268Sgonzo */ 1249129198Scognet 1250239268Sgonzo arm_pcache_type = CPU_CT_CTYPE(ctype); 1251129198Scognet 1252239268Sgonzo if (arm_pcache_unified == 0) { 1253239268Sgonzo isize = CPU_CT_ISIZE(ctype); 1254239268Sgonzo multiplier = (isize & CPU_CT_xSIZE_M) ? 3 : 2; 1255239268Sgonzo arm_picache_line_size = 1U << (CPU_CT_xSIZE_LEN(isize) + 3); 1256239268Sgonzo if (CPU_CT_xSIZE_ASSOC(isize) == 0) { 1257239268Sgonzo if (isize & CPU_CT_xSIZE_M) 1258239268Sgonzo arm_picache_line_size = 0; /* not present */ 1259239268Sgonzo else 1260239268Sgonzo arm_picache_ways = 1; 1261239268Sgonzo } else { 1262239268Sgonzo arm_picache_ways = multiplier << 1263239268Sgonzo (CPU_CT_xSIZE_ASSOC(isize) - 1); 1264239268Sgonzo } 1265239268Sgonzo arm_picache_size = multiplier << (CPU_CT_xSIZE_SIZE(isize) + 8); 1266239268Sgonzo } 1267239268Sgonzo 1268239268Sgonzo dsize = CPU_CT_DSIZE(ctype); 1269239268Sgonzo multiplier = (dsize & CPU_CT_xSIZE_M) ? 3 : 2; 1270239268Sgonzo arm_pdcache_line_size = 1U << (CPU_CT_xSIZE_LEN(dsize) + 3); 1271239268Sgonzo if (CPU_CT_xSIZE_ASSOC(dsize) == 0) { 1272239268Sgonzo if (dsize & CPU_CT_xSIZE_M) 1273239268Sgonzo arm_pdcache_line_size = 0; /* not present */ 1274129198Scognet else 1275239268Sgonzo arm_pdcache_ways = 1; 1276129198Scognet } else { 1277239268Sgonzo arm_pdcache_ways = multiplier << 1278239268Sgonzo (CPU_CT_xSIZE_ASSOC(dsize) - 1); 1279129198Scognet } 1280239268Sgonzo arm_pdcache_size = multiplier << (CPU_CT_xSIZE_SIZE(dsize) + 8); 1281129198Scognet 1282239268Sgonzo arm_dcache_align = arm_pdcache_line_size; 1283129198Scognet 1284239268Sgonzo arm_dcache_l2_assoc = CPU_CT_xSIZE_ASSOC(dsize) + multiplier - 2; 1285239268Sgonzo arm_dcache_l2_linesize = CPU_CT_xSIZE_LEN(dsize) + 3; 1286239268Sgonzo arm_dcache_l2_nsets = 6 + CPU_CT_xSIZE_SIZE(dsize) - 1287239268Sgonzo CPU_CT_xSIZE_ASSOC(dsize) - CPU_CT_xSIZE_LEN(dsize); 1288129198Scognet 1289239268Sgonzo out: 1290239268Sgonzo arm_dcache_align_mask = arm_dcache_align - 1; 1291239268Sgonzo } 1292129198Scognet} 1293129198Scognet#endif /* ARM7TDMI || ARM8 || ARM9 || XSCALE */ 1294129198Scognet 1295146619Scognet#if defined(CPU_SA110) || defined(CPU_SA1100) || defined(CPU_SA1110) || \ 1296146619Scognet defined(CPU_IXP12X0) 1297129198Scognet/* Cache information for CPUs without cache type registers. */ 1298129198Scognetstruct cachetab { 1299129198Scognet u_int32_t ct_cpuid; 1300129198Scognet int ct_pcache_type; 1301129198Scognet int ct_pcache_unified; 1302129198Scognet int ct_pdcache_size; 1303129198Scognet int ct_pdcache_line_size; 1304129198Scognet int ct_pdcache_ways; 1305129198Scognet int ct_picache_size; 1306129198Scognet int ct_picache_line_size; 1307129198Scognet int ct_picache_ways; 1308129198Scognet}; 1309129198Scognet 1310129198Scognetstruct cachetab cachetab[] = { 1311129198Scognet /* cpuid, cache type, u, dsiz, ls, wy, isiz, ls, wy */ 1312129198Scognet /* XXX is this type right for SA-1? */ 1313129198Scognet { CPU_ID_SA110, CPU_CT_CTYPE_WB1, 0, 16384, 32, 32, 16384, 32, 32 }, 1314129198Scognet { CPU_ID_SA1100, CPU_CT_CTYPE_WB1, 0, 8192, 32, 32, 16384, 32, 32 }, 1315129198Scognet { CPU_ID_SA1110, CPU_CT_CTYPE_WB1, 0, 8192, 32, 32, 16384, 32, 32 }, 1316129198Scognet { CPU_ID_IXP1200, CPU_CT_CTYPE_WB1, 0, 16384, 32, 32, 16384, 32, 32 }, /* XXX */ 1317129198Scognet { 0, 0, 0, 0, 0, 0, 0, 0} 1318129198Scognet}; 1319129198Scognet 1320137498Strhodesstatic void get_cachetype_table(void); 1321129198Scognet 1322129198Scognetstatic void 1323129198Scognetget_cachetype_table() 1324129198Scognet{ 1325129198Scognet int i; 1326129198Scognet u_int32_t cpuid = cpufunc_id(); 1327129198Scognet 1328129198Scognet for (i = 0; cachetab[i].ct_cpuid != 0; i++) { 1329129198Scognet if (cachetab[i].ct_cpuid == (cpuid & CPU_ID_CPU_MASK)) { 1330129198Scognet arm_pcache_type = cachetab[i].ct_pcache_type; 1331129198Scognet arm_pcache_unified = cachetab[i].ct_pcache_unified; 1332129198Scognet arm_pdcache_size = cachetab[i].ct_pdcache_size; 1333129198Scognet arm_pdcache_line_size = 1334129198Scognet cachetab[i].ct_pdcache_line_size; 1335129198Scognet arm_pdcache_ways = cachetab[i].ct_pdcache_ways; 1336129198Scognet arm_picache_size = cachetab[i].ct_picache_size; 1337129198Scognet arm_picache_line_size = 1338129198Scognet cachetab[i].ct_picache_line_size; 1339129198Scognet arm_picache_ways = cachetab[i].ct_picache_ways; 1340129198Scognet } 1341129198Scognet } 1342129198Scognet arm_dcache_align = arm_pdcache_line_size; 1343129198Scognet 1344129198Scognet arm_dcache_align_mask = arm_dcache_align - 1; 1345129198Scognet} 1346129198Scognet 1347146619Scognet#endif /* SA110 || SA1100 || SA1111 || IXP12X0 */ 1348129198Scognet 1349129198Scognet/* 1350129198Scognet * Cannot panic here as we may not have a console yet ... 1351129198Scognet */ 1352129198Scognet 1353129198Scognetint 1354129198Scognetset_cpufuncs() 1355129198Scognet{ 1356129198Scognet cputype = cpufunc_id(); 1357129198Scognet cputype &= CPU_ID_CPU_MASK; 1358129198Scognet 1359129198Scognet /* 1360129198Scognet * NOTE: cpu_do_powersave defaults to off. If we encounter a 1361129198Scognet * CPU type where we want to use it by default, then we set it. 1362129198Scognet */ 1363129198Scognet 1364129198Scognet#ifdef CPU_ARM7TDMI 1365129198Scognet if ((cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_ARM_LTD && 1366129198Scognet CPU_ID_IS7(cputype) && 1367129198Scognet (cputype & CPU_ID_7ARCH_MASK) == CPU_ID_7ARCH_V4T) { 1368129198Scognet cpufuncs = arm7tdmi_cpufuncs; 1369129198Scognet cpu_reset_needs_v4_MMU_disable = 0; 1370129198Scognet get_cachetype_cp15(); 1371129198Scognet pmap_pte_init_generic(); 1372166655Scognet goto out; 1373129198Scognet } 1374129198Scognet#endif 1375129198Scognet#ifdef CPU_ARM8 1376129198Scognet if ((cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_ARM_LTD && 1377129198Scognet (cputype & 0x0000f000) == 0x00008000) { 1378129198Scognet cpufuncs = arm8_cpufuncs; 1379129198Scognet cpu_reset_needs_v4_MMU_disable = 0; /* XXX correct? */ 1380129198Scognet get_cachetype_cp15(); 1381129198Scognet pmap_pte_init_arm8(); 1382166655Scognet goto out; 1383129198Scognet } 1384129198Scognet#endif /* CPU_ARM8 */ 1385129198Scognet#ifdef CPU_ARM9 1386129198Scognet if (((cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_ARM_LTD || 1387129198Scognet (cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_TI) && 1388129198Scognet (cputype & 0x0000f000) == 0x00009000) { 1389129198Scognet cpufuncs = arm9_cpufuncs; 1390129198Scognet cpu_reset_needs_v4_MMU_disable = 1; /* V4 or higher */ 1391129198Scognet get_cachetype_cp15(); 1392146605Scognet arm9_dcache_sets_inc = 1U << arm_dcache_l2_linesize; 1393146605Scognet arm9_dcache_sets_max = (1U << (arm_dcache_l2_linesize + 1394146605Scognet arm_dcache_l2_nsets)) - arm9_dcache_sets_inc; 1395146605Scognet arm9_dcache_index_inc = 1U << (32 - arm_dcache_l2_assoc); 1396146605Scognet arm9_dcache_index_max = 0U - arm9_dcache_index_inc; 1397137270Scognet#ifdef ARM9_CACHE_WRITE_THROUGH 1398129198Scognet pmap_pte_init_arm9(); 1399137270Scognet#else 1400137270Scognet pmap_pte_init_generic(); 1401137270Scognet#endif 1402166655Scognet goto out; 1403129198Scognet } 1404129198Scognet#endif /* CPU_ARM9 */ 1405172738Simp#if defined(CPU_ARM9E) || defined(CPU_ARM10) 1406239268Sgonzo if (cputype == CPU_ID_MV88FR131 || cputype == CPU_ID_MV88FR571_VD || 1407183835Sraj cputype == CPU_ID_MV88FR571_41) { 1408239268Sgonzo uint32_t sheeva_ctrl; 1409183835Sraj 1410239268Sgonzo sheeva_ctrl = (MV_DC_STREAM_ENABLE | MV_BTB_DISABLE | 1411239268Sgonzo MV_L2_ENABLE); 1412239268Sgonzo /* 1413239268Sgonzo * Workaround for Marvell MV78100 CPU: Cache prefetch 1414239268Sgonzo * mechanism may affect the cache coherency validity, 1415239268Sgonzo * so it needs to be disabled. 1416239268Sgonzo * 1417239268Sgonzo * Refer to errata document MV-S501058-00C.pdf (p. 3.1 1418239268Sgonzo * L2 Prefetching Mechanism) for details. 1419239268Sgonzo */ 1420239268Sgonzo if (cputype == CPU_ID_MV88FR571_VD || 1421239268Sgonzo cputype == CPU_ID_MV88FR571_41) 1422239268Sgonzo sheeva_ctrl |= MV_L2_PREFETCH_DISABLE; 1423212825Smav 1424239268Sgonzo sheeva_control_ext(0xffffffff & ~MV_WA_ENABLE, sheeva_ctrl); 1425183835Sraj 1426239268Sgonzo cpufuncs = sheeva_cpufuncs; 1427172738Simp get_cachetype_cp15(); 1428172738Simp pmap_pte_init_generic(); 1429174058Scognet goto out; 1430239268Sgonzo } else if (cputype == CPU_ID_ARM926EJS || cputype == CPU_ID_ARM1026EJS) { 1431239268Sgonzo cpufuncs = armv5_ec_cpufuncs; 1432239268Sgonzo get_cachetype_cp15(); 1433239268Sgonzo pmap_pte_init_generic(); 1434239268Sgonzo goto out; 1435172738Simp } 1436172738Simp#endif /* CPU_ARM9E || CPU_ARM10 */ 1437129198Scognet#ifdef CPU_ARM10 1438129198Scognet if (/* cputype == CPU_ID_ARM1020T || */ 1439129198Scognet cputype == CPU_ID_ARM1020E) { 1440129198Scognet /* 1441129198Scognet * Select write-through cacheing (this isn't really an 1442129198Scognet * option on ARM1020T). 1443129198Scognet */ 1444129198Scognet cpufuncs = arm10_cpufuncs; 1445129198Scognet cpu_reset_needs_v4_MMU_disable = 1; /* V4 or higher */ 1446129198Scognet get_cachetype_cp15(); 1447129198Scognet arm10_dcache_sets_inc = 1U << arm_dcache_l2_linesize; 1448236991Simp arm10_dcache_sets_max = 1449129198Scognet (1U << (arm_dcache_l2_linesize + arm_dcache_l2_nsets)) - 1450129198Scognet arm10_dcache_sets_inc; 1451129198Scognet arm10_dcache_index_inc = 1U << (32 - arm_dcache_l2_assoc); 1452129198Scognet arm10_dcache_index_max = 0U - arm10_dcache_index_inc; 1453129198Scognet pmap_pte_init_generic(); 1454166655Scognet goto out; 1455129198Scognet } 1456129198Scognet#endif /* CPU_ARM10 */ 1457244480Sgonzo#if defined(CPU_ARM1136) || defined(CPU_ARM1176) 1458244480Sgonzo if (cputype == CPU_ID_ARM1136JS 1459244480Sgonzo || cputype == CPU_ID_ARM1136JSR1 1460244480Sgonzo || cputype == CPU_ID_ARM1176JZS) { 1461244480Sgonzo#ifdef CPU_ARM1136 1462244480Sgonzo if (cputype == CPU_ID_ARM1136JS 1463244480Sgonzo || cputype == CPU_ID_ARM1136JSR1) 1464244480Sgonzo cpufuncs = arm1136_cpufuncs; 1465244480Sgonzo#endif 1466244480Sgonzo#ifdef CPU_ARM1176 1467244480Sgonzo if (cputype == CPU_ID_ARM1176JZS) 1468244480Sgonzo cpufuncs = arm1176_cpufuncs; 1469244480Sgonzo#endif 1470244480Sgonzo cpu_reset_needs_v4_MMU_disable = 1; /* V4 or higher */ 1471244480Sgonzo get_cachetype_cp15(); 1472239701Sgonzo 1473244480Sgonzo pmap_pte_init_mmu_v6(); 1474244480Sgonzo 1475244480Sgonzo goto out; 1476244480Sgonzo } 1477244480Sgonzo#endif /* CPU_ARM1136 || CPU_ARM1176 */ 1478239268Sgonzo#ifdef CPU_CORTEXA 1479256629Sbr if (cputype == CPU_ID_CORTEXA5 || 1480256629Sbr cputype == CPU_ID_CORTEXA7 || 1481253857Sganbold cputype == CPU_ID_CORTEXA8R1 || 1482239268Sgonzo cputype == CPU_ID_CORTEXA8R2 || 1483239268Sgonzo cputype == CPU_ID_CORTEXA8R3 || 1484239268Sgonzo cputype == CPU_ID_CORTEXA9R1 || 1485249999Swkoszek cputype == CPU_ID_CORTEXA9R2 || 1486252361Sray cputype == CPU_ID_CORTEXA9R3 || 1487252361Sray cputype == CPU_ID_CORTEXA15 ) { 1488239268Sgonzo cpufuncs = cortexa_cpufuncs; 1489239268Sgonzo cpu_reset_needs_v4_MMU_disable = 1; /* V4 or higher */ 1490239268Sgonzo get_cachetype_cp15(); 1491239268Sgonzo 1492239268Sgonzo pmap_pte_init_mmu_v6(); 1493239268Sgonzo /* Use powersave on this CPU. */ 1494239268Sgonzo cpu_do_powersave = 1; 1495239268Sgonzo goto out; 1496239268Sgonzo } 1497239268Sgonzo#endif /* CPU_CORTEXA */ 1498239268Sgonzo 1499239268Sgonzo#if defined(CPU_MV_PJ4B) 1500239268Sgonzo if (cputype == CPU_ID_MV88SV581X_V6 || 1501239268Sgonzo cputype == CPU_ID_MV88SV581X_V7 || 1502240486Sgber cputype == CPU_ID_MV88SV584X_V7 || 1503239268Sgonzo cputype == CPU_ID_ARM_88SV581X_V6 || 1504239268Sgonzo cputype == CPU_ID_ARM_88SV581X_V7) { 1505239268Sgonzo if (cpu_pfr(0) & ARM_PFR0_THUMBEE_MASK) 1506239268Sgonzo cpufuncs = pj4bv7_cpufuncs; 1507239268Sgonzo else 1508239268Sgonzo cpufuncs = pj4bv6_cpufuncs; 1509239268Sgonzo 1510239268Sgonzo get_cachetype_cp15(); 1511239268Sgonzo pmap_pte_init_mmu_v6(); 1512239268Sgonzo goto out; 1513240486Sgber } else if (cputype == CPU_ID_ARM_88SV584X_V6 || 1514240486Sgber cputype == CPU_ID_MV88SV584X_V6) { 1515239268Sgonzo cpufuncs = pj4bv6_cpufuncs; 1516239268Sgonzo get_cachetype_cp15(); 1517239268Sgonzo pmap_pte_init_mmu_v6(); 1518239268Sgonzo goto out; 1519239268Sgonzo } 1520239268Sgonzo 1521239268Sgonzo#endif /* CPU_MV_PJ4B */ 1522129198Scognet#ifdef CPU_SA110 1523129198Scognet if (cputype == CPU_ID_SA110) { 1524129198Scognet cpufuncs = sa110_cpufuncs; 1525129198Scognet cpu_reset_needs_v4_MMU_disable = 1; /* SA needs it */ 1526129198Scognet get_cachetype_table(); 1527129198Scognet pmap_pte_init_sa1(); 1528166655Scognet goto out; 1529129198Scognet } 1530129198Scognet#endif /* CPU_SA110 */ 1531129198Scognet#ifdef CPU_SA1100 1532129198Scognet if (cputype == CPU_ID_SA1100) { 1533129198Scognet cpufuncs = sa11x0_cpufuncs; 1534129198Scognet cpu_reset_needs_v4_MMU_disable = 1; /* SA needs it */ 1535129198Scognet get_cachetype_table(); 1536129198Scognet pmap_pte_init_sa1(); 1537129198Scognet /* Use powersave on this CPU. */ 1538129198Scognet cpu_do_powersave = 1; 1539129198Scognet 1540166655Scognet goto out; 1541129198Scognet } 1542129198Scognet#endif /* CPU_SA1100 */ 1543129198Scognet#ifdef CPU_SA1110 1544129198Scognet if (cputype == CPU_ID_SA1110) { 1545129198Scognet cpufuncs = sa11x0_cpufuncs; 1546129198Scognet cpu_reset_needs_v4_MMU_disable = 1; /* SA needs it */ 1547129198Scognet get_cachetype_table(); 1548129198Scognet pmap_pte_init_sa1(); 1549129198Scognet /* Use powersave on this CPU. */ 1550129198Scognet cpu_do_powersave = 1; 1551129198Scognet 1552166655Scognet goto out; 1553129198Scognet } 1554129198Scognet#endif /* CPU_SA1110 */ 1555207611Skevlo#if defined(CPU_FA526) || defined(CPU_FA626TE) 1556207611Skevlo if (cputype == CPU_ID_FA526 || cputype == CPU_ID_FA626TE) { 1557201468Srpaulo cpufuncs = fa526_cpufuncs; 1558201468Srpaulo cpu_reset_needs_v4_MMU_disable = 1; /* SA needs it */ 1559201468Srpaulo get_cachetype_cp15(); 1560201468Srpaulo pmap_pte_init_generic(); 1561201468Srpaulo 1562201468Srpaulo /* Use powersave on this CPU. */ 1563201468Srpaulo cpu_do_powersave = 1; 1564201468Srpaulo 1565201468Srpaulo goto out; 1566201468Srpaulo } 1567207611Skevlo#endif /* CPU_FA526 || CPU_FA626TE */ 1568129198Scognet#ifdef CPU_IXP12X0 1569129198Scognet if (cputype == CPU_ID_IXP1200) { 1570129198Scognet cpufuncs = ixp12x0_cpufuncs; 1571129198Scognet cpu_reset_needs_v4_MMU_disable = 1; 1572129198Scognet get_cachetype_table(); 1573129198Scognet pmap_pte_init_sa1(); 1574166655Scognet goto out; 1575129198Scognet } 1576129198Scognet#endif /* CPU_IXP12X0 */ 1577129198Scognet#ifdef CPU_XSCALE_80200 1578129198Scognet if (cputype == CPU_ID_80200) { 1579129198Scognet int rev = cpufunc_id() & CPU_ID_REVISION_MASK; 1580129198Scognet 1581129198Scognet i80200_icu_init(); 1582129198Scognet 1583129198Scognet#if defined(XSCALE_CCLKCFG) 1584129198Scognet /* 1585129198Scognet * Crank CCLKCFG to maximum legal value. 1586129198Scognet */ 1587129198Scognet __asm __volatile ("mcr p14, 0, %0, c6, c0, 0" 1588129198Scognet : 1589129198Scognet : "r" (XSCALE_CCLKCFG)); 1590129198Scognet#endif 1591129198Scognet 1592129198Scognet /* 1593129198Scognet * XXX Disable ECC in the Bus Controller Unit; we 1594129198Scognet * don't really support it, yet. Clear any pending 1595129198Scognet * error indications. 1596129198Scognet */ 1597129198Scognet __asm __volatile("mcr p13, 0, %0, c0, c1, 0" 1598129198Scognet : 1599129198Scognet : "r" (BCUCTL_E0|BCUCTL_E1|BCUCTL_EV)); 1600129198Scognet 1601129198Scognet cpufuncs = xscale_cpufuncs; 1602129198Scognet /* 1603129198Scognet * i80200 errata: Step-A0 and A1 have a bug where 1604129198Scognet * D$ dirty bits are not cleared on "invalidate by 1605129198Scognet * address". 1606129198Scognet * 1607129198Scognet * Workaround: Clean cache line before invalidating. 1608129198Scognet */ 1609129198Scognet if (rev == 0 || rev == 1) 1610129198Scognet cpufuncs.cf_dcache_inv_range = xscale_cache_purgeD_rng; 1611129198Scognet 1612129198Scognet cpu_reset_needs_v4_MMU_disable = 1; /* XScale needs it */ 1613129198Scognet get_cachetype_cp15(); 1614129198Scognet pmap_pte_init_xscale(); 1615166655Scognet goto out; 1616129198Scognet } 1617129198Scognet#endif /* CPU_XSCALE_80200 */ 1618161592Scognet#if defined(CPU_XSCALE_80321) || defined(CPU_XSCALE_80219) 1619129198Scognet if (cputype == CPU_ID_80321_400 || cputype == CPU_ID_80321_600 || 1620161592Scognet cputype == CPU_ID_80321_400_B0 || cputype == CPU_ID_80321_600_B0 || 1621161592Scognet cputype == CPU_ID_80219_400 || cputype == CPU_ID_80219_600) { 1622129198Scognet cpufuncs = xscale_cpufuncs; 1623129198Scognet cpu_reset_needs_v4_MMU_disable = 1; /* XScale needs it */ 1624129198Scognet get_cachetype_cp15(); 1625129198Scognet pmap_pte_init_xscale(); 1626166655Scognet goto out; 1627129198Scognet } 1628129198Scognet#endif /* CPU_XSCALE_80321 */ 1629161592Scognet 1630164080Scognet#if defined(CPU_XSCALE_81342) 1631164080Scognet if (cputype == CPU_ID_81342) { 1632164080Scognet cpufuncs = xscalec3_cpufuncs; 1633164080Scognet cpu_reset_needs_v4_MMU_disable = 1; /* XScale needs it */ 1634164080Scognet get_cachetype_cp15(); 1635164080Scognet pmap_pte_init_xscale(); 1636166655Scognet goto out; 1637164080Scognet } 1638164080Scognet#endif /* CPU_XSCALE_81342 */ 1639129198Scognet#ifdef CPU_XSCALE_PXA2X0 1640129198Scognet /* ignore core revision to test PXA2xx CPUs */ 1641129198Scognet if ((cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA250 || 1642191817Sstas (cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA27X || 1643129198Scognet (cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA210) { 1644129198Scognet 1645129198Scognet cpufuncs = xscale_cpufuncs; 1646129198Scognet cpu_reset_needs_v4_MMU_disable = 1; /* XScale needs it */ 1647129198Scognet get_cachetype_cp15(); 1648129198Scognet pmap_pte_init_xscale(); 1649129198Scognet 1650129198Scognet /* Use powersave on this CPU. */ 1651129198Scognet cpu_do_powersave = 1; 1652129198Scognet 1653166655Scognet goto out; 1654129198Scognet } 1655129198Scognet#endif /* CPU_XSCALE_PXA2X0 */ 1656129198Scognet#ifdef CPU_XSCALE_IXP425 1657129198Scognet if (cputype == CPU_ID_IXP425_533 || cputype == CPU_ID_IXP425_400 || 1658186352Ssam cputype == CPU_ID_IXP425_266 || cputype == CPU_ID_IXP435) { 1659129198Scognet 1660129198Scognet cpufuncs = xscale_cpufuncs; 1661129198Scognet cpu_reset_needs_v4_MMU_disable = 1; /* XScale needs it */ 1662129198Scognet get_cachetype_cp15(); 1663129198Scognet pmap_pte_init_xscale(); 1664129198Scognet 1665166655Scognet goto out; 1666129198Scognet } 1667129198Scognet#endif /* CPU_XSCALE_IXP425 */ 1668129198Scognet /* 1669129198Scognet * Bzzzz. And the answer was ... 1670129198Scognet */ 1671129198Scognet panic("No support for this CPU type (%08x) in kernel", cputype); 1672129198Scognet return(ARCHITECTURE_NOT_PRESENT); 1673166655Scognetout: 1674166655Scognet uma_set_align(arm_dcache_align_mask); 1675166655Scognet return (0); 1676129198Scognet} 1677129198Scognet 1678129198Scognet/* 1679129198Scognet * Fixup routines for data and prefetch aborts. 1680129198Scognet * 1681129198Scognet * Several compile time symbols are used 1682129198Scognet * 1683129198Scognet * DEBUG_FAULT_CORRECTION - Print debugging information during the 1684129198Scognet * correction of registers after a fault. 1685129198Scognet * ARM6_LATE_ABORT - ARM6 supports both early and late aborts 1686129198Scognet * when defined should use late aborts 1687129198Scognet */ 1688129198Scognet 1689129198Scognet 1690129198Scognet/* 1691129198Scognet * Null abort fixup routine. 1692129198Scognet * For use when no fixup is required. 1693129198Scognet */ 1694129198Scognetint 1695129198Scognetcpufunc_null_fixup(arg) 1696129198Scognet void *arg; 1697129198Scognet{ 1698129198Scognet return(ABORT_FIXUP_OK); 1699129198Scognet} 1700129198Scognet 1701129198Scognet 1702146619Scognet#if defined(CPU_ARM7TDMI) 1703129198Scognet 1704129198Scognet#ifdef DEBUG_FAULT_CORRECTION 1705129198Scognet#define DFC_PRINTF(x) printf x 1706129198Scognet#define DFC_DISASSEMBLE(x) disassemble(x) 1707129198Scognet#else 1708129198Scognet#define DFC_PRINTF(x) /* nothing */ 1709129198Scognet#define DFC_DISASSEMBLE(x) /* nothing */ 1710129198Scognet#endif 1711129198Scognet 1712129198Scognet/* 1713129198Scognet * "Early" data abort fixup. 1714129198Scognet * 1715129198Scognet * For ARM2, ARM2as, ARM3 and ARM6 (in early-abort mode). Also used 1716129198Scognet * indirectly by ARM6 (in late-abort mode) and ARM7[TDMI]. 1717129198Scognet * 1718129198Scognet * In early aborts, we may have to fix up LDM, STM, LDC and STC. 1719129198Scognet */ 1720129198Scognetint 1721129198Scognetearly_abort_fixup(arg) 1722129198Scognet void *arg; 1723129198Scognet{ 1724257217Sian struct trapframe *frame = arg; 1725129198Scognet u_int fault_pc; 1726129198Scognet u_int fault_instruction; 1727129198Scognet int saved_lr = 0; 1728129198Scognet 1729129198Scognet if ((frame->tf_spsr & PSR_MODE) == PSR_SVC32_MODE) { 1730129198Scognet 1731129198Scognet /* Ok an abort in SVC mode */ 1732129198Scognet 1733129198Scognet /* 1734129198Scognet * Copy the SVC r14 into the usr r14 - The usr r14 is garbage 1735129198Scognet * as the fault happened in svc mode but we need it in the 1736129198Scognet * usr slot so we can treat the registers as an array of ints 1737129198Scognet * during fixing. 1738129198Scognet * NOTE: This PC is in the position but writeback is not 1739129198Scognet * allowed on r15. 1740129198Scognet * Doing it like this is more efficient than trapping this 1741129198Scognet * case in all possible locations in the following fixup code. 1742129198Scognet */ 1743129198Scognet 1744129198Scognet saved_lr = frame->tf_usr_lr; 1745129198Scognet frame->tf_usr_lr = frame->tf_svc_lr; 1746129198Scognet 1747129198Scognet /* 1748129198Scognet * Note the trapframe does not have the SVC r13 so a fault 1749129198Scognet * from an instruction with writeback to r13 in SVC mode is 1750129198Scognet * not allowed. This should not happen as the kstack is 1751129198Scognet * always valid. 1752129198Scognet */ 1753129198Scognet } 1754129198Scognet 1755129198Scognet /* Get fault address and status from the CPU */ 1756129198Scognet 1757129198Scognet fault_pc = frame->tf_pc; 1758129198Scognet fault_instruction = *((volatile unsigned int *)fault_pc); 1759129198Scognet 1760129198Scognet /* Decode the fault instruction and fix the registers as needed */ 1761129198Scognet 1762129198Scognet if ((fault_instruction & 0x0e000000) == 0x08000000) { 1763129198Scognet int base; 1764129198Scognet int loop; 1765129198Scognet int count; 1766129198Scognet int *registers = &frame->tf_r0; 1767236991Simp 1768129198Scognet DFC_PRINTF(("LDM/STM\n")); 1769129198Scognet DFC_DISASSEMBLE(fault_pc); 1770129198Scognet if (fault_instruction & (1 << 21)) { 1771129198Scognet DFC_PRINTF(("This instruction must be corrected\n")); 1772129198Scognet base = (fault_instruction >> 16) & 0x0f; 1773129198Scognet if (base == 15) 1774129198Scognet return ABORT_FIXUP_FAILED; 1775129198Scognet /* Count registers transferred */ 1776129198Scognet count = 0; 1777129198Scognet for (loop = 0; loop < 16; ++loop) { 1778129198Scognet if (fault_instruction & (1<<loop)) 1779129198Scognet ++count; 1780129198Scognet } 1781129198Scognet DFC_PRINTF(("%d registers used\n", count)); 1782129198Scognet DFC_PRINTF(("Corrected r%d by %d bytes ", 1783129198Scognet base, count * 4)); 1784129198Scognet if (fault_instruction & (1 << 23)) { 1785129198Scognet DFC_PRINTF(("down\n")); 1786129198Scognet registers[base] -= count * 4; 1787129198Scognet } else { 1788129198Scognet DFC_PRINTF(("up\n")); 1789129198Scognet registers[base] += count * 4; 1790129198Scognet } 1791129198Scognet } 1792129198Scognet } else if ((fault_instruction & 0x0e000000) == 0x0c000000) { 1793129198Scognet int base; 1794129198Scognet int offset; 1795129198Scognet int *registers = &frame->tf_r0; 1796129198Scognet 1797129198Scognet /* REGISTER CORRECTION IS REQUIRED FOR THESE INSTRUCTIONS */ 1798129198Scognet 1799129198Scognet DFC_DISASSEMBLE(fault_pc); 1800129198Scognet 1801129198Scognet /* Only need to fix registers if write back is turned on */ 1802129198Scognet 1803129198Scognet if ((fault_instruction & (1 << 21)) != 0) { 1804129198Scognet base = (fault_instruction >> 16) & 0x0f; 1805129198Scognet if (base == 13 && 1806129198Scognet (frame->tf_spsr & PSR_MODE) == PSR_SVC32_MODE) 1807129198Scognet return ABORT_FIXUP_FAILED; 1808129198Scognet if (base == 15) 1809129198Scognet return ABORT_FIXUP_FAILED; 1810129198Scognet 1811129198Scognet offset = (fault_instruction & 0xff) << 2; 1812129198Scognet DFC_PRINTF(("r%d=%08x\n", base, registers[base])); 1813129198Scognet if ((fault_instruction & (1 << 23)) != 0) 1814129198Scognet offset = -offset; 1815129198Scognet registers[base] += offset; 1816129198Scognet DFC_PRINTF(("r%d=%08x\n", base, registers[base])); 1817129198Scognet } 1818129198Scognet } else if ((fault_instruction & 0x0e000000) == 0x0c000000) 1819129198Scognet return ABORT_FIXUP_FAILED; 1820129198Scognet 1821129198Scognet if ((frame->tf_spsr & PSR_MODE) == PSR_SVC32_MODE) { 1822129198Scognet 1823129198Scognet /* Ok an abort in SVC mode */ 1824129198Scognet 1825129198Scognet /* 1826129198Scognet * Copy the SVC r14 into the usr r14 - The usr r14 is garbage 1827129198Scognet * as the fault happened in svc mode but we need it in the 1828129198Scognet * usr slot so we can treat the registers as an array of ints 1829129198Scognet * during fixing. 1830129198Scognet * NOTE: This PC is in the position but writeback is not 1831129198Scognet * allowed on r15. 1832129198Scognet * Doing it like this is more efficient than trapping this 1833129198Scognet * case in all possible locations in the prior fixup code. 1834129198Scognet */ 1835129198Scognet 1836129198Scognet frame->tf_svc_lr = frame->tf_usr_lr; 1837129198Scognet frame->tf_usr_lr = saved_lr; 1838129198Scognet 1839129198Scognet /* 1840129198Scognet * Note the trapframe does not have the SVC r13 so a fault 1841129198Scognet * from an instruction with writeback to r13 in SVC mode is 1842129198Scognet * not allowed. This should not happen as the kstack is 1843129198Scognet * always valid. 1844129198Scognet */ 1845129198Scognet } 1846129198Scognet 1847129198Scognet return(ABORT_FIXUP_OK); 1848129198Scognet} 1849129198Scognet#endif /* CPU_ARM2/250/3/6/7 */ 1850129198Scognet 1851129198Scognet 1852146619Scognet#if defined(CPU_ARM7TDMI) 1853129198Scognet/* 1854129198Scognet * "Late" (base updated) data abort fixup 1855129198Scognet * 1856129198Scognet * For ARM6 (in late-abort mode) and ARM7. 1857129198Scognet * 1858129198Scognet * In this model, all data-transfer instructions need fixing up. We defer 1859129198Scognet * LDM, STM, LDC and STC fixup to the early-abort handler. 1860129198Scognet */ 1861129198Scognetint 1862129198Scognetlate_abort_fixup(arg) 1863129198Scognet void *arg; 1864129198Scognet{ 1865257217Sian struct trapframe *frame = arg; 1866129198Scognet u_int fault_pc; 1867129198Scognet u_int fault_instruction; 1868129198Scognet int saved_lr = 0; 1869129198Scognet 1870129198Scognet if ((frame->tf_spsr & PSR_MODE) == PSR_SVC32_MODE) { 1871129198Scognet 1872129198Scognet /* Ok an abort in SVC mode */ 1873129198Scognet 1874129198Scognet /* 1875129198Scognet * Copy the SVC r14 into the usr r14 - The usr r14 is garbage 1876129198Scognet * as the fault happened in svc mode but we need it in the 1877129198Scognet * usr slot so we can treat the registers as an array of ints 1878129198Scognet * during fixing. 1879129198Scognet * NOTE: This PC is in the position but writeback is not 1880129198Scognet * allowed on r15. 1881129198Scognet * Doing it like this is more efficient than trapping this 1882129198Scognet * case in all possible locations in the following fixup code. 1883129198Scognet */ 1884129198Scognet 1885129198Scognet saved_lr = frame->tf_usr_lr; 1886129198Scognet frame->tf_usr_lr = frame->tf_svc_lr; 1887129198Scognet 1888129198Scognet /* 1889129198Scognet * Note the trapframe does not have the SVC r13 so a fault 1890129198Scognet * from an instruction with writeback to r13 in SVC mode is 1891129198Scognet * not allowed. This should not happen as the kstack is 1892129198Scognet * always valid. 1893129198Scognet */ 1894129198Scognet } 1895129198Scognet 1896129198Scognet /* Get fault address and status from the CPU */ 1897129198Scognet 1898129198Scognet fault_pc = frame->tf_pc; 1899129198Scognet fault_instruction = *((volatile unsigned int *)fault_pc); 1900129198Scognet 1901129198Scognet /* Decode the fault instruction and fix the registers as needed */ 1902129198Scognet 1903129198Scognet /* Was is a swap instruction ? */ 1904129198Scognet 1905129198Scognet if ((fault_instruction & 0x0fb00ff0) == 0x01000090) { 1906129198Scognet DFC_DISASSEMBLE(fault_pc); 1907129198Scognet } else if ((fault_instruction & 0x0c000000) == 0x04000000) { 1908129198Scognet 1909129198Scognet /* Was is a ldr/str instruction */ 1910129198Scognet /* This is for late abort only */ 1911129198Scognet 1912129198Scognet int base; 1913129198Scognet int offset; 1914129198Scognet int *registers = &frame->tf_r0; 1915129198Scognet 1916129198Scognet DFC_DISASSEMBLE(fault_pc); 1917129198Scognet 1918129198Scognet /* This is for late abort only */ 1919129198Scognet 1920129198Scognet if ((fault_instruction & (1 << 24)) == 0 1921129198Scognet || (fault_instruction & (1 << 21)) != 0) { 1922129198Scognet /* postindexed ldr/str with no writeback */ 1923129198Scognet 1924129198Scognet base = (fault_instruction >> 16) & 0x0f; 1925129198Scognet if (base == 13 && 1926129198Scognet (frame->tf_spsr & PSR_MODE) == PSR_SVC32_MODE) 1927129198Scognet return ABORT_FIXUP_FAILED; 1928129198Scognet if (base == 15) 1929129198Scognet return ABORT_FIXUP_FAILED; 1930129198Scognet DFC_PRINTF(("late abt fix: r%d=%08x : ", 1931129198Scognet base, registers[base])); 1932129198Scognet if ((fault_instruction & (1 << 25)) == 0) { 1933129198Scognet /* Immediate offset - easy */ 1934129198Scognet 1935129198Scognet offset = fault_instruction & 0xfff; 1936129198Scognet if ((fault_instruction & (1 << 23))) 1937129198Scognet offset = -offset; 1938129198Scognet registers[base] += offset; 1939129198Scognet DFC_PRINTF(("imm=%08x ", offset)); 1940129198Scognet } else { 1941129198Scognet /* offset is a shifted register */ 1942129198Scognet int shift; 1943129198Scognet 1944129198Scognet offset = fault_instruction & 0x0f; 1945129198Scognet if (offset == base) 1946129198Scognet return ABORT_FIXUP_FAILED; 1947236991Simp 1948129198Scognet /* 1949129198Scognet * Register offset - hard we have to 1950129198Scognet * cope with shifts ! 1951129198Scognet */ 1952129198Scognet offset = registers[offset]; 1953129198Scognet 1954129198Scognet if ((fault_instruction & (1 << 4)) == 0) 1955129198Scognet /* shift with amount */ 1956129198Scognet shift = (fault_instruction >> 7) & 0x1f; 1957129198Scognet else { 1958129198Scognet /* shift with register */ 1959129198Scognet if ((fault_instruction & (1 << 7)) != 0) 1960129198Scognet /* undefined for now so bail out */ 1961129198Scognet return ABORT_FIXUP_FAILED; 1962129198Scognet shift = ((fault_instruction >> 8) & 0xf); 1963129198Scognet if (base == shift) 1964129198Scognet return ABORT_FIXUP_FAILED; 1965129198Scognet DFC_PRINTF(("shift reg=%d ", shift)); 1966129198Scognet shift = registers[shift]; 1967129198Scognet } 1968129198Scognet DFC_PRINTF(("shift=%08x ", shift)); 1969129198Scognet switch (((fault_instruction >> 5) & 0x3)) { 1970129198Scognet case 0 : /* Logical left */ 1971129198Scognet offset = (int)(((u_int)offset) << shift); 1972129198Scognet break; 1973129198Scognet case 1 : /* Logical Right */ 1974129198Scognet if (shift == 0) shift = 32; 1975129198Scognet offset = (int)(((u_int)offset) >> shift); 1976129198Scognet break; 1977129198Scognet case 2 : /* Arithmetic Right */ 1978129198Scognet if (shift == 0) shift = 32; 1979129198Scognet offset = (int)(((int)offset) >> shift); 1980129198Scognet break; 1981129198Scognet case 3 : /* Rotate right (rol or rxx) */ 1982129198Scognet return ABORT_FIXUP_FAILED; 1983129198Scognet break; 1984129198Scognet } 1985129198Scognet 1986129198Scognet DFC_PRINTF(("abt: fixed LDR/STR with " 1987129198Scognet "register offset\n")); 1988129198Scognet if ((fault_instruction & (1 << 23))) 1989129198Scognet offset = -offset; 1990129198Scognet DFC_PRINTF(("offset=%08x ", offset)); 1991129198Scognet registers[base] += offset; 1992129198Scognet } 1993129198Scognet DFC_PRINTF(("r%d=%08x\n", base, registers[base])); 1994129198Scognet } 1995129198Scognet } 1996129198Scognet 1997129198Scognet if ((frame->tf_spsr & PSR_MODE) == PSR_SVC32_MODE) { 1998129198Scognet 1999129198Scognet /* Ok an abort in SVC mode */ 2000129198Scognet 2001129198Scognet /* 2002129198Scognet * Copy the SVC r14 into the usr r14 - The usr r14 is garbage 2003129198Scognet * as the fault happened in svc mode but we need it in the 2004129198Scognet * usr slot so we can treat the registers as an array of ints 2005129198Scognet * during fixing. 2006129198Scognet * NOTE: This PC is in the position but writeback is not 2007129198Scognet * allowed on r15. 2008129198Scognet * Doing it like this is more efficient than trapping this 2009129198Scognet * case in all possible locations in the prior fixup code. 2010129198Scognet */ 2011129198Scognet 2012129198Scognet frame->tf_svc_lr = frame->tf_usr_lr; 2013129198Scognet frame->tf_usr_lr = saved_lr; 2014129198Scognet 2015129198Scognet /* 2016129198Scognet * Note the trapframe does not have the SVC r13 so a fault 2017129198Scognet * from an instruction with writeback to r13 in SVC mode is 2018129198Scognet * not allowed. This should not happen as the kstack is 2019129198Scognet * always valid. 2020129198Scognet */ 2021129198Scognet } 2022129198Scognet 2023129198Scognet /* 2024129198Scognet * Now let the early-abort fixup routine have a go, in case it 2025129198Scognet * was an LDM, STM, LDC or STC that faulted. 2026129198Scognet */ 2027129198Scognet 2028129198Scognet return early_abort_fixup(arg); 2029129198Scognet} 2030146619Scognet#endif /* CPU_ARM7TDMI */ 2031129198Scognet 2032129198Scognet/* 2033129198Scognet * CPU Setup code 2034129198Scognet */ 2035129198Scognet 2036146619Scognet#if defined(CPU_ARM7TDMI) || defined(CPU_ARM8) || defined (CPU_ARM9) || \ 2037172738Simp defined(CPU_ARM9E) || \ 2038161592Scognet defined(CPU_SA110) || defined(CPU_SA1100) || defined(CPU_SA1110) || \ 2039161592Scognet defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \ 2040161592Scognet defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \ 2041172738Simp defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342) || \ 2042244480Sgonzo defined(CPU_ARM10) || defined(CPU_ARM1136) || defined(CPU_ARM1176) ||\ 2043207611Skevlo defined(CPU_FA526) || defined(CPU_FA626TE) 2044129198Scognet 2045129198Scognet#define IGN 0 2046129198Scognet#define OR 1 2047129198Scognet#define BIC 2 2048129198Scognet 2049129198Scognetstruct cpu_option { 2050129198Scognet char *co_name; 2051129198Scognet int co_falseop; 2052129198Scognet int co_trueop; 2053129198Scognet int co_value; 2054129198Scognet}; 2055129198Scognet 2056137498Strhodesstatic u_int parse_cpu_options(char *, struct cpu_option *, u_int); 2057129198Scognet 2058129198Scognetstatic u_int 2059129198Scognetparse_cpu_options(args, optlist, cpuctrl) 2060129198Scognet char *args; 2061236991Simp struct cpu_option *optlist; 2062236991Simp u_int cpuctrl; 2063129198Scognet{ 2064129198Scognet int integer; 2065129198Scognet 2066129198Scognet if (args == NULL) 2067129198Scognet return(cpuctrl); 2068129198Scognet 2069129198Scognet while (optlist->co_name) { 2070129198Scognet if (get_bootconf_option(args, optlist->co_name, 2071129198Scognet BOOTOPT_TYPE_BOOLEAN, &integer)) { 2072129198Scognet if (integer) { 2073129198Scognet if (optlist->co_trueop == OR) 2074129198Scognet cpuctrl |= optlist->co_value; 2075129198Scognet else if (optlist->co_trueop == BIC) 2076129198Scognet cpuctrl &= ~optlist->co_value; 2077129198Scognet } else { 2078129198Scognet if (optlist->co_falseop == OR) 2079129198Scognet cpuctrl |= optlist->co_value; 2080129198Scognet else if (optlist->co_falseop == BIC) 2081129198Scognet cpuctrl &= ~optlist->co_value; 2082129198Scognet } 2083129198Scognet } 2084129198Scognet ++optlist; 2085129198Scognet } 2086129198Scognet return(cpuctrl); 2087129198Scognet} 2088161592Scognet#endif /* CPU_ARM7TDMI || CPU_ARM8 || CPU_SA110 || XSCALE*/ 2089129198Scognet 2090146619Scognet#if defined(CPU_ARM7TDMI) || defined(CPU_ARM8) 2091129198Scognetstruct cpu_option arm678_options[] = { 2092129198Scognet#ifdef COMPAT_12 2093129198Scognet { "nocache", IGN, BIC, CPU_CONTROL_IDC_ENABLE }, 2094129198Scognet { "nowritebuf", IGN, BIC, CPU_CONTROL_WBUF_ENABLE }, 2095129198Scognet#endif /* COMPAT_12 */ 2096129198Scognet { "cpu.cache", BIC, OR, CPU_CONTROL_IDC_ENABLE }, 2097129198Scognet { "cpu.nocache", OR, BIC, CPU_CONTROL_IDC_ENABLE }, 2098129198Scognet { "cpu.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 2099129198Scognet { "cpu.nowritebuf", OR, BIC, CPU_CONTROL_WBUF_ENABLE }, 2100129198Scognet { NULL, IGN, IGN, 0 } 2101129198Scognet}; 2102129198Scognet 2103129198Scognet#endif /* CPU_ARM6 || CPU_ARM7 || CPU_ARM7TDMI || CPU_ARM8 */ 2104129198Scognet 2105129198Scognet#ifdef CPU_ARM7TDMI 2106129198Scognetstruct cpu_option arm7tdmi_options[] = { 2107129198Scognet { "arm7.cache", BIC, OR, CPU_CONTROL_IDC_ENABLE }, 2108129198Scognet { "arm7.nocache", OR, BIC, CPU_CONTROL_IDC_ENABLE }, 2109129198Scognet { "arm7.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 2110129198Scognet { "arm7.nowritebuf", OR, BIC, CPU_CONTROL_WBUF_ENABLE }, 2111129198Scognet#ifdef COMPAT_12 2112129198Scognet { "fpaclk2", BIC, OR, CPU_CONTROL_CPCLK }, 2113129198Scognet#endif /* COMPAT_12 */ 2114129198Scognet { "arm700.fpaclk", BIC, OR, CPU_CONTROL_CPCLK }, 2115129198Scognet { NULL, IGN, IGN, 0 } 2116129198Scognet}; 2117129198Scognet 2118129198Scognetvoid 2119129198Scognetarm7tdmi_setup(args) 2120129198Scognet char *args; 2121129198Scognet{ 2122129198Scognet int cpuctrl; 2123129198Scognet 2124129198Scognet cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 2125129198Scognet | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 2126129198Scognet | CPU_CONTROL_IDC_ENABLE | CPU_CONTROL_WBUF_ENABLE; 2127129198Scognet 2128129198Scognet cpuctrl = parse_cpu_options(args, arm678_options, cpuctrl); 2129129198Scognet cpuctrl = parse_cpu_options(args, arm7tdmi_options, cpuctrl); 2130129198Scognet 2131129198Scognet#ifdef __ARMEB__ 2132129198Scognet cpuctrl |= CPU_CONTROL_BEND_ENABLE; 2133129198Scognet#endif 2134129198Scognet 2135129198Scognet /* Clear out the cache */ 2136129198Scognet cpu_idcache_wbinv_all(); 2137129198Scognet 2138129198Scognet /* Set the control register */ 2139129198Scognet ctrl = cpuctrl; 2140129198Scognet cpu_control(0xffffffff, cpuctrl); 2141129198Scognet} 2142129198Scognet#endif /* CPU_ARM7TDMI */ 2143129198Scognet 2144129198Scognet#ifdef CPU_ARM8 2145129198Scognetstruct cpu_option arm8_options[] = { 2146129198Scognet { "arm8.cache", BIC, OR, CPU_CONTROL_IDC_ENABLE }, 2147129198Scognet { "arm8.nocache", OR, BIC, CPU_CONTROL_IDC_ENABLE }, 2148129198Scognet { "arm8.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 2149129198Scognet { "arm8.nowritebuf", OR, BIC, CPU_CONTROL_WBUF_ENABLE }, 2150129198Scognet#ifdef COMPAT_12 2151129198Scognet { "branchpredict", BIC, OR, CPU_CONTROL_BPRD_ENABLE }, 2152129198Scognet#endif /* COMPAT_12 */ 2153129198Scognet { "cpu.branchpredict", BIC, OR, CPU_CONTROL_BPRD_ENABLE }, 2154129198Scognet { "arm8.branchpredict", BIC, OR, CPU_CONTROL_BPRD_ENABLE }, 2155129198Scognet { NULL, IGN, IGN, 0 } 2156129198Scognet}; 2157129198Scognet 2158129198Scognetvoid 2159129198Scognetarm8_setup(args) 2160129198Scognet char *args; 2161129198Scognet{ 2162129198Scognet int integer; 2163129198Scognet int cpuctrl, cpuctrlmask; 2164129198Scognet int clocktest; 2165129198Scognet int setclock = 0; 2166129198Scognet 2167129198Scognet cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 2168129198Scognet | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 2169129198Scognet | CPU_CONTROL_IDC_ENABLE | CPU_CONTROL_WBUF_ENABLE; 2170129198Scognet cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 2171129198Scognet | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 2172129198Scognet | CPU_CONTROL_IDC_ENABLE | CPU_CONTROL_WBUF_ENABLE 2173129198Scognet | CPU_CONTROL_BPRD_ENABLE | CPU_CONTROL_ROM_ENABLE 2174129198Scognet | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE; 2175129198Scognet 2176129198Scognet#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 2177129198Scognet cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 2178129198Scognet#endif 2179129198Scognet 2180129198Scognet cpuctrl = parse_cpu_options(args, arm678_options, cpuctrl); 2181129198Scognet cpuctrl = parse_cpu_options(args, arm8_options, cpuctrl); 2182129198Scognet 2183129198Scognet#ifdef __ARMEB__ 2184129198Scognet cpuctrl |= CPU_CONTROL_BEND_ENABLE; 2185129198Scognet#endif 2186129198Scognet 2187129198Scognet /* Get clock configuration */ 2188129198Scognet clocktest = arm8_clock_config(0, 0) & 0x0f; 2189129198Scognet 2190129198Scognet /* Special ARM8 clock and test configuration */ 2191129198Scognet if (get_bootconf_option(args, "arm8.clock.reset", BOOTOPT_TYPE_BOOLEAN, &integer)) { 2192129198Scognet clocktest = 0; 2193129198Scognet setclock = 1; 2194129198Scognet } 2195129198Scognet if (get_bootconf_option(args, "arm8.clock.dynamic", BOOTOPT_TYPE_BOOLEAN, &integer)) { 2196129198Scognet if (integer) 2197129198Scognet clocktest |= 0x01; 2198129198Scognet else 2199129198Scognet clocktest &= ~(0x01); 2200129198Scognet setclock = 1; 2201129198Scognet } 2202129198Scognet if (get_bootconf_option(args, "arm8.clock.sync", BOOTOPT_TYPE_BOOLEAN, &integer)) { 2203129198Scognet if (integer) 2204129198Scognet clocktest |= 0x02; 2205129198Scognet else 2206129198Scognet clocktest &= ~(0x02); 2207129198Scognet setclock = 1; 2208129198Scognet } 2209129198Scognet if (get_bootconf_option(args, "arm8.clock.fast", BOOTOPT_TYPE_BININT, &integer)) { 2210129198Scognet clocktest = (clocktest & ~0xc0) | (integer & 3) << 2; 2211129198Scognet setclock = 1; 2212129198Scognet } 2213129198Scognet if (get_bootconf_option(args, "arm8.test", BOOTOPT_TYPE_BININT, &integer)) { 2214129198Scognet clocktest |= (integer & 7) << 5; 2215129198Scognet setclock = 1; 2216129198Scognet } 2217129198Scognet 2218129198Scognet /* Clear out the cache */ 2219129198Scognet cpu_idcache_wbinv_all(); 2220129198Scognet 2221129198Scognet /* Set the control register */ 2222129198Scognet ctrl = cpuctrl; 2223129198Scognet cpu_control(0xffffffff, cpuctrl); 2224129198Scognet 2225236991Simp /* Set the clock/test register */ 2226129198Scognet if (setclock) 2227129198Scognet arm8_clock_config(0x7f, clocktest); 2228129198Scognet} 2229129198Scognet#endif /* CPU_ARM8 */ 2230129198Scognet 2231129198Scognet#ifdef CPU_ARM9 2232129198Scognetstruct cpu_option arm9_options[] = { 2233129198Scognet { "cpu.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2234129198Scognet { "cpu.nocache", OR, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2235129198Scognet { "arm9.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2236129198Scognet { "arm9.icache", BIC, OR, CPU_CONTROL_IC_ENABLE }, 2237129198Scognet { "arm9.dcache", BIC, OR, CPU_CONTROL_DC_ENABLE }, 2238129198Scognet { "cpu.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 2239129198Scognet { "cpu.nowritebuf", OR, BIC, CPU_CONTROL_WBUF_ENABLE }, 2240129198Scognet { "arm9.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 2241129198Scognet { NULL, IGN, IGN, 0 } 2242129198Scognet}; 2243129198Scognet 2244129198Scognetvoid 2245129198Scognetarm9_setup(args) 2246129198Scognet char *args; 2247129198Scognet{ 2248129198Scognet int cpuctrl, cpuctrlmask; 2249129198Scognet 2250129198Scognet cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 2251129198Scognet | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 2252129198Scognet | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 2253157618Scognet | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE | 2254157618Scognet CPU_CONTROL_ROUNDROBIN; 2255129198Scognet cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 2256129198Scognet | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 2257129198Scognet | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 2258129198Scognet | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE 2259129198Scognet | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE 2260146605Scognet | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_VECRELOC 2261146605Scognet | CPU_CONTROL_ROUNDROBIN; 2262129198Scognet 2263129198Scognet#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 2264129198Scognet cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 2265129198Scognet#endif 2266129198Scognet 2267129198Scognet cpuctrl = parse_cpu_options(args, arm9_options, cpuctrl); 2268129198Scognet 2269129198Scognet#ifdef __ARMEB__ 2270129198Scognet cpuctrl |= CPU_CONTROL_BEND_ENABLE; 2271129198Scognet#endif 2272142050Scognet if (vector_page == ARM_VECTORS_HIGH) 2273142050Scognet cpuctrl |= CPU_CONTROL_VECRELOC; 2274129198Scognet 2275129198Scognet /* Clear out the cache */ 2276129198Scognet cpu_idcache_wbinv_all(); 2277129198Scognet 2278129198Scognet /* Set the control register */ 2279146605Scognet cpu_control(cpuctrlmask, cpuctrl); 2280129198Scognet ctrl = cpuctrl; 2281129198Scognet 2282129198Scognet} 2283129198Scognet#endif /* CPU_ARM9 */ 2284129198Scognet 2285172738Simp#if defined(CPU_ARM9E) || defined(CPU_ARM10) 2286129198Scognetstruct cpu_option arm10_options[] = { 2287129198Scognet { "cpu.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2288129198Scognet { "cpu.nocache", OR, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2289129198Scognet { "arm10.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2290129198Scognet { "arm10.icache", BIC, OR, CPU_CONTROL_IC_ENABLE }, 2291129198Scognet { "arm10.dcache", BIC, OR, CPU_CONTROL_DC_ENABLE }, 2292129198Scognet { "cpu.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 2293129198Scognet { "cpu.nowritebuf", OR, BIC, CPU_CONTROL_WBUF_ENABLE }, 2294129198Scognet { "arm10.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 2295129198Scognet { NULL, IGN, IGN, 0 } 2296129198Scognet}; 2297129198Scognet 2298129198Scognetvoid 2299129198Scognetarm10_setup(args) 2300129198Scognet char *args; 2301129198Scognet{ 2302129198Scognet int cpuctrl, cpuctrlmask; 2303129198Scognet 2304129198Scognet cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_SYST_ENABLE 2305236991Simp | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 2306129198Scognet | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_BPRD_ENABLE; 2307129198Scognet cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_SYST_ENABLE 2308129198Scognet | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 2309129198Scognet | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE 2310129198Scognet | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE 2311129198Scognet | CPU_CONTROL_BPRD_ENABLE 2312129198Scognet | CPU_CONTROL_ROUNDROBIN | CPU_CONTROL_CPCLK; 2313129198Scognet 2314129198Scognet#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 2315129198Scognet cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 2316129198Scognet#endif 2317129198Scognet 2318129198Scognet cpuctrl = parse_cpu_options(args, arm10_options, cpuctrl); 2319129198Scognet 2320129198Scognet#ifdef __ARMEB__ 2321129198Scognet cpuctrl |= CPU_CONTROL_BEND_ENABLE; 2322129198Scognet#endif 2323129198Scognet 2324129198Scognet /* Clear out the cache */ 2325129198Scognet cpu_idcache_wbinv_all(); 2326129198Scognet 2327129198Scognet /* Now really make sure they are clean. */ 2328172738Simp __asm __volatile ("mcr\tp15, 0, r0, c7, c7, 0" : : ); 2329129198Scognet 2330174058Scognet if (vector_page == ARM_VECTORS_HIGH) 2331174058Scognet cpuctrl |= CPU_CONTROL_VECRELOC; 2332174058Scognet 2333129198Scognet /* Set the control register */ 2334129198Scognet ctrl = cpuctrl; 2335129198Scognet cpu_control(0xffffffff, cpuctrl); 2336129198Scognet 2337129198Scognet /* And again. */ 2338129198Scognet cpu_idcache_wbinv_all(); 2339129198Scognet} 2340172738Simp#endif /* CPU_ARM9E || CPU_ARM10 */ 2341129198Scognet 2342244480Sgonzo#if defined(CPU_ARM1136) || defined(CPU_ARM1176) 2343172738Simpstruct cpu_option arm11_options[] = { 2344172738Simp { "cpu.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2345172738Simp { "cpu.nocache", OR, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2346172738Simp { "arm11.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2347172738Simp { "arm11.icache", BIC, OR, CPU_CONTROL_IC_ENABLE }, 2348172738Simp { "arm11.dcache", BIC, OR, CPU_CONTROL_DC_ENABLE }, 2349172738Simp { NULL, IGN, IGN, 0 } 2350172738Simp}; 2351172738Simp 2352172738Simpvoid 2353244480Sgonzoarm11x6_setup(char *args) 2354172738Simp{ 2355244480Sgonzo int cpuctrl, cpuctrl_wax; 2356244480Sgonzo uint32_t auxctrl, auxctrl_wax; 2357244480Sgonzo uint32_t tmp, tmp2; 2358244480Sgonzo uint32_t sbz=0; 2359244480Sgonzo uint32_t cpuid; 2360172738Simp 2361244480Sgonzo cpuid = cpufunc_id(); 2362244480Sgonzo 2363244480Sgonzo cpuctrl = 2364244480Sgonzo CPU_CONTROL_MMU_ENABLE | 2365244480Sgonzo CPU_CONTROL_DC_ENABLE | 2366244480Sgonzo CPU_CONTROL_WBUF_ENABLE | 2367244480Sgonzo CPU_CONTROL_32BP_ENABLE | 2368244480Sgonzo CPU_CONTROL_32BD_ENABLE | 2369244480Sgonzo CPU_CONTROL_LABT_ENABLE | 2370244480Sgonzo CPU_CONTROL_SYST_ENABLE | 2371244480Sgonzo CPU_CONTROL_IC_ENABLE; 2372244480Sgonzo 2373244480Sgonzo /* 2374244480Sgonzo * "write as existing" bits 2375244480Sgonzo * inverse of this is mask 2376244480Sgonzo */ 2377244480Sgonzo cpuctrl_wax = 2378244480Sgonzo (3 << 30) | /* SBZ */ 2379244480Sgonzo (1 << 29) | /* FA */ 2380244480Sgonzo (1 << 28) | /* TR */ 2381244480Sgonzo (3 << 26) | /* SBZ */ 2382244480Sgonzo (3 << 19) | /* SBZ */ 2383244480Sgonzo (1 << 17); /* SBZ */ 2384244480Sgonzo 2385244480Sgonzo cpuctrl |= CPU_CONTROL_BPRD_ENABLE; 2386244480Sgonzo cpuctrl |= CPU_CONTROL_V6_EXTPAGE; 2387244480Sgonzo 2388172738Simp cpuctrl = parse_cpu_options(args, arm11_options, cpuctrl); 2389244480Sgonzo 2390172738Simp#ifdef __ARMEB__ 2391172738Simp cpuctrl |= CPU_CONTROL_BEND_ENABLE; 2392172738Simp#endif 2393244480Sgonzo 2394239701Sgonzo if (vector_page == ARM_VECTORS_HIGH) 2395239701Sgonzo cpuctrl |= CPU_CONTROL_VECRELOC; 2396172738Simp 2397244480Sgonzo auxctrl = 0; 2398244480Sgonzo auxctrl_wax = ~0; 2399244480Sgonzo /* 2400244480Sgonzo * This options enables the workaround for the 364296 ARM1136 2401244480Sgonzo * r0pX errata (possible cache data corruption with 2402244480Sgonzo * hit-under-miss enabled). It sets the undocumented bit 31 in 2403244480Sgonzo * the auxiliary control register and the FI bit in the control 2404244480Sgonzo * register, thus disabling hit-under-miss without putting the 2405244480Sgonzo * processor into full low interrupt latency mode. ARM11MPCore 2406244480Sgonzo * is not affected. 2407244480Sgonzo */ 2408244480Sgonzo if ((cpuid & CPU_ID_CPU_MASK) == CPU_ID_ARM1136JS) { /* ARM1136JSr0pX */ 2409244480Sgonzo cpuctrl |= CPU_CONTROL_FI_ENABLE; 2410244480Sgonzo auxctrl = ARM1136_AUXCTL_PFI; 2411244480Sgonzo auxctrl_wax = ~ARM1136_AUXCTL_PFI; 2412244480Sgonzo } 2413244480Sgonzo 2414244480Sgonzo /* 2415244480Sgonzo * Enable an errata workaround 2416244480Sgonzo */ 2417244480Sgonzo if ((cpuid & CPU_ID_CPU_MASK) == CPU_ID_ARM1176JZS) { /* ARM1176JZSr0 */ 2418244480Sgonzo auxctrl = ARM1176_AUXCTL_PHD; 2419244480Sgonzo auxctrl_wax = ~ARM1176_AUXCTL_PHD; 2420244480Sgonzo } 2421244480Sgonzo 2422244480Sgonzo /* Clear out the cache */ 2423172738Simp cpu_idcache_wbinv_all(); 2424172738Simp 2425244480Sgonzo /* Now really make sure they are clean. */ 2426244480Sgonzo __asm volatile ("mcr\tp15, 0, %0, c7, c7, 0" : : "r"(sbz)); 2427244480Sgonzo 2428244480Sgonzo /* Allow detection code to find the VFP if it's fitted. */ 2429244480Sgonzo __asm volatile ("mcr\tp15, 0, %0, c1, c0, 2" : : "r" (0x0fffffff)); 2430244480Sgonzo 2431172738Simp /* Set the control register */ 2432239701Sgonzo ctrl = cpuctrl; 2433244480Sgonzo cpu_control(~cpuctrl_wax, cpuctrl); 2434172738Simp 2435244480Sgonzo __asm volatile ("mrc p15, 0, %0, c1, c0, 1\n\t" 2436244480Sgonzo "and %1, %0, %2\n\t" 2437244480Sgonzo "orr %1, %1, %3\n\t" 2438244480Sgonzo "teq %0, %1\n\t" 2439244480Sgonzo "mcrne p15, 0, %1, c1, c0, 1\n\t" 2440244480Sgonzo : "=r"(tmp), "=r"(tmp2) : 2441244480Sgonzo "r"(auxctrl_wax), "r"(auxctrl)); 2442244480Sgonzo 2443244480Sgonzo /* And again. */ 2444172738Simp cpu_idcache_wbinv_all(); 2445172738Simp} 2446244480Sgonzo#endif /* CPU_ARM1136 || CPU_ARM1176 */ 2447172738Simp 2448239268Sgonzo#ifdef CPU_MV_PJ4B 2449239268Sgonzovoid 2450239268Sgonzopj4bv6_setup(char *args) 2451239268Sgonzo{ 2452239268Sgonzo int cpuctrl; 2453239268Sgonzo 2454239268Sgonzo pj4b_config(); 2455239268Sgonzo 2456239268Sgonzo cpuctrl = CPU_CONTROL_MMU_ENABLE; 2457239268Sgonzo#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 2458239268Sgonzo cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 2459239268Sgonzo#endif 2460239268Sgonzo cpuctrl |= CPU_CONTROL_DC_ENABLE; 2461239268Sgonzo cpuctrl |= (0xf << 3); 2462239268Sgonzo#ifdef __ARMEB__ 2463239268Sgonzo cpuctrl |= CPU_CONTROL_BEND_ENABLE; 2464239268Sgonzo#endif 2465239268Sgonzo cpuctrl |= CPU_CONTROL_SYST_ENABLE; 2466239268Sgonzo cpuctrl |= CPU_CONTROL_BPRD_ENABLE; 2467239268Sgonzo cpuctrl |= CPU_CONTROL_IC_ENABLE; 2468239268Sgonzo if (vector_page == ARM_VECTORS_HIGH) 2469239268Sgonzo cpuctrl |= CPU_CONTROL_VECRELOC; 2470239268Sgonzo cpuctrl |= (0x5 << 16); 2471239268Sgonzo cpuctrl |= CPU_CONTROL_V6_EXTPAGE; 2472239268Sgonzo /* XXX not yet */ 2473239268Sgonzo /* cpuctrl |= CPU_CONTROL_L2_ENABLE; */ 2474239268Sgonzo 2475239268Sgonzo /* Make sure caches are clean. */ 2476239268Sgonzo cpu_idcache_wbinv_all(); 2477239268Sgonzo cpu_l2cache_wbinv_all(); 2478239268Sgonzo 2479239268Sgonzo /* Set the control register */ 2480239268Sgonzo ctrl = cpuctrl; 2481239268Sgonzo cpu_control(0xffffffff, cpuctrl); 2482239268Sgonzo 2483239268Sgonzo cpu_idcache_wbinv_all(); 2484239268Sgonzo cpu_l2cache_wbinv_all(); 2485239268Sgonzo} 2486239268Sgonzo 2487239268Sgonzovoid 2488239268Sgonzopj4bv7_setup(args) 2489239268Sgonzo char *args; 2490239268Sgonzo{ 2491239268Sgonzo int cpuctrl; 2492239268Sgonzo 2493239268Sgonzo pj4b_config(); 2494239268Sgonzo 2495239268Sgonzo cpuctrl = CPU_CONTROL_MMU_ENABLE; 2496239268Sgonzo#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 2497239268Sgonzo cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 2498239268Sgonzo#endif 2499239268Sgonzo cpuctrl |= CPU_CONTROL_DC_ENABLE; 2500239268Sgonzo cpuctrl |= (0xf << 3); 2501239268Sgonzo cpuctrl |= CPU_CONTROL_BPRD_ENABLE; 2502239268Sgonzo cpuctrl |= CPU_CONTROL_IC_ENABLE; 2503239268Sgonzo if (vector_page == ARM_VECTORS_HIGH) 2504239268Sgonzo cpuctrl |= CPU_CONTROL_VECRELOC; 2505239268Sgonzo cpuctrl |= (0x5 << 16) | (1 < 22); 2506239268Sgonzo cpuctrl |= CPU_CONTROL_V6_EXTPAGE; 2507239268Sgonzo 2508239268Sgonzo /* Clear out the cache */ 2509239268Sgonzo cpu_idcache_wbinv_all(); 2510239268Sgonzo 2511239268Sgonzo /* Set the control register */ 2512239268Sgonzo ctrl = cpuctrl; 2513239268Sgonzo cpu_control(0xFFFFFFFF, cpuctrl); 2514239268Sgonzo 2515239268Sgonzo /* And again. */ 2516239268Sgonzo cpu_idcache_wbinv_all(); 2517239268Sgonzo} 2518239268Sgonzo#endif /* CPU_MV_PJ4B */ 2519239268Sgonzo 2520239268Sgonzo#ifdef CPU_CORTEXA 2521239268Sgonzo 2522239268Sgonzovoid 2523239268Sgonzocortexa_setup(char *args) 2524239268Sgonzo{ 2525239268Sgonzo int cpuctrl, cpuctrlmask; 2526239268Sgonzo 2527239268Sgonzo cpuctrlmask = CPU_CONTROL_MMU_ENABLE | /* MMU enable [0] */ 2528239268Sgonzo CPU_CONTROL_AFLT_ENABLE | /* Alignment fault [1] */ 2529239268Sgonzo CPU_CONTROL_DC_ENABLE | /* DCache enable [2] */ 2530239268Sgonzo CPU_CONTROL_BPRD_ENABLE | /* Branch prediction [11] */ 2531239268Sgonzo CPU_CONTROL_IC_ENABLE | /* ICache enable [12] */ 2532239268Sgonzo CPU_CONTROL_VECRELOC; /* Vector relocation [13] */ 2533239268Sgonzo 2534239268Sgonzo cpuctrl = CPU_CONTROL_MMU_ENABLE | 2535239268Sgonzo CPU_CONTROL_IC_ENABLE | 2536239268Sgonzo CPU_CONTROL_DC_ENABLE | 2537239268Sgonzo CPU_CONTROL_BPRD_ENABLE; 2538239268Sgonzo 2539239268Sgonzo#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 2540239268Sgonzo cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 2541239268Sgonzo#endif 2542239268Sgonzo 2543239268Sgonzo /* Switch to big endian */ 2544239268Sgonzo#ifdef __ARMEB__ 2545239268Sgonzo cpuctrl |= CPU_CONTROL_BEND_ENABLE; 2546239268Sgonzo#endif 2547239268Sgonzo 2548239268Sgonzo /* Check if the vector page is at the high address (0xffff0000) */ 2549239268Sgonzo if (vector_page == ARM_VECTORS_HIGH) 2550239268Sgonzo cpuctrl |= CPU_CONTROL_VECRELOC; 2551239268Sgonzo 2552239268Sgonzo /* Clear out the cache */ 2553239268Sgonzo cpu_idcache_wbinv_all(); 2554239268Sgonzo 2555239268Sgonzo /* Set the control register */ 2556239268Sgonzo ctrl = cpuctrl; 2557239268Sgonzo cpu_control(cpuctrlmask, cpuctrl); 2558239268Sgonzo 2559239268Sgonzo /* And again. */ 2560239268Sgonzo cpu_idcache_wbinv_all(); 2561239268Sgonzo#ifdef SMP 2562239268Sgonzo armv7_auxctrl((1 << 6) | (1 << 0), (1 << 6) | (1 << 0)); /* Enable SMP + TLB broadcasting */ 2563239268Sgonzo#endif 2564239268Sgonzo} 2565239268Sgonzo#endif /* CPU_CORTEXA */ 2566239268Sgonzo 2567239268Sgonzo 2568129198Scognet#ifdef CPU_SA110 2569129198Scognetstruct cpu_option sa110_options[] = { 2570129198Scognet#ifdef COMPAT_12 2571129198Scognet { "nocache", IGN, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2572129198Scognet { "nowritebuf", IGN, BIC, CPU_CONTROL_WBUF_ENABLE }, 2573129198Scognet#endif /* COMPAT_12 */ 2574129198Scognet { "cpu.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2575129198Scognet { "cpu.nocache", OR, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2576129198Scognet { "sa110.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2577129198Scognet { "sa110.icache", BIC, OR, CPU_CONTROL_IC_ENABLE }, 2578129198Scognet { "sa110.dcache", BIC, OR, CPU_CONTROL_DC_ENABLE }, 2579129198Scognet { "cpu.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 2580129198Scognet { "cpu.nowritebuf", OR, BIC, CPU_CONTROL_WBUF_ENABLE }, 2581129198Scognet { "sa110.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 2582129198Scognet { NULL, IGN, IGN, 0 } 2583129198Scognet}; 2584129198Scognet 2585129198Scognetvoid 2586129198Scognetsa110_setup(args) 2587129198Scognet char *args; 2588129198Scognet{ 2589129198Scognet int cpuctrl, cpuctrlmask; 2590129198Scognet 2591129198Scognet cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 2592129198Scognet | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 2593129198Scognet | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 2594129198Scognet | CPU_CONTROL_WBUF_ENABLE; 2595129198Scognet cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 2596129198Scognet | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 2597129198Scognet | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 2598129198Scognet | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE 2599129198Scognet | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE 2600129198Scognet | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_BPRD_ENABLE 2601129198Scognet | CPU_CONTROL_CPCLK; 2602129198Scognet 2603129198Scognet#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 2604129198Scognet cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 2605129198Scognet#endif 2606129198Scognet 2607129198Scognet cpuctrl = parse_cpu_options(args, sa110_options, cpuctrl); 2608129198Scognet 2609129198Scognet#ifdef __ARMEB__ 2610129198Scognet cpuctrl |= CPU_CONTROL_BEND_ENABLE; 2611129198Scognet#endif 2612129198Scognet 2613129198Scognet /* Clear out the cache */ 2614129198Scognet cpu_idcache_wbinv_all(); 2615129198Scognet 2616129198Scognet /* Set the control register */ 2617129198Scognet ctrl = cpuctrl; 2618129198Scognet/* cpu_control(cpuctrlmask, cpuctrl);*/ 2619129198Scognet cpu_control(0xffffffff, cpuctrl); 2620129198Scognet 2621236991Simp /* 2622129198Scognet * enable clockswitching, note that this doesn't read or write to r0, 2623129198Scognet * r0 is just to make it valid asm 2624129198Scognet */ 2625129198Scognet __asm ("mcr 15, 0, r0, c15, c1, 2"); 2626129198Scognet} 2627129198Scognet#endif /* CPU_SA110 */ 2628129198Scognet 2629129198Scognet#if defined(CPU_SA1100) || defined(CPU_SA1110) 2630129198Scognetstruct cpu_option sa11x0_options[] = { 2631129198Scognet#ifdef COMPAT_12 2632129198Scognet { "nocache", IGN, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2633129198Scognet { "nowritebuf", IGN, BIC, CPU_CONTROL_WBUF_ENABLE }, 2634129198Scognet#endif /* COMPAT_12 */ 2635129198Scognet { "cpu.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2636129198Scognet { "cpu.nocache", OR, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2637129198Scognet { "sa11x0.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2638129198Scognet { "sa11x0.icache", BIC, OR, CPU_CONTROL_IC_ENABLE }, 2639129198Scognet { "sa11x0.dcache", BIC, OR, CPU_CONTROL_DC_ENABLE }, 2640129198Scognet { "cpu.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 2641129198Scognet { "cpu.nowritebuf", OR, BIC, CPU_CONTROL_WBUF_ENABLE }, 2642129198Scognet { "sa11x0.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 2643129198Scognet { NULL, IGN, IGN, 0 } 2644129198Scognet}; 2645129198Scognet 2646129198Scognetvoid 2647129198Scognetsa11x0_setup(args) 2648129198Scognet char *args; 2649129198Scognet{ 2650129198Scognet int cpuctrl, cpuctrlmask; 2651129198Scognet 2652129198Scognet cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 2653129198Scognet | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 2654129198Scognet | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 2655129198Scognet | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE; 2656129198Scognet cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 2657129198Scognet | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 2658129198Scognet | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 2659129198Scognet | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE 2660129198Scognet | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE 2661129198Scognet | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_BPRD_ENABLE 2662129198Scognet | CPU_CONTROL_CPCLK | CPU_CONTROL_VECRELOC; 2663129198Scognet 2664129198Scognet#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 2665129198Scognet cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 2666129198Scognet#endif 2667129198Scognet 2668129198Scognet 2669129198Scognet cpuctrl = parse_cpu_options(args, sa11x0_options, cpuctrl); 2670129198Scognet 2671129198Scognet#ifdef __ARMEB__ 2672129198Scognet cpuctrl |= CPU_CONTROL_BEND_ENABLE; 2673129198Scognet#endif 2674129198Scognet 2675129198Scognet if (vector_page == ARM_VECTORS_HIGH) 2676129198Scognet cpuctrl |= CPU_CONTROL_VECRELOC; 2677129198Scognet /* Clear out the cache */ 2678129198Scognet cpu_idcache_wbinv_all(); 2679236991Simp /* Set the control register */ 2680129198Scognet ctrl = cpuctrl; 2681129198Scognet cpu_control(0xffffffff, cpuctrl); 2682129198Scognet} 2683129198Scognet#endif /* CPU_SA1100 || CPU_SA1110 */ 2684129198Scognet 2685207611Skevlo#if defined(CPU_FA526) || defined(CPU_FA626TE) 2686201468Srpaulostruct cpu_option fa526_options[] = { 2687201468Srpaulo#ifdef COMPAT_12 2688201468Srpaulo { "nocache", IGN, BIC, (CPU_CONTROL_IC_ENABLE | 2689201468Srpaulo CPU_CONTROL_DC_ENABLE) }, 2690201468Srpaulo { "nowritebuf", IGN, BIC, CPU_CONTROL_WBUF_ENABLE }, 2691201468Srpaulo#endif /* COMPAT_12 */ 2692201468Srpaulo { "cpu.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | 2693201468Srpaulo CPU_CONTROL_DC_ENABLE) }, 2694201468Srpaulo { "cpu.nocache", OR, BIC, (CPU_CONTROL_IC_ENABLE | 2695201468Srpaulo CPU_CONTROL_DC_ENABLE) }, 2696201468Srpaulo { "cpu.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 2697201468Srpaulo { "cpu.nowritebuf", OR, BIC, CPU_CONTROL_WBUF_ENABLE }, 2698201468Srpaulo { NULL, IGN, IGN, 0 } 2699201468Srpaulo}; 2700201468Srpaulo 2701201468Srpaulovoid 2702201468Srpaulofa526_setup(char *args) 2703201468Srpaulo{ 2704201468Srpaulo int cpuctrl, cpuctrlmask; 2705201468Srpaulo 2706201468Srpaulo cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 2707201468Srpaulo | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 2708201468Srpaulo | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 2709204122Skevlo | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE 2710204122Skevlo | CPU_CONTROL_BPRD_ENABLE; 2711201468Srpaulo cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 2712201468Srpaulo | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 2713201468Srpaulo | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 2714201468Srpaulo | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE 2715201468Srpaulo | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE 2716201468Srpaulo | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_BPRD_ENABLE 2717201468Srpaulo | CPU_CONTROL_CPCLK | CPU_CONTROL_VECRELOC; 2718201468Srpaulo 2719201468Srpaulo#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 2720201468Srpaulo cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 2721201468Srpaulo#endif 2722201468Srpaulo 2723201468Srpaulo cpuctrl = parse_cpu_options(args, fa526_options, cpuctrl); 2724201468Srpaulo 2725201468Srpaulo#ifdef __ARMEB__ 2726201468Srpaulo cpuctrl |= CPU_CONTROL_BEND_ENABLE; 2727201468Srpaulo#endif 2728201468Srpaulo 2729201468Srpaulo if (vector_page == ARM_VECTORS_HIGH) 2730201468Srpaulo cpuctrl |= CPU_CONTROL_VECRELOC; 2731201468Srpaulo 2732201468Srpaulo /* Clear out the cache */ 2733201468Srpaulo cpu_idcache_wbinv_all(); 2734201468Srpaulo 2735201468Srpaulo /* Set the control register */ 2736201468Srpaulo ctrl = cpuctrl; 2737201468Srpaulo cpu_control(0xffffffff, cpuctrl); 2738201468Srpaulo} 2739207611Skevlo#endif /* CPU_FA526 || CPU_FA626TE */ 2740201468Srpaulo 2741201468Srpaulo 2742129198Scognet#if defined(CPU_IXP12X0) 2743129198Scognetstruct cpu_option ixp12x0_options[] = { 2744129198Scognet { "cpu.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2745129198Scognet { "cpu.nocache", OR, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2746129198Scognet { "ixp12x0.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2747129198Scognet { "ixp12x0.icache", BIC, OR, CPU_CONTROL_IC_ENABLE }, 2748129198Scognet { "ixp12x0.dcache", BIC, OR, CPU_CONTROL_DC_ENABLE }, 2749129198Scognet { "cpu.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 2750129198Scognet { "cpu.nowritebuf", OR, BIC, CPU_CONTROL_WBUF_ENABLE }, 2751129198Scognet { "ixp12x0.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 2752129198Scognet { NULL, IGN, IGN, 0 } 2753129198Scognet}; 2754129198Scognet 2755129198Scognetvoid 2756129198Scognetixp12x0_setup(args) 2757129198Scognet char *args; 2758129198Scognet{ 2759129198Scognet int cpuctrl, cpuctrlmask; 2760129198Scognet 2761129198Scognet 2762129198Scognet cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_DC_ENABLE 2763129198Scognet | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_SYST_ENABLE 2764129198Scognet | CPU_CONTROL_IC_ENABLE; 2765129198Scognet 2766129198Scognet cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_AFLT_ENABLE 2767129198Scognet | CPU_CONTROL_DC_ENABLE | CPU_CONTROL_WBUF_ENABLE 2768129198Scognet | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_SYST_ENABLE 2769129198Scognet | CPU_CONTROL_ROM_ENABLE | CPU_CONTROL_IC_ENABLE 2770129198Scognet | CPU_CONTROL_VECRELOC; 2771129198Scognet 2772129198Scognet#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 2773129198Scognet cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 2774129198Scognet#endif 2775129198Scognet 2776129198Scognet cpuctrl = parse_cpu_options(args, ixp12x0_options, cpuctrl); 2777129198Scognet 2778129198Scognet#ifdef __ARMEB__ 2779129198Scognet cpuctrl |= CPU_CONTROL_BEND_ENABLE; 2780129198Scognet#endif 2781129198Scognet 2782129198Scognet if (vector_page == ARM_VECTORS_HIGH) 2783129198Scognet cpuctrl |= CPU_CONTROL_VECRELOC; 2784129198Scognet 2785129198Scognet /* Clear out the cache */ 2786129198Scognet cpu_idcache_wbinv_all(); 2787129198Scognet 2788236991Simp /* Set the control register */ 2789129198Scognet ctrl = cpuctrl; 2790129198Scognet /* cpu_control(0xffffffff, cpuctrl); */ 2791129198Scognet cpu_control(cpuctrlmask, cpuctrl); 2792129198Scognet} 2793129198Scognet#endif /* CPU_IXP12X0 */ 2794129198Scognet 2795129198Scognet#if defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \ 2796161592Scognet defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \ 2797164080Scognet defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342) 2798129198Scognetstruct cpu_option xscale_options[] = { 2799129198Scognet#ifdef COMPAT_12 2800129198Scognet { "branchpredict", BIC, OR, CPU_CONTROL_BPRD_ENABLE }, 2801129198Scognet { "nocache", IGN, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2802129198Scognet#endif /* COMPAT_12 */ 2803129198Scognet { "cpu.branchpredict", BIC, OR, CPU_CONTROL_BPRD_ENABLE }, 2804129198Scognet { "cpu.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2805129198Scognet { "cpu.nocache", OR, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2806129198Scognet { "xscale.branchpredict", BIC, OR, CPU_CONTROL_BPRD_ENABLE }, 2807129198Scognet { "xscale.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2808129198Scognet { "xscale.icache", BIC, OR, CPU_CONTROL_IC_ENABLE }, 2809129198Scognet { "xscale.dcache", BIC, OR, CPU_CONTROL_DC_ENABLE }, 2810129198Scognet { NULL, IGN, IGN, 0 } 2811129198Scognet}; 2812129198Scognet 2813129198Scognetvoid 2814129198Scognetxscale_setup(args) 2815129198Scognet char *args; 2816129198Scognet{ 2817129198Scognet uint32_t auxctl; 2818129198Scognet int cpuctrl, cpuctrlmask; 2819129198Scognet 2820129198Scognet /* 2821129198Scognet * The XScale Write Buffer is always enabled. Our option 2822129198Scognet * is to enable/disable coalescing. Note that bits 6:3 2823129198Scognet * must always be enabled. 2824129198Scognet */ 2825129198Scognet 2826129198Scognet cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 2827129198Scognet | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 2828129198Scognet | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 2829129198Scognet | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE 2830129198Scognet | CPU_CONTROL_BPRD_ENABLE; 2831129198Scognet cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 2832129198Scognet | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 2833129198Scognet | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 2834129198Scognet | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE 2835129198Scognet | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE 2836129198Scognet | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_BPRD_ENABLE 2837171618Scognet | CPU_CONTROL_CPCLK | CPU_CONTROL_VECRELOC | \ 2838171618Scognet CPU_CONTROL_L2_ENABLE; 2839129198Scognet 2840129198Scognet#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 2841129198Scognet cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 2842129198Scognet#endif 2843129198Scognet 2844129198Scognet cpuctrl = parse_cpu_options(args, xscale_options, cpuctrl); 2845129198Scognet 2846129198Scognet#ifdef __ARMEB__ 2847129198Scognet cpuctrl |= CPU_CONTROL_BEND_ENABLE; 2848129198Scognet#endif 2849129198Scognet 2850129198Scognet if (vector_page == ARM_VECTORS_HIGH) 2851129198Scognet cpuctrl |= CPU_CONTROL_VECRELOC; 2852171618Scognet#ifdef CPU_XSCALE_CORE3 2853171618Scognet cpuctrl |= CPU_CONTROL_L2_ENABLE; 2854171618Scognet#endif 2855129198Scognet 2856129198Scognet /* Clear out the cache */ 2857129198Scognet cpu_idcache_wbinv_all(); 2858129198Scognet 2859129198Scognet /* 2860129198Scognet * Set the control register. Note that bits 6:3 must always 2861129198Scognet * be set to 1. 2862129198Scognet */ 2863129198Scognet ctrl = cpuctrl; 2864129198Scognet/* cpu_control(cpuctrlmask, cpuctrl);*/ 2865129198Scognet cpu_control(0xffffffff, cpuctrl); 2866129198Scognet 2867129198Scognet /* Make sure write coalescing is turned on */ 2868129198Scognet __asm __volatile("mrc p15, 0, %0, c1, c0, 1" 2869129198Scognet : "=r" (auxctl)); 2870129198Scognet#ifdef XSCALE_NO_COALESCE_WRITES 2871129198Scognet auxctl |= XSCALE_AUXCTL_K; 2872129198Scognet#else 2873129198Scognet auxctl &= ~XSCALE_AUXCTL_K; 2874129198Scognet#endif 2875171618Scognet#ifdef CPU_XSCALE_CORE3 2876171618Scognet auxctl |= XSCALE_AUXCTL_LLR; 2877171618Scognet auxctl |= XSCALE_AUXCTL_MD_MASK; 2878171618Scognet#endif 2879129198Scognet __asm __volatile("mcr p15, 0, %0, c1, c0, 1" 2880129198Scognet : : "r" (auxctl)); 2881129198Scognet} 2882236991Simp#endif /* CPU_XSCALE_80200 || CPU_XSCALE_80321 || CPU_XSCALE_PXA2X0 || CPU_XSCALE_IXP425 2883161592Scognet CPU_XSCALE_80219 */ 2884