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.globl _start 32_start: 33 b reset 34 b . 35 b . 36 b . 37 b . 38 b . 39 b . 40 b . 41 .balignl 64,0xdeadbeef 42 43 .globl reset 44 .globl save_boot_params_ret 45#ifdef CONFIG_ARMV7_LPAE 46 .global switch_to_hypervisor_ret 47#endif 48 49 __blank_zone_start: 50 .fill 1024*8,1,0 51__blank_zone_end: 52 53 .globl _blank_zone_start 54_blank_zone_start: 55 .word __blank_zone_start 56 57 58 .globl _blank_zone_end 59_blank_zone_end: 60 .word __blank_zone_end 61 62 .balignl 16,0xdeadbeef 63 .globl _TEXT_BASE 64_TEXT_BASE: 65 .word TEXT_BASE 66 67 68_clr_remap_fmc_entry: 69 .word FMC_TEXT_ADRS + do_clr_remap - CONFIG_SYS_TEXT_BASE_ORI 70 71_start_armboot: 72 .word start_armboot 73 74reset: 75 /* Allow the board to save important registers */ 76 b save_boot_params 77save_boot_params_ret: 78#ifdef CONFIG_ARMV7_LPAE 79/* 80 * check for Hypervisor support 81 */ 82 mrc p15, 0, r0, c0, c1, 1 @ read ID_PFR1 83 and r0, r0, #CPUID_ARM_VIRT_MASK @ mask virtualization bits 84 cmp r0, #(1 << CPUID_ARM_VIRT_SHIFT) 85 beq switch_to_hypervisor 86switch_to_hypervisor_ret: 87#endif 88 /* 89 * disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode, 90 * except if in HYP mode already 91 */ 92 mrs r0, cpsr 93 and r1, r0, #0x1f @ mask mode bits 94 teq r1, #0x1a @ test for HYP mode 95 bicne r0, r0, #0x1f @ clear all mode bits 96 orrne r0, r0, #0x13 @ set SVC mode 97 orr r0, r0, #0xc0 @ disable FIQ and IRQ 98 msr cpsr,r0 99 100 mov r0, #0x55 101 mcr p15, 0,r0, c3,c0,0 @ set DACR accesses are checked 102 103/* 104 * Setup vector: 105 * (OMAP4 spl TEXT_BASE is not 32 byte aligned. 106 * Continue to use ROM code vector only in OMAP4 spl) 107 */ 108#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD)) 109 /* Set V=0 in CP15 SCTLR register - for VBAR to point to vector */ 110 mrc p15, 0, r0, c1, c0, 0 @ Read CP15 SCTLR Register 111 bic r0, #CR_V @ V = 0 112 mcr p15, 0, r0, c1, c0, 0 @ Write CP15 SCTLR Register 113 114 /* Set vector address in CP15 VBAR register */ 115 adrl r0, _start 116 mcr p15, 0, r0, c12, c0, 0 @Set VBAR 117#endif 118 119 /* the mask ROM code should have PLL and others stable */ 120#ifndef CONFIG_SKIP_LOWLEVEL_INIT 121 bl cpu_init_cp15 122#ifndef CONFIG_SKIP_LOWLEVEL_INIT_ONLY 123 bl cpu_init_crit 124#endif 125#endif 126 127#ifndef CONFIG_HISI_DISABLE_DOWNLOAD 128 /* 129 * read system register REG_SC_GEN2 130 * check if ziju flag 131 */ 132 ldr r0, =SYS_CTRL_REG_BASE 133 ldr r1, [r0, #REG_SC_GEN2] 134 ldr r2, =0x7a696a75 /* magic for "ziju" */ 135 cmp r1, r2 136 bne normal_start_flow 137 mov r1, sp /* save sp */ 138 str r1, [r0, #REG_SC_GEN2] /* clear ziju flag */ 139 140 /* init PLL/DDRC/pin mux/... */ 141 ldr r0, _blank_zone_start 142 ldr r1, _TEXT_BASE 143 sub r0, r0, r1 144 ldr r1, =RAM_START_ADRS 145 ldr sp, =STACK_TRAINING 146 add r0, r0, r1 147 mov r1, #0x0 /* flags: 0->normal 1->pm */ 148 bl init_registers /* init PLL/DDRC/... */ 149 /* after ziju, we need ddr traning */ 150 ldr r0, =REG_BASE_SCTL 151 152 bl start_ddr_training /* DDR training */ 153 ldr r0, =SYS_CTRL_REG_BASE 154 ldr r1, [r0, #REG_SC_GEN2] 155 mov sp, r1 /* restore sp */ 156 ldr r1, [r0, #REG_SC_GEN3] 157 mov pc, r1 /* return to bootrom */ 158 nop 159 nop 160 nop 161 nop 162 nop 163 nop 164 nop 165 nop 166 b . /* bug here */ 167 168normal_start_flow: 169#endif 170 /* init serial and printf a string. */ 171 ldr sp, =STACK_TRAINING 172 bl uart_early_init 173 bl msg_main_cpu_startup 174 175 /* 176 * enable syscnt 177 */ 178 ldr r0, =SYSCNT_REG_BASE 179 ldr r3, =SYSCNT_FREQ 180 str r3, [r0, #SYSCNT_FREQ_REG] 181 mov r3, #0x1 182 str r3, [r0, #SYSCNT_ENABLE_REG] 183 184 @if running not boot from nand/spi/emmc, 185 @we skipping boot_type checking. 186 mov r0, pc, lsr#24 187 cmp r0, #0x0 188 bne do_clr_remap 189 190check_boot_type: 191 ldr r0, =SYS_CTRL_REG_BASE 192 ldr r0, [r0, #REG_SYSSTAT] 193 mov r6, r0, lsr #3 194 and r6, #0x1 195 cmp r6, #0x1 196 ldrlo pc, _clr_remap_fmc_entry 197 198do_clr_remap: 199 /* do clear remap */ 200 ldr r4, =SYS_CTRL_REG_BASE 201 ldr r0, [r4, #REG_SC_CTRL] 202 203 @Set clear remap bit. 204 orr r0, #(1<<8) 205 str r0, [r4, #REG_SC_CTRL] 206 207 @enable I-Cache now 208 mrc p15, 0, r0, c1, c0, 0 209 orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */ 210 mcr p15, 0, r0, c1, c0, 0 211 212 @Check wether I am running in dynamic mem bank:<0x40000000 213 mov r0, pc, lsr#28 214 cmp r0, #4 215 blo ddr_init 216 217no_ddr_init: 218 adrl r0, _start 219 b copy_to_ddr 220 221ddr_init: 222 ldr r0, _blank_zone_start 223 ldr r1, _TEXT_BASE 224 sub r0, r0, r1 225 adrl r1, _start 226 add r0, r0, r1 227 mov r1, #0 /* flags: 0->normal 1->pm */ 228 bl init_registers 229 230 ldr sp, =STACK_TRAINING 231 ldr r0, =REG_BASE_SCTL 232 bl start_ddr_training /* DDR training */ 233 234check_boot_mode: 235 ldr r0, =SYS_CTRL_REG_BASE 236 ldr r0, [r0, #REG_SYSSTAT] 237 mov r6, r0, lsr #BOOT_SEL_SHIFT 238 and r6, #0x3 239 cmp r6, #BOOT_FROM_EMMC 240 bne copy_flash_to_ddr 241 242emmc_boot: 243 ldr r0, _TEXT_BASE 244 ldr r1, =__image_copy_start 245 ldr r2, =__bss_start 246 sub r1, r2, r1 247 bl emmc_boot_read 248 b relocate 249 250copy_flash_to_ddr: 251 /* relocate SPI nor/nand Boot to DDR */ 252 ldr r0, =FMC_TEXT_ADRS 253 254copy_to_ddr: 255 /* now, r0 stores __reset offset from where we get started */ 256 ldr r1, =__image_copy_start 257 258 /* compare source and target address, * 259 *if equal no copy to target address */ 260 cmp r0, r1 261 beq start_armboot 262 263 ldr r2, =__image_copy_start/*_start*/ 264 ldr r3, =__bss_start 265 sub r2, r3, r2 /* r2 <- size of armboot */ 266 /* memcpy(r1, r0, r2) */ 267 bl memcpy 268 269relocate: 270 ldr r0, =_start_armboot 271 ldr pc, [r0] 272 273bug: 274 nop 275 nop 276 nop 277 nop 278 nop 279 nop 280 nop 281 nop 282 b . /* bug here */ 283@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 284@ 285@ void memcpy(r1, r0, r2); 286@ 287 288.align 2 289memcpy: 290 add r2, r0, r2 291 memcpy_loop: 292 ldmia r0!, {r3 - r10} 293 stmia r1!, {r3 - r10} 294 cmp r0, r2 295 ble memcpy_loop 296 mov pc, lr 297 298@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 299 300.align 2 301msg_main_cpu_startup: 302 mov r5, lr 303 add r0, pc, #4 304 bl uart_early_puts 305 mov pc, r5 306 L10: 307#ifndef CONFIG_SUPPORT_CA_RELEASE 308 .ascii "\r\n\r\nSystem startup\r\n\0" 309#else 310 .ascii "\r\n\r\n\r\n\0" 311#endif 312 313/*------------------------------------------------------------------------------*/ 314 315ENTRY(c_runtime_cpu_setup) 316/* 317 * If I-cache is enabled invalidate it 318 */ 319#ifndef CONFIG_SYS_ICACHE_OFF 320 mcr p15, 0, r0, c7, c5, 0 @ invalidate icache 321 mcr p15, 0, r0, c7, c10, 4 @ DSB 322 mcr p15, 0, r0, c7, c5, 4 @ ISB 323#endif 324 325 bx lr 326 327ENDPROC(c_runtime_cpu_setup) 328 329/************************************************************************* 330 * 331 * void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3) 332 * __attribute__((weak)); 333 * 334 * Stack pointer is not yet initialized at this moment 335 * Don't save anything to stack even if compiled with -O0 336 * 337 *************************************************************************/ 338ENTRY(save_boot_params) 339 b save_boot_params_ret @ back to my caller 340ENDPROC(save_boot_params) 341 .weak save_boot_params 342 343#ifdef CONFIG_ARMV7_LPAE 344ENTRY(switch_to_hypervisor) 345 b switch_to_hypervisor_ret 346ENDPROC(switch_to_hypervisor) 347 .weak switch_to_hypervisor 348#endif 349 350/************************************************************************* 351 * 352 * cpu_init_cp15 353 * 354 * Setup CP15 registers (cache, MMU, TLBs). The I-cache is turned on unless 355 * CONFIG_SYS_ICACHE_OFF is defined. 356 * 357 *************************************************************************/ 358ENTRY(cpu_init_cp15) 359 /* 360 * Invalidate L1 I/D 361 */ 362 mov r0, #0 @ set up for MCR 363 mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs 364 mcr p15, 0, r0, c7, c5, 0 @ invalidate icache 365 mcr p15, 0, r0, c7, c5, 6 @ invalidate BP array 366 mcr p15, 0, r0, c7, c10, 4 @ DSB 367 mcr p15, 0, r0, c7, c5, 4 @ ISB 368 369 /* 370 * disable MMU stuff and caches 371 */ 372 mrc p15, 0, r0, c1, c0, 0 373 bic r0, r0, #0x00002000 @ clear bits 13 (--V-) 374 bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM) 375 orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align 376 orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB 377#ifdef CONFIG_SYS_ICACHE_OFF 378 bic r0, r0, #0x00001000 @ clear bit 12 (I) I-cache 379#else 380 orr r0, r0, #0x00001000 @ set bit 12 (I) I-cache 381#endif 382 mcr p15, 0, r0, c1, c0, 0 383 384#ifdef CONFIG_ARM_ERRATA_716044 385 mrc p15, 0, r0, c1, c0, 0 @ read system control register 386 orr r0, r0, #1 << 11 @ set bit #11 387 mcr p15, 0, r0, c1, c0, 0 @ write system control register 388#endif 389 390#if (defined(CONFIG_ARM_ERRATA_742230) || defined(CONFIG_ARM_ERRATA_794072)) 391 mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register 392 orr r0, r0, #1 << 4 @ set bit #4 393 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register 394#endif 395 396#ifdef CONFIG_ARM_ERRATA_743622 397 mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register 398 orr r0, r0, #1 << 6 @ set bit #6 399 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register 400#endif 401 402#ifdef CONFIG_ARM_ERRATA_751472 403 mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register 404 orr r0, r0, #1 << 11 @ set bit #11 405 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register 406#endif 407#ifdef CONFIG_ARM_ERRATA_761320 408 mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register 409 orr r0, r0, #1 << 21 @ set bit #21 410 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register 411#endif 412 413 mov r5, lr @ Store my Caller 414 mrc p15, 0, r1, c0, c0, 0 @ r1 has Read Main ID Register (MIDR) 415 mov r3, r1, lsr #20 @ get variant field 416 and r3, r3, #0xf @ r3 has CPU variant 417 and r4, r1, #0xf @ r4 has CPU revision 418 mov r2, r3, lsl #4 @ shift variant field for combined value 419 orr r2, r4, r2 @ r2 has combined CPU variant + revision 420 421#ifdef CONFIG_ARM_ERRATA_798870 422 cmp r2, #0x30 @ Applies to lower than R3p0 423 bge skip_errata_798870 @ skip if not affected rev 424 cmp r2, #0x20 @ Applies to including and above R2p0 425 blt skip_errata_798870 @ skip if not affected rev 426 427 mrc p15, 1, r0, c15, c0, 0 @ read l2 aux ctrl reg 428 orr r0, r0, #1 << 7 @ Enable hazard-detect timeout 429 push {r1-r5} @ Save the cpu info registers 430 bl v7_arch_cp15_set_l2aux_ctrl 431 isb @ Recommended ISB after l2actlr update 432 pop {r1-r5} @ Restore the cpu info - fall through 433skip_errata_798870: 434#endif 435 436#ifdef CONFIG_ARM_ERRATA_801819 437 cmp r2, #0x24 @ Applies to lt including R2p4 438 bgt skip_errata_801819 @ skip if not affected rev 439 cmp r2, #0x20 @ Applies to including and above R2p0 440 blt skip_errata_801819 @ skip if not affected rev 441 mrc p15, 0, r0, c0, c0, 6 @ pick up REVIDR reg 442 and r0, r0, #1 << 3 @ check REVIDR[3] 443 cmp r0, #1 << 3 444 beq skip_errata_801819 @ skip erratum if REVIDR[3] is set 445 446 mrc p15, 0, r0, c1, c0, 1 @ read auxilary control register 447 orr r0, r0, #3 << 27 @ Disables streaming. All write-allocate 448 @ lines allocate in the L1 or L2 cache. 449 orr r0, r0, #3 << 25 @ Disables streaming. All write-allocate 450 @ lines allocate in the L1 cache. 451 push {r1-r5} @ Save the cpu info registers 452 bl v7_arch_cp15_set_acr 453 pop {r1-r5} @ Restore the cpu info - fall through 454skip_errata_801819: 455#endif 456 457#ifdef CONFIG_ARM_ERRATA_454179 458 cmp r2, #0x21 @ Only on < r2p1 459 bge skip_errata_454179 460 461 mrc p15, 0, r0, c1, c0, 1 @ Read ACR 462 orr r0, r0, #(0x3 << 6) @ Set DBSM(BIT7) and IBE(BIT6) bits 463 push {r1-r5} @ Save the cpu info registers 464 bl v7_arch_cp15_set_acr 465 pop {r1-r5} @ Restore the cpu info - fall through 466 467skip_errata_454179: 468#endif 469 470#ifdef CONFIG_ARM_ERRATA_430973 471 cmp r2, #0x21 @ Only on < r2p1 472 bge skip_errata_430973 473 474 mrc p15, 0, r0, c1, c0, 1 @ Read ACR 475 orr r0, r0, #(0x1 << 6) @ Set IBE bit 476 push {r1-r5} @ Save the cpu info registers 477 bl v7_arch_cp15_set_acr 478 pop {r1-r5} @ Restore the cpu info - fall through 479 480skip_errata_430973: 481#endif 482 483#ifdef CONFIG_ARM_ERRATA_621766 484 cmp r2, #0x21 @ Only on < r2p1 485 bge skip_errata_621766 486 487 mrc p15, 0, r0, c1, c0, 1 @ Read ACR 488 orr r0, r0, #(0x1 << 5) @ Set L1NEON bit 489 push {r1-r5} @ Save the cpu info registers 490 bl v7_arch_cp15_set_acr 491 pop {r1-r5} @ Restore the cpu info - fall through 492 493skip_errata_621766: 494#endif 495 496 mov pc, r5 @ back to my caller 497ENDPROC(cpu_init_cp15) 498 499#if !defined(CONFIG_SKIP_LOWLEVEL_INIT) && \ 500 !defined(CONFIG_SKIP_LOWLEVEL_INIT_ONLY) 501/************************************************************************* 502 * 503 * CPU_init_critical registers 504 * 505 * setup important registers 506 * setup memory timing 507 * 508 *************************************************************************/ 509ENTRY(cpu_init_crit) 510 /* 511 * Jump to board specific initialization... 512 * The Mask ROM will have already initialized 513 * basic memory. Go here to bump up clock rate and handle 514 * wake up conditions. 515 */ 516 b lowlevel_init @ go setup pll,mux,memory 517ENDPROC(cpu_init_crit) 518#endif 519 520