Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 16 Jun 2017 14:28:52 -0700
From:      Aaron Plattner <aplattner@nvidia.com>
To:        <cem@freebsd.org>
Cc:        "freebsd-hackers@freebsd.org" <freebsd-hackers@freebsd.org>
Subject:   Re: efifb framebuffer info for NVIDIA driver console restore
Message-ID:  <533f7954-61af-4121-3801-d9e5f02e4d35@nvidia.com>
In-Reply-To: <CAG6CVpVfEebrzpTD7T_3M5di256DKjOEPcMwVxn7ZoR2RhBJ9g@mail.gmail.com>
References:  <c84970b6-6e70-2648-a711-57753696b2b0@nvidia.com> <CAG6CVpVfEebrzpTD7T_3M5di256DKjOEPcMwVxn7ZoR2RhBJ9g@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
Thanks, that seems to work great! Unless someone has a better idea, I'll
ship something based on this with a future driver release.

On 06/16/2017 11:08 AM, Conrad Meyer wrote:
> 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?533f7954-61af-4121-3801-d9e5f02e4d35>