mirror of
https://github.com/AsahiLinux/u-boot
synced 2025-02-17 22:49:02 +00:00
lcd: implement a callback for splashimage
On some architectures certain values of splashimage will lead to a data abort exception. Document the problem, and implement a callback for splashimage to reject such values. Cc: Anatolij Gustschin <agust@denx.de> Cc: Wolfgang Denk <wd@denx.de> Signed-off-by: Nikita Kiryanov <nikita@compulab.co.il> Acked-by: Igor Grinberg <grinberg@compulab.co.il>
This commit is contained in:
parent
48ec529100
commit
c088048533
4 changed files with 71 additions and 0 deletions
11
README
11
README
|
@ -1530,6 +1530,17 @@ CBFS (Coreboot Filesystem) support
|
||||||
allows for a "silent" boot where a splash screen is
|
allows for a "silent" boot where a splash screen is
|
||||||
loaded very quickly after power-on.
|
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
|
CONFIG_SPLASH_SCREEN_ALIGN
|
||||||
|
|
||||||
If this option is set the splash image can be freely positioned
|
If this option is set the splash image can be freely positioned
|
||||||
|
|
26
common/lcd.c
26
common/lcd.c
|
@ -33,6 +33,8 @@
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <command.h>
|
#include <command.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <search.h>
|
||||||
|
#include <env_callback.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <stdio_dev.h>
|
#include <stdio_dev.h>
|
||||||
#if defined(CONFIG_POST)
|
#if defined(CONFIG_POST)
|
||||||
|
@ -1099,6 +1101,30 @@ static void *lcd_logo(void)
|
||||||
#endif /* CONFIG_LCD_LOGO && !CONFIG_LCD_INFO_BELOW_LOGO */
|
#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)
|
void lcd_position_cursor(unsigned col, unsigned row)
|
||||||
{
|
{
|
||||||
console_col = min(col, CONSOLE_COLS - 1);
|
console_col = min(col, CONSOLE_COLS - 1);
|
||||||
|
|
27
doc/README.displaying-bmps
Normal file
27
doc/README.displaying-bmps
Normal file
|
@ -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.
|
|
@ -41,6 +41,12 @@
|
||||||
#define SILENT_CALLBACK
|
#define SILENT_CALLBACK
|
||||||
#endif
|
#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
|
* This list of callback bindings is static, but may be overridden by defining
|
||||||
* a new association in the ".callbacks" environment variable.
|
* a new association in the ".callbacks" environment variable.
|
||||||
|
@ -51,6 +57,7 @@
|
||||||
"bootfile:bootfile," \
|
"bootfile:bootfile," \
|
||||||
"loadaddr:loadaddr," \
|
"loadaddr:loadaddr," \
|
||||||
SILENT_CALLBACK \
|
SILENT_CALLBACK \
|
||||||
|
SPLASHIMAGE_CALLBACK \
|
||||||
"stdin:console,stdout:console,stderr:console," \
|
"stdin:console,stdout:console,stderr:console," \
|
||||||
CONFIG_ENV_CALLBACK_LIST_STATIC
|
CONFIG_ENV_CALLBACK_LIST_STATIC
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue