bus.h revision 1.4 1 /* $NetBSD: bus.h,v 1.4 2000/01/25 22:13:25 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 #define BUS_SPACE_MAP_PREFETCHABLE 0x0004
128 /*
129 * For simpler hadware, many x68k devices are mapped with shifted address
130 * i.e. only on even or odd addresses.
131 */
132 #define BUS_SPACE_MAP_SHIFTED 0x1001
133
134 #define bus_space_alloc(t,rs,re,s,a,b,f,r,h) \
135 ((*((t)->x68k_bus_space_alloc)) ((t),(rs),(re),(s),(a),(b),(f),(r),(h)))
136 #define bus_space_free(t,h,s) \
137 ((*((t)->x68k_bus_space_free)) ((t),(h),(s)))
138
139 /*
140 * Note: the 680x0 does not currently require barriers, but we must
141 * provide the flags to MI code.
142 */
143 #define bus_space_barrier(t, h, o, l, f) \
144 ((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f)))
145 #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */
146 #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */
147
148 #define bus_space_read_1(t,h,o) _bus_space_read_1(t,h,o)
149 #define bus_space_read_2(t,h,o) _bus_space_read_2(t,h,o)
150 #define bus_space_read_4(t,h,o) _bus_space_read_4(t,h,o)
151
152 #define bus_space_read_multi_1(t,h,o,p,c) _bus_space_read_multi_1(t,h,o,p,c)
153 #define bus_space_read_multi_2(t,h,o,p,c) _bus_space_read_multi_2(t,h,o,p,c)
154 #define bus_space_read_multi_4(t,h,o,p,c) _bus_space_read_multi_4(t,h,o,p,c)
155
156 #define bus_space_read_region_1(t,h,o,p,c) _bus_space_read_region_1(t,h,o,p,c)
157 #define bus_space_read_region_2(t,h,o,p,c) _bus_space_read_region_2(t,h,o,p,c)
158 #define bus_space_read_region_4(t,h,o,p,c) _bus_space_read_region_4(t,h,o,p,c)
159
160 #define bus_space_write_1(t,h,o,v) _bus_space_write_1(t,h,o,v)
161 #define bus_space_write_2(t,h,o,v) _bus_space_write_2(t,h,o,v)
162 #define bus_space_write_4(t,h,o,v) _bus_space_write_4(t,h,o,v)
163
164 #define bus_space_write_multi_1(t,h,o,p,c) _bus_space_write_multi_1(t,h,o,p,c)
165 #define bus_space_write_multi_2(t,h,o,p,c) _bus_space_write_multi_2(t,h,o,p,c)
166 #define bus_space_write_multi_4(t,h,o,p,c) _bus_space_write_multi_4(t,h,o,p,c)
167
168 #define bus_space_write_region_1(t,h,o,p,c) \
169 _bus_space_write_region_1(t,h,o,p,c)
170 #define bus_space_write_region_2(t,h,o,p,c) \
171 _bus_space_write_region_2(t,h,o,p,c)
172 #define bus_space_write_region_4(t,h,o,p,c) \
173 _bus_space_write_region_4(t,h,o,p,c)
174
175 #define bus_space_set_region_1(t,h,o,v,c) _bus_space_set_region_1(t,h,o,v,c)
176 #define bus_space_set_region_2(t,h,o,v,c) _bus_space_set_region_2(t,h,o,v,c)
177 #define bus_space_set_region_4(t,h,o,v,c) _bus_space_set_region_4(t,h,o,v,c)
178
179 #define bus_space_copy_region_1(t,sh,so,dh,do,c) \
180 _bus_space_copy_region_1(t,sh,so,dh,do,c)
181 #define bus_space_copy_region_2(t,sh,so,dh,do,c) \
182 _bus_space_copy_region_2(t,sh,so,dh,do,c)
183 #define bus_space_copy_region_4(t,sh,so,dh,do,c) \
184 _bus_space_copy_region_4(t,sh,so,dh,do,c)
185
186 static inline u_int8_t _bus_space_read_1
187 __P((bus_space_tag_t, bus_space_handle_t bsh, bus_size_t offset));
188 static inline u_int16_t _bus_space_read_2
189 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t));
190 static inline u_int32_t _bus_space_read_4
191 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t));
192
193 static inline void _bus_space_read_multi_1
194 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
195 u_int8_t *, bus_size_t));
196 static inline void _bus_space_read_multi_2
197 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
198 u_int16_t *, bus_size_t));
199 static inline void _bus_space_read_multi_4
200 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
201 u_int32_t *, bus_size_t));
202
203 static inline void _bus_space_read_region_1
204 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
205 u_int8_t *, bus_size_t));
206 static inline void _bus_space_read_region_2
207 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
208 u_int16_t *, bus_size_t));
209 static inline void _bus_space_read_region_4
210 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
211 u_int32_t *, bus_size_t));
212
213 static inline void _bus_space_write_1
214 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int8_t));
215 static inline void _bus_space_write_2
216 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t));
217 static inline void _bus_space_write_4
218 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t));
219
220 static inline void _bus_space_write_multi_1
221 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
222 u_int8_t *, bus_size_t));
223 static inline void _bus_space_write_multi_2
224 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
225 u_int16_t *, bus_size_t));
226 static inline void _bus_space_write_multi_4
227 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
228 u_int32_t *, bus_size_t));
229
230 static inline void _bus_space_write_region_1
231 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
232 u_int8_t *, bus_size_t));
233 static inline void _bus_space_write_region_2
234 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
235 u_int16_t *, bus_size_t));
236 static inline void _bus_space_write_region_4
237 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
238 u_int32_t *, bus_size_t));
239
240 static inline void _bus_space_set_region_1
241 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
242 u_int8_t, bus_size_t));
243 static inline void _bus_space_set_region_2
244 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
245 u_int16_t, bus_size_t));
246 static inline void _bus_space_set_region_4
247 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
248 u_int32_t, bus_size_t));
249
250 static inline void _bus_space_copy_region_1
251 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
252 bus_space_handle_t, bus_size_t, bus_size_t));
253 static inline void _bus_space_copy_region_2
254 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
255 bus_space_handle_t, bus_size_t, bus_size_t));
256 static inline void _bus_space_copy_region_4
257 __P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
258 bus_space_handle_t, bus_size_t, bus_size_t));
259
260
261 static inline u_int8_t
262 _bus_space_read_1(t, bsh, offset)
263 bus_space_tag_t t;
264 bus_space_handle_t bsh;
265 bus_size_t offset;
266 {
267 return (*((volatile u_int8_t *) ((bsh&0x80000000)
268 ? (bsh&0x7fffffff) + offset*2
269 : bsh + offset)));
270 }
271
272 static inline u_int16_t
273 _bus_space_read_2(t, bsh, offset)
274 bus_space_tag_t t;
275 bus_space_handle_t bsh;
276 bus_size_t offset;
277 {
278 return (*((volatile u_int16_t *) ((bsh&0x80000000)
279 ? (bsh&0x7fffffff) + offset*2
280 : bsh + offset)));
281 }
282
283 static inline u_int32_t
284 _bus_space_read_4(t, bsh, offset)
285 bus_space_tag_t t;
286 bus_space_handle_t bsh;
287 bus_size_t offset;
288 {
289 return (*((volatile u_int32_t *) ((bsh&0x80000000)
290 ? (bsh&0x7fffffff) + offset*2
291 : bsh + offset)));
292 }
293
294 static inline void
295 _bus_space_read_multi_1(t, bsh, offset, datap, count)
296 bus_space_tag_t t;
297 bus_space_handle_t bsh;
298 bus_size_t offset;
299 u_int8_t *datap;
300 bus_size_t count;
301 {
302 while (count-- > 0) {
303 *datap++ = *(volatile u_int8_t *) ((bsh&0x80000000)
304 ? ((bsh&0x7fffffff)
305 + offset*2)
306 : bsh + offset);
307 }
308 }
309
310 static inline void
311 _bus_space_read_multi_2(t, bsh, offset, datap, count)
312 bus_space_tag_t t;
313 bus_space_handle_t bsh;
314 bus_size_t offset;
315 u_int16_t *datap;
316 bus_size_t count;
317 {
318 while (count-- > 0) {
319 *datap++ = *(volatile u_int16_t *) ((bsh&0x80000000)
320 ? ((bsh&0x7fffffff)
321 + offset*2)
322 : bsh + offset);
323 }
324 }
325
326 static inline void
327 _bus_space_read_multi_4(t, bsh, offset, datap, count)
328 bus_space_tag_t t;
329 bus_space_handle_t bsh;
330 bus_size_t offset;
331 u_int32_t *datap;
332 bus_size_t count;
333 {
334 while (count-- > 0) {
335 *datap++ = *(volatile u_int32_t *) ((bsh&0x80000000)
336 ? ((bsh&0x7fffffff)
337 + offset*2)
338 : bsh + offset);
339 }
340 }
341
342 static inline void
343 _bus_space_read_region_1(t, bsh, offset, datap, count)
344 bus_space_tag_t t;
345 bus_space_handle_t bsh;
346 bus_size_t offset;
347 u_int8_t *datap;
348 bus_size_t count;
349 {
350 volatile u_int8_t *addr = (void *) ((bsh&0x80000000)
351 ? (bsh&0x7fffffff) + offset*2
352 : bsh + offset);
353
354 while (count-- > 0) {
355 *datap++ = *addr++;
356 }
357 }
358
359 static inline void
360 _bus_space_read_region_2(t, bsh, offset, datap, count)
361 bus_space_tag_t t;
362 bus_space_handle_t bsh;
363 bus_size_t offset;
364 u_int16_t *datap;
365 bus_size_t count;
366 {
367 volatile u_int16_t *addr = (void *) ((bsh&0x80000000)
368 ? (bsh&0x7fffffff) + offset*2
369 : bsh + offset);
370
371 while (count-- > 0) {
372 *datap++ = *addr++;
373 }
374 }
375
376 static inline void
377 _bus_space_read_region_4(t, bsh, offset, datap, count)
378 bus_space_tag_t t;
379 bus_space_handle_t bsh;
380 bus_size_t offset;
381 u_int32_t *datap;
382 bus_size_t count;
383 {
384 volatile u_int32_t *addr = (void *) ((bsh&0x80000000)
385 ? (bsh&0x7fffffff) + offset*2
386 : bsh + offset);
387
388 while (count-- > 0) {
389 *datap++ = *addr++;
390 }
391 }
392
393 static inline void
394 _bus_space_write_1(t, bsh, offset, value)
395 bus_space_tag_t t;
396 bus_space_handle_t bsh;
397 bus_size_t offset;
398 u_int8_t value;
399 {
400 *(volatile u_int8_t *) ((bsh&0x80000000)
401 ? (bsh&0x7fffffff) + offset*2
402 : bsh + offset) = value;
403 }
404
405 static inline void
406 _bus_space_write_2(t, bsh, offset, value)
407 bus_space_tag_t t;
408 bus_space_handle_t bsh;
409 bus_size_t offset;
410 u_int16_t value;
411 {
412 *(volatile u_int16_t *) ((bsh&0x80000000)
413 ? (bsh&0x7fffffff) + offset*2
414 : bsh + offset) = value;
415 }
416
417 static inline void
418 _bus_space_write_4(t, bsh, offset, value)
419 bus_space_tag_t t;
420 bus_space_handle_t bsh;
421 bus_size_t offset;
422 u_int32_t value;
423 {
424 *(volatile u_int32_t *) ((bsh&0x80000000)
425 ? (bsh&0x7fffffff) + offset*2
426 : bsh + offset) = value;
427 }
428
429 static inline void
430 _bus_space_write_multi_1(t, bsh, offset, datap, count)
431 bus_space_tag_t t;
432 bus_space_handle_t bsh;
433 bus_size_t offset;
434 u_int8_t *datap;
435 bus_size_t count;
436 {
437 while (count-- > 0) {
438 *(volatile u_int8_t *) ((bsh&0x80000000)
439 ? (bsh&0x7fffffff) + offset*2
440 : bsh + offset) = *datap++;
441 }
442 }
443
444 static inline void
445 _bus_space_write_multi_2(t, bsh, offset, datap, count)
446 bus_space_tag_t t;
447 bus_space_handle_t bsh;
448 bus_size_t offset;
449 u_int16_t *datap;
450 bus_size_t count;
451 {
452 while (count-- > 0) {
453 *(volatile u_int16_t *) ((bsh&0x80000000)
454 ? (bsh&0x7fffffff) + offset*2
455 : bsh + offset) = *datap++;
456 }
457 }
458
459 static inline void
460 _bus_space_write_multi_4(t, bsh, offset, datap, count)
461 bus_space_tag_t t;
462 bus_space_handle_t bsh;
463 bus_size_t offset;
464 u_int32_t *datap;
465 bus_size_t count;
466 {
467 while (count-- > 0) {
468 *(volatile u_int32_t *) ((bsh&0x80000000)
469 ? (bsh&0x7fffffff) + offset*2
470 : bsh + offset) = *datap++;
471 }
472 }
473
474 static inline void
475 _bus_space_write_region_1(t, bsh, offset, datap, count)
476 bus_space_tag_t t;
477 bus_space_handle_t bsh;
478 bus_size_t offset;
479 u_int8_t *datap;
480 bus_size_t count;
481 {
482 volatile u_int8_t *addr = (void *) ((bsh&0x80000000)
483 ? (bsh&0x7fffffff) + offset*2
484 : bsh + offset);
485
486 while (count-- > 0) {
487 *addr++ = *datap++;
488 }
489 }
490
491 static inline void
492 _bus_space_write_region_2(t, bsh, offset, datap, count)
493 bus_space_tag_t t;
494 bus_space_handle_t bsh;
495 bus_size_t offset;
496 u_int16_t *datap;
497 bus_size_t count;
498 {
499 volatile u_int16_t *addr = (void *) ((bsh&0x80000000)
500 ? (bsh&0x7fffffff) + offset*2
501 : bsh + offset);
502
503 while (count-- > 0) {
504 *addr++ = *datap++;
505 }
506 }
507
508 static inline void
509 _bus_space_write_region_4(t, bsh, offset, datap, count)
510 bus_space_tag_t t;
511 bus_space_handle_t bsh;
512 bus_size_t offset;
513 u_int32_t *datap;
514 bus_size_t count;
515 {
516 volatile u_int32_t *addr = (void *) ((bsh&0x80000000)
517 ? (bsh&0x7fffffff) + offset*2
518 : bsh + offset);
519
520 while (count-- > 0) {
521 *addr++ = *datap++;
522 }
523 }
524
525 static inline void
526 _bus_space_set_region_1(t, bsh, offset, value, count)
527 bus_space_tag_t t;
528 bus_space_handle_t bsh;
529 bus_size_t offset;
530 u_int8_t value;
531 bus_size_t count;
532 {
533 volatile u_int8_t *addr = (void *) ((bsh&0x80000000)
534 ? (bsh&0x7fffffff) + offset*2
535 : bsh + offset);
536
537 while (count-- > 0) {
538 *addr++ = value;
539 }
540 }
541
542 static inline void
543 _bus_space_set_region_2(t, bsh, offset, value, count)
544 bus_space_tag_t t;
545 bus_space_handle_t bsh;
546 bus_size_t offset;
547 u_int16_t value;
548 bus_size_t count;
549 {
550 volatile u_int16_t *addr = (void *) ((bsh&0x80000000)
551 ? (bsh&0x7fffffff) + offset*2
552 : bsh + offset);
553
554 while (count-- > 0) {
555 *addr++ = value;
556 }
557 }
558
559 static inline void
560 _bus_space_set_region_4(t, bsh, offset, value, count)
561 bus_space_tag_t t;
562 bus_space_handle_t bsh;
563 bus_size_t offset;
564 u_int32_t value;
565 bus_size_t count;
566 {
567 volatile u_int32_t *addr = (void *) ((bsh&0x80000000)
568 ? (bsh&0x7fffffff) + offset*2
569 : bsh + offset);
570
571 while (count-- > 0) {
572 *addr++ = value;
573 }
574 }
575
576 static inline void
577 _bus_space_copy_region_1(t, sbsh, soffset, dbsh, doffset, count)
578 bus_space_tag_t t;
579 bus_space_handle_t sbsh;
580 bus_size_t soffset;
581 bus_space_handle_t dbsh;
582 bus_size_t doffset;
583 bus_size_t count;
584 {
585 volatile u_int8_t *saddr = (void *) (sbsh + soffset);
586 volatile u_int8_t *daddr = (void *) (dbsh + doffset);
587
588 if ((u_int32_t) saddr >= (u_int32_t) daddr)
589 while (count-- > 0)
590 *daddr++ = *saddr++;
591 else {
592 saddr += count;
593 daddr += count;
594 while (count-- > 0)
595 *--daddr = *--saddr;
596 }
597 }
598
599 static inline void
600 _bus_space_copy_region_2(t, sbsh, soffset, dbsh, doffset, count)
601 bus_space_tag_t t;
602 bus_space_handle_t sbsh;
603 bus_size_t soffset;
604 bus_space_handle_t dbsh;
605 bus_size_t doffset;
606 bus_size_t count;
607 {
608 volatile u_int16_t *saddr = (void *) (sbsh + soffset);
609 volatile u_int16_t *daddr = (void *) (dbsh + doffset);
610
611 if ((u_int32_t) saddr >= (u_int32_t) daddr)
612 while (count-- > 0)
613 *daddr++ = *saddr++;
614 else {
615 saddr += count;
616 daddr += count;
617 while (count-- > 0)
618 *--daddr = *--saddr;
619 }
620 }
621
622 static inline void
623 _bus_space_copy_region_4(t, sbsh, soffset, dbsh, doffset, count)
624 bus_space_tag_t t;
625 bus_space_handle_t sbsh;
626 bus_size_t soffset;
627 bus_space_handle_t dbsh;
628 bus_size_t doffset;
629 bus_size_t count;
630 {
631 volatile u_int32_t *saddr = (void *) (sbsh + soffset);
632 volatile u_int32_t *daddr = (void *) (dbsh + doffset);
633
634 if ((u_int32_t) saddr >= (u_int32_t) daddr)
635 while (count-- > 0)
636 *daddr++ = *saddr++;
637 else {
638 saddr += count;
639 daddr += count;
640 while (count-- > 0)
641 *--daddr = *--saddr;
642 }
643 }
644
645 #define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t)
646
647 /*
648 * DMA segment
649 */
650 struct x68k_bus_dma_segment {
651 bus_addr_t ds_addr;
652 bus_size_t ds_len;
653 };
654 typedef struct x68k_bus_dma_segment bus_dma_segment_t;
655
656 /*
657 * DMA descriptor
658 */
659 /* Forwards needed by prototypes below. */
660 struct mbuf;
661 struct uio;
662
663 typedef struct x68k_bus_dma *bus_dma_tag_t;
664 typedef struct x68k_bus_dmamap *bus_dmamap_t;
665 struct x68k_bus_dma {
666 /*
667 * The `bounce threshold' is checked while we are loading
668 * the DMA map. If the physical address of the segment
669 * exceeds the threshold, an error will be returned. The
670 * caller can then take whatever action is necessary to
671 * bounce the transfer. If this value is 0, it will be
672 * ignored.
673 */
674 bus_addr_t _bounce_thresh;
675
676 /*
677 * DMA mapping methods.
678 */
679 int (*x68k_dmamap_create) __P((bus_dma_tag_t, bus_size_t, int,
680 bus_size_t, bus_size_t, int, bus_dmamap_t *));
681 void (*x68k_dmamap_destroy) __P((bus_dma_tag_t, bus_dmamap_t));
682 int (*x68k_dmamap_load) __P((bus_dma_tag_t, bus_dmamap_t, void *,
683 bus_size_t, struct proc *, int));
684 int (*x68k_dmamap_load_mbuf) __P((bus_dma_tag_t, bus_dmamap_t,
685 struct mbuf *, int));
686 int (*x68k_dmamap_load_uio) __P((bus_dma_tag_t, bus_dmamap_t,
687 struct uio *, int));
688 int (*x68k_dmamap_load_raw) __P((bus_dma_tag_t, bus_dmamap_t,
689 bus_dma_segment_t *, int, bus_size_t, int));
690 void (*x68k_dmamap_unload) __P((bus_dma_tag_t, bus_dmamap_t));
691 void (*x68k_dmamap_sync) __P((bus_dma_tag_t, bus_dmamap_t,
692 bus_addr_t, bus_size_t, int));
693
694 /*
695 * DMA memory utility functions.
696 */
697 int (*x68k_dmamem_alloc) __P((bus_dma_tag_t, bus_size_t, bus_size_t,
698 bus_size_t, bus_dma_segment_t *, int, int *, int));
699 void (*x68k_dmamem_free) __P((bus_dma_tag_t,
700 bus_dma_segment_t *, int));
701 int (*x68k_dmamem_map) __P((bus_dma_tag_t, bus_dma_segment_t *,
702 int, size_t, caddr_t *, int));
703 void (*x68k_dmamem_unmap) __P((bus_dma_tag_t, caddr_t, size_t));
704 int (*x68k_dmamem_mmap) __P((bus_dma_tag_t, bus_dma_segment_t *,
705 int, int, int, int));
706 };
707
708 /*
709 * bus_dmamap_t
710 *
711 * Describes a DMA mapping.
712 */
713 struct x68k_bus_dmamap {
714 /*
715 * PRIVATE MEMBERS: not for use my machine-independent code.
716 */
717 bus_size_t x68k_dm_size; /* largest DMA transfer mappable */
718 int x68k_dm_segcnt; /* number of segs this map can map */
719 bus_size_t x68k_dm_maxsegsz; /* largest possible segment */
720 bus_size_t x68k_dm_boundary; /* don't cross this */
721 bus_addr_t x68k_dm_bounce_thresh; /* bounce threshold */
722 int x68k_dm_flags; /* misc. flags */
723
724 void *x68k_dm_cookie; /* cookie for bus-specific functions */
725
726 /*
727 * PUBLIC MEMBERS: these are used by machine-independent code.
728 */
729 bus_size_t dm_mapsize; /* size of the mapping */
730 int dm_nsegs; /* # valid segments in mapping */
731 bus_dma_segment_t dm_segs[1]; /* segments; variable length */
732 };
733
734 int x68k_bus_dmamap_create __P((bus_dma_tag_t, bus_size_t, int, bus_size_t,
735 bus_size_t, int, bus_dmamap_t *));
736 void x68k_bus_dmamap_destroy __P((bus_dma_tag_t, bus_dmamap_t));
737 int x68k_bus_dmamap_load __P((bus_dma_tag_t, bus_dmamap_t, void *,
738 bus_size_t, struct proc *, int));
739 int x68k_bus_dmamap_load_mbuf __P((bus_dma_tag_t, bus_dmamap_t,
740 struct mbuf *, int));
741 int x68k_bus_dmamap_load_uio __P((bus_dma_tag_t, bus_dmamap_t,
742 struct uio *, int));
743 int x68k_bus_dmamap_load_raw __P((bus_dma_tag_t, bus_dmamap_t,
744 bus_dma_segment_t *, int, bus_size_t, int));
745 void x68k_bus_dmamap_unload __P((bus_dma_tag_t, bus_dmamap_t));
746 void x68k_bus_dmamap_sync __P((bus_dma_tag_t, bus_dmamap_t, bus_addr_t,
747 bus_size_t, int));
748
749 int x68k_bus_dmamem_alloc __P((bus_dma_tag_t tag, bus_size_t size,
750 bus_size_t alignment, bus_size_t boundary,
751 bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags));
752 void x68k_bus_dmamem_free __P((bus_dma_tag_t tag, bus_dma_segment_t *segs,
753 int nsegs));
754 int x68k_bus_dmamem_map __P((bus_dma_tag_t tag, bus_dma_segment_t *segs,
755 int nsegs, size_t size, caddr_t *kvap, int flags));
756 void x68k_bus_dmamem_unmap __P((bus_dma_tag_t tag, caddr_t kva,
757 size_t size));
758 int x68k_bus_dmamem_mmap __P((bus_dma_tag_t tag, bus_dma_segment_t *segs,
759 int nsegs, int off, int prot, int flags));
760
761 int x68k_bus_dmamap_load_buffer __P((bus_dmamap_t, void *,
762 bus_size_t buflen, struct proc *, int, paddr_t *, int *, int));
763 int x68k_bus_dmamem_alloc_range __P((bus_dma_tag_t tag, bus_size_t size,
764 bus_size_t alignment, bus_size_t boundary,
765 bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags,
766 paddr_t low, paddr_t high));
767
768 #define bus_dmamap_create(t,s,n,m,b,f,p) \
769 ((*((t)->x68k_dmamap_create)) ((t),(s),(n),(m),(b),(f),(p)))
770 #define bus_dmamap_destroy(t,p) \
771 ((*((t)->x68k_dmamap_destroy)) ((t),(p)))
772 #define bus_dmamap_load(t,m,b,s,p,f) \
773 ((*((t)->x68k_dmamap_load)) ((t),(m),(b),(s),(p),(f)))
774 #define bus_dmamap_load_mbuf(t,m,b,f) \
775 ((*((t)->x68k_dmamap_load_mbuf)) ((t),(m),(b),(f)))
776 #define bus_dmamap_load_uio(t,m,u,f) \
777 ((*((t)->x68k_dmamap_load_uio)) ((t),(m),(u),(f)))
778 #define bus_dmamap_load_raw(t,m,sg,n,s,f) \
779 ((*((t)->x68k_dmamap_load_raw)) ((t),(m),(sg),(n),(s),(f)))
780 #define bus_dmamap_unload(t,p) \
781 ((*((t)->x68k_dmamap_unload)) ((t),(p)))
782 #define bus_dmamap_sync(t,p,o,l,ops) \
783 ((*((t)->x68k_dmamap_sync)) ((t),(p),(o),(l),(ops)))
784
785 #define bus_dmamem_alloc(t,s,a,b,sg,n,r,f) \
786 ((*((t)->x68k_dmamem_alloc)) ((t),(s),(a),(b),(sg),(n),(r),(f)))
787 #define bus_dmamem_free(t,sg,n) \
788 ((*((t)->x68k_dmamem_free)) ((t),(sg),(n)))
789 #define bus_dmamem_map(t,sg,n,s,k,f) \
790 ((*((t)->x68k_dmamem_map)) ((t),(sg),(n),(s),(k),(f)))
791 #define bus_dmamem_unmap(t,k,s) \
792 ((*((t)->x68k_dmamem_unmap)) ((t),(k),(s)))
793 #define bus_dmamem_mmap(t,sg,n,o,p,f) \
794 ((*((t)->x68k_dmamem_mmap)) ((t),(sg),(n),(o),(p),(f)))
795
796 /*
797 * Flags used in various bus DMA methods.
798 */
799 #define BUS_DMA_WAITOK 0x00 /* safe to sleep (pseudo-flag) */
800 #define BUS_DMA_NOWAIT 0x01 /* not safe to sleep */
801 #define BUS_DMA_ALLOCNOW 0x02 /* perform resource allocation now */
802 #define BUS_DMA_COHERENT 0x04 /* hint: map memory DMA coherent */
803 #define BUS_DMA_BUS1 0x10 /* placeholders for bus functions... */
804 #define BUS_DMA_BUS2 0x20
805 #define BUS_DMA_BUS3 0x40
806 #define BUS_DMA_BUS4 0x80
807
808 /*
809 * Operations performed by bus_dmamap_sync().
810 */
811 #define BUS_DMASYNC_PREREAD 0x01 /* pre-read synchronization */
812 #define BUS_DMASYNC_POSTREAD 0x02 /* post-read synchronization */
813 #define BUS_DMASYNC_PREWRITE 0x04 /* pre-write synchronization */
814 #define BUS_DMASYNC_POSTWRITE 0x08 /* post-write synchronization */
815
816 #endif /* _X68K_BUS_H_ */
817