Re: [PATCH v2 02/10] spl: atf: support Linux as BL33 with TFA

Alexey Charkov <[email protected]> Tue, 4 Aug 2026 18:01:16 +0400
Newsgroups gmane.comp.boot-loaders.u-boot
Message-ID <CAKTNdwFz-0eBZypfv_rkR9MvrNHUg3VV+ErGjjrFkVFHEj+FEA@mail.gmail.com>
Hi Simon,

On Tue, Aug 4, 2026 at 5:02=E2=80=AFPM Simon Glass <[email protected]> wrote=
:
>
> Hi Alexey,
>
> On 2026-07-31T17:10:44, Alexey Charkov <[email protected]> wrote:
> > spl: atf: support Linux as BL33 with TFA
> >
> > Modern SoCs such as Rockchip RK3576 need TFA to be running to provide
> > firmware services to the OS.
> >
> > Enable the TFA boot flow to allow using Linux as BL33 (including its
> > calling convention) to facilitate Falcon mode boot on such SoCs.
> >
> > Signed-off-by: Alexey Charkov <[email protected]>
> >
> > common/spl/Kconfig   | 22 ++++++++++++++++++++--
> >  common/spl/spl_atf.c | 49 +++++++++++++++++++++++++++++++++-----------=
-----
> >  2 files changed, 53 insertions(+), 18 deletions(-)
>
> >     Enable the TFA boot flow to allow using Linux as BL33 (including it=
s
> >     calling convention) to facilitate Falcon mode boot on such SoCs.
>
> The commit message says 'including its calling convention', but the
> diff drops read_mpidr() unconditionally - every existing SPL_ATF user
> now gets the FDT address in x0 rather than the MPID. Please spell this
> out and note why it is safe (i.e. U-Boot proper as BL33 does not
> consume x0, and the previous MPID value was a vestige, as you
> mentioned in the v2 changelog). Right now that context lives only in
> the changelog below the '---', which does not land in git history.

Will do, thanks.

> > diff --git a/common/spl/spl_atf.c b/common/spl/spl_atf.c
> > @@ -87,8 +88,8 @@ struct bl31_params *bl2_plat_get_bl31_params_default(=
ulong bl32_entry,
> >       SET_PARAM_HEAD(bl33_ep_info, ATF_PARAM_EP, ATF_VERSION_1,
> >                      ATF_EP_NON_SECURE);
> >
> > -     /* BL33 expects to receive the primary CPU MPID (through x0) */
> > -     bl33_ep_info->args.arg0 =3D 0xffff & read_mpidr();
> > +     /* Pass the FDT address in x0, per the TF-A BL33 / Linux boot pro=
tocol. */
> > +     bl33_ep_info->args.arg0 =3D fdt_addr;
>
> Just to check - for the U-Boot-as-BL33 case where CONFIG_OF_BOARD or
> CONFIG_OF_SEPARATE is used and the FDT comes from elsewhere, does
> anything in-tree currently rely on x0 being the MPID? A quick look of
> the arm64 crt0 suggests not, but worth confirming across the SPL_ATF
> users (Rockchip, TI K3, socfpga, meson etc.) rather than assuming.

Nope, I went through both the mainline U-Boot codebase and TF-A -
nothing expects MPID there. TF-A stores whatever it received and puts
it back before handing over to the next stage. In U-Boot proper it's
just saved in save_boot_params, and can be claimed by either
CONFIG_BLOBLIST (which expects it to be an FDT pointer, not MPIDR) or
SAVE_PREV_BL_FDT_ADDR (same).

Per-platform overrides never mention MPIDR either - only DTB pointers.

The comment and the code was added in the initial commit bcc1726a7bdd
("spl: add support to booting with ATF") by Kever Yang back in 2017
and was never really propagated anywhere in the tree.

> > diff --git a/common/spl/spl_atf.c b/common/spl/spl_atf.c
> > @@ -189,7 +190,8 @@ static inline void raw_write_daif(unsigned int daif=
)
> >  typedef void __noreturn (*atf_entry_t)(struct bl31_params *params, voi=
d *plat_params);
> >
> >  static void __noreturn bl31_entry(ulong bl31_entry, ulong bl32_entry,
> > -                               ulong bl33_entry, ulong fdt_addr)
> > +                               ulong bl33_entry, ulong fdt_addr,
> > +                               ulong plat_param)
>
> The two arguments now mean quite different things - fdt_addr is what
> BL33 receives in x0 (and BL32 in arg3), plat_param is what BL31
> receives as its second parameter. A short kernel-doc comment on
> bl31_entry() spelling that out would help; the split is easy to miss
> and the ATF_NO_PLATFORM_PARAM path now diverges the two values
> silently.

Will do, thanks.

> > diff --git a/common/spl/spl_atf.c b/common/spl/spl_atf.c
> > @@ -253,10 +255,11 @@ ulong spl_fit_images_get_entry(void *blob, int no=
de)
> >
> >  void __noreturn spl_invoke_atf(struct spl_image_info *spl_image)
> >  {
> > -     ulong  bl32_entry =3D 0;
> > -     ulong  bl33_entry =3D CONFIG_TEXT_BASE;
> > -     void *blob =3D spl_image->fdt_addr;
> > +     bool falcon =3D CONFIG_IS_ENABLED(OS_BOOT) && spl_falcon_boot();
> > +     void *blob =3D spl_image_fdt_addr(spl_image);
>
> Switching to spl_image_fdt_addr() is a good change, but the helper
> returns 0 when neither LOAD_FIT nor LOAD_FIT_FULL is enabled. If
> somebody hits spl_invoke_atf() in that configuration we now pass
> blob=3D0 as x0 to BL33 (which for Linux is fatal) rather than the
> arbitrary junk the old code passed. Not a regression, but if that
> combination is not supposed to reach here at all, a build-time or
> runtime guard would be clearer than relying on the caller.

Indeed, will add an error path for the zero case here.

> > diff --git a/common/spl/Kconfig b/common/spl/Kconfig
> > @@ -1230,22 +1230,40 @@ config SPL_BOOTZ
> >  config SPL_BOOTI
> >       bool "Allow booting an Image style Linux kernel from SPL"
> >       depends on SPL_OS_BOOT && !SPL_OS_BOOT_SECURE
> > -     default y if ARM64 || RISCV
> > +     default y if (ARM64 || RISCV) && !SPL_ATF
>
> Flipping the default based on SPL_ATF will silently disable SPL_BOOTI
> on any future board that combines SPL_ATF + SPL_OS_BOOT + ARM64 and
> relies on the old default. No in-tree defconfig hits that today, but
> it is a bit of a trap. Would it be cleaner to leave the default alone
> and rely on the code path in spl_invoke_atf() to route around BOOTI
> when TF-A is in play? The help text already explains the option
> remains selectable.

Hmm, adding a future board but relying on a default which will have
predated the addition of the said board sounds weird, doesn't it? :)

I'm not sure I see a clean way to route around BOOTI from within
spl_invoke_atf(), given that BOOTI just jumps to the kernel image
without starting the firmware first. It might kind-of-boot, but it
will result in degraded functionality, so I thought removing a footgun
from being enabled by default made more sense. It's not needed in the
FIT (TF-A+Linux) flow either, so removing a "default y" from Kconfig
is a one-liner which saves [num_boards] lines of defconfig noise
disabling it in every board individually.

Best regards,
Alexey