Some of the modern SoCs such as Rockchip RK3576 require TF-A to be running
to provide firmware services to the OS, and current TF-A loading code in
SPL only supports loading TF-A with U-boot as BL33.

Extend SPL to support loading TF-A with Linux as BL33, and add necessary
hooks to enable this functionality with RK3576 booting from UFS flash.

This has been tested with an uncompressed ARM64 Image as the payload, as
well as with a GZip-compressed one (using existing SPL_GZIP functionality)
with a Zstd compressed initramfs and build-time pre-patched DTB to include
the kernel command line and initramfs location directly into the /chosen
node, on the Rockchip RK3576 based Flipper One board.
Booting this way lets me get from power-on to initramfs in 3.5 seconds -
without any extra optimizations - which is pretty impressive.

Build command is along these lines (native ARM64 build):
$ make -j$(nproc) \
        BL31=~/trusted-firmware-a/build/rk3576/release/bl31/bl31.elf \
        
ROCKCHIP_TPL=~/rkbin/bin/rk35/rk3576_ddr_lp4_2112MHz_lp5_2736MHz_v1.13.bin \
        LINUX_KERNEL=~/fit-artifacts/Image \
        LINUX_INITRD=~/fit-artifacts/ramdisk.cpio.zst

Loading a Falcon-equipped usb472 payload via Maskrom directly to RAM is
also possible:

rockusb download-sram u-boot-rockchip-usb471.bin
rockusb download-ddr u-boot-rockchip-usb472-falcon.bin

The caveat though is that the boot ROM checks the download-ddr payload
via an extremely slow (124 kB/s) unoptimized CRC16 routine, so loading
a meaningfully sized kernel and initramfs takes a long time by default.
This can be sidestepped by forcing the CRC bytes in the maskrom 0x472
payload to zeros, which skips the slow CRC16 check altogether. Another
speedup I have identified is to enable the processor's I-cache before
sending the 0x472 payload, which speeds up the CRC16 check by a factor
of 16x, making it borderline tolerable (~20s for my setup).

Signed-off-by: Alexey Charkov <[email protected]>
---
Changes in v2:
- s/ATF/TF-A/ throughout (thanks Marek)
- Refactored the common spl-atf code to avoid the global variable (thanks Marek)
- Dropped the misleading reference to U-Boot requiring the CPU MPID in x0
  register, which is not true for upstream U-Boot codebase (nor TF-A) and
  must be a vestige of older Rockchip-specific code from before 2017 when
  the comment was introduced (thanks Marek)
- Added a panic when secure Falcon mode is enabled but the Linux image
  cannot be loaded, to avoid falling back to potentially untrusted code in
  this case. This behavior is also prescribed by the existing Falcon mode
  documentation (thanks Marek)
- Factored out common atf-SEQ sections in the binman template to make them
  reused by both the U-Boot and Falcon mode images (thanks Jonas)
- Added support for multiple DTBs in the Falcon mode image, with the ability
  to select them via existing SPL board hooks such as
  board_fit_config_name_match() (thanks Jonas)
- Added test coverage for newly introduced binman functionality (thanks Jonas)
- Added documentation for the new TF-A Falcon mode support in SPL (thanks Jonas)
- Added support for embedding externally provided Linux initrd
- Added support for pre-patching FDTs in the FIT image with a /chosen node
  to facilitate the creation of a ready-to-boot Falcon mode image without
  extra preprocessing
- Added a caching helper for boot-time Falcon/U-Boot selection to avoid
  mismatched selections during the boot process when the board provided
  implementation of spl_start_uboot() is not idempotent
- Made the default spl_start_uboot() override for Rockchip non-weak to
  avoid relying on the link order, and added a separate board-overrideable
  hook board_spl_start_uboot() there
- Split out binman changes vs. Rockchip-specific image template
- Added a separate Kconfig option to enable Falcon-mode image generation
  for Rockchip SoCs, so that a Falcon-enabled SPL can be built without
  necessarily generating a Falcon-mode image with binman
- Enabled kernel compression support in binman-generated Falcon-mode images
  (using existing SPL_GZIP and SPL_LZMA support)
- Added a config fragment rockchip-falcon.config to easily enable the
  required Kconfig options for Falcon mode support in SPL and binman
- Link to v1: 
https://patch.msgid.link/[email protected]

To: [email protected]
Cc: Tom Rini <[email protected]>
Cc: Alexey Charkov <[email protected]>
Cc: Ronald Wahl <[email protected]>
Cc: Richard Genoud <[email protected]>
Cc: Miquel Raynal <[email protected]>
Cc: Bastien Curutchet <[email protected]>
Cc: Johan Jonker <[email protected]>
Cc: Daniel Golle <[email protected]>
Cc: Neil Armstrong <[email protected]>
Cc: Bhupesh Sharma <[email protected]>
Cc: Neha Malcom Francis <[email protected]>
Cc: Simon Glass <[email protected]>
Cc: Alper Nebi Yasak <[email protected]>
Cc: "Markus Schneider-Pargmann (TI)" <[email protected]>
Cc: Peter Robinson <[email protected]>
Cc: Tony Dinh <[email protected]>
Cc: James Hilliard <[email protected]>
Cc: Quentin Schulz <[email protected]>
Cc: Ilias Apalodimas <[email protected]>
Cc: Quentin Schulz <[email protected]>
Cc: Kever Yang <[email protected]>
Cc: Jonas Karlman <[email protected]>
Cc: João Marcos Costa <[email protected]>

---
Alexey Charkov (10):
      spl: Decide about Falcon mode boot only once
      spl: atf: support Linux as BL33 with TFA
      spl: ufs: add Falcon mode load path
      binman: Add support for externally provided Linux kernel blob
      binman: Add support for externally provided Linux initrd blob
      binman: Add support for pre-patching FDTs in a FIT with a /chosen node
      binman: tests: Add test coverage for a FIT with embedded Linux+initrd and 
/chosen
      rockchip: spl: default to Falcon mode boot in SPL if enabled
      rockchip: binman: Add support for Falcon mode FIT images with TF-A+Linux
      doc: falcon: Describe booting the OS through TF-A

 Makefile                                       |   2 +
 arch/arm/dts/rockchip-u-boot.dtsi              | 204 +++++++++++++++++++++----
 arch/arm/mach-rockchip/Kconfig                 |  49 ++++++
 arch/arm/mach-rockchip/spl.c                   |  29 ++++
 board/rockchip/rockchip-falcon.config          |   3 +
 common/spl/Kconfig                             |  45 +++++-
 common/spl/spl.c                               |  18 +++
 common/spl/spl_atf.c                           |  49 ++++--
 common/spl/spl_ufs.c                           |  58 ++++++-
 doc/board/rockchip/rockchip.rst                |   9 ++
 doc/develop/falcon.rst                         | 131 +++++++++++++++-
 include/spl.h                                  |  11 ++
 tools/binman/entry.py                          |   8 +
 tools/binman/etype/fit.py                      | 103 +++++++++++++
 tools/binman/etype/linux_initrd.py             |  23 +++
 tools/binman/etype/linux_kernel.py             |  22 +++
 tools/binman/ftest.py                          | 107 +++++++++++++
 tools/binman/missing-blob-help                 |  10 ++
 tools/binman/test/fit/fit_chosen.dts           |  62 ++++++++
 tools/binman/test/fit/fit_chosen_no_initrd.dts |  60 ++++++++
 tools/binman/test/fit/fit_chosen_no_load.dts   |  57 +++++++
 21 files changed, 1007 insertions(+), 53 deletions(-)
---
base-commit: 100e12ea78c73071b9710f08b32fd4590019266f
change-id: 20260609-atf-falcon-e7eef54d16e5

Best regards,
--  
Alexey Charkov <[email protected]>

Reply via email to