1/* 2 * armboot - Startup Code for OMAP3530/ARM Cortex CPU-core 3 * 4 * Copyright (c) 2004 Texas Instruments <r-woodruff2@ti.com> 5 * 6 * Copyright (c) 2001 Marius Gröger <mag@sysgo.de> 7 * Copyright (c) 2002 Alex Züpke <azu@sysgo.de> 8 * Copyright (c) 2002 Gary Jennejohn <garyj@denx.de> 9 * Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com> 10 * Copyright (c) 2003 Kshitij <kshitij@ti.com> 11 * Copyright (c) 2006-2008 Syed Mohammed Khasim <x0khasim@ti.com> 12 * 13 * SPDX-License-Identifier: GPL-2.0+ 14 */ 15 16#include <asm-offsets.h> 17#include <config.h> 18#include <asm/system.h> 19#include <linux/linkage.h> 20#include <asm/armv7.h> 21 22/************************************************************************* 23 * 24 * Startup Code (reset vector) 25 * 26 * Do important init only if we don't start from memory! 27 * Setup memory and board specific bits prior to relocation. 28 * Relocate armboot to ram. Setup stack. 29 * 30 *************************************************************************/ 31 32 .globl reset 33 .globl save_boot_params_ret 34 .type save_boot_params_ret,%function 35#ifdef CONFIG_ARMV7_LPAE 36 .global switch_to_hypervisor_ret 37#endif 38 39#if !CONFIG_IS_ENABLED(TINY_FRAMEWORK) 40 41reset: 42 /* Allow the board to save important registers */ 43 b save_boot_params 44save_boot_params_ret: 45#ifdef CONFIG_ARMV7_LPAE 46/* 47 * check for Hypervisor support 48 */ 49 mrc p15, 0, r0, c0, c1, 1 @ read ID_PFR1 50 and r0, r0, #CPUID_ARM_VIRT_MASK @ mask virtualization bits 51 cmp r0, #(1 << CPUID_ARM_VIRT_SHIFT) 52 beq switch_to_hypervisor 53switch_to_hypervisor_ret: 54#endif 55 /* 56 * disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode, 57 * except if in HYP mode already 58 */ 59 mrs r0, cpsr 60 and r1, r0, #0x1f @ mask mode bits 61 teq r1, #0x1a @ test for HYP mode 62 bicne r0, r0, #0x1f @ clear all mode bits 63 orrne r0, r0, #0x13 @ set SVC mode 64 orr r0, r0, #0xc0 @ disable FIQ and IRQ 65 msr cpsr,r0 66 67 /* Enable ACTLR.SMP bit */ 68 mrc p15, 0, r0, c1, c0, 1 69 orr r0, r0, #(1 << 6) @ Enable ACTLR.SMP bit 70 mcr p15, 0, r0, c1, c0, 1 71 72/* 73 * Setup vector: 74 * (OMAP4 spl TEXT_BASE is not 32 byte aligned. 75 * Continue to use ROM code vector only in OMAP4 spl) 76 */ 77#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD)) 78 /* Set V=0 in CP15 SCTLR register - for VBAR to point to vector */ 79 mrc p15, 0, r0, c1, c0, 0 @ Read CP15 SCTLR Register 80 bic r0, #CR_V @ V = 0 81 mcr p15, 0, r0, c1, c0, 0 @ Write CP15 SCTLR Register 82 83 /* Set vector address in CP15 VBAR register */ 84 ldr r0, =_start 85 mcr p15, 0, r0, c12, c0, 0 @Set VBAR 86#endif 87 88 /* Enable Asynchronous external abort after vectors setup */ 89 mrs r0, cpsr 90 bic r0, r0, #0x100 @ CPSR.A bit 91 msr cpsr_x,r0 92 93 /* the mask ROM code should have PLL and others stable */ 94#ifndef CONFIG_SKIP_LOWLEVEL_INIT 95 bl cpu_init_cp15 96#ifndef CONFIG_SKIP_LOWLEVEL_INIT_ONLY 97 bl cpu_init_crit 98#endif 99#endif 100 101 bl _main 102 103/*------------------------------------------------------------------------------*/ 104 105ENTRY(c_runtime_cpu_setup) 106/* 107 * If I-cache is enabled invalidate it 108 */ 109#ifndef CONFIG_SYS_ICACHE_OFF 110 mcr p15, 0, r0, c7, c5, 0 @ invalidate icache 111 mcr p15, 0, r0, c7, c10, 4 @ DSB 112 mcr p15, 0, r0, c7, c5, 4 @ ISB 113#endif 114 115 bx lr 116 117ENDPROC(c_runtime_cpu_setup) 118 119#endif/* !CONFIG_IS_ENABLED(TINY_FRAMEWORK) */ 120 121/************************************************************************* 122 * 123 * void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3) 124 * __attribute__((weak)); 125 * 126 * Stack pointer is not yet initialized at this moment 127 * Don't save anything to stack even if compiled with -O0 128 * 129 *************************************************************************/ 130ENTRY(save_boot_params) 131 b save_boot_params_ret @ back to my caller 132ENDPROC(save_boot_params) 133 .weak save_boot_params 134 135#ifdef CONFIG_ARMV7_LPAE 136ENTRY(switch_to_hypervisor) 137 b switch_to_hypervisor_ret 138ENDPROC(switch_to_hypervisor) 139 .weak switch_to_hypervisor 140#endif 141 142/************************************************************************* 143 * 144 * cpu_init_cp15 145 * 146 * Setup CP15 registers (cache, MMU, TLBs). The I-cache is turned on unless 147 * CONFIG_SYS_ICACHE_OFF is defined. 148 * 149 *************************************************************************/ 150ENTRY(cpu_init_cp15) 151 /* 152 * Invalidate L1 I/D 153 */ 154 mov r0, #0 @ set up for MCR 155 mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs 156 mcr p15, 0, r0, c7, c5, 0 @ invalidate icache 157 mcr p15, 0, r0, c7, c5, 6 @ invalidate BP array 158 mcr p15, 0, r0, c7, c10, 4 @ DSB 159 mcr p15, 0, r0, c7, c5, 4 @ ISB 160 161 /* 162 * disable MMU stuff and caches 163 */ 164 mrc p15, 0, r0, c1, c0, 0 165 bic r0, r0, #0x00002000 @ clear bits 13 (--V-) 166 bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM) 167#if 0 /* There is unalign access when decompress firmware. */ 168 orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align 169#endif 170 orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB 171#ifdef CONFIG_SYS_ICACHE_OFF 172 bic r0, r0, #0x00001000 @ clear bit 12 (I) I-cache 173#else 174 orr r0, r0, #0x00001000 @ set bit 12 (I) I-cache 175#endif 176 mcr p15, 0, r0, c1, c0, 0 177 178#ifdef CONFIG_ARM_ERRATA_716044 179 mrc p15, 0, r0, c1, c0, 0 @ read system control register 180 orr r0, r0, #1 << 11 @ set bit #11 181 mcr p15, 0, r0, c1, c0, 0 @ write system control register 182#endif 183 184#if (defined(CONFIG_ARM_ERRATA_742230) || defined(CONFIG_ARM_ERRATA_794072)) 185 mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register 186 orr r0, r0, #1 << 4 @ set bit #4 187 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register 188#endif 189 190#ifdef CONFIG_ARM_ERRATA_743622 191 mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register 192 orr r0, r0, #1 << 6 @ set bit #6 193 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register 194#endif 195 196#ifdef CONFIG_ARM_ERRATA_751472 197 mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register 198 orr r0, r0, #1 << 11 @ set bit #11 199 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register 200#endif 201#ifdef CONFIG_ARM_ERRATA_761320 202 mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register 203 orr r0, r0, #1 << 21 @ set bit #21 204 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register 205#endif 206 207#ifdef CONFIG_ARM_ERRATA_845369 208 mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register 209 orr r0, r0, #1 << 22 @ set bit #22 210 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register 211#endif 212 213 mov r5, lr @ Store my Caller 214 mrc p15, 0, r1, c0, c0, 0 @ r1 has Read Main ID Register (MIDR) 215 mov r3, r1, lsr #20 @ get variant field 216 and r3, r3, #0xf @ r3 has CPU variant 217 and r4, r1, #0xf @ r4 has CPU revision 218 mov r2, r3, lsl #4 @ shift variant field for combined value 219 orr r2, r4, r2 @ r2 has combined CPU variant + revision 220 221#ifdef CONFIG_ARM_ERRATA_798870 222 cmp r2, #0x30 @ Applies to lower than R3p0 223 bge skip_errata_798870 @ skip if not affected rev 224 cmp r2, #0x20 @ Applies to including and above R2p0 225 blt skip_errata_798870 @ skip if not affected rev 226 227 mrc p15, 1, r0, c15, c0, 0 @ read l2 aux ctrl reg 228 orr r0, r0, #1 << 7 @ Enable hazard-detect timeout 229 push {r1-r5} @ Save the cpu info registers 230 bl v7_arch_cp15_set_l2aux_ctrl 231 isb @ Recommended ISB after l2actlr update 232 pop {r1-r5} @ Restore the cpu info - fall through 233skip_errata_798870: 234#endif 235 236#ifdef CONFIG_ARM_ERRATA_801819 237 cmp r2, #0x24 @ Applies to lt including R2p4 238 bgt skip_errata_801819 @ skip if not affected rev 239 cmp r2, #0x20 @ Applies to including and above R2p0 240 blt skip_errata_801819 @ skip if not affected rev 241 mrc p15, 0, r0, c0, c0, 6 @ pick up REVIDR reg 242 and r0, r0, #1 << 3 @ check REVIDR[3] 243 cmp r0, #1 << 3 244 beq skip_errata_801819 @ skip erratum if REVIDR[3] is set 245 246 mrc p15, 0, r0, c1, c0, 1 @ read auxilary control register 247 orr r0, r0, #3 << 27 @ Disables streaming. All write-allocate 248 @ lines allocate in the L1 or L2 cache. 249 orr r0, r0, #3 << 25 @ Disables streaming. All write-allocate 250 @ lines allocate in the L1 cache. 251 push {r1-r5} @ Save the cpu info registers 252 bl v7_arch_cp15_set_acr 253 pop {r1-r5} @ Restore the cpu info - fall through 254skip_errata_801819: 255#endif 256 257#ifdef CONFIG_ARM_ERRATA_454179 258 cmp r2, #0x21 @ Only on < r2p1 259 bge skip_errata_454179 260 261 mrc p15, 0, r0, c1, c0, 1 @ Read ACR 262 orr r0, r0, #(0x3 << 6) @ Set DBSM(BIT7) and IBE(BIT6) bits 263 push {r1-r5} @ Save the cpu info registers 264 bl v7_arch_cp15_set_acr 265 pop {r1-r5} @ Restore the cpu info - fall through 266 267skip_errata_454179: 268#endif 269 270#ifdef CONFIG_ARM_ERRATA_430973 271 cmp r2, #0x21 @ Only on < r2p1 272 bge skip_errata_430973 273 274 mrc p15, 0, r0, c1, c0, 1 @ Read ACR 275 orr r0, r0, #(0x1 << 6) @ Set IBE bit 276 push {r1-r5} @ Save the cpu info registers 277 bl v7_arch_cp15_set_acr 278 pop {r1-r5} @ Restore the cpu info - fall through 279 280skip_errata_430973: 281#endif 282 283#ifdef CONFIG_ARM_ERRATA_621766 284 cmp r2, #0x21 @ Only on < r2p1 285 bge skip_errata_621766 286 287 mrc p15, 0, r0, c1, c0, 1 @ Read ACR 288 orr r0, r0, #(0x1 << 5) @ Set L1NEON bit 289 push {r1-r5} @ Save the cpu info registers 290 bl v7_arch_cp15_set_acr 291 pop {r1-r5} @ Restore the cpu info - fall through 292 293skip_errata_621766: 294#endif 295 296#ifdef CONFIG_ARM_ERRATA_725233 297 cmp r2, #0x21 @ Only on < r2p1 (Cortex A8) 298 bge skip_errata_725233 299 300 mrc p15, 1, r0, c9, c0, 2 @ Read L2ACR 301 orr r0, r0, #(0x1 << 27) @ L2 PLD data forwarding disable 302 push {r1-r5} @ Save the cpu info registers 303 bl v7_arch_cp15_set_l2aux_ctrl 304 pop {r1-r5} @ Restore the cpu info - fall through 305 306skip_errata_725233: 307#endif 308 309#ifdef CONFIG_ARM_ERRATA_852421 310 mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register 311 orr r0, r0, #1 << 24 @ set bit #24 312 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register 313#endif 314 315#ifdef CONFIG_ARM_ERRATA_852423 316 mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register 317 orr r0, r0, #1 << 12 @ set bit #12 318 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register 319#endif 320 321#if defined(CONFIG_ARM_ZERO_CNTVOFF) && defined(CONFIG_SPL_BUILD) 322 /* 323 * CNTVOFF usage constraints: 324 * Only accessible from Hyp mode, or from Monitor mode when SCR.NS is 325 * set to 1. 326 */ 327 /* switch to MON */ 328 cps #22 329 isb 330 331 /* Update SCR.NS to non Secure mode */ 332 mrc p15, 0, r0, c1, c1, 0 333 orr r0, r0, #(1 << 0) 334 mcr p15, 0, r0, c1, c1, 0 335 isb 336 337 /* set vtimer virtual offset 0 */ 338 mov r0, #0 339 mcrr p15, 4, r0, r0, c14 @ CNTVOFF 340 341 /* Update SCR.NS to Secure mode */ 342 mrc p15, 0, r0, c1, c1, 0 343 bic r0, r0, #(1 << 0) 344 mcr p15, 0, r0, c1, c1, 0 345 isb 346 347 /* switch back to SVC */ 348 cps #19 349 isb 350#endif 351 352 mov pc, r5 @ back to my caller 353ENDPROC(cpu_init_cp15) 354 355#if !defined(CONFIG_SKIP_LOWLEVEL_INIT) && \ 356 !defined(CONFIG_SKIP_LOWLEVEL_INIT_ONLY) 357/************************************************************************* 358 * 359 * CPU_init_critical registers 360 * 361 * setup important registers 362 * setup memory timing 363 * 364 *************************************************************************/ 365ENTRY(cpu_init_crit) 366 /* 367 * Jump to board specific initialization... 368 * The Mask ROM will have already initialized 369 * basic memory. Go here to bump up clock rate and handle 370 * wake up conditions. 371 */ 372 b lowlevel_init @ go setup pll,mux,memory 373ENDPROC(cpu_init_crit) 374#endif 375