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#ifdef CONFIG_ENABLE_36BIT_PHYS 447 lis r7, CONFIG_SYS_CCSRBAR_PHYS_HIGH@h 448 ori r7, r7, CONFIG_SYS_CCSRBAR_PHYS_HIGH@l 449 mtspr MAS7, r7 450#endif 451 mtspr MAS0, r0 452 mtspr MAS1, r1 453 mtspr MAS2, r2 454 mtspr MAS3, r3 455 isync 456 msync 457 tlbwe 458 459 /* 460 * Create a TLB for the current location of CCSR. Register R9 is reserved 461 * for the virtual address of this TLB (CONFIG_SYS_CCSRBAR + 0x1000). 462 */ 463create_ccsr_old_tlb: 464 lis r0, FSL_BOOKE_MAS0(0, 1, 0)@h 465 ori r0, r0, FSL_BOOKE_MAS0(0, 1, 0)@l 466 lis r2, FSL_BOOKE_MAS2(CONFIG_SYS_CCSRBAR + 0x1000, (MAS2_I|MAS2_G))@h 467 ori r2, r2, FSL_BOOKE_MAS2(CONFIG_SYS_CCSRBAR + 0x1000, (MAS2_I|MAS2_G))@l 468 lis r3, FSL_BOOKE_MAS3(CONFIG_SYS_CCSRBAR_DEFAULT, 0, (MAS3_SW|MAS3_SR))@h 469 ori r3, r3, FSL_BOOKE_MAS3(CONFIG_SYS_CCSRBAR_DEFAULT, 0, (MAS3_SW|MAS3_SR))@l 470#ifdef CONFIG_ENABLE_36BIT_PHYS 471 li r7, 0 /* The default CCSR address is always a 32-bit number */ 472 mtspr MAS7, r7 473#endif 474 mtspr MAS0, r0 475 /* MAS1 is the same as above */ 476 mtspr MAS2, r2 477 mtspr MAS3, r3 478 isync 479 msync 480 tlbwe 481 482 /* 483 * We have a TLB for what we think is the current (old) CCSR. Let's 484 * verify that, otherwise we won't be able to move it. 485 * CONFIG_SYS_CCSRBAR_DEFAULT is always a 32-bit number, so we only 486 * need to compare the lower 32 bits of CCSRBAR on CoreNet systems. 487 */ 488verify_old_ccsr: 489 lis r0, CONFIG_SYS_CCSRBAR_DEFAULT@h 490 ori r0, r0, CONFIG_SYS_CCSRBAR_DEFAULT@l 491#ifdef CONFIG_FSL_CORENET 492 lwz r1, 4(r9) /* CCSRBARL */ 493#else 494 lwz r1, 0(r9) /* CCSRBAR, shifted right by 12 */ 495 slwi r1, r1, 12 496#endif 497 498 cmpl 0, r0, r1 499 500 /* 501 * If the value we read from CCSRBARL is not what we expect, then 502 * enter an infinite loop. This will at least allow a debugger to 503 * halt execution and examine TLBs, etc. There's no point in going 504 * on. 505 */ 506infinite_debug_loop: 507 bne infinite_debug_loop 508 509#ifdef CONFIG_FSL_CORENET 510 511#define CCSR_LAWBARH0 (CONFIG_SYS_CCSRBAR + 0x1000) 512#define LAW_EN 0x80000000 513#define LAW_SIZE_4K 0xb 514#define CCSRBAR_LAWAR (LAW_EN | (0x1e << 20) | LAW_SIZE_4K) 515#define CCSRAR_C 0x80000000 /* Commit */ 516 517create_temp_law: 518 /* 519 * On CoreNet systems, we create the temporary LAW using a special LAW 520 * target ID of 0x1e. LAWBARH is at offset 0xc00 in CCSR. 521 */ 522 lis r0, CONFIG_SYS_CCSRBAR_PHYS_HIGH@h 523 ori r0, r0, CONFIG_SYS_CCSRBAR_PHYS_HIGH@l 524 lis r1, CONFIG_SYS_CCSRBAR_PHYS_LOW@h 525 ori r1, r1, CONFIG_SYS_CCSRBAR_PHYS_LOW@l 526 lis r2, CCSRBAR_LAWAR@h 527 ori r2, r2, CCSRBAR_LAWAR@l 528 529 stw r0, 0xc00(r9) /* LAWBARH0 */ 530 stw r1, 0xc04(r9) /* LAWBARL0 */ 531 sync 532 stw r2, 0xc08(r9) /* LAWAR0 */ 533 534 /* 535 * Read back from LAWAR to ensure the update is complete. e500mc 536 * cores also require an isync. 537 */ 538 lwz r0, 0xc08(r9) /* LAWAR0 */ 539 isync 540 541 /* 542 * Read the current CCSRBARH and CCSRBARL using load word instructions. 543 * Follow this with an isync instruction. This forces any outstanding 544 * accesses to configuration space to completion. 545 */ 546read_old_ccsrbar: 547 lwz r0, 0(r9) /* CCSRBARH */ 548 lwz r0, 4(r9) /* CCSRBARL */ 549 isync 550 551 /* 552 * Write the new values for CCSRBARH and CCSRBARL to their old 553 * locations. The CCSRBARH has a shadow register. When the CCSRBARH 554 * has a new value written it loads a CCSRBARH shadow register. When 555 * the CCSRBARL is written, the CCSRBARH shadow register contents 556 * along with the CCSRBARL value are loaded into the CCSRBARH and 557 * CCSRBARL registers, respectively. Follow this with a sync 558 * instruction. 559 */ 560write_new_ccsrbar: 561 lis r0, CONFIG_SYS_CCSRBAR_PHYS_HIGH@h 562 ori r0, r0, CONFIG_SYS_CCSRBAR_PHYS_HIGH@l 563 lis r1, CONFIG_SYS_CCSRBAR_PHYS_LOW@h 564 ori r1, r1, CONFIG_SYS_CCSRBAR_PHYS_LOW@l 565 lis r2, CCSRAR_C@h 566 ori r2, r2, CCSRAR_C@l 567 568 stw r0, 0(r9) /* Write to CCSRBARH */ 569 sync /* Make sure we write to CCSRBARH first */ 570 stw r1, 4(r9) /* Write to CCSRBARL */ 571 sync 572 573 /* 574 * Write a 1 to the commit bit (C) of CCSRAR at the old location. 575 * Follow this with a sync instruction. 576 */ 577 stw r2, 8(r9) 578 sync 579 580 /* Delete the temporary LAW */ 581delete_temp_law: 582 li r1, 0 583 stw r1, 0xc08(r8) 584 sync 585 stw r1, 0xc00(r8) 586 stw r1, 0xc04(r8) 587 sync 588 589#else /* #ifdef CONFIG_FSL_CORENET */ 590 591write_new_ccsrbar: 592 /* 593 * Read the current value of CCSRBAR using a load word instruction 594 * followed by an isync. This forces all accesses to configuration 595 * space to complete. 596 */ 597 sync 598 lwz r0, 0(r9) 599 isync 600 601/* CONFIG_SYS_CCSRBAR_PHYS right shifted by 12 */ 602#define CCSRBAR_PHYS_RS12 ((CONFIG_SYS_CCSRBAR_PHYS_HIGH << 20) | \ 603 (CONFIG_SYS_CCSRBAR_PHYS_LOW >> 12)) 604 605 /* Write the new value to CCSRBAR. */ 606 lis r0, CCSRBAR_PHYS_RS12@h 607 ori r0, r0, CCSRBAR_PHYS_RS12@l 608 stw r0, 0(r9) 609 sync 610 611 /* 612 * The manual says to perform a load of an address that does not 613 * access configuration space or the on-chip SRAM using an existing TLB, 614 * but that doesn't appear to be necessary. We will do the isync, 615 * though. 616 */ 617 isync 618 619 /* 620 * Read the contents of CCSRBAR from its new location, followed by 621 * another isync. 622 */ 623 lwz r0, 0(r8) 624 isync 625 626#endif /* #ifdef CONFIG_FSL_CORENET */ 627 628 /* Delete the temporary TLBs */ 629delete_temp_tlbs: 630 lis r0, FSL_BOOKE_MAS0(0, 0, 0)@h 631 ori r0, r0, FSL_BOOKE_MAS0(0, 0, 0)@l 632 li r1, 0 633 lis r2, FSL_BOOKE_MAS2(CONFIG_SYS_CCSRBAR, (MAS2_I|MAS2_G))@h 634 ori r2, r2, FSL_BOOKE_MAS2(CONFIG_SYS_CCSRBAR, (MAS2_I|MAS2_G))@l 635 mtspr MAS0, r0 636 mtspr MAS1, r1 637 mtspr MAS2, r2 638 isync 639 msync 640 tlbwe 641 642 lis r0, FSL_BOOKE_MAS0(0, 1, 0)@h 643 ori r0, r0, FSL_BOOKE_MAS0(0, 1, 0)@l 644 lis r2, FSL_BOOKE_MAS2(CONFIG_SYS_CCSRBAR + 0x1000, (MAS2_I|MAS2_G))@h 645 ori r2, r2, FSL_BOOKE_MAS2(CONFIG_SYS_CCSRBAR + 0x1000, (MAS2_I|MAS2_G))@l 646 mtspr MAS0, r0 647 mtspr MAS2, r2 648 isync 649 msync 650 tlbwe 651#endif /* #if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR_PHYS) */ 652 653create_init_ram_area: 654 lis r6,FSL_BOOKE_MAS0(1, 15, 0)@h 655 ori r6,r6,FSL_BOOKE_MAS0(1, 15, 0)@l 656 657#if !defined(CONFIG_SYS_RAMBOOT) && !defined(CONFIG_SECURE_BOOT) 658 /* create a temp mapping in AS=1 to the 4M boot window */ 659 lis r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_4M)@h 660 ori r7,r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_4M)@l 661 662 lis r8,FSL_BOOKE_MAS2(CONFIG_SYS_MONITOR_BASE & 0xffc00000, (MAS2_I|MAS2_G))@h 663 ori r8,r8,FSL_BOOKE_MAS2(CONFIG_SYS_MONITOR_BASE & 0xffc00000, (MAS2_I|MAS2_G))@l 664 665 /* The 85xx has the default boot window 0xff800000 - 0xffffffff */ 666 lis r9,FSL_BOOKE_MAS3(0xffc00000, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@h 667 ori r9,r9,FSL_BOOKE_MAS3(0xffc00000, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@l 668#elif !defined(CONFIG_SYS_RAMBOOT) && defined(CONFIG_SECURE_BOOT) 669 /* create a temp mapping in AS = 1 for Flash mapping 670 * created by PBL for ISBC code 671 */ 672 lis r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_1M)@h 673 ori r7,r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_1M)@l 674 675 lis r8,FSL_BOOKE_MAS2(CONFIG_SYS_MONITOR_BASE, (MAS2_I|MAS2_G))@h 676 ori r8,r8,FSL_BOOKE_MAS2(CONFIG_SYS_MONITOR_BASE, (MAS2_I|MAS2_G))@l 677 678 lis r9,FSL_BOOKE_MAS3(CONFIG_SYS_PBI_FLASH_WINDOW, 0, 679 (MAS3_SX|MAS3_SW|MAS3_SR))@h 680 ori r9,r9,FSL_BOOKE_MAS3(CONFIG_SYS_PBI_FLASH_WINDOW, 0, 681 (MAS3_SX|MAS3_SW|MAS3_SR))@l 682#else 683 /* 684 * create a temp mapping in AS=1 to the 1M CONFIG_SYS_MONITOR_BASE space, the main 685 * image has been relocated to CONFIG_SYS_MONITOR_BASE on the second stage. 686 */ 687 lis r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_1M)@h 688 ori r7,r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_1M)@l 689 690 lis r8,FSL_BOOKE_MAS2(CONFIG_SYS_MONITOR_BASE, (MAS2_I|MAS2_G))@h 691 ori r8,r8,FSL_BOOKE_MAS2(CONFIG_SYS_MONITOR_BASE, (MAS2_I|MAS2_G))@l 692 693 lis r9,FSL_BOOKE_MAS3(CONFIG_SYS_MONITOR_BASE, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@h 694 ori r9,r9,FSL_BOOKE_MAS3(CONFIG_SYS_MONITOR_BASE, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@l 695#endif 696 697 mtspr MAS0,r6 698 mtspr MAS1,r7 699 mtspr MAS2,r8 700 mtspr MAS3,r9 701 isync 702 msync 703 tlbwe 704 705 /* create a temp mapping in AS=1 to the stack */ 706 lis r6,FSL_BOOKE_MAS0(1, 14, 0)@h 707 ori r6,r6,FSL_BOOKE_MAS0(1, 14, 0)@l 708 709 lis r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_16K)@h 710 ori r7,r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_16K)@l 711 712 lis r8,FSL_BOOKE_MAS2(CONFIG_SYS_INIT_RAM_ADDR, 0)@h 713 ori r8,r8,FSL_BOOKE_MAS2(CONFIG_SYS_INIT_RAM_ADDR, 0)@l 714 715#if defined(CONFIG_SYS_INIT_RAM_ADDR_PHYS_LOW) && \ 716 defined(CONFIG_SYS_INIT_RAM_ADDR_PHYS_HIGH) 717 lis r9,FSL_BOOKE_MAS3(CONFIG_SYS_INIT_RAM_ADDR_PHYS_LOW, 0, 718 (MAS3_SX|MAS3_SW|MAS3_SR))@h 719 ori r9,r9,FSL_BOOKE_MAS3(CONFIG_SYS_INIT_RAM_ADDR_PHYS_LOW, 0, 720 (MAS3_SX|MAS3_SW|MAS3_SR))@l 721 li r10,CONFIG_SYS_INIT_RAM_ADDR_PHYS_HIGH 722 mtspr MAS7,r10 723#else 724 lis r9,FSL_BOOKE_MAS3(CONFIG_SYS_INIT_RAM_ADDR, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@h 725 ori r9,r9,FSL_BOOKE_MAS3(CONFIG_SYS_INIT_RAM_ADDR, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@l 726#endif 727 728 mtspr MAS0,r6 729 mtspr MAS1,r7 730 mtspr MAS2,r8 731 mtspr MAS3,r9 732 isync 733 msync 734 tlbwe 735 736 lis r6,MSR_IS|MSR_DS@h 737 ori r6,r6,MSR_IS|MSR_DS@l 738 lis r7,switch_as@h 739 ori r7,r7,switch_as@l 740 741 mtspr SPRN_SRR0,r7 742 mtspr SPRN_SRR1,r6 743 rfi 744 745switch_as: 746/* L1 DCache is used for initial RAM */ 747 748 /* Allocate Initial RAM in data cache. 749 */ 750 lis r3,CONFIG_SYS_INIT_RAM_ADDR@h 751 ori r3,r3,CONFIG_SYS_INIT_RAM_ADDR@l 752 mfspr r2, L1CFG0 753 andi. r2, r2, 0x1ff 754 /* cache size * 1024 / (2 * L1 line size) */ 755 slwi r2, r2, (10 - 1 - L1_CACHE_SHIFT) 756 mtctr r2 757 li r0,0 7581: 759 dcbz r0,r3 760 dcbtls 0,r0,r3 761 addi r3,r3,CONFIG_SYS_CACHELINE_SIZE 762 bdnz 1b 763 764 /* Jump out the last 4K page and continue to 'normal' start */ 765#ifdef CONFIG_SYS_RAMBOOT 766 b _start_cont 767#else 768 /* Calculate absolute address in FLASH and jump there */ 769 /*--------------------------------------------------------------*/ 770 lis r3,CONFIG_SYS_MONITOR_BASE@h 771 ori r3,r3,CONFIG_SYS_MONITOR_BASE@l 772 addi r3,r3,_start_cont - _start + _START_OFFSET 773 mtlr r3 774 blr 775#endif 776 777 .text 778 .globl _start 779_start: 780 .long 0x27051956 /* U-BOOT Magic Number */ 781 .globl version_string 782version_string: 783 .ascii U_BOOT_VERSION_STRING, "\0" 784 785 .align 4 786 .globl _start_cont 787_start_cont: 788 /* Setup the stack in initial RAM,could be L2-as-SRAM or L1 dcache*/ 789 lis r1,CONFIG_SYS_INIT_RAM_ADDR@h 790 ori r1,r1,CONFIG_SYS_INIT_SP_OFFSET@l 791 792 li r0,0 793 stwu r0,-4(r1) 794 stwu r0,-4(r1) /* Terminate call chain */ 795 796 stwu r1,-8(r1) /* Save back chain and move SP */ 797 lis r0,RESET_VECTOR@h /* Address of reset vector */ 798 ori r0,r0,RESET_VECTOR@l 799 stwu r1,-8(r1) /* Save back chain and move SP */ 800 stw r0,+12(r1) /* Save return addr (underflow vect) */ 801 802 GET_GOT 803 bl cpu_init_early_f 804 805 /* switch back to AS = 0 */ 806 lis r3,(MSR_CE|MSR_ME|MSR_DE)@h 807 ori r3,r3,(MSR_CE|MSR_ME|MSR_DE)@l 808 mtmsr r3 809 isync 810 811 bl cpu_init_f 812 bl board_init_f 813 isync 814 815 /* NOTREACHED - board_init_f() does not return */ 816 817#ifndef CONFIG_NAND_SPL 818 . = EXC_OFF_SYS_RESET 819 .globl _start_of_vectors 820_start_of_vectors: 821 822/* Critical input. */ 823 CRIT_EXCEPTION(0x0100, CriticalInput, CritcalInputException) 824 825/* Machine check */ 826 MCK_EXCEPTION(0x200, MachineCheck, MachineCheckException) 827 828/* Data Storage exception. */ 829 STD_EXCEPTION(0x0300, DataStorage, UnknownException) 830 831/* Instruction Storage exception. */ 832 STD_EXCEPTION(0x0400, InstStorage, UnknownException) 833 834/* External Interrupt exception. */ 835 STD_EXCEPTION(0x0500, ExtInterrupt, ExtIntException) 836 837/* Alignment exception. */ 838 . = 0x0600 839Alignment: 840 EXCEPTION_PROLOG(SRR0, SRR1) 841 mfspr r4,DAR 842 stw r4,_DAR(r21) 843 mfspr r5,DSISR 844 stw r5,_DSISR(r21) 845 addi r3,r1,STACK_FRAME_OVERHEAD 846 EXC_XFER_TEMPLATE(Alignment, AlignmentException, MSR_KERNEL, COPY_EE) 847 848/* Program check exception */ 849 . = 0x0700 850ProgramCheck: 851 EXCEPTION_PROLOG(SRR0, SRR1) 852 addi r3,r1,STACK_FRAME_OVERHEAD 853 EXC_XFER_TEMPLATE(ProgramCheck, ProgramCheckException, 854 MSR_KERNEL, COPY_EE) 855 856 /* No FPU on MPC85xx. This exception is not supposed to happen. 857 */ 858 STD_EXCEPTION(0x0800, FPUnavailable, UnknownException) 859 860 . = 0x0900 861/* 862 * r0 - SYSCALL number 863 * r3-... arguments 864 */ 865SystemCall: 866 addis r11,r0,0 /* get functions table addr */ 867 ori r11,r11,0 /* Note: this code is patched in trap_init */ 868 addis r12,r0,0 /* get number of functions */ 869 ori r12,r12,0 870 871 cmplw 0,r0,r12 872 bge 1f 873 874 rlwinm r0,r0,2,0,31 /* fn_addr = fn_tbl[r0] */ 875 add r11,r11,r0 876 lwz r11,0(r11) 877 878 li r20,0xd00-4 /* Get stack pointer */ 879 lwz r12,0(r20) 880 subi r12,r12,12 /* Adjust stack pointer */ 881 li r0,0xc00+_end_back-SystemCall 882 cmplw 0,r0,r12 /* Check stack overflow */ 883 bgt 1f 884 stw r12,0(r20) 885 886 mflr r0 887 stw r0,0(r12) 888 mfspr r0,SRR0 889 stw r0,4(r12) 890 mfspr r0,SRR1 891 stw r0,8(r12) 892 893 li r12,0xc00+_back-SystemCall 894 mtlr r12 895 mtspr SRR0,r11 896 8971: SYNC 898 rfi 899_back: 900 901 mfmsr r11 /* Disable interrupts */ 902 li r12,0 903 ori r12,r12,MSR_EE 904 andc r11,r11,r12 905 SYNC /* Some chip revs need this... */ 906 mtmsr r11 907 SYNC 908 909 li r12,0xd00-4 /* restore regs */ 910 lwz r12,0(r12) 911 912 lwz r11,0(r12) 913 mtlr r11 914 lwz r11,4(r12) 915 mtspr SRR0,r11 916 lwz r11,8(r12) 917 mtspr SRR1,r11 918 919 addi r12,r12,12 /* Adjust stack pointer */ 920 li r20,0xd00-4 921 stw r12,0(r20) 922 923 SYNC 924 rfi 925_end_back: 926 927 STD_EXCEPTION(0x0a00, Decrementer, timer_interrupt) 928 STD_EXCEPTION(0x0b00, IntervalTimer, UnknownException) 929 STD_EXCEPTION(0x0c00, WatchdogTimer, UnknownException) 930 931 STD_EXCEPTION(0x0d00, DataTLBError, UnknownException) 932 STD_EXCEPTION(0x0e00, InstructionTLBError, UnknownException) 933 934 CRIT_EXCEPTION(0x0f00, DebugBreakpoint, DebugException ) 935 936 .globl _end_of_vectors 937_end_of_vectors: 938 939 940 . = . + (0x100 - ( . & 0xff )) /* align for debug */ 941 942/* 943 * This code finishes saving the registers to the exception frame 944 * and jumps to the appropriate handler for the exception. 945 * Register r21 is pointer into trap frame, r1 has new stack pointer. 946 */ 947 .globl transfer_to_handler 948transfer_to_handler: 949 stw r22,_NIP(r21) 950 lis r22,MSR_POW@h 951 andc r23,r23,r22 952 stw r23,_MSR(r21) 953 SAVE_GPR(7, r21) 954 SAVE_4GPRS(8, r21) 955 SAVE_8GPRS(12, r21) 956 SAVE_8GPRS(24, r21) 957 958 mflr r23 959 andi. r24,r23,0x3f00 /* get vector offset */ 960 stw r24,TRAP(r21) 961 li r22,0 962 stw r22,RESULT(r21) 963 mtspr SPRG2,r22 /* r1 is now kernel sp */ 964 965 lwz r24,0(r23) /* virtual address of handler */ 966 lwz r23,4(r23) /* where to go when done */ 967 mtspr SRR0,r24 968 mtspr SRR1,r20 969 mtlr r23 970 SYNC 971 rfi /* jump to handler, enable MMU */ 972 973int_return: 974 mfmsr r28 /* Disable interrupts */ 975 li r4,0 976 ori r4,r4,MSR_EE 977 andc r28,r28,r4 978 SYNC /* Some chip revs need this... */ 979 mtmsr r28 980 SYNC 981 lwz r2,_CTR(r1) 982 lwz r0,_LINK(r1) 983 mtctr r2 984 mtlr r0 985 lwz r2,_XER(r1) 986 lwz r0,_CCR(r1) 987 mtspr XER,r2 988 mtcrf 0xFF,r0 989 REST_10GPRS(3, r1) 990 REST_10GPRS(13, r1) 991 REST_8GPRS(23, r1) 992 REST_GPR(31, r1) 993 lwz r2,_NIP(r1) /* Restore environment */ 994 lwz r0,_MSR(r1) 995 mtspr SRR0,r2 996 mtspr SRR1,r0 997 lwz r0,GPR0(r1) 998 lwz r2,GPR2(r1) 999 lwz r1,GPR1(r1) 1000 SYNC 1001 rfi 1002 1003crit_return: 1004 mfmsr r28 /* Disable interrupts */ 1005 li r4,0 1006 ori r4,r4,MSR_EE 1007 andc r28,r28,r4 1008 SYNC /* Some chip revs need this... */ 1009 mtmsr r28 1010 SYNC 1011 lwz r2,_CTR(r1) 1012 lwz r0,_LINK(r1) 1013 mtctr r2 1014 mtlr r0 1015 lwz r2,_XER(r1) 1016 lwz r0,_CCR(r1) 1017 mtspr XER,r2 1018 mtcrf 0xFF,r0 1019 REST_10GPRS(3, r1) 1020 REST_10GPRS(13, r1) 1021 REST_8GPRS(23, r1) 1022 REST_GPR(31, r1) 1023 lwz r2,_NIP(r1) /* Restore environment */ 1024 lwz r0,_MSR(r1) 1025 mtspr SPRN_CSRR0,r2 1026 mtspr SPRN_CSRR1,r0 1027 lwz r0,GPR0(r1) 1028 lwz r2,GPR2(r1) 1029 lwz r1,GPR1(r1) 1030 SYNC 1031 rfci 1032 1033mck_return: 1034 mfmsr r28 /* Disable interrupts */ 1035 li r4,0 1036 ori r4,r4,MSR_EE 1037 andc r28,r28,r4 1038 SYNC /* Some chip revs need this... */ 1039 mtmsr r28 1040 SYNC 1041 lwz r2,_CTR(r1) 1042 lwz r0,_LINK(r1) 1043 mtctr r2 1044 mtlr r0 1045 lwz r2,_XER(r1) 1046 lwz r0,_CCR(r1) 1047 mtspr XER,r2 1048 mtcrf 0xFF,r0 1049 REST_10GPRS(3, r1) 1050 REST_10GPRS(13, r1) 1051 REST_8GPRS(23, r1) 1052 REST_GPR(31, r1) 1053 lwz r2,_NIP(r1) /* Restore environment */ 1054 lwz r0,_MSR(r1) 1055 mtspr SPRN_MCSRR0,r2 1056 mtspr SPRN_MCSRR1,r0 1057 lwz r0,GPR0(r1) 1058 lwz r2,GPR2(r1) 1059 lwz r1,GPR1(r1) 1060 SYNC 1061 rfmci 1062 1063/* Cache functions. 1064*/ 1065.globl flush_icache 1066flush_icache: 1067.globl invalidate_icache 1068invalidate_icache: 1069 mfspr r0,L1CSR1 1070 ori r0,r0,L1CSR1_ICFI 1071 msync 1072 isync 1073 mtspr L1CSR1,r0 1074 isync 1075 blr /* entire I cache */ 1076 1077.globl invalidate_dcache 1078invalidate_dcache: 1079 mfspr r0,L1CSR0 1080 ori r0,r0,L1CSR0_DCFI 1081 msync 1082 isync 1083 mtspr L1CSR0,r0 1084 isync 1085 blr 1086 1087 .globl icache_enable 1088icache_enable: 1089 mflr r8 1090 bl invalidate_icache 1091 mtlr r8 1092 isync 1093 mfspr r4,L1CSR1 1094 ori r4,r4,0x0001 1095 oris r4,r4,0x0001 1096 mtspr L1CSR1,r4 1097 isync 1098 blr 1099 1100 .globl icache_disable 1101icache_disable: 1102 mfspr r0,L1CSR1 1103 lis r3,0 1104 ori r3,r3,L1CSR1_ICE 1105 andc r0,r0,r3 1106 mtspr L1CSR1,r0 1107 isync 1108 blr 1109 1110 .globl icache_status 1111icache_status: 1112 mfspr r3,L1CSR1 1113 andi. r3,r3,L1CSR1_ICE 1114 blr 1115 1116 .globl dcache_enable 1117dcache_enable: 1118 mflr r8 1119 bl invalidate_dcache 1120 mtlr r8 1121 isync 1122 mfspr r0,L1CSR0 1123 ori r0,r0,0x0001 1124 oris r0,r0,0x0001 1125 msync 1126 isync 1127 mtspr L1CSR0,r0 1128 isync 1129 blr 1130 1131 .globl dcache_disable 1132dcache_disable: 1133 mfspr r3,L1CSR0 1134 lis r4,0 1135 ori r4,r4,L1CSR0_DCE 1136 andc r3,r3,r4 1137 mtspr L1CSR0,r3 1138 isync 1139 blr 1140 1141 .globl dcache_status 1142dcache_status: 1143 mfspr r3,L1CSR0 1144 andi. r3,r3,L1CSR0_DCE 1145 blr 1146 1147 .globl get_pir 1148get_pir: 1149 mfspr r3,PIR 1150 blr 1151 1152 .globl get_pvr 1153get_pvr: 1154 mfspr r3,PVR 1155 blr 1156 1157 .globl get_svr 1158get_svr: 1159 mfspr r3,SVR 1160 blr 1161 1162 .globl wr_tcr 1163wr_tcr: 1164 mtspr TCR,r3 1165 blr 1166 1167/*------------------------------------------------------------------------------- */ 1168/* Function: in8 */ 1169/* Description: Input 8 bits */ 1170/*------------------------------------------------------------------------------- */ 1171 .globl in8 1172in8: 1173 lbz r3,0x0000(r3) 1174 blr 1175 1176/*------------------------------------------------------------------------------- */ 1177/* Function: out8 */ 1178/* Description: Output 8 bits */ 1179/*------------------------------------------------------------------------------- */ 1180 .globl out8 1181out8: 1182 stb r4,0x0000(r3) 1183 sync 1184 blr 1185 1186/*------------------------------------------------------------------------------- */ 1187/* Function: out16 */ 1188/* Description: Output 16 bits */ 1189/*------------------------------------------------------------------------------- */ 1190 .globl out16 1191out16: 1192 sth r4,0x0000(r3) 1193 sync 1194 blr 1195 1196/*------------------------------------------------------------------------------- */ 1197/* Function: out16r */ 1198/* Description: Byte reverse and output 16 bits */ 1199/*------------------------------------------------------------------------------- */ 1200 .globl out16r 1201out16r: 1202 sthbrx r4,r0,r3 1203 sync 1204 blr 1205 1206/*------------------------------------------------------------------------------- */ 1207/* Function: out32 */ 1208/* Description: Output 32 bits */ 1209/*------------------------------------------------------------------------------- */ 1210 .globl out32 1211out32: 1212 stw r4,0x0000(r3) 1213 sync 1214 blr 1215 1216/*------------------------------------------------------------------------------- */ 1217/* Function: out32r */ 1218/* Description: Byte reverse and output 32 bits */ 1219/*------------------------------------------------------------------------------- */ 1220 .globl out32r 1221out32r: 1222 stwbrx r4,r0,r3 1223 sync 1224 blr 1225 1226/*------------------------------------------------------------------------------- */ 1227/* Function: in16 */ 1228/* Description: Input 16 bits */ 1229/*------------------------------------------------------------------------------- */ 1230 .globl in16 1231in16: 1232 lhz r3,0x0000(r3) 1233 blr 1234 1235/*------------------------------------------------------------------------------- */ 1236/* Function: in16r */ 1237/* Description: Input 16 bits and byte reverse */ 1238/*------------------------------------------------------------------------------- */ 1239 .globl in16r 1240in16r: 1241 lhbrx r3,r0,r3 1242 blr 1243 1244/*------------------------------------------------------------------------------- */ 1245/* Function: in32 */ 1246/* Description: Input 32 bits */ 1247/*------------------------------------------------------------------------------- */ 1248 .globl in32 1249in32: 1250 lwz 3,0x0000(3) 1251 blr 1252 1253/*------------------------------------------------------------------------------- */ 1254/* Function: in32r */ 1255/* Description: Input 32 bits and byte reverse */ 1256/*------------------------------------------------------------------------------- */ 1257 .globl in32r 1258in32r: 1259 lwbrx r3,r0,r3 1260 blr 1261#endif /* !CONFIG_NAND_SPL */ 1262 1263/*------------------------------------------------------------------------------*/ 1264 1265/* 1266 * void write_tlb(mas0, mas1, mas2, mas3, mas7) 1267 */ 1268 .globl write_tlb 1269write_tlb: 1270 mtspr MAS0,r3 1271 mtspr MAS1,r4 1272 mtspr MAS2,r5 1273 mtspr MAS3,r6 1274#ifdef CONFIG_ENABLE_36BIT_PHYS 1275 mtspr MAS7,r7 1276#endif 1277 li r3,0 1278#ifdef CONFIG_SYS_BOOK3E_HV 1279 mtspr MAS8,r3 1280#endif 1281 isync 1282 tlbwe 1283 msync 1284 isync 1285 blr 1286 1287/* 1288 * void relocate_code (addr_sp, gd, addr_moni) 1289 * 1290 * This "function" does not return, instead it continues in RAM 1291 * after relocating the monitor code. 1292 * 1293 * r3 = dest 1294 * r4 = src 1295 * r5 = length in bytes 1296 * r6 = cachelinesize 1297 */ 1298 .globl relocate_code 1299relocate_code: 1300 mr r1,r3 /* Set new stack pointer */ 1301 mr r9,r4 /* Save copy of Init Data pointer */ 1302 mr r10,r5 /* Save copy of Destination Address */ 1303 1304 GET_GOT 1305 mr r3,r5 /* Destination Address */ 1306 lis r4,CONFIG_SYS_MONITOR_BASE@h /* Source Address */ 1307 ori r4,r4,CONFIG_SYS_MONITOR_BASE@l 1308 lwz r5,GOT(__init_end) 1309 sub r5,r5,r4 1310 li r6,CONFIG_SYS_CACHELINE_SIZE /* Cache Line Size */ 1311 1312 /* 1313 * Fix GOT pointer: 1314 * 1315 * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address 1316 * 1317 * Offset: 1318 */ 1319 sub r15,r10,r4 1320 1321 /* First our own GOT */ 1322 add r12,r12,r15 1323 /* the the one used by the C code */ 1324 add r30,r30,r15 1325 1326 /* 1327 * Now relocate code 1328 */ 1329 1330 cmplw cr1,r3,r4 1331 addi r0,r5,3 1332 srwi. r0,r0,2 1333 beq cr1,4f /* In place copy is not necessary */ 1334 beq 7f /* Protect against 0 count */ 1335 mtctr r0 1336 bge cr1,2f 1337 1338 la r8,-4(r4) 1339 la r7,-4(r3) 13401: lwzu r0,4(r8) 1341 stwu r0,4(r7) 1342 bdnz 1b 1343 b 4f 1344 13452: slwi r0,r0,2 1346 add r8,r4,r0 1347 add r7,r3,r0 13483: lwzu r0,-4(r8) 1349 stwu r0,-4(r7) 1350 bdnz 3b 1351 1352/* 1353 * Now flush the cache: note that we must start from a cache aligned 1354 * address. Otherwise we might miss one cache line. 1355 */ 13564: cmpwi r6,0 1357 add r5,r3,r5 1358 beq 7f /* Always flush prefetch queue in any case */ 1359 subi r0,r6,1 1360 andc r3,r3,r0 1361 mr r4,r3 13625: dcbst 0,r4 1363 add r4,r4,r6 1364 cmplw r4,r5 1365 blt 5b 1366 sync /* Wait for all dcbst to complete on bus */ 1367 mr r4,r3 13686: icbi 0,r4 1369 add r4,r4,r6 1370 cmplw r4,r5 1371 blt 6b 13727: sync /* Wait for all icbi to complete on bus */ 1373 isync 1374 1375 /* 1376 * Re-point the IVPR at RAM 1377 */ 1378 mtspr IVPR,r10 1379 1380/* 1381 * We are done. Do not return, instead branch to second part of board 1382 * initialization, now running from RAM. 1383 */ 1384 1385 addi r0,r10,in_ram - _start + _START_OFFSET 1386 mtlr r0 1387 blr /* NEVER RETURNS! */ 1388 .globl in_ram 1389in_ram: 1390 1391 /* 1392 * Relocation Function, r12 point to got2+0x8000 1393 * 1394 * Adjust got2 pointers, no need to check for 0, this code 1395 * already puts a few entries in the table. 1396 */ 1397 li r0,__got2_entries@sectoff@l 1398 la r3,GOT(_GOT2_TABLE_) 1399 lwz r11,GOT(_GOT2_TABLE_) 1400 mtctr r0 1401 sub r11,r3,r11 1402 addi r3,r3,-4 14031: lwzu r0,4(r3) 1404 cmpwi r0,0 1405 beq- 2f 1406 add r0,r0,r11 1407 stw r0,0(r3) 14082: bdnz 1b 1409 1410 /* 1411 * Now adjust the fixups and the pointers to the fixups 1412 * in case we need to move ourselves again. 1413 */ 1414 li r0,__fixup_entries@sectoff@l 1415 lwz r3,GOT(_FIXUP_TABLE_) 1416 cmpwi r0,0 1417 mtctr r0 1418 addi r3,r3,-4 1419 beq 4f 14203: lwzu r4,4(r3) 1421 lwzux r0,r4,r11 1422 cmpwi r0,0 1423 add r0,r0,r11 1424 stw r4,0(r3) 1425 beq- 5f 1426 stw r0,0(r4) 14275: bdnz 3b 14284: 1429clear_bss: 1430 /* 1431 * Now clear BSS segment 1432 */ 1433 lwz r3,GOT(__bss_start) 1434 lwz r4,GOT(__bss_end__) 1435 1436 cmplw 0,r3,r4 1437 beq 6f 1438 1439 li r0,0 14405: 1441 stw r0,0(r3) 1442 addi r3,r3,4 1443 cmplw 0,r3,r4 1444 bne 5b 14456: 1446 1447 mr r3,r9 /* Init Data pointer */ 1448 mr r4,r10 /* Destination Address */ 1449 bl board_init_r 1450 1451#ifndef CONFIG_NAND_SPL 1452 /* 1453 * Copy exception vector code to low memory 1454 * 1455 * r3: dest_addr 1456 * r7: source address, r8: end address, r9: target address 1457 */ 1458 .globl trap_init 1459trap_init: 1460 mflr r4 /* save link register */ 1461 GET_GOT 1462 lwz r7,GOT(_start_of_vectors) 1463 lwz r8,GOT(_end_of_vectors) 1464 1465 li r9,0x100 /* reset vector always at 0x100 */ 1466 1467 cmplw 0,r7,r8 1468 bgelr /* return if r7>=r8 - just in case */ 14691: 1470 lwz r0,0(r7) 1471 stw r0,0(r9) 1472 addi r7,r7,4 1473 addi r9,r9,4 1474 cmplw 0,r7,r8 1475 bne 1b 1476 1477 /* 1478 * relocate `hdlr' and `int_return' entries 1479 */ 1480 li r7,.L_CriticalInput - _start + _START_OFFSET 1481 bl trap_reloc 1482 li r7,.L_MachineCheck - _start + _START_OFFSET 1483 bl trap_reloc 1484 li r7,.L_DataStorage - _start + _START_OFFSET 1485 bl trap_reloc 1486 li r7,.L_InstStorage - _start + _START_OFFSET 1487 bl trap_reloc 1488 li r7,.L_ExtInterrupt - _start + _START_OFFSET 1489 bl trap_reloc 1490 li r7,.L_Alignment - _start + _START_OFFSET 1491 bl trap_reloc 1492 li r7,.L_ProgramCheck - _start + _START_OFFSET 1493 bl trap_reloc 1494 li r7,.L_FPUnavailable - _start + _START_OFFSET 1495 bl trap_reloc 1496 li r7,.L_Decrementer - _start + _START_OFFSET 1497 bl trap_reloc 1498 li r7,.L_IntervalTimer - _start + _START_OFFSET 1499 li r8,_end_of_vectors - _start + _START_OFFSET 15002: 1501 bl trap_reloc 1502 addi r7,r7,0x100 /* next exception vector */ 1503 cmplw 0,r7,r8 1504 blt 2b 1505 1506 /* Update IVORs as per relocated vector table address */ 1507 li r7,0x0100 1508 mtspr IVOR0,r7 /* 0: Critical input */ 1509 li r7,0x0200 1510 mtspr IVOR1,r7 /* 1: Machine check */ 1511 li r7,0x0300 1512 mtspr IVOR2,r7 /* 2: Data storage */ 1513 li r7,0x0400 1514 mtspr IVOR3,r7 /* 3: Instruction storage */ 1515 li r7,0x0500 1516 mtspr IVOR4,r7 /* 4: External interrupt */ 1517 li r7,0x0600 1518 mtspr IVOR5,r7 /* 5: Alignment */ 1519 li r7,0x0700 1520 mtspr IVOR6,r7 /* 6: Program check */ 1521 li r7,0x0800 1522 mtspr IVOR7,r7 /* 7: floating point unavailable */ 1523 li r7,0x0900 1524 mtspr IVOR8,r7 /* 8: System call */ 1525 /* 9: Auxiliary processor unavailable(unsupported) */ 1526 li r7,0x0a00 1527 mtspr IVOR10,r7 /* 10: Decrementer */ 1528 li r7,0x0b00 1529 mtspr IVOR11,r7 /* 11: Interval timer */ 1530 li r7,0x0c00 1531 mtspr IVOR12,r7 /* 12: Watchdog timer */ 1532 li r7,0x0d00 1533 mtspr IVOR13,r7 /* 13: Data TLB error */ 1534 li r7,0x0e00 1535 mtspr IVOR14,r7 /* 14: Instruction TLB error */ 1536 li r7,0x0f00 1537 mtspr IVOR15,r7 /* 15: Debug */ 1538 1539 lis r7,0x0 1540 mtspr IVPR,r7 1541 1542 mtlr r4 /* restore link register */ 1543 blr 1544 1545.globl unlock_ram_in_cache 1546unlock_ram_in_cache: 1547 /* invalidate the INIT_RAM section */ 1548 lis r3,(CONFIG_SYS_INIT_RAM_ADDR & ~(CONFIG_SYS_CACHELINE_SIZE-1))@h 1549 ori r3,r3,(CONFIG_SYS_INIT_RAM_ADDR & ~(CONFIG_SYS_CACHELINE_SIZE-1))@l 1550 mfspr r4,L1CFG0 1551 andi. r4,r4,0x1ff 1552 slwi r4,r4,(10 - 1 - L1_CACHE_SHIFT) 1553 mtctr r4 15541: dcbi r0,r3 1555 addi r3,r3,CONFIG_SYS_CACHELINE_SIZE 1556 bdnz 1b 1557 sync 1558 1559 /* Invalidate the TLB entries for the cache */ 1560 lis r3,CONFIG_SYS_INIT_RAM_ADDR@h 1561 ori r3,r3,CONFIG_SYS_INIT_RAM_ADDR@l 1562 tlbivax 0,r3 1563 addi r3,r3,0x1000 1564 tlbivax 0,r3 1565 addi r3,r3,0x1000 1566 tlbivax 0,r3 1567 addi r3,r3,0x1000 1568 tlbivax 0,r3 1569 isync 1570 blr 1571 1572.globl flush_dcache 1573flush_dcache: 1574 mfspr r3,SPRN_L1CFG0 1575 1576 rlwinm r5,r3,9,3 /* Extract cache block size */ 1577 twlgti r5,1 /* Only 32 and 64 byte cache blocks 1578 * are currently defined. 1579 */ 1580 li r4,32 1581 subfic r6,r5,2 /* r6 = log2(1KiB / cache block size) - 1582 * log2(number of ways) 1583 */ 1584 slw r5,r4,r5 /* r5 = cache block size */ 1585 1586 rlwinm r7,r3,0,0xff /* Extract number of KiB in the cache */ 1587 mulli r7,r7,13 /* An 8-way cache will require 13 1588 * loads per set. 1589 */ 1590 slw r7,r7,r6 1591 1592 /* save off HID0 and set DCFA */ 1593 mfspr r8,SPRN_HID0 1594 ori r9,r8,HID0_DCFA@l 1595 mtspr SPRN_HID0,r9 1596 isync 1597 1598 lis r4,0 1599 mtctr r7 1600 16011: lwz r3,0(r4) /* Load... */ 1602 add r4,r4,r5 1603 bdnz 1b 1604 1605 msync 1606 lis r4,0 1607 mtctr r7 1608 16091: dcbf 0,r4 /* ...and flush. */ 1610 add r4,r4,r5 1611 bdnz 1b 1612 1613 /* restore HID0 */ 1614 mtspr SPRN_HID0,r8 1615 isync 1616 1617 blr 1618 1619.globl setup_ivors 1620setup_ivors: 1621 1622#include "fixed_ivor.S" 1623 blr 1624#endif /* !CONFIG_NAND_SPL */ 1625