mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH 0/6] i.MX: Fix external NAND boot
@ 2020-02-18 15:37 Sascha Hauer
  2020-02-18 15:37 ` [PATCH 1/6] ARM: i.MX Phytec phycard i.MX27: get fdt in common init function Sascha Hauer
                   ` (5 more replies)
  0 siblings, 6 replies; 10+ messages in thread
From: Sascha Hauer @ 2020-02-18 15:37 UTC (permalink / raw)
  To: Barebox List

The external NAND boot on i.MX is broken since b0348d677b ("ARM: Compile
with -fPIE"). This series fixes it.

Sascha Hauer (6):
  ARM: i.MX Phytec phycard i.MX27: get fdt in common init function
  ARM: i.MX Phytec phycard i.MX27: replace __naked with noinline
  ARM: i.MX Phytec phycore i.MX27: replace __naked with noinline
  ARM: i.MX: external NAND boot: remove unnecessary arguments from
    imx*_nand_load_image
  ARM: i.MX: external NAND boot: Leave icache disabled
  ARM: i.MX: external NAND boot: Fix passing boarddata

 arch/arm/boards/eukrea_cpuimx25/lowlevel.c    |   2 +-
 arch/arm/boards/eukrea_cpuimx35/lowlevel.c    |   2 +-
 arch/arm/boards/guf-cupid/lowlevel.c          |   2 +-
 arch/arm/boards/guf-neso/lowlevel.c           |   2 +-
 arch/arm/boards/karo-tx25/lowlevel.c          |  34 ++-
 .../boards/phytec-phycard-imx27/lowlevel.c    |  38 ++-
 .../boards/phytec-phycore-imx27/lowlevel.c    |  36 ++-
 .../boards/phytec-phycore-imx31/lowlevel.c    |   2 +-
 .../boards/phytec-phycore-imx35/lowlevel.c    |   2 +-
 arch/arm/cpu/lowlevel.S                       |   2 +
 arch/arm/mach-imx/external-nand-boot.c        | 274 ++++++++++--------
 arch/arm/mach-imx/include/mach/imx-nand.h     |  19 +-
 12 files changed, 248 insertions(+), 167 deletions(-)

-- 
2.25.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/6] ARM: i.MX Phytec phycard i.MX27: get fdt in common init function
  2020-02-18 15:37 [PATCH 0/6] i.MX: Fix external NAND boot Sascha Hauer
@ 2020-02-18 15:37 ` Sascha Hauer
  2020-02-18 15:37 ` [PATCH 2/6] ARM: i.MX Phytec phycard i.MX27: replace __naked with noinline Sascha Hauer
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Sascha Hauer @ 2020-02-18 15:37 UTC (permalink / raw)
  To: Barebox List

No need to get the fdt pointer in the entry functions, we can do this
later.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 .../boards/phytec-phycard-imx27/lowlevel.c    | 21 +++++++------------
 1 file changed, 8 insertions(+), 13 deletions(-)

diff --git a/arch/arm/boards/phytec-phycard-imx27/lowlevel.c b/arch/arm/boards/phytec-phycard-imx27/lowlevel.c
index bd46df0962..ded85ee80f 100644
--- a/arch/arm/boards/phytec-phycard-imx27/lowlevel.c
+++ b/arch/arm/boards/phytec-phycard-imx27/lowlevel.c
@@ -77,8 +77,11 @@ static void sdram_init(int sdram)
 			MX27_ESDCTL_BASE_ADDR + IMX_ESDCTL0);
 }
 
-static void __bare_init __naked phytec_phycard_imx27_common_init(void *fdt, int sdram)
+extern char __dtb_imx27_phytec_phycard_s_rdk_bb_start[];
+
+static void __bare_init __naked phytec_phycard_imx27_common_init(int sdram)
 {
+	void *fdt;
 	unsigned long r;
 
 	arm_cpu_lowlevel_init();
@@ -89,6 +92,8 @@ static void __bare_init __naked phytec_phycard_imx27_common_init(void *fdt, int
 	writel(0x00000000, MX27_AIPI_BASE_ADDR + MX27_AIPI2_PSR0);
 	writel(0xffffffff, MX27_AIPI_BASE_ADDR + MX27_AIPI2_PSR1);
 
+	fdt = __dtb_imx27_phytec_phycard_s_rdk_bb_start + get_runtime_offset();
+
 	/* Skip SDRAM initialization if we run from RAM */
         r = get_pc();
         if (r > 0xa0000000 && r < 0xc0000000)
@@ -120,26 +125,16 @@ static void __bare_init __naked phytec_phycard_imx27_common_init(void *fdt, int
 	imx27_barebox_boot_nand_external(fdt);
 }
 
-extern char __dtb_imx27_phytec_phycard_s_rdk_bb_start[];
-
 ENTRY_FUNCTION(start_phytec_phycard_imx27_64mb, r0, r1, r2)
 {
-	void *fdt;
-
 	arm_setup_stack(MX27_IRAM_BASE_ADDR + MX27_IRAM_SIZE);
 
-	fdt = __dtb_imx27_phytec_phycard_s_rdk_bb_start + get_runtime_offset();
-
-	phytec_phycard_imx27_common_init(fdt, PHYCARD_MICRON_64MB);
+	phytec_phycard_imx27_common_init(PHYCARD_MICRON_64MB);
 }
 
 ENTRY_FUNCTION(start_phytec_phycard_imx27_128mb, r0, r1, r2)
 {
-	void *fdt;
-
 	arm_setup_stack(MX27_IRAM_BASE_ADDR + MX27_IRAM_SIZE);
 
-	fdt = __dtb_imx27_phytec_phycard_s_rdk_bb_start + get_runtime_offset();
-
-	phytec_phycard_imx27_common_init(fdt, PHYCARD_MICRON_128MB);
+	phytec_phycard_imx27_common_init(PHYCARD_MICRON_128MB);
 }
-- 
2.25.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 2/6] ARM: i.MX Phytec phycard i.MX27: replace __naked with noinline
  2020-02-18 15:37 [PATCH 0/6] i.MX: Fix external NAND boot Sascha Hauer
  2020-02-18 15:37 ` [PATCH 1/6] ARM: i.MX Phytec phycard i.MX27: get fdt in common init function Sascha Hauer
@ 2020-02-18 15:37 ` Sascha Hauer
  2020-02-18 15:37 ` [PATCH 3/6] ARM: i.MX Phytec phycore " Sascha Hauer
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Sascha Hauer @ 2020-02-18 15:37 UTC (permalink / raw)
  To: Barebox List

phytec_phycard_imx27_common_init() doesn't need to be __naked, because
the stack has already been setup. What we want to have though is the
noinline attribute to make sure phytec_phycard_imx27_common_init() is
indeed a separate function which is called with initialized stack.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/boards/phytec-phycard-imx27/lowlevel.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boards/phytec-phycard-imx27/lowlevel.c b/arch/arm/boards/phytec-phycard-imx27/lowlevel.c
index ded85ee80f..894f560fa8 100644
--- a/arch/arm/boards/phytec-phycard-imx27/lowlevel.c
+++ b/arch/arm/boards/phytec-phycard-imx27/lowlevel.c
@@ -79,7 +79,7 @@ static void sdram_init(int sdram)
 
 extern char __dtb_imx27_phytec_phycard_s_rdk_bb_start[];
 
-static void __bare_init __naked phytec_phycard_imx27_common_init(int sdram)
+static noinline void __bare_init phytec_phycard_imx27_common_init(int sdram)
 {
 	void *fdt;
 	unsigned long r;
-- 
2.25.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 3/6] ARM: i.MX Phytec phycore i.MX27: replace __naked with noinline
  2020-02-18 15:37 [PATCH 0/6] i.MX: Fix external NAND boot Sascha Hauer
  2020-02-18 15:37 ` [PATCH 1/6] ARM: i.MX Phytec phycard i.MX27: get fdt in common init function Sascha Hauer
  2020-02-18 15:37 ` [PATCH 2/6] ARM: i.MX Phytec phycard i.MX27: replace __naked with noinline Sascha Hauer
@ 2020-02-18 15:37 ` Sascha Hauer
  2020-02-18 15:37 ` [PATCH 4/6] ARM: i.MX: external NAND boot: remove unnecessary arguments from imx*_nand_load_image Sascha Hauer
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Sascha Hauer @ 2020-02-18 15:37 UTC (permalink / raw)
  To: Barebox List

phytec_phycore_imx27_common_init() doesn't need to be __naked, because
the stack has already been setup. What we want to have though is the
noinline attribute to make sure phytec_phycore_imx27_common_init() is
indeed a separate function which is called with initialized stack.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/boards/phytec-phycore-imx27/lowlevel.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boards/phytec-phycore-imx27/lowlevel.c b/arch/arm/boards/phytec-phycore-imx27/lowlevel.c
index a9e296a0af..ae5f1af830 100644
--- a/arch/arm/boards/phytec-phycore-imx27/lowlevel.c
+++ b/arch/arm/boards/phytec-phycore-imx27/lowlevel.c
@@ -33,7 +33,7 @@
 
 #define ESDCTL0_VAL (ESDCTL0_SDE | ESDCTL0_ROW13 | ESDCTL0_COL10)
 
-static void __bare_init __naked noinline phytec_phycorce_imx27_common_init(void *fdt)
+static void __bare_init noinline phytec_phycorce_imx27_common_init(void *fdt)
 {
 	uint32_t r;
 	int i;
-- 
2.25.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 4/6] ARM: i.MX: external NAND boot: remove unnecessary arguments from imx*_nand_load_image
  2020-02-18 15:37 [PATCH 0/6] i.MX: Fix external NAND boot Sascha Hauer
                   ` (2 preceding siblings ...)
  2020-02-18 15:37 ` [PATCH 3/6] ARM: i.MX Phytec phycore " Sascha Hauer
@ 2020-02-18 15:37 ` Sascha Hauer
  2020-02-18 15:37 ` [PATCH 5/6] ARM: i.MX: external NAND boot: Leave icache disabled Sascha Hauer
  2020-02-18 15:37 ` [PATCH 6/6] ARM: i.MX: external NAND boot: Fix passing boarddata Sascha Hauer
  5 siblings, 0 replies; 10+ messages in thread
From: Sascha Hauer @ 2020-02-18 15:37 UTC (permalink / raw)
  To: Barebox List

The imx*_nand_load_image functions all take dest, size, nfc_base and
pagesize_2k arguments. All of these can be guessed inside the functions,
so remove them.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-imx/external-nand-boot.c | 84 ++++++++++++--------------
 1 file changed, 39 insertions(+), 45 deletions(-)

diff --git a/arch/arm/mach-imx/external-nand-boot.c b/arch/arm/mach-imx/external-nand-boot.c
index c4d61aa786..de8e0ffe5d 100644
--- a/arch/arm/mach-imx/external-nand-boot.c
+++ b/arch/arm/mach-imx/external-nand-boot.c
@@ -134,12 +134,13 @@ static noinline void __bare_init imx_nandboot_get_page(void *regs, int v1,
 	imx_nandboot_send_page(regs, v1, NFC_OUTPUT, pagesize_2k);
 }
 
-static void __bare_init imx_nand_load_image(void *dest, int v1, int size,
+static void __bare_init imx_nand_load_image(void *dest, int v1,
 					    void __iomem *base, int pagesize_2k)
 {
 	u32 tmp, page, block, blocksize, pagesize, badblocks;
 	int bbt = 0;
 	void *regs, *spare0;
+	int size = *(uint32_t *)(dest + 0x2c);
 
 	if (pagesize_2k) {
 		pagesize = 2048;
@@ -239,60 +240,60 @@ static void __bare_init imx_nand_load_image(void *dest, int v1, int size,
 	}
 }
 
-static void BARE_INIT_FUNCTION(imx25_nand_load_image)(void *dest, int size,
-                void __iomem *base, int pagesize_2k)
+static void BARE_INIT_FUNCTION(imx25_nand_load_image)(void)
 {
-        imx_nand_load_image(dest, 0, size, base, pagesize_2k);
-}
-
-static void BARE_INIT_FUNCTION(imx27_nand_load_image)(void *dest, int size,
-                void __iomem *base, int pagesize_2k)
-{
-        imx_nand_load_image(dest, 1, size, base, pagesize_2k);
-}
-
-static void BARE_INIT_FUNCTION(imx31_nand_load_image)(void *dest, int size,
-                void __iomem *base, int pagesize_2k)
-{
-        imx_nand_load_image(dest, 1, size, base, pagesize_2k);
-}
-
-static void BARE_INIT_FUNCTION(imx35_nand_load_image)(void *dest, int size,
-                void __iomem *base, int pagesize_2k)
-{
-        imx_nand_load_image(dest, 0, size, base, pagesize_2k);
-}
+	void *sdram = (void *)MX25_CSD0_BASE_ADDR;
+	void __iomem *nfc_base = IOMEM(MX25_NFC_BASE_ADDR);
+	bool pagesize_2k;
 
-static inline int imx25_pagesize_2k(void)
-{
 	if (readl(MX25_CCM_BASE_ADDR + MX25_CCM_RCSR) & (1 << 8))
-		return 1;
+		pagesize_2k = true;
 	else
-		return 0;
+		pagesize_2k = false;
+
+	imx_nand_load_image(sdram, 0, nfc_base, pagesize_2k);
 }
 
-static inline int imx27_pagesize_2k(void)
+static void BARE_INIT_FUNCTION(imx27_nand_load_image)(void)
 {
+	void *sdram = (void *)MX27_CSD0_BASE_ADDR;
+	void __iomem *nfc_base = IOMEM(MX27_NFC_BASE_ADDR);
+	bool pagesize_2k;
+
 	if (readl(MX27_SYSCTRL_BASE_ADDR + 0x14) & (1 << 5))
-		return 1;
+		pagesize_2k = true;
 	else
-		return 0;
+		pagesize_2k = false;
+
+	imx_nand_load_image(sdram, 1, nfc_base, pagesize_2k);
 }
 
-static inline int imx31_pagesize_2k(void)
+static void BARE_INIT_FUNCTION(imx31_nand_load_image)(void)
 {
+	void *sdram = (void *)MX31_CSD0_BASE_ADDR;
+	void __iomem *nfc_base = IOMEM(MX31_NFC_BASE_ADDR);
+	bool pagesize_2k;
+
 	if (readl(MX31_CCM_BASE_ADDR + MX31_CCM_RCSR) & MX31_RCSR_NFMS)
-		return 1;
+		pagesize_2k = true;
 	else
-		return 0;
+		pagesize_2k = false;
+
+	imx_nand_load_image(sdram, 1, nfc_base, pagesize_2k);
 }
 
-static inline int imx35_pagesize_2k(void)
+static void BARE_INIT_FUNCTION(imx35_nand_load_image)(void)
 {
+	void *sdram = (void *)MX35_CSD0_BASE_ADDR;
+	void __iomem *nfc_base = IOMEM(MX35_NFC_BASE_ADDR);
+	bool pagesize_2k;
+
 	if (readl(MX35_CCM_BASE_ADDR + MX35_CCM_RCSR) & (1 << 8))
-		return 1;
+		pagesize_2k = true;
 	else
-		return 0;
+		pagesize_2k = false;
+
+	imx_nand_load_image(sdram, 0, nfc_base, pagesize_2k);
 }
 
 /*
@@ -307,20 +308,13 @@ static inline int imx35_pagesize_2k(void)
 static void __noreturn BARE_INIT_FUNCTION(imx##soc##_boot_nand_external_cont)  \
 			(void *boarddata)				\
 {									\
-	unsigned long nfc_base = MX##soc##_NFC_BASE_ADDR;		\
-	void *sdram = (void *)MX##soc##_CSD0_BASE_ADDR;			\
-	uint32_t image_size, r;						\
-									\
-	image_size = *(uint32_t *)(sdram + 0x2c);			\
+	uint32_t r;							\
 									\
 	r = get_cr();							\
 	r |= CR_I;							\
 	set_cr(r);							\
 									\
-	imx##soc##_nand_load_image(sdram,				\
-			image_size,					\
-			(void *)nfc_base,				\
-			imx##soc##_pagesize_2k());			\
+	imx##soc##_nand_load_image();					\
 									\
         imx##soc##_barebox_entry(boarddata);				\
 }									\
-- 
2.25.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 5/6] ARM: i.MX: external NAND boot: Leave icache disabled
  2020-02-18 15:37 [PATCH 0/6] i.MX: Fix external NAND boot Sascha Hauer
                   ` (3 preceding siblings ...)
  2020-02-18 15:37 ` [PATCH 4/6] ARM: i.MX: external NAND boot: remove unnecessary arguments from imx*_nand_load_image Sascha Hauer
@ 2020-02-18 15:37 ` Sascha Hauer
  2020-02-19  6:23   ` Oleksij Rempel
  2020-02-18 15:37 ` [PATCH 6/6] ARM: i.MX: external NAND boot: Fix passing boarddata Sascha Hauer
  5 siblings, 1 reply; 10+ messages in thread
From: Sascha Hauer @ 2020-02-18 15:37 UTC (permalink / raw)
  To: Barebox List

It seems running from the NFC SRAM doesn't work with the instruction
cache enabled, it leads to corruptions on the i.MX27. We stumbled upon
this earlier and the solution at that time was to disable the
instruction cache in the NAND boot code. It is, however, more reliable
to just not enable the instruction cache in the first place.
This is not particularly nice as we have to ifdef this in generic code,
duplicate arm_cpu_lowlevel_init(), or call arm_cpu_lowlevel_init() later
when we are out of NFC SRAM. From the different bad solutions I chose
to ifdef the instruction cache away. It will be enabled later in the
common cache functions.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/cpu/lowlevel.S                | 2 ++
 arch/arm/mach-imx/external-nand-boot.c | 9 ---------
 2 files changed, 2 insertions(+), 9 deletions(-)

diff --git a/arch/arm/cpu/lowlevel.S b/arch/arm/cpu/lowlevel.S
index 3b52644e43..203a4afc47 100644
--- a/arch/arm/cpu/lowlevel.S
+++ b/arch/arm/cpu/lowlevel.S
@@ -57,8 +57,10 @@ THUMB(	orr	r12, r12, #PSR_T_BIT	)
 	bic	r12, r12, #(CR_M | CR_C | CR_B)
 	bic	r12, r12, #(CR_S | CR_R | CR_V)
 
+#ifndef CONFIG_ARCH_IMX_EXTERNAL_BOOT_NAND
 	/* enable instruction cache */
 	orr	r12, r12, #CR_I
+#endif
 
 #if __LINUX_ARM_ARCH__ >= 6
 	orr	r12, r12, #CR_U
diff --git a/arch/arm/mach-imx/external-nand-boot.c b/arch/arm/mach-imx/external-nand-boot.c
index de8e0ffe5d..bf683de858 100644
--- a/arch/arm/mach-imx/external-nand-boot.c
+++ b/arch/arm/mach-imx/external-nand-boot.c
@@ -308,12 +308,6 @@ static void BARE_INIT_FUNCTION(imx35_nand_load_image)(void)
 static void __noreturn BARE_INIT_FUNCTION(imx##soc##_boot_nand_external_cont)  \
 			(void *boarddata)				\
 {									\
-	uint32_t r;							\
-									\
-	r = get_cr();							\
-	r |= CR_I;							\
-	set_cr(r);							\
-									\
 	imx##soc##_nand_load_image();					\
 									\
         imx##soc##_barebox_entry(boarddata);				\
@@ -331,9 +325,6 @@ void __noreturn BARE_INIT_FUNCTION(imx##soc##_barebox_boot_nand_external) \
 	int i;								\
 	void __noreturn (*fn)(void *);					\
 									\
-	r = get_cr();							\
-	r &= ~CR_I;							\
-	set_cr(r);							\
 	/* skip NAND boot if not running from NFC space */		\
 	r = get_pc();							\
 	if (r < nfc_base || r > nfc_base + 0x800)			\
-- 
2.25.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 6/6] ARM: i.MX: external NAND boot: Fix passing boarddata
  2020-02-18 15:37 [PATCH 0/6] i.MX: Fix external NAND boot Sascha Hauer
                   ` (4 preceding siblings ...)
  2020-02-18 15:37 ` [PATCH 5/6] ARM: i.MX: external NAND boot: Leave icache disabled Sascha Hauer
@ 2020-02-18 15:37 ` Sascha Hauer
  5 siblings, 0 replies; 10+ messages in thread
From: Sascha Hauer @ 2020-02-18 15:37 UTC (permalink / raw)
  To: Barebox List

We used to pass a device tree pointer to
imx*_barebox_boot_nand_external(). This no longer works since we compile
barebox with -fPIE.

The problem is that we only have the first 2KiB of the image available
when we start from NAND. The pointer to the device tree is not valid
yet. This hasn't been a problem because the pointer is only used later
when we have the full image in SDRAM. With -fPIE though the actual
pointer is derived indirectly through another pointer, and that pointer
to the pointer is also not valid which causes an invalid pointer to
the device tree later.

This is solved by splitting the NAND boot functions up into two
functions. With imx*_nand_relocate_to_sdram() the board code relocates
the image out of the NFC SRAM into SDRAM. From that point on the device
tree pointer can be accessed and the board can load the image using
imx*_nand_load_image() and can afterwards pass control to barebox
passing whatever device tee pointer it likes.

Fixes: b0348d677b ("ARM: Compile with -fPIE")
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/boards/eukrea_cpuimx25/lowlevel.c    |   2 +-
 arch/arm/boards/eukrea_cpuimx35/lowlevel.c    |   2 +-
 arch/arm/boards/guf-cupid/lowlevel.c          |   2 +-
 arch/arm/boards/guf-neso/lowlevel.c           |   2 +-
 arch/arm/boards/karo-tx25/lowlevel.c          |  34 +--
 .../boards/phytec-phycard-imx27/lowlevel.c    |  23 ++-
 .../boards/phytec-phycore-imx27/lowlevel.c    |  36 ++--
 .../boards/phytec-phycore-imx31/lowlevel.c    |   2 +-
 .../boards/phytec-phycore-imx35/lowlevel.c    |   2 +-
 arch/arm/mach-imx/external-nand-boot.c        | 195 ++++++++++++------
 arch/arm/mach-imx/include/mach/imx-nand.h     |  19 +-
 11 files changed, 209 insertions(+), 110 deletions(-)

diff --git a/arch/arm/boards/eukrea_cpuimx25/lowlevel.c b/arch/arm/boards/eukrea_cpuimx25/lowlevel.c
index c16316d4a1..95159bbbb1 100644
--- a/arch/arm/boards/eukrea_cpuimx25/lowlevel.c
+++ b/arch/arm/boards/eukrea_cpuimx25/lowlevel.c
@@ -130,7 +130,7 @@ void __bare_init __naked barebox_arm_reset_vector(uint32_t r0, uint32_t r1, uint
 	writel(0x82216080, MX25_ESDCTL_BASE_ADDR + IMX_ESDCTL0);
 
 	if (IS_ENABLED(CONFIG_ARCH_IMX_EXTERNAL_BOOT_NAND))
-		imx25_barebox_boot_nand_external(0);
+		imx25_barebox_boot_nand_external();
 
 out:
 	imx25_barebox_entry(NULL);
diff --git a/arch/arm/boards/eukrea_cpuimx35/lowlevel.c b/arch/arm/boards/eukrea_cpuimx35/lowlevel.c
index ab5235f7f0..4bb41b0f42 100644
--- a/arch/arm/boards/eukrea_cpuimx35/lowlevel.c
+++ b/arch/arm/boards/eukrea_cpuimx35/lowlevel.c
@@ -135,7 +135,7 @@ void __bare_init __naked barebox_arm_reset_vector(uint32_t r0, uint32_t r1, uint
 		r |= 0x1 << 28;
 		writel(r, MX35_CCM_BASE_ADDR + MX35_CCM_PDR4);
 
-		imx35_barebox_boot_nand_external(0);
+		imx35_barebox_boot_nand_external();
 	}
 
 out:
diff --git a/arch/arm/boards/guf-cupid/lowlevel.c b/arch/arm/boards/guf-cupid/lowlevel.c
index 0d7cfb618c..60dd567298 100644
--- a/arch/arm/boards/guf-cupid/lowlevel.c
+++ b/arch/arm/boards/guf-cupid/lowlevel.c
@@ -308,7 +308,7 @@ void __bare_init __naked barebox_arm_reset_vector(uint32_t r0, uint32_t r1, uint
 		r0 |= 0x1 << 28;
 		writel(r0, MX35_CCM_BASE_ADDR + MX35_CCM_PDR4);
 
-		imx35_barebox_boot_nand_external(0);
+		imx35_barebox_boot_nand_external();
 	}
 
 out:
diff --git a/arch/arm/boards/guf-neso/lowlevel.c b/arch/arm/boards/guf-neso/lowlevel.c
index 20f48be7dd..3ae70eca30 100644
--- a/arch/arm/boards/guf-neso/lowlevel.c
+++ b/arch/arm/boards/guf-neso/lowlevel.c
@@ -89,7 +89,7 @@ void __bare_init __naked barebox_arm_reset_vector(uint32_t r0, uint32_t r1, uint
 			MX27_ESDCTL_BASE_ADDR + IMX_ESDCTL0);
 
 	if (IS_ENABLED(CONFIG_ARCH_IMX_EXTERNAL_BOOT_NAND))
-		imx27_barebox_boot_nand_external(0);
+		imx27_barebox_boot_nand_external();
 
 out:
 	imx27_barebox_entry(NULL);
diff --git a/arch/arm/boards/karo-tx25/lowlevel.c b/arch/arm/boards/karo-tx25/lowlevel.c
index f79cd91640..6c34944f74 100644
--- a/arch/arm/boards/karo-tx25/lowlevel.c
+++ b/arch/arm/boards/karo-tx25/lowlevel.c
@@ -74,7 +74,24 @@ static inline void __bare_init  setup_sdram(uint32_t base, uint32_t esdctl,
 	writel(esdctl, esdctlreg);
 }
 
-static void __bare_init karo_tx25_common_init(void *fdt)
+extern char __dtb_imx25_karo_tx25_start[];
+
+static void __noreturn karo_tx25_start(void)
+{
+	void *fdt;
+
+	fdt = __dtb_imx25_karo_tx25_start + get_runtime_offset();
+
+	imx25_barebox_entry(fdt);
+}
+
+static void __noreturn karo_tx25_load_nand(void)
+{
+	imx25_nand_load_image();
+	karo_tx25_start();
+}
+
+static void __bare_init karo_tx25_common_init(void)
 {
 	uint32_t r;
 
@@ -138,7 +155,7 @@ static void __bare_init karo_tx25_common_init(void *fdt)
 	/* Skip SDRAM initialization if we run from RAM */
 	r = get_pc();
 	if (r > 0x80000000 && r < 0xa0000000)
-		goto out;
+		karo_tx25_start();
 
 	/* set to 3.3v SDRAM */
 	writel(0x800, MX25_IOMUXC_BASE_ADDR + 0x454);
@@ -156,21 +173,12 @@ static void __bare_init karo_tx25_common_init(void *fdt)
 	setup_sdram(0x80000000, ESDCTLVAL, ESDCFGVAL);
 	setup_sdram(0x90000000, ESDCTLVAL, ESDCFGVAL);
 
-	imx25_barebox_boot_nand_external(fdt);
-
-out:
-	imx25_barebox_entry(fdt);
+	imx25_nand_relocate_to_sdram(karo_tx25_load_nand);
 }
 
-extern char __dtb_imx25_karo_tx25_start[];
-
 ENTRY_FUNCTION(start_imx25_karo_tx25, r0, r1, r2)
 {
-	void *fdt;
-
 	arm_setup_stack(MX25_IRAM_BASE_ADDR + MX25_IRAM_SIZE);
 
-	fdt = __dtb_imx25_karo_tx25_start + get_runtime_offset();
-
-	karo_tx25_common_init(fdt);
+	karo_tx25_common_init();
 }
diff --git a/arch/arm/boards/phytec-phycard-imx27/lowlevel.c b/arch/arm/boards/phytec-phycard-imx27/lowlevel.c
index 894f560fa8..40d39680fd 100644
--- a/arch/arm/boards/phytec-phycard-imx27/lowlevel.c
+++ b/arch/arm/boards/phytec-phycard-imx27/lowlevel.c
@@ -79,9 +79,23 @@ static void sdram_init(int sdram)
 
 extern char __dtb_imx27_phytec_phycard_s_rdk_bb_start[];
 
-static noinline void __bare_init phytec_phycard_imx27_common_init(int sdram)
+static void __noreturn phytec_phycard_imx27_start(void)
 {
 	void *fdt;
+
+	fdt = __dtb_imx27_phytec_phycard_s_rdk_bb_start + get_runtime_offset();
+
+	imx27_barebox_entry(fdt);
+}
+
+static void __noreturn phytec_phycard_imx27_load_nand(void)
+{
+	imx27_nand_load_image();
+	phytec_phycard_imx27_start();
+}
+
+static noinline void __bare_init phytec_phycard_imx27_common_init(int sdram)
+{
 	unsigned long r;
 
 	arm_cpu_lowlevel_init();
@@ -92,12 +106,10 @@ static noinline void __bare_init phytec_phycard_imx27_common_init(int sdram)
 	writel(0x00000000, MX27_AIPI_BASE_ADDR + MX27_AIPI2_PSR0);
 	writel(0xffffffff, MX27_AIPI_BASE_ADDR + MX27_AIPI2_PSR1);
 
-	fdt = __dtb_imx27_phytec_phycard_s_rdk_bb_start + get_runtime_offset();
-
 	/* Skip SDRAM initialization if we run from RAM */
         r = get_pc();
         if (r > 0xa0000000 && r < 0xc0000000)
-                imx27_barebox_entry(fdt);
+		phytec_phycard_imx27_start();
 
 	/* 399 MHz */
 	writel(IMX_PLL_PD(0) |
@@ -122,7 +134,8 @@ static noinline void __bare_init phytec_phycard_imx27_common_init(int sdram)
 
 	sdram_init(sdram);
 
-	imx27_barebox_boot_nand_external(fdt);
+	imx27_nand_relocate_to_sdram(phytec_phycard_imx27_load_nand);
+	phytec_phycard_imx27_start();
 }
 
 ENTRY_FUNCTION(start_phytec_phycard_imx27_64mb, r0, r1, r2)
diff --git a/arch/arm/boards/phytec-phycore-imx27/lowlevel.c b/arch/arm/boards/phytec-phycore-imx27/lowlevel.c
index ae5f1af830..b3bebdb6df 100644
--- a/arch/arm/boards/phytec-phycore-imx27/lowlevel.c
+++ b/arch/arm/boards/phytec-phycore-imx27/lowlevel.c
@@ -33,7 +33,24 @@
 
 #define ESDCTL0_VAL (ESDCTL0_SDE | ESDCTL0_ROW13 | ESDCTL0_COL10)
 
-static void __bare_init noinline phytec_phycorce_imx27_common_init(void *fdt)
+extern char __dtb_imx27_phytec_phycore_rdk_start[];
+
+static void __noreturn phytec_phycore_imx27_start(void)
+{
+	void *fdt;
+
+	fdt = __dtb_imx27_phytec_phycore_rdk_start + get_runtime_offset();
+
+	imx27_barebox_entry(fdt);
+}
+
+static void __noreturn phytec_phycore_imx27_load_nand(void)
+{
+	imx27_nand_load_image();
+	phytec_phycore_imx27_start();
+}
+
+static void __bare_init noinline phytec_phycore_imx27_common_init(void)
 {
 	uint32_t r;
 	int i;
@@ -49,7 +66,7 @@ static void __bare_init noinline phytec_phycorce_imx27_common_init(void *fdt)
 	/* Skip SDRAM initialization if we run from RAM */
 	r = get_pc();
 	if (r > 0xa0000000 && r < 0xb0000000)
-		goto out;
+		phytec_phycore_imx27_start();
 
 	/* re-program the PLL prior(!) starting the SDRAM controller */
 	writel(MPCTL0_VAL, MX27_CCM_BASE_ADDR + MX27_MPCTL0);
@@ -93,22 +110,13 @@ static void __bare_init noinline phytec_phycorce_imx27_common_init(void *fdt)
 			ESDCTL0_BL | ESDCTL0_SMODE_NORMAL,
 			MX27_ESDCTL_BASE_ADDR + IMX_ESDCTL0);
 
-	if (IS_ENABLED(CONFIG_ARCH_IMX_EXTERNAL_BOOT_NAND))
-		imx27_barebox_boot_nand_external(fdt);
-
-out:
-	imx27_barebox_entry(fdt);
+	imx27_nand_relocate_to_sdram(phytec_phycore_imx27_load_nand);
+	phytec_phycore_imx27_start();
 }
 
-extern char __dtb_imx27_phytec_phycore_rdk_start[];
-
 ENTRY_FUNCTION(start_phytec_phycore_imx27, r0, r1, r2)
 {
-	void *fdt;
-
 	arm_setup_stack(MX27_IRAM_BASE_ADDR + MX27_IRAM_SIZE);
 
-	fdt = __dtb_imx27_phytec_phycore_rdk_start + get_runtime_offset();
-
-	phytec_phycorce_imx27_common_init(fdt);
+	phytec_phycore_imx27_common_init();
 }
diff --git a/arch/arm/boards/phytec-phycore-imx31/lowlevel.c b/arch/arm/boards/phytec-phycore-imx31/lowlevel.c
index b5f333987a..98e1e8711d 100644
--- a/arch/arm/boards/phytec-phycore-imx31/lowlevel.c
+++ b/arch/arm/boards/phytec-phycore-imx31/lowlevel.c
@@ -127,7 +127,7 @@ void __bare_init __naked barebox_arm_reset_vector(uint32_t r0, uint32_t r1, uint
 #endif
 
 	if (IS_ENABLED(CONFIG_ARCH_IMX_EXTERNAL_BOOT_NAND))
-		imx31_barebox_boot_nand_external(0);
+		imx31_barebox_boot_nand_external();
 	else
 		imx31_barebox_entry(NULL);
 }
diff --git a/arch/arm/boards/phytec-phycore-imx35/lowlevel.c b/arch/arm/boards/phytec-phycore-imx35/lowlevel.c
index b80dafec16..9768009be8 100644
--- a/arch/arm/boards/phytec-phycore-imx35/lowlevel.c
+++ b/arch/arm/boards/phytec-phycore-imx35/lowlevel.c
@@ -186,7 +186,7 @@ void __bare_init __naked barebox_arm_reset_vector(uint32_t r0, uint32_t r1, uint
 		r |= 0x1 << 28;
 		writel(r, MX35_CCM_BASE_ADDR + MX35_CCM_PDR4);
 
-		imx35_barebox_boot_nand_external(0);
+		imx35_barebox_boot_nand_external();
 	}
 
 out:
diff --git a/arch/arm/mach-imx/external-nand-boot.c b/arch/arm/mach-imx/external-nand-boot.c
index bf683de858..123589c071 100644
--- a/arch/arm/mach-imx/external-nand-boot.c
+++ b/arch/arm/mach-imx/external-nand-boot.c
@@ -240,7 +240,7 @@ static void __bare_init imx_nand_load_image(void *dest, int v1,
 	}
 }
 
-static void BARE_INIT_FUNCTION(imx25_nand_load_image)(void)
+void BARE_INIT_FUNCTION(imx25_nand_load_image)(void)
 {
 	void *sdram = (void *)MX25_CSD0_BASE_ADDR;
 	void __iomem *nfc_base = IOMEM(MX25_NFC_BASE_ADDR);
@@ -254,7 +254,7 @@ static void BARE_INIT_FUNCTION(imx25_nand_load_image)(void)
 	imx_nand_load_image(sdram, 0, nfc_base, pagesize_2k);
 }
 
-static void BARE_INIT_FUNCTION(imx27_nand_load_image)(void)
+void BARE_INIT_FUNCTION(imx27_nand_load_image)(void)
 {
 	void *sdram = (void *)MX27_CSD0_BASE_ADDR;
 	void __iomem *nfc_base = IOMEM(MX27_NFC_BASE_ADDR);
@@ -268,7 +268,7 @@ static void BARE_INIT_FUNCTION(imx27_nand_load_image)(void)
 	imx_nand_load_image(sdram, 1, nfc_base, pagesize_2k);
 }
 
-static void BARE_INIT_FUNCTION(imx31_nand_load_image)(void)
+void BARE_INIT_FUNCTION(imx31_nand_load_image)(void)
 {
 	void *sdram = (void *)MX31_CSD0_BASE_ADDR;
 	void __iomem *nfc_base = IOMEM(MX31_NFC_BASE_ADDR);
@@ -282,7 +282,7 @@ static void BARE_INIT_FUNCTION(imx31_nand_load_image)(void)
 	imx_nand_load_image(sdram, 1, nfc_base, pagesize_2k);
 }
 
-static void BARE_INIT_FUNCTION(imx35_nand_load_image)(void)
+void BARE_INIT_FUNCTION(imx35_nand_load_image)(void)
 {
 	void *sdram = (void *)MX35_CSD0_BASE_ADDR;
 	void __iomem *nfc_base = IOMEM(MX35_NFC_BASE_ADDR);
@@ -297,70 +297,131 @@ static void BARE_INIT_FUNCTION(imx35_nand_load_image)(void)
 }
 
 /*
- * SoC specific entries for booting in external NAND mode. To be called from
- * the board specific entry code. This is safe to call even if not booting from
- * NAND. In this case the booting is continued without loading an image from
- * NAND. This function needs a stack to be set up.
+ * relocate_to_sdram - move ourselves out of NFC SRAM
+ *
+ * @nfc_base: base address of the NFC controller
+ * @sdram: SDRAM base address where we move ourselves to
+ * @fn: Function we continue with when running in SDRAM
+ *
+ * This function moves ourselves out of NFC SRAM to SDRAM. In case we a currently
+ * not running in NFC SRAM this function returns. If running in NFC SRAM, this
+ * function will not return, but call @fn instead.
  */
+static void BARE_INIT_FUNCTION(relocate_to_sdram)(unsigned long nfc_base,
+						  unsigned long sdram,
+						  void __noreturn (*fn)(void))
+{
+	unsigned long __fn;
+	u32 r;
+	u32 *src, *trg;
+	int i;
+
+	/* skip NAND boot if not running from NFC space */
+	r = get_pc();
+	if (r < nfc_base || r > nfc_base + 0x800)
+		return;
+
+	src = (unsigned int *)nfc_base;
+	trg = (unsigned int *)sdram;
+
+	/*
+	 * Copy initial binary portion from NFC SRAM to beginning of
+	 * SDRAM
+	 */
+	for (i = 0; i < 0x800 / sizeof(int); i++)
+		*trg++ = *src++;
+
+	/* The next function we jump to */
+	__fn = (unsigned long)fn;
+	/* mask out TEXT_BASE */
+	__fn &= 0x7ff;
+	/*
+	 * and add sdram base instead where we copied the initial
+	 * binary above
+	 */
+	__fn += sdram;
+
+	fn = (void *)__fn;
 
-#define DEFINE_EXTERNAL_NAND_ENTRY(soc)					\
-									\
-static void __noreturn BARE_INIT_FUNCTION(imx##soc##_boot_nand_external_cont)  \
-			(void *boarddata)				\
-{									\
-	imx##soc##_nand_load_image();					\
-									\
-        imx##soc##_barebox_entry(boarddata);				\
-}									\
-									\
-void __noreturn BARE_INIT_FUNCTION(imx##soc##_barebox_boot_nand_external) \
-			(void *bd)				\
-{									\
-	unsigned long nfc_base = MX##soc##_NFC_BASE_ADDR;		\
-	unsigned long sdram = MX##soc##_CSD0_BASE_ADDR;			\
-	unsigned long boarddata = (unsigned long)bd;			\
-	unsigned long __fn;						\
-	u32 r;								\
-	u32 *src, *trg;							\
-	int i;								\
-	void __noreturn (*fn)(void *);					\
-									\
-	/* skip NAND boot if not running from NFC space */		\
-	r = get_pc();							\
-	if (r < nfc_base || r > nfc_base + 0x800)			\
-		imx##soc##_barebox_entry(bd);				\
-									\
-	src = (unsigned int *)nfc_base;					\
-	trg = (unsigned int *)sdram;					\
-									\
-	/*								\
-	 * Copy initial binary portion from NFC SRAM to beginning of	\
-	 * SDRAM							\
-	 */								\
-	for (i = 0; i < 0x800 / sizeof(int); i++)			\
-		*trg++ = *src++;					\
-									\
-	/* The next function we jump to */				\
-	__fn = (unsigned long)imx##soc##_boot_nand_external_cont;	\
-	/* mask out TEXT_BASE */					\
-	__fn &= 0x7ff;							\
-	/*								\
-	 * and add sdram base instead where we copied the initial	\
-	 * binary above							\
-	 */								\
-	__fn += sdram;							\
-									\
-	fn = (void *)__fn;						\
-									\
-	if (boarddata > nfc_base && boarddata < nfc_base + SZ_512K) {	\
-		boarddata &= SZ_512K - 1;				\
-		boarddata += sdram;					\
-	}								\
-									\
-	fn((void *)boarddata);						\
+	fn();
 }
 
-DEFINE_EXTERNAL_NAND_ENTRY(25)
-DEFINE_EXTERNAL_NAND_ENTRY(27)
-DEFINE_EXTERNAL_NAND_ENTRY(31)
-DEFINE_EXTERNAL_NAND_ENTRY(35)
+void BARE_INIT_FUNCTION(imx25_nand_relocate_to_sdram)(void __noreturn (*fn)(void))
+{
+	unsigned long nfc_base = MX25_NFC_BASE_ADDR;
+	unsigned long sdram = MX25_CSD0_BASE_ADDR;
+
+	relocate_to_sdram(nfc_base, sdram, fn);
+}
+
+static void __noreturn BARE_INIT_FUNCTION(imx25_boot_nand_external_cont)(void)
+{
+	imx25_nand_load_image();
+	imx25_barebox_entry(NULL);
+}
+
+void __noreturn BARE_INIT_FUNCTION(imx25_barebox_boot_nand_external)(void)
+{
+	imx25_nand_relocate_to_sdram(imx25_boot_nand_external_cont);
+	imx25_barebox_entry(NULL);
+}
+
+void BARE_INIT_FUNCTION(imx27_nand_relocate_to_sdram)(void __noreturn (*fn)(void))
+{
+	unsigned long nfc_base = MX27_NFC_BASE_ADDR;
+	unsigned long sdram = MX27_CSD0_BASE_ADDR;
+
+	relocate_to_sdram(nfc_base, sdram, fn);
+}
+
+static void __noreturn BARE_INIT_FUNCTION(imx27_boot_nand_external_cont)(void)
+{
+	imx27_nand_load_image();
+	imx27_barebox_entry(NULL);
+}
+
+void __noreturn BARE_INIT_FUNCTION(imx27_barebox_boot_nand_external)(void)
+{
+	imx27_nand_relocate_to_sdram(imx27_boot_nand_external_cont);
+	imx27_barebox_entry(NULL);
+}
+
+void BARE_INIT_FUNCTION(imx31_nand_relocate_to_sdram)(void __noreturn (*fn)(void))
+{
+	unsigned long nfc_base = MX31_NFC_BASE_ADDR;
+	unsigned long sdram = MX31_CSD0_BASE_ADDR;
+
+	relocate_to_sdram(nfc_base, sdram, fn);
+}
+
+static void __noreturn BARE_INIT_FUNCTION(imx31_boot_nand_external_cont)(void)
+{
+	imx31_nand_load_image();
+	imx31_barebox_entry(NULL);
+}
+
+void __noreturn BARE_INIT_FUNCTION(imx31_barebox_boot_nand_external)(void)
+{
+	imx31_nand_relocate_to_sdram(imx31_boot_nand_external_cont);
+	imx31_barebox_entry(NULL);
+}
+
+void BARE_INIT_FUNCTION(imx35_nand_relocate_to_sdram)(void __noreturn (*fn)(void))
+{
+	unsigned long nfc_base = MX35_NFC_BASE_ADDR;
+	unsigned long sdram = MX35_CSD0_BASE_ADDR;
+
+	relocate_to_sdram(nfc_base, sdram, fn);
+}
+
+static void __noreturn BARE_INIT_FUNCTION(imx35_boot_nand_external_cont)(void)
+{
+	imx35_nand_load_image();
+	imx35_barebox_entry(NULL);
+}
+
+void __noreturn BARE_INIT_FUNCTION(imx35_barebox_boot_nand_external)(void)
+{
+	imx35_nand_relocate_to_sdram(imx35_boot_nand_external_cont);
+	imx35_barebox_entry(NULL);
+}
diff --git a/arch/arm/mach-imx/include/mach/imx-nand.h b/arch/arm/mach-imx/include/mach/imx-nand.h
index 0adba0989a..f34799a011 100644
--- a/arch/arm/mach-imx/include/mach/imx-nand.h
+++ b/arch/arm/mach-imx/include/mach/imx-nand.h
@@ -3,11 +3,20 @@
 
 #include <linux/mtd/mtd.h>
 
-void imx21_barebox_boot_nand_external(void *boarddata);
-void imx25_barebox_boot_nand_external(void *boarddata);
-void imx27_barebox_boot_nand_external(void *boarddata);
-void imx31_barebox_boot_nand_external(void *boarddata);
-void imx35_barebox_boot_nand_external(void *boarddata);
+void imx25_nand_load_image(void);
+void imx27_nand_load_image(void);
+void imx31_nand_load_image(void);
+void imx35_nand_load_image(void);
+
+void imx25_nand_relocate_to_sdram(void __noreturn (*fn)(void));
+void imx27_nand_relocate_to_sdram(void __noreturn (*fn)(void));
+void imx31_nand_relocate_to_sdram(void __noreturn (*fn)(void));
+void imx35_nand_relocate_to_sdram(void __noreturn (*fn)(void));
+
+void imx25_barebox_boot_nand_external(void);
+void imx27_barebox_boot_nand_external(void);
+void imx31_barebox_boot_nand_external(void);
+void imx35_barebox_boot_nand_external(void);
 void imx_nand_set_layout(int writesize, int datawidth);
 
 struct imx_nand_platform_data {
-- 
2.25.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 5/6] ARM: i.MX: external NAND boot: Leave icache disabled
  2020-02-18 15:37 ` [PATCH 5/6] ARM: i.MX: external NAND boot: Leave icache disabled Sascha Hauer
@ 2020-02-19  6:23   ` Oleksij Rempel
  2020-02-19  8:27     ` Sascha Hauer
  0 siblings, 1 reply; 10+ messages in thread
From: Oleksij Rempel @ 2020-02-19  6:23 UTC (permalink / raw)
  To: Sascha Hauer, Barebox List


[-- Attachment #1.1.1: Type: text/plain, Size: 2707 bytes --]

Am 18.02.20 um 16:37 schrieb Sascha Hauer:
> It seems running from the NFC SRAM doesn't work with the instruction
> cache enabled, it leads to corruptions on the i.MX27. We stumbled upon
> this earlier and the solution at that time was to disable the
> instruction cache in the NAND boot code. It is, however, more reliable
> to just not enable the instruction cache in the first place.
> This is not particularly nice as we have to ifdef this in generic code,
> duplicate arm_cpu_lowlevel_init(), or call arm_cpu_lowlevel_init() later
> when we are out of NFC SRAM. From the different bad solutions I chose
> to ifdef the instruction cache away. It will be enabled later in the
> common cache functions.


Hm... is it possible that we have similar speculation issues as on i.MX6UL? The CPU was speculating
in to IOMEM, caused cache poisoning/corruption and executed corrupted cache.

> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
>  arch/arm/cpu/lowlevel.S                | 2 ++
>  arch/arm/mach-imx/external-nand-boot.c | 9 ---------
>  2 files changed, 2 insertions(+), 9 deletions(-)
> 
> diff --git a/arch/arm/cpu/lowlevel.S b/arch/arm/cpu/lowlevel.S
> index 3b52644e43..203a4afc47 100644
> --- a/arch/arm/cpu/lowlevel.S
> +++ b/arch/arm/cpu/lowlevel.S
> @@ -57,8 +57,10 @@ THUMB(	orr	r12, r12, #PSR_T_BIT	)
>  	bic	r12, r12, #(CR_M | CR_C | CR_B)
>  	bic	r12, r12, #(CR_S | CR_R | CR_V)
>  
> +#ifndef CONFIG_ARCH_IMX_EXTERNAL_BOOT_NAND
>  	/* enable instruction cache */
>  	orr	r12, r12, #CR_I
> +#endif
>  
>  #if __LINUX_ARM_ARCH__ >= 6
>  	orr	r12, r12, #CR_U
> diff --git a/arch/arm/mach-imx/external-nand-boot.c b/arch/arm/mach-imx/external-nand-boot.c
> index de8e0ffe5d..bf683de858 100644
> --- a/arch/arm/mach-imx/external-nand-boot.c
> +++ b/arch/arm/mach-imx/external-nand-boot.c
> @@ -308,12 +308,6 @@ static void BARE_INIT_FUNCTION(imx35_nand_load_image)(void)
>  static void __noreturn BARE_INIT_FUNCTION(imx##soc##_boot_nand_external_cont)  \
>  			(void *boarddata)				\
>  {									\
> -	uint32_t r;							\
> -									\
> -	r = get_cr();							\
> -	r |= CR_I;							\
> -	set_cr(r);							\
> -									\
>  	imx##soc##_nand_load_image();					\
>  									\
>          imx##soc##_barebox_entry(boarddata);				\
> @@ -331,9 +325,6 @@ void __noreturn BARE_INIT_FUNCTION(imx##soc##_barebox_boot_nand_external) \
>  	int i;								\
>  	void __noreturn (*fn)(void *);					\
>  									\
> -	r = get_cr();							\
> -	r &= ~CR_I;							\
> -	set_cr(r);							\
>  	/* skip NAND boot if not running from NFC space */		\
>  	r = get_pc();							\
>  	if (r < nfc_base || r > nfc_base + 0x800)			\
> 



[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 149 bytes --]

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 5/6] ARM: i.MX: external NAND boot: Leave icache disabled
  2020-02-19  6:23   ` Oleksij Rempel
@ 2020-02-19  8:27     ` Sascha Hauer
  2020-02-19 11:53       ` Lucas Stach
  0 siblings, 1 reply; 10+ messages in thread
From: Sascha Hauer @ 2020-02-19  8:27 UTC (permalink / raw)
  To: Oleksij Rempel; +Cc: Barebox List

On Wed, Feb 19, 2020 at 07:23:09AM +0100, Oleksij Rempel wrote:
> Am 18.02.20 um 16:37 schrieb Sascha Hauer:
> > It seems running from the NFC SRAM doesn't work with the instruction
> > cache enabled, it leads to corruptions on the i.MX27. We stumbled upon
> > this earlier and the solution at that time was to disable the
> > instruction cache in the NAND boot code. It is, however, more reliable
> > to just not enable the instruction cache in the first place.
> > This is not particularly nice as we have to ifdef this in generic code,
> > duplicate arm_cpu_lowlevel_init(), or call arm_cpu_lowlevel_init() later
> > when we are out of NFC SRAM. From the different bad solutions I chose
> > to ifdef the instruction cache away. It will be enabled later in the
> > common cache functions.
> 
> 
> Hm... is it possible that we have similar speculation issues as on i.MX6UL? The CPU was speculating
> in to IOMEM, caused cache poisoning/corruption and executed corrupted cache.

I don't know how much speculation an ARM9 processor does, but the end
result looks very similar. via JTAG I can see that the memory matches
my disassembly, just the CPU does something completely different.

Sascha

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 5/6] ARM: i.MX: external NAND boot: Leave icache disabled
  2020-02-19  8:27     ` Sascha Hauer
@ 2020-02-19 11:53       ` Lucas Stach
  0 siblings, 0 replies; 10+ messages in thread
From: Lucas Stach @ 2020-02-19 11:53 UTC (permalink / raw)
  To: Sascha Hauer, Oleksij Rempel; +Cc: Barebox List

On Mi, 2020-02-19 at 09:27 +0100, Sascha Hauer wrote:
> On Wed, Feb 19, 2020 at 07:23:09AM +0100, Oleksij Rempel wrote:
> > Am 18.02.20 um 16:37 schrieb Sascha Hauer:
> > > It seems running from the NFC SRAM doesn't work with the instruction
> > > cache enabled, it leads to corruptions on the i.MX27. We stumbled upon
> > > this earlier and the solution at that time was to disable the
> > > instruction cache in the NAND boot code. It is, however, more reliable
> > > to just not enable the instruction cache in the first place.
> > > This is not particularly nice as we have to ifdef this in generic code,
> > > duplicate arm_cpu_lowlevel_init(), or call arm_cpu_lowlevel_init() later
> > > when we are out of NFC SRAM. From the different bad solutions I chose
> > > to ifdef the instruction cache away. It will be enabled later in the
> > > common cache functions.
> > 
> > Hm... is it possible that we have similar speculation issues as on i.MX6UL? The CPU was speculating
> > in to IOMEM, caused cache poisoning/corruption and executed corrupted cache.
> 
> I don't know how much speculation an ARM9 processor does, but the end
> result looks very similar. via JTAG I can see that the memory matches
> my disassembly, just the CPU does something completely different.

Processors from this generation don't do much speculation at all. They
have a simple branch predictor, but wrong predictions are resolved via
a simple pipeline flush. I wouldn't expect a misspeculated instruction
to reach the load/store units on those simple cores.

It's much more likely that the I-cache simply issues AXI transactions
(most likely WRAP ones to implement critical word first) which the NAND
controller slave can't handle properly. In that case there is nothing
much we can do besides keeping the I$ disabled while we are running
from the NAND SRAM region.

Regards,
Lucas


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2020-02-19 11:54 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-18 15:37 [PATCH 0/6] i.MX: Fix external NAND boot Sascha Hauer
2020-02-18 15:37 ` [PATCH 1/6] ARM: i.MX Phytec phycard i.MX27: get fdt in common init function Sascha Hauer
2020-02-18 15:37 ` [PATCH 2/6] ARM: i.MX Phytec phycard i.MX27: replace __naked with noinline Sascha Hauer
2020-02-18 15:37 ` [PATCH 3/6] ARM: i.MX Phytec phycore " Sascha Hauer
2020-02-18 15:37 ` [PATCH 4/6] ARM: i.MX: external NAND boot: remove unnecessary arguments from imx*_nand_load_image Sascha Hauer
2020-02-18 15:37 ` [PATCH 5/6] ARM: i.MX: external NAND boot: Leave icache disabled Sascha Hauer
2020-02-19  6:23   ` Oleksij Rempel
2020-02-19  8:27     ` Sascha Hauer
2020-02-19 11:53       ` Lucas Stach
2020-02-18 15:37 ` [PATCH 6/6] ARM: i.MX: external NAND boot: Fix passing boarddata Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox