Home | History | Annotate | Line # | Download | only in pci
pci_machdep.c revision 1.5.34.1
      1  1.5.34.1  pgoyette /*	$NetBSD: pci_machdep.c,v 1.5.34.1 2016/11/04 14:49:01 pgoyette Exp $	*/
      2       1.2   garbled 
      3       1.2   garbled /*
      4       1.2   garbled  * Copyright (c) 1996 Christopher G. Demetriou.  All rights reserved.
      5       1.2   garbled  * Copyright (c) 1994 Charles M. Hannum.  All rights reserved.
      6       1.2   garbled  *
      7       1.2   garbled  * Redistribution and use in source and binary forms, with or without
      8       1.2   garbled  * modification, are permitted provided that the following conditions
      9       1.2   garbled  * are met:
     10       1.2   garbled  * 1. Redistributions of source code must retain the above copyright
     11       1.2   garbled  *    notice, this list of conditions and the following disclaimer.
     12       1.2   garbled  * 2. Redistributions in binary form must reproduce the above copyright
     13       1.2   garbled  *    notice, this list of conditions and the following disclaimer in the
     14       1.2   garbled  *    documentation and/or other materials provided with the distribution.
     15       1.2   garbled  * 3. All advertising materials mentioning features or use of this software
     16       1.2   garbled  *    must display the following acknowledgement:
     17       1.2   garbled  *	This product includes software developed by Charles M. Hannum.
     18       1.2   garbled  * 4. The name of the author may not be used to endorse or promote products
     19       1.2   garbled  *    derived from this software without specific prior written permission.
     20       1.2   garbled  *
     21       1.2   garbled  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     22       1.2   garbled  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     23       1.2   garbled  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     24       1.2   garbled  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     25       1.2   garbled  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     26       1.2   garbled  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     27       1.2   garbled  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     28       1.2   garbled  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     29       1.2   garbled  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     30       1.2   garbled  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31       1.2   garbled  */
     32       1.2   garbled 
     33       1.2   garbled /*
     34       1.2   garbled  * Machine-specific functions for PCI autoconfiguration.
     35       1.2   garbled  *
     36       1.2   garbled  * On PCs, there are two methods of generating PCI configuration cycles.
     37       1.2   garbled  * We try to detect the appropriate mechanism for this machine and set
     38       1.2   garbled  * up a few function pointers to access the correct method directly.
     39       1.2   garbled  *
     40       1.2   garbled  * The configuration method can be hard-coded in the config file by
     41       1.2   garbled  * using `options PCI_CONF_MODE=N', where `N' is the configuration mode
     42       1.2   garbled  * as defined section 3.6.4.1, `Generating Configuration Cycles'.
     43       1.2   garbled  */
     44       1.2   garbled 
     45       1.2   garbled #include <sys/cdefs.h>
     46  1.5.34.1  pgoyette __KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.5.34.1 2016/11/04 14:49:01 pgoyette Exp $");
     47       1.2   garbled 
     48       1.2   garbled #include <sys/param.h>
     49       1.4      matt #include <sys/bus.h>
     50       1.2   garbled #include <sys/device.h>
     51       1.2   garbled #include <sys/errno.h>
     52       1.2   garbled #include <sys/extent.h>
     53       1.4      matt #include <sys/intr.h>
     54       1.2   garbled #include <sys/malloc.h>
     55       1.2   garbled #include <sys/queue.h>
     56       1.2   garbled #include <sys/systm.h>
     57       1.2   garbled #include <sys/time.h>
     58       1.2   garbled 
     59       1.2   garbled #include <uvm/uvm.h>
     60       1.2   garbled 
     61       1.2   garbled #define _POWERPC_BUS_DMA_PRIVATE
     62       1.2   garbled 
     63       1.2   garbled #include <dev/ic/cpc700reg.h>
     64       1.4      matt 
     65       1.2   garbled #include <machine/pmppc.h>
     66       1.4      matt #include <machine/pio.h>
     67       1.2   garbled 
     68       1.2   garbled #include <dev/pci/pcivar.h>
     69       1.2   garbled #include <dev/pci/pcireg.h>
     70       1.2   garbled #include <dev/pci/pcidevs.h>
     71       1.2   garbled #include <dev/pci/pciconf.h>
     72       1.2   garbled 
     73       1.4      matt #include <evbppc/pmppc/dev/mainbus.h>
     74       1.2   garbled 
     75       1.2   garbled /*
     76       1.2   garbled  * Address conversion as seen from a PCI master.
     77       1.2   garbled  * XXX Shouldn't use 0x80000000, the actual value
     78       1.2   garbled  * should come from the BAR.
     79       1.2   garbled  */
     80       1.2   garbled #define PHYS_TO_PCI_MEM(x)	((x) + 0x80000000)
     81       1.2   garbled #define PCI_MEM_TO_PHYS(x)	((x) - 0x80000000)
     82       1.2   garbled 
     83       1.2   garbled static bus_addr_t phys_to_pci(bus_dma_tag_t, bus_addr_t);
     84       1.2   garbled static bus_addr_t pci_to_phys(bus_dma_tag_t, bus_addr_t);
     85       1.2   garbled 
     86       1.2   garbled extern struct powerpc_bus_dma_tag pci_bus_dma_tag;
     87       1.2   garbled 
     88       1.2   garbled void
     89       1.2   garbled pmppc_pci_get_chipset_tag(pci_chipset_tag_t pc)
     90       1.2   garbled {
     91       1.2   garbled 	pc->pc_conf_v = (void *)pc;
     92       1.2   garbled 
     93       1.2   garbled 	pc->pc_attach_hook = genppc_pci_indirect_attach_hook;
     94       1.2   garbled 	pc->pc_bus_maxdevs = genppc_pci_bus_maxdevs;
     95       1.2   garbled 	pc->pc_make_tag = genppc_pci_indirect_make_tag;
     96       1.2   garbled 	pc->pc_conf_read = genppc_pci_indirect_conf_read;
     97       1.2   garbled 	pc->pc_conf_write = genppc_pci_indirect_conf_write;
     98       1.2   garbled 
     99       1.2   garbled 	pc->pc_intr_v = (void *)pc;
    100       1.2   garbled 
    101       1.2   garbled 	pc->pc_intr_map = pmppc_pci_intr_map;
    102       1.2   garbled 	pc->pc_intr_string = genppc_pci_intr_string;
    103       1.2   garbled 	pc->pc_intr_evcnt = genppc_pci_intr_evcnt;
    104       1.2   garbled 	pc->pc_intr_establish = genppc_pci_intr_establish;
    105       1.2   garbled 	pc->pc_intr_disestablish = genppc_pci_intr_disestablish;
    106       1.4      matt 	pc->pc_intr_setattr = genppc_pci_intr_setattr;
    107  1.5.34.1  pgoyette 	pc->pc_intr_type = genppc_pci_intr_type;
    108  1.5.34.1  pgoyette 	pc->pc_intr_alloc = genppc_pci_intr_alloc;
    109  1.5.34.1  pgoyette 	pc->pc_intr_release = genppc_pci_intr_release;
    110  1.5.34.1  pgoyette 	pc->pc_intx_alloc = genppc_pci_intx_alloc;
    111  1.5.34.1  pgoyette 
    112  1.5.34.1  pgoyette 	pc->pc_msi_v = (void *)pc;
    113  1.5.34.1  pgoyette 	genppc_pci_chipset_msi_init(pc);
    114  1.5.34.1  pgoyette 
    115  1.5.34.1  pgoyette 	pc->pc_msix_v = (void *)pc;
    116  1.5.34.1  pgoyette 	genppc_pci_chipset_msix_init(pc);
    117       1.2   garbled 
    118       1.2   garbled 	pc->pc_conf_interrupt = pmppc_pci_conf_interrupt;
    119       1.2   garbled 	pc->pc_decompose_tag = genppc_pci_indirect_decompose_tag;
    120       1.2   garbled 	pc->pc_conf_hook = genppc_pci_conf_hook;
    121       1.2   garbled 
    122       1.5      matt 	pc->pc_addr = mapiodev(CPC_PCICFGADR, 4, false);
    123       1.5      matt 	pc->pc_data = mapiodev(CPC_PCICFGDATA, 4, false);
    124       1.2   garbled 	pc->pc_bus = 0;
    125       1.2   garbled 	pc->pc_node = 0;
    126       1.2   garbled 	pc->pc_memt = 0;
    127       1.2   garbled 	pc->pc_iot = 0;
    128       1.2   garbled 
    129       1.2   garbled 	/* the following two lines are required because unlike other ports,
    130       1.2   garbled 	 * we cannot just add PHYS_TO_BUS_MEM/BUS_MEM_TO_PHYS defines to
    131       1.2   garbled 	 * bus.h, because it would impact other evbppc ports.
    132       1.2   garbled 	 */
    133       1.2   garbled 	pci_bus_dma_tag._dma_phys_to_bus_mem = phys_to_pci;
    134       1.2   garbled 	pci_bus_dma_tag._dma_bus_mem_to_phys = pci_to_phys;
    135       1.2   garbled }
    136       1.2   garbled 
    137       1.2   garbled 
    138       1.2   garbled static bus_addr_t
    139       1.2   garbled phys_to_pci(bus_dma_tag_t t, bus_addr_t a)
    140       1.2   garbled {
    141       1.2   garbled 	return PHYS_TO_PCI_MEM(a);
    142       1.2   garbled }
    143       1.2   garbled 
    144       1.2   garbled static bus_addr_t pci_to_phys(bus_dma_tag_t t, bus_addr_t a)
    145       1.2   garbled {
    146       1.2   garbled 	return PCI_MEM_TO_PHYS(a);
    147       1.2   garbled }
    148       1.2   garbled 
    149       1.2   garbled int
    150       1.3    dyoung pmppc_pci_intr_map(const struct pci_attach_args *pa, pci_intr_handle_t *ihp)
    151       1.2   garbled {
    152       1.2   garbled 	int	pin = pa->pa_intrpin;
    153       1.2   garbled 	int	line = pa->pa_intrline;
    154       1.2   garbled 
    155       1.2   garbled 	if (pin == 0) {
    156       1.2   garbled 		/* No IRQ used. */
    157       1.2   garbled 		goto bad;
    158       1.2   garbled 	}
    159       1.2   garbled 
    160       1.2   garbled 	if (pin > 4) {
    161       1.2   garbled 		printf("pci_intr_map: bad interrupt pin %d\n", pin);
    162       1.2   garbled 		goto bad;
    163       1.2   garbled 	}
    164       1.2   garbled 
    165       1.2   garbled 	if (line == 255) {
    166       1.2   garbled 		printf("pci_intr_map: no mapping for pin %c\n", '@' + pin);
    167       1.2   garbled 		goto bad;
    168       1.2   garbled 	}
    169       1.2   garbled 	/*printf("pci_intr_map pin=%d line=%d\n", pin, line);*/
    170       1.2   garbled 
    171       1.2   garbled 	switch (line & 3) {	/* XXX what should this be? */
    172       1.2   garbled 	case 0: *ihp = PMPPC_I_BPMC_INTA; break;
    173       1.2   garbled 	case 1: *ihp = PMPPC_I_BPMC_INTB; break;
    174       1.2   garbled 	case 2: *ihp = PMPPC_I_BPMC_INTC; break;
    175       1.2   garbled 	case 3: *ihp = PMPPC_I_BPMC_INTD; break;
    176       1.2   garbled 	}
    177       1.2   garbled 	return 0;
    178       1.2   garbled 
    179       1.2   garbled bad:
    180       1.2   garbled 	*ihp = -1;
    181       1.2   garbled 	return 1;
    182       1.2   garbled }
    183       1.2   garbled 
    184       1.2   garbled void
    185       1.4      matt pmppc_pci_conf_interrupt(void *v, int bus, int dev, int pin, int swiz,
    186       1.4      matt     int *iline)
    187       1.2   garbled {
    188       1.2   garbled 	int line;
    189       1.2   garbled 
    190       1.2   garbled 	line = (swiz + dev) & 3;
    191       1.2   garbled 	/* XXX UGLY UGLY, figure out the real interrupt mapping */
    192       1.2   garbled 	if (bus==3&&dev==2&&pin==1&&swiz==3) line=2;
    193       1.2   garbled /*
    194       1.2   garbled 	printf("pci_conf_interrupt: bus=%d dev=%d pin=%d swiz=%d => line=%d\n",
    195       1.2   garbled 		bus, dev, pin, swiz, line);
    196       1.2   garbled */
    197       1.2   garbled 	*iline = line;
    198       1.2   garbled }
    199