
The normal situation with bootstd is that a bootflow is created from a bootmeth. In some cases, a script or user-command may cause an image to be loaded. To deal with this, add the concept of an ad-hoc bootflow. This can be used to record information about manually loaded images.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: - Add a new patch supporting ad-hoc bootflows
boot/bootstd-uclass.c | 44 +++++++++++++++++++++++++++++++++++++++++++ cmd/bootflow.c | 5 +++-- include/bootflow.h | 3 ++- include/bootstd.h | 19 +++++++++++++++++++ 4 files changed, 68 insertions(+), 3 deletions(-)
diff --git a/boot/bootstd-uclass.c b/boot/bootstd-uclass.c index 8c0fd4e63c3..9bee73ead58 100644 --- a/boot/bootstd-uclass.c +++ b/boot/bootstd-uclass.c @@ -7,6 +7,8 @@ */
#include <alist.h> +#include <blk.h> +#include <bootdev.h> #include <bootflow.h> #include <bootstd.h> #include <dm.h> @@ -161,11 +163,53 @@ int bootstd_get_priv(struct bootstd_priv **stdp) return 0; }
+int bootstd_img_add(struct blk_desc *desc, int part, const char *fname, + enum bootflow_img_t type, ulong addr, ulong size) +{ + struct udevice *bootdev = NULL; + struct bootstd_priv *std; + struct bootflow *bflow, bflow_s; + int ret; + + ret = bootstd_get_priv(&std); + if (ret) + return ret; + + if (desc) { + ret = bootdev_get_from_blk(desc->bdev, &bootdev); + if (ret) + return log_msg_ret("iad", ret); + } + + bflow = alist_getw(&std->bootflows, std->adhoc_bflow, struct bootflow); + if (!bflow) { + bflow = &bflow_s; + + bootflow_init(bflow, bootdev, NULL); + bflow->name = strdup("ad-hoc"); + if (!bflow->name) + return log_msg_ret("ian", -ENOMEM); + } + + if (!bootflow_img_add(bflow, fname, type, addr, size)) + return log_msg_ret("iaf", -ENOMEM); + + if (bflow == &bflow_s) { + ret = bootstd_add_bootflow(bflow); + if (ret < 0) + return log_msg_ret("iab", ret); + std->adhoc_bflow = ret; + } + + return 0; +} + static int bootstd_probe(struct udevice *dev) { struct bootstd_priv *std = dev_get_priv(dev);
alist_init_struct(&std->bootflows, struct bootflow); + std->adhoc_bflow = -1;
return 0; } diff --git a/cmd/bootflow.c b/cmd/bootflow.c index f88995a478f..5668a0c9b19 100644 --- a/cmd/bootflow.c +++ b/cmd/bootflow.c @@ -68,7 +68,8 @@ static void report_bootflow_err(struct bootflow *bflow, int err) static void show_bootflow(int index, struct bootflow *bflow, bool errors) { printf("%3x %-11s %-6s %-9.9s %4x %-25.25s %s\n", index, - bflow->method->name, bootflow_state_get_name(bflow->state), + bflow->method ? bflow->method->name : "(none)", + bootflow_state_get_name(bflow->state), bflow->dev ? dev_get_uclass_name(dev_get_parent(bflow->dev)) : "(none)", bflow->part, bflow->name, bflow->fname ?: ""); if (errors) @@ -388,7 +389,7 @@ static int do_bootflow_info(struct cmd_tbl *cmdtp, int flag, int argc, printf("Name: %s\n", bflow->name); printf("Device: %s\n", bflow->dev->name); printf("Block dev: %s\n", bflow->blk ? bflow->blk->name : "(none)"); - printf("Method: %s\n", bflow->method->name); + printf("Method: %s\n", bflow->method ? bflow->method->name : "(none)"); printf("State: %s\n", bootflow_state_get_name(bflow->state)); printf("Partition: %d\n", bflow->part); printf("Subdir: %s\n", bflow->subdir ? bflow->subdir : "(none)"); diff --git a/include/bootflow.h b/include/bootflow.h index 480cf8a5af1..d9045bc3dae 100644 --- a/include/bootflow.h +++ b/include/bootflow.h @@ -68,7 +68,8 @@ enum bootflow_flags_t { * @fs_type: Filesystem type (FS_TYPE...) if this is fixed by the media, else 0. * For example, the sandbox host-filesystem bootdev sets this to * FS_TYPE_SANDBOX - * @method: Bootmethod device used to perform the boot and read files + * @method: Bootmethod device used to perform the boot and read files; NULL for + * ad-hoc bootflows * @name: Name of bootflow (allocated) * @state: Current state (enum bootflow_state_t) * @subdir: Subdirectory to fetch files from (with trailing /), or NULL if none diff --git a/include/bootstd.h b/include/bootstd.h index 3398e48e88b..c39058c0787 100644 --- a/include/bootstd.h +++ b/include/bootstd.h @@ -10,10 +10,12 @@ #define __bootstd_h
#include <alist.h> +#include <bootflow.h> #include <dm/ofnode_decl.h> #include <linux/list.h> #include <linux/types.h>
+struct blk_desc; struct udevice;
/** @@ -33,6 +35,7 @@ struct udevice; * @cur_bootflow: Currently selected bootflow (for commands) * @bootflows: (struct bootflow) Global list of all bootflows across all * bootdevs + * @adhoc_bflow: Index of ad-hoc bootflow in bootflows (-1 if none) * @bootmeth_count: Number of bootmeth devices in @bootmeth_order * @bootmeth_order: List of bootmeth devices to use, in order, NULL-terminated * @vbe_bootmeth: Currently selected VBE bootmeth, NULL if none @@ -47,6 +50,7 @@ struct bootstd_priv { struct udevice *cur_bootdev; struct bootflow *cur_bootflow; struct alist bootflows; + int adhoc_bflow; int bootmeth_count; struct udevice **bootmeth_order; struct udevice *vbe_bootmeth; @@ -151,4 +155,19 @@ int bootstd_add_bootflow(struct bootflow *bflow); */ int bootstd_clear_bootflows_for_bootdev(struct udevice *dev);
+/** + * bootstd_img_add() - Add an image to the ad-hoc bootflow + * + * @desc: Block descriptor for the device from which the file was loaded, or + * NULL if not a block device + * @part: Partition number within the block device + * @fname: Filename of loaded file + * @type: File type, IH_TYPE_INVALID if not known + * @addr: Address where the file was loaded + * @size: Size of the file + * Return: 0 if OK, or -ve error code + */ +int bootstd_img_add(struct blk_desc *desc, int fs_type, const char *fname, + enum bootflow_img_t type, ulong addr, ulong size); + #endif