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