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$"); 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#include <machine/bootconfig.h> 63129198Scognet 64129198Scognet#ifdef CPU_XSCALE_80200 65135646Scognet#include <arm/xscale/i80200/i80200reg.h> 66135646Scognet#include <arm/xscale/i80200/i80200var.h> 67129198Scognet#endif 68129198Scognet 69161592Scognet#if defined(CPU_XSCALE_80321) || defined(CPU_XSCALE_80219) 70135646Scognet#include <arm/xscale/i80321/i80321reg.h> 71135646Scognet#include <arm/xscale/i80321/i80321var.h> 72129198Scognet#endif 73129198Scognet 74243579Smarcel/* 75243579Smarcel * Some definitions in i81342reg.h clash with i80321reg.h. 76243579Smarcel * This only happens for the LINT kernel. As it happens, 77243579Smarcel * we don't need anything from i81342reg.h that we already 78243579Smarcel * got from somewhere else during a LINT compile. 79243579Smarcel */ 80243579Smarcel#if defined(CPU_XSCALE_81342) && !defined(COMPILING_LINT) 81164080Scognet#include <arm/xscale/i8134x/i81342reg.h> 82164080Scognet#endif 83164080Scognet 84129198Scognet#ifdef CPU_XSCALE_IXP425 85135646Scognet#include <arm/xscale/ixp425/ixp425reg.h> 86135646Scognet#include <arm/xscale/ixp425/ixp425var.h> 87129198Scognet#endif 88129198Scognet 89129198Scognet/* PRIMARY CACHE VARIABLES */ 90129198Scognetint arm_picache_size; 91129198Scognetint arm_picache_line_size; 92129198Scognetint arm_picache_ways; 93129198Scognet 94129198Scognetint arm_pdcache_size; /* and unified */ 95129198Scognetint arm_pdcache_line_size; 96129198Scognetint arm_pdcache_ways; 97129198Scognet 98129198Scognetint arm_pcache_type; 99129198Scognetint arm_pcache_unified; 100129198Scognet 101129198Scognetint arm_dcache_align; 102129198Scognetint arm_dcache_align_mask; 103129198Scognet 104239268Sgonzou_int arm_cache_level; 105239268Sgonzou_int arm_cache_type[14]; 106239268Sgonzou_int arm_cache_loc; 107239268Sgonzo 108129198Scognet/* 1 == use cpu_sleep(), 0 == don't */ 109129198Scognetint cpu_do_powersave; 110129198Scognetint ctrl; 111129198Scognet 112129198Scognet#ifdef CPU_ARM9 113129198Scognetstruct cpu_functions arm9_cpufuncs = { 114129198Scognet /* CPU functions */ 115129198Scognet 116129198Scognet cpufunc_id, /* id */ 117129198Scognet cpufunc_nullop, /* cpwait */ 118129198Scognet 119129198Scognet /* MMU functions */ 120129198Scognet 121129198Scognet cpufunc_control, /* control */ 122129198Scognet cpufunc_domains, /* Domain */ 123129198Scognet arm9_setttb, /* Setttb */ 124129198Scognet cpufunc_faultstatus, /* Faultstatus */ 125129198Scognet cpufunc_faultaddress, /* Faultaddress */ 126129198Scognet 127129198Scognet /* TLB functions */ 128129198Scognet 129129198Scognet armv4_tlb_flushID, /* tlb_flushID */ 130129198Scognet arm9_tlb_flushID_SE, /* tlb_flushID_SE */ 131129198Scognet armv4_tlb_flushI, /* tlb_flushI */ 132129198Scognet (void *)armv4_tlb_flushI, /* tlb_flushI_SE */ 133129198Scognet armv4_tlb_flushD, /* tlb_flushD */ 134129198Scognet armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 135129198Scognet 136129198Scognet /* Cache operations */ 137129198Scognet 138146605Scognet arm9_icache_sync_all, /* icache_sync_all */ 139146605Scognet arm9_icache_sync_range, /* icache_sync_range */ 140129198Scognet 141146605Scognet arm9_dcache_wbinv_all, /* dcache_wbinv_all */ 142146605Scognet arm9_dcache_wbinv_range, /* dcache_wbinv_range */ 143195798Sraj arm9_dcache_inv_range, /* dcache_inv_range */ 144146605Scognet arm9_dcache_wb_range, /* dcache_wb_range */ 145129198Scognet 146266203Sian armv4_idcache_inv_all, /* idcache_inv_all */ 147146605Scognet arm9_idcache_wbinv_all, /* idcache_wbinv_all */ 148146605Scognet arm9_idcache_wbinv_range, /* idcache_wbinv_range */ 149171618Scognet cpufunc_nullop, /* l2cache_wbinv_all */ 150171781Scognet (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 151171781Scognet (void *)cpufunc_nullop, /* l2cache_inv_range */ 152171781Scognet (void *)cpufunc_nullop, /* l2cache_wb_range */ 153266387Sian (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ 154129198Scognet 155129198Scognet /* Other functions */ 156129198Scognet 157129198Scognet cpufunc_nullop, /* flush_prefetchbuf */ 158129198Scognet armv4_drain_writebuf, /* drain_writebuf */ 159129198Scognet cpufunc_nullop, /* flush_brnchtgt_C */ 160129198Scognet (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 161129198Scognet 162129198Scognet (void *)cpufunc_nullop, /* sleep */ 163129198Scognet 164129198Scognet /* Soft functions */ 165129198Scognet 166129198Scognet cpufunc_null_fixup, /* dataabt_fixup */ 167129198Scognet cpufunc_null_fixup, /* prefetchabt_fixup */ 168129198Scognet 169129198Scognet arm9_context_switch, /* context_switch */ 170129198Scognet 171129198Scognet arm9_setup /* cpu setup */ 172129198Scognet 173129198Scognet}; 174129198Scognet#endif /* CPU_ARM9 */ 175129198Scognet 176172738Simp#if defined(CPU_ARM9E) || defined(CPU_ARM10) 177172738Simpstruct cpu_functions armv5_ec_cpufuncs = { 178172738Simp /* CPU functions */ 179172738Simp 180172738Simp cpufunc_id, /* id */ 181172738Simp cpufunc_nullop, /* cpwait */ 182172738Simp 183172738Simp /* MMU functions */ 184172738Simp 185172738Simp cpufunc_control, /* control */ 186172738Simp cpufunc_domains, /* Domain */ 187172738Simp armv5_ec_setttb, /* Setttb */ 188172738Simp cpufunc_faultstatus, /* Faultstatus */ 189172738Simp cpufunc_faultaddress, /* Faultaddress */ 190172738Simp 191172738Simp /* TLB functions */ 192172738Simp 193172738Simp armv4_tlb_flushID, /* tlb_flushID */ 194172738Simp arm10_tlb_flushID_SE, /* tlb_flushID_SE */ 195172738Simp armv4_tlb_flushI, /* tlb_flushI */ 196172738Simp arm10_tlb_flushI_SE, /* tlb_flushI_SE */ 197172738Simp armv4_tlb_flushD, /* tlb_flushD */ 198172738Simp armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 199172738Simp 200172738Simp /* Cache operations */ 201172738Simp 202172738Simp armv5_ec_icache_sync_all, /* icache_sync_all */ 203172738Simp armv5_ec_icache_sync_range, /* icache_sync_range */ 204172738Simp 205172738Simp armv5_ec_dcache_wbinv_all, /* dcache_wbinv_all */ 206172738Simp armv5_ec_dcache_wbinv_range, /* dcache_wbinv_range */ 207195798Sraj armv5_ec_dcache_inv_range, /* dcache_inv_range */ 208172738Simp armv5_ec_dcache_wb_range, /* dcache_wb_range */ 209172738Simp 210266203Sian armv4_idcache_inv_all, /* idcache_inv_all */ 211172738Simp armv5_ec_idcache_wbinv_all, /* idcache_wbinv_all */ 212172738Simp armv5_ec_idcache_wbinv_range, /* idcache_wbinv_range */ 213172738Simp 214173442Scognet cpufunc_nullop, /* l2cache_wbinv_all */ 215173442Scognet (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 216173442Scognet (void *)cpufunc_nullop, /* l2cache_inv_range */ 217173442Scognet (void *)cpufunc_nullop, /* l2cache_wb_range */ 218266387Sian (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ 219236991Simp 220172738Simp /* Other functions */ 221172738Simp 222172738Simp cpufunc_nullop, /* flush_prefetchbuf */ 223172738Simp armv4_drain_writebuf, /* drain_writebuf */ 224172738Simp cpufunc_nullop, /* flush_brnchtgt_C */ 225172738Simp (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 226172738Simp 227172738Simp (void *)cpufunc_nullop, /* sleep */ 228172738Simp 229172738Simp /* Soft functions */ 230172738Simp 231172738Simp cpufunc_null_fixup, /* dataabt_fixup */ 232172738Simp cpufunc_null_fixup, /* prefetchabt_fixup */ 233172738Simp 234172738Simp arm10_context_switch, /* context_switch */ 235172738Simp 236172738Simp arm10_setup /* cpu setup */ 237172738Simp 238172738Simp}; 239183835Sraj 240186933Srajstruct cpu_functions sheeva_cpufuncs = { 241183835Sraj /* CPU functions */ 242183835Sraj 243183835Sraj cpufunc_id, /* id */ 244183835Sraj cpufunc_nullop, /* cpwait */ 245183835Sraj 246183835Sraj /* MMU functions */ 247183835Sraj 248183835Sraj cpufunc_control, /* control */ 249183835Sraj cpufunc_domains, /* Domain */ 250186933Sraj sheeva_setttb, /* Setttb */ 251183835Sraj cpufunc_faultstatus, /* Faultstatus */ 252183835Sraj cpufunc_faultaddress, /* Faultaddress */ 253183835Sraj 254183835Sraj /* TLB functions */ 255183835Sraj 256183835Sraj armv4_tlb_flushID, /* tlb_flushID */ 257183835Sraj arm10_tlb_flushID_SE, /* tlb_flushID_SE */ 258183835Sraj armv4_tlb_flushI, /* tlb_flushI */ 259183835Sraj arm10_tlb_flushI_SE, /* tlb_flushI_SE */ 260183835Sraj armv4_tlb_flushD, /* tlb_flushD */ 261183835Sraj armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 262183835Sraj 263183835Sraj /* Cache operations */ 264183835Sraj 265183835Sraj armv5_ec_icache_sync_all, /* icache_sync_all */ 266183835Sraj armv5_ec_icache_sync_range, /* icache_sync_range */ 267183835Sraj 268183835Sraj armv5_ec_dcache_wbinv_all, /* dcache_wbinv_all */ 269186933Sraj sheeva_dcache_wbinv_range, /* dcache_wbinv_range */ 270186933Sraj sheeva_dcache_inv_range, /* dcache_inv_range */ 271186933Sraj sheeva_dcache_wb_range, /* dcache_wb_range */ 272183835Sraj 273266203Sian armv4_idcache_inv_all, /* idcache_inv_all */ 274183835Sraj armv5_ec_idcache_wbinv_all, /* idcache_wbinv_all */ 275186933Sraj sheeva_idcache_wbinv_range, /* idcache_wbinv_all */ 276183835Sraj 277186933Sraj sheeva_l2cache_wbinv_all, /* l2cache_wbinv_all */ 278186933Sraj sheeva_l2cache_wbinv_range, /* l2cache_wbinv_range */ 279186933Sraj sheeva_l2cache_inv_range, /* l2cache_inv_range */ 280186933Sraj sheeva_l2cache_wb_range, /* l2cache_wb_range */ 281266387Sian (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ 282183835Sraj 283183835Sraj /* Other functions */ 284183835Sraj 285183835Sraj cpufunc_nullop, /* flush_prefetchbuf */ 286183835Sraj armv4_drain_writebuf, /* drain_writebuf */ 287183835Sraj cpufunc_nullop, /* flush_brnchtgt_C */ 288183835Sraj (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 289183835Sraj 290212825Smav sheeva_cpu_sleep, /* sleep */ 291183835Sraj 292183835Sraj /* Soft functions */ 293183835Sraj 294183835Sraj cpufunc_null_fixup, /* dataabt_fixup */ 295183835Sraj cpufunc_null_fixup, /* prefetchabt_fixup */ 296183835Sraj 297183835Sraj arm10_context_switch, /* context_switch */ 298183835Sraj 299183835Sraj arm10_setup /* cpu setup */ 300183835Sraj}; 301172738Simp#endif /* CPU_ARM9E || CPU_ARM10 */ 302172738Simp 303129198Scognet#ifdef CPU_ARM10 304129198Scognetstruct cpu_functions arm10_cpufuncs = { 305129198Scognet /* CPU functions */ 306129198Scognet 307129198Scognet cpufunc_id, /* id */ 308129198Scognet cpufunc_nullop, /* cpwait */ 309129198Scognet 310129198Scognet /* MMU functions */ 311129198Scognet 312129198Scognet cpufunc_control, /* control */ 313129198Scognet cpufunc_domains, /* Domain */ 314129198Scognet arm10_setttb, /* Setttb */ 315129198Scognet cpufunc_faultstatus, /* Faultstatus */ 316129198Scognet cpufunc_faultaddress, /* Faultaddress */ 317129198Scognet 318129198Scognet /* TLB functions */ 319129198Scognet 320129198Scognet armv4_tlb_flushID, /* tlb_flushID */ 321129198Scognet arm10_tlb_flushID_SE, /* tlb_flushID_SE */ 322129198Scognet armv4_tlb_flushI, /* tlb_flushI */ 323129198Scognet arm10_tlb_flushI_SE, /* tlb_flushI_SE */ 324129198Scognet armv4_tlb_flushD, /* tlb_flushD */ 325129198Scognet armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 326129198Scognet 327129198Scognet /* Cache operations */ 328129198Scognet 329129198Scognet arm10_icache_sync_all, /* icache_sync_all */ 330129198Scognet arm10_icache_sync_range, /* icache_sync_range */ 331129198Scognet 332129198Scognet arm10_dcache_wbinv_all, /* dcache_wbinv_all */ 333129198Scognet arm10_dcache_wbinv_range, /* dcache_wbinv_range */ 334129198Scognet arm10_dcache_inv_range, /* dcache_inv_range */ 335129198Scognet arm10_dcache_wb_range, /* dcache_wb_range */ 336129198Scognet 337266203Sian armv4_idcache_inv_all, /* idcache_inv_all */ 338129198Scognet arm10_idcache_wbinv_all, /* idcache_wbinv_all */ 339129198Scognet arm10_idcache_wbinv_range, /* idcache_wbinv_range */ 340171618Scognet cpufunc_nullop, /* l2cache_wbinv_all */ 341171781Scognet (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 342171781Scognet (void *)cpufunc_nullop, /* l2cache_inv_range */ 343171781Scognet (void *)cpufunc_nullop, /* l2cache_wb_range */ 344266387Sian (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ 345129198Scognet 346129198Scognet /* Other functions */ 347129198Scognet 348129198Scognet cpufunc_nullop, /* flush_prefetchbuf */ 349129198Scognet armv4_drain_writebuf, /* drain_writebuf */ 350129198Scognet cpufunc_nullop, /* flush_brnchtgt_C */ 351129198Scognet (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 352129198Scognet 353129198Scognet (void *)cpufunc_nullop, /* sleep */ 354129198Scognet 355129198Scognet /* Soft functions */ 356129198Scognet 357129198Scognet cpufunc_null_fixup, /* dataabt_fixup */ 358129198Scognet cpufunc_null_fixup, /* prefetchabt_fixup */ 359129198Scognet 360129198Scognet arm10_context_switch, /* context_switch */ 361129198Scognet 362129198Scognet arm10_setup /* cpu setup */ 363129198Scognet 364129198Scognet}; 365129198Scognet#endif /* CPU_ARM10 */ 366129198Scognet 367239268Sgonzo#ifdef CPU_MV_PJ4B 368239268Sgonzostruct cpu_functions pj4bv7_cpufuncs = { 369239268Sgonzo /* CPU functions */ 370239268Sgonzo 371239268Sgonzo cpufunc_id, /* id */ 372239268Sgonzo arm11_drain_writebuf, /* cpwait */ 373239268Sgonzo 374239268Sgonzo /* MMU functions */ 375239268Sgonzo 376239268Sgonzo cpufunc_control, /* control */ 377239268Sgonzo cpufunc_domains, /* Domain */ 378239268Sgonzo pj4b_setttb, /* Setttb */ 379239268Sgonzo cpufunc_faultstatus, /* Faultstatus */ 380239268Sgonzo cpufunc_faultaddress, /* Faultaddress */ 381239268Sgonzo 382239268Sgonzo /* TLB functions */ 383239268Sgonzo 384239268Sgonzo armv7_tlb_flushID, /* tlb_flushID */ 385239268Sgonzo armv7_tlb_flushID_SE, /* tlb_flushID_SE */ 386239268Sgonzo armv7_tlb_flushID, /* tlb_flushI */ 387239268Sgonzo armv7_tlb_flushID_SE, /* tlb_flushI_SE */ 388239268Sgonzo armv7_tlb_flushID, /* tlb_flushD */ 389239268Sgonzo armv7_tlb_flushID_SE, /* tlb_flushD_SE */ 390239268Sgonzo 391239268Sgonzo /* Cache operations */ 392239268Sgonzo armv7_idcache_wbinv_all, /* icache_sync_all */ 393239268Sgonzo armv7_icache_sync_range, /* icache_sync_range */ 394239268Sgonzo 395239268Sgonzo armv7_dcache_wbinv_all, /* dcache_wbinv_all */ 396239268Sgonzo armv7_dcache_wbinv_range, /* dcache_wbinv_range */ 397239268Sgonzo armv7_dcache_inv_range, /* dcache_inv_range */ 398239268Sgonzo armv7_dcache_wb_range, /* dcache_wb_range */ 399239268Sgonzo 400266203Sian armv7_idcache_inv_all, /* idcache_inv_all */ 401239268Sgonzo armv7_idcache_wbinv_all, /* idcache_wbinv_all */ 402239268Sgonzo armv7_idcache_wbinv_range, /* idcache_wbinv_all */ 403239268Sgonzo 404239268Sgonzo (void *)cpufunc_nullop, /* l2cache_wbinv_all */ 405239268Sgonzo (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 406239268Sgonzo (void *)cpufunc_nullop, /* l2cache_inv_range */ 407239268Sgonzo (void *)cpufunc_nullop, /* l2cache_wb_range */ 408266387Sian (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ 409239268Sgonzo 410239268Sgonzo /* Other functions */ 411239268Sgonzo 412239268Sgonzo pj4b_drain_readbuf, /* flush_prefetchbuf */ 413239268Sgonzo arm11_drain_writebuf, /* drain_writebuf */ 414239268Sgonzo pj4b_flush_brnchtgt_all, /* flush_brnchtgt_C */ 415239268Sgonzo pj4b_flush_brnchtgt_va, /* flush_brnchtgt_E */ 416239268Sgonzo 417239268Sgonzo (void *)cpufunc_nullop, /* sleep */ 418239268Sgonzo 419239268Sgonzo /* Soft functions */ 420239268Sgonzo 421239268Sgonzo cpufunc_null_fixup, /* dataabt_fixup */ 422239268Sgonzo cpufunc_null_fixup, /* prefetchabt_fixup */ 423239268Sgonzo 424239268Sgonzo arm11_context_switch, /* context_switch */ 425239268Sgonzo 426239268Sgonzo pj4bv7_setup /* cpu setup */ 427239268Sgonzo}; 428239268Sgonzo#endif /* CPU_MV_PJ4B */ 429239268Sgonzo 430129198Scognet#if defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \ 431161592Scognet defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \ 432161592Scognet defined(CPU_XSCALE_80219) 433161592Scognet 434129198Scognetstruct cpu_functions xscale_cpufuncs = { 435129198Scognet /* CPU functions */ 436129198Scognet 437129198Scognet cpufunc_id, /* id */ 438129198Scognet xscale_cpwait, /* cpwait */ 439129198Scognet 440129198Scognet /* MMU functions */ 441129198Scognet 442129198Scognet xscale_control, /* control */ 443129198Scognet cpufunc_domains, /* domain */ 444129198Scognet xscale_setttb, /* setttb */ 445129198Scognet cpufunc_faultstatus, /* faultstatus */ 446129198Scognet cpufunc_faultaddress, /* faultaddress */ 447129198Scognet 448129198Scognet /* TLB functions */ 449129198Scognet 450129198Scognet armv4_tlb_flushID, /* tlb_flushID */ 451129198Scognet xscale_tlb_flushID_SE, /* tlb_flushID_SE */ 452129198Scognet armv4_tlb_flushI, /* tlb_flushI */ 453129198Scognet (void *)armv4_tlb_flushI, /* tlb_flushI_SE */ 454129198Scognet armv4_tlb_flushD, /* tlb_flushD */ 455129198Scognet armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 456129198Scognet 457129198Scognet /* Cache operations */ 458129198Scognet 459129198Scognet xscale_cache_syncI, /* icache_sync_all */ 460129198Scognet xscale_cache_syncI_rng, /* icache_sync_range */ 461129198Scognet 462129198Scognet xscale_cache_purgeD, /* dcache_wbinv_all */ 463129198Scognet xscale_cache_purgeD_rng, /* dcache_wbinv_range */ 464129198Scognet xscale_cache_flushD_rng, /* dcache_inv_range */ 465129198Scognet xscale_cache_cleanD_rng, /* dcache_wb_range */ 466129198Scognet 467266203Sian xscale_cache_flushID, /* idcache_inv_all */ 468129198Scognet xscale_cache_purgeID, /* idcache_wbinv_all */ 469129198Scognet xscale_cache_purgeID_rng, /* idcache_wbinv_range */ 470171618Scognet cpufunc_nullop, /* l2cache_wbinv_all */ 471171781Scognet (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 472171781Scognet (void *)cpufunc_nullop, /* l2cache_inv_range */ 473171781Scognet (void *)cpufunc_nullop, /* l2cache_wb_range */ 474266387Sian (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ 475129198Scognet 476129198Scognet /* Other functions */ 477129198Scognet 478129198Scognet cpufunc_nullop, /* flush_prefetchbuf */ 479129198Scognet armv4_drain_writebuf, /* drain_writebuf */ 480129198Scognet cpufunc_nullop, /* flush_brnchtgt_C */ 481129198Scognet (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 482129198Scognet 483129198Scognet xscale_cpu_sleep, /* sleep */ 484129198Scognet 485129198Scognet /* Soft functions */ 486129198Scognet 487129198Scognet cpufunc_null_fixup, /* dataabt_fixup */ 488129198Scognet cpufunc_null_fixup, /* prefetchabt_fixup */ 489129198Scognet 490129198Scognet xscale_context_switch, /* context_switch */ 491129198Scognet 492129198Scognet xscale_setup /* cpu setup */ 493129198Scognet}; 494129198Scognet#endif 495161592Scognet/* CPU_XSCALE_80200 || CPU_XSCALE_80321 || CPU_XSCALE_PXA2X0 || CPU_XSCALE_IXP425 496161592Scognet CPU_XSCALE_80219 */ 497129198Scognet 498164080Scognet#ifdef CPU_XSCALE_81342 499164080Scognetstruct cpu_functions xscalec3_cpufuncs = { 500164080Scognet /* CPU functions */ 501164080Scognet 502164080Scognet cpufunc_id, /* id */ 503164080Scognet xscale_cpwait, /* cpwait */ 504164080Scognet 505164080Scognet /* MMU functions */ 506164080Scognet 507164080Scognet xscale_control, /* control */ 508164080Scognet cpufunc_domains, /* domain */ 509164080Scognet xscalec3_setttb, /* setttb */ 510164080Scognet cpufunc_faultstatus, /* faultstatus */ 511164080Scognet cpufunc_faultaddress, /* faultaddress */ 512164080Scognet 513164080Scognet /* TLB functions */ 514164080Scognet 515164080Scognet armv4_tlb_flushID, /* tlb_flushID */ 516164080Scognet xscale_tlb_flushID_SE, /* tlb_flushID_SE */ 517164080Scognet armv4_tlb_flushI, /* tlb_flushI */ 518164080Scognet (void *)armv4_tlb_flushI, /* tlb_flushI_SE */ 519164080Scognet armv4_tlb_flushD, /* tlb_flushD */ 520164080Scognet armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 521164080Scognet 522164080Scognet /* Cache operations */ 523164080Scognet 524164080Scognet xscalec3_cache_syncI, /* icache_sync_all */ 525171618Scognet xscalec3_cache_syncI_rng, /* icache_sync_range */ 526164080Scognet 527164080Scognet xscalec3_cache_purgeD, /* dcache_wbinv_all */ 528164080Scognet xscalec3_cache_purgeD_rng, /* dcache_wbinv_range */ 529164080Scognet xscale_cache_flushD_rng, /* dcache_inv_range */ 530164080Scognet xscalec3_cache_cleanD_rng, /* dcache_wb_range */ 531164080Scognet 532266203Sian xscale_cache_flushID, /* idcache_inv_all */ 533171618Scognet xscalec3_cache_purgeID, /* idcache_wbinv_all */ 534164080Scognet xscalec3_cache_purgeID_rng, /* idcache_wbinv_range */ 535171618Scognet xscalec3_l2cache_purge, /* l2cache_wbinv_all */ 536171618Scognet xscalec3_l2cache_purge_rng, /* l2cache_wbinv_range */ 537171618Scognet xscalec3_l2cache_flush_rng, /* l2cache_inv_range */ 538171618Scognet xscalec3_l2cache_clean_rng, /* l2cache_wb_range */ 539266387Sian (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ 540164080Scognet 541164080Scognet /* Other functions */ 542164080Scognet 543164080Scognet cpufunc_nullop, /* flush_prefetchbuf */ 544164080Scognet armv4_drain_writebuf, /* drain_writebuf */ 545164080Scognet cpufunc_nullop, /* flush_brnchtgt_C */ 546164080Scognet (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 547164080Scognet 548164080Scognet xscale_cpu_sleep, /* sleep */ 549164080Scognet 550164080Scognet /* Soft functions */ 551164080Scognet 552164080Scognet cpufunc_null_fixup, /* dataabt_fixup */ 553164080Scognet cpufunc_null_fixup, /* prefetchabt_fixup */ 554164080Scognet 555164080Scognet xscalec3_context_switch, /* context_switch */ 556164080Scognet 557164080Scognet xscale_setup /* cpu setup */ 558164080Scognet}; 559164080Scognet#endif /* CPU_XSCALE_81342 */ 560201468Srpaulo 561201468Srpaulo 562207611Skevlo#if defined(CPU_FA526) || defined(CPU_FA626TE) 563201468Srpaulostruct cpu_functions fa526_cpufuncs = { 564201468Srpaulo /* CPU functions */ 565201468Srpaulo 566207611Skevlo cpufunc_id, /* id */ 567207611Skevlo cpufunc_nullop, /* cpwait */ 568201468Srpaulo 569201468Srpaulo /* MMU functions */ 570201468Srpaulo 571207611Skevlo cpufunc_control, /* control */ 572207611Skevlo cpufunc_domains, /* domain */ 573207611Skevlo fa526_setttb, /* setttb */ 574207611Skevlo cpufunc_faultstatus, /* faultstatus */ 575207611Skevlo cpufunc_faultaddress, /* faultaddress */ 576201468Srpaulo 577201468Srpaulo /* TLB functions */ 578201468Srpaulo 579207611Skevlo armv4_tlb_flushID, /* tlb_flushID */ 580207611Skevlo fa526_tlb_flushID_SE, /* tlb_flushID_SE */ 581207611Skevlo armv4_tlb_flushI, /* tlb_flushI */ 582207611Skevlo fa526_tlb_flushI_SE, /* tlb_flushI_SE */ 583207611Skevlo armv4_tlb_flushD, /* tlb_flushD */ 584207611Skevlo armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 585201468Srpaulo 586201468Srpaulo /* Cache operations */ 587201468Srpaulo 588207611Skevlo fa526_icache_sync_all, /* icache_sync_all */ 589207611Skevlo fa526_icache_sync_range, /* icache_sync_range */ 590201468Srpaulo 591207611Skevlo fa526_dcache_wbinv_all, /* dcache_wbinv_all */ 592207611Skevlo fa526_dcache_wbinv_range, /* dcache_wbinv_range */ 593207611Skevlo fa526_dcache_inv_range, /* dcache_inv_range */ 594207611Skevlo fa526_dcache_wb_range, /* dcache_wb_range */ 595201468Srpaulo 596266203Sian armv4_idcache_inv_all, /* idcache_inv_all */ 597207611Skevlo fa526_idcache_wbinv_all, /* idcache_wbinv_all */ 598207611Skevlo fa526_idcache_wbinv_range, /* idcache_wbinv_range */ 599207611Skevlo cpufunc_nullop, /* l2cache_wbinv_all */ 600207611Skevlo (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 601207611Skevlo (void *)cpufunc_nullop, /* l2cache_inv_range */ 602207611Skevlo (void *)cpufunc_nullop, /* l2cache_wb_range */ 603266387Sian (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ 604201468Srpaulo 605201468Srpaulo /* Other functions */ 606201468Srpaulo 607207611Skevlo fa526_flush_prefetchbuf, /* flush_prefetchbuf */ 608207611Skevlo armv4_drain_writebuf, /* drain_writebuf */ 609207611Skevlo cpufunc_nullop, /* flush_brnchtgt_C */ 610207611Skevlo fa526_flush_brnchtgt_E, /* flush_brnchtgt_E */ 611201468Srpaulo 612207611Skevlo fa526_cpu_sleep, /* sleep */ 613201468Srpaulo 614201468Srpaulo /* Soft functions */ 615201468Srpaulo 616207611Skevlo cpufunc_null_fixup, /* dataabt_fixup */ 617207611Skevlo cpufunc_null_fixup, /* prefetchabt_fixup */ 618201468Srpaulo 619207611Skevlo fa526_context_switch, /* context_switch */ 620201468Srpaulo 621207611Skevlo fa526_setup /* cpu setup */ 622236991Simp}; 623207611Skevlo#endif /* CPU_FA526 || CPU_FA626TE */ 624201468Srpaulo 625244480Sgonzo#if defined(CPU_ARM1136) 626244480Sgonzostruct cpu_functions arm1136_cpufuncs = { 627239701Sgonzo /* CPU functions */ 628239701Sgonzo 629239701Sgonzo cpufunc_id, /* id */ 630244480Sgonzo cpufunc_nullop, /* cpwait */ 631239701Sgonzo 632239701Sgonzo /* MMU functions */ 633239701Sgonzo 634239701Sgonzo cpufunc_control, /* control */ 635239701Sgonzo cpufunc_domains, /* Domain */ 636244480Sgonzo arm11x6_setttb, /* Setttb */ 637239701Sgonzo cpufunc_faultstatus, /* Faultstatus */ 638239701Sgonzo cpufunc_faultaddress, /* Faultaddress */ 639239701Sgonzo 640239701Sgonzo /* TLB functions */ 641239701Sgonzo 642239701Sgonzo arm11_tlb_flushID, /* tlb_flushID */ 643239701Sgonzo arm11_tlb_flushID_SE, /* tlb_flushID_SE */ 644239701Sgonzo arm11_tlb_flushI, /* tlb_flushI */ 645239701Sgonzo arm11_tlb_flushI_SE, /* tlb_flushI_SE */ 646239701Sgonzo arm11_tlb_flushD, /* tlb_flushD */ 647239701Sgonzo arm11_tlb_flushD_SE, /* tlb_flushD_SE */ 648239701Sgonzo 649239701Sgonzo /* Cache operations */ 650239701Sgonzo 651244480Sgonzo arm11x6_icache_sync_all, /* icache_sync_all */ 652244480Sgonzo arm11x6_icache_sync_range, /* icache_sync_range */ 653239701Sgonzo 654244480Sgonzo arm11x6_dcache_wbinv_all, /* dcache_wbinv_all */ 655239701Sgonzo armv6_dcache_wbinv_range, /* dcache_wbinv_range */ 656239701Sgonzo armv6_dcache_inv_range, /* dcache_inv_range */ 657239701Sgonzo armv6_dcache_wb_range, /* dcache_wb_range */ 658239701Sgonzo 659266203Sian armv6_idcache_inv_all, /* idcache_inv_all */ 660244480Sgonzo arm11x6_idcache_wbinv_all, /* idcache_wbinv_all */ 661244480Sgonzo arm11x6_idcache_wbinv_range, /* idcache_wbinv_range */ 662239701Sgonzo 663244480Sgonzo (void *)cpufunc_nullop, /* l2cache_wbinv_all */ 664239701Sgonzo (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 665239701Sgonzo (void *)cpufunc_nullop, /* l2cache_inv_range */ 666239701Sgonzo (void *)cpufunc_nullop, /* l2cache_wb_range */ 667266387Sian (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ 668239701Sgonzo 669239701Sgonzo /* Other functions */ 670239701Sgonzo 671244480Sgonzo arm11x6_flush_prefetchbuf, /* flush_prefetchbuf */ 672239701Sgonzo arm11_drain_writebuf, /* drain_writebuf */ 673239701Sgonzo cpufunc_nullop, /* flush_brnchtgt_C */ 674239701Sgonzo (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 675239701Sgonzo 676244480Sgonzo arm11_sleep, /* sleep */ 677239701Sgonzo 678239701Sgonzo /* Soft functions */ 679239701Sgonzo 680239701Sgonzo cpufunc_null_fixup, /* dataabt_fixup */ 681239701Sgonzo cpufunc_null_fixup, /* prefetchabt_fixup */ 682239701Sgonzo 683239701Sgonzo arm11_context_switch, /* context_switch */ 684239701Sgonzo 685244480Sgonzo arm11x6_setup /* cpu setup */ 686239701Sgonzo}; 687244480Sgonzo#endif /* CPU_ARM1136 */ 688244480Sgonzo#if defined(CPU_ARM1176) 689244480Sgonzostruct cpu_functions arm1176_cpufuncs = { 690244480Sgonzo /* CPU functions */ 691244480Sgonzo 692244480Sgonzo cpufunc_id, /* id */ 693244480Sgonzo cpufunc_nullop, /* cpwait */ 694244480Sgonzo 695244480Sgonzo /* MMU functions */ 696244480Sgonzo 697244480Sgonzo cpufunc_control, /* control */ 698244480Sgonzo cpufunc_domains, /* Domain */ 699244480Sgonzo arm11x6_setttb, /* Setttb */ 700244480Sgonzo cpufunc_faultstatus, /* Faultstatus */ 701244480Sgonzo cpufunc_faultaddress, /* Faultaddress */ 702244480Sgonzo 703244480Sgonzo /* TLB functions */ 704244480Sgonzo 705244480Sgonzo arm11_tlb_flushID, /* tlb_flushID */ 706244480Sgonzo arm11_tlb_flushID_SE, /* tlb_flushID_SE */ 707244480Sgonzo arm11_tlb_flushI, /* tlb_flushI */ 708244480Sgonzo arm11_tlb_flushI_SE, /* tlb_flushI_SE */ 709244480Sgonzo arm11_tlb_flushD, /* tlb_flushD */ 710244480Sgonzo arm11_tlb_flushD_SE, /* tlb_flushD_SE */ 711244480Sgonzo 712244480Sgonzo /* Cache operations */ 713244480Sgonzo 714244480Sgonzo arm11x6_icache_sync_all, /* icache_sync_all */ 715244480Sgonzo arm11x6_icache_sync_range, /* icache_sync_range */ 716244480Sgonzo 717244480Sgonzo arm11x6_dcache_wbinv_all, /* dcache_wbinv_all */ 718244480Sgonzo armv6_dcache_wbinv_range, /* dcache_wbinv_range */ 719244480Sgonzo armv6_dcache_inv_range, /* dcache_inv_range */ 720244480Sgonzo armv6_dcache_wb_range, /* dcache_wb_range */ 721244480Sgonzo 722266203Sian armv6_idcache_inv_all, /* idcache_inv_all */ 723244480Sgonzo arm11x6_idcache_wbinv_all, /* idcache_wbinv_all */ 724244480Sgonzo arm11x6_idcache_wbinv_range, /* idcache_wbinv_range */ 725244480Sgonzo 726244480Sgonzo (void *)cpufunc_nullop, /* l2cache_wbinv_all */ 727244480Sgonzo (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 728244480Sgonzo (void *)cpufunc_nullop, /* l2cache_inv_range */ 729244480Sgonzo (void *)cpufunc_nullop, /* l2cache_wb_range */ 730266387Sian (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ 731244480Sgonzo 732244480Sgonzo /* Other functions */ 733244480Sgonzo 734244480Sgonzo arm11x6_flush_prefetchbuf, /* flush_prefetchbuf */ 735244480Sgonzo arm11_drain_writebuf, /* drain_writebuf */ 736244480Sgonzo cpufunc_nullop, /* flush_brnchtgt_C */ 737244480Sgonzo (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 738244480Sgonzo 739244480Sgonzo arm11x6_sleep, /* sleep */ 740244480Sgonzo 741244480Sgonzo /* Soft functions */ 742244480Sgonzo 743244480Sgonzo cpufunc_null_fixup, /* dataabt_fixup */ 744244480Sgonzo cpufunc_null_fixup, /* prefetchabt_fixup */ 745244480Sgonzo 746244480Sgonzo arm11_context_switch, /* context_switch */ 747244480Sgonzo 748244480Sgonzo arm11x6_setup /* cpu setup */ 749244480Sgonzo}; 750244480Sgonzo#endif /*CPU_ARM1176 */ 751239701Sgonzo 752266058Sian#if defined(CPU_CORTEXA) || defined(CPU_KRAIT) 753239268Sgonzostruct cpu_functions cortexa_cpufuncs = { 754239268Sgonzo /* CPU functions */ 755239268Sgonzo 756239268Sgonzo cpufunc_id, /* id */ 757239268Sgonzo cpufunc_nullop, /* cpwait */ 758239268Sgonzo 759239268Sgonzo /* MMU functions */ 760239268Sgonzo 761239268Sgonzo cpufunc_control, /* control */ 762239268Sgonzo cpufunc_domains, /* Domain */ 763239268Sgonzo armv7_setttb, /* Setttb */ 764239268Sgonzo cpufunc_faultstatus, /* Faultstatus */ 765239268Sgonzo cpufunc_faultaddress, /* Faultaddress */ 766239268Sgonzo 767266332Sian /* 768266332Sian * TLB functions. ARMv7 does all TLB ops based on a unified TLB model 769266332Sian * whether the hardware implements separate I+D or not, so we use the 770266332Sian * same 'ID' functions for all 3 variations. 771266332Sian */ 772239268Sgonzo 773243024Scognet armv7_tlb_flushID, /* tlb_flushID */ 774239268Sgonzo armv7_tlb_flushID_SE, /* tlb_flushID_SE */ 775266332Sian armv7_tlb_flushID, /* tlb_flushI */ 776266332Sian armv7_tlb_flushID_SE, /* tlb_flushI_SE */ 777266332Sian armv7_tlb_flushID, /* tlb_flushD */ 778266332Sian armv7_tlb_flushID_SE, /* tlb_flushD_SE */ 779239268Sgonzo 780239268Sgonzo /* Cache operations */ 781239268Sgonzo 782266373Sian armv7_icache_sync_all, /* icache_sync_all */ 783239268Sgonzo armv7_icache_sync_range, /* icache_sync_range */ 784239268Sgonzo 785239268Sgonzo armv7_dcache_wbinv_all, /* dcache_wbinv_all */ 786239268Sgonzo armv7_dcache_wbinv_range, /* dcache_wbinv_range */ 787239268Sgonzo armv7_dcache_inv_range, /* dcache_inv_range */ 788239268Sgonzo armv7_dcache_wb_range, /* dcache_wb_range */ 789239268Sgonzo 790266203Sian armv7_idcache_inv_all, /* idcache_inv_all */ 791239268Sgonzo armv7_idcache_wbinv_all, /* idcache_wbinv_all */ 792239268Sgonzo armv7_idcache_wbinv_range, /* idcache_wbinv_range */ 793239268Sgonzo 794243026Scognet /* 795243026Scognet * Note: For CPUs using the PL310 the L2 ops are filled in when the 796239268Sgonzo * L2 cache controller is actually enabled. 797239268Sgonzo */ 798239268Sgonzo cpufunc_nullop, /* l2cache_wbinv_all */ 799239268Sgonzo (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 800239268Sgonzo (void *)cpufunc_nullop, /* l2cache_inv_range */ 801239268Sgonzo (void *)cpufunc_nullop, /* l2cache_wb_range */ 802266387Sian (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ 803239268Sgonzo 804239268Sgonzo /* Other functions */ 805239268Sgonzo 806239268Sgonzo cpufunc_nullop, /* flush_prefetchbuf */ 807245478Scognet armv7_drain_writebuf, /* drain_writebuf */ 808239268Sgonzo cpufunc_nullop, /* flush_brnchtgt_C */ 809239268Sgonzo (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 810239268Sgonzo 811266207Sian armv7_sleep, /* sleep */ 812239268Sgonzo 813239268Sgonzo /* Soft functions */ 814239268Sgonzo 815239268Sgonzo cpufunc_null_fixup, /* dataabt_fixup */ 816239268Sgonzo cpufunc_null_fixup, /* prefetchabt_fixup */ 817239268Sgonzo 818245478Scognet armv7_context_switch, /* context_switch */ 819239268Sgonzo 820239268Sgonzo cortexa_setup /* cpu setup */ 821239268Sgonzo}; 822239268Sgonzo#endif /* CPU_CORTEXA */ 823201468Srpaulo 824129198Scognet/* 825129198Scognet * Global constants also used by locore.s 826129198Scognet */ 827129198Scognet 828129198Scognetstruct cpu_functions cpufuncs; 829129198Scognetu_int cputype; 830129198Scognetu_int cpu_reset_needs_v4_MMU_disable; /* flag used in locore.s */ 831129198Scognet 832266311Sian#if defined(CPU_ARM9) || \ 833244480Sgonzo defined (CPU_ARM9E) || defined (CPU_ARM10) || defined (CPU_ARM1136) || \ 834244480Sgonzo defined(CPU_ARM1176) || defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \ 835207611Skevlo defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \ 836239268Sgonzo defined(CPU_FA526) || defined(CPU_FA626TE) || defined(CPU_MV_PJ4B) || \ 837239268Sgonzo defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342) || \ 838266058Sian defined(CPU_CORTEXA) || defined(CPU_KRAIT) 839161592Scognet 840137498Strhodesstatic void get_cachetype_cp15(void); 841129198Scognet 842129198Scognet/* Additional cache information local to this file. Log2 of some of the 843129198Scognet above numbers. */ 844129198Scognetstatic int arm_dcache_l2_nsets; 845129198Scognetstatic int arm_dcache_l2_assoc; 846129198Scognetstatic int arm_dcache_l2_linesize; 847129198Scognet 848129198Scognetstatic void 849129198Scognetget_cachetype_cp15() 850129198Scognet{ 851239268Sgonzo u_int ctype, isize, dsize, cpuid; 852239268Sgonzo u_int clevel, csize, i, sel; 853129198Scognet u_int multiplier; 854239268Sgonzo u_char type; 855129198Scognet 856129198Scognet __asm __volatile("mrc p15, 0, %0, c0, c0, 1" 857129198Scognet : "=r" (ctype)); 858129198Scognet 859239268Sgonzo cpuid = cpufunc_id(); 860129198Scognet /* 861129198Scognet * ...and thus spake the ARM ARM: 862129198Scognet * 863129198Scognet * If an <opcode2> value corresponding to an unimplemented or 864129198Scognet * reserved ID register is encountered, the System Control 865129198Scognet * processor returns the value of the main ID register. 866129198Scognet */ 867239268Sgonzo if (ctype == cpuid) 868129198Scognet goto out; 869129198Scognet 870239268Sgonzo if (CPU_CT_FORMAT(ctype) == CPU_CT_ARMV7) { 871239268Sgonzo __asm __volatile("mrc p15, 1, %0, c0, c0, 1" 872239268Sgonzo : "=r" (clevel)); 873239268Sgonzo arm_cache_level = clevel; 874239268Sgonzo arm_cache_loc = CPU_CLIDR_LOC(arm_cache_level); 875239268Sgonzo i = 0; 876239268Sgonzo while ((type = (clevel & 0x7)) && i < 7) { 877239268Sgonzo if (type == CACHE_DCACHE || type == CACHE_UNI_CACHE || 878239268Sgonzo type == CACHE_SEP_CACHE) { 879239268Sgonzo sel = i << 1; 880239268Sgonzo __asm __volatile("mcr p15, 2, %0, c0, c0, 0" 881239268Sgonzo : : "r" (sel)); 882239268Sgonzo __asm __volatile("mrc p15, 1, %0, c0, c0, 0" 883239268Sgonzo : "=r" (csize)); 884239268Sgonzo arm_cache_type[sel] = csize; 885239268Sgonzo arm_dcache_align = 1 << 886239268Sgonzo (CPUV7_CT_xSIZE_LEN(csize) + 4); 887239268Sgonzo arm_dcache_align_mask = arm_dcache_align - 1; 888239268Sgonzo } 889239268Sgonzo if (type == CACHE_ICACHE || type == CACHE_SEP_CACHE) { 890239268Sgonzo sel = (i << 1) | 1; 891239268Sgonzo __asm __volatile("mcr p15, 2, %0, c0, c0, 0" 892239268Sgonzo : : "r" (sel)); 893239268Sgonzo __asm __volatile("mrc p15, 1, %0, c0, c0, 0" 894239268Sgonzo : "=r" (csize)); 895239268Sgonzo arm_cache_type[sel] = csize; 896239268Sgonzo } 897239268Sgonzo i++; 898239268Sgonzo clevel >>= 3; 899239268Sgonzo } 900239268Sgonzo } else { 901239268Sgonzo if ((ctype & CPU_CT_S) == 0) 902239268Sgonzo arm_pcache_unified = 1; 903129198Scognet 904239268Sgonzo /* 905239268Sgonzo * If you want to know how this code works, go read the ARM ARM. 906239268Sgonzo */ 907129198Scognet 908239268Sgonzo arm_pcache_type = CPU_CT_CTYPE(ctype); 909129198Scognet 910239268Sgonzo if (arm_pcache_unified == 0) { 911239268Sgonzo isize = CPU_CT_ISIZE(ctype); 912239268Sgonzo multiplier = (isize & CPU_CT_xSIZE_M) ? 3 : 2; 913239268Sgonzo arm_picache_line_size = 1U << (CPU_CT_xSIZE_LEN(isize) + 3); 914239268Sgonzo if (CPU_CT_xSIZE_ASSOC(isize) == 0) { 915239268Sgonzo if (isize & CPU_CT_xSIZE_M) 916239268Sgonzo arm_picache_line_size = 0; /* not present */ 917239268Sgonzo else 918239268Sgonzo arm_picache_ways = 1; 919239268Sgonzo } else { 920239268Sgonzo arm_picache_ways = multiplier << 921239268Sgonzo (CPU_CT_xSIZE_ASSOC(isize) - 1); 922239268Sgonzo } 923239268Sgonzo arm_picache_size = multiplier << (CPU_CT_xSIZE_SIZE(isize) + 8); 924239268Sgonzo } 925239268Sgonzo 926239268Sgonzo dsize = CPU_CT_DSIZE(ctype); 927239268Sgonzo multiplier = (dsize & CPU_CT_xSIZE_M) ? 3 : 2; 928239268Sgonzo arm_pdcache_line_size = 1U << (CPU_CT_xSIZE_LEN(dsize) + 3); 929239268Sgonzo if (CPU_CT_xSIZE_ASSOC(dsize) == 0) { 930239268Sgonzo if (dsize & CPU_CT_xSIZE_M) 931239268Sgonzo arm_pdcache_line_size = 0; /* not present */ 932129198Scognet else 933239268Sgonzo arm_pdcache_ways = 1; 934129198Scognet } else { 935239268Sgonzo arm_pdcache_ways = multiplier << 936239268Sgonzo (CPU_CT_xSIZE_ASSOC(dsize) - 1); 937129198Scognet } 938239268Sgonzo arm_pdcache_size = multiplier << (CPU_CT_xSIZE_SIZE(dsize) + 8); 939129198Scognet 940239268Sgonzo arm_dcache_align = arm_pdcache_line_size; 941129198Scognet 942239268Sgonzo arm_dcache_l2_assoc = CPU_CT_xSIZE_ASSOC(dsize) + multiplier - 2; 943239268Sgonzo arm_dcache_l2_linesize = CPU_CT_xSIZE_LEN(dsize) + 3; 944239268Sgonzo arm_dcache_l2_nsets = 6 + CPU_CT_xSIZE_SIZE(dsize) - 945239268Sgonzo CPU_CT_xSIZE_ASSOC(dsize) - CPU_CT_xSIZE_LEN(dsize); 946129198Scognet 947239268Sgonzo out: 948239268Sgonzo arm_dcache_align_mask = arm_dcache_align - 1; 949239268Sgonzo } 950129198Scognet} 951266311Sian#endif /* ARM9 || XSCALE */ 952129198Scognet 953129198Scognet/* 954129198Scognet * Cannot panic here as we may not have a console yet ... 955129198Scognet */ 956129198Scognet 957129198Scognetint 958129198Scognetset_cpufuncs() 959129198Scognet{ 960129198Scognet cputype = cpufunc_id(); 961129198Scognet cputype &= CPU_ID_CPU_MASK; 962129198Scognet 963129198Scognet /* 964129198Scognet * NOTE: cpu_do_powersave defaults to off. If we encounter a 965129198Scognet * CPU type where we want to use it by default, then we set it. 966129198Scognet */ 967129198Scognet 968129198Scognet#ifdef CPU_ARM9 969129198Scognet if (((cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_ARM_LTD || 970129198Scognet (cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_TI) && 971129198Scognet (cputype & 0x0000f000) == 0x00009000) { 972129198Scognet cpufuncs = arm9_cpufuncs; 973129198Scognet cpu_reset_needs_v4_MMU_disable = 1; /* V4 or higher */ 974129198Scognet get_cachetype_cp15(); 975146605Scognet arm9_dcache_sets_inc = 1U << arm_dcache_l2_linesize; 976146605Scognet arm9_dcache_sets_max = (1U << (arm_dcache_l2_linesize + 977146605Scognet arm_dcache_l2_nsets)) - arm9_dcache_sets_inc; 978146605Scognet arm9_dcache_index_inc = 1U << (32 - arm_dcache_l2_assoc); 979146605Scognet arm9_dcache_index_max = 0U - arm9_dcache_index_inc; 980137270Scognet#ifdef ARM9_CACHE_WRITE_THROUGH 981129198Scognet pmap_pte_init_arm9(); 982137270Scognet#else 983137270Scognet pmap_pte_init_generic(); 984137270Scognet#endif 985166655Scognet goto out; 986129198Scognet } 987129198Scognet#endif /* CPU_ARM9 */ 988172738Simp#if defined(CPU_ARM9E) || defined(CPU_ARM10) 989239268Sgonzo if (cputype == CPU_ID_MV88FR131 || cputype == CPU_ID_MV88FR571_VD || 990183835Sraj cputype == CPU_ID_MV88FR571_41) { 991239268Sgonzo uint32_t sheeva_ctrl; 992183835Sraj 993239268Sgonzo sheeva_ctrl = (MV_DC_STREAM_ENABLE | MV_BTB_DISABLE | 994239268Sgonzo MV_L2_ENABLE); 995239268Sgonzo /* 996239268Sgonzo * Workaround for Marvell MV78100 CPU: Cache prefetch 997239268Sgonzo * mechanism may affect the cache coherency validity, 998239268Sgonzo * so it needs to be disabled. 999239268Sgonzo * 1000239268Sgonzo * Refer to errata document MV-S501058-00C.pdf (p. 3.1 1001239268Sgonzo * L2 Prefetching Mechanism) for details. 1002239268Sgonzo */ 1003239268Sgonzo if (cputype == CPU_ID_MV88FR571_VD || 1004239268Sgonzo cputype == CPU_ID_MV88FR571_41) 1005239268Sgonzo sheeva_ctrl |= MV_L2_PREFETCH_DISABLE; 1006212825Smav 1007239268Sgonzo sheeva_control_ext(0xffffffff & ~MV_WA_ENABLE, sheeva_ctrl); 1008183835Sraj 1009239268Sgonzo cpufuncs = sheeva_cpufuncs; 1010172738Simp get_cachetype_cp15(); 1011172738Simp pmap_pte_init_generic(); 1012174058Scognet goto out; 1013239268Sgonzo } else if (cputype == CPU_ID_ARM926EJS || cputype == CPU_ID_ARM1026EJS) { 1014239268Sgonzo cpufuncs = armv5_ec_cpufuncs; 1015239268Sgonzo get_cachetype_cp15(); 1016239268Sgonzo pmap_pte_init_generic(); 1017239268Sgonzo goto out; 1018172738Simp } 1019172738Simp#endif /* CPU_ARM9E || CPU_ARM10 */ 1020129198Scognet#ifdef CPU_ARM10 1021129198Scognet if (/* cputype == CPU_ID_ARM1020T || */ 1022129198Scognet cputype == CPU_ID_ARM1020E) { 1023129198Scognet /* 1024129198Scognet * Select write-through cacheing (this isn't really an 1025129198Scognet * option on ARM1020T). 1026129198Scognet */ 1027129198Scognet cpufuncs = arm10_cpufuncs; 1028129198Scognet cpu_reset_needs_v4_MMU_disable = 1; /* V4 or higher */ 1029129198Scognet get_cachetype_cp15(); 1030129198Scognet arm10_dcache_sets_inc = 1U << arm_dcache_l2_linesize; 1031236991Simp arm10_dcache_sets_max = 1032129198Scognet (1U << (arm_dcache_l2_linesize + arm_dcache_l2_nsets)) - 1033129198Scognet arm10_dcache_sets_inc; 1034129198Scognet arm10_dcache_index_inc = 1U << (32 - arm_dcache_l2_assoc); 1035129198Scognet arm10_dcache_index_max = 0U - arm10_dcache_index_inc; 1036129198Scognet pmap_pte_init_generic(); 1037166655Scognet goto out; 1038129198Scognet } 1039129198Scognet#endif /* CPU_ARM10 */ 1040244480Sgonzo#if defined(CPU_ARM1136) || defined(CPU_ARM1176) 1041244480Sgonzo if (cputype == CPU_ID_ARM1136JS 1042244480Sgonzo || cputype == CPU_ID_ARM1136JSR1 1043244480Sgonzo || cputype == CPU_ID_ARM1176JZS) { 1044244480Sgonzo#ifdef CPU_ARM1136 1045244480Sgonzo if (cputype == CPU_ID_ARM1136JS 1046244480Sgonzo || cputype == CPU_ID_ARM1136JSR1) 1047244480Sgonzo cpufuncs = arm1136_cpufuncs; 1048244480Sgonzo#endif 1049244480Sgonzo#ifdef CPU_ARM1176 1050244480Sgonzo if (cputype == CPU_ID_ARM1176JZS) 1051244480Sgonzo cpufuncs = arm1176_cpufuncs; 1052244480Sgonzo#endif 1053244480Sgonzo cpu_reset_needs_v4_MMU_disable = 1; /* V4 or higher */ 1054244480Sgonzo get_cachetype_cp15(); 1055239701Sgonzo 1056244480Sgonzo pmap_pte_init_mmu_v6(); 1057244480Sgonzo 1058244480Sgonzo goto out; 1059244480Sgonzo } 1060244480Sgonzo#endif /* CPU_ARM1136 || CPU_ARM1176 */ 1061266058Sian#if defined(CPU_CORTEXA) || defined(CPU_KRAIT) 1062253857Sganbold if (cputype == CPU_ID_CORTEXA7 || 1063253857Sganbold cputype == CPU_ID_CORTEXA8R1 || 1064239268Sgonzo cputype == CPU_ID_CORTEXA8R2 || 1065239268Sgonzo cputype == CPU_ID_CORTEXA8R3 || 1066239268Sgonzo cputype == CPU_ID_CORTEXA9R1 || 1067249999Swkoszek cputype == CPU_ID_CORTEXA9R2 || 1068252361Sray cputype == CPU_ID_CORTEXA9R3 || 1069266341Sian cputype == CPU_ID_CORTEXA15R0 || 1070266341Sian cputype == CPU_ID_CORTEXA15R1 || 1071266341Sian cputype == CPU_ID_CORTEXA15R2 || 1072266341Sian cputype == CPU_ID_CORTEXA15R3 || 1073266058Sian cputype == CPU_ID_KRAIT ) { 1074239268Sgonzo cpufuncs = cortexa_cpufuncs; 1075239268Sgonzo cpu_reset_needs_v4_MMU_disable = 1; /* V4 or higher */ 1076239268Sgonzo get_cachetype_cp15(); 1077239268Sgonzo 1078239268Sgonzo pmap_pte_init_mmu_v6(); 1079239268Sgonzo /* Use powersave on this CPU. */ 1080239268Sgonzo cpu_do_powersave = 1; 1081239268Sgonzo goto out; 1082239268Sgonzo } 1083239268Sgonzo#endif /* CPU_CORTEXA */ 1084239268Sgonzo 1085239268Sgonzo#if defined(CPU_MV_PJ4B) 1086266046Sian if (cputype == CPU_ID_MV88SV581X_V7 || 1087240486Sgber cputype == CPU_ID_MV88SV584X_V7 || 1088239268Sgonzo cputype == CPU_ID_ARM_88SV581X_V7) { 1089266046Sian cpufuncs = pj4bv7_cpufuncs; 1090239268Sgonzo get_cachetype_cp15(); 1091239268Sgonzo pmap_pte_init_mmu_v6(); 1092239268Sgonzo goto out; 1093239268Sgonzo } 1094239268Sgonzo#endif /* CPU_MV_PJ4B */ 1095129198Scognet 1096207611Skevlo#if defined(CPU_FA526) || defined(CPU_FA626TE) 1097207611Skevlo if (cputype == CPU_ID_FA526 || cputype == CPU_ID_FA626TE) { 1098201468Srpaulo cpufuncs = fa526_cpufuncs; 1099201468Srpaulo cpu_reset_needs_v4_MMU_disable = 1; /* SA needs it */ 1100201468Srpaulo get_cachetype_cp15(); 1101201468Srpaulo pmap_pte_init_generic(); 1102201468Srpaulo 1103201468Srpaulo /* Use powersave on this CPU. */ 1104201468Srpaulo cpu_do_powersave = 1; 1105201468Srpaulo 1106201468Srpaulo goto out; 1107201468Srpaulo } 1108207611Skevlo#endif /* CPU_FA526 || CPU_FA626TE */ 1109266311Sian 1110129198Scognet#ifdef CPU_XSCALE_80200 1111129198Scognet if (cputype == CPU_ID_80200) { 1112129198Scognet int rev = cpufunc_id() & CPU_ID_REVISION_MASK; 1113129198Scognet 1114129198Scognet i80200_icu_init(); 1115129198Scognet 1116129198Scognet#if defined(XSCALE_CCLKCFG) 1117129198Scognet /* 1118129198Scognet * Crank CCLKCFG to maximum legal value. 1119129198Scognet */ 1120129198Scognet __asm __volatile ("mcr p14, 0, %0, c6, c0, 0" 1121129198Scognet : 1122129198Scognet : "r" (XSCALE_CCLKCFG)); 1123129198Scognet#endif 1124129198Scognet 1125129198Scognet /* 1126129198Scognet * XXX Disable ECC in the Bus Controller Unit; we 1127129198Scognet * don't really support it, yet. Clear any pending 1128129198Scognet * error indications. 1129129198Scognet */ 1130129198Scognet __asm __volatile("mcr p13, 0, %0, c0, c1, 0" 1131129198Scognet : 1132129198Scognet : "r" (BCUCTL_E0|BCUCTL_E1|BCUCTL_EV)); 1133129198Scognet 1134129198Scognet cpufuncs = xscale_cpufuncs; 1135129198Scognet /* 1136129198Scognet * i80200 errata: Step-A0 and A1 have a bug where 1137129198Scognet * D$ dirty bits are not cleared on "invalidate by 1138129198Scognet * address". 1139129198Scognet * 1140129198Scognet * Workaround: Clean cache line before invalidating. 1141129198Scognet */ 1142129198Scognet if (rev == 0 || rev == 1) 1143129198Scognet cpufuncs.cf_dcache_inv_range = xscale_cache_purgeD_rng; 1144129198Scognet 1145129198Scognet cpu_reset_needs_v4_MMU_disable = 1; /* XScale needs it */ 1146129198Scognet get_cachetype_cp15(); 1147129198Scognet pmap_pte_init_xscale(); 1148166655Scognet goto out; 1149129198Scognet } 1150129198Scognet#endif /* CPU_XSCALE_80200 */ 1151161592Scognet#if defined(CPU_XSCALE_80321) || defined(CPU_XSCALE_80219) 1152129198Scognet if (cputype == CPU_ID_80321_400 || cputype == CPU_ID_80321_600 || 1153161592Scognet cputype == CPU_ID_80321_400_B0 || cputype == CPU_ID_80321_600_B0 || 1154161592Scognet cputype == CPU_ID_80219_400 || cputype == CPU_ID_80219_600) { 1155129198Scognet cpufuncs = xscale_cpufuncs; 1156129198Scognet cpu_reset_needs_v4_MMU_disable = 1; /* XScale needs it */ 1157129198Scognet get_cachetype_cp15(); 1158129198Scognet pmap_pte_init_xscale(); 1159166655Scognet goto out; 1160129198Scognet } 1161129198Scognet#endif /* CPU_XSCALE_80321 */ 1162161592Scognet 1163164080Scognet#if defined(CPU_XSCALE_81342) 1164164080Scognet if (cputype == CPU_ID_81342) { 1165164080Scognet cpufuncs = xscalec3_cpufuncs; 1166164080Scognet cpu_reset_needs_v4_MMU_disable = 1; /* XScale needs it */ 1167164080Scognet get_cachetype_cp15(); 1168164080Scognet pmap_pte_init_xscale(); 1169166655Scognet goto out; 1170164080Scognet } 1171164080Scognet#endif /* CPU_XSCALE_81342 */ 1172129198Scognet#ifdef CPU_XSCALE_PXA2X0 1173129198Scognet /* ignore core revision to test PXA2xx CPUs */ 1174129198Scognet if ((cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA250 || 1175191817Sstas (cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA27X || 1176129198Scognet (cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA210) { 1177129198Scognet 1178129198Scognet cpufuncs = xscale_cpufuncs; 1179129198Scognet cpu_reset_needs_v4_MMU_disable = 1; /* XScale needs it */ 1180129198Scognet get_cachetype_cp15(); 1181129198Scognet pmap_pte_init_xscale(); 1182129198Scognet 1183129198Scognet /* Use powersave on this CPU. */ 1184129198Scognet cpu_do_powersave = 1; 1185129198Scognet 1186166655Scognet goto out; 1187129198Scognet } 1188129198Scognet#endif /* CPU_XSCALE_PXA2X0 */ 1189129198Scognet#ifdef CPU_XSCALE_IXP425 1190129198Scognet if (cputype == CPU_ID_IXP425_533 || cputype == CPU_ID_IXP425_400 || 1191186352Ssam cputype == CPU_ID_IXP425_266 || cputype == CPU_ID_IXP435) { 1192129198Scognet 1193129198Scognet cpufuncs = xscale_cpufuncs; 1194129198Scognet cpu_reset_needs_v4_MMU_disable = 1; /* XScale needs it */ 1195129198Scognet get_cachetype_cp15(); 1196129198Scognet pmap_pte_init_xscale(); 1197129198Scognet 1198166655Scognet goto out; 1199129198Scognet } 1200129198Scognet#endif /* CPU_XSCALE_IXP425 */ 1201129198Scognet /* 1202129198Scognet * Bzzzz. And the answer was ... 1203129198Scognet */ 1204129198Scognet panic("No support for this CPU type (%08x) in kernel", cputype); 1205129198Scognet return(ARCHITECTURE_NOT_PRESENT); 1206166655Scognetout: 1207166655Scognet uma_set_align(arm_dcache_align_mask); 1208166655Scognet return (0); 1209129198Scognet} 1210129198Scognet 1211129198Scognet/* 1212129198Scognet * Fixup routines for data and prefetch aborts. 1213129198Scognet * 1214129198Scognet * Several compile time symbols are used 1215129198Scognet * 1216129198Scognet * DEBUG_FAULT_CORRECTION - Print debugging information during the 1217129198Scognet * correction of registers after a fault. 1218129198Scognet */ 1219129198Scognet 1220129198Scognet 1221129198Scognet/* 1222129198Scognet * Null abort fixup routine. 1223129198Scognet * For use when no fixup is required. 1224129198Scognet */ 1225129198Scognetint 1226129198Scognetcpufunc_null_fixup(arg) 1227129198Scognet void *arg; 1228129198Scognet{ 1229129198Scognet return(ABORT_FIXUP_OK); 1230129198Scognet} 1231129198Scognet 1232129198Scognet/* 1233129198Scognet * CPU Setup code 1234129198Scognet */ 1235129198Scognet 1236266311Sian#if defined (CPU_ARM9) || \ 1237172738Simp defined(CPU_ARM9E) || \ 1238161592Scognet defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \ 1239161592Scognet defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \ 1240172738Simp defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342) || \ 1241244480Sgonzo defined(CPU_ARM10) || defined(CPU_ARM1136) || defined(CPU_ARM1176) ||\ 1242207611Skevlo defined(CPU_FA526) || defined(CPU_FA626TE) 1243129198Scognet 1244129198Scognet#define IGN 0 1245129198Scognet#define OR 1 1246129198Scognet#define BIC 2 1247129198Scognet 1248129198Scognetstruct cpu_option { 1249129198Scognet char *co_name; 1250129198Scognet int co_falseop; 1251129198Scognet int co_trueop; 1252129198Scognet int co_value; 1253129198Scognet}; 1254129198Scognet 1255137498Strhodesstatic u_int parse_cpu_options(char *, struct cpu_option *, u_int); 1256129198Scognet 1257129198Scognetstatic u_int 1258129198Scognetparse_cpu_options(args, optlist, cpuctrl) 1259129198Scognet char *args; 1260236991Simp struct cpu_option *optlist; 1261236991Simp u_int cpuctrl; 1262129198Scognet{ 1263129198Scognet int integer; 1264129198Scognet 1265129198Scognet if (args == NULL) 1266129198Scognet return(cpuctrl); 1267129198Scognet 1268129198Scognet while (optlist->co_name) { 1269129198Scognet if (get_bootconf_option(args, optlist->co_name, 1270129198Scognet BOOTOPT_TYPE_BOOLEAN, &integer)) { 1271129198Scognet if (integer) { 1272129198Scognet if (optlist->co_trueop == OR) 1273129198Scognet cpuctrl |= optlist->co_value; 1274129198Scognet else if (optlist->co_trueop == BIC) 1275129198Scognet cpuctrl &= ~optlist->co_value; 1276129198Scognet } else { 1277129198Scognet if (optlist->co_falseop == OR) 1278129198Scognet cpuctrl |= optlist->co_value; 1279129198Scognet else if (optlist->co_falseop == BIC) 1280129198Scognet cpuctrl &= ~optlist->co_value; 1281129198Scognet } 1282129198Scognet } 1283129198Scognet ++optlist; 1284129198Scognet } 1285129198Scognet return(cpuctrl); 1286129198Scognet} 1287266311Sian#endif /* CPU_ARM9 || XSCALE*/ 1288129198Scognet 1289129198Scognet#ifdef CPU_ARM9 1290129198Scognetstruct cpu_option arm9_options[] = { 1291129198Scognet { "cpu.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 1292129198Scognet { "cpu.nocache", OR, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 1293129198Scognet { "arm9.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 1294129198Scognet { "arm9.icache", BIC, OR, CPU_CONTROL_IC_ENABLE }, 1295129198Scognet { "arm9.dcache", BIC, OR, CPU_CONTROL_DC_ENABLE }, 1296129198Scognet { "cpu.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 1297129198Scognet { "cpu.nowritebuf", OR, BIC, CPU_CONTROL_WBUF_ENABLE }, 1298129198Scognet { "arm9.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 1299129198Scognet { NULL, IGN, IGN, 0 } 1300129198Scognet}; 1301129198Scognet 1302129198Scognetvoid 1303129198Scognetarm9_setup(args) 1304129198Scognet char *args; 1305129198Scognet{ 1306129198Scognet int cpuctrl, cpuctrlmask; 1307129198Scognet 1308129198Scognet cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 1309129198Scognet | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 1310129198Scognet | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 1311157618Scognet | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE | 1312157618Scognet CPU_CONTROL_ROUNDROBIN; 1313129198Scognet cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 1314129198Scognet | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 1315129198Scognet | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 1316129198Scognet | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE 1317129198Scognet | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE 1318146605Scognet | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_VECRELOC 1319146605Scognet | CPU_CONTROL_ROUNDROBIN; 1320129198Scognet 1321129198Scognet#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 1322129198Scognet cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 1323129198Scognet#endif 1324129198Scognet 1325129198Scognet cpuctrl = parse_cpu_options(args, arm9_options, cpuctrl); 1326129198Scognet 1327129198Scognet#ifdef __ARMEB__ 1328129198Scognet cpuctrl |= CPU_CONTROL_BEND_ENABLE; 1329129198Scognet#endif 1330142050Scognet if (vector_page == ARM_VECTORS_HIGH) 1331142050Scognet cpuctrl |= CPU_CONTROL_VECRELOC; 1332129198Scognet 1333129198Scognet /* Clear out the cache */ 1334129198Scognet cpu_idcache_wbinv_all(); 1335129198Scognet 1336129198Scognet /* Set the control register */ 1337146605Scognet cpu_control(cpuctrlmask, cpuctrl); 1338129198Scognet ctrl = cpuctrl; 1339129198Scognet 1340129198Scognet} 1341129198Scognet#endif /* CPU_ARM9 */ 1342129198Scognet 1343172738Simp#if defined(CPU_ARM9E) || defined(CPU_ARM10) 1344129198Scognetstruct cpu_option arm10_options[] = { 1345129198Scognet { "cpu.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 1346129198Scognet { "cpu.nocache", OR, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 1347129198Scognet { "arm10.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 1348129198Scognet { "arm10.icache", BIC, OR, CPU_CONTROL_IC_ENABLE }, 1349129198Scognet { "arm10.dcache", BIC, OR, CPU_CONTROL_DC_ENABLE }, 1350129198Scognet { "cpu.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 1351129198Scognet { "cpu.nowritebuf", OR, BIC, CPU_CONTROL_WBUF_ENABLE }, 1352129198Scognet { "arm10.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 1353129198Scognet { NULL, IGN, IGN, 0 } 1354129198Scognet}; 1355129198Scognet 1356129198Scognetvoid 1357129198Scognetarm10_setup(args) 1358129198Scognet char *args; 1359129198Scognet{ 1360129198Scognet int cpuctrl, cpuctrlmask; 1361129198Scognet 1362129198Scognet cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_SYST_ENABLE 1363236991Simp | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 1364129198Scognet | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_BPRD_ENABLE; 1365129198Scognet cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_SYST_ENABLE 1366129198Scognet | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 1367129198Scognet | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE 1368129198Scognet | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE 1369129198Scognet | CPU_CONTROL_BPRD_ENABLE 1370129198Scognet | CPU_CONTROL_ROUNDROBIN | CPU_CONTROL_CPCLK; 1371129198Scognet 1372129198Scognet#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 1373129198Scognet cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 1374129198Scognet#endif 1375129198Scognet 1376129198Scognet cpuctrl = parse_cpu_options(args, arm10_options, cpuctrl); 1377129198Scognet 1378129198Scognet#ifdef __ARMEB__ 1379129198Scognet cpuctrl |= CPU_CONTROL_BEND_ENABLE; 1380129198Scognet#endif 1381129198Scognet 1382129198Scognet /* Clear out the cache */ 1383129198Scognet cpu_idcache_wbinv_all(); 1384129198Scognet 1385129198Scognet /* Now really make sure they are clean. */ 1386172738Simp __asm __volatile ("mcr\tp15, 0, r0, c7, c7, 0" : : ); 1387129198Scognet 1388174058Scognet if (vector_page == ARM_VECTORS_HIGH) 1389174058Scognet cpuctrl |= CPU_CONTROL_VECRELOC; 1390174058Scognet 1391129198Scognet /* Set the control register */ 1392129198Scognet ctrl = cpuctrl; 1393129198Scognet cpu_control(0xffffffff, cpuctrl); 1394129198Scognet 1395129198Scognet /* And again. */ 1396129198Scognet cpu_idcache_wbinv_all(); 1397129198Scognet} 1398172738Simp#endif /* CPU_ARM9E || CPU_ARM10 */ 1399129198Scognet 1400244480Sgonzo#if defined(CPU_ARM1136) || defined(CPU_ARM1176) 1401172738Simpstruct cpu_option arm11_options[] = { 1402172738Simp { "cpu.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 1403172738Simp { "cpu.nocache", OR, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 1404172738Simp { "arm11.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 1405172738Simp { "arm11.icache", BIC, OR, CPU_CONTROL_IC_ENABLE }, 1406172738Simp { "arm11.dcache", BIC, OR, CPU_CONTROL_DC_ENABLE }, 1407172738Simp { NULL, IGN, IGN, 0 } 1408172738Simp}; 1409172738Simp 1410172738Simpvoid 1411244480Sgonzoarm11x6_setup(char *args) 1412172738Simp{ 1413244480Sgonzo int cpuctrl, cpuctrl_wax; 1414244480Sgonzo uint32_t auxctrl, auxctrl_wax; 1415244480Sgonzo uint32_t tmp, tmp2; 1416244480Sgonzo uint32_t sbz=0; 1417244480Sgonzo uint32_t cpuid; 1418172738Simp 1419244480Sgonzo cpuid = cpufunc_id(); 1420244480Sgonzo 1421244480Sgonzo cpuctrl = 1422244480Sgonzo CPU_CONTROL_MMU_ENABLE | 1423244480Sgonzo CPU_CONTROL_DC_ENABLE | 1424244480Sgonzo CPU_CONTROL_WBUF_ENABLE | 1425244480Sgonzo CPU_CONTROL_32BP_ENABLE | 1426244480Sgonzo CPU_CONTROL_32BD_ENABLE | 1427244480Sgonzo CPU_CONTROL_LABT_ENABLE | 1428244480Sgonzo CPU_CONTROL_SYST_ENABLE | 1429244480Sgonzo CPU_CONTROL_IC_ENABLE; 1430244480Sgonzo 1431244480Sgonzo /* 1432244480Sgonzo * "write as existing" bits 1433244480Sgonzo * inverse of this is mask 1434244480Sgonzo */ 1435244480Sgonzo cpuctrl_wax = 1436244480Sgonzo (3 << 30) | /* SBZ */ 1437244480Sgonzo (1 << 29) | /* FA */ 1438244480Sgonzo (1 << 28) | /* TR */ 1439244480Sgonzo (3 << 26) | /* SBZ */ 1440244480Sgonzo (3 << 19) | /* SBZ */ 1441244480Sgonzo (1 << 17); /* SBZ */ 1442244480Sgonzo 1443244480Sgonzo cpuctrl |= CPU_CONTROL_BPRD_ENABLE; 1444244480Sgonzo cpuctrl |= CPU_CONTROL_V6_EXTPAGE; 1445244480Sgonzo 1446172738Simp cpuctrl = parse_cpu_options(args, arm11_options, cpuctrl); 1447244480Sgonzo 1448172738Simp#ifdef __ARMEB__ 1449172738Simp cpuctrl |= CPU_CONTROL_BEND_ENABLE; 1450172738Simp#endif 1451244480Sgonzo 1452239701Sgonzo if (vector_page == ARM_VECTORS_HIGH) 1453239701Sgonzo cpuctrl |= CPU_CONTROL_VECRELOC; 1454172738Simp 1455244480Sgonzo auxctrl = 0; 1456244480Sgonzo auxctrl_wax = ~0; 1457244480Sgonzo /* 1458244480Sgonzo * This options enables the workaround for the 364296 ARM1136 1459244480Sgonzo * r0pX errata (possible cache data corruption with 1460244480Sgonzo * hit-under-miss enabled). It sets the undocumented bit 31 in 1461244480Sgonzo * the auxiliary control register and the FI bit in the control 1462244480Sgonzo * register, thus disabling hit-under-miss without putting the 1463244480Sgonzo * processor into full low interrupt latency mode. ARM11MPCore 1464244480Sgonzo * is not affected. 1465244480Sgonzo */ 1466244480Sgonzo if ((cpuid & CPU_ID_CPU_MASK) == CPU_ID_ARM1136JS) { /* ARM1136JSr0pX */ 1467244480Sgonzo cpuctrl |= CPU_CONTROL_FI_ENABLE; 1468244480Sgonzo auxctrl = ARM1136_AUXCTL_PFI; 1469244480Sgonzo auxctrl_wax = ~ARM1136_AUXCTL_PFI; 1470244480Sgonzo } 1471244480Sgonzo 1472244480Sgonzo /* 1473244480Sgonzo * Enable an errata workaround 1474244480Sgonzo */ 1475244480Sgonzo if ((cpuid & CPU_ID_CPU_MASK) == CPU_ID_ARM1176JZS) { /* ARM1176JZSr0 */ 1476244480Sgonzo auxctrl = ARM1176_AUXCTL_PHD; 1477244480Sgonzo auxctrl_wax = ~ARM1176_AUXCTL_PHD; 1478244480Sgonzo } 1479244480Sgonzo 1480244480Sgonzo /* Clear out the cache */ 1481172738Simp cpu_idcache_wbinv_all(); 1482172738Simp 1483244480Sgonzo /* Now really make sure they are clean. */ 1484244480Sgonzo __asm volatile ("mcr\tp15, 0, %0, c7, c7, 0" : : "r"(sbz)); 1485244480Sgonzo 1486244480Sgonzo /* Allow detection code to find the VFP if it's fitted. */ 1487244480Sgonzo __asm volatile ("mcr\tp15, 0, %0, c1, c0, 2" : : "r" (0x0fffffff)); 1488244480Sgonzo 1489172738Simp /* Set the control register */ 1490239701Sgonzo ctrl = cpuctrl; 1491244480Sgonzo cpu_control(~cpuctrl_wax, cpuctrl); 1492172738Simp 1493244480Sgonzo __asm volatile ("mrc p15, 0, %0, c1, c0, 1\n\t" 1494244480Sgonzo "and %1, %0, %2\n\t" 1495244480Sgonzo "orr %1, %1, %3\n\t" 1496244480Sgonzo "teq %0, %1\n\t" 1497244480Sgonzo "mcrne p15, 0, %1, c1, c0, 1\n\t" 1498244480Sgonzo : "=r"(tmp), "=r"(tmp2) : 1499244480Sgonzo "r"(auxctrl_wax), "r"(auxctrl)); 1500244480Sgonzo 1501244480Sgonzo /* And again. */ 1502172738Simp cpu_idcache_wbinv_all(); 1503172738Simp} 1504244480Sgonzo#endif /* CPU_ARM1136 || CPU_ARM1176 */ 1505172738Simp 1506239268Sgonzo#ifdef CPU_MV_PJ4B 1507239268Sgonzovoid 1508239268Sgonzopj4bv7_setup(args) 1509239268Sgonzo char *args; 1510239268Sgonzo{ 1511239268Sgonzo int cpuctrl; 1512239268Sgonzo 1513239268Sgonzo pj4b_config(); 1514239268Sgonzo 1515239268Sgonzo cpuctrl = CPU_CONTROL_MMU_ENABLE; 1516239268Sgonzo#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 1517239268Sgonzo cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 1518239268Sgonzo#endif 1519239268Sgonzo cpuctrl |= CPU_CONTROL_DC_ENABLE; 1520239268Sgonzo cpuctrl |= (0xf << 3); 1521239268Sgonzo cpuctrl |= CPU_CONTROL_BPRD_ENABLE; 1522239268Sgonzo cpuctrl |= CPU_CONTROL_IC_ENABLE; 1523239268Sgonzo if (vector_page == ARM_VECTORS_HIGH) 1524239268Sgonzo cpuctrl |= CPU_CONTROL_VECRELOC; 1525239268Sgonzo cpuctrl |= (0x5 << 16) | (1 < 22); 1526239268Sgonzo cpuctrl |= CPU_CONTROL_V6_EXTPAGE; 1527239268Sgonzo 1528239268Sgonzo /* Clear out the cache */ 1529239268Sgonzo cpu_idcache_wbinv_all(); 1530239268Sgonzo 1531239268Sgonzo /* Set the control register */ 1532239268Sgonzo ctrl = cpuctrl; 1533239268Sgonzo cpu_control(0xFFFFFFFF, cpuctrl); 1534239268Sgonzo 1535239268Sgonzo /* And again. */ 1536239268Sgonzo cpu_idcache_wbinv_all(); 1537239268Sgonzo} 1538239268Sgonzo#endif /* CPU_MV_PJ4B */ 1539239268Sgonzo 1540266058Sian#if defined(CPU_CORTEXA) || defined(CPU_KRAIT) 1541239268Sgonzo 1542239268Sgonzovoid 1543239268Sgonzocortexa_setup(char *args) 1544239268Sgonzo{ 1545239268Sgonzo int cpuctrl, cpuctrlmask; 1546239268Sgonzo 1547239268Sgonzo cpuctrlmask = CPU_CONTROL_MMU_ENABLE | /* MMU enable [0] */ 1548239268Sgonzo CPU_CONTROL_AFLT_ENABLE | /* Alignment fault [1] */ 1549239268Sgonzo CPU_CONTROL_DC_ENABLE | /* DCache enable [2] */ 1550239268Sgonzo CPU_CONTROL_BPRD_ENABLE | /* Branch prediction [11] */ 1551239268Sgonzo CPU_CONTROL_IC_ENABLE | /* ICache enable [12] */ 1552239268Sgonzo CPU_CONTROL_VECRELOC; /* Vector relocation [13] */ 1553239268Sgonzo 1554239268Sgonzo cpuctrl = CPU_CONTROL_MMU_ENABLE | 1555239268Sgonzo CPU_CONTROL_IC_ENABLE | 1556239268Sgonzo CPU_CONTROL_DC_ENABLE | 1557239268Sgonzo CPU_CONTROL_BPRD_ENABLE; 1558239268Sgonzo 1559239268Sgonzo#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 1560239268Sgonzo cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 1561239268Sgonzo#endif 1562239268Sgonzo 1563239268Sgonzo /* Switch to big endian */ 1564239268Sgonzo#ifdef __ARMEB__ 1565239268Sgonzo cpuctrl |= CPU_CONTROL_BEND_ENABLE; 1566239268Sgonzo#endif 1567239268Sgonzo 1568239268Sgonzo /* Check if the vector page is at the high address (0xffff0000) */ 1569239268Sgonzo if (vector_page == ARM_VECTORS_HIGH) 1570239268Sgonzo cpuctrl |= CPU_CONTROL_VECRELOC; 1571239268Sgonzo 1572239268Sgonzo /* Clear out the cache */ 1573239268Sgonzo cpu_idcache_wbinv_all(); 1574239268Sgonzo 1575239268Sgonzo /* Set the control register */ 1576239268Sgonzo ctrl = cpuctrl; 1577239268Sgonzo cpu_control(cpuctrlmask, cpuctrl); 1578239268Sgonzo 1579239268Sgonzo /* And again. */ 1580239268Sgonzo cpu_idcache_wbinv_all(); 1581239268Sgonzo#ifdef SMP 1582239268Sgonzo armv7_auxctrl((1 << 6) | (1 << 0), (1 << 6) | (1 << 0)); /* Enable SMP + TLB broadcasting */ 1583239268Sgonzo#endif 1584239268Sgonzo} 1585239268Sgonzo#endif /* CPU_CORTEXA */ 1586239268Sgonzo 1587207611Skevlo#if defined(CPU_FA526) || defined(CPU_FA626TE) 1588201468Srpaulostruct cpu_option fa526_options[] = { 1589201468Srpaulo#ifdef COMPAT_12 1590201468Srpaulo { "nocache", IGN, BIC, (CPU_CONTROL_IC_ENABLE | 1591201468Srpaulo CPU_CONTROL_DC_ENABLE) }, 1592201468Srpaulo { "nowritebuf", IGN, BIC, CPU_CONTROL_WBUF_ENABLE }, 1593201468Srpaulo#endif /* COMPAT_12 */ 1594201468Srpaulo { "cpu.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | 1595201468Srpaulo CPU_CONTROL_DC_ENABLE) }, 1596201468Srpaulo { "cpu.nocache", OR, BIC, (CPU_CONTROL_IC_ENABLE | 1597201468Srpaulo CPU_CONTROL_DC_ENABLE) }, 1598201468Srpaulo { "cpu.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 1599201468Srpaulo { "cpu.nowritebuf", OR, BIC, CPU_CONTROL_WBUF_ENABLE }, 1600201468Srpaulo { NULL, IGN, IGN, 0 } 1601201468Srpaulo}; 1602201468Srpaulo 1603201468Srpaulovoid 1604201468Srpaulofa526_setup(char *args) 1605201468Srpaulo{ 1606201468Srpaulo int cpuctrl, cpuctrlmask; 1607201468Srpaulo 1608201468Srpaulo cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 1609201468Srpaulo | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 1610201468Srpaulo | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 1611204122Skevlo | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE 1612204122Skevlo | CPU_CONTROL_BPRD_ENABLE; 1613201468Srpaulo cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 1614201468Srpaulo | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 1615201468Srpaulo | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 1616201468Srpaulo | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE 1617201468Srpaulo | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE 1618201468Srpaulo | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_BPRD_ENABLE 1619201468Srpaulo | CPU_CONTROL_CPCLK | CPU_CONTROL_VECRELOC; 1620201468Srpaulo 1621201468Srpaulo#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 1622201468Srpaulo cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 1623201468Srpaulo#endif 1624201468Srpaulo 1625201468Srpaulo cpuctrl = parse_cpu_options(args, fa526_options, cpuctrl); 1626201468Srpaulo 1627201468Srpaulo#ifdef __ARMEB__ 1628201468Srpaulo cpuctrl |= CPU_CONTROL_BEND_ENABLE; 1629201468Srpaulo#endif 1630201468Srpaulo 1631201468Srpaulo if (vector_page == ARM_VECTORS_HIGH) 1632201468Srpaulo cpuctrl |= CPU_CONTROL_VECRELOC; 1633201468Srpaulo 1634201468Srpaulo /* Clear out the cache */ 1635201468Srpaulo cpu_idcache_wbinv_all(); 1636201468Srpaulo 1637201468Srpaulo /* Set the control register */ 1638201468Srpaulo ctrl = cpuctrl; 1639201468Srpaulo cpu_control(0xffffffff, cpuctrl); 1640201468Srpaulo} 1641207611Skevlo#endif /* CPU_FA526 || CPU_FA626TE */ 1642201468Srpaulo 1643129198Scognet#if defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \ 1644161592Scognet defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \ 1645164080Scognet defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342) 1646129198Scognetstruct cpu_option xscale_options[] = { 1647129198Scognet#ifdef COMPAT_12 1648129198Scognet { "branchpredict", BIC, OR, CPU_CONTROL_BPRD_ENABLE }, 1649129198Scognet { "nocache", IGN, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 1650129198Scognet#endif /* COMPAT_12 */ 1651129198Scognet { "cpu.branchpredict", BIC, OR, CPU_CONTROL_BPRD_ENABLE }, 1652129198Scognet { "cpu.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 1653129198Scognet { "cpu.nocache", OR, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 1654129198Scognet { "xscale.branchpredict", BIC, OR, CPU_CONTROL_BPRD_ENABLE }, 1655129198Scognet { "xscale.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 1656129198Scognet { "xscale.icache", BIC, OR, CPU_CONTROL_IC_ENABLE }, 1657129198Scognet { "xscale.dcache", BIC, OR, CPU_CONTROL_DC_ENABLE }, 1658129198Scognet { NULL, IGN, IGN, 0 } 1659129198Scognet}; 1660129198Scognet 1661129198Scognetvoid 1662129198Scognetxscale_setup(args) 1663129198Scognet char *args; 1664129198Scognet{ 1665129198Scognet uint32_t auxctl; 1666129198Scognet int cpuctrl, cpuctrlmask; 1667129198Scognet 1668129198Scognet /* 1669129198Scognet * The XScale Write Buffer is always enabled. Our option 1670129198Scognet * is to enable/disable coalescing. Note that bits 6:3 1671129198Scognet * must always be enabled. 1672129198Scognet */ 1673129198Scognet 1674129198Scognet cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 1675129198Scognet | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 1676129198Scognet | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 1677129198Scognet | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE 1678129198Scognet | CPU_CONTROL_BPRD_ENABLE; 1679129198Scognet cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 1680129198Scognet | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 1681129198Scognet | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 1682129198Scognet | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE 1683129198Scognet | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE 1684129198Scognet | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_BPRD_ENABLE 1685171618Scognet | CPU_CONTROL_CPCLK | CPU_CONTROL_VECRELOC | \ 1686171618Scognet CPU_CONTROL_L2_ENABLE; 1687129198Scognet 1688129198Scognet#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 1689129198Scognet cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 1690129198Scognet#endif 1691129198Scognet 1692129198Scognet cpuctrl = parse_cpu_options(args, xscale_options, cpuctrl); 1693129198Scognet 1694129198Scognet#ifdef __ARMEB__ 1695129198Scognet cpuctrl |= CPU_CONTROL_BEND_ENABLE; 1696129198Scognet#endif 1697129198Scognet 1698129198Scognet if (vector_page == ARM_VECTORS_HIGH) 1699129198Scognet cpuctrl |= CPU_CONTROL_VECRELOC; 1700171618Scognet#ifdef CPU_XSCALE_CORE3 1701171618Scognet cpuctrl |= CPU_CONTROL_L2_ENABLE; 1702171618Scognet#endif 1703129198Scognet 1704129198Scognet /* Clear out the cache */ 1705129198Scognet cpu_idcache_wbinv_all(); 1706129198Scognet 1707129198Scognet /* 1708129198Scognet * Set the control register. Note that bits 6:3 must always 1709129198Scognet * be set to 1. 1710129198Scognet */ 1711129198Scognet ctrl = cpuctrl; 1712129198Scognet/* cpu_control(cpuctrlmask, cpuctrl);*/ 1713129198Scognet cpu_control(0xffffffff, cpuctrl); 1714129198Scognet 1715129198Scognet /* Make sure write coalescing is turned on */ 1716129198Scognet __asm __volatile("mrc p15, 0, %0, c1, c0, 1" 1717129198Scognet : "=r" (auxctl)); 1718129198Scognet#ifdef XSCALE_NO_COALESCE_WRITES 1719129198Scognet auxctl |= XSCALE_AUXCTL_K; 1720129198Scognet#else 1721129198Scognet auxctl &= ~XSCALE_AUXCTL_K; 1722129198Scognet#endif 1723171618Scognet#ifdef CPU_XSCALE_CORE3 1724171618Scognet auxctl |= XSCALE_AUXCTL_LLR; 1725171618Scognet auxctl |= XSCALE_AUXCTL_MD_MASK; 1726171618Scognet#endif 1727129198Scognet __asm __volatile("mcr p15, 0, %0, c1, c0, 1" 1728129198Scognet : : "r" (auxctl)); 1729129198Scognet} 1730236991Simp#endif /* CPU_XSCALE_80200 || CPU_XSCALE_80321 || CPU_XSCALE_PXA2X0 || CPU_XSCALE_IXP425 1731161592Scognet CPU_XSCALE_80219 */ 1732