diff --git a/sys/dev/pci/vga_pci.c b/sys/dev/pci/vga_pci.c index 18892930090d..60b1caedca02 100644 --- a/sys/dev/pci/vga_pci.c +++ b/sys/dev/pci/vga_pci.c @@ -1,4 +1,4 @@ -/* $NetBSD: vga_pci.c,v 1.6 2001/09/14 06:46:08 thorpej Exp $ */ +/* $NetBSD: vga_pci.c,v 1.7 2001/09/14 16:54:20 thorpej Exp $ */ /* * Copyright (c) 1995, 1996 Carnegie-Mellon University. @@ -44,14 +44,28 @@ #include #include +#include /* For legacy VGA address ranges */ + #include #include +#define NBARS 6 /* number of PCI BARs */ + +struct vga_bar { + bus_addr_t vb_base; + bus_size_t vb_size; + pcireg_t vb_type; + int vb_flags; +}; + struct vga_pci_softc { struct vga_softc sc_vga; pci_chipset_tag_t sc_pc; pcitag_t sc_pcitag; + + struct vga_bar sc_bars[NBARS]; + struct vga_bar sc_rom; }; int vga_pci_match __P((struct device *, struct cfdata *, void *)); @@ -122,6 +136,7 @@ vga_pci_attach(parent, self, aux) struct vga_softc *sc = &psc->sc_vga; struct pci_attach_args *pa = aux; char devinfo[256]; + int bar, reg; psc->sc_pc = pa->pa_pc; psc->sc_pcitag = pa->pa_tag; @@ -130,6 +145,36 @@ vga_pci_attach(parent, self, aux) printf(": %s (rev. 0x%02x)\n", devinfo, PCI_REVISION(pa->pa_class)); + /* + * Gather info about all the BARs. These are used to allow + * the X server to map the VGA device. + */ + for (bar = 0; bar < NBARS; bar++) { + reg = PCI_MAPREG_START + (bar * 4); + psc->sc_bars[bar].vb_type = pci_mapreg_type(psc->sc_pc, + psc->sc_pcitag, reg); + if (PCI_MAPREG_TYPE(psc->sc_bars[bar].vb_type) == + PCI_MAPREG_TYPE_IO) { + /* Don't bother fetching I/O BARs. */ + continue; + } + if (PCI_MAPREG_MEM_TYPE(psc->sc_bars[bar].vb_type) == + PCI_MAPREG_MEM_TYPE_64BIT) { + /* XXX */ + printf("%s: WARNING: ignoring 64-bit BAR @ 0x%02x\n", + sc->sc_dev.dv_xname, reg); + continue; + } + /* Ignore errors (unimplemented BARs). */ + (void) pci_mapreg_info(psc->sc_pc, psc->sc_pcitag, reg, + psc->sc_bars[bar].vb_type, + &psc->sc_bars[bar].vb_base, + &psc->sc_bars[bar].vb_size, + &psc->sc_bars[bar].vb_flags); + } + + /* XXX Expansion ROM? */ + vga_common_attach(sc, pa->pa_iot, pa->pa_memt, WSDISPLAY_TYPE_PCIVGA, &vga_pci_funcs); } @@ -164,7 +209,36 @@ vga_pci_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p) paddr_t vga_pci_mmap(void *v, off_t offset, int prot) { + struct vga_config *vc = v; + struct vga_pci_softc *psc = (void *) vc->softc; + struct vga_bar *vb; + int bar; - /* XXX Fill me in. */ + for (bar = 0; bar < NBARS; bar++) { + vb = &psc->sc_bars[bar]; + if (vb->vb_size == 0) + continue; + if (offset >= vb->vb_base && + offset < (vb->vb_base + vb->vb_size)) { + /* XXX This the right thing to do with flags? */ + return (bus_space_mmap(vc->hdl.vh_memt, vb->vb_base, + (offset - vb->vb_base), prot, vb->vb_flags)); + } + } + + /* XXX Expansion ROM? */ + + /* + * Allow mmap access to the legacy ISA hole. This is where + * the legacy video BIOS will be located, and also where + * the legacy VGA display buffer is located. + * + * XXX Security implications, here? + */ + if (offset >= IOM_BEGIN && offset < IOM_END) + return (bus_space_mmap(vc->hdl.vh_memt, IOM_BEGIN, + (offset - IOM_BEGIN), prot, 0)); + + /* Range not found. */ return (-1); }