Commit c08804853361bb7c6e2f9e0cdcdc0b327f71fe35

Authored by Nikita Kiryanov
Committed by Tom Rini
1 parent 48ec529100

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

... ... @@ -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
... ... @@ -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