The Raspberry Pi has the "tryboot" feature where it can boot from a
different partition enabling failsafe A/B updates. After boot the
firmware sets 'partition' property in /chosen/bootloader.

Copy the /chosen/bootloader node to the device tree.

Set the env variable boot_partition accordingly to allow boards to
create a bootcmd based on the boot partition.

Reviewed-by: Matthias Brugger <[email protected]>
Signed-off-by: Gregor Herburger <[email protected]>
---
Changes in v3:
- Copy the complete '/chosen/bootloader' node instead of only the
  partition property
- Link to v2: 
https://patch.msgid.link/[email protected]

Changes in v2:
- update Reviewed-by tag
---
 board/raspberrypi/rpi/rpi.c | 51 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c
index 1da5df92351c..ba8a2c1ba4cf 100644
--- a/board/raspberrypi/rpi/rpi.c
+++ b/board/raspberrypi/rpi/rpi.c
@@ -480,6 +480,20 @@ static void set_serial_number(void)
        env_set("serial#", serial_string);
 }
 
+static void set_boot_partition_fdt(void)
+{
+       void *fdtp = (void *)gd->fdt_blob;
+       u32 partition;
+
+       partition = fdt_getprop_u32_default(fdtp, "/chosen/bootloader", 
"partition", 1);
+       if (!partition) {
+               printf("Failed to the get partition property.\n");
+               return;
+       }
+
+       env_set_ulong("boot_partition", partition);
+}
+
 int misc_init_r(void)
 {
        set_fdt_addr();
@@ -489,6 +503,7 @@ int misc_init_r(void)
        set_board_info();
 #endif
        set_serial_number();
+       set_boot_partition_fdt();
 
        return 0;
 }
@@ -579,6 +594,39 @@ int board_fdt_blob_setup(void **fdtp)
        return 0;
 }
 
+int copy_node_all_properties(void *dst, void *src, const char *path, const 
char *node)
+{
+       int src_parent, dst_parent;
+       int src_node, dst_node;
+       int prop;
+       int len;
+
+       src_parent = fdt_path_offset(src, path);
+       dst_parent = fdt_path_offset(dst, path);
+       if (src_parent < 0 || dst_parent < 0)
+               return -1;
+
+       src_node = fdt_subnode_offset(src, src_parent, node);
+       if (src_node < 0)
+               return -1;
+
+       dst_node = fdt_find_or_add_subnode(dst, dst_parent, node);
+       if (dst_node < 0)
+               return -1;
+
+       fdt_for_each_property_offset(prop, src, src_node) {
+               const char *name;
+               const void *value = fdt_getprop_by_offset(src, prop, &name, 
&len);
+
+               if (!value || !name)
+                       continue;
+
+               fdt_setprop(dst, dst_node, name, value, len);
+       }
+
+       return 0;
+}
+
 int copy_property(void *dst, void *src, char *path, char *property)
 {
        int dst_offset, src_offset;
@@ -641,6 +689,9 @@ void  update_fdt_from_fw(void *fdt, void *fw_fdt)
 
        /* copy uart clk as provided by the firmware */
        copy_property(fdt, fw_fdt, "/clocks/clk-uart", "clock-frequency");
+
+       /* Copy the bootloader node */
+       copy_node_all_properties(fdt, fw_fdt, "/chosen", "bootloader");
 }
 
 int ft_board_setup(void *blob, struct bd_info *bd)

---
base-commit: baa64b2f892890f00a377eac4a3e685472bb56b5
change-id: 20260803-tryboot2-8c5221376e5a

Best regards,
--  
Gregor Herburger <[email protected]>

Reply via email to