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 259 /* run low-level CPU init code (from Flash) */ 260 bl cpu_init_f 261 sync 262 263#ifdef RUN_DIAG 264 265 /* Load PX_AUX register address in r4 */ 266 lis r4, PIXIS_BASE@h 267 ori r4, r4, 0x6 268 /* Load contents of PX_AUX in r3 bits 24 to 31*/ 269 lbz r3, 0(r4) 270 271 /* Mask and obtain the bit in r3 */ 272 rlwinm. r3, r3, 0, 24, 24 273 /* If not zero, jump and continue with u-boot */ 274 bne diag_done 275 276 /* Load back contents of PX_AUX in r3 bits 24 to 31 */ 277 lbz r3, 0(r4) 278 /* Set the MSB of the register value */ 279 ori r3, r3, 0x80 280 /* Write value in r3 back to PX_AUX */ 281 stb r3, 0(r4) 282 283 /* Get the address to jump to in r3*/ 284 lis r3, CONFIG_SYS_DIAG_ADDR@h 285 ori r3, r3, CONFIG_SYS_DIAG_ADDR@l 286 287 /* Load the LR with the branch address */ 288 mtlr r3 289 290 /* Branch to diagnostic */ 291 blr 292 293diag_done: 294#endif 295 296/* bl l2cache_enable */ 297 298 /* run 1st part of board init code (from Flash) */ 299 bl board_init_f 300 sync 301 302 /* NOTREACHED - board_init_f() does not return */ 303 304 .globl invalidate_bats 305invalidate_bats: 306 307 li r0, 0 308 /* invalidate BATs */ 309 mtspr IBAT0U, r0 310 mtspr IBAT1U, r0 311 mtspr IBAT2U, r0 312 mtspr IBAT3U, r0 313 mtspr IBAT4U, r0 314 mtspr IBAT5U, r0 315 mtspr IBAT6U, r0 316 mtspr IBAT7U, r0 317 318 isync 319 mtspr DBAT0U, r0 320 mtspr DBAT1U, r0 321 mtspr DBAT2U, r0 322 mtspr DBAT3U, r0 323 mtspr DBAT4U, r0 324 mtspr DBAT5U, r0 325 mtspr DBAT6U, r0 326 mtspr DBAT7U, r0 327 328 isync 329 sync 330 blr 331 332/* 333 * early_bats: 334 * 335 * Set up bats needed early on - this is usually the BAT for the 336 * stack-in-cache, the Flash, and CCSR space 337 */ 338 .globl early_bats 339early_bats: 340 /* IBAT 3 */ 341 lis r4, CONFIG_SYS_IBAT3L@h 342 ori r4, r4, CONFIG_SYS_IBAT3L@l 343 lis r3, CONFIG_SYS_IBAT3U@h 344 ori r3, r3, CONFIG_SYS_IBAT3U@l 345 mtspr IBAT3L, r4 346 mtspr IBAT3U, r3 347 isync 348 349 /* DBAT 3 */ 350 lis r4, CONFIG_SYS_DBAT3L@h 351 ori r4, r4, CONFIG_SYS_DBAT3L@l 352 lis r3, CONFIG_SYS_DBAT3U@h 353 ori r3, r3, CONFIG_SYS_DBAT3U@l 354 mtspr DBAT3L, r4 355 mtspr DBAT3U, r3 356 isync 357 358 /* IBAT 5 */ 359 lis r4, CONFIG_SYS_IBAT5L@h 360 ori r4, r4, CONFIG_SYS_IBAT5L@l 361 lis r3, CONFIG_SYS_IBAT5U@h 362 ori r3, r3, CONFIG_SYS_IBAT5U@l 363 mtspr IBAT5L, r4 364 mtspr IBAT5U, r3 365 isync 366 367 /* DBAT 5 */ 368 lis r4, CONFIG_SYS_DBAT5L@h 369 ori r4, r4, CONFIG_SYS_DBAT5L@l 370 lis r3, CONFIG_SYS_DBAT5U@h 371 ori r3, r3, CONFIG_SYS_DBAT5U@l 372 mtspr DBAT5L, r4 373 mtspr DBAT5U, r3 374 isync 375 376 /* IBAT 6 */ 377 lis r4, CONFIG_SYS_IBAT6L_EARLY@h 378 ori r4, r4, CONFIG_SYS_IBAT6L_EARLY@l 379 lis r3, CONFIG_SYS_IBAT6U_EARLY@h 380 ori r3, r3, CONFIG_SYS_IBAT6U_EARLY@l 381 mtspr IBAT6L, r4 382 mtspr IBAT6U, r3 383 isync 384 385 /* DBAT 6 */ 386 lis r4, CONFIG_SYS_DBAT6L_EARLY@h 387 ori r4, r4, CONFIG_SYS_DBAT6L_EARLY@l 388 lis r3, CONFIG_SYS_DBAT6U_EARLY@h 389 ori r3, r3, CONFIG_SYS_DBAT6U_EARLY@l 390 mtspr DBAT6L, r4 391 mtspr DBAT6U, r3 392 isync 393 394#if(CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR) 395 /* IBAT 7 */ 396 lis r4, CONFIG_SYS_CCSR_DEFAULT_IBATL@h 397 ori r4, r4, CONFIG_SYS_CCSR_DEFAULT_IBATL@l 398 lis r3, CONFIG_SYS_CCSR_DEFAULT_IBATU@h 399 ori r3, r3, CONFIG_SYS_CCSR_DEFAULT_IBATU@l 400 mtspr IBAT7L, r4 401 mtspr IBAT7U, r3 402 isync 403 404 /* DBAT 7 */ 405 lis r4, CONFIG_SYS_CCSR_DEFAULT_DBATL@h 406 ori r4, r4, CONFIG_SYS_CCSR_DEFAULT_DBATL@l 407 lis r3, CONFIG_SYS_CCSR_DEFAULT_DBATU@h 408 ori r3, r3, CONFIG_SYS_CCSR_DEFAULT_DBATU@l 409 mtspr DBAT7L, r4 410 mtspr DBAT7U, r3 411 isync 412#endif 413 blr 414 415 .globl clear_tlbs 416clear_tlbs: 417 addis r3, 0, 0x0000 418 addis r5, 0, 0x4 419 isync 420tlblp: 421 tlbie r3 422 sync 423 addi r3, r3, 0x1000 424 cmp 0, 0, r3, r5 425 blt tlblp 426 blr 427 428 .globl disable_addr_trans 429disable_addr_trans: 430 /* disable address translation */ 431 mflr r4 432 mfmsr r3 433 andi. r0, r3, (MSR_IR | MSR_DR) 434 beqlr 435 andc r3, r3, r0 436 mtspr SRR0, r4 437 mtspr SRR1, r3 438 rfi 439 440/* 441 * This code finishes saving the registers to the exception frame 442 * and jumps to the appropriate handler for the exception. 443 * Register r21 is pointer into trap frame, r1 has new stack pointer. 444 */ 445 .globl transfer_to_handler 446transfer_to_handler: 447 stw r22,_NIP(r21) 448 lis r22,MSR_POW@h 449 andc r23,r23,r22 450 stw r23,_MSR(r21) 451 SAVE_GPR(7, r21) 452 SAVE_4GPRS(8, r21) 453 SAVE_8GPRS(12, r21) 454 SAVE_8GPRS(24, r21) 455 mflr r23 456 andi. r24,r23,0x3f00 /* get vector offset */ 457 stw r24,TRAP(r21) 458 li r22,0 459 stw r22,RESULT(r21) 460 mtspr SPRG2,r22 /* r1 is now kernel sp */ 461 lwz r24,0(r23) /* virtual address of handler */ 462 lwz r23,4(r23) /* where to go when done */ 463 mtspr SRR0,r24 464 mtspr SRR1,r20 465 mtlr r23 466 SYNC 467 rfi /* jump to handler, enable MMU */ 468 469int_return: 470 mfmsr r28 /* Disable interrupts */ 471 li r4,0 472 ori r4,r4,MSR_EE 473 andc r28,r28,r4 474 SYNC /* Some chip revs need this... */ 475 mtmsr r28 476 SYNC 477 lwz r2,_CTR(r1) 478 lwz r0,_LINK(r1) 479 mtctr r2 480 mtlr r0 481 lwz r2,_XER(r1) 482 lwz r0,_CCR(r1) 483 mtspr XER,r2 484 mtcrf 0xFF,r0 485 REST_10GPRS(3, r1) 486 REST_10GPRS(13, r1) 487 REST_8GPRS(23, r1) 488 REST_GPR(31, r1) 489 lwz r2,_NIP(r1) /* Restore environment */ 490 lwz r0,_MSR(r1) 491 mtspr SRR0,r2 492 mtspr SRR1,r0 493 lwz r0,GPR0(r1) 494 lwz r2,GPR2(r1) 495 lwz r1,GPR1(r1) 496 SYNC 497 rfi 498 499 .globl dc_read 500dc_read: 501 blr 502 503 .globl get_pvr 504get_pvr: 505 mfspr r3, PVR 506 blr 507 508 .globl get_svr 509get_svr: 510 mfspr r3, SVR 511 blr 512 513 514/* 515 * Function: in8 516 * Description: Input 8 bits 517 */ 518 .globl in8 519in8: 520 lbz r3,0x0000(r3) 521 blr 522 523/* 524 * Function: out8 525 * Description: Output 8 bits 526 */ 527 .globl out8 528out8: 529 stb r4,0x0000(r3) 530 blr 531 532/* 533 * Function: out16 534 * Description: Output 16 bits 535 */ 536 .globl out16 537out16: 538 sth r4,0x0000(r3) 539 blr 540 541/* 542 * Function: out16r 543 * Description: Byte reverse and output 16 bits 544 */ 545 .globl out16r 546out16r: 547 sthbrx r4,r0,r3 548 blr 549 550/* 551 * Function: out32 552 * Description: Output 32 bits 553 */ 554 .globl out32 555out32: 556 stw r4,0x0000(r3) 557 blr 558 559/* 560 * Function: out32r 561 * Description: Byte reverse and output 32 bits 562 */ 563 .globl out32r 564out32r: 565 stwbrx r4,r0,r3 566 blr 567 568/* 569 * Function: in16 570 * Description: Input 16 bits 571 */ 572 .globl in16 573in16: 574 lhz r3,0x0000(r3) 575 blr 576 577/* 578 * Function: in16r 579 * Description: Input 16 bits and byte reverse 580 */ 581 .globl in16r 582in16r: 583 lhbrx r3,r0,r3 584 blr 585 586/* 587 * Function: in32 588 * Description: Input 32 bits 589 */ 590 .globl in32 591in32: 592 lwz 3,0x0000(3) 593 blr 594 595/* 596 * Function: in32r 597 * Description: Input 32 bits and byte reverse 598 */ 599 .globl in32r 600in32r: 601 lwbrx r3,r0,r3 602 blr 603 604/* 605 * void relocate_code (addr_sp, gd, addr_moni) 606 * 607 * This "function" does not return, instead it continues in RAM 608 * after relocating the monitor code. 609 * 610 * r3 = dest 611 * r4 = src 612 * r5 = length in bytes 613 * r6 = cachelinesize 614 */ 615 .globl relocate_code 616relocate_code: 617 618 mr r1, r3 /* Set new stack pointer */ 619 mr r9, r4 /* Save copy of Global Data pointer */ 620 mr r10, r5 /* Save copy of Destination Address */ 621 622 GET_GOT 623 mr r3, r5 /* Destination Address */ 624 lis r4, CONFIG_SYS_MONITOR_BASE@h /* Source Address */ 625 ori r4, r4, CONFIG_SYS_MONITOR_BASE@l 626 lwz r5, GOT(__init_end) 627 sub r5, r5, r4 628 li r6, CONFIG_SYS_CACHELINE_SIZE /* Cache Line Size */ 629 630 /* 631 * Fix GOT pointer: 632 * 633 * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address 634 * 635 * Offset: 636 */ 637 sub r15, r10, r4 638 639 /* First our own GOT */ 640 add r12, r12, r15 641 /* then the one used by the C code */ 642 add r30, r30, r15 643 644 /* 645 * Now relocate code 646 */ 647 cmplw cr1,r3,r4 648 addi r0,r5,3 649 srwi. r0,r0,2 650 beq cr1,4f /* In place copy is not necessary */ 651 beq 7f /* Protect against 0 count */ 652 mtctr r0 653 bge cr1,2f 654 655 la r8,-4(r4) 656 la r7,-4(r3) 6571: lwzu r0,4(r8) 658 stwu r0,4(r7) 659 bdnz 1b 660 b 4f 661 6622: slwi r0,r0,2 663 add r8,r4,r0 664 add r7,r3,r0 6653: lwzu r0,-4(r8) 666 stwu r0,-4(r7) 667 bdnz 3b 668/* 669 * Now flush the cache: note that we must start from a cache aligned 670 * address. Otherwise we might miss one cache line. 671 */ 6724: cmpwi r6,0 673 add r5,r3,r5 674 beq 7f /* Always flush prefetch queue in any case */ 675 subi r0,r6,1 676 andc r3,r3,r0 677 mr r4,r3 6785: dcbst 0,r4 679 add r4,r4,r6 680 cmplw r4,r5 681 blt 5b 682 sync /* Wait for all dcbst to complete on bus */ 683 mr r4,r3 6846: icbi 0,r4 685 add r4,r4,r6 686 cmplw r4,r5 687 blt 6b 6887: sync /* Wait for all icbi to complete on bus */ 689 isync 690 691/* 692 * We are done. Do not return, instead branch to second part of board 693 * initialization, now running from RAM. 694 */ 695 addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET 696 mtlr r0 697 blr 698 699in_ram: 700 /* 701 * Relocation Function, r12 point to got2+0x8000 702 * 703 * Adjust got2 pointers, no need to check for 0, this code 704 * already puts a few entries in the table. 705 */ 706 li r0,__got2_entries@sectoff@l 707 la r3,GOT(_GOT2_TABLE_) 708 lwz r11,GOT(_GOT2_TABLE_) 709 mtctr r0 710 sub r11,r3,r11 711 addi r3,r3,-4 7121: lwzu r0,4(r3) 713 cmpwi r0,0 714 beq- 2f 715 add r0,r0,r11 716 stw r0,0(r3) 7172: bdnz 1b 718 719 /* 720 * Now adjust the fixups and the pointers to the fixups 721 * in case we need to move ourselves again. 722 */ 723 li r0,__fixup_entries@sectoff@l 724 lwz r3,GOT(_FIXUP_TABLE_) 725 cmpwi r0,0 726 mtctr r0 727 addi r3,r3,-4 728 beq 4f 7293: lwzu r4,4(r3) 730 lwzux r0,r4,r11 731 cmpwi r0,0 732 add r0,r0,r11 733 stw r4,0(r3) 734 beq- 5f 735 stw r0,0(r4) 7365: bdnz 3b 7374: 738/* clear_bss: */ 739 /* 740 * Now clear BSS segment 741 */ 742 lwz r3,GOT(__bss_start) 743 lwz r4,GOT(__bss_end__) 744 745 cmplw 0, r3, r4 746 beq 6f 747 748 li r0, 0 7495: 750 stw r0, 0(r3) 751 addi r3, r3, 4 752 cmplw 0, r3, r4 753 bne 5b 7546: 755 mr r3, r9 /* Init Date pointer */ 756 mr r4, r10 /* Destination Address */ 757 bl board_init_r 758 759 /* not reached - end relocate_code */ 760/*-----------------------------------------------------------------------*/ 761 762 /* 763 * Copy exception vector code to low memory 764 * 765 * r3: dest_addr 766 * r7: source address, r8: end address, r9: target address 767 */ 768 .globl trap_init 769trap_init: 770 mflr r4 /* save link register */ 771 GET_GOT 772 lwz r7, GOT(_start) 773 lwz r8, GOT(_end_of_vectors) 774 775 li r9, 0x100 /* reset vector always at 0x100 */ 776 777 cmplw 0, r7, r8 778 bgelr /* return if r7>=r8 - just in case */ 7791: 780 lwz r0, 0(r7) 781 stw r0, 0(r9) 782 addi r7, r7, 4 783 addi r9, r9, 4 784 cmplw 0, r7, r8 785 bne 1b 786 787 /* 788 * relocate `hdlr' and `int_return' entries 789 */ 790 li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET 791 li r8, Alignment - _start + EXC_OFF_SYS_RESET 7922: 793 bl trap_reloc 794 addi r7, r7, 0x100 /* next exception vector */ 795 cmplw 0, r7, r8 796 blt 2b 797 798 li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET 799 bl trap_reloc 800 801 li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET 802 bl trap_reloc 803 804 li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET 805 li r8, SystemCall - _start + EXC_OFF_SYS_RESET 8063: 807 bl trap_reloc 808 addi r7, r7, 0x100 /* next exception vector */ 809 cmplw 0, r7, r8 810 blt 3b 811 812 li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET 813 li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET 8144: 815 bl trap_reloc 816 addi r7, r7, 0x100 /* next exception vector */ 817 cmplw 0, r7, r8 818 blt 4b 819 820 /* enable execptions from RAM vectors */ 821 mfmsr r7 822 li r8,MSR_IP 823 andc r7,r7,r8 824 ori r7,r7,MSR_ME /* Enable Machine Check */ 825 mtmsr r7 826 827 mtlr r4 /* restore link register */ 828 blr 829 830.globl enable_ext_addr 831enable_ext_addr: 832 mfspr r0, HID0 833 lis r0, (HID0_HIGH_BAT_EN | HID0_XBSEN | HID0_XAEN)@h 834 ori r0, r0, (HID0_HIGH_BAT_EN | HID0_XBSEN | HID0_XAEN)@l 835 mtspr HID0, r0 836 sync 837 isync 838 blr 839 840#if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR) 841.globl setup_ccsrbar 842setup_ccsrbar: 843 /* Special sequence needed to update CCSRBAR itself */ 844 lis r4, CONFIG_SYS_CCSRBAR_DEFAULT@h 845 ori r4, r4, CONFIG_SYS_CCSRBAR_DEFAULT@l 846 847 lis r5, CONFIG_SYS_CCSRBAR_PHYS_LOW@h 848 ori r5, r5, CONFIG_SYS_CCSRBAR_PHYS_LOW@l 849 srwi r5,r5,12 850 li r6, CONFIG_SYS_CCSRBAR_PHYS_HIGH@l 851 rlwimi r5,r6,20,8,11 852 stw r5, 0(r4) /* Store physical value of CCSR */ 853 isync 854 855 lis r5, CONFIG_SYS_TEXT_BASE@h 856 ori r5,r5,CONFIG_SYS_TEXT_BASE@l 857 lwz r5, 0(r5) 858 isync 859 860 /* Use VA of CCSR to do read */ 861 lis r3, CONFIG_SYS_CCSRBAR@h 862 lwz r5, CONFIG_SYS_CCSRBAR@l(r3) 863 isync 864 865 blr 866#endif 867 868#ifdef CONFIG_SYS_INIT_RAM_LOCK 869lock_ram_in_cache: 870 /* Allocate Initial RAM in data cache. 871 */ 872 lis r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@h 873 ori r3, r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@l 874 li r4, ((CONFIG_SYS_INIT_RAM_SIZE & ~31) + \ 875 (CONFIG_SYS_INIT_RAM_ADDR & 31) + 31) / 32 876 mtctr r4 8771: 878 dcbz r0, r3 879 addi r3, r3, 32 880 bdnz 1b 881#if 1 882/* Lock the data cache */ 883 mfspr r0, HID0 884 ori r0, r0, 0x1000 885 sync 886 mtspr HID0, r0 887 sync 888 blr 889#endif 890#if 0 891 /* Lock the first way of the data cache */ 892 mfspr r0, LDSTCR 893 ori r0, r0, 0x0080 894#if defined(CONFIG_ALTIVEC) 895 dssall 896#endif 897 sync 898 mtspr LDSTCR, r0 899 sync 900 isync 901 blr 902#endif 903 904.globl unlock_ram_in_cache 905unlock_ram_in_cache: 906 /* invalidate the INIT_RAM section */ 907 lis r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@h 908 ori r3, r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@l 909 li r4, ((CONFIG_SYS_INIT_RAM_SIZE & ~31) + \ 910 (CONFIG_SYS_INIT_RAM_ADDR & 31) + 31) / 32 911 mtctr r4 9121: icbi r0, r3 913 addi r3, r3, 32 914 bdnz 1b 915 sync /* Wait for all icbi to complete on bus */ 916 isync 917#if 1 918/* Unlock the data cache and invalidate it */ 919 mfspr r0, HID0 920 li r3,0x1000 921 andc r0,r0,r3 922 li r3,0x0400 923 or r0,r0,r3 924 sync 925 mtspr HID0, r0 926 sync 927 blr 928#endif 929#if 0 930 /* Unlock the first way of the data cache */ 931 mfspr r0, LDSTCR 932 li r3,0x0080 933 andc r0,r0,r3 934#ifdef CONFIG_ALTIVEC 935 dssall 936#endif 937 sync 938 mtspr LDSTCR, r0 939 sync 940 isync 941 li r3,0x0400 942 or r0,r0,r3 943 sync 944 mtspr HID0, r0 945 sync 946 blr 947#endif 948#endif 949