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