
The Allwinner SoCs support a special FEL boot mode, which can be activated by users via a button press (or other means). In the FEL mode, the BROM implements a custom FEL protocol over USB, which allows to upload code to the device and run it. This protocol had been reverse engineered and documented by Henrik Nordström:
http://lists.phcomp.co.uk/pipermail/arm-netbook/2012-June/004341.html
Because the BROM code is using some parts of the SRAM for itself, only a few areas are available for use in u-boot. Currently the SPL is loaded into the "0x2000-0x5cff Free for program use" area and the stack pointer is at the end of this area. This is barely enough to fit just the current SPL and leaves almost no headroom for the future code.
This patch enables the use of a more compact Thumb2 mode for compiling the FEL SPL binary. And also relocates the stack to another "0x8000-0xbfff Free for program use" area. Additionally, the BSS segment is cleared.
Signed-off-by: Siarhei Siamashka siarhei.siamashka@gmail.com --- arch/arm/cpu/armv7/sunxi/Makefile | 1 + arch/arm/cpu/armv7/sunxi/start_fel.S | 42 +++++++++++++++++++++++++++++ arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds | 4 +-- include/configs/sunxi-common.h | 2 -- 4 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 arch/arm/cpu/armv7/sunxi/start_fel.S
diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile index a64bfa1..b3eff98 100644 --- a/arch/arm/cpu/armv7/sunxi/Makefile +++ b/arch/arm/cpu/armv7/sunxi/Makefile @@ -21,5 +21,6 @@ ifdef CONFIG_SPL_BUILD obj-$(CONFIG_SUN7I) += dram.o ifdef CONFIG_SPL_FEL obj-y += start.o +extra-y += start_fel.o endif endif diff --git a/arch/arm/cpu/armv7/sunxi/start_fel.S b/arch/arm/cpu/armv7/sunxi/start_fel.S new file mode 100644 index 0000000..2789fd9 --- /dev/null +++ b/arch/arm/cpu/armv7/sunxi/start_fel.S @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2014 Siarhei Siamashka siarhei.siamashka@gmail.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +.syntax unified +.text +.arm +.arch armv7a +.p2align 2 + +.globl _start_fel +.globl s_init +.globl __bss_start +.globl __bss_end + +_start_fel: + /* Relocate stack to the 0x8000-0xBFFF area */ + mov r0, #0xC000 + str sp, [r0, #-4]! + str lr, [r0, #-4]! + adr lr, _exit_fel /* Return back to '_exit_fel' */ + mov sp, r0 + + /* Erase the BSS segment */ + ldr r0, =__bss_start + ldr r1, =__bss_end + mov r2, #0 +0: cmp r0, r1 + strbne r2, [r0], #1 + bne 0b + + /* Pass control to the 's_init()' function */ + b s_init + +_exit_fel: + /* Relocate stack back and return */ + mov r0, #0xC000 + ldr sp, [r0, #-4]! + ldr lr, [r0, #-4]! + bx lr diff --git a/arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds b/arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds index 364e35c..418c2fc 100644 --- a/arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds +++ b/arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds @@ -6,7 +6,7 @@ */ OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) -ENTRY(s_init) +ENTRY(_start_fel) SECTIONS { . = 0x00002000; @@ -14,7 +14,7 @@ SECTIONS . = ALIGN(4); .text : { - *(.text.s_init) + arch/arm/cpu/armv7/sunxi/start_fel.o (.text) *(.text*) }
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index 5d72d62..4b980e9 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -18,10 +18,8 @@ */ #define CONFIG_SUNXI /* sunxi family */ #ifdef CONFIG_SPL_BUILD -#ifndef CONFIG_SPL_FEL #define CONFIG_SYS_THUMB_BUILD /* Thumbs mode to save space in SPL */ #endif -#endif
#include <asm/arch/cpu.h> /* get chip and board defs */