blob: c40a8dba8b160c506f64148cfc05993005072ee9 [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)
136 GOT_ENTRY(.bss)
137 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
300#endif
301
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/*****************************************************************************/
507#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_405)
508 /*----------------------------------------------------------------------- */
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
554#if defined(CFG_OCM_DATA_ADDR) && defined(CFG_OCM_DATA_SIZE)
555 /********************************************************************
556 * Setup OCM - On Chip Memory
557 *******************************************************************/
558 /* Setup OCM */
559 lis r0, 0x7FFF
560 ori r0, r0, 0xFFFF
561 mfdcr r3, ocmiscntl /* get instr-side IRAM config */
562 mfdcr r4, ocmdscntl /* get data-side IRAM config */
563 and r3, r3, r0 /* disable data-side IRAM */
564 and r4, r4, r0 /* disable data-side IRAM */
565 mtdcr ocmiscntl, r3 /* set instr-side IRAM config */
566 mtdcr ocmdscntl, r4 /* set data-side IRAM config */
567 isync
568
569 addis r3, 0, CFG_OCM_DATA_ADDR@h /* OCM location */
570 mtdcr ocmdsarc, r3
571 addis r4, 0, 0xC000 /* OCM data area enabled */
572 mtdcr ocmdscntl, r4
573 isync
574#endif
575
576 /*----------------------------------------------------------------------- */
577 /* Setup temporary stack in DCACHE or OCM if needed for SDRAM SPD. */
578 /*----------------------------------------------------------------------- */
579#ifdef CFG_INIT_DCACHE_CS
580 /*----------------------------------------------------------------------- */
581 /* Memory Bank x (nothingness) initialization 1GB+64MEG */
582 /* used as temporary stack pointer for stage0 */
583 /*----------------------------------------------------------------------- */
584 li r4,PBxAP
585 mtdcr ebccfga,r4
586 lis r4,0x0380
587 ori r4,r4,0x0480
588 mtdcr ebccfgd,r4
589
590 addi r4,0,PBxCR
591 mtdcr ebccfga,r4
592 lis r4,0x400D
593 ori r4,r4,0xa000
594 mtdcr ebccfgd,r4
595
596 /* turn on data chache for this region */
597 lis r4,0x0080
598 mtdccr r4
599
600 /* set stack pointer and clear stack to known value */
601
602 lis r1,CFG_INIT_RAM_ADDR@h
603 ori r1,r1,CFG_INIT_SP_OFFSET@l
604
605 li r4,2048 /* we store 2048 words to stack */
606 mtctr r4
607
608 lis r2,CFG_INIT_RAM_ADDR@h /* we also clear data area */
609 ori r2,r2,CFG_INIT_RAM_END@l /* so cant copy value from r1 */
610
611 lis r4,0xdead /* we store 0xdeaddead in the stack */
612 ori r4,r4,0xdead
613
614..stackloop:
615 stwu r4,-4(r2)
616 bdnz ..stackloop
617
618 li r0, 0 /* Make room for stack frame header and */
619 stwu r0, -4(r1) /* clear final stack frame so that */
620 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
621 /*
622 * Set up a dummy frame to store reset vector as return address.
623 * this causes stack underflow to reset board.
624 */
625 stwu r1, -8(r1) /* Save back chain and move SP */
626 addis r0, 0, RESET_VECTOR@h /* Address of reset vector */
627 ori r0, r0, RESET_VECTOR@l
628 stwu r1, -8(r1) /* Save back chain and move SP */
629 stw r0, +12(r1) /* Save return addr (underflow vect) */
630
631#elif defined(CFG_TEMP_STACK_OCM) && \
632 (defined(CFG_OCM_DATA_ADDR) && defined(CFG_OCM_DATA_SIZE))
633 /*
634 * Stack in OCM.
635 */
636
637 /* Set up Stack at top of OCM */
638 lis r1, (CFG_INIT_RAM_ADDR + CFG_INIT_SP_OFFSET)@h
639 ori r1, r1, (CFG_INIT_RAM_ADDR + CFG_INIT_SP_OFFSET)@l
640
641 /* Set up a zeroized stack frame so that backtrace works right */
642 li r0, 0
643 stwu r0, -4(r1)
644 stwu r0, -4(r1)
645
646 /*
647 * Set up a dummy frame to store reset vector as return address.
648 * this causes stack underflow to reset board.
649 */
650 stwu r1, -8(r1) /* Save back chain and move SP */
651 lis r0, RESET_VECTOR@h /* Address of reset vector */
652 ori r0, r0, RESET_VECTOR@l
653 stwu r1, -8(r1) /* Save back chain and move SP */
654 stw r0, +12(r1) /* Save return addr (underflow vect) */
655#endif /* CFG_INIT_DCACHE_CS */
656
657 /*----------------------------------------------------------------------- */
658 /* Initialize SDRAM Controller */
659 /*----------------------------------------------------------------------- */
660 bl sdram_init
661
662 /*
663 * Setup temporary stack pointer only for boards
664 * that do not use SDRAM SPD I2C stuff since it
665 * is already initialized to use DCACHE or OCM
666 * stacks.
667 */
668#if !(defined(CFG_INIT_DCACHE_CS) || defined(CFG_TEMP_STACK_OCM))
669 lis r1, CFG_INIT_RAM_ADDR@h
670 ori r1,r1,CFG_INIT_SP_OFFSET /* set up the stack in SDRAM */
671
672 li r0, 0 /* Make room for stack frame header and */
673 stwu r0, -4(r1) /* clear final stack frame so that */
674 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
675 /*
676 * Set up a dummy frame to store reset vector as return address.
677 * this causes stack underflow to reset board.
678 */
679 stwu r1, -8(r1) /* Save back chain and move SP */
680 lis r0, RESET_VECTOR@h /* Address of reset vector */
681 ori r0, r0, RESET_VECTOR@l
682 stwu r1, -8(r1) /* Save back chain and move SP */
683 stw r0, +12(r1) /* Save return addr (underflow vect) */
684#endif /* !(CFG_INIT_DCACHE_CS || !CFG_TEM_STACK_OCM) */
685
686 GET_GOT /* initialize GOT access */
687
688 bl cpu_init_f /* run low-level CPU init code (from Flash) */
689
690 /* NEVER RETURNS! */
691 bl board_init_f /* run first part of init code (from Flash) */
692
693#endif /* CONFIG_405GP || CONFIG_405CR */
694
695
696 .globl _start_of_vectors
697_start_of_vectors:
698
699#if 0
700/*TODO Fixup _start above so we can do this*/
701/* Critical input. */
702 CRIT_EXCEPTION(0x100, CritcalInput, CritcalInputException)
703#endif
704
705/* Machine check */
706 STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)
707
708/* Data Storage exception. */
709 STD_EXCEPTION(0x300, DataStorage, UnknownException)
710
711/* Instruction Storage exception. */
712 STD_EXCEPTION(0x400, InstStorage, UnknownException)
713
714/* External Interrupt exception. */
715 STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
716
717/* Alignment exception. */
718 . = 0x600
719Alignment:
720 EXCEPTION_PROLOG
721 mfspr r4,DAR
722 stw r4,_DAR(r21)
723 mfspr r5,DSISR
724 stw r5,_DSISR(r21)
725 addi r3,r1,STACK_FRAME_OVERHEAD
726 li r20,MSR_KERNEL
727 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
728 lwz r6,GOT(transfer_to_handler)
729 mtlr r6
730 blrl
731.L_Alignment:
732 .long AlignmentException - _start + EXC_OFF_SYS_RESET
733 .long int_return - _start + EXC_OFF_SYS_RESET
734
735/* Program check exception */
736 . = 0x700
737ProgramCheck:
738 EXCEPTION_PROLOG
739 addi r3,r1,STACK_FRAME_OVERHEAD
740 li r20,MSR_KERNEL
741 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
742 lwz r6,GOT(transfer_to_handler)
743 mtlr r6
744 blrl
745.L_ProgramCheck:
746 .long ProgramCheckException - _start + EXC_OFF_SYS_RESET
747 .long int_return - _start + EXC_OFF_SYS_RESET
748
749 /* No FPU on MPC8xx. This exception is not supposed to happen.
750 */
751 STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
752
753 /* I guess we could implement decrementer, and may have
754 * to someday for timekeeping.
755 */
756 STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
757 STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
758 STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
759
760 . = 0xc00
761/*
762 * r0 - SYSCALL number
763 * r3-... arguments
764 */
765SystemCall:
766 addis r11,r0,0 /* get functions table addr */
767 ori r11,r11,0 /* Note: this code is patched in trap_init */
768 addis r12,r0,0 /* get number of functions */
769 ori r12,r12,0
770
771 cmplw 0, r0, r12
772 bge 1f
773
774 rlwinm r0,r0,2,0,31 /* fn_addr = fn_tbl[r0] */
775 add r11,r11,r0
776 lwz r11,0(r11)
777
wdenk7c7a23b2002-12-07 00:20:59 +0000778 li r20,0xd00-4 /* Get stack pointer */
779 lwz r12,0(r20)
780 subi r12,r12,12 /* Adjust stack pointer */
781 li r0,0xc00+_end_back-SystemCall
782 cmplw 0, r0, r12 /* Check stack overflow */
783 bgt 1f
784 stw r12,0(r20)
785
wdenk0442ed82002-11-03 10:24:00 +0000786 mflr r0
787 stw r0,0(r12)
788 mfspr r0,SRR0
789 stw r0,4(r12)
790 mfspr r0,SRR1
791 stw r0,8(r12)
792
793 li r12,0xc00+_back-SystemCall
794 mtlr r12
795 mtspr SRR0,r11
796
7971: SYNC
798 rfi
799
800_back:
801
802 mfmsr r11 /* Disable interrupts */
803 li r12,0
804 ori r12,r12,MSR_EE
805 andc r11,r11,r12
806 SYNC /* Some chip revs need this... */
807 mtmsr r11
808 SYNC
809
wdenk7c7a23b2002-12-07 00:20:59 +0000810 li r12,0xd00-4 /* restore regs */
811 lwz r12,0(r12)
812
wdenk0442ed82002-11-03 10:24:00 +0000813 lwz r11,0(r12)
814 mtlr r11
815 lwz r11,4(r12)
816 mtspr SRR0,r11
817 lwz r11,8(r12)
818 mtspr SRR1,r11
819
wdenk7c7a23b2002-12-07 00:20:59 +0000820 addi r12,r12,12 /* Adjust stack pointer */
821 li r20,0xd00-4
822 stw r12,0(r20)
823
wdenk0442ed82002-11-03 10:24:00 +0000824 SYNC
825 rfi
wdenk7c7a23b2002-12-07 00:20:59 +0000826_end_back:
wdenk0442ed82002-11-03 10:24:00 +0000827
828 STD_EXCEPTION(0xd00, SingleStep, UnknownException)
829
830 STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
831 STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
832
833 /* On the MPC8xx, this is a software emulation interrupt. It occurs
834 * for all unimplemented and illegal instructions.
835 */
836 STD_EXCEPTION(0x1000, PIT, PITException)
837
838 STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException)
839 STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException)
840 STD_EXCEPTION(0x1300, InstructionTLBError, UnknownException)
841 STD_EXCEPTION(0x1400, DataTLBError, UnknownException)
842
843 STD_EXCEPTION(0x1500, Reserved5, UnknownException)
844 STD_EXCEPTION(0x1600, Reserved6, UnknownException)
845 STD_EXCEPTION(0x1700, Reserved7, UnknownException)
846 STD_EXCEPTION(0x1800, Reserved8, UnknownException)
847 STD_EXCEPTION(0x1900, Reserved9, UnknownException)
848 STD_EXCEPTION(0x1a00, ReservedA, UnknownException)
849 STD_EXCEPTION(0x1b00, ReservedB, UnknownException)
850
851 STD_EXCEPTION(0x1c00, DataBreakpoint, UnknownException)
852 STD_EXCEPTION(0x1d00, InstructionBreakpoint, UnknownException)
853 STD_EXCEPTION(0x1e00, PeripheralBreakpoint, UnknownException)
854 STD_EXCEPTION(0x1f00, DevPortBreakpoint, UnknownException)
855
856 CRIT_EXCEPTION(0x2000, DebugBreakpoint, DebugException )
857
858 .globl _end_of_vectors
859_end_of_vectors:
860
861
862 . = 0x2100
863
864/*
865 * This code finishes saving the registers to the exception frame
866 * and jumps to the appropriate handler for the exception.
867 * Register r21 is pointer into trap frame, r1 has new stack pointer.
868 */
869 .globl transfer_to_handler
870transfer_to_handler:
871 stw r22,_NIP(r21)
872 lis r22,MSR_POW@h
873 andc r23,r23,r22
874 stw r23,_MSR(r21)
875 SAVE_GPR(7, r21)
876 SAVE_4GPRS(8, r21)
877 SAVE_8GPRS(12, r21)
878 SAVE_8GPRS(24, r21)
879#if 0
880 andi. r23,r23,MSR_PR
881 mfspr r23,SPRG3 /* if from user, fix up tss.regs */
882 beq 2f
883 addi r24,r1,STACK_FRAME_OVERHEAD
884 stw r24,PT_REGS(r23)
8852: addi r2,r23,-TSS /* set r2 to current */
886 tovirt(r2,r2,r23)
887#endif
888 mflr r23
889 andi. r24,r23,0x3f00 /* get vector offset */
890 stw r24,TRAP(r21)
891 li r22,0
892 stw r22,RESULT(r21)
893 mtspr SPRG2,r22 /* r1 is now kernel sp */
894#if 0
895 addi r24,r2,TASK_STRUCT_SIZE /* check for kernel stack overflow */
896 cmplw 0,r1,r2
897 cmplw 1,r1,r24
898 crand 1,1,4
899 bgt stack_ovf /* if r2 < r1 < r2+TASK_STRUCT_SIZE */
900#endif
901 lwz r24,0(r23) /* virtual address of handler */
902 lwz r23,4(r23) /* where to go when done */
903 mtspr SRR0,r24
904 mtspr SRR1,r20
905 mtlr r23
906 SYNC
907 rfi /* jump to handler, enable MMU */
908
909int_return:
910 mfmsr r28 /* Disable interrupts */
911 li r4,0
912 ori r4,r4,MSR_EE
913 andc r28,r28,r4
914 SYNC /* Some chip revs need this... */
915 mtmsr r28
916 SYNC
917 lwz r2,_CTR(r1)
918 lwz r0,_LINK(r1)
919 mtctr r2
920 mtlr r0
921 lwz r2,_XER(r1)
922 lwz r0,_CCR(r1)
923 mtspr XER,r2
924 mtcrf 0xFF,r0
925 REST_10GPRS(3, r1)
926 REST_10GPRS(13, r1)
927 REST_8GPRS(23, r1)
928 REST_GPR(31, r1)
929 lwz r2,_NIP(r1) /* Restore environment */
930 lwz r0,_MSR(r1)
931 mtspr SRR0,r2
932 mtspr SRR1,r0
933 lwz r0,GPR0(r1)
934 lwz r2,GPR2(r1)
935 lwz r1,GPR1(r1)
936 SYNC
937 rfi
938
939crit_return:
940 mfmsr r28 /* Disable interrupts */
941 li r4,0
942 ori r4,r4,MSR_EE
943 andc r28,r28,r4
944 SYNC /* Some chip revs need this... */
945 mtmsr r28
946 SYNC
947 lwz r2,_CTR(r1)
948 lwz r0,_LINK(r1)
949 mtctr r2
950 mtlr r0
951 lwz r2,_XER(r1)
952 lwz r0,_CCR(r1)
953 mtspr XER,r2
954 mtcrf 0xFF,r0
955 REST_10GPRS(3, r1)
956 REST_10GPRS(13, r1)
957 REST_8GPRS(23, r1)
958 REST_GPR(31, r1)
959 lwz r2,_NIP(r1) /* Restore environment */
960 lwz r0,_MSR(r1)
961 mtspr 990,r2 /* SRR2 */
962 mtspr 991,r0 /* SRR3 */
963 lwz r0,GPR0(r1)
964 lwz r2,GPR2(r1)
965 lwz r1,GPR1(r1)
966 SYNC
967 rfci
968
969/* Cache functions.
970*/
971invalidate_icache:
972 iccci r0,r0 /* for 405, iccci invalidates the */
973 blr /* entire I cache */
974
975invalidate_dcache:
976 addi r6,0,0x0000 /* clear GPR 6 */
977 /* Do loop for # of dcache congruence classes. */
978 addi r7,r0, (CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)
979 /* NOTE: dccci invalidates both */
980 mtctr r7 /* ways in the D cache */
981..dcloop:
982 dccci 0,r6 /* invalidate line */
983 addi r6,r6, CFG_CACHELINE_SIZE /* bump to next line */
984 bdnz ..dcloop
985 blr
986
987flush_dcache:
988 addis r9,r0,0x0002 /* set mask for EE and CE msr bits */
989 ori r9,r9,0x8000
990 mfmsr r12 /* save msr */
991 andc r9,r12,r9
992 mtmsr r9 /* disable EE and CE */
993 addi r10,r0,0x0001 /* enable data cache for unused memory */
994 mfdccr r9 /* region 0xF8000000-0xFFFFFFFF via */
995 or r10,r10,r9 /* bit 31 in dccr */
996 mtdccr r10
997
998 /* do loop for # of congruence classes. */
999 addi r10,r0,(CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)
1000 addi r11,r0,(CFG_DCACHE_SIZE / 2) /* D cache set size - 2 way sets */
1001 mtctr r10
1002 addi r10,r0,(0xE000-0x10000) /* start at 0xFFFFE000 */
1003 add r11,r10,r11 /* add to get to other side of cache line */
1004..flush_dcache_loop:
1005 lwz r3,0(r10) /* least recently used side */
1006 lwz r3,0(r11) /* the other side */
1007 dccci r0,r11 /* invalidate both sides */
1008 addi r10,r10,CFG_CACHELINE_SIZE /* bump to next line */
1009 addi r11,r11,CFG_CACHELINE_SIZE /* bump to next line */
1010 bdnz ..flush_dcache_loop
1011 sync /* allow memory access to complete */
1012 mtdccr r9 /* restore dccr */
1013 mtmsr r12 /* restore msr */
1014 blr
1015
1016 .globl icache_enable
1017icache_enable:
1018 mflr r8
1019 bl invalidate_icache
1020 mtlr r8
1021 isync
1022 addis r3,r0, 0x8000 /* set bit 0 */
1023 mticcr r3
1024 blr
1025
1026 .globl icache_disable
1027icache_disable:
1028 addis r3,r0, 0x0000 /* clear bit 0 */
1029 mticcr r3
1030 isync
1031 blr
1032
1033 .globl icache_status
1034icache_status:
1035 mficcr r3
1036 srwi r3, r3, 31 /* >>31 => select bit 0 */
1037 blr
1038
1039 .globl dcache_enable
1040dcache_enable:
1041 mflr r8
1042 bl invalidate_dcache
1043 mtlr r8
1044 isync
1045 addis r3,r0, 0x8000 /* set bit 0 */
1046 mtdccr r3
1047 blr
1048
1049 .globl dcache_disable
1050dcache_disable:
1051 mflr r8
1052 bl flush_dcache
1053 mtlr r8
1054 addis r3,r0, 0x0000 /* clear bit 0 */
1055 mtdccr r3
1056 blr
1057
1058 .globl dcache_status
1059dcache_status:
1060 mfdccr r3
1061 srwi r3, r3, 31 /* >>31 => select bit 0 */
1062 blr
1063
1064 .globl get_pvr
1065get_pvr:
1066 mfspr r3, PVR
1067 blr
1068
1069#if !defined(CONFIG_440)
1070 .globl wr_pit
1071wr_pit:
1072 mtspr pit, r3
1073 blr
1074#endif
1075
1076 .globl wr_tcr
1077wr_tcr:
1078 mtspr tcr, r3
1079 blr
1080
1081/*------------------------------------------------------------------------------- */
1082/* Function: in8 */
1083/* Description: Input 8 bits */
1084/*------------------------------------------------------------------------------- */
1085 .globl in8
1086in8:
1087 lbz r3,0x0000(r3)
1088 blr
1089
1090/*------------------------------------------------------------------------------- */
1091/* Function: out8 */
1092/* Description: Output 8 bits */
1093/*------------------------------------------------------------------------------- */
1094 .globl out8
1095out8:
1096 stb r4,0x0000(r3)
1097 blr
1098
1099/*------------------------------------------------------------------------------- */
1100/* Function: out16 */
1101/* Description: Output 16 bits */
1102/*------------------------------------------------------------------------------- */
1103 .globl out16
1104out16:
1105 sth r4,0x0000(r3)
1106 blr
1107
1108/*------------------------------------------------------------------------------- */
1109/* Function: out16r */
1110/* Description: Byte reverse and output 16 bits */
1111/*------------------------------------------------------------------------------- */
1112 .globl out16r
1113out16r:
1114 sthbrx r4,r0,r3
1115 blr
1116
1117/*------------------------------------------------------------------------------- */
1118/* Function: out32 */
1119/* Description: Output 32 bits */
1120/*------------------------------------------------------------------------------- */
1121 .globl out32
1122out32:
1123 stw r4,0x0000(r3)
1124 blr
1125
1126/*------------------------------------------------------------------------------- */
1127/* Function: out32r */
1128/* Description: Byte reverse and output 32 bits */
1129/*------------------------------------------------------------------------------- */
1130 .globl out32r
1131out32r:
1132 stwbrx r4,r0,r3
1133 blr
1134
1135/*------------------------------------------------------------------------------- */
1136/* Function: in16 */
1137/* Description: Input 16 bits */
1138/*------------------------------------------------------------------------------- */
1139 .globl in16
1140in16:
1141 lhz r3,0x0000(r3)
1142 blr
1143
1144/*------------------------------------------------------------------------------- */
1145/* Function: in16r */
1146/* Description: Input 16 bits and byte reverse */
1147/*------------------------------------------------------------------------------- */
1148 .globl in16r
1149in16r:
1150 lhbrx r3,r0,r3
1151 blr
1152
1153/*------------------------------------------------------------------------------- */
1154/* Function: in32 */
1155/* Description: Input 32 bits */
1156/*------------------------------------------------------------------------------- */
1157 .globl in32
1158in32:
1159 lwz 3,0x0000(3)
1160 blr
1161
1162/*------------------------------------------------------------------------------- */
1163/* Function: in32r */
1164/* Description: Input 32 bits and byte reverse */
1165/*------------------------------------------------------------------------------- */
1166 .globl in32r
1167in32r:
1168 lwbrx r3,r0,r3
1169 blr
1170
1171/*------------------------------------------------------------------------------- */
1172/* Function: ppcDcbf */
1173/* Description: Data Cache block flush */
1174/* Input: r3 = effective address */
1175/* Output: none. */
1176/*------------------------------------------------------------------------------- */
1177 .globl ppcDcbf
1178ppcDcbf:
1179 dcbf r0,r3
1180 blr
1181
1182/*------------------------------------------------------------------------------- */
1183/* Function: ppcDcbi */
1184/* Description: Data Cache block Invalidate */
1185/* Input: r3 = effective address */
1186/* Output: none. */
1187/*------------------------------------------------------------------------------- */
1188 .globl ppcDcbi
1189ppcDcbi:
1190 dcbi r0,r3
1191 blr
1192
1193/*------------------------------------------------------------------------------- */
1194/* Function: ppcSync */
1195/* Description: Processor Synchronize */
1196/* Input: none. */
1197/* Output: none. */
1198/*------------------------------------------------------------------------------- */
1199 .globl ppcSync
1200ppcSync:
1201 sync
1202 blr
1203
1204/*------------------------------------------------------------------------------*/
1205
1206/*
1207 * void relocate_code (addr_sp, gd, addr_moni)
1208 *
1209 * This "function" does not return, instead it continues in RAM
1210 * after relocating the monitor code.
1211 *
1212 * r3 = dest
1213 * r4 = src
1214 * r5 = length in bytes
1215 * r6 = cachelinesize
1216 */
1217 .globl relocate_code
1218relocate_code:
1219 mr r1, r3 /* Set new stack pointer */
1220 mr r9, r4 /* Save copy of Init Data pointer */
1221 mr r10, r5 /* Save copy of Destination Address */
1222
1223 mr r3, r5 /* Destination Address */
1224 lis r4, CFG_MONITOR_BASE@h /* Source Address */
1225 ori r4, r4, CFG_MONITOR_BASE@l
1226 lis r5, CFG_MONITOR_LEN@h /* Length in Bytes */
1227 ori r5, r5, CFG_MONITOR_LEN@l
1228 li r6, CFG_CACHELINE_SIZE /* Cache Line Size */
1229
1230 /*
1231 * Fix GOT pointer:
1232 *
1233 * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address
1234 *
1235 * Offset:
1236 */
1237 sub r15, r10, r4
1238
1239 /* First our own GOT */
1240 add r14, r14, r15
1241 /* the the one used by the C code */
1242 add r30, r30, r15
1243
1244 /*
1245 * Now relocate code
1246 */
1247
1248 cmplw cr1,r3,r4
1249 addi r0,r5,3
1250 srwi. r0,r0,2
1251 beq cr1,4f /* In place copy is not necessary */
1252 beq 7f /* Protect against 0 count */
1253 mtctr r0
1254 bge cr1,2f
1255
1256 la r8,-4(r4)
1257 la r7,-4(r3)
12581: lwzu r0,4(r8)
1259 stwu r0,4(r7)
1260 bdnz 1b
1261 b 4f
1262
12632: slwi r0,r0,2
1264 add r8,r4,r0
1265 add r7,r3,r0
12663: lwzu r0,-4(r8)
1267 stwu r0,-4(r7)
1268 bdnz 3b
1269
1270/*
1271 * Now flush the cache: note that we must start from a cache aligned
1272 * address. Otherwise we might miss one cache line.
1273 */
12744: cmpwi r6,0
1275 add r5,r3,r5
1276 beq 7f /* Always flush prefetch queue in any case */
1277 subi r0,r6,1
1278 andc r3,r3,r0
1279 mr r4,r3
12805: dcbst 0,r4
1281 add r4,r4,r6
1282 cmplw r4,r5
1283 blt 5b
1284 sync /* Wait for all dcbst to complete on bus */
1285 mr r4,r3
12866: icbi 0,r4
1287 add r4,r4,r6
1288 cmplw r4,r5
1289 blt 6b
12907: sync /* Wait for all icbi to complete on bus */
1291 isync
1292
1293/*
1294 * We are done. Do not return, instead branch to second part of board
1295 * initialization, now running from RAM.
1296 */
1297
1298 addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
1299 mtlr r0
1300 blr /* NEVER RETURNS! */
1301
1302in_ram:
1303
1304 /*
1305 * Relocation Function, r14 point to got2+0x8000
1306 *
1307 * Adjust got2 pointers, no need to check for 0, this code
1308 * already puts a few entries in the table.
1309 */
1310 li r0,__got2_entries@sectoff@l
1311 la r3,GOT(_GOT2_TABLE_)
1312 lwz r11,GOT(_GOT2_TABLE_)
1313 mtctr r0
1314 sub r11,r3,r11
1315 addi r3,r3,-4
13161: lwzu r0,4(r3)
1317 add r0,r0,r11
1318 stw r0,0(r3)
1319 bdnz 1b
1320
1321 /*
1322 * Now adjust the fixups and the pointers to the fixups
1323 * in case we need to move ourselves again.
1324 */
13252: li r0,__fixup_entries@sectoff@l
1326 lwz r3,GOT(_FIXUP_TABLE_)
1327 cmpwi r0,0
1328 mtctr r0
1329 addi r3,r3,-4
1330 beq 4f
13313: lwzu r4,4(r3)
1332 lwzux r0,r4,r11
1333 add r0,r0,r11
1334 stw r10,0(r3)
1335 stw r0,0(r4)
1336 bdnz 3b
13374:
1338clear_bss:
1339 /*
1340 * Now clear BSS segment
1341 */
1342 lwz r3,GOT(.bss)
1343 lwz r4,GOT(_end)
1344
1345 cmplw 0, r3, r4
1346 beq 6f
1347
1348 li r0, 0
13495:
1350 stw r0, 0(r3)
1351 addi r3, r3, 4
1352 cmplw 0, r3, r4
1353 bne 5b
13546:
1355
1356 mr r3, r9 /* Init Data pointer */
1357 mr r4, r10 /* Destination Address */
1358 bl board_init_r
1359
1360 /* Problems accessing "end" in C, so do it here */
1361 .globl get_endaddr
1362get_endaddr:
1363 lwz r3,GOT(_end)
1364 blr
1365
1366 /*
1367 * Copy exception vector code to low memory
1368 *
1369 * r3: dest_addr
1370 * r7: source address, r8: end address, r9: target address
1371 */
1372 .globl trap_init
1373trap_init:
1374 lwz r7, GOT(_start)
1375 lwz r8, GOT(_end_of_vectors)
1376
1377 rlwinm r9, r7, 0, 18, 31 /* _start & 0x3FFF */
1378
1379 cmplw 0, r7, r8
1380 bgelr /* return if r7>=r8 - just in case */
1381
1382 mflr r4 /* save link register */
13831:
1384 lwz r0, 0(r7)
1385 stw r0, 0(r9)
1386 addi r7, r7, 4
1387 addi r9, r9, 4
1388 cmplw 0, r7, r8
1389 bne 1b
1390
1391 /*
1392 * relocate `hdlr' and `int_return' entries
1393 */
1394 li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
1395 li r8, Alignment - _start + EXC_OFF_SYS_RESET
13962:
1397 bl trap_reloc
1398 addi r7, r7, 0x100 /* next exception vector */
1399 cmplw 0, r7, r8
1400 blt 2b
1401
1402 li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
1403 bl trap_reloc
1404
1405 li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
1406 bl trap_reloc
1407
1408 li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
1409 li r8, SystemCall - _start + EXC_OFF_SYS_RESET
14103:
1411 bl trap_reloc
1412 addi r7, r7, 0x100 /* next exception vector */
1413 cmplw 0, r7, r8
1414 blt 3b
1415
1416 li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
1417 li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
14184:
1419 bl trap_reloc
1420 addi r7, r7, 0x100 /* next exception vector */
1421 cmplw 0, r7, r8
1422 blt 4b
1423
1424 mtlr r4 /* restore link register */
1425 blr
1426
1427 /*
1428 * Function: relocate entries for one exception vector
1429 */
1430trap_reloc:
1431 lwz r0, 0(r7) /* hdlr ... */
1432 add r0, r0, r3 /* ... += dest_addr */
1433 stw r0, 0(r7)
1434
1435 lwz r0, 4(r7) /* int_return ... */
1436 add r0, r0, r3 /* ... += dest_addr */
1437 stw r0, 4(r7)
1438
1439 blr