start.S 9.4 KB
Newer Older
1 2 3 4 5 6 7
/*
 * armboot - Startup Code for OMAP3530/ARM Cortex CPU-core
 *
 * Copyright (c) 2004	Texas Instruments <r-woodruff2@ti.com>
 *
 * Copyright (c) 2001	Marius Gröger <mag@sysgo.de>
 * Copyright (c) 2002	Alex Züpke <azu@sysgo.de>
8
 * Copyright (c) 2002	Gary Jennejohn <garyj@denx.de>
9 10 11 12
 * Copyright (c) 2003	Richard Woodruff <r-woodruff2@ti.com>
 * Copyright (c) 2003	Kshitij <kshitij@ti.com>
 * Copyright (c) 2006-2008 Syed Mohammed Khasim <x0khasim@ti.com>
 *
13
 * SPDX-License-Identifier:	GPL-2.0+
14 15
 */

16
#include <asm-offsets.h>
17
#include <config.h>
A
Aneesh V 已提交
18
#include <asm/system.h>
19
#include <linux/linkage.h>
20
#include <asm/armv7.h>
21 22 23 24 25

/*************************************************************************
 *
 * Startup Code (reset vector)
 *
P
Pavel Machek 已提交
26 27 28
 * Do important init only if we don't start from memory!
 * Setup memory and board specific bits prior to relocation.
 * 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 36 37
#ifdef CONFIG_ARMV7_LPAE
	.global	switch_to_hypervisor_ret
#endif
38 39

reset:
40 41 42
	/* Allow the board to save important registers */
	b	save_boot_params
save_boot_params_ret:
43 44 45 46 47 48 49 50 51 52
#ifdef CONFIG_ARMV7_LPAE
/*
 * check for Hypervisor support
 */
	mrc	p15, 0, r0, c0, c1, 1		@ read ID_PFR1
	and	r0, r0, #CPUID_ARM_VIRT_MASK	@ mask virtualization bits
	cmp	r0, #(1 << CPUID_ARM_VIRT_SHIFT)
	beq	switch_to_hypervisor
switch_to_hypervisor_ret:
#endif
53
	/*
54 55
	 * disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode,
	 * except if in HYP mode already
56 57
	 */
	mrs	r0, cpsr
58 59 60 61 62
	and	r1, r0, #0x1f		@ mask mode bits
	teq	r1, #0x1a		@ test for HYP mode
	bicne	r0, r0, #0x1f		@ clear all mode bits
	orrne	r0, r0, #0x13		@ set SVC mode
	orr	r0, r0, #0xc0		@ disable FIQ and IRQ
63 64
	msr	cpsr,r0

A
Aneesh V 已提交
65 66 67 68 69
/*
 * Setup vector:
 * (OMAP4 spl TEXT_BASE is not 32 byte aligned.
 * Continue to use ROM code vector only in OMAP4 spl)
 */
70
#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD))
P
Peng Fan 已提交
71 72
	/* Set V=0 in CP15 SCTLR register - for VBAR to point to vector */
	mrc	p15, 0, r0, c1, c0, 0	@ Read CP15 SCTLR Register
A
Aneesh V 已提交
73
	bic	r0, #CR_V		@ V = 0
P
Peng Fan 已提交
74
	mcr	p15, 0, r0, c1, c0, 0	@ Write CP15 SCTLR Register
A
Aneesh V 已提交
75 76 77 78 79 80

	/* Set vector address in CP15 VBAR register */
	ldr	r0, =_start
	mcr	p15, 0, r0, c12, c0, 0	@Set VBAR
#endif

81 82
	/* the mask ROM code should have PLL and others stable */
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
83
	bl	cpu_init_cp15
84
#ifndef CONFIG_SKIP_LOWLEVEL_INIT_ONLY
85
	bl	cpu_init_crit
86
#endif
87 88
#endif

89
	bl	_main
90 91 92

/*------------------------------------------------------------------------------*/

93
ENTRY(c_runtime_cpu_setup)
94 95 96 97 98 99 100 101
/*
 * If I-cache is enabled invalidate it
 */
#ifndef CONFIG_SYS_ICACHE_OFF
	mcr	p15, 0, r0, c7, c5, 0	@ invalidate icache
	mcr     p15, 0, r0, c7, c10, 4	@ DSB
	mcr     p15, 0, r0, c7, c5, 4	@ ISB
#endif
102

103 104 105
	bx	lr

ENDPROC(c_runtime_cpu_setup)
106

107 108 109 110 111 112 113 114 115 116
/*************************************************************************
 *
 * void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3)
 *	__attribute__((weak));
 *
 * Stack pointer is not yet initialized at this moment
 * Don't save anything to stack even if compiled with -O0
 *
 *************************************************************************/
ENTRY(save_boot_params)
117
	b	save_boot_params_ret		@ back to my caller
118 119 120
ENDPROC(save_boot_params)
	.weak	save_boot_params

121 122 123 124 125 126 127
#ifdef CONFIG_ARMV7_LPAE
ENTRY(switch_to_hypervisor)
	b	switch_to_hypervisor_ret
ENDPROC(switch_to_hypervisor)
	.weak	switch_to_hypervisor
#endif

128 129
/*************************************************************************
 *
130
 * cpu_init_cp15
131
 *
132 133
 * Setup CP15 registers (cache, MMU, TLBs). The I-cache is turned on unless
 * CONFIG_SYS_ICACHE_OFF is defined.
134 135
 *
 *************************************************************************/
136
ENTRY(cpu_init_cp15)
137 138 139 140 141 142
	/*
	 * Invalidate L1 I/D
	 */
	mov	r0, #0			@ set up for MCR
	mcr	p15, 0, r0, c8, c7, 0	@ invalidate TLBs
	mcr	p15, 0, r0, c7, c5, 0	@ invalidate icache
143 144 145
	mcr	p15, 0, r0, c7, c5, 6	@ invalidate BP array
	mcr     p15, 0, r0, c7, c10, 4	@ DSB
	mcr     p15, 0, r0, c7, c5, 4	@ ISB
146 147 148 149 150 151 152 153

	/*
	 * disable MMU stuff and caches
	 */
	mrc	p15, 0, r0, c1, c0, 0
	bic	r0, r0, #0x00002000	@ clear bits 13 (--V-)
	bic	r0, r0, #0x00000007	@ clear bits 2:0 (-CAM)
	orr	r0, r0, #0x00000002	@ set bit 1 (--A-) Align
154 155 156 157 158 159
	orr	r0, r0, #0x00000800	@ set bit 11 (Z---) BTB
#ifdef CONFIG_SYS_ICACHE_OFF
	bic	r0, r0, #0x00001000	@ clear bit 12 (I) I-cache
#else
	orr	r0, r0, #0x00001000	@ set bit 12 (I) I-cache
#endif
160
	mcr	p15, 0, r0, c1, c0, 0
161

162 163 164 165 166 167
#ifdef CONFIG_ARM_ERRATA_716044
	mrc	p15, 0, r0, c1, c0, 0	@ read system control register
	orr	r0, r0, #1 << 11	@ set bit #11
	mcr	p15, 0, r0, c1, c0, 0	@ write system control register
#endif

168
#if (defined(CONFIG_ARM_ERRATA_742230) || defined(CONFIG_ARM_ERRATA_794072))
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
	mrc	p15, 0, r0, c15, c0, 1	@ read diagnostic register
	orr	r0, r0, #1 << 4		@ set bit #4
	mcr	p15, 0, r0, c15, c0, 1	@ write diagnostic register
#endif

#ifdef CONFIG_ARM_ERRATA_743622
	mrc	p15, 0, r0, c15, c0, 1	@ read diagnostic register
	orr	r0, r0, #1 << 6		@ set bit #6
	mcr	p15, 0, r0, c15, c0, 1	@ write diagnostic register
#endif

#ifdef CONFIG_ARM_ERRATA_751472
	mrc	p15, 0, r0, c15, c0, 1	@ read diagnostic register
	orr	r0, r0, #1 << 11	@ set bit #11
	mcr	p15, 0, r0, c15, c0, 1	@ write diagnostic register
#endif
185 186 187 188 189
#ifdef CONFIG_ARM_ERRATA_761320
	mrc	p15, 0, r0, c15, c0, 1	@ read diagnostic register
	orr	r0, r0, #1 << 21	@ set bit #21
	mcr	p15, 0, r0, c15, c0, 1	@ write diagnostic register
#endif
190

191 192 193 194 195 196
#ifdef CONFIG_ARM_ERRATA_845369
	mrc     p15, 0, r0, c15, c0, 1	@ read diagnostic register
	orr     r0, r0, #1 << 22	@ set bit #22
	mcr     p15, 0, r0, c15, c0, 1	@ write diagnostic register
#endif

197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217
	mov	r5, lr			@ Store my Caller
	mrc	p15, 0, r1, c0, c0, 0	@ r1 has Read Main ID Register (MIDR)
	mov	r3, r1, lsr #20		@ get variant field
	and	r3, r3, #0xf		@ r3 has CPU variant
	and	r4, r1, #0xf		@ r4 has CPU revision
	mov	r2, r3, lsl #4		@ shift variant field for combined value
	orr	r2, r4, r2		@ r2 has combined CPU variant + revision

#ifdef CONFIG_ARM_ERRATA_798870
	cmp	r2, #0x30		@ Applies to lower than R3p0
	bge	skip_errata_798870      @ skip if not affected rev
	cmp	r2, #0x20		@ Applies to including and above R2p0
	blt	skip_errata_798870      @ skip if not affected rev

	mrc	p15, 1, r0, c15, c0, 0  @ read l2 aux ctrl reg
	orr	r0, r0, #1 << 7         @ Enable hazard-detect timeout
	push	{r1-r5}			@ Save the cpu info registers
	bl	v7_arch_cp15_set_l2aux_ctrl
	isb				@ Recommended ISB after l2actlr update
	pop	{r1-r5}			@ Restore the cpu info - fall through
skip_errata_798870:
218 219
#endif

220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
#ifdef CONFIG_ARM_ERRATA_801819
	cmp	r2, #0x24		@ Applies to lt including R2p4
	bgt	skip_errata_801819      @ skip if not affected rev
	cmp	r2, #0x20		@ Applies to including and above R2p0
	blt	skip_errata_801819      @ skip if not affected rev
	mrc	p15, 0, r0, c0, c0, 6	@ pick up REVIDR reg
	and	r0, r0, #1 << 3		@ check REVIDR[3]
	cmp	r0, #1 << 3
	beq	skip_errata_801819	@ skip erratum if REVIDR[3] is set

	mrc	p15, 0, r0, c1, c0, 1	@ read auxilary control register
	orr	r0, r0, #3 << 27	@ Disables streaming. All write-allocate
					@ lines allocate in the L1 or L2 cache.
	orr	r0, r0, #3 << 25	@ Disables streaming. All write-allocate
					@ lines allocate in the L1 cache.
	push	{r1-r5}			@ Save the cpu info registers
	bl	v7_arch_cp15_set_acr
	pop	{r1-r5}			@ Restore the cpu info - fall through
skip_errata_801819:
#endif

241
#ifdef CONFIG_ARM_ERRATA_454179
242 243
	mrc	p15, 0, r0, c1, c0, 1	@ Read ACR

244
	cmp	r2, #0x21		@ Only on < r2p1
245
	orrlt	r0, r0, #(0x3 << 6)	@ Set DBSM(BIT7) and IBE(BIT6) bits
246 247 248 249

	push	{r1-r5}			@ Save the cpu info registers
	bl	v7_arch_cp15_set_acr
	pop	{r1-r5}			@ Restore the cpu info - fall through
250 251 252
#endif

#ifdef CONFIG_ARM_ERRATA_430973
253 254
	mrc	p15, 0, r0, c1, c0, 1	@ Read ACR

255
	cmp	r2, #0x21		@ Only on < r2p1
256
	orrlt	r0, r0, #(0x1 << 6)	@ Set IBE bit
257 258 259 260

	push	{r1-r5}			@ Save the cpu info registers
	bl	v7_arch_cp15_set_acr
	pop	{r1-r5}			@ Restore the cpu info - fall through
261 262 263
#endif

#ifdef CONFIG_ARM_ERRATA_621766
264 265
	mrc	p15, 0, r0, c1, c0, 1	@ Read ACR

266
	cmp	r2, #0x21		@ Only on < r2p1
267
	orrlt	r0, r0, #(0x1 << 5)	@ Set L1NEON bit
268 269 270 271

	push	{r1-r5}			@ Save the cpu info registers
	bl	v7_arch_cp15_set_acr
	pop	{r1-r5}			@ Restore the cpu info - fall through
272 273 274
#endif

#ifdef CONFIG_ARM_ERRATA_725233
275 276
	mrc	p15, 1, r0, c9, c0, 2	@ Read L2ACR

277
	cmp	r2, #0x21		@ Only on < r2p1 (Cortex A8)
278
	orrlt	r0, r0, #(0x1 << 27)	@ L2 PLD data forwarding disable
279 280 281 282

	push	{r1-r5}			@ Save the cpu info registers
	bl	v7_arch_cp15_set_l2aux_ctrl
	pop	{r1-r5}			@ Restore the cpu info - fall through
283 284
#endif

285 286 287 288 289 290 291 292 293 294 295 296
#ifdef CONFIG_ARM_ERRATA_852421
	mrc	p15, 0, r0, c15, c0, 1	@ read diagnostic register
	orr	r0, r0, #1 << 24	@ set bit #24
	mcr	p15, 0, r0, c15, c0, 1	@ write diagnostic register
#endif

#ifdef CONFIG_ARM_ERRATA_852423
	mrc	p15, 0, r0, c15, c0, 1	@ read diagnostic register
	orr	r0, r0, #1 << 12	@ set bit #12
	mcr	p15, 0, r0, c15, c0, 1	@ write diagnostic register
#endif

297
	mov	pc, r5			@ back to my caller
298
ENDPROC(cpu_init_cp15)
299

300 301
#if !defined(CONFIG_SKIP_LOWLEVEL_INIT) && \
	!defined(CONFIG_SKIP_LOWLEVEL_INIT_ONLY)
302 303 304 305 306 307 308 309
/*************************************************************************
 *
 * CPU_init_critical registers
 *
 * setup important registers
 * setup memory timing
 *
 *************************************************************************/
310
ENTRY(cpu_init_crit)
311 312 313 314 315 316
	/*
	 * Jump to board specific initialization...
	 * The Mask ROM will have already initialized
	 * basic memory. Go here to bump up clock rate and handle
	 * wake up conditions.
	 */
317
	b	lowlevel_init		@ go setup pll,mux,memory
318
ENDPROC(cpu_init_crit)
319
#endif