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