uboot/cpu/mpc8220/start.S
<<
>>
Prefs
   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
  79version_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
 102boot_cold:
 103boot_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
 172Alignment:
 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
 183ProgramCheck:
 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         */
 2261:      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
 272transfer_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
 294int_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
 331init_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/ppc/kernel/head.S    */
 423        /*                                                              */
 424        /*--------------------------------------------------------------*/
 425
 426        li      r3, 32
 427        mtctr   r3
 428        li      r3, 0
 4291:      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
 445icache_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
 462icache_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
 470icache_status:
 471        mfspr   r3, HID0
 472        rlwinm  r3, r3, HID0_ICE_BITPOS + 1, 31, 31
 473        blr
 474
 475        .globl  dcache_enable
 476dcache_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
 498dcache_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
 506dcache_status:
 507        mfspr   r3, HID0
 508        rlwinm  r3, r3, HID0_DCE_BITPOS + 1, 31, 31
 509        blr
 510
 511        .globl  get_pvr
 512get_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
 530relocate_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)
 5711:      lwzu    r0,4(r8)
 572        stwu    r0,4(r7)
 573        bdnz    1b
 574        b       4f
 575
 5762:      slwi    r0,r0,2
 577        add     r8,r4,r0
 578        add     r7,r3,r0
 5793:      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 */
 5874:      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
 5975:      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    */
 6029:      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
 6076:      icbi    0,r4
 608        add     r4,r4,r6
 609        cmplw   r4,r5
 610        blt     6b
 6117:      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
 623in_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
 6371:      lwzu    r0,4(r3)
 638        cmpwi   r0,0
 639        beq-    2f
 640        add     r0,r0,r11
 641        stw     r0,0(r3)
 6422:      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
 6543:      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
 6604:
 661clear_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
 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:
 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  */
 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
 751