Skip to contentSkip to conversation

PPC4xx: Enable Primordial Stack for 40x and Unify ECC Handling

PATCH Superseded Grant Erickson 2 participants 2 messages May 21, 2008 – May 22, 2008

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

PATCH v2 1/2 PPC4xx: Enable Primordial Stack for 40x and Unify ECC Handling

This patch (Part 1 of 2):

* Rolls up a suite of changes to enable correct primordial stack and global data handling when the data cache is used for such a purpose for PPC40x-variants (i.e. CFG_INIT_DCACHE_CS).

* Related to the first, unifies DDR2 SDRAM and ECC initialization by eliminating redundant ECC initialization implementations and moving redundant SDRAM initialization out of board code into shared 4xx code.

* Enables MCSR visibility on the 405EX(r).

* Enables the use of the data cache for initial RAM on both AMCC's Kilauea and Makalu and removes a redundant CFG_POST_MEMORY flag from each board's CONFIG_POST value.

With respect to the 4xx DDR initialization and ECC unification, there is certainly more work that can and should be done (file renaming, etc.). However, that can be handled at a later date on a second or third pass. As it stands, this patch moves things forward in an incremental yet positive way for those platforms that utilize this code and the features associated with it.

---
 cpu/ppc4xx/44x_spd_ddr.c    |   49 +-------
 cpu/ppc4xx/44x_spd_ddr2.c   |  120 ++++++++++++++++-
 cpu/ppc4xx/Makefile         |    1 +
 cpu/ppc4xx/cpu_init.c       |   85 ------------
 cpu/ppc4xx/ecc.c            |  121 +++++++++++++++++
 cpu/ppc4xx/ecc.h            |   42 ++++++
 cpu/ppc4xx/sdram.c          |   44 +------
 cpu/ppc4xx/start.S          |  303 +++++++++++++++++++++++++++++++++----------
 cpu/ppc4xx/traps.c          |    9 +-
 include/asm-ppc/processor.h |    6 +-
 include/ppc405.h            |  193 +++++++++++++++++++++++++--
 include/ppc4xx.h            |   15 ++
 12 files changed
cpu/ppc4xx/44x_spd_ddr.c +3 -46
index b9cf5cb..b7eeaf2 100644
@@ -53,6 +53,8 @@
 #include <ppc4xx.h>
 #include <asm/mmu.h>
 
+#include "ecc.h"
+
 #if defined(CONFIG_SPD_EEPROM) &&					\
 	(defined(CONFIG_440GP) || defined(CONFIG_440GX) ||		\
 	 defined(CONFIG_440EP) || defined(CONFIG_440GR))
@@ -296,10 +298,6 @@ static void program_tr0(unsigned long *dimm_populated,
 			unsigned long num_dimm_banks);
 static void program_tr1(void);
 
-#ifdef CONFIG_DDR_ECC
-static void program_ecc(unsigned long num_bytes);
-#endif
-
 static unsigned long program_bxcr(unsigned long *dimm_populated,
 				  unsigned char *iic0_dimm_addr,
 				  unsigned long num_dimm_banks);
@@ -418,7 +416,7 @@ long int spd_sdram(void) {
 	/*
 	 * If ecc is enabled, initialize the parity bits.
 	 */
-	program_ecc(total_size);
+	ecc_init(CFG_SDRAM_BASE, total_size);
 #endif
 
 	return total_size;
@@ -1402,45 +1400,4 @@ static unsigned long program_bxcr(unsigned long *dimm_populated,
 
 	return(bank_base_addr);
 }
-
-#ifdef CONFIG_DDR_ECC
-static void program_ecc(unsigned long num_bytes)
-{
-	unsigned long bank_base_addr;
-	unsigned long current_address;
-	unsigned long end_address;
-	unsigned long address_increment;
-	unsigned long cfg0;
-
-	/*
-	 * get Memory Controller Options 0 data
-	 */
-	mfsdram(mem_cfg0, cfg0);
-
-	/*
-	 * reset the bank_base address
-	 */
-	bank_base_addr = CFG_SDRAM_BASE;
-
-	if ((cfg0 & SDRAM_CFG0_MCHK_MASK) != SDRAM_CFG0_MCHK_NON) {
-		mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) | SDRAM_CFG0_MCHK_GEN);
-
-		if ((cfg0 & SDRAM_CFG0_DMWD_MASK) == SDRAM_CFG0_DMWD_32)
-			address_increment = 4;
-		else
-			address_increment = 8;
-
-		current_address = (unsigned long)(bank_base_addr);
-		end_address = (unsigned long)(bank_base_addr) + num_bytes;
-
-		while (current_address < end_address) {
-			*((unsigned long*)current_address) = 0x00000000;
-			current_address += address_increment;
-		}
-
-		mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) |
-			SDRAM_CFG0_MCHK_CHK);
-	}
-}
-#endif /* CONFIG_DDR_ECC */
 #endif /* CONFIG_SPD_EEPROM */
cpu/ppc4xx/44x_spd_ddr2.c +116 -4

140 lines not on this page · raw message

cpu/ppc4xx/Makefile +1 -0
index 178c5c6..800bb41 100644
@@ -45,6 +45,7 @@ COBJS	+= cpu.o
 COBJS	+= cpu_init.o
 COBJS	+= denali_data_eye.o
 COBJS	+= denali_spd_ddr2.o
+COBJS	+= ecc.o
 COBJS	+= fdt.o
 COBJS	+= gpio.o
 COBJS	+= i2c.o
cpu/ppc4xx/cpu_init.c +0 -85

97 lines not on this page · raw message

cpu/ppc4xx/ecc.c new file +121 -0

121 lines not on this page · raw message

cpu/ppc4xx/ecc.h new file +42 -0

42 lines not on this page · raw message

cpu/ppc4xx/sdram.c +1 -43

56 lines not on this page · raw message

cpu/ppc4xx/start.S +234 -69

421 lines not on this page · raw message

cpu/ppc4xx/traps.c +7 -2
index 38b6f89..8b7e32a 100644
@@ -170,7 +170,7 @@ MachineCheckException(struct pt_regs *regs)
 
 	val = get_esr();
 
-#if !defined(CONFIG_440)
+#if !defined(CONFIG_440) && !defined(CONFIG_405EX)
 	if (val& ESR_IMCP) {
 		printf("Instruction");
 		mtspr(ESR, val & ~ESR_IMCP);
@@ -179,7 +179,7 @@ MachineCheckException(struct pt_regs *regs)
 	}
 	printf(" machine check.\n");
 
-#elif defined(CONFIG_440)
+#elif defined(CONFIG_440) || defined(CONFIG_405EX)
 	if (val& ESR_IMCP){
 		printf("Instruction Synchronous Machine Check exception\n");
 		mtspr(SPRN_ESR, val & ~ESR_IMCP);
@@ -187,10 +187,15 @@ MachineCheckException(struct pt_regs *regs)
 		val = mfspr(MCSR);
 		if (val & MCSR_IB)
 			printf("Instruction Read PLB Error\n");
+#if defined(CONFIG_440)
 		if (val & MCSR_DRB)
 			printf("Data Read PLB Error\n");
 		if (val & MCSR_DWB)
 			printf("Data Write PLB Error\n");
+#else
+		if (val & MCSR_DB)
+			printf("Data PLB Error\n");
+#endif
 		if (val & MCSR_TLBP)
 			printf("TLB Parity Error\n");
 		if (val & MCSR_ICP){
include/asm-ppc/processor.h +4 -2
index 8bdfb9d..cfd8440 100644
@@ -460,17 +460,19 @@
 #define SPRN_PID2	0x27a	/* Process ID Register 2 */
 #define SPRN_MCSR	0x23c	/* Machine Check Syndrome register */
 #define SPRN_MCAR	0x23d	/* Machine Check Address register */
-#ifdef CONFIG_440
 #define MCSR_MCS	0x80000000	/* Machine Check Summary */
 #define MCSR_IB		0x40000000	/* Instruction PLB Error */
+#if defined(CONFIG_440)
 #define MCSR_DRB	0x20000000	/* Data Read PLB Error */
 #define MCSR_DWB	0x10000000	/* Data Write PLB Error */
+#else
+#define MCSR_DB		0x20000000	/* Data PLB Error */
+#endif /* defined(CONFIG_440) */
 #define MCSR_TLBP	0x08000000	/* TLB Parity Error */
 #define MCSR_ICP	0x04000000	/* I-Cache Parity Error */
 #define MCSR_DCSP	0x02000000	/* D-Cache Search Parity Error */
 #define MCSR_DCFP	0x01000000	/* D-Cache Flush Parity Error */
 #define MCSR_IMPE	0x00800000	/* Imprecise Machine Check Exception */
-#endif
 #define ESR_ST		0x00800000	/* Store Operation */
 
 #if defined(CONFIG_MPC86xx)
include/ppc405.h +179 -14

216 lines not on this page · raw message

include/ppc4xx.h +15 -0
index 76fe872..4a6eb86 100644
@@ -29,6 +29,21 @@
 #endif
 
 /*
+ * Macro for generating register field mnemonics
+ */
+#define	PPC_REG_BITS		32
+#define	PPC_REG_VAL(bit, value)	((value) << ((PPC_REG_BITS - 1) - (bit)))
+
+/*
+ * Elide casts when assembling register mnemonics
+ */
+#ifndef __ASSEMBLY__
+#define	static_cast(type, val)	(type)(val)
+#else
+#define	static_cast(type, val)	(val)
+#endif
+
+/*
  * Common stuff for 4xx (405 and 440)
  */
 
#1 lore raw

PATCH v2 1/2 PPC4xx: Enable Primordial Stack for 40x and Unify ECC Handling

Grant,

Quoted 1 line · Grant Erickson

This patch (Part 1 of 2):

Again, please find some comments below.

<snip>

Quoted 117 lines
cpu/ppc4xx/start.S +0 -0
index a513b45..e43da7b 100644
@@ -3,6 +3,8 @@
  *  Copyright (C) 1999	Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
  *  Copyright (C) 2000,2001,2002 Wolfgang Denk <[email protected]>
  *  Copyright (C) 2007 Stefan Roese <[email protected]>, DENX Software

Engineering + * Copyright (c) 2008 Nuovation System Designs, LLC
+ * Grant Erickson <[email protected]>
*
* See file CREDITS for list of people who contributed to this
* project.

cpu/ppc4xx/start.S +65 -0
@@ -79,34 +81,100 @@
 # if (CFG_INIT_DCACHE_CS == 0)
 #  define PBxAP pb0ap
 #  define PBxCR pb0cr
+#  if (defined(CFG_EBC_PB0AP) && defined(CFG_EBC_PB0CR))
+#   define PBxAP_VAL CFG_EBC_PB0AP
+#   define PBxCR_VAL CFG_EBC_PB0CR
+#  endif
 # endif
 # if (CFG_INIT_DCACHE_CS == 1)
 #  define PBxAP pb1ap
 #  define PBxCR pb1cr
+#  if (defined(CFG_EBC_PB1AP) && defined(CFG_EBC_PB1CR))
+#   define PBxAP_VAL CFG_EBC_PB1AP
+#   define PBxCR_VAL CFG_EBC_PB1CR
+#  endif
 # endif
 # if (CFG_INIT_DCACHE_CS == 2)
 #  define PBxAP pb2ap
 #  define PBxCR pb2cr
+#  if (defined(CFG_EBC_PB2AP) && defined(CFG_EBC_PB2CR))
+#   define PBxAP_VAL CFG_EBC_PB2AP
+#   define PBxCR_VAL CFG_EBC_PB2CR
+#  endif
 # endif
 # if (CFG_INIT_DCACHE_CS == 3)
 #  define PBxAP pb3ap
 #  define PBxCR pb3cr
+#  if (defined(CFG_EBC_PB3AP) && defined(CFG_EBC_PB3CR))
+#   define PBxAP_VAL CFG_EBC_PB3AP
+#   define PBxCR_VAL CFG_EBC_PB3CR
+#  endif
 # endif
 # if (CFG_INIT_DCACHE_CS == 4)
 #  define PBxAP pb4ap
 #  define PBxCR pb4cr
+#  if (defined(CFG_EBC_PB4AP) && defined(CFG_EBC_PB4CR))
+#   define PBxAP_VAL CFG_EBC_PB4AP
+#   define PBxCR_VAL CFG_EBC_PB4CR
+#  endif
 # endif
 # if (CFG_INIT_DCACHE_CS == 5)
 #  define PBxAP pb5ap
 #  define PBxCR pb5cr
+#  if (defined(CFG_EBC_PB5AP) && defined(CFG_EBC_PB5CR))
+#   define PBxAP_VAL CFG_EBC_PB5AP
+#   define PBxCR_VAL CFG_EBC_PB5CR
+#  endif
 # endif
 # if (CFG_INIT_DCACHE_CS == 6)
 #  define PBxAP pb6ap
 #  define PBxCR pb6cr
+#  if (defined(CFG_EBC_PB6AP) && defined(CFG_EBC_PB6CR))
+#   define PBxAP_VAL CFG_EBC_PB6AP
+#   define PBxCR_VAL CFG_EBC_PB6CR
+#  endif
 # endif
 # if (CFG_INIT_DCACHE_CS == 7)
 #  define PBxAP pb7ap
 #  define PBxCR pb7cr
+#  if (defined(CFG_EBC_PB7AP) && defined(CFG_EBC_PB7CR))
+#   define PBxAP_VAL CFG_EBC_PB7AP
+#   define PBxCR_VAL CFG_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 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 */
@@ -840,15 +908,25 @@ _start:
 	/* make sure above stores all comlete before going on */
 	sync

cpu/ppc4xx/start.S _start: · line 916

Quoted 10 lines
cpu/ppc4xx/start.S +4 -3
 
-	/*-----------------------------------------------------------------------
 */ -	/* Enable two 128MB cachable regions. */
-	/*-----------------------------------------------------------------------
 */ -	addis	r1,r0,0xc000
-	addi	r1,r1,0x0001
+	/*---------------------------------------------------------------------
+	 * Enable two 128MB cachable instruction regions at CFG_SDRAM_BASE
+	 * and another 128MB cacheable instruction region covering NOR flash
+	 * at CFG_FLASH_BASE. Disbale all cacheable data regions.

"Disable" instead of "Disbale".

cpu/ppc4xx/start.S _start: · line 919

Quoted 5 lines
cpu/ppc4xx/start.S +5 -0
+	 *------------------------------------------------------------------ */
+
+#define ICSACRVAL	(PPC_128MB_SACR_VALUE(CFG_SDRAM_BASE + (  0 << 20)) | \
+			 PPC_128MB_SACR_VALUE(CFG_SDRAM_BASE + (128 << 20)) | \
+			 PPC_128MB_SACR_VALUE(CFG_FLASH_BASE))

I don't like these #defines within the code. Please move them to the top of the file.

cpu/ppc4xx/start.S _start: · line 926

Quoted 8 lines
cpu/ppc4xx/start.S +4 -2
+	lis	r1, ICSACRVAL at h
+	ori	r1, r1, ICSACRVAL at l
 	mticcr	r1			/* instruction cache */
+	isync
 
-	addis	r1,r0,0x0000
-	addi	r1,r1,0x0000
+#define DCSACRVAL	0x00000000

Same here.

Quoted 13 lines
cpu/ppc4xx/start.S +2 -2
+	lis	r1, DCSACRVAL at h
+	ori	r1, r1, DCSACRVAL at l
 	mtdccr	r1			/* data cache */
 
 	addis	r1,r0,CFG_INIT_RAM_ADDR at h
@@ -902,16 +980,25 @@ _start:
 	bl	invalidate_icache
 	bl	invalidate_dcache
 
-	/*-----------------------------------------------------------------------
 */ -	/* Enable two 128MB cachable regions. */
-	/*-----------------------------------------------------------------------
 */ -	lis	r4,0xc000

cpu/ppc4xx/start.S _start: · line 993

Quoted 10 lines
cpu/ppc4xx/start.S +9 -1
-	ori	r4,r4,0x0001
+	/*---------------------------------------------------------------------
+	 * Enable two 128MB cachable instruction regions at CFG_SDRAM_BASE
+	 * and another 128MB cacheable instruction region covering NOR flash
+	 * at CFG_FLASH_BASE. Disbale all cacheable data regions.
+	 *------------------------------------------------------------------ */
+
+#define ICSACRVAL	(PPC_128MB_SACR_VALUE(CFG_SDRAM_BASE + (  0 << 20)) | \
+			 PPC_128MB_SACR_VALUE(CFG_SDRAM_BASE + (128 << 20)) | \
+			 PPC_128MB_SACR_VALUE(CFG_FLASH_BASE))

And now it's defined twice. Please remove.

cpu/ppc4xx/start.S _start: · line 998

Quoted 8 lines
cpu/ppc4xx/start.S +3 -2
+	lis	r4, ICSACRVAL at h
+	ori	r4, r4, ICSACRVAL at l
 	mticcr	r4			/* instruction cache */
 	isync
 
-	lis	r4,0x0000
-	ori	r4,r4,0x0000
+#define DCSACRVAL	0x00000000

Here too.

Please fix and resubmit. Thanks.

Best regards,
Stefan

=====================================================================
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office at denx.de
=====================================================================