xref: /openbsd-src/sys/arch/sparc64/include/bus.h (revision 0fc03ff9ea87e5606ae3b9c1106ab7a09598ebdb)
1*0fc03ff9Sjsg /*	$OpenBSD: bus.h,v 1.38 2024/10/22 22:01:58 jsg Exp $	*/
25fdbebc0Sjason /*	$NetBSD: bus.h,v 1.31 2001/09/21 15:30:41 wiz Exp $	*/
3bd12f793Sart 
4bd12f793Sart /*-
5bd12f793Sart  * Copyright (c) 1996, 1997, 1998, 2001 The NetBSD Foundation, Inc.
6bd12f793Sart  * All rights reserved.
7bd12f793Sart  *
8bd12f793Sart  * This code is derived from software contributed to The NetBSD Foundation
9bd12f793Sart  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
10bd12f793Sart  * NASA Ames Research Center.
11bd12f793Sart  *
12bd12f793Sart  * Redistribution and use in source and binary forms, with or without
13bd12f793Sart  * modification, are permitted provided that the following conditions
14bd12f793Sart  * are met:
15bd12f793Sart  * 1. Redistributions of source code must retain the above copyright
16bd12f793Sart  *    notice, this list of conditions and the following disclaimer.
17bd12f793Sart  * 2. Redistributions in binary form must reproduce the above copyright
18bd12f793Sart  *    notice, this list of conditions and the following disclaimer in the
19bd12f793Sart  *    documentation and/or other materials provided with the distribution.
20bd12f793Sart  *
21bd12f793Sart  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
22bd12f793Sart  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23bd12f793Sart  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24bd12f793Sart  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25bd12f793Sart  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26bd12f793Sart  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27bd12f793Sart  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28bd12f793Sart  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29bd12f793Sart  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30bd12f793Sart  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31bd12f793Sart  * POSSIBILITY OF SUCH DAMAGE.
32bd12f793Sart  */
33bd12f793Sart 
34bd12f793Sart /*
355cdd493aSjason  * Copyright (c) 1997-1999, 2001 Eduardo E. Horvath. All rights reserved.
36bd12f793Sart  * Copyright (c) 1996 Charles M. Hannum.  All rights reserved.
37bd12f793Sart  * Copyright (c) 1996 Christopher G. Demetriou.  All rights reserved.
38bd12f793Sart  *
39bd12f793Sart  * Redistribution and use in source and binary forms, with or without
40bd12f793Sart  * modification, are permitted provided that the following conditions
41bd12f793Sart  * are met:
42bd12f793Sart  * 1. Redistributions of source code must retain the above copyright
43bd12f793Sart  *    notice, this list of conditions and the following disclaimer.
44bd12f793Sart  * 2. Redistributions in binary form must reproduce the above copyright
45bd12f793Sart  *    notice, this list of conditions and the following disclaimer in the
46bd12f793Sart  *    documentation and/or other materials provided with the distribution.
47bd12f793Sart  * 3. All advertising materials mentioning features or use of this software
48bd12f793Sart  *    must display the following acknowledgement:
49bd12f793Sart  *      This product includes software developed by Christopher G. Demetriou
50bd12f793Sart  *	for the NetBSD Project.
51bd12f793Sart  * 4. The name of the author may not be used to endorse or promote products
52bd12f793Sart  *    derived from this software without specific prior written permission
53bd12f793Sart  *
54bd12f793Sart  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
55bd12f793Sart  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
56bd12f793Sart  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
57bd12f793Sart  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
58bd12f793Sart  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
59bd12f793Sart  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
60bd12f793Sart  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
61bd12f793Sart  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
62bd12f793Sart  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
63bd12f793Sart  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64bd12f793Sart  */
65bd12f793Sart 
662fa72412Spirofti #ifndef _MACHINE_BUS_H_
672fa72412Spirofti #define _MACHINE_BUS_H_
68bd12f793Sart 
6927d3e2e5Sdlg #include <sys/atomic.h>
70bd12f793Sart 
71f56b290dSderaadt #ifdef _KERNEL
72f56b290dSderaadt 
73bd12f793Sart /*
74bd12f793Sart  * Debug hooks
75bd12f793Sart  */
76bd12f793Sart 
77bd12f793Sart #define	BSDB_ACCESS	0x01
78bd12f793Sart #define BSDB_MAP	0x02
79eb79e960Shenric #define BSDB_ASSERT	0x04
80eb79e960Shenric #define BSDB_MAPDETAIL	0x08
81eb79e960Shenric #define	BSDB_ALL_ACCESS	0x10
82bd12f793Sart extern int bus_space_debug;
83bd12f793Sart 
84eb79e960Shenric #define BSHDB_ACCESS	0x01
85eb79e960Shenric #define BSHDB_NO_ACCESS	0x02
86eb79e960Shenric 
87eb79e960Shenric #if defined(BUS_SPACE_DEBUG)
88eb79e960Shenric #include <sys/systm.h>
89745b6152Shenric #define BUS_SPACE_PRINTF(l, s) do {				\
90745b6152Shenric 	if(bus_space_debug & (l)) printf s;			\
91745b6152Shenric } while(0)
92eb79e960Shenric #define BUS_SPACE_TRACE(t, h, s) do {				\
93eb79e960Shenric 	if ( (((bus_space_debug & BSDB_ALL_ACCESS) != 0) &&	\
94eb79e960Shenric 		(((h).bh_flags & BSHDB_NO_ACCESS) == 0)) ||	\
95eb79e960Shenric 	     (((bus_space_debug & BSDB_ACCESS) != 0) &&		\
96eb79e960Shenric 		(((h).bh_flags & BSHDB_ACCESS) != 0)))		\
97eb79e960Shenric 		printf s;					\
98eb79e960Shenric 	} while(0)
99eb79e960Shenric #define BUS_SPACE_SET_FLAGS(t, h, f) ((h).bh_flags |= (f))
100eb79e960Shenric #define BUS_SPACE_CLEAR_FLAGS(t, h, f) ((h).bh_flags &= ~(f))
101eb79e960Shenric #define BUS_SPACE_FLAG_DECL(s)	int s
102eb79e960Shenric #define BUS_SPACE_SAVE_FLAGS(t, h, s) (s = (h).bh_flags)
103eb79e960Shenric #define BUS_SPACE_RESTORE_FLAGS(t, h, s) (s = (h).bh_flags)
104eb79e960Shenric #define BUS_SPACE_ASSERT(t, h, o, n) do {			\
105eb79e960Shenric 	if (bus_space_debug & BSDB_ASSERT)			\
106eb79e960Shenric 		bus_space_assert(t, &(h), o, n);		\
107eb79e960Shenric 	} while(0)
108745b6152Shenric #else /* BUS_SPACE_DEBUG */
109eb79e960Shenric #define BUS_SPACE_PRINTF(l, s)
110eb79e960Shenric #define BUS_SPACE_TRACE(t, h, s)
111eb79e960Shenric #define BUS_SPACE_SET_FLAGS(t, h, f)
112eb79e960Shenric #define BUS_SPACE_CLEAR_FLAGS(t, h, f)
113eb79e960Shenric #define BUS_SPACE_FLAG_DECL(s)
114eb79e960Shenric #define BUS_SPACE_SAVE_FLAGS(t, h, s)
115eb79e960Shenric #define BUS_SPACE_RESTORE_FLAGS(t, h, s)
116eb79e960Shenric #define BUS_SPACE_ASSERT(t, h, o, n)
117745b6152Shenric #endif /* BUS_SPACE_DEBUG */
118eb79e960Shenric 
119eb79e960Shenric 
120bd12f793Sart /*
121d277156aSsobrado  * UPA and SBus spaces are non-cached and big endian
122bd12f793Sart  * (except for RAM and PROM)
123bd12f793Sart  *
124bd12f793Sart  * PCI spaces are non-cached and little endian
125bd12f793Sart  */
126bd12f793Sart 
1270793d0d1Sjsg enum sparc_bus_type {
128bd12f793Sart 	UPA_BUS_SPACE,
129bd12f793Sart 	SBUS_BUS_SPACE,
130bd12f793Sart 	PCI_CONFIG_BUS_SPACE,
131bd12f793Sart 	PCI_IO_BUS_SPACE,
132bd12f793Sart 	PCI_MEMORY_BUS_SPACE,
133bd12f793Sart 	LAST_BUS_SPACE
134bd12f793Sart };
135bd12f793Sart /* For backwards compatibility */
136bd12f793Sart #define SPARC_BUS_SPACE	UPA_BUS_SPACE
137bd12f793Sart 
138bd12f793Sart /*
139bd12f793Sart  * Bus address and size types
140bd12f793Sart  */
141eb79e960Shenric typedef const struct sparc_bus_space_tag	*bus_space_tag_t;
1427142cce9Smiod typedef u_long	bus_addr_t;
1437142cce9Smiod typedef u_long	bus_size_t;
144bd12f793Sart 
145eb79e960Shenric 
146eb79e960Shenric typedef struct _bus_space_handle {
147eb79e960Shenric         paddr_t		bh_ptr;
148eb79e960Shenric #ifdef BUS_SPACE_DEBUG
149eb79e960Shenric 	bus_space_tag_t	bh_tag;
150eb79e960Shenric 	bus_size_t	bh_size;
151eb79e960Shenric 	int		bh_flags;
152eb79e960Shenric #endif
153eb79e960Shenric } bus_space_handle_t;
154eb79e960Shenric 
1555fdbebc0Sjason /* For buses which have an iospace. */
1565fdbebc0Sjason #define BUS_ADDR_IOSPACE(x)     ((x)>>32)
1575fdbebc0Sjason #define BUS_ADDR_PADDR(x)       ((x)&0xffffffff)
158eb79e960Shenric #define BUS_ADDR(io, pa)        ((((bus_addr_t)io)<<32)|(pa))
1595fdbebc0Sjason 
160bd12f793Sart /*
161bd12f793Sart  * Access methods for bus resources and address space.
162bd12f793Sart  */
163bd12f793Sart 
164bd12f793Sart struct sparc_bus_space_tag {
165bd12f793Sart 	void	*cookie;
166bd12f793Sart 	bus_space_tag_t	parent;
1670793d0d1Sjsg 	enum sparc_bus_type default_type;
168eb79e960Shenric         u_int8_t	asi;
169eb79e960Shenric         u_int8_t	sasi;
170eb79e960Shenric 	char	name[32];
171bd12f793Sart 
172c4071fd1Smillert 	int     (*sparc_bus_alloc)(bus_space_tag_t,
173eb79e960Shenric 		bus_space_tag_t,
1745fdbebc0Sjason 		bus_addr_t, bus_addr_t,
1755fdbebc0Sjason 		bus_size_t, bus_size_t, bus_size_t,
176c4071fd1Smillert 		int, bus_addr_t *, bus_space_handle_t *);
177bd12f793Sart 
178c4071fd1Smillert 	void	(*sparc_bus_free)(bus_space_tag_t,
179eb79e960Shenric 		bus_space_tag_t,
180c4071fd1Smillert 		bus_space_handle_t, bus_size_t);
181bd12f793Sart 
182c4071fd1Smillert 	int	(*sparc_bus_map)(bus_space_tag_t,
183eb79e960Shenric 		bus_space_tag_t,
184eb79e960Shenric 		bus_addr_t,	bus_size_t,
185eb79e960Shenric 		int, bus_space_handle_t *);
186eb79e960Shenric 
187eb79e960Shenric 	int	(*sparc_bus_protect)(bus_space_tag_t,
188eb79e960Shenric 		bus_space_tag_t,
189eb79e960Shenric 		bus_space_handle_t, bus_size_t, int);
190bd12f793Sart 
191c4071fd1Smillert 	int	(*sparc_bus_unmap)(bus_space_tag_t,
192eb79e960Shenric 		bus_space_tag_t,
193c4071fd1Smillert 		bus_space_handle_t, bus_size_t);
1945fdbebc0Sjason 
195c4071fd1Smillert 	int	(*sparc_bus_subregion)(bus_space_tag_t,
196eb79e960Shenric 		bus_space_tag_t,
1975fdbebc0Sjason 		bus_space_handle_t, bus_size_t,
198c4071fd1Smillert 		bus_size_t, bus_space_handle_t *);
1995fdbebc0Sjason 
200c4071fd1Smillert 	paddr_t	(*sparc_bus_mmap)(bus_space_tag_t,
201eb79e960Shenric 		bus_space_tag_t,
202c4071fd1Smillert 		bus_addr_t, off_t, int, int);
2035fdbebc0Sjason 
2044f9e30d0Smillert 	void	*(*sparc_intr_establish)(bus_space_tag_t,
205eb79e960Shenric 		bus_space_tag_t,
2065fdbebc0Sjason 		int, int, int,
20785729938Shenric 		int (*)(void *), void *,
20885729938Shenric 		const char *);
2091d9e937eSjmatthew 	void	*(*sparc_intr_establish_cpu)(bus_space_tag_t,
2101d9e937eSjmatthew 		bus_space_tag_t,
2111d9e937eSjmatthew 		int, int, int,
2121d9e937eSjmatthew 		struct cpu_info *,
2131d9e937eSjmatthew 		int (*)(void *), void *,
2141d9e937eSjmatthew 		const char *);
215bd12f793Sart 
21659c45879Skettenis 	bus_addr_t (*sparc_bus_addr)(bus_space_tag_t,
21759c45879Skettenis 		bus_space_tag_t, bus_space_handle_t);
218bd12f793Sart };
219bd12f793Sart 
220bd12f793Sart /*
221bd12f793Sart  * Bus space function prototypes.
222bd12f793Sart  */
223eb79e960Shenric int		bus_space_alloc(
2245fdbebc0Sjason 				bus_space_tag_t,
2255fdbebc0Sjason 				bus_addr_t,		/* reg start */
2265fdbebc0Sjason 				bus_addr_t,		/* reg end */
2275fdbebc0Sjason 				bus_size_t,		/* size */
2285fdbebc0Sjason 				bus_size_t,		/* alignment */
2295fdbebc0Sjason 				bus_size_t,		/* boundary */
2305fdbebc0Sjason 				int,			/* flags */
2315fdbebc0Sjason 				bus_addr_t *,
232c4071fd1Smillert 				bus_space_handle_t *);
233eb79e960Shenric void		bus_space_free(
2345fdbebc0Sjason 				bus_space_tag_t,
2355fdbebc0Sjason 				bus_space_handle_t,
236c4071fd1Smillert 				bus_size_t);
237eb79e960Shenric int		bus_space_map(
238bd12f793Sart 				bus_space_tag_t,
239bd12f793Sart 				bus_addr_t,
240bd12f793Sart 				bus_size_t,
241bd12f793Sart 				int,			/*flags*/
242c4071fd1Smillert 				bus_space_handle_t *);
243eb79e960Shenric int		bus_space_protect(
244bd12f793Sart 				bus_space_tag_t,
245eb79e960Shenric 				bus_space_handle_t,
246bd12f793Sart 				bus_size_t,
247eb79e960Shenric 				int);			/*flags*/
248eb79e960Shenric int		bus_space_unmap(
249bd12f793Sart 				bus_space_tag_t,
250bd12f793Sart 				bus_space_handle_t,
251c4071fd1Smillert 				bus_size_t);
252eb79e960Shenric int		bus_space_subregion(
253bd12f793Sart 				bus_space_tag_t,
254bd12f793Sart 				bus_space_handle_t,
255bd12f793Sart 				bus_size_t,
256bd12f793Sart 				bus_size_t,
257c4071fd1Smillert 				bus_space_handle_t *);
258c4071fd1Smillert static void	bus_space_barrier(
259bd12f793Sart 				bus_space_tag_t,
260bd12f793Sart 				bus_space_handle_t,
261bd12f793Sart 				bus_size_t,
262bd12f793Sart 				bus_size_t,
263c4071fd1Smillert 				int);
264eb79e960Shenric paddr_t		bus_space_mmap(
265bd12f793Sart 				bus_space_tag_t,
2665fdbebc0Sjason 				bus_addr_t,		/*addr*/
2675fdbebc0Sjason 				off_t,			/*offset*/
2685fdbebc0Sjason 				int,			/*prot*/
269c4071fd1Smillert 				int);			/*flags*/
270eb79e960Shenric void	       *bus_intr_establish(
271bd12f793Sart 				bus_space_tag_t,
272bd12f793Sart 				int,			/*bus-specific intr*/
273bd12f793Sart 				int,			/*device class level,
274bd12f793Sart 							  see machine/intr.h*/
275bd12f793Sart 				int,			/*flags*/
276c4071fd1Smillert 				int (*)(void *),	/*handler*/
27785729938Shenric 				void *,			/*handler arg*/
27885729938Shenric 				const char *);		/*what*/
2791d9e937eSjmatthew void	       *bus_intr_establish_cpu(
2801d9e937eSjmatthew 				bus_space_tag_t,
2811d9e937eSjmatthew 				int,			/*bus-specific intr*/
2821d9e937eSjmatthew 				int,			/*device class level,
2831d9e937eSjmatthew 							  see machine/intr.h*/
2841d9e937eSjmatthew 				int,			/*flags*/
2851d9e937eSjmatthew 				struct cpu_info *,	/*cpu*/
2861d9e937eSjmatthew 				int (*)(void *),	/*handler*/
2871d9e937eSjmatthew 				void *,			/*handler arg*/
2881d9e937eSjmatthew 				const char *);		/*what*/
28985729938Shenric void	       *bus_intr_allocate(
29085729938Shenric 				bus_space_tag_t,
29185729938Shenric 				int (*)(void *),	/*handler*/
29285729938Shenric 				void *,			/*handler arg*/
29385729938Shenric 				int,			/*number*/
29485729938Shenric 				int,			/*pil*/
29585729938Shenric 				volatile u_int64_t *,	/*map*/
29685729938Shenric 				volatile u_int64_t *,	/*clr*/
29785729938Shenric 				const char *);		/*what*/
29885729938Shenric void		bus_intr_free(void *);
299eb79e960Shenric void		bus_space_render_tag(
300eb79e960Shenric 				bus_space_tag_t,
301eb79e960Shenric 				char *,
302eb79e960Shenric 				size_t);
303eb79e960Shenric void	       *bus_space_vaddr(
304eb79e960Shenric 				bus_space_tag_t,
305eb79e960Shenric 				bus_space_handle_t);
306bd12f793Sart 
307745b6152Shenric #ifdef BUS_SPACE_DEBUG
308745b6152Shenric void bus_space_assert(bus_space_tag_t,
309745b6152Shenric 	const bus_space_handle_t *,
310745b6152Shenric 	bus_size_t, int);
311745b6152Shenric void bus_space_render_tag(bus_space_tag_t, char*, size_t);
312745b6152Shenric #endif /* BUS_SPACE_DEBUG */
313745b6152Shenric 
314745b6152Shenric 
315eb79e960Shenric #define _BS_PRECALL(t,f)		\
316bd12f793Sart 	while (t->f == NULL)		\
317eb79e960Shenric 		t = t->parent;
318eb79e960Shenric #define _BS_POSTCALL
319bd12f793Sart 
320eb79e960Shenric #define _BS_CALL(t,f)			\
321eb79e960Shenric 	(*(t)->f)
3225fdbebc0Sjason 
32387881ff4Sdlg /* flags for bus_space_barrier() */
32487881ff4Sdlg #define	BUS_SPACE_BARRIER_READ	0x01		/* force read barrier */
32587881ff4Sdlg #define	BUS_SPACE_BARRIER_WRITE	0x02		/* force write barrier */
32687881ff4Sdlg 
327eb79e960Shenric static inline void
32847c47feaSjsg bus_space_barrier(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
32947c47feaSjsg     bus_size_t s, int f)
330bd12f793Sart {
33187881ff4Sdlg #ifdef notyet
33287881ff4Sdlg 	switch (f) {
33387881ff4Sdlg 	case (BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE):
33427d3e2e5Sdlg 		__membar("#LoadLoad|#StoreStore");
33587881ff4Sdlg 		break;
33687881ff4Sdlg 	case BUS_SPACE_BARRIER_READ:
33727d3e2e5Sdlg 		membar("#LoadLoad");
33887881ff4Sdlg 		break;
33987881ff4Sdlg 	case BUS_SPACE_BARRIER_WRITE:
34027d3e2e5Sdlg 		membar("#StoreStore");
34187881ff4Sdlg 		break;
34287881ff4Sdlg 	default:
34387881ff4Sdlg 		break;
34487881ff4Sdlg 	}
34587881ff4Sdlg #else
34627d3e2e5Sdlg 	__membar("#Sync");
34787881ff4Sdlg #endif
348bd12f793Sart }
349bd12f793Sart 
350eb79e960Shenric #include <sparc64/sparc64/busop.h>
351bd12f793Sart 
352bd12f793Sart /* flags for bus space map functions */
353bd12f793Sart #define BUS_SPACE_MAP_CACHEABLE		0x0001
354bd12f793Sart #define BUS_SPACE_MAP_LINEAR		0x0002
355bd12f793Sart #define BUS_SPACE_MAP_READONLY		0x0004
356bd12f793Sart #define BUS_SPACE_MAP_PREFETCHABLE	0x0008
357eb79e960Shenric #define BUS_SPACE_MAP_PROMADDRESS	0x0010
358bd12f793Sart #define BUS_SPACE_MAP_BUS1	0x0100	/* placeholders for bus functions... */
359bd12f793Sart #define BUS_SPACE_MAP_BUS2	0x0200
360bd12f793Sart #define BUS_SPACE_MAP_BUS3	0x0400
361bd12f793Sart #define BUS_SPACE_MAP_BUS4	0x0800
362bd12f793Sart 
363bd12f793Sart 
364f8e9be80Skettenis /* flags for bus_intr_establish() */
365f8e9be80Skettenis #define BUS_INTR_ESTABLISH_MPSAFE	0x0001
366f8e9be80Skettenis #define BUS_INTR_ESTABLISH_SOFTINTR	0x0002
367bd12f793Sart 
368bd12f793Sart /*
369bd12f793Sart  * Flags used in various bus DMA methods.
370bd12f793Sart  */
371bdd819b7Skettenis #define	BUS_DMA_WAITOK		0x0000	/* safe to sleep (pseudo-flag) */
372bdd819b7Skettenis #define	BUS_DMA_NOWAIT		0x0001	/* not safe to sleep */
373bdd819b7Skettenis #define	BUS_DMA_ALLOCNOW	0x0002	/* perform resource allocation now */
374bdd819b7Skettenis #define	BUS_DMA_COHERENT	0x0004	/* hint: map memory DMA coherent */
375bdd819b7Skettenis #define	BUS_DMA_NOWRITE		0x0008	/* I suppose the following two should default on */
376bdd819b7Skettenis #define	BUS_DMA_BUS1		0x0010	/* placeholders for bus functions... */
377bdd819b7Skettenis #define	BUS_DMA_BUS2		0x0020
378bdd819b7Skettenis #define	BUS_DMA_BUS3		0x0040
379bdd819b7Skettenis #define	BUS_DMA_BUS4		0x0080
380bdd819b7Skettenis #define	BUS_DMA_STREAMING	0x0100	/* hint: sequential, unidirectional */
381bdd819b7Skettenis #define	BUS_DMA_READ		0x0200	/* mapping is device -> memory only */
382bdd819b7Skettenis #define	BUS_DMA_WRITE		0x0400	/* mapping is memory -> device only */
383bdd819b7Skettenis #define	BUS_DMA_ZERO		0x0800	/* zero memory in dmamem_alloc */
384bdd819b7Skettenis #define	BUS_DMA_OVERRUN		0x1000  /* tolerate DMA overruns */
385b0002153Sdlg #define	BUS_DMA_64BIT		0x2000	/* device handles 64bit dva */
386bd12f793Sart 
387bd12f793Sart #define	BUS_DMA_NOCACHE		BUS_DMA_BUS1
388bd12f793Sart #define	BUS_DMA_DVMA		BUS_DMA_BUS2	/* Don't bother with alignment */
389f40adf33Sjason #define	BUS_DMA_24BIT		BUS_DMA_BUS3	/* 24bit device */
390bd12f793Sart 
391eb79e960Shenric #define BUS_DMA_RAW	BUS_DMA_STREAMING
392eb79e960Shenric 
393bd12f793Sart /* Forwards needed by prototypes below. */
394bd12f793Sart struct mbuf;
395bd12f793Sart struct uio;
396bd12f793Sart 
397bd12f793Sart /*
398bd12f793Sart  * Operations performed by bus_dmamap_sync().
399bd12f793Sart  */
400bd12f793Sart #define	BUS_DMASYNC_PREREAD	0x01	/* pre-read synchronization */
401bd12f793Sart #define	BUS_DMASYNC_POSTREAD	0x02	/* post-read synchronization */
402bd12f793Sart #define	BUS_DMASYNC_PREWRITE	0x04	/* pre-write synchronization */
403bd12f793Sart #define	BUS_DMASYNC_POSTWRITE	0x08	/* post-write synchronization */
404bd12f793Sart 
405bd12f793Sart typedef struct sparc_bus_dma_tag	*bus_dma_tag_t;
406bd12f793Sart typedef struct sparc_bus_dmamap		*bus_dmamap_t;
407bd12f793Sart 
408bd12f793Sart /*
409bd12f793Sart  *	bus_dma_segment_t
410bd12f793Sart  *
411bd12f793Sart  *	Describes a single contiguous DMA transaction.  Values
412bd12f793Sart  *	are suitable for programming into DMA registers.
413bd12f793Sart  */
414bd12f793Sart struct sparc_bus_dma_segment {
415bd12f793Sart 	bus_addr_t	ds_addr;	/* DVMA address */
416bd12f793Sart 	bus_size_t	ds_len;		/* length of transfer */
417745b6152Shenric 	/*
418745b6152Shenric 	 * The following is to support bus_dmamem_alloc()'s
419745b6152Shenric 	 * odd interface.  Only the values in the first
420745b6152Shenric 	 * segment are used.  This means that 3/5ths of
421745b6152Shenric 	 * most segments are useless space (and mbufs use 1024
422745b6152Shenric 	 * segments).
423745b6152Shenric 	 */
424bd12f793Sart 	bus_size_t	_ds_boundary;	/* don't cross this */
425bd12f793Sart 	bus_size_t	_ds_align;	/* align to this */
426bd12f793Sart 	void		*_ds_mlist;	/* XXX - dmamap_alloc'ed pages */
427bd12f793Sart };
428bd12f793Sart typedef struct sparc_bus_dma_segment	bus_dma_segment_t;
429bd12f793Sart 
430bd12f793Sart 
431bd12f793Sart /*
432bd12f793Sart  *	bus_dma_tag_t
433bd12f793Sart  *
434bd12f793Sart  *	A machine-dependent opaque type describing the implementation of
435bd12f793Sart  *	DMA for a given bus.
436bd12f793Sart  */
437bd12f793Sart struct sparc_bus_dma_tag {
438bd12f793Sart 	void	*_cookie;		/* cookie used in the guts */
439bd12f793Sart 	struct sparc_bus_dma_tag* _parent;
440bd12f793Sart 
441bd12f793Sart 	/*
442bd12f793Sart 	 * DMA mapping methods.
443bd12f793Sart 	 */
444745b6152Shenric 	int	(*_dmamap_create)(bus_dma_tag_t, bus_dma_tag_t, bus_size_t,
445745b6152Shenric 		    int, bus_size_t, bus_size_t, int, bus_dmamap_t *);
446745b6152Shenric 	void	(*_dmamap_destroy)(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t);
447745b6152Shenric 	int	(*_dmamap_load)(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t,
448745b6152Shenric 		    void *, bus_size_t, struct proc *, int);
449745b6152Shenric 	int	(*_dmamap_load_mbuf)(bus_dma_tag_t, bus_dma_tag_t,
450745b6152Shenric 		    bus_dmamap_t, struct mbuf *, int);
451745b6152Shenric 	int	(*_dmamap_load_uio)(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t,
452c4071fd1Smillert 		    struct uio *, int);
453745b6152Shenric 	int	(*_dmamap_load_raw)(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t,
454c4071fd1Smillert 		    bus_dma_segment_t *, int, bus_size_t, int);
455745b6152Shenric 	void	(*_dmamap_unload)(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t);
456745b6152Shenric 	void	(*_dmamap_sync)(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t,
457c4071fd1Smillert 		    bus_addr_t, bus_size_t, int);
458bd12f793Sart 
459bd12f793Sart 	/*
460bd12f793Sart 	 * DMA memory utility functions.
461bd12f793Sart 	 */
462745b6152Shenric 	int	(*_dmamem_alloc)(bus_dma_tag_t, bus_dma_tag_t, bus_size_t,
463745b6152Shenric 		    bus_size_t, bus_size_t, bus_dma_segment_t *, int, int *,
464745b6152Shenric 		    int);
465745b6152Shenric 	void	(*_dmamem_free)(bus_dma_tag_t, bus_dma_tag_t,
466c4071fd1Smillert 		    bus_dma_segment_t *, int);
467745b6152Shenric 	int	(*_dmamem_map)(bus_dma_tag_t, bus_dma_tag_t,
468745b6152Shenric 		    bus_dma_segment_t *, int, size_t, caddr_t *, int);
469745b6152Shenric 	void	(*_dmamem_unmap)(bus_dma_tag_t, bus_dma_tag_t, caddr_t,
470745b6152Shenric 		    size_t);
471745b6152Shenric 	paddr_t	(*_dmamem_mmap)(bus_dma_tag_t, bus_dma_tag_t,
472745b6152Shenric 		    bus_dma_segment_t *, int, off_t, int, int);
473bd12f793Sart };
474bd12f793Sart 
475745b6152Shenric #define _BD_PRECALL(t,f)		\
476745b6152Shenric 	while (t->f == NULL) {		\
477745b6152Shenric 		t = t->_parent;		\
478745b6152Shenric 	}
479745b6152Shenric #define _BD_CALL(t,f)			\
480745b6152Shenric 	(*(t)->f)
481745b6152Shenric #define _BD_POSTCALL
482bd12f793Sart 
483745b6152Shenric static inline int
484745b6152Shenric bus_dmamap_create(bus_dma_tag_t t, bus_size_t s, int n, bus_size_t m,
485745b6152Shenric     bus_size_t b, int f, bus_dmamap_t *p)
486745b6152Shenric {
487745b6152Shenric 	int r;
488745b6152Shenric 	const bus_dma_tag_t t0 = t;
489745b6152Shenric 	_BD_PRECALL(t, _dmamap_create);
490745b6152Shenric 	r = _BD_CALL(t, _dmamap_create)(t, t0, s, n, m, b, f, p);
491745b6152Shenric 	_BD_POSTCALL;
492745b6152Shenric 	return (r);
493745b6152Shenric }
494745b6152Shenric static inline void
495745b6152Shenric bus_dmamap_destroy(bus_dma_tag_t t, bus_dmamap_t p)
496745b6152Shenric {
497745b6152Shenric 	const bus_dma_tag_t t0 = t;
498745b6152Shenric 	_BD_PRECALL(t, _dmamap_destroy);
499745b6152Shenric 	_BD_CALL(t, _dmamap_destroy)(t, t0, p);
500745b6152Shenric 	_BD_POSTCALL;
501745b6152Shenric }
502745b6152Shenric static inline int
503745b6152Shenric bus_dmamap_load(bus_dma_tag_t t, bus_dmamap_t m, void *b, bus_size_t s,
504745b6152Shenric     struct proc *p, int f)
505745b6152Shenric {
506745b6152Shenric 	const bus_dma_tag_t t0 = t;
507745b6152Shenric 	int r;
508745b6152Shenric 	_BD_PRECALL(t, _dmamap_load);
509745b6152Shenric 	r = _BD_CALL(t, _dmamap_load)(t, t0, m, b, s, p, f);
510745b6152Shenric 	_BD_POSTCALL;
511745b6152Shenric 	return (r);
512745b6152Shenric }
513745b6152Shenric static inline int
514745b6152Shenric bus_dmamap_load_mbuf(bus_dma_tag_t t, bus_dmamap_t m, struct mbuf *b,
515745b6152Shenric     int f)
516745b6152Shenric {
517745b6152Shenric 	const bus_dma_tag_t t0 = t;
518745b6152Shenric 	int r;
519745b6152Shenric 	_BD_PRECALL(t, _dmamap_load_mbuf);
520745b6152Shenric 	r = _BD_CALL(t, _dmamap_load_mbuf)(t, t0, m, b, f);
521745b6152Shenric 	_BD_POSTCALL;
522745b6152Shenric 	return (r);
523745b6152Shenric }
524745b6152Shenric static inline int
525745b6152Shenric bus_dmamap_load_uio(bus_dma_tag_t t, bus_dmamap_t m, struct uio * u, int f)
526745b6152Shenric {
527745b6152Shenric 	const bus_dma_tag_t t0 = t;
528745b6152Shenric 	int r;
529745b6152Shenric 	_BD_PRECALL(t, _dmamap_load_uio);
530745b6152Shenric 	r = _BD_CALL(t, _dmamap_load_uio)(t, t0, m, u, f);
531745b6152Shenric 	_BD_POSTCALL;
532745b6152Shenric 	return (r);
533745b6152Shenric }
534745b6152Shenric static inline int
535745b6152Shenric bus_dmamap_load_raw(bus_dma_tag_t t, bus_dmamap_t m, bus_dma_segment_t *sg,
536745b6152Shenric     int n, bus_size_t s, int f)
537745b6152Shenric {
538745b6152Shenric 	const bus_dma_tag_t t0 = t;
539745b6152Shenric 	int r;
540745b6152Shenric 	_BD_PRECALL(t, _dmamap_load_raw);
541745b6152Shenric 	r = _BD_CALL(t, _dmamap_load_raw)(t, t0, m, sg, n, s, f);
542745b6152Shenric 	_BD_POSTCALL;
543745b6152Shenric 	return (r);
544745b6152Shenric }
545745b6152Shenric static inline void
546745b6152Shenric bus_dmamap_unload(bus_dma_tag_t t, bus_dmamap_t p)
547745b6152Shenric {
548745b6152Shenric 	const bus_dma_tag_t t0 = t;
549745b6152Shenric 	_BD_PRECALL(t, _dmamap_unload);
550745b6152Shenric 	_BD_CALL(t, _dmamap_unload)(t, t0, p);
551745b6152Shenric 	_BD_POSTCALL;
552745b6152Shenric }
553745b6152Shenric static inline void
554745b6152Shenric bus_dmamap_sync(bus_dma_tag_t t, bus_dmamap_t p, bus_addr_t o, bus_size_t l,
555745b6152Shenric     int ops)
556745b6152Shenric {
557745b6152Shenric 	const bus_dma_tag_t t0 = t;
558745b6152Shenric 	_BD_PRECALL(t, _dmamap_sync);
559745b6152Shenric 	_BD_CALL(t, _dmamap_sync)(t, t0, p, o, l, ops);
560745b6152Shenric 	_BD_POSTCALL;
561745b6152Shenric }
562745b6152Shenric static inline int
563745b6152Shenric bus_dmamem_alloc(bus_dma_tag_t t, bus_size_t s, bus_size_t a, bus_size_t b,
564745b6152Shenric     bus_dma_segment_t *sg, int n, int *r, int f)
565745b6152Shenric {
566745b6152Shenric 	const bus_dma_tag_t t0 = t;
567745b6152Shenric 	int ret;
568745b6152Shenric 	_BD_PRECALL(t, _dmamem_alloc);
569745b6152Shenric 	ret = _BD_CALL(t, _dmamem_alloc)(t, t0, s, a, b, sg, n, r, f);
570745b6152Shenric 	_BD_POSTCALL;
571745b6152Shenric 	return (ret);
572745b6152Shenric }
573745b6152Shenric static inline void
574745b6152Shenric bus_dmamem_free(bus_dma_tag_t t, bus_dma_segment_t *sg, int n)
575745b6152Shenric {
576745b6152Shenric 	const bus_dma_tag_t t0 = t;
577745b6152Shenric 	_BD_PRECALL(t, _dmamem_free);
578745b6152Shenric 	_BD_CALL(t, _dmamem_free)(t, t0, sg, n);
579745b6152Shenric 	_BD_POSTCALL;
580745b6152Shenric }
581745b6152Shenric static inline int
582745b6152Shenric bus_dmamem_map(bus_dma_tag_t t, bus_dma_segment_t *sg, int n, size_t s,
583745b6152Shenric     caddr_t *k, int f)
584745b6152Shenric {
585745b6152Shenric 	const bus_dma_tag_t t0 = t;
586745b6152Shenric 	int r;
587745b6152Shenric 	_BD_PRECALL(t, _dmamem_map);
588745b6152Shenric 	r = _BD_CALL(t, _dmamem_map)(t, t0, sg, n, s, k, f);
589745b6152Shenric 	_BD_POSTCALL;
590745b6152Shenric 	return (r);
591745b6152Shenric }
592745b6152Shenric static inline void
593745b6152Shenric bus_dmamem_unmap(bus_dma_tag_t t, caddr_t k, size_t s)
594745b6152Shenric {
595745b6152Shenric 	const bus_dma_tag_t t0 = t;
596745b6152Shenric 	_BD_PRECALL(t, _dmamem_unmap);
597745b6152Shenric 	_BD_CALL(t, _dmamem_unmap)(t, t0, k, s);
598745b6152Shenric 	_BD_POSTCALL;
599745b6152Shenric }
600745b6152Shenric static inline paddr_t
601745b6152Shenric bus_dmamem_mmap(bus_dma_tag_t t, bus_dma_segment_t *sg, int n, off_t o, int p,
602745b6152Shenric     int f)
603745b6152Shenric {
604745b6152Shenric 	const bus_dma_tag_t t0 = t;
605745b6152Shenric 	int r;
606745b6152Shenric 	_BD_PRECALL(t, _dmamem_mmap);
607745b6152Shenric 	r = _BD_CALL(t, _dmamem_mmap)(t, t0, sg, n, o, p, f);
608745b6152Shenric 	_BD_POSTCALL;
609745b6152Shenric 	return (r);
610745b6152Shenric }
611bd12f793Sart 
612bd12f793Sart /*
613bd12f793Sart  *	bus_dmamap_t
614bd12f793Sart  *
615bd12f793Sart  *	Describes a DMA mapping.
616bd12f793Sart  */
617bd12f793Sart struct sparc_bus_dmamap {
618bd12f793Sart 	/*
6195cdd493aSjason 	 * PRIVATE MEMBERS: not for use by machine-independent code.
620bd12f793Sart 	 */
6215cdd493aSjason 	bus_addr_t	_dm_dvmastart;	/* start and size of allocated */
6225cdd493aSjason 	bus_size_t	_dm_dvmasize;	/* DVMA segment for this map */
6235cdd493aSjason 
624bd12f793Sart 	bus_size_t	_dm_size;	/* largest DMA transfer mappable */
625bd12f793Sart 	bus_size_t	_dm_maxsegsz;	/* largest possible segment */
626bd12f793Sart 	bus_size_t	_dm_boundary;	/* don't cross this */
627bd12f793Sart 	int		_dm_segcnt;	/* number of segs this map can map */
628bd12f793Sart 	int		_dm_flags;	/* misc. flags */
629bd12f793Sart #define _DM_TYPE_LOAD	0
630bd12f793Sart #define _DM_TYPE_SEGS	1
631bd12f793Sart #define _DM_TYPE_UIO	2
632bd12f793Sart #define _DM_TYPE_MBUF	3
633745b6152Shenric 	int		_dm_type;	/* mapping type: raw, uio, mbuf, etc */
634745b6152Shenric 	void		*_dm_source;	/* source mbuf/uio/etc. for unload */
635bd12f793Sart 
636bd12f793Sart 	void		*_dm_cookie;	/* cookie for bus-specific functions */
637bd12f793Sart 
638bd12f793Sart 	/*
639bd12f793Sart 	 * PUBLIC MEMBERS: these are used by machine-independent code.
640bd12f793Sart 	 */
641bd12f793Sart 	bus_size_t	dm_mapsize;	/* size of the mapping */
642bd12f793Sart 	int		dm_nsegs;	/* # valid segments in mapping */
643745b6152Shenric 
644bd12f793Sart 	bus_dma_segment_t dm_segs[1];	/* segments; variable length */
645bd12f793Sart };
646bd12f793Sart 
647f56b290dSderaadt #endif /* _KERNEL */
648f56b290dSderaadt 
6492fa72412Spirofti #endif /* _MACHINE_BUS_H_ */
650eb79e960Shenric 
651