blob: aa857d030c87174d31667efb87a934b6bd5ba9fb [file] [log] [blame]
wdenk0442ed82002-11-03 10:24:00 +00001/*
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
wdenk3b57fe02003-05-30 12:48:29 +0000135 GOT_ENTRY(__init_end)
wdenk0442ed82002-11-03 10:24:00 +0000136 GOT_ENTRY(_end)
wdenk5d232d02003-05-22 22:52:13 +0000137 GOT_ENTRY(__bss_start)
wdenk0442ed82002-11-03 10:24:00 +0000138 END_GOT
139
140/*
141 * 440 Startup -- on reset only the top 4k of the effective
142 * address space is mapped in by an entry in the instruction
143 * and data shadow TLB. The .bootpg section is located in the
144 * top 4k & does only what's necessary to map in the the rest
145 * of the boot rom. Once the boot rom is mapped in we can
146 * proceed with normal startup.
147 *
148 * NOTE: CS0 only covers the top 2MB of the effective address
149 * space after reset.
150 */
151
152#if defined(CONFIG_440)
153 .section .bootpg,"ax"
154 .globl _start_440
155
156/**************************************************************************/
157_start_440:
158 /*----------------------------------------------------------------*/
159 /* Clear and set up some registers. */
160 /*----------------------------------------------------------------*/
161 iccci r0,r0 /* NOTE: operands not used for 440 */
162 dccci r0,r0 /* NOTE: operands not used for 440 */
163 sync
164 li r0,0
165 mtspr srr0,r0
166 mtspr srr1,r0
167 mtspr csrr0,r0
168 mtspr csrr1,r0
169
170 /*----------------------------------------------------------------*/
171 /* Initialize debug */
172 /*----------------------------------------------------------------*/
173 mtspr dbcr0,r0
174 mtspr dbcr1,r0
175 mtspr dbcr2,r0
176 mtspr iac1,r0
177 mtspr iac2,r0
178 mtspr iac3,r0
179 mtspr dac1,r0
180 mtspr dac2,r0
181 mtspr dvc1,r0
182 mtspr dvc2,r0
183
184 mfspr r1,dbsr
185 mtspr dbsr,r1 /* Clear all valid bits */
186
187 /*----------------------------------------------------------------*/
188 /* CCR0 init */
189 /*----------------------------------------------------------------*/
190 /* Disable store gathering & broadcast, guarantee inst/data
191 * cache block touch, force load/store alignment
192 * (see errata 1.12: 440_33)
193 */
194 lis r1,0x0030 /* store gathering & broadcast disable */
195 ori r1,r1,0x6000 /* cache touch */
196 mtspr ccr0,r1
197
198 /*----------------------------------------------------------------*/
199 /* Setup interrupt vectors */
200 /*----------------------------------------------------------------*/
201 mtspr ivpr,r0 /* Vectors start at 0x0000_0000 */
202 li r1,0x0100
203 mtspr ivor0,r1 /* Critical input */
204 li r1,0x0200
205 mtspr ivor1,r1 /* Machine check */
206 li r1,0x0300
207 mtspr ivor2,r1 /* Data storage */
208 li r1,0x0400
209 mtspr ivor3,r1 /* Instruction storage */
210 li r1,0x0500
211 mtspr ivor4,r1 /* External interrupt */
212 li r1,0x0600
213 mtspr ivor5,r1 /* Alignment */
214 li r1,0x0700
215 mtspr ivor6,r1 /* Program check */
216 li r1,0x0800
217 mtspr ivor7,r1 /* Floating point unavailable */
218 li r1,0x0c00
219 mtspr ivor8,r1 /* System call */
220 li r1,0x1000
221 mtspr ivor10,r1 /* Decrementer (PIT for 440) */
222 li r1,0x1400
223 mtspr ivor13,r1 /* Data TLB error */
224 li r1,0x1300
225 mtspr ivor14,r1 /* Instr TLB error */
226 li r1,0x2000
227 mtspr ivor15,r1 /* Debug */
228
229 /*----------------------------------------------------------------*/
230 /* Configure cache regions */
231 /*----------------------------------------------------------------*/
232 mtspr inv0,r0
233 mtspr inv1,r0
234 mtspr inv2,r0
235 mtspr inv3,r0
236 mtspr dnv0,r0
237 mtspr dnv1,r0
238 mtspr dnv2,r0
239 mtspr dnv3,r0
240 mtspr itv0,r0
241 mtspr itv1,r0
242 mtspr itv2,r0
243 mtspr itv3,r0
244 mtspr dtv0,r0
245 mtspr dtv1,r0
246 mtspr dtv2,r0
247 mtspr dtv3,r0
248
249 /*----------------------------------------------------------------*/
250 /* Cache victim limits */
251 /*----------------------------------------------------------------*/
252 /* floors 0, ceiling max to use the entire cache -- nothing locked
253 */
254 lis r1,0x0001
255 ori r1,r1,0xf800
256 mtspr ivlim,r1
257 mtspr dvlim,r1
258
259 /*----------------------------------------------------------------*/
260 /* Clear all TLB entries -- TID = 0, TS = 0 */
261 /*----------------------------------------------------------------*/
262 mtspr mmucr,r0
263 li r1,0x003f /* 64 TLB entries */
264 mtctr r1
2650: tlbwe r0,r1,0x0000 /* Invalidate all entries (V=0)*/
266 subi r1,r1,0x0001
267 bdnz 0b
268
269 /*----------------------------------------------------------------*/
270 /* TLB entry setup -- step thru tlbtab */
271 /*----------------------------------------------------------------*/
272 bl tlbtab /* Get tlbtab pointer */
273 mr r5,r0
274 li r1,0x003f /* 64 TLB entries max */
275 mtctr r1
276 li r4,0 /* TLB # */
277
278 addi r5,r5,-4
2791: lwzu r0,4(r5)
280 cmpwi r0,0
281 beq 2f /* 0 marks end */
282 lwzu r1,4(r5)
283 lwzu r2,4(r5)
284 tlbwe r0,r4,0 /* TLB Word 0 */
285 tlbwe r1,r4,1 /* TLB Word 1 */
286 tlbwe r2,r4,2 /* TLB Word 2 */
287 addi r4,r4,1 /* Next TLB */
288 bdnz 1b
289
290 /*----------------------------------------------------------------*/
291 /* Continue from 'normal' start */
292 /*----------------------------------------------------------------*/
2932: bl 3f
294 b _start
295
2963: li r0,0
297 mtspr srr1,r0 /* Keep things disabled for now */
298 mflr r1
299 mtspr srr0,r1
300 rfi
stroeseb867d702003-05-23 11:18:02 +0000301#endif /* CONFIG_440 */
wdenk0442ed82002-11-03 10:24:00 +0000302
303/*
304 * r3 - 1st arg to board_init(): IMMP pointer
305 * r4 - 2nd arg to board_init(): boot flag
306 */
307 .text
308 .long 0x27051956 /* U-Boot Magic Number */
309 .globl version_string
310version_string:
311 .ascii U_BOOT_VERSION
312 .ascii " (", __DATE__, " - ", __TIME__, ")"
313 .ascii CONFIG_IDENT_STRING, "\0"
314
315/*
316 * Maybe this should be moved somewhere else because the current
317 * location (0x100) is where the CriticalInput Execption should be.
318 */
319 . = EXC_OFF_SYS_RESET
320 .globl _start
321_start:
322
323/*****************************************************************************/
324#if defined(CONFIG_440)
325
326 /*----------------------------------------------------------------*/
327 /* Clear and set up some registers. */
328 /*----------------------------------------------------------------*/
329 li r0,0x0000
330 lis r1,0xffff
331 mtspr dec,r0 /* prevent dec exceptions */
332 mtspr tbl,r0 /* prevent fit & wdt exceptions */
333 mtspr tbu,r0
334 mtspr tsr,r1 /* clear all timer exception status */
335 mtspr tcr,r0 /* disable all */
336 mtspr esr,r0 /* clear exception syndrome register */
337 mtxer r0 /* clear integer exception register */
338 lis r1,0x0002 /* set CE bit (Critical Exceptions) */
339 ori r1,r1,0x1000 /* set ME bit (Machine Exceptions) */
340 mtmsr r1 /* change MSR */
341
342 /*----------------------------------------------------------------*/
343 /* Debug setup -- some (not very good) ice's need an event*/
344 /* to establish control :-( Define CFG_INIT_DBCR to the dbsr */
345 /* value you need in this case 0x8cff 0000 should do the trick */
346 /*----------------------------------------------------------------*/
347#if defined(CFG_INIT_DBCR)
348 lis r1,0xffff
349 ori r1,r1,0xffff
350 mtspr dbsr,r1 /* Clear all status bits */
351 lis r0,CFG_INIT_DBCR@h
352 ori r0,r0,CFG_INIT_DBCR@l
353 mtspr dbcr0,r0
354 isync
355#endif
356
357 /*----------------------------------------------------------------*/
358 /* Setup the internal SRAM */
359 /*----------------------------------------------------------------*/
360 li r0,0
361 mtdcr isram0_sb1cr,r0 /* Disable bank 1 */
362
363 li r2,0x7fff
364 ori r2,r2,0xffff
365 mfdcr r1,isram0_dpc
366 and r1,r1,r2 /* Disable parity check */
367 mtdcr isram0_dpc,r1
368 mfdcr r1,isram0_pmeg
369 andis. r1,r1,r2 /* Disable pwr mgmt */
370 mtdcr isram0_pmeg,r1
371
372 lis r1,0x8000 /* BAS = 8000_0000 */
373 ori r1,r1,0x0380 /* 8k rw */
374 mtdcr isram0_sb0cr,r1
375
376 /*----------------------------------------------------------------*/
377 /* Setup the stack in internal SRAM */
378 /*----------------------------------------------------------------*/
379 lis r1,CFG_INIT_RAM_ADDR@h
380 ori r1,r1,CFG_INIT_SP_OFFSET@l
381
382 li r0,0
383 stwu r0,-4(r1)
384 stwu r0,-4(r1) /* Terminate call chain */
385
386 stwu r1,-8(r1) /* Save back chain and move SP */
387 lis r0,RESET_VECTOR@h /* Address of reset vector */
388 ori r0,r0, RESET_VECTOR@l
389 stwu r1,-8(r1) /* Save back chain and move SP */
390 stw r0,+12(r1) /* Save return addr (underflow vect) */
391
392 GET_GOT
393 bl board_init_f
394
395#endif /* CONFIG_440 */
396
397/*****************************************************************************/
398#ifdef CONFIG_IOP480
399 /*----------------------------------------------------------------------- */
400 /* Set up some machine state registers. */
401 /*----------------------------------------------------------------------- */
402 addi r0,r0,0x0000 /* initialize r0 to zero */
403 mtspr esr,r0 /* clear Exception Syndrome Reg */
404 mttcr r0 /* timer control register */
405 mtexier r0 /* disable all interrupts */
406 addi r4,r0,0x1000 /* set ME bit (Machine Exceptions) */
407 oris r4,r4,0x2 /* set CE bit (Critical Exceptions) */
408 mtmsr r4 /* change MSR */
409 addis r4,r0,0xFFFF /* set r4 to 0xFFFFFFFF (status in the */
410 ori r4,r4,0xFFFF /* dbsr is cleared by setting bits to 1) */
411 mtdbsr r4 /* clear/reset the dbsr */
412 mtexisr r4 /* clear all pending interrupts */
413 addis r4,r0,0x8000
414 mtexier r4 /* enable critical exceptions */
415 addis r4,r0,0x0000 /* assume 403GCX - enable core clk */
416 ori r4,r4,0x4020 /* dbling (no harm done on GA and GC */
417 mtiocr r4 /* since bit not used) & DRC to latch */
418 /* data bus on rising edge of CAS */
419 /*----------------------------------------------------------------------- */
420 /* Clear XER. */
421 /*----------------------------------------------------------------------- */
422 mtxer r0
423 /*----------------------------------------------------------------------- */
424 /* Invalidate i-cache and d-cache TAG arrays. */
425 /*----------------------------------------------------------------------- */
426 addi r3,0,1024 /* 1/4 of I-cache size, half of D-cache */
427 addi r4,0,1024 /* 1/4 of I-cache */
428..cloop:
429 iccci 0,r3
430 iccci r4,r3
431 dccci 0,r3
432 addic. r3,r3,-16 /* move back one cache line */
433 bne ..cloop /* loop back to do rest until r3 = 0 */
434
435 /* */
436 /* initialize IOP480 so it can read 1 MB code area for SRAM spaces */
437 /* this requires enabling MA[17..0], by default only MA[12..0] are enabled. */
438 /* */
439
440 /* first copy IOP480 register base address into r3 */
441 addis r3,0,0x5000 /* IOP480 register base address hi */
442/* ori r3,r3,0x0000 / IOP480 register base address lo */
443
444#ifdef CONFIG_ADCIOP
445 /* use r4 as the working variable */
446 /* turn on CS3 (LOCCTL.7) */
447 lwz r4,0x84(r3) /* LOCTL is at offset 0x84 */
448 andi. r4,r4,0xff7f /* make bit 7 = 0 -- CS3 mode */
449 stw r4,0x84(r3) /* LOCTL is at offset 0x84 */
450#endif
451
452#ifdef CONFIG_DASA_SIM
453 /* use r4 as the working variable */
454 /* turn on MA17 (LOCCTL.7) */
455 lwz r4,0x84(r3) /* LOCTL is at offset 0x84 */
456 ori r4,r4,0x80 /* make bit 7 = 1 -- MA17 mode */
457 stw r4,0x84(r3) /* LOCTL is at offset 0x84 */
458#endif
459
460 /* turn on MA16..13 (LCS0BRD.12 = 0) */
461 lwz r4,0x100(r3) /* LCS0BRD is at offset 0x100 */
462 andi. r4,r4,0xefff /* make bit 12 = 0 */
463 stw r4,0x100(r3) /* LCS0BRD is at offset 0x100 */
464
465 /* make sure above stores all comlete before going on */
466 sync
467
468 /* last thing, set local init status done bit (DEVINIT.31) */
469 lwz r4,0x80(r3) /* DEVINIT is at offset 0x80 */
470 oris r4,r4,0x8000 /* make bit 31 = 1 */
471 stw r4,0x80(r3) /* DEVINIT is at offset 0x80 */
472
473 /* clear all pending interrupts and disable all interrupts */
474 li r4,-1 /* set p1 to 0xffffffff */
475 stw r4,0x1b0(r3) /* clear all pending interrupts */
476 stw r4,0x1b8(r3) /* clear all pending interrupts */
477 li r4,0 /* set r4 to 0 */
478 stw r4,0x1b4(r3) /* disable all interrupts */
479 stw r4,0x1bc(r3) /* disable all interrupts */
480
481 /* make sure above stores all comlete before going on */
482 sync
483
484 /*----------------------------------------------------------------------- */
485 /* Enable two 128MB cachable regions. */
486 /*----------------------------------------------------------------------- */
487 addis r1,r0,0x8000
488 addi r1,r1,0x0001
489 mticcr r1 /* instruction cache */
490
491 addis r1,r0,0x0000
492 addi r1,r1,0x0000
493 mtdccr r1 /* data cache */
494
495 addis r1,r0,CFG_INIT_RAM_ADDR@h
496 ori r1,r1,CFG_INIT_SP_OFFSET /* set up the stack to SDRAM */
497 li r0, 0 /* Make room for stack frame header and */
498 stwu r0, -4(r1) /* clear final stack frame so that */
499 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
500
501 GET_GOT /* initialize GOT access */
502
503 bl board_init_f /* run first part of init code (from Flash) */
504
505#endif /* CONFIG_IOP480 */
506
507/*****************************************************************************/
stroeseb867d702003-05-23 11:18:02 +0000508#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_405) || defined(CONFIG_405EP)
wdenk0442ed82002-11-03 10:24:00 +0000509 /*----------------------------------------------------------------------- */
510 /* Clear and set up some registers. */
511 /*----------------------------------------------------------------------- */
512 addi r4,r0,0x0000
513 mtspr sgr,r4
514 mtspr dcwr,r4
515 mtesr r4 /* clear Exception Syndrome Reg */
516 mttcr r4 /* clear Timer Control Reg */
517 mtxer r4 /* clear Fixed-Point Exception Reg */
518 mtevpr r4 /* clear Exception Vector Prefix Reg */
519 addi r4,r0,0x1000 /* set ME bit (Machine Exceptions) */
520 oris r4,r4,0x0002 /* set CE bit (Critical Exceptions) */
521 mtmsr r4 /* change MSR */
522 addi r4,r0,(0xFFFF-0x10000) /* set r4 to 0xFFFFFFFF (status in the */
523 /* dbsr is cleared by setting bits to 1) */
524 mtdbsr r4 /* clear/reset the dbsr */
525
526 /*----------------------------------------------------------------------- */
527 /* Invalidate I and D caches. Enable I cache for defined memory regions */
528 /* to speed things up. Leave the D cache disabled for now. It will be */
529 /* enabled/left disabled later based on user selected menu options. */
530 /* Be aware that the I cache may be disabled later based on the menu */
531 /* options as well. See miscLib/main.c. */
532 /*----------------------------------------------------------------------- */
533 bl invalidate_icache
534 bl invalidate_dcache
535
536 /*----------------------------------------------------------------------- */
537 /* Enable two 128MB cachable regions. */
538 /*----------------------------------------------------------------------- */
539 addis r4,r0,0x8000
540 addi r4,r4,0x0001
541 mticcr r4 /* instruction cache */
542 isync
543
544 addis r4,r0,0x0000
545 addi r4,r4,0x0000
546 mtdccr r4 /* data cache */
547
548#if !(defined(CFG_EBC_PB0AP) && defined(CFG_EBC_PB0CR))
549 /*----------------------------------------------------------------------- */
550 /* Tune the speed and size for flash CS0 */
551 /*----------------------------------------------------------------------- */
552 bl ext_bus_cntlr_init
553#endif
554
stroeseb867d702003-05-23 11:18:02 +0000555#if defined(CONFIG_405EP)
556 /*----------------------------------------------------------------------- */
557 /* DMA Status, clear to come up clean */
558 /*----------------------------------------------------------------------- */
wdenk8bde7f72003-06-27 21:31:46 +0000559 addis r3,r0, 0xFFFF /* Clear all existing DMA status */
560 ori r3,r3, 0xFFFF
561 mtdcr dmasr, r3
stroeseb867d702003-05-23 11:18:02 +0000562
563 bl ppc405ep_init /* do ppc405ep specific init */
564#endif /* CONFIG_405EP */
565
wdenk0442ed82002-11-03 10:24:00 +0000566#if defined(CFG_OCM_DATA_ADDR) && defined(CFG_OCM_DATA_SIZE)
567 /********************************************************************
568 * Setup OCM - On Chip Memory
569 *******************************************************************/
570 /* Setup OCM */
wdenk8bde7f72003-06-27 21:31:46 +0000571 lis r0, 0x7FFF
572 ori r0, r0, 0xFFFF
573 mfdcr r3, ocmiscntl /* get instr-side IRAM config */
574 mfdcr r4, ocmdscntl /* get data-side IRAM config */
575 and r3, r3, r0 /* disable data-side IRAM */
576 and r4, r4, r0 /* disable data-side IRAM */
577 mtdcr ocmiscntl, r3 /* set instr-side IRAM config */
578 mtdcr ocmdscntl, r4 /* set data-side IRAM config */
579 isync
wdenk0442ed82002-11-03 10:24:00 +0000580
581 addis r3, 0, CFG_OCM_DATA_ADDR@h /* OCM location */
582 mtdcr ocmdsarc, r3
583 addis r4, 0, 0xC000 /* OCM data area enabled */
584 mtdcr ocmdscntl, r4
wdenk8bde7f72003-06-27 21:31:46 +0000585 isync
wdenk0442ed82002-11-03 10:24:00 +0000586#endif
587
588 /*----------------------------------------------------------------------- */
589 /* Setup temporary stack in DCACHE or OCM if needed for SDRAM SPD. */
590 /*----------------------------------------------------------------------- */
591#ifdef CFG_INIT_DCACHE_CS
592 /*----------------------------------------------------------------------- */
593 /* Memory Bank x (nothingness) initialization 1GB+64MEG */
594 /* used as temporary stack pointer for stage0 */
595 /*----------------------------------------------------------------------- */
596 li r4,PBxAP
597 mtdcr ebccfga,r4
598 lis r4,0x0380
599 ori r4,r4,0x0480
600 mtdcr ebccfgd,r4
601
602 addi r4,0,PBxCR
603 mtdcr ebccfga,r4
604 lis r4,0x400D
605 ori r4,r4,0xa000
606 mtdcr ebccfgd,r4
607
608 /* turn on data chache for this region */
609 lis r4,0x0080
610 mtdccr r4
611
612 /* set stack pointer and clear stack to known value */
613
614 lis r1,CFG_INIT_RAM_ADDR@h
615 ori r1,r1,CFG_INIT_SP_OFFSET@l
616
617 li r4,2048 /* we store 2048 words to stack */
618 mtctr r4
619
620 lis r2,CFG_INIT_RAM_ADDR@h /* we also clear data area */
621 ori r2,r2,CFG_INIT_RAM_END@l /* so cant copy value from r1 */
622
623 lis r4,0xdead /* we store 0xdeaddead in the stack */
624 ori r4,r4,0xdead
625
626..stackloop:
627 stwu r4,-4(r2)
628 bdnz ..stackloop
629
630 li r0, 0 /* Make room for stack frame header and */
631 stwu r0, -4(r1) /* clear final stack frame so that */
632 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
633 /*
634 * Set up a dummy frame to store reset vector as return address.
635 * this causes stack underflow to reset board.
636 */
637 stwu r1, -8(r1) /* Save back chain and move SP */
638 addis r0, 0, RESET_VECTOR@h /* Address of reset vector */
639 ori r0, r0, RESET_VECTOR@l
640 stwu r1, -8(r1) /* Save back chain and move SP */
641 stw r0, +12(r1) /* Save return addr (underflow vect) */
642
643#elif defined(CFG_TEMP_STACK_OCM) && \
644 (defined(CFG_OCM_DATA_ADDR) && defined(CFG_OCM_DATA_SIZE))
645 /*
646 * Stack in OCM.
647 */
648
649 /* Set up Stack at top of OCM */
650 lis r1, (CFG_INIT_RAM_ADDR + CFG_INIT_SP_OFFSET)@h
651 ori r1, r1, (CFG_INIT_RAM_ADDR + CFG_INIT_SP_OFFSET)@l
652
653 /* Set up a zeroized stack frame so that backtrace works right */
654 li r0, 0
655 stwu r0, -4(r1)
656 stwu r0, -4(r1)
657
658 /*
659 * Set up a dummy frame to store reset vector as return address.
660 * this causes stack underflow to reset board.
661 */
662 stwu r1, -8(r1) /* Save back chain and move SP */
663 lis r0, RESET_VECTOR@h /* Address of reset vector */
664 ori r0, r0, RESET_VECTOR@l
665 stwu r1, -8(r1) /* Save back chain and move SP */
666 stw r0, +12(r1) /* Save return addr (underflow vect) */
667#endif /* CFG_INIT_DCACHE_CS */
668
669 /*----------------------------------------------------------------------- */
670 /* Initialize SDRAM Controller */
671 /*----------------------------------------------------------------------- */
672 bl sdram_init
673
674 /*
675 * Setup temporary stack pointer only for boards
676 * that do not use SDRAM SPD I2C stuff since it
677 * is already initialized to use DCACHE or OCM
678 * stacks.
679 */
680#if !(defined(CFG_INIT_DCACHE_CS) || defined(CFG_TEMP_STACK_OCM))
681 lis r1, CFG_INIT_RAM_ADDR@h
682 ori r1,r1,CFG_INIT_SP_OFFSET /* set up the stack in SDRAM */
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 lis r0, 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#endif /* !(CFG_INIT_DCACHE_CS || !CFG_TEM_STACK_OCM) */
697
698 GET_GOT /* initialize GOT access */
699
wdenk8bde7f72003-06-27 21:31:46 +0000700 bl cpu_init_f /* run low-level CPU init code (from Flash) */
wdenk0442ed82002-11-03 10:24:00 +0000701
702 /* NEVER RETURNS! */
703 bl board_init_f /* run first part of init code (from Flash) */
704
705#endif /* CONFIG_405GP || CONFIG_405CR */
706
707
stroeseb867d702003-05-23 11:18:02 +0000708/*****************************************************************************/
wdenk0442ed82002-11-03 10:24:00 +0000709 .globl _start_of_vectors
710_start_of_vectors:
711
712#if 0
713/*TODO Fixup _start above so we can do this*/
714/* Critical input. */
715 CRIT_EXCEPTION(0x100, CritcalInput, CritcalInputException)
716#endif
717
718/* Machine check */
wdenk2abbe072003-06-16 23:50:08 +0000719 CRIT_EXCEPTION(0x200, MachineCheck, MachineCheckException)
wdenk0442ed82002-11-03 10:24:00 +0000720
721/* Data Storage exception. */
722 STD_EXCEPTION(0x300, DataStorage, UnknownException)
723
724/* Instruction Storage exception. */
725 STD_EXCEPTION(0x400, InstStorage, UnknownException)
726
727/* External Interrupt exception. */
728 STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
729
730/* Alignment exception. */
731 . = 0x600
732Alignment:
733 EXCEPTION_PROLOG
734 mfspr r4,DAR
735 stw r4,_DAR(r21)
736 mfspr r5,DSISR
737 stw r5,_DSISR(r21)
738 addi r3,r1,STACK_FRAME_OVERHEAD
739 li r20,MSR_KERNEL
740 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
741 lwz r6,GOT(transfer_to_handler)
742 mtlr r6
743 blrl
744.L_Alignment:
745 .long AlignmentException - _start + EXC_OFF_SYS_RESET
746 .long int_return - _start + EXC_OFF_SYS_RESET
747
748/* Program check exception */
749 . = 0x700
750ProgramCheck:
751 EXCEPTION_PROLOG
752 addi r3,r1,STACK_FRAME_OVERHEAD
753 li r20,MSR_KERNEL
754 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
755 lwz r6,GOT(transfer_to_handler)
756 mtlr r6
757 blrl
758.L_ProgramCheck:
759 .long ProgramCheckException - _start + EXC_OFF_SYS_RESET
760 .long int_return - _start + EXC_OFF_SYS_RESET
761
762 /* No FPU on MPC8xx. This exception is not supposed to happen.
763 */
764 STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
765
766 /* I guess we could implement decrementer, and may have
767 * to someday for timekeeping.
768 */
769 STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
770 STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
771 STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
772
773 . = 0xc00
774/*
775 * r0 - SYSCALL number
776 * r3-... arguments
777 */
778SystemCall:
779 addis r11,r0,0 /* get functions table addr */
780 ori r11,r11,0 /* Note: this code is patched in trap_init */
781 addis r12,r0,0 /* get number of functions */
782 ori r12,r12,0
783
784 cmplw 0, r0, r12
785 bge 1f
786
787 rlwinm r0,r0,2,0,31 /* fn_addr = fn_tbl[r0] */
788 add r11,r11,r0
789 lwz r11,0(r11)
790
wdenk7c7a23b2002-12-07 00:20:59 +0000791 li r20,0xd00-4 /* Get stack pointer */
792 lwz r12,0(r20)
793 subi r12,r12,12 /* Adjust stack pointer */
794 li r0,0xc00+_end_back-SystemCall
795 cmplw 0, r0, r12 /* Check stack overflow */
796 bgt 1f
797 stw r12,0(r20)
798
wdenk0442ed82002-11-03 10:24:00 +0000799 mflr r0
800 stw r0,0(r12)
801 mfspr r0,SRR0
802 stw r0,4(r12)
803 mfspr r0,SRR1
804 stw r0,8(r12)
805
806 li r12,0xc00+_back-SystemCall
807 mtlr r12
808 mtspr SRR0,r11
809
8101: SYNC
811 rfi
812
813_back:
814
815 mfmsr r11 /* Disable interrupts */
816 li r12,0
817 ori r12,r12,MSR_EE
818 andc r11,r11,r12
819 SYNC /* Some chip revs need this... */
820 mtmsr r11
821 SYNC
822
wdenk7c7a23b2002-12-07 00:20:59 +0000823 li r12,0xd00-4 /* restore regs */
824 lwz r12,0(r12)
825
wdenk0442ed82002-11-03 10:24:00 +0000826 lwz r11,0(r12)
827 mtlr r11
828 lwz r11,4(r12)
829 mtspr SRR0,r11
830 lwz r11,8(r12)
831 mtspr SRR1,r11
832
wdenk7c7a23b2002-12-07 00:20:59 +0000833 addi r12,r12,12 /* Adjust stack pointer */
834 li r20,0xd00-4
835 stw r12,0(r20)
836
wdenk0442ed82002-11-03 10:24:00 +0000837 SYNC
838 rfi
wdenk7c7a23b2002-12-07 00:20:59 +0000839_end_back:
wdenk0442ed82002-11-03 10:24:00 +0000840
841 STD_EXCEPTION(0xd00, SingleStep, UnknownException)
842
843 STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
844 STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
845
846 /* On the MPC8xx, this is a software emulation interrupt. It occurs
847 * for all unimplemented and illegal instructions.
848 */
849 STD_EXCEPTION(0x1000, PIT, PITException)
850
851 STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException)
852 STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException)
853 STD_EXCEPTION(0x1300, InstructionTLBError, UnknownException)
854 STD_EXCEPTION(0x1400, DataTLBError, UnknownException)
855
856 STD_EXCEPTION(0x1500, Reserved5, UnknownException)
857 STD_EXCEPTION(0x1600, Reserved6, UnknownException)
858 STD_EXCEPTION(0x1700, Reserved7, UnknownException)
859 STD_EXCEPTION(0x1800, Reserved8, UnknownException)
860 STD_EXCEPTION(0x1900, Reserved9, UnknownException)
861 STD_EXCEPTION(0x1a00, ReservedA, UnknownException)
862 STD_EXCEPTION(0x1b00, ReservedB, UnknownException)
863
864 STD_EXCEPTION(0x1c00, DataBreakpoint, UnknownException)
865 STD_EXCEPTION(0x1d00, InstructionBreakpoint, UnknownException)
866 STD_EXCEPTION(0x1e00, PeripheralBreakpoint, UnknownException)
867 STD_EXCEPTION(0x1f00, DevPortBreakpoint, UnknownException)
868
869 CRIT_EXCEPTION(0x2000, DebugBreakpoint, DebugException )
870
871 .globl _end_of_vectors
872_end_of_vectors:
873
874
875 . = 0x2100
876
877/*
878 * This code finishes saving the registers to the exception frame
879 * and jumps to the appropriate handler for the exception.
880 * Register r21 is pointer into trap frame, r1 has new stack pointer.
881 */
882 .globl transfer_to_handler
883transfer_to_handler:
884 stw r22,_NIP(r21)
885 lis r22,MSR_POW@h
886 andc r23,r23,r22
887 stw r23,_MSR(r21)
888 SAVE_GPR(7, r21)
889 SAVE_4GPRS(8, r21)
890 SAVE_8GPRS(12, r21)
891 SAVE_8GPRS(24, r21)
892#if 0
893 andi. r23,r23,MSR_PR
894 mfspr r23,SPRG3 /* if from user, fix up tss.regs */
895 beq 2f
896 addi r24,r1,STACK_FRAME_OVERHEAD
897 stw r24,PT_REGS(r23)
8982: addi r2,r23,-TSS /* set r2 to current */
899 tovirt(r2,r2,r23)
900#endif
901 mflr r23
902 andi. r24,r23,0x3f00 /* get vector offset */
903 stw r24,TRAP(r21)
904 li r22,0
905 stw r22,RESULT(r21)
906 mtspr SPRG2,r22 /* r1 is now kernel sp */
907#if 0
908 addi r24,r2,TASK_STRUCT_SIZE /* check for kernel stack overflow */
909 cmplw 0,r1,r2
910 cmplw 1,r1,r24
911 crand 1,1,4
912 bgt stack_ovf /* if r2 < r1 < r2+TASK_STRUCT_SIZE */
913#endif
914 lwz r24,0(r23) /* virtual address of handler */
915 lwz r23,4(r23) /* where to go when done */
916 mtspr SRR0,r24
917 mtspr SRR1,r20
918 mtlr r23
919 SYNC
920 rfi /* jump to handler, enable MMU */
921
922int_return:
923 mfmsr r28 /* Disable interrupts */
924 li r4,0
925 ori r4,r4,MSR_EE
926 andc r28,r28,r4
927 SYNC /* Some chip revs need this... */
928 mtmsr r28
929 SYNC
930 lwz r2,_CTR(r1)
931 lwz r0,_LINK(r1)
932 mtctr r2
933 mtlr r0
934 lwz r2,_XER(r1)
935 lwz r0,_CCR(r1)
936 mtspr XER,r2
937 mtcrf 0xFF,r0
938 REST_10GPRS(3, r1)
939 REST_10GPRS(13, r1)
940 REST_8GPRS(23, r1)
941 REST_GPR(31, r1)
942 lwz r2,_NIP(r1) /* Restore environment */
943 lwz r0,_MSR(r1)
944 mtspr SRR0,r2
945 mtspr SRR1,r0
946 lwz r0,GPR0(r1)
947 lwz r2,GPR2(r1)
948 lwz r1,GPR1(r1)
949 SYNC
950 rfi
951
952crit_return:
953 mfmsr r28 /* Disable interrupts */
954 li r4,0
955 ori r4,r4,MSR_EE
956 andc r28,r28,r4
957 SYNC /* Some chip revs need this... */
958 mtmsr r28
959 SYNC
960 lwz r2,_CTR(r1)
961 lwz r0,_LINK(r1)
962 mtctr r2
963 mtlr r0
964 lwz r2,_XER(r1)
965 lwz r0,_CCR(r1)
966 mtspr XER,r2
967 mtcrf 0xFF,r0
968 REST_10GPRS(3, r1)
969 REST_10GPRS(13, r1)
970 REST_8GPRS(23, r1)
971 REST_GPR(31, r1)
972 lwz r2,_NIP(r1) /* Restore environment */
973 lwz r0,_MSR(r1)
974 mtspr 990,r2 /* SRR2 */
975 mtspr 991,r0 /* SRR3 */
976 lwz r0,GPR0(r1)
977 lwz r2,GPR2(r1)
978 lwz r1,GPR1(r1)
979 SYNC
980 rfci
981
982/* Cache functions.
983*/
984invalidate_icache:
985 iccci r0,r0 /* for 405, iccci invalidates the */
986 blr /* entire I cache */
987
988invalidate_dcache:
989 addi r6,0,0x0000 /* clear GPR 6 */
990 /* Do loop for # of dcache congruence classes. */
991 addi r7,r0, (CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)
992 /* NOTE: dccci invalidates both */
993 mtctr r7 /* ways in the D cache */
994..dcloop:
995 dccci 0,r6 /* invalidate line */
996 addi r6,r6, CFG_CACHELINE_SIZE /* bump to next line */
997 bdnz ..dcloop
998 blr
999
1000flush_dcache:
1001 addis r9,r0,0x0002 /* set mask for EE and CE msr bits */
1002 ori r9,r9,0x8000
1003 mfmsr r12 /* save msr */
1004 andc r9,r12,r9
1005 mtmsr r9 /* disable EE and CE */
1006 addi r10,r0,0x0001 /* enable data cache for unused memory */
1007 mfdccr r9 /* region 0xF8000000-0xFFFFFFFF via */
1008 or r10,r10,r9 /* bit 31 in dccr */
1009 mtdccr r10
1010
1011 /* do loop for # of congruence classes. */
1012 addi r10,r0,(CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)
1013 addi r11,r0,(CFG_DCACHE_SIZE / 2) /* D cache set size - 2 way sets */
1014 mtctr r10
1015 addi r10,r0,(0xE000-0x10000) /* start at 0xFFFFE000 */
1016 add r11,r10,r11 /* add to get to other side of cache line */
1017..flush_dcache_loop:
1018 lwz r3,0(r10) /* least recently used side */
1019 lwz r3,0(r11) /* the other side */
1020 dccci r0,r11 /* invalidate both sides */
1021 addi r10,r10,CFG_CACHELINE_SIZE /* bump to next line */
1022 addi r11,r11,CFG_CACHELINE_SIZE /* bump to next line */
1023 bdnz ..flush_dcache_loop
1024 sync /* allow memory access to complete */
1025 mtdccr r9 /* restore dccr */
1026 mtmsr r12 /* restore msr */
1027 blr
1028
1029 .globl icache_enable
1030icache_enable:
1031 mflr r8
1032 bl invalidate_icache
1033 mtlr r8
1034 isync
1035 addis r3,r0, 0x8000 /* set bit 0 */
1036 mticcr r3
1037 blr
1038
1039 .globl icache_disable
1040icache_disable:
1041 addis r3,r0, 0x0000 /* clear bit 0 */
1042 mticcr r3
1043 isync
1044 blr
1045
1046 .globl icache_status
1047icache_status:
1048 mficcr r3
1049 srwi r3, r3, 31 /* >>31 => select bit 0 */
1050 blr
1051
1052 .globl dcache_enable
1053dcache_enable:
1054 mflr r8
1055 bl invalidate_dcache
1056 mtlr r8
1057 isync
1058 addis r3,r0, 0x8000 /* set bit 0 */
1059 mtdccr r3
1060 blr
1061
1062 .globl dcache_disable
1063dcache_disable:
1064 mflr r8
1065 bl flush_dcache
1066 mtlr r8
1067 addis r3,r0, 0x0000 /* clear bit 0 */
1068 mtdccr r3
1069 blr
1070
1071 .globl dcache_status
1072dcache_status:
1073 mfdccr r3
1074 srwi r3, r3, 31 /* >>31 => select bit 0 */
1075 blr
1076
1077 .globl get_pvr
1078get_pvr:
1079 mfspr r3, PVR
1080 blr
1081
1082#if !defined(CONFIG_440)
1083 .globl wr_pit
1084wr_pit:
1085 mtspr pit, r3
1086 blr
1087#endif
1088
1089 .globl wr_tcr
1090wr_tcr:
1091 mtspr tcr, r3
1092 blr
1093
1094/*------------------------------------------------------------------------------- */
1095/* Function: in8 */
1096/* Description: Input 8 bits */
1097/*------------------------------------------------------------------------------- */
1098 .globl in8
1099in8:
1100 lbz r3,0x0000(r3)
1101 blr
1102
1103/*------------------------------------------------------------------------------- */
1104/* Function: out8 */
1105/* Description: Output 8 bits */
1106/*------------------------------------------------------------------------------- */
1107 .globl out8
1108out8:
1109 stb r4,0x0000(r3)
1110 blr
1111
1112/*------------------------------------------------------------------------------- */
1113/* Function: out16 */
1114/* Description: Output 16 bits */
1115/*------------------------------------------------------------------------------- */
1116 .globl out16
1117out16:
1118 sth r4,0x0000(r3)
1119 blr
1120
1121/*------------------------------------------------------------------------------- */
1122/* Function: out16r */
1123/* Description: Byte reverse and output 16 bits */
1124/*------------------------------------------------------------------------------- */
1125 .globl out16r
1126out16r:
1127 sthbrx r4,r0,r3
1128 blr
1129
1130/*------------------------------------------------------------------------------- */
1131/* Function: out32 */
1132/* Description: Output 32 bits */
1133/*------------------------------------------------------------------------------- */
1134 .globl out32
1135out32:
1136 stw r4,0x0000(r3)
1137 blr
1138
1139/*------------------------------------------------------------------------------- */
1140/* Function: out32r */
1141/* Description: Byte reverse and output 32 bits */
1142/*------------------------------------------------------------------------------- */
1143 .globl out32r
1144out32r:
1145 stwbrx r4,r0,r3
1146 blr
1147
1148/*------------------------------------------------------------------------------- */
1149/* Function: in16 */
1150/* Description: Input 16 bits */
1151/*------------------------------------------------------------------------------- */
1152 .globl in16
1153in16:
1154 lhz r3,0x0000(r3)
1155 blr
1156
1157/*------------------------------------------------------------------------------- */
1158/* Function: in16r */
1159/* Description: Input 16 bits and byte reverse */
1160/*------------------------------------------------------------------------------- */
1161 .globl in16r
1162in16r:
1163 lhbrx r3,r0,r3
1164 blr
1165
1166/*------------------------------------------------------------------------------- */
1167/* Function: in32 */
1168/* Description: Input 32 bits */
1169/*------------------------------------------------------------------------------- */
1170 .globl in32
1171in32:
1172 lwz 3,0x0000(3)
1173 blr
1174
1175/*------------------------------------------------------------------------------- */
1176/* Function: in32r */
1177/* Description: Input 32 bits and byte reverse */
1178/*------------------------------------------------------------------------------- */
1179 .globl in32r
1180in32r:
1181 lwbrx r3,r0,r3
1182 blr
1183
1184/*------------------------------------------------------------------------------- */
1185/* Function: ppcDcbf */
1186/* Description: Data Cache block flush */
1187/* Input: r3 = effective address */
1188/* Output: none. */
1189/*------------------------------------------------------------------------------- */
1190 .globl ppcDcbf
1191ppcDcbf:
1192 dcbf r0,r3
1193 blr
1194
1195/*------------------------------------------------------------------------------- */
1196/* Function: ppcDcbi */
1197/* Description: Data Cache block Invalidate */
1198/* Input: r3 = effective address */
1199/* Output: none. */
1200/*------------------------------------------------------------------------------- */
1201 .globl ppcDcbi
1202ppcDcbi:
1203 dcbi r0,r3
1204 blr
1205
1206/*------------------------------------------------------------------------------- */
1207/* Function: ppcSync */
1208/* Description: Processor Synchronize */
1209/* Input: none. */
1210/* Output: none. */
1211/*------------------------------------------------------------------------------- */
1212 .globl ppcSync
1213ppcSync:
1214 sync
1215 blr
1216
1217/*------------------------------------------------------------------------------*/
1218
1219/*
1220 * void relocate_code (addr_sp, gd, addr_moni)
1221 *
1222 * This "function" does not return, instead it continues in RAM
1223 * after relocating the monitor code.
1224 *
1225 * r3 = dest
1226 * r4 = src
1227 * r5 = length in bytes
1228 * r6 = cachelinesize
1229 */
1230 .globl relocate_code
1231relocate_code:
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
wdenk3b57fe02003-05-30 12:48:29 +00001239 lwz r5, GOT(__init_end)
1240 sub r5, r5, r4
wdenk0442ed82002-11-03 10:24:00 +00001241 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 */
wdenk5d232d02003-05-22 22:52:13 +00001355 lwz r3,GOT(__bss_start)
wdenk0442ed82002-11-03 10:24:00 +00001356 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
wdenk0442ed82002-11-03 10:24:00 +00001373 /*
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
wdenk682011f2003-06-03 23:54:09 +00001384 li r9, 0x100 /* reset vector always at 0x100 */
wdenk0442ed82002-11-03 10:24:00 +00001385
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
stroeseb867d702003-05-23 11:18:02 +00001447
1448
1449/**************************************************************************/
1450/* PPC405EP specific stuff */
1451/**************************************************************************/
1452#ifdef CONFIG_405EP
1453ppc405ep_init:
wdenk8bde7f72003-06-27 21:31:46 +00001454 /*
1455 !-----------------------------------------------------------------------
1456 ! Check FPGA for PCI internal/external arbitration
1457 ! If board is set to internal arbitration, update cpc0_pci
1458 !-----------------------------------------------------------------------
stroeseb867d702003-05-23 11:18:02 +00001459 */
wdenk8bde7f72003-06-27 21:31:46 +00001460 addi r3,0,CPC0_PCI_HOST_CFG_EN
stroeseb867d702003-05-23 11:18:02 +00001461#ifdef CONFIG_BUBINGA405EP
wdenk8bde7f72003-06-27 21:31:46 +00001462 addis r5,r0,FPGA_REG1@h /* set offset for FPGA_REG1 */
1463 ori r5,r5,FPGA_REG1@l
1464 lbz r5,0x0(r5) /* read to get PCI arb selection */
1465 andi. r6,r5,FPGA_REG1_PCI_INT_ARB /* using internal arbiter ?*/
1466 beq ..pci_cfg_set /* if not set, then bypass reg write*/
stroeseb867d702003-05-23 11:18:02 +00001467#endif
wdenk8bde7f72003-06-27 21:31:46 +00001468 ori r3,r3,CPC0_PCI_ARBIT_EN
stroeseb867d702003-05-23 11:18:02 +00001469..pci_cfg_set:
wdenk8bde7f72003-06-27 21:31:46 +00001470 mtdcr CPC0_PCI, r3 /* Enable internal arbiter*/
stroeseb867d702003-05-23 11:18:02 +00001471
wdenk8bde7f72003-06-27 21:31:46 +00001472 /*
1473 !-----------------------------------------------------------------------
1474 ! Check to see if chip is in bypass mode.
1475 ! If so, write stored CPC0_PLLMR0 and CPC0_PLLMR1 values and perform a
1476 ! CPU reset Otherwise, skip this step and keep going.
1477 ! Note: Running BIOS in bypass mode is not supported since PLB speed
1478 ! will not be fast enough for the SDRAM (min 66MHz)
1479 !-----------------------------------------------------------------------
stroeseb867d702003-05-23 11:18:02 +00001480 */
wdenk8bde7f72003-06-27 21:31:46 +00001481 mfdcr r5, CPC0_PLLMR1
1482 rlwinm r4,r5,1,0x1 /* get system clock source (SSCS) */
1483 cmpi cr0,0,r4,0x1
stroeseb867d702003-05-23 11:18:02 +00001484
wdenk8bde7f72003-06-27 21:31:46 +00001485 beq pll_done /* if SSCS =b'1' then PLL has */
1486 /* already been set */
1487 /* and CPU has been reset */
1488 /* so skip to next section */
stroeseb867d702003-05-23 11:18:02 +00001489
1490#ifdef CONFIG_BUBINGA405EP
1491 /*
wdenk8bde7f72003-06-27 21:31:46 +00001492 !-----------------------------------------------------------------------
1493 ! Read NVRAM to get value to write in PLLMR.
1494 ! If value has not been correctly saved, write default value
1495 ! Default config values (assuming on-board 33MHz SYS_CLK) are above.
1496 ! See CPU_DEFAULT_200 and CPU_DEFAULT_266 above.
1497 !
1498 ! WARNING: This code assumes the first three words in the nvram_t
1499 ! structure in openbios.h. Changing the beginning of
1500 ! the structure will break this code.
1501 !
1502 !-----------------------------------------------------------------------
stroeseb867d702003-05-23 11:18:02 +00001503 */
wdenk8bde7f72003-06-27 21:31:46 +00001504 addis r3,0,NVRAM_BASE@h
1505 addi r3,r3,NVRAM_BASE@l
stroeseb867d702003-05-23 11:18:02 +00001506
wdenk8bde7f72003-06-27 21:31:46 +00001507 lwz r4, 0(r3)
1508 addis r5,0,NVRVFY1@h
1509 addi r5,r5,NVRVFY1@l
1510 cmp cr0,0,r4,r5 /* Compare 1st NVRAM Magic number*/
1511 bne ..no_pllset
1512 addi r3,r3,4
1513 lwz r4, 0(r3)
1514 addis r5,0,NVRVFY2@h
1515 addi r5,r5,NVRVFY2@l
1516 cmp cr0,0,r4,r5 /* Compare 2 NVRAM Magic number */
1517 bne ..no_pllset
1518 addi r3,r3,8 /* Skip over conf_size */
1519 lwz r4, 4(r3) /* Load PLLMR1 value from NVRAM */
1520 lwz r3, 0(r3) /* Load PLLMR0 value from NVRAM */
1521 rlwinm r5,r4,1,0x1 /* get system clock source (SSCS) */
1522 cmpi cr0,0,r5,1 /* See if PLL is locked */
1523 beq pll_write
stroeseb867d702003-05-23 11:18:02 +00001524..no_pllset:
1525#endif /* CONFIG_BUBINGA405EP */
1526
wdenk8bde7f72003-06-27 21:31:46 +00001527 addis r3,0,PLLMR0_DEFAULT@h /* PLLMR0 default value */
1528 ori r3,r3,PLLMR0_DEFAULT@l /* */
1529 addis r4,0,PLLMR1_DEFAULT@h /* PLLMR1 default value */
1530 ori r4,r4,PLLMR1_DEFAULT@l /* */
stroeseb867d702003-05-23 11:18:02 +00001531
wdenk8bde7f72003-06-27 21:31:46 +00001532 b pll_write /* Write the CPC0_PLLMR with new value */
stroeseb867d702003-05-23 11:18:02 +00001533
1534pll_done:
wdenk8bde7f72003-06-27 21:31:46 +00001535 /*
1536 !-----------------------------------------------------------------------
1537 ! Clear Soft Reset Register
1538 ! This is needed to enable PCI if not booting from serial EPROM
1539 !-----------------------------------------------------------------------
stroeseb867d702003-05-23 11:18:02 +00001540 */
wdenk8bde7f72003-06-27 21:31:46 +00001541 addi r3, 0, 0x0
1542 mtdcr CPC0_SRR, r3
stroeseb867d702003-05-23 11:18:02 +00001543
wdenk8bde7f72003-06-27 21:31:46 +00001544 addis r3,0,0x0010
1545 mtctr r3
stroeseb867d702003-05-23 11:18:02 +00001546pci_wait:
wdenk8bde7f72003-06-27 21:31:46 +00001547 bdnz pci_wait
stroeseb867d702003-05-23 11:18:02 +00001548
1549 blr /* return to main code */
1550
1551/*
1552!-----------------------------------------------------------------------------
1553! Function: pll_write
1554! Description: Updates the value of the CPC0_PLLMR according to CMOS27E documentation
1555! That is:
1556! 1. Pll is first disabled (de-activated by putting in bypass mode)
1557! 2. PLL is reset
1558! 3. Clock dividers are set while PLL is held in reset and bypassed
1559! 4. PLL Reset is cleared
1560! 5. Wait 100us for PLL to lock
1561! 6. A core reset is performed
1562! Input: r3 = Value to write to CPC0_PLLMR0
1563! Input: r4 = Value to write to CPC0_PLLMR1
1564! Output r3 = none
1565!-----------------------------------------------------------------------------
1566*/
1567pll_write:
wdenk8bde7f72003-06-27 21:31:46 +00001568 mfdcr r5, CPC0_UCR
1569 andis. r5,r5,0xFFFF
1570 ori r5,r5,0x0101 /* Stop the UART clocks */
1571 mtdcr CPC0_UCR,r5 /* Before changing PLL */
stroeseb867d702003-05-23 11:18:02 +00001572
wdenk8bde7f72003-06-27 21:31:46 +00001573 mfdcr r5, CPC0_PLLMR1
1574 rlwinm r5,r5,0,0x7FFFFFFF /* Disable PLL */
1575 mtdcr CPC0_PLLMR1,r5
1576 oris r5,r5,0x4000 /* Set PLL Reset */
1577 mtdcr CPC0_PLLMR1,r5
stroeseb867d702003-05-23 11:18:02 +00001578
wdenk8bde7f72003-06-27 21:31:46 +00001579 mtdcr CPC0_PLLMR0,r3 /* Set clock dividers */
1580 rlwinm r5,r4,0,0x3FFFFFFF /* Reset & Bypass new PLL dividers */
1581 oris r5,r5,0x4000 /* Set PLL Reset */
1582 mtdcr CPC0_PLLMR1,r5 /* Set clock dividers */
1583 rlwinm r5,r5,0,0xBFFFFFFF /* Clear PLL Reset */
1584 mtdcr CPC0_PLLMR1,r5
stroeseb867d702003-05-23 11:18:02 +00001585
1586 /*
wdenk8bde7f72003-06-27 21:31:46 +00001587 ! Wait min of 100us for PLL to lock.
1588 ! See CMOS 27E databook for more info.
1589 ! At 200MHz, that means waiting 20,000 instructions
stroeseb867d702003-05-23 11:18:02 +00001590 */
wdenk8bde7f72003-06-27 21:31:46 +00001591 addi r3,0,20000 /* 2000 = 0x4e20 */
1592 mtctr r3
stroeseb867d702003-05-23 11:18:02 +00001593pll_wait:
wdenk8bde7f72003-06-27 21:31:46 +00001594 bdnz pll_wait
stroeseb867d702003-05-23 11:18:02 +00001595
wdenk8bde7f72003-06-27 21:31:46 +00001596 oris r5,r5,0x8000 /* Enable PLL */
1597 mtdcr CPC0_PLLMR1,r5 /* Engage */
stroeseb867d702003-05-23 11:18:02 +00001598
wdenk8bde7f72003-06-27 21:31:46 +00001599 /*
1600 * Reset CPU to guarantee timings are OK
1601 * Not sure if this is needed...
1602 */
1603 addis r3,0,0x1000
1604 mtspr dbcr0,r3 /* This will cause a CPU core reset, and */
1605 /* execution will continue from the poweron */
1606 /* vector of 0xfffffffc */
stroeseb867d702003-05-23 11:18:02 +00001607#endif /* CONFIG_405EP */