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 r12 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 EXC_XFER_TEMPLATE(Alignment, AlignmentException, MSR_KERNEL, COPY_EE) 125 126/* Program check exception */ 127 . = 0x700 128ProgramCheck: 129 EXCEPTION_PROLOG(SRR0, SRR1) 130 addi r3,r1,STACK_FRAME_OVERHEAD 131 EXC_XFER_TEMPLATE(ProgramCheck, ProgramCheckException, 132 MSR_KERNEL, COPY_EE) 133 134 STD_EXCEPTION(0x800, FPUnavailable, UnknownException) 135 136 /* I guess we could implement decrementer, and may have 137 * to someday for timekeeping. 138 */ 139 STD_EXCEPTION(0x900, Decrementer, timer_interrupt) 140 STD_EXCEPTION(0xa00, Trap_0a, UnknownException) 141 STD_EXCEPTION(0xb00, Trap_0b, UnknownException) 142 STD_EXCEPTION(0xc00, SystemCall, UnknownException) 143 STD_EXCEPTION(0xd00, SingleStep, UnknownException) 144 STD_EXCEPTION(0xe00, Trap_0e, UnknownException) 145 STD_EXCEPTION(0xf00, Trap_0f, UnknownException) 146 STD_EXCEPTION(0x1000, SoftEmu, SoftEmuException) 147 STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException) 148 STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException) 149 STD_EXCEPTION(0x1300, InstructionTLBError, UnknownException) 150 STD_EXCEPTION(0x1400, DataTLBError, UnknownException) 151 STD_EXCEPTION(0x1500, Reserved5, UnknownException) 152 STD_EXCEPTION(0x1600, Reserved6, UnknownException) 153 STD_EXCEPTION(0x1700, Reserved7, UnknownException) 154 STD_EXCEPTION(0x1800, Reserved8, UnknownException) 155 STD_EXCEPTION(0x1900, Reserved9, UnknownException) 156 STD_EXCEPTION(0x1a00, ReservedA, UnknownException) 157 STD_EXCEPTION(0x1b00, ReservedB, UnknownException) 158 STD_EXCEPTION(0x1c00, DataBreakpoint, UnknownException) 159 STD_EXCEPTION(0x1d00, InstructionBreakpoint, UnknownException) 160 STD_EXCEPTION(0x1e00, PeripheralBreakpoint, UnknownException) 161 STD_EXCEPTION(0x1f00, DevPortBreakpoint, UnknownException) 162 163 .globl _end_of_vectors 164_end_of_vectors: 165 166 . = 0x2000 167 168boot_cold: 169boot_warm: 170 /* 171 * NOTE: Only Cpu 0 will ever come here. Other cores go to an 172 * address specified by the BPTR 173 */ 1741: 175#ifdef CONFIG_SYS_RAMBOOT 176 /* disable everything */ 177 li r0, 0 178 mtspr HID0, r0 179 sync 180 mtmsr 0 181#endif 182 183 /* Invalidate BATs */ 184 bl invalidate_bats 185 sync 186 /* Invalidate all of TLB before MMU turn on */ 187 bl clear_tlbs 188 sync 189 190#ifdef CONFIG_SYS_L2 191 /* init the L2 cache */ 192 lis r3, L2_INIT@h 193 ori r3, r3, L2_INIT@l 194 mtspr l2cr, r3 195 /* invalidate the L2 cache */ 196 bl l2cache_invalidate 197 sync 198#endif 199 200 /* 201 * Calculate absolute address in FLASH and jump there 202 *------------------------------------------------------*/ 203 lis r3, CONFIG_SYS_MONITOR_BASE_EARLY@h 204 ori r3, r3, CONFIG_SYS_MONITOR_BASE_EARLY@l 205 addi r3, r3, in_flash - _start + EXC_OFF_SYS_RESET 206 mtlr r3 207 blr 208 209in_flash: 210 /* let the C-code set up the rest */ 211 /* */ 212 /* Be careful to keep code relocatable ! */ 213 /*------------------------------------------------------*/ 214 /* perform low-level init */ 215 216 /* enable extended addressing */ 217 bl enable_ext_addr 218 219 /* setup the bats */ 220 bl early_bats 221 222 /* 223 * Cache must be enabled here for stack-in-cache trick. 224 * This means we need to enable the BATS. 225 * Cache should be turned on after BATs, since by default 226 * everything is write-through. 227 */ 228 229 /* enable address translation */ 230 mfmsr r5 231 ori r5, r5, (MSR_IR | MSR_DR) 232 lis r3,addr_trans_enabled@h 233 ori r3, r3, addr_trans_enabled@l 234 mtspr SPRN_SRR0,r3 235 mtspr SPRN_SRR1,r5 236 rfi 237 238addr_trans_enabled: 239 /* enable and invalidate the data cache */ 240/* bl l1dcache_enable */ 241 bl dcache_enable 242 sync 243 244#if 1 245 bl icache_enable 246#endif 247 248#ifdef CONFIG_SYS_INIT_RAM_LOCK 249 bl lock_ram_in_cache 250 sync 251#endif 252 253#if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR) 254 bl setup_ccsrbar 255#endif 256 257 /* set up the stack pointer in our newly created 258 * cache-ram (r1) */ 259 lis r1, (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET)@h 260 ori r1, r1, (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET)@l 261 262 li r0, 0 /* Make room for stack frame header and */ 263 stwu r0, -4(r1) /* clear final stack frame so that */ 264 stwu r0, -4(r1) /* stack backtraces terminate cleanly */ 265 266 GET_GOT /* initialize GOT access */ 267 268 /* run low-level CPU init code (from Flash) */ 269 bl cpu_init_f 270 sync 271 272#ifdef RUN_DIAG 273 274 /* Load PX_AUX register address in r4 */ 275 lis r4, PIXIS_BASE@h 276 ori r4, r4, 0x6 277 /* Load contents of PX_AUX in r3 bits 24 to 31*/ 278 lbz r3, 0(r4) 279 280 /* Mask and obtain the bit in r3 */ 281 rlwinm. r3, r3, 0, 24, 24 282 /* If not zero, jump and continue with u-boot */ 283 bne diag_done 284 285 /* Load back contents of PX_AUX in r3 bits 24 to 31 */ 286 lbz r3, 0(r4) 287 /* Set the MSB of the register value */ 288 ori r3, r3, 0x80 289 /* Write value in r3 back to PX_AUX */ 290 stb r3, 0(r4) 291 292 /* Get the address to jump to in r3*/ 293 lis r3, CONFIG_SYS_DIAG_ADDR@h 294 ori r3, r3, CONFIG_SYS_DIAG_ADDR@l 295 296 /* Load the LR with the branch address */ 297 mtlr r3 298 299 /* Branch to diagnostic */ 300 blr 301 302diag_done: 303#endif 304 305/* bl l2cache_enable */ 306 mr r3, r21 307 308 /* r3: BOOTFLAG */ 309 /* run 1st part of board init code (from Flash) */ 310 bl board_init_f 311 sync 312 313 /* NOTREACHED */ 314 315 .globl invalidate_bats 316invalidate_bats: 317 318 li r0, 0 319 /* invalidate BATs */ 320 mtspr IBAT0U, r0 321 mtspr IBAT1U, r0 322 mtspr IBAT2U, r0 323 mtspr IBAT3U, r0 324 mtspr IBAT4U, r0 325 mtspr IBAT5U, r0 326 mtspr IBAT6U, r0 327 mtspr IBAT7U, r0 328 329 isync 330 mtspr DBAT0U, r0 331 mtspr DBAT1U, r0 332 mtspr DBAT2U, r0 333 mtspr DBAT3U, r0 334 mtspr DBAT4U, r0 335 mtspr DBAT5U, r0 336 mtspr DBAT6U, r0 337 mtspr DBAT7U, r0 338 339 isync 340 sync 341 blr 342 343/* 344 * early_bats: 345 * 346 * Set up bats needed early on - this is usually the BAT for the 347 * stack-in-cache, the Flash, and CCSR space 348 */ 349 .globl early_bats 350early_bats: 351 /* IBAT 3 */ 352 lis r4, CONFIG_SYS_IBAT3L@h 353 ori r4, r4, CONFIG_SYS_IBAT3L@l 354 lis r3, CONFIG_SYS_IBAT3U@h 355 ori r3, r3, CONFIG_SYS_IBAT3U@l 356 mtspr IBAT3L, r4 357 mtspr IBAT3U, r3 358 isync 359 360 /* DBAT 3 */ 361 lis r4, CONFIG_SYS_DBAT3L@h 362 ori r4, r4, CONFIG_SYS_DBAT3L@l 363 lis r3, CONFIG_SYS_DBAT3U@h 364 ori r3, r3, CONFIG_SYS_DBAT3U@l 365 mtspr DBAT3L, r4 366 mtspr DBAT3U, r3 367 isync 368 369 /* IBAT 5 */ 370 lis r4, CONFIG_SYS_IBAT5L@h 371 ori r4, r4, CONFIG_SYS_IBAT5L@l 372 lis r3, CONFIG_SYS_IBAT5U@h 373 ori r3, r3, CONFIG_SYS_IBAT5U@l 374 mtspr IBAT5L, r4 375 mtspr IBAT5U, r3 376 isync 377 378 /* DBAT 5 */ 379 lis r4, CONFIG_SYS_DBAT5L@h 380 ori r4, r4, CONFIG_SYS_DBAT5L@l 381 lis r3, CONFIG_SYS_DBAT5U@h 382 ori r3, r3, CONFIG_SYS_DBAT5U@l 383 mtspr DBAT5L, r4 384 mtspr DBAT5U, r3 385 isync 386 387 /* IBAT 6 */ 388 lis r4, CONFIG_SYS_IBAT6L_EARLY@h 389 ori r4, r4, CONFIG_SYS_IBAT6L_EARLY@l 390 lis r3, CONFIG_SYS_IBAT6U_EARLY@h 391 ori r3, r3, CONFIG_SYS_IBAT6U_EARLY@l 392 mtspr IBAT6L, r4 393 mtspr IBAT6U, r3 394 isync 395 396 /* DBAT 6 */ 397 lis r4, CONFIG_SYS_DBAT6L_EARLY@h 398 ori r4, r4, CONFIG_SYS_DBAT6L_EARLY@l 399 lis r3, CONFIG_SYS_DBAT6U_EARLY@h 400 ori r3, r3, CONFIG_SYS_DBAT6U_EARLY@l 401 mtspr DBAT6L, r4 402 mtspr DBAT6U, r3 403 isync 404 405#if(CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR) 406 /* IBAT 7 */ 407 lis r4, CONFIG_SYS_CCSR_DEFAULT_IBATL@h 408 ori r4, r4, CONFIG_SYS_CCSR_DEFAULT_IBATL@l 409 lis r3, CONFIG_SYS_CCSR_DEFAULT_IBATU@h 410 ori r3, r3, CONFIG_SYS_CCSR_DEFAULT_IBATU@l 411 mtspr IBAT7L, r4 412 mtspr IBAT7U, r3 413 isync 414 415 /* DBAT 7 */ 416 lis r4, CONFIG_SYS_CCSR_DEFAULT_DBATL@h 417 ori r4, r4, CONFIG_SYS_CCSR_DEFAULT_DBATL@l 418 lis r3, CONFIG_SYS_CCSR_DEFAULT_DBATU@h 419 ori r3, r3, CONFIG_SYS_CCSR_DEFAULT_DBATU@l 420 mtspr DBAT7L, r4 421 mtspr DBAT7U, r3 422 isync 423#endif 424 blr 425 426 .globl clear_tlbs 427clear_tlbs: 428 addis r3, 0, 0x0000 429 addis r5, 0, 0x4 430 isync 431tlblp: 432 tlbie r3 433 sync 434 addi r3, r3, 0x1000 435 cmp 0, 0, r3, r5 436 blt tlblp 437 blr 438 439 .globl disable_addr_trans 440disable_addr_trans: 441 /* disable address translation */ 442 mflr r4 443 mfmsr r3 444 andi. r0, r3, (MSR_IR | MSR_DR) 445 beqlr 446 andc r3, r3, r0 447 mtspr SRR0, r4 448 mtspr SRR1, r3 449 rfi 450 451/* 452 * This code finishes saving the registers to the exception frame 453 * and jumps to the appropriate handler for the exception. 454 * Register r21 is pointer into trap frame, r1 has new stack pointer. 455 */ 456 .globl transfer_to_handler 457transfer_to_handler: 458 stw r22,_NIP(r21) 459 lis r22,MSR_POW@h 460 andc r23,r23,r22 461 stw r23,_MSR(r21) 462 SAVE_GPR(7, r21) 463 SAVE_4GPRS(8, r21) 464 SAVE_8GPRS(12, r21) 465 SAVE_8GPRS(24, r21) 466 mflr r23 467 andi. r24,r23,0x3f00 /* get vector offset */ 468 stw r24,TRAP(r21) 469 li r22,0 470 stw r22,RESULT(r21) 471 mtspr SPRG2,r22 /* r1 is now kernel sp */ 472 lwz r24,0(r23) /* virtual address of handler */ 473 lwz r23,4(r23) /* where to go when done */ 474 mtspr SRR0,r24 475 mtspr SRR1,r20 476 mtlr r23 477 SYNC 478 rfi /* jump to handler, enable MMU */ 479 480int_return: 481 mfmsr r28 /* Disable interrupts */ 482 li r4,0 483 ori r4,r4,MSR_EE 484 andc r28,r28,r4 485 SYNC /* Some chip revs need this... */ 486 mtmsr r28 487 SYNC 488 lwz r2,_CTR(r1) 489 lwz r0,_LINK(r1) 490 mtctr r2 491 mtlr r0 492 lwz r2,_XER(r1) 493 lwz r0,_CCR(r1) 494 mtspr XER,r2 495 mtcrf 0xFF,r0 496 REST_10GPRS(3, r1) 497 REST_10GPRS(13, r1) 498 REST_8GPRS(23, r1) 499 REST_GPR(31, r1) 500 lwz r2,_NIP(r1) /* Restore environment */ 501 lwz r0,_MSR(r1) 502 mtspr SRR0,r2 503 mtspr SRR1,r0 504 lwz r0,GPR0(r1) 505 lwz r2,GPR2(r1) 506 lwz r1,GPR1(r1) 507 SYNC 508 rfi 509 510 .globl dc_read 511dc_read: 512 blr 513 514 .globl get_pvr 515get_pvr: 516 mfspr r3, PVR 517 blr 518 519 .globl get_svr 520get_svr: 521 mfspr r3, SVR 522 blr 523 524 525/* 526 * Function: in8 527 * Description: Input 8 bits 528 */ 529 .globl in8 530in8: 531 lbz r3,0x0000(r3) 532 blr 533 534/* 535 * Function: out8 536 * Description: Output 8 bits 537 */ 538 .globl out8 539out8: 540 stb r4,0x0000(r3) 541 blr 542 543/* 544 * Function: out16 545 * Description: Output 16 bits 546 */ 547 .globl out16 548out16: 549 sth r4,0x0000(r3) 550 blr 551 552/* 553 * Function: out16r 554 * Description: Byte reverse and output 16 bits 555 */ 556 .globl out16r 557out16r: 558 sthbrx r4,r0,r3 559 blr 560 561/* 562 * Function: out32 563 * Description: Output 32 bits 564 */ 565 .globl out32 566out32: 567 stw r4,0x0000(r3) 568 blr 569 570/* 571 * Function: out32r 572 * Description: Byte reverse and output 32 bits 573 */ 574 .globl out32r 575out32r: 576 stwbrx r4,r0,r3 577 blr 578 579/* 580 * Function: in16 581 * Description: Input 16 bits 582 */ 583 .globl in16 584in16: 585 lhz r3,0x0000(r3) 586 blr 587 588/* 589 * Function: in16r 590 * Description: Input 16 bits and byte reverse 591 */ 592 .globl in16r 593in16r: 594 lhbrx r3,r0,r3 595 blr 596 597/* 598 * Function: in32 599 * Description: Input 32 bits 600 */ 601 .globl in32 602in32: 603 lwz 3,0x0000(3) 604 blr 605 606/* 607 * Function: in32r 608 * Description: Input 32 bits and byte reverse 609 */ 610 .globl in32r 611in32r: 612 lwbrx r3,r0,r3 613 blr 614 615/* 616 * void relocate_code (addr_sp, gd, addr_moni) 617 * 618 * This "function" does not return, instead it continues in RAM 619 * after relocating the monitor code. 620 * 621 * r3 = dest 622 * r4 = src 623 * r5 = length in bytes 624 * r6 = cachelinesize 625 */ 626 .globl relocate_code 627relocate_code: 628 629 mr r1, r3 /* Set new stack pointer */ 630 mr r9, r4 /* Save copy of Global Data pointer */ 631 mr r10, r5 /* Save copy of Destination Address */ 632 633 GET_GOT 634 mr r3, r5 /* Destination Address */ 635 lis r4, CONFIG_SYS_MONITOR_BASE@h /* Source Address */ 636 ori r4, r4, CONFIG_SYS_MONITOR_BASE@l 637 lwz r5, GOT(__init_end) 638 sub r5, r5, r4 639 li r6, CONFIG_SYS_CACHELINE_SIZE /* Cache Line Size */ 640 641 /* 642 * Fix GOT pointer: 643 * 644 * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address 645 * 646 * Offset: 647 */ 648 sub r15, r10, r4 649 650 /* First our own GOT */ 651 add r12, r12, r15 652 /* then the one used by the C code */ 653 add r30, r30, r15 654 655 /* 656 * Now relocate code 657 */ 658 cmplw cr1,r3,r4 659 addi r0,r5,3 660 srwi. r0,r0,2 661 beq cr1,4f /* In place copy is not necessary */ 662 beq 7f /* Protect against 0 count */ 663 mtctr r0 664 bge cr1,2f 665 666 la r8,-4(r4) 667 la r7,-4(r3) 6681: lwzu r0,4(r8) 669 stwu r0,4(r7) 670 bdnz 1b 671 b 4f 672 6732: slwi r0,r0,2 674 add r8,r4,r0 675 add r7,r3,r0 6763: lwzu r0,-4(r8) 677 stwu r0,-4(r7) 678 bdnz 3b 679/* 680 * Now flush the cache: note that we must start from a cache aligned 681 * address. Otherwise we might miss one cache line. 682 */ 6834: cmpwi r6,0 684 add r5,r3,r5 685 beq 7f /* Always flush prefetch queue in any case */ 686 subi r0,r6,1 687 andc r3,r3,r0 688 mr r4,r3 6895: dcbst 0,r4 690 add r4,r4,r6 691 cmplw r4,r5 692 blt 5b 693 sync /* Wait for all dcbst to complete on bus */ 694 mr r4,r3 6956: icbi 0,r4 696 add r4,r4,r6 697 cmplw r4,r5 698 blt 6b 6997: sync /* Wait for all icbi to complete on bus */ 700 isync 701 702/* 703 * We are done. Do not return, instead branch to second part of board 704 * initialization, now running from RAM. 705 */ 706 addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET 707 mtlr r0 708 blr 709 710in_ram: 711 /* 712 * Relocation Function, r12 point to got2+0x8000 713 * 714 * Adjust got2 pointers, no need to check for 0, this code 715 * already puts a few entries in the table. 716 */ 717 li r0,__got2_entries@sectoff@l 718 la r3,GOT(_GOT2_TABLE_) 719 lwz r11,GOT(_GOT2_TABLE_) 720 mtctr r0 721 sub r11,r3,r11 722 addi r3,r3,-4 7231: lwzu r0,4(r3) 724 cmpwi r0,0 725 beq- 2f 726 add r0,r0,r11 727 stw r0,0(r3) 7282: bdnz 1b 729 730 /* 731 * Now adjust the fixups and the pointers to the fixups 732 * in case we need to move ourselves again. 733 */ 734 li r0,__fixup_entries@sectoff@l 735 lwz r3,GOT(_FIXUP_TABLE_) 736 cmpwi r0,0 737 mtctr r0 738 addi r3,r3,-4 739 beq 4f 7403: lwzu r4,4(r3) 741 lwzux r0,r4,r11 742 add r0,r0,r11 743 stw r10,0(r3) 744 stw r0,0(r4) 745 bdnz 3b 7464: 747/* clear_bss: */ 748 /* 749 * Now clear BSS segment 750 */ 751 lwz r3,GOT(__bss_start) 752 lwz r4,GOT(_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, TEXT_BASE@h 865 ori r5,r5,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_END & ~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_END & ~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