1/* SPDX-License-Identifier: GPL-2.0+ */ 2/* 3 * Copyright 2004, 2007, 2011 Freescale Semiconductor. 4 * Srikanth Srinivasan <srikanth.srinivaan@freescale.com> 5 */ 6 7/* U-Boot - Startup Code for 86xx PowerPC based Embedded Boards 8 * 9 * 10 * The processor starts at 0xfff00100 and the code is executed 11 * from flash. The code is organized to be at an other address 12 * in memory, but as long we don't jump around before relocating. 13 * board_init lies at a quite high address and when the cpu has 14 * jumped there, everything is ok. 15 */ 16#include <asm-offsets.h> 17#include <config.h> 18#include <mpc86xx.h> 19#include <version.h> 20 21#include <ppc_asm.tmpl> 22#include <ppc_defs.h> 23 24#include <asm/cache.h> 25#include <asm/mmu.h> 26#include <asm/u-boot.h> 27 28/* 29 * Need MSR_DR | MSR_IR enabled to access I/O (printf) in exceptions 30 */ 31 32/* 33 * Set up GOT: Global Offset Table 34 * 35 * Use r12 to access the GOT 36 */ 37 START_GOT 38 GOT_ENTRY(_GOT2_TABLE_) 39 GOT_ENTRY(_FIXUP_TABLE_) 40 41 GOT_ENTRY(_start) 42 GOT_ENTRY(_start_of_vectors) 43 GOT_ENTRY(_end_of_vectors) 44 GOT_ENTRY(transfer_to_handler) 45 46 GOT_ENTRY(__init_end) 47 GOT_ENTRY(__bss_end) 48 GOT_ENTRY(__bss_start) 49 END_GOT 50 51/* 52 * r3 - 1st arg to board_init(): IMMP pointer 53 * r4 - 2nd arg to board_init(): boot flag 54 */ 55 .text 56 .long 0x27051956 /* U-Boot Magic Number */ 57 .globl version_string 58version_string: 59 .ascii U_BOOT_VERSION_STRING, "\0" 60 61 . = EXC_OFF_SYS_RESET 62 .globl _start 63_start: 64 b boot_cold 65 66 /* the boot code is located below the exception table */ 67 68 .globl _start_of_vectors 69_start_of_vectors: 70 71/* Machine check */ 72 STD_EXCEPTION(0x200, MachineCheck, MachineCheckException) 73 74/* Data Storage exception. */ 75 STD_EXCEPTION(0x300, DataStorage, UnknownException) 76 77/* Instruction Storage exception. */ 78 STD_EXCEPTION(0x400, InstStorage, UnknownException) 79 80/* External Interrupt exception. */ 81 STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt) 82 83/* Alignment exception. */ 84 . = 0x600 85Alignment: 86 EXCEPTION_PROLOG(SRR0, SRR1) 87 mfspr r4,DAR 88 stw r4,_DAR(r21) 89 mfspr r5,DSISR 90 stw r5,_DSISR(r21) 91 addi r3,r1,STACK_FRAME_OVERHEAD 92 EXC_XFER_TEMPLATE(Alignment, AlignmentException, MSR_KERNEL, COPY_EE) 93 94/* Program check exception */ 95 . = 0x700 96ProgramCheck: 97 EXCEPTION_PROLOG(SRR0, SRR1) 98 addi r3,r1,STACK_FRAME_OVERHEAD 99 EXC_XFER_TEMPLATE(ProgramCheck, ProgramCheckException, 100 MSR_KERNEL, COPY_EE) 101 102 STD_EXCEPTION(0x800, FPUnavailable, UnknownException) 103 104 /* I guess we could implement decrementer, and may have 105 * to someday for timekeeping. 106 */ 107 STD_EXCEPTION(0x900, Decrementer, timer_interrupt) 108 STD_EXCEPTION(0xa00, Trap_0a, UnknownException) 109 STD_EXCEPTION(0xb00, Trap_0b, UnknownException) 110 STD_EXCEPTION(0xc00, SystemCall, UnknownException) 111 STD_EXCEPTION(0xd00, SingleStep, UnknownException) 112 STD_EXCEPTION(0xe00, Trap_0e, UnknownException) 113 STD_EXCEPTION(0xf00, Trap_0f, UnknownException) 114 STD_EXCEPTION(0x1000, SoftEmu, SoftEmuException) 115 STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException) 116 STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException) 117 STD_EXCEPTION(0x1300, InstructionTLBError, UnknownException) 118 STD_EXCEPTION(0x1400, DataTLBError, UnknownException) 119 STD_EXCEPTION(0x1500, Reserved5, UnknownException) 120 STD_EXCEPTION(0x1600, Reserved6, UnknownException) 121 STD_EXCEPTION(0x1700, Reserved7, UnknownException) 122 STD_EXCEPTION(0x1800, Reserved8, UnknownException) 123 STD_EXCEPTION(0x1900, Reserved9, UnknownException) 124 STD_EXCEPTION(0x1a00, ReservedA, UnknownException) 125 STD_EXCEPTION(0x1b00, ReservedB, UnknownException) 126 STD_EXCEPTION(0x1c00, DataBreakpoint, UnknownException) 127 STD_EXCEPTION(0x1d00, InstructionBreakpoint, UnknownException) 128 STD_EXCEPTION(0x1e00, PeripheralBreakpoint, UnknownException) 129 STD_EXCEPTION(0x1f00, DevPortBreakpoint, UnknownException) 130 131 .globl _end_of_vectors 132_end_of_vectors: 133 134 . = 0x2000 135 136boot_cold: 137 /* 138 * NOTE: Only Cpu 0 will ever come here. Other cores go to an 139 * address specified by the BPTR 140 */ 1411: 142#ifdef CONFIG_SYS_RAMBOOT 143 /* disable everything */ 144 li r0, 0 145 mtspr HID0, r0 146 sync 147 mtmsr 0 148#endif 149 150 /* Invalidate BATs */ 151 bl invalidate_bats 152 sync 153 /* Invalidate all of TLB before MMU turn on */ 154 bl clear_tlbs 155 sync 156 157#ifdef CONFIG_SYS_L2 158 /* init the L2 cache */ 159 lis r3, L2_INIT@h 160 ori r3, r3, L2_INIT@l 161 mtspr l2cr, r3 162 /* invalidate the L2 cache */ 163 bl l2cache_invalidate 164 sync 165#endif 166 167 /* 168 * Calculate absolute address in FLASH and jump there 169 *------------------------------------------------------*/ 170 lis r3, CONFIG_SYS_MONITOR_BASE_EARLY@h 171 ori r3, r3, CONFIG_SYS_MONITOR_BASE_EARLY@l 172 addi r3, r3, in_flash - _start + EXC_OFF_SYS_RESET 173 mtlr r3 174 blr 175 176in_flash: 177 /* let the C-code set up the rest */ 178 /* */ 179 /* Be careful to keep code relocatable ! */ 180 /*------------------------------------------------------*/ 181 /* perform low-level init */ 182 183 /* enable extended addressing */ 184 bl enable_ext_addr 185 186 /* setup the bats */ 187 bl early_bats 188 189 /* 190 * Cache must be enabled here for stack-in-cache trick. 191 * This means we need to enable the BATS. 192 * Cache should be turned on after BATs, since by default 193 * everything is write-through. 194 */ 195 196 /* enable address translation */ 197 mfmsr r5 198 ori r5, r5, (MSR_IR | MSR_DR) 199 lis r3,addr_trans_enabled@h 200 ori r3, r3, addr_trans_enabled@l 201 mtspr SPRN_SRR0,r3 202 mtspr SPRN_SRR1,r5 203 rfi 204 205addr_trans_enabled: 206 /* enable and invalidate the data cache */ 207/* bl l1dcache_enable */ 208 bl dcache_enable 209 sync 210 211#if 1 212 bl icache_enable 213#endif 214 215#ifdef CONFIG_SYS_INIT_RAM_LOCK 216 bl lock_ram_in_cache 217 sync 218#endif 219 220#if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR) 221 bl setup_ccsrbar 222#endif 223 224 /* set up the stack pointer in our newly created 225 * cache-ram (r1) */ 226 lis r1, (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET)@h 227 ori r1, r1, (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET)@l 228 229 li r0, 0 /* Make room for stack frame header and */ 230 stwu r0, -4(r1) /* clear final stack frame so that */ 231 stwu r0, -4(r1) /* stack backtraces terminate cleanly */ 232 233 GET_GOT /* initialize GOT access */ 234 235 /* run low-level CPU init code (from Flash) */ 236 bl cpu_init_f 237 sync 238 239#ifdef RUN_DIAG 240 241 /* Load PX_AUX register address in r4 */ 242 lis r4, PIXIS_BASE@h 243 ori r4, r4, 0x6 244 /* Load contents of PX_AUX in r3 bits 24 to 31*/ 245 lbz r3, 0(r4) 246 247 /* Mask and obtain the bit in r3 */ 248 rlwinm. r3, r3, 0, 24, 24 249 /* If not zero, jump and continue with u-boot */ 250 bne diag_done 251 252 /* Load back contents of PX_AUX in r3 bits 24 to 31 */ 253 lbz r3, 0(r4) 254 /* Set the MSB of the register value */ 255 ori r3, r3, 0x80 256 /* Write value in r3 back to PX_AUX */ 257 stb r3, 0(r4) 258 259 /* Get the address to jump to in r3*/ 260 lis r3, CONFIG_SYS_DIAG_ADDR@h 261 ori r3, r3, CONFIG_SYS_DIAG_ADDR@l 262 263 /* Load the LR with the branch address */ 264 mtlr r3 265 266 /* Branch to diagnostic */ 267 blr 268 269diag_done: 270#endif 271 272/* bl l2cache_enable */ 273 274 /* run 1st part of board init code (from Flash) */ 275 li r3, 0 /* clear boot_flag for calling board_init_f */ 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 548/* 549 * Function: in8 550 * Description: Input 8 bits 551 */ 552 .globl in8 553in8: 554 lbz r3,0x0000(r3) 555 blr 556 557/* 558 * Function: out8 559 * Description: Output 8 bits 560 */ 561 .globl out8 562out8: 563 stb r4,0x0000(r3) 564 blr 565 566/* 567 * Function: out16 568 * Description: Output 16 bits 569 */ 570 .globl out16 571out16: 572 sth r4,0x0000(r3) 573 blr 574 575/* 576 * Function: out16r 577 * Description: Byte reverse and output 16 bits 578 */ 579 .globl out16r 580out16r: 581 sthbrx r4,r0,r3 582 blr 583 584/* 585 * Function: out32 586 * Description: Output 32 bits 587 */ 588 .globl out32 589out32: 590 stw r4,0x0000(r3) 591 blr 592 593/* 594 * Function: out32r 595 * Description: Byte reverse and output 32 bits 596 */ 597 .globl out32r 598out32r: 599 stwbrx r4,r0,r3 600 blr 601 602/* 603 * Function: in16 604 * Description: Input 16 bits 605 */ 606 .globl in16 607in16: 608 lhz r3,0x0000(r3) 609 blr 610 611/* 612 * Function: in16r 613 * Description: Input 16 bits and byte reverse 614 */ 615 .globl in16r 616in16r: 617 lhbrx r3,r0,r3 618 blr 619 620/* 621 * Function: in32 622 * Description: Input 32 bits 623 */ 624 .globl in32 625in32: 626 lwz 3,0x0000(3) 627 blr 628 629/* 630 * Function: in32r 631 * Description: Input 32 bits and byte reverse 632 */ 633 .globl in32r 634in32r: 635 lwbrx r3,r0,r3 636 blr 637 638/* 639 * void relocate_code (addr_sp, gd, addr_moni) 640 * 641 * This "function" does not return, instead it continues in RAM 642 * after relocating the monitor code. 643 * 644 * r3 = dest 645 * r4 = src 646 * r5 = length in bytes 647 * r6 = cachelinesize 648 */ 649 .globl relocate_code 650relocate_code: 651 652 mr r1, r3 /* Set new stack pointer */ 653 mr r9, r4 /* Save copy of Global Data pointer */ 654 mr r10, r5 /* Save copy of Destination Address */ 655 656 GET_GOT 657 mr r3, r5 /* Destination Address */ 658 lis r4, CONFIG_SYS_MONITOR_BASE@h /* Source Address */ 659 ori r4, r4, CONFIG_SYS_MONITOR_BASE@l 660 lwz r5, GOT(__init_end) 661 sub r5, r5, r4 662 li r6, CONFIG_SYS_CACHELINE_SIZE /* Cache Line Size */ 663 664 /* 665 * Fix GOT pointer: 666 * 667 * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address 668 * 669 * Offset: 670 */ 671 sub r15, r10, r4 672 673 /* First our own GOT */ 674 add r12, r12, r15 675 /* then the one used by the C code */ 676 add r30, r30, r15 677 678 /* 679 * Now relocate code 680 */ 681 cmplw cr1,r3,r4 682 addi r0,r5,3 683 srwi. r0,r0,2 684 beq cr1,4f /* In place copy is not necessary */ 685 beq 7f /* Protect against 0 count */ 686 mtctr r0 687 bge cr1,2f 688 689 la r8,-4(r4) 690 la r7,-4(r3) 6911: lwzu r0,4(r8) 692 stwu r0,4(r7) 693 bdnz 1b 694 b 4f 695 6962: slwi r0,r0,2 697 add r8,r4,r0 698 add r7,r3,r0 6993: lwzu r0,-4(r8) 700 stwu r0,-4(r7) 701 bdnz 3b 702/* 703 * Now flush the cache: note that we must start from a cache aligned 704 * address. Otherwise we might miss one cache line. 705 */ 7064: cmpwi r6,0 707 add r5,r3,r5 708 beq 7f /* Always flush prefetch queue in any case */ 709 subi r0,r6,1 710 andc r3,r3,r0 711 mr r4,r3 7125: dcbst 0,r4 713 add r4,r4,r6 714 cmplw r4,r5 715 blt 5b 716 sync /* Wait for all dcbst to complete on bus */ 717 mr r4,r3 7186: icbi 0,r4 719 add r4,r4,r6 720 cmplw r4,r5 721 blt 6b 7227: sync /* Wait for all icbi to complete on bus */ 723 isync 724 725/* 726 * We are done. Do not return, instead branch to second part of board 727 * initialization, now running from RAM. 728 */ 729 addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET 730 mtlr r0 731 blr 732 733in_ram: 734 /* 735 * Relocation Function, r12 point to got2+0x8000 736 * 737 * Adjust got2 pointers, no need to check for 0, this code 738 * already puts a few entries in the table. 739 */ 740 li r0,__got2_entries@sectoff@l 741 la r3,GOT(_GOT2_TABLE_) 742 lwz r11,GOT(_GOT2_TABLE_) 743 mtctr r0 744 sub r11,r3,r11 745 addi r3,r3,-4 7461: lwzu r0,4(r3) 747 cmpwi r0,0 748 beq- 2f 749 add r0,r0,r11 750 stw r0,0(r3) 7512: bdnz 1b 752 753 /* 754 * Now adjust the fixups and the pointers to the fixups 755 * in case we need to move ourselves again. 756 */ 757 li r0,__fixup_entries@sectoff@l 758 lwz r3,GOT(_FIXUP_TABLE_) 759 cmpwi r0,0 760 mtctr r0 761 addi r3,r3,-4 762 beq 4f 7633: lwzu r4,4(r3) 764 lwzux r0,r4,r11 765 cmpwi r0,0 766 add r0,r0,r11 767 stw r4,0(r3) 768 beq- 5f 769 stw r0,0(r4) 7705: bdnz 3b 7714: 772/* clear_bss: */ 773 /* 774 * Now clear BSS segment 775 */ 776 lwz r3,GOT(__bss_start) 777 lwz r4,GOT(__bss_end) 778 779 cmplw 0, r3, r4 780 beq 6f 781 782 li r0, 0 7835: 784 stw r0, 0(r3) 785 addi r3, r3, 4 786 cmplw 0, r3, r4 787 bne 5b 7886: 789 mr r3, r9 /* Init Date pointer */ 790 mr r4, r10 /* Destination Address */ 791 bl board_init_r 792 793 /* not reached - end relocate_code */ 794/*-----------------------------------------------------------------------*/ 795 796 /* 797 * Copy exception vector code to low memory 798 * 799 * r3: dest_addr 800 * r7: source address, r8: end address, r9: target address 801 */ 802 .globl trap_init 803trap_init: 804 mflr r4 /* save link register */ 805 GET_GOT 806 lwz r7, GOT(_start) 807 lwz r8, GOT(_end_of_vectors) 808 809 li r9, 0x100 /* reset vector always at 0x100 */ 810 811 cmplw 0, r7, r8 812 bgelr /* return if r7>=r8 - just in case */ 8131: 814 lwz r0, 0(r7) 815 stw r0, 0(r9) 816 addi r7, r7, 4 817 addi r9, r9, 4 818 cmplw 0, r7, r8 819 bne 1b 820 821 /* 822 * relocate `hdlr' and `int_return' entries 823 */ 824 li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET 825 li r8, Alignment - _start + EXC_OFF_SYS_RESET 8262: 827 bl trap_reloc 828 addi r7, r7, 0x100 /* next exception vector */ 829 cmplw 0, r7, r8 830 blt 2b 831 832 li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET 833 bl trap_reloc 834 835 li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET 836 bl trap_reloc 837 838 li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET 839 li r8, SystemCall - _start + EXC_OFF_SYS_RESET 8403: 841 bl trap_reloc 842 addi r7, r7, 0x100 /* next exception vector */ 843 cmplw 0, r7, r8 844 blt 3b 845 846 li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET 847 li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET 8484: 849 bl trap_reloc 850 addi r7, r7, 0x100 /* next exception vector */ 851 cmplw 0, r7, r8 852 blt 4b 853 854 /* enable execptions from RAM vectors */ 855 mfmsr r7 856 li r8,MSR_IP 857 andc r7,r7,r8 858 ori r7,r7,MSR_ME /* Enable Machine Check */ 859 mtmsr r7 860 861 mtlr r4 /* restore link register */ 862 blr 863 864.globl enable_ext_addr 865enable_ext_addr: 866 mfspr r0, HID0 867 lis r0, (HID0_HIGH_BAT_EN | HID0_XBSEN | HID0_XAEN)@h 868 ori r0, r0, (HID0_HIGH_BAT_EN | HID0_XBSEN | HID0_XAEN)@l 869 mtspr HID0, r0 870 sync 871 isync 872 blr 873 874#if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR) 875.globl setup_ccsrbar 876setup_ccsrbar: 877 /* Special sequence needed to update CCSRBAR itself */ 878 lis r4, CONFIG_SYS_CCSRBAR_DEFAULT@h 879 ori r4, r4, CONFIG_SYS_CCSRBAR_DEFAULT@l 880 881 lis r5, CONFIG_SYS_CCSRBAR_PHYS_LOW@h 882 ori r5, r5, CONFIG_SYS_CCSRBAR_PHYS_LOW@l 883 srwi r5,r5,12 884 li r6, CONFIG_SYS_CCSRBAR_PHYS_HIGH@l 885 rlwimi r5,r6,20,8,11 886 stw r5, 0(r4) /* Store physical value of CCSR */ 887 isync 888 889 lis r5, CONFIG_SYS_TEXT_BASE@h 890 ori r5,r5,CONFIG_SYS_TEXT_BASE@l 891 lwz r5, 0(r5) 892 isync 893 894 /* Use VA of CCSR to do read */ 895 lis r3, CONFIG_SYS_CCSRBAR@h 896 lwz r5, CONFIG_SYS_CCSRBAR@l(r3) 897 isync 898 899 blr 900#endif 901 902#ifdef CONFIG_SYS_INIT_RAM_LOCK 903lock_ram_in_cache: 904 /* Allocate Initial RAM in data cache. 905 */ 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_SIZE & ~31) + \ 909 (CONFIG_SYS_INIT_RAM_ADDR & 31) + 31) / 32 910 mtctr r4 9111: 912 dcbz r0, r3 913 addi r3, r3, 32 914 bdnz 1b 915#if 1 916/* Lock the data cache */ 917 mfspr r0, HID0 918 ori r0, r0, 0x1000 919 sync 920 mtspr HID0, r0 921 sync 922 blr 923#endif 924#if 0 925 /* Lock the first way of the data cache */ 926 mfspr r0, LDSTCR 927 ori r0, r0, 0x0080 928#if defined(CONFIG_ALTIVEC) 929 dssall 930#endif 931 sync 932 mtspr LDSTCR, r0 933 sync 934 isync 935 blr 936#endif 937 938.globl unlock_ram_in_cache 939unlock_ram_in_cache: 940 /* invalidate the INIT_RAM section */ 941 lis r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@h 942 ori r3, r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@l 943 li r4, ((CONFIG_SYS_INIT_RAM_SIZE & ~31) + \ 944 (CONFIG_SYS_INIT_RAM_ADDR & 31) + 31) / 32 945 mtctr r4 9461: icbi r0, r3 947 addi r3, r3, 32 948 bdnz 1b 949 sync /* Wait for all icbi to complete on bus */ 950 isync 951#if 1 952/* Unlock the data cache and invalidate it */ 953 mfspr r0, HID0 954 li r3,0x1000 955 andc r0,r0,r3 956 li r3,0x0400 957 or r0,r0,r3 958 sync 959 mtspr HID0, r0 960 sync 961 blr 962#endif 963#if 0 964 /* Unlock the first way of the data cache */ 965 mfspr r0, LDSTCR 966 li r3,0x0080 967 andc r0,r0,r3 968#ifdef CONFIG_ALTIVEC 969 dssall 970#endif 971 sync 972 mtspr LDSTCR, r0 973 sync 974 isync 975 li r3,0x0400 976 or r0,r0,r3 977 sync 978 mtspr HID0, r0 979 sync 980 blr 981#endif 982#endif 983