]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
spl: atf: fix BL32 entry point for multi-segment TEE images
authorDaniel Golle <daniel@makrotopia.org>
Sun, 19 Jul 2026 01:51:17 +0000 (02:51 +0100)
committerTom Rini <trini@konsulko.com>
Wed, 29 Jul 2026 20:52:23 +0000 (14:52 -0600)
binman's split-elf operation records one FIT image node per ELF
segment, all with os = "tee", and only the segment containing the ELF
entry point carries an entry property. Since fdt_add_subnode() inserts
new subnodes in front of existing ones, the /fit-images nodes end up in
reverse recording order, so spl_fit_images_find() would return the
*last* TEE segment and its load address was passed to BL31 as the BL32
entry point.

On RK3588 with an OP-TEE tee.elf consisting of two PT_LOAD segments
this made BL31 (SPD=opteed) ERET into OP-TEE's data segment at
0x30200000 instead of the entry point at 0x30000000, hanging the boot
right after 'BL31: Initializing BL32'.

Prefer the FIT image node which provides an entry property and only
fall back to the first matching node when none of them has one.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
common/spl/spl_atf.c

index 8bc5db7739508c416efe6daacc008ff4068c9c46..17acd3665dfaee54b5629dcbd7ecb3c541713e83 100644 (file)
@@ -212,7 +212,9 @@ static void __noreturn bl31_entry(ulong bl31_entry, ulong bl32_entry,
 static int spl_fit_images_find(void *blob, int os)
 {
        int parent, node, ndepth = 0;
+       int found = -FDT_ERR_NOTFOUND;
        const void *data;
+       ulong val;
 
        if (!blob)
                return -FDT_ERR_BADMAGIC;
@@ -231,11 +233,23 @@ static int spl_fit_images_find(void *blob, int os)
                if (!data)
                        continue;
 
-               if (genimg_get_os_id(data) == os)
+               if (genimg_get_os_id(data) != os)
+                       continue;
+
+               /*
+                * A multi-segment image, e.g. an OP-TEE ELF split by
+                * binman, is recorded as one node per segment, all with
+                * the same os. Only the segment holding the ELF entry
+                * point carries an entry property, so prefer that node.
+                */
+               if (!fit_image_get_entry(blob, node, &val))
                        return node;
+
+               if (found < 0)
+                       found = node;
        };
 
-       return -FDT_ERR_NOTFOUND;
+       return found;
 }
 
 ulong spl_fit_images_get_entry(void *blob, int node)