diff options
author | Tom Rini <trini@konsulko.com> | 2025-01-15 17:34:26 -0600 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2025-01-15 19:27:14 -0600 |
commit | 178f6ecb21fe12ada74a9a1a08093c812b15eea5 (patch) | |
tree | 60dee6152b33cbd13f311875ce2fc8e9350a8c3d /boot/bootstd-uclass.c | |
parent | e26a9ac4c6900cac2fa043ac50a3a3c038f4505d (diff) | |
parent | a3d0fadca6b14f57477a4143334993daf52f89dc (diff) |
Merge patch series "bootstd: Support recording images"
Simon Glass <sjg@chromium.org> says:
This series provides a way to keep track of the images used in bootstd,
including the type of each image.
At present this is sort-of handled by struct bootflow but in quite an
ad-hoc way. The structure has become quite large and is hard to query.
Future work will be able to reduce its size.
Ultimately the 'bootflow info' command may change to also show images as
a list, but that is left for later, as this series is already fairly
long. So for now, just introduce the concept and adjust bootstd to use
it, with a simple command to list the images.
This series includes various alist enhancements, to make use of this new
data structure a little easier.
[trini: Drop patch 18 and 19 for now due to size considerations]
Link: https://lore.kernel.org/r/20241115231926.211999-1-sjg@chromium.org
Diffstat (limited to 'boot/bootstd-uclass.c')
-rw-r--r-- | boot/bootstd-uclass.c | 60 |
1 files changed, 54 insertions, 6 deletions
diff --git a/boot/bootstd-uclass.c b/boot/bootstd-uclass.c index fdb8d69e320..8c0fd4e63c3 100644 --- a/boot/bootstd-uclass.c +++ b/boot/bootstd-uclass.c @@ -6,6 +6,7 @@ * Written by Simon Glass <sjg@chromium.org> */ +#include <alist.h> #include <bootflow.h> #include <bootstd.h> #include <dm.h> @@ -42,13 +43,11 @@ static int bootstd_of_to_plat(struct udevice *dev) static void bootstd_clear_glob_(struct bootstd_priv *priv) { - while (!list_empty(&priv->glob_head)) { - struct bootflow *bflow; + struct bootflow *bflow; - bflow = list_first_entry(&priv->glob_head, struct bootflow, - glob_node); + alist_for_each(bflow, &priv->bootflows) bootflow_remove(bflow); - } + alist_empty(&priv->bootflows); } void bootstd_clear_glob(void) @@ -61,6 +60,44 @@ void bootstd_clear_glob(void) bootstd_clear_glob_(std); } +int bootstd_add_bootflow(struct bootflow *bflow) +{ + struct bootstd_priv *std; + int ret; + + ret = bootstd_get_priv(&std); + if (ret) + return ret; + + ret = std->bootflows.count; + bflow = alist_add(&std->bootflows, *bflow); + if (!bflow) + return log_msg_ret("bf2", -ENOMEM); + + return ret; +} + +int bootstd_clear_bootflows_for_bootdev(struct udevice *dev) +{ + struct bootstd_priv *std = bootstd_try_priv(); + struct bootflow *from, *to; + + /* if bootstd does not exist we cannot have any bootflows */ + if (!std) + return 0; + + /* Drop any bootflows that mention this dev */ + alist_for_each_filter(from, to, &std->bootflows) { + if (from->dev == dev) + bootflow_remove(from); + else + *to++ = *from; + } + alist_update_end(&std->bootflows, to); + + return 0; +} + static int bootstd_remove(struct udevice *dev) { struct bootstd_priv *priv = dev_get_priv(dev); @@ -100,6 +137,17 @@ const char *const *const bootstd_get_prefixes(struct udevice *dev) return std->prefixes ? std->prefixes : default_prefixes; } +struct bootstd_priv *bootstd_try_priv(void) +{ + struct udevice *dev; + + dev = uclass_try_first_device(UCLASS_BOOTSTD); + if (!dev || !device_active(dev)) + return NULL; + + return dev_get_priv(dev); +} + int bootstd_get_priv(struct bootstd_priv **stdp) { struct udevice *dev; @@ -117,7 +165,7 @@ static int bootstd_probe(struct udevice *dev) { struct bootstd_priv *std = dev_get_priv(dev); - INIT_LIST_HEAD(&std->glob_head); + alist_init_struct(&std->bootflows, struct bootflow); return 0; } |