From patchwork Mon Jan 19 20:41:11 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1648 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=1768855397; bh=XXgl/YcIxGlSEdWhgNuHluMBZhCTLbJRhwV7YwPJuow=; 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=gXUSupbnQENzvCxPNGANP6QdUi9eiZysrfYOz2HwBMeF65ZpqCP4IkQ3TodWjW9ab Z7/K3HI5YFmtEcq+acVe4lZ6oD6U3RFX7/stzGKALuTYkbtUDgGbSx603E3kj8nnl6 9F9BsUPA9MbncudWSysi3omQ7aDqe6JRwbqBcKtqZmLy5HFFveW+GUIQc7yyuKOC07 XbQ/UFWeHBU1VPXRVmBtpz93mYRcwm0aLw1TLsFxsFUrPVgEz/WiXqLAlHLkycT6z0 uk/JJybAhniARuoQHjwRfog/u88Pz5XyMu0bUvlxv5vXy7ViMgW8zoZqBBe3A/dqZZ uPsmMVA9+ryxQ== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 3FE6769525 for ; Mon, 19 Jan 2026 13:43:17 -0700 (MST) 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 c_QNzsbz_aPr for ; Mon, 19 Jan 2026 13:43:17 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1768855396; bh=XXgl/YcIxGlSEdWhgNuHluMBZhCTLbJRhwV7YwPJuow=; 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=ObFywdcfff4gJ2Wf7rqyDDZXmZ1BGmhALrqFAwF+GK5bUc0F+BYjJY3K4o1HeKAZR aIErrssj2coKXrW0aWq4eKYs+GV/DN+/3maqkt4s4Ogeh1+2PeZupkiWBqIxkQwpzo uCx2VzvXrOKG2TeBgK2e4ajlfOQiig1RTxkibX/cdHbyyWfHeKZ5Dp+RPLX56X63V3 Ibq5RspYsY52IPJ59nKB5t/AfKf3Pg9q82Ep7sPtUisoJqkAUgkLO9s5ImVYTtChXU 4EkjhZBRejG+6XdGxwwcG5kEHvJLeNzG69xul5mGU8ScKZFfTdkmaR+3pxOckXJUKy sLaLa9BQ2UxSg== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 38D7669504 for ; Mon, 19 Jan 2026 13:43:16 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1768855394; bh=fVxx5PosZ6mRpJzPLbgtfMYhqtL6CH/Sa6RdQHWKQY4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=r0W8KPwvKTlHdF+OygCUNXUkLmRLdvRp0q0owGSiKoGCN4sceiSyMk2P/3wg5Sr2M extZmnd3E9SaGSKuRlI2p76Et5wcyaqIyciyYBseZn1Ah/xaoeZYFcuxDYYVj6972b EWi9tSSO15KOXy37yHGV8BzMplWvFZ1pXv6YDVh+keFT6+lJu19HNTWi73/spbZOYt M6OU33dk8EaFyweKF4W1Rb267CEpzsrMHIKAUczU+CjIiZFVwiZvPYZChDteTb4Hcf JcLRoc35YYf7K6y4vRCUlwxPNvfc/YYdlH2stjhmxxisULD7AzFiyLhNtBPxty/bjB anHnTObxv2reQ== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 05C66693E3; Mon, 19 Jan 2026 13:43:14 -0700 (MST) 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 0d-VXQIupd_d; Mon, 19 Jan 2026 13:43:13 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1768855393; bh=D6HUbfOwJFaB0sBA1sTqO9C2E3pLnd6o+jQl7BEuUNA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=oA99oukDrQUasVZXHczEJSG+/x3byv/lLKxrx9K8PoEgXaFyAFucoCLcpO7Lw9PmE gI8w+HUbJW9sJpVuOPX2UszHGyii53c91vsrep5EewwSgTp4JFcmI+lC2uyvqan8oR p1hGFj5GNAgDri8fGgzSyckJP4O7oBzHH4/K8ZVK7vGBHonrKf5pQokRhFQwzAv+6S WXz6mXOtllJkyvLW/jcJPnjGByVZPDSAuoHput4zdMUI3E4hStfx3vpW0IiCZ9hCxu Ag5vv54jrMbPIQ9eyz/FmibWXyJ9OeSBkhN4nMdKRJX91NoWIuEItkXTxTn3wjXXSt V55wwuq6LrOUA== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id 4D758693BA; Mon, 19 Jan 2026 13:43:13 -0700 (MST) From: Simon Glass To: U-Boot Concept Date: Mon, 19 Jan 2026 13:41:11 -0700 Message-ID: <20260119204130.3972647-19-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260119204130.3972647-1-sjg@u-boot.org> References: <20260119204130.3972647-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: R7EHG4KDK6H6CTCKCTDBF3BM56IOBD7V X-Message-ID-Hash: R7EHG4KDK6H6CTCKCTDBF3BM56IOBD7V 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 , "Claude Opus 4 . 5" X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 18/27] expo: Add scene_chklog() for filtered logging 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 a helper function that checks the 'expo_log_filter' environment variable. If not set, all objects are logged. If set, it contains a comma-separated list of filters; only objects whose name contains one of the filter strings are logged. The feature is controlled by CONFIG_EXPO_LOG_FILTER, which is enabled by default for sandbox. Co-developed-by: Claude Opus 4.5 Signed-off-by: Simon Glass --- boot/Kconfig | 10 ++++++++++ boot/scene.c | 32 ++++++++++++++++++++++++++++++++ boot/scene_internal.h | 12 ++++++++++++ doc/develop/expo.rst | 27 +++++++++++++++++++++++++++ test/boot/expo.c | 37 +++++++++++++++++++++++++++++++++++++ 5 files changed, 118 insertions(+) diff --git a/boot/Kconfig b/boot/Kconfig index 7ff0dedb748..14b7ed573c9 100644 --- a/boot/Kconfig +++ b/boot/Kconfig @@ -1002,6 +1002,16 @@ config EXPO_TEST variable is set to 1. This is useful for debugging and performance analysis. +config EXPO_LOG_FILTER + bool "Enable expo log filter" + depends on EXPO + default y if SANDBOX + help + Enable the expo log filter. When enabled, the 'expo_log_filter' + environment variable can be set to filter log output by object name. + Only objects whose name contains the filter string are logged. This + is useful for debugging specific expo objects. + config BOOTMETH_SANDBOX def_bool y depends on SANDBOX diff --git a/boot/scene.c b/boot/scene.c index 3565bfd77de..9cade9aad41 100644 --- a/boot/scene.c +++ b/boot/scene.c @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -42,6 +43,37 @@ static const char *const scene_obj_type_names[] = { "textline", }; +bool scene_chklog(const char *name) +{ + const char *filter, *end, *p; + int len; + + if (!CONFIG_IS_ENABLED(EXPO_LOG_FILTER)) + return true; + + filter = env_get("expo_log_filter"); + if (!filter) + return true; + + /* Check each comma-separated filter */ + while (*filter) { + end = strchrnul(filter, ','); + len = end - filter; + + /* Check if this filter segment appears in name */ + for (p = name; *p; p++) { + if (!strncmp(p, filter, len)) + return true; + } + + if (!*end) + break; + filter = end + 1; + } + + return false; +} + int scene_new(struct expo *exp, const char *name, uint id, struct scene **scnp) { struct scene *scn; diff --git a/boot/scene_internal.h b/boot/scene_internal.h index db11f9c0f60..d3c67777cb1 100644 --- a/boot/scene_internal.h +++ b/boot/scene_internal.h @@ -613,6 +613,18 @@ int scene_calc_arrange(struct scene *scn, struct expo_arrange_info *arr); int scene_txt_generic_init(struct expo *exp, struct scene_txt_generic *gen, const char *name, uint str_id, const char *str); +/** + * scene_chklog() - Check if logging is enabled for an object + * + * This checks the 'expo_log_filter' environment variable. If not set, all + * objects are logged. If set, it contains a comma-separated list of filters; + * only objects whose name contains one of the filter strings are logged. + * + * @name: Object name to check + * Return: true if logging should happen, false to skip + */ +bool scene_chklog(const char *name); + /** * scene_flag_name() - Get the name of a scene flag * diff --git a/doc/develop/expo.rst b/doc/develop/expo.rst index fc642ed3696..7ef714be3da 100644 --- a/doc/develop/expo.rst +++ b/doc/develop/expo.rst @@ -605,6 +605,33 @@ These metrics help identify performance bottlenecks and verify that expo is operating efficiently. The timing information is particularly useful when optimizing display drivers or debugging slow rendering issues. +Log filter +~~~~~~~~~~ + +Expo supports filtering log output by object name, which is useful when +debugging specific objects. Set the ``expo_log_filter`` environment variable +to a substring that matches the object names you want to log. + +To enable log filtering:: + + => setenv expo_log_filter texted + => log filter-add -d console -A -c expo -l debug + +This shows debug logs only for objects whose name contains "texted". + +Multiple filters can be specified as a comma-separated list:: + + => setenv expo_log_filter menu,text + +This logs objects matching either "menu" or "text". + +Remove the filter to see all objects:: + + => setenv expo_log_filter + +This feature requires ``CONFIG_EXPO_LOG_FILTER`` which is enabled by default +for sandbox. + Writing expo tests ------------------ diff --git a/test/boot/expo.c b/test/boot/expo.c index 97b9bf82bb7..4febdf87cde 100644 --- a/test/boot/expo.c +++ b/test/boot/expo.c @@ -1260,6 +1260,43 @@ static int expo_scene_obj_type_name(struct unit_test_state *uts) } BOOTSTD_TEST(expo_scene_obj_type_name, 0); +/* Test scene_chklog() */ +static int expo_scene_chklog(struct unit_test_state *uts) +{ + /* Without filter, all objects should be logged */ + env_set("expo_log_filter", NULL); + ut_assert(scene_chklog("my-menu")); + ut_assert(scene_chklog("textline")); + + /* With a single filter, only matching objects should be logged */ + env_set("expo_log_filter", "menu"); + ut_assert(scene_chklog("my-menu")); + ut_assert(scene_chklog("menu-item")); + ut_assert(!scene_chklog("textline")); + ut_assert(!scene_chklog("other")); + + /* With comma-separated filters, any match should pass */ + env_set("expo_log_filter", "menu,text"); + ut_assert(scene_chklog("my-menu")); + ut_assert(scene_chklog("textline")); + ut_assert(scene_chklog("textedit")); + ut_assert(!scene_chklog("other")); + ut_assert(!scene_chklog("image")); + + /* Test with three filters */ + env_set("expo_log_filter", "menu,text,img"); + ut_assert(scene_chklog("my-menu")); + ut_assert(scene_chklog("textline")); + ut_assert(scene_chklog("img-logo")); + ut_assert(!scene_chklog("other")); + + /* Clear the filter */ + env_set("expo_log_filter", NULL); + + return 0; +} +BOOTSTD_TEST(expo_scene_chklog, 0); + /* Test scene_find_obj_within() */ static int expo_find_obj_within(struct unit_test_state *uts) {