]> git.sur5r.net Git - u-boot/blob - cpu/ppc4xx/start.S
a46197dde98cb8563efa03346cda6f98a86bafca
[u-boot] / cpu / ppc4xx / start.S
1 /*
2  *  Copyright (C) 1998  Dan Malek <dmalek@jlc.net>
3  *  Copyright (C) 1999  Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
4  *  Copyright (C) 2000,2001,2002 Wolfgang Denk <wd@denx.de>
5  *  Copyright (C) 2007 Stefan Roese <sr@denx.de>, DENX Software Engineering
6  *
7  * See file CREDITS for list of people who contributed to this
8  * project.
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License as
12  * published by the Free Software Foundation; either version 2 of
13  * the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
23  * MA 02111-1307 USA
24  */
25 /*------------------------------------------------------------------------------+
26  *
27  *       This source code has been made available to you by IBM on an AS-IS
28  *       basis.  Anyone receiving this source is licensed under IBM
29  *       copyrights to use it in any way he or she deems fit, including
30  *       copying it, modifying it, compiling it, and redistributing it either
31  *       with or without modifications.  No license under IBM patents or
32  *       patent applications is to be implied by the copyright license.
33  *
34  *       Any user of this software should understand that IBM cannot provide
35  *       technical support for this software and will not be responsible for
36  *       any consequences resulting from the use of this software.
37  *
38  *       Any person who transfers this source code or any derivative work
39  *       must include the IBM copyright notice, this paragraph, and the
40  *       preceding two paragraphs in the transferred software.
41  *
42  *       COPYRIGHT   I B M   CORPORATION 1995
43  *       LICENSED MATERIAL  -  PROGRAM PROPERTY OF I B M
44  *-------------------------------------------------------------------------------
45  */
46
47 /*  U-Boot - Startup Code for AMCC 4xx PowerPC based Embedded Boards
48  *
49  *
50  *  The processor starts at 0xfffffffc and the code is executed
51  *  from flash/rom.
52  *  in memory, but as long we don't jump around before relocating.
53  *  board_init lies at a quite high address and when the cpu has
54  *  jumped there, everything is ok.
55  *  This works because the cpu gives the FLASH (CS0) the whole
56  *  address space at startup, and board_init lies as a echo of
57  *  the flash somewhere up there in the memorymap.
58  *
59  *  board_init will change CS0 to be positioned at the correct
60  *  address and (s)dram will be positioned at address 0
61  */
62 #include <config.h>
63 #include <mpc8xx.h>
64 #include <ppc4xx.h>
65 #include <version.h>
66
67 #define _LINUX_CONFIG_H 1       /* avoid reading Linux autoconf.h file  */
68
69 #include <ppc_asm.tmpl>
70 #include <ppc_defs.h>
71
72 #include <asm/cache.h>
73 #include <asm/mmu.h>
74
75 #ifndef  CONFIG_IDENT_STRING
76 #define  CONFIG_IDENT_STRING ""
77 #endif
78
79 #ifdef CFG_INIT_DCACHE_CS
80 # if (CFG_INIT_DCACHE_CS == 0)
81 #  define PBxAP pb0ap
82 #  define PBxCR pb0cr
83 # endif
84 # if (CFG_INIT_DCACHE_CS == 1)
85 #  define PBxAP pb1ap
86 #  define PBxCR pb1cr
87 # endif
88 # if (CFG_INIT_DCACHE_CS == 2)
89 #  define PBxAP pb2ap
90 #  define PBxCR pb2cr
91 # endif
92 # if (CFG_INIT_DCACHE_CS == 3)
93 #  define PBxAP pb3ap
94 #  define PBxCR pb3cr
95 # endif
96 # if (CFG_INIT_DCACHE_CS == 4)
97 #  define PBxAP pb4ap
98 #  define PBxCR pb4cr
99 # endif
100 # if (CFG_INIT_DCACHE_CS == 5)
101 #  define PBxAP pb5ap
102 #  define PBxCR pb5cr
103 # endif
104 # if (CFG_INIT_DCACHE_CS == 6)
105 #  define PBxAP pb6ap
106 #  define PBxCR pb6cr
107 # endif
108 # if (CFG_INIT_DCACHE_CS == 7)
109 #  define PBxAP pb7ap
110 #  define PBxCR pb7cr
111 # endif
112 #endif /* CFG_INIT_DCACHE_CS */
113
114 #define function_prolog(func_name)      .text; \
115                                         .align 2; \
116                                         .globl func_name; \
117                                         func_name:
118 #define function_epilog(func_name)      .type func_name,@function; \
119                                         .size func_name,.-func_name
120
121 /* We don't want the  MMU yet.
122 */
123 #undef  MSR_KERNEL
124 #define MSR_KERNEL ( MSR_ME  )  /* Machine Check */
125
126
127         .extern ext_bus_cntlr_init
128         .extern sdram_init
129 #ifdef CONFIG_NAND_U_BOOT
130         .extern reconfig_tlb0
131 #endif
132
133 /*
134  * Set up GOT: Global Offset Table
135  *
136  * Use r14 to access the GOT
137  */
138 #if !defined(CONFIG_NAND_SPL)
139         START_GOT
140         GOT_ENTRY(_GOT2_TABLE_)
141         GOT_ENTRY(_FIXUP_TABLE_)
142
143         GOT_ENTRY(_start)
144         GOT_ENTRY(_start_of_vectors)
145         GOT_ENTRY(_end_of_vectors)
146         GOT_ENTRY(transfer_to_handler)
147
148         GOT_ENTRY(__init_end)
149         GOT_ENTRY(_end)
150         GOT_ENTRY(__bss_start)
151         END_GOT
152 #endif /* CONFIG_NAND_SPL */
153
154 #if defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL)
155         /*
156          * NAND U-Boot image is started from offset 0
157          */
158         .text
159 #if defined(CONFIG_440)
160         bl      reconfig_tlb0
161 #endif
162         GET_GOT
163         bl      cpu_init_f      /* run low-level CPU init code     (from Flash) */
164         bl      board_init_f
165 #endif
166
167 /*
168  * 440 Startup -- on reset only the top 4k of the effective
169  * address space is mapped in by an entry in the instruction
170  * and data shadow TLB. The .bootpg section is located in the
171  * top 4k & does only what's necessary to map in the the rest
172  * of the boot rom. Once the boot rom is mapped in we can
173  * proceed with normal startup.
174  *
175  * NOTE: CS0 only covers the top 2MB of the effective address
176  * space after reset.
177  */
178
179 #if defined(CONFIG_440)
180 #if !defined(CONFIG_NAND_SPL)
181     .section .bootpg,"ax"
182 #endif
183     .globl _start_440
184
185 /**************************************************************************/
186 _start_440:
187         /*--------------------------------------------------------------------+
188         | 440EPX BUP Change - Hardware team request
189         +--------------------------------------------------------------------*/
190 #if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
191         sync
192         nop
193         nop
194 #endif
195         /*----------------------------------------------------------------+
196         | Core bug fix.  Clear the esr
197         +-----------------------------------------------------------------*/
198         li      r0,0
199         mtspr   esr,r0
200         /*----------------------------------------------------------------*/
201         /* Clear and set up some registers. */
202         /*----------------------------------------------------------------*/
203         iccci   r0,r0           /* NOTE: operands not used for 440 */
204         dccci   r0,r0           /* NOTE: operands not used for 440 */
205         sync
206         li      r0,0
207         mtspr   srr0,r0
208         mtspr   srr1,r0
209         mtspr   csrr0,r0
210         mtspr   csrr1,r0
211         /* NOTE: 440GX adds machine check status regs */
212 #if defined(CONFIG_440) && !defined(CONFIG_440GP)
213         mtspr   mcsrr0,r0
214         mtspr   mcsrr1,r0
215         mfspr   r1,mcsr
216         mtspr   mcsr,r1
217 #endif
218
219         /*----------------------------------------------------------------*/
220         /* CCR0 init */
221         /*----------------------------------------------------------------*/
222         /* Disable store gathering & broadcast, guarantee inst/data
223         * cache block touch, force load/store alignment
224         * (see errata 1.12: 440_33)
225         */
226         lis     r1,0x0030       /* store gathering & broadcast disable */
227         ori     r1,r1,0x6000    /* cache touch */
228         mtspr   ccr0,r1
229
230         /*----------------------------------------------------------------*/
231         /* Initialize debug */
232         /*----------------------------------------------------------------*/
233         mfspr   r1,dbcr0
234         andis.  r1, r1, 0x8000  /* test DBCR0[EDM] bit                  */
235         bne     skip_debug_init /* if set, don't clear debug register   */
236         mtspr   dbcr0,r0
237         mtspr   dbcr1,r0
238         mtspr   dbcr2,r0
239         mtspr   iac1,r0
240         mtspr   iac2,r0
241         mtspr   iac3,r0
242         mtspr   dac1,r0
243         mtspr   dac2,r0
244         mtspr   dvc1,r0
245         mtspr   dvc2,r0
246
247         mfspr   r1,dbsr
248         mtspr   dbsr,r1         /* Clear all valid bits */
249 skip_debug_init:
250
251 #if defined (CONFIG_440SPE)
252         /*----------------------------------------------------------------+
253         | Initialize Core Configuration Reg1.
254         | a. ICDPEI: Record even parity. Normal operation.
255         | b. ICTPEI: Record even parity. Normal operation.
256         | c. DCTPEI: Record even parity. Normal operation.
257         | d. DCDPEI: Record even parity. Normal operation.
258         | e. DCUPEI: Record even parity. Normal operation.
259         | f. DCMPEI: Record even parity. Normal operation.
260         | g. FCOM:   Normal operation
261         | h. MMUPEI: Record even parity. Normal operation.
262         | i. FFF:    Flush only as much data as necessary.
263         | j. TCS:    Timebase increments from CPU clock.
264         +-----------------------------------------------------------------*/
265         li      r0,0
266         mtspr   ccr1, r0
267
268         /*----------------------------------------------------------------+
269         | Reset the timebase.
270         | The previous write to CCR1 sets the timebase source.
271         +-----------------------------------------------------------------*/
272         mtspr   tbl, r0
273         mtspr   tbu, r0
274 #endif
275
276         /*----------------------------------------------------------------*/
277         /* Setup interrupt vectors */
278         /*----------------------------------------------------------------*/
279         mtspr   ivpr,r0         /* Vectors start at 0x0000_0000 */
280         li      r1,0x0100
281         mtspr   ivor0,r1        /* Critical input */
282         li      r1,0x0200
283         mtspr   ivor1,r1        /* Machine check */
284         li      r1,0x0300
285         mtspr   ivor2,r1        /* Data storage */
286         li      r1,0x0400
287         mtspr   ivor3,r1        /* Instruction storage */
288         li      r1,0x0500
289         mtspr   ivor4,r1        /* External interrupt */
290         li      r1,0x0600
291         mtspr   ivor5,r1        /* Alignment */
292         li      r1,0x0700
293         mtspr   ivor6,r1        /* Program check */
294         li      r1,0x0800
295         mtspr   ivor7,r1        /* Floating point unavailable */
296         li      r1,0x0c00
297         mtspr   ivor8,r1        /* System call */
298         li      r1,0x0a00
299         mtspr   ivor9,r1        /* Auxiliary Processor unavailable */
300         li      r1,0x0900
301         mtspr   ivor10,r1       /* Decrementer */
302         li      r1,0x1300
303         mtspr   ivor13,r1       /* Data TLB error */
304         li      r1,0x1400
305         mtspr   ivor14,r1       /* Instr TLB error */
306         li      r1,0x2000
307         mtspr   ivor15,r1       /* Debug */
308
309         /*----------------------------------------------------------------*/
310         /* Configure cache regions  */
311         /*----------------------------------------------------------------*/
312         mtspr   inv0,r0
313         mtspr   inv1,r0
314         mtspr   inv2,r0
315         mtspr   inv3,r0
316         mtspr   dnv0,r0
317         mtspr   dnv1,r0
318         mtspr   dnv2,r0
319         mtspr   dnv3,r0
320         mtspr   itv0,r0
321         mtspr   itv1,r0
322         mtspr   itv2,r0
323         mtspr   itv3,r0
324         mtspr   dtv0,r0
325         mtspr   dtv1,r0
326         mtspr   dtv2,r0
327         mtspr   dtv3,r0
328
329         /*----------------------------------------------------------------*/
330         /* Cache victim limits */
331         /*----------------------------------------------------------------*/
332         /* floors 0, ceiling max to use the entire cache -- nothing locked
333         */
334         lis     r1,0x0001
335         ori     r1,r1,0xf800
336         mtspr   ivlim,r1
337         mtspr   dvlim,r1
338
339         /*----------------------------------------------------------------+
340         |Initialize MMUCR[STID] = 0.
341         +-----------------------------------------------------------------*/
342         mfspr   r0,mmucr
343         addis   r1,0,0xFFFF
344         ori     r1,r1,0xFF00
345         and     r0,r0,r1
346         mtspr   mmucr,r0
347
348         /*----------------------------------------------------------------*/
349         /* Clear all TLB entries -- TID = 0, TS = 0 */
350         /*----------------------------------------------------------------*/
351         addis   r0,0,0x0000
352         li      r1,0x003f       /* 64 TLB entries */
353         mtctr   r1
354 rsttlb: tlbwe   r0,r1,0x0000    /* Invalidate all entries (V=0)*/
355         tlbwe   r0,r1,0x0001
356         tlbwe   r0,r1,0x0002
357         subi    r1,r1,0x0001
358         bdnz    rsttlb
359
360         /*----------------------------------------------------------------*/
361         /* TLB entry setup -- step thru tlbtab */
362         /*----------------------------------------------------------------*/
363 #if defined(CONFIG_440SPE)
364         /*----------------------------------------------------------------*/
365         /* We have different TLB tables for revA and rev B of 440SPe */
366         /*----------------------------------------------------------------*/
367         mfspr   r1, PVR
368         lis     r0,0x5342
369         ori     r0,r0,0x1891
370         cmpw    r7,r1,r0
371         bne     r7,..revA
372         bl      tlbtabB
373         b       ..goon
374 ..revA:
375         bl      tlbtabA
376 ..goon:
377 #else
378         bl      tlbtab          /* Get tlbtab pointer */
379 #endif
380         mr      r5,r0
381         li      r1,0x003f       /* 64 TLB entries max */
382         mtctr   r1
383         li      r4,0            /* TLB # */
384
385         addi    r5,r5,-4
386 1:      lwzu    r0,4(r5)
387         cmpwi   r0,0
388         beq     2f              /* 0 marks end */
389         lwzu    r1,4(r5)
390         lwzu    r2,4(r5)
391         tlbwe   r0,r4,0         /* TLB Word 0 */
392         tlbwe   r1,r4,1         /* TLB Word 1 */
393         tlbwe   r2,r4,2         /* TLB Word 2 */
394         addi    r4,r4,1         /* Next TLB */
395         bdnz    1b
396
397         /*----------------------------------------------------------------*/
398         /* Continue from 'normal' start */
399         /*----------------------------------------------------------------*/
400 2:
401
402 #if defined(CONFIG_NAND_SPL)
403 #if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
404         /*
405          * Enable internal SRAM (only on 440EPx/GRx, 440EP/GR have no OCM)
406          */
407         lis     r2,0x7fff
408         ori     r2,r2,0xffff
409         mfdcr   r1,isram0_dpc
410         and     r1,r1,r2                /* Disable parity check */
411         mtdcr   isram0_dpc,r1
412         mfdcr   r1,isram0_pmeg
413         and     r1,r1,r2                /* Disable pwr mgmt */
414         mtdcr   isram0_pmeg,r1
415 #endif
416 #if defined(CONFIG_440EP)
417         /*
418          * On 440EP with no internal SRAM, we setup SDRAM very early
419          * and copy the NAND_SPL to SDRAM and jump to it
420          */
421         /* Clear Dcache to use as RAM */
422         addis   r3,r0,CFG_INIT_RAM_ADDR@h
423         ori     r3,r3,CFG_INIT_RAM_ADDR@l
424         addis   r4,r0,CFG_INIT_RAM_END@h
425         ori     r4,r4,CFG_INIT_RAM_END@l
426         rlwinm. r5,r4,0,27,31
427         rlwinm  r5,r4,27,5,31
428         beq     ..d_ran3
429         addi    r5,r5,0x0001
430 ..d_ran3:
431         mtctr   r5
432 ..d_ag3:
433         dcbz    r0,r3
434         addi    r3,r3,32
435         bdnz    ..d_ag3
436         /*----------------------------------------------------------------*/
437         /* Setup the stack in internal SRAM */
438         /*----------------------------------------------------------------*/
439         lis     r1,CFG_INIT_RAM_ADDR@h
440         ori     r1,r1,CFG_INIT_SP_OFFSET@l
441         li      r0,0
442         stwu    r0,-4(r1)
443         stwu    r0,-4(r1)               /* Terminate call chain */
444
445         stwu    r1,-8(r1)               /* Save back chain and move SP */
446         lis     r0,RESET_VECTOR@h       /* Address of reset vector */
447         ori     r0,r0, RESET_VECTOR@l
448         stwu    r1,-8(r1)               /* Save back chain and move SP */
449         stw     r0,+12(r1)              /* Save return addr (underflow vect) */
450         sync
451         bl      early_sdram_init
452         sync
453 #endif /* CONFIG_440EP */
454
455         /*
456          * Copy SPL from cache into internal SRAM
457          */
458         li      r4,(CFG_NAND_BOOT_SPL_SIZE >> 2) - 1
459         mtctr   r4
460         lis     r2,CFG_NAND_BOOT_SPL_SRC@h
461         ori     r2,r2,CFG_NAND_BOOT_SPL_SRC@l
462         lis     r3,CFG_NAND_BOOT_SPL_DST@h
463         ori     r3,r3,CFG_NAND_BOOT_SPL_DST@l
464 spl_loop:
465         lwzu    r4,4(r2)
466         stwu    r4,4(r3)
467         bdnz    spl_loop
468
469         /*
470          * Jump to code in RAM
471          */
472         bl      00f
473 00:     mflr    r10
474         lis     r3,(CFG_NAND_BOOT_SPL_SRC - CFG_NAND_BOOT_SPL_DST)@h
475         ori     r3,r3,(CFG_NAND_BOOT_SPL_SRC - CFG_NAND_BOOT_SPL_DST)@l
476         sub     r10,r10,r3
477         addi    r10,r10,28
478         mtlr    r10
479         blr
480
481 start_ram:
482         sync
483         isync
484 #endif /* CONFIG_NAND_SPL */
485
486         bl      3f
487         b       _start
488
489 3:      li      r0,0
490         mtspr   srr1,r0         /* Keep things disabled for now */
491         mflr    r1
492         mtspr   srr0,r1
493         rfi
494 #endif /* CONFIG_440 */
495
496 /*
497  * r3 - 1st arg to board_init(): IMMP pointer
498  * r4 - 2nd arg to board_init(): boot flag
499  */
500 #ifndef CONFIG_NAND_SPL
501         .text
502         .long   0x27051956              /* U-Boot Magic Number                  */
503         .globl  version_string
504 version_string:
505         .ascii U_BOOT_VERSION
506         .ascii " (", __DATE__, " - ", __TIME__, ")"
507         .ascii CONFIG_IDENT_STRING, "\0"
508
509         . = EXC_OFF_SYS_RESET
510         .globl  _start_of_vectors
511 _start_of_vectors:
512
513 /* Critical input. */
514         CRIT_EXCEPTION(0x100, CritcalInput, UnknownException)
515
516 #ifdef CONFIG_440
517 /* Machine check */
518         MCK_EXCEPTION(0x200, MachineCheck, MachineCheckException)
519 #else
520         CRIT_EXCEPTION(0x200, MachineCheck, MachineCheckException)
521 #endif /* CONFIG_440 */
522
523 /* Data Storage exception. */
524         STD_EXCEPTION(0x300, DataStorage, UnknownException)
525
526 /* Instruction Storage exception. */
527         STD_EXCEPTION(0x400, InstStorage, UnknownException)
528
529 /* External Interrupt exception. */
530         STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
531
532 /* Alignment exception. */
533         . = 0x600
534 Alignment:
535         EXCEPTION_PROLOG(SRR0, SRR1)
536         mfspr   r4,DAR
537         stw     r4,_DAR(r21)
538         mfspr   r5,DSISR
539         stw     r5,_DSISR(r21)
540         addi    r3,r1,STACK_FRAME_OVERHEAD
541         li      r20,MSR_KERNEL
542         rlwimi  r20,r23,0,16,16         /* copy EE bit from saved MSR */
543         lwz     r6,GOT(transfer_to_handler)
544         mtlr    r6
545         blrl
546 .L_Alignment:
547         .long   AlignmentException - _start + _START_OFFSET
548         .long   int_return - _start + _START_OFFSET
549
550 /* Program check exception */
551         . = 0x700
552 ProgramCheck:
553         EXCEPTION_PROLOG(SRR0, SRR1)
554         addi    r3,r1,STACK_FRAME_OVERHEAD
555         li      r20,MSR_KERNEL
556         rlwimi  r20,r23,0,16,16         /* copy EE bit from saved MSR */
557         lwz     r6,GOT(transfer_to_handler)
558         mtlr    r6
559         blrl
560 .L_ProgramCheck:
561         .long   ProgramCheckException - _start + _START_OFFSET
562         .long   int_return - _start + _START_OFFSET
563
564 #ifdef CONFIG_440
565         STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
566         STD_EXCEPTION(0x900, Decrementer, DecrementerPITException)
567         STD_EXCEPTION(0xa00, APU, UnknownException)
568 #endif
569         STD_EXCEPTION(0xc00, SystemCall, UnknownException)
570
571 #ifdef CONFIG_440
572         STD_EXCEPTION(0x1300, DataTLBError, UnknownException)
573         STD_EXCEPTION(0x1400, InstructionTLBError, UnknownException)
574 #else
575         STD_EXCEPTION(0x1000, PIT, DecrementerPITException)
576         STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException)
577         STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException)
578 #endif
579         CRIT_EXCEPTION(0x2000, DebugBreakpoint, DebugException )
580
581         .globl  _end_of_vectors
582 _end_of_vectors:
583         . = _START_OFFSET
584 #endif
585         .globl  _start
586 _start:
587
588 /*****************************************************************************/
589 #if defined(CONFIG_440)
590
591         /*----------------------------------------------------------------*/
592         /* Clear and set up some registers. */
593         /*----------------------------------------------------------------*/
594         li      r0,0x0000
595         lis     r1,0xffff
596         mtspr   dec,r0                  /* prevent dec exceptions */
597         mtspr   tbl,r0                  /* prevent fit & wdt exceptions */
598         mtspr   tbu,r0
599         mtspr   tsr,r1                  /* clear all timer exception status */
600         mtspr   tcr,r0                  /* disable all */
601         mtspr   esr,r0                  /* clear exception syndrome register */
602         mtxer   r0                      /* clear integer exception register */
603
604         /*----------------------------------------------------------------*/
605         /* Debug setup -- some (not very good) ice's need an event*/
606         /* to establish control :-( Define CFG_INIT_DBCR to the dbsr */
607         /* value you need in this case 0x8cff 0000 should do the trick */
608         /*----------------------------------------------------------------*/
609 #if defined(CFG_INIT_DBCR)
610         lis     r1,0xffff
611         ori     r1,r1,0xffff
612         mtspr   dbsr,r1                 /* Clear all status bits */
613         lis     r0,CFG_INIT_DBCR@h
614         ori     r0,r0,CFG_INIT_DBCR@l
615         mtspr   dbcr0,r0
616         isync
617 #endif
618
619         /*----------------------------------------------------------------*/
620         /* Setup the internal SRAM */
621         /*----------------------------------------------------------------*/
622         li      r0,0
623
624 #ifdef CFG_INIT_RAM_DCACHE
625         /* Clear Dcache to use as RAM */
626         addis   r3,r0,CFG_INIT_RAM_ADDR@h
627         ori     r3,r3,CFG_INIT_RAM_ADDR@l
628         addis   r4,r0,CFG_INIT_RAM_END@h
629         ori     r4,r4,CFG_INIT_RAM_END@l
630         rlwinm. r5,r4,0,27,31
631         rlwinm  r5,r4,27,5,31
632         beq     ..d_ran
633         addi    r5,r5,0x0001
634 ..d_ran:
635         mtctr   r5
636 ..d_ag:
637         dcbz    r0,r3
638         addi    r3,r3,32
639         bdnz    ..d_ag
640 #endif /* CFG_INIT_RAM_DCACHE */
641
642         /* 440EP & 440GR are only 440er PPC's without internal SRAM */
643 #if !defined(CONFIG_440EP) && !defined(CONFIG_440GR)
644         /* not all PPC's have internal SRAM usable as L2-cache */
645 #if defined(CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE)
646         mtdcr   l2_cache_cfg,r0         /* Ensure L2 Cache is off */
647 #endif
648
649         lis     r2,0x7fff
650         ori     r2,r2,0xffff
651         mfdcr   r1,isram0_dpc
652         and     r1,r1,r2                /* Disable parity check */
653         mtdcr   isram0_dpc,r1
654         mfdcr   r1,isram0_pmeg
655         and     r1,r1,r2                /* Disable pwr mgmt */
656         mtdcr   isram0_pmeg,r1
657
658         lis     r1,0x8000               /* BAS = 8000_0000 */
659 #if defined(CONFIG_440GX) || defined(CONFIG_440SP)
660         ori     r1,r1,0x0980            /* first 64k */
661         mtdcr   isram0_sb0cr,r1
662         lis     r1,0x8001
663         ori     r1,r1,0x0980            /* second 64k */
664         mtdcr   isram0_sb1cr,r1
665         lis     r1, 0x8002
666         ori     r1,r1, 0x0980           /* third 64k */
667         mtdcr   isram0_sb2cr,r1
668         lis     r1, 0x8003
669         ori     r1,r1, 0x0980           /* fourth 64k */
670         mtdcr   isram0_sb3cr,r1
671 #elif defined(CONFIG_440SPE)
672         lis     r1,0x0000               /* BAS = 0000_0000 */
673         ori     r1,r1,0x0984            /* first 64k */
674         mtdcr   isram0_sb0cr,r1
675         lis     r1,0x0001
676         ori     r1,r1,0x0984            /* second 64k */
677         mtdcr   isram0_sb1cr,r1
678         lis     r1, 0x0002
679         ori     r1,r1, 0x0984           /* third 64k */
680         mtdcr   isram0_sb2cr,r1
681         lis     r1, 0x0003
682         ori     r1,r1, 0x0984           /* fourth 64k */
683         mtdcr   isram0_sb3cr,r1
684 #elif defined(CONFIG_440GP)
685         ori     r1,r1,0x0380            /* 8k rw */
686         mtdcr   isram0_sb0cr,r1
687         mtdcr   isram0_sb1cr,r0         /* Disable bank 1 */
688 #endif
689 #endif /* #if !defined(CONFIG_440EP) && !defined(CONFIG_440GR) */
690
691         /*----------------------------------------------------------------*/
692         /* Setup the stack in internal SRAM */
693         /*----------------------------------------------------------------*/
694         lis     r1,CFG_INIT_RAM_ADDR@h
695         ori     r1,r1,CFG_INIT_SP_OFFSET@l
696         li      r0,0
697         stwu    r0,-4(r1)
698         stwu    r0,-4(r1)               /* Terminate call chain */
699
700         stwu    r1,-8(r1)               /* Save back chain and move SP */
701         lis     r0,RESET_VECTOR@h       /* Address of reset vector */
702         ori     r0,r0, RESET_VECTOR@l
703         stwu    r1,-8(r1)               /* Save back chain and move SP */
704         stw     r0,+12(r1)              /* Save return addr (underflow vect) */
705
706 #ifdef CONFIG_NAND_SPL
707         bl      nand_boot               /* will not return */
708 #else
709         GET_GOT
710
711         bl      cpu_init_f      /* run low-level CPU init code     (from Flash) */
712         bl      board_init_f
713 #endif
714
715 #endif /* CONFIG_440 */
716
717 /*****************************************************************************/
718 #ifdef CONFIG_IOP480
719         /*----------------------------------------------------------------------- */
720         /* Set up some machine state registers. */
721         /*----------------------------------------------------------------------- */
722         addi    r0,r0,0x0000            /* initialize r0 to zero */
723         mtspr   esr,r0                  /* clear Exception Syndrome Reg */
724         mttcr   r0                      /* timer control register */
725         mtexier r0                      /* disable all interrupts */
726         addis   r4,r0,0xFFFF            /* set r4 to 0xFFFFFFFF (status in the */
727         ori     r4,r4,0xFFFF            /* dbsr is cleared by setting bits to 1) */
728         mtdbsr  r4                      /* clear/reset the dbsr */
729         mtexisr r4                      /* clear all pending interrupts */
730         addis   r4,r0,0x8000
731         mtexier r4                      /* enable critical exceptions */
732         addis   r4,r0,0x0000            /* assume 403GCX - enable core clk */
733         ori     r4,r4,0x4020            /* dbling (no harm done on GA and GC */
734         mtiocr  r4                      /* since bit not used) & DRC to latch */
735                                         /* data bus on rising edge of CAS */
736         /*----------------------------------------------------------------------- */
737         /* Clear XER. */
738         /*----------------------------------------------------------------------- */
739         mtxer   r0
740         /*----------------------------------------------------------------------- */
741         /* Invalidate i-cache and d-cache TAG arrays. */
742         /*----------------------------------------------------------------------- */
743         addi    r3,0,1024               /* 1/4 of I-cache size, half of D-cache */
744         addi    r4,0,1024               /* 1/4 of I-cache */
745 ..cloop:
746         iccci   0,r3
747         iccci   r4,r3
748         dccci   0,r3
749         addic.  r3,r3,-16               /* move back one cache line */
750         bne     ..cloop                 /* loop back to do rest until r3 = 0 */
751
752         /* */
753         /* initialize IOP480 so it can read 1 MB code area for SRAM spaces */
754         /* this requires enabling MA[17..0], by default only MA[12..0] are enabled. */
755         /* */
756
757         /* first copy IOP480 register base address into r3 */
758         addis   r3,0,0x5000             /* IOP480 register base address hi */
759 /*      ori     r3,r3,0x0000            /  IOP480 register base address lo */
760
761 #ifdef CONFIG_ADCIOP
762         /* use r4 as the working variable */
763         /* turn on CS3 (LOCCTL.7) */
764         lwz     r4,0x84(r3)             /* LOCTL is at offset 0x84 */
765         andi.   r4,r4,0xff7f            /* make bit 7 = 0 -- CS3 mode */
766         stw     r4,0x84(r3)             /* LOCTL is at offset 0x84 */
767 #endif
768
769 #ifdef CONFIG_DASA_SIM
770         /* use r4 as the working variable */
771         /* turn on MA17 (LOCCTL.7) */
772         lwz     r4,0x84(r3)             /* LOCTL is at offset 0x84 */
773         ori     r4,r4,0x80              /* make bit 7 = 1 -- MA17 mode */
774         stw     r4,0x84(r3)             /* LOCTL is at offset 0x84 */
775 #endif
776
777         /* turn on MA16..13 (LCS0BRD.12 = 0) */
778         lwz     r4,0x100(r3)            /* LCS0BRD is at offset 0x100 */
779         andi.   r4,r4,0xefff            /* make bit 12 = 0 */
780         stw     r4,0x100(r3)            /* LCS0BRD is at offset 0x100 */
781
782         /* make sure above stores all comlete before going on */
783         sync
784
785         /* last thing, set local init status done bit (DEVINIT.31) */
786         lwz     r4,0x80(r3)             /* DEVINIT is at offset 0x80 */
787         oris    r4,r4,0x8000            /* make bit 31 = 1 */
788         stw     r4,0x80(r3)             /* DEVINIT is at offset 0x80 */
789
790         /* clear all pending interrupts and disable all interrupts */
791         li      r4,-1                   /* set p1 to 0xffffffff */
792         stw     r4,0x1b0(r3)            /* clear all pending interrupts */
793         stw     r4,0x1b8(r3)            /* clear all pending interrupts */
794         li      r4,0                    /* set r4 to 0 */
795         stw     r4,0x1b4(r3)            /* disable all interrupts */
796         stw     r4,0x1bc(r3)            /* disable all interrupts */
797
798         /* make sure above stores all comlete before going on */
799         sync
800
801         /*----------------------------------------------------------------------- */
802         /* Enable two 128MB cachable regions. */
803         /*----------------------------------------------------------------------- */
804         addis   r1,r0,0x8000
805         addi    r1,r1,0x0001
806         mticcr  r1                      /* instruction cache */
807
808         addis   r1,r0,0x0000
809         addi    r1,r1,0x0000
810         mtdccr  r1                      /* data cache */
811
812         addis   r1,r0,CFG_INIT_RAM_ADDR@h
813         ori     r1,r1,CFG_INIT_SP_OFFSET          /* set up the stack to SDRAM */
814         li      r0, 0                   /* Make room for stack frame header and */
815         stwu    r0, -4(r1)              /* clear final stack frame so that      */
816         stwu    r0, -4(r1)              /* stack backtraces terminate cleanly   */
817
818         GET_GOT                 /* initialize GOT access                        */
819
820         bl      board_init_f    /* run first part of init code (from Flash)     */
821
822 #endif  /* CONFIG_IOP480 */
823
824 /*****************************************************************************/
825 #if defined(CONFIG_405GP) || defined(CONFIG_405CR) || \
826     defined(CONFIG_405EP) || defined(CONFIG_405EZ) || \
827     defined(CONFIG_405)
828         /*----------------------------------------------------------------------- */
829         /* Clear and set up some registers. */
830         /*----------------------------------------------------------------------- */
831         addi    r4,r0,0x0000
832         mtspr   sgr,r4
833         mtspr   dcwr,r4
834         mtesr   r4                      /* clear Exception Syndrome Reg */
835         mttcr   r4                      /* clear Timer Control Reg */
836         mtxer   r4                      /* clear Fixed-Point Exception Reg */
837         mtevpr  r4                      /* clear Exception Vector Prefix Reg */
838         addi    r4,r0,(0xFFFF-0x10000)          /* set r4 to 0xFFFFFFFF (status in the */
839                                         /* dbsr is cleared by setting bits to 1) */
840         mtdbsr  r4                      /* clear/reset the dbsr */
841
842         /*----------------------------------------------------------------------- */
843         /* Invalidate I and D caches. Enable I cache for defined memory regions */
844         /* to speed things up. Leave the D cache disabled for now. It will be */
845         /* enabled/left disabled later based on user selected menu options. */
846         /* Be aware that the I cache may be disabled later based on the menu */
847         /* options as well. See miscLib/main.c. */
848         /*----------------------------------------------------------------------- */
849         bl      invalidate_icache
850         bl      invalidate_dcache
851
852         /*----------------------------------------------------------------------- */
853         /* Enable two 128MB cachable regions. */
854         /*----------------------------------------------------------------------- */
855         lis     r4,0x8000
856         ori     r4,r4,0x0001
857         mticcr  r4                      /* instruction cache */
858         isync
859
860         lis     r4,0x0000
861         ori     r4,r4,0x0000
862         mtdccr  r4                      /* data cache */
863
864 #if !(defined(CFG_EBC_PB0AP) && defined(CFG_EBC_PB0CR))
865         /*----------------------------------------------------------------------- */
866         /* Tune the speed and size for flash CS0  */
867         /*----------------------------------------------------------------------- */
868         bl      ext_bus_cntlr_init
869 #endif
870
871 #if defined(CONFIG_405EP)
872         /*----------------------------------------------------------------------- */
873         /* DMA Status, clear to come up clean */
874         /*----------------------------------------------------------------------- */
875         addis   r3,r0, 0xFFFF         /* Clear all existing DMA status */
876         ori     r3,r3, 0xFFFF
877         mtdcr   dmasr, r3
878
879         bl      ppc405ep_init         /* do ppc405ep specific init */
880 #endif /* CONFIG_405EP */
881
882 #if defined(CFG_OCM_DATA_ADDR) && defined(CFG_OCM_DATA_SIZE)
883 #if defined(CONFIG_405EZ)
884         /********************************************************************
885          * Setup OCM - On Chip Memory - PPC405EZ uses OCM Controller V2
886          *******************************************************************/
887         /*
888          * We can map the OCM on the PLB3, so map it at
889          * CFG_OCM_DATA_ADDR + 0x8000
890          */
891         lis     r3,CFG_OCM_DATA_ADDR@h  /* OCM location */
892         ori     r3,r3,CFG_OCM_DATA_ADDR@l
893         ori     r3,r3,0x0270            /* 16K for Bank 1, R/W/Enable */
894         mtdcr   ocmplb3cr1,r3           /* Set PLB Access */
895         ori     r3,r3,0x4000            /* Add 0x4000 for bank 2 */
896         mtdcr   ocmplb3cr2,r3           /* Set PLB Access */
897         isync
898
899         lis     r3,CFG_OCM_DATA_ADDR@h  /* OCM location */
900         ori     r3,r3,CFG_OCM_DATA_ADDR@l
901         ori     r3,r3,0x0270            /* 16K for Bank 1, R/W/Enable */
902         mtdcr   ocmdscr1, r3            /* Set Data Side */
903         mtdcr   ocmiscr1, r3            /* Set Instruction Side */
904         ori     r3,r3,0x4000            /* Add 0x4000 for bank 2 */
905         mtdcr   ocmdscr2, r3            /* Set Data Side */
906         mtdcr   ocmiscr2, r3            /* Set Instruction Side */
907         addis   r3,0,0x0800             /* OCM Data Parity Disable - 1 Wait State */
908         mtdcr   ocmdsisdpc,r3
909
910         isync
911 #else /* CONFIG_405EZ */
912         /********************************************************************
913          * Setup OCM - On Chip Memory
914          *******************************************************************/
915         /* Setup OCM */
916         lis     r0, 0x7FFF
917         ori     r0, r0, 0xFFFF
918         mfdcr   r3, ocmiscntl           /* get instr-side IRAM config */
919         mfdcr   r4, ocmdscntl           /* get data-side IRAM config */
920         and     r3, r3, r0              /* disable data-side IRAM */
921         and     r4, r4, r0              /* disable data-side IRAM */
922         mtdcr   ocmiscntl, r3           /* set instr-side IRAM config */
923         mtdcr   ocmdscntl, r4           /* set data-side IRAM config */
924         isync
925
926         lis     r3,CFG_OCM_DATA_ADDR@h  /* OCM location */
927         ori     r3,r3,CFG_OCM_DATA_ADDR@l
928         mtdcr   ocmdsarc, r3
929         addis   r4, 0, 0xC000           /* OCM data area enabled */
930         mtdcr   ocmdscntl, r4
931         isync
932 #endif /* CONFIG_405EZ */
933 #endif
934
935 #ifdef CONFIG_NAND_SPL
936         /*
937          * Copy SPL from cache into internal SRAM
938          */
939         li      r4,(CFG_NAND_BOOT_SPL_SIZE >> 2) - 1
940         mtctr   r4
941         lis     r2,CFG_NAND_BOOT_SPL_SRC@h
942         ori     r2,r2,CFG_NAND_BOOT_SPL_SRC@l
943         lis     r3,CFG_NAND_BOOT_SPL_DST@h
944         ori     r3,r3,CFG_NAND_BOOT_SPL_DST@l
945 spl_loop:
946         lwzu    r4,4(r2)
947         stwu    r4,4(r3)
948         bdnz    spl_loop
949
950         /*
951          * Jump to code in RAM
952          */
953         bl      00f
954 00:     mflr    r10
955         lis     r3,(CFG_NAND_BOOT_SPL_SRC - CFG_NAND_BOOT_SPL_DST)@h
956         ori     r3,r3,(CFG_NAND_BOOT_SPL_SRC - CFG_NAND_BOOT_SPL_DST)@l
957         sub     r10,r10,r3
958         addi    r10,r10,28
959         mtlr    r10
960         blr
961
962 start_ram:
963         sync
964         isync
965 #endif /* CONFIG_NAND_SPL */
966
967         /*----------------------------------------------------------------------- */
968         /* Setup temporary stack in DCACHE or OCM if needed for SDRAM SPD. */
969         /*----------------------------------------------------------------------- */
970 #ifdef CFG_INIT_DCACHE_CS
971         /*----------------------------------------------------------------------- */
972         /* Memory Bank x (nothingness) initialization 1GB+64MEG */
973         /* used as temporary stack pointer for stage0  */
974         /*----------------------------------------------------------------------- */
975         li      r4,PBxAP
976         mtdcr   ebccfga,r4
977         lis     r4,0x0380
978         ori     r4,r4,0x0480
979         mtdcr   ebccfgd,r4
980
981         addi    r4,0,PBxCR
982         mtdcr   ebccfga,r4
983         lis     r4,0x400D
984         ori     r4,r4,0xa000
985         mtdcr   ebccfgd,r4
986
987         /* turn on data chache for this region */
988         lis     r4,0x0080
989         mtdccr  r4
990
991         /* set stack pointer and clear stack to known value */
992
993         lis     r1,CFG_INIT_RAM_ADDR@h
994         ori     r1,r1,CFG_INIT_SP_OFFSET@l
995
996         li      r4,2048                 /* we store 2048 words to stack */
997         mtctr   r4
998
999         lis     r2,CFG_INIT_RAM_ADDR@h          /* we also clear data area */
1000         ori     r2,r2,CFG_INIT_RAM_END@l        /* so cant copy value from r1 */
1001
1002         lis     r4,0xdead               /* we store 0xdeaddead in the stack */
1003         ori     r4,r4,0xdead
1004
1005 ..stackloop:
1006         stwu    r4,-4(r2)
1007         bdnz    ..stackloop
1008
1009         li      r0, 0                   /* Make room for stack frame header and */
1010         stwu    r0, -4(r1)              /* clear final stack frame so that      */
1011         stwu    r0, -4(r1)              /* stack backtraces terminate cleanly   */
1012         /*
1013          * Set up a dummy frame to store reset vector as return address.
1014          * this causes stack underflow to reset board.
1015          */
1016         stwu    r1, -8(r1)              /* Save back chain and move SP */
1017         addis   r0, 0, RESET_VECTOR@h   /* Address of reset vector */
1018         ori     r0, r0, RESET_VECTOR@l
1019         stwu    r1, -8(r1)              /* Save back chain and move SP */
1020         stw     r0, +12(r1)             /* Save return addr (underflow vect) */
1021
1022 #elif defined(CFG_TEMP_STACK_OCM) && \
1023         (defined(CFG_OCM_DATA_ADDR) && defined(CFG_OCM_DATA_SIZE))
1024         /*
1025          * Stack in OCM.
1026          */
1027
1028         /* Set up Stack at top of OCM */
1029         lis     r1, (CFG_INIT_RAM_ADDR + CFG_INIT_SP_OFFSET)@h
1030         ori     r1, r1, (CFG_INIT_RAM_ADDR + CFG_INIT_SP_OFFSET)@l
1031
1032         /* Set up a zeroized stack frame so that backtrace works right */
1033         li      r0, 0
1034         stwu    r0, -4(r1)
1035         stwu    r0, -4(r1)
1036
1037         /*
1038          * Set up a dummy frame to store reset vector as return address.
1039          * this causes stack underflow to reset board.
1040          */
1041         stwu    r1, -8(r1)              /* Save back chain and move SP */
1042         lis     r0, RESET_VECTOR@h      /* Address of reset vector */
1043         ori     r0, r0, RESET_VECTOR@l
1044         stwu    r1, -8(r1)              /* Save back chain and move SP */
1045         stw     r0, +12(r1)             /* Save return addr (underflow vect) */
1046 #endif /* CFG_INIT_DCACHE_CS */
1047
1048         /*----------------------------------------------------------------------- */
1049         /* Initialize SDRAM Controller  */
1050         /*----------------------------------------------------------------------- */
1051         bl      sdram_init
1052
1053         /*
1054          * Setup temporary stack pointer only for boards
1055          * that do not use SDRAM SPD I2C stuff since it
1056          * is already initialized to use DCACHE or OCM
1057          * stacks.
1058          */
1059 #if !(defined(CFG_INIT_DCACHE_CS) || defined(CFG_TEMP_STACK_OCM))
1060         lis     r1, CFG_INIT_RAM_ADDR@h
1061         ori     r1,r1,CFG_INIT_SP_OFFSET /* set up the stack in SDRAM */
1062
1063         li      r0, 0                   /* Make room for stack frame header and */
1064         stwu    r0, -4(r1)              /* clear final stack frame so that      */
1065         stwu    r0, -4(r1)              /* stack backtraces terminate cleanly   */
1066         /*
1067          * Set up a dummy frame to store reset vector as return address.
1068          * this causes stack underflow to reset board.
1069          */
1070         stwu    r1, -8(r1)              /* Save back chain and move SP */
1071         lis     r0, RESET_VECTOR@h      /* Address of reset vector */
1072         ori     r0, r0, RESET_VECTOR@l
1073         stwu    r1, -8(r1)              /* Save back chain and move SP */
1074         stw     r0, +12(r1)             /* Save return addr (underflow vect) */
1075 #endif /* !(CFG_INIT_DCACHE_CS  || !CFG_TEM_STACK_OCM) */
1076
1077 #ifdef CONFIG_NAND_SPL
1078         bl      nand_boot               /* will not return */
1079 #else
1080         GET_GOT                 /* initialize GOT access                        */
1081
1082         bl      cpu_init_f      /* run low-level CPU init code     (from Flash) */
1083
1084         /* NEVER RETURNS! */
1085         bl      board_init_f    /* run first part of init code (from Flash)     */
1086 #endif /* CONFIG_NAND_SPL */
1087
1088 #endif  /* CONFIG_405GP || CONFIG_405CR || CONFIG_405 || CONFIG_405EP */
1089         /*----------------------------------------------------------------------- */
1090
1091
1092 #ifndef CONFIG_NAND_SPL
1093 /*
1094  * This code finishes saving the registers to the exception frame
1095  * and jumps to the appropriate handler for the exception.
1096  * Register r21 is pointer into trap frame, r1 has new stack pointer.
1097  */
1098         .globl  transfer_to_handler
1099 transfer_to_handler:
1100         stw     r22,_NIP(r21)
1101         lis     r22,MSR_POW@h
1102         andc    r23,r23,r22
1103         stw     r23,_MSR(r21)
1104         SAVE_GPR(7, r21)
1105         SAVE_4GPRS(8, r21)
1106         SAVE_8GPRS(12, r21)
1107         SAVE_8GPRS(24, r21)
1108         mflr    r23
1109         andi.   r24,r23,0x3f00          /* get vector offset */
1110         stw     r24,TRAP(r21)
1111         li      r22,0
1112         stw     r22,RESULT(r21)
1113         mtspr   SPRG2,r22               /* r1 is now kernel sp */
1114         lwz     r24,0(r23)              /* virtual address of handler */
1115         lwz     r23,4(r23)              /* where to go when done */
1116         mtspr   SRR0,r24
1117         mtspr   SRR1,r20
1118         mtlr    r23
1119         SYNC
1120         rfi                             /* jump to handler, enable MMU */
1121
1122 int_return:
1123         mfmsr   r28             /* Disable interrupts */
1124         li      r4,0
1125         ori     r4,r4,MSR_EE
1126         andc    r28,r28,r4
1127         SYNC                    /* Some chip revs need this... */
1128         mtmsr   r28
1129         SYNC
1130         lwz     r2,_CTR(r1)
1131         lwz     r0,_LINK(r1)
1132         mtctr   r2
1133         mtlr    r0
1134         lwz     r2,_XER(r1)
1135         lwz     r0,_CCR(r1)
1136         mtspr   XER,r2
1137         mtcrf   0xFF,r0
1138         REST_10GPRS(3, r1)
1139         REST_10GPRS(13, r1)
1140         REST_8GPRS(23, r1)
1141         REST_GPR(31, r1)
1142         lwz     r2,_NIP(r1)     /* Restore environment */
1143         lwz     r0,_MSR(r1)
1144         mtspr   SRR0,r2
1145         mtspr   SRR1,r0
1146         lwz     r0,GPR0(r1)
1147         lwz     r2,GPR2(r1)
1148         lwz     r1,GPR1(r1)
1149         SYNC
1150         rfi
1151
1152 crit_return:
1153         mfmsr   r28             /* Disable interrupts */
1154         li      r4,0
1155         ori     r4,r4,MSR_EE
1156         andc    r28,r28,r4
1157         SYNC                    /* Some chip revs need this... */
1158         mtmsr   r28
1159         SYNC
1160         lwz     r2,_CTR(r1)
1161         lwz     r0,_LINK(r1)
1162         mtctr   r2
1163         mtlr    r0
1164         lwz     r2,_XER(r1)
1165         lwz     r0,_CCR(r1)
1166         mtspr   XER,r2
1167         mtcrf   0xFF,r0
1168         REST_10GPRS(3, r1)
1169         REST_10GPRS(13, r1)
1170         REST_8GPRS(23, r1)
1171         REST_GPR(31, r1)
1172         lwz     r2,_NIP(r1)     /* Restore environment */
1173         lwz     r0,_MSR(r1)
1174         mtspr   csrr0,r2
1175         mtspr   csrr1,r0
1176         lwz     r0,GPR0(r1)
1177         lwz     r2,GPR2(r1)
1178         lwz     r1,GPR1(r1)
1179         SYNC
1180         rfci
1181
1182 #ifdef CONFIG_440
1183 mck_return:
1184         mfmsr   r28             /* Disable interrupts */
1185         li      r4,0
1186         ori     r4,r4,MSR_EE
1187         andc    r28,r28,r4
1188         SYNC                    /* Some chip revs need this... */
1189         mtmsr   r28
1190         SYNC
1191         lwz     r2,_CTR(r1)
1192         lwz     r0,_LINK(r1)
1193         mtctr   r2
1194         mtlr    r0
1195         lwz     r2,_XER(r1)
1196         lwz     r0,_CCR(r1)
1197         mtspr   XER,r2
1198         mtcrf   0xFF,r0
1199         REST_10GPRS(3, r1)
1200         REST_10GPRS(13, r1)
1201         REST_8GPRS(23, r1)
1202         REST_GPR(31, r1)
1203         lwz     r2,_NIP(r1)     /* Restore environment */
1204         lwz     r0,_MSR(r1)
1205         mtspr   mcsrr0,r2
1206         mtspr   mcsrr1,r0
1207         lwz     r0,GPR0(r1)
1208         lwz     r2,GPR2(r1)
1209         lwz     r1,GPR1(r1)
1210         SYNC
1211         rfmci
1212 #endif /* CONFIG_440 */
1213
1214
1215 /*
1216  * Cache functions.
1217  *
1218  * NOTE: currently the 440s run with dcache _disabled_ once relocated to DRAM,
1219  * although for some cache-ralated calls stubs have to be provided to satisfy
1220  * symbols resolution.
1221  *
1222  */
1223 #ifdef CONFIG_440
1224        .globl  dcache_disable
1225 dcache_disable:
1226         blr
1227
1228         .globl  dcache_status
1229 dcache_status:
1230         blr
1231 #else
1232 flush_dcache:
1233         addis   r9,r0,0x0002            /* set mask for EE and CE msr bits */
1234         ori     r9,r9,0x8000
1235         mfmsr   r12                     /* save msr */
1236         andc    r9,r12,r9
1237         mtmsr   r9                      /* disable EE and CE */
1238         addi    r10,r0,0x0001           /* enable data cache for unused memory */
1239         mfdccr  r9                      /* region 0xF8000000-0xFFFFFFFF via */
1240         or      r10,r10,r9              /* bit 31 in dccr */
1241         mtdccr  r10
1242
1243         /* do loop for # of congruence classes. */
1244         lis     r10,(CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@ha       /* TBS: for large cache sizes */
1245         ori     r10,r10,(CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@l
1246         lis     r11,(CFG_DCACHE_SIZE / 2)@ha /* D cache set size - 2 way sets */
1247         ori     r11,r11,(CFG_DCACHE_SIZE / 2)@l /* D cache set size - 2 way sets */
1248         mtctr   r10
1249         addi    r10,r0,(0xE000-0x10000) /* start at 0xFFFFE000 */
1250         add     r11,r10,r11             /* add to get to other side of cache line */
1251 ..flush_dcache_loop:
1252         lwz     r3,0(r10)               /* least recently used side */
1253         lwz     r3,0(r11)               /* the other side */
1254         dccci   r0,r11                  /* invalidate both sides */
1255         addi    r10,r10,CFG_CACHELINE_SIZE /* bump to next line */
1256         addi    r11,r11,CFG_CACHELINE_SIZE /* bump to next line */
1257         bdnz    ..flush_dcache_loop
1258         sync                            /* allow memory access to complete */
1259         mtdccr  r9                      /* restore dccr */
1260         mtmsr   r12                     /* restore msr */
1261         blr
1262
1263         .globl  icache_enable
1264 icache_enable:
1265         mflr    r8
1266         bl      invalidate_icache
1267         mtlr    r8
1268         isync
1269         addis   r3,r0, 0x8000         /* set bit 0 */
1270         mticcr  r3
1271         blr
1272
1273         .globl  icache_disable
1274 icache_disable:
1275         addis   r3,r0, 0x0000         /* clear bit 0 */
1276         mticcr  r3
1277         isync
1278         blr
1279
1280         .globl  icache_status
1281 icache_status:
1282         mficcr  r3
1283         srwi    r3, r3, 31      /* >>31 => select bit 0 */
1284         blr
1285
1286         .globl  dcache_enable
1287 dcache_enable:
1288         mflr    r8
1289         bl      invalidate_dcache
1290         mtlr    r8
1291         isync
1292         addis   r3,r0, 0x8000         /* set bit 0 */
1293         mtdccr  r3
1294         blr
1295
1296         .globl  dcache_disable
1297 dcache_disable:
1298         mflr    r8
1299         bl      flush_dcache
1300         mtlr    r8
1301         addis   r3,r0, 0x0000         /* clear bit 0 */
1302         mtdccr  r3
1303         blr
1304
1305         .globl  dcache_status
1306 dcache_status:
1307         mfdccr  r3
1308         srwi    r3, r3, 31      /* >>31 => select bit 0 */
1309         blr
1310 #endif
1311
1312         .globl get_pvr
1313 get_pvr:
1314         mfspr   r3, PVR
1315         blr
1316
1317 /*------------------------------------------------------------------------------- */
1318 /* Function:     out16 */
1319 /* Description:  Output 16 bits */
1320 /*------------------------------------------------------------------------------- */
1321         .globl  out16
1322 out16:
1323         sth     r4,0x0000(r3)
1324         blr
1325
1326 /*------------------------------------------------------------------------------- */
1327 /* Function:     out16r */
1328 /* Description:  Byte reverse and output 16 bits */
1329 /*------------------------------------------------------------------------------- */
1330         .globl  out16r
1331 out16r:
1332         sthbrx  r4,r0,r3
1333         blr
1334
1335 /*------------------------------------------------------------------------------- */
1336 /* Function:     out32r */
1337 /* Description:  Byte reverse and output 32 bits */
1338 /*------------------------------------------------------------------------------- */
1339         .globl  out32r
1340 out32r:
1341         stwbrx  r4,r0,r3
1342         blr
1343
1344 /*------------------------------------------------------------------------------- */
1345 /* Function:     in16 */
1346 /* Description:  Input 16 bits */
1347 /*------------------------------------------------------------------------------- */
1348         .globl  in16
1349 in16:
1350         lhz     r3,0x0000(r3)
1351         blr
1352
1353 /*------------------------------------------------------------------------------- */
1354 /* Function:     in16r */
1355 /* Description:  Input 16 bits and byte reverse */
1356 /*------------------------------------------------------------------------------- */
1357         .globl  in16r
1358 in16r:
1359         lhbrx   r3,r0,r3
1360         blr
1361
1362 /*------------------------------------------------------------------------------- */
1363 /* Function:     in32r */
1364 /* Description:  Input 32 bits and byte reverse */
1365 /*------------------------------------------------------------------------------- */
1366         .globl  in32r
1367 in32r:
1368         lwbrx   r3,r0,r3
1369         blr
1370
1371 /*------------------------------------------------------------------------------- */
1372 /* Function:     ppcDcbf */
1373 /* Description:  Data Cache block flush */
1374 /* Input:        r3 = effective address */
1375 /* Output:       none. */
1376 /*------------------------------------------------------------------------------- */
1377         .globl  ppcDcbf
1378 ppcDcbf:
1379         dcbf    r0,r3
1380         blr
1381
1382 /*------------------------------------------------------------------------------- */
1383 /* Function:     ppcDcbi */
1384 /* Description:  Data Cache block Invalidate */
1385 /* Input:        r3 = effective address */
1386 /* Output:       none. */
1387 /*------------------------------------------------------------------------------- */
1388         .globl  ppcDcbi
1389 ppcDcbi:
1390         dcbi    r0,r3
1391         blr
1392
1393 /*------------------------------------------------------------------------------- */
1394 /* Function:     ppcSync */
1395 /* Description:  Processor Synchronize */
1396 /* Input:        none. */
1397 /* Output:       none. */
1398 /*------------------------------------------------------------------------------- */
1399         .globl  ppcSync
1400 ppcSync:
1401         sync
1402         blr
1403
1404 /*
1405  * void relocate_code (addr_sp, gd, addr_moni)
1406  *
1407  * This "function" does not return, instead it continues in RAM
1408  * after relocating the monitor code.
1409  *
1410  * r3 = dest
1411  * r4 = src
1412  * r5 = length in bytes
1413  * r6 = cachelinesize
1414  */
1415         .globl  relocate_code
1416 relocate_code:
1417 #if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
1418     defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
1419     defined(CONFIG_440SP) || defined(CONFIG_440SPE)
1420         /*
1421          * On some 440er platforms the cache is enabled in the first TLB (Boot-CS)
1422          * to speed up the boot process. Now this cache needs to be disabled.
1423          */
1424         iccci   0,0                     /* Invalidate inst cache */
1425         dccci   0,0                     /* Invalidate data cache, now no longer our stack */
1426         sync
1427         isync
1428         addi    r1,r0,0x0000            /* TLB entry #0 */
1429         tlbre   r0,r1,0x0002            /* Read contents */
1430         ori     r0,r0,0x0c00            /* Or in the inhibit, write through bit */
1431         tlbwe   r0,r1,0x0002            /* Save it out */
1432         sync
1433         isync
1434 #endif
1435         mr      r1,  r3         /* Set new stack pointer                */
1436         mr      r9,  r4         /* Save copy of Init Data pointer       */
1437         mr      r10, r5         /* Save copy of Destination Address     */
1438
1439         mr      r3,  r5                         /* Destination Address  */
1440         lis     r4, CFG_MONITOR_BASE@h          /* Source      Address  */
1441         ori     r4, r4, CFG_MONITOR_BASE@l
1442         lwz     r5, GOT(__init_end)
1443         sub     r5, r5, r4
1444         li      r6, CFG_CACHELINE_SIZE          /* Cache Line Size      */
1445
1446         /*
1447          * Fix GOT pointer:
1448          *
1449          * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address
1450          *
1451          * Offset:
1452          */
1453         sub     r15, r10, r4
1454
1455         /* First our own GOT */
1456         add     r14, r14, r15
1457         /* the the one used by the C code */
1458         add     r30, r30, r15
1459
1460         /*
1461          * Now relocate code
1462          */
1463
1464         cmplw   cr1,r3,r4
1465         addi    r0,r5,3
1466         srwi.   r0,r0,2
1467         beq     cr1,4f          /* In place copy is not necessary       */
1468         beq     7f              /* Protect against 0 count              */
1469         mtctr   r0
1470         bge     cr1,2f
1471
1472         la      r8,-4(r4)
1473         la      r7,-4(r3)
1474 1:      lwzu    r0,4(r8)
1475         stwu    r0,4(r7)
1476         bdnz    1b
1477         b       4f
1478
1479 2:      slwi    r0,r0,2
1480         add     r8,r4,r0
1481         add     r7,r3,r0
1482 3:      lwzu    r0,-4(r8)
1483         stwu    r0,-4(r7)
1484         bdnz    3b
1485
1486 /*
1487  * Now flush the cache: note that we must start from a cache aligned
1488  * address. Otherwise we might miss one cache line.
1489  */
1490 4:      cmpwi   r6,0
1491         add     r5,r3,r5
1492         beq     7f              /* Always flush prefetch queue in any case */
1493         subi    r0,r6,1
1494         andc    r3,r3,r0
1495         mr      r4,r3
1496 5:      dcbst   0,r4
1497         add     r4,r4,r6
1498         cmplw   r4,r5
1499         blt     5b
1500         sync                    /* Wait for all dcbst to complete on bus */
1501         mr      r4,r3
1502 6:      icbi    0,r4
1503         add     r4,r4,r6
1504         cmplw   r4,r5
1505         blt     6b
1506 7:      sync                    /* Wait for all icbi to complete on bus */
1507         isync
1508
1509 /*
1510  * We are done. Do not return, instead branch to second part of board
1511  * initialization, now running from RAM.
1512  */
1513
1514         addi    r0, r10, in_ram - _start + _START_OFFSET
1515         mtlr    r0
1516         blr                             /* NEVER RETURNS! */
1517
1518 in_ram:
1519
1520         /*
1521          * Relocation Function, r14 point to got2+0x8000
1522          *
1523          * Adjust got2 pointers, no need to check for 0, this code
1524          * already puts a few entries in the table.
1525          */
1526         li      r0,__got2_entries@sectoff@l
1527         la      r3,GOT(_GOT2_TABLE_)
1528         lwz     r11,GOT(_GOT2_TABLE_)
1529         mtctr   r0
1530         sub     r11,r3,r11
1531         addi    r3,r3,-4
1532 1:      lwzu    r0,4(r3)
1533         add     r0,r0,r11
1534         stw     r0,0(r3)
1535         bdnz    1b
1536
1537         /*
1538          * Now adjust the fixups and the pointers to the fixups
1539          * in case we need to move ourselves again.
1540          */
1541 2:      li      r0,__fixup_entries@sectoff@l
1542         lwz     r3,GOT(_FIXUP_TABLE_)
1543         cmpwi   r0,0
1544         mtctr   r0
1545         addi    r3,r3,-4
1546         beq     4f
1547 3:      lwzu    r4,4(r3)
1548         lwzux   r0,r4,r11
1549         add     r0,r0,r11
1550         stw     r10,0(r3)
1551         stw     r0,0(r4)
1552         bdnz    3b
1553 4:
1554 clear_bss:
1555         /*
1556          * Now clear BSS segment
1557          */
1558         lwz     r3,GOT(__bss_start)
1559         lwz     r4,GOT(_end)
1560
1561         cmplw   0, r3, r4
1562         beq     6f
1563
1564         li      r0, 0
1565 5:
1566         stw     r0, 0(r3)
1567         addi    r3, r3, 4
1568         cmplw   0, r3, r4
1569         bne     5b
1570 6:
1571
1572         mr      r3, r9          /* Init Data pointer            */
1573         mr      r4, r10         /* Destination Address          */
1574         bl      board_init_r
1575
1576         /*
1577          * Copy exception vector code to low memory
1578          *
1579          * r3: dest_addr
1580          * r7: source address, r8: end address, r9: target address
1581          */
1582         .globl  trap_init
1583 trap_init:
1584         lwz     r7, GOT(_start_of_vectors)
1585         lwz     r8, GOT(_end_of_vectors)
1586
1587         li      r9, 0x100               /* reset vector always at 0x100 */
1588
1589         cmplw   0, r7, r8
1590         bgelr                           /* return if r7>=r8 - just in case */
1591
1592         mflr    r4                      /* save link register           */
1593 1:
1594         lwz     r0, 0(r7)
1595         stw     r0, 0(r9)
1596         addi    r7, r7, 4
1597         addi    r9, r9, 4
1598         cmplw   0, r7, r8
1599         bne     1b
1600
1601         /*
1602          * relocate `hdlr' and `int_return' entries
1603          */
1604         li      r7, .L_MachineCheck - _start + _START_OFFSET
1605         li      r8, Alignment - _start + _START_OFFSET
1606 2:
1607         bl      trap_reloc
1608         addi    r7, r7, 0x100           /* next exception vector */
1609         cmplw   0, r7, r8
1610         blt     2b
1611
1612         li      r7, .L_Alignment - _start + _START_OFFSET
1613         bl      trap_reloc
1614
1615         li      r7, .L_ProgramCheck - _start + _START_OFFSET
1616         bl      trap_reloc
1617
1618 #ifdef CONFIG_440
1619         li      r7, .L_FPUnavailable - _start + _START_OFFSET
1620         bl      trap_reloc
1621
1622         li      r7, .L_Decrementer - _start + _START_OFFSET
1623         bl      trap_reloc
1624
1625         li      r7, .L_APU - _start + _START_OFFSET
1626         bl      trap_reloc
1627
1628         li      r7, .L_InstructionTLBError - _start + _START_OFFSET
1629         bl      trap_reloc
1630
1631         li      r7, .L_DataTLBError - _start + _START_OFFSET
1632         bl      trap_reloc
1633 #else /* CONFIG_440 */
1634         li      r7, .L_PIT - _start + _START_OFFSET
1635         bl      trap_reloc
1636
1637         li      r7, .L_InstructionTLBMiss - _start + _START_OFFSET
1638         bl      trap_reloc
1639
1640         li      r7, .L_DataTLBMiss - _start + _START_OFFSET
1641         bl      trap_reloc
1642 #endif /* CONFIG_440 */
1643
1644         li      r7, .L_DebugBreakpoint - _start + _START_OFFSET
1645         bl      trap_reloc
1646
1647 #if !defined(CONFIG_440)
1648         addi    r7,r0,0x1000            /* set ME bit (Machine Exceptions) */
1649         oris    r7,r7,0x0002            /* set CE bit (Critical Exceptions) */
1650         mtmsr   r7                      /* change MSR */
1651 #else
1652         bl      __440_msr_set
1653         b       __440_msr_continue
1654
1655 __440_msr_set:
1656         addi    r7,r0,0x1000            /* set ME bit (Machine Exceptions) */
1657         oris    r7,r7,0x0002            /* set CE bit (Critical Exceptions) */
1658         mtspr   srr1,r7
1659         mflr    r7
1660         mtspr   srr0,r7
1661         rfi
1662 __440_msr_continue:
1663 #endif
1664
1665         mtlr    r4                      /* restore link register        */
1666         blr
1667
1668         /*
1669          * Function: relocate entries for one exception vector
1670          */
1671 trap_reloc:
1672         lwz     r0, 0(r7)               /* hdlr ...                     */
1673         add     r0, r0, r3              /*  ... += dest_addr            */
1674         stw     r0, 0(r7)
1675
1676         lwz     r0, 4(r7)               /* int_return ...               */
1677         add     r0, r0, r3              /*  ... += dest_addr            */
1678         stw     r0, 4(r7)
1679
1680         blr
1681
1682 #if defined(CONFIG_440)
1683 /*----------------------------------------------------------------------------+
1684 | dcbz_area.
1685 +----------------------------------------------------------------------------*/
1686         function_prolog(dcbz_area)
1687         rlwinm. r5,r4,0,27,31
1688         rlwinm  r5,r4,27,5,31
1689         beq     ..d_ra2
1690         addi    r5,r5,0x0001
1691 ..d_ra2:mtctr   r5
1692 ..d_ag2:dcbz    r0,r3
1693         addi    r3,r3,32
1694         bdnz    ..d_ag2
1695         sync
1696         blr
1697         function_epilog(dcbz_area)
1698
1699 /*----------------------------------------------------------------------------+
1700 | dflush.  Assume 32K at vector address is cachable.
1701 +----------------------------------------------------------------------------*/
1702         function_prolog(dflush)
1703         mfmsr   r9
1704         rlwinm  r8,r9,0,15,13
1705         rlwinm  r8,r8,0,17,15
1706         mtmsr   r8
1707         addi    r3,r0,0x0000
1708         mtspr   dvlim,r3
1709         mfspr   r3,ivpr
1710         addi    r4,r0,1024
1711         mtctr   r4
1712 ..dflush_loop:
1713         lwz     r6,0x0(r3)
1714         addi    r3,r3,32
1715         bdnz    ..dflush_loop
1716         addi    r3,r3,-32
1717         mtctr   r4
1718 ..ag:   dcbf    r0,r3
1719         addi    r3,r3,-32
1720         bdnz    ..ag
1721         sync
1722         mtmsr   r9
1723         blr
1724         function_epilog(dflush)
1725 #endif /* CONFIG_440 */
1726 #endif /* CONFIG_NAND_SPL */
1727
1728 /*------------------------------------------------------------------------------- */
1729 /* Function:     in8 */
1730 /* Description:  Input 8 bits */
1731 /*------------------------------------------------------------------------------- */
1732         .globl  in8
1733 in8:
1734         lbz     r3,0x0000(r3)
1735         blr
1736
1737 /*------------------------------------------------------------------------------- */
1738 /* Function:     out8 */
1739 /* Description:  Output 8 bits */
1740 /*------------------------------------------------------------------------------- */
1741         .globl  out8
1742 out8:
1743         stb     r4,0x0000(r3)
1744         blr
1745
1746 /*------------------------------------------------------------------------------- */
1747 /* Function:     out32 */
1748 /* Description:  Output 32 bits */
1749 /*------------------------------------------------------------------------------- */
1750         .globl  out32
1751 out32:
1752         stw     r4,0x0000(r3)
1753         blr
1754
1755 /*------------------------------------------------------------------------------- */
1756 /* Function:     in32 */
1757 /* Description:  Input 32 bits */
1758 /*------------------------------------------------------------------------------- */
1759         .globl  in32
1760 in32:
1761         lwz     3,0x0000(3)
1762         blr
1763
1764 invalidate_icache:
1765         iccci   r0,r0                   /* for 405, iccci invalidates the */
1766         blr                             /*   entire I cache */
1767
1768 invalidate_dcache:
1769         addi    r6,0,0x0000             /* clear GPR 6 */
1770         /* Do loop for # of dcache congruence classes. */
1771         lis     r7, (CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@ha       /* TBS for large sized cache */
1772         ori     r7, r7, (CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@l
1773                                         /* NOTE: dccci invalidates both */
1774         mtctr   r7                      /* ways in the D cache */
1775 ..dcloop:
1776         dccci   0,r6                    /* invalidate line */
1777         addi    r6,r6, CFG_CACHELINE_SIZE /* bump to next line */
1778         bdnz    ..dcloop
1779         blr
1780
1781 /**************************************************************************/
1782 /* PPC405EP specific stuff                                                */
1783 /**************************************************************************/
1784 #ifdef CONFIG_405EP
1785 ppc405ep_init:
1786
1787 #ifdef CONFIG_BUBINGA
1788         /*
1789          * Initialize EBC chip selects 1 & 4 and GPIO pins (for alternate
1790          * function) to support FPGA and NVRAM accesses below.
1791          */
1792
1793         lis     r3,GPIO0_OSRH@h         /* config GPIO output select */
1794         ori     r3,r3,GPIO0_OSRH@l
1795         lis     r4,CFG_GPIO0_OSRH@h
1796         ori     r4,r4,CFG_GPIO0_OSRH@l
1797         stw     r4,0(r3)
1798         lis     r3,GPIO0_OSRL@h
1799         ori     r3,r3,GPIO0_OSRL@l
1800         lis     r4,CFG_GPIO0_OSRL@h
1801         ori     r4,r4,CFG_GPIO0_OSRL@l
1802         stw     r4,0(r3)
1803
1804         lis     r3,GPIO0_ISR1H@h        /* config GPIO input select */
1805         ori     r3,r3,GPIO0_ISR1H@l
1806         lis     r4,CFG_GPIO0_ISR1H@h
1807         ori     r4,r4,CFG_GPIO0_ISR1H@l
1808         stw     r4,0(r3)
1809         lis     r3,GPIO0_ISR1L@h
1810         ori     r3,r3,GPIO0_ISR1L@l
1811         lis     r4,CFG_GPIO0_ISR1L@h
1812         ori     r4,r4,CFG_GPIO0_ISR1L@l
1813         stw     r4,0(r3)
1814
1815         lis     r3,GPIO0_TSRH@h         /* config GPIO three-state select */
1816         ori     r3,r3,GPIO0_TSRH@l
1817         lis     r4,CFG_GPIO0_TSRH@h
1818         ori     r4,r4,CFG_GPIO0_TSRH@l
1819         stw     r4,0(r3)
1820         lis     r3,GPIO0_TSRL@h
1821         ori     r3,r3,GPIO0_TSRL@l
1822         lis     r4,CFG_GPIO0_TSRL@h
1823         ori     r4,r4,CFG_GPIO0_TSRL@l
1824         stw     r4,0(r3)
1825
1826         lis     r3,GPIO0_TCR@h          /* config GPIO driver output enables */
1827         ori     r3,r3,GPIO0_TCR@l
1828         lis     r4,CFG_GPIO0_TCR@h
1829         ori     r4,r4,CFG_GPIO0_TCR@l
1830         stw     r4,0(r3)
1831
1832         li      r3,pb1ap                /* program EBC bank 1 for RTC access */
1833         mtdcr   ebccfga,r3
1834         lis     r3,CFG_EBC_PB1AP@h
1835         ori     r3,r3,CFG_EBC_PB1AP@l
1836         mtdcr   ebccfgd,r3
1837         li      r3,pb1cr
1838         mtdcr   ebccfga,r3
1839         lis     r3,CFG_EBC_PB1CR@h
1840         ori     r3,r3,CFG_EBC_PB1CR@l
1841         mtdcr   ebccfgd,r3
1842
1843         li      r3,pb1ap                /* program EBC bank 1 for RTC access */
1844         mtdcr   ebccfga,r3
1845         lis     r3,CFG_EBC_PB1AP@h
1846         ori     r3,r3,CFG_EBC_PB1AP@l
1847         mtdcr   ebccfgd,r3
1848         li      r3,pb1cr
1849         mtdcr   ebccfga,r3
1850         lis     r3,CFG_EBC_PB1CR@h
1851         ori     r3,r3,CFG_EBC_PB1CR@l
1852         mtdcr   ebccfgd,r3
1853
1854         li      r3,pb4ap                /* program EBC bank 4 for FPGA access */
1855         mtdcr   ebccfga,r3
1856         lis     r3,CFG_EBC_PB4AP@h
1857         ori     r3,r3,CFG_EBC_PB4AP@l
1858         mtdcr   ebccfgd,r3
1859         li      r3,pb4cr
1860         mtdcr   ebccfga,r3
1861         lis     r3,CFG_EBC_PB4CR@h
1862         ori     r3,r3,CFG_EBC_PB4CR@l
1863         mtdcr   ebccfgd,r3
1864 #endif
1865
1866 #ifndef CFG_CPC0_PCI
1867         li      r3,CPC0_PCI_HOST_CFG_EN
1868 #ifdef CONFIG_BUBINGA
1869         /*
1870         !-----------------------------------------------------------------------
1871         ! Check FPGA for PCI internal/external arbitration
1872         !   If board is set to internal arbitration, update cpc0_pci
1873         !-----------------------------------------------------------------------
1874         */
1875         addis   r5,r0,FPGA_REG1@h      /* set offset for FPGA_REG1 */
1876         ori     r5,r5,FPGA_REG1@l
1877         lbz     r5,0x0(r5)              /* read to get PCI arb selection */
1878         andi.   r6,r5,FPGA_REG1_PCI_INT_ARB  /* using internal arbiter ?*/
1879         beq     ..pci_cfg_set             /* if not set, then bypass reg write*/
1880 #endif
1881         ori     r3,r3,CPC0_PCI_ARBIT_EN
1882 #else /* CFG_CPC0_PCI */
1883         li      r3,CFG_CPC0_PCI
1884 #endif /* CFG_CPC0_PCI */
1885 ..pci_cfg_set:
1886         mtdcr   CPC0_PCI, r3             /* Enable internal arbiter*/
1887
1888         /*
1889         !-----------------------------------------------------------------------
1890         ! Check to see if chip is in bypass mode.
1891         ! If so, write stored CPC0_PLLMR0 and CPC0_PLLMR1 values and perform a
1892         ! CPU reset   Otherwise, skip this step and keep going.
1893         ! Note:  Running BIOS in bypass mode is not supported since PLB speed
1894         !        will not be fast enough for the SDRAM (min 66MHz)
1895         !-----------------------------------------------------------------------
1896         */
1897         mfdcr   r5, CPC0_PLLMR1
1898         rlwinm  r4,r5,1,0x1            /* get system clock source (SSCS) */
1899         cmpi    cr0,0,r4,0x1
1900
1901         beq    pll_done                   /* if SSCS =b'1' then PLL has */
1902                                           /* already been set */
1903                                           /* and CPU has been reset */
1904                                           /* so skip to next section */
1905
1906 #ifdef CONFIG_BUBINGA
1907         /*
1908         !-----------------------------------------------------------------------
1909         ! Read NVRAM to get value to write in PLLMR.
1910         ! If value has not been correctly saved, write default value
1911         ! Default config values (assuming on-board 33MHz SYS_CLK) are above.
1912         ! See CPU_DEFAULT_200 and CPU_DEFAULT_266 above.
1913         !
1914         ! WARNING:  This code assumes the first three words in the nvram_t
1915         !           structure in openbios.h.  Changing the beginning of
1916         !           the structure will break this code.
1917         !
1918         !-----------------------------------------------------------------------
1919         */
1920         addis   r3,0,NVRAM_BASE@h
1921         addi    r3,r3,NVRAM_BASE@l
1922
1923         lwz     r4, 0(r3)
1924         addis   r5,0,NVRVFY1@h
1925         addi    r5,r5,NVRVFY1@l
1926         cmp     cr0,0,r4,r5            /* Compare 1st NVRAM Magic number*/
1927         bne     ..no_pllset
1928         addi    r3,r3,4
1929         lwz     r4, 0(r3)
1930         addis   r5,0,NVRVFY2@h
1931         addi    r5,r5,NVRVFY2@l
1932         cmp     cr0,0,r4,r5            /* Compare 2 NVRAM Magic number */
1933         bne     ..no_pllset
1934         addi    r3,r3,8                 /* Skip over conf_size */
1935         lwz     r4, 4(r3)               /* Load PLLMR1 value from NVRAM */
1936         lwz     r3, 0(r3)               /* Load PLLMR0 value from NVRAM */
1937         rlwinm  r5,r4,1,0x1             /* get system clock source (SSCS) */
1938         cmpi     cr0,0,r5,1             /* See if PLL is locked */
1939         beq     pll_write
1940 ..no_pllset:
1941 #endif /* CONFIG_BUBINGA */
1942
1943         addis   r3,0,PLLMR0_DEFAULT@h       /* PLLMR0 default value */
1944         ori     r3,r3,PLLMR0_DEFAULT@l     /* */
1945         addis   r4,0,PLLMR1_DEFAULT@h       /* PLLMR1 default value */
1946         ori     r4,r4,PLLMR1_DEFAULT@l     /* */
1947
1948         b       pll_write                 /* Write the CPC0_PLLMR with new value */
1949
1950 pll_done:
1951         /*
1952         !-----------------------------------------------------------------------
1953         ! Clear Soft Reset Register
1954         ! This is needed to enable PCI if not booting from serial EPROM
1955         !-----------------------------------------------------------------------
1956                 */
1957         addi    r3, 0, 0x0
1958         mtdcr   CPC0_SRR, r3
1959
1960         addis    r3,0,0x0010
1961         mtctr   r3
1962 pci_wait:
1963         bdnz    pci_wait
1964
1965         blr                               /* return to main code */
1966
1967 /*
1968 !-----------------------------------------------------------------------------
1969 ! Function:     pll_write
1970 ! Description:  Updates the value of the CPC0_PLLMR according to CMOS27E documentation
1971 !               That is:
1972 !                         1.  Pll is first disabled (de-activated by putting in bypass mode)
1973 !                         2.  PLL is reset
1974 !                         3.  Clock dividers are set while PLL is held in reset and bypassed
1975 !                         4.  PLL Reset is cleared
1976 !                         5.  Wait 100us for PLL to lock
1977 !                         6.  A core reset is performed
1978 ! Input: r3 = Value to write to CPC0_PLLMR0
1979 ! Input: r4 = Value to write to CPC0_PLLMR1
1980 ! Output r3 = none
1981 !-----------------------------------------------------------------------------
1982 */
1983 pll_write:
1984         mfdcr  r5, CPC0_UCR
1985         andis. r5,r5,0xFFFF
1986         ori    r5,r5,0x0101              /* Stop the UART clocks */
1987         mtdcr  CPC0_UCR,r5               /* Before changing PLL */
1988
1989         mfdcr  r5, CPC0_PLLMR1
1990         rlwinm r5,r5,0,0x7FFFFFFF        /* Disable PLL */
1991         mtdcr   CPC0_PLLMR1,r5
1992         oris   r5,r5,0x4000              /* Set PLL Reset */
1993         mtdcr   CPC0_PLLMR1,r5
1994
1995         mtdcr   CPC0_PLLMR0,r3           /* Set clock dividers */
1996         rlwinm r5,r4,0,0x3FFFFFFF        /* Reset & Bypass new PLL dividers */
1997         oris   r5,r5,0x4000              /* Set PLL Reset */
1998         mtdcr   CPC0_PLLMR1,r5           /* Set clock dividers */
1999         rlwinm r5,r5,0,0xBFFFFFFF        /* Clear PLL Reset */
2000         mtdcr   CPC0_PLLMR1,r5
2001
2002                 /*
2003         ! Wait min of 100us for PLL to lock.
2004         ! See CMOS 27E databook for more info.
2005         ! At 200MHz, that means waiting 20,000 instructions
2006                  */
2007         addi    r3,0,20000              /* 2000 = 0x4e20 */
2008         mtctr   r3
2009 pll_wait:
2010         bdnz    pll_wait
2011
2012         oris   r5,r5,0x8000             /* Enable PLL */
2013         mtdcr   CPC0_PLLMR1,r5          /* Engage */
2014
2015         /*
2016          * Reset CPU to guarantee timings are OK
2017          * Not sure if this is needed...
2018          */
2019         addis r3,0,0x1000
2020         mtspr dbcr0,r3               /* This will cause a CPU core reset, and */
2021                                      /* execution will continue from the poweron */
2022                                      /* vector of 0xfffffffc */
2023 #endif /* CONFIG_405EP */
2024
2025 #if defined(CONFIG_440)
2026 /*----------------------------------------------------------------------------+
2027 | mttlb3.
2028 +----------------------------------------------------------------------------*/
2029         function_prolog(mttlb3)
2030         TLBWE(4,3,2)
2031         blr
2032         function_epilog(mttlb3)
2033
2034 /*----------------------------------------------------------------------------+
2035 | mftlb3.
2036 +----------------------------------------------------------------------------*/
2037         function_prolog(mftlb3)
2038         TLBRE(3,3,2)
2039         blr
2040         function_epilog(mftlb3)
2041
2042 /*----------------------------------------------------------------------------+
2043 | mttlb2.
2044 +----------------------------------------------------------------------------*/
2045         function_prolog(mttlb2)
2046         TLBWE(4,3,1)
2047         blr
2048         function_epilog(mttlb2)
2049
2050 /*----------------------------------------------------------------------------+
2051 | mftlb2.
2052 +----------------------------------------------------------------------------*/
2053         function_prolog(mftlb2)
2054         TLBRE(3,3,1)
2055         blr
2056         function_epilog(mftlb2)
2057
2058 /*----------------------------------------------------------------------------+
2059 | mttlb1.
2060 +----------------------------------------------------------------------------*/
2061         function_prolog(mttlb1)
2062         TLBWE(4,3,0)
2063         blr
2064         function_epilog(mttlb1)
2065
2066 /*----------------------------------------------------------------------------+
2067 | mftlb1.
2068 +----------------------------------------------------------------------------*/
2069         function_prolog(mftlb1)
2070         TLBRE(3,3,0)
2071         blr
2072         function_epilog(mftlb1)
2073 #endif /* CONFIG_440 */