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