forked from OERV-BSP/u-boot
When looking at ufetch output it isn't immediately obvious which CPU architecture the presented board has. This patch therefore adds the CPU architecture string (for example "powerpc") to the "CPU:" line. The new format is: CPU: powerpc (1 cores, 1 in use) Signed-off-by: J. Neuschäfer <j.ne@posteo.net> Reviewed-by: Caleb Connolly <caleb.connolly@linaro.org> Link: https://lore.kernel.org/r/20241211-ufetch-v2-3-2b5432ffaeb1@posteo.net Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
235 lines
6.6 KiB
C
235 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[38;5;4m"
|
|
#define YELLOW "\033[38;5;11m"
|
|
#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"
|
|
);
|