blob: bf80937a7c7b42f5d8a82ed388f8fd389b4580ed [file] [log] [blame]
wdenkfe8c2802002-11-03 00:38:21 +00001/*
2 * armboot - Startup Code for SA1100 CPU
3 *
4 * Copyright (C) 1998 Dan Malek <dmalek@jlc.net>
5 * Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
6 * Copyright (C) 2000 Wolfgang Denk <wd@denx.de>
Albert ARIBAUD60fbc8d2011-08-04 18:45:45 +02007 * Copyright (c) 2001 Alex Züpke <azu@sysgo.de>
wdenkfe8c2802002-11-03 00:38:21 +00008 *
Wolfgang Denkd79de1d2013-07-08 09:37:19 +02009 * SPDX-License-Identifier: GPL-2.0+
wdenkfe8c2802002-11-03 00:38:21 +000010 */
11
Wolfgang Denk0191e472010-10-26 14:34:52 +020012#include <asm-offsets.h>
wdenkfe8c2802002-11-03 00:38:21 +000013#include <config.h>
14#include <version.h>
15
wdenkfe8c2802002-11-03 00:38:21 +000016/*
17 *************************************************************************
18 *
19 * Jump vector table as in table 3.1 in [1]
20 *
21 *************************************************************************
22 */
23
24
25.globl _start
26_start: b reset
27 ldr pc, _undefined_instruction
28 ldr pc, _software_interrupt
29 ldr pc, _prefetch_abort
30 ldr pc, _data_abort
31 ldr pc, _not_used
32 ldr pc, _irq
33 ldr pc, _fiq
34
35_undefined_instruction: .word undefined_instruction
36_software_interrupt: .word software_interrupt
37_prefetch_abort: .word prefetch_abort
38_data_abort: .word data_abort
39_not_used: .word not_used
40_irq: .word irq
41_fiq: .word fiq
42
43 .balignl 16,0xdeadbeef
44
45
46/*
47 *************************************************************************
48 *
49 * Startup Code (reset vector)
50 *
51 * do important init only if we don't start from memory!
52 * relocate armboot to ram
53 * setup stack
54 * jump to second stage
55 *
56 *************************************************************************
57 */
58
wdenkfe8c2802002-11-03 00:38:21 +000059#ifdef CONFIG_USE_IRQ
60/* IRQ stack memory (calculated at run-time) */
61.globl IRQ_STACK_START
62IRQ_STACK_START:
63 .word 0x0badc0de
64
65/* IRQ stack memory (calculated at run-time) */
66.globl FIQ_STACK_START
67FIQ_STACK_START:
68 .word 0x0badc0de
69#endif
Heiko Schocher344c3032010-09-17 13:10:48 +020070
Heiko Schocher344c3032010-09-17 13:10:48 +020071/* IRQ stack memory (calculated at run-time) + 8 bytes */
72.globl IRQ_STACK_START_IN
73IRQ_STACK_START_IN:
74 .word 0x0badc0de
75
Heiko Schocher344c3032010-09-17 13:10:48 +020076/*
77 * the actual reset code
78 */
79
80reset:
81 /*
82 * set the cpu to SVC32 mode
83 */
84 mrs r0,cpsr
85 bic r0,r0,#0x1f
86 orr r0,r0,#0xd3
87 msr cpsr,r0
88
89 /*
90 * we do sys-critical inits only at reboot,
91 * not when booting from ram!
92 */
93#ifndef CONFIG_SKIP_LOWLEVEL_INIT
94 bl cpu_init_crit
95#endif
96
Albert ARIBAUDfacdae52013-01-08 10:18:02 +000097 bl _main
Heiko Schocher344c3032010-09-17 13:10:48 +020098
99/*------------------------------------------------------------------------------*/
100
Albert ARIBAUDfacdae52013-01-08 10:18:02 +0000101 .globl c_runtime_cpu_setup
102c_runtime_cpu_setup:
103
104 mov pc, lr
105
wdenkfe8c2802002-11-03 00:38:21 +0000106/*
107 *************************************************************************
108 *
109 * CPU_init_critical registers
110 *
111 * setup important registers
112 * setup memory timing
113 *
114 *************************************************************************
115 */
116
117
Mike Williamsbf895ad2011-07-22 04:01:30 +0000118/* Interrupt-Controller base address */
wdenkfe8c2802002-11-03 00:38:21 +0000119IC_BASE: .word 0x90050000
120#define ICMR 0x04
121
122
123/* Reset-Controller */
124RST_BASE: .word 0x90030000
125#define RSRR 0x00
126#define RCSR 0x04
127
128
129/* PWR */
130PWR_BASE: .word 0x90020000
131#define PSPR 0x08
132#define PPCR 0x14
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200133cpuspeed: .word CONFIG_SYS_CPUSPEED
wdenkfe8c2802002-11-03 00:38:21 +0000134
135
136cpu_init_crit:
137 /*
138 * mask all IRQs
139 */
140 ldr r0, IC_BASE
141 mov r1, #0x00
142 str r1, [r0, #ICMR]
143
144 /* set clock speed */
145 ldr r0, PWR_BASE
146 ldr r1, cpuspeed
147 str r1, [r0, #PPCR]
148
149 /*
150 * before relocating, we have to setup RAM timing
151 * because memory timing is board-dependend, you will
wdenk336b2bc2005-04-02 23:52:25 +0000152 * find a lowlevel_init.S in your board directory.
wdenkfe8c2802002-11-03 00:38:21 +0000153 */
154 mov ip, lr
wdenk336b2bc2005-04-02 23:52:25 +0000155 bl lowlevel_init
wdenkfe8c2802002-11-03 00:38:21 +0000156 mov lr, ip
157
158 /*
159 * disable MMU stuff and enable I-cache
160 */
161 mrc p15,0,r0,c1,c0
162 bic r0, r0, #0x00002000 @ clear bit 13 (X)
163 bic r0, r0, #0x0000000f @ clear bits 3-0 (WCAM)
164 orr r0, r0, #0x00001000 @ set bit 12 (I) Icache
165 orr r0, r0, #0x00000002 @ set bit 2 (A) Align
166 mcr p15,0,r0,c1,c0
167
168 /*
169 * flush v4 I/D caches
170 */
171 mov r0, #0
172 mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
173 mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
174
175 mov pc, lr
176
177
wdenkfe8c2802002-11-03 00:38:21 +0000178/*
179 *************************************************************************
180 *
181 * Interrupt handling
182 *
183 *************************************************************************
184 */
185
186@
187@ IRQ stack frame.
188@
189#define S_FRAME_SIZE 72
190
191#define S_OLD_R0 68
192#define S_PSR 64
193#define S_PC 60
194#define S_LR 56
195#define S_SP 52
196
197#define S_IP 48
198#define S_FP 44
199#define S_R10 40
200#define S_R9 36
201#define S_R8 32
202#define S_R7 28
203#define S_R6 24
204#define S_R5 20
205#define S_R4 16
206#define S_R3 12
207#define S_R2 8
208#define S_R1 4
209#define S_R0 0
210
211#define MODE_SVC 0x13
212#define I_BIT 0x80
213
214/*
215 * use bad_save_user_regs for abort/prefetch/undef/swi ...
216 * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
217 */
218
219 .macro bad_save_user_regs
220 sub sp, sp, #S_FRAME_SIZE
221 stmia sp, {r0 - r12} @ Calling r0-r12
222 add r8, sp, #S_PC
223
Heiko Schocher344c3032010-09-17 13:10:48 +0200224 ldr r2, IRQ_STACK_START_IN
wdenkfe8c2802002-11-03 00:38:21 +0000225 ldmia r2, {r2 - r4} @ get pc, cpsr, old_r0
226 add r0, sp, #S_FRAME_SIZE @ restore sp_SVC
227
228 add r5, sp, #S_SP
229 mov r1, lr
230 stmia r5, {r0 - r4} @ save sp_SVC, lr_SVC, pc, cpsr, old_r
231 mov r0, sp
232 .endm
233
234 .macro irq_save_user_regs
235 sub sp, sp, #S_FRAME_SIZE
236 stmia sp, {r0 - r12} @ Calling r0-r12
237 add r8, sp, #S_PC
238 stmdb r8, {sp, lr}^ @ Calling SP, LR
239 str lr, [r8, #0] @ Save calling PC
240 mrs r6, spsr
241 str r6, [r8, #4] @ Save CPSR
242 str r0, [r8, #8] @ Save OLD_R0
243 mov r0, sp
244 .endm
245
246 .macro irq_restore_user_regs
247 ldmia sp, {r0 - lr}^ @ Calling r0 - lr
248 mov r0, r0
249 ldr lr, [sp, #S_PC] @ Get PC
250 add sp, sp, #S_FRAME_SIZE
251 subs pc, lr, #4 @ return & move spsr_svc into cpsr
252 .endm
253
254 .macro get_bad_stack
Heiko Schocher344c3032010-09-17 13:10:48 +0200255 ldr r13, IRQ_STACK_START_IN @ setup our mode stack
wdenkfe8c2802002-11-03 00:38:21 +0000256
257 str lr, [r13] @ save caller lr / spsr
258 mrs lr, spsr
259 str lr, [r13, #4]
260
261 mov r13, #MODE_SVC @ prepare SVC-Mode
262 msr spsr_c, r13
263 mov lr, pc
264 movs pc, lr
265 .endm
266
267 .macro get_irq_stack @ setup IRQ stack
268 ldr sp, IRQ_STACK_START
269 .endm
270
271 .macro get_fiq_stack @ setup FIQ stack
272 ldr sp, FIQ_STACK_START
273 .endm
274
275/*
276 * exception handlers
277 */
278 .align 5
279undefined_instruction:
280 get_bad_stack
281 bad_save_user_regs
Wolfgang Denka1be4762008-05-20 16:00:29 +0200282 bl do_undefined_instruction
wdenkfe8c2802002-11-03 00:38:21 +0000283
284 .align 5
285software_interrupt:
286 get_bad_stack
287 bad_save_user_regs
Wolfgang Denka1be4762008-05-20 16:00:29 +0200288 bl do_software_interrupt
wdenkfe8c2802002-11-03 00:38:21 +0000289
290 .align 5
291prefetch_abort:
292 get_bad_stack
293 bad_save_user_regs
Wolfgang Denka1be4762008-05-20 16:00:29 +0200294 bl do_prefetch_abort
wdenkfe8c2802002-11-03 00:38:21 +0000295
296 .align 5
297data_abort:
298 get_bad_stack
299 bad_save_user_regs
Wolfgang Denka1be4762008-05-20 16:00:29 +0200300 bl do_data_abort
wdenkfe8c2802002-11-03 00:38:21 +0000301
302 .align 5
303not_used:
304 get_bad_stack
305 bad_save_user_regs
Wolfgang Denka1be4762008-05-20 16:00:29 +0200306 bl do_not_used
wdenkfe8c2802002-11-03 00:38:21 +0000307
308#ifdef CONFIG_USE_IRQ
309
310 .align 5
311irq:
312 get_irq_stack
313 irq_save_user_regs
Wolfgang Denka1be4762008-05-20 16:00:29 +0200314 bl do_irq
wdenkfe8c2802002-11-03 00:38:21 +0000315 irq_restore_user_regs
316
317 .align 5
318fiq:
319 get_fiq_stack
320 /* someone ought to write a more effiction fiq_save_user_regs */
321 irq_save_user_regs
Wolfgang Denka1be4762008-05-20 16:00:29 +0200322 bl do_fiq
wdenkfe8c2802002-11-03 00:38:21 +0000323 irq_restore_user_regs
324
325#else
326
327 .align 5
328irq:
329 get_bad_stack
330 bad_save_user_regs
Wolfgang Denka1be4762008-05-20 16:00:29 +0200331 bl do_irq
wdenkfe8c2802002-11-03 00:38:21 +0000332
333 .align 5
334fiq:
335 get_bad_stack
336 bad_save_user_regs
Wolfgang Denka1be4762008-05-20 16:00:29 +0200337 bl do_fiq
wdenkfe8c2802002-11-03 00:38:21 +0000338
339#endif
340
341 .align 5
342.globl reset_cpu
343reset_cpu:
344 ldr r0, RST_BASE
345 mov r1, #0x0 @ set bit 3-0 ...
346 str r1, [r0, #RCSR] @ ... to clear in RCSR
347 mov r1, #0x1
348 str r1, [r0, #RSRR] @ and perform reset
349 b reset_cpu @ silly, but repeat endlessly