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