mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-14 08:54:36 +00:00

Currently, the 8-bit escapes are being used, which aren't supported by vidconsole_escape_char. Since the current usage maps directly to the 3-bit equivalents anyway, let's use those instead. With this change, the fetch output looks as fetching in the vidconsole as it does over serial! Signed-off-by: Sam Day <me@samcday.com> Tested-by: Alexey Minnekhanov <alexeymin@postmarketos.org> Tested-by: Ferass El Hafidi <funderscore@postmarketos.org>
234 lines
6.6 KiB
C
234 lines
6.6 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
|
|
/* Small "fetch" utility for U-Boot */
|
|
|
|
#ifdef CONFIG_ARM64
|
|
#include <asm/system.h>
|
|
#endif
|
|
#include <dm/device.h>
|
|
#include <dm/uclass-internal.h>
|
|
#include <display_options.h>
|
|
#include <mmc.h>
|
|
#include <time.h>
|
|
#include <asm/global_data.h>
|
|
#include <cli.h>
|
|
#include <command.h>
|
|
#include <dm/ofnode.h>
|
|
#include <env.h>
|
|
#include <rand.h>
|
|
#include <vsprintf.h>
|
|
#include <linux/delay.h>
|
|
#include <linux/kernel.h>
|
|
#include <version.h>
|
|
|
|
DECLARE_GLOBAL_DATA_PTR;
|
|
|
|
#define LINE_WIDTH 40
|
|
#define BLUE "\033[34m"
|
|
#define YELLOW "\033[33m"
|
|
#define BOLD "\033[1m"
|
|
#define RESET "\033[0m"
|
|
static const char * const logo_lines[] = {
|
|
BLUE BOLD " ......::...... ",
|
|
BLUE BOLD " ...::::::::::::::::::... ",
|
|
BLUE BOLD " ..::::::::::::::::::::::::::.. ",
|
|
BLUE BOLD " .::::.:::::::::::::::...::::.::::. ",
|
|
BLUE BOLD " .::::::::::::::::::::..::::::::::::::. ",
|
|
BLUE BOLD " .::.:::::::::::::::::::" YELLOW "=*%#*" BLUE "::::::::::.::. ",
|
|
BLUE BOLD " .:::::::::::::::::....." YELLOW "*%%*-" BLUE ":....::::::::::. ",
|
|
BLUE BOLD " .:.:::...:::::::::.:-" YELLOW "===##*---==-" BLUE "::::::::::.:. ",
|
|
BLUE BOLD " .::::..::::........" YELLOW "-***#****###****-" BLUE "...::::::.:. ",
|
|
BLUE BOLD " ::.:.-" YELLOW "+***+=" BLUE "::-" YELLOW "=+**#%%%%%%%%%%%%###*= " BLUE "-::...::::. ",
|
|
BLUE BOLD ".:.::-" YELLOW "*****###%%%%%%%%%%%%%%%%%%%%%%%%%%#*=" BLUE ":..:::: ",
|
|
BLUE BOLD ".::" YELLOW "##" BLUE ":" YELLOW "***#%%%%%%#####%%%%%%%####%%%%%####%%%*" BLUE "-.::. ",
|
|
BLUE BOLD ":.:" YELLOW "#%" BLUE "::" YELLOW "*%%%%%%%#*****##%%%#*****##%%##*****#%%+" BLUE ".::.",
|
|
BLUE BOLD ".::" YELLOW "**==#%%%%%%%##****#%%%%##****#%%%%#****###%%" BLUE ":.. ",
|
|
BLUE BOLD "..:" YELLOW "#%" BLUE "::" YELLOW "*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%#%%%%%+ " BLUE ".:.",
|
|
BLUE BOLD " ::" YELLOW "##" BLUE ":" YELLOW "+**#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%* " BLUE "-.:: ",
|
|
BLUE BOLD " ..::-" YELLOW "#****#%#%%%%%%%%%%%%%%%%%%%%%%%%%%#*=" BLUE "-..::. ",
|
|
BLUE BOLD " ...:=" YELLOW "*****=" BLUE "::-" YELLOW "=+**###%%%%%%%%###**+= " BLUE "--:...::: ",
|
|
BLUE BOLD " .::.::--:........::::::--::::::......::::::. ",
|
|
BLUE BOLD " .::.....::::::::::...........:::::::::.::. ",
|
|
BLUE BOLD " .::::::::::::::::::::::::::::::::::::. ",
|
|
BLUE BOLD " .::::.::::::::::::::::::::::.::::. ",
|
|
BLUE BOLD " ..::::::::::::::::::::::::::.. ",
|
|
BLUE BOLD " ...::::::::::::::::::... ",
|
|
BLUE BOLD " ......::...... ",
|
|
};
|
|
|
|
enum output_lines {
|
|
FIRST,
|
|
SECOND,
|
|
KERNEL,
|
|
SYSINFO,
|
|
HOST,
|
|
UPTIME,
|
|
IP,
|
|
CMDS,
|
|
CONSOLES,
|
|
FEATURES,
|
|
RELOCATION,
|
|
CORES,
|
|
MEMORY,
|
|
STORAGE,
|
|
|
|
/* Up to 10 storage devices... Should be enough for anyone right? */
|
|
_LAST_LINE = (STORAGE + 10),
|
|
#define LAST_LINE (_LAST_LINE - 1UL)
|
|
};
|
|
|
|
/*
|
|
* TODO/ideas:
|
|
* - Refactor to not use a for loop
|
|
* - Handle multiple network interfaces
|
|
* - Include stats about number of bound/probed devices
|
|
* - Show U-Boot's size and malloc usage, fdt size, etc.
|
|
*/
|
|
|
|
|
|
static int do_ufetch(struct cmd_tbl *cmdtp, int flag, int argc,
|
|
char *const argv[])
|
|
{
|
|
int num_lines = max((size_t)LAST_LINE + 1, ARRAY_SIZE(logo_lines));
|
|
const char *model, *compatible;
|
|
char *ipaddr;
|
|
int n_cmds, n_cpus = 0, compatlen;
|
|
size_t size;
|
|
ofnode np;
|
|
bool skip_ascii = false;
|
|
|
|
if (argc > 1 && strcmp(argv[1], "-n") == 0) {
|
|
skip_ascii = true;
|
|
num_lines = LAST_LINE;
|
|
}
|
|
|
|
for (int line = 0; line < num_lines; line++) {
|
|
if (!skip_ascii) {
|
|
if (line < ARRAY_SIZE(logo_lines))
|
|
printf("%s ", logo_lines[line]);
|
|
else
|
|
printf("%*c ", LINE_WIDTH, ' ');
|
|
}
|
|
switch (line) {
|
|
case FIRST:
|
|
compatible = ofnode_read_string(ofnode_root(), "compatible");
|
|
if (!compatible)
|
|
compatible = "unknown";
|
|
printf(RESET "%s\n", compatible);
|
|
compatlen = strlen(compatible);
|
|
break;
|
|
case SECOND:
|
|
for (int j = 0; j < compatlen; j++)
|
|
putc('-');
|
|
putc('\n');
|
|
break;
|
|
case KERNEL:
|
|
printf("Kernel:" RESET " %s\n", U_BOOT_VERSION);
|
|
break;
|
|
case SYSINFO:
|
|
printf("Config:" RESET " %s_defconfig\n", CONFIG_SYS_CONFIG_NAME);
|
|
break;
|
|
case HOST:
|
|
model = ofnode_read_string(ofnode_root(), "model");
|
|
if (model)
|
|
printf("Host:" RESET " %s\n", model);
|
|
break;
|
|
case UPTIME:
|
|
printf("Uptime:" RESET " %ld seconds\n", get_timer(0) / 1000);
|
|
break;
|
|
case IP:
|
|
ipaddr = env_get("ipaddr");
|
|
if (!ipaddr)
|
|
ipaddr = "none";
|
|
printf("IP Address:" RESET " %s", ipaddr);
|
|
ipaddr = env_get("ipv6addr");
|
|
if (ipaddr)
|
|
printf(", %s\n", ipaddr);
|
|
else
|
|
putc('\n');
|
|
break;
|
|
case CMDS:
|
|
n_cmds = ll_entry_count(struct cmd_tbl, cmd);
|
|
printf("Commands:" RESET " %d (help)\n", n_cmds);
|
|
break;
|
|
case CONSOLES:
|
|
printf("Consoles:" RESET " %s", env_get("stdout"));
|
|
if (gd->baudrate)
|
|
printf(" (%d baud)", gd->baudrate);
|
|
putc('\n');
|
|
break;
|
|
case FEATURES:
|
|
printf("Features:" RESET " ");
|
|
if (IS_ENABLED(CONFIG_NET))
|
|
printf("Net");
|
|
if (IS_ENABLED(CONFIG_EFI_LOADER))
|
|
printf(", EFI");
|
|
if (IS_ENABLED(CONFIG_CMD_CAT))
|
|
printf(", cat :3");
|
|
#ifdef CONFIG_ARM64
|
|
switch (current_el()) {
|
|
case 2:
|
|
printf(", VMs");
|
|
break;
|
|
case 3:
|
|
printf(", full control!");
|
|
break;
|
|
}
|
|
#endif
|
|
printf("\n");
|
|
break;
|
|
case RELOCATION:
|
|
if (gd->flags & GD_FLG_SKIP_RELOC)
|
|
printf("Relocated:" RESET " no\n");
|
|
else
|
|
printf("Relocated:" RESET " to %#011lx\n", gd->relocaddr);
|
|
break;
|
|
case CORES:
|
|
ofnode_for_each_subnode(np, ofnode_path("/cpus")) {
|
|
if (ofnode_name_eq(np, "cpu"))
|
|
n_cpus++;
|
|
}
|
|
printf("CPU: " RESET CONFIG_SYS_ARCH " (%d cores, 1 in use)\n", n_cpus);
|
|
break;
|
|
case MEMORY:
|
|
for (int j = 0; j < CONFIG_NR_DRAM_BANKS && gd->bd->bi_dram[j].size; j++)
|
|
size += gd->bd->bi_dram[j].size;
|
|
printf("Memory:" RESET " ");
|
|
print_size(size, "\n");
|
|
break;
|
|
case STORAGE:
|
|
default: {
|
|
#ifdef CONFIG_BLK
|
|
struct udevice *dev;
|
|
struct blk_desc *desc;
|
|
int ret;
|
|
|
|
ret = uclass_find_device_by_seq(UCLASS_BLK, line - STORAGE, &dev);
|
|
if (!ret && dev) {
|
|
desc = dev_get_uclass_plat(dev);
|
|
size = desc->lba * desc->blksz;
|
|
printf("%4s %d: " RESET, blk_get_uclass_name(desc->uclass_id),
|
|
desc->lun);
|
|
if (size)
|
|
print_size(size, "");
|
|
else
|
|
printf("No media");
|
|
} else if (ret == -ENODEV && (skip_ascii || line > ARRAY_SIZE(logo_lines))) {
|
|
break;
|
|
}
|
|
#endif
|
|
printf("\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
printf(RESET "\n\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
U_BOOT_CMD(ufetch, 2, 1, do_ufetch,
|
|
"U-Boot fetch utility",
|
|
"Print information about your device.\n"
|
|
" -n Don't print the ASCII logo"
|
|
);
|