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