blob: afe8635585cb8f63b48bdc1011c2a2cb497f0a8a [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
135 GOT_ENTRY(_end)
wdenkbf2f8c92003-05-22 22:52:13 +0000136 GOT_ENTRY(__bss_start)
wdenk0442ed82002-11-03 10:24:00 +0000137 END_GOT
138
139/*
140 * 440 Startup -- on reset only the top 4k of the effective
141 * address space is mapped in by an entry in the instruction
142 * and data shadow TLB. The .bootpg section is located in the
143 * top 4k & does only what's necessary to map in the the rest
144 * of the boot rom. Once the boot rom is mapped in we can
145 * proceed with normal startup.
146 *
147 * NOTE: CS0 only covers the top 2MB of the effective address
148 * space after reset.
149 */
150
151#if defined(CONFIG_440)
152 .section .bootpg,"ax"
153 .globl _start_440
154
155/**************************************************************************/
156_start_440:
157 /*----------------------------------------------------------------*/
158 /* Clear and set up some registers. */
159 /*----------------------------------------------------------------*/
160 iccci r0,r0 /* NOTE: operands not used for 440 */
161 dccci r0,r0 /* NOTE: operands not used for 440 */
162 sync
163 li r0,0
164 mtspr srr0,r0
165 mtspr srr1,r0
166 mtspr csrr0,r0
167 mtspr csrr1,r0
168
169 /*----------------------------------------------------------------*/
170 /* Initialize debug */
171 /*----------------------------------------------------------------*/
172 mtspr dbcr0,r0
173 mtspr dbcr1,r0
174 mtspr dbcr2,r0
175 mtspr iac1,r0
176 mtspr iac2,r0
177 mtspr iac3,r0
178 mtspr dac1,r0
179 mtspr dac2,r0
180 mtspr dvc1,r0
181 mtspr dvc2,r0
182
183 mfspr r1,dbsr
184 mtspr dbsr,r1 /* Clear all valid bits */
185
186 /*----------------------------------------------------------------*/
187 /* CCR0 init */
188 /*----------------------------------------------------------------*/
189 /* Disable store gathering & broadcast, guarantee inst/data
190 * cache block touch, force load/store alignment
191 * (see errata 1.12: 440_33)
192 */
193 lis r1,0x0030 /* store gathering & broadcast disable */
194 ori r1,r1,0x6000 /* cache touch */
195 mtspr ccr0,r1
196
197 /*----------------------------------------------------------------*/
198 /* Setup interrupt vectors */
199 /*----------------------------------------------------------------*/
200 mtspr ivpr,r0 /* Vectors start at 0x0000_0000 */
201 li r1,0x0100
202 mtspr ivor0,r1 /* Critical input */
203 li r1,0x0200
204 mtspr ivor1,r1 /* Machine check */
205 li r1,0x0300
206 mtspr ivor2,r1 /* Data storage */
207 li r1,0x0400
208 mtspr ivor3,r1 /* Instruction storage */
209 li r1,0x0500
210 mtspr ivor4,r1 /* External interrupt */
211 li r1,0x0600
212 mtspr ivor5,r1 /* Alignment */
213 li r1,0x0700
214 mtspr ivor6,r1 /* Program check */
215 li r1,0x0800
216 mtspr ivor7,r1 /* Floating point unavailable */
217 li r1,0x0c00
218 mtspr ivor8,r1 /* System call */
219 li r1,0x1000
220 mtspr ivor10,r1 /* Decrementer (PIT for 440) */
221 li r1,0x1400
222 mtspr ivor13,r1 /* Data TLB error */
223 li r1,0x1300
224 mtspr ivor14,r1 /* Instr TLB error */
225 li r1,0x2000
226 mtspr ivor15,r1 /* Debug */
227
228 /*----------------------------------------------------------------*/
229 /* Configure cache regions */
230 /*----------------------------------------------------------------*/
231 mtspr inv0,r0
232 mtspr inv1,r0
233 mtspr inv2,r0
234 mtspr inv3,r0
235 mtspr dnv0,r0
236 mtspr dnv1,r0
237 mtspr dnv2,r0
238 mtspr dnv3,r0
239 mtspr itv0,r0
240 mtspr itv1,r0
241 mtspr itv2,r0
242 mtspr itv3,r0
243 mtspr dtv0,r0
244 mtspr dtv1,r0
245 mtspr dtv2,r0
246 mtspr dtv3,r0
247
248 /*----------------------------------------------------------------*/
249 /* Cache victim limits */
250 /*----------------------------------------------------------------*/
251 /* floors 0, ceiling max to use the entire cache -- nothing locked
252 */
253 lis r1,0x0001
254 ori r1,r1,0xf800
255 mtspr ivlim,r1
256 mtspr dvlim,r1
257
258 /*----------------------------------------------------------------*/
259 /* Clear all TLB entries -- TID = 0, TS = 0 */
260 /*----------------------------------------------------------------*/
261 mtspr mmucr,r0
262 li r1,0x003f /* 64 TLB entries */
263 mtctr r1
2640: tlbwe r0,r1,0x0000 /* Invalidate all entries (V=0)*/
265 subi r1,r1,0x0001
266 bdnz 0b
267
268 /*----------------------------------------------------------------*/
269 /* TLB entry setup -- step thru tlbtab */
270 /*----------------------------------------------------------------*/
271 bl tlbtab /* Get tlbtab pointer */
272 mr r5,r0
273 li r1,0x003f /* 64 TLB entries max */
274 mtctr r1
275 li r4,0 /* TLB # */
276
277 addi r5,r5,-4
2781: lwzu r0,4(r5)
279 cmpwi r0,0
280 beq 2f /* 0 marks end */
281 lwzu r1,4(r5)
282 lwzu r2,4(r5)
283 tlbwe r0,r4,0 /* TLB Word 0 */
284 tlbwe r1,r4,1 /* TLB Word 1 */
285 tlbwe r2,r4,2 /* TLB Word 2 */
286 addi r4,r4,1 /* Next TLB */
287 bdnz 1b
288
289 /*----------------------------------------------------------------*/
290 /* Continue from 'normal' start */
291 /*----------------------------------------------------------------*/
2922: bl 3f
293 b _start
294
2953: li r0,0
296 mtspr srr1,r0 /* Keep things disabled for now */
297 mflr r1
298 mtspr srr0,r1
299 rfi
stroese434979e2003-05-23 11:18:02 +0000300#endif /* CONFIG_440 */
wdenk0442ed82002-11-03 10:24:00 +0000301
302/*
303 * r3 - 1st arg to board_init(): IMMP pointer
304 * r4 - 2nd arg to board_init(): boot flag
305 */
306 .text
307 .long 0x27051956 /* U-Boot Magic Number */
308 .globl version_string
309version_string:
310 .ascii U_BOOT_VERSION
311 .ascii " (", __DATE__, " - ", __TIME__, ")"
312 .ascii CONFIG_IDENT_STRING, "\0"
313
314/*
315 * Maybe this should be moved somewhere else because the current
316 * location (0x100) is where the CriticalInput Execption should be.
317 */
318 . = EXC_OFF_SYS_RESET
319 .globl _start
320_start:
321
322/*****************************************************************************/
323#if defined(CONFIG_440)
324
325 /*----------------------------------------------------------------*/
326 /* Clear and set up some registers. */
327 /*----------------------------------------------------------------*/
328 li r0,0x0000
329 lis r1,0xffff
330 mtspr dec,r0 /* prevent dec exceptions */
331 mtspr tbl,r0 /* prevent fit & wdt exceptions */
332 mtspr tbu,r0
333 mtspr tsr,r1 /* clear all timer exception status */
334 mtspr tcr,r0 /* disable all */
335 mtspr esr,r0 /* clear exception syndrome register */
336 mtxer r0 /* clear integer exception register */
337 lis r1,0x0002 /* set CE bit (Critical Exceptions) */
338 ori r1,r1,0x1000 /* set ME bit (Machine Exceptions) */
339 mtmsr r1 /* change MSR */
340
341 /*----------------------------------------------------------------*/
342 /* Debug setup -- some (not very good) ice's need an event*/
343 /* to establish control :-( Define CFG_INIT_DBCR to the dbsr */
344 /* value you need in this case 0x8cff 0000 should do the trick */
345 /*----------------------------------------------------------------*/
346#if defined(CFG_INIT_DBCR)
347 lis r1,0xffff
348 ori r1,r1,0xffff
349 mtspr dbsr,r1 /* Clear all status bits */
350 lis r0,CFG_INIT_DBCR@h
351 ori r0,r0,CFG_INIT_DBCR@l
352 mtspr dbcr0,r0
353 isync
354#endif
355
356 /*----------------------------------------------------------------*/
357 /* Setup the internal SRAM */
358 /*----------------------------------------------------------------*/
359 li r0,0
360 mtdcr isram0_sb1cr,r0 /* Disable bank 1 */
361
362 li r2,0x7fff
363 ori r2,r2,0xffff
364 mfdcr r1,isram0_dpc
365 and r1,r1,r2 /* Disable parity check */
366 mtdcr isram0_dpc,r1
367 mfdcr r1,isram0_pmeg
368 andis. r1,r1,r2 /* Disable pwr mgmt */
369 mtdcr isram0_pmeg,r1
370
371 lis r1,0x8000 /* BAS = 8000_0000 */
372 ori r1,r1,0x0380 /* 8k rw */
373 mtdcr isram0_sb0cr,r1
374
375 /*----------------------------------------------------------------*/
376 /* Setup the stack in internal SRAM */
377 /*----------------------------------------------------------------*/
378 lis r1,CFG_INIT_RAM_ADDR@h
379 ori r1,r1,CFG_INIT_SP_OFFSET@l
380
381 li r0,0
382 stwu r0,-4(r1)
383 stwu r0,-4(r1) /* Terminate call chain */
384
385 stwu r1,-8(r1) /* Save back chain and move SP */
386 lis r0,RESET_VECTOR@h /* Address of reset vector */
387 ori r0,r0, RESET_VECTOR@l
388 stwu r1,-8(r1) /* Save back chain and move SP */
389 stw r0,+12(r1) /* Save return addr (underflow vect) */
390
391 GET_GOT
392 bl board_init_f
393
394#endif /* CONFIG_440 */
395
396/*****************************************************************************/
397#ifdef CONFIG_IOP480
398 /*----------------------------------------------------------------------- */
399 /* Set up some machine state registers. */
400 /*----------------------------------------------------------------------- */
401 addi r0,r0,0x0000 /* initialize r0 to zero */
402 mtspr esr,r0 /* clear Exception Syndrome Reg */
403 mttcr r0 /* timer control register */
404 mtexier r0 /* disable all interrupts */
405 addi r4,r0,0x1000 /* set ME bit (Machine Exceptions) */
406 oris r4,r4,0x2 /* set CE bit (Critical Exceptions) */
407 mtmsr r4 /* change MSR */
408 addis r4,r0,0xFFFF /* set r4 to 0xFFFFFFFF (status in the */
409 ori r4,r4,0xFFFF /* dbsr is cleared by setting bits to 1) */
410 mtdbsr r4 /* clear/reset the dbsr */
411 mtexisr r4 /* clear all pending interrupts */
412 addis r4,r0,0x8000
413 mtexier r4 /* enable critical exceptions */
414 addis r4,r0,0x0000 /* assume 403GCX - enable core clk */
415 ori r4,r4,0x4020 /* dbling (no harm done on GA and GC */
416 mtiocr r4 /* since bit not used) & DRC to latch */
417 /* data bus on rising edge of CAS */
418 /*----------------------------------------------------------------------- */
419 /* Clear XER. */
420 /*----------------------------------------------------------------------- */
421 mtxer r0
422 /*----------------------------------------------------------------------- */
423 /* Invalidate i-cache and d-cache TAG arrays. */
424 /*----------------------------------------------------------------------- */
425 addi r3,0,1024 /* 1/4 of I-cache size, half of D-cache */
426 addi r4,0,1024 /* 1/4 of I-cache */
427..cloop:
428 iccci 0,r3
429 iccci r4,r3
430 dccci 0,r3
431 addic. r3,r3,-16 /* move back one cache line */
432 bne ..cloop /* loop back to do rest until r3 = 0 */
433
434 /* */
435 /* initialize IOP480 so it can read 1 MB code area for SRAM spaces */
436 /* this requires enabling MA[17..0], by default only MA[12..0] are enabled. */
437 /* */
438
439 /* first copy IOP480 register base address into r3 */
440 addis r3,0,0x5000 /* IOP480 register base address hi */
441/* ori r3,r3,0x0000 / IOP480 register base address lo */
442
443#ifdef CONFIG_ADCIOP
444 /* use r4 as the working variable */
445 /* turn on CS3 (LOCCTL.7) */
446 lwz r4,0x84(r3) /* LOCTL is at offset 0x84 */
447 andi. r4,r4,0xff7f /* make bit 7 = 0 -- CS3 mode */
448 stw r4,0x84(r3) /* LOCTL is at offset 0x84 */
449#endif
450
451#ifdef CONFIG_DASA_SIM
452 /* use r4 as the working variable */
453 /* turn on MA17 (LOCCTL.7) */
454 lwz r4,0x84(r3) /* LOCTL is at offset 0x84 */
455 ori r4,r4,0x80 /* make bit 7 = 1 -- MA17 mode */
456 stw r4,0x84(r3) /* LOCTL is at offset 0x84 */
457#endif
458
459 /* turn on MA16..13 (LCS0BRD.12 = 0) */
460 lwz r4,0x100(r3) /* LCS0BRD is at offset 0x100 */
461 andi. r4,r4,0xefff /* make bit 12 = 0 */
462 stw r4,0x100(r3) /* LCS0BRD is at offset 0x100 */
463
464 /* make sure above stores all comlete before going on */
465 sync
466
467 /* last thing, set local init status done bit (DEVINIT.31) */
468 lwz r4,0x80(r3) /* DEVINIT is at offset 0x80 */
469 oris r4,r4,0x8000 /* make bit 31 = 1 */
470 stw r4,0x80(r3) /* DEVINIT is at offset 0x80 */
471
472 /* clear all pending interrupts and disable all interrupts */
473 li r4,-1 /* set p1 to 0xffffffff */
474 stw r4,0x1b0(r3) /* clear all pending interrupts */
475 stw r4,0x1b8(r3) /* clear all pending interrupts */
476 li r4,0 /* set r4 to 0 */
477 stw r4,0x1b4(r3) /* disable all interrupts */
478 stw r4,0x1bc(r3) /* disable all interrupts */
479
480 /* make sure above stores all comlete before going on */
481 sync
482
483 /*----------------------------------------------------------------------- */
484 /* Enable two 128MB cachable regions. */
485 /*----------------------------------------------------------------------- */
486 addis r1,r0,0x8000
487 addi r1,r1,0x0001
488 mticcr r1 /* instruction cache */
489
490 addis r1,r0,0x0000
491 addi r1,r1,0x0000
492 mtdccr r1 /* data cache */
493
494 addis r1,r0,CFG_INIT_RAM_ADDR@h
495 ori r1,r1,CFG_INIT_SP_OFFSET /* set up the stack to SDRAM */
496 li r0, 0 /* Make room for stack frame header and */
497 stwu r0, -4(r1) /* clear final stack frame so that */
498 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
499
500 GET_GOT /* initialize GOT access */
501
502 bl board_init_f /* run first part of init code (from Flash) */
503
504#endif /* CONFIG_IOP480 */
505
506/*****************************************************************************/
stroese434979e2003-05-23 11:18:02 +0000507#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_405) || defined(CONFIG_405EP)
wdenk0442ed82002-11-03 10:24:00 +0000508 /*----------------------------------------------------------------------- */
509 /* Clear and set up some registers. */
510 /*----------------------------------------------------------------------- */
511 addi r4,r0,0x0000
512 mtspr sgr,r4
513 mtspr dcwr,r4
514 mtesr r4 /* clear Exception Syndrome Reg */
515 mttcr r4 /* clear Timer Control Reg */
516 mtxer r4 /* clear Fixed-Point Exception Reg */
517 mtevpr r4 /* clear Exception Vector Prefix Reg */
518 addi r4,r0,0x1000 /* set ME bit (Machine Exceptions) */
519 oris r4,r4,0x0002 /* set CE bit (Critical Exceptions) */
520 mtmsr r4 /* change MSR */
521 addi r4,r0,(0xFFFF-0x10000) /* set r4 to 0xFFFFFFFF (status in the */
522 /* dbsr is cleared by setting bits to 1) */
523 mtdbsr r4 /* clear/reset the dbsr */
524
525 /*----------------------------------------------------------------------- */
526 /* Invalidate I and D caches. Enable I cache for defined memory regions */
527 /* to speed things up. Leave the D cache disabled for now. It will be */
528 /* enabled/left disabled later based on user selected menu options. */
529 /* Be aware that the I cache may be disabled later based on the menu */
530 /* options as well. See miscLib/main.c. */
531 /*----------------------------------------------------------------------- */
532 bl invalidate_icache
533 bl invalidate_dcache
534
535 /*----------------------------------------------------------------------- */
536 /* Enable two 128MB cachable regions. */
537 /*----------------------------------------------------------------------- */
538 addis r4,r0,0x8000
539 addi r4,r4,0x0001
540 mticcr r4 /* instruction cache */
541 isync
542
543 addis r4,r0,0x0000
544 addi r4,r4,0x0000
545 mtdccr r4 /* data cache */
546
547#if !(defined(CFG_EBC_PB0AP) && defined(CFG_EBC_PB0CR))
548 /*----------------------------------------------------------------------- */
549 /* Tune the speed and size for flash CS0 */
550 /*----------------------------------------------------------------------- */
551 bl ext_bus_cntlr_init
552#endif
553
stroese434979e2003-05-23 11:18:02 +0000554#if defined(CONFIG_405EP)
555 /*----------------------------------------------------------------------- */
556 /* DMA Status, clear to come up clean */
557 /*----------------------------------------------------------------------- */
558 addis r3,r0, 0xFFFF /* Clear all existing DMA status */
559 ori r3,r3, 0xFFFF
560 mtdcr dmasr, r3
561
562 bl ppc405ep_init /* do ppc405ep specific init */
563#endif /* CONFIG_405EP */
564
wdenk0442ed82002-11-03 10:24:00 +0000565#if defined(CFG_OCM_DATA_ADDR) && defined(CFG_OCM_DATA_SIZE)
566 /********************************************************************
567 * Setup OCM - On Chip Memory
568 *******************************************************************/
569 /* Setup OCM */
570 lis r0, 0x7FFF
571 ori r0, r0, 0xFFFF
572 mfdcr r3, ocmiscntl /* get instr-side IRAM config */
573 mfdcr r4, ocmdscntl /* get data-side IRAM config */
574 and r3, r3, r0 /* disable data-side IRAM */
575 and r4, r4, r0 /* disable data-side IRAM */
576 mtdcr ocmiscntl, r3 /* set instr-side IRAM config */
577 mtdcr ocmdscntl, r4 /* set data-side IRAM config */
578 isync
579
580 addis r3, 0, CFG_OCM_DATA_ADDR@h /* OCM location */
581 mtdcr ocmdsarc, r3
582 addis r4, 0, 0xC000 /* OCM data area enabled */
583 mtdcr ocmdscntl, r4
584 isync
585#endif
586
587 /*----------------------------------------------------------------------- */
588 /* Setup temporary stack in DCACHE or OCM if needed for SDRAM SPD. */
589 /*----------------------------------------------------------------------- */
590#ifdef CFG_INIT_DCACHE_CS
591 /*----------------------------------------------------------------------- */
592 /* Memory Bank x (nothingness) initialization 1GB+64MEG */
593 /* used as temporary stack pointer for stage0 */
594 /*----------------------------------------------------------------------- */
595 li r4,PBxAP
596 mtdcr ebccfga,r4
597 lis r4,0x0380
598 ori r4,r4,0x0480
599 mtdcr ebccfgd,r4
600
601 addi r4,0,PBxCR
602 mtdcr ebccfga,r4
603 lis r4,0x400D
604 ori r4,r4,0xa000
605 mtdcr ebccfgd,r4
606
607 /* turn on data chache for this region */
608 lis r4,0x0080
609 mtdccr r4
610
611 /* set stack pointer and clear stack to known value */
612
613 lis r1,CFG_INIT_RAM_ADDR@h
614 ori r1,r1,CFG_INIT_SP_OFFSET@l
615
616 li r4,2048 /* we store 2048 words to stack */
617 mtctr r4
618
619 lis r2,CFG_INIT_RAM_ADDR@h /* we also clear data area */
620 ori r2,r2,CFG_INIT_RAM_END@l /* so cant copy value from r1 */
621
622 lis r4,0xdead /* we store 0xdeaddead in the stack */
623 ori r4,r4,0xdead
624
625..stackloop:
626 stwu r4,-4(r2)
627 bdnz ..stackloop
628
629 li r0, 0 /* Make room for stack frame header and */
630 stwu r0, -4(r1) /* clear final stack frame so that */
631 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
632 /*
633 * Set up a dummy frame to store reset vector as return address.
634 * this causes stack underflow to reset board.
635 */
636 stwu r1, -8(r1) /* Save back chain and move SP */
637 addis r0, 0, RESET_VECTOR@h /* Address of reset vector */
638 ori r0, r0, RESET_VECTOR@l
639 stwu r1, -8(r1) /* Save back chain and move SP */
640 stw r0, +12(r1) /* Save return addr (underflow vect) */
641
642#elif defined(CFG_TEMP_STACK_OCM) && \
643 (defined(CFG_OCM_DATA_ADDR) && defined(CFG_OCM_DATA_SIZE))
644 /*
645 * Stack in OCM.
646 */
647
648 /* Set up Stack at top of OCM */
649 lis r1, (CFG_INIT_RAM_ADDR + CFG_INIT_SP_OFFSET)@h
650 ori r1, r1, (CFG_INIT_RAM_ADDR + CFG_INIT_SP_OFFSET)@l
651
652 /* Set up a zeroized stack frame so that backtrace works right */
653 li r0, 0
654 stwu r0, -4(r1)
655 stwu r0, -4(r1)
656
657 /*
658 * Set up a dummy frame to store reset vector as return address.
659 * this causes stack underflow to reset board.
660 */
661 stwu r1, -8(r1) /* Save back chain and move SP */
662 lis r0, RESET_VECTOR@h /* Address of reset vector */
663 ori r0, r0, RESET_VECTOR@l
664 stwu r1, -8(r1) /* Save back chain and move SP */
665 stw r0, +12(r1) /* Save return addr (underflow vect) */
666#endif /* CFG_INIT_DCACHE_CS */
667
668 /*----------------------------------------------------------------------- */
669 /* Initialize SDRAM Controller */
670 /*----------------------------------------------------------------------- */
671 bl sdram_init
672
673 /*
674 * Setup temporary stack pointer only for boards
675 * that do not use SDRAM SPD I2C stuff since it
676 * is already initialized to use DCACHE or OCM
677 * stacks.
678 */
679#if !(defined(CFG_INIT_DCACHE_CS) || defined(CFG_TEMP_STACK_OCM))
680 lis r1, CFG_INIT_RAM_ADDR@h
681 ori r1,r1,CFG_INIT_SP_OFFSET /* set up the stack in SDRAM */
682
683 li r0, 0 /* Make room for stack frame header and */
684 stwu r0, -4(r1) /* clear final stack frame so that */
685 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
686 /*
687 * Set up a dummy frame to store reset vector as return address.
688 * this causes stack underflow to reset board.
689 */
690 stwu r1, -8(r1) /* Save back chain and move SP */
691 lis r0, RESET_VECTOR@h /* Address of reset vector */
692 ori r0, r0, RESET_VECTOR@l
693 stwu r1, -8(r1) /* Save back chain and move SP */
694 stw r0, +12(r1) /* Save return addr (underflow vect) */
695#endif /* !(CFG_INIT_DCACHE_CS || !CFG_TEM_STACK_OCM) */
696
697 GET_GOT /* initialize GOT access */
698
699 bl cpu_init_f /* run low-level CPU init code (from Flash) */
700
701 /* NEVER RETURNS! */
702 bl board_init_f /* run first part of init code (from Flash) */
703
704#endif /* CONFIG_405GP || CONFIG_405CR */
705
706
stroese434979e2003-05-23 11:18:02 +0000707/*****************************************************************************/
wdenk0442ed82002-11-03 10:24:00 +0000708 .globl _start_of_vectors
709_start_of_vectors:
710
711#if 0
712/*TODO Fixup _start above so we can do this*/
713/* Critical input. */
714 CRIT_EXCEPTION(0x100, CritcalInput, CritcalInputException)
715#endif
716
717/* Machine check */
718 STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)
719
720/* Data Storage exception. */
721 STD_EXCEPTION(0x300, DataStorage, UnknownException)
722
723/* Instruction Storage exception. */
724 STD_EXCEPTION(0x400, InstStorage, UnknownException)
725
726/* External Interrupt exception. */
727 STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
728
729/* Alignment exception. */
730 . = 0x600
731Alignment:
732 EXCEPTION_PROLOG
733 mfspr r4,DAR
734 stw r4,_DAR(r21)
735 mfspr r5,DSISR
736 stw r5,_DSISR(r21)
737 addi r3,r1,STACK_FRAME_OVERHEAD
738 li r20,MSR_KERNEL
739 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
740 lwz r6,GOT(transfer_to_handler)
741 mtlr r6
742 blrl
743.L_Alignment:
744 .long AlignmentException - _start + EXC_OFF_SYS_RESET
745 .long int_return - _start + EXC_OFF_SYS_RESET
746
747/* Program check exception */
748 . = 0x700
749ProgramCheck:
750 EXCEPTION_PROLOG
751 addi r3,r1,STACK_FRAME_OVERHEAD
752 li r20,MSR_KERNEL
753 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
754 lwz r6,GOT(transfer_to_handler)
755 mtlr r6
756 blrl
757.L_ProgramCheck:
758 .long ProgramCheckException - _start + EXC_OFF_SYS_RESET
759 .long int_return - _start + EXC_OFF_SYS_RESET
760
761 /* No FPU on MPC8xx. This exception is not supposed to happen.
762 */
763 STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
764
765 /* I guess we could implement decrementer, and may have
766 * to someday for timekeeping.
767 */
768 STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
769 STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
770 STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
771
772 . = 0xc00
773/*
774 * r0 - SYSCALL number
775 * r3-... arguments
776 */
777SystemCall:
778 addis r11,r0,0 /* get functions table addr */
779 ori r11,r11,0 /* Note: this code is patched in trap_init */
780 addis r12,r0,0 /* get number of functions */
781 ori r12,r12,0
782
783 cmplw 0, r0, r12
784 bge 1f
785
786 rlwinm r0,r0,2,0,31 /* fn_addr = fn_tbl[r0] */
787 add r11,r11,r0
788 lwz r11,0(r11)
789
wdenkbb444c92002-12-07 00:20:59 +0000790 li r20,0xd00-4 /* Get stack pointer */
791 lwz r12,0(r20)
792 subi r12,r12,12 /* Adjust stack pointer */
793 li r0,0xc00+_end_back-SystemCall
794 cmplw 0, r0, r12 /* Check stack overflow */
795 bgt 1f
796 stw r12,0(r20)
797
wdenk0442ed82002-11-03 10:24:00 +0000798 mflr r0
799 stw r0,0(r12)
800 mfspr r0,SRR0
801 stw r0,4(r12)
802 mfspr r0,SRR1
803 stw r0,8(r12)
804
805 li r12,0xc00+_back-SystemCall
806 mtlr r12
807 mtspr SRR0,r11
808
8091: SYNC
810 rfi
811
812_back:
813
814 mfmsr r11 /* Disable interrupts */
815 li r12,0
816 ori r12,r12,MSR_EE
817 andc r11,r11,r12
818 SYNC /* Some chip revs need this... */
819 mtmsr r11
820 SYNC
821
wdenkbb444c92002-12-07 00:20:59 +0000822 li r12,0xd00-4 /* restore regs */
823 lwz r12,0(r12)
824
wdenk0442ed82002-11-03 10:24:00 +0000825 lwz r11,0(r12)
826 mtlr r11
827 lwz r11,4(r12)
828 mtspr SRR0,r11
829 lwz r11,8(r12)
830 mtspr SRR1,r11
831
wdenkbb444c92002-12-07 00:20:59 +0000832 addi r12,r12,12 /* Adjust stack pointer */
833 li r20,0xd00-4
834 stw r12,0(r20)
835
wdenk0442ed82002-11-03 10:24:00 +0000836 SYNC
837 rfi
wdenkbb444c92002-12-07 00:20:59 +0000838_end_back:
wdenk0442ed82002-11-03 10:24:00 +0000839
840 STD_EXCEPTION(0xd00, SingleStep, UnknownException)
841
842 STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
843 STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
844
845 /* On the MPC8xx, this is a software emulation interrupt. It occurs
846 * for all unimplemented and illegal instructions.
847 */
848 STD_EXCEPTION(0x1000, PIT, PITException)
849
850 STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException)
851 STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException)
852 STD_EXCEPTION(0x1300, InstructionTLBError, UnknownException)
853 STD_EXCEPTION(0x1400, DataTLBError, UnknownException)
854
855 STD_EXCEPTION(0x1500, Reserved5, UnknownException)
856 STD_EXCEPTION(0x1600, Reserved6, UnknownException)
857 STD_EXCEPTION(0x1700, Reserved7, UnknownException)
858 STD_EXCEPTION(0x1800, Reserved8, UnknownException)
859 STD_EXCEPTION(0x1900, Reserved9, UnknownException)
860 STD_EXCEPTION(0x1a00, ReservedA, UnknownException)
861 STD_EXCEPTION(0x1b00, ReservedB, UnknownException)
862
863 STD_EXCEPTION(0x1c00, DataBreakpoint, UnknownException)
864 STD_EXCEPTION(0x1d00, InstructionBreakpoint, UnknownException)
865 STD_EXCEPTION(0x1e00, PeripheralBreakpoint, UnknownException)
866 STD_EXCEPTION(0x1f00, DevPortBreakpoint, UnknownException)
867
868 CRIT_EXCEPTION(0x2000, DebugBreakpoint, DebugException )
869
870 .globl _end_of_vectors
871_end_of_vectors:
872
873
874 . = 0x2100
875
876/*
877 * This code finishes saving the registers to the exception frame
878 * and jumps to the appropriate handler for the exception.
879 * Register r21 is pointer into trap frame, r1 has new stack pointer.
880 */
881 .globl transfer_to_handler
882transfer_to_handler:
883 stw r22,_NIP(r21)
884 lis r22,MSR_POW@h
885 andc r23,r23,r22
886 stw r23,_MSR(r21)
887 SAVE_GPR(7, r21)
888 SAVE_4GPRS(8, r21)
889 SAVE_8GPRS(12, r21)
890 SAVE_8GPRS(24, r21)
891#if 0
892 andi. r23,r23,MSR_PR
893 mfspr r23,SPRG3 /* if from user, fix up tss.regs */
894 beq 2f
895 addi r24,r1,STACK_FRAME_OVERHEAD
896 stw r24,PT_REGS(r23)
8972: addi r2,r23,-TSS /* set r2 to current */
898 tovirt(r2,r2,r23)
899#endif
900 mflr r23
901 andi. r24,r23,0x3f00 /* get vector offset */
902 stw r24,TRAP(r21)
903 li r22,0
904 stw r22,RESULT(r21)
905 mtspr SPRG2,r22 /* r1 is now kernel sp */
906#if 0
907 addi r24,r2,TASK_STRUCT_SIZE /* check for kernel stack overflow */
908 cmplw 0,r1,r2
909 cmplw 1,r1,r24
910 crand 1,1,4
911 bgt stack_ovf /* if r2 < r1 < r2+TASK_STRUCT_SIZE */
912#endif
913 lwz r24,0(r23) /* virtual address of handler */
914 lwz r23,4(r23) /* where to go when done */
915 mtspr SRR0,r24
916 mtspr SRR1,r20
917 mtlr r23
918 SYNC
919 rfi /* jump to handler, enable MMU */
920
921int_return:
922 mfmsr r28 /* Disable interrupts */
923 li r4,0
924 ori r4,r4,MSR_EE
925 andc r28,r28,r4
926 SYNC /* Some chip revs need this... */
927 mtmsr r28
928 SYNC
929 lwz r2,_CTR(r1)
930 lwz r0,_LINK(r1)
931 mtctr r2
932 mtlr r0
933 lwz r2,_XER(r1)
934 lwz r0,_CCR(r1)
935 mtspr XER,r2
936 mtcrf 0xFF,r0
937 REST_10GPRS(3, r1)
938 REST_10GPRS(13, r1)
939 REST_8GPRS(23, r1)
940 REST_GPR(31, r1)
941 lwz r2,_NIP(r1) /* Restore environment */
942 lwz r0,_MSR(r1)
943 mtspr SRR0,r2
944 mtspr SRR1,r0
945 lwz r0,GPR0(r1)
946 lwz r2,GPR2(r1)
947 lwz r1,GPR1(r1)
948 SYNC
949 rfi
950
951crit_return:
952 mfmsr r28 /* Disable interrupts */
953 li r4,0
954 ori r4,r4,MSR_EE
955 andc r28,r28,r4
956 SYNC /* Some chip revs need this... */
957 mtmsr r28
958 SYNC
959 lwz r2,_CTR(r1)
960 lwz r0,_LINK(r1)
961 mtctr r2
962 mtlr r0
963 lwz r2,_XER(r1)
964 lwz r0,_CCR(r1)
965 mtspr XER,r2
966 mtcrf 0xFF,r0
967 REST_10GPRS(3, r1)
968 REST_10GPRS(13, r1)
969 REST_8GPRS(23, r1)
970 REST_GPR(31, r1)
971 lwz r2,_NIP(r1) /* Restore environment */
972 lwz r0,_MSR(r1)
973 mtspr 990,r2 /* SRR2 */
974 mtspr 991,r0 /* SRR3 */
975 lwz r0,GPR0(r1)
976 lwz r2,GPR2(r1)
977 lwz r1,GPR1(r1)
978 SYNC
979 rfci
980
981/* Cache functions.
982*/
983invalidate_icache:
984 iccci r0,r0 /* for 405, iccci invalidates the */
985 blr /* entire I cache */
986
987invalidate_dcache:
988 addi r6,0,0x0000 /* clear GPR 6 */
989 /* Do loop for # of dcache congruence classes. */
990 addi r7,r0, (CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)
991 /* NOTE: dccci invalidates both */
992 mtctr r7 /* ways in the D cache */
993..dcloop:
994 dccci 0,r6 /* invalidate line */
995 addi r6,r6, CFG_CACHELINE_SIZE /* bump to next line */
996 bdnz ..dcloop
997 blr
998
999flush_dcache:
1000 addis r9,r0,0x0002 /* set mask for EE and CE msr bits */
1001 ori r9,r9,0x8000
1002 mfmsr r12 /* save msr */
1003 andc r9,r12,r9
1004 mtmsr r9 /* disable EE and CE */
1005 addi r10,r0,0x0001 /* enable data cache for unused memory */
1006 mfdccr r9 /* region 0xF8000000-0xFFFFFFFF via */
1007 or r10,r10,r9 /* bit 31 in dccr */
1008 mtdccr r10
1009
1010 /* do loop for # of congruence classes. */
1011 addi r10,r0,(CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)
1012 addi r11,r0,(CFG_DCACHE_SIZE / 2) /* D cache set size - 2 way sets */
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:
1231 mr r1, r3 /* Set new stack pointer */
1232 mr r9, r4 /* Save copy of Init Data pointer */
1233 mr r10, r5 /* Save copy of Destination Address */
1234
1235 mr r3, r5 /* Destination Address */
1236 lis r4, CFG_MONITOR_BASE@h /* Source Address */
1237 ori r4, r4, CFG_MONITOR_BASE@l
1238 lis r5, CFG_MONITOR_LEN@h /* Length in Bytes */
1239 ori r5, r5, CFG_MONITOR_LEN@l
1240 li r6, CFG_CACHELINE_SIZE /* Cache Line Size */
1241
1242 /*
1243 * Fix GOT pointer:
1244 *
1245 * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address
1246 *
1247 * Offset:
1248 */
1249 sub r15, r10, r4
1250
1251 /* First our own GOT */
1252 add r14, r14, r15
1253 /* the the one used by the C code */
1254 add r30, r30, r15
1255
1256 /*
1257 * Now relocate code
1258 */
1259
1260 cmplw cr1,r3,r4
1261 addi r0,r5,3
1262 srwi. r0,r0,2
1263 beq cr1,4f /* In place copy is not necessary */
1264 beq 7f /* Protect against 0 count */
1265 mtctr r0
1266 bge cr1,2f
1267
1268 la r8,-4(r4)
1269 la r7,-4(r3)
12701: lwzu r0,4(r8)
1271 stwu r0,4(r7)
1272 bdnz 1b
1273 b 4f
1274
12752: slwi r0,r0,2
1276 add r8,r4,r0
1277 add r7,r3,r0
12783: lwzu r0,-4(r8)
1279 stwu r0,-4(r7)
1280 bdnz 3b
1281
1282/*
1283 * Now flush the cache: note that we must start from a cache aligned
1284 * address. Otherwise we might miss one cache line.
1285 */
12864: cmpwi r6,0
1287 add r5,r3,r5
1288 beq 7f /* Always flush prefetch queue in any case */
1289 subi r0,r6,1
1290 andc r3,r3,r0
1291 mr r4,r3
12925: dcbst 0,r4
1293 add r4,r4,r6
1294 cmplw r4,r5
1295 blt 5b
1296 sync /* Wait for all dcbst to complete on bus */
1297 mr r4,r3
12986: icbi 0,r4
1299 add r4,r4,r6
1300 cmplw r4,r5
1301 blt 6b
13027: sync /* Wait for all icbi to complete on bus */
1303 isync
1304
1305/*
1306 * We are done. Do not return, instead branch to second part of board
1307 * initialization, now running from RAM.
1308 */
1309
1310 addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
1311 mtlr r0
1312 blr /* NEVER RETURNS! */
1313
1314in_ram:
1315
1316 /*
1317 * Relocation Function, r14 point to got2+0x8000
1318 *
1319 * Adjust got2 pointers, no need to check for 0, this code
1320 * already puts a few entries in the table.
1321 */
1322 li r0,__got2_entries@sectoff@l
1323 la r3,GOT(_GOT2_TABLE_)
1324 lwz r11,GOT(_GOT2_TABLE_)
1325 mtctr r0
1326 sub r11,r3,r11
1327 addi r3,r3,-4
13281: lwzu r0,4(r3)
1329 add r0,r0,r11
1330 stw r0,0(r3)
1331 bdnz 1b
1332
1333 /*
1334 * Now adjust the fixups and the pointers to the fixups
1335 * in case we need to move ourselves again.
1336 */
13372: li r0,__fixup_entries@sectoff@l
1338 lwz r3,GOT(_FIXUP_TABLE_)
1339 cmpwi r0,0
1340 mtctr r0
1341 addi r3,r3,-4
1342 beq 4f
13433: lwzu r4,4(r3)
1344 lwzux r0,r4,r11
1345 add r0,r0,r11
1346 stw r10,0(r3)
1347 stw r0,0(r4)
1348 bdnz 3b
13494:
1350clear_bss:
1351 /*
1352 * Now clear BSS segment
1353 */
wdenkbf2f8c92003-05-22 22:52:13 +00001354 lwz r3,GOT(__bss_start)
wdenk0442ed82002-11-03 10:24:00 +00001355 lwz r4,GOT(_end)
1356
1357 cmplw 0, r3, r4
1358 beq 6f
1359
1360 li r0, 0
13615:
1362 stw r0, 0(r3)
1363 addi r3, r3, 4
1364 cmplw 0, r3, r4
1365 bne 5b
13666:
1367
1368 mr r3, r9 /* Init Data pointer */
1369 mr r4, r10 /* Destination Address */
1370 bl board_init_r
1371
1372 /* Problems accessing "end" in C, so do it here */
1373 .globl get_endaddr
1374get_endaddr:
1375 lwz r3,GOT(_end)
1376 blr
1377
1378 /*
1379 * Copy exception vector code to low memory
1380 *
1381 * r3: dest_addr
1382 * r7: source address, r8: end address, r9: target address
1383 */
1384 .globl trap_init
1385trap_init:
1386 lwz r7, GOT(_start)
1387 lwz r8, GOT(_end_of_vectors)
1388
1389 rlwinm r9, r7, 0, 18, 31 /* _start & 0x3FFF */
1390
1391 cmplw 0, r7, r8
1392 bgelr /* return if r7>=r8 - just in case */
1393
1394 mflr r4 /* save link register */
13951:
1396 lwz r0, 0(r7)
1397 stw r0, 0(r9)
1398 addi r7, r7, 4
1399 addi r9, r9, 4
1400 cmplw 0, r7, r8
1401 bne 1b
1402
1403 /*
1404 * relocate `hdlr' and `int_return' entries
1405 */
1406 li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
1407 li r8, Alignment - _start + EXC_OFF_SYS_RESET
14082:
1409 bl trap_reloc
1410 addi r7, r7, 0x100 /* next exception vector */
1411 cmplw 0, r7, r8
1412 blt 2b
1413
1414 li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
1415 bl trap_reloc
1416
1417 li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
1418 bl trap_reloc
1419
1420 li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
1421 li r8, SystemCall - _start + EXC_OFF_SYS_RESET
14223:
1423 bl trap_reloc
1424 addi r7, r7, 0x100 /* next exception vector */
1425 cmplw 0, r7, r8
1426 blt 3b
1427
1428 li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
1429 li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
14304:
1431 bl trap_reloc
1432 addi r7, r7, 0x100 /* next exception vector */
1433 cmplw 0, r7, r8
1434 blt 4b
1435
1436 mtlr r4 /* restore link register */
1437 blr
1438
1439 /*
1440 * Function: relocate entries for one exception vector
1441 */
1442trap_reloc:
1443 lwz r0, 0(r7) /* hdlr ... */
1444 add r0, r0, r3 /* ... += dest_addr */
1445 stw r0, 0(r7)
1446
1447 lwz r0, 4(r7) /* int_return ... */
1448 add r0, r0, r3 /* ... += dest_addr */
1449 stw r0, 4(r7)
1450
1451 blr
stroese434979e2003-05-23 11:18:02 +00001452
1453
1454/**************************************************************************/
1455/* PPC405EP specific stuff */
1456/**************************************************************************/
1457#ifdef CONFIG_405EP
1458ppc405ep_init:
1459 /*
1460 !-----------------------------------------------------------------------
1461 ! Check FPGA for PCI internal/external arbitration
1462 ! If board is set to internal arbitration, update cpc0_pci
1463 !-----------------------------------------------------------------------
1464 */
1465 addi r3,0,CPC0_PCI_HOST_CFG_EN
1466#ifdef CONFIG_BUBINGA405EP
1467 addis r5,r0,FPGA_REG1@h /* set offset for FPGA_REG1 */
1468 ori r5,r5,FPGA_REG1@l
1469 lbz r5,0x0(r5) /* read to get PCI arb selection */
1470 andi. r6,r5,FPGA_REG1_PCI_INT_ARB /* using internal arbiter ?*/
1471 beq ..pci_cfg_set /* if not set, then bypass reg write*/
1472#endif
1473 ori r3,r3,CPC0_PCI_ARBIT_EN
1474..pci_cfg_set:
1475 mtdcr CPC0_PCI, r3 /* Enable internal arbiter*/
1476
1477 /*
1478 !-----------------------------------------------------------------------
1479 ! Check to see if chip is in bypass mode.
1480 ! If so, write stored CPC0_PLLMR0 and CPC0_PLLMR1 values and perform a
1481 ! CPU reset Otherwise, skip this step and keep going.
1482 ! Note: Running BIOS in bypass mode is not supported since PLB speed
1483 ! will not be fast enough for the SDRAM (min 66MHz)
1484 !-----------------------------------------------------------------------
1485 */
1486 mfdcr r5, CPC0_PLLMR1
1487 rlwinm r4,r5,1,0x1 /* get system clock source (SSCS) */
1488 cmpi cr0,0,r4,0x1
1489
1490 beq pll_done /* if SSCS =b'1' then PLL has */
1491 /* already been set */
1492 /* and CPU has been reset */
1493 /* so skip to next section */
1494
1495#ifdef CONFIG_BUBINGA405EP
1496 /*
1497 !-----------------------------------------------------------------------
1498 ! Read NVRAM to get value to write in PLLMR.
1499 ! If value has not been correctly saved, write default value
1500 ! Default config values (assuming on-board 33MHz SYS_CLK) are above.
1501 ! See CPU_DEFAULT_200 and CPU_DEFAULT_266 above.
1502 !
1503 ! WARNING: This code assumes the first three words in the nvram_t
1504 ! structure in openbios.h. Changing the beginning of
1505 ! the structure will break this code.
1506 !
1507 !-----------------------------------------------------------------------
1508 */
1509 addis r3,0,NVRAM_BASE@h
1510 addi r3,r3,NVRAM_BASE@l
1511
1512 lwz r4, 0(r3)
1513 addis r5,0,NVRVFY1@h
1514 addi r5,r5,NVRVFY1@l
1515 cmp cr0,0,r4,r5 /* Compare 1st NVRAM Magic number*/
1516 bne ..no_pllset
1517 addi r3,r3,4
1518 lwz r4, 0(r3)
1519 addis r5,0,NVRVFY2@h
1520 addi r5,r5,NVRVFY2@l
1521 cmp cr0,0,r4,r5 /* Compare 2 NVRAM Magic number */
1522 bne ..no_pllset
1523 addi r3,r3,8 /* Skip over conf_size */
1524 lwz r4, 4(r3) /* Load PLLMR1 value from NVRAM */
1525 lwz r3, 0(r3) /* Load PLLMR0 value from NVRAM */
1526 rlwinm r5,r4,1,0x1 /* get system clock source (SSCS) */
1527 cmpi cr0,0,r5,1 /* See if PLL is locked */
1528 beq pll_write
1529..no_pllset:
1530#endif /* CONFIG_BUBINGA405EP */
1531
1532 addis r3,0,PLLMR0_DEFAULT@h /* PLLMR0 default value */
1533 ori r3,r3,PLLMR0_DEFAULT@l /* */
1534 addis r4,0,PLLMR1_DEFAULT@h /* PLLMR1 default value */
1535 ori r4,r4,PLLMR1_DEFAULT@l /* */
1536
1537 b pll_write /* Write the CPC0_PLLMR with new value */
1538
1539pll_done:
1540 /*
1541 !-----------------------------------------------------------------------
1542 ! Clear Soft Reset Register
1543 ! This is needed to enable PCI if not booting from serial EPROM
1544 !-----------------------------------------------------------------------
1545 */
1546 addi r3, 0, 0x0
1547 mtdcr CPC0_SRR, r3
1548
1549 addis r3,0,0x0010
1550 mtctr r3
1551pci_wait:
1552 bdnz pci_wait
1553
1554 blr /* return to main code */
1555
1556/*
1557!-----------------------------------------------------------------------------
1558! Function: pll_write
1559! Description: Updates the value of the CPC0_PLLMR according to CMOS27E documentation
1560! That is:
1561! 1. Pll is first disabled (de-activated by putting in bypass mode)
1562! 2. PLL is reset
1563! 3. Clock dividers are set while PLL is held in reset and bypassed
1564! 4. PLL Reset is cleared
1565! 5. Wait 100us for PLL to lock
1566! 6. A core reset is performed
1567! Input: r3 = Value to write to CPC0_PLLMR0
1568! Input: r4 = Value to write to CPC0_PLLMR1
1569! Output r3 = none
1570!-----------------------------------------------------------------------------
1571*/
1572pll_write:
1573 mfdcr r5, CPC0_UCR
1574 andis. r5,r5,0xFFFF
1575 ori r5,r5,0x0101 /* Stop the UART clocks */
1576 mtdcr CPC0_UCR,r5 /* Before changing PLL */
1577
1578 mfdcr r5, CPC0_PLLMR1
1579 rlwinm r5,r5,0,0x7FFFFFFF /* Disable PLL */
1580 mtdcr CPC0_PLLMR1,r5
1581 oris r5,r5,0x4000 /* Set PLL Reset */
1582 mtdcr CPC0_PLLMR1,r5
1583
1584 mtdcr CPC0_PLLMR0,r3 /* Set clock dividers */
1585 rlwinm r5,r4,0,0x3FFFFFFF /* Reset & Bypass new PLL dividers */
1586 oris r5,r5,0x4000 /* Set PLL Reset */
1587 mtdcr CPC0_PLLMR1,r5 /* Set clock dividers */
1588 rlwinm r5,r5,0,0xBFFFFFFF /* Clear PLL Reset */
1589 mtdcr CPC0_PLLMR1,r5
1590
1591 /*
1592 ! Wait min of 100us for PLL to lock.
1593 ! See CMOS 27E databook for more info.
1594 ! At 200MHz, that means waiting 20,000 instructions
1595 */
1596 addi r3,0,20000 /* 2000 = 0x4e20 */
1597 mtctr r3
1598pll_wait:
1599 bdnz pll_wait
1600
1601 oris r5,r5,0x8000 /* Enable PLL */
1602 mtdcr CPC0_PLLMR1,r5 /* Engage */
1603
1604 /*
1605 * Reset CPU to guarantee timings are OK
1606 * Not sure if this is needed...
1607 */
1608 addis r3,0,0x1000
1609 mtspr dbcr0,r3 /* This will cause a CPU core reset, and */
1610 /* execution will continue from the poweron */
1611 /* vector of 0xfffffffc */
1612#endif /* CONFIG_405EP */