From patchwork Tue Sep 30 23:25:46 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 460 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=1759274820; bh=cbpJnZsncmMMcHbX+iC7dhCUY9V4XHS9KWyuBPS3sUE=; 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=MiV5ARISj20F7Ft13Q10zhjM3+NJv4dhminjIKckC1csBL5qM36CF/5rl8hbgZimg U6q7EcKZc2a1mv5sYSlcG9vN2L/QAWpVIj33yM8fPWuvkEEZBsRzOxRwToyRYt939m 8AnHvCX+5dE6F6RAWrTb0Z+eYdalmEmHTwtLHM6GbTpN6V4P9EidbRY1wm3uPuF63K p0MgRZVWQZMNDxFNmJUCy5cH/fAneCdvhkPdyzOGmw/ou4uoUEHzWHrCLFy/COLOM9 wlxDpUrKNUinZxxNOmqxLjEsWEkZs5yxLoSlPyu2zkQNSLmE4DRSleAKjpuhvE6VWR c9W5xvJ6BV68A== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 1D60967E7F for ; Tue, 30 Sep 2025 17:27:00 -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 WjYVbJ6_FADp for ; Tue, 30 Sep 2025 17:27:00 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1759274820; bh=cbpJnZsncmMMcHbX+iC7dhCUY9V4XHS9KWyuBPS3sUE=; 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=MiV5ARISj20F7Ft13Q10zhjM3+NJv4dhminjIKckC1csBL5qM36CF/5rl8hbgZimg U6q7EcKZc2a1mv5sYSlcG9vN2L/QAWpVIj33yM8fPWuvkEEZBsRzOxRwToyRYt939m 8AnHvCX+5dE6F6RAWrTb0Z+eYdalmEmHTwtLHM6GbTpN6V4P9EidbRY1wm3uPuF63K p0MgRZVWQZMNDxFNmJUCy5cH/fAneCdvhkPdyzOGmw/ou4uoUEHzWHrCLFy/COLOM9 wlxDpUrKNUinZxxNOmqxLjEsWEkZs5yxLoSlPyu2zkQNSLmE4DRSleAKjpuhvE6VWR c9W5xvJ6BV68A== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 0C4A467E2E for ; Tue, 30 Sep 2025 17:27:00 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1759274818; bh=SiNdbAz13lZ/N/Rs/alhu6BCIRIM2KR8kQK6JdZ2t9o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=lC4fUgHGmHMlc/le/cUSPKhyK7jOzlWXlkrFwrgomwoC5pxDXQJaGu37n5bPNXUcc Ci4KTfwbe9osK+kyqicG2geHhAJpBKZONxqviiXSM7u3ZW1p4ZDv0mzTt2nsqHVTPo OUjHSbdnmgoFruCvojjB2S8Lv5ryaLTB7rTNegJR9MLqpO7Q+8VDmgcNkOzuTScuUv bXKwUcuELEHX9y9GFd7hM1hRkpO7Wjfj3zMPVj7fR/3UCnSIrOCvcn2VtMq1ETfkuh bq6mqRV9c2WmtIqQLKgLCiE08989m/1YPkf+HlRYY0toOQGeFFSX85Kbck6ZcpkeDl WvszMIYq9sznw== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 4834667B5E; Tue, 30 Sep 2025 17:26:58 -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 k26r4RoWQ-Ac; Tue, 30 Sep 2025 17:26:58 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1759274814; bh=Gsi9Ztef//pm0OwK0FbADvyN26x4D8PzwIdWZXHWHGM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=nkbEdhHDH7xBPl07tWeXJ/xs/eBMIW12I1g80KiAMqRfpQkQF1jApkZOuIHbVOQ1L 6Tnt0xVwuo69v5tnp/nvegDRh/0bJeB/G3WUpcEuCZgZRMNTR0qfudyYEChENCMHkE nrMfJxoIAJoOITtQKeSxWHmHI2/Z9PLZ86cUL/A7enmWEW0QGXCCxTUnPaX2ehBENB rLg9+VEoVxO/zozhu6511+vsA0+aN9Mi8hlc0DoQPtQbFSHrHA23ctz0EhCmjXUDDb jisRKekojpWx92qV33gNS0A+O9x1xpJzljiVonng0bSKZXQP6nObMokarH3uOkgw2v +eo8gKHffQ/dA== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id ECBE367E2E; Tue, 30 Sep 2025 17:26:53 -0600 (MDT) From: Simon Glass To: U-Boot Concept Date: Tue, 30 Sep 2025 17:25:46 -0600 Message-ID: <20250930232611.1564850-10-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250930232611.1564850-1-sjg@u-boot.org> References: <20250930232611.1564850-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: NSYMDWFQUDS2NKLPF6VVVDEUTOMN7KW4 X-Message-ID-Hash: NSYMDWFQUDS2NKLPF6VVVDEUTOMN7KW4 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 v2 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 --- (no changes since v1) 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 488cf7b9a7e..e6f99402d68 100644 --- a/boot/bootflow.c +++ b/boot/bootflow.c @@ -247,19 +247,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 @@ -310,6 +372,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! @@ -420,7 +506,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; }; /**