1/* 2 * Copyright (C) 1998 Dan Malek <dmalek@jlc.net> 3 * Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se> 4 * Copyright (C) 2000 - 2003 Wolfgang Denk <wd@denx.de> 5 * 6 * See file CREDITS for list of people who contributed to this 7 * project. 8 * 9 * This program is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU General Public License as 11 * published by the Free Software Foundation; either version 2 of 12 * the License, or (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 22 * MA 02111-1307 USA 23 */ 24 25/* 26 * U-Boot - Startup Code for MPC5xxx CPUs 27 */ 28#include <config.h> 29#include <mpc5xxx.h> 30#include <timestamp.h> 31#include <version.h> 32 33#define CONFIG_MPC5xxx 1 /* needed for Linux kernel header files */ 34#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */ 35 36#include <ppc_asm.tmpl> 37#include <ppc_defs.h> 38 39#include <asm/cache.h> 40#include <asm/mmu.h> 41 42#ifndef CONFIG_IDENT_STRING 43#define CONFIG_IDENT_STRING "" 44#endif 45 46/* We don't want the MMU yet. 47*/ 48#undef MSR_KERNEL 49/* Floating Point enable, Machine Check and Recoverable Interr. */ 50#ifdef DEBUG 51#define MSR_KERNEL (MSR_FP|MSR_RI) 52#else 53#define MSR_KERNEL (MSR_FP|MSR_ME|MSR_RI) 54#endif 55 56/* 57 * Set up GOT: Global Offset Table 58 * 59 * Use r12 to access the GOT 60 */ 61 START_GOT 62 GOT_ENTRY(_GOT2_TABLE_) 63 GOT_ENTRY(_FIXUP_TABLE_) 64 65 GOT_ENTRY(_start) 66 GOT_ENTRY(_start_of_vectors) 67 GOT_ENTRY(_end_of_vectors) 68 GOT_ENTRY(transfer_to_handler) 69 70 GOT_ENTRY(__init_end) 71 GOT_ENTRY(_end) 72 GOT_ENTRY(__bss_start) 73 END_GOT 74 75/* 76 * Version string 77 */ 78 .data 79 .globl version_string 80version_string: 81 .ascii U_BOOT_VERSION 82 .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")" 83 .ascii CONFIG_IDENT_STRING, "\0" 84 85/* 86 * Exception vectors 87 */ 88 .text 89 . = EXC_OFF_SYS_RESET 90 .globl _start 91_start: 92 li r21, BOOTFLAG_COLD /* Normal Power-On */ 93 nop 94 b boot_cold 95 96 . = EXC_OFF_SYS_RESET + 0x10 97 98 .globl _start_warm 99_start_warm: 100 li r21, BOOTFLAG_WARM /* Software reboot */ 101 b boot_warm 102 103boot_cold: 104boot_warm: 105 mfmsr r5 /* save msr contents */ 106 107 /* Move CSBoot and adjust instruction pointer */ 108 /*--------------------------------------------------------------*/ 109 110#if defined(CONFIG_SYS_LOWBOOT) 111# if defined(CONFIG_SYS_RAMBOOT) 112# error CONFIG_SYS_LOWBOOT is incompatible with CONFIG_SYS_RAMBOOT 113# endif /* CONFIG_SYS_RAMBOOT */ 114 lis r4, CONFIG_SYS_DEFAULT_MBAR@h 115 lis r3, START_REG(CONFIG_SYS_BOOTCS_START)@h 116 ori r3, r3, START_REG(CONFIG_SYS_BOOTCS_START)@l 117 stw r3, 0x4(r4) /* CS0 start */ 118 lis r3, STOP_REG(CONFIG_SYS_BOOTCS_START, CONFIG_SYS_BOOTCS_SIZE)@h 119 ori r3, r3, STOP_REG(CONFIG_SYS_BOOTCS_START, CONFIG_SYS_BOOTCS_SIZE)@l 120 stw r3, 0x8(r4) /* CS0 stop */ 121 lis r3, 0x02010000@h 122 ori r3, r3, 0x02010000@l 123 stw r3, 0x54(r4) /* CS0 and Boot enable */ 124 125 lis r3, lowboot_reentry@h /* jump from bootlow address space (0x0000xxxx) */ 126 ori r3, r3, lowboot_reentry@l /* to the address space the linker used */ 127 mtlr r3 128 blr 129 130lowboot_reentry: 131 lis r3, START_REG(CONFIG_SYS_BOOTCS_START)@h 132 ori r3, r3, START_REG(CONFIG_SYS_BOOTCS_START)@l 133 stw r3, 0x4c(r4) /* Boot start */ 134 lis r3, STOP_REG(CONFIG_SYS_BOOTCS_START, CONFIG_SYS_BOOTCS_SIZE)@h 135 ori r3, r3, STOP_REG(CONFIG_SYS_BOOTCS_START, CONFIG_SYS_BOOTCS_SIZE)@l 136 stw r3, 0x50(r4) /* Boot stop */ 137 lis r3, 0x02000001@h 138 ori r3, r3, 0x02000001@l 139 stw r3, 0x54(r4) /* Boot enable, CS0 disable */ 140#endif /* CONFIG_SYS_LOWBOOT */ 141 142#if defined(CONFIG_SYS_DEFAULT_MBAR) && !defined(CONFIG_SYS_RAMBOOT) 143 lis r3, CONFIG_SYS_MBAR@h 144 ori r3, r3, CONFIG_SYS_MBAR@l 145 /* MBAR is mirrored into the MBAR SPR */ 146 mtspr MBAR,r3 147 rlwinm r3, r3, 16, 16, 31 148 lis r4, CONFIG_SYS_DEFAULT_MBAR@h 149 stw r3, 0(r4) 150#endif /* CONFIG_SYS_DEFAULT_MBAR */ 151 152 /* Initialise the MPC5xxx processor core */ 153 /*--------------------------------------------------------------*/ 154 155 bl init_5xxx_core 156 157 /* initialize some things that are hard to access from C */ 158 /*--------------------------------------------------------------*/ 159 160 /* set up stack in on-chip SRAM */ 161 lis r3, CONFIG_SYS_INIT_RAM_ADDR@h 162 ori r3, r3, CONFIG_SYS_INIT_RAM_ADDR@l 163 ori r1, r3, CONFIG_SYS_INIT_SP_OFFSET 164 li r0, 0 /* Make room for stack frame header and */ 165 stwu r0, -4(r1) /* clear final stack frame so that */ 166 stwu r0, -4(r1) /* stack backtraces terminate cleanly */ 167 168 /* let the C-code set up the rest */ 169 /* */ 170 /* Be careful to keep code relocatable ! */ 171 /*--------------------------------------------------------------*/ 172 173 GET_GOT /* initialize GOT access */ 174 175 /* r3: IMMR */ 176 bl cpu_init_f /* run low-level CPU init code (in Flash)*/ 177 178 mr r3, r21 179 /* r3: BOOTFLAG */ 180 bl board_init_f /* run 1st part of board init code (in Flash)*/ 181 182/* 183 * Vector Table 184 */ 185 186 .globl _start_of_vectors 187_start_of_vectors: 188 189/* Machine check */ 190 STD_EXCEPTION(0x200, MachineCheck, MachineCheckException) 191 192/* Data Storage exception. */ 193 STD_EXCEPTION(0x300, DataStorage, UnknownException) 194 195/* Instruction Storage exception. */ 196 STD_EXCEPTION(0x400, InstStorage, UnknownException) 197 198/* External Interrupt exception. */ 199 STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt) 200 201/* Alignment exception. */ 202 . = 0x600 203Alignment: 204 EXCEPTION_PROLOG(SRR0, SRR1) 205 mfspr r4,DAR 206 stw r4,_DAR(r21) 207 mfspr r5,DSISR 208 stw r5,_DSISR(r21) 209 addi r3,r1,STACK_FRAME_OVERHEAD 210 EXC_XFER_TEMPLATE(Alignment, AlignmentException, MSR_KERNEL, COPY_EE) 211 212/* Program check exception */ 213 . = 0x700 214ProgramCheck: 215 EXCEPTION_PROLOG(SRR0, SRR1) 216 addi r3,r1,STACK_FRAME_OVERHEAD 217 EXC_XFER_TEMPLATE(ProgramCheck, ProgramCheckException, 218 MSR_KERNEL, COPY_EE) 219 220 STD_EXCEPTION(0x800, FPUnavailable, UnknownException) 221 222 /* I guess we could implement decrementer, and may have 223 * to someday for timekeeping. 224 */ 225 STD_EXCEPTION(0x900, Decrementer, timer_interrupt) 226 227 STD_EXCEPTION(0xa00, Trap_0a, UnknownException) 228 STD_EXCEPTION(0xb00, Trap_0b, UnknownException) 229 STD_EXCEPTION(0xc00, SystemCall, UnknownException) 230 STD_EXCEPTION(0xd00, SingleStep, UnknownException) 231 232 STD_EXCEPTION(0xe00, Trap_0e, UnknownException) 233 STD_EXCEPTION(0xf00, Trap_0f, UnknownException) 234 235 STD_EXCEPTION(0x1000, InstructionTLBMiss, UnknownException) 236 STD_EXCEPTION(0x1100, DataLoadTLBMiss, UnknownException) 237 STD_EXCEPTION(0x1200, DataStoreTLBMiss, UnknownException) 238#ifdef DEBUG 239 . = 0x1300 240 /* 241 * This exception occurs when the program counter matches the 242 * Instruction Address Breakpoint Register (IABR). 243 * 244 * I want the cpu to halt if this occurs so I can hunt around 245 * with the debugger and look at things. 246 * 247 * When DEBUG is defined, both machine check enable (in the MSR) 248 * and checkstop reset enable (in the reset mode register) are 249 * turned off and so a checkstop condition will result in the cpu 250 * halting. 251 * 252 * I force the cpu into a checkstop condition by putting an illegal 253 * instruction here (at least this is the theory). 254 * 255 * well - that didnt work, so just do an infinite loop! 256 */ 2571: b 1b 258#else 259 STD_EXCEPTION(0x1300, InstructionBreakpoint, DebugException) 260#endif 261 STD_EXCEPTION(0x1400, SMI, UnknownException) 262 263 STD_EXCEPTION(0x1500, Trap_15, UnknownException) 264 STD_EXCEPTION(0x1600, Trap_16, UnknownException) 265 STD_EXCEPTION(0x1700, Trap_17, UnknownException) 266 STD_EXCEPTION(0x1800, Trap_18, UnknownException) 267 STD_EXCEPTION(0x1900, Trap_19, UnknownException) 268 STD_EXCEPTION(0x1a00, Trap_1a, UnknownException) 269 STD_EXCEPTION(0x1b00, Trap_1b, UnknownException) 270 STD_EXCEPTION(0x1c00, Trap_1c, UnknownException) 271 STD_EXCEPTION(0x1d00, Trap_1d, UnknownException) 272 STD_EXCEPTION(0x1e00, Trap_1e, UnknownException) 273 STD_EXCEPTION(0x1f00, Trap_1f, UnknownException) 274 STD_EXCEPTION(0x2000, Trap_20, UnknownException) 275 STD_EXCEPTION(0x2100, Trap_21, UnknownException) 276 STD_EXCEPTION(0x2200, Trap_22, UnknownException) 277 STD_EXCEPTION(0x2300, Trap_23, UnknownException) 278 STD_EXCEPTION(0x2400, Trap_24, UnknownException) 279 STD_EXCEPTION(0x2500, Trap_25, UnknownException) 280 STD_EXCEPTION(0x2600, Trap_26, UnknownException) 281 STD_EXCEPTION(0x2700, Trap_27, UnknownException) 282 STD_EXCEPTION(0x2800, Trap_28, UnknownException) 283 STD_EXCEPTION(0x2900, Trap_29, UnknownException) 284 STD_EXCEPTION(0x2a00, Trap_2a, UnknownException) 285 STD_EXCEPTION(0x2b00, Trap_2b, UnknownException) 286 STD_EXCEPTION(0x2c00, Trap_2c, UnknownException) 287 STD_EXCEPTION(0x2d00, Trap_2d, UnknownException) 288 STD_EXCEPTION(0x2e00, Trap_2e, UnknownException) 289 STD_EXCEPTION(0x2f00, Trap_2f, UnknownException) 290 291 292 .globl _end_of_vectors 293_end_of_vectors: 294 295 . = 0x3000 296 297/* 298 * This code finishes saving the registers to the exception frame 299 * and jumps to the appropriate handler for the exception. 300 * Register r21 is pointer into trap frame, r1 has new stack pointer. 301 */ 302 .globl transfer_to_handler 303transfer_to_handler: 304 stw r22,_NIP(r21) 305 lis r22,MSR_POW@h 306 andc r23,r23,r22 307 stw r23,_MSR(r21) 308 SAVE_GPR(7, r21) 309 SAVE_4GPRS(8, r21) 310 SAVE_8GPRS(12, r21) 311 SAVE_8GPRS(24, r21) 312 mflr r23 313 andi. r24,r23,0x3f00 /* get vector offset */ 314 stw r24,TRAP(r21) 315 li r22,0 316 stw r22,RESULT(r21) 317 lwz r24,0(r23) /* virtual address of handler */ 318 lwz r23,4(r23) /* where to go when done */ 319 mtspr SRR0,r24 320 mtspr SRR1,r20 321 mtlr r23 322 SYNC 323 rfi /* jump to handler, enable MMU */ 324 325int_return: 326 mfmsr r28 /* Disable interrupts */ 327 li r4,0 328 ori r4,r4,MSR_EE 329 andc r28,r28,r4 330 SYNC /* Some chip revs need this... */ 331 mtmsr r28 332 SYNC 333 lwz r2,_CTR(r1) 334 lwz r0,_LINK(r1) 335 mtctr r2 336 mtlr r0 337 lwz r2,_XER(r1) 338 lwz r0,_CCR(r1) 339 mtspr XER,r2 340 mtcrf 0xFF,r0 341 REST_10GPRS(3, r1) 342 REST_10GPRS(13, r1) 343 REST_8GPRS(23, r1) 344 REST_GPR(31, r1) 345 lwz r2,_NIP(r1) /* Restore environment */ 346 lwz r0,_MSR(r1) 347 mtspr SRR0,r2 348 mtspr SRR1,r0 349 lwz r0,GPR0(r1) 350 lwz r2,GPR2(r1) 351 lwz r1,GPR1(r1) 352 SYNC 353 rfi 354 355/* 356 * This code initialises the MPC5xxx processor core 357 * (conforms to PowerPC 603e spec) 358 * Note: expects original MSR contents to be in r5. 359 */ 360 361 .globl init_5xx_core 362init_5xxx_core: 363 364 /* Initialize machine status; enable machine check interrupt */ 365 /*--------------------------------------------------------------*/ 366 367 li r3, MSR_KERNEL /* Set ME and RI flags */ 368 rlwimi r3, r5, 0, 25, 25 /* preserve IP bit set by HRCW */ 369#ifdef DEBUG 370 rlwimi r3, r5, 0, 21, 22 /* debugger might set SE & BE bits */ 371#endif 372 SYNC /* Some chip revs need this... */ 373 mtmsr r3 374 SYNC 375 mtspr SRR1, r3 /* Make SRR1 match MSR */ 376 377 /* Initialize the Hardware Implementation-dependent Registers */ 378 /* HID0 also contains cache control */ 379 /*--------------------------------------------------------------*/ 380 381 lis r3, CONFIG_SYS_HID0_INIT@h 382 ori r3, r3, CONFIG_SYS_HID0_INIT@l 383 SYNC 384 mtspr HID0, r3 385 386 lis r3, CONFIG_SYS_HID0_FINAL@h 387 ori r3, r3, CONFIG_SYS_HID0_FINAL@l 388 SYNC 389 mtspr HID0, r3 390 391 /* clear all BAT's */ 392 /*--------------------------------------------------------------*/ 393 394 li r0, 0 395 mtspr DBAT0U, r0 396 mtspr DBAT0L, r0 397 mtspr DBAT1U, r0 398 mtspr DBAT1L, r0 399 mtspr DBAT2U, r0 400 mtspr DBAT2L, r0 401 mtspr DBAT3U, r0 402 mtspr DBAT3L, r0 403 mtspr DBAT4U, r0 404 mtspr DBAT4L, r0 405 mtspr DBAT5U, r0 406 mtspr DBAT5L, r0 407 mtspr DBAT6U, r0 408 mtspr DBAT6L, r0 409 mtspr DBAT7U, r0 410 mtspr DBAT7L, r0 411 mtspr IBAT0U, r0 412 mtspr IBAT0L, r0 413 mtspr IBAT1U, r0 414 mtspr IBAT1L, r0 415 mtspr IBAT2U, r0 416 mtspr IBAT2L, r0 417 mtspr IBAT3U, r0 418 mtspr IBAT3L, r0 419 mtspr IBAT4U, r0 420 mtspr IBAT4L, r0 421 mtspr IBAT5U, r0 422 mtspr IBAT5L, r0 423 mtspr IBAT6U, r0 424 mtspr IBAT6L, r0 425 mtspr IBAT7U, r0 426 mtspr IBAT7L, r0 427 SYNC 428 429 /* invalidate all tlb's */ 430 /* */ 431 /* From the 603e User Manual: "The 603e provides the ability to */ 432 /* invalidate a TLB entry. The TLB Invalidate Entry (tlbie) */ 433 /* instruction invalidates the TLB entry indexed by the EA, and */ 434 /* operates on both the instruction and data TLBs simultaneously*/ 435 /* invalidating four TLB entries (both sets in each TLB). The */ 436 /* index corresponds to bits 15-19 of the EA. To invalidate all */ 437 /* entries within both TLBs, 32 tlbie instructions should be */ 438 /* issued, incrementing this field by one each time." */ 439 /* */ 440 /* "Note that the tlbia instruction is not implemented on the */ 441 /* 603e." */ 442 /* */ 443 /* bits 15-19 correspond to addresses 0x00000000 to 0x0001F000 */ 444 /* incrementing by 0x1000 each time. The code below is sort of */ 445 /* based on code in "flush_tlbs" from arch/powerpc/kernel/head.S */ 446 /* */ 447 /*--------------------------------------------------------------*/ 448 449 li r3, 32 450 mtctr r3 451 li r3, 0 4521: tlbie r3 453 addi r3, r3, 0x1000 454 bdnz 1b 455 SYNC 456 457 /* Done! */ 458 /*--------------------------------------------------------------*/ 459 460 blr 461 462/* Cache functions. 463 * 464 * Note: requires that all cache bits in 465 * HID0 are in the low half word. 466 */ 467 .globl icache_enable 468icache_enable: 469 mfspr r3, HID0 470 ori r3, r3, HID0_ICE 471 lis r4, 0 472 ori r4, r4, HID0_ILOCK 473 andc r3, r3, r4 474 ori r4, r3, HID0_ICFI 475 isync 476 mtspr HID0, r4 /* sets enable and invalidate, clears lock */ 477 isync 478 mtspr HID0, r3 /* clears invalidate */ 479 blr 480 481 .globl icache_disable 482icache_disable: 483 mfspr r3, HID0 484 lis r4, 0 485 ori r4, r4, HID0_ICE|HID0_ILOCK 486 andc r3, r3, r4 487 ori r4, r3, HID0_ICFI 488 isync 489 mtspr HID0, r4 /* sets invalidate, clears enable and lock */ 490 isync 491 mtspr HID0, r3 /* clears invalidate */ 492 blr 493 494 .globl icache_status 495icache_status: 496 mfspr r3, HID0 497 rlwinm r3, r3, HID0_ICE_BITPOS + 1, 31, 31 498 blr 499 500 .globl dcache_enable 501dcache_enable: 502 mfspr r3, HID0 503 ori r3, r3, HID0_DCE 504 lis r4, 0 505 ori r4, r4, HID0_DLOCK 506 andc r3, r3, r4 507 ori r4, r3, HID0_DCI 508 sync 509 mtspr HID0, r4 /* sets enable and invalidate, clears lock */ 510 sync 511 mtspr HID0, r3 /* clears invalidate */ 512 blr 513 514 .globl dcache_disable 515dcache_disable: 516 mfspr r3, HID0 517 lis r4, 0 518 ori r4, r4, HID0_DCE|HID0_DLOCK 519 andc r3, r3, r4 520 ori r4, r3, HID0_DCI 521 sync 522 mtspr HID0, r4 /* sets invalidate, clears enable and lock */ 523 sync 524 mtspr HID0, r3 /* clears invalidate */ 525 blr 526 527 .globl dcache_status 528dcache_status: 529 mfspr r3, HID0 530 rlwinm r3, r3, HID0_DCE_BITPOS + 1, 31, 31 531 blr 532 533 .globl get_svr 534get_svr: 535 mfspr r3, SVR 536 blr 537 538 .globl get_pvr 539get_pvr: 540 mfspr r3, PVR 541 blr 542 543/*------------------------------------------------------------------------------*/ 544 545/* 546 * void relocate_code (addr_sp, gd, addr_moni) 547 * 548 * This "function" does not return, instead it continues in RAM 549 * after relocating the monitor code. 550 * 551 * r3 = dest 552 * r4 = src 553 * r5 = length in bytes 554 * r6 = cachelinesize 555 */ 556 .globl relocate_code 557relocate_code: 558 mr r1, r3 /* Set new stack pointer */ 559 mr r9, r4 /* Save copy of Global Data pointer */ 560 mr r10, r5 /* Save copy of Destination Address */ 561 562 GET_GOT 563 mr r3, r5 /* Destination Address */ 564 lis r4, CONFIG_SYS_MONITOR_BASE@h /* Source Address */ 565 ori r4, r4, CONFIG_SYS_MONITOR_BASE@l 566 lwz r5, GOT(__init_end) 567 sub r5, r5, r4 568 li r6, CONFIG_SYS_CACHELINE_SIZE /* Cache Line Size */ 569 570 /* 571 * Fix GOT pointer: 572 * 573 * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address 574 * 575 * Offset: 576 */ 577 sub r15, r10, r4 578 579 /* First our own GOT */ 580 add r12, r12, r15 581 /* then the one used by the C code */ 582 add r30, r30, r15 583 584 /* 585 * Now relocate code 586 */ 587 588 cmplw cr1,r3,r4 589 addi r0,r5,3 590 srwi. r0,r0,2 591 beq cr1,4f /* In place copy is not necessary */ 592 beq 7f /* Protect against 0 count */ 593 mtctr r0 594 bge cr1,2f 595 596 la r8,-4(r4) 597 la r7,-4(r3) 5981: lwzu r0,4(r8) 599 stwu r0,4(r7) 600 bdnz 1b 601 b 4f 602 6032: slwi r0,r0,2 604 add r8,r4,r0 605 add r7,r3,r0 6063: lwzu r0,-4(r8) 607 stwu r0,-4(r7) 608 bdnz 3b 609 610/* 611 * Now flush the cache: note that we must start from a cache aligned 612 * address. Otherwise we might miss one cache line. 613 */ 6144: cmpwi r6,0 615 add r5,r3,r5 616 beq 7f /* Always flush prefetch queue in any case */ 617 subi r0,r6,1 618 andc r3,r3,r0 619 mfspr r7,HID0 /* don't do dcbst if dcache is disabled */ 620 rlwinm r7,r7,HID0_DCE_BITPOS+1,31,31 621 cmpwi r7,0 622 beq 9f 623 mr r4,r3 6245: dcbst 0,r4 625 add r4,r4,r6 626 cmplw r4,r5 627 blt 5b 628 sync /* Wait for all dcbst to complete on bus */ 6299: mfspr r7,HID0 /* don't do icbi if icache is disabled */ 630 rlwinm r7,r7,HID0_ICE_BITPOS+1,31,31 631 cmpwi r7,0 632 beq 7f 633 mr r4,r3 6346: icbi 0,r4 635 add r4,r4,r6 636 cmplw r4,r5 637 blt 6b 6387: sync /* Wait for all icbi to complete on bus */ 639 isync 640 641/* 642 * We are done. Do not return, instead branch to second part of board 643 * initialization, now running from RAM. 644 */ 645 646 addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET 647 mtlr r0 648 blr 649 650in_ram: 651 652 /* 653 * Relocation Function, r12 point to got2+0x8000 654 * 655 * Adjust got2 pointers, no need to check for 0, this code 656 * already puts a few entries in the table. 657 */ 658 li r0,__got2_entries@sectoff@l 659 la r3,GOT(_GOT2_TABLE_) 660 lwz r11,GOT(_GOT2_TABLE_) 661 mtctr r0 662 sub r11,r3,r11 663 addi r3,r3,-4 6641: lwzu r0,4(r3) 665 cmpwi r0,0 666 beq- 2f 667 add r0,r0,r11 668 stw r0,0(r3) 6692: bdnz 1b 670 671 /* 672 * Now adjust the fixups and the pointers to the fixups 673 * in case we need to move ourselves again. 674 */ 675 li r0,__fixup_entries@sectoff@l 676 lwz r3,GOT(_FIXUP_TABLE_) 677 cmpwi r0,0 678 mtctr r0 679 addi r3,r3,-4 680 beq 4f 6813: lwzu r4,4(r3) 682 lwzux r0,r4,r11 683 add r0,r0,r11 684 stw r10,0(r3) 685 stw r0,0(r4) 686 bdnz 3b 6874: 688clear_bss: 689 /* 690 * Now clear BSS segment 691 */ 692 lwz r3,GOT(__bss_start) 693 lwz r4,GOT(_end) 694 695 cmplw 0, r3, r4 696 beq 6f 697 698 li r0, 0 6995: 700 stw r0, 0(r3) 701 addi r3, r3, 4 702 cmplw 0, r3, r4 703 bne 5b 7046: 705 706 mr r3, r9 /* Global Data pointer */ 707 mr r4, r10 /* Destination Address */ 708 bl board_init_r 709 710 /* 711 * Copy exception vector code to low memory 712 * 713 * r3: dest_addr 714 * r7: source address, r8: end address, r9: target address 715 */ 716 .globl trap_init 717trap_init: 718 mflr r4 /* save link register */ 719 GET_GOT 720 lwz r7, GOT(_start) 721 lwz r8, GOT(_end_of_vectors) 722 723 li r9, 0x100 /* reset vector always at 0x100 */ 724 725 cmplw 0, r7, r8 726 bgelr /* return if r7>=r8 - just in case */ 7271: 728 lwz r0, 0(r7) 729 stw r0, 0(r9) 730 addi r7, r7, 4 731 addi r9, r9, 4 732 cmplw 0, r7, r8 733 bne 1b 734 735 /* 736 * relocate `hdlr' and `int_return' entries 737 */ 738 li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET 739 li r8, Alignment - _start + EXC_OFF_SYS_RESET 7402: 741 bl trap_reloc 742 addi r7, r7, 0x100 /* next exception vector */ 743 cmplw 0, r7, r8 744 blt 2b 745 746 li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET 747 bl trap_reloc 748 749 li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET 750 bl trap_reloc 751 752 li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET 753 li r8, SystemCall - _start + EXC_OFF_SYS_RESET 7543: 755 bl trap_reloc 756 addi r7, r7, 0x100 /* next exception vector */ 757 cmplw 0, r7, r8 758 blt 3b 759 760 li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET 761 li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET 7624: 763 bl trap_reloc 764 addi r7, r7, 0x100 /* next exception vector */ 765 cmplw 0, r7, r8 766 blt 4b 767 768 mfmsr r3 /* now that the vectors have */ 769 lis r7, MSR_IP@h /* relocated into low memory */ 770 ori r7, r7, MSR_IP@l /* MSR[IP] can be turned off */ 771 andc r3, r3, r7 /* (if it was on) */ 772 SYNC /* Some chip revs need this... */ 773 mtmsr r3 774 SYNC 775 776 mtlr r4 /* restore link register */ 777 blr 778