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