From 66a864441287506a7a2adfa85b75f650c6233b98 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 22 Oct 2024 06:29:40 +0200 Subject: [PATCH] wip --- boot/bootstd-uclass.c | 48 ++++++++++++++++++++++++++++++++++++++++++- cmd/bootflow.c | 7 ++++--- fs/fs.c | 16 +++++++++++++++ include/bootflow.h | 6 ++++-- include/bootstd.h | 23 ++++++++++++++++++++- 5 files changed, 93 insertions(+), 7 deletions(-) diff --git a/boot/bootstd-uclass.c b/boot/bootstd-uclass.c index 5675719ee84..8758a81c5a2 100644 --- a/boot/bootstd-uclass.c +++ b/boot/bootstd-uclass.c @@ -7,6 +7,8 @@ */ #include +#include +#include #include #include #include @@ -69,11 +71,12 @@ int bootstd_add_bootflow(struct bootflow *bflow) if (ret) return ret; + ret = std->bootflows.count; bflow = alist_add(&std->bootflows, *bflow); if (!bflow) return log_msg_ret("bf2", -ENOMEM); - return 0; + return ret; } int bootstd_clear_bootflows_for_bootdev(struct udevice *dev) @@ -160,11 +163,54 @@ int bootstd_get_priv(struct bootstd_priv **stdp) return 0; } +int bootstd_img_add(struct blk_desc *desc, int part, int fs_type, + 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 1c1146ce11e..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) @@ -208,7 +209,7 @@ static int do_bootflow_scan(struct cmd_tbl *cmdtp, int flag, int argc, if (!ret) num_valid++; ret = bootstd_add_bootflow(&bflow); - if (ret) { + if (ret < 0) { printf("Out of memory\n"); return CMD_RET_FAILURE; } @@ -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/fs/fs.c b/fs/fs.c index e2915e7cf79..4bfc9f14474 100644 --- a/fs/fs.c +++ b/fs/fs.c @@ -5,6 +5,7 @@ #define LOG_CATEGORY LOGC_CORE +#include #include #include #include @@ -732,12 +733,14 @@ int do_size(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[], int do_load(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[], int fstype) { + struct blk_desc *dev_desc; unsigned long addr; const char *addr_str; const char *filename; loff_t bytes; loff_t pos; loff_t len_read; + int dev_part, type; int ret; unsigned long time; char *ep; @@ -781,6 +784,11 @@ int do_load(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[], else pos = 0; + /* save globals before they are cleared */ + dev_desc = fs_dev_desc; + dev_part = fs_dev_part; + type = fs_type; + time = get_timer(0); ret = _fs_read(filename, addr, pos, bytes, 1, &len_read); time = get_timer(time); @@ -804,6 +812,14 @@ int do_load(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[], env_set_hex("fileaddr", addr); env_set_hex("filesize", len_read); + if (IS_ENABLED(CONFIG_BOOTSTD) && + bootstd_img_add(dev_desc, dev_part, type, filename, + (enum bootflow_img_t)IH_TYPE_INVALID, addr, + len_read)) { + log_err("Failed to record file\n"); + return CMD_RET_FAILURE; + } + return 0; } diff --git a/include/bootflow.h b/include/bootflow.h index 1fc0503c29c..74b4c554c8c 100644 --- a/include/bootflow.h +++ b/include/bootflow.h @@ -144,12 +144,14 @@ enum bootflow_img_t { * @type: Image type (IH_TYPE_...) * @addr: Address to which the image was loaded, 0 if not yet loaded * @size: Size of the image + * @fs_type: Filesystem where the file came from (FS_TYPE_ANY if not known) */ struct bootflow_img { char *fname; enum bootflow_img_t type; ulong addr; ulong size; + uint fs_type; }; /** @@ -163,7 +165,7 @@ struct bootflow_img { * * Internal flags: * @BOOTFLOWIF_SINGLE_DEV: (internal) Just scan one bootdev - * @BOOTFLOWIF_SKIP_GLOBAL: (internal) Don't scan global bootmeths +` * @BOOTFLOWIF_SKIP_GLOBAL: (internal) Don't scan global bootmeths * @BOOTFLOWIF_SINGLE_UCLASS: (internal) Keep scanning through all devices in * this uclass (used with things like "mmc") * @BOOTFLOWIF_SINGLE_MEDIA: (internal) Scan one media device in the uclass (used @@ -614,7 +616,7 @@ int bootflow_cmdline_auto(struct bootflow *bflow, const char *arg); */ const char *bootflow_img_type_name(enum bootflow_img_t type); -/* +/** * bootflow_get_seq() - Get the sequence number of a bootflow * * Bootflows are numbered by their position in the bootstd list. diff --git a/include/bootstd.h b/include/bootstd.h index c5b902372c3..a020d0667e3 100644 --- a/include/bootstd.h +++ b/include/bootstd.h @@ -10,10 +10,12 @@ #define __bootstd_h #include +#include #include #include #include +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; @@ -137,7 +141,7 @@ int bootstd_prog_boot(void); * since this function takes over ownership of these. This functions makes * a copy of @bflow itself (without allocating its fields again), so the * caller must dispose of the memory used by the @bflow pointer itself - * Return: 0 if OK, -ENOMEM if out of memory + * Return: element number in the list, if OK, -ENOMEM if out of memory */ int bootstd_add_bootflow(struct bootflow *bflow); @@ -151,4 +155,21 @@ 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 + * @fs_type: Filesystem type + * @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 part, int fs_type, + const char *fname, enum bootflow_img_t type, ulong addr, + ulong size); + #endif