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