Several fixes to ieee1275 and big-endian video.

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2013-05-02 22:30:20 +02:00
parent 813c16222f
commit a8905e8ae8
18 changed files with 655 additions and 72 deletions

View file

@ -43,6 +43,20 @@ static struct
grub_uint8_t *ptr;
} framebuffer;
static struct grub_video_palette_data serial_colors[] =
{
// {R, G, B}
{0x00, 0x00, 0x00, 0xFF}, // 0 = black
{0xA8, 0x00, 0x00, 0xFF}, // 1 = red
{0x00, 0xA8, 0x00, 0xFF}, // 2 = green
{0xFE, 0xFE, 0x54, 0xFF}, // 3 = yellow
{0x00, 0x00, 0xA8, 0xFF}, // 4 = blue
{0xA8, 0x00, 0xA8, 0xFF}, // 5 = magenta
{0x00, 0xA8, 0xA8, 0xFF}, // 6 = cyan
{0xFE, 0xFE, 0xFE, 0xFF} // 7 = white
};
static grub_err_t
grub_video_ieee1275_set_palette (unsigned int start, unsigned int count,
struct grub_video_palette_data *palette_data);
@ -123,11 +137,63 @@ grub_video_ieee1275_fill_mode_info (grub_ieee1275_phandle_t dev,
return grub_error (GRUB_ERR_IO, "Couldn't retrieve display pitch.");
out->pitch = tmp;
out->mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR;
out->bpp = 8;
out->bytes_per_pixel = 1;
if (grub_ieee1275_get_integer_property (dev, "depth", &tmp,
sizeof (tmp), 0))
tmp = 4;
out->mode_type = GRUB_VIDEO_MODE_TYPE_RGB;
out->bpp = tmp;
out->bytes_per_pixel = (out->bpp + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT;
out->number_of_colors = 256;
switch (tmp)
{
case 4:
case 8:
out->mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR;
out->bpp = 8;
if (have_setcolors)
out->number_of_colors = 1 << tmp;
else
out->number_of_colors = 8;
break;
/* FIXME: we may need byteswapping for the following. Currently it
was seen only on qemu and no byteswap was needed. */
case 15:
out->red_mask_size = 5;
out->red_field_pos = 10;
out->green_mask_size = 5;
out->green_field_pos = 5;
out->blue_mask_size = 5;
out->blue_field_pos = 0;
break;
case 16:
out->red_mask_size = 5;
out->red_field_pos = 11;
out->green_mask_size = 6;
out->green_field_pos = 5;
out->blue_mask_size = 5;
out->blue_field_pos = 0;
break;
case 32:
out->reserved_mask_size = 8;
out->reserved_field_pos = 24;
case 24:
out->red_mask_size = 8;
out->red_field_pos = 16;
out->green_mask_size = 8;
out->green_field_pos = 8;
out->blue_mask_size = 8;
out->blue_field_pos = 0;
break;
default:
return grub_error (GRUB_ERR_IO, "unsupported video depth %d", tmp);
}
out->blit_format = grub_video_get_blit_format (out);
return GRUB_ERR_NONE;
}
@ -192,7 +258,7 @@ grub_video_ieee1275_setup (unsigned int width, unsigned int height,
if (err)
return err;
grub_video_ieee1275_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS,
grub_video_ieee1275_set_palette (0, framebuffer.mode_info.number_of_colors,
grub_video_fbstd_colors);
return err;
@ -214,25 +280,35 @@ static grub_err_t
grub_video_ieee1275_set_palette (unsigned int start, unsigned int count,
struct grub_video_palette_data *palette_data)
{
grub_err_t err;
unsigned col;
struct grub_video_palette_data fb_palette_data[256];
grub_err_t err;
if (!(framebuffer.mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR))
return grub_video_fb_set_palette (start, count, palette_data);
if (!have_setcolors)
return grub_video_fb_set_palette (0, ARRAY_SIZE (serial_colors),
serial_colors);
if (start >= framebuffer.mode_info.number_of_colors)
return GRUB_ERR_NONE;
if (start + count > framebuffer.mode_info.number_of_colors)
count = framebuffer.mode_info.number_of_colors - start;
err = grub_video_fb_set_palette (start, count, palette_data);
if (err)
return err;
grub_video_fb_get_palette (0, ARRAY_SIZE (fb_palette_data), fb_palette_data);
/* Set colors. */
if (have_setcolors)
{
unsigned col;
for (col = 0; col < ARRAY_SIZE (fb_palette_data); col++)
grub_ieee1275_set_color (stdout_ihandle, col, fb_palette_data[col].r,
fb_palette_data[col].g,
fb_palette_data[col].b);
}
grub_video_fb_get_palette (0, ARRAY_SIZE (fb_palette_data),
fb_palette_data);
for (col = 0; col < ARRAY_SIZE (fb_palette_data); col++)
grub_ieee1275_set_color (stdout_ihandle, col, fb_palette_data[col].r,
fb_palette_data[col].g,
fb_palette_data[col].b);
return GRUB_ERR_NONE;
}