blob: 8010b0ee17a88696817d70c094ea08d707e6e0b8 [file] [log] [blame]
wdenkc6097192002-11-03 00:24:07 +00001/*
2 * armboot - Startup Code for XScale
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>
wdenka8c7c702003-12-06 19:49:23 +00007 * Copyright (C) 2001 Alex Zuepke <azu@sysgo.de>
wdenk1cb8e982003-03-06 21:55:29 +00008 * Copyright (C) 2002 Kyle Harris <kharris@nexus-tech.net>
Wolfgang Denk951a9542006-03-06 23:18:48 +01009 * Copyright (C) 2003 Robert Schwebel <r.schwebel@pengutronix.de>
10 * Copyright (C) 2003 Kai-Uwe Bloem <kai-uwe.bloem@auerswald.de>
wdenkc6097192002-11-03 00:24:07 +000011 *
12 * See file CREDITS for list of people who contributed to this
13 * project.
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation; either version 2 of
18 * the License, or (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
wdenk384ae022002-11-05 00:17:55 +000022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
wdenkc6097192002-11-03 00:24:07 +000023 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
28 * MA 02111-1307 USA
29 */
30
wdenkc6097192002-11-03 00:24:07 +000031#include <config.h>
32#include <version.h>
Markus Klotzbüchere8cd0082006-02-28 23:11:07 +010033#include <asm/arch/pxa-regs.h>
wdenkc6097192002-11-03 00:24:07 +000034
35.globl _start
wdenk384ae022002-11-05 00:17:55 +000036_start: b reset
Marek Vasut5ab877b2010-07-06 02:48:35 +020037#ifdef CONFIG_PRELOADER
38 ldr pc, _hang
39 ldr pc, _hang
40 ldr pc, _hang
41 ldr pc, _hang
42 ldr pc, _hang
43 ldr pc, _hang
44 ldr pc, _hang
45
46_hang:
47 .word do_hang
48 .word 0x12345678
49 .word 0x12345678
50 .word 0x12345678
51 .word 0x12345678
52 .word 0x12345678
53 .word 0x12345678
54 .word 0x12345678 /* now 16*4=64 */
55#else
wdenkc6097192002-11-03 00:24:07 +000056 ldr pc, _undefined_instruction
57 ldr pc, _software_interrupt
58 ldr pc, _prefetch_abort
59 ldr pc, _data_abort
60 ldr pc, _not_used
61 ldr pc, _irq
62 ldr pc, _fiq
63
wdenk384ae022002-11-05 00:17:55 +000064_undefined_instruction: .word undefined_instruction
wdenkc6097192002-11-03 00:24:07 +000065_software_interrupt: .word software_interrupt
66_prefetch_abort: .word prefetch_abort
67_data_abort: .word data_abort
68_not_used: .word not_used
69_irq: .word irq
70_fiq: .word fiq
Marek Vasut5ab877b2010-07-06 02:48:35 +020071#endif /* CONFIG_PRELOADER */
wdenkc6097192002-11-03 00:24:07 +000072
73 .balignl 16,0xdeadbeef
74
75
76/*
77 * Startup Code (reset vector)
78 *
wdenka8c7c702003-12-06 19:49:23 +000079 * do important init only if we don't start from RAM!
Marcel Ziswiler10c73822007-12-30 03:30:56 +010080 * - relocate armboot to RAM
wdenkc6097192002-11-03 00:24:07 +000081 * - setup stack
82 * - jump to second stage
83 */
84
wdenkc6097192002-11-03 00:24:07 +000085_TEXT_BASE:
86 .word TEXT_BASE
87
88.globl _armboot_start
89_armboot_start:
90 .word _start
91
92/*
wdenkf6e20fc2004-02-08 19:38:38 +000093 * These are defined in the board-specific linker script.
wdenk47cd00f2003-03-06 13:39:27 +000094 */
wdenk8bde7f72003-06-27 21:31:46 +000095.globl _bss_start
96_bss_start:
wdenkf6e20fc2004-02-08 19:38:38 +000097 .word __bss_start
wdenk47cd00f2003-03-06 13:39:27 +000098
99.globl _bss_end
100_bss_end:
wdenkf6e20fc2004-02-08 19:38:38 +0000101 .word _end
wdenk47cd00f2003-03-06 13:39:27 +0000102
wdenkc6097192002-11-03 00:24:07 +0000103#ifdef CONFIG_USE_IRQ
104/* IRQ stack memory (calculated at run-time) */
105.globl IRQ_STACK_START
106IRQ_STACK_START:
107 .word 0x0badc0de
108
109/* IRQ stack memory (calculated at run-time) */
110.globl FIQ_STACK_START
111FIQ_STACK_START:
112 .word 0x0badc0de
Marcel Ziswiler10c73822007-12-30 03:30:56 +0100113#endif /* CONFIG_USE_IRQ */
wdenkc6097192002-11-03 00:24:07 +0000114
115
116/****************************************************************************/
wdenk384ae022002-11-05 00:17:55 +0000117/* */
118/* the actual reset code */
119/* */
wdenkc6097192002-11-03 00:24:07 +0000120/****************************************************************************/
121
122reset:
Marcel Ziswiler10c73822007-12-30 03:30:56 +0100123 mrs r0,cpsr /* set the CPU to SVC32 mode */
wdenk384ae022002-11-05 00:17:55 +0000124 bic r0,r0,#0x1f /* (superviser mode, M=10011) */
wdenkc6097192002-11-03 00:24:07 +0000125 orr r0,r0,#0x13
126 msr cpsr,r0
127
wdenka8c7c702003-12-06 19:49:23 +0000128 /*
129 * we do sys-critical inits only at reboot,
Marcel Ziswiler10c73822007-12-30 03:30:56 +0100130 * not when booting from RAM!
wdenka8c7c702003-12-06 19:49:23 +0000131 */
wdenk8aa1a2d2005-04-04 12:44:11 +0000132#ifndef CONFIG_SKIP_LOWLEVEL_INIT
wdenk384ae022002-11-05 00:17:55 +0000133 bl cpu_init_crit /* we do sys-critical inits */
Marcel Ziswiler10c73822007-12-30 03:30:56 +0100134#endif /* !CONFIG_SKIP_LOWLEVEL_INIT */
wdenkc6097192002-11-03 00:24:07 +0000135
wdenk8aa1a2d2005-04-04 12:44:11 +0000136#ifndef CONFIG_SKIP_RELOCATE_UBOOT
wdenk1cb8e982003-03-06 21:55:29 +0000137relocate: /* relocate U-Boot to RAM */
138 adr r0, _start /* r0 <- current position of code */
wdenk8bde7f72003-06-27 21:31:46 +0000139 ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
Marek Vasut5ab877b2010-07-06 02:48:35 +0200140#ifndef CONFIG_PRELOADER
Wolfgang Denk951a9542006-03-06 23:18:48 +0100141 cmp r0, r1 /* don't reloc during debug */
142 beq stack_setup
Marek Vasut5ab877b2010-07-06 02:48:35 +0200143#endif
wdenk1cb8e982003-03-06 21:55:29 +0000144
wdenkc6097192002-11-03 00:24:07 +0000145 ldr r2, _armboot_start
wdenkf6e20fc2004-02-08 19:38:38 +0000146 ldr r3, _bss_start
Wolfgang Denk951a9542006-03-06 23:18:48 +0100147 sub r2, r3, r2 /* r2 <- size of armboot */
148 add r2, r0, r2 /* r2 <- source end address */
wdenkc6097192002-11-03 00:24:07 +0000149
150copy_loop:
151 ldmia r0!, {r3-r10} /* copy from source address [r0] */
152 stmia r1!, {r3-r10} /* copy to target address [r1] */
Marcel Ziswilerdbab0692008-07-09 08:17:06 +0200153 cmp r0, r2 /* until source end address [r2] */
wdenkc6097192002-11-03 00:24:07 +0000154 ble copy_loop
Marcel Ziswiler10c73822007-12-30 03:30:56 +0100155#endif /* !CONFIG_SKIP_RELOCATE_UBOOT */
wdenkc6097192002-11-03 00:24:07 +0000156
wdenk384ae022002-11-05 00:17:55 +0000157 /* Set up the stack */
wdenk1cb8e982003-03-06 21:55:29 +0000158stack_setup:
wdenka8c7c702003-12-06 19:49:23 +0000159 ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
Marek Vasut5ab877b2010-07-06 02:48:35 +0200160#ifdef CONFIG_PRELOADER
161 sub sp, r0, #128 /* leave 32 words for abort-stack */
162#else
163 sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */
164 sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */
wdenka8c7c702003-12-06 19:49:23 +0000165#ifdef CONFIG_USE_IRQ
166 sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
Marcel Ziswiler10c73822007-12-30 03:30:56 +0100167#endif /* CONFIG_USE_IRQ */
Vitaly Kuzmichev1a27f7d2010-06-15 22:18:11 +0400168 sub sp, r0, #12 /* leave 3 words for abort-stack */
169 bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
Marek Vasut5ab877b2010-07-06 02:48:35 +0200170#endif
wdenk47cd00f2003-03-06 13:39:27 +0000171
172clear_bss:
Wolfgang Denk951a9542006-03-06 23:18:48 +0100173 ldr r0, _bss_start /* find start of bss segment */
174 ldr r1, _bss_end /* stop here */
175 mov r2, #0x00000000 /* clear */
wdenk47cd00f2003-03-06 13:39:27 +0000176
Marek Vasut5ab877b2010-07-06 02:48:35 +0200177#ifndef CONFIG_PRELOADER
Wolfgang Denk951a9542006-03-06 23:18:48 +0100178clbss_l:str r2, [r0] /* clear loop... */
wdenk47cd00f2003-03-06 13:39:27 +0000179 add r0, r0, #4
180 cmp r0, r1
wdenka1191902005-01-09 17:12:27 +0000181 ble clbss_l
Marek Vasut5ab877b2010-07-06 02:48:35 +0200182#endif
wdenk47cd00f2003-03-06 13:39:27 +0000183
wdenkc6097192002-11-03 00:24:07 +0000184 ldr pc, _start_armboot
185
Marek Vasut5ab877b2010-07-06 02:48:35 +0200186#ifdef CONFIG_ONENAND_IPL
187_start_armboot: .word start_oneboot
188#else
wdenk384ae022002-11-05 00:17:55 +0000189_start_armboot: .word start_armboot
Marek Vasut5ab877b2010-07-06 02:48:35 +0200190#endif
wdenkc6097192002-11-03 00:24:07 +0000191
192/****************************************************************************/
wdenk384ae022002-11-05 00:17:55 +0000193/* */
194/* CPU_init_critical registers */
195/* */
196/* - setup important registers */
197/* - setup memory timing */
198/* */
wdenkc6097192002-11-03 00:24:07 +0000199/****************************************************************************/
Markus Klotzbücher43638c62006-03-06 15:04:25 +0100200/* mk@tbd: Fix this! */
Jean-Christophe PLAGNIOL-VILLARD27c38682008-05-01 02:13:44 +0200201#undef RCSR
Markus Klotzbücher43638c62006-03-06 15:04:25 +0100202#undef ICMR
203#undef OSMR3
204#undef OSCR
205#undef OWER
206#undef OIER
Marcel Ziswiler2a4741d2007-10-19 00:25:33 +0200207#undef CCCR
wdenkc6097192002-11-03 00:24:07 +0000208
Wolfgang Denk951a9542006-03-06 23:18:48 +0100209/* Interrupt-Controller base address */
wdenkc6097192002-11-03 00:24:07 +0000210IC_BASE: .word 0x40d00000
211#define ICMR 0x04
212
213/* Reset-Controller */
wdenk384ae022002-11-05 00:17:55 +0000214RST_BASE: .word 0x40f00030
wdenkc6097192002-11-03 00:24:07 +0000215#define RCSR 0x00
216
wdenk1cb8e982003-03-06 21:55:29 +0000217/* Operating System Timer */
wdenk384ae022002-11-05 00:17:55 +0000218OSTIMER_BASE: .word 0x40a00000
219#define OSMR3 0x0C
220#define OSCR 0x10
221#define OWER 0x18
222#define OIER 0x1C
wdenkc6097192002-11-03 00:24:07 +0000223
Wolfgang Denk951a9542006-03-06 23:18:48 +0100224/* Clock Manager Registers */
Markus Klotzbuecher40b0baf2006-03-24 14:35:25 +0100225#ifdef CONFIG_CPU_MONAHANS
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200226# ifndef CONFIG_SYS_MONAHANS_RUN_MODE_OSC_RATIO
227# error "You have to define CONFIG_SYS_MONAHANS_RUN_MODE_OSC_RATIO!!"
228# endif /* !CONFIG_SYS_MONAHANS_RUN_MODE_OSC_RATIO */
229# ifndef CONFIG_SYS_MONAHANS_TURBO_RUN_MODE_RATIO
230# define CONFIG_SYS_MONAHANS_TURBO_RUN_MODE_RATIO 0x1
231# endif /* !CONFIG_SYS_MONAHANS_TURBO_RUN_MODE_RATIO */
Marcel Ziswiler10c73822007-12-30 03:30:56 +0100232#else /* !CONFIG_CPU_MONAHANS */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200233#ifdef CONFIG_SYS_CPUSPEED
wdenk384ae022002-11-05 00:17:55 +0000234CC_BASE: .word 0x41300000
235#define CCCR 0x00
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200236cpuspeed: .word CONFIG_SYS_CPUSPEED
237#else /* !CONFIG_SYS_CPUSPEED */
238#error "You have to define CONFIG_SYS_CPUSPEED!!"
239#endif /* CONFIG_SYS_CPUSPEED */
Markus Klotzbuecher40b0baf2006-03-24 14:35:25 +0100240#endif /* CONFIG_CPU_MONAHANS */
wdenk1cb8e982003-03-06 21:55:29 +0000241
Markus Klotzbüchere0269572006-02-07 20:04:48 +0100242 /* takes care the CP15 update has taken place */
243 .macro CPWAIT reg
244 mrc p15,0,\reg,c2,c0,0
245 mov \reg,\reg
wdenkc6097192002-11-03 00:24:07 +0000246 sub pc,pc,#4
247 .endm
248
wdenkc6097192002-11-03 00:24:07 +0000249cpu_init_crit:
250
wdenk384ae022002-11-05 00:17:55 +0000251 /* mask all IRQs */
Markus Klotzbüchere0269572006-02-07 20:04:48 +0100252#ifndef CONFIG_CPU_MONAHANS
wdenkc6097192002-11-03 00:24:07 +0000253 ldr r0, IC_BASE
254 mov r1, #0x00
255 str r1, [r0, #ICMR]
Marcel Ziswiler10c73822007-12-30 03:30:56 +0100256#else /* CONFIG_CPU_MONAHANS */
Markus Klotzbüchere0269572006-02-07 20:04:48 +0100257 /* Step 1 - Enable CP6 permission */
Wolfgang Denk951a9542006-03-06 23:18:48 +0100258 mrc p15, 0, r1, c15, c1, 0 @ read CPAR
259 orr r1, r1, #0x40
260 mcr p15, 0, r1, c15, c1, 0
261 CPWAIT r1
wdenkc6097192002-11-03 00:24:07 +0000262
Wolfgang Denk951a9542006-03-06 23:18:48 +0100263 /* Step 2 - Mask ICMR & ICMR2 */
264 mov r1, #0
265 mcr p6, 0, r1, c1, c0, 0 @ ICMR
266 mcr p6, 0, r1, c7, c0, 0 @ ICMR2
Markus Klotzbüchere8cd0082006-02-28 23:11:07 +0100267
268 /* turn off all clocks but the ones we will definitly require */
Wolfgang Denk951a9542006-03-06 23:18:48 +0100269 ldr r1, =CKENA
270 ldr r2, =(CKENA_22_FFUART | CKENA_10_SRAM | CKENA_9_SMC | CKENA_8_DMC)
271 str r2, [r1]
272 ldr r1, =CKENB
273 ldr r2, =(CKENB_6_IRQ)
274 str r2, [r1]
Marcel Ziswiler10c73822007-12-30 03:30:56 +0100275#endif /* !CONFIG_CPU_MONAHANS */
wdenk1cb8e982003-03-06 21:55:29 +0000276
Markus Klotzbuecher40b0baf2006-03-24 14:35:25 +0100277 /* set clock speed */
278#ifdef CONFIG_CPU_MONAHANS
279 ldr r0, =ACCR
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200280 ldr r1, =(((CONFIG_SYS_MONAHANS_TURBO_RUN_MODE_RATIO<<8) & ACCR_XN_MASK) | (CONFIG_SYS_MONAHANS_RUN_MODE_OSC_RATIO & ACCR_XL_MASK))
Markus Klotzbuecher40b0baf2006-03-24 14:35:25 +0100281 str r1, [r0]
Marcel Ziswiler10c73822007-12-30 03:30:56 +0100282#else /* !CONFIG_CPU_MONAHANS */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200283#ifdef CONFIG_SYS_CPUSPEED
wdenkc6097192002-11-03 00:24:07 +0000284 ldr r0, CC_BASE
285 ldr r1, cpuspeed
286 str r1, [r0, #CCCR]
wdenk1cb8e982003-03-06 21:55:29 +0000287 mov r0, #2
wdenk7f6c2cb2002-11-10 22:06:23 +0000288 mcr p14, 0, r0, c6, c0, 0
wdenk1cb8e982003-03-06 21:55:29 +0000289
290setspeed_done:
Wolfgang Denk951a9542006-03-06 23:18:48 +0100291
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200292#endif /* CONFIG_SYS_CPUSPEED */
Markus Klotzbüchere0269572006-02-07 20:04:48 +0100293#endif /* CONFIG_CPU_MONAHANS */
wdenkc6097192002-11-03 00:24:07 +0000294
295 /*
296 * before relocating, we have to setup RAM timing
297 * because memory timing is board-dependend, you will
wdenk400558b2005-04-02 23:52:25 +0000298 * find a lowlevel_init.S in your board directory.
wdenkc6097192002-11-03 00:24:07 +0000299 */
300 mov ip, lr
wdenk400558b2005-04-02 23:52:25 +0000301 bl lowlevel_init
wdenkc6097192002-11-03 00:24:07 +0000302 mov lr, ip
303
304 /* Memory interfaces are working. Disable MMU and enable I-cache. */
Wolfgang Denk951a9542006-03-06 23:18:48 +0100305 /* mk: hmm, this is not in the monahans docs, leave it now but
Markus Klotzbüchere0269572006-02-07 20:04:48 +0100306 * check here if it doesn't work :-) */
wdenkc6097192002-11-03 00:24:07 +0000307
wdenk384ae022002-11-05 00:17:55 +0000308 ldr r0, =0x2001 /* enable access to all coproc. */
wdenkc6097192002-11-03 00:24:07 +0000309 mcr p15, 0, r0, c15, c1, 0
Markus Klotzbüchere0269572006-02-07 20:04:48 +0100310 CPWAIT r0
wdenkc6097192002-11-03 00:24:07 +0000311
312 mcr p15, 0, r0, c7, c10, 4 /* drain the write & fill buffers */
Markus Klotzbüchere0269572006-02-07 20:04:48 +0100313 CPWAIT r0
wdenkc6097192002-11-03 00:24:07 +0000314
wdenk384ae022002-11-05 00:17:55 +0000315 mcr p15, 0, r0, c7, c7, 0 /* flush Icache, Dcache and BTB */
Markus Klotzbüchere0269572006-02-07 20:04:48 +0100316 CPWAIT r0
wdenkc6097192002-11-03 00:24:07 +0000317
318 mcr p15, 0, r0, c8, c7, 0 /* flush instuction and data TLBs */
Markus Klotzbüchere0269572006-02-07 20:04:48 +0100319 CPWAIT r0
wdenkc6097192002-11-03 00:24:07 +0000320
wdenk384ae022002-11-05 00:17:55 +0000321 /* Enable the Icache */
wdenkc6097192002-11-03 00:24:07 +0000322/*
323 mrc p15, 0, r0, c1, c0, 0
324 orr r0, r0, #0x1800
325 mcr p15, 0, r0, c1, c0, 0
wdenk699b13a2002-11-03 18:03:52 +0000326 CPWAIT
wdenkc6097192002-11-03 00:24:07 +0000327*/
328 mov pc, lr
329
Marek Vasut5ab877b2010-07-06 02:48:35 +0200330#ifndef CONFIG_PRELOADER
wdenkc6097192002-11-03 00:24:07 +0000331/****************************************************************************/
wdenk384ae022002-11-05 00:17:55 +0000332/* */
333/* Interrupt handling */
334/* */
wdenkc6097192002-11-03 00:24:07 +0000335/****************************************************************************/
336
wdenk384ae022002-11-05 00:17:55 +0000337/* IRQ stack frame */
wdenkc6097192002-11-03 00:24:07 +0000338
339#define S_FRAME_SIZE 72
340
341#define S_OLD_R0 68
342#define S_PSR 64
343#define S_PC 60
344#define S_LR 56
345#define S_SP 52
346
347#define S_IP 48
348#define S_FP 44
349#define S_R10 40
350#define S_R9 36
351#define S_R8 32
352#define S_R7 28
353#define S_R6 24
354#define S_R5 20
355#define S_R4 16
356#define S_R3 12
357#define S_R2 8
358#define S_R1 4
359#define S_R0 0
360
361#define MODE_SVC 0x13
362
wdenk384ae022002-11-05 00:17:55 +0000363 /* use bad_save_user_regs for abort/prefetch/undef/swi ... */
wdenkc6097192002-11-03 00:24:07 +0000364
365 .macro bad_save_user_regs
366 sub sp, sp, #S_FRAME_SIZE
wdenk384ae022002-11-05 00:17:55 +0000367 stmia sp, {r0 - r12} /* Calling r0-r12 */
368 add r8, sp, #S_PC
wdenkc6097192002-11-03 00:24:07 +0000369
wdenkf6e20fc2004-02-08 19:38:38 +0000370 ldr r2, _armboot_start
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200371 sub r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN)
372 sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ set base 2 words into abort stack
wdenk384ae022002-11-05 00:17:55 +0000373 ldmia r2, {r2 - r4} /* get pc, cpsr, old_r0 */
374 add r0, sp, #S_FRAME_SIZE /* restore sp_SVC */
wdenkc6097192002-11-03 00:24:07 +0000375
376 add r5, sp, #S_SP
377 mov r1, lr
wdenk384ae022002-11-05 00:17:55 +0000378 stmia r5, {r0 - r4} /* save sp_SVC, lr_SVC, pc, cpsr, old_r */
wdenkc6097192002-11-03 00:24:07 +0000379 mov r0, sp
380 .endm
381
382
wdenk384ae022002-11-05 00:17:55 +0000383 /* use irq_save_user_regs / irq_restore_user_regs for */
384 /* IRQ/FIQ handling */
wdenkc6097192002-11-03 00:24:07 +0000385
386 .macro irq_save_user_regs
387 sub sp, sp, #S_FRAME_SIZE
wdenk384ae022002-11-05 00:17:55 +0000388 stmia sp, {r0 - r12} /* Calling r0-r12 */
389 add r8, sp, #S_PC
390 stmdb r8, {sp, lr}^ /* Calling SP, LR */
391 str lr, [r8, #0] /* Save calling PC */
392 mrs r6, spsr
393 str r6, [r8, #4] /* Save CPSR */
394 str r0, [r8, #8] /* Save OLD_R0 */
wdenkc6097192002-11-03 00:24:07 +0000395 mov r0, sp
396 .endm
397
398 .macro irq_restore_user_regs
399 ldmia sp, {r0 - lr}^ @ Calling r0 - lr
400 mov r0, r0
401 ldr lr, [sp, #S_PC] @ Get PC
402 add sp, sp, #S_FRAME_SIZE
403 subs pc, lr, #4 @ return & move spsr_svc into cpsr
404 .endm
405
406 .macro get_bad_stack
wdenkf6e20fc2004-02-08 19:38:38 +0000407 ldr r13, _armboot_start @ setup our mode stack
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200408 sub r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN)
409 sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack
wdenkc6097192002-11-03 00:24:07 +0000410
411 str lr, [r13] @ save caller lr / spsr
412 mrs lr, spsr
wdenk384ae022002-11-05 00:17:55 +0000413 str lr, [r13, #4]
wdenkc6097192002-11-03 00:24:07 +0000414
415 mov r13, #MODE_SVC @ prepare SVC-Mode
416 msr spsr_c, r13
417 mov lr, pc
418 movs pc, lr
419 .endm
420
421 .macro get_irq_stack @ setup IRQ stack
422 ldr sp, IRQ_STACK_START
423 .endm
424
425 .macro get_fiq_stack @ setup FIQ stack
426 ldr sp, FIQ_STACK_START
427 .endm
Marek Vasut5ab877b2010-07-06 02:48:35 +0200428#endif /* CONFIG_PRELOADER */
wdenkc6097192002-11-03 00:24:07 +0000429
430
431/****************************************************************************/
wdenk384ae022002-11-05 00:17:55 +0000432/* */
433/* exception handlers */
434/* */
wdenkc6097192002-11-03 00:24:07 +0000435/****************************************************************************/
436
Marek Vasut5ab877b2010-07-06 02:48:35 +0200437#ifdef CONFIG_PRELOADER
438 .align 5
439do_hang:
440 ldr sp, _TEXT_BASE /* use 32 words abort stack */
441 bl hang /* hang and never return */
442#else /* !CONFIG_PRELOADER */
wdenk384ae022002-11-05 00:17:55 +0000443 .align 5
wdenkc6097192002-11-03 00:24:07 +0000444undefined_instruction:
445 get_bad_stack
446 bad_save_user_regs
wdenk384ae022002-11-05 00:17:55 +0000447 bl do_undefined_instruction
wdenkc6097192002-11-03 00:24:07 +0000448
449 .align 5
450software_interrupt:
451 get_bad_stack
452 bad_save_user_regs
wdenk384ae022002-11-05 00:17:55 +0000453 bl do_software_interrupt
wdenkc6097192002-11-03 00:24:07 +0000454
455 .align 5
456prefetch_abort:
457 get_bad_stack
458 bad_save_user_regs
wdenk384ae022002-11-05 00:17:55 +0000459 bl do_prefetch_abort
wdenkc6097192002-11-03 00:24:07 +0000460
461 .align 5
462data_abort:
463 get_bad_stack
464 bad_save_user_regs
wdenk384ae022002-11-05 00:17:55 +0000465 bl do_data_abort
wdenkc6097192002-11-03 00:24:07 +0000466
467 .align 5
468not_used:
469 get_bad_stack
470 bad_save_user_regs
wdenk384ae022002-11-05 00:17:55 +0000471 bl do_not_used
wdenkc6097192002-11-03 00:24:07 +0000472
473#ifdef CONFIG_USE_IRQ
474
475 .align 5
476irq:
477 get_irq_stack
478 irq_save_user_regs
wdenk384ae022002-11-05 00:17:55 +0000479 bl do_irq
wdenkc6097192002-11-03 00:24:07 +0000480 irq_restore_user_regs
481
482 .align 5
483fiq:
484 get_fiq_stack
485 irq_save_user_regs /* someone ought to write a more */
wdenk384ae022002-11-05 00:17:55 +0000486 bl do_fiq /* effiction fiq_save_user_regs */
wdenkc6097192002-11-03 00:24:07 +0000487 irq_restore_user_regs
488
Marcel Ziswiler10c73822007-12-30 03:30:56 +0100489#else /* !CONFIG_USE_IRQ */
wdenkc6097192002-11-03 00:24:07 +0000490
491 .align 5
492irq:
493 get_bad_stack
494 bad_save_user_regs
wdenk384ae022002-11-05 00:17:55 +0000495 bl do_irq
wdenkc6097192002-11-03 00:24:07 +0000496
497 .align 5
498fiq:
499 get_bad_stack
500 bad_save_user_regs
wdenk384ae022002-11-05 00:17:55 +0000501 bl do_fiq
Marek Vasut5ab877b2010-07-06 02:48:35 +0200502#endif /* CONFIG_PRELOADER */
Marcel Ziswiler10c73822007-12-30 03:30:56 +0100503#endif /* CONFIG_USE_IRQ */
wdenkc6097192002-11-03 00:24:07 +0000504
wdenk1cb8e982003-03-06 21:55:29 +0000505/****************************************************************************/
Wolfgang Denk951a9542006-03-06 23:18:48 +0100506/* */
wdenk1cb8e982003-03-06 21:55:29 +0000507/* Reset function: the PXA250 doesn't have a reset function, so we have to */
Wolfgang Denk951a9542006-03-06 23:18:48 +0100508/* perform a watchdog timeout for a soft reset. */
509/* */
wdenk1cb8e982003-03-06 21:55:29 +0000510/****************************************************************************/
511
wdenkc6097192002-11-03 00:24:07 +0000512 .align 5
513.globl reset_cpu
wdenk1cb8e982003-03-06 21:55:29 +0000514
Wolfgang Denk951a9542006-03-06 23:18:48 +0100515 /* FIXME: this code is PXA250 specific. How is this handled on */
516 /* other XScale processors? */
wdenk1cb8e982003-03-06 21:55:29 +0000517
wdenkc6097192002-11-03 00:24:07 +0000518reset_cpu:
wdenk1cb8e982003-03-06 21:55:29 +0000519
wdenk384ae022002-11-05 00:17:55 +0000520 /* We set OWE:WME (watchdog enable) and wait until timeout happens */
wdenkc6097192002-11-03 00:24:07 +0000521
wdenk384ae022002-11-05 00:17:55 +0000522 ldr r0, OSTIMER_BASE
523 ldr r1, [r0, #OWER]
Wolfgang Denk951a9542006-03-06 23:18:48 +0100524 orr r1, r1, #0x0001 /* bit0: WME */
wdenk384ae022002-11-05 00:17:55 +0000525 str r1, [r0, #OWER]
526
527 /* OS timer does only wrap every 1165 seconds, so we have to set */
Wolfgang Denk951a9542006-03-06 23:18:48 +0100528 /* the match register as well. */
wdenk384ae022002-11-05 00:17:55 +0000529
Wolfgang Denk951a9542006-03-06 23:18:48 +0100530 ldr r1, [r0, #OSCR] /* read OS timer */
wdenk384ae022002-11-05 00:17:55 +0000531 add r1, r1, #0x800 /* let OSMR3 match after */
532 add r1, r1, #0x800 /* 4096*(1/3.6864MHz)=1ms */
533 str r1, [r0, #OSMR3]
534
535reset_endless:
536
537 b reset_endless