]> git.ipfire.org Git - people/ms/u-boot.git/blame - arch/powerpc/cpu/mpc8220/start.S
powerpc, 8xx: Fixup all 8xx u-boot.lds scripts
[people/ms/u-boot.git] / arch / powerpc / cpu / mpc8220 / start.S
CommitLineData
983fda83
WD
1/*
2 * Copyright (C) 1998 Dan Malek <dmalek@jlc.net>
3 * Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
4 * Copyright (C) 2000 - 2003 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 * U-Boot - Startup Code for MPC8220 CPUs
27 */
25ddd1fb 28#include <asm-offsets.h>
983fda83
WD
29#include <config.h>
30#include <mpc8220.h>
561858ee 31#include <timestamp.h>
983fda83
WD
32#include <version.h>
33
34#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */
35
36#include <ppc_asm.tmpl>
37#include <ppc_defs.h>
38
39#include <asm/cache.h>
40#include <asm/mmu.h>
d98b0523 41#include <asm/u-boot.h>
983fda83
WD
42
43#ifndef CONFIG_IDENT_STRING
44#define CONFIG_IDENT_STRING ""
45#endif
46
47/* We don't want the MMU yet.
48*/
49#undef MSR_KERNEL
50/* Floating Point enable, Machine Check and Recoverable Interr. */
51#ifdef DEBUG
52#define MSR_KERNEL (MSR_FP|MSR_RI)
53#else
54#define MSR_KERNEL (MSR_FP|MSR_ME|MSR_RI)
55#endif
56
57/*
58 * Set up GOT: Global Offset Table
59 *
0f8aa159 60 * Use r12 to access the GOT
983fda83
WD
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
71 GOT_ENTRY(__init_end)
44c6e659 72 GOT_ENTRY(__bss_end__)
983fda83
WD
73 GOT_ENTRY(__bss_start)
74 END_GOT
75
76/*
77 * Version string
78 */
79 .data
80 .globl version_string
81version_string:
82 .ascii U_BOOT_VERSION
561858ee 83 .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")"
983fda83
WD
84 .ascii CONFIG_IDENT_STRING, "\0"
85
86/*
87 * Exception vectors
88 */
89 .text
90 . = EXC_OFF_SYS_RESET
91 .globl _start
92_start:
983fda83
WD
93 mfmsr r5 /* save msr contents */
94
95 /* replace default MBAR base address from 0x80000000
96 to 0xf0000000 */
97
6d0f6bcf
JCPV
98#if defined(CONFIG_SYS_DEFAULT_MBAR) && !defined(CONFIG_SYS_RAMBOOT)
99 lis r3, CONFIG_SYS_MBAR@h
100 ori r3, r3, CONFIG_SYS_MBAR@l
983fda83
WD
101
102 /* MBAR is mirrored into the MBAR SPR */
103 mtspr MBAR,r3
3c2b3d45 104 mtspr SPRN_SPRG7W,r3
6d0f6bcf 105 lis r4, CONFIG_SYS_DEFAULT_MBAR@h
983fda83 106 stw r3, 0(r4)
6d0f6bcf 107#endif /* CONFIG_SYS_DEFAULT_MBAR */
983fda83
WD
108
109 /* Initialise the MPC8220 processor core */
110 /*--------------------------------------------------------------*/
111
112 bl init_8220_core
113
114 /* initialize some things that are hard to access from C */
115 /*--------------------------------------------------------------*/
116
117 /* set up stack in on-chip SRAM */
6d0f6bcf
JCPV
118 lis r3, CONFIG_SYS_INIT_RAM_ADDR@h
119 ori r3, r3, CONFIG_SYS_INIT_RAM_ADDR@l
120 ori r1, r3, CONFIG_SYS_INIT_SP_OFFSET
983fda83
WD
121
122 li r0, 0 /* Make room for stack frame header and */
123 stwu r0, -4(r1) /* clear final stack frame so that */
124 stwu r0, -4(r1) /* stack backtraces terminate cleanly */
125
126 /* let the C-code set up the rest */
127 /* */
128 /* Be careful to keep code relocatable ! */
129 /*--------------------------------------------------------------*/
130
131 GET_GOT /* initialize GOT access */
39768f77
JT
132#if defined(__pic__) && __pic__ == 1
133 /* Needed for upcoming -msingle-pic-base */
134 bl _GLOBAL_OFFSET_TABLE_@local-4
135 mflr r30
136#endif
983fda83
WD
137 /* r3: IMMR */
138 bl cpu_init_f /* run low-level CPU init code (in Flash)*/
139
983fda83
WD
140 bl board_init_f /* run 1st part of board init code (in Flash)*/
141
52ebd9c1
PT
142 /* NOTREACHED - board_init_f() does not return */
143
983fda83
WD
144/*
145 * Vector Table
146 */
147
148 .globl _start_of_vectors
149_start_of_vectors:
150
151/* Machine check */
152 STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)
153
154/* Data Storage exception. */
155 STD_EXCEPTION(0x300, DataStorage, UnknownException)
156
157/* Instruction Storage exception. */
158 STD_EXCEPTION(0x400, InstStorage, UnknownException)
159
160/* External Interrupt exception. */
161 STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
162
163/* Alignment exception. */
164 . = 0x600
165Alignment:
02032e8f 166 EXCEPTION_PROLOG(SRR0, SRR1)
983fda83
WD
167 mfspr r4,DAR
168 stw r4,_DAR(r21)
169 mfspr r5,DSISR
170 stw r5,_DSISR(r21)
171 addi r3,r1,STACK_FRAME_OVERHEAD
fc4e1887 172 EXC_XFER_TEMPLATE(Alignment, AlignmentException, MSR_KERNEL, COPY_EE)
983fda83
WD
173
174/* Program check exception */
175 . = 0x700
176ProgramCheck:
02032e8f 177 EXCEPTION_PROLOG(SRR0, SRR1)
983fda83 178 addi r3,r1,STACK_FRAME_OVERHEAD
fc4e1887
JT
179 EXC_XFER_TEMPLATE(ProgramCheck, ProgramCheckException,
180 MSR_KERNEL, COPY_EE)
983fda83
WD
181
182 STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
183
184 /* I guess we could implement decrementer, and may have
185 * to someday for timekeeping.
186 */
187 STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
188
189 STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
190 STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
191 STD_EXCEPTION(0xc00, SystemCall, UnknownException)
192 STD_EXCEPTION(0xd00, SingleStep, UnknownException)
193
194 STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
195 STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
196
197 STD_EXCEPTION(0x1000, InstructionTLBMiss, UnknownException)
198 STD_EXCEPTION(0x1100, DataLoadTLBMiss, UnknownException)
199 STD_EXCEPTION(0x1200, DataStoreTLBMiss, UnknownException)
200#ifdef DEBUG
201 . = 0x1300
202 /*
203 * This exception occurs when the program counter matches the
204 * Instruction Address Breakpoint Register (IABR).
205 *
206 * I want the cpu to halt if this occurs so I can hunt around
207 * with the debugger and look at things.
208 *
209 * When DEBUG is defined, both machine check enable (in the MSR)
210 * and checkstop reset enable (in the reset mode register) are
211 * turned off and so a checkstop condition will result in the cpu
212 * halting.
213 *
214 * I force the cpu into a checkstop condition by putting an illegal
215 * instruction here (at least this is the theory).
216 *
217 * well - that didnt work, so just do an infinite loop!
218 */
2191: b 1b
220#else
221 STD_EXCEPTION(0x1300, InstructionBreakpoint, DebugException)
222#endif
223 STD_EXCEPTION(0x1400, SMI, UnknownException)
224
225 STD_EXCEPTION(0x1500, Trap_15, UnknownException)
226 STD_EXCEPTION(0x1600, Trap_16, UnknownException)
227 STD_EXCEPTION(0x1700, Trap_17, UnknownException)
228 STD_EXCEPTION(0x1800, Trap_18, UnknownException)
229 STD_EXCEPTION(0x1900, Trap_19, UnknownException)
230 STD_EXCEPTION(0x1a00, Trap_1a, UnknownException)
231 STD_EXCEPTION(0x1b00, Trap_1b, UnknownException)
232 STD_EXCEPTION(0x1c00, Trap_1c, UnknownException)
233 STD_EXCEPTION(0x1d00, Trap_1d, UnknownException)
234 STD_EXCEPTION(0x1e00, Trap_1e, UnknownException)
235 STD_EXCEPTION(0x1f00, Trap_1f, UnknownException)
236 STD_EXCEPTION(0x2000, Trap_20, UnknownException)
237 STD_EXCEPTION(0x2100, Trap_21, UnknownException)
238 STD_EXCEPTION(0x2200, Trap_22, UnknownException)
239 STD_EXCEPTION(0x2300, Trap_23, UnknownException)
240 STD_EXCEPTION(0x2400, Trap_24, UnknownException)
241 STD_EXCEPTION(0x2500, Trap_25, UnknownException)
242 STD_EXCEPTION(0x2600, Trap_26, UnknownException)
243 STD_EXCEPTION(0x2700, Trap_27, UnknownException)
244 STD_EXCEPTION(0x2800, Trap_28, UnknownException)
245 STD_EXCEPTION(0x2900, Trap_29, UnknownException)
246 STD_EXCEPTION(0x2a00, Trap_2a, UnknownException)
247 STD_EXCEPTION(0x2b00, Trap_2b, UnknownException)
248 STD_EXCEPTION(0x2c00, Trap_2c, UnknownException)
249 STD_EXCEPTION(0x2d00, Trap_2d, UnknownException)
250 STD_EXCEPTION(0x2e00, Trap_2e, UnknownException)
251 STD_EXCEPTION(0x2f00, Trap_2f, UnknownException)
252
253
254 .globl _end_of_vectors
255_end_of_vectors:
256
257 . = 0x3000
258
259/*
260 * This code finishes saving the registers to the exception frame
261 * and jumps to the appropriate handler for the exception.
262 * Register r21 is pointer into trap frame, r1 has new stack pointer.
263 */
264 .globl transfer_to_handler
265transfer_to_handler:
266 stw r22,_NIP(r21)
267 lis r22,MSR_POW@h
268 andc r23,r23,r22
269 stw r23,_MSR(r21)
270 SAVE_GPR(7, r21)
271 SAVE_4GPRS(8, r21)
272 SAVE_8GPRS(12, r21)
273 SAVE_8GPRS(24, r21)
274 mflr r23
275 andi. r24,r23,0x3f00 /* get vector offset */
276 stw r24,TRAP(r21)
277 li r22,0
278 stw r22,RESULT(r21)
279 lwz r24,0(r23) /* virtual address of handler */
280 lwz r23,4(r23) /* where to go when done */
281 mtspr SRR0,r24
282 mtspr SRR1,r20
283 mtlr r23
284 SYNC
285 rfi /* jump to handler, enable MMU */
286
287int_return:
288 mfmsr r28 /* Disable interrupts */
289 li r4,0
290 ori r4,r4,MSR_EE
291 andc r28,r28,r4
292 SYNC /* Some chip revs need this... */
293 mtmsr r28
294 SYNC
295 lwz r2,_CTR(r1)
296 lwz r0,_LINK(r1)
297 mtctr r2
298 mtlr r0
299 lwz r2,_XER(r1)
300 lwz r0,_CCR(r1)
301 mtspr XER,r2
302 mtcrf 0xFF,r0
303 REST_10GPRS(3, r1)
304 REST_10GPRS(13, r1)
305 REST_8GPRS(23, r1)
306 REST_GPR(31, r1)
307 lwz r2,_NIP(r1) /* Restore environment */
308 lwz r0,_MSR(r1)
309 mtspr SRR0,r2
310 mtspr SRR1,r0
311 lwz r0,GPR0(r1)
312 lwz r2,GPR2(r1)
313 lwz r1,GPR1(r1)
314 SYNC
315 rfi
316
317/*
318 * This code initialises the MPC8220 processor core
319 * (conforms to PowerPC 603e spec)
320 * Note: expects original MSR contents to be in r5.
321 */
322
323 .globl init_8220_core
324init_8220_core:
325
326 /* Initialize machine status; enable machine check interrupt */
327 /*--------------------------------------------------------------*/
328
329 li r3, MSR_KERNEL /* Set ME and RI flags */
330 rlwimi r3, r5, 0, 25, 25 /* preserve IP bit set by HRCW */
331#ifdef DEBUG
332 rlwimi r3, r5, 0, 21, 22 /* debugger might set SE & BE bits */
333#endif
334 SYNC /* Some chip revs need this... */
335 mtmsr r3
336 SYNC
337 mtspr SRR1, r3 /* Make SRR1 match MSR */
338
339 /* Initialize the Hardware Implementation-dependent Registers */
340 /* HID0 also contains cache control */
341 /*--------------------------------------------------------------*/
342
6d0f6bcf
JCPV
343 lis r3, CONFIG_SYS_HID0_INIT@h
344 ori r3, r3, CONFIG_SYS_HID0_INIT@l
983fda83
WD
345 SYNC
346 mtspr HID0, r3
347
6d0f6bcf
JCPV
348 lis r3, CONFIG_SYS_HID0_FINAL@h
349 ori r3, r3, CONFIG_SYS_HID0_FINAL@l
983fda83
WD
350 SYNC
351 mtspr HID0, r3
352
353 /* Enable Extra BATs */
354 mfspr r3, 1011 /* HID2 */
355 lis r4, 0x0004
356 ori r4, r4, 0x0000
357 or r4, r4, r3
358 mtspr 1011, r4
359 sync
360
361 /* clear all BAT's */
362 /*--------------------------------------------------------------*/
363
364 li r0, 0
365 mtspr DBAT0U, r0
366 mtspr DBAT0L, r0
367 mtspr DBAT1U, r0
368 mtspr DBAT1L, r0
369 mtspr DBAT2U, r0
370 mtspr DBAT2L, r0
371 mtspr DBAT3U, r0
372 mtspr DBAT3L, r0
373 mtspr DBAT4U, r0
374 mtspr DBAT4L, r0
375 mtspr DBAT5U, r0
376 mtspr DBAT5L, r0
377 mtspr DBAT6U, r0
378 mtspr DBAT6L, r0
379 mtspr DBAT7U, r0
380 mtspr DBAT7L, r0
381 mtspr IBAT0U, r0
382 mtspr IBAT0L, r0
383 mtspr IBAT1U, r0
384 mtspr IBAT1L, r0
385 mtspr IBAT2U, r0
386 mtspr IBAT2L, r0
387 mtspr IBAT3U, r0
388 mtspr IBAT3L, r0
389 mtspr IBAT4U, r0
390 mtspr IBAT4L, r0
391 mtspr IBAT5U, r0
392 mtspr IBAT5L, r0
393 mtspr IBAT6U, r0
394 mtspr IBAT6L, r0
395 mtspr IBAT7U, r0
396 mtspr IBAT7L, r0
397 SYNC
398
399 /* invalidate all tlb's */
400 /* */
401 /* From the 603e User Manual: "The 603e provides the ability to */
402 /* invalidate a TLB entry. The TLB Invalidate Entry (tlbie) */
403 /* instruction invalidates the TLB entry indexed by the EA, and */
404 /* operates on both the instruction and data TLBs simultaneously*/
405 /* invalidating four TLB entries (both sets in each TLB). The */
406 /* index corresponds to bits 15-19 of the EA. To invalidate all */
407 /* entries within both TLBs, 32 tlbie instructions should be */
408 /* issued, incrementing this field by one each time." */
409 /* */
410 /* "Note that the tlbia instruction is not implemented on the */
411 /* 603e." */
412 /* */
413 /* bits 15-19 correspond to addresses 0x00000000 to 0x0001F000 */
414 /* incrementing by 0x1000 each time. The code below is sort of */
a47a12be 415 /* based on code in "flush_tlbs" from arch/powerpc/kernel/head.S */
983fda83
WD
416 /* */
417 /*--------------------------------------------------------------*/
418
419 li r3, 32
420 mtctr r3
421 li r3, 0
4221: tlbie r3
423 addi r3, r3, 0x1000
424 bdnz 1b
425 SYNC
426
427 /* Done! */
428 /*--------------------------------------------------------------*/
429
430 blr
431
432/* Cache functions.
433 *
434 * Note: requires that all cache bits in
435 * HID0 are in the low half word.
436 */
437 .globl icache_enable
438icache_enable:
439 lis r4, 0
6d0f6bcf 440 ori r4, r4, CONFIG_SYS_HID0_INIT /* set ICE & ICFI bit */
983fda83
WD
441 rlwinm r3, r4, 0, 21, 19 /* clear the ICFI bit */
442
443 /*
444 * The setting of the instruction cache enable (ICE) bit must be
445 * preceded by an isync instruction to prevent the cache from being
446 * enabled or disabled while an instruction access is in progress.
447 */
448 isync
449 mtspr HID0, r4 /* Enable Instr Cache & Inval cache */
450 mtspr HID0, r3 /* using 2 consec instructions */
451 isync
452 blr
453
454 .globl icache_disable
455icache_disable:
456 mfspr r3, HID0
457 rlwinm r3, r3, 0, 17, 15 /* clear the ICE bit */
458 mtspr HID0, r3
459 isync
460 blr
461
462 .globl icache_status
463icache_status:
464 mfspr r3, HID0
465 rlwinm r3, r3, HID0_ICE_BITPOS + 1, 31, 31
466 blr
467
468 .globl dcache_enable
469dcache_enable:
470 lis r4, 0
471 ori r4, r4, HID0_DCE|HID0_DCFI /* set DCE & DCFI bit */
472 rlwinm r3, r4, 0, 22, 20 /* clear the DCFI bit */
473
474 /* Enable address translation in MSR bit */
475 mfmsr r5
476 ori r5, r5, 0x
477
478
479 /*
480 * The setting of the instruction cache enable (ICE) bit must be
481 * preceded by an isync instruction to prevent the cache from being
482 * enabled or disabled while an instruction access is in progress.
483 */
484 isync
485 mtspr HID0, r4 /* Enable Data Cache & Inval cache*/
486 mtspr HID0, r3 /* using 2 consec instructions */
487 isync
488 blr
489
490 .globl dcache_disable
491dcache_disable:
492 mfspr r3, HID0
493 rlwinm r3, r3, 0, 18, 16 /* clear the DCE bit */
494 mtspr HID0, r3
495 isync
496 blr
497
498 .globl dcache_status
499dcache_status:
500 mfspr r3, HID0
501 rlwinm r3, r3, HID0_DCE_BITPOS + 1, 31, 31
502 blr
503
504 .globl get_pvr
505get_pvr:
506 mfspr r3, PVR
507 blr
508
509/*------------------------------------------------------------------------------*/
510
511/*
512 * void relocate_code (addr_sp, gd, addr_moni)
513 *
514 * This "function" does not return, instead it continues in RAM
515 * after relocating the monitor code.
516 *
517 * r3 = dest
518 * r4 = src
519 * r5 = length in bytes
520 * r6 = cachelinesize
521 */
522 .globl relocate_code
523relocate_code:
524 mr r1, r3 /* Set new stack pointer */
525 mr r9, r4 /* Save copy of Global Data pointer */
526 mr r10, r5 /* Save copy of Destination Address */
527
0f8aa159 528 GET_GOT
39768f77
JT
529#if defined(__pic__) && __pic__ == 1
530 /* Needed for upcoming -msingle-pic-base */
531 bl _GLOBAL_OFFSET_TABLE_@local-4
532 mflr r30
533#endif
983fda83 534 mr r3, r5 /* Destination Address */
6d0f6bcf
JCPV
535 lis r4, CONFIG_SYS_MONITOR_BASE@h /* Source Address */
536 ori r4, r4, CONFIG_SYS_MONITOR_BASE@l
983fda83
WD
537 lwz r5, GOT(__init_end)
538 sub r5, r5, r4
6d0f6bcf 539 li r6, CONFIG_SYS_CACHELINE_SIZE /* Cache Line Size */
983fda83
WD
540
541 /*
542 * Fix GOT pointer:
543 *
6d0f6bcf 544 * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address
983fda83
WD
545 *
546 * Offset:
547 */
548 sub r15, r10, r4
549
550 /* First our own GOT */
0f8aa159 551 add r12, r12, r15
983fda83
WD
552 /* then the one used by the C code */
553 add r30, r30, r15
554
555 /*
556 * Now relocate code
557 */
558
559 cmplw cr1,r3,r4
560 addi r0,r5,3
561 srwi. r0,r0,2
562 beq cr1,4f /* In place copy is not necessary */
563 beq 7f /* Protect against 0 count */
564 mtctr r0
565 bge cr1,2f
566
567 la r8,-4(r4)
568 la r7,-4(r3)
5691: lwzu r0,4(r8)
570 stwu r0,4(r7)
571 bdnz 1b
572 b 4f
573
5742: slwi r0,r0,2
575 add r8,r4,r0
576 add r7,r3,r0
5773: lwzu r0,-4(r8)
578 stwu r0,-4(r7)
579 bdnz 3b
580
581/*
582 * Now flush the cache: note that we must start from a cache aligned
583 * address. Otherwise we might miss one cache line.
584 */
5854: cmpwi r6,0
586 add r5,r3,r5
587 beq 7f /* Always flush prefetch queue in any case */
588 subi r0,r6,1
589 andc r3,r3,r0
590 mfspr r7,HID0 /* don't do dcbst if dcache is disabled */
591 rlwinm r7,r7,HID0_DCE_BITPOS+1,31,31
592 cmpwi r7,0
593 beq 9f
594 mr r4,r3
5955: dcbst 0,r4
596 add r4,r4,r6
597 cmplw r4,r5
598 blt 5b
599 sync /* Wait for all dcbst to complete on bus */
6009: mfspr r7,HID0 /* don't do icbi if icache is disabled */
601 rlwinm r7,r7,HID0_ICE_BITPOS+1,31,31
602 cmpwi r7,0
603 beq 7f
604 mr r4,r3
6056: icbi 0,r4
606 add r4,r4,r6
607 cmplw r4,r5
608 blt 6b
6097: sync /* Wait for all icbi to complete on bus */
610 isync
611
612/*
613 * We are done. Do not return, instead branch to second part of board
614 * initialization, now running from RAM.
615 */
616
617 addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
618 mtlr r0
619 blr
620
621in_ram:
622
623 /*
0f8aa159 624 * Relocation Function, r12 point to got2+0x8000
983fda83
WD
625 *
626 * Adjust got2 pointers, no need to check for 0, this code
627 * already puts a few entries in the table.
628 */
629 li r0,__got2_entries@sectoff@l
630 la r3,GOT(_GOT2_TABLE_)
631 lwz r11,GOT(_GOT2_TABLE_)
632 mtctr r0
633 sub r11,r3,r11
634 addi r3,r3,-4
6351: lwzu r0,4(r3)
afc3ba0f
JT
636 cmpwi r0,0
637 beq- 2f
983fda83
WD
638 add r0,r0,r11
639 stw r0,0(r3)
afc3ba0f 6402: bdnz 1b
983fda83
WD
641
642 /*
643 * Now adjust the fixups and the pointers to the fixups
644 * in case we need to move ourselves again.
645 */
afc3ba0f 646 li r0,__fixup_entries@sectoff@l
983fda83
WD
647 lwz r3,GOT(_FIXUP_TABLE_)
648 cmpwi r0,0
649 mtctr r0
650 addi r3,r3,-4
651 beq 4f
6523: lwzu r4,4(r3)
653 lwzux r0,r4,r11
d1e0b10a 654 cmpwi r0,0
983fda83 655 add r0,r0,r11
34bbf618 656 stw r4,0(r3)
d1e0b10a 657 beq- 5f
983fda83 658 stw r0,0(r4)
d1e0b10a 6595: bdnz 3b
983fda83
WD
6604:
661clear_bss:
662 /*
663 * Now clear BSS segment
664 */
665 lwz r3,GOT(__bss_start)
44c6e659 666 lwz r4,GOT(__bss_end__)
983fda83
WD
667
668 cmplw 0, r3, r4
669 beq 6f
670
671 li r0, 0
6725:
673 stw r0, 0(r3)
674 addi r3, r3, 4
675 cmplw 0, r3, r4
676 bne 5b
6776:
678
679 mr r3, r9 /* Global Data pointer */
680 mr r4, r10 /* Destination Address */
681 bl board_init_r
682
683 /*
684 * Copy exception vector code to low memory
685 *
686 * r3: dest_addr
687 * r7: source address, r8: end address, r9: target address
688 */
689 .globl trap_init
690trap_init:
0f8aa159
JT
691 mflr r4 /* save link register */
692 GET_GOT
983fda83
WD
693 lwz r7, GOT(_start)
694 lwz r8, GOT(_end_of_vectors)
695
696 li r9, 0x100 /* reset vector always at 0x100 */
697
698 cmplw 0, r7, r8
699 bgelr /* return if r7>=r8 - just in case */
983fda83
WD
7001:
701 lwz r0, 0(r7)
702 stw r0, 0(r9)
703 addi r7, r7, 4
704 addi r9, r9, 4
705 cmplw 0, r7, r8
706 bne 1b
707
708 /*
709 * relocate `hdlr' and `int_return' entries
710 */
711 li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
712 li r8, Alignment - _start + EXC_OFF_SYS_RESET
7132:
714 bl trap_reloc
715 addi r7, r7, 0x100 /* next exception vector */
716 cmplw 0, r7, r8
717 blt 2b
718
719 li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
720 bl trap_reloc
721
722 li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
723 bl trap_reloc
724
725 li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
726 li r8, SystemCall - _start + EXC_OFF_SYS_RESET
7273:
728 bl trap_reloc
729 addi r7, r7, 0x100 /* next exception vector */
730 cmplw 0, r7, r8
731 blt 3b
732
733 li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
734 li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
7354:
736 bl trap_reloc
737 addi r7, r7, 0x100 /* next exception vector */
738 cmplw 0, r7, r8
739 blt 4b
740
741 mfmsr r3 /* now that the vectors have */
742 lis r7, MSR_IP@h /* relocated into low memory */
743 ori r7, r7, MSR_IP@l /* MSR[IP] can be turned off */
744 andc r3, r3, r7 /* (if it was on) */
745 SYNC /* Some chip revs need this... */
746 mtmsr r3
747 SYNC
748
749 mtlr r4 /* restore link register */
750 blr