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