diff options
-rw-r--r-- | sys/dev/pci/agp.c | 4 | ||||
-rw-r--r-- | sys/dev/pci/agp_i810.c | 24 | ||||
-rw-r--r-- | sys/dev/pci/agpvar.h | 4 | ||||
-rw-r--r-- | sys/dev/pci/drm/drmP.h | 23 | ||||
-rw-r--r-- | sys/dev/pci/drm/drm_bufs.c | 29 | ||||
-rw-r--r-- | sys/dev/pci/drm/drm_drv.c | 6 | ||||
-rw-r--r-- | sys/dev/pci/drm/drm_memory.c | 52 | ||||
-rw-r--r-- | sys/dev/pci/drm/i915_drv.c | 3 | ||||
-rw-r--r-- | sys/dev/pci/drm/mach64_drv.c | 2 | ||||
-rw-r--r-- | sys/dev/pci/drm/mga_drv.c | 2 | ||||
-rw-r--r-- | sys/dev/pci/drm/r128_drv.c | 2 | ||||
-rw-r--r-- | sys/dev/pci/drm/radeon_drv.c | 2 | ||||
-rw-r--r-- | sys/dev/pci/drm/savage_drv.c | 2 | ||||
-rw-r--r-- | sys/dev/pci/drm/sis_drv.c | 2 | ||||
-rw-r--r-- | sys/dev/pci/drm/tdfx_drv.c | 2 | ||||
-rw-r--r-- | sys/dev/pci/drm/via_drv.c | 2 | ||||
-rw-r--r-- | sys/dev/pci/vga_pci.c | 110 | ||||
-rw-r--r-- | sys/dev/pci/vga_pcivar.h | 29 |
18 files changed, 218 insertions, 82 deletions
diff --git a/sys/dev/pci/agp.c b/sys/dev/pci/agp.c index 6c297f9031a..15f31704d45 100644 --- a/sys/dev/pci/agp.c +++ b/sys/dev/pci/agp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: agp.c,v 1.20 2008/04/09 18:59:58 oga Exp $ */ +/* $OpenBSD: agp.c,v 1.21 2008/05/06 19:19:02 oga Exp $ */ /*- * Copyright (c) 2000 Doug Rabson * All rights reserved. @@ -176,6 +176,8 @@ agp_attach(struct device *parent, struct device *self, void *aux) pci_get_capability(sc->sc_pc, sc->sc_pcitag, PCI_CAP_AGP, &sc->sc_capoff, NULL); + sc->vga_softc = (struct vga_pci_softc *)parent; + printf(": "); ret = (*ap->ap_attach)(sc, pa); if (ret == 0) diff --git a/sys/dev/pci/agp_i810.c b/sys/dev/pci/agp_i810.c index 67fbb6ee66c..cb7e1c013b0 100644 --- a/sys/dev/pci/agp_i810.c +++ b/sys/dev/pci/agp_i810.c @@ -1,4 +1,4 @@ -/* $OpenBSD: agp_i810.c,v 1.34 2008/03/23 19:54:47 oga Exp $ */ +/* $OpenBSD: agp_i810.c,v 1.35 2008/05/06 19:19:02 oga Exp $ */ /* $NetBSD: agp_i810.c,v 1.15 2003/01/31 00:07:39 thorpej Exp $ */ /*- @@ -157,6 +157,7 @@ agp_i810_attach(struct agp_softc *sc, struct pci_attach_args *pa) struct agp_i810_softc *isc; struct agp_gatt *gatt; bus_addr_t mmaddr, gmaddr; + struct vga_pci_bar *map; int error; u_int memtype = 0; @@ -251,26 +252,27 @@ agp_i810_attach(struct agp_softc *sc, struct pci_attach_args *pa) return (error); } - if (isc->chiptype == CHIP_I965) - memtype = pci_mapreg_type(isc->vga_pa.pa_pc, - isc->vga_pa.pa_tag, mmaddr); - - error = pci_mapreg_map(&isc->vga_pa, mmaddr, memtype, 0, - &isc->bst, &isc->bsh, NULL, &isc->bsz, 0); - if (error != 0) { + map = vga_pci_bar_map(sc->vga_softc, mmaddr, 0, + BUS_SPACE_MAP_LINEAR); + if (map == NULL) { printf("can't map mmadr registers\n"); agp_generic_detach(sc); return (error); } + isc->bst = map->bst; + isc->bsh = map->bsh; + isc->bsz = map->size; if (isc->chiptype == CHIP_I915 || isc->chiptype == CHIP_G33) { - error = pci_mapreg_map(&isc->vga_pa, AGP_I915_GTTADR, memtype, - 0, &isc->gtt_bst, &isc->gtt_bsh, NULL, NULL, 0); - if (error != 0) { + map = vga_pci_bar_map(sc->vga_softc, AGP_I915_GTTADR, + 0, BUS_SPACE_MAP_LINEAR); + if (map == NULL) { printf("can't map gatt registers\n"); agp_generic_detach(sc); return (error); } + isc->gtt_bst = map->bst; + isc->gtt_bsh = map->bsh; } isc->initial_aperture = AGP_GET_APERTURE(sc); diff --git a/sys/dev/pci/agpvar.h b/sys/dev/pci/agpvar.h index 5c5a0de6686..8f80f7769eb 100644 --- a/sys/dev/pci/agpvar.h +++ b/sys/dev/pci/agpvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: agpvar.h,v 1.12 2008/03/23 19:54:47 oga Exp $ */ +/* $OpenBSD: agpvar.h,v 1.13 2008/05/06 19:19:02 oga Exp $ */ /* $NetBSD: agpvar.h,v 1.4 2001/10/01 21:54:48 fvdl Exp $ */ /*- @@ -146,6 +146,8 @@ struct agp_softc { u_int32_t sc_allocated; /* amount allocated */ enum agp_acquire_state sc_state; struct agp_memory_list sc_memory; /* list of allocated memory */ + + struct vga_pci_softc *vga_softc; /* needed for shared mappings */ }; struct agp_gatt { diff --git a/sys/dev/pci/drm/drmP.h b/sys/dev/pci/drm/drmP.h index 07fd6976d4a..f93246c0e93 100644 --- a/sys/dev/pci/drm/drmP.h +++ b/sys/dev/pci/drm/drmP.h @@ -676,18 +676,6 @@ typedef struct drm_sg_mem { drm_dma_handle_t *dmah; /* Handle to PCI memory for ATI PCIGART table */ } drm_sg_mem_t; -#if defined(__NetBSD__) || defined(__OpenBSD__) -typedef struct { - int mapped; - int maptype; - bus_addr_t base; - bus_size_t size; - bus_space_handle_t bsh; - int flags; - void * vaddr; -} pci_map_data_t; -#endif - typedef TAILQ_HEAD(drm_map_list, drm_local_map) drm_map_list_t; typedef struct drm_local_map { @@ -703,7 +691,7 @@ typedef struct drm_local_map { #ifdef __FreeBSD__ struct resource *bsr; #else - pci_map_data_t *bsr; + struct vga_pci_bar *bsr; #endif bus_space_tag_t bst; bus_space_handle_t bsh; @@ -832,6 +820,7 @@ struct drm_device { #endif #ifdef __OpenBSD__ dev_t kdev; /* used by uvm_mmap, this is just a placeholder */ + struct vga_pci_softc *vga_softc; #endif int if_version; /* Highest interface version set */ @@ -885,10 +874,10 @@ struct drm_device { /* Storage of resource pointers for drm_get_resource_* */ #ifdef __FreeBSD__ struct resource *pcir[DRM_MAX_PCI_RESOURCE]; + int pcirid[DRM_MAX_PCI_RESOURCE]; #else - pci_map_data_t *pcir[DRM_MAX_PCI_RESOURCE]; + struct vga_pci_bar *pcir[DRM_MAX_PCI_RESOURCE]; #endif - int pcirid[DRM_MAX_PCI_RESOURCE]; int pci_domain; int pci_bus; @@ -950,8 +939,8 @@ d_poll_t drm_poll; d_mmap_t drm_mmap; #elif defined(__NetBSD__) || defined(__OpenBSD__) int drm_probe(struct pci_attach_args *, drm_pci_id_list_t * ); -void drm_attach(struct device *kdev, struct pci_attach_args *pa, - drm_pci_id_list_t *idlist); +void drm_attach(struct device *kdev, struct device *parent, + struct pci_attach_args *pa, drm_pci_id_list_t *idlist); int drm_detach(struct device *self, int flags); int drm_activate(struct device *self, enum devact act); dev_type_ioctl(drm_ioctl); diff --git a/sys/dev/pci/drm/drm_bufs.c b/sys/dev/pci/drm/drm_bufs.c index 64e32082e22..3451b7c63f1 100644 --- a/sys/dev/pci/drm/drm_bufs.c +++ b/sys/dev/pci/drm/drm_bufs.c @@ -67,9 +67,6 @@ drm_order(unsigned long size) int drm_alloc_resource(drm_device_t *dev, int resource) { -#ifdef __OpenBSD__ -#define PCIR_BAR(x) (PCI_MAPS + (x) * 4) -#endif if (resource >= DRM_MAX_PCI_RESOURCE) { DRM_ERROR("Resource %d too large\n", resource); return 1; @@ -81,8 +78,8 @@ drm_alloc_resource(drm_device_t *dev, int resource) return 0; } - dev->pcirid[resource] = PCIR_BAR(resource); #if defined (__FreeBSD__) + dev->pcirid[resource] = PCIR_BAR(resource); dev->pcir[resource] = bus_alloc_resource_any(dev->device, SYS_RES_MEMORY, &dev->pcirid[resource], RF_SHAREABLE); @@ -92,27 +89,12 @@ drm_alloc_resource(drm_device_t *dev, int resource) return 1; } #elif defined (__OpenBSD__) - dev->pcir[resource] = malloc(sizeof(*(dev->pcir)), M_DRM, M_NOWAIT | M_ZERO); + dev->pcir[resource] = vga_pci_bar_info(dev->vga_softc, resource); + DRM_LOCK(); if (dev->pcir[resource] == NULL) { - DRM_ERROR("Couldn't allocate memory for resource 0x%x\n", resource); - DRM_LOCK(); + DRM_ERROR("Can't get bar info for resource 0x%x\n", resource); return 1; } - dev->pcir[resource]->maptype = - pci_mapreg_type(dev->pa.pa_pc, dev->pa.pa_tag, - dev->pcirid[resource]); - if(pci_mapreg_info(dev->pa.pa_pc, dev->pa.pa_tag, - dev->pcirid[resource], - dev->pcir[resource]->maptype, - &(dev->pcir[resource]->base), - &(dev->pcir[resource]->size), - &(dev->pcir[resource]->flags))) { - dev->pcir[resource]->base = 0; - dev->pcir[resource]->size = 0; - } - if(dev->pcir[resource]->maptype == PCI_MAPREG_TYPE_MEM) - dev->pcir[resource]->flags |= BUS_SPACE_MAP_LINEAR; - DRM_LOCK(); #endif return 0; @@ -141,7 +123,7 @@ drm_get_resource_len(drm_device_t *dev, unsigned int resource) #ifdef __FreeBSD__ return rman_get_size(dev->pcir[resource]); #elif defined(__NetBSD__) || defined(__OpenBSD__) - return dev->pcir[resource]->size; + return dev->pcir[resource]->maxsize; #endif } @@ -211,7 +193,6 @@ drm_addmap(drm_device_t * dev, unsigned long offset, unsigned long size, switch ( map->type ) { case _DRM_REGISTERS: - map->bst = dev->pa.pa_iot; map->handle = drm_ioremap(dev, map); if (!map->handle) { DRM_LOCK(); diff --git a/sys/dev/pci/drm/drm_drv.c b/sys/dev/pci/drm/drm_drv.c index 7eaf8358810..bb0dcc82b7c 100644 --- a/sys/dev/pci/drm/drm_drv.c +++ b/sys/dev/pci/drm/drm_drv.c @@ -267,8 +267,8 @@ drm_probe(struct pci_attach_args *pa, drm_pci_id_list_t *idlist) } void -drm_attach(struct device *kdev, struct pci_attach_args *pa, - drm_pci_id_list_t *idlist) +drm_attach(struct device *parent, struct device *kdev, + struct pci_attach_args *pa, drm_pci_id_list_t *idlist) { int unit; drm_device_t *dev; @@ -288,7 +288,9 @@ drm_attach(struct device *kdev, struct pci_attach_args *pa, dev = drm_units[unit] = (drm_device_t*)kdev; dev->unit = unit; + /* needed for pci_mapreg_* */ memcpy(&dev->pa, pa, sizeof(dev->pa)); + dev->vga_softc = (struct vga_pci_softc *)parent; dev->irq = pa->pa_intrline; dev->pci_bus = pa->pa_bus; diff --git a/sys/dev/pci/drm/drm_memory.c b/sys/dev/pci/drm/drm_memory.c index 8d3ae1d4a5f..5900b431d17 100644 --- a/sys/dev/pci/drm/drm_memory.c +++ b/sys/dev/pci/drm/drm_memory.c @@ -97,13 +97,48 @@ drm_ioremap(drm_device_t *dev, drm_local_map_t *map) #ifdef __FreeBSD__ return pmap_mapdev(map->offset, map->size); #elif defined(__NetBSD__) || defined(__OpenBSD__) - int ret; - if (!map->bst) - map->bst = dev->pa.pa_memt; - if ((ret = bus_space_map(map->bst, map->offset, map->size, - BUS_SPACE_MAP_LINEAR, &map->bsh))) { - return NULL; + struct vga_pci_bar *bar = NULL; + int i; + + DRM_DEBUG("offset: 0x%x size: 0x%x type: %d\n", map->offset, map->size, + map->type); + + if (map->type == _DRM_AGP || map->type == _DRM_FRAME_BUFFER) { + /* + * there can be multiple agp maps in the same BAR, agp also + * quite possibly isn't the same as the vga device, just try + * to map it. + */ + DRM_DEBUG("AGP map\n"); + map->bst = dev->pa.pa_memt; + if (bus_space_map(map->bst, map->offset, + map->size, BUS_SPACE_MAP_LINEAR, &map->bsh)) { + DRM_ERROR("ioremap fail\n"); + return (NULL); + } + goto done; + } else { + for (i = 0 ; i < DRM_MAX_PCI_RESOURCE; ++i) { + bar = vga_pci_bar_info(dev->vga_softc, i); + if (bar == NULL) + continue; + + if (bar->base == map->offset) { + DRM_DEBUG("REGISTERS map\n"); + map->bsr = vga_pci_bar_map(dev->vga_softc, + bar->addr, map->size, BUS_SPACE_MAP_LINEAR); + if (map->bsr == NULL) { + DRM_ERROR("ioremap fail\n"); + return (NULL); + } + map->bst = map->bsr->bst; + map->bsh = map->bsr->bsh; + goto done; + } + } } +done: + /* handles are still supposed to be kernel virtual addresses */ return bus_space_vaddr(map->bst, map->bsh); #endif } @@ -114,7 +149,10 @@ drm_ioremapfree(drm_local_map_t *map) #ifdef __FreeBSD__ pmap_unmapdev((vm_offset_t) map->handle, map->size); #elif defined(__NetBSD__) || defined(__OpenBSD__) - bus_space_unmap(map->bst, map->bsh, map->size); + if (map != NULL && map->bsr != NULL) + vga_pci_bar_unmap(map->bsr); + else + bus_space_unmap(map->bst, map->bsh, map->size); #endif } diff --git a/sys/dev/pci/drm/i915_drv.c b/sys/dev/pci/drm/i915_drv.c index 61a3ba4218b..6b9be6b8200 100644 --- a/sys/dev/pci/drm/i915_drv.c +++ b/sys/dev/pci/drm/i915_drv.c @@ -129,7 +129,6 @@ i915drm_probe(struct device *parent, void *match, void *aux) i915drm_probe(struct device *parent, struct cfdata *match, void *aux) #endif { - DRM_DEBUG("\n"); return drm_probe((struct pci_attach_args *)aux, i915_pciidlist); } @@ -141,7 +140,7 @@ i915drm_attach(struct device *parent, struct device *self, void *aux) i915_configure(dev); - drm_attach(self, pa, i915_pciidlist); + drm_attach(parent, self, pa, i915_pciidlist); } #if defined(__OpenBSD__) diff --git a/sys/dev/pci/drm/mach64_drv.c b/sys/dev/pci/drm/mach64_drv.c index 78ef1bded92..9065840850f 100644 --- a/sys/dev/pci/drm/mach64_drv.c +++ b/sys/dev/pci/drm/mach64_drv.c @@ -138,7 +138,7 @@ mach64drm_attach(struct device *parent, struct device *self, void *aux) drm_device_t *dev = (drm_device_t *)self; mach64_configure(dev); - return drm_attach(self, pa, mach64_pciidlist); + return drm_attach(parent, self, pa, mach64_pciidlist); } #if defined(__OpenBSD__) diff --git a/sys/dev/pci/drm/mga_drv.c b/sys/dev/pci/drm/mga_drv.c index 8732c31aaf5..d18a7845063 100644 --- a/sys/dev/pci/drm/mga_drv.c +++ b/sys/dev/pci/drm/mga_drv.c @@ -188,7 +188,7 @@ mgadrm_attach(struct device *parent, struct device *self, void *aux) drm_device_t *dev = (drm_device_t *)self; mga_configure(dev); - return drm_attach(self, pa, mga_pciidlist); + return drm_attach(parent, self, pa, mga_pciidlist); } #if defined(__OpenBSD__) diff --git a/sys/dev/pci/drm/r128_drv.c b/sys/dev/pci/drm/r128_drv.c index c6b32790ade..9c16396f383 100644 --- a/sys/dev/pci/drm/r128_drv.c +++ b/sys/dev/pci/drm/r128_drv.c @@ -138,7 +138,7 @@ r128drm_attach(struct device *parent, struct device *self, void *aux) drm_device_t *dev = (drm_device_t *)self; r128_configure(dev); - return drm_attach(self, pa, r128_pciidlist); + return drm_attach(parent, self, pa, r128_pciidlist); } #if defined(__OpenBSD__) diff --git a/sys/dev/pci/drm/radeon_drv.c b/sys/dev/pci/drm/radeon_drv.c index 2ccd48818bc..082a4844db5 100644 --- a/sys/dev/pci/drm/radeon_drv.c +++ b/sys/dev/pci/drm/radeon_drv.c @@ -143,7 +143,7 @@ radeondrm_attach(struct device *parent, struct device *self, void *aux) drm_device_t *dev = (drm_device_t *)self; radeon_configure(dev); - return drm_attach(self, pa, radeon_pciidlist); + return drm_attach(parent, self, pa, radeon_pciidlist); } #if defined(__OpenBSD__) diff --git a/sys/dev/pci/drm/savage_drv.c b/sys/dev/pci/drm/savage_drv.c index 557bdbb1775..585fe9a9538 100644 --- a/sys/dev/pci/drm/savage_drv.c +++ b/sys/dev/pci/drm/savage_drv.c @@ -128,7 +128,7 @@ savagedrm_attach(struct device *parent, struct device *self, void *aux) drm_device_t *dev = (drm_device_t *)self; savage_configure(dev); - return drm_attach(self, pa, savage_pciidlist); + return drm_attach(parent, self, pa, savage_pciidlist); } #if defined(__OpenBSD__) diff --git a/sys/dev/pci/drm/sis_drv.c b/sys/dev/pci/drm/sis_drv.c index a986437aac8..072e1afdd0d 100644 --- a/sys/dev/pci/drm/sis_drv.c +++ b/sys/dev/pci/drm/sis_drv.c @@ -121,7 +121,7 @@ sisdrm_attach(struct device *parent, struct device *self, void *aux) drm_device_t *dev = (drm_device_t *)self; sis_configure(dev); - return drm_attach(self, pa, sis_pciidlist); + return drm_attach(parent, self, pa, sis_pciidlist); } #if defined(__OpenBSD__) diff --git a/sys/dev/pci/drm/tdfx_drv.c b/sys/dev/pci/drm/tdfx_drv.c index 954446c475d..37bf6075c16 100644 --- a/sys/dev/pci/drm/tdfx_drv.c +++ b/sys/dev/pci/drm/tdfx_drv.c @@ -122,7 +122,7 @@ tdfxdrm_attach(struct device *parent, struct device *self, void *aux) drm_device_t *dev = (drm_device_t *)self; tdfx_configure(dev); - return drm_attach(self, pa, tdfx_pciidlist); + return drm_attach(parent, self, pa, tdfx_pciidlist); } #if defined(__OpenBSD__) diff --git a/sys/dev/pci/drm/via_drv.c b/sys/dev/pci/drm/via_drv.c index 82a2374b296..86aa2b550ec 100644 --- a/sys/dev/pci/drm/via_drv.c +++ b/sys/dev/pci/drm/via_drv.c @@ -130,7 +130,7 @@ viadrm_attach(struct device *parent, struct device *self, void *opaque) drm_device_t *dev = (drm_device_t *)self; viadrm_configure(dev); - drm_attach(self, pa, via_pciidlist); + drm_attach(parent, self, pa, via_pciidlist); } #if defined(__OpenBSD__) diff --git a/sys/dev/pci/vga_pci.c b/sys/dev/pci/vga_pci.c index 7caf597c200..b6fcceaa91e 100644 --- a/sys/dev/pci/vga_pci.c +++ b/sys/dev/pci/vga_pci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vga_pci.c,v 1.30 2008/03/16 19:00:28 oga Exp $ */ +/* $OpenBSD: vga_pci.c,v 1.31 2008/05/06 19:19:02 oga Exp $ */ /* $NetBSD: vga_pci.c,v 1.3 1998/06/08 06:55:58 thorpej Exp $ */ /* @@ -101,6 +101,7 @@ int vga_pci_match(struct device *, void *, void *); void vga_pci_attach(struct device *, struct device *, void *); paddr_t vga_pci_mmap(void* v, off_t off, int prot); +void vga_pci_bar_init(struct vga_pci_softc *, struct pci_attach_args *); #if NAGP > 0 int agpsubmatch(struct device *, void *, void *); @@ -169,9 +170,7 @@ vga_pci_attach(struct device *parent, struct device *self, void *aux) struct agpbus_attach_args aba; #endif pcireg_t reg; -#ifdef VESAFB struct vga_pci_softc *sc = (struct vga_pci_softc *)self; -#endif /* * Enable bus master; X might need this for accelerated graphics. @@ -193,6 +192,8 @@ vga_pci_attach(struct device *parent, struct device *self, void *aux) vga_common_attach(self, pa->pa_iot, pa->pa_memt, WSDISPLAY_TYPE_PCIVGA); + vga_pci_bar_init(sc, pa); + #if NAGP > 0 /* * attach agp here instead of pchb so it can share mappings @@ -373,3 +374,106 @@ vga_pci_close(void *v) { } #endif + +/* + * Prepare dev->bars to be used for information. we do this at startup + * so we can do the whole array at once, dealing with 64-bit BARs correctly. + */ +void +vga_pci_bar_init(struct vga_pci_softc *dev, struct pci_attach_args *pa) +{ + pcireg_t type; + int addr = PCI_MAPREG_START, i = 0; + memcpy(&dev->pa, pa, sizeof(dev->pa)); + + while (i < VGA_PCI_MAX_BARS) { + dev->bars[i] = malloc(sizeof((*dev->bars[i])), M_DEVBUF, + M_NOWAIT | M_ZERO); + if (dev->bars[i] == NULL) { + return; + } + + dev->bars[i]->addr = addr; + + type = dev->bars[i]->maptype = pci_mapreg_type(pa->pa_pc, + pa->pa_tag, addr); + if (pci_mapreg_info(pa->pa_pc, pa->pa_tag, addr, + dev->bars[i]->maptype, &dev->bars[i]->base, + &dev->bars[i]->maxsize, &dev->bars[i]->flags) != 0) { + free(dev->bars[i], M_DEVBUF); + dev->bars[i] = NULL; + } + + addr+=4; + ++i; + } +} + +/* + * Get the vga_pci_bar struct for the address in question. returns NULL if + * invalid BAR is passed. + */ +struct vga_pci_bar* +vga_pci_bar_info(struct vga_pci_softc *dev, int no) +{ + if (dev == NULL || no > VGA_PCI_MAX_BARS) + return (NULL); + return (dev->bars[no]); +} + +/* + * map the BAR in question, returning the vga_pci_bar struct in case any more + * processing needs to be done. Returns NULL on failure. Can be called multiple + * times. + */ +struct vga_pci_bar* +vga_pci_bar_map(struct vga_pci_softc *dev, int addr, bus_size_t size, + int busflags) +{ + struct vga_pci_bar *bar = NULL; + int i; + + if (dev == NULL) + return (NULL); + + for (i = 0; i < VGA_PCI_MAX_BARS; i++) { + if (dev->bars[i] && dev->bars[i]->addr == addr) { + bar = dev->bars[i]; + break; + } + } + if (bar == NULL) { + printf("vga_pci_bar_map: given invalid address 0x%x\n", addr); + return (NULL); + } + + if (bar->mapped == 0) { + switch (bar->maptype) { + case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT: + case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT: + if (pci_mapreg_map(&dev->pa, bar->addr, bar->maptype, + bar->flags | busflags, &bar->bst, &bar->bsh, NULL, + &bar->size, size) == 0) + break; + default: + printf("vga_pci_bar_map: can't map bar 0x%x\n", addr); + return (NULL); + } + } + + bar->mapped++; + return (bar); +} + +/* + * "unmap" the BAR referred to by argument. If more than one place has mapped it + * we just decrement the reference counter so nothing untoward happens. + */ +void +vga_pci_bar_unmap(struct vga_pci_bar *bar) +{ + if (bar != NULL && bar->mapped != 0) { + if (--bar->mapped == 0) + bus_space_unmap(bar->bst, bar->bsh, bar->size); + } +} diff --git a/sys/dev/pci/vga_pcivar.h b/sys/dev/pci/vga_pcivar.h index 44aad8df68a..47f10b4b72c 100644 --- a/sys/dev/pci/vga_pcivar.h +++ b/sys/dev/pci/vga_pcivar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: vga_pcivar.h,v 1.9 2007/11/25 17:11:12 oga Exp $ */ +/* $OpenBSD: vga_pcivar.h,v 1.10 2008/05/06 19:19:02 oga Exp $ */ /* $NetBSD: vga_pcivar.h,v 1.1 1998/03/22 15:16:19 drochner Exp $ */ /* @@ -37,13 +37,26 @@ (PCI_CLASS(class) == PCI_CLASS_PREHISTORIC && \ PCI_SUBCLASS(class) == PCI_SUBCLASS_PREHISTORIC_VGA)) ? 1 : 0) +#define VGA_PCI_MAX_BARS 4 +struct vga_pci_bar { + int addr; + u_int mapped; + pcireg_t maptype; + bus_addr_t base; + bus_size_t size; + bus_size_t maxsize; + bus_space_tag_t bst; + bus_space_handle_t bsh; + int flags; + void *vaddr; +}; + struct vga_pci_softc { struct device sc_dev; -#if 0 - struct vga_config *sc_vc; /* VGA configuration */ -#endif + struct pci_attach_args pa; + struct vga_pci_bar *bars[VGA_PCI_MAX_BARS]; #ifdef VESAFB int sc_width; int sc_height; @@ -60,8 +73,12 @@ struct vga_pci_softc { #endif }; -int vga_pci_cnattach(bus_space_tag_t, bus_space_tag_t, - pci_chipset_tag_t, int, int, int); +int vga_pci_cnattach(bus_space_tag_t, bus_space_tag_t, + pci_chipset_tag_t, int, int, int); +struct vga_pci_bar *vga_pci_bar_info(struct vga_pci_softc *, int); +struct vga_pci_bar *vga_pci_bar_map(struct vga_pci_softc *, int, + bus_size_t, int); +void vga_pci_bar_unmap(struct vga_pci_bar*); #ifdef VESAFB int vesafb_find_mode(struct vga_pci_softc *, int, int, int); |