/* * PCI resource handling */ struct extent * octeon_pcibus_get_resource_extent(pci_chipset_tag_t pc, int io) { struct octeon_pcibus_softc *sc = pc->pc_conf_v; struct extent *ex; char *exname; int exnamesz; int errors; exnamesz = 1 + 16 + 4; exname = (char *)malloc(exnamesz, M_DEVBUF, M_NOWAIT); if (exname == NULL) return NULL; snprintf(exname, exnamesz, "%s%s", sc->sc_dev.dv_xname, io ? "_io" : "_mem"); ex = extent_create(exname, 0, 0xffffffffffffffff, M_DEVBUF, NULL, 0, EX_NOWAIT | EX_FILLED); if (ex == NULL) goto out; exname = NULL; errors = 0; if (io) { if (extent_free(ex, _OCTEON_PCIBUS_PCIIO_BASE, _OCTEON_PCIBUS_PCIIO_SIZE, EX_NOWAIT) != 0) errors++; } else { if (extent_free(ex, _OCTEON_PCIBUS_PCIMEM_BASE, _OCTEON_PCIBUS_PCIMEM_SIZE, EX_NOWAIT) != 0) errors++; } if (errors != 0) { extent_destroy(ex); ex = NULL; } #ifdef OCTEON_PCIBUS_DEBUG extent_print(ex); #endif out: if (exname != NULL) free(exname, M_DEVBUF); return ex; }
void _bus_dmamap_unload(bus_dma_tag_t t, bus_dmamap_t map) { bus_dma_segment_t *segs; vaddr_t dva; vsize_t sgsize; int error, s; #ifdef DIAGNOSTIC if (map->dm_nsegs != 1) panic("%s: invalid nsegs = %d", __func__, map->dm_nsegs); #endif segs = map->dm_segs; dva = segs[0]._ds_va & ~PGOFSET; sgsize = segs[0]._ds_sgsize; /* Unmap the DVMA addresses. */ pmap_remove(pmap_kernel(), dva, dva + sgsize); pmap_update(pmap_kernel()); /* Free the DVMA addresses. */ s = splvm(); error = extent_free(dvma_extent, dva, sgsize, EX_NOWAIT); splx(s); #ifdef DIAGNOSTIC if (error) panic("%s: unable to free DVMA region", __func__); #endif /* Mark the mappings as invalid. */ map->dm_mapsize = 0; map->dm_nsegs = 0; }
void __C(CHIP,_mem_unmap)( void *v, bus_space_handle_t memh, bus_size_t memsize, int acct) { bus_addr_t memaddr; int error; if (acct == 0) return; #ifdef EXTENT_DEBUG printf("mem: freeing handle 0x%lx for 0x%lx\n", memh, memsize); #endif memaddr = memh - ALPHA_PHYS_TO_K0SEG(CHIP_MEM_SYS_START(v)); #ifdef EXTENT_DEBUG printf("mem: freeing 0x%lx to 0x%lx\n", memaddr, memaddr + memsize - 1); #endif error = extent_free(CHIP_MEM_EXTENT(v), memaddr, memsize, EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0)); if (error) { printf("%s: WARNING: could not unmap 0x%lx-0x%lx (error %d)\n", __S(__C(CHIP,_mem_unmap)), memaddr, memaddr + memsize - 1, error); #ifdef EXTENT_DEBUG extent_print(CHIP_MEM_EXTENT(v)); #endif } }
int mbus_alloc(void *v, bus_addr_t rstart, bus_addr_t rend, bus_size_t size, bus_size_t align, bus_size_t boundary, int flags, bus_addr_t *addrp, bus_space_handle_t *bshp) { bus_addr_t bpa; int error; rstart &= HPPA_PHYSMAP; rend &= HPPA_PHYSMAP; if (rstart < hppa_ex->ex_start || rend > hppa_ex->ex_end) panic("bus_space_alloc: bad region start/end"); if ((error = extent_alloc_subregion(hppa_ex, rstart, rend, size, align, 0, boundary, EX_NOWAIT, &bpa))) return (error); if ((error = mbus_add_mapping(bpa, size, flags, bshp))) { if (extent_free(hppa_ex, bpa, size, EX_NOWAIT)) { printf("bus_space_alloc: pa 0x%lx, size 0x%lx\n", bpa, size); printf("bus_space_alloc: can't free region\n"); } } *addrp = bpa | ~HPPA_PHYSMAP; return (error); }
void jensenio_intio_unmap(void *v, bus_space_handle_t ioh, bus_size_t iosize, int acct) { struct jensenio_config *jcp = v; bus_addr_t ioaddr; int error; if (acct == 0) return; #ifdef EXTENT_DEBUG printf("intio: freeing handle 0x%lx for 0x%lx\n", ioh, iosize); #endif ioh = ALPHA_K0SEG_TO_PHYS(ioh); ioaddr = (ioh - JENSEN_VL82C106) >> 9; #ifdef EXTENT_DEBUG printf("intio: freeing 0x%lx to 0x%lx\n", ioaddr, ioaddr + iosize - 1); #endif error = extent_free(jcp->jc_io_ex, ioaddr, iosize, EX_NOWAIT | (jcp->jc_mallocsafe ? EX_MALLOCOK : 0)); if (error) { printf("WARNING: could not unmap 0x%lx-0x%lx (error %d)\n", ioaddr, ioaddr + iosize - 1, error); #ifdef EXTENT_DEBUG extent_print(jcp->jc_io_ex); #endif } }
int bus_space_map(bus_space_tag_t t, bus_addr_t bpa, bus_size_t size, int flags, bus_space_handle_t *bshp) { int error; struct extent *ex; /* * Pick the appropriate extent map. */ if (t == X86_BUS_SPACE_IO) { ex = ioport_ex; if (flags & BUS_SPACE_MAP_LINEAR) return (EINVAL); } else if (t == X86_BUS_SPACE_MEM) ex = iomem_ex; else panic("bus_space_map: bad bus space tag"); /* * Before we go any further, let's make sure that this * region is available. */ error = extent_alloc_region(ex, bpa, size, EX_NOWAIT | (ioport_malloc_safe ? EX_MALLOCOK : 0)); if (error) return (error); /* * For I/O space, that's all she wrote. */ if (t == X86_BUS_SPACE_IO) { *bshp = bpa; return (0); } if (bpa >= IOM_BEGIN && (bpa + size) <= IOM_END) { *bshp = (bus_space_handle_t)ISA_HOLE_VADDR(bpa); return(0); } /* * For memory space, map the bus physical address to * a kernel virtual address. */ error = x86_mem_add_mapping(bpa, size, flags, bshp); if (error) { if (extent_free(ex, bpa, size, EX_NOWAIT | (ioport_malloc_safe ? EX_MALLOCOK : 0))) { printf("bus_space_map: pa 0x%lx, size 0x%lx\n", bpa, size); printf("bus_space_map: can't free region\n"); } } return (error); }
int vme_map(struct vme_softc *sc, struct extent *ext, u_int awidth, bus_addr_t addr, bus_size_t size, int flags, vaddr_t *rva) { const struct vme_range *r; int rc; paddr_t pa; psize_t offs, len; /* * Since we need to map VME address ranges on demand, we will allocate * with a page granularity. */ pa = trunc_page(addr); offs = addr - pa; len = round_page(addr + size) - pa; /* * Check that the mapping fits within the available address ranges. */ for (r = sc->sc_ranges; r->vr_width != 0; r++) { if (r->vr_width == awidth && r->vr_start <= addr && r->vr_end >= addr + size - 1) break; } if (r->vr_width == 0) return EINVAL; /* * Register this range in the per-width extent. */ if (ext != NULL) { rc = extent_alloc_region(ext, atop(pa), atop(len), EX_NOWAIT | EX_MALLOCOK); if (rc != 0) return rc; } /* * Allocate virtual memory for the range and map it. */ rc = vme_map_r(r, pa, len, flags, UVM_PROT_RW, rva); if (rc != 0) { if (ext != NULL) (void)extent_free(ext, atop(pa), atop(len), EX_NOWAIT | EX_MALLOCOK); return rc; } *rva += offs; return 0; }
void pci_init_extents(void) { bios_memmap_t *bmp; u_int64_t size; if (pciio_ex == NULL) { /* * We only have 64K of addressable I/O space. * However, since BARs may contain garbage, we cover * the full 32-bit address space defined by PCI of * which we only make the first 64K available. */ pciio_ex = extent_create("pciio", 0, 0xffffffff, M_DEVBUF, NULL, 0, EX_NOWAIT | EX_FILLED); if (pciio_ex == NULL) return; extent_free(pciio_ex, 0, 0x10000, M_NOWAIT); } if (pcimem_ex == NULL) { pcimem_ex = extent_create("pcimem", 0, 0xffffffff, M_DEVBUF, NULL, 0, EX_NOWAIT); if (pcimem_ex == NULL) return; for (bmp = bios_memmap; bmp->type != BIOS_MAP_END; bmp++) { /* * Ignore address space beyond 4G. */ if (bmp->addr >= 0x100000000ULL) continue; size = bmp->size; if (bmp->addr + size >= 0x100000000ULL) size = 0x100000000ULL - bmp->addr; /* Ignore zero-sized regions. */ if (size == 0) continue; if (extent_alloc_region(pcimem_ex, bmp->addr, size, EX_NOWAIT)) printf("memory map conflict 0x%llx/0x%llx\n", bmp->addr, bmp->size); } /* Take out the video buffer area and BIOS areas. */ extent_alloc_region(pcimem_ex, IOM_BEGIN, IOM_SIZE, EX_CONFLICTOK | EX_NOWAIT); } }
void bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size) { struct extent *ex; u_long va, endva; bus_addr_t bpa; /* * Find the correct extent and bus physical address. */ if (t == X86_BUS_SPACE_IO) { ex = ioport_ex; bpa = bsh; } else if (t == X86_BUS_SPACE_MEM) { ex = iomem_ex; bpa = (bus_addr_t)ISA_PHYSADDR(bsh); if (IOM_BEGIN <= bpa && bpa <= IOM_END) goto ok; va = trunc_page(bsh); endva = round_page(bsh + size); #ifdef DIAGNOSTIC if (endva <= va) panic("bus_space_unmap: overflow"); #endif (void)pmap_extract(pmap_kernel(), va, &bpa); bpa += (bsh & PGOFSET); pmap_kremove(va, endva - va); pmap_update(pmap_kernel()); /* * Free the kernel virtual mapping. */ uvm_km_free(kernel_map, va, endva - va); } else panic("bus_space_unmap: bad bus space tag"); ok: if (extent_free(ex, bpa, size, EX_NOWAIT | (ioport_malloc_safe ? EX_MALLOCOK : 0))) { printf("bus_space_unmap: %s 0x%lx, size 0x%lx\n", (t == X86_BUS_SPACE_IO) ? "port" : "pa", bpa, size); printf("bus_space_unmap: can't free region\n"); } }
void b3_617_unmap_vme(void *vsc, vme_mapresc_t resc) { unsigned long i; struct b3_617_vmeresc *r = resc; /* unmap PCI window */ bus_space_unmap(sc->sc_vmet, r->handle, r->len); for (i = r->firstpage; i < r->firstpage + r->maplen; i += 4) write_mapmem(sc, i, MR_RAM_INVALID); extent_free(sc->vmeext, r->firstpage, r->maplen, 0); free(r, M_DEVBUF); }
void vme_unmap(struct vme_softc *sc, struct extent *ext, u_int awidth, vaddr_t vaddr, paddr_t paddr, bus_size_t size) { const struct vme_range *r; vaddr_t va; paddr_t pa, addr; psize_t len; va = trunc_page(vaddr); pa = trunc_page(paddr); len = round_page(paddr + size) - pa; /* * Retrieve the address range this mapping comes from. */ for (r = sc->sc_ranges; r->vr_width != 0; r++) { if (r->vr_width != awidth) continue; addr = paddr - r->vr_base; if (r->vr_width == awidth && r->vr_start <= addr && r->vr_end >= addr + size - 1) break; } if (r->vr_width == 0) { #ifdef DIAGNOSTIC printf("%s: nonsensical A%d mapping at va 0x%08lx pa 0x%08lx\n", __func__, AWIDTH(awidth), vaddr, paddr); #endif return; } /* * Undo the mapping. */ pmap_kremove(va, len); pmap_update(pmap_kernel()); uvm_km_free(kernel_map, va, len); /* * Unregister mapping. */ if (ext != NULL) { pa -= r->vr_base; extent_free(ext, atop(pa), atop(len), EX_NOWAIT | EX_MALLOCOK); } }
static void _default_unmap(void *t, bus_space_handle_t bsh, bus_size_t size) { struct playstation2_bus_space *pbs = t; struct extent *ex = pbs->pbs_extent; int error; if (ex == 0) return; error = extent_free(ex, bsh, size, EX_NOWAIT); if (error) { DPRINTF("%#lx-%#lx of %s space lost\n", bsh, bsh + size, ex->ex_name); } }
/* * Unmap a previously mapped device. */ void iounmap(void *kva, int size) { #ifdef DEBUG if (((vaddr_t)kva & PGOFSET) || (size & PGOFSET)) panic("iounmap: unaligned"); if ((uint8_t *)kva < extiobase || (uint8_t *)kva >= extiobase + ptoa(EIOMAPSIZE)) panic("iounmap: bad address"); #endif physunaccess(kva, size); if (extent_free(extio_ex, (vaddr_t)kva, size, EX_NOWAIT | (extio_ex_malloc_safe ? EX_MALLOCOK : 0))) printf("iounmap: kva %p size 0x%x: can't free region\n", kva, size); }
int au_himem_alloc(void *cookie, bus_addr_t start, bus_addr_t end, bus_size_t size, bus_size_t align, bus_size_t boundary, int flags, bus_addr_t *addrp, bus_space_handle_t *bshp) { au_himem_cookie_t *c = (au_himem_cookie_t *)cookie; int err; err = extent_alloc_subregion(c->c_extent, start, end, size, align, boundary, EX_FAST | EX_NOWAIT, addrp); if (err) { return err; } err = au_himem_map(cookie, *addrp, size, flags, bshp, 0); if (err) extent_free(c->c_extent, *addrp, size, EX_NOWAIT); return err; }
/* * Free some DVMA space allocated by the above. * This IS safe to call at interrupt time. * (Typically called at SPLBIO) */ void dvma_mapout(void *dma, int len) { vaddr_t seg_dma; vsize_t seg_len, seg_off; vaddr_t v, x; int sme; int s; /* Get seg-aligned address and length. */ seg_dma = (vaddr_t)dma; seg_len = (vsize_t)len; seg_off = seg_dma & SEGOFSET; seg_dma -= seg_off; seg_len = m68k_round_seg(seg_len + seg_off); s = splvm(); /* Flush cache and remove DVMA mappings. */ v = seg_dma; x = v + seg_len; while (v < x) { sme = get_segmap(v); #ifdef DIAGNOSTIC if (sme == SEGINV) panic("dvma_mapout: seg not mapped"); #endif #ifdef HAVECACHE /* flush write-back on the DVMA mappings */ if (cache_size) cache_flush_segment(v); #endif set_segmap_allctx(v, SEGINV); v += NBSG; } if (extent_free(dvma_extent, seg_dma, seg_len, EX_NOWAIT | EX_MALLOCOK)) panic("dvma_mapout: unable to free 0x%lx,0x%lx", seg_dma, seg_len); splx(s); }
int mbus_map(void *v, bus_addr_t bpa, bus_size_t size, int flags, bus_space_handle_t *bshp) { int error; bpa &= HPPA_PHYSMAP; if ((error = extent_alloc_region(hppa_ex, bpa, size, EX_NOWAIT))) return (error); if ((error = mbus_add_mapping(bpa, size, flags, bshp))) { if (extent_free(hppa_ex, bpa, size, EX_NOWAIT)) { printf("bus_space_map: pa 0x%lx, size 0x%lx\n", bpa, size); printf("bus_space_map: can't free region\n"); } } return error; }
void bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size) { vaddr_t kva; vsize_t offset; if (t->bustype == HP300_BUS_SPACE_INTIO) { /* * Intio space is direct-mapped in pmap_bootstrap(); nothing * to do */ return; } if (t->bustype != HP300_BUS_SPACE_DIO && t->bustype != HP300_BUS_SPACE_SGC) panic("%s: bad space tag", __func__); kva = m68k_trunc_page(bsh); offset = m68k_page_offset(bsh); size = m68k_round_page(offset + size); #ifdef DIAGNOSTIC if (bsh < (vaddr_t)extiobase || bsh >= ((vaddr_t)extiobase + ptoa(EIOMAPSIZE))) panic("%s: bad bus space handle", __func__); #endif /* * Unmap the range. */ physunaccess((void *)kva, size); /* * Free it from the extio extent map. */ if (extent_free(extio_ex, kva, size, EX_NOWAIT | (extio_ex_malloc_safe ? EX_MALLOCOK : 0))) printf("%s: kva 0x%lx size 0x%lx: " "can't free region\n", __func__, (u_long)bsh, size); }
void mbus_unmap(void *v, bus_space_handle_t bsh, bus_size_t size) { u_long sva, eva; sva = trunc_page(bsh); eva = round_page(bsh + size); #ifdef DIAGNOSTIC if (eva <= sva) panic("bus_space_unmap: overflow"); #endif pmap_kremove(sva, eva - sva); if (extent_free(hppa_ex, bsh, size, EX_NOWAIT)) { printf("bus_space_unmap: ps 0x%lx, size 0x%lx\n", bsh, size); printf("bus_space_unmap: can't free region\n"); } }
void arc_bus_space_unmap(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t size) { if (bst->bs_extent != NULL) { paddr_t pa; bus_addr_t addr; int err; /* bus_space_paddr() becomes unavailable after unmapping */ err = bus_space_paddr(bst, bsh, &pa); if (err) panic("arc_bus_space_unmap: %s va 0x%qx: error %d", bst->bs_name, (unsigned long long) bsh, err); addr = (bus_size_t)(pa - bst->bs_pbase) + bst->bs_start; extent_free(bst->bs_extent, addr, size, EX_NOWAIT | malloc_safe); } bus_space_dispose_handle(bst, bsh, size); }
/* * Unload a dvmamap. */ void viommu_dvmamap_unload(bus_dma_tag_t t, bus_dma_tag_t t0, bus_dmamap_t map) { struct iommu_state *is; struct iommu_map_state *ims = map->_dm_cookie; bus_addr_t dvmaddr = map->_dm_dvmastart; bus_size_t sgsize = map->_dm_dvmasize; int error; #ifdef DEBUG if (ims == NULL) panic("viommu_dvmamap_unload: null map state"); if (ims->ims_iommu == NULL) panic("viommu_dvmamap_unload: null iommu"); #endif /* DEBUG */ is = ims->ims_iommu; /* Remove the IOMMU entries */ viommu_iomap_unload_map(is, ims); /* Clear the iomap */ iommu_iomap_clear_pages(ims); bus_dmamap_unload(t->_parent, map); /* Mark the mappings as invalid. */ map->dm_mapsize = 0; map->dm_nsegs = 0; mtx_enter(&is->is_mtx); error = extent_free(is->is_dvmamap, dvmaddr, sgsize, EX_NOWAIT); map->_dm_dvmastart = 0; map->_dm_dvmasize = 0; mtx_leave(&is->is_mtx); if (error != 0) printf("warning: %qd of DVMA space lost\n", sgsize); }
void au_himem_unmap(void *cookie, bus_space_handle_t bsh, bus_size_t size, int acct) { au_himem_cookie_t *c = (au_himem_cookie_t *)cookie; vaddr_t va; vsize_t realsz; paddr_t pa; int s; va = (vaddr_t)TRUNC_PAGE(bsh); realsz = (vsize_t)ROUND_PAGE((bsh % PAGE_SIZE) + size); s = splhigh(); /* make sure that any pending writes are flushed */ wbflush(); /* * we have to get the bus address, so that we can free it in the * extent manager. this is the unfortunate thing about using * virtual memory instead of just a 1:1 mapping scheme. */ if (pmap_extract(pmap_kernel(), va, &pa) == false) panic("au_himem_unmap: virtual address invalid!"); /* now remove it from the pmap */ pmap_kremove(va, realsz); pmap_update(pmap_kernel()); splx(s); /* finally we can release both virtual and bus address ranges */ uvm_km_free(kernel_map, va, realsz, UVM_KMF_VAONLY); if (acct) { bus_addr_t addr; addr = ((pa - c->c_physoff) + (bsh % PAGE_SIZE)); extent_free(c->c_extent, addr, size, EX_NOWAIT); } }
/* * we take the trinary returned from intel_setup_mchbar and clean up after * it. */ void intel_teardown_mchbar(struct inteldrm_softc *dev_priv, struct pci_attach_args *bpa, int disable) { struct drm_device *dev = (struct drm_device *)dev_priv->drmdev; u_int64_t mchbar_addr; pcireg_t tmp, low, high = 0; int reg; reg = INTEL_INFO(dev)->gen >= 4 ? MCHBAR_I965 : MCHBAR_I915; switch(disable) { case 2: if (INTEL_INFO(dev)->gen >= 4) high = pci_conf_read(bpa->pa_pc, bpa->pa_tag, reg + 4); low = pci_conf_read(bpa->pa_pc, bpa->pa_tag, reg); mchbar_addr = ((u_int64_t)high << 32) | low; if (bpa->pa_memex) extent_free(bpa->pa_memex, mchbar_addr, MCHBAR_SIZE, 0); /* FALLTHROUGH */ case 1: if (IS_I915G(dev) || IS_I915GM(dev)) { tmp = pci_conf_read(bpa->pa_pc, bpa->pa_tag, DEVEN_REG); tmp &= ~DEVEN_MCHBAR_EN; pci_conf_write(bpa->pa_pc, bpa->pa_tag, DEVEN_REG, tmp); } else { tmp = pci_conf_read(bpa->pa_pc, bpa->pa_tag, reg); tmp &= ~1; pci_conf_write(bpa->pa_pc, bpa->pa_tag, reg, tmp); } break; case 0: default: break; }; }
void ppbattach(struct device *parent, struct device *self, void *aux) { struct ppb_softc *sc = (struct ppb_softc *)self; struct pci_attach_args *pa = aux; pci_chipset_tag_t pc = pa->pa_pc; struct pcibus_attach_args pba; pci_intr_handle_t ih; pcireg_t busdata, reg, blr; char *name; int pin; sc->sc_pc = pc; sc->sc_tag = pa->pa_tag; busdata = pci_conf_read(pc, pa->pa_tag, PPB_REG_BUSINFO); if (PPB_BUSINFO_SECONDARY(busdata) == 0) { printf(": not configured by system firmware\n"); return; } #if 0 /* * XXX can't do this, because we're not given our bus number * (we shouldn't need it), and because we've no way to * decompose our tag. */ /* sanity check. */ if (pa->pa_bus != PPB_BUSINFO_PRIMARY(busdata)) panic("ppbattach: bus in tag (%d) != bus in reg (%d)", pa->pa_bus, PPB_BUSINFO_PRIMARY(busdata)); #endif /* Check for PCI Express capabilities and setup hotplug support. */ if (pci_get_capability(pc, pa->pa_tag, PCI_CAP_PCIEXPRESS, &sc->sc_cap_off, ®) && (reg & PCI_PCIE_XCAP_SI)) { #ifdef __i386__ if (pci_intr_map(pa, &ih) == 0) sc->sc_intrhand = pci_intr_establish(pc, ih, IPL_BIO, ppb_intr, sc, self->dv_xname); #else if (pci_intr_map_msi(pa, &ih) == 0 || pci_intr_map(pa, &ih) == 0) sc->sc_intrhand = pci_intr_establish(pc, ih, IPL_BIO, ppb_intr, sc, self->dv_xname); #endif if (sc->sc_intrhand) { printf(": %s", pci_intr_string(pc, ih)); /* Enable hotplug interrupt. */ reg = pci_conf_read(pc, pa->pa_tag, sc->sc_cap_off + PCI_PCIE_SLCSR); reg |= (PCI_PCIE_SLCSR_HPE | PCI_PCIE_SLCSR_PDE); pci_conf_write(pc, pa->pa_tag, sc->sc_cap_off + PCI_PCIE_SLCSR, reg); timeout_set(&sc->sc_to, ppb_hotplug_insert_finish, sc); } } printf("\n"); if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_INTEL || (PCI_PRODUCT(pa->pa_id) != PCI_PRODUCT_INTEL_82801BA_HPB && PCI_PRODUCT(pa->pa_id) != PCI_PRODUCT_INTEL_82801BAM_HPB)) ppb_alloc_resources(sc, pa); for (pin = PCI_INTERRUPT_PIN_A; pin <= PCI_INTERRUPT_PIN_D; pin++) { pa->pa_intrpin = pa->pa_rawintrpin = pin; pa->pa_intrline = 0; pci_intr_map(pa, &sc->sc_ih[pin - PCI_INTERRUPT_PIN_A]); } /* * The UltraSPARC-IIi APB doesn't implement the standard * address range registers. */ if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_SUN && PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_SUN_SIMBA) goto attach; /* Figure out the I/O address range of the bridge. */ blr = pci_conf_read(pc, pa->pa_tag, PPB_REG_IOSTATUS); sc->sc_iobase = (blr & 0x000000f0) << 8; sc->sc_iolimit = (blr & 0x000f000) | 0x00000fff; blr = pci_conf_read(pc, pa->pa_tag, PPB_REG_IO_HI); sc->sc_iobase |= (blr & 0x0000ffff) << 16; sc->sc_iolimit |= (blr & 0xffff0000); if (sc->sc_iolimit > sc->sc_iobase) { name = malloc(32, M_DEVBUF, M_NOWAIT); if (name) { snprintf(name, 32, "%s pciio", sc->sc_dev.dv_xname); sc->sc_ioex = extent_create(name, 0, 0xffffffff, M_DEVBUF, NULL, 0, EX_NOWAIT | EX_FILLED); extent_free(sc->sc_ioex, sc->sc_iobase, sc->sc_iolimit - sc->sc_iobase + 1, EX_NOWAIT); } } /* Figure out the memory mapped I/O address range of the bridge. */ blr = pci_conf_read(pc, pa->pa_tag, PPB_REG_MEM); sc->sc_membase = (blr & 0x0000fff0) << 16; sc->sc_memlimit = (blr & 0xfff00000) | 0x000fffff; if (sc->sc_memlimit > sc->sc_membase) { name = malloc(32, M_DEVBUF, M_NOWAIT); if (name) { snprintf(name, 32, "%s pcimem", sc->sc_dev.dv_xname); sc->sc_memex = extent_create(name, 0, 0xffffffff, M_DEVBUF, NULL, 0, EX_NOWAIT | EX_FILLED); extent_free(sc->sc_memex, sc->sc_membase, sc->sc_memlimit - sc->sc_membase + 1, EX_NOWAIT); } } /* Figure out the prefetchable MMI/O address range of the bridge. */ blr = pci_conf_read(pc, pa->pa_tag, PPB_REG_PREFMEM); sc->sc_pmembase = (blr & 0x0000fff0) << 16; sc->sc_pmemlimit = (blr & 0xfff00000) | 0x000fffff; #ifdef __LP64__ /* XXX because extents use long... */ blr = pci_conf_read(pc, pa->pa_tag, PPB_REG_PREFBASE_HI32); sc->sc_pmembase |= ((uint64_t)blr) << 32; blr = pci_conf_read(pc, pa->pa_tag, PPB_REG_PREFLIM_HI32); sc->sc_pmemlimit |= ((uint64_t)blr) << 32; #endif if (sc->sc_pmemlimit > sc->sc_pmembase) { name = malloc(32, M_DEVBUF, M_NOWAIT); if (name) { snprintf(name, 32, "%s pcipmem", sc->sc_dev.dv_xname); sc->sc_pmemex = extent_create(name, 0, (u_long)-1L, M_DEVBUF, NULL, 0, EX_NOWAIT | EX_FILLED); extent_free(sc->sc_pmemex, sc->sc_pmembase, sc->sc_pmemlimit - sc->sc_pmembase + 1, EX_NOWAIT); } } /* * The Intel 82801BAM Hub-to-PCI can decode subtractively. * XXX We probably should handle subtractive decode bridges * in general. */ if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_INTEL && (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801BA_HPB || PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801BAM_HPB)) { if (sc->sc_ioex == NULL) sc->sc_ioex = pa->pa_ioex; if (sc->sc_memex == NULL) sc->sc_memex = pa->pa_memex; } attach: /* * Attach the PCI bus that hangs off of it. * * XXX Don't pass-through Memory Read Multiple. Should we? * XXX Consult the spec... */ bzero(&pba, sizeof(pba)); pba.pba_busname = "pci"; pba.pba_iot = pa->pa_iot; pba.pba_memt = pa->pa_memt; pba.pba_dmat = pa->pa_dmat; pba.pba_pc = pc; pba.pba_flags = pa->pa_flags & ~PCI_FLAGS_MRM_OKAY; pba.pba_ioex = sc->sc_ioex; pba.pba_memex = sc->sc_memex; pba.pba_pmemex = sc->sc_pmemex; pba.pba_domain = pa->pa_domain; pba.pba_bus = PPB_BUSINFO_SECONDARY(busdata); pba.pba_bridgeih = sc->sc_ih; pba.pba_bridgetag = &sc->sc_tag; pba.pba_intrswiz = pa->pa_intrswiz; pba.pba_intrtag = pa->pa_intrtag; sc->sc_psc = config_found(self, &pba, ppbprint); }
void socpcic_attach(struct socpcic_softc *sc) { struct pcibus_attach_args pba; struct extent *io_ex; struct extent *mem_ex; bus_addr_t io_base, mem_base; bus_size_t io_size, mem_size; uint32_t *ranges; int len; if (OF_getprop(sc->sc_node, "interrupt-map-mask", sc->sc_map_mask, sizeof(sc->sc_map_mask)) != sizeof(sc->sc_map_mask)) { printf(": missing interrupt-map-mask\n"); return; } sc->sc_map_len = OF_getproplen(sc->sc_node, "interrupt-map"); if (sc->sc_map_len > 0) { sc->sc_map = malloc(sc->sc_map_len, M_DEVBUF, M_NOWAIT); if (sc->sc_map == NULL) panic("out of memory"); len = OF_getprop(sc->sc_node, "interrupt-map", sc->sc_map, sc->sc_map_len); KASSERT(len == sc->sc_map_len); } sc->sc_ranges_len = OF_getproplen(sc->sc_node, "ranges"); if (sc->sc_ranges_len <= 0) { printf(": missing ranges\n"); return; } sc->sc_ranges = malloc(sc->sc_ranges_len, M_DEVBUF, M_NOWAIT); if (ranges == NULL) panic("out of memory"); len = OF_getprop(sc->sc_node, "ranges", sc->sc_ranges, sc->sc_ranges_len); KASSERT(len == sc->sc_ranges_len); ranges = sc->sc_ranges; while (len >= 6 * sizeof(uint32_t)) { switch (ranges[0] & OFW_PCI_PHYS_HI_SPACEMASK) { case OFW_PCI_PHYS_HI_SPACE_IO: KASSERT(ranges[1] == 0); KASSERT(ranges[4] == 0); sc->sc_io_bus_space.bus_base = ranges[3]; sc->sc_io_bus_space.bus_size = ranges[5]; sc->sc_io_bus_space.bus_io = 1; io_base = ranges[2]; io_size = ranges[5]; break; case OFW_PCI_PHYS_HI_SPACE_MEM32: KASSERT(ranges[1] == 0); KASSERT(ranges[4] == 0); sc->sc_mem_bus_space.bus_base = ranges[3]; sc->sc_mem_bus_space.bus_size = ranges[5]; sc->sc_mem_bus_space.bus_io = 0; mem_base = ranges[2]; mem_size = ranges[5]; break; } len -= 6 * sizeof(uint32_t); ranges += 6; } sc->sc_pc.pc_conf_v = sc; sc->sc_pc.pc_attach_hook = socpcic_attach_hook; sc->sc_pc.pc_bus_maxdevs = socpcic_bus_maxdevs; sc->sc_pc.pc_make_tag = socpcic_make_tag; sc->sc_pc.pc_decompose_tag = socpcic_decompose_tag; sc->sc_pc.pc_conf_size = socpcic_conf_size; sc->sc_pc.pc_conf_read = socpcic_conf_read; sc->sc_pc.pc_conf_write = socpcic_conf_write; sc->sc_pc.pc_intr_v = sc; sc->sc_pc.pc_intr_map = socpcic_intr_map; sc->sc_pc.pc_intr_string = socpcic_intr_string; sc->sc_pc.pc_intr_line = socpcic_intr_line; sc->sc_pc.pc_intr_establish = socpcic_intr_establish; sc->sc_pc.pc_intr_disestablish = socpcic_intr_disestablish; sc->sc_pc.pc_ether_hw_addr = socpcic_ether_hw_addr; io_ex = extent_create("pciio", 0, 0xffffffff, M_DEVBUF, NULL, 0, EX_NOWAIT | EX_FILLED); if (io_ex != NULL && io_size) extent_free(io_ex, io_base, io_size, EX_NOWAIT); mem_ex = extent_create("pcimem", 0, 0xffffffff, M_DEVBUF, NULL, 0, EX_NOWAIT | EX_FILLED); if (mem_ex != NULL) extent_free(mem_ex, mem_base, mem_size, EX_NOWAIT); bzero(&pba, sizeof(pba)); pba.pba_busname = "pci"; pba.pba_iot = &sc->sc_io_bus_space; pba.pba_memt = &sc->sc_mem_bus_space; pba.pba_dmat = sc->sc_dmat; pba.pba_ioex = io_ex; pba.pba_memex = mem_ex; pba.pba_pc = &sc->sc_pc; pba.pba_domain = pci_ndomains++; pba.pba_bus = 0; printf("\n"); config_found((struct device *)sc, &pba, socpcic_print); }
int b3_617_map_vme(void *vsc, vme_addr_t vmeaddr, vme_size_t len, vme_am_t am, vme_datasize_t datasizes, vme_swap_t swap, bus_space_tag_t *tag, bus_space_handle_t *handle, vme_mapresc_t *resc) { vme_addr_t vmebase, vmeend, va; unsigned long maplen, first, i; u_int32_t mapreg; bus_addr_t pcibase; int res; struct b3_617_vmeresc *r; /* first mapped address */ vmebase = vmeaddr & ~(VME_PAGESIZE - 1); /* base of last mapped page */ vmeend = (vmeaddr + len - 1) & ~(VME_PAGESIZE - 1); /* bytes in scatter table required */ maplen = ((vmeend - vmebase) / VME_PAGESIZE + 1) * 4; if (extent_alloc(sc->vmeext, maplen, 4, 0, EX_FAST, &first)) return (ENOMEM); /* * set up adapter mapping registers */ mapreg = (am << MR_AMOD_SHIFT) | MR_FC_RRAM | swap; for (i = first, va = vmebase; i < first + maplen; i += 4, va += VME_PAGESIZE) { write_mapmem(sc, i, mapreg | va); #ifdef BIT3DEBUG printf("mapreg@%lx=%x\n", i, read_mapmem(sc, i)); #endif } #ifdef DIAGNOSTIC if (va != vmeend + VME_PAGESIZE) panic("b3_617_map_pci_vme: botch"); #endif /* * map needed range in PCI space */ pcibase = sc->vmepbase + (first - MR_PCI_VME) / 4 * VME_PAGESIZE + (vmeaddr & (VME_PAGESIZE - 1)); if ((res = bus_space_map(sc->sc_vmet, pcibase, len, 0, handle))) { for (i = first; i < first + maplen; i += 4) write_mapmem(sc, i, MR_RAM_INVALID); extent_free(sc->vmeext, first, maplen, 0); return (res); } *tag = sc->sc_vmet; /* * save all data needed for later unmapping */ r = malloc(sizeof(*r), M_DEVBUF, M_NOWAIT); /* XXX check! */ r->handle = *handle; r->len = len; r->firstpage = first; r->maplen = maplen; *resc = r; return (0); }
void __BS(init)(bus_space_tag_t t, void *v) { #ifdef CHIP_EXTENT struct extent *ex; #endif /* * Initialize the bus space tag. */ /* cookie */ t->bs_cookie = v; /* mapping/unmapping */ t->bs_map = __BS(map); t->bs_unmap = __BS(unmap); t->bs_subregion = __BS(subregion); t->bs_translate = __BS(translate); t->bs_get_window = __BS(get_window); /* allocation/deallocation */ t->bs_alloc = __BS(alloc); t->bs_free = __BS(free); /* get kernel virtual address */ t->bs_vaddr = __BS(vaddr); /* mmap for user */ t->bs_mmap = __BS(mmap); /* barrier */ t->bs_barrier = __BS(barrier); /* read (single) */ t->bs_r_1 = __BS(read_1); t->bs_r_2 = __BS(read_2); t->bs_r_4 = __BS(read_4); t->bs_r_8 = __BS(read_8); /* read multiple */ t->bs_rm_1 = __BS(read_multi_1); t->bs_rm_2 = __BS(read_multi_2); t->bs_rm_4 = __BS(read_multi_4); t->bs_rm_8 = __BS(read_multi_8); /* read region */ t->bs_rr_1 = __BS(read_region_1); t->bs_rr_2 = __BS(read_region_2); t->bs_rr_4 = __BS(read_region_4); t->bs_rr_8 = __BS(read_region_8); /* write (single) */ t->bs_w_1 = __BS(write_1); t->bs_w_2 = __BS(write_2); t->bs_w_4 = __BS(write_4); t->bs_w_8 = __BS(write_8); /* write multiple */ t->bs_wm_1 = __BS(write_multi_1); t->bs_wm_2 = __BS(write_multi_2); t->bs_wm_4 = __BS(write_multi_4); t->bs_wm_8 = __BS(write_multi_8); /* write region */ t->bs_wr_1 = __BS(write_region_1); t->bs_wr_2 = __BS(write_region_2); t->bs_wr_4 = __BS(write_region_4); t->bs_wr_8 = __BS(write_region_8); /* set multiple */ t->bs_sm_1 = __BS(set_multi_1); t->bs_sm_2 = __BS(set_multi_2); t->bs_sm_4 = __BS(set_multi_4); t->bs_sm_8 = __BS(set_multi_8); /* set region */ t->bs_sr_1 = __BS(set_region_1); t->bs_sr_2 = __BS(set_region_2); t->bs_sr_4 = __BS(set_region_4); t->bs_sr_8 = __BS(set_region_8); /* copy */ t->bs_c_1 = __BS(copy_region_1); t->bs_c_2 = __BS(copy_region_2); t->bs_c_4 = __BS(copy_region_4); t->bs_c_8 = __BS(copy_region_8); #ifdef CHIP_NEED_STREAM /* read (single), stream */ t->bs_rs_1 = __BS(read_stream_1); t->bs_rs_2 = __BS(read_stream_2); t->bs_rs_4 = __BS(read_stream_4); t->bs_rs_8 = __BS(read_stream_8); /* read multiple, stream */ t->bs_rms_1 = __BS(read_multi_stream_1); t->bs_rms_2 = __BS(read_multi_stream_2); t->bs_rms_4 = __BS(read_multi_stream_4); t->bs_rms_8 = __BS(read_multi_stream_8); /* read region, stream */ t->bs_rrs_1 = __BS(read_region_stream_1); t->bs_rrs_2 = __BS(read_region_stream_2); t->bs_rrs_4 = __BS(read_region_stream_4); t->bs_rrs_8 = __BS(read_region_stream_8); /* write (single), stream */ t->bs_ws_1 = __BS(write_stream_1); t->bs_ws_2 = __BS(write_stream_2); t->bs_ws_4 = __BS(write_stream_4); t->bs_ws_8 = __BS(write_stream_8); /* write multiple, stream */ t->bs_wms_1 = __BS(write_multi_stream_1); t->bs_wms_2 = __BS(write_multi_stream_2); t->bs_wms_4 = __BS(write_multi_stream_4); t->bs_wms_8 = __BS(write_multi_stream_8); /* write region, stream */ t->bs_wrs_1 = __BS(write_region_stream_1); t->bs_wrs_2 = __BS(write_region_stream_2); t->bs_wrs_4 = __BS(write_region_stream_4); t->bs_wrs_8 = __BS(write_region_stream_8); #else /* CHIP_NEED_STREAM */ /* read (single), stream */ t->bs_rs_1 = __BS(read_1); t->bs_rs_2 = __BS(read_2); t->bs_rs_4 = __BS(read_4); t->bs_rs_8 = __BS(read_8); /* read multiple, stream */ t->bs_rms_1 = __BS(read_multi_1); t->bs_rms_2 = __BS(read_multi_2); t->bs_rms_4 = __BS(read_multi_4); t->bs_rms_8 = __BS(read_multi_8); /* read region, stream */ t->bs_rrs_1 = __BS(read_region_1); t->bs_rrs_2 = __BS(read_region_2); t->bs_rrs_4 = __BS(read_region_4); t->bs_rrs_8 = __BS(read_region_8); /* write (single), stream */ t->bs_ws_1 = __BS(write_1); t->bs_ws_2 = __BS(write_2); t->bs_ws_4 = __BS(write_4); t->bs_ws_8 = __BS(write_8); /* write multiple, stream */ t->bs_wms_1 = __BS(write_multi_1); t->bs_wms_2 = __BS(write_multi_2); t->bs_wms_4 = __BS(write_multi_4); t->bs_wms_8 = __BS(write_multi_8); /* write region, stream */ t->bs_wrs_1 = __BS(write_region_1); t->bs_wrs_2 = __BS(write_region_2); t->bs_wrs_4 = __BS(write_region_4); t->bs_wrs_8 = __BS(write_region_8); #endif /* CHIP_NEED_STREAM */ #ifdef CHIP_EXTENT /* XXX WE WANT EXTENT_NOCOALESCE, BUT WE CAN'T USE IT. XXX */ ex = extent_create(__S(__BS(bus)), 0x0UL, 0xffffffffUL, M_DEVBUF, (void *)CHIP_EX_STORE(v), CHIP_EX_STORE_SIZE(v), EX_NOWAIT); extent_alloc_region(ex, 0, 0xffffffffUL, EX_NOWAIT); #ifdef CHIP_W1_BUS_START /* * The window may be disabled. We notice this by seeing * -1 as the bus base address. */ if (CHIP_W1_BUS_START(v) == (bus_addr_t) -1) { #ifdef EXTENT_DEBUG printf("xxx: this space is disabled\n"); #endif return; } #ifdef EXTENT_DEBUG printf("xxx: freeing from 0x%x to 0x%x\n", CHIP_W1_BUS_START(v), CHIP_W1_BUS_END(v)); #endif extent_free(ex, CHIP_W1_BUS_START(v), CHIP_W1_BUS_END(v) - CHIP_W1_BUS_START(v) + 1, EX_NOWAIT); #endif #ifdef CHIP_W2_BUS_START if (CHIP_W2_BUS_START(v) != CHIP_W1_BUS_START(v)) { #ifdef EXTENT_DEBUG printf("xxx: freeing from 0x%lx to 0x%lx\n", (u_long)CHIP_W2_BUS_START(v), (u_long)CHIP_W2_BUS_END(v)); #endif extent_free(ex, CHIP_W2_BUS_START(v), CHIP_W2_BUS_END(v) - CHIP_W2_BUS_START(v) + 1, EX_NOWAIT); } else { #ifdef EXTENT_DEBUG printf("xxx: window 2 (0x%lx to 0x%lx) overlaps window 1\n", (u_long)CHIP_W2_BUS_START(v), (u_long)CHIP_W2_BUS_END(v)); #endif } #endif #ifdef CHIP_W3_BUS_START if (CHIP_W3_BUS_START(v) != CHIP_W1_BUS_START(v) && CHIP_W3_BUS_START(v) != CHIP_W2_BUS_START(v)) { #ifdef EXTENT_DEBUG printf("xxx: freeing from 0x%lx to 0x%lx\n", (u_long)CHIP_W3_BUS_START(v), (u_long)CHIP_W3_BUS_END(v)); #endif extent_free(ex, CHIP_W3_BUS_START(v), CHIP_W3_BUS_END(v) - CHIP_W3_BUS_START(v) + 1, EX_NOWAIT); } else { #ifdef EXTENT_DEBUG printf("xxx: window 2 (0x%lx to 0x%lx) overlaps window 1\n", (u_long)CHIP_W2_BUS_START(v), (u_long)CHIP_W2_BUS_END(v)); #endif } #endif #ifdef EXTENT_DEBUG extent_print(ex); #endif CHIP_EXTENT(v) = ex; #endif /* CHIP_EXTENT */ }
int bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart, bus_addr_t rend, bus_size_t size, bus_size_t alignment, bus_size_t boundary, int flags, bus_addr_t *bpap, bus_space_handle_t *bshp) { struct extent *ex; u_long bpa; int error; /* * Pick the appropriate extent map. */ if (t == X86_BUS_SPACE_IO) { ex = ioport_ex; } else if (t == X86_BUS_SPACE_MEM) ex = iomem_ex; else panic("bus_space_alloc: bad bus space tag"); /* * Sanity check the allocation against the extent's boundaries. */ if (rstart < ex->ex_start || rend > ex->ex_end) panic("bus_space_alloc: bad region start/end"); /* * Do the requested allocation. */ error = extent_alloc_subregion(ex, rstart, rend, size, alignment, 0, boundary, EX_FAST | EX_NOWAIT | (ioport_malloc_safe ? EX_MALLOCOK : 0), &bpa); if (error) return (error); /* * For I/O space, that's all she wrote. */ if (t == X86_BUS_SPACE_IO) { *bshp = *bpap = bpa; return (0); } /* * For memory space, map the bus physical address to * a kernel virtual address. */ error = x86_mem_add_mapping(bpa, size, flags, bshp); if (error) { if (extent_free(iomem_ex, bpa, size, EX_NOWAIT | (ioport_malloc_safe ? EX_MALLOCOK : 0))) { printf("bus_space_alloc: pa 0x%lx, size 0x%lx\n", bpa, size); printf("bus_space_alloc: can't free region\n"); } } *bpap = bpa; return (error); }
void __C(CHIP,_bus_mem_init)(bus_space_tag_t t, void *v) { #ifdef CHIP_D_MEM_W1_SYS_START struct extent *dex; #endif struct extent *sex; /* * Initialize the bus space tag. */ /* cookie */ t->abs_cookie = v; /* mapping/unmapping */ t->abs_map = __C(CHIP,_mem_map); t->abs_unmap = __C(CHIP,_mem_unmap); t->abs_subregion = __C(CHIP,_mem_subregion); t->abs_translate = __C(CHIP,_mem_translate); t->abs_get_window = __C(CHIP,_mem_get_window); /* allocation/deallocation */ t->abs_alloc = __C(CHIP,_mem_alloc); t->abs_free = __C(CHIP,_mem_free); /* get kernel virtual address */ t->abs_vaddr = __C(CHIP,_mem_vaddr); /* mmap for user */ t->abs_mmap = __C(CHIP,_mem_mmap); /* barrier */ t->abs_barrier = __C(CHIP,_mem_barrier); /* read (single) */ t->abs_r_1 = __C(CHIP,_mem_read_1); t->abs_r_2 = __C(CHIP,_mem_read_2); t->abs_r_4 = __C(CHIP,_mem_read_4); t->abs_r_8 = __C(CHIP,_mem_read_8); /* read multiple */ t->abs_rm_1 = __C(CHIP,_mem_read_multi_1); t->abs_rm_2 = __C(CHIP,_mem_read_multi_2); t->abs_rm_4 = __C(CHIP,_mem_read_multi_4); t->abs_rm_8 = __C(CHIP,_mem_read_multi_8); /* read region */ t->abs_rr_1 = __C(CHIP,_mem_read_region_1); t->abs_rr_2 = __C(CHIP,_mem_read_region_2); t->abs_rr_4 = __C(CHIP,_mem_read_region_4); t->abs_rr_8 = __C(CHIP,_mem_read_region_8); /* write (single) */ t->abs_w_1 = __C(CHIP,_mem_write_1); t->abs_w_2 = __C(CHIP,_mem_write_2); t->abs_w_4 = __C(CHIP,_mem_write_4); t->abs_w_8 = __C(CHIP,_mem_write_8); /* write multiple */ t->abs_wm_1 = __C(CHIP,_mem_write_multi_1); t->abs_wm_2 = __C(CHIP,_mem_write_multi_2); t->abs_wm_4 = __C(CHIP,_mem_write_multi_4); t->abs_wm_8 = __C(CHIP,_mem_write_multi_8); /* write region */ t->abs_wr_1 = __C(CHIP,_mem_write_region_1); t->abs_wr_2 = __C(CHIP,_mem_write_region_2); t->abs_wr_4 = __C(CHIP,_mem_write_region_4); t->abs_wr_8 = __C(CHIP,_mem_write_region_8); /* set multiple */ t->abs_sm_1 = __C(CHIP,_mem_set_multi_1); t->abs_sm_2 = __C(CHIP,_mem_set_multi_2); t->abs_sm_4 = __C(CHIP,_mem_set_multi_4); t->abs_sm_8 = __C(CHIP,_mem_set_multi_8); /* set region */ t->abs_sr_1 = __C(CHIP,_mem_set_region_1); t->abs_sr_2 = __C(CHIP,_mem_set_region_2); t->abs_sr_4 = __C(CHIP,_mem_set_region_4); t->abs_sr_8 = __C(CHIP,_mem_set_region_8); /* copy */ t->abs_c_1 = __C(CHIP,_mem_copy_region_1); t->abs_c_2 = __C(CHIP,_mem_copy_region_2); t->abs_c_4 = __C(CHIP,_mem_copy_region_4); t->abs_c_8 = __C(CHIP,_mem_copy_region_8); #ifdef CHIP_D_MEM_W1_SYS_START /* XXX WE WANT EXTENT_NOCOALESCE, BUT WE CAN'T USE IT. XXX */ dex = extent_create(__S(__C(CHIP,_bus_dmem)), 0x0UL, 0xffffffffffffffffUL, (void *)CHIP_D_MEM_EX_STORE(v), CHIP_D_MEM_EX_STORE_SIZE(v), EX_NOWAIT); extent_alloc_region(dex, 0, 0xffffffffffffffffUL, EX_NOWAIT); #ifdef CHIP_D_MEM_W1_BUS_START #ifdef EXTENT_DEBUG printf("dmem: freeing from 0x%lx to 0x%lx\n", CHIP_D_MEM_W1_BUS_START(v), CHIP_D_MEM_W1_BUS_END(v)); #endif extent_free(dex, CHIP_D_MEM_W1_BUS_START(v), CHIP_D_MEM_W1_BUS_END(v) - CHIP_D_MEM_W1_BUS_START(v) + 1, EX_NOWAIT); #endif #ifdef EXTENT_DEBUG extent_print(dex); #endif CHIP_D_MEM_EXTENT(v) = dex; #endif /* CHIP_D_MEM_W1_SYS_START */ /* XXX WE WANT EXTENT_NOCOALESCE, BUT WE CAN'T USE IT. XXX */ sex = extent_create(__S(__C(CHIP,_bus_smem)), 0x0UL, 0xffffffffffffffffUL, (void *)CHIP_S_MEM_EX_STORE(v), CHIP_S_MEM_EX_STORE_SIZE(v), EX_NOWAIT); extent_alloc_region(sex, 0, 0xffffffffffffffffUL, EX_NOWAIT); #ifdef CHIP_S_MEM_W1_BUS_START #ifdef EXTENT_DEBUG printf("smem: freeing from 0x%lx to 0x%lx\n", CHIP_S_MEM_W1_BUS_START(v), CHIP_S_MEM_W1_BUS_END(v)); #endif extent_free(sex, CHIP_S_MEM_W1_BUS_START(v), CHIP_S_MEM_W1_BUS_END(v) - CHIP_S_MEM_W1_BUS_START(v) + 1, EX_NOWAIT); #endif #ifdef CHIP_S_MEM_W2_BUS_START if (CHIP_S_MEM_W2_BUS_START(v) != CHIP_S_MEM_W1_BUS_START(v)) { #ifdef EXTENT_DEBUG printf("smem: freeing from 0x%lx to 0x%lx\n", CHIP_S_MEM_W2_BUS_START(v), CHIP_S_MEM_W2_BUS_END(v)); #endif extent_free(sex, CHIP_S_MEM_W2_BUS_START(v), CHIP_S_MEM_W2_BUS_END(v) - CHIP_S_MEM_W2_BUS_START(v) + 1, EX_NOWAIT); } else { #ifdef EXTENT_DEBUG printf("smem: window 2 (0x%lx to 0x%lx) overlaps window 1\n", CHIP_S_MEM_W2_BUS_START(v), CHIP_S_MEM_W2_BUS_END(v)); #endif } #endif #ifdef CHIP_S_MEM_W3_BUS_START if (CHIP_S_MEM_W3_BUS_START(v) != CHIP_S_MEM_W1_BUS_START(v) && CHIP_S_MEM_W3_BUS_START(v) != CHIP_S_MEM_W2_BUS_START(v)) { #ifdef EXTENT_DEBUG printf("smem: freeing from 0x%lx to 0x%lx\n", CHIP_S_MEM_W3_BUS_START(v), CHIP_S_MEM_W3_BUS_END(v)); #endif extent_free(sex, CHIP_S_MEM_W3_BUS_START(v), CHIP_S_MEM_W3_BUS_END(v) - CHIP_S_MEM_W3_BUS_START(v) + 1, EX_NOWAIT); } else { #ifdef EXTENT_DEBUG printf("smem: window 2 (0x%lx to 0x%lx) overlaps window 1\n", CHIP_S_MEM_W2_BUS_START(v), CHIP_S_MEM_W2_BUS_END(v)); #endif } #endif #ifdef EXTENT_DEBUG extent_print(sex); #endif CHIP_S_MEM_EXTENT(v) = sex; }
void __BS(unmap)(void *v, bus_space_handle_t h, bus_size_t size, int acct) { #ifdef CHIP_EXTENT bus_addr_t addr; int error; if (acct == 0) return; #ifdef EXTENT_DEBUG printf("xxx: freeing handle 0x%lx for 0x%lx\n", h, size); #endif if (h >= MIPS_KSEG0_START && h < MIPS_KSEG1_START) h = MIPS_KSEG0_TO_PHYS(h); else h = MIPS_KSEG1_TO_PHYS(h); #ifdef CHIP_W1_BUS_START if (h >= CHIP_W1_SYS_START(v) && h <= CHIP_W1_SYS_END(v)) { addr = CHIP_W1_BUS_START(v) + (h - CHIP_W1_SYS_START(v)); } else #endif #ifdef CHIP_W2_BUS_START if (h >= CHIP_W2_SYS_START(v) && h <= CHIP_W2_SYS_END(v)) { addr = CHIP_W2_BUS_START(v) + (h - CHIP_W2_SYS_START(v)); } else #endif #ifdef CHIP_W3_BUS_START if (h >= CHIP_W3_SYS_START(v) && h <= CHIP_W3_SYS_END(v)) { addr = CHIP_W3_BUS_START(v) + (h - CHIP_W3_SYS_START(v)); } else #endif { printf("\n"); #ifdef CHIP_W1_BUS_START printf("%s: sys window[1]=0x%lx-0x%lx\n", __S(__BS(map)), (u_long)CHIP_W1_SYS_START(v), (u_long)CHIP_W1_SYS_END(v)); #endif #ifdef CHIP_W2_BUS_START printf("%s: sys window[2]=0x%lx-0x%lx\n", __S(__BS(map)), (u_long)CHIP_W2_SYS_START(v), (u_long)CHIP_W2_SYS_END(v)); #endif #ifdef CHIP_W3_BUS_START printf("%s: sys window[3]=0x%lx-0x%lx\n", __S(__BS(map)), (u_long)CHIP_W3_SYS_START(v), (u_long)CHIP_W3_SYS_END(v)); #endif panic("%s: don't know how to unmap %lx", __S(__BS(unmap)), h); } #ifdef EXTENT_DEBUG printf("xxx: freeing 0x%lx to 0x%lx\n", addr, addr + size - 1); #endif error = extent_free(CHIP_EXTENT(v), addr, size, EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0)); if (error) { printf("%s: WARNING: could not unmap 0x%lx-0x%lx (error %d)\n", __S(__BS(unmap)), addr, addr + size - 1, error); #ifdef EXTENT_DEBUG extent_print(CHIP_EXTENT(v)); #endif } #endif /* CHIP_EXTENT */ }
int __BS(alloc)(void *v, bus_addr_t rstart, bus_addr_t rend, bus_size_t size, bus_size_t align, bus_size_t boundary, int flags, bus_addr_t *addrp, bus_space_handle_t *bshp) { #ifdef CHIP_EXTENT struct mips_bus_space_translation mbst; bus_addr_t addr; int error; #if CHIP_ALIGN_STRIDE != 0 int linear = flags & BUS_SPACE_MAP_LINEAR; /* * Can't map xxx space linearly. */ if (linear) return (EOPNOTSUPP); #endif /* * Do the requested allocation. */ #ifdef EXTENT_DEBUG printf("xxx: allocating from 0x%lx to 0x%lx\n", rstart, rend); #endif error = extent_alloc_subregion(CHIP_EXTENT(v), rstart, rend, size, align, boundary, EX_FAST | EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0), &addr); if (error) { #ifdef EXTENT_DEBUG printf("xxx: allocation failed (%d)\n", error); extent_print(CHIP_EXTENT(v)); #endif return (error); } #ifdef EXTENT_DEBUG printf("xxx: allocated 0x%lx to 0x%lx\n", addr, addr + size - 1); #endif error = __BS(translate)(v, addr, size, flags, &mbst); if (error) { (void) extent_free(CHIP_EXTENT(v), addr, size, EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0)); return (error); } *addrp = addr; if (flags & BUS_SPACE_MAP_CACHEABLE) *bshp = MIPS_PHYS_TO_KSEG0(mbst.mbst_sys_start + (addr - mbst.mbst_bus_start)); else *bshp = MIPS_PHYS_TO_KSEG1(mbst.mbst_sys_start + (addr - mbst.mbst_bus_start)); return (0); #else /* ! CHIP_EXTENT */ return (EOPNOTSUPP); #endif /* CHIP_EXTENT */ }