From b4d32f07114e79a78fd81345cdc4938114ee87bd Mon Sep 17 00:00:00 2001 From: Siarhei Siamashka Date: Fri, 6 May 2016 06:58:03 +0300 Subject: [PATCH] fel-sdboot.sunxi: Add support for A64 and A80 This small bootable stub, which just passes control to the FEL code in the BROM, needs to be adjusted to also support Allwinner A64 and Allwinner A80 because the BROM is located at a different address there. The SD card boot has a very low priority on Allwinner A64, but it at least has a higher priority than the SPI NOR Flash: https://linux-sunxi.org/BROM#A64 So this patch may help to simplify the FEL mode activation on devices, which are booting their firmware from the SPI NOR Flash. Changes in v2: - Use SCTLR.V to detect the exception vectors location as suggested by Jens Kuske. - Add a padding of 32 NOP instructions in the beginning as a workaround for some strange failures. Signed-off-by: Siarhei Siamashka --- bin/fel-sdboot.sunxi | Bin 512 -> 8192 bytes fel-sdboot.c | 21 ++++++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/bin/fel-sdboot.sunxi b/bin/fel-sdboot.sunxi index 6d3bbb27cd3a0373eaea66f8e660741f42019c8f..017c300c251e70f59ccfa1ec8a3449d35ee9c1f5 100644 GIT binary patch literal 8192 zcmeIuu?d4v7{u{U1L0w%Ncy*c`oIB{G&Ugy%nI(2C9LBjHkKCIA=qdN$p$Zt&XB_Y z!Ex>JJBobjqP)iEyXjxeAX=olT^w1X@@ST?9{*WC3l`T4M`fNTZQ4U>lecGJ I&X5fO0E&1JV*mgE diff --git a/fel-sdboot.c b/fel-sdboot.c index d62d7170c6..3767ae338f 100644 --- a/fel-sdboot.c +++ b/fel-sdboot.c @@ -36,5 +36,24 @@ dd if=fel-boot.sunxi of=/dev/sdX bs=1024 seek=8 void _start(void) { - ((void (*)(void))0xffff0020)(); + unsigned int sctlr; + + /* + * FEL mode fails to activate in an unpredictable way without + * this NOP padding. Minor changes in the code, such as checking + * the PC register (PC >= 0x10000) instead of SCTLR.V or doing + * jump instead of call to the FEL handler in the BROM sometimes + * break on A64 and sometimes break on A10/A13/A20. Trying to + * add DSB & ISB instructions and/or invalidating caches and + * BTB do not seem to make any difference. Only adding a bunch + * of NOP instructions in the beginning helps. + */ + asm volatile(".rept 32 \n nop \n .endr"); + + asm volatile("mrc p15, 0, %0, c1, c0, 0" : "=r" (sctlr)); + + if (sctlr & (1 << 13)) /* SCTLR.V */ + ((void (*)(void))0xffff0020)(); + else + ((void (*)(void))0x00000020)(); }