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