blob: ab8c2b73d8933737f67000119ee4f3412aa5a346 [file] [log] [blame]
Wolfgang Denk72a087e2006-10-24 14:27:35 +02001/*
2 * Copyright (C) 2005-2006 Atmel Corporation
3 *
4 * See file CREDITS for list of people who contributed to this
5 * project.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20 * MA 02111-1307 USA
21 */
22#include <config.h>
23#include <asm/sysreg.h>
24
25#ifndef PART_SPECIFIC_BOOTSTRAP
26# define PART_SPECIFIC_BOOTSTRAP
27#endif
28
29#define SYSREG_MMUCR_I_OFFSET 2
30#define SYSREG_MMUCR_S_OFFSET 4
31
32#define SR_INIT (SYSREG_BIT(GM) | SYSREG_BIT(EM) | SYSREG_BIT(M0))
33#define CPUCR_INIT (SYSREG_BIT(BI) | SYSREG_BIT(BE) \
34 | SYSREG_BIT(FE) | SYSREG_BIT(RE) \
35 | SYSREG_BIT(IBE) | SYSREG_BIT(IEE))
36
37 .text
38 .global _start
39_start:
40 PART_SPECIFIC_BOOTSTRAP
41
42 /* Reset the Status Register */
43 mov r0, lo(SR_INIT)
44 orh r0, hi(SR_INIT)
45 mtsr SYSREG_SR, r0
46
47 /* Reset CPUCR and invalidate the BTB */
48 mov r2, CPUCR_INIT
49 mtsr SYSREG_CPUCR, r2
50
51 /* Flush the caches */
52 mov r1, 0
53 cache r1[4], 8
54 cache r1[0], 0
55 sync 0
56
57 /* Reset the MMU to default settings */
58 mov r0, SYSREG_BIT(MMUCR_S) | SYSREG_BIT(MMUCR_I)
59 mtsr SYSREG_MMUCR, r0
60
61 /* Internal RAM should not need any initialization. We might
62 have to initialize external RAM here if the part doesn't
63 have internal RAM (or we may use the data cache) */
64
65 /* Jump to cacheable segment */
66 lddpc pc, 1f
67
68 .align 2
691: .long 2f
70
712: lddpc sp, sp_init
72
Wolfgang Denk72a087e2006-10-24 14:27:35 +020073 /* Initialize the GOT pointer */
74 lddpc r6, got_init
753: rsub r6, pc
Haavard Skinnemoen1f4f2122006-11-20 15:53:10 +010076
77 /* Let's go */
78 rjmp board_init_f
Wolfgang Denk72a087e2006-10-24 14:27:35 +020079
80 .align 2
81 .type sp_init,@object
82sp_init:
83 .long CFG_INIT_SP_ADDR
84got_init:
85 .long 3b - _GLOBAL_OFFSET_TABLE_
Haavard Skinnemoen1f4f2122006-11-20 15:53:10 +010086
87 /*
88 * void relocate_code(new_sp, new_gd, monitor_addr)
89 *
90 * Relocate the u-boot image into RAM and continue from there.
91 * Does not return.
92 */
93 .global relocate_code
94 .type relocate_code,@function
95relocate_code:
96 mov sp, r12 /* use new stack */
97 mov r12, r11 /* save new_gd */
98 mov r11, r10 /* save destination address */
99
100 /* copy .text section and flush the cache along the way */
101 lda.w r8, _text
102 lda.w r9, _etext
103 sub lr, r10, r8 /* relocation offset */
104
1051: ldm r8++, r0-r3
106 stm r10, r0-r3
107 sub r10, -16
108 ldm r8++, r0-r3
109 stm r10, r0-r3
110 sub r10, -16
111 cp.w r8, r9
112 cache r10[-4], 0x0d /* dcache clean/invalidate */
113 cache r10[-4], 0x01 /* icache invalidate */
114 brlt 1b
115
116 /* flush write buffer */
117 sync 0
118
119 /* copy data sections */
120 lda.w r9, _edata
1211: ld.d r0, r8++
122 st.d r10++, r0
123 cp.w r8, r9
124 brlt 1b
125
126 /* zero out .bss */
127 mov r0, 0
128 mov r1, 0
129 lda.w r9, _end
130 sub r9, r8
1311: st.d r10++, r0
132 sub r9, 8
133 brgt 1b
134
135 /* jump to RAM */
136 sub r0, pc, . - in_ram
137 add pc, r0, lr
138
139 .align 2
140in_ram:
141 /* find the new GOT and relocate it */
142 lddpc r6, got_init_reloc
1433: rsub r6, pc
144 mov r8, r6
145 lda.w r9, _egot
146 lda.w r10, _got
147 sub r9, r10
1481: ld.w r0, r8[0]
149 add r0, lr
150 st.w r8++, r0
151 sub r9, 4
152 brgt 1b
153
154 /* Move the exception handlers */
155 mfsr r2, SYSREG_EVBA
156 add r2, lr
157 mtsr SYSREG_EVBA, r2
158
159 /* Do the rest of the initialization sequence */
160 call board_init_r
161
162 .align 2
163got_init_reloc:
164 .long 3b - _GLOBAL_OFFSET_TABLE_