From: Chali Anis <[email protected]> When a "barebox,state" node is already reachable via barebox's live devicetree (statically compiled in, or injected by CONFIG_STATE_OVERLAY), render its fully resolved description - backend phandle included - with of_state_fixup() and publish it as a "BareboxState" UEFI variable, so an OS-side consumer can locate the state layout without needing a separate state.dtb file on the ESP.
state_to_efivars_export() and efi_late_init() are both late_efi_initcall, and within one initcall level, execution follows definition order in the object file, so state_to_efivars_export() must be defined after efi_late_init(): on boards with no state node in their own static devicetree, efi_late_init() is what loads and registers /boot/EFI/barebox/state.dtb, and only once that has had a chance to run does state_by_alias() have anything to find. Defined the other way around, state_to_efivars_export() would always run first and never see a state.dtb efi_late_init() had not loaded yet - it would only have happened to work when CONFIG_STATE_OVERLAY had already registered the node much earlier, at postcore_initcall, a narrower case than the state.dtb fallback efi_late_init() exists to support. Look the state instance up via the state_by_alias() helper (common/state/state.c) rather than open-coding the equivalent of_find_node_by_alias() + state_by_node(). This also means state not being set up yet is just a clean no-op, rather than the -ENODEV that open-coded version returned, which would've been logged as an initcall failure for what is an entirely ordinary condition. Assisted-by: Claude Sonnet 5 Signed-off-by: Chali Anis <[email protected]> --- efi/payload/init.c | 51 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/efi/payload/init.c b/efi/payload/init.c index f0ce2a82cefc..cdb73afffa2c 100644 --- a/efi/payload/init.c +++ b/efi/payload/init.c @@ -287,7 +287,6 @@ core_efi_initcall(efi_register_firmware_nodes_fixup); #define EFI_LOADER_FEATURE_SECUREBOOT_ENROLL (1LL << 11) #define EFI_LOADER_FEATURE_RETAIN_SHIM (1LL << 12) - static int efi_postcore_init(void) { const struct efi_device_path *parent_image_dp, *loaded_image_dp; @@ -404,6 +403,56 @@ static int efi_late_init(void) } late_efi_initcall(efi_late_init); +/* + * Must run after efi_late_init(): on boards with no state node compiled + * into their own devicetree, efi_late_init() is what loads and registers + * /boot/EFI/barebox/state.dtb (or, on CONFIG_STATE_OVERLAY targets, that + * already happened much earlier). Only once that has had a chance to run + * does state_by_alias() have anything to find here. + */ +static int state_to_efivars_export(void) +{ + struct device_node *np; + struct state *state; + void *fdt; + size_t size; + int ret; + + if (!IS_ENABLED(CONFIG_STATE)) + return 0; + + state = state_by_alias("state"); + if (!state) + return 0; + + np = of_new_node(NULL, NULL); + if (!np) + return -ENOMEM; + + ret = of_state_fixup(np, state); + if (ret) + goto out; + + fdt = of_flatten_dtb(np); + if (!fdt) { + ret = -ENOMEM; + goto out; + } + + size = fdt_totalsize(fdt); + + efi_set_variable("BareboxState", &efi_barebox_vendor_guid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + fdt, size); + + free(fdt); + ret = 0; +out: + of_delete_node(np); + return ret; +} +late_efi_initcall(state_to_efivars_export); static int do_efiexit(int argc, char *argv[]) { if (!BS)
