Home | History | Annotate | Line # | Download | only in dev
pyro.c revision 1.5.2.1
      1  1.5.2.1  cherry /*	$NetBSD: pyro.c,v 1.5.2.1 2011/06/23 14:19:42 cherry Exp $	*/
      2      1.2     mrg /*	from: $OpenBSD: pyro.c,v 1.20 2010/12/05 15:15:14 kettenis Exp $	*/
      3      1.1     mrg 
      4      1.1     mrg /*
      5      1.1     mrg  * Copyright (c) 2002 Jason L. Wright (jason (at) thought.net)
      6      1.1     mrg  * Copyright (c) 2003 Henric Jungheim
      7      1.1     mrg  * Copyright (c) 2007 Mark Kettenis
      8      1.2     mrg  * Copyright (c) 2011 Matthew R. Green
      9      1.1     mrg  * All rights reserved.
     10      1.1     mrg  *
     11      1.1     mrg  * Redistribution and use in source and binary forms, with or without
     12      1.1     mrg  * modification, are permitted provided that the following conditions
     13      1.1     mrg  * are met:
     14      1.1     mrg  * 1. Redistributions of source code must retain the above copyright
     15      1.1     mrg  *    notice, this list of conditions and the following disclaimer.
     16      1.1     mrg  * 2. Redistributions in binary form must reproduce the above copyright
     17      1.1     mrg  *    notice, this list of conditions and the following disclaimer in the
     18      1.1     mrg  *    documentation and/or other materials provided with the distribution.
     19      1.1     mrg  *
     20      1.1     mrg  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     21      1.1     mrg  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     22      1.1     mrg  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     23      1.1     mrg  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
     24      1.1     mrg  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     25      1.1     mrg  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     26      1.1     mrg  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     27      1.1     mrg  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     28      1.1     mrg  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
     29      1.1     mrg  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     30      1.1     mrg  * POSSIBILITY OF SUCH DAMAGE.
     31      1.1     mrg  */
     32      1.1     mrg 
     33      1.1     mrg #include <sys/param.h>
     34      1.1     mrg #include <sys/device.h>
     35      1.1     mrg #include <sys/errno.h>
     36      1.1     mrg #include <sys/malloc.h>
     37      1.1     mrg #include <sys/systm.h>
     38      1.1     mrg 
     39      1.1     mrg #define _SPARC_BUS_DMA_PRIVATE
     40      1.1     mrg #include <machine/bus.h>
     41      1.1     mrg #include <machine/autoconf.h>
     42      1.1     mrg 
     43      1.1     mrg #ifdef DDB
     44      1.1     mrg #include <machine/db_machdep.h>
     45      1.1     mrg #endif
     46      1.1     mrg 
     47      1.1     mrg #include <dev/pci/pcivar.h>
     48      1.1     mrg #include <dev/pci/pcireg.h>
     49      1.1     mrg 
     50      1.1     mrg #include <sparc64/dev/iommureg.h>
     51      1.1     mrg #include <sparc64/dev/iommuvar.h>
     52      1.1     mrg #include <sparc64/dev/pyrovar.h>
     53      1.1     mrg 
     54      1.1     mrg #ifdef DEBUG
     55      1.1     mrg #define PDB_PROM        0x01
     56      1.1     mrg #define PDB_BUSMAP      0x02
     57      1.1     mrg #define PDB_INTR        0x04
     58      1.1     mrg #define PDB_CONF        0x08
     59      1.2     mrg int pyro_debug = 0x4;
     60      1.1     mrg #define DPRINTF(l, s)   do { if (pyro_debug & l) printf s; } while (0)
     61      1.1     mrg #else
     62      1.1     mrg #define DPRINTF(l, s)
     63      1.1     mrg #endif
     64      1.1     mrg 
     65      1.1     mrg #define FIRE_RESET_GEN			0x7010
     66      1.1     mrg 
     67      1.1     mrg #define FIRE_RESET_GEN_XIR		0x0000000000000002L
     68      1.1     mrg 
     69      1.1     mrg #define FIRE_INTRMAP_INT_CNTRL_NUM_MASK	0x000003c0
     70      1.1     mrg #define FIRE_INTRMAP_INT_CNTRL_NUM0	0x00000040
     71      1.1     mrg #define FIRE_INTRMAP_INT_CNTRL_NUM1	0x00000080
     72      1.1     mrg #define FIRE_INTRMAP_INT_CNTRL_NUM2	0x00000100
     73      1.1     mrg #define FIRE_INTRMAP_INT_CNTRL_NUM3	0x00000200
     74      1.1     mrg #define FIRE_INTRMAP_T_JPID_SHIFT	26
     75      1.1     mrg #define FIRE_INTRMAP_T_JPID_MASK	0x7c000000
     76      1.1     mrg 
     77      1.1     mrg #define OBERON_INTRMAP_T_DESTID_SHIFT	21
     78      1.1     mrg #define OBERON_INTRMAP_T_DESTID_MASK	0x7fe00000
     79      1.1     mrg 
     80      1.1     mrg extern struct sparc_pci_chipset _sparc_pci_chipset;
     81      1.1     mrg 
     82  1.5.2.1  cherry int pyro_match(device_t, cfdata_t, void *);
     83  1.5.2.1  cherry void pyro_attach(device_t, device_t, void *);
     84      1.2     mrg int pyro_print(void *, const char *);
     85      1.2     mrg 
     86  1.5.2.1  cherry CFATTACH_DECL_NEW(pyro, sizeof(struct pyro_softc),
     87      1.2     mrg     pyro_match, pyro_attach, NULL, NULL);
     88      1.2     mrg 
     89      1.1     mrg void pyro_init(struct pyro_softc *, int);
     90      1.1     mrg void pyro_init_iommu(struct pyro_softc *, struct pyro_pbm *);
     91      1.1     mrg 
     92      1.1     mrg pci_chipset_tag_t pyro_alloc_chipset(struct pyro_pbm *, int,
     93      1.1     mrg     pci_chipset_tag_t);
     94      1.1     mrg bus_space_tag_t pyro_alloc_mem_tag(struct pyro_pbm *);
     95      1.1     mrg bus_space_tag_t pyro_alloc_io_tag(struct pyro_pbm *);
     96      1.1     mrg bus_space_tag_t pyro_alloc_config_tag(struct pyro_pbm *);
     97      1.2     mrg bus_space_tag_t pyro_alloc_bus_tag(struct pyro_pbm *, const char *, int);
     98      1.1     mrg bus_dma_tag_t pyro_alloc_dma_tag(struct pyro_pbm *);
     99      1.1     mrg 
    100      1.2     mrg #if 0
    101      1.1     mrg int pyro_conf_size(pci_chipset_tag_t, pcitag_t);
    102      1.2     mrg #endif
    103      1.1     mrg pcireg_t pyro_conf_read(pci_chipset_tag_t, pcitag_t, int);
    104      1.1     mrg void pyro_conf_write(pci_chipset_tag_t, pcitag_t, int, pcireg_t);
    105      1.1     mrg 
    106      1.2     mrg static void * pyro_pci_intr_establish(pci_chipset_tag_t pc,
    107      1.2     mrg 				      pci_intr_handle_t ih, int level,
    108      1.2     mrg 				      int (*func)(void *), void *arg);
    109      1.2     mrg 
    110      1.4  dyoung int pyro_intr_map(const struct pci_attach_args *, pci_intr_handle_t *);
    111      1.2     mrg int pyro_bus_map(bus_space_tag_t, bus_addr_t,
    112      1.2     mrg     bus_size_t, int, vaddr_t, bus_space_handle_t *);
    113      1.2     mrg paddr_t pyro_bus_mmap(bus_space_tag_t, bus_addr_t, off_t,
    114      1.1     mrg     int, int);
    115      1.2     mrg void *pyro_intr_establish(bus_space_tag_t, int, int,
    116      1.2     mrg     int (*)(void *), void *, void (*)(void));
    117      1.1     mrg 
    118      1.2     mrg int pyro_dmamap_create(bus_dma_tag_t, bus_size_t, int,
    119      1.1     mrg     bus_size_t, bus_size_t, int, bus_dmamap_t *);
    120      1.1     mrg 
    121      1.1     mrg int
    122  1.5.2.1  cherry pyro_match(struct device *parent, cfdata_t match, void *aux)
    123      1.1     mrg {
    124      1.1     mrg 	struct mainbus_attach_args *ma = aux;
    125      1.1     mrg 	char *str;
    126      1.1     mrg 
    127      1.1     mrg 	if (strcmp(ma->ma_name, "pci") != 0)
    128      1.1     mrg 		return (0);
    129      1.1     mrg 
    130      1.2     mrg 	str = prom_getpropstring(ma->ma_node, "compatible");
    131      1.1     mrg 	if (strcmp(str, "pciex108e,80f0") == 0 ||
    132      1.1     mrg 	    strcmp(str, "pciex108e,80f8") == 0)
    133      1.1     mrg 		return (1);
    134      1.1     mrg 
    135      1.1     mrg 	return (0);
    136      1.1     mrg }
    137      1.1     mrg 
    138      1.1     mrg void
    139      1.1     mrg pyro_attach(struct device *parent, struct device *self, void *aux)
    140      1.1     mrg {
    141  1.5.2.1  cherry 	struct pyro_softc *sc = device_private(self);
    142      1.1     mrg 	struct mainbus_attach_args *ma = aux;
    143      1.1     mrg 	char *str;
    144      1.1     mrg 	int busa;
    145      1.1     mrg 
    146  1.5.2.1  cherry 	sc->sc_dev = self;
    147      1.1     mrg 	sc->sc_node = ma->ma_node;
    148      1.1     mrg 	sc->sc_dmat = ma->ma_dmatag;
    149      1.2     mrg 	sc->sc_bustag = ma->ma_bustag;
    150      1.1     mrg 	sc->sc_csr = ma->ma_reg[0].ur_paddr;
    151      1.1     mrg 	sc->sc_xbc = ma->ma_reg[1].ur_paddr;
    152      1.1     mrg 	sc->sc_ign = INTIGN(ma->ma_upaid << INTMAP_IGN_SHIFT);
    153      1.1     mrg 
    154      1.1     mrg 	if ((ma->ma_reg[0].ur_paddr & 0x00700000) == 0x00600000)
    155      1.1     mrg 		busa = 1;
    156      1.1     mrg 	else
    157      1.1     mrg 		busa = 0;
    158      1.1     mrg 
    159      1.2     mrg 	if (bus_space_map(sc->sc_bustag, sc->sc_csr,
    160      1.2     mrg 	    ma->ma_reg[0].ur_len, BUS_SPACE_MAP_LINEAR, &sc->sc_csrh)) {
    161      1.1     mrg 		printf(": failed to map csr registers\n");
    162      1.1     mrg 		return;
    163      1.1     mrg 	}
    164      1.1     mrg 
    165      1.2     mrg 	if (bus_space_map(sc->sc_bustag, sc->sc_xbc,
    166      1.1     mrg 	    ma->ma_reg[1].ur_len, 0, &sc->sc_xbch)) {
    167      1.1     mrg 		printf(": failed to map xbc registers\n");
    168      1.1     mrg 		return;
    169      1.1     mrg 	}
    170      1.1     mrg 
    171      1.2     mrg 	str = prom_getpropstring(ma->ma_node, "compatible");
    172      1.1     mrg 	if (strcmp(str, "pciex108e,80f8") == 0)
    173      1.1     mrg 		sc->sc_oberon = 1;
    174      1.1     mrg 
    175      1.1     mrg 	pyro_init(sc, busa);
    176      1.1     mrg }
    177      1.1     mrg 
    178      1.1     mrg void
    179      1.1     mrg pyro_init(struct pyro_softc *sc, int busa)
    180      1.1     mrg {
    181      1.1     mrg 	struct pyro_pbm *pbm;
    182      1.1     mrg 	struct pcibus_attach_args pba;
    183      1.1     mrg 	int *busranges = NULL, nranges;
    184      1.1     mrg 
    185      1.1     mrg 	pbm = malloc(sizeof(*pbm), M_DEVBUF, M_NOWAIT | M_ZERO);
    186      1.1     mrg 	if (pbm == NULL)
    187      1.1     mrg 		panic("pyro: can't alloc pyro pbm");
    188      1.1     mrg 
    189      1.1     mrg 	pbm->pp_sc = sc;
    190      1.1     mrg 	pbm->pp_bus_a = busa;
    191      1.1     mrg 
    192      1.2     mrg 	if (prom_getprop(sc->sc_node, "ranges", sizeof(struct pyro_range),
    193      1.1     mrg 	    &pbm->pp_nrange, (void **)&pbm->pp_range))
    194      1.1     mrg 		panic("pyro: can't get ranges");
    195      1.1     mrg 
    196      1.2     mrg 	if (prom_getprop(sc->sc_node, "bus-range", sizeof(int), &nranges,
    197      1.1     mrg 	    (void **)&busranges))
    198      1.1     mrg 		panic("pyro: can't get bus-range");
    199      1.1     mrg 
    200      1.1     mrg 	printf(": \"%s\", rev %d, ign %x, bus %c %d to %d\n",
    201      1.1     mrg 	    sc->sc_oberon ? "Oberon" : "Fire",
    202      1.2     mrg 	    prom_getpropint(sc->sc_node, "module-revision#", 0), sc->sc_ign,
    203      1.1     mrg 	    busa ? 'A' : 'B', busranges[0], busranges[1]);
    204      1.1     mrg 
    205  1.5.2.1  cherry 	printf("%s: ", device_xname(sc->sc_dev));
    206      1.1     mrg 	pyro_init_iommu(sc, pbm);
    207      1.1     mrg 
    208      1.1     mrg 	pbm->pp_memt = pyro_alloc_mem_tag(pbm);
    209      1.1     mrg 	pbm->pp_iot = pyro_alloc_io_tag(pbm);
    210      1.1     mrg 	pbm->pp_cfgt = pyro_alloc_config_tag(pbm);
    211      1.1     mrg 	pbm->pp_dmat = pyro_alloc_dma_tag(pbm);
    212      1.5  dyoung 	pbm->pp_flags = (pbm->pp_memt ? PCI_FLAGS_MEM_OKAY : 0) |
    213      1.5  dyoung 		        (pbm->pp_iot ? PCI_FLAGS_IO_OKAY : 0);
    214      1.1     mrg 
    215      1.1     mrg 	if (bus_space_map(pbm->pp_cfgt, 0, 0x10000000, 0, &pbm->pp_cfgh))
    216      1.1     mrg 		panic("pyro: can't map config space");
    217      1.1     mrg 
    218      1.1     mrg 	pbm->pp_pc = pyro_alloc_chipset(pbm, sc->sc_node, &_sparc_pci_chipset);
    219      1.2     mrg 	pbm->pp_pc->spc_busmax = busranges[1];
    220      1.2     mrg 	pbm->pp_pc->spc_busnode = malloc(sizeof(*pbm->pp_pc->spc_busnode),
    221      1.2     mrg 	    M_DEVBUF, M_NOWAIT | M_ZERO);
    222      1.2     mrg 	if (pbm->pp_pc->spc_busnode == NULL)
    223      1.2     mrg 		panic("schizo: malloc busnode");
    224      1.1     mrg 
    225      1.2     mrg #if 0
    226      1.1     mrg 	pbm->pp_pc->bustag = pbm->pp_cfgt;
    227      1.1     mrg 	pbm->pp_pc->bushandle = pbm->pp_cfgh;
    228      1.2     mrg #endif
    229      1.1     mrg 
    230      1.1     mrg 	bzero(&pba, sizeof(pba));
    231      1.1     mrg 	pba.pba_bus = busranges[0];
    232      1.1     mrg 	pba.pba_pc = pbm->pp_pc;
    233      1.1     mrg 	pba.pba_flags = pbm->pp_flags;
    234      1.1     mrg 	pba.pba_dmat = pbm->pp_dmat;
    235      1.2     mrg 	pba.pba_dmat64 = NULL;	/* XXX */
    236      1.1     mrg 	pba.pba_memt = pbm->pp_memt;
    237      1.1     mrg 	pba.pba_iot = pbm->pp_iot;
    238      1.1     mrg 
    239      1.1     mrg 	free(busranges, M_DEVBUF);
    240      1.1     mrg 
    241  1.5.2.1  cherry 	config_found(sc->sc_dev, &pba, pyro_print);
    242      1.1     mrg }
    243      1.1     mrg 
    244      1.1     mrg void
    245      1.1     mrg pyro_init_iommu(struct pyro_softc *sc, struct pyro_pbm *pbm)
    246      1.1     mrg {
    247      1.1     mrg 	struct iommu_state *is = &pbm->pp_is;
    248      1.1     mrg 	int tsbsize = 7;
    249      1.1     mrg 	u_int32_t iobase = -1;
    250      1.1     mrg 	char *name;
    251      1.1     mrg 
    252      1.2     mrg 	pbm->pp_sb.sb_is = is;
    253      1.2     mrg 	is->is_bustag = sc->sc_bustag;
    254      1.1     mrg 
    255      1.1     mrg 	if (bus_space_subregion(is->is_bustag, sc->sc_csrh,
    256      1.1     mrg 	    0x40000, 0x100, &is->is_iommu)) {
    257      1.1     mrg 		panic("pyro: unable to create iommu handle");
    258      1.1     mrg 	}
    259      1.1     mrg 
    260      1.3     mrg 	/* We have no STC.  */
    261      1.3     mrg 	is->is_sb[0] = NULL;
    262      1.1     mrg 
    263      1.1     mrg 	name = (char *)malloc(32, M_DEVBUF, M_NOWAIT);
    264      1.1     mrg 	if (name == NULL)
    265      1.1     mrg 		panic("couldn't malloc iommu name");
    266  1.5.2.1  cherry 	snprintf(name, 32, "%s dvma", device_xname(sc->sc_dev));
    267      1.1     mrg 
    268      1.3     mrg 	/* Tell iommu how to set the TSB size.  */
    269      1.3     mrg 	is->is_flags = IOMMU_TSBSIZE_IN_PTSB;
    270      1.3     mrg 
    271      1.1     mrg 	/* On Oberon, we need to flush the cache. */
    272      1.1     mrg 	if (sc->sc_oberon)
    273      1.1     mrg 		is->is_flags |= IOMMU_FLUSH_CACHE;
    274      1.1     mrg 
    275      1.1     mrg 	iommu_init(name, is, tsbsize, iobase);
    276      1.1     mrg }
    277      1.1     mrg 
    278      1.1     mrg int
    279      1.1     mrg pyro_print(void *aux, const char *p)
    280      1.1     mrg {
    281      1.1     mrg 	if (p == NULL)
    282      1.1     mrg 		return (UNCONF);
    283      1.1     mrg 	return (QUIET);
    284      1.1     mrg }
    285      1.1     mrg 
    286      1.1     mrg pcireg_t
    287      1.1     mrg pyro_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
    288      1.1     mrg {
    289      1.2     mrg 	struct pyro_pbm *pp = pc->cookie;
    290      1.2     mrg 	pcireg_t val = (pcireg_t)~0;
    291      1.2     mrg 
    292      1.2     mrg 	DPRINTF(PDB_CONF, ("%s: tag %lx reg %x ", __func__, (long)tag, reg));
    293      1.2     mrg 	if (PCITAG_NODE(tag) != -1)
    294      1.2     mrg 		val = bus_space_read_4(pp->pp_cfgt, pp->pp_cfgh,
    295      1.2     mrg 		    (PCITAG_OFFSET(tag) << 4) + reg);
    296      1.2     mrg 	DPRINTF(PDB_CONF, (" returning %08x\n", (u_int)val));
    297      1.2     mrg 	return (val);
    298      1.1     mrg }
    299      1.1     mrg 
    300      1.1     mrg void
    301      1.1     mrg pyro_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t data)
    302      1.1     mrg {
    303      1.2     mrg 	struct pyro_pbm *pp = pc->cookie;
    304      1.2     mrg 
    305      1.2     mrg 	DPRINTF(PDB_CONF, ("%s: tag %lx; reg %x; data %x", __func__,
    306      1.2     mrg 		(long)tag, reg, (int)data));
    307      1.2     mrg 
    308      1.2     mrg 	/* If we don't know it, just punt it.  */
    309      1.2     mrg 	if (PCITAG_NODE(tag) == -1) {
    310      1.2     mrg 		DPRINTF(PDB_CONF, (" .. bad addr\n"));
    311      1.2     mrg 		return;
    312      1.2     mrg 	}
    313      1.2     mrg 
    314      1.2     mrg         bus_space_write_4(pp->pp_cfgt, pp->pp_cfgh,
    315      1.1     mrg 	    (PCITAG_OFFSET(tag) << 4) + reg, data);
    316      1.2     mrg 	DPRINTF(PDB_CONF, (" .. done\n"));
    317      1.1     mrg }
    318      1.1     mrg 
    319      1.1     mrg /*
    320      1.1     mrg  * Bus-specific interrupt mapping
    321      1.1     mrg  */
    322      1.1     mrg int
    323      1.4  dyoung pyro_intr_map(const struct pci_attach_args *pa, pci_intr_handle_t *ihp)
    324      1.1     mrg {
    325      1.1     mrg 	struct pyro_pbm *pp = pa->pa_pc->cookie;
    326      1.1     mrg 	struct pyro_softc *sc = pp->pp_sc;
    327      1.1     mrg 	u_int dev;
    328      1.1     mrg 
    329      1.1     mrg 	if (*ihp != (pci_intr_handle_t)-1) {
    330      1.1     mrg 		*ihp |= sc->sc_ign;
    331      1.3     mrg 		DPRINTF(PDB_INTR, ("%s: not -1 -> ih %lx\n", __func__, (u_long)*ihp));
    332      1.1     mrg 		return (0);
    333      1.1     mrg 	}
    334      1.1     mrg 
    335      1.1     mrg 	/*
    336      1.1     mrg 	 * We didn't find a PROM mapping for this interrupt.  Try to
    337      1.1     mrg 	 * construct one ourselves based on the swizzled interrupt pin
    338      1.1     mrg 	 * and the interrupt mapping for PCI slots documented in the
    339      1.1     mrg 	 * UltraSPARC-IIi User's Manual.
    340      1.1     mrg 	 */
    341      1.1     mrg 
    342      1.2     mrg 	if (pa->pa_intrpin == 0) {
    343      1.3     mrg 		DPRINTF(PDB_INTR, ("%s: no intrpen\n", __func__));
    344      1.1     mrg 		return (-1);
    345      1.2     mrg 	}
    346      1.1     mrg 
    347      1.1     mrg 	/*
    348      1.1     mrg 	 * This deserves some documentation.  Should anyone
    349      1.1     mrg 	 * have anything official looking, please speak up.
    350      1.1     mrg 	 */
    351      1.1     mrg 	dev = pa->pa_device - 1;
    352      1.1     mrg 
    353      1.1     mrg 	*ihp = (pa->pa_intrpin - 1) & INTMAP_PCIINT;
    354      1.1     mrg 	*ihp |= (dev << 2) & INTMAP_PCISLOT;
    355      1.1     mrg 	*ihp |= sc->sc_ign;
    356      1.1     mrg 
    357      1.3     mrg 	DPRINTF(PDB_INTR, ("%s: weird hack -> ih %lx\n", __func__, (u_long)*ihp));
    358      1.1     mrg 	return (0);
    359      1.1     mrg }
    360      1.1     mrg 
    361      1.1     mrg bus_space_tag_t
    362      1.1     mrg pyro_alloc_mem_tag(struct pyro_pbm *pp)
    363      1.1     mrg {
    364      1.2     mrg 	return (pyro_alloc_bus_tag(pp, "mem", PCI_MEMORY_BUS_SPACE));
    365      1.1     mrg }
    366      1.1     mrg 
    367      1.1     mrg bus_space_tag_t
    368      1.1     mrg pyro_alloc_io_tag(struct pyro_pbm *pp)
    369      1.1     mrg {
    370      1.2     mrg 	return (pyro_alloc_bus_tag(pp, "io", PCI_IO_BUS_SPACE));
    371      1.1     mrg }
    372      1.1     mrg 
    373      1.1     mrg bus_space_tag_t
    374      1.1     mrg pyro_alloc_config_tag(struct pyro_pbm *pp)
    375      1.1     mrg {
    376      1.2     mrg 	return (pyro_alloc_bus_tag(pp, "cfg", PCI_CONFIG_BUS_SPACE));
    377      1.1     mrg }
    378      1.1     mrg 
    379      1.1     mrg bus_space_tag_t
    380      1.2     mrg pyro_alloc_bus_tag(struct pyro_pbm *pbm, const char *name, int type)
    381      1.1     mrg {
    382      1.1     mrg 	struct pyro_softc *sc = pbm->pp_sc;
    383      1.1     mrg 	struct sparc_bus_space_tag *bt;
    384      1.1     mrg 
    385      1.1     mrg 	bt = malloc(sizeof(*bt), M_DEVBUF, M_NOWAIT | M_ZERO);
    386      1.1     mrg 	if (bt == NULL)
    387      1.1     mrg 		panic("pyro: could not allocate bus tag");
    388      1.1     mrg 
    389      1.2     mrg #if 0
    390      1.1     mrg 	snprintf(bt->name, sizeof(bt->name), "%s-pbm_%s(%d/%2.2x)",
    391  1.5.2.1  cherry 	    device_xname(sc->sc_dev), name, ss, asi);
    392      1.2     mrg #endif
    393      1.1     mrg 
    394      1.1     mrg 	bt->cookie = pbm;
    395      1.2     mrg 	bt->parent = sc->sc_bustag;
    396      1.2     mrg 	bt->type = type;
    397      1.2     mrg 	bt->sparc_bus_map = pyro_bus_map;
    398      1.2     mrg 	bt->sparc_bus_mmap = pyro_bus_mmap;
    399      1.2     mrg 	bt->sparc_intr_establish = pyro_intr_establish;
    400      1.1     mrg 	return (bt);
    401      1.1     mrg }
    402      1.1     mrg 
    403      1.1     mrg bus_dma_tag_t
    404      1.1     mrg pyro_alloc_dma_tag(struct pyro_pbm *pbm)
    405      1.1     mrg {
    406      1.1     mrg 	struct pyro_softc *sc = pbm->pp_sc;
    407      1.1     mrg 	bus_dma_tag_t dt, pdt = sc->sc_dmat;
    408      1.1     mrg 
    409      1.1     mrg 	dt = malloc(sizeof(*dt), M_DEVBUF, M_NOWAIT | M_ZERO);
    410      1.1     mrg 	if (dt == NULL)
    411      1.1     mrg 		panic("pyro: could not alloc dma tag");
    412      1.1     mrg 
    413      1.1     mrg 	dt->_cookie = pbm;
    414      1.1     mrg 	dt->_parent = pdt;
    415      1.2     mrg #define PCOPY(x)	dt->x = pdt->x
    416      1.1     mrg 	dt->_dmamap_create	= pyro_dmamap_create;
    417      1.2     mrg 	PCOPY(_dmamap_destroy);
    418      1.1     mrg 	dt->_dmamap_load	= iommu_dvmamap_load;
    419      1.2     mrg 	PCOPY(_dmamap_load_mbuf);
    420      1.2     mrg 	PCOPY(_dmamap_load_uio);
    421      1.1     mrg 	dt->_dmamap_load_raw	= iommu_dvmamap_load_raw;
    422      1.1     mrg 	dt->_dmamap_unload	= iommu_dvmamap_unload;
    423      1.1     mrg 	dt->_dmamap_sync	= iommu_dvmamap_sync;
    424      1.1     mrg 	dt->_dmamem_alloc	= iommu_dvmamem_alloc;
    425      1.1     mrg 	dt->_dmamem_free	= iommu_dvmamem_free;
    426      1.2     mrg 	dt->_dmamem_map = iommu_dvmamem_map;
    427      1.2     mrg 	dt->_dmamem_unmap = iommu_dvmamem_unmap;
    428      1.2     mrg 	PCOPY(_dmamem_mmap);
    429      1.2     mrg #undef	PCOPY
    430      1.1     mrg 	return (dt);
    431      1.1     mrg }
    432      1.1     mrg 
    433      1.1     mrg pci_chipset_tag_t
    434      1.1     mrg pyro_alloc_chipset(struct pyro_pbm *pbm, int node, pci_chipset_tag_t pc)
    435      1.1     mrg {
    436      1.1     mrg 	pci_chipset_tag_t npc;
    437      1.1     mrg 
    438      1.1     mrg 	npc = malloc(sizeof *npc, M_DEVBUF, M_NOWAIT);
    439      1.1     mrg 	if (npc == NULL)
    440      1.1     mrg 		panic("pyro: could not allocate pci_chipset_tag_t");
    441      1.1     mrg 	memcpy(npc, pc, sizeof *pc);
    442      1.1     mrg 	npc->cookie = pbm;
    443      1.1     mrg 	npc->rootnode = node;
    444      1.2     mrg 	npc->spc_conf_read = pyro_conf_read;
    445      1.2     mrg 	npc->spc_conf_write = pyro_conf_write;
    446      1.2     mrg 	npc->spc_intr_map = pyro_intr_map;
    447      1.2     mrg 	npc->spc_intr_establish = pyro_pci_intr_establish;
    448      1.2     mrg 	npc->spc_find_ino = NULL;
    449      1.1     mrg 	return (npc);
    450      1.1     mrg }
    451      1.1     mrg 
    452      1.1     mrg int
    453      1.2     mrg pyro_dmamap_create(bus_dma_tag_t t, bus_size_t size,
    454      1.1     mrg     int nsegments, bus_size_t maxsegsz, bus_size_t boundary, int flags,
    455      1.1     mrg     bus_dmamap_t *dmamp)
    456      1.1     mrg {
    457      1.2     mrg 	struct pyro_pbm *pbm = t->_cookie;
    458      1.2     mrg 	int error;
    459      1.1     mrg 
    460      1.2     mrg 	error = bus_dmamap_create(t->_parent, size, nsegments, maxsegsz,
    461      1.2     mrg 				  boundary, flags, dmamp);
    462      1.2     mrg 	if (error == 0)
    463      1.2     mrg 		(*dmamp)->_dm_cookie = &pbm->pp_sb;
    464      1.2     mrg 	return error;
    465      1.1     mrg }
    466      1.1     mrg 
    467      1.1     mrg int
    468      1.2     mrg pyro_bus_map(bus_space_tag_t t, bus_addr_t offset,
    469      1.2     mrg     bus_size_t size, int flags, vaddr_t unused, bus_space_handle_t *hp)
    470      1.1     mrg {
    471      1.1     mrg 	struct pyro_pbm *pbm = t->cookie;
    472      1.2     mrg 	struct pyro_softc *sc = pbm->pp_sc;
    473      1.1     mrg 	int i, ss;
    474      1.1     mrg 
    475      1.2     mrg 	DPRINTF(PDB_BUSMAP, ("pyro_bus_map: type %d off %qx sz %qx flags %d",
    476      1.2     mrg 	    t->type,
    477      1.1     mrg 	    (unsigned long long)offset,
    478      1.1     mrg 	    (unsigned long long)size,
    479      1.1     mrg 	    flags));
    480      1.1     mrg 
    481      1.2     mrg 	ss = sparc_pci_childspace(t->type);
    482      1.1     mrg 	DPRINTF(PDB_BUSMAP, (" cspace %d", ss));
    483      1.1     mrg 
    484      1.1     mrg 	if (t->parent == 0 || t->parent->sparc_bus_map == 0) {
    485      1.1     mrg 		printf("\n_pyro_bus_map: invalid parent");
    486      1.1     mrg 		return (EINVAL);
    487      1.1     mrg 	}
    488      1.1     mrg 
    489      1.1     mrg 	for (i = 0; i < pbm->pp_nrange; i++) {
    490      1.1     mrg 		bus_addr_t paddr;
    491      1.2     mrg 		struct pyro_range *pr = &pbm->pp_range[i];
    492      1.1     mrg 
    493      1.2     mrg 		if (((pr->cspace >> 24) & 0x03) != ss)
    494      1.1     mrg 			continue;
    495      1.1     mrg 
    496      1.2     mrg 		paddr = BUS_ADDR(pr->phys_hi, pr->phys_lo + offset);
    497      1.2     mrg 		return ((*sc->sc_bustag->sparc_bus_map)(t, paddr, size,
    498      1.2     mrg 			flags, 0, hp));
    499      1.1     mrg 	}
    500      1.1     mrg 
    501      1.1     mrg 	return (EINVAL);
    502      1.1     mrg }
    503      1.1     mrg 
    504      1.1     mrg paddr_t
    505      1.2     mrg pyro_bus_mmap(bus_space_tag_t t, bus_addr_t paddr,
    506      1.1     mrg     off_t off, int prot, int flags)
    507      1.1     mrg {
    508      1.1     mrg 	bus_addr_t offset = paddr;
    509      1.1     mrg 	struct pyro_pbm *pbm = t->cookie;
    510      1.2     mrg 	struct pyro_softc *sc = pbm->pp_sc;
    511      1.1     mrg 	int i, ss;
    512      1.1     mrg 
    513      1.2     mrg 	ss = sparc_pci_childspace(t->type);
    514      1.1     mrg 
    515      1.2     mrg 	DPRINTF(PDB_BUSMAP, ("pyro_bus_mmap: prot %d flags %d pa %qx\n",
    516      1.1     mrg 	    prot, flags, (unsigned long long)paddr));
    517      1.1     mrg 
    518      1.1     mrg 	if (t->parent == 0 || t->parent->sparc_bus_mmap == 0) {
    519      1.1     mrg 		printf("\n_pyro_bus_mmap: invalid parent");
    520      1.1     mrg 		return (-1);
    521      1.1     mrg 	}
    522      1.1     mrg 
    523      1.1     mrg 	for (i = 0; i < pbm->pp_nrange; i++) {
    524      1.2     mrg 		struct pyro_range *pr = &pbm->pp_range[i];
    525      1.1     mrg 
    526      1.2     mrg 		if (((pr->cspace >> 24) & 0x03) != ss)
    527      1.1     mrg 			continue;
    528      1.1     mrg 
    529      1.2     mrg 		paddr = BUS_ADDR(pr->phys_hi, pr->phys_lo + offset);
    530      1.2     mrg 		return (bus_space_mmap(sc->sc_bustag, paddr, off,
    531      1.2     mrg 				       prot, flags));
    532      1.1     mrg 	}
    533      1.1     mrg 
    534      1.1     mrg 	return (-1);
    535      1.1     mrg }
    536      1.1     mrg 
    537      1.1     mrg void *
    538      1.2     mrg pyro_intr_establish(bus_space_tag_t t, int ihandle, int level,
    539      1.2     mrg 	int (*handler)(void *), void *arg, void (*fastvec)(void) /* ignored */)
    540      1.1     mrg {
    541      1.1     mrg 	struct pyro_pbm *pbm = t->cookie;
    542      1.1     mrg 	struct pyro_softc *sc = pbm->pp_sc;
    543      1.1     mrg 	struct intrhand *ih = NULL;
    544      1.1     mrg 	volatile u_int64_t *intrmapptr = NULL, *intrclrptr = NULL;
    545      1.3     mrg 	u_int64_t *imapbase, *iclrbase;
    546      1.1     mrg 	int ino;
    547      1.1     mrg 
    548      1.1     mrg 	ino = INTINO(ihandle);
    549      1.2     mrg 	DPRINTF(PDB_INTR, ("%s: ih %lx; level %d ino %d", __func__, (u_long)ih, level, ino));
    550      1.1     mrg 
    551      1.1     mrg 	if (level == IPL_NONE)
    552      1.1     mrg 		level = INTLEV(ihandle);
    553      1.1     mrg 	if (level == IPL_NONE) {
    554      1.1     mrg 		printf(": no IPL, setting IPL 2.\n");
    555      1.1     mrg 		level = 2;
    556      1.1     mrg 	}
    557      1.1     mrg 
    558      1.3     mrg 	imapbase = (uint64_t *)((uintptr_t)bus_space_vaddr(sc->sc_bustag, sc->sc_csrh) + 0x1000);
    559      1.3     mrg 	iclrbase = (uint64_t *)((uintptr_t)bus_space_vaddr(sc->sc_bustag, sc->sc_csrh) + 0x1400);
    560      1.3     mrg 	intrmapptr = &imapbase[ino];
    561      1.3     mrg 	intrclrptr = &iclrbase[ino];
    562      1.3     mrg 	DPRINTF(PDB_INTR, (" imapbase %p iclrbase %p mapptr %p clrptr %p\n", imapbase, iclrbase, intrmapptr, intrclrptr));
    563      1.2     mrg 	ino |= INTVEC(ihandle);
    564      1.1     mrg 
    565      1.2     mrg 	ih = malloc(sizeof *ih, M_DEVBUF, M_NOWAIT);
    566      1.1     mrg 	if (ih == NULL)
    567      1.1     mrg 		return (NULL);
    568      1.1     mrg 
    569      1.2     mrg 	/* Register the map and clear intr registers */
    570      1.2     mrg 	ih->ih_map = intrmapptr;
    571      1.2     mrg 	ih->ih_clr = intrclrptr;
    572      1.2     mrg 
    573      1.2     mrg 	ih->ih_fun = handler;
    574      1.2     mrg 	ih->ih_arg = arg;
    575      1.2     mrg 	ih->ih_pil = level;
    576      1.2     mrg 	ih->ih_number = ino;
    577      1.2     mrg 
    578      1.2     mrg 	intr_establish(ih->ih_pil, level != IPL_VM, ih);
    579      1.1     mrg 
    580      1.1     mrg 	if (intrmapptr != NULL) {
    581      1.3     mrg 		u_int64_t imap;
    582      1.1     mrg 
    583      1.3     mrg 		imap = *intrmapptr;
    584      1.3     mrg 		DPRINTF(PDB_INTR, ("%s: read intrmap = %016qx", __func__,
    585      1.3     mrg 			(unsigned long long)imap));
    586      1.3     mrg 		imap &= ~FIRE_INTRMAP_INT_CNTRL_NUM_MASK;
    587      1.3     mrg 		imap |= FIRE_INTRMAP_INT_CNTRL_NUM0;
    588      1.3     mrg 		DPRINTF(PDB_INTR, ("; set intr group intrmap = %016qx",
    589      1.3     mrg 			(unsigned long long)imap));
    590      1.1     mrg 		if (sc->sc_oberon) {
    591      1.3     mrg 			imap &= ~OBERON_INTRMAP_T_DESTID_MASK;
    592      1.3     mrg 			imap |= CPU_JUPITERID <<
    593      1.1     mrg 			    OBERON_INTRMAP_T_DESTID_SHIFT;
    594      1.1     mrg 		} else {
    595      1.3     mrg 			imap &= ~FIRE_INTRMAP_T_JPID_MASK;
    596      1.3     mrg 			imap |= CPU_UPAID << FIRE_INTRMAP_T_JPID_SHIFT;
    597      1.1     mrg 		}
    598      1.3     mrg 		DPRINTF(PDB_INTR, ("; set cpuid num intrmap = %016qx",
    599      1.3     mrg 			(unsigned long long)imap));
    600      1.3     mrg 		imap |= INTMAP_V;
    601      1.3     mrg 		*intrmapptr = imap;
    602      1.3     mrg 		DPRINTF(PDB_INTR, ("; writing intrmap = %016qx",
    603      1.3     mrg 			(unsigned long long)imap));
    604      1.3     mrg 		imap = *intrmapptr;
    605      1.3     mrg 		DPRINTF(PDB_INTR, ("; reread intrmap = %016qx\n",
    606      1.3     mrg 			(unsigned long long)imap));
    607      1.3     mrg 		ih->ih_number |= imap & INTMAP_INR;
    608      1.2     mrg 	}
    609      1.2     mrg  	if (intrclrptr) {
    610      1.2     mrg  		/* set state to IDLE */
    611      1.2     mrg 		*intrclrptr = 0;
    612      1.2     mrg  	}
    613      1.1     mrg 
    614      1.1     mrg 	return (ih);
    615      1.1     mrg }
    616      1.1     mrg 
    617      1.2     mrg static void *
    618      1.2     mrg pyro_pci_intr_establish(pci_chipset_tag_t pc, pci_intr_handle_t ih, int level,
    619      1.2     mrg 	int (*func)(void *), void *arg)
    620      1.2     mrg {
    621      1.2     mrg 	void *cookie;
    622      1.2     mrg 	struct pyro_pbm *pbm = (struct pyro_pbm *)pc->cookie;
    623      1.2     mrg 
    624      1.3     mrg 	DPRINTF(PDB_INTR, ("%s: ih %lx; level %d\n", __func__, (u_long)ih, level));
    625      1.2     mrg 	cookie = bus_intr_establish(pbm->pp_memt, ih, level, func, arg);
    626      1.2     mrg 
    627      1.3     mrg 	DPRINTF(PDB_INTR, ("%s: returning handle %p\n", __func__, cookie));
    628      1.2     mrg 	return (cookie);
    629      1.2     mrg }
    630