Patchwork [U-Boot,v5,05/12] common: lcd.c: fix data abort exception when try to access bmp header

login
register
mail settings
Submitter Przemyslaw Marczak
Date Jan. 10, 2014, 2:31 p.m.
Message ID <af6eef57adbfe49093bd21b5bd4d88f53d5d2fcd.1389352945.git.p.marczak@samsung.com>
Download mbox | patch
Permalink /patch/309301/
State Changes Requested
Delegated to: Minkyu Kang
Headers show

Comments

Przemyslaw Marczak - Jan. 10, 2014, 2:31 p.m.
Changes:
- le16_to_cpu() to get_unaligned_le16()
- le32_to_cpu() to get_unaligned_le32()
when access fields in struct bmp header.

This changes avoids data abort exception caused by unaligned data access.

Signed-off-by: Przemyslaw Marczak <p.marczak@samsung.com>
Acked-by: Anatolij Gustschin <agust@denx.de>
---
Changes v2:
- new patch

Changes v3:
- common/Makefile - remove CFLAG: -mno-unaligned-access
- common/lcd.c - fix data abort exception when access bmp_header

Changes v4:
- add Acked-by

Changes v5:
- none

 common/lcd.c |   27 +++++++++++++--------------
 1 file changed, 13 insertions(+), 14 deletions(-)

Patch

diff --git a/common/lcd.c b/common/lcd.c
index 56bf067..aa81522 100644
--- a/common/lcd.c
+++ b/common/lcd.c
@@ -26,7 +26,7 @@ 
 #endif
 #include <lcd.h>
 #include <watchdog.h>
-
+#include <asm/unaligned.h>
 #include <splash.h>
 
 #if defined(CONFIG_CPU_PXA25X) || defined(CONFIG_CPU_PXA27X) || \
@@ -777,9 +777,9 @@  static void lcd_display_rle8_bitmap(bmp_image_t *bmp, ushort *cmap, uchar *fb,
 	int x, y;
 	int decode = 1;
 
-	width = le32_to_cpu(bmp->header.width);
-	height = le32_to_cpu(bmp->header.height);
-	bmap = (uchar *)bmp + le32_to_cpu(bmp->header.data_offset);
+	width = get_unaligned_le32(&bmp->header.width);
+	height = get_unaligned_le32(&bmp->header.height);
+	bmap = (uchar *)bmp + get_unaligned_le32(&bmp->header.data_offset);
 
 	x = 0;
 	y = height - 1;
@@ -900,9 +900,10 @@  int lcd_display_bitmap(ulong bmp_image, int x, int y)
 		return 1;
 	}
 
-	width = le32_to_cpu(bmp->header.width);
-	height = le32_to_cpu(bmp->header.height);
-	bmp_bpix = le16_to_cpu(bmp->header.bit_count);
+	width = get_unaligned_le32(&bmp->header.width);
+	height = get_unaligned_le32(&bmp->header.height);
+	bmp_bpix = get_unaligned_le16(&bmp->header.bit_count);
+
 	colors = 1 << bmp_bpix;
 
 	bpix = NBITS(panel_info.vl_bpix);
@@ -917,9 +918,7 @@  int lcd_display_bitmap(ulong bmp_image, int x, int y)
 	/* We support displaying 8bpp BMPs on 16bpp LCDs */
 	if (bpix != bmp_bpix && !(bmp_bpix == 8 && bpix == 16)) {
 		printf ("Error: %d bit/pixel mode, but BMP has %d bit/pixel\n",
-			bpix,
-			le16_to_cpu(bmp->header.bit_count));
-
+			bpix, get_unaligned_le16(&bmp->header.bit_count));
 		return 1;
 	}
 
@@ -956,7 +955,6 @@  int lcd_display_bitmap(ulong bmp_image, int x, int y)
 		}
 	}
 #endif
-
 	/*
 	 *  BMP format for Monochrome assumes that the state of a
 	 * pixel is described on a per Bit basis, not per Byte.
@@ -987,15 +985,16 @@  int lcd_display_bitmap(ulong bmp_image, int x, int y)
 	if ((y + height) > panel_info.vl_row)
 		height = panel_info.vl_row - y;
 
-	bmap = (uchar *) bmp + le32_to_cpu(bmp->header.data_offset);
-	fb   = (uchar *) (lcd_base +
+	bmap = (uchar *)bmp + get_unaligned_le32(&bmp->header.data_offset);
+	fb   = (uchar *)(lcd_base +
 		(y + height - 1) * lcd_line_length + x * bpix / 8);
 
 	switch (bmp_bpix) {
 	case 1: /* pass through */
 	case 8:
 #ifdef CONFIG_LCD_BMP_RLE8
-		if (le32_to_cpu(bmp->header.compression) == BMP_BI_RLE8) {
+		u32 compression = get_unaligned_le32(&bmp->header.compression);
+		if (compression == BMP_BI_RLE8) {
 			if (bpix != 16) {
 				/* TODO implement render code for bpix != 16 */
 				printf("Error: only support 16 bpix");