1/*
2 * Top-level entry points to the Boot ROM. This includes:
3 * - Reset, exception and interrupt vectors.
4 * - C run-time initialization.
5 * - Secondary CPU boot code.
6 *
7 * Copyright 2020 Google LLC
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 * http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 */
21
22#define	KiB (1024)
23
24#define SRAM_SIZE (128 * KiB)
25
26	.section .text.vectors, "ax"
27
28	.global _start
29	.type _start, %function
30_start:
31	ldr pc, reset_addr
32	. = 0x04
33	b	undefined_instruction
34	. = 0x08
35	b	software_interrupt
36	. = 0x0c
37	b	prefetch_abort
38	. = 0x10
39	b	data_abort
40	. = 0x18
41	b	interrupt
42	. = 0x1c
43	b	fast_interrupt
44
45	.align 2
46reset_addr:
47	.word reset
48
49undefined_instruction:
50	mov	r0, #1
51	ldr	pc, handle_exception_addr
52
53software_interrupt:
54	mov	r0, #2
55	ldr	pc, handle_exception_addr
56
57prefetch_abort:
58	mov	r0, #3
59	ldr	pc, handle_exception_addr
60
61data_abort:
62	mov	r0, #4
63	ldr	pc, handle_exception_addr
64
65interrupt:
66	mov	r0, #6
67	ldr	pc, handle_exception_addr
68
69fast_interrupt:
70	mov	r0, #7
71	ldr	pc, handle_exception_addr
72
73handle_exception_addr:
74	.word	handle_exception
75
76vectors_end:
77
78	. = 0xf8
79chip_id:
80	.word	0x00a92750
81
82	. = 0xfc
83rom_version:
84	.word	0x00010055
85
86	.text
87	.align 2
88handle_exception:
89
90	.global panic
91	.type panic, %function
92panic:
931:	wfi
94	b	1b
95	.size panic, . - panic
96
97	.type reset, %function
98reset:
99	mov	r0, #0
100	// Read the CPU ID from MPIDR.
101	mrc	p15, 0, r1, c0, c0, 5
102	tst	r1, #0x03
103	beq	cpu0_init
104
105	// Not CPU0 -- clear the SCRPAD register and wait for it to change.
106	ldr	r2, scrpad_addr
107	str	r0, [r2]
108	dsb	st
109	sev
1101:	wfe
111	ldr	r3, [r2]
112	cmp	r3, #0
113	beq	1b
114
115	// SCRPAD is no longer NULL, so jump there.
116	bx	r3
117	.size reset, . - reset
118
119	.type scrpad_addr, %object
120scrpad_addr:
121	.word	0xF080013C
122	.size scrpad_addr, . - scrpad_addr
123
124	.type cpu0_init, %function
125cpu0_init:
126	ldr	r1, sram_base_addr
127	add	sp, r1, #SRAM_SIZE
128
129	// Copy vectors from ROM to SRAM.
130	ldr	r3, rom_base_addr
131	mov	r2, #0x100
1321:	ldmia	r3!, {r4 - r11}
133	stmia	r1!, {r4 - r11}
134	subs	r2, #32
135	bgt	1b
136
137	// Copy data from ROM to SRAM.
138	ldr	r3, etext_addr
139	ldr	r2, edata_addr
1401:	ldmia	r3!, {r4 - r11}
141	stmia	r1!, {r4 - r11}
142	cmp	r1, r2
143	blt	1b
144
145	// Zero the BSS section.
146	ldr	r2, end_addr
1471:	stmia	r1!, {r0}
148	cmp	r1, r2
149	blt	1b
150
151	// Load the boot image into SRAM. Returns the entry address.
152	bl	load_boot_image
153
154	// Jump to the boot image. Panic if it returns back to us.
155	blx	r0
156	b	panic
157
158	.size cpu0_init, . - cpu0_init
159
160	.type sram_base_addr, %object
161sram_base_addr:
162	.word	0xFFFD0000
163	.size sram_base_addr, . - sram_base_addr
164
165	.type rom_base_addr, %object
166rom_base_addr:
167	.word	0xFFFF0000
168	.size rom_base_addr, . - rom_base_addr
169
170	.type etext_addr, %object
171etext_addr:
172	.word	_etext
173	.size etext_addr, . - etext_addr
174
175	.type edata_addr, %object
176edata_addr:
177	.word	_edata
178	.size edata_addr, . - edata_addr
179
180	.type end_addr, %object
181end_addr:
182	.word	_end
183	.size end_addr, . - end_addr
184