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