1 // SPDX-License-Identifier: GPL-2.0
3 /* Small "fetch" utility for U-Boot */
6 #include <asm/system.h>
9 #include <dm/uclass-internal.h>
10 #include <display_options.h>
13 #include <asm/global_data.h>
16 #include <dm/ofnode.h>
20 #include <linux/delay.h>
21 #include <linux/kernel.h>
24 DECLARE_GLOBAL_DATA_PTR;
27 #define BLUE "\033[38;5;4m"
28 #define YELLOW "\033[38;5;11m"
29 #define BOLD "\033[1m"
30 #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 " ......::...... ",
75 /* Up to 10 storage devices... Should be enough for anyone right? */
76 _LAST_LINE = (STORAGE + 10),
77 #define LAST_LINE (_LAST_LINE - 1UL)
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.
89 static int do_ufetch(struct cmd_tbl *cmdtp, int flag, int argc,
92 int num_lines = max(LAST_LINE + 1, ARRAY_SIZE(logo_lines));
93 const char *model, *compatible;
95 int n_cmds, n_cpus = 0, ret, compatlen;
99 struct blk_desc *desc;
100 bool skip_ascii = false;
102 if (argc > 1 && strcmp(argv[1], "-n") == 0) {
104 num_lines = LAST_LINE;
107 for (int line = 0; line < num_lines; line++) {
109 if (line < ARRAY_SIZE(logo_lines))
110 printf("%s ", logo_lines[line]);
112 printf("%*c ", LINE_WIDTH, ' ');
116 compatible = ofnode_read_string(ofnode_root(), "compatible");
118 compatible = "unknown";
119 printf(RESET "%s\n", compatible);
120 compatlen = strlen(compatible);
123 for (int j = 0; j < compatlen; j++)
128 printf("Kernel:" RESET " %s\n", U_BOOT_VERSION);
131 printf("Config:" RESET " %s_defconfig\n", CONFIG_SYS_CONFIG_NAME);
134 model = ofnode_read_string(ofnode_root(), "model");
136 printf("Host:" RESET " %s\n", model);
139 printf("Uptime:" RESET " %ld seconds\n", get_timer(0) / 1000);
142 ipaddr = env_get("ipaddr");
145 printf("IP Address:" RESET " %s", ipaddr);
146 ipaddr = env_get("ipv6addr");
148 printf(", %s\n", ipaddr);
153 n_cmds = ll_entry_count(struct cmd_tbl, cmd);
154 printf("Commands:" RESET " %d (help)\n", n_cmds);
157 printf("Consoles:" RESET " %s", env_get("stdout"));
159 printf(" (%d baud)", gd->baudrate);
163 printf("Features:" RESET " ");
164 if (IS_ENABLED(CONFIG_NET))
166 if (IS_ENABLED(CONFIG_EFI_LOADER))
168 if (IS_ENABLED(CONFIG_CMD_CAT))
171 switch (current_el()) {
176 printf(", full control!");
183 if (gd->flags & GD_FLG_SKIP_RELOC)
184 printf("Relocated:" RESET " no\n");
186 printf("Relocated:" RESET " to %#011lx\n", gd->relocaddr);
189 ofnode_for_each_subnode(np, ofnode_path("/cpus")) {
190 if (ofnode_name_eq(np, "cpu"))
193 printf("CPU:" RESET " %d (1 in use)\n", n_cpus);
196 for (int j = 0; j < CONFIG_NR_DRAM_BANKS && gd->bd->bi_dram[j].size; j++)
197 size += gd->bd->bi_dram[j].size;
198 printf("Memory:" RESET " ");
199 print_size(size, "\n");
203 ret = uclass_find_device_by_seq(UCLASS_BLK, line - STORAGE, &dev);
205 desc = dev_get_uclass_plat(dev);
206 size = desc->lba * desc->blksz;
207 printf("%4s %d: " RESET, blk_get_uclass_name(desc->uclass_id),
210 print_size(size, "");
213 } else if (ret == -ENODEV && (skip_ascii || line > ARRAY_SIZE(logo_lines))) {
220 printf(RESET "\n\n");
225 U_BOOT_CMD(ufetch, 2, 1, do_ufetch,
226 "U-Boot fetch utility",
227 "Print information about your device.\n"
228 " -n Don't print the ASCII logo"