Merge branch 'mpc86xx'
[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         li      r0,0
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 CPU clock.
221         +-----------------------------------------------------------------*/
222         li      r0,0
223         mtspr   ccr1, r0
224
225         /*----------------------------------------------------------------+
226         | Reset the timebase.
227         | The previous write to CCR1 sets the timebase source.
228         +-----------------------------------------------------------------*/
229         mtspr   tbl, r0
230         mtspr   tbu, r0
231 #endif
232
233         /*----------------------------------------------------------------*/
234         /* Setup interrupt vectors */
235         /*----------------------------------------------------------------*/
236         mtspr   ivpr,r0         /* Vectors start at 0x0000_0000 */
237         li      r1,0x0100
238         mtspr   ivor0,r1        /* Critical input */
239         li      r1,0x0200
240         mtspr   ivor1,r1        /* Machine check */
241         li      r1,0x0300
242         mtspr   ivor2,r1        /* Data storage */
243         li      r1,0x0400
244         mtspr   ivor3,r1        /* Instruction storage */
245         li      r1,0x0500
246         mtspr   ivor4,r1        /* External interrupt */
247         li      r1,0x0600
248         mtspr   ivor5,r1        /* Alignment */
249         li      r1,0x0700
250         mtspr   ivor6,r1        /* Program check */
251         li      r1,0x0800
252         mtspr   ivor7,r1        /* Floating point unavailable */
253         li      r1,0x0c00
254         mtspr   ivor8,r1        /* System call */
255         li      r1,0x1000
256         mtspr   ivor10,r1       /* Decrementer (PIT for 440) */
257         li      r1,0x1400
258         mtspr   ivor13,r1       /* Data TLB error */
259         li      r1,0x1300
260         mtspr   ivor14,r1       /* Instr TLB error */
261         li      r1,0x2000
262         mtspr   ivor15,r1       /* Debug */
263
264         /*----------------------------------------------------------------*/
265         /* Configure cache regions  */
266         /*----------------------------------------------------------------*/
267         mtspr   inv0,r0
268         mtspr   inv1,r0
269         mtspr   inv2,r0
270         mtspr   inv3,r0
271         mtspr   dnv0,r0
272         mtspr   dnv1,r0
273         mtspr   dnv2,r0
274         mtspr   dnv3,r0
275         mtspr   itv0,r0
276         mtspr   itv1,r0
277         mtspr   itv2,r0
278         mtspr   itv3,r0
279         mtspr   dtv0,r0
280         mtspr   dtv1,r0
281         mtspr   dtv2,r0
282         mtspr   dtv3,r0
283
284         /*----------------------------------------------------------------*/
285         /* Cache victim limits */
286         /*----------------------------------------------------------------*/
287         /* floors 0, ceiling max to use the entire cache -- nothing locked
288         */
289         lis     r1,0x0001
290         ori     r1,r1,0xf800
291         mtspr   ivlim,r1
292         mtspr   dvlim,r1
293
294         /*----------------------------------------------------------------+
295         |Initialize MMUCR[STID] = 0.
296         +-----------------------------------------------------------------*/
297         mfspr   r0,mmucr
298         addis   r1,0,0xFFFF
299         ori     r1,r1,0xFF00
300         and     r0,r0,r1
301         mtspr   mmucr,r0
302
303         /*----------------------------------------------------------------*/
304         /* Clear all TLB entries -- TID = 0, TS = 0 */
305         /*----------------------------------------------------------------*/
306         addis   r0,0,0x0000
307         li      r1,0x003f       /* 64 TLB entries */
308         mtctr   r1
309 rsttlb: tlbwe   r0,r1,0x0000    /* Invalidate all entries (V=0)*/
310         tlbwe   r0,r1,0x0001
311         tlbwe   r0,r1,0x0002
312         subi    r1,r1,0x0001
313         bdnz    rsttlb
314
315         /*----------------------------------------------------------------*/
316         /* TLB entry setup -- step thru tlbtab */
317         /*----------------------------------------------------------------*/
318         bl      tlbtab          /* Get tlbtab pointer */
319         mr      r5,r0
320         li      r1,0x003f       /* 64 TLB entries max */
321         mtctr   r1
322         li      r4,0            /* TLB # */
323
324         addi    r5,r5,-4
325 1:      lwzu    r0,4(r5)
326         cmpwi   r0,0
327         beq     2f              /* 0 marks end */
328         lwzu    r1,4(r5)
329         lwzu    r2,4(r5)
330         tlbwe   r0,r4,0         /* TLB Word 0 */
331         tlbwe   r1,r4,1         /* TLB Word 1 */
332         tlbwe   r2,r4,2         /* TLB Word 2 */
333         addi    r4,r4,1         /* Next TLB */
334         bdnz    1b
335
336         /*----------------------------------------------------------------*/
337         /* Continue from 'normal' start */
338         /*----------------------------------------------------------------*/
339 2:      bl      3f
340         b       _start
341
342 3:      li      r0,0
343         mtspr   srr1,r0         /* Keep things disabled for now */
344         mflr    r1
345         mtspr   srr0,r1
346         rfi
347 #endif /* CONFIG_440 */
348
349 /*
350  * r3 - 1st arg to board_init(): IMMP pointer
351  * r4 - 2nd arg to board_init(): boot flag
352  */
353         .text
354         .long   0x27051956              /* U-Boot Magic Number                  */
355         .globl  version_string
356 version_string:
357         .ascii U_BOOT_VERSION
358         .ascii " (", __DATE__, " - ", __TIME__, ")"
359         .ascii CONFIG_IDENT_STRING, "\0"
360
361 /*
362  * Maybe this should be moved somewhere else because the current
363  * location (0x100) is where the CriticalInput Execption should be.
364  */
365         . = EXC_OFF_SYS_RESET
366         .globl  _start
367 _start:
368
369 /*****************************************************************************/
370 #if defined(CONFIG_440)
371
372         /*----------------------------------------------------------------*/
373         /* Clear and set up some registers. */
374         /*----------------------------------------------------------------*/
375         li      r0,0x0000
376         lis     r1,0xffff
377         mtspr   dec,r0                  /* prevent dec exceptions */
378         mtspr   tbl,r0                  /* prevent fit & wdt exceptions */
379         mtspr   tbu,r0
380         mtspr   tsr,r1                  /* clear all timer exception status */
381         mtspr   tcr,r0                  /* disable all */
382         mtspr   esr,r0                  /* clear exception syndrome register */
383         mtxer   r0                      /* clear integer exception register */
384
385         /*----------------------------------------------------------------*/
386         /* Debug setup -- some (not very good) ice's need an event*/
387         /* to establish control :-( Define CFG_INIT_DBCR to the dbsr */
388         /* value you need in this case 0x8cff 0000 should do the trick */
389         /*----------------------------------------------------------------*/
390 #if defined(CFG_INIT_DBCR)
391         lis     r1,0xffff
392         ori     r1,r1,0xffff
393         mtspr   dbsr,r1                 /* Clear all status bits */
394         lis     r0,CFG_INIT_DBCR@h
395         ori     r0,r0,CFG_INIT_DBCR@l
396         mtspr   dbcr0,r0
397         isync
398 #endif
399
400         /*----------------------------------------------------------------*/
401         /* Setup the internal SRAM */
402         /*----------------------------------------------------------------*/
403         li      r0,0
404 #if defined(CONFIG_440EP) || defined(CONFIG_440GR)
405         /* Clear Dcache to use as RAM */
406         addis   r3,r0,CFG_INIT_RAM_ADDR@h
407         ori     r3,r3,CFG_INIT_RAM_ADDR@l
408         addis   r4,r0,CFG_INIT_RAM_END@h
409         ori     r4,r4,CFG_INIT_RAM_END@l
410         rlwinm. r5,r4,0,27,31
411         rlwinm  r5,r4,27,5,31
412         beq     ..d_ran
413         addi    r5,r5,0x0001
414 ..d_ran:
415         mtctr   r5
416 ..d_ag:
417         dcbz    r0,r3
418         addi    r3,r3,32
419         bdnz    ..d_ag
420 #else
421 #if defined (CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE)
422         mtdcr   l2_cache_cfg,r0         /* Ensure L2 Cache is off */
423 #endif
424         mtdcr   isram0_sb1cr,r0         /* Disable bank 1 */
425
426         li      r2,0x7fff
427         ori     r2,r2,0xffff
428         mfdcr   r1,isram0_dpc
429         and     r1,r1,r2                /* Disable parity check */
430         mtdcr   isram0_dpc,r1
431         mfdcr   r1,isram0_pmeg
432         andis.  r1,r1,r2                /* Disable pwr mgmt */
433         mtdcr   isram0_pmeg,r1
434
435         lis     r1,0x8000               /* BAS = 8000_0000 */
436 #if defined(CONFIG_440GX) || defined(CONFIG_440SP)
437         ori     r1,r1,0x0980            /* first 64k */
438         mtdcr   isram0_sb0cr,r1
439         lis     r1,0x8001
440         ori     r1,r1,0x0980            /* second 64k */
441         mtdcr   isram0_sb1cr,r1
442         lis     r1, 0x8002
443         ori     r1,r1, 0x0980           /* third 64k */
444         mtdcr   isram0_sb2cr,r1
445         lis     r1, 0x8003
446         ori     r1,r1, 0x0980           /* fourth 64k */
447         mtdcr   isram0_sb3cr,r1
448 #elif defined(CONFIG_440SPE)
449         lis     r1,0x0000               /* BAS = 0000_0000 */
450         ori     r1,r1,0x0984            /* first 64k */
451         mtdcr   isram0_sb0cr,r1
452         lis     r1,0x0001
453         ori     r1,r1,0x0984            /* second 64k */
454         mtdcr   isram0_sb1cr,r1
455         lis     r1, 0x0002
456         ori     r1,r1, 0x0984           /* third 64k */
457         mtdcr   isram0_sb2cr,r1
458         lis     r1, 0x0003
459         ori     r1,r1, 0x0984           /* fourth 64k */
460         mtdcr   isram0_sb3cr,r1
461 #else
462         ori     r1,r1,0x0380            /* 8k rw */
463         mtdcr   isram0_sb0cr,r1
464 #endif
465 #endif
466
467         /*----------------------------------------------------------------*/
468         /* Setup the stack in internal SRAM */
469         /*----------------------------------------------------------------*/
470         lis     r1,CFG_INIT_RAM_ADDR@h
471         ori     r1,r1,CFG_INIT_SP_OFFSET@l
472         li      r0,0
473         stwu    r0,-4(r1)
474         stwu    r0,-4(r1)               /* Terminate call chain */
475
476         stwu    r1,-8(r1)               /* Save back chain and move SP */
477         lis     r0,RESET_VECTOR@h       /* Address of reset vector */
478         ori     r0,r0, RESET_VECTOR@l
479         stwu    r1,-8(r1)               /* Save back chain and move SP */
480         stw     r0,+12(r1)              /* Save return addr (underflow vect) */
481
482         GET_GOT
483
484         bl      cpu_init_f      /* run low-level CPU init code     (from Flash) */
485         bl      board_init_f
486
487 #endif /* CONFIG_440 */
488
489 /*****************************************************************************/
490 #ifdef CONFIG_IOP480
491         /*----------------------------------------------------------------------- */
492         /* Set up some machine state registers. */
493         /*----------------------------------------------------------------------- */
494         addi    r0,r0,0x0000            /* initialize r0 to zero */
495         mtspr   esr,r0                  /* clear Exception Syndrome Reg */
496         mttcr   r0                      /* timer control register */
497         mtexier r0                      /* disable all interrupts */
498         addis   r4,r0,0xFFFF            /* set r4 to 0xFFFFFFFF (status in the */
499         ori     r4,r4,0xFFFF            /* dbsr is cleared by setting bits to 1) */
500         mtdbsr  r4                      /* clear/reset the dbsr */
501         mtexisr r4                      /* clear all pending interrupts */
502         addis   r4,r0,0x8000
503         mtexier r4                      /* enable critical exceptions */
504         addis   r4,r0,0x0000            /* assume 403GCX - enable core clk */
505         ori     r4,r4,0x4020            /* dbling (no harm done on GA and GC */
506         mtiocr  r4                      /* since bit not used) & DRC to latch */
507                                         /* data bus on rising edge of CAS */
508         /*----------------------------------------------------------------------- */
509         /* Clear XER. */
510         /*----------------------------------------------------------------------- */
511         mtxer   r0
512         /*----------------------------------------------------------------------- */
513         /* Invalidate i-cache and d-cache TAG arrays. */
514         /*----------------------------------------------------------------------- */
515         addi    r3,0,1024               /* 1/4 of I-cache size, half of D-cache */
516         addi    r4,0,1024               /* 1/4 of I-cache */
517 ..cloop:
518         iccci   0,r3
519         iccci   r4,r3
520         dccci   0,r3
521         addic.  r3,r3,-16               /* move back one cache line */
522         bne     ..cloop                 /* loop back to do rest until r3 = 0 */
523
524         /* */
525         /* initialize IOP480 so it can read 1 MB code area for SRAM spaces */
526         /* this requires enabling MA[17..0], by default only MA[12..0] are enabled. */
527         /* */
528
529         /* first copy IOP480 register base address into r3 */
530         addis   r3,0,0x5000             /* IOP480 register base address hi */
531 /*      ori     r3,r3,0x0000            /  IOP480 register base address lo */
532
533 #ifdef CONFIG_ADCIOP
534         /* use r4 as the working variable */
535         /* turn on CS3 (LOCCTL.7) */
536         lwz     r4,0x84(r3)             /* LOCTL is at offset 0x84 */
537         andi.   r4,r4,0xff7f            /* make bit 7 = 0 -- CS3 mode */
538         stw     r4,0x84(r3)             /* LOCTL is at offset 0x84 */
539 #endif
540
541 #ifdef CONFIG_DASA_SIM
542         /* use r4 as the working variable */
543         /* turn on MA17 (LOCCTL.7) */
544         lwz     r4,0x84(r3)             /* LOCTL is at offset 0x84 */
545         ori     r4,r4,0x80              /* make bit 7 = 1 -- MA17 mode */
546         stw     r4,0x84(r3)             /* LOCTL is at offset 0x84 */
547 #endif
548
549         /* turn on MA16..13 (LCS0BRD.12 = 0) */
550         lwz     r4,0x100(r3)            /* LCS0BRD is at offset 0x100 */
551         andi.   r4,r4,0xefff            /* make bit 12 = 0 */
552         stw     r4,0x100(r3)            /* LCS0BRD is at offset 0x100 */
553
554         /* make sure above stores all comlete before going on */
555         sync
556
557         /* last thing, set local init status done bit (DEVINIT.31) */
558         lwz     r4,0x80(r3)             /* DEVINIT is at offset 0x80 */
559         oris    r4,r4,0x8000            /* make bit 31 = 1 */
560         stw     r4,0x80(r3)             /* DEVINIT is at offset 0x80 */
561
562         /* clear all pending interrupts and disable all interrupts */
563         li      r4,-1                   /* set p1 to 0xffffffff */
564         stw     r4,0x1b0(r3)            /* clear all pending interrupts */
565         stw     r4,0x1b8(r3)            /* clear all pending interrupts */
566         li      r4,0                    /* set r4 to 0 */
567         stw     r4,0x1b4(r3)            /* disable all interrupts */
568         stw     r4,0x1bc(r3)            /* disable all interrupts */
569
570         /* make sure above stores all comlete before going on */
571         sync
572
573         /*----------------------------------------------------------------------- */
574         /* Enable two 128MB cachable regions. */
575         /*----------------------------------------------------------------------- */
576         addis   r1,r0,0x8000
577         addi    r1,r1,0x0001
578         mticcr  r1                      /* instruction cache */
579
580         addis   r1,r0,0x0000
581         addi    r1,r1,0x0000
582         mtdccr  r1                      /* data cache */
583
584         addis   r1,r0,CFG_INIT_RAM_ADDR@h
585         ori     r1,r1,CFG_INIT_SP_OFFSET          /* set up the stack to SDRAM */
586         li      r0, 0                   /* Make room for stack frame header and */
587         stwu    r0, -4(r1)              /* clear final stack frame so that      */
588         stwu    r0, -4(r1)              /* stack backtraces terminate cleanly   */
589
590         GET_GOT                 /* initialize GOT access                        */
591
592         bl      board_init_f    /* run first part of init code (from Flash)     */
593
594 #endif  /* CONFIG_IOP480 */
595
596 /*****************************************************************************/
597 #if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_405) || defined(CONFIG_405EP)
598         /*----------------------------------------------------------------------- */
599         /* Clear and set up some registers. */
600         /*----------------------------------------------------------------------- */
601         addi    r4,r0,0x0000
602         mtspr   sgr,r4
603         mtspr   dcwr,r4
604         mtesr   r4                      /* clear Exception Syndrome Reg */
605         mttcr   r4                      /* clear Timer Control Reg */
606         mtxer   r4                      /* clear Fixed-Point Exception Reg */
607         mtevpr  r4                      /* clear Exception Vector Prefix Reg */
608         addi    r4,r0,(0xFFFF-0x10000)          /* set r4 to 0xFFFFFFFF (status in the */
609                                         /* dbsr is cleared by setting bits to 1) */
610         mtdbsr  r4                      /* clear/reset the dbsr */
611
612         /*----------------------------------------------------------------------- */
613         /* Invalidate I and D caches. Enable I cache for defined memory regions */
614         /* to speed things up. Leave the D cache disabled for now. It will be */
615         /* enabled/left disabled later based on user selected menu options. */
616         /* Be aware that the I cache may be disabled later based on the menu */
617         /* options as well. See miscLib/main.c. */
618         /*----------------------------------------------------------------------- */
619         bl      invalidate_icache
620         bl      invalidate_dcache
621
622         /*----------------------------------------------------------------------- */
623         /* Enable two 128MB cachable regions. */
624         /*----------------------------------------------------------------------- */
625         addis   r4,r0,0x8000
626         addi    r4,r4,0x0001
627         mticcr  r4                      /* instruction cache */
628         isync
629
630         addis   r4,r0,0x0000
631         addi    r4,r4,0x0000
632         mtdccr  r4                      /* data cache */
633
634 #if !(defined(CFG_EBC_PB0AP) && defined(CFG_EBC_PB0CR))
635         /*----------------------------------------------------------------------- */
636         /* Tune the speed and size for flash CS0  */
637         /*----------------------------------------------------------------------- */
638         bl      ext_bus_cntlr_init
639 #endif
640
641 #if defined(CONFIG_405EP)
642         /*----------------------------------------------------------------------- */
643         /* DMA Status, clear to come up clean */
644         /*----------------------------------------------------------------------- */
645         addis   r3,r0, 0xFFFF         /* Clear all existing DMA status */
646         ori     r3,r3, 0xFFFF
647         mtdcr   dmasr, r3
648
649         bl      ppc405ep_init         /* do ppc405ep specific init */
650 #endif /* CONFIG_405EP */
651
652 #if defined(CFG_OCM_DATA_ADDR) && defined(CFG_OCM_DATA_SIZE)
653         /********************************************************************
654          * Setup OCM - On Chip Memory
655          *******************************************************************/
656         /* Setup OCM */
657         lis     r0, 0x7FFF
658         ori     r0, r0, 0xFFFF
659         mfdcr   r3, ocmiscntl           /* get instr-side IRAM config */
660         mfdcr   r4, ocmdscntl   /* get data-side IRAM config */
661         and     r3, r3, r0      /* disable data-side IRAM */
662         and     r4, r4, r0      /* disable data-side IRAM */
663         mtdcr   ocmiscntl, r3   /* set instr-side IRAM config */
664         mtdcr   ocmdscntl, r4   /* set data-side IRAM config */
665         isync
666
667         addis   r3, 0, CFG_OCM_DATA_ADDR@h /* OCM location */
668         mtdcr   ocmdsarc, r3
669         addis   r4, 0, 0xC000           /* OCM data area enabled */
670         mtdcr   ocmdscntl, r4
671         isync
672 #endif
673
674         /*----------------------------------------------------------------------- */
675         /* Setup temporary stack in DCACHE or OCM if needed for SDRAM SPD. */
676         /*----------------------------------------------------------------------- */
677 #ifdef CFG_INIT_DCACHE_CS
678         /*----------------------------------------------------------------------- */
679         /* Memory Bank x (nothingness) initialization 1GB+64MEG */
680         /* used as temporary stack pointer for stage0  */
681         /*----------------------------------------------------------------------- */
682         li      r4,PBxAP
683         mtdcr   ebccfga,r4
684         lis     r4,0x0380
685         ori     r4,r4,0x0480
686         mtdcr   ebccfgd,r4
687
688         addi    r4,0,PBxCR
689         mtdcr   ebccfga,r4
690         lis     r4,0x400D
691         ori     r4,r4,0xa000
692         mtdcr   ebccfgd,r4
693
694         /* turn on data chache for this region */
695         lis     r4,0x0080
696         mtdccr  r4
697
698         /* set stack pointer and clear stack to known value */
699
700         lis     r1,CFG_INIT_RAM_ADDR@h
701         ori     r1,r1,CFG_INIT_SP_OFFSET@l
702
703         li      r4,2048                 /* we store 2048 words to stack */
704         mtctr   r4
705
706         lis     r2,CFG_INIT_RAM_ADDR@h          /* we also clear data area */
707         ori     r2,r2,CFG_INIT_RAM_END@l        /* so cant copy value from r1 */
708
709         lis     r4,0xdead               /* we store 0xdeaddead in the stack */
710         ori     r4,r4,0xdead
711
712 ..stackloop:
713         stwu    r4,-4(r2)
714         bdnz    ..stackloop
715
716         li      r0, 0                   /* Make room for stack frame header and */
717         stwu    r0, -4(r1)              /* clear final stack frame so that      */
718         stwu    r0, -4(r1)              /* stack backtraces terminate cleanly   */
719         /*
720          * Set up a dummy frame to store reset vector as return address.
721          * this causes stack underflow to reset board.
722          */
723         stwu    r1, -8(r1)              /* Save back chain and move SP */
724         addis   r0, 0, RESET_VECTOR@h   /* Address of reset vector */
725         ori     r0, r0, RESET_VECTOR@l
726         stwu    r1, -8(r1)              /* Save back chain and move SP */
727         stw     r0, +12(r1)             /* Save return addr (underflow vect) */
728
729 #elif defined(CFG_TEMP_STACK_OCM) && \
730         (defined(CFG_OCM_DATA_ADDR) && defined(CFG_OCM_DATA_SIZE))
731         /*
732          * Stack in OCM.
733          */
734
735         /* Set up Stack at top of OCM */
736         lis     r1, (CFG_INIT_RAM_ADDR + CFG_INIT_SP_OFFSET)@h
737         ori     r1, r1, (CFG_INIT_RAM_ADDR + CFG_INIT_SP_OFFSET)@l
738
739         /* Set up a zeroized stack frame so that backtrace works right */
740         li      r0, 0
741         stwu    r0, -4(r1)
742         stwu    r0, -4(r1)
743
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         lis     r0, 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 #endif /* CFG_INIT_DCACHE_CS */
754
755         /*----------------------------------------------------------------------- */
756         /* Initialize SDRAM Controller  */
757         /*----------------------------------------------------------------------- */
758         bl      sdram_init
759
760         /*
761          * Setup temporary stack pointer only for boards
762          * that do not use SDRAM SPD I2C stuff since it
763          * is already initialized to use DCACHE or OCM
764          * stacks.
765          */
766 #if !(defined(CFG_INIT_DCACHE_CS) || defined(CFG_TEMP_STACK_OCM))
767         lis     r1, CFG_INIT_RAM_ADDR@h
768         ori     r1,r1,CFG_INIT_SP_OFFSET /* set up the stack in SDRAM */
769
770         li      r0, 0                   /* Make room for stack frame header and */
771         stwu    r0, -4(r1)              /* clear final stack frame so that      */
772         stwu    r0, -4(r1)              /* stack backtraces terminate cleanly   */
773         /*
774          * Set up a dummy frame to store reset vector as return address.
775          * this causes stack underflow to reset board.
776          */
777         stwu    r1, -8(r1)              /* Save back chain and move SP */
778         lis     r0, RESET_VECTOR@h      /* Address of reset vector */
779         ori     r0, r0, RESET_VECTOR@l
780         stwu    r1, -8(r1)              /* Save back chain and move SP */
781         stw     r0, +12(r1)             /* Save return addr (underflow vect) */
782 #endif /* !(CFG_INIT_DCACHE_CS  || !CFG_TEM_STACK_OCM) */
783
784         GET_GOT                 /* initialize GOT access                        */
785
786         bl      cpu_init_f      /* run low-level CPU init code     (from Flash) */
787
788         /* NEVER RETURNS! */
789         bl      board_init_f    /* run first part of init code (from Flash)     */
790
791 #endif  /* CONFIG_405GP || CONFIG_405CR || CONFIG_405 || CONFIG_405EP */
792         /*----------------------------------------------------------------------- */
793
794
795 /*****************************************************************************/
796         .globl  _start_of_vectors
797 _start_of_vectors:
798
799 #if 0
800 /*TODO Fixup _start above so we can do this*/
801 /* Critical input. */
802         CRIT_EXCEPTION(0x100, CritcalInput, CritcalInputException)
803 #endif
804
805 /* Machine check */
806         CRIT_EXCEPTION(0x200, MachineCheck, MachineCheckException)
807
808 /* Data Storage exception. */
809         STD_EXCEPTION(0x300, DataStorage, UnknownException)
810
811 /* Instruction Storage exception. */
812         STD_EXCEPTION(0x400, InstStorage, UnknownException)
813
814 /* External Interrupt exception. */
815         STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
816
817 /* Alignment exception. */
818         . = 0x600
819 Alignment:
820         EXCEPTION_PROLOG
821         mfspr   r4,DAR
822         stw     r4,_DAR(r21)
823         mfspr   r5,DSISR
824         stw     r5,_DSISR(r21)
825         addi    r3,r1,STACK_FRAME_OVERHEAD
826         li      r20,MSR_KERNEL
827         rlwimi  r20,r23,0,16,16         /* copy EE bit from saved MSR */
828         lwz     r6,GOT(transfer_to_handler)
829         mtlr    r6
830         blrl
831 .L_Alignment:
832         .long   AlignmentException - _start + EXC_OFF_SYS_RESET
833         .long   int_return - _start + EXC_OFF_SYS_RESET
834
835 /* Program check exception */
836         . = 0x700
837 ProgramCheck:
838         EXCEPTION_PROLOG
839         addi    r3,r1,STACK_FRAME_OVERHEAD
840         li      r20,MSR_KERNEL
841         rlwimi  r20,r23,0,16,16         /* copy EE bit from saved MSR */
842         lwz     r6,GOT(transfer_to_handler)
843         mtlr    r6
844         blrl
845 .L_ProgramCheck:
846         .long   ProgramCheckException - _start + EXC_OFF_SYS_RESET
847         .long   int_return - _start + EXC_OFF_SYS_RESET
848
849         /* No FPU on MPC8xx.  This exception is not supposed to happen.
850         */
851         STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
852
853         /* I guess we could implement decrementer, and may have
854          * to someday for timekeeping.
855          */
856         STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
857         STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
858         STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
859         STD_EXCEPTION(0xc00, SystemCall, UnknownException)
860         STD_EXCEPTION(0xd00, SingleStep, UnknownException)
861
862         STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
863         STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
864
865         /* On the MPC8xx, this is a software emulation interrupt.  It occurs
866          * for all unimplemented and illegal instructions.
867          */
868         STD_EXCEPTION(0x1000, PIT, PITException)
869
870         STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException)
871         STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException)
872         STD_EXCEPTION(0x1300, InstructionTLBError, UnknownException)
873         STD_EXCEPTION(0x1400, DataTLBError, UnknownException)
874
875         STD_EXCEPTION(0x1500, Reserved5, UnknownException)
876         STD_EXCEPTION(0x1600, Reserved6, UnknownException)
877         STD_EXCEPTION(0x1700, Reserved7, UnknownException)
878         STD_EXCEPTION(0x1800, Reserved8, UnknownException)
879         STD_EXCEPTION(0x1900, Reserved9, UnknownException)
880         STD_EXCEPTION(0x1a00, ReservedA, UnknownException)
881         STD_EXCEPTION(0x1b00, ReservedB, UnknownException)
882
883         STD_EXCEPTION(0x1c00, DataBreakpoint, UnknownException)
884         STD_EXCEPTION(0x1d00, InstructionBreakpoint, UnknownException)
885         STD_EXCEPTION(0x1e00, PeripheralBreakpoint, UnknownException)
886         STD_EXCEPTION(0x1f00, DevPortBreakpoint, UnknownException)
887
888         CRIT_EXCEPTION(0x2000, DebugBreakpoint, DebugException )
889
890         .globl  _end_of_vectors
891 _end_of_vectors:
892
893
894         . = 0x2100
895
896 /*
897  * This code finishes saving the registers to the exception frame
898  * and jumps to the appropriate handler for the exception.
899  * Register r21 is pointer into trap frame, r1 has new stack pointer.
900  */
901         .globl  transfer_to_handler
902 transfer_to_handler:
903         stw     r22,_NIP(r21)
904         lis     r22,MSR_POW@h
905         andc    r23,r23,r22
906         stw     r23,_MSR(r21)
907         SAVE_GPR(7, r21)
908         SAVE_4GPRS(8, r21)
909         SAVE_8GPRS(12, r21)
910         SAVE_8GPRS(24, r21)
911 #if 0
912         andi.   r23,r23,MSR_PR
913         mfspr   r23,SPRG3               /* if from user, fix up tss.regs */
914         beq     2f
915         addi    r24,r1,STACK_FRAME_OVERHEAD
916         stw     r24,PT_REGS(r23)
917 2:      addi    r2,r23,-TSS             /* set r2 to current */
918         tovirt(r2,r2,r23)
919 #endif
920         mflr    r23
921         andi.   r24,r23,0x3f00          /* get vector offset */
922         stw     r24,TRAP(r21)
923         li      r22,0
924         stw     r22,RESULT(r21)
925         mtspr   SPRG2,r22               /* r1 is now kernel sp */
926 #if 0
927         addi    r24,r2,TASK_STRUCT_SIZE /* check for kernel stack overflow */
928         cmplw   0,r1,r2
929         cmplw   1,r1,r24
930         crand   1,1,4
931         bgt     stack_ovf               /* if r2 < r1 < r2+TASK_STRUCT_SIZE */
932 #endif
933         lwz     r24,0(r23)              /* virtual address of handler */
934         lwz     r23,4(r23)              /* where to go when done */
935         mtspr   SRR0,r24
936         mtspr   SRR1,r20
937         mtlr    r23
938         SYNC
939         rfi                             /* jump to handler, enable MMU */
940
941 int_return:
942         mfmsr   r28             /* Disable interrupts */
943         li      r4,0
944         ori     r4,r4,MSR_EE
945         andc    r28,r28,r4
946         SYNC                    /* Some chip revs need this... */
947         mtmsr   r28
948         SYNC
949         lwz     r2,_CTR(r1)
950         lwz     r0,_LINK(r1)
951         mtctr   r2
952         mtlr    r0
953         lwz     r2,_XER(r1)
954         lwz     r0,_CCR(r1)
955         mtspr   XER,r2
956         mtcrf   0xFF,r0
957         REST_10GPRS(3, r1)
958         REST_10GPRS(13, r1)
959         REST_8GPRS(23, r1)
960         REST_GPR(31, r1)
961         lwz     r2,_NIP(r1)     /* Restore environment */
962         lwz     r0,_MSR(r1)
963         mtspr   SRR0,r2
964         mtspr   SRR1,r0
965         lwz     r0,GPR0(r1)
966         lwz     r2,GPR2(r1)
967         lwz     r1,GPR1(r1)
968         SYNC
969         rfi
970
971 crit_return:
972         mfmsr   r28             /* Disable interrupts */
973         li      r4,0
974         ori     r4,r4,MSR_EE
975         andc    r28,r28,r4
976         SYNC                    /* Some chip revs need this... */
977         mtmsr   r28
978         SYNC
979         lwz     r2,_CTR(r1)
980         lwz     r0,_LINK(r1)
981         mtctr   r2
982         mtlr    r0
983         lwz     r2,_XER(r1)
984         lwz     r0,_CCR(r1)
985         mtspr   XER,r2
986         mtcrf   0xFF,r0
987         REST_10GPRS(3, r1)
988         REST_10GPRS(13, r1)
989         REST_8GPRS(23, r1)
990         REST_GPR(31, r1)
991         lwz     r2,_NIP(r1)     /* Restore environment */
992         lwz     r0,_MSR(r1)
993         mtspr   990,r2          /* SRR2 */
994         mtspr   991,r0          /* SRR3 */
995         lwz     r0,GPR0(r1)
996         lwz     r2,GPR2(r1)
997         lwz     r1,GPR1(r1)
998         SYNC
999         rfci
1000
1001 /* Cache functions.
1002 */
1003 invalidate_icache:
1004         iccci   r0,r0                   /* for 405, iccci invalidates the */
1005         blr                             /*   entire I cache */
1006
1007 invalidate_dcache:
1008         addi    r6,0,0x0000             /* clear GPR 6 */
1009         /* Do loop for # of dcache congruence classes. */
1010         lis     r7, (CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@ha       /* TBS for large sized cache */
1011         ori     r7, r7, (CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@l
1012                                         /* NOTE: dccci invalidates both */
1013         mtctr   r7                      /* ways in the D cache */
1014 ..dcloop:
1015         dccci   0,r6                    /* invalidate line */
1016         addi    r6,r6, CFG_CACHELINE_SIZE /* bump to next line */
1017         bdnz    ..dcloop
1018         blr
1019
1020 flush_dcache:
1021         addis   r9,r0,0x0002            /* set mask for EE and CE msr bits */
1022         ori     r9,r9,0x8000
1023         mfmsr   r12                     /* save msr */
1024         andc    r9,r12,r9
1025         mtmsr   r9                      /* disable EE and CE */
1026         addi    r10,r0,0x0001           /* enable data cache for unused memory */
1027         mfdccr  r9                      /* region 0xF8000000-0xFFFFFFFF via */
1028         or      r10,r10,r9              /* bit 31 in dccr */
1029         mtdccr  r10
1030
1031         /* do loop for # of congruence classes. */
1032         lis     r10,(CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@ha       /* TBS: for large cache sizes */
1033         ori     r10,r10,(CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@l
1034         lis     r11,(CFG_DCACHE_SIZE / 2)@ha /* D cache set size - 2 way sets */
1035         ori     r11,r11,(CFG_DCACHE_SIZE / 2)@l /* D cache set size - 2 way sets */
1036         mtctr   r10
1037         addi    r10,r0,(0xE000-0x10000) /* start at 0xFFFFE000 */
1038         add     r11,r10,r11             /* add to get to other side of cache line */
1039 ..flush_dcache_loop:
1040         lwz     r3,0(r10)               /* least recently used side */
1041         lwz     r3,0(r11)               /* the other side */
1042         dccci   r0,r11                  /* invalidate both sides */
1043         addi    r10,r10,CFG_CACHELINE_SIZE /* bump to next line */
1044         addi    r11,r11,CFG_CACHELINE_SIZE /* bump to next line */
1045         bdnz    ..flush_dcache_loop
1046         sync                            /* allow memory access to complete */
1047         mtdccr  r9                      /* restore dccr */
1048         mtmsr   r12                     /* restore msr */
1049         blr
1050
1051         .globl  icache_enable
1052 icache_enable:
1053         mflr    r8
1054         bl      invalidate_icache
1055         mtlr    r8
1056         isync
1057         addis   r3,r0, 0x8000         /* set bit 0 */
1058         mticcr  r3
1059         blr
1060
1061         .globl  icache_disable
1062 icache_disable:
1063         addis   r3,r0, 0x0000         /* clear bit 0 */
1064         mticcr  r3
1065         isync
1066         blr
1067
1068         .globl  icache_status
1069 icache_status:
1070         mficcr  r3
1071         srwi    r3, r3, 31      /* >>31 => select bit 0 */
1072         blr
1073
1074         .globl  dcache_enable
1075 dcache_enable:
1076         mflr    r8
1077         bl      invalidate_dcache
1078         mtlr    r8
1079         isync
1080         addis   r3,r0, 0x8000         /* set bit 0 */
1081         mtdccr  r3
1082         blr
1083
1084         .globl  dcache_disable
1085 dcache_disable:
1086         mflr    r8
1087         bl      flush_dcache
1088         mtlr    r8
1089         addis   r3,r0, 0x0000         /* clear bit 0 */
1090         mtdccr  r3
1091         blr
1092
1093         .globl  dcache_status
1094 dcache_status:
1095         mfdccr  r3
1096         srwi    r3, r3, 31      /* >>31 => select bit 0 */
1097         blr
1098
1099         .globl get_pvr
1100 get_pvr:
1101         mfspr   r3, PVR
1102         blr
1103
1104 #if !defined(CONFIG_440)
1105         .globl wr_pit
1106 wr_pit:
1107         mtspr   pit, r3
1108         blr
1109 #endif
1110
1111         .globl wr_tcr
1112 wr_tcr:
1113         mtspr   tcr, r3
1114         blr
1115
1116 /*------------------------------------------------------------------------------- */
1117 /* Function:     in8 */
1118 /* Description:  Input 8 bits */
1119 /*------------------------------------------------------------------------------- */
1120         .globl  in8
1121 in8:
1122         lbz     r3,0x0000(r3)
1123         blr
1124
1125 /*------------------------------------------------------------------------------- */
1126 /* Function:     out8 */
1127 /* Description:  Output 8 bits */
1128 /*------------------------------------------------------------------------------- */
1129         .globl  out8
1130 out8:
1131         stb     r4,0x0000(r3)
1132         blr
1133
1134 /*------------------------------------------------------------------------------- */
1135 /* Function:     out16 */
1136 /* Description:  Output 16 bits */
1137 /*------------------------------------------------------------------------------- */
1138         .globl  out16
1139 out16:
1140         sth     r4,0x0000(r3)
1141         blr
1142
1143 /*------------------------------------------------------------------------------- */
1144 /* Function:     out16r */
1145 /* Description:  Byte reverse and output 16 bits */
1146 /*------------------------------------------------------------------------------- */
1147         .globl  out16r
1148 out16r:
1149         sthbrx  r4,r0,r3
1150         blr
1151
1152 /*------------------------------------------------------------------------------- */
1153 /* Function:     out32 */
1154 /* Description:  Output 32 bits */
1155 /*------------------------------------------------------------------------------- */
1156         .globl  out32
1157 out32:
1158         stw     r4,0x0000(r3)
1159         blr
1160
1161 /*------------------------------------------------------------------------------- */
1162 /* Function:     out32r */
1163 /* Description:  Byte reverse and output 32 bits */
1164 /*------------------------------------------------------------------------------- */
1165         .globl  out32r
1166 out32r:
1167         stwbrx  r4,r0,r3
1168         blr
1169
1170 /*------------------------------------------------------------------------------- */
1171 /* Function:     in16 */
1172 /* Description:  Input 16 bits */
1173 /*------------------------------------------------------------------------------- */
1174         .globl  in16
1175 in16:
1176         lhz     r3,0x0000(r3)
1177         blr
1178
1179 /*------------------------------------------------------------------------------- */
1180 /* Function:     in16r */
1181 /* Description:  Input 16 bits and byte reverse */
1182 /*------------------------------------------------------------------------------- */
1183         .globl  in16r
1184 in16r:
1185         lhbrx   r3,r0,r3
1186         blr
1187
1188 /*------------------------------------------------------------------------------- */
1189 /* Function:     in32 */
1190 /* Description:  Input 32 bits */
1191 /*------------------------------------------------------------------------------- */
1192         .globl  in32
1193 in32:
1194         lwz     3,0x0000(3)
1195         blr
1196
1197 /*------------------------------------------------------------------------------- */
1198 /* Function:     in32r */
1199 /* Description:  Input 32 bits and byte reverse */
1200 /*------------------------------------------------------------------------------- */
1201         .globl  in32r
1202 in32r:
1203         lwbrx   r3,r0,r3
1204         blr
1205
1206 /*------------------------------------------------------------------------------- */
1207 /* Function:     ppcDcbf */
1208 /* Description:  Data Cache block flush */
1209 /* Input:        r3 = effective address */
1210 /* Output:       none. */
1211 /*------------------------------------------------------------------------------- */
1212         .globl  ppcDcbf
1213 ppcDcbf:
1214         dcbf    r0,r3
1215         blr
1216
1217 /*------------------------------------------------------------------------------- */
1218 /* Function:     ppcDcbi */
1219 /* Description:  Data Cache block Invalidate */
1220 /* Input:        r3 = effective address */
1221 /* Output:       none. */
1222 /*------------------------------------------------------------------------------- */
1223         .globl  ppcDcbi
1224 ppcDcbi:
1225         dcbi    r0,r3
1226         blr
1227
1228 /*------------------------------------------------------------------------------- */
1229 /* Function:     ppcSync */
1230 /* Description:  Processor Synchronize */
1231 /* Input:        none. */
1232 /* Output:       none. */
1233 /*------------------------------------------------------------------------------- */
1234         .globl  ppcSync
1235 ppcSync:
1236         sync
1237         blr
1238
1239 /*------------------------------------------------------------------------------*/
1240
1241 /*
1242  * void relocate_code (addr_sp, gd, addr_moni)
1243  *
1244  * This "function" does not return, instead it continues in RAM
1245  * after relocating the monitor code.
1246  *
1247  * r3 = dest
1248  * r4 = src
1249  * r5 = length in bytes
1250  * r6 = cachelinesize
1251  */
1252         .globl  relocate_code
1253 relocate_code:
1254 #if defined(CONFIG_440EP) || defined(CONFIG_440GR) || defined(CONFIG_440SPE)
1255         /*
1256          * On some 440er platforms the cache is enabled in the first TLB (Boot-CS)
1257          * to speed up the boot process. Now this cache needs to be disabled.
1258          */
1259         iccci   0,0                     /* Invalidate inst cache */
1260         dccci   0,0                     /* Invalidate data cache, now no longer our stack */
1261         sync
1262         isync
1263         addi    r1,r0,0x0000            /* TLB entry #0 */
1264         tlbre   r0,r1,0x0002            /* Read contents */
1265         ori     r0,r0,0x0c00            /* Or in the inhibit, write through bit */
1266         tlbwe   r0,r1,0x0002            /* Save it out */
1267         sync
1268         isync
1269 #endif
1270         mr      r1,  r3         /* Set new stack pointer                */
1271         mr      r9,  r4         /* Save copy of Init Data pointer       */
1272         mr      r10, r5         /* Save copy of Destination Address     */
1273
1274         mr      r3,  r5                         /* Destination Address  */
1275         lis     r4, CFG_MONITOR_BASE@h          /* Source      Address  */
1276         ori     r4, r4, CFG_MONITOR_BASE@l
1277         lwz     r5, GOT(__init_end)
1278         sub     r5, r5, r4
1279         li      r6, CFG_CACHELINE_SIZE          /* Cache Line Size      */
1280
1281         /*
1282          * Fix GOT pointer:
1283          *
1284          * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address
1285          *
1286          * Offset:
1287          */
1288         sub     r15, r10, r4
1289
1290         /* First our own GOT */
1291         add     r14, r14, r15
1292         /* the the one used by the C code */
1293         add     r30, r30, r15
1294
1295         /*
1296          * Now relocate code
1297          */
1298
1299         cmplw   cr1,r3,r4
1300         addi    r0,r5,3
1301         srwi.   r0,r0,2
1302         beq     cr1,4f          /* In place copy is not necessary       */
1303         beq     7f              /* Protect against 0 count              */
1304         mtctr   r0
1305         bge     cr1,2f
1306
1307         la      r8,-4(r4)
1308         la      r7,-4(r3)
1309 1:      lwzu    r0,4(r8)
1310         stwu    r0,4(r7)
1311         bdnz    1b
1312         b       4f
1313
1314 2:      slwi    r0,r0,2
1315         add     r8,r4,r0
1316         add     r7,r3,r0
1317 3:      lwzu    r0,-4(r8)
1318         stwu    r0,-4(r7)
1319         bdnz    3b
1320
1321 /*
1322  * Now flush the cache: note that we must start from a cache aligned
1323  * address. Otherwise we might miss one cache line.
1324  */
1325 4:      cmpwi   r6,0
1326         add     r5,r3,r5
1327         beq     7f              /* Always flush prefetch queue in any case */
1328         subi    r0,r6,1
1329         andc    r3,r3,r0
1330         mr      r4,r3
1331 5:      dcbst   0,r4
1332         add     r4,r4,r6
1333         cmplw   r4,r5
1334         blt     5b
1335         sync                    /* Wait for all dcbst to complete on bus */
1336         mr      r4,r3
1337 6:      icbi    0,r4
1338         add     r4,r4,r6
1339         cmplw   r4,r5
1340         blt     6b
1341 7:      sync                    /* Wait for all icbi to complete on bus */
1342         isync
1343
1344 /*
1345  * We are done. Do not return, instead branch to second part of board
1346  * initialization, now running from RAM.
1347  */
1348
1349         addi    r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
1350         mtlr    r0
1351         blr                             /* NEVER RETURNS! */
1352
1353 in_ram:
1354
1355         /*
1356          * Relocation Function, r14 point to got2+0x8000
1357          *
1358          * Adjust got2 pointers, no need to check for 0, this code
1359          * already puts a few entries in the table.
1360          */
1361         li      r0,__got2_entries@sectoff@l
1362         la      r3,GOT(_GOT2_TABLE_)
1363         lwz     r11,GOT(_GOT2_TABLE_)
1364         mtctr   r0
1365         sub     r11,r3,r11
1366         addi    r3,r3,-4
1367 1:      lwzu    r0,4(r3)
1368         add     r0,r0,r11
1369         stw     r0,0(r3)
1370         bdnz    1b
1371
1372         /*
1373          * Now adjust the fixups and the pointers to the fixups
1374          * in case we need to move ourselves again.
1375          */
1376 2:      li      r0,__fixup_entries@sectoff@l
1377         lwz     r3,GOT(_FIXUP_TABLE_)
1378         cmpwi   r0,0
1379         mtctr   r0
1380         addi    r3,r3,-4
1381         beq     4f
1382 3:      lwzu    r4,4(r3)
1383         lwzux   r0,r4,r11
1384         add     r0,r0,r11
1385         stw     r10,0(r3)
1386         stw     r0,0(r4)
1387         bdnz    3b
1388 4:
1389 clear_bss:
1390         /*
1391          * Now clear BSS segment
1392          */
1393         lwz     r3,GOT(__bss_start)
1394         lwz     r4,GOT(_end)
1395
1396         cmplw   0, r3, r4
1397         beq     6f
1398
1399         li      r0, 0
1400 5:
1401         stw     r0, 0(r3)
1402         addi    r3, r3, 4
1403         cmplw   0, r3, r4
1404         bne     5b
1405 6:
1406
1407         mr      r3, r9          /* Init Data pointer            */
1408         mr      r4, r10         /* Destination Address          */
1409         bl      board_init_r
1410
1411         /*
1412          * Copy exception vector code to low memory
1413          *
1414          * r3: dest_addr
1415          * r7: source address, r8: end address, r9: target address
1416          */
1417         .globl  trap_init
1418 trap_init:
1419         lwz     r7, GOT(_start)
1420         lwz     r8, GOT(_end_of_vectors)
1421
1422         li      r9, 0x100               /* reset vector always at 0x100 */
1423
1424         cmplw   0, r7, r8
1425         bgelr                           /* return if r7>=r8 - just in case */
1426
1427         mflr    r4                      /* save link register           */
1428 1:
1429         lwz     r0, 0(r7)
1430         stw     r0, 0(r9)
1431         addi    r7, r7, 4
1432         addi    r9, r9, 4
1433         cmplw   0, r7, r8
1434         bne     1b
1435
1436         /*
1437          * relocate `hdlr' and `int_return' entries
1438          */
1439         li      r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
1440         li      r8, Alignment - _start + EXC_OFF_SYS_RESET
1441 2:
1442         bl      trap_reloc
1443         addi    r7, r7, 0x100           /* next exception vector        */
1444         cmplw   0, r7, r8
1445         blt     2b
1446
1447         li      r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
1448         bl      trap_reloc
1449
1450         li      r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
1451         bl      trap_reloc
1452
1453         li      r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
1454         li      r8, SystemCall - _start + EXC_OFF_SYS_RESET
1455 3:
1456         bl      trap_reloc
1457         addi    r7, r7, 0x100           /* next exception vector        */
1458         cmplw   0, r7, r8
1459         blt     3b
1460
1461         li      r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
1462         li      r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
1463 4:
1464         bl      trap_reloc
1465         addi    r7, r7, 0x100           /* next exception vector        */
1466         cmplw   0, r7, r8
1467         blt     4b
1468
1469 #if !defined(CONFIG_440GX) && !defined(CONFIG_440SPE)
1470         addi    r7,r0,0x1000            /* set ME bit (Machine Exceptions) */
1471         oris    r7,r7,0x0002            /* set CE bit (Critical Exceptions) */
1472         mtmsr   r7                      /* change MSR */
1473 #else
1474         bl      __440gx_msr_set
1475         b       __440gx_msr_continue
1476
1477 __440gx_msr_set:
1478         addi    r7,r0,0x1000            /* set ME bit (Machine Exceptions) */
1479         oris    r7,r7,0x0002            /* set CE bit (Critical Exceptions) */
1480         mtspr   srr1,r7
1481         mflr    r7
1482         mtspr   srr0,r7
1483         rfi
1484 __440gx_msr_continue:
1485 #endif
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 */