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