]>
Commit | Line | Data |
---|---|---|
074cff0d WD |
1 | /* |
2 | * Startup Code for S3C44B0 CPU-core | |
3 | * | |
4 | * (C) Copyright 2004 | |
5 | * DAVE Srl | |
6 | * | |
7 | * http://www.dave-tech.it | |
8 | * http://www.wawnet.biz | |
9 | * mailto:info@wawnet.biz | |
10 | * | |
11 | * See file CREDITS for list of people who contributed to this | |
12 | * project. | |
13 | * | |
14 | * This program is free software; you can redistribute it and/or | |
15 | * modify it under the terms of the GNU General Public License as | |
16 | * published by the Free Software Foundation; either version 2 of | |
17 | * the License, or (at your option) any later version. | |
18 | * | |
19 | * This program is distributed in the hope that it will be useful, | |
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
22 | * GNU General Public License for more details. | |
23 | * | |
24 | * You should have received a copy of the GNU General Public License | |
25 | * along with this program; if not, write to the Free Software | |
26 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
27 | * MA 02111-1307 USA | |
28 | */ | |
29 | ||
25ddd1fb | 30 | #include <asm-offsets.h> |
074cff0d WD |
31 | #include <config.h> |
32 | #include <version.h> | |
33 | ||
074cff0d WD |
34 | /* |
35 | * Jump vector table | |
36 | */ | |
37 | ||
38 | ||
39 | .globl _start | |
40 | _start: b reset | |
41 | add pc, pc, #0x0c000000 | |
42 | add pc, pc, #0x0c000000 | |
43 | add pc, pc, #0x0c000000 | |
44 | add pc, pc, #0x0c000000 | |
45 | add pc, pc, #0x0c000000 | |
46 | add pc, pc, #0x0c000000 | |
47 | add pc, pc, #0x0c000000 | |
48 | ||
49 | .balignl 16,0xdeadbeef | |
50 | ||
51 | ||
52 | /* | |
53 | ************************************************************************* | |
54 | * | |
55 | * Startup Code (reset vector) | |
56 | * | |
57 | * do important init only if we don't start from memory! | |
58 | * relocate u-boot to ram | |
59 | * setup stack | |
60 | * jump to second stage | |
61 | * | |
62 | ************************************************************************* | |
63 | */ | |
64 | ||
0110955a | 65 | .globl _TEXT_BASE |
074cff0d | 66 | _TEXT_BASE: |
14d0a02a | 67 | .word CONFIG_SYS_TEXT_BASE |
074cff0d | 68 | |
074cff0d | 69 | /* |
42dfe7a1 | 70 | * These are defined in the board-specific linker script. |
074cff0d | 71 | */ |
42dfe7a1 WD |
72 | .globl _bss_start |
73 | _bss_start: | |
74 | .word __bss_start | |
75 | ||
76 | .globl _bss_end | |
77 | _bss_end: | |
78 | .word _end | |
074cff0d WD |
79 | |
80 | #ifdef CONFIG_USE_IRQ | |
81 | /* IRQ stack memory (calculated at run-time) */ | |
82 | .globl IRQ_STACK_START | |
83 | IRQ_STACK_START: | |
84 | .word 0x0badc0de | |
85 | ||
86 | /* IRQ stack memory (calculated at run-time) */ | |
87 | .globl FIQ_STACK_START | |
88 | FIQ_STACK_START: | |
89 | .word 0x0badc0de | |
90 | #endif | |
91 | ||
0110955a HS |
92 | /* IRQ stack memory (calculated at run-time) + 8 bytes */ |
93 | .globl IRQ_STACK_START_IN | |
94 | IRQ_STACK_START_IN: | |
95 | .word 0x0badc0de | |
96 | ||
97 | .globl _datarel_start | |
98 | _datarel_start: | |
99 | .word __datarel_start | |
100 | ||
101 | .globl _datarelrolocal_start | |
102 | _datarelrolocal_start: | |
103 | .word __datarelrolocal_start | |
104 | ||
105 | .globl _datarellocal_start | |
106 | _datarellocal_start: | |
107 | .word __datarellocal_start | |
108 | ||
109 | .globl _datarelro_start | |
110 | _datarelro_start: | |
111 | .word __datarelro_start | |
112 | ||
113 | .globl _got_start | |
114 | _got_start: | |
115 | .word __got_start | |
116 | ||
117 | .globl _got_end | |
118 | _got_end: | |
119 | .word __got_end | |
120 | ||
121 | /* | |
122 | * the actual reset code | |
123 | */ | |
124 | ||
125 | reset: | |
126 | /* | |
127 | * set the cpu to SVC32 mode | |
128 | */ | |
129 | mrs r0,cpsr | |
130 | bic r0,r0,#0x1f | |
131 | orr r0,r0,#0xd3 | |
132 | msr cpsr,r0 | |
133 | ||
134 | /* | |
135 | * we do sys-critical inits only at reboot, | |
136 | * not when booting from ram! | |
137 | */ | |
138 | #ifndef CONFIG_SKIP_LOWLEVEL_INIT | |
139 | bl cpu_init_crit | |
140 | /* | |
141 | * before relocating, we have to setup RAM timing | |
142 | * because memory timing is board-dependend, you will | |
143 | * find a lowlevel_init.S in your board directory. | |
144 | */ | |
145 | bl lowlevel_init | |
146 | #endif | |
147 | ||
148 | /* Set stackpointer in internal RAM to call board_init_f */ | |
149 | call_board_init_f: | |
150 | ldr sp, =(CONFIG_SYS_INIT_SP_ADDR) | |
151 | ldr r0,=0x00000000 | |
152 | bl board_init_f | |
153 | ||
154 | /*------------------------------------------------------------------------------*/ | |
155 | ||
156 | /* | |
157 | * void relocate_code (addr_sp, gd, addr_moni) | |
158 | * | |
159 | * This "function" does not return, instead it continues in RAM | |
160 | * after relocating the monitor code. | |
161 | * | |
162 | */ | |
163 | .globl relocate_code | |
164 | relocate_code: | |
165 | mov r4, r0 /* save addr_sp */ | |
166 | mov r5, r1 /* save addr of gd */ | |
167 | mov r6, r2 /* save addr of destination */ | |
168 | mov r7, r2 /* save addr of destination */ | |
169 | ||
170 | /* Set up the stack */ | |
171 | stack_setup: | |
172 | mov sp, r4 | |
173 | ||
174 | adr r0, _start | |
175 | ldr r2, _TEXT_BASE | |
176 | ldr r3, _bss_start | |
177 | sub r2, r3, r2 /* r2 <- size of armboot */ | |
178 | add r2, r0, r2 /* r2 <- source end address */ | |
179 | cmp r0, r6 | |
180 | beq clear_bss | |
181 | ||
182 | #ifndef CONFIG_SKIP_RELOCATE_UBOOT | |
183 | copy_loop: | |
184 | ldmia r0!, {r9-r10} /* copy from source address [r0] */ | |
185 | stmia r6!, {r9-r10} /* copy to target address [r1] */ | |
da90d4ce AA |
186 | cmp r0, r2 /* until source end address [r2] */ |
187 | blo copy_loop | |
0110955a HS |
188 | |
189 | #ifndef CONFIG_PRELOADER | |
190 | /* fix got entries */ | |
191 | ldr r1, _TEXT_BASE /* Text base */ | |
192 | mov r0, r7 /* reloc addr */ | |
193 | ldr r2, _got_start /* addr in Flash */ | |
194 | ldr r3, _got_end /* addr in Flash */ | |
195 | sub r3, r3, r1 | |
196 | add r3, r3, r0 | |
197 | sub r2, r2, r1 | |
198 | add r2, r2, r0 | |
199 | ||
200 | fixloop: | |
201 | ldr r4, [r2] | |
202 | sub r4, r4, r1 | |
203 | add r4, r4, r0 | |
204 | str r4, [r2] | |
205 | add r2, r2, #4 | |
206 | cmp r2, r3 | |
79e63139 | 207 | blo fixloop |
0110955a HS |
208 | #endif |
209 | /* | |
210 | now copy to sram the interrupt vector | |
211 | */ | |
212 | adr r0, real_vectors | |
213 | add r2, r0, #1024 | |
214 | ldr r1, =0x0c000000 | |
215 | add r1, r1, #0x08 | |
216 | vector_copy_loop: | |
217 | ldmia r0!, {r3-r10} | |
218 | stmia r1!, {r3-r10} | |
219 | cmp r0, r2 | |
da90d4ce | 220 | blo vector_copy_loop |
0110955a HS |
221 | #endif /* #ifndef CONFIG_SKIP_RELOCATE_UBOOT */ |
222 | ||
223 | clear_bss: | |
224 | #ifndef CONFIG_PRELOADER | |
225 | ldr r0, _bss_start | |
226 | ldr r1, _bss_end | |
227 | ldr r3, _TEXT_BASE /* Text base */ | |
228 | mov r4, r7 /* reloc addr */ | |
229 | sub r0, r0, r3 | |
230 | add r0, r0, r4 | |
231 | sub r1, r1, r3 | |
232 | add r1, r1, r4 | |
233 | mov r2, #0x00000000 /* clear */ | |
234 | ||
235 | clbss_l:str r2, [r0] /* clear loop... */ | |
236 | add r0, r0, #4 | |
237 | cmp r0, r1 | |
238 | bne clbss_l | |
239 | ||
240 | bl coloured_LED_init | |
241 | bl red_LED_on | |
242 | #endif | |
074cff0d | 243 | |
0110955a HS |
244 | /* |
245 | * We are done. Do not return, instead branch to second part of board | |
246 | * initialization, now running from RAM. | |
247 | */ | |
248 | ldr r0, _TEXT_BASE | |
249 | ldr r2, _board_init_r | |
250 | sub r2, r2, r0 | |
251 | add r2, r2, r7 /* position from board_init_r in RAM */ | |
252 | /* setup parameters for board_init_r */ | |
253 | mov r0, r5 /* gd_t */ | |
254 | mov r1, r7 /* dest_addr */ | |
255 | /* jump to it ... */ | |
256 | mov lr, r2 | |
257 | mov pc, lr | |
258 | ||
259 | _board_init_r: .word board_init_r | |
260 | ||
074cff0d WD |
261 | /* |
262 | ************************************************************************* | |
263 | * | |
264 | * CPU_init_critical registers | |
265 | * | |
266 | * setup important registers | |
267 | * setup memory timing | |
268 | * | |
269 | ************************************************************************* | |
270 | */ | |
271 | ||
272 | #define INTCON (0x01c00000+0x200000) | |
273 | #define INTMSK (0x01c00000+0x20000c) | |
274 | #define LOCKTIME (0x01c00000+0x18000c) | |
275 | #define PLLCON (0x01c00000+0x180000) | |
276 | #define CLKCON (0x01c00000+0x180004) | |
277 | #define WTCON (0x01c00000+0x130000) | |
278 | cpu_init_crit: | |
279 | /* disable watch dog */ | |
53677ef1 | 280 | ldr r0, =WTCON |
074cff0d WD |
281 | ldr r1, =0x0 |
282 | str r1, [r0] | |
283 | ||
284 | /* | |
285 | * mask all IRQs by clearing all bits in the INTMRs | |
286 | */ | |
287 | ldr r1,=INTMSK | |
288 | ldr r0, =0x03fffeff | |
289 | str r0, [r1] | |
290 | ||
291 | ldr r1, =INTCON | |
292 | ldr r0, =0x05 | |
293 | str r0, [r1] | |
294 | ||
295 | /* Set Clock Control Register */ | |
296 | ldr r1, =LOCKTIME | |
297 | ldrb r0, =800 | |
298 | strb r0, [r1] | |
299 | ||
300 | ldr r1, =PLLCON | |
301 | ||
302 | #if CONFIG_S3C44B0_CLOCK_SPEED==66 | |
53677ef1 | 303 | ldr r0, =0x34031 /* 66MHz (Quartz=11MHz) */ |
074cff0d WD |
304 | #elif CONFIG_S3C44B0_CLOCK_SPEED==75 |
305 | ldr r0, =0x610c1 /*B2: Xtal=20mhz Fclk=75MHz */ | |
306 | #else | |
307 | # error CONFIG_S3C44B0_CLOCK_SPEED undefined | |
308 | #endif | |
309 | ||
310 | str r0, [r1] | |
311 | ||
312 | ldr r1,=CLKCON | |
313 | ldr r0, =0x7ff8 | |
314 | str r0, [r1] | |
315 | ||
316 | mov pc, lr | |
317 | ||
318 | ||
319 | /*************************************************/ | |
320 | /* interrupt vectors */ | |
321 | /*************************************************/ | |
322 | real_vectors: | |
323 | b reset | |
324 | b undefined_instruction | |
325 | b software_interrupt | |
326 | b prefetch_abort | |
327 | b data_abort | |
328 | b not_used | |
329 | b irq | |
330 | b fiq | |
331 | ||
332 | /*************************************************/ | |
333 | ||
334 | undefined_instruction: | |
335 | mov r6, #3 | |
336 | b reset | |
337 | ||
338 | software_interrupt: | |
339 | mov r6, #4 | |
340 | b reset | |
341 | ||
342 | prefetch_abort: | |
343 | mov r6, #5 | |
344 | b reset | |
345 | ||
346 | data_abort: | |
347 | mov r6, #6 | |
348 | b reset | |
349 | ||
350 | not_used: | |
351 | /* we *should* never reach this */ | |
352 | mov r6, #7 | |
353 | b reset | |
354 | ||
355 | irq: | |
356 | mov r6, #8 | |
357 | b reset | |
358 | ||
359 | fiq: | |
360 | mov r6, #9 | |
361 | b reset |