This commit is contained in:
Simon Glass
2024-10-22 06:29:40 +02:00
parent 1c52a50268
commit 66a8644412
5 changed files with 93 additions and 7 deletions

View File

@@ -7,6 +7,8 @@
*/
#include <alist.h>
#include <blk.h>
#include <bootdev.h>
#include <bootflow.h>
#include <bootstd.h>
#include <dm.h>
@@ -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;
}

View File

@@ -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)");

16
fs/fs.c
View File

@@ -5,6 +5,7 @@
#define LOG_CATEGORY LOGC_CORE
#include <bootstd.h>
#include <command.h>
#include <config.h>
#include <display_options.h>
@@ -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;
}

View File

@@ -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.

View File

@@ -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;
@@ -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