summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorYASUOKA Masahiko <yasuoka@cvs.openbsd.org>2015-08-30 10:05:10 +0000
committerYASUOKA Masahiko <yasuoka@cvs.openbsd.org>2015-08-30 10:05:10 +0000
commit6511681351d80cffa4c99567b91f501f17778efe (patch)
tree849a21b05362c2cbd322be85e93b1bd95eddc13f /sys
parent64b346d82ea0177e765dadf5172fd8663edb52b2 (diff)
Modify kernel to prepare boot from UEFI.
- Add new boot arg "bios_efi_info_t" to pass the paramters from UEFI - Make bios(4) and acpi(4) be able to probe with the parameters from UEFI - Add efifb(8). It uses the framebuffer from UEFI and it will work as a backend of wsdisplay(4) and wsfb (X11 video driver). Disabled by the kernel config for this moment input and ok kettenis
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/amd64/amd64/acpi_machdep.c15
-rw-r--r--sys/arch/amd64/amd64/bios.c73
-rw-r--r--sys/arch/amd64/amd64/efifb.c300
-rw-r--r--sys/arch/amd64/amd64/machdep.c14
-rw-r--r--sys/arch/amd64/amd64/mainbus.c7
-rw-r--r--sys/arch/amd64/amd64/wscons_machdep.c26
-rw-r--r--sys/arch/amd64/conf/GENERIC5
-rw-r--r--sys/arch/amd64/conf/files.amd649
-rw-r--r--sys/arch/amd64/include/biosvar.h18
-rw-r--r--sys/arch/amd64/include/efifbvar.h19
-rw-r--r--sys/dev/wscons/wsconsio.h3
11 files changed, 447 insertions, 42 deletions
diff --git a/sys/arch/amd64/amd64/acpi_machdep.c b/sys/arch/amd64/amd64/acpi_machdep.c
index 62fc59607af..fea60bf9ead 100644
--- a/sys/arch/amd64/amd64/acpi_machdep.c
+++ b/sys/arch/amd64/amd64/acpi_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpi_machdep.c,v 1.70 2015/03/16 20:31:47 deraadt Exp $ */
+/* $OpenBSD: acpi_machdep.c,v 1.71 2015/08/30 10:05:09 yasuoka Exp $ */
/*
* Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
*
@@ -137,7 +137,18 @@ acpi_probe(struct device *parent, struct cfdata *match,
paddr_t ebda;
/*
- * First try to find ACPI table entries in the EBDA
+ * First try to scan the ACPI table passed by parent if any
+ */
+ if (ba->ba_acpipbase != 0) {
+ if (acpi_scan(&handle, ba->ba_acpipbase, 16) != NULL) {
+ acpi_unmap(&handle);
+ return (1);
+ }
+ ba->ba_acpipbase = 0;
+ }
+
+ /*
+ * Next try to find ACPI table entries in the EBDA
*/
if (acpi_map(0, NBPG, &handle))
printf("acpi: failed to map BIOS data area\n");
diff --git a/sys/arch/amd64/amd64/bios.c b/sys/arch/amd64/amd64/bios.c
index a4fff7badc2..21c023302c5 100644
--- a/sys/arch/amd64/amd64/bios.c
+++ b/sys/arch/amd64/amd64/bios.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bios.c,v 1.31 2015/03/14 03:38:46 jsg Exp $ */
+/* $OpenBSD: bios.c,v 1.32 2015/08/30 10:05:09 yasuoka Exp $ */
/*
* Copyright (c) 2006 Gordon Willem Klok <gklok@cogeco.ca>
*
@@ -46,6 +46,7 @@ struct bios_softc {
struct device sc_dev;
};
+struct smbhdr *smbios_find(u_int8_t *);
void smbios_info(char *);
int bios_match(struct device *, void *, void *);
void bios_attach(struct device *, struct device *, void *);
@@ -95,35 +96,28 @@ bios_attach(struct device *parent, struct device *self, void *aux)
paddr_t pa, end;
u_int8_t *p;
int smbiosrev = 0;
+ struct smbhdr *hdr = NULL;
- /* see if we have SMBIOS extentions */
- for (p = ISA_HOLE_VADDR(SMBIOS_START);
- p < (u_int8_t *)ISA_HOLE_VADDR(SMBIOS_END); p+= 16) {
- struct smbhdr * hdr = (struct smbhdr *)p;
- u_int8_t chksum;
- int i;
-
- if (hdr->sig != SMBIOS_SIGNATURE)
- continue;
- i = hdr->len;
- for (chksum = 0; i--; chksum += p[i])
- ;
- if (chksum != 0)
- continue;
- p += 0x10;
- if (p[0] != '_' && p[1] != 'D' && p[2] != 'M' &&
- p[3] != 'I' && p[4] != '_')
- continue;
- for (chksum = 0, i = 0xf; i--; chksum += p[i])
- ;
- if (chksum != 0)
- continue;
+ if (bios_efiinfo != NULL && bios_efiinfo->config_smbios != 0)
+ hdr = smbios_find(PMAP_DIRECT_MAP(
+ (u_int8_t *)bios_efiinfo->config_smbios));
+
+ if (hdr == NULL) {
+ /* see if we have SMBIOS extentions */
+ for (p = ISA_HOLE_VADDR(SMBIOS_START);
+ p < (u_int8_t *)ISA_HOLE_VADDR(SMBIOS_END); p+= 16) {
+ hdr = smbios_find(p);
+ if (hdr == NULL)
+ continue;
+ }
+ }
+ if (hdr != NULL) {
pa = trunc_page(hdr->addr);
end = round_page(hdr->addr + hdr->size);
va = uvm_km_valloc(kernel_map, end-pa);
if (va == 0)
- break;
+ goto out;
smbios_entry.addr = (u_int8_t *)(va + (hdr->addr & PGOFSET));
smbios_entry.len = hdr->size;
@@ -159,8 +153,8 @@ bios_attach(struct device *parent, struct device *self, void *aux)
}
smbios_info(sc->sc_dev.dv_xname);
- break;
}
+out:
printf("\n");
/* No SMBIOS extensions, go looking for Soekris comBIOS */
@@ -205,6 +199,9 @@ bios_attach(struct device *parent, struct device *self, void *aux)
ba.ba_iot = X86_BUS_SPACE_IO;
ba.ba_memt = X86_BUS_SPACE_MEM;
+ if (bios_efiinfo != NULL)
+ ba.ba_acpipbase = bios_efiinfo->config_acpi;
+
config_found(self, &ba, bios_print);
}
#endif
@@ -223,6 +220,32 @@ bios_attach(struct device *parent, struct device *self, void *aux)
#endif
}
+struct smbhdr *
+smbios_find(u_int8_t *p)
+{
+ struct smbhdr * hdr = (struct smbhdr *)p;
+ u_int8_t chksum;
+ int i;
+
+ if (hdr->sig != SMBIOS_SIGNATURE)
+ return (NULL);
+ i = hdr->len;
+ for (chksum = 0; i--; chksum += p[i])
+ ;
+ if (chksum != 0)
+ return (NULL);
+ p += 0x10;
+ if (p[0] != '_' && p[1] != 'D' && p[2] != 'M' && p[3] != 'I' &&
+ p[4] != '_')
+ return (NULL);
+ for (chksum = 0, i = 0xf; i--; chksum += p[i])
+ ;
+ if (chksum != 0)
+ return (NULL);
+
+ return (hdr);
+}
+
/*
* smbios_find_table() takes a caller supplied smbios struct type and
* a pointer to a handle (struct smbtable) returning one if the structure
diff --git a/sys/arch/amd64/amd64/efifb.c b/sys/arch/amd64/amd64/efifb.c
new file mode 100644
index 00000000000..064522935a8
--- /dev/null
+++ b/sys/arch/amd64/amd64/efifb.c
@@ -0,0 +1,300 @@
+/* $OpenBSD: efifb.c,v 1.1 2015/08/30 10:05:09 yasuoka Exp $ */
+
+/*
+ * Copyright (c) 2015 YASUOKA Masahiko <yasuoka@yasuoka.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <uvm/uvm_extern.h>
+#include <machine/bus.h>
+
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wsdisplayvar.h>
+#include <dev/rasops/rasops.h>
+
+#include <machine/biosvar.h>
+#include <machine/efifbvar.h>
+
+struct efifb {
+ struct rasops_info rinfo;
+ int depth;
+ paddr_t paddr;
+ psize_t psize;
+};
+
+struct efifb_softc {
+ struct device sc_dev;
+ struct efifb *sc_fb;
+};
+
+int efifb_match(struct device *, void *, void *);
+void efifb_attach(struct device *, struct device *, void *);
+void efifb_rasops_preinit(struct efifb *);
+int efifb_ioctl(void *, u_long, caddr_t, int, struct proc *);
+paddr_t efifb_mmap(void *, off_t, int);
+int efifb_alloc_screen(void *, const struct wsscreen_descr *, void **,
+ int *, int *, long *);
+void efifb_free_screen(void *, void *);
+int efifb_show_screen(void *, void *, int, void (*cb) (void *, int, int),
+ void *);
+int efifb_list_font(void *, struct wsdisplay_font *);
+int efifb_load_font(void *, void *, struct wsdisplay_font *);
+
+struct cfattach efifb_ca = {
+ sizeof(struct efifb_softc), efifb_match, efifb_attach, NULL
+};
+
+#define EFIFB_WIDTH 100
+#define EFIFB_HEIGHT 31
+
+struct wsscreen_descr efifb_std_descr = { "std" };
+
+const struct wsscreen_descr *efifb_descrs[] = {
+ &efifb_std_descr
+};
+
+const struct wsscreen_list efifb_screen_list = {
+ nitems(efifb_descrs), efifb_descrs
+};
+
+struct wsdisplay_accessops efifb_accessops = {
+ .ioctl = efifb_ioctl,
+ .mmap = efifb_mmap,
+ .alloc_screen = efifb_alloc_screen,
+ .free_screen = efifb_free_screen,
+ .show_screen = efifb_show_screen,
+ .load_font = efifb_load_font,
+ .list_font = efifb_list_font
+};
+
+struct cfdriver efifb_cd = {
+ NULL, "efifb", DV_DULL
+};
+
+struct efifb efifb_console;
+
+int
+efifb_match(struct device *parent, void *cf, void *aux)
+{
+ if (bios_efiinfo != NULL)
+ return (1);
+
+ return (0);
+}
+
+void
+efifb_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct efifb *fb;
+ struct efifb_softc *sc = (struct efifb_softc *)self;
+ struct wsemuldisplaydev_attach_args
+ aa;
+ struct rasops_info *ri;
+ int ccol = 0, crow = 0;
+ long defattr;
+
+ printf("\n");
+
+ if (1) { /* XXX console */
+ aa.console = 1;
+ fb = sc->sc_fb = &efifb_console;
+ ri = &fb->rinfo;
+ ccol = ri->ri_ccol;
+ crow = ri->ri_crow;
+
+ efifb_rasops_preinit(fb);
+ ri->ri_flg &= ~RI_CLEAR;
+ ri->ri_flg |= RI_VCONS;
+
+ rasops_init(ri, efifb_std_descr.nrows, efifb_std_descr.ncols);
+ }
+
+ aa.scrdata = &efifb_screen_list;
+ aa.accessops = &efifb_accessops;
+ aa.accesscookie = sc;
+ aa.defaultscreens = 0;
+
+ ri->ri_ops.alloc_attr(ri->ri_active, 0, 0, 0, &defattr);
+ wsdisplay_cnattach(&efifb_std_descr, ri->ri_active, ccol, crow, defattr);
+
+ config_found(self, &aa, wsemuldisplaydevprint);
+}
+
+void
+efifb_rasops_preinit(struct efifb *fb)
+{
+#define bmnum(_x) (fls(_x) - ffs(_x) + 1)
+#define bmpos(_x) (ffs(_x) - 1)
+ struct rasops_info *ri = &fb->rinfo;
+
+ ri->ri_width = bios_efiinfo->fb_width;
+ ri->ri_height = bios_efiinfo->fb_height;
+ ri->ri_depth = fb->depth;
+ ri->ri_stride = bios_efiinfo->fb_pixpsl * (fb->depth / 8);
+ ri->ri_rnum = bmnum(bios_efiinfo->fb_red_mask);
+ ri->ri_rpos = bmpos(bios_efiinfo->fb_red_mask);
+ ri->ri_gnum = bmnum(bios_efiinfo->fb_green_mask);
+ ri->ri_gpos = bmpos(bios_efiinfo->fb_green_mask);
+ ri->ri_bnum = bmnum(bios_efiinfo->fb_blue_mask);
+ ri->ri_bpos = bmpos(bios_efiinfo->fb_blue_mask);
+}
+
+int
+efifb_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
+{
+ struct efifb_softc *sc = v;
+ struct efifb *fb = sc->sc_fb;
+ struct rasops_info *ri = &fb->rinfo;
+ struct wsdisplay_fbinfo *wdf;
+
+ switch (cmd) {
+ case WSDISPLAYIO_GTYPE:
+ *(u_int *)data = WSDISPLAY_TYPE_EFIFB;
+ break;
+ case WSDISPLAYIO_GINFO:
+ wdf = (struct wsdisplay_fbinfo *)data;
+ wdf->width = ri->ri_width;
+ wdf->height = ri->ri_height;
+ wdf->depth = ri->ri_depth;
+ wdf->cmsize = 0; /* color map is unavailable */
+ break;
+ case WSDISPLAYIO_LINEBYTES:
+ *(u_int *)data = ri->ri_stride;
+ break;
+ case WSDISPLAYIO_SMODE:
+ break;
+ case WSDISPLAYIO_GETSUPPORTEDDEPTH:
+ /* can't change the depth */
+ if (ri->ri_depth == 32 || ri->ri_depth == 24)
+ *(u_int *)data = WSDISPLAYIO_DEPTH_24;
+ else if (ri->ri_depth == 16)
+ *(u_int *)data = WSDISPLAYIO_DEPTH_16;
+ else if (ri->ri_depth == 15)
+ *(u_int *)data = WSDISPLAYIO_DEPTH_15;
+ else if (ri->ri_depth == 8)
+ *(u_int *)data = WSDISPLAYIO_DEPTH_8;
+ else if (ri->ri_depth == 4)
+ *(u_int *)data = WSDISPLAYIO_DEPTH_4;
+ else if (ri->ri_depth == 1)
+ *(u_int *)data = WSDISPLAYIO_DEPTH_1;
+ else
+ return (-1);
+ break;
+ default:
+ return (-1);
+ }
+
+ return (0);
+}
+
+paddr_t
+efifb_mmap(void *v, off_t off, int prot)
+{
+ struct efifb_softc *sc = v;
+
+ if (off > sc->sc_fb->psize)
+ return (-1);
+
+ return (sc->sc_fb->paddr + off);
+}
+
+int
+efifb_alloc_screen(void *v, const struct wsscreen_descr *descr,
+ void **cookiep, int *curxp, int *curyp, long *attrp)
+{
+ struct efifb_softc *sc = v;
+ struct rasops_info *ri = &sc->sc_fb->rinfo;
+
+ return rasops_alloc_screen(ri, cookiep, curxp, curyp, attrp);
+}
+
+void
+efifb_free_screen(void *v, void *cookie)
+{
+ struct efifb_softc *sc = v;
+ struct rasops_info *ri = &sc->sc_fb->rinfo;
+
+ rasops_free_screen(ri, cookie);
+}
+
+int
+efifb_show_screen(void *v, void *cookie, int waitok,
+ void (*cb) (void *, int, int), void *cb_arg)
+{
+ struct efifb_softc *sc = v;
+ struct rasops_info *ri = &sc->sc_fb->rinfo;
+
+ return rasops_show_screen(ri, cookie, waitok, cb, cb_arg);
+}
+
+int
+efifb_load_font(void *v, void *cookie, struct wsdisplay_font *font)
+{
+ struct efifb_softc *sc = v;
+ struct rasops_info *ri = &sc->sc_fb->rinfo;
+
+ return (rasops_load_font(ri, cookie, font));
+}
+
+int
+efifb_list_font(void *v, struct wsdisplay_font *font)
+{
+ struct efifb_softc *sc = v;
+ struct rasops_info *ri = &sc->sc_fb->rinfo;
+
+ return (rasops_list_font(ri, font));
+}
+
+int
+efifb_cnattach(void)
+{
+ struct efifb *fb = &efifb_console;
+ struct rasops_info *ri = &fb->rinfo;
+ long defattr = 0;
+
+ if (bios_efiinfo == NULL || bios_efiinfo->fb_addr == 0)
+ return (-1);
+
+ memset(&efifb_console, 0, sizeof(efifb_console));
+
+ fb = &efifb_console;
+ fb->paddr = bios_efiinfo->fb_addr;
+ fb->depth = max(fb->depth, fls(bios_efiinfo->fb_red_mask));
+ fb->depth = max(fb->depth, fls(bios_efiinfo->fb_green_mask));
+ fb->depth = max(fb->depth, fls(bios_efiinfo->fb_blue_mask));
+ fb->depth = max(fb->depth, fls(bios_efiinfo->fb_reserved_mask));
+ fb->psize = bios_efiinfo->fb_height *
+ bios_efiinfo->fb_pixpsl * (fb->depth / 8);
+
+ ri->ri_bits = (u_char *)PMAP_DIRECT_MAP(fb->paddr);
+
+ efifb_rasops_preinit(fb);
+
+ ri->ri_flg = RI_CLEAR | RI_CENTER;
+ rasops_init(ri, EFIFB_HEIGHT, EFIFB_WIDTH);
+ efifb_std_descr.ncols = ri->ri_cols;
+ efifb_std_descr.nrows = ri->ri_rows;
+ efifb_std_descr.textops = &ri->ri_ops;
+ efifb_std_descr.fontwidth = ri->ri_font->fontwidth;
+ efifb_std_descr.fontheight = ri->ri_font->fontheight;
+ efifb_std_descr.capabilities = ri->ri_caps;
+
+ ri->ri_ops.alloc_attr(ri, 0, 0, 0, &defattr);
+ wsdisplay_cnattach(&efifb_std_descr, ri, 0, 0, defattr);
+
+ return (0);
+}
diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c
index ae26de1d59f..10cffbc378b 100644
--- a/sys/arch/amd64/amd64/machdep.c
+++ b/sys/arch/amd64/amd64/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.215 2015/07/16 23:03:40 sf Exp $ */
+/* $OpenBSD: machdep.c,v 1.216 2015/08/30 10:05:09 yasuoka Exp $ */
/* $NetBSD: machdep.c,v 1.3 2003/05/07 22:58:18 fvdl Exp $ */
/*-
@@ -244,6 +244,7 @@ void getbootinfo(char *, int);
bios_diskinfo_t *bios_diskinfo;
bios_memmap_t *bios_memmap;
u_int32_t bios_cksumlen;
+bios_efiinfo_t *bios_efiinfo;
/*
* Size of memory segments, before any memory is stolen.
@@ -1804,6 +1805,7 @@ getbootinfo(char *bootinfo, int bootinfo_size)
bios_ddb_t *bios_ddb;
bios_bootduid_t *bios_bootduid;
bios_bootsr_t *bios_bootsr;
+ int docninit = 0;
#undef BOOTINFO_DEBUG
#ifdef BOOTINFO_DEBUG
@@ -1861,7 +1863,7 @@ getbootinfo(char *bootinfo, int bootinfo_size)
comconsiot = X86_BUS_SPACE_IO;
/* Probe the serial port this time. */
- cninit();
+ docninit++;
}
#endif
#ifdef BOOTINFO_DEBUG
@@ -1897,6 +1899,12 @@ getbootinfo(char *bootinfo, int bootinfo_size)
explicit_bzero(bios_bootsr, sizeof(bios_bootsr_t));
break;
+ case BOOTARG_EFIINFO:
+ bios_efiinfo = (bios_efiinfo_t *)q->ba_arg;
+ if (bios_efiinfo->fb_addr != 0)
+ docninit++;
+ break;
+
default:
#ifdef BOOTINFO_DEBUG
printf(" unsupported arg (%d) %p", q->ba_type,
@@ -1905,6 +1913,8 @@ getbootinfo(char *bootinfo, int bootinfo_size)
break;
}
}
+ if (docninit > 0)
+ cninit();
#ifdef BOOTINFO_DEBUG
printf("\n");
#endif
diff --git a/sys/arch/amd64/amd64/mainbus.c b/sys/arch/amd64/amd64/mainbus.c
index f987f94b757..d75b6ccdb36 100644
--- a/sys/arch/amd64/amd64/mainbus.c
+++ b/sys/arch/amd64/amd64/mainbus.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mainbus.c,v 1.30 2015/07/21 20:12:00 reyk Exp $ */
+/* $OpenBSD: mainbus.c,v 1.31 2015/08/30 10:05:09 yasuoka Exp $ */
/* $NetBSD: mainbus.c,v 1.1 2003/04/26 18:39:29 fvdl Exp $ */
/*
@@ -49,6 +49,7 @@
#include "bios.h"
#include "mpbios.h"
#include "pvbus.h"
+#include "efifb.h"
#include <machine/cpuvar.h>
#include <machine/i82093var.h>
@@ -230,6 +231,10 @@ mainbus_attach(struct device *parent, struct device *self, void *aux)
if (isa_has_been_seen == 0)
config_found(self, &mba_iba, mainbus_print);
#endif
+#if NEFIFB > 0
+ mba.mba_busname = "efifb";
+ config_found(self, &mba, mainbus_print);
+#endif
}
diff --git a/sys/arch/amd64/amd64/wscons_machdep.c b/sys/arch/amd64/amd64/wscons_machdep.c
index 83e7eaa5b40..71697ede808 100644
--- a/sys/arch/amd64/amd64/wscons_machdep.c
+++ b/sys/arch/amd64/amd64/wscons_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: wscons_machdep.c,v 1.10 2011/06/28 20:19:18 matthieu Exp $ */
+/* $OpenBSD: wscons_machdep.c,v 1.11 2015/08/30 10:05:09 yasuoka Exp $ */
/*
* Copyright (c) 2001 Aaron Campbell
@@ -71,8 +71,12 @@
#if NWSKBD > 0
#include <dev/wscons/wskbdvar.h>
#endif
+#include "efifb.h"
+#if NEFIFB > 0
+#include <machine/efifbvar.h>
+#endif
-void wscn_video_init(void);
+int wscn_video_init(void);
void wscn_input_init(int);
cons_decl(ws);
@@ -104,10 +108,11 @@ wscninit(struct consdev *cp)
if (initted)
return;
- initted = 1;
- wscn_video_init();
- wscn_input_init(0);
+ if (wscn_video_init() == 0) {
+ initted = 1;
+ wscn_input_init(0);
+ }
}
void
@@ -131,17 +136,22 @@ wscnpollc(dev_t dev, int on)
/*
* Configure the display part of the console.
*/
-void
+int
wscn_video_init()
{
+#if (NEFIFB > 0)
+ if (efifb_cnattach() == 0)
+ return (0);
+#endif
#if (NVGA > 0)
if (vga_cnattach(X86_BUS_SPACE_IO, X86_BUS_SPACE_MEM, -1, 1) == 0)
- return;
+ return (0);
#endif
#if (NPCDISPLAY > 0)
if (pcdisplay_cnattach(X86_BUS_SPACE_IO, X86_BUS_SPACE_MEM) == 0)
- return;
+ return (0);
#endif
+ return (-1);
}
/*
diff --git a/sys/arch/amd64/conf/GENERIC b/sys/arch/amd64/conf/GENERIC
index d752e3ee580..5feb08e2fbe 100644
--- a/sys/arch/amd64/conf/GENERIC
+++ b/sys/arch/amd64/conf/GENERIC
@@ -1,4 +1,4 @@
-# $OpenBSD: GENERIC,v 1.393 2015/08/25 01:57:44 bmercer Exp $
+# $OpenBSD: GENERIC,v 1.394 2015/08/30 10:05:09 yasuoka Exp $
#
# For further information on compiling OpenBSD kernels, see the config(8)
# man page.
@@ -334,6 +334,9 @@ lpt0 at isa? port 0x378 irq 7 # standard PC parallel ports
#lpt2 at isa? port 0x3bc
lpt* at puc?
+#efifb0 at mainbus? # EFI Framebuffer
+#wsdisplay0 at efifb? console 1
+
#bha* at pci? # BusLogic [57]4X SCSI controllers
ahc* at pci? # Adaptec 2940 SCSI controllers
jmb* at pci? # JMicron JMB36x controllers
diff --git a/sys/arch/amd64/conf/files.amd64 b/sys/arch/amd64/conf/files.amd64
index 57942f9410c..92e6e7ebc7e 100644
--- a/sys/arch/amd64/conf/files.amd64
+++ b/sys/arch/amd64/conf/files.amd64
@@ -1,4 +1,4 @@
-# $OpenBSD: files.amd64,v 1.79 2015/07/21 03:38:22 reyk Exp $
+# $OpenBSD: files.amd64,v 1.80 2015/08/30 10:05:09 yasuoka Exp $
maxpartitions 16
maxusers 2 16 128
@@ -107,6 +107,13 @@ attach ioapic at mainbus
file arch/amd64/amd64/ioapic.c ioapic needs-flag
#
+# EFI Framebuffer
+#
+device efifb: wsemuldisplaydev, rasops16, rasops8, rasops4
+attach efifb at mainbus
+file arch/amd64/amd64/efifb.c efifb needs-flag
+
+#
# PCI drivers
#
diff --git a/sys/arch/amd64/include/biosvar.h b/sys/arch/amd64/include/biosvar.h
index aab56cf7b27..2ffd366b09f 100644
--- a/sys/arch/amd64/include/biosvar.h
+++ b/sys/arch/amd64/include/biosvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: biosvar.h,v 1.21 2015/07/17 21:53:56 mlarkin Exp $ */
+/* $OpenBSD: biosvar.h,v 1.22 2015/08/30 10:05:09 yasuoka Exp $ */
/*
* Copyright (c) 1997-1999 Michael Shalayeff
@@ -190,6 +190,21 @@ typedef struct _bios_bootsr {
u_int8_t maskkey[BOOTSR_CRYPTO_MAXKEYBYTES];
} __packed bios_bootsr_t;
+#define BOOTARG_EFIINFO 11
+typedef struct _bios_efiinfo {
+ uint64_t config_acpi;
+ uint64_t config_smbios;
+ uint64_t fb_addr;
+ uint64_t fb_size;
+ uint32_t fb_height;
+ uint32_t fb_width;
+ uint32_t fb_pixpsl; /* pixels per scan line */
+ uint32_t fb_red_mask;
+ uint32_t fb_green_mask;
+ uint32_t fb_blue_mask;
+ uint32_t fb_reserved_mask;
+} __packed bios_efiinfo_t;
+
#if defined(_KERNEL) || defined (_STANDALONE)
#ifdef _LOCORE
@@ -237,6 +252,7 @@ bios_diskinfo_t *bios_getdiskinfo(dev_t);
extern u_int bootapiver;
extern bios_memmap_t *bios_memmap;
+extern bios_efiinfo_t *bios_efiinfo;
#endif /* _KERNEL */
#endif /* _LOCORE */
diff --git a/sys/arch/amd64/include/efifbvar.h b/sys/arch/amd64/include/efifbvar.h
new file mode 100644
index 00000000000..353e31e3800
--- /dev/null
+++ b/sys/arch/amd64/include/efifbvar.h
@@ -0,0 +1,19 @@
+/* $OpenBSD: efifbvar.h,v 1.1 2015/08/30 10:05:09 yasuoka Exp $ */
+
+/*
+ * Copyright (c) 2015 YASUOKA Masahiko <yasuoka@yasuoka.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+int efifb_cnattach(void);
diff --git a/sys/dev/wscons/wsconsio.h b/sys/dev/wscons/wsconsio.h
index c027a166fc7..5e6ae2b479d 100644
--- a/sys/dev/wscons/wsconsio.h
+++ b/sys/dev/wscons/wsconsio.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: wsconsio.h,v 1.71 2015/01/15 01:19:29 jsg Exp $ */
+/* $OpenBSD: wsconsio.h,v 1.72 2015/08/30 10:05:09 yasuoka Exp $ */
/* $NetBSD: wsconsio.h,v 1.74 2005/04/28 07:15:44 martin Exp $ */
/*
@@ -326,6 +326,7 @@ struct wsmouse_calibcoords {
#define WSDISPLAY_TYPE_LIGHT 68 /* SGI Light */
#define WSDISPLAY_TYPE_INTELDRM 69 /* Intel KMS framebuffer */
#define WSDISPLAY_TYPE_RADEONDRM 70 /* ATI Radeon KMS framebuffer */
+#define WSDISPLAY_TYPE_EFIFB 71 /* EFI framebuffer */
/* Basic display information. Not applicable to all display types. */
struct wsdisplay_fbinfo {