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