efifb framebuffer info for NVIDIA driver console restore
Aaron Plattner
aplattner at nvidia.com
Fri Jun 16 21:28:54 UTC 2017
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 at 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 at freebsd.org mailing list
>> https://lists.freebsd.org/mailman/listinfo/freebsd-hackers
>> To unsubscribe, send any mail to "freebsd-hackers-unsubscribe at freebsd.org"
>
More information about the freebsd-hackers
mailing list