From 233d54ad3d1bfc58bbe9c408b51216c4cf1c9de8 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Imre=20Vad=C3=A1sz?= Date: Sun, 21 Feb 2016 16:28:39 +0100 Subject: [PATCH] pc64: Introduce machine/framebuffer.h header. Probe EFI fb. * Move struct fb_info definition from dev/drm/include/linux/fb.h to platform/pc64/include/framebuffer.h. * Implement EFI framebuffer probing in platform/pc64/x86_64/machdep.c. --- sys/dev/drm/include/linux/fb.h | 17 +------- sys/dev/misc/syscons/sckmsrndr.c | 3 +- sys/dev/misc/syscons/scvidctl.c | 2 +- sys/dev/misc/syscons/syscons.c | 2 +- sys/platform/pc64/include/framebuffer.h | 32 ++++++++++++++ sys/platform/pc64/x86_64/machdep.c | 57 +++++++++++++++++++++++++ 6 files changed, 94 insertions(+), 19 deletions(-) create mode 100644 sys/platform/pc64/include/framebuffer.h diff --git a/sys/dev/drm/include/linux/fb.h b/sys/dev/drm/include/linux/fb.h index 9768dabd14..3802ec42c9 100644 --- a/sys/dev/drm/include/linux/fb.h +++ b/sys/dev/drm/include/linux/fb.h @@ -34,22 +34,9 @@ #include #include -#define KHZ2PICOS(a) (1000000000UL/(a)) +#include -struct fb_info { - vm_offset_t vaddr; - vm_paddr_t paddr; - uint16_t width; - uint16_t height; - uint16_t stride; - uint16_t depth; - int is_vga_boot_display; - void *cookie; - void (*restore)(void *); - struct device *device; -}; - -extern int register_framebuffer(struct fb_info *fb_info); +#define KHZ2PICOS(a) (1000000000UL/(a)) extern int fb_get_options(const char *name, char **option); diff --git a/sys/dev/misc/syscons/sckmsrndr.c b/sys/dev/misc/syscons/sckmsrndr.c index 77a6fb52c5..a715a61de3 100644 --- a/sys/dev/misc/syscons/sckmsrndr.c +++ b/sys/dev/misc/syscons/sckmsrndr.c @@ -38,8 +38,7 @@ #include #include - -#include +#include #include "syscons.h" diff --git a/sys/dev/misc/syscons/scvidctl.c b/sys/dev/misc/syscons/scvidctl.c index 1cb2172175..705241393e 100644 --- a/sys/dev/misc/syscons/scvidctl.c +++ b/sys/dev/misc/syscons/scvidctl.c @@ -44,8 +44,8 @@ #include #include +#include -#include #include #include "syscons.h" diff --git a/sys/dev/misc/syscons/syscons.c b/sys/dev/misc/syscons/syscons.c index eb7d87aed8..f60fad150d 100644 --- a/sys/dev/misc/syscons/syscons.c +++ b/sys/dev/misc/syscons/syscons.c @@ -60,8 +60,8 @@ #include #include #include +#include -#include #include #include #include diff --git a/sys/platform/pc64/include/framebuffer.h b/sys/platform/pc64/include/framebuffer.h new file mode 100644 index 0000000000..d64579add3 --- /dev/null +++ b/sys/platform/pc64/include/framebuffer.h @@ -0,0 +1,32 @@ +#ifndef _MACHINE_FRAMEBUFFER_H_ +#define _MACHINE_FRAMEBUFFER_H_ + +#ifdef _KERNEL + +struct fb_info { + vm_offset_t vaddr; + vm_paddr_t paddr; + uint16_t width; + uint16_t height; + uint16_t stride; + uint16_t depth; + int is_vga_boot_display; + void *cookie; + void (*restore)(void *); + struct device *device; +}; + +int probe_efi_fb(int early); + +int register_framebuffer(struct fb_info *fb_info); +/* + * XXX If syscons isn't enabled in kernel config, provide a dummy + * inline implementation of register_framebuffer(). + */ + +extern struct fb_info efi_fb_info; +extern int have_efi_framebuffer; + +#endif /* _KERNEL */ + +#endif /* !_MACHINE_FRAMEBUFFER_H_ */ diff --git a/sys/platform/pc64/x86_64/machdep.c b/sys/platform/pc64/x86_64/machdep.c index 6fdc468da9..dfb81ab870 100644 --- a/sys/platform/pc64/x86_64/machdep.c +++ b/sys/platform/pc64/x86_64/machdep.c @@ -113,6 +113,7 @@ #endif #include #include +#include #ifdef OLD_BUS_ARCH #include @@ -1734,6 +1735,62 @@ add_efi_map_entries(int *physmap_idx) } } +struct fb_info efi_fb_info; +int have_efi_framebuffer = 0; + +static void +efi_fb_init_vaddr(void) +{ + uint64_t sz; + + sz = efi_fb_info.stride * efi_fb_info.height; + efi_fb_info.vaddr = PHYS_TO_DMAP(efi_fb_info.paddr); + pmap_change_attr(efi_fb_info.vaddr, (sz + PAGE_MASK) / PAGE_SIZE, + VM_MEMATTR_WRITE_COMBINING); + + if (efi_fb_info.vaddr != 0) + memset((void *)efi_fb_info.vaddr, 0x77, sz); +} + +int +probe_efi_fb(int early) +{ + struct efi_fb *efifb; + caddr_t kmdp; + + if (have_efi_framebuffer) { + if (!early && efi_fb_info.vaddr == 0) + efi_fb_init_vaddr(); + return 0; + } + + 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) + return 1; + + have_efi_framebuffer = 1; + + efi_fb_info.is_vga_boot_display = 1; + efi_fb_info.width = efifb->fb_width; + efi_fb_info.height = efifb->fb_height; + efi_fb_info.stride = efifb->fb_stride * 4; + efi_fb_info.depth = 32; + efi_fb_info.paddr = efifb->fb_addr; + if (early) { + efi_fb_info.vaddr = 0; + } else { + efi_fb_init_vaddr(); + } + efi_fb_info.restore = NULL; + efi_fb_info.device = NULL; + + return 0; +} + static void getmemsize(caddr_t kmdp, u_int64_t first) { -- 2.41.0