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