blob: cfb94112d0aca7f3c8c7d5c73b741cd56df41a2b [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>
wdenkc0aa5c52003-12-06 19:49:23 +00007 * Copyright (C) 2001 Alex Zuepke <azu@sysgo.de>
wdenk1fe2c702003-03-06 21:55:29 +00008 * Copyright (C) 2002 Kyle Harris <kharris@nexus-tech.net>
Wolfgang Denk61ccd1d2006-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ücherd5dfcf92006-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 Vasutc13685c2010-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 Vasutc13685c2010-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 *
wdenkc0aa5c52003-12-06 19:49:23 +000079 * do important init only if we don't start from RAM!
Marcel Ziswiler00376352007-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
Heiko Schocher3d8f5fa2010-09-17 13:10:46 +020085.globl _TEXT_BASE
wdenkc6097192002-11-03 00:24:07 +000086_TEXT_BASE:
87 .word TEXT_BASE
88
Heiko Schocher3d8f5fa2010-09-17 13:10:46 +020089#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
wdenkc6097192002-11-03 00:24:07 +000090.globl _armboot_start
91_armboot_start:
92 .word _start
Heiko Schocher3d8f5fa2010-09-17 13:10:46 +020093#endif
wdenkc6097192002-11-03 00:24:07 +000094
95/*
wdenk927034e2004-02-08 19:38:38 +000096 * These are defined in the board-specific linker script.
wdenkcc1e2562003-03-06 13:39:27 +000097 */
wdenk57b2d802003-06-27 21:31:46 +000098.globl _bss_start
99_bss_start:
wdenk927034e2004-02-08 19:38:38 +0000100 .word __bss_start
wdenkcc1e2562003-03-06 13:39:27 +0000101
102.globl _bss_end
103_bss_end:
wdenk927034e2004-02-08 19:38:38 +0000104 .word _end
wdenkcc1e2562003-03-06 13:39:27 +0000105
wdenkc6097192002-11-03 00:24:07 +0000106#ifdef CONFIG_USE_IRQ
107/* IRQ stack memory (calculated at run-time) */
108.globl IRQ_STACK_START
109IRQ_STACK_START:
110 .word 0x0badc0de
111
112/* IRQ stack memory (calculated at run-time) */
113.globl FIQ_STACK_START
114FIQ_STACK_START:
115 .word 0x0badc0de
Marcel Ziswiler00376352007-12-30 03:30:56 +0100116#endif /* CONFIG_USE_IRQ */
wdenkc6097192002-11-03 00:24:07 +0000117
Heiko Schocher3d8f5fa2010-09-17 13:10:46 +0200118#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
119/* IRQ stack memory (calculated at run-time) + 8 bytes */
120.globl IRQ_STACK_START_IN
121IRQ_STACK_START_IN:
122 .word 0x0badc0de
123
124.globl _datarel_start
125_datarel_start:
126 .word __datarel_start
127
128.globl _datarelrolocal_start
129_datarelrolocal_start:
130 .word __datarelrolocal_start
131
132.globl _datarellocal_start
133_datarellocal_start:
134 .word __datarellocal_start
135
136.globl _datarelro_start
137_datarelro_start:
138 .word __datarelro_start
139
140.globl _got_start
141_got_start:
142 .word __got_start
143
144.globl _got_end
145_got_end:
146 .word __got_end
147
148/*
149 * the actual reset code
150 */
151
152reset:
153 /*
154 * set the cpu to SVC32 mode
155 */
156 mrs r0,cpsr
157 bic r0,r0,#0x1f
158 orr r0,r0,#0xd3
159 msr cpsr,r0
160
161 /*
162 * we do sys-critical inits only at reboot,
163 * not when booting from ram!
164 */
165#ifndef CONFIG_SKIP_LOWLEVEL_INIT
166 bl cpu_init_crit
167#endif
168
169/* Set stackpointer in internal RAM to call board_init_f */
170call_board_init_f:
171 ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
172 ldr r0,=0x00000000
173 bl board_init_f
174
175/*------------------------------------------------------------------------------*/
176
177/*
178 * void relocate_code (addr_sp, gd, addr_moni)
179 *
180 * This "function" does not return, instead it continues in RAM
181 * after relocating the monitor code.
182 *
183 */
184 .globl relocate_code
185relocate_code:
186 mov r4, r0 /* save addr_sp */
187 mov r5, r1 /* save addr of gd */
188 mov r6, r2 /* save addr of destination */
189 mov r7, r2 /* save addr of destination */
190
191 /* Set up the stack */
192stack_setup:
193 mov sp, r4
194
195 adr r0, _start
196 ldr r2, _TEXT_BASE
197 ldr r3, _bss_start
198 sub r2, r3, r2 /* r2 <- size of armboot */
199 add r2, r0, r2 /* r2 <- source end address */
200 cmp r0, r6
201 beq clear_bss
202
203#ifndef CONFIG_SKIP_RELOCATE_UBOOT
204copy_loop:
205 ldmia r0!, {r9-r10} /* copy from source address [r0] */
206 stmia r6!, {r9-r10} /* copy to target address [r1] */
Albert Aribaud0668d162010-10-05 16:06:39 +0200207 cmp r0, r2 /* until source end address [r2] */
208 blo copy_loop
Heiko Schocher3d8f5fa2010-09-17 13:10:46 +0200209
210#ifndef CONFIG_PRELOADER
211 /* fix got entries */
212 ldr r1, _TEXT_BASE /* Text base */
213 mov r0, r7 /* reloc addr */
214 ldr r2, _got_start /* addr in Flash */
215 ldr r3, _got_end /* addr in Flash */
216 sub r3, r3, r1
217 add r3, r3, r0
218 sub r2, r2, r1
219 add r2, r2, r0
220
221fixloop:
222 ldr r4, [r2]
223 sub r4, r4, r1
224 add r4, r4, r0
225 str r4, [r2]
226 add r2, r2, #4
227 cmp r2, r3
228 bne fixloop
229#endif
230#endif /* #ifndef CONFIG_SKIP_RELOCATE_UBOOT */
231
232clear_bss:
233#ifndef CONFIG_PRELOADER
234 ldr r0, _bss_start
235 ldr r1, _bss_end
236 ldr r3, _TEXT_BASE /* Text base */
237 mov r4, r7 /* reloc addr */
238 sub r0, r0, r3
239 add r0, r0, r4
240 sub r1, r1, r3
241 add r1, r1, r4
242 mov r2, #0x00000000 /* clear */
243
244clbss_l:str r2, [r0] /* clear loop... */
245 add r0, r0, #4
246 cmp r0, r1
247 bne clbss_l
248#endif
249
250/*
251 * We are done. Do not return, instead branch to second part of board
252 * initialization, now running from RAM.
253 */
254#ifdef CONFIG_ONENAND_IPL
255 ldr pc, _start_oneboot
256
257_start_oneboot: .word start_oneboot
258#else
259 ldr r0, _TEXT_BASE
260 ldr r2, _board_init_r
261 sub r2, r2, r0
262 add r2, r2, r7 /* position from board_init_r in RAM */
263 /* setup parameters for board_init_r */
264 mov r0, r5 /* gd_t */
265 mov r1, r7 /* dest_addr */
266 /* jump to it ... */
267 mov lr, r2
268 mov pc, lr
269
270_board_init_r: .word board_init_r
271#endif
272
273#else /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */
wdenkc6097192002-11-03 00:24:07 +0000274
275/****************************************************************************/
wdenk384ae022002-11-05 00:17:55 +0000276/* */
277/* the actual reset code */
278/* */
wdenkc6097192002-11-03 00:24:07 +0000279/****************************************************************************/
280
281reset:
Marcel Ziswiler00376352007-12-30 03:30:56 +0100282 mrs r0,cpsr /* set the CPU to SVC32 mode */
wdenk384ae022002-11-05 00:17:55 +0000283 bic r0,r0,#0x1f /* (superviser mode, M=10011) */
wdenkc6097192002-11-03 00:24:07 +0000284 orr r0,r0,#0x13
285 msr cpsr,r0
286
wdenkc0aa5c52003-12-06 19:49:23 +0000287 /*
288 * we do sys-critical inits only at reboot,
Marcel Ziswiler00376352007-12-30 03:30:56 +0100289 * not when booting from RAM!
wdenkc0aa5c52003-12-06 19:49:23 +0000290 */
wdenk3d3d99f2005-04-04 12:44:11 +0000291#ifndef CONFIG_SKIP_LOWLEVEL_INIT
wdenk384ae022002-11-05 00:17:55 +0000292 bl cpu_init_crit /* we do sys-critical inits */
Marcel Ziswiler00376352007-12-30 03:30:56 +0100293#endif /* !CONFIG_SKIP_LOWLEVEL_INIT */
wdenkc6097192002-11-03 00:24:07 +0000294
wdenk3d3d99f2005-04-04 12:44:11 +0000295#ifndef CONFIG_SKIP_RELOCATE_UBOOT
wdenk1fe2c702003-03-06 21:55:29 +0000296relocate: /* relocate U-Boot to RAM */
297 adr r0, _start /* r0 <- current position of code */
wdenk57b2d802003-06-27 21:31:46 +0000298 ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
Marek Vasutc13685c2010-07-06 02:48:35 +0200299#ifndef CONFIG_PRELOADER
Wolfgang Denk61ccd1d2006-03-06 23:18:48 +0100300 cmp r0, r1 /* don't reloc during debug */
301 beq stack_setup
Marek Vasutc13685c2010-07-06 02:48:35 +0200302#endif
wdenk1fe2c702003-03-06 21:55:29 +0000303
wdenkc6097192002-11-03 00:24:07 +0000304 ldr r2, _armboot_start
wdenk927034e2004-02-08 19:38:38 +0000305 ldr r3, _bss_start
Wolfgang Denk61ccd1d2006-03-06 23:18:48 +0100306 sub r2, r3, r2 /* r2 <- size of armboot */
307 add r2, r0, r2 /* r2 <- source end address */
wdenkc6097192002-11-03 00:24:07 +0000308
309copy_loop:
310 ldmia r0!, {r3-r10} /* copy from source address [r0] */
311 stmia r1!, {r3-r10} /* copy to target address [r1] */
Marcel Ziswilerf78280f2008-07-09 08:17:06 +0200312 cmp r0, r2 /* until source end address [r2] */
Albert Aribaud0668d162010-10-05 16:06:39 +0200313 blo copy_loop
Marcel Ziswiler00376352007-12-30 03:30:56 +0100314#endif /* !CONFIG_SKIP_RELOCATE_UBOOT */
wdenkc6097192002-11-03 00:24:07 +0000315
wdenk384ae022002-11-05 00:17:55 +0000316 /* Set up the stack */
wdenk1fe2c702003-03-06 21:55:29 +0000317stack_setup:
wdenkc0aa5c52003-12-06 19:49:23 +0000318 ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
Marek Vasutc13685c2010-07-06 02:48:35 +0200319#ifdef CONFIG_PRELOADER
320 sub sp, r0, #128 /* leave 32 words for abort-stack */
321#else
322 sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */
323 sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */
wdenkc0aa5c52003-12-06 19:49:23 +0000324#ifdef CONFIG_USE_IRQ
325 sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
Marcel Ziswiler00376352007-12-30 03:30:56 +0100326#endif /* CONFIG_USE_IRQ */
Vitaly Kuzmichev9c2cec42010-06-15 22:18:11 +0400327 sub sp, r0, #12 /* leave 3 words for abort-stack */
328 bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
Marek Vasutc13685c2010-07-06 02:48:35 +0200329#endif
wdenkcc1e2562003-03-06 13:39:27 +0000330
331clear_bss:
Wolfgang Denk61ccd1d2006-03-06 23:18:48 +0100332 ldr r0, _bss_start /* find start of bss segment */
333 ldr r1, _bss_end /* stop here */
334 mov r2, #0x00000000 /* clear */
wdenkcc1e2562003-03-06 13:39:27 +0000335
Marek Vasutc13685c2010-07-06 02:48:35 +0200336#ifndef CONFIG_PRELOADER
Wolfgang Denk61ccd1d2006-03-06 23:18:48 +0100337clbss_l:str r2, [r0] /* clear loop... */
wdenkcc1e2562003-03-06 13:39:27 +0000338 add r0, r0, #4
339 cmp r0, r1
Albert Aribaud0668d162010-10-05 16:06:39 +0200340 blo clbss_l
Marek Vasutc13685c2010-07-06 02:48:35 +0200341#endif
wdenkcc1e2562003-03-06 13:39:27 +0000342
wdenkc6097192002-11-03 00:24:07 +0000343 ldr pc, _start_armboot
344
Marek Vasutc13685c2010-07-06 02:48:35 +0200345#ifdef CONFIG_ONENAND_IPL
346_start_armboot: .word start_oneboot
347#else
wdenk384ae022002-11-05 00:17:55 +0000348_start_armboot: .word start_armboot
Marek Vasutc13685c2010-07-06 02:48:35 +0200349#endif
Heiko Schocher3d8f5fa2010-09-17 13:10:46 +0200350#endif /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */
wdenkc6097192002-11-03 00:24:07 +0000351
352/****************************************************************************/
wdenk384ae022002-11-05 00:17:55 +0000353/* */
354/* CPU_init_critical registers */
355/* */
356/* - setup important registers */
357/* - setup memory timing */
358/* */
wdenkc6097192002-11-03 00:24:07 +0000359/****************************************************************************/
Markus Klotzbücher27eba142006-03-06 15:04:25 +0100360/* mk@tbd: Fix this! */
Jean-Christophe PLAGNIOL-VILLARD58136172008-05-01 02:13:44 +0200361#undef RCSR
Markus Klotzbücher27eba142006-03-06 15:04:25 +0100362#undef ICMR
363#undef OSMR3
364#undef OSCR
365#undef OWER
366#undef OIER
Marcel Ziswiler53761bc2007-10-19 00:25:33 +0200367#undef CCCR
wdenkc6097192002-11-03 00:24:07 +0000368
Wolfgang Denk61ccd1d2006-03-06 23:18:48 +0100369/* Interrupt-Controller base address */
wdenkc6097192002-11-03 00:24:07 +0000370IC_BASE: .word 0x40d00000
371#define ICMR 0x04
372
373/* Reset-Controller */
wdenk384ae022002-11-05 00:17:55 +0000374RST_BASE: .word 0x40f00030
wdenkc6097192002-11-03 00:24:07 +0000375#define RCSR 0x00
376
wdenk1fe2c702003-03-06 21:55:29 +0000377/* Operating System Timer */
wdenk384ae022002-11-05 00:17:55 +0000378OSTIMER_BASE: .word 0x40a00000
379#define OSMR3 0x0C
380#define OSCR 0x10
381#define OWER 0x18
382#define OIER 0x1C
wdenkc6097192002-11-03 00:24:07 +0000383
Wolfgang Denk61ccd1d2006-03-06 23:18:48 +0100384/* Clock Manager Registers */
Markus Klotzbuecher121db762006-03-24 14:35:25 +0100385#ifdef CONFIG_CPU_MONAHANS
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200386# ifndef CONFIG_SYS_MONAHANS_RUN_MODE_OSC_RATIO
387# error "You have to define CONFIG_SYS_MONAHANS_RUN_MODE_OSC_RATIO!!"
388# endif /* !CONFIG_SYS_MONAHANS_RUN_MODE_OSC_RATIO */
389# ifndef CONFIG_SYS_MONAHANS_TURBO_RUN_MODE_RATIO
390# define CONFIG_SYS_MONAHANS_TURBO_RUN_MODE_RATIO 0x1
391# endif /* !CONFIG_SYS_MONAHANS_TURBO_RUN_MODE_RATIO */
Marcel Ziswiler00376352007-12-30 03:30:56 +0100392#else /* !CONFIG_CPU_MONAHANS */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200393#ifdef CONFIG_SYS_CPUSPEED
wdenk384ae022002-11-05 00:17:55 +0000394CC_BASE: .word 0x41300000
395#define CCCR 0x00
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200396cpuspeed: .word CONFIG_SYS_CPUSPEED
397#else /* !CONFIG_SYS_CPUSPEED */
398#error "You have to define CONFIG_SYS_CPUSPEED!!"
399#endif /* CONFIG_SYS_CPUSPEED */
Markus Klotzbuecher121db762006-03-24 14:35:25 +0100400#endif /* CONFIG_CPU_MONAHANS */
wdenk1fe2c702003-03-06 21:55:29 +0000401
Markus Klotzbücher21e69a02006-02-07 20:04:48 +0100402 /* takes care the CP15 update has taken place */
403 .macro CPWAIT reg
404 mrc p15,0,\reg,c2,c0,0
405 mov \reg,\reg
wdenkc6097192002-11-03 00:24:07 +0000406 sub pc,pc,#4
407 .endm
408
wdenkc6097192002-11-03 00:24:07 +0000409cpu_init_crit:
410
wdenk384ae022002-11-05 00:17:55 +0000411 /* mask all IRQs */
Markus Klotzbücher21e69a02006-02-07 20:04:48 +0100412#ifndef CONFIG_CPU_MONAHANS
wdenkc6097192002-11-03 00:24:07 +0000413 ldr r0, IC_BASE
414 mov r1, #0x00
415 str r1, [r0, #ICMR]
Marcel Ziswiler00376352007-12-30 03:30:56 +0100416#else /* CONFIG_CPU_MONAHANS */
Markus Klotzbücher21e69a02006-02-07 20:04:48 +0100417 /* Step 1 - Enable CP6 permission */
Wolfgang Denk61ccd1d2006-03-06 23:18:48 +0100418 mrc p15, 0, r1, c15, c1, 0 @ read CPAR
419 orr r1, r1, #0x40
420 mcr p15, 0, r1, c15, c1, 0
421 CPWAIT r1
wdenkc6097192002-11-03 00:24:07 +0000422
Wolfgang Denk61ccd1d2006-03-06 23:18:48 +0100423 /* Step 2 - Mask ICMR & ICMR2 */
424 mov r1, #0
425 mcr p6, 0, r1, c1, c0, 0 @ ICMR
426 mcr p6, 0, r1, c7, c0, 0 @ ICMR2
Markus Klotzbücherd5dfcf92006-02-28 23:11:07 +0100427
428 /* turn off all clocks but the ones we will definitly require */
Wolfgang Denk61ccd1d2006-03-06 23:18:48 +0100429 ldr r1, =CKENA
430 ldr r2, =(CKENA_22_FFUART | CKENA_10_SRAM | CKENA_9_SMC | CKENA_8_DMC)
431 str r2, [r1]
432 ldr r1, =CKENB
433 ldr r2, =(CKENB_6_IRQ)
434 str r2, [r1]
Marcel Ziswiler00376352007-12-30 03:30:56 +0100435#endif /* !CONFIG_CPU_MONAHANS */
wdenk1fe2c702003-03-06 21:55:29 +0000436
Markus Klotzbuecher121db762006-03-24 14:35:25 +0100437 /* set clock speed */
438#ifdef CONFIG_CPU_MONAHANS
439 ldr r0, =ACCR
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200440 ldr r1, =(((CONFIG_SYS_MONAHANS_TURBO_RUN_MODE_RATIO<<8) & ACCR_XN_MASK) | (CONFIG_SYS_MONAHANS_RUN_MODE_OSC_RATIO & ACCR_XL_MASK))
Markus Klotzbuecher121db762006-03-24 14:35:25 +0100441 str r1, [r0]
Marcel Ziswiler00376352007-12-30 03:30:56 +0100442#else /* !CONFIG_CPU_MONAHANS */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200443#ifdef CONFIG_SYS_CPUSPEED
wdenkc6097192002-11-03 00:24:07 +0000444 ldr r0, CC_BASE
445 ldr r1, cpuspeed
446 str r1, [r0, #CCCR]
wdenk1fe2c702003-03-06 21:55:29 +0000447 mov r0, #2
wdenk1272e232002-11-10 22:06:23 +0000448 mcr p14, 0, r0, c6, c0, 0
wdenk1fe2c702003-03-06 21:55:29 +0000449
450setspeed_done:
Wolfgang Denk61ccd1d2006-03-06 23:18:48 +0100451
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200452#endif /* CONFIG_SYS_CPUSPEED */
Markus Klotzbücher21e69a02006-02-07 20:04:48 +0100453#endif /* CONFIG_CPU_MONAHANS */
wdenkc6097192002-11-03 00:24:07 +0000454
455 /*
456 * before relocating, we have to setup RAM timing
457 * because memory timing is board-dependend, you will
wdenk336b2bc2005-04-02 23:52:25 +0000458 * find a lowlevel_init.S in your board directory.
wdenkc6097192002-11-03 00:24:07 +0000459 */
460 mov ip, lr
wdenk336b2bc2005-04-02 23:52:25 +0000461 bl lowlevel_init
wdenkc6097192002-11-03 00:24:07 +0000462 mov lr, ip
463
464 /* Memory interfaces are working. Disable MMU and enable I-cache. */
Wolfgang Denk61ccd1d2006-03-06 23:18:48 +0100465 /* mk: hmm, this is not in the monahans docs, leave it now but
Markus Klotzbücher21e69a02006-02-07 20:04:48 +0100466 * check here if it doesn't work :-) */
wdenkc6097192002-11-03 00:24:07 +0000467
wdenk384ae022002-11-05 00:17:55 +0000468 ldr r0, =0x2001 /* enable access to all coproc. */
wdenkc6097192002-11-03 00:24:07 +0000469 mcr p15, 0, r0, c15, c1, 0
Markus Klotzbücher21e69a02006-02-07 20:04:48 +0100470 CPWAIT r0
wdenkc6097192002-11-03 00:24:07 +0000471
472 mcr p15, 0, r0, c7, c10, 4 /* drain the write & fill buffers */
Markus Klotzbücher21e69a02006-02-07 20:04:48 +0100473 CPWAIT r0
wdenkc6097192002-11-03 00:24:07 +0000474
wdenk384ae022002-11-05 00:17:55 +0000475 mcr p15, 0, r0, c7, c7, 0 /* flush Icache, Dcache and BTB */
Markus Klotzbücher21e69a02006-02-07 20:04:48 +0100476 CPWAIT r0
wdenkc6097192002-11-03 00:24:07 +0000477
478 mcr p15, 0, r0, c8, c7, 0 /* flush instuction and data TLBs */
Markus Klotzbücher21e69a02006-02-07 20:04:48 +0100479 CPWAIT r0
wdenkc6097192002-11-03 00:24:07 +0000480
wdenk384ae022002-11-05 00:17:55 +0000481 /* Enable the Icache */
wdenkc6097192002-11-03 00:24:07 +0000482/*
483 mrc p15, 0, r0, c1, c0, 0
484 orr r0, r0, #0x1800
485 mcr p15, 0, r0, c1, c0, 0
wdenk699b13a2002-11-03 18:03:52 +0000486 CPWAIT
wdenkc6097192002-11-03 00:24:07 +0000487*/
488 mov pc, lr
489
Marek Vasutc13685c2010-07-06 02:48:35 +0200490#ifndef CONFIG_PRELOADER
wdenkc6097192002-11-03 00:24:07 +0000491/****************************************************************************/
wdenk384ae022002-11-05 00:17:55 +0000492/* */
493/* Interrupt handling */
494/* */
wdenkc6097192002-11-03 00:24:07 +0000495/****************************************************************************/
496
wdenk384ae022002-11-05 00:17:55 +0000497/* IRQ stack frame */
wdenkc6097192002-11-03 00:24:07 +0000498
499#define S_FRAME_SIZE 72
500
501#define S_OLD_R0 68
502#define S_PSR 64
503#define S_PC 60
504#define S_LR 56
505#define S_SP 52
506
507#define S_IP 48
508#define S_FP 44
509#define S_R10 40
510#define S_R9 36
511#define S_R8 32
512#define S_R7 28
513#define S_R6 24
514#define S_R5 20
515#define S_R4 16
516#define S_R3 12
517#define S_R2 8
518#define S_R1 4
519#define S_R0 0
520
521#define MODE_SVC 0x13
522
wdenk384ae022002-11-05 00:17:55 +0000523 /* use bad_save_user_regs for abort/prefetch/undef/swi ... */
wdenkc6097192002-11-03 00:24:07 +0000524
525 .macro bad_save_user_regs
526 sub sp, sp, #S_FRAME_SIZE
wdenk384ae022002-11-05 00:17:55 +0000527 stmia sp, {r0 - r12} /* Calling r0-r12 */
528 add r8, sp, #S_PC
wdenkc6097192002-11-03 00:24:07 +0000529
Heiko Schocher3d8f5fa2010-09-17 13:10:46 +0200530#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
wdenk927034e2004-02-08 19:38:38 +0000531 ldr r2, _armboot_start
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200532 sub r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN)
533 sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ set base 2 words into abort stack
Heiko Schocher3d8f5fa2010-09-17 13:10:46 +0200534#else
535 ldr r2, IRQ_STACK_START_IN
536#endif
wdenk384ae022002-11-05 00:17:55 +0000537 ldmia r2, {r2 - r4} /* get pc, cpsr, old_r0 */
538 add r0, sp, #S_FRAME_SIZE /* restore sp_SVC */
wdenkc6097192002-11-03 00:24:07 +0000539
540 add r5, sp, #S_SP
541 mov r1, lr
wdenk384ae022002-11-05 00:17:55 +0000542 stmia r5, {r0 - r4} /* save sp_SVC, lr_SVC, pc, cpsr, old_r */
wdenkc6097192002-11-03 00:24:07 +0000543 mov r0, sp
544 .endm
545
546
wdenk384ae022002-11-05 00:17:55 +0000547 /* use irq_save_user_regs / irq_restore_user_regs for */
548 /* IRQ/FIQ handling */
wdenkc6097192002-11-03 00:24:07 +0000549
550 .macro irq_save_user_regs
551 sub sp, sp, #S_FRAME_SIZE
wdenk384ae022002-11-05 00:17:55 +0000552 stmia sp, {r0 - r12} /* Calling r0-r12 */
553 add r8, sp, #S_PC
554 stmdb r8, {sp, lr}^ /* Calling SP, LR */
555 str lr, [r8, #0] /* Save calling PC */
556 mrs r6, spsr
557 str r6, [r8, #4] /* Save CPSR */
558 str r0, [r8, #8] /* Save OLD_R0 */
wdenkc6097192002-11-03 00:24:07 +0000559 mov r0, sp
560 .endm
561
562 .macro irq_restore_user_regs
563 ldmia sp, {r0 - lr}^ @ Calling r0 - lr
564 mov r0, r0
565 ldr lr, [sp, #S_PC] @ Get PC
566 add sp, sp, #S_FRAME_SIZE
567 subs pc, lr, #4 @ return & move spsr_svc into cpsr
568 .endm
569
570 .macro get_bad_stack
Heiko Schocher3d8f5fa2010-09-17 13:10:46 +0200571#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
wdenk927034e2004-02-08 19:38:38 +0000572 ldr r13, _armboot_start @ setup our mode stack
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200573 sub r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN)
574 sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack
Heiko Schocher3d8f5fa2010-09-17 13:10:46 +0200575#else
576 ldr r13, IRQ_STACK_START_IN @ setup our mode stack
577#endif
wdenkc6097192002-11-03 00:24:07 +0000578
579 str lr, [r13] @ save caller lr / spsr
580 mrs lr, spsr
wdenk384ae022002-11-05 00:17:55 +0000581 str lr, [r13, #4]
wdenkc6097192002-11-03 00:24:07 +0000582
583 mov r13, #MODE_SVC @ prepare SVC-Mode
584 msr spsr_c, r13
585 mov lr, pc
586 movs pc, lr
587 .endm
588
589 .macro get_irq_stack @ setup IRQ stack
590 ldr sp, IRQ_STACK_START
591 .endm
592
593 .macro get_fiq_stack @ setup FIQ stack
594 ldr sp, FIQ_STACK_START
595 .endm
Marek Vasutc13685c2010-07-06 02:48:35 +0200596#endif /* CONFIG_PRELOADER */
wdenkc6097192002-11-03 00:24:07 +0000597
598
599/****************************************************************************/
wdenk384ae022002-11-05 00:17:55 +0000600/* */
601/* exception handlers */
602/* */
wdenkc6097192002-11-03 00:24:07 +0000603/****************************************************************************/
604
Marek Vasutc13685c2010-07-06 02:48:35 +0200605#ifdef CONFIG_PRELOADER
606 .align 5
607do_hang:
608 ldr sp, _TEXT_BASE /* use 32 words abort stack */
609 bl hang /* hang and never return */
610#else /* !CONFIG_PRELOADER */
wdenk384ae022002-11-05 00:17:55 +0000611 .align 5
wdenkc6097192002-11-03 00:24:07 +0000612undefined_instruction:
613 get_bad_stack
614 bad_save_user_regs
wdenk384ae022002-11-05 00:17:55 +0000615 bl do_undefined_instruction
wdenkc6097192002-11-03 00:24:07 +0000616
617 .align 5
618software_interrupt:
619 get_bad_stack
620 bad_save_user_regs
wdenk384ae022002-11-05 00:17:55 +0000621 bl do_software_interrupt
wdenkc6097192002-11-03 00:24:07 +0000622
623 .align 5
624prefetch_abort:
625 get_bad_stack
626 bad_save_user_regs
wdenk384ae022002-11-05 00:17:55 +0000627 bl do_prefetch_abort
wdenkc6097192002-11-03 00:24:07 +0000628
629 .align 5
630data_abort:
631 get_bad_stack
632 bad_save_user_regs
wdenk384ae022002-11-05 00:17:55 +0000633 bl do_data_abort
wdenkc6097192002-11-03 00:24:07 +0000634
635 .align 5
636not_used:
637 get_bad_stack
638 bad_save_user_regs
wdenk384ae022002-11-05 00:17:55 +0000639 bl do_not_used
wdenkc6097192002-11-03 00:24:07 +0000640
641#ifdef CONFIG_USE_IRQ
642
643 .align 5
644irq:
645 get_irq_stack
646 irq_save_user_regs
wdenk384ae022002-11-05 00:17:55 +0000647 bl do_irq
wdenkc6097192002-11-03 00:24:07 +0000648 irq_restore_user_regs
649
650 .align 5
651fiq:
652 get_fiq_stack
653 irq_save_user_regs /* someone ought to write a more */
wdenk384ae022002-11-05 00:17:55 +0000654 bl do_fiq /* effiction fiq_save_user_regs */
wdenkc6097192002-11-03 00:24:07 +0000655 irq_restore_user_regs
656
Marcel Ziswiler00376352007-12-30 03:30:56 +0100657#else /* !CONFIG_USE_IRQ */
wdenkc6097192002-11-03 00:24:07 +0000658
659 .align 5
660irq:
661 get_bad_stack
662 bad_save_user_regs
wdenk384ae022002-11-05 00:17:55 +0000663 bl do_irq
wdenkc6097192002-11-03 00:24:07 +0000664
665 .align 5
666fiq:
667 get_bad_stack
668 bad_save_user_regs
wdenk384ae022002-11-05 00:17:55 +0000669 bl do_fiq
Marek Vasutc13685c2010-07-06 02:48:35 +0200670#endif /* CONFIG_PRELOADER */
Marcel Ziswiler00376352007-12-30 03:30:56 +0100671#endif /* CONFIG_USE_IRQ */
wdenkc6097192002-11-03 00:24:07 +0000672
wdenk1fe2c702003-03-06 21:55:29 +0000673/****************************************************************************/
Wolfgang Denk61ccd1d2006-03-06 23:18:48 +0100674/* */
wdenk1fe2c702003-03-06 21:55:29 +0000675/* Reset function: the PXA250 doesn't have a reset function, so we have to */
Wolfgang Denk61ccd1d2006-03-06 23:18:48 +0100676/* perform a watchdog timeout for a soft reset. */
677/* */
wdenk1fe2c702003-03-06 21:55:29 +0000678/****************************************************************************/
679
wdenkc6097192002-11-03 00:24:07 +0000680 .align 5
681.globl reset_cpu
wdenk1fe2c702003-03-06 21:55:29 +0000682
Wolfgang Denk61ccd1d2006-03-06 23:18:48 +0100683 /* FIXME: this code is PXA250 specific. How is this handled on */
684 /* other XScale processors? */
wdenk1fe2c702003-03-06 21:55:29 +0000685
wdenkc6097192002-11-03 00:24:07 +0000686reset_cpu:
wdenk1fe2c702003-03-06 21:55:29 +0000687
wdenk384ae022002-11-05 00:17:55 +0000688 /* We set OWE:WME (watchdog enable) and wait until timeout happens */
689
690 ldr r0, OSTIMER_BASE
691 ldr r1, [r0, #OWER]
Wolfgang Denk61ccd1d2006-03-06 23:18:48 +0100692 orr r1, r1, #0x0001 /* bit0: WME */
wdenk384ae022002-11-05 00:17:55 +0000693 str r1, [r0, #OWER]
694
695 /* OS timer does only wrap every 1165 seconds, so we have to set */
Wolfgang Denk61ccd1d2006-03-06 23:18:48 +0100696 /* the match register as well. */
wdenk384ae022002-11-05 00:17:55 +0000697
Wolfgang Denk61ccd1d2006-03-06 23:18:48 +0100698 ldr r1, [r0, #OSCR] /* read OS timer */
wdenk384ae022002-11-05 00:17:55 +0000699 add r1, r1, #0x800 /* let OSMR3 match after */
700 add r1, r1, #0x800 /* 4096*(1/3.6864MHz)=1ms */
701 str r1, [r0, #OSMR3]
702
703reset_endless:
wdenkc6097192002-11-03 00:24:07 +0000704
wdenk384ae022002-11-05 00:17:55 +0000705 b reset_endless