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