From patchwork Sat Mar 14 23:16:09 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1991 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=1773530275; bh=Wnl6BheaKIaVw6H39EoXuuSWPuLSoLikhrQDHbu5PDg=; 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=StC00afyqy/N/Lx/dMCv7IyRsNbGPW6buhmbBoLhF7ekf/CLWObU02FuFXQ4TEPB1 +kFwd9O770QEVDo4EI2c00bBsfB5hDOHwXZLv+Hkc07GPc1SbE0GK3UaY3gVjbJZ6I +HJG9lSqV0B7x89q8TKwNiSRtzSWDf6ISnICgXktKdpgqbKcAqCBT2Htf24DmRBS5t ZFCy0c28zY6XgLAHj7ncCcXASTCn1ox5ZFwl+ftS6pfCrvFFZHfhx5nhTlkx77mN1p CQSQh+SdXVBf6XL+ol6V1txfCLG4LL9kuUlE4Ncu7ncE9v+vLHM14pZJrE25ScB1sK I88ZMTVONs2iw== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id D4AF46A046 for ; Sat, 14 Mar 2026 17:17:55 -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 clDK163a3_gT for ; Sat, 14 Mar 2026 17:17:55 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1773530274; bh=Wnl6BheaKIaVw6H39EoXuuSWPuLSoLikhrQDHbu5PDg=; 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=YkNjhwdADaGNGd6mbYlwmCxmPquI8bnE5DRzdnB5FCCAPy6nPT4t1gFUN5q0lD98M jK0XI5pcW6GDg1nkv26ftkb4x0KZYa4tIaFM/TDthj+KIe2Egr6jQPwa4r98LUkz6c ATEpZq9W3KqpF5xkld+Qx1ZAXYdsRjQmMObZk3zzHamZidMJmYWRN34auFjeqhYAKa gQKJ0rwG6GMdfZdOVAIxuPR4gkEikIK2DgpOxa5DoJvdC4aIg13w1R0uLMeHPNf0Gz NPep4+uVXSNMXm67bwRtPMzbJHa6FropcvjTEeUyhed8bqBZDTU64yX2JTTkky5Xrl oy85UDIm4ZDow== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 70D796A04A for ; Sat, 14 Mar 2026 17:17:54 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1773530270; bh=E8ByFbCmhicnqLrATLL8nDsYiesK5D0WvOW2AaJWan0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hLiTXjBXaZlDOmcfZSyeB75SsGg1z5RQvM+8Rp8KisN1ivgVPPmwKBbv2/pdhitdX oOaqhp00KdlbWVLSxOMc5c9Q1Gk2nvI9MjZ1N8jB7B8uiEbdjEvPU/WMo6P3S9Y5tL dcQg4nd2Pf9jb5vRHoHsqBOC7odo8KNt6rv8MCMgfw9nnROQ2vbIPE5I2I9hz/TW0J eD6q1CEE+Ku0bonI/xW+Zi1hpDlcveIXYREGNIuTlwYfIocApIsZANehBR+hfwn7RE WmWwfVJxqfGTn82m3DkE4nZPzAWBof4vx2oresDuqMNz/1/ucvlP/Sa4OgDFp/zP8B nl3RPCcST0JUw== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 05A506A05A; Sat, 14 Mar 2026 17:17:50 -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 Ak-HJh8gke44; Sat, 14 Mar 2026 17:17:49 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1773530266; bh=FhBa3ZNThi9cn9zU6W3A6LrdOnYezCa1Y3Y+zMf/cSc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DgPIvduAyDrKFJwhb5peKqPpUGMrYTLDd50Ww64lj5puXFfstamoBqiklC7TOq8L7 S44V0TlwTnNFQQWtepoCjOknqgrmYy6GZheub3rs761lnP6CPmbs+guO7EFo89Z2Zp FjLCUBaasRJK1nqM2/JwLZgFVqQ7DSN1BJJ1Dtdhg7CSGjRQAqVWPLXoWvYPuyAI8a TbtEnKubNRqOj+xdcBy094b0+fmn2+zm94+uE7uYh53/IlTnbGBvoP++rkFIj5mUrn vqta1R7TE866nB4ZiQwXAGQNPknQXy+dRy86uX50rug8wEfb++NzJzT3OvVxFUAF+e Jn7xO2hO7PNtw== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id 1A61D6A04A; Sat, 14 Mar 2026 17:17:46 -0600 (MDT) From: Simon Glass To: U-Boot Concept Date: Sat, 14 Mar 2026 17:16:09 -0600 Message-ID: <20260314231618.338113-19-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260314231618.338113-1-sjg@u-boot.org> References: <20260314231618.338113-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: OQGYOKSTCDUKM6SBME2MMTMLBMOHS47I X-Message-ID-Hash: OQGYOKSTCDUKM6SBME2MMTMLBMOHS47I 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 18/19] bootstage: Add save/restore subcommands 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 'bootstage save' and 'bootstage restore' subcommands behind a new BOOTSTAGE_SAVE Kconfig (default y when UNIT_TEST is enabled). These store and retrieve the record count via $bootstage_count. Some commands (e.g. bootm) add bootstage records with unique IDs. In a pytest session with many tests, these accumulate and fill the bootstage table. The new commands allow the test framework to save the count before a test and restore it afterwards. Also add inline stubs for bootstage_get_rec_count() and bootstage_set_rec_count() when BOOTSTAGE is disabled, along with a test and command documentation. Signed-off-by: Simon Glass --- boot/Kconfig | 11 +++++ cmd/bootstage.c | 28 ++++++++++++ doc/usage/cmd/bootstage.rst | 86 +++++++++++++++++++++++++++++++++++++ doc/usage/index.rst | 1 + include/bootstage.h | 9 ++++ test/cmd/bootstage.c | 24 +++++++++++ 6 files changed, 159 insertions(+) create mode 100644 doc/usage/cmd/bootstage.rst diff --git a/boot/Kconfig b/boot/Kconfig index cd66060f4db..d9d5214ca0f 100644 --- a/boot/Kconfig +++ b/boot/Kconfig @@ -1479,6 +1479,17 @@ config BOOTSTAGE_FDT Code in the Linux kernel can find this in /proc/devicetree. +config BOOTSTAGE_SAVE + bool "Allow saving and restoring the bootstage record count" + depends on BOOTSTAGE + default y if UNIT_TEST + help + Provide 'bootstage save' and 'bootstage restore' subcommands + which store and retrieve the record count via the bootstage_count + environment variable. These are used by Python tests to prevent + records from accumulating across tests and filling the bootstage + table. + config BOOTSTAGE_STASH bool "Stash the boot timing information in memory before booting OS" depends on BOOTSTAGE diff --git a/cmd/bootstage.c b/cmd/bootstage.c index 5c6d5a3ab45..ce69097b96c 100644 --- a/cmd/bootstage.c +++ b/cmd/bootstage.c @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -62,8 +63,31 @@ static int do_bootstage_stash(struct cmd_tbl *cmdtp, int flag, int argc, } #endif +static int __maybe_unused do_bootstage_save(struct cmd_tbl *cmdtp, int flag, + int argc, char *const argv[]) +{ + env_set_hex("bootstage_count", bootstage_get_rec_count()); + + return 0; +} + +static int __maybe_unused do_bootstage_restore(struct cmd_tbl *cmdtp, int flag, + int argc, char *const argv[]) +{ + ulong count = env_get_hex("bootstage_count", 0); + + if (count) + bootstage_set_rec_count(count); + + return 0; +} + static struct cmd_tbl cmd_bootstage_sub[] = { U_BOOT_CMD_MKENT(report, 2, 1, do_bootstage_report, "", ""), +#if IS_ENABLED(CONFIG_BOOTSTAGE_SAVE) + U_BOOT_CMD_MKENT(save, 1, 0, do_bootstage_save, "", ""), + U_BOOT_CMD_MKENT(restore, 1, 0, do_bootstage_restore, "", ""), +#endif #if IS_ENABLED(CONFIG_BOOTSTAGE_STASH) U_BOOT_CMD_MKENT(stash, 4, 0, do_bootstage_stash, "", ""), U_BOOT_CMD_MKENT(unstash, 4, 0, do_bootstage_stash, "", ""), @@ -95,6 +119,10 @@ U_BOOT_CMD(bootstage, 4, 1, do_boostage, "Boot stage command", " - check boot progress and timing\n" "report - Print a report\n" +#if IS_ENABLED(CONFIG_BOOTSTAGE_SAVE) + "save - Save record count to $bootstage_count\n" + "restore - Restore record count from $bootstage_count\n" +#endif #if IS_ENABLED(CONFIG_BOOTSTAGE_STASH) "stash [ []] - Stash data into memory\n" "unstash [ []] - Unstash data from memory\n" diff --git a/doc/usage/cmd/bootstage.rst b/doc/usage/cmd/bootstage.rst new file mode 100644 index 00000000000..44069e6fedd --- /dev/null +++ b/doc/usage/cmd/bootstage.rst @@ -0,0 +1,86 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +.. index:: + single: bootstage (command) + +bootstage command +================= + +Synopsis +-------- + +:: + + bootstage report + bootstage save + bootstage restore + bootstage stash [ []] + bootstage unstash [ []] + +Description +----------- + +The *bootstage* command provides access to U-Boot's boot-timing records. + +bootstage report + Print a report of all bootstage records, showing the timestamp and elapsed + time for each stage. + +bootstage save + Save the current record count to the *bootstage_count* environment + variable. This can be used to snapshot the bootstage state before an + operation that adds records. + +bootstage restore + Restore the record count from *bootstage_count*, discarding any records + added since the last save. This is used by the Python test framework to + prevent records from accumulating across tests. + +bootstage stash + Stash bootstage data into memory at the given address and size. + Only available when ``CONFIG_BOOTSTAGE_STASH`` is enabled. + +bootstage unstash + Read back previously stashed bootstage data from memory. + Only available when ``CONFIG_BOOTSTAGE_STASH`` is enabled. + +Configuration +------------- + +The *bootstage* command is available when ``CONFIG_BOOTSTAGE`` is enabled. + +CONFIG_BOOTSTAGE_REPORT + Enable output of a boot-time report before booting the OS. + +CONFIG_BOOTSTAGE_RECORD_COUNT + Number of bootstage records to store (default 50). + +CONFIG_BOOTSTAGE_SAVE + Enable the *save* and *restore* subcommands. Default y when + ``CONFIG_UNIT_TEST`` is set. + +CONFIG_BOOTSTAGE_STASH + Enable the *stash* and *unstash* subcommands for passing bootstage + data to the OS via memory. + +Example +------- + +:: + + => bootstage report + Timer summary in microseconds (8 records): + Mark Elapsed Stage + 0 0 reset + 0 0 board_init_f + 29,743 29,743 board_init_r + 52,918 23,175 eth_common_init + 53,007 89 eth_initialize + + Accumulated time: + 1,235 dm_f + 670 of_live + 5,621 dm_r + + => bootstage save + => bootstage restore diff --git a/doc/usage/index.rst b/doc/usage/index.rst index 05e1828bf01..ecf0ba16700 100644 --- a/doc/usage/index.rst +++ b/doc/usage/index.rst @@ -49,6 +49,7 @@ Shell commands cmd/bootm cmd/bootmenu cmd/bootmeth + cmd/bootstage cmd/bootstd cmd/bootz cmd/button diff --git a/include/bootstage.h b/include/bootstage.h index da57f9b81c5..30858cbfb3f 100644 --- a/include/bootstage.h +++ b/include/bootstage.h @@ -519,6 +519,15 @@ static inline int bootstage_init(bool first) return 0; } +static inline uint bootstage_get_rec_count(void) +{ + return 0; +} + +static inline void bootstage_set_rec_count(uint count) +{ +} + #endif /* ENABLE_BOOTSTAGE */ /* helpers for SPL */ diff --git a/test/cmd/bootstage.c b/test/cmd/bootstage.c index dee4a0671fa..29df4725d1f 100644 --- a/test/cmd/bootstage.c +++ b/test/cmd/bootstage.c @@ -30,3 +30,27 @@ static int cmd_bootstage_report(struct unit_test_state *uts) return 0; } CMD_TEST(cmd_bootstage_report, UTF_CONSOLE); + +static int cmd_bootstage_save_restore(struct unit_test_state *uts) +{ + uint count; + + count = bootstage_get_rec_count(); + ut_assert(count > 0); + + /* Save the current count */ + ut_assertok(run_command("bootstage save", 0)); + ut_assert_console_end(); + + /* Add a new record and check the count grows by one */ + bootstage_mark_name(BOOTSTAGE_ID_USER + 60, "test_save_restore"); + ut_asserteq(count + 1, bootstage_get_rec_count()); + + /* Restore should bring the count back */ + ut_assertok(run_command("bootstage restore", 0)); + ut_assert_console_end(); + ut_asserteq(count, bootstage_get_rec_count()); + + return 0; +} +CMD_TEST(cmd_bootstage_save_restore, UTF_CONSOLE);