Home | History | Annotate | Line # | Download | only in dev
vme_machdep.c revision 1.5
      1  1.5       pk /*	$NetBSD: vme_machdep.c,v 1.5 1998/02/06 00:24:42 pk Exp $	*/
      2  1.1       pk 
      3  1.1       pk /*-
      4  1.4  thorpej  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
      5  1.1       pk  * All rights reserved.
      6  1.1       pk  *
      7  1.1       pk  * This code is derived from software contributed to The NetBSD Foundation
      8  1.1       pk  * by Paul Kranenburg.
      9  1.1       pk  *
     10  1.1       pk  * Redistribution and use in source and binary forms, with or without
     11  1.1       pk  * modification, are permitted provided that the following conditions
     12  1.1       pk  * are met:
     13  1.1       pk  * 1. Redistributions of source code must retain the above copyright
     14  1.1       pk  *    notice, this list of conditions and the following disclaimer.
     15  1.1       pk  * 2. Redistributions in binary form must reproduce the above copyright
     16  1.1       pk  *    notice, this list of conditions and the following disclaimer in the
     17  1.1       pk  *    documentation and/or other materials provided with the distribution.
     18  1.1       pk  * 3. All advertising materials mentioning features or use of this software
     19  1.1       pk  *    must display the following acknowledgement:
     20  1.1       pk  *        This product includes software developed by the NetBSD
     21  1.1       pk  *        Foundation, Inc. and its contributors.
     22  1.1       pk  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23  1.1       pk  *    contributors may be used to endorse or promote products derived
     24  1.1       pk  *    from this software without specific prior written permission.
     25  1.1       pk  *
     26  1.1       pk  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27  1.1       pk  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28  1.1       pk  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29  1.1       pk  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30  1.1       pk  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31  1.1       pk  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32  1.1       pk  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33  1.1       pk  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34  1.1       pk  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35  1.1       pk  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36  1.1       pk  * POSSIBILITY OF SUCH DAMAGE.
     37  1.1       pk  */
     38  1.1       pk 
     39  1.1       pk #include <sys/param.h>
     40  1.1       pk #include <sys/systm.h>
     41  1.1       pk #include <sys/device.h>
     42  1.1       pk #include <sys/malloc.h>
     43  1.1       pk 
     44  1.1       pk #include <sys/proc.h>
     45  1.1       pk #include <sys/user.h>
     46  1.1       pk #include <sys/syslog.h>
     47  1.1       pk 
     48  1.1       pk #include <vm/vm.h>
     49  1.1       pk 
     50  1.1       pk #define _SPARC_BUS_DMA_PRIVATE
     51  1.1       pk #include <machine/bus.h>
     52  1.1       pk #include <machine/autoconf.h>
     53  1.1       pk #include <machine/pmap.h>
     54  1.1       pk #include <machine/oldmon.h>
     55  1.1       pk #include <machine/cpu.h>
     56  1.1       pk #include <machine/ctlreg.h>
     57  1.1       pk 
     58  1.1       pk #include <dev/vme/vmevar.h>
     59  1.1       pk 
     60  1.1       pk #include <sparc/sparc/asm.h>
     61  1.1       pk #include <sparc/sparc/vaddrs.h>
     62  1.1       pk #include <sparc/sparc/cpuvar.h>
     63  1.1       pk #include <sparc/dev/vmereg.h>
     64  1.1       pk 
     65  1.1       pk struct vmebus_softc {
     66  1.1       pk 	struct device	 sc_dev;	/* base device */
     67  1.1       pk 	struct vmebusreg *sc_reg; 	/* VME control registers */
     68  1.1       pk 	struct vmebusvec *sc_vec;	/* VME interrupt vector */
     69  1.1       pk 	struct rom_range *sc_range;	/* ROM range property */
     70  1.1       pk 	int		 sc_nrange;
     71  1.1       pk 	volatile u_int32_t *sc_ioctags;	/* VME IO-cache tag registers */
     72  1.1       pk 	volatile u_int32_t *sc_iocflush;/* VME IO-cache flush registers */
     73  1.1       pk 	int 		 (*sc_vmeintr) __P((void *));
     74  1.1       pk 	struct bootpath	 *sc_bp;
     75  1.1       pk };
     76  1.1       pk struct  vmebus_softc *vmebus_sc;/*XXX*/
     77  1.1       pk 
     78  1.1       pk /* autoconfiguration driver */
     79  1.1       pk static int	vmematch    __P((struct device *, struct cfdata *, void *));
     80  1.1       pk static void	vmeattach   __P((struct device *, struct device *, void *));
     81  1.1       pk #if defined(SUN4)
     82  1.1       pk static void	vmeattach4  __P((struct device *, struct device *, void *));
     83  1.1       pk int 		vmeintr4  __P((void *));
     84  1.1       pk #endif
     85  1.1       pk #if defined(SUN4M)
     86  1.1       pk static void	vmeattach4m __P((struct device *, struct device *, void *));
     87  1.1       pk int 		vmeintr4m __P((void *));
     88  1.1       pk #endif
     89  1.1       pk 
     90  1.1       pk 
     91  1.1       pk static int	sparc_vme_probe __P((void *, bus_space_tag_t, vme_addr_t,
     92  1.5       pk 				     size_t, vme_size_t, vme_mod_t,
     93  1.2       pk 				     int (*) __P((void *, void *)), void *));
     94  1.1       pk static int	sparc_vme_map __P((void *, vme_addr_t, vme_size_t, vme_mod_t,
     95  1.1       pk 				   bus_space_tag_t, bus_space_handle_t *));
     96  1.1       pk static void	sparc_vme_unmap __P((void *));
     97  1.1       pk static int	sparc_vme_mmap_cookie __P((void *, vme_addr_t, vme_mod_t,
     98  1.1       pk 				   bus_space_tag_t, int *));
     99  1.1       pk static int	sparc_vme_intr_map __P((void *, int, int, vme_intr_handle_t *));
    100  1.1       pk static void *	sparc_vme_intr_establish __P((void *, vme_intr_handle_t,
    101  1.1       pk 					      int (*) __P((void *)), void *));
    102  1.1       pk static void	sparc_vme_intr_disestablish __P((void *, void *));
    103  1.1       pk 
    104  1.1       pk static void	vmebus_translate __P((struct vmebus_softc *, vme_mod_t,
    105  1.1       pk 				      struct rom_reg *));
    106  1.1       pk static void	sparc_vme_bus_establish __P((void *, struct device *));
    107  1.1       pk #if defined(SUN4M)
    108  1.1       pk static void	sparc_vme4m_barrier __P((void *));
    109  1.1       pk #endif
    110  1.1       pk 
    111  1.1       pk /*
    112  1.1       pk  * DMA functions.
    113  1.1       pk  */
    114  1.1       pk #if defined(SUN4)
    115  1.1       pk static int	sparc_vme4_dmamap_load __P((bus_dma_tag_t, bus_dmamap_t, void *,
    116  1.1       pk 		    bus_size_t, struct proc *, int));
    117  1.1       pk static void	sparc_vme4_dmamap_unload __P((bus_dma_tag_t, bus_dmamap_t));
    118  1.1       pk static void	sparc_vme4_dmamap_sync __P((bus_dma_tag_t, bus_dmamap_t,
    119  1.4  thorpej 		    bus_addr_t, bus_size_t, int));
    120  1.1       pk 
    121  1.1       pk static int	sparc_vme4_dmamem_alloc __P((bus_dma_tag_t, bus_size_t,
    122  1.1       pk 		    bus_size_t, bus_size_t, bus_dma_segment_t *,
    123  1.1       pk 		    int, int *, int));
    124  1.1       pk static void	sparc_vme4_dmamem_free __P((bus_dma_tag_t,
    125  1.1       pk 		    bus_dma_segment_t *, int));
    126  1.1       pk #endif
    127  1.1       pk 
    128  1.1       pk #if defined(SUN4M)
    129  1.1       pk static int	sparc_vme4m_dmamap_create __P((bus_dma_tag_t, bus_size_t, int,
    130  1.1       pk 		    bus_size_t, bus_size_t, int, bus_dmamap_t *));
    131  1.1       pk 
    132  1.1       pk static int	sparc_vme4m_dmamap_load __P((bus_dma_tag_t, bus_dmamap_t, void *,
    133  1.1       pk 		    bus_size_t, struct proc *, int));
    134  1.1       pk static void	sparc_vme4m_dmamap_unload __P((bus_dma_tag_t, bus_dmamap_t));
    135  1.1       pk static void	sparc_vme4m_dmamap_sync __P((bus_dma_tag_t, bus_dmamap_t,
    136  1.4  thorpej 		    bus_addr_t, bus_size_t, int));
    137  1.1       pk 
    138  1.1       pk static int	sparc_vme4m_dmamem_alloc __P((bus_dma_tag_t, bus_size_t,
    139  1.1       pk 		    bus_size_t, bus_size_t, bus_dma_segment_t *,
    140  1.1       pk 		    int, int *, int));
    141  1.1       pk static void	sparc_vme4m_dmamem_free __P((bus_dma_tag_t,
    142  1.1       pk 		    bus_dma_segment_t *, int));
    143  1.1       pk #endif
    144  1.1       pk 
    145  1.1       pk #if 0
    146  1.1       pk static void	sparc_vme_dmamap_destroy __P((bus_dma_tag_t, bus_dmamap_t));
    147  1.1       pk static int	sparc_vme_dmamem_map __P((bus_dma_tag_t, bus_dma_segment_t *,
    148  1.1       pk 		    int, size_t, caddr_t *, int));
    149  1.1       pk static void	sparc_vme_dmamem_unmap __P((bus_dma_tag_t, caddr_t, size_t));
    150  1.1       pk static int	sparc_vme_dmamem_mmap __P((bus_dma_tag_t,
    151  1.1       pk 		    bus_dma_segment_t *, int, int, int, int));
    152  1.1       pk #endif
    153  1.1       pk 
    154  1.1       pk struct cfattach vme_ca = {
    155  1.1       pk 	sizeof(struct vmebus_softc), vmematch, vmeattach
    156  1.1       pk };
    157  1.1       pk 
    158  1.1       pk struct sparc_bus_space_tag sparc_vme_bus_tag = {
    159  1.1       pk 	NULL, /* cookie */
    160  1.1       pk 	NULL, /* bus_map */
    161  1.1       pk 	NULL, /* bus_unmap */
    162  1.1       pk 	NULL, /* bus_subregion */
    163  1.1       pk 	NULL  /* barrier */
    164  1.1       pk };
    165  1.1       pk 
    166  1.1       pk struct vme_chipset_tag sparc_vme_chipset_tag = {
    167  1.1       pk 	NULL,
    168  1.1       pk 	sparc_vme_probe,
    169  1.1       pk 	sparc_vme_map,
    170  1.1       pk 	sparc_vme_unmap,
    171  1.1       pk 	sparc_vme_mmap_cookie,
    172  1.1       pk 	sparc_vme_intr_map,
    173  1.1       pk 	sparc_vme_intr_establish,
    174  1.1       pk 	sparc_vme_intr_disestablish,
    175  1.1       pk 	sparc_vme_bus_establish
    176  1.1       pk };
    177  1.1       pk 
    178  1.1       pk 
    179  1.1       pk #if defined(SUN4)
    180  1.1       pk struct sparc_bus_dma_tag sparc_vme4_dma_tag = {
    181  1.1       pk 	NULL,	/* cookie */
    182  1.1       pk 	_bus_dmamap_create,
    183  1.1       pk 	_bus_dmamap_destroy,
    184  1.1       pk 	sparc_vme4_dmamap_load,
    185  1.1       pk 	_bus_dmamap_load_mbuf,
    186  1.1       pk 	_bus_dmamap_load_uio,
    187  1.1       pk 	_bus_dmamap_load_raw,
    188  1.1       pk 	sparc_vme4_dmamap_unload,
    189  1.1       pk 	sparc_vme4_dmamap_sync,
    190  1.1       pk 
    191  1.1       pk 	sparc_vme4_dmamem_alloc,
    192  1.1       pk 	sparc_vme4_dmamem_free,
    193  1.1       pk 	_bus_dmamem_map,
    194  1.1       pk 	_bus_dmamem_unmap,
    195  1.1       pk 	_bus_dmamem_mmap
    196  1.1       pk };
    197  1.1       pk #endif
    198  1.1       pk 
    199  1.1       pk #if defined(SUN4M)
    200  1.1       pk struct sparc_bus_dma_tag sparc_vme4m_dma_tag = {
    201  1.1       pk 	NULL,	/* cookie */
    202  1.1       pk 	sparc_vme4m_dmamap_create,
    203  1.1       pk 	_bus_dmamap_destroy,
    204  1.1       pk 	sparc_vme4m_dmamap_load,
    205  1.1       pk 	_bus_dmamap_load_mbuf,
    206  1.1       pk 	_bus_dmamap_load_uio,
    207  1.1       pk 	_bus_dmamap_load_raw,
    208  1.1       pk 	sparc_vme4m_dmamap_unload,
    209  1.1       pk 	sparc_vme4m_dmamap_sync,
    210  1.1       pk 
    211  1.1       pk 	sparc_vme4m_dmamem_alloc,
    212  1.1       pk 	sparc_vme4m_dmamem_free,
    213  1.1       pk 	_bus_dmamem_map,
    214  1.1       pk 	_bus_dmamem_unmap,
    215  1.1       pk 	_bus_dmamem_mmap
    216  1.1       pk };
    217  1.1       pk #endif
    218  1.1       pk 
    219  1.1       pk 
    220  1.1       pk void
    221  1.1       pk sparc_vme_bus_establish(cookie, dev)
    222  1.1       pk 	void *cookie;
    223  1.1       pk 	struct device *dev;
    224  1.1       pk {
    225  1.1       pk 	struct vmebus_softc *sc = (struct vmebus_softc *)cookie;
    226  1.1       pk 	struct bootpath *bp = sc->sc_bp;
    227  1.1       pk 	char *name;
    228  1.1       pk 
    229  1.1       pk 	name = dev->dv_cfdata->cf_driver->cd_name;
    230  1.1       pk #ifdef DEBUG
    231  1.1       pk 	printf("sparc_vme_bus_establish: %s%d\n", name, dev->dv_unit);
    232  1.1       pk #endif
    233  1.1       pk 	if (bp != NULL && strcmp(bp->name, name) == 0 &&
    234  1.1       pk 	    dev->dv_unit == bp->val[1]) {
    235  1.1       pk 		bp->dev = dev;
    236  1.1       pk #ifdef DEBUG
    237  1.1       pk printf("sparc_vme_bus_establish: on the boot path\n");
    238  1.1       pk #endif
    239  1.1       pk 		sc->sc_bp++;
    240  1.1       pk 		bootpath_store(1, sc->sc_bp);
    241  1.1       pk 	}
    242  1.1       pk }
    243  1.1       pk 
    244  1.1       pk 
    245  1.1       pk int
    246  1.1       pk vmematch(parent, cf, aux)
    247  1.1       pk 	struct device *parent;
    248  1.1       pk 	struct cfdata *cf;
    249  1.1       pk 	void *aux;
    250  1.1       pk {
    251  1.1       pk 	register struct confargs *ca = aux;
    252  1.1       pk 	register struct romaux *ra = &ca->ca_ra;
    253  1.1       pk 
    254  1.1       pk 	if (CPU_ISSUN4C)
    255  1.1       pk 		return (0);
    256  1.1       pk 
    257  1.1       pk 	return (strcmp(cf->cf_driver->cd_name, ra->ra_name) == 0);
    258  1.1       pk }
    259  1.1       pk 
    260  1.1       pk void
    261  1.1       pk vmeattach(parent, self, aux)
    262  1.1       pk 	struct device *parent, *self;
    263  1.1       pk 	void *aux;
    264  1.1       pk {
    265  1.1       pk 	struct vmebus_softc *sc = (struct vmebus_softc *)self;
    266  1.1       pk 	struct confargs *ca = aux;
    267  1.1       pk 	register struct romaux *ra = &ca->ca_ra;
    268  1.1       pk 
    269  1.1       pk 	if (ra->ra_bp != NULL && strcmp(ra->ra_bp->name, "vme") == 0) {
    270  1.1       pk 		sc->sc_bp = ra->ra_bp + 1;
    271  1.1       pk 		bootpath_store(1, sc->sc_bp);
    272  1.1       pk 	}
    273  1.1       pk 
    274  1.1       pk #if defined(SUN4)
    275  1.1       pk 	if (CPU_ISSUN4)
    276  1.1       pk 		vmeattach4(parent, self, aux);
    277  1.1       pk #endif
    278  1.1       pk 
    279  1.1       pk #if defined(SUN4M)
    280  1.1       pk 	if (CPU_ISSUN4M)
    281  1.1       pk 		vmeattach4m(parent, self, aux);
    282  1.1       pk #endif
    283  1.1       pk 
    284  1.1       pk 	bootpath_store(1, NULL);
    285  1.1       pk }
    286  1.1       pk 
    287  1.1       pk #if defined(SUN4)
    288  1.1       pk void
    289  1.1       pk vmeattach4(parent, self, aux)
    290  1.1       pk 	struct device *parent, *self;
    291  1.1       pk 	void *aux;
    292  1.1       pk {
    293  1.1       pk 	struct vmebus_softc *sc = (struct vmebus_softc *)self;
    294  1.1       pk 	struct vme_busattach_args vba;
    295  1.1       pk 
    296  1.1       pk 	if (self->dv_unit > 0) {
    297  1.1       pk 		printf(" unsupported\n");
    298  1.1       pk 		return;
    299  1.1       pk 	}
    300  1.1       pk 
    301  1.1       pk 	/* VME interrupt entry point */
    302  1.1       pk 	sc->sc_vmeintr = vmeintr4;
    303  1.1       pk 
    304  1.1       pk /*XXX*/	sparc_vme_chipset_tag.cookie = self;
    305  1.1       pk /*XXX*/	sparc_vme4_dma_tag._cookie = self;
    306  1.1       pk 
    307  1.1       pk 	vba.vba_bustag = &sparc_vme_bus_tag;
    308  1.1       pk 	vba.vba_chipset_tag = &sparc_vme_chipset_tag;
    309  1.1       pk 	vba.vba_dmatag = &sparc_vme4_dma_tag;
    310  1.1       pk 
    311  1.1       pk 	printf("\n");
    312  1.1       pk 	(void)config_search(vmesearch, self, &vba);
    313  1.1       pk 	return;
    314  1.1       pk }
    315  1.1       pk #endif
    316  1.1       pk 
    317  1.1       pk #if defined(SUN4M)
    318  1.1       pk /* sun4m vmebus */
    319  1.1       pk void
    320  1.1       pk vmeattach4m(parent, self, aux)
    321  1.1       pk 	struct device *parent, *self;
    322  1.1       pk 	void *aux;
    323  1.1       pk {
    324  1.1       pk 	struct vmebus_softc *sc = (struct vmebus_softc *)self;
    325  1.1       pk 	struct confargs *ca = aux;
    326  1.1       pk 	register struct romaux *ra = &ca->ca_ra;
    327  1.1       pk 	int node, rlen;
    328  1.1       pk 	struct vme_busattach_args vba;
    329  1.1       pk 	int cline;
    330  1.1       pk 
    331  1.1       pk 	if (self->dv_unit > 0) {
    332  1.1       pk 		printf(" unsupported\n");
    333  1.1       pk 		return;
    334  1.1       pk 	}
    335  1.1       pk 
    336  1.1       pk 	/* VME interrupt entry point */
    337  1.1       pk 	sc->sc_vmeintr = vmeintr4m;
    338  1.1       pk 
    339  1.1       pk /*XXX*/	sparc_vme_chipset_tag.cookie = self;
    340  1.1       pk /*XXX*/	sparc_vme4m_dma_tag._cookie = self;
    341  1.1       pk 	sparc_vme_bus_tag.sparc_barrier = sparc_vme4m_barrier;
    342  1.1       pk 
    343  1.1       pk 	vba.vba_bustag = &sparc_vme_bus_tag;
    344  1.1       pk 	vba.vba_chipset_tag = &sparc_vme_chipset_tag;
    345  1.1       pk 	vba.vba_dmatag = &sparc_vme4m_dma_tag;
    346  1.1       pk 
    347  1.1       pk 	node = ra->ra_node;
    348  1.1       pk 
    349  1.1       pk 	/* Map VME control space */
    350  1.1       pk 	sc->sc_reg = (struct vmebusreg *)
    351  1.1       pk 		mapdev(&ra->ra_reg[0], 0, 0, ra->ra_reg[0].rr_len);
    352  1.1       pk 	sc->sc_vec = (struct vmebusvec *)
    353  1.1       pk 		mapdev(&ra->ra_reg[1], 0, 0, ra->ra_reg[1].rr_len);
    354  1.1       pk 	sc->sc_ioctags = (u_int32_t *)
    355  1.1       pk 		mapdev(&ra->ra_reg[1], 0, VME_IOC_TAGOFFSET, VME_IOC_SIZE);
    356  1.1       pk 	sc->sc_iocflush = (u_int32_t *)
    357  1.1       pk 		mapdev(&ra->ra_reg[1], 0, VME_IOC_FLUSHOFFSET, VME_IOC_SIZE);
    358  1.1       pk 
    359  1.1       pk /*XXX*/	sparc_vme_bus_tag.cookie = sc->sc_reg;
    360  1.1       pk 
    361  1.1       pk 	/*
    362  1.1       pk 	 * Get "range" property.
    363  1.1       pk 	 */
    364  1.1       pk 	rlen = getproplen(node, "ranges");
    365  1.1       pk 	if (rlen > 0) {
    366  1.1       pk 		sc->sc_nrange = rlen / sizeof(struct rom_range);
    367  1.1       pk 		sc->sc_range =
    368  1.1       pk 			(struct rom_range *)malloc(rlen, M_DEVBUF, M_NOWAIT);
    369  1.1       pk 		if (sc->sc_range == 0)
    370  1.1       pk 			panic("vme: PROM ranges too large: %d", rlen);
    371  1.1       pk 		(void)getprop(node, "ranges", sc->sc_range, rlen);
    372  1.1       pk 	}
    373  1.1       pk 
    374  1.1       pk 	vmebus_sc = sc;
    375  1.1       pk 
    376  1.1       pk 	/*
    377  1.1       pk 	 * Invalidate all IO-cache entries.
    378  1.1       pk 	 */
    379  1.1       pk 	for (cline = VME_IOC_SIZE/VME_IOC_LINESZ; cline > 0;) {
    380  1.1       pk 		sc->sc_ioctags[--cline] = 0;
    381  1.1       pk 	}
    382  1.1       pk 
    383  1.1       pk 	/* Enable IO-cache */
    384  1.1       pk 	sc->sc_reg->vmebus_cr |= VMEBUS_CR_C;
    385  1.1       pk 
    386  1.1       pk 	printf(": version 0x%x\n",
    387  1.1       pk 	       sc->sc_reg->vmebus_cr & VMEBUS_CR_IMPL);
    388  1.1       pk 
    389  1.1       pk 	(void)config_search(vmesearch, self, &vba);
    390  1.1       pk }
    391  1.1       pk #endif
    392  1.1       pk 
    393  1.1       pk void sparc_vme_async_fault __P((void));
    394  1.1       pk void
    395  1.1       pk sparc_vme_async_fault()
    396  1.1       pk {
    397  1.1       pk 	struct vmebus_softc *sc = vmebus_sc;
    398  1.1       pk 	u_int32_t addr;
    399  1.1       pk 
    400  1.1       pk 	addr = sc->sc_reg->vmebus_afar;
    401  1.1       pk 	printf("vme afsr: %x; addr %x\n", sc->sc_reg->vmebus_afsr, addr);
    402  1.1       pk }
    403  1.1       pk 
    404  1.1       pk int
    405  1.5       pk sparc_vme_probe(cookie, tag, addr, offset, size, mod, callback, arg)
    406  1.1       pk 	void *cookie;
    407  1.1       pk 	bus_space_tag_t tag;
    408  1.1       pk 	vme_addr_t addr;
    409  1.5       pk 	size_t offset;
    410  1.1       pk 	vme_size_t size;
    411  1.1       pk 	int mod;
    412  1.2       pk 	int (*callback) __P((void *, void *));
    413  1.2       pk 	void *arg;
    414  1.1       pk {
    415  1.1       pk 	struct rom_reg reg;
    416  1.1       pk 	caddr_t tmp;
    417  1.1       pk 	int result;
    418  1.1       pk 	struct vmebus_softc *sc = (struct vmebus_softc *)cookie;
    419  1.1       pk 
    420  1.1       pk /* XXX - Use bus_space_[un]map() etc. */
    421  1.1       pk 	reg.rr_paddr = (void *)addr;
    422  1.1       pk 	vmebus_translate(sc, mod, &reg);
    423  1.1       pk 	tmp = (caddr_t)mapdev(&reg, TMPMAP_VA, 0, NBPG);
    424  1.5       pk 	result = probeget(tmp + offset, size) != -1;
    425  1.2       pk 	if (result && callback != NULL)
    426  1.2       pk 		result = (*callback)(tmp, arg);
    427  1.1       pk 	pmap_remove(pmap_kernel(), TMPMAP_VA, TMPMAP_VA+NBPG);
    428  1.1       pk 	return (result);
    429  1.1       pk }
    430  1.1       pk 
    431  1.1       pk int
    432  1.1       pk sparc_vme_map(cookie, addr, size, mod, tag, handlep)
    433  1.1       pk 	void *cookie;
    434  1.1       pk 	vme_addr_t addr;
    435  1.1       pk 	vme_size_t size;
    436  1.1       pk 	int mod;
    437  1.1       pk 	bus_space_tag_t tag;
    438  1.1       pk 	bus_space_handle_t *handlep;
    439  1.1       pk {
    440  1.1       pk 	struct rom_reg reg;
    441  1.1       pk 	struct vmebus_softc *sc = (struct vmebus_softc *)cookie;
    442  1.1       pk 
    443  1.1       pk 	reg.rr_paddr = (void *)addr;
    444  1.1       pk 	vmebus_translate(sc, mod, &reg);
    445  1.1       pk 	*handlep = (bus_space_handle_t)mapdev(&reg, 0, 0, size);
    446  1.1       pk 	return (0);
    447  1.1       pk }
    448  1.1       pk 
    449  1.1       pk int
    450  1.1       pk sparc_vme_mmap_cookie(cookie, addr, mod, tag, handlep)
    451  1.1       pk 	void *cookie;
    452  1.1       pk 	vme_addr_t addr;
    453  1.1       pk 	int mod;
    454  1.1       pk 	bus_space_tag_t tag;
    455  1.1       pk 	int *handlep;
    456  1.1       pk {
    457  1.1       pk 	struct rom_reg reg;
    458  1.1       pk 	struct vmebus_softc *sc = (struct vmebus_softc *)cookie;
    459  1.1       pk 
    460  1.1       pk 	reg.rr_paddr = (void *)addr;
    461  1.1       pk 	vmebus_translate(sc, mod, &reg);
    462  1.1       pk 	*handlep = (int)reg.rr_paddr | PMAP_IOENC(reg.rr_iospace) | PMAP_NC;
    463  1.1       pk 	return (0);
    464  1.1       pk }
    465  1.1       pk 
    466  1.1       pk void
    467  1.1       pk vmebus_translate(sc, mod, rr)
    468  1.1       pk 	struct vmebus_softc *sc;
    469  1.1       pk 	vme_mod_t mod;
    470  1.1       pk 	struct rom_reg *rr;
    471  1.1       pk {
    472  1.1       pk 	register int j;
    473  1.1       pk 
    474  1.1       pk 	if (CPU_ISSUN4) {
    475  1.1       pk 		(int)rr->rr_iospace = (mod & VMEMOD_D32)
    476  1.1       pk 			? PMAP_VME32
    477  1.1       pk 			: PMAP_VME16;
    478  1.1       pk 
    479  1.1       pk 		switch (mod & ~VMEMOD_D32) {
    480  1.1       pk 		case VMEMOD_A16|VMEMOD_D|VMEMOD_S:
    481  1.1       pk 			rr->rr_paddr += 0xffff0000;
    482  1.1       pk 			break;
    483  1.1       pk 		case VMEMOD_A24|VMEMOD_D|VMEMOD_S:
    484  1.1       pk 			rr->rr_paddr += 0xff000000;
    485  1.1       pk 			break;
    486  1.1       pk 		case VMEMOD_A32|VMEMOD_D|VMEMOD_S:
    487  1.1       pk 			break;
    488  1.1       pk 		default:
    489  1.1       pk 			panic("vmebus_translate: unsupported VME modifier: %x",
    490  1.1       pk 				mod);
    491  1.1       pk 		}
    492  1.1       pk 		return;
    493  1.1       pk 	}
    494  1.1       pk 
    495  1.1       pk 
    496  1.1       pk 	/* sun4m VME node: translate through "ranges" property */
    497  1.1       pk 	if (sc->sc_nrange == 0)
    498  1.1       pk 		panic("vmebus: no ranges");
    499  1.1       pk 
    500  1.1       pk 	/* Translate into parent address spaces */
    501  1.1       pk 	for (j = 0; j < sc->sc_nrange; j++) {
    502  1.1       pk 		if (sc->sc_range[j].cspace == mod) {
    503  1.1       pk 			(int)rr->rr_paddr +=
    504  1.1       pk 				sc->sc_range[j].poffset;
    505  1.1       pk 			(int)rr->rr_iospace =
    506  1.1       pk 				sc->sc_range[j].pspace;
    507  1.1       pk 			return;
    508  1.1       pk 		}
    509  1.1       pk 	}
    510  1.1       pk 	panic("sparc_vme_translate: modifier %x not supported", mod);
    511  1.1       pk }
    512  1.1       pk 
    513  1.1       pk #if defined(SUN4M)
    514  1.1       pk void
    515  1.1       pk sparc_vme4m_barrier(cookie)
    516  1.1       pk 	void *cookie;
    517  1.1       pk {
    518  1.1       pk 	struct vmebusreg *vbp = (struct vmebusreg *)cookie;
    519  1.1       pk 
    520  1.1       pk 	/* Read async fault status to flush write-buffers */
    521  1.1       pk 	(*(volatile int *)&vbp->vmebus_afsr);
    522  1.1       pk }
    523  1.1       pk #endif
    524  1.1       pk 
    525  1.1       pk 
    526  1.1       pk 
    527  1.1       pk /*
    528  1.1       pk  * VME Interrupt Priority Level to sparc Processor Interrupt Level.
    529  1.1       pk  */
    530  1.1       pk static int vme_ipl_to_pil[] = {
    531  1.1       pk 	0,
    532  1.1       pk 	2,
    533  1.1       pk 	3,
    534  1.1       pk 	5,
    535  1.1       pk 	7,
    536  1.1       pk 	9,
    537  1.1       pk 	11,
    538  1.1       pk 	13
    539  1.1       pk };
    540  1.1       pk 
    541  1.1       pk 
    542  1.1       pk /*
    543  1.1       pk  * All VME device interrupts go through vmeintr(). This function reads
    544  1.1       pk  * the VME vector from the bus, then dispatches the device interrupt
    545  1.1       pk  * handler.  All handlers for devices that map to the same Processor
    546  1.1       pk  * Interrupt Level (according to the table above) are on a linked list
    547  1.1       pk  * of `sparc_vme_intr_handle' structures. The head of which is passed
    548  1.1       pk  * down as the argument to `vmeintr(void *arg)'.
    549  1.1       pk  */
    550  1.1       pk struct sparc_vme_intr_handle {
    551  1.1       pk 	struct intrhand ih;
    552  1.1       pk 	struct sparc_vme_intr_handle *next;
    553  1.1       pk 	int	vec;		/* VME interrupt vector */
    554  1.1       pk 	int	pri;		/* VME interrupt priority */
    555  1.1       pk 	struct vmebus_softc *sc;/*XXX*/
    556  1.1       pk };
    557  1.1       pk 
    558  1.1       pk #if defined(SUN4)
    559  1.1       pk int
    560  1.1       pk vmeintr4(arg)
    561  1.1       pk 	void *arg;
    562  1.1       pk {
    563  1.1       pk 	struct sparc_vme_intr_handle *ihp = (vme_intr_handle_t)arg;
    564  1.1       pk 	int level, vec;
    565  1.1       pk 	int i = 0;
    566  1.1       pk 
    567  1.1       pk 	level = (ihp->pri << 1) | 1;
    568  1.1       pk 
    569  1.1       pk 	vec = ldcontrolb((caddr_t)(AC_VMEINTVEC | level));
    570  1.1       pk 
    571  1.1       pk 	if (vec == -1) {
    572  1.1       pk 		printf("vme: spurious interrupt\n");
    573  1.1       pk 		return 1; /* XXX - pretend we handled it, for now */
    574  1.1       pk 	}
    575  1.1       pk 
    576  1.1       pk 	for (; ihp; ihp = ihp->next)
    577  1.1       pk 		if (ihp->vec == vec && ihp->ih.ih_fun)
    578  1.1       pk 			i += (ihp->ih.ih_fun)(ihp->ih.ih_arg);
    579  1.1       pk 	return (i);
    580  1.1       pk }
    581  1.1       pk #endif
    582  1.1       pk 
    583  1.1       pk #if defined(SUN4M)
    584  1.1       pk int
    585  1.1       pk vmeintr4m(arg)
    586  1.1       pk 	void *arg;
    587  1.1       pk {
    588  1.1       pk 	struct sparc_vme_intr_handle *ihp = (vme_intr_handle_t)arg;
    589  1.1       pk 	int level, vec;
    590  1.1       pk 	int i = 0;
    591  1.1       pk 
    592  1.1       pk 	level = (ihp->pri << 1) | 1;
    593  1.1       pk 
    594  1.1       pk #if 0
    595  1.1       pk 	int pending;
    596  1.1       pk 
    597  1.1       pk 	/* Flush VME <=> Sbus write buffers */
    598  1.1       pk 	(*(volatile int *)&ihp->sc->sc_reg->vmebus_afsr);
    599  1.1       pk 
    600  1.1       pk 	pending = *((int*)ICR_SI_PEND);
    601  1.1       pk 	if ((pending & SINTR_VME(ihp->pri)) == 0) {
    602  1.1       pk 		printf("vmeintr: non pending at pri %x(p 0x%x)\n",
    603  1.1       pk 			ihp->pri, pending);
    604  1.1       pk 		return (0);
    605  1.1       pk 	}
    606  1.1       pk #endif
    607  1.1       pk #if 0
    608  1.1       pk 	/* Why gives this a bus timeout sometimes? */
    609  1.1       pk 	vec = ihp->sc->sc_vec->vmebusvec[level];
    610  1.1       pk #else
    611  1.1       pk 	/* so, arrange to catch the fault... */
    612  1.1       pk 	{
    613  1.1       pk 	extern struct user *proc0paddr;
    614  1.1       pk 	extern int fkbyte __P((caddr_t, struct pcb *));
    615  1.1       pk 	caddr_t addr = (caddr_t)&ihp->sc->sc_vec->vmebusvec[level];
    616  1.1       pk 	struct pcb *xpcb;
    617  1.1       pk 	u_long saveonfault;
    618  1.1       pk 	int s;
    619  1.1       pk 
    620  1.1       pk 	s = splhigh();
    621  1.1       pk 	if (curproc == NULL)
    622  1.1       pk 		xpcb = (struct pcb *)proc0paddr;
    623  1.1       pk 	else
    624  1.1       pk 		xpcb = &curproc->p_addr->u_pcb;
    625  1.1       pk 
    626  1.1       pk 	saveonfault = (u_long)xpcb->pcb_onfault;
    627  1.1       pk 	vec = fkbyte(addr, xpcb);
    628  1.1       pk 	xpcb->pcb_onfault = (caddr_t)saveonfault;
    629  1.1       pk 
    630  1.1       pk 	splx(s);
    631  1.1       pk 	}
    632  1.1       pk #endif
    633  1.1       pk 
    634  1.1       pk 	if (vec == -1) {
    635  1.1       pk 		printf("vme: spurious interrupt: ");
    636  1.1       pk 		printf("SI: 0x%x, VME AFSR: 0x%x, VME AFAR 0x%x\n",
    637  1.1       pk 			*((int*)ICR_SI_PEND),
    638  1.1       pk 			ihp->sc->sc_reg->vmebus_afsr,
    639  1.1       pk 			ihp->sc->sc_reg->vmebus_afar);
    640  1.1       pk 		return 1; /* XXX - pretend we handled it, for now */
    641  1.1       pk 	}
    642  1.1       pk 
    643  1.1       pk 	for (; ihp; ihp = ihp->next)
    644  1.1       pk 		if (ihp->vec == vec && ihp->ih.ih_fun)
    645  1.1       pk 			i += (ihp->ih.ih_fun)(ihp->ih.ih_arg);
    646  1.1       pk 	return (i);
    647  1.1       pk }
    648  1.1       pk #endif
    649  1.1       pk 
    650  1.1       pk int
    651  1.1       pk sparc_vme_intr_map(cookie, vec, pri, ihp)
    652  1.1       pk 	void *cookie;
    653  1.1       pk 	int vec;
    654  1.1       pk 	int pri;
    655  1.1       pk 	vme_intr_handle_t *ihp;
    656  1.1       pk {
    657  1.1       pk 	struct sparc_vme_intr_handle *ih;
    658  1.1       pk 
    659  1.1       pk 	ih = (vme_intr_handle_t)
    660  1.1       pk 	    malloc(sizeof(struct sparc_vme_intr_handle), M_DEVBUF, M_NOWAIT);
    661  1.1       pk 	ih->pri = pri;
    662  1.1       pk 	ih->vec = vec;
    663  1.1       pk 	ih->sc = cookie;/*XXX*/
    664  1.1       pk 	*ihp = ih;
    665  1.1       pk 	return (0);
    666  1.1       pk }
    667  1.1       pk 
    668  1.1       pk void *
    669  1.1       pk sparc_vme_intr_establish(cookie, vih, func, arg)
    670  1.1       pk 	void *cookie;
    671  1.1       pk 	vme_intr_handle_t vih;
    672  1.1       pk 	int (*func) __P((void *));
    673  1.1       pk 	void *arg;
    674  1.1       pk {
    675  1.1       pk 	struct vmebus_softc *sc = (struct vmebus_softc *)cookie;
    676  1.1       pk 	struct sparc_vme_intr_handle *svih =
    677  1.1       pk 			(struct sparc_vme_intr_handle *)vih;
    678  1.1       pk 	struct intrhand *ih;
    679  1.1       pk 	int level;
    680  1.1       pk 
    681  1.1       pk 	/* Translate VME priority to processor IPL */
    682  1.1       pk 	level = vme_ipl_to_pil[svih->pri];
    683  1.1       pk 
    684  1.1       pk 	svih->ih.ih_fun = func;
    685  1.1       pk 	svih->ih.ih_arg = arg;
    686  1.1       pk 	svih->next = NULL;
    687  1.1       pk 
    688  1.1       pk 	/* ensure the interrupt subsystem will call us at this level */
    689  1.1       pk 	for (ih = intrhand[level]; ih != NULL; ih = ih->ih_next)
    690  1.1       pk 		if (ih->ih_fun == sc->sc_vmeintr)
    691  1.1       pk 			break;
    692  1.1       pk 
    693  1.1       pk 	if (ih == NULL) {
    694  1.1       pk 		ih = (struct intrhand *)
    695  1.1       pk 			malloc(sizeof(struct intrhand), M_DEVBUF, M_NOWAIT);
    696  1.1       pk 		if (ih == NULL)
    697  1.1       pk 			panic("vme_addirq");
    698  1.1       pk 		bzero(ih, sizeof *ih);
    699  1.1       pk 		ih->ih_fun = sc->sc_vmeintr;
    700  1.1       pk 		ih->ih_arg = vih;
    701  1.1       pk 		intr_establish(level, ih);
    702  1.1       pk 	} else {
    703  1.1       pk 		svih->next = (vme_intr_handle_t)ih->ih_arg;
    704  1.1       pk 		ih->ih_arg = vih;
    705  1.1       pk 	}
    706  1.1       pk 	return (NULL);
    707  1.1       pk }
    708  1.1       pk 
    709  1.1       pk void
    710  1.1       pk sparc_vme_unmap(cookie)
    711  1.1       pk 	void * cookie;
    712  1.1       pk {
    713  1.1       pk 	/* Not implemented */
    714  1.1       pk 	panic("sparc_vme_unmap");
    715  1.1       pk }
    716  1.1       pk 
    717  1.1       pk void
    718  1.1       pk sparc_vme_intr_disestablish(cookie, a)
    719  1.1       pk 	void *cookie;
    720  1.1       pk 	void *a;
    721  1.1       pk {
    722  1.1       pk 	/* Not implemented */
    723  1.1       pk 	panic("sparc_vme_intr_disestablish");
    724  1.1       pk }
    725  1.1       pk 
    726  1.1       pk 
    727  1.1       pk 
    728  1.1       pk /*
    729  1.1       pk  * VME DMA functions.
    730  1.1       pk  */
    731  1.1       pk 
    732  1.1       pk #if defined(SUN4)
    733  1.1       pk int
    734  1.1       pk sparc_vme4_dmamap_load(t, map, buf, buflen, p, flags)
    735  1.1       pk 	bus_dma_tag_t t;
    736  1.1       pk 	bus_dmamap_t map;
    737  1.1       pk 	void *buf;
    738  1.1       pk 	bus_size_t buflen;
    739  1.1       pk 	struct proc *p;
    740  1.1       pk 	int flags;
    741  1.1       pk {
    742  1.1       pk 	int error;
    743  1.1       pk 
    744  1.1       pk 	error = _bus_dmamap_load(t, map, buf, buflen, p, flags);
    745  1.1       pk 	if (error != 0)
    746  1.1       pk 		return (error);
    747  1.1       pk 
    748  1.1       pk 	/* Adjust DVMA address to VME view */
    749  1.1       pk 	map->dm_segs[0].ds_addr -= DVMA_BASE;
    750  1.1       pk 	return (0);
    751  1.1       pk }
    752  1.1       pk 
    753  1.1       pk void
    754  1.1       pk sparc_vme4_dmamap_unload(t, map)
    755  1.1       pk 	bus_dma_tag_t t;
    756  1.1       pk 	bus_dmamap_t map;
    757  1.1       pk {
    758  1.1       pk 	map->dm_segs[0].ds_addr += DVMA_BASE;
    759  1.1       pk 	_bus_dmamap_unload(t, map);
    760  1.1       pk }
    761  1.1       pk 
    762  1.1       pk int
    763  1.1       pk sparc_vme4_dmamem_alloc(t, size, alignment, boundary, segs, nsegs, rsegs, flags)
    764  1.1       pk 	bus_dma_tag_t t;
    765  1.1       pk 	bus_size_t size, alignment, boundary;
    766  1.1       pk 	bus_dma_segment_t *segs;
    767  1.1       pk 	int nsegs;
    768  1.1       pk 	int *rsegs;
    769  1.1       pk 	int flags;
    770  1.1       pk {
    771  1.1       pk 	int error;
    772  1.1       pk 
    773  1.1       pk 	error = _bus_dmamem_alloc(t, size, alignment, boundary,
    774  1.1       pk 				  segs, nsegs, rsegs, flags);
    775  1.1       pk 	if (error != 0)
    776  1.1       pk 		return (error);
    777  1.1       pk 
    778  1.1       pk 	segs[0].ds_addr -= DVMA_BASE;
    779  1.1       pk 	return (0);
    780  1.1       pk }
    781  1.1       pk 
    782  1.1       pk void
    783  1.1       pk sparc_vme4_dmamem_free(t, segs, nsegs)
    784  1.1       pk 	bus_dma_tag_t t;
    785  1.1       pk 	bus_dma_segment_t *segs;
    786  1.1       pk 	int nsegs;
    787  1.1       pk {
    788  1.1       pk 	segs[0].ds_addr += DVMA_BASE;
    789  1.1       pk 	_bus_dmamem_free(t, segs, nsegs);
    790  1.1       pk }
    791  1.1       pk 
    792  1.1       pk void
    793  1.4  thorpej sparc_vme4_dmamap_sync(t, map, offset, len, ops)
    794  1.1       pk 	bus_dma_tag_t t;
    795  1.1       pk 	bus_dmamap_t map;
    796  1.4  thorpej 	bus_addr_t offset;
    797  1.4  thorpej 	bus_size_t len;
    798  1.3  thorpej 	int ops;
    799  1.1       pk {
    800  1.3  thorpej 
    801  1.3  thorpej 	/*
    802  1.3  thorpej 	 * XXX Should perform cache flushes as necessary (e.g. 4/200 W/B).
    803  1.3  thorpej 	 */
    804  1.1       pk }
    805  1.1       pk #endif /* SUN4 */
    806  1.1       pk 
    807  1.1       pk #if defined(SUN4M)
    808  1.1       pk static int
    809  1.1       pk sparc_vme4m_dmamap_create (t, size, nsegments, maxsegsz, boundary, flags, dmamp)
    810  1.1       pk 	bus_dma_tag_t t;
    811  1.1       pk 	bus_size_t size;
    812  1.1       pk 	int nsegments;
    813  1.1       pk 	bus_size_t maxsegsz;
    814  1.1       pk 	bus_size_t boundary;
    815  1.1       pk 	int flags;
    816  1.1       pk 	bus_dmamap_t *dmamp;
    817  1.1       pk {
    818  1.1       pk 	int align;
    819  1.1       pk 
    820  1.1       pk 	/* VME DVMA addresses must always be 8K aligned */
    821  1.1       pk 	align = 8192;
    822  1.1       pk 
    823  1.1       pk 	/* XXX - todo: allocate DVMA addresses from assigned ranges:
    824  1.1       pk 		 upper 8MB for A32 space; upper 1MB for A24 space */
    825  1.1       pk 	return (_bus_dmamap_create(t, size, nsegments, maxsegsz,
    826  1.1       pk 				    boundary, /*align,*/ flags, dmamp));
    827  1.1       pk }
    828  1.1       pk 
    829  1.1       pk int
    830  1.1       pk sparc_vme4m_dmamap_load(t, map, buf, buflen, p, flags)
    831  1.1       pk 	bus_dma_tag_t t;
    832  1.1       pk 	bus_dmamap_t map;
    833  1.1       pk 	void *buf;
    834  1.1       pk 	bus_size_t buflen;
    835  1.1       pk 	struct proc *p;
    836  1.1       pk 	int flags;
    837  1.1       pk {
    838  1.1       pk 	struct vmebus_softc	*sc = (struct vmebus_softc *)t->_cookie;
    839  1.1       pk 	volatile u_int32_t	*ioctags;
    840  1.1       pk 	int			error;
    841  1.1       pk 
    842  1.1       pk 	buflen = (buflen + VME_IOC_PAGESZ - 1) & ~(VME_IOC_PAGESZ - 1);
    843  1.1       pk 	error = _bus_dmamap_load(t, map, buf, buflen, p, flags);
    844  1.1       pk 	if (error != 0)
    845  1.1       pk 		return (error);
    846  1.1       pk 
    847  1.1       pk 	/* allocate IO cache entries for this range */
    848  1.1       pk 	ioctags = sc->sc_ioctags + VME_IOC_LINE(map->dm_segs[0].ds_addr);
    849  1.1       pk 	for (;buflen > 0;) {
    850  1.1       pk 		*ioctags = VME_IOC_IC | VME_IOC_W;
    851  1.1       pk 		ioctags += VME_IOC_LINESZ/sizeof(*ioctags);
    852  1.1       pk 		buflen -= VME_IOC_PAGESZ;
    853  1.1       pk 	}
    854  1.1       pk 	return (0);
    855  1.1       pk }
    856  1.1       pk 
    857  1.1       pk 
    858  1.1       pk void
    859  1.1       pk sparc_vme4m_dmamap_unload(t, map)
    860  1.1       pk 	bus_dma_tag_t t;
    861  1.1       pk 	bus_dmamap_t map;
    862  1.1       pk {
    863  1.1       pk 	struct vmebus_softc	*sc = (struct vmebus_softc *)t->_cookie;
    864  1.1       pk 	volatile u_int32_t	*flushregs;
    865  1.1       pk 	int			len;
    866  1.1       pk 
    867  1.1       pk 	/* Flush VME IO cache */
    868  1.1       pk 	len = map->dm_segs[0].ds_len;
    869  1.1       pk 	flushregs = sc->sc_iocflush + VME_IOC_LINE(map->dm_segs[0].ds_addr);
    870  1.1       pk 	for (;len > 0;) {
    871  1.1       pk 		*flushregs = 0;
    872  1.1       pk 		flushregs += VME_IOC_LINESZ/sizeof(*flushregs);
    873  1.1       pk 		len -= VME_IOC_PAGESZ;
    874  1.1       pk 	}
    875  1.1       pk 	/* Read a tag to synchronize the IOC flushes */
    876  1.1       pk 	(*sc->sc_ioctags);
    877  1.1       pk 
    878  1.1       pk 	_bus_dmamap_unload(t, map);
    879  1.1       pk }
    880  1.1       pk 
    881  1.1       pk int
    882  1.1       pk sparc_vme4m_dmamem_alloc(t, size, alignmnt, boundary, segs, nsegs, rsegs, flags)
    883  1.1       pk 	bus_dma_tag_t t;
    884  1.1       pk 	bus_size_t size, alignmnt, boundary;
    885  1.1       pk 	bus_dma_segment_t *segs;
    886  1.1       pk 	int nsegs;
    887  1.1       pk 	int *rsegs;
    888  1.1       pk 	int flags;
    889  1.1       pk {
    890  1.1       pk 	int error;
    891  1.1       pk 
    892  1.1       pk 	error = _bus_dmamem_alloc(t, size, alignmnt, boundary,
    893  1.1       pk 				  segs, nsegs, rsegs, flags);
    894  1.1       pk 	if (error != 0)
    895  1.1       pk 		return (error);
    896  1.1       pk 
    897  1.1       pk 	return (0);
    898  1.1       pk }
    899  1.1       pk 
    900  1.1       pk void
    901  1.1       pk sparc_vme4m_dmamem_free(t, segs, nsegs)
    902  1.1       pk 	bus_dma_tag_t t;
    903  1.1       pk 	bus_dma_segment_t *segs;
    904  1.1       pk 	int nsegs;
    905  1.1       pk {
    906  1.1       pk 	_bus_dmamem_free(t, segs, nsegs);
    907  1.1       pk }
    908  1.1       pk 
    909  1.1       pk void
    910  1.4  thorpej sparc_vme4m_dmamap_sync(t, map, offset, len, ops)
    911  1.1       pk 	bus_dma_tag_t t;
    912  1.1       pk 	bus_dmamap_t map;
    913  1.4  thorpej 	bus_addr_t offset;
    914  1.4  thorpej 	bus_size_t len;
    915  1.3  thorpej 	int ops;
    916  1.1       pk {
    917  1.3  thorpej 
    918  1.3  thorpej 	/*
    919  1.3  thorpej 	 * XXX Should perform cache flushes as necessary.
    920  1.3  thorpej 	 */
    921  1.1       pk }
    922  1.1       pk #endif /* SUN4M */
    923