Home | History | Annotate | Line # | Download | only in jensenio
jensenio_bus_intio.c revision 1.1
      1 /* $NetBSD: jensenio_bus_intio.c,v 1.1 2000/07/12 20:36:08 thorpej Exp $ */
      2 
      3 /*-
      4  * Copyright (c) 1999 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Jason R. Thorpe.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  * 3. All advertising materials mentioning features or use of this software
     19  *    must display the following acknowledgement:
     20  *	This product includes software developed by the NetBSD
     21  *	Foundation, Inc. and its contributors.
     22  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23  *    contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36  * POSSIBILITY OF SUCH DAMAGE.
     37  */
     38 
     39 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
     40 
     41 __KERNEL_RCSID(0, "$NetBSD: jensenio_bus_intio.c,v 1.1 2000/07/12 20:36:08 thorpej Exp $");
     42 
     43 #include <sys/param.h>
     44 #include <sys/systm.h>
     45 #include <sys/malloc.h>
     46 #include <sys/device.h>
     47 #include <sys/extent.h>
     48 
     49 #include <machine/bus.h>
     50 
     51 #include <dev/eisa/eisavar.h>
     52 
     53 #include <dev/isa/isavar.h>
     54 
     55 #include <alpha/jensenio/jensenioreg.h>
     56 #include <alpha/jensenio/jenseniovar.h>
     57 
     58 /* mapping/unmapping */
     59 int		jensenio_intio_map(void *, bus_addr_t, bus_size_t, int,
     60 		    bus_space_handle_t *, int);
     61 void		jensenio_intio_unmap(void *, bus_space_handle_t,
     62 		    bus_size_t, int);
     63 int		jensenio_intio_subregion(void *, bus_space_handle_t,
     64 		    bus_size_t, bus_size_t, bus_space_handle_t *);
     65 
     66 /* allocation/deallocation */
     67 	/* Not supported for Internal space */
     68 
     69 /* barrier */
     70 inline void	jensenio_intio_barrier(void *, bus_space_handle_t,
     71 		    bus_size_t, bus_size_t, int);
     72 
     73 /* read (single) */
     74 inline u_int8_t	jensenio_intio_read_1(void *, bus_space_handle_t, bus_size_t);
     75 
     76 /* read multiple */
     77 void		jensenio_intio_read_multi_1(void *, bus_space_handle_t,
     78 		    bus_size_t, u_int8_t *, bus_size_t);
     79 
     80 /* read region */
     81 	/* Not supported for Internal space */
     82 
     83 /* write (single) */
     84 inline void	jensenio_intio_write_1(void *, bus_space_handle_t,
     85 		    bus_size_t, u_int8_t);
     86 
     87 /* write multiple */
     88 void		jensenio_intio_write_multi_1(void *, bus_space_handle_t,
     89 		    bus_size_t, const u_int8_t *, bus_size_t);
     90 
     91 /* write region */
     92 	/* Not supported for Internal space */
     93 
     94 /* set multiple */
     95 void		jensenio_intio_set_multi_1(void *, bus_space_handle_t,
     96 		    bus_size_t, u_int8_t, bus_size_t);
     97 
     98 /* set region */
     99 	/* Not supported for Internal space */
    100 
    101 /* copy */
    102 	/* Not supported for Internal space */
    103 
    104 void
    105 jensenio_bus_intio_init(bus_space_tag_t t, void *v)
    106 {
    107 
    108 	/*
    109 	 * Initialize the bus space tag.
    110 	 */
    111 
    112 	memset(t, 0, sizeof(*t));
    113 
    114 	/* cookie */
    115 	t->abs_cookie =		v;
    116 
    117 	/* mapping/unmapping */
    118 	t->abs_map =		jensenio_intio_map;
    119 	t->abs_unmap =		jensenio_intio_unmap;
    120 	t->abs_subregion =	jensenio_intio_subregion;
    121 
    122 	/* barrier */
    123 	t->abs_barrier =	jensenio_intio_barrier;
    124 
    125 	/* read (single) */
    126 	t->abs_r_1 =		jensenio_intio_read_1;
    127 
    128 	/* read multiple */
    129 	t->abs_rm_1 =		jensenio_intio_read_multi_1;
    130 
    131 	/* write (single) */
    132 	t->abs_w_1 =		jensenio_intio_write_1;
    133 
    134 	/* write multiple */
    135 	t->abs_wm_1 =		jensenio_intio_write_multi_1;
    136 
    137 	/* set multiple */
    138 	t->abs_sm_1 =		jensenio_intio_set_multi_1;
    139 
    140 	/*
    141 	 * Extent map is already set up.
    142 	 */
    143 }
    144 
    145 int
    146 jensenio_intio_map(void *v, bus_addr_t ioaddr, bus_size_t iosize, int flags,
    147     bus_space_handle_t *iohp, int acct)
    148 {
    149 	struct jensenio_config *jcp = v;
    150 	int linear = flags & BUS_SPACE_MAP_LINEAR;
    151 	int error;
    152 
    153 	/*
    154 	 * Can't map i/o space linearly.
    155 	 */
    156 	if (linear)
    157 		return (EOPNOTSUPP);
    158 
    159 	if (acct) {
    160 #ifdef EXTENT_DEBUG
    161 		printf("intio: allocating 0x%lx to 0x%lx\n", ioaddr,
    162 		    ioaddr + iosize - 1);
    163 #endif
    164 		error = extent_alloc_region(jcp->jc_io_ex, ioaddr, iosize,
    165 		    EX_NOWAIT | (jcp->jc_mallocsafe ? EX_MALLOCOK : 0));
    166 		if (error) {
    167 #ifdef EXTENT_DEBUG
    168 			printf("intio: allocation failed (%d)\n", error);
    169 			extent_print(jcp->jc_io_ex);
    170 #endif
    171 			return (error);
    172 		}
    173 	}
    174 
    175 	*iohp = ALPHA_PHYS_TO_K0SEG((ioaddr << 9) + JENSEN_VL82C106);
    176 	return (0);
    177 }
    178 
    179 void
    180 jensenio_intio_unmap(void *v, bus_space_handle_t ioh, bus_size_t iosize,
    181     int acct)
    182 {
    183 	struct jensenio_config *jcp = v;
    184 	bus_addr_t ioaddr;
    185 	int error;
    186 
    187 	if (acct == 0)
    188 		return;
    189 
    190 #ifdef EXTENT_DEBUG
    191 	printf("intio: freeing handle 0x%lx for 0x%lx\n", ioh, iosize);
    192 #endif
    193 
    194 	ioh = ALPHA_K0SEG_TO_PHYS(ioh);
    195 
    196 	ioaddr = (ioh - JENSEN_VL82C106) >> 9;
    197 
    198 #ifdef EXTENT_DEBUG
    199 	printf("intio: freeing 0x%lx to 0x%lx\n", ioaddr, ioaddr + iosize - 1);
    200 #endif
    201 	error = extent_free(jcp->jc_io_ex, ioaddr, iosize,
    202 	    EX_NOWAIT | (jcp->jc_mallocsafe ? EX_MALLOCOK : 0));
    203 	if (error) {
    204 		printf("WARNING: could not unmap 0x%lx-0x%lx (error %d)\n",
    205 		    ioaddr, ioaddr + iosize - 1, error);
    206 #ifdef EXTENT_DEBUG
    207 		extent_print(jcp->jc_io_ex);
    208 #endif
    209 	}
    210 }
    211 
    212 int
    213 jensenio_intio_subregion(void *v, bus_space_handle_t ioh, bus_size_t offset,
    214     bus_size_t size, bus_space_handle_t *nioh)
    215 {
    216 
    217 	*nioh = ioh + (offset << 9);
    218 	return (0);
    219 }
    220 
    221 inline void
    222 jensenio_intio_barrier(void *v, bus_space_handle_t h, bus_size_t o,
    223     bus_size_t l, int f)
    224 {
    225 
    226 	if ((f & BUS_SPACE_BARRIER_READ) != 0)
    227 		alpha_mb();
    228 	else if ((f & BUS_SPACE_BARRIER_WRITE) != 0)
    229 		alpha_wmb();
    230 }
    231 
    232 inline u_int8_t
    233 jensenio_intio_read_1(void *v, bus_space_handle_t ioh, bus_size_t off)
    234 {
    235 	register u_int32_t *port;
    236 
    237 	alpha_mb();
    238 
    239 	port = (u_int32_t *)(ioh + (off << 9));
    240 	return (*port & 0xff);
    241 }
    242 
    243 void
    244 jensenio_intio_read_multi_1(void *v, bus_space_handle_t h, bus_size_t o,
    245     u_int8_t *a, bus_size_t c)
    246 {
    247 
    248 	while (c-- > 0) {
    249 		jensenio_intio_barrier(v, h, o, sizeof *a,
    250 		    BUS_SPACE_BARRIER_READ);
    251 		*a++ = jensenio_intio_read_1(v, h, o);
    252 	}
    253 }
    254 
    255 inline void
    256 jensenio_intio_write_1(void *v, bus_space_handle_t ioh, bus_size_t off,
    257     u_int8_t val)
    258 {
    259 	register u_int32_t *port;
    260 
    261 	port = (u_int32_t *)(ioh + (off << 9));
    262 	*port = val;
    263 	alpha_mb();
    264 }
    265 
    266 void
    267 jensenio_intio_write_multi_1(void *v, bus_space_handle_t h, bus_size_t o,
    268     const u_int8_t *a, bus_size_t c)
    269 {
    270 
    271 	while (c-- > 0) {
    272 		jensenio_intio_write_1(v, h, o, *a++);
    273 		jensenio_intio_barrier(v, h, o, sizeof *a,
    274 		    BUS_SPACE_BARRIER_WRITE);
    275 	}
    276 }
    277 
    278 void
    279 jensenio_intio_set_multi_1(void *v, bus_space_handle_t h, bus_size_t o,
    280     u_int8_t val, bus_size_t c)
    281 {
    282 
    283 	while (c-- > 0) {
    284 		jensenio_intio_write_1(v, h, o, val);
    285 		jensenio_intio_barrier(v, h, o, sizeof val,
    286 		    BUS_SPACE_BARRIER_WRITE);
    287 	}
    288 }
    289