From: Sascha Hauer <s.hauer@pengutronix.de>
To: Barebox List <barebox@lists.infradead.org>
Cc: Wolfram.Dold@allegion.com,
"Florian Bäuerle" <florian.baeuerle@allegion.com>
Subject: [PATCH] ARM: i.MX27: Fix NAND boot with newer gcc
Date: Tue, 18 Sep 2018 16:53:53 +0200 [thread overview]
Message-ID: <20180918145354.30191-1-s.hauer@pengutronix.de> (raw)
This is a fix for a very weird icache problem when booting from NAND.
With a OSELAS-2018.01 toolchain imx27_barebox_boot_nand_external() is
compiled like this:
0000063c <imx27_barebox_boot_nand_external>:
63c: e92d4010 push {r4, lr}
640: e1a0200f mov r2, pc
644: e282230a add r2, r2, #671088640 ; 0x28000000
648: e3520b02 cmp r2, #2048 ; 0x800
64c: 9a000012 bls 69c <imx27_barebox_boot_nand_external+0x60>
650: eb000034 bl 728 <imx27_barebox_entry>
654: e592c000 ldr ip, [r2]
658: e2822004 add r2, r2, #4
65c: e580c000 str ip, [r0]
660: e1520001 cmp r2, r1
664: e2820332 add r0, r2, #-939524096 ; 0xc8000000
668: 1afffff9 bne 654 <imx27_barebox_boot_nand_external+0x18>
66c: e1a00003 mov r0, r3
670: e59f2034 ldr r2, [pc, #52] ; 6ac <imx27_barebox_boot_nand_external+0x70>
674: e2401376 sub r1, r0, #-671088639 ; 0xd8000001
678: e59f3030 ldr r3, [pc, #48] ; 6b0 <imx27_barebox_boot_nand_external+0x74>
67c: e1510002 cmp r1, r2
680: 93c004ff bicls r0, r0, #-16777216 ; 0xff000000
684: e1a03a83 lsl r3, r3, #21
688: e1a03aa3 lsr r3, r3, #21
68c: 93c0073e bicls r0, r0, #16252928 ; 0xf80000
690: e283320a add r3, r3, #-1610612736 ; 0xa0000000
694: 9280020a addls r0, r0, #-1610612736 ; 0xa0000000
698: e12fff33 blx r3
69c: e1a03000 mov r3, r0
6a0: e3a02336 mov r2, #-671088640 ; 0xd8000000
6a4: e59f1008 ldr r1, [pc, #8] ; 6b4 <imx27_barebox_boot_nand_external+0x78>
6a8: eaffffec b 660 <imx27_barebox_boot_nand_external+0x24>
6ac: 0007fffe .word 0x0007fffe
6b0: 00000604 .word 0x00000604
6b4: d8000800 .word 0xd8000800
From 0x64c the code jumps to 0x69c and then back to 0x660. The jump to
0x69c triggers a icache line fetch which works fine, but then when the
function continues and the code enters the same instruction cache line
at 0x680 again then only garbage is executed, most of the time we end up
in an endless loop and the CPU jumps back somewhere at the beginning of
the function.
I have carefully added nops right before the out of line code block.
When there are enough nops to move the block to the next cache line
then the code works again.
That of course is no solution to the problem. Since I am out of ideas
what the real issue is let's just disable the icache in this function
and re-enable it in the next function. This seems to solve the problem.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/mach-imx/external-nand-boot.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-imx/external-nand-boot.c b/arch/arm/mach-imx/external-nand-boot.c
index 17878e400b..745a129b23 100644
--- a/arch/arm/mach-imx/external-nand-boot.c
+++ b/arch/arm/mach-imx/external-nand-boot.c
@@ -323,10 +323,14 @@ void __noreturn BARE_INIT_FUNCTION(imx##soc##_boot_nand_external_cont) \
{ \
unsigned long nfc_base = MX##soc##_NFC_BASE_ADDR; \
void *sdram = (void *)MX##soc##_CSD0_BASE_ADDR; \
- uint32_t image_size; \
+ uint32_t image_size, r; \
\
image_size = *(uint32_t *)(sdram + 0x2c); \
\
+ r = get_cr(); \
+ r |= CR_I; \
+ set_cr(r); \
+ \
imx##soc##_nand_load_image(sdram, \
image_size, \
(void *)nfc_base, \
@@ -347,6 +351,9 @@ 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.19.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
next reply other threads:[~2018-09-18 14:54 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-09-18 14:53 Sascha Hauer [this message]
2018-09-18 15:40 ` Baeuerle, Florian
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180918145354.30191-1-s.hauer@pengutronix.de \
--to=s.hauer@pengutronix.de \
--cc=Wolfram.Dold@allegion.com \
--cc=barebox@lists.infradead.org \
--cc=florian.baeuerle@allegion.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox