]> Git Repo - u-boot.git/blob - cmd/ufetch.c
Merge branch 'master' of https://source.denx.de/u-boot/custodians/u-boot-sh
[u-boot.git] / cmd / ufetch.c
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 #define LINE_WIDTH 40
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 "                  ......::......                   ",
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 #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 {
92         int num_lines = max((size_t)LAST_LINE + 1, ARRAY_SIZE(logo_lines));
93         const char *model, *compatible;
94         char *ipaddr;
95         int n_cmds, n_cpus = 0, compatlen;
96         size_t size;
97         ofnode np;
98         bool skip_ascii = false;
99
100         if (argc > 1 && strcmp(argv[1], "-n") == 0) {
101                 skip_ascii = true;
102                 num_lines = LAST_LINE;
103         }
104
105         for (int line = 0; line < num_lines; line++) {
106                 if (!skip_ascii) {
107                         if (line < ARRAY_SIZE(logo_lines))
108                                 printf("%s  ", logo_lines[line]);
109                         else
110                                 printf("%*c  ", LINE_WIDTH, ' ');
111                 }
112                 switch (line) {
113                 case FIRST:
114                         compatible = ofnode_read_string(ofnode_root(), "compatible");
115                         if (!compatible)
116                                 compatible = "unknown";
117                         printf(RESET "%s\n", compatible);
118                         compatlen = strlen(compatible);
119                         break;
120                 case SECOND:
121                         for (int j = 0; j < compatlen; j++)
122                                 putc('-');
123                         putc('\n');
124                         break;
125                 case KERNEL:
126                         printf("Kernel:" RESET " %s\n", U_BOOT_VERSION);
127                         break;
128                 case SYSINFO:
129                         printf("Config:" RESET " %s_defconfig\n", CONFIG_SYS_CONFIG_NAME);
130                         break;
131                 case HOST:
132                         model = ofnode_read_string(ofnode_root(), "model");
133                         if (model)
134                                 printf("Host:" RESET " %s\n", model);
135                         break;
136                 case UPTIME:
137                         printf("Uptime:" RESET " %ld seconds\n", get_timer(0) / 1000);
138                         break;
139                 case IP:
140                         ipaddr = env_get("ipaddr");
141                         if (!ipaddr)
142                                 ipaddr = "none";
143                         printf("IP Address:" RESET " %s", ipaddr);
144                         ipaddr = env_get("ipv6addr");
145                         if (ipaddr)
146                                 printf(", %s\n", ipaddr);
147                         else
148                                 putc('\n');
149                         break;
150                 case CMDS:
151                         n_cmds = ll_entry_count(struct cmd_tbl, cmd);
152                         printf("Commands:" RESET " %d (help)\n", n_cmds);
153                         break;
154                 case CONSOLES:
155                         printf("Consoles:" RESET " %s", env_get("stdout"));
156                         if (gd->baudrate)
157                                 printf(" (%d baud)", gd->baudrate);
158                         putc('\n');
159                         break;
160                 case FEATURES:
161                         printf("Features:" RESET " ");
162                         if (IS_ENABLED(CONFIG_NET))
163                                 printf("Net");
164                         if (IS_ENABLED(CONFIG_EFI_LOADER))
165                                 printf(", EFI");
166                         if (IS_ENABLED(CONFIG_CMD_CAT))
167                                 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                         printf("\n");
179                         break;
180                 case RELOCATION:
181                         if (gd->flags & GD_FLG_SKIP_RELOC)
182                                 printf("Relocated:" RESET " no\n");
183                         else
184                                 printf("Relocated:" RESET " to %#011lx\n", gd->relocaddr);
185                         break;
186                 case CORES:
187                         ofnode_for_each_subnode(np, ofnode_path("/cpus")) {
188                                 if (ofnode_name_eq(np, "cpu"))
189                                         n_cpus++;
190                         }
191                         printf("CPU: " RESET CONFIG_SYS_ARCH " (%d cores, 1 in use)\n", n_cpus);
192                         break;
193                 case MEMORY:
194                         for (int j = 0; j < CONFIG_NR_DRAM_BANKS && gd->bd->bi_dram[j].size; j++)
195                                 size += gd->bd->bi_dram[j].size;
196                         printf("Memory:" RESET " ");
197                         print_size(size, "\n");
198                         break;
199                 case STORAGE:
200                 default: {
201 #ifdef CONFIG_BLK
202                         struct udevice *dev;
203                         struct blk_desc *desc;
204                         int ret;
205
206                         ret = uclass_find_device_by_seq(UCLASS_BLK, line - STORAGE, &dev);
207                         if (!ret && dev) {
208                                 desc = dev_get_uclass_plat(dev);
209                                 size = desc->lba * desc->blksz;
210                                 printf("%4s %d: " RESET, blk_get_uclass_name(desc->uclass_id),
211                                         desc->lun);
212                                 if (size)
213                                         print_size(size, "");
214                                 else
215                                         printf("No media");
216                         } else if (ret == -ENODEV && (skip_ascii || line > ARRAY_SIZE(logo_lines))) {
217                                 break;
218                         }
219 #endif
220                         printf("\n");
221                 }
222                 }
223         }
224
225         printf(RESET "\n\n");
226
227         return 0;
228 }
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 );
This page took 0.039797 seconds and 4 git commands to generate.