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