cpufunc.c revision 295096
1129198Scognet/* $NetBSD: cpufunc.c,v 1.65 2003/11/05 12:53:15 scw Exp $ */ 2129198Scognet 3139735Simp/*- 4129198Scognet * arm9 support code Copyright (C) 2001 ARM Ltd 5129198Scognet * Copyright (c) 1997 Mark Brinicombe. 6129198Scognet * Copyright (c) 1997 Causality Limited 7129198Scognet * All rights reserved. 8129198Scognet * 9129198Scognet * Redistribution and use in source and binary forms, with or without 10129198Scognet * modification, are permitted provided that the following conditions 11129198Scognet * are met: 12129198Scognet * 1. Redistributions of source code must retain the above copyright 13129198Scognet * notice, this list of conditions and the following disclaimer. 14129198Scognet * 2. Redistributions in binary form must reproduce the above copyright 15129198Scognet * notice, this list of conditions and the following disclaimer in the 16129198Scognet * documentation and/or other materials provided with the distribution. 17129198Scognet * 3. All advertising materials mentioning features or use of this software 18129198Scognet * must display the following acknowledgement: 19129198Scognet * This product includes software developed by Causality Limited. 20129198Scognet * 4. The name of Causality Limited may not be used to endorse or promote 21129198Scognet * products derived from this software without specific prior written 22129198Scognet * permission. 23129198Scognet * 24129198Scognet * THIS SOFTWARE IS PROVIDED BY CAUSALITY LIMITED ``AS IS'' AND ANY EXPRESS 25129198Scognet * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 26129198Scognet * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 27129198Scognet * DISCLAIMED. IN NO EVENT SHALL CAUSALITY LIMITED BE LIABLE FOR ANY DIRECT, 28129198Scognet * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 29129198Scognet * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 30129198Scognet * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31129198Scognet * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32129198Scognet * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33129198Scognet * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34129198Scognet * SUCH DAMAGE. 35129198Scognet * 36129198Scognet * RiscBSD kernel project 37129198Scognet * 38129198Scognet * cpufuncs.c 39129198Scognet * 40129198Scognet * C functions for supporting CPU / MMU / TLB specific operations. 41129198Scognet * 42129198Scognet * Created : 30/01/97 43129198Scognet */ 44129198Scognet#include <sys/cdefs.h> 45129198Scognet__FBSDID("$FreeBSD: head/sys/arm/arm/cpufunc.c 295096 2016-01-31 16:34:06Z mmel $"); 46129198Scognet 47129198Scognet#include <sys/param.h> 48129198Scognet#include <sys/systm.h> 49129198Scognet#include <sys/lock.h> 50129198Scognet#include <sys/mutex.h> 51132472Scognet#include <sys/bus.h> 52132472Scognet#include <machine/bus.h> 53129198Scognet#include <machine/cpu.h> 54129198Scognet#include <machine/disassem.h> 55129198Scognet 56129198Scognet#include <vm/vm.h> 57129198Scognet#include <vm/pmap.h> 58166655Scognet#include <vm/uma.h> 59129198Scognet 60129198Scognet#include <machine/cpuconf.h> 61129198Scognet#include <machine/cpufunc.h> 62129198Scognet 63161592Scognet#if defined(CPU_XSCALE_80321) || defined(CPU_XSCALE_80219) 64135646Scognet#include <arm/xscale/i80321/i80321reg.h> 65135646Scognet#include <arm/xscale/i80321/i80321var.h> 66129198Scognet#endif 67129198Scognet 68243579Smarcel/* 69243579Smarcel * Some definitions in i81342reg.h clash with i80321reg.h. 70243579Smarcel * This only happens for the LINT kernel. As it happens, 71243579Smarcel * we don't need anything from i81342reg.h that we already 72243579Smarcel * got from somewhere else during a LINT compile. 73243579Smarcel */ 74243579Smarcel#if defined(CPU_XSCALE_81342) && !defined(COMPILING_LINT) 75164080Scognet#include <arm/xscale/i8134x/i81342reg.h> 76164080Scognet#endif 77164080Scognet 78129198Scognet#ifdef CPU_XSCALE_IXP425 79135646Scognet#include <arm/xscale/ixp425/ixp425reg.h> 80135646Scognet#include <arm/xscale/ixp425/ixp425var.h> 81129198Scognet#endif 82129198Scognet 83129198Scognet/* PRIMARY CACHE VARIABLES */ 84129198Scognetint arm_picache_size; 85129198Scognetint arm_picache_line_size; 86129198Scognetint arm_picache_ways; 87129198Scognet 88129198Scognetint arm_pdcache_size; /* and unified */ 89129198Scognetint arm_pdcache_line_size; 90129198Scognetint arm_pdcache_ways; 91129198Scognet 92129198Scognetint arm_pcache_type; 93129198Scognetint arm_pcache_unified; 94129198Scognet 95129198Scognetint arm_dcache_align; 96129198Scognetint arm_dcache_align_mask; 97129198Scognet 98239268Sgonzou_int arm_cache_level; 99239268Sgonzou_int arm_cache_type[14]; 100239268Sgonzou_int arm_cache_loc; 101239268Sgonzo 102129198Scognetint ctrl; 103129198Scognet 104129198Scognet#ifdef CPU_ARM9 105129198Scognetstruct cpu_functions arm9_cpufuncs = { 106129198Scognet /* CPU functions */ 107129198Scognet 108129198Scognet cpufunc_nullop, /* cpwait */ 109129198Scognet 110129198Scognet /* MMU functions */ 111129198Scognet 112129198Scognet cpufunc_control, /* control */ 113129198Scognet arm9_setttb, /* Setttb */ 114129198Scognet 115129198Scognet /* TLB functions */ 116129198Scognet 117129198Scognet armv4_tlb_flushID, /* tlb_flushID */ 118129198Scognet arm9_tlb_flushID_SE, /* tlb_flushID_SE */ 119129198Scognet armv4_tlb_flushI, /* tlb_flushI */ 120129198Scognet (void *)armv4_tlb_flushI, /* tlb_flushI_SE */ 121129198Scognet armv4_tlb_flushD, /* tlb_flushD */ 122129198Scognet armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 123129198Scognet 124129198Scognet /* Cache operations */ 125129198Scognet 126146605Scognet arm9_icache_sync_all, /* icache_sync_all */ 127146605Scognet arm9_icache_sync_range, /* icache_sync_range */ 128129198Scognet 129146605Scognet arm9_dcache_wbinv_all, /* dcache_wbinv_all */ 130146605Scognet arm9_dcache_wbinv_range, /* dcache_wbinv_range */ 131195798Sraj arm9_dcache_inv_range, /* dcache_inv_range */ 132146605Scognet arm9_dcache_wb_range, /* dcache_wb_range */ 133129198Scognet 134262420Sian armv4_idcache_inv_all, /* idcache_inv_all */ 135146605Scognet arm9_idcache_wbinv_all, /* idcache_wbinv_all */ 136146605Scognet arm9_idcache_wbinv_range, /* idcache_wbinv_range */ 137171618Scognet cpufunc_nullop, /* l2cache_wbinv_all */ 138171781Scognet (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 139171781Scognet (void *)cpufunc_nullop, /* l2cache_inv_range */ 140171781Scognet (void *)cpufunc_nullop, /* l2cache_wb_range */ 141265870Sian (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ 142129198Scognet 143129198Scognet /* Other functions */ 144129198Scognet 145129198Scognet cpufunc_nullop, /* flush_prefetchbuf */ 146129198Scognet armv4_drain_writebuf, /* drain_writebuf */ 147129198Scognet 148129198Scognet (void *)cpufunc_nullop, /* sleep */ 149129198Scognet 150129198Scognet /* Soft functions */ 151129198Scognet 152129198Scognet arm9_context_switch, /* context_switch */ 153129198Scognet 154129198Scognet arm9_setup /* cpu setup */ 155129198Scognet 156129198Scognet}; 157129198Scognet#endif /* CPU_ARM9 */ 158129198Scognet 159280809Sandrew#if defined(CPU_ARM9E) 160172738Simpstruct cpu_functions armv5_ec_cpufuncs = { 161172738Simp /* CPU functions */ 162172738Simp 163172738Simp cpufunc_nullop, /* cpwait */ 164172738Simp 165172738Simp /* MMU functions */ 166172738Simp 167172738Simp cpufunc_control, /* control */ 168172738Simp armv5_ec_setttb, /* Setttb */ 169172738Simp 170172738Simp /* TLB functions */ 171172738Simp 172172738Simp armv4_tlb_flushID, /* tlb_flushID */ 173172738Simp arm10_tlb_flushID_SE, /* tlb_flushID_SE */ 174172738Simp armv4_tlb_flushI, /* tlb_flushI */ 175172738Simp arm10_tlb_flushI_SE, /* tlb_flushI_SE */ 176172738Simp armv4_tlb_flushD, /* tlb_flushD */ 177172738Simp armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 178172738Simp 179172738Simp /* Cache operations */ 180172738Simp 181172738Simp armv5_ec_icache_sync_all, /* icache_sync_all */ 182172738Simp armv5_ec_icache_sync_range, /* icache_sync_range */ 183172738Simp 184172738Simp armv5_ec_dcache_wbinv_all, /* dcache_wbinv_all */ 185172738Simp armv5_ec_dcache_wbinv_range, /* dcache_wbinv_range */ 186195798Sraj armv5_ec_dcache_inv_range, /* dcache_inv_range */ 187172738Simp armv5_ec_dcache_wb_range, /* dcache_wb_range */ 188172738Simp 189262420Sian armv4_idcache_inv_all, /* idcache_inv_all */ 190172738Simp armv5_ec_idcache_wbinv_all, /* idcache_wbinv_all */ 191172738Simp armv5_ec_idcache_wbinv_range, /* idcache_wbinv_range */ 192172738Simp 193173442Scognet cpufunc_nullop, /* l2cache_wbinv_all */ 194173442Scognet (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 195173442Scognet (void *)cpufunc_nullop, /* l2cache_inv_range */ 196173442Scognet (void *)cpufunc_nullop, /* l2cache_wb_range */ 197265870Sian (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ 198236991Simp 199172738Simp /* Other functions */ 200172738Simp 201172738Simp cpufunc_nullop, /* flush_prefetchbuf */ 202172738Simp armv4_drain_writebuf, /* drain_writebuf */ 203172738Simp 204172738Simp (void *)cpufunc_nullop, /* sleep */ 205172738Simp 206172738Simp /* Soft functions */ 207172738Simp 208172738Simp arm10_context_switch, /* context_switch */ 209172738Simp 210172738Simp arm10_setup /* cpu setup */ 211172738Simp 212172738Simp}; 213183835Sraj 214186933Srajstruct cpu_functions sheeva_cpufuncs = { 215183835Sraj /* CPU functions */ 216183835Sraj 217183835Sraj cpufunc_nullop, /* cpwait */ 218183835Sraj 219183835Sraj /* MMU functions */ 220183835Sraj 221183835Sraj cpufunc_control, /* control */ 222186933Sraj sheeva_setttb, /* Setttb */ 223183835Sraj 224183835Sraj /* TLB functions */ 225183835Sraj 226183835Sraj armv4_tlb_flushID, /* tlb_flushID */ 227183835Sraj arm10_tlb_flushID_SE, /* tlb_flushID_SE */ 228183835Sraj armv4_tlb_flushI, /* tlb_flushI */ 229183835Sraj arm10_tlb_flushI_SE, /* tlb_flushI_SE */ 230183835Sraj armv4_tlb_flushD, /* tlb_flushD */ 231183835Sraj armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 232183835Sraj 233183835Sraj /* Cache operations */ 234183835Sraj 235183835Sraj armv5_ec_icache_sync_all, /* icache_sync_all */ 236183835Sraj armv5_ec_icache_sync_range, /* icache_sync_range */ 237183835Sraj 238183835Sraj armv5_ec_dcache_wbinv_all, /* dcache_wbinv_all */ 239186933Sraj sheeva_dcache_wbinv_range, /* dcache_wbinv_range */ 240186933Sraj sheeva_dcache_inv_range, /* dcache_inv_range */ 241186933Sraj sheeva_dcache_wb_range, /* dcache_wb_range */ 242183835Sraj 243262420Sian armv4_idcache_inv_all, /* idcache_inv_all */ 244183835Sraj armv5_ec_idcache_wbinv_all, /* idcache_wbinv_all */ 245186933Sraj sheeva_idcache_wbinv_range, /* idcache_wbinv_all */ 246183835Sraj 247186933Sraj sheeva_l2cache_wbinv_all, /* l2cache_wbinv_all */ 248186933Sraj sheeva_l2cache_wbinv_range, /* l2cache_wbinv_range */ 249186933Sraj sheeva_l2cache_inv_range, /* l2cache_inv_range */ 250186933Sraj sheeva_l2cache_wb_range, /* l2cache_wb_range */ 251265870Sian (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ 252183835Sraj 253183835Sraj /* Other functions */ 254183835Sraj 255183835Sraj cpufunc_nullop, /* flush_prefetchbuf */ 256183835Sraj armv4_drain_writebuf, /* drain_writebuf */ 257183835Sraj 258212825Smav sheeva_cpu_sleep, /* sleep */ 259183835Sraj 260183835Sraj /* Soft functions */ 261183835Sraj 262183835Sraj arm10_context_switch, /* context_switch */ 263183835Sraj 264183835Sraj arm10_setup /* cpu setup */ 265183835Sraj}; 266280809Sandrew#endif /* CPU_ARM9E */ 267172738Simp 268239268Sgonzo#ifdef CPU_MV_PJ4B 269239268Sgonzostruct cpu_functions pj4bv7_cpufuncs = { 270239268Sgonzo /* CPU functions */ 271239268Sgonzo 272266672Szbb armv7_drain_writebuf, /* cpwait */ 273239268Sgonzo 274239268Sgonzo /* MMU functions */ 275239268Sgonzo 276239268Sgonzo cpufunc_control, /* control */ 277266672Szbb armv7_setttb, /* Setttb */ 278239268Sgonzo 279239268Sgonzo /* TLB functions */ 280239268Sgonzo 281239268Sgonzo armv7_tlb_flushID, /* tlb_flushID */ 282239268Sgonzo armv7_tlb_flushID_SE, /* tlb_flushID_SE */ 283239268Sgonzo armv7_tlb_flushID, /* tlb_flushI */ 284239268Sgonzo armv7_tlb_flushID_SE, /* tlb_flushI_SE */ 285239268Sgonzo armv7_tlb_flushID, /* tlb_flushD */ 286239268Sgonzo armv7_tlb_flushID_SE, /* tlb_flushD_SE */ 287239268Sgonzo 288239268Sgonzo /* Cache operations */ 289239268Sgonzo armv7_idcache_wbinv_all, /* icache_sync_all */ 290239268Sgonzo armv7_icache_sync_range, /* icache_sync_range */ 291239268Sgonzo 292239268Sgonzo armv7_dcache_wbinv_all, /* dcache_wbinv_all */ 293239268Sgonzo armv7_dcache_wbinv_range, /* dcache_wbinv_range */ 294239268Sgonzo armv7_dcache_inv_range, /* dcache_inv_range */ 295239268Sgonzo armv7_dcache_wb_range, /* dcache_wb_range */ 296239268Sgonzo 297262420Sian armv7_idcache_inv_all, /* idcache_inv_all */ 298239268Sgonzo armv7_idcache_wbinv_all, /* idcache_wbinv_all */ 299239268Sgonzo armv7_idcache_wbinv_range, /* idcache_wbinv_all */ 300239268Sgonzo 301239268Sgonzo (void *)cpufunc_nullop, /* l2cache_wbinv_all */ 302239268Sgonzo (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 303239268Sgonzo (void *)cpufunc_nullop, /* l2cache_inv_range */ 304239268Sgonzo (void *)cpufunc_nullop, /* l2cache_wb_range */ 305265870Sian (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ 306239268Sgonzo 307239268Sgonzo /* Other functions */ 308239268Sgonzo 309266672Szbb cpufunc_nullop, /* flush_prefetchbuf */ 310266672Szbb armv7_drain_writebuf, /* drain_writebuf */ 311239268Sgonzo 312239268Sgonzo (void *)cpufunc_nullop, /* sleep */ 313239268Sgonzo 314239268Sgonzo /* Soft functions */ 315266672Szbb armv7_context_switch, /* context_switch */ 316239268Sgonzo 317239268Sgonzo pj4bv7_setup /* cpu setup */ 318239268Sgonzo}; 319239268Sgonzo#endif /* CPU_MV_PJ4B */ 320239268Sgonzo 321280847Sandrew#if defined(CPU_XSCALE_80321) || \ 322161592Scognet defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \ 323161592Scognet defined(CPU_XSCALE_80219) 324161592Scognet 325129198Scognetstruct cpu_functions xscale_cpufuncs = { 326129198Scognet /* CPU functions */ 327283366Sandrew 328129198Scognet xscale_cpwait, /* cpwait */ 329129198Scognet 330129198Scognet /* MMU functions */ 331129198Scognet 332129198Scognet xscale_control, /* control */ 333129198Scognet xscale_setttb, /* setttb */ 334129198Scognet 335129198Scognet /* TLB functions */ 336129198Scognet 337129198Scognet armv4_tlb_flushID, /* tlb_flushID */ 338129198Scognet xscale_tlb_flushID_SE, /* tlb_flushID_SE */ 339129198Scognet armv4_tlb_flushI, /* tlb_flushI */ 340129198Scognet (void *)armv4_tlb_flushI, /* tlb_flushI_SE */ 341129198Scognet armv4_tlb_flushD, /* tlb_flushD */ 342129198Scognet armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 343129198Scognet 344129198Scognet /* Cache operations */ 345129198Scognet 346129198Scognet xscale_cache_syncI, /* icache_sync_all */ 347129198Scognet xscale_cache_syncI_rng, /* icache_sync_range */ 348129198Scognet 349129198Scognet xscale_cache_purgeD, /* dcache_wbinv_all */ 350129198Scognet xscale_cache_purgeD_rng, /* dcache_wbinv_range */ 351129198Scognet xscale_cache_flushD_rng, /* dcache_inv_range */ 352129198Scognet xscale_cache_cleanD_rng, /* dcache_wb_range */ 353129198Scognet 354262420Sian xscale_cache_flushID, /* idcache_inv_all */ 355129198Scognet xscale_cache_purgeID, /* idcache_wbinv_all */ 356129198Scognet xscale_cache_purgeID_rng, /* idcache_wbinv_range */ 357171618Scognet cpufunc_nullop, /* l2cache_wbinv_all */ 358171781Scognet (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 359171781Scognet (void *)cpufunc_nullop, /* l2cache_inv_range */ 360171781Scognet (void *)cpufunc_nullop, /* l2cache_wb_range */ 361265870Sian (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ 362129198Scognet 363129198Scognet /* Other functions */ 364129198Scognet 365129198Scognet cpufunc_nullop, /* flush_prefetchbuf */ 366129198Scognet armv4_drain_writebuf, /* drain_writebuf */ 367129198Scognet 368129198Scognet xscale_cpu_sleep, /* sleep */ 369129198Scognet 370129198Scognet /* Soft functions */ 371129198Scognet 372129198Scognet xscale_context_switch, /* context_switch */ 373129198Scognet 374129198Scognet xscale_setup /* cpu setup */ 375129198Scognet}; 376129198Scognet#endif 377280847Sandrew/* CPU_XSCALE_80321 || CPU_XSCALE_PXA2X0 || CPU_XSCALE_IXP425 378161592Scognet CPU_XSCALE_80219 */ 379129198Scognet 380164080Scognet#ifdef CPU_XSCALE_81342 381164080Scognetstruct cpu_functions xscalec3_cpufuncs = { 382164080Scognet /* CPU functions */ 383283366Sandrew 384164080Scognet xscale_cpwait, /* cpwait */ 385164080Scognet 386164080Scognet /* MMU functions */ 387164080Scognet 388164080Scognet xscale_control, /* control */ 389164080Scognet xscalec3_setttb, /* setttb */ 390164080Scognet 391164080Scognet /* TLB functions */ 392164080Scognet 393164080Scognet armv4_tlb_flushID, /* tlb_flushID */ 394164080Scognet xscale_tlb_flushID_SE, /* tlb_flushID_SE */ 395164080Scognet armv4_tlb_flushI, /* tlb_flushI */ 396164080Scognet (void *)armv4_tlb_flushI, /* tlb_flushI_SE */ 397164080Scognet armv4_tlb_flushD, /* tlb_flushD */ 398164080Scognet armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 399164080Scognet 400164080Scognet /* Cache operations */ 401164080Scognet 402164080Scognet xscalec3_cache_syncI, /* icache_sync_all */ 403171618Scognet xscalec3_cache_syncI_rng, /* icache_sync_range */ 404164080Scognet 405164080Scognet xscalec3_cache_purgeD, /* dcache_wbinv_all */ 406164080Scognet xscalec3_cache_purgeD_rng, /* dcache_wbinv_range */ 407164080Scognet xscale_cache_flushD_rng, /* dcache_inv_range */ 408164080Scognet xscalec3_cache_cleanD_rng, /* dcache_wb_range */ 409164080Scognet 410262420Sian xscale_cache_flushID, /* idcache_inv_all */ 411171618Scognet xscalec3_cache_purgeID, /* idcache_wbinv_all */ 412164080Scognet xscalec3_cache_purgeID_rng, /* idcache_wbinv_range */ 413171618Scognet xscalec3_l2cache_purge, /* l2cache_wbinv_all */ 414171618Scognet xscalec3_l2cache_purge_rng, /* l2cache_wbinv_range */ 415171618Scognet xscalec3_l2cache_flush_rng, /* l2cache_inv_range */ 416171618Scognet xscalec3_l2cache_clean_rng, /* l2cache_wb_range */ 417265870Sian (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ 418164080Scognet 419164080Scognet /* Other functions */ 420164080Scognet 421164080Scognet cpufunc_nullop, /* flush_prefetchbuf */ 422164080Scognet armv4_drain_writebuf, /* drain_writebuf */ 423164080Scognet 424164080Scognet xscale_cpu_sleep, /* sleep */ 425164080Scognet 426164080Scognet /* Soft functions */ 427164080Scognet 428164080Scognet xscalec3_context_switch, /* context_switch */ 429164080Scognet 430164080Scognet xscale_setup /* cpu setup */ 431164080Scognet}; 432164080Scognet#endif /* CPU_XSCALE_81342 */ 433201468Srpaulo 434201468Srpaulo 435280842Sandrew#if defined(CPU_FA526) 436201468Srpaulostruct cpu_functions fa526_cpufuncs = { 437201468Srpaulo /* CPU functions */ 438201468Srpaulo 439207611Skevlo cpufunc_nullop, /* cpwait */ 440201468Srpaulo 441201468Srpaulo /* MMU functions */ 442201468Srpaulo 443207611Skevlo cpufunc_control, /* control */ 444207611Skevlo fa526_setttb, /* setttb */ 445201468Srpaulo 446201468Srpaulo /* TLB functions */ 447201468Srpaulo 448207611Skevlo armv4_tlb_flushID, /* tlb_flushID */ 449207611Skevlo fa526_tlb_flushID_SE, /* tlb_flushID_SE */ 450207611Skevlo armv4_tlb_flushI, /* tlb_flushI */ 451207611Skevlo fa526_tlb_flushI_SE, /* tlb_flushI_SE */ 452207611Skevlo armv4_tlb_flushD, /* tlb_flushD */ 453207611Skevlo armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 454201468Srpaulo 455201468Srpaulo /* Cache operations */ 456201468Srpaulo 457207611Skevlo fa526_icache_sync_all, /* icache_sync_all */ 458207611Skevlo fa526_icache_sync_range, /* icache_sync_range */ 459201468Srpaulo 460207611Skevlo fa526_dcache_wbinv_all, /* dcache_wbinv_all */ 461207611Skevlo fa526_dcache_wbinv_range, /* dcache_wbinv_range */ 462207611Skevlo fa526_dcache_inv_range, /* dcache_inv_range */ 463207611Skevlo fa526_dcache_wb_range, /* dcache_wb_range */ 464201468Srpaulo 465262420Sian armv4_idcache_inv_all, /* idcache_inv_all */ 466207611Skevlo fa526_idcache_wbinv_all, /* idcache_wbinv_all */ 467207611Skevlo fa526_idcache_wbinv_range, /* idcache_wbinv_range */ 468207611Skevlo cpufunc_nullop, /* l2cache_wbinv_all */ 469207611Skevlo (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 470207611Skevlo (void *)cpufunc_nullop, /* l2cache_inv_range */ 471207611Skevlo (void *)cpufunc_nullop, /* l2cache_wb_range */ 472265870Sian (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ 473201468Srpaulo 474201468Srpaulo /* Other functions */ 475201468Srpaulo 476207611Skevlo fa526_flush_prefetchbuf, /* flush_prefetchbuf */ 477207611Skevlo armv4_drain_writebuf, /* drain_writebuf */ 478201468Srpaulo 479207611Skevlo fa526_cpu_sleep, /* sleep */ 480201468Srpaulo 481201468Srpaulo /* Soft functions */ 482201468Srpaulo 483201468Srpaulo 484207611Skevlo fa526_context_switch, /* context_switch */ 485201468Srpaulo 486207611Skevlo fa526_setup /* cpu setup */ 487236991Simp}; 488280842Sandrew#endif /* CPU_FA526 */ 489201468Srpaulo 490244480Sgonzo#if defined(CPU_ARM1176) 491244480Sgonzostruct cpu_functions arm1176_cpufuncs = { 492244480Sgonzo /* CPU functions */ 493283366Sandrew 494244480Sgonzo cpufunc_nullop, /* cpwait */ 495283366Sandrew 496244480Sgonzo /* MMU functions */ 497283366Sandrew 498244480Sgonzo cpufunc_control, /* control */ 499244480Sgonzo arm11x6_setttb, /* Setttb */ 500283366Sandrew 501244480Sgonzo /* TLB functions */ 502283366Sandrew 503244480Sgonzo arm11_tlb_flushID, /* tlb_flushID */ 504244480Sgonzo arm11_tlb_flushID_SE, /* tlb_flushID_SE */ 505244480Sgonzo arm11_tlb_flushI, /* tlb_flushI */ 506244480Sgonzo arm11_tlb_flushI_SE, /* tlb_flushI_SE */ 507244480Sgonzo arm11_tlb_flushD, /* tlb_flushD */ 508244480Sgonzo arm11_tlb_flushD_SE, /* tlb_flushD_SE */ 509283366Sandrew 510244480Sgonzo /* Cache operations */ 511283366Sandrew 512244480Sgonzo arm11x6_icache_sync_all, /* icache_sync_all */ 513244480Sgonzo arm11x6_icache_sync_range, /* icache_sync_range */ 514283366Sandrew 515244480Sgonzo arm11x6_dcache_wbinv_all, /* dcache_wbinv_all */ 516244480Sgonzo armv6_dcache_wbinv_range, /* dcache_wbinv_range */ 517244480Sgonzo armv6_dcache_inv_range, /* dcache_inv_range */ 518244480Sgonzo armv6_dcache_wb_range, /* dcache_wb_range */ 519283366Sandrew 520262420Sian armv6_idcache_inv_all, /* idcache_inv_all */ 521244480Sgonzo arm11x6_idcache_wbinv_all, /* idcache_wbinv_all */ 522244480Sgonzo arm11x6_idcache_wbinv_range, /* idcache_wbinv_range */ 523283366Sandrew 524244480Sgonzo (void *)cpufunc_nullop, /* l2cache_wbinv_all */ 525244480Sgonzo (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 526244480Sgonzo (void *)cpufunc_nullop, /* l2cache_inv_range */ 527244480Sgonzo (void *)cpufunc_nullop, /* l2cache_wb_range */ 528265870Sian (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ 529283366Sandrew 530244480Sgonzo /* Other functions */ 531283366Sandrew 532244480Sgonzo arm11x6_flush_prefetchbuf, /* flush_prefetchbuf */ 533244480Sgonzo arm11_drain_writebuf, /* drain_writebuf */ 534283366Sandrew 535244480Sgonzo arm11x6_sleep, /* sleep */ 536283366Sandrew 537244480Sgonzo /* Soft functions */ 538283366Sandrew 539244480Sgonzo arm11_context_switch, /* context_switch */ 540283366Sandrew 541244480Sgonzo arm11x6_setup /* cpu setup */ 542244480Sgonzo}; 543244480Sgonzo#endif /*CPU_ARM1176 */ 544239701Sgonzo 545259640Sganbold#if defined(CPU_CORTEXA) || defined(CPU_KRAIT) 546239268Sgonzostruct cpu_functions cortexa_cpufuncs = { 547239268Sgonzo /* CPU functions */ 548283366Sandrew 549239268Sgonzo cpufunc_nullop, /* cpwait */ 550283366Sandrew 551239268Sgonzo /* MMU functions */ 552283366Sandrew 553239268Sgonzo cpufunc_control, /* control */ 554239268Sgonzo armv7_setttb, /* Setttb */ 555283366Sandrew 556283366Sandrew /* 557263251Sian * TLB functions. ARMv7 does all TLB ops based on a unified TLB model 558263251Sian * whether the hardware implements separate I+D or not, so we use the 559263251Sian * same 'ID' functions for all 3 variations. 560263251Sian */ 561283366Sandrew 562243024Scognet armv7_tlb_flushID, /* tlb_flushID */ 563239268Sgonzo armv7_tlb_flushID_SE, /* tlb_flushID_SE */ 564263251Sian armv7_tlb_flushID, /* tlb_flushI */ 565263251Sian armv7_tlb_flushID_SE, /* tlb_flushI_SE */ 566263251Sian armv7_tlb_flushID, /* tlb_flushD */ 567263251Sian armv7_tlb_flushID_SE, /* tlb_flushD_SE */ 568283366Sandrew 569239268Sgonzo /* Cache operations */ 570283366Sandrew 571264994Sian armv7_icache_sync_all, /* icache_sync_all */ 572239268Sgonzo armv7_icache_sync_range, /* icache_sync_range */ 573283366Sandrew 574239268Sgonzo armv7_dcache_wbinv_all, /* dcache_wbinv_all */ 575239268Sgonzo armv7_dcache_wbinv_range, /* dcache_wbinv_range */ 576239268Sgonzo armv7_dcache_inv_range, /* dcache_inv_range */ 577239268Sgonzo armv7_dcache_wb_range, /* dcache_wb_range */ 578283366Sandrew 579262420Sian armv7_idcache_inv_all, /* idcache_inv_all */ 580239268Sgonzo armv7_idcache_wbinv_all, /* idcache_wbinv_all */ 581239268Sgonzo armv7_idcache_wbinv_range, /* idcache_wbinv_range */ 582283366Sandrew 583283366Sandrew /* 584243026Scognet * Note: For CPUs using the PL310 the L2 ops are filled in when the 585239268Sgonzo * L2 cache controller is actually enabled. 586239268Sgonzo */ 587239268Sgonzo cpufunc_nullop, /* l2cache_wbinv_all */ 588239268Sgonzo (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 589239268Sgonzo (void *)cpufunc_nullop, /* l2cache_inv_range */ 590239268Sgonzo (void *)cpufunc_nullop, /* l2cache_wb_range */ 591265870Sian (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ 592283366Sandrew 593239268Sgonzo /* Other functions */ 594283366Sandrew 595239268Sgonzo cpufunc_nullop, /* flush_prefetchbuf */ 596245478Scognet armv7_drain_writebuf, /* drain_writebuf */ 597283366Sandrew 598282934Sganbold armv7_cpu_sleep, /* sleep */ 599283366Sandrew 600239268Sgonzo /* Soft functions */ 601283366Sandrew 602245478Scognet armv7_context_switch, /* context_switch */ 603283366Sandrew 604239268Sgonzo cortexa_setup /* cpu setup */ 605239268Sgonzo}; 606239268Sgonzo#endif /* CPU_CORTEXA */ 607201468Srpaulo 608129198Scognet/* 609129198Scognet * Global constants also used by locore.s 610129198Scognet */ 611129198Scognet 612129198Scognetstruct cpu_functions cpufuncs; 613129198Scognetu_int cputype; 614129198Scognetu_int cpu_reset_needs_v4_MMU_disable; /* flag used in locore.s */ 615129198Scognet 616262958Sian#if defined(CPU_ARM9) || \ 617280824Sandrew defined (CPU_ARM9E) || \ 618280847Sandrew defined(CPU_ARM1176) || defined(CPU_XSCALE_80321) || \ 619207611Skevlo defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \ 620280842Sandrew defined(CPU_FA526) || defined(CPU_MV_PJ4B) || \ 621239268Sgonzo defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342) || \ 622259640Sganbold defined(CPU_CORTEXA) || defined(CPU_KRAIT) 623161592Scognet 624278518Szbb/* Global cache line sizes, use 32 as default */ 625278518Szbbint arm_dcache_min_line_size = 32; 626278518Szbbint arm_icache_min_line_size = 32; 627278518Szbbint arm_idcache_min_line_size = 32; 628278518Szbb 629137498Strhodesstatic void get_cachetype_cp15(void); 630129198Scognet 631129198Scognet/* Additional cache information local to this file. Log2 of some of the 632129198Scognet above numbers. */ 633129198Scognetstatic int arm_dcache_l2_nsets; 634129198Scognetstatic int arm_dcache_l2_assoc; 635129198Scognetstatic int arm_dcache_l2_linesize; 636129198Scognet 637129198Scognetstatic void 638129198Scognetget_cachetype_cp15() 639129198Scognet{ 640239268Sgonzo u_int ctype, isize, dsize, cpuid; 641239268Sgonzo u_int clevel, csize, i, sel; 642129198Scognet u_int multiplier; 643239268Sgonzo u_char type; 644129198Scognet 645129198Scognet __asm __volatile("mrc p15, 0, %0, c0, c0, 1" 646129198Scognet : "=r" (ctype)); 647129198Scognet 648295096Smmel cpuid = cpu_ident(); 649129198Scognet /* 650129198Scognet * ...and thus spake the ARM ARM: 651129198Scognet * 652129198Scognet * If an <opcode2> value corresponding to an unimplemented or 653129198Scognet * reserved ID register is encountered, the System Control 654129198Scognet * processor returns the value of the main ID register. 655129198Scognet */ 656239268Sgonzo if (ctype == cpuid) 657129198Scognet goto out; 658129198Scognet 659239268Sgonzo if (CPU_CT_FORMAT(ctype) == CPU_CT_ARMV7) { 660278518Szbb /* Resolve minimal cache line sizes */ 661278518Szbb arm_dcache_min_line_size = 1 << (CPU_CT_DMINLINE(ctype) + 2); 662278518Szbb arm_icache_min_line_size = 1 << (CPU_CT_IMINLINE(ctype) + 2); 663278518Szbb arm_idcache_min_line_size = 664278518Szbb min(arm_icache_min_line_size, arm_dcache_min_line_size); 665278518Szbb 666239268Sgonzo __asm __volatile("mrc p15, 1, %0, c0, c0, 1" 667239268Sgonzo : "=r" (clevel)); 668239268Sgonzo arm_cache_level = clevel; 669239268Sgonzo arm_cache_loc = CPU_CLIDR_LOC(arm_cache_level); 670239268Sgonzo i = 0; 671239268Sgonzo while ((type = (clevel & 0x7)) && i < 7) { 672239268Sgonzo if (type == CACHE_DCACHE || type == CACHE_UNI_CACHE || 673239268Sgonzo type == CACHE_SEP_CACHE) { 674239268Sgonzo sel = i << 1; 675239268Sgonzo __asm __volatile("mcr p15, 2, %0, c0, c0, 0" 676239268Sgonzo : : "r" (sel)); 677239268Sgonzo __asm __volatile("mrc p15, 1, %0, c0, c0, 0" 678239268Sgonzo : "=r" (csize)); 679239268Sgonzo arm_cache_type[sel] = csize; 680283366Sandrew arm_dcache_align = 1 << 681239268Sgonzo (CPUV7_CT_xSIZE_LEN(csize) + 4); 682239268Sgonzo arm_dcache_align_mask = arm_dcache_align - 1; 683239268Sgonzo } 684239268Sgonzo if (type == CACHE_ICACHE || type == CACHE_SEP_CACHE) { 685239268Sgonzo sel = (i << 1) | 1; 686239268Sgonzo __asm __volatile("mcr p15, 2, %0, c0, c0, 0" 687239268Sgonzo : : "r" (sel)); 688239268Sgonzo __asm __volatile("mrc p15, 1, %0, c0, c0, 0" 689239268Sgonzo : "=r" (csize)); 690239268Sgonzo arm_cache_type[sel] = csize; 691239268Sgonzo } 692239268Sgonzo i++; 693239268Sgonzo clevel >>= 3; 694239268Sgonzo } 695239268Sgonzo } else { 696239268Sgonzo if ((ctype & CPU_CT_S) == 0) 697239268Sgonzo arm_pcache_unified = 1; 698129198Scognet 699239268Sgonzo /* 700239268Sgonzo * If you want to know how this code works, go read the ARM ARM. 701239268Sgonzo */ 702129198Scognet 703239268Sgonzo arm_pcache_type = CPU_CT_CTYPE(ctype); 704129198Scognet 705239268Sgonzo if (arm_pcache_unified == 0) { 706239268Sgonzo isize = CPU_CT_ISIZE(ctype); 707239268Sgonzo multiplier = (isize & CPU_CT_xSIZE_M) ? 3 : 2; 708239268Sgonzo arm_picache_line_size = 1U << (CPU_CT_xSIZE_LEN(isize) + 3); 709239268Sgonzo if (CPU_CT_xSIZE_ASSOC(isize) == 0) { 710239268Sgonzo if (isize & CPU_CT_xSIZE_M) 711239268Sgonzo arm_picache_line_size = 0; /* not present */ 712239268Sgonzo else 713239268Sgonzo arm_picache_ways = 1; 714239268Sgonzo } else { 715239268Sgonzo arm_picache_ways = multiplier << 716239268Sgonzo (CPU_CT_xSIZE_ASSOC(isize) - 1); 717239268Sgonzo } 718239268Sgonzo arm_picache_size = multiplier << (CPU_CT_xSIZE_SIZE(isize) + 8); 719239268Sgonzo } 720239268Sgonzo 721239268Sgonzo dsize = CPU_CT_DSIZE(ctype); 722239268Sgonzo multiplier = (dsize & CPU_CT_xSIZE_M) ? 3 : 2; 723239268Sgonzo arm_pdcache_line_size = 1U << (CPU_CT_xSIZE_LEN(dsize) + 3); 724239268Sgonzo if (CPU_CT_xSIZE_ASSOC(dsize) == 0) { 725239268Sgonzo if (dsize & CPU_CT_xSIZE_M) 726239268Sgonzo arm_pdcache_line_size = 0; /* not present */ 727129198Scognet else 728239268Sgonzo arm_pdcache_ways = 1; 729129198Scognet } else { 730239268Sgonzo arm_pdcache_ways = multiplier << 731239268Sgonzo (CPU_CT_xSIZE_ASSOC(dsize) - 1); 732129198Scognet } 733239268Sgonzo arm_pdcache_size = multiplier << (CPU_CT_xSIZE_SIZE(dsize) + 8); 734129198Scognet 735239268Sgonzo arm_dcache_align = arm_pdcache_line_size; 736129198Scognet 737239268Sgonzo arm_dcache_l2_assoc = CPU_CT_xSIZE_ASSOC(dsize) + multiplier - 2; 738239268Sgonzo arm_dcache_l2_linesize = CPU_CT_xSIZE_LEN(dsize) + 3; 739239268Sgonzo arm_dcache_l2_nsets = 6 + CPU_CT_xSIZE_SIZE(dsize) - 740239268Sgonzo CPU_CT_xSIZE_ASSOC(dsize) - CPU_CT_xSIZE_LEN(dsize); 741129198Scognet 742239268Sgonzo out: 743239268Sgonzo arm_dcache_align_mask = arm_dcache_align - 1; 744239268Sgonzo } 745129198Scognet} 746262958Sian#endif /* ARM9 || XSCALE */ 747129198Scognet 748129198Scognet/* 749129198Scognet * Cannot panic here as we may not have a console yet ... 750129198Scognet */ 751129198Scognet 752129198Scognetint 753129198Scognetset_cpufuncs() 754129198Scognet{ 755295096Smmel cputype = cpu_ident(); 756129198Scognet cputype &= CPU_ID_CPU_MASK; 757129198Scognet 758129198Scognet#ifdef CPU_ARM9 759129198Scognet if (((cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_ARM_LTD || 760129198Scognet (cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_TI) && 761129198Scognet (cputype & 0x0000f000) == 0x00009000) { 762129198Scognet cpufuncs = arm9_cpufuncs; 763129198Scognet cpu_reset_needs_v4_MMU_disable = 1; /* V4 or higher */ 764129198Scognet get_cachetype_cp15(); 765146605Scognet arm9_dcache_sets_inc = 1U << arm_dcache_l2_linesize; 766146605Scognet arm9_dcache_sets_max = (1U << (arm_dcache_l2_linesize + 767146605Scognet arm_dcache_l2_nsets)) - arm9_dcache_sets_inc; 768146605Scognet arm9_dcache_index_inc = 1U << (32 - arm_dcache_l2_assoc); 769146605Scognet arm9_dcache_index_max = 0U - arm9_dcache_index_inc; 770137270Scognet pmap_pte_init_generic(); 771166655Scognet goto out; 772129198Scognet } 773129198Scognet#endif /* CPU_ARM9 */ 774280809Sandrew#if defined(CPU_ARM9E) 775239268Sgonzo if (cputype == CPU_ID_MV88FR131 || cputype == CPU_ID_MV88FR571_VD || 776183835Sraj cputype == CPU_ID_MV88FR571_41) { 777239268Sgonzo uint32_t sheeva_ctrl; 778183835Sraj 779239268Sgonzo sheeva_ctrl = (MV_DC_STREAM_ENABLE | MV_BTB_DISABLE | 780239268Sgonzo MV_L2_ENABLE); 781239268Sgonzo /* 782239268Sgonzo * Workaround for Marvell MV78100 CPU: Cache prefetch 783239268Sgonzo * mechanism may affect the cache coherency validity, 784239268Sgonzo * so it needs to be disabled. 785239268Sgonzo * 786239268Sgonzo * Refer to errata document MV-S501058-00C.pdf (p. 3.1 787239268Sgonzo * L2 Prefetching Mechanism) for details. 788239268Sgonzo */ 789239268Sgonzo if (cputype == CPU_ID_MV88FR571_VD || 790239268Sgonzo cputype == CPU_ID_MV88FR571_41) 791239268Sgonzo sheeva_ctrl |= MV_L2_PREFETCH_DISABLE; 792212825Smav 793239268Sgonzo sheeva_control_ext(0xffffffff & ~MV_WA_ENABLE, sheeva_ctrl); 794183835Sraj 795239268Sgonzo cpufuncs = sheeva_cpufuncs; 796172738Simp get_cachetype_cp15(); 797172738Simp pmap_pte_init_generic(); 798174058Scognet goto out; 799280809Sandrew } else if (cputype == CPU_ID_ARM926EJS) { 800239268Sgonzo cpufuncs = armv5_ec_cpufuncs; 801239268Sgonzo get_cachetype_cp15(); 802239268Sgonzo pmap_pte_init_generic(); 803239268Sgonzo goto out; 804172738Simp } 805280809Sandrew#endif /* CPU_ARM9E */ 806280824Sandrew#if defined(CPU_ARM1176) 807280824Sandrew if (cputype == CPU_ID_ARM1176JZS) { 808280868Sandrew cpufuncs = arm1176_cpufuncs; 809244480Sgonzo cpu_reset_needs_v4_MMU_disable = 1; /* V4 or higher */ 810244480Sgonzo get_cachetype_cp15(); 811244480Sgonzo goto out; 812244480Sgonzo } 813280824Sandrew#endif /* CPU_ARM1176 */ 814259640Sganbold#if defined(CPU_CORTEXA) || defined(CPU_KRAIT) 815256629Sbr if (cputype == CPU_ID_CORTEXA5 || 816256629Sbr cputype == CPU_ID_CORTEXA7 || 817253857Sganbold cputype == CPU_ID_CORTEXA8R1 || 818239268Sgonzo cputype == CPU_ID_CORTEXA8R2 || 819239268Sgonzo cputype == CPU_ID_CORTEXA8R3 || 820239268Sgonzo cputype == CPU_ID_CORTEXA9R1 || 821249999Swkoszek cputype == CPU_ID_CORTEXA9R2 || 822252361Sray cputype == CPU_ID_CORTEXA9R3 || 823286725Smarcel cputype == CPU_ID_CORTEXA9R4 || 824277156Sganbold cputype == CPU_ID_CORTEXA12R0 || 825263982Sbr cputype == CPU_ID_CORTEXA15R0 || 826263982Sbr cputype == CPU_ID_CORTEXA15R1 || 827263982Sbr cputype == CPU_ID_CORTEXA15R2 || 828263982Sbr cputype == CPU_ID_CORTEXA15R3 || 829291425Smmel cputype == CPU_ID_KRAIT300R0 || 830291425Smmel cputype == CPU_ID_KRAIT300R1 ) { 831239268Sgonzo cpufuncs = cortexa_cpufuncs; 832239268Sgonzo cpu_reset_needs_v4_MMU_disable = 1; /* V4 or higher */ 833239268Sgonzo get_cachetype_cp15(); 834239268Sgonzo goto out; 835239268Sgonzo } 836239268Sgonzo#endif /* CPU_CORTEXA */ 837283366Sandrew 838239268Sgonzo#if defined(CPU_MV_PJ4B) 839257281Szbb if (cputype == CPU_ID_MV88SV581X_V7 || 840240486Sgber cputype == CPU_ID_MV88SV584X_V7 || 841239268Sgonzo cputype == CPU_ID_ARM_88SV581X_V7) { 842257281Szbb cpufuncs = pj4bv7_cpufuncs; 843239268Sgonzo get_cachetype_cp15(); 844239268Sgonzo goto out; 845239268Sgonzo } 846239268Sgonzo#endif /* CPU_MV_PJ4B */ 847129198Scognet 848280842Sandrew#if defined(CPU_FA526) 849207611Skevlo if (cputype == CPU_ID_FA526 || cputype == CPU_ID_FA626TE) { 850201468Srpaulo cpufuncs = fa526_cpufuncs; 851201468Srpaulo cpu_reset_needs_v4_MMU_disable = 1; /* SA needs it */ 852201468Srpaulo get_cachetype_cp15(); 853201468Srpaulo pmap_pte_init_generic(); 854201468Srpaulo 855201468Srpaulo goto out; 856201468Srpaulo } 857280842Sandrew#endif /* CPU_FA526 */ 858262958Sian 859161592Scognet#if defined(CPU_XSCALE_80321) || defined(CPU_XSCALE_80219) 860129198Scognet if (cputype == CPU_ID_80321_400 || cputype == CPU_ID_80321_600 || 861161592Scognet cputype == CPU_ID_80321_400_B0 || cputype == CPU_ID_80321_600_B0 || 862161592Scognet cputype == CPU_ID_80219_400 || cputype == CPU_ID_80219_600) { 863129198Scognet cpufuncs = xscale_cpufuncs; 864129198Scognet cpu_reset_needs_v4_MMU_disable = 1; /* XScale needs it */ 865129198Scognet get_cachetype_cp15(); 866129198Scognet pmap_pte_init_xscale(); 867166655Scognet goto out; 868129198Scognet } 869129198Scognet#endif /* CPU_XSCALE_80321 */ 870161592Scognet 871164080Scognet#if defined(CPU_XSCALE_81342) 872164080Scognet if (cputype == CPU_ID_81342) { 873164080Scognet cpufuncs = xscalec3_cpufuncs; 874164080Scognet cpu_reset_needs_v4_MMU_disable = 1; /* XScale needs it */ 875164080Scognet get_cachetype_cp15(); 876164080Scognet pmap_pte_init_xscale(); 877166655Scognet goto out; 878164080Scognet } 879164080Scognet#endif /* CPU_XSCALE_81342 */ 880129198Scognet#ifdef CPU_XSCALE_PXA2X0 881129198Scognet /* ignore core revision to test PXA2xx CPUs */ 882129198Scognet if ((cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA250 || 883191817Sstas (cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA27X || 884129198Scognet (cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA210) { 885129198Scognet 886129198Scognet cpufuncs = xscale_cpufuncs; 887129198Scognet cpu_reset_needs_v4_MMU_disable = 1; /* XScale needs it */ 888129198Scognet get_cachetype_cp15(); 889129198Scognet pmap_pte_init_xscale(); 890129198Scognet 891166655Scognet goto out; 892129198Scognet } 893129198Scognet#endif /* CPU_XSCALE_PXA2X0 */ 894129198Scognet#ifdef CPU_XSCALE_IXP425 895129198Scognet if (cputype == CPU_ID_IXP425_533 || cputype == CPU_ID_IXP425_400 || 896186352Ssam cputype == CPU_ID_IXP425_266 || cputype == CPU_ID_IXP435) { 897129198Scognet 898129198Scognet cpufuncs = xscale_cpufuncs; 899129198Scognet cpu_reset_needs_v4_MMU_disable = 1; /* XScale needs it */ 900129198Scognet get_cachetype_cp15(); 901129198Scognet pmap_pte_init_xscale(); 902129198Scognet 903166655Scognet goto out; 904129198Scognet } 905129198Scognet#endif /* CPU_XSCALE_IXP425 */ 906129198Scognet /* 907129198Scognet * Bzzzz. And the answer was ... 908129198Scognet */ 909129198Scognet panic("No support for this CPU type (%08x) in kernel", cputype); 910129198Scognet return(ARCHITECTURE_NOT_PRESENT); 911166655Scognetout: 912166655Scognet uma_set_align(arm_dcache_align_mask); 913166655Scognet return (0); 914129198Scognet} 915129198Scognet 916129198Scognet/* 917129198Scognet * CPU Setup code 918129198Scognet */ 919129198Scognet 920129198Scognet#ifdef CPU_ARM9 921129198Scognetvoid 922280823Sandrewarm9_setup(void) 923129198Scognet{ 924129198Scognet int cpuctrl, cpuctrlmask; 925129198Scognet 926129198Scognet cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 927129198Scognet | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 928129198Scognet | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 929157618Scognet | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE | 930157618Scognet CPU_CONTROL_ROUNDROBIN; 931129198Scognet cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 932129198Scognet | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 933129198Scognet | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 934129198Scognet | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE 935129198Scognet | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE 936146605Scognet | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_VECRELOC 937146605Scognet | CPU_CONTROL_ROUNDROBIN; 938129198Scognet 939129198Scognet#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 940129198Scognet cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 941129198Scognet#endif 942129198Scognet 943129198Scognet#ifdef __ARMEB__ 944129198Scognet cpuctrl |= CPU_CONTROL_BEND_ENABLE; 945129198Scognet#endif 946142050Scognet if (vector_page == ARM_VECTORS_HIGH) 947142050Scognet cpuctrl |= CPU_CONTROL_VECRELOC; 948129198Scognet 949129198Scognet /* Clear out the cache */ 950129198Scognet cpu_idcache_wbinv_all(); 951129198Scognet 952129198Scognet /* Set the control register */ 953146605Scognet cpu_control(cpuctrlmask, cpuctrl); 954129198Scognet ctrl = cpuctrl; 955129198Scognet 956129198Scognet} 957129198Scognet#endif /* CPU_ARM9 */ 958129198Scognet 959280809Sandrew#if defined(CPU_ARM9E) 960129198Scognetvoid 961280823Sandrewarm10_setup(void) 962129198Scognet{ 963129198Scognet int cpuctrl, cpuctrlmask; 964129198Scognet 965129198Scognet cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_SYST_ENABLE 966236991Simp | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 967129198Scognet | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_BPRD_ENABLE; 968129198Scognet cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_SYST_ENABLE 969129198Scognet | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 970129198Scognet | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE 971129198Scognet | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE 972129198Scognet | CPU_CONTROL_BPRD_ENABLE 973129198Scognet | CPU_CONTROL_ROUNDROBIN | CPU_CONTROL_CPCLK; 974129198Scognet 975129198Scognet#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 976129198Scognet cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 977129198Scognet#endif 978129198Scognet 979129198Scognet#ifdef __ARMEB__ 980129198Scognet cpuctrl |= CPU_CONTROL_BEND_ENABLE; 981129198Scognet#endif 982129198Scognet 983129198Scognet /* Clear out the cache */ 984129198Scognet cpu_idcache_wbinv_all(); 985129198Scognet 986129198Scognet /* Now really make sure they are clean. */ 987172738Simp __asm __volatile ("mcr\tp15, 0, r0, c7, c7, 0" : : ); 988129198Scognet 989174058Scognet if (vector_page == ARM_VECTORS_HIGH) 990174058Scognet cpuctrl |= CPU_CONTROL_VECRELOC; 991174058Scognet 992129198Scognet /* Set the control register */ 993129198Scognet ctrl = cpuctrl; 994129198Scognet cpu_control(0xffffffff, cpuctrl); 995129198Scognet 996129198Scognet /* And again. */ 997129198Scognet cpu_idcache_wbinv_all(); 998129198Scognet} 999172738Simp#endif /* CPU_ARM9E || CPU_ARM10 */ 1000129198Scognet 1001280824Sandrew#if defined(CPU_ARM1176) \ 1002266083Smarkm || defined(CPU_MV_PJ4B) \ 1003266083Smarkm || defined(CPU_CORTEXA) || defined(CPU_KRAIT) 1004266083Smarkmstatic __inline void 1005266083Smarkmcpu_scc_setup_ccnt(void) 1006266083Smarkm{ 1007266083Smarkm/* This is how you give userland access to the CCNT and PMCn 1008266083Smarkm * registers. 1009266083Smarkm * BEWARE! This gives write access also, which may not be what 1010266083Smarkm * you want! 1011266083Smarkm */ 1012266083Smarkm#ifdef _PMC_USER_READ_WRITE_ 1013266083Smarkm /* Set PMUSERENR[0] to allow userland access */ 1014283365Sandrew cp15_pmuserenr_set(1); 1015266083Smarkm#endif 1016280824Sandrew#if defined(CPU_ARM1176) 1017267597Stuexen /* Set PMCR[2,0] to enable counters and reset CCNT */ 1018283365Sandrew cp15_pmcr_set(5); 1019267597Stuexen#else 1020267597Stuexen /* Set up the PMCCNTR register as a cyclecounter: 1021266083Smarkm * Set PMINTENCLR to 0xFFFFFFFF to block interrupts 1022266083Smarkm * Set PMCR[2,0] to enable counters and reset CCNT 1023266083Smarkm * Set PMCNTENSET to 0x80000000 to enable CCNT */ 1024283365Sandrew cp15_pminten_clr(0xFFFFFFFF); 1025283365Sandrew cp15_pmcr_set(5); 1026283365Sandrew cp15_pmcnten_set(0x80000000); 1027267597Stuexen#endif 1028266083Smarkm} 1029266083Smarkm#endif 1030266083Smarkm 1031280824Sandrew#if defined(CPU_ARM1176) 1032172738Simpvoid 1033280823Sandrewarm11x6_setup(void) 1034172738Simp{ 1035244480Sgonzo int cpuctrl, cpuctrl_wax; 1036244480Sgonzo uint32_t auxctrl, auxctrl_wax; 1037244480Sgonzo uint32_t tmp, tmp2; 1038244480Sgonzo uint32_t sbz=0; 1039244480Sgonzo uint32_t cpuid; 1040172738Simp 1041295096Smmel cpuid = cpu_ident(); 1042244480Sgonzo 1043244480Sgonzo cpuctrl = 1044244480Sgonzo CPU_CONTROL_MMU_ENABLE | 1045244480Sgonzo CPU_CONTROL_DC_ENABLE | 1046244480Sgonzo CPU_CONTROL_WBUF_ENABLE | 1047244480Sgonzo CPU_CONTROL_32BP_ENABLE | 1048244480Sgonzo CPU_CONTROL_32BD_ENABLE | 1049244480Sgonzo CPU_CONTROL_LABT_ENABLE | 1050244480Sgonzo CPU_CONTROL_SYST_ENABLE | 1051282019Sandrew CPU_CONTROL_IC_ENABLE | 1052282019Sandrew CPU_CONTROL_UNAL_ENABLE; 1053244480Sgonzo 1054244480Sgonzo /* 1055244480Sgonzo * "write as existing" bits 1056244480Sgonzo * inverse of this is mask 1057244480Sgonzo */ 1058244480Sgonzo cpuctrl_wax = 1059244480Sgonzo (3 << 30) | /* SBZ */ 1060244480Sgonzo (1 << 29) | /* FA */ 1061244480Sgonzo (1 << 28) | /* TR */ 1062283366Sandrew (3 << 26) | /* SBZ */ 1063244480Sgonzo (3 << 19) | /* SBZ */ 1064244480Sgonzo (1 << 17); /* SBZ */ 1065244480Sgonzo 1066244480Sgonzo cpuctrl |= CPU_CONTROL_BPRD_ENABLE; 1067244480Sgonzo cpuctrl |= CPU_CONTROL_V6_EXTPAGE; 1068244480Sgonzo 1069172738Simp#ifdef __ARMEB__ 1070172738Simp cpuctrl |= CPU_CONTROL_BEND_ENABLE; 1071172738Simp#endif 1072244480Sgonzo 1073239701Sgonzo if (vector_page == ARM_VECTORS_HIGH) 1074239701Sgonzo cpuctrl |= CPU_CONTROL_VECRELOC; 1075172738Simp 1076244480Sgonzo auxctrl = 0; 1077244480Sgonzo auxctrl_wax = ~0; 1078244480Sgonzo 1079244480Sgonzo /* 1080244480Sgonzo * Enable an errata workaround 1081244480Sgonzo */ 1082244480Sgonzo if ((cpuid & CPU_ID_CPU_MASK) == CPU_ID_ARM1176JZS) { /* ARM1176JZSr0 */ 1083244480Sgonzo auxctrl = ARM1176_AUXCTL_PHD; 1084244480Sgonzo auxctrl_wax = ~ARM1176_AUXCTL_PHD; 1085244480Sgonzo } 1086244480Sgonzo 1087244480Sgonzo /* Clear out the cache */ 1088172738Simp cpu_idcache_wbinv_all(); 1089172738Simp 1090244480Sgonzo /* Now really make sure they are clean. */ 1091244480Sgonzo __asm volatile ("mcr\tp15, 0, %0, c7, c7, 0" : : "r"(sbz)); 1092244480Sgonzo 1093244480Sgonzo /* Allow detection code to find the VFP if it's fitted. */ 1094283365Sandrew cp15_cpacr_set(0x0fffffff); 1095244480Sgonzo 1096172738Simp /* Set the control register */ 1097239701Sgonzo ctrl = cpuctrl; 1098244480Sgonzo cpu_control(~cpuctrl_wax, cpuctrl); 1099172738Simp 1100283365Sandrew tmp = cp15_actlr_get(); 1101283365Sandrew tmp2 = tmp; 1102283365Sandrew tmp &= auxctrl_wax; 1103283365Sandrew tmp |= auxctrl; 1104283365Sandrew if (tmp != tmp2) 1105283365Sandrew cp15_actlr_set(tmp); 1106244480Sgonzo 1107244480Sgonzo /* And again. */ 1108172738Simp cpu_idcache_wbinv_all(); 1109266083Smarkm 1110266083Smarkm cpu_scc_setup_ccnt(); 1111172738Simp} 1112280824Sandrew#endif /* CPU_ARM1176 */ 1113172738Simp 1114239268Sgonzo#ifdef CPU_MV_PJ4B 1115239268Sgonzovoid 1116280823Sandrewpj4bv7_setup(void) 1117239268Sgonzo{ 1118239268Sgonzo int cpuctrl; 1119239268Sgonzo 1120239268Sgonzo pj4b_config(); 1121239268Sgonzo 1122239268Sgonzo cpuctrl = CPU_CONTROL_MMU_ENABLE; 1123239268Sgonzo#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 1124239268Sgonzo cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 1125239268Sgonzo#endif 1126239268Sgonzo cpuctrl |= CPU_CONTROL_DC_ENABLE; 1127239268Sgonzo cpuctrl |= (0xf << 3); 1128239268Sgonzo cpuctrl |= CPU_CONTROL_BPRD_ENABLE; 1129239268Sgonzo cpuctrl |= CPU_CONTROL_IC_ENABLE; 1130239268Sgonzo if (vector_page == ARM_VECTORS_HIGH) 1131239268Sgonzo cpuctrl |= CPU_CONTROL_VECRELOC; 1132239268Sgonzo cpuctrl |= (0x5 << 16) | (1 < 22); 1133239268Sgonzo cpuctrl |= CPU_CONTROL_V6_EXTPAGE; 1134239268Sgonzo 1135239268Sgonzo /* Clear out the cache */ 1136239268Sgonzo cpu_idcache_wbinv_all(); 1137239268Sgonzo 1138239268Sgonzo /* Set the control register */ 1139239268Sgonzo ctrl = cpuctrl; 1140239268Sgonzo cpu_control(0xFFFFFFFF, cpuctrl); 1141239268Sgonzo 1142239268Sgonzo /* And again. */ 1143239268Sgonzo cpu_idcache_wbinv_all(); 1144266083Smarkm 1145266083Smarkm cpu_scc_setup_ccnt(); 1146239268Sgonzo} 1147239268Sgonzo#endif /* CPU_MV_PJ4B */ 1148239268Sgonzo 1149259640Sganbold#if defined(CPU_CORTEXA) || defined(CPU_KRAIT) 1150239268Sgonzo 1151239268Sgonzovoid 1152280823Sandrewcortexa_setup(void) 1153239268Sgonzo{ 1154239268Sgonzo int cpuctrl, cpuctrlmask; 1155283366Sandrew 1156239268Sgonzo cpuctrlmask = CPU_CONTROL_MMU_ENABLE | /* MMU enable [0] */ 1157239268Sgonzo CPU_CONTROL_AFLT_ENABLE | /* Alignment fault [1] */ 1158239268Sgonzo CPU_CONTROL_DC_ENABLE | /* DCache enable [2] */ 1159239268Sgonzo CPU_CONTROL_BPRD_ENABLE | /* Branch prediction [11] */ 1160239268Sgonzo CPU_CONTROL_IC_ENABLE | /* ICache enable [12] */ 1161239268Sgonzo CPU_CONTROL_VECRELOC; /* Vector relocation [13] */ 1162283366Sandrew 1163239268Sgonzo cpuctrl = CPU_CONTROL_MMU_ENABLE | 1164239268Sgonzo CPU_CONTROL_IC_ENABLE | 1165239268Sgonzo CPU_CONTROL_DC_ENABLE | 1166239268Sgonzo CPU_CONTROL_BPRD_ENABLE; 1167283366Sandrew 1168239268Sgonzo#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 1169239268Sgonzo cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 1170239268Sgonzo#endif 1171283366Sandrew 1172239268Sgonzo /* Switch to big endian */ 1173239268Sgonzo#ifdef __ARMEB__ 1174239268Sgonzo cpuctrl |= CPU_CONTROL_BEND_ENABLE; 1175239268Sgonzo#endif 1176283366Sandrew 1177239268Sgonzo /* Check if the vector page is at the high address (0xffff0000) */ 1178239268Sgonzo if (vector_page == ARM_VECTORS_HIGH) 1179239268Sgonzo cpuctrl |= CPU_CONTROL_VECRELOC; 1180283366Sandrew 1181239268Sgonzo /* Clear out the cache */ 1182239268Sgonzo cpu_idcache_wbinv_all(); 1183283366Sandrew 1184239268Sgonzo /* Set the control register */ 1185239268Sgonzo ctrl = cpuctrl; 1186239268Sgonzo cpu_control(cpuctrlmask, cpuctrl); 1187283366Sandrew 1188239268Sgonzo /* And again. */ 1189239268Sgonzo cpu_idcache_wbinv_all(); 1190289602Sian#if defined(SMP) && !defined(ARM_NEW_PMAP) 1191239268Sgonzo armv7_auxctrl((1 << 6) | (1 << 0), (1 << 6) | (1 << 0)); /* Enable SMP + TLB broadcasting */ 1192239268Sgonzo#endif 1193266083Smarkm 1194266083Smarkm cpu_scc_setup_ccnt(); 1195239268Sgonzo} 1196239268Sgonzo#endif /* CPU_CORTEXA */ 1197239268Sgonzo 1198280842Sandrew#if defined(CPU_FA526) 1199201468Srpaulovoid 1200280823Sandrewfa526_setup(void) 1201201468Srpaulo{ 1202201468Srpaulo int cpuctrl, cpuctrlmask; 1203201468Srpaulo 1204201468Srpaulo cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 1205201468Srpaulo | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 1206201468Srpaulo | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 1207204122Skevlo | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE 1208204122Skevlo | CPU_CONTROL_BPRD_ENABLE; 1209201468Srpaulo cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 1210201468Srpaulo | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 1211201468Srpaulo | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 1212201468Srpaulo | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE 1213201468Srpaulo | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE 1214201468Srpaulo | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_BPRD_ENABLE 1215201468Srpaulo | CPU_CONTROL_CPCLK | CPU_CONTROL_VECRELOC; 1216201468Srpaulo 1217201468Srpaulo#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 1218201468Srpaulo cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 1219201468Srpaulo#endif 1220201468Srpaulo 1221201468Srpaulo#ifdef __ARMEB__ 1222201468Srpaulo cpuctrl |= CPU_CONTROL_BEND_ENABLE; 1223201468Srpaulo#endif 1224201468Srpaulo 1225201468Srpaulo if (vector_page == ARM_VECTORS_HIGH) 1226201468Srpaulo cpuctrl |= CPU_CONTROL_VECRELOC; 1227201468Srpaulo 1228201468Srpaulo /* Clear out the cache */ 1229201468Srpaulo cpu_idcache_wbinv_all(); 1230201468Srpaulo 1231201468Srpaulo /* Set the control register */ 1232201468Srpaulo ctrl = cpuctrl; 1233201468Srpaulo cpu_control(0xffffffff, cpuctrl); 1234201468Srpaulo} 1235280842Sandrew#endif /* CPU_FA526 */ 1236201468Srpaulo 1237280847Sandrew#if defined(CPU_XSCALE_80321) || \ 1238161592Scognet defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \ 1239164080Scognet defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342) 1240129198Scognetvoid 1241280823Sandrewxscale_setup(void) 1242129198Scognet{ 1243129198Scognet uint32_t auxctl; 1244129198Scognet int cpuctrl, cpuctrlmask; 1245129198Scognet 1246129198Scognet /* 1247129198Scognet * The XScale Write Buffer is always enabled. Our option 1248129198Scognet * is to enable/disable coalescing. Note that bits 6:3 1249129198Scognet * must always be enabled. 1250129198Scognet */ 1251129198Scognet 1252129198Scognet cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 1253129198Scognet | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 1254129198Scognet | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 1255129198Scognet | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE 1256129198Scognet | CPU_CONTROL_BPRD_ENABLE; 1257129198Scognet cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 1258129198Scognet | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 1259129198Scognet | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 1260129198Scognet | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE 1261129198Scognet | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE 1262129198Scognet | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_BPRD_ENABLE 1263171618Scognet | CPU_CONTROL_CPCLK | CPU_CONTROL_VECRELOC | \ 1264171618Scognet CPU_CONTROL_L2_ENABLE; 1265129198Scognet 1266129198Scognet#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 1267129198Scognet cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 1268129198Scognet#endif 1269129198Scognet 1270129198Scognet#ifdef __ARMEB__ 1271129198Scognet cpuctrl |= CPU_CONTROL_BEND_ENABLE; 1272129198Scognet#endif 1273129198Scognet 1274129198Scognet if (vector_page == ARM_VECTORS_HIGH) 1275129198Scognet cpuctrl |= CPU_CONTROL_VECRELOC; 1276171618Scognet#ifdef CPU_XSCALE_CORE3 1277171618Scognet cpuctrl |= CPU_CONTROL_L2_ENABLE; 1278171618Scognet#endif 1279129198Scognet 1280129198Scognet /* Clear out the cache */ 1281129198Scognet cpu_idcache_wbinv_all(); 1282129198Scognet 1283129198Scognet /* 1284129198Scognet * Set the control register. Note that bits 6:3 must always 1285129198Scognet * be set to 1. 1286129198Scognet */ 1287129198Scognet ctrl = cpuctrl; 1288129198Scognet/* cpu_control(cpuctrlmask, cpuctrl);*/ 1289129198Scognet cpu_control(0xffffffff, cpuctrl); 1290129198Scognet 1291129198Scognet /* Make sure write coalescing is turned on */ 1292129198Scognet __asm __volatile("mrc p15, 0, %0, c1, c0, 1" 1293129198Scognet : "=r" (auxctl)); 1294129198Scognet#ifdef XSCALE_NO_COALESCE_WRITES 1295129198Scognet auxctl |= XSCALE_AUXCTL_K; 1296129198Scognet#else 1297129198Scognet auxctl &= ~XSCALE_AUXCTL_K; 1298129198Scognet#endif 1299171618Scognet#ifdef CPU_XSCALE_CORE3 1300171618Scognet auxctl |= XSCALE_AUXCTL_LLR; 1301171618Scognet auxctl |= XSCALE_AUXCTL_MD_MASK; 1302171618Scognet#endif 1303129198Scognet __asm __volatile("mcr p15, 0, %0, c1, c0, 1" 1304129198Scognet : : "r" (auxctl)); 1305129198Scognet} 1306280847Sandrew#endif /* CPU_XSCALE_80321 || CPU_XSCALE_PXA2X0 || CPU_XSCALE_IXP425 1307161592Scognet CPU_XSCALE_80219 */ 1308