blob: a001e1ce404d77a278756aa9b3a5dd7f312f459f [file] [log] [blame]
wdenk945af8d2003-07-16 21:53:01 +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 - 2003 Wolfgang Denk <wd@denx.de>
5 *
6 * See file CREDITS for list of people who contributed to this
7 * project.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of
12 * the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22 * MA 02111-1307 USA
23 */
24
25/*
26 * U-Boot - Startup Code for MPC5xxx CPUs
27 */
28#include <config.h>
29#include <mpc5xxx.h>
30#include <version.h>
31
32#define CONFIG_MPC5XXX 1 /* needed for Linux kernel header files */
33#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */
34
35#include <ppc_asm.tmpl>
36#include <ppc_defs.h>
37
38#include <asm/cache.h>
39#include <asm/mmu.h>
40
41#ifndef CONFIG_IDENT_STRING
42#define CONFIG_IDENT_STRING ""
43#endif
44
45/* We don't want the MMU yet.
46*/
47#undef MSR_KERNEL
48/* Floating Point enable, Machine Check and Recoverable Interr. */
49#ifdef DEBUG
50#define MSR_KERNEL (MSR_FP|MSR_RI)
51#else
52#define MSR_KERNEL (MSR_FP|MSR_ME|MSR_RI)
53#endif
54
55/*
56 * Set up GOT: Global Offset Table
57 *
58 * Use r14 to access the GOT
59 */
60 START_GOT
61 GOT_ENTRY(_GOT2_TABLE_)
62 GOT_ENTRY(_FIXUP_TABLE_)
63
64 GOT_ENTRY(_start)
65 GOT_ENTRY(_start_of_vectors)
66 GOT_ENTRY(_end_of_vectors)
67 GOT_ENTRY(transfer_to_handler)
68
69 GOT_ENTRY(__init_end)
70 GOT_ENTRY(_end)
71 GOT_ENTRY(__bss_start)
72 END_GOT
73
74/*
75 * Version string
76 */
77 .data
78 .globl version_string
79version_string:
80 .ascii U_BOOT_VERSION
81 .ascii " (", __DATE__, " - ", __TIME__, ")"
82 .ascii CONFIG_IDENT_STRING, "\0"
83
84/*
85 * Exception vectors
86 */
87 .text
88 . = EXC_OFF_SYS_RESET
89 .globl _start
90_start:
91 li r21, BOOTFLAG_COLD /* Normal Power-On */
92 nop
93 b boot_cold
94
95 . = EXC_OFF_SYS_RESET + 0x10
96
97 .globl _start_warm
98_start_warm:
99 li r21, BOOTFLAG_WARM /* Software reboot */
100 b boot_warm
101
102boot_cold:
103boot_warm:
104 mfmsr r5 /* save msr contents */
105
wdenk5cf9da42003-11-07 13:42:26 +0000106#if defined(CFG_LOWBOOT)
107 lis r4, CFG_DEFAULT_MBAR@h
108 lis r3, 0x0000FF00@h
109 ori r3, r3, 0x0000FF00@l
110 stw r3, 0x4(r4)
111 lis r3, 0x0000FFFF@h
112 ori r3, r3, 0x0000FFFF@l
113 stw r3, 0x8(r4)
114 lis r3, 0x00047800@h
115 ori r3, r3, 0x00047800@l
116 stw r3, 0x300(r4)
117 lis r3, 0x02010000@h
118 ori r3, r3, 0x02010000@l
119 stw r3, 0x54(r4)
120
wdenkd4ca31c2004-01-02 14:00:00 +0000121 lis r3, lowboot_reentry@h
122 ori r3, r3, lowboot_reentry@l
wdenk5cf9da42003-11-07 13:42:26 +0000123 mtlr r3
wdenkd4ca31c2004-01-02 14:00:00 +0000124 blr /* jump to flash based address */
125
126lowboot_reentry:
wdenk5cf9da42003-11-07 13:42:26 +0000127 lis r3, 0x0000FF00@h
128 ori r3, r3, 0x0000FF00@l
129 stw r3, 0x4c(r4)
130 lis r3, 0x0000FFFF@h
131 ori r3, r3, 0x0000FFFF@l
132 stw r3, 0x50(r4)
133 lis r3, 0x00047800@h
134 ori r3, r3, 0x00047800@l
135 stw r3, 0x300(r4)
136 lis r3, 0x02000001@h
137 ori r3, r3, 0x02000001@l
138 stw r3, 0x54(r4)
139#endif /* CFG_LOWBOOT */
wdenkd4ca31c2004-01-02 14:00:00 +0000140
wdenke0ac62d2003-08-17 18:55:18 +0000141#if defined(CFG_DEFAULT_MBAR) && !defined(CFG_RAMBOOT)
wdenk945af8d2003-07-16 21:53:01 +0000142 lis r3, CFG_MBAR@h
143 ori r3, r3, CFG_MBAR@l
144#if defined(CONFIG_MPC5200)
145 rlwinm r3, r3, 16, 16, 31
146#endif
147#if defined(CONFIG_MGT5100)
148 rlwinm r3, r3, 17, 15, 31
149#endif
150 lis r4, CFG_DEFAULT_MBAR@h
151 stw r3, 0(r4)
152#endif /* CFG_DEFAULT_MBAR */
153
154 /* Initialise the MPC5xxx processor core */
155 /*--------------------------------------------------------------*/
156
157 bl init_5xxx_core
158
159 /* initialize some things that are hard to access from C */
160 /*--------------------------------------------------------------*/
161
162 /* set up stack in on-chip SRAM */
163 lis r3, CFG_INIT_RAM_ADDR@h
164 ori r3, r3, CFG_INIT_RAM_ADDR@l
165 ori r1, r3, CFG_INIT_SP_OFFSET
166 li r0, 0 /* Make room for stack frame header and */
167 stwu r0, -4(r1) /* clear final stack frame so that */
168 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
169
170 /* let the C-code set up the rest */
171 /* */
172 /* Be careful to keep code relocatable ! */
173 /*--------------------------------------------------------------*/
174
175 GET_GOT /* initialize GOT access */
176
177 /* r3: IMMR */
178 bl cpu_init_f /* run low-level CPU init code (in Flash)*/
179
180 mr r3, r21
181 /* r3: BOOTFLAG */
182 bl board_init_f /* run 1st part of board init code (in Flash)*/
183
184/*
185 * Vector Table
186 */
187
188 .globl _start_of_vectors
189_start_of_vectors:
190
191/* Machine check */
192 STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)
193
194/* Data Storage exception. */
195 STD_EXCEPTION(0x300, DataStorage, UnknownException)
196
197/* Instruction Storage exception. */
198 STD_EXCEPTION(0x400, InstStorage, UnknownException)
199
200/* External Interrupt exception. */
201 STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
202
203/* Alignment exception. */
204 . = 0x600
205Alignment:
206 EXCEPTION_PROLOG
207 mfspr r4,DAR
208 stw r4,_DAR(r21)
209 mfspr r5,DSISR
210 stw r5,_DSISR(r21)
211 addi r3,r1,STACK_FRAME_OVERHEAD
212 li r20,MSR_KERNEL
213 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
214 rlwimi r20,r23,0,25,25 /* copy IP bit from saved MSR */
215 lwz r6,GOT(transfer_to_handler)
216 mtlr r6
217 blrl
218.L_Alignment:
219 .long AlignmentException - _start + EXC_OFF_SYS_RESET
220 .long int_return - _start + EXC_OFF_SYS_RESET
221
222/* Program check exception */
223 . = 0x700
224ProgramCheck:
225 EXCEPTION_PROLOG
226 addi r3,r1,STACK_FRAME_OVERHEAD
227 li r20,MSR_KERNEL
228 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
229 rlwimi r20,r23,0,25,25 /* copy IP bit from saved MSR */
230 lwz r6,GOT(transfer_to_handler)
231 mtlr r6
232 blrl
233.L_ProgramCheck:
234 .long ProgramCheckException - _start + EXC_OFF_SYS_RESET
235 .long int_return - _start + EXC_OFF_SYS_RESET
236
237 STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
238
239 /* I guess we could implement decrementer, and may have
240 * to someday for timekeeping.
241 */
242 STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
243
244 STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
245 STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
wdenk27b207f2003-07-24 23:38:38 +0000246 STD_EXCEPTION(0xc00, SystemCall, UnknownException)
wdenk945af8d2003-07-16 21:53:01 +0000247 STD_EXCEPTION(0xd00, SingleStep, UnknownException)
248
249 STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
250 STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
251
252 STD_EXCEPTION(0x1000, InstructionTLBMiss, UnknownException)
253 STD_EXCEPTION(0x1100, DataLoadTLBMiss, UnknownException)
254 STD_EXCEPTION(0x1200, DataStoreTLBMiss, UnknownException)
255#ifdef DEBUG
256 . = 0x1300
257 /*
258 * This exception occurs when the program counter matches the
259 * Instruction Address Breakpoint Register (IABR).
260 *
261 * I want the cpu to halt if this occurs so I can hunt around
262 * with the debugger and look at things.
263 *
264 * When DEBUG is defined, both machine check enable (in the MSR)
265 * and checkstop reset enable (in the reset mode register) are
266 * turned off and so a checkstop condition will result in the cpu
267 * halting.
268 *
269 * I force the cpu into a checkstop condition by putting an illegal
270 * instruction here (at least this is the theory).
271 *
272 * well - that didnt work, so just do an infinite loop!
273 */
2741: b 1b
275#else
276 STD_EXCEPTION(0x1300, InstructionBreakpoint, DebugException)
277#endif
278 STD_EXCEPTION(0x1400, SMI, UnknownException)
279
280 STD_EXCEPTION(0x1500, Trap_15, UnknownException)
281 STD_EXCEPTION(0x1600, Trap_16, UnknownException)
282 STD_EXCEPTION(0x1700, Trap_17, UnknownException)
283 STD_EXCEPTION(0x1800, Trap_18, UnknownException)
284 STD_EXCEPTION(0x1900, Trap_19, UnknownException)
285 STD_EXCEPTION(0x1a00, Trap_1a, UnknownException)
286 STD_EXCEPTION(0x1b00, Trap_1b, UnknownException)
287 STD_EXCEPTION(0x1c00, Trap_1c, UnknownException)
288 STD_EXCEPTION(0x1d00, Trap_1d, UnknownException)
289 STD_EXCEPTION(0x1e00, Trap_1e, UnknownException)
290 STD_EXCEPTION(0x1f00, Trap_1f, UnknownException)
291 STD_EXCEPTION(0x2000, Trap_20, UnknownException)
292 STD_EXCEPTION(0x2100, Trap_21, UnknownException)
293 STD_EXCEPTION(0x2200, Trap_22, UnknownException)
294 STD_EXCEPTION(0x2300, Trap_23, UnknownException)
295 STD_EXCEPTION(0x2400, Trap_24, UnknownException)
296 STD_EXCEPTION(0x2500, Trap_25, UnknownException)
297 STD_EXCEPTION(0x2600, Trap_26, UnknownException)
298 STD_EXCEPTION(0x2700, Trap_27, UnknownException)
299 STD_EXCEPTION(0x2800, Trap_28, UnknownException)
300 STD_EXCEPTION(0x2900, Trap_29, UnknownException)
301 STD_EXCEPTION(0x2a00, Trap_2a, UnknownException)
302 STD_EXCEPTION(0x2b00, Trap_2b, UnknownException)
303 STD_EXCEPTION(0x2c00, Trap_2c, UnknownException)
304 STD_EXCEPTION(0x2d00, Trap_2d, UnknownException)
305 STD_EXCEPTION(0x2e00, Trap_2e, UnknownException)
306 STD_EXCEPTION(0x2f00, Trap_2f, UnknownException)
307
308
309 .globl _end_of_vectors
310_end_of_vectors:
311
312 . = 0x3000
313
314/*
315 * This code finishes saving the registers to the exception frame
316 * and jumps to the appropriate handler for the exception.
317 * Register r21 is pointer into trap frame, r1 has new stack pointer.
318 */
319 .globl transfer_to_handler
320transfer_to_handler:
321 stw r22,_NIP(r21)
322 lis r22,MSR_POW@h
323 andc r23,r23,r22
324 stw r23,_MSR(r21)
325 SAVE_GPR(7, r21)
326 SAVE_4GPRS(8, r21)
327 SAVE_8GPRS(12, r21)
328 SAVE_8GPRS(24, r21)
329 mflr r23
330 andi. r24,r23,0x3f00 /* get vector offset */
331 stw r24,TRAP(r21)
332 li r22,0
333 stw r22,RESULT(r21)
334 lwz r24,0(r23) /* virtual address of handler */
335 lwz r23,4(r23) /* where to go when done */
336 mtspr SRR0,r24
337 mtspr SRR1,r20
338 mtlr r23
339 SYNC
340 rfi /* jump to handler, enable MMU */
341
342int_return:
343 mfmsr r28 /* Disable interrupts */
344 li r4,0
345 ori r4,r4,MSR_EE
346 andc r28,r28,r4
347 SYNC /* Some chip revs need this... */
348 mtmsr r28
349 SYNC
350 lwz r2,_CTR(r1)
351 lwz r0,_LINK(r1)
352 mtctr r2
353 mtlr r0
354 lwz r2,_XER(r1)
355 lwz r0,_CCR(r1)
356 mtspr XER,r2
357 mtcrf 0xFF,r0
358 REST_10GPRS(3, r1)
359 REST_10GPRS(13, r1)
360 REST_8GPRS(23, r1)
361 REST_GPR(31, r1)
362 lwz r2,_NIP(r1) /* Restore environment */
363 lwz r0,_MSR(r1)
364 mtspr SRR0,r2
365 mtspr SRR1,r0
366 lwz r0,GPR0(r1)
367 lwz r2,GPR2(r1)
368 lwz r1,GPR1(r1)
369 SYNC
370 rfi
371
372/*
373 * This code initialises the MPC5xxx processor core
374 * (conforms to PowerPC 603e spec)
375 * Note: expects original MSR contents to be in r5.
376 */
377
378 .globl init_5xx_core
379init_5xxx_core:
380
381 /* Initialize machine status; enable machine check interrupt */
382 /*--------------------------------------------------------------*/
383
384 li r3, MSR_KERNEL /* Set ME and RI flags */
385 rlwimi r3, r5, 0, 25, 25 /* preserve IP bit set by HRCW */
386#ifdef DEBUG
387 rlwimi r3, r5, 0, 21, 22 /* debugger might set SE & BE bits */
388#endif
389 SYNC /* Some chip revs need this... */
390 mtmsr r3
391 SYNC
392 mtspr SRR1, r3 /* Make SRR1 match MSR */
393
394 /* Initialize the Hardware Implementation-dependent Registers */
395 /* HID0 also contains cache control */
396 /*--------------------------------------------------------------*/
397
398 lis r3, CFG_HID0_INIT@h
399 ori r3, r3, CFG_HID0_INIT@l
400 SYNC
401 mtspr HID0, r3
402
403 lis r3, CFG_HID0_FINAL@h
404 ori r3, r3, CFG_HID0_FINAL@l
405 SYNC
406 mtspr HID0, r3
407
408 /* clear all BAT's */
409 /*--------------------------------------------------------------*/
410
411 li r0, 0
412 mtspr DBAT0U, r0
413 mtspr DBAT0L, r0
414 mtspr DBAT1U, r0
415 mtspr DBAT1L, r0
416 mtspr DBAT2U, r0
417 mtspr DBAT2L, r0
418 mtspr DBAT3U, r0
419 mtspr DBAT3L, r0
wdenk35656de2003-09-14 19:08:39 +0000420 mtspr DBAT4U, r0
421 mtspr DBAT4L, r0
422 mtspr DBAT5U, r0
423 mtspr DBAT5L, r0
424 mtspr DBAT6U, r0
425 mtspr DBAT6L, r0
426 mtspr DBAT7U, r0
427 mtspr DBAT7L, r0
wdenk945af8d2003-07-16 21:53:01 +0000428 mtspr IBAT0U, r0
429 mtspr IBAT0L, r0
430 mtspr IBAT1U, r0
431 mtspr IBAT1L, r0
432 mtspr IBAT2U, r0
433 mtspr IBAT2L, r0
434 mtspr IBAT3U, r0
435 mtspr IBAT3L, r0
wdenk35656de2003-09-14 19:08:39 +0000436 mtspr IBAT4U, r0
437 mtspr IBAT4L, r0
438 mtspr IBAT5U, r0
439 mtspr IBAT5L, r0
440 mtspr IBAT6U, r0
441 mtspr IBAT6L, r0
442 mtspr IBAT7U, r0
443 mtspr IBAT7L, r0
wdenk945af8d2003-07-16 21:53:01 +0000444 SYNC
445
446 /* invalidate all tlb's */
447 /* */
448 /* From the 603e User Manual: "The 603e provides the ability to */
449 /* invalidate a TLB entry. The TLB Invalidate Entry (tlbie) */
450 /* instruction invalidates the TLB entry indexed by the EA, and */
451 /* operates on both the instruction and data TLBs simultaneously*/
452 /* invalidating four TLB entries (both sets in each TLB). The */
453 /* index corresponds to bits 15-19 of the EA. To invalidate all */
454 /* entries within both TLBs, 32 tlbie instructions should be */
455 /* issued, incrementing this field by one each time." */
456 /* */
457 /* "Note that the tlbia instruction is not implemented on the */
458 /* 603e." */
459 /* */
460 /* bits 15-19 correspond to addresses 0x00000000 to 0x0001F000 */
461 /* incrementing by 0x1000 each time. The code below is sort of */
462 /* based on code in "flush_tlbs" from arch/ppc/kernel/head.S */
463 /* */
464 /*--------------------------------------------------------------*/
465
466 li r3, 32
467 mtctr r3
468 li r3, 0
4691: tlbie r3
470 addi r3, r3, 0x1000
471 bdnz 1b
472 SYNC
473
474 /* Done! */
475 /*--------------------------------------------------------------*/
476
477 blr
478
479/* Cache functions.
480 *
481 * Note: requires that all cache bits in
482 * HID0 are in the low half word.
483 */
484 .globl icache_enable
485icache_enable:
486 mfspr r3, HID0
487 ori r3, r3, HID0_ICE
488 lis r4, 0
489 ori r4, r4, HID0_ILOCK
490 andc r3, r3, r4
491 ori r4, r3, HID0_ICFI
492 isync
493 mtspr HID0, r4 /* sets enable and invalidate, clears lock */
494 isync
495 mtspr HID0, r3 /* clears invalidate */
496 blr
497
498 .globl icache_disable
499icache_disable:
500 mfspr r3, HID0
501 lis r4, 0
502 ori r4, r4, HID0_ICE|HID0_ILOCK
503 andc r3, r3, r4
504 ori r4, r3, HID0_ICFI
505 isync
506 mtspr HID0, r4 /* sets invalidate, clears enable and lock */
507 isync
508 mtspr HID0, r3 /* clears invalidate */
509 blr
510
511 .globl icache_status
512icache_status:
513 mfspr r3, HID0
514 rlwinm r3, r3, HID0_ICE_BITPOS + 1, 31, 31
515 blr
516
517 .globl dcache_enable
518dcache_enable:
519 mfspr r3, HID0
520 ori r3, r3, HID0_DCE
521 lis r4, 0
522 ori r4, r4, HID0_DLOCK
523 andc r3, r3, r4
524 ori r4, r3, HID0_DCI
525 sync
526 mtspr HID0, r4 /* sets enable and invalidate, clears lock */
527 sync
528 mtspr HID0, r3 /* clears invalidate */
529 blr
530
531 .globl dcache_disable
532dcache_disable:
533 mfspr r3, HID0
534 lis r4, 0
535 ori r4, r4, HID0_DCE|HID0_DLOCK
536 andc r3, r3, r4
537 ori r4, r3, HID0_DCI
538 sync
539 mtspr HID0, r4 /* sets invalidate, clears enable and lock */
540 sync
541 mtspr HID0, r3 /* clears invalidate */
542 blr
543
544 .globl dcache_status
545dcache_status:
546 mfspr r3, HID0
547 rlwinm r3, r3, HID0_DCE_BITPOS + 1, 31, 31
548 blr
549
550 .globl get_pvr
551get_pvr:
552 mfspr r3, PVR
553 blr
554
555/*------------------------------------------------------------------------------*/
556
557/*
558 * void relocate_code (addr_sp, gd, addr_moni)
559 *
560 * This "function" does not return, instead it continues in RAM
561 * after relocating the monitor code.
562 *
563 * r3 = dest
564 * r4 = src
565 * r5 = length in bytes
566 * r6 = cachelinesize
567 */
568 .globl relocate_code
569relocate_code:
570 mr r1, r3 /* Set new stack pointer */
571 mr r9, r4 /* Save copy of Global Data pointer */
572 mr r10, r5 /* Save copy of Destination Address */
573
574 mr r3, r5 /* Destination Address */
575 lis r4, CFG_MONITOR_BASE@h /* Source Address */
576 ori r4, r4, CFG_MONITOR_BASE@l
577 lwz r5, GOT(__init_end)
578 sub r5, r5, r4
579 li r6, CFG_CACHELINE_SIZE /* Cache Line Size */
580
581 /*
582 * Fix GOT pointer:
583 *
584 * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address
585 *
586 * Offset:
587 */
588 sub r15, r10, r4
589
590 /* First our own GOT */
591 add r14, r14, r15
592 /* then the one used by the C code */
593 add r30, r30, r15
594
595 /*
596 * Now relocate code
597 */
598
599 cmplw cr1,r3,r4
600 addi r0,r5,3
601 srwi. r0,r0,2
602 beq cr1,4f /* In place copy is not necessary */
603 beq 7f /* Protect against 0 count */
604 mtctr r0
605 bge cr1,2f
606
607 la r8,-4(r4)
608 la r7,-4(r3)
6091: lwzu r0,4(r8)
610 stwu r0,4(r7)
611 bdnz 1b
612 b 4f
613
6142: slwi r0,r0,2
615 add r8,r4,r0
616 add r7,r3,r0
6173: lwzu r0,-4(r8)
618 stwu r0,-4(r7)
619 bdnz 3b
620
621/*
622 * Now flush the cache: note that we must start from a cache aligned
623 * address. Otherwise we might miss one cache line.
624 */
6254: cmpwi r6,0
626 add r5,r3,r5
627 beq 7f /* Always flush prefetch queue in any case */
628 subi r0,r6,1
629 andc r3,r3,r0
630 mfspr r7,HID0 /* don't do dcbst if dcache is disabled */
631 rlwinm r7,r7,HID0_DCE_BITPOS+1,31,31
632 cmpwi r7,0
633 beq 9f
634 mr r4,r3
6355: dcbst 0,r4
636 add r4,r4,r6
637 cmplw r4,r5
638 blt 5b
639 sync /* Wait for all dcbst to complete on bus */
6409: mfspr r7,HID0 /* don't do icbi if icache is disabled */
641 rlwinm r7,r7,HID0_ICE_BITPOS+1,31,31
642 cmpwi r7,0
643 beq 7f
644 mr r4,r3
6456: icbi 0,r4
646 add r4,r4,r6
647 cmplw r4,r5
648 blt 6b
6497: sync /* Wait for all icbi to complete on bus */
650 isync
651
652/*
653 * We are done. Do not return, instead branch to second part of board
654 * initialization, now running from RAM.
655 */
656
657 addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
658 mtlr r0
659 blr
660
661in_ram:
662
663 /*
664 * Relocation Function, r14 point to got2+0x8000
665 *
666 * Adjust got2 pointers, no need to check for 0, this code
667 * already puts a few entries in the table.
668 */
669 li r0,__got2_entries@sectoff@l
670 la r3,GOT(_GOT2_TABLE_)
671 lwz r11,GOT(_GOT2_TABLE_)
672 mtctr r0
673 sub r11,r3,r11
674 addi r3,r3,-4
6751: lwzu r0,4(r3)
676 add r0,r0,r11
677 stw r0,0(r3)
678 bdnz 1b
679
680 /*
681 * Now adjust the fixups and the pointers to the fixups
682 * in case we need to move ourselves again.
683 */
6842: li r0,__fixup_entries@sectoff@l
685 lwz r3,GOT(_FIXUP_TABLE_)
686 cmpwi r0,0
687 mtctr r0
688 addi r3,r3,-4
689 beq 4f
6903: lwzu r4,4(r3)
691 lwzux r0,r4,r11
692 add r0,r0,r11
693 stw r10,0(r3)
694 stw r0,0(r4)
695 bdnz 3b
6964:
697clear_bss:
698 /*
699 * Now clear BSS segment
700 */
701 lwz r3,GOT(__bss_start)
702 lwz r4,GOT(_end)
703
704 cmplw 0, r3, r4
705 beq 6f
706
707 li r0, 0
7085:
709 stw r0, 0(r3)
710 addi r3, r3, 4
711 cmplw 0, r3, r4
712 bne 5b
7136:
714
715 mr r3, r9 /* Global Data pointer */
716 mr r4, r10 /* Destination Address */
717 bl board_init_r
718
719 /*
720 * Copy exception vector code to low memory
721 *
722 * r3: dest_addr
723 * r7: source address, r8: end address, r9: target address
724 */
725 .globl trap_init
726trap_init:
727 lwz r7, GOT(_start)
728 lwz r8, GOT(_end_of_vectors)
729
730 li r9, 0x100 /* reset vector always at 0x100 */
731
732 cmplw 0, r7, r8
733 bgelr /* return if r7>=r8 - just in case */
734
735 mflr r4 /* save link register */
7361:
737 lwz r0, 0(r7)
738 stw r0, 0(r9)
739 addi r7, r7, 4
740 addi r9, r9, 4
741 cmplw 0, r7, r8
742 bne 1b
743
744 /*
745 * relocate `hdlr' and `int_return' entries
746 */
747 li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
748 li r8, Alignment - _start + EXC_OFF_SYS_RESET
7492:
750 bl trap_reloc
751 addi r7, r7, 0x100 /* next exception vector */
752 cmplw 0, r7, r8
753 blt 2b
754
755 li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
756 bl trap_reloc
757
758 li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
759 bl trap_reloc
760
761 li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
762 li r8, SystemCall - _start + EXC_OFF_SYS_RESET
7633:
764 bl trap_reloc
765 addi r7, r7, 0x100 /* next exception vector */
766 cmplw 0, r7, r8
767 blt 3b
768
769 li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
770 li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
7714:
772 bl trap_reloc
773 addi r7, r7, 0x100 /* next exception vector */
774 cmplw 0, r7, r8
775 blt 4b
776
777 mfmsr r3 /* now that the vectors have */
778 lis r7, MSR_IP@h /* relocated into low memory */
779 ori r7, r7, MSR_IP@l /* MSR[IP] can be turned off */
780 andc r3, r3, r7 /* (if it was on) */
781 SYNC /* Some chip revs need this... */
782 mtmsr r3
783 SYNC
784
785 mtlr r4 /* restore link register */
786 blr
787
788 /*
789 * Function: relocate entries for one exception vector
790 */
791trap_reloc:
792 lwz r0, 0(r7) /* hdlr ... */
793 add r0, r0, r3 /* ... += dest_addr */
794 stw r0, 0(r7)
795
796 lwz r0, 4(r7) /* int_return ... */
797 add r0, r0, r3 /* ... += dest_addr */
798 stw r0, 4(r7)
799
800 blr