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