
Blackfin currently uses BSS variables before location. The device tree overlaps with the BSS region, meaning that it gets overwritten by any BSS variable accesses. To work around this, copy it out of the way early in boot.
The correct fix would be to adjust blackfin to avoid using BSS so early, but this is a large amount of work and involves testing on many boards. This solution is much more prudent for now.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/blackfin/cpu/cpu.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
diff --git a/arch/blackfin/cpu/cpu.c b/arch/blackfin/cpu/cpu.c index a8aaee4..d039c4f 100644 --- a/arch/blackfin/cpu/cpu.c +++ b/arch/blackfin/cpu/cpu.c @@ -11,6 +11,7 @@
#include <common.h> #include <command.h> +#include <libfdt.h> #include <serial.h> #include <version.h> #include <i2c.h> @@ -296,6 +297,20 @@ void cpu_init_f(ulong bootflag, ulong loaded_from_ldr) memcpy(&_sdata_l1, &_data_l1_lma, (unsigned long)_data_l1_len); }
+ /* + * Blackfin uses the BSS section before relcation. This is where the + * device tree is located, so we must relocate it before any BSS + * variables are used (e.g. bfin_poweron_retx, below). Copy it to + * the end of BSS. + */ + if (IS_ENABLED(CONFIG_OF_CONTROL)) { + const void *blob = &_image_binary_end; + int fdt_size = fdt_totalsize(blob); + + memcpy(__bss_stop, blob, fdt_size); + gd->fdt_blob = __bss_stop; + } + memset(__bss_start, '\0', __bss_stop - __bss_start);
/*