1/* 2 * (C) Copyright 2013 3 * David Feng <fenghua@phytium.com.cn> 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8#include <asm-offsets.h> 9#include <config.h> 10#include <linux/linkage.h> 11#include <asm/armv8/mmu.h> 12 13/************************************************************************* 14 * 15 * Startup Code (reset vector) 16 * 17 *************************************************************************/ 18/* 19 * Branch according to exception level 20 */ 21.macro switch_el, xreg, el3_label, el2_label, el1_label 22 mrs \xreg, CurrentEL 23 cmp \xreg, 0xc 24 b.eq \el3_label 25 cmp \xreg, 0x8 26 b.eq \el2_label 27 cmp \xreg, 0x4 28 b.eq \el1_label 29.endm 30 31/* 32 * Enter Exception. 33 * This will save the processor state that is ELR/X0~X30 34 * to the stack frame. 35 */ 36.macro exception_entry 37 stp x29, x30, [sp, #-16]! 38 stp x27, x28, [sp, #-16]! 39 stp x25, x26, [sp, #-16]! 40 stp x23, x24, [sp, #-16]! 41 stp x21, x22, [sp, #-16]! 42 stp x19, x20, [sp, #-16]! 43 stp x17, x18, [sp, #-16]! 44 stp x15, x16, [sp, #-16]! 45 stp x13, x14, [sp, #-16]! 46 stp x11, x12, [sp, #-16]! 47 stp x9, x10, [sp, #-16]! 48 stp x7, x8, [sp, #-16]! 49 stp x5, x6, [sp, #-16]! 50 stp x3, x4, [sp, #-16]! 51 stp x1, x2, [sp, #-16]! 52 53 /* Could be running at EL3/EL2/EL1 */ 54 switch_el x11, 3f, 2f, 1f 553: mrs x1, esr_el3 56 mrs x2, elr_el3 57 b 0f 582: mrs x1, esr_el2 59 mrs x2, elr_el2 60 b 0f 611: mrs x1, esr_el1 62 mrs x2, elr_el1 630: 64 stp x2, x0, [sp, #-16]! 65 mov x0, sp 66.endm 67 68.globl _start 69_start: 70 b reset 71 72.balignl 64,0xdeadbeef 73__blank_zone_start: 74.fill 1024*10,1,0 75__blank_zone_end: 76 77.globl _blank_zone_start 78_blank_zone_start: 79.quad __blank_zone_start 80 81.globl _blank_zone_end 82_blank_zone_end: 83.quad __blank_zone_end 84.balignl 16,0xdeadbeef 85 86.align 3 87 88.globl _TEXT_BASE 89_TEXT_BASE: 90 .quad TEXT_BASE 91 92/* 93 * These are defined in the linker script. 94 */ 95.globl _end_ofs 96_end_ofs: 97 .quad _end - _start 98 99.globl _bss_start_ofs 100_bss_start_ofs: 101 .quad __bss_start - _start 102 103.globl _bss_end_ofs 104_bss_end_ofs: 105 .quad __bss_end - _start 106 107reset: 108 /* 109 * Could be EL3/EL2/EL1, Initial State: 110 * Little Endian, MMU Disabled, i/dCache Disabled 111 */ 112 adr x0, vectors 113 switch_el x1, 3f, 2f, 1f 1143: msr vbar_el3, x0 115 mrs x0, scr_el3 116 orr x0, x0, #0xf /* SCR_EL3.NS|IRQ|FIQ|EA */ 117 msr scr_el3, x0 118 msr cptr_el3, xzr /* Enable FP/SIMD */ 119#ifdef COUNTER_FREQUENCY 120 ldr x0, =COUNTER_FREQUENCY 121 msr cntfrq_el0, x0 /* Initialize CNTFRQ */ 122#endif 123 b 0f 1242: msr vbar_el2, x0 125 mov x0, #0x33ff 126 msr cptr_el2, x0 /* Enable FP/SIMD */ 127 b 0f 1281: msr vbar_el1, x0 129 mov x0, #3 << 20 130 msr cpacr_el1, x0 /* Enable FP/SIMD */ 1310: 132 133 /* 134 * Cache/BPB/TLB Invalidate 135 * i-cache is invalidated before enabled in icache_enable() 136 * tlb is invalidated before mmu is enabled in dcache_enable() 137 * d-cache is invalidated before enabled in dcache_enable() 138 */ 139 140#ifndef CONFIG_HISI_DISABLE_DOWNLOAD 141 /* 142 * read system register REG_SC_GEN2 143 * check if ziju flag 144 */ 145 ldr x0, =SYS_CTRL_REG_BASE 146 ldr w1, [x0, #REG_SC_GEN2] 147 ldr w2, =0x7a696a75 /* magic for "ziju" */ 148 cmp w1, w2 149 bne normal_start_flow 150 mov x1, sp /* save sp */ 151 str w1, [x0, #REG_SC_GEN2] /* clear ziju flag */ 152 153ziju_flow: 154 ldr x2, =(STACK_TRAINING) 155 bic sp, x2, #0xf /* 16-byte alignment for ABI compliance */ 156 ldr x0, _blank_zone_start 157 ldr x1, _TEXT_BASE 158 sub x0, x0, x1 159 adr x1, _start 160 add x0, x0, x1 161 mov x1, #0x0 /* flags: 0->normal 1->pm */ 162 bl init_registers /* init PLL/DDRC/... */ 163 bl start_ddr_training /* DDR training */ 164 165 ldr x0, =SYS_CTRL_REG_BASE 166 ldr w1, [x0, #REG_SC_GEN2] 167 mov sp, x1 /* restore sp */ 168 ldr w1, [x0, #REG_SC_GEN3] 169 mov x30, x1 170 ret /* return to bootrom */ 171 nop 172 nop 173 nop 174 nop 175 nop 176 nop 177 b . /* bug here */ 178 179 180normal_start_flow: 181#endif 182 /* set stack for C code */ 183 ldr x0, =(CONFIG_SYS_INIT_SP_ADDR) 184 bic sp, x0, #0xf /* 16-byte alignment for ABI compliance */ 185 186 bl uart_early_init 187 adr x0, Str_SystemSartup 188 bl uart_early_puts 189 190 /* enable I-Cache */ 191 bl icache_enable 192 193running_addr_check: 194 adr x0,running_addr_check 195 lsr x0, x0, #28 196 cmp x0, #4 197 bge not_ddr_init 198 199 /* read init table and config registers */ 200 ldr x0, _blank_zone_start 201 ldr x1, _TEXT_BASE 202 sub x0, x0, x1 203 adr x1, _start 204 add x0, x0, x1 205 mov x1, #0 /* flags: 0->normal 1->pm */ 206 bl init_registers 207 bl start_ddr_training 208check_boot_mode: 209 ldr x0, =SYS_CTRL_REG_BASE 210 ldr w0, [x0, #REG_SYSSTAT] 211 lsr w6, w0, #2 212 and w6, w6, #0x3 213 cmp w6, #BOOT_FROM_EMMC 214 bne not_ddr_init 215 216#ifdef CONFIG_SDHCI 217emmc_boot: 218 ldr x0, _TEXT_BASE 219 ldr x1, =__image_copy_start /* x1 <- SRC &__image_copy_start */ 220 ldr x2, =__bss_start /* x2 <- SRC &__bss_start */ 221 sub x1, x2, x1 222 bl emmc_boot_read 223 b jump_to_ddr 224#endif 225 226not_ddr_init: 227master_cpu: 228relocate: 229 adr x0, _start /*runing addr start*/ 230 ldr x1, =__image_copy_start /* x1 <- SRC &__image_copy_start */ 231 cmp x0, x1 232 b.eq no_copy /* skip relocation */ 233 ldr x2, =__bss_start /* x2 <- SRC &__bss_start*/ 234 235copy_loop: 236 ldp x10, x11, [x0], #16 /* copy from source address [x0] */ 237 stp x10, x11, [x1], #16 /* copy to target address [x1] */ 238 cmp x1, x2 /* until source end address [x2] */ 239 b.lo copy_loop 240no_copy: 241clear_remap: 242 ldr x1, =SYS_CTRL_REG_BASE 243 ldr w0, [x1] 244 orr w0, w0, #0x100 245 str w0, [x1] 246jump_to_ddr: 247 adr x0, _start_armboot 248 ldr x30,[x0] 249 ret 250.align 3 251_start_armboot: .quad start_armboot 252 253/*-----------------------------------------------------------------------*/ 254 255/* 256 * Exception vectors. 257 */ 258 .align 3 259 .globl vectors 260vectors: 261 .align 3 262 b _do_bad_sync /* Current EL Synchronous Thread */ 263 264 .align 3 265 b _do_bad_irq /* Current EL IRQ Thread */ 266 267 .align 3 268 b _do_bad_fiq /* Current EL FIQ Thread */ 269 270 .align 3 271 b _do_bad_error /* Current EL Error Thread */ 272 273 .align 3 274 b _do_sync /* Current EL Synchronous Handler */ 275 276 .align 3 277 b _do_irq /* Current EL IRQ Handler */ 278 279 .align 3 280 b _do_fiq /* Current EL FIQ Handler */ 281 282 .align 3 283 b _do_error /* Current EL Error Handler */ 284 285 286_do_bad_sync: 287 exception_entry 288 bl do_bad_sync 289 b exception_exit 290 291_do_bad_irq: 292 exception_entry 293 bl do_bad_irq 294 b exception_exit 295 296_do_bad_fiq: 297 exception_entry 298 bl do_bad_fiq 299 b exception_exit 300 301_do_bad_error: 302 exception_entry 303 bl do_bad_error 304 b exception_exit 305 306_do_sync: 307 exception_entry 308 bl do_sync 309 b exception_exit 310 311_do_irq: 312 exception_entry 313 bl do_irq 314 b exception_exit 315 316_do_fiq: 317 exception_entry 318 bl do_fiq 319 b exception_exit 320 321_do_error: 322 exception_entry 323 bl do_error 324 b exception_exit 325 326exception_exit: 327 ldp x2, x0, [sp],#16 328 switch_el x11, 3f, 2f, 1f 3293: msr elr_el3, x2 330 b 0f 3312: msr elr_el2, x2 332 b 0f 3331: msr elr_el1, x2 3340: 335 ldp x1, x2, [sp],#16 336 ldp x3, x4, [sp],#16 337 ldp x5, x6, [sp],#16 338 ldp x7, x8, [sp],#16 339 ldp x9, x10, [sp],#16 340 ldp x11, x12, [sp],#16 341 ldp x13, x14, [sp],#16 342 ldp x15, x16, [sp],#16 343 ldp x17, x18, [sp],#16 344 ldp x19, x20, [sp],#16 345 ldp x21, x22, [sp],#16 346 ldp x23, x24, [sp],#16 347 ldp x25, x26, [sp],#16 348 ldp x27, x28, [sp],#16 349 ldp x29, x30, [sp],#16 350 eret 351 352/* 353 * void __asm_invalidate_icache_all(void) 354 * 355 * invalidate all tlb entries. 356 */ 357ENTRY(__asm_invalidate_icache_all) 358 ic ialluis 359 isb sy 360 ret 361ENDPROC(__asm_invalidate_icache_all) 362 363.align 3 364Str_SystemSartup: 365.ascii "\r\n\r\nSystem startup\r\n\0" 366