Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 16 Jun 2017 11:08:03 -0700
From:      Conrad Meyer <cem@freebsd.org>
To:        Aaron Plattner <aplattner@nvidia.com>
Cc:        "freebsd-hackers@freebsd.org" <freebsd-hackers@freebsd.org>
Subject:   Re: efifb framebuffer info for NVIDIA driver console restore
Message-ID:  <CAG6CVpVfEebrzpTD7T_3M5di256DKjOEPcMwVxn7ZoR2RhBJ9g@mail.gmail.com>
In-Reply-To: <c84970b6-6e70-2648-a711-57753696b2b0@nvidia.com>
References:  <c84970b6-6e70-2648-a711-57753696b2b0@nvidia.com>

next in thread | previous in thread | raw e-mail | index | archive | help
Hi Aaron,

I'm not sure it's the best way, but you could find EFI framebuffer
information in the same way the efifb vt(4) driver
(sys/dev/vt/hw/efifb/efifb.c) does, by inspecting the struct efi_fb
preload data (which is passed from the loader to the kernel).
Something like:

caddr_t kmdp;
struct efi_fb *efifb;

kmdp = preload_search_by_type("elf kernel");
if (kmdp == NULL)
        kmdp = preload_search_by_type("elf64 kernel");
efifb = (struct efi_fb *)preload_search_info(kmdp,
    MODINFO_METADATA | MODINFOMD_EFI_FB);
if (efifb != NULL)
        /* Found framebuffer information */;

Hope that helps,
Conrad

On Fri, Jun 16, 2017 at 9:51 AM, Aaron Plattner <aplattner@nvidia.com> wrote:
> Hi FreeBSD hackers,
>
> My name is Aaron Plattner. I'm a driver developer at NVIDIA working on
> the FreeBSD driver, among other things. I was hoping you could help me
> out regarding some changes I've been making to the driver.
>
> Recently, we've revamped how our driver handles switching from
> graphical modes to the console mode. For framebuffer consoles, the new
> nvidia_modeset module tries to take care of it without having to fall
> back to old-school VESA VBE modesets. However, in order for this to
> work, the driver needs to know where the framebuffer console is in
> physical memory, and its layout.
>
> On Linux, we get this information from the global 'screen_info'
> structure:
>
>   void NV_API_CALL os_get_screen_info(
>       NvU64 *pPhysicalAddress,
>       NvU16 *pFbWidth,
>       NvU16 *pFbHeight,
>       NvU16 *pFbDepth,
>       NvU16 *pFbPitch
>   )
>   {
>       //
>       // If there is not a framebuffer console, return 0 size.
>       //
>       // orig_video_isVGA is set to 1 during early Linux kernel
>       // initialization, and then will be set to a value, such as
>       // VIDEO_TYPE_VLFB or VIDEO_TYPE_EFI if an fbdev console is used.
>       //
>       if (screen_info.orig_video_isVGA <= 1)
>       {
>           *pPhysicalAddress = 0;
>           *pFbWidth = *pFbHeight = *pFbDepth = *pFbPitch = 0;
>           return;
>       }
>
>       *pPhysicalAddress = screen_info.lfb_base;
>   #if defined(VIDEO_CAPABILITY_64BIT_BASE)
>       *pPhysicalAddress |= (NvU64)screen_info.ext_lfb_base << 32;
>   #endif
>       *pFbWidth = screen_info.lfb_width;
>       *pFbHeight = screen_info.lfb_height;
>       *pFbDepth = screen_info.lfb_depth;
>       *pFbPitch = screen_info.lfb_linelength;
>   }
>
> This works for both legacy boot systems with vesafb as well as UEFI
> systems that use Linux's efifb.
>
> On FreeBSD, I was able to find this information on my legacy system:
>
>   void NV_API_CALL os_get_screen_info(
>       NvU64 *pPhysicalAddress,
>       NvU16 *pFbWidth,
>       NvU16 *pFbHeight,
>       NvU16 *pFbDepth,
>       NvU16 *pFbPitch
>   )
>   {
>       const sc_softc_t *sc = sc_get_softc(0, SC_KERNEL_CONSOLE);
>
>       if (sc)
>       {
>           const video_adapter_t *adp = sc->adp;
>
>           if (adp)
>           {
>               const struct video_info *vi = &adp->va_info;
>
>               if (vi && (vi->vi_flags & V_INFO_LINEAR))
>               {
>                   *pPhysicalAddress = vi->vi_buffer;
>                   *pFbWidth = vi->vi_width;
>                   *pFbHeight = vi->vi_height;
>                   *pFbDepth = vi->vi_depth;
>                   *pFbPitch = adp->va_line_width;
>                   return;
>               }
>           }
>       }
>
>       *pPhysicalAddress = 0;
>       *pFbWidth = *pFbHeight = *pFbDepth = *pFbPitch = 0;
>   }
>
> However, this doesn't work on UEFI systems because efifb doesn't go
> through the video_adapter_t stuff. Does anyone know how I can get that
> information from efifb, or who to talk to about adding an interface
> the driver can use to find it?
>
> Sincerely,
> Aaron
> _______________________________________________
> freebsd-hackers@freebsd.org mailing list
> https://lists.freebsd.org/mailman/listinfo/freebsd-hackers
> To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@freebsd.org"



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAG6CVpVfEebrzpTD7T_3M5di256DKjOEPcMwVxn7ZoR2RhBJ9g>