Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / u-boot / arch / powerpc / cpu / ppc4xx / start.S
diff --git a/qemu/roms/u-boot/arch/powerpc/cpu/ppc4xx/start.S b/qemu/roms/u-boot/arch/powerpc/cpu/ppc4xx/start.S
new file mode 100644 (file)
index 0000000..11b55d5
--- /dev/null
@@ -0,0 +1,1954 @@
+/*
+ *  Copyright (C) 1998 Dan Malek <dmalek@jlc.net>
+ *  Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
+ *  Copyright (C) 2000,2001,2002 Wolfgang Denk <wd@denx.de>
+ *  Copyright (C) 2007 Stefan Roese <sr@denx.de>, DENX Software Engineering
+ *  Copyright (c) 2008 Nuovation System Designs, LLC
+ *    Grant Erickson <gerickson@nuovations.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0 IBM-pibs
+ */
+
+/*
+ * Startup code for IBM/AMCC PowerPC 4xx (PPC4xx) based boards
+ *
+ * The following description only applies to the NOR flash style booting.
+ * NAND booting is different. For more details about NAND booting on 4xx
+ * take a look at doc/README.nand-boot-ppc440.
+ *
+ * The CPU starts at address 0xfffffffc (last word in the address space).
+ * The U-Boot image therefore has to be located in the "upper" area of the
+ * flash (e.g. 512MiB - 0xfff80000 ... 0xffffffff). The default value for
+ * the boot chip-select (CS0) is quite big and covers this area. On the
+ * 405EX this is for example 0xffe00000 ... 0xffffffff. U-Boot will
+ * reconfigure this CS0 (and other chip-selects as well when configured
+ * this way) in the boot process to the "correct" values matching the
+ * board layout.
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <asm/ppc4xx.h>
+#include <version.h>
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+#include <asm/cache.h>
+#include <asm/mmu.h>
+#include <asm/ppc4xx-isram.h>
+
+#ifdef CONFIG_SYS_INIT_DCACHE_CS
+# if (CONFIG_SYS_INIT_DCACHE_CS == 0)
+#  define PBxAP PB1AP
+#  define PBxCR PB0CR
+#  if (defined(CONFIG_SYS_EBC_PB0AP) && defined(CONFIG_SYS_EBC_PB0CR))
+#   define PBxAP_VAL CONFIG_SYS_EBC_PB0AP
+#   define PBxCR_VAL CONFIG_SYS_EBC_PB0CR
+#  endif
+# endif
+# if (CONFIG_SYS_INIT_DCACHE_CS == 1)
+#  define PBxAP PB1AP
+#  define PBxCR PB1CR
+#  if (defined(CONFIG_SYS_EBC_PB1AP) && defined(CONFIG_SYS_EBC_PB1CR))
+#   define PBxAP_VAL CONFIG_SYS_EBC_PB1AP
+#   define PBxCR_VAL CONFIG_SYS_EBC_PB1CR
+#  endif
+# endif
+# if (CONFIG_SYS_INIT_DCACHE_CS == 2)
+#  define PBxAP PB2AP
+#  define PBxCR PB2CR
+#  if (defined(CONFIG_SYS_EBC_PB2AP) && defined(CONFIG_SYS_EBC_PB2CR))
+#   define PBxAP_VAL CONFIG_SYS_EBC_PB2AP
+#   define PBxCR_VAL CONFIG_SYS_EBC_PB2CR
+#  endif
+# endif
+# if (CONFIG_SYS_INIT_DCACHE_CS == 3)
+#  define PBxAP PB3AP
+#  define PBxCR PB3CR
+#  if (defined(CONFIG_SYS_EBC_PB3AP) && defined(CONFIG_SYS_EBC_PB3CR))
+#   define PBxAP_VAL CONFIG_SYS_EBC_PB3AP
+#   define PBxCR_VAL CONFIG_SYS_EBC_PB3CR
+#  endif
+# endif
+# if (CONFIG_SYS_INIT_DCACHE_CS == 4)
+#  define PBxAP PB4AP
+#  define PBxCR PB4CR
+#  if (defined(CONFIG_SYS_EBC_PB4AP) && defined(CONFIG_SYS_EBC_PB4CR))
+#   define PBxAP_VAL CONFIG_SYS_EBC_PB4AP
+#   define PBxCR_VAL CONFIG_SYS_EBC_PB4CR
+#  endif
+# endif
+# if (CONFIG_SYS_INIT_DCACHE_CS == 5)
+#  define PBxAP PB5AP
+#  define PBxCR PB5CR
+#  if (defined(CONFIG_SYS_EBC_PB5AP) && defined(CONFIG_SYS_EBC_PB5CR))
+#   define PBxAP_VAL CONFIG_SYS_EBC_PB5AP
+#   define PBxCR_VAL CONFIG_SYS_EBC_PB5CR
+#  endif
+# endif
+# if (CONFIG_SYS_INIT_DCACHE_CS == 6)
+#  define PBxAP PB6AP
+#  define PBxCR PB6CR
+#  if (defined(CONFIG_SYS_EBC_PB6AP) && defined(CONFIG_SYS_EBC_PB6CR))
+#   define PBxAP_VAL CONFIG_SYS_EBC_PB6AP
+#   define PBxCR_VAL CONFIG_SYS_EBC_PB6CR
+#  endif
+# endif
+# if (CONFIG_SYS_INIT_DCACHE_CS == 7)
+#  define PBxAP PB7AP
+#  define PBxCR PB7CR
+#  if (defined(CONFIG_SYS_EBC_PB7AP) && defined(CONFIG_SYS_EBC_PB7CR))
+#   define PBxAP_VAL CONFIG_SYS_EBC_PB7AP
+#   define PBxCR_VAL CONFIG_SYS_EBC_PB7CR
+#  endif
+# endif
+# ifndef PBxAP_VAL
+#  define PBxAP_VAL    0
+# endif
+# ifndef PBxCR_VAL
+#  define PBxCR_VAL    0
+# endif
+/*
+ * Memory Bank x (nothingness) initialization CONFIG_SYS_INIT_RAM_ADDR + 64 MiB
+ * used as temporary stack pointer for the primordial stack
+ */
+# ifndef CONFIG_SYS_INIT_DCACHE_PBxAR
+#  define CONFIG_SYS_INIT_DCACHE_PBxAR (EBC_BXAP_BME_DISABLED                  | \
+                                EBC_BXAP_TWT_ENCODE(7)                 | \
+                                EBC_BXAP_BCE_DISABLE                   | \
+                                EBC_BXAP_BCT_2TRANS                    | \
+                                EBC_BXAP_CSN_ENCODE(0)                 | \
+                                EBC_BXAP_OEN_ENCODE(0)                 | \
+                                EBC_BXAP_WBN_ENCODE(0)                 | \
+                                EBC_BXAP_WBF_ENCODE(0)                 | \
+                                EBC_BXAP_TH_ENCODE(2)                  | \
+                                EBC_BXAP_RE_DISABLED                   | \
+                                EBC_BXAP_SOR_NONDELAYED                | \
+                                EBC_BXAP_BEM_WRITEONLY                 | \
+                                EBC_BXAP_PEN_DISABLED)
+# endif /* CONFIG_SYS_INIT_DCACHE_PBxAR */
+# ifndef CONFIG_SYS_INIT_DCACHE_PBxCR
+#  define CONFIG_SYS_INIT_DCACHE_PBxCR (EBC_BXCR_BAS_ENCODE(CONFIG_SYS_INIT_RAM_ADDR)  | \
+                                EBC_BXCR_BS_64MB                       | \
+                                EBC_BXCR_BU_RW                         | \
+                                EBC_BXCR_BW_16BIT)
+# endif /* CONFIG_SYS_INIT_DCACHE_PBxCR */
+# ifndef CONFIG_SYS_INIT_RAM_PATTERN
+#  define CONFIG_SYS_INIT_RAM_PATTERN  0xDEADDEAD
+# endif
+#endif /* CONFIG_SYS_INIT_DCACHE_CS */
+
+#if (defined(CONFIG_SYS_INIT_RAM_DCACHE) && (CONFIG_SYS_INIT_RAM_SIZE > (4 << 10)))
+#error Only 4k of init-ram is supported - please adjust CONFIG_SYS_INIT_RAM_SIZE!
+#endif
+
+/*
+ * Unless otherwise overriden, enable two 128MB cachable instruction regions
+ * at CONFIG_SYS_SDRAM_BASE and another 128MB cacheable instruction region covering
+ * NOR flash at CONFIG_SYS_FLASH_BASE. Disable all cacheable data regions.
+ */
+#if !defined(CONFIG_SYS_FLASH_BASE)
+/* If not already defined, set it to the "last" 128MByte region */
+# define CONFIG_SYS_FLASH_BASE         0xf8000000
+#endif
+#if !defined(CONFIG_SYS_ICACHE_SACR_VALUE)
+# define CONFIG_SYS_ICACHE_SACR_VALUE          \
+               (PPC_128MB_SACR_VALUE(CONFIG_SYS_SDRAM_BASE + (  0 << 20)) | \
+                PPC_128MB_SACR_VALUE(CONFIG_SYS_SDRAM_BASE + (128 << 20)) | \
+                PPC_128MB_SACR_VALUE(CONFIG_SYS_FLASH_BASE))
+#endif /* !defined(CONFIG_SYS_ICACHE_SACR_VALUE) */
+
+#if !defined(CONFIG_SYS_DCACHE_SACR_VALUE)
+# define CONFIG_SYS_DCACHE_SACR_VALUE          \
+               (0x00000000)
+#endif /* !defined(CONFIG_SYS_DCACHE_SACR_VALUE) */
+
+#if !defined(CONFIG_SYS_TLB_FOR_BOOT_FLASH)
+#define CONFIG_SYS_TLB_FOR_BOOT_FLASH  0       /* use TLB 0 as default */
+#endif
+
+#define function_prolog(func_name)     .text; \
+                                       .align 2; \
+                                       .globl func_name; \
+                                       func_name:
+#define function_epilog(func_name)     .type func_name,@function; \
+                                       .size func_name,.-func_name
+
+/* We don't want the  MMU yet.
+*/
+#undef MSR_KERNEL
+#define MSR_KERNEL ( MSR_ME  ) /* Machine Check */
+
+
+       .extern ext_bus_cntlr_init
+
+/*
+ * Set up GOT: Global Offset Table
+ *
+ * Use r12 to access the GOT
+ */
+#if !defined(CONFIG_SPL_BUILD)
+       START_GOT
+       GOT_ENTRY(_GOT2_TABLE_)
+       GOT_ENTRY(_FIXUP_TABLE_)
+
+       GOT_ENTRY(_start)
+       GOT_ENTRY(_start_of_vectors)
+       GOT_ENTRY(_end_of_vectors)
+       GOT_ENTRY(transfer_to_handler)
+
+       GOT_ENTRY(__init_end)
+       GOT_ENTRY(__bss_end)
+       GOT_ENTRY(__bss_start)
+       END_GOT
+#endif /* CONFIG_SPL_BUILD */
+
+#if defined(CONFIG_SYS_RAMBOOT) || defined(CONFIG_BOOT_FROM_XMD)
+       /*
+        * 4xx RAM-booting U-Boot image is started from offset 0
+        */
+       .text
+       bl      _start_440
+#endif
+
+#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD)
+       /*
+        * This is the entry of the real U-Boot from a board port
+        * that supports SPL booting on the PPC4xx. We only need
+        * to call board_init_f() here. Everything else has already
+        * been done in the SPL u-boot version.
+        */
+       GET_GOT                 /* initialize GOT access                */
+       bl      board_init_f    /* run 1st part of board init code (in Flash)*/
+       /* NOTREACHED - board_init_f() does not return */
+#endif
+
+/*
+ * 440 Startup -- on reset only the top 4k of the effective
+ * address space is mapped in by an entry in the instruction
+ * and data shadow TLB. The .bootpg section is located in the
+ * top 4k & does only what's necessary to map in the the rest
+ * of the boot rom. Once the boot rom is mapped in we can
+ * proceed with normal startup.
+ *
+ * NOTE: CS0 only covers the top 2MB of the effective address
+ * space after reset.
+ */
+
+#if defined(CONFIG_440)
+    .section .bootpg,"ax"
+    .globl _start_440
+
+/**************************************************************************/
+_start_440:
+       /*--------------------------------------------------------------------+
+       | 440EPX BUP Change - Hardware team request
+       +--------------------------------------------------------------------*/
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+       sync
+       nop
+       nop
+#endif
+       /*----------------------------------------------------------------+
+       | Core bug fix.  Clear the esr
+       +-----------------------------------------------------------------*/
+       li      r0,0
+       mtspr   SPRN_ESR,r0
+       /*----------------------------------------------------------------*/
+       /* Clear and set up some registers. */
+       /*----------------------------------------------------------------*/
+       iccci   r0,r0           /* NOTE: operands not used for 440 */
+       dccci   r0,r0           /* NOTE: operands not used for 440 */
+       sync
+       li      r0,0
+       mtspr   SPRN_SRR0,r0
+       mtspr   SPRN_SRR1,r0
+       mtspr   SPRN_CSRR0,r0
+       mtspr   SPRN_CSRR1,r0
+       /* NOTE: 440GX adds machine check status regs */
+#if defined(CONFIG_440) && !defined(CONFIG_440GP)
+       mtspr   SPRN_MCSRR0,r0
+       mtspr   SPRN_MCSRR1,r0
+       mfspr   r1,SPRN_MCSR
+       mtspr   SPRN_MCSR,r1
+#endif
+
+       /*----------------------------------------------------------------*/
+       /* CCR0 init */
+       /*----------------------------------------------------------------*/
+       /* Disable store gathering & broadcast, guarantee inst/data
+       * cache block touch, force load/store alignment
+       * (see errata 1.12: 440_33)
+       */
+       lis     r1,0x0030       /* store gathering & broadcast disable */
+       ori     r1,r1,0x6000    /* cache touch */
+       mtspr   SPRN_CCR0,r1
+
+       /*----------------------------------------------------------------*/
+       /* Initialize debug */
+       /*----------------------------------------------------------------*/
+       mfspr   r1,SPRN_DBCR0
+       andis.  r1, r1, 0x8000  /* test DBCR0[EDM] bit                  */
+       bne     skip_debug_init /* if set, don't clear debug register   */
+       mfspr   r1,SPRN_CCR0
+       ori     r1,r1,CCR0_DTB@l /* Disable Trace Broadcast */
+       mtspr   SPRN_CCR0,r1
+       mtspr   SPRN_DBCR0,r0
+       mtspr   SPRN_DBCR1,r0
+       mtspr   SPRN_DBCR2,r0
+       mtspr   SPRN_IAC1,r0
+       mtspr   SPRN_IAC2,r0
+       mtspr   SPRN_IAC3,r0
+       mtspr   SPRN_DAC1,r0
+       mtspr   SPRN_DAC2,r0
+       mtspr   SPRN_DVC1,r0
+       mtspr   SPRN_DVC2,r0
+
+       mfspr   r1,SPRN_DBSR
+       mtspr   SPRN_DBSR,r1    /* Clear all valid bits */
+skip_debug_init:
+
+#if defined (CONFIG_440SPE)
+       /*----------------------------------------------------------------+
+       | Initialize Core Configuration Reg1.
+       | a. ICDPEI: Record even parity. Normal operation.
+       | b. ICTPEI: Record even parity. Normal operation.
+       | c. DCTPEI: Record even parity. Normal operation.
+       | d. DCDPEI: Record even parity. Normal operation.
+       | e. DCUPEI: Record even parity. Normal operation.
+       | f. DCMPEI: Record even parity. Normal operation.
+       | g. FCOM:   Normal operation
+       | h. MMUPEI: Record even parity. Normal operation.
+       | i. FFF:    Flush only as much data as necessary.
+       | j. TCS:    Timebase increments from CPU clock.
+       +-----------------------------------------------------------------*/
+       li      r0,0
+       mtspr   SPRN_CCR1, r0
+
+       /*----------------------------------------------------------------+
+       | Reset the timebase.
+       | The previous write to CCR1 sets the timebase source.
+       +-----------------------------------------------------------------*/
+       mtspr   SPRN_TBWL, r0
+       mtspr   SPRN_TBWU, r0
+#endif
+
+       /*----------------------------------------------------------------*/
+       /* Setup interrupt vectors */
+       /*----------------------------------------------------------------*/
+       mtspr   SPRN_IVPR,r0            /* Vectors start at 0x0000_0000 */
+       li      r1,0x0100
+       mtspr   SPRN_IVOR0,r1   /* Critical input */
+       li      r1,0x0200
+       mtspr   SPRN_IVOR1,r1   /* Machine check */
+       li      r1,0x0300
+       mtspr   SPRN_IVOR2,r1   /* Data storage */
+       li      r1,0x0400
+       mtspr   SPRN_IVOR3,r1   /* Instruction storage */
+       li      r1,0x0500
+       mtspr   SPRN_IVOR4,r1   /* External interrupt */
+       li      r1,0x0600
+       mtspr   SPRN_IVOR5,r1   /* Alignment */
+       li      r1,0x0700
+       mtspr   SPRN_IVOR6,r1   /* Program check */
+       li      r1,0x0800
+       mtspr   SPRN_IVOR7,r1   /* Floating point unavailable */
+       li      r1,0x0c00
+       mtspr   SPRN_IVOR8,r1   /* System call */
+       li      r1,0x0a00
+       mtspr   SPRN_IVOR9,r1   /* Auxiliary Processor unavailable */
+       li      r1,0x0900
+       mtspr   SPRN_IVOR10,r1  /* Decrementer */
+       li      r1,0x1300
+       mtspr   SPRN_IVOR13,r1  /* Data TLB error */
+       li      r1,0x1400
+       mtspr   SPRN_IVOR14,r1  /* Instr TLB error */
+       li      r1,0x2000
+       mtspr   SPRN_IVOR15,r1  /* Debug */
+
+       /*----------------------------------------------------------------*/
+       /* Configure cache regions  */
+       /*----------------------------------------------------------------*/
+       mtspr   SPRN_INV0,r0
+       mtspr   SPRN_INV1,r0
+       mtspr   SPRN_INV2,r0
+       mtspr   SPRN_INV3,r0
+       mtspr   SPRN_DNV0,r0
+       mtspr   SPRN_DNV1,r0
+       mtspr   SPRN_DNV2,r0
+       mtspr   SPRN_DNV3,r0
+       mtspr   SPRN_ITV0,r0
+       mtspr   SPRN_ITV1,r0
+       mtspr   SPRN_ITV2,r0
+       mtspr   SPRN_ITV3,r0
+       mtspr   SPRN_DTV0,r0
+       mtspr   SPRN_DTV1,r0
+       mtspr   SPRN_DTV2,r0
+       mtspr   SPRN_DTV3,r0
+
+       /*----------------------------------------------------------------*/
+       /* Cache victim limits */
+       /*----------------------------------------------------------------*/
+       /* floors 0, ceiling max to use the entire cache -- nothing locked
+       */
+       lis     r1,0x0001
+       ori     r1,r1,0xf800
+       mtspr   SPRN_IVLIM,r1
+       mtspr   SPRN_DVLIM,r1
+
+       /*----------------------------------------------------------------+
+       |Initialize MMUCR[STID] = 0.
+       +-----------------------------------------------------------------*/
+       mfspr   r0,SPRN_MMUCR
+       addis   r1,0,0xFFFF
+       ori     r1,r1,0xFF00
+       and     r0,r0,r1
+       mtspr   SPRN_MMUCR,r0
+
+       /*----------------------------------------------------------------*/
+       /* Clear all TLB entries -- TID = 0, TS = 0 */
+       /*----------------------------------------------------------------*/
+       addis   r0,0,0x0000
+#ifdef CONFIG_SYS_RAMBOOT
+       li      r4,0            /* Start with TLB #0 */
+#else
+       li      r4,1            /* Start with TLB #1 */
+#endif
+       li      r1,64           /* 64 TLB entries */
+       sub     r1,r1,r4        /* calculate last TLB # */
+       mtctr   r1
+rsttlb:
+#ifdef CONFIG_SYS_RAMBOOT
+       tlbre   r3,r4,0         /* Read contents from TLB word #0 to get EPN */
+       rlwinm. r3,r3,0,0xfffffc00      /* Mask EPN */
+       beq     tlbnxt          /* Skip EPN=0 TLB, this is the SDRAM TLB */
+#endif
+       tlbwe   r0,r4,0         /* Invalidate all entries (V=0)*/
+       tlbwe   r0,r4,1
+       tlbwe   r0,r4,2
+tlbnxt:        addi    r4,r4,1         /* Next TLB */
+       bdnz    rsttlb
+
+       /*----------------------------------------------------------------*/
+       /* TLB entry setup -- step thru tlbtab */
+       /*----------------------------------------------------------------*/
+#if defined(CONFIG_440SPE_REVA)
+       /*----------------------------------------------------------------*/
+       /* We have different TLB tables for revA and rev B of 440SPe */
+       /*----------------------------------------------------------------*/
+       mfspr   r1, PVR
+       lis     r0,0x5342
+       ori     r0,r0,0x1891
+       cmpw    r7,r1,r0
+       bne     r7,..revA
+       bl      tlbtabB
+       b       ..goon
+..revA:
+       bl      tlbtabA
+..goon:
+#else
+       bl      tlbtab          /* Get tlbtab pointer */
+#endif
+       mr      r5,r0
+       li      r1,0x003f       /* 64 TLB entries max */
+       mtctr   r1
+       li      r4,0            /* TLB # */
+
+       addi    r5,r5,-4
+1:
+#ifdef CONFIG_SYS_RAMBOOT
+       tlbre   r3,r4,0         /* Read contents from TLB word #0 */
+       rlwinm. r3,r3,0,0x00000200      /* Mask V (valid) bit */
+       bne     tlbnx2          /* Skip V=1 TLB, this is the SDRAM TLB */
+#endif
+       lwzu    r0,4(r5)
+       cmpwi   r0,0
+       beq     2f              /* 0 marks end */
+       lwzu    r1,4(r5)
+       lwzu    r2,4(r5)
+       tlbwe   r0,r4,0         /* TLB Word 0 */
+       tlbwe   r1,r4,1         /* TLB Word 1 */
+       tlbwe   r2,r4,2         /* TLB Word 2 */
+tlbnx2:        addi    r4,r4,1         /* Next TLB */
+       bdnz    1b
+
+       /*----------------------------------------------------------------*/
+       /* Continue from 'normal' start */
+       /*----------------------------------------------------------------*/
+2:
+       bl      3f
+       b       _start
+
+3:     li      r0,0
+       mtspr   SPRN_SRR1,r0            /* Keep things disabled for now */
+       mflr    r1
+       mtspr   SPRN_SRR0,r1
+       rfi
+#endif /* CONFIG_440 */
+
+/*
+ * r3 - 1st arg to board_init(): IMMP pointer
+ * r4 - 2nd arg to board_init(): boot flag
+ */
+#if !defined(CONFIG_SPL_BUILD)
+       .text
+       .long   0x27051956              /* U-Boot Magic Number                  */
+       .globl  version_string
+version_string:
+       .ascii U_BOOT_VERSION_STRING, "\0"
+
+       . = EXC_OFF_SYS_RESET
+       .globl  _start_of_vectors
+_start_of_vectors:
+
+/* Critical input. */
+       CRIT_EXCEPTION(0x100, CritcalInput, UnknownException)
+
+#ifdef CONFIG_440
+/* Machine check */
+       MCK_EXCEPTION(0x200, MachineCheck, MachineCheckException)
+#else
+       CRIT_EXCEPTION(0x200, MachineCheck, MachineCheckException)
+#endif /* CONFIG_440 */
+
+/* Data Storage exception. */
+       STD_EXCEPTION(0x300, DataStorage, UnknownException)
+
+/* Instruction Storage exception. */
+       STD_EXCEPTION(0x400, InstStorage, UnknownException)
+
+/* External Interrupt exception. */
+       STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
+
+/* Alignment exception. */
+       . = 0x600
+Alignment:
+       EXCEPTION_PROLOG(SRR0, SRR1)
+       mfspr   r4,DAR
+       stw     r4,_DAR(r21)
+       mfspr   r5,DSISR
+       stw     r5,_DSISR(r21)
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       EXC_XFER_TEMPLATE(Alignment, AlignmentException, MSR_KERNEL, COPY_EE)
+
+/* Program check exception */
+       . = 0x700
+ProgramCheck:
+       EXCEPTION_PROLOG(SRR0, SRR1)
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       EXC_XFER_TEMPLATE(ProgramCheck, ProgramCheckException,
+               MSR_KERNEL, COPY_EE)
+
+#ifdef CONFIG_440
+       STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
+       STD_EXCEPTION(0x900, Decrementer, DecrementerPITException)
+       STD_EXCEPTION(0xa00, APU, UnknownException)
+#endif
+       STD_EXCEPTION(0xc00, SystemCall, UnknownException)
+
+#ifdef CONFIG_440
+       STD_EXCEPTION(0x1300, DataTLBError, UnknownException)
+       STD_EXCEPTION(0x1400, InstructionTLBError, UnknownException)
+#else
+       STD_EXCEPTION(0x1000, PIT, DecrementerPITException)
+       STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException)
+       STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException)
+#endif
+       CRIT_EXCEPTION(0x2000, DebugBreakpoint, DebugException )
+
+       .globl  _end_of_vectors
+_end_of_vectors:
+       . = _START_OFFSET
+#endif
+       .globl  _start
+_start:
+
+#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD)
+       /*
+        * This is the entry of the real U-Boot from a board port
+        * that supports SPL booting on the PPC4xx. We only need
+        * to call board_init_f() here. Everything else has already
+        * been done in the SPL u-boot version.
+        */
+       GET_GOT                 /* initialize GOT access                */
+       bl      board_init_f    /* run 1st part of board init code (in Flash)*/
+       /* NOTREACHED - board_init_f() does not return */
+#endif
+
+/*****************************************************************************/
+#if defined(CONFIG_440)
+
+       /*----------------------------------------------------------------*/
+       /* Clear and set up some registers. */
+       /*----------------------------------------------------------------*/
+       li      r0,0x0000
+       lis     r1,0xffff
+       mtspr   SPRN_DEC,r0                     /* prevent dec exceptions */
+       mtspr   SPRN_TBWL,r0                    /* prevent fit & wdt exceptions */
+       mtspr   SPRN_TBWU,r0
+       mtspr   SPRN_TSR,r1                     /* clear all timer exception status */
+       mtspr   SPRN_TCR,r0                     /* disable all */
+       mtspr   SPRN_ESR,r0                     /* clear exception syndrome register */
+       mtxer   r0                      /* clear integer exception register */
+
+       /*----------------------------------------------------------------*/
+       /* Debug setup -- some (not very good) ice's need an event*/
+       /* to establish control :-( Define CONFIG_SYS_INIT_DBCR to the dbsr */
+       /* value you need in this case 0x8cff 0000 should do the trick */
+       /*----------------------------------------------------------------*/
+#if defined(CONFIG_SYS_INIT_DBCR)
+       lis     r1,0xffff
+       ori     r1,r1,0xffff
+       mtspr   SPRN_DBSR,r1                    /* Clear all status bits */
+       lis     r0,CONFIG_SYS_INIT_DBCR@h
+       ori     r0,r0,CONFIG_SYS_INIT_DBCR@l
+       mtspr   SPRN_DBCR0,r0
+       isync
+#endif
+
+       /*----------------------------------------------------------------*/
+       /* Setup the internal SRAM */
+       /*----------------------------------------------------------------*/
+       li      r0,0
+
+#ifdef CONFIG_SYS_INIT_RAM_DCACHE
+       /* Clear Dcache to use as RAM */
+       addis   r3,r0,CONFIG_SYS_INIT_RAM_ADDR@h
+       ori     r3,r3,CONFIG_SYS_INIT_RAM_ADDR@l
+       addis   r4,r0,CONFIG_SYS_INIT_RAM_SIZE@h
+       ori     r4,r4,CONFIG_SYS_INIT_RAM_SIZE@l
+       rlwinm. r5,r4,0,27,31
+       rlwinm  r5,r4,27,5,31
+       beq     ..d_ran
+       addi    r5,r5,0x0001
+..d_ran:
+       mtctr   r5
+..d_ag:
+       dcbz    r0,r3
+       addi    r3,r3,32
+       bdnz    ..d_ag
+
+       /*
+        * Lock the init-ram/stack in d-cache, so that other regions
+        * may use d-cache as well
+        * Note, that this current implementation locks exactly 4k
+        * of d-cache, so please make sure that you don't define a
+        * bigger init-ram area. Take a look at the lwmon5 440EPx
+        * implementation as a reference.
+        */
+       msync
+       isync
+       /* 8. set TFLOOR/NFLOOR to 8 (-> 8*16*32 bytes locked -> 4k) */
+       lis     r1,0x0201
+       ori     r1,r1,0xf808
+       mtspr   SPRN_DVLIM,r1
+       lis     r1,0x0808
+       ori     r1,r1,0x0808
+       mtspr   SPRN_DNV0,r1
+       mtspr   SPRN_DNV1,r1
+       mtspr   SPRN_DNV2,r1
+       mtspr   SPRN_DNV3,r1
+       mtspr   SPRN_DTV0,r1
+       mtspr   SPRN_DTV1,r1
+       mtspr   SPRN_DTV2,r1
+       mtspr   SPRN_DTV3,r1
+       msync
+       isync
+#endif /* CONFIG_SYS_INIT_RAM_DCACHE */
+
+       /* 440EP & 440GR are only 440er PPC's without internal SRAM */
+#if !defined(CONFIG_440EP) && !defined(CONFIG_440GR)
+       /* not all PPC's have internal SRAM usable as L2-cache */
+#if defined(CONFIG_440GX) || \
+    defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \
+    defined(CONFIG_460SX)
+       mtdcr   L2_CACHE_CFG,r0         /* Ensure L2 Cache is off */
+#elif defined(CONFIG_460EX) || defined(CONFIG_460GT) || \
+      defined(CONFIG_APM821XX)
+       lis     r1, 0x0000
+       ori     r1,r1,0x0008            /* Set L2_CACHE_CFG[RDBW]=1 */
+       mtdcr   L2_CACHE_CFG,r1
+#endif
+
+       lis     r2,0x7fff
+       ori     r2,r2,0xffff
+       mfdcr   r1,ISRAM0_DPC
+       and     r1,r1,r2                /* Disable parity check */
+       mtdcr   ISRAM0_DPC,r1
+       mfdcr   r1,ISRAM0_PMEG
+       and     r1,r1,r2                /* Disable pwr mgmt */
+       mtdcr   ISRAM0_PMEG,r1
+
+       lis     r1,0x8000               /* BAS = 8000_0000 */
+#if defined(CONFIG_440GX) || defined(CONFIG_440SP)
+       ori     r1,r1,0x0980            /* first 64k */
+       mtdcr   ISRAM0_SB0CR,r1
+       lis     r1,0x8001
+       ori     r1,r1,0x0980            /* second 64k */
+       mtdcr   ISRAM0_SB1CR,r1
+       lis     r1, 0x8002
+       ori     r1,r1, 0x0980           /* third 64k */
+       mtdcr   ISRAM0_SB2CR,r1
+       lis     r1, 0x8003
+       ori     r1,r1, 0x0980           /* fourth 64k */
+       mtdcr   ISRAM0_SB3CR,r1
+#elif defined(CONFIG_440SPE) || defined(CONFIG_460EX) || \
+      defined(CONFIG_460GT) || defined(CONFIG_APM821XX)
+       lis     r1,0x0000               /* BAS = X_0000_0000 */
+       ori     r1,r1,0x0984            /* first 64k */
+       mtdcr   ISRAM0_SB0CR,r1
+       lis     r1,0x0001
+       ori     r1,r1,0x0984            /* second 64k */
+       mtdcr   ISRAM0_SB1CR,r1
+       lis     r1, 0x0002
+       ori     r1,r1, 0x0984           /* third 64k */
+       mtdcr   ISRAM0_SB2CR,r1
+       lis     r1, 0x0003
+       ori     r1,r1, 0x0984           /* fourth 64k */
+       mtdcr   ISRAM0_SB3CR,r1
+#if defined(CONFIG_460EX) || defined(CONFIG_460GT) || \
+    defined(CONFIG_APM821XX)
+       lis     r2,0x7fff
+       ori     r2,r2,0xffff
+       mfdcr   r1,ISRAM1_DPC
+       and     r1,r1,r2                /* Disable parity check */
+       mtdcr   ISRAM1_DPC,r1
+       mfdcr   r1,ISRAM1_PMEG
+       and     r1,r1,r2                /* Disable pwr mgmt */
+       mtdcr   ISRAM1_PMEG,r1
+
+       lis     r1,0x0004               /* BAS = 4_0004_0000 */
+       ori     r1,r1,ISRAM1_SIZE       /* ocm size */
+       mtdcr   ISRAM1_SB0CR,r1
+#endif
+#elif defined(CONFIG_460SX)
+       lis     r1,0x0000               /* BAS = 0000_0000 */
+       ori     r1,r1,0x0B84            /* first 128k */
+       mtdcr   ISRAM0_SB0CR,r1
+       lis     r1,0x0001
+       ori     r1,r1,0x0B84            /* second 128k */
+       mtdcr   ISRAM0_SB1CR,r1
+       lis     r1, 0x0002
+       ori     r1,r1, 0x0B84           /* third 128k */
+       mtdcr   ISRAM0_SB2CR,r1
+       lis     r1, 0x0003
+       ori     r1,r1, 0x0B84           /* fourth 128k */
+       mtdcr   ISRAM0_SB3CR,r1
+#elif defined(CONFIG_440GP)
+       ori     r1,r1,0x0380            /* 8k rw */
+       mtdcr   ISRAM0_SB0CR,r1
+       mtdcr   ISRAM0_SB1CR,r0         /* Disable bank 1 */
+#endif
+#endif /* #if !defined(CONFIG_440EP) && !defined(CONFIG_440GR) */
+
+       /*----------------------------------------------------------------*/
+       /* Setup the stack in internal SRAM */
+       /*----------------------------------------------------------------*/
+       lis     r1,CONFIG_SYS_INIT_RAM_ADDR@h
+       ori     r1,r1,CONFIG_SYS_INIT_SP_OFFSET@l
+       li      r0,0
+       stwu    r0,-4(r1)
+       stwu    r0,-4(r1)               /* Terminate call chain */
+
+       stwu    r1,-8(r1)               /* Save back chain and move SP */
+       lis     r0,RESET_VECTOR@h       /* Address of reset vector */
+       ori     r0,r0, RESET_VECTOR@l
+       stwu    r1,-8(r1)               /* Save back chain and move SP */
+       stw     r0,+12(r1)              /* Save return addr (underflow vect) */
+
+#ifndef CONFIG_SPL_BUILD
+       GET_GOT
+#endif
+
+       bl      cpu_init_f      /* run low-level CPU init code     (from Flash) */
+       bl      board_init_f
+       /* NOTREACHED - board_init_f() does not return */
+
+#endif /* CONFIG_440 */
+
+/*****************************************************************************/
+#if defined(CONFIG_405GP) || \
+    defined(CONFIG_405EP) || defined(CONFIG_405EZ) || \
+    defined(CONFIG_405EX) || defined(CONFIG_405)
+       /*----------------------------------------------------------------------- */
+       /* Clear and set up some registers. */
+       /*----------------------------------------------------------------------- */
+       addi    r4,r0,0x0000
+#if !defined(CONFIG_405EX)
+       mtspr   SPRN_SGR,r4
+#else
+       /*
+        * On 405EX, completely clearing the SGR leads to PPC hangup
+        * upon PCIe configuration access. The PCIe memory regions
+        * need to be guarded!
+        */
+       lis     r3,0x0000
+       ori     r3,r3,0x7FFC
+       mtspr   SPRN_SGR,r3
+#endif
+       mtspr   SPRN_DCWR,r4
+       mtesr   r4                      /* clear Exception Syndrome Reg */
+       mttcr   r4                      /* clear Timer Control Reg */
+       mtxer   r4                      /* clear Fixed-Point Exception Reg */
+       mtevpr  r4                      /* clear Exception Vector Prefix Reg */
+       addi    r4,r0,(0xFFFF-0x10000)          /* set r4 to 0xFFFFFFFF (status in the */
+                                       /* dbsr is cleared by setting bits to 1) */
+       mtdbsr  r4                      /* clear/reset the dbsr */
+
+       /* Invalidate the i- and d-caches. */
+       bl      invalidate_icache
+       bl      invalidate_dcache
+
+       /* Set-up icache cacheability. */
+       lis     r4, CONFIG_SYS_ICACHE_SACR_VALUE@h
+       ori     r4, r4, CONFIG_SYS_ICACHE_SACR_VALUE@l
+       mticcr  r4
+       isync
+
+       /* Set-up dcache cacheability. */
+       lis     r4, CONFIG_SYS_DCACHE_SACR_VALUE@h
+       ori     r4, r4, CONFIG_SYS_DCACHE_SACR_VALUE@l
+       mtdccr  r4
+
+#if !(defined(CONFIG_SYS_EBC_PB0AP) && defined(CONFIG_SYS_EBC_PB0CR))\
+                               && !defined (CONFIG_XILINX_405)
+       /*----------------------------------------------------------------------- */
+       /* Tune the speed and size for flash CS0  */
+       /*----------------------------------------------------------------------- */
+       bl      ext_bus_cntlr_init
+#endif
+
+#if !(defined(CONFIG_SYS_INIT_DCACHE_CS) || defined(CONFIG_SYS_TEMP_STACK_OCM))
+       /*
+        * For boards that don't have OCM and can't use the data cache
+        * for their primordial stack, setup stack here directly after the
+        * SDRAM is initialized in ext_bus_cntlr_init.
+        */
+       lis     r1, CONFIG_SYS_INIT_RAM_ADDR@h
+       ori     r1,r1,CONFIG_SYS_INIT_SP_OFFSET /* set up the stack in SDRAM */
+
+       li      r0, 0                   /* Make room for stack frame header and */
+       stwu    r0, -4(r1)              /* clear final stack frame so that      */
+       stwu    r0, -4(r1)              /* stack backtraces terminate cleanly   */
+       /*
+        * Set up a dummy frame to store reset vector as return address.
+        * this causes stack underflow to reset board.
+        */
+       stwu    r1, -8(r1)              /* Save back chain and move SP */
+       lis     r0, RESET_VECTOR@h      /* Address of reset vector */
+       ori     r0, r0, RESET_VECTOR@l
+       stwu    r1, -8(r1)              /* Save back chain and move SP */
+       stw     r0, +12(r1)             /* Save return addr (underflow vect) */
+#endif /* !(CONFIG_SYS_INIT_DCACHE_CS  || !CONFIG_SYS_TEM_STACK_OCM) */
+
+#if defined(CONFIG_405EP)
+       /*----------------------------------------------------------------------- */
+       /* DMA Status, clear to come up clean */
+       /*----------------------------------------------------------------------- */
+       addis   r3,r0, 0xFFFF           /* Clear all existing DMA status */
+       ori     r3,r3, 0xFFFF
+       mtdcr   DMASR, r3
+
+       bl      ppc405ep_init           /* do ppc405ep specific init */
+#endif /* CONFIG_405EP */
+
+#if defined(CONFIG_SYS_OCM_DATA_ADDR) && defined(CONFIG_SYS_OCM_DATA_SIZE)
+#if defined(CONFIG_405EZ)
+       /********************************************************************
+        * Setup OCM - On Chip Memory - PPC405EZ uses OCM Controller V2
+        *******************************************************************/
+       /*
+        * We can map the OCM on the PLB3, so map it at
+        * CONFIG_SYS_OCM_DATA_ADDR + 0x8000
+        */
+       lis     r3,CONFIG_SYS_OCM_DATA_ADDR@h   /* OCM location */
+       ori     r3,r3,CONFIG_SYS_OCM_DATA_ADDR@l
+       ori     r3,r3,0x0270            /* 16K for Bank 1, R/W/Enable */
+       mtdcr   OCM0_PLBCR1,r3          /* Set PLB Access */
+       ori     r3,r3,0x4000            /* Add 0x4000 for bank 2 */
+       mtdcr   OCM0_PLBCR2,r3          /* Set PLB Access */
+       isync
+
+       lis     r3,CONFIG_SYS_OCM_DATA_ADDR@h   /* OCM location */
+       ori     r3,r3,CONFIG_SYS_OCM_DATA_ADDR@l
+       ori     r3,r3,0x0270            /* 16K for Bank 1, R/W/Enable */
+       mtdcr   OCM0_DSRC1, r3          /* Set Data Side */
+       mtdcr   OCM0_ISRC1, r3          /* Set Instruction Side */
+       ori     r3,r3,0x4000            /* Add 0x4000 for bank 2 */
+       mtdcr   OCM0_DSRC2, r3          /* Set Data Side */
+       mtdcr   OCM0_ISRC2, r3          /* Set Instruction Side */
+       addis   r3,0,0x0800             /* OCM Data Parity Disable - 1 Wait State */
+       mtdcr   OCM0_DISDPC,r3
+
+       isync
+#else /* CONFIG_405EZ */
+       /********************************************************************
+        * Setup OCM - On Chip Memory
+        *******************************************************************/
+       /* Setup OCM */
+       lis     r0, 0x7FFF
+       ori     r0, r0, 0xFFFF
+       mfdcr   r3, OCM0_ISCNTL         /* get instr-side IRAM config */
+       mfdcr   r4, OCM0_DSCNTL         /* get data-side IRAM config */
+       and     r3, r3, r0              /* disable data-side IRAM */
+       and     r4, r4, r0              /* disable data-side IRAM */
+       mtdcr   OCM0_ISCNTL, r3         /* set instr-side IRAM config */
+       mtdcr   OCM0_DSCNTL, r4         /* set data-side IRAM config */
+       isync
+
+       lis     r3,CONFIG_SYS_OCM_DATA_ADDR@h   /* OCM location */
+       ori     r3,r3,CONFIG_SYS_OCM_DATA_ADDR@l
+       mtdcr   OCM0_DSARC, r3
+       addis   r4, 0, 0xC000           /* OCM data area enabled */
+       mtdcr   OCM0_DSCNTL, r4
+       isync
+#endif /* CONFIG_405EZ */
+#endif
+
+       /*----------------------------------------------------------------------- */
+       /* Setup temporary stack in DCACHE or OCM if needed for SDRAM SPD. */
+       /*----------------------------------------------------------------------- */
+#ifdef CONFIG_SYS_INIT_DCACHE_CS
+       li      r4, PBxAP
+       mtdcr   EBC0_CFGADDR, r4
+       lis     r4, CONFIG_SYS_INIT_DCACHE_PBxAR@h
+       ori     r4, r4, CONFIG_SYS_INIT_DCACHE_PBxAR@l
+       mtdcr   EBC0_CFGDATA, r4
+
+       addi    r4, 0, PBxCR
+       mtdcr   EBC0_CFGADDR, r4
+       lis     r4, CONFIG_SYS_INIT_DCACHE_PBxCR@h
+       ori     r4, r4, CONFIG_SYS_INIT_DCACHE_PBxCR@l
+       mtdcr   EBC0_CFGDATA, r4
+
+       /*
+        * Enable the data cache for the 128MB storage access control region
+        * at CONFIG_SYS_INIT_RAM_ADDR.
+        */
+       mfdccr  r4
+       oris    r4, r4, PPC_128MB_SACR_VALUE(CONFIG_SYS_INIT_RAM_ADDR)@h
+       ori     r4, r4, PPC_128MB_SACR_VALUE(CONFIG_SYS_INIT_RAM_ADDR)@l
+       mtdccr  r4
+
+       /*
+        * Preallocate data cache lines to be used to avoid a subsequent
+        * cache miss and an ensuing machine check exception when exceptions
+        * are enabled.
+        */
+       li      r0, 0
+
+       lis     r3, CONFIG_SYS_INIT_RAM_ADDR@h
+       ori     r3, r3, CONFIG_SYS_INIT_RAM_ADDR@l
+
+       lis     r4, CONFIG_SYS_INIT_RAM_SIZE@h
+       ori     r4, r4, CONFIG_SYS_INIT_RAM_SIZE@l
+
+       /*
+        * Convert the size, in bytes, to the number of cache lines/blocks
+        * to preallocate.
+        */
+       clrlwi. r5, r4, (32 - L1_CACHE_SHIFT)
+       srwi    r5, r4, L1_CACHE_SHIFT
+       beq     ..load_counter
+       addi    r5, r5, 0x0001
+..load_counter:
+       mtctr   r5
+
+       /* Preallocate the computed number of cache blocks. */
+..alloc_dcache_block:
+       dcba    r0, r3
+       addi    r3, r3, L1_CACHE_BYTES
+       bdnz    ..alloc_dcache_block
+       sync
+
+       /*
+        * Load the initial stack pointer and data area and convert the size,
+        * in bytes, to the number of words to initialize to a known value.
+        */
+       lis     r1, CONFIG_SYS_INIT_RAM_ADDR@h
+       ori     r1, r1, CONFIG_SYS_INIT_SP_OFFSET@l
+
+       lis     r4, (CONFIG_SYS_INIT_RAM_SIZE >> 2)@h
+       ori     r4, r4, (CONFIG_SYS_INIT_RAM_SIZE >> 2)@l
+       mtctr   r4
+
+       lis     r2, CONFIG_SYS_INIT_RAM_ADDR@h
+       ori     r2, r2, CONFIG_SYS_INIT_RAM_SIZE@l
+
+       lis     r4, CONFIG_SYS_INIT_RAM_PATTERN@h
+       ori     r4, r4, CONFIG_SYS_INIT_RAM_PATTERN@l
+
+..stackloop:
+       stwu    r4, -4(r2)
+       bdnz    ..stackloop
+
+       /*
+        * Make room for stack frame header and clear final stack frame so
+        * that stack backtraces terminate cleanly.
+        */
+       stwu    r0, -4(r1)
+       stwu    r0, -4(r1)
+
+       /*
+        * Set up a dummy frame to store reset vector as return address.
+        * this causes stack underflow to reset board.
+        */
+       stwu    r1, -8(r1)              /* Save back chain and move SP */
+       addis   r0, 0, RESET_VECTOR@h   /* Address of reset vector */
+       ori     r0, r0, RESET_VECTOR@l
+       stwu    r1, -8(r1)              /* Save back chain and move SP */
+       stw     r0, +12(r1)             /* Save return addr (underflow vect) */
+
+#elif defined(CONFIG_SYS_TEMP_STACK_OCM) && \
+       (defined(CONFIG_SYS_OCM_DATA_ADDR) && defined(CONFIG_SYS_OCM_DATA_SIZE))
+       /*
+        * Stack in OCM.
+        */
+
+       /* Set up Stack at top of OCM */
+       lis     r1, (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET)@h
+       ori     r1, r1, (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET)@l
+
+       /* Set up a zeroized stack frame so that backtrace works right */
+       li      r0, 0
+       stwu    r0, -4(r1)
+       stwu    r0, -4(r1)
+
+       /*
+        * Set up a dummy frame to store reset vector as return address.
+        * this causes stack underflow to reset board.
+        */
+       stwu    r1, -8(r1)              /* Save back chain and move SP */
+       lis     r0, RESET_VECTOR@h      /* Address of reset vector */
+       ori     r0, r0, RESET_VECTOR@l
+       stwu    r1, -8(r1)              /* Save back chain and move SP */
+       stw     r0, +12(r1)             /* Save return addr (underflow vect) */
+#endif /* CONFIG_SYS_INIT_DCACHE_CS */
+
+       GET_GOT                 /* initialize GOT access                        */
+
+       bl      cpu_init_f      /* run low-level CPU init code     (from Flash) */
+
+       bl      board_init_f    /* run first part of init code (from Flash)     */
+       /* NOTREACHED - board_init_f() does not return */
+
+#endif /* CONFIG_405GP || CONFIG_405 || CONFIG_405EP */
+       /*----------------------------------------------------------------------- */
+
+
+#if !defined(CONFIG_SPL_BUILD)
+/*
+ * This code finishes saving the registers to the exception frame
+ * and jumps to the appropriate handler for the exception.
+ * Register r21 is pointer into trap frame, r1 has new stack pointer.
+ */
+       .globl  transfer_to_handler
+transfer_to_handler:
+       stw     r22,_NIP(r21)
+       lis     r22,MSR_POW@h
+       andc    r23,r23,r22
+       stw     r23,_MSR(r21)
+       SAVE_GPR(7, r21)
+       SAVE_4GPRS(8, r21)
+       SAVE_8GPRS(12, r21)
+       SAVE_8GPRS(24, r21)
+       mflr    r23
+       andi.   r24,r23,0x3f00          /* get vector offset */
+       stw     r24,TRAP(r21)
+       li      r22,0
+       stw     r22,RESULT(r21)
+       mtspr   SPRG2,r22               /* r1 is now kernel sp */
+       lwz     r24,0(r23)              /* virtual address of handler */
+       lwz     r23,4(r23)              /* where to go when done */
+       mtspr   SRR0,r24
+       mtspr   SRR1,r20
+       mtlr    r23
+       SYNC
+       rfi                             /* jump to handler, enable MMU */
+
+int_return:
+       mfmsr   r28             /* Disable interrupts */
+       li      r4,0
+       ori     r4,r4,MSR_EE
+       andc    r28,r28,r4
+       SYNC                    /* Some chip revs need this... */
+       mtmsr   r28
+       SYNC
+       lwz     r2,_CTR(r1)
+       lwz     r0,_LINK(r1)
+       mtctr   r2
+       mtlr    r0
+       lwz     r2,_XER(r1)
+       lwz     r0,_CCR(r1)
+       mtspr   XER,r2
+       mtcrf   0xFF,r0
+       REST_10GPRS(3, r1)
+       REST_10GPRS(13, r1)
+       REST_8GPRS(23, r1)
+       REST_GPR(31, r1)
+       lwz     r2,_NIP(r1)     /* Restore environment */
+       lwz     r0,_MSR(r1)
+       mtspr   SRR0,r2
+       mtspr   SRR1,r0
+       lwz     r0,GPR0(r1)
+       lwz     r2,GPR2(r1)
+       lwz     r1,GPR1(r1)
+       SYNC
+       rfi
+
+crit_return:
+       mfmsr   r28             /* Disable interrupts */
+       li      r4,0
+       ori     r4,r4,MSR_EE
+       andc    r28,r28,r4
+       SYNC                    /* Some chip revs need this... */
+       mtmsr   r28
+       SYNC
+       lwz     r2,_CTR(r1)
+       lwz     r0,_LINK(r1)
+       mtctr   r2
+       mtlr    r0
+       lwz     r2,_XER(r1)
+       lwz     r0,_CCR(r1)
+       mtspr   XER,r2
+       mtcrf   0xFF,r0
+       REST_10GPRS(3, r1)
+       REST_10GPRS(13, r1)
+       REST_8GPRS(23, r1)
+       REST_GPR(31, r1)
+       lwz     r2,_NIP(r1)     /* Restore environment */
+       lwz     r0,_MSR(r1)
+       mtspr   SPRN_CSRR0,r2
+       mtspr   SPRN_CSRR1,r0
+       lwz     r0,GPR0(r1)
+       lwz     r2,GPR2(r1)
+       lwz     r1,GPR1(r1)
+       SYNC
+       rfci
+
+#ifdef CONFIG_440
+mck_return:
+       mfmsr   r28             /* Disable interrupts */
+       li      r4,0
+       ori     r4,r4,MSR_EE
+       andc    r28,r28,r4
+       SYNC                    /* Some chip revs need this... */
+       mtmsr   r28
+       SYNC
+       lwz     r2,_CTR(r1)
+       lwz     r0,_LINK(r1)
+       mtctr   r2
+       mtlr    r0
+       lwz     r2,_XER(r1)
+       lwz     r0,_CCR(r1)
+       mtspr   XER,r2
+       mtcrf   0xFF,r0
+       REST_10GPRS(3, r1)
+       REST_10GPRS(13, r1)
+       REST_8GPRS(23, r1)
+       REST_GPR(31, r1)
+       lwz     r2,_NIP(r1)     /* Restore environment */
+       lwz     r0,_MSR(r1)
+       mtspr   SPRN_MCSRR0,r2
+       mtspr   SPRN_MCSRR1,r0
+       lwz     r0,GPR0(r1)
+       lwz     r2,GPR2(r1)
+       lwz     r1,GPR1(r1)
+       SYNC
+       rfmci
+#endif /* CONFIG_440 */
+
+
+       .globl get_pvr
+get_pvr:
+       mfspr   r3, PVR
+       blr
+
+/*------------------------------------------------------------------------------- */
+/* Function:    out16 */
+/* Description:         Output 16 bits */
+/*------------------------------------------------------------------------------- */
+       .globl  out16
+out16:
+       sth     r4,0x0000(r3)
+       blr
+
+/*------------------------------------------------------------------------------- */
+/* Function:    out16r */
+/* Description:         Byte reverse and output 16 bits */
+/*------------------------------------------------------------------------------- */
+       .globl  out16r
+out16r:
+       sthbrx  r4,r0,r3
+       blr
+
+/*------------------------------------------------------------------------------- */
+/* Function:    out32r */
+/* Description:         Byte reverse and output 32 bits */
+/*------------------------------------------------------------------------------- */
+       .globl  out32r
+out32r:
+       stwbrx  r4,r0,r3
+       blr
+
+/*------------------------------------------------------------------------------- */
+/* Function:    in16 */
+/* Description:         Input 16 bits */
+/*------------------------------------------------------------------------------- */
+       .globl  in16
+in16:
+       lhz     r3,0x0000(r3)
+       blr
+
+/*------------------------------------------------------------------------------- */
+/* Function:    in16r */
+/* Description:         Input 16 bits and byte reverse */
+/*------------------------------------------------------------------------------- */
+       .globl  in16r
+in16r:
+       lhbrx   r3,r0,r3
+       blr
+
+/*------------------------------------------------------------------------------- */
+/* Function:    in32r */
+/* Description:         Input 32 bits and byte reverse */
+/*------------------------------------------------------------------------------- */
+       .globl  in32r
+in32r:
+       lwbrx   r3,r0,r3
+       blr
+
+#if !defined(CONFIG_SPL_BUILD)
+/*
+ * void relocate_code (addr_sp, gd, addr_moni)
+ *
+ * This "function" does not return, instead it continues in RAM
+ * after relocating the monitor code.
+ *
+ * r3 = Relocated stack pointer
+ * r4 = Relocated global data pointer
+ * r5 = Relocated text pointer
+ */
+       .globl  relocate_code
+relocate_code:
+#if defined(CONFIG_4xx_DCACHE) || defined(CONFIG_SYS_INIT_DCACHE_CS)
+       /*
+        * We need to flush the initial global data (gd_t) and bd_info
+        * before the dcache will be invalidated.
+        */
+
+       /* Save registers */
+       mr      r9, r3
+       mr      r10, r4
+       mr      r11, r5
+
+       /*
+        * Flush complete dcache, this is faster than flushing the
+        * ranges for global_data and bd_info instead.
+        */
+       bl      flush_dcache
+
+#if defined(CONFIG_SYS_INIT_DCACHE_CS)
+       /*
+        * Undo the earlier data cache set-up for the primordial stack and
+        * data area. First, invalidate the data cache and then disable data
+        * cacheability for that area. Finally, restore the EBC values, if
+        * any.
+        */
+
+       /* Invalidate the primordial stack and data area in cache */
+       lis     r3, CONFIG_SYS_INIT_RAM_ADDR@h
+       ori     r3, r3, CONFIG_SYS_INIT_RAM_ADDR@l
+
+       lis     r4, CONFIG_SYS_INIT_RAM_SIZE@h
+       ori     r4, r4, CONFIG_SYS_INIT_RAM_SIZE@l
+       add     r4, r4, r3
+
+       bl      invalidate_dcache_range
+
+       /* Disable cacheability for the region */
+       mfdccr  r3
+       lis     r4, ~PPC_128MB_SACR_VALUE(CONFIG_SYS_INIT_RAM_ADDR)@h
+       ori     r4, r4, ~PPC_128MB_SACR_VALUE(CONFIG_SYS_INIT_RAM_ADDR)@l
+       and     r3, r3, r4
+       mtdccr  r3
+
+       /* Restore the EBC parameters */
+       li      r3, PBxAP
+       mtdcr   EBC0_CFGADDR, r3
+       lis     r3, PBxAP_VAL@h
+       ori     r3, r3, PBxAP_VAL@l
+       mtdcr   EBC0_CFGDATA, r3
+
+       li      r3, PBxCR
+       mtdcr   EBC0_CFGADDR, r3
+       lis     r3, PBxCR_VAL@h
+       ori     r3, r3, PBxCR_VAL@l
+       mtdcr   EBC0_CFGDATA, r3
+#endif /* defined(CONFIG_SYS_INIT_DCACHE_CS) */
+
+       /* Restore registers */
+       mr      r3, r9
+       mr      r4, r10
+       mr      r5, r11
+#endif /* defined(CONFIG_4xx_DCACHE) || defined(CONFIG_SYS_INIT_DCACHE_CS) */
+
+#ifdef CONFIG_SYS_INIT_RAM_DCACHE
+       /*
+        * Unlock the previously locked d-cache
+        */
+       msync
+       isync
+       /* set TFLOOR/NFLOOR to 0 again */
+       lis     r6,0x0001
+       ori     r6,r6,0xf800
+       mtspr   SPRN_DVLIM,r6
+       lis     r6,0x0000
+       ori     r6,r6,0x0000
+       mtspr   SPRN_DNV0,r6
+       mtspr   SPRN_DNV1,r6
+       mtspr   SPRN_DNV2,r6
+       mtspr   SPRN_DNV3,r6
+       mtspr   SPRN_DTV0,r6
+       mtspr   SPRN_DTV1,r6
+       mtspr   SPRN_DTV2,r6
+       mtspr   SPRN_DTV3,r6
+       msync
+       isync
+
+       /* Invalidate data cache, now no longer our stack */
+       dccci   0,0
+       sync
+       isync
+#endif /* CONFIG_SYS_INIT_RAM_DCACHE */
+
+       /*
+        * On some 440er platforms the cache is enabled in the first TLB (Boot-CS)
+        * to speed up the boot process. Now this cache needs to be disabled.
+        */
+#if defined(CONFIG_440)
+       /* Clear all potential pending exceptions */
+       mfspr   r1,SPRN_MCSR
+       mtspr   SPRN_MCSR,r1
+       addi    r1,r0,CONFIG_SYS_TLB_FOR_BOOT_FLASH     /* Use defined TLB */
+       tlbre   r0,r1,0x0002            /* Read contents */
+       ori     r0,r0,0x0c00            /* Or in the inhibit, write through bit */
+       tlbwe   r0,r1,0x0002            /* Save it out */
+       sync
+       isync
+#endif /* defined(CONFIG_440) */
+       mr      r1,  r3         /* Set new stack pointer                */
+       mr      r9,  r4         /* Save copy of Init Data pointer       */
+       mr      r10, r5         /* Save copy of Destination Address     */
+
+       GET_GOT
+       mr      r3,  r5                         /* Destination Address  */
+       lis     r4, CONFIG_SYS_MONITOR_BASE@h           /* Source      Address  */
+       ori     r4, r4, CONFIG_SYS_MONITOR_BASE@l
+       lwz     r5, GOT(__init_end)
+       sub     r5, r5, r4
+       li      r6, L1_CACHE_BYTES              /* Cache Line Size      */
+
+       /*
+        * Fix GOT pointer:
+        *
+        * New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) + Destination Address
+        *
+        * Offset:
+        */
+       sub     r15, r10, r4
+
+       /* First our own GOT */
+       add     r12, r12, r15
+       /* then the one used by the C code */
+       add     r30, r30, r15
+
+       /*
+        * Now relocate code
+        */
+
+       cmplw   cr1,r3,r4
+       addi    r0,r5,3
+       srwi.   r0,r0,2
+       beq     cr1,4f          /* In place copy is not necessary       */
+       beq     7f              /* Protect against 0 count              */
+       mtctr   r0
+       bge     cr1,2f
+
+       la      r8,-4(r4)
+       la      r7,-4(r3)
+1:     lwzu    r0,4(r8)
+       stwu    r0,4(r7)
+       bdnz    1b
+       b       4f
+
+2:     slwi    r0,r0,2
+       add     r8,r4,r0
+       add     r7,r3,r0
+3:     lwzu    r0,-4(r8)
+       stwu    r0,-4(r7)
+       bdnz    3b
+
+/*
+ * Now flush the cache: note that we must start from a cache aligned
+ * address. Otherwise we might miss one cache line.
+ */
+4:     cmpwi   r6,0
+       add     r5,r3,r5
+       beq     7f              /* Always flush prefetch queue in any case */
+       subi    r0,r6,1
+       andc    r3,r3,r0
+       mr      r4,r3
+5:     dcbst   0,r4
+       add     r4,r4,r6
+       cmplw   r4,r5
+       blt     5b
+       sync                    /* Wait for all dcbst to complete on bus */
+       mr      r4,r3
+6:     icbi    0,r4
+       add     r4,r4,r6
+       cmplw   r4,r5
+       blt     6b
+7:     sync                    /* Wait for all icbi to complete on bus */
+       isync
+
+/*
+ * We are done. Do not return, instead branch to second part of board
+ * initialization, now running from RAM.
+ */
+
+       addi    r0, r10, in_ram - _start + _START_OFFSET
+       mtlr    r0
+       blr                             /* NEVER RETURNS! */
+
+in_ram:
+
+       /*
+        * Relocation Function, r12 point to got2+0x8000
+        *
+        * Adjust got2 pointers, no need to check for 0, this code
+        * already puts a few entries in the table.
+        */
+       li      r0,__got2_entries@sectoff@l
+       la      r3,GOT(_GOT2_TABLE_)
+       lwz     r11,GOT(_GOT2_TABLE_)
+       mtctr   r0
+       sub     r11,r3,r11
+       addi    r3,r3,-4
+1:     lwzu    r0,4(r3)
+       cmpwi   r0,0
+       beq-    2f
+       add     r0,r0,r11
+       stw     r0,0(r3)
+2:     bdnz    1b
+
+       /*
+        * Now adjust the fixups and the pointers to the fixups
+        * in case we need to move ourselves again.
+        */
+       li      r0,__fixup_entries@sectoff@l
+       lwz     r3,GOT(_FIXUP_TABLE_)
+       cmpwi   r0,0
+       mtctr   r0
+       addi    r3,r3,-4
+       beq     4f
+3:     lwzu    r4,4(r3)
+       lwzux   r0,r4,r11
+       cmpwi   r0,0
+       add     r0,r0,r11
+       stw     r4,0(r3)
+       beq-    5f
+       stw     r0,0(r4)
+5:     bdnz    3b
+4:
+clear_bss:
+       /*
+        * Now clear BSS segment
+        */
+       lwz     r3,GOT(__bss_start)
+       lwz     r4,GOT(__bss_end)
+
+       cmplw   0, r3, r4
+       beq     7f
+
+       li      r0, 0
+
+       andi.   r5, r4, 3
+       beq     6f
+       sub     r4, r4, r5
+       mtctr   r5
+       mr      r5, r4
+5:     stb     r0, 0(r5)
+       addi    r5, r5, 1
+       bdnz    5b
+6:
+       stw     r0, 0(r3)
+       addi    r3, r3, 4
+       cmplw   0, r3, r4
+       bne     6b
+
+7:
+       mr      r3, r9          /* Init Data pointer            */
+       mr      r4, r10         /* Destination Address          */
+       bl      board_init_r
+
+       /*
+        * Copy exception vector code to low memory
+        *
+        * r3: dest_addr
+        * r7: source address, r8: end address, r9: target address
+        */
+       .globl  trap_init
+trap_init:
+       mflr    r4                      /* save link register           */
+       GET_GOT
+       lwz     r7, GOT(_start_of_vectors)
+       lwz     r8, GOT(_end_of_vectors)
+
+       li      r9, 0x100               /* reset vector always at 0x100 */
+
+       cmplw   0, r7, r8
+       bgelr                           /* return if r7>=r8 - just in case */
+1:
+       lwz     r0, 0(r7)
+       stw     r0, 0(r9)
+       addi    r7, r7, 4
+       addi    r9, r9, 4
+       cmplw   0, r7, r8
+       bne     1b
+
+       /*
+        * relocate `hdlr' and `int_return' entries
+        */
+       li      r7, .L_MachineCheck - _start + _START_OFFSET
+       li      r8, Alignment - _start + _START_OFFSET
+2:
+       bl      trap_reloc
+       addi    r7, r7, 0x100           /* next exception vector */
+       cmplw   0, r7, r8
+       blt     2b
+
+       li      r7, .L_Alignment - _start + _START_OFFSET
+       bl      trap_reloc
+
+       li      r7, .L_ProgramCheck - _start + _START_OFFSET
+       bl      trap_reloc
+
+#ifdef CONFIG_440
+       li      r7, .L_FPUnavailable - _start + _START_OFFSET
+       bl      trap_reloc
+
+       li      r7, .L_Decrementer - _start + _START_OFFSET
+       bl      trap_reloc
+
+       li      r7, .L_APU - _start + _START_OFFSET
+       bl      trap_reloc
+
+       li      r7, .L_InstructionTLBError - _start + _START_OFFSET
+       bl      trap_reloc
+
+       li      r7, .L_DataTLBError - _start + _START_OFFSET
+       bl      trap_reloc
+#else /* CONFIG_440 */
+       li      r7, .L_PIT - _start + _START_OFFSET
+       bl      trap_reloc
+
+       li      r7, .L_InstructionTLBMiss - _start + _START_OFFSET
+       bl      trap_reloc
+
+       li      r7, .L_DataTLBMiss - _start + _START_OFFSET
+       bl      trap_reloc
+#endif /* CONFIG_440 */
+
+       li      r7, .L_DebugBreakpoint - _start + _START_OFFSET
+       bl      trap_reloc
+
+#if !defined(CONFIG_440)
+       addi    r7,r0,0x1000            /* set ME bit (Machine Exceptions) */
+       oris    r7,r7,0x0002            /* set CE bit (Critical Exceptions) */
+       mtmsr   r7                      /* change MSR */
+#else
+       bl      __440_msr_set
+       b       __440_msr_continue
+
+__440_msr_set:
+       addi    r7,r0,0x1000            /* set ME bit (Machine Exceptions) */
+       oris    r7,r7,0x0002            /* set CE bit (Critical Exceptions) */
+       mtspr   SPRN_SRR1,r7
+       mflr    r7
+       mtspr   SPRN_SRR0,r7
+       rfi
+__440_msr_continue:
+#endif
+
+       mtlr    r4                      /* restore link register        */
+       blr
+#endif /* CONFIG_SPL_BUILD */
+
+#if defined(CONFIG_440)
+/*----------------------------------------------------------------------------+
+| dcbz_area.
++----------------------------------------------------------------------------*/
+       function_prolog(dcbz_area)
+       rlwinm. r5,r4,0,27,31
+       rlwinm  r5,r4,27,5,31
+       beq     ..d_ra2
+       addi    r5,r5,0x0001
+..d_ra2:mtctr  r5
+..d_ag2:dcbz   r0,r3
+       addi    r3,r3,32
+       bdnz    ..d_ag2
+       sync
+       blr
+       function_epilog(dcbz_area)
+#endif /* CONFIG_440 */
+#endif /* CONFIG_SPL_BUILD */
+
+/*------------------------------------------------------------------------------- */
+/* Function:    in8 */
+/* Description:         Input 8 bits */
+/*------------------------------------------------------------------------------- */
+       .globl  in8
+in8:
+       lbz     r3,0x0000(r3)
+       blr
+
+/*------------------------------------------------------------------------------- */
+/* Function:    out8 */
+/* Description:         Output 8 bits */
+/*------------------------------------------------------------------------------- */
+       .globl  out8
+out8:
+       stb     r4,0x0000(r3)
+       blr
+
+/*------------------------------------------------------------------------------- */
+/* Function:    out32 */
+/* Description:         Output 32 bits */
+/*------------------------------------------------------------------------------- */
+       .globl  out32
+out32:
+       stw     r4,0x0000(r3)
+       blr
+
+/*------------------------------------------------------------------------------- */
+/* Function:    in32 */
+/* Description:         Input 32 bits */
+/*------------------------------------------------------------------------------- */
+       .globl  in32
+in32:
+       lwz     3,0x0000(3)
+       blr
+
+/**************************************************************************/
+/* PPC405EP specific stuff                                               */
+/**************************************************************************/
+#ifdef CONFIG_405EP
+ppc405ep_init:
+
+#ifdef CONFIG_BUBINGA
+       /*
+        * Initialize EBC chip selects 1 & 4 and GPIO pins (for alternate
+        * function) to support FPGA and NVRAM accesses below.
+        */
+
+       lis     r3,GPIO0_OSRH@h         /* config GPIO output select */
+       ori     r3,r3,GPIO0_OSRH@l
+       lis     r4,CONFIG_SYS_GPIO0_OSRH@h
+       ori     r4,r4,CONFIG_SYS_GPIO0_OSRH@l
+       stw     r4,0(r3)
+       lis     r3,GPIO0_OSRL@h
+       ori     r3,r3,GPIO0_OSRL@l
+       lis     r4,CONFIG_SYS_GPIO0_OSRL@h
+       ori     r4,r4,CONFIG_SYS_GPIO0_OSRL@l
+       stw     r4,0(r3)
+
+       lis     r3,GPIO0_ISR1H@h        /* config GPIO input select */
+       ori     r3,r3,GPIO0_ISR1H@l
+       lis     r4,CONFIG_SYS_GPIO0_ISR1H@h
+       ori     r4,r4,CONFIG_SYS_GPIO0_ISR1H@l
+       stw     r4,0(r3)
+       lis     r3,GPIO0_ISR1L@h
+       ori     r3,r3,GPIO0_ISR1L@l
+       lis     r4,CONFIG_SYS_GPIO0_ISR1L@h
+       ori     r4,r4,CONFIG_SYS_GPIO0_ISR1L@l
+       stw     r4,0(r3)
+
+       lis     r3,GPIO0_TSRH@h         /* config GPIO three-state select */
+       ori     r3,r3,GPIO0_TSRH@l
+       lis     r4,CONFIG_SYS_GPIO0_TSRH@h
+       ori     r4,r4,CONFIG_SYS_GPIO0_TSRH@l
+       stw     r4,0(r3)
+       lis     r3,GPIO0_TSRL@h
+       ori     r3,r3,GPIO0_TSRL@l
+       lis     r4,CONFIG_SYS_GPIO0_TSRL@h
+       ori     r4,r4,CONFIG_SYS_GPIO0_TSRL@l
+       stw     r4,0(r3)
+
+       lis     r3,GPIO0_TCR@h          /* config GPIO driver output enables */
+       ori     r3,r3,GPIO0_TCR@l
+       lis     r4,CONFIG_SYS_GPIO0_TCR@h
+       ori     r4,r4,CONFIG_SYS_GPIO0_TCR@l
+       stw     r4,0(r3)
+
+       li      r3,PB1AP                /* program EBC bank 1 for RTC access */
+       mtdcr   EBC0_CFGADDR,r3
+       lis     r3,CONFIG_SYS_EBC_PB1AP@h
+       ori     r3,r3,CONFIG_SYS_EBC_PB1AP@l
+       mtdcr   EBC0_CFGDATA,r3
+       li      r3,PB1CR
+       mtdcr   EBC0_CFGADDR,r3
+       lis     r3,CONFIG_SYS_EBC_PB1CR@h
+       ori     r3,r3,CONFIG_SYS_EBC_PB1CR@l
+       mtdcr   EBC0_CFGDATA,r3
+
+       li      r3,PB1AP                /* program EBC bank 1 for RTC access */
+       mtdcr   EBC0_CFGADDR,r3
+       lis     r3,CONFIG_SYS_EBC_PB1AP@h
+       ori     r3,r3,CONFIG_SYS_EBC_PB1AP@l
+       mtdcr   EBC0_CFGDATA,r3
+       li      r3,PB1CR
+       mtdcr   EBC0_CFGADDR,r3
+       lis     r3,CONFIG_SYS_EBC_PB1CR@h
+       ori     r3,r3,CONFIG_SYS_EBC_PB1CR@l
+       mtdcr   EBC0_CFGDATA,r3
+
+       li      r3,PB4AP                /* program EBC bank 4 for FPGA access */
+       mtdcr   EBC0_CFGADDR,r3
+       lis     r3,CONFIG_SYS_EBC_PB4AP@h
+       ori     r3,r3,CONFIG_SYS_EBC_PB4AP@l
+       mtdcr   EBC0_CFGDATA,r3
+       li      r3,PB4CR
+       mtdcr   EBC0_CFGADDR,r3
+       lis     r3,CONFIG_SYS_EBC_PB4CR@h
+       ori     r3,r3,CONFIG_SYS_EBC_PB4CR@l
+       mtdcr   EBC0_CFGDATA,r3
+#endif
+
+       /*
+       !-----------------------------------------------------------------------
+       ! Check to see if chip is in bypass mode.
+       ! If so, write stored CPC0_PLLMR0 and CPC0_PLLMR1 values and perform a
+       ! CPU reset   Otherwise, skip this step and keep going.
+       ! Note:  Running BIOS in bypass mode is not supported since PLB speed
+       !        will not be fast enough for the SDRAM (min 66MHz)
+       !-----------------------------------------------------------------------
+       */
+       mfdcr   r5, CPC0_PLLMR1
+       rlwinm  r4,r5,1,0x1             /* get system clock source (SSCS) */
+       cmpi    cr0,0,r4,0x1
+
+       beq    pll_done                 /* if SSCS =b'1' then PLL has */
+                                       /* already been set */
+                                       /* and CPU has been reset */
+                                       /* so skip to next section */
+
+#ifdef CONFIG_BUBINGA
+       /*
+       !-----------------------------------------------------------------------
+       ! Read NVRAM to get value to write in PLLMR.
+       ! If value has not been correctly saved, write default value
+       ! Default config values (assuming on-board 33MHz SYS_CLK) are above.
+       ! See CPU_DEFAULT_200 and CPU_DEFAULT_266 above.
+       !
+       ! WARNING:  This code assumes the first three words in the nvram_t
+       !           structure in openbios.h.  Changing the beginning of
+       !           the structure will break this code.
+       !
+       !-----------------------------------------------------------------------
+       */
+       addis   r3,0,NVRAM_BASE@h
+       addi    r3,r3,NVRAM_BASE@l
+
+       lwz     r4, 0(r3)
+       addis   r5,0,NVRVFY1@h
+       addi    r5,r5,NVRVFY1@l
+       cmp     cr0,0,r4,r5             /* Compare 1st NVRAM Magic number*/
+       bne     ..no_pllset
+       addi    r3,r3,4
+       lwz     r4, 0(r3)
+       addis   r5,0,NVRVFY2@h
+       addi    r5,r5,NVRVFY2@l
+       cmp     cr0,0,r4,r5             /* Compare 2 NVRAM Magic number */
+       bne     ..no_pllset
+       addi    r3,r3,8                 /* Skip over conf_size */
+       lwz     r4, 4(r3)               /* Load PLLMR1 value from NVRAM */
+       lwz     r3, 0(r3)               /* Load PLLMR0 value from NVRAM */
+       rlwinm  r5,r4,1,0x1             /* get system clock source (SSCS) */
+       cmpi     cr0,0,r5,1             /* See if PLL is locked */
+       beq     pll_write
+..no_pllset:
+#endif /* CONFIG_BUBINGA */
+
+#ifdef CONFIG_TAIHU
+       mfdcr   r4, CPC0_BOOT
+       andi.   r5, r4, CPC0_BOOT_SEP@l
+       bne     strap_1                 /* serial eeprom present */
+       addis   r5,0,CPLD_REG0_ADDR@h
+       ori     r5,r5,CPLD_REG0_ADDR@l
+       andi.   r5, r5, 0x10
+       bne     _pci_66mhz
+#endif /* CONFIG_TAIHU */
+
+#if defined(CONFIG_ZEUS)
+       mfdcr   r4, CPC0_BOOT
+       andi.   r5, r4, CPC0_BOOT_SEP@l
+       bne     strap_1                 /* serial eeprom present */
+       lis     r3,0x0000
+       addi    r3,r3,0x3030
+       lis     r4,0x8042
+       addi    r4,r4,0x223e
+       b       1f
+strap_1:
+       mfdcr   r3, CPC0_PLLMR0
+       mfdcr   r4, CPC0_PLLMR1
+       b       1f
+#endif
+
+       addis   r3,0,PLLMR0_DEFAULT@h   /* PLLMR0 default value */
+       ori     r3,r3,PLLMR0_DEFAULT@l  /* */
+       addis   r4,0,PLLMR1_DEFAULT@h   /* PLLMR1 default value */
+       ori     r4,r4,PLLMR1_DEFAULT@l  /* */
+
+#ifdef CONFIG_TAIHU
+       b       1f
+_pci_66mhz:
+       addis   r3,0,PLLMR0_DEFAULT_PCI66@h
+       ori     r3,r3,PLLMR0_DEFAULT_PCI66@l
+       addis   r4,0,PLLMR1_DEFAULT_PCI66@h
+       ori     r4,r4,PLLMR1_DEFAULT_PCI66@l
+       b       1f
+strap_1:
+       mfdcr   r3, CPC0_PLLMR0
+       mfdcr   r4, CPC0_PLLMR1
+#endif /* CONFIG_TAIHU */
+
+1:
+       b       pll_write               /* Write the CPC0_PLLMR with new value */
+
+pll_done:
+       /*
+       !-----------------------------------------------------------------------
+       ! Clear Soft Reset Register
+       ! This is needed to enable PCI if not booting from serial EPROM
+       !-----------------------------------------------------------------------
+               */
+       addi    r3, 0, 0x0
+       mtdcr   CPC0_SRR, r3
+
+       addis    r3,0,0x0010
+       mtctr   r3
+pci_wait:
+       bdnz    pci_wait
+
+       blr                             /* return to main code */
+
+/*
+!-----------------------------------------------------------------------------
+! Function:    pll_write
+! Description: Updates the value of the CPC0_PLLMR according to CMOS27E documentation
+!              That is:
+!                        1.  Pll is first disabled (de-activated by putting in bypass mode)
+!                        2.  PLL is reset
+!                        3.  Clock dividers are set while PLL is held in reset and bypassed
+!                        4.  PLL Reset is cleared
+!                        5.  Wait 100us for PLL to lock
+!                        6.  A core reset is performed
+! Input: r3 = Value to write to CPC0_PLLMR0
+! Input: r4 = Value to write to CPC0_PLLMR1
+! Output r3 = none
+!-----------------------------------------------------------------------------
+*/
+       .globl  pll_write
+pll_write:
+       mfdcr  r5, CPC0_UCR
+       andis. r5,r5,0xFFFF
+       ori    r5,r5,0x0101             /* Stop the UART clocks */
+       mtdcr  CPC0_UCR,r5              /* Before changing PLL */
+
+       mfdcr  r5, CPC0_PLLMR1
+       rlwinm r5,r5,0,0x7FFFFFFF       /* Disable PLL */
+       mtdcr   CPC0_PLLMR1,r5
+       oris   r5,r5,0x4000             /* Set PLL Reset */
+       mtdcr   CPC0_PLLMR1,r5
+
+       mtdcr   CPC0_PLLMR0,r3          /* Set clock dividers */
+       rlwinm r5,r4,0,0x3FFFFFFF       /* Reset & Bypass new PLL dividers */
+       oris   r5,r5,0x4000             /* Set PLL Reset */
+       mtdcr   CPC0_PLLMR1,r5          /* Set clock dividers */
+       rlwinm r5,r5,0,0xBFFFFFFF       /* Clear PLL Reset */
+       mtdcr   CPC0_PLLMR1,r5
+
+               /*
+       ! Wait min of 100us for PLL to lock.
+       ! See CMOS 27E databook for more info.
+       ! At 200MHz, that means waiting 20,000 instructions
+                */
+       addi    r3,0,20000              /* 2000 = 0x4e20 */
+       mtctr   r3
+pll_wait:
+       bdnz    pll_wait
+
+       oris   r5,r5,0x8000             /* Enable PLL */
+       mtdcr   CPC0_PLLMR1,r5          /* Engage */
+
+       /*
+        * Reset CPU to guarantee timings are OK
+        * Not sure if this is needed...
+        */
+       addis r3,0,0x1000
+       mtspr SPRN_DBCR0,r3             /* This will cause a CPU core reset, and */
+                                       /* execution will continue from the poweron */
+                                       /* vector of 0xfffffffc */
+#endif /* CONFIG_405EP */
+
+#if defined(CONFIG_440)
+/*----------------------------------------------------------------------------+
+| mttlb3.
++----------------------------------------------------------------------------*/
+       function_prolog(mttlb3)
+       TLBWE(4,3,2)
+       blr
+       function_epilog(mttlb3)
+
+/*----------------------------------------------------------------------------+
+| mftlb3.
++----------------------------------------------------------------------------*/
+       function_prolog(mftlb3)
+       TLBRE(3,3,2)
+       blr
+       function_epilog(mftlb3)
+
+/*----------------------------------------------------------------------------+
+| mttlb2.
++----------------------------------------------------------------------------*/
+       function_prolog(mttlb2)
+       TLBWE(4,3,1)
+       blr
+       function_epilog(mttlb2)
+
+/*----------------------------------------------------------------------------+
+| mftlb2.
++----------------------------------------------------------------------------*/
+       function_prolog(mftlb2)
+       TLBRE(3,3,1)
+       blr
+       function_epilog(mftlb2)
+
+/*----------------------------------------------------------------------------+
+| mttlb1.
++----------------------------------------------------------------------------*/
+       function_prolog(mttlb1)
+       TLBWE(4,3,0)
+       blr
+       function_epilog(mttlb1)
+
+/*----------------------------------------------------------------------------+
+| mftlb1.
++----------------------------------------------------------------------------*/
+       function_prolog(mftlb1)
+       TLBRE(3,3,0)
+       blr
+       function_epilog(mftlb1)
+#endif /* CONFIG_440 */