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