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