diff options
author | 2013-08-07 07:29:18 +0000 | |
---|---|---|
committer | 2013-08-07 07:29:18 +0000 | |
commit | 2d3c312a12a692cbfb831efe4e45e76e67ba7989 (patch) | |
tree | b0ec206431dd1997e84ac44f5fea3302aeb73678 | |
parent | bye bye TRUST_PACKAGES (diff) | |
download | wireguard-openbsd-2d3c312a12a692cbfb831efe4e45e76e67ba7989.tar.xz wireguard-openbsd-2d3c312a12a692cbfb831efe4e45e76e67ba7989.zip |
Mimic what's done on sparc64 and parse the OpenFirmware device tree to
enumerate the pci devices. This allow us to not store the interrupt
vector in the interrupt line register and to not try to attach pci
devices disabled by firmware.
With inputs from and ok kettenis@
-rw-r--r-- | sys/arch/macppc/conf/files.macppc | 4 | ||||
-rw-r--r-- | sys/arch/macppc/include/pci_machdep.h | 108 | ||||
-rw-r--r-- | sys/arch/macppc/macppc/ofw_machdep.c | 45 | ||||
-rw-r--r-- | sys/arch/macppc/macppc/rbus_machdep.c | 25 | ||||
-rw-r--r-- | sys/arch/macppc/pci/ht.c | 232 | ||||
-rw-r--r-- | sys/arch/macppc/pci/mpcpcibus.c | 380 | ||||
-rw-r--r-- | sys/arch/macppc/pci/pci_machdep.c | 340 | ||||
-rw-r--r-- | sys/arch/socppc/include/pci_machdep.h (renamed from sys/arch/powerpc/pci/pci_machdep.h) | 2 | ||||
-rw-r--r-- | sys/dev/pci/pcivar.h | 4 |
9 files changed, 512 insertions, 628 deletions
diff --git a/sys/arch/macppc/conf/files.macppc b/sys/arch/macppc/conf/files.macppc index 9af66a523d0..5faebd00f91 100644 --- a/sys/arch/macppc/conf/files.macppc +++ b/sys/arch/macppc/conf/files.macppc @@ -1,4 +1,4 @@ -# $OpenBSD: files.macppc,v 1.70 2013/05/31 19:32:30 mpi Exp $ +# $OpenBSD: files.macppc,v 1.71 2013/08/07 07:29:18 mpi Exp $ # # macppc-specific configuration info @@ -74,6 +74,8 @@ device ht {} : pcibus attach ht at mainbus file arch/macppc/pci/ht.c ht +file arch/macppc/pci/pci_machdep.c mpcpcibr | ht + device smu: i2cbus attach smu at mainbus file arch/macppc/dev/smu.c smu diff --git a/sys/arch/macppc/include/pci_machdep.h b/sys/arch/macppc/include/pci_machdep.h new file mode 100644 index 00000000000..6d5a3f3c094 --- /dev/null +++ b/sys/arch/macppc/include/pci_machdep.h @@ -0,0 +1,108 @@ +/* $OpenBSD: pci_machdep.h,v 1.1 2013/08/07 07:29:18 mpi Exp $ */ +/* $NetBSD: pci_machdep.h,v 1.7 2001/07/20 00:07:14 eeh Exp $ */ + +/* + * Copyright (c) 1999 Matthew R. Green + * 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. + */ + +#ifndef _MACHINE_PCI_MACHDEP_H_ +#define _MACHINE_PCI_MACHDEP_H_ + +extern struct powerpc_bus_dma_tag pci_bus_dma_tag; + +/* + * Forward declarations. + */ +struct pci_attach_args; + +/* + * define some bits used to glue into the common PCI code. + */ + +typedef struct ppc_pci_chipset *pci_chipset_tag_t; + +typedef unsigned long pci_intr_handle_t; + +/* + * The stuuuuuuupid allegedly MI PCI code expects pcitag_t to be a + * scalar type. But we really need to store both the OFW node and + * the bus/device/function info in it. (We'd like to store more, + * like all the ofw properties, but we don't need to.) Luckily, + * both are 32-bit values, so we can squeeze them into a u_int64_t + * with a little help from some macros. + */ + +#define PCITAG_NODE(x) (int)(((x)>>32)&0xffffffff) +#define PCITAG_OFFSET(x) ((x)&0xffffffff) +#define PCITAG_BUS(t) ((PCITAG_OFFSET(t)>>16)&0xff) +#define PCITAG_DEV(t) ((PCITAG_OFFSET(t)>>11)&0x1f) +#define PCITAG_FUN(t) ((PCITAG_OFFSET(t)>>8)&0x7) +#define PCITAG_CREATE(n,b,d,f) (((uint64_t)(n)<<32)|((b)<<16)|((d)<<11)|((f)<<8)) +typedef uint64_t pcitag_t; + +struct ppc_pci_chipset { + void *pc_conf_v; + int pc_node; + int busnode[256]; + + pcireg_t (*pc_conf_read)(void *, pcitag_t, int); + void (*pc_conf_write)(void *, pcitag_t, int, pcireg_t); +}; + + +void pci_attach_hook(struct device *, struct device *, + struct pcibus_attach_args *); +int pci_bus_maxdevs(pci_chipset_tag_t, int); +pcitag_t pci_make_tag(pci_chipset_tag_t, int, int, int); +void pci_decompose_tag(pci_chipset_tag_t, pcitag_t, int *, int *, + int *); +int pci_conf_size(pci_chipset_tag_t, pcitag_t); +pcireg_t pci_conf_read(pci_chipset_tag_t, pcitag_t, int); +void pci_conf_write(pci_chipset_tag_t, pcitag_t, int, pcireg_t); +int pci_intr_map(struct pci_attach_args *, pci_intr_handle_t *); +int pci_intr_map_msi(struct pci_attach_args *, pci_intr_handle_t *); +int pci_intr_line(pci_chipset_tag_t, pci_intr_handle_t); +const char *pci_intr_string(pci_chipset_tag_t, pci_intr_handle_t); +void *pci_intr_establish(pci_chipset_tag_t, pci_intr_handle_t, + int, int (*)(void *), void *, const char *); +void pci_intr_disestablish(pci_chipset_tag_t, void *); +int pci_ether_hw_addr(pci_chipset_tag_t, uint8_t *); + +#define pci_probe_device_hook(c, a) (0) + +#define pci_min_powerstate(c, t) (PCI_PMCSR_STATE_D3) + +#define pci_dev_postattach(a, b) + +int ofw_intr_map(int, uint32_t *, uint32_t *); +int ofw_enumerate_pcibus(struct pci_softc *, + int (*match)(struct pci_attach_args *), + struct pci_attach_args *); + +#define PCI_MACHDEP_ENUMERATE_BUS ofw_enumerate_pcibus + +#endif /* _MACHINE_PCI_MACHDEP_H_ */ diff --git a/sys/arch/macppc/macppc/ofw_machdep.c b/sys/arch/macppc/macppc/ofw_machdep.c index eba67f69c3d..bd879bbd9a0 100644 --- a/sys/arch/macppc/macppc/ofw_machdep.c +++ b/sys/arch/macppc/macppc/ofw_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ofw_machdep.c,v 1.37 2013/01/21 11:43:41 mpi Exp $ */ +/* $OpenBSD: ofw_machdep.c,v 1.38 2013/08/07 07:29:19 mpi Exp $ */ /* $NetBSD: ofw_machdep.c,v 1.1 1996/09/30 16:34:50 ws Exp $ */ /* @@ -50,6 +50,7 @@ #include <machine/autoconf.h> #include <dev/ofw/openfirm.h> +#include <dev/ofw/ofw_pci.h> #include <macppc/macppc/ofw_machdep.h> @@ -185,29 +186,6 @@ save_ofw_mapping() #include <dev/pci/pcivar.h> #include <arch/macppc/pci/vgafb_pcivar.h> -static pcitag_t ofw_make_tag( void *cpv, int bus, int dev, int fnc); - -/* ARGSUSED */ -static pcitag_t -ofw_make_tag(void *cpv, int bus, int dev, int fnc) -{ - return (bus << 16) | (dev << 11) | (fnc << 8); -} - -#define OFW_PCI_PHYS_HI_BUSMASK 0x00ff0000 -#define OFW_PCI_PHYS_HI_BUSSHIFT 16 -#define OFW_PCI_PHYS_HI_DEVICEMASK 0x0000f800 -#define OFW_PCI_PHYS_HI_DEVICESHIFT 11 -#define OFW_PCI_PHYS_HI_FUNCTIONMASK 0x00000700 -#define OFW_PCI_PHYS_HI_FUNCTIONSHIFT 8 - -#define pcibus(x) \ - (((x) & OFW_PCI_PHYS_HI_BUSMASK) >> OFW_PCI_PHYS_HI_BUSSHIFT) -#define pcidev(x) \ - (((x) & OFW_PCI_PHYS_HI_DEVICEMASK) >> OFW_PCI_PHYS_HI_DEVICESHIFT) -#define pcifunc(x) \ - (((x) & OFW_PCI_PHYS_HI_FUNCTIONMASK) >> OFW_PCI_PHYS_HI_FUNCTIONSHIFT) - struct ppc_bus_space ppc_membus; bus_space_tag_t cons_membus = &ppc_membus; @@ -376,16 +354,12 @@ void of_display_console() { #if NVGAFB_PCI > 0 + struct ofw_pci_register addr[8]; char name[32]; int len; int stdout_node; int display_node; int err; - u_int32_t memtag, iotag; - struct { - u_int32_t phys_hi, phys_mid, phys_lo; - u_int32_t size_hi, size_lo; - } addr [8]; stdout_node = OF_instance_to_package(OF_stdout); len = OF_getprop(stdout_node, "name", name, 20); @@ -433,25 +407,20 @@ of_display_console() if (OF_getnodebyname(0, "backlight") != 0) cons_backlight_available = 1; - memtag = ofw_make_tag(NULL, pcibus(addr[0].phys_hi), - pcidev(addr[0].phys_hi), - pcifunc(addr[0].phys_hi)); - iotag = ofw_make_tag(NULL, pcibus(addr[1].phys_hi), - pcidev(addr[1].phys_hi), - pcifunc(addr[1].phys_hi)); + vgafb_pci_console_tag = PCITAG_CREATE(display_node, + OFW_PCI_PHYS_HI_BUS(addr[1].phys_hi), + OFW_PCI_PHYS_HI_DEVICE(addr[1].phys_hi), + OFW_PCI_PHYS_HI_FUNCTION(addr[1].phys_hi)); #if 1 printf(": memaddr %x size %x, ", addr[0].phys_lo, addr[0].size_lo); printf(": consaddr %x, ", cons_addr); printf(": ioaddr %x, size %x", addr[1].phys_lo, addr[1].size_lo); - printf(": memtag %x, iotag %x", memtag, iotag); printf(": width %d linebytes %d height %d depth %d\n", cons_width, cons_linebytes, cons_height, cons_depth); #endif cons_membus->bus_base = 0x80000000; - vgafb_pci_console_tag = iotag; - vgafb_cnattach(cons_membus, cons_membus, -1, 0); if (cons_backlight_available == 1) diff --git a/sys/arch/macppc/macppc/rbus_machdep.c b/sys/arch/macppc/macppc/rbus_machdep.c index 54adbfd6bea..b6dc352fdc0 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.12 2013/01/21 11:45:43 mpi Exp $ */ +/* $OpenBSD: rbus_machdep.c,v 1.13 2013/08/07 07:29:19 mpi Exp $ */ /* $NetBSD: rbus_machdep.c,v 1.2 1999/10/15 06:43:06 haya Exp $ */ /* @@ -28,20 +28,15 @@ #include <sys/param.h> #include <sys/systm.h> -#include <sys/extent.h> -#include <sys/proc.h> -#include <sys/sysctl.h> -#include <sys/device.h> - -#include <uvm/uvm_extern.h> #include <machine/bus.h> #include <dev/cardbus/rbus.h> -#include <dev/pci/pcireg.h> #include <dev/pci/pcivar.h> #include <dev/pci/pcidevs.h> +#include <dev/ofw/openfirm.h> + void macppc_cardbus_init(pci_chipset_tag_t pc, pcitag_t tag); rbus_tag_t @@ -113,4 +108,18 @@ void pccbb_attach_hook(struct device *parent, struct device *self, struct pci_attach_args *pa) { + pci_chipset_tag_t pc = pa->pa_pc; + int node = PCITAG_NODE(pa->pa_tag); + int bus, busrange[2]; + + if (OF_getprop(OF_parent(node), "bus-range", &busrange, + sizeof(busrange)) != sizeof(busrange)) + return; + + bus = busrange[0] + 1; + while (bus < 256 && pc->busnode[bus]) + bus++; + if (bus == 256) + return; + pc->busnode[bus] = node; } diff --git a/sys/arch/macppc/pci/ht.c b/sys/arch/macppc/pci/ht.c index 1de294a49cb..38e6012e929 100644 --- a/sys/arch/macppc/pci/ht.c +++ b/sys/arch/macppc/pci/ht.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ht.c,v 1.15 2013/01/21 15:06:29 mpi Exp $ */ +/* $OpenBSD: ht.c,v 1.16 2013/08/07 07:29:19 mpi Exp $ */ /* * Copyright (c) 2005 Mark Kettenis @@ -32,29 +32,11 @@ int ht_match(struct device *, void *, void *); void ht_attach(struct device *, struct device *, void *); -void ht_attach_hook(struct device *, struct device *, - struct pcibus_attach_args *); -int ht_bus_maxdevs(void *, int); -pcitag_t ht_make_tag(void *, int, int, int); -void ht_decompose_tag(void *, pcitag_t, int *, int *, int *); -int ht_conf_size(void *, pcitag_t); pcireg_t ht_conf_read(void *, pcitag_t, int); void ht_conf_write(void *, pcitag_t, int, pcireg_t); -int ht_intr_map(void *, pcitag_t, int, int, pci_intr_handle_t *); -const char *ht_intr_string(void *, pci_intr_handle_t); -int ht_intr_line(void *, pci_intr_handle_t); -void *ht_intr_establish(void *, pci_intr_handle_t, int, int (*)(void *), - void *, const char *); -void ht_intr_disestablish(void *, void *); - -int ht_ether_hw_addr(struct ppc_pci_chipset *, u_int8_t *); int ht_print(void *, const char *); -#define BUS_SHIFT 16 -#define DEVICE_SHIFT 11 -#define FNC_SHIFT 8 - struct ht_softc { struct device sc_dev; int sc_maxdevs; @@ -76,27 +58,6 @@ struct cfdriver ht_cd = { NULL, "ht", DV_DULL, }; -#if 0 -struct powerpc_bus_dma_tag pci_bus_dma_tag = { - NULL, - _dmamap_create, - _dmamap_destroy, - _dmamap_load, - _dmamap_load_mbuf, - _dmamap_load_uio, - _dmamap_load_raw, - _dmamap_unload, - _dmamap_sync, - _dmamem_alloc, - _dmamem_free, - _dmamem_map, - _dmamem_unmap, - _dmamem_mmap -}; -#else -extern struct powerpc_bus_dma_tag pci_bus_dma_tag; -#endif - int ht_match(struct device *parent, void *cf, void *aux) { @@ -115,8 +76,7 @@ ht_attach(struct device *parent, struct device *self, void *aux) struct pcibus_attach_args pba; u_int32_t regs[6]; char compat[32]; - int node, nn; - int len; + int node, len; if (ca->ca_node == 0) { printf(": invalid node on ht config\n"); @@ -144,7 +104,7 @@ ht_attach(struct device *parent, struct device *self, void *aux) sc->sc_maxdevs++; if (bus_space_map(sc->sc_memt, regs[1], - (1 << DEVICE_SHIFT)*sc->sc_maxdevs, 0, &sc->sc_config0_memh)) { + (1 << 11)*sc->sc_maxdevs, 0, &sc->sc_config0_memh)) { printf(": can't map PCI config0 memory\n"); return; } @@ -168,22 +128,10 @@ ht_attach(struct device *parent, struct device *self, void *aux) printf(": %s", compat); sc->sc_pc.pc_conf_v = sc; - sc->sc_pc.pc_attach_hook = ht_attach_hook; - sc->sc_pc.pc_bus_maxdevs = ht_bus_maxdevs; - sc->sc_pc.pc_make_tag = ht_make_tag; - sc->sc_pc.pc_decompose_tag = ht_decompose_tag; - sc->sc_pc.pc_conf_size = ht_conf_size; + sc->sc_pc.pc_node = ca->ca_node; sc->sc_pc.pc_conf_read = ht_conf_read; sc->sc_pc.pc_conf_write = ht_conf_write; - sc->sc_pc.pc_intr_v = sc; - sc->sc_pc.pc_intr_map = ht_intr_map; - sc->sc_pc.pc_intr_string = ht_intr_string; - sc->sc_pc.pc_intr_line = ht_intr_line; - sc->sc_pc.pc_intr_establish = ht_intr_establish; - sc->sc_pc.pc_intr_disestablish = ht_intr_disestablish; - sc->sc_pc.pc_ether_hw_addr = ht_ether_hw_addr; - bzero(&pba, sizeof(pba)); pba.pba_busname = "pci"; pba.pba_iot = sc->sc_iot; @@ -195,90 +143,35 @@ ht_attach(struct device *parent, struct device *self, void *aux) printf(", %d devices\n", sc->sc_maxdevs); - extern void fix_node_irq(int, struct pcibus_attach_args *); - - for (node = OF_child(ca->ca_node); node; node = nn) { - fix_node_irq(node, &pba); - - if ((nn = OF_child(node)) != 0) - continue; - - while ((nn = OF_peer(node)) == 0) { - node = OF_parent(node); - if (node == ca->ca_node) { - nn = 0; - break; - } - } - } - config_found(self, &pba, ht_print); } -void -ht_attach_hook(struct device *parent, struct device *self, - struct pcibus_attach_args *pba) -{ -} - -int -ht_bus_maxdevs(void *cpv, int bus) -{ - struct ht_softc *sc = cpv; - - /* XXX Probing more busses doesn't work. */ - if (bus == 0) - return sc->sc_maxdevs; - return 32; -} - -pcitag_t -ht_make_tag(void *cpv, int bus, int dev, int fnc) -{ - return (bus << BUS_SHIFT) | (dev << DEVICE_SHIFT) | (fnc << FNC_SHIFT); -} - -void -ht_decompose_tag(void *cpv, pcitag_t tag, int *busp, int *devp, int *fncp) -{ - if (busp != NULL) - *busp = (tag >> BUS_SHIFT) & 0xff; - if (devp != NULL) - *devp = (tag >> DEVICE_SHIFT) & 0x1f; - if (fncp != NULL) - *fncp = (tag >> FNC_SHIFT) & 0x7; -} - -int -ht_conf_size(void *cpv, pcitag_t tag) -{ - return PCI_CONFIG_SPACE_SIZE; -} - pcireg_t ht_conf_read(void *cpv, pcitag_t tag, int offset) { struct ht_softc *sc = cpv; int bus, dev, fcn; pcireg_t reg; + uint32_t val; + val = PCITAG_OFFSET(tag); #ifdef DEBUG - printf("ht_conf_read: tag=%x, offset=%x\n", tag, offset); + printf("ht_conf_read: tag=%x, offset=%x\n", val, offset); #endif - ht_decompose_tag(NULL, tag, &bus, &dev, &fcn); + pci_decompose_tag(NULL, tag, &bus, &dev, &fcn); if (bus == 0 && dev == 0) { - tag |= (offset << 2); - reg = bus_space_read_4(sc->sc_iot, sc->sc_config0_ioh, tag); + val |= (offset << 2); + reg = bus_space_read_4(sc->sc_iot, sc->sc_config0_ioh, val); reg = letoh32(reg); } else if (bus == 0) { /* XXX Why can we only access function 0? */ if (fcn > 0) return ~0; - tag |= offset; - reg = bus_space_read_4(sc->sc_memt, sc->sc_config0_memh, tag); + val |= offset; + reg = bus_space_read_4(sc->sc_memt, sc->sc_config0_memh, val); } else { - tag |= offset; - reg = bus_space_read_4(sc->sc_memt, sc->sc_config1_memh, tag); + val |= offset; + reg = bus_space_read_4(sc->sc_memt, sc->sc_config1_memh, val); } #ifdef DEBUG printf("ht_conf_read: reg=%x\n", reg); @@ -291,104 +184,33 @@ ht_conf_write(void *cpv, pcitag_t tag, int offset, pcireg_t data) { struct ht_softc *sc = cpv; int bus, dev, fcn; + uint32_t val; + val = PCITAG_OFFSET(tag); #ifdef DEBUG printf("ht_conf_write: tag=%x, offset=%x, data = %x\n", - tag, offset, data); + val, offset, data); #endif - ht_decompose_tag(NULL, tag, &bus, &dev, &fcn); + pci_decompose_tag(NULL, tag, &bus, &dev, &fcn); if (bus == 0 && dev == 0) { - tag |= (offset << 2); + val |= (offset << 2); data = htole32(data); - bus_space_write_4(sc->sc_iot, sc->sc_config0_ioh, tag, data); - bus_space_read_4(sc->sc_iot, sc->sc_config0_ioh, tag); + bus_space_write_4(sc->sc_iot, sc->sc_config0_ioh, val, data); + bus_space_read_4(sc->sc_iot, sc->sc_config0_ioh, val); } else if (bus == 0) { /* XXX Why can we only access function 0? */ if (fcn > 0) return; - tag |= offset; - bus_space_write_4(sc->sc_memt, sc->sc_config0_memh, tag, data); - bus_space_read_4(sc->sc_memt, sc->sc_config0_memh, tag); + val |= offset; + bus_space_write_4(sc->sc_memt, sc->sc_config0_memh, val, data); + bus_space_read_4(sc->sc_memt, sc->sc_config0_memh, val); } else { - tag |= offset; - bus_space_write_4(sc->sc_memt, sc->sc_config1_memh, tag, data); - bus_space_read_4(sc->sc_memt, sc->sc_config1_memh, tag); + val |= offset; + bus_space_write_4(sc->sc_memt, sc->sc_config1_memh, val, data); + bus_space_read_4(sc->sc_memt, sc->sc_config1_memh, val); } } -/* XXX */ -#define PCI_INTERRUPT_NO_CONNECTION 0xff - -int -ht_intr_map(void *cpv, pcitag_t tag, int pin, int line, - pci_intr_handle_t *ihp) -{ - int error = 0; - -#ifdef DEBUG - printf("ht_intr_map: tag=%x, pin=%d, line=%d\n", tag, pin, line); -#endif - - *ihp = -1; - if (line == PCI_INTERRUPT_NO_CONNECTION) - error = 1; /* No IRQ used. */ - else if (pin > PCI_INTERRUPT_PIN_MAX) { - printf("ht_intr_map: bad interrupt pin %d\n", pin); - error = 1; - } - - if (!error) - *ihp = line; - return error; -} - -const char * -ht_intr_string(void *cpv, pci_intr_handle_t ih) -{ - static char str[16]; - - snprintf(str, sizeof str, "irq %ld", ih); - return (str); -} - -int -ht_intr_line(void *cpv, pci_intr_handle_t ih) -{ - return (ih); -} - -void * -ht_intr_establish(void *cpv, pci_intr_handle_t ih, int level, - int (*func)(void *), void *arg, const char *name) -{ - return (*intr_establish_func)(cpv, ih, IST_LEVEL, level, func, arg, - name); -} - -void -ht_intr_disestablish(void *lcv, void *cookie) -{ -} - -int -ht_ether_hw_addr(struct ppc_pci_chipset *lcpc, u_int8_t *oaddr) -{ - u_int8_t laddr[6]; - int node; - int len; - - node = OF_finddevice("enet"); - len = OF_getprop(node, "local-mac-address", laddr, sizeof(laddr)); - if (sizeof(laddr) == len) { - memcpy(oaddr, laddr, sizeof(laddr)); - return 1; - } - - oaddr[0] = oaddr[1] = oaddr[2] = 0xff; - oaddr[3] = oaddr[4] = oaddr[5] = 0xff; - return 0; -} - int ht_print(void *aux, const char *pnp) { diff --git a/sys/arch/macppc/pci/mpcpcibus.c b/sys/arch/macppc/pci/mpcpcibus.c index ab4ff0bf772..e117270c3cc 100644 --- a/sys/arch/macppc/pci/mpcpcibus.c +++ b/sys/arch/macppc/pci/mpcpcibus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mpcpcibus.c,v 1.45 2013/01/21 15:06:29 mpi Exp $ */ +/* $OpenBSD: mpcpcibus.c,v 1.46 2013/08/07 07:29:19 mpi Exp $ */ /* * Copyright (c) 1997 Per Fogelstrom @@ -26,11 +26,6 @@ * */ -/* - * Generic PCI BUS Bridge driver. - * specialized hooks for different config methods. - */ - #include <sys/param.h> #include <sys/systm.h> #include <sys/device.h> @@ -49,27 +44,10 @@ int mpcpcibrmatch(struct device *, void *, void *); void mpcpcibrattach(struct device *, struct device *, void *); -void mpc_attach_hook(struct device *, struct device *, - struct pcibus_attach_args *); -int mpc_bus_maxdevs(void *, int); -pcitag_t mpc_make_tag(void *, int, int, int); -void mpc_decompose_tag(void *, pcitag_t, int *, int *, int *); -int mpc_conf_size(void *, pcitag_t); pcireg_t mpc_conf_read(void *, pcitag_t, int); void mpc_conf_write(void *, pcitag_t, int, pcireg_t); -int mpc_intr_map(void *, pcitag_t, int, int, pci_intr_handle_t *); -const char *mpc_intr_string(void *, pci_intr_handle_t); -int mpc_intr_line(void *, pci_intr_handle_t); -void *mpc_intr_establish(void *, pci_intr_handle_t, - int, int (*func)(void *), void *, const char *); -void mpc_intr_disestablish(void *, void *); -int mpc_ether_hw_addr(struct ppc_pci_chipset *, u_int8_t *); u_int32_t mpc_gen_config_reg(void *cpv, pcitag_t tag, int offset); -int of_ether_hw_addr(struct ppc_pci_chipset *, u_int8_t *); -int find_node_intr (int parent, u_int32_t *addr, u_int32_t *intr); - -void fix_node_irq(int node, struct pcibus_attach_args *pba); struct pcibr_config { bus_space_tag_t lc_memt; @@ -78,8 +56,6 @@ struct pcibr_config { bus_space_handle_t ioh_cfc; struct ppc_pci_chipset lc_pc; int config_type; - int bus; - int node; }; struct pcibr_softc { @@ -132,23 +108,6 @@ struct config_type config_offsets[] = { {NULL, 0x00000000, 0x00000000, 0 }, }; -struct powerpc_bus_dma_tag pci_bus_dma_tag = { - NULL, - _dmamap_create, - _dmamap_destroy, - _dmamap_load, - _dmamap_load_mbuf, - _dmamap_load_uio, - _dmamap_load_raw, - _dmamap_unload, - _dmamap_sync, - _dmamem_alloc, - _dmamem_free, - _dmamem_map, - _dmamem_unmap, - _dmamem_mmap -}; - int mpcpcibrmatch(struct device *parent, void *match, void *aux) { @@ -319,7 +278,6 @@ mpcpcibus_find_ranges_64(struct pcibr_softc *sc, u_int32_t *range_store, prange[i].phys_lo, prange[i].size_lo); #endif - if (base != 0) { if ((base + size) == prange[i].phys_lo) { size += prange[i].size_lo; @@ -348,7 +306,6 @@ mpcpcibrattach(struct device *parent, struct device *self, void *aux) struct confargs *ca = aux; struct pcibr_config *lcp; struct pcibus_attach_args pba; - int node; int of_node = 0; char compat[32]; u_int32_t addr_offset; @@ -444,26 +401,13 @@ mpcpcibrattach(struct device *parent, struct device *self, void *aux) of_node = ca->ca_node; - lcp->node = ca->ca_node; lcp->lc_pc.pc_conf_v = lcp; - lcp->lc_pc.pc_attach_hook = mpc_attach_hook; - lcp->lc_pc.pc_bus_maxdevs = mpc_bus_maxdevs; - lcp->lc_pc.pc_make_tag = mpc_make_tag; - lcp->lc_pc.pc_decompose_tag = mpc_decompose_tag; - lcp->lc_pc.pc_conf_size = mpc_conf_size; + lcp->lc_pc.pc_node = ca->ca_node; lcp->lc_pc.pc_conf_read = mpc_conf_read; lcp->lc_pc.pc_conf_write = mpc_conf_write; - lcp->lc_pc.pc_ether_hw_addr = of_ether_hw_addr; lcp->lc_iot = &sc->sc_iobus_space; lcp->lc_memt = &sc->sc_membus_space; - lcp->lc_pc.pc_intr_v = lcp; - lcp->lc_pc.pc_intr_map = mpc_intr_map; - lcp->lc_pc.pc_intr_string = mpc_intr_string; - lcp->lc_pc.pc_intr_line = mpc_intr_line; - lcp->lc_pc.pc_intr_establish = mpc_intr_establish; - lcp->lc_pc.pc_intr_disestablish = mpc_intr_disestablish; - printf(": %s\n", compat); bzero(&pba, sizeof(pba)); @@ -478,178 +422,7 @@ mpcpcibrattach(struct device *parent, struct device *self, void *aux) pba.pba_domain = pci_ndomains++; pba.pba_bus = 0; - /* we want to check pci irq settings */ - if (of_node != 0) { - int nn; - - for (node = OF_child(of_node); node; node = nn) { - char name[32]; - int len; - len = OF_getprop(node, "name", name, - sizeof(name)); - name[len] = 0; - fix_node_irq(node, &pba); - - /* iterate section */ - if ((nn = OF_child(node)) != 0) - continue; - - while ((nn = OF_peer(node)) == 0) { - node = OF_parent(node); - if (node == of_node) { - nn = 0; /* done */ - break; - } - } - } - } - config_found(self, &pba, mpcpcibrprint); - -} - -#define OFW_PCI_PHYS_HI_BUSMASK 0x00ff0000 -#define OFW_PCI_PHYS_HI_BUSSHIFT 16 -#define OFW_PCI_PHYS_HI_DEVICEMASK 0x0000f800 -#define OFW_PCI_PHYS_HI_DEVICESHIFT 11 -#define OFW_PCI_PHYS_HI_FUNCTIONMASK 0x00000700 -#define OFW_PCI_PHYS_HI_FUNCTIONSHIFT 8 - -#define pcibus(x) \ - (((x) & OFW_PCI_PHYS_HI_BUSMASK) >> OFW_PCI_PHYS_HI_BUSSHIFT) -#define pcidev(x) \ - (((x) & OFW_PCI_PHYS_HI_DEVICEMASK) >> OFW_PCI_PHYS_HI_DEVICESHIFT) -#define pcifunc(x) \ - (((x) & OFW_PCI_PHYS_HI_FUNCTIONMASK) >> OFW_PCI_PHYS_HI_FUNCTIONSHIFT) - -/* - * Find PCI IRQ from OF. - */ -int -find_node_intr(int parent, u_int32_t *addr, u_int32_t *intr) -{ - int iparent, len, mlen, alen, ilen; - int match, i, step; - u_int32_t map[144], *mp, *mp1; - u_int32_t cpu_imask[8], maskedaddr[8]; - u_int32_t address_cells, interrupt_cells, mask_cells; - - len = OF_getprop(parent, "interrupt-map", map, sizeof(map)); - mlen = OF_getprop(parent, "interrupt-map-mask", cpu_imask, sizeof(cpu_imask)); - alen = OF_getprop(parent, "#address-cells", - &address_cells, sizeof(address_cells)); - ilen = OF_getprop(parent, "#interrupt-cells", - &interrupt_cells, sizeof(interrupt_cells)); - - if (len == -1 || mlen == -1 || alen == -1 || ilen == -1) - goto nomap; - - mask_cells = address_cells + interrupt_cells; - if (mask_cells != (mlen / sizeof(u_int32_t))) - goto nomap; - for (i = 0; i < mask_cells; i++) - maskedaddr[i] = addr[i] & cpu_imask[i]; - - /* interrupt-map is formatted as follows - * int * #address-cells, int * #interrupt-cells, int, int, int - * eg - * address-cells = 3 - * interrupt-cells = 1 - * 00001000 00000000 00000000 00000000 ff911258 00000034 00000001 - * 00001800 00000000 00000000 00000000 ff911258 00000035 00000001 - * 00002000 00000000 00000000 00000000 ff911258 00000036 00000001 - * | address cells | | intr | |parent| | irq | |edge/level| - * | cells| | interrupt cells | - * | of parent | - * or at least something close to that. - */ - - mp = map; - while (len > mlen) { - mp1 = mp + mask_cells; - - iparent = *mp1; - alen = OF_getprop(iparent, "#address-cells", - &address_cells, sizeof(address_cells)); - if (alen == -1) - address_cells = 0; - ilen = OF_getprop(iparent, "#interrupt-cells", - &interrupt_cells, sizeof(interrupt_cells)); - if (ilen == -1) - goto nomap; - - step = mask_cells + 1 + address_cells + interrupt_cells; - - match = bcmp(maskedaddr, mp, mlen); - if (match == 0) { - if (OF_getprop(iparent, "interrupt-controller", - NULL, 0) == 0) { - *intr = mp1[1]; - return 1; - } - /* Recurse with new 'addr'. */ - return find_node_intr(iparent, &mp1[1], intr); - } - len -= step * sizeof(u_int32_t); - mp += step; - } -nomap: - return -1; -} - -void -fix_node_irq(int node, struct pcibus_attach_args *pba) -{ - struct { - u_int32_t phys_hi, phys_mid, phys_lo; - u_int32_t size_hi, size_lo; - } addr [8]; - u_int32_t map[144]; - int len; - pcitag_t tag; - u_int32_t irq; - u_int32_t intr; - int parent; - - pci_chipset_tag_t pc = pba->pba_pc; - - len = OF_getprop(node, "assigned-addresses", addr, sizeof(addr)); - if (len == -1 || len < sizeof(addr[0])) - return; - - /* if this node has a AAPL,interrupts property, firmware - * has initialized the register correctly. - */ - len = OF_getprop(node, "AAPL,interrupts", &intr, 4); - if (len != 4) { - - parent = OF_parent(node); - - irq = -1; - - /* we want the first interrupt, set size_hi to 1 */ - addr[0].size_hi = 1; - if (find_node_intr(parent, &addr[0].phys_hi, &irq) == -1) { - len = OF_getprop(node, "interrupts", map, - sizeof(map)); - if (len != -1 && len != 4) { - irq = map[0]; - } else - return; - } - } else - irq = intr; - /* program the interrupt line register with the value - * found in openfirmware - */ - - tag = pci_make_tag(pc, pcibus(addr[0].phys_hi), - pcidev(addr[0].phys_hi), pcifunc(addr[0].phys_hi)); - - intr = pci_conf_read(pc, tag, PCI_INTERRUPT_REG); - intr &= ~PCI_INTERRUPT_LINE_MASK; - intr |= irq & PCI_INTERRUPT_LINE_MASK; - pci_conf_write(pc, tag, PCI_INTERRUPT_REG, intr); } static int @@ -663,92 +436,14 @@ mpcpcibrprint(void *aux, const char *pnp) return(UNCONF); } -void -mpc_attach_hook(struct device *parent, struct device *self, - struct pcibus_attach_args *pba) -{ -} - -int -of_ether_hw_addr(struct ppc_pci_chipset *lcpc, u_int8_t *oaddr) -{ - u_int8_t laddr[6]; - struct pcibr_config *lcp = lcpc->pc_conf_v; - int of_node = lcp->node; - int node, nn; - for (node = OF_child(of_node); node; node = nn) { - char name[32]; - int len; - len = OF_getprop(node, "name", name, - sizeof(name)); - name[len] = 0; - - len = OF_getprop(node, "local-mac-address", laddr, - sizeof laddr); - if (sizeof (laddr) == len) { - bcopy (laddr, oaddr, sizeof laddr); - return 1; - } - - /* iterate section */ - if ((nn = OF_child(node)) != 0) { - continue; - } - while ((nn = OF_peer(node)) == 0) { - node = OF_parent(node); - if (node == of_node) { - nn = 0; /* done */ - break; - } - } - } - oaddr[0] = oaddr[1] = oaddr[2] = 0xff; - oaddr[3] = oaddr[4] = oaddr[5] = 0xff; - return 0; -} - -int -mpc_ether_hw_addr(struct ppc_pci_chipset *p, u_int8_t *s) -{ - printf("mpc_ether_hw_addr not supported\n"); - return(0); -} - -int -mpc_bus_maxdevs(void *cpv, int busno) -{ - return(32); -} - -#define BUS_SHIFT 16 -#define DEVICE_SHIFT 11 -#define FNC_SHIFT 8 - -pcitag_t -mpc_make_tag(void *cpv, int bus, int dev, int fnc) -{ - return (bus << BUS_SHIFT) | (dev << DEVICE_SHIFT) | (fnc << FNC_SHIFT); -} - -void -mpc_decompose_tag(void *cpv, pcitag_t tag, int *busp, int *devp, int *fncp) -{ - if (busp != NULL) - *busp = (tag >> BUS_SHIFT) & 0xff; - if (devp != NULL) - *devp = (tag >> DEVICE_SHIFT) & 0x1f; - if (fncp != NULL) - *fncp = (tag >> FNC_SHIFT) & 0x7; -} - u_int32_t mpc_gen_config_reg(void *cpv, pcitag_t tag, int offset) { struct pcibr_config *cp = cpv; unsigned int bus, dev, fcn; - u_int32_t reg; + u_int32_t reg, val = PCITAG_OFFSET(tag); - mpc_decompose_tag(cpv, tag, &bus, &dev, &fcn); + pci_decompose_tag(cpv, tag, &bus, &dev, &fcn); if (cp->config_type & 1) { /* Config Mechanism #2 */ @@ -762,31 +457,24 @@ mpc_gen_config_reg(void *cpv, pcitag_t tag, int offset) * that 11-15 is reserved. */ reg = 1 << (dev) | fcn << 8 | offset; - } else { if (dev > 15) return 0xffffffff; /* * config type 1 */ - reg = tag | offset | 1; + reg = val | offset | 1; } } else { /* config mechanism #2, type 0 * standard cf8/cfc config */ - reg = 0x80000000 | tag | offset; + reg = 0x80000000 | val | offset; } return reg; } -int -mpc_conf_size(void *cpv, pcitag_t tag) -{ - return PCI_CONFIG_SPACE_SIZE; -} - /* #define DEBUG_CONFIG */ pcireg_t mpc_conf_read(void *cpv, pcitag_t tag, int offset) @@ -837,7 +525,7 @@ mpc_conf_read(void *cpv, pcitag_t tag, int offset) #ifdef DEBUG_CONFIG if (!((offset == 0) && (data == 0xffffffff))) { unsigned int bus, dev, fcn; - mpc_decompose_tag(cpv, tag, &bus, &dev, &fcn); + pci_decompose_tag(cpv, tag, &bus, &dev, &fcn); printf("mpc_conf_read bus %x dev %x fcn %x offset %x", bus, dev, fcn, offset); printf(" daddr %x reg %x",daddr, reg); @@ -868,7 +556,7 @@ mpc_conf_write(void *cpv, pcitag_t tag, int offset, pcireg_t data) #ifdef DEBUG_CONFIG { unsigned int bus, dev, fcn; - mpc_decompose_tag(cpv, tag, &bus, &dev, &fcn); + pci_decompose_tag(cpv, tag, &bus, &dev, &fcn); printf("mpc_conf_write bus %x dev %x fcn %x offset %x", bus, dev, fcn, offset); printf(" daddr %x reg %x",daddr, reg); @@ -886,55 +574,3 @@ mpc_conf_write(void *cpv, pcitag_t tag, int offset, pcireg_t data) splx(s); } - - -/*ARGSUSED*/ -int -mpc_intr_map(void *lcv, pcitag_t bustag, int buspin, int line, - pci_intr_handle_t *ihp) -{ - int error = 0; - - *ihp = -1; - if (buspin == 0) - error = 1; /* No IRQ used. */ - else if (buspin > 4) { - printf("mpc_intr_map: bad interrupt pin %d\n", buspin); - error = 1; - } - if (line == 0xff || line == 0) - error = 1; - - if (!error) - *ihp = line; - return error; -} - -const char * -mpc_intr_string(void *lcv, pci_intr_handle_t ih) -{ - static char str[16]; - - snprintf(str, sizeof str, "irq %ld", ih); - return(str); -} - -int -mpc_intr_line(void *lcv, pci_intr_handle_t ih) -{ - return (ih); -} - -void * -mpc_intr_establish(void *lcv, pci_intr_handle_t ih, int level, - int (*func)(void *), void *arg, const char *name) -{ - return (*intr_establish_func)(lcv, ih, IST_LEVEL, level, func, arg, - name); -} - -void -mpc_intr_disestablish(void *lcv, void *cookie) -{ - /* XXX We should probably do something clever here.... later */ -} diff --git a/sys/arch/macppc/pci/pci_machdep.c b/sys/arch/macppc/pci/pci_machdep.c new file mode 100644 index 00000000000..fc32e87f12e --- /dev/null +++ b/sys/arch/macppc/pci/pci_machdep.c @@ -0,0 +1,340 @@ +/* $OpenBSD: pci_machdep.c,v 1.1 2013/08/07 07:29:19 mpi Exp $ */ + +/* + * Copyright (c) 2013 Martin Pieuchot + * Copyright (c) 1997 Per Fogelstrom + * + * 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. + * + * 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 <machine/bus.h> +#include <machine/autoconf.h> + +#include <dev/pci/pcireg.h> +#include <dev/pci/pcivar.h> + +#include <dev/ofw/openfirm.h> +#include <dev/ofw/ofw_pci.h> + + +struct powerpc_bus_dma_tag pci_bus_dma_tag = { + NULL, + _dmamap_create, + _dmamap_destroy, + _dmamap_load, + _dmamap_load_mbuf, + _dmamap_load_uio, + _dmamap_load_raw, + _dmamap_unload, + _dmamap_sync, + _dmamem_alloc, + _dmamem_free, + _dmamem_map, + _dmamem_unmap, + _dmamem_mmap +}; + +void +pci_attach_hook(struct device *parent, struct device *self, + struct pcibus_attach_args *pba) +{ +} + +int +pci_bus_maxdevs(pci_chipset_tag_t pc, int busno) +{ + return (32); +} + +pcitag_t +pci_make_tag(pci_chipset_tag_t pc, int b, int d, int f) +{ + struct ofw_pci_register reg; + pcitag_t tag; + int node, busrange[2]; + + if (pc->busnode[b]) + return PCITAG_CREATE(0, b, d, f); + + for (node = pc->pc_node; node; node = OF_peer(node)) { + /* + * Check for PCI-PCI bridges. If the device we want is + * in the bus-range for that bridge, work our way down. + */ + while ((OF_getprop(node, "bus-range", &busrange, + sizeof(busrange)) == sizeof(busrange)) && + (b >= busrange[0] && b <= busrange[1])) { + node = OF_child(node); + } + + if (OF_getprop(node, "reg", ®, sizeof(reg)) < sizeof(reg)) + continue; + + if (b != OFW_PCI_PHYS_HI_BUS(reg.phys_hi)) + continue; + if (d != OFW_PCI_PHYS_HI_DEVICE(reg.phys_hi)) + continue; + if (f != OFW_PCI_PHYS_HI_FUNCTION(reg.phys_hi)) + continue; + + tag = PCITAG_CREATE(node, b, d, f); + + return (tag); + } + + return (PCITAG_CREATE(-1, b, d, f)); +} + +void +pci_decompose_tag(pci_chipset_tag_t pc, pcitag_t tag, int *b, int *d, int *f) +{ + if (b != NULL) + *b = PCITAG_BUS(tag); + if (d != NULL) + *d = PCITAG_DEV(tag); + if (f != NULL) + *f = PCITAG_FUN(tag); +} + +int +pci_conf_size(pci_chipset_tag_t pc, pcitag_t tag) +{ + return (PCI_CONFIG_SPACE_SIZE); +} + +pcireg_t +pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg) +{ + if (PCITAG_NODE(tag) != -1) + return (*(pc)->pc_conf_read)(pc->pc_conf_v, tag, reg); + + return ((pcireg_t)~0); +} + +void +pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t data) +{ + if (PCITAG_NODE(tag) != -1) + (*(pc)->pc_conf_write)(pc->pc_conf_v, tag, reg, data); +} + +int +pci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp) +{ + struct ofw_pci_register reg; + int node = PCITAG_NODE(pa->pa_tag); + int intr[4], nintr, len; + + if (OF_getprop(node, "reg", ®, sizeof(reg)) < sizeof(reg)) + return (ENODEV); + + /* Try to get the old Apple OFW interrupt property first. */ + len = OF_getprop(node, "AAPL,interrupts", &intr, sizeof(intr)); + if (len == sizeof(intr[0])) + goto found; + + len = OF_getprop(node, "interrupts", intr, sizeof(intr)); + if (len < sizeof(intr[0])) + return (ENODEV); + + /* + * If we have multiple interrupts for a device, choose the one + * that corresponds to the PCI function. + */ + nintr = len / sizeof(intr[0]); + if (PCITAG_FUN(pa->pa_tag) < nintr) + intr[0] = intr[PCITAG_FUN(pa->pa_tag)]; + + reg.size_hi = intr[0]; + if (ofw_intr_map(OF_parent(node), (uint32_t *)®, intr)) { + /* + * This can fail on some machines where the parent's + * node doesn't have any "interrupt-map" and friends. + * + * In this case just trust what we got in "interrupts". + */ + } + +found: + *ihp = intr[0]; + + return (0); +} + +int +pci_intr_map_msi(struct pci_attach_args *pa, pci_intr_handle_t *ihp) +{ + return (-1); +} + +int +pci_intr_line(pci_chipset_tag_t pc, pci_intr_handle_t ih) +{ + return (ih); +} + +const char * +pci_intr_string(pci_chipset_tag_t pc, pci_intr_handle_t ih) +{ + static char str[16]; + + snprintf(str, sizeof(str), "irq %ld", ih); + + return (str); +} + +void * +pci_intr_establish(pci_chipset_tag_t pc, pci_intr_handle_t ih, int lvl, + int (*func)(void *), void *arg, const char *what) +{ + return (*intr_establish_func)(pc, ih, IST_LEVEL, lvl, func, arg, what); +} + +void +pci_intr_disestablish(pci_chipset_tag_t pc, void *cookie) +{ + (*intr_disestablish_func)(pc, cookie); +} + +int +pci_ether_hw_addr(pci_chipset_tag_t pc, uint8_t *oaddr) +{ + uint8_t laddr[6]; + int node, len; + + node = OF_finddevice("enet"); + len = OF_getprop(node, "local-mac-address", laddr, sizeof(laddr)); + if (sizeof(laddr) == len) { + memcpy(oaddr, laddr, sizeof(laddr)); + return (1); + } + + oaddr[0] = oaddr[1] = oaddr[2] = 0xff; + oaddr[3] = oaddr[4] = oaddr[5] = 0xff; + + return (0); +} + +int +ofw_enumerate_pcibus(struct pci_softc *sc, + int (*match)(struct pci_attach_args *), struct pci_attach_args *pap) +{ + pci_chipset_tag_t pc = sc->sc_pc; + struct ofw_pci_register reg; + int node, b, d, f, ret; + pcireg_t bhlcr; + pcitag_t tag; + + if (sc->sc_bridgetag) + node = PCITAG_NODE(*sc->sc_bridgetag); + else + node = pc->pc_node; + + for (node = OF_child(node); node; node = OF_peer(node)) { + if (OF_getprop(node, "reg", ®, sizeof(reg)) < sizeof(reg)) + continue; + + b = OFW_PCI_PHYS_HI_BUS(reg.phys_hi); + d = OFW_PCI_PHYS_HI_DEVICE(reg.phys_hi); + f = OFW_PCI_PHYS_HI_FUNCTION(reg.phys_hi); + + tag = PCITAG_CREATE(node, b, d, f); + + bhlcr = pci_conf_read(pc, tag, PCI_BHLC_REG); + if (PCI_HDRTYPE_TYPE(bhlcr) > 2) + continue; + + ret = pci_probe_device(sc, tag, match, pap); + if (match != NULL && ret != 0) + return (ret); + } + + return (0); +} + +int +ofw_intr_map(int node, uint32_t *addr, uint32_t *intr) +{ + uint32_t imap[144], mmask[8], *mp, *mp1; + uint32_t acells, icells, mcells; + int ilen, mlen, i, step = 0; + int parent; + + ilen = OF_getprop(node, "interrupt-map", imap, sizeof(imap)); + mlen = OF_getprop(node, "interrupt-map-mask", mmask, sizeof(mmask)); + if (ilen < 0 || mlen < 0) + return (-1); + + if ((OF_getprop(node, "#address-cells", &acells, 4) < 0) || + (OF_getprop(node, "#interrupt-cells", &icells, 4) < 0)) + return (-1); + + mcells = acells + icells; + if (mcells != (mlen / sizeof(mmask[0]))) + return (-1); + + for (i = 0; i < mcells; i++) + addr[i] &= mmask[i]; + + /* interrupt-map is formatted as follows + * int * #address-cells, int * #interrupt-cells, int, int, int + * eg + * address-cells = 3 + * interrupt-cells = 1 + * 00001000 00000000 00000000 00000000 ff911258 00000034 00000001 + * 00001800 00000000 00000000 00000000 ff911258 00000035 00000001 + * 00002000 00000000 00000000 00000000 ff911258 00000036 00000001 + * | address cells | | intr | |node| | irq | |edge/level| + * | cells| | interrupt cells | + * | of node | + * or at least something close to that. + */ + for (mp = imap; ilen > mlen; mp += step) { + mp1 = mp + mcells; + parent = *mp1; + + if (bcmp(mp, addr, mlen) == 0) { + /* + * If we have a match and the parent is not an + * interrupt controller continue recursively. + */ + if (OF_getprop(parent, "interrupt-controller", NULL, 0)) + return ofw_intr_map(parent, &mp1[1], intr); + + *intr = mp1[1]; + return (0); + } + + if (OF_getprop(parent, "#address-cells", &acells, 4) < 0) + acells = 0; + if (OF_getprop(parent, "#interrupt-cells", &icells, 4) < 0) + break; + + step = mcells + 1 + acells + icells; + ilen -= step * sizeof(imap[0]); + } + + return (-1); +} diff --git a/sys/arch/powerpc/pci/pci_machdep.h b/sys/arch/socppc/include/pci_machdep.h index 99db8749e9a..2ba90f5d6ef 100644 --- a/sys/arch/powerpc/pci/pci_machdep.h +++ b/sys/arch/socppc/include/pci_machdep.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pci_machdep.h,v 1.23 2012/08/28 19:52:18 kettenis Exp $ */ +/* $OpenBSD: pci_machdep.h,v 1.1 2013/08/07 07:29:20 mpi Exp $ */ /* * Copyright (c) 1996 Carnegie-Mellon University. diff --git a/sys/dev/pci/pcivar.h b/sys/dev/pci/pcivar.h index 2aec82ec631..0fe08aaa9b0 100644 --- a/sys/dev/pci/pcivar.h +++ b/sys/dev/pci/pcivar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pcivar.h,v 1.67 2012/09/19 23:01:21 kettenis Exp $ */ +/* $OpenBSD: pcivar.h,v 1.68 2013/08/07 07:29:19 mpi Exp $ */ /* $NetBSD: pcivar.h,v 1.23 1997/06/06 23:48:05 thorpej Exp $ */ /* @@ -73,8 +73,6 @@ struct pci_softc; #include <alpha/pci/pci_machdep.h> #elif defined(__i386__) #include <i386/pci/pci_machdep.h> -#elif defined(__powerpc__) -#include <powerpc/pci/pci_machdep.h> #elif defined(__sgi__) #include <sgi/pci/pci_machdep.h> #else |