Coverage Report

Created: 2026-03-11 06:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/u-boot/cmd/ufetch.c
Line
Count
Source
1
// SPDX-License-Identifier: GPL-2.0
2
3
/* Small "fetch" utility for U-Boot */
4
5
#ifdef CONFIG_ARM64
6
#include <asm/system.h>
7
#endif
8
#include <dm/device.h>
9
#include <dm/uclass-internal.h>
10
#include <display_options.h>
11
#include <mmc.h>
12
#include <time.h>
13
#include <asm/global_data.h>
14
#include <cli.h>
15
#include <command.h>
16
#include <dm/ofnode.h>
17
#include <env.h>
18
#include <rand.h>
19
#include <vsprintf.h>
20
#include <linux/delay.h>
21
#include <linux/kernel.h>
22
#include <version.h>
23
24
DECLARE_GLOBAL_DATA_PTR;
25
26
0
#define LINE_WIDTH 40
27
#define BLUE "\033[34m"
28
#define YELLOW "\033[33m"
29
#define BOLD "\033[1m"
30
0
#define RESET "\033[0m"
31
static const char * const logo_lines[] = {
32
  BLUE BOLD "                  ......::......                   ",
33
  BLUE BOLD "             ...::::::::::::::::::...              ",
34
  BLUE BOLD "          ..::::::::::::::::::::::::::..           ",
35
  BLUE BOLD "        .::::.:::::::::::::::...::::.::::.         ",
36
  BLUE BOLD "      .::::::::::::::::::::..::::::::::::::.       ",
37
  BLUE BOLD "    .::.:::::::::::::::::::" YELLOW "=*%#*" BLUE "::::::::::.::.     ",
38
  BLUE BOLD "   .:::::::::::::::::....." YELLOW "*%%*-" BLUE ":....::::::::::.    ",
39
  BLUE BOLD "  .:.:::...:::::::::.:-" YELLOW "===##*---==-" BLUE "::::::::::.:.   ",
40
  BLUE BOLD " .::::..::::........" YELLOW "-***#****###****-" BLUE "...::::::.:.  ",
41
  BLUE BOLD " ::.:.-" YELLOW "+***+=" BLUE "::-" YELLOW "=+**#%%%%%%%%%%%%###*= " BLUE "-::...::::. ",
42
  BLUE BOLD ".:.::-" YELLOW "*****###%%%%%%%%%%%%%%%%%%%%%%%%%%#*=" BLUE ":..:::: ",
43
  BLUE BOLD ".::" YELLOW "##" BLUE ":" YELLOW "***#%%%%%%#####%%%%%%%####%%%%%####%%%*" BLUE "-.::. ",
44
  BLUE BOLD ":.:" YELLOW "#%" BLUE "::" YELLOW "*%%%%%%%#*****##%%%#*****##%%##*****#%%+" BLUE ".::.",
45
  BLUE BOLD ".::" YELLOW "**==#%%%%%%%##****#%%%%##****#%%%%#****###%%" BLUE ":.. ",
46
  BLUE BOLD "..:" YELLOW "#%" BLUE "::" YELLOW "*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%#%%%%%+ " BLUE ".:.",
47
  BLUE BOLD " ::" YELLOW "##" BLUE ":" YELLOW "+**#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%* " BLUE "-.:: ",
48
  BLUE BOLD " ..::-" YELLOW "#****#%#%%%%%%%%%%%%%%%%%%%%%%%%%%#*=" BLUE "-..::.  ",
49
  BLUE BOLD "  ...:=" YELLOW "*****=" BLUE "::-" YELLOW "=+**###%%%%%%%%###**+=  " BLUE "--:...:::  ",
50
  BLUE BOLD "   .::.::--:........::::::--::::::......::::::.    ",
51
  BLUE BOLD "    .::.....::::::::::...........:::::::::.::.     ",
52
  BLUE BOLD "      .::::::::::::::::::::::::::::::::::::.       ",
53
  BLUE BOLD "        .::::.::::::::::::::::::::::.::::.         ",
54
  BLUE BOLD "          ..::::::::::::::::::::::::::..           ",
55
  BLUE BOLD "             ...::::::::::::::::::...              ",
56
  BLUE BOLD "                  ......::......                   ",
57
};
58
59
enum output_lines {
60
  FIRST,
61
  SECOND,
62
  KERNEL,
63
  SYSINFO,
64
  HOST,
65
  UPTIME,
66
  IP,
67
  CMDS,
68
  CONSOLES,
69
  FEATURES,
70
  RELOCATION,
71
  CORES,
72
  MEMORY,
73
  STORAGE,
74
75
  /* Up to 10 storage devices... Should be enough for anyone right? */
76
  _LAST_LINE = (STORAGE + 10),
77
0
#define LAST_LINE (_LAST_LINE - 1UL)
78
};
79
80
/*
81
 * TODO/ideas:
82
 * - Refactor to not use a for loop
83
 * - Handle multiple network interfaces
84
 * - Include stats about number of bound/probed devices
85
 * - Show U-Boot's size and malloc usage, fdt size, etc.
86
 */
87
88
89
static int do_ufetch(struct cmd_tbl *cmdtp, int flag, int argc,
90
         char *const argv[])
91
0
{
92
0
  int num_lines = max((size_t)LAST_LINE + 1, ARRAY_SIZE(logo_lines));
93
0
  const char *model, *compatible;
94
0
  char *ipaddr;
95
0
  int n_cmds, n_cpus = 0, compatlen;
96
0
  size_t size = 0;
97
0
  ofnode np;
98
0
  bool skip_ascii = false;
99
100
0
  if (argc > 1 && strcmp(argv[1], "-n") == 0) {
101
0
    skip_ascii = true;
102
0
    num_lines = LAST_LINE;
103
0
  }
104
105
0
  for (int line = 0; line < num_lines; line++) {
106
0
    if (!skip_ascii) {
107
0
      if (line < ARRAY_SIZE(logo_lines))
108
0
        printf("%s  ", logo_lines[line]);
109
0
      else
110
0
        printf("%*c  ", LINE_WIDTH, ' ');
111
0
    }
112
0
    switch (line) {
113
0
    case FIRST:
114
0
      compatible = ofnode_read_string(ofnode_root(), "compatible");
115
0
      if (!compatible)
116
0
        compatible = "unknown";
117
0
      printf(RESET "%s\n", compatible);
118
0
      compatlen = strlen(compatible);
119
0
      break;
120
0
    case SECOND:
121
0
      for (int j = 0; j < compatlen; j++)
122
0
        putc('-');
123
0
      putc('\n');
124
0
      break;
125
0
    case KERNEL:
126
0
      printf("Kernel:" RESET " %s\n", U_BOOT_VERSION);
127
0
      break;
128
0
    case SYSINFO:
129
0
      printf("Config:" RESET " %s_defconfig\n", CONFIG_SYS_CONFIG_NAME);
130
0
      break;
131
0
    case HOST:
132
0
      model = ofnode_read_string(ofnode_root(), "model");
133
0
      if (model)
134
0
        printf("Host:" RESET " %s\n", model);
135
0
      break;
136
0
    case UPTIME:
137
0
      printf("Uptime:" RESET " %ld seconds\n", get_timer(0) / 1000);
138
0
      break;
139
0
    case IP:
140
0
      ipaddr = env_get("ipaddr");
141
0
      if (!ipaddr)
142
0
        ipaddr = "none";
143
0
      printf("IP Address:" RESET " %s", ipaddr);
144
0
      ipaddr = env_get("ipv6addr");
145
0
      if (ipaddr)
146
0
        printf(", %s\n", ipaddr);
147
0
      else
148
0
        putc('\n');
149
0
      break;
150
0
    case CMDS:
151
0
      n_cmds = ll_entry_count(struct cmd_tbl, cmd);
152
0
      printf("Commands:" RESET " %d (help)\n", n_cmds);
153
0
      break;
154
0
    case CONSOLES:
155
0
      printf("Consoles:" RESET " %s", env_get("stdout"));
156
0
      if (gd->baudrate)
157
0
        printf(" (%d baud)", gd->baudrate);
158
0
      putc('\n');
159
0
      break;
160
0
    case FEATURES:
161
0
      printf("Features:" RESET " ");
162
0
      if (IS_ENABLED(CONFIG_NET))
163
0
        printf("Net");
164
0
      if (IS_ENABLED(CONFIG_EFI_LOADER))
165
0
        printf(", EFI");
166
0
      if (IS_ENABLED(CONFIG_CMD_CAT))
167
0
        printf(", cat :3");
168
#ifdef CONFIG_ARM64
169
      switch (current_el()) {
170
      case 2:
171
        printf(", VMs");
172
        break;
173
      case 3:
174
        printf(", full control!");
175
        break;
176
      }
177
#endif
178
0
      printf("\n");
179
0
      break;
180
0
    case RELOCATION:
181
0
      if (gd->flags & GD_FLG_SKIP_RELOC)
182
0
        printf("Relocated:" RESET " no\n");
183
0
      else
184
0
        printf("Relocated:" RESET " to %#011lx\n", gd->relocaddr);
185
0
      break;
186
0
    case CORES:
187
0
      ofnode_for_each_subnode(np, ofnode_path("/cpus")) {
188
0
        if (ofnode_name_eq(np, "cpu"))
189
0
          n_cpus++;
190
0
      }
191
0
      printf("CPU: " RESET CONFIG_SYS_ARCH " (%d cores, 1 in use)\n", n_cpus);
192
0
      break;
193
0
    case MEMORY:
194
0
      for (int j = 0; j < CONFIG_NR_DRAM_BANKS && gd->bd->bi_dram[j].size; j++)
195
0
        size += gd->bd->bi_dram[j].size;
196
0
      printf("Memory:" RESET " ");
197
0
      print_size(size, "\n");
198
0
      break;
199
0
    case STORAGE:
200
0
    default: {
201
0
#ifdef CONFIG_BLK
202
0
      struct udevice *dev;
203
0
      struct blk_desc *desc;
204
0
      int ret;
205
206
0
      ret = uclass_find_device_by_seq(UCLASS_BLK, line - STORAGE, &dev);
207
0
      if (!ret && dev) {
208
0
        desc = dev_get_uclass_plat(dev);
209
0
        size = desc->lba * desc->blksz;
210
0
        printf("%4s %d: " RESET, blk_get_uclass_name(desc->uclass_id),
211
0
          desc->lun);
212
0
        if (size)
213
0
          print_size(size, "");
214
0
        else
215
0
          printf("No media");
216
0
      } else if (ret == -ENODEV && (skip_ascii || line > ARRAY_SIZE(logo_lines))) {
217
0
        break;
218
0
      }
219
0
#endif
220
0
      printf("\n");
221
0
    }
222
0
    }
223
0
  }
224
225
0
  printf(RESET "\n\n");
226
227
0
  return 0;
228
0
}
229
230
U_BOOT_CMD(ufetch, 2, 1, do_ufetch,
231
     "U-Boot fetch utility",
232
     "Print information about your device.\n"
233
     "    -n    Don't print the ASCII logo"
234
);