]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
2009-08-04 Robert Millan <rmh.grub@aybabtu.com>
authorrobertmh <robertmh@localhost>
Tue, 4 Aug 2009 21:28:19 +0000 (21:28 +0000)
committerrobertmh <robertmh@localhost>
Tue, 4 Aug 2009 21:28:19 +0000 (21:28 +0000)
        Fix a bug resulting in black screen when loading Linux using a
        packed video mode.

        * kern/i386/pc/startup.S (grub_vbe_bios_getset_dac_palette_width): New
        function.

        * include/grub/i386/pc/vbe.h (GRUB_VBE_CAPABILITY_DACWIDTH): New macro.
        (grub_vbe_bios_getset_dac_palette_width): New function.
        (grub_vbe_bios_get_dac_palette_width)
        (grub_vbe_bios_set_dac_palette_width): New macros (act as wrappers for
        grub_vbe_bios_getset_dac_palette_width()).

        * video/i386/pc/vbe.c (grub_vbe_probe): Use `GRUB_VBE_STATUS_OK' to
        check for return status.
        (grub_vbe_get_video_mode_info): When getting information for a packed
        mode (<= 8 bpp), obtain DAC palette width using
        grub_vbe_bios_getset_dac_palette_width(), and use that for initializing
        {red,green,blue}_mark_size.

ChangeLog
include/grub/i386/pc/vbe.h
kern/i386/pc/startup.S
video/i386/pc/vbe.c

index 2437c7cacf680ee52717ba98fea6e8847124537c..44f14a0d43fc0e825ab53f256c8a1d22d83e05f8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2009-08-04  Robert Millan  <rmh.grub@aybabtu.com>
+
+       Fix a bug resulting in black screen when loading Linux using a
+       packed video mode.
+
+       * kern/i386/pc/startup.S (grub_vbe_bios_getset_dac_palette_width): New
+       function.
+
+       * include/grub/i386/pc/vbe.h (GRUB_VBE_CAPABILITY_DACWIDTH): New macro.
+       (grub_vbe_bios_getset_dac_palette_width): New function.
+       (grub_vbe_bios_get_dac_palette_width)
+       (grub_vbe_bios_set_dac_palette_width): New macros (act as wrappers for
+       grub_vbe_bios_getset_dac_palette_width()).
+
+       * video/i386/pc/vbe.c (grub_vbe_probe): Use `GRUB_VBE_STATUS_OK' to
+       check for return status.
+       (grub_vbe_get_video_mode_info): When getting information for a packed
+       mode (<= 8 bpp), obtain DAC palette width using
+       grub_vbe_bios_getset_dac_palette_width(), and use that for initializing
+       {red,green,blue}_mark_size.
+
 2009-08-04  Felix Zielcke  <fzielcke@z-51.de>
 
        * commands/search.c (options): Fix help output to match actual code.
index bd6ecd7e4e097bfd93c08729f7291d58b5180bf6..fad3c6c364110a4c65ac7c19a8f180273cf23fe2 100644 (file)
@@ -30,6 +30,8 @@
 /* VBE status codes.  */
 #define GRUB_VBE_STATUS_OK             0x004f
 
+#define GRUB_VBE_CAPABILITY_DACWIDTH   (1 << 0)
+
 /* Bits from the GRUB_VBE "mode_attributes" field in the mode info struct.  */
 #define GRUB_VBE_MODEATTR_SUPPORTED                 (1 << 0)
 #define GRUB_VBE_MODEATTR_RESERVED_1                (1 << 1)
@@ -181,6 +183,11 @@ grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_get_controller_info) (struct grub_vb
 grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_get_mode_info) (grub_uint32_t mode,
                                                             struct grub_vbe_mode_info_block *mode_info);
 
+grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_getset_dac_palette_width) (int set, int *width);
+
+#define grub_vbe_bios_get_dac_palette_width(width)     grub_vbe_bios_getset_dac_palette_width(0, (width))
+#define grub_vbe_bios_set_dac_palette_width(width)     grub_vbe_bios_getset_dac_palette_width(1, (width))
+
 /* Call VESA BIOS 0x4f02 to set video mode, return status.  */
 grub_vbe_status_t EXPORT_FUNC(grub_vbe_bios_set_mode) (grub_uint32_t mode,
                                                        struct grub_vbe_crtc_info_block *crtc_info);
index be258fb08e23a627f917b0d0ea7c98720c179355..1a896eda17b212080aa1fb6f114f6fcace3f270c 100644 (file)
@@ -1732,6 +1732,52 @@ FUNCTION(grub_vbe_bios_get_mode)
        popl    %ebp
        ret
 
+/*
+ * grub_vbe_status_t grub_vbe_bios_getset_dac_palette_width (int set, int *dac_mask_size)
+ *
+ * Register allocations for parameters:
+ * %eax                set
+ * %edx                *dac_mask_size
+ */
+FUNCTION(grub_vbe_bios_getset_dac_palette_width)
+       pushl   %ebp
+       pushl   %ebx
+
+       xorl    %ebx, %ebx
+
+       /* If we only want to fetch the value, set %bl to 1.  */
+       testl   %eax, %eax
+       jne     1f
+       incb    %bl
+1:
+
+       /* Put desired width in %bh.  */
+       movl    (%edx), %eax
+       movb    %al, %bh
+
+       call    prot_to_real
+       .code16
+
+       movw    $0x4f08, %ax
+       int     $0x10
+
+       movw    %ax, %dx        /* real_to_prot destroys %eax.  */
+
+       DATA32 call     real_to_prot
+       .code32
+
+       /* Move result back to *dac_mask_size.  */
+       movb    %bh, %al
+       movl    %eax, (%edx)
+
+       /* Return value in %eax.  */
+       xorl    %eax, %eax
+       movw    %dx, %ax
+
+       popl    %ebx
+       popl    %ebp
+       ret
+
 /*
  * grub_vbe_status_t grub_vbe_bios_set_memory_window (grub_uint32_t window,
  *                                                   grub_uint32_t position);
index ae0840234a493da340a8147b985c95c85e0fdb7f..1670a737dafa1ecd5520fef3ff8fac7bca828fe3 100644 (file)
@@ -116,7 +116,7 @@ grub_vbe_probe (struct grub_vbe_info_block *info_block)
 
       /* Try to get controller info block.  */
       status = grub_vbe_bios_get_controller_info (vbe_ib);
-      if (status == 0x004F)
+      if (status == GRUB_VBE_STATUS_OK)
         {
           /* Copy it for later usage.  */
           grub_memcpy (&controller_info, vbe_ib, sizeof (controller_info));
@@ -300,6 +300,24 @@ grub_vbe_get_video_mode_info (grub_uint32_t mode,
 
       /* Make copy of mode info block.  */
       grub_memcpy (mode_info, mi_tmp, sizeof (*mode_info));
+
+      /* Packed mode.  Query DAC Palette width for color sizes.  */
+      if (mode_info->bits_per_pixel <= 8)
+       {
+         int width = 8;
+         status = 0;
+
+         if (controller_info.capabilities & GRUB_VBE_CAPABILITY_DACWIDTH)
+           status = grub_vbe_bios_set_dac_palette_width (& width);
+
+         if (status != GRUB_VBE_STATUS_OK)
+           /* 6 is default after mode reset.  */
+           width = 6;
+
+         mode_info->red_mask_size = mode_info->green_mask_size
+           = mode_info->blue_mask_size = width;
+         mode_info->rsvd_mask_size = 0;
+       }
     }
   else
     /* Just clear mode info block if it isn't a VESA mode.  */