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