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