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