[U-Boot] powerpc/mpc85xx: Alignment issue when adding code to start.S

Mario Six mario.six at gdsys.cc
Tue Mar 22 09:51:17 CET 2016


Hi,

I've been implementing pre-relocation malloc for MPC58xx to enable  
CONFIG_DM on
our P1022 board (controlcenterd). The patch so far looks like this:

"

diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init_early.c  
b/arch/powerpc/cpu/mpc85xx/cpu_init_early.c
index 235a635..e6e1688 100644
--- a/arch/powerpc/cpu/mpc85xx/cpu_init_early.c
+++ b/arch/powerpc/cpu/mpc85xx/cpu_init_early.c
@@ -82,7 +82,6 @@ void setup_ifc(void)
  void cpu_init_early_f(void *fdt)
  {
  	u32 mas0, mas1, mas2, mas3, mas7;
-	int i;
  #ifdef CONFIG_SYS_FSL_ERRATUM_P1010_A003549
  	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
  #endif
@@ -95,13 +94,6 @@ void cpu_init_early_f(void *fdt)
  	/* Pointer is writable since we allocated a register for it */
  	gd = (gd_t *) (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET);

-	/*
-	 * Clear initial global data
-	 *   we don't use memset so we can share this code with NAND_SPL
-	 */
-	for (i = 0; i < sizeof(gd_t); i++)
-		((char *)gd)[i] = 0;
-
  #ifdef CONFIG_QEMU_E500
  	/*
  	 * CONFIG_SYS_CCSRBAR_PHYS below may use gd->fdt_blob on ePAPR systems,
diff --git a/arch/powerpc/cpu/mpc85xx/start.S  
b/arch/powerpc/cpu/mpc85xx/start.S
index d867e2a..faf2804 100644
--- a/arch/powerpc/cpu/mpc85xx/start.S
+++ b/arch/powerpc/cpu/mpc85xx/start.S
@@ -1152,6 +1152,29 @@ _start_cont:
  	/* Setup the stack in initial RAM,could be L2-as-SRAM or L1 dcache*/
  	lis	r3,(CONFIG_SYS_INIT_RAM_ADDR)@h
  	ori	r3,r3,((CONFIG_SYS_INIT_SP_OFFSET-16)&~0xf)@l /* Align to 16 */
+
+#ifdef CONFIG_SYS_MALLOC_F_LEN
+	/* Leave 16+ byte for back chain termination and NULL return address */
+	subi	r3,r3,((CONFIG_SYS_MALLOC_F_LEN+16+15)&~0xf)
+
+	/* End of RAM */
+	lis	r4,(CONFIG_SYS_INIT_RAM_ADDR)@h
+	ori	r4,r4,(CONFIG_SYS_INIT_RAM_SIZE)@l
+
+	li	r0,0
+
+1: 	subi 	r4,r4,4
+	stw 	r0,0(r4)
+	cmplw 	r4,r3
+	bne	1b
+
+	lis	r4,(CONFIG_SYS_INIT_RAM_ADDR)@h
+	ori	r4,r4,(CONFIG_SYS_GBL_DATA_OFFSET)@l
+
+	addi	r3,r3,16	/* Pre-relocation malloc area */
+	stw	r3,GD_MALLOC_BASE(r4)
+	subi	r3,r3,16
+#endif
  	li	r0,0
  	stw	r0,0(r3)	/* Terminate Back Chain */
  	stw	r0,+4(r3)	/* NULL return address. */
--
1.8.3

"

While tweaking the code, I found out that the board sometimes crashed and
sometimes did not crash. As it turns out, the code I added had to have a
specific length to work (the version above does not work, for example;  
but some
additional nops are enough to make it work). I suspected an alignment issue
somewhere below the function and traced it to the exception handlers that are
defined there. Specifically, the timer_interrupt exception, since the  
following
patch fixes the issue:

"
diff --git a/arch/powerpc/cpu/mpc85xx/start.S  
b/arch/powerpc/cpu/mpc85xx/start.S
index faf2804..d87c034 100644
--- a/arch/powerpc/cpu/mpc85xx/start.S
+++ b/arch/powerpc/cpu/mpc85xx/start.S
@@ -1240,6 +1240,7 @@ ProgramCheck:
  	*/
  	STD_EXCEPTION(0x0800, FPUnavailable, UnknownException)
  	STD_EXCEPTION(0x0900, SystemCall, UnknownException)
+	. = 0x0a00
  	STD_EXCEPTION(0x0a00, Decrementer, timer_interrupt)
  	STD_EXCEPTION(0x0b00, IntervalTimer, UnknownException)
  	STD_EXCEPTION(0x0c00, WatchdogTimer, UnknownException)
--
1.8.3

"

Next, I ran a bisect (since the patch worked on v2015.01 without problems) and
identified the commit 96d2bb952bbf2e5a14f6ad668312cbce3cc4485a
(powerpc/mpc85xx: Don't relocate exception vectors) as the cause. Indeed, this
commit removes the explicit alignment of the exceptions.

Possibly, some explicit alignment is needed after all?

Best regards,

Mario



More information about the U-Boot mailing list