Merge branch 'origin'
[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         dccci   0,0                         /* Invalidate data cache, now no longer our stack */
1202         sync
1203         addi    r1,r0,0x0000            /* TLB entry #0 */
1204         tlbre   r0,r1,0x0002            /* Read contents */
1205         ori     r0,r0,0x0c00            /* Or in the inhibit, write through bit */
1206         tlbwe   r0,r1,0x0002            /* Save it out */
1207         isync
1208 #endif
1209         mr      r1,  r3         /* Set new stack pointer                */
1210         mr      r9,  r4         /* Save copy of Init Data pointer       */
1211         mr      r10, r5         /* Save copy of Destination Address     */
1212
1213         mr      r3,  r5                         /* Destination Address  */
1214         lis     r4, CFG_MONITOR_BASE@h          /* Source      Address  */
1215         ori     r4, r4, CFG_MONITOR_BASE@l
1216         lwz     r5, GOT(__init_end)
1217         sub     r5, r5, r4
1218         li      r6, CFG_CACHELINE_SIZE          /* Cache Line Size      */
1219
1220         /*
1221          * Fix GOT pointer:
1222          *
1223          * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address
1224          *
1225          * Offset:
1226          */
1227         sub     r15, r10, r4
1228
1229         /* First our own GOT */
1230         add     r14, r14, r15
1231         /* the the one used by the C code */
1232         add     r30, r30, r15
1233
1234         /*
1235          * Now relocate code
1236          */
1237
1238         cmplw   cr1,r3,r4
1239         addi    r0,r5,3
1240         srwi.   r0,r0,2
1241         beq     cr1,4f          /* In place copy is not necessary       */
1242         beq     7f              /* Protect against 0 count              */
1243         mtctr   r0
1244         bge     cr1,2f
1245
1246         la      r8,-4(r4)
1247         la      r7,-4(r3)
1248 1:      lwzu    r0,4(r8)
1249         stwu    r0,4(r7)
1250         bdnz    1b
1251         b       4f
1252
1253 2:      slwi    r0,r0,2
1254         add     r8,r4,r0
1255         add     r7,r3,r0
1256 3:      lwzu    r0,-4(r8)
1257         stwu    r0,-4(r7)
1258         bdnz    3b
1259
1260 /*
1261  * Now flush the cache: note that we must start from a cache aligned
1262  * address. Otherwise we might miss one cache line.
1263  */
1264 4:      cmpwi   r6,0
1265         add     r5,r3,r5
1266         beq     7f              /* Always flush prefetch queue in any case */
1267         subi    r0,r6,1
1268         andc    r3,r3,r0
1269         mr      r4,r3
1270 5:      dcbst   0,r4
1271         add     r4,r4,r6
1272         cmplw   r4,r5
1273         blt     5b
1274         sync                    /* Wait for all dcbst to complete on bus */
1275         mr      r4,r3
1276 6:      icbi    0,r4
1277         add     r4,r4,r6
1278         cmplw   r4,r5
1279         blt     6b
1280 7:      sync                    /* Wait for all icbi to complete on bus */
1281         isync
1282
1283 /*
1284  * We are done. Do not return, instead branch to second part of board
1285  * initialization, now running from RAM.
1286  */
1287
1288         addi    r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
1289         mtlr    r0
1290         blr                             /* NEVER RETURNS! */
1291
1292 in_ram:
1293
1294         /*
1295          * Relocation Function, r14 point to got2+0x8000
1296          *
1297          * Adjust got2 pointers, no need to check for 0, this code
1298          * already puts a few entries in the table.
1299          */
1300         li      r0,__got2_entries@sectoff@l
1301         la      r3,GOT(_GOT2_TABLE_)
1302         lwz     r11,GOT(_GOT2_TABLE_)
1303         mtctr   r0
1304         sub     r11,r3,r11
1305         addi    r3,r3,-4
1306 1:      lwzu    r0,4(r3)
1307         add     r0,r0,r11
1308         stw     r0,0(r3)
1309         bdnz    1b
1310
1311         /*
1312          * Now adjust the fixups and the pointers to the fixups
1313          * in case we need to move ourselves again.
1314          */
1315 2:      li      r0,__fixup_entries@sectoff@l
1316         lwz     r3,GOT(_FIXUP_TABLE_)
1317         cmpwi   r0,0
1318         mtctr   r0
1319         addi    r3,r3,-4
1320         beq     4f
1321 3:      lwzu    r4,4(r3)
1322         lwzux   r0,r4,r11
1323         add     r0,r0,r11
1324         stw     r10,0(r3)
1325         stw     r0,0(r4)
1326         bdnz    3b
1327 4:
1328 clear_bss:
1329         /*
1330          * Now clear BSS segment
1331          */
1332         lwz     r3,GOT(__bss_start)
1333         lwz     r4,GOT(_end)
1334
1335         cmplw   0, r3, r4
1336         beq     6f
1337
1338         li      r0, 0
1339 5:
1340         stw     r0, 0(r3)
1341         addi    r3, r3, 4
1342         cmplw   0, r3, r4
1343         bne     5b
1344 6:
1345
1346         mr      r3, r9          /* Init Data pointer            */
1347         mr      r4, r10         /* Destination Address          */
1348         bl      board_init_r
1349
1350         /*
1351          * Copy exception vector code to low memory
1352          *
1353          * r3: dest_addr
1354          * r7: source address, r8: end address, r9: target address
1355          */
1356         .globl  trap_init
1357 trap_init:
1358         lwz     r7, GOT(_start)
1359         lwz     r8, GOT(_end_of_vectors)
1360
1361         li      r9, 0x100               /* reset vector always at 0x100 */
1362
1363         cmplw   0, r7, r8
1364         bgelr                           /* return if r7>=r8 - just in case */
1365
1366         mflr    r4                      /* save link register           */
1367 1:
1368         lwz     r0, 0(r7)
1369         stw     r0, 0(r9)
1370         addi    r7, r7, 4
1371         addi    r9, r9, 4
1372         cmplw   0, r7, r8
1373         bne     1b
1374
1375         /*
1376          * relocate `hdlr' and `int_return' entries
1377          */
1378         li      r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
1379         li      r8, Alignment - _start + EXC_OFF_SYS_RESET
1380 2:
1381         bl      trap_reloc
1382         addi    r7, r7, 0x100           /* next exception vector        */
1383         cmplw   0, r7, r8
1384         blt     2b
1385
1386         li      r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
1387         bl      trap_reloc
1388
1389         li      r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
1390         bl      trap_reloc
1391
1392         li      r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
1393         li      r8, SystemCall - _start + EXC_OFF_SYS_RESET
1394 3:
1395         bl      trap_reloc
1396         addi    r7, r7, 0x100           /* next exception vector        */
1397         cmplw   0, r7, r8
1398         blt     3b
1399
1400         li      r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
1401         li      r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
1402 4:
1403         bl      trap_reloc
1404         addi    r7, r7, 0x100           /* next exception vector        */
1405         cmplw   0, r7, r8
1406         blt     4b
1407
1408 #if !defined(CONFIG_440_GX)
1409         addi    r7,r0,0x1000            /* set ME bit (Machine Exceptions) */
1410         oris    r7,r7,0x0002            /* set CE bit (Critical Exceptions) */
1411         mtmsr   r7                      /* change MSR */
1412 #else
1413         bl      __440gx_msr_set
1414         b       __440gx_msr_continue
1415
1416 __440gx_msr_set:
1417         addi    r7,r0,0x1000            /* set ME bit (Machine Exceptions) */
1418         oris    r7,r7,0x0002            /* set CE bit (Critical Exceptions) */
1419         mtspr   srr1,r7
1420         mflr    r7
1421         mtspr   srr0,r7
1422         rfi
1423 __440gx_msr_continue:
1424 #endif
1425
1426         mtlr    r4                      /* restore link register        */
1427         blr
1428
1429         /*
1430          * Function: relocate entries for one exception vector
1431          */
1432 trap_reloc:
1433         lwz     r0, 0(r7)               /* hdlr ...                     */
1434         add     r0, r0, r3              /*  ... += dest_addr            */
1435         stw     r0, 0(r7)
1436
1437         lwz     r0, 4(r7)               /* int_return ...               */
1438         add     r0, r0, r3              /*  ... += dest_addr            */
1439         stw     r0, 4(r7)
1440
1441         blr
1442
1443
1444 /**************************************************************************/
1445 /* PPC405EP specific stuff                                                */
1446 /**************************************************************************/
1447 #ifdef CONFIG_405EP
1448 ppc405ep_init:
1449
1450 #ifdef CONFIG_BUBINGA
1451         /*
1452          * Initialize EBC chip selects 1 & 4 and GPIO pins (for alternate
1453          * function) to support FPGA and NVRAM accesses below.
1454          */
1455
1456         lis     r3,GPIO0_OSRH@h         /* config GPIO output select */
1457         ori     r3,r3,GPIO0_OSRH@l
1458         lis     r4,CFG_GPIO0_OSRH@h
1459         ori     r4,r4,CFG_GPIO0_OSRH@l
1460         stw     r4,0(r3)
1461         lis     r3,GPIO0_OSRL@h
1462         ori     r3,r3,GPIO0_OSRL@l
1463         lis     r4,CFG_GPIO0_OSRL@h
1464         ori     r4,r4,CFG_GPIO0_OSRL@l
1465         stw     r4,0(r3)
1466
1467         lis     r3,GPIO0_ISR1H@h        /* config GPIO input select */
1468         ori     r3,r3,GPIO0_ISR1H@l
1469         lis     r4,CFG_GPIO0_ISR1H@h
1470         ori     r4,r4,CFG_GPIO0_ISR1H@l
1471         stw     r4,0(r3)
1472         lis     r3,GPIO0_ISR1L@h
1473         ori     r3,r3,GPIO0_ISR1L@l
1474         lis     r4,CFG_GPIO0_ISR1L@h
1475         ori     r4,r4,CFG_GPIO0_ISR1L@l
1476         stw     r4,0(r3)
1477
1478         lis     r3,GPIO0_TSRH@h         /* config GPIO three-state select */
1479         ori     r3,r3,GPIO0_TSRH@l
1480         lis     r4,CFG_GPIO0_TSRH@h
1481         ori     r4,r4,CFG_GPIO0_TSRH@l
1482         stw     r4,0(r3)
1483         lis     r3,GPIO0_TSRL@h
1484         ori     r3,r3,GPIO0_TSRL@l
1485         lis     r4,CFG_GPIO0_TSRL@h
1486         ori     r4,r4,CFG_GPIO0_TSRL@l
1487         stw     r4,0(r3)
1488
1489         lis     r3,GPIO0_TCR@h          /* config GPIO driver output enables */
1490         ori     r3,r3,GPIO0_TCR@l
1491         lis     r4,CFG_GPIO0_TCR@h
1492         ori     r4,r4,CFG_GPIO0_TCR@l
1493         stw     r4,0(r3)
1494
1495         li      r3,pb1ap                /* program EBC bank 1 for RTC access */
1496         mtdcr   ebccfga,r3
1497         lis     r3,CFG_EBC_PB1AP@h
1498         ori     r3,r3,CFG_EBC_PB1AP@l
1499         mtdcr   ebccfgd,r3
1500         li      r3,pb1cr
1501         mtdcr   ebccfga,r3
1502         lis     r3,CFG_EBC_PB1CR@h
1503         ori     r3,r3,CFG_EBC_PB1CR@l
1504         mtdcr   ebccfgd,r3
1505
1506         li      r3,pb1ap                /* program EBC bank 1 for RTC access */
1507         mtdcr   ebccfga,r3
1508         lis     r3,CFG_EBC_PB1AP@h
1509         ori     r3,r3,CFG_EBC_PB1AP@l
1510         mtdcr   ebccfgd,r3
1511         li      r3,pb1cr
1512         mtdcr   ebccfga,r3
1513         lis     r3,CFG_EBC_PB1CR@h
1514         ori     r3,r3,CFG_EBC_PB1CR@l
1515         mtdcr   ebccfgd,r3
1516
1517         li      r3,pb4ap                /* program EBC bank 4 for FPGA access */
1518         mtdcr   ebccfga,r3
1519         lis     r3,CFG_EBC_PB4AP@h
1520         ori     r3,r3,CFG_EBC_PB4AP@l
1521         mtdcr   ebccfgd,r3
1522         li      r3,pb4cr
1523         mtdcr   ebccfga,r3
1524         lis     r3,CFG_EBC_PB4CR@h
1525         ori     r3,r3,CFG_EBC_PB4CR@l
1526         mtdcr   ebccfgd,r3
1527 #endif
1528
1529         addi    r3,0,CPC0_PCI_HOST_CFG_EN
1530 #ifdef CONFIG_BUBINGA
1531         /*
1532         !-----------------------------------------------------------------------
1533         ! Check FPGA for PCI internal/external arbitration
1534         !   If board is set to internal arbitration, update cpc0_pci
1535         !-----------------------------------------------------------------------
1536         */
1537         addis   r5,r0,FPGA_REG1@h      /* set offset for FPGA_REG1 */
1538         ori     r5,r5,FPGA_REG1@l
1539         lbz     r5,0x0(r5)              /* read to get PCI arb selection */
1540         andi.   r6,r5,FPGA_REG1_PCI_INT_ARB  /* using internal arbiter ?*/
1541         beq     ..pci_cfg_set             /* if not set, then bypass reg write*/
1542 #endif
1543         ori     r3,r3,CPC0_PCI_ARBIT_EN
1544 ..pci_cfg_set:
1545         mtdcr   CPC0_PCI, r3             /* Enable internal arbiter*/
1546
1547         /*
1548         !-----------------------------------------------------------------------
1549         ! Check to see if chip is in bypass mode.
1550         ! If so, write stored CPC0_PLLMR0 and CPC0_PLLMR1 values and perform a
1551         ! CPU reset   Otherwise, skip this step and keep going.
1552         ! Note:  Running BIOS in bypass mode is not supported since PLB speed
1553         !        will not be fast enough for the SDRAM (min 66MHz)
1554         !-----------------------------------------------------------------------
1555         */
1556         mfdcr   r5, CPC0_PLLMR1
1557         rlwinm  r4,r5,1,0x1            /* get system clock source (SSCS) */
1558         cmpi    cr0,0,r4,0x1
1559
1560         beq    pll_done                   /* if SSCS =b'1' then PLL has */
1561                                           /* already been set */
1562                                           /* and CPU has been reset */
1563                                           /* so skip to next section */
1564
1565 #ifdef CONFIG_BUBINGA
1566         /*
1567         !-----------------------------------------------------------------------
1568         ! Read NVRAM to get value to write in PLLMR.
1569         ! If value has not been correctly saved, write default value
1570         ! Default config values (assuming on-board 33MHz SYS_CLK) are above.
1571         ! See CPU_DEFAULT_200 and CPU_DEFAULT_266 above.
1572         !
1573         ! WARNING:  This code assumes the first three words in the nvram_t
1574         !           structure in openbios.h.  Changing the beginning of
1575         !           the structure will break this code.
1576         !
1577         !-----------------------------------------------------------------------
1578         */
1579         addis   r3,0,NVRAM_BASE@h
1580         addi    r3,r3,NVRAM_BASE@l
1581
1582         lwz     r4, 0(r3)
1583         addis   r5,0,NVRVFY1@h
1584         addi    r5,r5,NVRVFY1@l
1585         cmp     cr0,0,r4,r5            /* Compare 1st NVRAM Magic number*/
1586         bne     ..no_pllset
1587         addi    r3,r3,4
1588         lwz     r4, 0(r3)
1589         addis   r5,0,NVRVFY2@h
1590         addi    r5,r5,NVRVFY2@l
1591         cmp     cr0,0,r4,r5            /* Compare 2 NVRAM Magic number */
1592         bne     ..no_pllset
1593         addi    r3,r3,8                 /* Skip over conf_size */
1594         lwz     r4, 4(r3)               /* Load PLLMR1 value from NVRAM */
1595         lwz     r3, 0(r3)               /* Load PLLMR0 value from NVRAM */
1596         rlwinm  r5,r4,1,0x1             /* get system clock source (SSCS) */
1597         cmpi     cr0,0,r5,1             /* See if PLL is locked */
1598         beq     pll_write
1599 ..no_pllset:
1600 #endif /* CONFIG_BUBINGA */
1601
1602         addis   r3,0,PLLMR0_DEFAULT@h       /* PLLMR0 default value */
1603         ori     r3,r3,PLLMR0_DEFAULT@l     /* */
1604         addis   r4,0,PLLMR1_DEFAULT@h       /* PLLMR1 default value */
1605         ori     r4,r4,PLLMR1_DEFAULT@l     /* */
1606
1607         b       pll_write                 /* Write the CPC0_PLLMR with new value */
1608
1609 pll_done:
1610         /*
1611         !-----------------------------------------------------------------------
1612         ! Clear Soft Reset Register
1613         ! This is needed to enable PCI if not booting from serial EPROM
1614         !-----------------------------------------------------------------------
1615                 */
1616         addi    r3, 0, 0x0
1617         mtdcr   CPC0_SRR, r3
1618
1619         addis    r3,0,0x0010
1620         mtctr   r3
1621 pci_wait:
1622         bdnz    pci_wait
1623
1624         blr                               /* return to main code */
1625
1626 /*
1627 !-----------------------------------------------------------------------------
1628 ! Function:     pll_write
1629 ! Description:  Updates the value of the CPC0_PLLMR according to CMOS27E documentation
1630 !               That is:
1631 !                         1.  Pll is first disabled (de-activated by putting in bypass mode)
1632 !                         2.  PLL is reset
1633 !                         3.  Clock dividers are set while PLL is held in reset and bypassed
1634 !                         4.  PLL Reset is cleared
1635 !                         5.  Wait 100us for PLL to lock
1636 !                         6.  A core reset is performed
1637 ! Input: r3 = Value to write to CPC0_PLLMR0
1638 ! Input: r4 = Value to write to CPC0_PLLMR1
1639 ! Output r3 = none
1640 !-----------------------------------------------------------------------------
1641 */
1642 pll_write:
1643         mfdcr  r5, CPC0_UCR
1644         andis. r5,r5,0xFFFF
1645         ori    r5,r5,0x0101              /* Stop the UART clocks */
1646         mtdcr  CPC0_UCR,r5               /* Before changing PLL */
1647
1648         mfdcr  r5, CPC0_PLLMR1
1649         rlwinm r5,r5,0,0x7FFFFFFF        /* Disable PLL */
1650         mtdcr   CPC0_PLLMR1,r5
1651         oris   r5,r5,0x4000              /* Set PLL Reset */
1652         mtdcr   CPC0_PLLMR1,r5
1653
1654         mtdcr   CPC0_PLLMR0,r3           /* Set clock dividers */
1655         rlwinm r5,r4,0,0x3FFFFFFF        /* Reset & Bypass new PLL dividers */
1656         oris   r5,r5,0x4000              /* Set PLL Reset */
1657         mtdcr   CPC0_PLLMR1,r5           /* Set clock dividers */
1658         rlwinm r5,r5,0,0xBFFFFFFF        /* Clear PLL Reset */
1659         mtdcr   CPC0_PLLMR1,r5
1660
1661                 /*
1662         ! Wait min of 100us for PLL to lock.
1663         ! See CMOS 27E databook for more info.
1664         ! At 200MHz, that means waiting 20,000 instructions
1665                  */
1666         addi    r3,0,20000              /* 2000 = 0x4e20 */
1667         mtctr   r3
1668 pll_wait:
1669         bdnz    pll_wait
1670
1671         oris   r5,r5,0x8000             /* Enable PLL */
1672         mtdcr   CPC0_PLLMR1,r5          /* Engage */
1673
1674         /*
1675          * Reset CPU to guarantee timings are OK
1676          * Not sure if this is needed...
1677          */
1678         addis r3,0,0x1000
1679         mtspr dbcr0,r3               /* This will cause a CPU core reset, and */
1680                                      /* execution will continue from the poweron */
1681                                      /* vector of 0xfffffffc */
1682 #endif /* CONFIG_405EP */