mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-12-02 17:41:08 +00:00
d9f48579dc
These are associated with the ethernet boot device but do not match its uclass name, so handle them as special cases. Provide a way to pass flags through with the bootdev so that we know how to process it. The flags are checked by the bootmeths, to ensure that only the selected bootmeth is used. While these both use the network device, they work quite differently. It is common to run only one of these, or to run PXE before DHCP. Provide bootflow flags to control which methods are used. Check these in the two bootmeths so that only the chosen one is used. Signed-off-by: Simon Glass <sjg@chromium.org>
154 lines
3.3 KiB
C
154 lines
3.3 KiB
C
// SPDX-License-Identifier: GPL-2.0+
|
|
/*
|
|
* 'bootdev' command
|
|
*
|
|
* Copyright 2021 Google LLC
|
|
* Written by Simon Glass <sjg@chromium.org>
|
|
*/
|
|
|
|
#include <common.h>
|
|
#include <bootdev.h>
|
|
#include <bootflow.h>
|
|
#include <bootstd.h>
|
|
#include <command.h>
|
|
#include <dm.h>
|
|
#include <dm/device-internal.h>
|
|
#include <dm/uclass-internal.h>
|
|
|
|
static int bootdev_check_state(struct bootstd_priv **stdp)
|
|
{
|
|
struct bootstd_priv *std;
|
|
int ret;
|
|
|
|
ret = bootstd_get_priv(&std);
|
|
if (ret)
|
|
return ret;
|
|
if (!std->cur_bootdev) {
|
|
printf("Please use 'bootdev select' first\n");
|
|
return -ENOENT;
|
|
}
|
|
*stdp = std;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int do_bootdev_list(struct cmd_tbl *cmdtp, int flag, int argc,
|
|
char *const argv[])
|
|
{
|
|
bool probe;
|
|
|
|
probe = argc >= 2 && !strcmp(argv[1], "-p");
|
|
bootdev_list(probe);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int do_bootdev_select(struct cmd_tbl *cmdtp, int flag, int argc,
|
|
char *const argv[])
|
|
{
|
|
struct bootstd_priv *std;
|
|
struct udevice *dev;
|
|
int ret;
|
|
|
|
ret = bootstd_get_priv(&std);
|
|
if (ret)
|
|
return CMD_RET_FAILURE;
|
|
if (argc < 2) {
|
|
std->cur_bootdev = NULL;
|
|
return 0;
|
|
}
|
|
if (bootdev_find_by_any(argv[1], &dev, NULL))
|
|
return CMD_RET_FAILURE;
|
|
|
|
std->cur_bootdev = dev;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int do_bootdev_info(struct cmd_tbl *cmdtp, int flag, int argc,
|
|
char *const argv[])
|
|
{
|
|
struct bootstd_priv *priv;
|
|
struct bootflow *bflow;
|
|
int ret, i, num_valid;
|
|
struct udevice *dev;
|
|
bool probe;
|
|
|
|
probe = argc >= 2 && !strcmp(argv[1], "-p");
|
|
|
|
ret = bootdev_check_state(&priv);
|
|
if (ret)
|
|
return CMD_RET_FAILURE;
|
|
|
|
dev = priv->cur_bootdev;
|
|
|
|
/* Count the number of bootflows, including how many are valid*/
|
|
num_valid = 0;
|
|
for (ret = bootdev_first_bootflow(dev, &bflow), i = 0;
|
|
!ret;
|
|
ret = bootdev_next_bootflow(&bflow), i++)
|
|
num_valid += bflow->state == BOOTFLOWST_READY;
|
|
|
|
/*
|
|
* Prove the device, if requested, otherwise assume that there is no
|
|
* error
|
|
*/
|
|
ret = 0;
|
|
if (probe)
|
|
ret = device_probe(dev);
|
|
|
|
printf("Name: %s\n", dev->name);
|
|
printf("Sequence: %d\n", dev_seq(dev));
|
|
printf("Status: %s\n", ret ? simple_itoa(ret) : device_active(dev) ?
|
|
"Probed" : "OK");
|
|
printf("Uclass: %s\n", dev_get_uclass_name(dev_get_parent(dev)));
|
|
printf("Bootflows: %d (%d valid)\n", i, num_valid);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int do_bootdev_hunt(struct cmd_tbl *cmdtp, int flag, int argc,
|
|
char *const argv[])
|
|
{
|
|
struct bootstd_priv *priv;
|
|
const char *spec = NULL;
|
|
bool list = false;
|
|
int ret = 0;
|
|
|
|
if (argc >= 2) {
|
|
if (!strcmp(argv[1], "-l"))
|
|
list = true;
|
|
else
|
|
spec = argv[1];
|
|
}
|
|
|
|
ret = bootstd_get_priv(&priv);
|
|
if (ret)
|
|
return ret;
|
|
if (list) {
|
|
bootdev_list_hunters(priv);
|
|
} else {
|
|
ret = bootdev_hunt(spec, true);
|
|
if (ret) {
|
|
printf("Failed (err=%dE)\n", ret);
|
|
|
|
return CMD_RET_FAILURE;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#ifdef CONFIG_SYS_LONGHELP
|
|
static char bootdev_help_text[] =
|
|
"list [-p] - list all available bootdevs (-p to probe)\n"
|
|
"bootdev hunt [-l|<spec>] - use hunt drivers to find bootdevs\n"
|
|
"bootdev select <bd> - select a bootdev by name | label | seq\n"
|
|
"bootdev info [-p] - show information about a bootdev (-p to probe)";
|
|
#endif
|
|
|
|
U_BOOT_CMD_WITH_SUBCMDS(bootdev, "Boot devices", bootdev_help_text,
|
|
U_BOOT_SUBCMD_MKENT(list, 2, 1, do_bootdev_list),
|
|
U_BOOT_SUBCMD_MKENT(hunt, 2, 1, do_bootdev_hunt),
|
|
U_BOOT_SUBCMD_MKENT(select, 2, 1, do_bootdev_select),
|
|
U_BOOT_SUBCMD_MKENT(info, 2, 1, do_bootdev_info));
|