From 3fcbae5f849b2a5c36ad5ca0d90dd94191760053 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 31 Oct 2024 18:50:23 +0100 Subject: dm: sysinfo: Shorten the SYSINFO_ID prefix We are about to add a large number of new entries. Update the prefix to be a little shorter. For SMBIOS items, use SYSID_SM_ (for System Management) which is enough to distinguish it. For now at least, it seems that most items will be for SMBIOS. Signed-off-by: Simon Glass Acked-by: Raymond Mao --- lib/smbios.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'lib') diff --git a/lib/smbios.c b/lib/smbios.c index 7c24ea129eb..a36d4b4e54a 100644 --- a/lib/smbios.c +++ b/lib/smbios.c @@ -270,7 +270,7 @@ static int smbios_add_prop_si(struct smbios_ctx *ctx, const char *prop, static int smbios_add_prop(struct smbios_ctx *ctx, const char *prop, const char *dval) { - return smbios_add_prop_si(ctx, prop, SYSINFO_ID_NONE, dval); + return smbios_add_prop_si(ctx, prop, SYSID_NONE, dval); } static void smbios_set_eos(struct smbios_ctx *ctx, char *eos) @@ -393,27 +393,27 @@ static int smbios_write_type1(ulong *current, int handle, fill_smbios_header(t, SMBIOS_SYSTEM_INFORMATION, len, handle); smbios_set_eos(ctx, t->eos); t->manufacturer = smbios_add_prop_si(ctx, "manufacturer", - SYSINFO_ID_SMBIOS_SYSTEM_MANUFACTURER, + SYSID_SM_SYSTEM_MANUFACTURER, NULL); t->product_name = smbios_add_prop_si(ctx, "product", - SYSINFO_ID_SMBIOS_SYSTEM_PRODUCT, + SYSID_SM_SYSTEM_PRODUCT, NULL); t->version = smbios_add_prop_si(ctx, "version", - SYSINFO_ID_SMBIOS_SYSTEM_VERSION, + SYSID_SM_SYSTEM_VERSION, NULL); if (serial_str) { t->serial_number = smbios_add_prop(ctx, NULL, serial_str); strncpy((char *)t->uuid, serial_str, sizeof(t->uuid)); } else { t->serial_number = smbios_add_prop_si(ctx, "serial", - SYSINFO_ID_SMBIOS_SYSTEM_SERIAL, + SYSID_SM_SYSTEM_SERIAL, NULL); } t->wakeup_type = SMBIOS_WAKEUP_TYPE_UNKNOWN; t->sku_number = smbios_add_prop_si(ctx, "sku", - SYSINFO_ID_SMBIOS_SYSTEM_SKU, NULL); + SYSID_SM_SYSTEM_SKU, NULL); t->family = smbios_add_prop_si(ctx, "family", - SYSINFO_ID_SMBIOS_SYSTEM_FAMILY, NULL); + SYSID_SM_SYSTEM_FAMILY, NULL); len = t->length + smbios_string_table_len(ctx); *current += len; @@ -433,20 +433,20 @@ static int smbios_write_type2(ulong *current, int handle, fill_smbios_header(t, SMBIOS_BOARD_INFORMATION, len, handle); smbios_set_eos(ctx, t->eos); t->manufacturer = smbios_add_prop_si(ctx, "manufacturer", - SYSINFO_ID_SMBIOS_BASEBOARD_MANUFACTURER, + SYSID_SM_BASEBOARD_MANUFACTURER, NULL); t->product_name = smbios_add_prop_si(ctx, "product", - SYSINFO_ID_SMBIOS_BASEBOARD_PRODUCT, + SYSID_SM_BASEBOARD_PRODUCT, NULL); t->version = smbios_add_prop_si(ctx, "version", - SYSINFO_ID_SMBIOS_BASEBOARD_VERSION, + SYSID_SM_BASEBOARD_VERSION, NULL); t->serial_number = smbios_add_prop_si(ctx, "serial", - SYSINFO_ID_SMBIOS_BASEBOARD_SERIAL, + SYSID_SM_BASEBOARD_SERIAL, NULL); t->asset_tag_number = smbios_add_prop_si(ctx, "asset-tag", - SYSINFO_ID_SMBIOS_BASEBOARD_ASSET_TAG, + SYSID_SM_BASEBOARD_ASSET_TAG, NULL); t->feature_flags = SMBIOS_BOARD_FEATURE_HOSTING; t->board_type = SMBIOS_BOARD_MOTHERBOARD; -- cgit v1.3.1 From 9063dba2d326e07682338cdb636787e99f1bf3f5 Mon Sep 17 00:00:00 2001 From: Adriano Cordova Date: Mon, 11 Nov 2024 18:09:45 -0300 Subject: net: net_utils: Move ip_to_string to lib/net_utils.c The function string_to_ip is already in net_utils, which is compiled unconditionally, but ip_to_string is currently only accessible if the legacy network stack is selected. This commit puts ip_to_string in net_utils.c and removes it from the legacy network code. Signed-off-by: Adriano Cordova Reviewed-by: Heinrich Schuchardt --- include/net-common.h | 10 ++++++++++ lib/net_utils.c | 11 +++++++++++ net/net.c | 11 ----------- 3 files changed, 21 insertions(+), 11 deletions(-) (limited to 'lib') diff --git a/include/net-common.h b/include/net-common.h index 3cd0f343744..b7a519e36db 100644 --- a/include/net-common.h +++ b/include/net-common.h @@ -426,6 +426,16 @@ void string_to_enetaddr(const char *addr, uint8_t *enetaddr); */ struct in_addr string_to_ip(const char *s); +/** + * ip_to_string() - Convert a string to ip address + * + * Implemented in lib/net_utils.c (built unconditionally) + * + * @x: Input ip to parse + * @s: string containing the parsed ip address + */ +void ip_to_string(struct in_addr x, char *s); + /* copy a filename (allow for "..." notation, limit length) */ void copy_filename(char *dst, const char *src, int size); diff --git a/lib/net_utils.c b/lib/net_utils.c index c70fef0d991..621f6512b62 100644 --- a/lib/net_utils.c +++ b/lib/net_utils.c @@ -152,6 +152,17 @@ out_err: } #endif +void ip_to_string(struct in_addr x, char *s) +{ + x.s_addr = ntohl(x.s_addr); + sprintf(s, "%d.%d.%d.%d", + (int) ((x.s_addr >> 24) & 0xff), + (int) ((x.s_addr >> 16) & 0xff), + (int) ((x.s_addr >> 8) & 0xff), + (int) ((x.s_addr >> 0) & 0xff) + ); +} + void string_to_enetaddr(const char *addr, uint8_t *enetaddr) { char *end; diff --git a/net/net.c b/net/net.c index f47e9fbe33a..ca35704f661 100644 --- a/net/net.c +++ b/net/net.c @@ -1723,17 +1723,6 @@ int net_parse_bootfile(struct in_addr *ipaddr, char *filename, int max_len) return 1; } -void ip_to_string(struct in_addr x, char *s) -{ - x.s_addr = ntohl(x.s_addr); - sprintf(s, "%d.%d.%d.%d", - (int) ((x.s_addr >> 24) & 0xff), - (int) ((x.s_addr >> 16) & 0xff), - (int) ((x.s_addr >> 8) & 0xff), - (int) ((x.s_addr >> 0) & 0xff) - ); -} - void vlan_to_string(ushort x, char *s) { x = ntohs(x); -- cgit v1.3.1 From d92fdb60677b3990919a4216d3452418db215224 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 1 Nov 2024 10:17:54 +0100 Subject: binman: Add option for pointing to separate description Adding binman node with target images description can be unwanted feature but as of today there is no way to disable it. Also on size constrained systems it is not useful to add binman description to DTB. Introduce BINMAN_DTB Kconfig symbol which allows separate DTB for target from DTB for binman itself. Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/f1379d2587f9bf279a7a75c318aabbc1b35ee0c6.1730452668.git.michal.simek@amd.com --- Makefile | 11 ++++++++++- lib/Kconfig | 9 +++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/Makefile b/Makefile index 22953bdabd8..3434e9582fd 100644 --- a/Makefile +++ b/Makefile @@ -1392,12 +1392,21 @@ endif default_dt := $(if $(DEVICE_TREE),$(DEVICE_TREE),$(CONFIG_DEFAULT_DEVICE_TREE)) endif +binman_dtb := $(shell echo $(CONFIG_BINMAN_DTB)) +ifeq ($(strip $(binman_dtb)),) +ifeq ($(CONFIG_OF_EMBED),y) +binman_dtb = ./dts/dt.dtb +else +binman_dtb = ./u-boot.dtb +endif +endif + quiet_cmd_binman = BINMAN $@ cmd_binman = $(srctree)/tools/binman/binman $(if $(BINMAN_DEBUG),-D) \ $(foreach f,$(BINMAN_TOOLPATHS),--toolpath $(f)) \ --toolpath $(objtree)/tools \ $(if $(BINMAN_VERBOSE),-v$(BINMAN_VERBOSE)) \ - build -u -d u-boot.dtb -O . -m \ + build -u -d $(binman_dtb) -O . -m \ --allow-missing --fake-ext-blobs \ $(if $(BINMAN_ALLOW_MISSING),--ignore-missing) \ -I . -I $(srctree) -I $(srctree)/board/$(BOARDDIR) \ diff --git a/lib/Kconfig b/lib/Kconfig index 56ffdfa1839..0b089814d14 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -45,6 +45,15 @@ config BINMAN_FDT locate entries in the firmware image. See binman.h for the available functionality. +config BINMAN_DTB + string "binman DTB description" + depends on BINMAN + help + This enables option to point to different DTB file with binman node which + is outside of DTB used by the firmware. Use this option if information + about generated images shouldn't be the part of target binary. Or on system + with limited storage. + config CC_OPTIMIZE_LIBS_FOR_SPEED bool "Optimize libraries for speed" help -- cgit v1.3.1 From f0dab28915b7890d5a7d958bc4b6f9b61f535cb4 Mon Sep 17 00:00:00 2001 From: Benedikt Spranger Date: Fri, 18 Oct 2024 10:30:02 +0200 Subject: tiny-printf: Handle NULL pointer argument to %s A NULL pointer argument to %s causes a NULL pointer dereference in the fixed width numerical printout code, since p is overwritten with NULL. In case of %s width is 0. Check width before dereferencing the pointer. Signed-off-by: Benedikt Spranger Reviewed-by: John Ogness --- lib/tiny-printf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/tiny-printf.c b/lib/tiny-printf.c index cc1dfe61cf7..0503c17341f 100644 --- a/lib/tiny-printf.c +++ b/lib/tiny-printf.c @@ -312,7 +312,7 @@ static int _vprintf(struct printf_info *info, const char *fmt, va_list va) *info->bf = 0; info->bf = p; - while (*info->bf++ && width > 0) + while (width > 0 && info->bf && *info->bf++) width--; while (width-- > 0) info->putc(info, lz ? '0' : ' '); -- cgit v1.3.1 From e46e4d6fd7f969f0e60b0f54b69830da543b0d96 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 27 Nov 2024 11:17:19 -0600 Subject: sandbox: efi_loader: Correct use of addresses as pointers The cache-flush function is incorrect which causes a crash in the remoteproc tests with arm64. Fix both problems by using map_sysmem() to convert an address to a pointer and map_to_sysmem() to convert a pointer to an address. Also update the image-loader's cache-flushing logic. Signed-off-by: Simon Glass Fixes: 3286d223fd7 ("sandbox: implement invalidate_icache_all()") Acked-by: Heinrich Schuchardt Changes in v6: - Re-introduce Changes in v2: - Drop message about EFI_LOADER arch/sandbox/cpu/cache.c | 8 +++++++- drivers/remoteproc/rproc-elf-loader.c | 18 +++++++++++------- lib/efi_loader/efi_image_loader.c | 3 ++- 3 files changed, 20 insertions(+), 9 deletions(-) Reviewed-by: Heinrich Schuchardt --- arch/sandbox/cpu/cache.c | 8 +++++++- drivers/remoteproc/rproc-elf-loader.c | 18 +++++++++++------- lib/efi_loader/efi_image_loader.c | 3 ++- 3 files changed, 20 insertions(+), 9 deletions(-) (limited to 'lib') diff --git a/arch/sandbox/cpu/cache.c b/arch/sandbox/cpu/cache.c index c8a5e64214b..96b3da47e8e 100644 --- a/arch/sandbox/cpu/cache.c +++ b/arch/sandbox/cpu/cache.c @@ -4,12 +4,18 @@ */ #include +#include #include void flush_cache(unsigned long addr, unsigned long size) { + void *ptr; + + ptr = map_sysmem(addr, size); + /* Clang uses (char *) parameters, GCC (void *) */ - __builtin___clear_cache((void *)addr, (void *)(addr + size)); + __builtin___clear_cache(map_sysmem(addr, size), ptr + size); + unmap_sysmem(ptr); } void invalidate_icache_all(void) diff --git a/drivers/remoteproc/rproc-elf-loader.c b/drivers/remoteproc/rproc-elf-loader.c index ab1836b3f07..0b3941b7798 100644 --- a/drivers/remoteproc/rproc-elf-loader.c +++ b/drivers/remoteproc/rproc-elf-loader.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -180,6 +181,7 @@ int rproc_elf32_load_image(struct udevice *dev, unsigned long addr, ulong size) for (i = 0; i < ehdr->e_phnum; i++, phdr++) { void *dst = (void *)(uintptr_t)phdr->p_paddr; void *src = (void *)addr + phdr->p_offset; + ulong dst_addr; if (phdr->p_type != PT_LOAD) continue; @@ -195,10 +197,11 @@ int rproc_elf32_load_image(struct udevice *dev, unsigned long addr, ulong size) if (phdr->p_filesz != phdr->p_memsz) memset(dst + phdr->p_filesz, 0x00, phdr->p_memsz - phdr->p_filesz); - flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN), - roundup((unsigned long)dst + phdr->p_filesz, + dst_addr = map_to_sysmem(dst); + flush_cache(rounddown(dst_addr, ARCH_DMA_MINALIGN), + roundup(dst_addr + phdr->p_filesz, ARCH_DMA_MINALIGN) - - rounddown((unsigned long)dst, ARCH_DMA_MINALIGN)); + rounddown(dst_addr, ARCH_DMA_MINALIGN)); } return 0; @@ -377,6 +380,7 @@ int rproc_elf32_load_rsc_table(struct udevice *dev, ulong fw_addr, const struct dm_rproc_ops *ops; Elf32_Shdr *shdr; void *src, *dst; + ulong dst_addr; shdr = rproc_elf32_find_rsc_table(dev, fw_addr, fw_size); if (!shdr) @@ -398,10 +402,10 @@ int rproc_elf32_load_rsc_table(struct udevice *dev, ulong fw_addr, (ulong)dst, *rsc_size); memcpy(dst, src, *rsc_size); - flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN), - roundup((unsigned long)dst + *rsc_size, - ARCH_DMA_MINALIGN) - - rounddown((unsigned long)dst, ARCH_DMA_MINALIGN)); + dst_addr = map_to_sysmem(dst); + flush_cache(rounddown(dst_addr, ARCH_DMA_MINALIGN), + roundup(dst_addr + *rsc_size, ARCH_DMA_MINALIGN) - + rounddown(dst_addr, ARCH_DMA_MINALIGN)); return 0; } diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c index 0ddf69a0918..bb58cf1badb 100644 --- a/lib/efi_loader/efi_image_loader.c +++ b/lib/efi_loader/efi_image_loader.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -977,7 +978,7 @@ efi_status_t efi_load_pe(struct efi_loaded_image_obj *handle, } /* Flush cache */ - flush_cache((ulong)efi_reloc, + flush_cache(map_to_sysmem(efi_reloc), ALIGN(virt_size, EFI_CACHELINE_SIZE)); /* -- cgit v1.3.1 From 9bab7d2a7c37b486ed6c368cfdfb42575ab112e4 Mon Sep 17 00:00:00 2001 From: Adriano Cordova Date: Wed, 4 Dec 2024 00:05:16 -0300 Subject: net: wget: let wget_with_dns work with dns disabled This was marked as TODO in the code: - Enable use of wget_with_dns even if CMD_DNS is disabled if the given uri has the ip address for the http server. - Move the check for CMD_DNS inside wget_with_dns. - Rename wget_with_dns to wget_do_request Signed-off-by: Adriano Cordova Reviewed-by: Heinrich Schuchardt Reviewed-by: Jerome Forissier --- include/net-common.h | 7 +++++-- lib/efi_loader/efi_bootmgr.c | 2 +- net/lwip/wget.c | 4 ++-- net/net-common.c | 2 +- net/wget.c | 34 ++++++++++++++++++++-------------- 5 files changed, 29 insertions(+), 20 deletions(-) (limited to 'lib') diff --git a/include/net-common.h b/include/net-common.h index c5e314b360d..8fc1bac47f5 100644 --- a/include/net-common.h +++ b/include/net-common.h @@ -501,13 +501,16 @@ int dhcp_run(ulong addr, const char *fname, bool autoload); int do_tftpb(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); /** - * wget_with_dns() - runs dns host IP address resulution before wget + * wget_do_request() - sends a wget request + * + * Sends a wget request, if DNS resolution is enabled it resolves the + * given uri. * * @dst_addr: destination address to download the file * @uri: uri string of target file of wget * Return: zero on success, negative if failed */ -int wget_with_dns(ulong dst_addr, char *uri); +int wget_do_request(ulong dst_addr, char *uri); /** * wget_validate_uri() - varidate the uri * diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c index 8c51a6ef2ed..c6124c590d9 100644 --- a/lib/efi_loader/efi_bootmgr.c +++ b/lib/efi_loader/efi_bootmgr.c @@ -479,7 +479,7 @@ static efi_status_t try_load_from_uri_path(struct efi_device_path_uri *uridp, } image_addr = hextoul(s, NULL); - err = wget_with_dns(image_addr, uridp->uri); + err = wget_do_request(image_addr, uridp->uri); if (err < 0) { ret = EFI_INVALID_PARAMETER; goto err; diff --git a/net/lwip/wget.c b/net/lwip/wget.c index 263d6dab26c..669eded0f38 100644 --- a/net/lwip/wget.c +++ b/net/lwip/wget.c @@ -353,7 +353,7 @@ static int wget_loop(struct udevice *udev, ulong dst_addr, char *uri) return -1; } -int wget_with_dns(ulong dst_addr, char *uri) +int wget_do_request(ulong dst_addr, char *uri) { eth_set_current(); @@ -387,7 +387,7 @@ int do_wget(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]) return CMD_RET_FAILURE; wget_info = &default_wget_info; - if (wget_with_dns(dst_addr, nurl)) + if (wget_do_request(dst_addr, nurl)) return CMD_RET_FAILURE; return CMD_RET_SUCCESS; diff --git a/net/net-common.c b/net/net-common.c index 45288fe5f80..e01b0da7d7b 100644 --- a/net/net-common.c +++ b/net/net-common.c @@ -23,5 +23,5 @@ struct wget_http_info *wget_info; int wget_request(ulong dst_addr, char *uri, struct wget_http_info *info) { wget_info = info ? info : &default_wget_info; - return wget_with_dns(dst_addr, uri); + return wget_do_request(dst_addr, uri); } diff --git a/net/wget.c b/net/wget.c index 5d70b7a82e0..f3b43b06b8b 100644 --- a/net/wget.c +++ b/net/wget.c @@ -535,8 +535,7 @@ void wget_start(void) wget_send(TCP_SYN, 0, 0, 0); } -#if (IS_ENABLED(CONFIG_CMD_DNS)) -int wget_with_dns(ulong dst_addr, char *uri) +int wget_do_request(ulong dst_addr, char *uri) { int ret; char *s, *host_name, *file_name, *str_copy; @@ -555,24 +554,32 @@ int wget_with_dns(ulong dst_addr, char *uri) s = str_copy + strlen("http://"); host_name = strsep(&s, "/"); if (!s) { - log_err("Error: invalied uri, no file path\n"); ret = -EINVAL; goto out; } file_name = s; - /* TODO: If the given uri has ip address for the http server, skip dns */ - net_dns_resolve = host_name; - net_dns_env_var = "httpserverip"; - if (net_loop(DNS) < 0) { - log_err("Error: dns lookup of %s failed, check setup\n", net_dns_resolve); - ret = -EINVAL; - goto out; - } - s = env_get("httpserverip"); - if (!s) { + host_name = strsep(&host_name, ":"); + + if (string_to_ip(host_name).s_addr) { + s = host_name; + } else { +#if IS_ENABLED(CONFIG_CMD_DNS) + net_dns_resolve = host_name; + net_dns_env_var = "httpserverip"; + if (net_loop(DNS) < 0) { + ret = -EINVAL; + goto out; + } + s = env_get("httpserverip"); + if (!s) { + ret = -EINVAL; + goto out; + } +#else ret = -EINVAL; goto out; +#endif } strlcpy(net_boot_file_name, s, sizeof(net_boot_file_name)); @@ -586,7 +593,6 @@ out: return ret < 0 ? ret : 0; } -#endif /** * wget_validate_uri() - validate the uri for wget -- cgit v1.3.1 From f43641decffd6fdef60ee38751983c70747a0edc Mon Sep 17 00:00:00 2001 From: Adriano Cordova Date: Wed, 4 Dec 2024 00:05:18 -0300 Subject: efi_loader: device_path: add efi_dp_from_ipv4 Add efi_dp_from_ipv4 to form a device path from an ipv4 address. Signed-off-by: Adriano Cordova Reviewed-by: Ilias Apalodimas --- lib/efi_loader/efi_device_path.c | 47 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'lib') diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c index ee387e1dfd4..6fcbc91e0ba 100644 --- a/lib/efi_loader/efi_device_path.c +++ b/lib/efi_loader/efi_device_path.c @@ -974,6 +974,53 @@ struct efi_device_path __maybe_unused *efi_dp_from_eth(void) return start; } +/** + * efi_dp_from_ipv4() - set device path from IPv4 address + * + * Set the device path to an ethernet device path as provided by + * efi_dp_from_eth() concatenated with a device path of subtype + * DEVICE_PATH_SUB_TYPE_MSG_IPV4, and an END node. + * + * @ip: IPv4 local address + * @mask: network mask + * @srv: IPv4 remote/server address + * Return: pointer to device path, NULL on error + */ +static struct efi_device_path *efi_dp_from_ipv4(struct efi_ipv4_address *ip, + struct efi_ipv4_address *mask, + struct efi_ipv4_address *srv) +{ + struct efi_device_path *dp1, *dp2, *pos; + struct { + struct efi_device_path_ipv4 ipv4dp; + struct efi_device_path end; + } dp; + + memset(&dp.ipv4dp, 0, sizeof(dp.ipv4dp)); + dp.ipv4dp.dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE; + dp.ipv4dp.dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_IPV4; + dp.ipv4dp.dp.length = sizeof(dp.ipv4dp); + dp.ipv4dp.protocol = 6; + if (ip) + memcpy(&dp.ipv4dp.local_ip_address, ip, sizeof(*ip)); + if (mask) + memcpy(&dp.ipv4dp.subnet_mask, mask, sizeof(*mask)); + if (srv) + memcpy(&dp.ipv4dp.remote_ip_address, srv, sizeof(*srv)); + pos = &dp.end; + memcpy(pos, &END, sizeof(END)); + + dp1 = efi_dp_from_eth(); + if (!dp1) + return NULL; + + dp2 = efi_dp_concat(dp1, (const struct efi_device_path *)&dp, 0); + + efi_free_pool(dp1); + + return dp2; +} + /* Construct a device-path for memory-mapped image */ struct efi_device_path *efi_dp_from_mem(uint32_t memory_type, uint64_t start_address, -- cgit v1.3.1 From aaf63429a1121167a4e742c1ff8ecb75d478efb2 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Wed, 4 Dec 2024 00:05:19 -0300 Subject: efi_loader: add IPv4() to device path to text protocol Implement Ipv4() node support in the device path to text protocol. Signed-off-by: Adriano Cordova Reviewed-by: Ilias Apalodimas Signed-off-by: Heinrich Schuchardt --- lib/efi_loader/efi_device_path_to_text.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'lib') diff --git a/lib/efi_loader/efi_device_path_to_text.c b/lib/efi_loader/efi_device_path_to_text.c index 0c7b30a26e7..481a9712d9d 100644 --- a/lib/efi_loader/efi_device_path_to_text.c +++ b/lib/efi_loader/efi_device_path_to_text.c @@ -8,6 +8,7 @@ #include #include #include +#include #define MAC_OUTPUT_LEN 22 #define UNKNOWN_OUTPUT_LEN 23 @@ -170,6 +171,28 @@ static char *dp_msging(char *s, struct efi_device_path *dp) break; } + case DEVICE_PATH_SUB_TYPE_MSG_IPV4: { + struct efi_device_path_ipv4 *idp = + (struct efi_device_path_ipv4 *)dp; + + s += sprintf(s, "IPv4(%pI4,", &idp->remote_ip_address); + switch (idp->protocol) { + case IPPROTO_TCP: + s += sprintf(s, "TCP,"); + case IPPROTO_UDP: + s += sprintf(s, "UDP,"); + default: + s += sprintf(s, "0x%x,", idp->protocol); + } + s += sprintf(s, idp->static_ip_address ? "Static" : "DHCP"); + s += sprintf(s, ",%pI4", &idp->local_ip_address); + if (idp->dp.length == sizeof(struct efi_device_path_ipv4)) + s += sprintf(s, ",%pI4,%pI4", &idp->gateway_ip_address, + &idp->subnet_mask); + s += sprintf(s, ")"); + + break; + } case DEVICE_PATH_SUB_TYPE_MSG_USB_CLASS: { struct efi_device_path_usb_class *ucdp = (struct efi_device_path_usb_class *)dp; -- cgit v1.3.1 From b20f497f22a76785f4c615af78a5b70f6ba49046 Mon Sep 17 00:00:00 2001 From: Adriano Cordova Date: Wed, 4 Dec 2024 00:05:21 -0300 Subject: efi_loader: efi_net: add efi_net_set_addr, efi_net_get_addr Add the functions efi_net_set_addr and efi_net_get_addr to set and get the ip address from efi code in a network agnostic way. This could also go in net_common, or be compiled conditionally for each network stack. Signed-off-by: Adriano Cordova Reviewed-by: Heinrich Schuchardt --- include/efi_loader.h | 16 ++++++ lib/efi_loader/efi_net.c | 125 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 141 insertions(+) (limited to 'lib') diff --git a/include/efi_loader.h b/include/efi_loader.h index 39809eac1bc..612bc42816b 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -125,6 +125,22 @@ static inline void efi_set_bootdev(const char *dev, const char *devnr, size_t buffer_size) { } #endif +#if CONFIG_IS_ENABLED(NETDEVICES) && CONFIG_IS_ENABLED(EFI_LOADER) +void efi_net_get_addr(struct efi_ipv4_address *ip, + struct efi_ipv4_address *mask, + struct efi_ipv4_address *gw); +void efi_net_set_addr(struct efi_ipv4_address *ip, + struct efi_ipv4_address *mask, + struct efi_ipv4_address *gw); +#else +static inline void efi_net_get_addr(struct efi_ipv4_address *ip, + struct efi_ipv4_address *mask, + struct efi_ipv4_address *gw) { } +static inline void efi_net_set_addr(struct efi_ipv4_address *ip, + struct efi_ipv4_address *mask, + struct efi_ipv4_address *gw) { } +#endif + /* Maximum number of configuration tables */ #define EFI_MAX_CONFIGURATION_TABLES 16 diff --git a/lib/efi_loader/efi_net.c b/lib/efi_loader/efi_net.c index 7cd536705f4..3491d4c4818 100644 --- a/lib/efi_loader/efi_net.c +++ b/lib/efi_loader/efi_net.c @@ -17,6 +17,7 @@ #include #include +#include #include static const efi_guid_t efi_net_guid = EFI_SIMPLE_NETWORK_PROTOCOL_GUID; @@ -997,3 +998,127 @@ out_of_resources: printf("ERROR: Out of memory\n"); return EFI_OUT_OF_RESOURCES; } + +/** + * efi_net_get_addr() - get IP address information + * + * Copy the current IP address, mask, and gateway into the + * efi_ipv4_address structs pointed to by ip, mask and gw, + * respectively. + * + * @ip: pointer to an efi_ipv4_address struct to + * be filled with the current IP address + * @mask: pointer to an efi_ipv4_address struct to + * be filled with the current network mask + * @gw: pointer to an efi_ipv4_address struct to be + * filled with the current network gateway + */ +void efi_net_get_addr(struct efi_ipv4_address *ip, + struct efi_ipv4_address *mask, + struct efi_ipv4_address *gw) +{ +#ifdef CONFIG_NET_LWIP + char ipstr[] = "ipaddr\0\0"; + char maskstr[] = "netmask\0\0"; + char gwstr[] = "gatewayip\0\0"; + int idx; + struct in_addr tmp; + char *env; + + idx = dev_seq(eth_get_dev()); + + if (idx < 0 || idx > 99) { + log_err("unexpected idx %d\n", idx); + return; + } + + if (idx) { + sprintf(ipstr, "ipaddr%d", idx); + sprintf(maskstr, "netmask%d", idx); + sprintf(gwstr, "gatewayip%d", idx); + } + + env = env_get(ipstr); + if (env && ip) { + tmp = string_to_ip(env); + memcpy(ip, &tmp, sizeof(tmp)); + } + + env = env_get(maskstr); + if (env && mask) { + tmp = string_to_ip(env); + memcpy(mask, &tmp, sizeof(tmp)); + } + env = env_get(gwstr); + if (env && gw) { + tmp = string_to_ip(env); + memcpy(gw, &tmp, sizeof(tmp)); + } +#else + if (ip) + memcpy(ip, &net_ip, sizeof(net_ip)); + if (mask) + memcpy(mask, &net_netmask, sizeof(net_netmask)); +#endif +} + +/** + * efi_net_set_addr() - set IP address information + * + * Set the current IP address, mask, and gateway to the + * efi_ipv4_address structs pointed to by ip, mask and gw, + * respectively. + * + * @ip: pointer to new IP address + * @mask: pointer to new network mask to set + * @gw: pointer to new network gateway + */ +void efi_net_set_addr(struct efi_ipv4_address *ip, + struct efi_ipv4_address *mask, + struct efi_ipv4_address *gw) +{ +#ifdef CONFIG_NET_LWIP + char ipstr[] = "ipaddr\0\0"; + char maskstr[] = "netmask\0\0"; + char gwstr[] = "gatewayip\0\0"; + int idx; + struct in_addr *addr; + char tmp[46]; + + idx = dev_seq(eth_get_dev()); + + if (idx < 0 || idx > 99) { + log_err("unexpected idx %d\n", idx); + return; + } + + if (idx) { + sprintf(ipstr, "ipaddr%d", idx); + sprintf(maskstr, "netmask%d", idx); + sprintf(gwstr, "gatewayip%d", idx); + } + + if (ip) { + addr = (struct in_addr *)ip; + ip_to_string(*addr, tmp); + env_set(ipstr, tmp); + } + + if (mask) { + addr = (struct in_addr *)mask; + ip_to_string(*addr, tmp); + env_set(maskstr, tmp); + } + + if (gw) { + addr = (struct in_addr *)gw; + ip_to_string(*addr, tmp); + env_set(gwstr, tmp); + } +#else + if (ip) + memcpy(&net_ip, ip, sizeof(*ip)); + if (mask) + memcpy(&net_netmask, mask, sizeof(*mask)); +#endif +} -- cgit v1.3.1 From 4b0723004b65bfaab528ce3aa669eb552e06130a Mon Sep 17 00:00:00 2001 From: Adriano Cordova Date: Wed, 4 Dec 2024 00:05:22 -0300 Subject: efi_loader: device_path: add support for HTTP device path Add efi_dp_from_http to form a device path from HTTP. The device path is the concatenation of the device path returned by efi_dp_from_ipv4 together with an URI node and an END node. Signed-off-by: Adriano Cordova Reviewed-by: Heinrich Schuchardt Reviewed-by: Ilias Apalodimas --- include/efi_loader.h | 1 + lib/efi_loader/efi_device_path.c | 64 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) (limited to 'lib') diff --git a/include/efi_loader.h b/include/efi_loader.h index 612bc42816b..96b204dfc31 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -872,6 +872,7 @@ struct efi_device_path *efi_dp_part_node(struct blk_desc *desc, int part); struct efi_device_path *efi_dp_from_file(const struct efi_device_path *dp, const char *path); struct efi_device_path *efi_dp_from_eth(void); +struct efi_device_path *efi_dp_from_http(const char *server); struct efi_device_path *efi_dp_from_mem(uint32_t mem_type, uint64_t start_address, size_t size); diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c index 6fcbc91e0ba..a6d43006869 100644 --- a/lib/efi_loader/efi_device_path.c +++ b/lib/efi_loader/efi_device_path.c @@ -1021,6 +1021,70 @@ static struct efi_device_path *efi_dp_from_ipv4(struct efi_ipv4_address *ip, return dp2; } +/** + * efi_dp_from_http() - set device path from http + * + * Set the device path to an IPv4 path as provided by efi_dp_from_ipv4 + * concatenated with a device path of subtype DEVICE_PATH_SUB_TYPE_MSG_URI, + * and an END node. + * + * @server: URI of remote server + * Return: pointer to HTTP device path, NULL on error + */ +struct efi_device_path *efi_dp_from_http(const char *server) +{ + struct efi_device_path *dp1, *dp2; + struct efi_device_path_uri *uridp; + efi_uintn_t uridp_len; + char *pos; + char tmp[128]; + struct efi_ipv4_address ip; + struct efi_ipv4_address mask; + + if ((server && strlen("http://") + strlen(server) + 1 > sizeof(tmp)) || + (!server && IS_ENABLED(CONFIG_NET_LWIP))) + return NULL; + + efi_net_get_addr(&ip, &mask, NULL); + + dp1 = efi_dp_from_ipv4(&ip, &mask, NULL); + if (!dp1) + return NULL; + + strcpy(tmp, "http://"); + + if (server) { + strlcat(tmp, server, sizeof(tmp)); +#if !IS_ENABLED(CONFIG_NET_LWIP) + } + else { + ip_to_string(net_server_ip, tmp + strlen("http://")); +#endif + } + + uridp_len = sizeof(struct efi_device_path) + strlen(tmp) + 1; + uridp = efi_alloc(uridp_len + sizeof(END)); + if (!uridp) { + log_err("Out of memory\n"); + return NULL; + } + uridp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE; + uridp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_URI; + uridp->dp.length = uridp_len; + debug("device path: setting uri device path to %s\n", tmp); + memcpy(uridp->uri, tmp, strlen(tmp) + 1); + + pos = (char *)uridp + uridp_len; + memcpy(pos, &END, sizeof(END)); + + dp2 = efi_dp_concat(dp1, (const struct efi_device_path *)uridp, 0); + + efi_free_pool(uridp); + efi_free_pool(dp1); + + return dp2; +} + /* Construct a device-path for memory-mapped image */ struct efi_device_path *efi_dp_from_mem(uint32_t memory_type, uint64_t start_address, -- cgit v1.3.1 From e55a4acb54e807c6411c4f6ab914fa2b3f55784e Mon Sep 17 00:00:00 2001 From: Adriano Cordova Date: Wed, 4 Dec 2024 00:05:23 -0300 Subject: efi_loader: net: set EFI bootdevice device path to HTTP when loaded from wget Set the device path of the efi boot device to an HTTP device path (as formed by efi_dp_from_http) when the next boot stage is loaded using wget (i.e., when wget is used with wget_info.set_bootdev=1). When loaded from HTTP, the device path should account for it so that the next boot stage is aware (e.g. grub only loads its http stack if it itself was loaded from http, and it checks this from its device path). Signed-off-by: Adriano Cordova Reviewed-by: Heinrich Schuchardt --- include/efi_loader.h | 5 ++++ lib/efi_loader/efi_bootbin.c | 42 ++++++++++++++++++------------ lib/efi_loader/efi_device_path.c | 5 ++-- lib/efi_loader/efi_net.c | 55 +++++++++++++++++++++++++++++++++++++++- net/lwip/wget.c | 5 ++-- net/wget.c | 2 +- 6 files changed, 91 insertions(+), 23 deletions(-) (limited to 'lib') diff --git a/include/efi_loader.h b/include/efi_loader.h index 96b204dfc31..0da0248db46 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -126,6 +126,10 @@ static inline void efi_set_bootdev(const char *dev, const char *devnr, #endif #if CONFIG_IS_ENABLED(NETDEVICES) && CONFIG_IS_ENABLED(EFI_LOADER) +/* Call this to update the current device path of the efi net device */ +efi_status_t efi_net_set_dp(const char *dev, const char *server); +/* Call this to get the current device path of the efi net device */ +void efi_net_get_dp(struct efi_device_path **dp); void efi_net_get_addr(struct efi_ipv4_address *ip, struct efi_ipv4_address *mask, struct efi_ipv4_address *gw); @@ -133,6 +137,7 @@ void efi_net_set_addr(struct efi_ipv4_address *ip, struct efi_ipv4_address *mask, struct efi_ipv4_address *gw); #else +static inline void efi_net_get_dp(struct efi_device_path **dp) { } static inline void efi_net_get_addr(struct efi_ipv4_address *ip, struct efi_ipv4_address *mask, struct efi_ipv4_address *gw) { } diff --git a/lib/efi_loader/efi_bootbin.c b/lib/efi_loader/efi_bootbin.c index a87006b3c0e..b677bbc3124 100644 --- a/lib/efi_loader/efi_bootbin.c +++ b/lib/efi_loader/efi_bootbin.c @@ -93,24 +93,34 @@ void efi_set_bootdev(const char *dev, const char *devnr, const char *path, image_addr = buffer; image_size = buffer_size; +#if IS_ENABLED(CONFIG_NETDEVICES) + if (!strcmp(dev, "Net") || !strcmp(dev, "Http")) { + ret = efi_net_set_dp(dev, devnr); + if (ret != EFI_SUCCESS) + goto error; + } +#endif + ret = efi_dp_from_name(dev, devnr, path, &device, &image); - if (ret == EFI_SUCCESS) { - bootefi_device_path = device; - if (image) { - /* FIXME: image should not contain device */ - struct efi_device_path *image_tmp = image; - - efi_dp_split_file_path(image, &device, &image); - efi_free_pool(image_tmp); - } - bootefi_image_path = image; - log_debug("- boot device %pD\n", device); - if (image) - log_debug("- image %pD\n", image); - } else { - log_debug("- efi_dp_from_name() failed, err=%lx\n", ret); - efi_clear_bootdev(); + if (ret != EFI_SUCCESS) + goto error; + + bootefi_device_path = device; + if (image) { + /* FIXME: image should not contain device */ + struct efi_device_path *image_tmp = image; + + efi_dp_split_file_path(image, &device, &image); + efi_free_pool(image_tmp); } + bootefi_image_path = image; + log_debug("- boot device %pD\n", device); + if (image) + log_debug("- image %pD\n", image); + return; +error: + log_debug("- efi_dp_from_name() failed, err=%lx\n", ret); + efi_clear_bootdev(); } /** diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c index a6d43006869..5eae6fd39cc 100644 --- a/lib/efi_loader/efi_device_path.c +++ b/lib/efi_loader/efi_device_path.c @@ -1185,8 +1185,9 @@ efi_status_t efi_dp_from_name(const char *dev, const char *devnr, dp = efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE, (uintptr_t)image_addr, image_size); - } else if (IS_ENABLED(CONFIG_NETDEVICES) && !strcmp(dev, "Net")) { - dp = efi_dp_from_eth(); + } else if (IS_ENABLED(CONFIG_NETDEVICES) && + (!strcmp(dev, "Net") || !strcmp(dev, "Http"))) { + efi_net_get_dp(&dp); } else if (!strcmp(dev, "Uart")) { dp = efi_dp_from_uart(); } else { diff --git a/lib/efi_loader/efi_net.c b/lib/efi_loader/efi_net.c index 3491d4c4818..e8af2e3d95e 100644 --- a/lib/efi_loader/efi_net.c +++ b/lib/efi_loader/efi_net.c @@ -16,6 +16,7 @@ */ #include +#include #include #include #include @@ -32,6 +33,13 @@ static int rx_packet_idx; static int rx_packet_num; static struct efi_net_obj *netobj; +/* + * The current network device path. This device path is updated when a new + * bootfile is downloaded from the network. If then the bootfile is loaded + * as an efi image, net_dp is passed as the device path of the loaded image. + */ +static struct efi_device_path *net_dp; + /* * The notification function of this event is called in every timer cycle * to check if a new network packet has been received. @@ -902,8 +910,10 @@ efi_status_t efi_net_register(void) &netobj->net); if (r != EFI_SUCCESS) goto failure_to_add_protocol; + if (!net_dp) + efi_net_set_dp("Net", NULL); r = efi_add_protocol(&netobj->header, &efi_guid_device_path, - efi_dp_from_eth()); + net_dp); if (r != EFI_SUCCESS) goto failure_to_add_protocol; r = efi_add_protocol(&netobj->header, &efi_pxe_base_code_protocol_guid, @@ -999,6 +1009,49 @@ out_of_resources: return EFI_OUT_OF_RESOURCES; } +/** + * efi_net_set_dp() - set device path of efi net device + * + * This gets called to update the device path when a new boot + * file is downloaded + * + * @dev: dev to set the device path from + * @server: remote server address + * Return: status code + */ +efi_status_t efi_net_set_dp(const char *dev, const char *server) +{ + efi_free_pool(net_dp); + + net_dp = NULL; + if (!strcmp(dev, "Net")) + net_dp = efi_dp_from_eth(); + else if (!strcmp(dev, "Http")) + net_dp = efi_dp_from_http(server); + + if (!net_dp) + return EFI_OUT_OF_RESOURCES; + + return EFI_SUCCESS; +} + +/** + * efi_net_get_dp() - get device path of efi net device + * + * Produce a copy of the current device path + * + * @dp: copy of the current device path, or NULL on error + */ +void efi_net_get_dp(struct efi_device_path **dp) +{ + if (!dp) + return; + if (!net_dp) + efi_net_set_dp("Net", NULL); + if (net_dp) + *dp = efi_dp_dup(net_dp); +} + /** * efi_net_get_addr() - get IP address information * diff --git a/net/lwip/wget.c b/net/lwip/wget.c index 669eded0f38..c23f0640ec6 100644 --- a/net/lwip/wget.c +++ b/net/lwip/wget.c @@ -260,10 +260,9 @@ static void httpc_result_cb(void *arg, httpc_result_t httpc_result, printf("%u bytes transferred in %lu ms (", rx_content_len, elapsed); print_size(rx_content_len / elapsed * 1000, "/s)\n"); printf("Bytes transferred = %lu (%lx hex)\n", ctx->size, ctx->size); - if (wget_info->set_bootdev) { - efi_set_bootdev("Net", "", ctx->path, map_sysmem(ctx->saved_daddr, 0), + if (wget_info->set_bootdev) + efi_set_bootdev("Http", ctx->server_name, ctx->path, map_sysmem(ctx->saved_daddr, 0), rx_content_len); - } wget_lwip_set_file_size(rx_content_len); if (env_set_hex("filesize", rx_content_len) || env_set_hex("fileaddr", ctx->saved_daddr)) { diff --git a/net/wget.c b/net/wget.c index f3b43b06b8b..d338eaf4ef3 100644 --- a/net/wget.c +++ b/net/wget.c @@ -447,7 +447,7 @@ static void wget_handler(uchar *pkt, u16 dport, net_set_state(wget_loop_state); 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, + efi_set_bootdev("Http", NULL, image_url, map_sysmem(image_load_addr, 0), net_boot_file_size); env_set_hex("filesize", net_boot_file_size); -- cgit v1.3.1 From 5a5c5bf40a0ea479426ad3f5c0cbc5afa675786f Mon Sep 17 00:00:00 2001 From: Adriano Cordova Date: Wed, 4 Dec 2024 00:05:24 -0300 Subject: efi_loader: net: add support to send http requests and parse http headers Add network-stack agnostic way to send an http request and parse http headers from efi drivers. This uses wget as a backend and communicates with it via efi_wget_info. The function efi_net_do_request allocates a buffer on behalf of an efi application using efi_alloc and passes it to wget to receive the data. If the method is GET and the buffer is too small, it re-allocates the buffer based on the last received Content-Length header and tries again. If the method is HEAD it just issues one request. So issuing a HEAD request (to update Content-Length) and then a GET request is preferred but not required. The function efi_net_parse_headers parses a raw buffer containing an http header into an array of EFI specific 'http_header' structs. Signed-off-by: Adriano Cordova Reviewed-by: Heinrich Schuchardt --- include/efi_loader.h | 13 ++++ lib/efi_loader/efi_net.c | 155 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 168 insertions(+) (limited to 'lib') diff --git a/include/efi_loader.h b/include/efi_loader.h index 0da0248db46..b6f865ca769 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -16,6 +16,7 @@ #include #include #include +#include #include struct blk_desc; @@ -136,6 +137,18 @@ void efi_net_get_addr(struct efi_ipv4_address *ip, void efi_net_set_addr(struct efi_ipv4_address *ip, struct efi_ipv4_address *mask, struct efi_ipv4_address *gw); +efi_status_t efi_net_do_request(u8 *url, enum efi_http_method method, void **buffer, + u32 *status_code, ulong *file_size, char *headers_buffer); +#define MAX_HTTP_HEADERS_SIZE SZ_64K +#define MAX_HTTP_HEADERS 100 +#define MAX_HTTP_HEADER_NAME 128 +#define MAX_HTTP_HEADER_VALUE 512 +struct http_header { + uchar name[MAX_HTTP_HEADER_NAME]; + uchar value[MAX_HTTP_HEADER_VALUE]; +}; + +void efi_net_parse_headers(ulong *num_headers, struct http_header *headers); #else static inline void efi_net_get_dp(struct efi_device_path **dp) { } static inline void efi_net_get_addr(struct efi_ipv4_address *ip, diff --git a/lib/efi_loader/efi_net.c b/lib/efi_loader/efi_net.c index e8af2e3d95e..368f62c5b2d 100644 --- a/lib/efi_loader/efi_net.c +++ b/lib/efi_loader/efi_net.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -40,6 +41,12 @@ static struct efi_net_obj *netobj; */ static struct efi_device_path *net_dp; +static struct wget_http_info efi_wget_info = { + .set_bootdev = false, + .check_buffer_size = true, + +}; + /* * The notification function of this event is called in every timer cycle * to check if a new network packet has been received. @@ -1175,3 +1182,151 @@ void efi_net_set_addr(struct efi_ipv4_address *ip, memcpy(&net_netmask, mask, sizeof(*mask)); #endif } + +/** + * efi_net_set_buffer() - allocate a buffer of min 64K + * + * @buffer: allocated buffer + * @size: desired buffer size + * Return: status code + */ +static efi_status_t efi_net_set_buffer(void **buffer, size_t size) +{ + efi_status_t ret = EFI_SUCCESS; + + if (size < SZ_64K) + size = SZ_64K; + + efi_free_pool(*buffer); + + *buffer = efi_alloc(size); + if (!*buffer) + ret = EFI_OUT_OF_RESOURCES; + + efi_wget_info.buffer_size = (ulong)size; + + return ret; +} + +/** + * efi_net_parse_headers() - parse HTTP headers + * + * Parses the raw buffer efi_wget_info.headers into an array headers + * of efi structs http_headers. The array should be at least + * MAX_HTTP_HEADERS long. + * + * @num_headers: number of headers + * @headers: caller provided array of struct http_headers + */ +void efi_net_parse_headers(ulong *num_headers, struct http_header *headers) +{ + if (!num_headers || !headers) + return; + + // Populate info with http headers. + *num_headers = 0; + const uchar *line_start = efi_wget_info.headers; + const uchar *line_end; + ulong count; + struct http_header *current_header; + const uchar *separator; + size_t name_length, value_length; + + // Skip the first line (request or status line) + line_end = strstr(line_start, "\r\n"); + + if (line_end) + line_start = line_end + 2; + + while ((line_end = strstr(line_start, "\r\n")) != NULL) { + count = *num_headers; + if (line_start == line_end || count >= MAX_HTTP_HEADERS) + break; + current_header = headers + count; + separator = strchr(line_start, ':'); + if (separator) { + name_length = separator - line_start; + ++separator; + while (*separator == ' ') + ++separator; + value_length = line_end - separator; + if (name_length < MAX_HTTP_HEADER_NAME && + value_length < MAX_HTTP_HEADER_VALUE) { + strncpy(current_header->name, line_start, name_length); + current_header->name[name_length] = '\0'; + strncpy(current_header->value, separator, value_length); + current_header->value[value_length] = '\0'; + (*num_headers)++; + } + } + line_start = line_end + 2; + } +} + +/** + * efi_net_do_request() - issue an HTTP request using wget + * + * @url: url + * @method: HTTP method + * @buffer: data buffer + * @status_code: HTTP status code + * @file_size: file size in bytes + * @headers_buffer: headers buffer + * Return: status code + */ +efi_status_t efi_net_do_request(u8 *url, enum efi_http_method method, void **buffer, + u32 *status_code, ulong *file_size, char *headers_buffer) +{ + efi_status_t ret = EFI_SUCCESS; + int wget_ret; + static bool last_head; + + if (!buffer || !file_size) + return EFI_ABORTED; + + efi_wget_info.method = (enum wget_http_method)method; + efi_wget_info.headers = headers_buffer; + + switch (method) { + case HTTP_METHOD_GET: + ret = efi_net_set_buffer(buffer, last_head ? (size_t)efi_wget_info.hdr_cont_len : 0); + if (ret != EFI_SUCCESS) + goto out; + wget_ret = wget_request((ulong)*buffer, url, &efi_wget_info); + if ((ulong)efi_wget_info.hdr_cont_len > efi_wget_info.buffer_size) { + // Try again with updated buffer size + ret = efi_net_set_buffer(buffer, (size_t)efi_wget_info.hdr_cont_len); + if (ret != EFI_SUCCESS) + goto out; + if (wget_request((ulong)*buffer, url, &efi_wget_info)) { + efi_free_pool(*buffer); + ret = EFI_DEVICE_ERROR; + goto out; + } + } else if (wget_ret) { + efi_free_pool(*buffer); + ret = EFI_DEVICE_ERROR; + goto out; + } + // Pass the actual number of received bytes to the application + *file_size = efi_wget_info.file_size; + *status_code = efi_wget_info.status_code; + last_head = false; + break; + case HTTP_METHOD_HEAD: + ret = efi_net_set_buffer(buffer, 0); + if (ret != EFI_SUCCESS) + goto out; + wget_request((ulong)*buffer, url, &efi_wget_info); + *file_size = 0; + *status_code = efi_wget_info.status_code; + last_head = true; + break; + default: + ret = EFI_UNSUPPORTED; + break; + } + +out: + return ret; +} -- cgit v1.3.1 From 929363cbb35ef9943f9c02938dc23d2c78582c5f Mon Sep 17 00:00:00 2001 From: Adriano Cordova Date: Wed, 4 Dec 2024 00:05:25 -0300 Subject: efi_loader: efi_net: add EFI_IP4_CONFIG2_PROTOCOL Add an implementation of the EFI_IP4_CONFIG2_PROTOCOL. The protocol is attached to the handle of the efi network device. This is the same handle where snp and pxe are attached to. Signed-off-by: Adriano Cordova --- include/efi_loader.h | 3 + lib/efi_loader/Kconfig | 9 ++ lib/efi_loader/Makefile | 1 + lib/efi_loader/efi_ipconfig.c | 214 ++++++++++++++++++++++++++++++++++++++++++ lib/efi_loader/efi_net.c | 20 +++- 5 files changed, 242 insertions(+), 5 deletions(-) create mode 100644 lib/efi_loader/efi_ipconfig.c (limited to 'lib') diff --git a/include/efi_loader.h b/include/efi_loader.h index b6f865ca769..9be09a799ba 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -626,6 +626,9 @@ int efi_disk_create_partitions(efi_handle_t parent, struct blk_desc *desc, efi_status_t efi_gop_register(void); /* Called by bootefi to make the network interface available */ efi_status_t efi_net_register(void); +/* Called by efi_net_register to make the ip4 config2 protocol available */ +efi_status_t efi_ipconfig_register(const efi_handle_t handle, + struct efi_ip4_config2_protocol *ip4config); /* Called by bootefi to make the watchdog available */ efi_status_t efi_watchdog_register(void); efi_status_t efi_initrd_register(void); diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index d93f28b8422..0b932df85c5 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -476,6 +476,15 @@ config EFI_RISCV_BOOT_PROTOCOL replace the transfer via the device-tree. The latter is not possible on systems using ACPI. +config EFI_IP4_CONFIG2_PROTOCOL + bool "EFI_IP4_CONFIG2_PROTOCOL support" + default y if ARCH_QEMU || SANDBOX + depends on NET || NET_LWIP + help + Provides an implementation of the EFI_IP4_CONFIG2_PROTOCOL, this + protocol can be used to set and get the current ip address and + other network information. + endmenu menu "Misc options" diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile index 87131ab911d..30cd1de9d60 100644 --- a/lib/efi_loader/Makefile +++ b/lib/efi_loader/Makefile @@ -59,6 +59,7 @@ obj-$(CONFIG_EFI_ESRT) += efi_esrt.o obj-$(CONFIG_VIDEO) += efi_gop.o obj-$(CONFIG_BLK) += efi_disk.o obj-$(CONFIG_NETDEVICES) += efi_net.o +obj-$(CONFIG_EFI_IP4_CONFIG2_PROTOCOL) += efi_ipconfig.o obj-$(CONFIG_ACPI) += efi_acpi.o obj-$(CONFIG_SMBIOS) += efi_smbios.o obj-$(CONFIG_EFI_RNG_PROTOCOL) += efi_rng.o diff --git a/lib/efi_loader/efi_ipconfig.c b/lib/efi_loader/efi_ipconfig.c new file mode 100644 index 00000000000..0b247a4c028 --- /dev/null +++ b/lib/efi_loader/efi_ipconfig.c @@ -0,0 +1,214 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Implementation of EFI_IP4_CONFIG2_PROTOCOL + * + */ + +#include +#include +#include +#include +#include + +static const efi_guid_t efi_ip4_config2_guid = EFI_IP4_CONFIG2_PROTOCOL_GUID; + +struct efi_ip4_config2_manual_address current_http_ip; +static enum efi_ip4_config2_policy current_policy; +static char current_mac_addr[32]; + +/* EFI_IP4_CONFIG2_PROTOCOL */ + +/* + * efi_ip4_config2_set_data() - Set the configuration for the EFI IPv4 network + * stack running on the communication device + * + * This function implements EFI_IP4_CONFIG2_PROTOCOL.SetData() + * See the Unified Extensible Firmware Interface + * (UEFI) specification for details. + * + * @this: pointer to the protocol instance + * @data_type: the type of data to set + * @data_size: size of the buffer pointed to by data in bytes + * @data: the data buffer to set + * Return: status code + */ +static efi_status_t EFIAPI efi_ip4_config2_set_data(struct efi_ip4_config2_protocol *this, + enum efi_ip4_config2_data_type data_type, + efi_uintn_t data_size, + void *data) +{ + EFI_ENTRY("%p, %d, %zu, %p", this, data_type, data_size, data); + efi_status_t ret = EFI_SUCCESS; + + if (!this || (data && !data_size) || (!data && data_size)) + return EFI_EXIT(EFI_INVALID_PARAMETER); + + switch (data_type) { + case EFI_IP4_CONFIG2_DATA_TYPE_INTERFACEINFO: + return EFI_EXIT(EFI_WRITE_PROTECTED); + case EFI_IP4_CONFIG2_DATA_TYPE_MANUAL_ADDRESS: + if (current_policy != EFI_IP4_CONFIG2_POLICY_STATIC) + return EFI_EXIT(EFI_WRITE_PROTECTED); + if (!data_size && !data) { + memset((void *)¤t_http_ip, 0, + sizeof(current_http_ip)); + return EFI_EXIT(EFI_SUCCESS); + } + if (data && data_size == sizeof(struct efi_ip4_config2_manual_address)) { + memcpy((void *)¤t_http_ip, data, + sizeof(struct efi_ip4_config2_manual_address)); + efi_net_set_addr(¤t_http_ip.address, + ¤t_http_ip.subnet_mask, NULL); + return EFI_EXIT(EFI_SUCCESS); + } + return EFI_EXIT(EFI_BAD_BUFFER_SIZE); + case EFI_IP4_CONFIG2_DATA_TYPE_POLICY: + if (data && data_size == sizeof(enum efi_ip4_config2_policy)) { + current_policy = *(enum efi_ip4_config2_policy *)data; + return EFI_EXIT(EFI_SUCCESS); + } + return EFI_EXIT(EFI_BAD_BUFFER_SIZE); + + default: + return EFI_EXIT(EFI_UNSUPPORTED); + } + + return EFI_EXIT(ret); +} + +/* + * efi_ip4_config2_get_data() - Get the configuration for the EFI IPv4 network + * stack running on the communication device + * + * This function implements EFI_IP4_CONFIG2_PROTOCOL.GetData() + * See the Unified Extensible Firmware Interface + * (UEFI) specification for details. + * + * @this: pointer to the protocol instance + * @data_type: the type of data to get + * @data_size: size + * @data: the data buffer + * Return: status code + */ +static efi_status_t EFIAPI efi_ip4_config2_get_data(struct efi_ip4_config2_protocol *this, + enum efi_ip4_config2_data_type data_type, + efi_uintn_t *data_size, + void *data) +{ + EFI_ENTRY("%p, %d, %p, %p", this, data_type, data_size, data); + + efi_status_t ret = EFI_SUCCESS; + struct efi_ip4_config2_interface_info *info; + int tmp; + + if (!this || !data_size) + return EFI_EXIT(EFI_INVALID_PARAMETER); + + if (*data_size && !data) + return EFI_EXIT(EFI_INVALID_PARAMETER); + + tmp = sizeof(struct efi_ip4_config2_interface_info) + sizeof(struct efi_ip4_route_table); + + switch (data_type) { + case EFI_IP4_CONFIG2_DATA_TYPE_INTERFACEINFO: + if (*data_size < tmp) { + *data_size = tmp; + return EFI_EXIT(EFI_BUFFER_TOO_SMALL); + } + + info = (struct efi_ip4_config2_interface_info *)data; + memset(info, 0, sizeof(*info)); + + info->hw_address_size = 6; + memcpy(info->hw_address.mac_addr, current_mac_addr, 6); + // Set the route table size + + info->route_table_size = 0; + break; + case EFI_IP4_CONFIG2_DATA_TYPE_MANUAL_ADDRESS: + if (*data_size < sizeof(struct efi_ip4_config2_manual_address)) { + *data_size = sizeof(struct efi_ip4_config2_manual_address); + return EFI_EXIT(EFI_BUFFER_TOO_SMALL); + } + + efi_net_get_addr(¤t_http_ip.address, ¤t_http_ip.subnet_mask, NULL); + memcpy(data, (void *)¤t_http_ip, + sizeof(struct efi_ip4_config2_manual_address)); + + break; + default: + return EFI_EXIT(EFI_NOT_FOUND); + } + return EFI_EXIT(ret); +} + +/* + * efi_ip4_config2_register_notify() - Register an event that is to be signaled whenever + * a configuration process on the specified configuration + * data is done + * + * This function implements EFI_IP4_CONFIG2_PROTOCOL.RegisterDataNotify() + * See the Unified Extensible Firmware Interface + * (UEFI) specification for details. + * + * @this: pointer to the protocol instance + * @data_type: the type of data to register the event for + * @event: the event to register + * Return: status code + */ +static efi_status_t EFIAPI efi_ip4_config2_register_notify(struct efi_ip4_config2_protocol *this, + enum efi_ip4_config2_data_type data_type, + struct efi_event *event) +{ + EFI_ENTRY("%p, %d, %p", this, data_type, event); + + return EFI_EXIT(EFI_UNSUPPORTED); +} + +/* + * efi_ip4_config2_unregister_notify() - Remove a previously registered eventfor + * the specified configuration data + * + * This function implements EFI_IP4_CONFIG2_PROTOCOL.UnregisterDataNotify() + * See the Unified Extensible Firmware Interface + * (UEFI) specification for details. + * + * @this: pointer to the protocol instance + * @data_type: the type of data to remove the event for + * @event: the event to unregister + * Return: status code + */ +static efi_status_t EFIAPI efi_ip4_config2_unregister_notify(struct efi_ip4_config2_protocol *this, + enum efi_ip4_config2_data_type data_type, + struct efi_event *event) +{ + EFI_ENTRY("%p, %d, %p", this, data_type, event); + + return EFI_EXIT(EFI_UNSUPPORTED); +} + +/** + * efi_ipconfig_register() - register the ip4_config2 protocol + * + */ +efi_status_t efi_ipconfig_register(const efi_handle_t handle, + struct efi_ip4_config2_protocol *ip4config) +{ + efi_status_t r = EFI_SUCCESS; + + r = efi_add_protocol(handle, &efi_ip4_config2_guid, + ip4config); + if (r != EFI_SUCCESS) { + log_err("ERROR: Failure to add protocol\n"); + return r; + } + + memcpy(current_mac_addr, eth_get_ethaddr(), 6); + + ip4config->set_data = efi_ip4_config2_set_data; + ip4config->get_data = efi_ip4_config2_get_data; + ip4config->register_data_notify = efi_ip4_config2_register_notify; + ip4config->unregister_data_notify = efi_ip4_config2_unregister_notify; + + return EFI_SUCCESS; +} diff --git a/lib/efi_loader/efi_net.c b/lib/efi_loader/efi_net.c index 368f62c5b2d..916c15999e2 100644 --- a/lib/efi_loader/efi_net.c +++ b/lib/efi_loader/efi_net.c @@ -60,11 +60,12 @@ static struct efi_event *wait_for_packet; /** * struct efi_net_obj - EFI object representing a network interface * - * @header: EFI object header - * @net: simple network protocol interface - * @net_mode: status of the network interface - * @pxe: PXE base code protocol interface - * @pxe_mode: status of the PXE base code protocol + * @header: EFI object header + * @net: simple network protocol interface + * @net_mode: status of the network interface + * @pxe: PXE base code protocol interface + * @pxe_mode: status of the PXE base code protocol + * @ip4_config2: IP4 Config2 protocol interface */ struct efi_net_obj { struct efi_object header; @@ -72,6 +73,9 @@ struct efi_net_obj { struct efi_simple_network_mode net_mode; struct efi_pxe_base_code_protocol pxe; struct efi_pxe_mode pxe_mode; +#if IS_ENABLED(CONFIG_EFI_IP4_CONFIG2_PROTOCOL) + struct efi_ip4_config2_protocol ip4_config2; +#endif }; /* @@ -999,6 +1003,12 @@ efi_status_t efi_net_register(void) return r; } +#if IS_ENABLED(CONFIG_EFI_IP4_CONFIG2_PROTOCOL) + r = efi_ipconfig_register(&netobj->header, &netobj->ip4_config2); + if (r != EFI_SUCCESS) + goto failure_to_add_protocol; +#endif + return EFI_SUCCESS; failure_to_add_protocol: printf("ERROR: Failure to add protocol\n"); -- cgit v1.3.1 From 238e0269d82f9662b27cd040e32c3543ccf3380f Mon Sep 17 00:00:00 2001 From: Adriano Cordova Date: Wed, 4 Dec 2024 00:05:26 -0300 Subject: efi_loader: efi_net: add EFI_HTTP_PROTOCOL Add an EFI HTTP driver. This commit implements the EFI_HTTP_PROTOCOL and the EFI_HTTP_SERVICE_BINDING_PROTOCOL. The latter is attached to the handle of th efi network device. This is the same handle where snp, pxe, and ipconfig are attached to. Signed-off-by: Adriano Cordova --- include/efi_loader.h | 3 + lib/efi_loader/Kconfig | 8 + lib/efi_loader/Makefile | 1 + lib/efi_loader/efi_http.c | 548 ++++++++++++++++++++++++++++++++++++++++++++++ lib/efi_loader/efi_net.c | 20 +- 5 files changed, 578 insertions(+), 2 deletions(-) create mode 100644 lib/efi_loader/efi_http.c (limited to 'lib') diff --git a/include/efi_loader.h b/include/efi_loader.h index 9be09a799ba..9afbec35ebf 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -629,6 +629,9 @@ efi_status_t efi_net_register(void); /* Called by efi_net_register to make the ip4 config2 protocol available */ efi_status_t efi_ipconfig_register(const efi_handle_t handle, struct efi_ip4_config2_protocol *ip4config); +/* Called by efi_net_register to make the http protocol available */ +efi_status_t efi_http_register(const efi_handle_t handle, + struct efi_service_binding_protocol *http_service_binding); /* Called by bootefi to make the watchdog available */ efi_status_t efi_watchdog_register(void); efi_status_t efi_initrd_register(void); diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index 0b932df85c5..5c73457d9b9 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -485,6 +485,14 @@ config EFI_IP4_CONFIG2_PROTOCOL protocol can be used to set and get the current ip address and other network information. +config EFI_HTTP_PROTOCOL + bool "EFI_HTTP_PROTOCOL support" + default y if ARCH_QEMU || SANDBOX + depends on WGET + help + Provides an EFI HTTP driver implementing the EFI_HTTP_PROTOCOL. and + EFI_HTTP_SERVICE_BINDING_PROTOCOL. + endmenu menu "Misc options" diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile index 30cd1de9d60..2a0b4172bd7 100644 --- a/lib/efi_loader/Makefile +++ b/lib/efi_loader/Makefile @@ -60,6 +60,7 @@ obj-$(CONFIG_VIDEO) += efi_gop.o obj-$(CONFIG_BLK) += efi_disk.o obj-$(CONFIG_NETDEVICES) += efi_net.o obj-$(CONFIG_EFI_IP4_CONFIG2_PROTOCOL) += efi_ipconfig.o +obj-$(CONFIG_EFI_HTTP_PROTOCOL) += efi_http.o obj-$(CONFIG_ACPI) += efi_acpi.o obj-$(CONFIG_SMBIOS) += efi_smbios.o obj-$(CONFIG_EFI_RNG_PROTOCOL) += efi_rng.o diff --git a/lib/efi_loader/efi_http.c b/lib/efi_loader/efi_http.c new file mode 100644 index 00000000000..694e1993418 --- /dev/null +++ b/lib/efi_loader/efi_http.c @@ -0,0 +1,548 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * An HTTP driver + * + * HTTP_PROTOCOL + * HTTP_SERVICE_BINDING_PROTOCOL + * IP4_CONFIG2_PROTOCOL + */ + +#include +#include +#include +#include +#include +#include + +static const efi_guid_t efi_http_service_binding_guid = EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID; +static const efi_guid_t efi_http_guid = EFI_HTTP_PROTOCOL_GUID; + +/** + * struct efi_http_instance - EFI object representing an HTTP protocol instance + * + * @http: EFI_HTTP_PROTOCOL interface + * @handle: handle to efi object + * @configured: configuration status + * @http_load_addr: data buffer + * @file_size: size of data + * @current_offset: offset in data buffer + * @status_code: HTTP status code + * @num_headers: number of received headers + * @headers: array of headers + * @headers_buffer: raw buffer with headers + */ +struct efi_http_instance { + struct efi_http_protocol http; + efi_handle_t handle; + bool configured; + void *http_load_addr; + ulong file_size; + ulong current_offset; + u32 status_code; + ulong num_headers; + struct http_header headers[MAX_HTTP_HEADERS]; + char headers_buffer[MAX_HTTP_HEADERS_SIZE]; +}; + +static int num_instances; + +/* + * efi_u32_to_httpstatus() - convert u32 to status + * + */ +enum efi_http_status_code efi_u32_to_httpstatus(u32 status); + +/* + * efi_http_send_data() - sends data to client + * + * + * @client_buffer: client buffer to send data to + * @client_buffer_size: size of the client buffer + * @inst: HTTP instance for which to send data + * + * Return: status code + */ +static efi_status_t efi_http_send_data(void *client_buffer, + efi_uintn_t *client_buffer_size, + struct efi_http_instance *inst) +{ + efi_status_t ret = EFI_SUCCESS; + ulong total_size, transfer_size; + uchar *ptr; + + // Amount of data left; + total_size = inst->file_size; + transfer_size = total_size - inst->current_offset; + debug("efi_http: sending data to client, total size %lu\n", total_size); + // Amount of data the client is willing to receive + if (transfer_size > *client_buffer_size) + transfer_size = *client_buffer_size; + else + *client_buffer_size = transfer_size; + debug("efi_http: transfer size %lu\n", transfer_size); + if (!transfer_size) // Ok, only headers + goto out; + + if (!client_buffer) { + ret = EFI_INVALID_PARAMETER; + goto out; + } + + // Send data + ptr = (uchar *)inst->http_load_addr + inst->current_offset; + memcpy(client_buffer, ptr, transfer_size); + + inst->current_offset += transfer_size; + + // Whole file served, clean the buffer: + if (inst->current_offset == inst->file_size) { + efi_free_pool(inst->http_load_addr); + inst->http_load_addr = NULL; + inst->current_offset = 0; + inst->file_size = 0; + } + +out: + return ret; +} + +/* EFI_HTTP_PROTOCOL */ + +/* + * efi_http_get_mode_data() - Gets the current operational status. + * + * This function implements EFI_HTTP_PROTOCOL.GetModeData(). + * See the Unified Extensible Firmware Interface + * (UEFI) specification for details. + * + * @this: pointer to the protocol instance + * @data: pointer to the buffer for operational parameters + * of this HTTP instance + * Return: status code + */ +static efi_status_t EFIAPI efi_http_get_mode_data(struct efi_http_protocol *this, + struct efi_http_config_data *data) +{ + EFI_ENTRY("%p, %p", this, data); + + efi_status_t ret = EFI_UNSUPPORTED; + + return EFI_EXIT(ret); +} + +/* + * efi_http_configure() - Initializes operational status for this + * EFI HTTP instance. + * + * This function implements EFI_HTTP_PROTOCOL.Configure(). + * See the Unified Extensible Firmware Interface + * (UEFI) specification for details. + * + * @this: pointer to the protocol instance + * @data: pointer to the buffer for operational parameters of + * this HTTP instance + * Return: status code + */ +static efi_status_t EFIAPI efi_http_configure(struct efi_http_protocol *this, + struct efi_http_config_data *data) +{ + EFI_ENTRY("%p, %p", this, data); + + efi_status_t ret = EFI_SUCCESS; + enum efi_http_version http_version; + struct efi_httpv4_access_point *ipv4_node; + struct efi_http_instance *http_instance; + + if (!this) { + ret = EFI_INVALID_PARAMETER; + goto out; + } + + http_instance = (struct efi_http_instance *)this; + + if (!data) { + efi_free_pool(http_instance->http_load_addr); + http_instance->http_load_addr = NULL; + http_instance->current_offset = 0; + http_instance->configured = false; + + goto out; + } + + if (http_instance->configured) { + ret = EFI_ALREADY_STARTED; + goto out; + } + + http_version = data->http_version; + ipv4_node = data->access_point.ipv4_node; + + if ((http_version != HTTPVERSION10 && + http_version != HTTPVERSION11) || + data->is_ipv6 || !ipv4_node) { /* Only support ipv4 */ + ret = EFI_UNSUPPORTED; + goto out; + } + + if (!ipv4_node->use_default_address) { + efi_net_set_addr((struct efi_ipv4_address *)&ipv4_node->local_address, + (struct efi_ipv4_address *)&ipv4_node->local_subnet, NULL); + } + + http_instance->current_offset = 0; + http_instance->configured = true; + +out: + return EFI_EXIT(ret); +} + +/* + * efi_http_request() - Queues an HTTP request to this HTTP instance + * + * This function implements EFI_HTTP_PROTOCOL.Request(). + * See the Unified Extensible Firmware Interface + * (UEFI) specification for details. + * + * @this: pointer to the protocol instance + * @token: pointer to storage containing HTTP request token + * Return: status code + */ +static efi_status_t EFIAPI efi_http_request(struct efi_http_protocol *this, + struct efi_http_token *token) +{ + EFI_ENTRY("%p, %p", this, token); + + efi_status_t ret = EFI_SUCCESS; + u8 *tmp; + u8 url_8[1024]; + u16 *url_16; + enum efi_http_method current_method; + struct efi_http_instance *http_instance; + + if (!token || !this || !token->message || + !token->message->data.request) { + ret = EFI_INVALID_PARAMETER; + goto out; + } + + http_instance = (struct efi_http_instance *)this; + + if (!http_instance->configured) { + ret = EFI_NOT_STARTED; + goto out; + } + + current_method = token->message->data.request->method; + url_16 = token->message->data.request->url; + + /* Parse URL. It comes in UCS-2 encoding and follows RFC3986 */ + tmp = url_8; + utf16_utf8_strncpy((char **)&tmp, url_16, 1024); + + ret = efi_net_do_request(url_8, current_method, &http_instance->http_load_addr, + &http_instance->status_code, &http_instance->file_size, + http_instance->headers_buffer); + if (ret != EFI_SUCCESS) + goto out; + + // We have a successful request + efi_net_parse_headers(&http_instance->num_headers, http_instance->headers); + http_instance->current_offset = 0; + token->status = EFI_SUCCESS; + goto out_signal; + +out_signal: + efi_signal_event(token->event); +out: + return EFI_EXIT(ret); +} + +/* + * efi_http_cancel() - Abort an asynchronous HTTP request or response token + * + * This function implements EFI_HTTP_PROTOCOL.Cancel(). + * See the Unified Extensible Firmware Interface + * (UEFI) specification for details. + * + * @this: pointer to the protocol instance + * @token: pointer to storage containing HTTP request token + * Return: status code + */ +static efi_status_t EFIAPI efi_http_cancel(struct efi_http_protocol *this, + struct efi_http_token *token) +{ + EFI_ENTRY("%p, %p", this, token); + + efi_status_t ret = EFI_UNSUPPORTED; + + return EFI_EXIT(ret); +} + +/* + * efi_http_response() - Queues an HTTP response to this HTTP instance + * + * This function implements EFI_HTTP_PROTOCOL.Response(). + * See the Unified Extensible Firmware Interface + * (UEFI) specification for details. + * + * @this: pointer to the protocol instance + * @token: pointer to storage containing HTTP request token + * Return: status code + */ +static efi_status_t EFIAPI efi_http_response(struct efi_http_protocol *this, + struct efi_http_token *token) +{ + EFI_ENTRY("%p, %p", this, token); + + efi_status_t ret = EFI_SUCCESS; + struct efi_http_instance *http_instance; + struct efi_http_header **client_headers; + struct efi_http_response_data *response; + + if (!token || !this || !token->message) { + ret = EFI_INVALID_PARAMETER; + goto out; + } + + http_instance = (struct efi_http_instance *)this; + + // Set HTTP status code + if (token->message->data.response) { // TODO extra check, see spec. + response = token->message->data.response; + response->status_code = efi_u32_to_httpstatus(http_instance->status_code); + } + + client_headers = &token->message->headers; + + ret = efi_allocate_pool(EFI_BOOT_SERVICES_DATA, + (http_instance->num_headers) * sizeof(struct efi_http_header), + (void **)client_headers); // This is deallocated by the client. + if (ret != EFI_SUCCESS) + goto out_bad_signal; + + // Send headers + token->message->header_count = http_instance->num_headers; + for (int i = 0; i < http_instance->num_headers; i++) { + (*client_headers)[i].field_name = http_instance->headers[i].name; + (*client_headers)[i].field_value = http_instance->headers[i].value; + } + + ret = efi_http_send_data(token->message->body, &token->message->body_length, http_instance); + if (ret != EFI_SUCCESS) + goto out_bad_signal; + + token->status = EFI_SUCCESS; + goto out_signal; + +out_bad_signal: + token->status = EFI_ABORTED; +out_signal: + efi_signal_event(token->event); +out: + return EFI_EXIT(ret); +} + +/* + * efi_http_poll() - Polls for incoming data packets and processes outgoing data packets + * + * This function implements EFI_HTTP_PROTOCOL.Poll(). + * See the Unified Extensible Firmware Interface + * (UEFI) specification for details. + * + * @this: pointer to the protocol instance + * @token: pointer to storage containing HTTP request token + * Return: status code + */ +static efi_status_t EFIAPI efi_http_poll(struct efi_http_protocol *this) +{ + EFI_ENTRY("%p", this); + + efi_status_t ret = EFI_UNSUPPORTED; + + return EFI_EXIT(ret); +} + +/* EFI_HTTP_SERVICE_BINDING_PROTOCOL */ + +/* + * efi_http_service_binding_create_child() - Creates a child handle + * and installs a protocol + * + * This function implements EFI_HTTP_SERVICE_BINDING.CreateChild(). + * See the Unified Extensible Firmware Interface + * (UEFI) specification for details. + * + * @this: pointer to the protocol instance + * @child_handle: pointer to child handle + * Return: status code + */ +static efi_status_t EFIAPI efi_http_service_binding_create_child( + struct efi_service_binding_protocol *this, + efi_handle_t *child_handle) +{ + EFI_ENTRY("%p, %p", this, child_handle); + + efi_status_t ret = EFI_SUCCESS; + struct efi_http_instance *new_instance; + + if (!child_handle) + return EFI_EXIT(EFI_INVALID_PARAMETER); + + new_instance = calloc(1, sizeof(struct efi_http_instance)); + if (!new_instance) { + ret = EFI_OUT_OF_RESOURCES; + goto failure_to_add_protocol; + } + + if (*child_handle) { + new_instance->handle = *child_handle; + goto install; + } + + new_instance->handle = calloc(1, sizeof(struct efi_object)); + if (!new_instance->handle) { + efi_free_pool((void *)new_instance); + ret = EFI_OUT_OF_RESOURCES; + goto failure_to_add_protocol; + } + + efi_add_handle(new_instance->handle); + *child_handle = new_instance->handle; + +install: + ret = efi_add_protocol(new_instance->handle, &efi_http_guid, + &new_instance->http); + if (ret != EFI_SUCCESS) + goto failure_to_add_protocol; + + new_instance->http.get_mode_data = efi_http_get_mode_data; + new_instance->http.configure = efi_http_configure; + new_instance->http.request = efi_http_request; + new_instance->http.cancel = efi_http_cancel; + new_instance->http.response = efi_http_response; + new_instance->http.poll = efi_http_poll; + ++num_instances; + + return EFI_EXIT(EFI_SUCCESS); + +failure_to_add_protocol: + return EFI_EXIT(ret); +} + +/* + * efi_http_service_binding_destroy_child() - Destroys a child handle with + * a protocol installed on it + * + * This function implements EFI_HTTP_SERVICE_BINDING.DestroyChild(). + * See the Unified Extensible Firmware Interface + * (UEFI) specification for details. + * + * @this: pointer to the protocol instance + * @child_handle: child handle + * Return: status code + */ +static efi_status_t EFIAPI efi_http_service_binding_destroy_child( + struct efi_service_binding_protocol *this, + efi_handle_t child_handle) +{ + EFI_ENTRY("%p, %p", this, child_handle); + efi_status_t ret = EFI_SUCCESS; + struct efi_http_instance *http_instance; + struct efi_handler *phandler; + void *protocol_interface; + + if (num_instances == 0) + return EFI_EXIT(EFI_NOT_FOUND); + + if (!child_handle) + return EFI_EXIT(EFI_INVALID_PARAMETER); + + efi_search_protocol(child_handle, &efi_http_guid, &phandler); + + if (phandler) + protocol_interface = phandler->protocol_interface; + + ret = efi_delete_handle(child_handle); + if (ret != EFI_SUCCESS) + return EFI_EXIT(ret); + + http_instance = (struct efi_http_instance *)protocol_interface; + efi_free_pool(http_instance->http_load_addr); + http_instance->http_load_addr = NULL; + + free(protocol_interface); + + num_instances--; + + return EFI_EXIT(EFI_SUCCESS); +} + +/** + * efi_http_register() - register the http protocol + * + */ +efi_status_t efi_http_register(const efi_handle_t handle, + struct efi_service_binding_protocol *http_service_binding) +{ + efi_status_t r = EFI_SUCCESS; + + r = efi_add_protocol(handle, &efi_http_service_binding_guid, + http_service_binding); + if (r != EFI_SUCCESS) + goto failure_to_add_protocol; + + http_service_binding->create_child = efi_http_service_binding_create_child; + http_service_binding->destroy_child = efi_http_service_binding_destroy_child; + + return EFI_SUCCESS; +failure_to_add_protocol: + return r; +} + +enum efi_http_status_code efi_u32_to_httpstatus(u32 status) +{ + switch (status) { + case 100: return HTTP_STATUS_100_CONTINUE; + case 101: return HTTP_STATUS_101_SWITCHING_PROTOCOLS; + case 200: return HTTP_STATUS_200_OK; + case 201: return HTTP_STATUS_201_CREATED; + case 202: return HTTP_STATUS_202_ACCEPTED; + case 203: return HTTP_STATUS_203_NON_AUTHORITATIVE_INFORMATION; + case 204: return HTTP_STATUS_204_NO_CONTENT; + case 205: return HTTP_STATUS_205_RESET_CONTENT; + case 206: return HTTP_STATUS_206_PARTIAL_CONTENT; + case 300: return HTTP_STATUS_300_MULTIPLE_CHOICES; + case 301: return HTTP_STATUS_301_MOVED_PERMANENTLY; + case 302: return HTTP_STATUS_302_FOUND; + case 303: return HTTP_STATUS_303_SEE_OTHER; + case 304: return HTTP_STATUS_304_NOT_MODIFIED; + case 305: return HTTP_STATUS_305_USE_PROXY; + case 307: return HTTP_STATUS_307_TEMPORARY_REDIRECT; + case 400: return HTTP_STATUS_400_BAD_REQUEST; + case 401: return HTTP_STATUS_401_UNAUTHORIZED; + case 402: return HTTP_STATUS_402_PAYMENT_REQUIRED; + case 403: return HTTP_STATUS_403_FORBIDDEN; + case 404: return HTTP_STATUS_404_NOT_FOUND; + case 405: return HTTP_STATUS_405_METHOD_NOT_ALLOWED; + case 406: return HTTP_STATUS_406_NOT_ACCEPTABLE; + case 407: return HTTP_STATUS_407_PROXY_AUTHENTICATION_REQUIRED; + case 408: return HTTP_STATUS_408_REQUEST_TIME_OUT; + case 409: return HTTP_STATUS_409_CONFLICT; + case 410: return HTTP_STATUS_410_GONE; + case 411: return HTTP_STATUS_411_LENGTH_REQUIRED; + case 412: return HTTP_STATUS_412_PRECONDITION_FAILED; + case 413: return HTTP_STATUS_413_REQUEST_ENTITY_TOO_LARGE; + case 414: return HTTP_STATUS_414_REQUEST_URI_TOO_LARGE; + case 415: return HTTP_STATUS_415_UNSUPPORTED_MEDIA_TYPE; + case 416: return HTTP_STATUS_416_REQUESTED_RANGE_NOT_SATISFIED; + case 417: return HTTP_STATUS_417_EXPECTATION_FAILED; + case 500: return HTTP_STATUS_500_INTERNAL_SERVER_ERROR; + case 501: return HTTP_STATUS_501_NOT_IMPLEMENTED; + case 502: return HTTP_STATUS_502_BAD_GATEWAY; + case 503: return HTTP_STATUS_503_SERVICE_UNAVAILABLE; + case 504: return HTTP_STATUS_504_GATEWAY_TIME_OUT; + case 505: return HTTP_STATUS_505_HTTP_VERSION_NOT_SUPPORTED; + case 308: return HTTP_STATUS_308_PERMANENT_REDIRECT; + default: return HTTP_STATUS_UNSUPPORTED_STATUS; + } +} diff --git a/lib/efi_loader/efi_net.c b/lib/efi_loader/efi_net.c index 916c15999e2..67593ef50c0 100644 --- a/lib/efi_loader/efi_net.c +++ b/lib/efi_loader/efi_net.c @@ -66,6 +66,7 @@ static struct efi_event *wait_for_packet; * @pxe: PXE base code protocol interface * @pxe_mode: status of the PXE base code protocol * @ip4_config2: IP4 Config2 protocol interface + * @http_service_binding: Http service binding protocol interface */ struct efi_net_obj { struct efi_object header; @@ -76,6 +77,9 @@ struct efi_net_obj { #if IS_ENABLED(CONFIG_EFI_IP4_CONFIG2_PROTOCOL) struct efi_ip4_config2_protocol ip4_config2; #endif +#if IS_ENABLED(CONFIG_EFI_HTTP_PROTOCOL) + struct efi_service_binding_protocol http_service_binding; +#endif }; /* @@ -1009,6 +1013,19 @@ efi_status_t efi_net_register(void) goto failure_to_add_protocol; #endif +#ifdef CONFIG_EFI_HTTP_PROTOCOL + r = efi_http_register(&netobj->header, &netobj->http_service_binding); + if (r != EFI_SUCCESS) + goto failure_to_add_protocol; + /* + * No harm on doing the following. If the PXE handle is present, the client could + * find it and try to get its IP address from it. In here the PXE handle is present + * but the PXE protocol is not yet implmenented, so we add this in the meantime. + */ + efi_net_get_addr((struct efi_ipv4_address *)&netobj->pxe_mode.station_ip, + (struct efi_ipv4_address *)&netobj->pxe_mode.subnet_mask, NULL); +#endif + return EFI_SUCCESS; failure_to_add_protocol: printf("ERROR: Failure to add protocol\n"); @@ -1207,8 +1224,6 @@ static efi_status_t efi_net_set_buffer(void **buffer, size_t size) if (size < SZ_64K) size = SZ_64K; - efi_free_pool(*buffer); - *buffer = efi_alloc(size); if (!*buffer) ret = EFI_OUT_OF_RESOURCES; @@ -1305,6 +1320,7 @@ efi_status_t efi_net_do_request(u8 *url, enum efi_http_method method, void **buf wget_ret = wget_request((ulong)*buffer, url, &efi_wget_info); if ((ulong)efi_wget_info.hdr_cont_len > efi_wget_info.buffer_size) { // Try again with updated buffer size + efi_free_pool(*buffer); ret = efi_net_set_buffer(buffer, (size_t)efi_wget_info.hdr_cont_len); if (ret != EFI_SUCCESS) goto out; -- cgit v1.3.1 From 6df3af4f7cc587231a6019e677fee31d83eb3f14 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Wed, 4 Dec 2024 00:05:27 -0300 Subject: lib: uuid: display HTTP and IPV4 Config II protocols Add long texts for * EFI HTTP Protocol * EFI HTTP Service Binding Protocol * EFI IPv4 Configuration II Protocol to the uuid library. Signed-off-by: Adriano Cordova Reviewed-by: Ilias Apalodimas Signed-off-by: Heinrich Schuchardt --- lib/uuid.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'lib') diff --git a/lib/uuid.c b/lib/uuid.c index 538a1ba6aa8..97388f597a6 100644 --- a/lib/uuid.c +++ b/lib/uuid.c @@ -175,6 +175,20 @@ static const struct { "Firmware Management", EFI_FIRMWARE_MANAGEMENT_PROTOCOL_GUID }, +#if IS_ENABLED(CONFIG_EFI_HTTP_PROTOCOL) + { + "HTTP", + EFI_HTTP_PROTOCOL_GUID, + }, + { + "HTTP Service Binding", + EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID, + }, + { + "IPv4 Config2", + EFI_IP4_CONFIG2_PROTOCOL_GUID, + }, +#endif /* Configuration table GUIDs */ { "ACPI table", -- cgit v1.3.1 From 84d4ee5d055e0155555d5c7dab882ccd67b84af4 Mon Sep 17 00:00:00 2001 From: Adriano Cordova Date: Wed, 4 Dec 2024 00:05:28 -0300 Subject: efi_selftest: add test for HTTP protocol Add a test for the EFI_HTTP_PROTOCOL and EFI_SEVICE_BINDING_PROTOCOL. Signed-off-by: Adriano Cordova --- lib/efi_selftest/Makefile | 2 +- lib/efi_selftest/efi_selftest_http.c | 321 +++++++++++++++++++++++++++++++++++ 2 files changed, 322 insertions(+), 1 deletion(-) create mode 100644 lib/efi_selftest/efi_selftest_http.c (limited to 'lib') diff --git a/lib/efi_selftest/Makefile b/lib/efi_selftest/Makefile index 414701893f6..140c08effc5 100644 --- a/lib/efi_selftest/Makefile +++ b/lib/efi_selftest/Makefile @@ -52,7 +52,7 @@ efi_selftest_watchdog.o obj-$(CONFIG_EFI_ECPT) += efi_selftest_ecpt.o obj-$(CONFIG_NETDEVICES) += efi_selftest_snp.o - +obj-$(CONFIG_EFI_HTTP_PROTOCOL) += efi_selftest_http.o obj-$(CONFIG_EFI_DEVICE_PATH_TO_TEXT) += efi_selftest_devicepath.o obj-$(CONFIG_EFI_UNICODE_COLLATION_PROTOCOL2) += \ efi_selftest_unicode_collation.o diff --git a/lib/efi_selftest/efi_selftest_http.c b/lib/efi_selftest/efi_selftest_http.c new file mode 100644 index 00000000000..b63c401f055 --- /dev/null +++ b/lib/efi_selftest/efi_selftest_http.c @@ -0,0 +1,321 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * efi_selftest_http + * + * This unit test covers the IPv4 Config2 Protocol, Http Service Binding Protocol, + * and Http Protocol. + * + * An Http HEAD and an Http GET request are sent to the same destination. The test + * is successful if the HEAD request gets a response with a valid Content-Length header + * and the subsequent GET request receives the amount of bytes informed by the previous + * Content-Length header. + * + */ + +#include +#include +#include + +static struct efi_boot_services *boottime; + +static struct efi_http_protocol *http; +static struct efi_service_binding_protocol *http_service; +static struct efi_ip4_config2_protocol *ip4_config2; +static efi_handle_t http_protocol_handle; + +static const efi_guid_t efi_http_guid = EFI_HTTP_PROTOCOL_GUID; +static const efi_guid_t efi_http_service_binding_guid = EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID; +static const efi_guid_t efi_ip4_config2_guid = EFI_IP4_CONFIG2_PROTOCOL_GUID; +static int callback_done; + +/* + * Setup unit test. + * + * + * @handle: handle of the loaded image + * @systable: system table + * Return: EFI_ST_SUCCESS for success + */ +static int setup(const efi_handle_t handle, + const struct efi_system_table *systable) +{ + efi_status_t ret; + efi_handle_t *net_handle; + efi_uintn_t num_handles; + efi_handle_t *handles; + struct efi_http_config_data http_config; + struct efi_httpv4_access_point ipv4_node; + + boottime = systable->boottime; + + num_handles = 0; + boottime->locate_handle_buffer(BY_PROTOCOL, &efi_ip4_config2_guid, + NULL, &num_handles, &handles); + + if (!num_handles) { + efi_st_error("Failed to locate ipv4 config2 protocol\n"); + return EFI_ST_FAILURE; + } + + for (net_handle = handles; num_handles--; net_handle++) { + ret = boottime->open_protocol(*net_handle, &efi_ip4_config2_guid, + (void **)&ip4_config2, 0, 0, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS || !ip4_config2) + continue; + ret = boottime->open_protocol(*net_handle, + &efi_http_service_binding_guid, + (void **)&http_service, 0, 0, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS || !http_service) + continue; + break; // Get first handle that supports both protocols + } + + if (!ip4_config2 || !http_service) { + efi_st_error("Failed to open ipv4 config2 or http service binding protocol\n"); + return EFI_ST_FAILURE; + } + + http_protocol_handle = NULL; + ret = http_service->create_child(http_service, &http_protocol_handle); + if (ret != EFI_SUCCESS || !http_protocol_handle) { + efi_st_error("Failed to create an http service instance\n"); + return EFI_ST_FAILURE; + } + + ret = boottime->open_protocol(http_protocol_handle, &efi_http_guid, + (void **)&http, 0, 0, EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS || !http) { + efi_st_error("Failed to open http protocol\n"); + return EFI_ST_FAILURE; + } + efi_st_printf("HTTP Service Binding: child created successfully\n"); + + http_config.http_version = HTTPVERSION11; + http_config.is_ipv6 = false; + http_config.access_point.ipv4_node = &ipv4_node; + ipv4_node.use_default_address = true; + + ret = http->configure(http, &http_config); + if (ret != EFI_SUCCESS) { + efi_st_error("Failed to configure http instance\n"); + return EFI_ST_FAILURE; + } + + return EFI_ST_SUCCESS; +} + +void EFIAPI efi_test_http_callback(struct efi_event *event, void *context) +{ + callback_done = 1; +} + +/* + * Execute unit test. + * + * + * Return: EFI_ST_SUCCESS for success + */ +static int execute(void) +{ + efi_status_t ret; + struct efi_http_request_data request_data; + struct efi_http_message request_message; + struct efi_http_token request_token; + struct efi_http_response_data response_data; + struct efi_http_message response_message; + struct efi_http_token response_token; + enum efi_http_status_code status_code; + void *response_buffer; + efi_uintn_t len, sum; + char *url = "http://example.com/"; + u16 url_16[64]; + u16 *tmp; + + /* Setup may have failed */ + if (!ip4_config2 || !http) { + efi_st_error("Cannot proceed with test after setup failure\n"); + return EFI_ST_FAILURE; + } + + tmp = url_16; + utf8_utf16_strcpy(&tmp, url); + request_data.url = url_16; + request_data.method = HTTP_METHOD_GET; + + request_message.data.request = &request_data; + request_message.header_count = 3; + request_message.body_length = 0; + request_message.body = NULL; + + /* request token */ + request_token.event = NULL; + request_token.status = EFI_NOT_READY; + request_token.message = &request_message; + callback_done = 0; + ret = boottime->create_event(EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + efi_test_http_callback, + NULL, + &request_token.event); + + if (ret != EFI_SUCCESS) { + efi_st_error("Failed to create request event\n"); + return EFI_ST_FAILURE; + } + + ret = http->request(http, &request_token); + + if (ret != EFI_SUCCESS) { + boottime->close_event(request_token.event); + efi_st_printf("Failed to proceed with the http request\n"); + return EFI_ST_SUCCESS; + } + + while (!callback_done) + http->poll(http); + + response_data.status_code = HTTP_STATUS_UNSUPPORTED_STATUS; + response_message.data.response = &response_data; + response_message.header_count = 0; + response_message.headers = NULL; + response_message.body_length = 0; + response_message.body = NULL; + response_token.event = NULL; + + ret = boottime->create_event(EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + efi_test_http_callback, + NULL, + &response_token.event); + + if (ret != EFI_SUCCESS) { + boottime->close_event(request_token.event); + efi_st_error("Failed to create response event\n"); + return EFI_ST_FAILURE; + } + + response_token.status = EFI_SUCCESS; + response_token.message = &response_message; + + callback_done = 0; + ret = http->response(http, &response_token); + + if (ret != EFI_SUCCESS) { + efi_st_error("Failed http first response\n"); + goto fail; + } + + while (!callback_done) + http->poll(http); + + if (response_message.data.response->status_code != HTTP_STATUS_200_OK) { + status_code = response_message.data.response->status_code; + if (status_code == HTTP_STATUS_404_NOT_FOUND) { + efi_st_error("File not found\n"); + } else { + efi_st_error("Bad http status %d\n", + response_message.data.response->status_code); + } + goto fail_free_hdr; + } + + ret = boottime->allocate_pool(EFI_LOADER_CODE, response_message.body_length, + &response_buffer); + if (ret != EFI_SUCCESS) { + efi_st_error("Failed allocating response buffer\n"); + goto fail_free_hdr; + } + + len = response_message.body_length; + sum = 0; + while (len) { + response_message.data.response = NULL; + response_message.header_count = 0; + response_message.headers = NULL; + response_message.body_length = len; + response_message.body = response_buffer + sum; + + response_token.message = &response_message; + response_token.status = EFI_NOT_READY; + + callback_done = 0; + ret = http->response(http, &response_token); + if (ret != EFI_SUCCESS) { + efi_st_error("Failed http second response\n"); + goto fail_free_buf; + } + + while (!callback_done) + http->poll(http); + + if (!response_message.body_length) + break; + + len -= response_message.body_length; + sum += response_message.body_length; + } + + if (len) + goto fail_free_buf; + + boottime->free_pool(response_buffer); + if (response_message.headers) + boottime->free_pool(response_message.headers); + boottime->close_event(request_token.event); + boottime->close_event(response_token.event); + efi_st_printf("Efi Http request executed successfully\n"); + return EFI_ST_SUCCESS; + +fail_free_buf: + boottime->free_pool(response_buffer); +fail_free_hdr: + if (response_message.headers) + boottime->free_pool(response_message.headers); +fail: + boottime->close_event(request_token.event); + boottime->close_event(response_token.event); + return EFI_ST_FAILURE; +} + +/* + * Tear down unit test. + * + * Return: EFI_ST_SUCCESS for success + */ +static int teardown(void) +{ + efi_status_t ret; + int exit_status = EFI_ST_SUCCESS; + + if (!http_service || !http_protocol_handle) { + efi_st_error("No handles to destroy http instance"); + exit_status = EFI_ST_FAILURE; + } else { + ret = http_service->destroy_child(http_service, http_protocol_handle); + if (ret != EFI_SUCCESS) { + efi_st_error("Failed to destroy http instance"); + exit_status = EFI_ST_FAILURE; + } + efi_st_printf("HTTP Service Binding: child destroyed successfully\n"); + } + + return exit_status; +} + +EFI_UNIT_TEST(http) = { + .name = "http protocol", + .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT, + .setup = setup, + .execute = execute, + .teardown = teardown, +#ifdef CONFIG_SANDBOX + /* + * Running this test on the sandbox requires setting environment + * variable ethact to a network interface connected to a DHCP server and + * ethrotate to 'no'. + */ + .on_request = true, +#endif +}; -- cgit v1.3.1 From 6caec797d5c453ccba5eeb0bc9194c5939094cb4 Mon Sep 17 00:00:00 2001 From: Adriano Cordova Date: Wed, 4 Dec 2024 00:05:29 -0300 Subject: efi_selftest: add test for IPv4 Config2 protocol Add a test for the EFI_IP4_CONFIG2_PROTOCOL. The test sets the ip policy to static, adds an ip address, and then reads the current ip address and checks for it to be the same as the one that was set. Signed-off-by: Adriano Cordova --- lib/efi_selftest/Makefile | 2 + lib/efi_selftest/efi_selftest_ipconfig.c | 176 +++++++++++++++++++++++++++++++ 2 files changed, 178 insertions(+) create mode 100644 lib/efi_selftest/efi_selftest_ipconfig.c (limited to 'lib') diff --git a/lib/efi_selftest/Makefile b/lib/efi_selftest/Makefile index 140c08effc5..17fbfad116f 100644 --- a/lib/efi_selftest/Makefile +++ b/lib/efi_selftest/Makefile @@ -53,6 +53,8 @@ efi_selftest_watchdog.o obj-$(CONFIG_EFI_ECPT) += efi_selftest_ecpt.o obj-$(CONFIG_NETDEVICES) += efi_selftest_snp.o obj-$(CONFIG_EFI_HTTP_PROTOCOL) += efi_selftest_http.o +obj-$(CONFIG_EFI_HTTP_PROTOCOL) += efi_selftest_ipconfig.o + obj-$(CONFIG_EFI_DEVICE_PATH_TO_TEXT) += efi_selftest_devicepath.o obj-$(CONFIG_EFI_UNICODE_COLLATION_PROTOCOL2) += \ efi_selftest_unicode_collation.o diff --git a/lib/efi_selftest/efi_selftest_ipconfig.c b/lib/efi_selftest/efi_selftest_ipconfig.c new file mode 100644 index 00000000000..8d594f5e193 --- /dev/null +++ b/lib/efi_selftest/efi_selftest_ipconfig.c @@ -0,0 +1,176 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * efi_selftest_ipconfig + * + * This unit test covers the IPv4 Config2 Protocol. + * + */ + +#include +#include +#include + +static struct efi_boot_services *boottime; + +static struct efi_ip4_config2_protocol *ip4_config2; +static const efi_guid_t efi_ip4_config2_guid = EFI_IP4_CONFIG2_PROTOCOL_GUID; + +/* + * Setup unit test. + * + * Open IPv4 Config2 protocol + * + * @handle: handle of the loaded image + * @systable: system table + * Return: EFI_ST_SUCCESS for success + */ +static int setup(const efi_handle_t handle, + const struct efi_system_table *systable) +{ + efi_status_t ret; + efi_handle_t *net_handle; + efi_uintn_t num_handles; + efi_handle_t *handles; + + boottime = systable->boottime; + + num_handles = 0; + boottime->locate_handle_buffer(BY_PROTOCOL, &efi_ip4_config2_guid, + NULL, &num_handles, &handles); + + if (!num_handles) { + efi_st_error("Failed to locate ipv4 config2 protocol\n"); + return EFI_ST_FAILURE; + } + + for (net_handle = handles; num_handles--; net_handle++) { + ret = boottime->open_protocol(*net_handle, &efi_ip4_config2_guid, + (void **)&ip4_config2, 0, 0, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS || !ip4_config2) + continue; + break; // Get first handle that supports ipv4 + } + + if (!ip4_config2) { + efi_st_error("Failed to open ipv4 config2 protocol\n"); + return EFI_ST_FAILURE; + } + + return EFI_ST_SUCCESS; +} + +/* + * Execute unit test. + * + * + * Return: EFI_ST_SUCCESS for success + */ +static int execute(void) +{ + efi_status_t ret; + enum efi_ip4_config2_policy policy; + efi_uintn_t data_size; + struct efi_ip4_config2_manual_address manual_address; + struct efi_ip4_config2_manual_address orig_address; + u8 netmask[] = {255, 255, 255, 0}; + u8 ip[] = {10, 0, 0, 1}; + + /* Setup may have failed */ + if (!ip4_config2) { + efi_st_error("Setup failure, cannot proceed with test\n"); + return EFI_ST_FAILURE; + } + + /* Set policy to static */ + policy = EFI_IP4_CONFIG2_POLICY_STATIC; + ret = ip4_config2->set_data(ip4_config2, EFI_IP4_CONFIG2_DATA_TYPE_POLICY, + sizeof(policy), (void *)&policy); + if (ret != EFI_SUCCESS) { + efi_st_error("Failed to set policy\n"); + return EFI_ST_FAILURE; + } + + /* Save original ip address and netmask */ + data_size = sizeof(manual_address); + ret = ip4_config2->get_data(ip4_config2, EFI_IP4_CONFIG2_DATA_TYPE_MANUAL_ADDRESS, + &data_size, &orig_address); + if (ret != EFI_SUCCESS) { + efi_st_error("Failed to save original ip address and netmask\n"); + return EFI_ST_FAILURE; + } + + /* Set static ip and netmask */ + memcpy(&manual_address.address, ip, + sizeof(struct efi_ipv4_address)); + memcpy(&manual_address.subnet_mask, netmask, + sizeof(struct efi_ipv4_address)); + ret = ip4_config2->set_data(ip4_config2, EFI_IP4_CONFIG2_DATA_TYPE_MANUAL_ADDRESS, + sizeof(manual_address), &manual_address); + if (ret != EFI_SUCCESS) { + efi_st_error("Failed to get ip address and netmask\n"); + return EFI_ST_FAILURE; + } + + /* Try to set interface info, this should fail */ + ret = ip4_config2->set_data(ip4_config2, EFI_IP4_CONFIG2_DATA_TYPE_INTERFACEINFO, 0, NULL); + if (ret == EFI_SUCCESS) { + efi_st_error("Interface info is read-only\n"); + return EFI_ST_FAILURE; + } + + /* Get ip address and netmask and check that they match with the previously set ones */ + data_size = sizeof(manual_address); + ret = ip4_config2->get_data(ip4_config2, EFI_IP4_CONFIG2_DATA_TYPE_MANUAL_ADDRESS, + &data_size, &manual_address); + if (ret != EFI_SUCCESS) { + efi_st_error("Failed to get ip address and netmask\n"); + return EFI_ST_FAILURE; + } + if (memcmp(ip, &manual_address.address, + sizeof(struct efi_ipv4_address)) || + memcmp(netmask, &manual_address.subnet_mask, + sizeof(struct efi_ipv4_address))) { + efi_st_error("Ip address mismatch\n"); + return EFI_ST_FAILURE; + } + + /* Restore original ip address and netmask */ + ret = ip4_config2->set_data(ip4_config2, EFI_IP4_CONFIG2_DATA_TYPE_MANUAL_ADDRESS, + sizeof(orig_address), &orig_address); + if (ret != EFI_SUCCESS) { + efi_st_error("Failed to restore original ip address and netmask\n"); + return EFI_ST_FAILURE; + } + + efi_st_printf("Efi ipconfig test execute succeeded\n"); + return EFI_ST_SUCCESS; +} + +/* + * Tear down unit test. + * + * Return: EFI_ST_SUCCESS for success + */ +static int teardown(void) +{ + int exit_status = EFI_ST_SUCCESS; + + return exit_status; +} + +EFI_UNIT_TEST(ipconfig) = { + .name = "IPv4 config2 protocol", + .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT, + .setup = setup, + .execute = execute, + .teardown = teardown, +#ifdef CONFIG_SANDBOX + /* + * Running this test on the sandbox requires setting environment + * variable ethact to a network interface connected to a DHCP server and + * ethrotate to 'no'. + */ + .on_request = true, +#endif +}; -- cgit v1.3.1 From 4b0cf71639ac7c24d2e89242f4cbfe2af8b6c6fb Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Fri, 15 Nov 2024 10:53:58 -0600 Subject: efi_loader: Fix Kconfig logic around OF_LIBFDT Given that OF_LIBFDT is library functionality, the feature of EFI_LOADER needs to select OF_LIBFDT rather than depend on it being already enabled. Acked-by: Heinrich Schuchardt Signed-off-by: Tom Rini --- lib/efi_loader/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index 5c73457d9b9..c46ffe3a9d8 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -2,7 +2,7 @@ menu "UEFI Support" config EFI_LOADER bool "Support running UEFI applications" - depends on OF_LIBFDT && ( \ + depends on ( \ ARM && (SYS_CPU = arm1136 || \ SYS_CPU = arm1176 || \ SYS_CPU = armv7 || \ @@ -21,6 +21,7 @@ config EFI_LOADER select EVENT_DYNAMIC select LIB_UUID select LMB + select OF_LIBFDT imply PARTITION_UUIDS select REGEX imply FAT -- cgit v1.3.1 From 86f58ea539e35b47235dff0dd77ec20fe8894469 Mon Sep 17 00:00:00 2001 From: Christoph Niedermaier Date: Sat, 7 Dec 2024 00:04:19 +0100 Subject: lib: hashtable: Prevent recursive calling of callback functions In case there are two variables which each implement env callback that performs env_set() on the other variable, the callbacks will call each other recursively until the stack runs out. Prevent such a recursion from happening. Example which triggers this behavior: static int on_foo(...) { env_set("bar", 0); ... } static int on_bar(...) { env_set("foo", 0); ... } U_BOOT_ENV_CALLBACK(foo, on_foo); U_BOOT_ENV_CALLBACK(bar, on_bar); Signed-off-by: Christoph Niedermaier Suggested-by: Marek Vasut --- lib/hashtable.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/hashtable.c b/lib/hashtable.c index e8a59e2dcac..75c263b5053 100644 --- a/lib/hashtable.c +++ b/lib/hashtable.c @@ -221,11 +221,32 @@ static int do_callback(const struct env_entry *e, const char *name, const char *value, enum env_op op, int flags) { + int ret = 0; + #ifndef CONFIG_XPL_BUILD - if (e->callback) - return e->callback(name, value, op, flags); + static bool in_callback; + + if (!e->callback || in_callback) + return 0; + + /* + * In case there are two variables which each implement env callback + * that performs env_set() on the other variable, the callbacks will + * call each other recursively until the stack runs out. Prevent such + * a recursion from happening. + * + * Example which triggers this behavior: + * static int on_foo(...) { env_set("bar", 0); ... } + * static int on_bar(...) { env_set("foo", 0); ... } + * U_BOOT_ENV_CALLBACK(foo, on_foo); + * U_BOOT_ENV_CALLBACK(bar, on_bar); + */ + in_callback = true; + ret = e->callback(name, value, op, flags); + in_callback = false; #endif - return 0; + + return ret; } /* -- cgit v1.3.1 From 214dc4a160ec8712ed8a0fad0c409753264c79d6 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 7 Dec 2024 10:24:08 -0700 Subject: spl: lib: Allow for decompression in any SPL build Add Kconfig symbols and update the Makefile rules so that decompression can be used in TPL and VPL Signed-off-by: Simon Glass --- lib/Kconfig | 35 +++++++++++++++++++++++++++++++++++ lib/Makefile | 12 ++++++------ 2 files changed, 41 insertions(+), 6 deletions(-) (limited to 'lib') diff --git a/lib/Kconfig b/lib/Kconfig index 56ffdfa1839..3fa580ab1eb 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -832,12 +832,36 @@ config SPL_LZ4 fast compression and decompression speed. It belongs to the LZ77 family of byte-oriented compression schemes. +config TPL_LZ4 + bool "Enable LZ4 decompression support in TPL" + depends on TPL + help + This enables support for the LZ4 decompression algorithm in TPL. LZ4 + is a lossless data compression algorithm that is focused on + fast compression and decompression speed. It belongs to the LZ77 + family of byte-oriented compression schemes. + +config VPL_LZ4 + bool "Enable LZ4 decompression support in VPL" + depends on VPL + help + This enables support for the LZ4 decompression algorithm in VPL. LZ4 + is a lossless data compression algorithm that is focused on + fast compression and decompression speed. It belongs to the LZ77 + family of byte-oriented compression schemes. + config SPL_LZMA bool "Enable LZMA decompression support for SPL build" depends on SPL help This enables support for LZMA compression algorithm for SPL boot. +config TPL_LZMA + bool "Enable LZMA decompression support for TPL build" + depends on TPL + help + This enables support for LZMA compression algorithm for TPL boot. + config VPL_LZMA bool "Enable LZMA decompression support for VPL build" default y if LZMA @@ -856,11 +880,22 @@ config SPL_GZIP help This enables support for the GZIP compression algorithm for SPL boot. +config TPL_GZIP + bool "Enable gzip decompression support for SPL build" + select TPL_ZLIB + help + This enables support for the GZIP compression algorithm for TPL + config SPL_ZLIB bool help This enables compression lib for SPL boot. +config TPL_ZLIB + bool + help + This enables compression lib for TPL + config SPL_ZSTD bool "Enable Zstandard decompression support in SPL" depends on SPL diff --git a/lib/Makefile b/lib/Makefile index dbcfa87ebd6..31cfbb67aa0 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -83,12 +83,12 @@ obj-$(CONFIG_$(XPL_)SHA512_LEGACY) += sha512.o obj-$(CONFIG_CRYPT_PW) += crypt/ obj-$(CONFIG_$(XPL_)ASN1_DECODER_LEGACY) += asn1_decoder.o -obj-$(CONFIG_$(XPL_)ZLIB) += zlib/ -obj-$(CONFIG_$(XPL_)ZSTD) += zstd/ -obj-$(CONFIG_$(XPL_)GZIP) += gunzip.o -obj-$(CONFIG_$(XPL_)LZO) += lzo/ -obj-$(CONFIG_$(XPL_)LZMA) += lzma/ -obj-$(CONFIG_$(XPL_)LZ4) += lz4_wrapper.o +obj-$(CONFIG_$(PHASE_)ZLIB) += zlib/ +obj-$(CONFIG_$(PHASE_)ZSTD) += zstd/ +obj-$(CONFIG_$(PHASE_)GZIP) += gunzip.o +obj-$(CONFIG_$(PHASE_)LZO) += lzo/ +obj-$(CONFIG_$(PHASE_)LZMA) += lzma/ +obj-$(CONFIG_$(PHASE_)LZ4) += lz4_wrapper.o obj-$(CONFIG_$(XPL_)LIB_RATIONAL) += rational.o -- cgit v1.3.1 From 79520fea6d88060a6293436924ca2b44ade43180 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 7 Dec 2024 10:24:10 -0700 Subject: lib: Allow crc8 in TPL and VPL Provide options to enable the CRC8 feature in TPL and VPL builds. Signed-off-by: Simon Glass --- lib/Kconfig | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'lib') diff --git a/lib/Kconfig b/lib/Kconfig index 3fa580ab1eb..c8ac99df78e 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -719,6 +719,24 @@ config SPL_CRC8 checksum with feedback to produce an 8-bit result. The code is small and it does not require a lookup table (unlike CRC32). +config TPL_CRC8 + bool "Support CRC8 in TPL" + depends on TPL + help + Enables CRC8 support in TPL. This is not normally required. CRC8 is + a simple and fast checksumming algorithm which does a bytewise + checksum with feedback to produce an 8-bit result. The code is small + and it does not require a lookup table (unlike CRC32). + +config VPL_CRC8 + bool "Support CRC8 in VPL" + depends on VPL + help + Enables CRC8 support in VPL. This is not normally required. CRC8 is + a simple and fast checksumming algorithm which does a bytewise + checksum with feedback to produce an 8-bit result. The code is small + and it does not require a lookup table (unlike CRC32). + config SPL_CRC16 bool "Support CRC16 in SPL" depends on SPL -- cgit v1.3.1 From f0315babfb43c6d1f5d4ff0ea7554ec2c27bf7b1 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 7 Dec 2024 10:24:12 -0700 Subject: hash: Plumb crc8 into the hash functions Add an entry for crc8, with watchdog handling. Signed-off-by: Simon Glass --- common/hash.c | 8 ++++++++ include/u-boot/crc.h | 3 +++ lib/crc8.c | 6 ++++++ 3 files changed, 17 insertions(+) (limited to 'lib') diff --git a/common/hash.c b/common/hash.c index db6925d6782..5d389420eff 100644 --- a/common/hash.c +++ b/common/hash.c @@ -304,6 +304,14 @@ static struct hash_algo hash_algo[] = { .hash_update = hash_update_crc16_ccitt, .hash_finish = hash_finish_crc16_ccitt, }, +#if CONFIG_IS_ENABLED(CRC8) + { + .name = "crc8", + .digest_size = 1, + .chunk_size = CHUNKSZ_CRC32, + .hash_func_ws = crc8_wd_buf, + }, +#endif #if CONFIG_IS_ENABLED(CRC32) { .name = "crc32", diff --git a/include/u-boot/crc.h b/include/u-boot/crc.h index 5174bd7ac41..b2badaf6a97 100644 --- a/include/u-boot/crc.h +++ b/include/u-boot/crc.h @@ -25,6 +25,9 @@ */ unsigned int crc8(unsigned int crc_start, const unsigned char *vptr, int len); +void crc8_wd_buf(const unsigned char *input, unsigned int len, + unsigned char output[1], unsigned int chunk_sz); + /* lib/crc16.c - 16 bit CRC with polynomial x^16 + x^15 + x^2 + 1 */ uint16_t crc16(uint16_t crc, const unsigned char *buffer, size_t len); diff --git a/lib/crc8.c b/lib/crc8.c index 20d46d16147..811e19917b4 100644 --- a/lib/crc8.c +++ b/lib/crc8.c @@ -32,3 +32,9 @@ unsigned int crc8(unsigned int crc, const unsigned char *vptr, int len) return crc; } + +void crc8_wd_buf(const unsigned char *input, unsigned int len, + unsigned char output[1], unsigned int chunk_sz) +{ + *output = crc8(0, input, len); +} -- cgit v1.3.1 From a33185173dce550d6ecb96b7fa625bb5e2183d66 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Thu, 12 Dec 2024 21:07:26 -0600 Subject: Revert "Merge patch series "vbe: Series part E"" This reverts commit 1fdf53ace13f745fe8ad4d2d4e79eed98088d555, reversing changes made to e5aef1bbf11412eebd4c242b46adff5301353c30. I had missed that this caused too much size growth on rcar3_salvator-x. Signed-off-by: Tom Rini --- boot/Kconfig | 71 +------------------------------------------ boot/bootdev-uclass.c | 10 ++---- boot/image-fit.c | 29 +++++++----------- common/hash.c | 8 ----- common/malloc_simple.c | 3 +- common/spl/Kconfig.vpl | 17 ----------- common/spl/spl.c | 15 ++++----- common/spl/spl_atf.c | 36 +++++++++++----------- common/spl/spl_fit.c | 12 ++------ common/spl/spl_legacy.c | 8 ++--- common/spl/spl_mmc.c | 6 ++-- configs/sandbox_vpl_defconfig | 2 -- include/image.h | 16 +--------- include/spl.h | 28 ++++++++--------- include/u-boot/crc.h | 3 -- lib/Kconfig | 53 -------------------------------- lib/Makefile | 12 ++++---- lib/crc8.c | 6 ---- 18 files changed, 68 insertions(+), 267 deletions(-) (limited to 'lib') diff --git a/boot/Kconfig b/boot/Kconfig index 20935a269c6..99dcedcc840 100644 --- a/boot/Kconfig +++ b/boot/Kconfig @@ -163,18 +163,6 @@ config SPL_FIT select SPL_HASH select SPL_OF_LIBFDT -config VPL_FIT - bool "Support Flattened Image Tree within VPL" - depends on VPL - select VPL_HASH - select VPL_OF_LIBFDT - -config TPL_FIT - bool "Support Flattened Image Tree within TPL" - depends on TPL - select TPL_HASH - select TPL_OF_LIBFDT - config SPL_FIT_PRINT bool "Support FIT printing within SPL" depends on SPL_FIT @@ -280,28 +268,6 @@ config SPL_LOAD_FIT_FULL particular it can handle selecting from multiple device tree and passing the correct one to U-Boot. -config TPL_LOAD_FIT - bool "Enable TPL loading U-Boot as a FIT (basic fitImage features)" - depends on TPL - select TPL_FIT - help - Normally with the SPL framework a legacy image is generated as part - of the build. This contains U-Boot along with information as to - where it should be loaded. This option instead enables generation - of a FIT (Flat Image Tree) which provides more flexibility. In - particular it can handle selecting from multiple device tree - and passing the correct one to U-Boot. - - This path has the following limitations: - - 1. "loadables" images, other than FDTs, which do not have a "load" - property will not be loaded. This limitation also applies to FPGA - images with the correct "compatible" string. - 2. For FPGA images, the supported "compatible" list is in the - doc/uImage.FIT/source_file_format.txt. - 3. FDTs are only loaded for images with an "os" property of "u-boot". - "linux" images are also supported with Falcon boot mode. - config SPL_FIT_IMAGE_POST_PROCESS bool "Enable post-processing of FIT artifacts after loading by the SPL" depends on SPL_LOAD_FIT @@ -326,22 +292,6 @@ config VPL_FIT select VPL_HASH select VPL_OF_LIBFDT -config VPL_LOAD_FIT - bool "Enable VPL loading U-Boot as a FIT (basic fitImage features)" - select VPL_FIT - default y - -config VPL_LOAD_FIT_FULL - bool "Enable SPL loading U-Boot as a FIT (full fitImage features)" - select VPL_FIT - help - Normally with the SPL framework a legacy image is generated as part - of the build. This contains U-Boot along with information as to - where it should be loaded. This option instead enables generation - of a FIT (Flat Image Tree) which provides more flexibility. In - particular it can handle selecting from multiple device tree - and passing the correct one to U-Boot. - config VPL_FIT_PRINT bool "Support FIT printing within VPL" depends on VPL_FIT @@ -670,15 +620,6 @@ config VPL_BOOTMETH_VBE supports selection of various firmware components, selection of an OS to boot as well as updating these using fwupd. -config TPL_BOOTMETH_VBE - bool "Bootdev support for Verified Boot for Embedded (TPL)" - depends on TPL - default y - help - Enables support for VBE boot. This is a standard boot method which - supports selection of various firmware components, seleciton of an OS to - boot as well as updating these using fwupd. - if BOOTMETH_VBE config BOOTMETH_VBE_REQUEST @@ -704,8 +645,6 @@ config SPL_BOOTMETH_VBE_REQUEST config BOOTMETH_VBE_SIMPLE bool "Bootdev support for VBE 'simple' method" default y - imply SPL_CRC8 if SPL - imply VPL_CRC8 if VPL help Enables support for VBE 'simple' boot. This allows updating a single firmware image in boot media such as MMC. It does not support any sort @@ -759,15 +698,7 @@ config VPL_BOOTMETH_VBE_SIMPLE_FW This option enabled for VPL, since it is the phase where the SPL decision is made. -config TPL_BOOTMETH_VBE_SIMPLE_FW - bool "Bootdev support for VBE 'simple' method firmware phase (TPL)" - depends on VPL - default y - help - Enables support for the firmware parts of VBE 'simple' boot, in TPL. - TPL loads a FIT containing the VPL binary and a suitable devicetree. - -endif # BOOTMETH_VBE_SIMPLE +endif # BOOTMETH_VBE config EXPO bool "Support for expos - groups of scenes displaying a UI" diff --git a/boot/bootdev-uclass.c b/boot/bootdev-uclass.c index 2e61c853142..64ec4fde493 100644 --- a/boot/bootdev-uclass.c +++ b/boot/bootdev-uclass.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -279,13 +278,8 @@ int bootdev_setup_for_sibling_blk(struct udevice *blk, const char *drv_name) int ret, len; len = bootdev_get_suffix_start(blk, ".blk"); - if (xpl_phase() < PHASE_BOARD_R) { - strlcpy(dev_name, blk->name, sizeof(dev_name) - 5); - strcat(dev_name, ".sib"); - } else { - snprintf(dev_name, sizeof(dev_name), "%.*s.%s", len, blk->name, - "bootdev"); - } + snprintf(dev_name, sizeof(dev_name), "%.*s.%s", len, blk->name, + "bootdev"); parent = dev_get_parent(blk); ret = device_find_child_by_name(parent, dev_name, &dev); diff --git a/boot/image-fit.c b/boot/image-fit.c index db7fb61bca9..7d56f0b5e6e 100644 --- a/boot/image-fit.c +++ b/boot/image-fit.c @@ -1729,13 +1729,13 @@ int fit_conf_find_compat(const void *fit, const void *fdt) images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH); if (confs_noffset < 0 || images_noffset < 0) { debug("Can't find configurations or images nodes.\n"); - return -EINVAL; + return -1; } fdt_compat = fdt_getprop(fdt, 0, "compatible", &fdt_compat_len); if (!fdt_compat) { debug("Fdt for comparison has no \"compatible\" property.\n"); - return -ENXIO; + return -1; } /* @@ -1812,7 +1812,7 @@ int fit_conf_find_compat(const void *fit, const void *fdt) } if (!best_match_offset) { debug("No match found.\n"); - return -ENOENT; + return -1; } return best_match_offset; @@ -2095,18 +2095,17 @@ int fit_image_load(struct bootm_headers *images, ulong addr, * fit_conf_get_node() will try to find default config node */ bootstage_mark(bootstage_id + BOOTSTAGE_SUB_NO_UNIT_NAME); - ret = -ENXIO; - if (IS_ENABLED(CONFIG_FIT_BEST_MATCH) && !fit_uname_config) - ret = fit_conf_find_compat(fit, gd_fdt_blob()); - if (ret < 0 && ret != -EINVAL) - ret = fit_conf_get_node(fit, fit_uname_config); - if (ret < 0) { + if (IS_ENABLED(CONFIG_FIT_BEST_MATCH) && !fit_uname_config) { + cfg_noffset = fit_conf_find_compat(fit, gd_fdt_blob()); + } else { + cfg_noffset = fit_conf_get_node(fit, fit_uname_config); + } + if (cfg_noffset < 0) { puts("Could not find configuration node\n"); bootstage_error(bootstage_id + BOOTSTAGE_SUB_NO_UNIT_NAME); return -ENOENT; } - cfg_noffset = ret; fit_base_uname_config = fdt_get_name(fit, cfg_noffset, NULL); printf(" Using '%s' configuration\n", fit_base_uname_config); @@ -2226,7 +2225,6 @@ int fit_image_load(struct bootm_headers *images, ulong addr, data = map_to_sysmem(buf); load = data; if (load_op == FIT_LOAD_IGNORED) { - log_debug("load_op: not loading\n"); /* Don't load */ } else if (fit_image_get_load(fit, noffset, &load)) { if (load_op == FIT_LOAD_REQUIRED) { @@ -2263,13 +2261,10 @@ int fit_image_load(struct bootm_headers *images, ulong addr, /* Kernel images get decompressed later in bootm_load_os(). */ if (!fit_image_get_comp(fit, noffset, &comp) && comp != IH_COMP_NONE && - load_op != FIT_LOAD_IGNORED && !(image_type == IH_TYPE_KERNEL || image_type == IH_TYPE_KERNEL_NOLOAD || image_type == IH_TYPE_RAMDISK)) { ulong max_decomp_len = len * 20; - - log_debug("decompressing image\n"); if (load == data) { loadbuf = malloc(max_decomp_len); load = map_to_sysmem(loadbuf); @@ -2284,7 +2279,6 @@ int fit_image_load(struct bootm_headers *images, ulong addr, } len = load_end - load; } else if (load != data) { - log_debug("copying\n"); loadbuf = map_sysmem(load, len); memcpy(loadbuf, buf, len); } @@ -2294,9 +2288,8 @@ int fit_image_load(struct bootm_headers *images, ulong addr, " please fix your .its file!\n"); /* verify that image data is a proper FDT blob */ - if (load_op != FIT_LOAD_IGNORED && image_type == IH_TYPE_FLATDT && - fdt_check_header(loadbuf)) { - puts("Subimage data is not a FDT\n"); + if (image_type == IH_TYPE_FLATDT && fdt_check_header(loadbuf)) { + puts("Subimage data is not a FDT"); return -ENOEXEC; } diff --git a/common/hash.c b/common/hash.c index 5d389420eff..db6925d6782 100644 --- a/common/hash.c +++ b/common/hash.c @@ -304,14 +304,6 @@ static struct hash_algo hash_algo[] = { .hash_update = hash_update_crc16_ccitt, .hash_finish = hash_finish_crc16_ccitt, }, -#if CONFIG_IS_ENABLED(CRC8) - { - .name = "crc8", - .digest_size = 1, - .chunk_size = CHUNKSZ_CRC32, - .hash_func_ws = crc8_wd_buf, - }, -#endif #if CONFIG_IS_ENABLED(CRC32) { .name = "crc32", diff --git a/common/malloc_simple.c b/common/malloc_simple.c index f0f90a095bd..5a8ec538f8f 100644 --- a/common/malloc_simple.c +++ b/common/malloc_simple.c @@ -26,8 +26,7 @@ static void *alloc_simple(size_t bytes, int align) log_debug("size=%lx, ptr=%lx, limit=%x: ", (ulong)bytes, new_ptr, gd->malloc_limit); if (new_ptr > gd->malloc_limit) { - log_err("alloc space exhausted ptr %lx limit %x\n", new_ptr, - gd->malloc_limit); + log_err("alloc space exhausted\n"); return NULL; } diff --git a/common/spl/Kconfig.vpl b/common/spl/Kconfig.vpl index eb57dfabea5..d06f36d4ee4 100644 --- a/common/spl/Kconfig.vpl +++ b/common/spl/Kconfig.vpl @@ -222,29 +222,12 @@ config VPL_SPI_FLASH_SUPPORT lines). This enables the drivers in drivers/mtd/spi as part of a VPL build. This normally requires VPL_SPI_SUPPORT. -config VPL_SYS_MALLOC_SIMPLE - bool "Only use malloc_simple functions in the VPL" - default y - help - Say Y here to only use the *_simple malloc functions from - malloc_simple.c, rather then using the versions from dlmalloc.c; - this will make the VPL binary smaller at the cost of more heap - usage as the *_simple malloc functions do not re-use free-ed mem. - config VPL_TEXT_BASE hex "VPL Text Base" default 0x0 help The address in memory that VPL will be running from. -config VPL_MAX_SIZE - hex "Maximum size (in bytes) for the VPL stage" - default 0x2e000 if ROCKCHIP_RK3399 - default 0x0 - help - The maximum size (in bytes) of the TPL stage. This size is determined - by the amount of internal SRAM memory. - config VPL_BINMAN_SYMBOLS bool "Declare binman symbols in VPL" depends on VPL_FRAMEWORK && BINMAN diff --git a/common/spl/spl.c b/common/spl/spl.c index ad31a2f8b6c..1ceb63daf31 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -631,13 +631,10 @@ static int boot_from_devices(struct spl_image_info *spl_image, "Unsupported Boot Device!\n"); } } - if (loader) { - ret = spl_load_image(spl_image, loader); - if (!ret) { - spl_image->boot_device = bootdev; - return 0; - } - printf("Error: %d\n", ret); + if (loader && + !spl_load_image(spl_image, loader)) { + spl_image->boot_device = bootdev; + return 0; } } } @@ -836,7 +833,7 @@ void board_init_r(gd_t *dummy1, ulong dummy2) */ void preloader_console_init(void) { -#if CONFIG_IS_ENABLED(SERIAL) +#ifdef CONFIG_SPL_SERIAL gd->baudrate = CONFIG_BAUDRATE; serial_init(); /* serial communications setup */ @@ -895,7 +892,7 @@ __weak void spl_relocate_stack_check(void) */ ulong spl_relocate_stack_gd(void) { -#if CONFIG_IS_ENABLED(STACK_R) +#ifdef CONFIG_SPL_STACK_R gd_t *new_gd; ulong ptr = CONFIG_SPL_STACK_R_ADDR; diff --git a/common/spl/spl_atf.c b/common/spl/spl_atf.c index 8bc5db77395..0397b86a33b 100644 --- a/common/spl/spl_atf.c +++ b/common/spl/spl_atf.c @@ -41,9 +41,9 @@ struct bl2_to_bl31_params_mem_v2 { struct entry_point_info bl31_ep_info; }; -struct bl31_params *bl2_plat_get_bl31_params_default(ulong bl32_entry, - ulong bl33_entry, - ulong fdt_addr) +struct bl31_params *bl2_plat_get_bl31_params_default(uintptr_t bl32_entry, + uintptr_t bl33_entry, + uintptr_t fdt_addr) { static struct bl2_to_bl31_params_mem bl31_params_mem; struct bl31_params *bl2_to_bl31_params; @@ -100,17 +100,17 @@ struct bl31_params *bl2_plat_get_bl31_params_default(ulong bl32_entry, return bl2_to_bl31_params; } -__weak struct bl31_params *bl2_plat_get_bl31_params(ulong bl32_entry, - ulong bl33_entry, - ulong fdt_addr) +__weak struct bl31_params *bl2_plat_get_bl31_params(uintptr_t bl32_entry, + uintptr_t bl33_entry, + uintptr_t fdt_addr) { return bl2_plat_get_bl31_params_default(bl32_entry, bl33_entry, fdt_addr); } -struct bl_params *bl2_plat_get_bl31_params_v2_default(ulong bl32_entry, - ulong bl33_entry, - ulong fdt_addr) +struct bl_params *bl2_plat_get_bl31_params_v2_default(uintptr_t bl32_entry, + uintptr_t bl33_entry, + uintptr_t fdt_addr) { static struct bl2_to_bl31_params_mem_v2 bl31_params_mem; struct bl_params *bl_params; @@ -173,9 +173,9 @@ struct bl_params *bl2_plat_get_bl31_params_v2_default(ulong bl32_entry, return bl_params; } -__weak struct bl_params *bl2_plat_get_bl31_params_v2(ulong bl32_entry, - ulong bl33_entry, - ulong fdt_addr) +__weak struct bl_params *bl2_plat_get_bl31_params_v2(uintptr_t bl32_entry, + uintptr_t bl33_entry, + uintptr_t fdt_addr) { return bl2_plat_get_bl31_params_v2_default(bl32_entry, bl33_entry, fdt_addr); @@ -188,8 +188,8 @@ static inline void raw_write_daif(unsigned int daif) typedef void __noreturn (*atf_entry_t)(struct bl31_params *params, void *plat_params); -static void __noreturn bl31_entry(ulong bl31_entry, ulong bl32_entry, - ulong bl33_entry, ulong fdt_addr) +static void __noreturn bl31_entry(uintptr_t bl31_entry, uintptr_t bl32_entry, + uintptr_t bl33_entry, uintptr_t fdt_addr) { atf_entry_t atf_entry = (atf_entry_t)bl31_entry; void *bl31_params; @@ -238,7 +238,7 @@ static int spl_fit_images_find(void *blob, int os) return -FDT_ERR_NOTFOUND; } -ulong spl_fit_images_get_entry(void *blob, int node) +uintptr_t spl_fit_images_get_entry(void *blob, int node) { ulong val; int ret; @@ -253,10 +253,10 @@ ulong spl_fit_images_get_entry(void *blob, int node) void __noreturn spl_invoke_atf(struct spl_image_info *spl_image) { - ulong bl32_entry = 0; - ulong bl33_entry = CONFIG_TEXT_BASE; + uintptr_t bl32_entry = 0; + uintptr_t bl33_entry = CONFIG_TEXT_BASE; void *blob = spl_image->fdt_addr; - ulong platform_param = (ulong)blob; + uintptr_t platform_param = (uintptr_t)blob; int node; /* diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c index ac8462577ff..3160f573bfb 100644 --- a/common/spl/spl_fit.c +++ b/common/spl/spl_fit.c @@ -190,7 +190,7 @@ static int get_aligned_image_size(struct spl_load_info *info, int data_size, /** * load_simple_fit(): load the image described in a certain FIT node * @info: points to information about the device to load data from - * @fit_offset: the offset of the FIT image on the device + * @sector: the start sector of the FIT image on the device * @ctx: points to the FIT context structure * @node: offset of the DT node describing the image to load (relative * to @fit) @@ -243,14 +243,11 @@ static int load_simple_fit(struct spl_load_info *info, ulong fit_offset, if (!fit_image_get_data_position(fit, node, &offset)) { external_data = true; } else if (!fit_image_get_data_offset(fit, node, &offset)) { - log_debug("read offset %x = offset from fit %lx\n", - offset, (ulong)offset + ctx->ext_data_offset); offset += ctx->ext_data_offset; external_data = true; } if (external_data) { - ulong read_offset; void *src_ptr; /* External data */ @@ -273,10 +270,6 @@ static int load_simple_fit(struct spl_load_info *info, ulong fit_offset, overhead = get_aligned_image_overhead(info, offset); size = get_aligned_image_size(info, length, offset); - read_offset = fit_offset + get_aligned_image_offset(info, - offset); - log_debug("reading from offset %x / %lx size %lx to %p: ", - offset, read_offset, size, src_ptr); if (info->read(info, fit_offset + @@ -343,7 +336,6 @@ static int load_simple_fit(struct spl_load_info *info, ulong fit_offset, else image_info->entry_point = FDT_ERROR; } - log_debug("- done loading\n"); upl_add_image(fit, node, load_addr, length); @@ -870,7 +862,7 @@ int spl_load_fit_image(struct spl_image_info *spl_image, { struct bootm_headers images; const char *fit_uname_config = NULL; - ulong fdt_hack; + uintptr_t fdt_hack; const char *uname; ulong fw_data = 0, dt_data = 0, img_data = 0; ulong fw_len = 0, dt_len = 0, img_len = 0; diff --git a/common/spl/spl_legacy.c b/common/spl/spl_legacy.c index b3efb3e630e..9252b3a3de0 100644 --- a/common/spl/spl_legacy.c +++ b/common/spl/spl_legacy.c @@ -16,11 +16,11 @@ #define LZMA_LEN (1 << 20) -static void spl_parse_legacy_validate(ulong start, ulong size) +static void spl_parse_legacy_validate(uintptr_t start, uintptr_t size) { - ulong spl_start = (ulong)_start; - ulong spl_end = (ulong)&_image_binary_end; - ulong end = start + size; + uintptr_t spl_start = (uintptr_t)_start; + uintptr_t spl_end = (uintptr_t)&_image_binary_end; + uintptr_t end = start + size; if ((start >= spl_start && start < spl_end) || (end > spl_start && end <= spl_end) || diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c index fe4230170a0..1f696593216 100644 --- a/common/spl/spl_mmc.c +++ b/common/spl/spl_mmc.c @@ -81,10 +81,8 @@ static int spl_mmc_find_device(struct mmc **mmcp, int mmc_dev) struct uclass *uc; log_debug("Selecting MMC dev %d; seqs:\n", mmc_dev); - if (_LOG_DEBUG) { - uclass_id_foreach_dev(UCLASS_MMC, dev, uc) - log_debug("%d: %s\n", dev_seq(dev), dev->name); - } + uclass_id_foreach_dev(UCLASS_MMC, dev, uc) + log_debug("%d: %s\n", dev_seq(dev), dev->name); ret = mmc_init_device(mmc_dev); #else ret = mmc_initialize(NULL); diff --git a/configs/sandbox_vpl_defconfig b/configs/sandbox_vpl_defconfig index 46329395ba5..84df2b85260 100644 --- a/configs/sandbox_vpl_defconfig +++ b/configs/sandbox_vpl_defconfig @@ -27,8 +27,6 @@ CONFIG_FIT=y CONFIG_FIT_VERBOSE=y CONFIG_FIT_BEST_MATCH=y CONFIG_SPL_LOAD_FIT=y -# CONFIG_TPL_BOOTMETH_VBE is not set -# CONFIG_TPL_BOOTMETH_VBE_SIMPLE_FW is not set CONFIG_UPL=y CONFIG_UPL_IN=y CONFIG_BOOTSTAGE=y diff --git a/include/image.h b/include/image.h index ab96510f62c..9be5acd8158 100644 --- a/include/image.h +++ b/include/image.h @@ -1171,18 +1171,6 @@ int fit_image_get_data_size_unciphered(const void *fit, int noffset, int fit_image_get_data_and_size(const void *fit, int noffset, const void **data, size_t *size); -/** - * fit_image_get_phase() - Get the phase from a FIT image - * - * @fit: FIT to read from - * @offset: offset node to read - * @phasep: Returns phase, if any - * Return: 0 if read OK and *phasep is value, -ENOENT if there was no phase - * property in the node, other -ve value on other error - */ -int fit_image_get_phase(const void *fit, int offset, - enum image_phase_t *phasep); - /** * fit_get_data_node() - Get verified image data for an image * @fit: Pointer to the FIT format image header @@ -1411,9 +1399,7 @@ int fit_check_format(const void *fit, ulong size); * copied into the configuration node in the FIT image. This is required to * match configurations with compressed FDTs. * - * Returns: offset to the configuration to use if one was found, -EINVAL if - * there a /configurations or /images node is missing, -ENOENT if no match was - * found, -ENXIO if the FDT node has no compatible string + * Returns: offset to the configuration to use if one was found, -1 otherwise */ int fit_conf_find_compat(const void *fit, const void *fdt); diff --git a/include/spl.h b/include/spl.h index 43b344dbc55..269e36bb441 100644 --- a/include/spl.h +++ b/include/spl.h @@ -268,8 +268,8 @@ enum spl_sandbox_flags { struct spl_image_info { const char *name; u8 os; - ulong load_addr; - ulong entry_point; + uintptr_t load_addr; + uintptr_t entry_point; #if CONFIG_IS_ENABLED(LOAD_FIT) || CONFIG_IS_ENABLED(LOAD_FIT_FULL) void *fdt_addr; #endif @@ -951,9 +951,9 @@ void __noreturn spl_invoke_atf(struct spl_image_info *spl_image); * * Return: bl31 params structure pointer */ -struct bl31_params *bl2_plat_get_bl31_params(ulong bl32_entry, - ulong bl33_entry, - ulong fdt_addr); +struct bl31_params *bl2_plat_get_bl31_params(uintptr_t bl32_entry, + uintptr_t bl33_entry, + uintptr_t fdt_addr); /** * bl2_plat_get_bl31_params_default() - prepare params for bl31. @@ -972,9 +972,9 @@ struct bl31_params *bl2_plat_get_bl31_params(ulong bl32_entry, * * Return: bl31 params structure pointer */ -struct bl31_params *bl2_plat_get_bl31_params_default(ulong bl32_entry, - ulong bl33_entry, - ulong fdt_addr); +struct bl31_params *bl2_plat_get_bl31_params_default(uintptr_t bl32_entry, + uintptr_t bl33_entry, + uintptr_t fdt_addr); /** * bl2_plat_get_bl31_params_v2() - return params for bl31 @@ -988,9 +988,9 @@ struct bl31_params *bl2_plat_get_bl31_params_default(ulong bl32_entry, * * Return: bl31 params structure pointer */ -struct bl_params *bl2_plat_get_bl31_params_v2(ulong bl32_entry, - ulong bl33_entry, - ulong fdt_addr); +struct bl_params *bl2_plat_get_bl31_params_v2(uintptr_t bl32_entry, + uintptr_t bl33_entry, + uintptr_t fdt_addr); /** * bl2_plat_get_bl31_params_v2_default() - prepare params for bl31. @@ -1007,9 +1007,9 @@ struct bl_params *bl2_plat_get_bl31_params_v2(ulong bl32_entry, * * Return: bl31 params structure pointer */ -struct bl_params *bl2_plat_get_bl31_params_v2_default(ulong bl32_entry, - ulong bl33_entry, - ulong fdt_addr); +struct bl_params *bl2_plat_get_bl31_params_v2_default(uintptr_t bl32_entry, + uintptr_t bl33_entry, + uintptr_t fdt_addr); /** * spl_optee_entry - entry function for optee * diff --git a/include/u-boot/crc.h b/include/u-boot/crc.h index b2badaf6a97..5174bd7ac41 100644 --- a/include/u-boot/crc.h +++ b/include/u-boot/crc.h @@ -25,9 +25,6 @@ */ unsigned int crc8(unsigned int crc_start, const unsigned char *vptr, int len); -void crc8_wd_buf(const unsigned char *input, unsigned int len, - unsigned char output[1], unsigned int chunk_sz); - /* lib/crc16.c - 16 bit CRC with polynomial x^16 + x^15 + x^2 + 1 */ uint16_t crc16(uint16_t crc, const unsigned char *buffer, size_t len); diff --git a/lib/Kconfig b/lib/Kconfig index 8f1a96d98c4..0b089814d14 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -728,24 +728,6 @@ config SPL_CRC8 checksum with feedback to produce an 8-bit result. The code is small and it does not require a lookup table (unlike CRC32). -config TPL_CRC8 - bool "Support CRC8 in TPL" - depends on TPL - help - Enables CRC8 support in TPL. This is not normally required. CRC8 is - a simple and fast checksumming algorithm which does a bytewise - checksum with feedback to produce an 8-bit result. The code is small - and it does not require a lookup table (unlike CRC32). - -config VPL_CRC8 - bool "Support CRC8 in VPL" - depends on VPL - help - Enables CRC8 support in VPL. This is not normally required. CRC8 is - a simple and fast checksumming algorithm which does a bytewise - checksum with feedback to produce an 8-bit result. The code is small - and it does not require a lookup table (unlike CRC32). - config SPL_CRC16 bool "Support CRC16 in SPL" depends on SPL @@ -859,36 +841,12 @@ config SPL_LZ4 fast compression and decompression speed. It belongs to the LZ77 family of byte-oriented compression schemes. -config TPL_LZ4 - bool "Enable LZ4 decompression support in TPL" - depends on TPL - help - This enables support for the LZ4 decompression algorithm in TPL. LZ4 - is a lossless data compression algorithm that is focused on - fast compression and decompression speed. It belongs to the LZ77 - family of byte-oriented compression schemes. - -config VPL_LZ4 - bool "Enable LZ4 decompression support in VPL" - depends on VPL - help - This enables support for the LZ4 decompression algorithm in VPL. LZ4 - is a lossless data compression algorithm that is focused on - fast compression and decompression speed. It belongs to the LZ77 - family of byte-oriented compression schemes. - config SPL_LZMA bool "Enable LZMA decompression support for SPL build" depends on SPL help This enables support for LZMA compression algorithm for SPL boot. -config TPL_LZMA - bool "Enable LZMA decompression support for TPL build" - depends on TPL - help - This enables support for LZMA compression algorithm for TPL boot. - config VPL_LZMA bool "Enable LZMA decompression support for VPL build" default y if LZMA @@ -907,22 +865,11 @@ config SPL_GZIP help This enables support for the GZIP compression algorithm for SPL boot. -config TPL_GZIP - bool "Enable gzip decompression support for SPL build" - select TPL_ZLIB - help - This enables support for the GZIP compression algorithm for TPL - config SPL_ZLIB bool help This enables compression lib for SPL boot. -config TPL_ZLIB - bool - help - This enables compression lib for TPL - config SPL_ZSTD bool "Enable Zstandard decompression support in SPL" depends on SPL diff --git a/lib/Makefile b/lib/Makefile index 5cb3278d2ef..d24ed629732 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -83,12 +83,12 @@ obj-$(CONFIG_$(XPL_)SHA512_LEGACY) += sha512.o obj-$(CONFIG_CRYPT_PW) += crypt/ obj-$(CONFIG_$(XPL_)ASN1_DECODER_LEGACY) += asn1_decoder.o -obj-$(CONFIG_$(PHASE_)ZLIB) += zlib/ -obj-$(CONFIG_$(PHASE_)ZSTD) += zstd/ -obj-$(CONFIG_$(PHASE_)GZIP) += gunzip.o -obj-$(CONFIG_$(PHASE_)LZO) += lzo/ -obj-$(CONFIG_$(PHASE_)LZMA) += lzma/ -obj-$(CONFIG_$(PHASE_)LZ4) += lz4_wrapper.o +obj-$(CONFIG_$(XPL_)ZLIB) += zlib/ +obj-$(CONFIG_$(XPL_)ZSTD) += zstd/ +obj-$(CONFIG_$(XPL_)GZIP) += gunzip.o +obj-$(CONFIG_$(XPL_)LZO) += lzo/ +obj-$(CONFIG_$(XPL_)LZMA) += lzma/ +obj-$(CONFIG_$(XPL_)LZ4) += lz4_wrapper.o obj-$(CONFIG_$(XPL_)LIB_RATIONAL) += rational.o diff --git a/lib/crc8.c b/lib/crc8.c index 811e19917b4..20d46d16147 100644 --- a/lib/crc8.c +++ b/lib/crc8.c @@ -32,9 +32,3 @@ unsigned int crc8(unsigned int crc, const unsigned char *vptr, int len) return crc; } - -void crc8_wd_buf(const unsigned char *input, unsigned int len, - unsigned char output[1], unsigned int chunk_sz) -{ - *output = crc8(0, input, len); -} -- cgit v1.3.1 From 3b3c7280b82b1f08807a070ac066cd02919dfde1 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Tue, 3 Dec 2024 21:42:57 +0800 Subject: smbios: address build warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit include display_options.h to address build warning: lib/smbios.c: In function ‘smbios_update_version’: lib/smbios.c:305:9: warning: implicit declaration of function ‘print_buffer’ [-Wimplicit-function-declaration] print_buffer((ulong)ptr, ptr, 1, old_len + 1, 0); ^~~~~~~~~~~~ Signed-off-by: Peng Fan Reviewed-by: Heinrich Schuchardt Reviewed-by: Ilias Apalodimas --- lib/smbios.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib') diff --git a/lib/smbios.c b/lib/smbios.c index a36d4b4e54a..defb6b42f45 100644 --- a/lib/smbios.c +++ b/lib/smbios.c @@ -7,6 +7,7 @@ #define LOG_CATEGORY LOGC_BOARD +#include #include #include #include -- cgit v1.3.1 From 447f18d00de80384df334acdbe5972762d3d1e1e Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 2 Nov 2024 11:49:41 -0600 Subject: fdt: Correct condition for receiving bloblist The condition for receiving a bloblist from TPL is reversed. This was only noticed are the other fixes landed. Fix it. Signed-off-by: Simon Glass Reviewed-by: Matthias Brugger --- lib/fdtdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/fdtdec.c b/lib/fdtdec.c index b0655988029..60e28173c03 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -1677,7 +1677,7 @@ int fdtdec_setup(void) */ if (CONFIG_IS_ENABLED(BLOBLIST) && (xpl_prev_phase() != PHASE_TPL || - !IS_ENABLED(CONFIG_TPL_BLOBLIST))) { + IS_ENABLED(CONFIG_TPL_BLOBLIST))) { ret = bloblist_maybe_init(); if (!ret) { gd->fdt_blob = bloblist_find(BLOBLISTT_CONTROL_FDT, 0); -- cgit v1.3.1 From fc37a73e667916e15e01e0f9d189da792df2b351 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 2 Nov 2024 11:49:42 -0600 Subject: fdt: Swap the signature for board_fdt_blob_setup() This returns a devicetree and updates a parameter with an error code. Swap it, since this fits better with the way U-Boot normally works. It also (more easily) allows leaving the existing pointer unchanged. No yaks were harmed in this change, but there is a very small code-size reduction. For sifive, the OF_BOARD option must be set for the function to be called, so there is no point in checking it again. Also OF_SEPARATE is defined always. Signed-off-by: Simon Glass Reviewed-by: Matthias Brugger Reviewed-by: Patrice Chotard [trini: Update total_compute] Signed-off-by: Tom Rini --- arch/arm/mach-apple/board.c | 7 +++-- arch/arm/mach-snapdragon/board.c | 9 +++--- arch/arm/mach-stm32mp/boot_params.c | 19 +++++++------ arch/sandbox/cpu/cpu.c | 34 +++++++++++------------ board/Marvell/octeontx/board-fdt.c | 12 +++----- board/Marvell/octeontx2/board-fdt.c | 12 +++----- board/Marvell/octeontx2/board.c | 3 +- board/andestech/ae350/ae350.c | 23 ++++++++------- board/armltd/total_compute/total_compute.c | 12 ++++---- board/armltd/vexpress64/vexpress64.c | 33 ++++++++++------------ board/broadcom/bcmstb/bcmstb.c | 7 +++-- board/emulation/qemu-arm/qemu-arm.c | 7 +++-- board/emulation/qemu-ppce500/qemu-ppce500.c | 12 +++----- board/emulation/qemu-riscv/qemu-riscv.c | 7 +++-- board/highbank/highbank.c | 7 +++-- board/raspberrypi/rpi/rpi.c | 13 ++++----- board/sifive/unleashed/unleashed.c | 12 ++++---- board/sifive/unmatched/unmatched.c | 11 ++++---- board/starfive/visionfive2/starfive_visionfive2.c | 11 ++++---- board/xen/xenguest_arm64/xenguest_arm64.c | 14 +++++----- board/xilinx/common/board.c | 26 +++++++++-------- include/fdtdec.h | 9 +++--- lib/fdtdec.c | 14 +++++++--- 23 files changed, 157 insertions(+), 157 deletions(-) (limited to 'lib') diff --git a/arch/arm/mach-apple/board.c b/arch/arm/mach-apple/board.c index 0b6d290b8ac..2644a04a622 100644 --- a/arch/arm/mach-apple/board.c +++ b/arch/arm/mach-apple/board.c @@ -691,11 +691,12 @@ int dram_init_banksize(void) extern long fw_dtb_pointer; -void *board_fdt_blob_setup(int *err) +int board_fdt_blob_setup(void **fdtp) { /* Return DTB pointer passed by m1n1 */ - *err = 0; - return (void *)fw_dtb_pointer; + *fdtp = (void *)fw_dtb_pointer; + + return 0; } void build_mem_map(void) diff --git a/arch/arm/mach-snapdragon/board.c b/arch/arm/mach-snapdragon/board.c index 75a880f093c..f1319df4314 100644 --- a/arch/arm/mach-snapdragon/board.c +++ b/arch/arm/mach-snapdragon/board.c @@ -150,12 +150,12 @@ static void show_psci_version(void) * or for supporting quirky devices where it's easier to leave the downstream DT in place * to improve ABL compatibility. Otherwise, we use the DT provided by ABL. */ -void *board_fdt_blob_setup(int *err) +int board_fdt_blob_setup(void **fdtp) { struct fdt_header *fdt; bool internal_valid, external_valid; + int ret = 0; - *err = 0; fdt = (struct fdt_header *)get_prev_bl_fdt_addr(); external_valid = fdt && !fdt_check_header(fdt); internal_valid = !fdt_check_header(gd->fdt_blob); @@ -170,10 +170,11 @@ void *board_fdt_blob_setup(int *err) if (internal_valid) { debug("Using built in FDT\n"); + ret = -EEXIST; } else { debug("Using external FDT\n"); /* So we can use it before returning */ - gd->fdt_blob = fdt; + *fdtp = fdt; } /* @@ -182,7 +183,7 @@ void *board_fdt_blob_setup(int *err) */ qcom_parse_memory(); - return (void *)gd->fdt_blob; + return ret; } void reset_cpu(void) diff --git a/arch/arm/mach-stm32mp/boot_params.c b/arch/arm/mach-stm32mp/boot_params.c index ebddf6a7dbc..2d058edc419 100644 --- a/arch/arm/mach-stm32mp/boot_params.c +++ b/arch/arm/mach-stm32mp/boot_params.c @@ -6,6 +6,7 @@ #define LOG_CATEGORY LOGC_ARCH #include +#include #include #include #include @@ -16,20 +17,22 @@ * Use the saved FDT address provided by TF-A at boot time (NT_FW_CONFIG = * Non Trusted Firmware configuration file) when the pointer is valid */ -void *board_fdt_blob_setup(int *err) +int board_fdt_blob_setup(void **fdtp) { unsigned long nt_fw_dtb = get_stm32mp_bl2_dtb(); log_debug("%s: nt_fw_dtb=%lx\n", __func__, nt_fw_dtb); - *err = 0; /* use external device tree only if address is valid */ - if (nt_fw_dtb >= STM32_DDR_BASE) { - if (fdt_magic(nt_fw_dtb) == FDT_MAGIC) - return (void *)nt_fw_dtb; - log_debug("%s: DTB not found.\n", __func__); + if (nt_fw_dtb < STM32_DDR_BASE || + fdt_magic(nt_fw_dtb) != FDT_MAGIC) { + log_debug("DTB not found.\n"); + log_debug("fall back to builtin DTB, %p\n", _end); + + return -EEXIST; } - log_debug("%s: fall back to builtin DTB, %p\n", __func__, _end); - return (void *)_end; + *fdtp = (void *)nt_fw_dtb; + + return 0; } diff --git a/arch/sandbox/cpu/cpu.c b/arch/sandbox/cpu/cpu.c index d1c4dcf0764..6407193c5f1 100644 --- a/arch/sandbox/cpu/cpu.c +++ b/arch/sandbox/cpu/cpu.c @@ -368,7 +368,7 @@ static int setup_auto_tree(void *blob) return 0; } -void *board_fdt_blob_setup(int *ret) +int board_fdt_blob_setup(void **fdtp) { struct sandbox_state *state = state_get_current(); const char *fname = state->fdt_fname; @@ -378,43 +378,41 @@ void *board_fdt_blob_setup(int *ret) int fd; if (gd->fdt_blob) - return (void *)gd->fdt_blob; + return -EEXIST; blob = map_sysmem(CONFIG_SYS_FDT_LOAD_ADDR, 0); - *ret = 0; if (!state->fdt_fname) { err = setup_auto_tree(blob); - if (!err) - goto done; - os_printf("Unable to create empty FDT: %s\n", fdt_strerror(err)); - *ret = -EINVAL; - goto fail; + if (err) { + os_printf("Unable to create empty FDT: %s\n", + fdt_strerror(err)); + return -EINVAL; + } + *fdtp = blob; + + return 0; } err = os_get_filesize(fname, &size); if (err < 0) { os_printf("Failed to find FDT file '%s'\n", fname); - *ret = err; - goto fail; + return err; } fd = os_open(fname, OS_O_RDONLY); if (fd < 0) { os_printf("Failed to open FDT file '%s'\n", fname); - *ret = -EACCES; - goto fail; + return -EACCES; } if (os_read(fd, blob, size) != size) { os_close(fd); os_printf("Failed to read FDT file '%s'\n", fname); - *ret = -EIO; - goto fail; + return -EIO; } os_close(fd); -done: - return blob; -fail: - return NULL; + *fdtp = blob; + + return 0; } ulong timer_get_boot_us(void) diff --git a/board/Marvell/octeontx/board-fdt.c b/board/Marvell/octeontx/board-fdt.c index 6642b167e19..9d913b959e0 100644 --- a/board/Marvell/octeontx/board-fdt.c +++ b/board/Marvell/octeontx/board-fdt.c @@ -296,13 +296,9 @@ int ft_board_setup(void *blob, struct bd_info *bd) return 0; } -/** - * Return the FDT base address that was passed by ATF - * - * Return: FDT base address received from ATF in x1 register - */ -void *board_fdt_blob_setup(int *err) +int board_fdt_blob_setup(void **fdtp) { - *err = 0; - return (void *)fdt_base_addr; + *fdtp = (void *)fdt_base_addr; + + return 0; } diff --git a/board/Marvell/octeontx2/board-fdt.c b/board/Marvell/octeontx2/board-fdt.c index 04be9fb0a9a..e5a4db00bb7 100644 --- a/board/Marvell/octeontx2/board-fdt.c +++ b/board/Marvell/octeontx2/board-fdt.c @@ -210,13 +210,9 @@ int ft_board_setup(void *blob, struct bd_info *bd) return 0; } -/** - * Return the FDT base address that was passed by ATF - * - * Return: FDT base address received from ATF in x1 register - */ -void *board_fdt_blob_setup(int *err) +int board_fdt_blob_setup(void **fdtp) { - *err = 0; - return (void *)fdt_base_addr; + *fdtp = (void *)fdt_base_addr; + + return 0; } diff --git a/board/Marvell/octeontx2/board.c b/board/Marvell/octeontx2/board.c index 974e9eb8200..01ba53cf68d 100644 --- a/board/Marvell/octeontx2/board.c +++ b/board/Marvell/octeontx2/board.c @@ -234,7 +234,8 @@ static int do_go_uboot(struct cmd_tbl *cmdtp, int flag, int argc, return CMD_RET_USAGE; addr = hextoul(argv[1], NULL); - fdt = board_fdt_blob_setup(&err); + fdt = (void *)gd->fdt_blob; + err = board_fdt_blob_setup(&fdt); entry = (uboot_entry_t)addr; flush_cache((ulong)addr, 1 << 20); /* 1MiB should be enough */ dcache_disable(); diff --git a/board/andestech/ae350/ae350.c b/board/andestech/ae350/ae350.c index 5ae5baed6ba..1d9d4a929c2 100644 --- a/board/andestech/ae350/ae350.c +++ b/board/andestech/ae350/ae350.c @@ -79,21 +79,24 @@ ulong board_flash_get_legacy(ulong base, int banknum, flash_info_t *info) } #define ANDES_HW_DTB_ADDRESS 0xF2000000 -void *board_fdt_blob_setup(int *err) +int board_fdt_blob_setup(void **fdtp) { - *err = 0; - if (IS_ENABLED(CONFIG_OF_SEPARATE) || IS_ENABLED(CONFIG_OF_BOARD)) { - if (fdt_magic((uintptr_t)gd->arch.firmware_fdt_addr) == FDT_MAGIC) - return (void *)(ulong)gd->arch.firmware_fdt_addr; + if (fdt_magic((uintptr_t)gd->arch.firmware_fdt_addr) == + FDT_MAGIC) { + *fdtp = (void *)(ulong)gd->arch.firmware_fdt_addr; + + return 0; + } } - if (fdt_magic(CONFIG_SYS_FDT_BASE) == FDT_MAGIC) - return (void *)CONFIG_SYS_FDT_BASE; - return (void *)ANDES_HW_DTB_ADDRESS; + if (fdt_magic(CONFIG_SYS_FDT_BASE) == FDT_MAGIC) { + *fdtp = (void *)CONFIG_SYS_FDT_BASE; + + return 0; + } - *err = -EINVAL; - return NULL; + return -EINVAL; } #ifdef CONFIG_SPL_BOARD_INIT diff --git a/board/armltd/total_compute/total_compute.c b/board/armltd/total_compute/total_compute.c index 1336d2eb163..75ba3c33d56 100644 --- a/board/armltd/total_compute/total_compute.c +++ b/board/armltd/total_compute/total_compute.c @@ -37,15 +37,13 @@ struct mm_region *mem_map = total_compute_mem_map; */ unsigned long __section(".data") fw_dtb_pointer; -void *board_fdt_blob_setup(int *err) +int board_fdt_blob_setup(void **fdtp) { - *err = 0; - if (fdt_magic(fw_dtb_pointer) != FDT_MAGIC) { - *err = -ENXIO; - return NULL; - } + if (fdt_magic(fw_dtb_pointer) != FDT_MAGIC) + return -ENXIO; - return (void *)fw_dtb_pointer; + *fdtp = (void *)fw_dtb_pointer; + return 0; } int misc_init_r(void) diff --git a/board/armltd/vexpress64/vexpress64.c b/board/armltd/vexpress64/vexpress64.c index 0119f54f0df..b5ede58757d 100644 --- a/board/armltd/vexpress64/vexpress64.c +++ b/board/armltd/vexpress64/vexpress64.c @@ -168,42 +168,37 @@ static bool is_valid_dtb(uintptr_t dtb_ptr) return fdt_subnode_offset((void *)dtb_ptr, 0, "memory") >= 0; } -void *board_fdt_blob_setup(int *err) +int board_fdt_blob_setup(void **fdtp) { #ifdef CONFIG_TARGET_VEXPRESS64_JUNO phys_addr_t fdt_rom_addr = find_dtb_in_nor_flash(CONFIG_JUNO_DTB_PART); - *err = 0; - if (fdt_rom_addr == ~0UL) { - *err = -ENXIO; - return NULL; - } + if (fdt_rom_addr == ~0UL) + return -ENXIO; - return (void *)fdt_rom_addr; + *fdtp = (void *)fdt_rom_addr; + return 0; #endif #ifdef VEXPRESS_FDT_ADDR if (fdt_magic(VEXPRESS_FDT_ADDR) == FDT_MAGIC) { - *err = 0; - return (void *)VEXPRESS_FDT_ADDR; + *fdtp = (void *)VEXPRESS_FDT_ADDR; + return 0; } #endif if (is_valid_dtb(prior_stage_fdt_address[1])) { - *err = 0; - return (void *)prior_stage_fdt_address[1]; + *fdtp = (void *)prior_stage_fdt_address[1]; + return 0; } else if (is_valid_dtb(prior_stage_fdt_address[0])) { - *err = 0; - return (void *)prior_stage_fdt_address[0]; + *fdtp = (void *)prior_stage_fdt_address[0]; + return 0; } - if (fdt_magic(gd->fdt_blob) == FDT_MAGIC) { - *err = 0; - return (void *)gd->fdt_blob; - } + if (fdt_magic(*fdtp) == FDT_MAGIC) + return 0; - *err = -ENXIO; - return NULL; + return -ENXIO; } #endif diff --git a/board/broadcom/bcmstb/bcmstb.c b/board/broadcom/bcmstb/bcmstb.c index bc05aecc446..e655f610c84 100644 --- a/board/broadcom/bcmstb/bcmstb.c +++ b/board/broadcom/bcmstb/bcmstb.c @@ -130,9 +130,10 @@ int board_late_init(void) return 0; } -void *board_fdt_blob_setup(int *err) +int board_fdt_blob_setup(void **fdtp) { - *err = 0; /* Stored the DTB address there during our init */ - return (void *)prior_stage_fdt_address; + *fdtp = (void *)prior_stage_fdt_address; + + return 0; } diff --git a/board/emulation/qemu-arm/qemu-arm.c b/board/emulation/qemu-arm/qemu-arm.c index e0e18b4dfea..31f5a775137 100644 --- a/board/emulation/qemu-arm/qemu-arm.c +++ b/board/emulation/qemu-arm/qemu-arm.c @@ -149,11 +149,12 @@ int dram_init_banksize(void) return 0; } -void *board_fdt_blob_setup(int *err) +int board_fdt_blob_setup(void **fdtp) { - *err = 0; /* QEMU loads a generated DTB for us at the start of RAM. */ - return (void *)CFG_SYS_SDRAM_BASE; + *fdtp = (void *)CFG_SYS_SDRAM_BASE; + + return 0; } void enable_caches(void) diff --git a/board/emulation/qemu-ppce500/qemu-ppce500.c b/board/emulation/qemu-ppce500/qemu-ppce500.c index 58e5d5eb942..40d295dbf06 100644 --- a/board/emulation/qemu-ppce500/qemu-ppce500.c +++ b/board/emulation/qemu-ppce500/qemu-ppce500.c @@ -334,15 +334,11 @@ u32 cpu_mask(void) return (1 << cpu_numcores()) - 1; } -/** - * Return the virtual address of FDT that was passed by QEMU - * - * Return: virtual address of FDT received from QEMU in r3 register - */ -void *board_fdt_blob_setup(int *err) +int board_fdt_blob_setup(void **fdtp) { - *err = 0; - return get_fdt_virt(); + *fdtp = get_fdt_virt(); + + return 0; } /* See CFG_SYS_NS16550_CLK in arch/powerpc/include/asm/config.h */ diff --git a/board/emulation/qemu-riscv/qemu-riscv.c b/board/emulation/qemu-riscv/qemu-riscv.c index e5193e31e37..a90222ea6a4 100644 --- a/board/emulation/qemu-riscv/qemu-riscv.c +++ b/board/emulation/qemu-riscv/qemu-riscv.c @@ -64,9 +64,10 @@ int board_fit_config_name_match(const char *name) } #endif -void *board_fdt_blob_setup(int *err) +int board_fdt_blob_setup(void **fdtp) { - *err = 0; /* Stored the DTB address there during our init */ - return (void *)(ulong)gd->arch.firmware_fdt_addr; + *fdtp = (void *)(ulong)gd->arch.firmware_fdt_addr; + + return 0; } diff --git a/board/highbank/highbank.c b/board/highbank/highbank.c index f3df83ed6c9..0ec88447384 100644 --- a/board/highbank/highbank.c +++ b/board/highbank/highbank.c @@ -97,15 +97,16 @@ int ft_board_setup(void *fdt, struct bd_info *bd) } #endif -void *board_fdt_blob_setup(int *err) +int board_fdt_blob_setup(void **fdtp) { - *err = 0; /* * The ECME management processor loads the DTB from NOR flash * into DRAM (at 4KB), where it gets patched to contain the * detected memory size. */ - return (void *)0x1000; + *fdtp = (void *)0x1000; + + return 0; } static int is_highbank(void) diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c index 9122f33d88d..c46fe4b2350 100644 --- a/board/raspberrypi/rpi/rpi.c +++ b/board/raspberrypi/rpi/rpi.c @@ -508,15 +508,14 @@ int board_init(void) /* * If the firmware passed a device tree use it for U-Boot. */ -void *board_fdt_blob_setup(int *err) +int board_fdt_blob_setup(void **fdtp) { - *err = 0; - if (fdt_magic(fw_dtb_pointer) != FDT_MAGIC) { - *err = -ENXIO; - return NULL; - } + if (fdt_magic(fw_dtb_pointer) != FDT_MAGIC) + return -ENXIO; - return (void *)fw_dtb_pointer; + *fdtp = (void *)fw_dtb_pointer; + + return 0; } int copy_property(void *dst, void *src, char *path, char *property) diff --git a/board/sifive/unleashed/unleashed.c b/board/sifive/unleashed/unleashed.c index 3c5dd50c369..c1c374610c3 100644 --- a/board/sifive/unleashed/unleashed.c +++ b/board/sifive/unleashed/unleashed.c @@ -114,15 +114,15 @@ int misc_init_r(void) #endif -void *board_fdt_blob_setup(int *err) +int board_fdt_blob_setup(void **fdtp) { - *err = 0; - if (IS_ENABLED(CONFIG_OF_SEPARATE) || IS_ENABLED(CONFIG_OF_BOARD)) { - if (gd->arch.firmware_fdt_addr) - return (ulong *)(uintptr_t)gd->arch.firmware_fdt_addr; + if (gd->arch.firmware_fdt_addr) { + *fdtp = (ulong *)(uintptr_t)gd->arch.firmware_fdt_addr; + + return 0; } - return (ulong *)_end; + return -EEXIST; } int board_init(void) diff --git a/board/sifive/unmatched/unmatched.c b/board/sifive/unmatched/unmatched.c index c8696270ba2..23e03e145ee 100644 --- a/board/sifive/unmatched/unmatched.c +++ b/board/sifive/unmatched/unmatched.c @@ -10,15 +10,14 @@ #include #include -void *board_fdt_blob_setup(int *err) +int board_fdt_blob_setup(void **fdtp) { - *err = 0; - if (IS_ENABLED(CONFIG_OF_SEPARATE) || IS_ENABLED(CONFIG_OF_BOARD)) { - if (gd->arch.firmware_fdt_addr) - return (ulong *)(uintptr_t)gd->arch.firmware_fdt_addr; + if (gd->arch.firmware_fdt_addr) { + *fdtp = (ulong *)(uintptr_t)gd->arch.firmware_fdt_addr; + return 0; } - return (ulong *)_end; + return -EEXIST; } int board_init(void) diff --git a/board/starfive/visionfive2/starfive_visionfive2.c b/board/starfive/visionfive2/starfive_visionfive2.c index f6114602f88..3940d45b13f 100644 --- a/board/starfive/visionfive2/starfive_visionfive2.c +++ b/board/starfive/visionfive2/starfive_visionfive2.c @@ -115,15 +115,14 @@ int board_late_init(void) return 0; } -void *board_fdt_blob_setup(int *err) +int board_fdt_blob_setup(void **fdtp) { - *err = 0; - if (IS_ENABLED(CONFIG_OF_SEPARATE) || IS_ENABLED(CONFIG_OF_BOARD)) { - if (gd->arch.firmware_fdt_addr) - return (ulong *)(uintptr_t)gd->arch.firmware_fdt_addr; + if (gd->arch.firmware_fdt_addr) { + *fdtp = (ulong *)(uintptr_t)gd->arch.firmware_fdt_addr; + return 0; } - return (ulong *)_end; + return -EEXIST; } int ft_board_setup(void *blob, struct bd_info *bd) diff --git a/board/xen/xenguest_arm64/xenguest_arm64.c b/board/xen/xenguest_arm64/xenguest_arm64.c index 4c3b9c9e278..216a022aa15 100644 --- a/board/xen/xenguest_arm64/xenguest_arm64.c +++ b/board/xen/xenguest_arm64/xenguest_arm64.c @@ -44,14 +44,14 @@ int board_init(void) * x0 is the physical address of the device tree blob (dtb) in system RAM. * This is stored in rom_pointer during low level init. */ -void *board_fdt_blob_setup(int *err) +int board_fdt_blob_setup(void **fdtp) { - *err = 0; - if (fdt_magic(rom_pointer[0]) != FDT_MAGIC) { - *err = -ENXIO; - return NULL; - } - return (void *)rom_pointer[0]; + if (fdt_magic(rom_pointer[0]) != FDT_MAGIC) + return -ENXIO; + + *fdtp = (void *)rom_pointer[0]; + + return 0; } /* diff --git a/board/xilinx/common/board.c b/board/xilinx/common/board.c index a12dccd4c51..deea6c71103 100644 --- a/board/xilinx/common/board.c +++ b/board/xilinx/common/board.c @@ -358,17 +358,17 @@ __maybe_unused int xilinx_read_eeprom(void) } #if defined(CONFIG_OF_BOARD) -void *board_fdt_blob_setup(int *err) +int board_fdt_blob_setup(void **fdtp) { void *fdt_blob; - *err = 0; - if (IS_ENABLED(CONFIG_TARGET_XILINX_MBV)) { fdt_blob = (void *)CONFIG_XILINX_OF_BOARD_DTB_ADDR; - if (fdt_magic(fdt_blob) == FDT_MAGIC) - return fdt_blob; + if (fdt_magic(fdt_blob) == FDT_MAGIC) { + *fdtp = fdt_blob; + return 0; + } } if (!IS_ENABLED(CONFIG_XPL_BUILD) && @@ -376,8 +376,10 @@ void *board_fdt_blob_setup(int *err) !IS_ENABLED(CONFIG_ZYNQMP_NO_DDR)) { fdt_blob = (void *)CONFIG_XILINX_OF_BOARD_DTB_ADDR; - if (fdt_magic(fdt_blob) == FDT_MAGIC) - return fdt_blob; + if (fdt_magic(fdt_blob) == FDT_MAGIC) { + *fdtp = fdt_blob; + return 0; + } debug("DTB is not passed via %p\n", fdt_blob); } @@ -396,13 +398,15 @@ void *board_fdt_blob_setup(int *err) fdt_blob = (ulong *)_end; } - if (fdt_magic(fdt_blob) == FDT_MAGIC) - return fdt_blob; + if (fdt_magic(fdt_blob) == FDT_MAGIC) { + *fdtp = fdt_blob; + + return 0; + } debug("DTB is also not passed via %p\n", fdt_blob); - *err = -EINVAL; - return NULL; + return -EINVAL; } #endif diff --git a/include/fdtdec.h b/include/fdtdec.h index 555c9520379..58bbd8f392e 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -1191,11 +1191,12 @@ int fdtdec_resetup(int *rescan); * * The existing devicetree is available at gd->fdt_blob * - * @err: 0 on success, -EEXIST if the devicetree is already correct, or other - * internal error code if we fail to setup a DTB - * @returns new devicetree blob pointer + * @fdtp: Existing devicetree blob pointer; update this and return 0 if a + * different devicetree should be used + * Return: 0 on success, -EEXIST if the existing FDT is OK, -ve error code if we + * fail to setup a DTB */ -void *board_fdt_blob_setup(int *err); +int board_fdt_blob_setup(void **fdtp); /* * Decode the size of memory diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 60e28173c03..c5d29d4385a 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -1706,11 +1706,17 @@ int fdtdec_setup(void) /* Allow the board to override the fdt address. */ if (IS_ENABLED(CONFIG_OF_BOARD)) { - gd->fdt_blob = board_fdt_blob_setup(&ret); - if (!ret) + void *blob; + + blob = (void *)gd->fdt_blob; + ret = board_fdt_blob_setup(&blob); + if (ret) { + if (ret != -EEXIST) + return ret; + } else { gd->fdt_src = FDTSRC_BOARD; - else if (ret != -EEXIST) - return ret; + gd->fdt_blob = blob; + } } /* Allow the early environment to override the fdt address */ -- cgit v1.3.1 From 79d7b11102e31f3b92afff1c94dd9fe1a8b9a9e4 Mon Sep 17 00:00:00 2001 From: Paul HENRYS Date: Mon, 25 Nov 2024 18:47:15 +0100 Subject: aes: Allow to store randomly generated IV in the FIT When the initialisation vector is randomly generated, its value shall be stored in the FIT together with the encrypted data. The changes allow to store the IV in the FIT also in the case where the key is not stored in the DTB but retrieved somewhere else at runtime. Signed-off-by: Paul HENRYS Reviewed-by: Simon Glass --- include/image.h | 15 +++++++++++++++ lib/aes/aes-encrypt.c | 7 +++++++ tools/image-host.c | 2 +- 3 files changed, 23 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/include/image.h b/include/image.h index 9be5acd8158..cfe3c971a36 100644 --- a/include/image.h +++ b/include/image.h @@ -1788,6 +1788,21 @@ struct cipher_algo { const unsigned char *data, int data_len, unsigned char **cipher, int *cipher_len); + /** + * add_cipher_data() - Add cipher data to the FIT and device tree + * + * This is used to add the ciphered data to the FIT and other cipher + * related information (key and initialization vector) to a device tree. + * + * @info: Pointer to image cipher information. + * @keydest: Pointer to a device tree where the key and IV can be + * stored. keydest can be NULL when the key is retrieved at + * runtime by another mean. + * @fit: Pointer to the FIT image. + * @node_noffset: Offset where the cipher information are stored in the + * FIT. + * return: 0 on success, a negative error code otherwise. + */ int (*add_cipher_data)(struct image_cipher_info *info, void *keydest, void *fit, int node_noffset); diff --git a/lib/aes/aes-encrypt.c b/lib/aes/aes-encrypt.c index e74e35eaa28..90e1407b4f0 100644 --- a/lib/aes/aes-encrypt.c +++ b/lib/aes/aes-encrypt.c @@ -84,6 +84,13 @@ int image_aes_add_cipher_data(struct image_cipher_info *info, void *keydest, char name[128]; int ret = 0; + if (!keydest && !info->ivname) { + /* At least, store the IV in the FIT image */ + ret = fdt_setprop(fit, node_noffset, "iv", + info->iv, info->cipher->iv_len); + goto done; + } + /* Either create or overwrite the named cipher node */ parent = fdt_subnode_offset(keydest, 0, FIT_CIPHER_NODENAME); if (parent == -FDT_ERR_NOTFOUND) { diff --git a/tools/image-host.c b/tools/image-host.c index 5e01b853c50..16389bd4880 100644 --- a/tools/image-host.c +++ b/tools/image-host.c @@ -535,7 +535,7 @@ fit_image_process_cipher(const char *keydir, void *keydest, void *fit, * size values * And, if needed, write the iv in the FIT file */ - if (keydest) { + if (keydest || (!keydest && !info.ivname)) { ret = info.cipher->add_cipher_data(&info, keydest, fit, node_noffset); if (ret) { fprintf(stderr, -- cgit v1.3.1 From 0b0e0f273dbd3ea6e60c98dab14e09cc9fb64958 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 19 Dec 2024 11:29:03 -0700 Subject: spl: lib: Allow for decompression in any SPL build Add Kconfig symbols and update the Makefile rules so that decompression can be used in TPL and VPL Signed-off-by: Simon Glass --- lib/Kconfig | 35 +++++++++++++++++++++++++++++++++++ lib/Makefile | 12 ++++++------ 2 files changed, 41 insertions(+), 6 deletions(-) (limited to 'lib') diff --git a/lib/Kconfig b/lib/Kconfig index 0b089814d14..203f40e2662 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -841,12 +841,36 @@ config SPL_LZ4 fast compression and decompression speed. It belongs to the LZ77 family of byte-oriented compression schemes. +config TPL_LZ4 + bool "Enable LZ4 decompression support in TPL" + depends on TPL + help + This enables support for the LZ4 decompression algorithm in TPL. LZ4 + is a lossless data compression algorithm that is focused on + fast compression and decompression speed. It belongs to the LZ77 + family of byte-oriented compression schemes. + +config VPL_LZ4 + bool "Enable LZ4 decompression support in VPL" + depends on VPL + help + This enables support for the LZ4 decompression algorithm in VPL. LZ4 + is a lossless data compression algorithm that is focused on + fast compression and decompression speed. It belongs to the LZ77 + family of byte-oriented compression schemes. + config SPL_LZMA bool "Enable LZMA decompression support for SPL build" depends on SPL help This enables support for LZMA compression algorithm for SPL boot. +config TPL_LZMA + bool "Enable LZMA decompression support for TPL build" + depends on TPL + help + This enables support for LZMA compression algorithm for TPL boot. + config VPL_LZMA bool "Enable LZMA decompression support for VPL build" default y if LZMA @@ -865,11 +889,22 @@ config SPL_GZIP help This enables support for the GZIP compression algorithm for SPL boot. +config TPL_GZIP + bool "Enable gzip decompression support for SPL build" + select TPL_ZLIB + help + This enables support for the GZIP compression algorithm for TPL + config SPL_ZLIB bool help This enables compression lib for SPL boot. +config TPL_ZLIB + bool + help + This enables compression lib for TPL + config SPL_ZSTD bool "Enable Zstandard decompression support in SPL" depends on SPL diff --git a/lib/Makefile b/lib/Makefile index d24ed629732..5cb3278d2ef 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -83,12 +83,12 @@ obj-$(CONFIG_$(XPL_)SHA512_LEGACY) += sha512.o obj-$(CONFIG_CRYPT_PW) += crypt/ obj-$(CONFIG_$(XPL_)ASN1_DECODER_LEGACY) += asn1_decoder.o -obj-$(CONFIG_$(XPL_)ZLIB) += zlib/ -obj-$(CONFIG_$(XPL_)ZSTD) += zstd/ -obj-$(CONFIG_$(XPL_)GZIP) += gunzip.o -obj-$(CONFIG_$(XPL_)LZO) += lzo/ -obj-$(CONFIG_$(XPL_)LZMA) += lzma/ -obj-$(CONFIG_$(XPL_)LZ4) += lz4_wrapper.o +obj-$(CONFIG_$(PHASE_)ZLIB) += zlib/ +obj-$(CONFIG_$(PHASE_)ZSTD) += zstd/ +obj-$(CONFIG_$(PHASE_)GZIP) += gunzip.o +obj-$(CONFIG_$(PHASE_)LZO) += lzo/ +obj-$(CONFIG_$(PHASE_)LZMA) += lzma/ +obj-$(CONFIG_$(PHASE_)LZ4) += lz4_wrapper.o obj-$(CONFIG_$(XPL_)LIB_RATIONAL) += rational.o -- cgit v1.3.1 From ded772fafacf71b15f838c1b69983656d1decab3 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 19 Dec 2024 11:29:05 -0700 Subject: lib: Allow crc8 in TPL and VPL Provide options to enable the CRC8 feature in TPL and VPL builds. Signed-off-by: Simon Glass --- lib/Kconfig | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'lib') diff --git a/lib/Kconfig b/lib/Kconfig index 203f40e2662..8f1a96d98c4 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -728,6 +728,24 @@ config SPL_CRC8 checksum with feedback to produce an 8-bit result. The code is small and it does not require a lookup table (unlike CRC32). +config TPL_CRC8 + bool "Support CRC8 in TPL" + depends on TPL + help + Enables CRC8 support in TPL. This is not normally required. CRC8 is + a simple and fast checksumming algorithm which does a bytewise + checksum with feedback to produce an 8-bit result. The code is small + and it does not require a lookup table (unlike CRC32). + +config VPL_CRC8 + bool "Support CRC8 in VPL" + depends on VPL + help + Enables CRC8 support in VPL. This is not normally required. CRC8 is + a simple and fast checksumming algorithm which does a bytewise + checksum with feedback to produce an 8-bit result. The code is small + and it does not require a lookup table (unlike CRC32). + config SPL_CRC16 bool "Support CRC16 in SPL" depends on SPL -- cgit v1.3.1 From 6f1b27a724b0d75bf89cc0f8be95fc3bcb4d4fe8 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 19 Dec 2024 11:29:07 -0700 Subject: hash: Plumb crc8 into the hash functions Add an entry for crc8, with watchdog handling. Signed-off-by: Simon Glass Reviewed-by: Jaehoon Chung --- common/Kconfig | 8 ++++++++ common/hash.c | 8 ++++++++ include/u-boot/crc.h | 3 +++ lib/crc8.c | 6 ++++++ 4 files changed, 25 insertions(+) (limited to 'lib') diff --git a/common/Kconfig b/common/Kconfig index e8d89bf6eb9..0e8c44f3f74 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -845,6 +845,14 @@ config HASH and the algorithms it supports are defined in common/hash.c. See also CMD_HASH for command-line access. +config HASH_CRC8 + bool "Make crc8 available via the hash API" + depends on HASH && CRC8 + help + Most times, the crc8() function is called directly. To make it also + available via the hash API, e.g. in hash_block(), enable this + option. + config AVB_VERIFY bool "Build Android Verified Boot operations" depends on LIBAVB diff --git a/common/hash.c b/common/hash.c index db6925d6782..8dd9da85768 100644 --- a/common/hash.c +++ b/common/hash.c @@ -304,6 +304,14 @@ static struct hash_algo hash_algo[] = { .hash_update = hash_update_crc16_ccitt, .hash_finish = hash_finish_crc16_ccitt, }, +#if CONFIG_IS_ENABLED(CRC8) && IS_ENABLED(CONFIG_HASH_CRC8) + { + .name = "crc8", + .digest_size = 1, + .chunk_size = CHUNKSZ_CRC32, + .hash_func_ws = crc8_wd_buf, + }, +#endif #if CONFIG_IS_ENABLED(CRC32) { .name = "crc32", diff --git a/include/u-boot/crc.h b/include/u-boot/crc.h index 5174bd7ac41..b2badaf6a97 100644 --- a/include/u-boot/crc.h +++ b/include/u-boot/crc.h @@ -25,6 +25,9 @@ */ unsigned int crc8(unsigned int crc_start, const unsigned char *vptr, int len); +void crc8_wd_buf(const unsigned char *input, unsigned int len, + unsigned char output[1], unsigned int chunk_sz); + /* lib/crc16.c - 16 bit CRC with polynomial x^16 + x^15 + x^2 + 1 */ uint16_t crc16(uint16_t crc, const unsigned char *buffer, size_t len); diff --git a/lib/crc8.c b/lib/crc8.c index 20d46d16147..811e19917b4 100644 --- a/lib/crc8.c +++ b/lib/crc8.c @@ -32,3 +32,9 @@ unsigned int crc8(unsigned int crc, const unsigned char *vptr, int len) return crc; } + +void crc8_wd_buf(const unsigned char *input, unsigned int len, + unsigned char output[1], unsigned int chunk_sz) +{ + *output = crc8(0, input, len); +} -- cgit v1.3.1 From a59887d251307ad4ebc194b58ddb5af003e8fe06 Mon Sep 17 00:00:00 2001 From: Sam Protsenko Date: Tue, 10 Dec 2024 20:25:47 -0600 Subject: lmb: Fix flags data type in lmb_add_region_flags() rgnflags variable in lmb_add_region_flags() has incorrect type: it's declared as phys_size_t when it should be enum lmb_flags. That copy-paste mistake was firstly introduced in commit 59c0ea5df33f ("lmb: Add support of flags for no-map properties"), and then copied further into commit ed17a33fed29 ("lmb: make LMB memory map persistent and global"). Fix it by using the correct type to match struct lmb_region field. No functional change. Signed-off-by: Sam Protsenko Reviewed-by: Ilias Apalodimas Acked-by: Sughosh Ganu --- lib/lmb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/lmb.c b/lib/lmb.c index a695edf70df..1d57f48bff6 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -202,7 +202,7 @@ static long lmb_add_region_flags(struct alist *lmb_rgn_lst, phys_addr_t base, for (i = 0; i < lmb_rgn_lst->count; i++) { phys_addr_t rgnbase = rgn[i].base; phys_size_t rgnsize = rgn[i].size; - phys_size_t rgnflags = rgn[i].flags; + enum lmb_flags rgnflags = rgn[i].flags; ret = lmb_addrs_adjacent(base, size, rgnbase, rgnsize); if (ret > 0) { -- cgit v1.3.1 From 8ab61628b8a2292aa9267de64f42d2a81882321b Mon Sep 17 00:00:00 2001 From: Sam Protsenko Date: Tue, 10 Dec 2024 20:25:48 -0600 Subject: lmb: Make const flag_str[] in lmb_print_region_flags() more const flag_str[] is a pointer to const. Make it also a const pointer. Improve a style a bit while a it, to make this line fit 80 characters limit. No functional change. Signed-off-by: Sam Protsenko Reviewed-by: Ilias Apalodimas --- lib/lmb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/lmb.c b/lib/lmb.c index 1d57f48bff6..0f9de26b64a 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -472,7 +472,8 @@ static int lmb_map_update_notify(phys_addr_t addr, phys_size_t size, u8 op, static void lmb_print_region_flags(enum lmb_flags flags) { - const char *flag_str[] = { "none", "no-map", "no-overwrite", "no-notify" }; + const char * const flag_str[] = { "none", "no-map", "no-overwrite", + "no-notify" }; unsigned int pflags = flags & (LMB_NOMAP | LMB_NOOVERWRITE | LMB_NONOTIFY); -- cgit v1.3.1 From 85ebda86faf33edea3a2467c28b47713823c904c Mon Sep 17 00:00:00 2001 From: Sam Protsenko Date: Tue, 10 Dec 2024 20:25:49 -0600 Subject: lmb: Improve coding style Fix checkpatch warnings. No functional change. Signed-off-by: Sam Protsenko Acked-by: Ilias Apalodimas --- lib/lmb.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) (limited to 'lib') diff --git a/lib/lmb.c b/lib/lmb.c index 0f9de26b64a..40f03151929 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -57,7 +57,6 @@ static long lmb_regions_overlap(struct alist *lmb_rgn_lst, unsigned long r1, unsigned long r2) { struct lmb_region *rgn = lmb_rgn_lst->data; - phys_addr_t base1 = rgn[r1].base; phys_size_t size1 = rgn[r1].size; phys_addr_t base2 = rgn[r2].base; @@ -70,11 +69,11 @@ static long lmb_regions_adjacent(struct alist *lmb_rgn_lst, unsigned long r1, unsigned long r2) { struct lmb_region *rgn = lmb_rgn_lst->data; - phys_addr_t base1 = rgn[r1].base; phys_size_t size1 = rgn[r1].size; phys_addr_t base2 = rgn[r2].base; phys_size_t size2 = rgn[r2].size; + return lmb_addrs_adjacent(base1, size1, base2, size2); } @@ -228,6 +227,8 @@ static long lmb_add_region_flags(struct alist *lmb_rgn_lst, phys_addr_t base, coalesced++; break; + + return -1; } } @@ -278,14 +279,17 @@ static long _lmb_free(struct alist *lmb_rgn_lst, phys_addr_t base, phys_addr_t end = base + size - 1; int i; - rgnbegin = rgnend = 0; /* supress gcc warnings */ + /* Suppress GCC warnings */ + rgnbegin = 0; + rgnend = 0; + rgn = lmb_rgn_lst->data; /* Find the region where (base, size) belongs to */ for (i = 0; i < lmb_rgn_lst->count; i++) { rgnbegin = rgn[i].base; rgnend = rgnbegin + rgn[i].size - 1; - if ((rgnbegin <= base) && (end <= rgnend)) + if (rgnbegin <= base && end <= rgnend) break; } @@ -294,7 +298,7 @@ static long _lmb_free(struct alist *lmb_rgn_lst, phys_addr_t base, return -1; /* Check to see if we are removing entire region */ - if ((rgnbegin == base) && (rgnend == end)) { + if (rgnbegin == base && rgnend == end) { lmb_remove_region(lmb_rgn_lst, i); return 0; } @@ -330,6 +334,7 @@ static long lmb_overlaps_region(struct alist *lmb_rgn_lst, phys_addr_t base, for (i = 0; i < lmb_rgn_lst->count; i++) { phys_addr_t rgnbase = rgn[i].base; phys_size_t rgnsize = rgn[i].size; + if (lmb_addrs_overlap(base, size, rgnbase, rgnsize)) break; } @@ -705,7 +710,7 @@ long lmb_reserve(phys_addr_t base, phys_size_t size) } static phys_addr_t _lmb_alloc_base(phys_size_t size, ulong align, - phys_addr_t max_addr, enum lmb_flags flags) + phys_addr_t max_addr, enum lmb_flags flags) { int ret; long i, rgn; @@ -720,16 +725,18 @@ static phys_addr_t _lmb_alloc_base(phys_size_t size, ulong align, if (lmbsize < size) continue; - if (max_addr == LMB_ALLOC_ANYWHERE) + + if (max_addr == LMB_ALLOC_ANYWHERE) { base = lmb_align_down(lmbbase + lmbsize - size, align); - else if (lmbbase < max_addr) { + } else if (lmbbase < max_addr) { base = lmbbase + lmbsize; if (base < lmbbase) base = -1; base = min(base, max_addr); base = lmb_align_down(base - size, align); - } else + } else { continue; + } while (base && lmbbase <= base) { rgn = lmb_overlaps_region(&lmb.used_mem, base, size); @@ -803,7 +810,7 @@ phys_addr_t lmb_alloc_base_flags(phys_size_t size, ulong align, } static phys_addr_t _lmb_alloc_addr(phys_addr_t base, phys_size_t size, - enum lmb_flags flags) + enum lmb_flags flags) { long rgn; struct lmb_region *lmb_memory = lmb.free_mem.data; -- cgit v1.3.1 From 22db5b213703e7ae17b8b2496393253b3664bdd5 Mon Sep 17 00:00:00 2001 From: Sam Protsenko Date: Tue, 10 Dec 2024 20:25:50 -0600 Subject: lmb: Improve kernel-doc comments Fix warnings from kernel-doc script. Improve and unify overall style of kernel-doc comments in lmb source files. Move all kernel-doc comments for public functions into the header, as recommended in U-Boot documentation [1]: Non-trivial functions should have a comment which describes what they do. If it is an exported function, put the comment in the header file so the API is in one place. If it is a static function, put it in the C file. This also takes care of existing duplication. While at it, do a bit of cosmetic cleanups as well. No functional change. [1] doc/develop/codingstyle.rst Signed-off-by: Sam Protsenko Acked-by: Ilias Apalodimas --- include/lmb.h | 125 ++++++++++++++++++++++++++++++++++------------------------ lib/lmb.c | 55 -------------------------- 2 files changed, 74 insertions(+), 106 deletions(-) (limited to 'lib') diff --git a/include/lmb.h b/include/lmb.h index f221f0cce8f..03d5fac6aa7 100644 --- a/include/lmb.h +++ b/include/lmb.h @@ -1,6 +1,13 @@ /* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Logical memory blocks. + * + * Copyright (C) 2001 Peter Bergner, IBM Corp. + */ + #ifndef _LINUX_LMB_H #define _LINUX_LMB_H + #ifdef __KERNEL__ #include @@ -8,21 +15,15 @@ #include #include -/* - * Logical memory blocks. - * - * Copyright (C) 2001 Peter Bergner, IBM Corp. - */ - -#define LMB_ALLOC_ANYWHERE 0 -#define LMB_ALIST_INITIAL_SIZE 4 +#define LMB_ALLOC_ANYWHERE 0 +#define LMB_ALIST_INITIAL_SIZE 4 /** - * enum lmb_flags - definition of memory region attributes - * @LMB_NONE: no special request - * @LMB_NOMAP: don't add to mmu configuration - * @LMB_NOOVERWRITE: the memory region cannot be overwritten/re-reserved - * @LMB_NONOTIFY: do not notify other modules of changes to this memory region + * enum lmb_flags - Definition of memory region attributes + * @LMB_NONE: No special request + * @LMB_NOMAP: Don't add to MMU configuration + * @LMB_NOOVERWRITE: The memory region cannot be overwritten/re-reserved + * @LMB_NONOTIFY: Do not notify other modules of changes to this memory region */ enum lmb_flags { LMB_NONE = 0, @@ -32,11 +33,10 @@ enum lmb_flags { }; /** - * struct lmb_region - Description of one region. - * - * @base: Base address of the region. - * @size: Size of the region - * @flags: memory region attributes + * struct lmb_region - Description of one region + * @base: Base address of the region + * @size: Size of the region + * @flags: Memory region attributes */ struct lmb_region { phys_addr_t base; @@ -46,10 +46,9 @@ struct lmb_region { /** * struct lmb - The LMB structure - * - * @free_mem: List of free memory regions - * @used_mem: List of used/reserved memory regions - * @test: Is structure being used for LMB tests + * @free_mem: List of free memory regions + * @used_mem: List of used/reserved memory regions + * @test: Is structure being used for LMB tests */ struct lmb { struct alist free_mem; @@ -58,51 +57,77 @@ struct lmb { }; /** - * lmb_init() - Initialise the LMB module + * lmb_init() - Initialise the LMB module. + * + * Return: 0 on success, negative error code on failure. * * Initialise the LMB lists needed for keeping the memory map. There - * are two lists, in form of alloced list data structure. One for the + * are two lists, in form of allocated list data structure. One for the * available memory, and one for the used memory. Initialise the two * lists as part of board init. Add memory to the available memory * list and reserve common areas by adding them to the used memory * list. - * - * Return: 0 on success, -ve on error */ int lmb_init(void); /** - * lmb_add_memory() - Add memory range for LMB allocations + * lmb_add_memory() - Add memory range for LMB allocations. * * Add the entire available memory range to the pool of memory that * can be used by the LMB module for allocations. - * - * Return: None */ void lmb_add_memory(void); long lmb_add(phys_addr_t base, phys_size_t size); -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 a memory region (with no special flags) + * @base: Base address of the memory region + * @size: Size of the memory region * - * @base: base address of the memory region - * @size: size of the memory region - * @flags: flags for the memory region - * Return: 0 if OK, > 0 for coalesced region or a negative error code. + * 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 + * @base: Base address of the memory region + * @size: Size of the memory region + * @flags: Flags for the memory region + * + * Return: + * * %0 - Added successfully, or it's already added (only if LMB_NONE) + * * %-EEXIST - The region is already added, and flags != LMB_NONE + * * %-1 - Failure */ long lmb_reserve_flags(phys_addr_t base, phys_size_t size, enum lmb_flags 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); phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size); phys_size_t lmb_get_free_size(phys_addr_t addr); +/** + * lmb_alloc_base_flags() - Allocate specified memory region with specified + * attributes + * @size: Size of the region requested + * @align: Alignment of the memory region requested + * @max_addr: Maximum address of the requested region + * @flags: Memory region attributes to be set + * + * Allocate a region of memory with the attributes specified through the + * parameter. The max_addr parameter is used to specify the maximum address + * below which the requested region should be allocated. + * + * Return: Base address on success, 0 on error. + */ phys_addr_t lmb_alloc_base_flags(phys_size_t size, ulong align, phys_addr_t max_addr, uint flags); /** - * lmb_alloc_addr_flags() - Allocate specified memory address with specified attributes + * lmb_alloc_addr_flags() - Allocate specified memory address with specified + * attributes * @base: Base Address requested * @size: Size of the region requested * @flags: Memory region attributes to be set @@ -111,20 +136,21 @@ phys_addr_t lmb_alloc_base_flags(phys_size_t size, ulong align, * parameter. The base parameter is used to specify the base address * of the requested region. * - * Return: base address on success, 0 on error + * Return: Base address on success, 0 on error. */ phys_addr_t lmb_alloc_addr_flags(phys_addr_t base, phys_size_t size, uint flags); /** - * lmb_is_reserved_flags() - test if address is in reserved region with flag bits set + * lmb_is_reserved_flags() - Test if address is in reserved region with flag + * bits set + * @addr: Address to be tested + * @flags: Bitmap with bits to be tested * * The function checks if a reserved region comprising @addr exists which has * all flag bits set which are set in @flags. * - * @addr: address to be tested - * @flags: bitmap with bits to be tested - * Return: 1 if matching reservation exists, 0 otherwise + * Return: 1 if matching reservation exists, 0 otherwise. */ int lmb_is_reserved_flags(phys_addr_t addr, int flags); @@ -134,9 +160,7 @@ int lmb_is_reserved_flags(phys_addr_t addr, int flags); * @size: Size of the region to be freed * @flags: Memory region attributes * - * Free up a region of memory. - * - * Return: 0 if successful, -1 on failure + * Return: 0 on success, negative error code on failure. */ long lmb_free_flags(phys_addr_t base, phys_size_t size, uint flags); @@ -160,7 +184,7 @@ static inline int lmb_read_check(phys_addr_t addr, phys_size_t len) * io_lmb_setup() - Initialize LMB struct * @io_lmb: IO LMB to initialize * - * Returns: 0 on success, negative error code on failure + * Return: 0 on success, negative error code on failure. */ int io_lmb_setup(struct lmb *io_lmb); @@ -178,12 +202,13 @@ void io_lmb_teardown(struct lmb *io_lmb); * * Add the IOVA space [base, base + size] to be managed by io_lmb. * - * Returns: 0 if the region addition was successful, -1 on failure + * Return: 0 on success, negative error code on failure. */ long io_lmb_add(struct lmb *io_lmb, phys_addr_t base, phys_size_t size); /** - * io_lmb_alloc() - Allocate specified IO memory address with specified alignment + * io_lmb_alloc() - Allocate specified IO memory address with specified + * alignment * @io_lmb: LMB to alloc from * @size: Size of the region requested * @align: Required address and size alignment @@ -191,7 +216,7 @@ long io_lmb_add(struct lmb *io_lmb, phys_addr_t base, phys_size_t size); * Allocate a region of IO memory. The base parameter is used to specify the * base address of the requested region. * - * Return: base IO address on success, 0 on error + * Return: Base IO address on success, 0 on error. */ phys_addr_t io_lmb_alloc(struct lmb *io_lmb, phys_size_t size, ulong align); @@ -201,9 +226,7 @@ phys_addr_t io_lmb_alloc(struct lmb *io_lmb, phys_size_t size, ulong align); * @base: Base Address of region to be freed * @size: Size of the region to be freed * - * Free up a region of IOVA space. - * - * Return: 0 if successful, -1 on failure + * Return: 0 on success, negative error code on failure. */ long io_lmb_free(struct lmb *io_lmb, phys_addr_t base, phys_size_t size); diff --git a/lib/lmb.c b/lib/lmb.c index 40f03151929..f9880a8dc62 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -601,14 +601,6 @@ static __maybe_unused void lmb_reserve_common_spl(void) } } -/** - * lmb_add_memory() - Add memory range for LMB allocations - * - * Add the entire available memory range to the pool of memory that - * can be used by the LMB module for allocations. - * - * Return: None - */ void lmb_add_memory(void) { int i; @@ -665,16 +657,6 @@ long lmb_add(phys_addr_t base, phys_size_t size) return lmb_map_update_notify(base, size, MAP_OP_ADD, LMB_NONE); } -/** - * lmb_free_flags() - Free up a region of memory - * @base: Base Address of region to be freed - * @size: Size of the region to be freed - * @flags: Memory region attributes - * - * Free up a region of memory. - * - * Return: 0 if successful, negative error code on failure - */ long lmb_free_flags(phys_addr_t base, phys_size_t size, uint flags) { @@ -782,19 +764,6 @@ phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr) return alloc; } -/** - * lmb_alloc_base_flags() - Allocate specified memory region with specified attributes - * @size: Size of the region requested - * @align: Alignment of the memory region requested - * @max_addr: Maximum address of the requested region - * @flags: Memory region attributes to be set - * - * Allocate a region of memory with the attributes specified through the - * parameter. The max_addr parameter is used to specify the maximum address - * below which the requested region should be allocated. - * - * Return: base address on success, 0 on error - */ phys_addr_t lmb_alloc_base_flags(phys_size_t size, ulong align, phys_addr_t max_addr, uint flags) { @@ -843,18 +812,6 @@ phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size) return _lmb_alloc_addr(base, size, LMB_NONE); } -/** - * lmb_alloc_addr_flags() - Allocate specified memory address with specified attributes - * @base: Base Address requested - * @size: Size of the region requested - * @flags: Memory region attributes to be set - * - * Allocate a region of memory with the attributes specified through the - * parameter. The base parameter is used to specify the base address - * of the requested region. - * - * Return: base address on success, 0 on error - */ phys_addr_t lmb_alloc_addr_flags(phys_addr_t base, phys_size_t size, uint flags) { @@ -927,18 +884,6 @@ static int lmb_setup(bool test) return 0; } -/** - * lmb_init() - Initialise the LMB module - * - * Initialise the LMB lists needed for keeping the memory map. There - * are two lists, in form of alloced list data structure. One for the - * available memory, and one for the used memory. Initialise the two - * lists as part of board init. Add memory to the available memory - * list and reserve common areas by adding them to the used memory - * list. - * - * Return: 0 on success, -ve on error - */ int lmb_init(void) { int ret; -- cgit v1.3.1 From 6c9f27505a5e20ed538d1dafdf43cf9d18ab8624 Mon Sep 17 00:00:00 2001 From: Ilias Apalodimas Date: Wed, 18 Dec 2024 09:02:30 +0200 Subject: lmb: Remove lmb_align_down() We already have a macro for this. Use it instead of adding yet another variant for alignment. Reviewed-by: Sam Protsenko Tested-by: Sam Protsenko Signed-off-by: Ilias Apalodimas --- lib/lmb.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'lib') diff --git a/lib/lmb.c b/lib/lmb.c index f9880a8dc62..b9c26cb02e1 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -342,11 +342,6 @@ static long lmb_overlaps_region(struct alist *lmb_rgn_lst, phys_addr_t base, return (i < lmb_rgn_lst->count) ? i : -1; } -static phys_addr_t lmb_align_down(phys_addr_t addr, phys_size_t size) -{ - return addr & ~(size - 1); -} - /* * IOVA LMB memory maps using lmb pointers instead of the global LMB memory map. */ @@ -400,7 +395,7 @@ phys_addr_t io_lmb_alloc(struct lmb *io_lmb, phys_size_t size, ulong align) if (lmbsize < size) continue; - base = lmb_align_down(lmbbase + lmbsize - size, align); + base = ALIGN_DOWN(lmbbase + lmbsize - size, align); while (base && lmbbase <= base) { rgn = lmb_overlaps_region(&io_lmb->used_mem, base, size); @@ -416,7 +411,7 @@ phys_addr_t io_lmb_alloc(struct lmb *io_lmb, phys_size_t size, ulong align) res_base = lmb_used[rgn].base; if (res_base < size) break; - base = lmb_align_down(res_base - size, align); + base = ALIGN_DOWN(res_base - size, align); } } return 0; @@ -709,13 +704,13 @@ static phys_addr_t _lmb_alloc_base(phys_size_t size, ulong align, continue; if (max_addr == LMB_ALLOC_ANYWHERE) { - base = lmb_align_down(lmbbase + lmbsize - size, align); + base = ALIGN_DOWN(lmbbase + lmbsize - size, align); } else if (lmbbase < max_addr) { base = lmbbase + lmbsize; if (base < lmbbase) base = -1; base = min(base, max_addr); - base = lmb_align_down(base - size, align); + base = ALIGN_DOWN(base - size, align); } else { continue; } @@ -740,7 +735,7 @@ static phys_addr_t _lmb_alloc_base(phys_size_t size, ulong align, res_base = lmb_used[rgn].base; if (res_base < size) break; - base = lmb_align_down(res_base - size, align); + base = ALIGN_DOWN(res_base - size, align); } } return 0; -- cgit v1.3.1 From 3d56c06551d7a54870cfdf8c639b3ff35521b87f Mon Sep 17 00:00:00 2001 From: Ilias Apalodimas Date: Wed, 18 Dec 2024 09:02:31 +0200 Subject: lmb: Move enum lmb_flags to a u32 LMB flags is not an enum anymore. It's currently used as a bitmask in various places of our code. So make it a u32 which is more appropriate when dealing with masks. Reviewed-by: Sam Protsenko Tested-by: Sam Protsenko Signed-off-by: Ilias Apalodimas --- boot/image-fdt.c | 4 ++-- include/lmb.h | 27 +++++++++++++-------------- lib/lmb.c | 18 +++++++++--------- test/cmd/bdinfo.c | 2 +- 4 files changed, 25 insertions(+), 26 deletions(-) (limited to 'lib') diff --git a/boot/image-fdt.c b/boot/image-fdt.c index 73c43c30684..cda7c3aa9e3 100644 --- a/boot/image-fdt.c +++ b/boot/image-fdt.c @@ -68,7 +68,7 @@ static const struct legacy_img_hdr *image_get_fdt(ulong fdt_addr) } #endif -static void boot_fdt_reserve_region(u64 addr, u64 size, enum lmb_flags flags) +static void boot_fdt_reserve_region(u64 addr, u64 size, u32 flags) { long ret; @@ -100,7 +100,7 @@ void boot_fdt_add_mem_rsv_regions(void *fdt_blob) int i, total, ret; int nodeoffset, subnode; struct fdt_resource res; - enum lmb_flags flags; + u32 flags; if (fdt_check_header(fdt_blob) != 0) return; diff --git a/include/lmb.h b/include/lmb.h index 03d5fac6aa7..3b911d5d839 100644 --- a/include/lmb.h +++ b/include/lmb.h @@ -19,18 +19,17 @@ #define LMB_ALIST_INITIAL_SIZE 4 /** - * enum lmb_flags - Definition of memory region attributes - * @LMB_NONE: No special request - * @LMB_NOMAP: Don't add to MMU configuration - * @LMB_NOOVERWRITE: The memory region cannot be overwritten/re-reserved - * @LMB_NONOTIFY: Do not notify other modules of changes to this memory region - */ -enum lmb_flags { - LMB_NONE = 0, - LMB_NOMAP = BIT(1), - LMB_NOOVERWRITE = BIT(2), - LMB_NONOTIFY = BIT(3), -}; + * DOC: Memory region attribute flags. + * + * %LMB_NONE: No special request + * %LMB_NOMAP: Don't add to MMU configuration + * %LMB_NOOVERWRITE: The memory region cannot be overwritten/re-reserved + * %LMB_NONOTIFY: Do not notify other modules of changes to this memory region + */ +#define LMB_NONE 0 +#define LMB_NOMAP BIT(0) +#define LMB_NOOVERWRITE BIT(1) +#define LMB_NONOTIFY BIT(2) /** * struct lmb_region - Description of one region @@ -41,7 +40,7 @@ enum lmb_flags { struct lmb_region { phys_addr_t base; phys_size_t size; - enum lmb_flags flags; + u32 flags; }; /** @@ -101,7 +100,7 @@ long lmb_reserve(phys_addr_t base, phys_size_t size); * * %-1 - Failure */ long lmb_reserve_flags(phys_addr_t base, phys_size_t size, - enum lmb_flags flags); + 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 b9c26cb02e1..edecdb8e9cb 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -188,7 +188,7 @@ static long lmb_resize_regions(struct alist *lmb_rgn_lst, * * %-1 - Failure */ static long lmb_add_region_flags(struct alist *lmb_rgn_lst, phys_addr_t base, - phys_size_t size, enum lmb_flags flags) + phys_size_t size, u32 flags) { unsigned long coalesced = 0; long ret, i; @@ -201,7 +201,7 @@ static long lmb_add_region_flags(struct alist *lmb_rgn_lst, phys_addr_t base, for (i = 0; i < lmb_rgn_lst->count; i++) { phys_addr_t rgnbase = rgn[i].base; phys_size_t rgnsize = rgn[i].size; - enum lmb_flags rgnflags = rgn[i].flags; + u32 rgnflags = rgn[i].flags; ret = lmb_addrs_adjacent(base, size, rgnbase, rgnsize); if (ret > 0) { @@ -430,14 +430,14 @@ long io_lmb_free(struct lmb *io_lmb, phys_addr_t base, phys_size_t size) static struct lmb lmb; -static bool lmb_should_notify(enum lmb_flags flags) +static bool lmb_should_notify(u32 flags) { return !lmb.test && !(flags & LMB_NONOTIFY) && CONFIG_IS_ENABLED(EFI_LOADER); } static int lmb_map_update_notify(phys_addr_t addr, phys_size_t size, u8 op, - enum lmb_flags flags) + u32 flags) { u64 efi_addr; u64 pages; @@ -470,7 +470,7 @@ static int lmb_map_update_notify(phys_addr_t addr, phys_size_t size, u8 op, return 0; } -static void lmb_print_region_flags(enum lmb_flags flags) +static void lmb_print_region_flags(u32 flags) { const char * const flag_str[] = { "none", "no-map", "no-overwrite", "no-notify" }; @@ -495,7 +495,7 @@ static void lmb_dump_region(struct alist *lmb_rgn_lst, char *name) { struct lmb_region *rgn = lmb_rgn_lst->data; unsigned long long base, size, end; - enum lmb_flags flags; + u32 flags; int i; printf(" %s.count = %#x\n", name, lmb_rgn_lst->count); @@ -669,7 +669,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, enum lmb_flags flags) +long lmb_reserve_flags(phys_addr_t base, phys_size_t size, u32 flags) { long ret = 0; struct alist *lmb_rgn_lst = &lmb.used_mem; @@ -687,7 +687,7 @@ long lmb_reserve(phys_addr_t base, phys_size_t size) } static phys_addr_t _lmb_alloc_base(phys_size_t size, ulong align, - phys_addr_t max_addr, enum lmb_flags flags) + phys_addr_t max_addr, u32 flags) { int ret; long i, rgn; @@ -774,7 +774,7 @@ phys_addr_t lmb_alloc_base_flags(phys_size_t size, ulong align, } static phys_addr_t _lmb_alloc_addr(phys_addr_t base, phys_size_t size, - enum lmb_flags flags) + u32 flags) { long rgn; struct lmb_region *lmb_memory = lmb.free_mem.data; diff --git a/test/cmd/bdinfo.c b/test/cmd/bdinfo.c index bb419ab2394..014391b38ac 100644 --- a/test/cmd/bdinfo.c +++ b/test/cmd/bdinfo.c @@ -104,7 +104,7 @@ static int lmb_test_dump_region(struct unit_test_state *uts, { struct lmb_region *rgn = lmb_rgn_lst->data; unsigned long long base, size, end; - enum lmb_flags flags; + u32 flags; int i; ut_assert_nextline(" %s.count = %#x", name, lmb_rgn_lst->count); -- 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 'lib') 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 400c34db8957bbe49b15dcc0310697f829c63e01 Mon Sep 17 00:00:00 2001 From: Ilias Apalodimas Date: Wed, 18 Dec 2024 09:02:33 +0200 Subject: lmb: Rename free_mem to available_mem free_mem is a misnomer. We never update it with the free memory for LMB. Instead, it describes all available memory and is checked against used_mem to decide whether an area is free or not. So let's rename this field to better match its usage. Reviewed-by: Sam Protsenko Tested-by: Sam Protsenko Signed-off-by: Ilias Apalodimas --- include/lmb.h | 4 ++-- lib/lmb.c | 34 +++++++++++++++++----------------- test/cmd/bdinfo.c | 2 +- test/lib/lmb.c | 2 +- 4 files changed, 21 insertions(+), 21 deletions(-) (limited to 'lib') diff --git a/include/lmb.h b/include/lmb.h index 3abe24deb56..18030c610ab 100644 --- a/include/lmb.h +++ b/include/lmb.h @@ -45,12 +45,12 @@ struct lmb_region { /** * struct lmb - The LMB structure - * @free_mem: List of free memory regions + * @available_mem: List of memory available to LMB * @used_mem: List of used/reserved memory regions * @test: Is structure being used for LMB tests */ struct lmb { - struct alist free_mem; + struct alist available_mem; struct alist used_mem; bool test; }; diff --git a/lib/lmb.c b/lib/lmb.c index fd0e91981ad..da960e422ad 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -350,7 +350,7 @@ int io_lmb_setup(struct lmb *io_lmb) { int ret; - ret = alist_init(&io_lmb->free_mem, sizeof(struct lmb_region), + ret = alist_init(&io_lmb->available_mem, sizeof(struct lmb_region), (uint)LMB_ALIST_INITIAL_SIZE); if (!ret) { log_debug("Unable to initialise the list for LMB free IOVA\n"); @@ -371,13 +371,13 @@ int io_lmb_setup(struct lmb *io_lmb) void io_lmb_teardown(struct lmb *io_lmb) { - alist_uninit(&io_lmb->free_mem); + alist_uninit(&io_lmb->available_mem); alist_uninit(&io_lmb->used_mem); } long io_lmb_add(struct lmb *io_lmb, phys_addr_t base, phys_size_t size) { - return lmb_add_region_flags(&io_lmb->free_mem, base, size, LMB_NONE); + return lmb_add_region_flags(&io_lmb->available_mem, base, size, LMB_NONE); } /* derived and simplified from _lmb_alloc_base() */ @@ -387,9 +387,9 @@ phys_addr_t io_lmb_alloc(struct lmb *io_lmb, phys_size_t size, ulong align) phys_addr_t base = 0; phys_addr_t res_base; struct lmb_region *lmb_used = io_lmb->used_mem.data; - struct lmb_region *lmb_memory = io_lmb->free_mem.data; + struct lmb_region *lmb_memory = io_lmb->available_mem.data; - for (i = io_lmb->free_mem.count - 1; i >= 0; i--) { + for (i = io_lmb->available_mem.count - 1; i >= 0; i--) { phys_addr_t lmbbase = lmb_memory[i].base; phys_size_t lmbsize = lmb_memory[i].size; @@ -515,7 +515,7 @@ static void lmb_dump_region(struct alist *lmb_rgn_lst, char *name) void lmb_dump_all_force(void) { printf("lmb_dump_all:\n"); - lmb_dump_region(&lmb.free_mem, "memory"); + lmb_dump_region(&lmb.available_mem, "memory"); lmb_dump_region(&lmb.used_mem, "reserved"); } @@ -642,7 +642,7 @@ static long lmb_add_region(struct alist *lmb_rgn_lst, phys_addr_t base, long lmb_add(phys_addr_t base, phys_size_t size) { long ret; - struct alist *lmb_rgn_lst = &lmb.free_mem; + struct alist *lmb_rgn_lst = &lmb.available_mem; ret = lmb_add_region(lmb_rgn_lst, base, size); if (ret) @@ -688,9 +688,9 @@ static phys_addr_t _lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t base = 0; phys_addr_t res_base; struct lmb_region *lmb_used = lmb.used_mem.data; - struct lmb_region *lmb_memory = lmb.free_mem.data; + struct lmb_region *lmb_memory = lmb.available_mem.data; - for (i = lmb.free_mem.count - 1; i >= 0; i--) { + for (i = lmb.available_mem.count - 1; i >= 0; i--) { phys_addr_t lmbbase = lmb_memory[i].base; phys_size_t lmbsize = lmb_memory[i].size; @@ -771,10 +771,10 @@ static phys_addr_t _lmb_alloc_addr(phys_addr_t base, phys_size_t size, u32 flags) { long rgn; - struct lmb_region *lmb_memory = lmb.free_mem.data; + struct lmb_region *lmb_memory = lmb.available_mem.data; /* Check if the requested address is in one of the memory regions */ - rgn = lmb_overlaps_region(&lmb.free_mem, base, size); + rgn = lmb_overlaps_region(&lmb.available_mem, base, size); if (rgn >= 0) { /* * Check if the requested end address is in the same memory @@ -813,10 +813,10 @@ phys_size_t lmb_get_free_size(phys_addr_t addr) int i; long rgn; struct lmb_region *lmb_used = lmb.used_mem.data; - struct lmb_region *lmb_memory = lmb.free_mem.data; + struct lmb_region *lmb_memory = lmb.available_mem.data; /* check if the requested address is in the memory regions */ - rgn = lmb_overlaps_region(&lmb.free_mem, addr, 1); + rgn = lmb_overlaps_region(&lmb.available_mem, addr, 1); if (rgn >= 0) { for (i = 0; i < lmb.used_mem.count; i++) { if (addr < lmb_used[i].base) { @@ -830,8 +830,8 @@ phys_size_t lmb_get_free_size(phys_addr_t addr) } } /* if we come here: no reserved ranges above requested addr */ - return lmb_memory[lmb.free_mem.count - 1].base + - lmb_memory[lmb.free_mem.count - 1].size - addr; + return lmb_memory[lmb.available_mem.count - 1].base + + lmb_memory[lmb.available_mem.count - 1].size - addr; } return 0; } @@ -854,7 +854,7 @@ static int lmb_setup(bool test) { bool ret; - ret = alist_init(&lmb.free_mem, sizeof(struct lmb_region), + ret = alist_init(&lmb.available_mem, sizeof(struct lmb_region), (uint)LMB_ALIST_INITIAL_SIZE); if (!ret) { log_debug("Unable to initialise the list for LMB free memory\n"); @@ -914,7 +914,7 @@ int lmb_push(struct lmb *store) void lmb_pop(struct lmb *store) { - alist_uninit(&lmb.free_mem); + alist_uninit(&lmb.available_mem); alist_uninit(&lmb.used_mem); lmb = *store; } diff --git a/test/cmd/bdinfo.c b/test/cmd/bdinfo.c index 014391b38ac..76429485708 100644 --- a/test/cmd/bdinfo.c +++ b/test/cmd/bdinfo.c @@ -131,7 +131,7 @@ static int lmb_test_dump_all(struct unit_test_state *uts) struct lmb *lmb = lmb_get(); ut_assert_nextline("lmb_dump_all:"); - ut_assertok(lmb_test_dump_region(uts, &lmb->free_mem, "memory")); + ut_assertok(lmb_test_dump_region(uts, &lmb->available_mem, "memory")); ut_assertok(lmb_test_dump_region(uts, &lmb->used_mem, "reserved")); return 0; diff --git a/test/lib/lmb.c b/test/lib/lmb.c index 3c3e862ffa0..6e870274fed 100644 --- a/test/lib/lmb.c +++ b/test/lib/lmb.c @@ -65,7 +65,7 @@ static int setup_lmb_test(struct unit_test_state *uts, struct lmb *store, ut_assertok(lmb_push(store)); lmb = lmb_get(); - *mem_lstp = &lmb->free_mem; + *mem_lstp = &lmb->available_mem; *used_lstp = &lmb->used_mem; return 0; -- cgit v1.3.1 From c207d6e3e31fd07885fa341209fcf90740e9f7d6 Mon Sep 17 00:00:00 2001 From: Ilias Apalodimas Date: Wed, 18 Dec 2024 09:02:34 +0200 Subject: lmb: Remove lmb_add_region() There's no point defining a function that's called only once just to avoid passing the flags. Remove the wrapper and just call lmb_add_region_flags(). Acked-by: Sughosh Ganu Reviewed-by: Heinrich Schuchardt Reviewed-by: Sam Protsenko Tested-by: Sam Protsenko Signed-off-by: Ilias Apalodimas --- lib/lmb.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'lib') diff --git a/lib/lmb.c b/lib/lmb.c index da960e422ad..659581f13f2 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -632,19 +632,13 @@ void lmb_add_memory(void) } } -static long lmb_add_region(struct alist *lmb_rgn_lst, phys_addr_t base, - phys_size_t size) -{ - return lmb_add_region_flags(lmb_rgn_lst, base, size, LMB_NONE); -} - /* This routine may be called with relocation disabled. */ long lmb_add(phys_addr_t base, phys_size_t size) { long ret; struct alist *lmb_rgn_lst = &lmb.available_mem; - ret = lmb_add_region(lmb_rgn_lst, base, size); + ret = lmb_add_region_flags(lmb_rgn_lst, base, size, LMB_NONE); if (ret) return ret; -- cgit v1.3.1 From 15e0c5e390ffac7682193b7e1a615898b569deb1 Mon Sep 17 00:00:00 2001 From: Ilias Apalodimas Date: Wed, 18 Dec 2024 09:02:35 +0200 Subject: lmb: Remove lmb_alloc_addr_flags() lmb_alloc_addr() is just calling lmb_alloc_addr_flags() with LMB_NONE There's not much we gain from this abstraction, so let's remove the latter, add a flags argument to lmb_alloc_addr() and make the code a bit easier to follow. Reviewed-by: Sam Protsenko Tested-by: Sam Protsenko Signed-off-by: Ilias Apalodimas --- fs/fs.c | 2 +- include/lmb.h | 10 ++++------ lib/efi_loader/efi_memory.c | 2 +- lib/lmb.c | 15 ++------------- test/lib/lmb.c | 34 +++++++++++++++++----------------- 5 files changed, 25 insertions(+), 38 deletions(-) (limited to 'lib') diff --git a/fs/fs.c b/fs/fs.c index 21a23efd932..99ddcc5e37b 100644 --- a/fs/fs.c +++ b/fs/fs.c @@ -554,7 +554,7 @@ static int fs_read_lmb_check(const char *filename, ulong addr, loff_t offset, lmb_dump_all(); - if (lmb_alloc_addr(addr, read_len) == addr) + if (lmb_alloc_addr(addr, read_len, LMB_NONE) == addr) return 0; log_err("** Reading file would overwrite reserved memory **\n"); diff --git a/include/lmb.h b/include/lmb.h index 18030c610ab..e38af036a0d 100644 --- a/include/lmb.h +++ b/include/lmb.h @@ -94,7 +94,6 @@ 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); -phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size); phys_size_t lmb_get_free_size(phys_addr_t addr); /** @@ -115,8 +114,8 @@ phys_addr_t lmb_alloc_base_flags(phys_size_t size, ulong align, phys_addr_t max_addr, uint flags); /** - * lmb_alloc_addr_flags() - Allocate specified memory address with specified - * attributes + * lmb_alloc_addr() - Allocate specified memory address with specified attributes + * * @base: Base Address requested * @size: Size of the region requested * @flags: Memory region attributes to be set @@ -127,8 +126,7 @@ phys_addr_t lmb_alloc_base_flags(phys_size_t size, ulong align, * * Return: Base address on success, 0 on error. */ -phys_addr_t lmb_alloc_addr_flags(phys_addr_t base, phys_size_t size, - uint flags); +phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size, uint flags); /** * lmb_is_reserved_flags() - Test if address is in reserved region with flag @@ -166,7 +164,7 @@ void lmb_pop(struct lmb *store); static inline int lmb_read_check(phys_addr_t addr, phys_size_t len) { - return lmb_alloc_addr(addr, len) == addr ? 0 : -1; + return lmb_alloc_addr(addr, len, LMB_NONE) == addr ? 0 : -1; } /** diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c index edd7da7d8c6..34e2b9e18ef 100644 --- a/lib/efi_loader/efi_memory.c +++ b/lib/efi_loader/efi_memory.c @@ -490,7 +490,7 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type, return EFI_NOT_FOUND; addr = map_to_sysmem((void *)(uintptr_t)*memory); - addr = (u64)lmb_alloc_addr_flags(addr, len, flags); + addr = (u64)lmb_alloc_addr(addr, len, flags); if (!addr) return EFI_NOT_FOUND; break; diff --git a/lib/lmb.c b/lib/lmb.c index 659581f13f2..ffad7ec12eb 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -761,8 +761,7 @@ phys_addr_t lmb_alloc_base_flags(phys_size_t size, ulong align, return alloc; } -static phys_addr_t _lmb_alloc_addr(phys_addr_t base, phys_size_t size, - u32 flags) +static phys_addr_t _lmb_alloc_addr(phys_addr_t base, phys_size_t size, u32 flags) { long rgn; struct lmb_region *lmb_memory = lmb.available_mem.data; @@ -786,17 +785,7 @@ static phys_addr_t _lmb_alloc_addr(phys_addr_t base, phys_size_t size, return 0; } -/* - * Try to allocate a specific address range: must be in defined memory but not - * reserved - */ -phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size) -{ - return _lmb_alloc_addr(base, size, LMB_NONE); -} - -phys_addr_t lmb_alloc_addr_flags(phys_addr_t base, phys_size_t size, - uint flags) +phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size, uint flags) { return _lmb_alloc_addr(base, size, flags); } diff --git a/test/lib/lmb.c b/test/lib/lmb.c index 6e870274fed..971614fd831 100644 --- a/test/lib/lmb.c +++ b/test/lib/lmb.c @@ -530,21 +530,21 @@ static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram) ut_asserteq(ret, 0); /* Try to allocate a page twice */ - b = lmb_alloc_addr_flags(alloc_addr_a, 0x1000, LMB_NONE); + b = lmb_alloc_addr(alloc_addr_a, 0x1000, LMB_NONE); ut_asserteq(b, alloc_addr_a); - b = lmb_alloc_addr_flags(alloc_addr_a, 0x1000, LMB_NOOVERWRITE); + b = lmb_alloc_addr(alloc_addr_a, 0x1000, LMB_NOOVERWRITE); ut_asserteq(b, 0); - b = lmb_alloc_addr_flags(alloc_addr_a, 0x1000, LMB_NONE); + b = lmb_alloc_addr(alloc_addr_a, 0x1000, LMB_NONE); ut_asserteq(b, alloc_addr_a); - b = lmb_alloc_addr_flags(alloc_addr_a, 0x2000, LMB_NONE); + b = lmb_alloc_addr(alloc_addr_a, 0x2000, LMB_NONE); ut_asserteq(b, alloc_addr_a); ret = lmb_free(alloc_addr_a, 0x2000); ut_asserteq(ret, 0); - b = lmb_alloc_addr_flags(alloc_addr_a, 0x1000, LMB_NOOVERWRITE); + b = lmb_alloc_addr(alloc_addr_a, 0x1000, LMB_NOOVERWRITE); ut_asserteq(b, alloc_addr_a); - b = lmb_alloc_addr_flags(alloc_addr_a, 0x1000, LMB_NONE); + b = lmb_alloc_addr(alloc_addr_a, 0x1000, LMB_NONE); ut_asserteq(b, 0); - b = lmb_alloc_addr_flags(alloc_addr_a, 0x1000, LMB_NOOVERWRITE); + b = lmb_alloc_addr(alloc_addr_a, 0x1000, LMB_NOOVERWRITE); ut_asserteq(b, 0); ret = lmb_free(alloc_addr_a, 0x1000); ut_asserteq(ret, 0); @@ -560,22 +560,22 @@ static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram) alloc_addr_b, 0x10000, alloc_addr_c, 0x10000); /* allocate blocks */ - a = lmb_alloc_addr(ram, alloc_addr_a - ram); + a = lmb_alloc_addr(ram, alloc_addr_a - ram, LMB_NONE); ut_asserteq(a, ram); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 3, ram, 0x8010000, alloc_addr_b, 0x10000, alloc_addr_c, 0x10000); b = lmb_alloc_addr(alloc_addr_a + 0x10000, - alloc_addr_b - alloc_addr_a - 0x10000); + alloc_addr_b - alloc_addr_a - 0x10000, LMB_NONE); ut_asserteq(b, alloc_addr_a + 0x10000); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 2, ram, 0x10010000, alloc_addr_c, 0x10000, 0, 0); c = lmb_alloc_addr(alloc_addr_b + 0x10000, - alloc_addr_c - alloc_addr_b - 0x10000); + alloc_addr_c - alloc_addr_b - 0x10000, LMB_NONE); ut_asserteq(c, alloc_addr_b + 0x10000); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, ram, 0x18010000, 0, 0, 0, 0); d = lmb_alloc_addr(alloc_addr_c + 0x10000, - ram_end - alloc_addr_c - 0x10000); + ram_end - alloc_addr_c - 0x10000, LMB_NONE); ut_asserteq(d, alloc_addr_c + 0x10000); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, ram, ram_size, 0, 0, 0, 0); @@ -591,7 +591,7 @@ static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram) /* allocate at 3 points in free range */ - d = lmb_alloc_addr(ram_end - 4, 4); + d = lmb_alloc_addr(ram_end - 4, 4, LMB_NONE); ut_asserteq(d, ram_end - 4); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 2, ram, 0x18010000, d, 4, 0, 0); @@ -600,7 +600,7 @@ static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram) ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, ram, 0x18010000, 0, 0, 0, 0); - d = lmb_alloc_addr(ram_end - 128, 4); + d = lmb_alloc_addr(ram_end - 128, 4, LMB_NONE); ut_asserteq(d, ram_end - 128); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 2, ram, 0x18010000, d, 4, 0, 0); @@ -609,7 +609,7 @@ static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram) ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, ram, 0x18010000, 0, 0, 0, 0); - d = lmb_alloc_addr(alloc_addr_c + 0x10000, 4); + d = lmb_alloc_addr(alloc_addr_c + 0x10000, 4, LMB_NONE); ut_asserteq(d, alloc_addr_c + 0x10000); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, ram, 0x18010004, 0, 0, 0, 0); @@ -624,18 +624,18 @@ static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram) ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, ram + 0x8000000, 0x10010000, 0, 0, 0, 0); - d = lmb_alloc_addr(ram, 4); + d = lmb_alloc_addr(ram, 4, LMB_NONE); ut_asserteq(d, ram); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 2, d, 4, ram + 0x8000000, 0x10010000, 0, 0); /* check that allocating outside memory fails */ if (ram_end != 0) { - ret = lmb_alloc_addr(ram_end, 1); + ret = lmb_alloc_addr(ram_end, 1, LMB_NONE); ut_asserteq(ret, 0); } if (ram != 0) { - ret = lmb_alloc_addr(ram - 1, 1); + ret = lmb_alloc_addr(ram - 1, 1, LMB_NONE); ut_asserteq(ret, 0); } -- cgit v1.3.1 From 3075708017dc2d1b735ed7c9556da6ff5070f14f Mon Sep 17 00:00:00 2001 From: Ilias Apalodimas Date: Wed, 18 Dec 2024 09:02:36 +0200 Subject: lmb: Remove lmb_alloc_base_flags() lmb_alloc_base() is just calling lmb_alloc_base_flags() with LMB_NONE. There's not much we gain from this abstraction, so let's remove the former add the flags argument to lmb_alloc_base() and make the code a bit easier to follow. Reviewed-by: Sam Protsenko Tested-by: Sam Protsenko Signed-off-by: Ilias Apalodimas --- boot/image-board.c | 18 +++++++++++------- boot/image-fdt.c | 5 +++-- include/lmb.h | 7 +++---- lib/efi_loader/efi_memory.c | 4 ++-- lib/lmb.c | 19 +++---------------- test/lib/lmb.c | 8 ++++---- 6 files changed, 26 insertions(+), 35 deletions(-) (limited to 'lib') diff --git a/boot/image-board.c b/boot/image-board.c index 070ada00718..4e86a9a2271 100644 --- a/boot/image-board.c +++ b/boot/image-board.c @@ -565,9 +565,11 @@ int boot_ramdisk_high(ulong rd_data, ulong rd_len, ulong *initrd_start, lmb_reserve(rd_data, rd_len, LMB_NONE); } else { if (initrd_high) - *initrd_start = (ulong)lmb_alloc_base(rd_len, - 0x1000, - initrd_high); + *initrd_start = + (ulong)lmb_alloc_base(rd_len, + 0x1000, + initrd_high, + LMB_NONE); else *initrd_start = (ulong)lmb_alloc(rd_len, 0x1000); @@ -839,7 +841,8 @@ int boot_get_cmdline(ulong *cmd_start, ulong *cmd_end) barg = IF_ENABLED_INT(CONFIG_SYS_BOOT_GET_CMDLINE, CONFIG_SYS_BARGSIZE); cmdline = (char *)(ulong)lmb_alloc_base(barg, 0xf, - env_get_bootm_mapsize() + env_get_bootm_low()); + env_get_bootm_mapsize() + env_get_bootm_low(), + LMB_NONE); if (!cmdline) return -1; @@ -872,9 +875,10 @@ int boot_get_cmdline(ulong *cmd_start, ulong *cmd_end) int boot_get_kbd(struct bd_info **kbd) { *kbd = (struct bd_info *)(ulong)lmb_alloc_base(sizeof(struct bd_info), - 0xf, - env_get_bootm_mapsize() + - env_get_bootm_low()); + 0xf, + env_get_bootm_mapsize() + + env_get_bootm_low(), + LMB_NONE); if (!*kbd) return -1; diff --git a/boot/image-fdt.c b/boot/image-fdt.c index d717f669072..9d1598b1a93 100644 --- a/boot/image-fdt.c +++ b/boot/image-fdt.c @@ -187,7 +187,8 @@ int boot_relocate_fdt(char **of_flat_tree, ulong *of_size) 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); + addr = lmb_alloc_base(of_len, 0x1000, desired_addr, + LMB_NONE); of_start = map_sysmem(addr, of_len); if (of_start == NULL) { puts("Failed using fdt_high value for Device Tree"); @@ -216,7 +217,7 @@ int boot_relocate_fdt(char **of_flat_tree, ulong *of_size) * for LMB allocation. */ usable = min(start + size, low + mapsize); - addr = lmb_alloc_base(of_len, 0x1000, usable); + addr = lmb_alloc_base(of_len, 0x1000, usable, LMB_NONE); of_start = map_sysmem(addr, of_len); /* Allocation succeeded, use this block. */ if (of_start != NULL) diff --git a/include/lmb.h b/include/lmb.h index e38af036a0d..a0e666a1f7c 100644 --- a/include/lmb.h +++ b/include/lmb.h @@ -93,11 +93,10 @@ long lmb_add(phys_addr_t base, phys_size_t size); 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); phys_size_t lmb_get_free_size(phys_addr_t addr); /** - * lmb_alloc_base_flags() - Allocate specified memory region with specified + * lmb_alloc_base() - Allocate specified memory region with specified * attributes * @size: Size of the region requested * @align: Alignment of the memory region requested @@ -110,8 +109,8 @@ phys_size_t lmb_get_free_size(phys_addr_t addr); * * Return: Base address on success, 0 on error. */ -phys_addr_t lmb_alloc_base_flags(phys_size_t size, ulong align, - phys_addr_t max_addr, uint flags); +phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr, + uint flags); /** * lmb_alloc_addr() - Allocate specified memory address with specified attributes diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c index 34e2b9e18ef..1212772471e 100644 --- a/lib/efi_loader/efi_memory.c +++ b/lib/efi_loader/efi_memory.c @@ -472,7 +472,7 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type, switch (type) { case EFI_ALLOCATE_ANY_PAGES: /* Any page */ - addr = (u64)lmb_alloc_base_flags(len, EFI_PAGE_SIZE, + addr = (u64)lmb_alloc_base(len, EFI_PAGE_SIZE, LMB_ALLOC_ANYWHERE, flags); if (!addr) return EFI_OUT_OF_RESOURCES; @@ -480,7 +480,7 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type, case EFI_ALLOCATE_MAX_ADDRESS: /* Max address */ addr = map_to_sysmem((void *)(uintptr_t)*memory); - addr = (u64)lmb_alloc_base_flags(len, EFI_PAGE_SIZE, addr, + addr = (u64)lmb_alloc_base(len, EFI_PAGE_SIZE, addr, flags); if (!addr) return EFI_OUT_OF_RESOURCES; diff --git a/lib/lmb.c b/lib/lmb.c index ffad7ec12eb..bdaaa634abd 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -731,24 +731,11 @@ static phys_addr_t _lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t lmb_alloc(phys_size_t size, ulong align) { - return lmb_alloc_base(size, align, LMB_ALLOC_ANYWHERE); + return lmb_alloc_base(size, align, LMB_ALLOC_ANYWHERE, LMB_NONE); } -phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr) -{ - phys_addr_t alloc; - - alloc = _lmb_alloc_base(size, align, max_addr, LMB_NONE); - - if (alloc == 0) - printf("ERROR: Failed to allocate 0x%lx bytes below 0x%lx.\n", - (ulong)size, (ulong)max_addr); - - return alloc; -} - -phys_addr_t lmb_alloc_base_flags(phys_size_t size, ulong align, - phys_addr_t max_addr, uint flags) +phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr, + uint flags) { phys_addr_t alloc; diff --git a/test/lib/lmb.c b/test/lib/lmb.c index 971614fd831..fcb5f1af532 100644 --- a/test/lib/lmb.c +++ b/test/lib/lmb.c @@ -128,7 +128,7 @@ static int test_multi_alloc(struct unit_test_state *uts, const phys_addr_t ram, ASSERT_LMB(mem_lst, used_lst, 0, 0, 2, alloc_64k_addr, 0x10000, ram_end - 4, 4, 0, 0); /* alloc below end of reserved region -> below reserved region */ - b = lmb_alloc_base(4, 1, alloc_64k_end); + b = lmb_alloc_base(4, 1, alloc_64k_end, LMB_NONE); ut_asserteq(b, alloc_64k_addr - 4); ASSERT_LMB(mem_lst, used_lst, 0, 0, 2, alloc_64k_addr - 4, 0x10000 + 4, ram_end - 4, 4, 0, 0); @@ -138,7 +138,7 @@ static int test_multi_alloc(struct unit_test_state *uts, const phys_addr_t ram, ut_asserteq(c, ram_end - 8); ASSERT_LMB(mem_lst, used_lst, 0, 0, 2, alloc_64k_addr - 4, 0x10000 + 4, ram_end - 8, 8, 0, 0); - d = lmb_alloc_base(4, 1, alloc_64k_end); + d = lmb_alloc_base(4, 1, alloc_64k_end, LMB_NONE); ut_asserteq(d, alloc_64k_addr - 8); ASSERT_LMB(mem_lst, used_lst, 0, 0, 2, alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 8, 0, 0); @@ -163,7 +163,7 @@ static int test_multi_alloc(struct unit_test_state *uts, const phys_addr_t ram, alloc_64k_addr - 8, 4, alloc_64k_addr, 0x10000, ram_end - 8, 4); /* allocate again to ensure we get the same address */ - b2 = lmb_alloc_base(4, 1, alloc_64k_end); + b2 = lmb_alloc_base(4, 1, alloc_64k_end, LMB_NONE); ut_asserteq(b, b2); ASSERT_LMB(mem_lst, used_lst, 0, 0, 2, alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 4, 0, 0); @@ -363,7 +363,7 @@ static int test_noreserved(struct unit_test_state *uts, const phys_addr_t ram, ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 0, 0, 0, 0, 0, 0, 0); /* allocate a block with base*/ - b = lmb_alloc_base(alloc_size, align, ram_end); + b = lmb_alloc_base(alloc_size, align, ram_end, LMB_NONE); ut_assert(a == b); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, ram + ram_size - alloc_size_aligned, -- cgit v1.3.1 From 1a25191bc1381f320a359a5dc9c835dde4658175 Mon Sep 17 00:00:00 2001 From: Ilias Apalodimas Date: Wed, 18 Dec 2024 09:02:37 +0200 Subject: lmb: Rename _lmb_alloc_addr() to lmb_alloc_addr_flags() lmb_alloc_addr_flags() is a wrapper for _lmb_alloc_addr() and it's the only function using it. Rename _lmb_alloc_addr() to lmb_alloc_addr_flags() and remove the wrapper. Reviewed-by: Sam Protsenko Tested-by: Sam Protsenko Signed-off-by: Ilias Apalodimas --- include/lmb.h | 2 +- lib/lmb.c | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) (limited to 'lib') diff --git a/include/lmb.h b/include/lmb.h index a0e666a1f7c..d9d7435a431 100644 --- a/include/lmb.h +++ b/include/lmb.h @@ -125,7 +125,7 @@ phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr, * * Return: Base address on success, 0 on error. */ -phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size, uint flags); +phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size, u32 flags); /** * lmb_is_reserved_flags() - Test if address is in reserved region with flag diff --git a/lib/lmb.c b/lib/lmb.c index bdaaa634abd..7ca44591e1d 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -748,7 +748,7 @@ phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr, return alloc; } -static phys_addr_t _lmb_alloc_addr(phys_addr_t base, phys_size_t size, u32 flags) +phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size, u32 flags) { long rgn; struct lmb_region *lmb_memory = lmb.available_mem.data; @@ -772,11 +772,6 @@ static phys_addr_t _lmb_alloc_addr(phys_addr_t base, phys_size_t size, u32 flags return 0; } -phys_addr_t lmb_alloc_addr(phys_addr_t base, phys_size_t size, uint flags) -{ - return _lmb_alloc_addr(base, size, flags); -} - /* Return number of bytes from a given address that are free */ phys_size_t lmb_get_free_size(phys_addr_t addr) { -- cgit v1.3.1 From 623f5cf517ae0e0f6f7132ac6411ea0a8dd9b3f7 Mon Sep 17 00:00:00 2001 From: Evgeny Bachinin Date: Wed, 11 Dec 2024 01:39:57 +0300 Subject: fdtdec: encapsulate dtb_dt_embedded() within Patch keeps the access to dtb_dt_embedded() within fdtdec API, by means of new API function introduction. This new function is a common place for updating appropriate global_data fields for OF_EMBED case. Also, the consequence of the patch is movement of '___dtb_dt_*begin' symbols' declaration from header file, because nobody used symbols outside the lib/fdtdec.c. Signed-off-by: Evgeny Bachinin Suggested-by: Simon Glass Reviewed-by: Simon Glass --- common/board_r.c | 4 ++-- include/fdtdec.h | 24 +++++++----------------- lib/fdtdec.c | 26 ++++++++++++++++++++++++-- 3 files changed, 33 insertions(+), 21 deletions(-) (limited to 'lib') diff --git a/common/board_r.c b/common/board_r.c index 88dc756b2a5..3c6a4c1f5df 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -155,11 +155,11 @@ static int initr_reloc_global_data(void) /* * For CONFIG_OF_EMBED case the FDT is embedded into ELF, available by - * __dtb_dt_begin. After U-boot ELF self-relocation to RAM top address + * __dtb_dt_begin. After U-Boot ELF self-relocation to RAM top address * it is worth to update fdt_blob in global_data */ if (IS_ENABLED(CONFIG_OF_EMBED)) - gd->fdt_blob = dtb_dt_embedded(); + fdtdec_setup_embed(); #ifdef CONFIG_EFI_LOADER /* diff --git a/include/fdtdec.h b/include/fdtdec.h index 555c9520379..88eeb512978 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -136,23 +136,6 @@ struct fdt_pci_addr { u32 phys_lo; }; -extern u8 __dtb_dt_begin[]; /* embedded device tree blob */ -extern u8 __dtb_dt_spl_begin[]; /* embedded device tree blob for SPL/TPL */ - -/* Get a pointer to the embedded devicetree, if there is one, else NULL */ -static inline u8 *dtb_dt_embedded(void) -{ -#ifdef CONFIG_OF_EMBED -# ifdef CONFIG_XPL_BUILD - return __dtb_dt_spl_begin; -# else - return __dtb_dt_begin; -# endif -#else - return NULL; -#endif -} - /** * Compute the size of a resource. * @@ -1155,6 +1138,13 @@ int fdtdec_set_carveout(void *blob, const char *node, const char *prop_name, const char *name, const char **compatibles, unsigned int count, unsigned long flags); +/** + * fdtdec_setup_embed - pick up embedded DTS + * + * Should be invoked under CONFIG_OF_EMBED guard. + */ +void fdtdec_setup_embed(void); + /** * Set up the device tree ready for use */ diff --git a/lib/fdtdec.c b/lib/fdtdec.c index b0655988029..9cb94a15844 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -93,6 +93,23 @@ static const char *const fdt_src_name[] = { [FDTSRC_BLOBLIST] = "bloblist", }; +extern u8 __dtb_dt_begin[]; /* embedded device tree blob */ +extern u8 __dtb_dt_spl_begin[]; /* embedded device tree blob for SPL/TPL */ + +/* Get a pointer to the embedded devicetree, if there is one, else NULL */ +static u8 *dtb_dt_embedded(void) +{ +#ifdef CONFIG_OF_EMBED +# ifdef CONFIG_XPL_BUILD + return __dtb_dt_spl_begin; +# else + return __dtb_dt_begin; +# endif +#else + return NULL; +#endif +} + const char *fdtdec_get_srcname(void) { return fdt_src_name[gd->fdt_src]; @@ -1664,6 +1681,12 @@ static void setup_multi_dtb_fit(void) } } +void fdtdec_setup_embed(void) +{ + gd->fdt_blob = dtb_dt_embedded(); + gd->fdt_src = FDTSRC_EMBED; +} + int fdtdec_setup(void) { int ret = -ENOENT; @@ -1699,8 +1722,7 @@ int fdtdec_setup(void) gd->fdt_blob = fdt_find_separate(); gd->fdt_src = FDTSRC_SEPARATE; } else { /* embed dtb in ELF file for testing / development */ - gd->fdt_blob = dtb_dt_embedded(); - gd->fdt_src = FDTSRC_EMBED; + fdtdec_setup_embed(); } } -- cgit v1.3.1 From e2f0e9a320d1efba9ed280e9a4b14df661daef54 Mon Sep 17 00:00:00 2001 From: Evgeny Bachinin Date: Wed, 11 Dec 2024 01:39:58 +0300 Subject: fdtdec: dtb_dt_embedded: replace ifdefs by IS_ENABLED() Patch fixes the checkpatch warnings like: ``` WARNING: Use 'if (IS_ENABLED(CONFIG...))' instead of '#if or #ifdef' #94: FILE: lib/fdtdec.c:102: +#ifdef CONFIG_OF_EMBED ``` Signed-off-by: Evgeny Bachinin Reviewed-by: Simon Glass --- lib/fdtdec.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'lib') diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 9cb94a15844..7f141889086 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -99,15 +99,15 @@ extern u8 __dtb_dt_spl_begin[]; /* embedded device tree blob for SPL/TPL */ /* Get a pointer to the embedded devicetree, if there is one, else NULL */ static u8 *dtb_dt_embedded(void) { -#ifdef CONFIG_OF_EMBED -# ifdef CONFIG_XPL_BUILD - return __dtb_dt_spl_begin; -# else - return __dtb_dt_begin; -# endif -#else - return NULL; -#endif + u8 *addr = NULL; + + if (IS_ENABLED(CONFIG_OF_EMBED)) { + addr = __dtb_dt_begin; + + if (IS_ENABLED(CONFIG_XPL_BUILD)) + addr = __dtb_dt_spl_begin; + } + return addr; } const char *fdtdec_get_srcname(void) -- 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 'lib') 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