xref: /openbsd/sys/arch/amd64/include/bus.h (revision 3cab2bb3)
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 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 	switch (flags) {
480 	case (BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE):
481 		__asm volatile("mfence");
482 		break;
483 	case BUS_SPACE_BARRIER_WRITE:
484 		__asm volatile("sfence");
485 		break;
486 	default:
487 		__asm volatile("lfence");
488 		break;
489 	}
490 }
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_ */
699