cpufunc.c revision 283366
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 283366 2015-05-24 12:20:11Z andrew $"); 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_id, /* id */ 109129198Scognet cpufunc_nullop, /* cpwait */ 110129198Scognet 111129198Scognet /* MMU functions */ 112129198Scognet 113129198Scognet cpufunc_control, /* control */ 114129198Scognet cpufunc_domains, /* Domain */ 115129198Scognet arm9_setttb, /* Setttb */ 116129198Scognet cpufunc_faultstatus, /* Faultstatus */ 117129198Scognet cpufunc_faultaddress, /* Faultaddress */ 118129198Scognet 119129198Scognet /* TLB functions */ 120129198Scognet 121129198Scognet armv4_tlb_flushID, /* tlb_flushID */ 122129198Scognet arm9_tlb_flushID_SE, /* tlb_flushID_SE */ 123129198Scognet armv4_tlb_flushI, /* tlb_flushI */ 124129198Scognet (void *)armv4_tlb_flushI, /* tlb_flushI_SE */ 125129198Scognet armv4_tlb_flushD, /* tlb_flushD */ 126129198Scognet armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 127129198Scognet 128129198Scognet /* Cache operations */ 129129198Scognet 130146605Scognet arm9_icache_sync_all, /* icache_sync_all */ 131146605Scognet arm9_icache_sync_range, /* icache_sync_range */ 132129198Scognet 133146605Scognet arm9_dcache_wbinv_all, /* dcache_wbinv_all */ 134146605Scognet arm9_dcache_wbinv_range, /* dcache_wbinv_range */ 135195798Sraj arm9_dcache_inv_range, /* dcache_inv_range */ 136146605Scognet arm9_dcache_wb_range, /* dcache_wb_range */ 137129198Scognet 138262420Sian armv4_idcache_inv_all, /* idcache_inv_all */ 139146605Scognet arm9_idcache_wbinv_all, /* idcache_wbinv_all */ 140146605Scognet arm9_idcache_wbinv_range, /* idcache_wbinv_range */ 141171618Scognet cpufunc_nullop, /* l2cache_wbinv_all */ 142171781Scognet (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 143171781Scognet (void *)cpufunc_nullop, /* l2cache_inv_range */ 144171781Scognet (void *)cpufunc_nullop, /* l2cache_wb_range */ 145265870Sian (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ 146129198Scognet 147129198Scognet /* Other functions */ 148129198Scognet 149129198Scognet cpufunc_nullop, /* flush_prefetchbuf */ 150129198Scognet armv4_drain_writebuf, /* drain_writebuf */ 151129198Scognet cpufunc_nullop, /* flush_brnchtgt_C */ 152129198Scognet (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 153129198Scognet 154129198Scognet (void *)cpufunc_nullop, /* sleep */ 155129198Scognet 156129198Scognet /* Soft functions */ 157129198Scognet 158129198Scognet cpufunc_null_fixup, /* dataabt_fixup */ 159129198Scognet cpufunc_null_fixup, /* prefetchabt_fixup */ 160129198Scognet 161129198Scognet arm9_context_switch, /* context_switch */ 162129198Scognet 163129198Scognet arm9_setup /* cpu setup */ 164129198Scognet 165129198Scognet}; 166129198Scognet#endif /* CPU_ARM9 */ 167129198Scognet 168280809Sandrew#if defined(CPU_ARM9E) 169172738Simpstruct cpu_functions armv5_ec_cpufuncs = { 170172738Simp /* CPU functions */ 171172738Simp 172172738Simp cpufunc_id, /* id */ 173172738Simp cpufunc_nullop, /* cpwait */ 174172738Simp 175172738Simp /* MMU functions */ 176172738Simp 177172738Simp cpufunc_control, /* control */ 178172738Simp cpufunc_domains, /* Domain */ 179172738Simp armv5_ec_setttb, /* Setttb */ 180172738Simp cpufunc_faultstatus, /* Faultstatus */ 181172738Simp cpufunc_faultaddress, /* Faultaddress */ 182172738Simp 183172738Simp /* TLB functions */ 184172738Simp 185172738Simp armv4_tlb_flushID, /* tlb_flushID */ 186172738Simp arm10_tlb_flushID_SE, /* tlb_flushID_SE */ 187172738Simp armv4_tlb_flushI, /* tlb_flushI */ 188172738Simp arm10_tlb_flushI_SE, /* tlb_flushI_SE */ 189172738Simp armv4_tlb_flushD, /* tlb_flushD */ 190172738Simp armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 191172738Simp 192172738Simp /* Cache operations */ 193172738Simp 194172738Simp armv5_ec_icache_sync_all, /* icache_sync_all */ 195172738Simp armv5_ec_icache_sync_range, /* icache_sync_range */ 196172738Simp 197172738Simp armv5_ec_dcache_wbinv_all, /* dcache_wbinv_all */ 198172738Simp armv5_ec_dcache_wbinv_range, /* dcache_wbinv_range */ 199195798Sraj armv5_ec_dcache_inv_range, /* dcache_inv_range */ 200172738Simp armv5_ec_dcache_wb_range, /* dcache_wb_range */ 201172738Simp 202262420Sian armv4_idcache_inv_all, /* idcache_inv_all */ 203172738Simp armv5_ec_idcache_wbinv_all, /* idcache_wbinv_all */ 204172738Simp armv5_ec_idcache_wbinv_range, /* idcache_wbinv_range */ 205172738Simp 206173442Scognet cpufunc_nullop, /* l2cache_wbinv_all */ 207173442Scognet (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 208173442Scognet (void *)cpufunc_nullop, /* l2cache_inv_range */ 209173442Scognet (void *)cpufunc_nullop, /* l2cache_wb_range */ 210265870Sian (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ 211236991Simp 212172738Simp /* Other functions */ 213172738Simp 214172738Simp cpufunc_nullop, /* flush_prefetchbuf */ 215172738Simp armv4_drain_writebuf, /* drain_writebuf */ 216172738Simp cpufunc_nullop, /* flush_brnchtgt_C */ 217172738Simp (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 218172738Simp 219172738Simp (void *)cpufunc_nullop, /* sleep */ 220172738Simp 221172738Simp /* Soft functions */ 222172738Simp 223172738Simp cpufunc_null_fixup, /* dataabt_fixup */ 224172738Simp cpufunc_null_fixup, /* prefetchabt_fixup */ 225172738Simp 226172738Simp arm10_context_switch, /* context_switch */ 227172738Simp 228172738Simp arm10_setup /* cpu setup */ 229172738Simp 230172738Simp}; 231183835Sraj 232186933Srajstruct cpu_functions sheeva_cpufuncs = { 233183835Sraj /* CPU functions */ 234183835Sraj 235183835Sraj cpufunc_id, /* id */ 236183835Sraj cpufunc_nullop, /* cpwait */ 237183835Sraj 238183835Sraj /* MMU functions */ 239183835Sraj 240183835Sraj cpufunc_control, /* control */ 241183835Sraj cpufunc_domains, /* Domain */ 242186933Sraj sheeva_setttb, /* Setttb */ 243183835Sraj cpufunc_faultstatus, /* Faultstatus */ 244183835Sraj cpufunc_faultaddress, /* Faultaddress */ 245183835Sraj 246183835Sraj /* TLB functions */ 247183835Sraj 248183835Sraj armv4_tlb_flushID, /* tlb_flushID */ 249183835Sraj arm10_tlb_flushID_SE, /* tlb_flushID_SE */ 250183835Sraj armv4_tlb_flushI, /* tlb_flushI */ 251183835Sraj arm10_tlb_flushI_SE, /* tlb_flushI_SE */ 252183835Sraj armv4_tlb_flushD, /* tlb_flushD */ 253183835Sraj armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 254183835Sraj 255183835Sraj /* Cache operations */ 256183835Sraj 257183835Sraj armv5_ec_icache_sync_all, /* icache_sync_all */ 258183835Sraj armv5_ec_icache_sync_range, /* icache_sync_range */ 259183835Sraj 260183835Sraj armv5_ec_dcache_wbinv_all, /* dcache_wbinv_all */ 261186933Sraj sheeva_dcache_wbinv_range, /* dcache_wbinv_range */ 262186933Sraj sheeva_dcache_inv_range, /* dcache_inv_range */ 263186933Sraj sheeva_dcache_wb_range, /* dcache_wb_range */ 264183835Sraj 265262420Sian armv4_idcache_inv_all, /* idcache_inv_all */ 266183835Sraj armv5_ec_idcache_wbinv_all, /* idcache_wbinv_all */ 267186933Sraj sheeva_idcache_wbinv_range, /* idcache_wbinv_all */ 268183835Sraj 269186933Sraj sheeva_l2cache_wbinv_all, /* l2cache_wbinv_all */ 270186933Sraj sheeva_l2cache_wbinv_range, /* l2cache_wbinv_range */ 271186933Sraj sheeva_l2cache_inv_range, /* l2cache_inv_range */ 272186933Sraj sheeva_l2cache_wb_range, /* l2cache_wb_range */ 273265870Sian (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ 274183835Sraj 275183835Sraj /* Other functions */ 276183835Sraj 277183835Sraj cpufunc_nullop, /* flush_prefetchbuf */ 278183835Sraj armv4_drain_writebuf, /* drain_writebuf */ 279183835Sraj cpufunc_nullop, /* flush_brnchtgt_C */ 280183835Sraj (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 281183835Sraj 282212825Smav sheeva_cpu_sleep, /* sleep */ 283183835Sraj 284183835Sraj /* Soft functions */ 285183835Sraj 286183835Sraj cpufunc_null_fixup, /* dataabt_fixup */ 287183835Sraj cpufunc_null_fixup, /* prefetchabt_fixup */ 288183835Sraj 289183835Sraj arm10_context_switch, /* context_switch */ 290183835Sraj 291183835Sraj arm10_setup /* cpu setup */ 292183835Sraj}; 293280809Sandrew#endif /* CPU_ARM9E */ 294172738Simp 295239268Sgonzo#ifdef CPU_MV_PJ4B 296239268Sgonzostruct cpu_functions pj4bv7_cpufuncs = { 297239268Sgonzo /* CPU functions */ 298239268Sgonzo 299239268Sgonzo cpufunc_id, /* id */ 300266672Szbb armv7_drain_writebuf, /* cpwait */ 301239268Sgonzo 302239268Sgonzo /* MMU functions */ 303239268Sgonzo 304239268Sgonzo cpufunc_control, /* control */ 305239268Sgonzo cpufunc_domains, /* Domain */ 306266672Szbb armv7_setttb, /* Setttb */ 307239268Sgonzo cpufunc_faultstatus, /* Faultstatus */ 308239268Sgonzo cpufunc_faultaddress, /* Faultaddress */ 309239268Sgonzo 310239268Sgonzo /* TLB functions */ 311239268Sgonzo 312239268Sgonzo armv7_tlb_flushID, /* tlb_flushID */ 313239268Sgonzo armv7_tlb_flushID_SE, /* tlb_flushID_SE */ 314239268Sgonzo armv7_tlb_flushID, /* tlb_flushI */ 315239268Sgonzo armv7_tlb_flushID_SE, /* tlb_flushI_SE */ 316239268Sgonzo armv7_tlb_flushID, /* tlb_flushD */ 317239268Sgonzo armv7_tlb_flushID_SE, /* tlb_flushD_SE */ 318239268Sgonzo 319239268Sgonzo /* Cache operations */ 320239268Sgonzo armv7_idcache_wbinv_all, /* icache_sync_all */ 321239268Sgonzo armv7_icache_sync_range, /* icache_sync_range */ 322239268Sgonzo 323239268Sgonzo armv7_dcache_wbinv_all, /* dcache_wbinv_all */ 324239268Sgonzo armv7_dcache_wbinv_range, /* dcache_wbinv_range */ 325239268Sgonzo armv7_dcache_inv_range, /* dcache_inv_range */ 326239268Sgonzo armv7_dcache_wb_range, /* dcache_wb_range */ 327239268Sgonzo 328262420Sian armv7_idcache_inv_all, /* idcache_inv_all */ 329239268Sgonzo armv7_idcache_wbinv_all, /* idcache_wbinv_all */ 330239268Sgonzo armv7_idcache_wbinv_range, /* idcache_wbinv_all */ 331239268Sgonzo 332239268Sgonzo (void *)cpufunc_nullop, /* l2cache_wbinv_all */ 333239268Sgonzo (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 334239268Sgonzo (void *)cpufunc_nullop, /* l2cache_inv_range */ 335239268Sgonzo (void *)cpufunc_nullop, /* l2cache_wb_range */ 336265870Sian (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ 337239268Sgonzo 338239268Sgonzo /* Other functions */ 339239268Sgonzo 340266672Szbb cpufunc_nullop, /* flush_prefetchbuf */ 341266672Szbb armv7_drain_writebuf, /* drain_writebuf */ 342266672Szbb cpufunc_nullop, /* flush_brnchtgt_C */ 343266672Szbb (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 344239268Sgonzo 345239268Sgonzo (void *)cpufunc_nullop, /* sleep */ 346239268Sgonzo 347239268Sgonzo /* Soft functions */ 348239268Sgonzo 349239268Sgonzo cpufunc_null_fixup, /* dataabt_fixup */ 350239268Sgonzo cpufunc_null_fixup, /* prefetchabt_fixup */ 351239268Sgonzo 352266672Szbb armv7_context_switch, /* context_switch */ 353239268Sgonzo 354239268Sgonzo pj4bv7_setup /* cpu setup */ 355239268Sgonzo}; 356239268Sgonzo#endif /* CPU_MV_PJ4B */ 357239268Sgonzo 358280847Sandrew#if defined(CPU_XSCALE_80321) || \ 359161592Scognet defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \ 360161592Scognet defined(CPU_XSCALE_80219) 361161592Scognet 362129198Scognetstruct cpu_functions xscale_cpufuncs = { 363129198Scognet /* CPU functions */ 364283366Sandrew 365129198Scognet cpufunc_id, /* id */ 366129198Scognet xscale_cpwait, /* cpwait */ 367129198Scognet 368129198Scognet /* MMU functions */ 369129198Scognet 370129198Scognet xscale_control, /* control */ 371129198Scognet cpufunc_domains, /* domain */ 372129198Scognet xscale_setttb, /* setttb */ 373129198Scognet cpufunc_faultstatus, /* faultstatus */ 374129198Scognet cpufunc_faultaddress, /* faultaddress */ 375129198Scognet 376129198Scognet /* TLB functions */ 377129198Scognet 378129198Scognet armv4_tlb_flushID, /* tlb_flushID */ 379129198Scognet xscale_tlb_flushID_SE, /* tlb_flushID_SE */ 380129198Scognet armv4_tlb_flushI, /* tlb_flushI */ 381129198Scognet (void *)armv4_tlb_flushI, /* tlb_flushI_SE */ 382129198Scognet armv4_tlb_flushD, /* tlb_flushD */ 383129198Scognet armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 384129198Scognet 385129198Scognet /* Cache operations */ 386129198Scognet 387129198Scognet xscale_cache_syncI, /* icache_sync_all */ 388129198Scognet xscale_cache_syncI_rng, /* icache_sync_range */ 389129198Scognet 390129198Scognet xscale_cache_purgeD, /* dcache_wbinv_all */ 391129198Scognet xscale_cache_purgeD_rng, /* dcache_wbinv_range */ 392129198Scognet xscale_cache_flushD_rng, /* dcache_inv_range */ 393129198Scognet xscale_cache_cleanD_rng, /* dcache_wb_range */ 394129198Scognet 395262420Sian xscale_cache_flushID, /* idcache_inv_all */ 396129198Scognet xscale_cache_purgeID, /* idcache_wbinv_all */ 397129198Scognet xscale_cache_purgeID_rng, /* idcache_wbinv_range */ 398171618Scognet cpufunc_nullop, /* l2cache_wbinv_all */ 399171781Scognet (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 400171781Scognet (void *)cpufunc_nullop, /* l2cache_inv_range */ 401171781Scognet (void *)cpufunc_nullop, /* l2cache_wb_range */ 402265870Sian (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ 403129198Scognet 404129198Scognet /* Other functions */ 405129198Scognet 406129198Scognet cpufunc_nullop, /* flush_prefetchbuf */ 407129198Scognet armv4_drain_writebuf, /* drain_writebuf */ 408129198Scognet cpufunc_nullop, /* flush_brnchtgt_C */ 409129198Scognet (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 410129198Scognet 411129198Scognet xscale_cpu_sleep, /* sleep */ 412129198Scognet 413129198Scognet /* Soft functions */ 414129198Scognet 415129198Scognet cpufunc_null_fixup, /* dataabt_fixup */ 416129198Scognet cpufunc_null_fixup, /* prefetchabt_fixup */ 417129198Scognet 418129198Scognet xscale_context_switch, /* context_switch */ 419129198Scognet 420129198Scognet xscale_setup /* cpu setup */ 421129198Scognet}; 422129198Scognet#endif 423280847Sandrew/* CPU_XSCALE_80321 || CPU_XSCALE_PXA2X0 || CPU_XSCALE_IXP425 424161592Scognet CPU_XSCALE_80219 */ 425129198Scognet 426164080Scognet#ifdef CPU_XSCALE_81342 427164080Scognetstruct cpu_functions xscalec3_cpufuncs = { 428164080Scognet /* CPU functions */ 429283366Sandrew 430164080Scognet cpufunc_id, /* id */ 431164080Scognet xscale_cpwait, /* cpwait */ 432164080Scognet 433164080Scognet /* MMU functions */ 434164080Scognet 435164080Scognet xscale_control, /* control */ 436164080Scognet cpufunc_domains, /* domain */ 437164080Scognet xscalec3_setttb, /* setttb */ 438164080Scognet cpufunc_faultstatus, /* faultstatus */ 439164080Scognet cpufunc_faultaddress, /* faultaddress */ 440164080Scognet 441164080Scognet /* TLB functions */ 442164080Scognet 443164080Scognet armv4_tlb_flushID, /* tlb_flushID */ 444164080Scognet xscale_tlb_flushID_SE, /* tlb_flushID_SE */ 445164080Scognet armv4_tlb_flushI, /* tlb_flushI */ 446164080Scognet (void *)armv4_tlb_flushI, /* tlb_flushI_SE */ 447164080Scognet armv4_tlb_flushD, /* tlb_flushD */ 448164080Scognet armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 449164080Scognet 450164080Scognet /* Cache operations */ 451164080Scognet 452164080Scognet xscalec3_cache_syncI, /* icache_sync_all */ 453171618Scognet xscalec3_cache_syncI_rng, /* icache_sync_range */ 454164080Scognet 455164080Scognet xscalec3_cache_purgeD, /* dcache_wbinv_all */ 456164080Scognet xscalec3_cache_purgeD_rng, /* dcache_wbinv_range */ 457164080Scognet xscale_cache_flushD_rng, /* dcache_inv_range */ 458164080Scognet xscalec3_cache_cleanD_rng, /* dcache_wb_range */ 459164080Scognet 460262420Sian xscale_cache_flushID, /* idcache_inv_all */ 461171618Scognet xscalec3_cache_purgeID, /* idcache_wbinv_all */ 462164080Scognet xscalec3_cache_purgeID_rng, /* idcache_wbinv_range */ 463171618Scognet xscalec3_l2cache_purge, /* l2cache_wbinv_all */ 464171618Scognet xscalec3_l2cache_purge_rng, /* l2cache_wbinv_range */ 465171618Scognet xscalec3_l2cache_flush_rng, /* l2cache_inv_range */ 466171618Scognet xscalec3_l2cache_clean_rng, /* l2cache_wb_range */ 467265870Sian (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ 468164080Scognet 469164080Scognet /* Other functions */ 470164080Scognet 471164080Scognet cpufunc_nullop, /* flush_prefetchbuf */ 472164080Scognet armv4_drain_writebuf, /* drain_writebuf */ 473164080Scognet cpufunc_nullop, /* flush_brnchtgt_C */ 474164080Scognet (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 475164080Scognet 476164080Scognet xscale_cpu_sleep, /* sleep */ 477164080Scognet 478164080Scognet /* Soft functions */ 479164080Scognet 480164080Scognet cpufunc_null_fixup, /* dataabt_fixup */ 481164080Scognet cpufunc_null_fixup, /* prefetchabt_fixup */ 482164080Scognet 483164080Scognet xscalec3_context_switch, /* context_switch */ 484164080Scognet 485164080Scognet xscale_setup /* cpu setup */ 486164080Scognet}; 487164080Scognet#endif /* CPU_XSCALE_81342 */ 488201468Srpaulo 489201468Srpaulo 490280842Sandrew#if defined(CPU_FA526) 491201468Srpaulostruct cpu_functions fa526_cpufuncs = { 492201468Srpaulo /* CPU functions */ 493201468Srpaulo 494207611Skevlo cpufunc_id, /* id */ 495207611Skevlo cpufunc_nullop, /* cpwait */ 496201468Srpaulo 497201468Srpaulo /* MMU functions */ 498201468Srpaulo 499207611Skevlo cpufunc_control, /* control */ 500207611Skevlo cpufunc_domains, /* domain */ 501207611Skevlo fa526_setttb, /* setttb */ 502207611Skevlo cpufunc_faultstatus, /* faultstatus */ 503207611Skevlo cpufunc_faultaddress, /* faultaddress */ 504201468Srpaulo 505201468Srpaulo /* TLB functions */ 506201468Srpaulo 507207611Skevlo armv4_tlb_flushID, /* tlb_flushID */ 508207611Skevlo fa526_tlb_flushID_SE, /* tlb_flushID_SE */ 509207611Skevlo armv4_tlb_flushI, /* tlb_flushI */ 510207611Skevlo fa526_tlb_flushI_SE, /* tlb_flushI_SE */ 511207611Skevlo armv4_tlb_flushD, /* tlb_flushD */ 512207611Skevlo armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 513201468Srpaulo 514201468Srpaulo /* Cache operations */ 515201468Srpaulo 516207611Skevlo fa526_icache_sync_all, /* icache_sync_all */ 517207611Skevlo fa526_icache_sync_range, /* icache_sync_range */ 518201468Srpaulo 519207611Skevlo fa526_dcache_wbinv_all, /* dcache_wbinv_all */ 520207611Skevlo fa526_dcache_wbinv_range, /* dcache_wbinv_range */ 521207611Skevlo fa526_dcache_inv_range, /* dcache_inv_range */ 522207611Skevlo fa526_dcache_wb_range, /* dcache_wb_range */ 523201468Srpaulo 524262420Sian armv4_idcache_inv_all, /* idcache_inv_all */ 525207611Skevlo fa526_idcache_wbinv_all, /* idcache_wbinv_all */ 526207611Skevlo fa526_idcache_wbinv_range, /* idcache_wbinv_range */ 527207611Skevlo cpufunc_nullop, /* l2cache_wbinv_all */ 528207611Skevlo (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 529207611Skevlo (void *)cpufunc_nullop, /* l2cache_inv_range */ 530207611Skevlo (void *)cpufunc_nullop, /* l2cache_wb_range */ 531265870Sian (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ 532201468Srpaulo 533201468Srpaulo /* Other functions */ 534201468Srpaulo 535207611Skevlo fa526_flush_prefetchbuf, /* flush_prefetchbuf */ 536207611Skevlo armv4_drain_writebuf, /* drain_writebuf */ 537207611Skevlo cpufunc_nullop, /* flush_brnchtgt_C */ 538207611Skevlo fa526_flush_brnchtgt_E, /* flush_brnchtgt_E */ 539201468Srpaulo 540207611Skevlo fa526_cpu_sleep, /* sleep */ 541201468Srpaulo 542201468Srpaulo /* Soft functions */ 543201468Srpaulo 544207611Skevlo cpufunc_null_fixup, /* dataabt_fixup */ 545207611Skevlo cpufunc_null_fixup, /* prefetchabt_fixup */ 546201468Srpaulo 547207611Skevlo fa526_context_switch, /* context_switch */ 548201468Srpaulo 549207611Skevlo fa526_setup /* cpu setup */ 550236991Simp}; 551280842Sandrew#endif /* CPU_FA526 */ 552201468Srpaulo 553244480Sgonzo#if defined(CPU_ARM1176) 554244480Sgonzostruct cpu_functions arm1176_cpufuncs = { 555244480Sgonzo /* CPU functions */ 556283366Sandrew 557244480Sgonzo cpufunc_id, /* id */ 558244480Sgonzo cpufunc_nullop, /* cpwait */ 559283366Sandrew 560244480Sgonzo /* MMU functions */ 561283366Sandrew 562244480Sgonzo cpufunc_control, /* control */ 563244480Sgonzo cpufunc_domains, /* Domain */ 564244480Sgonzo arm11x6_setttb, /* Setttb */ 565244480Sgonzo cpufunc_faultstatus, /* Faultstatus */ 566244480Sgonzo cpufunc_faultaddress, /* Faultaddress */ 567283366Sandrew 568244480Sgonzo /* TLB functions */ 569283366Sandrew 570244480Sgonzo arm11_tlb_flushID, /* tlb_flushID */ 571244480Sgonzo arm11_tlb_flushID_SE, /* tlb_flushID_SE */ 572244480Sgonzo arm11_tlb_flushI, /* tlb_flushI */ 573244480Sgonzo arm11_tlb_flushI_SE, /* tlb_flushI_SE */ 574244480Sgonzo arm11_tlb_flushD, /* tlb_flushD */ 575244480Sgonzo arm11_tlb_flushD_SE, /* tlb_flushD_SE */ 576283366Sandrew 577244480Sgonzo /* Cache operations */ 578283366Sandrew 579244480Sgonzo arm11x6_icache_sync_all, /* icache_sync_all */ 580244480Sgonzo arm11x6_icache_sync_range, /* icache_sync_range */ 581283366Sandrew 582244480Sgonzo arm11x6_dcache_wbinv_all, /* dcache_wbinv_all */ 583244480Sgonzo armv6_dcache_wbinv_range, /* dcache_wbinv_range */ 584244480Sgonzo armv6_dcache_inv_range, /* dcache_inv_range */ 585244480Sgonzo armv6_dcache_wb_range, /* dcache_wb_range */ 586283366Sandrew 587262420Sian armv6_idcache_inv_all, /* idcache_inv_all */ 588244480Sgonzo arm11x6_idcache_wbinv_all, /* idcache_wbinv_all */ 589244480Sgonzo arm11x6_idcache_wbinv_range, /* idcache_wbinv_range */ 590283366Sandrew 591244480Sgonzo (void *)cpufunc_nullop, /* l2cache_wbinv_all */ 592244480Sgonzo (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 593244480Sgonzo (void *)cpufunc_nullop, /* l2cache_inv_range */ 594244480Sgonzo (void *)cpufunc_nullop, /* l2cache_wb_range */ 595265870Sian (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ 596283366Sandrew 597244480Sgonzo /* Other functions */ 598283366Sandrew 599244480Sgonzo arm11x6_flush_prefetchbuf, /* flush_prefetchbuf */ 600244480Sgonzo arm11_drain_writebuf, /* drain_writebuf */ 601244480Sgonzo cpufunc_nullop, /* flush_brnchtgt_C */ 602244480Sgonzo (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 603283366Sandrew 604244480Sgonzo arm11x6_sleep, /* sleep */ 605283366Sandrew 606244480Sgonzo /* Soft functions */ 607283366Sandrew 608244480Sgonzo cpufunc_null_fixup, /* dataabt_fixup */ 609244480Sgonzo cpufunc_null_fixup, /* prefetchabt_fixup */ 610283366Sandrew 611244480Sgonzo arm11_context_switch, /* context_switch */ 612283366Sandrew 613244480Sgonzo arm11x6_setup /* cpu setup */ 614244480Sgonzo}; 615244480Sgonzo#endif /*CPU_ARM1176 */ 616239701Sgonzo 617259640Sganbold#if defined(CPU_CORTEXA) || defined(CPU_KRAIT) 618239268Sgonzostruct cpu_functions cortexa_cpufuncs = { 619239268Sgonzo /* CPU functions */ 620283366Sandrew 621239268Sgonzo cpufunc_id, /* id */ 622239268Sgonzo cpufunc_nullop, /* cpwait */ 623283366Sandrew 624239268Sgonzo /* MMU functions */ 625283366Sandrew 626239268Sgonzo cpufunc_control, /* control */ 627239268Sgonzo cpufunc_domains, /* Domain */ 628239268Sgonzo armv7_setttb, /* Setttb */ 629239268Sgonzo cpufunc_faultstatus, /* Faultstatus */ 630239268Sgonzo cpufunc_faultaddress, /* Faultaddress */ 631283366Sandrew 632283366Sandrew /* 633263251Sian * TLB functions. ARMv7 does all TLB ops based on a unified TLB model 634263251Sian * whether the hardware implements separate I+D or not, so we use the 635263251Sian * same 'ID' functions for all 3 variations. 636263251Sian */ 637283366Sandrew 638243024Scognet armv7_tlb_flushID, /* tlb_flushID */ 639239268Sgonzo armv7_tlb_flushID_SE, /* tlb_flushID_SE */ 640263251Sian armv7_tlb_flushID, /* tlb_flushI */ 641263251Sian armv7_tlb_flushID_SE, /* tlb_flushI_SE */ 642263251Sian armv7_tlb_flushID, /* tlb_flushD */ 643263251Sian armv7_tlb_flushID_SE, /* tlb_flushD_SE */ 644283366Sandrew 645239268Sgonzo /* Cache operations */ 646283366Sandrew 647264994Sian armv7_icache_sync_all, /* icache_sync_all */ 648239268Sgonzo armv7_icache_sync_range, /* icache_sync_range */ 649283366Sandrew 650239268Sgonzo armv7_dcache_wbinv_all, /* dcache_wbinv_all */ 651239268Sgonzo armv7_dcache_wbinv_range, /* dcache_wbinv_range */ 652239268Sgonzo armv7_dcache_inv_range, /* dcache_inv_range */ 653239268Sgonzo armv7_dcache_wb_range, /* dcache_wb_range */ 654283366Sandrew 655262420Sian armv7_idcache_inv_all, /* idcache_inv_all */ 656239268Sgonzo armv7_idcache_wbinv_all, /* idcache_wbinv_all */ 657239268Sgonzo armv7_idcache_wbinv_range, /* idcache_wbinv_range */ 658283366Sandrew 659283366Sandrew /* 660243026Scognet * Note: For CPUs using the PL310 the L2 ops are filled in when the 661239268Sgonzo * L2 cache controller is actually enabled. 662239268Sgonzo */ 663239268Sgonzo cpufunc_nullop, /* l2cache_wbinv_all */ 664239268Sgonzo (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 665239268Sgonzo (void *)cpufunc_nullop, /* l2cache_inv_range */ 666239268Sgonzo (void *)cpufunc_nullop, /* l2cache_wb_range */ 667265870Sian (void *)cpufunc_nullop, /* l2cache_drain_writebuf */ 668283366Sandrew 669239268Sgonzo /* Other functions */ 670283366Sandrew 671239268Sgonzo cpufunc_nullop, /* flush_prefetchbuf */ 672245478Scognet armv7_drain_writebuf, /* drain_writebuf */ 673239268Sgonzo cpufunc_nullop, /* flush_brnchtgt_C */ 674239268Sgonzo (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 675283366Sandrew 676282934Sganbold armv7_cpu_sleep, /* sleep */ 677283366Sandrew 678239268Sgonzo /* Soft functions */ 679283366Sandrew 680239268Sgonzo cpufunc_null_fixup, /* dataabt_fixup */ 681239268Sgonzo cpufunc_null_fixup, /* prefetchabt_fixup */ 682283366Sandrew 683245478Scognet armv7_context_switch, /* context_switch */ 684283366Sandrew 685239268Sgonzo cortexa_setup /* cpu setup */ 686239268Sgonzo}; 687239268Sgonzo#endif /* CPU_CORTEXA */ 688201468Srpaulo 689129198Scognet/* 690129198Scognet * Global constants also used by locore.s 691129198Scognet */ 692129198Scognet 693129198Scognetstruct cpu_functions cpufuncs; 694129198Scognetu_int cputype; 695129198Scognetu_int cpu_reset_needs_v4_MMU_disable; /* flag used in locore.s */ 696129198Scognet 697262958Sian#if defined(CPU_ARM9) || \ 698280824Sandrew defined (CPU_ARM9E) || \ 699280847Sandrew defined(CPU_ARM1176) || defined(CPU_XSCALE_80321) || \ 700207611Skevlo defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \ 701280842Sandrew defined(CPU_FA526) || defined(CPU_MV_PJ4B) || \ 702239268Sgonzo defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342) || \ 703259640Sganbold defined(CPU_CORTEXA) || defined(CPU_KRAIT) 704161592Scognet 705278518Szbb/* Global cache line sizes, use 32 as default */ 706278518Szbbint arm_dcache_min_line_size = 32; 707278518Szbbint arm_icache_min_line_size = 32; 708278518Szbbint arm_idcache_min_line_size = 32; 709278518Szbb 710137498Strhodesstatic void get_cachetype_cp15(void); 711129198Scognet 712129198Scognet/* Additional cache information local to this file. Log2 of some of the 713129198Scognet above numbers. */ 714129198Scognetstatic int arm_dcache_l2_nsets; 715129198Scognetstatic int arm_dcache_l2_assoc; 716129198Scognetstatic int arm_dcache_l2_linesize; 717129198Scognet 718129198Scognetstatic void 719129198Scognetget_cachetype_cp15() 720129198Scognet{ 721239268Sgonzo u_int ctype, isize, dsize, cpuid; 722239268Sgonzo u_int clevel, csize, i, sel; 723129198Scognet u_int multiplier; 724239268Sgonzo u_char type; 725129198Scognet 726129198Scognet __asm __volatile("mrc p15, 0, %0, c0, c0, 1" 727129198Scognet : "=r" (ctype)); 728129198Scognet 729239268Sgonzo cpuid = cpufunc_id(); 730129198Scognet /* 731129198Scognet * ...and thus spake the ARM ARM: 732129198Scognet * 733129198Scognet * If an <opcode2> value corresponding to an unimplemented or 734129198Scognet * reserved ID register is encountered, the System Control 735129198Scognet * processor returns the value of the main ID register. 736129198Scognet */ 737239268Sgonzo if (ctype == cpuid) 738129198Scognet goto out; 739129198Scognet 740239268Sgonzo if (CPU_CT_FORMAT(ctype) == CPU_CT_ARMV7) { 741278518Szbb /* Resolve minimal cache line sizes */ 742278518Szbb arm_dcache_min_line_size = 1 << (CPU_CT_DMINLINE(ctype) + 2); 743278518Szbb arm_icache_min_line_size = 1 << (CPU_CT_IMINLINE(ctype) + 2); 744278518Szbb arm_idcache_min_line_size = 745278518Szbb min(arm_icache_min_line_size, arm_dcache_min_line_size); 746278518Szbb 747239268Sgonzo __asm __volatile("mrc p15, 1, %0, c0, c0, 1" 748239268Sgonzo : "=r" (clevel)); 749239268Sgonzo arm_cache_level = clevel; 750239268Sgonzo arm_cache_loc = CPU_CLIDR_LOC(arm_cache_level); 751239268Sgonzo i = 0; 752239268Sgonzo while ((type = (clevel & 0x7)) && i < 7) { 753239268Sgonzo if (type == CACHE_DCACHE || type == CACHE_UNI_CACHE || 754239268Sgonzo type == CACHE_SEP_CACHE) { 755239268Sgonzo sel = i << 1; 756239268Sgonzo __asm __volatile("mcr p15, 2, %0, c0, c0, 0" 757239268Sgonzo : : "r" (sel)); 758239268Sgonzo __asm __volatile("mrc p15, 1, %0, c0, c0, 0" 759239268Sgonzo : "=r" (csize)); 760239268Sgonzo arm_cache_type[sel] = csize; 761283366Sandrew arm_dcache_align = 1 << 762239268Sgonzo (CPUV7_CT_xSIZE_LEN(csize) + 4); 763239268Sgonzo arm_dcache_align_mask = arm_dcache_align - 1; 764239268Sgonzo } 765239268Sgonzo if (type == CACHE_ICACHE || type == CACHE_SEP_CACHE) { 766239268Sgonzo sel = (i << 1) | 1; 767239268Sgonzo __asm __volatile("mcr p15, 2, %0, c0, c0, 0" 768239268Sgonzo : : "r" (sel)); 769239268Sgonzo __asm __volatile("mrc p15, 1, %0, c0, c0, 0" 770239268Sgonzo : "=r" (csize)); 771239268Sgonzo arm_cache_type[sel] = csize; 772239268Sgonzo } 773239268Sgonzo i++; 774239268Sgonzo clevel >>= 3; 775239268Sgonzo } 776239268Sgonzo } else { 777239268Sgonzo if ((ctype & CPU_CT_S) == 0) 778239268Sgonzo arm_pcache_unified = 1; 779129198Scognet 780239268Sgonzo /* 781239268Sgonzo * If you want to know how this code works, go read the ARM ARM. 782239268Sgonzo */ 783129198Scognet 784239268Sgonzo arm_pcache_type = CPU_CT_CTYPE(ctype); 785129198Scognet 786239268Sgonzo if (arm_pcache_unified == 0) { 787239268Sgonzo isize = CPU_CT_ISIZE(ctype); 788239268Sgonzo multiplier = (isize & CPU_CT_xSIZE_M) ? 3 : 2; 789239268Sgonzo arm_picache_line_size = 1U << (CPU_CT_xSIZE_LEN(isize) + 3); 790239268Sgonzo if (CPU_CT_xSIZE_ASSOC(isize) == 0) { 791239268Sgonzo if (isize & CPU_CT_xSIZE_M) 792239268Sgonzo arm_picache_line_size = 0; /* not present */ 793239268Sgonzo else 794239268Sgonzo arm_picache_ways = 1; 795239268Sgonzo } else { 796239268Sgonzo arm_picache_ways = multiplier << 797239268Sgonzo (CPU_CT_xSIZE_ASSOC(isize) - 1); 798239268Sgonzo } 799239268Sgonzo arm_picache_size = multiplier << (CPU_CT_xSIZE_SIZE(isize) + 8); 800239268Sgonzo } 801239268Sgonzo 802239268Sgonzo dsize = CPU_CT_DSIZE(ctype); 803239268Sgonzo multiplier = (dsize & CPU_CT_xSIZE_M) ? 3 : 2; 804239268Sgonzo arm_pdcache_line_size = 1U << (CPU_CT_xSIZE_LEN(dsize) + 3); 805239268Sgonzo if (CPU_CT_xSIZE_ASSOC(dsize) == 0) { 806239268Sgonzo if (dsize & CPU_CT_xSIZE_M) 807239268Sgonzo arm_pdcache_line_size = 0; /* not present */ 808129198Scognet else 809239268Sgonzo arm_pdcache_ways = 1; 810129198Scognet } else { 811239268Sgonzo arm_pdcache_ways = multiplier << 812239268Sgonzo (CPU_CT_xSIZE_ASSOC(dsize) - 1); 813129198Scognet } 814239268Sgonzo arm_pdcache_size = multiplier << (CPU_CT_xSIZE_SIZE(dsize) + 8); 815129198Scognet 816239268Sgonzo arm_dcache_align = arm_pdcache_line_size; 817129198Scognet 818239268Sgonzo arm_dcache_l2_assoc = CPU_CT_xSIZE_ASSOC(dsize) + multiplier - 2; 819239268Sgonzo arm_dcache_l2_linesize = CPU_CT_xSIZE_LEN(dsize) + 3; 820239268Sgonzo arm_dcache_l2_nsets = 6 + CPU_CT_xSIZE_SIZE(dsize) - 821239268Sgonzo CPU_CT_xSIZE_ASSOC(dsize) - CPU_CT_xSIZE_LEN(dsize); 822129198Scognet 823239268Sgonzo out: 824239268Sgonzo arm_dcache_align_mask = arm_dcache_align - 1; 825239268Sgonzo } 826129198Scognet} 827262958Sian#endif /* ARM9 || XSCALE */ 828129198Scognet 829129198Scognet/* 830129198Scognet * Cannot panic here as we may not have a console yet ... 831129198Scognet */ 832129198Scognet 833129198Scognetint 834129198Scognetset_cpufuncs() 835129198Scognet{ 836129198Scognet cputype = cpufunc_id(); 837129198Scognet cputype &= CPU_ID_CPU_MASK; 838129198Scognet 839129198Scognet#ifdef CPU_ARM9 840129198Scognet if (((cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_ARM_LTD || 841129198Scognet (cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_TI) && 842129198Scognet (cputype & 0x0000f000) == 0x00009000) { 843129198Scognet cpufuncs = arm9_cpufuncs; 844129198Scognet cpu_reset_needs_v4_MMU_disable = 1; /* V4 or higher */ 845129198Scognet get_cachetype_cp15(); 846146605Scognet arm9_dcache_sets_inc = 1U << arm_dcache_l2_linesize; 847146605Scognet arm9_dcache_sets_max = (1U << (arm_dcache_l2_linesize + 848146605Scognet arm_dcache_l2_nsets)) - arm9_dcache_sets_inc; 849146605Scognet arm9_dcache_index_inc = 1U << (32 - arm_dcache_l2_assoc); 850146605Scognet arm9_dcache_index_max = 0U - arm9_dcache_index_inc; 851137270Scognet pmap_pte_init_generic(); 852166655Scognet goto out; 853129198Scognet } 854129198Scognet#endif /* CPU_ARM9 */ 855280809Sandrew#if defined(CPU_ARM9E) 856239268Sgonzo if (cputype == CPU_ID_MV88FR131 || cputype == CPU_ID_MV88FR571_VD || 857183835Sraj cputype == CPU_ID_MV88FR571_41) { 858239268Sgonzo uint32_t sheeva_ctrl; 859183835Sraj 860239268Sgonzo sheeva_ctrl = (MV_DC_STREAM_ENABLE | MV_BTB_DISABLE | 861239268Sgonzo MV_L2_ENABLE); 862239268Sgonzo /* 863239268Sgonzo * Workaround for Marvell MV78100 CPU: Cache prefetch 864239268Sgonzo * mechanism may affect the cache coherency validity, 865239268Sgonzo * so it needs to be disabled. 866239268Sgonzo * 867239268Sgonzo * Refer to errata document MV-S501058-00C.pdf (p. 3.1 868239268Sgonzo * L2 Prefetching Mechanism) for details. 869239268Sgonzo */ 870239268Sgonzo if (cputype == CPU_ID_MV88FR571_VD || 871239268Sgonzo cputype == CPU_ID_MV88FR571_41) 872239268Sgonzo sheeva_ctrl |= MV_L2_PREFETCH_DISABLE; 873212825Smav 874239268Sgonzo sheeva_control_ext(0xffffffff & ~MV_WA_ENABLE, sheeva_ctrl); 875183835Sraj 876239268Sgonzo cpufuncs = sheeva_cpufuncs; 877172738Simp get_cachetype_cp15(); 878172738Simp pmap_pte_init_generic(); 879174058Scognet goto out; 880280809Sandrew } else if (cputype == CPU_ID_ARM926EJS) { 881239268Sgonzo cpufuncs = armv5_ec_cpufuncs; 882239268Sgonzo get_cachetype_cp15(); 883239268Sgonzo pmap_pte_init_generic(); 884239268Sgonzo goto out; 885172738Simp } 886280809Sandrew#endif /* CPU_ARM9E */ 887280824Sandrew#if defined(CPU_ARM1176) 888280824Sandrew if (cputype == CPU_ID_ARM1176JZS) { 889280868Sandrew cpufuncs = arm1176_cpufuncs; 890244480Sgonzo cpu_reset_needs_v4_MMU_disable = 1; /* V4 or higher */ 891244480Sgonzo get_cachetype_cp15(); 892239701Sgonzo 893244480Sgonzo pmap_pte_init_mmu_v6(); 894244480Sgonzo 895244480Sgonzo goto out; 896244480Sgonzo } 897280824Sandrew#endif /* CPU_ARM1176 */ 898259640Sganbold#if defined(CPU_CORTEXA) || defined(CPU_KRAIT) 899256629Sbr if (cputype == CPU_ID_CORTEXA5 || 900256629Sbr cputype == CPU_ID_CORTEXA7 || 901253857Sganbold cputype == CPU_ID_CORTEXA8R1 || 902239268Sgonzo cputype == CPU_ID_CORTEXA8R2 || 903239268Sgonzo cputype == CPU_ID_CORTEXA8R3 || 904239268Sgonzo cputype == CPU_ID_CORTEXA9R1 || 905249999Swkoszek cputype == CPU_ID_CORTEXA9R2 || 906252361Sray cputype == CPU_ID_CORTEXA9R3 || 907277156Sganbold cputype == CPU_ID_CORTEXA12R0 || 908263982Sbr cputype == CPU_ID_CORTEXA15R0 || 909263982Sbr cputype == CPU_ID_CORTEXA15R1 || 910263982Sbr cputype == CPU_ID_CORTEXA15R2 || 911263982Sbr cputype == CPU_ID_CORTEXA15R3 || 912259640Sganbold cputype == CPU_ID_KRAIT ) { 913239268Sgonzo cpufuncs = cortexa_cpufuncs; 914239268Sgonzo cpu_reset_needs_v4_MMU_disable = 1; /* V4 or higher */ 915239268Sgonzo get_cachetype_cp15(); 916283366Sandrew 917239268Sgonzo pmap_pte_init_mmu_v6(); 918239268Sgonzo goto out; 919239268Sgonzo } 920239268Sgonzo#endif /* CPU_CORTEXA */ 921283366Sandrew 922239268Sgonzo#if defined(CPU_MV_PJ4B) 923257281Szbb if (cputype == CPU_ID_MV88SV581X_V7 || 924240486Sgber cputype == CPU_ID_MV88SV584X_V7 || 925239268Sgonzo cputype == CPU_ID_ARM_88SV581X_V7) { 926257281Szbb cpufuncs = pj4bv7_cpufuncs; 927239268Sgonzo get_cachetype_cp15(); 928239268Sgonzo pmap_pte_init_mmu_v6(); 929239268Sgonzo goto out; 930239268Sgonzo } 931239268Sgonzo#endif /* CPU_MV_PJ4B */ 932129198Scognet 933280842Sandrew#if defined(CPU_FA526) 934207611Skevlo if (cputype == CPU_ID_FA526 || cputype == CPU_ID_FA626TE) { 935201468Srpaulo cpufuncs = fa526_cpufuncs; 936201468Srpaulo cpu_reset_needs_v4_MMU_disable = 1; /* SA needs it */ 937201468Srpaulo get_cachetype_cp15(); 938201468Srpaulo pmap_pte_init_generic(); 939201468Srpaulo 940201468Srpaulo goto out; 941201468Srpaulo } 942280842Sandrew#endif /* CPU_FA526 */ 943262958Sian 944161592Scognet#if defined(CPU_XSCALE_80321) || defined(CPU_XSCALE_80219) 945129198Scognet if (cputype == CPU_ID_80321_400 || cputype == CPU_ID_80321_600 || 946161592Scognet cputype == CPU_ID_80321_400_B0 || cputype == CPU_ID_80321_600_B0 || 947161592Scognet cputype == CPU_ID_80219_400 || cputype == CPU_ID_80219_600) { 948129198Scognet cpufuncs = xscale_cpufuncs; 949129198Scognet cpu_reset_needs_v4_MMU_disable = 1; /* XScale needs it */ 950129198Scognet get_cachetype_cp15(); 951129198Scognet pmap_pte_init_xscale(); 952166655Scognet goto out; 953129198Scognet } 954129198Scognet#endif /* CPU_XSCALE_80321 */ 955161592Scognet 956164080Scognet#if defined(CPU_XSCALE_81342) 957164080Scognet if (cputype == CPU_ID_81342) { 958164080Scognet cpufuncs = xscalec3_cpufuncs; 959164080Scognet cpu_reset_needs_v4_MMU_disable = 1; /* XScale needs it */ 960164080Scognet get_cachetype_cp15(); 961164080Scognet pmap_pte_init_xscale(); 962166655Scognet goto out; 963164080Scognet } 964164080Scognet#endif /* CPU_XSCALE_81342 */ 965129198Scognet#ifdef CPU_XSCALE_PXA2X0 966129198Scognet /* ignore core revision to test PXA2xx CPUs */ 967129198Scognet if ((cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA250 || 968191817Sstas (cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA27X || 969129198Scognet (cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA210) { 970129198Scognet 971129198Scognet cpufuncs = xscale_cpufuncs; 972129198Scognet cpu_reset_needs_v4_MMU_disable = 1; /* XScale needs it */ 973129198Scognet get_cachetype_cp15(); 974129198Scognet pmap_pte_init_xscale(); 975129198Scognet 976166655Scognet goto out; 977129198Scognet } 978129198Scognet#endif /* CPU_XSCALE_PXA2X0 */ 979129198Scognet#ifdef CPU_XSCALE_IXP425 980129198Scognet if (cputype == CPU_ID_IXP425_533 || cputype == CPU_ID_IXP425_400 || 981186352Ssam cputype == CPU_ID_IXP425_266 || cputype == CPU_ID_IXP435) { 982129198Scognet 983129198Scognet cpufuncs = xscale_cpufuncs; 984129198Scognet cpu_reset_needs_v4_MMU_disable = 1; /* XScale needs it */ 985129198Scognet get_cachetype_cp15(); 986129198Scognet pmap_pte_init_xscale(); 987129198Scognet 988166655Scognet goto out; 989129198Scognet } 990129198Scognet#endif /* CPU_XSCALE_IXP425 */ 991129198Scognet /* 992129198Scognet * Bzzzz. And the answer was ... 993129198Scognet */ 994129198Scognet panic("No support for this CPU type (%08x) in kernel", cputype); 995129198Scognet return(ARCHITECTURE_NOT_PRESENT); 996166655Scognetout: 997166655Scognet uma_set_align(arm_dcache_align_mask); 998166655Scognet return (0); 999129198Scognet} 1000129198Scognet 1001129198Scognet/* 1002129198Scognet * Fixup routines for data and prefetch aborts. 1003129198Scognet * 1004129198Scognet * Several compile time symbols are used 1005129198Scognet * 1006129198Scognet * DEBUG_FAULT_CORRECTION - Print debugging information during the 1007129198Scognet * correction of registers after a fault. 1008129198Scognet */ 1009129198Scognet 1010129198Scognet 1011129198Scognet/* 1012129198Scognet * Null abort fixup routine. 1013129198Scognet * For use when no fixup is required. 1014129198Scognet */ 1015129198Scognetint 1016129198Scognetcpufunc_null_fixup(arg) 1017129198Scognet void *arg; 1018129198Scognet{ 1019129198Scognet return(ABORT_FIXUP_OK); 1020129198Scognet} 1021129198Scognet 1022129198Scognet/* 1023129198Scognet * CPU Setup code 1024129198Scognet */ 1025129198Scognet 1026129198Scognet#ifdef CPU_ARM9 1027129198Scognetvoid 1028280823Sandrewarm9_setup(void) 1029129198Scognet{ 1030129198Scognet int cpuctrl, cpuctrlmask; 1031129198Scognet 1032129198Scognet cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 1033129198Scognet | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 1034129198Scognet | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 1035157618Scognet | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE | 1036157618Scognet CPU_CONTROL_ROUNDROBIN; 1037129198Scognet cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 1038129198Scognet | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 1039129198Scognet | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 1040129198Scognet | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE 1041129198Scognet | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE 1042146605Scognet | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_VECRELOC 1043146605Scognet | CPU_CONTROL_ROUNDROBIN; 1044129198Scognet 1045129198Scognet#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 1046129198Scognet cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 1047129198Scognet#endif 1048129198Scognet 1049129198Scognet#ifdef __ARMEB__ 1050129198Scognet cpuctrl |= CPU_CONTROL_BEND_ENABLE; 1051129198Scognet#endif 1052142050Scognet if (vector_page == ARM_VECTORS_HIGH) 1053142050Scognet cpuctrl |= CPU_CONTROL_VECRELOC; 1054129198Scognet 1055129198Scognet /* Clear out the cache */ 1056129198Scognet cpu_idcache_wbinv_all(); 1057129198Scognet 1058129198Scognet /* Set the control register */ 1059146605Scognet cpu_control(cpuctrlmask, cpuctrl); 1060129198Scognet ctrl = cpuctrl; 1061129198Scognet 1062129198Scognet} 1063129198Scognet#endif /* CPU_ARM9 */ 1064129198Scognet 1065280809Sandrew#if defined(CPU_ARM9E) 1066129198Scognetvoid 1067280823Sandrewarm10_setup(void) 1068129198Scognet{ 1069129198Scognet int cpuctrl, cpuctrlmask; 1070129198Scognet 1071129198Scognet cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_SYST_ENABLE 1072236991Simp | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 1073129198Scognet | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_BPRD_ENABLE; 1074129198Scognet cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_SYST_ENABLE 1075129198Scognet | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 1076129198Scognet | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE 1077129198Scognet | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE 1078129198Scognet | CPU_CONTROL_BPRD_ENABLE 1079129198Scognet | CPU_CONTROL_ROUNDROBIN | CPU_CONTROL_CPCLK; 1080129198Scognet 1081129198Scognet#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 1082129198Scognet cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 1083129198Scognet#endif 1084129198Scognet 1085129198Scognet#ifdef __ARMEB__ 1086129198Scognet cpuctrl |= CPU_CONTROL_BEND_ENABLE; 1087129198Scognet#endif 1088129198Scognet 1089129198Scognet /* Clear out the cache */ 1090129198Scognet cpu_idcache_wbinv_all(); 1091129198Scognet 1092129198Scognet /* Now really make sure they are clean. */ 1093172738Simp __asm __volatile ("mcr\tp15, 0, r0, c7, c7, 0" : : ); 1094129198Scognet 1095174058Scognet if (vector_page == ARM_VECTORS_HIGH) 1096174058Scognet cpuctrl |= CPU_CONTROL_VECRELOC; 1097174058Scognet 1098129198Scognet /* Set the control register */ 1099129198Scognet ctrl = cpuctrl; 1100129198Scognet cpu_control(0xffffffff, cpuctrl); 1101129198Scognet 1102129198Scognet /* And again. */ 1103129198Scognet cpu_idcache_wbinv_all(); 1104129198Scognet} 1105172738Simp#endif /* CPU_ARM9E || CPU_ARM10 */ 1106129198Scognet 1107280824Sandrew#if defined(CPU_ARM1176) \ 1108266083Smarkm || defined(CPU_MV_PJ4B) \ 1109266083Smarkm || defined(CPU_CORTEXA) || defined(CPU_KRAIT) 1110266083Smarkmstatic __inline void 1111266083Smarkmcpu_scc_setup_ccnt(void) 1112266083Smarkm{ 1113266083Smarkm/* This is how you give userland access to the CCNT and PMCn 1114266083Smarkm * registers. 1115266083Smarkm * BEWARE! This gives write access also, which may not be what 1116266083Smarkm * you want! 1117266083Smarkm */ 1118266083Smarkm#ifdef _PMC_USER_READ_WRITE_ 1119266083Smarkm /* Set PMUSERENR[0] to allow userland access */ 1120283365Sandrew cp15_pmuserenr_set(1); 1121266083Smarkm#endif 1122280824Sandrew#if defined(CPU_ARM1176) 1123267597Stuexen /* Set PMCR[2,0] to enable counters and reset CCNT */ 1124283365Sandrew cp15_pmcr_set(5); 1125267597Stuexen#else 1126267597Stuexen /* Set up the PMCCNTR register as a cyclecounter: 1127266083Smarkm * Set PMINTENCLR to 0xFFFFFFFF to block interrupts 1128266083Smarkm * Set PMCR[2,0] to enable counters and reset CCNT 1129266083Smarkm * Set PMCNTENSET to 0x80000000 to enable CCNT */ 1130283365Sandrew cp15_pminten_clr(0xFFFFFFFF); 1131283365Sandrew cp15_pmcr_set(5); 1132283365Sandrew cp15_pmcnten_set(0x80000000); 1133267597Stuexen#endif 1134266083Smarkm} 1135266083Smarkm#endif 1136266083Smarkm 1137280824Sandrew#if defined(CPU_ARM1176) 1138172738Simpvoid 1139280823Sandrewarm11x6_setup(void) 1140172738Simp{ 1141244480Sgonzo int cpuctrl, cpuctrl_wax; 1142244480Sgonzo uint32_t auxctrl, auxctrl_wax; 1143244480Sgonzo uint32_t tmp, tmp2; 1144244480Sgonzo uint32_t sbz=0; 1145244480Sgonzo uint32_t cpuid; 1146172738Simp 1147244480Sgonzo cpuid = cpufunc_id(); 1148244480Sgonzo 1149244480Sgonzo cpuctrl = 1150244480Sgonzo CPU_CONTROL_MMU_ENABLE | 1151244480Sgonzo CPU_CONTROL_DC_ENABLE | 1152244480Sgonzo CPU_CONTROL_WBUF_ENABLE | 1153244480Sgonzo CPU_CONTROL_32BP_ENABLE | 1154244480Sgonzo CPU_CONTROL_32BD_ENABLE | 1155244480Sgonzo CPU_CONTROL_LABT_ENABLE | 1156244480Sgonzo CPU_CONTROL_SYST_ENABLE | 1157282019Sandrew CPU_CONTROL_IC_ENABLE | 1158282019Sandrew CPU_CONTROL_UNAL_ENABLE; 1159244480Sgonzo 1160244480Sgonzo /* 1161244480Sgonzo * "write as existing" bits 1162244480Sgonzo * inverse of this is mask 1163244480Sgonzo */ 1164244480Sgonzo cpuctrl_wax = 1165244480Sgonzo (3 << 30) | /* SBZ */ 1166244480Sgonzo (1 << 29) | /* FA */ 1167244480Sgonzo (1 << 28) | /* TR */ 1168283366Sandrew (3 << 26) | /* SBZ */ 1169244480Sgonzo (3 << 19) | /* SBZ */ 1170244480Sgonzo (1 << 17); /* SBZ */ 1171244480Sgonzo 1172244480Sgonzo cpuctrl |= CPU_CONTROL_BPRD_ENABLE; 1173244480Sgonzo cpuctrl |= CPU_CONTROL_V6_EXTPAGE; 1174244480Sgonzo 1175172738Simp#ifdef __ARMEB__ 1176172738Simp cpuctrl |= CPU_CONTROL_BEND_ENABLE; 1177172738Simp#endif 1178244480Sgonzo 1179239701Sgonzo if (vector_page == ARM_VECTORS_HIGH) 1180239701Sgonzo cpuctrl |= CPU_CONTROL_VECRELOC; 1181172738Simp 1182244480Sgonzo auxctrl = 0; 1183244480Sgonzo auxctrl_wax = ~0; 1184244480Sgonzo 1185244480Sgonzo /* 1186244480Sgonzo * Enable an errata workaround 1187244480Sgonzo */ 1188244480Sgonzo if ((cpuid & CPU_ID_CPU_MASK) == CPU_ID_ARM1176JZS) { /* ARM1176JZSr0 */ 1189244480Sgonzo auxctrl = ARM1176_AUXCTL_PHD; 1190244480Sgonzo auxctrl_wax = ~ARM1176_AUXCTL_PHD; 1191244480Sgonzo } 1192244480Sgonzo 1193244480Sgonzo /* Clear out the cache */ 1194172738Simp cpu_idcache_wbinv_all(); 1195172738Simp 1196244480Sgonzo /* Now really make sure they are clean. */ 1197244480Sgonzo __asm volatile ("mcr\tp15, 0, %0, c7, c7, 0" : : "r"(sbz)); 1198244480Sgonzo 1199244480Sgonzo /* Allow detection code to find the VFP if it's fitted. */ 1200283365Sandrew cp15_cpacr_set(0x0fffffff); 1201244480Sgonzo 1202172738Simp /* Set the control register */ 1203239701Sgonzo ctrl = cpuctrl; 1204244480Sgonzo cpu_control(~cpuctrl_wax, cpuctrl); 1205172738Simp 1206283365Sandrew tmp = cp15_actlr_get(); 1207283365Sandrew tmp2 = tmp; 1208283365Sandrew tmp &= auxctrl_wax; 1209283365Sandrew tmp |= auxctrl; 1210283365Sandrew if (tmp != tmp2) 1211283365Sandrew cp15_actlr_set(tmp); 1212244480Sgonzo 1213244480Sgonzo /* And again. */ 1214172738Simp cpu_idcache_wbinv_all(); 1215266083Smarkm 1216266083Smarkm cpu_scc_setup_ccnt(); 1217172738Simp} 1218280824Sandrew#endif /* CPU_ARM1176 */ 1219172738Simp 1220239268Sgonzo#ifdef CPU_MV_PJ4B 1221239268Sgonzovoid 1222280823Sandrewpj4bv7_setup(void) 1223239268Sgonzo{ 1224239268Sgonzo int cpuctrl; 1225239268Sgonzo 1226239268Sgonzo pj4b_config(); 1227239268Sgonzo 1228239268Sgonzo cpuctrl = CPU_CONTROL_MMU_ENABLE; 1229239268Sgonzo#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 1230239268Sgonzo cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 1231239268Sgonzo#endif 1232239268Sgonzo cpuctrl |= CPU_CONTROL_DC_ENABLE; 1233239268Sgonzo cpuctrl |= (0xf << 3); 1234239268Sgonzo cpuctrl |= CPU_CONTROL_BPRD_ENABLE; 1235239268Sgonzo cpuctrl |= CPU_CONTROL_IC_ENABLE; 1236239268Sgonzo if (vector_page == ARM_VECTORS_HIGH) 1237239268Sgonzo cpuctrl |= CPU_CONTROL_VECRELOC; 1238239268Sgonzo cpuctrl |= (0x5 << 16) | (1 < 22); 1239239268Sgonzo cpuctrl |= CPU_CONTROL_V6_EXTPAGE; 1240239268Sgonzo 1241239268Sgonzo /* Clear out the cache */ 1242239268Sgonzo cpu_idcache_wbinv_all(); 1243239268Sgonzo 1244239268Sgonzo /* Set the control register */ 1245239268Sgonzo ctrl = cpuctrl; 1246239268Sgonzo cpu_control(0xFFFFFFFF, cpuctrl); 1247239268Sgonzo 1248239268Sgonzo /* And again. */ 1249239268Sgonzo cpu_idcache_wbinv_all(); 1250266083Smarkm 1251266083Smarkm cpu_scc_setup_ccnt(); 1252239268Sgonzo} 1253239268Sgonzo#endif /* CPU_MV_PJ4B */ 1254239268Sgonzo 1255259640Sganbold#if defined(CPU_CORTEXA) || defined(CPU_KRAIT) 1256239268Sgonzo 1257239268Sgonzovoid 1258280823Sandrewcortexa_setup(void) 1259239268Sgonzo{ 1260239268Sgonzo int cpuctrl, cpuctrlmask; 1261283366Sandrew 1262239268Sgonzo cpuctrlmask = CPU_CONTROL_MMU_ENABLE | /* MMU enable [0] */ 1263239268Sgonzo CPU_CONTROL_AFLT_ENABLE | /* Alignment fault [1] */ 1264239268Sgonzo CPU_CONTROL_DC_ENABLE | /* DCache enable [2] */ 1265239268Sgonzo CPU_CONTROL_BPRD_ENABLE | /* Branch prediction [11] */ 1266239268Sgonzo CPU_CONTROL_IC_ENABLE | /* ICache enable [12] */ 1267239268Sgonzo CPU_CONTROL_VECRELOC; /* Vector relocation [13] */ 1268283366Sandrew 1269239268Sgonzo cpuctrl = CPU_CONTROL_MMU_ENABLE | 1270239268Sgonzo CPU_CONTROL_IC_ENABLE | 1271239268Sgonzo CPU_CONTROL_DC_ENABLE | 1272239268Sgonzo CPU_CONTROL_BPRD_ENABLE; 1273283366Sandrew 1274239268Sgonzo#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 1275239268Sgonzo cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 1276239268Sgonzo#endif 1277283366Sandrew 1278239268Sgonzo /* Switch to big endian */ 1279239268Sgonzo#ifdef __ARMEB__ 1280239268Sgonzo cpuctrl |= CPU_CONTROL_BEND_ENABLE; 1281239268Sgonzo#endif 1282283366Sandrew 1283239268Sgonzo /* Check if the vector page is at the high address (0xffff0000) */ 1284239268Sgonzo if (vector_page == ARM_VECTORS_HIGH) 1285239268Sgonzo cpuctrl |= CPU_CONTROL_VECRELOC; 1286283366Sandrew 1287239268Sgonzo /* Clear out the cache */ 1288239268Sgonzo cpu_idcache_wbinv_all(); 1289283366Sandrew 1290239268Sgonzo /* Set the control register */ 1291239268Sgonzo ctrl = cpuctrl; 1292239268Sgonzo cpu_control(cpuctrlmask, cpuctrl); 1293283366Sandrew 1294239268Sgonzo /* And again. */ 1295239268Sgonzo cpu_idcache_wbinv_all(); 1296239268Sgonzo#ifdef SMP 1297239268Sgonzo armv7_auxctrl((1 << 6) | (1 << 0), (1 << 6) | (1 << 0)); /* Enable SMP + TLB broadcasting */ 1298239268Sgonzo#endif 1299266083Smarkm 1300266083Smarkm cpu_scc_setup_ccnt(); 1301239268Sgonzo} 1302239268Sgonzo#endif /* CPU_CORTEXA */ 1303239268Sgonzo 1304280842Sandrew#if defined(CPU_FA526) 1305201468Srpaulovoid 1306280823Sandrewfa526_setup(void) 1307201468Srpaulo{ 1308201468Srpaulo int cpuctrl, cpuctrlmask; 1309201468Srpaulo 1310201468Srpaulo cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 1311201468Srpaulo | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 1312201468Srpaulo | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 1313204122Skevlo | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE 1314204122Skevlo | CPU_CONTROL_BPRD_ENABLE; 1315201468Srpaulo cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 1316201468Srpaulo | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 1317201468Srpaulo | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 1318201468Srpaulo | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE 1319201468Srpaulo | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE 1320201468Srpaulo | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_BPRD_ENABLE 1321201468Srpaulo | CPU_CONTROL_CPCLK | CPU_CONTROL_VECRELOC; 1322201468Srpaulo 1323201468Srpaulo#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 1324201468Srpaulo cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 1325201468Srpaulo#endif 1326201468Srpaulo 1327201468Srpaulo#ifdef __ARMEB__ 1328201468Srpaulo cpuctrl |= CPU_CONTROL_BEND_ENABLE; 1329201468Srpaulo#endif 1330201468Srpaulo 1331201468Srpaulo if (vector_page == ARM_VECTORS_HIGH) 1332201468Srpaulo cpuctrl |= CPU_CONTROL_VECRELOC; 1333201468Srpaulo 1334201468Srpaulo /* Clear out the cache */ 1335201468Srpaulo cpu_idcache_wbinv_all(); 1336201468Srpaulo 1337201468Srpaulo /* Set the control register */ 1338201468Srpaulo ctrl = cpuctrl; 1339201468Srpaulo cpu_control(0xffffffff, cpuctrl); 1340201468Srpaulo} 1341280842Sandrew#endif /* CPU_FA526 */ 1342201468Srpaulo 1343280847Sandrew#if defined(CPU_XSCALE_80321) || \ 1344161592Scognet defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \ 1345164080Scognet defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342) 1346129198Scognetvoid 1347280823Sandrewxscale_setup(void) 1348129198Scognet{ 1349129198Scognet uint32_t auxctl; 1350129198Scognet int cpuctrl, cpuctrlmask; 1351129198Scognet 1352129198Scognet /* 1353129198Scognet * The XScale Write Buffer is always enabled. Our option 1354129198Scognet * is to enable/disable coalescing. Note that bits 6:3 1355129198Scognet * must always be enabled. 1356129198Scognet */ 1357129198Scognet 1358129198Scognet cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 1359129198Scognet | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 1360129198Scognet | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 1361129198Scognet | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE 1362129198Scognet | CPU_CONTROL_BPRD_ENABLE; 1363129198Scognet cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 1364129198Scognet | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 1365129198Scognet | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 1366129198Scognet | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE 1367129198Scognet | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE 1368129198Scognet | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_BPRD_ENABLE 1369171618Scognet | CPU_CONTROL_CPCLK | CPU_CONTROL_VECRELOC | \ 1370171618Scognet CPU_CONTROL_L2_ENABLE; 1371129198Scognet 1372129198Scognet#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 1373129198Scognet cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 1374129198Scognet#endif 1375129198Scognet 1376129198Scognet#ifdef __ARMEB__ 1377129198Scognet cpuctrl |= CPU_CONTROL_BEND_ENABLE; 1378129198Scognet#endif 1379129198Scognet 1380129198Scognet if (vector_page == ARM_VECTORS_HIGH) 1381129198Scognet cpuctrl |= CPU_CONTROL_VECRELOC; 1382171618Scognet#ifdef CPU_XSCALE_CORE3 1383171618Scognet cpuctrl |= CPU_CONTROL_L2_ENABLE; 1384171618Scognet#endif 1385129198Scognet 1386129198Scognet /* Clear out the cache */ 1387129198Scognet cpu_idcache_wbinv_all(); 1388129198Scognet 1389129198Scognet /* 1390129198Scognet * Set the control register. Note that bits 6:3 must always 1391129198Scognet * be set to 1. 1392129198Scognet */ 1393129198Scognet ctrl = cpuctrl; 1394129198Scognet/* cpu_control(cpuctrlmask, cpuctrl);*/ 1395129198Scognet cpu_control(0xffffffff, cpuctrl); 1396129198Scognet 1397129198Scognet /* Make sure write coalescing is turned on */ 1398129198Scognet __asm __volatile("mrc p15, 0, %0, c1, c0, 1" 1399129198Scognet : "=r" (auxctl)); 1400129198Scognet#ifdef XSCALE_NO_COALESCE_WRITES 1401129198Scognet auxctl |= XSCALE_AUXCTL_K; 1402129198Scognet#else 1403129198Scognet auxctl &= ~XSCALE_AUXCTL_K; 1404129198Scognet#endif 1405171618Scognet#ifdef CPU_XSCALE_CORE3 1406171618Scognet auxctl |= XSCALE_AUXCTL_LLR; 1407171618Scognet auxctl |= XSCALE_AUXCTL_MD_MASK; 1408171618Scognet#endif 1409129198Scognet __asm __volatile("mcr p15, 0, %0, c1, c0, 1" 1410129198Scognet : : "r" (auxctl)); 1411129198Scognet} 1412280847Sandrew#endif /* CPU_XSCALE_80321 || CPU_XSCALE_PXA2X0 || CPU_XSCALE_IXP425 1413161592Scognet CPU_XSCALE_80219 */ 1414