efifb framebuffer info for NVIDIA driver console restore
Conrad Meyer
cem at freebsd.org
Sat Jun 17 02:46:14 UTC 2017
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