cpufunc.c revision 259640
1129198Scognet/* $NetBSD: cpufunc.c,v 1.65 2003/11/05 12:53:15 scw Exp $ */ 2129198Scognet 3139735Simp/*- 4129198Scognet * arm7tdmi support code Copyright (c) 2001 John Fremlin 5129198Scognet * arm8 support code Copyright (c) 1997 ARM Limited 6129198Scognet * arm8 support code Copyright (c) 1997 Causality Limited 7129198Scognet * arm9 support code Copyright (C) 2001 ARM Ltd 8129198Scognet * Copyright (c) 1997 Mark Brinicombe. 9129198Scognet * Copyright (c) 1997 Causality Limited 10129198Scognet * All rights reserved. 11129198Scognet * 12129198Scognet * Redistribution and use in source and binary forms, with or without 13129198Scognet * modification, are permitted provided that the following conditions 14129198Scognet * are met: 15129198Scognet * 1. Redistributions of source code must retain the above copyright 16129198Scognet * notice, this list of conditions and the following disclaimer. 17129198Scognet * 2. Redistributions in binary form must reproduce the above copyright 18129198Scognet * notice, this list of conditions and the following disclaimer in the 19129198Scognet * documentation and/or other materials provided with the distribution. 20129198Scognet * 3. All advertising materials mentioning features or use of this software 21129198Scognet * must display the following acknowledgement: 22129198Scognet * This product includes software developed by Causality Limited. 23129198Scognet * 4. The name of Causality Limited may not be used to endorse or promote 24129198Scognet * products derived from this software without specific prior written 25129198Scognet * permission. 26129198Scognet * 27129198Scognet * THIS SOFTWARE IS PROVIDED BY CAUSALITY LIMITED ``AS IS'' AND ANY EXPRESS 28129198Scognet * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 29129198Scognet * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 30129198Scognet * DISCLAIMED. IN NO EVENT SHALL CAUSALITY LIMITED BE LIABLE FOR ANY DIRECT, 31129198Scognet * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 32129198Scognet * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 33129198Scognet * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34129198Scognet * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35129198Scognet * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36129198Scognet * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37129198Scognet * SUCH DAMAGE. 38129198Scognet * 39129198Scognet * RiscBSD kernel project 40129198Scognet * 41129198Scognet * cpufuncs.c 42129198Scognet * 43129198Scognet * C functions for supporting CPU / MMU / TLB specific operations. 44129198Scognet * 45129198Scognet * Created : 30/01/97 46129198Scognet */ 47129198Scognet#include <sys/cdefs.h> 48129198Scognet__FBSDID("$FreeBSD: head/sys/arm/arm/cpufunc.c 259640 2013-12-20 00:56:23Z ganbold $"); 49129198Scognet 50129198Scognet#include <sys/param.h> 51129198Scognet#include <sys/systm.h> 52129198Scognet#include <sys/lock.h> 53129198Scognet#include <sys/mutex.h> 54132472Scognet#include <sys/bus.h> 55132472Scognet#include <machine/bus.h> 56129198Scognet#include <machine/cpu.h> 57129198Scognet#include <machine/disassem.h> 58129198Scognet 59129198Scognet#include <vm/vm.h> 60129198Scognet#include <vm/pmap.h> 61166655Scognet#include <vm/uma.h> 62129198Scognet 63129198Scognet#include <machine/cpuconf.h> 64129198Scognet#include <machine/cpufunc.h> 65129198Scognet#include <machine/bootconfig.h> 66129198Scognet 67129198Scognet#ifdef CPU_XSCALE_80200 68135646Scognet#include <arm/xscale/i80200/i80200reg.h> 69135646Scognet#include <arm/xscale/i80200/i80200var.h> 70129198Scognet#endif 71129198Scognet 72161592Scognet#if defined(CPU_XSCALE_80321) || defined(CPU_XSCALE_80219) 73135646Scognet#include <arm/xscale/i80321/i80321reg.h> 74135646Scognet#include <arm/xscale/i80321/i80321var.h> 75129198Scognet#endif 76129198Scognet 77243579Smarcel/* 78243579Smarcel * Some definitions in i81342reg.h clash with i80321reg.h. 79243579Smarcel * This only happens for the LINT kernel. As it happens, 80243579Smarcel * we don't need anything from i81342reg.h that we already 81243579Smarcel * got from somewhere else during a LINT compile. 82243579Smarcel */ 83243579Smarcel#if defined(CPU_XSCALE_81342) && !defined(COMPILING_LINT) 84164080Scognet#include <arm/xscale/i8134x/i81342reg.h> 85164080Scognet#endif 86164080Scognet 87129198Scognet#ifdef CPU_XSCALE_IXP425 88135646Scognet#include <arm/xscale/ixp425/ixp425reg.h> 89135646Scognet#include <arm/xscale/ixp425/ixp425var.h> 90129198Scognet#endif 91129198Scognet 92129198Scognet/* PRIMARY CACHE VARIABLES */ 93129198Scognetint arm_picache_size; 94129198Scognetint arm_picache_line_size; 95129198Scognetint arm_picache_ways; 96129198Scognet 97129198Scognetint arm_pdcache_size; /* and unified */ 98129198Scognetint arm_pdcache_line_size; 99129198Scognetint arm_pdcache_ways; 100129198Scognet 101129198Scognetint arm_pcache_type; 102129198Scognetint arm_pcache_unified; 103129198Scognet 104129198Scognetint arm_dcache_align; 105129198Scognetint arm_dcache_align_mask; 106129198Scognet 107239268Sgonzou_int arm_cache_level; 108239268Sgonzou_int arm_cache_type[14]; 109239268Sgonzou_int arm_cache_loc; 110239268Sgonzo 111129198Scognet/* 1 == use cpu_sleep(), 0 == don't */ 112129198Scognetint cpu_do_powersave; 113129198Scognetint ctrl; 114129198Scognet 115129198Scognet#ifdef CPU_ARM7TDMI 116129198Scognetstruct cpu_functions arm7tdmi_cpufuncs = { 117129198Scognet /* CPU functions */ 118129198Scognet 119129198Scognet cpufunc_id, /* id */ 120129198Scognet cpufunc_nullop, /* cpwait */ 121129198Scognet 122129198Scognet /* MMU functions */ 123129198Scognet 124129198Scognet cpufunc_control, /* control */ 125129198Scognet cpufunc_domains, /* domain */ 126129198Scognet arm7tdmi_setttb, /* setttb */ 127129198Scognet cpufunc_faultstatus, /* faultstatus */ 128129198Scognet cpufunc_faultaddress, /* faultaddress */ 129129198Scognet 130129198Scognet /* TLB functions */ 131129198Scognet 132129198Scognet arm7tdmi_tlb_flushID, /* tlb_flushID */ 133129198Scognet arm7tdmi_tlb_flushID_SE, /* tlb_flushID_SE */ 134129198Scognet arm7tdmi_tlb_flushID, /* tlb_flushI */ 135129198Scognet arm7tdmi_tlb_flushID_SE, /* tlb_flushI_SE */ 136129198Scognet arm7tdmi_tlb_flushID, /* tlb_flushD */ 137129198Scognet arm7tdmi_tlb_flushID_SE, /* tlb_flushD_SE */ 138129198Scognet 139129198Scognet /* Cache operations */ 140129198Scognet 141129198Scognet cpufunc_nullop, /* icache_sync_all */ 142129198Scognet (void *)cpufunc_nullop, /* icache_sync_range */ 143129198Scognet 144129198Scognet arm7tdmi_cache_flushID, /* dcache_wbinv_all */ 145129198Scognet (void *)arm7tdmi_cache_flushID, /* dcache_wbinv_range */ 146129198Scognet (void *)arm7tdmi_cache_flushID, /* dcache_inv_range */ 147129198Scognet (void *)cpufunc_nullop, /* dcache_wb_range */ 148129198Scognet 149129198Scognet arm7tdmi_cache_flushID, /* idcache_wbinv_all */ 150129198Scognet (void *)arm7tdmi_cache_flushID, /* idcache_wbinv_range */ 151171618Scognet cpufunc_nullop, /* l2cache_wbinv_all */ 152171781Scognet (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 153171781Scognet (void *)cpufunc_nullop, /* l2cache_inv_range */ 154171781Scognet (void *)cpufunc_nullop, /* l2cache_wb_range */ 155129198Scognet 156129198Scognet /* Other functions */ 157129198Scognet 158129198Scognet cpufunc_nullop, /* flush_prefetchbuf */ 159129198Scognet cpufunc_nullop, /* drain_writebuf */ 160129198Scognet cpufunc_nullop, /* flush_brnchtgt_C */ 161129198Scognet (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 162129198Scognet 163129198Scognet (void *)cpufunc_nullop, /* sleep */ 164129198Scognet 165129198Scognet /* Soft functions */ 166129198Scognet 167129198Scognet late_abort_fixup, /* dataabt_fixup */ 168129198Scognet cpufunc_null_fixup, /* prefetchabt_fixup */ 169129198Scognet 170129198Scognet arm7tdmi_context_switch, /* context_switch */ 171129198Scognet 172129198Scognet arm7tdmi_setup /* cpu setup */ 173129198Scognet 174129198Scognet}; 175129198Scognet#endif /* CPU_ARM7TDMI */ 176129198Scognet 177129198Scognet#ifdef CPU_ARM8 178129198Scognetstruct cpu_functions arm8_cpufuncs = { 179129198Scognet /* CPU functions */ 180129198Scognet 181129198Scognet cpufunc_id, /* id */ 182129198Scognet cpufunc_nullop, /* cpwait */ 183129198Scognet 184129198Scognet /* MMU functions */ 185129198Scognet 186129198Scognet cpufunc_control, /* control */ 187129198Scognet cpufunc_domains, /* domain */ 188129198Scognet arm8_setttb, /* setttb */ 189129198Scognet cpufunc_faultstatus, /* faultstatus */ 190129198Scognet cpufunc_faultaddress, /* faultaddress */ 191129198Scognet 192129198Scognet /* TLB functions */ 193129198Scognet 194129198Scognet arm8_tlb_flushID, /* tlb_flushID */ 195129198Scognet arm8_tlb_flushID_SE, /* tlb_flushID_SE */ 196129198Scognet arm8_tlb_flushID, /* tlb_flushI */ 197129198Scognet arm8_tlb_flushID_SE, /* tlb_flushI_SE */ 198129198Scognet arm8_tlb_flushID, /* tlb_flushD */ 199129198Scognet arm8_tlb_flushID_SE, /* tlb_flushD_SE */ 200129198Scognet 201129198Scognet /* Cache operations */ 202129198Scognet 203129198Scognet cpufunc_nullop, /* icache_sync_all */ 204129198Scognet (void *)cpufunc_nullop, /* icache_sync_range */ 205129198Scognet 206129198Scognet arm8_cache_purgeID, /* dcache_wbinv_all */ 207129198Scognet (void *)arm8_cache_purgeID, /* dcache_wbinv_range */ 208129198Scognet/*XXX*/ (void *)arm8_cache_purgeID, /* dcache_inv_range */ 209129198Scognet (void *)arm8_cache_cleanID, /* dcache_wb_range */ 210129198Scognet 211129198Scognet arm8_cache_purgeID, /* idcache_wbinv_all */ 212129198Scognet (void *)arm8_cache_purgeID, /* idcache_wbinv_range */ 213171618Scognet cpufunc_nullop, /* l2cache_wbinv_all */ 214171781Scognet (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 215171781Scognet (void *)cpufunc_nullop, /* l2cache_inv_range */ 216171781Scognet (void *)cpufunc_nullop, /* l2cache_wb_range */ 217129198Scognet 218129198Scognet /* Other functions */ 219129198Scognet 220129198Scognet cpufunc_nullop, /* flush_prefetchbuf */ 221129198Scognet cpufunc_nullop, /* drain_writebuf */ 222129198Scognet cpufunc_nullop, /* flush_brnchtgt_C */ 223129198Scognet (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 224129198Scognet 225129198Scognet (void *)cpufunc_nullop, /* sleep */ 226129198Scognet 227129198Scognet /* Soft functions */ 228129198Scognet 229129198Scognet cpufunc_null_fixup, /* dataabt_fixup */ 230129198Scognet cpufunc_null_fixup, /* prefetchabt_fixup */ 231129198Scognet 232129198Scognet arm8_context_switch, /* context_switch */ 233129198Scognet 234129198Scognet arm8_setup /* cpu setup */ 235236991Simp}; 236129198Scognet#endif /* CPU_ARM8 */ 237129198Scognet 238129198Scognet#ifdef CPU_ARM9 239129198Scognetstruct cpu_functions arm9_cpufuncs = { 240129198Scognet /* CPU functions */ 241129198Scognet 242129198Scognet cpufunc_id, /* id */ 243129198Scognet cpufunc_nullop, /* cpwait */ 244129198Scognet 245129198Scognet /* MMU functions */ 246129198Scognet 247129198Scognet cpufunc_control, /* control */ 248129198Scognet cpufunc_domains, /* Domain */ 249129198Scognet arm9_setttb, /* Setttb */ 250129198Scognet cpufunc_faultstatus, /* Faultstatus */ 251129198Scognet cpufunc_faultaddress, /* Faultaddress */ 252129198Scognet 253129198Scognet /* TLB functions */ 254129198Scognet 255129198Scognet armv4_tlb_flushID, /* tlb_flushID */ 256129198Scognet arm9_tlb_flushID_SE, /* tlb_flushID_SE */ 257129198Scognet armv4_tlb_flushI, /* tlb_flushI */ 258129198Scognet (void *)armv4_tlb_flushI, /* tlb_flushI_SE */ 259129198Scognet armv4_tlb_flushD, /* tlb_flushD */ 260129198Scognet armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 261129198Scognet 262129198Scognet /* Cache operations */ 263129198Scognet 264146605Scognet arm9_icache_sync_all, /* icache_sync_all */ 265146605Scognet arm9_icache_sync_range, /* icache_sync_range */ 266129198Scognet 267146605Scognet arm9_dcache_wbinv_all, /* dcache_wbinv_all */ 268146605Scognet arm9_dcache_wbinv_range, /* dcache_wbinv_range */ 269195798Sraj arm9_dcache_inv_range, /* dcache_inv_range */ 270146605Scognet arm9_dcache_wb_range, /* dcache_wb_range */ 271129198Scognet 272146605Scognet arm9_idcache_wbinv_all, /* idcache_wbinv_all */ 273146605Scognet arm9_idcache_wbinv_range, /* idcache_wbinv_range */ 274171618Scognet cpufunc_nullop, /* l2cache_wbinv_all */ 275171781Scognet (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 276171781Scognet (void *)cpufunc_nullop, /* l2cache_inv_range */ 277171781Scognet (void *)cpufunc_nullop, /* l2cache_wb_range */ 278129198Scognet 279129198Scognet /* Other functions */ 280129198Scognet 281129198Scognet cpufunc_nullop, /* flush_prefetchbuf */ 282129198Scognet armv4_drain_writebuf, /* drain_writebuf */ 283129198Scognet cpufunc_nullop, /* flush_brnchtgt_C */ 284129198Scognet (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 285129198Scognet 286129198Scognet (void *)cpufunc_nullop, /* sleep */ 287129198Scognet 288129198Scognet /* Soft functions */ 289129198Scognet 290129198Scognet cpufunc_null_fixup, /* dataabt_fixup */ 291129198Scognet cpufunc_null_fixup, /* prefetchabt_fixup */ 292129198Scognet 293129198Scognet arm9_context_switch, /* context_switch */ 294129198Scognet 295129198Scognet arm9_setup /* cpu setup */ 296129198Scognet 297129198Scognet}; 298129198Scognet#endif /* CPU_ARM9 */ 299129198Scognet 300172738Simp#if defined(CPU_ARM9E) || defined(CPU_ARM10) 301172738Simpstruct cpu_functions armv5_ec_cpufuncs = { 302172738Simp /* CPU functions */ 303172738Simp 304172738Simp cpufunc_id, /* id */ 305172738Simp cpufunc_nullop, /* cpwait */ 306172738Simp 307172738Simp /* MMU functions */ 308172738Simp 309172738Simp cpufunc_control, /* control */ 310172738Simp cpufunc_domains, /* Domain */ 311172738Simp armv5_ec_setttb, /* Setttb */ 312172738Simp cpufunc_faultstatus, /* Faultstatus */ 313172738Simp cpufunc_faultaddress, /* Faultaddress */ 314172738Simp 315172738Simp /* TLB functions */ 316172738Simp 317172738Simp armv4_tlb_flushID, /* tlb_flushID */ 318172738Simp arm10_tlb_flushID_SE, /* tlb_flushID_SE */ 319172738Simp armv4_tlb_flushI, /* tlb_flushI */ 320172738Simp arm10_tlb_flushI_SE, /* tlb_flushI_SE */ 321172738Simp armv4_tlb_flushD, /* tlb_flushD */ 322172738Simp armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 323172738Simp 324172738Simp /* Cache operations */ 325172738Simp 326172738Simp armv5_ec_icache_sync_all, /* icache_sync_all */ 327172738Simp armv5_ec_icache_sync_range, /* icache_sync_range */ 328172738Simp 329172738Simp armv5_ec_dcache_wbinv_all, /* dcache_wbinv_all */ 330172738Simp armv5_ec_dcache_wbinv_range, /* dcache_wbinv_range */ 331195798Sraj armv5_ec_dcache_inv_range, /* dcache_inv_range */ 332172738Simp armv5_ec_dcache_wb_range, /* dcache_wb_range */ 333172738Simp 334172738Simp armv5_ec_idcache_wbinv_all, /* idcache_wbinv_all */ 335172738Simp armv5_ec_idcache_wbinv_range, /* idcache_wbinv_range */ 336172738Simp 337173442Scognet cpufunc_nullop, /* l2cache_wbinv_all */ 338173442Scognet (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 339173442Scognet (void *)cpufunc_nullop, /* l2cache_inv_range */ 340173442Scognet (void *)cpufunc_nullop, /* l2cache_wb_range */ 341236991Simp 342172738Simp /* Other functions */ 343172738Simp 344172738Simp cpufunc_nullop, /* flush_prefetchbuf */ 345172738Simp armv4_drain_writebuf, /* drain_writebuf */ 346172738Simp cpufunc_nullop, /* flush_brnchtgt_C */ 347172738Simp (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 348172738Simp 349172738Simp (void *)cpufunc_nullop, /* sleep */ 350172738Simp 351172738Simp /* Soft functions */ 352172738Simp 353172738Simp cpufunc_null_fixup, /* dataabt_fixup */ 354172738Simp cpufunc_null_fixup, /* prefetchabt_fixup */ 355172738Simp 356172738Simp arm10_context_switch, /* context_switch */ 357172738Simp 358172738Simp arm10_setup /* cpu setup */ 359172738Simp 360172738Simp}; 361183835Sraj 362186933Srajstruct cpu_functions sheeva_cpufuncs = { 363183835Sraj /* CPU functions */ 364183835Sraj 365183835Sraj cpufunc_id, /* id */ 366183835Sraj cpufunc_nullop, /* cpwait */ 367183835Sraj 368183835Sraj /* MMU functions */ 369183835Sraj 370183835Sraj cpufunc_control, /* control */ 371183835Sraj cpufunc_domains, /* Domain */ 372186933Sraj sheeva_setttb, /* Setttb */ 373183835Sraj cpufunc_faultstatus, /* Faultstatus */ 374183835Sraj cpufunc_faultaddress, /* Faultaddress */ 375183835Sraj 376183835Sraj /* TLB functions */ 377183835Sraj 378183835Sraj armv4_tlb_flushID, /* tlb_flushID */ 379183835Sraj arm10_tlb_flushID_SE, /* tlb_flushID_SE */ 380183835Sraj armv4_tlb_flushI, /* tlb_flushI */ 381183835Sraj arm10_tlb_flushI_SE, /* tlb_flushI_SE */ 382183835Sraj armv4_tlb_flushD, /* tlb_flushD */ 383183835Sraj armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 384183835Sraj 385183835Sraj /* Cache operations */ 386183835Sraj 387183835Sraj armv5_ec_icache_sync_all, /* icache_sync_all */ 388183835Sraj armv5_ec_icache_sync_range, /* icache_sync_range */ 389183835Sraj 390183835Sraj armv5_ec_dcache_wbinv_all, /* dcache_wbinv_all */ 391186933Sraj sheeva_dcache_wbinv_range, /* dcache_wbinv_range */ 392186933Sraj sheeva_dcache_inv_range, /* dcache_inv_range */ 393186933Sraj sheeva_dcache_wb_range, /* dcache_wb_range */ 394183835Sraj 395183835Sraj armv5_ec_idcache_wbinv_all, /* idcache_wbinv_all */ 396186933Sraj sheeva_idcache_wbinv_range, /* idcache_wbinv_all */ 397183835Sraj 398186933Sraj sheeva_l2cache_wbinv_all, /* l2cache_wbinv_all */ 399186933Sraj sheeva_l2cache_wbinv_range, /* l2cache_wbinv_range */ 400186933Sraj sheeva_l2cache_inv_range, /* l2cache_inv_range */ 401186933Sraj sheeva_l2cache_wb_range, /* l2cache_wb_range */ 402183835Sraj 403183835Sraj /* Other functions */ 404183835Sraj 405183835Sraj cpufunc_nullop, /* flush_prefetchbuf */ 406183835Sraj armv4_drain_writebuf, /* drain_writebuf */ 407183835Sraj cpufunc_nullop, /* flush_brnchtgt_C */ 408183835Sraj (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 409183835Sraj 410212825Smav sheeva_cpu_sleep, /* sleep */ 411183835Sraj 412183835Sraj /* Soft functions */ 413183835Sraj 414183835Sraj cpufunc_null_fixup, /* dataabt_fixup */ 415183835Sraj cpufunc_null_fixup, /* prefetchabt_fixup */ 416183835Sraj 417183835Sraj arm10_context_switch, /* context_switch */ 418183835Sraj 419183835Sraj arm10_setup /* cpu setup */ 420183835Sraj}; 421172738Simp#endif /* CPU_ARM9E || CPU_ARM10 */ 422172738Simp 423129198Scognet#ifdef CPU_ARM10 424129198Scognetstruct cpu_functions arm10_cpufuncs = { 425129198Scognet /* CPU functions */ 426129198Scognet 427129198Scognet cpufunc_id, /* id */ 428129198Scognet cpufunc_nullop, /* cpwait */ 429129198Scognet 430129198Scognet /* MMU functions */ 431129198Scognet 432129198Scognet cpufunc_control, /* control */ 433129198Scognet cpufunc_domains, /* Domain */ 434129198Scognet arm10_setttb, /* Setttb */ 435129198Scognet cpufunc_faultstatus, /* Faultstatus */ 436129198Scognet cpufunc_faultaddress, /* Faultaddress */ 437129198Scognet 438129198Scognet /* TLB functions */ 439129198Scognet 440129198Scognet armv4_tlb_flushID, /* tlb_flushID */ 441129198Scognet arm10_tlb_flushID_SE, /* tlb_flushID_SE */ 442129198Scognet armv4_tlb_flushI, /* tlb_flushI */ 443129198Scognet arm10_tlb_flushI_SE, /* tlb_flushI_SE */ 444129198Scognet armv4_tlb_flushD, /* tlb_flushD */ 445129198Scognet armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 446129198Scognet 447129198Scognet /* Cache operations */ 448129198Scognet 449129198Scognet arm10_icache_sync_all, /* icache_sync_all */ 450129198Scognet arm10_icache_sync_range, /* icache_sync_range */ 451129198Scognet 452129198Scognet arm10_dcache_wbinv_all, /* dcache_wbinv_all */ 453129198Scognet arm10_dcache_wbinv_range, /* dcache_wbinv_range */ 454129198Scognet arm10_dcache_inv_range, /* dcache_inv_range */ 455129198Scognet arm10_dcache_wb_range, /* dcache_wb_range */ 456129198Scognet 457129198Scognet arm10_idcache_wbinv_all, /* idcache_wbinv_all */ 458129198Scognet arm10_idcache_wbinv_range, /* idcache_wbinv_range */ 459171618Scognet cpufunc_nullop, /* l2cache_wbinv_all */ 460171781Scognet (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 461171781Scognet (void *)cpufunc_nullop, /* l2cache_inv_range */ 462171781Scognet (void *)cpufunc_nullop, /* l2cache_wb_range */ 463129198Scognet 464129198Scognet /* Other functions */ 465129198Scognet 466129198Scognet cpufunc_nullop, /* flush_prefetchbuf */ 467129198Scognet armv4_drain_writebuf, /* drain_writebuf */ 468129198Scognet cpufunc_nullop, /* flush_brnchtgt_C */ 469129198Scognet (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 470129198Scognet 471129198Scognet (void *)cpufunc_nullop, /* sleep */ 472129198Scognet 473129198Scognet /* Soft functions */ 474129198Scognet 475129198Scognet cpufunc_null_fixup, /* dataabt_fixup */ 476129198Scognet cpufunc_null_fixup, /* prefetchabt_fixup */ 477129198Scognet 478129198Scognet arm10_context_switch, /* context_switch */ 479129198Scognet 480129198Scognet arm10_setup /* cpu setup */ 481129198Scognet 482129198Scognet}; 483129198Scognet#endif /* CPU_ARM10 */ 484129198Scognet 485239268Sgonzo#ifdef CPU_MV_PJ4B 486239268Sgonzostruct cpu_functions pj4bv7_cpufuncs = { 487239268Sgonzo /* CPU functions */ 488239268Sgonzo 489239268Sgonzo cpufunc_id, /* id */ 490239268Sgonzo arm11_drain_writebuf, /* cpwait */ 491239268Sgonzo 492239268Sgonzo /* MMU functions */ 493239268Sgonzo 494239268Sgonzo cpufunc_control, /* control */ 495239268Sgonzo cpufunc_domains, /* Domain */ 496239268Sgonzo pj4b_setttb, /* Setttb */ 497239268Sgonzo cpufunc_faultstatus, /* Faultstatus */ 498239268Sgonzo cpufunc_faultaddress, /* Faultaddress */ 499239268Sgonzo 500239268Sgonzo /* TLB functions */ 501239268Sgonzo 502239268Sgonzo armv7_tlb_flushID, /* tlb_flushID */ 503239268Sgonzo armv7_tlb_flushID_SE, /* tlb_flushID_SE */ 504239268Sgonzo armv7_tlb_flushID, /* tlb_flushI */ 505239268Sgonzo armv7_tlb_flushID_SE, /* tlb_flushI_SE */ 506239268Sgonzo armv7_tlb_flushID, /* tlb_flushD */ 507239268Sgonzo armv7_tlb_flushID_SE, /* tlb_flushD_SE */ 508239268Sgonzo 509239268Sgonzo /* Cache operations */ 510239268Sgonzo armv7_idcache_wbinv_all, /* icache_sync_all */ 511239268Sgonzo armv7_icache_sync_range, /* icache_sync_range */ 512239268Sgonzo 513239268Sgonzo armv7_dcache_wbinv_all, /* dcache_wbinv_all */ 514239268Sgonzo armv7_dcache_wbinv_range, /* dcache_wbinv_range */ 515239268Sgonzo armv7_dcache_inv_range, /* dcache_inv_range */ 516239268Sgonzo armv7_dcache_wb_range, /* dcache_wb_range */ 517239268Sgonzo 518239268Sgonzo armv7_idcache_wbinv_all, /* idcache_wbinv_all */ 519239268Sgonzo armv7_idcache_wbinv_range, /* idcache_wbinv_all */ 520239268Sgonzo 521239268Sgonzo (void *)cpufunc_nullop, /* l2cache_wbinv_all */ 522239268Sgonzo (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 523239268Sgonzo (void *)cpufunc_nullop, /* l2cache_inv_range */ 524239268Sgonzo (void *)cpufunc_nullop, /* l2cache_wb_range */ 525239268Sgonzo 526239268Sgonzo /* Other functions */ 527239268Sgonzo 528239268Sgonzo pj4b_drain_readbuf, /* flush_prefetchbuf */ 529239268Sgonzo arm11_drain_writebuf, /* drain_writebuf */ 530239268Sgonzo pj4b_flush_brnchtgt_all, /* flush_brnchtgt_C */ 531239268Sgonzo pj4b_flush_brnchtgt_va, /* flush_brnchtgt_E */ 532239268Sgonzo 533239268Sgonzo (void *)cpufunc_nullop, /* sleep */ 534239268Sgonzo 535239268Sgonzo /* Soft functions */ 536239268Sgonzo 537239268Sgonzo cpufunc_null_fixup, /* dataabt_fixup */ 538239268Sgonzo cpufunc_null_fixup, /* prefetchabt_fixup */ 539239268Sgonzo 540239268Sgonzo arm11_context_switch, /* context_switch */ 541239268Sgonzo 542239268Sgonzo pj4bv7_setup /* cpu setup */ 543239268Sgonzo}; 544239268Sgonzo#endif /* CPU_MV_PJ4B */ 545239268Sgonzo 546129198Scognet#ifdef CPU_SA110 547129198Scognetstruct cpu_functions sa110_cpufuncs = { 548129198Scognet /* CPU functions */ 549129198Scognet 550129198Scognet cpufunc_id, /* id */ 551129198Scognet cpufunc_nullop, /* cpwait */ 552129198Scognet 553129198Scognet /* MMU functions */ 554129198Scognet 555129198Scognet cpufunc_control, /* control */ 556129198Scognet cpufunc_domains, /* domain */ 557129198Scognet sa1_setttb, /* setttb */ 558129198Scognet cpufunc_faultstatus, /* faultstatus */ 559129198Scognet cpufunc_faultaddress, /* faultaddress */ 560129198Scognet 561129198Scognet /* TLB functions */ 562129198Scognet 563129198Scognet armv4_tlb_flushID, /* tlb_flushID */ 564129198Scognet sa1_tlb_flushID_SE, /* tlb_flushID_SE */ 565129198Scognet armv4_tlb_flushI, /* tlb_flushI */ 566129198Scognet (void *)armv4_tlb_flushI, /* tlb_flushI_SE */ 567129198Scognet armv4_tlb_flushD, /* tlb_flushD */ 568129198Scognet armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 569129198Scognet 570129198Scognet /* Cache operations */ 571129198Scognet 572129198Scognet sa1_cache_syncI, /* icache_sync_all */ 573129198Scognet sa1_cache_syncI_rng, /* icache_sync_range */ 574129198Scognet 575129198Scognet sa1_cache_purgeD, /* dcache_wbinv_all */ 576129198Scognet sa1_cache_purgeD_rng, /* dcache_wbinv_range */ 577129198Scognet/*XXX*/ sa1_cache_purgeD_rng, /* dcache_inv_range */ 578129198Scognet sa1_cache_cleanD_rng, /* dcache_wb_range */ 579129198Scognet 580129198Scognet sa1_cache_purgeID, /* idcache_wbinv_all */ 581129198Scognet sa1_cache_purgeID_rng, /* idcache_wbinv_range */ 582171618Scognet cpufunc_nullop, /* l2cache_wbinv_all */ 583171781Scognet (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 584171781Scognet (void *)cpufunc_nullop, /* l2cache_inv_range */ 585171781Scognet (void *)cpufunc_nullop, /* l2cache_wb_range */ 586129198Scognet 587129198Scognet /* Other functions */ 588129198Scognet 589129198Scognet cpufunc_nullop, /* flush_prefetchbuf */ 590129198Scognet armv4_drain_writebuf, /* drain_writebuf */ 591129198Scognet cpufunc_nullop, /* flush_brnchtgt_C */ 592129198Scognet (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 593129198Scognet 594129198Scognet (void *)cpufunc_nullop, /* sleep */ 595129198Scognet 596129198Scognet /* Soft functions */ 597129198Scognet 598129198Scognet cpufunc_null_fixup, /* dataabt_fixup */ 599129198Scognet cpufunc_null_fixup, /* prefetchabt_fixup */ 600129198Scognet 601129198Scognet sa110_context_switch, /* context_switch */ 602129198Scognet 603129198Scognet sa110_setup /* cpu setup */ 604236991Simp}; 605129198Scognet#endif /* CPU_SA110 */ 606129198Scognet 607129198Scognet#if defined(CPU_SA1100) || defined(CPU_SA1110) 608129198Scognetstruct cpu_functions sa11x0_cpufuncs = { 609129198Scognet /* CPU functions */ 610129198Scognet 611129198Scognet cpufunc_id, /* id */ 612129198Scognet cpufunc_nullop, /* cpwait */ 613129198Scognet 614129198Scognet /* MMU functions */ 615129198Scognet 616129198Scognet cpufunc_control, /* control */ 617129198Scognet cpufunc_domains, /* domain */ 618129198Scognet sa1_setttb, /* setttb */ 619129198Scognet cpufunc_faultstatus, /* faultstatus */ 620129198Scognet cpufunc_faultaddress, /* faultaddress */ 621129198Scognet 622129198Scognet /* TLB functions */ 623129198Scognet 624129198Scognet armv4_tlb_flushID, /* tlb_flushID */ 625129198Scognet sa1_tlb_flushID_SE, /* tlb_flushID_SE */ 626129198Scognet armv4_tlb_flushI, /* tlb_flushI */ 627129198Scognet (void *)armv4_tlb_flushI, /* tlb_flushI_SE */ 628129198Scognet armv4_tlb_flushD, /* tlb_flushD */ 629129198Scognet armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 630129198Scognet 631129198Scognet /* Cache operations */ 632129198Scognet 633129198Scognet sa1_cache_syncI, /* icache_sync_all */ 634129198Scognet sa1_cache_syncI_rng, /* icache_sync_range */ 635129198Scognet 636129198Scognet sa1_cache_purgeD, /* dcache_wbinv_all */ 637129198Scognet sa1_cache_purgeD_rng, /* dcache_wbinv_range */ 638129198Scognet/*XXX*/ sa1_cache_purgeD_rng, /* dcache_inv_range */ 639129198Scognet sa1_cache_cleanD_rng, /* dcache_wb_range */ 640129198Scognet 641129198Scognet sa1_cache_purgeID, /* idcache_wbinv_all */ 642129198Scognet sa1_cache_purgeID_rng, /* idcache_wbinv_range */ 643171618Scognet cpufunc_nullop, /* l2cache_wbinv_all */ 644171781Scognet (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 645171781Scognet (void *)cpufunc_nullop, /* l2cache_inv_range */ 646171781Scognet (void *)cpufunc_nullop, /* l2cache_wb_range */ 647129198Scognet 648129198Scognet /* Other functions */ 649129198Scognet 650129198Scognet sa11x0_drain_readbuf, /* flush_prefetchbuf */ 651129198Scognet armv4_drain_writebuf, /* drain_writebuf */ 652129198Scognet cpufunc_nullop, /* flush_brnchtgt_C */ 653129198Scognet (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 654129198Scognet 655129198Scognet sa11x0_cpu_sleep, /* sleep */ 656129198Scognet 657129198Scognet /* Soft functions */ 658129198Scognet 659129198Scognet cpufunc_null_fixup, /* dataabt_fixup */ 660129198Scognet cpufunc_null_fixup, /* prefetchabt_fixup */ 661129198Scognet 662129198Scognet sa11x0_context_switch, /* context_switch */ 663129198Scognet 664129198Scognet sa11x0_setup /* cpu setup */ 665236991Simp}; 666129198Scognet#endif /* CPU_SA1100 || CPU_SA1110 */ 667129198Scognet 668129198Scognet#ifdef CPU_IXP12X0 669129198Scognetstruct cpu_functions ixp12x0_cpufuncs = { 670129198Scognet /* CPU functions */ 671129198Scognet 672129198Scognet cpufunc_id, /* id */ 673129198Scognet cpufunc_nullop, /* cpwait */ 674129198Scognet 675129198Scognet /* MMU functions */ 676129198Scognet 677129198Scognet cpufunc_control, /* control */ 678129198Scognet cpufunc_domains, /* domain */ 679129198Scognet sa1_setttb, /* setttb */ 680129198Scognet cpufunc_faultstatus, /* faultstatus */ 681129198Scognet cpufunc_faultaddress, /* faultaddress */ 682129198Scognet 683129198Scognet /* TLB functions */ 684129198Scognet 685129198Scognet armv4_tlb_flushID, /* tlb_flushID */ 686129198Scognet sa1_tlb_flushID_SE, /* tlb_flushID_SE */ 687129198Scognet armv4_tlb_flushI, /* tlb_flushI */ 688129198Scognet (void *)armv4_tlb_flushI, /* tlb_flushI_SE */ 689129198Scognet armv4_tlb_flushD, /* tlb_flushD */ 690129198Scognet armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 691129198Scognet 692129198Scognet /* Cache operations */ 693129198Scognet 694129198Scognet sa1_cache_syncI, /* icache_sync_all */ 695129198Scognet sa1_cache_syncI_rng, /* icache_sync_range */ 696129198Scognet 697129198Scognet sa1_cache_purgeD, /* dcache_wbinv_all */ 698129198Scognet sa1_cache_purgeD_rng, /* dcache_wbinv_range */ 699129198Scognet/*XXX*/ sa1_cache_purgeD_rng, /* dcache_inv_range */ 700129198Scognet sa1_cache_cleanD_rng, /* dcache_wb_range */ 701129198Scognet 702129198Scognet sa1_cache_purgeID, /* idcache_wbinv_all */ 703129198Scognet sa1_cache_purgeID_rng, /* idcache_wbinv_range */ 704171618Scognet cpufunc_nullop, /* l2cache_wbinv_all */ 705171781Scognet (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 706171781Scognet (void *)cpufunc_nullop, /* l2cache_inv_range */ 707171781Scognet (void *)cpufunc_nullop, /* l2cache_wb_range */ 708129198Scognet 709129198Scognet /* Other functions */ 710129198Scognet 711129198Scognet ixp12x0_drain_readbuf, /* flush_prefetchbuf */ 712129198Scognet armv4_drain_writebuf, /* drain_writebuf */ 713129198Scognet cpufunc_nullop, /* flush_brnchtgt_C */ 714129198Scognet (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 715129198Scognet 716129198Scognet (void *)cpufunc_nullop, /* sleep */ 717129198Scognet 718129198Scognet /* Soft functions */ 719129198Scognet 720129198Scognet cpufunc_null_fixup, /* dataabt_fixup */ 721129198Scognet cpufunc_null_fixup, /* prefetchabt_fixup */ 722129198Scognet 723129198Scognet ixp12x0_context_switch, /* context_switch */ 724129198Scognet 725129198Scognet ixp12x0_setup /* cpu setup */ 726236991Simp}; 727129198Scognet#endif /* CPU_IXP12X0 */ 728129198Scognet 729129198Scognet#if defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \ 730161592Scognet defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \ 731161592Scognet defined(CPU_XSCALE_80219) 732161592Scognet 733129198Scognetstruct cpu_functions xscale_cpufuncs = { 734129198Scognet /* CPU functions */ 735129198Scognet 736129198Scognet cpufunc_id, /* id */ 737129198Scognet xscale_cpwait, /* cpwait */ 738129198Scognet 739129198Scognet /* MMU functions */ 740129198Scognet 741129198Scognet xscale_control, /* control */ 742129198Scognet cpufunc_domains, /* domain */ 743129198Scognet xscale_setttb, /* setttb */ 744129198Scognet cpufunc_faultstatus, /* faultstatus */ 745129198Scognet cpufunc_faultaddress, /* faultaddress */ 746129198Scognet 747129198Scognet /* TLB functions */ 748129198Scognet 749129198Scognet armv4_tlb_flushID, /* tlb_flushID */ 750129198Scognet xscale_tlb_flushID_SE, /* tlb_flushID_SE */ 751129198Scognet armv4_tlb_flushI, /* tlb_flushI */ 752129198Scognet (void *)armv4_tlb_flushI, /* tlb_flushI_SE */ 753129198Scognet armv4_tlb_flushD, /* tlb_flushD */ 754129198Scognet armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 755129198Scognet 756129198Scognet /* Cache operations */ 757129198Scognet 758129198Scognet xscale_cache_syncI, /* icache_sync_all */ 759129198Scognet xscale_cache_syncI_rng, /* icache_sync_range */ 760129198Scognet 761129198Scognet xscale_cache_purgeD, /* dcache_wbinv_all */ 762129198Scognet xscale_cache_purgeD_rng, /* dcache_wbinv_range */ 763129198Scognet xscale_cache_flushD_rng, /* dcache_inv_range */ 764129198Scognet xscale_cache_cleanD_rng, /* dcache_wb_range */ 765129198Scognet 766129198Scognet xscale_cache_purgeID, /* idcache_wbinv_all */ 767129198Scognet xscale_cache_purgeID_rng, /* idcache_wbinv_range */ 768171618Scognet cpufunc_nullop, /* l2cache_wbinv_all */ 769171781Scognet (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 770171781Scognet (void *)cpufunc_nullop, /* l2cache_inv_range */ 771171781Scognet (void *)cpufunc_nullop, /* l2cache_wb_range */ 772129198Scognet 773129198Scognet /* Other functions */ 774129198Scognet 775129198Scognet cpufunc_nullop, /* flush_prefetchbuf */ 776129198Scognet armv4_drain_writebuf, /* drain_writebuf */ 777129198Scognet cpufunc_nullop, /* flush_brnchtgt_C */ 778129198Scognet (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 779129198Scognet 780129198Scognet xscale_cpu_sleep, /* sleep */ 781129198Scognet 782129198Scognet /* Soft functions */ 783129198Scognet 784129198Scognet cpufunc_null_fixup, /* dataabt_fixup */ 785129198Scognet cpufunc_null_fixup, /* prefetchabt_fixup */ 786129198Scognet 787129198Scognet xscale_context_switch, /* context_switch */ 788129198Scognet 789129198Scognet xscale_setup /* cpu setup */ 790129198Scognet}; 791129198Scognet#endif 792161592Scognet/* CPU_XSCALE_80200 || CPU_XSCALE_80321 || CPU_XSCALE_PXA2X0 || CPU_XSCALE_IXP425 793161592Scognet CPU_XSCALE_80219 */ 794129198Scognet 795164080Scognet#ifdef CPU_XSCALE_81342 796164080Scognetstruct cpu_functions xscalec3_cpufuncs = { 797164080Scognet /* CPU functions */ 798164080Scognet 799164080Scognet cpufunc_id, /* id */ 800164080Scognet xscale_cpwait, /* cpwait */ 801164080Scognet 802164080Scognet /* MMU functions */ 803164080Scognet 804164080Scognet xscale_control, /* control */ 805164080Scognet cpufunc_domains, /* domain */ 806164080Scognet xscalec3_setttb, /* setttb */ 807164080Scognet cpufunc_faultstatus, /* faultstatus */ 808164080Scognet cpufunc_faultaddress, /* faultaddress */ 809164080Scognet 810164080Scognet /* TLB functions */ 811164080Scognet 812164080Scognet armv4_tlb_flushID, /* tlb_flushID */ 813164080Scognet xscale_tlb_flushID_SE, /* tlb_flushID_SE */ 814164080Scognet armv4_tlb_flushI, /* tlb_flushI */ 815164080Scognet (void *)armv4_tlb_flushI, /* tlb_flushI_SE */ 816164080Scognet armv4_tlb_flushD, /* tlb_flushD */ 817164080Scognet armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 818164080Scognet 819164080Scognet /* Cache operations */ 820164080Scognet 821164080Scognet xscalec3_cache_syncI, /* icache_sync_all */ 822171618Scognet xscalec3_cache_syncI_rng, /* icache_sync_range */ 823164080Scognet 824164080Scognet xscalec3_cache_purgeD, /* dcache_wbinv_all */ 825164080Scognet xscalec3_cache_purgeD_rng, /* dcache_wbinv_range */ 826164080Scognet xscale_cache_flushD_rng, /* dcache_inv_range */ 827164080Scognet xscalec3_cache_cleanD_rng, /* dcache_wb_range */ 828164080Scognet 829171618Scognet xscalec3_cache_purgeID, /* idcache_wbinv_all */ 830164080Scognet xscalec3_cache_purgeID_rng, /* idcache_wbinv_range */ 831171618Scognet xscalec3_l2cache_purge, /* l2cache_wbinv_all */ 832171618Scognet xscalec3_l2cache_purge_rng, /* l2cache_wbinv_range */ 833171618Scognet xscalec3_l2cache_flush_rng, /* l2cache_inv_range */ 834171618Scognet xscalec3_l2cache_clean_rng, /* l2cache_wb_range */ 835164080Scognet 836164080Scognet /* Other functions */ 837164080Scognet 838164080Scognet cpufunc_nullop, /* flush_prefetchbuf */ 839164080Scognet armv4_drain_writebuf, /* drain_writebuf */ 840164080Scognet cpufunc_nullop, /* flush_brnchtgt_C */ 841164080Scognet (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 842164080Scognet 843164080Scognet xscale_cpu_sleep, /* sleep */ 844164080Scognet 845164080Scognet /* Soft functions */ 846164080Scognet 847164080Scognet cpufunc_null_fixup, /* dataabt_fixup */ 848164080Scognet cpufunc_null_fixup, /* prefetchabt_fixup */ 849164080Scognet 850164080Scognet xscalec3_context_switch, /* context_switch */ 851164080Scognet 852164080Scognet xscale_setup /* cpu setup */ 853164080Scognet}; 854164080Scognet#endif /* CPU_XSCALE_81342 */ 855201468Srpaulo 856201468Srpaulo 857207611Skevlo#if defined(CPU_FA526) || defined(CPU_FA626TE) 858201468Srpaulostruct cpu_functions fa526_cpufuncs = { 859201468Srpaulo /* CPU functions */ 860201468Srpaulo 861207611Skevlo cpufunc_id, /* id */ 862207611Skevlo cpufunc_nullop, /* cpwait */ 863201468Srpaulo 864201468Srpaulo /* MMU functions */ 865201468Srpaulo 866207611Skevlo cpufunc_control, /* control */ 867207611Skevlo cpufunc_domains, /* domain */ 868207611Skevlo fa526_setttb, /* setttb */ 869207611Skevlo cpufunc_faultstatus, /* faultstatus */ 870207611Skevlo cpufunc_faultaddress, /* faultaddress */ 871201468Srpaulo 872201468Srpaulo /* TLB functions */ 873201468Srpaulo 874207611Skevlo armv4_tlb_flushID, /* tlb_flushID */ 875207611Skevlo fa526_tlb_flushID_SE, /* tlb_flushID_SE */ 876207611Skevlo armv4_tlb_flushI, /* tlb_flushI */ 877207611Skevlo fa526_tlb_flushI_SE, /* tlb_flushI_SE */ 878207611Skevlo armv4_tlb_flushD, /* tlb_flushD */ 879207611Skevlo armv4_tlb_flushD_SE, /* tlb_flushD_SE */ 880201468Srpaulo 881201468Srpaulo /* Cache operations */ 882201468Srpaulo 883207611Skevlo fa526_icache_sync_all, /* icache_sync_all */ 884207611Skevlo fa526_icache_sync_range, /* icache_sync_range */ 885201468Srpaulo 886207611Skevlo fa526_dcache_wbinv_all, /* dcache_wbinv_all */ 887207611Skevlo fa526_dcache_wbinv_range, /* dcache_wbinv_range */ 888207611Skevlo fa526_dcache_inv_range, /* dcache_inv_range */ 889207611Skevlo fa526_dcache_wb_range, /* dcache_wb_range */ 890201468Srpaulo 891207611Skevlo fa526_idcache_wbinv_all, /* idcache_wbinv_all */ 892207611Skevlo fa526_idcache_wbinv_range, /* idcache_wbinv_range */ 893207611Skevlo cpufunc_nullop, /* l2cache_wbinv_all */ 894207611Skevlo (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 895207611Skevlo (void *)cpufunc_nullop, /* l2cache_inv_range */ 896207611Skevlo (void *)cpufunc_nullop, /* l2cache_wb_range */ 897201468Srpaulo 898201468Srpaulo /* Other functions */ 899201468Srpaulo 900207611Skevlo fa526_flush_prefetchbuf, /* flush_prefetchbuf */ 901207611Skevlo armv4_drain_writebuf, /* drain_writebuf */ 902207611Skevlo cpufunc_nullop, /* flush_brnchtgt_C */ 903207611Skevlo fa526_flush_brnchtgt_E, /* flush_brnchtgt_E */ 904201468Srpaulo 905207611Skevlo fa526_cpu_sleep, /* sleep */ 906201468Srpaulo 907201468Srpaulo /* Soft functions */ 908201468Srpaulo 909207611Skevlo cpufunc_null_fixup, /* dataabt_fixup */ 910207611Skevlo cpufunc_null_fixup, /* prefetchabt_fixup */ 911201468Srpaulo 912207611Skevlo fa526_context_switch, /* context_switch */ 913201468Srpaulo 914207611Skevlo fa526_setup /* cpu setup */ 915236991Simp}; 916207611Skevlo#endif /* CPU_FA526 || CPU_FA626TE */ 917201468Srpaulo 918244480Sgonzo#if defined(CPU_ARM1136) 919244480Sgonzostruct cpu_functions arm1136_cpufuncs = { 920239701Sgonzo /* CPU functions */ 921239701Sgonzo 922239701Sgonzo cpufunc_id, /* id */ 923244480Sgonzo cpufunc_nullop, /* cpwait */ 924239701Sgonzo 925239701Sgonzo /* MMU functions */ 926239701Sgonzo 927239701Sgonzo cpufunc_control, /* control */ 928239701Sgonzo cpufunc_domains, /* Domain */ 929244480Sgonzo arm11x6_setttb, /* Setttb */ 930239701Sgonzo cpufunc_faultstatus, /* Faultstatus */ 931239701Sgonzo cpufunc_faultaddress, /* Faultaddress */ 932239701Sgonzo 933239701Sgonzo /* TLB functions */ 934239701Sgonzo 935239701Sgonzo arm11_tlb_flushID, /* tlb_flushID */ 936239701Sgonzo arm11_tlb_flushID_SE, /* tlb_flushID_SE */ 937239701Sgonzo arm11_tlb_flushI, /* tlb_flushI */ 938239701Sgonzo arm11_tlb_flushI_SE, /* tlb_flushI_SE */ 939239701Sgonzo arm11_tlb_flushD, /* tlb_flushD */ 940239701Sgonzo arm11_tlb_flushD_SE, /* tlb_flushD_SE */ 941239701Sgonzo 942239701Sgonzo /* Cache operations */ 943239701Sgonzo 944244480Sgonzo arm11x6_icache_sync_all, /* icache_sync_all */ 945244480Sgonzo arm11x6_icache_sync_range, /* icache_sync_range */ 946239701Sgonzo 947244480Sgonzo arm11x6_dcache_wbinv_all, /* dcache_wbinv_all */ 948239701Sgonzo armv6_dcache_wbinv_range, /* dcache_wbinv_range */ 949239701Sgonzo armv6_dcache_inv_range, /* dcache_inv_range */ 950239701Sgonzo armv6_dcache_wb_range, /* dcache_wb_range */ 951239701Sgonzo 952244480Sgonzo arm11x6_idcache_wbinv_all, /* idcache_wbinv_all */ 953244480Sgonzo arm11x6_idcache_wbinv_range, /* idcache_wbinv_range */ 954239701Sgonzo 955244480Sgonzo (void *)cpufunc_nullop, /* l2cache_wbinv_all */ 956239701Sgonzo (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 957239701Sgonzo (void *)cpufunc_nullop, /* l2cache_inv_range */ 958239701Sgonzo (void *)cpufunc_nullop, /* l2cache_wb_range */ 959239701Sgonzo 960239701Sgonzo /* Other functions */ 961239701Sgonzo 962244480Sgonzo arm11x6_flush_prefetchbuf, /* flush_prefetchbuf */ 963239701Sgonzo arm11_drain_writebuf, /* drain_writebuf */ 964239701Sgonzo cpufunc_nullop, /* flush_brnchtgt_C */ 965239701Sgonzo (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 966239701Sgonzo 967244480Sgonzo arm11_sleep, /* sleep */ 968239701Sgonzo 969239701Sgonzo /* Soft functions */ 970239701Sgonzo 971239701Sgonzo cpufunc_null_fixup, /* dataabt_fixup */ 972239701Sgonzo cpufunc_null_fixup, /* prefetchabt_fixup */ 973239701Sgonzo 974239701Sgonzo arm11_context_switch, /* context_switch */ 975239701Sgonzo 976244480Sgonzo arm11x6_setup /* cpu setup */ 977239701Sgonzo}; 978244480Sgonzo#endif /* CPU_ARM1136 */ 979244480Sgonzo#if defined(CPU_ARM1176) 980244480Sgonzostruct cpu_functions arm1176_cpufuncs = { 981244480Sgonzo /* CPU functions */ 982244480Sgonzo 983244480Sgonzo cpufunc_id, /* id */ 984244480Sgonzo cpufunc_nullop, /* cpwait */ 985244480Sgonzo 986244480Sgonzo /* MMU functions */ 987244480Sgonzo 988244480Sgonzo cpufunc_control, /* control */ 989244480Sgonzo cpufunc_domains, /* Domain */ 990244480Sgonzo arm11x6_setttb, /* Setttb */ 991244480Sgonzo cpufunc_faultstatus, /* Faultstatus */ 992244480Sgonzo cpufunc_faultaddress, /* Faultaddress */ 993244480Sgonzo 994244480Sgonzo /* TLB functions */ 995244480Sgonzo 996244480Sgonzo arm11_tlb_flushID, /* tlb_flushID */ 997244480Sgonzo arm11_tlb_flushID_SE, /* tlb_flushID_SE */ 998244480Sgonzo arm11_tlb_flushI, /* tlb_flushI */ 999244480Sgonzo arm11_tlb_flushI_SE, /* tlb_flushI_SE */ 1000244480Sgonzo arm11_tlb_flushD, /* tlb_flushD */ 1001244480Sgonzo arm11_tlb_flushD_SE, /* tlb_flushD_SE */ 1002244480Sgonzo 1003244480Sgonzo /* Cache operations */ 1004244480Sgonzo 1005244480Sgonzo arm11x6_icache_sync_all, /* icache_sync_all */ 1006244480Sgonzo arm11x6_icache_sync_range, /* icache_sync_range */ 1007244480Sgonzo 1008244480Sgonzo arm11x6_dcache_wbinv_all, /* dcache_wbinv_all */ 1009244480Sgonzo armv6_dcache_wbinv_range, /* dcache_wbinv_range */ 1010244480Sgonzo armv6_dcache_inv_range, /* dcache_inv_range */ 1011244480Sgonzo armv6_dcache_wb_range, /* dcache_wb_range */ 1012244480Sgonzo 1013244480Sgonzo arm11x6_idcache_wbinv_all, /* idcache_wbinv_all */ 1014244480Sgonzo arm11x6_idcache_wbinv_range, /* idcache_wbinv_range */ 1015244480Sgonzo 1016244480Sgonzo (void *)cpufunc_nullop, /* l2cache_wbinv_all */ 1017244480Sgonzo (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 1018244480Sgonzo (void *)cpufunc_nullop, /* l2cache_inv_range */ 1019244480Sgonzo (void *)cpufunc_nullop, /* l2cache_wb_range */ 1020244480Sgonzo 1021244480Sgonzo /* Other functions */ 1022244480Sgonzo 1023244480Sgonzo arm11x6_flush_prefetchbuf, /* flush_prefetchbuf */ 1024244480Sgonzo arm11_drain_writebuf, /* drain_writebuf */ 1025244480Sgonzo cpufunc_nullop, /* flush_brnchtgt_C */ 1026244480Sgonzo (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 1027244480Sgonzo 1028244480Sgonzo arm11x6_sleep, /* sleep */ 1029244480Sgonzo 1030244480Sgonzo /* Soft functions */ 1031244480Sgonzo 1032244480Sgonzo cpufunc_null_fixup, /* dataabt_fixup */ 1033244480Sgonzo cpufunc_null_fixup, /* prefetchabt_fixup */ 1034244480Sgonzo 1035244480Sgonzo arm11_context_switch, /* context_switch */ 1036244480Sgonzo 1037244480Sgonzo arm11x6_setup /* cpu setup */ 1038244480Sgonzo}; 1039244480Sgonzo#endif /*CPU_ARM1176 */ 1040239701Sgonzo 1041259640Sganbold#if defined(CPU_CORTEXA) || defined(CPU_KRAIT) 1042239268Sgonzostruct cpu_functions cortexa_cpufuncs = { 1043239268Sgonzo /* CPU functions */ 1044239268Sgonzo 1045239268Sgonzo cpufunc_id, /* id */ 1046239268Sgonzo cpufunc_nullop, /* cpwait */ 1047239268Sgonzo 1048239268Sgonzo /* MMU functions */ 1049239268Sgonzo 1050239268Sgonzo cpufunc_control, /* control */ 1051239268Sgonzo cpufunc_domains, /* Domain */ 1052239268Sgonzo armv7_setttb, /* Setttb */ 1053239268Sgonzo cpufunc_faultstatus, /* Faultstatus */ 1054239268Sgonzo cpufunc_faultaddress, /* Faultaddress */ 1055239268Sgonzo 1056239268Sgonzo /* TLB functions */ 1057239268Sgonzo 1058243024Scognet armv7_tlb_flushID, /* tlb_flushID */ 1059239268Sgonzo armv7_tlb_flushID_SE, /* tlb_flushID_SE */ 1060239268Sgonzo arm11_tlb_flushI, /* tlb_flushI */ 1061239268Sgonzo arm11_tlb_flushI_SE, /* tlb_flushI_SE */ 1062239268Sgonzo arm11_tlb_flushD, /* tlb_flushD */ 1063239268Sgonzo arm11_tlb_flushD_SE, /* tlb_flushD_SE */ 1064239268Sgonzo 1065239268Sgonzo /* Cache operations */ 1066239268Sgonzo 1067239268Sgonzo armv7_idcache_wbinv_all, /* icache_sync_all */ 1068239268Sgonzo armv7_icache_sync_range, /* icache_sync_range */ 1069239268Sgonzo 1070239268Sgonzo armv7_dcache_wbinv_all, /* dcache_wbinv_all */ 1071239268Sgonzo armv7_dcache_wbinv_range, /* dcache_wbinv_range */ 1072239268Sgonzo armv7_dcache_inv_range, /* dcache_inv_range */ 1073239268Sgonzo armv7_dcache_wb_range, /* dcache_wb_range */ 1074239268Sgonzo 1075239268Sgonzo armv7_idcache_wbinv_all, /* idcache_wbinv_all */ 1076239268Sgonzo armv7_idcache_wbinv_range, /* idcache_wbinv_range */ 1077239268Sgonzo 1078243026Scognet /* 1079243026Scognet * Note: For CPUs using the PL310 the L2 ops are filled in when the 1080239268Sgonzo * L2 cache controller is actually enabled. 1081239268Sgonzo */ 1082239268Sgonzo cpufunc_nullop, /* l2cache_wbinv_all */ 1083239268Sgonzo (void *)cpufunc_nullop, /* l2cache_wbinv_range */ 1084239268Sgonzo (void *)cpufunc_nullop, /* l2cache_inv_range */ 1085239268Sgonzo (void *)cpufunc_nullop, /* l2cache_wb_range */ 1086239268Sgonzo 1087239268Sgonzo /* Other functions */ 1088239268Sgonzo 1089239268Sgonzo cpufunc_nullop, /* flush_prefetchbuf */ 1090245478Scognet armv7_drain_writebuf, /* drain_writebuf */ 1091239268Sgonzo cpufunc_nullop, /* flush_brnchtgt_C */ 1092239268Sgonzo (void *)cpufunc_nullop, /* flush_brnchtgt_E */ 1093239268Sgonzo 1094239268Sgonzo arm11_sleep, /* sleep */ 1095239268Sgonzo 1096239268Sgonzo /* Soft functions */ 1097239268Sgonzo 1098239268Sgonzo cpufunc_null_fixup, /* dataabt_fixup */ 1099239268Sgonzo cpufunc_null_fixup, /* prefetchabt_fixup */ 1100239268Sgonzo 1101245478Scognet armv7_context_switch, /* context_switch */ 1102239268Sgonzo 1103239268Sgonzo cortexa_setup /* cpu setup */ 1104239268Sgonzo}; 1105239268Sgonzo#endif /* CPU_CORTEXA */ 1106201468Srpaulo 1107129198Scognet/* 1108129198Scognet * Global constants also used by locore.s 1109129198Scognet */ 1110129198Scognet 1111129198Scognetstruct cpu_functions cpufuncs; 1112129198Scognetu_int cputype; 1113129198Scognetu_int cpu_reset_needs_v4_MMU_disable; /* flag used in locore.s */ 1114129198Scognet 1115207611Skevlo#if defined(CPU_ARM7TDMI) || defined(CPU_ARM8) || defined(CPU_ARM9) || \ 1116244480Sgonzo defined (CPU_ARM9E) || defined (CPU_ARM10) || defined (CPU_ARM1136) || \ 1117244480Sgonzo defined(CPU_ARM1176) || defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \ 1118207611Skevlo defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \ 1119239268Sgonzo defined(CPU_FA526) || defined(CPU_FA626TE) || defined(CPU_MV_PJ4B) || \ 1120239268Sgonzo defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342) || \ 1121259640Sganbold defined(CPU_CORTEXA) || defined(CPU_KRAIT) 1122161592Scognet 1123137498Strhodesstatic void get_cachetype_cp15(void); 1124129198Scognet 1125129198Scognet/* Additional cache information local to this file. Log2 of some of the 1126129198Scognet above numbers. */ 1127129198Scognetstatic int arm_dcache_l2_nsets; 1128129198Scognetstatic int arm_dcache_l2_assoc; 1129129198Scognetstatic int arm_dcache_l2_linesize; 1130129198Scognet 1131129198Scognetstatic void 1132129198Scognetget_cachetype_cp15() 1133129198Scognet{ 1134239268Sgonzo u_int ctype, isize, dsize, cpuid; 1135239268Sgonzo u_int clevel, csize, i, sel; 1136129198Scognet u_int multiplier; 1137239268Sgonzo u_char type; 1138129198Scognet 1139129198Scognet __asm __volatile("mrc p15, 0, %0, c0, c0, 1" 1140129198Scognet : "=r" (ctype)); 1141129198Scognet 1142239268Sgonzo cpuid = cpufunc_id(); 1143129198Scognet /* 1144129198Scognet * ...and thus spake the ARM ARM: 1145129198Scognet * 1146129198Scognet * If an <opcode2> value corresponding to an unimplemented or 1147129198Scognet * reserved ID register is encountered, the System Control 1148129198Scognet * processor returns the value of the main ID register. 1149129198Scognet */ 1150239268Sgonzo if (ctype == cpuid) 1151129198Scognet goto out; 1152129198Scognet 1153239268Sgonzo if (CPU_CT_FORMAT(ctype) == CPU_CT_ARMV7) { 1154239268Sgonzo __asm __volatile("mrc p15, 1, %0, c0, c0, 1" 1155239268Sgonzo : "=r" (clevel)); 1156239268Sgonzo arm_cache_level = clevel; 1157239268Sgonzo arm_cache_loc = CPU_CLIDR_LOC(arm_cache_level); 1158239268Sgonzo i = 0; 1159239268Sgonzo while ((type = (clevel & 0x7)) && i < 7) { 1160239268Sgonzo if (type == CACHE_DCACHE || type == CACHE_UNI_CACHE || 1161239268Sgonzo type == CACHE_SEP_CACHE) { 1162239268Sgonzo sel = i << 1; 1163239268Sgonzo __asm __volatile("mcr p15, 2, %0, c0, c0, 0" 1164239268Sgonzo : : "r" (sel)); 1165239268Sgonzo __asm __volatile("mrc p15, 1, %0, c0, c0, 0" 1166239268Sgonzo : "=r" (csize)); 1167239268Sgonzo arm_cache_type[sel] = csize; 1168239268Sgonzo arm_dcache_align = 1 << 1169239268Sgonzo (CPUV7_CT_xSIZE_LEN(csize) + 4); 1170239268Sgonzo arm_dcache_align_mask = arm_dcache_align - 1; 1171239268Sgonzo } 1172239268Sgonzo if (type == CACHE_ICACHE || type == CACHE_SEP_CACHE) { 1173239268Sgonzo sel = (i << 1) | 1; 1174239268Sgonzo __asm __volatile("mcr p15, 2, %0, c0, c0, 0" 1175239268Sgonzo : : "r" (sel)); 1176239268Sgonzo __asm __volatile("mrc p15, 1, %0, c0, c0, 0" 1177239268Sgonzo : "=r" (csize)); 1178239268Sgonzo arm_cache_type[sel] = csize; 1179239268Sgonzo } 1180239268Sgonzo i++; 1181239268Sgonzo clevel >>= 3; 1182239268Sgonzo } 1183239268Sgonzo } else { 1184239268Sgonzo if ((ctype & CPU_CT_S) == 0) 1185239268Sgonzo arm_pcache_unified = 1; 1186129198Scognet 1187239268Sgonzo /* 1188239268Sgonzo * If you want to know how this code works, go read the ARM ARM. 1189239268Sgonzo */ 1190129198Scognet 1191239268Sgonzo arm_pcache_type = CPU_CT_CTYPE(ctype); 1192129198Scognet 1193239268Sgonzo if (arm_pcache_unified == 0) { 1194239268Sgonzo isize = CPU_CT_ISIZE(ctype); 1195239268Sgonzo multiplier = (isize & CPU_CT_xSIZE_M) ? 3 : 2; 1196239268Sgonzo arm_picache_line_size = 1U << (CPU_CT_xSIZE_LEN(isize) + 3); 1197239268Sgonzo if (CPU_CT_xSIZE_ASSOC(isize) == 0) { 1198239268Sgonzo if (isize & CPU_CT_xSIZE_M) 1199239268Sgonzo arm_picache_line_size = 0; /* not present */ 1200239268Sgonzo else 1201239268Sgonzo arm_picache_ways = 1; 1202239268Sgonzo } else { 1203239268Sgonzo arm_picache_ways = multiplier << 1204239268Sgonzo (CPU_CT_xSIZE_ASSOC(isize) - 1); 1205239268Sgonzo } 1206239268Sgonzo arm_picache_size = multiplier << (CPU_CT_xSIZE_SIZE(isize) + 8); 1207239268Sgonzo } 1208239268Sgonzo 1209239268Sgonzo dsize = CPU_CT_DSIZE(ctype); 1210239268Sgonzo multiplier = (dsize & CPU_CT_xSIZE_M) ? 3 : 2; 1211239268Sgonzo arm_pdcache_line_size = 1U << (CPU_CT_xSIZE_LEN(dsize) + 3); 1212239268Sgonzo if (CPU_CT_xSIZE_ASSOC(dsize) == 0) { 1213239268Sgonzo if (dsize & CPU_CT_xSIZE_M) 1214239268Sgonzo arm_pdcache_line_size = 0; /* not present */ 1215129198Scognet else 1216239268Sgonzo arm_pdcache_ways = 1; 1217129198Scognet } else { 1218239268Sgonzo arm_pdcache_ways = multiplier << 1219239268Sgonzo (CPU_CT_xSIZE_ASSOC(dsize) - 1); 1220129198Scognet } 1221239268Sgonzo arm_pdcache_size = multiplier << (CPU_CT_xSIZE_SIZE(dsize) + 8); 1222129198Scognet 1223239268Sgonzo arm_dcache_align = arm_pdcache_line_size; 1224129198Scognet 1225239268Sgonzo arm_dcache_l2_assoc = CPU_CT_xSIZE_ASSOC(dsize) + multiplier - 2; 1226239268Sgonzo arm_dcache_l2_linesize = CPU_CT_xSIZE_LEN(dsize) + 3; 1227239268Sgonzo arm_dcache_l2_nsets = 6 + CPU_CT_xSIZE_SIZE(dsize) - 1228239268Sgonzo CPU_CT_xSIZE_ASSOC(dsize) - CPU_CT_xSIZE_LEN(dsize); 1229129198Scognet 1230239268Sgonzo out: 1231239268Sgonzo arm_dcache_align_mask = arm_dcache_align - 1; 1232239268Sgonzo } 1233129198Scognet} 1234129198Scognet#endif /* ARM7TDMI || ARM8 || ARM9 || XSCALE */ 1235129198Scognet 1236146619Scognet#if defined(CPU_SA110) || defined(CPU_SA1100) || defined(CPU_SA1110) || \ 1237146619Scognet defined(CPU_IXP12X0) 1238129198Scognet/* Cache information for CPUs without cache type registers. */ 1239129198Scognetstruct cachetab { 1240129198Scognet u_int32_t ct_cpuid; 1241129198Scognet int ct_pcache_type; 1242129198Scognet int ct_pcache_unified; 1243129198Scognet int ct_pdcache_size; 1244129198Scognet int ct_pdcache_line_size; 1245129198Scognet int ct_pdcache_ways; 1246129198Scognet int ct_picache_size; 1247129198Scognet int ct_picache_line_size; 1248129198Scognet int ct_picache_ways; 1249129198Scognet}; 1250129198Scognet 1251129198Scognetstruct cachetab cachetab[] = { 1252129198Scognet /* cpuid, cache type, u, dsiz, ls, wy, isiz, ls, wy */ 1253129198Scognet /* XXX is this type right for SA-1? */ 1254129198Scognet { CPU_ID_SA110, CPU_CT_CTYPE_WB1, 0, 16384, 32, 32, 16384, 32, 32 }, 1255129198Scognet { CPU_ID_SA1100, CPU_CT_CTYPE_WB1, 0, 8192, 32, 32, 16384, 32, 32 }, 1256129198Scognet { CPU_ID_SA1110, CPU_CT_CTYPE_WB1, 0, 8192, 32, 32, 16384, 32, 32 }, 1257129198Scognet { CPU_ID_IXP1200, CPU_CT_CTYPE_WB1, 0, 16384, 32, 32, 16384, 32, 32 }, /* XXX */ 1258129198Scognet { 0, 0, 0, 0, 0, 0, 0, 0} 1259129198Scognet}; 1260129198Scognet 1261137498Strhodesstatic void get_cachetype_table(void); 1262129198Scognet 1263129198Scognetstatic void 1264129198Scognetget_cachetype_table() 1265129198Scognet{ 1266129198Scognet int i; 1267129198Scognet u_int32_t cpuid = cpufunc_id(); 1268129198Scognet 1269129198Scognet for (i = 0; cachetab[i].ct_cpuid != 0; i++) { 1270129198Scognet if (cachetab[i].ct_cpuid == (cpuid & CPU_ID_CPU_MASK)) { 1271129198Scognet arm_pcache_type = cachetab[i].ct_pcache_type; 1272129198Scognet arm_pcache_unified = cachetab[i].ct_pcache_unified; 1273129198Scognet arm_pdcache_size = cachetab[i].ct_pdcache_size; 1274129198Scognet arm_pdcache_line_size = 1275129198Scognet cachetab[i].ct_pdcache_line_size; 1276129198Scognet arm_pdcache_ways = cachetab[i].ct_pdcache_ways; 1277129198Scognet arm_picache_size = cachetab[i].ct_picache_size; 1278129198Scognet arm_picache_line_size = 1279129198Scognet cachetab[i].ct_picache_line_size; 1280129198Scognet arm_picache_ways = cachetab[i].ct_picache_ways; 1281129198Scognet } 1282129198Scognet } 1283129198Scognet arm_dcache_align = arm_pdcache_line_size; 1284129198Scognet 1285129198Scognet arm_dcache_align_mask = arm_dcache_align - 1; 1286129198Scognet} 1287129198Scognet 1288146619Scognet#endif /* SA110 || SA1100 || SA1111 || IXP12X0 */ 1289129198Scognet 1290129198Scognet/* 1291129198Scognet * Cannot panic here as we may not have a console yet ... 1292129198Scognet */ 1293129198Scognet 1294129198Scognetint 1295129198Scognetset_cpufuncs() 1296129198Scognet{ 1297129198Scognet cputype = cpufunc_id(); 1298129198Scognet cputype &= CPU_ID_CPU_MASK; 1299129198Scognet 1300129198Scognet /* 1301129198Scognet * NOTE: cpu_do_powersave defaults to off. If we encounter a 1302129198Scognet * CPU type where we want to use it by default, then we set it. 1303129198Scognet */ 1304129198Scognet 1305129198Scognet#ifdef CPU_ARM7TDMI 1306129198Scognet if ((cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_ARM_LTD && 1307129198Scognet CPU_ID_IS7(cputype) && 1308129198Scognet (cputype & CPU_ID_7ARCH_MASK) == CPU_ID_7ARCH_V4T) { 1309129198Scognet cpufuncs = arm7tdmi_cpufuncs; 1310129198Scognet cpu_reset_needs_v4_MMU_disable = 0; 1311129198Scognet get_cachetype_cp15(); 1312129198Scognet pmap_pte_init_generic(); 1313166655Scognet goto out; 1314129198Scognet } 1315129198Scognet#endif 1316129198Scognet#ifdef CPU_ARM8 1317129198Scognet if ((cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_ARM_LTD && 1318129198Scognet (cputype & 0x0000f000) == 0x00008000) { 1319129198Scognet cpufuncs = arm8_cpufuncs; 1320129198Scognet cpu_reset_needs_v4_MMU_disable = 0; /* XXX correct? */ 1321129198Scognet get_cachetype_cp15(); 1322129198Scognet pmap_pte_init_arm8(); 1323166655Scognet goto out; 1324129198Scognet } 1325129198Scognet#endif /* CPU_ARM8 */ 1326129198Scognet#ifdef CPU_ARM9 1327129198Scognet if (((cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_ARM_LTD || 1328129198Scognet (cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_TI) && 1329129198Scognet (cputype & 0x0000f000) == 0x00009000) { 1330129198Scognet cpufuncs = arm9_cpufuncs; 1331129198Scognet cpu_reset_needs_v4_MMU_disable = 1; /* V4 or higher */ 1332129198Scognet get_cachetype_cp15(); 1333146605Scognet arm9_dcache_sets_inc = 1U << arm_dcache_l2_linesize; 1334146605Scognet arm9_dcache_sets_max = (1U << (arm_dcache_l2_linesize + 1335146605Scognet arm_dcache_l2_nsets)) - arm9_dcache_sets_inc; 1336146605Scognet arm9_dcache_index_inc = 1U << (32 - arm_dcache_l2_assoc); 1337146605Scognet arm9_dcache_index_max = 0U - arm9_dcache_index_inc; 1338137270Scognet#ifdef ARM9_CACHE_WRITE_THROUGH 1339129198Scognet pmap_pte_init_arm9(); 1340137270Scognet#else 1341137270Scognet pmap_pte_init_generic(); 1342137270Scognet#endif 1343166655Scognet goto out; 1344129198Scognet } 1345129198Scognet#endif /* CPU_ARM9 */ 1346172738Simp#if defined(CPU_ARM9E) || defined(CPU_ARM10) 1347239268Sgonzo if (cputype == CPU_ID_MV88FR131 || cputype == CPU_ID_MV88FR571_VD || 1348183835Sraj cputype == CPU_ID_MV88FR571_41) { 1349239268Sgonzo uint32_t sheeva_ctrl; 1350183835Sraj 1351239268Sgonzo sheeva_ctrl = (MV_DC_STREAM_ENABLE | MV_BTB_DISABLE | 1352239268Sgonzo MV_L2_ENABLE); 1353239268Sgonzo /* 1354239268Sgonzo * Workaround for Marvell MV78100 CPU: Cache prefetch 1355239268Sgonzo * mechanism may affect the cache coherency validity, 1356239268Sgonzo * so it needs to be disabled. 1357239268Sgonzo * 1358239268Sgonzo * Refer to errata document MV-S501058-00C.pdf (p. 3.1 1359239268Sgonzo * L2 Prefetching Mechanism) for details. 1360239268Sgonzo */ 1361239268Sgonzo if (cputype == CPU_ID_MV88FR571_VD || 1362239268Sgonzo cputype == CPU_ID_MV88FR571_41) 1363239268Sgonzo sheeva_ctrl |= MV_L2_PREFETCH_DISABLE; 1364212825Smav 1365239268Sgonzo sheeva_control_ext(0xffffffff & ~MV_WA_ENABLE, sheeva_ctrl); 1366183835Sraj 1367239268Sgonzo cpufuncs = sheeva_cpufuncs; 1368172738Simp get_cachetype_cp15(); 1369172738Simp pmap_pte_init_generic(); 1370174058Scognet goto out; 1371239268Sgonzo } else if (cputype == CPU_ID_ARM926EJS || cputype == CPU_ID_ARM1026EJS) { 1372239268Sgonzo cpufuncs = armv5_ec_cpufuncs; 1373239268Sgonzo get_cachetype_cp15(); 1374239268Sgonzo pmap_pte_init_generic(); 1375239268Sgonzo goto out; 1376172738Simp } 1377172738Simp#endif /* CPU_ARM9E || CPU_ARM10 */ 1378129198Scognet#ifdef CPU_ARM10 1379129198Scognet if (/* cputype == CPU_ID_ARM1020T || */ 1380129198Scognet cputype == CPU_ID_ARM1020E) { 1381129198Scognet /* 1382129198Scognet * Select write-through cacheing (this isn't really an 1383129198Scognet * option on ARM1020T). 1384129198Scognet */ 1385129198Scognet cpufuncs = arm10_cpufuncs; 1386129198Scognet cpu_reset_needs_v4_MMU_disable = 1; /* V4 or higher */ 1387129198Scognet get_cachetype_cp15(); 1388129198Scognet arm10_dcache_sets_inc = 1U << arm_dcache_l2_linesize; 1389236991Simp arm10_dcache_sets_max = 1390129198Scognet (1U << (arm_dcache_l2_linesize + arm_dcache_l2_nsets)) - 1391129198Scognet arm10_dcache_sets_inc; 1392129198Scognet arm10_dcache_index_inc = 1U << (32 - arm_dcache_l2_assoc); 1393129198Scognet arm10_dcache_index_max = 0U - arm10_dcache_index_inc; 1394129198Scognet pmap_pte_init_generic(); 1395166655Scognet goto out; 1396129198Scognet } 1397129198Scognet#endif /* CPU_ARM10 */ 1398244480Sgonzo#if defined(CPU_ARM1136) || defined(CPU_ARM1176) 1399244480Sgonzo if (cputype == CPU_ID_ARM1136JS 1400244480Sgonzo || cputype == CPU_ID_ARM1136JSR1 1401244480Sgonzo || cputype == CPU_ID_ARM1176JZS) { 1402244480Sgonzo#ifdef CPU_ARM1136 1403244480Sgonzo if (cputype == CPU_ID_ARM1136JS 1404244480Sgonzo || cputype == CPU_ID_ARM1136JSR1) 1405244480Sgonzo cpufuncs = arm1136_cpufuncs; 1406244480Sgonzo#endif 1407244480Sgonzo#ifdef CPU_ARM1176 1408244480Sgonzo if (cputype == CPU_ID_ARM1176JZS) 1409244480Sgonzo cpufuncs = arm1176_cpufuncs; 1410244480Sgonzo#endif 1411244480Sgonzo cpu_reset_needs_v4_MMU_disable = 1; /* V4 or higher */ 1412244480Sgonzo get_cachetype_cp15(); 1413239701Sgonzo 1414244480Sgonzo pmap_pte_init_mmu_v6(); 1415244480Sgonzo 1416244480Sgonzo goto out; 1417244480Sgonzo } 1418244480Sgonzo#endif /* CPU_ARM1136 || CPU_ARM1176 */ 1419259640Sganbold#if defined(CPU_CORTEXA) || defined(CPU_KRAIT) 1420256629Sbr if (cputype == CPU_ID_CORTEXA5 || 1421256629Sbr cputype == CPU_ID_CORTEXA7 || 1422253857Sganbold cputype == CPU_ID_CORTEXA8R1 || 1423239268Sgonzo cputype == CPU_ID_CORTEXA8R2 || 1424239268Sgonzo cputype == CPU_ID_CORTEXA8R3 || 1425239268Sgonzo cputype == CPU_ID_CORTEXA9R1 || 1426249999Swkoszek cputype == CPU_ID_CORTEXA9R2 || 1427252361Sray cputype == CPU_ID_CORTEXA9R3 || 1428259640Sganbold cputype == CPU_ID_CORTEXA15 || 1429259640Sganbold cputype == CPU_ID_KRAIT ) { 1430239268Sgonzo cpufuncs = cortexa_cpufuncs; 1431239268Sgonzo cpu_reset_needs_v4_MMU_disable = 1; /* V4 or higher */ 1432239268Sgonzo get_cachetype_cp15(); 1433239268Sgonzo 1434239268Sgonzo pmap_pte_init_mmu_v6(); 1435239268Sgonzo /* Use powersave on this CPU. */ 1436239268Sgonzo cpu_do_powersave = 1; 1437239268Sgonzo goto out; 1438239268Sgonzo } 1439239268Sgonzo#endif /* CPU_CORTEXA */ 1440239268Sgonzo 1441239268Sgonzo#if defined(CPU_MV_PJ4B) 1442257281Szbb if (cputype == CPU_ID_MV88SV581X_V7 || 1443240486Sgber cputype == CPU_ID_MV88SV584X_V7 || 1444239268Sgonzo cputype == CPU_ID_ARM_88SV581X_V7) { 1445257281Szbb cpufuncs = pj4bv7_cpufuncs; 1446239268Sgonzo get_cachetype_cp15(); 1447239268Sgonzo pmap_pte_init_mmu_v6(); 1448239268Sgonzo goto out; 1449239268Sgonzo } 1450239268Sgonzo#endif /* CPU_MV_PJ4B */ 1451129198Scognet#ifdef CPU_SA110 1452129198Scognet if (cputype == CPU_ID_SA110) { 1453129198Scognet cpufuncs = sa110_cpufuncs; 1454129198Scognet cpu_reset_needs_v4_MMU_disable = 1; /* SA needs it */ 1455129198Scognet get_cachetype_table(); 1456129198Scognet pmap_pte_init_sa1(); 1457166655Scognet goto out; 1458129198Scognet } 1459129198Scognet#endif /* CPU_SA110 */ 1460129198Scognet#ifdef CPU_SA1100 1461129198Scognet if (cputype == CPU_ID_SA1100) { 1462129198Scognet cpufuncs = sa11x0_cpufuncs; 1463129198Scognet cpu_reset_needs_v4_MMU_disable = 1; /* SA needs it */ 1464129198Scognet get_cachetype_table(); 1465129198Scognet pmap_pte_init_sa1(); 1466129198Scognet /* Use powersave on this CPU. */ 1467129198Scognet cpu_do_powersave = 1; 1468129198Scognet 1469166655Scognet goto out; 1470129198Scognet } 1471129198Scognet#endif /* CPU_SA1100 */ 1472129198Scognet#ifdef CPU_SA1110 1473129198Scognet if (cputype == CPU_ID_SA1110) { 1474129198Scognet cpufuncs = sa11x0_cpufuncs; 1475129198Scognet cpu_reset_needs_v4_MMU_disable = 1; /* SA needs it */ 1476129198Scognet get_cachetype_table(); 1477129198Scognet pmap_pte_init_sa1(); 1478129198Scognet /* Use powersave on this CPU. */ 1479129198Scognet cpu_do_powersave = 1; 1480129198Scognet 1481166655Scognet goto out; 1482129198Scognet } 1483129198Scognet#endif /* CPU_SA1110 */ 1484207611Skevlo#if defined(CPU_FA526) || defined(CPU_FA626TE) 1485207611Skevlo if (cputype == CPU_ID_FA526 || cputype == CPU_ID_FA626TE) { 1486201468Srpaulo cpufuncs = fa526_cpufuncs; 1487201468Srpaulo cpu_reset_needs_v4_MMU_disable = 1; /* SA needs it */ 1488201468Srpaulo get_cachetype_cp15(); 1489201468Srpaulo pmap_pte_init_generic(); 1490201468Srpaulo 1491201468Srpaulo /* Use powersave on this CPU. */ 1492201468Srpaulo cpu_do_powersave = 1; 1493201468Srpaulo 1494201468Srpaulo goto out; 1495201468Srpaulo } 1496207611Skevlo#endif /* CPU_FA526 || CPU_FA626TE */ 1497129198Scognet#ifdef CPU_IXP12X0 1498129198Scognet if (cputype == CPU_ID_IXP1200) { 1499129198Scognet cpufuncs = ixp12x0_cpufuncs; 1500129198Scognet cpu_reset_needs_v4_MMU_disable = 1; 1501129198Scognet get_cachetype_table(); 1502129198Scognet pmap_pte_init_sa1(); 1503166655Scognet goto out; 1504129198Scognet } 1505129198Scognet#endif /* CPU_IXP12X0 */ 1506129198Scognet#ifdef CPU_XSCALE_80200 1507129198Scognet if (cputype == CPU_ID_80200) { 1508129198Scognet int rev = cpufunc_id() & CPU_ID_REVISION_MASK; 1509129198Scognet 1510129198Scognet i80200_icu_init(); 1511129198Scognet 1512129198Scognet#if defined(XSCALE_CCLKCFG) 1513129198Scognet /* 1514129198Scognet * Crank CCLKCFG to maximum legal value. 1515129198Scognet */ 1516129198Scognet __asm __volatile ("mcr p14, 0, %0, c6, c0, 0" 1517129198Scognet : 1518129198Scognet : "r" (XSCALE_CCLKCFG)); 1519129198Scognet#endif 1520129198Scognet 1521129198Scognet /* 1522129198Scognet * XXX Disable ECC in the Bus Controller Unit; we 1523129198Scognet * don't really support it, yet. Clear any pending 1524129198Scognet * error indications. 1525129198Scognet */ 1526129198Scognet __asm __volatile("mcr p13, 0, %0, c0, c1, 0" 1527129198Scognet : 1528129198Scognet : "r" (BCUCTL_E0|BCUCTL_E1|BCUCTL_EV)); 1529129198Scognet 1530129198Scognet cpufuncs = xscale_cpufuncs; 1531129198Scognet /* 1532129198Scognet * i80200 errata: Step-A0 and A1 have a bug where 1533129198Scognet * D$ dirty bits are not cleared on "invalidate by 1534129198Scognet * address". 1535129198Scognet * 1536129198Scognet * Workaround: Clean cache line before invalidating. 1537129198Scognet */ 1538129198Scognet if (rev == 0 || rev == 1) 1539129198Scognet cpufuncs.cf_dcache_inv_range = xscale_cache_purgeD_rng; 1540129198Scognet 1541129198Scognet cpu_reset_needs_v4_MMU_disable = 1; /* XScale needs it */ 1542129198Scognet get_cachetype_cp15(); 1543129198Scognet pmap_pte_init_xscale(); 1544166655Scognet goto out; 1545129198Scognet } 1546129198Scognet#endif /* CPU_XSCALE_80200 */ 1547161592Scognet#if defined(CPU_XSCALE_80321) || defined(CPU_XSCALE_80219) 1548129198Scognet if (cputype == CPU_ID_80321_400 || cputype == CPU_ID_80321_600 || 1549161592Scognet cputype == CPU_ID_80321_400_B0 || cputype == CPU_ID_80321_600_B0 || 1550161592Scognet cputype == CPU_ID_80219_400 || cputype == CPU_ID_80219_600) { 1551129198Scognet cpufuncs = xscale_cpufuncs; 1552129198Scognet cpu_reset_needs_v4_MMU_disable = 1; /* XScale needs it */ 1553129198Scognet get_cachetype_cp15(); 1554129198Scognet pmap_pte_init_xscale(); 1555166655Scognet goto out; 1556129198Scognet } 1557129198Scognet#endif /* CPU_XSCALE_80321 */ 1558161592Scognet 1559164080Scognet#if defined(CPU_XSCALE_81342) 1560164080Scognet if (cputype == CPU_ID_81342) { 1561164080Scognet cpufuncs = xscalec3_cpufuncs; 1562164080Scognet cpu_reset_needs_v4_MMU_disable = 1; /* XScale needs it */ 1563164080Scognet get_cachetype_cp15(); 1564164080Scognet pmap_pte_init_xscale(); 1565166655Scognet goto out; 1566164080Scognet } 1567164080Scognet#endif /* CPU_XSCALE_81342 */ 1568129198Scognet#ifdef CPU_XSCALE_PXA2X0 1569129198Scognet /* ignore core revision to test PXA2xx CPUs */ 1570129198Scognet if ((cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA250 || 1571191817Sstas (cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA27X || 1572129198Scognet (cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA210) { 1573129198Scognet 1574129198Scognet cpufuncs = xscale_cpufuncs; 1575129198Scognet cpu_reset_needs_v4_MMU_disable = 1; /* XScale needs it */ 1576129198Scognet get_cachetype_cp15(); 1577129198Scognet pmap_pte_init_xscale(); 1578129198Scognet 1579129198Scognet /* Use powersave on this CPU. */ 1580129198Scognet cpu_do_powersave = 1; 1581129198Scognet 1582166655Scognet goto out; 1583129198Scognet } 1584129198Scognet#endif /* CPU_XSCALE_PXA2X0 */ 1585129198Scognet#ifdef CPU_XSCALE_IXP425 1586129198Scognet if (cputype == CPU_ID_IXP425_533 || cputype == CPU_ID_IXP425_400 || 1587186352Ssam cputype == CPU_ID_IXP425_266 || cputype == CPU_ID_IXP435) { 1588129198Scognet 1589129198Scognet cpufuncs = xscale_cpufuncs; 1590129198Scognet cpu_reset_needs_v4_MMU_disable = 1; /* XScale needs it */ 1591129198Scognet get_cachetype_cp15(); 1592129198Scognet pmap_pte_init_xscale(); 1593129198Scognet 1594166655Scognet goto out; 1595129198Scognet } 1596129198Scognet#endif /* CPU_XSCALE_IXP425 */ 1597129198Scognet /* 1598129198Scognet * Bzzzz. And the answer was ... 1599129198Scognet */ 1600129198Scognet panic("No support for this CPU type (%08x) in kernel", cputype); 1601129198Scognet return(ARCHITECTURE_NOT_PRESENT); 1602166655Scognetout: 1603166655Scognet uma_set_align(arm_dcache_align_mask); 1604166655Scognet return (0); 1605129198Scognet} 1606129198Scognet 1607129198Scognet/* 1608129198Scognet * Fixup routines for data and prefetch aborts. 1609129198Scognet * 1610129198Scognet * Several compile time symbols are used 1611129198Scognet * 1612129198Scognet * DEBUG_FAULT_CORRECTION - Print debugging information during the 1613129198Scognet * correction of registers after a fault. 1614129198Scognet * ARM6_LATE_ABORT - ARM6 supports both early and late aborts 1615129198Scognet * when defined should use late aborts 1616129198Scognet */ 1617129198Scognet 1618129198Scognet 1619129198Scognet/* 1620129198Scognet * Null abort fixup routine. 1621129198Scognet * For use when no fixup is required. 1622129198Scognet */ 1623129198Scognetint 1624129198Scognetcpufunc_null_fixup(arg) 1625129198Scognet void *arg; 1626129198Scognet{ 1627129198Scognet return(ABORT_FIXUP_OK); 1628129198Scognet} 1629129198Scognet 1630129198Scognet 1631146619Scognet#if defined(CPU_ARM7TDMI) 1632129198Scognet 1633129198Scognet#ifdef DEBUG_FAULT_CORRECTION 1634129198Scognet#define DFC_PRINTF(x) printf x 1635129198Scognet#define DFC_DISASSEMBLE(x) disassemble(x) 1636129198Scognet#else 1637129198Scognet#define DFC_PRINTF(x) /* nothing */ 1638129198Scognet#define DFC_DISASSEMBLE(x) /* nothing */ 1639129198Scognet#endif 1640129198Scognet 1641129198Scognet/* 1642129198Scognet * "Early" data abort fixup. 1643129198Scognet * 1644129198Scognet * For ARM2, ARM2as, ARM3 and ARM6 (in early-abort mode). Also used 1645129198Scognet * indirectly by ARM6 (in late-abort mode) and ARM7[TDMI]. 1646129198Scognet * 1647129198Scognet * In early aborts, we may have to fix up LDM, STM, LDC and STC. 1648129198Scognet */ 1649129198Scognetint 1650129198Scognetearly_abort_fixup(arg) 1651129198Scognet void *arg; 1652129198Scognet{ 1653257217Sian struct trapframe *frame = arg; 1654129198Scognet u_int fault_pc; 1655129198Scognet u_int fault_instruction; 1656129198Scognet int saved_lr = 0; 1657129198Scognet 1658129198Scognet if ((frame->tf_spsr & PSR_MODE) == PSR_SVC32_MODE) { 1659129198Scognet 1660129198Scognet /* Ok an abort in SVC mode */ 1661129198Scognet 1662129198Scognet /* 1663129198Scognet * Copy the SVC r14 into the usr r14 - The usr r14 is garbage 1664129198Scognet * as the fault happened in svc mode but we need it in the 1665129198Scognet * usr slot so we can treat the registers as an array of ints 1666129198Scognet * during fixing. 1667129198Scognet * NOTE: This PC is in the position but writeback is not 1668129198Scognet * allowed on r15. 1669129198Scognet * Doing it like this is more efficient than trapping this 1670129198Scognet * case in all possible locations in the following fixup code. 1671129198Scognet */ 1672129198Scognet 1673129198Scognet saved_lr = frame->tf_usr_lr; 1674129198Scognet frame->tf_usr_lr = frame->tf_svc_lr; 1675129198Scognet 1676129198Scognet /* 1677129198Scognet * Note the trapframe does not have the SVC r13 so a fault 1678129198Scognet * from an instruction with writeback to r13 in SVC mode is 1679129198Scognet * not allowed. This should not happen as the kstack is 1680129198Scognet * always valid. 1681129198Scognet */ 1682129198Scognet } 1683129198Scognet 1684129198Scognet /* Get fault address and status from the CPU */ 1685129198Scognet 1686129198Scognet fault_pc = frame->tf_pc; 1687129198Scognet fault_instruction = *((volatile unsigned int *)fault_pc); 1688129198Scognet 1689129198Scognet /* Decode the fault instruction and fix the registers as needed */ 1690129198Scognet 1691129198Scognet if ((fault_instruction & 0x0e000000) == 0x08000000) { 1692129198Scognet int base; 1693129198Scognet int loop; 1694129198Scognet int count; 1695129198Scognet int *registers = &frame->tf_r0; 1696236991Simp 1697129198Scognet DFC_PRINTF(("LDM/STM\n")); 1698129198Scognet DFC_DISASSEMBLE(fault_pc); 1699129198Scognet if (fault_instruction & (1 << 21)) { 1700129198Scognet DFC_PRINTF(("This instruction must be corrected\n")); 1701129198Scognet base = (fault_instruction >> 16) & 0x0f; 1702129198Scognet if (base == 15) 1703129198Scognet return ABORT_FIXUP_FAILED; 1704129198Scognet /* Count registers transferred */ 1705129198Scognet count = 0; 1706129198Scognet for (loop = 0; loop < 16; ++loop) { 1707129198Scognet if (fault_instruction & (1<<loop)) 1708129198Scognet ++count; 1709129198Scognet } 1710129198Scognet DFC_PRINTF(("%d registers used\n", count)); 1711129198Scognet DFC_PRINTF(("Corrected r%d by %d bytes ", 1712129198Scognet base, count * 4)); 1713129198Scognet if (fault_instruction & (1 << 23)) { 1714129198Scognet DFC_PRINTF(("down\n")); 1715129198Scognet registers[base] -= count * 4; 1716129198Scognet } else { 1717129198Scognet DFC_PRINTF(("up\n")); 1718129198Scognet registers[base] += count * 4; 1719129198Scognet } 1720129198Scognet } 1721129198Scognet } else if ((fault_instruction & 0x0e000000) == 0x0c000000) { 1722129198Scognet int base; 1723129198Scognet int offset; 1724129198Scognet int *registers = &frame->tf_r0; 1725129198Scognet 1726129198Scognet /* REGISTER CORRECTION IS REQUIRED FOR THESE INSTRUCTIONS */ 1727129198Scognet 1728129198Scognet DFC_DISASSEMBLE(fault_pc); 1729129198Scognet 1730129198Scognet /* Only need to fix registers if write back is turned on */ 1731129198Scognet 1732129198Scognet if ((fault_instruction & (1 << 21)) != 0) { 1733129198Scognet base = (fault_instruction >> 16) & 0x0f; 1734129198Scognet if (base == 13 && 1735129198Scognet (frame->tf_spsr & PSR_MODE) == PSR_SVC32_MODE) 1736129198Scognet return ABORT_FIXUP_FAILED; 1737129198Scognet if (base == 15) 1738129198Scognet return ABORT_FIXUP_FAILED; 1739129198Scognet 1740129198Scognet offset = (fault_instruction & 0xff) << 2; 1741129198Scognet DFC_PRINTF(("r%d=%08x\n", base, registers[base])); 1742129198Scognet if ((fault_instruction & (1 << 23)) != 0) 1743129198Scognet offset = -offset; 1744129198Scognet registers[base] += offset; 1745129198Scognet DFC_PRINTF(("r%d=%08x\n", base, registers[base])); 1746129198Scognet } 1747129198Scognet } else if ((fault_instruction & 0x0e000000) == 0x0c000000) 1748129198Scognet return ABORT_FIXUP_FAILED; 1749129198Scognet 1750129198Scognet if ((frame->tf_spsr & PSR_MODE) == PSR_SVC32_MODE) { 1751129198Scognet 1752129198Scognet /* Ok an abort in SVC mode */ 1753129198Scognet 1754129198Scognet /* 1755129198Scognet * Copy the SVC r14 into the usr r14 - The usr r14 is garbage 1756129198Scognet * as the fault happened in svc mode but we need it in the 1757129198Scognet * usr slot so we can treat the registers as an array of ints 1758129198Scognet * during fixing. 1759129198Scognet * NOTE: This PC is in the position but writeback is not 1760129198Scognet * allowed on r15. 1761129198Scognet * Doing it like this is more efficient than trapping this 1762129198Scognet * case in all possible locations in the prior fixup code. 1763129198Scognet */ 1764129198Scognet 1765129198Scognet frame->tf_svc_lr = frame->tf_usr_lr; 1766129198Scognet frame->tf_usr_lr = saved_lr; 1767129198Scognet 1768129198Scognet /* 1769129198Scognet * Note the trapframe does not have the SVC r13 so a fault 1770129198Scognet * from an instruction with writeback to r13 in SVC mode is 1771129198Scognet * not allowed. This should not happen as the kstack is 1772129198Scognet * always valid. 1773129198Scognet */ 1774129198Scognet } 1775129198Scognet 1776129198Scognet return(ABORT_FIXUP_OK); 1777129198Scognet} 1778129198Scognet#endif /* CPU_ARM2/250/3/6/7 */ 1779129198Scognet 1780129198Scognet 1781146619Scognet#if defined(CPU_ARM7TDMI) 1782129198Scognet/* 1783129198Scognet * "Late" (base updated) data abort fixup 1784129198Scognet * 1785129198Scognet * For ARM6 (in late-abort mode) and ARM7. 1786129198Scognet * 1787129198Scognet * In this model, all data-transfer instructions need fixing up. We defer 1788129198Scognet * LDM, STM, LDC and STC fixup to the early-abort handler. 1789129198Scognet */ 1790129198Scognetint 1791129198Scognetlate_abort_fixup(arg) 1792129198Scognet void *arg; 1793129198Scognet{ 1794257217Sian struct trapframe *frame = arg; 1795129198Scognet u_int fault_pc; 1796129198Scognet u_int fault_instruction; 1797129198Scognet int saved_lr = 0; 1798129198Scognet 1799129198Scognet if ((frame->tf_spsr & PSR_MODE) == PSR_SVC32_MODE) { 1800129198Scognet 1801129198Scognet /* Ok an abort in SVC mode */ 1802129198Scognet 1803129198Scognet /* 1804129198Scognet * Copy the SVC r14 into the usr r14 - The usr r14 is garbage 1805129198Scognet * as the fault happened in svc mode but we need it in the 1806129198Scognet * usr slot so we can treat the registers as an array of ints 1807129198Scognet * during fixing. 1808129198Scognet * NOTE: This PC is in the position but writeback is not 1809129198Scognet * allowed on r15. 1810129198Scognet * Doing it like this is more efficient than trapping this 1811129198Scognet * case in all possible locations in the following fixup code. 1812129198Scognet */ 1813129198Scognet 1814129198Scognet saved_lr = frame->tf_usr_lr; 1815129198Scognet frame->tf_usr_lr = frame->tf_svc_lr; 1816129198Scognet 1817129198Scognet /* 1818129198Scognet * Note the trapframe does not have the SVC r13 so a fault 1819129198Scognet * from an instruction with writeback to r13 in SVC mode is 1820129198Scognet * not allowed. This should not happen as the kstack is 1821129198Scognet * always valid. 1822129198Scognet */ 1823129198Scognet } 1824129198Scognet 1825129198Scognet /* Get fault address and status from the CPU */ 1826129198Scognet 1827129198Scognet fault_pc = frame->tf_pc; 1828129198Scognet fault_instruction = *((volatile unsigned int *)fault_pc); 1829129198Scognet 1830129198Scognet /* Decode the fault instruction and fix the registers as needed */ 1831129198Scognet 1832129198Scognet /* Was is a swap instruction ? */ 1833129198Scognet 1834129198Scognet if ((fault_instruction & 0x0fb00ff0) == 0x01000090) { 1835129198Scognet DFC_DISASSEMBLE(fault_pc); 1836129198Scognet } else if ((fault_instruction & 0x0c000000) == 0x04000000) { 1837129198Scognet 1838129198Scognet /* Was is a ldr/str instruction */ 1839129198Scognet /* This is for late abort only */ 1840129198Scognet 1841129198Scognet int base; 1842129198Scognet int offset; 1843129198Scognet int *registers = &frame->tf_r0; 1844129198Scognet 1845129198Scognet DFC_DISASSEMBLE(fault_pc); 1846129198Scognet 1847129198Scognet /* This is for late abort only */ 1848129198Scognet 1849129198Scognet if ((fault_instruction & (1 << 24)) == 0 1850129198Scognet || (fault_instruction & (1 << 21)) != 0) { 1851129198Scognet /* postindexed ldr/str with no writeback */ 1852129198Scognet 1853129198Scognet base = (fault_instruction >> 16) & 0x0f; 1854129198Scognet if (base == 13 && 1855129198Scognet (frame->tf_spsr & PSR_MODE) == PSR_SVC32_MODE) 1856129198Scognet return ABORT_FIXUP_FAILED; 1857129198Scognet if (base == 15) 1858129198Scognet return ABORT_FIXUP_FAILED; 1859129198Scognet DFC_PRINTF(("late abt fix: r%d=%08x : ", 1860129198Scognet base, registers[base])); 1861129198Scognet if ((fault_instruction & (1 << 25)) == 0) { 1862129198Scognet /* Immediate offset - easy */ 1863129198Scognet 1864129198Scognet offset = fault_instruction & 0xfff; 1865129198Scognet if ((fault_instruction & (1 << 23))) 1866129198Scognet offset = -offset; 1867129198Scognet registers[base] += offset; 1868129198Scognet DFC_PRINTF(("imm=%08x ", offset)); 1869129198Scognet } else { 1870129198Scognet /* offset is a shifted register */ 1871129198Scognet int shift; 1872129198Scognet 1873129198Scognet offset = fault_instruction & 0x0f; 1874129198Scognet if (offset == base) 1875129198Scognet return ABORT_FIXUP_FAILED; 1876236991Simp 1877129198Scognet /* 1878129198Scognet * Register offset - hard we have to 1879129198Scognet * cope with shifts ! 1880129198Scognet */ 1881129198Scognet offset = registers[offset]; 1882129198Scognet 1883129198Scognet if ((fault_instruction & (1 << 4)) == 0) 1884129198Scognet /* shift with amount */ 1885129198Scognet shift = (fault_instruction >> 7) & 0x1f; 1886129198Scognet else { 1887129198Scognet /* shift with register */ 1888129198Scognet if ((fault_instruction & (1 << 7)) != 0) 1889129198Scognet /* undefined for now so bail out */ 1890129198Scognet return ABORT_FIXUP_FAILED; 1891129198Scognet shift = ((fault_instruction >> 8) & 0xf); 1892129198Scognet if (base == shift) 1893129198Scognet return ABORT_FIXUP_FAILED; 1894129198Scognet DFC_PRINTF(("shift reg=%d ", shift)); 1895129198Scognet shift = registers[shift]; 1896129198Scognet } 1897129198Scognet DFC_PRINTF(("shift=%08x ", shift)); 1898129198Scognet switch (((fault_instruction >> 5) & 0x3)) { 1899129198Scognet case 0 : /* Logical left */ 1900129198Scognet offset = (int)(((u_int)offset) << shift); 1901129198Scognet break; 1902129198Scognet case 1 : /* Logical Right */ 1903129198Scognet if (shift == 0) shift = 32; 1904129198Scognet offset = (int)(((u_int)offset) >> shift); 1905129198Scognet break; 1906129198Scognet case 2 : /* Arithmetic Right */ 1907129198Scognet if (shift == 0) shift = 32; 1908129198Scognet offset = (int)(((int)offset) >> shift); 1909129198Scognet break; 1910129198Scognet case 3 : /* Rotate right (rol or rxx) */ 1911129198Scognet return ABORT_FIXUP_FAILED; 1912129198Scognet break; 1913129198Scognet } 1914129198Scognet 1915129198Scognet DFC_PRINTF(("abt: fixed LDR/STR with " 1916129198Scognet "register offset\n")); 1917129198Scognet if ((fault_instruction & (1 << 23))) 1918129198Scognet offset = -offset; 1919129198Scognet DFC_PRINTF(("offset=%08x ", offset)); 1920129198Scognet registers[base] += offset; 1921129198Scognet } 1922129198Scognet DFC_PRINTF(("r%d=%08x\n", base, registers[base])); 1923129198Scognet } 1924129198Scognet } 1925129198Scognet 1926129198Scognet if ((frame->tf_spsr & PSR_MODE) == PSR_SVC32_MODE) { 1927129198Scognet 1928129198Scognet /* Ok an abort in SVC mode */ 1929129198Scognet 1930129198Scognet /* 1931129198Scognet * Copy the SVC r14 into the usr r14 - The usr r14 is garbage 1932129198Scognet * as the fault happened in svc mode but we need it in the 1933129198Scognet * usr slot so we can treat the registers as an array of ints 1934129198Scognet * during fixing. 1935129198Scognet * NOTE: This PC is in the position but writeback is not 1936129198Scognet * allowed on r15. 1937129198Scognet * Doing it like this is more efficient than trapping this 1938129198Scognet * case in all possible locations in the prior fixup code. 1939129198Scognet */ 1940129198Scognet 1941129198Scognet frame->tf_svc_lr = frame->tf_usr_lr; 1942129198Scognet frame->tf_usr_lr = saved_lr; 1943129198Scognet 1944129198Scognet /* 1945129198Scognet * Note the trapframe does not have the SVC r13 so a fault 1946129198Scognet * from an instruction with writeback to r13 in SVC mode is 1947129198Scognet * not allowed. This should not happen as the kstack is 1948129198Scognet * always valid. 1949129198Scognet */ 1950129198Scognet } 1951129198Scognet 1952129198Scognet /* 1953129198Scognet * Now let the early-abort fixup routine have a go, in case it 1954129198Scognet * was an LDM, STM, LDC or STC that faulted. 1955129198Scognet */ 1956129198Scognet 1957129198Scognet return early_abort_fixup(arg); 1958129198Scognet} 1959146619Scognet#endif /* CPU_ARM7TDMI */ 1960129198Scognet 1961129198Scognet/* 1962129198Scognet * CPU Setup code 1963129198Scognet */ 1964129198Scognet 1965146619Scognet#if defined(CPU_ARM7TDMI) || defined(CPU_ARM8) || defined (CPU_ARM9) || \ 1966172738Simp defined(CPU_ARM9E) || \ 1967161592Scognet defined(CPU_SA110) || defined(CPU_SA1100) || defined(CPU_SA1110) || \ 1968161592Scognet defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \ 1969161592Scognet defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \ 1970172738Simp defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342) || \ 1971244480Sgonzo defined(CPU_ARM10) || defined(CPU_ARM1136) || defined(CPU_ARM1176) ||\ 1972207611Skevlo defined(CPU_FA526) || defined(CPU_FA626TE) 1973129198Scognet 1974129198Scognet#define IGN 0 1975129198Scognet#define OR 1 1976129198Scognet#define BIC 2 1977129198Scognet 1978129198Scognetstruct cpu_option { 1979129198Scognet char *co_name; 1980129198Scognet int co_falseop; 1981129198Scognet int co_trueop; 1982129198Scognet int co_value; 1983129198Scognet}; 1984129198Scognet 1985137498Strhodesstatic u_int parse_cpu_options(char *, struct cpu_option *, u_int); 1986129198Scognet 1987129198Scognetstatic u_int 1988129198Scognetparse_cpu_options(args, optlist, cpuctrl) 1989129198Scognet char *args; 1990236991Simp struct cpu_option *optlist; 1991236991Simp u_int cpuctrl; 1992129198Scognet{ 1993129198Scognet int integer; 1994129198Scognet 1995129198Scognet if (args == NULL) 1996129198Scognet return(cpuctrl); 1997129198Scognet 1998129198Scognet while (optlist->co_name) { 1999129198Scognet if (get_bootconf_option(args, optlist->co_name, 2000129198Scognet BOOTOPT_TYPE_BOOLEAN, &integer)) { 2001129198Scognet if (integer) { 2002129198Scognet if (optlist->co_trueop == OR) 2003129198Scognet cpuctrl |= optlist->co_value; 2004129198Scognet else if (optlist->co_trueop == BIC) 2005129198Scognet cpuctrl &= ~optlist->co_value; 2006129198Scognet } else { 2007129198Scognet if (optlist->co_falseop == OR) 2008129198Scognet cpuctrl |= optlist->co_value; 2009129198Scognet else if (optlist->co_falseop == BIC) 2010129198Scognet cpuctrl &= ~optlist->co_value; 2011129198Scognet } 2012129198Scognet } 2013129198Scognet ++optlist; 2014129198Scognet } 2015129198Scognet return(cpuctrl); 2016129198Scognet} 2017161592Scognet#endif /* CPU_ARM7TDMI || CPU_ARM8 || CPU_SA110 || XSCALE*/ 2018129198Scognet 2019146619Scognet#if defined(CPU_ARM7TDMI) || defined(CPU_ARM8) 2020129198Scognetstruct cpu_option arm678_options[] = { 2021129198Scognet#ifdef COMPAT_12 2022129198Scognet { "nocache", IGN, BIC, CPU_CONTROL_IDC_ENABLE }, 2023129198Scognet { "nowritebuf", IGN, BIC, CPU_CONTROL_WBUF_ENABLE }, 2024129198Scognet#endif /* COMPAT_12 */ 2025129198Scognet { "cpu.cache", BIC, OR, CPU_CONTROL_IDC_ENABLE }, 2026129198Scognet { "cpu.nocache", OR, BIC, CPU_CONTROL_IDC_ENABLE }, 2027129198Scognet { "cpu.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 2028129198Scognet { "cpu.nowritebuf", OR, BIC, CPU_CONTROL_WBUF_ENABLE }, 2029129198Scognet { NULL, IGN, IGN, 0 } 2030129198Scognet}; 2031129198Scognet 2032129198Scognet#endif /* CPU_ARM6 || CPU_ARM7 || CPU_ARM7TDMI || CPU_ARM8 */ 2033129198Scognet 2034129198Scognet#ifdef CPU_ARM7TDMI 2035129198Scognetstruct cpu_option arm7tdmi_options[] = { 2036129198Scognet { "arm7.cache", BIC, OR, CPU_CONTROL_IDC_ENABLE }, 2037129198Scognet { "arm7.nocache", OR, BIC, CPU_CONTROL_IDC_ENABLE }, 2038129198Scognet { "arm7.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 2039129198Scognet { "arm7.nowritebuf", OR, BIC, CPU_CONTROL_WBUF_ENABLE }, 2040129198Scognet#ifdef COMPAT_12 2041129198Scognet { "fpaclk2", BIC, OR, CPU_CONTROL_CPCLK }, 2042129198Scognet#endif /* COMPAT_12 */ 2043129198Scognet { "arm700.fpaclk", BIC, OR, CPU_CONTROL_CPCLK }, 2044129198Scognet { NULL, IGN, IGN, 0 } 2045129198Scognet}; 2046129198Scognet 2047129198Scognetvoid 2048129198Scognetarm7tdmi_setup(args) 2049129198Scognet char *args; 2050129198Scognet{ 2051129198Scognet int cpuctrl; 2052129198Scognet 2053129198Scognet cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 2054129198Scognet | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 2055129198Scognet | CPU_CONTROL_IDC_ENABLE | CPU_CONTROL_WBUF_ENABLE; 2056129198Scognet 2057129198Scognet cpuctrl = parse_cpu_options(args, arm678_options, cpuctrl); 2058129198Scognet cpuctrl = parse_cpu_options(args, arm7tdmi_options, cpuctrl); 2059129198Scognet 2060129198Scognet#ifdef __ARMEB__ 2061129198Scognet cpuctrl |= CPU_CONTROL_BEND_ENABLE; 2062129198Scognet#endif 2063129198Scognet 2064129198Scognet /* Clear out the cache */ 2065129198Scognet cpu_idcache_wbinv_all(); 2066129198Scognet 2067129198Scognet /* Set the control register */ 2068129198Scognet ctrl = cpuctrl; 2069129198Scognet cpu_control(0xffffffff, cpuctrl); 2070129198Scognet} 2071129198Scognet#endif /* CPU_ARM7TDMI */ 2072129198Scognet 2073129198Scognet#ifdef CPU_ARM8 2074129198Scognetstruct cpu_option arm8_options[] = { 2075129198Scognet { "arm8.cache", BIC, OR, CPU_CONTROL_IDC_ENABLE }, 2076129198Scognet { "arm8.nocache", OR, BIC, CPU_CONTROL_IDC_ENABLE }, 2077129198Scognet { "arm8.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 2078129198Scognet { "arm8.nowritebuf", OR, BIC, CPU_CONTROL_WBUF_ENABLE }, 2079129198Scognet#ifdef COMPAT_12 2080129198Scognet { "branchpredict", BIC, OR, CPU_CONTROL_BPRD_ENABLE }, 2081129198Scognet#endif /* COMPAT_12 */ 2082129198Scognet { "cpu.branchpredict", BIC, OR, CPU_CONTROL_BPRD_ENABLE }, 2083129198Scognet { "arm8.branchpredict", BIC, OR, CPU_CONTROL_BPRD_ENABLE }, 2084129198Scognet { NULL, IGN, IGN, 0 } 2085129198Scognet}; 2086129198Scognet 2087129198Scognetvoid 2088129198Scognetarm8_setup(args) 2089129198Scognet char *args; 2090129198Scognet{ 2091129198Scognet int integer; 2092129198Scognet int cpuctrl, cpuctrlmask; 2093129198Scognet int clocktest; 2094129198Scognet int setclock = 0; 2095129198Scognet 2096129198Scognet cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 2097129198Scognet | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 2098129198Scognet | CPU_CONTROL_IDC_ENABLE | CPU_CONTROL_WBUF_ENABLE; 2099129198Scognet cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 2100129198Scognet | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 2101129198Scognet | CPU_CONTROL_IDC_ENABLE | CPU_CONTROL_WBUF_ENABLE 2102129198Scognet | CPU_CONTROL_BPRD_ENABLE | CPU_CONTROL_ROM_ENABLE 2103129198Scognet | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE; 2104129198Scognet 2105129198Scognet#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 2106129198Scognet cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 2107129198Scognet#endif 2108129198Scognet 2109129198Scognet cpuctrl = parse_cpu_options(args, arm678_options, cpuctrl); 2110129198Scognet cpuctrl = parse_cpu_options(args, arm8_options, cpuctrl); 2111129198Scognet 2112129198Scognet#ifdef __ARMEB__ 2113129198Scognet cpuctrl |= CPU_CONTROL_BEND_ENABLE; 2114129198Scognet#endif 2115129198Scognet 2116129198Scognet /* Get clock configuration */ 2117129198Scognet clocktest = arm8_clock_config(0, 0) & 0x0f; 2118129198Scognet 2119129198Scognet /* Special ARM8 clock and test configuration */ 2120129198Scognet if (get_bootconf_option(args, "arm8.clock.reset", BOOTOPT_TYPE_BOOLEAN, &integer)) { 2121129198Scognet clocktest = 0; 2122129198Scognet setclock = 1; 2123129198Scognet } 2124129198Scognet if (get_bootconf_option(args, "arm8.clock.dynamic", BOOTOPT_TYPE_BOOLEAN, &integer)) { 2125129198Scognet if (integer) 2126129198Scognet clocktest |= 0x01; 2127129198Scognet else 2128129198Scognet clocktest &= ~(0x01); 2129129198Scognet setclock = 1; 2130129198Scognet } 2131129198Scognet if (get_bootconf_option(args, "arm8.clock.sync", BOOTOPT_TYPE_BOOLEAN, &integer)) { 2132129198Scognet if (integer) 2133129198Scognet clocktest |= 0x02; 2134129198Scognet else 2135129198Scognet clocktest &= ~(0x02); 2136129198Scognet setclock = 1; 2137129198Scognet } 2138129198Scognet if (get_bootconf_option(args, "arm8.clock.fast", BOOTOPT_TYPE_BININT, &integer)) { 2139129198Scognet clocktest = (clocktest & ~0xc0) | (integer & 3) << 2; 2140129198Scognet setclock = 1; 2141129198Scognet } 2142129198Scognet if (get_bootconf_option(args, "arm8.test", BOOTOPT_TYPE_BININT, &integer)) { 2143129198Scognet clocktest |= (integer & 7) << 5; 2144129198Scognet setclock = 1; 2145129198Scognet } 2146129198Scognet 2147129198Scognet /* Clear out the cache */ 2148129198Scognet cpu_idcache_wbinv_all(); 2149129198Scognet 2150129198Scognet /* Set the control register */ 2151129198Scognet ctrl = cpuctrl; 2152129198Scognet cpu_control(0xffffffff, cpuctrl); 2153129198Scognet 2154236991Simp /* Set the clock/test register */ 2155129198Scognet if (setclock) 2156129198Scognet arm8_clock_config(0x7f, clocktest); 2157129198Scognet} 2158129198Scognet#endif /* CPU_ARM8 */ 2159129198Scognet 2160129198Scognet#ifdef CPU_ARM9 2161129198Scognetstruct cpu_option arm9_options[] = { 2162129198Scognet { "cpu.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2163129198Scognet { "cpu.nocache", OR, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2164129198Scognet { "arm9.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2165129198Scognet { "arm9.icache", BIC, OR, CPU_CONTROL_IC_ENABLE }, 2166129198Scognet { "arm9.dcache", BIC, OR, CPU_CONTROL_DC_ENABLE }, 2167129198Scognet { "cpu.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 2168129198Scognet { "cpu.nowritebuf", OR, BIC, CPU_CONTROL_WBUF_ENABLE }, 2169129198Scognet { "arm9.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 2170129198Scognet { NULL, IGN, IGN, 0 } 2171129198Scognet}; 2172129198Scognet 2173129198Scognetvoid 2174129198Scognetarm9_setup(args) 2175129198Scognet char *args; 2176129198Scognet{ 2177129198Scognet int cpuctrl, cpuctrlmask; 2178129198Scognet 2179129198Scognet cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 2180129198Scognet | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 2181129198Scognet | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 2182157618Scognet | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE | 2183157618Scognet CPU_CONTROL_ROUNDROBIN; 2184129198Scognet cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 2185129198Scognet | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 2186129198Scognet | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 2187129198Scognet | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE 2188129198Scognet | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE 2189146605Scognet | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_VECRELOC 2190146605Scognet | CPU_CONTROL_ROUNDROBIN; 2191129198Scognet 2192129198Scognet#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 2193129198Scognet cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 2194129198Scognet#endif 2195129198Scognet 2196129198Scognet cpuctrl = parse_cpu_options(args, arm9_options, cpuctrl); 2197129198Scognet 2198129198Scognet#ifdef __ARMEB__ 2199129198Scognet cpuctrl |= CPU_CONTROL_BEND_ENABLE; 2200129198Scognet#endif 2201142050Scognet if (vector_page == ARM_VECTORS_HIGH) 2202142050Scognet cpuctrl |= CPU_CONTROL_VECRELOC; 2203129198Scognet 2204129198Scognet /* Clear out the cache */ 2205129198Scognet cpu_idcache_wbinv_all(); 2206129198Scognet 2207129198Scognet /* Set the control register */ 2208146605Scognet cpu_control(cpuctrlmask, cpuctrl); 2209129198Scognet ctrl = cpuctrl; 2210129198Scognet 2211129198Scognet} 2212129198Scognet#endif /* CPU_ARM9 */ 2213129198Scognet 2214172738Simp#if defined(CPU_ARM9E) || defined(CPU_ARM10) 2215129198Scognetstruct cpu_option arm10_options[] = { 2216129198Scognet { "cpu.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2217129198Scognet { "cpu.nocache", OR, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2218129198Scognet { "arm10.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2219129198Scognet { "arm10.icache", BIC, OR, CPU_CONTROL_IC_ENABLE }, 2220129198Scognet { "arm10.dcache", BIC, OR, CPU_CONTROL_DC_ENABLE }, 2221129198Scognet { "cpu.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 2222129198Scognet { "cpu.nowritebuf", OR, BIC, CPU_CONTROL_WBUF_ENABLE }, 2223129198Scognet { "arm10.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 2224129198Scognet { NULL, IGN, IGN, 0 } 2225129198Scognet}; 2226129198Scognet 2227129198Scognetvoid 2228129198Scognetarm10_setup(args) 2229129198Scognet char *args; 2230129198Scognet{ 2231129198Scognet int cpuctrl, cpuctrlmask; 2232129198Scognet 2233129198Scognet cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_SYST_ENABLE 2234236991Simp | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 2235129198Scognet | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_BPRD_ENABLE; 2236129198Scognet cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_SYST_ENABLE 2237129198Scognet | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 2238129198Scognet | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE 2239129198Scognet | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE 2240129198Scognet | CPU_CONTROL_BPRD_ENABLE 2241129198Scognet | CPU_CONTROL_ROUNDROBIN | CPU_CONTROL_CPCLK; 2242129198Scognet 2243129198Scognet#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 2244129198Scognet cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 2245129198Scognet#endif 2246129198Scognet 2247129198Scognet cpuctrl = parse_cpu_options(args, arm10_options, cpuctrl); 2248129198Scognet 2249129198Scognet#ifdef __ARMEB__ 2250129198Scognet cpuctrl |= CPU_CONTROL_BEND_ENABLE; 2251129198Scognet#endif 2252129198Scognet 2253129198Scognet /* Clear out the cache */ 2254129198Scognet cpu_idcache_wbinv_all(); 2255129198Scognet 2256129198Scognet /* Now really make sure they are clean. */ 2257172738Simp __asm __volatile ("mcr\tp15, 0, r0, c7, c7, 0" : : ); 2258129198Scognet 2259174058Scognet if (vector_page == ARM_VECTORS_HIGH) 2260174058Scognet cpuctrl |= CPU_CONTROL_VECRELOC; 2261174058Scognet 2262129198Scognet /* Set the control register */ 2263129198Scognet ctrl = cpuctrl; 2264129198Scognet cpu_control(0xffffffff, cpuctrl); 2265129198Scognet 2266129198Scognet /* And again. */ 2267129198Scognet cpu_idcache_wbinv_all(); 2268129198Scognet} 2269172738Simp#endif /* CPU_ARM9E || CPU_ARM10 */ 2270129198Scognet 2271244480Sgonzo#if defined(CPU_ARM1136) || defined(CPU_ARM1176) 2272172738Simpstruct cpu_option arm11_options[] = { 2273172738Simp { "cpu.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2274172738Simp { "cpu.nocache", OR, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2275172738Simp { "arm11.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2276172738Simp { "arm11.icache", BIC, OR, CPU_CONTROL_IC_ENABLE }, 2277172738Simp { "arm11.dcache", BIC, OR, CPU_CONTROL_DC_ENABLE }, 2278172738Simp { NULL, IGN, IGN, 0 } 2279172738Simp}; 2280172738Simp 2281172738Simpvoid 2282244480Sgonzoarm11x6_setup(char *args) 2283172738Simp{ 2284244480Sgonzo int cpuctrl, cpuctrl_wax; 2285244480Sgonzo uint32_t auxctrl, auxctrl_wax; 2286244480Sgonzo uint32_t tmp, tmp2; 2287244480Sgonzo uint32_t sbz=0; 2288244480Sgonzo uint32_t cpuid; 2289172738Simp 2290244480Sgonzo cpuid = cpufunc_id(); 2291244480Sgonzo 2292244480Sgonzo cpuctrl = 2293244480Sgonzo CPU_CONTROL_MMU_ENABLE | 2294244480Sgonzo CPU_CONTROL_DC_ENABLE | 2295244480Sgonzo CPU_CONTROL_WBUF_ENABLE | 2296244480Sgonzo CPU_CONTROL_32BP_ENABLE | 2297244480Sgonzo CPU_CONTROL_32BD_ENABLE | 2298244480Sgonzo CPU_CONTROL_LABT_ENABLE | 2299244480Sgonzo CPU_CONTROL_SYST_ENABLE | 2300244480Sgonzo CPU_CONTROL_IC_ENABLE; 2301244480Sgonzo 2302244480Sgonzo /* 2303244480Sgonzo * "write as existing" bits 2304244480Sgonzo * inverse of this is mask 2305244480Sgonzo */ 2306244480Sgonzo cpuctrl_wax = 2307244480Sgonzo (3 << 30) | /* SBZ */ 2308244480Sgonzo (1 << 29) | /* FA */ 2309244480Sgonzo (1 << 28) | /* TR */ 2310244480Sgonzo (3 << 26) | /* SBZ */ 2311244480Sgonzo (3 << 19) | /* SBZ */ 2312244480Sgonzo (1 << 17); /* SBZ */ 2313244480Sgonzo 2314244480Sgonzo cpuctrl |= CPU_CONTROL_BPRD_ENABLE; 2315244480Sgonzo cpuctrl |= CPU_CONTROL_V6_EXTPAGE; 2316244480Sgonzo 2317172738Simp cpuctrl = parse_cpu_options(args, arm11_options, cpuctrl); 2318244480Sgonzo 2319172738Simp#ifdef __ARMEB__ 2320172738Simp cpuctrl |= CPU_CONTROL_BEND_ENABLE; 2321172738Simp#endif 2322244480Sgonzo 2323239701Sgonzo if (vector_page == ARM_VECTORS_HIGH) 2324239701Sgonzo cpuctrl |= CPU_CONTROL_VECRELOC; 2325172738Simp 2326244480Sgonzo auxctrl = 0; 2327244480Sgonzo auxctrl_wax = ~0; 2328244480Sgonzo /* 2329244480Sgonzo * This options enables the workaround for the 364296 ARM1136 2330244480Sgonzo * r0pX errata (possible cache data corruption with 2331244480Sgonzo * hit-under-miss enabled). It sets the undocumented bit 31 in 2332244480Sgonzo * the auxiliary control register and the FI bit in the control 2333244480Sgonzo * register, thus disabling hit-under-miss without putting the 2334244480Sgonzo * processor into full low interrupt latency mode. ARM11MPCore 2335244480Sgonzo * is not affected. 2336244480Sgonzo */ 2337244480Sgonzo if ((cpuid & CPU_ID_CPU_MASK) == CPU_ID_ARM1136JS) { /* ARM1136JSr0pX */ 2338244480Sgonzo cpuctrl |= CPU_CONTROL_FI_ENABLE; 2339244480Sgonzo auxctrl = ARM1136_AUXCTL_PFI; 2340244480Sgonzo auxctrl_wax = ~ARM1136_AUXCTL_PFI; 2341244480Sgonzo } 2342244480Sgonzo 2343244480Sgonzo /* 2344244480Sgonzo * Enable an errata workaround 2345244480Sgonzo */ 2346244480Sgonzo if ((cpuid & CPU_ID_CPU_MASK) == CPU_ID_ARM1176JZS) { /* ARM1176JZSr0 */ 2347244480Sgonzo auxctrl = ARM1176_AUXCTL_PHD; 2348244480Sgonzo auxctrl_wax = ~ARM1176_AUXCTL_PHD; 2349244480Sgonzo } 2350244480Sgonzo 2351244480Sgonzo /* Clear out the cache */ 2352172738Simp cpu_idcache_wbinv_all(); 2353172738Simp 2354244480Sgonzo /* Now really make sure they are clean. */ 2355244480Sgonzo __asm volatile ("mcr\tp15, 0, %0, c7, c7, 0" : : "r"(sbz)); 2356244480Sgonzo 2357244480Sgonzo /* Allow detection code to find the VFP if it's fitted. */ 2358244480Sgonzo __asm volatile ("mcr\tp15, 0, %0, c1, c0, 2" : : "r" (0x0fffffff)); 2359244480Sgonzo 2360172738Simp /* Set the control register */ 2361239701Sgonzo ctrl = cpuctrl; 2362244480Sgonzo cpu_control(~cpuctrl_wax, cpuctrl); 2363172738Simp 2364244480Sgonzo __asm volatile ("mrc p15, 0, %0, c1, c0, 1\n\t" 2365244480Sgonzo "and %1, %0, %2\n\t" 2366244480Sgonzo "orr %1, %1, %3\n\t" 2367244480Sgonzo "teq %0, %1\n\t" 2368244480Sgonzo "mcrne p15, 0, %1, c1, c0, 1\n\t" 2369244480Sgonzo : "=r"(tmp), "=r"(tmp2) : 2370244480Sgonzo "r"(auxctrl_wax), "r"(auxctrl)); 2371244480Sgonzo 2372244480Sgonzo /* And again. */ 2373172738Simp cpu_idcache_wbinv_all(); 2374172738Simp} 2375244480Sgonzo#endif /* CPU_ARM1136 || CPU_ARM1176 */ 2376172738Simp 2377239268Sgonzo#ifdef CPU_MV_PJ4B 2378239268Sgonzovoid 2379239268Sgonzopj4bv7_setup(args) 2380239268Sgonzo char *args; 2381239268Sgonzo{ 2382239268Sgonzo int cpuctrl; 2383239268Sgonzo 2384239268Sgonzo pj4b_config(); 2385239268Sgonzo 2386239268Sgonzo cpuctrl = CPU_CONTROL_MMU_ENABLE; 2387239268Sgonzo#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 2388239268Sgonzo cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 2389239268Sgonzo#endif 2390239268Sgonzo cpuctrl |= CPU_CONTROL_DC_ENABLE; 2391239268Sgonzo cpuctrl |= (0xf << 3); 2392239268Sgonzo cpuctrl |= CPU_CONTROL_BPRD_ENABLE; 2393239268Sgonzo cpuctrl |= CPU_CONTROL_IC_ENABLE; 2394239268Sgonzo if (vector_page == ARM_VECTORS_HIGH) 2395239268Sgonzo cpuctrl |= CPU_CONTROL_VECRELOC; 2396239268Sgonzo cpuctrl |= (0x5 << 16) | (1 < 22); 2397239268Sgonzo cpuctrl |= CPU_CONTROL_V6_EXTPAGE; 2398239268Sgonzo 2399239268Sgonzo /* Clear out the cache */ 2400239268Sgonzo cpu_idcache_wbinv_all(); 2401239268Sgonzo 2402239268Sgonzo /* Set the control register */ 2403239268Sgonzo ctrl = cpuctrl; 2404239268Sgonzo cpu_control(0xFFFFFFFF, cpuctrl); 2405239268Sgonzo 2406239268Sgonzo /* And again. */ 2407239268Sgonzo cpu_idcache_wbinv_all(); 2408239268Sgonzo} 2409239268Sgonzo#endif /* CPU_MV_PJ4B */ 2410239268Sgonzo 2411259640Sganbold#if defined(CPU_CORTEXA) || defined(CPU_KRAIT) 2412239268Sgonzo 2413239268Sgonzovoid 2414239268Sgonzocortexa_setup(char *args) 2415239268Sgonzo{ 2416239268Sgonzo int cpuctrl, cpuctrlmask; 2417239268Sgonzo 2418239268Sgonzo cpuctrlmask = CPU_CONTROL_MMU_ENABLE | /* MMU enable [0] */ 2419239268Sgonzo CPU_CONTROL_AFLT_ENABLE | /* Alignment fault [1] */ 2420239268Sgonzo CPU_CONTROL_DC_ENABLE | /* DCache enable [2] */ 2421239268Sgonzo CPU_CONTROL_BPRD_ENABLE | /* Branch prediction [11] */ 2422239268Sgonzo CPU_CONTROL_IC_ENABLE | /* ICache enable [12] */ 2423239268Sgonzo CPU_CONTROL_VECRELOC; /* Vector relocation [13] */ 2424239268Sgonzo 2425239268Sgonzo cpuctrl = CPU_CONTROL_MMU_ENABLE | 2426239268Sgonzo CPU_CONTROL_IC_ENABLE | 2427239268Sgonzo CPU_CONTROL_DC_ENABLE | 2428239268Sgonzo CPU_CONTROL_BPRD_ENABLE; 2429239268Sgonzo 2430239268Sgonzo#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 2431239268Sgonzo cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 2432239268Sgonzo#endif 2433239268Sgonzo 2434239268Sgonzo /* Switch to big endian */ 2435239268Sgonzo#ifdef __ARMEB__ 2436239268Sgonzo cpuctrl |= CPU_CONTROL_BEND_ENABLE; 2437239268Sgonzo#endif 2438239268Sgonzo 2439239268Sgonzo /* Check if the vector page is at the high address (0xffff0000) */ 2440239268Sgonzo if (vector_page == ARM_VECTORS_HIGH) 2441239268Sgonzo cpuctrl |= CPU_CONTROL_VECRELOC; 2442239268Sgonzo 2443239268Sgonzo /* Clear out the cache */ 2444239268Sgonzo cpu_idcache_wbinv_all(); 2445239268Sgonzo 2446239268Sgonzo /* Set the control register */ 2447239268Sgonzo ctrl = cpuctrl; 2448239268Sgonzo cpu_control(cpuctrlmask, cpuctrl); 2449239268Sgonzo 2450239268Sgonzo /* And again. */ 2451239268Sgonzo cpu_idcache_wbinv_all(); 2452239268Sgonzo#ifdef SMP 2453239268Sgonzo armv7_auxctrl((1 << 6) | (1 << 0), (1 << 6) | (1 << 0)); /* Enable SMP + TLB broadcasting */ 2454239268Sgonzo#endif 2455239268Sgonzo} 2456239268Sgonzo#endif /* CPU_CORTEXA */ 2457239268Sgonzo 2458239268Sgonzo 2459129198Scognet#ifdef CPU_SA110 2460129198Scognetstruct cpu_option sa110_options[] = { 2461129198Scognet#ifdef COMPAT_12 2462129198Scognet { "nocache", IGN, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2463129198Scognet { "nowritebuf", IGN, BIC, CPU_CONTROL_WBUF_ENABLE }, 2464129198Scognet#endif /* COMPAT_12 */ 2465129198Scognet { "cpu.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2466129198Scognet { "cpu.nocache", OR, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2467129198Scognet { "sa110.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2468129198Scognet { "sa110.icache", BIC, OR, CPU_CONTROL_IC_ENABLE }, 2469129198Scognet { "sa110.dcache", BIC, OR, CPU_CONTROL_DC_ENABLE }, 2470129198Scognet { "cpu.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 2471129198Scognet { "cpu.nowritebuf", OR, BIC, CPU_CONTROL_WBUF_ENABLE }, 2472129198Scognet { "sa110.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 2473129198Scognet { NULL, IGN, IGN, 0 } 2474129198Scognet}; 2475129198Scognet 2476129198Scognetvoid 2477129198Scognetsa110_setup(args) 2478129198Scognet char *args; 2479129198Scognet{ 2480129198Scognet int cpuctrl, cpuctrlmask; 2481129198Scognet 2482129198Scognet cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 2483129198Scognet | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 2484129198Scognet | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 2485129198Scognet | CPU_CONTROL_WBUF_ENABLE; 2486129198Scognet cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 2487129198Scognet | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 2488129198Scognet | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 2489129198Scognet | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE 2490129198Scognet | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE 2491129198Scognet | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_BPRD_ENABLE 2492129198Scognet | CPU_CONTROL_CPCLK; 2493129198Scognet 2494129198Scognet#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 2495129198Scognet cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 2496129198Scognet#endif 2497129198Scognet 2498129198Scognet cpuctrl = parse_cpu_options(args, sa110_options, cpuctrl); 2499129198Scognet 2500129198Scognet#ifdef __ARMEB__ 2501129198Scognet cpuctrl |= CPU_CONTROL_BEND_ENABLE; 2502129198Scognet#endif 2503129198Scognet 2504129198Scognet /* Clear out the cache */ 2505129198Scognet cpu_idcache_wbinv_all(); 2506129198Scognet 2507129198Scognet /* Set the control register */ 2508129198Scognet ctrl = cpuctrl; 2509129198Scognet/* cpu_control(cpuctrlmask, cpuctrl);*/ 2510129198Scognet cpu_control(0xffffffff, cpuctrl); 2511129198Scognet 2512236991Simp /* 2513129198Scognet * enable clockswitching, note that this doesn't read or write to r0, 2514129198Scognet * r0 is just to make it valid asm 2515129198Scognet */ 2516129198Scognet __asm ("mcr 15, 0, r0, c15, c1, 2"); 2517129198Scognet} 2518129198Scognet#endif /* CPU_SA110 */ 2519129198Scognet 2520129198Scognet#if defined(CPU_SA1100) || defined(CPU_SA1110) 2521129198Scognetstruct cpu_option sa11x0_options[] = { 2522129198Scognet#ifdef COMPAT_12 2523129198Scognet { "nocache", IGN, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2524129198Scognet { "nowritebuf", IGN, BIC, CPU_CONTROL_WBUF_ENABLE }, 2525129198Scognet#endif /* COMPAT_12 */ 2526129198Scognet { "cpu.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2527129198Scognet { "cpu.nocache", OR, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2528129198Scognet { "sa11x0.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2529129198Scognet { "sa11x0.icache", BIC, OR, CPU_CONTROL_IC_ENABLE }, 2530129198Scognet { "sa11x0.dcache", BIC, OR, CPU_CONTROL_DC_ENABLE }, 2531129198Scognet { "cpu.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 2532129198Scognet { "cpu.nowritebuf", OR, BIC, CPU_CONTROL_WBUF_ENABLE }, 2533129198Scognet { "sa11x0.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 2534129198Scognet { NULL, IGN, IGN, 0 } 2535129198Scognet}; 2536129198Scognet 2537129198Scognetvoid 2538129198Scognetsa11x0_setup(args) 2539129198Scognet char *args; 2540129198Scognet{ 2541129198Scognet int cpuctrl, cpuctrlmask; 2542129198Scognet 2543129198Scognet cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 2544129198Scognet | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 2545129198Scognet | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 2546129198Scognet | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE; 2547129198Scognet cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 2548129198Scognet | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 2549129198Scognet | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 2550129198Scognet | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE 2551129198Scognet | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE 2552129198Scognet | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_BPRD_ENABLE 2553129198Scognet | CPU_CONTROL_CPCLK | CPU_CONTROL_VECRELOC; 2554129198Scognet 2555129198Scognet#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 2556129198Scognet cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 2557129198Scognet#endif 2558129198Scognet 2559129198Scognet 2560129198Scognet cpuctrl = parse_cpu_options(args, sa11x0_options, cpuctrl); 2561129198Scognet 2562129198Scognet#ifdef __ARMEB__ 2563129198Scognet cpuctrl |= CPU_CONTROL_BEND_ENABLE; 2564129198Scognet#endif 2565129198Scognet 2566129198Scognet if (vector_page == ARM_VECTORS_HIGH) 2567129198Scognet cpuctrl |= CPU_CONTROL_VECRELOC; 2568129198Scognet /* Clear out the cache */ 2569129198Scognet cpu_idcache_wbinv_all(); 2570236991Simp /* Set the control register */ 2571129198Scognet ctrl = cpuctrl; 2572129198Scognet cpu_control(0xffffffff, cpuctrl); 2573129198Scognet} 2574129198Scognet#endif /* CPU_SA1100 || CPU_SA1110 */ 2575129198Scognet 2576207611Skevlo#if defined(CPU_FA526) || defined(CPU_FA626TE) 2577201468Srpaulostruct cpu_option fa526_options[] = { 2578201468Srpaulo#ifdef COMPAT_12 2579201468Srpaulo { "nocache", IGN, BIC, (CPU_CONTROL_IC_ENABLE | 2580201468Srpaulo CPU_CONTROL_DC_ENABLE) }, 2581201468Srpaulo { "nowritebuf", IGN, BIC, CPU_CONTROL_WBUF_ENABLE }, 2582201468Srpaulo#endif /* COMPAT_12 */ 2583201468Srpaulo { "cpu.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | 2584201468Srpaulo CPU_CONTROL_DC_ENABLE) }, 2585201468Srpaulo { "cpu.nocache", OR, BIC, (CPU_CONTROL_IC_ENABLE | 2586201468Srpaulo CPU_CONTROL_DC_ENABLE) }, 2587201468Srpaulo { "cpu.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 2588201468Srpaulo { "cpu.nowritebuf", OR, BIC, CPU_CONTROL_WBUF_ENABLE }, 2589201468Srpaulo { NULL, IGN, IGN, 0 } 2590201468Srpaulo}; 2591201468Srpaulo 2592201468Srpaulovoid 2593201468Srpaulofa526_setup(char *args) 2594201468Srpaulo{ 2595201468Srpaulo int cpuctrl, cpuctrlmask; 2596201468Srpaulo 2597201468Srpaulo cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 2598201468Srpaulo | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 2599201468Srpaulo | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 2600204122Skevlo | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE 2601204122Skevlo | CPU_CONTROL_BPRD_ENABLE; 2602201468Srpaulo cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 2603201468Srpaulo | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 2604201468Srpaulo | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 2605201468Srpaulo | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE 2606201468Srpaulo | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE 2607201468Srpaulo | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_BPRD_ENABLE 2608201468Srpaulo | CPU_CONTROL_CPCLK | CPU_CONTROL_VECRELOC; 2609201468Srpaulo 2610201468Srpaulo#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 2611201468Srpaulo cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 2612201468Srpaulo#endif 2613201468Srpaulo 2614201468Srpaulo cpuctrl = parse_cpu_options(args, fa526_options, cpuctrl); 2615201468Srpaulo 2616201468Srpaulo#ifdef __ARMEB__ 2617201468Srpaulo cpuctrl |= CPU_CONTROL_BEND_ENABLE; 2618201468Srpaulo#endif 2619201468Srpaulo 2620201468Srpaulo if (vector_page == ARM_VECTORS_HIGH) 2621201468Srpaulo cpuctrl |= CPU_CONTROL_VECRELOC; 2622201468Srpaulo 2623201468Srpaulo /* Clear out the cache */ 2624201468Srpaulo cpu_idcache_wbinv_all(); 2625201468Srpaulo 2626201468Srpaulo /* Set the control register */ 2627201468Srpaulo ctrl = cpuctrl; 2628201468Srpaulo cpu_control(0xffffffff, cpuctrl); 2629201468Srpaulo} 2630207611Skevlo#endif /* CPU_FA526 || CPU_FA626TE */ 2631201468Srpaulo 2632201468Srpaulo 2633129198Scognet#if defined(CPU_IXP12X0) 2634129198Scognetstruct cpu_option ixp12x0_options[] = { 2635129198Scognet { "cpu.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2636129198Scognet { "cpu.nocache", OR, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2637129198Scognet { "ixp12x0.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2638129198Scognet { "ixp12x0.icache", BIC, OR, CPU_CONTROL_IC_ENABLE }, 2639129198Scognet { "ixp12x0.dcache", BIC, OR, CPU_CONTROL_DC_ENABLE }, 2640129198Scognet { "cpu.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 2641129198Scognet { "cpu.nowritebuf", OR, BIC, CPU_CONTROL_WBUF_ENABLE }, 2642129198Scognet { "ixp12x0.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE }, 2643129198Scognet { NULL, IGN, IGN, 0 } 2644129198Scognet}; 2645129198Scognet 2646129198Scognetvoid 2647129198Scognetixp12x0_setup(args) 2648129198Scognet char *args; 2649129198Scognet{ 2650129198Scognet int cpuctrl, cpuctrlmask; 2651129198Scognet 2652129198Scognet 2653129198Scognet cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_DC_ENABLE 2654129198Scognet | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_SYST_ENABLE 2655129198Scognet | CPU_CONTROL_IC_ENABLE; 2656129198Scognet 2657129198Scognet cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_AFLT_ENABLE 2658129198Scognet | CPU_CONTROL_DC_ENABLE | CPU_CONTROL_WBUF_ENABLE 2659129198Scognet | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_SYST_ENABLE 2660129198Scognet | CPU_CONTROL_ROM_ENABLE | CPU_CONTROL_IC_ENABLE 2661129198Scognet | CPU_CONTROL_VECRELOC; 2662129198Scognet 2663129198Scognet#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 2664129198Scognet cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 2665129198Scognet#endif 2666129198Scognet 2667129198Scognet cpuctrl = parse_cpu_options(args, ixp12x0_options, cpuctrl); 2668129198Scognet 2669129198Scognet#ifdef __ARMEB__ 2670129198Scognet cpuctrl |= CPU_CONTROL_BEND_ENABLE; 2671129198Scognet#endif 2672129198Scognet 2673129198Scognet if (vector_page == ARM_VECTORS_HIGH) 2674129198Scognet cpuctrl |= CPU_CONTROL_VECRELOC; 2675129198Scognet 2676129198Scognet /* Clear out the cache */ 2677129198Scognet cpu_idcache_wbinv_all(); 2678129198Scognet 2679236991Simp /* Set the control register */ 2680129198Scognet ctrl = cpuctrl; 2681129198Scognet /* cpu_control(0xffffffff, cpuctrl); */ 2682129198Scognet cpu_control(cpuctrlmask, cpuctrl); 2683129198Scognet} 2684129198Scognet#endif /* CPU_IXP12X0 */ 2685129198Scognet 2686129198Scognet#if defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \ 2687161592Scognet defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \ 2688164080Scognet defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342) 2689129198Scognetstruct cpu_option xscale_options[] = { 2690129198Scognet#ifdef COMPAT_12 2691129198Scognet { "branchpredict", BIC, OR, CPU_CONTROL_BPRD_ENABLE }, 2692129198Scognet { "nocache", IGN, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2693129198Scognet#endif /* COMPAT_12 */ 2694129198Scognet { "cpu.branchpredict", BIC, OR, CPU_CONTROL_BPRD_ENABLE }, 2695129198Scognet { "cpu.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2696129198Scognet { "cpu.nocache", OR, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2697129198Scognet { "xscale.branchpredict", BIC, OR, CPU_CONTROL_BPRD_ENABLE }, 2698129198Scognet { "xscale.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) }, 2699129198Scognet { "xscale.icache", BIC, OR, CPU_CONTROL_IC_ENABLE }, 2700129198Scognet { "xscale.dcache", BIC, OR, CPU_CONTROL_DC_ENABLE }, 2701129198Scognet { NULL, IGN, IGN, 0 } 2702129198Scognet}; 2703129198Scognet 2704129198Scognetvoid 2705129198Scognetxscale_setup(args) 2706129198Scognet char *args; 2707129198Scognet{ 2708129198Scognet uint32_t auxctl; 2709129198Scognet int cpuctrl, cpuctrlmask; 2710129198Scognet 2711129198Scognet /* 2712129198Scognet * The XScale Write Buffer is always enabled. Our option 2713129198Scognet * is to enable/disable coalescing. Note that bits 6:3 2714129198Scognet * must always be enabled. 2715129198Scognet */ 2716129198Scognet 2717129198Scognet cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 2718129198Scognet | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 2719129198Scognet | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 2720129198Scognet | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE 2721129198Scognet | CPU_CONTROL_BPRD_ENABLE; 2722129198Scognet cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE 2723129198Scognet | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE 2724129198Scognet | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE 2725129198Scognet | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE 2726129198Scognet | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE 2727129198Scognet | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_BPRD_ENABLE 2728171618Scognet | CPU_CONTROL_CPCLK | CPU_CONTROL_VECRELOC | \ 2729171618Scognet CPU_CONTROL_L2_ENABLE; 2730129198Scognet 2731129198Scognet#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS 2732129198Scognet cpuctrl |= CPU_CONTROL_AFLT_ENABLE; 2733129198Scognet#endif 2734129198Scognet 2735129198Scognet cpuctrl = parse_cpu_options(args, xscale_options, cpuctrl); 2736129198Scognet 2737129198Scognet#ifdef __ARMEB__ 2738129198Scognet cpuctrl |= CPU_CONTROL_BEND_ENABLE; 2739129198Scognet#endif 2740129198Scognet 2741129198Scognet if (vector_page == ARM_VECTORS_HIGH) 2742129198Scognet cpuctrl |= CPU_CONTROL_VECRELOC; 2743171618Scognet#ifdef CPU_XSCALE_CORE3 2744171618Scognet cpuctrl |= CPU_CONTROL_L2_ENABLE; 2745171618Scognet#endif 2746129198Scognet 2747129198Scognet /* Clear out the cache */ 2748129198Scognet cpu_idcache_wbinv_all(); 2749129198Scognet 2750129198Scognet /* 2751129198Scognet * Set the control register. Note that bits 6:3 must always 2752129198Scognet * be set to 1. 2753129198Scognet */ 2754129198Scognet ctrl = cpuctrl; 2755129198Scognet/* cpu_control(cpuctrlmask, cpuctrl);*/ 2756129198Scognet cpu_control(0xffffffff, cpuctrl); 2757129198Scognet 2758129198Scognet /* Make sure write coalescing is turned on */ 2759129198Scognet __asm __volatile("mrc p15, 0, %0, c1, c0, 1" 2760129198Scognet : "=r" (auxctl)); 2761129198Scognet#ifdef XSCALE_NO_COALESCE_WRITES 2762129198Scognet auxctl |= XSCALE_AUXCTL_K; 2763129198Scognet#else 2764129198Scognet auxctl &= ~XSCALE_AUXCTL_K; 2765129198Scognet#endif 2766171618Scognet#ifdef CPU_XSCALE_CORE3 2767171618Scognet auxctl |= XSCALE_AUXCTL_LLR; 2768171618Scognet auxctl |= XSCALE_AUXCTL_MD_MASK; 2769171618Scognet#endif 2770129198Scognet __asm __volatile("mcr p15, 0, %0, c1, c0, 1" 2771129198Scognet : : "r" (auxctl)); 2772129198Scognet} 2773236991Simp#endif /* CPU_XSCALE_80200 || CPU_XSCALE_80321 || CPU_XSCALE_PXA2X0 || CPU_XSCALE_IXP425 2774161592Scognet CPU_XSCALE_80219 */ 2775