blob: 4a0e7a11191ed1d6ed515467b8c10f6cc1c17e4d [file] [log] [blame]
wdenk47d1a6e2002-11-03 00:01:44 +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 * Copyright (C) 2001 Josh Huber <huber@mclx.com>
6 *
7 * See file CREDITS for list of people who contributed to this
8 * project.
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
23 * MA 02111-1307 USA
24 */
25
26/* U-Boot - Startup Code for PowerPC based Embedded Boards
27 *
28 *
29 * The processor starts at 0xfff00100 and the code is executed
30 * from flash. The code is organized to be at an other address
31 * in memory, but as long we don't jump around before relocating.
32 * board_init lies at a quite high address and when the cpu has
33 * jumped there, everything is ok.
34 */
35#include <config.h>
36#include <74xx_7xx.h>
37#include <version.h>
38
39#include <ppc_asm.tmpl>
40#include <ppc_defs.h>
41
42#include <asm/cache.h>
43#include <asm/mmu.h>
44
45#include <galileo/gt64260R.h>
46
47#ifndef CONFIG_IDENT_STRING
48#define CONFIG_IDENT_STRING ""
49#endif
50
51/* We don't want the MMU yet.
52*/
53#undef MSR_KERNEL
54/* Machine Check and Recoverable Interr. */
55#define MSR_KERNEL ( MSR_ME | MSR_RI )
56
57/*
58 * Set up GOT: Global Offset Table
59 *
60 * Use r14 to access the GOT
61 */
62 START_GOT
63 GOT_ENTRY(_GOT2_TABLE_)
64 GOT_ENTRY(_FIXUP_TABLE_)
65
66 GOT_ENTRY(_start)
67 GOT_ENTRY(_start_of_vectors)
68 GOT_ENTRY(_end_of_vectors)
69 GOT_ENTRY(transfer_to_handler)
70
wdenk3b57fe02003-05-30 12:48:29 +000071 GOT_ENTRY(__init_end)
wdenk47d1a6e2002-11-03 00:01:44 +000072 GOT_ENTRY(_end)
wdenk5d232d02003-05-22 22:52:13 +000073 GOT_ENTRY(__bss_start)
wdenk47d1a6e2002-11-03 00:01:44 +000074 END_GOT
75
76/*
77 * r3 - 1st arg to board_init(): IMMP pointer
78 * r4 - 2nd arg to board_init(): boot flag
79 */
80 .text
81 .long 0x27051956 /* U-Boot Magic Number */
82 .globl version_string
83version_string:
84 .ascii U_BOOT_VERSION
85 .ascii " (", __DATE__, " - ", __TIME__, ")"
86 .ascii CONFIG_IDENT_STRING, "\0"
87
88 . = EXC_OFF_SYS_RESET
89 .globl _start
90_start:
91 li r21, BOOTFLAG_COLD /* Normal Power-On: Boot from FLASH */
92 b boot_cold
93 sync
94
95 . = EXC_OFF_SYS_RESET + 0x10
96
97 .globl _start_warm
98_start_warm:
99 li r21, BOOTFLAG_WARM /* Software reboot */
100 b boot_warm
101 sync
102
103 /* the boot code is located below the exception table */
104
105 .globl _start_of_vectors
106_start_of_vectors:
107
108/* Machine check */
109 STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)
110
111/* Data Storage exception. "Never" generated on the 860. */
112 STD_EXCEPTION(0x300, DataStorage, UnknownException)
113
114/* Instruction Storage exception. "Never" generated on the 860. */
115 STD_EXCEPTION(0x400, InstStorage, UnknownException)
116
117/* External Interrupt exception. */
118 STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
119
120/* Alignment exception. */
121 . = 0x600
122Alignment:
123 EXCEPTION_PROLOG
124 mfspr r4,DAR
125 stw r4,_DAR(r21)
126 mfspr r5,DSISR
127 stw r5,_DSISR(r21)
128 addi r3,r1,STACK_FRAME_OVERHEAD
129 li r20,MSR_KERNEL
130 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
131 lwz r6,GOT(transfer_to_handler)
132 mtlr r6
133 blrl
134.L_Alignment:
135 .long AlignmentException - _start + EXC_OFF_SYS_RESET
136 .long int_return - _start + EXC_OFF_SYS_RESET
137
138/* Program check exception */
139 . = 0x700
140ProgramCheck:
141 EXCEPTION_PROLOG
142 addi r3,r1,STACK_FRAME_OVERHEAD
143 li r20,MSR_KERNEL
144 rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
145 lwz r6,GOT(transfer_to_handler)
146 mtlr r6
147 blrl
148.L_ProgramCheck:
149 .long ProgramCheckException - _start + EXC_OFF_SYS_RESET
150 .long int_return - _start + EXC_OFF_SYS_RESET
151
152 /* No FPU on MPC8xx. This exception is not supposed to happen.
153 */
154 STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
155
156 /* I guess we could implement decrementer, and may have
157 * to someday for timekeeping.
158 */
159 STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
160 STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
161 STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
162
163 . = 0xc00
164/*
165 * r0 - SYSCALL number
166 * r3-... arguments
167 */
168SystemCall:
169 addis r11,r0,0 /* get functions table addr */
170 ori r11,r11,0 /* Note: this code is patched in trap_init */
171 addis r12,r0,0 /* get number of functions */
172 ori r12,r12,0
173
174 cmplw 0, r0, r12
175 bge 1f
176
177 rlwinm r0,r0,2,0,31 /* fn_addr = fn_tbl[r0] */
178 add r11,r11,r0
179 lwz r11,0(r11)
180
wdenk7c7a23b2002-12-07 00:20:59 +0000181 li r20,0xd00-4 /* Get stack pointer */
182 lwz r12,0(r20)
183 subi r12,r12,12 /* Adjust stack pointer */
184 li r0,0xc00+_end_back-SystemCall
185 cmplw 0, r0, r12 /* Check stack overflow */
186 bgt 1f
187 stw r12,0(r20)
188
wdenk47d1a6e2002-11-03 00:01:44 +0000189 mflr r0
190 stw r0,0(r12)
191 mfspr r0,SRR0
192 stw r0,4(r12)
193 mfspr r0,SRR1
194 stw r0,8(r12)
195
196 li r12,0xc00+_back-SystemCall
197 mtlr r12
198 mtspr SRR0,r11
199
2001: SYNC
201 rfi
202
203_back:
204
205 mfmsr r11 /* Disable interrupts */
206 li r12,0
207 ori r12,r12,MSR_EE
208 andc r11,r11,r12
209 SYNC /* Some chip revs need this... */
210 mtmsr r11
211 SYNC
212
wdenk7c7a23b2002-12-07 00:20:59 +0000213 li r12,0xd00-4 /* restore regs */
214 lwz r12,0(r12)
215
wdenk47d1a6e2002-11-03 00:01:44 +0000216 lwz r11,0(r12)
217 mtlr r11
218 lwz r11,4(r12)
219 mtspr SRR0,r11
220 lwz r11,8(r12)
221 mtspr SRR1,r11
222
wdenk7c7a23b2002-12-07 00:20:59 +0000223 addi r12,r12,12 /* Adjust stack pointer */
224 li r20,0xd00-4
225 stw r12,0(r20)
226
wdenk47d1a6e2002-11-03 00:01:44 +0000227 SYNC
228 rfi
wdenk7c7a23b2002-12-07 00:20:59 +0000229_end_back:
wdenk47d1a6e2002-11-03 00:01:44 +0000230
231 STD_EXCEPTION(0xd00, SingleStep, UnknownException)
232
233 STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
234 STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
235
236 /*
237 * On the MPC8xx, this is a software emulation interrupt. It
238 * occurs for all unimplemented and illegal instructions.
239 */
240 STD_EXCEPTION(0x1000, SoftEmu, SoftEmuException)
241
242 STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException)
243 STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException)
244 STD_EXCEPTION(0x1300, InstructionTLBError, UnknownException)
245 STD_EXCEPTION(0x1400, DataTLBError, UnknownException)
246
247 STD_EXCEPTION(0x1500, Reserved5, UnknownException)
248 STD_EXCEPTION(0x1600, Reserved6, UnknownException)
249 STD_EXCEPTION(0x1700, Reserved7, UnknownException)
250 STD_EXCEPTION(0x1800, Reserved8, UnknownException)
251 STD_EXCEPTION(0x1900, Reserved9, UnknownException)
252 STD_EXCEPTION(0x1a00, ReservedA, UnknownException)
253 STD_EXCEPTION(0x1b00, ReservedB, UnknownException)
254
255 STD_EXCEPTION(0x1c00, DataBreakpoint, UnknownException)
256 STD_EXCEPTION(0x1d00, InstructionBreakpoint, UnknownException)
257 STD_EXCEPTION(0x1e00, PeripheralBreakpoint, UnknownException)
258 STD_EXCEPTION(0x1f00, DevPortBreakpoint, UnknownException)
259
260 .globl _end_of_vectors
261_end_of_vectors:
262
263 . = 0x2000
264
265boot_cold:
266boot_warm:
267 /* disable everything */
268 li r0, 0
269 mtspr HID0, r0
270 sync
271 mtmsr 0
272 bl invalidate_bats
273 sync
274
275#ifdef CFG_L2
276 /* init the L2 cache */
277 addis r3, r0, L2_INIT@h
278 ori r3, r3, L2_INIT@l
279 sync
280 mtspr l2cr, r3
281#endif
282#if defined(CONFIG_ALTIVEC) && defined(CONFIG_74xx)
283 .long 0x7e00066c
284 /*
285 * dssall instruction, gas doesn't have it yet
286 * ...for altivec, data stream stop all this probably
287 * isn't needed unless we warm (software) reboot U-Boot
288 */
289#endif
290
291#ifdef CFG_L2
292 /* invalidate the L2 cache */
293 bl l2cache_invalidate
294 sync
295#endif
296#ifdef CFG_BOARD_ASM_INIT
297 /* do early init */
298 bl board_asm_init
299#endif
300
301 /*
302 * Calculate absolute address in FLASH and jump there
303 *------------------------------------------------------*/
304 lis r3, CFG_MONITOR_BASE@h
305 ori r3, r3, CFG_MONITOR_BASE@l
306 addi r3, r3, in_flash - _start + EXC_OFF_SYS_RESET
307 mtlr r3
308 blr
309
310in_flash:
311 /* let the C-code set up the rest */
312 /* */
313 /* Be careful to keep code relocatable ! */
314 /*------------------------------------------------------*/
315
316 /* perform low-level init */
317 /* sdram init, galileo init, etc */
318 /* r3: NHR bit from HID0 */
319
320 /* setup the bats */
321 bl setup_bats
322 sync
323
324 /*
325 * Cache must be enabled here for stack-in-cache trick.
326 * This means we need to enable the BATS.
327 * This means:
328 * 1) for the EVB, original gt regs need to be mapped
329 * 2) need to have an IBAT for the 0xf region,
330 * we are running there!
331 * Cache should be turned on after BATs, since by default
332 * everything is write-through.
333 * The init-mem BAT can be reused after reloc. The old
334 * gt-regs BAT can be reused after board_init_f calls
335 * board_pre_init (EVB only).
336 */
337#if !defined(CONFIG_BAB7xx) && !defined(CONFIG_ELPPC)
338 /* enable address translation */
339 bl enable_addr_trans
340 sync
341
342 /* enable and invalidate the data cache */
343 bl l1dcache_enable
344 sync
345#endif
346#ifdef CFG_INIT_RAM_LOCK
347 bl lock_ram_in_cache
348 sync
349#endif
350
351 /* set up the stack pointer in our newly created
352 * cache-ram (r1) */
353 lis r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@h
354 ori r1, r1, (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET)@l
355
356 li r0, 0 /* Make room for stack frame header and */
357 stwu r0, -4(r1) /* clear final stack frame so that */
358 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
359
360 GET_GOT /* initialize GOT access */
361
362 /* run low-level CPU init code (from Flash) */
363 bl cpu_init_f
364 sync
365
366 mr r3, r21
367
368 /* r3: BOOTFLAG */
369 /* run 1st part of board init code (from Flash) */
370 bl board_init_f
371 sync
372
373 /* NOTREACHED */
374
375 .globl invalidate_bats
376invalidate_bats:
377 /* invalidate BATs */
378 mtspr IBAT0U, r0
379 mtspr IBAT1U, r0
380 mtspr IBAT2U, r0
381 mtspr IBAT3U, r0
382 isync
383 mtspr DBAT0U, r0
384 mtspr DBAT1U, r0
385 mtspr DBAT2U, r0
386 mtspr DBAT3U, r0
387 isync
388 sync
389 blr
390
391 /* setup_bats - set them up to some initial state */
392 .globl setup_bats
393setup_bats:
394 addis r0, r0, 0x0000
395
396 /* IBAT 0 */
397 addis r4, r0, CFG_IBAT0L@h
398 ori r4, r4, CFG_IBAT0L@l
399 addis r3, r0, CFG_IBAT0U@h
400 ori r3, r3, CFG_IBAT0U@l
401 mtspr IBAT0L, r4
402 mtspr IBAT0U, r3
403 isync
404
405 /* DBAT 0 */
406 addis r4, r0, CFG_DBAT0L@h
407 ori r4, r4, CFG_DBAT0L@l
408 addis r3, r0, CFG_DBAT0U@h
409 ori r3, r3, CFG_DBAT0U@l
410 mtspr DBAT0L, r4
411 mtspr DBAT0U, r3
412 isync
413
414 /* IBAT 1 */
415 addis r4, r0, CFG_IBAT1L@h
416 ori r4, r4, CFG_IBAT1L@l
417 addis r3, r0, CFG_IBAT1U@h
418 ori r3, r3, CFG_IBAT1U@l
419 mtspr IBAT1L, r4
420 mtspr IBAT1U, r3
421 isync
422
423 /* DBAT 1 */
424 addis r4, r0, CFG_DBAT1L@h
425 ori r4, r4, CFG_DBAT1L@l
426 addis r3, r0, CFG_DBAT1U@h
427 ori r3, r3, CFG_DBAT1U@l
428 mtspr DBAT1L, r4
429 mtspr DBAT1U, r3
430 isync
431
432 /* IBAT 2 */
433 addis r4, r0, CFG_IBAT2L@h
434 ori r4, r4, CFG_IBAT2L@l
435 addis r3, r0, CFG_IBAT2U@h
436 ori r3, r3, CFG_IBAT2U@l
437 mtspr IBAT2L, r4
438 mtspr IBAT2U, r3
439 isync
440
441 /* DBAT 2 */
442 addis r4, r0, CFG_DBAT2L@h
443 ori r4, r4, CFG_DBAT2L@l
444 addis r3, r0, CFG_DBAT2U@h
445 ori r3, r3, CFG_DBAT2U@l
446 mtspr DBAT2L, r4
447 mtspr DBAT2U, r3
448 isync
449
450 /* IBAT 3 */
451 addis r4, r0, CFG_IBAT3L@h
452 ori r4, r4, CFG_IBAT3L@l
453 addis r3, r0, CFG_IBAT3U@h
454 ori r3, r3, CFG_IBAT3U@l
455 mtspr IBAT3L, r4
456 mtspr IBAT3U, r3
457 isync
458
459 /* DBAT 3 */
460 addis r4, r0, CFG_DBAT3L@h
461 ori r4, r4, CFG_DBAT3L@l
462 addis r3, r0, CFG_DBAT3U@h
463 ori r3, r3, CFG_DBAT3U@l
464 mtspr DBAT3L, r4
465 mtspr DBAT3U, r3
466 isync
467
468 /* bats are done, now invalidate the TLBs */
469
470 addis r3, 0, 0x0000
471 addis r5, 0, 0x4 /* upper bound of 0x00040000 for 7400/750 */
472
473 isync
474
475tlblp:
476 tlbie r3
477 sync
478 addi r3, r3, 0x1000
479 cmp 0, 0, r3, r5
480 blt tlblp
481
482 blr
483
484 .globl enable_addr_trans
485enable_addr_trans:
486 /* enable address translation */
487 mfmsr r5
488 ori r5, r5, (MSR_IR | MSR_DR)
489 mtmsr r5
490 isync
491 blr
492
493 .globl disable_addr_trans
494disable_addr_trans:
495 /* disable address translation */
496 mflr r4
497 mfmsr r3
498 andi. r0, r3, (MSR_IR | MSR_DR)
499 beqlr
500 andc r3, r3, r0
501 mtspr SRR0, r4
502 mtspr SRR1, r3
503 rfi
504
505/*
506 * This code finishes saving the registers to the exception frame
507 * and jumps to the appropriate handler for the exception.
508 * Register r21 is pointer into trap frame, r1 has new stack pointer.
509 */
510 .globl transfer_to_handler
511transfer_to_handler:
512 stw r22,_NIP(r21)
513 lis r22,MSR_POW@h
514 andc r23,r23,r22
515 stw r23,_MSR(r21)
516 SAVE_GPR(7, r21)
517 SAVE_4GPRS(8, r21)
518 SAVE_8GPRS(12, r21)
519 SAVE_8GPRS(24, r21)
520 mflr r23
521 andi. r24,r23,0x3f00 /* get vector offset */
522 stw r24,TRAP(r21)
523 li r22,0
524 stw r22,RESULT(r21)
525 mtspr SPRG2,r22 /* r1 is now kernel sp */
526 lwz r24,0(r23) /* virtual address of handler */
527 lwz r23,4(r23) /* where to go when done */
528 mtspr SRR0,r24
529 mtspr SRR1,r20
530 mtlr r23
531 SYNC
532 rfi /* jump to handler, enable MMU */
533
534int_return:
535 mfmsr r28 /* Disable interrupts */
536 li r4,0
537 ori r4,r4,MSR_EE
538 andc r28,r28,r4
539 SYNC /* Some chip revs need this... */
540 mtmsr r28
541 SYNC
542 lwz r2,_CTR(r1)
543 lwz r0,_LINK(r1)
544 mtctr r2
545 mtlr r0
546 lwz r2,_XER(r1)
547 lwz r0,_CCR(r1)
548 mtspr XER,r2
549 mtcrf 0xFF,r0
550 REST_10GPRS(3, r1)
551 REST_10GPRS(13, r1)
552 REST_8GPRS(23, r1)
553 REST_GPR(31, r1)
554 lwz r2,_NIP(r1) /* Restore environment */
555 lwz r0,_MSR(r1)
556 mtspr SRR0,r2
557 mtspr SRR1,r0
558 lwz r0,GPR0(r1)
559 lwz r2,GPR2(r1)
560 lwz r1,GPR1(r1)
561 SYNC
562 rfi
563
564 .globl dc_read
565dc_read:
566 blr
567
568 .globl get_pvr
569get_pvr:
570 mfspr r3, PVR
571 blr
572
573/*-----------------------------------------------------------------------*/
574/*
575 * void relocate_code (addr_sp, gd, addr_moni)
576 *
577 * This "function" does not return, instead it continues in RAM
578 * after relocating the monitor code.
579 *
580 * r3 = dest
581 * r4 = src
582 * r5 = length in bytes
583 * r6 = cachelinesize
584 */
585 .globl relocate_code
586relocate_code:
587 mr r1, r3 /* Set new stack pointer */
588 mr r9, r4 /* Save copy of Global Data pointer */
589 mr r10, r5 /* Save copy of Destination Address */
590
591 mr r3, r5 /* Destination Address */
592 lis r4, CFG_MONITOR_BASE@h /* Source Address */
593 ori r4, r4, CFG_MONITOR_BASE@l
wdenk3b57fe02003-05-30 12:48:29 +0000594 lwz r5, GOT(__init_end)
595 sub r5, r5, r4
wdenk47d1a6e2002-11-03 00:01:44 +0000596 li r6, CFG_CACHELINE_SIZE /* Cache Line Size */
597
598 /*
599 * Fix GOT pointer:
600 *
601 * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address
602 *
603 * Offset:
604 */
605 sub r15, r10, r4
606
607 /* First our own GOT */
608 add r14, r14, r15
609 /* then the one used by the C code */
610 add r30, r30, r15
611
612 /*
613 * Now relocate code
614 */
615#ifdef CONFIG_ECC
616 bl board_relocate_rom
617 sync
618 mr r3, r10 /* Destination Address */
619 lis r4, CFG_MONITOR_BASE@h /* Source Address */
620 ori r4, r4, CFG_MONITOR_BASE@l
wdenk3b57fe02003-05-30 12:48:29 +0000621 lwz r5, GOT(__init_end)
622 sub r5, r5, r4
wdenk47d1a6e2002-11-03 00:01:44 +0000623 li r6, CFG_CACHELINE_SIZE /* Cache Line Size */
624#else
625 cmplw cr1,r3,r4
626 addi r0,r5,3
627 srwi. r0,r0,2
628 beq cr1,4f /* In place copy is not necessary */
629 beq 7f /* Protect against 0 count */
630 mtctr r0
631 bge cr1,2f
632
633 la r8,-4(r4)
634 la r7,-4(r3)
6351: lwzu r0,4(r8)
636 stwu r0,4(r7)
637 bdnz 1b
638 b 4f
639
6402: slwi r0,r0,2
641 add r8,r4,r0
642 add r7,r3,r0
6433: lwzu r0,-4(r8)
644 stwu r0,-4(r7)
645 bdnz 3b
646#endif
647/*
648 * Now flush the cache: note that we must start from a cache aligned
649 * address. Otherwise we might miss one cache line.
650 */
6514: cmpwi r6,0
652 add r5,r3,r5
653 beq 7f /* Always flush prefetch queue in any case */
654 subi r0,r6,1
655 andc r3,r3,r0
656 mr r4,r3
6575: dcbst 0,r4
658 add r4,r4,r6
659 cmplw r4,r5
660 blt 5b
661 sync /* Wait for all dcbst to complete on bus */
662 mr r4,r3
6636: icbi 0,r4
664 add r4,r4,r6
665 cmplw r4,r5
666 blt 6b
6677: sync /* Wait for all icbi to complete on bus */
668 isync
669
670/*
671 * We are done. Do not return, instead branch to second part of board
672 * initialization, now running from RAM.
673 */
674 addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
675 mtlr r0
676 blr
677
678in_ram:
679#ifdef CONFIG_ECC
680 bl board_init_ecc
681#endif
682 /*
683 * Relocation Function, r14 point to got2+0x8000
684 *
685 * Adjust got2 pointers, no need to check for 0, this code
686 * already puts a few entries in the table.
687 */
688 li r0,__got2_entries@sectoff@l
689 la r3,GOT(_GOT2_TABLE_)
690 lwz r11,GOT(_GOT2_TABLE_)
691 mtctr r0
692 sub r11,r3,r11
693 addi r3,r3,-4
6941: lwzu r0,4(r3)
695 add r0,r0,r11
696 stw r0,0(r3)
697 bdnz 1b
698
699 /*
700 * Now adjust the fixups and the pointers to the fixups
701 * in case we need to move ourselves again.
702 */
7032: li r0,__fixup_entries@sectoff@l
704 lwz r3,GOT(_FIXUP_TABLE_)
705 cmpwi r0,0
706 mtctr r0
707 addi r3,r3,-4
708 beq 4f
7093: lwzu r4,4(r3)
710 lwzux r0,r4,r11
711 add r0,r0,r11
712 stw r10,0(r3)
713 stw r0,0(r4)
714 bdnz 3b
7154:
716/* clear_bss: */
717 /*
718 * Now clear BSS segment
719 */
wdenk5d232d02003-05-22 22:52:13 +0000720 lwz r3,GOT(__bss_start)
wdenk47d1a6e2002-11-03 00:01:44 +0000721 lwz r4,GOT(_end)
722
723 cmplw 0, r3, r4
724 beq 6f
725
726 li r0, 0
7275:
728 stw r0, 0(r3)
729 addi r3, r3, 4
730 cmplw 0, r3, r4
731 bne 5b
7326:
733 mr r3, r10 /* Destination Address */
wdenk7c7a23b2002-12-07 00:20:59 +0000734#ifdef CONFIG_AMIGAONEG3SE
735 mr r4, r9 /* Use RAM copy of the global data */
736#endif
wdenk47d1a6e2002-11-03 00:01:44 +0000737 bl after_reloc
738
739 /* not reached - end relocate_code */
740/*-----------------------------------------------------------------------*/
741
wdenk47d1a6e2002-11-03 00:01:44 +0000742 /*
743 * Copy exception vector code to low memory
744 *
745 * r3: dest_addr
746 * r7: source address, r8: end address, r9: target address
747 */
748 .globl trap_init
749trap_init:
750 lwz r7, GOT(_start)
751 lwz r8, GOT(_end_of_vectors)
752
753 rlwinm r9, r7, 0, 18, 31 /* _start & 0x3FFF */
754
755 cmplw 0, r7, r8
756 bgelr /* return if r7>=r8 - just in case */
757
758 mflr r4 /* save link register */
7591:
760 lwz r0, 0(r7)
761 stw r0, 0(r9)
762 addi r7, r7, 4
763 addi r9, r9, 4
764 cmplw 0, r7, r8
765 bne 1b
766
767 /*
768 * relocate `hdlr' and `int_return' entries
769 */
770 li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
771 li r8, Alignment - _start + EXC_OFF_SYS_RESET
7722:
773 bl trap_reloc
774 addi r7, r7, 0x100 /* next exception vector */
775 cmplw 0, r7, r8
776 blt 2b
777
778 li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
779 bl trap_reloc
780
781 li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
782 bl trap_reloc
783
784 li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
785 li r8, SystemCall - _start + EXC_OFF_SYS_RESET
7863:
787 bl trap_reloc
788 addi r7, r7, 0x100 /* next exception vector */
789 cmplw 0, r7, r8
790 blt 3b
791
792 li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
793 li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
7944:
795 bl trap_reloc
796 addi r7, r7, 0x100 /* next exception vector */
797 cmplw 0, r7, r8
798 blt 4b
799
800 /* enable execptions from RAM vectors */
801 mfmsr r7
802 li r8,MSR_IP
803 andc r7,r7,r8
804 mtmsr r7
805
806 mtlr r4 /* restore link register */
807 blr
808
809 /*
810 * Function: relocate entries for one exception vector
811 */
812trap_reloc:
813 lwz r0, 0(r7) /* hdlr ... */
814 add r0, r0, r3 /* ... += dest_addr */
815 stw r0, 0(r7)
816
817 lwz r0, 4(r7) /* int_return ... */
818 add r0, r0, r3 /* ... += dest_addr */
819 stw r0, 4(r7)
820
821 sync
822 isync
823
824 blr
825
826#ifdef CFG_INIT_RAM_LOCK
827lock_ram_in_cache:
828 /* Allocate Initial RAM in data cache.
829 */
830 lis r3, (CFG_INIT_RAM_ADDR & ~31)@h
831 ori r3, r3, (CFG_INIT_RAM_ADDR & ~31)@l
832 li r2, ((CFG_INIT_RAM_END & ~31) + \
833 (CFG_INIT_RAM_ADDR & 31) + 31) / 32
834 mtctr r2
8351:
836 dcbz r0, r3
837 addi r3, r3, 32
838 bdnz 1b
839
840 /* Lock the data cache */
841 mfspr r0, HID0
842 ori r0, r0, 0x1000
843 sync
844 mtspr HID0, r0
845 sync
846 blr
847
848.globl unlock_ram_in_cache
849unlock_ram_in_cache:
850 /* invalidate the INIT_RAM section */
851 lis r3, (CFG_INIT_RAM_ADDR & ~31)@h
852 ori r3, r3, (CFG_INIT_RAM_ADDR & ~31)@l
853 li r2, ((CFG_INIT_RAM_END & ~31) + \
854 (CFG_INIT_RAM_ADDR & 31) + 31) / 32
855 mtctr r2
8561: icbi r0, r3
857 addi r3, r3, 32
858 bdnz 1b
859 sync /* Wait for all icbi to complete on bus */
860 isync
861
862 /* Unlock the data cache and invalidate it */
863 mfspr r0, HID0
864 li r3,0x1000
865 andc r0,r0,r3
866 li r3,0x0400
867 or r0,r0,r3
868 sync
869 mtspr HID0, r0
870 sync
871 blr
872#endif