1*a47a12beSStefan Roese/* 2*a47a12beSStefan Roese * Copyright (C) 1998 Dan Malek <dmalek@jlc.net> 3*a47a12beSStefan Roese * Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se> 4*a47a12beSStefan Roese * Copyright (C) 2000, 2001,2002 Wolfgang Denk <wd@denx.de> 5*a47a12beSStefan Roese * Copyright Freescale Semiconductor, Inc. 2004, 2006, 2008. 6*a47a12beSStefan Roese * 7*a47a12beSStefan Roese * See file CREDITS for list of people who contributed to this 8*a47a12beSStefan Roese * project. 9*a47a12beSStefan Roese * 10*a47a12beSStefan Roese * This program is free software; you can redistribute it and/or 11*a47a12beSStefan Roese * modify it under the terms of the GNU General Public License as 12*a47a12beSStefan Roese * published by the Free Software Foundation; either version 2 of 13*a47a12beSStefan Roese * the License, or (at your option) any later version. 14*a47a12beSStefan Roese * 15*a47a12beSStefan Roese * This program is distributed in the hope that it will be useful, 16*a47a12beSStefan Roese * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*a47a12beSStefan Roese * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*a47a12beSStefan Roese * GNU General Public License for more details. 19*a47a12beSStefan Roese * 20*a47a12beSStefan Roese * You should have received a copy of the GNU General Public License 21*a47a12beSStefan Roese * along with this program; if not, write to the Free Software 22*a47a12beSStefan Roese * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 23*a47a12beSStefan Roese * MA 02111-1307 USA 24*a47a12beSStefan Roese */ 25*a47a12beSStefan Roese 26*a47a12beSStefan Roese/* 27*a47a12beSStefan Roese * U-Boot - Startup Code for MPC83xx PowerPC based Embedded Boards 28*a47a12beSStefan Roese */ 29*a47a12beSStefan Roese 30*a47a12beSStefan Roese#include <config.h> 31*a47a12beSStefan Roese#include <mpc83xx.h> 32*a47a12beSStefan Roese#include <timestamp.h> 33*a47a12beSStefan Roese#include <version.h> 34*a47a12beSStefan Roese 35*a47a12beSStefan Roese#define CONFIG_83XX 1 /* needed for Linux kernel header files*/ 36*a47a12beSStefan Roese#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */ 37*a47a12beSStefan Roese 38*a47a12beSStefan Roese#include <ppc_asm.tmpl> 39*a47a12beSStefan Roese#include <ppc_defs.h> 40*a47a12beSStefan Roese 41*a47a12beSStefan Roese#include <asm/cache.h> 42*a47a12beSStefan Roese#include <asm/mmu.h> 43*a47a12beSStefan Roese 44*a47a12beSStefan Roese#ifndef CONFIG_IDENT_STRING 45*a47a12beSStefan Roese#define CONFIG_IDENT_STRING "MPC83XX" 46*a47a12beSStefan Roese#endif 47*a47a12beSStefan Roese 48*a47a12beSStefan Roese/* We don't want the MMU yet. 49*a47a12beSStefan Roese */ 50*a47a12beSStefan Roese#undef MSR_KERNEL 51*a47a12beSStefan Roese 52*a47a12beSStefan Roese/* 53*a47a12beSStefan Roese * Floating Point enable, Machine Check and Recoverable Interr. 54*a47a12beSStefan Roese */ 55*a47a12beSStefan Roese#ifdef DEBUG 56*a47a12beSStefan Roese#define MSR_KERNEL (MSR_FP|MSR_RI) 57*a47a12beSStefan Roese#else 58*a47a12beSStefan Roese#define MSR_KERNEL (MSR_FP|MSR_ME|MSR_RI) 59*a47a12beSStefan Roese#endif 60*a47a12beSStefan Roese 61*a47a12beSStefan Roese#if !defined(CONFIG_NAND_SPL) && !defined(CONFIG_SYS_RAMBOOT) 62*a47a12beSStefan Roese#define CONFIG_SYS_FLASHBOOT 63*a47a12beSStefan Roese#endif 64*a47a12beSStefan Roese 65*a47a12beSStefan Roese/* 66*a47a12beSStefan Roese * Set up GOT: Global Offset Table 67*a47a12beSStefan Roese * 68*a47a12beSStefan Roese * Use r12 to access the GOT 69*a47a12beSStefan Roese */ 70*a47a12beSStefan Roese START_GOT 71*a47a12beSStefan Roese GOT_ENTRY(_GOT2_TABLE_) 72*a47a12beSStefan Roese GOT_ENTRY(__bss_start) 73*a47a12beSStefan Roese GOT_ENTRY(_end) 74*a47a12beSStefan Roese 75*a47a12beSStefan Roese#ifndef CONFIG_NAND_SPL 76*a47a12beSStefan Roese GOT_ENTRY(_FIXUP_TABLE_) 77*a47a12beSStefan Roese GOT_ENTRY(_start) 78*a47a12beSStefan Roese GOT_ENTRY(_start_of_vectors) 79*a47a12beSStefan Roese GOT_ENTRY(_end_of_vectors) 80*a47a12beSStefan Roese GOT_ENTRY(transfer_to_handler) 81*a47a12beSStefan Roese#endif 82*a47a12beSStefan Roese END_GOT 83*a47a12beSStefan Roese 84*a47a12beSStefan Roese/* 85*a47a12beSStefan Roese * The Hard Reset Configuration Word (HRCW) table is in the first 64 86*a47a12beSStefan Roese * (0x40) bytes of flash. It has 8 bytes, but each byte is repeated 8 87*a47a12beSStefan Roese * times so the processor can fetch it out of flash whether the flash 88*a47a12beSStefan Roese * is 8, 16, 32, or 64 bits wide (hardware trickery). 89*a47a12beSStefan Roese */ 90*a47a12beSStefan Roese .text 91*a47a12beSStefan Roese#define _HRCW_TABLE_ENTRY(w) \ 92*a47a12beSStefan Roese .fill 8,1,(((w)>>24)&0xff); \ 93*a47a12beSStefan Roese .fill 8,1,(((w)>>16)&0xff); \ 94*a47a12beSStefan Roese .fill 8,1,(((w)>> 8)&0xff); \ 95*a47a12beSStefan Roese .fill 8,1,(((w) )&0xff) 96*a47a12beSStefan Roese 97*a47a12beSStefan Roese _HRCW_TABLE_ENTRY(CONFIG_SYS_HRCW_LOW) 98*a47a12beSStefan Roese _HRCW_TABLE_ENTRY(CONFIG_SYS_HRCW_HIGH) 99*a47a12beSStefan Roese 100*a47a12beSStefan Roese/* 101*a47a12beSStefan Roese * Magic number and version string - put it after the HRCW since it 102*a47a12beSStefan Roese * cannot be first in flash like it is in many other processors. 103*a47a12beSStefan Roese */ 104*a47a12beSStefan Roese .long 0x27051956 /* U-Boot Magic Number */ 105*a47a12beSStefan Roese 106*a47a12beSStefan Roese .globl version_string 107*a47a12beSStefan Roeseversion_string: 108*a47a12beSStefan Roese .ascii U_BOOT_VERSION 109*a47a12beSStefan Roese .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")" 110*a47a12beSStefan Roese .ascii " ", CONFIG_IDENT_STRING, "\0" 111*a47a12beSStefan Roese 112*a47a12beSStefan Roese .align 2 113*a47a12beSStefan Roese 114*a47a12beSStefan Roese .globl enable_addr_trans 115*a47a12beSStefan Roeseenable_addr_trans: 116*a47a12beSStefan Roese /* enable address translation */ 117*a47a12beSStefan Roese mfmsr r5 118*a47a12beSStefan Roese ori r5, r5, (MSR_IR | MSR_DR) 119*a47a12beSStefan Roese mtmsr r5 120*a47a12beSStefan Roese isync 121*a47a12beSStefan Roese blr 122*a47a12beSStefan Roese 123*a47a12beSStefan Roese .globl disable_addr_trans 124*a47a12beSStefan Roesedisable_addr_trans: 125*a47a12beSStefan Roese /* disable address translation */ 126*a47a12beSStefan Roese mflr r4 127*a47a12beSStefan Roese mfmsr r3 128*a47a12beSStefan Roese andi. r0, r3, (MSR_IR | MSR_DR) 129*a47a12beSStefan Roese beqlr 130*a47a12beSStefan Roese andc r3, r3, r0 131*a47a12beSStefan Roese mtspr SRR0, r4 132*a47a12beSStefan Roese mtspr SRR1, r3 133*a47a12beSStefan Roese rfi 134*a47a12beSStefan Roese 135*a47a12beSStefan Roese .globl get_pvr 136*a47a12beSStefan Roeseget_pvr: 137*a47a12beSStefan Roese mfspr r3, PVR 138*a47a12beSStefan Roese blr 139*a47a12beSStefan Roese 140*a47a12beSStefan Roese .globl ppcDWstore 141*a47a12beSStefan RoeseppcDWstore: 142*a47a12beSStefan Roese lfd 1, 0(r4) 143*a47a12beSStefan Roese stfd 1, 0(r3) 144*a47a12beSStefan Roese blr 145*a47a12beSStefan Roese 146*a47a12beSStefan Roese .globl ppcDWload 147*a47a12beSStefan RoeseppcDWload: 148*a47a12beSStefan Roese lfd 1, 0(r3) 149*a47a12beSStefan Roese stfd 1, 0(r4) 150*a47a12beSStefan Roese blr 151*a47a12beSStefan Roese 152*a47a12beSStefan Roese#ifndef CONFIG_DEFAULT_IMMR 153*a47a12beSStefan Roese#error CONFIG_DEFAULT_IMMR must be defined 154*a47a12beSStefan Roese#endif /* CONFIG_SYS_DEFAULT_IMMR */ 155*a47a12beSStefan Roese#ifndef CONFIG_SYS_IMMR 156*a47a12beSStefan Roese#define CONFIG_SYS_IMMR CONFIG_DEFAULT_IMMR 157*a47a12beSStefan Roese#endif /* CONFIG_SYS_IMMR */ 158*a47a12beSStefan Roese 159*a47a12beSStefan Roese/* 160*a47a12beSStefan Roese * After configuration, a system reset exception is executed using the 161*a47a12beSStefan Roese * vector at offset 0x100 relative to the base set by MSR[IP]. If 162*a47a12beSStefan Roese * MSR[IP] is 0, the base address is 0x00000000. If MSR[IP] is 1, the 163*a47a12beSStefan Roese * base address is 0xfff00000. In the case of a Power On Reset or Hard 164*a47a12beSStefan Roese * Reset, the value of MSR[IP] is determined by the CIP field in the 165*a47a12beSStefan Roese * HRCW. 166*a47a12beSStefan Roese * 167*a47a12beSStefan Roese * Other bits in the HRCW set up the Base Address and Port Size in BR0. 168*a47a12beSStefan Roese * This determines the location of the boot ROM (flash or EPROM) in the 169*a47a12beSStefan Roese * processor's address space at boot time. As long as the HRCW is set up 170*a47a12beSStefan Roese * so that we eventually end up executing the code below when the 171*a47a12beSStefan Roese * processor executes the reset exception, the actual values used should 172*a47a12beSStefan Roese * not matter. 173*a47a12beSStefan Roese * 174*a47a12beSStefan Roese * Once we have got here, the address mask in OR0 is cleared so that the 175*a47a12beSStefan Roese * bottom 32K of the boot ROM is effectively repeated all throughout the 176*a47a12beSStefan Roese * processor's address space, after which we can jump to the absolute 177*a47a12beSStefan Roese * address at which the boot ROM was linked at compile time, and proceed 178*a47a12beSStefan Roese * to initialise the memory controller without worrying if the rug will 179*a47a12beSStefan Roese * be pulled out from under us, so to speak (it will be fine as long as 180*a47a12beSStefan Roese * we configure BR0 with the same boot ROM link address). 181*a47a12beSStefan Roese */ 182*a47a12beSStefan Roese . = EXC_OFF_SYS_RESET 183*a47a12beSStefan Roese 184*a47a12beSStefan Roese .globl _start 185*a47a12beSStefan Roese_start: /* time t 0 */ 186*a47a12beSStefan Roese li r21, BOOTFLAG_COLD /* Normal Power-On: Boot from FLASH*/ 187*a47a12beSStefan Roese nop 188*a47a12beSStefan Roese b boot_cold 189*a47a12beSStefan Roese 190*a47a12beSStefan Roese . = EXC_OFF_SYS_RESET + 0x10 191*a47a12beSStefan Roese 192*a47a12beSStefan Roese .globl _start_warm 193*a47a12beSStefan Roese_start_warm: 194*a47a12beSStefan Roese li r21, BOOTFLAG_WARM /* Software reboot */ 195*a47a12beSStefan Roese b boot_warm 196*a47a12beSStefan Roese 197*a47a12beSStefan Roese 198*a47a12beSStefan Roeseboot_cold: /* time t 3 */ 199*a47a12beSStefan Roese lis r4, CONFIG_DEFAULT_IMMR@h 200*a47a12beSStefan Roese nop 201*a47a12beSStefan Roeseboot_warm: /* time t 5 */ 202*a47a12beSStefan Roese mfmsr r5 /* save msr contents */ 203*a47a12beSStefan Roese 204*a47a12beSStefan Roese /* 83xx manuals prescribe a specific sequence for updating IMMRBAR. */ 205*a47a12beSStefan Roese bl 1f 206*a47a12beSStefan Roese1: mflr r7 207*a47a12beSStefan Roese 208*a47a12beSStefan Roese lis r3, CONFIG_SYS_IMMR@h 209*a47a12beSStefan Roese ori r3, r3, CONFIG_SYS_IMMR@l 210*a47a12beSStefan Roese 211*a47a12beSStefan Roese lwz r6, IMMRBAR(r4) 212*a47a12beSStefan Roese isync 213*a47a12beSStefan Roese 214*a47a12beSStefan Roese stw r3, IMMRBAR(r4) 215*a47a12beSStefan Roese lwz r6, 0(r7) /* Arbitrary external load */ 216*a47a12beSStefan Roese isync 217*a47a12beSStefan Roese 218*a47a12beSStefan Roese lwz r6, IMMRBAR(r3) 219*a47a12beSStefan Roese isync 220*a47a12beSStefan Roese 221*a47a12beSStefan Roese /* Initialise the E300 processor core */ 222*a47a12beSStefan Roese /*------------------------------------------*/ 223*a47a12beSStefan Roese 224*a47a12beSStefan Roese#ifdef CONFIG_NAND_SPL 225*a47a12beSStefan Roese /* The FCM begins execution after only the first page 226*a47a12beSStefan Roese * is loaded. Wait for the rest before branching 227*a47a12beSStefan Roese * to another flash page. 228*a47a12beSStefan Roese */ 229*a47a12beSStefan Roese1: lwz r6, 0x50b0(r3) 230*a47a12beSStefan Roese andi. r6, r6, 1 231*a47a12beSStefan Roese beq 1b 232*a47a12beSStefan Roese#endif 233*a47a12beSStefan Roese 234*a47a12beSStefan Roese bl init_e300_core 235*a47a12beSStefan Roese 236*a47a12beSStefan Roese#ifdef CONFIG_SYS_FLASHBOOT 237*a47a12beSStefan Roese 238*a47a12beSStefan Roese /* Inflate flash location so it appears everywhere, calculate */ 239*a47a12beSStefan Roese /* the absolute address in final location of the FLASH, jump */ 240*a47a12beSStefan Roese /* there and deflate the flash size back to minimal size */ 241*a47a12beSStefan Roese /*------------------------------------------------------------*/ 242*a47a12beSStefan Roese bl map_flash_by_law1 243*a47a12beSStefan Roese lis r4, (CONFIG_SYS_MONITOR_BASE)@h 244*a47a12beSStefan Roese ori r4, r4, (CONFIG_SYS_MONITOR_BASE)@l 245*a47a12beSStefan Roese addi r5, r4, in_flash - _start + EXC_OFF_SYS_RESET 246*a47a12beSStefan Roese mtlr r5 247*a47a12beSStefan Roese blr 248*a47a12beSStefan Roesein_flash: 249*a47a12beSStefan Roese#if 1 /* Remapping flash with LAW0. */ 250*a47a12beSStefan Roese bl remap_flash_by_law0 251*a47a12beSStefan Roese#endif 252*a47a12beSStefan Roese#endif /* CONFIG_SYS_FLASHBOOT */ 253*a47a12beSStefan Roese 254*a47a12beSStefan Roese /* setup the bats */ 255*a47a12beSStefan Roese bl setup_bats 256*a47a12beSStefan Roese sync 257*a47a12beSStefan Roese 258*a47a12beSStefan Roese /* 259*a47a12beSStefan Roese * Cache must be enabled here for stack-in-cache trick. 260*a47a12beSStefan Roese * This means we need to enable the BATS. 261*a47a12beSStefan Roese * This means: 262*a47a12beSStefan Roese * 1) for the EVB, original gt regs need to be mapped 263*a47a12beSStefan Roese * 2) need to have an IBAT for the 0xf region, 264*a47a12beSStefan Roese * we are running there! 265*a47a12beSStefan Roese * Cache should be turned on after BATs, since by default 266*a47a12beSStefan Roese * everything is write-through. 267*a47a12beSStefan Roese * The init-mem BAT can be reused after reloc. The old 268*a47a12beSStefan Roese * gt-regs BAT can be reused after board_init_f calls 269*a47a12beSStefan Roese * board_early_init_f (EVB only). 270*a47a12beSStefan Roese */ 271*a47a12beSStefan Roese /* enable address translation */ 272*a47a12beSStefan Roese bl enable_addr_trans 273*a47a12beSStefan Roese sync 274*a47a12beSStefan Roese 275*a47a12beSStefan Roese /* enable the data cache */ 276*a47a12beSStefan Roese bl dcache_enable 277*a47a12beSStefan Roese sync 278*a47a12beSStefan Roese#ifdef CONFIG_SYS_INIT_RAM_LOCK 279*a47a12beSStefan Roese bl lock_ram_in_cache 280*a47a12beSStefan Roese sync 281*a47a12beSStefan Roese#endif 282*a47a12beSStefan Roese 283*a47a12beSStefan Roese /* set up the stack pointer in our newly created 284*a47a12beSStefan Roese * cache-ram (r1) */ 285*a47a12beSStefan Roese lis r1, (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET)@h 286*a47a12beSStefan Roese ori r1, r1, (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET)@l 287*a47a12beSStefan Roese 288*a47a12beSStefan Roese li r0, 0 /* Make room for stack frame header and */ 289*a47a12beSStefan Roese stwu r0, -4(r1) /* clear final stack frame so that */ 290*a47a12beSStefan Roese stwu r0, -4(r1) /* stack backtraces terminate cleanly */ 291*a47a12beSStefan Roese 292*a47a12beSStefan Roese 293*a47a12beSStefan Roese /* let the C-code set up the rest */ 294*a47a12beSStefan Roese /* */ 295*a47a12beSStefan Roese /* Be careful to keep code relocatable & stack humble */ 296*a47a12beSStefan Roese /*------------------------------------------------------*/ 297*a47a12beSStefan Roese 298*a47a12beSStefan Roese GET_GOT /* initialize GOT access */ 299*a47a12beSStefan Roese 300*a47a12beSStefan Roese /* r3: IMMR */ 301*a47a12beSStefan Roese lis r3, CONFIG_SYS_IMMR@h 302*a47a12beSStefan Roese /* run low-level CPU init code (in Flash)*/ 303*a47a12beSStefan Roese bl cpu_init_f 304*a47a12beSStefan Roese 305*a47a12beSStefan Roese /* r3: BOOTFLAG */ 306*a47a12beSStefan Roese mr r3, r21 307*a47a12beSStefan Roese /* run 1st part of board init code (in Flash)*/ 308*a47a12beSStefan Roese bl board_init_f 309*a47a12beSStefan Roese 310*a47a12beSStefan Roese#ifndef CONFIG_NAND_SPL 311*a47a12beSStefan Roese/* 312*a47a12beSStefan Roese * Vector Table 313*a47a12beSStefan Roese */ 314*a47a12beSStefan Roese 315*a47a12beSStefan Roese .globl _start_of_vectors 316*a47a12beSStefan Roese_start_of_vectors: 317*a47a12beSStefan Roese 318*a47a12beSStefan Roese/* Machine check */ 319*a47a12beSStefan Roese STD_EXCEPTION(0x200, MachineCheck, MachineCheckException) 320*a47a12beSStefan Roese 321*a47a12beSStefan Roese/* Data Storage exception. */ 322*a47a12beSStefan Roese STD_EXCEPTION(0x300, DataStorage, UnknownException) 323*a47a12beSStefan Roese 324*a47a12beSStefan Roese/* Instruction Storage exception. */ 325*a47a12beSStefan Roese STD_EXCEPTION(0x400, InstStorage, UnknownException) 326*a47a12beSStefan Roese 327*a47a12beSStefan Roese/* External Interrupt exception. */ 328*a47a12beSStefan Roese#ifndef FIXME 329*a47a12beSStefan Roese STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt) 330*a47a12beSStefan Roese#endif 331*a47a12beSStefan Roese 332*a47a12beSStefan Roese/* Alignment exception. */ 333*a47a12beSStefan Roese . = 0x600 334*a47a12beSStefan RoeseAlignment: 335*a47a12beSStefan Roese EXCEPTION_PROLOG(SRR0, SRR1) 336*a47a12beSStefan Roese mfspr r4,DAR 337*a47a12beSStefan Roese stw r4,_DAR(r21) 338*a47a12beSStefan Roese mfspr r5,DSISR 339*a47a12beSStefan Roese stw r5,_DSISR(r21) 340*a47a12beSStefan Roese addi r3,r1,STACK_FRAME_OVERHEAD 341*a47a12beSStefan Roese EXC_XFER_TEMPLATE(Alignment, AlignmentException, MSR_KERNEL, COPY_EE) 342*a47a12beSStefan Roese 343*a47a12beSStefan Roese/* Program check exception */ 344*a47a12beSStefan Roese . = 0x700 345*a47a12beSStefan RoeseProgramCheck: 346*a47a12beSStefan Roese EXCEPTION_PROLOG(SRR0, SRR1) 347*a47a12beSStefan Roese addi r3,r1,STACK_FRAME_OVERHEAD 348*a47a12beSStefan Roese EXC_XFER_TEMPLATE(ProgramCheck, ProgramCheckException, 349*a47a12beSStefan Roese MSR_KERNEL, COPY_EE) 350*a47a12beSStefan Roese 351*a47a12beSStefan Roese STD_EXCEPTION(0x800, FPUnavailable, UnknownException) 352*a47a12beSStefan Roese 353*a47a12beSStefan Roese /* I guess we could implement decrementer, and may have 354*a47a12beSStefan Roese * to someday for timekeeping. 355*a47a12beSStefan Roese */ 356*a47a12beSStefan Roese STD_EXCEPTION(0x900, Decrementer, timer_interrupt) 357*a47a12beSStefan Roese 358*a47a12beSStefan Roese STD_EXCEPTION(0xa00, Trap_0a, UnknownException) 359*a47a12beSStefan Roese STD_EXCEPTION(0xb00, Trap_0b, UnknownException) 360*a47a12beSStefan Roese STD_EXCEPTION(0xc00, SystemCall, UnknownException) 361*a47a12beSStefan Roese STD_EXCEPTION(0xd00, SingleStep, UnknownException) 362*a47a12beSStefan Roese 363*a47a12beSStefan Roese STD_EXCEPTION(0xe00, Trap_0e, UnknownException) 364*a47a12beSStefan Roese STD_EXCEPTION(0xf00, Trap_0f, UnknownException) 365*a47a12beSStefan Roese 366*a47a12beSStefan Roese STD_EXCEPTION(0x1000, InstructionTLBMiss, UnknownException) 367*a47a12beSStefan Roese STD_EXCEPTION(0x1100, DataLoadTLBMiss, UnknownException) 368*a47a12beSStefan Roese STD_EXCEPTION(0x1200, DataStoreTLBMiss, UnknownException) 369*a47a12beSStefan Roese#ifdef DEBUG 370*a47a12beSStefan Roese . = 0x1300 371*a47a12beSStefan Roese /* 372*a47a12beSStefan Roese * This exception occurs when the program counter matches the 373*a47a12beSStefan Roese * Instruction Address Breakpoint Register (IABR). 374*a47a12beSStefan Roese * 375*a47a12beSStefan Roese * I want the cpu to halt if this occurs so I can hunt around 376*a47a12beSStefan Roese * with the debugger and look at things. 377*a47a12beSStefan Roese * 378*a47a12beSStefan Roese * When DEBUG is defined, both machine check enable (in the MSR) 379*a47a12beSStefan Roese * and checkstop reset enable (in the reset mode register) are 380*a47a12beSStefan Roese * turned off and so a checkstop condition will result in the cpu 381*a47a12beSStefan Roese * halting. 382*a47a12beSStefan Roese * 383*a47a12beSStefan Roese * I force the cpu into a checkstop condition by putting an illegal 384*a47a12beSStefan Roese * instruction here (at least this is the theory). 385*a47a12beSStefan Roese * 386*a47a12beSStefan Roese * well - that didnt work, so just do an infinite loop! 387*a47a12beSStefan Roese */ 388*a47a12beSStefan Roese1: b 1b 389*a47a12beSStefan Roese#else 390*a47a12beSStefan Roese STD_EXCEPTION(0x1300, InstructionBreakpoint, DebugException) 391*a47a12beSStefan Roese#endif 392*a47a12beSStefan Roese STD_EXCEPTION(0x1400, SMI, UnknownException) 393*a47a12beSStefan Roese 394*a47a12beSStefan Roese STD_EXCEPTION(0x1500, Trap_15, UnknownException) 395*a47a12beSStefan Roese STD_EXCEPTION(0x1600, Trap_16, UnknownException) 396*a47a12beSStefan Roese STD_EXCEPTION(0x1700, Trap_17, UnknownException) 397*a47a12beSStefan Roese STD_EXCEPTION(0x1800, Trap_18, UnknownException) 398*a47a12beSStefan Roese STD_EXCEPTION(0x1900, Trap_19, UnknownException) 399*a47a12beSStefan Roese STD_EXCEPTION(0x1a00, Trap_1a, UnknownException) 400*a47a12beSStefan Roese STD_EXCEPTION(0x1b00, Trap_1b, UnknownException) 401*a47a12beSStefan Roese STD_EXCEPTION(0x1c00, Trap_1c, UnknownException) 402*a47a12beSStefan Roese STD_EXCEPTION(0x1d00, Trap_1d, UnknownException) 403*a47a12beSStefan Roese STD_EXCEPTION(0x1e00, Trap_1e, UnknownException) 404*a47a12beSStefan Roese STD_EXCEPTION(0x1f00, Trap_1f, UnknownException) 405*a47a12beSStefan Roese STD_EXCEPTION(0x2000, Trap_20, UnknownException) 406*a47a12beSStefan Roese STD_EXCEPTION(0x2100, Trap_21, UnknownException) 407*a47a12beSStefan Roese STD_EXCEPTION(0x2200, Trap_22, UnknownException) 408*a47a12beSStefan Roese STD_EXCEPTION(0x2300, Trap_23, UnknownException) 409*a47a12beSStefan Roese STD_EXCEPTION(0x2400, Trap_24, UnknownException) 410*a47a12beSStefan Roese STD_EXCEPTION(0x2500, Trap_25, UnknownException) 411*a47a12beSStefan Roese STD_EXCEPTION(0x2600, Trap_26, UnknownException) 412*a47a12beSStefan Roese STD_EXCEPTION(0x2700, Trap_27, UnknownException) 413*a47a12beSStefan Roese STD_EXCEPTION(0x2800, Trap_28, UnknownException) 414*a47a12beSStefan Roese STD_EXCEPTION(0x2900, Trap_29, UnknownException) 415*a47a12beSStefan Roese STD_EXCEPTION(0x2a00, Trap_2a, UnknownException) 416*a47a12beSStefan Roese STD_EXCEPTION(0x2b00, Trap_2b, UnknownException) 417*a47a12beSStefan Roese STD_EXCEPTION(0x2c00, Trap_2c, UnknownException) 418*a47a12beSStefan Roese STD_EXCEPTION(0x2d00, Trap_2d, UnknownException) 419*a47a12beSStefan Roese STD_EXCEPTION(0x2e00, Trap_2e, UnknownException) 420*a47a12beSStefan Roese STD_EXCEPTION(0x2f00, Trap_2f, UnknownException) 421*a47a12beSStefan Roese 422*a47a12beSStefan Roese 423*a47a12beSStefan Roese .globl _end_of_vectors 424*a47a12beSStefan Roese_end_of_vectors: 425*a47a12beSStefan Roese 426*a47a12beSStefan Roese . = 0x3000 427*a47a12beSStefan Roese 428*a47a12beSStefan Roese/* 429*a47a12beSStefan Roese * This code finishes saving the registers to the exception frame 430*a47a12beSStefan Roese * and jumps to the appropriate handler for the exception. 431*a47a12beSStefan Roese * Register r21 is pointer into trap frame, r1 has new stack pointer. 432*a47a12beSStefan Roese */ 433*a47a12beSStefan Roese .globl transfer_to_handler 434*a47a12beSStefan Roesetransfer_to_handler: 435*a47a12beSStefan Roese stw r22,_NIP(r21) 436*a47a12beSStefan Roese lis r22,MSR_POW@h 437*a47a12beSStefan Roese andc r23,r23,r22 438*a47a12beSStefan Roese stw r23,_MSR(r21) 439*a47a12beSStefan Roese SAVE_GPR(7, r21) 440*a47a12beSStefan Roese SAVE_4GPRS(8, r21) 441*a47a12beSStefan Roese SAVE_8GPRS(12, r21) 442*a47a12beSStefan Roese SAVE_8GPRS(24, r21) 443*a47a12beSStefan Roese mflr r23 444*a47a12beSStefan Roese andi. r24,r23,0x3f00 /* get vector offset */ 445*a47a12beSStefan Roese stw r24,TRAP(r21) 446*a47a12beSStefan Roese li r22,0 447*a47a12beSStefan Roese stw r22,RESULT(r21) 448*a47a12beSStefan Roese lwz r24,0(r23) /* virtual address of handler */ 449*a47a12beSStefan Roese lwz r23,4(r23) /* where to go when done */ 450*a47a12beSStefan Roese mtspr SRR0,r24 451*a47a12beSStefan Roese mtspr SRR1,r20 452*a47a12beSStefan Roese mtlr r23 453*a47a12beSStefan Roese SYNC 454*a47a12beSStefan Roese rfi /* jump to handler, enable MMU */ 455*a47a12beSStefan Roese 456*a47a12beSStefan Roeseint_return: 457*a47a12beSStefan Roese mfmsr r28 /* Disable interrupts */ 458*a47a12beSStefan Roese li r4,0 459*a47a12beSStefan Roese ori r4,r4,MSR_EE 460*a47a12beSStefan Roese andc r28,r28,r4 461*a47a12beSStefan Roese SYNC /* Some chip revs need this... */ 462*a47a12beSStefan Roese mtmsr r28 463*a47a12beSStefan Roese SYNC 464*a47a12beSStefan Roese lwz r2,_CTR(r1) 465*a47a12beSStefan Roese lwz r0,_LINK(r1) 466*a47a12beSStefan Roese mtctr r2 467*a47a12beSStefan Roese mtlr r0 468*a47a12beSStefan Roese lwz r2,_XER(r1) 469*a47a12beSStefan Roese lwz r0,_CCR(r1) 470*a47a12beSStefan Roese mtspr XER,r2 471*a47a12beSStefan Roese mtcrf 0xFF,r0 472*a47a12beSStefan Roese REST_10GPRS(3, r1) 473*a47a12beSStefan Roese REST_10GPRS(13, r1) 474*a47a12beSStefan Roese REST_8GPRS(23, r1) 475*a47a12beSStefan Roese REST_GPR(31, r1) 476*a47a12beSStefan Roese lwz r2,_NIP(r1) /* Restore environment */ 477*a47a12beSStefan Roese lwz r0,_MSR(r1) 478*a47a12beSStefan Roese mtspr SRR0,r2 479*a47a12beSStefan Roese mtspr SRR1,r0 480*a47a12beSStefan Roese lwz r0,GPR0(r1) 481*a47a12beSStefan Roese lwz r2,GPR2(r1) 482*a47a12beSStefan Roese lwz r1,GPR1(r1) 483*a47a12beSStefan Roese SYNC 484*a47a12beSStefan Roese rfi 485*a47a12beSStefan Roese#endif /* !CONFIG_NAND_SPL */ 486*a47a12beSStefan Roese 487*a47a12beSStefan Roese/* 488*a47a12beSStefan Roese * This code initialises the E300 processor core 489*a47a12beSStefan Roese * (conforms to PowerPC 603e spec) 490*a47a12beSStefan Roese * Note: expects original MSR contents to be in r5. 491*a47a12beSStefan Roese */ 492*a47a12beSStefan Roese .globl init_e300_core 493*a47a12beSStefan Roeseinit_e300_core: /* time t 10 */ 494*a47a12beSStefan Roese /* Initialize machine status; enable machine check interrupt */ 495*a47a12beSStefan Roese /*-----------------------------------------------------------*/ 496*a47a12beSStefan Roese 497*a47a12beSStefan Roese li r3, MSR_KERNEL /* Set ME and RI flags */ 498*a47a12beSStefan Roese rlwimi r3, r5, 0, 25, 25 /* preserve IP bit set by HRCW */ 499*a47a12beSStefan Roese#ifdef DEBUG 500*a47a12beSStefan Roese rlwimi r3, r5, 0, 21, 22 /* debugger might set SE & BE bits */ 501*a47a12beSStefan Roese#endif 502*a47a12beSStefan Roese SYNC /* Some chip revs need this... */ 503*a47a12beSStefan Roese mtmsr r3 504*a47a12beSStefan Roese SYNC 505*a47a12beSStefan Roese mtspr SRR1, r3 /* Make SRR1 match MSR */ 506*a47a12beSStefan Roese 507*a47a12beSStefan Roese 508*a47a12beSStefan Roese lis r3, CONFIG_SYS_IMMR@h 509*a47a12beSStefan Roese#if defined(CONFIG_WATCHDOG) 510*a47a12beSStefan Roese /* Initialise the Wathcdog values and reset it (if req) */ 511*a47a12beSStefan Roese /*------------------------------------------------------*/ 512*a47a12beSStefan Roese lis r4, CONFIG_SYS_WATCHDOG_VALUE 513*a47a12beSStefan Roese ori r4, r4, (SWCRR_SWEN | SWCRR_SWRI | SWCRR_SWPR) 514*a47a12beSStefan Roese stw r4, SWCRR(r3) 515*a47a12beSStefan Roese 516*a47a12beSStefan Roese /* and reset it */ 517*a47a12beSStefan Roese 518*a47a12beSStefan Roese li r4, 0x556C 519*a47a12beSStefan Roese sth r4, SWSRR@l(r3) 520*a47a12beSStefan Roese li r4, -0x55C7 521*a47a12beSStefan Roese sth r4, SWSRR@l(r3) 522*a47a12beSStefan Roese#else 523*a47a12beSStefan Roese /* Disable Wathcdog */ 524*a47a12beSStefan Roese /*-------------------*/ 525*a47a12beSStefan Roese lwz r4, SWCRR(r3) 526*a47a12beSStefan Roese /* Check to see if its enabled for disabling 527*a47a12beSStefan Roese once disabled by SW you can't re-enable */ 528*a47a12beSStefan Roese andi. r4, r4, 0x4 529*a47a12beSStefan Roese beq 1f 530*a47a12beSStefan Roese xor r4, r4, r4 531*a47a12beSStefan Roese stw r4, SWCRR(r3) 532*a47a12beSStefan Roese1: 533*a47a12beSStefan Roese#endif /* CONFIG_WATCHDOG */ 534*a47a12beSStefan Roese 535*a47a12beSStefan Roese#if defined(CONFIG_MASK_AER_AO) 536*a47a12beSStefan Roese /* Write the Arbiter Event Enable to mask Address Only traps. */ 537*a47a12beSStefan Roese /* This prevents the dcbz instruction from being trapped when */ 538*a47a12beSStefan Roese /* HID0_ABE Address Broadcast Enable is set and the MEMORY */ 539*a47a12beSStefan Roese /* COHERENCY bit is set in the WIMG bits, which is often */ 540*a47a12beSStefan Roese /* needed for PCI operation. */ 541*a47a12beSStefan Roese lwz r4, 0x0808(r3) 542*a47a12beSStefan Roese rlwinm r0, r4, 0, ~AER_AO 543*a47a12beSStefan Roese stw r0, 0x0808(r3) 544*a47a12beSStefan Roese#endif /* CONFIG_MASK_AER_AO */ 545*a47a12beSStefan Roese 546*a47a12beSStefan Roese /* Initialize the Hardware Implementation-dependent Registers */ 547*a47a12beSStefan Roese /* HID0 also contains cache control */ 548*a47a12beSStefan Roese /* - force invalidation of data and instruction caches */ 549*a47a12beSStefan Roese /*------------------------------------------------------*/ 550*a47a12beSStefan Roese 551*a47a12beSStefan Roese lis r3, CONFIG_SYS_HID0_INIT@h 552*a47a12beSStefan Roese ori r3, r3, (CONFIG_SYS_HID0_INIT | HID0_ICFI | HID0_DCFI)@l 553*a47a12beSStefan Roese SYNC 554*a47a12beSStefan Roese mtspr HID0, r3 555*a47a12beSStefan Roese 556*a47a12beSStefan Roese lis r3, CONFIG_SYS_HID0_FINAL@h 557*a47a12beSStefan Roese ori r3, r3, (CONFIG_SYS_HID0_FINAL & ~(HID0_ICFI | HID0_DCFI))@l 558*a47a12beSStefan Roese SYNC 559*a47a12beSStefan Roese mtspr HID0, r3 560*a47a12beSStefan Roese 561*a47a12beSStefan Roese lis r3, CONFIG_SYS_HID2@h 562*a47a12beSStefan Roese ori r3, r3, CONFIG_SYS_HID2@l 563*a47a12beSStefan Roese SYNC 564*a47a12beSStefan Roese mtspr HID2, r3 565*a47a12beSStefan Roese 566*a47a12beSStefan Roese /* Done! */ 567*a47a12beSStefan Roese /*------------------------------*/ 568*a47a12beSStefan Roese blr 569*a47a12beSStefan Roese 570*a47a12beSStefan Roese /* setup_bats - set them up to some initial state */ 571*a47a12beSStefan Roese .globl setup_bats 572*a47a12beSStefan Roesesetup_bats: 573*a47a12beSStefan Roese addis r0, r0, 0x0000 574*a47a12beSStefan Roese 575*a47a12beSStefan Roese /* IBAT 0 */ 576*a47a12beSStefan Roese addis r4, r0, CONFIG_SYS_IBAT0L@h 577*a47a12beSStefan Roese ori r4, r4, CONFIG_SYS_IBAT0L@l 578*a47a12beSStefan Roese addis r3, r0, CONFIG_SYS_IBAT0U@h 579*a47a12beSStefan Roese ori r3, r3, CONFIG_SYS_IBAT0U@l 580*a47a12beSStefan Roese mtspr IBAT0L, r4 581*a47a12beSStefan Roese mtspr IBAT0U, r3 582*a47a12beSStefan Roese 583*a47a12beSStefan Roese /* DBAT 0 */ 584*a47a12beSStefan Roese addis r4, r0, CONFIG_SYS_DBAT0L@h 585*a47a12beSStefan Roese ori r4, r4, CONFIG_SYS_DBAT0L@l 586*a47a12beSStefan Roese addis r3, r0, CONFIG_SYS_DBAT0U@h 587*a47a12beSStefan Roese ori r3, r3, CONFIG_SYS_DBAT0U@l 588*a47a12beSStefan Roese mtspr DBAT0L, r4 589*a47a12beSStefan Roese mtspr DBAT0U, r3 590*a47a12beSStefan Roese 591*a47a12beSStefan Roese /* IBAT 1 */ 592*a47a12beSStefan Roese addis r4, r0, CONFIG_SYS_IBAT1L@h 593*a47a12beSStefan Roese ori r4, r4, CONFIG_SYS_IBAT1L@l 594*a47a12beSStefan Roese addis r3, r0, CONFIG_SYS_IBAT1U@h 595*a47a12beSStefan Roese ori r3, r3, CONFIG_SYS_IBAT1U@l 596*a47a12beSStefan Roese mtspr IBAT1L, r4 597*a47a12beSStefan Roese mtspr IBAT1U, r3 598*a47a12beSStefan Roese 599*a47a12beSStefan Roese /* DBAT 1 */ 600*a47a12beSStefan Roese addis r4, r0, CONFIG_SYS_DBAT1L@h 601*a47a12beSStefan Roese ori r4, r4, CONFIG_SYS_DBAT1L@l 602*a47a12beSStefan Roese addis r3, r0, CONFIG_SYS_DBAT1U@h 603*a47a12beSStefan Roese ori r3, r3, CONFIG_SYS_DBAT1U@l 604*a47a12beSStefan Roese mtspr DBAT1L, r4 605*a47a12beSStefan Roese mtspr DBAT1U, r3 606*a47a12beSStefan Roese 607*a47a12beSStefan Roese /* IBAT 2 */ 608*a47a12beSStefan Roese addis r4, r0, CONFIG_SYS_IBAT2L@h 609*a47a12beSStefan Roese ori r4, r4, CONFIG_SYS_IBAT2L@l 610*a47a12beSStefan Roese addis r3, r0, CONFIG_SYS_IBAT2U@h 611*a47a12beSStefan Roese ori r3, r3, CONFIG_SYS_IBAT2U@l 612*a47a12beSStefan Roese mtspr IBAT2L, r4 613*a47a12beSStefan Roese mtspr IBAT2U, r3 614*a47a12beSStefan Roese 615*a47a12beSStefan Roese /* DBAT 2 */ 616*a47a12beSStefan Roese addis r4, r0, CONFIG_SYS_DBAT2L@h 617*a47a12beSStefan Roese ori r4, r4, CONFIG_SYS_DBAT2L@l 618*a47a12beSStefan Roese addis r3, r0, CONFIG_SYS_DBAT2U@h 619*a47a12beSStefan Roese ori r3, r3, CONFIG_SYS_DBAT2U@l 620*a47a12beSStefan Roese mtspr DBAT2L, r4 621*a47a12beSStefan Roese mtspr DBAT2U, r3 622*a47a12beSStefan Roese 623*a47a12beSStefan Roese /* IBAT 3 */ 624*a47a12beSStefan Roese addis r4, r0, CONFIG_SYS_IBAT3L@h 625*a47a12beSStefan Roese ori r4, r4, CONFIG_SYS_IBAT3L@l 626*a47a12beSStefan Roese addis r3, r0, CONFIG_SYS_IBAT3U@h 627*a47a12beSStefan Roese ori r3, r3, CONFIG_SYS_IBAT3U@l 628*a47a12beSStefan Roese mtspr IBAT3L, r4 629*a47a12beSStefan Roese mtspr IBAT3U, r3 630*a47a12beSStefan Roese 631*a47a12beSStefan Roese /* DBAT 3 */ 632*a47a12beSStefan Roese addis r4, r0, CONFIG_SYS_DBAT3L@h 633*a47a12beSStefan Roese ori r4, r4, CONFIG_SYS_DBAT3L@l 634*a47a12beSStefan Roese addis r3, r0, CONFIG_SYS_DBAT3U@h 635*a47a12beSStefan Roese ori r3, r3, CONFIG_SYS_DBAT3U@l 636*a47a12beSStefan Roese mtspr DBAT3L, r4 637*a47a12beSStefan Roese mtspr DBAT3U, r3 638*a47a12beSStefan Roese 639*a47a12beSStefan Roese#ifdef CONFIG_HIGH_BATS 640*a47a12beSStefan Roese /* IBAT 4 */ 641*a47a12beSStefan Roese addis r4, r0, CONFIG_SYS_IBAT4L@h 642*a47a12beSStefan Roese ori r4, r4, CONFIG_SYS_IBAT4L@l 643*a47a12beSStefan Roese addis r3, r0, CONFIG_SYS_IBAT4U@h 644*a47a12beSStefan Roese ori r3, r3, CONFIG_SYS_IBAT4U@l 645*a47a12beSStefan Roese mtspr IBAT4L, r4 646*a47a12beSStefan Roese mtspr IBAT4U, r3 647*a47a12beSStefan Roese 648*a47a12beSStefan Roese /* DBAT 4 */ 649*a47a12beSStefan Roese addis r4, r0, CONFIG_SYS_DBAT4L@h 650*a47a12beSStefan Roese ori r4, r4, CONFIG_SYS_DBAT4L@l 651*a47a12beSStefan Roese addis r3, r0, CONFIG_SYS_DBAT4U@h 652*a47a12beSStefan Roese ori r3, r3, CONFIG_SYS_DBAT4U@l 653*a47a12beSStefan Roese mtspr DBAT4L, r4 654*a47a12beSStefan Roese mtspr DBAT4U, r3 655*a47a12beSStefan Roese 656*a47a12beSStefan Roese /* IBAT 5 */ 657*a47a12beSStefan Roese addis r4, r0, CONFIG_SYS_IBAT5L@h 658*a47a12beSStefan Roese ori r4, r4, CONFIG_SYS_IBAT5L@l 659*a47a12beSStefan Roese addis r3, r0, CONFIG_SYS_IBAT5U@h 660*a47a12beSStefan Roese ori r3, r3, CONFIG_SYS_IBAT5U@l 661*a47a12beSStefan Roese mtspr IBAT5L, r4 662*a47a12beSStefan Roese mtspr IBAT5U, r3 663*a47a12beSStefan Roese 664*a47a12beSStefan Roese /* DBAT 5 */ 665*a47a12beSStefan Roese addis r4, r0, CONFIG_SYS_DBAT5L@h 666*a47a12beSStefan Roese ori r4, r4, CONFIG_SYS_DBAT5L@l 667*a47a12beSStefan Roese addis r3, r0, CONFIG_SYS_DBAT5U@h 668*a47a12beSStefan Roese ori r3, r3, CONFIG_SYS_DBAT5U@l 669*a47a12beSStefan Roese mtspr DBAT5L, r4 670*a47a12beSStefan Roese mtspr DBAT5U, r3 671*a47a12beSStefan Roese 672*a47a12beSStefan Roese /* IBAT 6 */ 673*a47a12beSStefan Roese addis r4, r0, CONFIG_SYS_IBAT6L@h 674*a47a12beSStefan Roese ori r4, r4, CONFIG_SYS_IBAT6L@l 675*a47a12beSStefan Roese addis r3, r0, CONFIG_SYS_IBAT6U@h 676*a47a12beSStefan Roese ori r3, r3, CONFIG_SYS_IBAT6U@l 677*a47a12beSStefan Roese mtspr IBAT6L, r4 678*a47a12beSStefan Roese mtspr IBAT6U, r3 679*a47a12beSStefan Roese 680*a47a12beSStefan Roese /* DBAT 6 */ 681*a47a12beSStefan Roese addis r4, r0, CONFIG_SYS_DBAT6L@h 682*a47a12beSStefan Roese ori r4, r4, CONFIG_SYS_DBAT6L@l 683*a47a12beSStefan Roese addis r3, r0, CONFIG_SYS_DBAT6U@h 684*a47a12beSStefan Roese ori r3, r3, CONFIG_SYS_DBAT6U@l 685*a47a12beSStefan Roese mtspr DBAT6L, r4 686*a47a12beSStefan Roese mtspr DBAT6U, r3 687*a47a12beSStefan Roese 688*a47a12beSStefan Roese /* IBAT 7 */ 689*a47a12beSStefan Roese addis r4, r0, CONFIG_SYS_IBAT7L@h 690*a47a12beSStefan Roese ori r4, r4, CONFIG_SYS_IBAT7L@l 691*a47a12beSStefan Roese addis r3, r0, CONFIG_SYS_IBAT7U@h 692*a47a12beSStefan Roese ori r3, r3, CONFIG_SYS_IBAT7U@l 693*a47a12beSStefan Roese mtspr IBAT7L, r4 694*a47a12beSStefan Roese mtspr IBAT7U, r3 695*a47a12beSStefan Roese 696*a47a12beSStefan Roese /* DBAT 7 */ 697*a47a12beSStefan Roese addis r4, r0, CONFIG_SYS_DBAT7L@h 698*a47a12beSStefan Roese ori r4, r4, CONFIG_SYS_DBAT7L@l 699*a47a12beSStefan Roese addis r3, r0, CONFIG_SYS_DBAT7U@h 700*a47a12beSStefan Roese ori r3, r3, CONFIG_SYS_DBAT7U@l 701*a47a12beSStefan Roese mtspr DBAT7L, r4 702*a47a12beSStefan Roese mtspr DBAT7U, r3 703*a47a12beSStefan Roese#endif 704*a47a12beSStefan Roese 705*a47a12beSStefan Roese isync 706*a47a12beSStefan Roese 707*a47a12beSStefan Roese /* invalidate all tlb's 708*a47a12beSStefan Roese * 709*a47a12beSStefan Roese * From the 603e User Manual: "The 603e provides the ability to 710*a47a12beSStefan Roese * invalidate a TLB entry. The TLB Invalidate Entry (tlbie) 711*a47a12beSStefan Roese * instruction invalidates the TLB entry indexed by the EA, and 712*a47a12beSStefan Roese * operates on both the instruction and data TLBs simultaneously 713*a47a12beSStefan Roese * invalidating four TLB entries (both sets in each TLB). The 714*a47a12beSStefan Roese * index corresponds to bits 15-19 of the EA. To invalidate all 715*a47a12beSStefan Roese * entries within both TLBs, 32 tlbie instructions should be 716*a47a12beSStefan Roese * issued, incrementing this field by one each time." 717*a47a12beSStefan Roese * 718*a47a12beSStefan Roese * "Note that the tlbia instruction is not implemented on the 719*a47a12beSStefan Roese * 603e." 720*a47a12beSStefan Roese * 721*a47a12beSStefan Roese * bits 15-19 correspond to addresses 0x00000000 to 0x0001F000 722*a47a12beSStefan Roese * incrementing by 0x1000 each time. The code below is sort of 723*a47a12beSStefan Roese * based on code in "flush_tlbs" from arch/powerpc/kernel/head.S 724*a47a12beSStefan Roese * 725*a47a12beSStefan Roese */ 726*a47a12beSStefan Roese lis r3, 0 727*a47a12beSStefan Roese lis r5, 2 728*a47a12beSStefan Roese 729*a47a12beSStefan Roese1: 730*a47a12beSStefan Roese tlbie r3 731*a47a12beSStefan Roese addi r3, r3, 0x1000 732*a47a12beSStefan Roese cmp 0, 0, r3, r5 733*a47a12beSStefan Roese blt 1b 734*a47a12beSStefan Roese 735*a47a12beSStefan Roese blr 736*a47a12beSStefan Roese 737*a47a12beSStefan Roese/* Cache functions. 738*a47a12beSStefan Roese * 739*a47a12beSStefan Roese * Note: requires that all cache bits in 740*a47a12beSStefan Roese * HID0 are in the low half word. 741*a47a12beSStefan Roese */ 742*a47a12beSStefan Roese .globl icache_enable 743*a47a12beSStefan Roeseicache_enable: 744*a47a12beSStefan Roese mfspr r3, HID0 745*a47a12beSStefan Roese ori r3, r3, HID0_ICE 746*a47a12beSStefan Roese li r4, HID0_ICFI|HID0_ILOCK 747*a47a12beSStefan Roese andc r3, r3, r4 748*a47a12beSStefan Roese ori r4, r3, HID0_ICFI 749*a47a12beSStefan Roese isync 750*a47a12beSStefan Roese mtspr HID0, r4 /* sets enable and invalidate, clears lock */ 751*a47a12beSStefan Roese isync 752*a47a12beSStefan Roese mtspr HID0, r3 /* clears invalidate */ 753*a47a12beSStefan Roese blr 754*a47a12beSStefan Roese 755*a47a12beSStefan Roese .globl icache_disable 756*a47a12beSStefan Roeseicache_disable: 757*a47a12beSStefan Roese mfspr r3, HID0 758*a47a12beSStefan Roese lis r4, 0 759*a47a12beSStefan Roese ori r4, r4, HID0_ICE|HID0_ICFI|HID0_ILOCK 760*a47a12beSStefan Roese andc r3, r3, r4 761*a47a12beSStefan Roese isync 762*a47a12beSStefan Roese mtspr HID0, r3 /* clears invalidate, enable and lock */ 763*a47a12beSStefan Roese blr 764*a47a12beSStefan Roese 765*a47a12beSStefan Roese .globl icache_status 766*a47a12beSStefan Roeseicache_status: 767*a47a12beSStefan Roese mfspr r3, HID0 768*a47a12beSStefan Roese rlwinm r3, r3, (31 - HID0_ICE_SHIFT + 1), 31, 31 769*a47a12beSStefan Roese blr 770*a47a12beSStefan Roese 771*a47a12beSStefan Roese .globl dcache_enable 772*a47a12beSStefan Roesedcache_enable: 773*a47a12beSStefan Roese mfspr r3, HID0 774*a47a12beSStefan Roese li r5, HID0_DCFI|HID0_DLOCK 775*a47a12beSStefan Roese andc r3, r3, r5 776*a47a12beSStefan Roese ori r3, r3, HID0_DCE 777*a47a12beSStefan Roese sync 778*a47a12beSStefan Roese mtspr HID0, r3 /* enable, no invalidate */ 779*a47a12beSStefan Roese blr 780*a47a12beSStefan Roese 781*a47a12beSStefan Roese .globl dcache_disable 782*a47a12beSStefan Roesedcache_disable: 783*a47a12beSStefan Roese mflr r4 784*a47a12beSStefan Roese bl flush_dcache /* uses r3 and r5 */ 785*a47a12beSStefan Roese mfspr r3, HID0 786*a47a12beSStefan Roese li r5, HID0_DCE|HID0_DLOCK 787*a47a12beSStefan Roese andc r3, r3, r5 788*a47a12beSStefan Roese ori r5, r3, HID0_DCFI 789*a47a12beSStefan Roese sync 790*a47a12beSStefan Roese mtspr HID0, r5 /* sets invalidate, clears enable and lock */ 791*a47a12beSStefan Roese sync 792*a47a12beSStefan Roese mtspr HID0, r3 /* clears invalidate */ 793*a47a12beSStefan Roese mtlr r4 794*a47a12beSStefan Roese blr 795*a47a12beSStefan Roese 796*a47a12beSStefan Roese .globl dcache_status 797*a47a12beSStefan Roesedcache_status: 798*a47a12beSStefan Roese mfspr r3, HID0 799*a47a12beSStefan Roese rlwinm r3, r3, (31 - HID0_DCE_SHIFT + 1), 31, 31 800*a47a12beSStefan Roese blr 801*a47a12beSStefan Roese 802*a47a12beSStefan Roese .globl flush_dcache 803*a47a12beSStefan Roeseflush_dcache: 804*a47a12beSStefan Roese lis r3, 0 805*a47a12beSStefan Roese lis r5, CONFIG_SYS_CACHELINE_SIZE 806*a47a12beSStefan Roese1: cmp 0, 1, r3, r5 807*a47a12beSStefan Roese bge 2f 808*a47a12beSStefan Roese lwz r5, 0(r3) 809*a47a12beSStefan Roese lis r5, CONFIG_SYS_CACHELINE_SIZE 810*a47a12beSStefan Roese addi r3, r3, 0x4 811*a47a12beSStefan Roese b 1b 812*a47a12beSStefan Roese2: blr 813*a47a12beSStefan Roese 814*a47a12beSStefan Roese/*-------------------------------------------------------------------*/ 815*a47a12beSStefan Roese 816*a47a12beSStefan Roese/* 817*a47a12beSStefan Roese * void relocate_code (addr_sp, gd, addr_moni) 818*a47a12beSStefan Roese * 819*a47a12beSStefan Roese * This "function" does not return, instead it continues in RAM 820*a47a12beSStefan Roese * after relocating the monitor code. 821*a47a12beSStefan Roese * 822*a47a12beSStefan Roese * r3 = dest 823*a47a12beSStefan Roese * r4 = src 824*a47a12beSStefan Roese * r5 = length in bytes 825*a47a12beSStefan Roese * r6 = cachelinesize 826*a47a12beSStefan Roese */ 827*a47a12beSStefan Roese .globl relocate_code 828*a47a12beSStefan Roeserelocate_code: 829*a47a12beSStefan Roese mr r1, r3 /* Set new stack pointer */ 830*a47a12beSStefan Roese mr r9, r4 /* Save copy of Global Data pointer */ 831*a47a12beSStefan Roese mr r10, r5 /* Save copy of Destination Address */ 832*a47a12beSStefan Roese 833*a47a12beSStefan Roese GET_GOT 834*a47a12beSStefan Roese mr r3, r5 /* Destination Address */ 835*a47a12beSStefan Roese lis r4, CONFIG_SYS_MONITOR_BASE@h /* Source Address */ 836*a47a12beSStefan Roese ori r4, r4, CONFIG_SYS_MONITOR_BASE@l 837*a47a12beSStefan Roese lwz r5, GOT(__bss_start) 838*a47a12beSStefan Roese sub r5, r5, r4 839*a47a12beSStefan Roese li r6, CONFIG_SYS_CACHELINE_SIZE /* Cache Line Size */ 840*a47a12beSStefan Roese 841*a47a12beSStefan Roese /* 842*a47a12beSStefan Roese * Fix GOT pointer: 843*a47a12beSStefan Roese * 844*a47a12beSStefan Roese * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) 845*a47a12beSStefan Roese * + Destination Address 846*a47a12beSStefan Roese * 847*a47a12beSStefan Roese * Offset: 848*a47a12beSStefan Roese */ 849*a47a12beSStefan Roese sub r15, r10, r4 850*a47a12beSStefan Roese 851*a47a12beSStefan Roese /* First our own GOT */ 852*a47a12beSStefan Roese add r12, r12, r15 853*a47a12beSStefan Roese /* then the one used by the C code */ 854*a47a12beSStefan Roese add r30, r30, r15 855*a47a12beSStefan Roese 856*a47a12beSStefan Roese /* 857*a47a12beSStefan Roese * Now relocate code 858*a47a12beSStefan Roese */ 859*a47a12beSStefan Roese 860*a47a12beSStefan Roese cmplw cr1,r3,r4 861*a47a12beSStefan Roese addi r0,r5,3 862*a47a12beSStefan Roese srwi. r0,r0,2 863*a47a12beSStefan Roese beq cr1,4f /* In place copy is not necessary */ 864*a47a12beSStefan Roese beq 7f /* Protect against 0 count */ 865*a47a12beSStefan Roese mtctr r0 866*a47a12beSStefan Roese bge cr1,2f 867*a47a12beSStefan Roese la r8,-4(r4) 868*a47a12beSStefan Roese la r7,-4(r3) 869*a47a12beSStefan Roese 870*a47a12beSStefan Roese /* copy */ 871*a47a12beSStefan Roese1: lwzu r0,4(r8) 872*a47a12beSStefan Roese stwu r0,4(r7) 873*a47a12beSStefan Roese bdnz 1b 874*a47a12beSStefan Roese 875*a47a12beSStefan Roese addi r0,r5,3 876*a47a12beSStefan Roese srwi. r0,r0,2 877*a47a12beSStefan Roese mtctr r0 878*a47a12beSStefan Roese la r8,-4(r4) 879*a47a12beSStefan Roese la r7,-4(r3) 880*a47a12beSStefan Roese 881*a47a12beSStefan Roese /* and compare */ 882*a47a12beSStefan Roese20: lwzu r20,4(r8) 883*a47a12beSStefan Roese lwzu r21,4(r7) 884*a47a12beSStefan Roese xor. r22, r20, r21 885*a47a12beSStefan Roese bne 30f 886*a47a12beSStefan Roese bdnz 20b 887*a47a12beSStefan Roese b 4f 888*a47a12beSStefan Roese 889*a47a12beSStefan Roese /* compare failed */ 890*a47a12beSStefan Roese30: li r3, 0 891*a47a12beSStefan Roese blr 892*a47a12beSStefan Roese 893*a47a12beSStefan Roese2: slwi r0,r0,2 /* re copy in reverse order ... y do we needed it? */ 894*a47a12beSStefan Roese add r8,r4,r0 895*a47a12beSStefan Roese add r7,r3,r0 896*a47a12beSStefan Roese3: lwzu r0,-4(r8) 897*a47a12beSStefan Roese stwu r0,-4(r7) 898*a47a12beSStefan Roese bdnz 3b 899*a47a12beSStefan Roese 900*a47a12beSStefan Roese/* 901*a47a12beSStefan Roese * Now flush the cache: note that we must start from a cache aligned 902*a47a12beSStefan Roese * address. Otherwise we might miss one cache line. 903*a47a12beSStefan Roese */ 904*a47a12beSStefan Roese4: cmpwi r6,0 905*a47a12beSStefan Roese add r5,r3,r5 906*a47a12beSStefan Roese beq 7f /* Always flush prefetch queue in any case */ 907*a47a12beSStefan Roese subi r0,r6,1 908*a47a12beSStefan Roese andc r3,r3,r0 909*a47a12beSStefan Roese mr r4,r3 910*a47a12beSStefan Roese5: dcbst 0,r4 911*a47a12beSStefan Roese add r4,r4,r6 912*a47a12beSStefan Roese cmplw r4,r5 913*a47a12beSStefan Roese blt 5b 914*a47a12beSStefan Roese sync /* Wait for all dcbst to complete on bus */ 915*a47a12beSStefan Roese mr r4,r3 916*a47a12beSStefan Roese6: icbi 0,r4 917*a47a12beSStefan Roese add r4,r4,r6 918*a47a12beSStefan Roese cmplw r4,r5 919*a47a12beSStefan Roese blt 6b 920*a47a12beSStefan Roese7: sync /* Wait for all icbi to complete on bus */ 921*a47a12beSStefan Roese isync 922*a47a12beSStefan Roese 923*a47a12beSStefan Roese/* 924*a47a12beSStefan Roese * We are done. Do not return, instead branch to second part of board 925*a47a12beSStefan Roese * initialization, now running from RAM. 926*a47a12beSStefan Roese */ 927*a47a12beSStefan Roese addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET 928*a47a12beSStefan Roese mtlr r0 929*a47a12beSStefan Roese blr 930*a47a12beSStefan Roese 931*a47a12beSStefan Roesein_ram: 932*a47a12beSStefan Roese 933*a47a12beSStefan Roese /* 934*a47a12beSStefan Roese * Relocation Function, r12 point to got2+0x8000 935*a47a12beSStefan Roese * 936*a47a12beSStefan Roese * Adjust got2 pointers, no need to check for 0, this code 937*a47a12beSStefan Roese * already puts a few entries in the table. 938*a47a12beSStefan Roese */ 939*a47a12beSStefan Roese li r0,__got2_entries@sectoff@l 940*a47a12beSStefan Roese la r3,GOT(_GOT2_TABLE_) 941*a47a12beSStefan Roese lwz r11,GOT(_GOT2_TABLE_) 942*a47a12beSStefan Roese mtctr r0 943*a47a12beSStefan Roese sub r11,r3,r11 944*a47a12beSStefan Roese addi r3,r3,-4 945*a47a12beSStefan Roese1: lwzu r0,4(r3) 946*a47a12beSStefan Roese cmpwi r0,0 947*a47a12beSStefan Roese beq- 2f 948*a47a12beSStefan Roese add r0,r0,r11 949*a47a12beSStefan Roese stw r0,0(r3) 950*a47a12beSStefan Roese2: bdnz 1b 951*a47a12beSStefan Roese 952*a47a12beSStefan Roese#ifndef CONFIG_NAND_SPL 953*a47a12beSStefan Roese /* 954*a47a12beSStefan Roese * Now adjust the fixups and the pointers to the fixups 955*a47a12beSStefan Roese * in case we need to move ourselves again. 956*a47a12beSStefan Roese */ 957*a47a12beSStefan Roese li r0,__fixup_entries@sectoff@l 958*a47a12beSStefan Roese lwz r3,GOT(_FIXUP_TABLE_) 959*a47a12beSStefan Roese cmpwi r0,0 960*a47a12beSStefan Roese mtctr r0 961*a47a12beSStefan Roese addi r3,r3,-4 962*a47a12beSStefan Roese beq 4f 963*a47a12beSStefan Roese3: lwzu r4,4(r3) 964*a47a12beSStefan Roese lwzux r0,r4,r11 965*a47a12beSStefan Roese add r0,r0,r11 966*a47a12beSStefan Roese stw r10,0(r3) 967*a47a12beSStefan Roese stw r0,0(r4) 968*a47a12beSStefan Roese bdnz 3b 969*a47a12beSStefan Roese4: 970*a47a12beSStefan Roese#endif 971*a47a12beSStefan Roese 972*a47a12beSStefan Roeseclear_bss: 973*a47a12beSStefan Roese /* 974*a47a12beSStefan Roese * Now clear BSS segment 975*a47a12beSStefan Roese */ 976*a47a12beSStefan Roese lwz r3,GOT(__bss_start) 977*a47a12beSStefan Roese#if defined(CONFIG_HYMOD) 978*a47a12beSStefan Roese /* 979*a47a12beSStefan Roese * For HYMOD - the environment is the very last item in flash. 980*a47a12beSStefan Roese * The real .bss stops just before environment starts, so only 981*a47a12beSStefan Roese * clear up to that point. 982*a47a12beSStefan Roese * 983*a47a12beSStefan Roese * taken from mods for FADS board 984*a47a12beSStefan Roese */ 985*a47a12beSStefan Roese lwz r4,GOT(environment) 986*a47a12beSStefan Roese#else 987*a47a12beSStefan Roese lwz r4,GOT(_end) 988*a47a12beSStefan Roese#endif 989*a47a12beSStefan Roese 990*a47a12beSStefan Roese cmplw 0, r3, r4 991*a47a12beSStefan Roese beq 6f 992*a47a12beSStefan Roese 993*a47a12beSStefan Roese li r0, 0 994*a47a12beSStefan Roese5: 995*a47a12beSStefan Roese stw r0, 0(r3) 996*a47a12beSStefan Roese addi r3, r3, 4 997*a47a12beSStefan Roese cmplw 0, r3, r4 998*a47a12beSStefan Roese bne 5b 999*a47a12beSStefan Roese6: 1000*a47a12beSStefan Roese 1001*a47a12beSStefan Roese mr r3, r9 /* Global Data pointer */ 1002*a47a12beSStefan Roese mr r4, r10 /* Destination Address */ 1003*a47a12beSStefan Roese bl board_init_r 1004*a47a12beSStefan Roese 1005*a47a12beSStefan Roese#ifndef CONFIG_NAND_SPL 1006*a47a12beSStefan Roese /* 1007*a47a12beSStefan Roese * Copy exception vector code to low memory 1008*a47a12beSStefan Roese * 1009*a47a12beSStefan Roese * r3: dest_addr 1010*a47a12beSStefan Roese * r7: source address, r8: end address, r9: target address 1011*a47a12beSStefan Roese */ 1012*a47a12beSStefan Roese .globl trap_init 1013*a47a12beSStefan Roesetrap_init: 1014*a47a12beSStefan Roese mflr r4 /* save link register */ 1015*a47a12beSStefan Roese GET_GOT 1016*a47a12beSStefan Roese lwz r7, GOT(_start) 1017*a47a12beSStefan Roese lwz r8, GOT(_end_of_vectors) 1018*a47a12beSStefan Roese 1019*a47a12beSStefan Roese li r9, 0x100 /* reset vector always at 0x100 */ 1020*a47a12beSStefan Roese 1021*a47a12beSStefan Roese cmplw 0, r7, r8 1022*a47a12beSStefan Roese bgelr /* return if r7>=r8 - just in case */ 1023*a47a12beSStefan Roese1: 1024*a47a12beSStefan Roese lwz r0, 0(r7) 1025*a47a12beSStefan Roese stw r0, 0(r9) 1026*a47a12beSStefan Roese addi r7, r7, 4 1027*a47a12beSStefan Roese addi r9, r9, 4 1028*a47a12beSStefan Roese cmplw 0, r7, r8 1029*a47a12beSStefan Roese bne 1b 1030*a47a12beSStefan Roese 1031*a47a12beSStefan Roese /* 1032*a47a12beSStefan Roese * relocate `hdlr' and `int_return' entries 1033*a47a12beSStefan Roese */ 1034*a47a12beSStefan Roese li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET 1035*a47a12beSStefan Roese li r8, Alignment - _start + EXC_OFF_SYS_RESET 1036*a47a12beSStefan Roese2: 1037*a47a12beSStefan Roese bl trap_reloc 1038*a47a12beSStefan Roese addi r7, r7, 0x100 /* next exception vector */ 1039*a47a12beSStefan Roese cmplw 0, r7, r8 1040*a47a12beSStefan Roese blt 2b 1041*a47a12beSStefan Roese 1042*a47a12beSStefan Roese li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET 1043*a47a12beSStefan Roese bl trap_reloc 1044*a47a12beSStefan Roese 1045*a47a12beSStefan Roese li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET 1046*a47a12beSStefan Roese bl trap_reloc 1047*a47a12beSStefan Roese 1048*a47a12beSStefan Roese li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET 1049*a47a12beSStefan Roese li r8, SystemCall - _start + EXC_OFF_SYS_RESET 1050*a47a12beSStefan Roese3: 1051*a47a12beSStefan Roese bl trap_reloc 1052*a47a12beSStefan Roese addi r7, r7, 0x100 /* next exception vector */ 1053*a47a12beSStefan Roese cmplw 0, r7, r8 1054*a47a12beSStefan Roese blt 3b 1055*a47a12beSStefan Roese 1056*a47a12beSStefan Roese li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET 1057*a47a12beSStefan Roese li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET 1058*a47a12beSStefan Roese4: 1059*a47a12beSStefan Roese bl trap_reloc 1060*a47a12beSStefan Roese addi r7, r7, 0x100 /* next exception vector */ 1061*a47a12beSStefan Roese cmplw 0, r7, r8 1062*a47a12beSStefan Roese blt 4b 1063*a47a12beSStefan Roese 1064*a47a12beSStefan Roese mfmsr r3 /* now that the vectors have */ 1065*a47a12beSStefan Roese lis r7, MSR_IP@h /* relocated into low memory */ 1066*a47a12beSStefan Roese ori r7, r7, MSR_IP@l /* MSR[IP] can be turned off */ 1067*a47a12beSStefan Roese andc r3, r3, r7 /* (if it was on) */ 1068*a47a12beSStefan Roese SYNC /* Some chip revs need this... */ 1069*a47a12beSStefan Roese mtmsr r3 1070*a47a12beSStefan Roese SYNC 1071*a47a12beSStefan Roese 1072*a47a12beSStefan Roese mtlr r4 /* restore link register */ 1073*a47a12beSStefan Roese blr 1074*a47a12beSStefan Roese 1075*a47a12beSStefan Roese#endif /* !CONFIG_NAND_SPL */ 1076*a47a12beSStefan Roese 1077*a47a12beSStefan Roese#ifdef CONFIG_SYS_INIT_RAM_LOCK 1078*a47a12beSStefan Roeselock_ram_in_cache: 1079*a47a12beSStefan Roese /* Allocate Initial RAM in data cache. 1080*a47a12beSStefan Roese */ 1081*a47a12beSStefan Roese lis r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@h 1082*a47a12beSStefan Roese ori r3, r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@l 1083*a47a12beSStefan Roese li r4, ((CONFIG_SYS_INIT_RAM_END & ~31) + \ 1084*a47a12beSStefan Roese (CONFIG_SYS_INIT_RAM_ADDR & 31) + 31) / 32 1085*a47a12beSStefan Roese mtctr r4 1086*a47a12beSStefan Roese1: 1087*a47a12beSStefan Roese dcbz r0, r3 1088*a47a12beSStefan Roese addi r3, r3, 32 1089*a47a12beSStefan Roese bdnz 1b 1090*a47a12beSStefan Roese 1091*a47a12beSStefan Roese /* Lock the data cache */ 1092*a47a12beSStefan Roese mfspr r0, HID0 1093*a47a12beSStefan Roese ori r0, r0, HID0_DLOCK 1094*a47a12beSStefan Roese sync 1095*a47a12beSStefan Roese mtspr HID0, r0 1096*a47a12beSStefan Roese sync 1097*a47a12beSStefan Roese blr 1098*a47a12beSStefan Roese 1099*a47a12beSStefan Roese#ifndef CONFIG_NAND_SPL 1100*a47a12beSStefan Roese.globl unlock_ram_in_cache 1101*a47a12beSStefan Roeseunlock_ram_in_cache: 1102*a47a12beSStefan Roese /* invalidate the INIT_RAM section */ 1103*a47a12beSStefan Roese lis r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@h 1104*a47a12beSStefan Roese ori r3, r3, (CONFIG_SYS_INIT_RAM_ADDR & ~31)@l 1105*a47a12beSStefan Roese li r4, ((CONFIG_SYS_INIT_RAM_END & ~31) + \ 1106*a47a12beSStefan Roese (CONFIG_SYS_INIT_RAM_ADDR & 31) + 31) / 32 1107*a47a12beSStefan Roese mtctr r4 1108*a47a12beSStefan Roese1: icbi r0, r3 1109*a47a12beSStefan Roese dcbi r0, r3 1110*a47a12beSStefan Roese addi r3, r3, 32 1111*a47a12beSStefan Roese bdnz 1b 1112*a47a12beSStefan Roese sync /* Wait for all icbi to complete on bus */ 1113*a47a12beSStefan Roese isync 1114*a47a12beSStefan Roese 1115*a47a12beSStefan Roese /* Unlock the data cache and invalidate it */ 1116*a47a12beSStefan Roese mfspr r3, HID0 1117*a47a12beSStefan Roese li r5, HID0_DLOCK|HID0_DCFI 1118*a47a12beSStefan Roese andc r3, r3, r5 /* no invalidate, unlock */ 1119*a47a12beSStefan Roese ori r5, r3, HID0_DCFI /* invalidate, unlock */ 1120*a47a12beSStefan Roese sync 1121*a47a12beSStefan Roese mtspr HID0, r5 /* invalidate, unlock */ 1122*a47a12beSStefan Roese sync 1123*a47a12beSStefan Roese mtspr HID0, r3 /* no invalidate, unlock */ 1124*a47a12beSStefan Roese blr 1125*a47a12beSStefan Roese#endif /* !CONFIG_NAND_SPL */ 1126*a47a12beSStefan Roese#endif /* CONFIG_SYS_INIT_RAM_LOCK */ 1127*a47a12beSStefan Roese 1128*a47a12beSStefan Roese#ifdef CONFIG_SYS_FLASHBOOT 1129*a47a12beSStefan Roesemap_flash_by_law1: 1130*a47a12beSStefan Roese /* When booting from ROM (Flash or EPROM), clear the */ 1131*a47a12beSStefan Roese /* Address Mask in OR0 so ROM appears everywhere */ 1132*a47a12beSStefan Roese /*----------------------------------------------------*/ 1133*a47a12beSStefan Roese lis r3, (CONFIG_SYS_IMMR)@h /* r3 <= CONFIG_SYS_IMMR */ 1134*a47a12beSStefan Roese lwz r4, OR0@l(r3) 1135*a47a12beSStefan Roese li r5, 0x7fff /* r5 <= 0x00007FFFF */ 1136*a47a12beSStefan Roese and r4, r4, r5 1137*a47a12beSStefan Roese stw r4, OR0@l(r3) /* OR0 <= OR0 & 0x00007FFFF */ 1138*a47a12beSStefan Roese 1139*a47a12beSStefan Roese /* As MPC8349E User's Manual presented, when RCW[BMS] is set to 0, 1140*a47a12beSStefan Roese * system will boot from 0x0000_0100, and the LBLAWBAR0[BASE_ADDR] 1141*a47a12beSStefan Roese * reset value is 0x00000; when RCW[BMS] is set to 1, system will boot 1142*a47a12beSStefan Roese * from 0xFFF0_0100, and the LBLAWBAR0[BASE_ADDR] reset value is 1143*a47a12beSStefan Roese * 0xFF800. From the hard resetting to here, the processor fetched and 1144*a47a12beSStefan Roese * executed the instructions one by one. There is not absolutely 1145*a47a12beSStefan Roese * jumping happened. Laterly, the u-boot code has to do an absolutely 1146*a47a12beSStefan Roese * jumping to tell the CPU instruction fetching component what the 1147*a47a12beSStefan Roese * u-boot TEXT base address is. Because the TEXT base resides in the 1148*a47a12beSStefan Roese * boot ROM memory space, to garantee the code can run smoothly after 1149*a47a12beSStefan Roese * that jumping, we must map in the entire boot ROM by Local Access 1150*a47a12beSStefan Roese * Window. Sometimes, we desire an non-0x00000 or non-0xFF800 starting 1151*a47a12beSStefan Roese * address for boot ROM, such as 0xFE000000. In this case, the default 1152*a47a12beSStefan Roese * LBIU Local Access Widow 0 will not cover this memory space. So, we 1153*a47a12beSStefan Roese * need another window to map in it. 1154*a47a12beSStefan Roese */ 1155*a47a12beSStefan Roese lis r4, (CONFIG_SYS_FLASH_BASE)@h 1156*a47a12beSStefan Roese ori r4, r4, (CONFIG_SYS_FLASH_BASE)@l 1157*a47a12beSStefan Roese stw r4, LBLAWBAR1(r3) /* LBLAWBAR1 <= CONFIG_SYS_FLASH_BASE */ 1158*a47a12beSStefan Roese 1159*a47a12beSStefan Roese /* Store 0x80000012 + log2(CONFIG_SYS_FLASH_SIZE) into LBLAWAR1 */ 1160*a47a12beSStefan Roese lis r4, (0x80000012)@h 1161*a47a12beSStefan Roese ori r4, r4, (0x80000012)@l 1162*a47a12beSStefan Roese li r5, CONFIG_SYS_FLASH_SIZE 1163*a47a12beSStefan Roese1: srawi. r5, r5, 1 /* r5 = r5 >> 1 */ 1164*a47a12beSStefan Roese addi r4, r4, 1 1165*a47a12beSStefan Roese bne 1b 1166*a47a12beSStefan Roese 1167*a47a12beSStefan Roese stw r4, LBLAWAR1(r3) /* LBLAWAR1 <= 8MB Flash Size */ 1168*a47a12beSStefan Roese blr 1169*a47a12beSStefan Roese 1170*a47a12beSStefan Roese /* Though all the LBIU Local Access Windows and LBC Banks will be 1171*a47a12beSStefan Roese * initialized in the C code, we'd better configure boot ROM's 1172*a47a12beSStefan Roese * window 0 and bank 0 correctly at here. 1173*a47a12beSStefan Roese */ 1174*a47a12beSStefan Roeseremap_flash_by_law0: 1175*a47a12beSStefan Roese /* Initialize the BR0 with the boot ROM starting address. */ 1176*a47a12beSStefan Roese lwz r4, BR0(r3) 1177*a47a12beSStefan Roese li r5, 0x7FFF 1178*a47a12beSStefan Roese and r4, r4, r5 1179*a47a12beSStefan Roese lis r5, (CONFIG_SYS_FLASH_BASE & 0xFFFF8000)@h 1180*a47a12beSStefan Roese ori r5, r5, (CONFIG_SYS_FLASH_BASE & 0xFFFF8000)@l 1181*a47a12beSStefan Roese or r5, r5, r4 1182*a47a12beSStefan Roese stw r5, BR0(r3) /* r5 <= (CONFIG_SYS_FLASH_BASE & 0xFFFF8000) | (BR0 & 0x00007FFF) */ 1183*a47a12beSStefan Roese 1184*a47a12beSStefan Roese lwz r4, OR0(r3) 1185*a47a12beSStefan Roese lis r5, ~((CONFIG_SYS_FLASH_SIZE << 4) - 1) 1186*a47a12beSStefan Roese or r4, r4, r5 1187*a47a12beSStefan Roese stw r4, OR0(r3) 1188*a47a12beSStefan Roese 1189*a47a12beSStefan Roese lis r4, (CONFIG_SYS_FLASH_BASE)@h 1190*a47a12beSStefan Roese ori r4, r4, (CONFIG_SYS_FLASH_BASE)@l 1191*a47a12beSStefan Roese stw r4, LBLAWBAR0(r3) /* LBLAWBAR0 <= CONFIG_SYS_FLASH_BASE */ 1192*a47a12beSStefan Roese 1193*a47a12beSStefan Roese /* Store 0x80000012 + log2(CONFIG_SYS_FLASH_SIZE) into LBLAWAR0 */ 1194*a47a12beSStefan Roese lis r4, (0x80000012)@h 1195*a47a12beSStefan Roese ori r4, r4, (0x80000012)@l 1196*a47a12beSStefan Roese li r5, CONFIG_SYS_FLASH_SIZE 1197*a47a12beSStefan Roese1: srawi. r5, r5, 1 /* r5 = r5 >> 1 */ 1198*a47a12beSStefan Roese addi r4, r4, 1 1199*a47a12beSStefan Roese bne 1b 1200*a47a12beSStefan Roese stw r4, LBLAWAR0(r3) /* LBLAWAR0 <= Flash Size */ 1201*a47a12beSStefan Roese 1202*a47a12beSStefan Roese 1203*a47a12beSStefan Roese xor r4, r4, r4 1204*a47a12beSStefan Roese stw r4, LBLAWBAR1(r3) 1205*a47a12beSStefan Roese stw r4, LBLAWAR1(r3) /* Off LBIU LAW1 */ 1206*a47a12beSStefan Roese blr 1207*a47a12beSStefan Roese#endif /* CONFIG_SYS_FLASHBOOT */ 1208