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