blob: 26811e11ad7606cd040069bbb86cc745f2987e78 [file] [log] [blame]
wdenk21136db2003-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
wdenk4b16c2e2003-11-07 13:42:26 +0000106#if defined(CFG_LOWBOOT)
wdenkca262162004-02-09 20:51:26 +0000107#if defined(CFG_RAMBOOT)
108#error CFG_LOWBOOT is incompatible with CFG_RAMBOOT
109#endif /* CFG_RAMBOOT */
wdenk4b16c2e2003-11-07 13:42:26 +0000110 lis r4, CFG_DEFAULT_MBAR@h
111 lis r3, 0x0000FF00@h
112 ori r3, r3, 0x0000FF00@l
113 stw r3, 0x4(r4)
114 lis r3, 0x0000FFFF@h
115 ori r3, r3, 0x0000FFFF@l
116 stw r3, 0x8(r4)
117 lis r3, 0x00047800@h
118 ori r3, r3, 0x00047800@l
119 stw r3, 0x300(r4)
120 lis r3, 0x02010000@h
121 ori r3, r3, 0x02010000@l
122 stw r3, 0x54(r4)
123
wdenk1ebf41e2004-01-02 14:00:00 +0000124 lis r3, lowboot_reentry@h
125 ori r3, r3, lowboot_reentry@l
wdenk4b16c2e2003-11-07 13:42:26 +0000126 mtlr r3
wdenk1ebf41e2004-01-02 14:00:00 +0000127 blr /* jump to flash based address */
128
129lowboot_reentry:
wdenk4b16c2e2003-11-07 13:42:26 +0000130 lis r3, 0x0000FF00@h
131 ori r3, r3, 0x0000FF00@l
132 stw r3, 0x4c(r4)
133 lis r3, 0x0000FFFF@h
134 ori r3, r3, 0x0000FFFF@l
135 stw r3, 0x50(r4)
136 lis r3, 0x00047800@h
137 ori r3, r3, 0x00047800@l
138 stw r3, 0x300(r4)
139 lis r3, 0x02000001@h
140 ori r3, r3, 0x02000001@l
141 stw r3, 0x54(r4)
142#endif /* CFG_LOWBOOT */
wdenk1ebf41e2004-01-02 14:00:00 +0000143
wdenk5d841732003-08-17 18:55:18 +0000144#if defined(CFG_DEFAULT_MBAR) && !defined(CFG_RAMBOOT)
wdenk21136db2003-07-16 21:53:01 +0000145 lis r3, CFG_MBAR@h
146 ori r3, r3, CFG_MBAR@l
147#if defined(CONFIG_MPC5200)
148 rlwinm r3, r3, 16, 16, 31
149#endif
150#if defined(CONFIG_MGT5100)
151 rlwinm r3, r3, 17, 15, 31
152#endif
153 lis r4, CFG_DEFAULT_MBAR@h
154 stw r3, 0(r4)
155#endif /* CFG_DEFAULT_MBAR */
156
157 /* Initialise the MPC5xxx processor core */
158 /*--------------------------------------------------------------*/
159
160 bl init_5xxx_core
161
162 /* initialize some things that are hard to access from C */
163 /*--------------------------------------------------------------*/
164
165 /* set up stack in on-chip SRAM */
166 lis r3, CFG_INIT_RAM_ADDR@h
167 ori r3, r3, CFG_INIT_RAM_ADDR@l
168 ori r1, r3, CFG_INIT_SP_OFFSET
169 li r0, 0 /* Make room for stack frame header and */
170 stwu r0, -4(r1) /* clear final stack frame so that */
171 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
172
173 /* let the C-code set up the rest */
174 /* */
175 /* Be careful to keep code relocatable ! */
176 /*--------------------------------------------------------------*/
177
178 GET_GOT /* initialize GOT access */
179
180 /* r3: IMMR */
181 bl cpu_init_f /* run low-level CPU init code (in Flash)*/
182
183 mr r3, r21
184 /* r3: BOOTFLAG */
185 bl board_init_f /* run 1st part of board init code (in Flash)*/
186
187/*
188 * Vector Table
189 */
190
191 .globl _start_of_vectors
192_start_of_vectors:
193
194/* Machine check */
195 STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)
196
197/* Data Storage exception. */
198 STD_EXCEPTION(0x300, DataStorage, UnknownException)
199
200/* Instruction Storage exception. */
201 STD_EXCEPTION(0x400, InstStorage, UnknownException)
202
203/* External Interrupt exception. */
204 STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
205
206/* Alignment exception. */
207 . = 0x600
208Alignment:
209 EXCEPTION_PROLOG
210 mfspr r4,DAR
211 stw r4,_DAR(r21)
212 mfspr r5,DSISR
213 stw r5,_DSISR(r21)
214 addi r3,r1,STACK_FRAME_OVERHEAD
215 li r20,MSR_KERNEL
216 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
217 rlwimi r20,r23,0,25,25 /* copy IP bit from saved MSR */
218 lwz r6,GOT(transfer_to_handler)
219 mtlr r6
220 blrl
221.L_Alignment:
222 .long AlignmentException - _start + EXC_OFF_SYS_RESET
223 .long int_return - _start + EXC_OFF_SYS_RESET
224
225/* Program check exception */
226 . = 0x700
227ProgramCheck:
228 EXCEPTION_PROLOG
229 addi r3,r1,STACK_FRAME_OVERHEAD
230 li r20,MSR_KERNEL
231 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
232 rlwimi r20,r23,0,25,25 /* copy IP bit from saved MSR */
233 lwz r6,GOT(transfer_to_handler)
234 mtlr r6
235 blrl
236.L_ProgramCheck:
237 .long ProgramCheckException - _start + EXC_OFF_SYS_RESET
238 .long int_return - _start + EXC_OFF_SYS_RESET
239
240 STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
241
242 /* I guess we could implement decrementer, and may have
243 * to someday for timekeeping.
244 */
245 STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
246
247 STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
248 STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
wdenk874ac262003-07-24 23:38:38 +0000249 STD_EXCEPTION(0xc00, SystemCall, UnknownException)
wdenk21136db2003-07-16 21:53:01 +0000250 STD_EXCEPTION(0xd00, SingleStep, UnknownException)
251
252 STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
253 STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
254
255 STD_EXCEPTION(0x1000, InstructionTLBMiss, UnknownException)
256 STD_EXCEPTION(0x1100, DataLoadTLBMiss, UnknownException)
257 STD_EXCEPTION(0x1200, DataStoreTLBMiss, UnknownException)
258#ifdef DEBUG
259 . = 0x1300
260 /*
261 * This exception occurs when the program counter matches the
262 * Instruction Address Breakpoint Register (IABR).
263 *
264 * I want the cpu to halt if this occurs so I can hunt around
265 * with the debugger and look at things.
266 *
267 * When DEBUG is defined, both machine check enable (in the MSR)
268 * and checkstop reset enable (in the reset mode register) are
269 * turned off and so a checkstop condition will result in the cpu
270 * halting.
271 *
272 * I force the cpu into a checkstop condition by putting an illegal
273 * instruction here (at least this is the theory).
274 *
275 * well - that didnt work, so just do an infinite loop!
276 */
2771: b 1b
278#else
279 STD_EXCEPTION(0x1300, InstructionBreakpoint, DebugException)
280#endif
281 STD_EXCEPTION(0x1400, SMI, UnknownException)
282
283 STD_EXCEPTION(0x1500, Trap_15, UnknownException)
284 STD_EXCEPTION(0x1600, Trap_16, UnknownException)
285 STD_EXCEPTION(0x1700, Trap_17, UnknownException)
286 STD_EXCEPTION(0x1800, Trap_18, UnknownException)
287 STD_EXCEPTION(0x1900, Trap_19, UnknownException)
288 STD_EXCEPTION(0x1a00, Trap_1a, UnknownException)
289 STD_EXCEPTION(0x1b00, Trap_1b, UnknownException)
290 STD_EXCEPTION(0x1c00, Trap_1c, UnknownException)
291 STD_EXCEPTION(0x1d00, Trap_1d, UnknownException)
292 STD_EXCEPTION(0x1e00, Trap_1e, UnknownException)
293 STD_EXCEPTION(0x1f00, Trap_1f, UnknownException)
294 STD_EXCEPTION(0x2000, Trap_20, UnknownException)
295 STD_EXCEPTION(0x2100, Trap_21, UnknownException)
296 STD_EXCEPTION(0x2200, Trap_22, UnknownException)
297 STD_EXCEPTION(0x2300, Trap_23, UnknownException)
298 STD_EXCEPTION(0x2400, Trap_24, UnknownException)
299 STD_EXCEPTION(0x2500, Trap_25, UnknownException)
300 STD_EXCEPTION(0x2600, Trap_26, UnknownException)
301 STD_EXCEPTION(0x2700, Trap_27, UnknownException)
302 STD_EXCEPTION(0x2800, Trap_28, UnknownException)
303 STD_EXCEPTION(0x2900, Trap_29, UnknownException)
304 STD_EXCEPTION(0x2a00, Trap_2a, UnknownException)
305 STD_EXCEPTION(0x2b00, Trap_2b, UnknownException)
306 STD_EXCEPTION(0x2c00, Trap_2c, UnknownException)
307 STD_EXCEPTION(0x2d00, Trap_2d, UnknownException)
308 STD_EXCEPTION(0x2e00, Trap_2e, UnknownException)
309 STD_EXCEPTION(0x2f00, Trap_2f, UnknownException)
310
311
312 .globl _end_of_vectors
313_end_of_vectors:
314
315 . = 0x3000
316
317/*
318 * This code finishes saving the registers to the exception frame
319 * and jumps to the appropriate handler for the exception.
320 * Register r21 is pointer into trap frame, r1 has new stack pointer.
321 */
322 .globl transfer_to_handler
323transfer_to_handler:
324 stw r22,_NIP(r21)
325 lis r22,MSR_POW@h
326 andc r23,r23,r22
327 stw r23,_MSR(r21)
328 SAVE_GPR(7, r21)
329 SAVE_4GPRS(8, r21)
330 SAVE_8GPRS(12, r21)
331 SAVE_8GPRS(24, r21)
332 mflr r23
333 andi. r24,r23,0x3f00 /* get vector offset */
334 stw r24,TRAP(r21)
335 li r22,0
336 stw r22,RESULT(r21)
337 lwz r24,0(r23) /* virtual address of handler */
338 lwz r23,4(r23) /* where to go when done */
339 mtspr SRR0,r24
340 mtspr SRR1,r20
341 mtlr r23
342 SYNC
343 rfi /* jump to handler, enable MMU */
344
345int_return:
346 mfmsr r28 /* Disable interrupts */
347 li r4,0
348 ori r4,r4,MSR_EE
349 andc r28,r28,r4
350 SYNC /* Some chip revs need this... */
351 mtmsr r28
352 SYNC
353 lwz r2,_CTR(r1)
354 lwz r0,_LINK(r1)
355 mtctr r2
356 mtlr r0
357 lwz r2,_XER(r1)
358 lwz r0,_CCR(r1)
359 mtspr XER,r2
360 mtcrf 0xFF,r0
361 REST_10GPRS(3, r1)
362 REST_10GPRS(13, r1)
363 REST_8GPRS(23, r1)
364 REST_GPR(31, r1)
365 lwz r2,_NIP(r1) /* Restore environment */
366 lwz r0,_MSR(r1)
367 mtspr SRR0,r2
368 mtspr SRR1,r0
369 lwz r0,GPR0(r1)
370 lwz r2,GPR2(r1)
371 lwz r1,GPR1(r1)
372 SYNC
373 rfi
374
375/*
376 * This code initialises the MPC5xxx processor core
377 * (conforms to PowerPC 603e spec)
378 * Note: expects original MSR contents to be in r5.
379 */
380
381 .globl init_5xx_core
382init_5xxx_core:
383
384 /* Initialize machine status; enable machine check interrupt */
385 /*--------------------------------------------------------------*/
386
387 li r3, MSR_KERNEL /* Set ME and RI flags */
388 rlwimi r3, r5, 0, 25, 25 /* preserve IP bit set by HRCW */
389#ifdef DEBUG
390 rlwimi r3, r5, 0, 21, 22 /* debugger might set SE & BE bits */
391#endif
392 SYNC /* Some chip revs need this... */
393 mtmsr r3
394 SYNC
395 mtspr SRR1, r3 /* Make SRR1 match MSR */
396
397 /* Initialize the Hardware Implementation-dependent Registers */
398 /* HID0 also contains cache control */
399 /*--------------------------------------------------------------*/
400
401 lis r3, CFG_HID0_INIT@h
402 ori r3, r3, CFG_HID0_INIT@l
403 SYNC
404 mtspr HID0, r3
405
406 lis r3, CFG_HID0_FINAL@h
407 ori r3, r3, CFG_HID0_FINAL@l
408 SYNC
409 mtspr HID0, r3
410
411 /* clear all BAT's */
412 /*--------------------------------------------------------------*/
413
414 li r0, 0
415 mtspr DBAT0U, r0
416 mtspr DBAT0L, r0
417 mtspr DBAT1U, r0
418 mtspr DBAT1L, r0
419 mtspr DBAT2U, r0
420 mtspr DBAT2L, r0
421 mtspr DBAT3U, r0
422 mtspr DBAT3L, r0
wdenkfc314ce2003-09-14 19:08:39 +0000423 mtspr DBAT4U, r0
424 mtspr DBAT4L, r0
425 mtspr DBAT5U, r0
426 mtspr DBAT5L, r0
427 mtspr DBAT6U, r0
428 mtspr DBAT6L, r0
429 mtspr DBAT7U, r0
430 mtspr DBAT7L, r0
wdenk21136db2003-07-16 21:53:01 +0000431 mtspr IBAT0U, r0
432 mtspr IBAT0L, r0
433 mtspr IBAT1U, r0
434 mtspr IBAT1L, r0
435 mtspr IBAT2U, r0
436 mtspr IBAT2L, r0
437 mtspr IBAT3U, r0
438 mtspr IBAT3L, r0
wdenkfc314ce2003-09-14 19:08:39 +0000439 mtspr IBAT4U, r0
440 mtspr IBAT4L, r0
441 mtspr IBAT5U, r0
442 mtspr IBAT5L, r0
443 mtspr IBAT6U, r0
444 mtspr IBAT6L, r0
445 mtspr IBAT7U, r0
446 mtspr IBAT7L, r0
wdenk21136db2003-07-16 21:53:01 +0000447 SYNC
448
449 /* invalidate all tlb's */
450 /* */
451 /* From the 603e User Manual: "The 603e provides the ability to */
452 /* invalidate a TLB entry. The TLB Invalidate Entry (tlbie) */
453 /* instruction invalidates the TLB entry indexed by the EA, and */
454 /* operates on both the instruction and data TLBs simultaneously*/
455 /* invalidating four TLB entries (both sets in each TLB). The */
456 /* index corresponds to bits 15-19 of the EA. To invalidate all */
457 /* entries within both TLBs, 32 tlbie instructions should be */
458 /* issued, incrementing this field by one each time." */
459 /* */
460 /* "Note that the tlbia instruction is not implemented on the */
461 /* 603e." */
462 /* */
463 /* bits 15-19 correspond to addresses 0x00000000 to 0x0001F000 */
464 /* incrementing by 0x1000 each time. The code below is sort of */
465 /* based on code in "flush_tlbs" from arch/ppc/kernel/head.S */
466 /* */
467 /*--------------------------------------------------------------*/
468
469 li r3, 32
470 mtctr r3
471 li r3, 0
4721: tlbie r3
473 addi r3, r3, 0x1000
474 bdnz 1b
475 SYNC
476
477 /* Done! */
478 /*--------------------------------------------------------------*/
479
480 blr
481
482/* Cache functions.
483 *
484 * Note: requires that all cache bits in
485 * HID0 are in the low half word.
486 */
487 .globl icache_enable
488icache_enable:
489 mfspr r3, HID0
490 ori r3, r3, HID0_ICE
491 lis r4, 0
492 ori r4, r4, HID0_ILOCK
493 andc r3, r3, r4
494 ori r4, r3, HID0_ICFI
495 isync
496 mtspr HID0, r4 /* sets enable and invalidate, clears lock */
497 isync
498 mtspr HID0, r3 /* clears invalidate */
499 blr
500
501 .globl icache_disable
502icache_disable:
503 mfspr r3, HID0
504 lis r4, 0
505 ori r4, r4, HID0_ICE|HID0_ILOCK
506 andc r3, r3, r4
507 ori r4, r3, HID0_ICFI
508 isync
509 mtspr HID0, r4 /* sets invalidate, clears enable and lock */
510 isync
511 mtspr HID0, r3 /* clears invalidate */
512 blr
513
514 .globl icache_status
515icache_status:
516 mfspr r3, HID0
517 rlwinm r3, r3, HID0_ICE_BITPOS + 1, 31, 31
518 blr
519
520 .globl dcache_enable
521dcache_enable:
522 mfspr r3, HID0
523 ori r3, r3, HID0_DCE
524 lis r4, 0
525 ori r4, r4, HID0_DLOCK
526 andc r3, r3, r4
527 ori r4, r3, HID0_DCI
528 sync
529 mtspr HID0, r4 /* sets enable and invalidate, clears lock */
530 sync
531 mtspr HID0, r3 /* clears invalidate */
532 blr
533
534 .globl dcache_disable
535dcache_disable:
536 mfspr r3, HID0
537 lis r4, 0
538 ori r4, r4, HID0_DCE|HID0_DLOCK
539 andc r3, r3, r4
540 ori r4, r3, HID0_DCI
541 sync
542 mtspr HID0, r4 /* sets invalidate, clears enable and lock */
543 sync
544 mtspr HID0, r3 /* clears invalidate */
545 blr
546
547 .globl dcache_status
548dcache_status:
549 mfspr r3, HID0
550 rlwinm r3, r3, HID0_DCE_BITPOS + 1, 31, 31
551 blr
552
553 .globl get_pvr
554get_pvr:
555 mfspr r3, PVR
556 blr
557
558/*------------------------------------------------------------------------------*/
559
560/*
561 * void relocate_code (addr_sp, gd, addr_moni)
562 *
563 * This "function" does not return, instead it continues in RAM
564 * after relocating the monitor code.
565 *
566 * r3 = dest
567 * r4 = src
568 * r5 = length in bytes
569 * r6 = cachelinesize
570 */
571 .globl relocate_code
572relocate_code:
573 mr r1, r3 /* Set new stack pointer */
574 mr r9, r4 /* Save copy of Global Data pointer */
575 mr r10, r5 /* Save copy of Destination Address */
576
577 mr r3, r5 /* Destination Address */
578 lis r4, CFG_MONITOR_BASE@h /* Source Address */
579 ori r4, r4, CFG_MONITOR_BASE@l
580 lwz r5, GOT(__init_end)
581 sub r5, r5, r4
582 li r6, CFG_CACHELINE_SIZE /* Cache Line Size */
583
584 /*
585 * Fix GOT pointer:
586 *
587 * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address
588 *
589 * Offset:
590 */
591 sub r15, r10, r4
592
593 /* First our own GOT */
594 add r14, r14, r15
595 /* then the one used by the C code */
596 add r30, r30, r15
597
598 /*
599 * Now relocate code
600 */
601
602 cmplw cr1,r3,r4
603 addi r0,r5,3
604 srwi. r0,r0,2
605 beq cr1,4f /* In place copy is not necessary */
606 beq 7f /* Protect against 0 count */
607 mtctr r0
608 bge cr1,2f
609
610 la r8,-4(r4)
611 la r7,-4(r3)
6121: lwzu r0,4(r8)
613 stwu r0,4(r7)
614 bdnz 1b
615 b 4f
616
6172: slwi r0,r0,2
618 add r8,r4,r0
619 add r7,r3,r0
6203: lwzu r0,-4(r8)
621 stwu r0,-4(r7)
622 bdnz 3b
623
624/*
625 * Now flush the cache: note that we must start from a cache aligned
626 * address. Otherwise we might miss one cache line.
627 */
6284: cmpwi r6,0
629 add r5,r3,r5
630 beq 7f /* Always flush prefetch queue in any case */
631 subi r0,r6,1
632 andc r3,r3,r0
633 mfspr r7,HID0 /* don't do dcbst if dcache is disabled */
634 rlwinm r7,r7,HID0_DCE_BITPOS+1,31,31
635 cmpwi r7,0
636 beq 9f
637 mr r4,r3
6385: dcbst 0,r4
639 add r4,r4,r6
640 cmplw r4,r5
641 blt 5b
642 sync /* Wait for all dcbst to complete on bus */
6439: mfspr r7,HID0 /* don't do icbi if icache is disabled */
644 rlwinm r7,r7,HID0_ICE_BITPOS+1,31,31
645 cmpwi r7,0
646 beq 7f
647 mr r4,r3
6486: icbi 0,r4
649 add r4,r4,r6
650 cmplw r4,r5
651 blt 6b
6527: sync /* Wait for all icbi to complete on bus */
653 isync
654
655/*
656 * We are done. Do not return, instead branch to second part of board
657 * initialization, now running from RAM.
658 */
659
660 addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
661 mtlr r0
662 blr
663
664in_ram:
665
666 /*
667 * Relocation Function, r14 point to got2+0x8000
668 *
669 * Adjust got2 pointers, no need to check for 0, this code
670 * already puts a few entries in the table.
671 */
672 li r0,__got2_entries@sectoff@l
673 la r3,GOT(_GOT2_TABLE_)
674 lwz r11,GOT(_GOT2_TABLE_)
675 mtctr r0
676 sub r11,r3,r11
677 addi r3,r3,-4
6781: lwzu r0,4(r3)
679 add r0,r0,r11
680 stw r0,0(r3)
681 bdnz 1b
682
683 /*
684 * Now adjust the fixups and the pointers to the fixups
685 * in case we need to move ourselves again.
686 */
6872: li r0,__fixup_entries@sectoff@l
688 lwz r3,GOT(_FIXUP_TABLE_)
689 cmpwi r0,0
690 mtctr r0
691 addi r3,r3,-4
692 beq 4f
6933: lwzu r4,4(r3)
694 lwzux r0,r4,r11
695 add r0,r0,r11
696 stw r10,0(r3)
697 stw r0,0(r4)
698 bdnz 3b
6994:
700clear_bss:
701 /*
702 * Now clear BSS segment
703 */
704 lwz r3,GOT(__bss_start)
705 lwz r4,GOT(_end)
706
707 cmplw 0, r3, r4
708 beq 6f
709
710 li r0, 0
7115:
712 stw r0, 0(r3)
713 addi r3, r3, 4
714 cmplw 0, r3, r4
715 bne 5b
7166:
717
718 mr r3, r9 /* Global Data pointer */
719 mr r4, r10 /* Destination Address */
720 bl board_init_r
721
722 /*
723 * Copy exception vector code to low memory
724 *
725 * r3: dest_addr
726 * r7: source address, r8: end address, r9: target address
727 */
728 .globl trap_init
729trap_init:
730 lwz r7, GOT(_start)
731 lwz r8, GOT(_end_of_vectors)
732
733 li r9, 0x100 /* reset vector always at 0x100 */
734
735 cmplw 0, r7, r8
736 bgelr /* return if r7>=r8 - just in case */
737
738 mflr r4 /* save link register */
7391:
740 lwz r0, 0(r7)
741 stw r0, 0(r9)
742 addi r7, r7, 4
743 addi r9, r9, 4
744 cmplw 0, r7, r8
745 bne 1b
746
747 /*
748 * relocate `hdlr' and `int_return' entries
749 */
750 li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
751 li r8, Alignment - _start + EXC_OFF_SYS_RESET
7522:
753 bl trap_reloc
754 addi r7, r7, 0x100 /* next exception vector */
755 cmplw 0, r7, r8
756 blt 2b
757
758 li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
759 bl trap_reloc
760
761 li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
762 bl trap_reloc
763
764 li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
765 li r8, SystemCall - _start + EXC_OFF_SYS_RESET
7663:
767 bl trap_reloc
768 addi r7, r7, 0x100 /* next exception vector */
769 cmplw 0, r7, r8
770 blt 3b
771
772 li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
773 li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
7744:
775 bl trap_reloc
776 addi r7, r7, 0x100 /* next exception vector */
777 cmplw 0, r7, r8
778 blt 4b
779
780 mfmsr r3 /* now that the vectors have */
781 lis r7, MSR_IP@h /* relocated into low memory */
782 ori r7, r7, MSR_IP@l /* MSR[IP] can be turned off */
783 andc r3, r3, r7 /* (if it was on) */
784 SYNC /* Some chip revs need this... */
785 mtmsr r3
786 SYNC
787
788 mtlr r4 /* restore link register */
789 blr
790
791 /*
792 * Function: relocate entries for one exception vector
793 */
794trap_reloc:
795 lwz r0, 0(r7) /* hdlr ... */
796 add r0, r0, r3 /* ... += dest_addr */
797 stw r0, 0(r7)
798
799 lwz r0, 4(r7) /* int_return ... */
800 add r0, r0, r3 /* ... += dest_addr */
801 stw r0, 4(r7)
802
803 blr