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