uboot/cpu/mpc86xx/start.S
<<
>>
Prefs
   1/*
   2 * Copyright 2004, 2007 Freescale Semiconductor.
   3 * Srikanth Srinivasan <srikanth.srinivaan@freescale.com>
   4 *
   5 * See file CREDITS for list of people who contributed to this
   6 * project.
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License as
  10 * published by the Free Software Foundation; either version 2 of
  11 * the License, or (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 * MA 02111-1307 USA
  22 */
  23
  24/*  U-Boot - Startup Code for 86xx PowerPC based Embedded Boards
  25 *
  26 *
  27 *  The processor starts at 0xfff00100 and the code is executed
  28 *  from flash. The code is organized to be at an other address
  29 *  in memory, but as long we don't jump around before relocating.
  30 *  board_init lies at a quite high address and when the cpu has
  31 *  jumped there, everything is ok.
  32 */
  33#include <config.h>
  34#include <mpc86xx.h>
  35#include <timestamp.h>
  36#include <version.h>
  37
  38#include <ppc_asm.tmpl>
  39#include <ppc_defs.h>
  40
  41#include <asm/cache.h>
  42#include <asm/mmu.h>
  43
  44#ifndef CONFIG_IDENT_STRING
  45#define CONFIG_IDENT_STRING ""
  46#endif
  47
  48/*
  49 * Need MSR_DR | MSR_IR enabled to access I/O (printf) in exceptions
  50 */
  51
  52/*
  53 * Set up GOT: Global Offset Table
  54 *
  55 * Use r14 to access the GOT
  56 */
  57        START_GOT
  58        GOT_ENTRY(_GOT2_TABLE_)
  59        GOT_ENTRY(_FIXUP_TABLE_)
  60
  61        GOT_ENTRY(_start)
  62        GOT_ENTRY(_start_of_vectors)
  63        GOT_ENTRY(_end_of_vectors)
  64        GOT_ENTRY(transfer_to_handler)
  65
  66        GOT_ENTRY(__init_end)
  67        GOT_ENTRY(_end)
  68        GOT_ENTRY(__bss_start)
  69        END_GOT
  70
  71/*
  72 * r3 - 1st arg to board_init(): IMMP pointer
  73 * r4 - 2nd arg to board_init(): boot flag
  74 */
  75        .text
  76        .long   0x27051956              /* U-Boot Magic Number */
  77        .globl  version_string
  78version_string:
  79        .ascii  U_BOOT_VERSION
  80        .ascii  " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")"
  81        .ascii  CONFIG_IDENT_STRING, "\0"
  82
  83        . = EXC_OFF_SYS_RESET
  84        .globl  _start
  85_start:
  86        li      r21, BOOTFLAG_COLD      /* Normal Power-On: Boot from FLASH */
  87        b       boot_cold
  88        sync
  89
  90        . = EXC_OFF_SYS_RESET + 0x10
  91
  92        .globl  _start_warm
  93_start_warm:
  94        li      r21, BOOTFLAG_WARM      /* Software reboot */
  95        b       boot_warm
  96        sync
  97
  98        /* the boot code is located below the exception table */
  99
 100        .globl  _start_of_vectors
 101_start_of_vectors:
 102
 103/* Machine check */
 104        STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)
 105
 106/* Data Storage exception. */
 107        STD_EXCEPTION(0x300, DataStorage, UnknownException)
 108
 109/* Instruction Storage exception. */
 110        STD_EXCEPTION(0x400, InstStorage, UnknownException)
 111
 112/* External Interrupt exception. */
 113        STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
 114
 115/* Alignment exception. */
 116        . = 0x600
 117Alignment:
 118        EXCEPTION_PROLOG(SRR0, SRR1)
 119        mfspr   r4,DAR
 120        stw     r4,_DAR(r21)
 121        mfspr   r5,DSISR
 122        stw     r5,_DSISR(r21)
 123        addi    r3,r1,STACK_FRAME_OVERHEAD
 124        li      r20,MSR_KERNEL
 125        rlwimi  r20,r23,0,16,16         /* copy EE bit from saved MSR */
 126        lwz     r6,GOT(transfer_to_handler)
 127        mtlr    r6
 128        blrl
 129.L_Alignment:
 130        .long   AlignmentException - _start + EXC_OFF_SYS_RESET
 131        .long   int_return - _start + EXC_OFF_SYS_RESET
 132
 133/* Program check exception */
 134        . = 0x700
 135ProgramCheck:
 136        EXCEPTION_PROLOG(SRR0, SRR1)
 137        addi    r3,r1,STACK_FRAME_OVERHEAD
 138        li      r20,MSR_KERNEL
 139        rlwimi  r20,r23,0,16,16         /* copy EE bit from saved MSR */
 140        lwz     r6,GOT(transfer_to_handler)
 141        mtlr    r6
 142        blrl
 143.L_ProgramCheck:
 144        .long   ProgramCheckException - _start + EXC_OFF_SYS_RESET
 145        .long   int_return - _start + EXC_OFF_SYS_RESET
 146
 147        STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
 148
 149        /* I guess we could implement decrementer, and may have
 150         * to someday for timekeeping.
 151         */
 152        STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
 153        STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
 154        STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
 155        STD_EXCEPTION(0xc00, SystemCall, UnknownException)
 156        STD_EXCEPTION(0xd00, SingleStep, UnknownException)
 157        STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
 158        STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
 159        STD_EXCEPTION(0x1000, SoftEmu, SoftEmuException)
 160        STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException)
 161        STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException)
 162        STD_EXCEPTION(0x1300, InstructionTLBError, UnknownException)
 163        STD_EXCEPTION(0x1400, DataTLBError, UnknownException)
 164        STD_EXCEPTION(0x1500, Reserved5, UnknownException)
 165        STD_EXCEPTION(0x1600, Reserved6, UnknownException)
 166        STD_EXCEPTION(0x1700, Reserved7, UnknownException)
 167        STD_EXCEPTION(0x1800, Reserved8, UnknownException)
 168        STD_EXCEPTION(0x1900, Reserved9, UnknownException)
 169        STD_EXCEPTION(0x1a00, ReservedA, UnknownException)
 170        STD_EXCEPTION(0x1b00, ReservedB, UnknownException)
 171        STD_EXCEPTION(0x1c00, DataBreakpoint, UnknownException)
 172        STD_EXCEPTION(0x1d00, InstructionBreakpoint, UnknownException)
 173        STD_EXCEPTION(0x1e00, PeripheralBreakpoint, UnknownException)
 174        STD_EXCEPTION(0x1f00, DevPortBreakpoint, UnknownException)
 175
 176        .globl  _end_of_vectors
 177_end_of_vectors:
 178
 179        . = 0x2000
 180
 181boot_cold:
 182boot_warm:
 183        /*
 184         * NOTE: Only Cpu 0 will ever come here.  Other cores go to an
 185         * address specified by the BPTR
 186         */
 1871:
 188#ifdef CONFIG_SYS_RAMBOOT
 189        /* disable everything */
 190        li      r0, 0
 191        mtspr   HID0, r0
 192        sync
 193        mtmsr   0
 194#endif
 195
 196        /* Invalidate BATs */
 197        bl      invalidate_bats
 198        sync
 199        /* Invalidate all of TLB before MMU turn on */
 200        bl      clear_tlbs
 201        sync
 202
 203#ifdef CONFIG_SYS_L2
 204        /* init the L2 cache */
 205        lis     r3, L2_INIT@h
 206        ori     r3, r3, L2_INIT@l
 207        mtspr   l2cr, r3
 208        /* invalidate the L2 cache */
 209        bl      l2cache_invalidate
 210        sync
 211#endif
 212
 213        /*
 214         * Calculate absolute address in FLASH and jump there
 215         *------------------------------------------------------*/
 216        lis     r3, CONFIG_SYS_MONITOR_BASE_EARLY@h
 217        ori     r3, r3, CONFIG_SYS_MONITOR_BASE_EARLY@l
 218        addi    r3, r3, in_flash - _start + EXC_OFF_SYS_RESET
 219        mtlr    r3
 220        blr
 221
 222in_flash:
 223        /* let the C-code set up the rest                       */
 224        /*                                                      */
 225        /* Be careful to keep code relocatable !                */
 226        /*------------------------------------------------------*/
 227        /* perform low-level init */
 228
 229        /* enable extended addressing */
 230        bl      enable_ext_addr
 231
 232        /* setup the bats */
 233        bl      early_bats
 234
 235        /*
 236         * Cache must be enabled here for stack-in-cache trick.
 237         * This means we need to enable the BATS.
 238         * Cache should be turned on after BATs, since by default
 239         * everything is write-through.
 240         */
 241
 242        /* enable address translation */
 243        mfmsr   r5
 244        ori     r5, r5, (MSR_IR | MSR_DR)
 245        lis     r3,addr_trans_enabled@h
 246        ori     r3, r3, addr_trans_enabled@l
 247        mtspr   SPRN_SRR0,r3
 248        mtspr   SPRN_SRR1,r5
 249        rfi
 250
 251addr_trans_enabled:
 252        /* enable and invalidate the data cache */
 253/*      bl      l1dcache_enable */
 254        bl      dcache_enable
 255        sync
 256
 257#if 1
 258        bl      icache_enable
 259#endif
 260
 261#ifdef CONFIG_SYS_INIT_RAM_LOCK
 262        bl      lock_ram_in_cache
 263        sync
 264#endif
 265
 266#if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR)
 267        bl      setup_ccsrbar
 268#endif
 269
 270        /* set up the stack pointer in our newly created
 271         * cache-ram (r1) */
 272        lis     r1, (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET)@h
 273        ori     r1, r1, (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET)@l
 274
 275        li      r0, 0           /* Make room for stack frame header and */
 276        stwu    r0, -4(r1)      /* clear final stack frame so that      */
 277        stwu    r0, -4(r1)      /* stack backtraces terminate cleanly   */
 278
 279        GET_GOT                 /* initialize GOT access        */
 280
 281        /* run low-level CPU init code     (from Flash) */
 282        bl      cpu_init_f
 283        sync
 284
 285#ifdef  RUN_DIAG
 286
 287        /* Load PX_AUX register address in r4 */
 288        lis     r4, PIXIS_BASE@h
 289        ori     r4, r4, 0x6
 290        /* Load contents of PX_AUX in r3 bits 24 to 31*/
 291        lbz     r3, 0(r4)
 292
 293        /* Mask and obtain the bit in r3 */
 294        rlwinm. r3, r3, 0, 24, 24
 295        /* If not zero, jump and continue with u-boot */
 296        bne     diag_done
 297
 298        /* Load back contents of PX_AUX in r3 bits 24 to 31 */
 299        lbz     r3, 0(r4)
 300        /* Set the MSB of the register value */
 301        ori     r3, r3, 0x80
 302        /* Write value in r3 back to PX_AUX */
 303        stb     r3, 0(r4)
 304
 305        /* Get the address to jump to in r3*/
 306        lis     r3, CONFIG_SYS_DIAG_ADDR@h
 307        ori     r3, r3, CONFIG_SYS_DIAG_ADDR@l
 308
 309        /* Load the LR with the branch address */
 310        mtlr    r3
 311
 312        /* Branch to diagnostic */
 313        blr
 314
 315diag_done:
 316#endif
 317
 318/*      bl      l2cache_enable */
 319        mr      r3, r21
 320
 321        /* r3: BOOTFLAG */
 322        /* run 1st part of board init code (from Flash)   */
 323        bl      board_init_f
 324        sync
 325
 326        /* NOTREACHED */
 327
 328        .globl  invalidate_bats
 329invalidate_bats:
 330
 331        li      r0, 0
 332        /* invalidate BATs */
 333        mtspr   IBAT0U, r0
 334        mtspr   IBAT1U, r0
 335        mtspr   IBAT2U, r0
 336        mtspr   IBAT3U, r0
 337        mtspr   IBAT4U, r0
 338        mtspr   IBAT5U, r0
 339        mtspr   IBAT6U, r0
 340        mtspr   IBAT7U, r0
 341
 342        isync
 343        mtspr   DBAT0U, r0
 344        mtspr   DBAT1U, r0
 345        mtspr   DBAT2U, r0
 346        mtspr   DBAT3U, r0
 347        mtspr   DBAT4U, r0
 348        mtspr   DBAT5U, r0
 349        mtspr   DBAT6U, r0
 350        mtspr   DBAT7U, r0
 351
 352        isync
 353        sync
 354        blr
 355
 356/*
 357 * early_bats:
 358 *
 359 * Set up bats needed early on - this is usually the BAT for the
 360 * stack-in-cache, the Flash, and CCSR space
 361 */
 362        .globl  early_bats
 363early_bats:
 364        /* IBAT 3 */
 365        lis     r4, CONFIG_SYS_IBAT3L@h
 366        ori     r4, r4, CONFIG_SYS_IBAT3L@l
 367        lis     r3, CONFIG_SYS_IBAT3U@h
 368        ori     r3, r3, CONFIG_SYS_IBAT3U@l
 369        mtspr   IBAT3L, r4
 370        mtspr   IBAT3U, r3
 371        isync
 372
 373        /* DBAT 3 */
 374        lis     r4, CONFIG_SYS_DBAT3L@h
 375        ori     r4, r4, CONFIG_SYS_DBAT3L@l
 376        lis     r3, CONFIG_SYS_DBAT3U@h
 377        ori     r3, r3, CONFIG_SYS_DBAT3U@l
 378        mtspr   DBAT3L, r4
 379        mtspr   DBAT3U, r3
 380        isync
 381
 382        /* IBAT 5 */
 383        lis     r4, CONFIG_SYS_IBAT5L@h
 384        ori     r4, r4, CONFIG_SYS_IBAT5L@l
 385        lis     r3, CONFIG_SYS_IBAT5U@h
 386        ori     r3, r3, CONFIG_SYS_IBAT5U@l
 387        mtspr   IBAT5L, r4
 388        mtspr   IBAT5U, r3
 389        isync
 390
 391        /* DBAT 5 */
 392        lis     r4, CONFIG_SYS_DBAT5L@h
 393        ori     r4, r4, CONFIG_SYS_DBAT5L@l
 394        lis     r3, CONFIG_SYS_DBAT5U@h
 395        ori     r3, r3, CONFIG_SYS_DBAT5U@l
 396        mtspr   DBAT5L, r4
 397        mtspr   DBAT5U, r3
 398        isync
 399
 400        /* IBAT 6 */
 401        lis     r4, CONFIG_SYS_IBAT6L_EARLY@h
 402        ori     r4, r4, CONFIG_SYS_IBAT6L_EARLY@l
 403        lis     r3, CONFIG_SYS_IBAT6U_EARLY@h
 404        ori     r3, r3, CONFIG_SYS_IBAT6U_EARLY@l
 405        mtspr   IBAT6L, r4
 406        mtspr   IBAT6U, r3
 407        isync
 408
 409        /* DBAT 6 */
 410        lis     r4, CONFIG_SYS_DBAT6L_EARLY@h
 411        ori     r4, r4, CONFIG_SYS_DBAT6L_EARLY@l
 412        lis     r3, CONFIG_SYS_DBAT6U_EARLY@h
 413        ori     r3, r3, CONFIG_SYS_DBAT6U_EARLY@l
 414        mtspr   DBAT6L, r4
 415        mtspr   DBAT6U, r3
 416        isync
 417
 418#if(CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR)
 419        /* IBAT 7 */
 420        lis     r4, CONFIG_SYS_CCSR_DEFAULT_IBATL@h
 421        ori     r4, r4, CONFIG_SYS_CCSR_DEFAULT_IBATL@l
 422        lis     r3, CONFIG_SYS_CCSR_DEFAULT_IBATU@h
 423        ori     r3, r3, CONFIG_SYS_CCSR_DEFAULT_IBATU@l
 424        mtspr   IBAT7L, r4
 425        mtspr   IBAT7U, r3
 426        isync
 427
 428        /* DBAT 7 */
 429        lis     r4, CONFIG_SYS_CCSR_DEFAULT_DBATL@h
 430        ori     r4, r4, CONFIG_SYS_CCSR_DEFAULT_DBATL@l
 431        lis     r3, CONFIG_SYS_CCSR_DEFAULT_DBATU@h
 432        ori     r3, r3, CONFIG_SYS_CCSR_DEFAULT_DBATU@l
 433        mtspr   DBAT7L, r4
 434        mtspr   DBAT7U, r3
 435        isync
 436#endif
 437        blr
 438
 439        .globl clear_tlbs
 440clear_tlbs:
 441        addis   r3, 0, 0x0000
 442        addis   r5, 0, 0x4
 443        isync
 444tlblp:
 445        tlbie   r3
 446        sync
 447        addi    r3, r3, 0x1000
 448        cmp     0, 0, r3, r5
 449        blt tlblp
 450        blr
 451
 452        .globl disable_addr_trans
 453disable_addr_trans:
 454        /* disable address translation */
 455        mflr    r4
 456        mfmsr   r3
 457        andi.   r0, r3, (MSR_IR | MSR_DR)
 458        beqlr
 459        andc    r3, r3, r0
 460        mtspr   SRR0, r4
 461        mtspr   SRR1, r3
 462        rfi
 463
 464/*
 465 * This code finishes saving the registers to the exception frame
 466 * and jumps to the appropriate handler for the exception.
 467 * Register r21 is pointer into trap frame, r1 has new stack pointer.
 468 */
 469        .globl  transfer_to_handler
 470transfer_to_handler:
 471        stw     r22,_NIP(r21)
 472        lis     r22,MSR_POW@h
 473        andc    r23,r23,r22
 474        stw     r23,_MSR(r21)
 475        SAVE_GPR(7, r21)
 476        SAVE_4GPRS(8, r21)
 477        SAVE_8GPRS(12, r21)
 478        SAVE_8GPRS(24, r21)
 479        mflr    r23
 480        andi.   r24,r23,0x3f00          /* get vector offset */
 481        stw     r24,TRAP(r21)
 482        li      r22,0
 483        stw     r22,RESULT(r21)
 484        mtspr   SPRG2,r22               /* r1 is now kernel sp */
 485        lwz     r24,0(r23)              /* virtual address of handler */
 486        lwz     r23,4(r23)              /* where to go when done */
 487        mtspr   SRR0,r24
 488        mtspr   SRR1,r20
 489        mtlr    r23
 490        SYNC
 491        rfi                             /* jump to handler, enable MMU */
 492
 493int_return:
 494        mfmsr   r28             /* Disable interrupts */
 495        li      r4,0
 496        ori     r4,r4,MSR_EE
 497        andc    r28,r28,r4
 498        SYNC                    /* Some chip revs need this... */
 499        mtmsr   r28
 500        SYNC
 501        lwz     r2,_CTR(r1)
 502        lwz     r0,_LINK(r1)
 503        mtctr   r2
 504        mtlr    r0
 505        lwz     r2,_XER(r1)
 506        lwz     r0,_CCR(r1)
 507        mtspr   XER,r2
 508        mtcrf   0xFF,r0
 509        REST_10GPRS(3, r1)
 510        REST_10GPRS(13, r1)
 511        REST_8GPRS(23, r1)
 512        REST_GPR(31, r1)
 513        lwz     r2,_NIP(r1)     /* Restore environment */
 514        lwz     r0,_MSR(r1)
 515        mtspr   SRR0,r2
 516        mtspr   SRR1,r0
 517        lwz     r0,GPR0(r1)
 518        lwz     r2,GPR2(r1)
 519        lwz     r1,GPR1(r1)
 520        SYNC
 521        rfi
 522
 523        .globl  dc_read
 524dc_read:
 525        blr
 526
 527        .globl get_pvr
 528get_pvr:
 529        mfspr   r3, PVR
 530        blr
 531
 532        .globl get_svr
 533get_svr:
 534        mfspr   r3, SVR
 535        blr
 536
 537
 538/*
 539 * Function:    in8
 540 * Description: Input 8 bits
 541 */
 542        .globl  in8
 543in8:
 544        lbz     r3,0x0000(r3)
 545        blr
 546
 547/*
 548 * Function:    out8
 549 * Description: Output 8 bits
 550 */
 551        .globl  out8
 552out8:
 553        stb     r4,0x0000(r3)
 554        blr
 555
 556/*
 557 * Function:    out16
 558 * Description: Output 16 bits
 559 */
 560        .globl  out16
 561out16:
 562        sth     r4,0x0000(r3)
 563        blr
 564
 565/*
 566 * Function:    out16r
 567 * Description: Byte reverse and output 16 bits
 568 */
 569        .globl  out16r
 570out16r:
 571        sthbrx  r4,r0,r3
 572        blr
 573
 574/*
 575 * Function:    out32
 576 * Description: Output 32 bits
 577 */
 578        .globl  out32
 579out32:
 580        stw     r4,0x0000(r3)
 581        blr
 582
 583/*
 584 * Function:    out32r
 585 * Description: Byte reverse and output 32 bits
 586 */
 587        .globl  out32r
 588out32r:
 589        stwbrx  r4,r0,r3
 590        blr
 591
 592/*
 593 * Function:    in16
 594 * Description: Input 16 bits
 595 */
 596        .globl  in16
 597in16:
 598        lhz     r3,0x0000(r3)
 599        blr
 600
 601/*
 602 * Function:    in16r
 603 * Description: Input 16 bits and byte reverse
 604 */
 605        .globl  in16r
 606in16r:
 607        lhbrx   r3,r0,r3
 608        blr
 609
 610/*
 611 * Function:    in32
 612 * Description: Input 32 bits
 613 */
 614        .globl  in32
 615in32:
 616        lwz     3,0x0000(3)
 617        blr
 618
 619/*
 620 * Function:    in32r
 621 * Description: Input 32 bits and byte reverse
 622 */
 623        .globl  in32r
 624in32r:
 625        lwbrx   r3,r0,r3
 626        blr
 627
 628/*
 629 * void relocate_code (addr_sp, gd, addr_moni)
 630 *
 631 * This "function" does not return, instead it continues in RAM
 632 * after relocating the monitor code.
 633 *
 634 * r3 = dest
 635 * r4 = src
 636 * r5 = length in bytes
 637 * r6 = cachelinesize
 638 */
 639        .globl  relocate_code
 640relocate_code:
 641
 642        mr      r1,  r3         /* Set new stack pointer                */
 643        mr      r9,  r4         /* Save copy of Global Data pointer     */
 644        mr      r10, r5         /* Save copy of Destination Address     */
 645
 646        mr      r3,  r5                         /* Destination Address  */
 647        lis     r4, CONFIG_SYS_MONITOR_BASE@h           /* Source      Address  */
 648        ori     r4, r4, CONFIG_SYS_MONITOR_BASE@l
 649        lwz     r5, GOT(__init_end)
 650        sub     r5, r5, r4
 651        li      r6, CONFIG_SYS_CACHELINE_SIZE           /* Cache Line Size      */
 652
 653        /*
 654         * Fix GOT pointer:
 655         *
 656         * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address
 657         *
 658         * Offset:
 659         */
 660        sub     r15, r10, r4
 661
 662        /* First our own GOT */
 663        add     r14, r14, r15
 664        /* then the one used by the C code */
 665        add     r30, r30, r15
 666
 667        /*
 668         * Now relocate code
 669         */
 670        cmplw   cr1,r3,r4
 671        addi    r0,r5,3
 672        srwi.   r0,r0,2
 673        beq     cr1,4f          /* In place copy is not necessary       */
 674        beq     7f              /* Protect against 0 count              */
 675        mtctr   r0
 676        bge     cr1,2f
 677
 678        la      r8,-4(r4)
 679        la      r7,-4(r3)
 6801:      lwzu    r0,4(r8)
 681        stwu    r0,4(r7)
 682        bdnz    1b
 683        b       4f
 684
 6852:      slwi    r0,r0,2
 686        add     r8,r4,r0
 687        add     r7,r3,r0
 6883:      lwzu    r0,-4(r8)
 689        stwu    r0,-4(r7)
 690        bdnz    3b
 691/*
 692 * Now flush the cache: note that we must start from a cache aligned
 693 * address. Otherwise we might miss one cache line.
 694 */
 6954:      cmpwi   r6,0
 696        add     r5,r3,r5
 697        beq     7f              /* Always flush prefetch queue in any case */
 698        subi    r0,r6,1
 699        andc    r3,r3,r0
 700        mr      r4,r3
 7015:      dcbst   0,r4
 702        add     r4,r4,r6
 703        cmplw   r4,r5
 704        blt     5b
 705        sync                    /* Wait for all dcbst to complete on bus */
 706        mr      r4,r3
 7076:      icbi    0,r4
 708        add     r4,r4,r6
 709        cmplw   r4,r5
 710        blt     6b
 7117:      sync                    /* Wait for all icbi to complete on bus */
 712        isync
 713
 714/*
 715 * We are done. Do not return, instead branch to second part of board
 716 * initialization, now running from RAM.
 717 */
 718        addi    r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
 719        mtlr    r0
 720        blr
 721
 722in_ram:
 723        /*
 724         * Relocation Function, r14 point to got2+0x8000
 725         *
 726         * Adjust got2 pointers, no need to check for 0, this code
 727         * already puts a few entries in the table.
 728         */
 729        li      r0,__got2_entries@sectoff@l
 730        la      r3,GOT(_GOT2_TABLE_)
 731        lwz     r11,GOT(_GOT2_TABLE_)
 732        mtctr   r0
 733        sub     r11,r3,r11
 734        addi    r3,r3,-4
 7351:      lwzu    r0,4(r3)
 736        add     r0,r0,r11
 737        stw     r0,0(r3)
 738        bdnz    1b
 739
 740        /*
 741         * Now adjust the fixups and the pointers to the fixups
 742         * in case we need to move ourselves again.
 743         */
 7442:      li      r0,__fixup_entries@sectoff@l
 745        lwz     r3,GOT(_FIXUP_TABLE_)
 746        cmpwi   r0,0
 747        mtctr   r0
 748        addi    r3,r3,-4
 749        beq     4f
 7503:      lwzu    r4,4(r3)
 751        lwzux   r0,r4,r11
 752        add     r0,r0,r11
 753        stw     r10,0(r3)
 754        stw     r0,0(r4)
 755        bdnz    3b
 7564:
 757/* clear_bss: */
 758        /*
 759         * Now clear BSS segment
 760         */
 761        lwz     r3,GOT(__bss_start)
 762        lwz     r4,GOT(_end)
 763
 764        cmplw   0, r3, r4
 765        beq     6f
 766
 767        li      r0, 0
 7685:
 769        stw     r0, 0(r3)
 770        addi    r3, r3, 4
 771        cmplw   0, r3, r4
 772        bne     5b
 7736:
 774        mr      r3, r9          /* Init Date pointer            */
 775        mr      r4, r10         /* Destination Address          */
 776        bl      board_init_r
 777
 778        /* not reached - end relocate_code */
 779/*-----------------------------------------------------------------------*/
 780
 781        /*
 782         * Copy exception vector code to low memory
 783         *
 784         * r3: dest_addr
 785         * r7: source address, r8: end address, r9: target address
 786         */
 787        .globl  trap_init
 788trap_init:
 789        lwz     r7, GOT(_start)
 790        lwz     r8, GOT(_end_of_vectors)
 791
 792        li      r9, 0x100               /* reset vector always at 0x100 */
 793
 794        cmplw   0, r7, r8
 795        bgelr                           /* return if r7>=r8 - just in case */
 796
 797        mflr    r4                      /* save link register           */
 7981:
 799        lwz     r0, 0(r7)
 800        stw     r0, 0(r9)
 801        addi    r7, r7, 4
 802        addi    r9, r9, 4
 803        cmplw   0, r7, r8
 804        bne     1b
 805
 806        /*
 807         * relocate `hdlr' and `int_return' entries
 808         */
 809        li      r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
 810        li      r8, Alignment - _start + EXC_OFF_SYS_RESET
 8112:
 812        bl      trap_reloc
 813        addi    r7, r7, 0x100           /* next exception vector        */
 814        cmplw   0, r7, r8
 815        blt     2b
 816
 817        li      r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
 818        bl      trap_reloc
 819
 820        li      r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
 821        bl      trap_reloc
 822
 823        li      r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
 824        li      r8, SystemCall - _start + EXC_OFF_SYS_RESET
 8253:
 826        bl      trap_reloc
 827        addi    r7, r7, 0x100           /* next exception vector        */
 828        cmplw   0, r7, r8
 829        blt     3b
 830
 831        li      r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
 832        li      r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
 8334:
 834        bl      trap_reloc
 835        addi    r7, r7, 0x100           /* next exception vector        */
 836        cmplw   0, r7, r8
 837        blt     4b
 838
 839        /* enable execptions from RAM vectors */
 840        mfmsr   r7
 841        li      r8,MSR_IP
 842        andc    r7,r7,r8
 843        ori     r7,r7,MSR_ME            /* Enable Machine Check */
 844        mtmsr   r7
 845
 846        mtlr    r4                      /* restore link register        */
 847        blr
 848
 849        /*
 850         * Function: relocate entries for one exception vector
 851         */
 852trap_reloc:
 853        lwz     r0, 0(r7)               /* hdlr ...                     */
 854        add     r0, r0, r3              /*  ... += dest_addr            */
 855        stw     r0, 0(r7)
 856
 857        lwz     r0, 4(r7)               /* int_return ...               */
 858        add     r0, r0, r3              /*  ... += dest_addr            */
 859        stw     r0, 4(r7)
 860
 861        sync
 862        isync
 863
 864        blr
 865
 866.globl enable_ext_addr
 867enable_ext_addr:
 868        mfspr   r0, HID0
 869        lis     r0, (HID0_HIGH_BAT_EN | HID0_XBSEN | HID0_XAEN)@h
 870        ori     r0, r0, (HID0_HIGH_BAT_EN | HID0_XBSEN | HID0_XAEN)@l
 871        mtspr   HID0, r0
 872        sync
 873        isync
 874        blr
 875
 876#if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR)
 877.globl setup_ccsrbar
 878setup_ccsrbar:
 879        /* Special sequence needed to update CCSRBAR itself */
 880        lis     r4, CONFIG_SYS_CCSRBAR_DEFAULT@h
 881        ori     r4, r4, CONFIG_SYS_CCSRBAR_DEFAULT@l
 882
 883        lis     r5, CONFIG_SYS_CCSRBAR_PHYS_LOW@h
 884        ori     r5, r5, CONFIG_SYS_CCSRBAR_PHYS_LOW@l
 885        srwi    r5,r5,12
 886        li      r6, CONFIG_SYS_CCSRBAR_PHYS_HIGH@l
 887        rlwimi  r5,r6,20,8,11
 888        stw     r5, 0(r4) /* Store physical value of CCSR */
 889        isync
 890
 891        lis     r5, TEXT_BASE@h
 892        ori     r5,r5,TEXT_BASE@l
 893        lwz     r5, 0(r5)
 894        isync
 895
 896        /* Use VA of CCSR to do read */
 897        lis     r3, CONFIG_SYS_CCSRBAR@h
 898        lwz     r5, CONFIG_SYS_CCSRBAR@l(r3)
 899        isync
 900
 901        blr
 902#endif
 903
 904#ifdef CONFIG_SYS_INIT_RAM_LOCK
 905lock_ram_in_cache:
 906        /* Allocate Initial RAM in data cache.
 907         */
 908        lis     r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@h
 909        ori     r3, r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@l
 910        li      r4, ((CONFIG_SYS_INIT_RAM_END & ~31) + \
 911                     (CONFIG_SYS_INIT_RAM_ADDR & 31) + 31) / 32
 912        mtctr   r4
 9131:
 914        dcbz    r0, r3
 915        addi    r3, r3, 32
 916        bdnz    1b
 917#if 1
 918/* Lock the data cache */
 919        mfspr   r0, HID0
 920        ori     r0, r0, 0x1000
 921        sync
 922        mtspr   HID0, r0
 923        sync
 924        blr
 925#endif
 926#if 0
 927        /* Lock the first way of the data cache */
 928        mfspr   r0, LDSTCR
 929        ori     r0, r0, 0x0080
 930#if defined(CONFIG_ALTIVEC)
 931        dssall
 932#endif
 933        sync
 934        mtspr   LDSTCR, r0
 935        sync
 936        isync
 937        blr
 938#endif
 939
 940.globl unlock_ram_in_cache
 941unlock_ram_in_cache:
 942        /* invalidate the INIT_RAM section */
 943        lis     r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@h
 944        ori     r3, r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@l
 945        li      r4, ((CONFIG_SYS_INIT_RAM_END & ~31) + \
 946                     (CONFIG_SYS_INIT_RAM_ADDR & 31) + 31) / 32
 947        mtctr   r4
 9481:      icbi    r0, r3
 949        addi    r3, r3, 32
 950        bdnz    1b
 951        sync                    /* Wait for all icbi to complete on bus */
 952        isync
 953#if 1
 954/* Unlock the data cache and invalidate it */
 955        mfspr   r0, HID0
 956        li      r3,0x1000
 957        andc    r0,r0,r3
 958        li      r3,0x0400
 959        or      r0,r0,r3
 960        sync
 961        mtspr   HID0, r0
 962        sync
 963        blr
 964#endif
 965#if 0
 966        /* Unlock the first way of the data cache */
 967        mfspr   r0, LDSTCR
 968        li      r3,0x0080
 969        andc    r0,r0,r3
 970#ifdef CONFIG_ALTIVEC
 971        dssall
 972#endif
 973        sync
 974        mtspr   LDSTCR, r0
 975        sync
 976        isync
 977        li      r3,0x0400
 978        or      r0,r0,r3
 979        sync
 980        mtspr   HID0, r0
 981        sync
 982        blr
 983#endif
 984#endif
 985