powerpc/mpc86xx: Disable translation for BAT setup

We really shouldn't be overwriting bat registers with translation enabled,
especially when we're executing code using one of them for translating
the current instruction stream.  Instead, disable address translation
while doing the final BAT setup.

In order to do this, setup_bats has to move back to asm code, because we
require translation to be enabled to have a stack for C code.  The yucky
thing about that is that the assembler doesn't like ULL so we have to
switch to using HIGH/LOW pairs for physical addresses that are > 32 bits
in length.

Signed-off-by: Becky Bruce <beckyb@kernel.crashing.org>
Acked-by: York Sun <yorksun@freescale.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
diff --git a/arch/powerpc/cpu/mpc86xx/start.S b/arch/powerpc/cpu/mpc86xx/start.S
index 32896d4..ef80ecf 100644
--- a/arch/powerpc/cpu/mpc86xx/start.S
+++ b/arch/powerpc/cpu/mpc86xx/start.S
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004, 2007 Freescale Semiconductor.
+ * Copyright 2004, 2007, 2011 Freescale Semiconductor.
  * Srikanth Srinivasan <srikanth.srinivaan@freescale.com>
  *
  * See file CREDITS for list of people who contributed to this
@@ -322,6 +322,73 @@
 	sync
 	blr
 
+#define CONFIG_BAT_PAIR(n) \
+	lis	r4, CONFIG_SYS_IBAT##n##L@h; 		\
+	ori	r4, r4, CONFIG_SYS_IBAT##n##L@l; 	\
+	lis	r3, CONFIG_SYS_IBAT##n##U@h; 		\
+	ori	r3, r3, CONFIG_SYS_IBAT##n##U@l; 	\
+	mtspr	IBAT##n##L, r4; 			\
+	mtspr	IBAT##n##U, r3; 			\
+	lis	r4, CONFIG_SYS_DBAT##n##L@h; 		\
+	ori	r4, r4, CONFIG_SYS_DBAT##n##L@l; 	\
+	lis	r3, CONFIG_SYS_DBAT##n##U@h; 		\
+	ori	r3, r3, CONFIG_SYS_DBAT##n##U@l; 	\
+	mtspr	DBAT##n##L, r4;				\
+	mtspr	DBAT##n##U, r3;
+
+/*
+ * setup_bats:
+ *
+ * Set up the final BAT registers now that setup is done.
+ *
+ * Assumes that:
+ *	1) Address translation is enabled upon entry
+ *	2) The boot rom is still accessible via 1:1 translation
+ */
+	.globl setup_bats
+setup_bats:
+	mflr	r5
+	sync
+
+	/*
+	 * When we disable address translation, we will get 1:1 (VA==PA)
+	 * translation.  The only place we know for sure is safe for that is
+	 * the bootrom where we originally started out.  Pop back into there.
+	 */
+	lis	r4, CONFIG_SYS_MONITOR_BASE_EARLY@h
+	ori	r4, r4, CONFIG_SYS_MONITOR_BASE_EARLY@l
+	addi	r4, r4, trans_disabled - _start + EXC_OFF_SYS_RESET
+
+	/* disable address translation */
+	mfmsr	r3
+	rlwinm	r3, r3, 0, 28, 25
+	mtspr	SRR0, r4
+	mtspr	SRR1, r3
+	rfi
+
+trans_disabled:
+#if defined(CONFIG_SYS_DBAT0U) && defined(CONFIG_SYS_DBAT0L) \
+	&& defined(CONFIG_SYS_IBAT0U) && defined(CONFIG_SYS_IBAT0L)
+	CONFIG_BAT_PAIR(0)
+#endif
+	CONFIG_BAT_PAIR(1)
+	CONFIG_BAT_PAIR(2)
+	CONFIG_BAT_PAIR(3)
+	CONFIG_BAT_PAIR(4)
+	CONFIG_BAT_PAIR(5)
+	CONFIG_BAT_PAIR(6)
+	CONFIG_BAT_PAIR(7)
+
+	sync
+	isync
+
+	/* Turn translation back on and return */
+	mfmsr	r3
+	ori	r3, r3, (MSR_IR | MSR_DR)
+	mtspr	SPRN_SRR0,r5
+	mtspr	SPRN_SRR1,r3
+	rfi
+
 /*
  * early_bats:
  *