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