Re: [PATCH 3/3] arm64: renesas: Add TFA BL31 handoff support

Quentin Schulz
2025-01-29T17:33:04Z

On 1/29/25 6:00 PM, Marek Vasut wrote:
> On 1/29/25 5:02 PM, Quentin Schulz wrote:
>>> +void armv8_switch_to_el2_prep(u64 args, u64 mach_nr, u64 fdt_addr,
>>> +                  u64 arg4, u64 entry_point, u64 es_flag)
>>> +{
>>> +    typedef void __noreturn (*image_entry_noargs_t)(void);
>>> +    image_entry_noargs_t image_entry =
>>> +        (image_entry_noargs_t)(void *)tfa_bl31_image_addr;
>>> +    struct bl2_to_bl31_params_mem *blinfo =
>>> +        (struct bl2_to_bl31_params_mem *)PARAMS_BASE;
>>> +
>>> +    /*
>>> +     * Destination address in arch/arm/cpu/armv8/transition.S
>>> +     * right past the first bl in armv8_switch_to_el2() to let
>>> +     * the rest of U-Boot pre-Linux code run. The code does run
>>> +     * without stack pointer!
>>> +     */
>>> +    const u64 ep = ((u64)(uintptr_t)&armv8_switch_to_el2) + 4;
>>> +
>>> +    /* If TFA BL31 was not part of the fitImage, do regular boot. */
>>> +    if (!tfa_bl31_image_loaded)
>>> +        return;
>>> +
>>> +    /*
>>> +     * Set up kernel entry point and parameters:
>>> +     * x0 is FDT address, x1..x3 must be 0
>>> +     */
>>> +    blinfo->bl33_ep_info.pc = ep;
>>> +    blinfo->bl33_ep_info.args.arg0 = args;
>>> +    blinfo->bl33_ep_info.args.arg1 = mach_nr;
>>> +    blinfo->bl33_ep_info.args.arg2 = fdt_addr;
>>> +    blinfo->bl33_ep_info.args.arg3 = arg4;
>>> +    blinfo->bl33_ep_info.args.arg4 = entry_point;
>>> +    blinfo->bl33_ep_info.args.arg5 = es_flag;
>>> +    blinfo->bl33_image_info.image_base = ep;
>>> +
>>> +    /* Jump to TFA BL31 */
>>> +    image_entry();
>>> +}
>>
>> Shouldn't we have a weak implementation that SoC vendor can override
>> if they feel like it?
>
> We do have one. Please do have a look at 1/3 in this series:
>
> WEAK(armv8_switch_to_el2_prep)
>

Well yes, and it's completely empty :)

>> To me this feels like it could be much quicker adopted if we had some
>> default people could try out for their boards.
>>
>> We already have a generic spl_invoke_atf() so why not the same for
>> this mechanism? As far as I could tell, we get the load address of TEE
>> and U- Boot proper (bl32 and bl33) and pass it the FDT (or nothing if
>> SPL_ATF_NO_PLATFORM_PARAM symbol set).
>
> Looking at spl_invoke_atf(), it _almost_ looks like something I could
> use, but from what I see there and here, the handoff structure layout is
> slightly different, it seems to be board specific.
>

I believe it's common to any board with SPL_ATF symbol enabled.

That would be...

$ git grep CONFIG_SPL_ATF= configs | cut -f1 -d ':' | sort
configs/anbernic-rgxx3-rk3566_defconfig
configs/bpi-r2-pro-rk3568_defconfig
configs/cm3588-nas-rk3588_defconfig
configs/coolpi-4b-rk3588s_defconfig
configs/coolpi-cm5-evb-rk3588_defconfig
configs/coolpi-cm5-genbook-rk3588_defconfig
configs/evb-px30_defconfig
configs/evb-px5_defconfig
configs/evb-rk3328_defconfig
configs/evb-rk3568_defconfig
configs/evb-rk3588_defconfig
configs/firefly-px30_defconfig
configs/generic-rk3568_defconfig
configs/generic-rk3588_defconfig
configs/jaguar-rk3588_defconfig
configs/khadas-edge2-rk3588s_defconfig
configs/lubancat-2-rk3568_defconfig
configs/nanopc-t6-rk3588_defconfig
configs/nanopi-r2c-plus-rk3328_defconfig
configs/nanopi-r2c-rk3328_defconfig
configs/nanopi-r2s-plus-rk3328_defconfig
configs/nanopi-r2s-rk3328_defconfig
configs/nanopi-r3s-rk3566_defconfig
configs/nanopi-r5c-rk3568_defconfig
configs/nanopi-r5s-rk3568_defconfig
configs/nanopi-r6c-rk3588s_defconfig
configs/nanopi-r6s-rk3588s_defconfig
configs/neu6a-io-rk3588_defconfig
configs/neu6b-io-rk3588_defconfig
configs/nova-rk3588s_defconfig
configs/odroid-go2_defconfig
configs/odroid-m1-rk3568_defconfig
configs/odroid-m1s-rk3566_defconfig
configs/odroid-m2-rk3588s_defconfig
configs/orangepi-3b-rk3566_defconfig
configs/orangepi-5-plus-rk3588_defconfig
configs/orangepi-5-rk3588s_defconfig
configs/orangepi-r1-plus-lts-rk3328_defconfig
configs/orangepi-r1-plus-rk3328_defconfig
configs/pinetab2-rk3566_defconfig
configs/powkiddy-x55-rk3566_defconfig
configs/px30-core-ctouch2-of10-px30_defconfig
configs/px30-core-ctouch2-px30_defconfig
configs/px30-core-edimm2.2-px30_defconfig
configs/qnap-ts433-rk3568_defconfig
configs/quartz64-a-rk3566_defconfig
configs/quartz64-b-rk3566_defconfig
configs/quartzpro64-rk3588_defconfig
configs/radxa-cm3-io-rk3566_defconfig
configs/radxa-e25-rk3568_defconfig
configs/radxa-zero-3-rk3566_defconfig
configs/ringneck-px30_defconfig
configs/roc-cc-rk3328_defconfig
configs/rock-3a-rk3568_defconfig
configs/rock-3b-rk3568_defconfig
configs/rock-3c-rk3566_defconfig
configs/rock5a-rk3588s_defconfig
configs/rock5b-rk3588_defconfig
configs/rock-5c-rk3588s_defconfig
configs/rock-5-itx-rk3588_defconfig
configs/rock64-rk3328_defconfig
configs/rock-pi-e-rk3328_defconfig
configs/rock-pi-e-v3-rk3328_defconfig
configs/sige7-rk3588_defconfig
configs/socfpga_agilex5_defconfig
configs/socfpga_agilex_atf_defconfig
configs/socfpga_agilex_vab_defconfig
configs/socfpga_n5x_atf_defconfig
configs/socfpga_n5x_vab_defconfig
configs/socfpga_stratix10_atf_defconfig
configs/soquartz-blade-rk3566_defconfig
configs/soquartz-cm4-rk3566_defconfig
configs/soquartz-model-a-rk3566_defconfig
configs/tiger-rk3588_defconfig
configs/toybrick-rk3588_defconfig
configs/turing-rk1-rk3588_defconfig
configs/xilinx_zynqmp_kria_defconfig
configs/xilinx_zynqmp_virt_defconfig

Essentially Rockchip boards + some socfpga and Xilinx ZynqMP boards.

... which I guess confirms what you've been saying, I don't feel like
it's generic enough to warrant making it the default, weak, implementation.

Cheers,
Quentin