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