From patchwork Sun Mar 22 23:57:12 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 2046 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=1774223883; bh=Wdcp0yNwk9MjJ9ZwkDxWuzgpIKRr4JkcJY1HIIzTs/s=; 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=FbF3ticPyqmJyhGquGui5Qd6y/ZxagLPNWbB514+9dpLit9wRa7fX4/Gh6G3Xryq4 vGQIttMWQxJRv4ugHtOhaSzO6l/NwDHYrxn6BWP8xIwm0QU1wsDGE7HFyww8xP56md 88iEl2+/K6oidfEnDXI5wO+qkbZdsEscQMPb1lFt9g7QAyPw01iXyD2OOQ83kwX59w 25cAXhMA5Zuu/u+5xjdBQz1My0wa7mU27wO6UAFyx1tugsvwhSbwEV0PfiM17ptub6 XLg0ROJwOGHB1bIdB2/GDTtGesm/O/maHDxT+/ldQ0a0wJ9Az8WpFlHTZNmwZj3neU KhqJvDjHxjWXQ== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 808316A1D7 for ; Sun, 22 Mar 2026 17:58:03 -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 CWXB-O4Pm_Ae for ; Sun, 22 Mar 2026 17:58:03 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774223883; bh=Wdcp0yNwk9MjJ9ZwkDxWuzgpIKRr4JkcJY1HIIzTs/s=; 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=FbF3ticPyqmJyhGquGui5Qd6y/ZxagLPNWbB514+9dpLit9wRa7fX4/Gh6G3Xryq4 vGQIttMWQxJRv4ugHtOhaSzO6l/NwDHYrxn6BWP8xIwm0QU1wsDGE7HFyww8xP56md 88iEl2+/K6oidfEnDXI5wO+qkbZdsEscQMPb1lFt9g7QAyPw01iXyD2OOQ83kwX59w 25cAXhMA5Zuu/u+5xjdBQz1My0wa7mU27wO6UAFyx1tugsvwhSbwEV0PfiM17ptub6 XLg0ROJwOGHB1bIdB2/GDTtGesm/O/maHDxT+/ldQ0a0wJ9Az8WpFlHTZNmwZj3neU KhqJvDjHxjWXQ== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 621976A0CA for ; Sun, 22 Mar 2026 17:58:03 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774223879; bh=RuhfGCgQ9X08W2Ko8Wa4DOVxzoTA/zhs6BeEmn+alNs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=i186KmwWX/FnZPqEfOkkko/xx1heX5ICNxdjEMtmd7JmiLHOFK2AddVaMc+LSuOkC sSKiZVIjAarFkPEq+ER1mAQR2P2WNL1Padm4gleaN6GN8TIifzxgk5Rp7laWMDRG0F twBYyRsht9PvNQ50+kcl3yVWFW58zUJ8u1Syft6cIieY/Hep47iq7SV1kRCrhTiIHV NDO7kHgMToRw6ZmDNaPiXWh7q6+xRSnBh9kRed6QstgXxyRWZ4pLADBq18Ii2XffJ6 ee7nU4oGnNZacHvoWzEYrYNIK7BPMfwBRXSpj+ZDEZtUU0KoUM75pO3NRZfGWLyeJI MkdBEBJy1kkjQ== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id F125F6A0CA; Sun, 22 Mar 2026 17:57:59 -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 L63eUHS4URyl; Sun, 22 Mar 2026 17:57:59 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1774223868; bh=EeaTzSCPAdu8i4Bo05lMSOfjghVvoyEiOnLKpoOMGnM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=PCChWWuzHg1/luIDh2Y9ic5SFHLqCrQ48JLL4Y2892YIv0j2Jxg6w0ZTo2jGu9g2Z Hao7A9p6Kd2fH1pBiABvf3p1X/HJaQcNaDYnMYg/oUZSP7fNgDrlqPj1hYEI6L2wZ8 TFBg0XTLVhoFBm7v5LzD9idx7q1o5biakOuJuizSm9h1CDNbZDzUeUGDUaqEGdf2oe n1xHlwescQHRa3T6GePuoih4MrR8Tcj02MV2+MenEk7+7KCrryQO0GBUaO1xDVozio 4AB5Z4iloZIJXp0XeFF4aG/yo4mvg73hioHVp0q0CDXs+l0gJqQS/+toToYv5suKly dx/eIX0AjGM+Q== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id 961B96A1DD; Sun, 22 Mar 2026 17:57:48 -0600 (MDT) From: Simon Glass To: U-Boot Concept Date: Sun, 22 Mar 2026 17:57:12 -0600 Message-ID: <20260322235719.1729267-15-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260322235719.1729267-1-sjg@u-boot.org> References: <20260322235719.1729267-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: 66PK65OFF2KWFIODPQMTRCBD7PPHZIBR X-Message-ID-Hash: 66PK65OFF2KWFIODPQMTRCBD7PPHZIBR 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: Simon Glass X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 14/14] extlinux: Convert pxe_context to an alist with bootmeth_id lookup 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 Replace the single struct pxe_context in extlinux_priv with an alist of contexts, one per extlinux.conf file. Use bflow->bootmeth_id so that boot and read_all can locate the correct context from the alist. Add extlinux_get_ctx() in ext_pxe_common.c which returns an existing context by bootmeth_id or allocates a new one. This ensures read_all and boot share the same context, preserving the label state set up by pxe_probe(). Add extlinux_bootmeth_probe() and update extlinux_bootmeth_remove() for alist lifecycle management, used by both extlinux and PXE drivers. The VBE driver uses its own priv struct and continues with local contexts. Signed-off-by: Simon Glass --- boot/bootmeth_extlinux.c | 34 +++++++++++++++++++++++++++++----- boot/bootmeth_pxe.c | 15 +++++++++++++-- boot/ext_pxe_common.c | 22 ++++++++++++++++++++++ boot/vbe_abrec_os.c | 2 +- include/extlinux.h | 32 +++++++++++++++++++++++++++++--- 5 files changed, 94 insertions(+), 11 deletions(-) diff --git a/boot/bootmeth_extlinux.c b/boot/bootmeth_extlinux.c index ca9120c3f99..286d176ae20 100644 --- a/boot/bootmeth_extlinux.c +++ b/boot/bootmeth_extlinux.c @@ -218,8 +218,13 @@ static int extlinux_read_bootflow(struct udevice *dev, struct bootflow *bflow) static int extlinux_local_boot(struct udevice *dev, struct bootflow *bflow) { struct extlinux_priv *priv = dev_get_priv(dev); + struct pxe_context *ctx; - return extlinux_boot(dev, bflow, &priv->ctx, extlinux_getfile, true, + ctx = extlinux_get_ctx(priv, bflow); + if (!ctx) + return log_msg_ret("ctx", -ENOMEM); + + return extlinux_boot(dev, bflow, ctx, extlinux_getfile, true, bflow->fname, false); } @@ -227,19 +232,37 @@ static int extlinux_local_boot(struct udevice *dev, struct bootflow *bflow) static int extlinux_local_read_all(struct udevice *dev, struct bootflow *bflow) { struct extlinux_priv *priv = dev_get_priv(dev); + struct pxe_context *ctx; + + ctx = extlinux_get_ctx(priv, bflow); + if (!ctx) + return log_msg_ret("ctx", -ENOMEM); - return extlinux_read_all(dev, bflow, &priv->ctx, extlinux_getfile, + return extlinux_read_all(dev, bflow, ctx, extlinux_getfile, true, bflow->fname); } #endif +int extlinux_bootmeth_probe(struct udevice *dev) +{ + struct extlinux_priv *priv = dev_get_priv(dev); + + alist_init_struct(&priv->ctxs, struct pxe_context); + + return 0; +} + int extlinux_bootmeth_remove(struct udevice *dev) { struct extlinux_priv *priv = dev_get_priv(dev); + struct pxe_context *ctx; - if (priv->ctx.cfg) - pxe_menu_uninit(priv->ctx.cfg); - pxe_destroy_ctx(&priv->ctx); + alist_for_each(ctx, &priv->ctxs) { + if (ctx->cfg) + pxe_menu_uninit(ctx->cfg); + pxe_destroy_ctx(ctx); + } + alist_uninit(&priv->ctxs); return 0; } @@ -278,6 +301,7 @@ U_BOOT_DRIVER(bootmeth_1extlinux) = { .of_match = extlinux_bootmeth_ids, .ops = &extlinux_bootmeth_ops, .bind = extlinux_bootmeth_bind, + .probe = extlinux_bootmeth_probe, .remove = extlinux_bootmeth_remove, .plat_auto = sizeof(struct extlinux_plat), .priv_auto = sizeof(struct extlinux_priv), diff --git a/boot/bootmeth_pxe.c b/boot/bootmeth_pxe.c index 772acc9107d..cc2a415f3c4 100644 --- a/boot/bootmeth_pxe.c +++ b/boot/bootmeth_pxe.c @@ -146,8 +146,13 @@ static int extlinux_pxe_read_file(struct udevice *dev, struct bootflow *bflow, static int extlinux_pxe_boot(struct udevice *dev, struct bootflow *bflow) { struct extlinux_priv *priv = dev_get_priv(dev); + struct pxe_context *ctx; - return extlinux_boot(dev, bflow, &priv->ctx, extlinux_pxe_getfile, + ctx = extlinux_get_ctx(priv, bflow); + if (!ctx) + return log_msg_ret("ctx", -ENOMEM); + + return extlinux_boot(dev, bflow, ctx, extlinux_pxe_getfile, false, bflow->subdir, false); } @@ -155,8 +160,13 @@ static int extlinux_pxe_boot(struct udevice *dev, struct bootflow *bflow) static int extlinux_pxe_read_all(struct udevice *dev, struct bootflow *bflow) { struct extlinux_priv *priv = dev_get_priv(dev); + struct pxe_context *ctx; + + ctx = extlinux_get_ctx(priv, bflow); + if (!ctx) + return log_msg_ret("ctx", -ENOMEM); - return extlinux_read_all(dev, bflow, &priv->ctx, + return extlinux_read_all(dev, bflow, ctx, extlinux_pxe_getfile, false, bflow->subdir); } #endif @@ -193,6 +203,7 @@ U_BOOT_DRIVER(bootmeth_zpxe) = { .of_match = extlinux_bootmeth_pxe_ids, .ops = &extlinux_bootmeth_pxe_ops, .bind = extlinux_bootmeth_pxe_bind, + .probe = extlinux_bootmeth_probe, .remove = extlinux_bootmeth_remove, .plat_auto = sizeof(struct extlinux_plat), .priv_auto = sizeof(struct extlinux_priv), diff --git a/boot/ext_pxe_common.c b/boot/ext_pxe_common.c index 5a4b6455a53..8a59b29ead8 100644 --- a/boot/ext_pxe_common.c +++ b/boot/ext_pxe_common.c @@ -75,6 +75,28 @@ int extlinux_set_property(struct udevice *dev, const char *property, return 0; } +struct pxe_context *extlinux_get_ctx(struct extlinux_priv *priv, + struct bootflow *bflow) +{ + struct pxe_context *ctx; + + /* Return existing context if one was already allocated */ + if (bflow->bootmeth_id >= 0) { + ctx = alist_getw(&priv->ctxs, bflow->bootmeth_id, + struct pxe_context); + if (ctx) + return ctx; + } + + /* Allocate a new one */ + ctx = alist_add_placeholder(&priv->ctxs); + if (!ctx) + return NULL; + bflow->bootmeth_id = priv->ctxs.count - 1; + + return ctx; +} + static int extlinux_setup(struct udevice *dev, struct bootflow *bflow, pxe_getfile_func getfile, bool allow_abs_path, const char *bootfile, struct pxe_context *ctx) diff --git a/boot/vbe_abrec_os.c b/boot/vbe_abrec_os.c index 9d0136b059b..9b41dcbf303 100644 --- a/boot/vbe_abrec_os.c +++ b/boot/vbe_abrec_os.c @@ -288,5 +288,5 @@ U_BOOT_DRIVER(vbe_abrec_os) = { .bind = bootmeth_vbe_abrec_os_bind, .probe = bootmeth_vbe_abrec_os_probe, .priv_auto = sizeof(struct abrec_priv), - .plat_auto = sizeof(struct extlinux_plat) + .plat_auto = sizeof(struct extlinux_plat), }; diff --git a/include/extlinux.h b/include/extlinux.h index 8630a8e3dc7..bad901cc3e6 100644 --- a/include/extlinux.h +++ b/include/extlinux.h @@ -36,22 +36,48 @@ struct extlinux_plat { /** * struct extlinux_priv - private runtime data for this bootmeth * - * @ctx: holds the PXE context + * @ctxs: list of parsed PXE contexts (alist of struct pxe_context), one per + * extlinux.conf file found during scanning */ struct extlinux_priv { - struct pxe_context ctx; + struct alist ctxs; }; +/** + * extlinux_bootmeth_probe() - Probe function for extlinux-based bootmeths + * + * Initialises the context alist in extlinux_priv. Must be called from the + * probe function of any driver that uses extlinux_priv. + * + * @dev: Bootmethod device + * Return: 0 if OK + */ +int extlinux_bootmeth_probe(struct udevice *dev); + /** * extlinux_bootmeth_remove() - Remove function for extlinux-based bootmeths * - * Frees the PXE context. Shared by extlinux and PXE drivers. + * Frees all cached PXE contexts in the alist. * * @dev: Bootmethod device * Return: 0 if OK */ int extlinux_bootmeth_remove(struct udevice *dev); +/** + * extlinux_get_ctx() - Get or allocate a PXE context for a bootflow + * + * If bflow->bootmeth_id already points to a valid context (e.g. from a + * prior read_all), return it. Otherwise allocate a new context in the + * alist and store its index in bflow->bootmeth_id. + * + * @priv: Private data for this bootmeth + * @bflow: Bootflow to get context for + * Return: Context, or NULL on allocation failure + */ +struct pxe_context *extlinux_get_ctx(struct extlinux_priv *priv, + struct bootflow *bflow); + /** * extlinux_set_property() - set an extlinux property *