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