1/* 2 * Copyright 2004, 2007-2011 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 /* Setup interrupt vectors */ 183 lis r1,CONFIG_SYS_MONITOR_BASE@h 184 mtspr IVPR,r1 185 186 li r1,0x0100 187 mtspr IVOR0,r1 /* 0: Critical input */ 188 li r1,0x0200 189 mtspr IVOR1,r1 /* 1: Machine check */ 190 li r1,0x0300 191 mtspr IVOR2,r1 /* 2: Data storage */ 192 li r1,0x0400 193 mtspr IVOR3,r1 /* 3: Instruction storage */ 194 li r1,0x0500 195 mtspr IVOR4,r1 /* 4: External interrupt */ 196 li r1,0x0600 197 mtspr IVOR5,r1 /* 5: Alignment */ 198 li r1,0x0700 199 mtspr IVOR6,r1 /* 6: Program check */ 200 li r1,0x0800 201 mtspr IVOR7,r1 /* 7: floating point unavailable */ 202 li r1,0x0900 203 mtspr IVOR8,r1 /* 8: System call */ 204 /* 9: Auxiliary processor unavailable(unsupported) */ 205 li r1,0x0a00 206 mtspr IVOR10,r1 /* 10: Decrementer */ 207 li r1,0x0b00 208 mtspr IVOR11,r1 /* 11: Interval timer */ 209 li r1,0x0c00 210 mtspr IVOR12,r1 /* 12: Watchdog timer */ 211 li r1,0x0d00 212 mtspr IVOR13,r1 /* 13: Data TLB error */ 213 li r1,0x0e00 214 mtspr IVOR14,r1 /* 14: Instruction TLB error */ 215 li r1,0x0f00 216 mtspr IVOR15,r1 /* 15: Debug */ 217 218 /* Clear and set up some registers. */ 219 li r0,0x0000 220 lis r1,0xffff 221 mtspr DEC,r0 /* prevent dec exceptions */ 222 mttbl r0 /* prevent fit & wdt exceptions */ 223 mttbu r0 224 mtspr TSR,r1 /* clear all timer exception status */ 225 mtspr TCR,r0 /* disable all */ 226 mtspr ESR,r0 /* clear exception syndrome register */ 227 mtspr MCSR,r0 /* machine check syndrome register */ 228 mtxer r0 /* clear integer exception register */ 229 230#ifdef CONFIG_SYS_BOOK3E_HV 231 mtspr MAS8,r0 /* make sure MAS8 is clear */ 232#endif 233 234 /* Enable Time Base and Select Time Base Clock */ 235 lis r0,HID0_EMCP@h /* Enable machine check */ 236#if defined(CONFIG_ENABLE_36BIT_PHYS) 237 ori r0,r0,HID0_ENMAS7@l /* Enable MAS7 */ 238#endif 239#ifndef CONFIG_E500MC 240 ori r0,r0,HID0_TBEN@l /* Enable Timebase */ 241#endif 242 mtspr HID0,r0 243 244#ifndef CONFIG_E500MC 245 li r0,(HID1_ASTME|HID1_ABE)@l /* Addr streaming & broadcast */ 246 mfspr r3,PVR 247 andi. r3,r3, 0xff 248 cmpwi r3,0x50@l /* if we are rev 5.0 or greater set MBDD */ 249 blt 1f 250 /* Set MBDD bit also */ 251 ori r0, r0, HID1_MBDD@l 2521: 253 mtspr HID1,r0 254#endif 255 256 /* Enable Branch Prediction */ 257#if defined(CONFIG_BTB) 258 lis r0,BUCSR_ENABLE@h 259 ori r0,r0,BUCSR_ENABLE@l 260 mtspr SPRN_BUCSR,r0 261#endif 262 263#if defined(CONFIG_SYS_INIT_DBCR) 264 lis r1,0xffff 265 ori r1,r1,0xffff 266 mtspr DBSR,r1 /* Clear all status bits */ 267 lis r0,CONFIG_SYS_INIT_DBCR@h /* DBCR0[IDM] must be set */ 268 ori r0,r0,CONFIG_SYS_INIT_DBCR@l 269 mtspr DBCR0,r0 270#endif 271 272#ifdef CONFIG_MPC8569 273#define CONFIG_SYS_LBC_ADDR (CONFIG_SYS_CCSRBAR_DEFAULT + 0x5000) 274#define CONFIG_SYS_LBCR_ADDR (CONFIG_SYS_LBC_ADDR + 0xd0) 275 276 /* MPC8569 Rev.0 silcon needs to set bit 13 of LBCR to allow elBC to 277 * use address space which is more than 12bits, and it must be done in 278 * the 4K boot page. So we set this bit here. 279 */ 280 281 /* create a temp mapping TLB0[0] for LBCR */ 282 lis r6,FSL_BOOKE_MAS0(0, 0, 0)@h 283 ori r6,r6,FSL_BOOKE_MAS0(0, 0, 0)@l 284 285 lis r7,FSL_BOOKE_MAS1(1, 0, 0, 0, BOOKE_PAGESZ_4K)@h 286 ori r7,r7,FSL_BOOKE_MAS1(1, 0, 0, 0, BOOKE_PAGESZ_4K)@l 287 288 lis r8,FSL_BOOKE_MAS2(CONFIG_SYS_LBC_ADDR, MAS2_I|MAS2_G)@h 289 ori r8,r8,FSL_BOOKE_MAS2(CONFIG_SYS_LBC_ADDR, MAS2_I|MAS2_G)@l 290 291 lis r9,FSL_BOOKE_MAS3(CONFIG_SYS_LBC_ADDR, 0, 292 (MAS3_SX|MAS3_SW|MAS3_SR))@h 293 ori r9,r9,FSL_BOOKE_MAS3(CONFIG_SYS_LBC_ADDR, 0, 294 (MAS3_SX|MAS3_SW|MAS3_SR))@l 295 296 mtspr MAS0,r6 297 mtspr MAS1,r7 298 mtspr MAS2,r8 299 mtspr MAS3,r9 300 isync 301 msync 302 tlbwe 303 304 /* Set LBCR register */ 305 lis r4,CONFIG_SYS_LBCR_ADDR@h 306 ori r4,r4,CONFIG_SYS_LBCR_ADDR@l 307 308 lis r5,CONFIG_SYS_LBC_LBCR@h 309 ori r5,r5,CONFIG_SYS_LBC_LBCR@l 310 stw r5,0(r4) 311 isync 312 313 /* invalidate this temp TLB */ 314 lis r4,CONFIG_SYS_LBC_ADDR@h 315 ori r4,r4,CONFIG_SYS_LBC_ADDR@l 316 tlbivax 0,r4 317 isync 318 319#endif /* CONFIG_MPC8569 */ 320 321/* 322 * Relocate CCSR, if necessary. We relocate CCSR if (obviously) the default 323 * location is not where we want it. This typically happens on a 36-bit 324 * system, where we want to move CCSR to near the top of 36-bit address space. 325 * 326 * To move CCSR, we create two temporary TLBs, one for the old location, and 327 * another for the new location. On CoreNet systems, we also need to create 328 * a special, temporary LAW. 329 * 330 * As a general rule, TLB0 is used for short-term TLBs, and TLB1 is used for 331 * long-term TLBs, so we use TLB0 here. 332 */ 333#if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR_PHYS) 334 335#if !defined(CONFIG_SYS_CCSRBAR_PHYS_HIGH) || !defined(CONFIG_SYS_CCSRBAR_PHYS_LOW) 336#error "CONFIG_SYS_CCSRBAR_PHYS_HIGH and CONFIG_SYS_CCSRBAR_PHYS_LOW) must be defined." 337#endif 338 339purge_old_ccsr_tlb: 340 lis r8, CONFIG_SYS_CCSRBAR@h 341 ori r8, r8, CONFIG_SYS_CCSRBAR@l 342 lis r9, (CONFIG_SYS_CCSRBAR + 0x1000)@h 343 ori r9, r9, (CONFIG_SYS_CCSRBAR + 0x1000)@l 344 345 /* 346 * In a multi-stage boot (e.g. NAND boot), a previous stage may have 347 * created a TLB for CCSR, which will interfere with our relocation 348 * code. Since we're going to create a new TLB for CCSR anyway, 349 * it should be safe to delete this old TLB here. We have to search 350 * for it, though. 351 */ 352 353 li r1, 0 354 mtspr MAS6, r1 /* Search the current address space and PID */ 355 isync 356 msync 357 tlbsx 0, r8 358 mfspr r1, MAS1 359 andis. r2, r1, MAS1_VALID@h /* Check for the Valid bit */ 360 beq 1f /* Skip if no TLB found */ 361 362 rlwinm r1, r1, 0, 1, 31 /* Clear Valid bit */ 363 mtspr MAS1, r1 364 isync 365 msync 366 tlbwe 3671: 368 369create_ccsr_new_tlb: 370 /* 371 * Create a TLB for the new location of CCSR. Register R8 is reserved 372 * for the virtual address of this TLB (CONFIG_SYS_CCSRBAR). 373 */ 374 lis r0, FSL_BOOKE_MAS0(0, 0, 0)@h 375 ori r0, r0, FSL_BOOKE_MAS0(0, 0, 0)@l 376 lis r1, FSL_BOOKE_MAS1(1, 0, 0, 0, BOOKE_PAGESZ_4K)@h 377 ori r1, r1, FSL_BOOKE_MAS1(1, 0, 0, 0, BOOKE_PAGESZ_4K)@l 378 lis r2, FSL_BOOKE_MAS2(CONFIG_SYS_CCSRBAR, (MAS2_I|MAS2_G))@h 379 ori r2, r2, FSL_BOOKE_MAS2(CONFIG_SYS_CCSRBAR, (MAS2_I|MAS2_G))@l 380 lis r3, FSL_BOOKE_MAS3(CONFIG_SYS_CCSRBAR_PHYS_LOW, 0, (MAS3_SW|MAS3_SR))@h 381 ori r3, r3, FSL_BOOKE_MAS3(CONFIG_SYS_CCSRBAR_PHYS_LOW, 0, (MAS3_SW|MAS3_SR))@l 382 lis r7, CONFIG_SYS_CCSRBAR_PHYS_HIGH@h 383 ori r7, r7, CONFIG_SYS_CCSRBAR_PHYS_HIGH@l 384 mtspr MAS0, r0 385 mtspr MAS1, r1 386 mtspr MAS2, r2 387 mtspr MAS3, r3 388 mtspr MAS7, r7 389 isync 390 msync 391 tlbwe 392 393 /* 394 * Create a TLB for the current location of CCSR. Register R9 is reserved 395 * for the virtual address of this TLB (CONFIG_SYS_CCSRBAR + 0x1000). 396 */ 397create_ccsr_old_tlb: 398 lis r0, FSL_BOOKE_MAS0(0, 1, 0)@h 399 ori r0, r0, FSL_BOOKE_MAS0(0, 1, 0)@l 400 lis r2, FSL_BOOKE_MAS2(CONFIG_SYS_CCSRBAR + 0x1000, (MAS2_I|MAS2_G))@h 401 ori r2, r2, FSL_BOOKE_MAS2(CONFIG_SYS_CCSRBAR + 0x1000, (MAS2_I|MAS2_G))@l 402 lis r3, FSL_BOOKE_MAS3(CONFIG_SYS_CCSRBAR_DEFAULT, 0, (MAS3_SW|MAS3_SR))@h 403 ori r3, r3, FSL_BOOKE_MAS3(CONFIG_SYS_CCSRBAR_DEFAULT, 0, (MAS3_SW|MAS3_SR))@l 404 li r7, 0 /* The default CCSR address is always a 32-bit number */ 405 mtspr MAS0, r0 406 /* MAS1 is the same as above */ 407 mtspr MAS2, r2 408 mtspr MAS3, r3 409 mtspr MAS7, r7 410 isync 411 msync 412 tlbwe 413 414#ifdef CONFIG_FSL_CORENET 415 416#define CCSR_LAWBARH0 (CONFIG_SYS_CCSRBAR + 0x1000) 417#define LAW_EN 0x80000000 418#define LAW_SIZE_4K 0xb 419#define CCSRBAR_LAWAR (LAW_EN | (0x1e << 20) | LAW_SIZE_4K) 420#define CCSRAR_C 0x80000000 /* Commit */ 421 422create_temp_law: 423 /* 424 * On CoreNet systems, we create the temporary LAW using a special LAW 425 * target ID of 0x1e. LAWBARH is at offset 0xc00 in CCSR. 426 */ 427 lis r0, CONFIG_SYS_CCSRBAR_PHYS_HIGH@h 428 ori r0, r0, CONFIG_SYS_CCSRBAR_PHYS_HIGH@l 429 lis r1, CONFIG_SYS_CCSRBAR_PHYS_LOW@h 430 ori r1, r1, CONFIG_SYS_CCSRBAR_PHYS_LOW@l 431 lis r2, CCSRBAR_LAWAR@h 432 ori r2, r2, CCSRBAR_LAWAR@l 433 434 stw r0, 0xc00(r9) /* LAWBARH0 */ 435 stw r1, 0xc04(r9) /* LAWBARL0 */ 436 sync 437 stw r2, 0xc08(r9) /* LAWAR0 */ 438 439 /* 440 * Read back from LAWAR to ensure the update is complete. e500mc 441 * cores also require an isync. 442 */ 443 lwz r0, 0xc08(r9) /* LAWAR0 */ 444 isync 445 446 /* 447 * Read the current CCSRBARH and CCSRBARL using load word instructions. 448 * Follow this with an isync instruction. This forces any outstanding 449 * accesses to configuration space to completion. 450 */ 451read_old_ccsrbar: 452 lwz r0, 0(r9) /* CCSRBARH */ 453 lwz r0, 4(r9) /* CCSRBARL */ 454 isync 455 456 /* 457 * Write the new values for CCSRBARH and CCSRBARL to their old 458 * locations. The CCSRBARH has a shadow register. When the CCSRBARH 459 * has a new value written it loads a CCSRBARH shadow register. When 460 * the CCSRBARL is written, the CCSRBARH shadow register contents 461 * along with the CCSRBARL value are loaded into the CCSRBARH and 462 * CCSRBARL registers, respectively. Follow this with a sync 463 * instruction. 464 */ 465write_new_ccsrbar: 466 lis r0, CONFIG_SYS_CCSRBAR_PHYS_HIGH@h 467 ori r0, r0, CONFIG_SYS_CCSRBAR_PHYS_HIGH@l 468 lis r1, CONFIG_SYS_CCSRBAR_PHYS_LOW@h 469 ori r1, r1, CONFIG_SYS_CCSRBAR_PHYS_LOW@l 470 lis r2, CCSRAR_C@h 471 ori r2, r2, CCSRAR_C@l 472 473 stw r0, 0(r9) /* Write to CCSRBARH */ 474 sync /* Make sure we write to CCSRBARH first */ 475 stw r1, 4(r9) /* Write to CCSRBARL */ 476 sync 477 478 /* 479 * Write a 1 to the commit bit (C) of CCSRAR at the old location. 480 * Follow this with a sync instruction. 481 */ 482 stw r2, 8(r9) 483 sync 484 485 /* Delete the temporary LAW */ 486delete_temp_law: 487 li r1, 0 488 stw r1, 0xc08(r8) 489 sync 490 stw r1, 0xc00(r8) 491 stw r1, 0xc04(r8) 492 sync 493 494#else /* #ifdef CONFIG_FSL_CORENET */ 495 496write_new_ccsrbar: 497 /* 498 * Read the current value of CCSRBAR using a load word instruction 499 * followed by an isync. This forces all accesses to configuration 500 * space to complete. 501 */ 502 sync 503 lwz r0, 0(r9) 504 isync 505 506/* CONFIG_SYS_CCSRBAR_PHYS right shifted by 12 */ 507#define CCSRBAR_PHYS_RS12 ((CONFIG_SYS_CCSRBAR_PHYS_HIGH << 20) | \ 508 (CONFIG_SYS_CCSRBAR_PHYS_LOW >> 12)) 509 510 /* Write the new value to CCSRBAR. */ 511 lis r0, CCSRBAR_PHYS_RS12@h 512 ori r0, r0, CCSRBAR_PHYS_RS12@l 513 stw r0, 0(r9) 514 sync 515 516 /* 517 * The manual says to perform a load of an address that does not 518 * access configuration space or the on-chip SRAM using an existing TLB, 519 * but that doesn't appear to be necessary. We will do the isync, 520 * though. 521 */ 522 isync 523 524 /* 525 * Read the contents of CCSRBAR from its new location, followed by 526 * another isync. 527 */ 528 lwz r0, 0(r8) 529 isync 530 531#endif /* #ifdef CONFIG_FSL_CORENET */ 532 533 /* Delete the temporary TLBs */ 534delete_temp_tlbs: 535 lis r0, FSL_BOOKE_MAS0(0, 0, 0)@h 536 ori r0, r0, FSL_BOOKE_MAS0(0, 0, 0)@l 537 li r1, 0 538 lis r2, FSL_BOOKE_MAS2(CONFIG_SYS_CCSRBAR, (MAS2_I|MAS2_G))@h 539 ori r2, r2, FSL_BOOKE_MAS2(CONFIG_SYS_CCSRBAR, (MAS2_I|MAS2_G))@l 540 mtspr MAS0, r0 541 mtspr MAS1, r1 542 mtspr MAS2, r2 543 isync 544 msync 545 tlbwe 546 547 lis r0, FSL_BOOKE_MAS0(0, 1, 0)@h 548 ori r0, r0, FSL_BOOKE_MAS0(0, 1, 0)@l 549 lis r2, FSL_BOOKE_MAS2(CONFIG_SYS_CCSRBAR + 0x1000, (MAS2_I|MAS2_G))@h 550 ori r2, r2, FSL_BOOKE_MAS2(CONFIG_SYS_CCSRBAR + 0x1000, (MAS2_I|MAS2_G))@l 551 mtspr MAS0, r0 552 mtspr MAS2, r2 553 isync 554 msync 555 tlbwe 556#endif /* #if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR_PHYS) */ 557 558create_init_ram_area: 559 lis r6,FSL_BOOKE_MAS0(1, 15, 0)@h 560 ori r6,r6,FSL_BOOKE_MAS0(1, 15, 0)@l 561 562#if !defined(CONFIG_SYS_RAMBOOT) && !defined(CONFIG_SECURE_BOOT) 563 /* create a temp mapping in AS=1 to the 4M boot window */ 564 lis r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_4M)@h 565 ori r7,r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_4M)@l 566 567 lis r8,FSL_BOOKE_MAS2(CONFIG_SYS_MONITOR_BASE & 0xffc00000, (MAS2_I|MAS2_G))@h 568 ori r8,r8,FSL_BOOKE_MAS2(CONFIG_SYS_MONITOR_BASE & 0xffc00000, (MAS2_I|MAS2_G))@l 569 570 /* The 85xx has the default boot window 0xff800000 - 0xffffffff */ 571 lis r9,FSL_BOOKE_MAS3(0xffc00000, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@h 572 ori r9,r9,FSL_BOOKE_MAS3(0xffc00000, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@l 573#elif !defined(CONFIG_SYS_RAMBOOT) && defined(CONFIG_SECURE_BOOT) 574 /* create a temp mapping in AS = 1 for Flash mapping 575 * created by PBL for ISBC code 576 */ 577 lis r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_1M)@h 578 ori r7,r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_1M)@l 579 580 lis r8,FSL_BOOKE_MAS2(CONFIG_SYS_MONITOR_BASE, (MAS2_I|MAS2_G))@h 581 ori r8,r8,FSL_BOOKE_MAS2(CONFIG_SYS_MONITOR_BASE, (MAS2_I|MAS2_G))@l 582 583 lis r9,FSL_BOOKE_MAS3(CONFIG_SYS_PBI_FLASH_WINDOW, 0, 584 (MAS3_SX|MAS3_SW|MAS3_SR))@h 585 ori r9,r9,FSL_BOOKE_MAS3(CONFIG_SYS_PBI_FLASH_WINDOW, 0, 586 (MAS3_SX|MAS3_SW|MAS3_SR))@l 587#else 588 /* 589 * create a temp mapping in AS=1 to the 1M CONFIG_SYS_MONITOR_BASE space, the main 590 * image has been relocated to CONFIG_SYS_MONITOR_BASE on the second stage. 591 */ 592 lis r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_1M)@h 593 ori r7,r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_1M)@l 594 595 lis r8,FSL_BOOKE_MAS2(CONFIG_SYS_MONITOR_BASE, (MAS2_I|MAS2_G))@h 596 ori r8,r8,FSL_BOOKE_MAS2(CONFIG_SYS_MONITOR_BASE, (MAS2_I|MAS2_G))@l 597 598 lis r9,FSL_BOOKE_MAS3(CONFIG_SYS_MONITOR_BASE, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@h 599 ori r9,r9,FSL_BOOKE_MAS3(CONFIG_SYS_MONITOR_BASE, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@l 600#endif 601 602 mtspr MAS0,r6 603 mtspr MAS1,r7 604 mtspr MAS2,r8 605 mtspr MAS3,r9 606 isync 607 msync 608 tlbwe 609 610 /* create a temp mapping in AS=1 to the stack */ 611 lis r6,FSL_BOOKE_MAS0(1, 14, 0)@h 612 ori r6,r6,FSL_BOOKE_MAS0(1, 14, 0)@l 613 614 lis r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_16K)@h 615 ori r7,r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_16K)@l 616 617 lis r8,FSL_BOOKE_MAS2(CONFIG_SYS_INIT_RAM_ADDR, 0)@h 618 ori r8,r8,FSL_BOOKE_MAS2(CONFIG_SYS_INIT_RAM_ADDR, 0)@l 619 620#if defined(CONFIG_SYS_INIT_RAM_ADDR_PHYS_LOW) && \ 621 defined(CONFIG_SYS_INIT_RAM_ADDR_PHYS_HIGH) 622 lis r9,FSL_BOOKE_MAS3(CONFIG_SYS_INIT_RAM_ADDR_PHYS_LOW, 0, 623 (MAS3_SX|MAS3_SW|MAS3_SR))@h 624 ori r9,r9,FSL_BOOKE_MAS3(CONFIG_SYS_INIT_RAM_ADDR_PHYS_LOW, 0, 625 (MAS3_SX|MAS3_SW|MAS3_SR))@l 626 li r10,CONFIG_SYS_INIT_RAM_ADDR_PHYS_HIGH 627 mtspr MAS7,r10 628#else 629 lis r9,FSL_BOOKE_MAS3(CONFIG_SYS_INIT_RAM_ADDR, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@h 630 ori r9,r9,FSL_BOOKE_MAS3(CONFIG_SYS_INIT_RAM_ADDR, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@l 631#endif 632 633 mtspr MAS0,r6 634 mtspr MAS1,r7 635 mtspr MAS2,r8 636 mtspr MAS3,r9 637 isync 638 msync 639 tlbwe 640 641 lis r6,MSR_IS|MSR_DS@h 642 ori r6,r6,MSR_IS|MSR_DS@l 643 lis r7,switch_as@h 644 ori r7,r7,switch_as@l 645 646 mtspr SPRN_SRR0,r7 647 mtspr SPRN_SRR1,r6 648 rfi 649 650switch_as: 651/* L1 DCache is used for initial RAM */ 652 653 /* Allocate Initial RAM in data cache. 654 */ 655 lis r3,CONFIG_SYS_INIT_RAM_ADDR@h 656 ori r3,r3,CONFIG_SYS_INIT_RAM_ADDR@l 657 mfspr r2, L1CFG0 658 andi. r2, r2, 0x1ff 659 /* cache size * 1024 / (2 * L1 line size) */ 660 slwi r2, r2, (10 - 1 - L1_CACHE_SHIFT) 661 mtctr r2 662 li r0,0 6631: 664 dcbz r0,r3 665 dcbtls 0,r0,r3 666 addi r3,r3,CONFIG_SYS_CACHELINE_SIZE 667 bdnz 1b 668 669 /* Jump out the last 4K page and continue to 'normal' start */ 670#ifdef CONFIG_SYS_RAMBOOT 671 b _start_cont 672#else 673 /* Calculate absolute address in FLASH and jump there */ 674 /*--------------------------------------------------------------*/ 675 lis r3,CONFIG_SYS_MONITOR_BASE@h 676 ori r3,r3,CONFIG_SYS_MONITOR_BASE@l 677 addi r3,r3,_start_cont - _start + _START_OFFSET 678 mtlr r3 679 blr 680#endif 681 682 .text 683 .globl _start 684_start: 685 .long 0x27051956 /* U-BOOT Magic Number */ 686 .globl version_string 687version_string: 688 .ascii U_BOOT_VERSION_STRING, "\0" 689 690 .align 4 691 .globl _start_cont 692_start_cont: 693 /* Setup the stack in initial RAM,could be L2-as-SRAM or L1 dcache*/ 694 lis r1,CONFIG_SYS_INIT_RAM_ADDR@h 695 ori r1,r1,CONFIG_SYS_INIT_SP_OFFSET@l 696 697 li r0,0 698 stwu r0,-4(r1) 699 stwu r0,-4(r1) /* Terminate call chain */ 700 701 stwu r1,-8(r1) /* Save back chain and move SP */ 702 lis r0,RESET_VECTOR@h /* Address of reset vector */ 703 ori r0,r0,RESET_VECTOR@l 704 stwu r1,-8(r1) /* Save back chain and move SP */ 705 stw r0,+12(r1) /* Save return addr (underflow vect) */ 706 707 GET_GOT 708 bl cpu_init_early_f 709 710 /* switch back to AS = 0 */ 711 lis r3,(MSR_CE|MSR_ME|MSR_DE)@h 712 ori r3,r3,(MSR_CE|MSR_ME|MSR_DE)@l 713 mtmsr r3 714 isync 715 716 bl cpu_init_f 717 bl board_init_f 718 isync 719 720 /* NOTREACHED - board_init_f() does not return */ 721 722#ifndef CONFIG_NAND_SPL 723 . = EXC_OFF_SYS_RESET 724 .globl _start_of_vectors 725_start_of_vectors: 726 727/* Critical input. */ 728 CRIT_EXCEPTION(0x0100, CriticalInput, CritcalInputException) 729 730/* Machine check */ 731 MCK_EXCEPTION(0x200, MachineCheck, MachineCheckException) 732 733/* Data Storage exception. */ 734 STD_EXCEPTION(0x0300, DataStorage, UnknownException) 735 736/* Instruction Storage exception. */ 737 STD_EXCEPTION(0x0400, InstStorage, UnknownException) 738 739/* External Interrupt exception. */ 740 STD_EXCEPTION(0x0500, ExtInterrupt, ExtIntException) 741 742/* Alignment exception. */ 743 . = 0x0600 744Alignment: 745 EXCEPTION_PROLOG(SRR0, SRR1) 746 mfspr r4,DAR 747 stw r4,_DAR(r21) 748 mfspr r5,DSISR 749 stw r5,_DSISR(r21) 750 addi r3,r1,STACK_FRAME_OVERHEAD 751 EXC_XFER_TEMPLATE(Alignment, AlignmentException, MSR_KERNEL, COPY_EE) 752 753/* Program check exception */ 754 . = 0x0700 755ProgramCheck: 756 EXCEPTION_PROLOG(SRR0, SRR1) 757 addi r3,r1,STACK_FRAME_OVERHEAD 758 EXC_XFER_TEMPLATE(ProgramCheck, ProgramCheckException, 759 MSR_KERNEL, COPY_EE) 760 761 /* No FPU on MPC85xx. This exception is not supposed to happen. 762 */ 763 STD_EXCEPTION(0x0800, FPUnavailable, UnknownException) 764 765 . = 0x0900 766/* 767 * r0 - SYSCALL number 768 * r3-... arguments 769 */ 770SystemCall: 771 addis r11,r0,0 /* get functions table addr */ 772 ori r11,r11,0 /* Note: this code is patched in trap_init */ 773 addis r12,r0,0 /* get number of functions */ 774 ori r12,r12,0 775 776 cmplw 0,r0,r12 777 bge 1f 778 779 rlwinm r0,r0,2,0,31 /* fn_addr = fn_tbl[r0] */ 780 add r11,r11,r0 781 lwz r11,0(r11) 782 783 li r20,0xd00-4 /* Get stack pointer */ 784 lwz r12,0(r20) 785 subi r12,r12,12 /* Adjust stack pointer */ 786 li r0,0xc00+_end_back-SystemCall 787 cmplw 0,r0,r12 /* Check stack overflow */ 788 bgt 1f 789 stw r12,0(r20) 790 791 mflr r0 792 stw r0,0(r12) 793 mfspr r0,SRR0 794 stw r0,4(r12) 795 mfspr r0,SRR1 796 stw r0,8(r12) 797 798 li r12,0xc00+_back-SystemCall 799 mtlr r12 800 mtspr SRR0,r11 801 8021: SYNC 803 rfi 804_back: 805 806 mfmsr r11 /* Disable interrupts */ 807 li r12,0 808 ori r12,r12,MSR_EE 809 andc r11,r11,r12 810 SYNC /* Some chip revs need this... */ 811 mtmsr r11 812 SYNC 813 814 li r12,0xd00-4 /* restore regs */ 815 lwz r12,0(r12) 816 817 lwz r11,0(r12) 818 mtlr r11 819 lwz r11,4(r12) 820 mtspr SRR0,r11 821 lwz r11,8(r12) 822 mtspr SRR1,r11 823 824 addi r12,r12,12 /* Adjust stack pointer */ 825 li r20,0xd00-4 826 stw r12,0(r20) 827 828 SYNC 829 rfi 830_end_back: 831 832 STD_EXCEPTION(0x0a00, Decrementer, timer_interrupt) 833 STD_EXCEPTION(0x0b00, IntervalTimer, UnknownException) 834 STD_EXCEPTION(0x0c00, WatchdogTimer, UnknownException) 835 836 STD_EXCEPTION(0x0d00, DataTLBError, UnknownException) 837 STD_EXCEPTION(0x0e00, InstructionTLBError, UnknownException) 838 839 CRIT_EXCEPTION(0x0f00, DebugBreakpoint, DebugException ) 840 841 .globl _end_of_vectors 842_end_of_vectors: 843 844 845 . = . + (0x100 - ( . & 0xff )) /* align for debug */ 846 847/* 848 * This code finishes saving the registers to the exception frame 849 * and jumps to the appropriate handler for the exception. 850 * Register r21 is pointer into trap frame, r1 has new stack pointer. 851 */ 852 .globl transfer_to_handler 853transfer_to_handler: 854 stw r22,_NIP(r21) 855 lis r22,MSR_POW@h 856 andc r23,r23,r22 857 stw r23,_MSR(r21) 858 SAVE_GPR(7, r21) 859 SAVE_4GPRS(8, r21) 860 SAVE_8GPRS(12, r21) 861 SAVE_8GPRS(24, r21) 862 863 mflr r23 864 andi. r24,r23,0x3f00 /* get vector offset */ 865 stw r24,TRAP(r21) 866 li r22,0 867 stw r22,RESULT(r21) 868 mtspr SPRG2,r22 /* r1 is now kernel sp */ 869 870 lwz r24,0(r23) /* virtual address of handler */ 871 lwz r23,4(r23) /* where to go when done */ 872 mtspr SRR0,r24 873 mtspr SRR1,r20 874 mtlr r23 875 SYNC 876 rfi /* jump to handler, enable MMU */ 877 878int_return: 879 mfmsr r28 /* Disable interrupts */ 880 li r4,0 881 ori r4,r4,MSR_EE 882 andc r28,r28,r4 883 SYNC /* Some chip revs need this... */ 884 mtmsr r28 885 SYNC 886 lwz r2,_CTR(r1) 887 lwz r0,_LINK(r1) 888 mtctr r2 889 mtlr r0 890 lwz r2,_XER(r1) 891 lwz r0,_CCR(r1) 892 mtspr XER,r2 893 mtcrf 0xFF,r0 894 REST_10GPRS(3, r1) 895 REST_10GPRS(13, r1) 896 REST_8GPRS(23, r1) 897 REST_GPR(31, r1) 898 lwz r2,_NIP(r1) /* Restore environment */ 899 lwz r0,_MSR(r1) 900 mtspr SRR0,r2 901 mtspr SRR1,r0 902 lwz r0,GPR0(r1) 903 lwz r2,GPR2(r1) 904 lwz r1,GPR1(r1) 905 SYNC 906 rfi 907 908crit_return: 909 mfmsr r28 /* Disable interrupts */ 910 li r4,0 911 ori r4,r4,MSR_EE 912 andc r28,r28,r4 913 SYNC /* Some chip revs need this... */ 914 mtmsr r28 915 SYNC 916 lwz r2,_CTR(r1) 917 lwz r0,_LINK(r1) 918 mtctr r2 919 mtlr r0 920 lwz r2,_XER(r1) 921 lwz r0,_CCR(r1) 922 mtspr XER,r2 923 mtcrf 0xFF,r0 924 REST_10GPRS(3, r1) 925 REST_10GPRS(13, r1) 926 REST_8GPRS(23, r1) 927 REST_GPR(31, r1) 928 lwz r2,_NIP(r1) /* Restore environment */ 929 lwz r0,_MSR(r1) 930 mtspr SPRN_CSRR0,r2 931 mtspr SPRN_CSRR1,r0 932 lwz r0,GPR0(r1) 933 lwz r2,GPR2(r1) 934 lwz r1,GPR1(r1) 935 SYNC 936 rfci 937 938mck_return: 939 mfmsr r28 /* Disable interrupts */ 940 li r4,0 941 ori r4,r4,MSR_EE 942 andc r28,r28,r4 943 SYNC /* Some chip revs need this... */ 944 mtmsr r28 945 SYNC 946 lwz r2,_CTR(r1) 947 lwz r0,_LINK(r1) 948 mtctr r2 949 mtlr r0 950 lwz r2,_XER(r1) 951 lwz r0,_CCR(r1) 952 mtspr XER,r2 953 mtcrf 0xFF,r0 954 REST_10GPRS(3, r1) 955 REST_10GPRS(13, r1) 956 REST_8GPRS(23, r1) 957 REST_GPR(31, r1) 958 lwz r2,_NIP(r1) /* Restore environment */ 959 lwz r0,_MSR(r1) 960 mtspr SPRN_MCSRR0,r2 961 mtspr SPRN_MCSRR1,r0 962 lwz r0,GPR0(r1) 963 lwz r2,GPR2(r1) 964 lwz r1,GPR1(r1) 965 SYNC 966 rfmci 967 968/* Cache functions. 969*/ 970.globl flush_icache 971flush_icache: 972.globl invalidate_icache 973invalidate_icache: 974 mfspr r0,L1CSR1 975 ori r0,r0,L1CSR1_ICFI 976 msync 977 isync 978 mtspr L1CSR1,r0 979 isync 980 blr /* entire I cache */ 981 982.globl invalidate_dcache 983invalidate_dcache: 984 mfspr r0,L1CSR0 985 ori r0,r0,L1CSR0_DCFI 986 msync 987 isync 988 mtspr L1CSR0,r0 989 isync 990 blr 991 992 .globl icache_enable 993icache_enable: 994 mflr r8 995 bl invalidate_icache 996 mtlr r8 997 isync 998 mfspr r4,L1CSR1 999 ori r4,r4,0x0001 1000 oris r4,r4,0x0001 1001 mtspr L1CSR1,r4 1002 isync 1003 blr 1004 1005 .globl icache_disable 1006icache_disable: 1007 mfspr r0,L1CSR1 1008 lis r3,0 1009 ori r3,r3,L1CSR1_ICE 1010 andc r0,r0,r3 1011 mtspr L1CSR1,r0 1012 isync 1013 blr 1014 1015 .globl icache_status 1016icache_status: 1017 mfspr r3,L1CSR1 1018 andi. r3,r3,L1CSR1_ICE 1019 blr 1020 1021 .globl dcache_enable 1022dcache_enable: 1023 mflr r8 1024 bl invalidate_dcache 1025 mtlr r8 1026 isync 1027 mfspr r0,L1CSR0 1028 ori r0,r0,0x0001 1029 oris r0,r0,0x0001 1030 msync 1031 isync 1032 mtspr L1CSR0,r0 1033 isync 1034 blr 1035 1036 .globl dcache_disable 1037dcache_disable: 1038 mfspr r3,L1CSR0 1039 lis r4,0 1040 ori r4,r4,L1CSR0_DCE 1041 andc r3,r3,r4 1042 mtspr L1CSR0,r3 1043 isync 1044 blr 1045 1046 .globl dcache_status 1047dcache_status: 1048 mfspr r3,L1CSR0 1049 andi. r3,r3,L1CSR0_DCE 1050 blr 1051 1052 .globl get_pir 1053get_pir: 1054 mfspr r3,PIR 1055 blr 1056 1057 .globl get_pvr 1058get_pvr: 1059 mfspr r3,PVR 1060 blr 1061 1062 .globl get_svr 1063get_svr: 1064 mfspr r3,SVR 1065 blr 1066 1067 .globl wr_tcr 1068wr_tcr: 1069 mtspr TCR,r3 1070 blr 1071 1072/*------------------------------------------------------------------------------- */ 1073/* Function: in8 */ 1074/* Description: Input 8 bits */ 1075/*------------------------------------------------------------------------------- */ 1076 .globl in8 1077in8: 1078 lbz r3,0x0000(r3) 1079 blr 1080 1081/*------------------------------------------------------------------------------- */ 1082/* Function: out8 */ 1083/* Description: Output 8 bits */ 1084/*------------------------------------------------------------------------------- */ 1085 .globl out8 1086out8: 1087 stb r4,0x0000(r3) 1088 sync 1089 blr 1090 1091/*------------------------------------------------------------------------------- */ 1092/* Function: out16 */ 1093/* Description: Output 16 bits */ 1094/*------------------------------------------------------------------------------- */ 1095 .globl out16 1096out16: 1097 sth r4,0x0000(r3) 1098 sync 1099 blr 1100 1101/*------------------------------------------------------------------------------- */ 1102/* Function: out16r */ 1103/* Description: Byte reverse and output 16 bits */ 1104/*------------------------------------------------------------------------------- */ 1105 .globl out16r 1106out16r: 1107 sthbrx r4,r0,r3 1108 sync 1109 blr 1110 1111/*------------------------------------------------------------------------------- */ 1112/* Function: out32 */ 1113/* Description: Output 32 bits */ 1114/*------------------------------------------------------------------------------- */ 1115 .globl out32 1116out32: 1117 stw r4,0x0000(r3) 1118 sync 1119 blr 1120 1121/*------------------------------------------------------------------------------- */ 1122/* Function: out32r */ 1123/* Description: Byte reverse and output 32 bits */ 1124/*------------------------------------------------------------------------------- */ 1125 .globl out32r 1126out32r: 1127 stwbrx r4,r0,r3 1128 sync 1129 blr 1130 1131/*------------------------------------------------------------------------------- */ 1132/* Function: in16 */ 1133/* Description: Input 16 bits */ 1134/*------------------------------------------------------------------------------- */ 1135 .globl in16 1136in16: 1137 lhz r3,0x0000(r3) 1138 blr 1139 1140/*------------------------------------------------------------------------------- */ 1141/* Function: in16r */ 1142/* Description: Input 16 bits and byte reverse */ 1143/*------------------------------------------------------------------------------- */ 1144 .globl in16r 1145in16r: 1146 lhbrx r3,r0,r3 1147 blr 1148 1149/*------------------------------------------------------------------------------- */ 1150/* Function: in32 */ 1151/* Description: Input 32 bits */ 1152/*------------------------------------------------------------------------------- */ 1153 .globl in32 1154in32: 1155 lwz 3,0x0000(3) 1156 blr 1157 1158/*------------------------------------------------------------------------------- */ 1159/* Function: in32r */ 1160/* Description: Input 32 bits and byte reverse */ 1161/*------------------------------------------------------------------------------- */ 1162 .globl in32r 1163in32r: 1164 lwbrx r3,r0,r3 1165 blr 1166#endif /* !CONFIG_NAND_SPL */ 1167 1168/*------------------------------------------------------------------------------*/ 1169 1170/* 1171 * void write_tlb(mas0, mas1, mas2, mas3, mas7) 1172 */ 1173 .globl write_tlb 1174write_tlb: 1175 mtspr MAS0,r3 1176 mtspr MAS1,r4 1177 mtspr MAS2,r5 1178 mtspr MAS3,r6 1179#ifdef CONFIG_ENABLE_36BIT_PHYS 1180 mtspr MAS7,r7 1181#endif 1182 li r3,0 1183#ifdef CONFIG_SYS_BOOK3E_HV 1184 mtspr MAS8,r3 1185#endif 1186 isync 1187 tlbwe 1188 msync 1189 isync 1190 blr 1191 1192/* 1193 * void relocate_code (addr_sp, gd, addr_moni) 1194 * 1195 * This "function" does not return, instead it continues in RAM 1196 * after relocating the monitor code. 1197 * 1198 * r3 = dest 1199 * r4 = src 1200 * r5 = length in bytes 1201 * r6 = cachelinesize 1202 */ 1203 .globl relocate_code 1204relocate_code: 1205 mr r1,r3 /* Set new stack pointer */ 1206 mr r9,r4 /* Save copy of Init Data pointer */ 1207 mr r10,r5 /* Save copy of Destination Address */ 1208 1209 GET_GOT 1210 mr r3,r5 /* Destination Address */ 1211 lis r4,CONFIG_SYS_MONITOR_BASE@h /* Source Address */ 1212 ori r4,r4,CONFIG_SYS_MONITOR_BASE@l 1213 lwz r5,GOT(__init_end) 1214 sub r5,r5,r4 1215 li r6,CONFIG_SYS_CACHELINE_SIZE /* Cache Line Size */ 1216 1217 /* 1218 * Fix GOT pointer: 1219 * 1220 * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address 1221 * 1222 * Offset: 1223 */ 1224 sub r15,r10,r4 1225 1226 /* First our own GOT */ 1227 add r12,r12,r15 1228 /* the the one used by the C code */ 1229 add r30,r30,r15 1230 1231 /* 1232 * Now relocate code 1233 */ 1234 1235 cmplw cr1,r3,r4 1236 addi r0,r5,3 1237 srwi. r0,r0,2 1238 beq cr1,4f /* In place copy is not necessary */ 1239 beq 7f /* Protect against 0 count */ 1240 mtctr r0 1241 bge cr1,2f 1242 1243 la r8,-4(r4) 1244 la r7,-4(r3) 12451: lwzu r0,4(r8) 1246 stwu r0,4(r7) 1247 bdnz 1b 1248 b 4f 1249 12502: slwi r0,r0,2 1251 add r8,r4,r0 1252 add r7,r3,r0 12533: lwzu r0,-4(r8) 1254 stwu r0,-4(r7) 1255 bdnz 3b 1256 1257/* 1258 * Now flush the cache: note that we must start from a cache aligned 1259 * address. Otherwise we might miss one cache line. 1260 */ 12614: cmpwi r6,0 1262 add r5,r3,r5 1263 beq 7f /* Always flush prefetch queue in any case */ 1264 subi r0,r6,1 1265 andc r3,r3,r0 1266 mr r4,r3 12675: dcbst 0,r4 1268 add r4,r4,r6 1269 cmplw r4,r5 1270 blt 5b 1271 sync /* Wait for all dcbst to complete on bus */ 1272 mr r4,r3 12736: icbi 0,r4 1274 add r4,r4,r6 1275 cmplw r4,r5 1276 blt 6b 12777: sync /* Wait for all icbi to complete on bus */ 1278 isync 1279 1280 /* 1281 * Re-point the IVPR at RAM 1282 */ 1283 mtspr IVPR,r10 1284 1285/* 1286 * We are done. Do not return, instead branch to second part of board 1287 * initialization, now running from RAM. 1288 */ 1289 1290 addi r0,r10,in_ram - _start + _START_OFFSET 1291 mtlr r0 1292 blr /* NEVER RETURNS! */ 1293 .globl in_ram 1294in_ram: 1295 1296 /* 1297 * Relocation Function, r12 point to got2+0x8000 1298 * 1299 * Adjust got2 pointers, no need to check for 0, this code 1300 * already puts a few entries in the table. 1301 */ 1302 li r0,__got2_entries@sectoff@l 1303 la r3,GOT(_GOT2_TABLE_) 1304 lwz r11,GOT(_GOT2_TABLE_) 1305 mtctr r0 1306 sub r11,r3,r11 1307 addi r3,r3,-4 13081: lwzu r0,4(r3) 1309 cmpwi r0,0 1310 beq- 2f 1311 add r0,r0,r11 1312 stw r0,0(r3) 13132: bdnz 1b 1314 1315 /* 1316 * Now adjust the fixups and the pointers to the fixups 1317 * in case we need to move ourselves again. 1318 */ 1319 li r0,__fixup_entries@sectoff@l 1320 lwz r3,GOT(_FIXUP_TABLE_) 1321 cmpwi r0,0 1322 mtctr r0 1323 addi r3,r3,-4 1324 beq 4f 13253: lwzu r4,4(r3) 1326 lwzux r0,r4,r11 1327 cmpwi r0,0 1328 add r0,r0,r11 1329 stw r4,0(r3) 1330 beq- 5f 1331 stw r0,0(r4) 13325: bdnz 3b 13334: 1334clear_bss: 1335 /* 1336 * Now clear BSS segment 1337 */ 1338 lwz r3,GOT(__bss_start) 1339 lwz r4,GOT(__bss_end__) 1340 1341 cmplw 0,r3,r4 1342 beq 6f 1343 1344 li r0,0 13455: 1346 stw r0,0(r3) 1347 addi r3,r3,4 1348 cmplw 0,r3,r4 1349 bne 5b 13506: 1351 1352 mr r3,r9 /* Init Data pointer */ 1353 mr r4,r10 /* Destination Address */ 1354 bl board_init_r 1355 1356#ifndef CONFIG_NAND_SPL 1357 /* 1358 * Copy exception vector code to low memory 1359 * 1360 * r3: dest_addr 1361 * r7: source address, r8: end address, r9: target address 1362 */ 1363 .globl trap_init 1364trap_init: 1365 mflr r4 /* save link register */ 1366 GET_GOT 1367 lwz r7,GOT(_start_of_vectors) 1368 lwz r8,GOT(_end_of_vectors) 1369 1370 li r9,0x100 /* reset vector always at 0x100 */ 1371 1372 cmplw 0,r7,r8 1373 bgelr /* return if r7>=r8 - just in case */ 13741: 1375 lwz r0,0(r7) 1376 stw r0,0(r9) 1377 addi r7,r7,4 1378 addi r9,r9,4 1379 cmplw 0,r7,r8 1380 bne 1b 1381 1382 /* 1383 * relocate `hdlr' and `int_return' entries 1384 */ 1385 li r7,.L_CriticalInput - _start + _START_OFFSET 1386 bl trap_reloc 1387 li r7,.L_MachineCheck - _start + _START_OFFSET 1388 bl trap_reloc 1389 li r7,.L_DataStorage - _start + _START_OFFSET 1390 bl trap_reloc 1391 li r7,.L_InstStorage - _start + _START_OFFSET 1392 bl trap_reloc 1393 li r7,.L_ExtInterrupt - _start + _START_OFFSET 1394 bl trap_reloc 1395 li r7,.L_Alignment - _start + _START_OFFSET 1396 bl trap_reloc 1397 li r7,.L_ProgramCheck - _start + _START_OFFSET 1398 bl trap_reloc 1399 li r7,.L_FPUnavailable - _start + _START_OFFSET 1400 bl trap_reloc 1401 li r7,.L_Decrementer - _start + _START_OFFSET 1402 bl trap_reloc 1403 li r7,.L_IntervalTimer - _start + _START_OFFSET 1404 li r8,_end_of_vectors - _start + _START_OFFSET 14052: 1406 bl trap_reloc 1407 addi r7,r7,0x100 /* next exception vector */ 1408 cmplw 0,r7,r8 1409 blt 2b 1410 1411 lis r7,0x0 1412 mtspr IVPR,r7 1413 1414 mtlr r4 /* restore link register */ 1415 blr 1416 1417.globl unlock_ram_in_cache 1418unlock_ram_in_cache: 1419 /* invalidate the INIT_RAM section */ 1420 lis r3,(CONFIG_SYS_INIT_RAM_ADDR & ~(CONFIG_SYS_CACHELINE_SIZE-1))@h 1421 ori r3,r3,(CONFIG_SYS_INIT_RAM_ADDR & ~(CONFIG_SYS_CACHELINE_SIZE-1))@l 1422 mfspr r4,L1CFG0 1423 andi. r4,r4,0x1ff 1424 slwi r4,r4,(10 - 1 - L1_CACHE_SHIFT) 1425 mtctr r4 14261: dcbi r0,r3 1427 addi r3,r3,CONFIG_SYS_CACHELINE_SIZE 1428 bdnz 1b 1429 sync 1430 1431 /* Invalidate the TLB entries for the cache */ 1432 lis r3,CONFIG_SYS_INIT_RAM_ADDR@h 1433 ori r3,r3,CONFIG_SYS_INIT_RAM_ADDR@l 1434 tlbivax 0,r3 1435 addi r3,r3,0x1000 1436 tlbivax 0,r3 1437 addi r3,r3,0x1000 1438 tlbivax 0,r3 1439 addi r3,r3,0x1000 1440 tlbivax 0,r3 1441 isync 1442 blr 1443 1444.globl flush_dcache 1445flush_dcache: 1446 mfspr r3,SPRN_L1CFG0 1447 1448 rlwinm r5,r3,9,3 /* Extract cache block size */ 1449 twlgti r5,1 /* Only 32 and 64 byte cache blocks 1450 * are currently defined. 1451 */ 1452 li r4,32 1453 subfic r6,r5,2 /* r6 = log2(1KiB / cache block size) - 1454 * log2(number of ways) 1455 */ 1456 slw r5,r4,r5 /* r5 = cache block size */ 1457 1458 rlwinm r7,r3,0,0xff /* Extract number of KiB in the cache */ 1459 mulli r7,r7,13 /* An 8-way cache will require 13 1460 * loads per set. 1461 */ 1462 slw r7,r7,r6 1463 1464 /* save off HID0 and set DCFA */ 1465 mfspr r8,SPRN_HID0 1466 ori r9,r8,HID0_DCFA@l 1467 mtspr SPRN_HID0,r9 1468 isync 1469 1470 lis r4,0 1471 mtctr r7 1472 14731: lwz r3,0(r4) /* Load... */ 1474 add r4,r4,r5 1475 bdnz 1b 1476 1477 msync 1478 lis r4,0 1479 mtctr r7 1480 14811: dcbf 0,r4 /* ...and flush. */ 1482 add r4,r4,r5 1483 bdnz 1b 1484 1485 /* restore HID0 */ 1486 mtspr SPRN_HID0,r8 1487 isync 1488 1489 blr 1490 1491.globl setup_ivors 1492setup_ivors: 1493 1494#include "fixed_ivor.S" 1495 blr 1496#endif /* !CONFIG_NAND_SPL */ 1497