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