From 4d28fcdf65950576f0e0f5447c89421126dc4943 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Wed, 30 Oct 2024 22:34:02 +0100 Subject: cmd/nvedit.c: teach 'env default' to optionally keep runtime variables It can be useful to set all variables defined in the default environment to the value they have there, but without removing variables that are only defined at runtime. This can sort-of be done today, by using the "env default var1 var2 ..." variant, but that requires listing all variables defined in the default environment. It's much more convenient to be able to say env default -k -a The -k flag is also meaningful in the other case: If var1 is not defined in the default environment, but var2 is, env default var1 var2 would emit a warning about var1 not being in the default env and thus being deleted. With -k, there's no warning, and var1 is kept as-is. Signed-off-by: Rasmus Villemoes --- cmd/nvedit.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'cmd') diff --git a/cmd/nvedit.c b/cmd/nvedit.c index 392f90f8698..1f259801293 100644 --- a/cmd/nvedit.c +++ b/cmd/nvedit.c @@ -523,6 +523,9 @@ static int do_env_default(struct cmd_tbl *cmdtp, int flag, case 'f': /* force */ env_flag |= H_FORCE; break; + case 'k': + env_flag |= H_NOCLEAR; + break; default: return cmd_usage(cmdtp); } @@ -1133,8 +1136,9 @@ U_BOOT_LONGHELP(env, #if defined(CONFIG_CMD_ENV_CALLBACK) "callbacks - print callbacks and their associated variables\nenv " #endif - "default [-f] -a - [forcibly] reset default environment\n" - "env default [-f] var [...] - [forcibly] reset variable(s) to their default values\n" + "default [-k] [-f] -a - [forcibly] reset default environment\n" + "env default [-k] [-f] var [...] - [forcibly] reset variable(s) to their default values\n" + " \"-k\": keep variables not defined in default environment\n" "env delete [-f] var [...] - [forcibly] delete variable(s)\n" #if defined(CONFIG_CMD_EDITENV) "env edit name - edit environment variable\n" -- cgit v1.3.1 From 657b799585023b694f229816d249f7a733130d82 Mon Sep 17 00:00:00 2001 From: Adriano Cordova Date: Mon, 11 Nov 2024 18:08:55 -0300 Subject: net: Kconfig: add CONFIG_WGET symbol Let net/wget.c and net/lwip/wget.c depend on CONFIG_WGET, and cmd/wget.c depend on CONFIG_CMD_WGET. This way, the wget code can be used regardless of whether the wget command is available. Signed-off-by: Adriano Cordova Reviewed-by: Heinrich Schuchardt --- cmd/Kconfig | 5 +---- net/Kconfig | 9 +++++++++ net/Makefile | 2 +- net/lwip/Makefile | 2 +- 4 files changed, 12 insertions(+), 6 deletions(-) (limited to 'cmd') diff --git a/cmd/Kconfig b/cmd/Kconfig index 636833646f6..8f3ad94089c 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -2115,11 +2115,8 @@ config CMD_TFTPBOOT config CMD_WGET bool "wget" - depends on CMD_NET default y if SANDBOX - select PROT_TCP if NET - select PROT_TCP_LWIP if NET_LWIP - select PROT_DNS_LWIP if NET_LWIP + select WGET help wget is a simple command to download kernel, or other files, from a http server over TCP. diff --git a/net/Kconfig b/net/Kconfig index 76ab7d91eeb..b4bb68dd613 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -244,6 +244,15 @@ config NET_RANDOM_ETHADDR generated. It will be saved to the appropriate environment variable, too. +config WGET + bool "Enable wget" + select PROT_TCP if NET + select PROT_TCP_LWIP if NET_LWIP + select PROT_DNS_LWIP if NET_LWIP + help + Selecting this will enable wget, an interface to send HTTP requests + via the network stack. + config TFTP_BLOCKSIZE int "TFTP block size" default 1468 diff --git a/net/Makefile b/net/Makefile index 209377aeb26..7c917b318c0 100644 --- a/net/Makefile +++ b/net/Makefile @@ -29,7 +29,7 @@ obj-$(CONFIG_$(PHASE_)TCP_FUNCTION_FASTBOOT) += fastboot_tcp.o obj-$(CONFIG_CMD_WOL) += wol.o obj-$(CONFIG_PROT_UDP) += udp.o obj-$(CONFIG_PROT_TCP) += tcp.o -obj-$(CONFIG_CMD_WGET) += wget.o +obj-$(CONFIG_WGET) += wget.o # Disable this warning as it is triggered by: # sprintf(buf, index ? "foo%d" : "foo", index) diff --git a/net/lwip/Makefile b/net/lwip/Makefile index f2558f8763a..79dd6b3fb50 100644 --- a/net/lwip/Makefile +++ b/net/lwip/Makefile @@ -5,4 +5,4 @@ obj-$(CONFIG_CMD_DHCP) += dhcp.o obj-$(CONFIG_CMD_DNS) += dns.o obj-$(CONFIG_CMD_PING) += ping.o obj-$(CONFIG_CMD_TFTPBOOT) += tftp.o -obj-$(CONFIG_CMD_WGET) += wget.o +obj-$(CONFIG_WGET) += wget.o -- cgit v1.3.1 From 2dd076a9c1b4137f0a48e84596fa29da2e957858 Mon Sep 17 00:00:00 2001 From: Adriano Cordova Date: Mon, 11 Nov 2024 18:08:58 -0300 Subject: net: wget: integrate struct wget_info into legacy wget code Each wget request now fills the struct wget_info. The efi bootdevice is now set conditionally to the set_bootdevice variable in wget_info, and the same holds for lmb memory check. Signed-off-by: Adriano Cordova --- cmd/net.c | 2 ++ net/wget.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 72 insertions(+), 21 deletions(-) (limited to 'cmd') diff --git a/cmd/net.c b/cmd/net.c index c90578e1b9f..79525f73a51 100644 --- a/cmd/net.c +++ b/cmd/net.c @@ -196,6 +196,8 @@ U_BOOT_CMD( #if defined(CONFIG_CMD_WGET) static int do_wget(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]) { + wget_info = &default_wget_info; + return netboot_common(WGET, cmdtp, argc, argv); } diff --git a/net/wget.c b/net/wget.c index 635f82efbb3..21f18758664 100644 --- a/net/wget.c +++ b/net/wget.c @@ -22,10 +22,10 @@ DECLARE_GLOBAL_DATA_PTR; /* The default, change with environment variable 'httpdstp' */ #define SERVER_PORT 80 -static const char bootfile1[] = "GET "; +static const char bootfileGET[] = "GET "; +static const char bootfileHEAD[] = "HEAD "; static const char bootfile3[] = " HTTP/1.0\r\n\r\n"; static const char http_eom[] = "\r\n\r\n"; -static const char http_ok[] = "200"; static const char content_len[] = "Content-Length"; static const char linefeed[] = "\r\n"; static struct in_addr web_server_ip; @@ -77,7 +77,7 @@ static inline int store_block(uchar *src, unsigned int offset, unsigned int len) ulong newsize = offset + len; uchar *ptr; - if (CONFIG_IS_ENABLED(LMB)) { + if (CONFIG_IS_ENABLED(LMB) && wget_info->set_bootdev) { if (store_addr < image_load_addr || lmb_read_check(store_addr, len)) { printf("\nwget error: "); @@ -132,8 +132,17 @@ static void wget_send_stored(void) IP_TCP_HDR_SIZE + TCP_TSOPT_SIZE + 2; offset = ptr; - memcpy(offset, &bootfile1, strlen(bootfile1)); - offset += strlen(bootfile1); + switch (wget_info->method) { + case WGET_HTTP_METHOD_HEAD: + memcpy(offset, &bootfileHEAD, strlen(bootfileHEAD)); + offset += strlen(bootfileHEAD); + break; + case WGET_HTTP_METHOD_GET: + default: + memcpy(offset, &bootfileGET, strlen(bootfileGET)); + offset += strlen(bootfileGET); + break; + } memcpy(offset, image_url, strlen(image_url)); offset += strlen(image_url); @@ -193,6 +202,47 @@ static void wget_timeout_handler(void) #define PKT_QUEUE_OFFSET 0x20000 #define PKT_QUEUE_PACKET_SIZE 0x800 +static void wget_fill_info(const uchar *pkt, int hlen) +{ + const char *first_space; + const char *second_space; + char *pos, *end; + + if (wget_info->headers && hlen < MAX_HTTP_HEADERS_SIZE) + strncpy(wget_info->headers, pkt, hlen); + + //Get status code + first_space = strchr(pkt, ' '); + if (!first_space) { + wget_info->status_code = -1; + return; + } + + second_space = strchr(first_space + 1, ' '); + if (!second_space) { + wget_info->status_code = -1; + return; + } + + wget_info->status_code = (u32)simple_strtoul(first_space + 1, &end, 10); + + if (second_space != end) + wget_info->status_code = -1; + + pos = strstr((char *)pkt, content_len); + + if (pos) { + pos += sizeof(content_len) + 1; + while (*pos == ' ') + pos++; + content_length = simple_strtoul(pos, &end, 10); + debug_cond(DEBUG_WGET, + "wget: Connected Len %lu\n", + content_length); + wget_info->hdr_cont_len = content_length; + } +} + static void wget_connected(uchar *pkt, unsigned int tcp_seq_num, u8 action, unsigned int tcp_ack_num, unsigned int len) { @@ -241,7 +291,11 @@ static void wget_connected(uchar *pkt, unsigned int tcp_seq_num, initial_data_seq_num = tcp_seq_num + hlen; next_data_seq_num = tcp_seq_num + len; - if (strstr((char *)pkt, http_ok) == 0) { + wget_fill_info(pkt, hlen); + debug_cond(DEBUG_WGET, + "wget: HTTP Status Code %d\n", wget_info->status_code); + + if (wget_info->status_code != 200) { debug_cond(DEBUG_WGET, "wget: Connected Bad Xfer\n"); wget_loop_state = NETLOOP_FAIL; @@ -251,17 +305,6 @@ static void wget_connected(uchar *pkt, unsigned int tcp_seq_num, "wget: Connected Pkt %p hlen %x\n", pkt, hlen); - pos = strstr((char *)pkt, content_len); - if (!pos) { - content_length = -1; - } else { - pos += sizeof(content_len) + 2; - strict_strtoul(pos, 10, &content_length); - debug_cond(DEBUG_WGET, - "wget: Connected Len %lu\n", - content_length); - } - net_boot_file_size = 0; if (len > hlen) { @@ -397,10 +440,13 @@ static void wget_handler(uchar *pkt, u16 dport, case WGET_TRANSFERRED: printf("Packets received %d, Transfer Successful\n", packets); net_set_state(wget_loop_state); - efi_set_bootdev("Net", "", image_url, - map_sysmem(image_load_addr, 0), - net_boot_file_size); - env_set_hex("filesize", net_boot_file_size); + wget_info->file_size = net_boot_file_size; + if (wget_info->method == WGET_HTTP_METHOD_GET && wget_info->set_bootdev) { + efi_set_bootdev("Net", "", image_url, + map_sysmem(image_load_addr, 0), + net_boot_file_size); + env_set_hex("filesize", net_boot_file_size); + } break; } } @@ -425,6 +471,9 @@ static unsigned int random_port(void) void wget_start(void) { + if (!wget_info) + wget_info = &default_wget_info; + image_url = strchr(net_boot_file_name, ':'); if (image_url > 0) { web_server_ip = string_to_ip(net_boot_file_name); -- cgit v1.3.1 From e2032a0e4e55ea0958aae32f783f3a0726e34415 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Sat, 26 Oct 2024 08:09:00 -0600 Subject: global: Remove bi_sramstart/bi_sramsize These fields are currently set on exactly two platforms today, and used by only one of them. Update pic32mzdask to use CFG_SYS_SRAM* in the one location it needs it and otherwise drop this field from the bd_info struct. Signed-off-by: Tom Rini --- Kconfig | 21 --------------------- api/api_platform-powerpc.c | 1 - cmd/bdinfo.c | 4 ---- common/board_f.c | 7 ------- include/asm-generic/u-boot.h | 2 -- include/configs/pic32mzdask.h | 5 ++++- 6 files changed, 4 insertions(+), 36 deletions(-) (limited to 'cmd') diff --git a/Kconfig b/Kconfig index eb55f2511d9..bd63fea2e9a 100644 --- a/Kconfig +++ b/Kconfig @@ -595,27 +595,6 @@ config SYS_MEM_TOP_HIDE WARNING: Please make sure that this value is a multiple of the OS page size. -config SYS_HAS_SRAM - bool - default y if TARGET_PIC32MZDASK - default y if TARGET_DEVKIT8000 - help - Enable this to allow support for the on board SRAM. - SRAM base address is controlled by CONFIG_SYS_SRAM_BASE. - SRAM size is controlled by CONFIG_SYS_SRAM_SIZE. - -config SYS_SRAM_BASE - hex - default 0x80000000 if TARGET_PIC32MZDASK - default 0x40200000 if TARGET_DEVKIT8000 - default 0x0 - -config SYS_SRAM_SIZE - hex - default 0x00080000 if TARGET_PIC32MZDASK - default 0x10000 if TARGET_DEVKIT8000 - default 0x0 - config SYS_MONITOR_LEN int "Maximum size in bytes reserved for U-Boot in memory" default 1048576 if X86 diff --git a/api/api_platform-powerpc.c b/api/api_platform-powerpc.c index 3a04a9f691c..2c1ab043af6 100644 --- a/api/api_platform-powerpc.c +++ b/api/api_platform-powerpc.c @@ -43,7 +43,6 @@ int platform_sys_info(struct sys_info *si) platform_set_mr(si, gd->ram_base, gd->ram_size, MR_ATTR_DRAM); platform_set_mr(si, gd->bd->bi_flashstart, gd->bd->bi_flashsize, MR_ATTR_FLASH); - platform_set_mr(si, gd->bd->bi_sramstart, gd->bd->bi_sramsize, MR_ATTR_SRAM); return 1; } diff --git a/cmd/bdinfo.c b/cmd/bdinfo.c index 4c0e2adabc3..ae9e1923eac 100644 --- a/cmd/bdinfo.c +++ b/cmd/bdinfo.c @@ -140,10 +140,6 @@ static int bdinfo_print_all(struct bd_info *bd) #endif bdinfo_print_num_l("boot_params", (ulong)bd->bi_boot_params); print_bi_dram(bd); - if (IS_ENABLED(CONFIG_SYS_HAS_SRAM)) { - bdinfo_print_num_l("sramstart", (ulong)bd->bi_sramstart); - bdinfo_print_num_l("sramsize", (ulong)bd->bi_sramsize); - } bdinfo_print_num_l("flashstart", (ulong)bd->bi_flashstart); bdinfo_print_num_l("flashsize", (ulong)bd->bi_flashsize); bdinfo_print_num_l("flashoffset", (ulong)bd->bi_flashoffset); diff --git a/common/board_f.c b/common/board_f.c index 98dc2591e1d..ebc934ab810 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -637,13 +637,6 @@ __weak int arch_setup_bdinfo(void) int setup_bdinfo(void) { - struct bd_info *bd = gd->bd; - - if (IS_ENABLED(CONFIG_SYS_HAS_SRAM)) { - bd->bi_sramstart = CONFIG_SYS_SRAM_BASE; /* start of SRAM */ - bd->bi_sramsize = CONFIG_SYS_SRAM_SIZE; /* size of SRAM */ - } - return arch_setup_bdinfo(); } diff --git a/include/asm-generic/u-boot.h b/include/asm-generic/u-boot.h index 70303acd558..8c619c1b74a 100644 --- a/include/asm-generic/u-boot.h +++ b/include/asm-generic/u-boot.h @@ -30,8 +30,6 @@ struct bd_info { unsigned long bi_flashstart; /* start of FLASH memory */ unsigned long bi_flashsize; /* size of FLASH memory */ unsigned long bi_flashoffset; /* reserved area for startup monitor */ - unsigned long bi_sramstart; /* start of SRAM memory */ - unsigned long bi_sramsize; /* size of SRAM memory */ #ifdef CONFIG_ARM unsigned long bi_arm_freq; /* arm frequency */ unsigned long bi_dsp_freq; /* dsp core frequency */ diff --git a/include/configs/pic32mzdask.h b/include/configs/pic32mzdask.h index 0ae4fc55a97..8de930eab54 100644 --- a/include/configs/pic32mzdask.h +++ b/include/configs/pic32mzdask.h @@ -19,8 +19,11 @@ */ /* Initial RAM for temporary stack, global data */ #define CFG_SYS_INIT_RAM_SIZE 0x10000 +#define CFG_SYS_SRAM_BASE 0x80000000 +#define CFG_SYS_SRAM_SIZE 0x00080000 + #define CFG_SYS_INIT_RAM_ADDR \ - (CONFIG_SYS_SRAM_BASE + CONFIG_SYS_SRAM_SIZE - CFG_SYS_INIT_RAM_SIZE) + (CFG_SYS_SRAM_BASE + CFG_SYS_SRAM_SIZE - CFG_SYS_INIT_RAM_SIZE) /* SDRAM Configuration (for final code, data, stack, heap) */ #define CFG_SYS_SDRAM_BASE 0x88000000 -- cgit v1.3.1 From 86d462c05d57f0bb4df582453d0d0b2d7cabc6ff Mon Sep 17 00:00:00 2001 From: Caleb Connolly Date: Fri, 15 Nov 2024 01:47:29 +0100 Subject: cmd: add a fetch utility Add a small utility for displaying some information about U-Boot and the hardware it's running on in a similar fashion to the popular neofetch tool for Linux [1]. While the output is meant to be useful, it should also be pleasing to look at and perhaps entertaining. The ufetch command aims to bring this to U-Boot, featuring a colorful ASCII art version of the U-Boot logo. [1]: https://en.wikipedia.org/wiki/Neofetch Reviewed-by: Simon Glass Acked-by: Ilias Apalodimas Tested-by: Mattijs Korpershoek # vim3 Tested-by: Neil Armstrong # on SM8560-QRD Acked-by: Heinrich Schuchardt Tested-by: Tony Dinh Signed-off-by: Caleb Connolly --- MAINTAINERS | 5 + cmd/Kconfig | 7 ++ cmd/Makefile | 1 + cmd/ufetch.c | 229 ++++++++++++++++++++++++++++++++++++++++++++++ configs/sandbox_defconfig | 1 + 5 files changed, 243 insertions(+) create mode 100644 cmd/ufetch.c (limited to 'cmd') diff --git a/MAINTAINERS b/MAINTAINERS index 8c6c0c2a4bc..ba31f86feb6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1736,6 +1736,11 @@ S: Maintained T: git https://source.denx.de/u-boot/custodians/u-boot-ubi.git F: drivers/mtd/ubi/ +UFETCH +M: Caleb Connolly +S: Maintained +F: cmd/ufetch.c + UFS M: Neil Armstrong M: Bhupesh Sharma diff --git a/cmd/Kconfig b/cmd/Kconfig index 702adfd287c..4936a70f3ef 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -176,6 +176,13 @@ config CMD_CPU internal name) and clock frequency. Other information may be available depending on the CPU driver. +config CMD_UFETCH + bool "U-Boot fetch" + depends on BLK + help + Fetch utility for U-Boot (akin to neofetch). Prints information + about U-Boot and the board it is running on in a pleasing format. + config CMD_FWU_METADATA bool "fwu metadata read" depends on FWU_MULTI_BANK_UPDATE diff --git a/cmd/Makefile b/cmd/Makefile index d1f369deec0..1e6d3128c8c 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -53,6 +53,7 @@ obj-$(CONFIG_CMD_CPU) += cpu.o obj-$(CONFIG_CMD_DATE) += date.o obj-$(CONFIG_CMD_DEMO) += demo.o obj-$(CONFIG_CMD_DM) += dm.o +obj-$(CONFIG_CMD_UFETCH) += ufetch.o obj-$(CONFIG_CMD_SOUND) += sound.o ifdef CONFIG_POST obj-$(CONFIG_CMD_DIAG) += diag.o diff --git a/cmd/ufetch.c b/cmd/ufetch.c new file mode 100644 index 00000000000..0b825d7e8c7 --- /dev/null +++ b/cmd/ufetch.c @@ -0,0 +1,229 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* Small "fetch" utility for U-Boot */ + +#ifdef CONFIG_ARM64 +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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(LAST_LINE + 1, ARRAY_SIZE(logo_lines)); + const char *model, *compatible; + char *ipaddr; + int n_cmds, n_cpus = 0, ret, compatlen; + size_t size; + ofnode np; + struct udevice *dev; + struct blk_desc *desc; + 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 " %d (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: + 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; + } + 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" +); diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 8c244c859bc..af56571f0d0 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -52,6 +52,7 @@ CONFIG_DISPLAY_BOARDINFO_LATE=y CONFIG_STACKPROTECTOR=y CONFIG_ANDROID_AB=y CONFIG_CMD_CPU=y +CONFIG_CMD_UFETCH=y CONFIG_CMD_LICENSE=y CONFIG_CMD_SMBIOS=y CONFIG_CMD_BOOTM_PRE_LOAD=y -- cgit v1.3.1 From 75ad667aad2a6f488d894633e1a8656137572adc Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Tue, 10 Sep 2024 01:23:34 +0200 Subject: cmd: mtd: simplify mtd_show_device() CONFIG_DM=y is always true. Signed-off-by: Heinrich Schuchardt Reviewed-by: Miquel Raynal Acked-by: Michael Trimarchi --- cmd/mtd.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'cmd') diff --git a/cmd/mtd.c b/cmd/mtd.c index f178d7bea61..c25997cfb24 100644 --- a/cmd/mtd.c +++ b/cmd/mtd.c @@ -122,13 +122,11 @@ static void mtd_show_device(struct mtd_info *mtd) { /* Device */ printf("* %s\n", mtd->name); -#if defined(CONFIG_DM) if (mtd->dev) { printf(" - device: %s\n", mtd->dev->name); printf(" - parent: %s\n", mtd->dev->parent->name); printf(" - driver: %s\n", mtd->dev->driver->name); } -#endif if (IS_ENABLED(CONFIG_OF_CONTROL) && mtd->dev) { char buf[256]; int res; -- cgit v1.3.1 From 1fac577207196e12932c2c733b58e3b14013b1ce Mon Sep 17 00:00:00 2001 From: Michael Trimarchi Date: Thu, 12 Dec 2024 19:28:07 +0100 Subject: nand: Add a watch command This is a debug command to monitor the retention state of the data on the array. The command needs a duplication of the mtd_read_oob() function to actually return the maximum number of bitflips encountered while reading the page. We could write a specific implementation for the Sunxi driver but this is probably enough. nand watch - check an area for bitflips nand watch.part - check a partition for bitflips nand watch.chip - check the whole device for bitflips The output may be a bit verbose and could look like: => nand watch.chip device 0 whole chip size adjusted to 0xff60000 (5 bad blocks) NAND watch for bitflips in area 0x0-0xff60000: Page 0 (0x00000000) -> error -74 Page 1 (0x00000800) -> error -74 Page 2 (0x00001000) -> error -74 Page 3 (0x00001800) -> error -74 Page 4 (0x00002000) -> error -74 Page 5 (0x00002800) -> error -74 Page 6 (0x00003000) -> error -74 Page 7 (0x00003800) -> error -74 Page 8 (0x00004000) -> error -74 Page 9 (0x00004800) -> error -74 Page 10 (0x00005000) -> error -74 Page 11 (0x00005800) -> error -74 Page 12 (0x00006000) -> error -74 Page 13 (0x00006800) -> error -74 Page 14 (0x00007000) -> error -74 Page 15 (0x00007800) -> error -74 Page 16 (0x00008000) -> error -74 Page 17 (0x00008800) -> error -74 Page 18 (0x00009000) -> error -74 Page 19 (0x00009800) -> error -74 Page 20 (0x0000a000) -> error -74 Page 21 (0x0000a800) -> error -74 Page 22 (0x0000b000) -> error -74 Page 23 (0x0000b800) -> error -74 Page 1110 (0x0022b000) -> up to 1 bf/chunk Page 1122 (0x00231000) -> up to 1 bf/chunk Page 1132 (0x00236000) -> up to 1 bf/chunk Page 1362 (0x002a9000) -> up to 1 bf/chunk Page 4990 (0x009bf000) -> up to 1 bf/chunk Page 5728 (0x00b30000) -> up to 1 bf/chunk Page 7116 (0x00de6000) -> up to 1 bf/chunk Page 7160 (0x00dfc000) -> up to 1 bf/chunk Page 7494 (0x00ea3000) -> up to 1 bf/chunk Page 10842 (0x0152d000) -> up to 1 bf/chunk Page 11614 (0x016af000) -> up to 1 bf/chunk Page 11970 (0x01761000) -> up to 1 bf/chunk Page 12536 (0x0187c000) -> up to 1 bf/chunk Page 12687 (0x018c7800) -> up to 1 bf/chunk Page 14298 (0x01bed000) -> up to 1 bf/chunk Page 18268 (0x023ae000) -> up to 1 bf/chunk Page 18760 (0x024a4000) -> up to 1 bf/chunk Page 21440 (0x029e0000) -> up to 1 bf/chunk Page 22336 (0x02ba0000) -> up to 1 bf/chunk Page 22592 (0x02c20000) -> up to 1 bf/chunk Page 23872 (0x02ea0000) -> up to 1 bf/chunk Page 27584 (0x035e0000) -> up to 1 bf/chunk Page 35008 (0x04460000) -> up to 1 bf/chunk Page 37184 (0x048a0000) -> up to 1 bf/chunk Page 41728 (0x05180000) -> up to 1 bf/chunk Page 42176 (0x05260000) -> up to 1 bf/chunk Page 43200 (0x05460000) -> up to 1 bf/chunk Page 43328 (0x054a0000) -> up to 1 bf/chunk Page 45376 (0x058a0000) -> up to 1 bf/chunk Page 47040 (0x05be0000) -> up to 1 bf/chunk Page 47552 (0x05ce0000) -> up to 1 bf/chunk Page 49344 (0x06060000) -> up to 1 bf/chunk Page 49856 (0x06160000) -> up to 1 bf/chunk Page 62784 (0x07aa0000) -> up to 1 bf/chunk Page 65153 (0x07f40800) -> up to 1 bf/chunk Page 65228 (0x07f66000) -> up to 1 bf/chunk Page 65382 (0x07fb3000) -> up to 1 bf/chunk Page 98624 (0x0c0a0000) -> up to 1 bf/chunk Page 101952 (0x0c720000) -> up to 1 bf/chunk Page 107584 (0x0d220000) -> up to 1 bf/chunk Page 118208 (0x0e6e0000) -> up to 1 bf/chunk Page 126656 (0x0f760000) -> up to 1 bf/chunk Page 127680 (0x0f960000) -> up to 1 bf/chunk Page 129920 (0x0fdc0000) -> up to 1 bf/chunk Maximum number of bitflips: 1 Pages with bitflips: 44/130752 It is also possible to reduce the output with the .quiet suffix in order to just show the summary. => nand watch.chip device 0 whole chip size adjusted to 0xff60000 (5 bad blocks) NAND watch for bitflips in area 0x0-0xff60000: Maximum number of bitflips: 1 Pages with bitflips: 44/130752 Signed-off-by: Miquel Raynal Signed-off-by: Michael Trimarchi --- cmd/Kconfig | 5 +++ cmd/nand.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++ drivers/mtd/mtdcore.c | 22 +++++++++++ 3 files changed, 130 insertions(+) (limited to 'cmd') diff --git a/cmd/Kconfig b/cmd/Kconfig index 4936a70f3ef..93efeaec6f4 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -1497,6 +1497,11 @@ config CMD_NAND_TORTURE help NAND torture support. +config CMD_NAND_WATCH + bool "nand watch" + help + NAND watch bitflip support. + endif # CMD_NAND config CMD_NVME diff --git a/cmd/nand.c b/cmd/nand.c index 5a328e0acdd..2f785deeb7f 100644 --- a/cmd/nand.c +++ b/cmd/nand.c @@ -231,6 +231,54 @@ free_dat: return ret; } +#ifdef CONFIG_CMD_NAND_WATCH +static int nand_watch_bf(struct mtd_info *mtd, ulong off, ulong size, bool quiet) +{ + unsigned int max_bf = 0, pages_wbf = 0; + unsigned int first_page, pages, i; + struct mtd_oob_ops ops = {}; + u_char *buf; + int ret; + + buf = memalign(ARCH_DMA_MINALIGN, mtd->writesize); + if (!buf) { + puts("No memory for page buffer\n"); + return 1; + } + + first_page = off / mtd->writesize; + pages = size / mtd->writesize; + + ops.datbuf = buf; + ops.len = mtd->writesize; + for (i = first_page; i < first_page + pages; i++) { + ulong addr = mtd->writesize * i; + ret = mtd_read_oob_bf(mtd, addr, &ops); + if (ret < 0) { + if (quiet) + continue; + + printf("Page %7d (0x%08lx) -> error %d\n", + i, addr, ret); + } else if (ret) { + max_bf = max(max_bf, (unsigned int)ret); + pages_wbf++; + if (quiet) + continue; + printf("Page %7d (0x%08lx) -> up to %2d bf/chunk\n", + i, addr, ret); + } + } + + printf("Maximum number of bitflips: %u\n", max_bf); + printf("Pages with bitflips: %u/%u\n", pages_wbf, pages); + + free(buf); + + return 0; +} +#endif + /* ------------------------------------------------------------------------- */ static int set_dev(int dev) @@ -781,6 +829,55 @@ static int do_nand(struct cmd_tbl *cmdtp, int flag, int argc, return ret == 0 ? 0 : 1; } +#ifdef CONFIG_CMD_NAND_WATCH + if (strncmp(cmd, "watch", 5) == 0) { + int args = 2; + + if (cmd[5]) { + if (!strncmp(&cmd[5], ".part", 5)) { + args = 1; + } else if (!strncmp(&cmd[5], ".chip", 5)) { + args = 0; + } else { + goto usage; + } + } + + if (cmd[10]) + if (!strncmp(&cmd[10], ".quiet", 6)) + quiet = true; + + if (argc != 2 + args) + goto usage; + + ret = mtd_arg_off_size(argc - 2, argv + 2, &dev, &off, &size, + &maxsize, MTD_DEV_TYPE_NAND, mtd->size); + if (ret) + return ret; + + /* size is unspecified */ + if (argc < 4) + adjust_size_for_badblocks(&size, off, dev); + + if ((off & (mtd->writesize - 1)) || + (size & (mtd->writesize - 1))) { + printf("Attempt to read non page-aligned data\n"); + return -EINVAL; + } + + ret = set_dev(dev); + if (ret) + return ret; + + mtd = get_nand_dev_by_index(dev); + + printf("\nNAND watch for bitflips in area 0x%llx-0x%llx:\n", + off, off + size); + + return nand_watch_bf(mtd, off, size, quiet); + } +#endif + #ifdef CONFIG_CMD_NAND_TORTURE if (strcmp(cmd, "torture") == 0) { loff_t endoff; @@ -946,6 +1043,12 @@ U_BOOT_LONGHELP(nand, "nand erase.chip [clean] - erase entire chip'\n" "nand bad - show bad blocks\n" "nand dump[.oob] off - dump page\n" +#ifdef CONFIG_CMD_NAND_WATCH + "nand watch - check an area for bitflips\n" + "nand watch.part - check a partition for bitflips\n" + "nand watch.chip - check the whole device for bitflips\n" + "\t\t.quiet - Query only the summary, not the details\n" +#endif #ifdef CONFIG_CMD_NAND_TORTURE "nand torture off - torture one block at offset\n" "nand torture off [size] - torture blocks from off to off+size\n" diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index 5bd64bd6ad4..3bfa5aebbc6 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -1124,6 +1124,28 @@ int mtd_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops) } EXPORT_SYMBOL_GPL(mtd_read_oob); +/* This is a bare copy of mtd_read_oob returning the actual number of bitflips */ +int mtd_read_oob_bf(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops) +{ + int ret_code; + ops->retlen = ops->oobretlen = 0; + if (!mtd->_read_oob) + return -EOPNOTSUPP; + /* + * In cases where ops->datbuf != NULL, mtd->_read_oob() has semantics + * similar to mtd->_read(), returning a non-negative integer + * representing max bitflips. In other cases, mtd->_read_oob() may + * return -EUCLEAN. In all cases, perform similar logic to mtd_read(). + */ + ret_code = mtd->_read_oob(mtd, from, ops); + if (unlikely(ret_code < 0)) + return ret_code; + if (mtd->ecc_strength == 0) + return 0; /* device lacks ecc */ + return ret_code; +} +EXPORT_SYMBOL_GPL(mtd_read_oob_bf); + int mtd_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops) { -- cgit v1.3.1 From 900a8951c3b6035c25632438ebc7240cbc77883c Mon Sep 17 00:00:00 2001 From: Ilias Apalodimas Date: Wed, 18 Dec 2024 09:02:32 +0200 Subject: lmb: Remove lmb_reserve_flags() lmb_reserve() is just calling lmb_reserve_flags() with LMB_NONE. There's not much we gain from this abstraction. So let's remove the latter, add the flags argument to lmb_reserve() and make the code a bit easier to follow. Reviewed-by: Tom Rini Reviewed-by: Sam Protsenko Tested-by: Sam Protsenko Signed-off-by: Ilias Apalodimas --- arch/powerpc/cpu/mpc85xx/mp.c | 2 +- arch/powerpc/lib/misc.c | 2 +- boot/bootm.c | 3 ++- boot/image-board.c | 2 +- boot/image-fdt.c | 6 +++--- cmd/booti.c | 2 +- cmd/bootz.c | 2 +- cmd/load.c | 2 +- include/lmb.h | 14 ++----------- lib/lmb.c | 28 ++++++++++--------------- test/lib/lmb.c | 48 +++++++++++++++++++++---------------------- 11 files changed, 48 insertions(+), 63 deletions(-) (limited to 'cmd') diff --git a/arch/powerpc/cpu/mpc85xx/mp.c b/arch/powerpc/cpu/mpc85xx/mp.c index bed465cb2cb..8918a401fac 100644 --- a/arch/powerpc/cpu/mpc85xx/mp.c +++ b/arch/powerpc/cpu/mpc85xx/mp.c @@ -412,7 +412,7 @@ void cpu_mp_lmb_reserve(void) { u32 bootpg = determine_mp_bootpg(NULL); - lmb_reserve(bootpg, 4096); + lmb_reserve(bootpg, 4096, LMB_NONE); } void setup_mp(void) diff --git a/arch/powerpc/lib/misc.c b/arch/powerpc/lib/misc.c index 4cd23b3406d..7e303419624 100644 --- a/arch/powerpc/lib/misc.c +++ b/arch/powerpc/lib/misc.c @@ -40,7 +40,7 @@ int arch_misc_init(void) printf("WARNING: adjusting available memory from 0x%lx to 0x%llx\n", size, (unsigned long long)bootm_size); - lmb_reserve(base, bootm_size - size); + lmb_reserve(base, bootm_size - size, LMB_NONE); } #ifdef CONFIG_MP diff --git a/boot/bootm.c b/boot/bootm.c index 16a43d519a8..854ac7ec738 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -696,7 +696,8 @@ static int bootm_load_os(struct bootm_headers *images, int boot_progress) } if (CONFIG_IS_ENABLED(LMB)) - lmb_reserve(images->os.load, (load_end - images->os.load)); + lmb_reserve(images->os.load, (load_end - images->os.load), + LMB_NONE); return 0; } diff --git a/boot/image-board.c b/boot/image-board.c index b726bd6b303..070ada00718 100644 --- a/boot/image-board.c +++ b/boot/image-board.c @@ -562,7 +562,7 @@ int boot_ramdisk_high(ulong rd_data, ulong rd_len, ulong *initrd_start, debug(" in-place initrd\n"); *initrd_start = rd_data; *initrd_end = rd_data + rd_len; - lmb_reserve(rd_data, rd_len); + lmb_reserve(rd_data, rd_len, LMB_NONE); } else { if (initrd_high) *initrd_start = (ulong)lmb_alloc_base(rd_len, diff --git a/boot/image-fdt.c b/boot/image-fdt.c index cda7c3aa9e3..d717f669072 100644 --- a/boot/image-fdt.c +++ b/boot/image-fdt.c @@ -72,7 +72,7 @@ static void boot_fdt_reserve_region(u64 addr, u64 size, u32 flags) { long ret; - ret = lmb_reserve_flags(addr, size, flags); + ret = lmb_reserve(addr, size, flags); if (!ret) { debug(" reserving fdt memory region: addr=%llx size=%llx flags=%x\n", (unsigned long long)addr, @@ -184,7 +184,7 @@ int boot_relocate_fdt(char **of_flat_tree, ulong *of_size) if (desired_addr == ~0UL) { /* All ones means use fdt in place */ of_start = fdt_blob; - lmb_reserve(map_to_sysmem(of_start), of_len); + lmb_reserve(map_to_sysmem(of_start), of_len, LMB_NONE); disable_relocation = 1; } else if (desired_addr) { addr = lmb_alloc_base(of_len, 0x1000, desired_addr); @@ -675,7 +675,7 @@ int image_setup_libfdt(struct bootm_headers *images, void *blob, bool lmb) /* Create a new LMB reservation */ if (CONFIG_IS_ENABLED(LMB) && lmb) - lmb_reserve(map_to_sysmem(blob), of_size); + lmb_reserve(map_to_sysmem(blob), of_size, LMB_NONE); #if defined(CONFIG_ARCH_KEYSTONE) if (IS_ENABLED(CONFIG_OF_BOARD_SETUP)) diff --git a/cmd/booti.c b/cmd/booti.c index 43e79e87201..1a57fe91397 100644 --- a/cmd/booti.c +++ b/cmd/booti.c @@ -87,7 +87,7 @@ static int booti_start(struct bootm_info *bmi) images->os.start = relocated_addr; images->os.end = relocated_addr + image_size; - lmb_reserve(images->ep, le32_to_cpu(image_size)); + lmb_reserve(images->ep, le32_to_cpu(image_size), LMB_NONE); /* * Handle the BOOTM_STATE_FINDOTHER state ourselves as we do not diff --git a/cmd/bootz.c b/cmd/bootz.c index 787203f5bd7..99318ff213f 100644 --- a/cmd/bootz.c +++ b/cmd/bootz.c @@ -56,7 +56,7 @@ static int bootz_start(struct cmd_tbl *cmdtp, int flag, int argc, if (ret != 0) return 1; - lmb_reserve(images->ep, zi_end - zi_start); + lmb_reserve(images->ep, zi_end - zi_start, LMB_NONE); /* * Handle the BOOTM_STATE_FINDOTHER state ourselves as we do not diff --git a/cmd/load.c b/cmd/load.c index 20d802502ae..899bb4f598e 100644 --- a/cmd/load.c +++ b/cmd/load.c @@ -179,7 +179,7 @@ static ulong load_serial(long offset) { void *dst; - ret = lmb_reserve(store_addr, binlen); + ret = lmb_reserve(store_addr, binlen, LMB_NONE); if (ret) { printf("\nCannot overwrite reserved area (%08lx..%08lx)\n", store_addr, store_addr + binlen); diff --git a/include/lmb.h b/include/lmb.h index 3b911d5d839..3abe24deb56 100644 --- a/include/lmb.h +++ b/include/lmb.h @@ -80,16 +80,7 @@ void lmb_add_memory(void); long lmb_add(phys_addr_t base, phys_size_t size); /** - * lmb_reserve() - Reserve a memory region (with no special flags) - * @base: Base address of the memory region - * @size: Size of the memory region - * - * Return: 0 on success, negative error code on failure. - */ -long lmb_reserve(phys_addr_t base, phys_size_t size); - -/** - * lmb_reserve_flags() - Reserve one region with a specific flags bitfield + * lmb_reserve() - Reserve one region with a specific flags bitfield * @base: Base address of the memory region * @size: Size of the memory region * @flags: Flags for the memory region @@ -99,8 +90,7 @@ long lmb_reserve(phys_addr_t base, phys_size_t size); * * %-EEXIST - The region is already added, and flags != LMB_NONE * * %-1 - Failure */ -long lmb_reserve_flags(phys_addr_t base, phys_size_t size, - u32 flags); +long lmb_reserve(phys_addr_t base, phys_size_t size, u32 flags); phys_addr_t lmb_alloc(phys_size_t size, ulong align); phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr); diff --git a/lib/lmb.c b/lib/lmb.c index edecdb8e9cb..fd0e91981ad 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -553,12 +553,11 @@ static void lmb_reserve_uboot_region(void) if (bank_end > end) bank_end = end - 1; - lmb_reserve_flags(rsv_start, bank_end - rsv_start + 1, - LMB_NOOVERWRITE); + lmb_reserve(rsv_start, bank_end - rsv_start + 1, LMB_NOOVERWRITE); if (gd->flags & GD_FLG_SKIP_RELOC) - lmb_reserve_flags((phys_addr_t)(uintptr_t)_start, - gd->mon_len, LMB_NOOVERWRITE); + lmb_reserve((phys_addr_t)(uintptr_t)_start, + gd->mon_len, LMB_NOOVERWRITE); break; } @@ -584,7 +583,7 @@ static __maybe_unused void lmb_reserve_common_spl(void) if (IS_ENABLED(CONFIG_SPL_STACK_R_ADDR)) { rsv_start = gd->start_addr_sp - 16384; rsv_size = 16384; - lmb_reserve_flags(rsv_start, rsv_size, LMB_NOOVERWRITE); + lmb_reserve(rsv_start, rsv_size, LMB_NOOVERWRITE); } if (IS_ENABLED(CONFIG_SPL_SEPARATE_BSS)) { @@ -592,7 +591,7 @@ static __maybe_unused void lmb_reserve_common_spl(void) rsv_start = (phys_addr_t)(uintptr_t)__bss_start; rsv_size = (phys_addr_t)(uintptr_t)__bss_end - (phys_addr_t)(uintptr_t)__bss_start; - lmb_reserve_flags(rsv_start, rsv_size, LMB_NOOVERWRITE); + lmb_reserve(rsv_start, rsv_size, LMB_NOOVERWRITE); } } @@ -624,11 +623,11 @@ void lmb_add_memory(void) * allocated */ if (bd->bi_dram[i].start >= ram_top) - lmb_reserve_flags(bd->bi_dram[i].start, size, - LMB_NOOVERWRITE); + lmb_reserve(bd->bi_dram[i].start, size, + LMB_NOOVERWRITE); else if (bank_end > ram_top) - lmb_reserve_flags(ram_top, bank_end - ram_top, - LMB_NOOVERWRITE); + lmb_reserve(ram_top, bank_end - ram_top, + LMB_NOOVERWRITE); } } } @@ -669,7 +668,7 @@ long lmb_free(phys_addr_t base, phys_size_t size) return lmb_free_flags(base, size, LMB_NONE); } -long lmb_reserve_flags(phys_addr_t base, phys_size_t size, u32 flags) +long lmb_reserve(phys_addr_t base, phys_size_t size, u32 flags) { long ret = 0; struct alist *lmb_rgn_lst = &lmb.used_mem; @@ -681,11 +680,6 @@ long lmb_reserve_flags(phys_addr_t base, phys_size_t size, u32 flags) return lmb_map_update_notify(base, size, MAP_OP_RESERVE, flags); } -long lmb_reserve(phys_addr_t base, phys_size_t size) -{ - return lmb_reserve_flags(base, size, LMB_NONE); -} - static phys_addr_t _lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr, u32 flags) { @@ -790,7 +784,7 @@ static phys_addr_t _lmb_alloc_addr(phys_addr_t base, phys_size_t size, lmb_memory[rgn].size, base + size - 1, 1)) { /* ok, reserve the memory */ - if (!lmb_reserve_flags(base, size, flags)) + if (!lmb_reserve(base, size, flags)) return base; } } diff --git a/test/lib/lmb.c b/test/lib/lmb.c index 48c3c966f8f..3c3e862ffa0 100644 --- a/test/lib/lmb.c +++ b/test/lib/lmb.c @@ -117,7 +117,7 @@ static int test_multi_alloc(struct unit_test_state *uts, const phys_addr_t ram, } /* reserve 64KiB somewhere */ - ret = lmb_reserve(alloc_64k_addr, 0x10000); + ret = lmb_reserve(alloc_64k_addr, 0x10000, LMB_NONE); ut_asserteq(ret, 0); ASSERT_LMB(mem_lst, used_lst, 0, 0, 1, alloc_64k_addr, 0x10000, 0, 0, 0, 0); @@ -264,7 +264,7 @@ static int test_bigblock(struct unit_test_state *uts, const phys_addr_t ram) ut_asserteq(ret, 0); /* reserve 64KiB in the middle of RAM */ - ret = lmb_reserve(alloc_64k_addr, 0x10000); + ret = lmb_reserve(alloc_64k_addr, 0x10000, LMB_NONE); ut_asserteq(ret, 0); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, alloc_64k_addr, 0x10000, 0, 0, 0, 0); @@ -466,35 +466,35 @@ static int lib_test_lmb_overlapping_reserve(struct unit_test_state *uts) ret = lmb_add(ram, ram_size); ut_asserteq(ret, 0); - ret = lmb_reserve(0x40010000, 0x10000); + ret = lmb_reserve(0x40010000, 0x10000, LMB_NONE); ut_asserteq(ret, 0); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, 0x40010000, 0x10000, 0, 0, 0, 0); /* allocate overlapping region should return the coalesced count */ - ret = lmb_reserve(0x40011000, 0x10000); + ret = lmb_reserve(0x40011000, 0x10000, LMB_NONE); ut_asserteq(ret, 0); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, 0x40010000, 0x11000, 0, 0, 0, 0); /* allocate 3nd region */ - ret = lmb_reserve(0x40030000, 0x10000); + ret = lmb_reserve(0x40030000, 0x10000, LMB_NONE); ut_asserteq(ret, 0); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 2, 0x40010000, 0x11000, 0x40030000, 0x10000, 0, 0); /* allocate 2nd region , This should coalesced all region into one */ - ret = lmb_reserve(0x40020000, 0x10000); + ret = lmb_reserve(0x40020000, 0x10000, LMB_NONE); ut_assert(ret >= 0); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, 0x40010000, 0x30000, 0, 0, 0, 0); /* allocate 2nd region, which should be added as first region */ - ret = lmb_reserve(0x40000000, 0x8000); + ret = lmb_reserve(0x40000000, 0x8000, LMB_NONE); ut_assert(ret >= 0); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 2, 0x40000000, 0x8000, 0x40010000, 0x30000, 0, 0); /* allocate 3rd region, coalesce with first and overlap with second */ - ret = lmb_reserve(0x40008000, 0x10000); + ret = lmb_reserve(0x40008000, 0x10000, LMB_NONE); ut_assert(ret >= 0); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, 0x40000000, 0x40000, 0, 0, 0, 0); @@ -550,11 +550,11 @@ static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram) ut_asserteq(ret, 0); /* reserve 3 blocks */ - ret = lmb_reserve(alloc_addr_a, 0x10000); + ret = lmb_reserve(alloc_addr_a, 0x10000, LMB_NONE); ut_asserteq(ret, 0); - ret = lmb_reserve(alloc_addr_b, 0x10000); + ret = lmb_reserve(alloc_addr_b, 0x10000, LMB_NONE); ut_asserteq(ret, 0); - ret = lmb_reserve(alloc_addr_c, 0x10000); + ret = lmb_reserve(alloc_addr_c, 0x10000, LMB_NONE); ut_asserteq(ret, 0); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 3, alloc_addr_a, 0x10000, alloc_addr_b, 0x10000, alloc_addr_c, 0x10000); @@ -680,11 +680,11 @@ static int test_get_unreserved_size(struct unit_test_state *uts, ut_asserteq(ret, 0); /* reserve 3 blocks */ - ret = lmb_reserve(alloc_addr_a, 0x10000); + ret = lmb_reserve(alloc_addr_a, 0x10000, LMB_NONE); ut_asserteq(ret, 0); - ret = lmb_reserve(alloc_addr_b, 0x10000); + ret = lmb_reserve(alloc_addr_b, 0x10000, LMB_NONE); ut_asserteq(ret, 0); - ret = lmb_reserve(alloc_addr_c, 0x10000); + ret = lmb_reserve(alloc_addr_c, 0x10000, LMB_NONE); ut_asserteq(ret, 0); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 3, alloc_addr_a, 0x10000, alloc_addr_b, 0x10000, alloc_addr_c, 0x10000); @@ -747,19 +747,19 @@ static int lib_test_lmb_flags(struct unit_test_state *uts) ut_asserteq(ret, 0); /* reserve, same flag */ - ret = lmb_reserve_flags(0x40010000, 0x10000, LMB_NOMAP); + ret = lmb_reserve(0x40010000, 0x10000, LMB_NOMAP); ut_asserteq(ret, 0); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, 0x40010000, 0x10000, 0, 0, 0, 0); /* reserve again, same flag */ - ret = lmb_reserve_flags(0x40010000, 0x10000, LMB_NOMAP); + ret = lmb_reserve(0x40010000, 0x10000, LMB_NOMAP); ut_asserteq(ret, -EEXIST); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, 0x40010000, 0x10000, 0, 0, 0, 0); /* reserve again, new flag */ - ret = lmb_reserve_flags(0x40010000, 0x10000, LMB_NONE); + ret = lmb_reserve(0x40010000, 0x10000, LMB_NONE); ut_asserteq(ret, -1); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, 0x40010000, 0x10000, 0, 0, 0, 0); @@ -767,20 +767,20 @@ static int lib_test_lmb_flags(struct unit_test_state *uts) ut_asserteq(lmb_is_nomap(&used[0]), 1); /* merge after */ - ret = lmb_reserve_flags(0x40020000, 0x10000, LMB_NOMAP); + ret = lmb_reserve(0x40020000, 0x10000, LMB_NOMAP); ut_asserteq(ret, 0); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, 0x40010000, 0x20000, 0, 0, 0, 0); /* merge before */ - ret = lmb_reserve_flags(0x40000000, 0x10000, LMB_NOMAP); + ret = lmb_reserve(0x40000000, 0x10000, LMB_NOMAP); ut_asserteq(ret, 0); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, 0x40000000, 0x30000, 0, 0, 0, 0); ut_asserteq(lmb_is_nomap(&used[0]), 1); - ret = lmb_reserve_flags(0x40030000, 0x10000, LMB_NONE); + ret = lmb_reserve(0x40030000, 0x10000, LMB_NONE); ut_asserteq(ret, 0); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 2, 0x40000000, 0x30000, 0x40030000, 0x10000, 0, 0); @@ -789,7 +789,7 @@ static int lib_test_lmb_flags(struct unit_test_state *uts) ut_asserteq(lmb_is_nomap(&used[1]), 0); /* test that old API use LMB_NONE */ - ret = lmb_reserve(0x40040000, 0x10000); + ret = lmb_reserve(0x40040000, 0x10000, LMB_NONE); ut_asserteq(ret, 0); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 2, 0x40000000, 0x30000, 0x40030000, 0x20000, 0, 0); @@ -797,18 +797,18 @@ static int lib_test_lmb_flags(struct unit_test_state *uts) ut_asserteq(lmb_is_nomap(&used[0]), 1); ut_asserteq(lmb_is_nomap(&used[1]), 0); - ret = lmb_reserve_flags(0x40070000, 0x10000, LMB_NOMAP); + ret = lmb_reserve(0x40070000, 0x10000, LMB_NOMAP); ut_asserteq(ret, 0); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 3, 0x40000000, 0x30000, 0x40030000, 0x20000, 0x40070000, 0x10000); - ret = lmb_reserve_flags(0x40050000, 0x10000, LMB_NOMAP); + ret = lmb_reserve(0x40050000, 0x10000, LMB_NOMAP); ut_asserteq(ret, 0); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 4, 0x40000000, 0x30000, 0x40030000, 0x20000, 0x40050000, 0x10000); /* merge with 2 adjacent regions */ - ret = lmb_reserve_flags(0x40060000, 0x10000, LMB_NOMAP); + ret = lmb_reserve(0x40060000, 0x10000, LMB_NOMAP); ut_asserteq(ret, 0); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 3, 0x40000000, 0x30000, 0x40030000, 0x20000, 0x40050000, 0x30000); -- cgit v1.3.1 From 60a684e0a9f341d96c30ce0e1e472d7a203c85aa Mon Sep 17 00:00:00 2001 From: Jerome Forissier Date: Fri, 13 Dec 2024 13:45:36 +0100 Subject: trace: add support for 'trace wipe' Implement a 'trace wipe' command to delete the currently accumulated trace data. This comes handy when someone needs to trace a particular command. For example: => trace pause; trace wipe => trace resume; dhcp; trace pause => trace stats => trace calls 0x02100000 0x10000000 => tftpput $profbase $profoffset 192.168.0.16:trace.bin Signed-off-by: Jerome Forissier Reviewed-by: Ilias Apalodimas --- cmd/trace.c | 5 +++++ include/trace.h | 2 ++ lib/trace.c | 47 +++++++++++++++++++++++++++++++++-------------- 3 files changed, 40 insertions(+), 14 deletions(-) (limited to 'cmd') diff --git a/cmd/trace.c b/cmd/trace.c index 937e6a682ad..d36008720db 100644 --- a/cmd/trace.c +++ b/cmd/trace.c @@ -100,6 +100,10 @@ int do_trace(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) case 's': trace_print_stats(); break; + case 'w': + if (trace_wipe()) + return CMD_RET_FAILURE; + break; default: return CMD_RET_USAGE; } @@ -113,6 +117,7 @@ U_BOOT_CMD( "stats - display tracing statistics\n" "trace pause - pause tracing\n" "trace resume - resume tracing\n" + "trace wipe - wipe traces\n" "trace funclist [ ] - dump function list into buffer\n" "trace calls [ ] " "- dump function call trace into buffer" diff --git a/include/trace.h b/include/trace.h index 763d6d1255a..782eaae2fc2 100644 --- a/include/trace.h +++ b/include/trace.h @@ -100,6 +100,8 @@ void trace_set_enabled(int enabled); int trace_early_init(void); +int trace_clear(void); + /** * Init the trace system * diff --git a/lib/trace.c b/lib/trace.c index cabbe47b58a..def9f912c92 100644 --- a/lib/trace.c +++ b/lib/trace.c @@ -351,14 +351,8 @@ static int get_func_count(void) return gd->mon_len / FUNC_SITE_SIZE; } -/** - * trace_init() - initialize the tracing system and enable it - * - * @buff: Pointer to trace buffer - * @buff_size: Size of trace buffer - * Return: 0 if ok - */ -int notrace trace_init(void *buff, size_t buff_size) +static int notrace trace_init_(void *buff, size_t buff_size, bool copy_early, + bool enable) { int func_count = get_func_count(); size_t needed; @@ -368,7 +362,7 @@ int notrace trace_init(void *buff, size_t buff_size) return func_count; trace_save_gd(); - if (!was_disabled) { + if (copy_early) { #ifdef CONFIG_TRACE_EARLY ulong used, count; char *end; @@ -394,9 +388,6 @@ int notrace trace_init(void *buff, size_t buff_size) } puts("\n"); memcpy(buff, hdr, used); -#else - puts("trace: already enabled\n"); - return -EALREADY; #endif } hdr = (struct trace_hdr *)buff; @@ -419,13 +410,41 @@ int notrace trace_init(void *buff, size_t buff_size) hdr->ftrace_size = (buff_size - needed) / sizeof(*hdr->ftrace); hdr->depth_limit = CONFIG_TRACE_CALL_DEPTH_LIMIT; - puts("trace: enabled\n"); - trace_enabled = 1; + printf("trace: initialized, %senabled\n", enable ? "" : "not "); + trace_enabled = enable; trace_inited = 1; return 0; } +/** + * trace_init() - initialize the tracing system and enable it + * + * @buff: Pointer to trace buffer + * @buff_size: Size of trace buffer + * Return: 0 if ok + */ +int notrace trace_init(void *buff, size_t buff_size) +{ + /* If traces are enabled already, we may have early traces to copy */ + return trace_init_(buff, buff_size, trace_enabled, true); +} + +/** + * trace_clear() - clear accumulated traced data + * + * May be called with tracing enabled or disabled. + */ +int notrace trace_clear(void) +{ + bool was_enabled = trace_enabled; + + if (trace_enabled) + trace_enabled = 0; + return trace_init_(gd->trace_buff, CONFIG_TRACE_BUFFER_SIZE, + false, was_enabled); +} + #ifdef CONFIG_TRACE_EARLY /** * trace_early_init() - initialize the tracing system for early tracing -- cgit v1.3.1 From e3cf80fbe02d2d46e11c20c3c0e9032d01ae33e2 Mon Sep 17 00:00:00 2001 From: Venkatesh Yadav Abbarapu Date: Thu, 19 Dec 2024 10:09:17 +0530 Subject: cmd: Add support for optee commands Add the basic 'hello world ta' command which increment of the value passed. This provides easy test for establishing a session with OP-TEE TA and verify. It includes following "hello world ta" subcommands: optee hello; default value '0' is passed and gets incremented. optee hello ; value to increment via OP-TEE HELLO WORLD TA. To enable the OP-TEE side HELLO WORLD example please refer https://optee.readthedocs.io/en/latest/building/gits/optee_examples/optee_examples.html Signed-off-by: Venkatesh Yadav Abbarapu Reviewed-by: Jerome Forissier --- cmd/Kconfig | 6 ++++++ cmd/Makefile | 1 + cmd/optee.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+) create mode 100644 cmd/optee.c (limited to 'cmd') diff --git a/cmd/Kconfig b/cmd/Kconfig index 1d7ddb4ed36..4b33468891e 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -1446,6 +1446,12 @@ config CMD_OPTEE_RPMB in the Replay Protection Memory Block partition in eMMC by using Persistent Objects in OPTEE +config CMD_OPTEE + bool "Enable OP-TEE commands" + depends on OPTEE + help + OP-TEE commands support. + config CMD_MTD bool "mtd" depends on MTD diff --git a/cmd/Makefile b/cmd/Makefile index d1f369deec0..533d0f6a1be 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -118,6 +118,7 @@ obj-$(CONFIG_CMD_PAUSE) += pause.o obj-$(CONFIG_CMD_SLEEP) += sleep.o obj-$(CONFIG_CMD_MMC) += mmc.o obj-$(CONFIG_CMD_OPTEE_RPMB) += optee_rpmb.o +obj-$(CONFIG_CMD_OPTEE) += optee.o obj-$(CONFIG_CMD_MP) += mp.o obj-$(CONFIG_CMD_MTD) += mtd.o obj-$(CONFIG_CMD_MTDPARTS) += mtdparts.o diff --git a/cmd/optee.c b/cmd/optee.c new file mode 100644 index 00000000000..d0d37293986 --- /dev/null +++ b/cmd/optee.c @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * (C) Copyright 2024, Advanced Micro Devices, Inc. + */ +#include +#include +#include +#include + +#define TA_HELLO_WORLD_CMD_INC_VALUE 0 +/* This needs to match the UUID of the Hello World TA. */ +#define TA_HELLO_WORLD_UUID \ + { 0x8aaaf200, 0x2450, 0x11e4, \ + { 0xab, 0xe2, 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b} } + +static int hello_world_ta(unsigned int value) +{ + const struct tee_optee_ta_uuid uuid = TA_HELLO_WORLD_UUID; + struct tee_open_session_arg session_arg; + struct udevice *tee = NULL; + struct tee_invoke_arg arg; + struct tee_param param[2]; + int rc; + + tee = tee_find_device(tee, NULL, NULL, NULL); + if (!tee) + return -ENODEV; + + memset(&session_arg, 0, sizeof(session_arg)); + tee_optee_ta_uuid_to_octets(session_arg.uuid, &uuid); + rc = tee_open_session(tee, &session_arg, 0, NULL); + if (rc) { + printf("tee_open_session(): failed(%d)\n", rc); + return rc; + } + + arg.func = TA_HELLO_WORLD_CMD_INC_VALUE; + arg.session = session_arg.session; + + param[0].attr = TEE_PARAM_ATTR_TYPE_VALUE_INOUT; + param[0].u.value.a = value; + + printf("Value before: 0x%x\n", (int)param[0].u.value.a); + printf("Calling TA\n"); + tee_invoke_func(tee, &arg, 1, param); + + printf("Value after: 0x%x\n", (int)param[0].u.value.a); + return tee_close_session(tee, session_arg.session); +} + +static int do_optee_hello_world_ta(struct cmd_tbl *cmdtp, int flag, int argc, + char * const argv[]) +{ + int ret, value = 0; + + if (strcmp(argv[1], NULL)) + value = hextoul(argv[1], NULL); + + ret = hello_world_ta(value); + if (ret) + return CMD_RET_FAILURE; + + return CMD_RET_SUCCESS; +} + +U_BOOT_LONGHELP(optee, + "hello [] Invoke the OP-TEE 'Hello World' TA\n"); + +U_BOOT_CMD_WITH_SUBCMDS(optee, "OP-TEE commands", optee_help_text, + U_BOOT_SUBCMD_MKENT(hello, 2, 1, do_optee_hello_world_ta)); -- cgit v1.3.1