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#include <system-constants.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 39reset: 40 /* Allow the board to save important registers */ 41 b save_boot_params 42save_boot_params_ret: 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 label */ 50 ldr r1, =reset /* r1 <- Linked value of reset label */ 51 subs r4, r0, r1 /* r4 <- Runtime-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_end */ 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 offset */ 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 76pie_fixup_done: 77#endif 78 79#ifdef CONFIG_ARMV7_LPAE 80/* 81 * check for Hypervisor support 82 */ 83 mrc p15, 0, r0, c0, c1, 1 @ read ID_PFR1 84 and r0, r0, #CPUID_ARM_VIRT_MASK @ mask virtualization bits 85 cmp r0, #(1 << CPUID_ARM_VIRT_SHIFT) 86 beq switch_to_hypervisor 87switch_to_hypervisor_ret: 88#endif 89 /* 90 * disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode, 91 * except if in HYP mode already 92 */ 93 mrs r0, cpsr 94 and r1, r0, #0x1f @ mask mode bits 95 teq r1, #0x1a @ test for HYP mode 96 bicne r0, r0, #0x1f @ clear all mode bits 97 orrne r0, r0, #0x13 @ set SVC mode 98 orr r0, r0, #0xc0 @ disable FIQ and IRQ 99 msr cpsr,r0 100 101#if !CONFIG_IS_ENABLED(SYS_NO_VECTOR_TABLE) 102/* 103 * Setup vector: 104 */ 105 /* Set V=0 in CP15 SCTLR register - for VBAR to point to vector */ 106 mrc p15, 0, r0, c1, c0, 0 @ Read CP15 SCTLR Register 107 bic r0, #CR_V @ V = 0 108 mcr p15, 0, r0, c1, c0, 0 @ Write CP15 SCTLR Register 109 110#ifdef CONFIG_HAS_VBAR 111 /* Set vector address in CP15 VBAR register */ 112 ldr r0, =_start 113 mcr p15, 0, r0, c12, c0, 0 @Set VBAR 114#endif 115#endif 116 117 /* the mask ROM code should have PLL and others stable */ 118#if !CONFIG_IS_ENABLED(SKIP_LOWLEVEL_INIT) 119#ifdef CONFIG_CPU_V7A 120 bl cpu_init_cp15 121#endif 122#if !CONFIG_IS_ENABLED(SKIP_LOWLEVEL_INIT_ONLY) 123 bl cpu_init_crit 124#endif 125#endif 126 127 bl _main 128 129/*------------------------------------------------------------------------------*/ 130 131ENTRY(c_runtime_cpu_setup) 132/* 133 * If I-cache is enabled invalidate it 134 */ 135#if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF) 136 mcr p15, 0, r0, c7, c5, 0 @ invalidate icache 137 dsb 138 isb 139#endif 140 141 bx lr 142 143ENDPROC(c_runtime_cpu_setup) 144 145/************************************************************************* 146 * 147 * void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3) 148 * __attribute__((weak)); 149 * 150 * Stack pointer is not yet initialized at this moment 151 * Don't save anything to stack even if compiled with -O0 152 * 153 *************************************************************************/ 154WEAK(save_boot_params) 155#if (IS_ENABLED(CONFIG_BLOBLIST)) 156 /* Calculate the PC-relative address of saved_args */ 157 adr r12, saved_args_offset 158 ldr r13, saved_args_offset 159 add r12, r12, r13 160 161 /* 162 * Intentionally swapping r0 with r2 in order to simplify the C 163 * function we use later. 164 */ 165 str r2, [r12] 166 str r1, [r12, #4] 167 str r0, [r12, #8] 168 str r3, [r12, #12] 169#endif 170 b save_boot_params_ret @ back to my caller 171ENDPROC(save_boot_params) 172 173#if (IS_ENABLED(CONFIG_BLOBLIST)) 174saved_args_offset: 175 .long saved_args - . /* offset from current code to save_args */ 176 177 .section .data 178 .align 2 179 .global saved_args 180saved_args: 181 .rept 4 182 .word 0 183 .endr 184END(saved_args) 185#endif 186 187#ifdef CONFIG_ARMV7_LPAE 188WEAK(switch_to_hypervisor) 189 b switch_to_hypervisor_ret 190ENDPROC(switch_to_hypervisor) 191#endif 192 193/************************************************************************* 194 * 195 * cpu_init_cp15 196 * 197 * Setup CP15 registers (cache, MMU, TLBs). The I-cache is turned on unless 198 * CONFIG_SYS_ICACHE_OFF is defined. 199 * 200 *************************************************************************/ 201ENTRY(cpu_init_cp15) 202 203#if CONFIG_IS_ENABLED(ARMV7_SET_CORTEX_SMPEN) 204 /* 205 * The Arm Cortex-A7 TRM says this bit must be enabled before 206 * "any cache or TLB maintenance operations are performed". 207 */ 208 mrc p15, 0, r0, c1, c0, 1 @ read auxilary control register 209 orr r0, r0, #1 << 6 @ set SMP bit to enable coherency 210 mcr p15, 0, r0, c1, c0, 1 @ write auxilary control register 211#endif 212 213 /* 214 * Invalidate L1 I/D 215 */ 216 mov r0, #0 @ set up for MCR 217 mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs 218 mcr p15, 0, r0, c7, c5, 0 @ invalidate icache 219 mcr p15, 0, r0, c7, c5, 6 @ invalidate BP array 220 dsb 221 isb 222 223 /* 224 * disable MMU stuff and caches 225 */ 226 mrc p15, 0, r0, c1, c0, 0 227 bic r0, r0, #0x00002000 @ clear bits 13 (--V-) 228 bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM) 229 orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align 230 orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB 231#if CONFIG_IS_ENABLED(SYS_ICACHE_OFF) 232 bic r0, r0, #0x00001000 @ clear bit 12 (I) I-cache 233#else 234 orr r0, r0, #0x00001000 @ set bit 12 (I) I-cache 235#endif 236 mcr p15, 0, r0, c1, c0, 0 237 238#ifdef CONFIG_ARM_ERRATA_716044 239 mrc p15, 0, r0, c1, c0, 0 @ read system control register 240 orr r0, r0, #1 << 11 @ set bit #11 241 mcr p15, 0, r0, c1, c0, 0 @ write system control register 242#endif 243 244#if (defined(CONFIG_ARM_ERRATA_742230) || defined(CONFIG_ARM_ERRATA_794072)) 245 mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register 246 orr r0, r0, #1 << 4 @ set bit #4 247 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register 248#endif 249 250#ifdef CONFIG_ARM_ERRATA_743622 251 mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register 252 orr r0, r0, #1 << 6 @ set bit #6 253 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register 254#endif 255 256#ifdef CONFIG_ARM_ERRATA_751472 257 mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register 258 orr r0, r0, #1 << 11 @ set bit #11 259 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register 260#endif 261#ifdef CONFIG_ARM_ERRATA_761320 262 mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register 263 orr r0, r0, #1 << 21 @ set bit #21 264 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register 265#endif 266 267#ifdef CONFIG_ARM_ERRATA_845369 268 mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register 269 orr r0, r0, #1 << 22 @ set bit #22 270 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register 271#endif 272 273 mov r5, lr @ Store my Caller 274 mrc p15, 0, r1, c0, c0, 0 @ r1 has Read Main ID Register (MIDR) 275 mov r3, r1, lsr #20 @ get variant field 276 and r3, r3, #0xf @ r3 has CPU variant 277 and r4, r1, #0xf @ r4 has CPU revision 278 mov r2, r3, lsl #4 @ shift variant field for combined value 279 orr r2, r4, r2 @ r2 has combined CPU variant + revision 280 281/* Early stack for ERRATA that needs into call C code */ 282#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK) 283 ldr r0, =(CONFIG_SPL_STACK) 284#else 285 ldr r0, =(SYS_INIT_SP_ADDR) 286#endif 287 bic r0, r0, #7 /* 8-byte alignment for ABI compliance */ 288 mov sp, r0 289 290#ifdef CONFIG_ARM_ERRATA_798870 291 cmp r2, #0x30 @ Applies to lower than R3p0 292 bge skip_errata_798870 @ skip if not affected rev 293 cmp r2, #0x20 @ Applies to including and above R2p0 294 blt skip_errata_798870 @ skip if not affected rev 295 296 mrc p15, 1, r0, c15, c0, 0 @ read l2 aux ctrl reg 297 orr r0, r0, #1 << 7 @ Enable hazard-detect timeout 298 push {r1-r5} @ Save the cpu info registers 299 bl v7_arch_cp15_set_l2aux_ctrl 300 isb @ Recommended ISB after l2actlr update 301 pop {r1-r5} @ Restore the cpu info - fall through 302skip_errata_798870: 303#endif 304 305#ifdef CONFIG_ARM_ERRATA_801819 306 cmp r2, #0x24 @ Applies to lt including R2p4 307 bgt skip_errata_801819 @ skip if not affected rev 308 cmp r2, #0x20 @ Applies to including and above R2p0 309 blt skip_errata_801819 @ skip if not affected rev 310 mrc p15, 0, r0, c0, c0, 6 @ pick up REVIDR reg 311 and r0, r0, #1 << 3 @ check REVIDR[3] 312 cmp r0, #1 << 3 313 beq skip_errata_801819 @ skip erratum if REVIDR[3] is set 314 315 mrc p15, 0, r0, c1, c0, 1 @ read auxilary control register 316 orr r0, r0, #3 << 27 @ Disables streaming. All write-allocate 317 @ lines allocate in the L1 or L2 cache. 318 orr r0, r0, #3 << 25 @ Disables streaming. All write-allocate 319 @ lines allocate in the L1 cache. 320 push {r1-r5} @ Save the cpu info registers 321 bl v7_arch_cp15_set_acr 322 pop {r1-r5} @ Restore the cpu info - fall through 323skip_errata_801819: 324#endif 325 326#ifdef CONFIG_ARM_CORTEX_A15_CVE_2017_5715 327 mrc p15, 0, r0, c1, c0, 1 @ read auxilary control register 328 orr r0, r0, #1 << 0 @ Enable invalidates of BTB 329 push {r1-r5} @ Save the cpu info registers 330 bl v7_arch_cp15_set_acr 331 pop {r1-r5} @ Restore the cpu info - fall through 332#endif 333 334#ifdef CONFIG_ARM_ERRATA_454179 335 mrc p15, 0, r0, c1, c0, 1 @ Read ACR 336 337 cmp r2, #0x21 @ Only on < r2p1 338 orrlt r0, r0, #(0x3 << 6) @ Set DBSM(BIT7) and IBE(BIT6) bits 339 340 push {r1-r5} @ Save the cpu info registers 341 bl v7_arch_cp15_set_acr 342 pop {r1-r5} @ Restore the cpu info - fall through 343#endif 344 345#if defined(CONFIG_ARM_ERRATA_430973) || defined (CONFIG_ARM_CORTEX_A8_CVE_2017_5715) 346 mrc p15, 0, r0, c1, c0, 1 @ Read ACR 347 348#ifdef CONFIG_ARM_CORTEX_A8_CVE_2017_5715 349 orr r0, r0, #(0x1 << 6) @ Set IBE bit always to enable OS WA 350#else 351 cmp r2, #0x21 @ Only on < r2p1 352 orrlt r0, r0, #(0x1 << 6) @ Set IBE bit 353#endif 354 push {r1-r5} @ Save the cpu info registers 355 bl v7_arch_cp15_set_acr 356 pop {r1-r5} @ Restore the cpu info - fall through 357#endif 358 359#ifdef CONFIG_ARM_ERRATA_621766 360 mrc p15, 0, r0, c1, c0, 1 @ Read ACR 361 362 cmp r2, #0x21 @ Only on < r2p1 363 orrlt r0, r0, #(0x1 << 5) @ Set L1NEON bit 364 365 push {r1-r5} @ Save the cpu info registers 366 bl v7_arch_cp15_set_acr 367 pop {r1-r5} @ Restore the cpu info - fall through 368#endif 369 370#ifdef CONFIG_ARM_ERRATA_725233 371 mrc p15, 1, r0, c9, c0, 2 @ Read L2ACR 372 373 cmp r2, #0x21 @ Only on < r2p1 (Cortex A8) 374 orrlt r0, r0, #(0x1 << 27) @ L2 PLD data forwarding disable 375 376 push {r1-r5} @ Save the cpu info registers 377 bl v7_arch_cp15_set_l2aux_ctrl 378 pop {r1-r5} @ Restore the cpu info - fall through 379#endif 380 381#ifdef CONFIG_ARM_ERRATA_852421 382 mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register 383 orr r0, r0, #1 << 24 @ set bit #24 384 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register 385#endif 386 387#ifdef CONFIG_ARM_ERRATA_852423 388 mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register 389 orr r0, r0, #1 << 12 @ set bit #12 390 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register 391#endif 392 393 mov pc, r5 @ back to my caller 394ENDPROC(cpu_init_cp15) 395 396#if !CONFIG_IS_ENABLED(SKIP_LOWLEVEL_INIT) && \ 397 !CONFIG_IS_ENABLED(SKIP_LOWLEVEL_INIT_ONLY) 398/************************************************************************* 399 * 400 * CPU_init_critical registers 401 * 402 * setup important registers 403 * setup memory timing 404 * 405 *************************************************************************/ 406ENTRY(cpu_init_crit) 407 /* 408 * Jump to board specific initialization... 409 * The Mask ROM will have already initialized 410 * basic memory. Go here to bump up clock rate and handle 411 * wake up conditions. 412 */ 413 b lowlevel_init @ go setup pll,mux,memory 414ENDPROC(cpu_init_crit) 415#endif 416 417#if CONFIG_POSITION_INDEPENDENT 418_rel_dyn_start_ofs: 419 .word __rel_dyn_start - pie_fixup 420_rel_dyn_end_ofs: 421 .word __rel_dyn_end - pie_fixup 422#endif 423