Blame SOURCES/0405-Several-fixes-to-ieee1275-and-big-endian-video.patch

f96e0b
From f3d557cb000022e4d163f2e566e243aa73632675 Mon Sep 17 00:00:00 2001
f96e0b
From: Vladimir 'phcoder' Serbinenko <phcoder@gmail.com>
f96e0b
Date: Thu, 2 May 2013 22:30:20 +0200
f96e0b
Subject: [PATCH 405/482] 	Several fixes to ieee1275 and big-endian
f96e0b
 video.
f96e0b
f96e0b
---
f96e0b
 ChangeLog                            |   4 +
f96e0b
 grub-core/tests/checksums.c          |   3 +
f96e0b
 grub-core/tests/video_checksum.c     |  82 +++++++++-
f96e0b
 grub-core/tests/videotest_checksum.c |  38 ++++-
f96e0b
 grub-core/video/bochs.c              |   1 +
f96e0b
 grub-core/video/cirrus.c             |   6 +-
f96e0b
 grub-core/video/efi_uga.c            |   2 +-
f96e0b
 grub-core/video/emu/sdl.c            |  12 +-
f96e0b
 grub-core/video/fb/fbblit.c          |  78 +++++++++-
f96e0b
 grub-core/video/fb/fbfill.c          |  20 +--
f96e0b
 grub-core/video/fb/fbutil.c          |   8 +
f96e0b
 grub-core/video/fb/video_fb.c        | 280 +++++++++++++++++++++++++++++++----
f96e0b
 grub-core/video/i386/pc/vbe.c        |   5 +-
f96e0b
 grub-core/video/ieee1275.c           | 106 +++++++++++--
f96e0b
 grub-core/video/readers/jpeg.c       |  13 ++
f96e0b
 grub-core/video/readers/png.c        |  61 +++++++-
f96e0b
 grub-core/video/sis315pro.c          |   4 +-
f96e0b
 include/grub/video_fb.h              |   4 +-
f96e0b
 18 files changed, 655 insertions(+), 72 deletions(-)
f96e0b
f96e0b
diff --git a/ChangeLog b/ChangeLog
f96e0b
index 8525dd9..3ff4a05 100644
f96e0b
--- a/ChangeLog
f96e0b
+++ b/ChangeLog
f96e0b
@@ -1,5 +1,9 @@
f96e0b
 2013-05-02  Vladimir Serbinenko  <phcoder@gmail.com>
f96e0b
 
f96e0b
+	Several fixes to ieee1275 and big-endian video.
f96e0b
+
f96e0b
+2013-05-02  Vladimir Serbinenko  <phcoder@gmail.com>
f96e0b
+
f96e0b
 	Add missing exports on mips.
f96e0b
 
f96e0b
 2013-05-02  Vladimir Serbinenko  <phcoder@gmail.com>
f96e0b
diff --git a/grub-core/tests/checksums.c b/grub-core/tests/checksums.c
f96e0b
index 93d100f..583c696 100644
f96e0b
--- a/grub-core/tests/checksums.c
f96e0b
+++ b/grub-core/tests/checksums.c
f96e0b
@@ -1,6 +1,9 @@
f96e0b
   { "videotest", 640, 480, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi16 */, (grub_uint32_t []) { 0x7f1853ba, 0x7f1853ba, 0x7f1853ba, 0x7f1853ba, 0x7f1853ba, }, 5 },
f96e0b
   { "videotest", 800, 600, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi16 */, (grub_uint32_t []) { 0xff1957f0, 0xff1957f0, 0xff1957f0, 0xff1957f0, 0xff1957f0, }, 5 },
f96e0b
   { "videotest", 1024, 768, 0x2, 16, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi16 */, (grub_uint32_t []) { 0xcb45d8c5, 0xcb45d8c5, 0xcb45d8c5, 0xcb45d8c5, 0xcb45d8c5, }, 5 },
f96e0b
+  { "videotest", 640, 480, 0x2, 256, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 640x480xi256 */, (grub_uint32_t []) { 0x2d1b122b, 0x2d1b122b, 0x2d1b122b, 0x2d1b122b, 0x2d1b122b, }, 5 },
f96e0b
+  { "videotest", 800, 600, 0x2, 256, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 800x600xi256 */, (grub_uint32_t []) { 0x327d1082, 0x327d1082, 0x327d1082, 0x327d1082, 0x327d1082, }, 5 },
f96e0b
+  { "videotest", 1024, 768, 0x2, 256, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0 /* 1024x768xi256 */, (grub_uint32_t []) { 0xadd0f186, 0xadd0f186, 0xadd0f186, 0xadd0f186, 0xadd0f186, }, 5 },
f96e0b
   { "videotest", 640, 480, 0x1, 256, 15, 2, 10, 5, 5, 5, 0, 5, 0, 0 /* 640x480xrgb555 */, (grub_uint32_t []) { 0x2c97569c, 0x2c97569c, 0x2c97569c, 0x2c97569c, 0x2c97569c, }, 5 },
f96e0b
   { "videotest", 800, 600, 0x1, 256, 15, 2, 10, 5, 5, 5, 0, 5, 0, 0 /* 800x600xrgb555 */, (grub_uint32_t []) { 0x9bd7a3ac, 0x9bd7a3ac, 0x9bd7a3ac, 0x9bd7a3ac, 0x9bd7a3ac, }, 5 },
f96e0b
   { "videotest", 1024, 768, 0x1, 256, 15, 2, 10, 5, 5, 5, 0, 5, 0, 0 /* 1024x768xrgb555 */, (grub_uint32_t []) { 0xedbceb9c, 0xedbceb9c, 0xedbceb9c, 0xedbceb9c, 0xedbceb9c, }, 5 },
f96e0b
diff --git a/grub-core/tests/video_checksum.c b/grub-core/tests/video_checksum.c
f96e0b
index b2aab79..cf47fa2 100644
f96e0b
--- a/grub-core/tests/video_checksum.c
f96e0b
+++ b/grub-core/tests/video_checksum.c
f96e0b
@@ -249,14 +249,16 @@ get_modename (void)
f96e0b
     }
f96e0b
   if (capt_mode_info.red_field_pos == 0)
f96e0b
     {
f96e0b
-      grub_snprintf (buf, sizeof (buf), "bgr%d%d%d", capt_mode_info.blue_mask_size,
f96e0b
+      grub_snprintf (buf, sizeof (buf), "bgra%d%d%d%d", capt_mode_info.blue_mask_size,
f96e0b
 		     capt_mode_info.green_mask_size,
f96e0b
-		     capt_mode_info.red_mask_size);
f96e0b
+		     capt_mode_info.red_mask_size,
f96e0b
+		     capt_mode_info.reserved_mask_size);
f96e0b
       return buf;
f96e0b
     }
f96e0b
-  grub_snprintf (buf, sizeof (buf), "rgb%d%d%d", capt_mode_info.red_mask_size,
f96e0b
+  grub_snprintf (buf, sizeof (buf), "rgba%d%d%d%d", capt_mode_info.red_mask_size,
f96e0b
 		 capt_mode_info.green_mask_size,
f96e0b
-		 capt_mode_info.blue_mask_size);
f96e0b
+		 capt_mode_info.blue_mask_size,
f96e0b
+		 capt_mode_info.reserved_mask_size);
f96e0b
   return buf;
f96e0b
 }
f96e0b
 
f96e0b
@@ -270,11 +272,81 @@ static void
f96e0b
 checksum (void)
f96e0b
 {
f96e0b
   void *ptr;
f96e0b
-  grub_uint32_t crc;
f96e0b
+  grub_uint32_t crc = 0;
f96e0b
 
f96e0b
   ptr = grub_video_capture_get_framebuffer ();
f96e0b
 
f96e0b
+#ifdef GRUB_CPU_WORDS_BIGENDIAN
f96e0b
+  switch (capt_mode_info.bytes_per_pixel)
f96e0b
+    {
f96e0b
+    case 1:
f96e0b
+      crc = grub_getcrc32c (0, ptr, capt_mode_info.pitch
f96e0b
+			    * capt_mode_info.height);
f96e0b
+      break;
f96e0b
+    case 2:
f96e0b
+      {
f96e0b
+	unsigned x, y, rowskip;
f96e0b
+	grub_uint8_t *iptr = ptr;
f96e0b
+	crc = 0;
f96e0b
+	rowskip = capt_mode_info.pitch - capt_mode_info.width * 2;
f96e0b
+	for (y = 0; y < capt_mode_info.height; y++)
f96e0b
+	  {
f96e0b
+	    for (x = 0; x < capt_mode_info.width; x++)
f96e0b
+	      {
f96e0b
+		crc = grub_getcrc32c (crc, iptr + 1, 1);
f96e0b
+		crc = grub_getcrc32c (crc, iptr, 1);
f96e0b
+		iptr += 2;
f96e0b
+	      }
f96e0b
+	    crc = grub_getcrc32c (crc, iptr, rowskip);
f96e0b
+	    iptr += rowskip;
f96e0b
+	  }
f96e0b
+	break;
f96e0b
+      }
f96e0b
+    case 3:
f96e0b
+      {
f96e0b
+	unsigned x, y, rowskip;
f96e0b
+	grub_uint8_t *iptr = ptr;
f96e0b
+	crc = 0;
f96e0b
+	rowskip = capt_mode_info.pitch - capt_mode_info.width * 3;
f96e0b
+	for (y = 0; y < capt_mode_info.height; y++)
f96e0b
+	  {
f96e0b
+	    for (x = 0; x < capt_mode_info.width; x++)
f96e0b
+	      {
f96e0b
+		crc = grub_getcrc32c (crc, iptr + 2, 1);
f96e0b
+		crc = grub_getcrc32c (crc, iptr + 1, 1);
f96e0b
+		crc = grub_getcrc32c (crc, iptr, 1);
f96e0b
+		iptr += 3;
f96e0b
+	      }
f96e0b
+	    crc = grub_getcrc32c (crc, iptr, rowskip);
f96e0b
+	    iptr += rowskip;
f96e0b
+	  }
f96e0b
+	break;
f96e0b
+      }
f96e0b
+    case 4:
f96e0b
+      {
f96e0b
+	unsigned x, y, rowskip;
f96e0b
+	grub_uint8_t *iptr = ptr;
f96e0b
+	crc = 0;
f96e0b
+	rowskip = capt_mode_info.pitch - capt_mode_info.width * 4;
f96e0b
+	for (y = 0; y < capt_mode_info.height; y++)
f96e0b
+	  {
f96e0b
+	    for (x = 0; x < capt_mode_info.width; x++)
f96e0b
+	      {
f96e0b
+		crc = grub_getcrc32c (crc, iptr + 3, 1);
f96e0b
+		crc = grub_getcrc32c (crc, iptr + 2, 1);
f96e0b
+		crc = grub_getcrc32c (crc, iptr + 1, 1);
f96e0b
+		crc = grub_getcrc32c (crc, iptr, 1);
f96e0b
+		iptr += 4;
f96e0b
+	      }
f96e0b
+	    crc = grub_getcrc32c (crc, iptr, rowskip);
f96e0b
+	    iptr += rowskip;
f96e0b
+	  }
f96e0b
+	break;
f96e0b
+      }
f96e0b
+    }
f96e0b
+#else
f96e0b
   crc = grub_getcrc32c (0, ptr, capt_mode_info.pitch * capt_mode_info.height);
f96e0b
+#endif
f96e0b
   if (!checksums || ctr >= nchk)
f96e0b
     {
f96e0b
       grub_test_assert (0, "Unexpected checksum %s_%dx%dx%s:%d: 0x%x",
f96e0b
diff --git a/grub-core/tests/videotest_checksum.c b/grub-core/tests/videotest_checksum.c
f96e0b
index 3c70f8c..7833d04 100644
f96e0b
--- a/grub-core/tests/videotest_checksum.c
f96e0b
+++ b/grub-core/tests/videotest_checksum.c
f96e0b
@@ -63,6 +63,42 @@ struct
f96e0b
 	.number_of_colors = GRUB_VIDEO_FBSTD_NUMCOLORS
f96e0b
       },
f96e0b
     },
f96e0b
+
f96e0b
+
f96e0b
+    {
f96e0b
+      .mode_info = {
f96e0b
+	.width = 640,
f96e0b
+	.height = 480,
f96e0b
+	.pitch = 640,
f96e0b
+	.mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR,
f96e0b
+	.bpp = 8,
f96e0b
+	.bytes_per_pixel = 1,
f96e0b
+	.number_of_colors = GRUB_VIDEO_FBSTD_EXT_NUMCOLORS
f96e0b
+      },
f96e0b
+    },
f96e0b
+    {
f96e0b
+      .mode_info = {
f96e0b
+	.width = 800,
f96e0b
+	.height = 600,
f96e0b
+	.pitch = 800,
f96e0b
+	.mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR,
f96e0b
+	.bpp = 8,
f96e0b
+	.bytes_per_pixel = 1,
f96e0b
+	.number_of_colors = GRUB_VIDEO_FBSTD_EXT_NUMCOLORS
f96e0b
+      },
f96e0b
+    },
f96e0b
+    {
f96e0b
+      .mode_info = {
f96e0b
+	.width = 1024,
f96e0b
+	.height = 768,
f96e0b
+	.pitch = 1024,
f96e0b
+	.mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR,
f96e0b
+	.bpp = 8,
f96e0b
+	.bytes_per_pixel = 1,
f96e0b
+	.number_of_colors = GRUB_VIDEO_FBSTD_EXT_NUMCOLORS
f96e0b
+      },
f96e0b
+    },
f96e0b
+
f96e0b
     {
f96e0b
       .mode_info = {
f96e0b
 	.width = 640,
f96e0b
@@ -275,7 +311,7 @@ videotest_checksum (void)
f96e0b
     {
f96e0b
       grub_video_capture_start (&tests[i].mode_info,
f96e0b
 				grub_video_fbstd_colors,
f96e0b
-				GRUB_VIDEO_FBSTD_NUMCOLORS);
f96e0b
+				tests[i].mode_info.number_of_colors);
f96e0b
       grub_terminal_input_fake_sequence ((int []) { '\n' }, 1);
f96e0b
 
f96e0b
       grub_video_checksum ("videotest");
f96e0b
diff --git a/grub-core/video/bochs.c b/grub-core/video/bochs.c
f96e0b
index aea486c..287ae0f 100644
f96e0b
--- a/grub-core/video/bochs.c
f96e0b
+++ b/grub-core/video/bochs.c
f96e0b
@@ -331,6 +331,7 @@ grub_video_bochs_setup (unsigned int width, unsigned int height,
f96e0b
     case 4:
f96e0b
     case 8:
f96e0b
       framebuffer.mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR;
f96e0b
+      framebuffer.mode_info.number_of_colors = 16;
f96e0b
       break;
f96e0b
     case 16:
f96e0b
       framebuffer.mode_info.red_mask_size = 5;
f96e0b
diff --git a/grub-core/video/cirrus.c b/grub-core/video/cirrus.c
f96e0b
index 073c54e..00e6516 100644
f96e0b
--- a/grub-core/video/cirrus.c
f96e0b
+++ b/grub-core/video/cirrus.c
f96e0b
@@ -295,15 +295,14 @@ grub_video_cirrus_setup (unsigned int width, unsigned int height,
f96e0b
       && !grub_video_check_mode_flag (mode_type, mode_mask,
f96e0b
 				      GRUB_VIDEO_MODE_TYPE_INDEX_COLOR, 0))
f96e0b
     depth = 24;
f96e0b
-
f96e0b
-  if (depth == 0)
f96e0b
+  else if (depth == 0)
f96e0b
     depth = 8;
f96e0b
 
f96e0b
   if (depth != 32 && depth != 24 && depth != 16 && depth != 15 && depth != 8)
f96e0b
     return grub_error (GRUB_ERR_IO, "only 32, 24, 16, 15 and 8-bit bpp are"
f96e0b
 		       " supported by cirrus video");
f96e0b
 
f96e0b
-  bytes_per_pixel = (depth + 7) / 8;
f96e0b
+  bytes_per_pixel = (depth + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT;
f96e0b
   pitch = width * bytes_per_pixel;
f96e0b
 
f96e0b
   if (pitch > CIRRUS_MAX_PITCH)
f96e0b
@@ -411,6 +410,7 @@ grub_video_cirrus_setup (unsigned int width, unsigned int height,
f96e0b
     {
f96e0b
     case 8:
f96e0b
       framebuffer.mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR;
f96e0b
+      framebuffer.mode_info.number_of_colors = 16;
f96e0b
       break;
f96e0b
     case 16:
f96e0b
       framebuffer.mode_info.red_mask_size = 5;
f96e0b
diff --git a/grub-core/video/efi_uga.c b/grub-core/video/efi_uga.c
f96e0b
index 695f015..159df8e 100644
f96e0b
--- a/grub-core/video/efi_uga.c
f96e0b
+++ b/grub-core/video/efi_uga.c
f96e0b
@@ -247,7 +247,7 @@ grub_video_uga_setup (unsigned int width, unsigned int height,
f96e0b
       framebuffer.mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_RGB;
f96e0b
       framebuffer.mode_info.bpp = 32;
f96e0b
       framebuffer.mode_info.bytes_per_pixel = 4;
f96e0b
-      framebuffer.mode_info.number_of_colors = 256; /* TODO: fix me.  */
f96e0b
+      framebuffer.mode_info.number_of_colors = 256;
f96e0b
       framebuffer.mode_info.red_mask_size = 8;
f96e0b
       framebuffer.mode_info.red_field_pos = 16;
f96e0b
       framebuffer.mode_info.green_mask_size = 8;
f96e0b
diff --git a/grub-core/video/emu/sdl.c b/grub-core/video/emu/sdl.c
f96e0b
index f4c1a6a..6fd01be 100644
f96e0b
--- a/grub-core/video/emu/sdl.c
f96e0b
+++ b/grub-core/video/emu/sdl.c
f96e0b
@@ -151,8 +151,7 @@ grub_video_sdl_setup (unsigned int width, unsigned int height,
f96e0b
     return err;
f96e0b
 
f96e0b
   /* Copy default palette to initialize emulated palette.  */
f96e0b
-  grub_video_sdl_set_palette (0, (sizeof (grub_video_fbstd_colors)
f96e0b
-				  / sizeof (grub_video_fbstd_colors[0])),
f96e0b
+  grub_video_sdl_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS,
f96e0b
 			      grub_video_fbstd_colors);
f96e0b
 
f96e0b
   /* Reset render target to SDL one.  */
f96e0b
@@ -166,7 +165,14 @@ grub_video_sdl_set_palette (unsigned int start, unsigned int count,
f96e0b
   unsigned i;
f96e0b
   if (window->format->palette)
f96e0b
     {
f96e0b
-      SDL_Color *tmp = grub_malloc (count * sizeof (tmp[0]));
f96e0b
+      SDL_Color *tmp;
f96e0b
+      if (start >= mode_info.number_of_colors)
f96e0b
+	return GRUB_ERR_NONE;
f96e0b
+
f96e0b
+      if (start + count > mode_info.number_of_colors)
f96e0b
+	count = mode_info.number_of_colors - start;
f96e0b
+
f96e0b
+      tmp = grub_malloc (count * sizeof (tmp[0]));
f96e0b
       for (i = 0; i < count; i++)
f96e0b
 	{
f96e0b
 	  tmp[i].r = palette_data[i].r;
f96e0b
diff --git a/grub-core/video/fb/fbblit.c b/grub-core/video/fb/fbblit.c
f96e0b
index 4d262d7..13e2926 100644
f96e0b
--- a/grub-core/video/fb/fbblit.c
f96e0b
+++ b/grub-core/video/fb/fbblit.c
f96e0b
@@ -416,15 +416,25 @@ grub_video_fbblit_replace_BGRX8888_RGBX8888 (struct grub_video_fbblit_info *dst,
f96e0b
     {
f96e0b
       for (i = 0; i < width; i++)
f96e0b
         {
f96e0b
+#ifdef GRUB_CPU_WORDS_BIGENDIAN
f96e0b
+          grub_uint8_t a = *srcptr++;
f96e0b
+#endif
f96e0b
           grub_uint8_t r = *srcptr++;
f96e0b
           grub_uint8_t g = *srcptr++;
f96e0b
           grub_uint8_t b = *srcptr++;
f96e0b
+#ifndef GRUB_CPU_WORDS_BIGENDIAN
f96e0b
           grub_uint8_t a = *srcptr++;
f96e0b
+#endif
f96e0b
 
f96e0b
+#ifdef GRUB_CPU_WORDS_BIGENDIAN
f96e0b
+          *dstptr++ = a;
f96e0b
+#endif
f96e0b
           *dstptr++ = b;
f96e0b
           *dstptr++ = g;
f96e0b
           *dstptr++ = r;
f96e0b
+#ifndef GRUB_CPU_WORDS_BIGENDIAN
f96e0b
           *dstptr++ = a;
f96e0b
+#endif
f96e0b
         }
f96e0b
 
f96e0b
       srcptr += srcrowskip;
f96e0b
@@ -463,12 +473,19 @@ grub_video_fbblit_replace_BGRX8888_RGB888 (struct grub_video_fbblit_info *dst,
f96e0b
           grub_uint8_t g = *srcptr++;
f96e0b
           grub_uint8_t b = *srcptr++;
f96e0b
 
f96e0b
+#ifdef GRUB_CPU_WORDS_BIGENDIAN
f96e0b
+          /* Set alpha component as opaque.  */
f96e0b
+          *dstptr++ = 255;
f96e0b
+#endif
f96e0b
+
f96e0b
           *dstptr++ = b;
f96e0b
           *dstptr++ = g;
f96e0b
           *dstptr++ = r;
f96e0b
 
f96e0b
+#ifndef GRUB_CPU_WORDS_BIGENDIAN
f96e0b
           /* Set alpha component as opaque.  */
f96e0b
           *dstptr++ = 255;
f96e0b
+#endif
f96e0b
         }
f96e0b
 
f96e0b
       srcptr += srcrowskip;
f96e0b
@@ -514,9 +531,15 @@ grub_video_fbblit_replace_BGR888_RGBX8888 (struct grub_video_fbblit_info *dst,
f96e0b
           sg = (color >> 8) & 0xFF;
f96e0b
           sb = (color >> 16) & 0xFF;
f96e0b
 
f96e0b
+#ifdef GRUB_CPU_WORDS_BIGENDIAN
f96e0b
+          *dstptr++ = sr;
f96e0b
+          *dstptr++ = sg;
f96e0b
+          *dstptr++ = sb;
f96e0b
+#else
f96e0b
           *dstptr++ = sb;
f96e0b
           *dstptr++ = sg;
f96e0b
           *dstptr++ = sr;
f96e0b
+#endif
f96e0b
         }
f96e0b
 
f96e0b
       GRUB_VIDEO_FB_ADVANCE_POINTER (srcptr, srcrowskip);
f96e0b
@@ -593,10 +616,15 @@ grub_video_fbblit_replace_RGBX8888_RGB888 (struct grub_video_fbblit_info *dst,
f96e0b
     {
f96e0b
       for (i = 0; i < width; i++)
f96e0b
         {
f96e0b
+#ifdef GRUB_CPU_WORDS_BIGENDIAN
f96e0b
+          sb = *srcptr++;
f96e0b
+          sg = *srcptr++;
f96e0b
+          sr = *srcptr++;
f96e0b
+#else
f96e0b
           sr = *srcptr++;
f96e0b
           sg = *srcptr++;
f96e0b
           sb = *srcptr++;
f96e0b
-
f96e0b
+#endif
f96e0b
           /* Set alpha as opaque.  */
f96e0b
           color = 0xFF000000 | (sb << 16) | (sg << 8) | sr;
f96e0b
 
f96e0b
@@ -641,9 +669,15 @@ grub_video_fbblit_replace_RGB888_RGBX8888 (struct grub_video_fbblit_info *dst,
f96e0b
 	  sg = (color >> 8) & 0xFF;
f96e0b
 	  sb = (color >> 16) & 0xFF;
f96e0b
 
f96e0b
+#ifndef GRUB_CPU_WORDS_BIGENDIAN
f96e0b
 	  *dstptr++ = sr;
f96e0b
 	  *dstptr++ = sg;
f96e0b
 	  *dstptr++ = sb;
f96e0b
+#else
f96e0b
+	  *dstptr++ = sb;
f96e0b
+	  *dstptr++ = sg;
f96e0b
+	  *dstptr++ = sr;
f96e0b
+#endif
f96e0b
 	}
f96e0b
       GRUB_VIDEO_FB_ADVANCE_POINTER (srcptr, srcrowskip);
f96e0b
       GRUB_VIDEO_FB_ADVANCE_POINTER (dstptr, dstrowskip);
f96e0b
@@ -681,9 +715,15 @@ grub_video_fbblit_replace_index_RGBX8888 (struct grub_video_fbblit_info *dst,
f96e0b
 	{
f96e0b
 	  color = *srcptr++;
f96e0b
 
f96e0b
+#ifdef GRUB_CPU_WORDS_BIGENDIAN
f96e0b
+	  sb = (color >> 0) & 0xFF;
f96e0b
+	  sg = (color >> 8) & 0xFF;
f96e0b
+	  sr = (color >> 16) & 0xFF;
f96e0b
+#else
f96e0b
 	  sr = (color >> 0) & 0xFF;
f96e0b
 	  sg = (color >> 8) & 0xFF;
f96e0b
 	  sb = (color >> 16) & 0xFF;
f96e0b
+#endif
f96e0b
 
f96e0b
 	  color = grub_video_fb_map_rgb(sr, sg, sb);
f96e0b
 	  *dstptr++ = color & 0xFF;
f96e0b
@@ -722,9 +762,15 @@ grub_video_fbblit_replace_index_RGB888 (struct grub_video_fbblit_info *dst,
f96e0b
     {
f96e0b
       for (i = 0; i < width; i++)
f96e0b
         {
f96e0b
+#ifndef GRUB_CPU_WORDS_BIGENDIAN
f96e0b
           sr = *srcptr++;
f96e0b
           sg = *srcptr++;
f96e0b
           sb = *srcptr++;
f96e0b
+#else
f96e0b
+          sb = *srcptr++;
f96e0b
+          sg = *srcptr++;
f96e0b
+          sr = *srcptr++;
f96e0b
+#endif
f96e0b
 
f96e0b
           color = grub_video_fb_map_rgb(sr, sg, sb);
f96e0b
 
f96e0b
@@ -948,9 +994,15 @@ grub_video_fbblit_blend_BGR888_RGBA8888 (struct grub_video_fbblit_info *dst,
f96e0b
               dr = (dr * (255 - a) + sr * a) / 255;
f96e0b
             }
f96e0b
 
f96e0b
+#ifndef GRUB_CPU_WORDS_BIGENDIAN
f96e0b
           *dstptr++ = db;
f96e0b
           *dstptr++ = dg;
f96e0b
           *dstptr++ = dr;
f96e0b
+#else
f96e0b
+          *dstptr++ = dr;
f96e0b
+          *dstptr++ = dg;
f96e0b
+          *dstptr++ = db;
f96e0b
+#endif
f96e0b
         }
f96e0b
 
f96e0b
       GRUB_VIDEO_FB_ADVANCE_POINTER (srcptr, srcrowskip);
f96e0b
@@ -1079,24 +1131,42 @@ grub_video_fbblit_blend_RGB888_RGBA8888 (struct grub_video_fbblit_info *dst,
f96e0b
 
f96e0b
           if (a == 255)
f96e0b
             {
f96e0b
+#ifndef GRUB_CPU_WORDS_BIGENDIAN
f96e0b
               *dstptr++ = sr;
f96e0b
               *dstptr++ = sg;
f96e0b
               *dstptr++ = sb;
f96e0b
+#else
f96e0b
+              *dstptr++ = sb;
f96e0b
+              *dstptr++ = sg;
f96e0b
+              *dstptr++ = sr;
f96e0b
+#endif
f96e0b
 
f96e0b
               continue;
f96e0b
             }
f96e0b
 
f96e0b
+#ifndef GRUB_CPU_WORDS_BIGENDIAN
f96e0b
+          db = dstptr[0];
f96e0b
+          dg = dstptr[1];
f96e0b
+          dr = dstptr[2];
f96e0b
+#else
f96e0b
           dr = dstptr[0];
f96e0b
           dg = dstptr[1];
f96e0b
           db = dstptr[2];
f96e0b
+#endif
f96e0b
 
f96e0b
           dr = (dr * (255 - a) + sr * a) / 255;
f96e0b
           dg = (dg * (255 - a) + sg * a) / 255;
f96e0b
           db = (db * (255 - a) + sb * a) / 255;
f96e0b
 
f96e0b
+#ifndef GRUB_CPU_WORDS_BIGENDIAN
f96e0b
           *dstptr++ = dr;
f96e0b
           *dstptr++ = dg;
f96e0b
           *dstptr++ = db;
f96e0b
+#else
f96e0b
+          *dstptr++ = db;
f96e0b
+          *dstptr++ = dg;
f96e0b
+          *dstptr++ = dr;
f96e0b
+#endif
f96e0b
         }
f96e0b
       GRUB_VIDEO_FB_ADVANCE_POINTER (srcptr, srcrowskip);
f96e0b
       GRUB_VIDEO_FB_ADVANCE_POINTER (dstptr, dstrowskip);
f96e0b
@@ -1330,9 +1400,15 @@ grub_video_fbblit_blend_XXX888_1bit (struct grub_video_fbblit_info *dst,
f96e0b
 
f96e0b
 	  if (a == 255)
f96e0b
 	    {
f96e0b
+#ifndef GRUB_CPU_WORDS_BIGENDIAN
f96e0b
 	      ((grub_uint8_t *) dstptr)[0] = color & 0xff;
f96e0b
 	      ((grub_uint8_t *) dstptr)[1] = (color & 0xff00) >> 8;
f96e0b
 	      ((grub_uint8_t *) dstptr)[2] = (color & 0xff0000) >> 16;
f96e0b
+#else
f96e0b
+	      ((grub_uint8_t *) dstptr)[2] = color & 0xff;
f96e0b
+	      ((grub_uint8_t *) dstptr)[1] = (color & 0xff00) >> 8;
f96e0b
+	      ((grub_uint8_t *) dstptr)[0] = (color & 0xff0000) >> 16;
f96e0b
+#endif
f96e0b
 	    }
f96e0b
 	  else if (a != 0)
f96e0b
 	    {
f96e0b
diff --git a/grub-core/video/fb/fbfill.c b/grub-core/video/fb/fbfill.c
f96e0b
index 5f3e55f..74b157b 100644
f96e0b
--- a/grub-core/video/fb/fbfill.c
f96e0b
+++ b/grub-core/video/fb/fbfill.c
f96e0b
@@ -87,10 +87,15 @@ grub_video_fbfill_direct24 (struct grub_video_fbblit_info *dst,
f96e0b
   int j;
f96e0b
   grub_size_t rowskip;
f96e0b
   grub_uint8_t *dstptr;
f96e0b
+#ifndef GRUB_CPU_WORDS_BIGENDIAN
f96e0b
   grub_uint8_t fill0 = (grub_uint8_t)((color >> 0) & 0xFF);
f96e0b
   grub_uint8_t fill1 = (grub_uint8_t)((color >> 8) & 0xFF);
f96e0b
   grub_uint8_t fill2 = (grub_uint8_t)((color >> 16) & 0xFF);
f96e0b
-
f96e0b
+#else
f96e0b
+  grub_uint8_t fill2 = (grub_uint8_t)((color >> 0) & 0xFF);
f96e0b
+  grub_uint8_t fill1 = (grub_uint8_t)((color >> 8) & 0xFF);
f96e0b
+  grub_uint8_t fill0 = (grub_uint8_t)((color >> 16) & 0xFF);
f96e0b
+#endif
f96e0b
   /* Calculate the number of bytes to advance from the end of one line
f96e0b
      to the beginning of the next line.  */
f96e0b
   rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
f96e0b
@@ -122,13 +127,11 @@ grub_video_fbfill_direct16 (struct grub_video_fbblit_info *dst,
f96e0b
   int i;
f96e0b
   int j;
f96e0b
   grub_size_t rowskip;
f96e0b
-  grub_uint8_t *dstptr;
f96e0b
-  grub_uint8_t fill0 = (grub_uint8_t)((color >> 0) & 0xFF);
f96e0b
-  grub_uint8_t fill1 = (grub_uint8_t)((color >> 8) & 0xFF);
f96e0b
+  grub_uint16_t *dstptr;
f96e0b
 
f96e0b
   /* Calculate the number of bytes to advance from the end of one line
f96e0b
      to the beginning of the next line.  */
f96e0b
-  rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
f96e0b
+  rowskip = (dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width);
f96e0b
 
f96e0b
   /* Get the start address.  */
f96e0b
   dstptr = grub_video_fb_get_video_ptr (dst, x, y);
f96e0b
@@ -136,13 +139,10 @@ grub_video_fbfill_direct16 (struct grub_video_fbblit_info *dst,
f96e0b
   for (j = 0; j < height; j++)
f96e0b
     {
f96e0b
       for (i = 0; i < width; i++)
f96e0b
-        {
f96e0b
-          *dstptr++ = fill0;
f96e0b
-          *dstptr++ = fill1;
f96e0b
-        }
f96e0b
+	*dstptr++ = color;
f96e0b
 
f96e0b
       /* Advance the dest pointer to the right location on the next line.  */
f96e0b
-      dstptr += rowskip;
f96e0b
+      GRUB_VIDEO_FB_ADVANCE_POINTER (dstptr, rowskip);
f96e0b
     }
f96e0b
 }
f96e0b
 
f96e0b
diff --git a/grub-core/video/fb/fbutil.c b/grub-core/video/fb/fbutil.c
f96e0b
index c7fb087..81b3860 100644
f96e0b
--- a/grub-core/video/fb/fbutil.c
f96e0b
+++ b/grub-core/video/fb/fbutil.c
f96e0b
@@ -82,7 +82,11 @@ get_pixel (struct grub_video_fbblit_info *source,
f96e0b
       {
f96e0b
         grub_uint8_t *ptr;
f96e0b
         ptr = grub_video_fb_get_video_ptr (source, x, y);
f96e0b
+#ifdef GRUB_CPU_WORDS_BIGENDIAN
f96e0b
+        color = ptr[2] | (ptr[1] << 8) | (ptr[0] << 16);
f96e0b
+#else
f96e0b
         color = ptr[0] | (ptr[1] << 8) | (ptr[2] << 16);
f96e0b
+#endif
f96e0b
       }
f96e0b
       break;
f96e0b
 
f96e0b
@@ -131,7 +135,11 @@ set_pixel (struct grub_video_fbblit_info *source,
f96e0b
     case 24:
f96e0b
       {
f96e0b
         grub_uint8_t *ptr;
f96e0b
+#ifdef GRUB_CPU_WORDS_BIGENDIAN
f96e0b
+        grub_uint8_t *colorptr = ((grub_uint8_t *)&color) + 1;
f96e0b
+#else
f96e0b
         grub_uint8_t *colorptr = (grub_uint8_t *)&color;
f96e0b
+#endif
f96e0b
 
f96e0b
         ptr = grub_video_fb_get_video_ptr (source, x, y);
f96e0b
 
f96e0b
diff --git a/grub-core/video/fb/video_fb.c b/grub-core/video/fb/video_fb.c
f96e0b
index cfe441f..836842e 100644
f96e0b
--- a/grub-core/video/fb/video_fb.c
f96e0b
+++ b/grub-core/video/fb/video_fb.c
f96e0b
@@ -59,8 +59,10 @@ static struct
f96e0b
 
f96e0b
 /* Specify "standard" VGA palette, some video cards may
f96e0b
    need this and this will also be used when using RGB modes.  */
f96e0b
-struct grub_video_palette_data grub_video_fbstd_colors[GRUB_VIDEO_FBSTD_NUMCOLORS] =
f96e0b
+struct grub_video_palette_data grub_video_fbstd_colors[GRUB_VIDEO_FBSTD_EXT_NUMCOLORS] =
f96e0b
   {
f96e0b
+    /* Standard (3-bit) colors.  */
f96e0b
+
f96e0b
     // {R, G, B, A}
f96e0b
     {0x00, 0x00, 0x00, 0xFF}, // 0 = black
f96e0b
     {0x00, 0x00, 0xA8, 0xFF}, // 1 = blue
f96e0b
@@ -71,6 +73,7 @@ struct grub_video_palette_data grub_video_fbstd_colors[GRUB_VIDEO_FBSTD_NUMCOLOR
f96e0b
     {0xA8, 0x54, 0x00, 0xFF}, // 6 = brown
f96e0b
     {0xA8, 0xA8, 0xA8, 0xFF}, // 7 = light gray
f96e0b
 
f96e0b
+    /* Bright (4-bit) colors.  */
f96e0b
     {0x54, 0x54, 0x54, 0xFF}, // 8 = dark gray
f96e0b
     {0x54, 0x54, 0xFE, 0xFF}, // 9 = bright blue
f96e0b
     {0x54, 0xFE, 0x54, 0xFF}, // 10 = bright green
f96e0b
@@ -78,7 +81,249 @@ struct grub_video_palette_data grub_video_fbstd_colors[GRUB_VIDEO_FBSTD_NUMCOLOR
f96e0b
     {0xFE, 0x54, 0x54, 0xFF}, // 12 = bright red
f96e0b
     {0xFE, 0x54, 0xFE, 0xFF}, // 13 = bright magenta
f96e0b
     {0xFE, 0xFE, 0x54, 0xFF}, // 14 = yellow
f96e0b
-    {0xFE, 0xFE, 0xFE, 0xFF}  // 15 = white
f96e0b
+    {0xFE, 0xFE, 0xFE, 0xFF}, // 15 = white
f96e0b
+
f96e0b
+    /* Extended (8-bit) colors. Completes preceding colors to full RGB332.  */
f96e0b
+    {0x00, 0x00, 0x55, 0xFF}, // RGB332 = (0, 0, 1)
f96e0b
+    {0x00, 0x00, 0xFF, 0xFF}, // RGB332 = (0, 0, 3)
f96e0b
+    {0x00, 0x24, 0x00, 0xFF}, // RGB332 = (0, 1, 0)
f96e0b
+    {0x00, 0x24, 0x55, 0xFF}, // RGB332 = (0, 1, 1)
f96e0b
+    {0x00, 0x24, 0xAA, 0xFF}, // RGB332 = (0, 1, 2)
f96e0b
+    {0x00, 0x24, 0xFF, 0xFF}, // RGB332 = (0, 1, 3)
f96e0b
+    {0x00, 0x48, 0x00, 0xFF}, // RGB332 = (0, 2, 0)
f96e0b
+    {0x00, 0x48, 0x55, 0xFF}, // RGB332 = (0, 2, 1)
f96e0b
+    {0x00, 0x48, 0xAA, 0xFF}, // RGB332 = (0, 2, 2)
f96e0b
+    {0x00, 0x48, 0xFF, 0xFF}, // RGB332 = (0, 2, 3)
f96e0b
+    {0x00, 0x6C, 0x00, 0xFF}, // RGB332 = (0, 3, 0)
f96e0b
+    {0x00, 0x6C, 0x55, 0xFF}, // RGB332 = (0, 3, 1)
f96e0b
+    {0x00, 0x6C, 0xAA, 0xFF}, // RGB332 = (0, 3, 2)
f96e0b
+    {0x00, 0x6C, 0xFF, 0xFF}, // RGB332 = (0, 3, 3)
f96e0b
+    {0x00, 0x90, 0x00, 0xFF}, // RGB332 = (0, 4, 0)
f96e0b
+    {0x00, 0x90, 0x55, 0xFF}, // RGB332 = (0, 4, 1)
f96e0b
+    {0x00, 0x90, 0xAA, 0xFF}, // RGB332 = (0, 4, 2)
f96e0b
+    {0x00, 0x90, 0xFF, 0xFF}, // RGB332 = (0, 4, 3)
f96e0b
+    {0x00, 0xB4, 0x55, 0xFF}, // RGB332 = (0, 5, 1)
f96e0b
+    {0x00, 0xB4, 0xFF, 0xFF}, // RGB332 = (0, 5, 3)
f96e0b
+    {0x00, 0xD8, 0x00, 0xFF}, // RGB332 = (0, 6, 0)
f96e0b
+    {0x00, 0xD8, 0x55, 0xFF}, // RGB332 = (0, 6, 1)
f96e0b
+    {0x00, 0xD8, 0xAA, 0xFF}, // RGB332 = (0, 6, 2)
f96e0b
+    {0x00, 0xD8, 0xFF, 0xFF}, // RGB332 = (0, 6, 3)
f96e0b
+    {0x00, 0xFC, 0x00, 0xFF}, // RGB332 = (0, 7, 0)
f96e0b
+    {0x00, 0xFC, 0x55, 0xFF}, // RGB332 = (0, 7, 1)
f96e0b
+    {0x00, 0xFC, 0xAA, 0xFF}, // RGB332 = (0, 7, 2)
f96e0b
+    {0x00, 0xFC, 0xFF, 0xFF}, // RGB332 = (0, 7, 3)
f96e0b
+    {0x24, 0x00, 0x00, 0xFF}, // RGB332 = (1, 0, 0)
f96e0b
+    {0x24, 0x00, 0x55, 0xFF}, // RGB332 = (1, 0, 1)
f96e0b
+    {0x24, 0x00, 0xAA, 0xFF}, // RGB332 = (1, 0, 2)
f96e0b
+    {0x24, 0x00, 0xFF, 0xFF}, // RGB332 = (1, 0, 3)
f96e0b
+    {0x24, 0x24, 0x00, 0xFF}, // RGB332 = (1, 1, 0)
f96e0b
+    {0x24, 0x24, 0x55, 0xFF}, // RGB332 = (1, 1, 1)
f96e0b
+    {0x24, 0x24, 0xAA, 0xFF}, // RGB332 = (1, 1, 2)
f96e0b
+    {0x24, 0x24, 0xFF, 0xFF}, // RGB332 = (1, 1, 3)
f96e0b
+    {0x24, 0x48, 0x00, 0xFF}, // RGB332 = (1, 2, 0)
f96e0b
+    {0x24, 0x48, 0x55, 0xFF}, // RGB332 = (1, 2, 1)
f96e0b
+    {0x24, 0x48, 0xAA, 0xFF}, // RGB332 = (1, 2, 2)
f96e0b
+    {0x24, 0x48, 0xFF, 0xFF}, // RGB332 = (1, 2, 3)
f96e0b
+    {0x24, 0x6C, 0x00, 0xFF}, // RGB332 = (1, 3, 0)
f96e0b
+    {0x24, 0x6C, 0x55, 0xFF}, // RGB332 = (1, 3, 1)
f96e0b
+    {0x24, 0x6C, 0xAA, 0xFF}, // RGB332 = (1, 3, 2)
f96e0b
+    {0x24, 0x6C, 0xFF, 0xFF}, // RGB332 = (1, 3, 3)
f96e0b
+    {0x24, 0x90, 0x00, 0xFF}, // RGB332 = (1, 4, 0)
f96e0b
+    {0x24, 0x90, 0x55, 0xFF}, // RGB332 = (1, 4, 1)
f96e0b
+    {0x24, 0x90, 0xAA, 0xFF}, // RGB332 = (1, 4, 2)
f96e0b
+    {0x24, 0x90, 0xFF, 0xFF}, // RGB332 = (1, 4, 3)
f96e0b
+    {0x24, 0xB4, 0x00, 0xFF}, // RGB332 = (1, 5, 0)
f96e0b
+    {0x24, 0xB4, 0x55, 0xFF}, // RGB332 = (1, 5, 1)
f96e0b
+    {0x24, 0xB4, 0xAA, 0xFF}, // RGB332 = (1, 5, 2)
f96e0b
+    {0x24, 0xB4, 0xFF, 0xFF}, // RGB332 = (1, 5, 3)
f96e0b
+    {0x24, 0xD8, 0x00, 0xFF}, // RGB332 = (1, 6, 0)
f96e0b
+    {0x24, 0xD8, 0x55, 0xFF}, // RGB332 = (1, 6, 1)
f96e0b
+    {0x24, 0xD8, 0xAA, 0xFF}, // RGB332 = (1, 6, 2)
f96e0b
+    {0x24, 0xD8, 0xFF, 0xFF}, // RGB332 = (1, 6, 3)
f96e0b
+    {0x24, 0xFC, 0x00, 0xFF}, // RGB332 = (1, 7, 0)
f96e0b
+    {0x24, 0xFC, 0x55, 0xFF}, // RGB332 = (1, 7, 1)
f96e0b
+    {0x24, 0xFC, 0xAA, 0xFF}, // RGB332 = (1, 7, 2)
f96e0b
+    {0x24, 0xFC, 0xFF, 0xFF}, // RGB332 = (1, 7, 3)
f96e0b
+    {0x48, 0x00, 0x00, 0xFF}, // RGB332 = (2, 0, 0)
f96e0b
+    {0x48, 0x00, 0x55, 0xFF}, // RGB332 = (2, 0, 1)
f96e0b
+    {0x48, 0x00, 0xAA, 0xFF}, // RGB332 = (2, 0, 2)
f96e0b
+    {0x48, 0x00, 0xFF, 0xFF}, // RGB332 = (2, 0, 3)
f96e0b
+    {0x48, 0x24, 0x00, 0xFF}, // RGB332 = (2, 1, 0)
f96e0b
+    {0x48, 0x24, 0x55, 0xFF}, // RGB332 = (2, 1, 1)
f96e0b
+    {0x48, 0x24, 0xAA, 0xFF}, // RGB332 = (2, 1, 2)
f96e0b
+    {0x48, 0x24, 0xFF, 0xFF}, // RGB332 = (2, 1, 3)
f96e0b
+    {0x48, 0x48, 0x00, 0xFF}, // RGB332 = (2, 2, 0)
f96e0b
+    {0x48, 0x48, 0xAA, 0xFF}, // RGB332 = (2, 2, 2)
f96e0b
+    {0x48, 0x6C, 0x00, 0xFF}, // RGB332 = (2, 3, 0)
f96e0b
+    {0x48, 0x6C, 0x55, 0xFF}, // RGB332 = (2, 3, 1)
f96e0b
+    {0x48, 0x6C, 0xAA, 0xFF}, // RGB332 = (2, 3, 2)
f96e0b
+    {0x48, 0x6C, 0xFF, 0xFF}, // RGB332 = (2, 3, 3)
f96e0b
+    {0x48, 0x90, 0x00, 0xFF}, // RGB332 = (2, 4, 0)
f96e0b
+    {0x48, 0x90, 0x55, 0xFF}, // RGB332 = (2, 4, 1)
f96e0b
+    {0x48, 0x90, 0xAA, 0xFF}, // RGB332 = (2, 4, 2)
f96e0b
+    {0x48, 0x90, 0xFF, 0xFF}, // RGB332 = (2, 4, 3)
f96e0b
+    {0x48, 0xB4, 0x00, 0xFF}, // RGB332 = (2, 5, 0)
f96e0b
+    {0x48, 0xB4, 0x55, 0xFF}, // RGB332 = (2, 5, 1)
f96e0b
+    {0x48, 0xB4, 0xAA, 0xFF}, // RGB332 = (2, 5, 2)
f96e0b
+    {0x48, 0xB4, 0xFF, 0xFF}, // RGB332 = (2, 5, 3)
f96e0b
+    {0x48, 0xD8, 0x00, 0xFF}, // RGB332 = (2, 6, 0)
f96e0b
+    {0x48, 0xD8, 0x55, 0xFF}, // RGB332 = (2, 6, 1)
f96e0b
+    {0x48, 0xD8, 0xAA, 0xFF}, // RGB332 = (2, 6, 2)
f96e0b
+    {0x48, 0xD8, 0xFF, 0xFF}, // RGB332 = (2, 6, 3)
f96e0b
+    {0x48, 0xFC, 0x00, 0xFF}, // RGB332 = (2, 7, 0)
f96e0b
+    {0x48, 0xFC, 0xAA, 0xFF}, // RGB332 = (2, 7, 2)
f96e0b
+    {0x6C, 0x00, 0x00, 0xFF}, // RGB332 = (3, 0, 0)
f96e0b
+    {0x6C, 0x00, 0x55, 0xFF}, // RGB332 = (3, 0, 1)
f96e0b
+    {0x6C, 0x00, 0xAA, 0xFF}, // RGB332 = (3, 0, 2)
f96e0b
+    {0x6C, 0x00, 0xFF, 0xFF}, // RGB332 = (3, 0, 3)
f96e0b
+    {0x6C, 0x24, 0x00, 0xFF}, // RGB332 = (3, 1, 0)
f96e0b
+    {0x6C, 0x24, 0x55, 0xFF}, // RGB332 = (3, 1, 1)
f96e0b
+    {0x6C, 0x24, 0xAA, 0xFF}, // RGB332 = (3, 1, 2)
f96e0b
+    {0x6C, 0x24, 0xFF, 0xFF}, // RGB332 = (3, 1, 3)
f96e0b
+    {0x6C, 0x48, 0x00, 0xFF}, // RGB332 = (3, 2, 0)
f96e0b
+    {0x6C, 0x48, 0x55, 0xFF}, // RGB332 = (3, 2, 1)
f96e0b
+    {0x6C, 0x48, 0xAA, 0xFF}, // RGB332 = (3, 2, 2)
f96e0b
+    {0x6C, 0x48, 0xFF, 0xFF}, // RGB332 = (3, 2, 3)
f96e0b
+    {0x6C, 0x6C, 0x00, 0xFF}, // RGB332 = (3, 3, 0)
f96e0b
+    {0x6C, 0x6C, 0x55, 0xFF}, // RGB332 = (3, 3, 1)
f96e0b
+    {0x6C, 0x6C, 0xAA, 0xFF}, // RGB332 = (3, 3, 2)
f96e0b
+    {0x6C, 0x6C, 0xFF, 0xFF}, // RGB332 = (3, 3, 3)
f96e0b
+    {0x6C, 0x90, 0x00, 0xFF}, // RGB332 = (3, 4, 0)
f96e0b
+    {0x6C, 0x90, 0x55, 0xFF}, // RGB332 = (3, 4, 1)
f96e0b
+    {0x6C, 0x90, 0xAA, 0xFF}, // RGB332 = (3, 4, 2)
f96e0b
+    {0x6C, 0x90, 0xFF, 0xFF}, // RGB332 = (3, 4, 3)
f96e0b
+    {0x6C, 0xB4, 0x00, 0xFF}, // RGB332 = (3, 5, 0)
f96e0b
+    {0x6C, 0xB4, 0x55, 0xFF}, // RGB332 = (3, 5, 1)
f96e0b
+    {0x6C, 0xB4, 0xAA, 0xFF}, // RGB332 = (3, 5, 2)
f96e0b
+    {0x6C, 0xB4, 0xFF, 0xFF}, // RGB332 = (3, 5, 3)
f96e0b
+    {0x6C, 0xD8, 0x00, 0xFF}, // RGB332 = (3, 6, 0)
f96e0b
+    {0x6C, 0xD8, 0x55, 0xFF}, // RGB332 = (3, 6, 1)
f96e0b
+    {0x6C, 0xD8, 0xAA, 0xFF}, // RGB332 = (3, 6, 2)
f96e0b
+    {0x6C, 0xD8, 0xFF, 0xFF}, // RGB332 = (3, 6, 3)
f96e0b
+    {0x6C, 0xFC, 0x00, 0xFF}, // RGB332 = (3, 7, 0)
f96e0b
+    {0x6C, 0xFC, 0x55, 0xFF}, // RGB332 = (3, 7, 1)
f96e0b
+    {0x6C, 0xFC, 0xAA, 0xFF}, // RGB332 = (3, 7, 2)
f96e0b
+    {0x6C, 0xFC, 0xFF, 0xFF}, // RGB332 = (3, 7, 3)
f96e0b
+    {0x90, 0x00, 0x00, 0xFF}, // RGB332 = (4, 0, 0)
f96e0b
+    {0x90, 0x00, 0x55, 0xFF}, // RGB332 = (4, 0, 1)
f96e0b
+    {0x90, 0x00, 0xAA, 0xFF}, // RGB332 = (4, 0, 2)
f96e0b
+    {0x90, 0x00, 0xFF, 0xFF}, // RGB332 = (4, 0, 3)
f96e0b
+    {0x90, 0x24, 0x00, 0xFF}, // RGB332 = (4, 1, 0)
f96e0b
+    {0x90, 0x24, 0x55, 0xFF}, // RGB332 = (4, 1, 1)
f96e0b
+    {0x90, 0x24, 0xAA, 0xFF}, // RGB332 = (4, 1, 2)
f96e0b
+    {0x90, 0x24, 0xFF, 0xFF}, // RGB332 = (4, 1, 3)
f96e0b
+    {0x90, 0x48, 0x00, 0xFF}, // RGB332 = (4, 2, 0)
f96e0b
+    {0x90, 0x48, 0x55, 0xFF}, // RGB332 = (4, 2, 1)
f96e0b
+    {0x90, 0x48, 0xAA, 0xFF}, // RGB332 = (4, 2, 2)
f96e0b
+    {0x90, 0x48, 0xFF, 0xFF}, // RGB332 = (4, 2, 3)
f96e0b
+    {0x90, 0x6C, 0x00, 0xFF}, // RGB332 = (4, 3, 0)
f96e0b
+    {0x90, 0x6C, 0x55, 0xFF}, // RGB332 = (4, 3, 1)
f96e0b
+    {0x90, 0x6C, 0xAA, 0xFF}, // RGB332 = (4, 3, 2)
f96e0b
+    {0x90, 0x6C, 0xFF, 0xFF}, // RGB332 = (4, 3, 3)
f96e0b
+    {0x90, 0x90, 0x00, 0xFF}, // RGB332 = (4, 4, 0)
f96e0b
+    {0x90, 0x90, 0x55, 0xFF}, // RGB332 = (4, 4, 1)
f96e0b
+    {0x90, 0x90, 0xAA, 0xFF}, // RGB332 = (4, 4, 2)
f96e0b
+    {0x90, 0x90, 0xFF, 0xFF}, // RGB332 = (4, 4, 3)
f96e0b
+    {0x90, 0xB4, 0x00, 0xFF}, // RGB332 = (4, 5, 0)
f96e0b
+    {0x90, 0xB4, 0x55, 0xFF}, // RGB332 = (4, 5, 1)
f96e0b
+    {0x90, 0xB4, 0xAA, 0xFF}, // RGB332 = (4, 5, 2)
f96e0b
+    {0x90, 0xB4, 0xFF, 0xFF}, // RGB332 = (4, 5, 3)
f96e0b
+    {0x90, 0xD8, 0x00, 0xFF}, // RGB332 = (4, 6, 0)
f96e0b
+    {0x90, 0xD8, 0x55, 0xFF}, // RGB332 = (4, 6, 1)
f96e0b
+    {0x90, 0xD8, 0xAA, 0xFF}, // RGB332 = (4, 6, 2)
f96e0b
+    {0x90, 0xD8, 0xFF, 0xFF}, // RGB332 = (4, 6, 3)
f96e0b
+    {0x90, 0xFC, 0x00, 0xFF}, // RGB332 = (4, 7, 0)
f96e0b
+    {0x90, 0xFC, 0x55, 0xFF}, // RGB332 = (4, 7, 1)
f96e0b
+    {0x90, 0xFC, 0xAA, 0xFF}, // RGB332 = (4, 7, 2)
f96e0b
+    {0x90, 0xFC, 0xFF, 0xFF}, // RGB332 = (4, 7, 3)
f96e0b
+    {0xB4, 0x00, 0x55, 0xFF}, // RGB332 = (5, 0, 1)
f96e0b
+    {0xB4, 0x00, 0xFF, 0xFF}, // RGB332 = (5, 0, 3)
f96e0b
+    {0xB4, 0x24, 0x00, 0xFF}, // RGB332 = (5, 1, 0)
f96e0b
+    {0xB4, 0x24, 0x55, 0xFF}, // RGB332 = (5, 1, 1)
f96e0b
+    {0xB4, 0x24, 0xAA, 0xFF}, // RGB332 = (5, 1, 2)
f96e0b
+    {0xB4, 0x24, 0xFF, 0xFF}, // RGB332 = (5, 1, 3)
f96e0b
+    {0xB4, 0x48, 0x55, 0xFF}, // RGB332 = (5, 2, 1)
f96e0b
+    {0xB4, 0x48, 0xAA, 0xFF}, // RGB332 = (5, 2, 2)
f96e0b
+    {0xB4, 0x48, 0xFF, 0xFF}, // RGB332 = (5, 2, 3)
f96e0b
+    {0xB4, 0x6C, 0x00, 0xFF}, // RGB332 = (5, 3, 0)
f96e0b
+    {0xB4, 0x6C, 0x55, 0xFF}, // RGB332 = (5, 3, 1)
f96e0b
+    {0xB4, 0x6C, 0xAA, 0xFF}, // RGB332 = (5, 3, 2)
f96e0b
+    {0xB4, 0x6C, 0xFF, 0xFF}, // RGB332 = (5, 3, 3)
f96e0b
+    {0xB4, 0x90, 0x00, 0xFF}, // RGB332 = (5, 4, 0)
f96e0b
+    {0xB4, 0x90, 0x55, 0xFF}, // RGB332 = (5, 4, 1)
f96e0b
+    {0xB4, 0x90, 0xAA, 0xFF}, // RGB332 = (5, 4, 2)
f96e0b
+    {0xB4, 0x90, 0xFF, 0xFF}, // RGB332 = (5, 4, 3)
f96e0b
+    {0xB4, 0xB4, 0x00, 0xFF}, // RGB332 = (5, 5, 0)
f96e0b
+    {0xB4, 0xB4, 0x55, 0xFF}, // RGB332 = (5, 5, 1)
f96e0b
+    {0xB4, 0xB4, 0xFF, 0xFF}, // RGB332 = (5, 5, 3)
f96e0b
+    {0xB4, 0xD8, 0x00, 0xFF}, // RGB332 = (5, 6, 0)
f96e0b
+    {0xB4, 0xD8, 0x55, 0xFF}, // RGB332 = (5, 6, 1)
f96e0b
+    {0xB4, 0xD8, 0xAA, 0xFF}, // RGB332 = (5, 6, 2)
f96e0b
+    {0xB4, 0xD8, 0xFF, 0xFF}, // RGB332 = (5, 6, 3)
f96e0b
+    {0xB4, 0xFC, 0x00, 0xFF}, // RGB332 = (5, 7, 0)
f96e0b
+    {0xB4, 0xFC, 0x55, 0xFF}, // RGB332 = (5, 7, 1)
f96e0b
+    {0xB4, 0xFC, 0xAA, 0xFF}, // RGB332 = (5, 7, 2)
f96e0b
+    {0xB4, 0xFC, 0xFF, 0xFF}, // RGB332 = (5, 7, 3)
f96e0b
+    {0xD8, 0x00, 0x00, 0xFF}, // RGB332 = (6, 0, 0)
f96e0b
+    {0xD8, 0x00, 0x55, 0xFF}, // RGB332 = (6, 0, 1)
f96e0b
+    {0xD8, 0x00, 0xAA, 0xFF}, // RGB332 = (6, 0, 2)
f96e0b
+    {0xD8, 0x00, 0xFF, 0xFF}, // RGB332 = (6, 0, 3)
f96e0b
+    {0xD8, 0x24, 0x00, 0xFF}, // RGB332 = (6, 1, 0)
f96e0b
+    {0xD8, 0x24, 0x55, 0xFF}, // RGB332 = (6, 1, 1)
f96e0b
+    {0xD8, 0x24, 0xAA, 0xFF}, // RGB332 = (6, 1, 2)
f96e0b
+    {0xD8, 0x24, 0xFF, 0xFF}, // RGB332 = (6, 1, 3)
f96e0b
+    {0xD8, 0x48, 0x00, 0xFF}, // RGB332 = (6, 2, 0)
f96e0b
+    {0xD8, 0x48, 0x55, 0xFF}, // RGB332 = (6, 2, 1)
f96e0b
+    {0xD8, 0x48, 0xAA, 0xFF}, // RGB332 = (6, 2, 2)
f96e0b
+    {0xD8, 0x48, 0xFF, 0xFF}, // RGB332 = (6, 2, 3)
f96e0b
+    {0xD8, 0x6C, 0x00, 0xFF}, // RGB332 = (6, 3, 0)
f96e0b
+    {0xD8, 0x6C, 0x55, 0xFF}, // RGB332 = (6, 3, 1)
f96e0b
+    {0xD8, 0x6C, 0xAA, 0xFF}, // RGB332 = (6, 3, 2)
f96e0b
+    {0xD8, 0x6C, 0xFF, 0xFF}, // RGB332 = (6, 3, 3)
f96e0b
+    {0xD8, 0x90, 0x00, 0xFF}, // RGB332 = (6, 4, 0)
f96e0b
+    {0xD8, 0x90, 0x55, 0xFF}, // RGB332 = (6, 4, 1)
f96e0b
+    {0xD8, 0x90, 0xAA, 0xFF}, // RGB332 = (6, 4, 2)
f96e0b
+    {0xD8, 0x90, 0xFF, 0xFF}, // RGB332 = (6, 4, 3)
f96e0b
+    {0xD8, 0xB4, 0x00, 0xFF}, // RGB332 = (6, 5, 0)
f96e0b
+    {0xD8, 0xB4, 0x55, 0xFF}, // RGB332 = (6, 5, 1)
f96e0b
+    {0xD8, 0xB4, 0xAA, 0xFF}, // RGB332 = (6, 5, 2)
f96e0b
+    {0xD8, 0xB4, 0xFF, 0xFF}, // RGB332 = (6, 5, 3)
f96e0b
+    {0xD8, 0xD8, 0x00, 0xFF}, // RGB332 = (6, 6, 0)
f96e0b
+    {0xD8, 0xD8, 0x55, 0xFF}, // RGB332 = (6, 6, 1)
f96e0b
+    {0xD8, 0xD8, 0xAA, 0xFF}, // RGB332 = (6, 6, 2)
f96e0b
+    {0xD8, 0xD8, 0xFF, 0xFF}, // RGB332 = (6, 6, 3)
f96e0b
+    {0xD8, 0xFC, 0x00, 0xFF}, // RGB332 = (6, 7, 0)
f96e0b
+    {0xD8, 0xFC, 0x55, 0xFF}, // RGB332 = (6, 7, 1)
f96e0b
+    {0xD8, 0xFC, 0xAA, 0xFF}, // RGB332 = (6, 7, 2)
f96e0b
+    {0xD8, 0xFC, 0xFF, 0xFF}, // RGB332 = (6, 7, 3)
f96e0b
+    {0xFC, 0x00, 0x00, 0xFF}, // RGB332 = (7, 0, 0)
f96e0b
+    {0xFC, 0x00, 0x55, 0xFF}, // RGB332 = (7, 0, 1)
f96e0b
+    {0xFC, 0x00, 0xAA, 0xFF}, // RGB332 = (7, 0, 2)
f96e0b
+    {0xFC, 0x00, 0xFF, 0xFF}, // RGB332 = (7, 0, 3)
f96e0b
+    {0xFC, 0x24, 0x00, 0xFF}, // RGB332 = (7, 1, 0)
f96e0b
+    {0xFC, 0x24, 0x55, 0xFF}, // RGB332 = (7, 1, 1)
f96e0b
+    {0xFC, 0x24, 0xAA, 0xFF}, // RGB332 = (7, 1, 2)
f96e0b
+    {0xFC, 0x24, 0xFF, 0xFF}, // RGB332 = (7, 1, 3)
f96e0b
+    {0xFC, 0x48, 0x00, 0xFF}, // RGB332 = (7, 2, 0)
f96e0b
+    {0xFC, 0x48, 0xAA, 0xFF}, // RGB332 = (7, 2, 2)
f96e0b
+    {0xFC, 0x6C, 0x00, 0xFF}, // RGB332 = (7, 3, 0)
f96e0b
+    {0xFC, 0x6C, 0x55, 0xFF}, // RGB332 = (7, 3, 1)
f96e0b
+    {0xFC, 0x6C, 0xAA, 0xFF}, // RGB332 = (7, 3, 2)
f96e0b
+    {0xFC, 0x6C, 0xFF, 0xFF}, // RGB332 = (7, 3, 3)
f96e0b
+    {0xFC, 0x90, 0x00, 0xFF}, // RGB332 = (7, 4, 0)
f96e0b
+    {0xFC, 0x90, 0x55, 0xFF}, // RGB332 = (7, 4, 1)
f96e0b
+    {0xFC, 0x90, 0xAA, 0xFF}, // RGB332 = (7, 4, 2)
f96e0b
+    {0xFC, 0x90, 0xFF, 0xFF}, // RGB332 = (7, 4, 3)
f96e0b
+    {0xFC, 0xB4, 0x00, 0xFF}, // RGB332 = (7, 5, 0)
f96e0b
+    {0xFC, 0xB4, 0x55, 0xFF}, // RGB332 = (7, 5, 1)
f96e0b
+    {0xFC, 0xB4, 0xAA, 0xFF}, // RGB332 = (7, 5, 2)
f96e0b
+    {0xFC, 0xB4, 0xFF, 0xFF}, // RGB332 = (7, 5, 3)
f96e0b
+    {0xFC, 0xD8, 0x00, 0xFF}, // RGB332 = (7, 6, 0)
f96e0b
+    {0xFC, 0xD8, 0x55, 0xFF}, // RGB332 = (7, 6, 1)
f96e0b
+    {0xFC, 0xD8, 0xAA, 0xFF}, // RGB332 = (7, 6, 2)
f96e0b
+    {0xFC, 0xD8, 0xFF, 0xFF}, // RGB332 = (7, 6, 3)
f96e0b
+    {0xFC, 0xFC, 0x00, 0xFF}, // RGB332 = (7, 7, 0)
f96e0b
+    {0xFC, 0xFC, 0xAA, 0xFF}, // RGB332 = (7, 7, 2)
f96e0b
   };
f96e0b
 
f96e0b
 grub_err_t
f96e0b
@@ -487,38 +732,21 @@ grub_video_fb_fill_rect (grub_video_color_t color, int x, int y,
f96e0b
 
f96e0b
   /* Try to figure out more optimized version.  Note that color is already
f96e0b
      mapped to target format so we can make assumptions based on that.  */
f96e0b
-  if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGRA_8888)
f96e0b
-    {
f96e0b
-      grub_video_fbfill_direct32 (&target, color, x, y,
f96e0b
-                                        width, height);
f96e0b
-      return GRUB_ERR_NONE;
f96e0b
-    }
f96e0b
-  else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGBA_8888)
f96e0b
+  switch (target.mode_info->bytes_per_pixel)
f96e0b
     {
f96e0b
+    case 4:
f96e0b
       grub_video_fbfill_direct32 (&target, color, x, y,
f96e0b
-                                        width, height);
f96e0b
+				  width, height);
f96e0b
       return GRUB_ERR_NONE;
f96e0b
-    }
f96e0b
-  else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_888)
f96e0b
-    {
f96e0b
+    case 3:
f96e0b
       grub_video_fbfill_direct24 (&target, color, x, y,
f96e0b
-                                        width, height);
f96e0b
+				  width, height);
f96e0b
       return GRUB_ERR_NONE;
f96e0b
-    }
f96e0b
-  else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_RGB_565)
f96e0b
-    {
f96e0b
+    case 2:
f96e0b
       grub_video_fbfill_direct16 (&target, color, x, y,
f96e0b
                                         width, height);
f96e0b
       return GRUB_ERR_NONE;
f96e0b
-    }
f96e0b
-  else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_BGR_565)
f96e0b
-    {
f96e0b
-      grub_video_fbfill_direct16 (&target, color, x, y,
f96e0b
-                                        width, height);
f96e0b
-      return GRUB_ERR_NONE;
f96e0b
-    }
f96e0b
-  else if (target.mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR)
f96e0b
-    {
f96e0b
+    case 1:
f96e0b
       grub_video_fbfill_direct8 (&target, color, x, y,
f96e0b
 				       width, height);
f96e0b
       return GRUB_ERR_NONE;
f96e0b
diff --git a/grub-core/video/i386/pc/vbe.c b/grub-core/video/i386/pc/vbe.c
f96e0b
index f112f15..6f7ede1 100644
f96e0b
--- a/grub-core/video/i386/pc/vbe.c
f96e0b
+++ b/grub-core/video/i386/pc/vbe.c
f96e0b
@@ -938,7 +938,10 @@ vbe2videoinfo (grub_uint32_t mode,
f96e0b
   else
f96e0b
     mode_info->pitch = vbeinfo->bytes_per_scan_line;
f96e0b
 
f96e0b
-  mode_info->number_of_colors = 256; /* TODO: fix me.  */
f96e0b
+  if (mode_info->mode_type & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR)
f96e0b
+    mode_info->number_of_colors = 16;
f96e0b
+  else
f96e0b
+    mode_info->number_of_colors = 256;
f96e0b
   mode_info->red_mask_size = vbeinfo->red_mask_size;
f96e0b
   mode_info->red_field_pos = vbeinfo->red_field_position;
f96e0b
   mode_info->green_mask_size = vbeinfo->green_mask_size;
f96e0b
diff --git a/grub-core/video/ieee1275.c b/grub-core/video/ieee1275.c
f96e0b
index 5830b68..5c58702 100644
f96e0b
--- a/grub-core/video/ieee1275.c
f96e0b
+++ b/grub-core/video/ieee1275.c
f96e0b
@@ -43,6 +43,20 @@ static struct
f96e0b
   grub_uint8_t *ptr;
f96e0b
 } framebuffer;
f96e0b
 
f96e0b
+static struct grub_video_palette_data serial_colors[] =
f96e0b
+  {
f96e0b
+    // {R, G, B}
f96e0b
+    {0x00, 0x00, 0x00, 0xFF}, // 0 = black
f96e0b
+    {0xA8, 0x00, 0x00, 0xFF}, // 1 = red
f96e0b
+    {0x00, 0xA8, 0x00, 0xFF}, // 2 = green
f96e0b
+    {0xFE, 0xFE, 0x54, 0xFF}, // 3 = yellow
f96e0b
+    {0x00, 0x00, 0xA8, 0xFF}, // 4 = blue
f96e0b
+    {0xA8, 0x00, 0xA8, 0xFF}, // 5 = magenta
f96e0b
+    {0x00, 0xA8, 0xA8, 0xFF}, // 6 = cyan
f96e0b
+    {0xFE, 0xFE, 0xFE, 0xFF}  // 7 = white
f96e0b
+  };
f96e0b
+
f96e0b
+
f96e0b
 static grub_err_t
f96e0b
 grub_video_ieee1275_set_palette (unsigned int start, unsigned int count,
f96e0b
 				 struct grub_video_palette_data *palette_data);
f96e0b
@@ -123,11 +137,63 @@ grub_video_ieee1275_fill_mode_info (grub_ieee1275_phandle_t dev,
f96e0b
     return grub_error (GRUB_ERR_IO, "Couldn't retrieve display pitch.");
f96e0b
   out->pitch = tmp;
f96e0b
 
f96e0b
-  out->mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR;
f96e0b
-  out->bpp = 8;
f96e0b
-  out->bytes_per_pixel = 1;
f96e0b
+  if (grub_ieee1275_get_integer_property (dev, "depth", &tmp,
f96e0b
+					  sizeof (tmp), 0))
f96e0b
+    tmp = 4;
f96e0b
+
f96e0b
+  out->mode_type = GRUB_VIDEO_MODE_TYPE_RGB;
f96e0b
+  out->bpp = tmp;
f96e0b
+  out->bytes_per_pixel = (out->bpp + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT;
f96e0b
   out->number_of_colors = 256;
f96e0b
 
f96e0b
+  switch (tmp)
f96e0b
+    {
f96e0b
+    case 4:
f96e0b
+    case 8:
f96e0b
+      out->mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR;
f96e0b
+      out->bpp = 8;
f96e0b
+      if (have_setcolors)
f96e0b
+	out->number_of_colors = 1 << tmp;
f96e0b
+      else
f96e0b
+	out->number_of_colors = 8;
f96e0b
+      break;
f96e0b
+
f96e0b
+      /* FIXME: we may need byteswapping for the following. Currently it
f96e0b
+	 was seen only on qemu and no byteswap was needed.  */
f96e0b
+    case 15:
f96e0b
+      out->red_mask_size = 5;
f96e0b
+      out->red_field_pos = 10;
f96e0b
+      out->green_mask_size = 5;
f96e0b
+      out->green_field_pos = 5;
f96e0b
+      out->blue_mask_size = 5;
f96e0b
+      out->blue_field_pos = 0;
f96e0b
+      break;
f96e0b
+
f96e0b
+    case 16:
f96e0b
+      out->red_mask_size = 5;
f96e0b
+      out->red_field_pos = 11;
f96e0b
+      out->green_mask_size = 6;
f96e0b
+      out->green_field_pos = 5;
f96e0b
+      out->blue_mask_size = 5;
f96e0b
+      out->blue_field_pos = 0;
f96e0b
+      break;
f96e0b
+
f96e0b
+    case 32:
f96e0b
+      out->reserved_mask_size = 8;
f96e0b
+      out->reserved_field_pos = 24;
f96e0b
+
f96e0b
+    case 24:
f96e0b
+      out->red_mask_size = 8;
f96e0b
+      out->red_field_pos = 16;
f96e0b
+      out->green_mask_size = 8;
f96e0b
+      out->green_field_pos = 8;
f96e0b
+      out->blue_mask_size = 8;
f96e0b
+      out->blue_field_pos = 0;
f96e0b
+      break;
f96e0b
+    default:
f96e0b
+      return grub_error (GRUB_ERR_IO, "unsupported video depth %d", tmp);
f96e0b
+    }
f96e0b
+
f96e0b
   out->blit_format = grub_video_get_blit_format (out);
f96e0b
   return GRUB_ERR_NONE;
f96e0b
 }
f96e0b
@@ -192,7 +258,7 @@ grub_video_ieee1275_setup (unsigned int width, unsigned int height,
f96e0b
   if (err)
f96e0b
     return err;
f96e0b
 
f96e0b
-  grub_video_ieee1275_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS,
f96e0b
+  grub_video_ieee1275_set_palette (0, framebuffer.mode_info.number_of_colors,
f96e0b
 				   grub_video_fbstd_colors);
f96e0b
     
f96e0b
   return err;
f96e0b
@@ -214,25 +280,35 @@ static grub_err_t
f96e0b
 grub_video_ieee1275_set_palette (unsigned int start, unsigned int count,
f96e0b
 				 struct grub_video_palette_data *palette_data)
f96e0b
 {
f96e0b
-  grub_err_t err;
f96e0b
+  unsigned col;
f96e0b
   struct grub_video_palette_data fb_palette_data[256];
f96e0b
+  grub_err_t err;
f96e0b
+
f96e0b
+  if (!(framebuffer.mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR))
f96e0b
+    return grub_video_fb_set_palette (start, count, palette_data);
f96e0b
+
f96e0b
+  if (!have_setcolors)
f96e0b
+    return grub_video_fb_set_palette (0, ARRAY_SIZE (serial_colors),
f96e0b
+    				      serial_colors);
f96e0b
+
f96e0b
+  if (start >= framebuffer.mode_info.number_of_colors)
f96e0b
+    return GRUB_ERR_NONE;
f96e0b
+
f96e0b
+  if (start + count > framebuffer.mode_info.number_of_colors)
f96e0b
+    count = framebuffer.mode_info.number_of_colors - start;
f96e0b
 
f96e0b
   err = grub_video_fb_set_palette (start, count, palette_data);
f96e0b
   if (err)
f96e0b
     return err;
f96e0b
 
f96e0b
-  grub_video_fb_get_palette (0, ARRAY_SIZE (fb_palette_data), fb_palette_data);
f96e0b
-
f96e0b
   /* Set colors.  */
f96e0b
-  if (have_setcolors)
f96e0b
-    {
f96e0b
-      unsigned col;
f96e0b
-      for (col = 0; col < ARRAY_SIZE (fb_palette_data); col++)
f96e0b
-	grub_ieee1275_set_color (stdout_ihandle, col, fb_palette_data[col].r,
f96e0b
-				 fb_palette_data[col].g,
f96e0b
-				 fb_palette_data[col].b);
f96e0b
-    }
f96e0b
+  grub_video_fb_get_palette (0, ARRAY_SIZE (fb_palette_data),
f96e0b
+			     fb_palette_data);
f96e0b
 
f96e0b
+  for (col = 0; col < ARRAY_SIZE (fb_palette_data); col++)
f96e0b
+    grub_ieee1275_set_color (stdout_ihandle, col, fb_palette_data[col].r,
f96e0b
+			     fb_palette_data[col].g,
f96e0b
+			     fb_palette_data[col].b);
f96e0b
   return GRUB_ERR_NONE;
f96e0b
 }
f96e0b
 
f96e0b
diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c
f96e0b
index f5e63ae..33f28c3 100644
f96e0b
--- a/grub-core/video/readers/jpeg.c
f96e0b
+++ b/grub-core/video/readers/jpeg.c
f96e0b
@@ -528,7 +528,11 @@ grub_jpeg_ycrcb_to_rgb (int yy, int cr, int cb, grub_uint8_t * rgb)
f96e0b
     dd = 0;
f96e0b
   if (dd > 255)
f96e0b
     dd = 255;
f96e0b
+#ifdef GRUB_CPU_WORDS_BIGENDIAN
f96e0b
+  rgb[2] = dd;
f96e0b
+#else
f96e0b
   *(rgb++) = dd;
f96e0b
+#endif
f96e0b
 
f96e0b
   /* Green  */
f96e0b
   dd = yy - ((cb * CONST (0.34414) + cr * CONST (0.71414)) >> SHIFT_BITS);
f96e0b
@@ -536,7 +540,11 @@ grub_jpeg_ycrcb_to_rgb (int yy, int cr, int cb, grub_uint8_t * rgb)
f96e0b
     dd = 0;
f96e0b
   if (dd > 255)
f96e0b
     dd = 255;
f96e0b
+#ifdef GRUB_CPU_WORDS_BIGENDIAN
f96e0b
+  rgb[1] = dd;
f96e0b
+#else
f96e0b
   *(rgb++) = dd;
f96e0b
+#endif
f96e0b
 
f96e0b
   /* Blue  */
f96e0b
   dd = yy + ((cb * CONST (1.772)) >> SHIFT_BITS);
f96e0b
@@ -544,7 +552,12 @@ grub_jpeg_ycrcb_to_rgb (int yy, int cr, int cb, grub_uint8_t * rgb)
f96e0b
     dd = 0;
f96e0b
   if (dd > 255)
f96e0b
     dd = 255;
f96e0b
+#ifdef GRUB_CPU_WORDS_BIGENDIAN
f96e0b
+  rgb[0] = dd;
f96e0b
+  rgb += 3;
f96e0b
+#else
f96e0b
   *(rgb++) = dd;
f96e0b
+#endif
f96e0b
 }
f96e0b
 
f96e0b
 static grub_err_t
f96e0b
diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c
f96e0b
index 7ef7e3b..6cae896 100644
f96e0b
--- a/grub-core/video/readers/png.c
f96e0b
+++ b/grub-core/video/readers/png.c
f96e0b
@@ -253,9 +253,12 @@ grub_png_decode_image_header (struct grub_png_data *data)
f96e0b
 		       "png: color type not supported");
f96e0b
 
f96e0b
   if (data->is_16bit)
f96e0b
-    {
f96e0b
       data->bpp <<= 1;
f96e0b
 
f96e0b
+#ifndef GRUB_CPU_WORDS_BIGENDIAN
f96e0b
+  if (data->is_16bit)
f96e0b
+#endif
f96e0b
+    {
f96e0b
       data->image_data = grub_malloc (data->image_height *
f96e0b
                                       data->image_width *  data->bpp);
f96e0b
       if (grub_errno)
f96e0b
@@ -263,11 +266,13 @@ grub_png_decode_image_header (struct grub_png_data *data)
f96e0b
 
f96e0b
       data->cur_rgb = data->image_data;
f96e0b
     }
f96e0b
+#ifndef GRUB_CPU_WORDS_BIGENDIAN
f96e0b
   else
f96e0b
     {
f96e0b
       data->image_data = 0;
f96e0b
       data->cur_rgb = (*data->bitmap)->data;
f96e0b
     }
f96e0b
+#endif
f96e0b
 
f96e0b
   data->raw_bytes = data->image_height * (data->image_width + 1) * data->bpp;
f96e0b
 
f96e0b
@@ -536,7 +541,7 @@ grub_png_output_byte (struct grub_png_data *data, grub_uint8_t n)
f96e0b
       data->cur_filter = n;
f96e0b
     }
f96e0b
   else
f96e0b
-    *(data->cur_rgb++) = n;
f96e0b
+    *data->cur_rgb++ = n;
f96e0b
 
f96e0b
   data->cur_column++;
f96e0b
   row_bytes = data->image_width * data->bpp;
f96e0b
@@ -772,12 +777,60 @@ grub_png_convert_image (struct grub_png_data *data)
f96e0b
   grub_uint8_t *d1, *d2;
f96e0b
 
f96e0b
   d1 = (*data->bitmap)->data;
f96e0b
-  d2 = data->image_data + 1;
f96e0b
+  d2 = data->image_data + data->is_16bit;
f96e0b
 
f96e0b
   /* Only copy the upper 8 bit.  */
f96e0b
+#ifndef GRUB_CPU_WORDS_BIGENDIAN
f96e0b
   for (i = 0; i < (data->image_width * data->image_height * data->bpp >> 1);
f96e0b
        i++, d1++, d2+=2)
f96e0b
     *d1 = *d2;
f96e0b
+#else
f96e0b
+  switch (data->bpp)
f96e0b
+    {
f96e0b
+      /* 16-bit with alpha.  */
f96e0b
+    case 8:
f96e0b
+      for (i = 0; i < (data->image_width * data->image_height);
f96e0b
+	   i++, d1 += 4, d2+=8)
f96e0b
+	{
f96e0b
+	  d1[0] = d2[7];
f96e0b
+	  d1[1] = d2[5];
f96e0b
+	  d1[2] = d2[3];
f96e0b
+	  d1[3] = d2[1];
f96e0b
+	}
f96e0b
+      break;
f96e0b
+      /* 16-bit without alpha.  */
f96e0b
+    case 6:
f96e0b
+      for (i = 0; i < (data->image_width * data->image_height);
f96e0b
+	   i++, d1 += 3, d2+=6)
f96e0b
+	{
f96e0b
+	  d1[0] = d2[5];
f96e0b
+	  d1[1] = d2[3];
f96e0b
+	  d1[2] = d2[1];
f96e0b
+	}
f96e0b
+      break;
f96e0b
+      /* 8-bit with alpha.  */
f96e0b
+    case 4:
f96e0b
+      for (i = 0; i < (data->image_width * data->image_height);
f96e0b
+	   i++, d1 += 4, d2 += 4)
f96e0b
+	{
f96e0b
+	  d1[0] = d2[3];
f96e0b
+	  d1[1] = d2[2];
f96e0b
+	  d1[2] = d2[1];
f96e0b
+	  d1[3] = d2[0];
f96e0b
+	}
f96e0b
+      break;
f96e0b
+      /* 8-bit without alpha.  */
f96e0b
+    case 3:
f96e0b
+      for (i = 0; i < (data->image_width * data->image_height);
f96e0b
+	   i++, d1 += 3, d2 += 3)
f96e0b
+	{
f96e0b
+	  d1[0] = d2[2];
f96e0b
+	  d1[1] = d2[1];
f96e0b
+	  d1[2] = d2[0];
f96e0b
+	}
f96e0b
+      break;
f96e0b
+    }
f96e0b
+#endif
f96e0b
 }
f96e0b
 
f96e0b
 static grub_err_t
f96e0b
@@ -816,7 +869,9 @@ grub_png_decode_png (struct grub_png_data *data)
f96e0b
 	  break;
f96e0b
 
f96e0b
 	case PNG_CHUNK_IEND:
f96e0b
+#ifndef GRUB_CPU_WORDS_BIGENDIAN
f96e0b
           if (data->is_16bit)
f96e0b
+#endif
f96e0b
             grub_png_convert_image (data);
f96e0b
 
f96e0b
 	  return grub_errno;
f96e0b
diff --git a/grub-core/video/sis315pro.c b/grub-core/video/sis315pro.c
f96e0b
index a986669..cf45493 100644
f96e0b
--- a/grub-core/video/sis315pro.c
f96e0b
+++ b/grub-core/video/sis315pro.c
f96e0b
@@ -152,7 +152,7 @@ grub_video_sis315pro_setup (unsigned int width, unsigned int height,
f96e0b
   framebuffer.mode_info.bpp = 8;
f96e0b
   framebuffer.mode_info.bytes_per_pixel = 1;
f96e0b
   framebuffer.mode_info.pitch = 640 * 1;
f96e0b
-  framebuffer.mode_info.number_of_colors = 256;
f96e0b
+  framebuffer.mode_info.number_of_colors = 16;
f96e0b
   framebuffer.mode_info.red_mask_size = 0;
f96e0b
   framebuffer.mode_info.red_field_pos = 0;
f96e0b
   framebuffer.mode_info.green_mask_size = 0;
f96e0b
@@ -372,7 +372,7 @@ grub_video_sis315pro_setup (unsigned int width, unsigned int height,
f96e0b
     return err;
f96e0b
 
f96e0b
   /* Copy default palette to initialize emulated palette.  */
f96e0b
-  err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS,
f96e0b
+  err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_EXT_NUMCOLORS,
f96e0b
 				   grub_video_fbstd_colors);
f96e0b
 #endif
f96e0b
   return err;
f96e0b
diff --git a/include/grub/video_fb.h b/include/grub/video_fb.h
f96e0b
index 0628467..ffe16c3 100644
f96e0b
--- a/include/grub/video_fb.h
f96e0b
+++ b/include/grub/video_fb.h
f96e0b
@@ -31,7 +31,9 @@ struct grub_video_fbblit_info;
f96e0b
 struct grub_video_fbrender_target;
f96e0b
 
f96e0b
 #define GRUB_VIDEO_FBSTD_NUMCOLORS 16
f96e0b
-extern struct grub_video_palette_data EXPORT_VAR(grub_video_fbstd_colors)[GRUB_VIDEO_FBSTD_NUMCOLORS];
f96e0b
+#define GRUB_VIDEO_FBSTD_EXT_NUMCOLORS 256
f96e0b
+
f96e0b
+extern struct grub_video_palette_data EXPORT_VAR(grub_video_fbstd_colors)[GRUB_VIDEO_FBSTD_EXT_NUMCOLORS];
f96e0b
 
f96e0b
 grub_err_t
f96e0b
 EXPORT_FUNC(grub_video_fb_init) (void);
f96e0b
-- 
f96e0b
1.8.2.1
f96e0b