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