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