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