blob: 5218c859dfc60a66f251f0751b2c5faefb9ce0ca [file] [log] [blame]
wdenk983fda82004-10-28 00:09:35 +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 MPC8220 CPUs
27 */
28#include <config.h>
29#include <mpc8220.h>
Peter Tyser561858e2008-11-03 09:30:59 -060030#include <timestamp.h>
wdenk983fda82004-10-28 00:09:35 +000031#include <version.h>
32
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
Peter Tyser561858e2008-11-03 09:30:59 -060081 .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")"
wdenk983fda82004-10-28 00:09:35 +000082 .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
106 /* replace default MBAR base address from 0x80000000
107 to 0xf0000000 */
108
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200109#if defined(CONFIG_SYS_DEFAULT_MBAR) && !defined(CONFIG_SYS_RAMBOOT)
110 lis r3, CONFIG_SYS_MBAR@h
111 ori r3, r3, CONFIG_SYS_MBAR@l
wdenk983fda82004-10-28 00:09:35 +0000112
113 /* MBAR is mirrored into the MBAR SPR */
114 mtspr MBAR,r3
wdenk3c2b3d42005-04-05 23:32:21 +0000115 mtspr SPRN_SPRG7W,r3
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200116 lis r4, CONFIG_SYS_DEFAULT_MBAR@h
wdenk983fda82004-10-28 00:09:35 +0000117 stw r3, 0(r4)
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200118#endif /* CONFIG_SYS_DEFAULT_MBAR */
wdenk983fda82004-10-28 00:09:35 +0000119
120 /* Initialise the MPC8220 processor core */
121 /*--------------------------------------------------------------*/
122
123 bl init_8220_core
124
125 /* initialize some things that are hard to access from C */
126 /*--------------------------------------------------------------*/
127
128 /* set up stack in on-chip SRAM */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200129 lis r3, CONFIG_SYS_INIT_RAM_ADDR@h
130 ori r3, r3, CONFIG_SYS_INIT_RAM_ADDR@l
131 ori r1, r3, CONFIG_SYS_INIT_SP_OFFSET
wdenk983fda82004-10-28 00:09:35 +0000132
133 li r0, 0 /* Make room for stack frame header and */
134 stwu r0, -4(r1) /* clear final stack frame so that */
135 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
136
137 /* let the C-code set up the rest */
138 /* */
139 /* Be careful to keep code relocatable ! */
140 /*--------------------------------------------------------------*/
141
142 GET_GOT /* initialize GOT access */
143
144 /* r3: IMMR */
145 bl cpu_init_f /* run low-level CPU init code (in Flash)*/
146
147 mr r3, r21
148 /* r3: BOOTFLAG */
149 bl board_init_f /* run 1st part of board init code (in Flash)*/
150
151/*
152 * Vector Table
153 */
154
155 .globl _start_of_vectors
156_start_of_vectors:
157
158/* Machine check */
159 STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)
160
161/* Data Storage exception. */
162 STD_EXCEPTION(0x300, DataStorage, UnknownException)
163
164/* Instruction Storage exception. */
165 STD_EXCEPTION(0x400, InstStorage, UnknownException)
166
167/* External Interrupt exception. */
168 STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
169
170/* Alignment exception. */
171 . = 0x600
172Alignment:
Rafal Jaworowski02032e82007-06-22 14:58:04 +0200173 EXCEPTION_PROLOG(SRR0, SRR1)
wdenk983fda82004-10-28 00:09:35 +0000174 mfspr r4,DAR
175 stw r4,_DAR(r21)
176 mfspr r5,DSISR
177 stw r5,_DSISR(r21)
178 addi r3,r1,STACK_FRAME_OVERHEAD
Joakim Tjernlundfc4e1882010-01-19 14:41:55 +0100179 EXC_XFER_TEMPLATE(Alignment, AlignmentException, MSR_KERNEL, COPY_EE)
wdenk983fda82004-10-28 00:09:35 +0000180
181/* Program check exception */
182 . = 0x700
183ProgramCheck:
Rafal Jaworowski02032e82007-06-22 14:58:04 +0200184 EXCEPTION_PROLOG(SRR0, SRR1)
wdenk983fda82004-10-28 00:09:35 +0000185 addi r3,r1,STACK_FRAME_OVERHEAD
Joakim Tjernlundfc4e1882010-01-19 14:41:55 +0100186 EXC_XFER_TEMPLATE(ProgramCheck, ProgramCheckException,
187 MSR_KERNEL, COPY_EE)
wdenk983fda82004-10-28 00:09:35 +0000188
189 STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
190
191 /* I guess we could implement decrementer, and may have
192 * to someday for timekeeping.
193 */
194 STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
195
196 STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
197 STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
198 STD_EXCEPTION(0xc00, SystemCall, UnknownException)
199 STD_EXCEPTION(0xd00, SingleStep, UnknownException)
200
201 STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
202 STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
203
204 STD_EXCEPTION(0x1000, InstructionTLBMiss, UnknownException)
205 STD_EXCEPTION(0x1100, DataLoadTLBMiss, UnknownException)
206 STD_EXCEPTION(0x1200, DataStoreTLBMiss, UnknownException)
207#ifdef DEBUG
208 . = 0x1300
209 /*
210 * This exception occurs when the program counter matches the
211 * Instruction Address Breakpoint Register (IABR).
212 *
213 * I want the cpu to halt if this occurs so I can hunt around
214 * with the debugger and look at things.
215 *
216 * When DEBUG is defined, both machine check enable (in the MSR)
217 * and checkstop reset enable (in the reset mode register) are
218 * turned off and so a checkstop condition will result in the cpu
219 * halting.
220 *
221 * I force the cpu into a checkstop condition by putting an illegal
222 * instruction here (at least this is the theory).
223 *
224 * well - that didnt work, so just do an infinite loop!
225 */
2261: b 1b
227#else
228 STD_EXCEPTION(0x1300, InstructionBreakpoint, DebugException)
229#endif
230 STD_EXCEPTION(0x1400, SMI, UnknownException)
231
232 STD_EXCEPTION(0x1500, Trap_15, UnknownException)
233 STD_EXCEPTION(0x1600, Trap_16, UnknownException)
234 STD_EXCEPTION(0x1700, Trap_17, UnknownException)
235 STD_EXCEPTION(0x1800, Trap_18, UnknownException)
236 STD_EXCEPTION(0x1900, Trap_19, UnknownException)
237 STD_EXCEPTION(0x1a00, Trap_1a, UnknownException)
238 STD_EXCEPTION(0x1b00, Trap_1b, UnknownException)
239 STD_EXCEPTION(0x1c00, Trap_1c, UnknownException)
240 STD_EXCEPTION(0x1d00, Trap_1d, UnknownException)
241 STD_EXCEPTION(0x1e00, Trap_1e, UnknownException)
242 STD_EXCEPTION(0x1f00, Trap_1f, UnknownException)
243 STD_EXCEPTION(0x2000, Trap_20, UnknownException)
244 STD_EXCEPTION(0x2100, Trap_21, UnknownException)
245 STD_EXCEPTION(0x2200, Trap_22, UnknownException)
246 STD_EXCEPTION(0x2300, Trap_23, UnknownException)
247 STD_EXCEPTION(0x2400, Trap_24, UnknownException)
248 STD_EXCEPTION(0x2500, Trap_25, UnknownException)
249 STD_EXCEPTION(0x2600, Trap_26, UnknownException)
250 STD_EXCEPTION(0x2700, Trap_27, UnknownException)
251 STD_EXCEPTION(0x2800, Trap_28, UnknownException)
252 STD_EXCEPTION(0x2900, Trap_29, UnknownException)
253 STD_EXCEPTION(0x2a00, Trap_2a, UnknownException)
254 STD_EXCEPTION(0x2b00, Trap_2b, UnknownException)
255 STD_EXCEPTION(0x2c00, Trap_2c, UnknownException)
256 STD_EXCEPTION(0x2d00, Trap_2d, UnknownException)
257 STD_EXCEPTION(0x2e00, Trap_2e, UnknownException)
258 STD_EXCEPTION(0x2f00, Trap_2f, UnknownException)
259
260
261 .globl _end_of_vectors
262_end_of_vectors:
263
264 . = 0x3000
265
266/*
267 * This code finishes saving the registers to the exception frame
268 * and jumps to the appropriate handler for the exception.
269 * Register r21 is pointer into trap frame, r1 has new stack pointer.
270 */
271 .globl transfer_to_handler
272transfer_to_handler:
273 stw r22,_NIP(r21)
274 lis r22,MSR_POW@h
275 andc r23,r23,r22
276 stw r23,_MSR(r21)
277 SAVE_GPR(7, r21)
278 SAVE_4GPRS(8, r21)
279 SAVE_8GPRS(12, r21)
280 SAVE_8GPRS(24, r21)
281 mflr r23
282 andi. r24,r23,0x3f00 /* get vector offset */
283 stw r24,TRAP(r21)
284 li r22,0
285 stw r22,RESULT(r21)
286 lwz r24,0(r23) /* virtual address of handler */
287 lwz r23,4(r23) /* where to go when done */
288 mtspr SRR0,r24
289 mtspr SRR1,r20
290 mtlr r23
291 SYNC
292 rfi /* jump to handler, enable MMU */
293
294int_return:
295 mfmsr r28 /* Disable interrupts */
296 li r4,0
297 ori r4,r4,MSR_EE
298 andc r28,r28,r4
299 SYNC /* Some chip revs need this... */
300 mtmsr r28
301 SYNC
302 lwz r2,_CTR(r1)
303 lwz r0,_LINK(r1)
304 mtctr r2
305 mtlr r0
306 lwz r2,_XER(r1)
307 lwz r0,_CCR(r1)
308 mtspr XER,r2
309 mtcrf 0xFF,r0
310 REST_10GPRS(3, r1)
311 REST_10GPRS(13, r1)
312 REST_8GPRS(23, r1)
313 REST_GPR(31, r1)
314 lwz r2,_NIP(r1) /* Restore environment */
315 lwz r0,_MSR(r1)
316 mtspr SRR0,r2
317 mtspr SRR1,r0
318 lwz r0,GPR0(r1)
319 lwz r2,GPR2(r1)
320 lwz r1,GPR1(r1)
321 SYNC
322 rfi
323
324/*
325 * This code initialises the MPC8220 processor core
326 * (conforms to PowerPC 603e spec)
327 * Note: expects original MSR contents to be in r5.
328 */
329
330 .globl init_8220_core
331init_8220_core:
332
333 /* Initialize machine status; enable machine check interrupt */
334 /*--------------------------------------------------------------*/
335
336 li r3, MSR_KERNEL /* Set ME and RI flags */
337 rlwimi r3, r5, 0, 25, 25 /* preserve IP bit set by HRCW */
338#ifdef DEBUG
339 rlwimi r3, r5, 0, 21, 22 /* debugger might set SE & BE bits */
340#endif
341 SYNC /* Some chip revs need this... */
342 mtmsr r3
343 SYNC
344 mtspr SRR1, r3 /* Make SRR1 match MSR */
345
346 /* Initialize the Hardware Implementation-dependent Registers */
347 /* HID0 also contains cache control */
348 /*--------------------------------------------------------------*/
349
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200350 lis r3, CONFIG_SYS_HID0_INIT@h
351 ori r3, r3, CONFIG_SYS_HID0_INIT@l
wdenk983fda82004-10-28 00:09:35 +0000352 SYNC
353 mtspr HID0, r3
354
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200355 lis r3, CONFIG_SYS_HID0_FINAL@h
356 ori r3, r3, CONFIG_SYS_HID0_FINAL@l
wdenk983fda82004-10-28 00:09:35 +0000357 SYNC
358 mtspr HID0, r3
359
360 /* Enable Extra BATs */
361 mfspr r3, 1011 /* HID2 */
362 lis r4, 0x0004
363 ori r4, r4, 0x0000
364 or r4, r4, r3
365 mtspr 1011, r4
366 sync
367
368 /* clear all BAT's */
369 /*--------------------------------------------------------------*/
370
371 li r0, 0
372 mtspr DBAT0U, r0
373 mtspr DBAT0L, r0
374 mtspr DBAT1U, r0
375 mtspr DBAT1L, r0
376 mtspr DBAT2U, r0
377 mtspr DBAT2L, r0
378 mtspr DBAT3U, r0
379 mtspr DBAT3L, r0
380 mtspr DBAT4U, r0
381 mtspr DBAT4L, r0
382 mtspr DBAT5U, r0
383 mtspr DBAT5L, r0
384 mtspr DBAT6U, r0
385 mtspr DBAT6L, r0
386 mtspr DBAT7U, r0
387 mtspr DBAT7L, r0
388 mtspr IBAT0U, r0
389 mtspr IBAT0L, r0
390 mtspr IBAT1U, r0
391 mtspr IBAT1L, r0
392 mtspr IBAT2U, r0
393 mtspr IBAT2L, r0
394 mtspr IBAT3U, r0
395 mtspr IBAT3L, r0
396 mtspr IBAT4U, r0
397 mtspr IBAT4L, r0
398 mtspr IBAT5U, r0
399 mtspr IBAT5L, r0
400 mtspr IBAT6U, r0
401 mtspr IBAT6L, r0
402 mtspr IBAT7U, r0
403 mtspr IBAT7L, r0
404 SYNC
405
406 /* invalidate all tlb's */
407 /* */
408 /* From the 603e User Manual: "The 603e provides the ability to */
409 /* invalidate a TLB entry. The TLB Invalidate Entry (tlbie) */
410 /* instruction invalidates the TLB entry indexed by the EA, and */
411 /* operates on both the instruction and data TLBs simultaneously*/
412 /* invalidating four TLB entries (both sets in each TLB). The */
413 /* index corresponds to bits 15-19 of the EA. To invalidate all */
414 /* entries within both TLBs, 32 tlbie instructions should be */
415 /* issued, incrementing this field by one each time." */
416 /* */
417 /* "Note that the tlbia instruction is not implemented on the */
418 /* 603e." */
419 /* */
420 /* bits 15-19 correspond to addresses 0x00000000 to 0x0001F000 */
421 /* incrementing by 0x1000 each time. The code below is sort of */
422 /* based on code in "flush_tlbs" from arch/ppc/kernel/head.S */
423 /* */
424 /*--------------------------------------------------------------*/
425
426 li r3, 32
427 mtctr r3
428 li r3, 0
4291: tlbie r3
430 addi r3, r3, 0x1000
431 bdnz 1b
432 SYNC
433
434 /* Done! */
435 /*--------------------------------------------------------------*/
436
437 blr
438
439/* Cache functions.
440 *
441 * Note: requires that all cache bits in
442 * HID0 are in the low half word.
443 */
444 .globl icache_enable
445icache_enable:
446 lis r4, 0
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200447 ori r4, r4, CONFIG_SYS_HID0_INIT /* set ICE & ICFI bit */
wdenk983fda82004-10-28 00:09:35 +0000448 rlwinm r3, r4, 0, 21, 19 /* clear the ICFI bit */
449
450 /*
451 * The setting of the instruction cache enable (ICE) bit must be
452 * preceded by an isync instruction to prevent the cache from being
453 * enabled or disabled while an instruction access is in progress.
454 */
455 isync
456 mtspr HID0, r4 /* Enable Instr Cache & Inval cache */
457 mtspr HID0, r3 /* using 2 consec instructions */
458 isync
459 blr
460
461 .globl icache_disable
462icache_disable:
463 mfspr r3, HID0
464 rlwinm r3, r3, 0, 17, 15 /* clear the ICE bit */
465 mtspr HID0, r3
466 isync
467 blr
468
469 .globl icache_status
470icache_status:
471 mfspr r3, HID0
472 rlwinm r3, r3, HID0_ICE_BITPOS + 1, 31, 31
473 blr
474
475 .globl dcache_enable
476dcache_enable:
477 lis r4, 0
478 ori r4, r4, HID0_DCE|HID0_DCFI /* set DCE & DCFI bit */
479 rlwinm r3, r4, 0, 22, 20 /* clear the DCFI bit */
480
481 /* Enable address translation in MSR bit */
482 mfmsr r5
483 ori r5, r5, 0x
484
485
486 /*
487 * The setting of the instruction cache enable (ICE) bit must be
488 * preceded by an isync instruction to prevent the cache from being
489 * enabled or disabled while an instruction access is in progress.
490 */
491 isync
492 mtspr HID0, r4 /* Enable Data Cache & Inval cache*/
493 mtspr HID0, r3 /* using 2 consec instructions */
494 isync
495 blr
496
497 .globl dcache_disable
498dcache_disable:
499 mfspr r3, HID0
500 rlwinm r3, r3, 0, 18, 16 /* clear the DCE bit */
501 mtspr HID0, r3
502 isync
503 blr
504
505 .globl dcache_status
506dcache_status:
507 mfspr r3, HID0
508 rlwinm r3, r3, HID0_DCE_BITPOS + 1, 31, 31
509 blr
510
511 .globl get_pvr
512get_pvr:
513 mfspr r3, PVR
514 blr
515
516/*------------------------------------------------------------------------------*/
517
518/*
519 * void relocate_code (addr_sp, gd, addr_moni)
520 *
521 * This "function" does not return, instead it continues in RAM
522 * after relocating the monitor code.
523 *
524 * r3 = dest
525 * r4 = src
526 * r5 = length in bytes
527 * r6 = cachelinesize
528 */
529 .globl relocate_code
530relocate_code:
531 mr r1, r3 /* Set new stack pointer */
532 mr r9, r4 /* Save copy of Global Data pointer */
533 mr r10, r5 /* Save copy of Destination Address */
534
535 mr r3, r5 /* Destination Address */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200536 lis r4, CONFIG_SYS_MONITOR_BASE@h /* Source Address */
537 ori r4, r4, CONFIG_SYS_MONITOR_BASE@l
wdenk983fda82004-10-28 00:09:35 +0000538 lwz r5, GOT(__init_end)
539 sub r5, r5, r4
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200540 li r6, CONFIG_SYS_CACHELINE_SIZE /* Cache Line Size */
wdenk983fda82004-10-28 00:09:35 +0000541
542 /*
543 * Fix GOT pointer:
544 *
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200545 * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address
wdenk983fda82004-10-28 00:09:35 +0000546 *
547 * Offset:
548 */
549 sub r15, r10, r4
550
551 /* First our own GOT */
552 add r14, r14, r15
553 /* then the one used by the C code */
554 add r30, r30, r15
555
556 /*
557 * Now relocate code
558 */
559
560 cmplw cr1,r3,r4
561 addi r0,r5,3
562 srwi. r0,r0,2
563 beq cr1,4f /* In place copy is not necessary */
564 beq 7f /* Protect against 0 count */
565 mtctr r0
566 bge cr1,2f
567
568 la r8,-4(r4)
569 la r7,-4(r3)
5701: lwzu r0,4(r8)
571 stwu r0,4(r7)
572 bdnz 1b
573 b 4f
574
5752: slwi r0,r0,2
576 add r8,r4,r0
577 add r7,r3,r0
5783: lwzu r0,-4(r8)
579 stwu r0,-4(r7)
580 bdnz 3b
581
582/*
583 * Now flush the cache: note that we must start from a cache aligned
584 * address. Otherwise we might miss one cache line.
585 */
5864: cmpwi r6,0
587 add r5,r3,r5
588 beq 7f /* Always flush prefetch queue in any case */
589 subi r0,r6,1
590 andc r3,r3,r0
591 mfspr r7,HID0 /* don't do dcbst if dcache is disabled */
592 rlwinm r7,r7,HID0_DCE_BITPOS+1,31,31
593 cmpwi r7,0
594 beq 9f
595 mr r4,r3
5965: dcbst 0,r4
597 add r4,r4,r6
598 cmplw r4,r5
599 blt 5b
600 sync /* Wait for all dcbst to complete on bus */
6019: mfspr r7,HID0 /* don't do icbi if icache is disabled */
602 rlwinm r7,r7,HID0_ICE_BITPOS+1,31,31
603 cmpwi r7,0
604 beq 7f
605 mr r4,r3
6066: icbi 0,r4
607 add r4,r4,r6
608 cmplw r4,r5
609 blt 6b
6107: sync /* Wait for all icbi to complete on bus */
611 isync
612
613/*
614 * We are done. Do not return, instead branch to second part of board
615 * initialization, now running from RAM.
616 */
617
618 addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
619 mtlr r0
620 blr
621
622in_ram:
623
624 /*
625 * Relocation Function, r14 point to got2+0x8000
626 *
627 * Adjust got2 pointers, no need to check for 0, this code
628 * already puts a few entries in the table.
629 */
630 li r0,__got2_entries@sectoff@l
631 la r3,GOT(_GOT2_TABLE_)
632 lwz r11,GOT(_GOT2_TABLE_)
633 mtctr r0
634 sub r11,r3,r11
635 addi r3,r3,-4
6361: lwzu r0,4(r3)
Joakim Tjernlundafc3ba02009-10-08 02:03:51 +0200637 cmpwi r0,0
638 beq- 2f
wdenk983fda82004-10-28 00:09:35 +0000639 add r0,r0,r11
640 stw r0,0(r3)
Joakim Tjernlundafc3ba02009-10-08 02:03:51 +02006412: bdnz 1b
wdenk983fda82004-10-28 00:09:35 +0000642
643 /*
644 * Now adjust the fixups and the pointers to the fixups
645 * in case we need to move ourselves again.
646 */
Joakim Tjernlundafc3ba02009-10-08 02:03:51 +0200647 li r0,__fixup_entries@sectoff@l
wdenk983fda82004-10-28 00:09:35 +0000648 lwz r3,GOT(_FIXUP_TABLE_)
649 cmpwi r0,0
650 mtctr r0
651 addi r3,r3,-4
652 beq 4f
6533: lwzu r4,4(r3)
654 lwzux r0,r4,r11
655 add r0,r0,r11
656 stw r10,0(r3)
657 stw r0,0(r4)
658 bdnz 3b
6594:
660clear_bss:
661 /*
662 * Now clear BSS segment
663 */
664 lwz r3,GOT(__bss_start)
665 lwz r4,GOT(_end)
666
667 cmplw 0, r3, r4
668 beq 6f
669
670 li r0, 0
6715:
672 stw r0, 0(r3)
673 addi r3, r3, 4
674 cmplw 0, r3, r4
675 bne 5b
6766:
677
678 mr r3, r9 /* Global Data pointer */
679 mr r4, r10 /* Destination Address */
680 bl board_init_r
681
682 /*
683 * Copy exception vector code to low memory
684 *
685 * r3: dest_addr
686 * r7: source address, r8: end address, r9: target address
687 */
688 .globl trap_init
689trap_init:
690 lwz r7, GOT(_start)
691 lwz r8, GOT(_end_of_vectors)
692
693 li r9, 0x100 /* reset vector always at 0x100 */
694
695 cmplw 0, r7, r8
696 bgelr /* return if r7>=r8 - just in case */
697
698 mflr r4 /* save link register */
6991:
700 lwz r0, 0(r7)
701 stw r0, 0(r9)
702 addi r7, r7, 4
703 addi r9, r9, 4
704 cmplw 0, r7, r8
705 bne 1b
706
707 /*
708 * relocate `hdlr' and `int_return' entries
709 */
710 li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
711 li r8, Alignment - _start + EXC_OFF_SYS_RESET
7122:
713 bl trap_reloc
714 addi r7, r7, 0x100 /* next exception vector */
715 cmplw 0, r7, r8
716 blt 2b
717
718 li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
719 bl trap_reloc
720
721 li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
722 bl trap_reloc
723
724 li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
725 li r8, SystemCall - _start + EXC_OFF_SYS_RESET
7263:
727 bl trap_reloc
728 addi r7, r7, 0x100 /* next exception vector */
729 cmplw 0, r7, r8
730 blt 3b
731
732 li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
733 li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
7344:
735 bl trap_reloc
736 addi r7, r7, 0x100 /* next exception vector */
737 cmplw 0, r7, r8
738 blt 4b
739
740 mfmsr r3 /* now that the vectors have */
741 lis r7, MSR_IP@h /* relocated into low memory */
742 ori r7, r7, MSR_IP@l /* MSR[IP] can be turned off */
743 andc r3, r3, r7 /* (if it was on) */
744 SYNC /* Some chip revs need this... */
745 mtmsr r3
746 SYNC
747
748 mtlr r4 /* restore link register */
749 blr