"Das U-Boot" Source Tree
at master 234 lines 6.7 kB view raw
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 24DECLARE_GLOBAL_DATA_PTR; 25 26#define LINE_WIDTH 40 27#define BLUE "\033[34m" 28#define YELLOW "\033[33m" 29#define BOLD "\033[1m" 30#define RESET "\033[0m" 31static 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 59enum 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 89static 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 230U_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);