• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * This file is based off of the OMAP3530/ARM Cortex start.S file from Das
4 * U-Boot, which itself got the file from armboot.
5 */
6
7/* Early initialization code for ARMv7 architecture. */
8
9#include <arch/asm.h>
10
11.arm
12	/*
13	 * Just in case the maskrom or the vendor basic firmware passes on a
14	 * parameter when calling the bootblock, store it here for handling by C
15	 * code.
16	 */
17	.section .bss, "aw" @nobits
18	.global maskrom_param
19maskrom_param:
20	.word 0
21
22ENTRY(_start)
23	/*
24	 * Set the CPU to System mode with IRQ and FIQ disabled. Prefetch/Data
25	 * aborts may happen early and crash before the abort handlers are
26	 * installed, but at least the problem will show up near the code that
27	 * causes it.
28	 */
29	msr	cpsr_cxf, #0xdf
30	bl	_thumb_start
31ENDPROC(_start)
32
33.thumb
34ENTRY(_thumb_start)
35
36	/* Preserve the maskrom passed value, if any */
37	mov	r10, r0
38
39	bl	arm_init_caches
40
41	/*
42	 * From Cortex-A Series Programmer's Guide:
43	 * Only CPU 0 performs initialization. Other CPUs go into WFI
44	 * to do this, first work out which CPU this is
45	 * this code typically is run before any other initialization step
46	 */
47	mrc p15, 0, r1, c0, c0, 5	@ Read Multiprocessor Affinity Register
48	and r1, r1, #0x3 @ Extract CPU ID bits
49	cmp r1, #0
50	bne wait_for_interrupt		@ If this is not core0, wait
51
52	/*
53	 * Initialize the stack to a known value. This is used to check for
54	 * stack overflow later in the boot process.
55	 */
56	ldr	r0, =_stack
57	ldr	r1, =_estack
58	ldr	r2, =0xdeadbeef
59init_stack_loop:
60	str	r2, [r0]
61	add	r0, #4
62	cmp	r0, r1
63	bne	init_stack_loop
64
65	/* Set stackpointer in internal RAM */
66	ldr	sp, =_estack
67
68	/*
69	 * For platforms where the flash is memory mapped (qemu), check if the
70	 * bootblock needs to relocate itself.
71	 */
72check_position:
73	adr	r0, check_position
74	ldr	r1, =check_position
75
76	cmp	r0, r1
77	beq	call_bootblock
78
79	/* Calculate source */
80	ldr	r2, =_program
81	sub	r1, r1, r2
82	sub	r1, r0, r1
83	/* Get destination */
84	ldr	r0, =_program
85	/* Get size */
86	ldr	r2, =_eprogram
87	sub	r2, r2, r0
88
89	bl	memcpy
90
91	/* Get absolute address */
92	ldr	lr, =call_bootblock
93	/* Directly modify pc as branch instruction changes the state */
94	mov	pc, lr
95
96call_bootblock:
97
98	/* Restore parameter passed in by maskrom/vendor firmware. */
99	ldr	r0, =maskrom_param
100	str	r10, [r0]
101
102	ldr	r0,=0x00000000
103	/*
104	 * The current design of cpu_info places the struct at the top of the
105	 * stack. Free enough space to accommodate for that, but make sure it's
106	 * 8-byte aligned for ABI compliance.
107	 */
108	sub	sp, sp, #16
109	bl	main
110
111wait_for_interrupt:
112	wfi
113	mov	pc, lr			@ back to my caller
114ENDPROC(_thumb_start)
115