Merge branch 'master' of git://git.denx.de/u-boot-x86
[platform/kernel/u-boot.git] / 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 #if defined(__pic__) && __pic__ == 1
259         /* Needed for upcoming -msingle-pic-base */
260         bl      _GLOBAL_OFFSET_TABLE_@local-4
261         mflr    r30
262 #endif
263         /* run low-level CPU init code     (from Flash) */
264         bl      cpu_init_f
265         sync
266
267 #ifdef  RUN_DIAG
268
269         /* Load PX_AUX register address in r4 */
270         lis     r4, PIXIS_BASE@h
271         ori     r4, r4, 0x6
272         /* Load contents of PX_AUX in r3 bits 24 to 31*/
273         lbz     r3, 0(r4)
274
275         /* Mask and obtain the bit in r3 */
276         rlwinm. r3, r3, 0, 24, 24
277         /* If not zero, jump and continue with u-boot */
278         bne     diag_done
279
280         /* Load back contents of PX_AUX in r3 bits 24 to 31 */
281         lbz     r3, 0(r4)
282         /* Set the MSB of the register value */
283         ori     r3, r3, 0x80
284         /* Write value in r3 back to PX_AUX */
285         stb     r3, 0(r4)
286
287         /* Get the address to jump to in r3*/
288         lis     r3, CONFIG_SYS_DIAG_ADDR@h
289         ori     r3, r3, CONFIG_SYS_DIAG_ADDR@l
290
291         /* Load the LR with the branch address */
292         mtlr    r3
293
294         /* Branch to diagnostic */
295         blr
296
297 diag_done:
298 #endif
299
300 /*      bl      l2cache_enable */
301
302         /* run 1st part of board init code (from Flash)   */
303         bl      board_init_f
304         sync
305
306         /* NOTREACHED - board_init_f() does not return */
307
308         .globl  invalidate_bats
309 invalidate_bats:
310
311         li      r0, 0
312         /* invalidate BATs */
313         mtspr   IBAT0U, r0
314         mtspr   IBAT1U, r0
315         mtspr   IBAT2U, r0
316         mtspr   IBAT3U, r0
317         mtspr   IBAT4U, r0
318         mtspr   IBAT5U, r0
319         mtspr   IBAT6U, r0
320         mtspr   IBAT7U, r0
321
322         isync
323         mtspr   DBAT0U, r0
324         mtspr   DBAT1U, r0
325         mtspr   DBAT2U, r0
326         mtspr   DBAT3U, r0
327         mtspr   DBAT4U, r0
328         mtspr   DBAT5U, r0
329         mtspr   DBAT6U, r0
330         mtspr   DBAT7U, r0
331
332         isync
333         sync
334         blr
335
336 /*
337  * early_bats:
338  *
339  * Set up bats needed early on - this is usually the BAT for the
340  * stack-in-cache, the Flash, and CCSR space
341  */
342         .globl  early_bats
343 early_bats:
344         /* IBAT 3 */
345         lis     r4, CONFIG_SYS_IBAT3L@h
346         ori     r4, r4, CONFIG_SYS_IBAT3L@l
347         lis     r3, CONFIG_SYS_IBAT3U@h
348         ori     r3, r3, CONFIG_SYS_IBAT3U@l
349         mtspr   IBAT3L, r4
350         mtspr   IBAT3U, r3
351         isync
352
353         /* DBAT 3 */
354         lis     r4, CONFIG_SYS_DBAT3L@h
355         ori     r4, r4, CONFIG_SYS_DBAT3L@l
356         lis     r3, CONFIG_SYS_DBAT3U@h
357         ori     r3, r3, CONFIG_SYS_DBAT3U@l
358         mtspr   DBAT3L, r4
359         mtspr   DBAT3U, r3
360         isync
361
362         /* IBAT 5 */
363         lis     r4, CONFIG_SYS_IBAT5L@h
364         ori     r4, r4, CONFIG_SYS_IBAT5L@l
365         lis     r3, CONFIG_SYS_IBAT5U@h
366         ori     r3, r3, CONFIG_SYS_IBAT5U@l
367         mtspr   IBAT5L, r4
368         mtspr   IBAT5U, r3
369         isync
370
371         /* DBAT 5 */
372         lis     r4, CONFIG_SYS_DBAT5L@h
373         ori     r4, r4, CONFIG_SYS_DBAT5L@l
374         lis     r3, CONFIG_SYS_DBAT5U@h
375         ori     r3, r3, CONFIG_SYS_DBAT5U@l
376         mtspr   DBAT5L, r4
377         mtspr   DBAT5U, r3
378         isync
379
380         /* IBAT 6 */
381         lis     r4, CONFIG_SYS_IBAT6L_EARLY@h
382         ori     r4, r4, CONFIG_SYS_IBAT6L_EARLY@l
383         lis     r3, CONFIG_SYS_IBAT6U_EARLY@h
384         ori     r3, r3, CONFIG_SYS_IBAT6U_EARLY@l
385         mtspr   IBAT6L, r4
386         mtspr   IBAT6U, r3
387         isync
388
389         /* DBAT 6 */
390         lis     r4, CONFIG_SYS_DBAT6L_EARLY@h
391         ori     r4, r4, CONFIG_SYS_DBAT6L_EARLY@l
392         lis     r3, CONFIG_SYS_DBAT6U_EARLY@h
393         ori     r3, r3, CONFIG_SYS_DBAT6U_EARLY@l
394         mtspr   DBAT6L, r4
395         mtspr   DBAT6U, r3
396         isync
397
398 #if(CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR)
399         /* IBAT 7 */
400         lis     r4, CONFIG_SYS_CCSR_DEFAULT_IBATL@h
401         ori     r4, r4, CONFIG_SYS_CCSR_DEFAULT_IBATL@l
402         lis     r3, CONFIG_SYS_CCSR_DEFAULT_IBATU@h
403         ori     r3, r3, CONFIG_SYS_CCSR_DEFAULT_IBATU@l
404         mtspr   IBAT7L, r4
405         mtspr   IBAT7U, r3
406         isync
407
408         /* DBAT 7 */
409         lis     r4, CONFIG_SYS_CCSR_DEFAULT_DBATL@h
410         ori     r4, r4, CONFIG_SYS_CCSR_DEFAULT_DBATL@l
411         lis     r3, CONFIG_SYS_CCSR_DEFAULT_DBATU@h
412         ori     r3, r3, CONFIG_SYS_CCSR_DEFAULT_DBATU@l
413         mtspr   DBAT7L, r4
414         mtspr   DBAT7U, r3
415         isync
416 #endif
417         blr
418
419         .globl clear_tlbs
420 clear_tlbs:
421         addis   r3, 0, 0x0000
422         addis   r5, 0, 0x4
423         isync
424 tlblp:
425         tlbie   r3
426         sync
427         addi    r3, r3, 0x1000
428         cmp     0, 0, r3, r5
429         blt tlblp
430         blr
431
432         .globl disable_addr_trans
433 disable_addr_trans:
434         /* disable address translation */
435         mflr    r4
436         mfmsr   r3
437         andi.   r0, r3, (MSR_IR | MSR_DR)
438         beqlr
439         andc    r3, r3, r0
440         mtspr   SRR0, r4
441         mtspr   SRR1, r3
442         rfi
443
444 /*
445  * This code finishes saving the registers to the exception frame
446  * and jumps to the appropriate handler for the exception.
447  * Register r21 is pointer into trap frame, r1 has new stack pointer.
448  */
449         .globl  transfer_to_handler
450 transfer_to_handler:
451         stw     r22,_NIP(r21)
452         lis     r22,MSR_POW@h
453         andc    r23,r23,r22
454         stw     r23,_MSR(r21)
455         SAVE_GPR(7, r21)
456         SAVE_4GPRS(8, r21)
457         SAVE_8GPRS(12, r21)
458         SAVE_8GPRS(24, r21)
459         mflr    r23
460         andi.   r24,r23,0x3f00          /* get vector offset */
461         stw     r24,TRAP(r21)
462         li      r22,0
463         stw     r22,RESULT(r21)
464         mtspr   SPRG2,r22               /* r1 is now kernel sp */
465         lwz     r24,0(r23)              /* virtual address of handler */
466         lwz     r23,4(r23)              /* where to go when done */
467         mtspr   SRR0,r24
468         mtspr   SRR1,r20
469         mtlr    r23
470         SYNC
471         rfi                             /* jump to handler, enable MMU */
472
473 int_return:
474         mfmsr   r28             /* Disable interrupts */
475         li      r4,0
476         ori     r4,r4,MSR_EE
477         andc    r28,r28,r4
478         SYNC                    /* Some chip revs need this... */
479         mtmsr   r28
480         SYNC
481         lwz     r2,_CTR(r1)
482         lwz     r0,_LINK(r1)
483         mtctr   r2
484         mtlr    r0
485         lwz     r2,_XER(r1)
486         lwz     r0,_CCR(r1)
487         mtspr   XER,r2
488         mtcrf   0xFF,r0
489         REST_10GPRS(3, r1)
490         REST_10GPRS(13, r1)
491         REST_8GPRS(23, r1)
492         REST_GPR(31, r1)
493         lwz     r2,_NIP(r1)     /* Restore environment */
494         lwz     r0,_MSR(r1)
495         mtspr   SRR0,r2
496         mtspr   SRR1,r0
497         lwz     r0,GPR0(r1)
498         lwz     r2,GPR2(r1)
499         lwz     r1,GPR1(r1)
500         SYNC
501         rfi
502
503         .globl  dc_read
504 dc_read:
505         blr
506
507         .globl get_pvr
508 get_pvr:
509         mfspr   r3, PVR
510         blr
511
512         .globl get_svr
513 get_svr:
514         mfspr   r3, SVR
515         blr
516
517
518 /*
519  * Function:    in8
520  * Description: Input 8 bits
521  */
522         .globl  in8
523 in8:
524         lbz     r3,0x0000(r3)
525         blr
526
527 /*
528  * Function:    out8
529  * Description: Output 8 bits
530  */
531         .globl  out8
532 out8:
533         stb     r4,0x0000(r3)
534         blr
535
536 /*
537  * Function:    out16
538  * Description: Output 16 bits
539  */
540         .globl  out16
541 out16:
542         sth     r4,0x0000(r3)
543         blr
544
545 /*
546  * Function:    out16r
547  * Description: Byte reverse and output 16 bits
548  */
549         .globl  out16r
550 out16r:
551         sthbrx  r4,r0,r3
552         blr
553
554 /*
555  * Function:    out32
556  * Description: Output 32 bits
557  */
558         .globl  out32
559 out32:
560         stw     r4,0x0000(r3)
561         blr
562
563 /*
564  * Function:    out32r
565  * Description: Byte reverse and output 32 bits
566  */
567         .globl  out32r
568 out32r:
569         stwbrx  r4,r0,r3
570         blr
571
572 /*
573  * Function:    in16
574  * Description: Input 16 bits
575  */
576         .globl  in16
577 in16:
578         lhz     r3,0x0000(r3)
579         blr
580
581 /*
582  * Function:    in16r
583  * Description: Input 16 bits and byte reverse
584  */
585         .globl  in16r
586 in16r:
587         lhbrx   r3,r0,r3
588         blr
589
590 /*
591  * Function:    in32
592  * Description: Input 32 bits
593  */
594         .globl  in32
595 in32:
596         lwz     3,0x0000(3)
597         blr
598
599 /*
600  * Function:    in32r
601  * Description: Input 32 bits and byte reverse
602  */
603         .globl  in32r
604 in32r:
605         lwbrx   r3,r0,r3
606         blr
607
608 /*
609  * void relocate_code (addr_sp, gd, addr_moni)
610  *
611  * This "function" does not return, instead it continues in RAM
612  * after relocating the monitor code.
613  *
614  * r3 = dest
615  * r4 = src
616  * r5 = length in bytes
617  * r6 = cachelinesize
618  */
619         .globl  relocate_code
620 relocate_code:
621
622         mr      r1,  r3         /* Set new stack pointer                */
623         mr      r9,  r4         /* Save copy of Global Data pointer     */
624         mr      r10, r5         /* Save copy of Destination Address     */
625
626         GET_GOT
627 #if defined(__pic__) && __pic__ == 1
628         /* Needed for upcoming -msingle-pic-base */
629         bl      _GLOBAL_OFFSET_TABLE_@local-4
630         mflr    r30
631 #endif
632         mr      r3,  r5                         /* Destination Address  */
633         lis     r4, CONFIG_SYS_MONITOR_BASE@h           /* Source      Address  */
634         ori     r4, r4, CONFIG_SYS_MONITOR_BASE@l
635         lwz     r5, GOT(__init_end)
636         sub     r5, r5, r4
637         li      r6, CONFIG_SYS_CACHELINE_SIZE           /* Cache Line Size      */
638
639         /*
640          * Fix GOT pointer:
641          *
642          * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address
643          *
644          * Offset:
645          */
646         sub     r15, r10, r4
647
648         /* First our own GOT */
649         add     r12, r12, r15
650         /* then the one used by the C code */
651         add     r30, r30, r15
652
653         /*
654          * Now relocate code
655          */
656         cmplw   cr1,r3,r4
657         addi    r0,r5,3
658         srwi.   r0,r0,2
659         beq     cr1,4f          /* In place copy is not necessary       */
660         beq     7f              /* Protect against 0 count              */
661         mtctr   r0
662         bge     cr1,2f
663
664         la      r8,-4(r4)
665         la      r7,-4(r3)
666 1:      lwzu    r0,4(r8)
667         stwu    r0,4(r7)
668         bdnz    1b
669         b       4f
670
671 2:      slwi    r0,r0,2
672         add     r8,r4,r0
673         add     r7,r3,r0
674 3:      lwzu    r0,-4(r8)
675         stwu    r0,-4(r7)
676         bdnz    3b
677 /*
678  * Now flush the cache: note that we must start from a cache aligned
679  * address. Otherwise we might miss one cache line.
680  */
681 4:      cmpwi   r6,0
682         add     r5,r3,r5
683         beq     7f              /* Always flush prefetch queue in any case */
684         subi    r0,r6,1
685         andc    r3,r3,r0
686         mr      r4,r3
687 5:      dcbst   0,r4
688         add     r4,r4,r6
689         cmplw   r4,r5
690         blt     5b
691         sync                    /* Wait for all dcbst to complete on bus */
692         mr      r4,r3
693 6:      icbi    0,r4
694         add     r4,r4,r6
695         cmplw   r4,r5
696         blt     6b
697 7:      sync                    /* Wait for all icbi to complete on bus */
698         isync
699
700 /*
701  * We are done. Do not return, instead branch to second part of board
702  * initialization, now running from RAM.
703  */
704         addi    r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
705         mtlr    r0
706         blr
707
708 in_ram:
709         /*
710          * Relocation Function, r12 point to got2+0x8000
711          *
712          * Adjust got2 pointers, no need to check for 0, this code
713          * already puts a few entries in the table.
714          */
715         li      r0,__got2_entries@sectoff@l
716         la      r3,GOT(_GOT2_TABLE_)
717         lwz     r11,GOT(_GOT2_TABLE_)
718         mtctr   r0
719         sub     r11,r3,r11
720         addi    r3,r3,-4
721 1:      lwzu    r0,4(r3)
722         cmpwi   r0,0
723         beq-    2f
724         add     r0,r0,r11
725         stw     r0,0(r3)
726 2:      bdnz    1b
727
728         /*
729          * Now adjust the fixups and the pointers to the fixups
730          * in case we need to move ourselves again.
731          */
732         li      r0,__fixup_entries@sectoff@l
733         lwz     r3,GOT(_FIXUP_TABLE_)
734         cmpwi   r0,0
735         mtctr   r0
736         addi    r3,r3,-4
737         beq     4f
738 3:      lwzu    r4,4(r3)
739         lwzux   r0,r4,r11
740         cmpwi   r0,0
741         add     r0,r0,r11
742         stw     r4,0(r3)
743         beq-    5f
744         stw     r0,0(r4)
745 5:      bdnz    3b
746 4:
747 /* clear_bss: */
748         /*
749          * Now clear BSS segment
750          */
751         lwz     r3,GOT(__bss_start)
752         lwz     r4,GOT(__bss_end__)
753
754         cmplw   0, r3, r4
755         beq     6f
756
757         li      r0, 0
758 5:
759         stw     r0, 0(r3)
760         addi    r3, r3, 4
761         cmplw   0, r3, r4
762         bne     5b
763 6:
764         mr      r3, r9          /* Init Date pointer            */
765         mr      r4, r10         /* Destination Address          */
766         bl      board_init_r
767
768         /* not reached - end relocate_code */
769 /*-----------------------------------------------------------------------*/
770
771         /*
772          * Copy exception vector code to low memory
773          *
774          * r3: dest_addr
775          * r7: source address, r8: end address, r9: target address
776          */
777         .globl  trap_init
778 trap_init:
779         mflr    r4                      /* save link register           */
780         GET_GOT
781         lwz     r7, GOT(_start)
782         lwz     r8, GOT(_end_of_vectors)
783
784         li      r9, 0x100               /* reset vector always at 0x100 */
785
786         cmplw   0, r7, r8
787         bgelr                           /* return if r7>=r8 - just in case */
788 1:
789         lwz     r0, 0(r7)
790         stw     r0, 0(r9)
791         addi    r7, r7, 4
792         addi    r9, r9, 4
793         cmplw   0, r7, r8
794         bne     1b
795
796         /*
797          * relocate `hdlr' and `int_return' entries
798          */
799         li      r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
800         li      r8, Alignment - _start + EXC_OFF_SYS_RESET
801 2:
802         bl      trap_reloc
803         addi    r7, r7, 0x100           /* next exception vector        */
804         cmplw   0, r7, r8
805         blt     2b
806
807         li      r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
808         bl      trap_reloc
809
810         li      r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
811         bl      trap_reloc
812
813         li      r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
814         li      r8, SystemCall - _start + EXC_OFF_SYS_RESET
815 3:
816         bl      trap_reloc
817         addi    r7, r7, 0x100           /* next exception vector        */
818         cmplw   0, r7, r8
819         blt     3b
820
821         li      r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
822         li      r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
823 4:
824         bl      trap_reloc
825         addi    r7, r7, 0x100           /* next exception vector        */
826         cmplw   0, r7, r8
827         blt     4b
828
829         /* enable execptions from RAM vectors */
830         mfmsr   r7
831         li      r8,MSR_IP
832         andc    r7,r7,r8
833         ori     r7,r7,MSR_ME            /* Enable Machine Check */
834         mtmsr   r7
835
836         mtlr    r4                      /* restore link register        */
837         blr
838
839 .globl enable_ext_addr
840 enable_ext_addr:
841         mfspr   r0, HID0
842         lis     r0, (HID0_HIGH_BAT_EN | HID0_XBSEN | HID0_XAEN)@h
843         ori     r0, r0, (HID0_HIGH_BAT_EN | HID0_XBSEN | HID0_XAEN)@l
844         mtspr   HID0, r0
845         sync
846         isync
847         blr
848
849 #if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR)
850 .globl setup_ccsrbar
851 setup_ccsrbar:
852         /* Special sequence needed to update CCSRBAR itself */
853         lis     r4, CONFIG_SYS_CCSRBAR_DEFAULT@h
854         ori     r4, r4, CONFIG_SYS_CCSRBAR_DEFAULT@l
855
856         lis     r5, CONFIG_SYS_CCSRBAR_PHYS_LOW@h
857         ori     r5, r5, CONFIG_SYS_CCSRBAR_PHYS_LOW@l
858         srwi    r5,r5,12
859         li      r6, CONFIG_SYS_CCSRBAR_PHYS_HIGH@l
860         rlwimi  r5,r6,20,8,11
861         stw     r5, 0(r4) /* Store physical value of CCSR */
862         isync
863
864         lis     r5, CONFIG_SYS_TEXT_BASE@h
865         ori     r5,r5,CONFIG_SYS_TEXT_BASE@l
866         lwz     r5, 0(r5)
867         isync
868
869         /* Use VA of CCSR to do read */
870         lis     r3, CONFIG_SYS_CCSRBAR@h
871         lwz     r5, CONFIG_SYS_CCSRBAR@l(r3)
872         isync
873
874         blr
875 #endif
876
877 #ifdef CONFIG_SYS_INIT_RAM_LOCK
878 lock_ram_in_cache:
879         /* Allocate Initial RAM in data cache.
880          */
881         lis     r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@h
882         ori     r3, r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@l
883         li      r4, ((CONFIG_SYS_INIT_RAM_SIZE & ~31) + \
884                      (CONFIG_SYS_INIT_RAM_ADDR & 31) + 31) / 32
885         mtctr   r4
886 1:
887         dcbz    r0, r3
888         addi    r3, r3, 32
889         bdnz    1b
890 #if 1
891 /* Lock the data cache */
892         mfspr   r0, HID0
893         ori     r0, r0, 0x1000
894         sync
895         mtspr   HID0, r0
896         sync
897         blr
898 #endif
899 #if 0
900         /* Lock the first way of the data cache */
901         mfspr   r0, LDSTCR
902         ori     r0, r0, 0x0080
903 #if defined(CONFIG_ALTIVEC)
904         dssall
905 #endif
906         sync
907         mtspr   LDSTCR, r0
908         sync
909         isync
910         blr
911 #endif
912
913 .globl unlock_ram_in_cache
914 unlock_ram_in_cache:
915         /* invalidate the INIT_RAM section */
916         lis     r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@h
917         ori     r3, r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@l
918         li      r4, ((CONFIG_SYS_INIT_RAM_SIZE & ~31) + \
919                      (CONFIG_SYS_INIT_RAM_ADDR & 31) + 31) / 32
920         mtctr   r4
921 1:      icbi    r0, r3
922         addi    r3, r3, 32
923         bdnz    1b
924         sync                    /* Wait for all icbi to complete on bus */
925         isync
926 #if 1
927 /* Unlock the data cache and invalidate it */
928         mfspr   r0, HID0
929         li      r3,0x1000
930         andc    r0,r0,r3
931         li      r3,0x0400
932         or      r0,r0,r3
933         sync
934         mtspr   HID0, r0
935         sync
936         blr
937 #endif
938 #if 0
939         /* Unlock the first way of the data cache */
940         mfspr   r0, LDSTCR
941         li      r3,0x0080
942         andc    r0,r0,r3
943 #ifdef CONFIG_ALTIVEC
944         dssall
945 #endif
946         sync
947         mtspr   LDSTCR, r0
948         sync
949         isync
950         li      r3,0x0400
951         or      r0,r0,r3
952         sync
953         mtspr   HID0, r0
954         sync
955         blr
956 #endif
957 #endif