diff options
| -rw-r--r-- | README | 11 | ||||
| -rw-r--r-- | common/lcd.c | 26 | ||||
| -rw-r--r-- | doc/README.displaying-bmps | 27 | ||||
| -rw-r--r-- | include/env_callback.h | 7 | 
4 files changed, 71 insertions, 0 deletions
| @@ -1530,6 +1530,17 @@ CBFS (Coreboot Filesystem) support  		allows for a "silent" boot where a splash screen is  		loaded very quickly after power-on. +		CONFIG_SPLASHIMAGE_GUARD + +		If this option is set, then U-Boot will prevent the environment +		variable "splashimage" from being set to a problematic address +		(see README.displaying-bmps and README.arm-unaligned-accesses). +		This option is useful for targets where, due to alignment +		restrictions, an improperly aligned BMP image will cause a data +		abort. If you think you will not have problems with unaligned +		accesses (for example because your toolchain prevents them) +		there is no need to set this option. +  		CONFIG_SPLASH_SCREEN_ALIGN  		If this option is set the splash image can be freely positioned diff --git a/common/lcd.c b/common/lcd.c index ba6975be2..590bbb930 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -33,6 +33,8 @@  #include <common.h>  #include <command.h>  #include <stdarg.h> +#include <search.h> +#include <env_callback.h>  #include <linux/types.h>  #include <stdio_dev.h>  #if defined(CONFIG_POST) @@ -1099,6 +1101,30 @@ static void *lcd_logo(void)  #endif /* CONFIG_LCD_LOGO && !CONFIG_LCD_INFO_BELOW_LOGO */  } +#ifdef CONFIG_SPLASHIMAGE_GUARD +static int on_splashimage(const char *name, const char *value, enum env_op op, +	int flags) +{ +	ulong addr; +	int aligned; + +	if (op == env_op_delete) +		return 0; + +	addr = simple_strtoul(value, NULL, 16); +	/* See README.displaying-bmps */ +	aligned = (addr % 4 == 2); +	if (!aligned) { +		printf("Invalid splashimage value. Value must be 16 bit aligned, but not 32 bit aligned\n"); +		return -1; +	} + +	return 0; +} + +U_BOOT_ENV_CALLBACK(splashimage, on_splashimage); +#endif +  void lcd_position_cursor(unsigned col, unsigned row)  {  	console_col = min(col, CONSOLE_COLS - 1); diff --git a/doc/README.displaying-bmps b/doc/README.displaying-bmps new file mode 100644 index 000000000..331154166 --- /dev/null +++ b/doc/README.displaying-bmps @@ -0,0 +1,27 @@ +If you are experiencing hangups/data-aborts when trying to display a BMP image, +the following might be relevant to your situation... + +Some architectures cannot handle unaligned memory accesses, and an attempt to +perform one will lead to a data abort. On such architectures it is necessary to +make sure all data is properly aligned, and in many situations simply choosing +a 32 bit aligned address is enough to ensure proper alignment. This is not +always the case when dealing with data that has an internal layout such as a +BMP image: + +BMP images have a header that starts with 2 byte-size fields followed by mostly +32 bit fields. The packed struct that represents this header can be seen below: + +typedef struct bmp_header { +	/* Header */ +	char signature[2]; +	__u32	file_size; +	__u32	reserved; +	__u32	data_offset; +	... etc +} __attribute__ ((packed)) bmp_header_t; + +When placed in an aligned address such as 0x80a00000, char signature offsets +the __u32 fields into unaligned addresses (in our example 0x80a00002, +0x80a00006, and so on...). When these fields are accessed by U-Boot, a 32 bit +access is generated at a non-32-bit-aligned address, causing a data abort. +The proper alignment for BMP images is therefore: 32-bit-aligned-address + 2. diff --git a/include/env_callback.h b/include/env_callback.h index c583120c1..62428d1e0 100644 --- a/include/env_callback.h +++ b/include/env_callback.h @@ -41,6 +41,12 @@  #define SILENT_CALLBACK  #endif +#ifdef CONFIG_SPLASHIMAGE_GUARD +#define SPLASHIMAGE_CALLBACK "splashimage:splashimage," +#else +#define SPLASHIMAGE_CALLBACK +#endif +  /*   * This list of callback bindings is static, but may be overridden by defining   * a new association in the ".callbacks" environment variable. @@ -51,6 +57,7 @@  	"bootfile:bootfile," \  	"loadaddr:loadaddr," \  	SILENT_CALLBACK \ +	SPLASHIMAGE_CALLBACK \  	"stdin:console,stdout:console,stderr:console," \  	CONFIG_ENV_CALLBACK_LIST_STATIC |