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