[U-Boot-Users] [PATCH] PPC40x: Rework CFG_INIT_DCACHE_CS Block to Avoid Machine Checks

Grant Erickson gerickson at nuovations.com
Fri May 16 23:35:11 CEST 2008


This patch lays the ground work for moving out-of-assembly and unifying the SDRAM initialization code for PowerPC 405EX[r]-based boards.

include/ppc405.h:
  Wrapped casts in EBC mnemonics with a macro such that the mnemonics can be used from assembly as well as from C.

cpu/ppc4xx/start.S:
  Reworked code to handle the primordial stack and data area initialization when CFG_INIT_DCACHE_CS is asserted.

  The most important change was the addition of a 'dcba' loop (per-AMCC) to preallocate data cache blocks to be used for such a purpose. In addition, other changes include replacing magic numbers with the approriate mnemonics to improve code readability and self-documentation.

Tested On:
  AMCC "Haleakala" with:
    CFG_SDRAM_BASE=0x00000000
    CFG_INIT_DCACHE_CS=4
    CFG_INIT_RAM_ADDR=(CFG_SDRAM_BASE + (1 << 30))
    CFG_INIT_RAM_END=(4 << 10)

Signed-off-by: Grant Erickson <gerickson at nuovations.com>
---
 include/ppc405.h   |   45 +++++++++++++++++++++++++++++++++++----------
 cpu/ppc4xx/start.S |  124 +++++++++++++++++++++++++++++++++++++++-------------
 2 files changed, 128 insertions(+), 41 deletions(-)

diff --git a/include/ppc405.h b/include/ppc405.h
index 009aa68..d02eb71 100644
--- a/include/ppc405.h
+++ b/include/ppc405.h
@@ -25,6 +25,12 @@
 #define	PPC_REG_BITS		32
 #define	PPC_REG_VAL(bit, value)	((value) << ((PPC_REG_BITS - 1) - (bit)))
 
+#ifndef __ASSEMBLY__
+#define	static_cast(type, val)	(type)(val)
+#else
+#define	static_cast(type, val)	(val)
+#endif
+
 #ifndef CONFIG_IOP480
 #define CFG_DCACHE_SIZE		(16 << 10)	/* For AMCC 405 CPUs	*/
 #else
@@ -371,7 +377,8 @@
 
 /* Bank Configuration Register */
 #define	EBC_BXCR_BAS_MASK	PPC_REG_VAL(11, 0xFFF)
-#define EBC_BXCR_BAS_ENCODE(n)	((((unsigned long)(n))&EBC_BXCR_BAS_MASK)<<0)
+#define EBC_BXCR_BAS_ENCODE(n)	(((static_cast(unsigned long, n)) & \
+				  EBC_BXCR_BAS_MASK) << 0)
 #define EBC_BXCR_BS_MASK	PPC_REG_VAL(14, 0x7)
 #define EBC_BXCR_BS_1MB		PPC_REG_VAL(14, 0x0)
 #define EBC_BXCR_BS_2MB		PPC_REG_VAL(14, 0x1)
@@ -394,9 +401,15 @@
 /* Bank Access Parameter Register */
 #define EBC_BXAP_BME_ENABLED	PPC_REG_VAL(0, 0x1)
 #define EBC_BXAP_BME_DISABLED	PPC_REG_VAL(0, 0x0)
-#define EBC_BXAP_TWT_ENCODE(n)	PPC_REG_VAL(8, ((unsigned long)(n)) & 0xFF)
-#define	EBC_BXAP_FWT_ENCODE(n)	PPC_REG_VAL(5, ((unsigned long)(n)) & 0x1F)
-#define	EBC_BXAP_BWT_ENCODE(n)	PPC_REG_VAL(8, ((unsigned long)(n)) & 0x7)
+#define EBC_BXAP_TWT_ENCODE(n)	PPC_REG_VAL(8, \
+					    (static_cast(unsigned long, n)) \
+					    & 0xFF)
+#define	EBC_BXAP_FWT_ENCODE(n)	PPC_REG_VAL(5, \
+					    (static_cast(unsigned long, n)) \
+					    & 0x1F)
+#define	EBC_BXAP_BWT_ENCODE(n)	PPC_REG_VAL(8, \
+					    (static_cast(unsigned long, n)) \
+					    & 0x7)
 #define EBC_BXAP_BCE_DISABLE	PPC_REG_VAL(9, 0x0)
 #define EBC_BXAP_BCE_ENABLE	PPC_REG_VAL(9, 0x1)
 #define EBC_BXAP_BCT_MASK	PPC_REG_VAL(11, 0x3)
@@ -404,11 +417,21 @@
 #define EBC_BXAP_BCT_4TRANS	PPC_REG_VAL(11, 0x1)
 #define EBC_BXAP_BCT_8TRANS	PPC_REG_VAL(11, 0x2)
 #define EBC_BXAP_BCT_16TRANS	PPC_REG_VAL(11, 0x3)
-#define EBC_BXAP_CSN_ENCODE(n)	PPC_REG_VAL(13, ((unsigned long)(n)) & 0x3)
-#define EBC_BXAP_OEN_ENCODE(n)	PPC_REG_VAL(15, ((unsigned long)(n)) & 0x3)
-#define EBC_BXAP_WBN_ENCODE(n)	PPC_REG_VAL(17, ((unsigned long)(n)) & 0x3)
-#define EBC_BXAP_WBF_ENCODE(n)	PPC_REG_VAL(19, ((unsigned long)(n)) & 0x3)
-#define EBC_BXAP_TH_ENCODE(n)	PPC_REG_VAL(22, ((unsigned long)(n)) & 0x7)
+#define EBC_BXAP_CSN_ENCODE(n)	PPC_REG_VAL(13, \
+					    (static_cast(unsigned long, n)) \
+					    & 0x3)
+#define EBC_BXAP_OEN_ENCODE(n)	PPC_REG_VAL(15, \
+					    (static_cast(unsigned long, n)) \
+					    & 0x3)
+#define EBC_BXAP_WBN_ENCODE(n)	PPC_REG_VAL(17, \
+					    (static_cast(unsigned long, n)) \
+					    & 0x3)
+#define EBC_BXAP_WBF_ENCODE(n)	PPC_REG_VAL(19, \
+					    (static_cast(unsigned long, n)) \
+					    & 0x3)
+#define EBC_BXAP_TH_ENCODE(n)	PPC_REG_VAL(22, \
+					    (static_cast(unsigned long, n)) \
+					    & 0x7)
 #define EBC_BXAP_RE_ENABLED	PPC_REG_VAL(23, 0x1)
 #define EBC_BXAP_RE_DISABLED	PPC_REG_VAL(23, 0x0)
 #define EBC_BXAP_SOR_DELAYED	PPC_REG_VAL(24, 0x0)
@@ -453,7 +476,9 @@
 #define EBC_CFG_PME_DISABLE	PPC_REG_VAL(14, 0x0)
 #define EBC_CFG_PME_ENABLE	PPC_REG_VAL(14, 0x1)
 #define EBC_CFG_PMT_MASK	PPC_REG_VAL(19, 0x1F)
-#define EBC_CFG_PMT_ENCODE(n)	PPC_REG_VAL(19, ((unsigned long)(n)) & 0x1F)
+#define EBC_CFG_PMT_ENCODE(n)	PPC_REG_VAL(19, \
+					    (static_cast(unsigned long, n)) \
+					    & 0x1F)
 #define EBC_CFG_PR_MASK		PPC_REG_VAL(21, 0x3)
 #define EBC_CFG_PR_16		PPC_REG_VAL(21, 0x0)
 #define EBC_CFG_PR_32		PPC_REG_VAL(21, 0x1)
diff --git a/cpu/ppc4xx/start.S b/cpu/ppc4xx/start.S
index a513b45..92eb925 100644
--- a/cpu/ppc4xx/start.S
+++ b/cpu/ppc4xx/start.S
@@ -108,6 +108,34 @@
 #  define PBxAP pb7ap
 #  define PBxCR pb7cr
 # endif
+/*
+ * Memory Bank x (nothingness) initialization CFG_INIT_RAM_ADDR + 64 MiB
+ * used as temporary stack pointer for the primordial stack
+ */
+# ifndef CFG_INIT_DCACHE_PBxAR
+#  define CFG_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 /* CFG_INIT_DCACHE_PBxAR */
+# ifndef CFG_INIT_DCACHE_PBxCR
+#  define CFG_INIT_DCACHE_PBxCR	(EBC_BXCR_BAS_ENCODE(CFG_INIT_RAM_ADDR)	| \
+		      		 EBC_BXCR_BS_64MB			| \
+				 EBC_BXCR_BU_RW				| \
+				 EBC_BXCR_BW_16BIT)
+# endif /* CFG_INIT_DCACHE_PBxCR */
+# ifndef CFG_INIT_RAM_PATTERN
+#  define CFG_INIT_RAM_PATTERN	0xDEADDEAD
+# endif
 #endif /* CFG_INIT_DCACHE_CS */
 
 #if (defined(CFG_INIT_RAM_DCACHE) && (CFG_INIT_RAM_END > (4 << 10)))
@@ -922,9 +950,9 @@ _start:
 #endif
 #if !(defined(CFG_INIT_DCACHE_CS) || defined(CFG_TEMP_STACK_OCM))
 	/*
-	 * Boards like the Kilauea (405EX) don't have OCM and can't use
-	 * DCache for init-ram. So setup stack here directly after the
-	 * SDRAM is initialized.
+	 * 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, CFG_INIT_RAM_ADDR at h
 	ori	r1,r1,CFG_INIT_SP_OFFSET /* set up the stack in SDRAM */
@@ -1043,47 +1071,81 @@ start_ram:
 	/* Setup temporary stack in DCACHE or OCM if needed for SDRAM SPD. */
 	/*----------------------------------------------------------------------- */
 #ifdef CFG_INIT_DCACHE_CS
-	/*----------------------------------------------------------------------- */
-	/* Memory Bank x (nothingness) initialization 1GB+64MEG */
-	/* used as temporary stack pointer for stage0  */
-	/*----------------------------------------------------------------------- */
-	li	r4,PBxAP
-	mtdcr	ebccfga,r4
-	lis	r4,0x0380
-	ori	r4,r4,0x0480
-	mtdcr	ebccfgd,r4
-
-	addi	r4,0,PBxCR
-	mtdcr	ebccfga,r4
-	lis	r4,0x400D
-	ori	r4,r4,0xa000
-	mtdcr	ebccfgd,r4
+	li	r4, PBxAP
+	mtdcr	ebccfga, r4
+	lis	r4, CFG_INIT_DCACHE_PBxAR at h
+	ori	r4, r4, CFG_INIT_DCACHE_PBxAR at l
+	mtdcr	ebccfgd, r4
+
+	addi	r4, 0, PBxCR
+	mtdcr	ebccfga, r4
+	lis	r4, CFG_INIT_DCACHE_PBxCR at h
+	ori	r4, r4, CFG_INIT_DCACHE_PBxCR at l
+	mtdcr	ebccfgd, r4
 
 	/* turn on data cache for this region */
-	lis	r4,0x0080
+	lis	r4, 0x0080
 	mtdccr	r4
 
-	/* set stack pointer and clear stack to known value */
+	/*
+	 * 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	r1,CFG_INIT_RAM_ADDR at h
-	ori	r1,r1,CFG_INIT_SP_OFFSET at l
+	lis	r3, CFG_INIT_RAM_ADDR at h
+	ori	r3, r3, CFG_INIT_RAM_ADDR at l
+
+	lis	r4, CFG_INIT_RAM_END at h
+	ori	r4, r4, CFG_INIT_RAM_END at 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
 
-	li	r4,2048			/* we store 2048 words to stack */
+	/* 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, CFG_INIT_RAM_ADDR at h
+	ori	r1, r1, CFG_INIT_SP_OFFSET at l
+
+	lis	r4, (CFG_INIT_RAM_END >> 2)@h
+	ori	r4, r4, (CFG_INIT_RAM_END >> 2)@l
 	mtctr	r4
 
-	lis	r2,CFG_INIT_RAM_ADDR at h		/* we also clear data area */
-	ori	r2,r2,CFG_INIT_RAM_END at l	/* so cant copy value from r1 */
+	lis	r2, CFG_INIT_RAM_ADDR at h
+	ori	r2, r2, CFG_INIT_RAM_END at l
 
-	lis	r4,0xdead		/* we store 0xdeaddead in the stack */
-	ori	r4,r4,0xdead
+	lis	r4, CFG_INIT_RAM_PATTERN at h
+	ori	r4, r4, CFG_INIT_RAM_PATTERN at l
 
 ..stackloop:
-	stwu	r4,-4(r2)
+	stwu	r4, -4(r2)
 	bdnz	..stackloop
 
-	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	*/
+	/*
+	 * 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.
-- 
1.5.4.3





More information about the U-Boot mailing list