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