bus.h revision 1.3 1 /* $NetBSD: bus.h,v 1.3 1999/03/23 21:29:06 drochner Exp $ */
2
3 /*-
4 * Copyright (c) 1998 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9 * NASA Ames Research Center.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
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.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the NetBSD
22 * Foundation, Inc. and its contributors.
23 * 4. Neither the name of The NetBSD Foundation nor the names of its
24 * contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
38 */
39
40 /*
41 * bus_space(9) and bus_dma(9) interface for NetBSD/x68k.
42 */
43
44 #ifndef _X68K_BUS_H_
45 #define _X68K_BUS_H_
46
47 /*
48 * Bus address and size types
49 */
50 typedef u_long bus_addr_t;
51 typedef u_long bus_size_t;
52 typedef u_long bus_space_handle_t;
53
54 /*
55 * Bus space descripter
56 */
57 typedef struct x68k_bus_space *bus_space_tag_t;
58
59 struct x68k_bus_space {
60 #if 0
61 enum {
62 X68K_INTIO_BUS,
63 X68K_PCI_BUS,
64 X68K_NEPTUNE_BUS
65 } x68k_bus_type;
66 #endif
67
68 int (*x68k_bus_space_map) __P((
69 bus_space_tag_t,
70 bus_addr_t,
71 bus_size_t,
72 int, /* flags */
73 bus_space_handle_t *));
74 void (*x68k_bus_space_unmap) __P((
75 bus_space_tag_t,
76 bus_space_handle_t,
77 bus_size_t));
78 int (*x68k_bus_space_subregion) __P((
79 bus_space_tag_t,
80 bus_space_handle_t,
81 bus_size_t, /* offset */
82 bus_size_t, /* size */
83 bus_space_handle_t *));
84
85 int (*x68k_bus_space_alloc) __P((
86 bus_space_tag_t,
87 bus_addr_t, /* reg_start */
88 bus_addr_t, /* reg_end */
89 bus_size_t,
90 bus_size_t, /* alignment */
91 bus_size_t, /* boundary */
92 int, /* flags */
93 bus_addr_t *,
94 bus_space_handle_t *));
95 void (*x68k_bus_space_free) __P((
96 bus_space_tag_t,
97 bus_space_handle_t,
98 bus_size_t));
99
100 #if 0
101 void (*x68k_bus_space_barrier) __P((
102 bus_space_tag_t,
103 bus_space_handle_t,
104 bus_size_t, /* offset */
105 bus_size_t, /* length */
106 int)); /* flags */
107 #endif
108
109 struct device *x68k_bus_device;
110 };
111
112 int x68k_bus_space_alloc __P((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 *));
113 void x68k_bus_space_free __P((bus_space_tag_t, bus_space_handle_t, bus_size_t));
114
115 /*
116 * bus_space(9) interface
117 */
118
119 #define bus_space_map(t,a,s,f,h) \
120 ((*((t)->x68k_bus_space_map)) ((t),(a),(s),(f),(h)))
121 #define bus_space_unmap(t,h,s) \
122 ((*((t)->x68k_bus_space_unmap)) ((t),(h),(s)))
123 #define bus_space_subregion(t,h,o,s,p) \
124 ((*((t)->x68k_bus_space_subregion)) ((t),(h),(o),(s),(p)))
125 #define BUS_SPACE_MAP_CACHEABLE 0x0001
126 #define BUS_SPACE_MAP_LINEAR 0x0002
127 /*
128 * For simpler hadware, many x68k devices are mapped with shifted address
129 * i.e. only on even or odd addresses.
130 */
131 #define BUS_SPACE_MAP_SHIFTED 0x1001
132
133 #define bus_space_alloc(t,rs,re,s,a,b,f,r,h) \
134 ((*((t)->x68k_bus_space_alloc)) ((t),(rs),(re),(s),(a),(b),(f),(r),(h)))
135 #define bus_space_free(t,h,s) \
136 ((*((t)->x68k_bus_space_free)) ((t),(h),(s)))
137
138 /*
139 * Note: the 680x0 does not currently require barriers, but we must
140 * provide the flags to MI code.
141 */
142 #define bus_space_barrier(t, h, o, l, f) \
143 ((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f)))
144 #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */
145 #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */
146
147 #define bus_space_read_1(t,h,o) _bus_space_read_1(t,h,o)
148 #define bus_space_read_2(t,h,o) _bus_space_read_2(t,h,o)
149 #define bus_space_read_4(t,h,o) _bus_space_read_4(t,h,o)
150
151 #define bus_space_read_multi_1(t,h,o,p,c) _bus_space_read_multi_1(t,h,o,p,c)
152 #define bus_space_read_multi_2(t,h,o,p,c) _bus_space_read_multi_2(t,h,o,p,c)
153 #define bus_space_read_multi_4(t,h,o,p,c) _bus_space_read_multi_4(t,h,o,p,c)
154
155 #define bus_space_read_region_1(t,h,o,p,c) _bus_space_read_region_1(t,h,o,p,c)
156 #define bus_space_read_region_2(t,h,o,p,c) _bus_space_read_region_2(t,h,o,p,c)
157 #define bus_space_read_region_4(t,h,o,p,c) _bus_space_read_region_4(t,h,o,p,c)
158
159 #define bus_space_write_1(t,h,o,v) _bus_space_write_1(t,h,o,v)
160 #define bus_space_write_2(t,h,o,v) _bus_space_write_2(t,h,o,v)
161 #define bus_space_write_4(t,h,o,v) _bus_space_write_4(t,h,o,v)
162
163 #define bus_space_write_multi_1(t,h,o,p,c) _bus_space_write_multi_1(t,h,o,p,c)
164 #define bus_space_write_multi_2(t,h,o,p,c) _bus_space_write_multi_2(t,h,o,p,c)
165 #define bus_space_write_multi_4(t,h,o,p,c) _bus_space_write_multi_4(t,h,o,p,c)
166
167 #define bus_space_write_region_1(t,h,o,p,c) \
168 _bus_space_write_region_1(t,h,o,p,c)
169 #define bus_space_write_region_2(t,h,o,p,c) \
170 _bus_space_write_region_2(t,h,o,p,c)
171 #define bus_space_write_region_4(t,h,o,p,c) \
172 _bus_space_write_region_4(t,h,o,p,c)
173
174 #define bus_space_set_region_1(t,h,o,v,c) _bus_space_set_region_1(t,h,o,v,c)
175 #define bus_space_set_region_2(t,h,o,v,c) _bus_space_set_region_2(t,h,o,v,c)
176 #define bus_space_set_region_4(t,h,o,v,c) _bus_space_set_region_4(t,h,o,v,c)
177
178 #define bus_space_copy_region_1(t,sh,so,dh,do,c) \
179 _bus_space_copy_region_1(t,sh,so,dh,do,c)
180 #define bus_space_copy_region_2(t,sh,so,dh,do,c) \
181 _bus_space_copy_region_2(t,sh,so,dh,do,c)
182 #define bus_space_copy_region_4(t,sh,so,dh,do,c) \
183 _bus_space_copy_region_4(t,sh,so,dh,do,c)
184
185 static inline u_int8_t _bus_space_read_1
186 __P((bus_space_tag_t, bus_space_handle_t bsh, bus_size_t offset));
187 static inline u_int16_t _bus_space_read_2
188 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t));
189 static inline u_int32_t _bus_space_read_4
190 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t));
191
192 static inline void _bus_space_read_multi_1
193 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
194 u_int8_t *, bus_size_t));
195 static inline void _bus_space_read_multi_2
196 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
197 u_int16_t *, bus_size_t));
198 static inline void _bus_space_read_multi_4
199 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
200 u_int32_t *, bus_size_t));
201
202 static inline void _bus_space_read_region_1
203 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
204 u_int8_t *, bus_size_t));
205 static inline void _bus_space_read_region_2
206 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
207 u_int16_t *, bus_size_t));
208 static inline void _bus_space_read_region_4
209 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
210 u_int32_t *, bus_size_t));
211
212 static inline void _bus_space_write_1
213 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int8_t));
214 static inline void _bus_space_write_2
215 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t));
216 static inline void _bus_space_write_4
217 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t));
218
219 static inline void _bus_space_write_multi_1
220 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
221 u_int8_t *, bus_size_t));
222 static inline void _bus_space_write_multi_2
223 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
224 u_int16_t *, bus_size_t));
225 static inline void _bus_space_write_multi_4
226 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
227 u_int32_t *, bus_size_t));
228
229 static inline void _bus_space_write_region_1
230 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
231 u_int8_t *, bus_size_t));
232 static inline void _bus_space_write_region_2
233 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
234 u_int16_t *, bus_size_t));
235 static inline void _bus_space_write_region_4
236 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
237 u_int32_t *, bus_size_t));
238
239 static inline void _bus_space_set_region_1
240 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
241 u_int8_t, bus_size_t));
242 static inline void _bus_space_set_region_2
243 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
244 u_int16_t, bus_size_t));
245 static inline void _bus_space_set_region_4
246 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
247 u_int32_t, bus_size_t));
248
249 static inline void _bus_space_copy_region_1
250 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
251 bus_space_handle_t, bus_size_t, bus_size_t));
252 static inline void _bus_space_copy_region_2
253 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
254 bus_space_handle_t, bus_size_t, bus_size_t));
255 static inline void _bus_space_copy_region_4
256 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
257 bus_space_handle_t, bus_size_t, bus_size_t));
258
259
260 static inline u_int8_t
261 _bus_space_read_1(t, bsh, offset)
262 bus_space_tag_t t;
263 bus_space_handle_t bsh;
264 bus_size_t offset;
265 {
266 return (*((volatile u_int8_t *) ((bsh&0x80000000)
267 ? (bsh&0x7fffffff) + offset*2
268 : bsh + offset)));
269 }
270
271 static inline u_int16_t
272 _bus_space_read_2(t, bsh, offset)
273 bus_space_tag_t t;
274 bus_space_handle_t bsh;
275 bus_size_t offset;
276 {
277 return (*((volatile u_int16_t *) ((bsh&0x80000000)
278 ? (bsh&0x7fffffff) + offset*2
279 : bsh + offset)));
280 }
281
282 static inline u_int32_t
283 _bus_space_read_4(t, bsh, offset)
284 bus_space_tag_t t;
285 bus_space_handle_t bsh;
286 bus_size_t offset;
287 {
288 return (*((volatile u_int32_t *) ((bsh&0x80000000)
289 ? (bsh&0x7fffffff) + offset*2
290 : bsh + offset)));
291 }
292
293 static inline void
294 _bus_space_read_multi_1(t, bsh, offset, datap, count)
295 bus_space_tag_t t;
296 bus_space_handle_t bsh;
297 bus_size_t offset;
298 u_int8_t *datap;
299 bus_size_t count;
300 {
301 while (count-- > 0) {
302 *datap++ = *(volatile u_int8_t *) ((bsh&0x80000000)
303 ? ((bsh&0x7fffffff)
304 + offset*2)
305 : bsh + offset);
306 }
307 }
308
309 static inline void
310 _bus_space_read_multi_2(t, bsh, offset, datap, count)
311 bus_space_tag_t t;
312 bus_space_handle_t bsh;
313 bus_size_t offset;
314 u_int16_t *datap;
315 bus_size_t count;
316 {
317 while (count-- > 0) {
318 *datap++ = *(volatile u_int16_t *) ((bsh&0x80000000)
319 ? ((bsh&0x7fffffff)
320 + offset*2)
321 : bsh + offset);
322 }
323 }
324
325 static inline void
326 _bus_space_read_multi_4(t, bsh, offset, datap, count)
327 bus_space_tag_t t;
328 bus_space_handle_t bsh;
329 bus_size_t offset;
330 u_int32_t *datap;
331 bus_size_t count;
332 {
333 while (count-- > 0) {
334 *datap++ = *(volatile u_int32_t *) ((bsh&0x80000000)
335 ? ((bsh&0x7fffffff)
336 + offset*2)
337 : bsh + offset);
338 }
339 }
340
341 static inline void
342 _bus_space_read_region_1(t, bsh, offset, datap, count)
343 bus_space_tag_t t;
344 bus_space_handle_t bsh;
345 bus_size_t offset;
346 u_int8_t *datap;
347 bus_size_t count;
348 {
349 volatile u_int8_t *addr = (void *) ((bsh&0x80000000)
350 ? (bsh&0x7fffffff) + offset*2
351 : bsh + offset);
352
353 while (count-- > 0) {
354 *datap++ = *addr++;
355 }
356 }
357
358 static inline void
359 _bus_space_read_region_2(t, bsh, offset, datap, count)
360 bus_space_tag_t t;
361 bus_space_handle_t bsh;
362 bus_size_t offset;
363 u_int16_t *datap;
364 bus_size_t count;
365 {
366 volatile u_int16_t *addr = (void *) ((bsh&0x80000000)
367 ? (bsh&0x7fffffff) + offset*2
368 : bsh + offset);
369
370 while (count-- > 0) {
371 *datap++ = *addr++;
372 }
373 }
374
375 static inline void
376 _bus_space_read_region_4(t, bsh, offset, datap, count)
377 bus_space_tag_t t;
378 bus_space_handle_t bsh;
379 bus_size_t offset;
380 u_int32_t *datap;
381 bus_size_t count;
382 {
383 volatile u_int32_t *addr = (void *) ((bsh&0x80000000)
384 ? (bsh&0x7fffffff) + offset*2
385 : bsh + offset);
386
387 while (count-- > 0) {
388 *datap++ = *addr++;
389 }
390 }
391
392 static inline void
393 _bus_space_write_1(t, bsh, offset, value)
394 bus_space_tag_t t;
395 bus_space_handle_t bsh;
396 bus_size_t offset;
397 u_int8_t value;
398 {
399 *(volatile u_int8_t *) ((bsh&0x80000000)
400 ? (bsh&0x7fffffff) + offset*2
401 : bsh + offset) = value;
402 }
403
404 static inline void
405 _bus_space_write_2(t, bsh, offset, value)
406 bus_space_tag_t t;
407 bus_space_handle_t bsh;
408 bus_size_t offset;
409 u_int16_t value;
410 {
411 *(volatile u_int16_t *) ((bsh&0x80000000)
412 ? (bsh&0x7fffffff) + offset*2
413 : bsh + offset) = value;
414 }
415
416 static inline void
417 _bus_space_write_4(t, bsh, offset, value)
418 bus_space_tag_t t;
419 bus_space_handle_t bsh;
420 bus_size_t offset;
421 u_int32_t value;
422 {
423 *(volatile u_int32_t *) ((bsh&0x80000000)
424 ? (bsh&0x7fffffff) + offset*2
425 : bsh + offset) = value;
426 }
427
428 static inline void
429 _bus_space_write_multi_1(t, bsh, offset, datap, count)
430 bus_space_tag_t t;
431 bus_space_handle_t bsh;
432 bus_size_t offset;
433 u_int8_t *datap;
434 bus_size_t count;
435 {
436 while (count-- > 0) {
437 *(volatile u_int8_t *) ((bsh&0x80000000)
438 ? (bsh&0x7fffffff) + offset*2
439 : bsh + offset) = *datap++;
440 }
441 }
442
443 static inline void
444 _bus_space_write_multi_2(t, bsh, offset, datap, count)
445 bus_space_tag_t t;
446 bus_space_handle_t bsh;
447 bus_size_t offset;
448 u_int16_t *datap;
449 bus_size_t count;
450 {
451 while (count-- > 0) {
452 *(volatile u_int16_t *) ((bsh&0x80000000)
453 ? (bsh&0x7fffffff) + offset*2
454 : bsh + offset) = *datap++;
455 }
456 }
457
458 static inline void
459 _bus_space_write_multi_4(t, bsh, offset, datap, count)
460 bus_space_tag_t t;
461 bus_space_handle_t bsh;
462 bus_size_t offset;
463 u_int32_t *datap;
464 bus_size_t count;
465 {
466 while (count-- > 0) {
467 *(volatile u_int32_t *) ((bsh&0x80000000)
468 ? (bsh&0x7fffffff) + offset*2
469 : bsh + offset) = *datap++;
470 }
471 }
472
473 static inline void
474 _bus_space_write_region_1(t, bsh, offset, datap, count)
475 bus_space_tag_t t;
476 bus_space_handle_t bsh;
477 bus_size_t offset;
478 u_int8_t *datap;
479 bus_size_t count;
480 {
481 volatile u_int8_t *addr = (void *) ((bsh&0x80000000)
482 ? (bsh&0x7fffffff) + offset*2
483 : bsh + offset);
484
485 while (count-- > 0) {
486 *addr++ = *datap++;
487 }
488 }
489
490 static inline void
491 _bus_space_write_region_2(t, bsh, offset, datap, count)
492 bus_space_tag_t t;
493 bus_space_handle_t bsh;
494 bus_size_t offset;
495 u_int16_t *datap;
496 bus_size_t count;
497 {
498 volatile u_int16_t *addr = (void *) ((bsh&0x80000000)
499 ? (bsh&0x7fffffff) + offset*2
500 : bsh + offset);
501
502 while (count-- > 0) {
503 *addr++ = *datap++;
504 }
505 }
506
507 static inline void
508 _bus_space_write_region_4(t, bsh, offset, datap, count)
509 bus_space_tag_t t;
510 bus_space_handle_t bsh;
511 bus_size_t offset;
512 u_int32_t *datap;
513 bus_size_t count;
514 {
515 volatile u_int32_t *addr = (void *) ((bsh&0x80000000)
516 ? (bsh&0x7fffffff) + offset*2
517 : bsh + offset);
518
519 while (count-- > 0) {
520 *addr++ = *datap++;
521 }
522 }
523
524 static inline void
525 _bus_space_set_region_1(t, bsh, offset, value, count)
526 bus_space_tag_t t;
527 bus_space_handle_t bsh;
528 bus_size_t offset;
529 u_int8_t value;
530 bus_size_t count;
531 {
532 volatile u_int8_t *addr = (void *) ((bsh&0x80000000)
533 ? (bsh&0x7fffffff) + offset*2
534 : bsh + offset);
535
536 while (count-- > 0) {
537 *addr++ = value;
538 }
539 }
540
541 static inline void
542 _bus_space_set_region_2(t, bsh, offset, value, count)
543 bus_space_tag_t t;
544 bus_space_handle_t bsh;
545 bus_size_t offset;
546 u_int16_t value;
547 bus_size_t count;
548 {
549 volatile u_int16_t *addr = (void *) ((bsh&0x80000000)
550 ? (bsh&0x7fffffff) + offset*2
551 : bsh + offset);
552
553 while (count-- > 0) {
554 *addr++ = value;
555 }
556 }
557
558 static inline void
559 _bus_space_set_region_4(t, bsh, offset, value, count)
560 bus_space_tag_t t;
561 bus_space_handle_t bsh;
562 bus_size_t offset;
563 u_int32_t value;
564 bus_size_t count;
565 {
566 volatile u_int32_t *addr = (void *) ((bsh&0x80000000)
567 ? (bsh&0x7fffffff) + offset*2
568 : bsh + offset);
569
570 while (count-- > 0) {
571 *addr++ = value;
572 }
573 }
574
575 static inline void
576 _bus_space_copy_region_1(t, sbsh, soffset, dbsh, doffset, count)
577 bus_space_tag_t t;
578 bus_space_handle_t sbsh;
579 bus_size_t soffset;
580 bus_space_handle_t dbsh;
581 bus_size_t doffset;
582 bus_size_t count;
583 {
584 volatile u_int8_t *saddr = (void *) (sbsh + soffset);
585 volatile u_int8_t *daddr = (void *) (dbsh + doffset);
586
587 if ((u_int32_t) saddr >= (u_int32_t) daddr)
588 while (count-- > 0)
589 *daddr++ = *saddr++;
590 else {
591 saddr += count;
592 daddr += count;
593 while (count-- > 0)
594 *--daddr = *--saddr;
595 }
596 }
597
598 static inline void
599 _bus_space_copy_region_2(t, sbsh, soffset, dbsh, doffset, count)
600 bus_space_tag_t t;
601 bus_space_handle_t sbsh;
602 bus_size_t soffset;
603 bus_space_handle_t dbsh;
604 bus_size_t doffset;
605 bus_size_t count;
606 {
607 volatile u_int16_t *saddr = (void *) (sbsh + soffset);
608 volatile u_int16_t *daddr = (void *) (dbsh + doffset);
609
610 if ((u_int32_t) saddr >= (u_int32_t) daddr)
611 while (count-- > 0)
612 *daddr++ = *saddr++;
613 else {
614 saddr += count;
615 daddr += count;
616 while (count-- > 0)
617 *--daddr = *--saddr;
618 }
619 }
620
621 static inline void
622 _bus_space_copy_region_4(t, sbsh, soffset, dbsh, doffset, count)
623 bus_space_tag_t t;
624 bus_space_handle_t sbsh;
625 bus_size_t soffset;
626 bus_space_handle_t dbsh;
627 bus_size_t doffset;
628 bus_size_t count;
629 {
630 volatile u_int32_t *saddr = (void *) (sbsh + soffset);
631 volatile u_int32_t *daddr = (void *) (dbsh + doffset);
632
633 if ((u_int32_t) saddr >= (u_int32_t) daddr)
634 while (count-- > 0)
635 *daddr++ = *saddr++;
636 else {
637 saddr += count;
638 daddr += count;
639 while (count-- > 0)
640 *--daddr = *--saddr;
641 }
642 }
643
644 #define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t)
645
646 /*
647 * DMA segment
648 */
649 struct x68k_bus_dma_segment {
650 bus_addr_t ds_addr;
651 bus_size_t ds_len;
652 };
653 typedef struct x68k_bus_dma_segment bus_dma_segment_t;
654
655 /*
656 * DMA descriptor
657 */
658 /* Forwards needed by prototypes below. */
659 struct mbuf;
660 struct uio;
661
662 typedef struct x68k_bus_dma *bus_dma_tag_t;
663 typedef struct x68k_bus_dmamap *bus_dmamap_t;
664 struct x68k_bus_dma {
665 /*
666 * The `bounce threshold' is checked while we are loading
667 * the DMA map. If the physical address of the segment
668 * exceeds the threshold, an error will be returned. The
669 * caller can then take whatever action is necessary to
670 * bounce the transfer. If this value is 0, it will be
671 * ignored.
672 */
673 bus_addr_t _bounce_thresh;
674
675 /*
676 * DMA mapping methods.
677 */
678 int (*x68k_dmamap_create) __P((bus_dma_tag_t, bus_size_t, int,
679 bus_size_t, bus_size_t, int, bus_dmamap_t *));
680 void (*x68k_dmamap_destroy) __P((bus_dma_tag_t, bus_dmamap_t));
681 int (*x68k_dmamap_load) __P((bus_dma_tag_t, bus_dmamap_t, void *,
682 bus_size_t, struct proc *, int));
683 int (*x68k_dmamap_load_mbuf) __P((bus_dma_tag_t, bus_dmamap_t,
684 struct mbuf *, int));
685 int (*x68k_dmamap_load_uio) __P((bus_dma_tag_t, bus_dmamap_t,
686 struct uio *, int));
687 int (*x68k_dmamap_load_raw) __P((bus_dma_tag_t, bus_dmamap_t,
688 bus_dma_segment_t *, int, bus_size_t, int));
689 void (*x68k_dmamap_unload) __P((bus_dma_tag_t, bus_dmamap_t));
690 void (*x68k_dmamap_sync) __P((bus_dma_tag_t, bus_dmamap_t,
691 bus_addr_t, bus_size_t, int));
692
693 /*
694 * DMA memory utility functions.
695 */
696 int (*x68k_dmamem_alloc) __P((bus_dma_tag_t, bus_size_t, bus_size_t,
697 bus_size_t, bus_dma_segment_t *, int, int *, int));
698 void (*x68k_dmamem_free) __P((bus_dma_tag_t,
699 bus_dma_segment_t *, int));
700 int (*x68k_dmamem_map) __P((bus_dma_tag_t, bus_dma_segment_t *,
701 int, size_t, caddr_t *, int));
702 void (*x68k_dmamem_unmap) __P((bus_dma_tag_t, caddr_t, size_t));
703 int (*x68k_dmamem_mmap) __P((bus_dma_tag_t, bus_dma_segment_t *,
704 int, int, int, int));
705 };
706
707 /*
708 * bus_dmamap_t
709 *
710 * Describes a DMA mapping.
711 */
712 struct x68k_bus_dmamap {
713 /*
714 * PRIVATE MEMBERS: not for use my machine-independent code.
715 */
716 bus_size_t x68k_dm_size; /* largest DMA transfer mappable */
717 int x68k_dm_segcnt; /* number of segs this map can map */
718 bus_size_t x68k_dm_maxsegsz; /* largest possible segment */
719 bus_size_t x68k_dm_boundary; /* don't cross this */
720 bus_addr_t x68k_dm_bounce_thresh; /* bounce threshold */
721 int x68k_dm_flags; /* misc. flags */
722
723 void *x68k_dm_cookie; /* cookie for bus-specific functions */
724
725 /*
726 * PUBLIC MEMBERS: these are used by machine-independent code.
727 */
728 bus_size_t dm_mapsize; /* size of the mapping */
729 int dm_nsegs; /* # valid segments in mapping */
730 bus_dma_segment_t dm_segs[1]; /* segments; variable length */
731 };
732
733 int x68k_bus_dmamap_create __P((bus_dma_tag_t, bus_size_t, int, bus_size_t,
734 bus_size_t, int, bus_dmamap_t *));
735 void x68k_bus_dmamap_destroy __P((bus_dma_tag_t, bus_dmamap_t));
736 int x68k_bus_dmamap_load __P((bus_dma_tag_t, bus_dmamap_t, void *,
737 bus_size_t, struct proc *, int));
738 int x68k_bus_dmamap_load_mbuf __P((bus_dma_tag_t, bus_dmamap_t,
739 struct mbuf *, int));
740 int x68k_bus_dmamap_load_uio __P((bus_dma_tag_t, bus_dmamap_t,
741 struct uio *, int));
742 int x68k_bus_dmamap_load_raw __P((bus_dma_tag_t, bus_dmamap_t,
743 bus_dma_segment_t *, int, bus_size_t, int));
744 void x68k_bus_dmamap_unload __P((bus_dma_tag_t, bus_dmamap_t));
745 void x68k_bus_dmamap_sync __P((bus_dma_tag_t, bus_dmamap_t, bus_addr_t,
746 bus_size_t, int));
747
748 int x68k_bus_dmamem_alloc __P((bus_dma_tag_t tag, bus_size_t size,
749 bus_size_t alignment, bus_size_t boundary,
750 bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags));
751 void x68k_bus_dmamem_free __P((bus_dma_tag_t tag, bus_dma_segment_t *segs,
752 int nsegs));
753 int x68k_bus_dmamem_map __P((bus_dma_tag_t tag, bus_dma_segment_t *segs,
754 int nsegs, size_t size, caddr_t *kvap, int flags));
755 void x68k_bus_dmamem_unmap __P((bus_dma_tag_t tag, caddr_t kva,
756 size_t size));
757 int x68k_bus_dmamem_mmap __P((bus_dma_tag_t tag, bus_dma_segment_t *segs,
758 int nsegs, int off, int prot, int flags));
759
760 int x68k_bus_dmamap_load_buffer __P((bus_dmamap_t, void *,
761 bus_size_t buflen, struct proc *, int, paddr_t *, int *, int));
762 int x68k_bus_dmamem_alloc_range __P((bus_dma_tag_t tag, bus_size_t size,
763 bus_size_t alignment, bus_size_t boundary,
764 bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags,
765 paddr_t low, paddr_t high));
766
767 #define bus_dmamap_create(t,s,n,m,b,f,p) \
768 ((*((t)->x68k_dmamap_create)) ((t),(s),(n),(m),(b),(f),(p)))
769 #define bus_dmamap_destroy(t,p) \
770 ((*((t)->x68k_dmamap_destroy)) ((t),(p)))
771 #define bus_dmamap_load(t,m,b,s,p,f) \
772 ((*((t)->x68k_dmamap_load)) ((t),(m),(b),(s),(p),(f)))
773 #define bus_dmamap_load_mbuf(t,m,b,f) \
774 ((*((t)->x68k_dmamap_load_mbuf)) ((t),(m),(b),(f)))
775 #define bus_dmamap_load_uio(t,m,u,f) \
776 ((*((t)->x68k_dmamap_load_uio)) ((t),(m),(u),(f)))
777 #define bus_dmamap_load_raw(t,m,sg,n,s,f) \
778 ((*((t)->x68k_dmamap_load_raw)) ((t),(m),(sg),(n),(s),(f)))
779 #define bus_dmamap_unload(t,p) \
780 ((*((t)->x68k_dmamap_unload)) ((t),(p)))
781 #define bus_dmamap_sync(t,p,o,l,ops) \
782 ((*((t)->x68k_dmamap_sync)) ((t),(p),(o),(l),(ops)))
783
784 #define bus_dmamem_alloc(t,s,a,b,sg,n,r,f) \
785 ((*((t)->x68k_dmamem_alloc)) ((t),(s),(a),(b),(sg),(n),(r),(f)))
786 #define bus_dmamem_free(t,sg,n) \
787 ((*((t)->x68k_dmamem_free)) ((t),(sg),(n)))
788 #define bus_dmamem_map(t,sg,n,s,k,f) \
789 ((*((t)->x68k_dmamem_map)) ((t),(sg),(n),(s),(k),(f)))
790 #define bus_dmamem_unmap(t,k,s) \
791 ((*((t)->x68k_dmamem_unmap)) ((t),(k),(s)))
792 #define bus_dmamem_mmap(t,sg,n,o,p,f) \
793 ((*((t)->x68k_dmamem_mmap)) ((t),(sg),(n),(o),(p),(f)))
794
795 /*
796 * Flags used in various bus DMA methods.
797 */
798 #define BUS_DMA_WAITOK 0x00 /* safe to sleep (pseudo-flag) */
799 #define BUS_DMA_NOWAIT 0x01 /* not safe to sleep */
800 #define BUS_DMA_ALLOCNOW 0x02 /* perform resource allocation now */
801 #define BUS_DMA_COHERENT 0x04 /* hint: map memory DMA coherent */
802 #define BUS_DMA_BUS1 0x10 /* placeholders for bus functions... */
803 #define BUS_DMA_BUS2 0x20
804 #define BUS_DMA_BUS3 0x40
805 #define BUS_DMA_BUS4 0x80
806
807 /*
808 * Operations performed by bus_dmamap_sync().
809 */
810 #define BUS_DMASYNC_PREREAD 0x01 /* pre-read synchronization */
811 #define BUS_DMASYNC_POSTREAD 0x02 /* post-read synchronization */
812 #define BUS_DMASYNC_PREWRITE 0x04 /* pre-write synchronization */
813 #define BUS_DMASYNC_POSTWRITE 0x08 /* post-write synchronization */
814
815 #endif /* _X68K_BUS_H_ */
816