* [U-Boot] [PATCH v2 1/3] arm: Allow lr to be saved by board code
@ 2015-02-07 17:47 Simon Glass
2015-02-07 17:47 ` [U-Boot] [PATCH v2 2/3] arm: spl: Provide for a board-specific loader Simon Glass
` (2 more replies)
0 siblings, 3 replies; 12+ messages in thread
From: Simon Glass @ 2015-02-07 17:47 UTC (permalink / raw)
To: u-boot
The link register value can be required on some boards (e.g. FEL mode on
sunxi) so use a branch instruction to jump to save_boot_params() instead
of a branch link.
This requires a branch back to save_boot_params_ret so adjust the users
to deal with this. For exynos just drop the function since it doesn't
do anything.
Signed-off-by: Simon Glass <sjg@chromium.org>
---
Changes in v2:
- Change save_boot_params() to not use lr for return
- Fix up existing save_boot_params() functions for new API
arch/arm/cpu/armv7/exynos/spl_boot.c | 1 -
arch/arm/cpu/armv7/omap-common/lowlevel_init.S | 2 +-
arch/arm/cpu/armv7/omap3/lowlevel_init.S | 2 +-
arch/arm/cpu/armv7/start.S | 7 +++++--
arch/arm/include/asm/system.h | 15 +++++++++++++++
board/nokia/rx51/lowlevel_init.S | 3 ++-
6 files changed, 24 insertions(+), 6 deletions(-)
diff --git a/arch/arm/cpu/armv7/exynos/spl_boot.c b/arch/arm/cpu/armv7/exynos/spl_boot.c
index bc237c9..c7f943e 100644
--- a/arch/arm/cpu/armv7/exynos/spl_boot.c
+++ b/arch/arm/cpu/armv7/exynos/spl_boot.c
@@ -309,4 +309,3 @@ void board_init_r(gd_t *id, ulong dest_addr)
while (1)
;
}
-void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3) {}
diff --git a/arch/arm/cpu/armv7/omap-common/lowlevel_init.S b/arch/arm/cpu/armv7/omap-common/lowlevel_init.S
index 86c0e42..e19c7ae 100644
--- a/arch/arm/cpu/armv7/omap-common/lowlevel_init.S
+++ b/arch/arm/cpu/armv7/omap-common/lowlevel_init.S
@@ -19,7 +19,7 @@
ENTRY(save_boot_params)
ldr r1, =OMAP_SRAM_SCRATCH_BOOT_PARAMS
str r0, [r1]
- bx lr
+ b save_boot_params_ret
ENDPROC(save_boot_params)
ENTRY(set_pl310_ctrl_reg)
diff --git a/arch/arm/cpu/armv7/omap3/lowlevel_init.S b/arch/arm/cpu/armv7/omap3/lowlevel_init.S
index 78577b1..80cb263 100644
--- a/arch/arm/cpu/armv7/omap3/lowlevel_init.S
+++ b/arch/arm/cpu/armv7/omap3/lowlevel_init.S
@@ -23,7 +23,7 @@ ENTRY(save_boot_params)
ldr r5, [r0, #0x4]
and r5, r5, #0xff
str r5, [r4]
- bx lr
+ b save_boot_params_ret
ENDPROC(save_boot_params)
#endif
diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S
index 70048c1..9b49ece 100644
--- a/arch/arm/cpu/armv7/start.S
+++ b/arch/arm/cpu/armv7/start.S
@@ -31,9 +31,12 @@
*************************************************************************/
.globl reset
+ .globl save_boot_params_ret
reset:
- bl save_boot_params
+ /* Allow the board to save important registers */
+ b save_boot_params
+save_boot_params_ret:
/*
* disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode,
* except if in HYP mode already
@@ -96,7 +99,7 @@ ENDPROC(c_runtime_cpu_setup)
*
*************************************************************************/
ENTRY(save_boot_params)
- bx lr @ back to my caller
+ b save_boot_params_ret @ back to my caller
ENDPROC(save_boot_params)
.weak save_boot_params
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index 89f2294..7820486 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -142,6 +142,21 @@ void flush_l3_cache(void);
#ifndef __ASSEMBLY__
+/**
+ * save_boot_params() - Save boot parameters before starting reset sequence
+ *
+ * If you provide this function it will be called immediately U-Boot starts,
+ * both for SPL and U-Boot proper.
+ *
+ * All registers are unchanged from U-Boot entry. No registers need be
+ * preserved.
+ *
+ * This is not a normal C function. There is no stack. Return by branching to
+ * save_boot_params_ret.
+ *
+ * void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3);
+ */
+
#define isb() __asm__ __volatile__ ("" : : : "memory")
#define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t");
diff --git a/board/nokia/rx51/lowlevel_init.S b/board/nokia/rx51/lowlevel_init.S
index e252909..9d4ea1b 100644
--- a/board/nokia/rx51/lowlevel_init.S
+++ b/board/nokia/rx51/lowlevel_init.S
@@ -37,7 +37,8 @@ ih_magic: /* IH_MAGIC in big endian from include/image.h */
.global save_boot_params
save_boot_params:
-
+ /* Get return address */
+ ldr lr, =save_boot_params_ret
/* Copy valid attached kernel to address KERNEL_ADDRESS */
--
2.2.0.rc0.207.ga3a616c
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [U-Boot] [PATCH v2 2/3] arm: spl: Provide for a board-specific loader
2015-02-07 17:47 [U-Boot] [PATCH v2 1/3] arm: Allow lr to be saved by board code Simon Glass
@ 2015-02-07 17:47 ` Simon Glass
2015-02-08 3:44 ` Siarhei Siamashka
2015-02-07 17:47 ` [U-Boot] [PATCH v2 3/3] sunxi: Normalise FEL support Simon Glass
2015-02-08 3:43 ` [U-Boot] [PATCH v2 1/3] arm: Allow lr to be saved by board code Siarhei Siamashka
2 siblings, 1 reply; 12+ messages in thread
From: Simon Glass @ 2015-02-07 17:47 UTC (permalink / raw)
To: u-boot
Some boards have a special way of loading U-Boot that does not fit with
the existing SPL code. For example sunxi uses an 'FEL' mode where U-Boot
is loaded over USB. Add a CONFIG option and boot mode for this.
Signed-off-by: Simon Glass <sjg@chromium.org>
---
Changes in v2: None
arch/arm/include/asm/spl.h | 4 ++++
common/spl/spl.c | 5 +++++
2 files changed, 9 insertions(+)
diff --git a/arch/arm/include/asm/spl.h b/arch/arm/include/asm/spl.h
index 8acd7cd..17b6f54 100644
--- a/arch/arm/include/asm/spl.h
+++ b/arch/arm/include/asm/spl.h
@@ -26,10 +26,14 @@ enum {
BOOT_DEVICE_SPI,
BOOT_DEVICE_SATA,
BOOT_DEVICE_I2C,
+ BOOT_DEVICE_BOARD,
BOOT_DEVICE_NONE
};
#endif
+/* Board-specific load method */
+void spl_board_load_image(void);
+
/* Linker symbols. */
extern char __bss_start[], __bss_end[];
diff --git a/common/spl/spl.c b/common/spl/spl.c
index daaeb50..ded0f30 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -229,6 +229,11 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
spl_sata_load_image();
break;
#endif
+#ifdef CONFIG_SPL_BOARD_LOAD_IMAGE
+ case BOOT_DEVICE_BOARD:
+ spl_board_load_image();
+ break;
+#endif
default:
#if defined(CONFIG_SPL_SERIAL_SUPPORT) && defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
puts("SPL: Unsupported Boot Device!\n");
--
2.2.0.rc0.207.ga3a616c
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [U-Boot] [PATCH v2 3/3] sunxi: Normalise FEL support
2015-02-07 17:47 [U-Boot] [PATCH v2 1/3] arm: Allow lr to be saved by board code Simon Glass
2015-02-07 17:47 ` [U-Boot] [PATCH v2 2/3] arm: spl: Provide for a board-specific loader Simon Glass
@ 2015-02-07 17:47 ` Simon Glass
2015-02-07 17:59 ` Hans de Goede
2015-02-08 3:48 ` Siarhei Siamashka
2015-02-08 3:43 ` [U-Boot] [PATCH v2 1/3] arm: Allow lr to be saved by board code Siarhei Siamashka
2 siblings, 2 replies; 12+ messages in thread
From: Simon Glass @ 2015-02-07 17:47 UTC (permalink / raw)
To: u-boot
Make sunxi's FEL code fit with the normal U-Boot boot sequence instead of
creating its own. There are some #ifdefs required in start.S. Future work
will hopefully remove these.
This series is available at u-boot-dm, branch sunxi-working.
Signed-off-by: Simon Glass <sjg@chromium.org>
---
Changes in v2:
- Adjust for new save_boot_params() API
- Drop patch to change r0 to r2 in start.S
- Add #ifdefs to start.S to deal with FEL
- Use 'Fast Early Loader' as the full name for FEL
arch/arm/cpu/armv7/start.S | 5 +-
arch/arm/cpu/armv7/sunxi/Makefile | 4 +-
arch/arm/cpu/armv7/sunxi/board.c | 21 ++++++++
arch/arm/cpu/armv7/sunxi/config.mk | 2 -
arch/arm/cpu/armv7/sunxi/fel_utils.S | 25 +++++++++
arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds | 82 -----------------------------
arch/arm/include/asm/arch-sunxi/sys_proto.h | 10 ++++
board/sunxi/Kconfig | 10 ++++
include/configs/sunxi-common.h | 6 +--
scripts/Makefile.spl | 2 -
10 files changed, 73 insertions(+), 94 deletions(-)
create mode 100644 arch/arm/cpu/armv7/sunxi/fel_utils.S
delete mode 100644 arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds
diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S
index 9b49ece..098a83a 100644
--- a/arch/arm/cpu/armv7/start.S
+++ b/arch/arm/cpu/armv7/start.S
@@ -54,7 +54,8 @@ save_boot_params_ret:
* (OMAP4 spl TEXT_BASE is not 32 byte aligned.
* Continue to use ROM code vector only in OMAP4 spl)
*/
-#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD))
+#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD)) && \
+ !defined(CONFIG_SPL_FEL)
/* Set V=0 in CP15 SCTLR register - for VBAR to point to vector */
mrc p15, 0, r0, c1, c0, 0 @ Read CP15 SCTLR Register
bic r0, #CR_V @ V = 0
@@ -67,7 +68,9 @@ save_boot_params_ret:
/* the mask ROM code should have PLL and others stable */
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+#ifndef CONFIG_SPL_FEL
bl cpu_init_cp15
+#endif
bl cpu_init_crit
#endif
diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile
index 48db744..c1b975a 100644
--- a/arch/arm/cpu/armv7/sunxi/Makefile
+++ b/arch/arm/cpu/armv7/sunxi/Makefile
@@ -38,7 +38,5 @@ obj-$(CONFIG_MACH_SUN5I) += dram_sun4i.o
obj-$(CONFIG_MACH_SUN6I) += dram_sun6i.o
obj-$(CONFIG_MACH_SUN7I) += dram_sun4i.o
obj-$(CONFIG_MACH_SUN8I) += dram_sun8i.o
-ifdef CONFIG_SPL_FEL
-obj-y += start.o
-endif
+obj-y += fel_utils.o
endif
diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c
index 6e28bcd..b7492ac 100644
--- a/arch/arm/cpu/armv7/sunxi/board.c
+++ b/arch/arm/cpu/armv7/sunxi/board.c
@@ -27,6 +27,13 @@
#include <linux/compiler.h>
+struct fel_stash {
+ uint32_t sp;
+ uint32_t lr;
+};
+
+struct fel_stash fel_stash __attribute__((section(".data")));
+
static int gpio_init(void)
{
#if CONFIG_CONS_INDEX == 1 && defined(CONFIG_UART0_PORT_F)
@@ -65,6 +72,12 @@ static int gpio_init(void)
return 0;
}
+void spl_board_load_image(void)
+{
+ debug("Returning to FEL sp=%x, lr=%x\n", fel_stash.sp, fel_stash.lr);
+ return_to_fel(fel_stash.sp, fel_stash.lr);
+}
+
void s_init(void)
{
#if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I
@@ -95,6 +108,14 @@ void s_init(void)
*/
u32 spl_boot_device(void)
{
+ /*
+ * Have we been asked to return to the FEL portion of the boot ROM?
+ * TODO: We need a more robust test here, or bracket this with
+ * #ifdef CONFIG_SPL_FEL.
+ */
+ if (fel_stash.lr >= 0xffff0000 && fel_stash.lr < 0xffff4000)
+ return BOOT_DEVICE_BOARD;
+
return BOOT_DEVICE_MMC1;
}
diff --git a/arch/arm/cpu/armv7/sunxi/config.mk b/arch/arm/cpu/armv7/sunxi/config.mk
index 00f5ffc..76ffec9 100644
--- a/arch/arm/cpu/armv7/sunxi/config.mk
+++ b/arch/arm/cpu/armv7/sunxi/config.mk
@@ -1,8 +1,6 @@
# Build a combined spl + u-boot image
ifdef CONFIG_SPL
ifndef CONFIG_SPL_BUILD
-ifndef CONFIG_SPL_FEL
ALL-y += u-boot-sunxi-with-spl.bin
endif
endif
-endif
diff --git a/arch/arm/cpu/armv7/sunxi/fel_utils.S b/arch/arm/cpu/armv7/sunxi/fel_utils.S
new file mode 100644
index 0000000..0c1de52
--- /dev/null
+++ b/arch/arm/cpu/armv7/sunxi/fel_utils.S
@@ -0,0 +1,25 @@
+/*
+ * Utility functions for FEL mode.
+ *
+ * Copyright (c) 2015 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <asm/system.h>
+#include <linux/linkage.h>
+
+ENTRY(save_boot_params)
+ ldr r0, =fel_stash
+ str sp, [r0, #0]
+ str lr, [r0, #4]
+ b save_boot_params_ret
+ENDPROC(save_boot_params)
+
+ENTRY(return_to_fel)
+ mov sp, r0
+ mov lr, r1
+ bx lr
+ENDPROC(return_to_fel)
diff --git a/arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds b/arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds
deleted file mode 100644
index 928b7c1..0000000
--- a/arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * (C) Copyright 2013
- * Henrik Nordstrom <henrik@henriknordstrom.net>
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
-OUTPUT_ARCH(arm)
-ENTRY(s_init)
-SECTIONS
-{
- . = 0x00002000;
-
- . = ALIGN(4);
- .text :
- {
- *(.text.s_init)
- *(.text*)
- }
-
- . = ALIGN(4);
- .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
-
- . = ALIGN(4);
- .data : {
- *(.data*)
- }
-
- . = ALIGN(4);
- .u_boot_list : {
- KEEP(*(SORT(.u_boot_list*)));
- }
-
- . = ALIGN(4);
- . = .;
-
- . = ALIGN(4);
- .rel.dyn : {
- __rel_dyn_start = .;
- *(.rel*)
- __rel_dyn_end = .;
- }
-
- .dynsym : {
- __dynsym_start = .;
- *(.dynsym)
- }
-
- . = ALIGN(4);
- .note.gnu.build-id :
- {
- *(.note.gnu.build-id)
- }
- _end = .;
-
- . = ALIGN(4096);
- .mmutable : {
- *(.mmutable)
- }
-
- .bss_start __rel_dyn_start (OVERLAY) : {
- KEEP(*(.__bss_start));
- __bss_base = .;
- }
-
- .bss __bss_base (OVERLAY) : {
- *(.bss*)
- . = ALIGN(4);
- __bss_limit = .;
- }
-
- .bss_end __bss_limit (OVERLAY) : {
- KEEP(*(.__bss_end));
- }
-
- /DISCARD/ : { *(.dynstr*) }
- /DISCARD/ : { *(.dynamic*) }
- /DISCARD/ : { *(.plt*) }
- /DISCARD/ : { *(.interp*) }
- /DISCARD/ : { *(.gnu*) }
- /DISCARD/ : { *(.note*) }
-}
diff --git a/arch/arm/include/asm/arch-sunxi/sys_proto.h b/arch/arm/include/asm/arch-sunxi/sys_proto.h
index c3e636e..60a5bd8 100644
--- a/arch/arm/include/asm/arch-sunxi/sys_proto.h
+++ b/arch/arm/include/asm/arch-sunxi/sys_proto.h
@@ -13,4 +13,14 @@
void sdelay(unsigned long);
+/* return_to_fel() - Return to BROM from SPL
+ *
+ * This returns back into the BROM after U-Boot SPL has performed its initial
+ * init. It uses the provided lr and sp to do so.
+ *
+ * @lr: BROM link register value (return address)
+ * @sp: BROM stack pointer
+ */
+void return_to_fel(uint32_t lr, uint32_t sp);
+
#endif
diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig
index 4a21589..3eab81f 100644
--- a/board/sunxi/Kconfig
+++ b/board/sunxi/Kconfig
@@ -149,6 +149,16 @@ config SPL_FEL
bool "SPL/FEL mode support"
depends on SPL
default n
+ help
+ This enables support for Fast Early Loader (FEL) mode. This
+ allows U-Boot to be loaded to the board over USB by the on-chip
+ boot rom. U-Boot should be sent in two parts: SPL first, with
+ 'fel write 0x2000 u-boot-spl.bin; fel exe 0x2000' then U-Boot with
+ 'fel write 0x4a000000 u-boot.bin; fel exe 0x4a000000'. This option
+ shrinks the amount of SRAM available to SPL, so only enable it if
+ you need FEL. Note that enabling this option only allows FEL to be
+ used; it is still possible to boot U-Boot from boot media. U-Boot
+ SPL detects when it is being loaded using FEL.
config UART0_PORT_F
bool "UART0 on MicroSD breakout board"
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
index 6cfd7e1..3becb4f 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 */
@@ -146,10 +144,10 @@
#define CONFIG_SPL_SERIAL_SUPPORT
#define CONFIG_SPL_LIBGENERIC_SUPPORT
+#define CONFIG_SPL_BOARD_LOAD_IMAGE
+
#ifdef CONFIG_SPL_FEL
-#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds"
-#define CONFIG_SPL_START_S_PATH "arch/arm/cpu/armv7/sunxi"
#define CONFIG_SPL_TEXT_BASE 0x2000
#define CONFIG_SPL_MAX_SIZE 0x4000 /* 16 KiB */
diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl
index ecf3037..5a1962b 100644
--- a/scripts/Makefile.spl
+++ b/scripts/Makefile.spl
@@ -153,10 +153,8 @@ ALL-y += $(obj)/$(BOARD)-spl.bin
endif
ifdef CONFIG_SUNXI
-ifndef CONFIG_SPL_FEL
ALL-y += $(obj)/sunxi-spl.bin
endif
-endif
ifeq ($(CONFIG_SYS_SOC),"at91")
ALL-y += boot.bin
--
2.2.0.rc0.207.ga3a616c
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [U-Boot] [PATCH v2 3/3] sunxi: Normalise FEL support
2015-02-07 17:47 ` [U-Boot] [PATCH v2 3/3] sunxi: Normalise FEL support Simon Glass
@ 2015-02-07 17:59 ` Hans de Goede
2015-02-07 18:02 ` Simon Glass
2015-02-08 3:48 ` Siarhei Siamashka
1 sibling, 1 reply; 12+ messages in thread
From: Hans de Goede @ 2015-02-07 17:59 UTC (permalink / raw)
To: u-boot
Hi,
On 02/07/2015 06:47 PM, Simon Glass wrote:
> Make sunxi's FEL code fit with the normal U-Boot boot sequence instead of
> creating its own. There are some #ifdefs required in start.S. Future work
> will hopefully remove these.
About the #ifdefs, I would really like to see us move to having 1 unified
loader for sunxi, which means getting rid of them. Even though we do use
a label to return from save_boot_params, save_boot_params could still
use r0 to return stuff, like you did in your previous patch-set, or we
could add a global variable to start.S which lives in .data and gets
initialized with 0, and save_boot_params could optionally save some
skip flags there.
Note this dropping of #ifdefs can wait till after v2015.04, for now this
patch-set should get fel mode working as before which is the goal for
v2015.04.
Regards,
Hans
>
> This series is available at u-boot-dm, branch sunxi-working.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2:
> - Adjust for new save_boot_params() API
> - Drop patch to change r0 to r2 in start.S
> - Add #ifdefs to start.S to deal with FEL
> - Use 'Fast Early Loader' as the full name for FEL
>
> arch/arm/cpu/armv7/start.S | 5 +-
> arch/arm/cpu/armv7/sunxi/Makefile | 4 +-
> arch/arm/cpu/armv7/sunxi/board.c | 21 ++++++++
> arch/arm/cpu/armv7/sunxi/config.mk | 2 -
> arch/arm/cpu/armv7/sunxi/fel_utils.S | 25 +++++++++
> arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds | 82 -----------------------------
> arch/arm/include/asm/arch-sunxi/sys_proto.h | 10 ++++
> board/sunxi/Kconfig | 10 ++++
> include/configs/sunxi-common.h | 6 +--
> scripts/Makefile.spl | 2 -
> 10 files changed, 73 insertions(+), 94 deletions(-)
> create mode 100644 arch/arm/cpu/armv7/sunxi/fel_utils.S
> delete mode 100644 arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds
>
> diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S
> index 9b49ece..098a83a 100644
> --- a/arch/arm/cpu/armv7/start.S
> +++ b/arch/arm/cpu/armv7/start.S
> @@ -54,7 +54,8 @@ save_boot_params_ret:
> * (OMAP4 spl TEXT_BASE is not 32 byte aligned.
> * Continue to use ROM code vector only in OMAP4 spl)
> */
> -#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD))
> +#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD)) && \
> + !defined(CONFIG_SPL_FEL)
> /* Set V=0 in CP15 SCTLR register - for VBAR to point to vector */
> mrc p15, 0, r0, c1, c0, 0 @ Read CP15 SCTLR Register
> bic r0, #CR_V @ V = 0
> @@ -67,7 +68,9 @@ save_boot_params_ret:
>
> /* the mask ROM code should have PLL and others stable */
> #ifndef CONFIG_SKIP_LOWLEVEL_INIT
> +#ifndef CONFIG_SPL_FEL
> bl cpu_init_cp15
> +#endif
> bl cpu_init_crit
> #endif
>
> diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile
> index 48db744..c1b975a 100644
> --- a/arch/arm/cpu/armv7/sunxi/Makefile
> +++ b/arch/arm/cpu/armv7/sunxi/Makefile
> @@ -38,7 +38,5 @@ obj-$(CONFIG_MACH_SUN5I) += dram_sun4i.o
> obj-$(CONFIG_MACH_SUN6I) += dram_sun6i.o
> obj-$(CONFIG_MACH_SUN7I) += dram_sun4i.o
> obj-$(CONFIG_MACH_SUN8I) += dram_sun8i.o
> -ifdef CONFIG_SPL_FEL
> -obj-y += start.o
> -endif
> +obj-y += fel_utils.o
> endif
> diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c
> index 6e28bcd..b7492ac 100644
> --- a/arch/arm/cpu/armv7/sunxi/board.c
> +++ b/arch/arm/cpu/armv7/sunxi/board.c
> @@ -27,6 +27,13 @@
>
> #include <linux/compiler.h>
>
> +struct fel_stash {
> + uint32_t sp;
> + uint32_t lr;
> +};
> +
> +struct fel_stash fel_stash __attribute__((section(".data")));
> +
> static int gpio_init(void)
> {
> #if CONFIG_CONS_INDEX == 1 && defined(CONFIG_UART0_PORT_F)
> @@ -65,6 +72,12 @@ static int gpio_init(void)
> return 0;
> }
>
> +void spl_board_load_image(void)
> +{
> + debug("Returning to FEL sp=%x, lr=%x\n", fel_stash.sp, fel_stash.lr);
> + return_to_fel(fel_stash.sp, fel_stash.lr);
> +}
> +
> void s_init(void)
> {
> #if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I
> @@ -95,6 +108,14 @@ void s_init(void)
> */
> u32 spl_boot_device(void)
> {
> + /*
> + * Have we been asked to return to the FEL portion of the boot ROM?
> + * TODO: We need a more robust test here, or bracket this with
> + * #ifdef CONFIG_SPL_FEL.
> + */
> + if (fel_stash.lr >= 0xffff0000 && fel_stash.lr < 0xffff4000)
> + return BOOT_DEVICE_BOARD;
> +
> return BOOT_DEVICE_MMC1;
> }
>
> diff --git a/arch/arm/cpu/armv7/sunxi/config.mk b/arch/arm/cpu/armv7/sunxi/config.mk
> index 00f5ffc..76ffec9 100644
> --- a/arch/arm/cpu/armv7/sunxi/config.mk
> +++ b/arch/arm/cpu/armv7/sunxi/config.mk
> @@ -1,8 +1,6 @@
> # Build a combined spl + u-boot image
> ifdef CONFIG_SPL
> ifndef CONFIG_SPL_BUILD
> -ifndef CONFIG_SPL_FEL
> ALL-y += u-boot-sunxi-with-spl.bin
> endif
> endif
> -endif
> diff --git a/arch/arm/cpu/armv7/sunxi/fel_utils.S b/arch/arm/cpu/armv7/sunxi/fel_utils.S
> new file mode 100644
> index 0000000..0c1de52
> --- /dev/null
> +++ b/arch/arm/cpu/armv7/sunxi/fel_utils.S
> @@ -0,0 +1,25 @@
> +/*
> + * Utility functions for FEL mode.
> + *
> + * Copyright (c) 2015 Google, Inc
> + *
> + * SPDX-License-Identifier: GPL-2.0+
> + */
> +
> +#include <asm-offsets.h>
> +#include <config.h>
> +#include <asm/system.h>
> +#include <linux/linkage.h>
> +
> +ENTRY(save_boot_params)
> + ldr r0, =fel_stash
> + str sp, [r0, #0]
> + str lr, [r0, #4]
> + b save_boot_params_ret
> +ENDPROC(save_boot_params)
> +
> +ENTRY(return_to_fel)
> + mov sp, r0
> + mov lr, r1
> + bx lr
> +ENDPROC(return_to_fel)
> diff --git a/arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds b/arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds
> deleted file mode 100644
> index 928b7c1..0000000
> --- a/arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds
> +++ /dev/null
> @@ -1,82 +0,0 @@
> -/*
> - * (C) Copyright 2013
> - * Henrik Nordstrom <henrik@henriknordstrom.net>
> - *
> - * SPDX-License-Identifier: GPL-2.0+
> - */
> -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
> -OUTPUT_ARCH(arm)
> -ENTRY(s_init)
> -SECTIONS
> -{
> - . = 0x00002000;
> -
> - . = ALIGN(4);
> - .text :
> - {
> - *(.text.s_init)
> - *(.text*)
> - }
> -
> - . = ALIGN(4);
> - .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
> -
> - . = ALIGN(4);
> - .data : {
> - *(.data*)
> - }
> -
> - . = ALIGN(4);
> - .u_boot_list : {
> - KEEP(*(SORT(.u_boot_list*)));
> - }
> -
> - . = ALIGN(4);
> - . = .;
> -
> - . = ALIGN(4);
> - .rel.dyn : {
> - __rel_dyn_start = .;
> - *(.rel*)
> - __rel_dyn_end = .;
> - }
> -
> - .dynsym : {
> - __dynsym_start = .;
> - *(.dynsym)
> - }
> -
> - . = ALIGN(4);
> - .note.gnu.build-id :
> - {
> - *(.note.gnu.build-id)
> - }
> - _end = .;
> -
> - . = ALIGN(4096);
> - .mmutable : {
> - *(.mmutable)
> - }
> -
> - .bss_start __rel_dyn_start (OVERLAY) : {
> - KEEP(*(.__bss_start));
> - __bss_base = .;
> - }
> -
> - .bss __bss_base (OVERLAY) : {
> - *(.bss*)
> - . = ALIGN(4);
> - __bss_limit = .;
> - }
> -
> - .bss_end __bss_limit (OVERLAY) : {
> - KEEP(*(.__bss_end));
> - }
> -
> - /DISCARD/ : { *(.dynstr*) }
> - /DISCARD/ : { *(.dynamic*) }
> - /DISCARD/ : { *(.plt*) }
> - /DISCARD/ : { *(.interp*) }
> - /DISCARD/ : { *(.gnu*) }
> - /DISCARD/ : { *(.note*) }
> -}
> diff --git a/arch/arm/include/asm/arch-sunxi/sys_proto.h b/arch/arm/include/asm/arch-sunxi/sys_proto.h
> index c3e636e..60a5bd8 100644
> --- a/arch/arm/include/asm/arch-sunxi/sys_proto.h
> +++ b/arch/arm/include/asm/arch-sunxi/sys_proto.h
> @@ -13,4 +13,14 @@
>
> void sdelay(unsigned long);
>
> +/* return_to_fel() - Return to BROM from SPL
> + *
> + * This returns back into the BROM after U-Boot SPL has performed its initial
> + * init. It uses the provided lr and sp to do so.
> + *
> + * @lr: BROM link register value (return address)
> + * @sp: BROM stack pointer
> + */
> +void return_to_fel(uint32_t lr, uint32_t sp);
> +
> #endif
> diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig
> index 4a21589..3eab81f 100644
> --- a/board/sunxi/Kconfig
> +++ b/board/sunxi/Kconfig
> @@ -149,6 +149,16 @@ config SPL_FEL
> bool "SPL/FEL mode support"
> depends on SPL
> default n
> + help
> + This enables support for Fast Early Loader (FEL) mode. This
> + allows U-Boot to be loaded to the board over USB by the on-chip
> + boot rom. U-Boot should be sent in two parts: SPL first, with
> + 'fel write 0x2000 u-boot-spl.bin; fel exe 0x2000' then U-Boot with
> + 'fel write 0x4a000000 u-boot.bin; fel exe 0x4a000000'. This option
> + shrinks the amount of SRAM available to SPL, so only enable it if
> + you need FEL. Note that enabling this option only allows FEL to be
> + used; it is still possible to boot U-Boot from boot media. U-Boot
> + SPL detects when it is being loaded using FEL.
>
> config UART0_PORT_F
> bool "UART0 on MicroSD breakout board"
> diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
> index 6cfd7e1..3becb4f 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 */
>
> @@ -146,10 +144,10 @@
> #define CONFIG_SPL_SERIAL_SUPPORT
> #define CONFIG_SPL_LIBGENERIC_SUPPORT
>
> +#define CONFIG_SPL_BOARD_LOAD_IMAGE
> +
> #ifdef CONFIG_SPL_FEL
>
> -#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds"
> -#define CONFIG_SPL_START_S_PATH "arch/arm/cpu/armv7/sunxi"
> #define CONFIG_SPL_TEXT_BASE 0x2000
> #define CONFIG_SPL_MAX_SIZE 0x4000 /* 16 KiB */
>
> diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl
> index ecf3037..5a1962b 100644
> --- a/scripts/Makefile.spl
> +++ b/scripts/Makefile.spl
> @@ -153,10 +153,8 @@ ALL-y += $(obj)/$(BOARD)-spl.bin
> endif
>
> ifdef CONFIG_SUNXI
> -ifndef CONFIG_SPL_FEL
> ALL-y += $(obj)/sunxi-spl.bin
> endif
> -endif
>
> ifeq ($(CONFIG_SYS_SOC),"at91")
> ALL-y += boot.bin
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* [U-Boot] [PATCH v2 3/3] sunxi: Normalise FEL support
2015-02-07 17:59 ` Hans de Goede
@ 2015-02-07 18:02 ` Simon Glass
2015-02-07 21:46 ` Hans de Goede
0 siblings, 1 reply; 12+ messages in thread
From: Simon Glass @ 2015-02-07 18:02 UTC (permalink / raw)
To: u-boot
Hi Hans,
On 7 February 2015 at 10:59, Hans de Goede <hdegoede@redhat.com> wrote:
> Hi,
>
> On 02/07/2015 06:47 PM, Simon Glass wrote:
>>
>> Make sunxi's FEL code fit with the normal U-Boot boot sequence instead of
>> creating its own. There are some #ifdefs required in start.S. Future work
>> will hopefully remove these.
>
>
> About the #ifdefs, I would really like to see us move to having 1 unified
> loader for sunxi, which means getting rid of them. Even though we do use
> a label to return from save_boot_params, save_boot_params could still
> use r0 to return stuff, like you did in your previous patch-set, or we
> could add a global variable to start.S which lives in .data and gets
> initialized with 0, and save_boot_params could optionally save some
> skip flags there.
>
> Note this dropping of #ifdefs can wait till after v2015.04, for now this
> patch-set should get fel mode working as before which is the goal for
> v2015.04.
OK. It's just as easy for me to do this now, but Albert was not keen
on doing this at run-time.
So if you can remove the #ifdefs by calling back into the BROM that
would probably be better. For now I think Albert prefers the #ifdefs.
>> This series is available at u-boot-dm, branch sunxi-working.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> ---
>>
[snip]
Regards,
Simon
^ permalink raw reply [flat|nested] 12+ messages in thread
* [U-Boot] [PATCH v2 3/3] sunxi: Normalise FEL support
2015-02-07 18:02 ` Simon Glass
@ 2015-02-07 21:46 ` Hans de Goede
0 siblings, 0 replies; 12+ messages in thread
From: Hans de Goede @ 2015-02-07 21:46 UTC (permalink / raw)
To: u-boot
Hi,
On 02/07/2015 07:02 PM, Simon Glass wrote:
> Hi Hans,
>
> On 7 February 2015 at 10:59, Hans de Goede <hdegoede@redhat.com> wrote:
>> Hi,
>>
>> On 02/07/2015 06:47 PM, Simon Glass wrote:
>>>
>>> Make sunxi's FEL code fit with the normal U-Boot boot sequence instead of
>>> creating its own. There are some #ifdefs required in start.S. Future work
>>> will hopefully remove these.
>>
>>
>> About the #ifdefs, I would really like to see us move to having 1 unified
>> loader for sunxi, which means getting rid of them. Even though we do use
>> a label to return from save_boot_params, save_boot_params could still
>> use r0 to return stuff, like you did in your previous patch-set, or we
>> could add a global variable to start.S which lives in .data and gets
>> initialized with 0, and save_boot_params could optionally save some
>> skip flags there.
>>
>> Note this dropping of #ifdefs can wait till after v2015.04, for now this
>> patch-set should get fel mode working as before which is the goal for
>> v2015.04.
>
> OK. It's just as easy for me to do this now, but Albert was not keen
> on doing this at run-time.
>
> So if you can remove the #ifdefs by calling back into the BROM that
> would probably be better.
Calling back into the BROm, rather then returning into it means that
usb needs to get re-initialized and the usb-host will see a usb
disconnect / reconnect, which is not really pretty, so I would like
to avoid that, and instead use something like your proposed runtime
checking with flags
> For now I think Albert prefers the #ifdefs.
#ifdefs are fine for v2015.04, but for v2015.07 I really believe we
need something runtime so that we can move to one unified loader
for sunxi. Albert can you give us some guidance on how we can best
implement runtime checks like the ones which Simon did with flags
stored in r0 in his initial patch-set ?
Regards,
Hans
^ permalink raw reply [flat|nested] 12+ messages in thread
* [U-Boot] [PATCH v2 1/3] arm: Allow lr to be saved by board code
2015-02-07 17:47 [U-Boot] [PATCH v2 1/3] arm: Allow lr to be saved by board code Simon Glass
2015-02-07 17:47 ` [U-Boot] [PATCH v2 2/3] arm: spl: Provide for a board-specific loader Simon Glass
2015-02-07 17:47 ` [U-Boot] [PATCH v2 3/3] sunxi: Normalise FEL support Simon Glass
@ 2015-02-08 3:43 ` Siarhei Siamashka
2 siblings, 0 replies; 12+ messages in thread
From: Siarhei Siamashka @ 2015-02-08 3:43 UTC (permalink / raw)
To: u-boot
On Sat, 7 Feb 2015 10:47:28 -0700
Simon Glass <sjg@chromium.org> wrote:
> The link register value can be required on some boards (e.g. FEL mode on
> sunxi) so use a branch instruction to jump to save_boot_params() instead
> of a branch link.
>
> This requires a branch back to save_boot_params_ret so adjust the users
> to deal with this. For exynos just drop the function since it doesn't
> do anything.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2:
> - Change save_boot_params() to not use lr for return
> - Fix up existing save_boot_params() functions for new API
>
> arch/arm/cpu/armv7/exynos/spl_boot.c | 1 -
> arch/arm/cpu/armv7/omap-common/lowlevel_init.S | 2 +-
> arch/arm/cpu/armv7/omap3/lowlevel_init.S | 2 +-
> arch/arm/cpu/armv7/start.S | 7 +++++--
> arch/arm/include/asm/system.h | 15 +++++++++++++++
> board/nokia/rx51/lowlevel_init.S | 3 ++-
> 6 files changed, 24 insertions(+), 6 deletions(-)
>
> diff --git a/arch/arm/cpu/armv7/exynos/spl_boot.c b/arch/arm/cpu/armv7/exynos/spl_boot.c
> index bc237c9..c7f943e 100644
> --- a/arch/arm/cpu/armv7/exynos/spl_boot.c
> +++ b/arch/arm/cpu/armv7/exynos/spl_boot.c
> @@ -309,4 +309,3 @@ void board_init_r(gd_t *id, ulong dest_addr)
> while (1)
> ;
> }
> -void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3) {}
> diff --git a/arch/arm/cpu/armv7/omap-common/lowlevel_init.S b/arch/arm/cpu/armv7/omap-common/lowlevel_init.S
> index 86c0e42..e19c7ae 100644
> --- a/arch/arm/cpu/armv7/omap-common/lowlevel_init.S
> +++ b/arch/arm/cpu/armv7/omap-common/lowlevel_init.S
> @@ -19,7 +19,7 @@
> ENTRY(save_boot_params)
> ldr r1, =OMAP_SRAM_SCRATCH_BOOT_PARAMS
> str r0, [r1]
> - bx lr
> + b save_boot_params_ret
> ENDPROC(save_boot_params)
>
> ENTRY(set_pl310_ctrl_reg)
> diff --git a/arch/arm/cpu/armv7/omap3/lowlevel_init.S b/arch/arm/cpu/armv7/omap3/lowlevel_init.S
> index 78577b1..80cb263 100644
> --- a/arch/arm/cpu/armv7/omap3/lowlevel_init.S
> +++ b/arch/arm/cpu/armv7/omap3/lowlevel_init.S
> @@ -23,7 +23,7 @@ ENTRY(save_boot_params)
> ldr r5, [r0, #0x4]
> and r5, r5, #0xff
> str r5, [r4]
> - bx lr
> + b save_boot_params_ret
> ENDPROC(save_boot_params)
> #endif
>
> diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S
> index 70048c1..9b49ece 100644
> --- a/arch/arm/cpu/armv7/start.S
> +++ b/arch/arm/cpu/armv7/start.S
> @@ -31,9 +31,12 @@
> *************************************************************************/
>
> .globl reset
> + .globl save_boot_params_ret
>
> reset:
> - bl save_boot_params
> + /* Allow the board to save important registers */
> + b save_boot_params
> +save_boot_params_ret:
> /*
> * disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode,
> * except if in HYP mode already
> @@ -96,7 +99,7 @@ ENDPROC(c_runtime_cpu_setup)
> *
> *************************************************************************/
> ENTRY(save_boot_params)
> - bx lr @ back to my caller
> + b save_boot_params_ret @ back to my caller
> ENDPROC(save_boot_params)
> .weak save_boot_params
>
> diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
> index 89f2294..7820486 100644
> --- a/arch/arm/include/asm/system.h
> +++ b/arch/arm/include/asm/system.h
> @@ -142,6 +142,21 @@ void flush_l3_cache(void);
>
> #ifndef __ASSEMBLY__
>
> +/**
> + * save_boot_params() - Save boot parameters before starting reset sequence
> + *
> + * If you provide this function it will be called immediately U-Boot starts,
> + * both for SPL and U-Boot proper.
> + *
> + * All registers are unchanged from U-Boot entry. No registers need be
> + * preserved.
> + *
> + * This is not a normal C function. There is no stack. Return by branching to
> + * save_boot_params_ret.
> + *
> + * void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3);
> + */
> +
> #define isb() __asm__ __volatile__ ("" : : : "memory")
>
> #define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t");
> diff --git a/board/nokia/rx51/lowlevel_init.S b/board/nokia/rx51/lowlevel_init.S
> index e252909..9d4ea1b 100644
> --- a/board/nokia/rx51/lowlevel_init.S
> +++ b/board/nokia/rx51/lowlevel_init.S
> @@ -37,7 +37,8 @@ ih_magic: /* IH_MAGIC in big endian from include/image.h */
>
> .global save_boot_params
> save_boot_params:
> -
> + /* Get return address */
> + ldr lr, =save_boot_params_ret
>
> /* Copy valid attached kernel to address KERNEL_ADDRESS */
>
Acked-by: Siarhei Siamashka <siarhei.siamashka@gmail.com>
--
Best regards,
Siarhei Siamashka
^ permalink raw reply [flat|nested] 12+ messages in thread
* [U-Boot] [PATCH v2 2/3] arm: spl: Provide for a board-specific loader
2015-02-07 17:47 ` [U-Boot] [PATCH v2 2/3] arm: spl: Provide for a board-specific loader Simon Glass
@ 2015-02-08 3:44 ` Siarhei Siamashka
0 siblings, 0 replies; 12+ messages in thread
From: Siarhei Siamashka @ 2015-02-08 3:44 UTC (permalink / raw)
To: u-boot
On Sat, 7 Feb 2015 10:47:29 -0700
Simon Glass <sjg@chromium.org> wrote:
> Some boards have a special way of loading U-Boot that does not fit with
> the existing SPL code. For example sunxi uses an 'FEL' mode where U-Boot
> is loaded over USB. Add a CONFIG option and boot mode for this.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
> arch/arm/include/asm/spl.h | 4 ++++
> common/spl/spl.c | 5 +++++
> 2 files changed, 9 insertions(+)
>
> diff --git a/arch/arm/include/asm/spl.h b/arch/arm/include/asm/spl.h
> index 8acd7cd..17b6f54 100644
> --- a/arch/arm/include/asm/spl.h
> +++ b/arch/arm/include/asm/spl.h
> @@ -26,10 +26,14 @@ enum {
> BOOT_DEVICE_SPI,
> BOOT_DEVICE_SATA,
> BOOT_DEVICE_I2C,
> + BOOT_DEVICE_BOARD,
> BOOT_DEVICE_NONE
> };
> #endif
>
> +/* Board-specific load method */
> +void spl_board_load_image(void);
> +
> /* Linker symbols. */
> extern char __bss_start[], __bss_end[];
>
> diff --git a/common/spl/spl.c b/common/spl/spl.c
> index daaeb50..ded0f30 100644
> --- a/common/spl/spl.c
> +++ b/common/spl/spl.c
> @@ -229,6 +229,11 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
> spl_sata_load_image();
> break;
> #endif
> +#ifdef CONFIG_SPL_BOARD_LOAD_IMAGE
> + case BOOT_DEVICE_BOARD:
> + spl_board_load_image();
> + break;
> +#endif
> default:
> #if defined(CONFIG_SPL_SERIAL_SUPPORT) && defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
> puts("SPL: Unsupported Boot Device!\n");
Acked-by: Siarhei Siamashka <siarhei.siamashka@gmail.com>
--
Best regards,
Siarhei Siamashka
^ permalink raw reply [flat|nested] 12+ messages in thread
* [U-Boot] [PATCH v2 3/3] sunxi: Normalise FEL support
2015-02-07 17:47 ` [U-Boot] [PATCH v2 3/3] sunxi: Normalise FEL support Simon Glass
2015-02-07 17:59 ` Hans de Goede
@ 2015-02-08 3:48 ` Siarhei Siamashka
2015-02-09 22:23 ` Simon Glass
1 sibling, 1 reply; 12+ messages in thread
From: Siarhei Siamashka @ 2015-02-08 3:48 UTC (permalink / raw)
To: u-boot
On Sat, 7 Feb 2015 10:47:30 -0700
Simon Glass <sjg@chromium.org> wrote:
> Make sunxi's FEL code fit with the normal U-Boot boot sequence instead of
> creating its own. There are some #ifdefs required in start.S. Future work
> will hopefully remove these.
>
> This series is available at u-boot-dm, branch sunxi-working.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2:
> - Adjust for new save_boot_params() API
> - Drop patch to change r0 to r2 in start.S
> - Add #ifdefs to start.S to deal with FEL
> - Use 'Fast Early Loader' as the full name for FEL
Thanks for working on these patches. It looks like we are finally
getting really close to resolving the sunxi FEL boot problem.
Some comments are below.
> arch/arm/cpu/armv7/start.S | 5 +-
> arch/arm/cpu/armv7/sunxi/Makefile | 4 +-
> arch/arm/cpu/armv7/sunxi/board.c | 21 ++++++++
> arch/arm/cpu/armv7/sunxi/config.mk | 2 -
> arch/arm/cpu/armv7/sunxi/fel_utils.S | 25 +++++++++
> arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds | 82 -----------------------------
> arch/arm/include/asm/arch-sunxi/sys_proto.h | 10 ++++
> board/sunxi/Kconfig | 10 ++++
> include/configs/sunxi-common.h | 6 +--
> scripts/Makefile.spl | 2 -
> 10 files changed, 73 insertions(+), 94 deletions(-)
> create mode 100644 arch/arm/cpu/armv7/sunxi/fel_utils.S
> delete mode 100644 arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds
>
> diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S
> index 9b49ece..098a83a 100644
> --- a/arch/arm/cpu/armv7/start.S
> +++ b/arch/arm/cpu/armv7/start.S
> @@ -54,7 +54,8 @@ save_boot_params_ret:
> * (OMAP4 spl TEXT_BASE is not 32 byte aligned.
> * Continue to use ROM code vector only in OMAP4 spl)
> */
> -#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD))
> +#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD)) && \
> + !defined(CONFIG_SPL_FEL)
Maybe we can just update the 'save_boot_params' function to save the
important configuration registers and then undo this configuration
in 'return_to_fel'? This allows us to avoid the sunxi specific ifdefs
in the core ARM code.
In this particular case, restoring VBAR and CPSR is important because
the BROM code uses an IRQ handler for FEL (presumably USB related).
And we want to ensure that this IRQ handler works properly again
after resuming the FEL code.
> /* Set V=0 in CP15 SCTLR register - for VBAR to point to vector */
> mrc p15, 0, r0, c1, c0, 0 @ Read CP15 SCTLR Register
> bic r0, #CR_V @ V = 0
> @@ -67,7 +68,9 @@ save_boot_params_ret:
>
> /* the mask ROM code should have PLL and others stable */
> #ifndef CONFIG_SKIP_LOWLEVEL_INIT
> +#ifndef CONFIG_SPL_FEL
Same here.
> bl cpu_init_cp15
> +#endif
> bl cpu_init_crit
> #endif
>
> diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile
> index 48db744..c1b975a 100644
> --- a/arch/arm/cpu/armv7/sunxi/Makefile
> +++ b/arch/arm/cpu/armv7/sunxi/Makefile
> @@ -38,7 +38,5 @@ obj-$(CONFIG_MACH_SUN5I) += dram_sun4i.o
> obj-$(CONFIG_MACH_SUN6I) += dram_sun6i.o
> obj-$(CONFIG_MACH_SUN7I) += dram_sun4i.o
> obj-$(CONFIG_MACH_SUN8I) += dram_sun8i.o
> -ifdef CONFIG_SPL_FEL
> -obj-y += start.o
> -endif
> +obj-y += fel_utils.o
> endif
> diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c
> index 6e28bcd..b7492ac 100644
> --- a/arch/arm/cpu/armv7/sunxi/board.c
> +++ b/arch/arm/cpu/armv7/sunxi/board.c
> @@ -27,6 +27,13 @@
>
> #include <linux/compiler.h>
>
> +struct fel_stash {
> + uint32_t sp;
> + uint32_t lr;
> +};
struct fel_stash {
uint32_t sp;
uint32_t lr;
uint32_t cpsr;
uint32_t sctlr;
uint32_t vbar;
uint32_t cr;
};
> +struct fel_stash fel_stash __attribute__((section(".data")));
> +
> static int gpio_init(void)
> {
> #if CONFIG_CONS_INDEX == 1 && defined(CONFIG_UART0_PORT_F)
> @@ -65,6 +72,12 @@ static int gpio_init(void)
> return 0;
> }
>
> +void spl_board_load_image(void)
> +{
> + debug("Returning to FEL sp=%x, lr=%x\n", fel_stash.sp, fel_stash.lr);
> + return_to_fel(fel_stash.sp, fel_stash.lr);
> +}
> +
> void s_init(void)
> {
> #if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I
> @@ -95,6 +108,14 @@ void s_init(void)
> */
> u32 spl_boot_device(void)
> {
> + /*
> + * Have we been asked to return to the FEL portion of the boot ROM?
> + * TODO: We need a more robust test here, or bracket this with
> + * #ifdef CONFIG_SPL_FEL.
> + */
> + if (fel_stash.lr >= 0xffff0000 && fel_stash.lr < 0xffff4000)
> + return BOOT_DEVICE_BOARD;
> return BOOT_DEVICE_MMC1;
It is probably better to do it this way:
#ifdef CONFIG_SPL_FEL
return BOOT_DEVICE_BOARD;
#else
if (memcmp((void *)4, "eGON.BT0", 8) == 0)
return BOOT_DEVICE_MMC1;
else
return BOOT_DEVICE_BOARD;
#endif
The memcmp (or equivalent code) ensures that it is compatible with
https://github.com/ssvb/sunxi-tools/commit/aa7e1880986e5c9a825b08aed9dc5621b821805f
Then the new 'fel spl u-boot-sunxi-with-spl.bin' command for loading
and executing the SPL works fine without CONFIG_SPL_FEL defined
(because the SD card specific "eGON.BT0" signature is replaced with
the "eGON.FEL" signature by the 'fel' tool in the device memory
before transferring control to the SPL code). Needless to say that
the SPL built this way still works when written to the SD card.
And if CONFIG_SPL_FEL is defined, then the FEL support still works in a
legacy way (via 'fel write 0x2000 u-boot-spl.bin; fel exe 0x2000').
We would only need to drop the legacy way in u-boot v2015.07 if the
new one proves to be problem free by that time :-)
> }
>
> diff --git a/arch/arm/cpu/armv7/sunxi/config.mk b/arch/arm/cpu/armv7/sunxi/config.mk
> index 00f5ffc..76ffec9 100644
> --- a/arch/arm/cpu/armv7/sunxi/config.mk
> +++ b/arch/arm/cpu/armv7/sunxi/config.mk
> @@ -1,8 +1,6 @@
> # Build a combined spl + u-boot image
> ifdef CONFIG_SPL
> ifndef CONFIG_SPL_BUILD
> -ifndef CONFIG_SPL_FEL
> ALL-y += u-boot-sunxi-with-spl.bin
> endif
> endif
> -endif
> diff --git a/arch/arm/cpu/armv7/sunxi/fel_utils.S b/arch/arm/cpu/armv7/sunxi/fel_utils.S
> new file mode 100644
> index 0000000..0c1de52
> --- /dev/null
> +++ b/arch/arm/cpu/armv7/sunxi/fel_utils.S
> @@ -0,0 +1,25 @@
> +/*
> + * Utility functions for FEL mode.
> + *
> + * Copyright (c) 2015 Google, Inc
> + *
> + * SPDX-License-Identifier: GPL-2.0+
> + */
> +
> +#include <asm-offsets.h>
> +#include <config.h>
> +#include <asm/system.h>
> +#include <linux/linkage.h>
> +
> +ENTRY(save_boot_params)
> + ldr r0, =fel_stash
> + str sp, [r0, #0]
> + str lr, [r0, #4]
> + b save_boot_params_ret
> +ENDPROC(save_boot_params)
> +
> +ENTRY(return_to_fel)
> + mov sp, r0
> + mov lr, r1
> + bx lr
> +ENDPROC(return_to_fel)
ENTRY(save_boot_params)
ldr r0, =fel_stash
str sp, [r0, #0]
str lr, [r0, #4]
mrs lr, cpsr @ Read CPSR
str lr, [r0, #8]
mrc p15, 0, lr, c1, c0, 0 @ Read CP15 SCTLR
str lr, [r0, #12]
mrc p15, 0, lr, c12, c0, 0 @ Read VBAR
str lr, [r0, #16]
mrc p15, 0, lr, c1, c0, 0 @ Read CP15 Control
str lr, [r0, #20]
b save_boot_params_ret
ENDPROC(save_boot_params)
ENTRY(return_to_fel)
ldr r0, =fel_stash
ldr lr, [r0, #20]
mcr p15, 0, lr, c1, c0, 0 @ Write CP15 Control
ldr lr, [r0, #16]
mcr p15, 0, lr, c12, c0, 0 @ Write VBAR
ldr lr, [r0, #12]
mcr p15, 0, lr, c1, c0, 0 @ Write CP15 SCTLR
ldr lr, [r0, #8]
msr cpsr, lr @ Write CPSR
ldr sp, [r0, #0]
ldr lr, [r0, #4]
bx lr
ENDPROC(return_to_fel)
This seems to work for me. However we probably might try to skip
restoring some of these registers. Also somebody might want to
review the order in which the registers should be restored.
> diff --git a/arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds b/arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds
> deleted file mode 100644
> index 928b7c1..0000000
> --- a/arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds
> +++ /dev/null
> @@ -1,82 +0,0 @@
> -/*
> - * (C) Copyright 2013
> - * Henrik Nordstrom <henrik@henriknordstrom.net>
> - *
> - * SPDX-License-Identifier: GPL-2.0+
> - */
> -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
> -OUTPUT_ARCH(arm)
> -ENTRY(s_init)
> -SECTIONS
> -{
> - . = 0x00002000;
> -
> - . = ALIGN(4);
> - .text :
> - {
> - *(.text.s_init)
> - *(.text*)
> - }
> -
> - . = ALIGN(4);
> - .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
> -
> - . = ALIGN(4);
> - .data : {
> - *(.data*)
> - }
> -
> - . = ALIGN(4);
> - .u_boot_list : {
> - KEEP(*(SORT(.u_boot_list*)));
> - }
> -
> - . = ALIGN(4);
> - . = .;
> -
> - . = ALIGN(4);
> - .rel.dyn : {
> - __rel_dyn_start = .;
> - *(.rel*)
> - __rel_dyn_end = .;
> - }
> -
> - .dynsym : {
> - __dynsym_start = .;
> - *(.dynsym)
> - }
> -
> - . = ALIGN(4);
> - .note.gnu.build-id :
> - {
> - *(.note.gnu.build-id)
> - }
> - _end = .;
> -
> - . = ALIGN(4096);
> - .mmutable : {
> - *(.mmutable)
> - }
> -
> - .bss_start __rel_dyn_start (OVERLAY) : {
> - KEEP(*(.__bss_start));
> - __bss_base = .;
> - }
> -
> - .bss __bss_base (OVERLAY) : {
> - *(.bss*)
> - . = ALIGN(4);
> - __bss_limit = .;
> - }
> -
> - .bss_end __bss_limit (OVERLAY) : {
> - KEEP(*(.__bss_end));
> - }
> -
> - /DISCARD/ : { *(.dynstr*) }
> - /DISCARD/ : { *(.dynamic*) }
> - /DISCARD/ : { *(.plt*) }
> - /DISCARD/ : { *(.interp*) }
> - /DISCARD/ : { *(.gnu*) }
> - /DISCARD/ : { *(.note*) }
> -}
> diff --git a/arch/arm/include/asm/arch-sunxi/sys_proto.h b/arch/arm/include/asm/arch-sunxi/sys_proto.h
> index c3e636e..60a5bd8 100644
> --- a/arch/arm/include/asm/arch-sunxi/sys_proto.h
> +++ b/arch/arm/include/asm/arch-sunxi/sys_proto.h
> @@ -13,4 +13,14 @@
>
> void sdelay(unsigned long);
>
> +/* return_to_fel() - Return to BROM from SPL
> + *
> + * This returns back into the BROM after U-Boot SPL has performed its initial
> + * init. It uses the provided lr and sp to do so.
> + *
> + * @lr: BROM link register value (return address)
> + * @sp: BROM stack pointer
> + */
> +void return_to_fel(uint32_t lr, uint32_t sp);
> +
> #endif
> diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig
> index 4a21589..3eab81f 100644
> --- a/board/sunxi/Kconfig
> +++ b/board/sunxi/Kconfig
> @@ -149,6 +149,16 @@ config SPL_FEL
> bool "SPL/FEL mode support"
> depends on SPL
> default n
> + help
> + This enables support for Fast Early Loader (FEL) mode. This
> + allows U-Boot to be loaded to the board over USB by the on-chip
> + boot rom. U-Boot should be sent in two parts: SPL first, with
> + 'fel write 0x2000 u-boot-spl.bin; fel exe 0x2000' then U-Boot with
> + 'fel write 0x4a000000 u-boot.bin; fel exe 0x4a000000'. This option
> + shrinks the amount of SRAM available to SPL, so only enable it if
> + you need FEL. Note that enabling this option only allows FEL to be
> + used; it is still possible to boot U-Boot from boot media. U-Boot
> + SPL detects when it is being loaded using FEL.
>
> config UART0_PORT_F
> bool "UART0 on MicroSD breakout board"
> diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
> index 6cfd7e1..3becb4f 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 */
>
> @@ -146,10 +144,10 @@
> #define CONFIG_SPL_SERIAL_SUPPORT
> #define CONFIG_SPL_LIBGENERIC_SUPPORT
>
> +#define CONFIG_SPL_BOARD_LOAD_IMAGE
> +
> #ifdef CONFIG_SPL_FEL
>
> -#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds"
> -#define CONFIG_SPL_START_S_PATH "arch/arm/cpu/armv7/sunxi"
> #define CONFIG_SPL_TEXT_BASE 0x2000
> #define CONFIG_SPL_MAX_SIZE 0x4000 /* 16 KiB */
>
> diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl
> index ecf3037..5a1962b 100644
> --- a/scripts/Makefile.spl
> +++ b/scripts/Makefile.spl
> @@ -153,10 +153,8 @@ ALL-y += $(obj)/$(BOARD)-spl.bin
> endif
>
> ifdef CONFIG_SUNXI
> -ifndef CONFIG_SPL_FEL
> ALL-y += $(obj)/sunxi-spl.bin
> endif
> -endif
>
> ifeq ($(CONFIG_SYS_SOC),"at91")
> ALL-y += boot.bin
One more theoretical concern is the placement of the stack in the legacy
FEL mode after your changes. Now it seems to be moved to 0x8000, which
might be fine though, according to the memory map from
https://github.com/hno/Allwinner-Info/blob/master/FEL-usb/USB-protocol.txt
If we want to preserve the old behaviour, then we would need to place
it around 0x5d00.
--
Best regards,
Siarhei Siamashka
^ permalink raw reply [flat|nested] 12+ messages in thread
* [U-Boot] [PATCH v2 3/3] sunxi: Normalise FEL support
2015-02-08 3:48 ` Siarhei Siamashka
@ 2015-02-09 22:23 ` Simon Glass
2015-02-11 3:05 ` Siarhei Siamashka
0 siblings, 1 reply; 12+ messages in thread
From: Simon Glass @ 2015-02-09 22:23 UTC (permalink / raw)
To: u-boot
Hi Siarhei,
On 7 February 2015 at 20:48, Siarhei Siamashka
<siarhei.siamashka@gmail.com> wrote:
> On Sat, 7 Feb 2015 10:47:30 -0700
> Simon Glass <sjg@chromium.org> wrote:
>
>> Make sunxi's FEL code fit with the normal U-Boot boot sequence instead of
>> creating its own. There are some #ifdefs required in start.S. Future work
>> will hopefully remove these.
>>
>> This series is available at u-boot-dm, branch sunxi-working.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> ---
>>
>> Changes in v2:
>> - Adjust for new save_boot_params() API
>> - Drop patch to change r0 to r2 in start.S
>> - Add #ifdefs to start.S to deal with FEL
>> - Use 'Fast Early Loader' as the full name for FEL
>
> Thanks for working on these patches. It looks like we are finally
> getting really close to resolving the sunxi FEL boot problem.
>
> Some comments are below.
>
>> arch/arm/cpu/armv7/start.S | 5 +-
>> arch/arm/cpu/armv7/sunxi/Makefile | 4 +-
>> arch/arm/cpu/armv7/sunxi/board.c | 21 ++++++++
>> arch/arm/cpu/armv7/sunxi/config.mk | 2 -
>> arch/arm/cpu/armv7/sunxi/fel_utils.S | 25 +++++++++
>> arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds | 82 -----------------------------
>> arch/arm/include/asm/arch-sunxi/sys_proto.h | 10 ++++
>> board/sunxi/Kconfig | 10 ++++
>> include/configs/sunxi-common.h | 6 +--
>> scripts/Makefile.spl | 2 -
>> 10 files changed, 73 insertions(+), 94 deletions(-)
>> create mode 100644 arch/arm/cpu/armv7/sunxi/fel_utils.S
>> delete mode 100644 arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds
>>
>> diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S
>> index 9b49ece..098a83a 100644
>> --- a/arch/arm/cpu/armv7/start.S
>> +++ b/arch/arm/cpu/armv7/start.S
>> @@ -54,7 +54,8 @@ save_boot_params_ret:
>> * (OMAP4 spl TEXT_BASE is not 32 byte aligned.
>> * Continue to use ROM code vector only in OMAP4 spl)
>> */
>> -#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD))
>> +#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD)) && \
>> + !defined(CONFIG_SPL_FEL)
>
> Maybe we can just update the 'save_boot_params' function to save the
> important configuration registers and then undo this configuration
> in 'return_to_fel'? This allows us to avoid the sunxi specific ifdefs
> in the core ARM code.
>
> In this particular case, restoring VBAR and CPSR is important because
> the BROM code uses an IRQ handler for FEL (presumably USB related).
> And we want to ensure that this IRQ handler works properly again
> after resuming the FEL code.
We could indeed.
It would avoid the #ifdef but my understanding is that you might be
able to avoid having to 'return' to the BROM through another means. In
any case we could perhaps leave that change until the next release?
>
>> /* Set V=0 in CP15 SCTLR register - for VBAR to point to vector */
>> mrc p15, 0, r0, c1, c0, 0 @ Read CP15 SCTLR Register
>> bic r0, #CR_V @ V = 0
>> @@ -67,7 +68,9 @@ save_boot_params_ret:
>>
>> /* the mask ROM code should have PLL and others stable */
>> #ifndef CONFIG_SKIP_LOWLEVEL_INIT
>> +#ifndef CONFIG_SPL_FEL
>
> Same here.
>
>> bl cpu_init_cp15
>> +#endif
>> bl cpu_init_crit
>> #endif
>>
>> diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile
>> index 48db744..c1b975a 100644
>> --- a/arch/arm/cpu/armv7/sunxi/Makefile
>> +++ b/arch/arm/cpu/armv7/sunxi/Makefile
>> @@ -38,7 +38,5 @@ obj-$(CONFIG_MACH_SUN5I) += dram_sun4i.o
>> obj-$(CONFIG_MACH_SUN6I) += dram_sun6i.o
>> obj-$(CONFIG_MACH_SUN7I) += dram_sun4i.o
>> obj-$(CONFIG_MACH_SUN8I) += dram_sun8i.o
>> -ifdef CONFIG_SPL_FEL
>> -obj-y += start.o
>> -endif
>> +obj-y += fel_utils.o
>> endif
>> diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c
>> index 6e28bcd..b7492ac 100644
>> --- a/arch/arm/cpu/armv7/sunxi/board.c
>> +++ b/arch/arm/cpu/armv7/sunxi/board.c
>> @@ -27,6 +27,13 @@
>>
>> #include <linux/compiler.h>
>>
>> +struct fel_stash {
>> + uint32_t sp;
>> + uint32_t lr;
>> +};
>
> struct fel_stash {
> uint32_t sp;
> uint32_t lr;
> uint32_t cpsr;
> uint32_t sctlr;
> uint32_t vbar;
> uint32_t cr;
> };
>
>> +struct fel_stash fel_stash __attribute__((section(".data")));
>> +
>> static int gpio_init(void)
>> {
>> #if CONFIG_CONS_INDEX == 1 && defined(CONFIG_UART0_PORT_F)
>> @@ -65,6 +72,12 @@ static int gpio_init(void)
>> return 0;
>> }
>>
>> +void spl_board_load_image(void)
>> +{
>> + debug("Returning to FEL sp=%x, lr=%x\n", fel_stash.sp, fel_stash.lr);
>> + return_to_fel(fel_stash.sp, fel_stash.lr);
>> +}
>> +
>> void s_init(void)
>> {
>> #if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I
>> @@ -95,6 +108,14 @@ void s_init(void)
>> */
>> u32 spl_boot_device(void)
>> {
>> + /*
>> + * Have we been asked to return to the FEL portion of the boot ROM?
>> + * TODO: We need a more robust test here, or bracket this with
>> + * #ifdef CONFIG_SPL_FEL.
>> + */
>> + if (fel_stash.lr >= 0xffff0000 && fel_stash.lr < 0xffff4000)
>> + return BOOT_DEVICE_BOARD;
>> return BOOT_DEVICE_MMC1;
>
> It is probably better to do it this way:
>
> #ifdef CONFIG_SPL_FEL
> return BOOT_DEVICE_BOARD;
> #else
> if (memcmp((void *)4, "eGON.BT0", 8) == 0)
> return BOOT_DEVICE_MMC1;
> else
> return BOOT_DEVICE_BOARD;
> #endif
>
> The memcmp (or equivalent code) ensures that it is compatible with
> https://github.com/ssvb/sunxi-tools/commit/aa7e1880986e5c9a825b08aed9dc5621b821805f
>
> Then the new 'fel spl u-boot-sunxi-with-spl.bin' command for loading
> and executing the SPL works fine without CONFIG_SPL_FEL defined
> (because the SD card specific "eGON.BT0" signature is replaced with
> the "eGON.FEL" signature by the 'fel' tool in the device memory
> before transferring control to the SPL code). Needless to say that
> the SPL built this way still works when written to the SD card.
>
> And if CONFIG_SPL_FEL is defined, then the FEL support still works in a
> legacy way (via 'fel write 0x2000 u-boot-spl.bin; fel exe 0x2000').
>
> We would only need to drop the legacy way in u-boot v2015.07 if the
> new one proves to be problem free by that time :-)
So you mean that we can drop CONFIG_SPL_FEL?
[snip]
>
> ENTRY(save_boot_params)
> ldr r0, =fel_stash
> str sp, [r0, #0]
> str lr, [r0, #4]
> mrs lr, cpsr @ Read CPSR
> str lr, [r0, #8]
> mrc p15, 0, lr, c1, c0, 0 @ Read CP15 SCTLR
> str lr, [r0, #12]
> mrc p15, 0, lr, c12, c0, 0 @ Read VBAR
> str lr, [r0, #16]
> mrc p15, 0, lr, c1, c0, 0 @ Read CP15 Control
> str lr, [r0, #20]
> b save_boot_params_ret
> ENDPROC(save_boot_params)
>
> ENTRY(return_to_fel)
> ldr r0, =fel_stash
> ldr lr, [r0, #20]
> mcr p15, 0, lr, c1, c0, 0 @ Write CP15 Control
> ldr lr, [r0, #16]
> mcr p15, 0, lr, c12, c0, 0 @ Write VBAR
> ldr lr, [r0, #12]
> mcr p15, 0, lr, c1, c0, 0 @ Write CP15 SCTLR
> ldr lr, [r0, #8]
> msr cpsr, lr @ Write CPSR
> ldr sp, [r0, #0]
> ldr lr, [r0, #4]
> bx lr
> ENDPROC(return_to_fel)
>
>
> This seems to work for me. However we probably might try to skip
> restoring some of these registers. Also somebody might want to
> review the order in which the registers should be restored.
I can certainly incorporate this into the patch.
Is that what you would prefer? It seems more complicated, and also a
bit odd to save a whole load of data that we then corrupt and restore,
but it is fine with me.
>
>> diff --git a/arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds b/arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds
>> deleted file mode 100644
>> index 928b7c1..0000000
>> --- a/arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds
>> +++ /dev/null
>> @@ -1,82 +0,0 @@
>> -/*
>> - * (C) Copyright 2013
>> - * Henrik Nordstrom <henrik@henriknordstrom.net>
>> - *
>> - * SPDX-License-Identifier: GPL-2.0+
>> - */
>> -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
>> -OUTPUT_ARCH(arm)
>> -ENTRY(s_init)
>> -SECTIONS
>> -{
>> - . = 0x00002000;
>> -
>> - . = ALIGN(4);
>> - .text :
>> - {
>> - *(.text.s_init)
>> - *(.text*)
>> - }
>> -
>> - . = ALIGN(4);
>> - .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
>> -
>> - . = ALIGN(4);
>> - .data : {
>> - *(.data*)
>> - }
>> -
>> - . = ALIGN(4);
>> - .u_boot_list : {
>> - KEEP(*(SORT(.u_boot_list*)));
>> - }
>> -
>> - . = ALIGN(4);
>> - . = .;
>> -
>> - . = ALIGN(4);
>> - .rel.dyn : {
>> - __rel_dyn_start = .;
>> - *(.rel*)
>> - __rel_dyn_end = .;
>> - }
>> -
>> - .dynsym : {
>> - __dynsym_start = .;
>> - *(.dynsym)
>> - }
>> -
>> - . = ALIGN(4);
>> - .note.gnu.build-id :
>> - {
>> - *(.note.gnu.build-id)
>> - }
>> - _end = .;
>> -
>> - . = ALIGN(4096);
>> - .mmutable : {
>> - *(.mmutable)
>> - }
>> -
>> - .bss_start __rel_dyn_start (OVERLAY) : {
>> - KEEP(*(.__bss_start));
>> - __bss_base = .;
>> - }
>> -
>> - .bss __bss_base (OVERLAY) : {
>> - *(.bss*)
>> - . = ALIGN(4);
>> - __bss_limit = .;
>> - }
>> -
>> - .bss_end __bss_limit (OVERLAY) : {
>> - KEEP(*(.__bss_end));
>> - }
>> -
>> - /DISCARD/ : { *(.dynstr*) }
>> - /DISCARD/ : { *(.dynamic*) }
>> - /DISCARD/ : { *(.plt*) }
>> - /DISCARD/ : { *(.interp*) }
>> - /DISCARD/ : { *(.gnu*) }
>> - /DISCARD/ : { *(.note*) }
>> -}
>> diff --git a/arch/arm/include/asm/arch-sunxi/sys_proto.h b/arch/arm/include/asm/arch-sunxi/sys_proto.h
>> index c3e636e..60a5bd8 100644
>> --- a/arch/arm/include/asm/arch-sunxi/sys_proto.h
>> +++ b/arch/arm/include/asm/arch-sunxi/sys_proto.h
>> @@ -13,4 +13,14 @@
>>
>> void sdelay(unsigned long);
>>
>> +/* return_to_fel() - Return to BROM from SPL
>> + *
>> + * This returns back into the BROM after U-Boot SPL has performed its initial
>> + * init. It uses the provided lr and sp to do so.
>> + *
>> + * @lr: BROM link register value (return address)
>> + * @sp: BROM stack pointer
>> + */
>> +void return_to_fel(uint32_t lr, uint32_t sp);
>> +
>> #endif
>> diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig
>> index 4a21589..3eab81f 100644
>> --- a/board/sunxi/Kconfig
>> +++ b/board/sunxi/Kconfig
>> @@ -149,6 +149,16 @@ config SPL_FEL
>> bool "SPL/FEL mode support"
>> depends on SPL
>> default n
>> + help
>> + This enables support for Fast Early Loader (FEL) mode. This
>> + allows U-Boot to be loaded to the board over USB by the on-chip
>> + boot rom. U-Boot should be sent in two parts: SPL first, with
>> + 'fel write 0x2000 u-boot-spl.bin; fel exe 0x2000' then U-Boot with
>> + 'fel write 0x4a000000 u-boot.bin; fel exe 0x4a000000'. This option
>> + shrinks the amount of SRAM available to SPL, so only enable it if
>> + you need FEL. Note that enabling this option only allows FEL to be
>> + used; it is still possible to boot U-Boot from boot media. U-Boot
>> + SPL detects when it is being loaded using FEL.
>>
>> config UART0_PORT_F
>> bool "UART0 on MicroSD breakout board"
>> diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
>> index 6cfd7e1..3becb4f 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 */
>>
>> @@ -146,10 +144,10 @@
>> #define CONFIG_SPL_SERIAL_SUPPORT
>> #define CONFIG_SPL_LIBGENERIC_SUPPORT
>>
>> +#define CONFIG_SPL_BOARD_LOAD_IMAGE
>> +
>> #ifdef CONFIG_SPL_FEL
>>
>> -#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds"
>> -#define CONFIG_SPL_START_S_PATH "arch/arm/cpu/armv7/sunxi"
>> #define CONFIG_SPL_TEXT_BASE 0x2000
>> #define CONFIG_SPL_MAX_SIZE 0x4000 /* 16 KiB */
>>
>> diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl
>> index ecf3037..5a1962b 100644
>> --- a/scripts/Makefile.spl
>> +++ b/scripts/Makefile.spl
>> @@ -153,10 +153,8 @@ ALL-y += $(obj)/$(BOARD)-spl.bin
>> endif
>>
>> ifdef CONFIG_SUNXI
>> -ifndef CONFIG_SPL_FEL
>> ALL-y += $(obj)/sunxi-spl.bin
>> endif
>> -endif
>>
>> ifeq ($(CONFIG_SYS_SOC),"at91")
>> ALL-y += boot.bin
>
> One more theoretical concern is the placement of the stack in the legacy
> FEL mode after your changes. Now it seems to be moved to 0x8000, which
> might be fine though, according to the memory map from
>
> https://github.com/hno/Allwinner-Info/blob/master/FEL-usb/USB-protocol.txt
>
> If we want to preserve the old behaviour, then we would need to place
> it around 0x5d00.
I'm wondering if it might be better for you to take over and respin
this patch? My role has perhaps been to provide a proof-of-concept
implementation, but I don't need to do the final bit.
Let me know what you think.
Regards,
Simon
^ permalink raw reply [flat|nested] 12+ messages in thread
* [U-Boot] [PATCH v2 3/3] sunxi: Normalise FEL support
2015-02-09 22:23 ` Simon Glass
@ 2015-02-11 3:05 ` Siarhei Siamashka
2015-02-11 4:45 ` Simon Glass
0 siblings, 1 reply; 12+ messages in thread
From: Siarhei Siamashka @ 2015-02-11 3:05 UTC (permalink / raw)
To: u-boot
On Mon, 9 Feb 2015 15:23:17 -0700
Simon Glass <sjg@chromium.org> wrote:
> Hi Siarhei,
>
> On 7 February 2015 at 20:48, Siarhei Siamashka
> <siarhei.siamashka@gmail.com> wrote:
> > On Sat, 7 Feb 2015 10:47:30 -0700
> > Simon Glass <sjg@chromium.org> wrote:
> >
> >> Make sunxi's FEL code fit with the normal U-Boot boot sequence instead of
> >> creating its own. There are some #ifdefs required in start.S. Future work
> >> will hopefully remove these.
> >>
> >> This series is available at u-boot-dm, branch sunxi-working.
> >>
> >> Signed-off-by: Simon Glass <sjg@chromium.org>
> >> ---
> >>
> >> Changes in v2:
> >> - Adjust for new save_boot_params() API
> >> - Drop patch to change r0 to r2 in start.S
> >> - Add #ifdefs to start.S to deal with FEL
> >> - Use 'Fast Early Loader' as the full name for FEL
> >
> > Thanks for working on these patches. It looks like we are finally
> > getting really close to resolving the sunxi FEL boot problem.
> >
> > Some comments are below.
> >
> >> arch/arm/cpu/armv7/start.S | 5 +-
> >> arch/arm/cpu/armv7/sunxi/Makefile | 4 +-
> >> arch/arm/cpu/armv7/sunxi/board.c | 21 ++++++++
> >> arch/arm/cpu/armv7/sunxi/config.mk | 2 -
> >> arch/arm/cpu/armv7/sunxi/fel_utils.S | 25 +++++++++
> >> arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds | 82 -----------------------------
> >> arch/arm/include/asm/arch-sunxi/sys_proto.h | 10 ++++
> >> board/sunxi/Kconfig | 10 ++++
> >> include/configs/sunxi-common.h | 6 +--
> >> scripts/Makefile.spl | 2 -
> >> 10 files changed, 73 insertions(+), 94 deletions(-)
> >> create mode 100644 arch/arm/cpu/armv7/sunxi/fel_utils.S
> >> delete mode 100644 arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds
> >>
> >> diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S
> >> index 9b49ece..098a83a 100644
> >> --- a/arch/arm/cpu/armv7/start.S
> >> +++ b/arch/arm/cpu/armv7/start.S
> >> @@ -54,7 +54,8 @@ save_boot_params_ret:
> >> * (OMAP4 spl TEXT_BASE is not 32 byte aligned.
> >> * Continue to use ROM code vector only in OMAP4 spl)
> >> */
> >> -#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD))
> >> +#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD)) && \
> >> + !defined(CONFIG_SPL_FEL)
> >
> > Maybe we can just update the 'save_boot_params' function to save the
> > important configuration registers and then undo this configuration
> > in 'return_to_fel'? This allows us to avoid the sunxi specific ifdefs
> > in the core ARM code.
> >
> > In this particular case, restoring VBAR and CPSR is important because
> > the BROM code uses an IRQ handler for FEL (presumably USB related).
> > And we want to ensure that this IRQ handler works properly again
> > after resuming the FEL code.
>
> We could indeed.
>
> It would avoid the #ifdef but my understanding is that you might be
> able to avoid having to 'return' to the BROM through another means. In
> any case we could perhaps leave that change until the next release?
I just previously thought that the FEL tool could store the return
address somewhere in beginning of SRAM in the eGON header extension.
In this case, restoring the 'lr' and 'sp' registers would be unnecessary
and the use of the 'save_boot_params' function could be dropped.
But if we still need to save/restore VBAR and the other control
registers, then this idea about not saving 'lr' and 'sp' does not
really improve anything.
[...]
> >> u32 spl_boot_device(void)
> >> {
> >> + /*
> >> + * Have we been asked to return to the FEL portion of the boot ROM?
> >> + * TODO: We need a more robust test here, or bracket this with
> >> + * #ifdef CONFIG_SPL_FEL.
> >> + */
> >> + if (fel_stash.lr >= 0xffff0000 && fel_stash.lr < 0xffff4000)
> >> + return BOOT_DEVICE_BOARD;
> >> return BOOT_DEVICE_MMC1;
> >
> > It is probably better to do it this way:
> >
> > #ifdef CONFIG_SPL_FEL
> > return BOOT_DEVICE_BOARD;
> > #else
> > if (memcmp((void *)4, "eGON.BT0", 8) == 0)
> > return BOOT_DEVICE_MMC1;
> > else
> > return BOOT_DEVICE_BOARD;
> > #endif
> >
> > The memcmp (or equivalent code) ensures that it is compatible with
> > https://github.com/ssvb/sunxi-tools/commit/aa7e1880986e5c9a825b08aed9dc5621b821805f
> >
> > Then the new 'fel spl u-boot-sunxi-with-spl.bin' command for loading
> > and executing the SPL works fine without CONFIG_SPL_FEL defined
> > (because the SD card specific "eGON.BT0" signature is replaced with
> > the "eGON.FEL" signature by the 'fel' tool in the device memory
> > before transferring control to the SPL code). Needless to say that
> > the SPL built this way still works when written to the SD card.
> >
> > And if CONFIG_SPL_FEL is defined, then the FEL support still works in a
> > legacy way (via 'fel write 0x2000 u-boot-spl.bin; fel exe 0x2000').
> >
> > We would only need to drop the legacy way in u-boot v2015.07 if the
> > new one proves to be problem free by that time :-)
>
> So you mean that we can drop CONFIG_SPL_FEL?
Yes, we can already do this. But in order to play safe, the
CONFIG_SPL_FEL option could be still kept for a while to provide
the users with an alternative method just in case.
> [snip]
>
> >
> > ENTRY(save_boot_params)
> > ldr r0, =fel_stash
> > str sp, [r0, #0]
> > str lr, [r0, #4]
> > mrs lr, cpsr @ Read CPSR
> > str lr, [r0, #8]
> > mrc p15, 0, lr, c1, c0, 0 @ Read CP15 SCTLR
> > str lr, [r0, #12]
> > mrc p15, 0, lr, c12, c0, 0 @ Read VBAR
> > str lr, [r0, #16]
> > mrc p15, 0, lr, c1, c0, 0 @ Read CP15 Control
> > str lr, [r0, #20]
> > b save_boot_params_ret
> > ENDPROC(save_boot_params)
> >
> > ENTRY(return_to_fel)
> > ldr r0, =fel_stash
> > ldr lr, [r0, #20]
> > mcr p15, 0, lr, c1, c0, 0 @ Write CP15 Control
> > ldr lr, [r0, #16]
> > mcr p15, 0, lr, c12, c0, 0 @ Write VBAR
> > ldr lr, [r0, #12]
> > mcr p15, 0, lr, c1, c0, 0 @ Write CP15 SCTLR
> > ldr lr, [r0, #8]
> > msr cpsr, lr @ Write CPSR
> > ldr sp, [r0, #0]
> > ldr lr, [r0, #4]
> > bx lr
> > ENDPROC(return_to_fel)
> >
> >
> > This seems to work for me. However we probably might try to skip
> > restoring some of these registers. Also somebody might want to
> > review the order in which the registers should be restored.
>
> I can certainly incorporate this into the patch.
>
> Is that what you would prefer? It seems more complicated, and also a
> bit odd to save a whole load of data that we then corrupt and restore,
> but it is fine with me.
This is a way not to touch the Albert's code in 'start.S', but instead
deal with the problem in the sunxi code.
If Albert has objections against the introduction of special flags to
skip setup of these control registers, then I think that saving them
early and restoring back to the original values when returning back
to the BROM as the only possible alternative.
The BROM will not be able to work correctly if the VBAR register is
clobbered by the SPL.
Yes, this all is a bit odd. But as Hans explained earlier, the main
u-boot binary has to be pretty much standalone and can't rely on the
stuff being configured by the SPL:
http://lists.denx.de/pipermail/u-boot/2015-January/202204.html
[...]
> > One more theoretical concern is the placement of the stack in the legacy
> > FEL mode after your changes. Now it seems to be moved to 0x8000, which
> > might be fine though, according to the memory map from
> >
> > https://github.com/hno/Allwinner-Info/blob/master/FEL-usb/USB-protocol.txt
> >
> > If we want to preserve the old behaviour, then we would need to place
> > it around 0x5d00.
>
> I'm wondering if it might be better for you to take over and respin
> this patch? My role has perhaps been to provide a proof-of-concept
> implementation, but I don't need to do the final bit.
>
> Let me know what you think.
I'm just applying these changes on top of your patches (just all the
same as is discussed here):
https://github.com/ssvb/u-boot-sunxi/commit/6385323f7704b3802f594a05fc8c373a4617ebbc
And after this, the CONFIG_SPL_FEL define becomes unnecessary. Even
though this old method still works (relying on the CONFIG_SPL_FEL
define and uploading the SPL to 0x2000).
You could squash these changes in your third patch if nobody has
objections.
Regarding the stack location. The stack at 0x8000 might be also
perfectly fine. We have not done a detailed analysis of the BROM
disassembly, so can't be absolutely sure about anything. But
based on just treating the BROM as a black box and running some
experimental tests, it looks OK so far.
Maybe Hans has an opinion about how we should deal with it?
--
Best regards,
Siarhei Siamashka
^ permalink raw reply [flat|nested] 12+ messages in thread
* [U-Boot] [PATCH v2 3/3] sunxi: Normalise FEL support
2015-02-11 3:05 ` Siarhei Siamashka
@ 2015-02-11 4:45 ` Simon Glass
0 siblings, 0 replies; 12+ messages in thread
From: Simon Glass @ 2015-02-11 4:45 UTC (permalink / raw)
To: u-boot
Hi Siarhei,
On 10 February 2015 at 20:05, Siarhei Siamashka
<siarhei.siamashka@gmail.com> wrote:
> On Mon, 9 Feb 2015 15:23:17 -0700
> Simon Glass <sjg@chromium.org> wrote:
>
>> Hi Siarhei,
>>
>> On 7 February 2015 at 20:48, Siarhei Siamashka
>> <siarhei.siamashka@gmail.com> wrote:
>> > On Sat, 7 Feb 2015 10:47:30 -0700
>> > Simon Glass <sjg@chromium.org> wrote:
>> >
>> >> Make sunxi's FEL code fit with the normal U-Boot boot sequence instead of
>> >> creating its own. There are some #ifdefs required in start.S. Future work
>> >> will hopefully remove these.
>> >>
>> >> This series is available at u-boot-dm, branch sunxi-working.
>> >>
>> >> Signed-off-by: Simon Glass <sjg@chromium.org>
>> >> ---
>> >>
>> >> Changes in v2:
>> >> - Adjust for new save_boot_params() API
>> >> - Drop patch to change r0 to r2 in start.S
>> >> - Add #ifdefs to start.S to deal with FEL
>> >> - Use 'Fast Early Loader' as the full name for FEL
>> >
>> > Thanks for working on these patches. It looks like we are finally
>> > getting really close to resolving the sunxi FEL boot problem.
>> >
>> > Some comments are below.
>> >
>> >> arch/arm/cpu/armv7/start.S | 5 +-
>> >> arch/arm/cpu/armv7/sunxi/Makefile | 4 +-
>> >> arch/arm/cpu/armv7/sunxi/board.c | 21 ++++++++
>> >> arch/arm/cpu/armv7/sunxi/config.mk | 2 -
>> >> arch/arm/cpu/armv7/sunxi/fel_utils.S | 25 +++++++++
>> >> arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds | 82 -----------------------------
>> >> arch/arm/include/asm/arch-sunxi/sys_proto.h | 10 ++++
>> >> board/sunxi/Kconfig | 10 ++++
>> >> include/configs/sunxi-common.h | 6 +--
>> >> scripts/Makefile.spl | 2 -
>> >> 10 files changed, 73 insertions(+), 94 deletions(-)
>> >> create mode 100644 arch/arm/cpu/armv7/sunxi/fel_utils.S
>> >> delete mode 100644 arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds
>> >>
>> >> diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S
>> >> index 9b49ece..098a83a 100644
>> >> --- a/arch/arm/cpu/armv7/start.S
>> >> +++ b/arch/arm/cpu/armv7/start.S
>> >> @@ -54,7 +54,8 @@ save_boot_params_ret:
>> >> * (OMAP4 spl TEXT_BASE is not 32 byte aligned.
>> >> * Continue to use ROM code vector only in OMAP4 spl)
>> >> */
>> >> -#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD))
>> >> +#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD)) && \
>> >> + !defined(CONFIG_SPL_FEL)
>> >
>> > Maybe we can just update the 'save_boot_params' function to save the
>> > important configuration registers and then undo this configuration
>> > in 'return_to_fel'? This allows us to avoid the sunxi specific ifdefs
>> > in the core ARM code.
>> >
>> > In this particular case, restoring VBAR and CPSR is important because
>> > the BROM code uses an IRQ handler for FEL (presumably USB related).
>> > And we want to ensure that this IRQ handler works properly again
>> > after resuming the FEL code.
>>
>> We could indeed.
>>
>> It would avoid the #ifdef but my understanding is that you might be
>> able to avoid having to 'return' to the BROM through another means. In
>> any case we could perhaps leave that change until the next release?
>
> I just previously thought that the FEL tool could store the return
> address somewhere in beginning of SRAM in the eGON header extension.
> In this case, restoring the 'lr' and 'sp' registers would be unnecessary
> and the use of the 'save_boot_params' function could be dropped.
>
> But if we still need to save/restore VBAR and the other control
> registers, then this idea about not saving 'lr' and 'sp' does not
> really improve anything.
OK I see see.
>
> [...]
>
>> >> u32 spl_boot_device(void)
>> >> {
>> >> + /*
>> >> + * Have we been asked to return to the FEL portion of the boot ROM?
>> >> + * TODO: We need a more robust test here, or bracket this with
>> >> + * #ifdef CONFIG_SPL_FEL.
>> >> + */
>> >> + if (fel_stash.lr >= 0xffff0000 && fel_stash.lr < 0xffff4000)
>> >> + return BOOT_DEVICE_BOARD;
>> >> return BOOT_DEVICE_MMC1;
>> >
>> > It is probably better to do it this way:
>> >
>> > #ifdef CONFIG_SPL_FEL
>> > return BOOT_DEVICE_BOARD;
>> > #else
>> > if (memcmp((void *)4, "eGON.BT0", 8) == 0)
>> > return BOOT_DEVICE_MMC1;
>> > else
>> > return BOOT_DEVICE_BOARD;
>> > #endif
>> >
>> > The memcmp (or equivalent code) ensures that it is compatible with
>> > https://github.com/ssvb/sunxi-tools/commit/aa7e1880986e5c9a825b08aed9dc5621b821805f
>> >
>> > Then the new 'fel spl u-boot-sunxi-with-spl.bin' command for loading
>> > and executing the SPL works fine without CONFIG_SPL_FEL defined
>> > (because the SD card specific "eGON.BT0" signature is replaced with
>> > the "eGON.FEL" signature by the 'fel' tool in the device memory
>> > before transferring control to the SPL code). Needless to say that
>> > the SPL built this way still works when written to the SD card.
>> >
>> > And if CONFIG_SPL_FEL is defined, then the FEL support still works in a
>> > legacy way (via 'fel write 0x2000 u-boot-spl.bin; fel exe 0x2000').
>> >
>> > We would only need to drop the legacy way in u-boot v2015.07 if the
>> > new one proves to be problem free by that time :-)
>>
>> So you mean that we can drop CONFIG_SPL_FEL?
>
> Yes, we can already do this. But in order to play safe, the
> CONFIG_SPL_FEL option could be still kept for a while to provide
> the users with an alternative method just in case.
OK.
>
>> [snip]
>>
>> >
>> > ENTRY(save_boot_params)
>> > ldr r0, =fel_stash
>> > str sp, [r0, #0]
>> > str lr, [r0, #4]
>> > mrs lr, cpsr @ Read CPSR
>> > str lr, [r0, #8]
>> > mrc p15, 0, lr, c1, c0, 0 @ Read CP15 SCTLR
>> > str lr, [r0, #12]
>> > mrc p15, 0, lr, c12, c0, 0 @ Read VBAR
>> > str lr, [r0, #16]
>> > mrc p15, 0, lr, c1, c0, 0 @ Read CP15 Control
>> > str lr, [r0, #20]
>> > b save_boot_params_ret
>> > ENDPROC(save_boot_params)
>> >
>> > ENTRY(return_to_fel)
>> > ldr r0, =fel_stash
>> > ldr lr, [r0, #20]
>> > mcr p15, 0, lr, c1, c0, 0 @ Write CP15 Control
>> > ldr lr, [r0, #16]
>> > mcr p15, 0, lr, c12, c0, 0 @ Write VBAR
>> > ldr lr, [r0, #12]
>> > mcr p15, 0, lr, c1, c0, 0 @ Write CP15 SCTLR
>> > ldr lr, [r0, #8]
>> > msr cpsr, lr @ Write CPSR
>> > ldr sp, [r0, #0]
>> > ldr lr, [r0, #4]
>> > bx lr
>> > ENDPROC(return_to_fel)
>> >
>> >
>> > This seems to work for me. However we probably might try to skip
>> > restoring some of these registers. Also somebody might want to
>> > review the order in which the registers should be restored.
>>
>> I can certainly incorporate this into the patch.
>>
>> Is that what you would prefer? It seems more complicated, and also a
>> bit odd to save a whole load of data that we then corrupt and restore,
>> but it is fine with me.
>
> This is a way not to touch the Albert's code in 'start.S', but instead
> deal with the problem in the sunxi code.
>
> If Albert has objections against the introduction of special flags to
> skip setup of these control registers, then I think that saving them
> early and restoring back to the original values when returning back
> to the BROM as the only possible alternative.
>
> The BROM will not be able to work correctly if the VBAR register is
> clobbered by the SPL.
>
> Yes, this all is a bit odd. But as Hans explained earlier, the main
> u-boot binary has to be pretty much standalone and can't rely on the
> stuff being configured by the SPL:
>
> http://lists.denx.de/pipermail/u-boot/2015-January/202204.html
As I may have mentioned I am not keen on this. If this is aimed at
engineers they can decide how they want to configure things for
development purposes. But I will leave this to you.
Albert specifically requested #ifdef instead of run-time so I don't
think he objects.
>
>
> [...]
>
>> > One more theoretical concern is the placement of the stack in the legacy
>> > FEL mode after your changes. Now it seems to be moved to 0x8000, which
>> > might be fine though, according to the memory map from
>> >
>> > https://github.com/hno/Allwinner-Info/blob/master/FEL-usb/USB-protocol.txt
>> >
>> > If we want to preserve the old behaviour, then we would need to place
>> > it around 0x5d00.
>>
>> I'm wondering if it might be better for you to take over and respin
>> this patch? My role has perhaps been to provide a proof-of-concept
>> implementation, but I don't need to do the final bit.
>>
>> Let me know what you think.
>
> I'm just applying these changes on top of your patches (just all the
> same as is discussed here):
>
> https://github.com/ssvb/u-boot-sunxi/commit/6385323f7704b3802f594a05fc8c373a4617ebbc
>
> And after this, the CONFIG_SPL_FEL define becomes unnecessary. Even
> though this old method still works (relying on the CONFIG_SPL_FEL
> define and uploading the SPL to 0x2000).
>
> You could squash these changes in your third patch if nobody has
> objections.
>
> Regarding the stack location. The stack at 0x8000 might be also
> perfectly fine. We have not done a detailed analysis of the BROM
> disassembly, so can't be absolutely sure about anything. But
> based on just treating the BROM as a black box and running some
> experimental tests, it looks OK so far.
>
> Maybe Hans has an opinion about how we should deal with it?
I believe that the patch I sent works OK. So maybe the best thing is
for you to send a new patch on top of that.
If Albert can ACK my series (+/- the last patch) and then you can take
it through the sunxi tree I think. (I don't mind, this is just a
suggestion).
What I am getting at is that I feel I have provided a possible
solution but I don't want to get in the way of you deciding how best
to arrange things for sunxi. I think it is reasonable for you to merge
a few changes on top of what I have for this release. My goal is to
drop gdata. I'm really pleased to learn about FEL but I don't mind too
much exactly how it works.
Regards,
Simon
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2015-02-11 4:45 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-02-07 17:47 [U-Boot] [PATCH v2 1/3] arm: Allow lr to be saved by board code Simon Glass
2015-02-07 17:47 ` [U-Boot] [PATCH v2 2/3] arm: spl: Provide for a board-specific loader Simon Glass
2015-02-08 3:44 ` Siarhei Siamashka
2015-02-07 17:47 ` [U-Boot] [PATCH v2 3/3] sunxi: Normalise FEL support Simon Glass
2015-02-07 17:59 ` Hans de Goede
2015-02-07 18:02 ` Simon Glass
2015-02-07 21:46 ` Hans de Goede
2015-02-08 3:48 ` Siarhei Siamashka
2015-02-09 22:23 ` Simon Glass
2015-02-11 3:05 ` Siarhei Siamashka
2015-02-11 4:45 ` Simon Glass
2015-02-08 3:43 ` [U-Boot] [PATCH v2 1/3] arm: Allow lr to be saved by board code Siarhei Siamashka
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.