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