Commit c08804853361bb7c6e2f9e0cdcdc0b327f71fe35
Committed by
Tom Rini
1 parent
48ec529100
Exists in
master
and in
53 other branches
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>
Showing 4 changed files with 71 additions and 0 deletions Side-by-side Diff
README
... | ... | @@ -1530,6 +1530,17 @@ |
1530 | 1530 | allows for a "silent" boot where a splash screen is |
1531 | 1531 | loaded very quickly after power-on. |
1532 | 1532 | |
1533 | + CONFIG_SPLASHIMAGE_GUARD | |
1534 | + | |
1535 | + If this option is set, then U-Boot will prevent the environment | |
1536 | + variable "splashimage" from being set to a problematic address | |
1537 | + (see README.displaying-bmps and README.arm-unaligned-accesses). | |
1538 | + This option is useful for targets where, due to alignment | |
1539 | + restrictions, an improperly aligned BMP image will cause a data | |
1540 | + abort. If you think you will not have problems with unaligned | |
1541 | + accesses (for example because your toolchain prevents them) | |
1542 | + there is no need to set this option. | |
1543 | + | |
1533 | 1544 | CONFIG_SPLASH_SCREEN_ALIGN |
1534 | 1545 | |
1535 | 1546 | If this option is set the splash image can be freely positioned |
common/lcd.c
... | ... | @@ -33,6 +33,8 @@ |
33 | 33 | #include <common.h> |
34 | 34 | #include <command.h> |
35 | 35 | #include <stdarg.h> |
36 | +#include <search.h> | |
37 | +#include <env_callback.h> | |
36 | 38 | #include <linux/types.h> |
37 | 39 | #include <stdio_dev.h> |
38 | 40 | #if defined(CONFIG_POST) |
... | ... | @@ -1098,6 +1100,30 @@ |
1098 | 1100 | return (void *)lcd_base; |
1099 | 1101 | #endif /* CONFIG_LCD_LOGO && !CONFIG_LCD_INFO_BELOW_LOGO */ |
1100 | 1102 | } |
1103 | + | |
1104 | +#ifdef CONFIG_SPLASHIMAGE_GUARD | |
1105 | +static int on_splashimage(const char *name, const char *value, enum env_op op, | |
1106 | + int flags) | |
1107 | +{ | |
1108 | + ulong addr; | |
1109 | + int aligned; | |
1110 | + | |
1111 | + if (op == env_op_delete) | |
1112 | + return 0; | |
1113 | + | |
1114 | + addr = simple_strtoul(value, NULL, 16); | |
1115 | + /* See README.displaying-bmps */ | |
1116 | + aligned = (addr % 4 == 2); | |
1117 | + if (!aligned) { | |
1118 | + printf("Invalid splashimage value. Value must be 16 bit aligned, but not 32 bit aligned\n"); | |
1119 | + return -1; | |
1120 | + } | |
1121 | + | |
1122 | + return 0; | |
1123 | +} | |
1124 | + | |
1125 | +U_BOOT_ENV_CALLBACK(splashimage, on_splashimage); | |
1126 | +#endif | |
1101 | 1127 | |
1102 | 1128 | void lcd_position_cursor(unsigned col, unsigned row) |
1103 | 1129 | { |
doc/README.displaying-bmps
1 | +If you are experiencing hangups/data-aborts when trying to display a BMP image, | |
2 | +the following might be relevant to your situation... | |
3 | + | |
4 | +Some architectures cannot handle unaligned memory accesses, and an attempt to | |
5 | +perform one will lead to a data abort. On such architectures it is necessary to | |
6 | +make sure all data is properly aligned, and in many situations simply choosing | |
7 | +a 32 bit aligned address is enough to ensure proper alignment. This is not | |
8 | +always the case when dealing with data that has an internal layout such as a | |
9 | +BMP image: | |
10 | + | |
11 | +BMP images have a header that starts with 2 byte-size fields followed by mostly | |
12 | +32 bit fields. The packed struct that represents this header can be seen below: | |
13 | + | |
14 | +typedef struct bmp_header { | |
15 | + /* Header */ | |
16 | + char signature[2]; | |
17 | + __u32 file_size; | |
18 | + __u32 reserved; | |
19 | + __u32 data_offset; | |
20 | + ... etc | |
21 | +} __attribute__ ((packed)) bmp_header_t; | |
22 | + | |
23 | +When placed in an aligned address such as 0x80a00000, char signature offsets | |
24 | +the __u32 fields into unaligned addresses (in our example 0x80a00002, | |
25 | +0x80a00006, and so on...). When these fields are accessed by U-Boot, a 32 bit | |
26 | +access is generated at a non-32-bit-aligned address, causing a data abort. | |
27 | +The proper alignment for BMP images is therefore: 32-bit-aligned-address + 2. |
include/env_callback.h
... | ... | @@ -41,6 +41,12 @@ |
41 | 41 | #define SILENT_CALLBACK |
42 | 42 | #endif |
43 | 43 | |
44 | +#ifdef CONFIG_SPLASHIMAGE_GUARD | |
45 | +#define SPLASHIMAGE_CALLBACK "splashimage:splashimage," | |
46 | +#else | |
47 | +#define SPLASHIMAGE_CALLBACK | |
48 | +#endif | |
49 | + | |
44 | 50 | /* |
45 | 51 | * This list of callback bindings is static, but may be overridden by defining |
46 | 52 | * a new association in the ".callbacks" environment variable. |
... | ... | @@ -51,6 +57,7 @@ |
51 | 57 | "bootfile:bootfile," \ |
52 | 58 | "loadaddr:loadaddr," \ |
53 | 59 | SILENT_CALLBACK \ |
60 | + SPLASHIMAGE_CALLBACK \ | |
54 | 61 | "stdin:console,stdout:console,stderr:console," \ |
55 | 62 | CONFIG_ENV_CALLBACK_LIST_STATIC |
56 | 63 |