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