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 <version.h> 11#include <linux/linkage.h> 12#include <asm/macro.h> 13#include <asm/armv8/mmu.h> 14 15/************************************************************************* 16 * 17 * Startup Code (reset vector) 18 * 19 *************************************************************************/ 20 21.globl _start 22_start: 23 b reset 24 25 .align 3 26 27.globl _TEXT_BASE 28_TEXT_BASE: 29 .quad CONFIG_SYS_TEXT_BASE 30 31/* 32 * These are defined in the linker script. 33 */ 34.globl _end_ofs 35_end_ofs: 36 .quad _end - _start 37 38.globl _bss_start_ofs 39_bss_start_ofs: 40 .quad __bss_start - _start 41 42.globl _bss_end_ofs 43_bss_end_ofs: 44 .quad __bss_end - _start 45 46reset: 47 /* 48 * Could be EL3/EL2/EL1, Initial State: 49 * Little Endian, MMU Disabled, i/dCache Disabled 50 */ 51 adr x0, vectors 52 switch_el x1, 3f, 2f, 1f 533: msr vbar_el3, x0 54 msr cptr_el3, xzr /* Enable FP/SIMD */ 55 ldr x0, =COUNTER_FREQUENCY 56 msr cntfrq_el0, x0 /* Initialize CNTFRQ */ 57 b 0f 582: msr vbar_el2, x0 59 mov x0, #0x33ff 60 msr cptr_el2, x0 /* Enable FP/SIMD */ 61 b 0f 621: msr vbar_el1, x0 63 mov x0, #3 << 20 64 msr cpacr_el1, x0 /* Enable FP/SIMD */ 650: 66 67 /* Cache/BPB/TLB Invalidate */ 68 bl __asm_flush_dcache_all /* dCache clean&invalidate */ 69 bl __asm_invalidate_icache_all /* iCache invalidate */ 70 bl __asm_invalidate_tlb_all /* invalidate TLBs */ 71 72 /* Processor specific initialization */ 73 bl lowlevel_init 74 75 branch_if_master x0, x1, master_cpu 76 77 /* 78 * Slave CPUs 79 */ 80slave_cpu: 81 wfe 82 ldr x1, =CPU_RELEASE_ADDR 83 ldr x0, [x1] 84 cbz x0, slave_cpu 85 br x0 /* branch to the given address */ 86 87 /* 88 * Master CPU 89 */ 90master_cpu: 91 bl _main 92 93/*-----------------------------------------------------------------------*/ 94 95WEAK(lowlevel_init) 96 /* Initialize GIC Secure Bank Status */ 97 mov x29, lr /* Save LR */ 98 bl gic_init 99 100 branch_if_master x0, x1, 1f 101 102 /* 103 * Slave should wait for master clearing spin table. 104 * This sync prevent salves observing incorrect 105 * value of spin table and jumping to wrong place. 106 */ 107 bl wait_for_wakeup 108 109 /* 110 * All processors will enter EL2 and optionally EL1. 111 */ 112 bl armv8_switch_to_el2 113#ifdef CONFIG_ARMV8_SWITCH_TO_EL1 114 bl armv8_switch_to_el1 115#endif 116 1171: 118 mov lr, x29 /* Restore LR */ 119 ret 120ENDPROC(lowlevel_init) 121 122/*-----------------------------------------------------------------------*/ 123 124ENTRY(c_runtime_cpu_setup) 125 /* If I-cache is enabled invalidate it */ 126#ifndef CONFIG_SYS_ICACHE_OFF 127 ic iallu /* I+BTB cache invalidate */ 128 isb sy 129#endif 130 131#ifndef CONFIG_SYS_DCACHE_OFF 132 /* 133 * Setup MAIR and TCR. 134 */ 135 ldr x0, =MEMORY_ATTRIBUTES 136 ldr x1, =TCR_FLAGS 137 138 switch_el x2, 3f, 2f, 1f 1393: orr x1, x1, TCR_EL3_IPS_BITS 140 msr mair_el3, x0 141 msr tcr_el3, x1 142 b 0f 1432: orr x1, x1, TCR_EL2_IPS_BITS 144 msr mair_el2, x0 145 msr tcr_el2, x1 146 b 0f 1471: orr x1, x1, TCR_EL1_IPS_BITS 148 msr mair_el1, x0 149 msr tcr_el1, x1 1500: 151#endif 152 153 /* Relocate vBAR */ 154 adr x0, vectors 155 switch_el x1, 3f, 2f, 1f 1563: msr vbar_el3, x0 157 b 0f 1582: msr vbar_el2, x0 159 b 0f 1601: msr vbar_el1, x0 1610: 162 163 ret 164ENDPROC(c_runtime_cpu_setup) 165