[U-Boot] [PATCH v3 3/8] arm: Only do CP15 init on ARMv7

Simon Glass sjg at chromium.org
Mon Oct 31 23:03:07 CET 2011


Some SOCs have do not start up with their 'main' CPU. The first U-Boot
code may then be executed with a CPU which does not have a CP15.

Here we split the initialization of CP15 into a separate call, and only
do it if we detect an ARMv7 chip.

The test for ARMv7 cannot use CP15, since this may trigger an undefined
instruction exception on an ARM7TDMI, so we check for a Q bit in the
APSR instead.

An alternative to this is to make boards set CONFIG_SKIP_LOWLEVEL_INIT
and then call cpu_init_cp15() later. However after much discussion on
the U-Boot mailing list this was rejected as undesirable.

See: http://patchwork.ozlabs.org/patch/119621/

Signed-off-by: Simon Glass <sjg at chromium.org>
---
Changes in v3:
- Update comment and also make it match style
- Fix cpu_init_cp15() name
- Remove exporting of cpu_init_cp15() from start.S
- Add test for ARMv7 CPU and skip CP15 init if not found

 arch/arm/cpu/armv7/start.S |   45 ++++++++++++++++++++++++-------------------
 1 files changed, 25 insertions(+), 20 deletions(-)

diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S
index db8e9d2..528585f 100644
--- a/arch/arm/cpu/armv7/start.S
+++ b/arch/arm/cpu/armv7/start.S
@@ -168,7 +168,23 @@ next:
 #endif
 	/* the mask ROM code should have PLL and others stable */
 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
-	bl	cpu_init_crit
+	@ Try to set the Q bit in the APSR. If this fails, we are not ARMv7
+	@ An ARM7TDMI will see APSR_nzcvq as CPSR_f (they are equivalent)
+	@ and we use that syntax to be kind to older tool chains
+	msr	CPSR_f, #0x08000000	@ set Q bit
+	mrs	r0, CPSR		@ see if it is still there
+	tst	r0, #0x08000000
+	blne	cpu_init_cp15		@ if so, we are ARMv7, so init it!
+
+	msr	CPSR_f, #0x00		@ clear Q bit
+
+	/*
+	 * Jump to board specific initialization...
+	 * The Mask ROM will have already initialized
+	 * basic memory. Go here to bump up clock rate and handle
+	 * wake up conditions.
+	 */
+	bl	lowlevel_init		@ go setup pll,mux,memory
 #endif
 
 /* Set stackpointer in internal RAM to call board_init_f */
@@ -307,15 +323,14 @@ _board_init_r_ofs:
 
 
 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
-/*************************************************************************
- *
- * CPU_init_critical registers
- *
- * setup important registers
- * setup memory timing
+/*
+ * cpu_init_cp15
  *
- *************************************************************************/
-cpu_init_crit:
+ * Setup CP15 registers (cache, MMU, TLBs) to initial reset values. The MMU
+ * and D-cache are turned off. The I-cache is turned on unless
+ * CONFIG_SYS_ICACHE_OFF is defined.
+ */
+cpu_init_cp15:
 	/*
 	 * Invalidate L1 I/D
 	 */
@@ -340,18 +355,8 @@ cpu_init_crit:
 	orr	r0, r0, #0x00001000	@ set bit 12 (I) I-cache
 #endif
 	mcr	p15, 0, r0, c1, c0, 0
-
-	/*
-	 * Jump to board specific initialization...
-	 * The Mask ROM will have already initialized
-	 * basic memory. Go here to bump up clock rate and handle
-	 * wake up conditions.
-	 */
-	mov	ip, lr			@ persevere link reg across call
-	bl	lowlevel_init		@ go setup pll,mux,memory
-	mov	lr, ip			@ restore link
 	mov	pc, lr			@ back to my caller
-#endif
+#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
 
 #ifndef CONFIG_SPL_BUILD
 /*
-- 
1.7.3.1



More information about the U-Boot mailing list