[PATCH 2/3] image: Add support for starting TFA BL31 as fitImage loadables

Marek Vasut
2025-01-12T22:38:37Z

Add support for starting TFA from U-Boot running in EL3 as part of
fitImage boot, so the user can start U-Boot in the highest privilege
level on the platform, bundle TFA, Linux, DT into a single fitImage
and boot such a bundle as a whole.

There are two main benefits of this approach. First is the ability
to run U-Boot in EL3, where it has unrestricted access to the entire
system and can act as a useful debug tool, as it was always intended
to be used. Second is the ability to easily and safely update of any
component in the fitImage, be it TFA, Linux or DT.

The boot process is similar to regular Linux with DT fitImage boot
process, except the TFA has to be bundled into the fitImage. For the
bundling instructions, see below. The TFA is started as a 'loadables'
with custom U_BOOT_FIT_LOADABLE_HANDLER and armv8_switch_to_el2_prep()
handling implemented in board code, and performing the handoff and
boot in case the TFA was loaded.

The loadables handler is optional and meant to set up any sort of
handoff structures used by the TFA BL31 or perform any other setup
that is needed by the blob. The custom armv8_switch_to_el2_prep()
has to implement the jump to TFA BL31 with return to U-Boot just
before booting the Linux kernel.

Example fitImage image and configuration section:

/dts-v1/;

/ {
description = "Linux kernel with FDT blob and TFA BL31";

images {
kernel-1 { ... };
fdt-1 { ... };
atf-1 { /* This is the TFA BL31 image */
description = "TFA BL31";
data = /incbin/("../build/plat/release/bl31.bin");
type = "tfa-bl31";
arch = "arm64";
os = "arm-trusted-firmware";
compression = "none";
load = <0x46400000>;
entry = <0x46400000>;
};
};

configurations {
default = "conf-1";
conf-1 {
description = "Boot Linux";
kernel = "kernel-1";
fdt = "fdt-1";
loadables = "atf-1"; /* This is the TFA BL31 loadable */
};
};
};

Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
---
Cc: Andre Przywara <andre.przywara@arm.com>
Cc: Caleb Connolly <caleb.connolly@linaro.org>
Cc: Igor Opaniuk <igor.opaniuk@gmail.com>
Cc: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Cc: Julien Masson <jmasson@baylibre.com>
Cc: Mattijs Korpershoek <mkorpershoek@baylibre.com>
Cc: Maxim Moskalets <maximmosk4@gmail.com>
Cc: Michael Walle <mwalle@kernel.org>
Cc: Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
Cc: Patrick Rudolph <patrick.rudolph@9elements.com>
Cc: Paul Barker <paul.barker.ct@bp.renesas.com>
Cc: Paul-Erwan Rio <paulerwan.rio@gmail.com>
Cc: Peter Hoyes <Peter.Hoyes@arm.com>
Cc: Raymond Mao <raymond.mao@linaro.org>
Cc: Sam Protsenko <semen.protsenko@linaro.org>
Cc: Simon Glass <sjg@chromium.org>
Cc: Sughosh Ganu <sughosh.ganu@linaro.org>
Cc: Tom Rini <trini@konsulko.com>
Cc: u-boot@lists.denx.de
---
boot/image-fit.c | 1 +
boot/image.c | 1 +
include/image.h | 1 +
3 files changed, 3 insertions(+)

diff --git a/boot/image-fit.c b/boot/image-fit.c
index db7fb61bca9..3b6d7231aff 100644
--- a/boot/image-fit.c
+++ b/boot/image-fit.c
@@ -2167,6 +2167,7 @@ int fit_image_load(struct bootm_headers *images, ulong addr,
type_ok = fit_image_check_type(fit, noffset, image_type) ||
fit_image_check_type(fit, noffset, IH_TYPE_FIRMWARE) ||
fit_image_check_type(fit, noffset, IH_TYPE_TEE) ||
+ fit_image_check_type(fit, noffset, IH_TYPE_TFA_BL31) ||
(image_type == IH_TYPE_KERNEL &&
fit_image_check_type(fit, noffset, IH_TYPE_KERNEL_NOLOAD));

diff --git a/boot/image.c b/boot/image.c
index abac254e026..139c5bd035a 100644
--- a/boot/image.c
+++ b/boot/image.c
@@ -183,6 +183,7 @@ static const table_entry_t uimage_type[] = {
{ IH_TYPE_FDT_LEGACY, "fdt_legacy", "legacy Image with Flat Device Tree ", },
{ IH_TYPE_RENESAS_SPKG, "spkgimage", "Renesas SPKG Image" },
{ IH_TYPE_STARFIVE_SPL, "sfspl", "StarFive SPL Image" },
+ { IH_TYPE_TFA_BL31, "tfa-bl31", "TFA BL31 Image", },
{ -1, "", "", },
};

diff --git a/include/image.h b/include/image.h
index 0a61dfd556c..3adb7219809 100644
--- a/include/image.h
+++ b/include/image.h
@@ -232,6 +232,7 @@ enum image_type_t {
IH_TYPE_FDT_LEGACY, /* Binary Flat Device Tree Blob in a Legacy Image */
IH_TYPE_RENESAS_SPKG, /* Renesas SPKG image */
IH_TYPE_STARFIVE_SPL, /* StarFive SPL image */
+ IH_TYPE_TFA_BL31, /* TFA BL31 image */

IH_TYPE_COUNT, /* Number of image types */
};
--
2.45.2