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