]> git.sur5r.net Git - u-boot/blob - arch/powerpc/cpu/mpc8220/start.S
PowerPC: Add support for -msingle-pic-base
[u-boot] / 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 <asm-offsets.h>
29 #include <config.h>
30 #include <mpc8220.h>
31 #include <timestamp.h>
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>
41 #include <asm/u-boot.h>
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  *
60  * Use r12 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
71         GOT_ENTRY(__init_end)
72         GOT_ENTRY(__bss_end__)
73         GOT_ENTRY(__bss_start)
74         END_GOT
75
76 /*
77  * Version string
78  */
79         .data
80         .globl  version_string
81 version_string:
82         .ascii U_BOOT_VERSION
83         .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")"
84         .ascii CONFIG_IDENT_STRING, "\0"
85
86 /*
87  * Exception vectors
88  */
89         .text
90         . = EXC_OFF_SYS_RESET
91         .globl  _start
92 _start:
93         mfmsr   r5                  /* save msr contents    */
94
95         /* replace default MBAR base address from 0x80000000
96             to 0xf0000000 */
97
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
101
102         /* MBAR is mirrored into the MBAR SPR */
103         mtspr   MBAR,r3
104         mtspr   SPRN_SPRG7W,r3
105         lis     r4, CONFIG_SYS_DEFAULT_MBAR@h
106         stw     r3, 0(r4)
107 #endif /* CONFIG_SYS_DEFAULT_MBAR */
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 */
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
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                */
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
137         /* r3: IMMR */
138         bl      cpu_init_f      /* run low-level CPU init code (in Flash)*/
139
140         bl      board_init_f    /* run 1st part of board init code (in Flash)*/
141
142         /* NOTREACHED - board_init_f() does not return */
143
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
165 Alignment:
166         EXCEPTION_PROLOG(SRR0, SRR1)
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
172         EXC_XFER_TEMPLATE(Alignment, AlignmentException, MSR_KERNEL, COPY_EE)
173
174 /* Program check exception */
175         . = 0x700
176 ProgramCheck:
177         EXCEPTION_PROLOG(SRR0, SRR1)
178         addi    r3,r1,STACK_FRAME_OVERHEAD
179         EXC_XFER_TEMPLATE(ProgramCheck, ProgramCheckException,
180                 MSR_KERNEL, COPY_EE)
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          */
219 1:      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
265 transfer_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
287 int_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
324 init_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
343         lis     r3, CONFIG_SYS_HID0_INIT@h
344         ori     r3, r3, CONFIG_SYS_HID0_INIT@l
345         SYNC
346         mtspr   HID0, r3
347
348         lis     r3, CONFIG_SYS_HID0_FINAL@h
349         ori     r3, r3, CONFIG_SYS_HID0_FINAL@l
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  */
415         /* based on code in "flush_tlbs" from arch/powerpc/kernel/head.S        */
416         /*                                                              */
417         /*--------------------------------------------------------------*/
418
419         li      r3, 32
420         mtctr   r3
421         li      r3, 0
422 1:      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
438 icache_enable:
439         lis     r4, 0
440         ori     r4, r4, CONFIG_SYS_HID0_INIT /* set ICE & ICFI bit              */
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
455 icache_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
463 icache_status:
464         mfspr   r3, HID0
465         rlwinm  r3, r3, HID0_ICE_BITPOS + 1, 31, 31
466         blr
467
468         .globl  dcache_enable
469 dcache_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
491 dcache_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
499 dcache_status:
500         mfspr   r3, HID0
501         rlwinm  r3, r3, HID0_DCE_BITPOS + 1, 31, 31
502         blr
503
504         .globl  get_pvr
505 get_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
523 relocate_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
528         GET_GOT
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
534         mr      r3,  r5     /* Destination Address              */
535         lis     r4, CONFIG_SYS_MONITOR_BASE@h   /* Source Address       */
536         ori     r4, r4, CONFIG_SYS_MONITOR_BASE@l
537         lwz     r5, GOT(__init_end)
538         sub     r5, r5, r4
539         li      r6, CONFIG_SYS_CACHELINE_SIZE   /* Cache Line Size      */
540
541         /*
542          * Fix GOT pointer:
543          *
544          * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address
545          *
546          * Offset:
547          */
548         sub     r15, r10, r4
549
550         /* First our own GOT */
551         add     r12, r12, r15
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)
569 1:      lwzu    r0,4(r8)
570         stwu    r0,4(r7)
571         bdnz    1b
572         b       4f
573
574 2:      slwi    r0,r0,2
575         add     r8,r4,r0
576         add     r7,r3,r0
577 3:      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  */
585 4:      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
595 5:      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    */
600 9:      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
605 6:      icbi    0,r4
606         add     r4,r4,r6
607         cmplw   r4,r5
608         blt     6b
609 7:      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
621 in_ram:
622
623         /*
624          * Relocation Function, r12 point to got2+0x8000
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
635 1:      lwzu    r0,4(r3)
636         cmpwi   r0,0
637         beq-    2f
638         add     r0,r0,r11
639         stw     r0,0(r3)
640 2:      bdnz    1b
641
642         /*
643          * Now adjust the fixups and the pointers to the fixups
644          * in case we need to move ourselves again.
645          */
646         li      r0,__fixup_entries@sectoff@l
647         lwz     r3,GOT(_FIXUP_TABLE_)
648         cmpwi   r0,0
649         mtctr   r0
650         addi    r3,r3,-4
651         beq     4f
652 3:      lwzu    r4,4(r3)
653         lwzux   r0,r4,r11
654         cmpwi   r0,0
655         add     r0,r0,r11
656         stw     r4,0(r3)
657         beq-    5f
658         stw     r0,0(r4)
659 5:      bdnz    3b
660 4:
661 clear_bss:
662         /*
663          * Now clear BSS segment
664          */
665         lwz     r3,GOT(__bss_start)
666         lwz     r4,GOT(__bss_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