rockchip: boot0 hook: support early return for RK3188/RK3066-style BROM
authorPhilipp Tomsich <philipp.tomsich@theobroma-systems.com>
Tue, 10 Oct 2017 14:21:10 +0000 (16:21 +0200)
committerPhilipp Tomsich <philipp.tomsich@theobroma-systems.com>
Tue, 21 Nov 2017 22:57:22 +0000 (23:57 +0100)
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>
Tested-by: Andy Yan <andy.yan@rock-chips.com>
arch/arm/include/asm/arch-rockchip/boot0.h
arch/arm/mach-rockchip/Kconfig

index f7c614669cf7716fa0444a0c97d5d8c17d9018e8..af3a733e98443a8c3aead6c22e69ab48dcc67ae9 100644 (file)
         * 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 */
+       mov     r0, #0           /* return 0 to the BROM to signal 'OK' */
+       bx      lr               /* return control to the BROM */
+entry_counter:
+       .word   0
 #endif
        b reset
 #if !defined(CONFIG_ARM64)
@@ -32,7 +45,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
index 31e9864c8da6940075e247b4097b2a6d88126182..d59a1d5ccb2de053a9afb178be1b17c29e0325d3 100644 (file)
@@ -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