[U-Boot] [PATCH v4 00/18] rockchip: back-to-bootrom: replace assembly-implementation with C-code

Recent discussions confirmed (what the code always assumed): the Rockchip BROM always enters U-Boot with the stack-pointer valid (i.e. the U-Boot startup code is running off the BROM stack).
We can thus replace the back-to-bootrom code (i.e. both the save_boot_params and back_to_bootrom implementations) using C-code based on setjmp/longjmp. The new implementation is already structured to allow an easy drop-in of Andy's changes to enter download-mode when returning to the BROM.
This turned out to require a some tweaking to system.h (making sure that the prototype for save_boot_params_ret is visible for A64)and start.S (so binutils knows that this is a possible function entry and it can correctly insert A32-to-Thumb transitions) and taking the axe to setjmp.h (which created quite a few issues with it not expecting A32/T32/Thumb call-sites and some fragility from GCC being smart about the clobber-list of the inline assembly... which led to r9 not being saved or restored).
For v4+: To fix issues with the RK3188 support, this also updates the boot0 hook changes (i.e. allowing the boot0-hook to insert code/data before the ARM vector table) that Kever had submitted this spring and implements a similar "early back-to-bootrom" as suggested by Pawel (for the RK3066) as a generic mechanism.
Changes in v4: - after merging the 'back-to-bootrom' series with the 'boot0-hook' series, this drops the TPL stub and builds only a single SPL image that uses the 'early back-to-bootrom' logic originally implemented by Pawel for the RK3066. - changes the SPL_STACK_BASE to +0x800 (from +0x804), as the boot0 hook already reserves the space for the SPL magic (previously inserted by mkimage) - no longer updates rk3188-board-tpl.c (as we have just removed it in an earlier commit of the series)
Changes in v3: - tracked the root-cause why no interwork branch was emitted and fixed it using a '.type'-directive in start.S to mark save_boot_params_ret as a (possible) function-entry. - converted setjmp/longjmp from inline-assembly to separate .S files to improve predicatability if emitted code
Changes in v2: - [added in v2] chain back_to_bootrom calls for SPL, first returning to the TPL (using the same mechanism) and the to the BROM from the TPL - also covers the RK3188 (which I had originally missed)
Kever Yang (3): rockchip: boot0: align to 0x20 for armv7 '_start' rockchip: mkimage: use spl_boot0 for all Rockchip SoCs rockchip: rk3288: use aligned address for SPL_TEXT_BASE
Philipp Tomsich (15): arm: boot0 hook: move boot0 hook before '_start' rockchip: enable boot0-hook for all Rockchip SoCs rockchip: rk3036: use aligned address for SPL_TEXT_BASE socfpga: boot0 hook: adjust to unified boot0 semantics bcm235xx: boot0 hook: adjust to unified boot0 semantics bcm281xx: boot0 hook: adjust to unified boot0 semantics rockchip: boot0 hook: support early return for RK3188/RK3066-style BROM arm: make save_boot_params_ret prototype visible for AArch64 arm: mark save_boot_params_ret as a function arm: provide a PCS-compliant setjmp implementation rockchip: back-to-bootrom: replace assembly-implementation with C-code rockchip: rk3188: use boot0 hook to load up SPL in 2 steps rockchip: back-to-bootrom: allow passing a cmd to the bootrom rockchip: rk3188: move CONFIG_SPL_* entries from rk3188_common.h to Kconfig rockchip: mkimage: remove unused code-paths (spl_boot0 is now implied)
arch/arm/Kconfig | 1 + arch/arm/cpu/armv7/start.S | 1 + arch/arm/include/asm/arch-bcm235xx/boot0.h | 2 + arch/arm/include/asm/arch-bcm281xx/boot0.h | 2 + arch/arm/include/asm/arch-rockchip/boot0.h | 37 ++++++++--- arch/arm/include/asm/arch-rockchip/bootrom.h | 30 ++++++--- arch/arm/include/asm/setjmp.h | 94 ++++------------------------ arch/arm/include/asm/system.h | 62 +++++++++--------- arch/arm/lib/Makefile | 6 ++ arch/arm/lib/setjmp.S | 37 +++++++++++ arch/arm/lib/setjmp_aarch64.S | 42 +++++++++++++ arch/arm/lib/vectors.S | 54 ++++++++++------ arch/arm/mach-rockchip/Kconfig | 39 ++++++++++-- arch/arm/mach-rockchip/Makefile | 5 +- arch/arm/mach-rockchip/bootrom.c | 54 +++++++++++++++- arch/arm/mach-rockchip/rk3036-board-spl.c | 2 +- arch/arm/mach-rockchip/rk3188-board-spl.c | 14 +---- arch/arm/mach-rockchip/rk3188-board-tpl.c | 86 ------------------------- arch/arm/mach-rockchip/rk322x-board-spl.c | 2 +- arch/arm/mach-rockchip/rk3288-board-spl.c | 4 +- arch/arm/mach-rockchip/rk3288-board-tpl.c | 2 +- arch/arm/mach-rockchip/rk3368-board-tpl.c | 2 +- arch/arm/mach-rockchip/rk3399-board-spl.c | 2 +- arch/arm/mach-rockchip/save_boot_param.S | 69 -------------------- arch/arm/mach-socfpga/include/mach/boot0.h | 3 + doc/README.rockchip | 10 +-- include/configs/rk3036_common.h | 2 +- include/configs/rk3188_common.h | 18 +----- include/configs/rk3288_common.h | 2 +- tools/rkcommon.c | 45 +++++-------- 30 files changed, 347 insertions(+), 382 deletions(-) create mode 100644 arch/arm/lib/setjmp.S create mode 100644 arch/arm/lib/setjmp_aarch64.S delete mode 100644 arch/arm/mach-rockchip/rk3188-board-tpl.c delete mode 100644 arch/arm/mach-rockchip/save_boot_param.S

The boot0 hook on ARM does not insert its payload before the vector table. This is both a mismatch with thec comment above it and contradict usage of the boot0 hook on ARM64.
To fix this (and unify the semantics for ARM and ARM64), we change the boot0-hook semantics on ARM to match those on ARM64: (1) if a boot0-hook is present it is inserted at the start of the image (2) if a boot0-hook is present, emitting the ARM vector table (and the _start) symbol are suppressed in vectors.S and the boot0-hook has full control over where and when it wants to emit these
Signed-off-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com ---
Changes in v4: None Changes in v3: None Changes in v2: None
arch/arm/include/asm/arch-rockchip/boot0.h | 1 - arch/arm/lib/vectors.S | 54 +++++++++++++++++++----------- 2 files changed, 35 insertions(+), 20 deletions(-)
diff --git a/arch/arm/include/asm/arch-rockchip/boot0.h b/arch/arm/include/asm/arch-rockchip/boot0.h index 72d264b..455d842 100644 --- a/arch/arm/include/asm/arch-rockchip/boot0.h +++ b/arch/arm/include/asm/arch-rockchip/boot0.h @@ -1,4 +1,3 @@ - /* * Copyright 2017 Theobroma Systems Design und Consulting GmbH * diff --git a/arch/arm/lib/vectors.S b/arch/arm/lib/vectors.S index 1019091..9cb0d2e 100644 --- a/arch/arm/lib/vectors.S +++ b/arch/arm/lib/vectors.S @@ -16,6 +16,22 @@ #include <config.h>
/* + * A macro to allow insertion of an ARM exception vector either + * for the non-boot0 case or by a boot0-header. + */ + .macro ARM_VECTORS + b reset + ldr pc, _undefined_instruction + ldr pc, _software_interrupt + ldr pc, _prefetch_abort + ldr pc, _data_abort + ldr pc, _not_used + ldr pc, _irq + ldr pc, _fiq + .endm + + +/* ************************************************************************* * * Symbol _start is referenced elsewhere, so make it global @@ -35,6 +51,23 @@
.section ".vectors", "ax"
+#if defined(CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK) +/* + * Various SoCs need something special and SoC-specific up front in + * order to boot, allow them to set that in their boot0.h file and then + * use it here. + * + * To allow a boot0 hook to insert a 'special' sequence after the vector + * table (e.g. for the socfpga), the presence of a boot0 hook supresses + * the below vector table and assumes that the vector table is filled in + * by the boot0 hook. The requirements for a boot0 hook thus are: + * (1) defines '_start:' as appropriate + * (2) inserts the vector table using ARM_VECTORS as appropriate + */ +#include <asm/arch/boot0.h> + +#else + /* ************************************************************************* * @@ -46,28 +79,11 @@ */
_start: - #ifdef CONFIG_SYS_DV_NOR_BOOT_CFG .word CONFIG_SYS_DV_NOR_BOOT_CFG #endif - - b reset - ldr pc, _undefined_instruction - ldr pc, _software_interrupt - ldr pc, _prefetch_abort - ldr pc, _data_abort - ldr pc, _not_used - ldr pc, _irq - ldr pc, _fiq - -#ifdef CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK -/* - * Various SoCs need something special and SoC-specific up front in - * order to boot, allow them to set that in their boot0.h file and then - * use it here. - */ -#include <asm/arch/boot0.h> -#endif + ARM_VECTORS +#endif /* !defined(CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK) */
/* *************************************************************************

From: Kever Yang kever.yang@rock-chips.com
The '_start' is using as vector table base address, and will write to VBAR register, so it needs to be aligned to 0x20 for armv7.
Signed-off-by: Kever Yang kever.yang@rock-chips.com [Updated to current code base:] Signed-off-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com
---
Changes in v4: None Changes in v3: None Changes in v2: None
arch/arm/include/asm/arch-rockchip/boot0.h | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/arch/arm/include/asm/arch-rockchip/boot0.h b/arch/arm/include/asm/arch-rockchip/boot0.h index 455d842..f7c6146 100644 --- a/arch/arm/include/asm/arch-rockchip/boot0.h +++ b/arch/arm/include/asm/arch-rockchip/boot0.h @@ -6,12 +6,13 @@
/* * Execution starts on the instruction following this 4-byte header - * (containing the magic 'RK33'). + * (containing the magic 'RK30', 'RK31', 'RK32' or 'RK33'). This + * magic constant will be written into the final image by the rkimage + * tool, but we need to reserve space for it here. * * To make life easier for everyone, we build the SPL binary with * space for this 4-byte header already included in the binary. */ - #ifdef CONFIG_SPL_BUILD /* * We need to add 4 bytes of space for the 'RK33' at the @@ -26,6 +27,15 @@ b reset /* may be overwritten --- should be 'nop' or a 'b reset' */ #endif b reset +#if !defined(CONFIG_ARM64) + /* + * For armv7, the addr '_start' will used as vector start address + * and write to VBAR register, which needs to aligned to 0x20. + */ + .align(5) +_start: + ARM_VECTORS +#endif
#if defined(CONFIG_ROCKCHIP_RK3399) && defined(CONFIG_SPL_BUILD) .space CONFIG_ROCKCHIP_SPL_RESERVE_IRAM /* space for the ATF data */

Rockchip SoCs bootrom design is like this: - First 2KB or 4KB internal memory is for bootrom stack and heap; - Then the first 4-byte suppose to be a TAG like 'RK33'; - The the following memory address end with '0004' is the first instruction load and running by bootrom;
Let's use the boot0 hook to reserve the first 4-byte tag for all the Rockchip SoCs.
Signed-off-by: Philipp Tomsich philipp.tomsich@theobroma-systems [Commit message:] Signed-off-by: Kever Yang kever.yang@rock-chips.com
Signed-off-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com ---
Changes in v4: None Changes in v3: None Changes in v2: None
arch/arm/Kconfig | 1 + arch/arm/mach-rockchip/Kconfig | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 5d1ce3e..d5050d0 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1109,6 +1109,7 @@ config ARCH_ROCKCHIP select DM_USB if USB select DM_PWM select DM_REGULATOR + select ENABLE_ARM_SOC_BOOT0_HOOK imply CMD_FASTBOOT imply FASTBOOT imply FAT_WRITE diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig index d9b25d5..31e9864 100644 --- a/arch/arm/mach-rockchip/Kconfig +++ b/arch/arm/mach-rockchip/Kconfig @@ -74,7 +74,6 @@ config ROCKCHIP_RK3368 imply SPL_SEPARATE_BSS imply SPL_SERIAL_SUPPORT imply TPL_SERIAL_SUPPORT - select ENABLE_ARM_SOC_BOOT0_HOOK select DEBUG_UART_BOARD_INIT select SYS_NS16550 help @@ -112,7 +111,6 @@ config ROCKCHIP_RK3399 select SPL_SEPARATE_BSS select SPL_SERIAL_SUPPORT select SPL_DRIVERS_MISC_SUPPORT - select ENABLE_ARM_SOC_BOOT0_HOOK select DEBUG_UART_BOARD_INIT help The Rockchip RK3399 is a ARM-based SoC with a dual-core Cortex-A72

Hi Philipp:
On 2017年10月07日 03:28, Philipp Tomsich wrote:
Rockchip SoCs bootrom design is like this:
- First 2KB or 4KB internal memory is for bootrom stack and heap;
- Then the first 4-byte suppose to be a TAG like 'RK33';
- The the following memory address end with '0004' is the first instruction load and running by bootrom;
Let's use the boot0 hook to reserve the first 4-byte tag for all the Rockchip SoCs.
Signed-off-by: Philipp Tomsich philipp.tomsich@theobroma-systems [Commit message:]
What's this ?
Signed-off-by: Kever Yang kever.yang@rock-chips.com
Signed-off-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com
Changes in v4: None Changes in v3: None Changes in v2: None
arch/arm/Kconfig | 1 + arch/arm/mach-rockchip/Kconfig | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 5d1ce3e..d5050d0 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1109,6 +1109,7 @@ config ARCH_ROCKCHIP select DM_USB if USB select DM_PWM select DM_REGULATOR
- select ENABLE_ARM_SOC_BOOT0_HOOK imply CMD_FASTBOOT imply FASTBOOT imply FAT_WRITE
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig index d9b25d5..31e9864 100644 --- a/arch/arm/mach-rockchip/Kconfig +++ b/arch/arm/mach-rockchip/Kconfig @@ -74,7 +74,6 @@ config ROCKCHIP_RK3368 imply SPL_SEPARATE_BSS imply SPL_SERIAL_SUPPORT imply TPL_SERIAL_SUPPORT
- select ENABLE_ARM_SOC_BOOT0_HOOK select DEBUG_UART_BOARD_INIT select SYS_NS16550 help
@@ -112,7 +111,6 @@ config ROCKCHIP_RK3399 select SPL_SEPARATE_BSS select SPL_SERIAL_SUPPORT select SPL_DRIVERS_MISC_SUPPORT
- select ENABLE_ARM_SOC_BOOT0_HOOK select DEBUG_UART_BOARD_INIT help The Rockchip RK3399 is a ARM-based SoC with a dual-core Cortex-A72

On 9 Oct 2017, at 11:37, Andy Yan andy.yan@rock-chips.com wrote:
Hi Philipp:
On 2017年10月07日 03:28, Philipp Tomsich wrote:
Rockchip SoCs bootrom design is like this:
- First 2KB or 4KB internal memory is for bootrom stack and heap;
- Then the first 4-byte suppose to be a TAG like 'RK33';
- The the following memory address end with '0004' is the first instruction load and running by bootrom;
Let's use the boot0 hook to reserve the first 4-byte tag for all the Rockchip SoCs.
Signed-off-by: Philipp Tomsich philipp.tomsich@theobroma-systems [Commit message:]
What's this ?
This means "I took the commit message from Kever’s original boot0-series, but the content of the patch was rewritten”.
Signed-off-by: Kever Yang kever.yang@rock-chips.com
Signed-off-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com
Changes in v4: None Changes in v3: None Changes in v2: None
arch/arm/Kconfig | 1 + arch/arm/mach-rockchip/Kconfig | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 5d1ce3e..d5050d0 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1109,6 +1109,7 @@ config ARCH_ROCKCHIP select DM_USB if USB select DM_PWM select DM_REGULATOR
- select ENABLE_ARM_SOC_BOOT0_HOOK imply CMD_FASTBOOT imply FASTBOOT imply FAT_WRITE
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig index d9b25d5..31e9864 100644 --- a/arch/arm/mach-rockchip/Kconfig +++ b/arch/arm/mach-rockchip/Kconfig @@ -74,7 +74,6 @@ config ROCKCHIP_RK3368 imply SPL_SEPARATE_BSS imply SPL_SERIAL_SUPPORT imply TPL_SERIAL_SUPPORT
- select ENABLE_ARM_SOC_BOOT0_HOOK select DEBUG_UART_BOARD_INIT select SYS_NS16550 help
@@ -112,7 +111,6 @@ config ROCKCHIP_RK3399 select SPL_SEPARATE_BSS select SPL_SERIAL_SUPPORT select SPL_DRIVERS_MISC_SUPPORT
- select ENABLE_ARM_SOC_BOOT0_HOOK select DEBUG_UART_BOARD_INIT help The Rockchip RK3399 is a ARM-based SoC with a dual-core Cortex-A72

From: Kever Yang kever.yang@rock-chips.com
Enable the spl_boot0 in SPL and use the pre-padding TAG memory, the mkimage do not need to pad it but only need to replace the value with correct TAG value.
Signed-off-by: Kever Yang kever.yang@rock-chips.com [Updated:] Signed-off-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com
---
Changes in v4: None Changes in v3: None Changes in v2: None
tools/rkcommon.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/tools/rkcommon.c b/tools/rkcommon.c index 1a24e16..c83260a 100644 --- a/tools/rkcommon.c +++ b/tools/rkcommon.c @@ -72,15 +72,15 @@ struct spl_info { };
static struct spl_info spl_infos[] = { - { "rk3036", "RK30", 0x1000, false, false }, - { "rk3128", "RK31", 0x1800, false, false }, - { "rk3188", "RK31", 0x8000 - 0x800, true, false }, - { "rk322x", "RK32", 0x8000 - 0x1000, false, false }, - { "rk3288", "RK32", 0x8000, false, false }, - { "rk3328", "RK32", 0x8000 - 0x1000, false, false }, + { "rk3036", "RK30", 0x1000, false, true }, + { "rk3128", "RK31", 0x1800, false, true }, + { "rk3188", "RK31", 0x8000 - 0x800, true, true }, + { "rk322x", "RK32", 0x8000 - 0x1000, false, true }, + { "rk3288", "RK32", 0x8000, false, true }, + { "rk3328", "RK32", 0x8000 - 0x1000, false, true }, { "rk3368", "RK33", 0x8000 - 0x1000, false, true }, { "rk3399", "RK33", 0x30000 - 0x2000, false, true }, - { "rv1108", "RK11", 0x1800, false, false}, + { "rv1108", "RK11", 0x1800, false, true }, };
static unsigned char rc4_key[16] = {

From: Kever Yang kever.yang@rock-chips.com
After we use boot0 hook, we can use offset '000' instead of '004' as SPL_TEXT_BASE.
Signed-off-by: Kever Yang kever.yang@rock-chips.com [Updated tag in commit summary:] Signed-off-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com
---
Changes in v4: None Changes in v3: None Changes in v2: None
include/configs/rk3288_common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/configs/rk3288_common.h b/include/configs/rk3288_common.h index 34f2558..9201cb6 100644 --- a/include/configs/rk3288_common.h +++ b/include/configs/rk3288_common.h @@ -35,7 +35,7 @@ #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_TPL_BOOTROM_SUPPORT) # define CONFIG_SPL_TEXT_BASE 0x0 #else -# define CONFIG_SPL_TEXT_BASE 0xff704004 +# define CONFIG_SPL_TEXT_BASE 0xff704000 #endif
/* MMC/SD IP block */

With the boot0-hook inserting the additional padding to receive our SPL magic, the SPL_TEXT_BASE can be aligned again.
Signed-off-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com ---
Changes in v4: None Changes in v3: None Changes in v2: None
include/configs/rk3036_common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/configs/rk3036_common.h b/include/configs/rk3036_common.h index 9ac0df5..a387099 100644 --- a/include/configs/rk3036_common.h +++ b/include/configs/rk3036_common.h @@ -26,7 +26,7 @@ #define CONFIG_SYS_INIT_SP_ADDR 0x60100000 #define CONFIG_SYS_LOAD_ADDR 0x60800800 #define CONFIG_SPL_STACK 0x10081fff -#define CONFIG_SPL_TEXT_BASE 0x10081004 +#define CONFIG_SPL_TEXT_BASE 0x10081000
#define CONFIG_ROCKCHIP_MAX_INIT_SIZE (4 << 10) #define CONFIG_ROCKCHIP_CHIP_TAG "RK30"

With the updated boot0 semantics (i.e. giving the boot0-hook control over when and where the vector table is emitted), the boot0-hook for the socfpga needs to be adjusted.
Signed-off-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com ---
Changes in v4: None Changes in v3: None Changes in v2: None
arch/arm/mach-socfpga/include/mach/boot0.h | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/arch/arm/mach-socfpga/include/mach/boot0.h b/arch/arm/mach-socfpga/include/mach/boot0.h index 22d9e7f..d6b9435 100644 --- a/arch/arm/mach-socfpga/include/mach/boot0.h +++ b/arch/arm/mach-socfpga/include/mach/boot0.h @@ -7,6 +7,9 @@ #ifndef __BOOT0_H #define __BOOT0_H
+_start: + ARM_VECTORS + #ifdef CONFIG_SPL_BUILD .balignl 64,0xf33db33f;

On 10/06/2017 09:28 PM, Philipp Tomsich wrote:
With the updated boot0 semantics (i.e. giving the boot0-hook control over when and where the vector table is emitted), the boot0-hook for the socfpga needs to be adjusted.
Signed-off-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com
Does this still produce the same binary with this patch ? The stuff at offset 0x40 (IIRC) is important.
Changes in v4: None Changes in v3: None Changes in v2: None
arch/arm/mach-socfpga/include/mach/boot0.h | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/arch/arm/mach-socfpga/include/mach/boot0.h b/arch/arm/mach-socfpga/include/mach/boot0.h index 22d9e7f..d6b9435 100644 --- a/arch/arm/mach-socfpga/include/mach/boot0.h +++ b/arch/arm/mach-socfpga/include/mach/boot0.h @@ -7,6 +7,9 @@ #ifndef __BOOT0_H #define __BOOT0_H
+_start:
- ARM_VECTORS
#ifdef CONFIG_SPL_BUILD .balignl 64,0xf33db33f;

This updates the BCM235xx boot0-hook to the updated boot0 semantics by emitting _start and the vector table before the boot0 hook (as was the case before).
Signed-off-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com ---
Changes in v4: None Changes in v3: None Changes in v2: None
arch/arm/include/asm/arch-bcm235xx/boot0.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/arm/include/asm/arch-bcm235xx/boot0.h b/arch/arm/include/asm/arch-bcm235xx/boot0.h index a747bd3..68686ed 100644 --- a/arch/arm/include/asm/arch-bcm235xx/boot0.h +++ b/arch/arm/include/asm/arch-bcm235xx/boot0.h @@ -5,5 +5,7 @@ */
/* BOOT0 header information */ +_start: + ARM_VECTORS .word 0xbabeface .word _end - _start

This updates the BCM281xx boot0-hook to the updated boot0 semantics by emitting _start and the vector table before the boot0 hook (as was the case before).
Signed-off-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com ---
Changes in v4: None Changes in v3: None Changes in v2: None
arch/arm/include/asm/arch-bcm281xx/boot0.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/arm/include/asm/arch-bcm281xx/boot0.h b/arch/arm/include/asm/arch-bcm281xx/boot0.h index a747bd3..28f05ba 100644 --- a/arch/arm/include/asm/arch-bcm281xx/boot0.h +++ b/arch/arm/include/asm/arch-bcm281xx/boot0.h @@ -5,5 +5,7 @@ */
/* BOOT0 header information */ +_start: + ARM_VECTORS .word 0xbabeface .word _end - _start

Some Rockchip BROM versions (e.g. the RK3188 and RK3066) first read 1KB data from NAND into SRAM and executes it. Then, following a return to bootrom, the BROM loads additional code to SRAM (not overwriting the first block read) and reenters at the same address as the first time.
To support booting either a TPL (on the RK3066) or SPL (on the RK3188) using this model of having to count entries, this commit adds code to the boot0 hook to track the number of entries and handle them accordingly.
Signed-off-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com Signed-off-by: Paweł Jarosz paweljarosz3691@gmail.com ---
Changes in v4: None Changes in v3: None Changes in v2: None
arch/arm/include/asm/arch-rockchip/boot0.h | 24 ++++++++++++++++++------ arch/arm/mach-rockchip/Kconfig | 28 ++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 6 deletions(-)
diff --git a/arch/arm/include/asm/arch-rockchip/boot0.h b/arch/arm/include/asm/arch-rockchip/boot0.h index f7c6146..06091d0 100644 --- a/arch/arm/include/asm/arch-rockchip/boot0.h +++ b/arch/arm/include/asm/arch-rockchip/boot0.h @@ -19,12 +19,24 @@ * beginning of the executable. However, as we want to keep * this generic and make it applicable to builds that are like * the RK3368 (TPL needs this, SPL doesn't) or the RK3399 (no - * TPL, but extra space needed in the SPL), we simply repeat - * the 'b reset' with the expectation that the first one will - * be overwritten, if this is the first stage contained in the - * final image created with mkimage)... + * TPL, but extra space needed in the SPL), we simply insert + * a branch-to-next-instruction-word with the expectation that + * the first one may be overwritten, if this is the first stage + * contained in the final image created with mkimage)... */ - b reset /* may be overwritten --- should be 'nop' or a 'b reset' */ + b 1f /* if overwritten, entry-address is at the next word */ +1: +#endif +#if CONFIG_IS_ENABLED(ROCKCHIP_EARLYRETURN_TO_BROM) + adr r3, entry_counter + ldr r0, [r3] + cmp r0, #1 /* check if entry_counter == 1 */ + beq reset /* regular bootup */ + add r0, #1 + str r0, [r3] /* increment the entry_counter in memory */ + bx lr /* return to bootrom */ +entry_counter: + .word 0 #endif b reset #if !defined(CONFIG_ARM64) @@ -32,7 +44,7 @@ * For armv7, the addr '_start' will used as vector start address * and write to VBAR register, which needs to aligned to 0x20. */ - .align(5) + .align(5), 0x0 _start: ARM_VECTORS #endif diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig index 31e9864..d59a1d5 100644 --- a/arch/arm/mach-rockchip/Kconfig +++ b/arch/arm/mach-rockchip/Kconfig @@ -158,6 +158,34 @@ config ROCKCHIP_SPL_RESERVE_IRAM config ROCKCHIP_BROM_HELPER bool
+config SPL_ROCKCHIP_EARLYRETURN_TO_BROM + bool "SPL requires early-return (for RK3188-style BROM) to BROM" + depends on SPL && ENABLE_ARM_SOC_BOOT0_HOOK + help + Some Rockchip BROM variants (e.g. on the RK3188) load the + first stage in segments and enter multiple times. E.g. on + the RK3188, the first 1KB of the first stage are loaded + first and entered; after returning to the BROM, the + remainder of the first stage is loaded, but the BROM + re-enters at the same address/to the same code as previously. + + This enables support code in the BOOT0 hook for the SPL stage + to allow multiple entries. + +config TPL_ROCKCHIP_EARLYRETURN_TO_BROM + bool "TPL requires early-return (for RK3188-style BROM) to BROM" + depends on TPL && ENABLE_ARM_SOC_BOOT0_HOOK + help + Some Rockchip BROM variants (e.g. on the RK3188) load the + first stage in segments and enter multiple times. E.g. on + the RK3188, the first 1KB of the first stage are loaded + first and entered; after returning to the BROM, the + remainder of the first stage is loaded, but the BROM + re-enters at the same address/to the same code as previously. + + This enables support code in the BOOT0 hook for the TPL stage + to allow multiple entries. + config SPL_MMC_SUPPORT default y if !SPL_ROCKCHIP_BACK_TO_BROM

Hi Philipp:
On 2017年10月07日 03:28, Philipp Tomsich wrote:
Some Rockchip BROM versions (e.g. the RK3188 and RK3066) first read 1KB data from NAND into SRAM and executes it. Then, following a return to bootrom, the BROM loads additional code to SRAM (not overwriting the first block read) and reenters at the same address as the first time.
To support booting either a TPL (on the RK3066) or SPL (on the RK3188) using this model of having to count entries, this commit adds code to the boot0 hook to track the number of entries and handle them accordingly.
Signed-off-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com Signed-off-by: Paweł Jarosz paweljarosz3691@gmail.com
Changes in v4: None Changes in v3: None Changes in v2: None
arch/arm/include/asm/arch-rockchip/boot0.h | 24 ++++++++++++++++++------ arch/arm/mach-rockchip/Kconfig | 28 ++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 6 deletions(-)
diff --git a/arch/arm/include/asm/arch-rockchip/boot0.h b/arch/arm/include/asm/arch-rockchip/boot0.h index f7c6146..06091d0 100644 --- a/arch/arm/include/asm/arch-rockchip/boot0.h +++ b/arch/arm/include/asm/arch-rockchip/boot0.h @@ -19,12 +19,24 @@ * beginning of the executable. However, as we want to keep * this generic and make it applicable to builds that are like * the RK3368 (TPL needs this, SPL doesn't) or the RK3399 (no
* TPL, but extra space needed in the SPL), we simply repeat
* the 'b reset' with the expectation that the first one will
* be overwritten, if this is the first stage contained in the
* final image created with mkimage)...
* TPL, but extra space needed in the SPL), we simply insert
* a branch-to-next-instruction-word with the expectation that
* the first one may be overwritten, if this is the first stage
*/* contained in the final image created with mkimage)...
- b reset /* may be overwritten --- should be 'nop' or a 'b reset' */
- b 1f /* if overwritten, entry-address is at the next word */
+1: +#endif +#if CONFIG_IS_ENABLED(ROCKCHIP_EARLYRETURN_TO_BROM)
- adr r3, entry_counter
- ldr r0, [r3]
- cmp r0, #1 /* check if entry_counter == 1 */
- beq reset /* regular bootup */
- add r0, #1
- str r0, [r3] /* increment the entry_counter in memory */
- bx lr /* return to bootrom */
This seems not work on rk3188, When I track the code flow with DS-5, I found the entry_counter always be zero when we run here from bootrom(even it is set to 1 before return to bootrom), so it return to bootrom again and again.
+entry_counter:
- .word 0 #endif b reset #if !defined(CONFIG_ARM64)
@@ -32,7 +44,7 @@ * For armv7, the addr '_start' will used as vector start address * and write to VBAR register, which needs to aligned to 0x20. */
- .align(5)
- .align(5), 0x0 _start: ARM_VECTORS #endif
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig index 31e9864..d59a1d5 100644 --- a/arch/arm/mach-rockchip/Kconfig +++ b/arch/arm/mach-rockchip/Kconfig @@ -158,6 +158,34 @@ config ROCKCHIP_SPL_RESERVE_IRAM config ROCKCHIP_BROM_HELPER bool
+config SPL_ROCKCHIP_EARLYRETURN_TO_BROM
bool "SPL requires early-return (for RK3188-style BROM) to BROM"
- depends on SPL && ENABLE_ARM_SOC_BOOT0_HOOK
- help
Some Rockchip BROM variants (e.g. on the RK3188) load the
first stage in segments and enter multiple times. E.g. on
the RK3188, the first 1KB of the first stage are loaded
first and entered; after returning to the BROM, the
remainder of the first stage is loaded, but the BROM
re-enters at the same address/to the same code as previously.
This enables support code in the BOOT0 hook for the SPL stage
to allow multiple entries.
+config TPL_ROCKCHIP_EARLYRETURN_TO_BROM
bool "TPL requires early-return (for RK3188-style BROM) to BROM"
- depends on TPL && ENABLE_ARM_SOC_BOOT0_HOOK
- help
Some Rockchip BROM variants (e.g. on the RK3188) load the
first stage in segments and enter multiple times. E.g. on
the RK3188, the first 1KB of the first stage are loaded
first and entered; after returning to the BROM, the
remainder of the first stage is loaded, but the BROM
re-enters at the same address/to the same code as previously.
This enables support code in the BOOT0 hook for the TPL stage
to allow multiple entries.
- config SPL_MMC_SUPPORT default y if !SPL_ROCKCHIP_BACK_TO_BROM

Andy,
On 10 Oct 2017, at 11:01, Andy Yan andy.yan@rock-chips.com wrote:
Hi Philipp:
On 2017年10月07日 03:28, Philipp Tomsich wrote:
Some Rockchip BROM versions (e.g. the RK3188 and RK3066) first read 1KB data from NAND into SRAM and executes it. Then, following a return to bootrom, the BROM loads additional code to SRAM (not overwriting the first block read) and reenters at the same address as the first time.
To support booting either a TPL (on the RK3066) or SPL (on the RK3188) using this model of having to count entries, this commit adds code to the boot0 hook to track the number of entries and handle them accordingly.
Signed-off-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com Signed-off-by: Paweł Jarosz paweljarosz3691@gmail.com
Changes in v4: None Changes in v3: None Changes in v2: None
arch/arm/include/asm/arch-rockchip/boot0.h | 24 ++++++++++++++++++------ arch/arm/mach-rockchip/Kconfig | 28 ++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 6 deletions(-)
diff --git a/arch/arm/include/asm/arch-rockchip/boot0.h b/arch/arm/include/asm/arch-rockchip/boot0.h index f7c6146..06091d0 100644 --- a/arch/arm/include/asm/arch-rockchip/boot0.h +++ b/arch/arm/include/asm/arch-rockchip/boot0.h @@ -19,12 +19,24 @@ * beginning of the executable. However, as we want to keep * this generic and make it applicable to builds that are like * the RK3368 (TPL needs this, SPL doesn't) or the RK3399 (no
* TPL, but extra space needed in the SPL), we simply repeat
* the 'b reset' with the expectation that the first one will
* be overwritten, if this is the first stage contained in the
* final image created with mkimage)...
* TPL, but extra space needed in the SPL), we simply insert
* a branch-to-next-instruction-word with the expectation that
* the first one may be overwritten, if this is the first stage
*/* contained in the final image created with mkimage)...
- b reset /* may be overwritten --- should be 'nop' or a 'b reset' */
- b 1f /* if overwritten, entry-address is at the next word */
+1: +#endif +#if CONFIG_IS_ENABLED(ROCKCHIP_EARLYRETURN_TO_BROM)
- adr r3, entry_counter
- ldr r0, [r3]
- cmp r0, #1 /* check if entry_counter == 1 */
- beq reset /* regular bootup */
- add r0, #1
- str r0, [r3] /* increment the entry_counter in memory */
- bx lr /* return to bootrom */
This seems not work on rk3188, When I track the code flow with DS-5, I
found the entry_counter always be zero when we run here from bootrom(even it is set to 1 before return to bootrom), so it return to bootrom again and again.
I think I see a potential problem: do we need to return 0 (r0 = 0) to the bootrom? I.e. do we need to put a "mov r0, #0” before the "bx lr”?
Could you either try this out (or look at the BROM code)?
Thanks, Philipp.
+entry_counter:
- .word 0
#endif b reset #if !defined(CONFIG_ARM64) @@ -32,7 +44,7 @@ * For armv7, the addr '_start' will used as vector start address * and write to VBAR register, which needs to aligned to 0x20. */
- .align(5)
- .align(5), 0x0
_start: ARM_VECTORS #endif diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig index 31e9864..d59a1d5 100644 --- a/arch/arm/mach-rockchip/Kconfig +++ b/arch/arm/mach-rockchip/Kconfig @@ -158,6 +158,34 @@ config ROCKCHIP_SPL_RESERVE_IRAM config ROCKCHIP_BROM_HELPER bool +config SPL_ROCKCHIP_EARLYRETURN_TO_BROM
bool "SPL requires early-return (for RK3188-style BROM) to BROM"
- depends on SPL && ENABLE_ARM_SOC_BOOT0_HOOK
- help
Some Rockchip BROM variants (e.g. on the RK3188) load the
first stage in segments and enter multiple times. E.g. on
the RK3188, the first 1KB of the first stage are loaded
first and entered; after returning to the BROM, the
remainder of the first stage is loaded, but the BROM
re-enters at the same address/to the same code as previously.
This enables support code in the BOOT0 hook for the SPL stage
to allow multiple entries.
+config TPL_ROCKCHIP_EARLYRETURN_TO_BROM
bool "TPL requires early-return (for RK3188-style BROM) to BROM"
- depends on TPL && ENABLE_ARM_SOC_BOOT0_HOOK
- help
Some Rockchip BROM variants (e.g. on the RK3188) load the
first stage in segments and enter multiple times. E.g. on
the RK3188, the first 1KB of the first stage are loaded
first and entered; after returning to the BROM, the
remainder of the first stage is loaded, but the BROM
re-enters at the same address/to the same code as previously.
This enables support code in the BOOT0 hook for the TPL stage
to allow multiple entries.
config SPL_MMC_SUPPORT default y if !SPL_ROCKCHIP_BACK_TO_BROM

Hi:
On 2017年10月10日 17:01, Andy Yan wrote:
Hi Philipp:
On 2017年10月07日 03:28, Philipp Tomsich wrote:
Some Rockchip BROM versions (e.g. the RK3188 and RK3066) first read 1KB data from NAND into SRAM and executes it. Then, following a return to bootrom, the BROM loads additional code to SRAM (not overwriting the first block read) and reenters at the same address as the first time.
To support booting either a TPL (on the RK3066) or SPL (on the RK3188) using this model of having to count entries, this commit adds code to the boot0 hook to track the number of entries and handle them accordingly.
Signed-off-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com Signed-off-by: Paweł Jarosz paweljarosz3691@gmail.com
Changes in v4: None Changes in v3: None Changes in v2: None
arch/arm/include/asm/arch-rockchip/boot0.h | 24 ++++++++++++++++++------ arch/arm/mach-rockchip/Kconfig | 28 ++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 6 deletions(-)
diff --git a/arch/arm/include/asm/arch-rockchip/boot0.h b/arch/arm/include/asm/arch-rockchip/boot0.h index f7c6146..06091d0 100644 --- a/arch/arm/include/asm/arch-rockchip/boot0.h +++ b/arch/arm/include/asm/arch-rockchip/boot0.h @@ -19,12 +19,24 @@ * beginning of the executable. However, as we want to keep * this generic and make it applicable to builds that are like * the RK3368 (TPL needs this, SPL doesn't) or the RK3399 (no - * TPL, but extra space needed in the SPL), we simply repeat - * the 'b reset' with the expectation that the first one will - * be overwritten, if this is the first stage contained in the - * final image created with mkimage)... + * TPL, but extra space needed in the SPL), we simply insert + * a branch-to-next-instruction-word with the expectation that + * the first one may be overwritten, if this is the first stage + * contained in the final image created with mkimage)... */ - b reset /* may be overwritten --- should be 'nop' or a 'b reset' */ + b 1f /* if overwritten, entry-address is at the next word */ +1: +#endif +#if CONFIG_IS_ENABLED(ROCKCHIP_EARLYRETURN_TO_BROM) + adr r3, entry_counter + ldr r0, [r3] + cmp r0, #1 /* check if entry_counter == 1 */ + beq reset /* regular bootup */ + add r0, #1 + str r0, [r3] /* increment the entry_counter in memory */
It seems that we need to clear r0 to zero before return to bootrom, a non-zero return value will drive the system to bootrom download mode.
+ bx lr /* return to bootrom */
This seems not work on rk3188, When I track the code flow with DS-5, I found the entry_counter always be zero when we run here from bootrom(even it is set to 1 before return to bootrom), so it return to bootrom again and again.
+entry_counter: + .word 0 #endif b reset #if !defined(CONFIG_ARM64) @@ -32,7 +44,7 @@ * For armv7, the addr '_start' will used as vector start address * and write to VBAR register, which needs to aligned to 0x20. */ - .align(5) + .align(5), 0x0 _start: ARM_VECTORS #endif diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig index 31e9864..d59a1d5 100644 --- a/arch/arm/mach-rockchip/Kconfig +++ b/arch/arm/mach-rockchip/Kconfig @@ -158,6 +158,34 @@ config ROCKCHIP_SPL_RESERVE_IRAM config ROCKCHIP_BROM_HELPER bool +config SPL_ROCKCHIP_EARLYRETURN_TO_BROM + bool "SPL requires early-return (for RK3188-style BROM) to BROM" + depends on SPL && ENABLE_ARM_SOC_BOOT0_HOOK + help + Some Rockchip BROM variants (e.g. on the RK3188) load the + first stage in segments and enter multiple times. E.g. on + the RK3188, the first 1KB of the first stage are loaded + first and entered; after returning to the BROM, the + remainder of the first stage is loaded, but the BROM + re-enters at the same address/to the same code as previously.
+ This enables support code in the BOOT0 hook for the SPL stage + to allow multiple entries.
+config TPL_ROCKCHIP_EARLYRETURN_TO_BROM + bool "TPL requires early-return (for RK3188-style BROM) to BROM" + depends on TPL && ENABLE_ARM_SOC_BOOT0_HOOK + help + Some Rockchip BROM variants (e.g. on the RK3188) load the + first stage in segments and enter multiple times. E.g. on + the RK3188, the first 1KB of the first stage are loaded + first and entered; after returning to the BROM, the + remainder of the first stage is loaded, but the BROM + re-enters at the same address/to the same code as previously.
+ This enables support code in the BOOT0 hook for the TPL stage + to allow multiple entries.
config SPL_MMC_SUPPORT default y if !SPL_ROCKCHIP_BACK_TO_BROM

On 10 Oct 2017, at 11:22, Andy Yan andy.yan@rock-chips.com wrote:
Hi:
On 2017年10月10日 17:01, Andy Yan wrote:
Hi Philipp:
On 2017年10月07日 03:28, Philipp Tomsich wrote:
Some Rockchip BROM versions (e.g. the RK3188 and RK3066) first read 1KB data from NAND into SRAM and executes it. Then, following a return to bootrom, the BROM loads additional code to SRAM (not overwriting the first block read) and reenters at the same address as the first time.
To support booting either a TPL (on the RK3066) or SPL (on the RK3188) using this model of having to count entries, this commit adds code to the boot0 hook to track the number of entries and handle them accordingly.
Signed-off-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com Signed-off-by: Paweł Jarosz paweljarosz3691@gmail.com
Changes in v4: None Changes in v3: None Changes in v2: None
arch/arm/include/asm/arch-rockchip/boot0.h | 24 ++++++++++++++++++------ arch/arm/mach-rockchip/Kconfig | 28 ++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 6 deletions(-)
diff --git a/arch/arm/include/asm/arch-rockchip/boot0.h b/arch/arm/include/asm/arch-rockchip/boot0.h index f7c6146..06091d0 100644 --- a/arch/arm/include/asm/arch-rockchip/boot0.h +++ b/arch/arm/include/asm/arch-rockchip/boot0.h @@ -19,12 +19,24 @@ * beginning of the executable. However, as we want to keep * this generic and make it applicable to builds that are like * the RK3368 (TPL needs this, SPL doesn't) or the RK3399 (no
* TPL, but extra space needed in the SPL), we simply repeat
* the 'b reset' with the expectation that the first one will
* be overwritten, if this is the first stage contained in the
* final image created with mkimage)...
* TPL, but extra space needed in the SPL), we simply insert
* a branch-to-next-instruction-word with the expectation that
* the first one may be overwritten, if this is the first stage
* contained in the final image created with mkimage)... */
- b reset /* may be overwritten --- should be 'nop' or a 'b reset' */
- b 1f /* if overwritten, entry-address is at the next word */
+1: +#endif +#if CONFIG_IS_ENABLED(ROCKCHIP_EARLYRETURN_TO_BROM)
- adr r3, entry_counter
- ldr r0, [r3]
- cmp r0, #1 /* check if entry_counter == 1 */
- beq reset /* regular bootup */
- add r0, #1
- str r0, [r3] /* increment the entry_counter in memory */
It seems that we need to clear r0 to zero before return to bootrom, a non-zero return value will drive the system to bootrom download mode.
Did you test if clearing the r0-register before returning fixes this and we boot through into SPL? If so, I’ll create a v5 of the patch … if not, we will need to dig deeper to determine why this does not work as expected.
- bx lr /* return to bootrom */
This seems not work on rk3188, When I track the code flow with DS-5, I
found the entry_counter always be zero when we run here from bootrom(even it is set to 1 before return to bootrom), so it return to bootrom again and again.
+entry_counter:
- .word 0 #endif b reset #if !defined(CONFIG_ARM64)
@@ -32,7 +44,7 @@ * For armv7, the addr '_start' will used as vector start address * and write to VBAR register, which needs to aligned to 0x20. */
- .align(5)
- .align(5), 0x0 _start: ARM_VECTORS #endif
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig index 31e9864..d59a1d5 100644 --- a/arch/arm/mach-rockchip/Kconfig +++ b/arch/arm/mach-rockchip/Kconfig @@ -158,6 +158,34 @@ config ROCKCHIP_SPL_RESERVE_IRAM config ROCKCHIP_BROM_HELPER bool +config SPL_ROCKCHIP_EARLYRETURN_TO_BROM
bool "SPL requires early-return (for RK3188-style BROM) to BROM"
- depends on SPL && ENABLE_ARM_SOC_BOOT0_HOOK
- help
Some Rockchip BROM variants (e.g. on the RK3188) load the
first stage in segments and enter multiple times. E.g. on
the RK3188, the first 1KB of the first stage are loaded
first and entered; after returning to the BROM, the
remainder of the first stage is loaded, but the BROM
re-enters at the same address/to the same code as previously.
This enables support code in the BOOT0 hook for the SPL stage
to allow multiple entries.
+config TPL_ROCKCHIP_EARLYRETURN_TO_BROM
bool "TPL requires early-return (for RK3188-style BROM) to BROM"
- depends on TPL && ENABLE_ARM_SOC_BOOT0_HOOK
- help
Some Rockchip BROM variants (e.g. on the RK3188) load the
first stage in segments and enter multiple times. E.g. on
the RK3188, the first 1KB of the first stage are loaded
first and entered; after returning to the BROM, the
remainder of the first stage is loaded, but the BROM
re-enters at the same address/to the same code as previously.
This enables support code in the BOOT0 hook for the TPL stage
to allow multiple entries.
- config SPL_MMC_SUPPORT default y if !SPL_ROCKCHIP_BACK_TO_BROM

Hi Philipp:
On 2017年10月10日 18:50, Dr. Philipp Tomsich wrote:
On 10 Oct 2017, at 11:22, Andy Yan <andy.yan@rock-chips.com mailto:andy.yan@rock-chips.com> wrote:
Hi:
On 2017年10月10日 17:01, Andy Yan wrote:
Hi Philipp:
On 2017年10月07日 03:28, Philipp Tomsich wrote:
Some Rockchip BROM versions (e.g. the RK3188 and RK3066) first read 1KB data from NAND into SRAM and executes it. Then, following a return to bootrom, the BROM loads additional code to SRAM (not overwriting the first block read) and reenters at the same address as the first time.
To support booting either a TPL (on the RK3066) or SPL (on the RK3188) using this model of having to count entries, this commit adds code to the boot0 hook to track the number of entries and handle them accordingly.
Signed-off-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com mailto:philipp.tomsich@theobroma-systems.com> Signed-off-by: Paweł Jarosz <paweljarosz3691@gmail.com
mailto:paweljarosz3691@gmail.com>
Changes in v4: None Changes in v3: None Changes in v2: None
arch/arm/include/asm/arch-rockchip/boot0.h | 24 ++++++++++++++++++------ arch/arm/mach-rockchip/Kconfig | 28 ++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 6 deletions(-)
diff --git a/arch/arm/include/asm/arch-rockchip/boot0.h b/arch/arm/include/asm/arch-rockchip/boot0.h index f7c6146..06091d0 100644 --- a/arch/arm/include/asm/arch-rockchip/boot0.h +++ b/arch/arm/include/asm/arch-rockchip/boot0.h @@ -19,12 +19,24 @@
- beginning of the executable. However, as we want to keep
- this generic and make it applicable to builds that are like
- the RK3368 (TPL needs this, SPL doesn't) or the RK3399 (no
- * TPL, but extra space needed in the SPL), we simply repeat - * the 'b reset' with the expectation that the first one will - * be overwritten, if this is the first stage contained in the - * final image created with mkimage)... + * TPL, but extra space needed in the SPL), we simply insert + * a branch-to-next-instruction-word with the expectation that + * the first one may be overwritten, if this is the first stage + * contained in the final image created with mkimage)... */ - b reset /* may be overwritten --- should be 'nop' or a 'b reset' */ + b 1f /* if overwritten, entry-address is at the next word */ +1: +#endif +#if CONFIG_IS_ENABLED(ROCKCHIP_EARLYRETURN_TO_BROM) + adr r3, entry_counter + ldr r0, [r3] + cmp r0, #1 /* check if entry_counter == 1 */ + beq reset /* regular bootup */ + add r0, #1 + str r0, [r3] /* increment the entry_counter in memory */
It seems that we need to clear r0 to zero before return to bootrom, a non-zero return value will drive the system to bootrom download mode.
Did you test if clearing the r0-register before returning fixes this and we boot through into SPL? If so, I’ll create a v5 of the patch … if not, we will need to dig deeper to determine why this does not work as expected.
Yes, we can boot into uboot shell if clear r0 before return to bootrom from here.
+ bx lr /* return to bootrom */
This seems not work on rk3188, When I track the code flow with DS-5, I found the entry_counter always be zero when we run here from bootrom(even it is set to 1 before return to bootrom), so it return to bootrom again and again.
+entry_counter: + .word 0 #endif b reset #if !defined(CONFIG_ARM64) @@ -32,7 +44,7 @@
- For armv7, the addr '_start' will used as vector start address
- and write to VBAR register, which needs to aligned to 0x20.
*/ - .align(5) + .align(5), 0x0 _start: ARM_VECTORS #endif diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig index 31e9864..d59a1d5 100644 --- a/arch/arm/mach-rockchip/Kconfig +++ b/arch/arm/mach-rockchip/Kconfig @@ -158,6 +158,34 @@ config ROCKCHIP_SPL_RESERVE_IRAM config ROCKCHIP_BROM_HELPER bool +config SPL_ROCKCHIP_EARLYRETURN_TO_BROM + bool "SPL requires early-return (for RK3188-style BROM) to BROM" + depends on SPL && ENABLE_ARM_SOC_BOOT0_HOOK + help + Some Rockchip BROM variants (e.g. on the RK3188) load the + first stage in segments and enter multiple times. E.g. on + the RK3188, the first 1KB of the first stage are loaded + first and entered; after returning to the BROM, the + remainder of the first stage is loaded, but the BROM + re-enters at the same address/to the same code as previously.
+ This enables support code in the BOOT0 hook for the SPL stage + to allow multiple entries.
+config TPL_ROCKCHIP_EARLYRETURN_TO_BROM + bool "TPL requires early-return (for RK3188-style BROM) to BROM" + depends on TPL && ENABLE_ARM_SOC_BOOT0_HOOK + help + Some Rockchip BROM variants (e.g. on the RK3188) load the + first stage in segments and enter multiple times. E.g. on + the RK3188, the first 1KB of the first stage are loaded + first and entered; after returning to the BROM, the + remainder of the first stage is loaded, but the BROM + re-enters at the same address/to the same code as previously.
+ This enables support code in the BOOT0 hook for the TPL stage + to allow multiple entries.
config SPL_MMC_SUPPORT default y if !SPL_ROCKCHIP_BACK_TO_BROM

The save_boot_params_ret() prototype (for those of us, that have a valid SP on entry and can implement save_boot_params() in C), was previously only defined for !defined(CONFIG_ARM64).
This moves the declaration to a common block to ensure the prototype is available to everyone that might need it.
Signed-off-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com Tested-by: Andy Yan andy.yan@rock-chips.com ---
Changes in v4: None Changes in v3: None Changes in v2: None
arch/arm/include/asm/system.h | 62 +++++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 31 deletions(-)
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index 79bd19a..e2af296 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h @@ -332,37 +332,6 @@ void psci_arch_init(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); - */ - -/** - * save_boot_params_ret() - Return from save_boot_params() - * - * If you provide save_boot_params(), then you should jump back to this - * function when done. Try to preserve all registers. - * - * If your implementation of save_boot_params() is in C then it is acceptable - * to simply call save_boot_params_ret() at the end of your function. Since - * there is no link register set up, you cannot just exit the function. U-Boot - * will return to the (initialised) value of lr, and likely crash/hang. - * - * If your implementation of save_boot_params() is in assembler then you - * should use 'b' or 'bx' to return to save_boot_params_ret. - */ -void save_boot_params_ret(void); - #ifdef CONFIG_ARMV7_LPAE void switch_to_hypervisor_ret(void); #endif @@ -556,6 +525,37 @@ void mmu_page_table_flush(unsigned long start, unsigned long stop);
#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); + */ + +/** + * save_boot_params_ret() - Return from save_boot_params() + * + * If you provide save_boot_params(), then you should jump back to this + * function when done. Try to preserve all registers. + * + * If your implementation of save_boot_params() is in C then it is acceptable + * to simply call save_boot_params_ret() at the end of your function. Since + * there is no link register set up, you cannot just exit the function. U-Boot + * will return to the (initialised) value of lr, and likely crash/hang. + * + * If your implementation of save_boot_params() is in assembler then you + * should use 'b' or 'bx' to return to save_boot_params_ret. + */ +void save_boot_params_ret(void); + +/** * Change the cache settings for a region. * * \param start start address of memory region to change

As no '.type' was set for save_boot_params_ret in start.S, binutils did not track whether it was emitted as A32 or T32. By properly marking save_boot_params_ret as a potential function entry, we can make sure that the compiler will insert the appropriate instructions for branching to save_boot_params_ret both for call-sites emitted as A32 and T32.
Reported-by: Andy Yan andy.yan@rock-chips.com Signed-off-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com Tested-by: Andy Yan andy.yan@rock-chips.com
---
Changes in v4: None Changes in v3: - tracked the root-cause why no interwork branch was emitted and fixed it using a '.type'-directive in start.S to mark save_boot_params_ret as a (possible) function-entry.
Changes in v2: None
arch/arm/cpu/armv7/start.S | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S index 7b84a7a..95a0b52 100644 --- a/arch/arm/cpu/armv7/start.S +++ b/arch/arm/cpu/armv7/start.S @@ -31,6 +31,7 @@
.globl reset .globl save_boot_params_ret + .type save_boot_params_ret,%function #ifdef CONFIG_ARMV7_LPAE .global switch_to_hypervisor_ret #endif

The previous setjmp-implementation (as a static inline function that contained an 'asm volatile' sequence) was extremely fragile: (some versions of) GCC optimised the set of registers. One critical example was the removal of 'r9' from the clobber list, if -ffixed-reg9 was supplied.
To increase robustness and ensure PCS-compliant behaviour, the setjmp and longjmp implementation are now in assembly and closely match what one would expect to find in a libc implementation.
Signed-off-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com Tested-by: Andy Yan andy.yan@rock-chips.com
---
Changes in v4: None Changes in v3: - converted setjmp/longjmp from inline-assembly to separate .S files to improve predicatability if emitted code
Changes in v2: None
arch/arm/include/asm/setjmp.h | 94 ++++++------------------------------------- arch/arm/lib/Makefile | 6 +++ arch/arm/lib/setjmp.S | 37 +++++++++++++++++ arch/arm/lib/setjmp_aarch64.S | 42 +++++++++++++++++++ 4 files changed, 98 insertions(+), 81 deletions(-) create mode 100644 arch/arm/lib/setjmp.S create mode 100644 arch/arm/lib/setjmp_aarch64.S
diff --git a/arch/arm/include/asm/setjmp.h b/arch/arm/include/asm/setjmp.h index c3399a7..517beeb 100644 --- a/arch/arm/include/asm/setjmp.h +++ b/arch/arm/include/asm/setjmp.h @@ -1,6 +1,6 @@ /* - * (C) Copyright 2016 - * Alexander Graf agraf@suse.de + * (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH + * (C) Copyright 2016 Alexander Graf agraf@suse.de * * SPDX-License-Identifier: GPL-2.0+ */ @@ -8,89 +8,21 @@ #ifndef _SETJMP_H_ #define _SETJMP_H_ 1
+/* + * This really should be opaque, but the EFI implementation wrongly + * assumes that a 'struct jmp_buf_data' is defined. + */ struct jmp_buf_data { - ulong target; - ulong regs[5]; - int ret; -}; - -typedef struct jmp_buf_data jmp_buf[1]; - -static inline int setjmp(jmp_buf jmp) -{ - jmp->ret = 0; - -#ifdef CONFIG_ARM64 - asm volatile( - "adr x1, jmp_target\n" - "str x1, %0\n" - "stp x26, x27, %1\n" - "stp x28, x29, %2\n" - "mov x1, sp\n" - "str x1, %3\n" - "jmp_target: " - : "=m" (jmp->target), "=m" (jmp->regs[0]), - "=m" (jmp->regs[2]), "=m" (jmp->regs[4]) - : - : "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", - "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", - "x16", "x17", "x18", "x19", "x20", "x21", "x22", - "x23", "x24", "x25", /* x26, x27, x28, x29, sp */ - "x30", "cc", "memory"); -#else - asm volatile( -#if CONFIG_IS_ENABLED(SYS_THUMB_BUILD) - ".align 2\n" - "adr r0, jmp_target\n" - "add r0, r0, $1\n" +#if defined(__aarch64__) + u64 regs[13]; #else - "adr r0, jmp_target\n" -#endif - "mov r1, %0\n" - "mov r2, sp\n" - "stm r1!, {r0, r2, r4, r5, r6, r7}\n" - ".align 2\n" - "jmp_target: \n" - : - : "l" (&jmp->target) - : "r0", "r1", "r2", "r3", /* "r4", "r5", "r6", "r7", */ - "r8", "r9", "r10", "r11", /* sp, */ "ip", "lr", - "cc", "memory"); -#endif - - return jmp->ret; -} - -static inline __noreturn void longjmp(jmp_buf jmp, int ret) -{ - jmp->ret = ret; - -#ifdef CONFIG_ARM64 - asm volatile( - "ldr x0, %0\n" - "ldr x1, %3\n" - "mov sp, x1\n" - "ldp x26, x27, %1\n" - "ldp x28, x25, %2\n" - "mov x29, x25\n" - "br x0\n" - : - : "m" (jmp->target), "m" (jmp->regs[0]), "m" (jmp->regs[2]), - "m" (jmp->regs[4]) - : "x0", "x1", "x25", "x26", "x27", "x28"); -#else - asm volatile( - "mov r1, %0\n" - "ldm r1!, {r0, r2, r4, r5, r6, r7}\n" - "mov sp, r2\n" - "bx r0\n" - : - : "l" (&jmp->target) - : "r1"); + u32 regs[10]; /* r4-r9, sl, fp, sp, lr */ #endif +};
- while (1) { } -} +typedef struct jmp_buf_data jmp_buf[1];
+int setjmp(jmp_buf jmp); +void longjmp(jmp_buf jmp, int ret);
#endif /* _SETJMP_H_ */ diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index 6e1c436..abffa10 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -17,6 +17,12 @@ else obj-y += vectors.o crt0.o endif
+ifdef CONFIG_ARM64 +obj-y += setjmp_aarch64.o +else +obj-y += setjmp.o +endif + ifndef CONFIG_SPL_BUILD ifdef CONFIG_ARM64 obj-y += relocate_64.o diff --git a/arch/arm/lib/setjmp.S b/arch/arm/lib/setjmp.S new file mode 100644 index 0000000..6746e5e --- /dev/null +++ b/arch/arm/lib/setjmp.S @@ -0,0 +1,37 @@ +/* + * (C) 2017 Theobroma Systems Design und Consulting GmbH + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <config.h> +#include <asm/assembler.h> +#include <linux/linkage.h> + +.pushsection .text.setjmp, "ax" +ENTRY(setjmp) + /* + * A subroutine must preserve the contents of the registers + * r4-r8, r10, r11 (v1-v5, v7 and v8) and SP (and r9 in PCS + * variants that designate r9 as v6). + */ + mov ip, sp + stm a1, {v1-v8, ip, lr} + mov a1, #0 + bx lr +ENDPROC(setjmp) +.popsection + +.pushsection .text.longjmp, "ax" +ENTRY(longjmp) + ldm a1, {v1-v8, ip, lr} + mov sp, ip + mov a1, a2 + /* If we were passed a return value of zero, return one instead */ + cmp a1, #0 + bne 1f + mov a1, #1 +1: + bx lr +ENDPROC(longjmp) +.popsection diff --git a/arch/arm/lib/setjmp_aarch64.S b/arch/arm/lib/setjmp_aarch64.S new file mode 100644 index 0000000..b68edb8 --- /dev/null +++ b/arch/arm/lib/setjmp_aarch64.S @@ -0,0 +1,42 @@ +/* + * (C) 2017 Theobroma Systems Design und Consulting GmbH + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <config.h> +#include <asm/macro.h> +#include <linux/linkage.h> + +.pushsection .text.setjmp, "ax" +ENTRY(setjmp) + /* Preserve all callee-saved registers and the SP */ + stp x19, x20, [x0,#0] + stp x21, x22, [x0,#16] + stp x23, x24, [x0,#32] + stp x25, x26, [x0,#48] + stp x27, x28, [x0,#64] + stp x29, x30, [x0,#80] + mov x2, sp + str x2, [x0, #96] + mov x0, #0 + ret +ENDPROC(setjmp) +.popsection + +.pushsection .text.longjmp, "ax" +ENTRY(longjmp) + ldp x19, x20, [x0,#0] + ldp x21, x22, [x0,#16] + ldp x23, x24, [x0,#32] + ldp x25, x26, [x0,#48] + ldp x27, x28, [x0,#64] + ldp x29, x30, [x0,#80] + ldr x2, [x0,#96] + mov sp, x2 + /* Move the return value in place, but return 1 if passed 0. */ + adds x0, xzr, x1 + csinc x0, x0, xzr, ne + ret +ENDPROC(longjmp) +.popsection

The back-to-bootrom implementation for Rockchip has always relied on the stack-pointer being valid on entry, so there was little reason to have this as an assembly implementation.
This provides a new C-only implementation of save_boot_params and back_to_bootrom (relying on setjmp/longjmp) and removes the older assembly-only implementation.
Signed-off-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com Tested-by: Andy Yan andy.yan@rock-chips.com ---
Changes in v4: None Changes in v3: None Changes in v2: None
arch/arm/include/asm/arch-rockchip/bootrom.h | 27 ++++++++--- arch/arm/mach-rockchip/Makefile | 4 +- arch/arm/mach-rockchip/bootrom.c | 52 ++++++++++++++++++++- arch/arm/mach-rockchip/save_boot_param.S | 69 ---------------------------- 4 files changed, 73 insertions(+), 79 deletions(-) delete mode 100644 arch/arm/mach-rockchip/save_boot_param.S
diff --git a/arch/arm/include/asm/arch-rockchip/bootrom.h b/arch/arm/include/asm/arch-rockchip/bootrom.h index 169cc5e..2f61a33 100644 --- a/arch/arm/include/asm/arch-rockchip/bootrom.h +++ b/arch/arm/include/asm/arch-rockchip/bootrom.h @@ -1,5 +1,6 @@ /* * (C) Copyright 2017 Heiko Stuebner heiko@sntech.de + * (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH * * SPDX-License-Identifier: GPL-2.0 */ @@ -14,15 +15,27 @@ extern u32 SAVE_SP_ADDR;
/** - * Hand control back to the bootrom to load another - * boot stage. + * back_to_bootrom() - return to bootrom (for TPL/SPL), passing a + * result code + * + * Transfer control back to the Rockchip BROM, restoring necessary + * register context and passing a command/result code to the BROM + * to instruct its next actions (e.g. continue boot sequence, enter + * download mode, ...). + * + * This function does not return. */ -void back_to_bootrom(void); +enum rockchip_bootrom_cmd { + /* + * These can not start at 0, as 0 has a special meaning + * for setjmp(). + */
-/** - * Assembler component for the above (do not call this directly) - */ -void _back_to_bootrom_s(void); + BROM_BOOT_NEXTSTAGE = 1, /* continue boot-sequence */ + BROM_BOOT_ENTER_DNL, /* have BROM enter download-mode */ +}; + +void back_to_bootrom(void);
/** * Boot-device identifiers as used by the BROM diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile index daafc8d..b875dfc 100644 --- a/arch/arm/mach-rockchip/Makefile +++ b/arch/arm/mach-rockchip/Makefile @@ -8,8 +8,8 @@ # this may have entered from ATF with the stack-pointer pointing to # inaccessible/protected memory (and the bootrom-helper assumes that # the stack-pointer is valid before switching to the U-Boot stack). -obj-spl-$(CONFIG_ROCKCHIP_BROM_HELPER) += bootrom.o save_boot_param.o -obj-tpl-$(CONFIG_ROCKCHIP_BROM_HELPER) += bootrom.o save_boot_param.o +obj-spl-$(CONFIG_ROCKCHIP_BROM_HELPER) += bootrom.o +obj-tpl-$(CONFIG_ROCKCHIP_BROM_HELPER) += bootrom.o
obj-tpl-$(CONFIG_ROCKCHIP_RK3188) += rk3188-board-tpl.o obj-tpl-$(CONFIG_ROCKCHIP_RK3288) += rk3288-board-tpl.o diff --git a/arch/arm/mach-rockchip/bootrom.c b/arch/arm/mach-rockchip/bootrom.c index 8380e4e..7b9b307 100644 --- a/arch/arm/mach-rockchip/bootrom.c +++ b/arch/arm/mach-rockchip/bootrom.c @@ -6,11 +6,61 @@
#include <common.h> #include <asm/arch/bootrom.h> +#include <asm/setjmp.h> +#include <asm/system.h> + +/* + * Force the jmp_buf to the data-section, as .bss will not be valid + * when save_boot_params is invoked. + */ +static jmp_buf brom_ctx __section(".data");
void back_to_bootrom(void) { #if CONFIG_IS_ENABLED(LIBCOMMON_SUPPORT) puts("Returning to boot ROM...\n"); #endif - _back_to_bootrom_s(); + longjmp(brom_ctx, BROM_BOOT_NEXTSTAGE); +} + +/* + * All Rockchip BROM implementations enter with a valid stack-pointer, + * so this can safely be implemented in C (providing a single + * implementation both for ARMv7 and AArch64). + */ +int save_boot_params(void) +{ + int ret = setjmp(brom_ctx); + + switch (ret) { + case 0: + /* + * This is the initial pass through this function + * (i.e. saving the context), setjmp just setup up the + * brom_ctx: transfer back into the startup-code at + * 'save_boot_params_ret' and let the compiler know + * that this will not return. + */ + save_boot_params_ret(); + while (true) + /* does not return */; + break; + + case BROM_BOOT_NEXTSTAGE: + /* + * To instruct the BROM to boot the next stage, we + * need to return 0 to it: i.e. we need to rewrite + * the return code once more. + */ + ret = 0; + break; + + default: +#if CONFIG_IS_ENABLED(LIBCOMMON_SUPPORT) + puts("FATAL: unexpected command to back_to_bootrom()\n"); +#endif + hang(); + }; + + return ret; } diff --git a/arch/arm/mach-rockchip/save_boot_param.S b/arch/arm/mach-rockchip/save_boot_param.S deleted file mode 100644 index 50fce20..0000000 --- a/arch/arm/mach-rockchip/save_boot_param.S +++ /dev/null @@ -1,69 +0,0 @@ -/* - * (C) Copyright 2016 Rockchip Electronics Co., Ltd - * (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <linux/linkage.h> - -#if defined(CONFIG_ARM64) -.globl SAVE_SP_ADDR -SAVE_SP_ADDR: - .quad 0 - -ENTRY(save_boot_params) - sub sp, sp, #0x60 - stp x29, x30, [sp, #0x50] - stp x27, x28, [sp, #0x40] - stp x25, x26, [sp, #0x30] - stp x23, x24, [sp, #0x20] - stp x21, x22, [sp, #0x10] - stp x19, x20, [sp, #0] - ldr x8, =SAVE_SP_ADDR - mov x9, sp - str x9, [x8] - b save_boot_params_ret /* back to my caller */ -ENDPROC(save_boot_params) - -.globl _back_to_bootrom_s -ENTRY(_back_to_bootrom_s) - ldr x0, =SAVE_SP_ADDR - ldr x0, [x0] - mov sp, x0 - ldp x29, x30, [sp, #0x50] - ldp x27, x28, [sp, #0x40] - ldp x25, x26, [sp, #0x30] - ldp x23, x24, [sp, #0x20] - ldp x21, x22, [sp, #0x10] - ldp x19, x20, [sp] - add sp, sp, #0x60 - mov x0, xzr - ret -ENDPROC(_back_to_bootrom_s) -#else -.globl SAVE_SP_ADDR -SAVE_SP_ADDR: - .word 0 - -/* - * void save_boot_params - * - * Save sp, lr, r1~r12 - */ -ENTRY(save_boot_params) - push {r1-r12, lr} - ldr r0, =SAVE_SP_ADDR - str sp, [r0] - b save_boot_params_ret @ back to my caller -ENDPROC(save_boot_params) - - -.globl _back_to_bootrom_s -ENTRY(_back_to_bootrom_s) - ldr r0, =SAVE_SP_ADDR - ldr sp, [r0] - mov r0, #0 - pop {r1-r12, pc} -ENDPROC(_back_to_bootrom_s) -#endif

For the RK3188, the BROM will attempt to load up the first stage image (SPL for the RK3188) in two steps: first 1KB to offset 0x800 in the SRAM and then the remainder to offset 0xc00 in the SRAM. It always enters at 0x804, though.
With this changeset, the RK3188 boot removes the TPL (stub) stage and builds a single SPL binary that utilizes the early back-to-bootrom via the boot0-hook.
Consequently, the passing of the saved boot params via pmu->os_reg[2] is also removed.
Signed-off-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com ---
Changes in v4: - after merging the 'back-to-bootrom' series with the 'boot0-hook' series, this drops the TPL stub and builds only a single SPL image that uses the 'early back-to-bootrom' logic originally implemented by Pawel for the RK3066. - changes the SPL_STACK_BASE to +0x800 (from +0x804), as the boot0 hook already reserves the space for the SPL magic (previously inserted by mkimage)
Changes in v3: None Changes in v2: - [added in v2] chain back_to_bootrom calls for SPL, first returning to the TPL (using the same mechanism) and the to the BROM from the TPL
arch/arm/mach-rockchip/Kconfig | 2 +- arch/arm/mach-rockchip/Makefile | 1 - arch/arm/mach-rockchip/rk3188-board-spl.c | 10 ---- arch/arm/mach-rockchip/rk3188-board-tpl.c | 86 ------------------------------- doc/README.rockchip | 10 ++-- include/configs/rk3188_common.h | 12 ++--- 6 files changed, 9 insertions(+), 112 deletions(-) delete mode 100644 arch/arm/mach-rockchip/rk3188-board-tpl.c
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig index d59a1d5..09f2c45 100644 --- a/arch/arm/mach-rockchip/Kconfig +++ b/arch/arm/mach-rockchip/Kconfig @@ -18,7 +18,7 @@ config ROCKCHIP_RK3188 select SUPPORT_SPL select SUPPORT_TPL select SPL - select TPL + select SPL_ROCKCHIP_EARLYRETURN_TO_BROM select BOARD_LATE_INIT select ROCKCHIP_BROM_HELPER help diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile index b875dfc..c15e9bf 100644 --- a/arch/arm/mach-rockchip/Makefile +++ b/arch/arm/mach-rockchip/Makefile @@ -11,7 +11,6 @@ obj-spl-$(CONFIG_ROCKCHIP_BROM_HELPER) += bootrom.o obj-tpl-$(CONFIG_ROCKCHIP_BROM_HELPER) += bootrom.o
-obj-tpl-$(CONFIG_ROCKCHIP_RK3188) += rk3188-board-tpl.o obj-tpl-$(CONFIG_ROCKCHIP_RK3288) += rk3288-board-tpl.o obj-tpl-$(CONFIG_ROCKCHIP_RK3368) += rk3368-board-tpl.o
diff --git a/arch/arm/mach-rockchip/rk3188-board-spl.c b/arch/arm/mach-rockchip/rk3188-board-spl.c index 406207e..05d4ae6 100644 --- a/arch/arm/mach-rockchip/rk3188-board-spl.c +++ b/arch/arm/mach-rockchip/rk3188-board-spl.c @@ -101,7 +101,6 @@ static int setup_arm_clock(void) void board_init_f(ulong dummy) { struct udevice *pinctrl, *dev; - struct rk3188_pmu *pmu; int ret;
/* Example code showing how to enable the debug UART on RK3188 */ @@ -145,15 +144,6 @@ void board_init_f(ulong dummy) return; }
- /* - * Recover the bootrom's stackpointer. - * For whatever reason needs to run after rockchip_get_clk. - */ - pmu = syscon_get_first_range(ROCKCHIP_SYSCON_PMU); - if (IS_ERR(pmu)) - pr_err("pmu syscon returned %ld\n", PTR_ERR(pmu)); - SAVE_SP_ADDR = readl(&pmu->sys_reg[2]); - ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl); if (ret) { debug("Pinctrl init failed: %d\n", ret); diff --git a/arch/arm/mach-rockchip/rk3188-board-tpl.c b/arch/arm/mach-rockchip/rk3188-board-tpl.c deleted file mode 100644 index b458ef6..0000000 --- a/arch/arm/mach-rockchip/rk3188-board-tpl.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * (C) Copyright 2015 Google, Inc - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <debug_uart.h> -#include <spl.h> -#include <asm/io.h> -#include <asm/arch/bootrom.h> -#include <asm/arch/pmu_rk3188.h> - -DECLARE_GLOBAL_DATA_PTR; - -/* track how often we were entered */ -static int rk3188_num_entries __attribute__ ((section(".data"))); - -#define PMU_BASE 0x20004000 -#define SPL_ENTRY 0x10080C00 - -static void jump_to_spl(void) -{ - typedef void __noreturn (*image_entry_noargs_t)(void); - - struct rk3188_pmu * const pmu = (void *)PMU_BASE; - image_entry_noargs_t tpl_entry = - (image_entry_noargs_t)(unsigned long)SPL_ENTRY; - - /* Store the SAVE_SP_ADDR in a location shared with SPL. */ - writel(SAVE_SP_ADDR, &pmu->sys_reg[2]); - tpl_entry(); -} - -void board_init_f(ulong dummy) -{ - /* Example code showing how to enable the debug UART on RK3188 */ -#ifdef EARLY_UART -#include <asm/arch/grf_rk3188.h> - /* Enable early UART on the RK3188 */ -#define GRF_BASE 0x20008000 - struct rk3188_grf * const grf = (void *)GRF_BASE; - - rk_clrsetreg(&grf->gpio1b_iomux, - GPIO1B1_MASK << GPIO1B1_SHIFT | - GPIO1B0_MASK << GPIO1B0_SHIFT, - GPIO1B1_UART2_SOUT << GPIO1B1_SHIFT | - GPIO1B0_UART2_SIN << GPIO1B0_SHIFT); - /* - * Debug UART can be used from here if required: - * - * debug_uart_init(); - * printch('a'); - * printhex8(0x1234); - * printascii("string"); - */ - debug_uart_init(); - - printch('t'); - printch('p'); - printch('l'); - printch('-'); - printch(rk3188_num_entries + 1 + '0'); - printch('\n'); -#endif - - rk3188_num_entries++; - - if (rk3188_num_entries == 1) { - /* - * The original loader did some very basic integrity - * checking at this point, but the remaining few bytes - * could be used for any improvement making sense - * really early on. - */ - - back_to_bootrom(); - } else { - /* - * TPL part of the loader should now wait for us - * at offset 0xC00 in the sram. Should never return - * from there. - */ - jump_to_spl(); - } -} diff --git a/doc/README.rockchip b/doc/README.rockchip index 4b7be0b..57f551b 100644 --- a/doc/README.rockchip +++ b/doc/README.rockchip @@ -176,17 +176,17 @@ described above, but the image creation needs a bit more care.
The bootrom of rk3188 expects to find a small 1kb loader which returns control to the bootrom, after which it will load the real loader, which -can then be up to 29kb in size and does the regular ddr init. +can then be up to 29kb in size and does the regular ddr init. This is +handled by a single image (built as the SPL stage) that tests whether +it is handled for the first or second time via code executed from the +boot0-hook.
Additionally the rk3188 requires everything the bootrom loads to be rc4-encrypted. Except for the very first stage the bootrom always reads and decodes 2kb pages, so files should be sized accordingly.
# copy tpl, pad to 1020 bytes and append spl -cat tpl/u-boot-tpl.bin > tplspl.bin -truncate -s 1020 tplspl.bin -cat spl/u-boot-spl.bin >> tplspl.bin -tools/mkimage -n rk3188 -T rksd -d tplspl.bin out +tools/mkimage -n rk3188 -T rksd -d spl/u-boot-spl.bin out
# truncate, encode and append u-boot.bin truncate -s %2048 u-boot.bin diff --git a/include/configs/rk3188_common.h b/include/configs/rk3188_common.h index 5e46234..9824a10 100644 --- a/include/configs/rk3188_common.h +++ b/include/configs/rk3188_common.h @@ -37,14 +37,9 @@ #define CONFIG_ROCKCHIP_MAX_INIT_SIZE (0x8000 - 0x800) #define CONFIG_ROCKCHIP_CHIP_TAG "RK31"
-#ifdef CONFIG_TPL_BUILD -#define CONFIG_SPL_TEXT_BASE 0x10080804 -/* tpl size 1kb - 4byte RK31 header */ -#define CONFIG_SPL_MAX_SIZE (0x400 - 0x4) -#elif defined(CONFIG_SPL_BUILD) -/* spl size 32kb sram - 2kb bootrom - 1kb spl */ -#define CONFIG_SPL_MAX_SIZE (0x8000 - 0xC00) -#define CONFIG_SPL_TEXT_BASE 0x10080C00 +#define CONFIG_SPL_TEXT_BASE 0x10080800 +/* spl size 32kb sram - 2kb bootrom */ +#define CONFIG_SPL_MAX_SIZE (0x8000 - 0x800) #define CONFIG_SPL_FRAMEWORK 1 #define CONFIG_SPL_CLK 1 #define CONFIG_SPL_PINCTRL 1 @@ -53,7 +48,6 @@ #define CONFIG_SPL_RAM 1 #define CONFIG_SPL_DRIVERS_MISC_SUPPORT 1 #define CONFIG_ROCKCHIP_SERIAL 1 -#endif
#define CONFIG_SPL_STACK 0x10087fff

The BROM supports forcing it to enter download-mode, if an appropriate result/cmd-word is returned to it. There already is a series to support this in review, so this prepares the (newly C-version) of the back-to-bootrom code to accept a cmd to passed on to the BROM.
All the existing call-sites are adjusted to match the changed function signature.
Signed-off-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com Tested-by: Andy Yan andy.yan@rock-chips.com
---
Changes in v4: - no longer updates rk3188-board-tpl.c (as we have just removed it in an earlier commit)
Changes in v3: None Changes in v2: - also covers the RK3188 (which I had originally missed)
arch/arm/include/asm/arch-rockchip/bootrom.h | 5 ++++- arch/arm/mach-rockchip/bootrom.c | 4 ++-- arch/arm/mach-rockchip/rk3036-board-spl.c | 2 +- arch/arm/mach-rockchip/rk3188-board-spl.c | 4 ++-- arch/arm/mach-rockchip/rk322x-board-spl.c | 2 +- arch/arm/mach-rockchip/rk3288-board-spl.c | 4 ++-- arch/arm/mach-rockchip/rk3288-board-tpl.c | 2 +- arch/arm/mach-rockchip/rk3368-board-tpl.c | 2 +- arch/arm/mach-rockchip/rk3399-board-spl.c | 2 +- 9 files changed, 15 insertions(+), 12 deletions(-)
diff --git a/arch/arm/include/asm/arch-rockchip/bootrom.h b/arch/arm/include/asm/arch-rockchip/bootrom.h index 2f61a33..103b799 100644 --- a/arch/arm/include/asm/arch-rockchip/bootrom.h +++ b/arch/arm/include/asm/arch-rockchip/bootrom.h @@ -24,6 +24,9 @@ extern u32 SAVE_SP_ADDR; * download mode, ...). * * This function does not return. + * + * @brom_cmd: indicates how the bootrom should continue the boot + * sequence (e.g. load the next stage) */ enum rockchip_bootrom_cmd { /* @@ -35,7 +38,7 @@ enum rockchip_bootrom_cmd { BROM_BOOT_ENTER_DNL, /* have BROM enter download-mode */ };
-void back_to_bootrom(void); +void back_to_bootrom(enum rockchip_bootrom_cmd brom_cmd);
/** * Boot-device identifiers as used by the BROM diff --git a/arch/arm/mach-rockchip/bootrom.c b/arch/arm/mach-rockchip/bootrom.c index 7b9b307..e369fdc 100644 --- a/arch/arm/mach-rockchip/bootrom.c +++ b/arch/arm/mach-rockchip/bootrom.c @@ -15,12 +15,12 @@ */ static jmp_buf brom_ctx __section(".data");
-void back_to_bootrom(void) +void back_to_bootrom(enum rockchip_bootrom_cmd brom_cmd) { #if CONFIG_IS_ENABLED(LIBCOMMON_SUPPORT) puts("Returning to boot ROM...\n"); #endif - longjmp(brom_ctx, BROM_BOOT_NEXTSTAGE); + longjmp(brom_ctx, brom_cmd); }
/* diff --git a/arch/arm/mach-rockchip/rk3036-board-spl.c b/arch/arm/mach-rockchip/rk3036-board-spl.c index 9458201..550e3a1 100644 --- a/arch/arm/mach-rockchip/rk3036-board-spl.c +++ b/arch/arm/mach-rockchip/rk3036-board-spl.c @@ -40,7 +40,7 @@ void board_init_f(ulong dummy) sdram_init();
/* return to maskrom */ - back_to_bootrom(); + back_to_bootrom(BROM_BOOT_NEXTSTAGE); }
/* Place Holders */ diff --git a/arch/arm/mach-rockchip/rk3188-board-spl.c b/arch/arm/mach-rockchip/rk3188-board-spl.c index 05d4ae6..8e3b8ae 100644 --- a/arch/arm/mach-rockchip/rk3188-board-spl.c +++ b/arch/arm/mach-rockchip/rk3188-board-spl.c @@ -158,7 +158,7 @@ void board_init_f(ulong dummy)
setup_arm_clock(); #if CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM) && !defined(CONFIG_SPL_BOARD_INIT) - back_to_bootrom(); + back_to_bootrom(BROM_BOOT_NEXTSTAGE); #endif }
@@ -219,7 +219,7 @@ void spl_board_init(void)
preloader_console_init(); #if CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM) - back_to_bootrom(); + back_to_bootrom(BROM_BOOT_NEXTSTAGE); #endif return;
diff --git a/arch/arm/mach-rockchip/rk322x-board-spl.c b/arch/arm/mach-rockchip/rk322x-board-spl.c index 4ddb8ba..35f4f97 100644 --- a/arch/arm/mach-rockchip/rk322x-board-spl.c +++ b/arch/arm/mach-rockchip/rk322x-board-spl.c @@ -76,6 +76,6 @@ void board_init_f(ulong dummy) /* Disable the ddr secure region setting to make it non-secure */ rk_clrreg(SGRF_DDR_CON0, 0x4000); #if defined(CONFIG_ROCKCHIP_SPL_BACK_TO_BROM) && !defined(CONFIG_SPL_BOARD_INIT) - back_to_bootrom(); + back_to_bootrom(BROM_BOOT_NEXTSTAGE); #endif } diff --git a/arch/arm/mach-rockchip/rk3288-board-spl.c b/arch/arm/mach-rockchip/rk3288-board-spl.c index 7b7fd5a..f64a548 100644 --- a/arch/arm/mach-rockchip/rk3288-board-spl.c +++ b/arch/arm/mach-rockchip/rk3288-board-spl.c @@ -216,7 +216,7 @@ void board_init_f(ulong dummy) #endif
#if CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM) && !defined(CONFIG_SPL_BOARD_INIT) - back_to_bootrom(); + back_to_bootrom(BROM_BOOT_NEXTSTAGE); #endif }
@@ -283,7 +283,7 @@ void spl_board_init(void)
preloader_console_init(); #if CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM) - back_to_bootrom(); + back_to_bootrom(BROM_BOOT_NEXTSTAGE); #endif return; err: diff --git a/arch/arm/mach-rockchip/rk3288-board-tpl.c b/arch/arm/mach-rockchip/rk3288-board-tpl.c index 3d08b5b..150beea 100644 --- a/arch/arm/mach-rockchip/rk3288-board-tpl.c +++ b/arch/arm/mach-rockchip/rk3288-board-tpl.c @@ -69,7 +69,7 @@ void board_init_f(ulong dummy)
void board_return_to_bootrom(void) { - back_to_bootrom(); + back_to_bootrom(BROM_BOOT_NEXTSTAGE); }
u32 spl_boot_device(void) diff --git a/arch/arm/mach-rockchip/rk3368-board-tpl.c b/arch/arm/mach-rockchip/rk3368-board-tpl.c index b3e6ffa..60d5aea 100644 --- a/arch/arm/mach-rockchip/rk3368-board-tpl.c +++ b/arch/arm/mach-rockchip/rk3368-board-tpl.c @@ -148,7 +148,7 @@ void board_init_f(ulong dummy)
void board_return_to_bootrom(void) { - back_to_bootrom(); + back_to_bootrom(BROM_BOOT_NEXTSTAGE); }
u32 spl_boot_device(void) diff --git a/arch/arm/mach-rockchip/rk3399-board-spl.c b/arch/arm/mach-rockchip/rk3399-board-spl.c index 9c20f56..b96903e 100644 --- a/arch/arm/mach-rockchip/rk3399-board-spl.c +++ b/arch/arm/mach-rockchip/rk3399-board-spl.c @@ -23,7 +23,7 @@ DECLARE_GLOBAL_DATA_PTR;
void board_return_to_bootrom(void) { - back_to_bootrom(); + back_to_bootrom(BROM_BOOT_NEXTSTAGE); }
static const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {

There still are a few CONFIG_SPL_* options selected using defines from rk3188_common.h instead of via Kconfig. This migrates those over to Kconfig.
Signed-off-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com ---
Changes in v4: None Changes in v3: None Changes in v2: None
arch/arm/mach-rockchip/Kconfig | 7 ++++++- include/configs/rk3188_common.h | 6 ------ 2 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig index 09f2c45..36df484 100644 --- a/arch/arm/mach-rockchip/Kconfig +++ b/arch/arm/mach-rockchip/Kconfig @@ -16,8 +16,13 @@ config ROCKCHIP_RK3188 select CPU_V7 select SPL_BOARD_INIT if SPL select SUPPORT_SPL - select SUPPORT_TPL select SPL + select SPL_CLK + select SPL_PINCTRL + select SPL_REGMAP + select SPL_SYSCON + select SPL_RAM + select SPL_DRIVERS_MISC_SUPPORT select SPL_ROCKCHIP_EARLYRETURN_TO_BROM select BOARD_LATE_INIT select ROCKCHIP_BROM_HELPER diff --git a/include/configs/rk3188_common.h b/include/configs/rk3188_common.h index 9824a10..0382450 100644 --- a/include/configs/rk3188_common.h +++ b/include/configs/rk3188_common.h @@ -41,12 +41,6 @@ /* spl size 32kb sram - 2kb bootrom */ #define CONFIG_SPL_MAX_SIZE (0x8000 - 0x800) #define CONFIG_SPL_FRAMEWORK 1 -#define CONFIG_SPL_CLK 1 -#define CONFIG_SPL_PINCTRL 1 -#define CONFIG_SPL_REGMAP 1 -#define CONFIG_SPL_SYSCON 1 -#define CONFIG_SPL_RAM 1 -#define CONFIG_SPL_DRIVERS_MISC_SUPPORT 1 #define CONFIG_ROCKCHIP_SERIAL 1
#define CONFIG_SPL_STACK 0x10087fff

With all targets converted to generate prepadded images, this removes the spl_boot0 field from our config structure and removes the unused code-path (for images that are not prepadded): i.e. spl_boot0 is now implied as 'true' and the code is specialised by removing the other case.
Signed-off-by: Philipp Tomsich philipp.tomsich@theobroma-systems.com ---
Changes in v4: None Changes in v3: None Changes in v2: None
tools/rkcommon.c | 45 ++++++++++++++------------------------------- 1 file changed, 14 insertions(+), 31 deletions(-)
diff --git a/tools/rkcommon.c b/tools/rkcommon.c index c83260a..aed2b95 100644 --- a/tools/rkcommon.c +++ b/tools/rkcommon.c @@ -58,9 +58,6 @@ struct header1_info { * @spl_hdr: Boot ROM requires a 4-bytes spl header * @spl_size: Spl size(include extra 4-bytes spl header) * @spl_rc4: RC4 encode the SPL binary (same key as header) - * @spl_boot0: A new-style (ARM_SOC_BOOT0_HOOK) image that should - * have the boot magic (e.g. 'RK33') written to its first - * word. */
struct spl_info { @@ -68,19 +65,18 @@ struct spl_info { const char *spl_hdr; const uint32_t spl_size; const bool spl_rc4; - const bool spl_boot0; };
static struct spl_info spl_infos[] = { - { "rk3036", "RK30", 0x1000, false, true }, - { "rk3128", "RK31", 0x1800, false, true }, - { "rk3188", "RK31", 0x8000 - 0x800, true, true }, - { "rk322x", "RK32", 0x8000 - 0x1000, false, true }, - { "rk3288", "RK32", 0x8000, false, true }, - { "rk3328", "RK32", 0x8000 - 0x1000, false, true }, - { "rk3368", "RK33", 0x8000 - 0x1000, false, true }, - { "rk3399", "RK33", 0x30000 - 0x2000, false, true }, - { "rv1108", "RK11", 0x1800, false, true }, + { "rk3036", "RK30", 0x1000, false }, + { "rk3128", "RK31", 0x1800, false }, + { "rk3188", "RK31", 0x8000 - 0x800, true }, + { "rk322x", "RK32", 0x8000 - 0x1000, false }, + { "rk3288", "RK32", 0x8000, false }, + { "rk3328", "RK32", 0x8000 - 0x1000, false }, + { "rk3368", "RK33", 0x8000 - 0x1000, false }, + { "rk3399", "RK33", 0x30000 - 0x2000, false }, + { "rv1108", "RK11", 0x1800, false }, };
static unsigned char rc4_key[16] = { @@ -158,16 +154,6 @@ bool rkcommon_need_rc4_spl(struct image_tool_params *params) return info->spl_rc4; }
-bool rkcommon_spl_is_boot0(struct image_tool_params *params) -{ - struct spl_info *info = rkcommon_get_spl_info(params->imagename); - - /* - * info would not be NULL, because of we checked params before. - */ - return info->spl_boot0; -} - static void rkcommon_set_header0(void *buf, uint file_size, struct image_tool_params *params) { @@ -366,15 +352,12 @@ int rkcommon_vrec_header(struct image_tool_params *params, * have the first 4 bytes reserved for the spl_name). Reserving * these 4 bytes is done using the BOOT0_HOOK infrastructure. * - * Depending on this, the header is either 0x800 (if this is a - * 'boot0'-style payload, which has reserved 4 bytes at the - * beginning for the 'spl_name' and expects us to overwrite - * its first 4 bytes) or 0x804 bytes in length. + * The header is always at 0x800 (as we now use a payload + * prepadded using the boot0 hook for all targets): the first + * 4 bytes of these images can safely be overwritten using the + * boot magic. */ - if (rkcommon_spl_is_boot0(params)) - tparams->header_size = RK_SPL_HDR_START; - else - tparams->header_size = RK_SPL_HDR_START + 4; + tparams->header_size = RK_SPL_HDR_START;
/* Allocate, clear and install the header */ tparams->hdr = malloc(tparams->header_size);
participants (4)
-
Andy Yan
-
Dr. Philipp Tomsich
-
Marek Vasut
-
Philipp Tomsich