bus.h revision 1.1 1 /* $NetBSD: bus.h,v 1.1 2001/06/14 12:57:10 fredette Exp $ */
2
3 /*-
4 * Copyright (c) 1996, 1997, 1998, 2001 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 * Copyright (c) 1996 Charles M. Hannum. All rights reserved.
42 * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
43 *
44 * Redistribution and use in source and binary forms, with or without
45 * modification, are permitted provided that the following conditions
46 * are met:
47 * 1. Redistributions of source code must retain the above copyright
48 * notice, this list of conditions and the following disclaimer.
49 * 2. Redistributions in binary form must reproduce the above copyright
50 * notice, this list of conditions and the following disclaimer in the
51 * documentation and/or other materials provided with the distribution.
52 * 3. All advertising materials mentioning features or use of this software
53 * must display the following acknowledgement:
54 * This product includes software developed by Christopher G. Demetriou
55 * for the NetBSD Project.
56 * 4. The name of the author may not be used to endorse or promote products
57 * derived from this software without specific prior written permission
58 *
59 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
60 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
61 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
62 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
63 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
64 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
65 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
66 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
67 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
68 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
69 */
70
71 #ifndef _SUN68K_BUS_H_
72 #define _SUN68K_BUS_H_
73
74 #define SUN68K_BUS_SPACE 0
75
76 /*
77 * Bus address and size types
78 */
79 typedef u_long bus_space_handle_t;
80 typedef u_long bus_type_t;
81 typedef u_long bus_addr_t;
82 typedef u_long bus_size_t;
83
84 /*
85 * Access methods for bus resources and address space.
86 */
87 typedef struct sun68k_bus_space_tag *bus_space_tag_t;
88
89 struct sun68k_bus_space_tag {
90 void *cookie;
91 bus_space_tag_t parent;
92
93 int (*sun68k_bus_map) __P((
94 bus_space_tag_t,
95 bus_type_t,
96 bus_addr_t,
97 bus_size_t,
98 int, /*flags*/
99 vaddr_t, /*preferred vaddr*/
100 bus_space_handle_t *));
101 int (*sun68k_bus_unmap) __P((
102 bus_space_tag_t,
103 bus_space_handle_t,
104 bus_size_t));
105 int (*sun68k_bus_subregion) __P((
106 bus_space_tag_t,
107 bus_space_handle_t,
108 bus_size_t, /*offset*/
109 bus_size_t, /*size*/
110 bus_space_handle_t *));
111
112 void (*sun68k_bus_barrier) __P((
113 bus_space_tag_t,
114 bus_space_handle_t,
115 bus_size_t, /*offset*/
116 bus_size_t, /*size*/
117 int)); /*flags*/
118
119 int (*sun68k_bus_mmap) __P((
120 bus_space_tag_t,
121 bus_type_t, /**/
122 bus_addr_t, /**/
123 int, /*flags*/
124 bus_space_handle_t *));
125
126 void *(*sun68k_intr_establish) __P((
127 bus_space_tag_t,
128 int, /*bus-specific intr*/
129 int, /*device class level,
130 see machine/intr.h*/
131 int, /*flags*/
132 int (*) __P((void *)), /*handler*/
133 void *)); /*handler arg*/
134
135 int (*sun68k_bus_peek) __P((
136 bus_space_tag_t,
137 bus_space_handle_t,
138 bus_size_t, /*offset*/
139 size_t, /*probe size*/
140 void *)); /*result ptr*/
141
142 int (*sun68k_bus_poke) __P((
143 bus_space_tag_t,
144 bus_space_handle_t,
145 bus_size_t, /*offset*/
146 size_t, /*probe size*/
147 u_int32_t)); /*value*/
148 };
149
150 #if 0
151 /*
152 * The following macro could be used to generate the bus_space*() functions
153 * but it uses a gcc extension and is ANSI-only.
154 #define PROTO_bus_space_xxx __P((bus_space_tag_t t, ...))
155 #define RETURNTYPE_bus_space_xxx void *
156 #define BUSFUN(name, returntype, t, args...) \
157 __inline__ RETURNTYPE_##name \
158 bus_##name PROTO_##name \
159 { \
160 while (t->sun68k_##name == NULL) \
161 t = t->parent; \
162 return (*(t)->sun68k_##name)(t, args); \
163 }
164 */
165 #endif
166
167 /*
168 * Bus space function prototypes.
169 */
170 static int bus_space_map __P((
171 bus_space_tag_t,
172 bus_addr_t,
173 bus_size_t,
174 int, /*flags*/
175 bus_space_handle_t *));
176 static int bus_space_map2 __P((
177 bus_space_tag_t,
178 bus_type_t,
179 bus_addr_t,
180 bus_size_t,
181 int, /*flags*/
182 vaddr_t, /*preferred vaddr*/
183 bus_space_handle_t *));
184 static int bus_space_unmap __P((
185 bus_space_tag_t,
186 bus_space_handle_t,
187 bus_size_t));
188 static int bus_space_subregion __P((
189 bus_space_tag_t,
190 bus_space_handle_t,
191 bus_size_t,
192 bus_size_t,
193 bus_space_handle_t *));
194 static void bus_space_barrier __P((
195 bus_space_tag_t,
196 bus_space_handle_t,
197 bus_size_t,
198 bus_size_t,
199 int));
200 static int bus_space_mmap __P((
201 bus_space_tag_t,
202 bus_type_t, /**/
203 bus_addr_t, /**/
204 int, /*flags*/
205 bus_space_handle_t *));
206 static void *bus_intr_establish __P((
207 bus_space_tag_t,
208 int, /*bus-specific intr*/
209 int, /*device class level,
210 see machine/intr.h*/
211 int, /*flags*/
212 int (*) __P((void *)), /*handler*/
213 void *)); /*handler arg*/
214 static int _bus_space_peek __P((
215 bus_space_tag_t,
216 bus_space_handle_t,
217 bus_size_t, /*offset*/
218 size_t, /*probe size*/
219 void *)); /*result ptr*/
220 static int _bus_space_poke __P((
221 bus_space_tag_t,
222 bus_space_handle_t,
223 bus_size_t, /*offset*/
224 size_t, /*probe size*/
225 u_int32_t)); /*value*/
226
227 /* This macro finds the first "upstream" implementation of method `f' */
228 #define _BS_CALL(t,f) \
229 while (t->f == NULL) \
230 t = t->parent; \
231 return (*(t)->f)
232
233 __inline__ int
234 bus_space_map(t, a, s, f, hp)
235 bus_space_tag_t t;
236 bus_addr_t a;
237 bus_size_t s;
238 int f;
239 bus_space_handle_t *hp;
240 {
241 _BS_CALL(t, sun68k_bus_map)((t), 0, (a), (s), (f), 0, (hp));
242 }
243
244 __inline__ int
245 bus_space_map2(t, bt, a, s, f, v, hp)
246 bus_space_tag_t t;
247 bus_type_t bt;
248 bus_addr_t a;
249 bus_size_t s;
250 int f;
251 vaddr_t v;
252 bus_space_handle_t *hp;
253 {
254 _BS_CALL(t, sun68k_bus_map)(t, bt, a, s, f, v, hp);
255 }
256
257 __inline__ int
258 bus_space_unmap(t, h, s)
259 bus_space_tag_t t;
260 bus_space_handle_t h;
261 bus_size_t s;
262 {
263 _BS_CALL(t, sun68k_bus_unmap)(t, h, s);
264 }
265
266 __inline__ int
267 bus_space_subregion(t, h, o, s, hp)
268 bus_space_tag_t t;
269 bus_space_handle_t h;
270 bus_size_t o;
271 bus_size_t s;
272 bus_space_handle_t *hp;
273 {
274 _BS_CALL(t, sun68k_bus_subregion)(t, h, o, s, hp);
275 }
276
277 __inline__ int
278 bus_space_mmap(t, bt, a, f, hp)
279 bus_space_tag_t t;
280 bus_type_t bt;
281 bus_addr_t a;
282 int f;
283 bus_space_handle_t *hp;
284 {
285 _BS_CALL(t, sun68k_bus_mmap)(t, bt, a, f, hp);
286 }
287
288 __inline__ void *
289 bus_intr_establish(t, p, l, f, h, a)
290 bus_space_tag_t t;
291 int p;
292 int l;
293 int f;
294 int (*h)__P((void *));
295 void *a;
296 {
297 _BS_CALL(t, sun68k_intr_establish)(t, p, l, f, h, a);
298 }
299
300 __inline__ void
301 bus_space_barrier(t, h, o, s, f)
302 bus_space_tag_t t;
303 bus_space_handle_t h;
304 bus_size_t o;
305 bus_size_t s;
306 int f;
307 {
308 _BS_CALL(t, sun68k_bus_barrier)(t, h, o, s, f);
309 }
310
311 __inline__ int
312 _bus_space_peek(t, h, o, s, vp)
313 bus_space_tag_t t;
314 bus_space_handle_t h;
315 bus_size_t o;
316 size_t s;
317 void *vp;
318 {
319 _BS_CALL(t, sun68k_bus_peek)(t, h, o, s, vp);
320 }
321
322 __inline__ int
323 _bus_space_poke(t, h, o, s, v)
324 bus_space_tag_t t;
325 bus_space_handle_t h;
326 bus_size_t o;
327 size_t s;
328 u_int32_t v;
329 {
330 _BS_CALL(t, sun68k_bus_poke)(t, h, o, s, v);
331 }
332
333 #if 0
334 int bus_space_alloc __P((bus_space_tag_t t, bus_addr_t rstart,
335 bus_addr_t rend, bus_size_t size, bus_size_t align,
336 bus_size_t boundary, int flags, bus_addr_t *addrp,
337 bus_space_handle_t *bshp));
338 void bus_space_free __P((bus_space_tag_t t, bus_space_handle_t bsh,
339 bus_size_t size));
340 #endif
341
342 /* flags for bus space map functions */
343 #define BUS_SPACE_MAP_CACHEABLE 0x0001
344 #define BUS_SPACE_MAP_LINEAR 0x0002
345 #define BUS_SPACE_MAP_PREFETCHABLE 0x0004
346 #define BUS_SPACE_MAP_BUS1 0x0100 /* placeholders for bus functions... */
347 #define BUS_SPACE_MAP_BUS2 0x0200
348 #define BUS_SPACE_MAP_BUS3 0x0400
349 #define BUS_SPACE_MAP_BUS4 0x0800
350
351 /* Internal flag: try to find and use a PROM maping for the device. */
352 #define _SUN68K_BUS_MAP_USE_PROM BUS_SPACE_MAP_BUS1
353
354 /* flags for intr_establish() */
355 #define BUS_INTR_ESTABLISH_FASTTRAP 1
356 #define BUS_INTR_ESTABLISH_SOFTINTR 2
357
358 /* flags for bus_space_barrier() */
359 #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */
360 #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */
361
362 /*
363 * int bus_space_peek_N(bus_space_tag_t tag,
364 * bus_space_handle_t bsh, bus_size_t offset, u_intN_t *valuep);
365 *
366 * Cautiously read 1, 2, 4 or 8 byte quantity from bus space described
367 * by tag/handle/offset.
368 * If no hardware responds to the read access, the function returns a
369 * non-zero value. Otherwise the value read is placed in `valuep'.
370 */
371
372 #define bus_space_peek_1(t, h, o, vp) \
373 _bus_space_peek(t, h, o, sizeof(u_int8_t), (void *)vp)
374
375 #define bus_space_peek_2(t, h, o, vp) \
376 _bus_space_peek(t, h, o, sizeof(u_int16_t), (void *)vp)
377
378 #define bus_space_peek_4(t, h, o, vp) \
379 _bus_space_peek(t, h, o, sizeof(u_int32_t), (void *)vp)
380
381 /*
382 * int bus_space_poke_N(bus_space_tag_t tag,
383 * bus_space_handle_t bsh, bus_size_t offset, u_intN_t value);
384 *
385 * Cautiously write 1, 2, 4 or 8 byte quantity to bus space described
386 * by tag/handle/offset.
387 * If no hardware responds to the write access, the function returns a
388 * non-zero value.
389 */
390
391 #define bus_space_poke_1(t, h, o, v) \
392 _bus_space_poke(t, h, o, sizeof(u_int8_t), v)
393
394 #define bus_space_poke_2(t, h, o, v) \
395 _bus_space_poke(t, h, o, sizeof(u_int16_t), v)
396
397 #define bus_space_poke_4(t, h, o, v) \
398 _bus_space_poke(t, h, o, sizeof(u_int32_t), v)
399
400 /*
401 * u_intN_t bus_space_read_N __P((bus_space_tag_t tag,
402 * bus_space_handle_t bsh, bus_size_t offset));
403 *
404 * Read a 1, 2, 4, or 8 byte quantity from bus space
405 * described by tag/handle/offset.
406 */
407
408 #define bus_space_read_1(t, h, o) \
409 ((void)t, *(volatile u_int8_t *)((h) + (o)))
410
411 #define bus_space_read_2(t, h, o) \
412 ((void)t, *(volatile u_int16_t *)((h) + (o)))
413
414 #define bus_space_read_4(t, h, o) \
415 ((void)t, *(volatile u_int32_t *)((h) + (o)))
416
417 #define bus_space_read_8(t, h, o) \
418 ((void)t, *(volatile u_int64_t *)((h) + (o)))
419
420
421 /*
422 * void bus_space_write_N __P((bus_space_tag_t tag,
423 * bus_space_handle_t bsh, bus_size_t offset,
424 * u_intN_t value));
425 *
426 * Write the 1, 2, 4, or 8 byte value `value' to bus space
427 * described by tag/handle/offset.
428 */
429
430 #define bus_space_write_1(t, h, o, v) do { \
431 ((void)t, (void)(*(volatile u_int8_t *)((h) + (o)) = (v))); \
432 } while (0)
433
434 #define bus_space_write_2(t, h, o, v) do { \
435 ((void)t, (void)(*(volatile u_int16_t *)((h) + (o)) = (v))); \
436 } while (0)
437
438 #define bus_space_write_4(t, h, o, v) do { \
439 ((void)t, (void)(*(volatile u_int32_t *)((h) + (o)) = (v))); \
440 } while (0)
441
442 #define bus_space_write_8(t, h, o, v) do { \
443 ((void)t, (void)(*(volatile u_int64_t *)((h) + (o)) = (v))); \
444 } while (0)
445
446
447 /*
448 * void bus_space_read_multi_N __P((bus_space_tag_t tag,
449 * bus_space_handle_t bsh, bus_size_t offset,
450 * u_intN_t *addr, bus_size_t count));
451 *
452 * Read `count' 1, 2, 4, or 8 byte quantities from bus space
453 * described by tag/handle/offset and copy into buffer provided.
454 */
455
456 void bus_space_read_multi_1 __P((bus_space_tag_t,
457 bus_space_handle_t,
458 bus_size_t,
459 u_int8_t *,
460 bus_size_t));
461
462 void bus_space_read_multi_2 __P((bus_space_tag_t,
463 bus_space_handle_t,
464 bus_size_t,
465 u_int16_t *,
466 bus_size_t));
467
468 void bus_space_read_multi_4 __P((bus_space_tag_t,
469 bus_space_handle_t,
470 bus_size_t,
471 u_int32_t *,
472 bus_size_t));
473
474 void bus_space_read_multi_8 __P((bus_space_tag_t,
475 bus_space_handle_t,
476 bus_size_t,
477 u_int64_t *,
478 bus_size_t));
479
480 extern __inline__ void
481 bus_space_read_multi_1(t, h, o, a, c)
482 bus_space_tag_t t;
483 bus_space_handle_t h;
484 bus_size_t o, c;
485 u_int8_t *a;
486 {
487 while (c-- > 0)
488 *a++ = bus_space_read_1(t, h, o);
489 }
490
491 extern __inline__ void
492 bus_space_read_multi_2(t, h, o, a, c)
493 bus_space_tag_t t;
494 bus_space_handle_t h;
495 bus_size_t o, c;
496 u_int16_t *a;
497 {
498 while (c-- > 0)
499 *a++ = bus_space_read_2(t, h, o);
500 }
501
502 extern __inline__ void
503 bus_space_read_multi_4(t, h, o, a, c)
504 bus_space_tag_t t;
505 bus_space_handle_t h;
506 bus_size_t o, c;
507 u_int32_t *a;
508 {
509 while (c-- > 0)
510 *a++ = bus_space_read_4(t, h, o);
511 }
512
513 extern __inline__ void
514 bus_space_read_multi_8(t, h, o, a, c)
515 bus_space_tag_t t;
516 bus_space_handle_t h;
517 bus_size_t o, c;
518 u_int64_t *a;
519 {
520 while (c-- > 0)
521 *a++ = bus_space_read_8(t, h, o);
522 }
523
524
525 /*
526 * void bus_space_write_multi_N __P((bus_space_tag_t tag,
527 * bus_space_handle_t bsh, bus_size_t offset,
528 * const u_intN_t *addr, bus_size_t count));
529 *
530 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
531 * provided to bus space described by tag/handle/offset.
532 */
533 void bus_space_write_multi_1 __P((bus_space_tag_t,
534 bus_space_handle_t,
535 bus_size_t,
536 const u_int8_t *,
537 bus_size_t));
538 void bus_space_write_multi_2 __P((bus_space_tag_t,
539 bus_space_handle_t,
540 bus_size_t,
541 const u_int16_t *,
542 bus_size_t));
543 void bus_space_write_multi_4 __P((bus_space_tag_t,
544 bus_space_handle_t,
545 bus_size_t,
546 const u_int32_t *,
547 bus_size_t));
548 void bus_space_write_multi_8 __P((bus_space_tag_t,
549 bus_space_handle_t,
550 bus_size_t,
551 const u_int64_t *,
552 bus_size_t));
553 extern __inline__ void
554 bus_space_write_multi_1(t, h, o, a, c)
555 bus_space_tag_t t;
556 bus_space_handle_t h;
557 bus_size_t o, c;
558 const u_int8_t *a;
559 {
560 while (c-- > 0)
561 bus_space_write_1(t, h, o, *a++);
562 }
563
564 extern __inline__ void
565 bus_space_write_multi_2(t, h, o, a, c)
566 bus_space_tag_t t;
567 bus_space_handle_t h;
568 bus_size_t o, c;
569 const u_int16_t *a;
570 {
571 while (c-- > 0)
572 bus_space_write_2(t, h, o, *a++);
573 }
574
575 extern __inline__ void
576 bus_space_write_multi_4(t, h, o, a, c)
577 bus_space_tag_t t;
578 bus_space_handle_t h;
579 bus_size_t o, c;
580 const u_int32_t *a;
581 {
582 while (c-- > 0)
583 bus_space_write_4(t, h, o, *a++);
584 }
585
586 extern __inline__ void
587 bus_space_write_multi_8(t, h, o, a, c)
588 bus_space_tag_t t;
589 bus_space_handle_t h;
590 bus_size_t o, c;
591 const u_int64_t *a;
592 {
593 while (c-- > 0)
594 bus_space_write_8(t, h, o, *a++);
595 }
596
597 /*
598 * void bus_space_set_multi_N __P((bus_space_tag_t tag,
599 * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
600 * bus_size_t count));
601 *
602 * Write the 1, 2, 4, or 8 byte value `val' to bus space described
603 * by tag/handle/offset `count' times.
604 */
605 void bus_space_set_multi_1 __P((bus_space_tag_t,
606 bus_space_handle_t,
607 bus_size_t,
608 const u_int8_t,
609 bus_size_t));
610 void bus_space_set_multi_2 __P((bus_space_tag_t,
611 bus_space_handle_t,
612 bus_size_t,
613 const u_int16_t,
614 bus_size_t));
615 void bus_space_set_multi_4 __P((bus_space_tag_t,
616 bus_space_handle_t,
617 bus_size_t,
618 const u_int32_t,
619 bus_size_t));
620 void bus_space_set_multi_8 __P((bus_space_tag_t,
621 bus_space_handle_t,
622 bus_size_t,
623 const u_int64_t,
624 bus_size_t));
625
626 extern __inline__ void
627 bus_space_set_multi_1(t, h, o, v, c)
628 bus_space_tag_t t;
629 bus_space_handle_t h;
630 bus_size_t o, c;
631 const u_int8_t v;
632 {
633 while (c-- > 0)
634 bus_space_write_1(t, h, o, v);
635 }
636
637 extern __inline__ void
638 bus_space_set_multi_2(t, h, o, v, c)
639 bus_space_tag_t t;
640 bus_space_handle_t h;
641 bus_size_t o, c;
642 const u_int16_t v;
643 {
644 while (c-- > 0)
645 bus_space_write_2(t, h, o, v);
646 }
647
648 extern __inline__ void
649 bus_space_set_multi_4(t, h, o, v, c)
650 bus_space_tag_t t;
651 bus_space_handle_t h;
652 bus_size_t o, c;
653 const u_int32_t v;
654 {
655 while (c-- > 0)
656 bus_space_write_4(t, h, o, v);
657 }
658
659 extern __inline__ void
660 bus_space_set_multi_8(t, h, o, v, c)
661 bus_space_tag_t t;
662 bus_space_handle_t h;
663 bus_size_t o, c;
664 const u_int64_t v;
665 {
666 while (c-- > 0)
667 bus_space_write_8(t, h, o, v);
668 }
669
670
671 /*
672 * void bus_space_read_region_N __P((bus_space_tag_t tag,
673 * bus_space_handle_t bsh, bus_size_t off,
674 * u_intN_t *addr, bus_size_t count));
675 *
676 */
677 void bus_space_read_region_1 __P((bus_space_tag_t,
678 bus_space_handle_t,
679 bus_size_t,
680 u_int8_t *,
681 bus_size_t));
682 void bus_space_read_region_2 __P((bus_space_tag_t,
683 bus_space_handle_t,
684 bus_size_t,
685 u_int16_t *,
686 bus_size_t));
687 void bus_space_read_region_4 __P((bus_space_tag_t,
688 bus_space_handle_t,
689 bus_size_t,
690 u_int32_t *,
691 bus_size_t));
692 void bus_space_read_region_8 __P((bus_space_tag_t,
693 bus_space_handle_t,
694 bus_size_t,
695 u_int64_t *,
696 bus_size_t));
697
698 extern __inline__ void
699 bus_space_read_region_1(t, h, o, a, c)
700 bus_space_tag_t t;
701 bus_space_handle_t h;
702 bus_size_t o, c;
703 u_int8_t *a;
704 {
705 for (; c; a++, c--, o++)
706 *a = bus_space_read_1(t, h, o);
707 }
708 extern __inline__ void
709 bus_space_read_region_2(t, h, o, a, c)
710 bus_space_tag_t t;
711 bus_space_handle_t h;
712 bus_size_t o, c;
713 u_int16_t *a;
714 {
715 for (; c; a++, c--, o+=2)
716 *a = bus_space_read_2(t, h, o);
717 }
718 extern __inline__ void
719 bus_space_read_region_4(t, h, o, a, c)
720 bus_space_tag_t t;
721 bus_space_handle_t h;
722 bus_size_t o, c;
723 u_int32_t *a;
724 {
725 for (; c; a++, c--, o+=4)
726 *a = bus_space_read_4(t, h, o);
727 }
728 extern __inline__ void
729 bus_space_read_region_8(t, h, o, a, c)
730 bus_space_tag_t t;
731 bus_space_handle_t h;
732 bus_size_t o, c;
733 u_int64_t *a;
734 {
735 for (; c; a++, c--, o+=8)
736 *a = bus_space_read_8(t, h, o);
737 }
738
739 /*
740 * void bus_space_write_region_N __P((bus_space_tag_t tag,
741 * bus_space_handle_t bsh, bus_size_t off,
742 * u_intN_t *addr, bus_size_t count));
743 *
744 */
745 void bus_space_write_region_1 __P((bus_space_tag_t,
746 bus_space_handle_t,
747 bus_size_t,
748 const u_int8_t *,
749 bus_size_t));
750 void bus_space_write_region_2 __P((bus_space_tag_t,
751 bus_space_handle_t,
752 bus_size_t,
753 const u_int16_t *,
754 bus_size_t));
755 void bus_space_write_region_4 __P((bus_space_tag_t,
756 bus_space_handle_t,
757 bus_size_t,
758 const u_int32_t *,
759 bus_size_t));
760 void bus_space_write_region_8 __P((bus_space_tag_t,
761 bus_space_handle_t,
762 bus_size_t,
763 const u_int64_t *,
764 bus_size_t));
765 extern __inline__ void
766 bus_space_write_region_1(t, h, o, a, c)
767 bus_space_tag_t t;
768 bus_space_handle_t h;
769 bus_size_t o, c;
770 const u_int8_t *a;
771 {
772 for (; c; a++, c--, o++)
773 bus_space_write_1(t, h, o, *a);
774 }
775
776 extern __inline__ void
777 bus_space_write_region_2(t, h, o, a, c)
778 bus_space_tag_t t;
779 bus_space_handle_t h;
780 bus_size_t o, c;
781 const u_int16_t *a;
782 {
783 for (; c; a++, c--, o+=2)
784 bus_space_write_2(t, h, o, *a);
785 }
786
787 extern __inline__ void
788 bus_space_write_region_4(t, h, o, a, c)
789 bus_space_tag_t t;
790 bus_space_handle_t h;
791 bus_size_t o, c;
792 const u_int32_t *a;
793 {
794 for (; c; a++, c--, o+=4)
795 bus_space_write_4(t, h, o, *a);
796 }
797
798 extern __inline__ void
799 bus_space_write_region_8(t, h, o, a, c)
800 bus_space_tag_t t;
801 bus_space_handle_t h;
802 bus_size_t o, c;
803 const u_int64_t *a;
804 {
805 for (; c; a++, c--, o+=8)
806 bus_space_write_8(t, h, o, *a);
807 }
808
809
810 /*
811 * void bus_space_set_region_N __P((bus_space_tag_t tag,
812 * bus_space_handle_t bsh, bus_size_t off,
813 * u_intN_t *addr, bus_size_t count));
814 *
815 */
816 void bus_space_set_region_1 __P((bus_space_tag_t,
817 bus_space_handle_t,
818 bus_size_t,
819 const u_int8_t,
820 bus_size_t));
821 void bus_space_set_region_2 __P((bus_space_tag_t,
822 bus_space_handle_t,
823 bus_size_t,
824 const u_int16_t,
825 bus_size_t));
826 void bus_space_set_region_4 __P((bus_space_tag_t,
827 bus_space_handle_t,
828 bus_size_t,
829 const u_int32_t,
830 bus_size_t));
831 void bus_space_set_region_8 __P((bus_space_tag_t,
832 bus_space_handle_t,
833 bus_size_t,
834 const u_int64_t,
835 bus_size_t));
836
837 extern __inline__ void
838 bus_space_set_region_1(t, h, o, v, c)
839 bus_space_tag_t t;
840 bus_space_handle_t h;
841 bus_size_t o, c;
842 const u_int8_t v;
843 {
844 for (; c; c--, o++)
845 bus_space_write_1(t, h, o, v);
846 }
847
848 extern __inline__ void
849 bus_space_set_region_2(t, h, o, v, c)
850 bus_space_tag_t t;
851 bus_space_handle_t h;
852 bus_size_t o, c;
853 const u_int16_t v;
854 {
855 for (; c; c--, o+=2)
856 bus_space_write_2(t, h, o, v);
857 }
858
859 extern __inline__ void
860 bus_space_set_region_4(t, h, o, v, c)
861 bus_space_tag_t t;
862 bus_space_handle_t h;
863 bus_size_t o, c;
864 const u_int32_t v;
865 {
866 for (; c; c--, o+=4)
867 bus_space_write_4(t, h, o, v);
868 }
869
870 extern __inline__ void
871 bus_space_set_region_8(t, h, o, v, c)
872 bus_space_tag_t t;
873 bus_space_handle_t h;
874 bus_size_t o, c;
875 const u_int64_t v;
876 {
877 for (; c; c--, o+=8)
878 bus_space_write_8(t, h, o, v);
879 }
880
881
882 /*
883 * void bus_space_copy_region_N __P((bus_space_tag_t tag,
884 * bus_space_handle_t bsh1, bus_size_t off1,
885 * bus_space_handle_t bsh2, bus_size_t off2,
886 * bus_size_t count));
887 *
888 * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
889 * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
890 */
891 void bus_space_copy_region_1 __P((bus_space_tag_t,
892 bus_space_handle_t,
893 bus_size_t,
894 bus_space_handle_t,
895 bus_size_t,
896 bus_size_t));
897 void bus_space_copy_region_2 __P((bus_space_tag_t,
898 bus_space_handle_t,
899 bus_size_t,
900 bus_space_handle_t,
901 bus_size_t,
902 bus_size_t));
903 void bus_space_copy_region_4 __P((bus_space_tag_t,
904 bus_space_handle_t,
905 bus_size_t,
906 bus_space_handle_t,
907 bus_size_t,
908 bus_size_t));
909 void bus_space_copy_region_8 __P((bus_space_tag_t,
910 bus_space_handle_t,
911 bus_size_t,
912 bus_space_handle_t,
913 bus_size_t,
914 bus_size_t));
915
916
917 extern __inline__ void
918 bus_space_copy_region_1(t, h1, o1, h2, o2, c)
919 bus_space_tag_t t;
920 bus_space_handle_t h1, h2;
921 bus_size_t o1, o2;
922 bus_size_t c;
923 {
924 for (; c; c--, o1++, o2++)
925 bus_space_write_1(t, h1, o1, bus_space_read_1(t, h2, o2));
926 }
927
928 extern __inline__ void
929 bus_space_copy_region_2(t, h1, o1, h2, o2, c)
930 bus_space_tag_t t;
931 bus_space_handle_t h1, h2;
932 bus_size_t o1, o2;
933 bus_size_t c;
934 {
935 for (; c; c--, o1+=2, o2+=2)
936 bus_space_write_2(t, h1, o1, bus_space_read_2(t, h2, o2));
937 }
938
939 extern __inline__ void
940 bus_space_copy_region_4(t, h1, o1, h2, o2, c)
941 bus_space_tag_t t;
942 bus_space_handle_t h1, h2;
943 bus_size_t o1, o2;
944 bus_size_t c;
945 {
946 for (; c; c--, o1+=4, o2+=4)
947 bus_space_write_4(t, h1, o1, bus_space_read_4(t, h2, o2));
948 }
949
950 extern __inline__ void
951 bus_space_copy_region_8(t, h1, o1, h2, o2, c)
952 bus_space_tag_t t;
953 bus_space_handle_t h1, h2;
954 bus_size_t o1, o2;
955 bus_size_t c;
956 {
957 for (; c; c--, o1+=8, o2+=8)
958 bus_space_write_8(t, h1, o1, bus_space_read_8(t, h2, o2));
959 }
960
961 /*
962 * void bus_space_copyin __P((bus_space_tag_t tag,
963 * bus_space_handle_t bsh, bus_size_t off,
964 * void *addr, bus_size_t count));
965 *
966 * Copy `count' bytes from bus space starting at tag/bsh/off
967 * to kernel memory at addr using the most optimized transfer
968 * possible for the bus.
969 */
970
971 #define bus_space_copyin(t, h, o, a, c) \
972 ((void)t, w16copy((u_int8_t *)((h) + (o)), (a), (c)))
973
974 /*
975 * void bus_space_copyout __P((bus_space_tag_t tag,
976 * bus_space_handle_t bsh, bus_size_t off,
977 * const void *addr, bus_size_t count));
978 *
979 * Copy `count' bytes to bus space starting at tag/bsh/off
980 * from kernel memory at addr using the most optimized transfer
981 * possible for the bus.
982 */
983
984 #define bus_space_copyout(t, h, o, a, c) \
985 ((void)t, w16copy((a), (u_int8_t *)((h) + (o)), (c)))
986
987 #define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t)
988
989 /*--------------------------------*/
990
991 /*
992 * Flags used in various bus DMA methods.
993 */
994 #define BUS_DMA_WAITOK 0x00 /* safe to sleep (pseudo-flag) */
995 #define BUS_DMA_NOWAIT 0x01 /* not safe to sleep */
996 #define BUS_DMA_ALLOCNOW 0x02 /* perform resource allocation now */
997 #define BUS_DMA_COHERENT 0x04 /* hint: map memory DMA coherent */
998 #define BUS_DMA_BUS1 0x10 /* placeholders for bus functions... */
999 #define BUS_DMA_BUS2 0x20
1000 #define BUS_DMA_BUS3 0x40
1001 #define BUS_DMA_BUS4 0x80
1002
1003 /* For devices that have a 24-bit address space */
1004 #define BUS_DMA_24BIT BUS_DMA_BUS1
1005
1006 /* Internal flag: current DVMA address is equal to the KVA buffer address */
1007 #define _BUS_DMA_DIRECTMAP BUS_DMA_BUS2
1008
1009 /*
1010 * Internal flag: current DVMA address has been double-mapped by hand
1011 * to the KVA buffer address (without the pmap's help).
1012 */
1013 #define _BUS_DMA_NOPMAP BUS_DMA_BUS3
1014
1015 /* Forwards needed by prototypes below. */
1016 struct mbuf;
1017 struct uio;
1018
1019 /*
1020 * Operations performed by bus_dmamap_sync().
1021 */
1022 #define BUS_DMASYNC_PREREAD 0x01 /* pre-read synchronization */
1023 #define BUS_DMASYNC_POSTREAD 0x02 /* post-read synchronization */
1024 #define BUS_DMASYNC_PREWRITE 0x04 /* pre-write synchronization */
1025 #define BUS_DMASYNC_POSTWRITE 0x08 /* post-write synchronization */
1026
1027 typedef struct sun68k_bus_dma_tag *bus_dma_tag_t;
1028 typedef struct sun68k_bus_dmamap *bus_dmamap_t;
1029
1030 /*
1031 * bus_dma_segment_t
1032 *
1033 * Describes a single contiguous DMA transaction. Values
1034 * are suitable for programming into DMA registers.
1035 */
1036 struct sun68k_bus_dma_segment {
1037 bus_addr_t ds_addr; /* DVMA address */
1038 bus_size_t ds_len; /* length of transfer */
1039 bus_size_t _ds_sgsize; /* size of allocated DVMA segment */
1040 void *_ds_mlist; /* page list when dmamem_alloc'ed */
1041 vaddr_t _ds_va; /* VA when dmamem_map'ed */
1042 };
1043 typedef struct sun68k_bus_dma_segment bus_dma_segment_t;
1044
1045
1046 /*
1047 * bus_dma_tag_t
1048 *
1049 * A machine-dependent opaque type describing the implementation of
1050 * DMA for a given bus.
1051 */
1052 struct sun68k_bus_dma_tag {
1053 void *_cookie; /* cookie used in the guts */
1054
1055 /*
1056 * DMA mapping methods.
1057 */
1058 int (*_dmamap_create) __P((bus_dma_tag_t, bus_size_t, int,
1059 bus_size_t, bus_size_t, int, bus_dmamap_t *));
1060 void (*_dmamap_destroy) __P((bus_dma_tag_t, bus_dmamap_t));
1061 int (*_dmamap_load) __P((bus_dma_tag_t, bus_dmamap_t, void *,
1062 bus_size_t, struct proc *, int));
1063 int (*_dmamap_load_mbuf) __P((bus_dma_tag_t, bus_dmamap_t,
1064 struct mbuf *, int));
1065 int (*_dmamap_load_uio) __P((bus_dma_tag_t, bus_dmamap_t,
1066 struct uio *, int));
1067 int (*_dmamap_load_raw) __P((bus_dma_tag_t, bus_dmamap_t,
1068 bus_dma_segment_t *, int, bus_size_t, int));
1069 void (*_dmamap_unload) __P((bus_dma_tag_t, bus_dmamap_t));
1070 void (*_dmamap_sync) __P((bus_dma_tag_t, bus_dmamap_t,
1071 bus_addr_t, bus_size_t, int));
1072
1073 /*
1074 * DMA memory utility functions.
1075 */
1076 int (*_dmamem_alloc) __P((bus_dma_tag_t, bus_size_t, bus_size_t,
1077 bus_size_t, bus_dma_segment_t *, int, int *, int));
1078 void (*_dmamem_free) __P((bus_dma_tag_t,
1079 bus_dma_segment_t *, int));
1080 int (*_dmamem_map) __P((bus_dma_tag_t, bus_dma_segment_t *,
1081 int, size_t, caddr_t *, int));
1082 void (*_dmamem_unmap) __P((bus_dma_tag_t, caddr_t, size_t));
1083 paddr_t (*_dmamem_mmap) __P((bus_dma_tag_t, bus_dma_segment_t *,
1084 int, off_t, int, int));
1085 };
1086
1087 #define bus_dmamap_create(t, s, n, m, b, f, p) \
1088 (*(t)->_dmamap_create)((t), (s), (n), (m), (b), (f), (p))
1089 #define bus_dmamap_destroy(t, p) \
1090 (*(t)->_dmamap_destroy)((t), (p))
1091 #define bus_dmamap_load(t, m, b, s, p, f) \
1092 (*(t)->_dmamap_load)((t), (m), (b), (s), (p), (f))
1093 #define bus_dmamap_load_mbuf(t, m, b, f) \
1094 (*(t)->_dmamap_load_mbuf)((t), (m), (b), (f))
1095 #define bus_dmamap_load_uio(t, m, u, f) \
1096 (*(t)->_dmamap_load_uio)((t), (m), (u), (f))
1097 #define bus_dmamap_load_raw(t, m, sg, n, s, f) \
1098 (*(t)->_dmamap_load_raw)((t), (m), (sg), (n), (s), (f))
1099 #define bus_dmamap_unload(t, p) \
1100 (*(t)->_dmamap_unload)((t), (p))
1101 #define bus_dmamap_sync(t, p, o, l, ops) \
1102 (void)((t)->_dmamap_sync ? \
1103 (*(t)->_dmamap_sync)((t), (p), (o), (l), (ops)) : (void)0)
1104
1105 #define bus_dmamem_alloc(t, s, a, b, sg, n, r, f) \
1106 (*(t)->_dmamem_alloc)((t), (s), (a), (b), (sg), (n), (r), (f))
1107 #define bus_dmamem_free(t, sg, n) \
1108 (*(t)->_dmamem_free)((t), (sg), (n))
1109 #define bus_dmamem_map(t, sg, n, s, k, f) \
1110 (*(t)->_dmamem_map)((t), (sg), (n), (s), (k), (f))
1111 #define bus_dmamem_unmap(t, k, s) \
1112 (*(t)->_dmamem_unmap)((t), (k), (s))
1113 #define bus_dmamem_mmap(t, sg, n, o, p, f) \
1114 (*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
1115
1116 /*
1117 * bus_dmamap_t
1118 *
1119 * Describes a DMA mapping.
1120 */
1121 struct sun68k_bus_dmamap {
1122 /*
1123 * PRIVATE MEMBERS: not for use by machine-independent code.
1124 */
1125 bus_size_t _dm_size; /* largest DMA transfer mappable */
1126 int _dm_segcnt; /* number of segs this map can map */
1127 bus_size_t _dm_maxsegsz; /* largest possible segment */
1128 bus_size_t _dm_boundary; /* don't cross this */
1129 int _dm_flags; /* misc. flags */
1130
1131 void *_dm_cookie; /* cookie for bus-specific functions */
1132
1133 u_long _dm_align; /* DVMA alignment; must be a
1134 multiple of the page size */
1135 u_long _dm_ex_start; /* constraints on DVMA map */
1136 u_long _dm_ex_end; /* allocations; used by the VME bus
1137 driver and by the IOMMU driver
1138 when mapping 24-bit devices */
1139
1140 /*
1141 * PUBLIC MEMBERS: these are used by machine-independent code.
1142 */
1143 bus_size_t dm_mapsize; /* size of the mapping */
1144 int dm_nsegs; /* # valid segments in mapping */
1145 bus_dma_segment_t dm_segs[1]; /* segments; variable length */
1146 };
1147
1148 #ifdef _SUN68K_BUS_DMA_PRIVATE
1149 int _bus_dmamap_create __P((bus_dma_tag_t, bus_size_t, int, bus_size_t,
1150 bus_size_t, int, bus_dmamap_t *));
1151 void _bus_dmamap_destroy __P((bus_dma_tag_t, bus_dmamap_t));
1152 int _bus_dmamap_load_mbuf __P((bus_dma_tag_t, bus_dmamap_t,
1153 struct mbuf *, int));
1154 int _bus_dmamap_load_uio __P((bus_dma_tag_t, bus_dmamap_t,
1155 struct uio *, int));
1156 int _bus_dmamap_load_raw __P((bus_dma_tag_t, bus_dmamap_t,
1157 bus_dma_segment_t *, int, bus_size_t, int));
1158 int _bus_dmamap_load __P((bus_dma_tag_t, bus_dmamap_t, void *,
1159 bus_size_t, struct proc *, int));
1160 void _bus_dmamap_unload __P((bus_dma_tag_t, bus_dmamap_t));
1161 void _bus_dmamap_sync __P((bus_dma_tag_t, bus_dmamap_t, bus_addr_t,
1162 bus_size_t, int));
1163
1164 int _bus_dmamem_alloc __P((bus_dma_tag_t tag, bus_size_t size,
1165 bus_size_t alignment, bus_size_t boundary,
1166 bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags));
1167 void _bus_dmamem_free __P((bus_dma_tag_t tag, bus_dma_segment_t *segs,
1168 int nsegs));
1169 int _bus_dmamem_map __P((bus_dma_tag_t tag, bus_dma_segment_t *segs,
1170 int nsegs, size_t size, caddr_t *kvap,
1171 int flags));
1172 void _bus_dmamem_unmap __P((bus_dma_tag_t tag, caddr_t kva,
1173 size_t size));
1174 paddr_t _bus_dmamem_mmap __P((bus_dma_tag_t tag, bus_dma_segment_t *segs,
1175 int nsegs, off_t off, int prot, int flags));
1176
1177 int _bus_dmamem_alloc_range __P((bus_dma_tag_t tag, bus_size_t size,
1178 bus_size_t alignment, bus_size_t boundary,
1179 bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags,
1180 vaddr_t low, vaddr_t high));
1181
1182 vaddr_t _bus_dma_valloc_skewed(size_t, u_long, u_long, u_long);
1183 #endif /* _SUN68K_BUS_DMA_PRIVATE */
1184
1185 #endif /* _SUN68K_BUS_H_ */
1186