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