diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2009-05-03 21:30:10 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2009-05-03 21:30:10 +0000 |
commit | bd74198d1bacda9a7174aa132a93f922df4cfe4f (patch) | |
tree | cfb5fe65f43b425c257f26df7cd02cb6aece3f38 | |
parent | 444cf09812c53e424a7a660801091456e94aeaa0 (diff) |
Get rid of pci_addr_fixup machinery; set up the appropriate extents and pass
them along when we attach pci(4). Simplify the rbus code by using extents
too.
-rw-r--r-- | sys/arch/macppc/conf/files.macppc | 3 | ||||
-rw-r--r-- | sys/arch/macppc/macppc/rbus_machdep.c | 48 | ||||
-rw-r--r-- | sys/arch/macppc/pci/mpcpcibus.c | 165 | ||||
-rw-r--r-- | sys/arch/macppc/pci/pci_addr_fixup.c | 500 | ||||
-rw-r--r-- | sys/arch/macppc/pci/pcibrvar.h | 26 |
5 files changed, 102 insertions, 640 deletions
diff --git a/sys/arch/macppc/conf/files.macppc b/sys/arch/macppc/conf/files.macppc index 273b6b477fd..814bd305cb4 100644 --- a/sys/arch/macppc/conf/files.macppc +++ b/sys/arch/macppc/conf/files.macppc @@ -1,4 +1,4 @@ -# $OpenBSD: files.macppc,v 1.59 2008/03/21 18:44:14 deraadt Exp $ +# $OpenBSD: files.macppc,v 1.60 2009/05/03 21:30:09 kettenis Exp $ # # macppc-specific configuration info @@ -70,7 +70,6 @@ include "dev/puc/files.puc" device mpcpcibr {} : pcibus attach mpcpcibr at mainbus file arch/macppc/pci/mpcpcibus.c mpcpcibr -file arch/macppc/pci/pci_addr_fixup.c mpcpcibr device ht {} : pcibus attach ht at mainbus diff --git a/sys/arch/macppc/macppc/rbus_machdep.c b/sys/arch/macppc/macppc/rbus_machdep.c index 754b7e5f340..add5956a68d 100644 --- a/sys/arch/macppc/macppc/rbus_machdep.c +++ b/sys/arch/macppc/macppc/rbus_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rbus_machdep.c,v 1.7 2007/12/09 17:02:56 kettenis Exp $ */ +/* $OpenBSD: rbus_machdep.c,v 1.8 2009/05/03 21:30:09 kettenis Exp $ */ /* $NetBSD: rbus_machdep.c,v 1.2 1999/10/15 06:43:06 haya Exp $ */ /* @@ -49,60 +49,22 @@ void macppc_cardbus_init(pci_chipset_tag_t pc, pcitag_t tag); -/********************************************************************** - * rbus_tag_t rbus_fakeparent_mem(struct pci_attach_args *pa) - * - * This function makes an rbus tag for memory space. This rbus tag - * shares the all memory region of ex_iomem. - **********************************************************************/ -#define RBUS_MEM_SIZE 0x10000000 - rbus_tag_t rbus_pccbb_parent_mem(struct device *self, struct pci_attach_args *pa) { - bus_addr_t start; - bus_size_t size; - struct extent *ex; - macppc_cardbus_init(pa->pa_pc, pa->pa_tag); - size = RBUS_MEM_SIZE; - if ((ex = pciaddr_search(PCIADDR_SEARCH_MEM, self, &start, size)) == - NULL) - { - /* XXX */ - printf("failed\n"); - } - - return rbus_new_root_share(pa->pa_memt, ex, start, size, 0); + return (rbus_new_root_share(pa->pa_memt, pa->pa_memex, + 0x00000000, 0xffffffff, 0)); } - -/********************************************************************** - * rbus_tag_t rbus_pccbb_parent_io(struct pci_attach_args *pa) - **********************************************************************/ -#define RBUS_IO_SIZE 0x1000 - rbus_tag_t rbus_pccbb_parent_io(struct device *self, struct pci_attach_args *pa) { - struct extent *ex; - bus_addr_t start; - bus_size_t size; - - - size = RBUS_IO_SIZE; - if ((ex = pciaddr_search(PCIADDR_SEARCH_IO, self, &start, size)) == - NULL) - { - /* XXX */ - printf("failed\n"); - } - - return rbus_new_root_share(pa->pa_iot, ex, start, size, 0); + return (rbus_new_root_share(pa->pa_iot, pa->pa_ioex, + 0x0000, 0xffff, 0)); } - /* * Big ugly hack to enable bridge/fix interrupts */ diff --git a/sys/arch/macppc/pci/mpcpcibus.c b/sys/arch/macppc/pci/mpcpcibus.c index 74cac636b33..ed27df753ae 100644 --- a/sys/arch/macppc/pci/mpcpcibus.c +++ b/sys/arch/macppc/pci/mpcpcibus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mpcpcibus.c,v 1.38 2009/03/29 22:58:31 kettenis Exp $ */ +/* $OpenBSD: mpcpcibus.c,v 1.39 2009/05/03 21:30:09 kettenis Exp $ */ /* * Copyright (c) 1997 Per Fogelstrom @@ -88,6 +88,9 @@ struct cfdriver mpcpcibr_cd = { static int mpcpcibrprint(void *, const char *pnp); +void mpcpcibus_find_ranges_32(struct pcibr_softc *, u_int32_t *, int); +void mpcpcibus_find_ranges_64(struct pcibr_softc *, u_int32_t *, int); + struct pcibr_config mpc_config; /* @@ -147,34 +150,26 @@ mpcpcibrmatch(struct device *parent, void *match, void *aux) return found; } -int pci_map_a = 0; - struct ranges_32 { - u_int32_t flags; - u_int32_t pad1; - u_int32_t pad2; - u_int32_t base; - u_int32_t pad3; - u_int32_t size; + u_int32_t cspace; + u_int32_t child_hi; + u_int32_t child_lo; + u_int32_t phys; + u_int32_t size_hi; + u_int32_t size_lo; }; + void -mpcpcibus_find_ranges_32 (struct pcibr_softc *sc, u_int32_t *range_store, - int rangesize); -void -mpcpcibus_find_ranges_64 (struct pcibr_softc *sc, u_int32_t *range_store, - int rangesize); -void -mpcpcibus_find_ranges_32 (struct pcibr_softc *sc, u_int32_t *range_store, +mpcpcibus_find_ranges_32(struct pcibr_softc *sc, u_int32_t *range_store, int rangesize) { - int found; + int i, found; unsigned int base = 0; unsigned int size = 0; struct ranges_32 *prange = (void *)range_store; int rangelen; - int i; - rangelen = rangesize / sizeof (struct ranges_32); + rangelen = rangesize / sizeof(struct ranges_32); /* mac configs */ sc->sc_membus_space.bus_base = 0; @@ -184,18 +179,20 @@ mpcpcibus_find_ranges_32 (struct pcibr_softc *sc, u_int32_t *range_store, /* find io(config) base, flag == 0x01000000 */ found = 0; - for (i = 0; i < rangelen ; i++) { - if (prange[i].flags == 0x01000000) { + for (i = 0; i < rangelen; i++) { + if (prange[i].cspace == 0x01000000) { /* find last? */ found = i; + + if (sc->sc_ioex) + extent_free(sc->sc_ioex, prange[i].child_lo, + prange[i].size_lo, EX_NOWAIT); } } /* found the io space ranges */ - if (prange[found].flags == 0x01000000) { - sc->sc_iobus_space.bus_base = - prange[found].base; - sc->sc_iobus_space.bus_size = - prange[found].size; + if (prange[found].cspace == 0x01000000) { + sc->sc_iobus_space.bus_base = prange[found].phys; + sc->sc_iobus_space.bus_size = prange[found].size_lo; } /* the mem space ranges @@ -206,26 +203,29 @@ mpcpcibus_find_ranges_32 (struct pcibr_softc *sc, u_int32_t *range_store, * and all IO and device memory will be in * upper 2G of address space, set to * 0x80000000 - * start with segment 1 not 0, 0 is config. */ - for (i = 0; i < rangelen ; i++) { - if (prange[i].flags == 0x02000000) { + for (i = 0; i < rangelen; i++) { + if (prange[i].cspace == 0x02000000) { #ifdef DEBUG_PCI printf("\nfound mem %x %x", - prange[i].base, - prange[i].size); + prange[i].phys, + prange[i].size_lo); #endif if (base != 0) { - if ((base + size) == prange[i].base) - size += prange[i].size; + if ((base + size) == prange[i].phys) + size += prange[i].size_lo; else { - size = prange[i].size; - base = prange[i].base; + base = prange[i].phys; + size = prange[i].size_lo; } } else { - base = prange[i].base; - size = prange[i].size; + base = prange[i].phys; + size = prange[i].size_lo; } + + if (sc->sc_memex) + extent_free(sc->sc_memex, prange[i].child_lo, + prange[i].size_lo, EX_NOWAIT); } } sc->sc_membus_space.bus_base = base; @@ -233,55 +233,61 @@ mpcpcibus_find_ranges_32 (struct pcibr_softc *sc, u_int32_t *range_store, } struct ranges_64 { - u_int32_t flags; - u_int32_t pad1; - u_int32_t pad2; - u_int32_t pad3; - u_int32_t base; - u_int32_t pad4; - u_int32_t size; + u_int32_t cspace; + u_int32_t child_hi; + u_int32_t child_lo; + u_int32_t phys_hi; + u_int32_t phys_lo; + u_int32_t size_hi; + u_int32_t size_lo; }; + void -mpcpcibus_find_ranges_64 (struct pcibr_softc *sc, u_int32_t *range_store, +mpcpcibus_find_ranges_64(struct pcibr_softc *sc, u_int32_t *range_store, int rangesize) { int i, found; unsigned int base = 0; unsigned int size = 0; - int rangelen; struct ranges_64 *prange = (void *)range_store; + int rangelen; - rangelen = rangesize / sizeof (struct ranges_64); + rangelen = rangesize / sizeof(struct ranges_64); /* mac configs */ - sc->sc_membus_space.bus_base = 0; sc->sc_membus_space.bus_io = 0; sc->sc_iobus_space.bus_base = 0; sc->sc_iobus_space.bus_io = 1; - if (prange[0].flags == 0xabb10113) { /* appl U3; */ - prange[0].flags = 0x01000000; - prange[0].base = 0xf8070000; - prange[0].size = 0x00001000; - prange[1].flags = 0x02000000; - prange[1].base = 0xf2000000; - prange[1].size = 0x02800000; + if (prange[0].cspace == 0xabb10113) { /* appl U3; */ + prange[0].cspace = 0x01000000; + prange[0].child_lo = 0x00000000; + prange[0].phys_lo = 0xf8070000; + prange[0].size_lo = 0x00001000; + prange[1].cspace = 0x02000000; + prange[1].child_lo = 0xf2000000; + prange[1].phys_lo = 0xf2000000; + prange[1].size_lo = 0x02800000; rangelen = 2; } /* find io(config) base, flag == 0x01000000 */ found = 0; - for (i = 0; i < rangelen ; i++) { - if (prange[i].flags == 0x01000000) { + for (i = 0; i < rangelen; i++) { + if (prange[i].cspace == 0x01000000) { /* find last? */ found = i; + + if (sc->sc_ioex) + extent_free(sc->sc_ioex, prange[i].child_lo, + prange[i].size_lo, EX_NOWAIT); } } /* found the io space ranges */ - if (prange[found].flags == 0x01000000) { - sc->sc_iobus_space.bus_base = prange[found].base; - sc->sc_iobus_space.bus_size = prange[found].size; + if (prange[found].cspace == 0x01000000) { + sc->sc_iobus_space.bus_base = prange[found].phys_lo; + sc->sc_iobus_space.bus_size = prange[found].size_lo; } /* the mem space ranges @@ -292,27 +298,30 @@ mpcpcibus_find_ranges_64 (struct pcibr_softc *sc, u_int32_t *range_store, * and all IO and device memory will be in * upper 2G of address space, set to * 0x80000000 - * start with segment 1 not 0, 0 is config. */ - for (i = 0; i < rangelen ; i++) { - if (prange[i].flags == 0x02000000) { + for (i = 0; i < rangelen; i++) { + if (prange[i].cspace == 0x02000000) { #ifdef DEBUG_PCI printf("\nfound mem %x %x", - prange[i].base, - prange[i].size); + prange[i].phys_lo, + prange[i].size_lo); #endif if (base != 0) { - if ((base + size) == prange[i].base) { - size += prange[i].size; + if ((base + size) == prange[i].phys_lo) { + size += prange[i].size_lo; } else { - base = prange[i].base; - size = prange[i].size; + base = prange[i].phys_lo; + size = prange[i].size_lo; } } else { - base = prange[i].base; - size = prange[i].size; + base = prange[i].phys_lo; + size = prange[i].size_lo; } + + if (sc->sc_memex) + extent_free(sc->sc_memex, prange[i].child_lo, + prange[i].size_lo, EX_NOWAIT); } } sc->sc_membus_space.bus_base = base; @@ -373,6 +382,15 @@ mpcpcibrattach(struct device *parent, struct device *self, void *aux) lcp = sc->sc_pcibr = &sc->pcibr_config; + snprintf(sc->sc_ioex_name, sizeof(sc->sc_ioex_name), + "%s pciio", sc->sc_dev.dv_xname); + sc->sc_ioex = extent_create(sc->sc_ioex_name, 0x00000000, 0xffffffff, + M_DEVBUF, NULL, 0, EX_NOWAIT | EX_FILLED); + snprintf(sc->sc_memex_name, sizeof(sc->sc_memex_name), + "%s pcimem", sc->sc_dev.dv_xname); + sc->sc_memex = extent_create(sc->sc_memex_name, 0x00000000, 0xffffffff, + M_DEVBUF, NULL, 0, EX_NOWAIT | EX_FILLED); + if (ppc_proc_is_64b) mpcpcibus_find_ranges_64 (sc, range_store, rangesize); else @@ -435,15 +453,14 @@ mpcpcibrattach(struct device *parent, struct device *self, void *aux) printf(": %s, Revision 0x%x\n", compat, mpc_cfg_read_1(lcp, MPC106_PCI_REVID)); - if ((strcmp(compat, "bandit")) != 0) - pci_addr_fixup(sc, &lcp->lc_pc, 32); - bzero(&pba, sizeof(pba)); pba.pba_dmat = &pci_bus_dma_tag; pba.pba_busname = "pci"; pba.pba_iot = &sc->sc_iobus_space; pba.pba_memt = &sc->sc_membus_space; + pba.pba_ioex = sc->sc_ioex; + pba.pba_memex = sc->sc_memex; pba.pba_pc = &lcp->lc_pc; pba.pba_domain = pci_ndomains++; pba.pba_bus = 0; diff --git a/sys/arch/macppc/pci/pci_addr_fixup.c b/sys/arch/macppc/pci/pci_addr_fixup.c deleted file mode 100644 index 74e21fda01a..00000000000 --- a/sys/arch/macppc/pci/pci_addr_fixup.c +++ /dev/null @@ -1,500 +0,0 @@ -/* $OpenBSD: pci_addr_fixup.c,v 1.11 2006/07/14 05:46:54 deraadt Exp $ */ -/* $NetBSD: pci_addr_fixup.c,v 1.7 2000/08/03 20:10:45 nathanw Exp $ */ - -/*- - * Copyright (c) 2000 UCHIYAMA Yasushi. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/malloc.h> -#include <sys/kernel.h> -#include <sys/device.h> -#include <sys/extent.h> - -#include <uvm/uvm_param.h> -#include <machine/bus.h> - -#include <dev/pci/pcireg.h> -#include <dev/pci/pcivar.h> -#include <dev/pci/pcidevs.h> - -#include <macppc/pci/pcibrvar.h> - -typedef int (*pciaddr_resource_manage_func_t)(struct pcibr_softc *, - pci_chipset_tag_t, pcitag_t, int, struct extent *, int, bus_addr_t *, - bus_size_t); -void pciaddr_resource_manage(struct pcibr_softc *, - pci_chipset_tag_t, pcitag_t, pciaddr_resource_manage_func_t); -void pciaddr_resource_reserve(struct pcibr_softc *, - pci_chipset_tag_t, pcitag_t); -void pciaddr_resource_reserve_disabled(struct pcibr_softc *, - pci_chipset_tag_t, pcitag_t); -int pciaddr_do_resource_reserve(struct pcibr_softc *, - pci_chipset_tag_t, pcitag_t, int, struct extent *, int, - bus_addr_t *, bus_size_t); -int pciaddr_do_resource_reserve_disabled(struct pcibr_softc *, - pci_chipset_tag_t, pcitag_t, int, struct extent *, int, - bus_addr_t *, bus_size_t); -void pciaddr_resource_allocate(struct pcibr_softc *, - pci_chipset_tag_t, pcitag_t); -int pciaddr_do_resource_allocate(struct pcibr_softc *, - pci_chipset_tag_t, pcitag_t, int, struct extent *, int, bus_addr_t *, - bus_size_t); -bus_addr_t pciaddr_ioaddr(u_int32_t); -void pciaddr_print_devid(pci_chipset_tag_t, pcitag_t); - -int pciaddr_device_is_agp(pci_chipset_tag_t, pcitag_t); - -void pci_device_foreach(struct pcibr_softc *sc, pci_chipset_tag_t pc, - int maxbus, - void (*func)(struct pcibr_softc *, pci_chipset_tag_t, pcitag_t)); - -#define PCIADDR_MEM_START 0x0 -#define PCIADDR_MEM_END 0xffffffff -#define PCIADDR_PORT_START 0x0 -#define PCIADDR_PORT_END 0xffff - -int pcibr_flags = 0; -#define PCIBR_VERBOSE 1 -#define PCIBR_ADDR_FIXUP 2 - -#define PCIBIOS_PRINTV(x) if (pcibr_flags & PCIBR_VERBOSE) \ - printf x - -void -pci_addr_fixup(struct pcibr_softc *sc, pci_chipset_tag_t pc, int maxbus) -{ - const char *verbose_header = - "[%s]-----------------------\n" - " device vendor product\n" - " register space address size\n" - "--------------------------------------------\n"; - const char *verbose_footer = - "--------------------------[%3d devices bogus]\n"; - - sc->extent_mem = extent_create("PCI I/O memory space", - sc->sc_membus_space.bus_base, - sc->sc_membus_space.bus_base + sc->sc_membus_space.bus_size, - M_DEVBUF, 0, 0, EX_NOWAIT); - KASSERT(sc->extent_mem); - sc->extent_port = extent_create("PCI I/O port space", - PCIADDR_PORT_START, PCIADDR_PORT_END, - M_DEVBUF, 0, 0, EX_NOWAIT); - KASSERT(sc->extent_port); - - /* - * 1. check & reserve system BIOS setting. - */ - PCIBIOS_PRINTV((verbose_header, "System BIOS Setting")); - pci_device_foreach(sc, pc, maxbus, pciaddr_resource_reserve); - pci_device_foreach(sc, pc, maxbus, pciaddr_resource_reserve_disabled); - PCIBIOS_PRINTV((verbose_footer, sc->nbogus)); - - { - struct extent_region *rp; - struct extent *ex = sc->extent_mem; - for (rp = LIST_FIRST(&ex->ex_regions); - rp; rp = LIST_NEXT(rp, er_link)) { - } - } - { - struct extent_region *rp; - struct extent *ex = sc->extent_port; - for (rp = LIST_FIRST(&ex->ex_regions); - rp; rp = LIST_NEXT(rp, er_link)) { - } - } - - /* - * 4. do fixup - */ - PCIBIOS_PRINTV((verbose_header, "PCIBIOS fixup stage")); - sc->nbogus = 0; - pci_device_foreach(sc, pc, maxbus, pciaddr_resource_allocate); - PCIBIOS_PRINTV((verbose_footer, sc->nbogus)); - -} - -void -pciaddr_resource_reserve(struct pcibr_softc *sc, pci_chipset_tag_t pc, - pcitag_t tag) -{ - if (pcibr_flags & PCIBR_VERBOSE) - pciaddr_print_devid(pc, tag); - pciaddr_resource_manage(sc, pc, tag, pciaddr_do_resource_reserve); -} - -void -pciaddr_resource_reserve_disabled(struct pcibr_softc *sc, - pci_chipset_tag_t pc, pcitag_t tag) -{ - if (pcibr_flags & PCIBR_VERBOSE) - pciaddr_print_devid(pc, tag); - pciaddr_resource_manage(sc, pc, tag, - pciaddr_do_resource_reserve_disabled); -} - -void -pciaddr_resource_allocate(struct pcibr_softc *sc, pci_chipset_tag_t pc, - pcitag_t tag) -{ - if (pcibr_flags & PCIBR_VERBOSE) - pciaddr_print_devid(pc, tag); - pciaddr_resource_manage(sc, pc, tag, pciaddr_do_resource_allocate); -} - -void -pciaddr_resource_manage(struct pcibr_softc *sc, pci_chipset_tag_t pc, - pcitag_t tag, pciaddr_resource_manage_func_t func) -{ - struct extent *ex; - pcireg_t val, mask; - bus_addr_t addr; - bus_size_t size; - int error, mapreg, type, reg_start, reg_end, width; - - val = pci_conf_read(pc, tag, PCI_BHLC_REG); - switch (PCI_HDRTYPE_TYPE(val)) { - default: - printf("WARNING: unknown PCI device header.\n"); - sc->nbogus++; - return; - case 0: - reg_start = PCI_MAPREG_START; - reg_end = PCI_MAPREG_END; - break; - case 1: /* PCI-PCI bridge */ - reg_start = PCI_MAPREG_START; - reg_end = PCI_MAPREG_PPB_END; - break; - case 2: /* PCI-CardBus bridge */ - reg_start = PCI_MAPREG_START; - reg_end = PCI_MAPREG_PCB_END; - break; - } - error = 0; - - for (mapreg = reg_start; mapreg < reg_end; mapreg += width) { - /* inquire PCI device bus space requirement */ - val = pci_conf_read(pc, tag, mapreg); - pci_conf_write(pc, tag, mapreg, ~0); - - mask = pci_conf_read(pc, tag, mapreg); - pci_conf_write(pc, tag, mapreg, val); - - type = PCI_MAPREG_TYPE(val); - width = 4; - if (type == PCI_MAPREG_TYPE_MEM) { - if (PCI_MAPREG_MEM_TYPE(val) == - PCI_MAPREG_MEM_TYPE_64BIT) { - /* XXX We could examine the upper 32 bits - * XXX of the BAR here, but we are totally - * XXX unprepared to handle a non-zero value, - * XXX either here or anywhere else in - * XXX i386-land. - * XXX So just arrange to not look at the - * XXX upper 32 bits, lest we misinterpret - * XXX it as a 32-bit BAR set to zero. - */ - width = 8; - } - addr = PCI_MAPREG_MEM_ADDR(val); - size = PCI_MAPREG_MEM_SIZE(mask); - ex = sc->extent_mem; - } else { - /* XXX some devices give 32bit value */ - addr = PCI_MAPREG_IO_ADDR(val) & PCIADDR_PORT_END; - size = PCI_MAPREG_IO_SIZE(mask); - ex = sc->extent_port; - } - - if (!size) /* unused register */ - continue; - - /* reservation/allocation phase */ - error += (*func) (sc, pc, tag, mapreg, ex, type, &addr, size); - - PCIBIOS_PRINTV(("\t%02xh %s 0x%08x 0x%08x\n", - mapreg, type ? "port" : "mem ", - (unsigned int)addr, (unsigned int)size)); - } - - if (error) - sc->nbogus++; - - PCIBIOS_PRINTV(("\t\t[%s]\n", error ? "NG" : "OK")); -} - -int -pciaddr_do_resource_allocate(struct pcibr_softc *sc, pci_chipset_tag_t pc, - pcitag_t tag, int mapreg, struct extent *ex, int type, bus_addr_t *addr, - bus_size_t size) -{ - bus_addr_t start; - int error; - - if (*addr) /* no need to allocate */ - return (0); - - /* XXX Don't allocate if device is AGP device to avoid conflict. */ - if (pciaddr_device_is_agp(pc, tag)) - return (0); - - start = (type == PCI_MAPREG_TYPE_MEM ? sc->sc_membus_space.bus_base - : PCIADDR_PORT_START); - if (start < ex->ex_start || start + size - 1 >= ex->ex_end) { - PCIBIOS_PRINTV(("No available resources. fixup failed\n")); - return (1); - } - error = extent_alloc_subregion(ex, start, ex->ex_end, size, size, 0, 0, - EX_FAST|EX_NOWAIT|EX_MALLOCOK, addr); - if (error) { - PCIBIOS_PRINTV(("No available resources. fixup failed\n")); - return (1); - } - - /* write new address to PCI device configuration header */ - pci_conf_write(pc, tag, mapreg, *addr); - /* check */ - if (pcibr_flags & PCIBR_VERBOSE) { - printf("pci_addr_fixup: "); - pciaddr_print_devid(pc, tag); - } - - if (pciaddr_ioaddr(pci_conf_read(pc, tag, mapreg)) != *addr) { - pci_conf_write(pc, tag, mapreg, 0); /* clear */ - printf("fixup failed. (new address=%#lx)\n", *addr); - return (1); - } - if (pcibr_flags & PCIBR_VERBOSE) - printf("new address 0x%08lx\n", *addr); - - return (0); -} - -int -pciaddr_do_resource_reserve(struct pcibr_softc *sc, pci_chipset_tag_t pc, - pcitag_t tag, int mapreg, struct extent *ex, int type, bus_addr_t *addr, - bus_size_t size) -{ - pcireg_t val; - int error; - - if (*addr == 0) - return (0); - - val = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); - if (type == PCI_MAPREG_TYPE_MEM && - (val & PCI_COMMAND_MEM_ENABLE) != PCI_COMMAND_MEM_ENABLE) - return (0); - if (type == PCI_MAPREG_TYPE_IO && - (val & PCI_COMMAND_IO_ENABLE) != PCI_COMMAND_IO_ENABLE) - return (0); - - error = extent_alloc_region(ex, *addr, size, EX_NOWAIT | EX_MALLOCOK); - if (error) { - PCIBIOS_PRINTV(("Resource conflict.\n")); - pci_conf_write(pc, tag, mapreg, 0); /* clear */ - return (1); - } - - return (0); -} - -int -pciaddr_do_resource_reserve_disabled(struct pcibr_softc *sc, - pci_chipset_tag_t pc, pcitag_t tag, int mapreg, struct extent *ex, - int type, bus_addr_t *addr, bus_size_t size) -{ - pcireg_t val; - int error; - - if (*addr == 0) - return (0); - - val = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); - if (type == PCI_MAPREG_TYPE_MEM && - (val & PCI_COMMAND_MEM_ENABLE) == PCI_COMMAND_MEM_ENABLE) - return (0); - if (type == PCI_MAPREG_TYPE_IO && - (val & PCI_COMMAND_IO_ENABLE) == PCI_COMMAND_IO_ENABLE) - return (0); - - error = extent_alloc_region(ex, *addr, size, EX_NOWAIT | EX_MALLOCOK); - if (error) { - PCIBIOS_PRINTV(("Resource conflict.\n")); - pci_conf_write(pc, tag, mapreg, 0); /* clear */ - return (1); - } - - return (0); -} - -bus_addr_t -pciaddr_ioaddr(u_int32_t val) -{ - return ((PCI_MAPREG_TYPE(val) == PCI_MAPREG_TYPE_MEM) - ? PCI_MAPREG_MEM_ADDR(val) - : (PCI_MAPREG_IO_ADDR(val) & PCIADDR_PORT_END)); -} - -void -pciaddr_print_devid(pci_chipset_tag_t pc, pcitag_t tag) -{ - int bus, device, function; - pcireg_t id; - - id = pci_conf_read(pc, tag, PCI_ID_REG); - pci_decompose_tag(pc, tag, &bus, &device, &function); - printf("%03d:%02d:%d %04x:%04x\n", bus, device, function, - PCI_VENDOR(id), PCI_PRODUCT(id)); -} - -int -pciaddr_device_is_agp(pci_chipset_tag_t pc, pcitag_t tag) -{ - pcireg_t class, status, rval; - int off; - - /* Check AGP device. */ - class = pci_conf_read(pc, tag, PCI_CLASS_REG); - if (PCI_CLASS(class) == PCI_CLASS_DISPLAY) { - status = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); - if (status & PCI_STATUS_CAPLIST_SUPPORT) { - rval = pci_conf_read(pc, tag, PCI_CAPLISTPTR_REG); - for (off = PCI_CAPLIST_PTR(rval); - off != 0; - off = PCI_CAPLIST_NEXT(rval) ) { - rval = pci_conf_read(pc, tag, off); - if (PCI_CAPLIST_CAP(rval) == PCI_CAP_AGP) - return (1); - } - } - } - return (0); -} - - -struct extent * -pciaddr_search(int mem_port, struct device *parent, bus_addr_t *startp, - bus_size_t size) -{ - struct pcibr_softc *sc; - - /* find the bridge, 'mpcpcibr' */ - - sc = NULL; - while (parent != NULL) { - if (strncmp("mpcpcibr", parent->dv_xname, 8) == 0) { - sc = (void *)parent; - break; - } - parent = parent->dv_parent; - } - - if (sc && !(pcibr_flags & PCIBR_ADDR_FIXUP)) { - struct extent_region *rp; - struct extent *ex = mem_port? sc->extent_mem : sc->extent_port; - - /* Search the PCI I/O memory space extent for free - * space that will accommodate size. Remember that the - * extent stores allocated space and we're searching - * for the gaps. - * - * If we're at the end or the gap between this region - * and the next region big enough, then we're done - */ - *startp = ex->ex_start; - rp = LIST_FIRST(&ex->ex_regions); - - for (rp = LIST_FIRST(&ex->ex_regions); - rp && *startp + size > rp->er_start; - rp = LIST_NEXT(rp, er_link)) { - bus_addr_t new_start; - - new_start = (rp->er_end - 1 + size) & ~(size - 1); - if (new_start > *startp) - *startp = new_start; - } - - return (ex); - } - - return (NULL); -} - - -void -pci_device_foreach(struct pcibr_softc *sc, pci_chipset_tag_t pc, int maxbus, - void (*func)(struct pcibr_softc *, pci_chipset_tag_t, pcitag_t)) -{ - const struct pci_quirkdata *qd; - int bus, device, function, maxdevs, nfuncs; - pcireg_t id, bhlcr; - pcitag_t tag; - - for (bus = 0; bus <= maxbus; bus++) { - maxdevs = pci_bus_maxdevs(pc, bus); - for (device = 0; device < maxdevs; device++) { - tag = pci_make_tag(pc, bus, device, 0); - id = pci_conf_read(pc, tag, PCI_ID_REG); - - /* Invalid vendor ID value? */ - if (PCI_VENDOR(id) == PCI_VENDOR_INVALID) - continue; - /* XXX Not invalid, but we've done this ~forever. */ - if (PCI_VENDOR(id) == 0) - continue; - - qd = pci_lookup_quirkdata(PCI_VENDOR(id), - PCI_PRODUCT(id)); - - bhlcr = pci_conf_read(pc, tag, PCI_BHLC_REG); - if (PCI_HDRTYPE_MULTIFN(bhlcr) || - (qd != NULL && - (qd->quirks & PCI_QUIRK_MULTIFUNCTION) != 0)) - nfuncs = 8; - else - nfuncs = 1; - - for (function = 0; function < nfuncs; function++) { - tag = pci_make_tag(pc, bus, device, function); - id = pci_conf_read(pc, tag, PCI_ID_REG); - - /* Invalid vendor ID value? */ - if (PCI_VENDOR(id) == PCI_VENDOR_INVALID) - continue; - /* - * XXX Not invalid, but we've done this - * ~forever. - */ - if (PCI_VENDOR(id) == 0) - continue; - (*func)(sc, pc, tag); - } - } - } -} diff --git a/sys/arch/macppc/pci/pcibrvar.h b/sys/arch/macppc/pci/pcibrvar.h index 7234c72cae2..09e2abb277e 100644 --- a/sys/arch/macppc/pci/pcibrvar.h +++ b/sys/arch/macppc/pci/pcibrvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pcibrvar.h,v 1.6 2003/06/09 16:10:04 deraadt Exp $ */ +/* $OpenBSD: pcibrvar.h,v 1.7 2009/05/03 21:30:09 kettenis Exp $ */ /* * Copyright (c) 1997 Per Fogelstrom @@ -49,24 +49,8 @@ struct pcibr_softc { struct ppc_bus_space sc_iobus_space; struct powerpc_bus_dma_tag sc_dmatag; struct pcibr_config pcibr_config; - struct extent *extent_mem; - struct extent *extent_port; - u_int32_t mem_alloc_start; - u_int32_t port_alloc_start; - int nbogus; + struct extent *sc_ioex; + struct extent *sc_memex; + char sc_ioex_name[32]; + char sc_memex_name[32]; }; - -struct pci_reserve_mem { - bus_addr_t start; - bus_size_t size; - char *name; -}; - -void pci_addr_fixup(struct pcibr_softc *, pci_chipset_tag_t, int); - -#define PCIADDR_SEARCH_IO 0 -#define PCIADDR_SEARCH_MEM 1 - - -struct extent * pciaddr_search(int mem_port, struct device *, - bus_addr_t *startp, bus_size_t size); |