1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * 'bootmeth' command 4 * 5 * Copyright 2021 Google LLC 6 * Written by Simon Glass <sjg@chromium.org> 7 */ 8 9#include <common.h> 10#include <bootdev.h> 11#include <bootmeth.h> 12#include <bootstd.h> 13#include <command.h> 14#include <dm.h> 15#include <malloc.h> 16#include <dm/uclass-internal.h> 17 18static int do_bootmeth_list(struct cmd_tbl *cmdtp, int flag, int argc, 19 char *const argv[]) 20{ 21 struct bootstd_priv *std; 22 struct udevice *dev; 23 bool use_order; 24 bool all = false; 25 int ret; 26 int i; 27 28 if (argc > 1 && *argv[1] == '-') { 29 all = strchr(argv[1], 'a'); 30 argc--; 31 argv++; 32 } 33 34 ret = bootstd_get_priv(&std); 35 if (ret) { 36 printf("Cannot get bootstd (err=%d)\n", ret); 37 return CMD_RET_FAILURE; 38 } 39 40 printf("Order Seq Name Description\n"); 41 printf("----- --- ------------------ ------------------\n"); 42 43 /* 44 * Use the ordering if we have one, so long as we are not trying to list 45 * all bootmethds 46 */ 47 use_order = std->bootmeth_count && !all; 48 if (use_order) 49 dev = std->bootmeth_order[0]; 50 else 51 ret = uclass_find_first_device(UCLASS_BOOTMETH, &dev); 52 53 for (i = 0; dev;) { 54 struct bootmeth_uc_plat *ucp = dev_get_uclass_plat(dev); 55 int order = i; 56 57 /* 58 * With the -a flag we may list bootdevs that are not in the 59 * ordering. Find their place in the order 60 */ 61 if (all && std->bootmeth_count) { 62 int j; 63 64 /* Find the position of this bootmeth in the order */ 65 order = -1; 66 for (j = 0; j < std->bootmeth_count; j++) { 67 if (std->bootmeth_order[j] == dev) 68 order = j; 69 } 70 } 71 72 if (ucp->flags & BOOTMETHF_GLOBAL) 73 printf("%5s", "glob"); 74 else if (order == -1) 75 printf("%5s", "-"); 76 else 77 printf("%5x", order); 78 printf(" %3x %-19.19s %s\n", dev_seq(dev), dev->name, 79 ucp->desc); 80 i++; 81 if (use_order) 82 dev = std->bootmeth_order[i]; 83 else 84 uclass_find_next_device(&dev); 85 } 86 printf("----- --- ------------------ ------------------\n"); 87 printf("(%d bootmeth%s)\n", i, i != 1 ? "s" : ""); 88 89 return 0; 90} 91 92static int do_bootmeth_order(struct cmd_tbl *cmdtp, int flag, int argc, 93 char *const argv[]) 94{ 95 int ret; 96 97 ret = bootmeth_set_order(argv[1]); 98 if (ret) { 99 printf("Failed (err=%d)\n", ret); 100 return CMD_RET_FAILURE; 101 } 102 env_set("bootmeths", argv[1]); 103 104 return 0; 105} 106 107U_BOOT_LONGHELP(bootmeth, 108 "list [-a] - list available bootmeths (-a all)\n" 109 "bootmeth order [<bd> ...] - select bootmeth order / subset to use"); 110 111U_BOOT_CMD_WITH_SUBCMDS(bootmeth, "Boot methods", bootmeth_help_text, 112 U_BOOT_SUBCMD_MKENT(list, 2, 1, do_bootmeth_list), 113 U_BOOT_SUBCMD_MKENT(order, CONFIG_SYS_MAXARGS, 1, do_bootmeth_order)); 114