On 12/07/2014 16:45, Vladimir 'φ-coder/phcoder' Serbinenko wrote:
> On 28.10.2014 21:32, Kris Moore wrote:
>> Got another patch for review today.
>>
>> This patch adds support for FreeBSD's new VT console driver when booting
>> in EFI mode on FreeBSD 10.1 and later.
>>
>> Please let me know any comments, or things that need addressed to get
>> this merged in.
>>
>> Thanks!
>>
>> -- Kris Moore PC-BSD Software iXsystems
>>
>>
>> patch-grub-fb
>>
>>
>> From a9c20c1640cdea0ba902095cb18760f5ebe98875 Mon Sep 17 00:00:00 2001
>> From: Kris Moore <k...@pcbsd.org>
>> Date: Tue, 28 Oct 2014 15:59:59 -0400
>> Subject: [PATCH 1/2] Add support for passing EFI framebuffer information to
>>  FreeBSD kernel on FreeBSD 10.1 and later.
>>
>> ---
>>  grub-core/loader/i386/bsd.c          | 75 
>> ++++++++++++++++++++++++++++++++++++
>>  grub-core/video/efi_gop.c            | 14 +++++++
>>  include/grub/i386/bsd.h              |  1 +
>>  include/grub/i386/freebsd_bootinfo.h | 33 ++++++++++++++++
>>  include/grub/video.h                 | 18 +++++++++
>>  5 files changed, 141 insertions(+)
>>  create mode 100644 include/grub/i386/freebsd_bootinfo.h
>>
>> diff --git grub-core/loader/i386/bsd.c grub-core/loader/i386/bsd.c
>> index 8f691e0..c685552 100644
>> --- grub-core/loader/i386/bsd.c
>> +++ grub-core/loader/i386/bsd.c
>> @@ -48,6 +48,7 @@ GRUB_MOD_LICENSE ("GPLv3+");
>>  #ifdef GRUB_MACHINE_EFI
>>  #include <grub/efi/efi.h>
>>  #define NETBSD_DEFAULT_VIDEO_MODE "800x600"
>> +#define FREEBSD_DEFAULT_VIDEO_MODE "800x600"
>>  #else
>>  #define NETBSD_DEFAULT_VIDEO_MODE "text"
>>  #include <grub/i386/pc/vbe.h>
>> @@ -584,6 +585,63 @@ freebsd_get_zfs (void)
>>    grub_free (uuid);
>>  }
>>  
>> +#ifdef GRUB_MACHINE_EFI
>> +
>> +static grub_err_t
>> +grub_freebsd_setup_video (void)
>> +{
>> +  struct grub_video_mode_info mode_info;
>> +  void *framebuffer;
>> +  const char *modevar;
>> +  struct grub_freebsd_btinfo_framebuf efifb;
>> +  grub_err_t err;
>> +  grub_video_driver_id_t driv_id;
>> +
>> +  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)
>> +    {
>> +      char *tmp;
>> +      tmp = grub_xasprintf ("%s;" FREEBSD_DEFAULT_VIDEO_MODE, modevar);
>> +      if (! tmp)
>> +    return grub_errno;
>> +      err = grub_video_set_mode (tmp, 0, 0);
>> +      grub_free (tmp);
>> +    }
>> +  else
>> +    err = grub_video_set_mode (FREEBSD_DEFAULT_VIDEO_MODE, 0, 0);
>> +
>> +  if (err)
>> +    return err;
>> +
>> +  driv_id = grub_video_get_driver_id ();
>> +  if (driv_id == GRUB_VIDEO_DRIVER_NONE)
>> +    return GRUB_ERR_NONE;
>> +
>> +  err = grub_video_get_info_and_fini (&mode_info, &framebuffer);
>> +
>> +  if (err)
>> +    return err;
>> +
>> +  efifb.fb_width = mode_info.width;
>> +  efifb.fb_height = mode_info.height;
>> +  efifb.fb_stride = mode_info.stride;
>> +
>> +  efifb.fb_addr = (grub_addr_t) framebuffer;
>> +  efifb.fb_size = ALIGN_UP (mode_info.pitch * efifb.fb_height, 65536);
>> +
>> +  efifb.fb_mask_red = mode_info.red_mask;
>> +  efifb.fb_mask_green = mode_info.green_mask;
>> +  efifb.fb_mask_blue = mode_info.blue_mask;
>> +  efifb.fb_mask_reserved = mode_info.reserved_mask;
>> +
>> +  err = grub_bsd_add_meta ( FREEBSD_MODINFO_METADATA | 
>> FREEBSD_BTINFO_FRAMEBUF, &efifb, sizeof (efifb));
>> +  return err;
>> +}
>> +#endif
>> +
>>  static grub_err_t
>>  grub_freebsd_boot (void)
>>  {
>> @@ -687,6 +745,10 @@ grub_freebsd_boot (void)
>>              *(grub_uint32_t *) p_tag = bootflags;
>>            break;
>>  
>> +        case FREEBSD_MODINFO_METADATA | FREEBSD_BTINFO_FRAMEBUF:
>> +          grub_memcpy (p_tag, tag->data, tag->len);
>> +          break;
>> +
>>          case FREEBSD_MODINFO_METADATA | FREEBSD_MODINFOMD_ENVP:
>>            if (is_64bit)
>>              *(grub_uint64_t *) p_tag = bi.environment;
>> @@ -716,7 +778,10 @@ grub_freebsd_boot (void)
>>  
>>    bi.kern_end = kern_end;
>>  
>> +#ifndef GRUB_MACHINE_EFI
>> +  /* Don't set text mode on EFI boot */
>>    grub_video_set_mode ("text", 0, 0);
>> +#endif
>>  
>>    if (is_64bit)
>>      {
>> @@ -1560,6 +1625,16 @@ grub_cmd_freebsd (grub_extcmd_context_t ctxt, int 
>> argc, char *argv[])
>>                                 FREEBSD_MODINFOMD_KERNEND, &data, len);
>>        if (err)
>>          return err;
>> +
>> +#ifdef GRUB_MACHINE_EFI
>> +      err = grub_freebsd_setup_video ();
>> +      if (err)
>> +      {
>> +        grub_print_error ();
>> +        grub_puts_ (N_("Booting in EFI blind mode"));
>> +        grub_errno = GRUB_ERR_NONE;
>> +      }
>> +#endif
>>      }
>>        grub_bsd_get_device (&freebsd_biosdev, &unit, &slice, &part);
>>        freebsd_zfsguid = 0;
>> diff --git grub-core/video/efi_gop.c grub-core/video/efi_gop.c
>> index 7f9d1c2..cfe0119 100644
>> --- grub-core/video/efi_gop.c
>> +++ grub-core/video/efi_gop.c
>> @@ -180,6 +180,8 @@ grub_video_gop_fill_real_mode_info (unsigned mode,
>>    out->mode_type = GRUB_VIDEO_MODE_TYPE_RGB;
>>    out->bpp = grub_video_gop_get_bpp (in);
>>    out->bytes_per_pixel = out->bpp >> 3;
>> +  out->stride = in->pixels_per_scanline;
>> +  out->pixel_format = in->pixel_format;
> Please, don't add redundant fields to structs. All this info can be
> inferred from available fields in FreeBSD code. As a bonus it will work
> with other gfx drivers.
> Another point: is this driver usable on non-EFI? It's of particular
> interest on coreboot where changing video mode currently requires reflash.
>
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> https://lists.gnu.org/mailman/listinfo/grub-devel

Attached is a cleaned up version of the patch which doesn't add to any
existing structs now. Let me know if this is closer to what you had in
mind.

I don't think this driver is usable on non-EFI FreeBSD yet. They have a
new VT console driver, but I'm not sure their loader does video mode
passthrough outside of EFI. I'm sure it will in the future, probably
sometime in 11.X.

-- 
Kris Moore
PC-BSD Software
iXsystems

From 997363ec7698f34d74769960c4e76cf8b369052e Mon Sep 17 00:00:00 2001
From: Kris Moore <k...@pcbsd.org>
Date: Tue, 30 Dec 2014 14:34:58 -0500
Subject: [PATCH] Add the patch for FreeBSD UEFI booting / framebuffer
 passthrough, add fixes to ACPI environment variables while here

---
 ChangeLog                            |   9 +++
 grub-core/loader/i386/bsd.c          | 134 +++++++++++++++++++++++++++++++++++
 include/grub/i386/bsd.h              |   1 +
 include/grub/i386/freebsd_bootinfo.h |  33 +++++++++
 4 files changed, 177 insertions(+)
 create mode 100644 include/grub/i386/freebsd_bootinfo.h

diff --git ChangeLog ChangeLog
index c38917b..b717a2d 100644
--- ChangeLog
+++ ChangeLog
@@ -1,3 +1,12 @@
+2014-12-30  Kris Moore  <k...@pcbsd.org>
+       * grub-core/loader/i386/bsd.c: Set FreeBSD specific ACPI hints when 
booting
+       in EFI mode
+       * grub-core/loader/i386/bsd.c: Add default FreeBSD EFI video mode, and
+       structure to pass information into EFI booted kernel
+       * include/grub/i386/bsd.h: Include new freebsd_bootinfo.h
+       * include/grub/i386/freebsd_bootinfo.h: Add grub_freebsd_btinfo_framebuf
+       structure for FreeBSD EFI framebuffer passthrough
+
 2014-12-09  Andrei Borzenkov  <arvidj...@gmail.com>
 
        * grub-core/term/serial.c (grub_cmd_serial): Fix --rtscts
diff --git grub-core/loader/i386/bsd.c grub-core/loader/i386/bsd.c
index 8f691e0..9d51cff 100644
--- grub-core/loader/i386/bsd.c
+++ grub-core/loader/i386/bsd.c
@@ -42,12 +42,14 @@
 GRUB_MOD_LICENSE ("GPLv3+");
 
 #include <grub/video.h>
+#include <grub/acpi.h>
 #ifdef GRUB_MACHINE_PCBIOS
 #include <grub/machine/biosnum.h>
 #endif
 #ifdef GRUB_MACHINE_EFI
 #include <grub/efi/efi.h>
 #define NETBSD_DEFAULT_VIDEO_MODE "800x600"
+#define FREEBSD_DEFAULT_VIDEO_MODE "800x600"
 #else
 #define NETBSD_DEFAULT_VIDEO_MODE "text"
 #include <grub/i386/pc/vbe.h>
@@ -584,6 +586,72 @@ freebsd_get_zfs (void)
   grub_free (uuid);
 }
 
+#ifdef GRUB_MACHINE_EFI
+
+static grub_err_t
+grub_freebsd_setup_video (void)
+{
+  struct grub_video_mode_info mode_info;
+  void *framebuffer;
+  const char *modevar;
+  struct grub_freebsd_btinfo_framebuf efifb;
+  grub_err_t err;
+  grub_video_driver_id_t driv_id;
+
+  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)
+    {
+      char *tmp;
+      tmp = grub_xasprintf ("%s;" FREEBSD_DEFAULT_VIDEO_MODE, modevar);
+      if (! tmp)
+       return grub_errno;
+      err = grub_video_set_mode (tmp, 0, 0);
+      grub_free (tmp);
+    }
+  else
+    err = grub_video_set_mode (FREEBSD_DEFAULT_VIDEO_MODE, 0, 0);
+
+  if (err)
+    return err;
+
+  driv_id = grub_video_get_driver_id ();
+  if (driv_id == GRUB_VIDEO_DRIVER_NONE)
+    return GRUB_ERR_NONE;
+
+  err = grub_video_get_info_and_fini (&mode_info, &framebuffer);
+
+  if (err)
+    return err;
+
+  efifb.fb_width = mode_info.width;
+  efifb.fb_height = mode_info.height;
+  efifb.fb_stride = mode_info.pitch / mode_info.bytes_per_pixel;
+
+  efifb.fb_addr = (grub_addr_t) framebuffer;
+  efifb.fb_size = ALIGN_UP (mode_info.pitch * efifb.fb_height, 65536);
+
+  if ( mode_info.blue_field_pos == 16 ) {
+    efifb.fb_mask_red = 0x000000ff;
+    efifb.fb_mask_green = 0x0000ff00;
+    efifb.fb_mask_blue = 0x00ff0000;
+  }
+
+  if ( mode_info.blue_field_pos == 0 ) {
+    efifb.fb_mask_red = 0x00ff0000;
+    efifb.fb_mask_green = 0x0000ff00;
+    efifb.fb_mask_blue = 0x000000ff;
+  }
+
+  efifb.fb_mask_reserved = 0xff000000;
+
+  err = grub_bsd_add_meta ( FREEBSD_MODINFO_METADATA | 
FREEBSD_BTINFO_FRAMEBUF, &efifb, sizeof (efifb));
+  return err;
+}
+#endif
+
 static grub_err_t
 grub_freebsd_boot (void)
 {
@@ -602,6 +670,55 @@ grub_freebsd_boot (void)
 
   bi.boot_device = freebsd_biosdev;
 
+#ifdef GRUB_MACHINE_EFI
+  /* When booting in EFI mode, we need to export some additional kernel ACPI 
hints */
+  struct grub_acpi_rsdp_v10 *v1;
+  struct grub_acpi_rsdp_v20 *v2;
+  v1 = grub_acpi_get_rsdpv1 ();
+  v2 = grub_acpi_get_rsdpv2 ();
+  if (v2 && v2->length > 40)
+    v2 = 0;
+
+  int revision;
+  char acpiBuf[24];
+
+  if (v1)
+  {
+     revision = v1->revision;
+     if ( revision == 0 )
+        revision = 1;
+     grub_snprintf (acpiBuf, sizeof (acpiBuf), "%d", revision);
+     grub_env_set("kFreeBSD.hint.acpi.0.revision", acpiBuf);
+
+     grub_snprintf (acpiBuf, sizeof (acpiBuf), "%s", v1->oemid);
+     grub_env_set("kFreeBSD.hint.acpi.0.oem", acpiBuf);
+
+     grub_snprintf (acpiBuf, sizeof (acpiBuf), "0x%016x", v1->rsdt_addr);
+     grub_env_set("kFreeBSD.hint.acpi.0.rsdt", acpiBuf);
+
+     grub_snprintf (acpiBuf, sizeof (acpiBuf), "0x%016llx", (unsigned long 
long)v1);
+     grub_env_set("kFreeBSD.hint.acpi.0.rsdp", acpiBuf);
+  }
+
+  if (v2)
+  {
+     revision = v2->rsdpv1.revision;
+     if ( revision == 0 )
+        revision = 1;
+
+     grub_snprintf (acpiBuf, sizeof (acpiBuf), "%d", revision);
+     grub_env_set("kFreeBSD.hint.acpi.0.revision", acpiBuf);
+
+     grub_snprintf (acpiBuf, sizeof (acpiBuf), "0x%016llx", (unsigned long 
long)v2->xsdt_addr);
+     grub_env_set("kFreeBSD.hint.acpi.0.xsdt", acpiBuf);
+
+     grub_snprintf (acpiBuf, sizeof (acpiBuf), "%d", v2->length);
+     grub_env_set("kFreeBSD.hint.acpi.0.xsdt_length", acpiBuf);
+  }
+
+
+#endif
+
   p_size = 0;
   FOR_SORTED_ENV (var)
     if ((grub_memcmp (var->name, "kFreeBSD.", sizeof("kFreeBSD.") - 1) == 0) 
&& (var->name[sizeof("kFreeBSD.") - 1]))
@@ -687,6 +804,10 @@ grub_freebsd_boot (void)
                *(grub_uint32_t *) p_tag = bootflags;
              break;
 
+           case FREEBSD_MODINFO_METADATA | FREEBSD_BTINFO_FRAMEBUF:
+             grub_memcpy (p_tag, tag->data, tag->len);
+             break;
+
            case FREEBSD_MODINFO_METADATA | FREEBSD_MODINFOMD_ENVP:
              if (is_64bit)
                *(grub_uint64_t *) p_tag = bi.environment;
@@ -716,7 +837,10 @@ grub_freebsd_boot (void)
 
   bi.kern_end = kern_end;
 
+#ifndef GRUB_MACHINE_EFI
+  /* Don't set text mode on EFI boot */
   grub_video_set_mode ("text", 0, 0);
+#endif
 
   if (is_64bit)
     {
@@ -1560,6 +1684,16 @@ grub_cmd_freebsd (grub_extcmd_context_t ctxt, int argc, 
char *argv[])
                                   FREEBSD_MODINFOMD_KERNEND, &data, len);
          if (err)
            return err;
+
+#ifdef GRUB_MACHINE_EFI
+         err = grub_freebsd_setup_video ();
+         if (err)
+         {
+           grub_print_error ();
+           grub_puts_ (N_("Booting in EFI blind mode"));
+           grub_errno = GRUB_ERR_NONE;
+         }
+#endif
        }
       grub_bsd_get_device (&freebsd_biosdev, &unit, &slice, &part);
       freebsd_zfsguid = 0;
diff --git include/grub/i386/bsd.h include/grub/i386/bsd.h
index 524d47a..b7bb545 100644
--- include/grub/i386/bsd.h
+++ include/grub/i386/bsd.h
@@ -26,6 +26,7 @@
 #include <grub/i386/netbsd_reboot.h>
 #include <grub/i386/openbsd_reboot.h>
 #include <grub/i386/freebsd_linker.h>
+#include <grub/i386/freebsd_bootinfo.h>
 #include <grub/i386/netbsd_bootinfo.h>
 #include <grub/i386/openbsd_bootarg.h>
 
diff --git include/grub/i386/freebsd_bootinfo.h 
include/grub/i386/freebsd_bootinfo.h
new file mode 100644
index 0000000..17e5997
--- /dev/null
+++ include/grub/i386/freebsd_bootinfo.h
@@ -0,0 +1,33 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2008,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/types.h>
+
+#define FREEBSD_BTINFO_FRAMEBUF  0x1005
+
+struct grub_freebsd_btinfo_framebuf {
+  grub_uint64_t        fb_addr;
+  grub_uint64_t        fb_size;
+  grub_int32_t         fb_height;
+  grub_int32_t         fb_width;
+  grub_int32_t         fb_stride;
+  grub_uint32_t        fb_mask_red;
+  grub_uint32_t        fb_mask_green;
+  grub_uint32_t        fb_mask_blue;
+  grub_uint32_t        fb_mask_reserved;
+};
-- 
2.2.1

_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to