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