pc64: Introduce machine/framebuffer.h header. Probe EFI fb.
authorImre Vadász <imre@vdsz.com>
Sun, 21 Feb 2016 15:28:39 +0000 (16:28 +0100)
committerImre Vadasz <imre@vdsz.com>
Sun, 21 Feb 2016 20:35:23 +0000 (21:35 +0100)
* 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
sys/dev/misc/syscons/sckmsrndr.c
sys/dev/misc/syscons/scvidctl.c
sys/dev/misc/syscons/syscons.c
sys/platform/pc64/include/framebuffer.h [new file with mode: 0644]
sys/platform/pc64/x86_64/machdep.c

index 9768dab..3802ec4 100644 (file)
 #include <linux/list.h>
 #include <linux/backlight.h>
 
-#define        KHZ2PICOS(a)    (1000000000UL/(a))
+#include <machine/framebuffer.h>
 
-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);
 
index 77a6fb5..a715a61 100644 (file)
@@ -38,8 +38,7 @@
 #include <sys/thread2.h>
 
 #include <machine/console.h>
-
-#include <dev/drm/include/linux/fb.h>
+#include <machine/framebuffer.h>
 
 #include "syscons.h"
 
index 1cb2172..7052413 100644 (file)
@@ -44,8 +44,8 @@
 #include <sys/thread2.h>
 
 #include <machine/console.h>
+#include <machine/framebuffer.h>
 
-#include <dev/drm/include/linux/fb.h>
 #include <dev/video/fb/fbreg.h>
 #include "syscons.h"
 
index eb7d87a..f60fad1 100644 (file)
@@ -60,8 +60,8 @@
 #include <machine/psl.h>
 #include <machine/pc/display.h>
 #include <machine/frame.h>
+#include <machine/framebuffer.h>
 
-#include <dev/drm/include/linux/fb.h>
 #include <dev/misc/kbd/kbdreg.h>
 #include <dev/video/fb/fbreg.h>
 #include <dev/video/fb/splashreg.h>
diff --git a/sys/platform/pc64/include/framebuffer.h b/sys/platform/pc64/include/framebuffer.h
new file mode 100644 (file)
index 0000000..d64579a
--- /dev/null
@@ -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_ */
index 6fdc468..dfb81ab 100644 (file)
 #endif
 #include <machine/cputypes.h>
 #include <machine/intr_machdep.h>
+#include <machine/framebuffer.h>
 
 #ifdef OLD_BUS_ARCH
 #include <bus/isa/isa_device.h>
@@ -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)
 {