Line data Source code
1 : /* $OpenBSD: bus.h,v 1.34 2017/06/04 06:21:37 sf Exp $ */
2 : /* $NetBSD: bus.h,v 1.6 1996/11/10 03:19:25 thorpej Exp $ */
3 :
4 : /*-
5 : * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
6 : * All rights reserved.
7 : *
8 : * This code is derived from software contributed to The NetBSD Foundation
9 : * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
10 : * NASA Ames Research Center.
11 : *
12 : * Redistribution and use in source and binary forms, with or without
13 : * modification, are permitted provided that the following conditions
14 : * are met:
15 : * 1. Redistributions of source code must retain the above copyright
16 : * notice, this list of conditions and the following disclaimer.
17 : * 2. Redistributions in binary form must reproduce the above copyright
18 : * notice, this list of conditions and the following disclaimer in the
19 : * documentation and/or other materials provided with the distribution.
20 : *
21 : * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
22 : * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 : * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 : * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25 : * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 : * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 : * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 : * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 : * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 : * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 : * POSSIBILITY OF SUCH DAMAGE.
32 : */
33 :
34 : /*
35 : * Copyright (c) 1996 Charles M. Hannum. All rights reserved.
36 : * Copyright (c) 1996 Jason R. Thorpe. All rights reserved.
37 : * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
38 : *
39 : * Redistribution and use in source and binary forms, with or without
40 : * modification, are permitted provided that the following conditions
41 : * are met:
42 : * 1. Redistributions of source code must retain the above copyright
43 : * notice, this list of conditions and the following disclaimer.
44 : * 2. Redistributions in binary form must reproduce the above copyright
45 : * notice, this list of conditions and the following disclaimer in the
46 : * documentation and/or other materials provided with the distribution.
47 : * 3. All advertising materials mentioning features or use of this software
48 : * must display the following acknowledgement:
49 : * This product includes software developed by Christopher G. Demetriou
50 : * for the NetBSD Project.
51 : * 4. The name of the author may not be used to endorse or promote products
52 : * derived from this software without specific prior written permission
53 : *
54 : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
55 : * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
56 : * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
57 : * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
58 : * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
59 : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
60 : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
61 : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
62 : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
63 : * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64 : */
65 :
66 : #ifndef _MACHINE_BUS_H_
67 : #define _MACHINE_BUS_H_
68 :
69 : #include <sys/mutex.h>
70 : #include <sys/tree.h>
71 :
72 : #include <machine/pio.h>
73 :
74 : /*
75 : * Bus address and size types
76 : */
77 : typedef u_long bus_addr_t;
78 : typedef u_long bus_size_t;
79 :
80 : /*
81 : * Access methods for bus resources and address space.
82 : */
83 : struct x86_bus_space_ops;
84 : typedef const struct x86_bus_space_ops *bus_space_tag_t;
85 : typedef u_long bus_space_handle_t;
86 :
87 : int bus_space_map(bus_space_tag_t t, bus_addr_t addr,
88 : bus_size_t size, int flags, bus_space_handle_t *bshp);
89 : /* like map, but without extent map checking/allocation */
90 : int _bus_space_map(bus_space_tag_t t, bus_addr_t addr,
91 : bus_size_t size, int flags, bus_space_handle_t *bshp);
92 :
93 : int bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart,
94 : bus_addr_t rend, bus_size_t size, bus_size_t align,
95 : bus_size_t boundary, int flags, bus_addr_t *addrp,
96 : bus_space_handle_t *bshp);
97 : void bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh,
98 : bus_size_t size);
99 :
100 : /*
101 : * int bus_space_unmap(bus_space_tag_t t,
102 : * bus_space_handle_t bsh, bus_size_t size);
103 : *
104 : * Unmap a region of bus space.
105 : */
106 :
107 : void bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh,
108 : bus_size_t size);
109 : void _bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh,
110 : bus_size_t size, bus_addr_t *);
111 :
112 : /* like bus_space_map(), but without extent map checking/allocation */
113 : int _bus_space_map(bus_space_tag_t t, bus_addr_t addr,
114 : bus_size_t size, int flags, bus_space_handle_t *bshp);
115 :
116 : /*
117 : * int bus_space_subregion(bus_space_tag_t t,
118 : * bus_space_handle_t bsh, bus_size_t offset, bus_size_t size,
119 : * bus_space_handle_t *nbshp);
120 : *
121 : * Get a new handle for a subregion of an already-mapped area of bus space.
122 : */
123 :
124 : int bus_space_subregion(bus_space_tag_t t, bus_space_handle_t bsh,
125 : bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp);
126 :
127 : struct x86_bus_space_ops {
128 :
129 : /*
130 : * u_intN_t bus_space_read_N(bus_space_tag_t tag,
131 : * bus_space_handle_t bsh, bus_size_t offset);
132 : *
133 : * Read a 1, 2, 4, or 8 byte quantity from bus space
134 : * described by tag/handle/offset.
135 : */
136 : u_int8_t (*read_1)(bus_space_handle_t, bus_size_t);
137 : u_int16_t (*read_2)(bus_space_handle_t, bus_size_t);
138 : u_int32_t (*read_4)(bus_space_handle_t, bus_size_t);
139 : u_int64_t (*read_8)(bus_space_handle_t, bus_size_t);
140 :
141 : #define bus_space_read_1(_t, _h, _o) ((_t)->read_1((_h), (_o)))
142 : #define bus_space_read_2(_t, _h, _o) ((_t)->read_2((_h), (_o)))
143 : #define bus_space_read_4(_t, _h, _o) ((_t)->read_4((_h), (_o)))
144 : #define bus_space_read_8(_t, _h, _o) ((_t)->read_8((_h), (_o)))
145 :
146 : #define bus_space_read_raw_2(_t, _h, _o) ((_t)->read_2((_h), (_o)))
147 : #define bus_space_read_raw_4(_t, _h, _o) ((_t)->read_4((_h), (_o)))
148 : #define bus_space_read_raw_8(_t, _h, _o) ((_t)->read_8((_h), (_o)))
149 :
150 : /*
151 : * void bus_space_read_multi_N(bus_space_tag_t tag,
152 : * bus_space_handle_t bsh, bus_size_t offset,
153 : * u_intN_t *addr, size_t count);
154 : *
155 : * Read `count' 1, 2, 4, or 8 byte quantities from bus space
156 : * described by tag/handle/offset and copy into buffer provided.
157 : */
158 :
159 : void (*read_multi_1)(bus_space_handle_t, bus_size_t,
160 : u_int8_t *, bus_size_t);
161 : void (*read_multi_2)(bus_space_handle_t, bus_size_t,
162 : u_int16_t *, bus_size_t);
163 : void (*read_multi_4)(bus_space_handle_t, bus_size_t,
164 : u_int32_t *, bus_size_t);
165 : void (*read_multi_8)(bus_space_handle_t, bus_size_t,
166 : u_int64_t *, bus_size_t);
167 :
168 : #define bus_space_read_multi_1(_t, _h, _o, _a, _c) \
169 : ((_t)->read_multi_1((_h), (_o), (_a), (_c)))
170 : #define bus_space_read_multi_2(_t, _h, _o, _a, _c) \
171 : ((_t)->read_multi_2((_h), (_o), (_a), (_c)))
172 : #define bus_space_read_multi_4(_t, _h, _o, _a, _c) \
173 : ((_t)->read_multi_4((_h), (_o), (_a), (_c)))
174 : #define bus_space_read_multi_8(_t, _h, _o, _a, _c) \
175 : ((_t)->read_multi_8((_h), (_o), (_a), (_c)))
176 :
177 : /*
178 : * void bus_space_read_raw_multi_N(bus_space_tag_t tag,
179 : * bus_space_handle_t bsh, bus_size_t offset,
180 : * u_int8_t *addr, size_t count);
181 : *
182 : * Read `count' bytes in 2, 4 or 8 byte wide quantities from bus space
183 : * described by tag/handle/offset and copy into buffer provided. The buffer
184 : * must have proper alignment for the N byte wide entities. Furthermore
185 : * possible byte-swapping should be done by these functions.
186 : */
187 :
188 : #define bus_space_read_raw_multi_2(_t, _h, _o, _a, _c) \
189 : ((_t)->read_multi_2((_h), (_o), (u_int16_t *)(_a), (_c) >> 1))
190 : #define bus_space_read_raw_multi_4(_t, _h, _o, _a, _c) \
191 : ((_t)->read_multi_4((_h), (_o), (u_int32_t *)(_a), (_c) >> 2))
192 : #define bus_space_read_raw_multi_8(_t, _h, _o, _a, _c) \
193 : ((_t)->read_multi_8((_h), (_o), (u_int64_t *)(_a), (_c) >> 3))
194 :
195 : /*
196 : * void bus_space_read_region_N(bus_space_tag_t tag,
197 : * bus_space_handle_t bsh, bus_size_t offset,
198 : * u_intN_t *addr, size_t count);
199 : *
200 : * Read `count' 1, 2, 4, or 8 byte quantities from bus space
201 : * described by tag/handle and starting at `offset' and copy into
202 : * buffer provided.
203 : */
204 :
205 : void (*read_region_1)(bus_space_handle_t,
206 : bus_size_t, u_int8_t *, bus_size_t);
207 : void (*read_region_2)(bus_space_handle_t,
208 : bus_size_t, u_int16_t *, bus_size_t);
209 : void (*read_region_4)(bus_space_handle_t,
210 : bus_size_t, u_int32_t *, bus_size_t);
211 : void (*read_region_8)(bus_space_handle_t,
212 : bus_size_t, u_int64_t *, bus_size_t);
213 :
214 : #define bus_space_read_region_1(_t, _h, _o, _a, _c) \
215 : ((_t)->read_region_1((_h), (_o), (_a), (_c)))
216 : #define bus_space_read_region_2(_t, _h, _o, _a, _c) \
217 : ((_t)->read_region_2((_h), (_o), (_a), (_c)))
218 : #define bus_space_read_region_4(_t, _h, _o, _a, _c) \
219 : ((_t)->read_region_4((_h), (_o), (_a), (_c)))
220 : #define bus_space_read_region_8(_t, _h, _o, _a, _c) \
221 : ((_t)->read_region_8((_h), (_o), (_a), (_c)))
222 :
223 : /*
224 : * void bus_space_read_raw_region_N(bus_space_tag_t tag,
225 : * bus_space_handle_t bsh, bus_size_t offset,
226 : * u_int8_t *addr, size_t count);
227 : *
228 : * Read `count' bytes in 2, 4 or 8 byte wide quantities from bus space
229 : * described by tag/handle and starting at `offset' and copy into
230 : * buffer provided. The buffer must have proper alignment for the N byte
231 : * wide entities. Furthermore possible byte-swapping should be done by
232 : * these functions.
233 : */
234 :
235 : #define bus_space_read_raw_region_2(_t, _h, _o, _a, _c) \
236 : ((_t)->read_region_2((_h), (_o), (u_int16_t *)(_a), (_c) >> 1))
237 : #define bus_space_read_raw_region_4(_t, _h, _o, _a, _c) \
238 : ((_t)->read_region_4((_h), (_o), (u_int32_t *)(_a), (_c) >> 2))
239 : #define bus_space_read_raw_region_8(_t, _h, _o, _a, _c) \
240 : ((_t)->read_region_8((_h), (_o), (u_int64_t *)(_a), (_c) >> 3))
241 :
242 : /*
243 : * void bus_space_write_N(bus_space_tag_t tag,
244 : * bus_space_handle_t bsh, bus_size_t offset,
245 : * u_intN_t value);
246 : *
247 : * Write the 1, 2, 4, or 8 byte value `value' to bus space
248 : * described by tag/handle/offset.
249 : */
250 :
251 : void (*write_1)(bus_space_handle_t, bus_size_t, u_int8_t);
252 : void (*write_2)(bus_space_handle_t, bus_size_t, u_int16_t);
253 : void (*write_4)(bus_space_handle_t, bus_size_t, u_int32_t);
254 : void (*write_8)(bus_space_handle_t, bus_size_t, u_int64_t);
255 :
256 : #define bus_space_write_1(_t, _h, _o, _v) \
257 : ((_t)->write_1((_h), (_o), (_v)))
258 : #define bus_space_write_2(_t, _h, _o, _v) \
259 : ((_t)->write_2((_h), (_o), (_v)))
260 : #define bus_space_write_4(_t, _h, _o, _v) \
261 : ((_t)->write_4((_h), (_o), (_v)))
262 : #define bus_space_write_8(_t, _h, _o, _v) \
263 : ((_t)->write_8((_h), (_o), (_v)))
264 :
265 : #define bus_space_write_raw_2(_t, _h, _o, _v) \
266 : ((_t)->write_2((_h), (_o), (_v)))
267 : #define bus_space_write_raw_4(_t, _h, _o, _v) \
268 : ((_t)->write_4((_h), (_o), (_v)))
269 : #define bus_space_write_raw_8(_t, _h, _o, _v) \
270 : ((_t)->write_8((_h), (_o), (_v)))
271 :
272 : /*
273 : * void bus_space_write_multi_N(bus_space_tag_t tag,
274 : * bus_space_handle_t bsh, bus_size_t offset,
275 : * const u_intN_t *addr, size_t count);
276 : *
277 : * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
278 : * provided to bus space described by tag/handle/offset.
279 : */
280 :
281 : void (*write_multi_1)(bus_space_handle_t,
282 : bus_size_t, const u_int8_t *, bus_size_t);
283 : void (*write_multi_2)(bus_space_handle_t,
284 : bus_size_t, const u_int16_t *, bus_size_t);
285 : void (*write_multi_4)(bus_space_handle_t,
286 : bus_size_t, const u_int32_t *, bus_size_t);
287 : void (*write_multi_8)(bus_space_handle_t,
288 : bus_size_t, const u_int64_t *, bus_size_t);
289 :
290 : #define bus_space_write_multi_1(_t, _h, _o, _a, _c) \
291 : ((_t)->write_multi_1((_h), (_o), (_a), (_c)))
292 : #define bus_space_write_multi_2(_t, _h, _o, _a, _c) \
293 : ((_t)->write_multi_2((_h), (_o), (_a), (_c)))
294 : #define bus_space_write_multi_4(_t, _h, _o, _a, _c) \
295 : ((_t)->write_multi_4((_h), (_o), (_a), (_c)))
296 : #define bus_space_write_multi_8(_t, _h, _o, _a, _c) \
297 : ((_t)->write_multi_8((_h), (_o), (_a), (_c)))
298 :
299 : /*
300 : * void bus_space_write_raw_multi_N(bus_space_tag_t tag,
301 : * bus_space_handle_t bsh, bus_size_t offset,
302 : * const u_int8_t *addr, size_t count);
303 : *
304 : * Write `count' bytes in 2, 4 or 8 byte wide quantities from the buffer
305 : * provided to bus space described by tag/handle/offset. The buffer
306 : * must have proper alignment for the N byte wide entities. Furthermore
307 : * possible byte-swapping should be done by these functions.
308 : */
309 :
310 : #define bus_space_write_raw_multi_2(_t, _h, _o, _a, _c) \
311 : ((_t)->write_multi_2((_h), (_o), (const u_int16_t *)(_a), (_c) >> 1))
312 : #define bus_space_write_raw_multi_4(_t, _h, _o, _a, _c) \
313 : ((_t)->write_multi_4((_h), (_o), (const u_int32_t *)(_a), (_c) >> 2))
314 : #define bus_space_write_raw_multi_8(_t, _h, _o, _a, _c) \
315 : ((_t)->write_multi_8((_h), (_o), (const u_int64_t *)(_a), (_c) >> 3))
316 :
317 : /*
318 : * void bus_space_write_region_N(bus_space_tag_t tag,
319 : * bus_space_handle_t bsh, bus_size_t offset,
320 : * const u_intN_t *addr, size_t count);
321 : *
322 : * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
323 : * to bus space described by tag/handle starting at `offset'.
324 : */
325 :
326 : void (*write_region_1)(bus_space_handle_t,
327 : bus_size_t, const u_int8_t *, bus_size_t);
328 : void (*write_region_2)(bus_space_handle_t,
329 : bus_size_t, const u_int16_t *, bus_size_t);
330 : void (*write_region_4)(bus_space_handle_t,
331 : bus_size_t, const u_int32_t *, bus_size_t);
332 : void (*write_region_8)(bus_space_handle_t,
333 : bus_size_t, const u_int64_t *, bus_size_t);
334 :
335 : #define bus_space_write_region_1(_t, _h, _o, _a, _c) \
336 : ((_t)->write_region_1((_h), (_o), (_a), (_c)))
337 : #define bus_space_write_region_2(_t, _h, _o, _a, _c) \
338 : ((_t)->write_region_2((_h), (_o), (_a), (_c)))
339 : #define bus_space_write_region_4(_t, _h, _o, _a, _c) \
340 : ((_t)->write_region_4((_h), (_o), (_a), (_c)))
341 : #define bus_space_write_region_8(_t, _h, _o, _a, _c) \
342 : ((_t)->write_region_8((_h), (_o), (_a), (_c)))
343 :
344 : /*
345 : * void bus_space_write_raw_region_N(bus_space_tag_t tag,
346 : * bus_space_handle_t bsh, bus_size_t offset,
347 : * const u_int8_t *addr, size_t count);
348 : *
349 : * Write `count' bytes in 2, 4 or 8 byte wide quantities to bus space
350 : * described by tag/handle and starting at `offset' from the
351 : * buffer provided. The buffer must have proper alignment for the N byte
352 : * wide entities. Furthermore possible byte-swapping should be done by
353 : * these functions.
354 : */
355 :
356 : #define bus_space_write_raw_region_2(_t, _h, _o, _a, _c) \
357 : ((_t)->write_region_2((_h), (_o), (const u_int16_t *)(_a), (_c) >> 1))
358 : #define bus_space_write_raw_region_4(_t, _h, _o, _a, _c) \
359 : ((_t)->write_region_4((_h), (_o), (const u_int32_t *)(_a), (_c) >> 2))
360 : #define bus_space_write_raw_region_8(_t, _h, _o, _a, _c) \
361 : ((_t)->write_region_8((_h), (_o), (const u_int64_t *)(_a), (_c) >> 3))
362 :
363 : /*
364 : * void bus_space_set_multi_N(bus_space_tag_t tag,
365 : * bus_space_handle_t bsh, bus_size_t offset,
366 : * u_intN_t val, size_t count);
367 : *
368 : * Write the 1, 2, 4, or 8 byte value `val' to bus space described
369 : * by tag/handle/offset `count' times.
370 : */
371 :
372 : void (*set_multi_1)(bus_space_handle_t,
373 : bus_size_t, u_int8_t, size_t);
374 : void (*set_multi_2)(bus_space_handle_t,
375 : bus_size_t, u_int16_t, size_t);
376 : void (*set_multi_4)(bus_space_handle_t,
377 : bus_size_t, u_int32_t, size_t);
378 : void (*set_multi_8)(bus_space_handle_t,
379 : bus_size_t, u_int64_t, size_t);
380 :
381 : #define bus_space_set_multi_1(_t, _h, _o, _a, _c) \
382 : ((_t)->set_multi_1((_h), (_o), (_a), (_c)))
383 : #define bus_space_set_multi_2(_t, _h, _o, _a, _c) \
384 : ((_t)->set_multi_2((_h), (_o), (_a), (_c)))
385 : #define bus_space_set_multi_4(_t, _h, _o, _a, _c) \
386 : ((_t)->set_multi_4((_h), (_o), (_a), (_c)))
387 : #define bus_space_set_multi_8(_t, _h, _o, _a, _c) \
388 : ((_t)->set_multi_8((_h), (_o), (_a), (_c)))
389 :
390 : /*
391 : * void bus_space_set_region_N(bus_space_tag_t tag,
392 : * bus_space_handle_t bsh, bus_size_t offset,
393 : * u_intN_t val, size_t count);
394 : *
395 : * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
396 : * by tag/handle starting at `offset'.
397 : */
398 :
399 : void (*set_region_1)(bus_space_handle_t,
400 : bus_size_t, u_int8_t, size_t);
401 : void (*set_region_2)(bus_space_handle_t,
402 : bus_size_t, u_int16_t, size_t);
403 : void (*set_region_4)(bus_space_handle_t,
404 : bus_size_t, u_int32_t, size_t);
405 : void (*set_region_8)(bus_space_handle_t,
406 : bus_size_t, u_int64_t, size_t);
407 :
408 : #define bus_space_set_region_1(_t, _h, _o, _a, _c) \
409 : ((_t)->set_region_1((_h), (_o), (_a), (_c)))
410 : #define bus_space_set_region_2(_t, _h, _o, _a, _c) \
411 : ((_t)->set_region_2((_h), (_o), (_a), (_c)))
412 : #define bus_space_set_region_4(_t, _h, _o, _a, _c) \
413 : ((_t)->set_region_4((_h), (_o), (_a), (_c)))
414 : #define bus_space_set_region_8(_t, _h, _o, _a, _c) \
415 : ((_t)->set_region_8((_h), (_o), (_a), (_c)))
416 :
417 : /*
418 : * void bus_space_copy_N(bus_space_tag_t tag,
419 : * bus_space_handle_t bsh1, bus_size_t off1,
420 : * bus_space_handle_t bsh2, bus_size_t off2,
421 : * size_t count);
422 : *
423 : * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
424 : * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
425 : */
426 :
427 : void (*copy_1)(bus_space_handle_t,
428 : bus_size_t, bus_space_handle_t, bus_size_t, size_t);
429 : void (*copy_2)(bus_space_handle_t,
430 : bus_size_t, bus_space_handle_t, bus_size_t, size_t);
431 : void (*copy_4)(bus_space_handle_t,
432 : bus_size_t, bus_space_handle_t, bus_size_t, size_t);
433 : void (*copy_8)(bus_space_handle_t,
434 : bus_size_t, bus_space_handle_t, bus_size_t, size_t);
435 :
436 : #define bus_space_copy_1(_t, _h1, _o1, _h2, _o2, _c) \
437 : ((_t)->copy_1((_h1), (_o1), (_h2), (_o2), (_c)))
438 : #define bus_space_copy_2(_t, _h1, _o1, _h2, _o2, _c) \
439 : ((_t)->copy_2((_h1), (_o1), (_h2), (_o2), (_c)))
440 : #define bus_space_copy_4(_t, _h1, _o1, _h2, _o2, _c) \
441 : ((_t)->copy_4((_h1), (_o1), (_h2), (_o2), (_c)))
442 : #define bus_space_copy_8(_t, _h1, _o1, _h2, _o2, _c) \
443 : ((_t)->copy_8((_h1), (_o1), (_h2), (_o2), (_c)))
444 :
445 : /*
446 : * void *bus_space_vaddr(bus_space_tag_t, bus_space_handle_t);
447 : *
448 : * Get the kernel virtual address for the mapped bus space.
449 : * Only allowed for regions mapped with BUS_SPACE_MAP_LINEAR.
450 : */
451 : void * (*vaddr)(bus_space_handle_t);
452 :
453 : #define bus_space_vaddr(_t, _h) \
454 : ((_t)->vaddr((_h)))
455 :
456 : /*
457 : * paddr_t bus_space_mmap(bus_space_tag_t t, bus_addr_t base,
458 : * off_t offset, int prot, int flags);
459 : *
460 : * Mmap an area of bus space.
461 : */
462 :
463 : paddr_t (*mmap)(bus_addr_t, off_t, int, int);
464 :
465 : #define bus_space_mmap(_t, _a, _o, _p, _f) \
466 : ((_t)->mmap((_a), (_o), (_p), (_f)))
467 : };
468 :
469 : /*
470 : * Bus read/write barrier methods.
471 : */
472 : #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */
473 : #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */
474 :
475 : static inline void
476 0 : bus_space_barrier(bus_space_tag_t space, bus_space_handle_t
477 : handle, bus_size_t offset, bus_size_t length, int flags)
478 : {
479 0 : switch (flags) {
480 : case (BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE):
481 0 : __asm volatile("mfence");
482 0 : break;
483 : case BUS_SPACE_BARRIER_WRITE:
484 0 : __asm volatile("sfence");
485 0 : break;
486 : default:
487 0 : __asm volatile("lfence");
488 0 : break;
489 : }
490 0 : }
491 :
492 : #define BUS_SPACE_MAP_CACHEABLE 0x0001
493 : #define BUS_SPACE_MAP_LINEAR 0x0002
494 : #define BUS_SPACE_MAP_PREFETCHABLE 0x0008
495 :
496 : /*
497 : * Values for the x86 bus space tag, not to be used directly by MI code.
498 : */
499 :
500 : /* space is i/o space */
501 : extern const struct x86_bus_space_ops x86_bus_space_io_ops;
502 : #define X86_BUS_SPACE_IO (&x86_bus_space_io_ops)
503 :
504 : /* space is mem space */
505 : extern const struct x86_bus_space_ops x86_bus_space_mem_ops;
506 : #define X86_BUS_SPACE_MEM (&x86_bus_space_mem_ops)
507 :
508 : /*
509 : * bus_dma
510 : */
511 :
512 : /*
513 : * Flags used in various bus DMA methods.
514 : */
515 : #define BUS_DMA_WAITOK 0x0000 /* safe to sleep (pseudo-flag) */
516 : #define BUS_DMA_NOWAIT 0x0001 /* not safe to sleep */
517 : #define BUS_DMA_ALLOCNOW 0x0002 /* perform resource allocation now */
518 : #define BUS_DMA_COHERENT 0x0004 /* hint: map memory DMA coherent */
519 : #define BUS_DMA_BUS1 0x0010 /* placeholders for bus functions... */
520 : #define BUS_DMA_BUS2 0x0020
521 : #define BUS_DMA_32BIT 0x0040
522 : #define BUS_DMA_24BIT 0x0080 /* isadma map */
523 : #define BUS_DMA_STREAMING 0x0100 /* hint: sequential, unidirectional */
524 : #define BUS_DMA_READ 0x0200 /* mapping is device -> memory only */
525 : #define BUS_DMA_WRITE 0x0400 /* mapping is memory -> device only */
526 : #define BUS_DMA_NOCACHE 0x0800 /* map memory uncached */
527 : #define BUS_DMA_ZERO 0x1000 /* zero memory in dmamem_alloc */
528 : #define BUS_DMA_64BIT 0x2000 /* device handles 64bit dva */
529 :
530 : /* Forwards needed by prototypes below. */
531 : struct mbuf;
532 : struct proc;
533 : struct uio;
534 :
535 : /*
536 : * Operations performed by bus_dmamap_sync().
537 : */
538 : #define BUS_DMASYNC_PREREAD 0x01
539 : #define BUS_DMASYNC_POSTREAD 0x02
540 : #define BUS_DMASYNC_PREWRITE 0x04
541 : #define BUS_DMASYNC_POSTWRITE 0x08
542 :
543 : typedef struct bus_dma_tag *bus_dma_tag_t;
544 : typedef struct bus_dmamap *bus_dmamap_t;
545 :
546 : /*
547 : * bus_dma_segment_t
548 : *
549 : * Describes a single contiguous DMA transaction. Values
550 : * are suitable for programming into DMA registers.
551 : */
552 : struct bus_dma_segment {
553 : bus_addr_t ds_addr; /* DMA address */
554 : bus_size_t ds_len; /* length of transfer */
555 : /*
556 : * Ugh. need this so can pass alignment down from bus_dmamem_alloc
557 : * to scatter gather maps. only the first one is used so the rest is
558 : * wasted space. bus_dma could do with fixing the api for this.
559 : */
560 : bus_size_t _ds_boundary; /* don't cross */
561 : bus_size_t _ds_align; /* align to me */
562 : };
563 : typedef struct bus_dma_segment bus_dma_segment_t;
564 :
565 : /*
566 : * bus_dma_tag_t
567 : *
568 : * A machine-dependent opaque type describing the implementation of
569 : * DMA for a given bus.
570 : */
571 :
572 : struct bus_dma_tag {
573 : void *_cookie; /* cookie used in the guts */
574 :
575 : /*
576 : * DMA mapping methods.
577 : */
578 : int (*_dmamap_create)(bus_dma_tag_t, bus_size_t, int,
579 : bus_size_t, bus_size_t, int, bus_dmamap_t *);
580 : void (*_dmamap_destroy)(bus_dma_tag_t, bus_dmamap_t);
581 : int (*_dmamap_load)(bus_dma_tag_t, bus_dmamap_t, void *,
582 : bus_size_t, struct proc *, int);
583 : int (*_dmamap_load_mbuf)(bus_dma_tag_t, bus_dmamap_t,
584 : struct mbuf *, int);
585 : int (*_dmamap_load_uio)(bus_dma_tag_t, bus_dmamap_t,
586 : struct uio *, int);
587 : int (*_dmamap_load_raw)(bus_dma_tag_t, bus_dmamap_t,
588 : bus_dma_segment_t *, int, bus_size_t, int);
589 : void (*_dmamap_unload)(bus_dma_tag_t, bus_dmamap_t);
590 : void (*_dmamap_sync)(bus_dma_tag_t, bus_dmamap_t,
591 : bus_addr_t, bus_size_t, int);
592 :
593 : /*
594 : * DMA memory utility functions.
595 : */
596 : int (*_dmamem_alloc)(bus_dma_tag_t, bus_size_t, bus_size_t,
597 : bus_size_t, bus_dma_segment_t *, int, int *, int);
598 : int (*_dmamem_alloc_range)(bus_dma_tag_t, bus_size_t, bus_size_t,
599 : bus_size_t, bus_dma_segment_t *, int, int *, int,
600 : bus_addr_t, bus_addr_t);
601 : void (*_dmamem_free)(bus_dma_tag_t,
602 : bus_dma_segment_t *, int);
603 : int (*_dmamem_map)(bus_dma_tag_t, bus_dma_segment_t *,
604 : int, size_t, caddr_t *, int);
605 : void (*_dmamem_unmap)(bus_dma_tag_t, caddr_t, size_t);
606 : paddr_t (*_dmamem_mmap)(bus_dma_tag_t, bus_dma_segment_t *,
607 : int, off_t, int, int);
608 : };
609 :
610 : #define bus_dmamap_create(t, s, n, m, b, f, p) \
611 : (*(t)->_dmamap_create)((t), (s), (n), (m), (b), (f), (p))
612 : #define bus_dmamap_destroy(t, p) \
613 : (*(t)->_dmamap_destroy)((t), (p))
614 : #define bus_dmamap_load(t, m, b, s, p, f) \
615 : (*(t)->_dmamap_load)((t), (m), (b), (s), (p), (f))
616 : #define bus_dmamap_load_mbuf(t, m, b, f) \
617 : (*(t)->_dmamap_load_mbuf)((t), (m), (b), (f))
618 : #define bus_dmamap_load_uio(t, m, u, f) \
619 : (*(t)->_dmamap_load_uio)((t), (m), (u), (f))
620 : #define bus_dmamap_load_raw(t, m, sg, n, s, f) \
621 : (*(t)->_dmamap_load_raw)((t), (m), (sg), (n), (s), (f))
622 : #define bus_dmamap_unload(t, p) \
623 : (*(t)->_dmamap_unload)((t), (p))
624 : #define bus_dmamap_sync(t, p, o, l, ops) \
625 : (*(t)->_dmamap_sync)((t), (p), (o), (l), (ops))
626 :
627 : #define bus_dmamem_alloc(t, s, a, b, sg, n, r, f) \
628 : (*(t)->_dmamem_alloc)((t), (s), (a), (b), (sg), (n), (r), (f))
629 : #define bus_dmamem_alloc_range(t, s, a, b, sg, n, r, f, l, h) \
630 : (*(t)->_dmamem_alloc_range)((t), (s), (a), (b), (sg), \
631 : (n), (r), (f), (l), (h))
632 : #define bus_dmamem_free(t, sg, n) \
633 : (*(t)->_dmamem_free)((t), (sg), (n))
634 : #define bus_dmamem_map(t, sg, n, s, k, f) \
635 : (*(t)->_dmamem_map)((t), (sg), (n), (s), (k), (f))
636 : #define bus_dmamem_unmap(t, k, s) \
637 : (*(t)->_dmamem_unmap)((t), (k), (s))
638 : #define bus_dmamem_mmap(t, sg, n, o, p, f) \
639 : (*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
640 :
641 : /*
642 : * bus_dmamap_t
643 : *
644 : * Describes a DMA mapping.
645 : */
646 : struct bus_dmamap {
647 : /*
648 : * PRIVATE MEMBERS: not for use by machine-independent code.
649 : */
650 : bus_size_t _dm_size; /* largest DMA transfer mappable */
651 : int _dm_flags; /* misc. flags */
652 : int _dm_segcnt; /* number of segs this map can map */
653 : bus_size_t _dm_maxsegsz; /* largest possible segment */
654 : bus_size_t _dm_boundary; /* don't cross this */
655 :
656 : void *_dm_cookie; /* cookie for bus-specific functions */
657 :
658 : /*
659 : * PUBLIC MEMBERS: these are used by machine-independent code.
660 : */
661 : bus_size_t dm_mapsize; /* size of the mapping */
662 : int dm_nsegs; /* # valid segments in mapping */
663 : bus_dma_segment_t dm_segs[1]; /* segments; variable length */
664 : };
665 :
666 : int _bus_dmamap_create(bus_dma_tag_t, bus_size_t, int, bus_size_t,
667 : bus_size_t, int, bus_dmamap_t *);
668 : void _bus_dmamap_destroy(bus_dma_tag_t, bus_dmamap_t);
669 : int _bus_dmamap_load(bus_dma_tag_t, bus_dmamap_t, void *,
670 : bus_size_t, struct proc *, int);
671 : int _bus_dmamap_load_mbuf(bus_dma_tag_t, bus_dmamap_t,
672 : struct mbuf *, int);
673 : int _bus_dmamap_load_uio(bus_dma_tag_t, bus_dmamap_t,
674 : struct uio *, int);
675 : int _bus_dmamap_load_raw(bus_dma_tag_t, bus_dmamap_t,
676 : bus_dma_segment_t *, int, bus_size_t, int);
677 : void _bus_dmamap_unload(bus_dma_tag_t, bus_dmamap_t);
678 : void _bus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t, bus_addr_t,
679 : bus_size_t, int);
680 :
681 : int _bus_dmamem_alloc(bus_dma_tag_t tag, bus_size_t size,
682 : bus_size_t alignment, bus_size_t boundary,
683 : bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags);
684 : void _bus_dmamem_free(bus_dma_tag_t tag, bus_dma_segment_t *segs,
685 : int nsegs);
686 : int _bus_dmamem_map(bus_dma_tag_t tag, bus_dma_segment_t *segs,
687 : int nsegs, size_t size, caddr_t *kvap, int flags);
688 : void _bus_dmamem_unmap(bus_dma_tag_t tag, caddr_t kva,
689 : size_t size);
690 : paddr_t _bus_dmamem_mmap(bus_dma_tag_t tag, bus_dma_segment_t *segs,
691 : int nsegs, off_t off, int prot, int flags);
692 :
693 : int _bus_dmamem_alloc_range(bus_dma_tag_t tag, bus_size_t size,
694 : bus_size_t alignment, bus_size_t boundary,
695 : bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags,
696 : bus_addr_t low, bus_addr_t high);
697 :
698 : #endif /* _MACHINE_BUS_H_ */
|