]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
use video subsystem on EFI
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Wed, 16 Dec 2009 18:04:58 +0000 (19:04 +0100)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Wed, 16 Dec 2009 18:04:58 +0000 (19:04 +0100)
conf/i386-efi.rmk
conf/i386-pc.rmk
conf/x86_64-efi.rmk
include/grub/i386/xnu.h
loader/i386/efi/linux.c
loader/i386/efi/xnu.c [deleted file]
loader/i386/pc/xnu.c [deleted file]
loader/i386/xnu.c

index 629b83999d68b1c17ea439c96bd98fbf30a8fae8..a037ed383b281b481afae7ce9b260621ed7c4b9b 100644 (file)
@@ -154,7 +154,7 @@ efi_gop_mod_CFLAGS = $(COMMON_CFLAGS)
 efi_gop_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
 pkglib_MODULES += xnu.mod
-xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/i386/efi/xnu.c\
+xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c \
         loader/macho.c loader/xnu.c
 xnu_mod_CFLAGS = $(COMMON_CFLAGS)
 xnu_mod_LDFLAGS = $(COMMON_LDFLAGS)
index 031c24adf2da04d77860fb7e2d6ec22cfa052cad..b71a7edc0114f6c46a345f84f191cf3177b9437c 100644 (file)
@@ -183,7 +183,7 @@ linux_mod_CFLAGS = $(COMMON_CFLAGS)
 linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
 pkglib_MODULES += xnu.mod
-xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/i386/pc/xnu.c\
+xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c \
         loader/macho.c loader/xnu.c
 xnu_mod_CFLAGS = $(COMMON_CFLAGS)
 xnu_mod_LDFLAGS = $(COMMON_LDFLAGS)
index ee511e1bdb910801178d917bec37977c7f645968..6db52f480837af787f9a0b177bf77fcdfdf0c06c 100644 (file)
@@ -160,7 +160,7 @@ efi_gop_mod_CFLAGS = $(COMMON_CFLAGS)
 efi_gop_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
 pkglib_MODULES += xnu.mod
-xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/i386/efi/xnu.c\
+xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c \
         loader/macho.c loader/xnu.c
 xnu_mod_CFLAGS = $(COMMON_CFLAGS)
 xnu_mod_LDFLAGS = $(COMMON_LDFLAGS)
index 306dc7b65bff2571411ff4ca1fa280f004efd3d9..ea2767a79c686e11c7a63280031531f3b7599957 100644 (file)
@@ -76,6 +76,5 @@ extern grub_uint32_t grub_xnu_arg1;
 extern char grub_xnu_cmdline[1024];
 grub_err_t grub_xnu_boot (void);
 grub_err_t grub_cpu_xnu_fill_devicetree (void);
-grub_err_t grub_xnu_set_video (struct grub_xnu_boot_params *bootparams_relloc);
 extern grub_uint32_t grub_xnu_heap_will_be_at;
 #endif
index 8cd4d23f2c22e6f7ec4c7a321aa3c1b15c80d87d..3b066d58900c2913ae4174d14c08b43c140a8eca 100644 (file)
 #include <grub/cpu/linux.h>
 #include <grub/efi/api.h>
 #include <grub/efi/efi.h>
-#include <grub/efi/uga_draw.h>
-#include <grub/pci.h>
 #include <grub/command.h>
 #include <grub/memory.h>
+#include <grub/env.h>
+#include <grub/video.h>
+#include <grub/time.h>
 
 #define GRUB_LINUX_CL_OFFSET           0x1000
 #define GRUB_LINUX_CL_END_OFFSET       0x2000
@@ -285,6 +286,66 @@ grub_e820_add_region (struct grub_e820_mmap *e820_map, int *e820_num,
     }
 }
 
+static grub_err_t
+grub_linux_setup_video (struct linux_kernel_params *params)
+{
+  struct grub_video_mode_info mode_info;
+  void *framebuffer;
+  grub_err_t err;
+
+  err = grub_video_get_info_and_fini (&mode_info, &framebuffer);
+
+  if (err)
+    return err;
+
+  params->lfb_width = mode_info.width;
+  params->lfb_height = mode_info.height;
+  params->lfb_depth = mode_info.bpp;
+  params->lfb_line_len = mode_info.pitch;
+
+  params->lfb_base = (grub_size_t) framebuffer;
+  params->lfb_size = (params->lfb_line_len * params->lfb_height + 65535) >> 16;
+
+  params->red_mask_size = mode_info.red_mask_size;
+  params->red_field_pos = mode_info.red_field_pos;
+  params->green_mask_size = mode_info.green_mask_size;
+  params->green_field_pos = mode_info.green_field_pos;
+  params->blue_mask_size = mode_info.blue_mask_size;
+  params->blue_field_pos = mode_info.blue_field_pos;
+  params->reserved_mask_size = mode_info.reserved_mask_size;
+  params->reserved_field_pos = mode_info.reserved_field_pos;
+
+  params->have_vga = GRUB_VIDEO_TYPE_EFI;
+
+#ifdef GRUB_MACHINE_PCBIOS
+  /* VESA packed modes may come with zeroed mask sizes, which need
+     to be set here according to DAC Palette width.  If we don't,
+     this results in Linux displaying a black screen.  */
+  if (mode_info.bpp <= 8)
+    {
+      struct grub_vbe_info_block controller_info;
+      int status;
+      int width = 8;
+
+      status = grub_vbe_bios_get_controller_info (&controller_info);
+
+      if (status == GRUB_VBE_STATUS_OK &&
+         (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;
+
+      params->red_mask_size = params->green_mask_size
+       = params->blue_mask_size = width;
+      params->reserved_mask_size = 0;
+    }
+#endif
+
+  return 0;
+}
+
 #ifdef __x86_64__
 extern grub_uint8_t grub_linux_trampoline_start[];
 extern grub_uint8_t grub_linux_trampoline_end[];
@@ -299,9 +360,14 @@ grub_linux_boot (void)
   grub_efi_uintn_t desc_size;
   grub_efi_uint32_t desc_version;
   int e820_num;
+  const char *modevar;
+  char *tmp;
+  grub_err_t err;
 
   params = real_mode_mem;
 
+  grub_printf ("%d\n", __LINE__);
+
   grub_dprintf ("linux", "code32_start = %x, idt_desc = %lx, gdt_desc = %lx\n",
                (unsigned) params->code32_start,
                (unsigned long) &(idt_desc.limit),
@@ -310,6 +376,8 @@ grub_linux_boot (void)
                (unsigned) idt_desc.limit, (unsigned long) idt_desc.base,
                (unsigned) gdt_desc.limit, (unsigned long) gdt_desc.base);
 
+  grub_printf ("%d\n", __LINE__);
+
   auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
   int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
     {
@@ -348,10 +416,43 @@ grub_linux_boot (void)
       return 0;
     }
 
+  grub_printf ("%d\n", __LINE__);
+
   e820_num = 0;
   grub_mmap_iterate (hook);
   params->mmap_size = e820_num;
 
+  modevar = grub_env_get ("gfxpayload");
+
+  /* Now all graphical modes are acceptable.
+     May change in future if we have modes without framebuffer.  */
+  if (modevar && *modevar != 0)
+    {
+      tmp = grub_malloc (grub_strlen (modevar)
+                        + sizeof (";auto"));
+      if (! tmp)
+       return grub_errno;
+      grub_sprintf (tmp, "%s;auto", modevar);
+      err = grub_video_set_mode (tmp, GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0);
+      grub_free (tmp);
+    }
+  else
+    err = grub_video_set_mode ("auto", GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0);
+
+  grub_printf ("Trampoline at %p. code32=%x, real_mode_mem=%p\n",
+              ((char *) prot_mode_mem + (prot_mode_pages << 12)),
+              (unsigned) params->code32_start, real_mode_mem);
+
+  if (!err)
+    err = grub_linux_setup_video (params);
+
+  if (err)
+    {
+      grub_print_error ();
+      grub_printf ("Booting however\n");
+      grub_errno = GRUB_ERR_NONE;
+    }
+
   mmap_size = find_mmap_size ();
   if (grub_efi_get_memory_map (&mmap_size, mmap_buf, &map_key,
                               &desc_size, &desc_version) <= 0)
@@ -424,174 +525,6 @@ grub_linux_unload (void)
   return GRUB_ERR_NONE;
 }
 
-static grub_efi_guid_t uga_draw_guid = GRUB_EFI_UGA_DRAW_GUID;
-
-
-#define RGB_MASK       0xffffff
-#define RGB_MAGIC      0x121314
-#define LINE_MIN       800
-#define LINE_MAX       4096
-#define FBTEST_STEP    (0x10000 >> 2)
-#define FBTEST_COUNT   8
-
-static int
-find_line_len (grub_uint32_t *fb_base, grub_uint32_t *line_len)
-{
-  grub_uint32_t *base = (grub_uint32_t *) (grub_target_addr_t) *fb_base;
-  int i;
-
-  for (i = 0; i < FBTEST_COUNT; i++, base += FBTEST_STEP)
-    {
-      if ((*base & RGB_MASK) == RGB_MAGIC)
-       {
-         int j;
-
-         for (j = LINE_MIN; j <= LINE_MAX; j++)
-           {
-             if ((base[j] & RGB_MASK) == RGB_MAGIC)
-               {
-                 *fb_base = (grub_uint32_t) (grub_target_addr_t) base;
-                 *line_len = j << 2;
-
-                 return 1;
-               }
-           }
-
-         break;
-       }
-    }
-
-  return 0;
-}
-
-static int
-find_framebuf (grub_uint32_t *fb_base, grub_uint32_t *line_len)
-{
-  int found = 0;
-
-  auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev,
-                                      grub_pci_id_t pciid);
-
-  int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev,
-                                 grub_pci_id_t pciid)
-    {
-      grub_pci_address_t addr;
-
-      addr = grub_pci_make_address (dev, 2);
-      if (grub_pci_read (addr) >> 24 == 0x3)
-       {
-         int i;
-
-         grub_printf ("Display controller: %d:%d.%d\nDevice id: %x\n",
-                      grub_pci_get_bus (dev), grub_pci_get_device (dev),
-                      grub_pci_get_function (dev), pciid);
-         addr += 8;
-         for (i = 0; i < 6; i++, addr += 4)
-           {
-             grub_uint32_t old_bar1, old_bar2, type;
-             grub_uint64_t base64;
-
-             old_bar1 = grub_pci_read (addr);
-             if ((! old_bar1) || (old_bar1 & GRUB_PCI_ADDR_SPACE_IO))
-               continue;
-
-             type = old_bar1 & GRUB_PCI_ADDR_MEM_TYPE_MASK;
-             if (type == GRUB_PCI_ADDR_MEM_TYPE_64)
-               {
-                 if (i == 5)
-                   break;
-
-                 old_bar2 = grub_pci_read (addr + 4);
-               }
-             else
-               old_bar2 = 0;
-
-             base64 = old_bar2;
-             base64 <<= 32;
-             base64 |= (old_bar1 & GRUB_PCI_ADDR_MEM_MASK);
-
-             grub_printf ("%s(%d): 0x%llx\n",
-                          ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) ?
-                           "VMEM" : "MMIO"), i,
-                          (unsigned long long) base64);
-
-             if ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) && (! found))
-               {
-                 *fb_base = base64;
-                 if (find_line_len (fb_base, line_len))
-                   found++;
-               }
-
-             if (type == GRUB_PCI_ADDR_MEM_TYPE_64)
-               {
-                 i++;
-                 addr += 4;
-               }
-           }
-       }
-
-      return found;
-    }
-
-  grub_pci_iterate (find_card);
-  return found;
-}
-
-static int
-grub_linux_setup_video (struct linux_kernel_params *params)
-{
-  grub_efi_uga_draw_protocol_t *c;
-  grub_uint32_t width, height, depth, rate, pixel, fb_base, line_len;
-  int ret;
-
-  c = grub_efi_locate_protocol (&uga_draw_guid, 0);
-  if (! c)
-    return 1;
-
-  if (efi_call_5 (c->get_mode, c, &width, &height, &depth, &rate))
-    return 1;
-
-  grub_printf ("Video mode: %ux%u-%u@%u\n", width, height, depth, rate);
-
-  grub_efi_set_text_mode (0);
-  pixel = RGB_MAGIC;
-  efi_call_10 (c->blt, c, (struct grub_efi_uga_pixel *) &pixel,
-              GRUB_EFI_UGA_VIDEO_FILL, 0, 0, 0, 0, 1, height, 0);
-  ret = find_framebuf (&fb_base, &line_len);
-  grub_efi_set_text_mode (1);
-
-  if (! ret)
-    {
-      grub_printf ("Can\'t find frame buffer address\n");
-      return 1;
-    }
-
-  grub_printf ("Frame buffer base: 0x%x\n", fb_base);
-  grub_printf ("Video line length: %d\n", line_len);
-
-  params->lfb_width = width;
-  params->lfb_height = height;
-  params->lfb_depth = depth;
-  params->lfb_line_len = line_len;
-
-  params->lfb_base = fb_base;
-  params->lfb_size = (line_len * params->lfb_height + 65535) >> 16;
-
-  params->red_mask_size = 8;
-  params->red_field_pos = 16;
-  params->green_mask_size = 8;
-  params->green_field_pos = 8;
-  params->blue_mask_size = 8;
-  params->blue_field_pos = 0;
-  params->reserved_mask_size = 8;
-  params->reserved_field_pos = 24;
-
-  params->have_vga = GRUB_VIDEO_TYPE_VLFB;
-  params->vid_mode = 0x338;  /* 1024x768x32  */
-
-  return 0;
-}
-
 static grub_err_t
 grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
                int argc, char *argv[])
@@ -790,8 +723,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
   grub_printf ("   [Linux-bzImage, setup=0x%x, size=0x%x]\n",
               (unsigned) real_size, (unsigned) prot_size);
 
-  grub_linux_setup_video (params);
-
   /* Detect explicitly specified memory size, if any.  */
   linux_mem_size = 0;
   for (i = 1; i < argc; i++)
@@ -857,7 +788,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
 
   if (grub_errno == GRUB_ERR_NONE)
     {
-      grub_loader_set (grub_linux_boot, grub_linux_unload, 1);
+      grub_loader_set (grub_linux_boot, grub_linux_unload, 0);
       loaded = 1;
     }
 
diff --git a/loader/i386/efi/xnu.c b/loader/i386/efi/xnu.c
deleted file mode 100644 (file)
index 2367328..0000000
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/env.h>
-#include <grub/xnu.h>
-#include <grub/cpu/xnu.h>
-#include <grub/efi/api.h>
-#include <grub/efi/efi.h>
-#include <grub/efi/uga_draw.h>
-#include <grub/pci.h>
-#include <grub/misc.h>
-
-/* Setup video for xnu. Big parts are copied from linux.c. */
-
-static grub_efi_guid_t uga_draw_guid = GRUB_EFI_UGA_DRAW_GUID;
-
-#define RGB_MASK       0xffffff
-#define RGB_MAGIC      0x121314
-#define LINE_MIN       800
-#define LINE_MAX       4096
-#define FBTEST_STEP    (0x10000 >> 2)
-#define FBTEST_COUNT   8
-
-static int
-find_line_len (grub_uint32_t *fb_base, grub_uint32_t *line_len)
-{
-  grub_uint32_t *base = (grub_uint32_t *) (grub_target_addr_t) *fb_base;
-  int i;
-
-  for (i = 0; i < FBTEST_COUNT; i++, base += FBTEST_STEP)
-    {
-      if ((*base & RGB_MASK) == RGB_MAGIC)
-       {
-         int j;
-
-         for (j = LINE_MIN; j <= LINE_MAX; j++)
-           {
-             if ((base[j] & RGB_MASK) == RGB_MAGIC)
-               {
-                 *fb_base = (grub_uint32_t) (grub_target_addr_t) base;
-                 *line_len = j << 2;
-
-                 return 1;
-               }
-           }
-
-         break;
-       }
-    }
-
-  return 0;
-}
-
-static int
-find_framebuf (grub_uint32_t *fb_base, grub_uint32_t *line_len)
-{
-  int found = 0;
-
-  auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev,
-                                      grub_pci_id_t pciid);
-
-  int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev,
-                                 grub_pci_id_t pciid)
-    {
-      grub_pci_address_t addr;
-
-      addr = grub_pci_make_address (dev, 2);
-      if (grub_pci_read (addr) >> 24 == 0x3)
-       {
-         int i;
-
-         grub_printf ("Display controller: %d:%d.%d\nDevice id: %x\n",
-                      grub_pci_get_bus (dev), grub_pci_get_device (dev),
-                      grub_pci_get_function (dev), pciid);
-         addr += 8;
-         for (i = 0; i < 6; i++, addr += 4)
-           {
-             grub_uint32_t old_bar1, old_bar2, type;
-             grub_uint64_t base64;
-
-             old_bar1 = grub_pci_read (addr);
-             if ((! old_bar1) || (old_bar1 & GRUB_PCI_ADDR_SPACE_IO))
-               continue;
-
-             type = old_bar1 & GRUB_PCI_ADDR_MEM_TYPE_MASK;
-             if (type == GRUB_PCI_ADDR_MEM_TYPE_64)
-               {
-                 if (i == 5)
-                   break;
-
-                 old_bar2 = grub_pci_read (addr + 4);
-               }
-             else
-               old_bar2 = 0;
-
-             base64 = old_bar2;
-             base64 <<= 32;
-             base64 |= (old_bar1 & GRUB_PCI_ADDR_MEM_MASK);
-
-             grub_printf ("%s(%d): 0x%llx\n",
-                          ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) ?
-                           "VMEM" : "MMIO"), i,
-                          (unsigned long long) base64);
-
-             if ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) && (! found))
-               {
-                 *fb_base = base64;
-                 if (find_line_len (fb_base, line_len))
-                   found++;
-               }
-
-             if (type == GRUB_PCI_ADDR_MEM_TYPE_64)
-               {
-                 i++;
-                 addr += 4;
-               }
-           }
-       }
-
-      return found;
-    }
-
-  grub_pci_iterate (find_card);
-  return found;
-}
-
-grub_err_t
-grub_xnu_set_video (struct grub_xnu_boot_params *params)
-{
-  grub_efi_uga_draw_protocol_t *c;
-  grub_uint32_t width, height, depth, rate, pixel, fb_base, line_len;
-  int ret;
-
-  c = grub_efi_locate_protocol (&uga_draw_guid, 0);
-  if (! c)
-    return grub_error (GRUB_ERR_IO, "Couldn't find UGADraw");
-
-  if (efi_call_5 (c->get_mode, c, &width, &height, &depth, &rate))
-    return grub_error (GRUB_ERR_IO, "Couldn't retrieve video mode");
-
-  grub_printf ("Video mode: %ux%u-%u@%u\n", width, height, depth, rate);
-
-  grub_efi_set_text_mode (0);
-  pixel = RGB_MAGIC;
-  efi_call_10 (c->blt, c, (struct grub_efi_uga_pixel *) &pixel,
-              GRUB_EFI_UGA_VIDEO_FILL, 0, 0, 0, 0, 1, height, 0);
-  ret = find_framebuf (&fb_base, &line_len);
-  grub_efi_set_text_mode (1);
-
-  if (! ret)
-    return grub_error (GRUB_ERR_IO, "Can\'t find frame buffer address\n");
-
-  grub_printf ("Frame buffer base: 0x%x\n", fb_base);
-  grub_printf ("Video line length: %d\n", line_len);
-
-  params->lfb_width = width;
-  params->lfb_height = height;
-  params->lfb_depth = depth;
-  params->lfb_line_len = line_len;
-  params->lfb_mode = GRUB_XNU_VIDEO_TEXT_IN_VIDEO;
-  params->lfb_base = fb_base;
-  return GRUB_ERR_NONE;
-}
diff --git a/loader/i386/pc/xnu.c b/loader/i386/pc/xnu.c
deleted file mode 100644 (file)
index 839d0ad..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <grub/env.h>
-#include <grub/misc.h>
-#include <grub/xnu.h>
-#include <grub/mm.h>
-#include <grub/cpu/xnu.h>
-#include <grub/video_fb.h>
-
-#define min(a,b) (((a) < (b)) ? (a) : (b))
-#define max(a,b) (((a) > (b)) ? (a) : (b))
-
-#define DEFAULT_VIDEO_MODE "auto"
-
-/* Setup video for xnu. */
-grub_err_t
-grub_xnu_set_video (struct grub_xnu_boot_params *params)
-{
-  struct grub_video_mode_info mode_info;
-  int ret;
-  char *tmp, *modevar;
-  void *framebuffer;
-  grub_err_t err;
-
-  modevar = grub_env_get ("gfxpayload");
-  /* Consider only graphical 32-bit deep modes.  */
-  if (! modevar || *modevar == 0)
-    err = grub_video_set_mode (DEFAULT_VIDEO_MODE,
-                              GRUB_VIDEO_MODE_TYPE_PURE_TEXT
-                              | GRUB_VIDEO_MODE_TYPE_DEPTH_MASK,
-                              32 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS);
-  else
-    {
-      tmp = grub_malloc (grub_strlen (modevar)
-                        + sizeof (DEFAULT_VIDEO_MODE) + 1);
-      if (! tmp)
-       return grub_error (GRUB_ERR_OUT_OF_MEMORY,
-                          "couldn't allocate temporary storag");
-      grub_sprintf (tmp, "%s;" DEFAULT_VIDEO_MODE, modevar);
-      err = grub_video_set_mode (tmp,
-                                GRUB_VIDEO_MODE_TYPE_PURE_TEXT
-                                | GRUB_VIDEO_MODE_TYPE_DEPTH_MASK,
-                                32 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS);
-      grub_free (tmp);
-    }
-
-  if (err)
-    return err;
-
-  if (grub_xnu_bitmap)
-    {
-      int x, y;
-
-      x = mode_info.width - grub_xnu_bitmap->mode_info.width;
-      x /= 2;
-      y = mode_info.height - grub_xnu_bitmap->mode_info.height;
-      y /= 2;
-      err = grub_video_blit_bitmap (grub_xnu_bitmap,
-                                   GRUB_VIDEO_BLIT_REPLACE,
-                                   x > 0 ? x : 0,
-                                   y > 0 ? y : 0,
-                                   x < 0 ? -x : 0,
-                                   y < 0 ? -y : 0,
-                                   min (grub_xnu_bitmap->mode_info.width,
-                                        mode_info.width),
-                                   min (grub_xnu_bitmap->mode_info.height,
-                                        mode_info.height));
-      if (err)
-       {
-         grub_print_error ();
-         grub_errno = GRUB_ERR_NONE;
-         grub_xnu_bitmap = 0;
-       }
-      err = GRUB_ERR_NONE;
-    }
-
-  ret = grub_video_get_info_and_fini (&mode_info, &framebuffer);
-  if (ret)
-    return grub_error (GRUB_ERR_IO, "couldn't retrieve video parameters");
-
-  params->lfb_width = mode_info.width;
-  params->lfb_height = mode_info.height;
-  params->lfb_depth = mode_info.bpp;
-  params->lfb_line_len = mode_info.pitch;
-
-  params->lfb_base = PTR_TO_UINT32 (framebuffer);
-  params->lfb_mode = grub_xnu_bitmap
-    ? GRUB_XNU_VIDEO_SPLASH : GRUB_XNU_VIDEO_TEXT_IN_VIDEO;
-
-  return GRUB_ERR_NONE;
-}
-
index 6a353595013255be6d921af2778dfd655bf23975..23fbbe7e09b309f5355207b7a6ad6019a0f2f796 100644 (file)
 #include <grub/misc.h>
 #include <grub/term.h>
 
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+
+#define DEFAULT_VIDEO_MODE "auto"
+
 char grub_xnu_cmdline[1024];
 grub_uint32_t grub_xnu_heap_will_be_at;
 grub_uint32_t grub_xnu_entry_point, grub_xnu_arg1, grub_xnu_stack;
@@ -417,6 +422,84 @@ grub_xnu_boot_resume (void)
                                state);  
 }
 
+/* Setup video for xnu. */
+static grub_err_t
+grub_xnu_set_video (struct grub_xnu_boot_params *params)
+{
+  struct grub_video_mode_info mode_info;
+  int ret;
+  char *tmp, *modevar;
+  void *framebuffer;
+  grub_err_t err;
+
+  modevar = grub_env_get ("gfxpayload");
+  /* Consider only graphical 32-bit deep modes.  */
+  if (! modevar || *modevar == 0)
+    err = grub_video_set_mode (DEFAULT_VIDEO_MODE,
+                              GRUB_VIDEO_MODE_TYPE_PURE_TEXT
+                              | GRUB_VIDEO_MODE_TYPE_DEPTH_MASK,
+                              32 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS);
+  else
+    {
+      tmp = grub_malloc (grub_strlen (modevar)
+                        + sizeof (DEFAULT_VIDEO_MODE) + 1);
+      if (! tmp)
+       return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+                          "couldn't allocate temporary storag");
+      grub_sprintf (tmp, "%s;" DEFAULT_VIDEO_MODE, modevar);
+      err = grub_video_set_mode (tmp,
+                                GRUB_VIDEO_MODE_TYPE_PURE_TEXT
+                                | GRUB_VIDEO_MODE_TYPE_DEPTH_MASK,
+                                32 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS);
+      grub_free (tmp);
+    }
+
+  if (err)
+    return err;
+
+  if (grub_xnu_bitmap)
+    {
+      int x, y;
+
+      x = mode_info.width - grub_xnu_bitmap->mode_info.width;
+      x /= 2;
+      y = mode_info.height - grub_xnu_bitmap->mode_info.height;
+      y /= 2;
+      err = grub_video_blit_bitmap (grub_xnu_bitmap,
+                                   GRUB_VIDEO_BLIT_REPLACE,
+                                   x > 0 ? x : 0,
+                                   y > 0 ? y : 0,
+                                   x < 0 ? -x : 0,
+                                   y < 0 ? -y : 0,
+                                   min (grub_xnu_bitmap->mode_info.width,
+                                        mode_info.width),
+                                   min (grub_xnu_bitmap->mode_info.height,
+                                        mode_info.height));
+      if (err)
+       {
+         grub_print_error ();
+         grub_errno = GRUB_ERR_NONE;
+         grub_xnu_bitmap = 0;
+       }
+      err = GRUB_ERR_NONE;
+    }
+
+  ret = grub_video_get_info_and_fini (&mode_info, &framebuffer);
+  if (ret)
+    return grub_error (GRUB_ERR_IO, "couldn't retrieve video parameters");
+
+  params->lfb_width = mode_info.width;
+  params->lfb_height = mode_info.height;
+  params->lfb_depth = mode_info.bpp;
+  params->lfb_line_len = mode_info.pitch;
+
+  params->lfb_base = PTR_TO_UINT32 (framebuffer);
+  params->lfb_mode = grub_xnu_bitmap
+    ? GRUB_XNU_VIDEO_SPLASH : GRUB_XNU_VIDEO_TEXT_IN_VIDEO;
+
+  return GRUB_ERR_NONE;
+}
+
 /* Boot xnu. */
 grub_err_t
 grub_xnu_boot (void)