From patchwork Tue Sep 30 00:51:25 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 445 Return-Path: X-Original-To: u-boot-concept@u-boot.org Delivered-To: u-boot-concept@u-boot.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1759193544; bh=0MwrCvZShBFk6jR7/Y4yXP7o/1cbryBPQFKRNIdp5rw=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=RJEEOr0sHwLORZqmXhOuBZMw5nb5AGi2ZhCm3ZZ5UCOrpkymQ8s2CZxDSnvQioKOK yBsdEDP+GWQCNs1Oj6rS+P/vUlPFWv5bi15ivqlbmFJ+Jkn69vNTt2NkW0CyXjNLWW CZ9pNRqIr/077WL2EmdJz0pKWJrOa/Bn1jl+oZdQJp43iK36e4bsZneQYQD48EQOzG +vpROq48LYwUh2wlUhZ9NUB+MTHiUG7t2u/1/j0YtWRkpkh1ciPw871P5OcaQh3NF7 NsG2oX2p+ukpiSeX7jL7uH6fhmSoKTxL7SWEQRnslpNfLwdH9j73Es9iIckkna4UdN PI16qvqakoIag== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 4F45767B49 for ; Mon, 29 Sep 2025 18:52:24 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id YSV0ts9Ulqer for ; Mon, 29 Sep 2025 18:52:24 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1759193543; bh=0MwrCvZShBFk6jR7/Y4yXP7o/1cbryBPQFKRNIdp5rw=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=vOrSdiHnYYJ5T26SqJNgadHljLFD31Ao7IDB6MBYxGyuaBVb2kEiIfIk3RVyWCdVt IUzjNUHRBCg/xtOTHiAoaMi8NFeppxsP5UsTtkeifQkSlL+gUItG+NoD7TVIFq3SFO ZVn3SPtUyQlEu1/QZtQSF4FHCgMaDsb5nUxeUBIvA31FZ9q2p4ueMFdHDg6SvcpGcQ YONozefy+ou1YQLT+GjDfkbg68y1vivK6slMkIZeWmKP/vvS805lJf8Z3IgLeLw4qo f5BF5ArVsREtHLQj02opuPdnuB0x5pLORI2vV9efeAITVQCpl+W3B1XirtRnXBaTS9 RO0v+cPbITTjg== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 4FA7C67E58 for ; Mon, 29 Sep 2025 18:52:23 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1759193541; bh=vQinVZCCMnRhJJQuOm4AdRaAcoQpB1zbCVHGom4bOLk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HZV9bW91pc6LbP1nvB04oEg1qXzv/TEqtXL7zymFl+GJMwePBa0ou4Rh20+A4EOfk fr3m7DQ+Qdey2og5gmv7QauWjUP9TEZum8IHiVlOzd6EFcoNcWIzPo7bqRhiaykcmv LbjOwCsOEDwbEgeh/klTDHGdSfAZI6oxJAH3qnT+OQnl79IcIb6yDO2SQCRdkvjmb4 bC2iHXN63lDN9IaSD8NRx2pMI3kYZ8wopXnE3LijBbT4aU0GhIY7r8/7ifsyfGpyCa 3Igut6KfEkE1HtG9RrR8h/UW5A7YYU2hYW5etnB81OuORY7rWkESESs52/hVS4nk5P nPF1S4hsDOhyA== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 3786667E03; Mon, 29 Sep 2025 18:52:21 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10026) with ESMTP id g7LuNzMDVb1m; Mon, 29 Sep 2025 18:52:21 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1759193537; bh=aso+vnYCqItWVL5dpKnfPdEiJAuMJ9XGVySDednTpRg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Ptf35RnVJ+BE0z8unnQVZDUsvp5LB1t+r1a/sgNXN2KopkgMkRx70L5ODys42bb8m 2ba2SiPI9ujSXZV6N2MGbd14tP5GoeAYp+M8DxvteK2VJKWz7YhjWREbnk98xYPvN4 JDQkwmFRQEf/31XPEkjLvWlUs7BFwvctUXIlSVHzyud6Nonlps99PD8bzGGV4VMS/R jdwA6Wp8ZKeHhonnrc7AJGVqRl+rNShJF/wFobivVn+MJSpc/UMSRDC0p1qKsmx1jY AP5uIa5KYTLDOREN8TurTiSvHCP5n3F7+KKfDvmoSZuYUTRt3Q9TfTI2+Rjxp4C3lC bQh98R0mu182Q== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id D75BA67E59; Mon, 29 Sep 2025 18:52:16 -0600 (MDT) From: Simon Glass To: U-Boot Concept Date: Mon, 29 Sep 2025 18:51:25 -0600 Message-ID: <20250930005137.3650600-10-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250930005137.3650600-1-sjg@u-boot.org> References: <20250930005137.3650600-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: HSFORPN3Z3E3DLMLGOTDKIMGKOBE6KJQ X-Message-ID-Hash: HSFORPN3Z3E3DLMLGOTDKIMGKOBE6KJQ X-MailFrom: sjg@u-boot.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Heinrich Schuchardt , Simon Glass X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 09/15] boot: Support rescanning the global bootmeths List-Id: Discussion and patches related to U-Boot Concept Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Simon Glass Add the logic to scan through the global bootmeths for every new bootdev, in preparation for allowing global bootmeths to select where in the hunter ordering they go. Use a new bootmeth_glob_allowed() function to check if a bootmeth is allowed, ensuring that each can run at most once. For now this has no actual effect, since the global bootmeths are unconditionally processed at the start, with iter->methods_done being updated to include all of them. Therefore when scanning again, no unprocessed global bootmeths will be found. Signed-off-by: Simon Glass --- boot/bootflow.c | 90 ++++++++++++++++++++++++++++++++++++++++++++-- include/bootflow.h | 5 +++ 2 files changed, 93 insertions(+), 2 deletions(-) diff --git a/boot/bootflow.c b/boot/bootflow.c index a91d76c6baf..51e6ad6dd86 100644 --- a/boot/bootflow.c +++ b/boot/bootflow.c @@ -245,19 +245,81 @@ static void scan_next_in_uclass(struct udevice **devp) *devp = dev; } +/** + * bootmeth_glob_allowed() - Check if a global bootmeth is usable at this point + * + * @iter: Bootflow iterator being used + * Return: true if the global bootmeth has not already been used + */ +static bool bootmeth_glob_allowed(struct bootflow_iter *iter, int meth_seq) +{ + struct udevice *meth = iter->method_order[meth_seq]; + bool done = iter->methods_done & BIT(meth_seq); + + log_debug("considering glob '%s': done %d\n", meth->name, done); + + /* if this one has already been used, try the next */ + if (done) + return false; + + return true; +} + +/** + * next_glob_bootmeth() - Find the next global bootmeth to use + * + * Scans the global bootmeths to find the first unused one whose priority has + * been reached. If found, iter->cur_method and iter->method are set up and + * doing_global is set to true + * + * @iter: Bootflow iterator being used + * Return 0 if found, -ENOENT if no more global bootmeths are available + */ +static int next_glob_bootmeth(struct bootflow_iter *iter) +{ + log_debug("rescan global bootmeths have_global %d\n", + iter->have_global); + if (IS_ENABLED(CONFIG_BOOTMETH_GLOBAL) && iter->have_global) { + int i; + + /* rescan the global bootmeths */ + log_debug("first_glob_method %d num_methods %d methods_done %x\n", + iter->first_glob_method, iter->num_methods, + iter->methods_done); + for (i = iter->first_glob_method; i < iter->num_methods; i++) { + if (bootmeth_glob_allowed(iter, i)) { + iter->cur_method = i; + iter->method = iter->method_order[i]; + iter->doing_global = true; + iter->dev = NULL; + return 0; + } + } + } + + return -ENOENT; +} + /** * prepare_bootdev() - Get ready to use a bootdev * * @iter: Bootflow iterator being used * @dev: UCLASS_BOOTDEV device to use * @method_flags: Method flag for the bootdev + * @check_global: true to check global bootmeths before processing @dev * Return 0 if OK, -ve if the bootdev failed to probe */ static int prepare_bootdev(struct bootflow_iter *iter, struct udevice *dev, - int method_flags) + int method_flags, bool check_global) { int ret; + if (check_global && !next_glob_bootmeth(iter)) { + iter->pending_bootdev = dev; + iter->pending_method_flags = method_flags; + return 0; + } + /* * Probe the bootdev. This does not probe any attached block device, * since they are siblings @@ -308,6 +370,30 @@ static int iter_incr(struct bootflow_iter *iter) iter->num_methods = iter->first_glob_method; iter->doing_global = false; + /* + * we've come to the end, so see if we should use a pending + * bootdev from when we decided to rescan the global bootmeths + */ + if (iter->pending_bootdev) { + int meth_flags = iter->pending_method_flags; + + dev = iter->pending_bootdev; + iter->pending_bootdev = NULL; + iter->pending_method_flags = 0; + + ret = prepare_bootdev(iter, dev, meth_flags, false); + if (ret) + return log_msg_ret("ipb", ret); + + iter->cur_method = 0; + iter->method = iter->method_order[iter->cur_method]; + + log_debug("-> using pending bootdev '%s' method '%s'\n", + dev->name, iter->method->name); + + return 0; + } + /* * Don't move to the next dev as we haven't tried this * one yet! @@ -418,7 +504,7 @@ static int iter_incr(struct bootflow_iter *iter) if (ret) bootflow_iter_set_dev(iter, NULL, 0); else - ret = prepare_bootdev(iter, dev, method_flags); + ret = prepare_bootdev(iter, dev, method_flags, true); } /* if there are no more bootdevs, give up */ diff --git a/include/bootflow.h b/include/bootflow.h index 051158780e6..5ef0f4b61d3 100644 --- a/include/bootflow.h +++ b/include/bootflow.h @@ -280,6 +280,9 @@ enum { * (enum bootflow_meth_flags_t) * @methods_done: indicates which methods have been processed, one bit for * each method in @method_order[] + * @pending_bootdev: if non-NULL, bootdev which will be used when the global + * bootmeths are done + * @pending_method_flags: method flags which will be used with @pending_bootdev */ struct bootflow_iter { int flags; @@ -303,6 +306,8 @@ struct bootflow_iter { bool doing_global; int method_flags; uint methods_done; + struct udevice *pending_bootdev; + int pending_method_flags; }; /**