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