1 /* $NetBSD: bus.h,v 1.17 2007/03/04 06:01:07 christos Exp $ */
4 * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9 * NASA Ames Research Center.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
34 * bus_space(9) and bus_dma(9) interface for NetBSD/x68k.
40 #ifndef X68K_BUS_PERFORMANCE_HACK
41 #if defined(__GNUC__) && defined(__STDC__)
42 #define X68K_BUS_PERFORMANCE_HACK 1
44 #define X68K_BUS_PERFORMANCE_HACK 0
49 * Bus address and size types
51 typedef u_long bus_addr_t
;
52 typedef u_long bus_size_t
;
53 typedef u_long bus_space_handle_t
;
56 * Bus space descripter
58 typedef struct x68k_bus_space
*bus_space_tag_t
;
60 struct x68k_bus_space
{
69 int (*x68k_bus_space_map
)(
74 bus_space_handle_t
*);
75 void (*x68k_bus_space_unmap
)(
79 int (*x68k_bus_space_subregion
)(
82 bus_size_t
, /* offset */
83 bus_size_t
, /* size */
84 bus_space_handle_t
*);
86 int (*x68k_bus_space_alloc
)(
88 bus_addr_t
, /* reg_start */
89 bus_addr_t
, /* reg_end */
91 bus_size_t
, /* alignment */
92 bus_size_t
, /* boundary */
95 bus_space_handle_t
*);
96 void (*x68k_bus_space_free
)(
102 void (*x68k_bus_space_barrier
)(
105 bus_size_t
, /* offset */
106 bus_size_t
, /* length */
110 struct device
*x68k_bus_device
;
113 int x68k_bus_space_alloc(bus_space_tag_t
, bus_addr_t
, bus_addr_t
, bus_size_t
, bus_size_t
, bus_size_t
, int, bus_addr_t
*, bus_space_handle_t
*);
114 void x68k_bus_space_free(bus_space_tag_t
, bus_space_handle_t
, bus_size_t
);
117 * bus_space(9) interface
120 #define bus_space_map(t,a,s,f,h) \
121 ((*((t)->x68k_bus_space_map)) ((t),(a),(s),(f),(h)))
122 #define bus_space_unmap(t,h,s) \
123 ((*((t)->x68k_bus_space_unmap)) ((t),(h),(s)))
124 #define bus_space_subregion(t,h,o,s,p) \
125 ((*((t)->x68k_bus_space_subregion)) ((t),(h),(o),(s),(p)))
126 #define BUS_SPACE_MAP_CACHEABLE 0x0001
127 #define BUS_SPACE_MAP_LINEAR 0x0002
128 #define BUS_SPACE_MAP_PREFETCHABLE 0x0004
130 * For simpler hadware, many x68k devices are mapped with shifted address
131 * i.e. only on even or odd addresses.
133 #define BUS_SPACE_MAP_SHIFTED_MASK 0x1001
134 #define BUS_SPACE_MAP_SHIFTED_ODD 0x1001
135 #define BUS_SPACE_MAP_SHIFTED_EVEN 0x1000
136 #define BUS_SPACE_MAP_SHIFTED BUS_SPACE_MAP_SHIFTED_ODD
138 #define bus_space_alloc(t,rs,re,s,a,b,f,r,h) \
139 ((*((t)->x68k_bus_space_alloc)) ((t),(rs),(re),(s),(a),(b),(f),(r),(h)))
140 #define bus_space_free(t,h,s) \
141 ((*((t)->x68k_bus_space_free)) ((t),(h),(s)))
144 * Note: the 680x0 does not currently require barriers, but we must
145 * provide the flags to MI code.
147 #define bus_space_barrier(t, h, o, l, f) \
148 ((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f)))
149 #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */
150 #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */
152 #define bus_space_read_1(t,h,o) _bus_space_read_1(t,h,o)
153 #define bus_space_read_2(t,h,o) _bus_space_read_2(t,h,o)
154 #define bus_space_read_4(t,h,o) _bus_space_read_4(t,h,o)
156 #define bus_space_read_multi_1(t,h,o,p,c) _bus_space_read_multi_1(t,h,o,p,c)
157 #define bus_space_read_multi_2(t,h,o,p,c) _bus_space_read_multi_2(t,h,o,p,c)
158 #define bus_space_read_multi_4(t,h,o,p,c) _bus_space_read_multi_4(t,h,o,p,c)
160 #define bus_space_read_region_1(t,h,o,p,c) _bus_space_read_region_1(t,h,o,p,c)
161 #define bus_space_read_region_2(t,h,o,p,c) _bus_space_read_region_2(t,h,o,p,c)
162 #define bus_space_read_region_4(t,h,o,p,c) _bus_space_read_region_4(t,h,o,p,c)
164 #define bus_space_write_1(t,h,o,v) _bus_space_write_1(t,h,o,v)
165 #define bus_space_write_2(t,h,o,v) _bus_space_write_2(t,h,o,v)
166 #define bus_space_write_4(t,h,o,v) _bus_space_write_4(t,h,o,v)
168 #define bus_space_write_multi_1(t,h,o,p,c) _bus_space_write_multi_1(t,h,o,p,c)
169 #define bus_space_write_multi_2(t,h,o,p,c) _bus_space_write_multi_2(t,h,o,p,c)
170 #define bus_space_write_multi_4(t,h,o,p,c) _bus_space_write_multi_4(t,h,o,p,c)
172 #define bus_space_write_region_1(t,h,o,p,c) \
173 _bus_space_write_region_1(t,h,o,p,c)
174 #define bus_space_write_region_2(t,h,o,p,c) \
175 _bus_space_write_region_2(t,h,o,p,c)
176 #define bus_space_write_region_4(t,h,o,p,c) \
177 _bus_space_write_region_4(t,h,o,p,c)
179 #define bus_space_set_region_1(t,h,o,v,c) _bus_space_set_region_1(t,h,o,v,c)
180 #define bus_space_set_region_2(t,h,o,v,c) _bus_space_set_region_2(t,h,o,v,c)
181 #define bus_space_set_region_4(t,h,o,v,c) _bus_space_set_region_4(t,h,o,v,c)
183 #define bus_space_copy_region_1(t,sh,so,dh,do,c) \
184 _bus_space_copy_region_1(t,sh,so,dh,do,c)
185 #define bus_space_copy_region_2(t,sh,so,dh,do,c) \
186 _bus_space_copy_region_2(t,sh,so,dh,do,c)
187 #define bus_space_copy_region_4(t,sh,so,dh,do,c) \
188 _bus_space_copy_region_4(t,sh,so,dh,do,c)
190 static __inline u_int8_t _bus_space_read_1
191 (bus_space_tag_t
, bus_space_handle_t bsh
, bus_size_t offset
);
192 static __inline u_int16_t _bus_space_read_2
193 (bus_space_tag_t
, bus_space_handle_t
, bus_size_t
);
194 static __inline u_int32_t _bus_space_read_4
195 (bus_space_tag_t
, bus_space_handle_t
, bus_size_t
);
197 static __inline
void _bus_space_read_multi_1
198 (bus_space_tag_t
, bus_space_handle_t
, bus_size_t
,
199 u_int8_t
*, bus_size_t
);
200 static __inline
void _bus_space_read_multi_2
201 (bus_space_tag_t
, bus_space_handle_t
, bus_size_t
,
202 u_int16_t
*, bus_size_t
);
203 static __inline
void _bus_space_read_multi_4
204 (bus_space_tag_t
, bus_space_handle_t
, bus_size_t
,
205 u_int32_t
*, bus_size_t
);
207 static __inline
void _bus_space_read_region_1
208 (bus_space_tag_t
, bus_space_handle_t
, bus_size_t
,
209 u_int8_t
*, bus_size_t
);
210 static __inline
void _bus_space_read_region_2
211 (bus_space_tag_t
, bus_space_handle_t
, bus_size_t
,
212 u_int16_t
*, bus_size_t
);
213 static __inline
void _bus_space_read_region_4
214 (bus_space_tag_t
, bus_space_handle_t
, bus_size_t
,
215 u_int32_t
*, bus_size_t
);
217 static __inline
void _bus_space_write_1
218 (bus_space_tag_t
, bus_space_handle_t
, bus_size_t
, u_int8_t
);
219 static __inline
void _bus_space_write_2
220 (bus_space_tag_t
, bus_space_handle_t
, bus_size_t
, u_int16_t
);
221 static __inline
void _bus_space_write_4
222 (bus_space_tag_t
, bus_space_handle_t
, bus_size_t
, u_int32_t
);
224 static __inline
void _bus_space_write_multi_1
225 (bus_space_tag_t
, bus_space_handle_t
, bus_size_t
,
226 u_int8_t
*, bus_size_t
);
227 static __inline
void _bus_space_write_multi_2
228 (bus_space_tag_t
, bus_space_handle_t
, bus_size_t
,
229 u_int16_t
*, bus_size_t
);
230 static __inline
void _bus_space_write_multi_4
231 (bus_space_tag_t
, bus_space_handle_t
, bus_size_t
,
232 u_int32_t
*, bus_size_t
);
234 static __inline
void _bus_space_write_region_1
235 (bus_space_tag_t
, bus_space_handle_t
, bus_size_t
,
236 u_int8_t
*, bus_size_t
);
237 static __inline
void _bus_space_write_region_2
238 (bus_space_tag_t
, bus_space_handle_t
, bus_size_t
,
239 u_int16_t
*, bus_size_t
);
240 static __inline
void _bus_space_write_region_4
241 (bus_space_tag_t
, bus_space_handle_t
, bus_size_t
,
242 u_int32_t
*, bus_size_t
);
244 static __inline
void _bus_space_set_region_1
245 (bus_space_tag_t
, bus_space_handle_t
, bus_size_t
,
246 u_int8_t
, bus_size_t
);
247 static __inline
void _bus_space_set_region_2
248 (bus_space_tag_t
, bus_space_handle_t
, bus_size_t
,
249 u_int16_t
, bus_size_t
);
250 static __inline
void _bus_space_set_region_4
251 (bus_space_tag_t
, bus_space_handle_t
, bus_size_t
,
252 u_int32_t
, bus_size_t
);
254 static __inline
void _bus_space_copy_region_1
255 (bus_space_tag_t
, bus_space_handle_t
, bus_size_t
,
256 bus_space_handle_t
, bus_size_t
, bus_size_t
);
257 static __inline
void _bus_space_copy_region_2
258 (bus_space_tag_t
, bus_space_handle_t
, bus_size_t
,
259 bus_space_handle_t
, bus_size_t
, bus_size_t
);
260 static __inline
void _bus_space_copy_region_4
261 (bus_space_tag_t
, bus_space_handle_t
, bus_size_t
,
262 bus_space_handle_t
, bus_size_t
, bus_size_t
);
265 #define __X68K_BUS_ADDR(tag, handle, offset) \
266 (((long)(handle) < 0 ? (offset) * 2 : (offset)) \
267 + ((handle) & 0x7fffffff))
269 static __inline u_int8_t
270 _bus_space_read_1(t
, bsh
, offset
)
272 bus_space_handle_t bsh
;
275 return (*((volatile u_int8_t
*) __X68K_BUS_ADDR(t
, bsh
, offset
)));
278 static __inline u_int16_t
279 _bus_space_read_2(t
, bsh
, offset
)
281 bus_space_handle_t bsh
;
284 return (*((volatile u_int16_t
*) __X68K_BUS_ADDR(t
, bsh
, offset
)));
287 static __inline u_int32_t
288 _bus_space_read_4(t
, bsh
, offset
)
290 bus_space_handle_t bsh
;
293 return (*((volatile u_int32_t
*) __X68K_BUS_ADDR(t
, bsh
, offset
)));
297 _bus_space_read_multi_1(t
, bsh
, offset
, datap
, count
)
299 bus_space_handle_t bsh
;
304 #if X68K_BUS_PERFORMANCE_HACK
305 u_int8_t
*regadr
= (u_int8_t
*) __X68K_BUS_ADDR(t
, bsh
, offset
);
306 for (; count
; count
--) {
307 __asm("| avoid optim. _bus_space_read_multi_1" : : : "memory");
311 while (count
-- > 0) {
312 *datap
++ = *(volatile u_int8_t
*)
313 __X68K_BUS_ADDR(t
, bsh
, offset
);
319 _bus_space_read_multi_2(t
, bsh
, offset
, datap
, count
)
321 bus_space_handle_t bsh
;
326 #if X68K_BUS_PERFORMANCE_HACK
327 u_int16_t
*regadr
= (u_int16_t
*) __X68K_BUS_ADDR(t
, bsh
, offset
);
328 for (; count
; count
--) {
329 __asm("| avoid optim. _bus_space_read_multi_2" : : : "memory");
333 while (count
-- > 0) {
334 *datap
++ = *(volatile u_int16_t
*)
335 __X68K_BUS_ADDR(t
, bsh
, offset
);
341 _bus_space_read_multi_4(t
, bsh
, offset
, datap
, count
)
343 bus_space_handle_t bsh
;
348 #if X68K_BUS_PERFORMANCE_HACK
349 u_int32_t
*regadr
= (u_int32_t
*) __X68K_BUS_ADDR(t
, bsh
, offset
);
350 for (; count
; count
--) {
351 __asm("| avoid optim. _bus_space_read_multi_4" : : : "memory");
355 while (count
-- > 0) {
356 *datap
++ = *(volatile u_int32_t
*)
357 __X68K_BUS_ADDR(t
, bsh
, offset
);
363 _bus_space_read_region_1(t
, bsh
, offset
, datap
, count
)
365 bus_space_handle_t bsh
;
370 #if X68K_BUS_PERFORMANCE_HACK
371 u_int8_t
*addr
= (void *) __X68K_BUS_ADDR(t
, bsh
, offset
);
373 for (; count
; count
--) {
374 __asm("| avoid optim. _bus_space_read_region_1" : : : "memory");
378 volatile u_int8_t
*addr
= (void *) __X68K_BUS_ADDR(t
, bsh
, offset
);
380 while (count
-- > 0) {
387 _bus_space_read_region_2(t
, bsh
, offset
, datap
, count
)
389 bus_space_handle_t bsh
;
394 #if X68K_BUS_PERFORMANCE_HACK
395 u_int16_t
*addr
= (void *) __X68K_BUS_ADDR(t
, bsh
, offset
);
397 for (; count
; count
--) {
398 __asm("| avoid optim. _bus_space_read_region_2" : : : "memory");
402 volatile u_int16_t
*addr
= (void *) __X68K_BUS_ADDR(t
, bsh
, offset
);
404 while (count
-- > 0) {
411 _bus_space_read_region_4(t
, bsh
, offset
, datap
, count
)
413 bus_space_handle_t bsh
;
418 #if X68K_BUS_PERFORMANCE_HACK
419 u_int32_t
*addr
= (void *) __X68K_BUS_ADDR(t
, bsh
, offset
);
421 for (; count
; count
--) {
422 __asm("| avoid optim. _bus_space_read_region_4" : : : "memory");
426 volatile u_int32_t
*addr
= (void *) __X68K_BUS_ADDR(t
, bsh
, offset
);
428 while (count
-- > 0) {
435 _bus_space_write_1(t
, bsh
, offset
, value
)
437 bus_space_handle_t bsh
;
441 *(volatile u_int8_t
*) __X68K_BUS_ADDR(t
, bsh
, offset
) = value
;
445 _bus_space_write_2(t
, bsh
, offset
, value
)
447 bus_space_handle_t bsh
;
451 *(volatile u_int16_t
*) __X68K_BUS_ADDR(t
, bsh
, offset
) = value
;
455 _bus_space_write_4(t
, bsh
, offset
, value
)
457 bus_space_handle_t bsh
;
461 *(volatile u_int32_t
*) __X68K_BUS_ADDR(t
, bsh
, offset
) = value
;
465 _bus_space_write_multi_1(t
, bsh
, offset
, datap
, count
)
467 bus_space_handle_t bsh
;
472 #if X68K_BUS_PERFORMANCE_HACK
473 u_int8_t
*regadr
= (u_int8_t
*) __X68K_BUS_ADDR(t
, bsh
, offset
);
474 for (; count
; count
--) {
475 __asm("| avoid optim. _bus_space_write_multi_1" : : : "memory");
479 while (count
-- > 0) {
480 *(volatile u_int8_t
*) __X68K_BUS_ADDR(t
, bsh
, offset
)
487 _bus_space_write_multi_2(t
, bsh
, offset
, datap
, count
)
489 bus_space_handle_t bsh
;
494 #if X68K_BUS_PERFORMANCE_HACK
495 u_int16_t
*regadr
= (u_int16_t
*) __X68K_BUS_ADDR(t
, bsh
, offset
);
496 for (; count
; count
--) {
497 __asm("| avoid optim. _bus_space_write_multi_2" : : : "memory");
501 while (count
-- > 0) {
502 *(volatile u_int16_t
*) __X68K_BUS_ADDR(t
, bsh
, offset
)
509 _bus_space_write_multi_4(t
, bsh
, offset
, datap
, count
)
511 bus_space_handle_t bsh
;
516 #if X68K_BUS_PERFORMANCE_HACK
517 u_int32_t
*regadr
= (u_int32_t
*) __X68K_BUS_ADDR(t
, bsh
, offset
);
518 for (; count
; count
--) {
519 __asm("| avoid optim. _bus_space_write_multi_4" : : : "memory");
523 while (count
-- > 0) {
524 *(volatile u_int32_t
*) __X68K_BUS_ADDR(t
, bsh
, offset
)
531 _bus_space_write_region_1(t
, bsh
, offset
, datap
, count
)
533 bus_space_handle_t bsh
;
538 #if X68K_BUS_PERFORMANCE_HACK
539 u_int8_t
*addr
= (void *) __X68K_BUS_ADDR(t
, bsh
, offset
);
541 for (; count
; count
--) {
542 __asm("| avoid optim. _bus_space_write_region_1": : : "memory");
546 volatile u_int8_t
*addr
= (void *) __X68K_BUS_ADDR(t
, bsh
, offset
);
548 while (count
-- > 0) {
555 _bus_space_write_region_2(t
, bsh
, offset
, datap
, count
)
557 bus_space_handle_t bsh
;
562 #if X68K_BUS_PERFORMANCE_HACK
563 u_int16_t
*addr
= (void *) __X68K_BUS_ADDR(t
, bsh
, offset
);
565 for (; count
; count
--) {
566 __asm("| avoid optim. _bus_space_write_region_2": : : "memory");
570 volatile u_int16_t
*addr
= (void *) __X68K_BUS_ADDR(t
, bsh
, offset
);
572 while (count
-- > 0) {
579 _bus_space_write_region_4(t
, bsh
, offset
, datap
, count
)
581 bus_space_handle_t bsh
;
586 #if X68K_BUS_PERFORMANCE_HACK
587 u_int32_t
*addr
= (void *) __X68K_BUS_ADDR(t
, bsh
, offset
);
589 for (; count
; count
--) {
590 __asm("| avoid optim. _bus_space_write_region_4": : : "memory");
594 volatile u_int32_t
*addr
= (void *) __X68K_BUS_ADDR(t
, bsh
, offset
);
596 while (count
-- > 0) {
603 _bus_space_set_region_1(t
, bsh
, offset
, value
, count
)
605 bus_space_handle_t bsh
;
610 #if X68K_BUS_PERFORMANCE_HACK
611 u_int8_t
*addr
= (void *) __X68K_BUS_ADDR(t
, bsh
, offset
);
613 for (; count
; count
--) {
614 __asm("| avoid optim. _bus_space_set_region_1" : : : "memory");
618 volatile u_int8_t
*addr
= (void *) __X68K_BUS_ADDR(t
, bsh
, offset
);
620 while (count
-- > 0) {
627 _bus_space_set_region_2(t
, bsh
, offset
, value
, count
)
629 bus_space_handle_t bsh
;
634 #if X68K_BUS_PERFORMANCE_HACK
635 u_int16_t
*addr
= (void *) __X68K_BUS_ADDR(t
, bsh
, offset
);
637 for (; count
; count
--) {
638 __asm("| avoid optim. _bus_space_set_region_2" : : : "memory");
642 volatile u_int16_t
*addr
= (void *) __X68K_BUS_ADDR(t
, bsh
, offset
);
644 while (count
-- > 0) {
651 _bus_space_set_region_4(t
, bsh
, offset
, value
, count
)
653 bus_space_handle_t bsh
;
658 #if X68K_BUS_PERFORMANCE_HACK
659 u_int32_t
*addr
= (void *) __X68K_BUS_ADDR(t
, bsh
, offset
);
661 for (; count
; count
--) {
662 __asm("| avoid optim. _bus_space_set_region_4" : : : "memory");
666 volatile u_int32_t
*addr
= (void *) __X68K_BUS_ADDR(t
, bsh
, offset
);
668 while (count
-- > 0) {
675 _bus_space_copy_region_1(t
, sbsh
, soffset
, dbsh
, doffset
, count
)
677 bus_space_handle_t sbsh
;
679 bus_space_handle_t dbsh
;
683 volatile u_int8_t
*saddr
= (void *) (sbsh
+ soffset
);
684 volatile u_int8_t
*daddr
= (void *) (dbsh
+ doffset
);
686 if ((u_int32_t
) saddr
>= (u_int32_t
) daddr
)
698 _bus_space_copy_region_2(t
, sbsh
, soffset
, dbsh
, doffset
, count
)
700 bus_space_handle_t sbsh
;
702 bus_space_handle_t dbsh
;
706 volatile u_int16_t
*saddr
= (void *) (sbsh
+ soffset
);
707 volatile u_int16_t
*daddr
= (void *) (dbsh
+ doffset
);
709 if ((u_int32_t
) saddr
>= (u_int32_t
) daddr
)
721 _bus_space_copy_region_4(t
, sbsh
, soffset
, dbsh
, doffset
, count
)
723 bus_space_handle_t sbsh
;
725 bus_space_handle_t dbsh
;
729 volatile u_int32_t
*saddr
= (void *) (sbsh
+ soffset
);
730 volatile u_int32_t
*daddr
= (void *) (dbsh
+ doffset
);
732 if ((u_int32_t
) saddr
>= (u_int32_t
) daddr
)
743 #define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t)
748 struct x68k_bus_dma_segment
{
752 typedef struct x68k_bus_dma_segment bus_dma_segment_t
;
757 /* Forwards needed by prototypes below. */
761 typedef struct x68k_bus_dma
*bus_dma_tag_t
;
762 typedef struct x68k_bus_dmamap
*bus_dmamap_t
;
764 #define BUS_DMA_TAG_VALID(t) ((t) != (bus_dma_tag_t)0)
766 struct x68k_bus_dma
{
768 * The `bounce threshold' is checked while we are loading
769 * the DMA map. If the physical address of the segment
770 * exceeds the threshold, an error will be returned. The
771 * caller can then take whatever action is necessary to
772 * bounce the transfer. If this value is 0, it will be
775 bus_addr_t _bounce_thresh
;
778 * DMA mapping methods.
780 int (*x68k_dmamap_create
)(bus_dma_tag_t
, bus_size_t
, int,
781 bus_size_t
, bus_size_t
, int, bus_dmamap_t
*);
782 void (*x68k_dmamap_destroy
)(bus_dma_tag_t
, bus_dmamap_t
);
783 int (*x68k_dmamap_load
)(bus_dma_tag_t
, bus_dmamap_t
, void *,
784 bus_size_t
, struct proc
*, int);
785 int (*x68k_dmamap_load_mbuf
)(bus_dma_tag_t
, bus_dmamap_t
,
787 int (*x68k_dmamap_load_uio
)(bus_dma_tag_t
, bus_dmamap_t
,
789 int (*x68k_dmamap_load_raw
)(bus_dma_tag_t
, bus_dmamap_t
,
790 bus_dma_segment_t
*, int, bus_size_t
, int);
791 void (*x68k_dmamap_unload
)(bus_dma_tag_t
, bus_dmamap_t
);
792 void (*x68k_dmamap_sync
)(bus_dma_tag_t
, bus_dmamap_t
,
793 bus_addr_t
, bus_size_t
, int);
796 * DMA memory utility functions.
798 int (*x68k_dmamem_alloc
)(bus_dma_tag_t
, bus_size_t
, bus_size_t
,
799 bus_size_t
, bus_dma_segment_t
*, int, int *, int);
800 void (*x68k_dmamem_free
)(bus_dma_tag_t
,
801 bus_dma_segment_t
*, int);
802 int (*x68k_dmamem_map
)(bus_dma_tag_t
, bus_dma_segment_t
*,
803 int, size_t, void **, int);
804 void (*x68k_dmamem_unmap
)(bus_dma_tag_t
, void *, size_t);
805 paddr_t (*x68k_dmamem_mmap
)(bus_dma_tag_t
, bus_dma_segment_t
*,
806 int, off_t
, int, int);
812 * Describes a DMA mapping.
814 struct x68k_bus_dmamap
{
816 * PRIVATE MEMBERS: not for use my machine-independent code.
818 bus_size_t x68k_dm_size
; /* largest DMA transfer mappable */
819 int x68k_dm_segcnt
; /* number of segs this map can map */
820 bus_size_t x68k_dm_maxmaxsegsz
; /* fixed largest possible segment*/
821 bus_size_t x68k_dm_boundary
; /* don't cross this */
822 bus_addr_t x68k_dm_bounce_thresh
; /* bounce threshold */
823 int x68k_dm_flags
; /* misc. flags */
825 void *x68k_dm_cookie
; /* cookie for bus-specific functions */
828 * PUBLIC MEMBERS: these are used by machine-independent code.
830 bus_size_t dm_maxsegsz
; /* largest possible segment */
831 bus_size_t dm_mapsize
; /* size of the mapping */
832 int dm_nsegs
; /* # valid segments in mapping */
833 bus_dma_segment_t dm_segs
[1]; /* segments; variable length */
836 int x68k_bus_dmamap_create(bus_dma_tag_t
, bus_size_t
, int, bus_size_t
,
837 bus_size_t
, int, bus_dmamap_t
*);
838 void x68k_bus_dmamap_destroy(bus_dma_tag_t
, bus_dmamap_t
);
839 int x68k_bus_dmamap_load(bus_dma_tag_t
, bus_dmamap_t
, void *,
840 bus_size_t
, struct proc
*, int);
841 int x68k_bus_dmamap_load_mbuf(bus_dma_tag_t
, bus_dmamap_t
,
843 int x68k_bus_dmamap_load_uio(bus_dma_tag_t
, bus_dmamap_t
,
845 int x68k_bus_dmamap_load_raw(bus_dma_tag_t
, bus_dmamap_t
,
846 bus_dma_segment_t
*, int, bus_size_t
, int);
847 void x68k_bus_dmamap_unload(bus_dma_tag_t
, bus_dmamap_t
);
848 void x68k_bus_dmamap_sync(bus_dma_tag_t
, bus_dmamap_t
, bus_addr_t
,
851 int x68k_bus_dmamem_alloc(bus_dma_tag_t tag
, bus_size_t size
,
852 bus_size_t alignment
, bus_size_t boundary
,
853 bus_dma_segment_t
*segs
, int nsegs
, int *rsegs
, int flags
);
854 void x68k_bus_dmamem_free(bus_dma_tag_t tag
, bus_dma_segment_t
*segs
,
856 int x68k_bus_dmamem_map(bus_dma_tag_t tag
, bus_dma_segment_t
*segs
,
857 int nsegs
, size_t size
, void **kvap
, int flags
);
858 void x68k_bus_dmamem_unmap(bus_dma_tag_t tag
, void *kva
,
860 paddr_t
x68k_bus_dmamem_mmap(bus_dma_tag_t tag
, bus_dma_segment_t
*segs
,
861 int nsegs
, off_t off
, int prot
, int flags
);
863 int x68k_bus_dmamap_load_buffer(bus_dmamap_t
, void *,
864 bus_size_t buflen
, struct proc
*, int, paddr_t
*, int *, int);
865 int x68k_bus_dmamem_alloc_range(bus_dma_tag_t tag
, bus_size_t size
,
866 bus_size_t alignment
, bus_size_t boundary
,
867 bus_dma_segment_t
*segs
, int nsegs
, int *rsegs
, int flags
,
868 paddr_t low
, paddr_t high
);
870 #define bus_dmamap_create(t,s,n,m,b,f,p) \
871 ((*((t)->x68k_dmamap_create)) ((t),(s),(n),(m),(b),(f),(p)))
872 #define bus_dmamap_destroy(t,p) \
873 ((*((t)->x68k_dmamap_destroy)) ((t),(p)))
874 #define bus_dmamap_load(t,m,b,s,p,f) \
875 ((*((t)->x68k_dmamap_load)) ((t),(m),(b),(s),(p),(f)))
876 #define bus_dmamap_load_mbuf(t,m,b,f) \
877 ((*((t)->x68k_dmamap_load_mbuf)) ((t),(m),(b),(f)))
878 #define bus_dmamap_load_uio(t,m,u,f) \
879 ((*((t)->x68k_dmamap_load_uio)) ((t),(m),(u),(f)))
880 #define bus_dmamap_load_raw(t,m,sg,n,s,f) \
881 ((*((t)->x68k_dmamap_load_raw)) ((t),(m),(sg),(n),(s),(f)))
882 #define bus_dmamap_unload(t,p) \
883 ((*((t)->x68k_dmamap_unload)) ((t),(p)))
884 #define bus_dmamap_sync(t,p,o,l,ops) \
885 ((*((t)->x68k_dmamap_sync)) ((t),(p),(o),(l),(ops)))
887 #define bus_dmamem_alloc(t,s,a,b,sg,n,r,f) \
888 ((*((t)->x68k_dmamem_alloc)) ((t),(s),(a),(b),(sg),(n),(r),(f)))
889 #define bus_dmamem_free(t,sg,n) \
890 ((*((t)->x68k_dmamem_free)) ((t),(sg),(n)))
891 #define bus_dmamem_map(t,sg,n,s,k,f) \
892 ((*((t)->x68k_dmamem_map)) ((t),(sg),(n),(s),(k),(f)))
893 #define bus_dmamem_unmap(t,k,s) \
894 ((*((t)->x68k_dmamem_unmap)) ((t),(k),(s)))
895 #define bus_dmamem_mmap(t,sg,n,o,p,f) \
896 ((*((t)->x68k_dmamem_mmap)) ((t),(sg),(n),(o),(p),(f)))
898 #define bus_dmatag_subregion(t, mna, mxa, nt, f) EOPNOTSUPP
899 #define bus_dmatag_destroy(t)
902 * Flags used in various bus DMA methods.
904 #define BUS_DMA_WAITOK 0x000 /* safe to sleep (pseudo-flag) */
905 #define BUS_DMA_NOWAIT 0x001 /* not safe to sleep */
906 #define BUS_DMA_ALLOCNOW 0x002 /* perform resource allocation now */
907 #define BUS_DMA_COHERENT 0x004 /* hint: map memory DMA coherent */
908 #define BUS_DMA_STREAMING 0x008 /* hint: sequential, unidirectional */
909 #define BUS_DMA_BUS1 0x010 /* placeholders for bus functions... */
910 #define BUS_DMA_BUS2 0x020
911 #define BUS_DMA_BUS3 0x040
912 #define BUS_DMA_BUS4 0x080
913 #define BUS_DMA_READ 0x100 /* mapping is device -> memory only */
914 #define BUS_DMA_WRITE 0x200 /* mapping is memory -> device only */
915 #define BUS_DMA_NOCACHE 0x400 /* hint: map non-cached memory */
918 * Operations performed by bus_dmamap_sync().
920 #define BUS_DMASYNC_PREREAD 0x01 /* pre-read synchronization */
921 #define BUS_DMASYNC_POSTREAD 0x02 /* post-read synchronization */
922 #define BUS_DMASYNC_PREWRITE 0x04 /* pre-write synchronization */
923 #define BUS_DMASYNC_POSTWRITE 0x08 /* post-write synchronization */
925 #endif /* _X68K_BUS_H_ */