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