blob: 6f397a44c663036874669fca7ad785f0a5f01206 [file] [log] [blame]
wdenkc6097192002-11-03 00:24:07 +00001/*
2 * Copyright (C) 1998 Dan Malek <dmalek@jlc.net>
3 * Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
4 * Copyright (C) 2000,2001,2002 Wolfgang Denk <wd@denx.de>
5 *
Wolfgang Denkd79de1d2013-07-08 09:37:19 +02006 * SPDX-License-Identifier: GPL-2.0+
wdenkc6097192002-11-03 00:24:07 +00007 */
8
9/* U-Boot - Startup Code for PowerPC based Embedded Boards
10 *
11 *
12 * The processor starts at 0x00000100 and the code is executed
13 * from flash. The code is organized to be at an other address
14 * in memory, but as long we don't jump around before relocating.
15 * board_init lies at a quite high address and when the cpu has
16 * jumped there, everything is ok.
17 * This works because the cpu gives the FLASH (CS0) the whole
18 * address space at startup, and board_init lies as a echo of
19 * the flash somewhere up there in the memorymap.
20 *
21 * board_init will change CS0 to be positioned at the correct
22 * address and (s)dram will be positioned at address 0
23 */
Wolfgang Denk0191e472010-10-26 14:34:52 +020024#include <asm-offsets.h>
wdenkc6097192002-11-03 00:24:07 +000025#include <config.h>
26#include <mpc824x.h>
27#include <version.h>
28
29#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */
30
31#include <ppc_asm.tmpl>
32#include <ppc_defs.h>
33
34#include <asm/cache.h>
35#include <asm/mmu.h>
Peter Tyser3a1362d2010-10-14 23:33:24 -050036#include <asm/u-boot.h>
wdenkc6097192002-11-03 00:24:07 +000037
wdenkc6097192002-11-03 00:24:07 +000038/* We don't want the MMU yet.
39*/
40#undef MSR_KERNEL
41/* FP, Machine Check and Recoverable Interr. */
42#define MSR_KERNEL ( MSR_FP | MSR_ME | MSR_RI )
43
44/*
45 * Set up GOT: Global Offset Table
46 *
Joakim Tjernlund3fbaa4d2010-01-19 14:41:56 +010047 * Use r12 to access the GOT
wdenkc6097192002-11-03 00:24:07 +000048 */
49 START_GOT
50 GOT_ENTRY(_GOT2_TABLE_)
51 GOT_ENTRY(_FIXUP_TABLE_)
52
53 GOT_ENTRY(_start)
54 GOT_ENTRY(_start_of_vectors)
55 GOT_ENTRY(_end_of_vectors)
56 GOT_ENTRY(transfer_to_handler)
57
wdenkb9a83a92003-05-30 12:48:29 +000058 GOT_ENTRY(__init_end)
Simon Glassed70c8f2013-03-14 06:54:53 +000059 GOT_ENTRY(__bss_end)
wdenkbf2f8c92003-05-22 22:52:13 +000060 GOT_ENTRY(__bss_start)
wdenkc6097192002-11-03 00:24:07 +000061#if defined(CONFIG_FADS)
62 GOT_ENTRY(environment)
63#endif
64 END_GOT
65
66/*
67 * r3 - 1st arg to board_init(): IMMP pointer
68 * r4 - 2nd arg to board_init(): boot flag
69 */
70 .text
71 .long 0x27051956 /* U-Boot Magic Number */
72 .globl version_string
73version_string:
Andreas Bießmann61d01952011-07-18 20:24:04 +020074 .ascii U_BOOT_VERSION_STRING, "\0"
wdenkc6097192002-11-03 00:24:07 +000075
76 . = EXC_OFF_SYS_RESET
77 .globl _start
78_start:
wdenkc6097192002-11-03 00:24:07 +000079 /* Initialize machine status; enable machine check interrupt */
80 /*----------------------------------------------------------------------*/
81 li r3, MSR_KERNEL /* Set FP, ME, RI flags */
82 mtmsr r3
83 mtspr SRR1, r3 /* Make SRR1 match MSR */
84
85 addis r0,0,0x0000 /* lets make sure that r0 is really 0 */
86 mtspr HID0, r0 /* disable I and D caches */
87
88 mfspr r3, ICR /* clear Interrupt Cause Register */
89
90 mfmsr r3 /* turn off address translation */
91 addis r4,0,0xffff
92 ori r4,r4,0xffcf
93 and r3,r3,r4
94 mtmsr r3
95 isync
96 sync /* the MMU should be off... */
97
98
99in_flash:
wdenkc6097192002-11-03 00:24:07 +0000100 /*
101 * Setup BATs - cannot be done in C since we don't have a stack yet
102 */
103 bl setup_bats
104
105 /* Enable MMU.
106 */
107 mfmsr r3
108 ori r3, r3, (MSR_IR | MSR_DR)
109 mtmsr r3
Stefan Roeseed062042012-09-19 03:18:53 +0000110
wdenkc6097192002-11-03 00:24:07 +0000111 /* Enable and invalidate data cache.
112 */
113 mfspr r3, HID0
114 mr r2, r3
115 ori r3, r3, HID0_DCE | HID0_DCI
116 ori r2, r2, HID0_DCE
117 sync
118 mtspr HID0, r3
119 mtspr HID0, r2
120 sync
121
122 /* Allocate Initial RAM in data cache.
123 */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200124 lis r3, CONFIG_SYS_INIT_RAM_ADDR@h
125 ori r3, r3, CONFIG_SYS_INIT_RAM_ADDR@l
wdenkc6097192002-11-03 00:24:07 +0000126 li r2, 128
127 mtctr r2
1281:
129 dcbz r0, r3
130 addi r3, r3, 32
131 bdnz 1b
132
133 /* Lock way0 in data cache.
134 */
135 mfspr r3, 1011
136 lis r2, 0xffff
137 ori r2, r2, 0xff1f
138 and r3, r3, r2
139 ori r3, r3, 0x0080
140 sync
141 mtspr 1011, r3
Stefan Roeseed062042012-09-19 03:18:53 +0000142
wdenkc6097192002-11-03 00:24:07 +0000143 /*
144 * Thisk the stack pointer *somewhere* sensible. Doesnt
145 * matter much where as we'll move it when we relocate
146 */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200147 lis r1, (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET)@h
148 ori r1, r1, (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET)@l
wdenkc6097192002-11-03 00:24:07 +0000149
150 li r0, 0 /* Make room for stack frame header and */
151 stwu r0, -4(r1) /* clear final stack frame so that */
152 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
153
154 /* let the C-code set up the rest */
155 /* */
156 /* Be careful to keep code relocatable ! */
157 /*----------------------------------------------------------------------*/
158
159 GET_GOT /* initialize GOT access */
Wolfgang Denkb2d36ea2011-04-20 22:11:21 +0200160
wdenkc6097192002-11-03 00:24:07 +0000161 /* r3: IMMR */
162 bl cpu_init_f /* run low-level CPU init code (from Flash) */
163
wdenkc6097192002-11-03 00:24:07 +0000164 bl board_init_f /* run 1st part of board init code (from Flash) */
165
Peter Tyser0c44caf2010-09-14 19:13:53 -0500166 /* NOTREACHED - board_init_f() does not return */
167
wdenkc6097192002-11-03 00:24:07 +0000168
wdenkc6097192002-11-03 00:24:07 +0000169 .globl _start_of_vectors
170_start_of_vectors:
171
172/* Machine check */
173 STD_EXCEPTION(EXC_OFF_MACH_CHCK, MachineCheck, MachineCheckException)
174
175/* Data Storage exception. "Never" generated on the 860. */
176 STD_EXCEPTION(EXC_OFF_DATA_STOR, DataStorage, UnknownException)
177
178/* Instruction Storage exception. "Never" generated on the 860. */
179 STD_EXCEPTION(EXC_OFF_INS_STOR, InstStorage, UnknownException)
180
181/* External Interrupt exception. */
182 STD_EXCEPTION(EXC_OFF_EXTERNAL, ExtInterrupt, external_interrupt)
183
184/* Alignment exception. */
185 . = EXC_OFF_ALIGN
186Alignment:
Rafal Jaworowski06244e42007-06-22 14:58:04 +0200187 EXCEPTION_PROLOG(SRR0, SRR1)
wdenkc6097192002-11-03 00:24:07 +0000188 mfspr r4,DAR
189 stw r4,_DAR(r21)
190 mfspr r5,DSISR
191 stw r5,_DSISR(r21)
192 addi r3,r1,STACK_FRAME_OVERHEAD
Joakim Tjernlund4ff6bc02010-01-19 14:41:55 +0100193 EXC_XFER_TEMPLATE(Alignment, AlignmentException, MSR_KERNEL, COPY_EE)
wdenkc6097192002-11-03 00:24:07 +0000194
195/* Program check exception */
196 . = EXC_OFF_PROGRAM
197ProgramCheck:
Rafal Jaworowski06244e42007-06-22 14:58:04 +0200198 EXCEPTION_PROLOG(SRR0, SRR1)
wdenkc6097192002-11-03 00:24:07 +0000199 addi r3,r1,STACK_FRAME_OVERHEAD
Joakim Tjernlund4ff6bc02010-01-19 14:41:55 +0100200 EXC_XFER_TEMPLATE(ProgramCheck, ProgramCheckException,
201 MSR_KERNEL, COPY_EE)
wdenkc6097192002-11-03 00:24:07 +0000202
203 /* No FPU on MPC8xx. This exception is not supposed to happen.
204 */
205 STD_EXCEPTION(EXC_OFF_FPUNAVAIL, FPUnavailable, UnknownException)
206
207 /* I guess we could implement decrementer, and may have
208 * to someday for timekeeping.
209 */
210 STD_EXCEPTION(EXC_OFF_DECR, Decrementer, timer_interrupt)
211 STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
212 STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
wdenk874ac262003-07-24 23:38:38 +0000213 STD_EXCEPTION(0xc00, SystemCall, UnknownException)
wdenkc6097192002-11-03 00:24:07 +0000214
215 STD_EXCEPTION(EXC_OFF_TRACE, SingleStep, UnknownException)
216
217 STD_EXCEPTION(EXC_OFF_FPUNASSIST, Trap_0e, UnknownException)
218 STD_EXCEPTION(EXC_OFF_PMI, Trap_0f, UnknownException)
219
220 STD_EXCEPTION(EXC_OFF_ITME, InstructionTransMiss, UnknownException)
221 STD_EXCEPTION(EXC_OFF_DLTME, DataLoadTransMiss, UnknownException)
222 STD_EXCEPTION(EXC_OFF_DSTME, DataStoreTransMiss, UnknownException)
wdenk4a5c8a72003-03-06 00:02:04 +0000223 STD_EXCEPTION(EXC_OFF_IABE, InstructionBreakpoint, DebugException)
wdenkc6097192002-11-03 00:24:07 +0000224 STD_EXCEPTION(EXC_OFF_SMIE, SysManageInt, UnknownException)
225 STD_EXCEPTION(0x1500, Reserved5, UnknownException)
226 STD_EXCEPTION(0x1600, Reserved6, UnknownException)
227 STD_EXCEPTION(0x1700, Reserved7, UnknownException)
228 STD_EXCEPTION(0x1800, Reserved8, UnknownException)
229 STD_EXCEPTION(0x1900, Reserved9, UnknownException)
230 STD_EXCEPTION(0x1a00, ReservedA, UnknownException)
231 STD_EXCEPTION(0x1b00, ReservedB, UnknownException)
232 STD_EXCEPTION(0x1c00, ReservedC, UnknownException)
233 STD_EXCEPTION(0x1d00, ReservedD, UnknownException)
234 STD_EXCEPTION(0x1e00, ReservedE, UnknownException)
235 STD_EXCEPTION(0x1f00, ReservedF, UnknownException)
236
237 STD_EXCEPTION(EXC_OFF_RMTE, RunModeTrace, UnknownException)
238
239 .globl _end_of_vectors
240_end_of_vectors:
241
242
243 . = 0x3000
244
245/*
246 * This code finishes saving the registers to the exception frame
247 * and jumps to the appropriate handler for the exception.
248 * Register r21 is pointer into trap frame, r1 has new stack pointer.
249 */
250 .globl transfer_to_handler
251transfer_to_handler:
252 stw r22,_NIP(r21)
253 lis r22,MSR_POW@h
254 andc r23,r23,r22
255 stw r23,_MSR(r21)
256 SAVE_GPR(7, r21)
257 SAVE_4GPRS(8, r21)
258 SAVE_8GPRS(12, r21)
259 SAVE_8GPRS(24, r21)
260#if 0
261 andi. r23,r23,MSR_PR
262 mfspr r23,SPRG3 /* if from user, fix up tss.regs */
263 beq 2f
264 addi r24,r1,STACK_FRAME_OVERHEAD
265 stw r24,PT_REGS(r23)
2662: addi r2,r23,-TSS /* set r2 to current */
267 tovirt(r2,r2,r23)
268#endif
269 mflr r23
270 andi. r24,r23,0x3f00 /* get vector offset */
271 stw r24,TRAP(r21)
272 li r22,0
273 stw r22,RESULT(r21)
274 mtspr SPRG2,r22 /* r1 is now kernel sp */
275#if 0
276 addi r24,r2,TASK_STRUCT_SIZE /* check for kernel stack overflow */
277 cmplw 0,r1,r2
278 cmplw 1,r1,r24
279 crand 1,1,4
280 bgt stack_ovf /* if r2 < r1 < r2+TASK_STRUCT_SIZE */
281#endif
282 lwz r24,0(r23) /* virtual address of handler */
283 lwz r23,4(r23) /* where to go when done */
284 mtspr SRR0,r24
285 ori r20,r20,0x30 /* enable IR, DR */
286 mtspr SRR1,r20
287 mtlr r23
288 SYNC
289 rfi /* jump to handler, enable MMU */
290
291int_return:
292 mfmsr r28 /* Disable interrupts */
293 li r4,0
294 ori r4,r4,MSR_EE
295 andc r28,r28,r4
296 SYNC /* Some chip revs need this... */
297 mtmsr r28
298 SYNC
299 lwz r2,_CTR(r1)
300 lwz r0,_LINK(r1)
301 mtctr r2
302 mtlr r0
303 lwz r2,_XER(r1)
304 lwz r0,_CCR(r1)
305 mtspr XER,r2
306 mtcrf 0xFF,r0
307 REST_10GPRS(3, r1)
308 REST_10GPRS(13, r1)
309 REST_8GPRS(23, r1)
310 REST_GPR(31, r1)
311 lwz r2,_NIP(r1) /* Restore environment */
312 lwz r0,_MSR(r1)
313 mtspr SRR0,r2
314 mtspr SRR1,r0
315 lwz r0,GPR0(r1)
316 lwz r2,GPR2(r1)
317 lwz r1,GPR1(r1)
318 SYNC
319 rfi
320
321/* Cache functions.
322*/
323 .globl icache_enable
324icache_enable:
325 mfspr r5,HID0 /* turn on the I cache. */
326 ori r5,r5,0x8800 /* Instruction cache only! */
327 addis r6,0,0xFFFF
328 ori r6,r6,0xF7FF
329 and r6,r5,r6 /* clear the invalidate bit */
330 sync
331 mtspr HID0,r5
332 mtspr HID0,r6
333 isync
334 sync
335 blr
336
337 .globl icache_disable
338icache_disable:
339 mfspr r5,HID0
340 addis r6,0,0xFFFF
341 ori r6,r6,0x7FFF
342 and r5,r5,r6
343 sync
344 mtspr HID0,r5
345 isync
346 sync
347 blr
348
349 .globl icache_status
350icache_status:
351 mfspr r3, HID0
352 srwi r3, r3, 15 /* >>15 & 1=> select bit 16 */
353 andi. r3, r3, 1
354 blr
355
356 .globl dcache_enable
357dcache_enable:
358 mfspr r5,HID0 /* turn on the D cache. */
359 ori r5,r5,0x4400 /* Data cache only! */
360 mfspr r4, PVR /* read PVR */
361 srawi r3, r4, 16 /* shift off the least 16 bits */
362 cmpi 0, 0, r3, 0xC /* Check for Max pvr */
363 bne NotMax
364 ori r5,r5,0x0040 /* setting the DCFA bit, for Max rev 1 errata */
365NotMax:
366 addis r6,0,0xFFFF
367 ori r6,r6,0xFBFF
368 and r6,r5,r6 /* clear the invalidate bit */
369 sync
370 mtspr HID0,r5
371 mtspr HID0,r6
372 isync
373 sync
374 blr
375
376 .globl dcache_disable
377dcache_disable:
378 mfspr r5,HID0
379 addis r6,0,0xFFFF
380 ori r6,r6,0xBFFF
381 and r5,r5,r6
382 sync
383 mtspr HID0,r5
384 isync
385 sync
386 blr
387
388 .globl dcache_status
389dcache_status:
390 mfspr r3, HID0
391 srwi r3, r3, 14 /* >>14 & 1=> select bit 17 */
392 andi. r3, r3, 1
393 blr
394
395 .globl dc_read
396dc_read:
397/*TODO : who uses this, what should it do?
398*/
399 blr
400
401
402 .globl get_pvr
403get_pvr:
404 mfspr r3, PVR
405 blr
406
407
408/*------------------------------------------------------------------------------*/
409
410/*
411 * void relocate_code (addr_sp, gd, addr_moni)
412 *
413 * This "function" does not return, instead it continues in RAM
414 * after relocating the monitor code.
415 *
416 * r3 = dest
417 * r4 = src
418 * r5 = length in bytes
419 * r6 = cachelinesize
420 */
421 .globl relocate_code
422relocate_code:
423
424 mr r1, r3 /* Set new stack pointer */
425 mr r9, r4 /* Save copy of Global Data pointer */
426 mr r10, r5 /* Save copy of Destination Address */
427
Joakim Tjernlund3fbaa4d2010-01-19 14:41:56 +0100428 GET_GOT
wdenkc6097192002-11-03 00:24:07 +0000429 mr r3, r5 /* Destination Address */
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200430#ifdef CONFIG_SYS_RAMBOOT
431 lis r4, CONFIG_SYS_SDRAM_BASE@h /* Source Address */
432 ori r4, r4, CONFIG_SYS_SDRAM_BASE@l
wdenkc6097192002-11-03 00:24:07 +0000433#else
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200434 lis r4, CONFIG_SYS_MONITOR_BASE@h /* Source Address */
435 ori r4, r4, CONFIG_SYS_MONITOR_BASE@l
wdenkc6097192002-11-03 00:24:07 +0000436#endif
wdenkb9a83a92003-05-30 12:48:29 +0000437 lwz r5, GOT(__init_end)
438 sub r5, r5, r4
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200439 li r6, CONFIG_SYS_CACHELINE_SIZE /* Cache Line Size */
wdenkc6097192002-11-03 00:24:07 +0000440
441 /*
442 * Fix GOT pointer:
443 *
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200444 * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address
wdenkc6097192002-11-03 00:24:07 +0000445 *
446 * Offset:
447 */
448 sub r15, r10, r4
449
450 /* First our own GOT */
Joakim Tjernlund3fbaa4d2010-01-19 14:41:56 +0100451 add r12, r12, r15
wdenkc6097192002-11-03 00:24:07 +0000452 /* the the one used by the C code */
453 add r30, r30, r15
454
455 /*
456 * Now relocate code
457 */
458
459 cmplw cr1,r3,r4
460 addi r0,r5,3
461 srwi. r0,r0,2
462 beq cr1,4f /* In place copy is not necessary */
463 beq 7f /* Protect against 0 count */
464 mtctr r0
465 bge cr1,2f
466
467 la r8,-4(r4)
468 la r7,-4(r3)
4691: lwzu r0,4(r8)
470 stwu r0,4(r7)
471 bdnz 1b
472 b 4f
473
4742: slwi r0,r0,2
475 add r8,r4,r0
476 add r7,r3,r0
4773: lwzu r0,-4(r8)
478 stwu r0,-4(r7)
479 bdnz 3b
480
wdenk2c9b05d2003-09-10 22:30:53 +00004814:
wdenk2c9b05d2003-09-10 22:30:53 +0000482/* Unlock the data cache and invalidate locked area */
483 xor r0, r0, r0
484 mtspr 1011, r0
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200485 lis r4, CONFIG_SYS_INIT_RAM_ADDR@h
486 ori r4, r4, CONFIG_SYS_INIT_RAM_ADDR@l
wdenk2c9b05d2003-09-10 22:30:53 +0000487 li r0, 128
488 mtctr r0
48941:
490 dcbi r0, r4
491 addi r4, r4, 32
492 bdnz 41b
wdenk2c9b05d2003-09-10 22:30:53 +0000493
wdenkc6097192002-11-03 00:24:07 +0000494/*
495 * Now flush the cache: note that we must start from a cache aligned
496 * address. Otherwise we might miss one cache line.
497 */
wdenk2c9b05d2003-09-10 22:30:53 +0000498 cmpwi r6,0
wdenkc6097192002-11-03 00:24:07 +0000499 add r5,r3,r5
500 beq 7f /* Always flush prefetch queue in any case */
501 subi r0,r6,1
502 andc r3,r3,r0
503 mr r4,r3
5045: dcbst 0,r4
505 add r4,r4,r6
506 cmplw r4,r5
507 blt 5b
508 sync /* Wait for all dcbst to complete on bus */
509 mr r4,r3
5106: icbi 0,r4
511 add r4,r4,r6
512 cmplw r4,r5
513 blt 6b
5147: sync /* Wait for all icbi to complete on bus */
515 isync
516
517/*
518 * We are done. Do not return, instead branch to second part of board
519 * initialization, now running from RAM.
520 */
521
522 addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
523 mtlr r0
524 blr
525
526in_ram:
527
528 /*
Joakim Tjernlund3fbaa4d2010-01-19 14:41:56 +0100529 * Relocation Function, r12 point to got2+0x8000
wdenkc6097192002-11-03 00:24:07 +0000530 *
531 * Adjust got2 pointers, no need to check for 0, this code
532 * already puts a few entries in the table.
533 */
534 li r0,__got2_entries@sectoff@l
535 la r3,GOT(_GOT2_TABLE_)
536 lwz r11,GOT(_GOT2_TABLE_)
537 mtctr r0
538 sub r11,r3,r11
539 addi r3,r3,-4
5401: lwzu r0,4(r3)
Joakim Tjernlund4f2fdac2009-10-08 02:03:51 +0200541 cmpwi r0,0
542 beq- 2f
wdenkc6097192002-11-03 00:24:07 +0000543 add r0,r0,r11
544 stw r0,0(r3)
Joakim Tjernlund4f2fdac2009-10-08 02:03:51 +02005452: bdnz 1b
wdenkc6097192002-11-03 00:24:07 +0000546
547 /*
548 * Now adjust the fixups and the pointers to the fixups
549 * in case we need to move ourselves again.
550 */
Joakim Tjernlund4f2fdac2009-10-08 02:03:51 +0200551 li r0,__fixup_entries@sectoff@l
wdenkc6097192002-11-03 00:24:07 +0000552 lwz r3,GOT(_FIXUP_TABLE_)
553 cmpwi r0,0
554 mtctr r0
555 addi r3,r3,-4
556 beq 4f
5573: lwzu r4,4(r3)
558 lwzux r0,r4,r11
Joakim Tjernlundc61b25a2010-10-14 11:51:44 +0200559 cmpwi r0,0
wdenkc6097192002-11-03 00:24:07 +0000560 add r0,r0,r11
Joakim Tjernlund401b5922010-11-04 19:02:00 +0100561 stw r4,0(r3)
Joakim Tjernlundc61b25a2010-10-14 11:51:44 +0200562 beq- 5f
wdenkc6097192002-11-03 00:24:07 +0000563 stw r0,0(r4)
Joakim Tjernlundc61b25a2010-10-14 11:51:44 +02005645: bdnz 3b
wdenkc6097192002-11-03 00:24:07 +00005654:
566clear_bss:
567 /*
568 * Now clear BSS segment
569 */
wdenkbf2f8c92003-05-22 22:52:13 +0000570 lwz r3,GOT(__bss_start)
Simon Glassed70c8f2013-03-14 06:54:53 +0000571 lwz r4,GOT(__bss_end)
wdenkc6097192002-11-03 00:24:07 +0000572
573 cmplw 0, r3, r4
574 beq 6f
575
576 li r0, 0
5775:
578 stw r0, 0(r3)
579 addi r3, r3, 4
580 cmplw 0, r3, r4
581 blt 5b
5826:
583
584 mr r3, r9 /* Global Data pointer */
585 mr r4, r10 /* Destination Address */
586 bl board_init_r
587
wdenkc6097192002-11-03 00:24:07 +0000588 /*
589 * Copy exception vector code to low memory
590 *
591 * r3: dest_addr
592 * r7: source address, r8: end address, r9: target address
593 */
594 .globl trap_init
595trap_init:
Joakim Tjernlund3fbaa4d2010-01-19 14:41:56 +0100596 mflr r4 /* save link register */
597 GET_GOT
wdenkc6097192002-11-03 00:24:07 +0000598 lwz r7, GOT(_start)
599 lwz r8, GOT(_end_of_vectors)
600
wdenk4e112c12003-06-03 23:54:09 +0000601 li r9, 0x100 /* reset vector always at 0x100 */
wdenkc6097192002-11-03 00:24:07 +0000602
603 cmplw 0, r7, r8
604 bgelr /* return if r7>=r8 - just in case */
wdenkc6097192002-11-03 00:24:07 +00006051:
606 lwz r0, 0(r7)
607 stw r0, 0(r9)
608 addi r7, r7, 4
609 addi r9, r9, 4
610 cmplw 0, r7, r8
611 bne 1b
612
613 /*
614 * relocate `hdlr' and `int_return' entries
615 */
616 li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
617 li r8, Alignment - _start + EXC_OFF_SYS_RESET
6182:
619 bl trap_reloc
620 addi r7, r7, 0x100 /* next exception vector */
621 cmplw 0, r7, r8
622 blt 2b
623
624 li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
625 bl trap_reloc
626
627 li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
628 bl trap_reloc
629
630 li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
631 li r8, SystemCall - _start + EXC_OFF_SYS_RESET
6323:
633 bl trap_reloc
634 addi r7, r7, 0x100 /* next exception vector */
635 cmplw 0, r7, r8
636 blt 3b
637
638 li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
639 li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
6404:
641 bl trap_reloc
642 addi r7, r7, 0x100 /* next exception vector */
643 cmplw 0, r7, r8
644 blt 4b
645
646 mtlr r4 /* restore link register */
647 blr
648
wdenkc6097192002-11-03 00:24:07 +0000649 /* Setup the BAT registers.
650 */
651setup_bats:
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200652 lis r4, CONFIG_SYS_IBAT0L@h
653 ori r4, r4, CONFIG_SYS_IBAT0L@l
654 lis r3, CONFIG_SYS_IBAT0U@h
655 ori r3, r3, CONFIG_SYS_IBAT0U@l
wdenkc6097192002-11-03 00:24:07 +0000656 mtspr IBAT0L, r4
657 mtspr IBAT0U, r3
658 isync
659
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200660 lis r4, CONFIG_SYS_DBAT0L@h
661 ori r4, r4, CONFIG_SYS_DBAT0L@l
662 lis r3, CONFIG_SYS_DBAT0U@h
663 ori r3, r3, CONFIG_SYS_DBAT0U@l
wdenkc6097192002-11-03 00:24:07 +0000664 mtspr DBAT0L, r4
665 mtspr DBAT0U, r3
666 isync
667
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200668 lis r4, CONFIG_SYS_IBAT1L@h
669 ori r4, r4, CONFIG_SYS_IBAT1L@l
670 lis r3, CONFIG_SYS_IBAT1U@h
671 ori r3, r3, CONFIG_SYS_IBAT1U@l
wdenkc6097192002-11-03 00:24:07 +0000672 mtspr IBAT1L, r4
673 mtspr IBAT1U, r3
674 isync
675
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200676 lis r4, CONFIG_SYS_DBAT1L@h
677 ori r4, r4, CONFIG_SYS_DBAT1L@l
678 lis r3, CONFIG_SYS_DBAT1U@h
679 ori r3, r3, CONFIG_SYS_DBAT1U@l
wdenkc6097192002-11-03 00:24:07 +0000680 mtspr DBAT1L, r4
681 mtspr DBAT1U, r3
682 isync
683
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200684 lis r4, CONFIG_SYS_IBAT2L@h
685 ori r4, r4, CONFIG_SYS_IBAT2L@l
686 lis r3, CONFIG_SYS_IBAT2U@h
687 ori r3, r3, CONFIG_SYS_IBAT2U@l
wdenkc6097192002-11-03 00:24:07 +0000688 mtspr IBAT2L, r4
689 mtspr IBAT2U, r3
690 isync
691
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200692 lis r4, CONFIG_SYS_DBAT2L@h
693 ori r4, r4, CONFIG_SYS_DBAT2L@l
694 lis r3, CONFIG_SYS_DBAT2U@h
695 ori r3, r3, CONFIG_SYS_DBAT2U@l
wdenkc6097192002-11-03 00:24:07 +0000696 mtspr DBAT2L, r4
697 mtspr DBAT2U, r3
698 isync
699
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200700 lis r4, CONFIG_SYS_IBAT3L@h
701 ori r4, r4, CONFIG_SYS_IBAT3L@l
702 lis r3, CONFIG_SYS_IBAT3U@h
703 ori r3, r3, CONFIG_SYS_IBAT3U@l
wdenkc6097192002-11-03 00:24:07 +0000704 mtspr IBAT3L, r4
705 mtspr IBAT3U, r3
706 isync
707
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200708 lis r4, CONFIG_SYS_DBAT3L@h
709 ori r4, r4, CONFIG_SYS_DBAT3L@l
710 lis r3, CONFIG_SYS_DBAT3U@h
711 ori r3, r3, CONFIG_SYS_DBAT3U@l
wdenkc6097192002-11-03 00:24:07 +0000712 mtspr DBAT3L, r4
713 mtspr DBAT3U, r3
714 isync
715
716 /* Invalidate TLBs.
717 * -> for (val = 0; val < 0x20000; val+=0x1000)
718 * -> tlbie(val);
719 */
720 lis r3, 0
721 lis r5, 2
722
7231:
724 tlbie r3
725 addi r3, r3, 0x1000
726 cmp 0, 0, r3, r5
727 blt 1b
728
729 blr