From: Masahiro Yamada Date: Wed, 7 Jan 2015 10:41:38 +0000 (+0900) Subject: ARM: UniPhier: remove __packed that causes a problem on GCC 4.9 X-Git-Url: http://git.dujemihanovic.xyz/?a=commitdiff_plain;h=d6bc30af524463b8020329b80150e773bbc77d27;p=u-boot.git ARM: UniPhier: remove __packed that causes a problem on GCC 4.9 The DDR PHY training function, ddrphy_prepare_training() would not work if compiled with GCC 4.9. The struct ddrphy (arch/arm/include/asm/arch-uniphier/ddrphy-regs.h) is specified with __packed because it represents a hardware register mapping, but it turned out to cause a problem on GCC 4.9. If -mno-unaligned-access is specified (yes, it is in arch/arm/cpu/armv7/config.mk), GCC 4.9 is aware of the __attribute__((packed)) and generates extra instructions to perform the memory access in a way that does not cause unaligned access. (Actually it is not need here because the register base, the first argument of the ddrphy_prepare_training(), is always given with a 4-byte aligned address.) Anyway, as a result, readl() / writel() is divided into byte-wise accesses. The problem is that this hardware only accepts 4-byte register access. Byte-wise accesses lead to unexpected behavior. There are some options to avoid this problem. [1] Remove -mno-unaligned-access [2] Add __aligned(4) along with __packed to struct ddrphy [3] Remove __packed from struct ddrphy [1] solves the problem for ARMv7, but it does not for pre-ARMv6 and ARMv6-M architectures where -mno-unaligned-access is default. So, [1] does not seem reasonable in terms of code portability. Both [2] and [3] work well, but [2] seems too much. All the members of struct ddrphy have the u32 type. No padding would be inserted even if __packed is dropped. Signed-off-by: Masahiro Yamada Reviewed-by: Tom Rini --- diff --git a/arch/arm/include/asm/arch-uniphier/ddrphy-regs.h b/arch/arm/include/asm/arch-uniphier/ddrphy-regs.h index 484559c6cd..6b7d600a9c 100644 --- a/arch/arm/include/asm/arch-uniphier/ddrphy-regs.h +++ b/arch/arm/include/asm/arch-uniphier/ddrphy-regs.h @@ -72,7 +72,7 @@ struct ddrphy { u32 gtr; /* General Timing Register */ u32 rsv[3]; /* Reserved */ } dx[9]; -} __packed; +}; #endif /* __ASSEMBLY__ */