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