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