From: Chali Anis <[email protected]> barebox_register_of() - the only thing that ever registers a live devicetree root pre-boot on x86 EFI - lived in boarddata.c, which was compiled solely for CONFIG_EFI_STUB (the chain-loaded/ARM handoff-data entry point). x86 uses CONFIG_EFI_PAYLOAD (entry-single.c's standalone efi_main()), so no code ever called it there: of_get_root_node() stayed NULL for the entire pre-boot sequence. That's what state_overlay_apply() (CONFIG_STATE_OVERLAY's postcore_initcall) and state_to_efivars_export() (the BareboxState UEFI variable export) both rely on, so neither ever had anything to work with on x86. Compile boarddata.o for CONFIG_EFI_PAYLOAD too - efi_register_of() only needs BS, which entry-single.c's efi_main() already sets before any initcall runs, and handle_efi_boarddata() already no-ops cleanly when there is no PBL handoff data, the normal case for this entry point.
On x86, actually binding a struct state to the node CONFIG_STATE_OVERLAY adds still needs a fresh of_probe() pass: barebox_register_of() already ran one, before the overlay added anything, and the next one needs to happen later still than state_overlay_apply()'s own postcore_initcall, too - PCI/SATA enumeration (and thus the disk cdevs a partuuid-based state backend resolves against) only completes well after that point. Add efi_devices_probe() at device_efi_initcall to cover it. Finally, now that a state node reachable via CONFIG_STATE_OVERLAY is something x86 can actually end up with pre-boot, add efi_late_init()'s "skip loading the standalone state.dtb whenever a 'state' alias is already present" check - it's only meaningful once that can happen. Tested on QEMU as the EFI payload with a partuuid-referenced backend. Assisted-by: Claude Sonnet 5 Signed-off-by: Chali Anis <[email protected]> --- efi/payload/Makefile | 1 + efi/payload/init.c | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/efi/payload/Makefile b/efi/payload/Makefile index 6306540ab595..f8b19428a99c 100644 --- a/efi/payload/Makefile +++ b/efi/payload/Makefile @@ -11,3 +11,4 @@ obj-pbl-$(CONFIG_EFI_PAYLOAD) += early-mem.o obj-$(CONFIG_EFI_PAYLOAD) += entry-single.o pbl-$(CONFIG_EFI_STUB) += entry-multi.o obj-$(CONFIG_EFI_STUB) += boarddata.o +obj-$(CONFIG_EFI_PAYLOAD) += boarddata.o diff --git a/efi/payload/init.c b/efi/payload/init.c index cdb73afffa2c..e644ec60bb87 100644 --- a/efi/payload/init.c +++ b/efi/payload/init.c @@ -355,7 +355,7 @@ static int efi_late_init(void) void *fdt; int ret; - if (!IS_ENABLED(CONFIG_STATE)) + if (!IS_ENABLED(CONFIG_STATE) || of_find_node_by_alias(NULL, "state")) return 0; if (!get_mounted_path("/boot")) { @@ -453,6 +453,22 @@ static int state_to_efivars_export(void) return ret; } late_efi_initcall(state_to_efivars_export); + +/* + * On x86, PCI/SATA enumeration (and thus the disk cdevs a partuuid-based + * state backend resolves against) only completes well after the one + * of_probe() pass barebox_register_of() already did, before the state + * overlay even added its node. Re-probe once devices have actually shown + * up, so such a backend can still bind. + */ +static int __maybe_unused efi_devices_probe(void) +{ + return of_probe(); +} +#if IS_ENABLED(CONFIG_X86) +device_efi_initcall(efi_devices_probe); +#endif + static int do_efiexit(int argc, char *argv[]) { if (!BS)
