Initial revision
diff --git a/board/bmw/early_init.S b/board/bmw/early_init.S
new file mode 100644
index 0000000..ec20a67
--- /dev/null
+++ b/board/bmw/early_init.S
@@ -0,0 +1,1172 @@
+#include <ppc_asm.tmpl>
+#include <mpc824x.h>
+#include <ppc_defs.h>
+#include <asm/cache.h>
+#include <asm/mmu.h>
+
+#define USE_V2_INIT 1 /* Jimmy Blair's initialization. */
+
+
+/*
+ * Initialize the MMU using BAT entries and hardwired TLB
+ * This obviates the need for any code in cpu_init_f which
+ * configures the BAT registers.
+*/
+#define MEMORY_MGMT_MSR_BITS (MSR_DR | MSR_IR) /* Data and Inst Relocate */
+	.global	iommu_setup
+	/* Initialize IO/MMU mappings via BAT method Ch. 7,
+	 * PPC Programming Reference
+         */
+iommu_setup:
+
+/* initialize the BAT registers (SPRs 528 - 543 */
+#define	mtibat0u(x)	mtspr	528,(x)			/* SPR 528 (IBAT0U) */
+#define mtibat0l(x)	mtspr	529,(x)			/* SPR 529 (IBAT0L) */
+#define mtibat1u(x)	mtspr	530,(x)			/* SPR 530 (IBAT1U) */
+#define mtibat1l(x)	mtspr	531,(x)			/* SPR 531 (IBAT1L) */
+#define mtibat2u(x)	mtspr	532,(x)			/* SPR 532 (IBAT2U) */
+#define mtibat2l(x)	mtspr	533,(x)			/* SPR 533 (IBAT2L) */
+#define mtibat3u(x)	mtspr	534,(x)			/* SPR 534 (IBAT3U) */
+#define mtibat3l(x)	mtspr	535,(x)			/* SPR 535 (IBAT3L) */
+#define mtdbat0u(x)	mtspr	536,(x)			/* SPR 536 (DBAT0U) */
+#define mtdbat0l(x)	mtspr	537,(x)			/* SPR 537 (DBAT0L) */
+#define mtdbat1u(x)	mtspr	538,(x)			/* SPR 538 (DBAT1U) */
+#define mtdbat1l(x)	mtspr	539,(x)			/* SPR 539 (DBAT1L) */
+#define mtdbat2u(x)	mtspr	540,(x)			/* SPR 540 (DBAT2U) */
+#define mtdbat2l(x)	mtspr	541,(x)			/* SPR 541 (DBAT2L) */
+#define mtdbat3u(x)	mtspr	542,(x)			/* SPR 542 (DBAT3U) */
+#define mtdbat3l(x)	mtspr	543,(x)			/* SPR 543 (DBAT3L) */
+
+
+/* PowerPC processors do not necessarily initialize the BAT
+   registers on power-up or reset.  So they are in an unknown
+   state.  Before programming the BATs for the first time, all
+   BAT registers MUST have their Vs and Vp bits cleared in the
+   upper BAT half in order to avoid possibly having 2 BATs
+   valid and mapping the same memory region.
+
+   The reason for this is that, even with address translation
+   disabled, multiple BAT hits for an address are treated as
+   programming errors and can cause unpredictable results.
+
+   It is up to the software to make sure it never has 2 IBAT
+   mappings or 2 DBAT mappings that are valid for the same
+   addresses.  It is not necessary to perform this code
+   sequence every time the BATs are programmed, only when
+   there is a possibility that there may be overlapping BAT
+   entries.
+
+   When programming the BATs in non-reset scenarios, even if
+   you are sure that your new mapping will not temporarily
+   create overlapping regions, it is still a wise idea to
+   invalidate a BAT entry by setting its upper BAT register to
+   all 0's before programming it.  This will avoid having a
+   BAT marked valid that is in an unknown or transient state
+*/
+
+        addis   r5,0,0x0000
+	mtibat0u(r5)
+	mtibat0l(r5)
+	mtibat1u(r5)
+	mtibat1l(r5)
+	mtibat2u(r5)
+	mtibat2l(r5)
+	mtibat3u(r5)
+	mtibat3l(r5)
+	mtdbat0u(r5)
+	mtdbat0l(r5)
+	mtdbat1u(r5)
+	mtdbat1l(r5)
+	mtdbat2u(r5)
+	mtdbat2l(r5)
+	mtdbat3u(r5)
+	mtdbat3l(r5)
+        isync
+
+/*
+ *  Set up I/D BAT0
+ */
+        lis     r4, CFG_DBAT0L@h
+        ori     r4, r4, CFG_DBAT0L@l
+        lis     r3, CFG_DBAT0U@h
+        ori     r3, r3, CFG_DBAT0U@l
+
+        mtdbat0l(r4)
+        isync
+        mtdbat0u(r3)
+        isync
+        sync
+
+        lis     r4, CFG_IBAT0L@h
+        ori     r4, r4, CFG_IBAT0L@l
+        lis     r3, CFG_IBAT0U@h
+        ori     r3, r3, CFG_IBAT0U@l
+
+        isync
+        mtibat0l(r4)
+        isync
+	mtibat0u(r3)
+        isync
+
+/*
+ *  Set up I/D BAT1
+ */
+        lis     r4, CFG_IBAT1L@h
+        ori     r4, r4, CFG_IBAT1L@l
+        lis     r3, CFG_IBAT1U@h
+        ori     r3, r3, CFG_IBAT1U@l
+
+        isync
+        mtibat1l(r4)
+        isync
+        mtibat1u(r3)
+        isync
+        mtdbat1l(r4)
+        isync
+        mtdbat1u(r3)
+        isync
+        sync
+
+/*
+ *  Set up I/D BAT2
+ */
+        lis     r4, CFG_IBAT2L@h
+        ori     r4, r4, CFG_IBAT2L@l
+        lis     r3, CFG_IBAT2U@h
+        ori     r3, r3, CFG_IBAT2U@l
+
+        isync
+        mtibat2l(r4)
+        isync
+        mtibat2u(r3)
+        isync
+        mtdbat2l(r4)
+        isync
+        mtdbat2u(r3)
+        isync
+        sync
+
+/*
+ *  Setup I/D BAT3
+ */
+        lis     r4, CFG_IBAT3L@h
+        ori     r4, r4, CFG_IBAT3L@l
+        lis     r3, CFG_IBAT3U@h
+        ori     r3, r3, CFG_IBAT3U@l
+
+        isync
+        mtibat3l(r4)
+        isync
+        mtibat3u(r3)
+        isync
+        mtdbat3l(r4)
+        isync
+        mtdbat3u(r3)
+        isync
+        sync
+
+
+/*
+ *  Invalidate all 64 TLB's
+ */
+        lis     r3, 0
+        mtctr   r3
+        lis     r5, 4
+
+tlblp:
+        tlbie   r3
+        sync
+        addi    r3, r3, 0x1000
+        cmplw   r3, r5
+        blt     tlblp
+
+        sync
+
+/*
+ *  Enable Data Translation
+ */
+	lis	r4, MEMORY_MGMT_MSR_BITS@h
+	ori	r4, r4, MEMORY_MGMT_MSR_BITS@l
+	mfmsr	r3
+	or	r3, r4, r3
+	mtmsr	r3
+	isync
+	sync
+
+        blr
+
+
+#ifdef USE_V2_INIT
+/* #define USER_I_CACHE_ENABLE 1*/ /* Fast rom boots */
+/* Macro for hiadjust and lo */
+#define HIADJ(arg)	arg@ha
+#define HI(arg)		arg@h
+#define LO(arg)		arg@l
+
+#undef LOADPTR
+#define	LOADPTR(reg,const32) \
+	  addis reg,r0,HIADJ(const32); addi reg,reg,LO(const32)
+
+.globl  early_init_f
+
+early_init_f:
+/* MPC8245/BMW CPCI System Init
+ * Jimmy Blair, Broadcom Corp, 2002.
+ */
+        mflr    r11
+ 	/* Zero-out registers */
+
+	addis	r0,r0,0
+	mtspr	SPRG0,r0
+	mtspr	SPRG1,r0
+	mtspr	SPRG2,r0
+	mtspr	SPRG3,r0
+
+	/* Set MPU/MSR to a known state. Turn on FP */
+
+	LOADPTR (r3, MSR_FP)
+	sync
+	mtmsr	r3
+	isync
+
+	/* Init the floating point control/status register */
+
+	mtfsfi	7,0x0
+	mtfsfi	6,0x0
+	mtfsfi	5,0x0
+	mtfsfi	4,0x0
+	mtfsfi	3,0x0
+	mtfsfi	2,0x0
+	mtfsfi	1,0x0
+	mtfsfi	0,0x0
+	isync
+
+	/* Set MPU/MSR to a known state. Turn off FP */
+
+#if 1	/* Turn off floating point (remove to keep FP on) */
+        andi.	r3, r3, 0
+	sync
+	mtmsr 	r3
+	isync
+#endif
+
+	/* Init the Segment registers */
+
+	andi.	r3, r3, 0
+	isync
+	mtsr	0,r3
+	isync
+	mtsr	1,r3
+	isync
+	mtsr	2,r3
+	isync
+	mtsr	3,r3
+	isync
+	mtsr	4,r3
+	isync
+	mtsr	5,r3
+	isync
+	mtsr	6,r3
+	isync
+	mtsr	7,r3
+	isync
+	mtsr	8,r3
+	isync
+	mtsr	9,r3
+	isync
+	mtsr	10,r3
+	isync
+	mtsr	11,r3
+	isync
+	mtsr	12,r3
+	isync
+	mtsr	13,r3
+	isync
+	mtsr	14,r3
+	isync
+	mtsr	15,r3
+	isync
+
+	/* Turn off data and instruction cache control bits */
+
+	mfspr	r3, HID0
+	isync
+	rlwinm	r4, r3, 0, 18, 15	/* r4 has ICE and DCE bits cleared */
+	sync
+	isync
+	mtspr	HID0, r4		/* HID0 = r4 */
+	isync
+
+	/* Get cpu type */
+
+	mfspr	r28, PVR
+	rlwinm	r28, r28, 16, 16, 31
+
+	/* invalidate the MPU's data/instruction caches */
+
+	lis	r3, 0x0
+	cmpli	0, 0, r28, CPU_TYPE_603
+	beq	cpuIs603
+	cmpli	0, 0, r28, CPU_TYPE_603E
+	beq	cpuIs603
+	cmpli	0, 0, r28, CPU_TYPE_603P
+	beq	cpuIs603
+	cmpli	0, 0, r28, CPU_TYPE_604R
+	bne	cpuNot604R
+
+cpuIs604R:
+	lis	r3, 0x0
+	mtspr	HID0, r3		/* disable the caches */
+	isync
+	ori	r4, r4, 0x0002		/* disable BTAC by setting bit 30 */
+
+cpuNot604R:
+	ori	r3, r3, (HID0_ICFI |HID0_DCI)
+
+cpuIs603:
+	ori	r3, r3, (HID0_ICE | HID0_DCE)
+	or	r4, r4, r3		/* set bits */
+	sync
+	isync
+	mtspr	HID0, r4		/* HID0 = r4 */
+	andc	r4, r4, r3		/* clear bits */
+	isync
+	cmpli	0, 0, r28, CPU_TYPE_604
+	beq	cpuIs604
+	cmpli	0, 0, r28, CPU_TYPE_604E
+	beq	cpuIs604
+	cmpli	0, 0, r28, CPU_TYPE_604R
+	beq	cpuIs604
+	mtspr	HID0, r4
+	isync
+
+#ifdef USER_I_CACHE_ENABLE
+	b	instCacheOn603
+#else
+	b	cacheEnableDone
+#endif
+
+cpuIs604:
+	LOADPTR (r5, 0x1000)		/* loop count, 0x1000 */
+	mtspr	CTR, r5
+loopDelay:
+	nop
+	bdnz	loopDelay
+	isync
+	mtspr	HID0, r4
+	isync
+
+	/* turn the Instruction cache ON for faster FLASH ROM boots */
+
+#ifdef USER_I_CACHE_ENABLE
+
+	ori	r4, r4, (HID0_ICE | HID0_ICFI)
+	isync				/* Synchronize for ICE enable */
+	b	writeReg4
+instCacheOn603:
+	ori	r4, r4, (HID0_ICE | HID0_ICFI)
+	rlwinm	r3, r4, 0, 21, 19	/* clear the ICFI bit */
+
+	/*
+         * The setting of the instruction cache enable (ICE) bit must be
+         * preceded by an isync instruction to prevent the cache from being
+         * enabled or disabled while an instruction access is in progress.
+         */
+	isync
+writeReg4:
+	mtspr	HID0, r4		/* Enable Instr Cache & Inval cache */
+	cmpli	0, 0, r28, CPU_TYPE_604
+	beq	cacheEnableDone
+	cmpli	0, 0, r28, CPU_TYPE_604E
+	beq	cacheEnableDone
+
+	mtspr	HID0, r3		/* using 2 consec instructions */
+					/* PPC603 recommendation */
+#endif
+cacheEnableDone:
+
+	/* Detect map A or B */
+
+	addis	r5,r0, HI(CHRP_REG_ADDR)
+	addis	r6,r0, HI(CHRP_REG_DATA)
+	LOADPTR (r7, KAHLUA_ID)		/* Kahlua PCI controller ID */
+	LOADPTR (r8, BMC_BASE)
+
+	stwbrx	r8,0,(r5)
+	lwbrx	r3,0,(r6)		/* Store read value to r3 */
+	cmp	0,0,r3,r7
+	beq	cr0, X4_KAHLUA_START
+
+        /* It's not an 8240, is it an 8245? */
+
+	LOADPTR (r7, KAHLUA2_ID)	/* Kahlua PCI controller ID */
+	cmp	0,0,r3,r7
+	beq	cr0, X4_KAHLUA_START
+
+        /* Save the PCI controller type in r7 */
+	mr	r7, r3
+
+	LOADPTR (r5, PREP_REG_ADDR)
+	LOADPTR (r6, PREP_REG_DATA)
+
+X4_KAHLUA_START:
+	/* MPC8245 changes begin here */
+	LOADPTR (r3, MPC107_PCI_CMD)	/* PCI command reg */
+	stwbrx	r3,0,r5
+	li	r4, 6			/* Command register value */
+	sthbrx	r4, 0, r6
+
+	LOADPTR (r3, MPC107_PCI_STAT)	/* PCI status reg */
+	stwbrx	r3,0,r5
+	li	r4, -1			/* Write-to-clear all bits */
+	li	r3, 2			/* PCI_STATUS is at +2 offset */
+	sthbrx	r4, r3, r6
+
+	/*-------PROC_INT1_ADR */
+
+	LOADPTR (r3, PROC_INT1_ADR)	/* Processor I/F Config 1 reg. */
+	stwbrx	r3,0,r5
+	LOADPTR (r4, 0xff141b98)
+	stwbrx	r4,0,r6
+
+	/*-------PROC_INT2_ADR */
+
+	LOADPTR (r3, PROC_INT2_ADR)	/* Processor I/F Config 2 reg. */
+	stwbrx	r3,0,r5
+        lis	r4, 0x2000		/* Flush PCI config writes */
+	stwbrx	r4,0,r6
+
+	LOADPTR (r9, KAHLUA2_ID)
+        cmpl	0, 0, r7, r9
+        bne     L1not8245
+
+        /* MIOCR1 -- turn on bit for DLL delay */
+
+	LOADPTR (r3, MIOCR1_ADR_X)
+	stwbrx	r3,0,r5
+        li      r4, 0x04
+	stb	r4, MIOCR1_SHIFT(r6)
+
+        /* For the MPC8245, set register 77 to %00100000 (see Errata #15) */
+        /* SDRAM_CLK_DEL (0x77)*/
+
+	LOADPTR (r3, MIOCR2_ADR_X)
+	stwbrx	r3,0,r5
+        li      r4, 0x10
+	stb	r4, MIOCR2_SHIFT(r6)
+
+        /* PMCR2 -- set PCI hold delay to <10>b for 33 MHz */
+
+	LOADPTR (r3, PMCR2_ADR_X)
+	stwbrx	r3,0,r5
+        li      r4, 0x20
+	stb	r4, PMCR2_SHIFT(r6)
+
+	/* Initialize EUMBBAR early since 8245 has internal UART in EUMB */
+
+	LOADPTR (r3, EUMBBAR)
+	stwbrx	r3,0,r5
+	LOADPTR (r4, CFG_EUMB_ADDR)
+	stwbrx	r4,0,r6
+
+L1not8245:
+
+        /* Toggle the DLL reset bit in AMBOR */
+
+	LOADPTR (r3, AMBOR)
+	stwbrx	r3,0,r5
+	lbz	r4, 0(r6)
+
+        andi.   r4, r4, 0xdf
+	stb	r4, 0(r6)		/* Clear DLL_RESET */
+        sync
+
+        ori     r4, r4, 0x20		/* Set DLL_RESET */
+	stb	r4, 0(r6)
+        sync
+
+        andi.   r4, r4, 0xdf
+	stb	r4, 0(r6)		/* Clear DLL_RESET */
+
+
+	/* Enable RCS2, use supplied timings */
+	LOADPTR (r3, ERCR1)
+	stwbrx	r3,0,r5
+	LOADPTR (r4, 0x80408000)
+	stwbrx	r4,0,r6
+
+	/* Disable RCS3 parameters */
+	LOADPTR (r3, ERCR2)
+	stwbrx	r3,0,r5
+	LOADPTR (r4, 0x00000000)
+	stwbrx	r4,0,r6
+
+	/* RCS3 at 0x70000000, 64KBytes */
+	LOADPTR (r3, ERCR2)
+	stwbrx	r3,0,r5
+	LOADPTR (r4, 0x00000004)
+	stwbrx	r4,0,r6
+
+	/*-------MCCR1 */
+
+#ifdef INCLUDE_ECC
+#define MC_ECC				1
+#else /* INCLUDE_ECC */
+#define MC_ECC				0
+#endif /* INCLUDE_ECC */
+
+#define MC1_ROMNAL			8		/* 0-15 */
+#define MC1_ROMFAL			11		/* 0-31 */
+#define MC1_DBUS_SIZE			0		/* 0-3, read only */
+#define MC1_BURST			0		/* 0-1 */
+#define MC1_MEMGO			0		/* 0-1 */
+#define MC1_SREN			1		/* 0-1 */
+#define MC1_RAM_TYPE			0		/* 0-1 */
+#define MC1_PCKEN			MC_ECC		/* 0-1 */
+#define MC1_BANKBITS			0x5555		/* 2 bits/bank 7-0 */
+
+	LOADPTR (r3, MEM_CONT1_ADR)	/* Set MCCR1 (F0) */
+	stwbrx	r3,0,r5
+	LOADPTR(r4, \
+		MC1_ROMNAL << 28 | MC1_ROMFAL << 23 | \
+		MC1_DBUS_SIZE << 21 | MC1_BURST << 20 | \
+		MC1_MEMGO << 19 | MC1_SREN << 18 | \
+		MC1_RAM_TYPE << 17 | MC1_PCKEN << 16 )
+	li	r3, MC1_BANKBITS
+        cmpl	0, 0, r7, r9		/* Check for Kahlua2 */
+        bne     BankBitsAdd
+        cmpli   0, 0, r3, 0x5555
+        beq     K2BankBitsHack		/* On 8245, 5555 ==> 0 */
+BankBitsAdd:
+	ori	r4, r3, 0
+K2BankBitsHack:
+	stwbrx	r4, 0, r6
+
+	/*------- MCCR2 */
+
+#define MC2_TS_WAIT_TIMER		0		/* 0-7 */
+#define MC2_ASRISE			8		/* 0-15 */
+#define MC2_ASFALL			4		/* 0-15 */
+#define MC2_INLINE_PAR_NOT_ECC		0		/* 0-1 */
+#define MC2_WRITE_PARITY_CHK_EN		MC_ECC		/* 0-1 */
+#define MC2_INLRD_PARECC_CHK_EN		MC_ECC		/* 0-1 */
+#define MC2_ECC_EN			0		/* 0-1 */
+#define MC2_EDO				0		/* 0-1 */
+/*
+*  N.B. This refresh interval looks good up to 85 MHz with Hynix SDRAM.
+*  May need to be decreased for 100 MHz
+*/
+#define MC2_REFINT			0x3a5		/* 0-0x3fff */
+#define MC2_RSV_PG			0		/* 0-1 */
+#define MC2_RMW_PAR			MC_ECC		/* 0-1 */
+
+	LOADPTR (r3, MEM_CONT2_ADR)	/* Set MCCR2 (F4) */
+	stwbrx	r3,0,r5
+	LOADPTR(r4, \
+		MC2_TS_WAIT_TIMER << 29 | MC2_ASRISE << 25 | \
+		MC2_ASFALL << 21 | MC2_INLINE_PAR_NOT_ECC << 20 | \
+		MC2_WRITE_PARITY_CHK_EN << 19 | \
+		MC2_INLRD_PARECC_CHK_EN << 18 | \
+		MC2_ECC_EN << 17 | MC2_EDO << 16 | \
+		MC2_REFINT << 2 | MC2_RSV_PG << 1 | MC2_RMW_PAR)
+        cmpl	0, 0, r7, r9		/* Check for Kahlua2 */
+        bne     notK2
+        /* clear Kahlua2 reserved bits */
+	LOADPTR (r3, 0xfffcffff)
+	and	r4, r4, r3
+notK2:
+	stwbrx	r4,0,r6
+
+	/*------- MCCR3 */
+
+#define MC_BSTOPRE			0x079		/* 0-0x7ff */
+
+#define MC3_BSTOPRE_U			(MC_BSTOPRE >> 4 & 0xf)
+#define MC3_REFREC			8		/* 0-15 */
+#define MC3_RDLAT			(4+MC_ECC)	/* 0-15 */
+#define MC3_CPX				0		/* 0-1 */
+#define MC3_RAS6P			0		/* 0-15 */
+#define MC3_CAS5			0		/* 0-7 */
+#define MC3_CP4				0		/* 0-7 */
+#define MC3_CAS3			0		/* 0-7 */
+#define MC3_RCD2			0		/* 0-7 */
+#define MC3_RP1				0		/* 0-7 */
+
+	LOADPTR (r3, MEM_CONT3_ADR)	/* Set MCCR3 (F8) */
+	stwbrx	r3,0,r5
+	LOADPTR(r4, \
+		MC3_BSTOPRE_U << 28 | MC3_REFREC << 24 | \
+		MC3_RDLAT << 20 | MC3_CPX << 19 | \
+		MC3_RAS6P << 15 | MC3_CAS5 << 12 | MC3_CP4 << 9 | \
+		MC3_CAS3 << 6 | MC3_RCD2 << 3 | MC3_RP1)
+        cmpl	0, 0, r7, r9              /* Check for Kahlua2 */
+        bne     notK2b
+        /* clear Kahlua2 reserved bits */
+	LOADPTR (r3, 0xff000000)
+	and	r4, r4, r3
+notK2b:
+	stwbrx	r4,0,r6
+
+	/*------- MCCR4 */
+
+#define MC4_PRETOACT			3		/* 0-15 */
+#define MC4_ACTOPRE			5		/* 0-15 */
+#define MC4_WMODE			0		/* 0-1 */
+#define MC4_INLINE			MC_ECC		/* 0-1 */
+#define MC4_REGISTERED			(1-MC_ECC)	/* 0-1 */
+#define MC4_BSTOPRE_UU			(MC_BSTOPRE >> 8 & 3)
+#define MC4_REGDIMM			0		/* 0-1 */
+#define MC4_SDMODE_CAS			2		/* 0-7 */
+#define MC4_DBUS_RCS1			1		/* 0-1, 8-bit */
+#define MC4_SDMODE_WRAP			0		/* 0-1 */
+#define MC4_SDMODE_BURST		2		/* 0-7 */
+#define MC4_ACTORW			3		/* 0-15 */
+#define MC4_BSTOPRE_L			(MC_BSTOPRE & 0xf)
+
+	LOADPTR (r3, MEM_CONT4_ADR)	/* Set MCCR4 (FC) */
+	stwbrx	r3,0,r5
+	LOADPTR(r4, \
+		MC4_PRETOACT << 28 | MC4_ACTOPRE << 24 | \
+		MC4_WMODE << 23 | MC4_INLINE << 22 | \
+		MC4_REGISTERED << 20 | MC4_BSTOPRE_UU << 18 | \
+		MC4_DBUS_RCS1 << 17 | \
+		MC4_REGDIMM << 15 | MC4_SDMODE_CAS << 12 | \
+		MC4_SDMODE_WRAP << 11 | MC4_SDMODE_BURST << 8 | \
+		MC4_ACTORW << 4 | MC4_BSTOPRE_L)
+        cmpl	0, 0, r7, r9                /* Check for Kahlua 2 */
+        bne     notK2c
+        /* Turn on Kahlua2 extended ROM space */
+	LOADPTR (r3, 0x00200000)
+	or	r4, r4, r3
+notK2c:
+	stwbrx	r4,0,r6
+
+#ifdef INCLUDE_ECC
+	/*------- MEM_ERREN1 */
+
+	LOADPTR (r3, MEM_ERREN1_ADR)	/* Set MEM_ERREN1 (c0) */
+	stwbrx	r3,0,r5
+	lwbrx	r4,0,r6
+	ori	r4,r4,4			/* Set MEM_PERR_EN */
+	stwbrx	r4,0,r6
+#endif /* INCLUDE_ECC */
+
+	/*------- MSAR/MEAR */
+
+	LOADPTR (r3, MEM_START1_ADR)	/* Set MSAR1 (80) */
+	stwbrx	r3,0,r5
+	LOADPTR (r4, 0xc0804000)
+	stwbrx	r4,0,r6
+
+	LOADPTR (r3, MEM_START2_ADR)	/* Set MSAR2 (84) */
+	stwbrx	r3,0,r5
+	LOADPTR (r4, 0xc0804000)
+	stwbrx	r4,0,r6
+
+	LOADPTR (r3, XMEM_START1_ADR)	/* Set MESAR1 (88) */
+	stwbrx	r3,0,r5
+	LOADPTR (r4, 0x00000000)
+	stwbrx	r4,0,r6
+
+	LOADPTR (r3, XMEM_START2_ADR)	/* Set MESAR2 (8c) */
+	stwbrx	r3,0,r5
+	LOADPTR (r4, 0x01010101)
+	stwbrx	r4,0,r6
+
+	LOADPTR (r3, MEM_END1_ADR)	/* Set MEAR1 (90) */
+	stwbrx	r3,0,r5
+	LOADPTR (r4, 0xffbf7f3f)
+	stwbrx	r4,0,r6
+
+	LOADPTR (r3, MEM_END2_ADR)	/* Set MEAR2 (94) */
+	stwbrx	r3,0,r5
+	LOADPTR (r4, 0xffbf7f3f)
+	stwbrx	r4,0,r6
+
+	LOADPTR (r3, XMEM_END1_ADR)	/* MEEAR1 (98) */
+	stwbrx	r3,0,r5
+	LOADPTR (r4, 0x00000000)
+	stwbrx	r4,0,r6
+
+	LOADPTR (r3, XMEM_END2_ADR)	/* MEEAR2 (9c) */
+	stwbrx	r3,0,r5
+	LOADPTR (r4, 0x01010101)
+	stwbrx	r4,0,r6
+
+	/*-------ODCR */
+
+	LOADPTR (r3, ODCR_ADR_X)	/* Set ODCR */
+	stwbrx	r3,0,r5
+
+	li	r4, 0x7f
+	stb	r4, ODCR_SHIFT(r6)	/* ODCR is at +3 offset */
+
+	/*-------MBEN */
+
+	LOADPTR (r3, MEM_EN_ADR)	/* Set MBEN (a0) */
+	stwbrx	r3,0,r5
+	li	r4, 0x01		/* Enable bank 0 */
+	stb	r4, 0(r6)		/* MBEN is at +0 offset */
+
+#if 0   /* Jimmy:  I think page made is broken */
+	/*-------PGMAX */
+
+	LOADPTR (r3, MPM_ADR_X)
+	stwbrx	r3,0,r5
+	li	r4, 0x32
+	stb	r4, MPM_SHIFT(r6)		/* PAGE_MODE is at +3 offset */
+#endif
+
+	/* Wait before initializing other registers */
+
+	lis	r4,0x0001
+	mtctr	r4
+
+KahluaX4wait200us:
+	bdnz	KahluaX4wait200us
+
+	/* Set MEMGO bit */
+
+	LOADPTR (r3, MEM_CONT1_ADR)	/* MCCR1 (F0) |= PGMAX */
+	stwbrx	r3,0,r5
+	lwbrx	r4,0,r6			/* old MCCR1 */
+	oris	r4,r4,0x0008		/* MEMGO=1 */
+	stwbrx	r4, 0, r6
+
+	/* Wait again */
+
+	addis	r4,r0,0x0002
+	ori	r4,r4,0xffff
+
+	mtctr	r4
+
+KahluaX4wait8ref:
+	bdnz	KahluaX4wait8ref
+
+	sync
+	eieio
+        mtlr    r11
+	blr
+
+#else /* USE_V2_INIT */
+
+
+
+/* U-Boot works, but memory will not run reliably for all address ranges.
+ * Early U-Boot Working init, but 2.4.19 kernel will crash since memory is not
+ * initialized correctly. Could work if debugged.
+ */
+/* PCI Support routines */
+
+    .globl __pci_config_read_32
+__pci_config_read_32:
+    lis     r4, 0xfec0
+    stwbrx   r3, r0, r4
+    sync
+    lis     r4, 0xfee0
+    lwbrx   r3, 0, r4
+    blr
+    .globl __pci_config_read_16
+__pci_config_read_16:
+    lis     r4, 0xfec0
+    andi.    r5, r3, 2
+    stwbrx  r3, r0, r4
+    sync
+    oris     r4, r5, 0xfee0
+    lhbrx    r3, r0, r4
+    blr
+    .globl __pci_config_read_8
+__pci_config_read_8:
+    lis     r4, 0xfec0
+    andi.    r5, r3, 3
+    stwbrx  r3, r0, r4
+    sync
+    oris     r4, r5, 0xfee0
+    lbz      r3, 0(4)
+    blr
+    .globl __pci_config_write_32
+__pci_config_write_32:
+    lis     r5, 0xfec0
+    stwbrx   r3, r0, r5
+    sync
+    lis      r5, 0xfee0
+    stwbrx   r4, r0, r5
+    sync
+    blr
+    .globl __pci_config_write_16
+__pci_config_write_16:
+    lis     r5, 0xfec0
+    andi.    r6, r3, 2
+    stwbrx  r3, r0, 5
+    sync
+    oris     r5, r6, 0xfee0
+    sthbrx    r4, r0, r5
+    sync
+    blr
+    .globl __pci_config_write_8
+__pci_config_write_8:
+    lis      r5, 0xfec0
+    andi.    r6, r3, 3
+    stwbrx   r3, r0, r5
+    sync
+    oris      r5, r6, 0xfee0
+    stb       r4, 0(r5)
+    sync
+    blr
+    .globl  in_8
+in_8:
+    oris    r3, r3, 0xfe00
+    lbz     r3,0(r3)
+    blr
+    .globl  in_16
+in_16:
+    oris    r3, r3, 0xfe00
+    lhbrx   r3, 0, r3
+    blr
+    .globl in_16_ne
+in_16_ne:
+    oris    r3, r3, 0xfe00
+    lhzx    r3, 0, r3
+    blr
+    .globl  in_32
+in_32:
+    oris    r3, r3, 0xfe00
+    lwbrx   r3, 0, r3
+    blr
+    .globl  out_8
+out_8:
+    oris    r3, r3, 0xfe00
+    stb     r4, 0(r3)
+    eieio
+    blr
+    .globl  out_16
+out_16:
+    oris    r3, r3, 0xfe00
+    sthbrx  r4, 0, r3
+    eieio
+    blr
+    .globl  out_16_ne
+out_16_ne:
+    oris    r3, r3, 0xfe00
+    sth     r4, 0(r3)
+    eieio
+    blr
+    .globl  out_32
+out_32:
+    oris    r3, r3, 0xfe00
+    stwbrx  r4, 0, r3
+    eieio
+    blr
+    .globl  read_8
+read_8:
+    lbz     r3,0(r3)
+    blr
+    .globl  read_16
+read_16:
+    lhbrx   r3, 0, r3
+    blr
+    .globl  read_32
+read_32:
+    lwbrx   r3, 0, r3
+    blr
+    .globl  read_32_ne
+read_32_ne:
+    lwz     r3, 0(r3)
+    blr
+    .globl  write_8
+write_8:
+    stb     r4, 0(r3)
+    eieio
+    blr
+    .globl  write_16
+write_16:
+    sthbrx  r4, 0, r3
+    eieio
+    blr
+    .globl  write_32
+write_32:
+    stwbrx  r4, 0, r3
+    eieio
+    blr
+    .globl  write_32_ne
+write_32_ne:
+    stw     r4, 0(r3)
+    eieio
+    blr
+
+
+.globl  early_init_f
+
+early_init_f:
+        mflr    r11
+        lis     r10, 0x8000
+
+        /* PCI Latency Timer */
+        li      r4, 0x0d
+        ori     r3, r10, PLTR@l
+        bl      __pci_config_write_8
+
+        /* Cache Line Size */
+        li      r4, 0x08
+        ori     r3, r10, PCLSR@l
+        bl      __pci_config_write_8
+
+        /* PCI Cmd */
+        li      r4, 6
+        ori     r3, r10, PCICR@l
+        bl      __pci_config_write_16
+
+#if 1
+        /* PCI Stat */
+        ori     r3, r10, PCISR@l
+        bl      __pci_config_read_16
+        ori     r4, r4, 0xffff
+        ori     r3, r10, PCISR@l
+        bl      __pci_config_write_16
+#endif
+
+        /* PICR1 */
+        lis     r4, 0xff14
+        ori     r4, r4, 0x1b98
+        ori     r3, r10, PICR1@l
+        bl      __pci_config_write_32
+
+
+        /* PICR2 */
+        lis     r4, 0x0404
+        ori     r4, r4, 0x0004
+        ori     r3, r10, PICR2@l
+        bl      __pci_config_write_32
+
+	/* MIOCR1 */
+        li      r4, 0x04
+        ori     r3, r10, MIOCR1@l
+        bl      __pci_config_write_8
+
+	/* For the MPC8245, set register 77 to %00100000 (see Errata #15) */
+	/* SDRAM_CLK_DEL (0x77)*/
+        li      r4, 0x10
+        ori     r3, r10, MIOCR2@l
+        bl      __pci_config_write_8
+
+        /* EUMBBAR */
+        lis     r4, 0xfc00
+        ori     r3, r10, EUMBBAR@l
+        bl      __pci_config_write_32
+
+	/* AMBOR */
+
+       /* Even if Address Map B is not being used (though it should),
+        * the memory DLL needs to be cleared/set/cleared before using memory.
+	*/
+
+        ori     r3, r10, AMBOR@l
+        bl      __pci_config_read_8	/* get Current bits */
+
+        andi.   r4, r4, 0xffdf
+        ori     r3, r10, AMBOR@l
+        bl      __pci_config_write_16	/* Clear DLL_RESET */
+
+        ori    r4, r4, 0x0020
+        ori     r3, r10, AMBOR@l
+        bl      __pci_config_write_16	/* Set DLL_RESET */
+
+        andi.   r4, r4, 0xffdf
+        ori     r3, r10, AMBOR@l
+        bl      __pci_config_write_16	/* Clear DLL_RESET */
+
+        /* ERCR1 */
+        lis     r4, 0x8040		/* Enable RCS2, use supplied timings */
+        ori     r4, r4, 0x8000
+        ori     r3, r10, ERCR1@l
+        bl      __pci_config_write_32
+
+        /* ERCR2 */
+        lis     r4, 0x0000		/* Disable RCS3 parms */
+        ori     r4, r4, 0x0000
+        ori     r3, r10, ERCR2@l
+        bl      __pci_config_write_32
+
+        /* ERCR3 */
+        lis     r4, 0x0000		/* RCS3 at 0x70000000, 64K bytes */
+        ori     r4, r4, 0x0004
+        ori     r3, r10, ERCR2@l
+        bl      __pci_config_write_32
+
+	/* Preserve memgo bit */
+        /* MCCR1 */
+
+/*	lis     r4, 0x75a8		/  Safe Local ROM = 11+3 clocks */
+  	lis     r4, 0x75a0              /* Safe Local ROM = 11+3 clocks */
+/*      lis     r4, 0x73a0              /  Fast Local ROM = 7+3 clocks */
+/*      oris    r4, r4, 0x0010          /  Burst ROM/Flash enable */
+/*      oris    r4, r4, 0x0004          /  Self-refresh enable */
+
+/*      ori     r4,r4,0xFFFF            /  16Mbit  2bank SDRAM */
+/*      ori     r4,r4,0xAAAA            /  256Mbit 4bank SDRAM (8245 only) */
+/*      ori     r4,r4,0x5555            /  64Mbit  2bank SDRAM */
+        ori     r4,r4,0x0000            /* 64Mbit  4bank SDRAM */
+
+        ori     r3, r10, MCCR1@l
+        bl      __pci_config_write_32
+
+        /* MCCR2 */
+
+        lis     r4,0x0000
+/*      oris    r4,r4,0x4000            /  TS_WAIT_TIMER = 3 clocks */
+        oris    r4,r4,0x1000            /* ASRISE = 8 clocks */
+        oris    r4,r4,0x0080            /* ASFALL = 8 clocks */
+/*      oris    r4,r4,0x0010            /  SDRAM Parity (else ECC) */
+/*      oris    r4,r4,0x0008            /  Write parity check */
+/*      oris    r4,r4,0x0004            /  SDRAM inline reads */
+
+
+/* Select a refresh rate; it needs to match the bus speed; if too */
+/* slow, data may be lost; if too fast, performance is lost.  We */
+/* use the fastest value so we run at all speeds. */
+/* Refresh = (15600ns/busclk) - (213 (see UM)). */
+
+/*      ori     r4,r4,0x1d2c            /  133 MHz mem bus        = 1867 */
+/*      ori     r4,r4,0x150c            /  100 MHz mem bus        = 1347 */
+/*      ori     r4,r4,0x10fc            /   83 MHz mem bus        = 1087 */
+/*      ori     r4,r4,0x0cc4            /   66 MHz mem bus        =  817 */
+        ori     r4,r4,0x04cc            /*  33 MHz mem bus (SAFE) =  307 */
+/*      ori     r4,r4,0x0002            /  Reserve a page */
+/*      ori     r4,r4,0x0001            /  RWM parity */
+
+        ori     r3, r10, MCCR2@l
+        bl      __pci_config_write_32
+
+
+        /* MCCR3 */
+        lis     r4,0x0000               /* BSTOPRE_M = 7 (see A/N) */
+        oris    r4,r4,0x0500            /* REFREC    = 8 clocks */
+        ori     r3, r10, MCCR3@l
+        bl      __pci_config_write_32
+
+        /* MCCR4 */                     /* Turn on registered buffer mode */
+        lis     r4, 0x2000              /* PRETOACT = 3 clocks */
+        oris    r4,r4,0x0400            /* ACTOPRE  = 5 clocks */
+/*      oris    r4,r4,0x0080            /  Enable 8-beat burst (32-bit bus) */
+/*      oris    r4,r4,0x0040            /  Enable Inline ECC/Parity */
+        oris    r4,r4,0x0020            /* EXTROM enabled */
+        oris    r4,r4,0x0010            /* Registered buffers */
+/*      oris    r4,r4,0x0000            /  BSTOPRE_U = 0 (see A/N) */
+        oris    r4,r4,0x0002            /* DBUS_SIZ[2] (8 bit on RCS1) */
+
+/*      ori     r4,r4,0x8000            /  Registered DIMMs */
+        ori     r4,r4,0x2000            /*CAS Latency (CL=3) (see RDLAT) */
+/*      ori     r4,r4,0x2000            /  CAS Latency (CL=2) (see RDLAT) */
+/*      ori     r4,r4,0x0300            /  Sequential wrap/8-beat burst */
+        ori     r4,r4,0x0200            /* Sequential wrap/4-beat burst */
+        ori     r4,r4,0x0030            /* ACTORW  = 3 clocks */
+        ori     r4,r4,0x0009            /* BSTOPRE_L = 9 (see A/N) */
+
+        ori     r3, r10, MCCR4@l
+        bl      __pci_config_write_32
+
+	/* MSAR1 */
+        lis     r4, 0xc0804000@h
+        ori     r4, r4, 0xc0804000@l
+        ori     r3, r10, MSAR1@l
+        bl      __pci_config_write_32
+
+	/* MSAR2 */
+        lis     r4, 0xc0804000@h
+        ori     r4, r4, 0xc0804000@l
+        ori     r3, r10, MSAR2@l
+        bl      __pci_config_write_32
+
+	/* MESAR1 */
+        lis     r4, 0x00000000@h
+        ori     r4, r4, 0x00000000@l
+        ori     r3, r10, EMSAR1@l
+        bl      __pci_config_write_32
+
+	/* MESAR2 */
+        lis     r4, 0x01010101@h
+        ori     r4, r4, 0x01010101@l
+        ori     r3, r10, EMSAR2@l
+        bl      __pci_config_write_32
+
+	/* MEAR1 */
+        lis     r4, 0xffbf7f3f@h
+        ori     r4, r4, 0xffbf7f3f@l
+        ori     r3, r10, MEAR1@l
+        bl      __pci_config_write_32
+
+	/* MEAR2 */
+        lis     r4, 0xffbf7f3f@h
+        ori     r4, r4, 0xffbf7f3f@l
+        ori     r3, r10, MEAR2@l
+        bl      __pci_config_write_32
+
+	/* MEEAR1 */
+        lis     r4, 0x00000000@h
+        ori     r4, r4, 0x00000000@l
+        ori     r3, r10, EMEAR1@l
+        bl      __pci_config_write_32
+
+	/* MEEAR2 */
+        lis     r4, 0x01010101@h
+        ori     r4, r4, 0x01010101@l
+        ori     r3, r10, EMEAR2@l
+        bl      __pci_config_write_32
+
+	/* ODCR */
+        li      r4, 0x7f
+        ori     r3, r10, ODCR@l
+        bl      __pci_config_write_8
+
+	/* MBER */
+        li      r4, 0x01
+        ori     r3, r10, MBER@l
+        bl      __pci_config_write_8
+
+        /* Page CTR aka PGMAX */
+        li      r4, 0x32
+        ori     r3, r10, 0x70
+        bl      __pci_config_write_8
+
+#if 0
+	/* CLK Drive */
+        ori     r4, r10, 0xfc01 /* Top bit will be ignored */
+        ori     r3, r10, 0x74
+        bl      __pci_config_write_16
+#endif
+
+	/* delay */
+        lis     r7, 1
+        mtctr   r7
+label1: 	bdnz    label1
+
+        /* Set memgo bit */
+        /* MCCR1 */
+        ori     r3, r10, MCCR1@l
+        bl      __pci_config_read_32
+        lis	r7, 0x0008
+        or	r4, r3, r7
+        ori     r3, r10, MCCR1@l
+        bl      __pci_config_write_32
+
+	/* delay again */
+        lis     r7, 1
+        mtctr   r7
+label2: 	bdnz    label2
+#if 0
+/* DEBUG: Infinite loop, write then read */
+loop:
+        lis     r7, 0xffff
+        mtctr   r7
+        li	r3, 0x5004
+        lis	r4, 0xa0a0
+        ori	r4, r4, 0x5050
+	bl write_32_ne
+        li	r3, 0x5004
+	bl read_32_ne
+      	bdnz    loop
+#endif
+        mtlr    r11
+        blr
+#endif
+