xref: /openbsd/sys/arch/amd64/include/bus.h (revision 891d7ab6)
1 /*	$OpenBSD: bus.h,v 1.25 2011/03/23 16:54:34 pirofti 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  * Values for the x86 bus space tag, not to be used directly by MI code.
76  */
77 #define	X86_BUS_SPACE_IO	0	/* space is i/o space */
78 #define X86_BUS_SPACE_MEM	1	/* space is mem space */
79 
80 /*
81  * Bus address and size types
82  */
83 typedef u_long bus_addr_t;
84 typedef u_long bus_size_t;
85 
86 /*
87  * Access methods for bus resources and address space.
88  */
89 typedef	int bus_space_tag_t;
90 typedef	u_long bus_space_handle_t;
91 
92 int	bus_space_map(bus_space_tag_t t, bus_addr_t addr,
93     bus_size_t size, int flags, bus_space_handle_t *bshp);
94 /* like map, but without extent map checking/allocation */
95 int	_bus_space_map(bus_space_tag_t t, bus_addr_t addr,
96     bus_size_t size, int flags, bus_space_handle_t *bshp);
97 
98 int	bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart,
99 	    bus_addr_t rend, bus_size_t size, bus_size_t align,
100 	    bus_size_t boundary, int flags, bus_addr_t *addrp,
101 	    bus_space_handle_t *bshp);
102 void	bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh,
103 	    bus_size_t size);
104 
105 /*
106  *      int bus_space_unmap(bus_space_tag_t t,
107  *          bus_space_handle_t bsh, bus_size_t size);
108  *
109  * Unmap a region of bus space.
110  */
111 
112 void	bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh,
113 	    bus_size_t size);
114 void	_bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh,
115 	    bus_size_t size, bus_addr_t *);
116 
117 /* like bus_space_map(), but without extent map checking/allocation */
118 int	_bus_space_map(bus_space_tag_t t, bus_addr_t addr,
119 	    bus_size_t size, int flags, bus_space_handle_t *bshp);
120 
121 /*
122  *      int bus_space_subregion(bus_space_tag_t t,
123  *          bus_space_handle_t bsh, bus_size_t offset, bus_size_t size,
124  *          bus_space_handle_t *nbshp);
125  *
126  * Get a new handle for a subregion of an already-mapped area of bus space.
127  */
128 
129 int	bus_space_subregion(bus_space_tag_t t, bus_space_handle_t bsh,
130 	    bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp);
131 
132 /*
133  *	u_intN_t bus_space_read_N(bus_space_tag_t tag,
134  *	    bus_space_handle_t bsh, bus_size_t offset);
135  *
136  * Read a 1, 2, 4, or 8 byte quantity from bus space
137  * described by tag/handle/offset.
138  */
139 u_int8_t	bus_space_read_1(bus_space_tag_t, bus_space_handle_t,
140 		    bus_size_t);
141 
142 u_int16_t	bus_space_read_2(bus_space_tag_t, bus_space_handle_t,
143 		    bus_size_t);
144 
145 u_int32_t	bus_space_read_4(bus_space_tag_t, bus_space_handle_t,
146 		    bus_size_t);
147 
148 #if 0	/* Cause a link error for bus_space_read_8 */
149 #define	bus_space_read_8(t, h, o)	!!! bus_space_read_8 unimplemented !!!
150 #endif
151 
152 /*
153  *	void bus_space_read_multi_N(bus_space_tag_t tag,
154  *	    bus_space_handle_t bsh, bus_size_t offset,
155  *	    u_intN_t *addr, size_t count);
156  *
157  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
158  * described by tag/handle/offset and copy into buffer provided.
159  */
160 
161 void	bus_space_read_multi_1(bus_space_tag_t, bus_space_handle_t, bus_size_t,
162 	    u_int8_t *, bus_size_t);
163 
164 void	bus_space_read_multi_2(bus_space_tag_t, bus_space_handle_t, bus_size_t,
165 	    u_int16_t *, bus_size_t);
166 
167 void	bus_space_read_multi_4(bus_space_tag_t, bus_space_handle_t, bus_size_t,
168 	    u_int32_t *, bus_size_t);
169 
170 #if 0	/* Cause a link error for bus_space_read_multi_8 */
171 #define	bus_space_read_multi_8	!!! bus_space_read_multi_8 unimplemented !!!
172 #endif
173 
174 /*
175  *	void bus_space_read_raw_multi_N(bus_space_tag_t tag,
176  *	    bus_space_handle_t bsh, bus_size_t offset,
177  *	    u_int8_t *addr, size_t count);
178  *
179  * Read `count' bytes in 2, 4 or 8 byte wide quantities from bus space
180  * described by tag/handle/offset and copy into buffer provided.  The buffer
181  * must have proper alignment for the N byte wide entities.  Furthermore
182  * possible byte-swapping should be done by these functions.
183  */
184 
185 #define	bus_space_read_raw_multi_2(t, h, o, a, c) \
186     bus_space_read_multi_2((t), (h), (o), (u_int16_t *)(a), (c) >> 1)
187 #define	bus_space_read_raw_multi_4(t, h, o, a, c) \
188     bus_space_read_multi_4((t), (h), (o), (u_int32_t *)(a), (c) >> 2)
189 
190 #if 0	/* Cause a link error for bus_space_read_raw_multi_8 */
191 #define	bus_space_read_raw_multi_8 \
192     !!! bus_space_read_raw_multi_8 unimplemented !!!
193 #endif
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	bus_space_read_region_1(bus_space_tag_t, bus_space_handle_t,
206 	    bus_size_t, u_int8_t *, bus_size_t);
207 void	bus_space_read_region_2(bus_space_tag_t, bus_space_handle_t,
208 	    bus_size_t, u_int16_t *, bus_size_t);
209 void	bus_space_read_region_4(bus_space_tag_t, bus_space_handle_t,
210 	    bus_size_t, u_int32_t *, bus_size_t);
211 
212 #define bus_space_read_region_stream_1 bus_space_read_region_1
213 #if 0	/* Cause a link error for bus_space_read_region_8 */
214 #define	bus_space_read_region_8	!!! bus_space_read_region_8 unimplemented !!!
215 #endif
216 
217 /*
218  *	void bus_space_read_raw_region_N(bus_space_tag_t tag,
219  *	    bus_space_handle_t bsh, bus_size_t offset,
220  *	    u_int8_t *addr, size_t count);
221  *
222  * Read `count' bytes in 2, 4 or 8 byte wide quantities from bus space
223  * described by tag/handle and starting at `offset' and copy into
224  * buffer provided.  The buffer must have proper alignment for the N byte
225  * wide entities.  Furthermore possible byte-swapping should be done by
226  * these functions.
227  */
228 
229 #define	bus_space_read_raw_region_2(t, h, o, a, c) \
230     bus_space_read_region_2((t), (h), (o), (u_int16_t *)(a), (c) >> 1)
231 #define	bus_space_read_raw_region_4(t, h, o, a, c) \
232     bus_space_read_region_4((t), (h), (o), (u_int32_t *)(a), (c) >> 2)
233 
234 #if 0	/* Cause a link error for bus_space_read_raw_region_8 */
235 #define	bus_space_read_raw_region_8 \
236     !!! bus_space_read_raw_region_8 unimplemented !!!
237 #endif
238 
239 /*
240  *	void bus_space_write_N(bus_space_tag_t tag,
241  *	    bus_space_handle_t bsh, bus_size_t offset,
242  *	    u_intN_t value);
243  *
244  * Write the 1, 2, 4, or 8 byte value `value' to bus space
245  * described by tag/handle/offset.
246  */
247 
248 void	bus_space_write_1(bus_space_tag_t, bus_space_handle_t,
249 	    bus_size_t, u_int8_t);
250 void	bus_space_write_2(bus_space_tag_t, bus_space_handle_t,
251 	    bus_size_t, u_int16_t);
252 void	bus_space_write_4(bus_space_tag_t, bus_space_handle_t,
253 	    bus_size_t, u_int32_t);
254 
255 #if 0	/* Cause a link error for bus_space_write_8 */
256 #define	bus_space_write_8	!!! bus_space_write_8 not implemented !!!
257 #endif
258 
259 /*
260  *	void bus_space_write_multi_N(bus_space_tag_t tag,
261  *	    bus_space_handle_t bsh, bus_size_t offset,
262  *	    const u_intN_t *addr, size_t count);
263  *
264  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
265  * provided to bus space described by tag/handle/offset.
266  */
267 
268 void	bus_space_write_multi_1(bus_space_tag_t, bus_space_handle_t,
269 	    bus_size_t, const u_int8_t *, bus_size_t);
270 void	bus_space_write_multi_2(bus_space_tag_t, bus_space_handle_t,
271 	    bus_size_t, const u_int16_t *, bus_size_t);
272 void	bus_space_write_multi_4(bus_space_tag_t, bus_space_handle_t,
273 	    bus_size_t, const u_int32_t *, bus_size_t);
274 
275 #if 0	/* Cause a link error for bus_space_write_multi_8 */
276 #define	bus_space_write_multi_8(t, h, o, a, c)				\
277 			!!! bus_space_write_multi_8 unimplemented !!!
278 #endif
279 
280 /*
281  *	void bus_space_write_raw_multi_N(bus_space_tag_t tag,
282  *	    bus_space_handle_t bsh, bus_size_t offset,
283  *	    const u_int8_t *addr, size_t count);
284  *
285  * Write `count' bytes in 2, 4 or 8 byte wide quantities from the buffer
286  * provided to bus space described by tag/handle/offset.  The buffer
287  * must have proper alignment for the N byte wide entities.  Furthermore
288  * possible byte-swapping should be done by these functions.
289  */
290 
291 #define	bus_space_write_raw_multi_2(t, h, o, a, c) \
292     bus_space_write_multi_2((t), (h), (o), (const u_int16_t *)(a), (c) >> 1)
293 #define	bus_space_write_raw_multi_4(t, h, o, a, c) \
294     bus_space_write_multi_4((t), (h), (o), (const u_int32_t *)(a), (c) >> 2)
295 
296 #if 0	/* Cause a link error for bus_space_write_raw_multi_8 */
297 #define	bus_space_write_raw_multi_8 \
298     !!! bus_space_write_raw_multi_8 unimplemented !!!
299 #endif
300 
301 /*
302  *	void bus_space_write_region_N(bus_space_tag_t tag,
303  *	    bus_space_handle_t bsh, bus_size_t offset,
304  *	    const u_intN_t *addr, size_t count);
305  *
306  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
307  * to bus space described by tag/handle starting at `offset'.
308  */
309 
310 void	bus_space_write_region_1(bus_space_tag_t, bus_space_handle_t,
311 	    bus_size_t, const u_int8_t *, bus_size_t);
312 void	bus_space_write_region_2(bus_space_tag_t, bus_space_handle_t,
313 	    bus_size_t, const u_int16_t *, bus_size_t);
314 void	bus_space_write_region_4(bus_space_tag_t, bus_space_handle_t,
315 	    bus_size_t, const u_int32_t *, bus_size_t);
316 
317 #if 0	/* Cause a link error for bus_space_write_region_8 */
318 #define	bus_space_write_region_8					\
319 			!!! bus_space_write_region_8 unimplemented !!!
320 #endif
321 
322 /*
323  *	void bus_space_write_raw_region_N(bus_space_tag_t tag,
324  *	    bus_space_handle_t bsh, bus_size_t offset,
325  *	    const u_int8_t *addr, size_t count);
326  *
327  * Write `count' bytes in 2, 4 or 8 byte wide quantities to bus space
328  * described by tag/handle and starting at `offset' from the
329  * buffer provided.  The buffer must have proper alignment for the N byte
330  * wide entities.  Furthermore possible byte-swapping should be done by
331  * these functions.
332  */
333 
334 #define	bus_space_write_raw_region_2(t, h, o, a, c) \
335     bus_space_write_region_2((t), (h), (o), (const u_int16_t *)(a), (c) >> 1)
336 #define	bus_space_write_raw_region_4(t, h, o, a, c) \
337     bus_space_write_region_4((t), (h), (o), (const u_int32_t *)(a), (c) >> 2)
338 
339 #if 0	/* Cause a link error for bus_space_write_raw_region_8 */
340 #define	bus_space_write_raw_region_8 \
341     !!! bus_space_write_raw_region_8 unimplemented !!!
342 #endif
343 
344 /*
345  *	void bus_space_set_multi_N(bus_space_tag_t tag,
346  *	    bus_space_handle_t bsh, bus_size_t offset,
347  *	    u_intN_t val, size_t count);
348  *
349  * Write the 1, 2, 4, or 8 byte value `val' to bus space described
350  * by tag/handle/offset `count' times.
351  */
352 
353 void	bus_space_set_multi_1(bus_space_tag_t, bus_space_handle_t,
354 	    bus_size_t, u_int8_t, size_t);
355 void	bus_space_set_multi_2(bus_space_tag_t, bus_space_handle_t,
356 	    bus_size_t, u_int16_t, size_t);
357 void	bus_space_set_multi_4(bus_space_tag_t, bus_space_handle_t,
358 	    bus_size_t, u_int32_t, size_t);
359 
360 #if 0	/* Cause a link error for bus_space_set_multi_8 */
361 #define	bus_space_set_multi_8					\
362 			!!! bus_space_set_multi_8 unimplemented !!!
363 #endif
364 
365 /*
366  *	void bus_space_set_region_N(bus_space_tag_t tag,
367  *	    bus_space_handle_t bsh, bus_size_t offset,
368  *	    u_intN_t val, size_t count);
369  *
370  * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
371  * by tag/handle starting at `offset'.
372  */
373 
374 void	bus_space_set_region_1(bus_space_tag_t, bus_space_handle_t,
375 	    bus_size_t, u_int8_t, size_t);
376 void	bus_space_set_region_2(bus_space_tag_t, bus_space_handle_t,
377 	    bus_size_t, u_int16_t, size_t);
378 void	bus_space_set_region_4(bus_space_tag_t, bus_space_handle_t,
379 	    bus_size_t, u_int32_t, size_t);
380 
381 #if 0	/* Cause a link error for bus_space_set_region_8 */
382 #define	bus_space_set_region_8					\
383 			!!! bus_space_set_region_8 unimplemented !!!
384 #endif
385 
386 /*
387  *	void bus_space_copy_N(bus_space_tag_t tag,
388  *	    bus_space_handle_t bsh1, bus_size_t off1,
389  *	    bus_space_handle_t bsh2, bus_size_t off2,
390  *	    size_t count);
391  *
392  * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
393  * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
394  */
395 
396 void	bus_space_copy_1(bus_space_tag_t, bus_space_handle_t,
397 	    bus_size_t, bus_space_handle_t, bus_size_t, size_t);
398 void	bus_space_copy_2(bus_space_tag_t, bus_space_handle_t,
399 	    bus_size_t, bus_space_handle_t, bus_size_t, size_t);
400 void	bus_space_copy_4(bus_space_tag_t, bus_space_handle_t,
401 	    bus_size_t, bus_space_handle_t, bus_size_t, size_t);
402 
403 #if 0	/* Cause a link error for bus_space_copy_8 */
404 #define	bus_space_copy_8					\
405 			!!! bus_space_copy_8 unimplemented !!!
406 #endif
407 
408 /*
409  * Bus read/write barrier methods.
410  */
411 #define	BUS_SPACE_BARRIER_READ	0x01		/* force read barrier */
412 #define	BUS_SPACE_BARRIER_WRITE	0x02		/* force write barrier */
413 
414 void	bus_space_barrier(bus_space_tag_t, bus_space_handle_t,
415 	    bus_size_t, bus_size_t, int);
416 
417 #define	BUS_SPACE_MAP_CACHEABLE		0x0001
418 #define	BUS_SPACE_MAP_LINEAR		0x0002
419 #define	BUS_SPACE_MAP_PREFETCHABLE	0x0008
420 
421 /*
422  *	void *bus_space_vaddr(bus_space_tag_t, bus_space_handle_t);
423  *
424  * Get the kernel virtual address for the mapped bus space.
425  * Only allowed for regions mapped with BUS_SPACE_MAP_LINEAR.
426  */
427 #define bus_space_vaddr(t, h) \
428 	((t) == X86_BUS_SPACE_IO ? (void *)(NULL) : (void *)(h))
429 /*
430  * Flags used in various bus DMA methods.
431  */
432 #define	BUS_DMA_WAITOK		0x0000	/* safe to sleep (pseudo-flag) */
433 #define	BUS_DMA_NOWAIT		0x0001	/* not safe to sleep */
434 #define	BUS_DMA_ALLOCNOW	0x0002	/* perform resource allocation now */
435 #define	BUS_DMA_COHERENT	0x0004	/* hint: map memory DMA coherent */
436 #define	BUS_DMA_BUS1		0x0010	/* placeholders for bus functions... */
437 #define	BUS_DMA_BUS2		0x0020
438 #define	BUS_DMA_32BIT		0x0040
439 #define	BUS_DMA_24BIT		0x0080	/* isadma map */
440 #define	BUS_DMA_STREAMING	0x0100	/* hint: sequential, unidirectional */
441 #define	BUS_DMA_READ		0x0200	/* mapping is device -> memory only */
442 #define	BUS_DMA_WRITE		0x0400	/* mapping is memory -> device only */
443 #define	BUS_DMA_NOCACHE		0x0800	/* map memory uncached */
444 #define	BUS_DMA_ZERO		0x1000	/* zero memory in dmamem_alloc */
445 #define	BUS_DMA_SG		0x2000	/* Internal. memory is for SG map */
446 
447 /* types for _dm_buftype */
448 #define	BUS_BUFTYPE_INVALID	0
449 #define	BUS_BUFTYPE_LINEAR	1
450 #define	BUS_BUFTYPE_MBUF	2
451 #define	BUS_BUFTYPE_UIO		3
452 #define	BUS_BUFTYPE_RAW		4
453 
454 /* Forwards needed by prototypes below. */
455 struct mbuf;
456 struct proc;
457 struct uio;
458 
459 /*
460  * Operations performed by bus_dmamap_sync().
461  */
462 #define BUS_DMASYNC_PREREAD	0x01
463 #define BUS_DMASYNC_POSTREAD	0x02
464 #define BUS_DMASYNC_PREWRITE	0x04
465 #define BUS_DMASYNC_POSTWRITE	0x08
466 
467 typedef struct bus_dma_tag		*bus_dma_tag_t;
468 typedef struct bus_dmamap		*bus_dmamap_t;
469 
470 /*
471  *	bus_dma_segment_t
472  *
473  *	Describes a single contiguous DMA transaction.  Values
474  *	are suitable for programming into DMA registers.
475  */
476 struct bus_dma_segment {
477 	bus_addr_t	ds_addr;	/* DMA address */
478 	bus_size_t	ds_len;		/* length of transfer */
479 	/*
480 	 * Ugh. need this so can pass alignment down from bus_dmamem_alloc
481 	 * to scatter gather maps. only the first one is used so the rest is
482 	 * wasted space. bus_dma could do with fixing the api for this.
483 	 */
484 	 bus_size_t	_ds_boundary;	/* don't cross */
485 	 bus_size_t	_ds_align;	/* align to me */
486 };
487 typedef struct bus_dma_segment	bus_dma_segment_t;
488 
489 /*
490  *	bus_dma_tag_t
491  *
492  *	A machine-dependent opaque type describing the implementation of
493  *	DMA for a given bus.
494  */
495 
496 struct bus_dma_tag {
497 	void	*_cookie;		/* cookie used in the guts */
498 
499 	/*
500 	 * DMA mapping methods.
501 	 */
502 	int	(*_dmamap_create)(bus_dma_tag_t, bus_size_t, int,
503 		    bus_size_t, bus_size_t, int, bus_dmamap_t *);
504 	void	(*_dmamap_destroy)(bus_dma_tag_t, bus_dmamap_t);
505 	int	(*_dmamap_load)(bus_dma_tag_t, bus_dmamap_t, void *,
506 		    bus_size_t, struct proc *, int);
507 	int	(*_dmamap_load_mbuf)(bus_dma_tag_t, bus_dmamap_t,
508 		    struct mbuf *, int);
509 	int	(*_dmamap_load_uio)(bus_dma_tag_t, bus_dmamap_t,
510 		    struct uio *, int);
511 	int	(*_dmamap_load_raw)(bus_dma_tag_t, bus_dmamap_t,
512 		    bus_dma_segment_t *, int, bus_size_t, int);
513 	void	(*_dmamap_unload)(bus_dma_tag_t, bus_dmamap_t);
514 	void	(*_dmamap_sync)(bus_dma_tag_t, bus_dmamap_t,
515 		    bus_addr_t, bus_size_t, int);
516 
517 	/*
518 	 * DMA memory utility functions.
519 	 */
520 	int	(*_dmamem_alloc)(bus_dma_tag_t, bus_size_t, bus_size_t,
521 		    bus_size_t, bus_dma_segment_t *, int, int *, int);
522 	void	(*_dmamem_free)(bus_dma_tag_t,
523 		    bus_dma_segment_t *, int);
524 	int	(*_dmamem_map)(bus_dma_tag_t, bus_dma_segment_t *,
525 		    int, size_t, caddr_t *, int);
526 	void	(*_dmamem_unmap)(bus_dma_tag_t, caddr_t, size_t);
527 	paddr_t	(*_dmamem_mmap)(bus_dma_tag_t, bus_dma_segment_t *,
528 		    int, off_t, int, int);
529 };
530 
531 #define	bus_dmamap_create(t, s, n, m, b, f, p)			\
532 	(*(t)->_dmamap_create)((t), (s), (n), (m), (b), (f), (p))
533 #define	bus_dmamap_destroy(t, p)				\
534 	(*(t)->_dmamap_destroy)((t), (p))
535 #define	bus_dmamap_load(t, m, b, s, p, f)			\
536 	(*(t)->_dmamap_load)((t), (m), (b), (s), (p), (f))
537 #define	bus_dmamap_load_mbuf(t, m, b, f)			\
538 	(*(t)->_dmamap_load_mbuf)((t), (m), (b), (f))
539 #define	bus_dmamap_load_uio(t, m, u, f)				\
540 	(*(t)->_dmamap_load_uio)((t), (m), (u), (f))
541 #define	bus_dmamap_load_raw(t, m, sg, n, s, f)			\
542 	(*(t)->_dmamap_load_raw)((t), (m), (sg), (n), (s), (f))
543 #define	bus_dmamap_unload(t, p)					\
544 	(*(t)->_dmamap_unload)((t), (p))
545 #define	bus_dmamap_sync(t, p, o, l, ops)			\
546 	(*(t)->_dmamap_sync)((t), (p), (o), (l), (ops))
547 
548 #define	bus_dmamem_alloc(t, s, a, b, sg, n, r, f)		\
549 	(*(t)->_dmamem_alloc)((t), (s), (a), (b), (sg), (n), (r), (f))
550 #define	bus_dmamem_free(t, sg, n)				\
551 	(*(t)->_dmamem_free)((t), (sg), (n))
552 #define	bus_dmamem_map(t, sg, n, s, k, f)			\
553 	(*(t)->_dmamem_map)((t), (sg), (n), (s), (k), (f))
554 #define	bus_dmamem_unmap(t, k, s)				\
555 	(*(t)->_dmamem_unmap)((t), (k), (s))
556 #define	bus_dmamem_mmap(t, sg, n, o, p, f)			\
557 	(*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
558 
559 /*
560  *	bus_dmamap_t
561  *
562  *	Describes a DMA mapping.
563  */
564 struct bus_dmamap {
565 	/*
566 	 * PRIVATE MEMBERS: not for use by machine-independent code.
567 	 */
568 	bus_size_t	_dm_size;	/* largest DMA transfer mappable */
569 	int		_dm_segcnt;	/* number of segs this map can map */
570 	bus_size_t	_dm_maxsegsz;	/* largest possible segment */
571 	bus_size_t	_dm_boundary;	/* don't cross this */
572 	int		_dm_flags;	/* misc. flags */
573 
574 	void		*_dm_cookie;	/* cookie for bus-specific functions */
575 
576 	/*
577 	 * PUBLIC MEMBERS: these are used by machine-independent code.
578 	 */
579 	bus_size_t	dm_mapsize;	/* size of the mapping */
580 	int		dm_nsegs;	/* # valid segments in mapping */
581 	bus_dma_segment_t dm_segs[1];	/* segments; variable length */
582 };
583 
584 int	_bus_dmamap_create(bus_dma_tag_t, bus_size_t, int, bus_size_t,
585 	    bus_size_t, int, bus_dmamap_t *);
586 void	_bus_dmamap_destroy(bus_dma_tag_t, bus_dmamap_t);
587 int	_bus_dmamap_load(bus_dma_tag_t, bus_dmamap_t, void *,
588 	    bus_size_t, struct proc *, int);
589 int	_bus_dmamap_load_mbuf(bus_dma_tag_t, bus_dmamap_t,
590 	    struct mbuf *, int);
591 int	_bus_dmamap_load_uio(bus_dma_tag_t, bus_dmamap_t,
592 	    struct uio *, int);
593 int	_bus_dmamap_load_raw(bus_dma_tag_t, bus_dmamap_t,
594 	    bus_dma_segment_t *, int, bus_size_t, int);
595 void	_bus_dmamap_unload(bus_dma_tag_t, bus_dmamap_t);
596 void	_bus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t, bus_addr_t,
597 	    bus_size_t, int);
598 
599 int	_bus_dmamem_alloc(bus_dma_tag_t tag, bus_size_t size,
600 	    bus_size_t alignment, bus_size_t boundary,
601 	    bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags);
602 void	_bus_dmamem_free(bus_dma_tag_t tag, bus_dma_segment_t *segs,
603 	    int nsegs);
604 int	_bus_dmamem_map(bus_dma_tag_t tag, bus_dma_segment_t *segs,
605 	    int nsegs, size_t size, caddr_t *kvap, int flags);
606 void	_bus_dmamem_unmap(bus_dma_tag_t tag, caddr_t kva,
607 	    size_t size);
608 paddr_t	_bus_dmamem_mmap(bus_dma_tag_t tag, bus_dma_segment_t *segs,
609 	    int nsegs, off_t off, int prot, int flags);
610 
611 int	_bus_dmamem_alloc_range(bus_dma_tag_t tag, bus_size_t size,
612 	    bus_size_t alignment, bus_size_t boundary,
613 	    bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags,
614 	    paddr_t low, paddr_t high);
615 
616 struct extent;
617 
618 /* Scatter gather bus_dma functions. */
619 struct sg_cookie {
620 	struct mutex	 sg_mtx;
621 	struct extent	*sg_ex;
622 	void		*sg_hdl;
623 
624 	void		(*bind_page)(void *, bus_addr_t, paddr_t, int);
625 	void		(*unbind_page)(void *, bus_addr_t);
626 	void		(*flush_tlb)(void *);
627 };
628 
629 /*
630  * per-map DVMA page table
631  */
632 struct sg_page_entry {
633 	SPLAY_ENTRY(sg_page_entry)	spe_node;
634 	paddr_t				spe_pa;
635 	bus_addr_t			spe_va;
636 };
637 
638 /* for sg_dma this will be in the map's dm_cookie. */
639 struct sg_page_map {
640 	SPLAY_HEAD(sg_page_tree, sg_page_entry) spm_tree;
641 
642 	void			*spm_origbuf;	/* pointer to original data */
643 	int			 spm_buftype;	/* type of data */
644 	struct proc		*spm_proc;	/* proc that owns the mapping */
645 
646 	int			 spm_maxpage;	/* Size of allocated page map */
647 	int			 spm_pagecnt;	/* Number of entries in use */
648 	bus_addr_t		 spm_start;	/* dva when bound */
649 	bus_size_t		 spm_size;	/* size of bound map */
650 	struct sg_page_entry	 spm_map[1];
651 };
652 
653 struct sg_cookie	*sg_dmatag_init(char *, void *, bus_addr_t, bus_size_t,
654 			    void (*)(void *, vaddr_t, paddr_t, int),
655 			    void (*)(void *, vaddr_t), void (*)(void *));
656 void	sg_dmatag_destroy(struct sg_cookie *);
657 int	sg_dmamap_create(bus_dma_tag_t, bus_size_t, int, bus_size_t,
658 	    bus_size_t, int, bus_dmamap_t *);
659 void	sg_dmamap_destroy(bus_dma_tag_t, bus_dmamap_t);
660 void	sg_dmamap_set_alignment(bus_dma_tag_t, bus_dmamap_t, u_long);
661 int	sg_dmamap_load(bus_dma_tag_t, bus_dmamap_t, void *, bus_size_t,
662 	    struct proc *, int);
663 int	sg_dmamap_load_mbuf(bus_dma_tag_t, bus_dmamap_t,
664 	    struct mbuf *, int);
665 int	sg_dmamap_load_uio(bus_dma_tag_t, bus_dmamap_t, struct uio *, int);
666 int	sg_dmamap_load_raw(bus_dma_tag_t, bus_dmamap_t, bus_dma_segment_t *,
667 	    int, bus_size_t, int);
668 void	sg_dmamap_unload(bus_dma_tag_t, bus_dmamap_t);
669 int	sg_dmamap_load_buffer(bus_dma_tag_t, bus_dmamap_t, void *, bus_size_t,
670 	    struct proc *, int, int *, int);
671 int	sg_dmamap_load_physarray(bus_dma_tag_t, bus_dmamap_t, paddr_t *,
672 	    int, int, int *, int);
673 int	sg_dmamem_alloc(bus_dma_tag_t, bus_size_t, bus_size_t, bus_size_t,
674 	    bus_dma_segment_t *, int, int *, int);
675 
676 /*
677  *      paddr_t bus_space_mmap(bus_space_tag_t t, bus_addr_t base,
678  *          off_t offset, int prot, int flags);
679  *
680  * Mmap an area of bus space.
681  */
682 
683 paddr_t bus_space_mmap(bus_space_tag_t, bus_addr_t, off_t, int, int);
684 
685 #endif /* _MACHINE_BUS_H_ */
686