]>
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 | ||
30 | ||
31 | #include <config.h> | |
32 | #include <version.h> | |
33 | ||
34 | ||
35 | /* | |
36 | * Jump vector table | |
37 | */ | |
38 | ||
39 | ||
40 | .globl _start | |
41 | _start: b reset | |
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 | add pc, pc, #0x0c000000 | |
49 | ||
50 | .balignl 16,0xdeadbeef | |
51 | ||
52 | ||
53 | /* | |
54 | ************************************************************************* | |
55 | * | |
56 | * Startup Code (reset vector) | |
57 | * | |
58 | * do important init only if we don't start from memory! | |
59 | * relocate u-boot to ram | |
60 | * setup stack | |
61 | * jump to second stage | |
62 | * | |
63 | ************************************************************************* | |
64 | */ | |
65 | ||
0110955a | 66 | .globl _TEXT_BASE |
074cff0d | 67 | _TEXT_BASE: |
14d0a02a | 68 | .word CONFIG_SYS_TEXT_BASE |
074cff0d | 69 | |
0110955a | 70 | #if defined(CONFIG_SYS_ARM_WITHOUT_RELOC) |
074cff0d WD |
71 | .globl _armboot_start |
72 | _armboot_start: | |
73 | .word _start | |
0110955a | 74 | #endif |
074cff0d WD |
75 | |
76 | /* | |
42dfe7a1 | 77 | * These are defined in the board-specific linker script. |
074cff0d | 78 | */ |
42dfe7a1 WD |
79 | .globl _bss_start |
80 | _bss_start: | |
81 | .word __bss_start | |
82 | ||
83 | .globl _bss_end | |
84 | _bss_end: | |
85 | .word _end | |
074cff0d WD |
86 | |
87 | #ifdef CONFIG_USE_IRQ | |
88 | /* IRQ stack memory (calculated at run-time) */ | |
89 | .globl IRQ_STACK_START | |
90 | IRQ_STACK_START: | |
91 | .word 0x0badc0de | |
92 | ||
93 | /* IRQ stack memory (calculated at run-time) */ | |
94 | .globl FIQ_STACK_START | |
95 | FIQ_STACK_START: | |
96 | .word 0x0badc0de | |
97 | #endif | |
98 | ||
0110955a HS |
99 | #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) |
100 | /* IRQ stack memory (calculated at run-time) + 8 bytes */ | |
101 | .globl IRQ_STACK_START_IN | |
102 | IRQ_STACK_START_IN: | |
103 | .word 0x0badc0de | |
104 | ||
105 | .globl _datarel_start | |
106 | _datarel_start: | |
107 | .word __datarel_start | |
108 | ||
109 | .globl _datarelrolocal_start | |
110 | _datarelrolocal_start: | |
111 | .word __datarelrolocal_start | |
112 | ||
113 | .globl _datarellocal_start | |
114 | _datarellocal_start: | |
115 | .word __datarellocal_start | |
116 | ||
117 | .globl _datarelro_start | |
118 | _datarelro_start: | |
119 | .word __datarelro_start | |
120 | ||
121 | .globl _got_start | |
122 | _got_start: | |
123 | .word __got_start | |
124 | ||
125 | .globl _got_end | |
126 | _got_end: | |
127 | .word __got_end | |
128 | ||
129 | /* | |
130 | * the actual reset code | |
131 | */ | |
132 | ||
133 | reset: | |
134 | /* | |
135 | * set the cpu to SVC32 mode | |
136 | */ | |
137 | mrs r0,cpsr | |
138 | bic r0,r0,#0x1f | |
139 | orr r0,r0,#0xd3 | |
140 | msr cpsr,r0 | |
141 | ||
142 | /* | |
143 | * we do sys-critical inits only at reboot, | |
144 | * not when booting from ram! | |
145 | */ | |
146 | #ifndef CONFIG_SKIP_LOWLEVEL_INIT | |
147 | bl cpu_init_crit | |
148 | /* | |
149 | * before relocating, we have to setup RAM timing | |
150 | * because memory timing is board-dependend, you will | |
151 | * find a lowlevel_init.S in your board directory. | |
152 | */ | |
153 | bl lowlevel_init | |
154 | #endif | |
155 | ||
156 | /* Set stackpointer in internal RAM to call board_init_f */ | |
157 | call_board_init_f: | |
158 | ldr sp, =(CONFIG_SYS_INIT_SP_ADDR) | |
159 | ldr r0,=0x00000000 | |
160 | bl board_init_f | |
161 | ||
162 | /*------------------------------------------------------------------------------*/ | |
163 | ||
164 | /* | |
165 | * void relocate_code (addr_sp, gd, addr_moni) | |
166 | * | |
167 | * This "function" does not return, instead it continues in RAM | |
168 | * after relocating the monitor code. | |
169 | * | |
170 | */ | |
171 | .globl relocate_code | |
172 | relocate_code: | |
173 | mov r4, r0 /* save addr_sp */ | |
174 | mov r5, r1 /* save addr of gd */ | |
175 | mov r6, r2 /* save addr of destination */ | |
176 | mov r7, r2 /* save addr of destination */ | |
177 | ||
178 | /* Set up the stack */ | |
179 | stack_setup: | |
180 | mov sp, r4 | |
181 | ||
182 | adr r0, _start | |
183 | ldr r2, _TEXT_BASE | |
184 | ldr r3, _bss_start | |
185 | sub r2, r3, r2 /* r2 <- size of armboot */ | |
186 | add r2, r0, r2 /* r2 <- source end address */ | |
187 | cmp r0, r6 | |
188 | beq clear_bss | |
189 | ||
190 | #ifndef CONFIG_SKIP_RELOCATE_UBOOT | |
191 | copy_loop: | |
192 | ldmia r0!, {r9-r10} /* copy from source address [r0] */ | |
193 | stmia r6!, {r9-r10} /* copy to target address [r1] */ | |
da90d4ce AA |
194 | cmp r0, r2 /* until source end address [r2] */ |
195 | blo copy_loop | |
0110955a HS |
196 | |
197 | #ifndef CONFIG_PRELOADER | |
198 | /* fix got entries */ | |
199 | ldr r1, _TEXT_BASE /* Text base */ | |
200 | mov r0, r7 /* reloc addr */ | |
201 | ldr r2, _got_start /* addr in Flash */ | |
202 | ldr r3, _got_end /* addr in Flash */ | |
203 | sub r3, r3, r1 | |
204 | add r3, r3, r0 | |
205 | sub r2, r2, r1 | |
206 | add r2, r2, r0 | |
207 | ||
208 | fixloop: | |
209 | ldr r4, [r2] | |
210 | sub r4, r4, r1 | |
211 | add r4, r4, r0 | |
212 | str r4, [r2] | |
213 | add r2, r2, #4 | |
214 | cmp r2, r3 | |
215 | bne fixloop | |
216 | #endif | |
217 | /* | |
218 | now copy to sram the interrupt vector | |
219 | */ | |
220 | adr r0, real_vectors | |
221 | add r2, r0, #1024 | |
222 | ldr r1, =0x0c000000 | |
223 | add r1, r1, #0x08 | |
224 | vector_copy_loop: | |
225 | ldmia r0!, {r3-r10} | |
226 | stmia r1!, {r3-r10} | |
227 | cmp r0, r2 | |
da90d4ce | 228 | blo vector_copy_loop |
0110955a HS |
229 | #endif /* #ifndef CONFIG_SKIP_RELOCATE_UBOOT */ |
230 | ||
231 | clear_bss: | |
232 | #ifndef CONFIG_PRELOADER | |
233 | ldr r0, _bss_start | |
234 | ldr r1, _bss_end | |
235 | ldr r3, _TEXT_BASE /* Text base */ | |
236 | mov r4, r7 /* reloc addr */ | |
237 | sub r0, r0, r3 | |
238 | add r0, r0, r4 | |
239 | sub r1, r1, r3 | |
240 | add r1, r1, r4 | |
241 | mov r2, #0x00000000 /* clear */ | |
242 | ||
243 | clbss_l:str r2, [r0] /* clear loop... */ | |
244 | add r0, r0, #4 | |
245 | cmp r0, r1 | |
246 | bne clbss_l | |
247 | ||
248 | bl coloured_LED_init | |
249 | bl red_LED_on | |
250 | #endif | |
074cff0d | 251 | |
0110955a HS |
252 | /* |
253 | * We are done. Do not return, instead branch to second part of board | |
254 | * initialization, now running from RAM. | |
255 | */ | |
256 | ldr r0, _TEXT_BASE | |
257 | ldr r2, _board_init_r | |
258 | sub r2, r2, r0 | |
259 | add r2, r2, r7 /* position from board_init_r in RAM */ | |
260 | /* setup parameters for board_init_r */ | |
261 | mov r0, r5 /* gd_t */ | |
262 | mov r1, r7 /* dest_addr */ | |
263 | /* jump to it ... */ | |
264 | mov lr, r2 | |
265 | mov pc, lr | |
266 | ||
267 | _board_init_r: .word board_init_r | |
268 | ||
269 | #else /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */ | |
074cff0d WD |
270 | /* |
271 | * the actual reset code | |
272 | */ | |
273 | ||
274 | reset: | |
275 | /* | |
276 | * set the cpu to SVC32 mode | |
277 | */ | |
278 | mrs r0,cpsr | |
279 | bic r0,r0,#0x1f | |
280 | orr r0,r0,#0x13 | |
281 | msr cpsr,r0 | |
282 | ||
283 | /* | |
284 | * we do sys-critical inits only at reboot, | |
285 | * not when booting from ram! | |
286 | */ | |
287 | ||
8aa1a2d1 | 288 | #ifndef CONFIG_SKIP_LOWLEVEL_INIT |
074cff0d WD |
289 | bl cpu_init_crit |
290 | /* | |
291 | * before relocating, we have to setup RAM timing | |
292 | * because memory timing is board-dependend, you will | |
400558b5 | 293 | * find a lowlevel_init.S in your board directory. |
074cff0d | 294 | */ |
400558b5 | 295 | bl lowlevel_init |
074cff0d WD |
296 | #endif |
297 | ||
8aa1a2d1 | 298 | #ifndef CONFIG_SKIP_RELOCATE_UBOOT |
074cff0d WD |
299 | relocate: /* relocate U-Boot to RAM */ |
300 | adr r0, _start /* r0 <- current position of code */ | |
301 | ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ | |
302 | cmp r0, r1 /* don't reloc during debug */ | |
303 | beq stack_setup | |
304 | ||
305 | ldr r2, _armboot_start | |
42dfe7a1 | 306 | ldr r3, _bss_start |
074cff0d WD |
307 | sub r2, r3, r2 /* r2 <- size of armboot */ |
308 | add r2, r0, r2 /* r2 <- source end address */ | |
309 | ||
310 | copy_loop: | |
311 | ldmia r0!, {r3-r10} /* copy from source address [r0] */ | |
312 | stmia r1!, {r3-r10} /* copy to target address [r1] */ | |
da90d4ce AA |
313 | cmp r0, r2 /* until source end address [r2] */ |
314 | blo copy_loop | |
074cff0d WD |
315 | |
316 | /* | |
317 | now copy to sram the interrupt vector | |
318 | */ | |
319 | adr r0, real_vectors | |
320 | add r2, r0, #1024 | |
321 | ldr r1, =0x0c000000 | |
322 | add r1, r1, #0x08 | |
323 | vector_copy_loop: | |
324 | ldmia r0!, {r3-r10} | |
325 | stmia r1!, {r3-r10} | |
326 | cmp r0, r2 | |
da90d4ce | 327 | blo vector_copy_loop |
8aa1a2d1 | 328 | #endif /* CONFIG_SKIP_RELOCATE_UBOOT */ |
074cff0d WD |
329 | |
330 | /* Set up the stack */ | |
331 | stack_setup: | |
332 | ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ | |
6d0f6bcf JCPV |
333 | sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */ |
334 | sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */ | |
074cff0d WD |
335 | #ifdef CONFIG_USE_IRQ |
336 | sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) | |
337 | #endif | |
338 | sub sp, r0, #12 /* leave 3 words for abort-stack */ | |
1a27f7d9 | 339 | bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ |
074cff0d WD |
340 | |
341 | ldr pc, _start_armboot | |
342 | ||
343 | _start_armboot: .word start_armboot | |
344 | ||
0110955a | 345 | #endif /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */ |
074cff0d WD |
346 | |
347 | /* | |
348 | ************************************************************************* | |
349 | * | |
350 | * CPU_init_critical registers | |
351 | * | |
352 | * setup important registers | |
353 | * setup memory timing | |
354 | * | |
355 | ************************************************************************* | |
356 | */ | |
357 | ||
358 | #define INTCON (0x01c00000+0x200000) | |
359 | #define INTMSK (0x01c00000+0x20000c) | |
360 | #define LOCKTIME (0x01c00000+0x18000c) | |
361 | #define PLLCON (0x01c00000+0x180000) | |
362 | #define CLKCON (0x01c00000+0x180004) | |
363 | #define WTCON (0x01c00000+0x130000) | |
364 | cpu_init_crit: | |
365 | /* disable watch dog */ | |
53677ef1 | 366 | ldr r0, =WTCON |
074cff0d WD |
367 | ldr r1, =0x0 |
368 | str r1, [r0] | |
369 | ||
370 | /* | |
371 | * mask all IRQs by clearing all bits in the INTMRs | |
372 | */ | |
373 | ldr r1,=INTMSK | |
374 | ldr r0, =0x03fffeff | |
375 | str r0, [r1] | |
376 | ||
377 | ldr r1, =INTCON | |
378 | ldr r0, =0x05 | |
379 | str r0, [r1] | |
380 | ||
381 | /* Set Clock Control Register */ | |
382 | ldr r1, =LOCKTIME | |
383 | ldrb r0, =800 | |
384 | strb r0, [r1] | |
385 | ||
386 | ldr r1, =PLLCON | |
387 | ||
388 | #if CONFIG_S3C44B0_CLOCK_SPEED==66 | |
53677ef1 | 389 | ldr r0, =0x34031 /* 66MHz (Quartz=11MHz) */ |
074cff0d WD |
390 | #elif CONFIG_S3C44B0_CLOCK_SPEED==75 |
391 | ldr r0, =0x610c1 /*B2: Xtal=20mhz Fclk=75MHz */ | |
392 | #else | |
393 | # error CONFIG_S3C44B0_CLOCK_SPEED undefined | |
394 | #endif | |
395 | ||
396 | str r0, [r1] | |
397 | ||
398 | ldr r1,=CLKCON | |
399 | ldr r0, =0x7ff8 | |
400 | str r0, [r1] | |
401 | ||
402 | mov pc, lr | |
403 | ||
404 | ||
405 | /*************************************************/ | |
406 | /* interrupt vectors */ | |
407 | /*************************************************/ | |
408 | real_vectors: | |
409 | b reset | |
410 | b undefined_instruction | |
411 | b software_interrupt | |
412 | b prefetch_abort | |
413 | b data_abort | |
414 | b not_used | |
415 | b irq | |
416 | b fiq | |
417 | ||
418 | /*************************************************/ | |
419 | ||
420 | undefined_instruction: | |
421 | mov r6, #3 | |
422 | b reset | |
423 | ||
424 | software_interrupt: | |
425 | mov r6, #4 | |
426 | b reset | |
427 | ||
428 | prefetch_abort: | |
429 | mov r6, #5 | |
430 | b reset | |
431 | ||
432 | data_abort: | |
433 | mov r6, #6 | |
434 | b reset | |
435 | ||
436 | not_used: | |
437 | /* we *should* never reach this */ | |
438 | mov r6, #7 | |
439 | b reset | |
440 | ||
441 | irq: | |
442 | mov r6, #8 | |
443 | b reset | |
444 | ||
445 | fiq: | |
446 | mov r6, #9 | |
447 | b reset |