diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2015-10-30 11:21:02 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2015-10-30 11:21:02 +0000 |
commit | 4349f443d21b2ef4bab32588bf193e260bfadd26 (patch) | |
tree | e3ccef881757501a38250ce825dddf9d4754a85f | |
parent | 7679e2512e2fbc9973bcb0e662e6a9c0ba232f57 (diff) |
Fix interaction between inteldrm(4) and efifb(4). If we were booted by UEFI
firmware and the efifb(4) framebuffer address matches one of the BARs
associated with the inteldrm(4) device, make inteldrm(4) the console and
prevent efifb(4) from attaching. Make sure that we do a full clear of the
framebuffer when inteldrm(4) attaches to prevent the contents of the old
framebuffer from showing up.
Based on an earlier diff from yasuoka@
ok yasuoka@
-rw-r--r-- | sys/arch/amd64/amd64/efifb.c | 42 | ||||
-rw-r--r-- | sys/arch/amd64/include/efifbvar.h | 6 | ||||
-rw-r--r-- | sys/dev/pci/drm/i915/i915_drv.c | 40 |
3 files changed, 74 insertions, 14 deletions
diff --git a/sys/arch/amd64/amd64/efifb.c b/sys/arch/amd64/amd64/efifb.c index 4f3375f077a..479f89951dd 100644 --- a/sys/arch/amd64/amd64/efifb.c +++ b/sys/arch/amd64/amd64/efifb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: efifb.c,v 1.6 2015/09/07 18:19:58 kettenis Exp $ */ +/* $OpenBSD: efifb.c,v 1.7 2015/10/30 11:21:01 kettenis Exp $ */ /* * Copyright (c) 2015 YASUOKA Masahiko <yasuoka@yasuoka.net> @@ -25,6 +25,7 @@ #include <dev/wscons/wsconsio.h> #include <dev/wscons/wsdisplayvar.h> #include <dev/rasops/rasops.h> +#include <dev/pci/pcivar.h> #include <machine/biosvar.h> #include <machine/efifbvar.h> @@ -93,7 +94,7 @@ efifb_match(struct device *parent, void *cf, void *aux) struct efifb_attach_args *eaa = aux; if (strcmp(eaa->eaa_name, efifb_cd.cd_name) == 0 && - bios_efiinfo != NULL) + efifb_console.paddr != 0) return (1); return (0); @@ -312,3 +313,40 @@ efifb_cnattach(void) return (0); } + +int +efifb_is_console(struct pci_attach_args *pa) +{ + pci_chipset_tag_t pc = pa->pa_pc; + pcitag_t tag = pa->pa_tag; + pcireg_t type; + bus_addr_t base; + bus_size_t size; + int reg; + + for (reg = PCI_MAPREG_START; reg < PCI_MAPREG_END; reg += 4) { + if (!pci_mapreg_probe(pc, tag, reg, &type)) + continue; + + if (type == PCI_MAPREG_TYPE_IO) + continue; + + if (pci_mapreg_info(pc, tag, reg, type, &base, &size, NULL)) + continue; + + if (efifb_console.paddr >= base && + efifb_console.paddr < base + size) + return 1; + + if (type & PCI_MAPREG_MEM_TYPE_64BIT) + reg += 4; + } + + return 0; +} + +void +efifb_cndetach(void) +{ + efifb_console.paddr = 0; +} diff --git a/sys/arch/amd64/include/efifbvar.h b/sys/arch/amd64/include/efifbvar.h index bf5668c9a0d..67bfdb33ecd 100644 --- a/sys/arch/amd64/include/efifbvar.h +++ b/sys/arch/amd64/include/efifbvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: efifbvar.h,v 1.2 2015/08/31 19:56:32 kettenis Exp $ */ +/* $OpenBSD: efifbvar.h,v 1.3 2015/10/30 11:21:01 kettenis Exp $ */ /* * Copyright (c) 2015 YASUOKA Masahiko <yasuoka@yasuoka.net> @@ -23,6 +23,10 @@ struct efifb_attach_args { const char *eaa_name; }; +struct pci_attach_args; + int efifb_cnattach(void); +int efifb_is_console(struct pci_attach_args *); +void efifb_cndetach(void); #endif /* _MACHINE_EFIFB_H_ */ diff --git a/sys/dev/pci/drm/i915/i915_drv.c b/sys/dev/pci/drm/i915/i915_drv.c index 52a987276c1..7b5b6393284 100644 --- a/sys/dev/pci/drm/i915/i915_drv.c +++ b/sys/dev/pci/drm/i915/i915_drv.c @@ -1,4 +1,4 @@ -/* $OpenBSD: i915_drv.c,v 1.95 2015/10/29 07:47:03 kettenis Exp $ */ +/* $OpenBSD: i915_drv.c,v 1.96 2015/10/30 11:21:01 kettenis Exp $ */ /* * Copyright (c) 2008-2009 Owain G. Ainsworth <oga@openbsd.org> * @@ -956,6 +956,14 @@ int i915_reset(struct drm_device *dev) return 0; } +#ifdef __amd64__ +#include "efifb.h" +#endif + +#if NEFIFB > 0 +#include <machine/efifbvar.h> +#endif + #include "intagp.h" #if NINTAGP > 0 @@ -1223,15 +1231,6 @@ inteldrm_attach(struct device *parent, struct device *self, void *aux) int console = 0; int i; - if (PCI_CLASS(pa->pa_class) == PCI_CLASS_DISPLAY && - PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_DISPLAY_VGA && - (pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG) - & (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE)) - == (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE)) { - console = 1; - vga_console_attached = 1; - } - info = i915_get_device_id(PCI_PRODUCT(pa->pa_id)); KASSERT(info->gen != 0); @@ -1244,6 +1243,20 @@ inteldrm_attach(struct device *parent, struct device *self, void *aux) dev_priv->memex = pa->pa_memex; dev_priv->regs = &dev_priv->bar; + if (PCI_CLASS(pa->pa_class) == PCI_CLASS_DISPLAY && + PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_DISPLAY_VGA && + (pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG) + & (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE)) + == (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE)) { + vga_console_attached = 1; + console = 1; + } + +#if NEFIFB > 0 + if (efifb_is_console(pa)) + console = 1; +#endif + printf("\n"); inteldrm_driver.num_ioctls = i915_max_ioctl; @@ -1495,12 +1508,17 @@ inteldrm_attach(struct device *parent, struct device *self, void *aux) if (ri->ri_bits == NULL) return; +#if NEFIFB > 0 + if (efifb_is_console(pa)) + efifb_cndetach(); +#endif + printf("%s: %dx%d\n", dev_priv->sc_dev.dv_xname, ri->ri_width, ri->ri_height); intel_fbdev_restore_mode(dev); - ri->ri_flg = RI_CENTER | RI_WRONLY | RI_VCONS; + ri->ri_flg = RI_CENTER | RI_WRONLY | RI_VCONS | RI_CLEAR; ri->ri_hw = dev_priv; rasops_init(ri, 160, 160); |