blob: 3abc619269f44e9a24a2fe8fb76252cee68d8063 [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
179 li r20,MSR_KERNEL
180 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
181 rlwimi r20,r23,0,25,25 /* copy IP bit from saved MSR */
182 lwz r6,GOT(transfer_to_handler)
183 mtlr r6
184 blrl
185.L_Alignment:
186 .long AlignmentException - _start + EXC_OFF_SYS_RESET
187 .long int_return - _start + EXC_OFF_SYS_RESET
188
189/* Program check exception */
190 . = 0x700
191ProgramCheck:
Rafal Jaworowski02032e82007-06-22 14:58:04 +0200192 EXCEPTION_PROLOG(SRR0, SRR1)
wdenk983fda82004-10-28 00:09:35 +0000193 addi r3,r1,STACK_FRAME_OVERHEAD
194 li r20,MSR_KERNEL
195 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
196 rlwimi r20,r23,0,25,25 /* copy IP bit from saved MSR */
197 lwz r6,GOT(transfer_to_handler)
198 mtlr r6
199 blrl
200.L_ProgramCheck:
201 .long ProgramCheckException - _start + EXC_OFF_SYS_RESET
202 .long int_return - _start + EXC_OFF_SYS_RESET
203
204 STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
205
206 /* I guess we could implement decrementer, and may have
207 * to someday for timekeeping.
208 */
209 STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
210
211 STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
212 STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
213 STD_EXCEPTION(0xc00, SystemCall, UnknownException)
214 STD_EXCEPTION(0xd00, SingleStep, UnknownException)
215
216 STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
217 STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
218
219 STD_EXCEPTION(0x1000, InstructionTLBMiss, UnknownException)
220 STD_EXCEPTION(0x1100, DataLoadTLBMiss, UnknownException)
221 STD_EXCEPTION(0x1200, DataStoreTLBMiss, UnknownException)
222#ifdef DEBUG
223 . = 0x1300
224 /*
225 * This exception occurs when the program counter matches the
226 * Instruction Address Breakpoint Register (IABR).
227 *
228 * I want the cpu to halt if this occurs so I can hunt around
229 * with the debugger and look at things.
230 *
231 * When DEBUG is defined, both machine check enable (in the MSR)
232 * and checkstop reset enable (in the reset mode register) are
233 * turned off and so a checkstop condition will result in the cpu
234 * halting.
235 *
236 * I force the cpu into a checkstop condition by putting an illegal
237 * instruction here (at least this is the theory).
238 *
239 * well - that didnt work, so just do an infinite loop!
240 */
2411: b 1b
242#else
243 STD_EXCEPTION(0x1300, InstructionBreakpoint, DebugException)
244#endif
245 STD_EXCEPTION(0x1400, SMI, UnknownException)
246
247 STD_EXCEPTION(0x1500, Trap_15, UnknownException)
248 STD_EXCEPTION(0x1600, Trap_16, UnknownException)
249 STD_EXCEPTION(0x1700, Trap_17, UnknownException)
250 STD_EXCEPTION(0x1800, Trap_18, UnknownException)
251 STD_EXCEPTION(0x1900, Trap_19, UnknownException)
252 STD_EXCEPTION(0x1a00, Trap_1a, UnknownException)
253 STD_EXCEPTION(0x1b00, Trap_1b, UnknownException)
254 STD_EXCEPTION(0x1c00, Trap_1c, UnknownException)
255 STD_EXCEPTION(0x1d00, Trap_1d, UnknownException)
256 STD_EXCEPTION(0x1e00, Trap_1e, UnknownException)
257 STD_EXCEPTION(0x1f00, Trap_1f, UnknownException)
258 STD_EXCEPTION(0x2000, Trap_20, UnknownException)
259 STD_EXCEPTION(0x2100, Trap_21, UnknownException)
260 STD_EXCEPTION(0x2200, Trap_22, UnknownException)
261 STD_EXCEPTION(0x2300, Trap_23, UnknownException)
262 STD_EXCEPTION(0x2400, Trap_24, UnknownException)
263 STD_EXCEPTION(0x2500, Trap_25, UnknownException)
264 STD_EXCEPTION(0x2600, Trap_26, UnknownException)
265 STD_EXCEPTION(0x2700, Trap_27, UnknownException)
266 STD_EXCEPTION(0x2800, Trap_28, UnknownException)
267 STD_EXCEPTION(0x2900, Trap_29, UnknownException)
268 STD_EXCEPTION(0x2a00, Trap_2a, UnknownException)
269 STD_EXCEPTION(0x2b00, Trap_2b, UnknownException)
270 STD_EXCEPTION(0x2c00, Trap_2c, UnknownException)
271 STD_EXCEPTION(0x2d00, Trap_2d, UnknownException)
272 STD_EXCEPTION(0x2e00, Trap_2e, UnknownException)
273 STD_EXCEPTION(0x2f00, Trap_2f, UnknownException)
274
275
276 .globl _end_of_vectors
277_end_of_vectors:
278
279 . = 0x3000
280
281/*
282 * This code finishes saving the registers to the exception frame
283 * and jumps to the appropriate handler for the exception.
284 * Register r21 is pointer into trap frame, r1 has new stack pointer.
285 */
286 .globl transfer_to_handler
287transfer_to_handler:
288 stw r22,_NIP(r21)
289 lis r22,MSR_POW@h
290 andc r23,r23,r22
291 stw r23,_MSR(r21)
292 SAVE_GPR(7, r21)
293 SAVE_4GPRS(8, r21)
294 SAVE_8GPRS(12, r21)
295 SAVE_8GPRS(24, r21)
296 mflr r23
297 andi. r24,r23,0x3f00 /* get vector offset */
298 stw r24,TRAP(r21)
299 li r22,0
300 stw r22,RESULT(r21)
301 lwz r24,0(r23) /* virtual address of handler */
302 lwz r23,4(r23) /* where to go when done */
303 mtspr SRR0,r24
304 mtspr SRR1,r20
305 mtlr r23
306 SYNC
307 rfi /* jump to handler, enable MMU */
308
309int_return:
310 mfmsr r28 /* Disable interrupts */
311 li r4,0
312 ori r4,r4,MSR_EE
313 andc r28,r28,r4
314 SYNC /* Some chip revs need this... */
315 mtmsr r28
316 SYNC
317 lwz r2,_CTR(r1)
318 lwz r0,_LINK(r1)
319 mtctr r2
320 mtlr r0
321 lwz r2,_XER(r1)
322 lwz r0,_CCR(r1)
323 mtspr XER,r2
324 mtcrf 0xFF,r0
325 REST_10GPRS(3, r1)
326 REST_10GPRS(13, r1)
327 REST_8GPRS(23, r1)
328 REST_GPR(31, r1)
329 lwz r2,_NIP(r1) /* Restore environment */
330 lwz r0,_MSR(r1)
331 mtspr SRR0,r2
332 mtspr SRR1,r0
333 lwz r0,GPR0(r1)
334 lwz r2,GPR2(r1)
335 lwz r1,GPR1(r1)
336 SYNC
337 rfi
338
339/*
340 * This code initialises the MPC8220 processor core
341 * (conforms to PowerPC 603e spec)
342 * Note: expects original MSR contents to be in r5.
343 */
344
345 .globl init_8220_core
346init_8220_core:
347
348 /* Initialize machine status; enable machine check interrupt */
349 /*--------------------------------------------------------------*/
350
351 li r3, MSR_KERNEL /* Set ME and RI flags */
352 rlwimi r3, r5, 0, 25, 25 /* preserve IP bit set by HRCW */
353#ifdef DEBUG
354 rlwimi r3, r5, 0, 21, 22 /* debugger might set SE & BE bits */
355#endif
356 SYNC /* Some chip revs need this... */
357 mtmsr r3
358 SYNC
359 mtspr SRR1, r3 /* Make SRR1 match MSR */
360
361 /* Initialize the Hardware Implementation-dependent Registers */
362 /* HID0 also contains cache control */
363 /*--------------------------------------------------------------*/
364
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200365 lis r3, CONFIG_SYS_HID0_INIT@h
366 ori r3, r3, CONFIG_SYS_HID0_INIT@l
wdenk983fda82004-10-28 00:09:35 +0000367 SYNC
368 mtspr HID0, r3
369
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200370 lis r3, CONFIG_SYS_HID0_FINAL@h
371 ori r3, r3, CONFIG_SYS_HID0_FINAL@l
wdenk983fda82004-10-28 00:09:35 +0000372 SYNC
373 mtspr HID0, r3
374
375 /* Enable Extra BATs */
376 mfspr r3, 1011 /* HID2 */
377 lis r4, 0x0004
378 ori r4, r4, 0x0000
379 or r4, r4, r3
380 mtspr 1011, r4
381 sync
382
383 /* clear all BAT's */
384 /*--------------------------------------------------------------*/
385
386 li r0, 0
387 mtspr DBAT0U, r0
388 mtspr DBAT0L, r0
389 mtspr DBAT1U, r0
390 mtspr DBAT1L, r0
391 mtspr DBAT2U, r0
392 mtspr DBAT2L, r0
393 mtspr DBAT3U, r0
394 mtspr DBAT3L, r0
395 mtspr DBAT4U, r0
396 mtspr DBAT4L, r0
397 mtspr DBAT5U, r0
398 mtspr DBAT5L, r0
399 mtspr DBAT6U, r0
400 mtspr DBAT6L, r0
401 mtspr DBAT7U, r0
402 mtspr DBAT7L, r0
403 mtspr IBAT0U, r0
404 mtspr IBAT0L, r0
405 mtspr IBAT1U, r0
406 mtspr IBAT1L, r0
407 mtspr IBAT2U, r0
408 mtspr IBAT2L, r0
409 mtspr IBAT3U, r0
410 mtspr IBAT3L, r0
411 mtspr IBAT4U, r0
412 mtspr IBAT4L, r0
413 mtspr IBAT5U, r0
414 mtspr IBAT5L, r0
415 mtspr IBAT6U, r0
416 mtspr IBAT6L, r0
417 mtspr IBAT7U, r0
418 mtspr IBAT7L, r0
419 SYNC
420
421 /* invalidate all tlb's */
422 /* */
423 /* From the 603e User Manual: "The 603e provides the ability to */
424 /* invalidate a TLB entry. The TLB Invalidate Entry (tlbie) */
425 /* instruction invalidates the TLB entry indexed by the EA, and */
426 /* operates on both the instruction and data TLBs simultaneously*/
427 /* invalidating four TLB entries (both sets in each TLB). The */
428 /* index corresponds to bits 15-19 of the EA. To invalidate all */
429 /* entries within both TLBs, 32 tlbie instructions should be */
430 /* issued, incrementing this field by one each time." */
431 /* */
432 /* "Note that the tlbia instruction is not implemented on the */
433 /* 603e." */
434 /* */
435 /* bits 15-19 correspond to addresses 0x00000000 to 0x0001F000 */
436 /* incrementing by 0x1000 each time. The code below is sort of */
437 /* based on code in "flush_tlbs" from arch/ppc/kernel/head.S */
438 /* */
439 /*--------------------------------------------------------------*/
440
441 li r3, 32
442 mtctr r3
443 li r3, 0
4441: tlbie r3
445 addi r3, r3, 0x1000
446 bdnz 1b
447 SYNC
448
449 /* Done! */
450 /*--------------------------------------------------------------*/
451
452 blr
453
454/* Cache functions.
455 *
456 * Note: requires that all cache bits in
457 * HID0 are in the low half word.
458 */
459 .globl icache_enable
460icache_enable:
461 lis r4, 0
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200462 ori r4, r4, CONFIG_SYS_HID0_INIT /* set ICE & ICFI bit */
wdenk983fda82004-10-28 00:09:35 +0000463 rlwinm r3, r4, 0, 21, 19 /* clear the ICFI bit */
464
465 /*
466 * The setting of the instruction cache enable (ICE) bit must be
467 * preceded by an isync instruction to prevent the cache from being
468 * enabled or disabled while an instruction access is in progress.
469 */
470 isync
471 mtspr HID0, r4 /* Enable Instr Cache & Inval cache */
472 mtspr HID0, r3 /* using 2 consec instructions */
473 isync
474 blr
475
476 .globl icache_disable
477icache_disable:
478 mfspr r3, HID0
479 rlwinm r3, r3, 0, 17, 15 /* clear the ICE bit */
480 mtspr HID0, r3
481 isync
482 blr
483
484 .globl icache_status
485icache_status:
486 mfspr r3, HID0
487 rlwinm r3, r3, HID0_ICE_BITPOS + 1, 31, 31
488 blr
489
490 .globl dcache_enable
491dcache_enable:
492 lis r4, 0
493 ori r4, r4, HID0_DCE|HID0_DCFI /* set DCE & DCFI bit */
494 rlwinm r3, r4, 0, 22, 20 /* clear the DCFI bit */
495
496 /* Enable address translation in MSR bit */
497 mfmsr r5
498 ori r5, r5, 0x
499
500
501 /*
502 * The setting of the instruction cache enable (ICE) bit must be
503 * preceded by an isync instruction to prevent the cache from being
504 * enabled or disabled while an instruction access is in progress.
505 */
506 isync
507 mtspr HID0, r4 /* Enable Data Cache & Inval cache*/
508 mtspr HID0, r3 /* using 2 consec instructions */
509 isync
510 blr
511
512 .globl dcache_disable
513dcache_disable:
514 mfspr r3, HID0
515 rlwinm r3, r3, 0, 18, 16 /* clear the DCE bit */
516 mtspr HID0, r3
517 isync
518 blr
519
520 .globl dcache_status
521dcache_status:
522 mfspr r3, HID0
523 rlwinm r3, r3, HID0_DCE_BITPOS + 1, 31, 31
524 blr
525
526 .globl get_pvr
527get_pvr:
528 mfspr r3, PVR
529 blr
530
531/*------------------------------------------------------------------------------*/
532
533/*
534 * void relocate_code (addr_sp, gd, addr_moni)
535 *
536 * This "function" does not return, instead it continues in RAM
537 * after relocating the monitor code.
538 *
539 * r3 = dest
540 * r4 = src
541 * r5 = length in bytes
542 * r6 = cachelinesize
543 */
544 .globl relocate_code
545relocate_code:
546 mr r1, r3 /* Set new stack pointer */
547 mr r9, r4 /* Save copy of Global Data pointer */
548 mr r10, r5 /* Save copy of Destination Address */
549
550 mr r3, r5 /* Destination Address */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200551 lis r4, CONFIG_SYS_MONITOR_BASE@h /* Source Address */
552 ori r4, r4, CONFIG_SYS_MONITOR_BASE@l
wdenk983fda82004-10-28 00:09:35 +0000553 lwz r5, GOT(__init_end)
554 sub r5, r5, r4
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200555 li r6, CONFIG_SYS_CACHELINE_SIZE /* Cache Line Size */
wdenk983fda82004-10-28 00:09:35 +0000556
557 /*
558 * Fix GOT pointer:
559 *
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200560 * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address
wdenk983fda82004-10-28 00:09:35 +0000561 *
562 * Offset:
563 */
564 sub r15, r10, r4
565
566 /* First our own GOT */
567 add r14, r14, r15
568 /* then the one used by the C code */
569 add r30, r30, r15
570
571 /*
572 * Now relocate code
573 */
574
575 cmplw cr1,r3,r4
576 addi r0,r5,3
577 srwi. r0,r0,2
578 beq cr1,4f /* In place copy is not necessary */
579 beq 7f /* Protect against 0 count */
580 mtctr r0
581 bge cr1,2f
582
583 la r8,-4(r4)
584 la r7,-4(r3)
5851: lwzu r0,4(r8)
586 stwu r0,4(r7)
587 bdnz 1b
588 b 4f
589
5902: slwi r0,r0,2
591 add r8,r4,r0
592 add r7,r3,r0
5933: lwzu r0,-4(r8)
594 stwu r0,-4(r7)
595 bdnz 3b
596
597/*
598 * Now flush the cache: note that we must start from a cache aligned
599 * address. Otherwise we might miss one cache line.
600 */
6014: cmpwi r6,0
602 add r5,r3,r5
603 beq 7f /* Always flush prefetch queue in any case */
604 subi r0,r6,1
605 andc r3,r3,r0
606 mfspr r7,HID0 /* don't do dcbst if dcache is disabled */
607 rlwinm r7,r7,HID0_DCE_BITPOS+1,31,31
608 cmpwi r7,0
609 beq 9f
610 mr r4,r3
6115: dcbst 0,r4
612 add r4,r4,r6
613 cmplw r4,r5
614 blt 5b
615 sync /* Wait for all dcbst to complete on bus */
6169: mfspr r7,HID0 /* don't do icbi if icache is disabled */
617 rlwinm r7,r7,HID0_ICE_BITPOS+1,31,31
618 cmpwi r7,0
619 beq 7f
620 mr r4,r3
6216: icbi 0,r4
622 add r4,r4,r6
623 cmplw r4,r5
624 blt 6b
6257: sync /* Wait for all icbi to complete on bus */
626 isync
627
628/*
629 * We are done. Do not return, instead branch to second part of board
630 * initialization, now running from RAM.
631 */
632
633 addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
634 mtlr r0
635 blr
636
637in_ram:
638
639 /*
640 * Relocation Function, r14 point to got2+0x8000
641 *
642 * Adjust got2 pointers, no need to check for 0, this code
643 * already puts a few entries in the table.
644 */
645 li r0,__got2_entries@sectoff@l
646 la r3,GOT(_GOT2_TABLE_)
647 lwz r11,GOT(_GOT2_TABLE_)
648 mtctr r0
649 sub r11,r3,r11
650 addi r3,r3,-4
6511: lwzu r0,4(r3)
652 add r0,r0,r11
653 stw r0,0(r3)
654 bdnz 1b
655
656 /*
657 * Now adjust the fixups and the pointers to the fixups
658 * in case we need to move ourselves again.
659 */
6602: li r0,__fixup_entries@sectoff@l
661 lwz r3,GOT(_FIXUP_TABLE_)
662 cmpwi r0,0
663 mtctr r0
664 addi r3,r3,-4
665 beq 4f
6663: lwzu r4,4(r3)
667 lwzux r0,r4,r11
668 add r0,r0,r11
669 stw r10,0(r3)
670 stw r0,0(r4)
671 bdnz 3b
6724:
673clear_bss:
674 /*
675 * Now clear BSS segment
676 */
677 lwz r3,GOT(__bss_start)
678 lwz r4,GOT(_end)
679
680 cmplw 0, r3, r4
681 beq 6f
682
683 li r0, 0
6845:
685 stw r0, 0(r3)
686 addi r3, r3, 4
687 cmplw 0, r3, r4
688 bne 5b
6896:
690
691 mr r3, r9 /* Global Data pointer */
692 mr r4, r10 /* Destination Address */
693 bl board_init_r
694
695 /*
696 * Copy exception vector code to low memory
697 *
698 * r3: dest_addr
699 * r7: source address, r8: end address, r9: target address
700 */
701 .globl trap_init
702trap_init:
703 lwz r7, GOT(_start)
704 lwz r8, GOT(_end_of_vectors)
705
706 li r9, 0x100 /* reset vector always at 0x100 */
707
708 cmplw 0, r7, r8
709 bgelr /* return if r7>=r8 - just in case */
710
711 mflr r4 /* save link register */
7121:
713 lwz r0, 0(r7)
714 stw r0, 0(r9)
715 addi r7, r7, 4
716 addi r9, r9, 4
717 cmplw 0, r7, r8
718 bne 1b
719
720 /*
721 * relocate `hdlr' and `int_return' entries
722 */
723 li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
724 li r8, Alignment - _start + EXC_OFF_SYS_RESET
7252:
726 bl trap_reloc
727 addi r7, r7, 0x100 /* next exception vector */
728 cmplw 0, r7, r8
729 blt 2b
730
731 li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
732 bl trap_reloc
733
734 li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
735 bl trap_reloc
736
737 li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
738 li r8, SystemCall - _start + EXC_OFF_SYS_RESET
7393:
740 bl trap_reloc
741 addi r7, r7, 0x100 /* next exception vector */
742 cmplw 0, r7, r8
743 blt 3b
744
745 li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
746 li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
7474:
748 bl trap_reloc
749 addi r7, r7, 0x100 /* next exception vector */
750 cmplw 0, r7, r8
751 blt 4b
752
753 mfmsr r3 /* now that the vectors have */
754 lis r7, MSR_IP@h /* relocated into low memory */
755 ori r7, r7, MSR_IP@l /* MSR[IP] can be turned off */
756 andc r3, r3, r7 /* (if it was on) */
757 SYNC /* Some chip revs need this... */
758 mtmsr r3
759 SYNC
760
761 mtlr r4 /* restore link register */
762 blr
763
764 /*
765 * Function: relocate entries for one exception vector
766 */
767trap_reloc:
768 lwz r0, 0(r7) /* hdlr ... */
769 add r0, r0, r3 /* ... += dest_addr */
770 stw r0, 0(r7)
771
772 lwz r0, 4(r7) /* int_return ... */
773 add r0, r0, r3 /* ... += dest_addr */
774 stw r0, 4(r7)
775
776 blr