1 /* $NetBSD: bus.h,v 1.55 2009/04/16 16:55:00 macallan Exp $ */
4 * Copyright (c) 1996, 1997, 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 * Copyright (c) 1996 Charles M. Hannum. All rights reserved.
35 * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions
40 * 1. Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in the
44 * documentation and/or other materials provided with the distribution.
45 * 3. All advertising materials mentioning features or use of this software
46 * must display the following acknowledgement:
47 * This product includes software developed by Christopher G. Demetriou
48 * for the NetBSD Project.
49 * 4. The name of the author may not be used to endorse or promote products
50 * derived from this software without specific prior written permission
52 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
53 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
54 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
55 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
56 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
57 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
58 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
59 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
60 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
61 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
67 #define SPARC_BUS_SPACE 0
70 * Bus address and size types
72 typedef u_long bus_space_handle_t
;
73 typedef uint64_t bus_addr_t
;
74 typedef u_long bus_size_t
;
76 /* bus_addr_t is extended to 64-bits and has the iospace encoded in it */
77 #define BUS_ADDR_IOSPACE(x) ((x)>>32)
78 #define BUS_ADDR_PADDR(x) ((x)&0xffffffff)
79 #define BUS_ADDR(io, pa) \
80 ((((uint64_t)(uint32_t)(io))<<32) | (uint32_t)(pa))
82 #define __BUS_SPACE_HAS_STREAM_METHODS 1
85 * Access methods for bus resources and address space.
87 typedef struct sparc_bus_space_tag
*bus_space_tag_t
;
89 struct sparc_bus_space_tag
{
91 bus_space_tag_t parent
;
94 * Windows onto the parent bus that this tag maps. If ranges
95 * is non-NULL, the address will be translated, and recursively
96 * mapped via the parent tag.
98 struct openprom_range
*ranges
;
101 int (*sparc_bus_map
)(
106 vaddr_t
, /*preferred vaddr*/
107 bus_space_handle_t
*);
108 int (*sparc_bus_unmap
)(
112 int (*sparc_bus_subregion
)(
115 bus_size_t
, /*offset*/
117 bus_space_handle_t
*);
119 void (*sparc_bus_barrier
)(
122 bus_size_t
, /*offset*/
126 paddr_t (*sparc_bus_mmap
)(
133 void *(*sparc_intr_establish
)(
135 int, /*bus-specific intr*/
136 int, /*device class level,
138 int (*)(void *), /*handler*/
139 void *, /*handler arg*/
140 void (*)(void)); /*optional fast vector*/
142 uint8_t (*sparc_read_1
)(
143 bus_space_tag_t space
,
144 bus_space_handle_t handle
,
147 uint16_t (*sparc_read_2
)(
148 bus_space_tag_t space
,
149 bus_space_handle_t handle
,
152 uint32_t (*sparc_read_4
)(
153 bus_space_tag_t space
,
154 bus_space_handle_t handle
,
157 uint64_t (*sparc_read_8
)(
158 bus_space_tag_t space
,
159 bus_space_handle_t handle
,
162 void (*sparc_write_1
)(
163 bus_space_tag_t space
,
164 bus_space_handle_t handle
,
168 void (*sparc_write_2
)(
169 bus_space_tag_t space
,
170 bus_space_handle_t handle
,
174 void (*sparc_write_4
)(
175 bus_space_tag_t space
,
176 bus_space_handle_t handle
,
180 void (*sparc_write_8
)(
181 bus_space_tag_t space
,
182 bus_space_handle_t handle
,
187 bus_space_tag_t
bus_space_tag_alloc(bus_space_tag_t
, void *);
188 int bus_space_translate_address_generic(struct openprom_range
*,
192 * Bus space function prototypes.
193 * In bus_space_map2(), supply a special virtual address only if you
194 * get it from ../sparc/vaddrs.h.
196 static int bus_space_map(
201 bus_space_handle_t
*);
202 static int bus_space_map2(
207 vaddr_t
, /*preferred vaddr*/
208 bus_space_handle_t
*);
209 static int bus_space_unmap(
213 static int bus_space_subregion(
218 bus_space_handle_t
*);
219 static void bus_space_barrier(
225 static paddr_t
bus_space_mmap(
231 static void *bus_intr_establish(
233 int, /*bus-specific intr*/
234 int, /*device class level,
236 int (*)(void *), /*handler*/
237 void *); /*handler arg*/
238 static void *bus_intr_establish2(
240 int, /*bus-specific intr*/
241 int, /*device class level,
243 int (*)(void *), /*handler*/
244 void *, /*handler arg*/
245 void (*)(void)); /*optional fast vector*/
250 bus_space_map(t
, a
, s
, f
, hp
)
255 bus_space_handle_t
*hp
;
257 return (*t
->sparc_bus_map
)(t
, a
, s
, f
, (vaddr_t
)0, hp
);
261 bus_space_map2(t
, a
, s
, f
, v
, hp
)
267 bus_space_handle_t
*hp
;
269 return (*t
->sparc_bus_map
)(t
, a
, s
, f
, v
, hp
);
273 bus_space_unmap(t
, h
, s
)
275 bus_space_handle_t h
;
278 return (*t
->sparc_bus_unmap
)(t
, h
, s
);
282 bus_space_subregion(t
, h
, o
, s
, hp
)
284 bus_space_handle_t h
;
287 bus_space_handle_t
*hp
;
289 return (*t
->sparc_bus_subregion
)(t
, h
, o
, s
, hp
);
292 static __inline paddr_t
293 bus_space_mmap(t
, a
, o
, p
, f
)
300 return (*t
->sparc_bus_mmap
)(t
, a
, o
, p
, f
);
303 static __inline
void *
304 bus_intr_establish(t
, p
, l
, h
, a
)
311 return (*t
->sparc_intr_establish
)(t
, p
, l
, h
, a
, NULL
);
314 static __inline
void *
315 bus_intr_establish2(t
, p
, l
, h
, a
, v
)
323 return (*t
->sparc_intr_establish
)(t
, p
, l
, h
, a
, v
);
327 bus_space_barrier(t
, h
, o
, s
, f
)
329 bus_space_handle_t h
;
334 (*t
->sparc_bus_barrier
)(t
, h
, o
, s
, f
);
339 int bus_space_alloc(bus_space_tag_t t
, bus_addr_t rstart
,
340 bus_addr_t rend
, bus_size_t size
, bus_size_t align
,
341 bus_size_t boundary
, int flags
, bus_addr_t
*addrp
,
342 bus_space_handle_t
*bshp
);
343 void bus_space_free(bus_space_tag_t t
, bus_space_handle_t bsh
,
347 #define bus_space_vaddr(t, h) ((void)(t), (void *)(h))
349 /* flags for bus space map functions */
350 #define BUS_SPACE_MAP_CACHEABLE 0x0001
351 #define BUS_SPACE_MAP_LINEAR 0x0002
352 #define BUS_SPACE_MAP_PREFETCHABLE 0x0004
353 #define BUS_SPACE_MAP_BUS1 0x0100 /* placeholders for bus functions... */
354 #define BUS_SPACE_MAP_BUS2 0x0200
355 #define BUS_SPACE_MAP_BUS3 0x0400
356 #define BUS_SPACE_MAP_LARGE 0x0800 /* map outside IODEV range */
359 /* flags for bus_space_barrier() */
360 #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */
361 #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */
364 * Device space probe assistant.
365 * The optional callback function's arguments are:
366 * the temporary virtual address
367 * the passed `arg' argument
372 bus_size_t
, /* probe size */
375 int (*)(void *, void *), /* callback function */
376 void *); /* callback arg */
380 * u_intN_t bus_space_read_N(bus_space_tag_t tag,
381 * bus_space_handle_t bsh, bus_size_t offset);
383 * Read a 1, 2, 4, or 8 byte quantity from bus space
384 * described by tag/handle/offset.
387 #define bus_space_read_1_real(t, h, o) \
388 ((void)(t), *(volatile uint8_t *)((h) + (o)))
390 #define bus_space_read_2_real(t, h, o) \
391 ((void)(t), *(volatile uint16_t *)((h) + (o)))
393 #define bus_space_read_4_real(t, h, o) \
394 ((void)(t), *(volatile uint32_t *)((h) + (o)))
396 #define bus_space_read_8_real(t, h, o) \
397 ((void)(t), *(volatile uint64_t *)((h) + (o)))
401 static uint8_t bus_space_read_1(bus_space_tag_t
,
404 static uint16_t bus_space_read_2(bus_space_tag_t
,
407 static uint32_t bus_space_read_4(bus_space_tag_t
,
410 static uint64_t bus_space_read_8(bus_space_tag_t
,
414 static __inline
uint8_t
415 bus_space_read_1(t
, h
, o
)
417 bus_space_handle_t h
;
420 return (*t
->sparc_read_1
)(t
, h
, o
);
423 static __inline
uint16_t
424 bus_space_read_2(t
, h
, o
)
426 bus_space_handle_t h
;
429 return (*t
->sparc_read_2
)(t
, h
, o
);
432 static __inline
uint32_t
433 bus_space_read_4(t
, h
, o
)
435 bus_space_handle_t h
;
438 return (*t
->sparc_read_4
)(t
, h
, o
);
441 static __inline
uint64_t
442 bus_space_read_8(t
, h
, o
)
444 bus_space_handle_t h
;
447 return (*t
->sparc_read_8
)(t
, h
, o
);
450 #if __SLIM_SPARC_BUS_SPACE
451 static __inline
uint8_t
452 bus_space_read_1(t
, h
, o
)
454 bus_space_handle_t h
;
458 return bus_space_read_1_real(t
, h
, o
);
461 static __inline
uint16_t
462 bus_space_read_2(t
, h
, o
)
464 bus_space_handle_t h
;
468 return bus_space_read_2_real(t
, h
, o
);
471 static __inline
uint32_t
472 bus_space_read_4(t
, h
, o
)
474 bus_space_handle_t h
;
478 return bus_space_read_4_real(t
, h
, o
);
481 static __inline
uint64_t
482 bus_space_read_8(t
, h
, o
)
484 bus_space_handle_t h
;
488 return bus_space_read_8_real(t
, h
, o
);
491 #endif /* __SLIM_SPARC_BUS_SPACE */
493 #define bus_space_read_stream_1 bus_space_read_1_real
494 #define bus_space_read_stream_2 bus_space_read_2_real
495 #define bus_space_read_stream_4 bus_space_read_4_real
496 #define bus_space_read_stream_8 bus_space_read_8_real
500 * void bus_space_write_N(bus_space_tag_t tag,
501 * bus_space_handle_t bsh, bus_size_t offset,
504 * Write the 1, 2, 4, or 8 byte value `value' to bus space
505 * described by tag/handle/offset.
508 #define bus_space_write_1_real(t, h, o, v) do { \
509 ((void)(t), (void)(*(volatile uint8_t *)((h) + (o)) = (v))); \
510 } while (/* CONSTCOND */ 0)
512 #define bus_space_write_2_real(t, h, o, v) do { \
513 ((void)(t), (void)(*(volatile uint16_t *)((h) + (o)) = (v))); \
514 } while (/* CONSTCOND */ 0)
516 #define bus_space_write_4_real(t, h, o, v) do { \
517 ((void)(t), (void)(*(volatile uint32_t *)((h) + (o)) = (v))); \
518 } while (/* CONSTCOND */ 0)
520 #define bus_space_write_8_real(t, h, o, v) do { \
521 ((void)(t), (void)(*(volatile uint64_t *)((h) + (o)) = (v))); \
522 } while (/* CONSTCOND */ 0)
526 static void bus_space_write_1(bus_space_tag_t
,
530 static void bus_space_write_2(bus_space_tag_t
,
534 static void bus_space_write_4(bus_space_tag_t
,
538 static void bus_space_write_8(bus_space_tag_t
,
544 bus_space_write_1(t
, h
, o
, v
)
546 bus_space_handle_t h
;
550 (*t
->sparc_write_1
)(t
, h
, o
, v
);
554 bus_space_write_2(t
, h
, o
, v
)
556 bus_space_handle_t h
;
560 (*t
->sparc_write_2
)(t
, h
, o
, v
);
564 bus_space_write_4(t
, h
, o
, v
)
566 bus_space_handle_t h
;
570 (*t
->sparc_write_4
)(t
, h
, o
, v
);
574 bus_space_write_8(t
, h
, o
, v
)
576 bus_space_handle_t h
;
580 (*t
->sparc_write_8
)(t
, h
, o
, v
);
583 #if __SLIM_SPARC_BUS_SPACE
586 bus_space_write_1(t
, h
, o
, v
)
588 bus_space_handle_t h
;
593 bus_space_write_1_real(t
, h
, o
, v
);
597 bus_space_write_2(t
, h
, o
, v
)
599 bus_space_handle_t h
;
604 bus_space_write_2_real(t
, h
, o
, v
);
608 bus_space_write_4(t
, h
, o
, v
)
610 bus_space_handle_t h
;
615 bus_space_write_4_real(t
, h
, o
, v
);
619 bus_space_write_8(t
, h
, o
, v
)
621 bus_space_handle_t h
;
626 bus_space_write_8_real(t
, h
, o
, v
);
629 #endif /* __SLIM_SPARC_BUS_SPACE */
631 #define bus_space_write_stream_1 bus_space_write_1_real
632 #define bus_space_write_stream_2 bus_space_write_2_real
633 #define bus_space_write_stream_4 bus_space_write_4_real
634 #define bus_space_write_stream_8 bus_space_write_8_real
638 * void bus_space_read_multi_N(bus_space_tag_t tag,
639 * bus_space_handle_t bsh, bus_size_t offset,
640 * u_intN_t *addr, bus_size_t count);
642 * Read `count' 1, 2, 4, or 8 byte quantities from bus space
643 * described by tag/handle/offset and copy into buffer provided.
646 static void bus_space_read_multi_1(bus_space_tag_t
,
652 static void bus_space_read_multi_2(bus_space_tag_t
,
658 static void bus_space_read_multi_4(bus_space_tag_t
,
664 static void bus_space_read_multi_8(bus_space_tag_t
,
671 bus_space_read_multi_1(t
, h
, o
, a
, c
)
673 bus_space_handle_t h
;
678 *a
++ = bus_space_read_1(t
, h
, o
);
682 bus_space_read_multi_2(t
, h
, o
, a
, c
)
684 bus_space_handle_t h
;
689 *a
++ = bus_space_read_2(t
, h
, o
);
693 bus_space_read_multi_4(t
, h
, o
, a
, c
)
695 bus_space_handle_t h
;
700 *a
++ = bus_space_read_4(t
, h
, o
);
704 bus_space_read_multi_8(t
, h
, o
, a
, c
)
706 bus_space_handle_t h
;
711 *a
++ = bus_space_read_8(t
, h
, o
);
714 #define bus_space_read_multi_stream_1 bus_space_read_multi_1
716 static void bus_space_read_multi_stream_2(bus_space_tag_t
,
722 static void bus_space_read_multi_stream_4(bus_space_tag_t
,
728 static void bus_space_read_multi_stream_8(bus_space_tag_t
,
735 bus_space_read_multi_stream_2(t
, h
, o
, a
, c
)
737 bus_space_handle_t h
;
742 *a
++ = bus_space_read_2_real(t
, h
, o
);
746 bus_space_read_multi_stream_4(t
, h
, o
, a
, c
)
748 bus_space_handle_t h
;
753 *a
++ = bus_space_read_4_real(t
, h
, o
);
757 bus_space_read_multi_stream_8(t
, h
, o
, a
, c
)
759 bus_space_handle_t h
;
764 *a
++ = bus_space_read_8_real(t
, h
, o
);
768 * void bus_space_write_multi_N(bus_space_tag_t tag,
769 * bus_space_handle_t bsh, bus_size_t offset,
770 * const u_intN_t *addr, bus_size_t count);
772 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
773 * provided to bus space described by tag/handle/offset.
775 static void bus_space_write_multi_1(bus_space_tag_t
,
780 static void bus_space_write_multi_2(bus_space_tag_t
,
785 static void bus_space_write_multi_4(bus_space_tag_t
,
790 static void bus_space_write_multi_8(bus_space_tag_t
,
796 bus_space_write_multi_1(t
, h
, o
, a
, c
)
798 bus_space_handle_t h
;
803 bus_space_write_1(t
, h
, o
, *a
++);
807 bus_space_write_multi_2(t
, h
, o
, a
, c
)
809 bus_space_handle_t h
;
814 bus_space_write_2(t
, h
, o
, *a
++);
818 bus_space_write_multi_4(t
, h
, o
, a
, c
)
820 bus_space_handle_t h
;
825 bus_space_write_4(t
, h
, o
, *a
++);
829 bus_space_write_multi_8(t
, h
, o
, a
, c
)
831 bus_space_handle_t h
;
836 bus_space_write_8(t
, h
, o
, *a
++);
839 #define bus_space_write_multi_stream_1 bus_space_write_multi_1
841 static void bus_space_write_multi_stream_2(bus_space_tag_t
,
846 static void bus_space_write_multi_stream_4(bus_space_tag_t
,
851 static void bus_space_write_multi_stream_8(bus_space_tag_t
,
858 bus_space_write_multi_stream_2(t
, h
, o
, a
, c
)
860 bus_space_handle_t h
;
865 bus_space_write_2_real(t
, h
, o
, *a
++);
869 bus_space_write_multi_stream_4(t
, h
, o
, a
, c
)
871 bus_space_handle_t h
;
876 bus_space_write_4_real(t
, h
, o
, *a
++);
880 bus_space_write_multi_stream_8(t
, h
, o
, a
, c
)
882 bus_space_handle_t h
;
887 bus_space_write_8_real(t
, h
, o
, *a
++);
892 * void bus_space_set_multi_N(bus_space_tag_t tag,
893 * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
896 * Write the 1, 2, 4, or 8 byte value `val' to bus space described
897 * by tag/handle/offset `count' times.
899 static void bus_space_set_multi_1(bus_space_tag_t
,
904 static void bus_space_set_multi_2(bus_space_tag_t
,
909 static void bus_space_set_multi_4(bus_space_tag_t
,
914 static void bus_space_set_multi_8(bus_space_tag_t
,
921 bus_space_set_multi_1(t
, h
, o
, v
, c
)
923 bus_space_handle_t h
;
928 bus_space_write_1(t
, h
, o
, v
);
932 bus_space_set_multi_2(t
, h
, o
, v
, c
)
934 bus_space_handle_t h
;
939 bus_space_write_2(t
, h
, o
, v
);
943 bus_space_set_multi_4(t
, h
, o
, v
, c
)
945 bus_space_handle_t h
;
950 bus_space_write_4(t
, h
, o
, v
);
954 bus_space_set_multi_8(t
, h
, o
, v
, c
)
956 bus_space_handle_t h
;
961 bus_space_write_8(t
, h
, o
, v
);
966 * void bus_space_read_region_N(bus_space_tag_t tag,
967 * bus_space_handle_t bsh, bus_size_t off,
968 * u_intN_t *addr, bus_size_t count);
971 static void bus_space_read_region_1(bus_space_tag_t
,
976 static void bus_space_read_region_2(bus_space_tag_t
,
981 static void bus_space_read_region_4(bus_space_tag_t
,
986 static void bus_space_read_region_8(bus_space_tag_t
,
993 bus_space_read_region_1(t
, h
, o
, a
, c
)
995 bus_space_handle_t h
;
999 for (; c
; a
++, c
--, o
++)
1000 *a
= bus_space_read_1(t
, h
, o
);
1003 static __inline
void
1004 bus_space_read_region_2(t
, h
, o
, a
, c
)
1006 bus_space_handle_t h
;
1010 for (; c
; a
++, c
--, o
+=2)
1011 *a
= bus_space_read_2(t
, h
, o
);
1014 static __inline
void
1015 bus_space_read_region_4(t
, h
, o
, a
, c
)
1017 bus_space_handle_t h
;
1021 for (; c
; a
++, c
--, o
+=4)
1022 *a
= bus_space_read_4(t
, h
, o
);
1025 static __inline
void
1026 bus_space_read_region_8(t
, h
, o
, a
, c
)
1028 bus_space_handle_t h
;
1032 for (; c
; a
++, c
--, o
+=8)
1033 *a
= bus_space_read_8(t
, h
, o
);
1037 * void bus_space_write_region_N(bus_space_tag_t tag,
1038 * bus_space_handle_t bsh, bus_size_t off,
1039 * u_intN_t *addr, bus_size_t count);
1042 static void bus_space_write_region_1(bus_space_tag_t
,
1047 static void bus_space_write_region_2(bus_space_tag_t
,
1052 static void bus_space_write_region_4(bus_space_tag_t
,
1057 static void bus_space_write_region_8(bus_space_tag_t
,
1062 static __inline
void
1063 bus_space_write_region_1(t
, h
, o
, a
, c
)
1065 bus_space_handle_t h
;
1069 for (; c
; a
++, c
--, o
++)
1070 bus_space_write_1(t
, h
, o
, *a
);
1073 static __inline
void
1074 bus_space_write_region_2(t
, h
, o
, a
, c
)
1076 bus_space_handle_t h
;
1080 for (; c
; a
++, c
--, o
+=2)
1081 bus_space_write_2(t
, h
, o
, *a
);
1084 static __inline
void
1085 bus_space_write_region_4(t
, h
, o
, a
, c
)
1087 bus_space_handle_t h
;
1091 for (; c
; a
++, c
--, o
+=4)
1092 bus_space_write_4(t
, h
, o
, *a
);
1095 static __inline
void
1096 bus_space_write_region_8(t
, h
, o
, a
, c
)
1098 bus_space_handle_t h
;
1102 for (; c
; a
++, c
--, o
+=8)
1103 bus_space_write_8(t
, h
, o
, *a
);
1108 * void bus_space_set_region_N(bus_space_tag_t tag,
1109 * bus_space_handle_t bsh, bus_size_t off,
1110 * u_intN_t *addr, bus_size_t count);
1113 static void bus_space_set_region_1(bus_space_tag_t
,
1118 static void bus_space_set_region_2(bus_space_tag_t
,
1123 static void bus_space_set_region_4(bus_space_tag_t
,
1128 static void bus_space_set_region_8(bus_space_tag_t
,
1134 static __inline
void
1135 bus_space_set_region_1(t
, h
, o
, v
, c
)
1137 bus_space_handle_t h
;
1142 bus_space_write_1(t
, h
, o
, v
);
1145 static __inline
void
1146 bus_space_set_region_2(t
, h
, o
, v
, c
)
1148 bus_space_handle_t h
;
1152 for (; c
; c
--, o
+=2)
1153 bus_space_write_2(t
, h
, o
, v
);
1156 static __inline
void
1157 bus_space_set_region_4(t
, h
, o
, v
, c
)
1159 bus_space_handle_t h
;
1163 for (; c
; c
--, o
+=4)
1164 bus_space_write_4(t
, h
, o
, v
);
1167 static __inline
void
1168 bus_space_set_region_8(t
, h
, o
, v
, c
)
1170 bus_space_handle_t h
;
1174 for (; c
; c
--, o
+=8)
1175 bus_space_write_8(t
, h
, o
, v
);
1180 * void bus_space_copy_region_N(bus_space_tag_t tag,
1181 * bus_space_handle_t bsh1, bus_size_t off1,
1182 * bus_space_handle_t bsh2, bus_size_t off2,
1183 * bus_size_t count);
1185 * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
1186 * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
1188 static void bus_space_copy_region_1(bus_space_tag_t
,
1194 static void bus_space_copy_region_2(bus_space_tag_t
,
1200 static void bus_space_copy_region_4(bus_space_tag_t
,
1206 static void bus_space_copy_region_8(bus_space_tag_t
,
1214 static __inline
void
1215 bus_space_copy_region_1(t
, h1
, o1
, h2
, o2
, c
)
1217 bus_space_handle_t h1
, h2
;
1221 for (; c
; c
--, o1
++, o2
++)
1222 bus_space_write_1(t
, h1
, o1
, bus_space_read_1(t
, h2
, o2
));
1225 static __inline
void
1226 bus_space_copy_region_2(t
, h1
, o1
, h2
, o2
, c
)
1228 bus_space_handle_t h1
, h2
;
1232 for (; c
; c
--, o1
+=2, o2
+=2)
1233 bus_space_write_2(t
, h1
, o1
, bus_space_read_2(t
, h2
, o2
));
1236 static __inline
void
1237 bus_space_copy_region_4(t
, h1
, o1
, h2
, o2
, c
)
1239 bus_space_handle_t h1
, h2
;
1243 for (; c
; c
--, o1
+=4, o2
+=4)
1244 bus_space_write_4(t
, h1
, o1
, bus_space_read_4(t
, h2
, o2
));
1247 static __inline
void
1248 bus_space_copy_region_8(t
, h1
, o1
, h2
, o2
, c
)
1250 bus_space_handle_t h1
, h2
;
1254 for (; c
; c
--, o1
+=8, o2
+=8)
1255 bus_space_write_8(t
, h1
, o1
, bus_space_read_8(t
, h2
, o2
));
1259 * void bus_space_read_region_stream_N(bus_space_tag_t tag,
1260 * bus_space_handle_t bsh, bus_size_t off,
1261 * u_intN_t *addr, bus_size_t count);
1264 static void bus_space_read_region_stream_1(bus_space_tag_t
,
1269 static void bus_space_read_region_stream_2(bus_space_tag_t
,
1274 static void bus_space_read_region_stream_4(bus_space_tag_t
,
1279 static void bus_space_read_region_stream_8(bus_space_tag_t
,
1285 static __inline
void
1286 bus_space_read_region_stream_1(t
, h
, o
, a
, c
)
1288 bus_space_handle_t h
;
1292 for (; c
; a
++, c
--, o
++)
1293 *a
= bus_space_read_stream_1(t
, h
, o
);
1295 static __inline
void
1296 bus_space_read_region_stream_2(t
, h
, o
, a
, c
)
1298 bus_space_handle_t h
;
1302 for (; c
; a
++, c
--, o
+=2)
1303 *a
= bus_space_read_stream_2(t
, h
, o
);
1305 static __inline
void
1306 bus_space_read_region_stream_4(t
, h
, o
, a
, c
)
1308 bus_space_handle_t h
;
1312 for (; c
; a
++, c
--, o
+=4)
1313 *a
= bus_space_read_stream_4(t
, h
, o
);
1315 static __inline
void
1316 bus_space_read_region_stream_8(t
, h
, o
, a
, c
)
1318 bus_space_handle_t h
;
1322 for (; c
; a
++, c
--, o
+=8)
1323 *a
= bus_space_read_stream_8(t
, h
, o
);
1327 * void bus_space_write_region_stream_N(bus_space_tag_t tag,
1328 * bus_space_handle_t bsh, bus_size_t off,
1329 * u_intN_t *addr, bus_size_t count);
1332 static void bus_space_write_region_stream_1(bus_space_tag_t
,
1337 static void bus_space_write_region_stream_2(bus_space_tag_t
,
1342 static void bus_space_write_region_stream_4(bus_space_tag_t
,
1347 static void bus_space_write_region_stream_8(bus_space_tag_t
,
1352 static __inline
void
1353 bus_space_write_region_stream_1(t
, h
, o
, a
, c
)
1355 bus_space_handle_t h
;
1359 for (; c
; a
++, c
--, o
++)
1360 bus_space_write_stream_1(t
, h
, o
, *a
);
1363 static __inline
void
1364 bus_space_write_region_stream_2(t
, h
, o
, a
, c
)
1366 bus_space_handle_t h
;
1370 for (; c
; a
++, c
--, o
+=2)
1371 bus_space_write_stream_2(t
, h
, o
, *a
);
1374 static __inline
void
1375 bus_space_write_region_stream_4(t
, h
, o
, a
, c
)
1377 bus_space_handle_t h
;
1381 for (; c
; a
++, c
--, o
+=4)
1382 bus_space_write_stream_4(t
, h
, o
, *a
);
1385 static __inline
void
1386 bus_space_write_region_stream_8(t
, h
, o
, a
, c
)
1388 bus_space_handle_t h
;
1392 for (; c
; a
++, c
--, o
+=8)
1393 bus_space_write_stream_8(t
, h
, o
, *a
);
1398 * void bus_space_set_region_stream_N(bus_space_tag_t tag,
1399 * bus_space_handle_t bsh, bus_size_t off,
1400 * u_intN_t *addr, bus_size_t count);
1403 static void bus_space_set_region_stream_1(bus_space_tag_t
,
1408 static void bus_space_set_region_stream_2(bus_space_tag_t
,
1413 static void bus_space_set_region_stream_4(bus_space_tag_t
,
1418 static void bus_space_set_region_stream_8(bus_space_tag_t
,
1424 static __inline
void
1425 bus_space_set_region_stream_1(t
, h
, o
, v
, c
)
1427 bus_space_handle_t h
;
1432 bus_space_write_stream_1(t
, h
, o
, v
);
1435 static __inline
void
1436 bus_space_set_region_stream_2(t
, h
, o
, v
, c
)
1438 bus_space_handle_t h
;
1442 for (; c
; c
--, o
+=2)
1443 bus_space_write_stream_2(t
, h
, o
, v
);
1446 static __inline
void
1447 bus_space_set_region_stream_4(t
, h
, o
, v
, c
)
1449 bus_space_handle_t h
;
1453 for (; c
; c
--, o
+=4)
1454 bus_space_write_stream_4(t
, h
, o
, v
);
1457 static __inline
void
1458 bus_space_set_region_stream_8(t
, h
, o
, v
, c
)
1460 bus_space_handle_t h
;
1464 for (; c
; c
--, o
+=8)
1465 bus_space_write_stream_8(t
, h
, o
, v
);
1470 * void bus_space_copy_region_stream_N(bus_space_tag_t tag,
1471 * bus_space_handle_t bsh1, bus_size_t off1,
1472 * bus_space_handle_t bsh2, bus_size_t off2,
1473 * bus_size_t count);
1475 * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
1476 * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
1478 static void bus_space_copy_region_stream_1(bus_space_tag_t
,
1484 static void bus_space_copy_region_stream_2(bus_space_tag_t
,
1490 static void bus_space_copy_region_stream_4(bus_space_tag_t
,
1496 static void bus_space_copy_region_stream_8(bus_space_tag_t
,
1503 static __inline
void
1504 bus_space_copy_region_stream_1(t
, h1
, o1
, h2
, o2
, c
)
1506 bus_space_handle_t h1
, h2
;
1510 for (; c
; c
--, o1
++, o2
++)
1511 bus_space_write_stream_1(t
, h1
, o1
, bus_space_read_stream_1(t
, h2
, o2
));
1514 static __inline
void
1515 bus_space_copy_region_stream_2(t
, h1
, o1
, h2
, o2
, c
)
1517 bus_space_handle_t h1
, h2
;
1521 for (; c
; c
--, o1
+=2, o2
+=2)
1522 bus_space_write_stream_2(t
, h1
, o1
, bus_space_read_stream_2(t
, h2
, o2
));
1525 static __inline
void
1526 bus_space_copy_region_stream_4(t
, h1
, o1
, h2
, o2
, c
)
1528 bus_space_handle_t h1
, h2
;
1532 for (; c
; c
--, o1
+=4, o2
+=4)
1533 bus_space_write_stream_4(t
, h1
, o1
, bus_space_read_stream_4(t
, h2
, o2
));
1536 static __inline
void
1537 bus_space_copy_region_stream_8(t
, h1
, o1
, h2
, o2
, c
)
1539 bus_space_handle_t h1
, h2
;
1543 for (; c
; c
--, o1
+=8, o2
+=8)
1544 bus_space_write_stream_8(t
, h1
, o1
, bus_space_read_8(t
, h2
, o2
));
1547 #define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t)
1549 /*--------------------------------*/
1552 * Flags used in various bus DMA methods.
1554 #define BUS_DMA_WAITOK 0x000 /* safe to sleep (pseudo-flag) */
1555 #define BUS_DMA_NOWAIT 0x001 /* not safe to sleep */
1556 #define BUS_DMA_ALLOCNOW 0x002 /* perform resource allocation now */
1557 #define BUS_DMA_COHERENT 0x004 /* hint: map memory DMA coherent */
1558 #define BUS_DMA_STREAMING 0x008 /* hint: sequential, unidirectional */
1559 #define BUS_DMA_BUS1 0x010 /* placeholders for bus functions... */
1560 #define BUS_DMA_BUS2 0x020
1561 #define BUS_DMA_BUS3 0x040
1562 #define BUS_DMA_BUS4 0x080
1563 #define BUS_DMA_READ 0x100 /* mapping is device -> memory only */
1564 #define BUS_DMA_WRITE 0x200 /* mapping is memory -> device only */
1565 #define BUS_DMA_NOCACHE 0x400 /* hint: map non-cached memory */
1567 /* For devices that have a 24-bit address space */
1568 #define BUS_DMA_24BIT BUS_DMA_BUS1
1570 /* Internal flag: current DVMA address is equal to the KVA buffer address */
1571 #define _BUS_DMA_DIRECTMAP BUS_DMA_BUS2
1573 /* Forwards needed by prototypes below. */
1578 * Operations performed by bus_dmamap_sync().
1580 #define BUS_DMASYNC_PREREAD 0x01 /* pre-read synchronization */
1581 #define BUS_DMASYNC_POSTREAD 0x02 /* post-read synchronization */
1582 #define BUS_DMASYNC_PREWRITE 0x04 /* pre-write synchronization */
1583 #define BUS_DMASYNC_POSTWRITE 0x08 /* post-write synchronization */
1585 typedef struct sparc_bus_dma_tag
*bus_dma_tag_t
;
1586 typedef struct sparc_bus_dmamap
*bus_dmamap_t
;
1588 #define BUS_DMA_TAG_VALID(t) ((t) != (bus_dma_tag_t)0)
1593 * Describes a single contiguous DMA transaction. Values
1594 * are suitable for programming into DMA registers.
1596 struct sparc_bus_dma_segment
{
1597 bus_addr_t ds_addr
; /* DVMA address */
1598 bus_size_t ds_len
; /* length of transfer */
1599 bus_size_t _ds_sgsize
; /* size of allocated DVMA segment */
1600 void *_ds_mlist
; /* page list when dmamem_alloc'ed */
1601 vaddr_t _ds_va
; /* VA when dmamem_map'ed */
1603 typedef struct sparc_bus_dma_segment bus_dma_segment_t
;
1609 * A machine-dependent opaque type describing the implementation of
1610 * DMA for a given bus.
1612 struct sparc_bus_dma_tag
{
1613 void *_cookie
; /* cookie used in the guts */
1616 * DMA mapping methods.
1618 int (*_dmamap_create
)(bus_dma_tag_t
, bus_size_t
, int,
1619 bus_size_t
, bus_size_t
, int, bus_dmamap_t
*);
1620 void (*_dmamap_destroy
)(bus_dma_tag_t
, bus_dmamap_t
);
1621 int (*_dmamap_load
)(bus_dma_tag_t
, bus_dmamap_t
, void *,
1622 bus_size_t
, struct proc
*, int);
1623 int (*_dmamap_load_mbuf
)(bus_dma_tag_t
, bus_dmamap_t
,
1624 struct mbuf
*, int);
1625 int (*_dmamap_load_uio
)(bus_dma_tag_t
, bus_dmamap_t
,
1627 int (*_dmamap_load_raw
)(bus_dma_tag_t
, bus_dmamap_t
,
1628 bus_dma_segment_t
*, int, bus_size_t
, int);
1629 void (*_dmamap_unload
)(bus_dma_tag_t
, bus_dmamap_t
);
1630 void (*_dmamap_sync
)(bus_dma_tag_t
, bus_dmamap_t
,
1631 bus_addr_t
, bus_size_t
, int);
1634 * DMA memory utility functions.
1636 int (*_dmamem_alloc
)(bus_dma_tag_t
, bus_size_t
, bus_size_t
,
1637 bus_size_t
, bus_dma_segment_t
*, int, int *, int);
1638 void (*_dmamem_free
)(bus_dma_tag_t
,
1639 bus_dma_segment_t
*, int);
1640 int (*_dmamem_map
)(bus_dma_tag_t
, bus_dma_segment_t
*,
1641 int, size_t, void **, int);
1642 void (*_dmamem_unmap
)(bus_dma_tag_t
, void *, size_t);
1643 paddr_t (*_dmamem_mmap
)(bus_dma_tag_t
, bus_dma_segment_t
*,
1644 int, off_t
, int, int);
1647 #define bus_dmamap_create(t, s, n, m, b, f, p) \
1648 (*(t)->_dmamap_create)((t), (s), (n), (m), (b), (f), (p))
1649 #define bus_dmamap_destroy(t, p) \
1650 (*(t)->_dmamap_destroy)((t), (p))
1651 #define bus_dmamap_load(t, m, b, s, p, f) \
1652 (*(t)->_dmamap_load)((t), (m), (b), (s), (p), (f))
1653 #define bus_dmamap_load_mbuf(t, m, b, f) \
1654 (*(t)->_dmamap_load_mbuf)((t), (m), (b), (f))
1655 #define bus_dmamap_load_uio(t, m, u, f) \
1656 (*(t)->_dmamap_load_uio)((t), (m), (u), (f))
1657 #define bus_dmamap_load_raw(t, m, sg, n, s, f) \
1658 (*(t)->_dmamap_load_raw)((t), (m), (sg), (n), (s), (f))
1659 #define bus_dmamap_unload(t, p) \
1660 (*(t)->_dmamap_unload)((t), (p))
1661 #define bus_dmamap_sync(t, p, o, l, ops) \
1662 (void)((t)->_dmamap_sync ? \
1663 (*(t)->_dmamap_sync)((t), (p), (o), (l), (ops)) : (void)0)
1665 #define bus_dmamem_alloc(t, s, a, b, sg, n, r, f) \
1666 (*(t)->_dmamem_alloc)((t), (s), (a), (b), (sg), (n), (r), (f))
1667 #define bus_dmamem_free(t, sg, n) \
1668 (*(t)->_dmamem_free)((t), (sg), (n))
1669 #define bus_dmamem_map(t, sg, n, s, k, f) \
1670 (*(t)->_dmamem_map)((t), (sg), (n), (s), (k), (f))
1671 #define bus_dmamem_unmap(t, k, s) \
1672 (*(t)->_dmamem_unmap)((t), (k), (s))
1673 #define bus_dmamem_mmap(t, sg, n, o, p, f) \
1674 (*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
1676 #define bus_dmatag_subregion(t, mna, mxa, nt, f) EOPNOTSUPP
1677 #define bus_dmatag_destroy(t)
1682 * Describes a DMA mapping.
1684 struct sparc_bus_dmamap
{
1686 * PRIVATE MEMBERS: not for use by machine-independent code.
1688 bus_size_t _dm_size
; /* largest DMA transfer mappable */
1689 int _dm_segcnt
; /* number of segs this map can map */
1690 bus_size_t _dm_maxmaxsegsz
; /* fixed largest possible segment */
1691 bus_size_t _dm_boundary
; /* don't cross this */
1692 int _dm_flags
; /* misc. flags */
1694 void *_dm_cookie
; /* cookie for bus-specific functions */
1696 u_long _dm_align
; /* DVMA alignment; must be a
1697 multiple of the page size */
1698 u_long _dm_ex_start
; /* constraints on DVMA map */
1699 u_long _dm_ex_end
; /* allocations; used by the VME bus
1700 driver and by the IOMMU driver
1701 when mapping 24-bit devices */
1704 * PUBLIC MEMBERS: these are used by machine-independent code.
1706 bus_size_t dm_maxsegsz
; /* largest possible segment */
1707 bus_size_t dm_mapsize
; /* size of the mapping */
1708 int dm_nsegs
; /* # valid segments in mapping */
1709 bus_dma_segment_t dm_segs
[1]; /* segments; variable length */
1712 #ifdef _SPARC_BUS_DMA_PRIVATE
1713 int _bus_dmamap_create(bus_dma_tag_t
, bus_size_t
, int, bus_size_t
,
1714 bus_size_t
, int, bus_dmamap_t
*);
1715 void _bus_dmamap_destroy(bus_dma_tag_t
, bus_dmamap_t
);
1716 int _bus_dmamap_load_mbuf(bus_dma_tag_t
, bus_dmamap_t
,
1717 struct mbuf
*, int);
1718 int _bus_dmamap_load_uio(bus_dma_tag_t
, bus_dmamap_t
,
1720 int _bus_dmamap_load_raw(bus_dma_tag_t
, bus_dmamap_t
,
1721 bus_dma_segment_t
*, int, bus_size_t
, int);
1722 void _bus_dmamap_unload(bus_dma_tag_t
, bus_dmamap_t
);
1723 void _bus_dmamap_sync(bus_dma_tag_t
, bus_dmamap_t
, bus_addr_t
,
1726 int _bus_dmamem_alloc(bus_dma_tag_t tag
, bus_size_t size
,
1727 bus_size_t alignment
, bus_size_t boundary
,
1728 bus_dma_segment_t
*segs
, int nsegs
, int *rsegs
, int flags
);
1729 void _bus_dmamem_free(bus_dma_tag_t tag
, bus_dma_segment_t
*segs
,
1731 void _bus_dmamem_unmap(bus_dma_tag_t tag
, void *kva
,
1733 paddr_t
_bus_dmamem_mmap(bus_dma_tag_t tag
, bus_dma_segment_t
*segs
,
1734 int nsegs
, off_t off
, int prot
, int flags
);
1736 int _bus_dmamem_alloc_range(bus_dma_tag_t tag
, bus_size_t size
,
1737 bus_size_t alignment
, bus_size_t boundary
,
1738 bus_dma_segment_t
*segs
, int nsegs
, int *rsegs
, int flags
,
1739 vaddr_t low
, vaddr_t high
);
1741 vaddr_t
_bus_dma_valloc_skewed(size_t, u_long
, u_long
, u_long
);
1742 #endif /* _SPARC_BUS_DMA_PRIVATE */
1744 #endif /* _SPARC_BUS_H_ */