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