1/* 2 * Copyright 2004, 2007-2012 Freescale Semiconductor, Inc. 3 * Copyright (C) 2003 Motorola,Inc. 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 Motorola 85xx PowerPC based Embedded Boards 25 * 26 * The processor starts at 0xfffffffc and the code is first executed in the 27 * last 4K page(0xfffff000-0xffffffff) in flash/rom. 28 * 29 */ 30 31#include <asm-offsets.h> 32#include <config.h> 33#include <mpc85xx.h> 34#include <version.h> 35 36#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */ 37 38#include <ppc_asm.tmpl> 39#include <ppc_defs.h> 40 41#include <asm/cache.h> 42#include <asm/mmu.h> 43 44#undef MSR_KERNEL 45#define MSR_KERNEL ( MSR_ME ) /* Machine Check */ 46 47/* 48 * Set up GOT: Global Offset Table 49 * 50 * Use r12 to access the GOT 51 */ 52 START_GOT 53 GOT_ENTRY(_GOT2_TABLE_) 54 GOT_ENTRY(_FIXUP_TABLE_) 55 56#ifndef CONFIG_NAND_SPL 57 GOT_ENTRY(_start) 58 GOT_ENTRY(_start_of_vectors) 59 GOT_ENTRY(_end_of_vectors) 60 GOT_ENTRY(transfer_to_handler) 61#endif 62 63 GOT_ENTRY(__init_end) 64 GOT_ENTRY(__bss_end__) 65 GOT_ENTRY(__bss_start) 66 END_GOT 67 68/* 69 * e500 Startup -- after reset only the last 4KB of the effective 70 * address space is mapped in the MMU L2 TLB1 Entry0. The .bootpg 71 * section is located at THIS LAST page and basically does three 72 * things: clear some registers, set up exception tables and 73 * add more TLB entries for 'larger spaces'(e.g. the boot rom) to 74 * continue the boot procedure. 75 76 * Once the boot rom is mapped by TLB entries we can proceed 77 * with normal startup. 78 * 79 */ 80 81 .section .bootpg,"ax" 82 .globl _start_e500 83 84_start_e500: 85/* Enable debug exception */ 86 li r1,MSR_DE 87 mtmsr r1 88 89#ifdef CONFIG_SYS_FSL_ERRATUM_A004510 90 mfspr r3,SPRN_SVR 91 rlwinm r3,r3,0,0xff 92 li r4,CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV 93 cmpw r3,r4 94 beq 1f 95 96#ifdef CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV2 97 li r4,CONFIG_SYS_FSL_ERRATUM_A004510_SVR_REV2 98 cmpw r3,r4 99 beq 1f 100#endif 101 102 /* Not a supported revision affected by erratum */ 103 li r27,0 104 b 2f 105 1061: li r27,1 /* Remember for later that we have the erratum */ 107 /* Erratum says set bits 55:60 to 001001 */ 108 msync 109 isync 110 mfspr r3,976 111 li r4,0x48 112 rlwimi r3,r4,0,0x1f8 113 mtspr 976,r3 114 isync 1152: 116#endif 117 118#if defined(CONFIG_SECURE_BOOT) && defined(CONFIG_E500MC) 119 /* ISBC uses L2 as stack. 120 * Disable L2 cache here so that u-boot can enable it later 121 * as part of it's normal flow 122 */ 123 124 /* Check if L2 is enabled */ 125 mfspr r3, SPRN_L2CSR0 126 lis r2, L2CSR0_L2E@h 127 ori r2, r2, L2CSR0_L2E@l 128 and. r4, r3, r2 129 beq l2_disabled 130 131 mfspr r3, SPRN_L2CSR0 132 /* Flush L2 cache */ 133 lis r2,(L2CSR0_L2FL)@h 134 ori r2, r2, (L2CSR0_L2FL)@l 135 or r3, r2, r3 136 sync 137 isync 138 mtspr SPRN_L2CSR0,r3 139 isync 1401: 141 mfspr r3, SPRN_L2CSR0 142 and. r1, r3, r2 143 bne 1b 144 145 mfspr r3, SPRN_L2CSR0 146 lis r2, L2CSR0_L2E@h 147 ori r2, r2, L2CSR0_L2E@l 148 andc r4, r3, r2 149 sync 150 isync 151 mtspr SPRN_L2CSR0,r4 152 isync 153 154l2_disabled: 155#endif 156 157/* clear registers/arrays not reset by hardware */ 158 159 /* L1 */ 160 li r0,2 161 mtspr L1CSR0,r0 /* invalidate d-cache */ 162 mtspr L1CSR1,r0 /* invalidate i-cache */ 163 164 mfspr r1,DBSR 165 mtspr DBSR,r1 /* Clear all valid bits */ 166 167 /* 168 * Enable L1 Caches early 169 * 170 */ 171 172#if defined(CONFIG_E500MC) && defined(CONFIG_SYS_CACHE_STASHING) 173 /* set stash id to (coreID) * 2 + 32 + L1 CT (0) */ 174 li r2,(32 + 0) 175 mtspr L1CSR2,r2 176#endif 177 178 /* Enable/invalidate the I-Cache */ 179 lis r2,(L1CSR1_ICFI|L1CSR1_ICLFR)@h 180 ori r2,r2,(L1CSR1_ICFI|L1CSR1_ICLFR)@l 181 mtspr SPRN_L1CSR1,r2 1821: 183 mfspr r3,SPRN_L1CSR1 184 and. r1,r3,r2 185 bne 1b 186 187 lis r3,(L1CSR1_CPE|L1CSR1_ICE)@h 188 ori r3,r3,(L1CSR1_CPE|L1CSR1_ICE)@l 189 mtspr SPRN_L1CSR1,r3 190 isync 1912: 192 mfspr r3,SPRN_L1CSR1 193 andi. r1,r3,L1CSR1_ICE@l 194 beq 2b 195 196 /* Enable/invalidate the D-Cache */ 197 lis r2,(L1CSR0_DCFI|L1CSR0_DCLFR)@h 198 ori r2,r2,(L1CSR0_DCFI|L1CSR0_DCLFR)@l 199 mtspr SPRN_L1CSR0,r2 2001: 201 mfspr r3,SPRN_L1CSR0 202 and. r1,r3,r2 203 bne 1b 204 205 lis r3,(L1CSR0_CPE|L1CSR0_DCE)@h 206 ori r3,r3,(L1CSR0_CPE|L1CSR0_DCE)@l 207 mtspr SPRN_L1CSR0,r3 208 isync 2092: 210 mfspr r3,SPRN_L1CSR0 211 andi. r1,r3,L1CSR0_DCE@l 212 beq 2b 213 214 .macro create_tlb1_entry esel ts tsize epn wimg rpn perm phy_high scratch 215 lis \scratch, FSL_BOOKE_MAS0(1, \esel, 0)@h 216 ori \scratch, \scratch, FSL_BOOKE_MAS0(1, \esel, 0)@l 217 mtspr MAS0, \scratch 218 lis \scratch, FSL_BOOKE_MAS1(1, 1, 0, \ts, \tsize)@h 219 ori \scratch, \scratch, FSL_BOOKE_MAS1(1, 1, 0, \ts, \tsize)@l 220 mtspr MAS1, \scratch 221 lis \scratch, FSL_BOOKE_MAS2(\epn, \wimg)@h 222 ori \scratch, \scratch, FSL_BOOKE_MAS2(\epn, \wimg)@l 223 mtspr MAS2, \scratch 224 lis \scratch, FSL_BOOKE_MAS3(\rpn, 0, \perm)@h 225 ori \scratch, \scratch, FSL_BOOKE_MAS3(\rpn, 0, \perm)@l 226 mtspr MAS3, \scratch 227 lis \scratch, \phy_high@h 228 ori \scratch, \scratch, \phy_high@l 229 mtspr MAS7, \scratch 230 isync 231 msync 232 tlbwe 233 isync 234 .endm 235 236 .macro create_tlb0_entry esel ts tsize epn wimg rpn perm phy_high scratch 237 lis \scratch, FSL_BOOKE_MAS0(0, \esel, 0)@h 238 ori \scratch, \scratch, FSL_BOOKE_MAS0(0, \esel, 0)@l 239 mtspr MAS0, \scratch 240 lis \scratch, FSL_BOOKE_MAS1(1, 0, 0, \ts, \tsize)@h 241 ori \scratch, \scratch, FSL_BOOKE_MAS1(1, 0, 0, \ts, \tsize)@l 242 mtspr MAS1, \scratch 243 lis \scratch, FSL_BOOKE_MAS2(\epn, \wimg)@h 244 ori \scratch, \scratch, FSL_BOOKE_MAS2(\epn, \wimg)@l 245 mtspr MAS2, \scratch 246 lis \scratch, FSL_BOOKE_MAS3(\rpn, 0, \perm)@h 247 ori \scratch, \scratch, FSL_BOOKE_MAS3(\rpn, 0, \perm)@l 248 mtspr MAS3, \scratch 249 lis \scratch, \phy_high@h 250 ori \scratch, \scratch, \phy_high@l 251 mtspr MAS7, \scratch 252 isync 253 msync 254 tlbwe 255 isync 256 .endm 257 258 .macro delete_tlb1_entry esel scratch 259 lis \scratch, FSL_BOOKE_MAS0(1, \esel, 0)@h 260 ori \scratch, \scratch, FSL_BOOKE_MAS0(1, \esel, 0)@l 261 mtspr MAS0, \scratch 262 li \scratch, 0 263 mtspr MAS1, \scratch 264 isync 265 msync 266 tlbwe 267 isync 268 .endm 269 270 .macro delete_tlb0_entry esel epn wimg scratch 271 lis \scratch, FSL_BOOKE_MAS0(0, \esel, 0)@h 272 ori \scratch, \scratch, FSL_BOOKE_MAS0(0, \esel, 0)@l 273 mtspr MAS0, \scratch 274 li \scratch, 0 275 mtspr MAS1, \scratch 276 lis \scratch, FSL_BOOKE_MAS2(\epn, \wimg)@h 277 ori \scratch, \scratch, FSL_BOOKE_MAS2(\epn, \wimg)@l 278 mtspr MAS2, \scratch 279 isync 280 msync 281 tlbwe 282 isync 283 .endm 284 285#if defined(CONFIG_SYS_PPC_E500_DEBUG_TLB) && !defined(CONFIG_NAND_SPL) 286/* 287 * TLB entry for debuggging in AS1 288 * Create temporary TLB entry in AS0 to handle debug exception 289 * As on debug exception MSR is cleared i.e. Address space is changed 290 * to 0. A TLB entry (in AS0) is required to handle debug exception generated 291 * in AS1. 292 */ 293 294#if !defined(CONFIG_SYS_RAMBOOT) && !defined(CONFIG_SECURE_BOOT) 295/* 296 * TLB entry is created for IVPR + IVOR15 to map on valid OP code address 297 * bacause flash's virtual address maps to 0xff800000 - 0xffffffff. 298 * and this window is outside of 4K boot window. 299 */ 300 create_tlb1_entry CONFIG_SYS_PPC_E500_DEBUG_TLB, \ 301 0, BOOKE_PAGESZ_4M, \ 302 CONFIG_SYS_MONITOR_BASE & 0xffc00000, MAS2_I|MAS2_G, \ 303 0xffc00000, MAS3_SX|MAS3_SW|MAS3_SR, \ 304 0, r6 305 306#elif !defined(CONFIG_SYS_RAMBOOT) && defined(CONFIG_SECURE_BOOT) 307 create_tlb1_entry CONFIG_SYS_PPC_E500_DEBUG_TLB, \ 308 0, BOOKE_PAGESZ_1M, \ 309 CONFIG_SYS_MONITOR_BASE, MAS2_I|MAS2_G, \ 310 CONFIG_SYS_PBI_FLASH_WINDOW, MAS3_SX|MAS3_SW|MAS3_SR, \ 311 0, r6 312#else 313/* 314 * TLB entry is created for IVPR + IVOR15 to map on valid OP code address 315 * because "nexti" will resize TLB to 4K 316 */ 317 create_tlb1_entry CONFIG_SYS_PPC_E500_DEBUG_TLB, \ 318 0, BOOKE_PAGESZ_256K, \ 319 CONFIG_SYS_MONITOR_BASE, MAS2_I, \ 320 CONFIG_SYS_MONITOR_BASE, MAS3_SX|MAS3_SW|MAS3_SR, \ 321 0, r6 322#endif 323#endif 324 325/* 326 * Ne need to setup interrupt vector for NAND SPL 327 * because NAND SPL never compiles it. 328 */ 329#if !defined(CONFIG_NAND_SPL) 330 /* Setup interrupt vectors */ 331 lis r1,CONFIG_SYS_MONITOR_BASE@h 332 mtspr IVPR,r1 333 334 lis r3,(CONFIG_SYS_MONITOR_BASE & 0xffff)@h 335 ori r3,r3,(CONFIG_SYS_MONITOR_BASE & 0xffff)@l 336 337 addi r4,r3,CriticalInput - _start + _START_OFFSET 338 mtspr IVOR0,r4 /* 0: Critical input */ 339 addi r4,r3,MachineCheck - _start + _START_OFFSET 340 mtspr IVOR1,r4 /* 1: Machine check */ 341 addi r4,r3,DataStorage - _start + _START_OFFSET 342 mtspr IVOR2,r4 /* 2: Data storage */ 343 addi r4,r3,InstStorage - _start + _START_OFFSET 344 mtspr IVOR3,r4 /* 3: Instruction storage */ 345 addi r4,r3,ExtInterrupt - _start + _START_OFFSET 346 mtspr IVOR4,r4 /* 4: External interrupt */ 347 addi r4,r3,Alignment - _start + _START_OFFSET 348 mtspr IVOR5,r4 /* 5: Alignment */ 349 addi r4,r3,ProgramCheck - _start + _START_OFFSET 350 mtspr IVOR6,r4 /* 6: Program check */ 351 addi r4,r3,FPUnavailable - _start + _START_OFFSET 352 mtspr IVOR7,r4 /* 7: floating point unavailable */ 353 addi r4,r3,SystemCall - _start + _START_OFFSET 354 mtspr IVOR8,r4 /* 8: System call */ 355 /* 9: Auxiliary processor unavailable(unsupported) */ 356 addi r4,r3,Decrementer - _start + _START_OFFSET 357 mtspr IVOR10,r4 /* 10: Decrementer */ 358 addi r4,r3,IntervalTimer - _start + _START_OFFSET 359 mtspr IVOR11,r4 /* 11: Interval timer */ 360 addi r4,r3,WatchdogTimer - _start + _START_OFFSET 361 mtspr IVOR12,r4 /* 12: Watchdog timer */ 362 addi r4,r3,DataTLBError - _start + _START_OFFSET 363 mtspr IVOR13,r4 /* 13: Data TLB error */ 364 addi r4,r3,InstructionTLBError - _start + _START_OFFSET 365 mtspr IVOR14,r4 /* 14: Instruction TLB error */ 366 addi r4,r3,DebugBreakpoint - _start + _START_OFFSET 367 mtspr IVOR15,r4 /* 15: Debug */ 368#endif 369 370 /* Clear and set up some registers. */ 371 li r0,0x0000 372 lis r1,0xffff 373 mtspr DEC,r0 /* prevent dec exceptions */ 374 mttbl r0 /* prevent fit & wdt exceptions */ 375 mttbu r0 376 mtspr TSR,r1 /* clear all timer exception status */ 377 mtspr TCR,r0 /* disable all */ 378 mtspr ESR,r0 /* clear exception syndrome register */ 379 mtspr MCSR,r0 /* machine check syndrome register */ 380 mtxer r0 /* clear integer exception register */ 381 382#ifdef CONFIG_SYS_BOOK3E_HV 383 mtspr MAS8,r0 /* make sure MAS8 is clear */ 384#endif 385 386 /* Enable Time Base and Select Time Base Clock */ 387 lis r0,HID0_EMCP@h /* Enable machine check */ 388#if defined(CONFIG_ENABLE_36BIT_PHYS) 389 ori r0,r0,HID0_ENMAS7@l /* Enable MAS7 */ 390#endif 391#ifndef CONFIG_E500MC 392 ori r0,r0,HID0_TBEN@l /* Enable Timebase */ 393#endif 394 mtspr HID0,r0 395 396#ifndef CONFIG_E500MC 397 li r0,(HID1_ASTME|HID1_ABE)@l /* Addr streaming & broadcast */ 398 mfspr r3,PVR 399 andi. r3,r3, 0xff 400 cmpwi r3,0x50@l /* if we are rev 5.0 or greater set MBDD */ 401 blt 1f 402 /* Set MBDD bit also */ 403 ori r0, r0, HID1_MBDD@l 4041: 405 mtspr HID1,r0 406#endif 407 408#ifdef CONFIG_SYS_FSL_ERRATUM_CPU_A003999 409 mfspr r3,977 410 oris r3,r3,0x0100 411 mtspr 977,r3 412#endif 413 414 /* Enable Branch Prediction */ 415#if defined(CONFIG_BTB) 416 lis r0,BUCSR_ENABLE@h 417 ori r0,r0,BUCSR_ENABLE@l 418 mtspr SPRN_BUCSR,r0 419#endif 420 421#if defined(CONFIG_SYS_INIT_DBCR) 422 lis r1,0xffff 423 ori r1,r1,0xffff 424 mtspr DBSR,r1 /* Clear all status bits */ 425 lis r0,CONFIG_SYS_INIT_DBCR@h /* DBCR0[IDM] must be set */ 426 ori r0,r0,CONFIG_SYS_INIT_DBCR@l 427 mtspr DBCR0,r0 428#endif 429 430#ifdef CONFIG_MPC8569 431#define CONFIG_SYS_LBC_ADDR (CONFIG_SYS_CCSRBAR_DEFAULT + 0x5000) 432#define CONFIG_SYS_LBCR_ADDR (CONFIG_SYS_LBC_ADDR + 0xd0) 433 434 /* MPC8569 Rev.0 silcon needs to set bit 13 of LBCR to allow elBC to 435 * use address space which is more than 12bits, and it must be done in 436 * the 4K boot page. So we set this bit here. 437 */ 438 439 /* create a temp mapping TLB0[0] for LBCR */ 440 create_tlb0_entry 0, \ 441 0, BOOKE_PAGESZ_4K, \ 442 CONFIG_SYS_LBC_ADDR, MAS2_I|MAS2_G, \ 443 CONFIG_SYS_LBC_ADDR, MAS3_SW|MAS3_SR, \ 444 0, r6 445 446 /* Set LBCR register */ 447 lis r4,CONFIG_SYS_LBCR_ADDR@h 448 ori r4,r4,CONFIG_SYS_LBCR_ADDR@l 449 450 lis r5,CONFIG_SYS_LBC_LBCR@h 451 ori r5,r5,CONFIG_SYS_LBC_LBCR@l 452 stw r5,0(r4) 453 isync 454 455 /* invalidate this temp TLB */ 456 lis r4,CONFIG_SYS_LBC_ADDR@h 457 ori r4,r4,CONFIG_SYS_LBC_ADDR@l 458 tlbivax 0,r4 459 isync 460 461#endif /* CONFIG_MPC8569 */ 462 463/* 464 * Search for the TLB that covers the code we're executing, and shrink it 465 * so that it covers only this 4K page. That will ensure that any other 466 * TLB we create won't interfere with it. We assume that the TLB exists, 467 * which is why we don't check the Valid bit of MAS1. We also assume 468 * it is in TLB1. 469 * 470 * This is necessary, for example, when booting from the on-chip ROM, 471 * which (oddly) creates a single 4GB TLB that covers CCSR and DDR. 472 */ 473 bl nexti /* Find our address */ 474nexti: mflr r1 /* R1 = our PC */ 475 li r2, 0 476 mtspr MAS6, r2 /* Assume the current PID and AS are 0 */ 477 isync 478 msync 479 tlbsx 0, r1 /* This must succeed */ 480 481 mfspr r14, MAS0 /* Save ESEL for later */ 482 rlwinm r14, r14, 16, 0xfff 483 484 /* Set the size of the TLB to 4KB */ 485 mfspr r3, MAS1 486 li r2, 0xF00 487 andc r3, r3, r2 /* Clear the TSIZE bits */ 488 ori r3, r3, MAS1_TSIZE(BOOKE_PAGESZ_4K)@l 489 oris r3, r3, MAS1_IPROT@h 490 mtspr MAS1, r3 491 492 /* 493 * Set the base address of the TLB to our PC. We assume that 494 * virtual == physical. We also assume that MAS2_EPN == MAS3_RPN. 495 */ 496 lis r3, MAS2_EPN@h 497 ori r3, r3, MAS2_EPN@l /* R3 = MAS2_EPN */ 498 499 and r1, r1, r3 /* Our PC, rounded down to the nearest page */ 500 501 mfspr r2, MAS2 502 andc r2, r2, r3 503 or r2, r2, r1 504#ifdef CONFIG_SYS_FSL_ERRATUM_A004510 505 cmpwi r27,0 506 beq 1f 507 andi. r15, r2, MAS2_I|MAS2_G /* save the old I/G for later */ 508 rlwinm r2, r2, 0, ~MAS2_I 509 ori r2, r2, MAS2_G 5101: 511#endif 512 mtspr MAS2, r2 /* Set the EPN to our PC base address */ 513 514 mfspr r2, MAS3 515 andc r2, r2, r3 516 or r2, r2, r1 517 mtspr MAS3, r2 /* Set the RPN to our PC base address */ 518 519 isync 520 msync 521 tlbwe 522 523/* 524 * Clear out any other TLB entries that may exist, to avoid conflicts. 525 * Our TLB entry is in r14. 526 */ 527 li r0, TLBIVAX_ALL | TLBIVAX_TLB0 528 tlbivax 0, r0 529 tlbsync 530 531 mfspr r4, SPRN_TLB1CFG 532 rlwinm r4, r4, 0, TLBnCFG_NENTRY_MASK 533 534 li r3, 0 535 mtspr MAS1, r3 5361: cmpw r3, r14 537#if defined(CONFIG_SYS_PPC_E500_DEBUG_TLB) && !defined(CONFIG_NAND_SPL) 538 cmpwi cr1, r3, CONFIG_SYS_PPC_E500_DEBUG_TLB 539 cror cr0*4+eq, cr0*4+eq, cr1*4+eq 540#endif 541 rlwinm r5, r3, 16, MAS0_ESEL_MSK 542 addi r3, r3, 1 543 beq 2f /* skip the entry we're executing from */ 544 545 oris r5, r5, MAS0_TLBSEL(1)@h 546 mtspr MAS0, r5 547 548 isync 549 tlbwe 550 isync 551 msync 552 5532: cmpw r3, r4 554 blt 1b 555 556/* 557 * Relocate CCSR, if necessary. We relocate CCSR if (obviously) the default 558 * location is not where we want it. This typically happens on a 36-bit 559 * system, where we want to move CCSR to near the top of 36-bit address space. 560 * 561 * To move CCSR, we create two temporary TLBs, one for the old location, and 562 * another for the new location. On CoreNet systems, we also need to create 563 * a special, temporary LAW. 564 * 565 * As a general rule, TLB0 is used for short-term TLBs, and TLB1 is used for 566 * long-term TLBs, so we use TLB0 here. 567 */ 568#if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR_PHYS) 569 570#if !defined(CONFIG_SYS_CCSRBAR_PHYS_HIGH) || !defined(CONFIG_SYS_CCSRBAR_PHYS_LOW) 571#error "CONFIG_SYS_CCSRBAR_PHYS_HIGH and CONFIG_SYS_CCSRBAR_PHYS_LOW) must be defined." 572#endif 573 574create_ccsr_new_tlb: 575 /* 576 * Create a TLB for the new location of CCSR. Register R8 is reserved 577 * for the virtual address of this TLB (CONFIG_SYS_CCSRBAR). 578 */ 579 lis r8, CONFIG_SYS_CCSRBAR@h 580 ori r8, r8, CONFIG_SYS_CCSRBAR@l 581 lis r9, (CONFIG_SYS_CCSRBAR + 0x1000)@h 582 ori r9, r9, (CONFIG_SYS_CCSRBAR + 0x1000)@l 583 create_tlb0_entry 0, \ 584 0, BOOKE_PAGESZ_4K, \ 585 CONFIG_SYS_CCSRBAR, MAS2_I|MAS2_G, \ 586 CONFIG_SYS_CCSRBAR_PHYS_LOW, MAS3_SW|MAS3_SR, \ 587 CONFIG_SYS_CCSRBAR_PHYS_HIGH, r3 588 /* 589 * Create a TLB for the current location of CCSR. Register R9 is reserved 590 * for the virtual address of this TLB (CONFIG_SYS_CCSRBAR + 0x1000). 591 */ 592create_ccsr_old_tlb: 593 create_tlb0_entry 1, \ 594 0, BOOKE_PAGESZ_4K, \ 595 CONFIG_SYS_CCSRBAR + 0x1000, MAS2_I|MAS2_G, \ 596 CONFIG_SYS_CCSRBAR_DEFAULT, MAS3_SW|MAS3_SR, \ 597 0, r3 /* The default CCSR address is always a 32-bit number */ 598 599 600 /* 601 * We have a TLB for what we think is the current (old) CCSR. Let's 602 * verify that, otherwise we won't be able to move it. 603 * CONFIG_SYS_CCSRBAR_DEFAULT is always a 32-bit number, so we only 604 * need to compare the lower 32 bits of CCSRBAR on CoreNet systems. 605 */ 606verify_old_ccsr: 607 lis r0, CONFIG_SYS_CCSRBAR_DEFAULT@h 608 ori r0, r0, CONFIG_SYS_CCSRBAR_DEFAULT@l 609#ifdef CONFIG_FSL_CORENET 610 lwz r1, 4(r9) /* CCSRBARL */ 611#else 612 lwz r1, 0(r9) /* CCSRBAR, shifted right by 12 */ 613 slwi r1, r1, 12 614#endif 615 616 cmpl 0, r0, r1 617 618 /* 619 * If the value we read from CCSRBARL is not what we expect, then 620 * enter an infinite loop. This will at least allow a debugger to 621 * halt execution and examine TLBs, etc. There's no point in going 622 * on. 623 */ 624infinite_debug_loop: 625 bne infinite_debug_loop 626 627#ifdef CONFIG_FSL_CORENET 628 629#define CCSR_LAWBARH0 (CONFIG_SYS_CCSRBAR + 0x1000) 630#define LAW_EN 0x80000000 631#define LAW_SIZE_4K 0xb 632#define CCSRBAR_LAWAR (LAW_EN | (0x1e << 20) | LAW_SIZE_4K) 633#define CCSRAR_C 0x80000000 /* Commit */ 634 635create_temp_law: 636 /* 637 * On CoreNet systems, we create the temporary LAW using a special LAW 638 * target ID of 0x1e. LAWBARH is at offset 0xc00 in CCSR. 639 */ 640 lis r0, CONFIG_SYS_CCSRBAR_PHYS_HIGH@h 641 ori r0, r0, CONFIG_SYS_CCSRBAR_PHYS_HIGH@l 642 lis r1, CONFIG_SYS_CCSRBAR_PHYS_LOW@h 643 ori r1, r1, CONFIG_SYS_CCSRBAR_PHYS_LOW@l 644 lis r2, CCSRBAR_LAWAR@h 645 ori r2, r2, CCSRBAR_LAWAR@l 646 647 stw r0, 0xc00(r9) /* LAWBARH0 */ 648 stw r1, 0xc04(r9) /* LAWBARL0 */ 649 sync 650 stw r2, 0xc08(r9) /* LAWAR0 */ 651 652 /* 653 * Read back from LAWAR to ensure the update is complete. e500mc 654 * cores also require an isync. 655 */ 656 lwz r0, 0xc08(r9) /* LAWAR0 */ 657 isync 658 659 /* 660 * Read the current CCSRBARH and CCSRBARL using load word instructions. 661 * Follow this with an isync instruction. This forces any outstanding 662 * accesses to configuration space to completion. 663 */ 664read_old_ccsrbar: 665 lwz r0, 0(r9) /* CCSRBARH */ 666 lwz r0, 4(r9) /* CCSRBARL */ 667 isync 668 669 /* 670 * Write the new values for CCSRBARH and CCSRBARL to their old 671 * locations. The CCSRBARH has a shadow register. When the CCSRBARH 672 * has a new value written it loads a CCSRBARH shadow register. When 673 * the CCSRBARL is written, the CCSRBARH shadow register contents 674 * along with the CCSRBARL value are loaded into the CCSRBARH and 675 * CCSRBARL registers, respectively. Follow this with a sync 676 * instruction. 677 */ 678write_new_ccsrbar: 679 lis r0, CONFIG_SYS_CCSRBAR_PHYS_HIGH@h 680 ori r0, r0, CONFIG_SYS_CCSRBAR_PHYS_HIGH@l 681 lis r1, CONFIG_SYS_CCSRBAR_PHYS_LOW@h 682 ori r1, r1, CONFIG_SYS_CCSRBAR_PHYS_LOW@l 683 lis r2, CCSRAR_C@h 684 ori r2, r2, CCSRAR_C@l 685 686 stw r0, 0(r9) /* Write to CCSRBARH */ 687 sync /* Make sure we write to CCSRBARH first */ 688 stw r1, 4(r9) /* Write to CCSRBARL */ 689 sync 690 691 /* 692 * Write a 1 to the commit bit (C) of CCSRAR at the old location. 693 * Follow this with a sync instruction. 694 */ 695 stw r2, 8(r9) 696 sync 697 698 /* Delete the temporary LAW */ 699delete_temp_law: 700 li r1, 0 701 stw r1, 0xc08(r8) 702 sync 703 stw r1, 0xc00(r8) 704 stw r1, 0xc04(r8) 705 sync 706 707#else /* #ifdef CONFIG_FSL_CORENET */ 708 709write_new_ccsrbar: 710 /* 711 * Read the current value of CCSRBAR using a load word instruction 712 * followed by an isync. This forces all accesses to configuration 713 * space to complete. 714 */ 715 sync 716 lwz r0, 0(r9) 717 isync 718 719/* CONFIG_SYS_CCSRBAR_PHYS right shifted by 12 */ 720#define CCSRBAR_PHYS_RS12 ((CONFIG_SYS_CCSRBAR_PHYS_HIGH << 20) | \ 721 (CONFIG_SYS_CCSRBAR_PHYS_LOW >> 12)) 722 723 /* Write the new value to CCSRBAR. */ 724 lis r0, CCSRBAR_PHYS_RS12@h 725 ori r0, r0, CCSRBAR_PHYS_RS12@l 726 stw r0, 0(r9) 727 sync 728 729 /* 730 * The manual says to perform a load of an address that does not 731 * access configuration space or the on-chip SRAM using an existing TLB, 732 * but that doesn't appear to be necessary. We will do the isync, 733 * though. 734 */ 735 isync 736 737 /* 738 * Read the contents of CCSRBAR from its new location, followed by 739 * another isync. 740 */ 741 lwz r0, 0(r8) 742 isync 743 744#endif /* #ifdef CONFIG_FSL_CORENET */ 745 746 /* Delete the temporary TLBs */ 747delete_temp_tlbs: 748 delete_tlb0_entry 0, CONFIG_SYS_CCSRBAR, MAS2_I|MAS2_G, r3 749 delete_tlb0_entry 1, CONFIG_SYS_CCSRBAR + 0x1000, MAS2_I|MAS2_G, r3 750 751#endif /* #if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR_PHYS) */ 752 753#ifdef CONFIG_SYS_FSL_ERRATUM_A004510 754#define DCSR_LAWBARH0 (CONFIG_SYS_CCSRBAR + 0x1000) 755#define LAW_SIZE_1M 0x13 756#define DCSRBAR_LAWAR (LAW_EN | (0x1d << 20) | LAW_SIZE_1M) 757 758 cmpwi r27,0 759 beq 9f 760 761 /* 762 * Create a TLB entry for CCSR 763 * 764 * We're executing out of TLB1 entry in r14, and that's the only 765 * TLB entry that exists. To allocate some TLB entries for our 766 * own use, flip a bit high enough that we won't flip it again 767 * via incrementing. 768 */ 769 770 xori r8, r14, 32 771 lis r0, MAS0_TLBSEL(1)@h 772 rlwimi r0, r8, 16, MAS0_ESEL_MSK 773 lis r1, FSL_BOOKE_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_16M)@h 774 ori r1, r1, FSL_BOOKE_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_16M)@l 775 lis r7, CONFIG_SYS_CCSRBAR@h 776 ori r7, r7, CONFIG_SYS_CCSRBAR@l 777 ori r2, r7, MAS2_I|MAS2_G 778 lis r3, FSL_BOOKE_MAS3(CONFIG_SYS_CCSRBAR_PHYS_LOW, 0, (MAS3_SW|MAS3_SR))@h 779 ori r3, r3, FSL_BOOKE_MAS3(CONFIG_SYS_CCSRBAR_PHYS_LOW, 0, (MAS3_SW|MAS3_SR))@l 780 lis r4, CONFIG_SYS_CCSRBAR_PHYS_HIGH@h 781 ori r4, r4, CONFIG_SYS_CCSRBAR_PHYS_HIGH@l 782 mtspr MAS0, r0 783 mtspr MAS1, r1 784 mtspr MAS2, r2 785 mtspr MAS3, r3 786 mtspr MAS7, r4 787 isync 788 tlbwe 789 isync 790 msync 791 792 /* Map DCSR temporarily to physical address zero */ 793 li r0, 0 794 lis r3, DCSRBAR_LAWAR@h 795 ori r3, r3, DCSRBAR_LAWAR@l 796 797 stw r0, 0xc00(r7) /* LAWBARH0 */ 798 stw r0, 0xc04(r7) /* LAWBARL0 */ 799 sync 800 stw r3, 0xc08(r7) /* LAWAR0 */ 801 802 /* Read back from LAWAR to ensure the update is complete. */ 803 lwz r3, 0xc08(r7) /* LAWAR0 */ 804 isync 805 806 /* Create a TLB entry for DCSR at zero */ 807 808 addi r9, r8, 1 809 lis r0, MAS0_TLBSEL(1)@h 810 rlwimi r0, r9, 16, MAS0_ESEL_MSK 811 lis r1, FSL_BOOKE_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_1M)@h 812 ori r1, r1, FSL_BOOKE_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_1M)@l 813 li r6, 0 /* DCSR effective address */ 814 ori r2, r6, MAS2_I|MAS2_G 815 li r3, MAS3_SW|MAS3_SR 816 li r4, 0 817 mtspr MAS0, r0 818 mtspr MAS1, r1 819 mtspr MAS2, r2 820 mtspr MAS3, r3 821 mtspr MAS7, r4 822 isync 823 tlbwe 824 isync 825 msync 826 827 /* enable the timebase */ 828#define CTBENR 0xe2084 829 li r3, 1 830 addis r4, r7, CTBENR@ha 831 stw r3, CTBENR@l(r4) 832 lwz r3, CTBENR@l(r4) 833 twi 0,r3,0 834 isync 835 836 .macro erratum_set_ccsr offset value 837 addis r3, r7, \offset@ha 838 lis r4, \value@h 839 addi r3, r3, \offset@l 840 ori r4, r4, \value@l 841 bl erratum_set_value 842 .endm 843 844 .macro erratum_set_dcsr offset value 845 addis r3, r6, \offset@ha 846 lis r4, \value@h 847 addi r3, r3, \offset@l 848 ori r4, r4, \value@l 849 bl erratum_set_value 850 .endm 851 852 erratum_set_dcsr 0xb0e08 0xe0201800 853 erratum_set_dcsr 0xb0e18 0xe0201800 854 erratum_set_dcsr 0xb0e38 0xe0400000 855 erratum_set_dcsr 0xb0008 0x00900000 856 erratum_set_dcsr 0xb0e40 0xe00a0000 857 erratum_set_ccsr 0x18600 CONFIG_SYS_FSL_CORENET_SNOOPVEC_COREONLY 858 erratum_set_ccsr 0x10f00 0x415e5000 859 erratum_set_ccsr 0x11f00 0x415e5000 860 861 /* Make temp mapping uncacheable again, if it was initially */ 862 bl 2f 8632: mflr r3 864 tlbsx 0, r3 865 mfspr r4, MAS2 866 rlwimi r4, r15, 0, MAS2_I 867 rlwimi r4, r15, 0, MAS2_G 868 mtspr MAS2, r4 869 isync 870 tlbwe 871 isync 872 msync 873 874 /* Clear the cache */ 875 lis r3,(L1CSR1_ICFI|L1CSR1_ICLFR)@h 876 ori r3,r3,(L1CSR1_ICFI|L1CSR1_ICLFR)@l 877 sync 878 isync 879 mtspr SPRN_L1CSR1,r3 880 isync 8812: sync 882 mfspr r4,SPRN_L1CSR1 883 and. r4,r4,r3 884 bne 2b 885 886 lis r3,(L1CSR1_CPE|L1CSR1_ICE)@h 887 ori r3,r3,(L1CSR1_CPE|L1CSR1_ICE)@l 888 sync 889 isync 890 mtspr SPRN_L1CSR1,r3 891 isync 8922: sync 893 mfspr r4,SPRN_L1CSR1 894 and. r4,r4,r3 895 beq 2b 896 897 /* Remove temporary mappings */ 898 lis r0, MAS0_TLBSEL(1)@h 899 rlwimi r0, r9, 16, MAS0_ESEL_MSK 900 li r3, 0 901 mtspr MAS0, r0 902 mtspr MAS1, r3 903 isync 904 tlbwe 905 isync 906 msync 907 908 li r3, 0 909 stw r3, 0xc08(r7) /* LAWAR0 */ 910 lwz r3, 0xc08(r7) 911 isync 912 913 lis r0, MAS0_TLBSEL(1)@h 914 rlwimi r0, r8, 16, MAS0_ESEL_MSK 915 li r3, 0 916 mtspr MAS0, r0 917 mtspr MAS1, r3 918 isync 919 tlbwe 920 isync 921 msync 922 923 b 9f 924 925 /* r3 = addr, r4 = value, clobbers r5, r11, r12 */ 926erratum_set_value: 927 /* Lock two cache lines into I-Cache */ 928 sync 929 mfspr r11, SPRN_L1CSR1 930 rlwinm r11, r11, 0, ~L1CSR1_ICUL 931 sync 932 isync 933 mtspr SPRN_L1CSR1, r11 934 isync 935 936 mflr r12 937 bl 5f 9385: mflr r5 939 addi r5, r5, 2f - 5b 940 icbtls 0, 0, r5 941 addi r5, r5, 64 942 943 sync 944 mfspr r11, SPRN_L1CSR1 9453: andi. r11, r11, L1CSR1_ICUL 946 bne 3b 947 948 icbtls 0, 0, r5 949 addi r5, r5, 64 950 951 sync 952 mfspr r11, SPRN_L1CSR1 9533: andi. r11, r11, L1CSR1_ICUL 954 bne 3b 955 956 b 2f 957 .align 6 958 /* Inside a locked cacheline, wait a while, write, then wait a while */ 9592: sync 960 961 mfspr r5, SPRN_TBRL 962 addis r11, r5, 0x10000@h /* wait 65536 timebase ticks */ 9634: mfspr r5, SPRN_TBRL 964 subf. r5, r5, r11 965 bgt 4b 966 967 stw r4, 0(r3) 968 969 mfspr r5, SPRN_TBRL 970 addis r11, r5, 0x10000@h /* wait 65536 timebase ticks */ 9714: mfspr r5, SPRN_TBRL 972 subf. r5, r5, r11 973 bgt 4b 974 975 sync 976 977 /* 978 * Fill out the rest of this cache line and the next with nops, 979 * to ensure that nothing outside the locked area will be 980 * fetched due to a branch. 981 */ 982 .rept 19 983 nop 984 .endr 985 986 sync 987 mfspr r11, SPRN_L1CSR1 988 rlwinm r11, r11, 0, ~L1CSR1_ICUL 989 sync 990 isync 991 mtspr SPRN_L1CSR1, r11 992 isync 993 994 mtlr r12 995 blr 996 9979: 998#endif 999 1000create_init_ram_area: 1001 lis r6,FSL_BOOKE_MAS0(1, 15, 0)@h 1002 ori r6,r6,FSL_BOOKE_MAS0(1, 15, 0)@l 1003 1004#if !defined(CONFIG_SYS_RAMBOOT) && !defined(CONFIG_SECURE_BOOT) 1005 /* create a temp mapping in AS=1 to the 4M boot window */ 1006 create_tlb1_entry 15, \ 1007 1, BOOKE_PAGESZ_4M, \ 1008 CONFIG_SYS_MONITOR_BASE & 0xffc00000, MAS2_I|MAS2_G, \ 1009 0xffc00000, MAS3_SX|MAS3_SW|MAS3_SR, \ 1010 0, r6 1011 1012#elif !defined(CONFIG_SYS_RAMBOOT) && defined(CONFIG_SECURE_BOOT) 1013 /* create a temp mapping in AS = 1 for Flash mapping 1014 * created by PBL for ISBC code 1015 */ 1016 create_tlb1_entry 15, \ 1017 1, BOOKE_PAGESZ_1M, \ 1018 CONFIG_SYS_MONITOR_BASE, MAS2_I|MAS2_G, \ 1019 CONFIG_SYS_PBI_FLASH_WINDOW, MAS3_SX|MAS3_SW|MAS3_SR, \ 1020 0, r6 1021#else 1022 /* 1023 * create a temp mapping in AS=1 to the 1M CONFIG_SYS_MONITOR_BASE space, the main 1024 * image has been relocated to CONFIG_SYS_MONITOR_BASE on the second stage. 1025 */ 1026 create_tlb1_entry 15, \ 1027 1, BOOKE_PAGESZ_1M, \ 1028 CONFIG_SYS_MONITOR_BASE, MAS2_I|MAS2_G, \ 1029 CONFIG_SYS_MONITOR_BASE, MAS3_SX|MAS3_SW|MAS3_SR, \ 1030 0, r6 1031#endif 1032 1033 /* create a temp mapping in AS=1 to the stack */ 1034#if defined(CONFIG_SYS_INIT_RAM_ADDR_PHYS_LOW) && \ 1035 defined(CONFIG_SYS_INIT_RAM_ADDR_PHYS_HIGH) 1036 create_tlb1_entry 14, \ 1037 1, BOOKE_PAGESZ_16K, \ 1038 CONFIG_SYS_INIT_RAM_ADDR, 0, \ 1039 CONFIG_SYS_INIT_RAM_ADDR_PHYS_LOW, MAS3_SX|MAS3_SW|MAS3_SR, \ 1040 CONFIG_SYS_INIT_RAM_ADDR_PHYS_HIGH, r6 1041 1042#else 1043 create_tlb1_entry 14, \ 1044 1, BOOKE_PAGESZ_16K, \ 1045 CONFIG_SYS_INIT_RAM_ADDR, 0, \ 1046 CONFIG_SYS_INIT_RAM_ADDR, MAS3_SX|MAS3_SW|MAS3_SR, \ 1047 0, r6 1048#endif 1049 1050 lis r6,MSR_IS|MSR_DS|MSR_DE@h 1051 ori r6,r6,MSR_IS|MSR_DS|MSR_DE@l 1052 lis r7,switch_as@h 1053 ori r7,r7,switch_as@l 1054 1055 mtspr SPRN_SRR0,r7 1056 mtspr SPRN_SRR1,r6 1057 rfi 1058 1059switch_as: 1060/* L1 DCache is used for initial RAM */ 1061 1062 /* Allocate Initial RAM in data cache. 1063 */ 1064 lis r3,CONFIG_SYS_INIT_RAM_ADDR@h 1065 ori r3,r3,CONFIG_SYS_INIT_RAM_ADDR@l 1066 mfspr r2, L1CFG0 1067 andi. r2, r2, 0x1ff 1068 /* cache size * 1024 / (2 * L1 line size) */ 1069 slwi r2, r2, (10 - 1 - L1_CACHE_SHIFT) 1070 mtctr r2 1071 li r0,0 10721: 1073 dcbz r0,r3 1074 dcbtls 0,r0,r3 1075 addi r3,r3,CONFIG_SYS_CACHELINE_SIZE 1076 bdnz 1b 1077 1078 /* Jump out the last 4K page and continue to 'normal' start */ 1079#ifdef CONFIG_SYS_RAMBOOT 1080 b _start_cont 1081#else 1082 /* Calculate absolute address in FLASH and jump there */ 1083 /*--------------------------------------------------------------*/ 1084 lis r3,CONFIG_SYS_MONITOR_BASE@h 1085 ori r3,r3,CONFIG_SYS_MONITOR_BASE@l 1086 addi r3,r3,_start_cont - _start + _START_OFFSET 1087 mtlr r3 1088 blr 1089#endif 1090 1091 .text 1092 .globl _start 1093_start: 1094 .long 0x27051956 /* U-BOOT Magic Number */ 1095 .globl version_string 1096version_string: 1097 .ascii U_BOOT_VERSION_STRING, "\0" 1098 1099 .align 4 1100 .globl _start_cont 1101_start_cont: 1102 /* Setup the stack in initial RAM,could be L2-as-SRAM or L1 dcache*/ 1103 lis r3,(CONFIG_SYS_INIT_RAM_ADDR)@h 1104 ori r3,r3,((CONFIG_SYS_INIT_SP_OFFSET-16)&~0xf)@l /* Align to 16 */ 1105 li r0,0 1106 stw r0,0(r3) /* Terminate Back Chain */ 1107 stw r0,+4(r3) /* NULL return address. */ 1108 mr r1,r3 /* Transfer to SP(r1) */ 1109 1110 GET_GOT 1111 bl cpu_init_early_f 1112 1113 /* switch back to AS = 0 */ 1114 lis r3,(MSR_CE|MSR_ME|MSR_DE)@h 1115 ori r3,r3,(MSR_CE|MSR_ME|MSR_DE)@l 1116 mtmsr r3 1117 isync 1118 1119 bl cpu_init_f 1120 bl board_init_f 1121 isync 1122 1123 /* NOTREACHED - board_init_f() does not return */ 1124 1125#ifndef CONFIG_NAND_SPL 1126 . = EXC_OFF_SYS_RESET 1127 .globl _start_of_vectors 1128_start_of_vectors: 1129 1130/* Critical input. */ 1131 CRIT_EXCEPTION(0x0100, CriticalInput, CritcalInputException) 1132 1133/* Machine check */ 1134 MCK_EXCEPTION(0x200, MachineCheck, MachineCheckException) 1135 1136/* Data Storage exception. */ 1137 STD_EXCEPTION(0x0300, DataStorage, UnknownException) 1138 1139/* Instruction Storage exception. */ 1140 STD_EXCEPTION(0x0400, InstStorage, UnknownException) 1141 1142/* External Interrupt exception. */ 1143 STD_EXCEPTION(0x0500, ExtInterrupt, ExtIntException) 1144 1145/* Alignment exception. */ 1146 . = 0x0600 1147Alignment: 1148 EXCEPTION_PROLOG(SRR0, SRR1) 1149 mfspr r4,DAR 1150 stw r4,_DAR(r21) 1151 mfspr r5,DSISR 1152 stw r5,_DSISR(r21) 1153 addi r3,r1,STACK_FRAME_OVERHEAD 1154 EXC_XFER_TEMPLATE(Alignment, AlignmentException, MSR_KERNEL, COPY_EE) 1155 1156/* Program check exception */ 1157 . = 0x0700 1158ProgramCheck: 1159 EXCEPTION_PROLOG(SRR0, SRR1) 1160 addi r3,r1,STACK_FRAME_OVERHEAD 1161 EXC_XFER_TEMPLATE(ProgramCheck, ProgramCheckException, 1162 MSR_KERNEL, COPY_EE) 1163 1164 /* No FPU on MPC85xx. This exception is not supposed to happen. 1165 */ 1166 STD_EXCEPTION(0x0800, FPUnavailable, UnknownException) 1167 1168 . = 0x0900 1169/* 1170 * r0 - SYSCALL number 1171 * r3-... arguments 1172 */ 1173SystemCall: 1174 addis r11,r0,0 /* get functions table addr */ 1175 ori r11,r11,0 /* Note: this code is patched in trap_init */ 1176 addis r12,r0,0 /* get number of functions */ 1177 ori r12,r12,0 1178 1179 cmplw 0,r0,r12 1180 bge 1f 1181 1182 rlwinm r0,r0,2,0,31 /* fn_addr = fn_tbl[r0] */ 1183 add r11,r11,r0 1184 lwz r11,0(r11) 1185 1186 li r20,0xd00-4 /* Get stack pointer */ 1187 lwz r12,0(r20) 1188 subi r12,r12,12 /* Adjust stack pointer */ 1189 li r0,0xc00+_end_back-SystemCall 1190 cmplw 0,r0,r12 /* Check stack overflow */ 1191 bgt 1f 1192 stw r12,0(r20) 1193 1194 mflr r0 1195 stw r0,0(r12) 1196 mfspr r0,SRR0 1197 stw r0,4(r12) 1198 mfspr r0,SRR1 1199 stw r0,8(r12) 1200 1201 li r12,0xc00+_back-SystemCall 1202 mtlr r12 1203 mtspr SRR0,r11 1204 12051: SYNC 1206 rfi 1207_back: 1208 1209 mfmsr r11 /* Disable interrupts */ 1210 li r12,0 1211 ori r12,r12,MSR_EE 1212 andc r11,r11,r12 1213 SYNC /* Some chip revs need this... */ 1214 mtmsr r11 1215 SYNC 1216 1217 li r12,0xd00-4 /* restore regs */ 1218 lwz r12,0(r12) 1219 1220 lwz r11,0(r12) 1221 mtlr r11 1222 lwz r11,4(r12) 1223 mtspr SRR0,r11 1224 lwz r11,8(r12) 1225 mtspr SRR1,r11 1226 1227 addi r12,r12,12 /* Adjust stack pointer */ 1228 li r20,0xd00-4 1229 stw r12,0(r20) 1230 1231 SYNC 1232 rfi 1233_end_back: 1234 1235 STD_EXCEPTION(0x0a00, Decrementer, timer_interrupt) 1236 STD_EXCEPTION(0x0b00, IntervalTimer, UnknownException) 1237 STD_EXCEPTION(0x0c00, WatchdogTimer, UnknownException) 1238 1239 STD_EXCEPTION(0x0d00, DataTLBError, UnknownException) 1240 STD_EXCEPTION(0x0e00, InstructionTLBError, UnknownException) 1241 1242 CRIT_EXCEPTION(0x0f00, DebugBreakpoint, DebugException ) 1243 1244 .globl _end_of_vectors 1245_end_of_vectors: 1246 1247 1248 . = . + (0x100 - ( . & 0xff )) /* align for debug */ 1249 1250/* 1251 * This code finishes saving the registers to the exception frame 1252 * and jumps to the appropriate handler for the exception. 1253 * Register r21 is pointer into trap frame, r1 has new stack pointer. 1254 */ 1255 .globl transfer_to_handler 1256transfer_to_handler: 1257 stw r22,_NIP(r21) 1258 lis r22,MSR_POW@h 1259 andc r23,r23,r22 1260 stw r23,_MSR(r21) 1261 SAVE_GPR(7, r21) 1262 SAVE_4GPRS(8, r21) 1263 SAVE_8GPRS(12, r21) 1264 SAVE_8GPRS(24, r21) 1265 1266 mflr r23 1267 andi. r24,r23,0x3f00 /* get vector offset */ 1268 stw r24,TRAP(r21) 1269 li r22,0 1270 stw r22,RESULT(r21) 1271 mtspr SPRG2,r22 /* r1 is now kernel sp */ 1272 1273 lwz r24,0(r23) /* virtual address of handler */ 1274 lwz r23,4(r23) /* where to go when done */ 1275 mtspr SRR0,r24 1276 mtspr SRR1,r20 1277 mtlr r23 1278 SYNC 1279 rfi /* jump to handler, enable MMU */ 1280 1281int_return: 1282 mfmsr r28 /* Disable interrupts */ 1283 li r4,0 1284 ori r4,r4,MSR_EE 1285 andc r28,r28,r4 1286 SYNC /* Some chip revs need this... */ 1287 mtmsr r28 1288 SYNC 1289 lwz r2,_CTR(r1) 1290 lwz r0,_LINK(r1) 1291 mtctr r2 1292 mtlr r0 1293 lwz r2,_XER(r1) 1294 lwz r0,_CCR(r1) 1295 mtspr XER,r2 1296 mtcrf 0xFF,r0 1297 REST_10GPRS(3, r1) 1298 REST_10GPRS(13, r1) 1299 REST_8GPRS(23, r1) 1300 REST_GPR(31, r1) 1301 lwz r2,_NIP(r1) /* Restore environment */ 1302 lwz r0,_MSR(r1) 1303 mtspr SRR0,r2 1304 mtspr SRR1,r0 1305 lwz r0,GPR0(r1) 1306 lwz r2,GPR2(r1) 1307 lwz r1,GPR1(r1) 1308 SYNC 1309 rfi 1310 1311crit_return: 1312 mfmsr r28 /* Disable interrupts */ 1313 li r4,0 1314 ori r4,r4,MSR_EE 1315 andc r28,r28,r4 1316 SYNC /* Some chip revs need this... */ 1317 mtmsr r28 1318 SYNC 1319 lwz r2,_CTR(r1) 1320 lwz r0,_LINK(r1) 1321 mtctr r2 1322 mtlr r0 1323 lwz r2,_XER(r1) 1324 lwz r0,_CCR(r1) 1325 mtspr XER,r2 1326 mtcrf 0xFF,r0 1327 REST_10GPRS(3, r1) 1328 REST_10GPRS(13, r1) 1329 REST_8GPRS(23, r1) 1330 REST_GPR(31, r1) 1331 lwz r2,_NIP(r1) /* Restore environment */ 1332 lwz r0,_MSR(r1) 1333 mtspr SPRN_CSRR0,r2 1334 mtspr SPRN_CSRR1,r0 1335 lwz r0,GPR0(r1) 1336 lwz r2,GPR2(r1) 1337 lwz r1,GPR1(r1) 1338 SYNC 1339 rfci 1340 1341mck_return: 1342 mfmsr r28 /* Disable interrupts */ 1343 li r4,0 1344 ori r4,r4,MSR_EE 1345 andc r28,r28,r4 1346 SYNC /* Some chip revs need this... */ 1347 mtmsr r28 1348 SYNC 1349 lwz r2,_CTR(r1) 1350 lwz r0,_LINK(r1) 1351 mtctr r2 1352 mtlr r0 1353 lwz r2,_XER(r1) 1354 lwz r0,_CCR(r1) 1355 mtspr XER,r2 1356 mtcrf 0xFF,r0 1357 REST_10GPRS(3, r1) 1358 REST_10GPRS(13, r1) 1359 REST_8GPRS(23, r1) 1360 REST_GPR(31, r1) 1361 lwz r2,_NIP(r1) /* Restore environment */ 1362 lwz r0,_MSR(r1) 1363 mtspr SPRN_MCSRR0,r2 1364 mtspr SPRN_MCSRR1,r0 1365 lwz r0,GPR0(r1) 1366 lwz r2,GPR2(r1) 1367 lwz r1,GPR1(r1) 1368 SYNC 1369 rfmci 1370 1371/* Cache functions. 1372*/ 1373.globl flush_icache 1374flush_icache: 1375.globl invalidate_icache 1376invalidate_icache: 1377 mfspr r0,L1CSR1 1378 ori r0,r0,L1CSR1_ICFI 1379 msync 1380 isync 1381 mtspr L1CSR1,r0 1382 isync 1383 blr /* entire I cache */ 1384 1385.globl invalidate_dcache 1386invalidate_dcache: 1387 mfspr r0,L1CSR0 1388 ori r0,r0,L1CSR0_DCFI 1389 msync 1390 isync 1391 mtspr L1CSR0,r0 1392 isync 1393 blr 1394 1395 .globl icache_enable 1396icache_enable: 1397 mflr r8 1398 bl invalidate_icache 1399 mtlr r8 1400 isync 1401 mfspr r4,L1CSR1 1402 ori r4,r4,0x0001 1403 oris r4,r4,0x0001 1404 mtspr L1CSR1,r4 1405 isync 1406 blr 1407 1408 .globl icache_disable 1409icache_disable: 1410 mfspr r0,L1CSR1 1411 lis r3,0 1412 ori r3,r3,L1CSR1_ICE 1413 andc r0,r0,r3 1414 mtspr L1CSR1,r0 1415 isync 1416 blr 1417 1418 .globl icache_status 1419icache_status: 1420 mfspr r3,L1CSR1 1421 andi. r3,r3,L1CSR1_ICE 1422 blr 1423 1424 .globl dcache_enable 1425dcache_enable: 1426 mflr r8 1427 bl invalidate_dcache 1428 mtlr r8 1429 isync 1430 mfspr r0,L1CSR0 1431 ori r0,r0,0x0001 1432 oris r0,r0,0x0001 1433 msync 1434 isync 1435 mtspr L1CSR0,r0 1436 isync 1437 blr 1438 1439 .globl dcache_disable 1440dcache_disable: 1441 mfspr r3,L1CSR0 1442 lis r4,0 1443 ori r4,r4,L1CSR0_DCE 1444 andc r3,r3,r4 1445 mtspr L1CSR0,r3 1446 isync 1447 blr 1448 1449 .globl dcache_status 1450dcache_status: 1451 mfspr r3,L1CSR0 1452 andi. r3,r3,L1CSR0_DCE 1453 blr 1454 1455 .globl get_pir 1456get_pir: 1457 mfspr r3,PIR 1458 blr 1459 1460 .globl get_pvr 1461get_pvr: 1462 mfspr r3,PVR 1463 blr 1464 1465 .globl get_svr 1466get_svr: 1467 mfspr r3,SVR 1468 blr 1469 1470 .globl wr_tcr 1471wr_tcr: 1472 mtspr TCR,r3 1473 blr 1474 1475/*------------------------------------------------------------------------------- */ 1476/* Function: in8 */ 1477/* Description: Input 8 bits */ 1478/*------------------------------------------------------------------------------- */ 1479 .globl in8 1480in8: 1481 lbz r3,0x0000(r3) 1482 blr 1483 1484/*------------------------------------------------------------------------------- */ 1485/* Function: out8 */ 1486/* Description: Output 8 bits */ 1487/*------------------------------------------------------------------------------- */ 1488 .globl out8 1489out8: 1490 stb r4,0x0000(r3) 1491 sync 1492 blr 1493 1494/*------------------------------------------------------------------------------- */ 1495/* Function: out16 */ 1496/* Description: Output 16 bits */ 1497/*------------------------------------------------------------------------------- */ 1498 .globl out16 1499out16: 1500 sth r4,0x0000(r3) 1501 sync 1502 blr 1503 1504/*------------------------------------------------------------------------------- */ 1505/* Function: out16r */ 1506/* Description: Byte reverse and output 16 bits */ 1507/*------------------------------------------------------------------------------- */ 1508 .globl out16r 1509out16r: 1510 sthbrx r4,r0,r3 1511 sync 1512 blr 1513 1514/*------------------------------------------------------------------------------- */ 1515/* Function: out32 */ 1516/* Description: Output 32 bits */ 1517/*------------------------------------------------------------------------------- */ 1518 .globl out32 1519out32: 1520 stw r4,0x0000(r3) 1521 sync 1522 blr 1523 1524/*------------------------------------------------------------------------------- */ 1525/* Function: out32r */ 1526/* Description: Byte reverse and output 32 bits */ 1527/*------------------------------------------------------------------------------- */ 1528 .globl out32r 1529out32r: 1530 stwbrx r4,r0,r3 1531 sync 1532 blr 1533 1534/*------------------------------------------------------------------------------- */ 1535/* Function: in16 */ 1536/* Description: Input 16 bits */ 1537/*------------------------------------------------------------------------------- */ 1538 .globl in16 1539in16: 1540 lhz r3,0x0000(r3) 1541 blr 1542 1543/*------------------------------------------------------------------------------- */ 1544/* Function: in16r */ 1545/* Description: Input 16 bits and byte reverse */ 1546/*------------------------------------------------------------------------------- */ 1547 .globl in16r 1548in16r: 1549 lhbrx r3,r0,r3 1550 blr 1551 1552/*------------------------------------------------------------------------------- */ 1553/* Function: in32 */ 1554/* Description: Input 32 bits */ 1555/*------------------------------------------------------------------------------- */ 1556 .globl in32 1557in32: 1558 lwz 3,0x0000(3) 1559 blr 1560 1561/*------------------------------------------------------------------------------- */ 1562/* Function: in32r */ 1563/* Description: Input 32 bits and byte reverse */ 1564/*------------------------------------------------------------------------------- */ 1565 .globl in32r 1566in32r: 1567 lwbrx r3,r0,r3 1568 blr 1569#endif /* !CONFIG_NAND_SPL */ 1570 1571/*------------------------------------------------------------------------------*/ 1572 1573/* 1574 * void write_tlb(mas0, mas1, mas2, mas3, mas7) 1575 */ 1576 .globl write_tlb 1577write_tlb: 1578 mtspr MAS0,r3 1579 mtspr MAS1,r4 1580 mtspr MAS2,r5 1581 mtspr MAS3,r6 1582#ifdef CONFIG_ENABLE_36BIT_PHYS 1583 mtspr MAS7,r7 1584#endif 1585 li r3,0 1586#ifdef CONFIG_SYS_BOOK3E_HV 1587 mtspr MAS8,r3 1588#endif 1589 isync 1590 tlbwe 1591 msync 1592 isync 1593 blr 1594 1595/* 1596 * void relocate_code (addr_sp, gd, addr_moni) 1597 * 1598 * This "function" does not return, instead it continues in RAM 1599 * after relocating the monitor code. 1600 * 1601 * r3 = dest 1602 * r4 = src 1603 * r5 = length in bytes 1604 * r6 = cachelinesize 1605 */ 1606 .globl relocate_code 1607relocate_code: 1608 mr r1,r3 /* Set new stack pointer */ 1609 mr r9,r4 /* Save copy of Init Data pointer */ 1610 mr r10,r5 /* Save copy of Destination Address */ 1611 1612 GET_GOT 1613 mr r3,r5 /* Destination Address */ 1614 lis r4,CONFIG_SYS_MONITOR_BASE@h /* Source Address */ 1615 ori r4,r4,CONFIG_SYS_MONITOR_BASE@l 1616 lwz r5,GOT(__init_end) 1617 sub r5,r5,r4 1618 li r6,CONFIG_SYS_CACHELINE_SIZE /* Cache Line Size */ 1619 1620 /* 1621 * Fix GOT pointer: 1622 * 1623 * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address 1624 * 1625 * Offset: 1626 */ 1627 sub r15,r10,r4 1628 1629 /* First our own GOT */ 1630 add r12,r12,r15 1631 /* the the one used by the C code */ 1632 add r30,r30,r15 1633 1634 /* 1635 * Now relocate code 1636 */ 1637 1638 cmplw cr1,r3,r4 1639 addi r0,r5,3 1640 srwi. r0,r0,2 1641 beq cr1,4f /* In place copy is not necessary */ 1642 beq 7f /* Protect against 0 count */ 1643 mtctr r0 1644 bge cr1,2f 1645 1646 la r8,-4(r4) 1647 la r7,-4(r3) 16481: lwzu r0,4(r8) 1649 stwu r0,4(r7) 1650 bdnz 1b 1651 b 4f 1652 16532: slwi r0,r0,2 1654 add r8,r4,r0 1655 add r7,r3,r0 16563: lwzu r0,-4(r8) 1657 stwu r0,-4(r7) 1658 bdnz 3b 1659 1660/* 1661 * Now flush the cache: note that we must start from a cache aligned 1662 * address. Otherwise we might miss one cache line. 1663 */ 16644: cmpwi r6,0 1665 add r5,r3,r5 1666 beq 7f /* Always flush prefetch queue in any case */ 1667 subi r0,r6,1 1668 andc r3,r3,r0 1669 mr r4,r3 16705: dcbst 0,r4 1671 add r4,r4,r6 1672 cmplw r4,r5 1673 blt 5b 1674 sync /* Wait for all dcbst to complete on bus */ 1675 mr r4,r3 16766: icbi 0,r4 1677 add r4,r4,r6 1678 cmplw r4,r5 1679 blt 6b 16807: sync /* Wait for all icbi to complete on bus */ 1681 isync 1682 1683/* 1684 * We are done. Do not return, instead branch to second part of board 1685 * initialization, now running from RAM. 1686 */ 1687 1688 addi r0,r10,in_ram - _start + _START_OFFSET 1689 1690 /* 1691 * As IVPR is going to point RAM address, 1692 * Make sure IVOR15 has valid opcode to support debugger 1693 */ 1694 mtspr IVOR15,r0 1695 1696 /* 1697 * Re-point the IVPR at RAM 1698 */ 1699 mtspr IVPR,r10 1700 1701 mtlr r0 1702 blr /* NEVER RETURNS! */ 1703 .globl in_ram 1704in_ram: 1705 1706 /* 1707 * Relocation Function, r12 point to got2+0x8000 1708 * 1709 * Adjust got2 pointers, no need to check for 0, this code 1710 * already puts a few entries in the table. 1711 */ 1712 li r0,__got2_entries@sectoff@l 1713 la r3,GOT(_GOT2_TABLE_) 1714 lwz r11,GOT(_GOT2_TABLE_) 1715 mtctr r0 1716 sub r11,r3,r11 1717 addi r3,r3,-4 17181: lwzu r0,4(r3) 1719 cmpwi r0,0 1720 beq- 2f 1721 add r0,r0,r11 1722 stw r0,0(r3) 17232: bdnz 1b 1724 1725 /* 1726 * Now adjust the fixups and the pointers to the fixups 1727 * in case we need to move ourselves again. 1728 */ 1729 li r0,__fixup_entries@sectoff@l 1730 lwz r3,GOT(_FIXUP_TABLE_) 1731 cmpwi r0,0 1732 mtctr r0 1733 addi r3,r3,-4 1734 beq 4f 17353: lwzu r4,4(r3) 1736 lwzux r0,r4,r11 1737 cmpwi r0,0 1738 add r0,r0,r11 1739 stw r4,0(r3) 1740 beq- 5f 1741 stw r0,0(r4) 17425: bdnz 3b 17434: 1744clear_bss: 1745 /* 1746 * Now clear BSS segment 1747 */ 1748 lwz r3,GOT(__bss_start) 1749 lwz r4,GOT(__bss_end__) 1750 1751 cmplw 0,r3,r4 1752 beq 6f 1753 1754 li r0,0 17555: 1756 stw r0,0(r3) 1757 addi r3,r3,4 1758 cmplw 0,r3,r4 1759 bne 5b 17606: 1761 1762 mr r3,r9 /* Init Data pointer */ 1763 mr r4,r10 /* Destination Address */ 1764 bl board_init_r 1765 1766#ifndef CONFIG_NAND_SPL 1767 /* 1768 * Copy exception vector code to low memory 1769 * 1770 * r3: dest_addr 1771 * r7: source address, r8: end address, r9: target address 1772 */ 1773 .globl trap_init 1774trap_init: 1775 mflr r4 /* save link register */ 1776 GET_GOT 1777 lwz r7,GOT(_start_of_vectors) 1778 lwz r8,GOT(_end_of_vectors) 1779 1780 li r9,0x100 /* reset vector always at 0x100 */ 1781 1782 cmplw 0,r7,r8 1783 bgelr /* return if r7>=r8 - just in case */ 17841: 1785 lwz r0,0(r7) 1786 stw r0,0(r9) 1787 addi r7,r7,4 1788 addi r9,r9,4 1789 cmplw 0,r7,r8 1790 bne 1b 1791 1792 /* 1793 * relocate `hdlr' and `int_return' entries 1794 */ 1795 li r7,.L_CriticalInput - _start + _START_OFFSET 1796 bl trap_reloc 1797 li r7,.L_MachineCheck - _start + _START_OFFSET 1798 bl trap_reloc 1799 li r7,.L_DataStorage - _start + _START_OFFSET 1800 bl trap_reloc 1801 li r7,.L_InstStorage - _start + _START_OFFSET 1802 bl trap_reloc 1803 li r7,.L_ExtInterrupt - _start + _START_OFFSET 1804 bl trap_reloc 1805 li r7,.L_Alignment - _start + _START_OFFSET 1806 bl trap_reloc 1807 li r7,.L_ProgramCheck - _start + _START_OFFSET 1808 bl trap_reloc 1809 li r7,.L_FPUnavailable - _start + _START_OFFSET 1810 bl trap_reloc 1811 li r7,.L_Decrementer - _start + _START_OFFSET 1812 bl trap_reloc 1813 li r7,.L_IntervalTimer - _start + _START_OFFSET 1814 li r8,_end_of_vectors - _start + _START_OFFSET 18152: 1816 bl trap_reloc 1817 addi r7,r7,0x100 /* next exception vector */ 1818 cmplw 0,r7,r8 1819 blt 2b 1820 1821 /* Update IVORs as per relocated vector table address */ 1822 li r7,0x0100 1823 mtspr IVOR0,r7 /* 0: Critical input */ 1824 li r7,0x0200 1825 mtspr IVOR1,r7 /* 1: Machine check */ 1826 li r7,0x0300 1827 mtspr IVOR2,r7 /* 2: Data storage */ 1828 li r7,0x0400 1829 mtspr IVOR3,r7 /* 3: Instruction storage */ 1830 li r7,0x0500 1831 mtspr IVOR4,r7 /* 4: External interrupt */ 1832 li r7,0x0600 1833 mtspr IVOR5,r7 /* 5: Alignment */ 1834 li r7,0x0700 1835 mtspr IVOR6,r7 /* 6: Program check */ 1836 li r7,0x0800 1837 mtspr IVOR7,r7 /* 7: floating point unavailable */ 1838 li r7,0x0900 1839 mtspr IVOR8,r7 /* 8: System call */ 1840 /* 9: Auxiliary processor unavailable(unsupported) */ 1841 li r7,0x0a00 1842 mtspr IVOR10,r7 /* 10: Decrementer */ 1843 li r7,0x0b00 1844 mtspr IVOR11,r7 /* 11: Interval timer */ 1845 li r7,0x0c00 1846 mtspr IVOR12,r7 /* 12: Watchdog timer */ 1847 li r7,0x0d00 1848 mtspr IVOR13,r7 /* 13: Data TLB error */ 1849 li r7,0x0e00 1850 mtspr IVOR14,r7 /* 14: Instruction TLB error */ 1851 li r7,0x0f00 1852 mtspr IVOR15,r7 /* 15: Debug */ 1853 1854 lis r7,0x0 1855 mtspr IVPR,r7 1856 1857 mtlr r4 /* restore link register */ 1858 blr 1859 1860.globl unlock_ram_in_cache 1861unlock_ram_in_cache: 1862 /* invalidate the INIT_RAM section */ 1863 lis r3,(CONFIG_SYS_INIT_RAM_ADDR & ~(CONFIG_SYS_CACHELINE_SIZE-1))@h 1864 ori r3,r3,(CONFIG_SYS_INIT_RAM_ADDR & ~(CONFIG_SYS_CACHELINE_SIZE-1))@l 1865 mfspr r4,L1CFG0 1866 andi. r4,r4,0x1ff 1867 slwi r4,r4,(10 - 1 - L1_CACHE_SHIFT) 1868 mtctr r4 18691: dcbi r0,r3 1870 addi r3,r3,CONFIG_SYS_CACHELINE_SIZE 1871 bdnz 1b 1872 sync 1873 1874 /* Invalidate the TLB entries for the cache */ 1875 lis r3,CONFIG_SYS_INIT_RAM_ADDR@h 1876 ori r3,r3,CONFIG_SYS_INIT_RAM_ADDR@l 1877 tlbivax 0,r3 1878 addi r3,r3,0x1000 1879 tlbivax 0,r3 1880 addi r3,r3,0x1000 1881 tlbivax 0,r3 1882 addi r3,r3,0x1000 1883 tlbivax 0,r3 1884 isync 1885 blr 1886 1887.globl flush_dcache 1888flush_dcache: 1889 mfspr r3,SPRN_L1CFG0 1890 1891 rlwinm r5,r3,9,3 /* Extract cache block size */ 1892 twlgti r5,1 /* Only 32 and 64 byte cache blocks 1893 * are currently defined. 1894 */ 1895 li r4,32 1896 subfic r6,r5,2 /* r6 = log2(1KiB / cache block size) - 1897 * log2(number of ways) 1898 */ 1899 slw r5,r4,r5 /* r5 = cache block size */ 1900 1901 rlwinm r7,r3,0,0xff /* Extract number of KiB in the cache */ 1902 mulli r7,r7,13 /* An 8-way cache will require 13 1903 * loads per set. 1904 */ 1905 slw r7,r7,r6 1906 1907 /* save off HID0 and set DCFA */ 1908 mfspr r8,SPRN_HID0 1909 ori r9,r8,HID0_DCFA@l 1910 mtspr SPRN_HID0,r9 1911 isync 1912 1913 lis r4,0 1914 mtctr r7 1915 19161: lwz r3,0(r4) /* Load... */ 1917 add r4,r4,r5 1918 bdnz 1b 1919 1920 msync 1921 lis r4,0 1922 mtctr r7 1923 19241: dcbf 0,r4 /* ...and flush. */ 1925 add r4,r4,r5 1926 bdnz 1b 1927 1928 /* restore HID0 */ 1929 mtspr SPRN_HID0,r8 1930 isync 1931 1932 blr 1933 1934.globl setup_ivors 1935setup_ivors: 1936 1937#include "fixed_ivor.S" 1938 blr 1939#endif /* !CONFIG_NAND_SPL */ 1940