diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/Kconfig | 16 | ||||
-rw-r--r-- | common/Makefile | 3 | ||||
-rw-r--r-- | common/bmp.c | 149 | ||||
-rw-r--r-- | common/cli_hush.c | 8 | ||||
-rw-r--r-- | common/splash.c | 20 |
5 files changed, 183 insertions, 13 deletions
diff --git a/common/Kconfig b/common/Kconfig index f2783ee65d7..bbabadb35e1 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -559,7 +559,7 @@ config BOARD_TYPES config DISPLAY_CPUINFO bool "Display information about the CPU during start up" - default y if ARC|| ARM || NIOS2 || X86 || XTENSA || M68K + default y if ARC || ARM || NIOS2 || X86 || XTENSA || M68K help Display information about the CPU that U-Boot is running on when U-Boot starts up. The function print_cpuinfo() is called @@ -626,7 +626,7 @@ config EVENT_DEBUG bool "Enable event debugging assistance" default y if SANDBOX help - Enable this get usefui features for seeing what is happening with + Enable this to get useful features for seeing what is happening with events, such as event-type names. This adds to the code size of U-Boot so can be turned off for production builds. @@ -1154,3 +1154,15 @@ config FDT_SIMPLEFB config IO_TRACE bool + +config BMP + bool "Enable bmp image display" + default y if CMD_BMP + help + Enable bmp functions to display bmp image and get bmp info. + +config SPL_BMP + bool "Enable bmp image display at SPL" + depends on SPL_VIDEO + help + Enable bmp functions to display bmp image and get bmp info at SPL. diff --git a/common/Makefile b/common/Makefile index a50302d8b52..c87bb2e78b3 100644 --- a/common/Makefile +++ b/common/Makefile @@ -45,6 +45,7 @@ endif # !CONFIG_SPL_BUILD obj-$(CONFIG_$(SPL_TPL_)BOOTSTAGE) += bootstage.o obj-$(CONFIG_$(SPL_TPL_)BLOBLIST) += bloblist.o +obj-$(CONFIG_$(SPL_)BMP) += bmp.o ifdef CONFIG_SPL_BUILD ifdef CONFIG_SPL_DFU @@ -56,6 +57,8 @@ obj-$(CONFIG_$(SPL_TPL_)OF_LIBFDT) += fdt_support.o obj-$(CONFIG_SPL_USB_HOST) += usb.o usb_hub.o obj-$(CONFIG_SPL_USB_STORAGE) += usb_storage.o obj-$(CONFIG_SPL_MUSB_NEW) += usb.o +obj-$(CONFIG_SPL_SPLASH_SCREEN) += splash.o +obj-$(CONFIG_SPL_SPLASH_SOURCE) += splash_source.o endif # CONFIG_SPL_BUILD #others diff --git a/common/bmp.c b/common/bmp.c new file mode 100644 index 00000000000..57764f3653e --- /dev/null +++ b/common/bmp.c @@ -0,0 +1,149 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2002 + * Detlev Zundel, DENX Software Engineering, dzu@denx.de. + */ + +/* + * BMP handling routines + */ + +#include <common.h> +#include <bmp_layout.h> +#include <command.h> +#include <dm.h> +#include <gzip.h> +#include <log.h> +#include <malloc.h> +#include <mapmem.h> +#include <splash.h> +#include <video.h> +#include <asm/byteorder.h> + +/* + * Allocate and decompress a BMP image using gunzip(). + * + * Returns a pointer to the decompressed image data. This pointer is + * aligned to 32-bit-aligned-address + 2. + * See doc/README.displaying-bmps for explanation. + * + * The allocation address is passed to 'alloc_addr' and must be freed + * by the caller after use. + * + * Returns NULL if decompression failed, or if the decompressed data + * didn't contain a valid BMP signature or decompression is not enabled in + * Kconfig. + */ +struct bmp_image *gunzip_bmp(unsigned long addr, unsigned long *lenp, + void **alloc_addr) +{ + void *dst; + unsigned long len; + struct bmp_image *bmp; + + if (!CONFIG_IS_ENABLED(VIDEO_BMP_GZIP)) + return NULL; + + /* + * Decompress bmp image + */ + len = CONFIG_VAL(VIDEO_LOGO_MAX_SIZE); + /* allocate extra 3 bytes for 32-bit-aligned-address + 2 alignment */ + dst = malloc(CONFIG_VAL(VIDEO_LOGO_MAX_SIZE) + 3); + if (!dst) { + puts("Error: malloc in gunzip failed!\n"); + return NULL; + } + + /* align to 32-bit-aligned-address + 2 */ + bmp = dst + 2; + + if (gunzip(bmp, CONFIG_VAL(VIDEO_LOGO_MAX_SIZE), map_sysmem(addr, 0), + &len)) { + free(dst); + return NULL; + } + if (len == CONFIG_VAL(VIDEO_LOGO_MAX_SIZE)) + puts("Image could be truncated (increase CONFIG_VIDEO_LOGO_MAX_SIZE)!\n"); + + /* + * Check for bmp mark 'BM' + */ + if (!((bmp->header.signature[0] == 'B') && + (bmp->header.signature[1] == 'M'))) { + free(dst); + return NULL; + } + + debug("Gzipped BMP image detected!\n"); + + *alloc_addr = dst; + return bmp; +} + +#ifdef CONFIG_NEEDS_MANUAL_RELOC +void bmp_reloc(void) +{ + fixup_cmdtable(cmd_bmp_sub, ARRAY_SIZE(cmd_bmp_sub)); +} +#endif + +int bmp_info(ulong addr) +{ + struct bmp_image *bmp = (struct bmp_image *)map_sysmem(addr, 0); + void *bmp_alloc_addr = NULL; + unsigned long len; + + if (!((bmp->header.signature[0] == 'B') && + (bmp->header.signature[1] == 'M'))) + bmp = gunzip_bmp(addr, &len, &bmp_alloc_addr); + + if (!bmp) { + printf("There is no valid bmp file at the given address\n"); + return 1; + } + + printf("Image size : %d x %d\n", le32_to_cpu(bmp->header.width), + le32_to_cpu(bmp->header.height)); + printf("Bits per pixel: %d\n", le16_to_cpu(bmp->header.bit_count)); + printf("Compression : %d\n", le32_to_cpu(bmp->header.compression)); + + if (bmp_alloc_addr) + free(bmp_alloc_addr); + + return 0; +} + +int bmp_display(ulong addr, int x, int y) +{ + struct udevice *dev; + int ret; + struct bmp_image *bmp = map_sysmem(addr, 0); + void *bmp_alloc_addr = NULL; + unsigned long len; + + if (!((bmp->header.signature[0] == 'B') && + (bmp->header.signature[1] == 'M'))) + bmp = gunzip_bmp(addr, &len, &bmp_alloc_addr); + + if (!bmp) { + printf("There is no valid bmp file at the given address\n"); + return 1; + } + addr = map_to_sysmem(bmp); + + ret = uclass_first_device_err(UCLASS_VIDEO, &dev); + if (!ret) { + bool align = false; + + if (x == BMP_ALIGN_CENTER || y == BMP_ALIGN_CENTER) + align = true; + + ret = video_bmp_display(dev, addr, x, y, align); + } + + if (bmp_alloc_addr) + free(bmp_alloc_addr); + + return ret ? CMD_RET_FAILURE : 0; +} diff --git a/common/cli_hush.c b/common/cli_hush.c index 1ad7a509dfa..171069f5f49 100644 --- a/common/cli_hush.c +++ b/common/cli_hush.c @@ -2171,12 +2171,18 @@ int set_local_var(const char *s, int flg_export) * NAME=VALUE format. So the first order of business is to * split 's' on the '=' into 'name' and 'value' */ value = strchr(name, '='); - if (value == NULL || *(value + 1) == 0) { + if (!value) { free(name); return -1; } *value++ = 0; + if (!*value) { + unset_local_var(name); + free(name); + return 0; + } + for(cur = top_vars; cur; cur = cur->next) { if(strcmp(cur->name, name)==0) break; diff --git a/common/splash.c b/common/splash.c index 4bc54b1bf9e..6820db683bd 100644 --- a/common/splash.c +++ b/common/splash.c @@ -89,19 +89,18 @@ static inline int splash_video_logo_load(void) { return -ENOSYS; } __weak int splash_screen_prepare(void) { - if (IS_ENABLED(CONFIG_SPLASH_SOURCE)) + if (CONFIG_IS_ENABLED(SPLASH_SOURCE)) return splash_source_load(default_splash_locations, ARRAY_SIZE(default_splash_locations)); return splash_video_logo_load(); } -#ifdef CONFIG_SPLASH_SCREEN_ALIGN void splash_get_pos(int *x, int *y) { char *s = env_get("splashpos"); - if (!s) + if (!CONFIG_IS_ENABLED(SPLASH_SCREEN_ALIGN) || !s) return; if (s[0] == 'm') @@ -117,9 +116,8 @@ void splash_get_pos(int *x, int *y) *y = simple_strtol(s + 1, NULL, 0); } } -#endif /* CONFIG_SPLASH_SCREEN_ALIGN */ -#if defined(CONFIG_VIDEO) && !defined(CONFIG_HIDE_LOGO_VERSION) +#if CONFIG_IS_ENABLED(VIDEO) && !CONFIG_IS_ENABLED(HIDE_LOGO_VERSION) #ifdef CONFIG_VIDEO_LOGO #include <bmp_logo.h> @@ -159,13 +157,13 @@ void splash_display_banner(void) * Common function to show a splash image if env("splashimage") is set. * For additional details please refer to doc/README.splashprepare. */ -#if defined(CONFIG_SPLASH_SCREEN) && defined(CONFIG_CMD_BMP) int splash_display(void) { ulong addr; char *s; int x = 0, y = 0, ret; - + if (!CONFIG_IS_ENABLED(SPLASH_SCREEN)) + return -ENOSYS; s = env_get("splashimage"); if (!s) return -EINVAL; @@ -177,16 +175,18 @@ int splash_display(void) splash_get_pos(&x, &y); - ret = bmp_display(addr, x, y); + if (CONFIG_IS_ENABLED(BMP)) + ret = bmp_display(addr, x, y); + else + return -ENOSYS; /* Skip banner output on video console if the logo is not at 0,0 */ if (x || y) goto end; -#if defined(CONFIG_VIDEO) && !defined(CONFIG_HIDE_LOGO_VERSION) +#if CONFIG_IS_ENABLED(VIDEO) && !CONFIG_IS_ENABLED(HIDE_LOGO_VERSION) splash_display_banner(); #endif end: return ret; } -#endif |