1 /* SPDX-License-Identifier: GPL-2.0+ */
3 * armboot - Startup Code for OMAP3530/ARM Cortex CPU-core
5 * Copyright (c) 2004 Texas Instruments <r-woodruff2@ti.com>
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>
15 #include <asm-offsets.h>
17 #include <asm/system.h>
18 #include <linux/linkage.h>
19 #include <asm/armv7.h>
20 #include <system-constants.h>
22 /*************************************************************************
24 * Startup Code (reset vector)
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.
30 *************************************************************************/
33 .globl save_boot_params_ret
34 .type save_boot_params_ret,%function
35 #ifdef CONFIG_ARMV7_LPAE
36 .global switch_to_hypervisor_ret
40 /* Allow the board to save important registers */
43 #ifdef CONFIG_POSITION_INDEPENDENT
45 * Fix .rela.dyn relocations. This allows U-Boot to loaded to and
46 * executed at a different address than it was linked at.
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 */
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 */
61 ldr r0, [r2] /* r0 <- Link location */
62 ldr r1, [r2, #4] /* r1 <- fixup */
63 cmp r1, #23 /* relative fixup? */
66 /* relative fix: increase location by offset */
79 #ifdef CONFIG_ARMV7_LPAE
81 * check for Hypervisor support
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
87 switch_to_hypervisor_ret:
90 * disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode,
91 * except if in HYP mode already
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
101 #if !CONFIG_IS_ENABLED(SYS_NO_VECTOR_TABLE)
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
110 #ifdef CONFIG_HAS_VBAR
111 /* Set vector address in CP15 VBAR register */
113 mcr p15, 0, r0, c12, c0, 0 @Set VBAR
117 /* the mask ROM code should have PLL and others stable */
118 #if !CONFIG_IS_ENABLED(SKIP_LOWLEVEL_INIT)
119 #ifdef CONFIG_CPU_V7A
122 #if !CONFIG_IS_ENABLED(SKIP_LOWLEVEL_INIT_ONLY)
129 /*------------------------------------------------------------------------------*/
131 ENTRY(c_runtime_cpu_setup)
133 * If I-cache is enabled invalidate it
135 #if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF)
136 mcr p15, 0, r0, c7, c5, 0 @ invalidate icache
143 ENDPROC(c_runtime_cpu_setup)
145 /*************************************************************************
147 * void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3)
148 * __attribute__((weak));
150 * Stack pointer is not yet initialized at this moment
151 * Don't save anything to stack even if compiled with -O0
153 *************************************************************************/
154 WEAK(save_boot_params)
155 b save_boot_params_ret @ back to my caller
156 ENDPROC(save_boot_params)
158 #ifdef CONFIG_ARMV7_LPAE
159 WEAK(switch_to_hypervisor)
160 b switch_to_hypervisor_ret
161 ENDPROC(switch_to_hypervisor)
164 /*************************************************************************
168 * Setup CP15 registers (cache, MMU, TLBs). The I-cache is turned on unless
169 * CONFIG_SYS_ICACHE_OFF is defined.
171 *************************************************************************/
174 #if CONFIG_IS_ENABLED(ARMV7_SET_CORTEX_SMPEN)
176 * The Arm Cortex-A7 TRM says this bit must be enabled before
177 * "any cache or TLB maintenance operations are performed".
179 mrc p15, 0, r0, c1, c0, 1 @ read auxilary control register
180 orr r0, r0, #1 << 6 @ set SMP bit to enable coherency
181 mcr p15, 0, r0, c1, c0, 1 @ write auxilary control register
187 mov r0, #0 @ set up for MCR
188 mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs
189 mcr p15, 0, r0, c7, c5, 0 @ invalidate icache
190 mcr p15, 0, r0, c7, c5, 6 @ invalidate BP array
195 * disable MMU stuff and caches
197 mrc p15, 0, r0, c1, c0, 0
198 bic r0, r0, #0x00002000 @ clear bits 13 (--V-)
199 bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM)
200 orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align
201 orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB
202 #if CONFIG_IS_ENABLED(SYS_ICACHE_OFF)
203 bic r0, r0, #0x00001000 @ clear bit 12 (I) I-cache
205 orr r0, r0, #0x00001000 @ set bit 12 (I) I-cache
207 mcr p15, 0, r0, c1, c0, 0
209 #ifdef CONFIG_ARM_ERRATA_716044
210 mrc p15, 0, r0, c1, c0, 0 @ read system control register
211 orr r0, r0, #1 << 11 @ set bit #11
212 mcr p15, 0, r0, c1, c0, 0 @ write system control register
215 #if (defined(CONFIG_ARM_ERRATA_742230) || defined(CONFIG_ARM_ERRATA_794072))
216 mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
217 orr r0, r0, #1 << 4 @ set bit #4
218 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
221 #ifdef CONFIG_ARM_ERRATA_743622
222 mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
223 orr r0, r0, #1 << 6 @ set bit #6
224 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
227 #ifdef CONFIG_ARM_ERRATA_751472
228 mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
229 orr r0, r0, #1 << 11 @ set bit #11
230 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
232 #ifdef CONFIG_ARM_ERRATA_761320
233 mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
234 orr r0, r0, #1 << 21 @ set bit #21
235 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
238 #ifdef CONFIG_ARM_ERRATA_845369
239 mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
240 orr r0, r0, #1 << 22 @ set bit #22
241 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
244 mov r5, lr @ Store my Caller
245 mrc p15, 0, r1, c0, c0, 0 @ r1 has Read Main ID Register (MIDR)
246 mov r3, r1, lsr #20 @ get variant field
247 and r3, r3, #0xf @ r3 has CPU variant
248 and r4, r1, #0xf @ r4 has CPU revision
249 mov r2, r3, lsl #4 @ shift variant field for combined value
250 orr r2, r4, r2 @ r2 has combined CPU variant + revision
252 /* Early stack for ERRATA that needs into call C code */
253 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)
254 ldr r0, =(CONFIG_SPL_STACK)
256 ldr r0, =(SYS_INIT_SP_ADDR)
258 bic r0, r0, #7 /* 8-byte alignment for ABI compliance */
261 #ifdef CONFIG_ARM_ERRATA_798870
262 cmp r2, #0x30 @ Applies to lower than R3p0
263 bge skip_errata_798870 @ skip if not affected rev
264 cmp r2, #0x20 @ Applies to including and above R2p0
265 blt skip_errata_798870 @ skip if not affected rev
267 mrc p15, 1, r0, c15, c0, 0 @ read l2 aux ctrl reg
268 orr r0, r0, #1 << 7 @ Enable hazard-detect timeout
269 push {r1-r5} @ Save the cpu info registers
270 bl v7_arch_cp15_set_l2aux_ctrl
271 isb @ Recommended ISB after l2actlr update
272 pop {r1-r5} @ Restore the cpu info - fall through
276 #ifdef CONFIG_ARM_ERRATA_801819
277 cmp r2, #0x24 @ Applies to lt including R2p4
278 bgt skip_errata_801819 @ skip if not affected rev
279 cmp r2, #0x20 @ Applies to including and above R2p0
280 blt skip_errata_801819 @ skip if not affected rev
281 mrc p15, 0, r0, c0, c0, 6 @ pick up REVIDR reg
282 and r0, r0, #1 << 3 @ check REVIDR[3]
284 beq skip_errata_801819 @ skip erratum if REVIDR[3] is set
286 mrc p15, 0, r0, c1, c0, 1 @ read auxilary control register
287 orr r0, r0, #3 << 27 @ Disables streaming. All write-allocate
288 @ lines allocate in the L1 or L2 cache.
289 orr r0, r0, #3 << 25 @ Disables streaming. All write-allocate
290 @ lines allocate in the L1 cache.
291 push {r1-r5} @ Save the cpu info registers
292 bl v7_arch_cp15_set_acr
293 pop {r1-r5} @ Restore the cpu info - fall through
297 #ifdef CONFIG_ARM_CORTEX_A15_CVE_2017_5715
298 mrc p15, 0, r0, c1, c0, 1 @ read auxilary control register
299 orr r0, r0, #1 << 0 @ Enable invalidates of BTB
300 push {r1-r5} @ Save the cpu info registers
301 bl v7_arch_cp15_set_acr
302 pop {r1-r5} @ Restore the cpu info - fall through
305 #ifdef CONFIG_ARM_ERRATA_454179
306 mrc p15, 0, r0, c1, c0, 1 @ Read ACR
308 cmp r2, #0x21 @ Only on < r2p1
309 orrlt r0, r0, #(0x3 << 6) @ Set DBSM(BIT7) and IBE(BIT6) bits
311 push {r1-r5} @ Save the cpu info registers
312 bl v7_arch_cp15_set_acr
313 pop {r1-r5} @ Restore the cpu info - fall through
316 #if defined(CONFIG_ARM_ERRATA_430973) || defined (CONFIG_ARM_CORTEX_A8_CVE_2017_5715)
317 mrc p15, 0, r0, c1, c0, 1 @ Read ACR
319 #ifdef CONFIG_ARM_CORTEX_A8_CVE_2017_5715
320 orr r0, r0, #(0x1 << 6) @ Set IBE bit always to enable OS WA
322 cmp r2, #0x21 @ Only on < r2p1
323 orrlt r0, r0, #(0x1 << 6) @ Set IBE bit
325 push {r1-r5} @ Save the cpu info registers
326 bl v7_arch_cp15_set_acr
327 pop {r1-r5} @ Restore the cpu info - fall through
330 #ifdef CONFIG_ARM_ERRATA_621766
331 mrc p15, 0, r0, c1, c0, 1 @ Read ACR
333 cmp r2, #0x21 @ Only on < r2p1
334 orrlt r0, r0, #(0x1 << 5) @ Set L1NEON bit
336 push {r1-r5} @ Save the cpu info registers
337 bl v7_arch_cp15_set_acr
338 pop {r1-r5} @ Restore the cpu info - fall through
341 #ifdef CONFIG_ARM_ERRATA_725233
342 mrc p15, 1, r0, c9, c0, 2 @ Read L2ACR
344 cmp r2, #0x21 @ Only on < r2p1 (Cortex A8)
345 orrlt r0, r0, #(0x1 << 27) @ L2 PLD data forwarding disable
347 push {r1-r5} @ Save the cpu info registers
348 bl v7_arch_cp15_set_l2aux_ctrl
349 pop {r1-r5} @ Restore the cpu info - fall through
352 #ifdef CONFIG_ARM_ERRATA_852421
353 mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
354 orr r0, r0, #1 << 24 @ set bit #24
355 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
358 #ifdef CONFIG_ARM_ERRATA_852423
359 mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
360 orr r0, r0, #1 << 12 @ set bit #12
361 mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
364 mov pc, r5 @ back to my caller
365 ENDPROC(cpu_init_cp15)
367 #if !CONFIG_IS_ENABLED(SKIP_LOWLEVEL_INIT) && \
368 !CONFIG_IS_ENABLED(SKIP_LOWLEVEL_INIT_ONLY)
369 /*************************************************************************
371 * CPU_init_critical registers
373 * setup important registers
374 * setup memory timing
376 *************************************************************************/
379 * Jump to board specific initialization...
380 * The Mask ROM will have already initialized
381 * basic memory. Go here to bump up clock rate and handle
382 * wake up conditions.
384 b lowlevel_init @ go setup pll,mux,memory
385 ENDPROC(cpu_init_crit)
388 #if CONFIG_POSITION_INDEPENDENT
390 .word __rel_dyn_start - pie_fixup
392 .word __rel_dyn_end - pie_fixup