]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/powerpc/cpu/mpc86xx/start.S
Merge branch 'u-boot-imx/master' into 'u-boot-arm/master'
[karo-tx-uboot.git] / arch / powerpc / cpu / mpc86xx / start.S
1 /*
2  * Copyright 2004, 2007, 2011 Freescale Semiconductor.
3  * Srikanth Srinivasan <srikanth.srinivaan@freescale.com>
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23
24 /*  U-Boot - Startup Code for 86xx PowerPC based Embedded Boards
25  *
26  *
27  *  The processor starts at 0xfff00100 and the code is executed
28  *  from flash. The code is organized to be at an other address
29  *  in memory, but as long we don't jump around before relocating.
30  *  board_init lies at a quite high address and when the cpu has
31  *  jumped there, everything is ok.
32  */
33 #include <asm-offsets.h>
34 #include <config.h>
35 #include <mpc86xx.h>
36 #include <version.h>
37
38 #include <ppc_asm.tmpl>
39 #include <ppc_defs.h>
40
41 #include <asm/cache.h>
42 #include <asm/mmu.h>
43 #include <asm/u-boot.h>
44
45 /*
46  * Need MSR_DR | MSR_IR enabled to access I/O (printf) in exceptions
47  */
48
49 /*
50  * Set up GOT: Global Offset Table
51  *
52  * Use r12 to access the GOT
53  */
54         START_GOT
55         GOT_ENTRY(_GOT2_TABLE_)
56         GOT_ENTRY(_FIXUP_TABLE_)
57
58         GOT_ENTRY(_start)
59         GOT_ENTRY(_start_of_vectors)
60         GOT_ENTRY(_end_of_vectors)
61         GOT_ENTRY(transfer_to_handler)
62
63         GOT_ENTRY(__init_end)
64         GOT_ENTRY(__bss_end)
65         GOT_ENTRY(__bss_start)
66         END_GOT
67
68 /*
69  * r3 - 1st arg to board_init(): IMMP pointer
70  * r4 - 2nd arg to board_init(): boot flag
71  */
72         .text
73         .long   0x27051956              /* U-Boot Magic Number */
74         .globl  version_string
75 version_string:
76         .ascii U_BOOT_VERSION_STRING, "\0"
77
78         . = EXC_OFF_SYS_RESET
79         .globl  _start
80 _start:
81         b       boot_cold
82
83         /* the boot code is located below the exception table */
84
85         .globl  _start_of_vectors
86 _start_of_vectors:
87
88 /* Machine check */
89         STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)
90
91 /* Data Storage exception. */
92         STD_EXCEPTION(0x300, DataStorage, UnknownException)
93
94 /* Instruction Storage exception. */
95         STD_EXCEPTION(0x400, InstStorage, UnknownException)
96
97 /* External Interrupt exception. */
98         STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
99
100 /* Alignment exception. */
101         . = 0x600
102 Alignment:
103         EXCEPTION_PROLOG(SRR0, SRR1)
104         mfspr   r4,DAR
105         stw     r4,_DAR(r21)
106         mfspr   r5,DSISR
107         stw     r5,_DSISR(r21)
108         addi    r3,r1,STACK_FRAME_OVERHEAD
109         EXC_XFER_TEMPLATE(Alignment, AlignmentException, MSR_KERNEL, COPY_EE)
110
111 /* Program check exception */
112         . = 0x700
113 ProgramCheck:
114         EXCEPTION_PROLOG(SRR0, SRR1)
115         addi    r3,r1,STACK_FRAME_OVERHEAD
116         EXC_XFER_TEMPLATE(ProgramCheck, ProgramCheckException,
117                 MSR_KERNEL, COPY_EE)
118
119         STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
120
121         /* I guess we could implement decrementer, and may have
122          * to someday for timekeeping.
123          */
124         STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
125         STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
126         STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
127         STD_EXCEPTION(0xc00, SystemCall, UnknownException)
128         STD_EXCEPTION(0xd00, SingleStep, UnknownException)
129         STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
130         STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
131         STD_EXCEPTION(0x1000, SoftEmu, SoftEmuException)
132         STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException)
133         STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException)
134         STD_EXCEPTION(0x1300, InstructionTLBError, UnknownException)
135         STD_EXCEPTION(0x1400, DataTLBError, UnknownException)
136         STD_EXCEPTION(0x1500, Reserved5, UnknownException)
137         STD_EXCEPTION(0x1600, Reserved6, UnknownException)
138         STD_EXCEPTION(0x1700, Reserved7, UnknownException)
139         STD_EXCEPTION(0x1800, Reserved8, UnknownException)
140         STD_EXCEPTION(0x1900, Reserved9, UnknownException)
141         STD_EXCEPTION(0x1a00, ReservedA, UnknownException)
142         STD_EXCEPTION(0x1b00, ReservedB, UnknownException)
143         STD_EXCEPTION(0x1c00, DataBreakpoint, UnknownException)
144         STD_EXCEPTION(0x1d00, InstructionBreakpoint, UnknownException)
145         STD_EXCEPTION(0x1e00, PeripheralBreakpoint, UnknownException)
146         STD_EXCEPTION(0x1f00, DevPortBreakpoint, UnknownException)
147
148         .globl  _end_of_vectors
149 _end_of_vectors:
150
151         . = 0x2000
152
153 boot_cold:
154         /*
155          * NOTE: Only Cpu 0 will ever come here.  Other cores go to an
156          * address specified by the BPTR
157          */
158 1:
159 #ifdef CONFIG_SYS_RAMBOOT
160         /* disable everything */
161         li      r0, 0
162         mtspr   HID0, r0
163         sync
164         mtmsr   0
165 #endif
166
167         /* Invalidate BATs */
168         bl      invalidate_bats
169         sync
170         /* Invalidate all of TLB before MMU turn on */
171         bl      clear_tlbs
172         sync
173
174 #ifdef CONFIG_SYS_L2
175         /* init the L2 cache */
176         lis     r3, L2_INIT@h
177         ori     r3, r3, L2_INIT@l
178         mtspr   l2cr, r3
179         /* invalidate the L2 cache */
180         bl      l2cache_invalidate
181         sync
182 #endif
183
184         /*
185          * Calculate absolute address in FLASH and jump there
186          *------------------------------------------------------*/
187         lis     r3, CONFIG_SYS_MONITOR_BASE_EARLY@h
188         ori     r3, r3, CONFIG_SYS_MONITOR_BASE_EARLY@l
189         addi    r3, r3, in_flash - _start + EXC_OFF_SYS_RESET
190         mtlr    r3
191         blr
192
193 in_flash:
194         /* let the C-code set up the rest                       */
195         /*                                                      */
196         /* Be careful to keep code relocatable !                */
197         /*------------------------------------------------------*/
198         /* perform low-level init */
199
200         /* enable extended addressing */
201         bl      enable_ext_addr
202
203         /* setup the bats */
204         bl      early_bats
205
206         /*
207          * Cache must be enabled here for stack-in-cache trick.
208          * This means we need to enable the BATS.
209          * Cache should be turned on after BATs, since by default
210          * everything is write-through.
211          */
212
213         /* enable address translation */
214         mfmsr   r5
215         ori     r5, r5, (MSR_IR | MSR_DR)
216         lis     r3,addr_trans_enabled@h
217         ori     r3, r3, addr_trans_enabled@l
218         mtspr   SPRN_SRR0,r3
219         mtspr   SPRN_SRR1,r5
220         rfi
221
222 addr_trans_enabled:
223         /* enable and invalidate the data cache */
224 /*      bl      l1dcache_enable */
225         bl      dcache_enable
226         sync
227
228 #if 1
229         bl      icache_enable
230 #endif
231
232 #ifdef CONFIG_SYS_INIT_RAM_LOCK
233         bl      lock_ram_in_cache
234         sync
235 #endif
236
237 #if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR)
238         bl      setup_ccsrbar
239 #endif
240
241         /* set up the stack pointer in our newly created
242          * cache-ram (r1) */
243         lis     r1, (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET)@h
244         ori     r1, r1, (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET)@l
245
246         li      r0, 0           /* Make room for stack frame header and */
247         stwu    r0, -4(r1)      /* clear final stack frame so that      */
248         stwu    r0, -4(r1)      /* stack backtraces terminate cleanly   */
249
250         GET_GOT                 /* initialize GOT access        */
251
252         /* run low-level CPU init code     (from Flash) */
253         bl      cpu_init_f
254         sync
255
256 #ifdef  RUN_DIAG
257
258         /* Load PX_AUX register address in r4 */
259         lis     r4, PIXIS_BASE@h
260         ori     r4, r4, 0x6
261         /* Load contents of PX_AUX in r3 bits 24 to 31*/
262         lbz     r3, 0(r4)
263
264         /* Mask and obtain the bit in r3 */
265         rlwinm. r3, r3, 0, 24, 24
266         /* If not zero, jump and continue with u-boot */
267         bne     diag_done
268
269         /* Load back contents of PX_AUX in r3 bits 24 to 31 */
270         lbz     r3, 0(r4)
271         /* Set the MSB of the register value */
272         ori     r3, r3, 0x80
273         /* Write value in r3 back to PX_AUX */
274         stb     r3, 0(r4)
275
276         /* Get the address to jump to in r3*/
277         lis     r3, CONFIG_SYS_DIAG_ADDR@h
278         ori     r3, r3, CONFIG_SYS_DIAG_ADDR@l
279
280         /* Load the LR with the branch address */
281         mtlr    r3
282
283         /* Branch to diagnostic */
284         blr
285
286 diag_done:
287 #endif
288
289 /*      bl      l2cache_enable */
290
291         /* run 1st part of board init code (from Flash)   */
292         bl      board_init_f
293         sync
294
295         /* NOTREACHED - board_init_f() does not return */
296
297         .globl  invalidate_bats
298 invalidate_bats:
299
300         li      r0, 0
301         /* invalidate BATs */
302         mtspr   IBAT0U, r0
303         mtspr   IBAT1U, r0
304         mtspr   IBAT2U, r0
305         mtspr   IBAT3U, r0
306         mtspr   IBAT4U, r0
307         mtspr   IBAT5U, r0
308         mtspr   IBAT6U, r0
309         mtspr   IBAT7U, r0
310
311         isync
312         mtspr   DBAT0U, r0
313         mtspr   DBAT1U, r0
314         mtspr   DBAT2U, r0
315         mtspr   DBAT3U, r0
316         mtspr   DBAT4U, r0
317         mtspr   DBAT5U, r0
318         mtspr   DBAT6U, r0
319         mtspr   DBAT7U, r0
320
321         isync
322         sync
323         blr
324
325 #define CONFIG_BAT_PAIR(n) \
326         lis     r4, CONFIG_SYS_IBAT##n##L@h;            \
327         ori     r4, r4, CONFIG_SYS_IBAT##n##L@l;        \
328         lis     r3, CONFIG_SYS_IBAT##n##U@h;            \
329         ori     r3, r3, CONFIG_SYS_IBAT##n##U@l;        \
330         mtspr   IBAT##n##L, r4;                         \
331         mtspr   IBAT##n##U, r3;                         \
332         lis     r4, CONFIG_SYS_DBAT##n##L@h;            \
333         ori     r4, r4, CONFIG_SYS_DBAT##n##L@l;        \
334         lis     r3, CONFIG_SYS_DBAT##n##U@h;            \
335         ori     r3, r3, CONFIG_SYS_DBAT##n##U@l;        \
336         mtspr   DBAT##n##L, r4;                         \
337         mtspr   DBAT##n##U, r3;
338
339 /*
340  * setup_bats:
341  *
342  * Set up the final BAT registers now that setup is done.
343  *
344  * Assumes that:
345  *      1) Address translation is enabled upon entry
346  *      2) The boot rom is still accessible via 1:1 translation
347  */
348         .globl setup_bats
349 setup_bats:
350         mflr    r5
351         sync
352
353         /*
354          * When we disable address translation, we will get 1:1 (VA==PA)
355          * translation.  The only place we know for sure is safe for that is
356          * the bootrom where we originally started out.  Pop back into there.
357          */
358         lis     r4, CONFIG_SYS_MONITOR_BASE_EARLY@h
359         ori     r4, r4, CONFIG_SYS_MONITOR_BASE_EARLY@l
360         addi    r4, r4, trans_disabled - _start + EXC_OFF_SYS_RESET
361
362         /* disable address translation */
363         mfmsr   r3
364         rlwinm  r3, r3, 0, 28, 25
365         mtspr   SRR0, r4
366         mtspr   SRR1, r3
367         rfi
368
369 trans_disabled:
370 #if defined(CONFIG_SYS_DBAT0U) && defined(CONFIG_SYS_DBAT0L) \
371         && defined(CONFIG_SYS_IBAT0U) && defined(CONFIG_SYS_IBAT0L)
372         CONFIG_BAT_PAIR(0)
373 #endif
374         CONFIG_BAT_PAIR(1)
375         CONFIG_BAT_PAIR(2)
376         CONFIG_BAT_PAIR(3)
377         CONFIG_BAT_PAIR(4)
378         CONFIG_BAT_PAIR(5)
379         CONFIG_BAT_PAIR(6)
380         CONFIG_BAT_PAIR(7)
381
382         sync
383         isync
384
385         /* Turn translation back on and return */
386         mfmsr   r3
387         ori     r3, r3, (MSR_IR | MSR_DR)
388         mtspr   SPRN_SRR0,r5
389         mtspr   SPRN_SRR1,r3
390         rfi
391
392 /*
393  * early_bats:
394  *
395  * Set up bats needed early on - this is usually the BAT for the
396  * stack-in-cache, the Flash, and CCSR space
397  */
398         .globl  early_bats
399 early_bats:
400         /* IBAT 3 */
401         lis     r4, CONFIG_SYS_IBAT3L@h
402         ori     r4, r4, CONFIG_SYS_IBAT3L@l
403         lis     r3, CONFIG_SYS_IBAT3U@h
404         ori     r3, r3, CONFIG_SYS_IBAT3U@l
405         mtspr   IBAT3L, r4
406         mtspr   IBAT3U, r3
407         isync
408
409         /* DBAT 3 */
410         lis     r4, CONFIG_SYS_DBAT3L@h
411         ori     r4, r4, CONFIG_SYS_DBAT3L@l
412         lis     r3, CONFIG_SYS_DBAT3U@h
413         ori     r3, r3, CONFIG_SYS_DBAT3U@l
414         mtspr   DBAT3L, r4
415         mtspr   DBAT3U, r3
416         isync
417
418         /* IBAT 5 */
419         lis     r4, CONFIG_SYS_IBAT5L@h
420         ori     r4, r4, CONFIG_SYS_IBAT5L@l
421         lis     r3, CONFIG_SYS_IBAT5U@h
422         ori     r3, r3, CONFIG_SYS_IBAT5U@l
423         mtspr   IBAT5L, r4
424         mtspr   IBAT5U, r3
425         isync
426
427         /* DBAT 5 */
428         lis     r4, CONFIG_SYS_DBAT5L@h
429         ori     r4, r4, CONFIG_SYS_DBAT5L@l
430         lis     r3, CONFIG_SYS_DBAT5U@h
431         ori     r3, r3, CONFIG_SYS_DBAT5U@l
432         mtspr   DBAT5L, r4
433         mtspr   DBAT5U, r3
434         isync
435
436         /* IBAT 6 */
437         lis     r4, CONFIG_SYS_IBAT6L_EARLY@h
438         ori     r4, r4, CONFIG_SYS_IBAT6L_EARLY@l
439         lis     r3, CONFIG_SYS_IBAT6U_EARLY@h
440         ori     r3, r3, CONFIG_SYS_IBAT6U_EARLY@l
441         mtspr   IBAT6L, r4
442         mtspr   IBAT6U, r3
443         isync
444
445         /* DBAT 6 */
446         lis     r4, CONFIG_SYS_DBAT6L_EARLY@h
447         ori     r4, r4, CONFIG_SYS_DBAT6L_EARLY@l
448         lis     r3, CONFIG_SYS_DBAT6U_EARLY@h
449         ori     r3, r3, CONFIG_SYS_DBAT6U_EARLY@l
450         mtspr   DBAT6L, r4
451         mtspr   DBAT6U, r3
452         isync
453
454 #if(CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR)
455         /* IBAT 7 */
456         lis     r4, CONFIG_SYS_CCSR_DEFAULT_IBATL@h
457         ori     r4, r4, CONFIG_SYS_CCSR_DEFAULT_IBATL@l
458         lis     r3, CONFIG_SYS_CCSR_DEFAULT_IBATU@h
459         ori     r3, r3, CONFIG_SYS_CCSR_DEFAULT_IBATU@l
460         mtspr   IBAT7L, r4
461         mtspr   IBAT7U, r3
462         isync
463
464         /* DBAT 7 */
465         lis     r4, CONFIG_SYS_CCSR_DEFAULT_DBATL@h
466         ori     r4, r4, CONFIG_SYS_CCSR_DEFAULT_DBATL@l
467         lis     r3, CONFIG_SYS_CCSR_DEFAULT_DBATU@h
468         ori     r3, r3, CONFIG_SYS_CCSR_DEFAULT_DBATU@l
469         mtspr   DBAT7L, r4
470         mtspr   DBAT7U, r3
471         isync
472 #endif
473         blr
474
475         .globl clear_tlbs
476 clear_tlbs:
477         addis   r3, 0, 0x0000
478         addis   r5, 0, 0x4
479         isync
480 tlblp:
481         tlbie   r3
482         sync
483         addi    r3, r3, 0x1000
484         cmp     0, 0, r3, r5
485         blt tlblp
486         blr
487
488         .globl disable_addr_trans
489 disable_addr_trans:
490         /* disable address translation */
491         mflr    r4
492         mfmsr   r3
493         andi.   r0, r3, (MSR_IR | MSR_DR)
494         beqlr
495         andc    r3, r3, r0
496         mtspr   SRR0, r4
497         mtspr   SRR1, r3
498         rfi
499
500 /*
501  * This code finishes saving the registers to the exception frame
502  * and jumps to the appropriate handler for the exception.
503  * Register r21 is pointer into trap frame, r1 has new stack pointer.
504  */
505         .globl  transfer_to_handler
506 transfer_to_handler:
507         stw     r22,_NIP(r21)
508         lis     r22,MSR_POW@h
509         andc    r23,r23,r22
510         stw     r23,_MSR(r21)
511         SAVE_GPR(7, r21)
512         SAVE_4GPRS(8, r21)
513         SAVE_8GPRS(12, r21)
514         SAVE_8GPRS(24, r21)
515         mflr    r23
516         andi.   r24,r23,0x3f00          /* get vector offset */
517         stw     r24,TRAP(r21)
518         li      r22,0
519         stw     r22,RESULT(r21)
520         mtspr   SPRG2,r22               /* r1 is now kernel sp */
521         lwz     r24,0(r23)              /* virtual address of handler */
522         lwz     r23,4(r23)              /* where to go when done */
523         mtspr   SRR0,r24
524         mtspr   SRR1,r20
525         mtlr    r23
526         SYNC
527         rfi                             /* jump to handler, enable MMU */
528
529 int_return:
530         mfmsr   r28             /* Disable interrupts */
531         li      r4,0
532         ori     r4,r4,MSR_EE
533         andc    r28,r28,r4
534         SYNC                    /* Some chip revs need this... */
535         mtmsr   r28
536         SYNC
537         lwz     r2,_CTR(r1)
538         lwz     r0,_LINK(r1)
539         mtctr   r2
540         mtlr    r0
541         lwz     r2,_XER(r1)
542         lwz     r0,_CCR(r1)
543         mtspr   XER,r2
544         mtcrf   0xFF,r0
545         REST_10GPRS(3, r1)
546         REST_10GPRS(13, r1)
547         REST_8GPRS(23, r1)
548         REST_GPR(31, r1)
549         lwz     r2,_NIP(r1)     /* Restore environment */
550         lwz     r0,_MSR(r1)
551         mtspr   SRR0,r2
552         mtspr   SRR1,r0
553         lwz     r0,GPR0(r1)
554         lwz     r2,GPR2(r1)
555         lwz     r1,GPR1(r1)
556         SYNC
557         rfi
558
559         .globl  dc_read
560 dc_read:
561         blr
562
563         .globl get_pvr
564 get_pvr:
565         mfspr   r3, PVR
566         blr
567
568         .globl get_svr
569 get_svr:
570         mfspr   r3, SVR
571         blr
572
573
574 /*
575  * Function:    in8
576  * Description: Input 8 bits
577  */
578         .globl  in8
579 in8:
580         lbz     r3,0x0000(r3)
581         blr
582
583 /*
584  * Function:    out8
585  * Description: Output 8 bits
586  */
587         .globl  out8
588 out8:
589         stb     r4,0x0000(r3)
590         blr
591
592 /*
593  * Function:    out16
594  * Description: Output 16 bits
595  */
596         .globl  out16
597 out16:
598         sth     r4,0x0000(r3)
599         blr
600
601 /*
602  * Function:    out16r
603  * Description: Byte reverse and output 16 bits
604  */
605         .globl  out16r
606 out16r:
607         sthbrx  r4,r0,r3
608         blr
609
610 /*
611  * Function:    out32
612  * Description: Output 32 bits
613  */
614         .globl  out32
615 out32:
616         stw     r4,0x0000(r3)
617         blr
618
619 /*
620  * Function:    out32r
621  * Description: Byte reverse and output 32 bits
622  */
623         .globl  out32r
624 out32r:
625         stwbrx  r4,r0,r3
626         blr
627
628 /*
629  * Function:    in16
630  * Description: Input 16 bits
631  */
632         .globl  in16
633 in16:
634         lhz     r3,0x0000(r3)
635         blr
636
637 /*
638  * Function:    in16r
639  * Description: Input 16 bits and byte reverse
640  */
641         .globl  in16r
642 in16r:
643         lhbrx   r3,r0,r3
644         blr
645
646 /*
647  * Function:    in32
648  * Description: Input 32 bits
649  */
650         .globl  in32
651 in32:
652         lwz     3,0x0000(3)
653         blr
654
655 /*
656  * Function:    in32r
657  * Description: Input 32 bits and byte reverse
658  */
659         .globl  in32r
660 in32r:
661         lwbrx   r3,r0,r3
662         blr
663
664 /*
665  * void relocate_code (addr_sp, gd, addr_moni)
666  *
667  * This "function" does not return, instead it continues in RAM
668  * after relocating the monitor code.
669  *
670  * r3 = dest
671  * r4 = src
672  * r5 = length in bytes
673  * r6 = cachelinesize
674  */
675         .globl  relocate_code
676 relocate_code:
677
678         mr      r1,  r3         /* Set new stack pointer                */
679         mr      r9,  r4         /* Save copy of Global Data pointer     */
680         mr      r10, r5         /* Save copy of Destination Address     */
681
682         GET_GOT
683         mr      r3,  r5                         /* Destination Address  */
684         lis     r4, CONFIG_SYS_MONITOR_BASE@h           /* Source      Address  */
685         ori     r4, r4, CONFIG_SYS_MONITOR_BASE@l
686         lwz     r5, GOT(__init_end)
687         sub     r5, r5, r4
688         li      r6, CONFIG_SYS_CACHELINE_SIZE           /* Cache Line Size      */
689
690         /*
691          * Fix GOT pointer:
692          *
693          * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address
694          *
695          * Offset:
696          */
697         sub     r15, r10, r4
698
699         /* First our own GOT */
700         add     r12, r12, r15
701         /* then the one used by the C code */
702         add     r30, r30, r15
703
704         /*
705          * Now relocate code
706          */
707         cmplw   cr1,r3,r4
708         addi    r0,r5,3
709         srwi.   r0,r0,2
710         beq     cr1,4f          /* In place copy is not necessary       */
711         beq     7f              /* Protect against 0 count              */
712         mtctr   r0
713         bge     cr1,2f
714
715         la      r8,-4(r4)
716         la      r7,-4(r3)
717 1:      lwzu    r0,4(r8)
718         stwu    r0,4(r7)
719         bdnz    1b
720         b       4f
721
722 2:      slwi    r0,r0,2
723         add     r8,r4,r0
724         add     r7,r3,r0
725 3:      lwzu    r0,-4(r8)
726         stwu    r0,-4(r7)
727         bdnz    3b
728 /*
729  * Now flush the cache: note that we must start from a cache aligned
730  * address. Otherwise we might miss one cache line.
731  */
732 4:      cmpwi   r6,0
733         add     r5,r3,r5
734         beq     7f              /* Always flush prefetch queue in any case */
735         subi    r0,r6,1
736         andc    r3,r3,r0
737         mr      r4,r3
738 5:      dcbst   0,r4
739         add     r4,r4,r6
740         cmplw   r4,r5
741         blt     5b
742         sync                    /* Wait for all dcbst to complete on bus */
743         mr      r4,r3
744 6:      icbi    0,r4
745         add     r4,r4,r6
746         cmplw   r4,r5
747         blt     6b
748 7:      sync                    /* Wait for all icbi to complete on bus */
749         isync
750
751 /*
752  * We are done. Do not return, instead branch to second part of board
753  * initialization, now running from RAM.
754  */
755         addi    r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
756         mtlr    r0
757         blr
758
759 in_ram:
760         /*
761          * Relocation Function, r12 point to got2+0x8000
762          *
763          * Adjust got2 pointers, no need to check for 0, this code
764          * already puts a few entries in the table.
765          */
766         li      r0,__got2_entries@sectoff@l
767         la      r3,GOT(_GOT2_TABLE_)
768         lwz     r11,GOT(_GOT2_TABLE_)
769         mtctr   r0
770         sub     r11,r3,r11
771         addi    r3,r3,-4
772 1:      lwzu    r0,4(r3)
773         cmpwi   r0,0
774         beq-    2f
775         add     r0,r0,r11
776         stw     r0,0(r3)
777 2:      bdnz    1b
778
779         /*
780          * Now adjust the fixups and the pointers to the fixups
781          * in case we need to move ourselves again.
782          */
783         li      r0,__fixup_entries@sectoff@l
784         lwz     r3,GOT(_FIXUP_TABLE_)
785         cmpwi   r0,0
786         mtctr   r0
787         addi    r3,r3,-4
788         beq     4f
789 3:      lwzu    r4,4(r3)
790         lwzux   r0,r4,r11
791         cmpwi   r0,0
792         add     r0,r0,r11
793         stw     r4,0(r3)
794         beq-    5f
795         stw     r0,0(r4)
796 5:      bdnz    3b
797 4:
798 /* clear_bss: */
799         /*
800          * Now clear BSS segment
801          */
802         lwz     r3,GOT(__bss_start)
803         lwz     r4,GOT(__bss_end)
804
805         cmplw   0, r3, r4
806         beq     6f
807
808         li      r0, 0
809 5:
810         stw     r0, 0(r3)
811         addi    r3, r3, 4
812         cmplw   0, r3, r4
813         bne     5b
814 6:
815         mr      r3, r9          /* Init Date pointer            */
816         mr      r4, r10         /* Destination Address          */
817         bl      board_init_r
818
819         /* not reached - end relocate_code */
820 /*-----------------------------------------------------------------------*/
821
822         /*
823          * Copy exception vector code to low memory
824          *
825          * r3: dest_addr
826          * r7: source address, r8: end address, r9: target address
827          */
828         .globl  trap_init
829 trap_init:
830         mflr    r4                      /* save link register           */
831         GET_GOT
832         lwz     r7, GOT(_start)
833         lwz     r8, GOT(_end_of_vectors)
834
835         li      r9, 0x100               /* reset vector always at 0x100 */
836
837         cmplw   0, r7, r8
838         bgelr                           /* return if r7>=r8 - just in case */
839 1:
840         lwz     r0, 0(r7)
841         stw     r0, 0(r9)
842         addi    r7, r7, 4
843         addi    r9, r9, 4
844         cmplw   0, r7, r8
845         bne     1b
846
847         /*
848          * relocate `hdlr' and `int_return' entries
849          */
850         li      r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
851         li      r8, Alignment - _start + EXC_OFF_SYS_RESET
852 2:
853         bl      trap_reloc
854         addi    r7, r7, 0x100           /* next exception vector        */
855         cmplw   0, r7, r8
856         blt     2b
857
858         li      r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
859         bl      trap_reloc
860
861         li      r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
862         bl      trap_reloc
863
864         li      r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
865         li      r8, SystemCall - _start + EXC_OFF_SYS_RESET
866 3:
867         bl      trap_reloc
868         addi    r7, r7, 0x100           /* next exception vector        */
869         cmplw   0, r7, r8
870         blt     3b
871
872         li      r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
873         li      r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
874 4:
875         bl      trap_reloc
876         addi    r7, r7, 0x100           /* next exception vector        */
877         cmplw   0, r7, r8
878         blt     4b
879
880         /* enable execptions from RAM vectors */
881         mfmsr   r7
882         li      r8,MSR_IP
883         andc    r7,r7,r8
884         ori     r7,r7,MSR_ME            /* Enable Machine Check */
885         mtmsr   r7
886
887         mtlr    r4                      /* restore link register        */
888         blr
889
890 .globl enable_ext_addr
891 enable_ext_addr:
892         mfspr   r0, HID0
893         lis     r0, (HID0_HIGH_BAT_EN | HID0_XBSEN | HID0_XAEN)@h
894         ori     r0, r0, (HID0_HIGH_BAT_EN | HID0_XBSEN | HID0_XAEN)@l
895         mtspr   HID0, r0
896         sync
897         isync
898         blr
899
900 #if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR)
901 .globl setup_ccsrbar
902 setup_ccsrbar:
903         /* Special sequence needed to update CCSRBAR itself */
904         lis     r4, CONFIG_SYS_CCSRBAR_DEFAULT@h
905         ori     r4, r4, CONFIG_SYS_CCSRBAR_DEFAULT@l
906
907         lis     r5, CONFIG_SYS_CCSRBAR_PHYS_LOW@h
908         ori     r5, r5, CONFIG_SYS_CCSRBAR_PHYS_LOW@l
909         srwi    r5,r5,12
910         li      r6, CONFIG_SYS_CCSRBAR_PHYS_HIGH@l
911         rlwimi  r5,r6,20,8,11
912         stw     r5, 0(r4) /* Store physical value of CCSR */
913         isync
914
915         lis     r5, CONFIG_SYS_TEXT_BASE@h
916         ori     r5,r5,CONFIG_SYS_TEXT_BASE@l
917         lwz     r5, 0(r5)
918         isync
919
920         /* Use VA of CCSR to do read */
921         lis     r3, CONFIG_SYS_CCSRBAR@h
922         lwz     r5, CONFIG_SYS_CCSRBAR@l(r3)
923         isync
924
925         blr
926 #endif
927
928 #ifdef CONFIG_SYS_INIT_RAM_LOCK
929 lock_ram_in_cache:
930         /* Allocate Initial RAM in data cache.
931          */
932         lis     r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@h
933         ori     r3, r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@l
934         li      r4, ((CONFIG_SYS_INIT_RAM_SIZE & ~31) + \
935                      (CONFIG_SYS_INIT_RAM_ADDR & 31) + 31) / 32
936         mtctr   r4
937 1:
938         dcbz    r0, r3
939         addi    r3, r3, 32
940         bdnz    1b
941 #if 1
942 /* Lock the data cache */
943         mfspr   r0, HID0
944         ori     r0, r0, 0x1000
945         sync
946         mtspr   HID0, r0
947         sync
948         blr
949 #endif
950 #if 0
951         /* Lock the first way of the data cache */
952         mfspr   r0, LDSTCR
953         ori     r0, r0, 0x0080
954 #if defined(CONFIG_ALTIVEC)
955         dssall
956 #endif
957         sync
958         mtspr   LDSTCR, r0
959         sync
960         isync
961         blr
962 #endif
963
964 .globl unlock_ram_in_cache
965 unlock_ram_in_cache:
966         /* invalidate the INIT_RAM section */
967         lis     r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@h
968         ori     r3, r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@l
969         li      r4, ((CONFIG_SYS_INIT_RAM_SIZE & ~31) + \
970                      (CONFIG_SYS_INIT_RAM_ADDR & 31) + 31) / 32
971         mtctr   r4
972 1:      icbi    r0, r3
973         addi    r3, r3, 32
974         bdnz    1b
975         sync                    /* Wait for all icbi to complete on bus */
976         isync
977 #if 1
978 /* Unlock the data cache and invalidate it */
979         mfspr   r0, HID0
980         li      r3,0x1000
981         andc    r0,r0,r3
982         li      r3,0x0400
983         or      r0,r0,r3
984         sync
985         mtspr   HID0, r0
986         sync
987         blr
988 #endif
989 #if 0
990         /* Unlock the first way of the data cache */
991         mfspr   r0, LDSTCR
992         li      r3,0x0080
993         andc    r0,r0,r3
994 #ifdef CONFIG_ALTIVEC
995         dssall
996 #endif
997         sync
998         mtspr   LDSTCR, r0
999         sync
1000         isync
1001         li      r3,0x0400
1002         or      r0,r0,r3
1003         sync
1004         mtspr   HID0, r0
1005         sync
1006         blr
1007 #endif
1008 #endif