xref: /netbsd/sys/arch/ews4800mips/include/bus.h (revision 8a06b90d)
1 /*	$NetBSD: bus.h,v 1.8 2019/09/23 16:17:55 skrll Exp $	*/
2 
3 /*-
4  * Copyright (c) 1997, 1998, 2000, 2001, 2005 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  *
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.
31  */
32 
33 /*
34  * Copyright (c) 1996 Carnegie-Mellon University.
35  * All rights reserved.
36  *
37  * Author: Chris G. Demetriou
38  *
39  * Permission to use, copy, modify and distribute this software and
40  * its documentation is hereby granted, provided that both the copyright
41  * notice and this permission notice appear in all copies of the
42  * software, derivative works or modified versions, and any portions
43  * thereof, and that both notices appear in supporting documentation.
44  *
45  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
46  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
47  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
48  *
49  * Carnegie Mellon requests users of this software to return to
50  *
51  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
52  *  School of Computer Science
53  *  Carnegie Mellon University
54  *  Pittsburgh PA 15213-3890
55  *
56  * any improvements or extensions that they make and grant Carnegie the
57  * rights to redistribute these changes.
58  */
59 
60 #ifndef _EWS4800MIPS_BUS_H_
61 #define	_EWS4800MIPS_BUS_H_
62 
63 #include <sys/types.h>
64 #ifdef _KERNEL
65 /*
66  * Turn on BUS_SPACE_DEBUG if the global DEBUG option is enabled.
67  */
68 #if defined(DEBUG) && !defined(BUS_SPACE_DEBUG)
69 #define	BUS_SPACE_DEBUG
70 #endif
71 
72 #ifdef BUS_SPACE_DEBUG
73 #include <sys/systm.h> /* for printf() prototype */
74 /*
75  * Macros for checking the aligned-ness of pointers passed to bus
76  * space ops.  Strict alignment is required by the MIPS architecture,
77  * and a trap will occur if unaligned access is performed.  These
78  * may aid in the debugging of a broken device driver by displaying
79  * useful information about the problem.
80  */
81 #define	__BUS_SPACE_ALIGNED_ADDRESS(p, t)				\
82 	((((uint32_t)(p)) & (sizeof(t)-1)) == 0)
83 
84 #define	__BUS_SPACE_ADDRESS_SANITY(p, t, d)				\
85 ({									\
86 	if (__BUS_SPACE_ALIGNED_ADDRESS((p), t) == 0) {			\
87 		printf("%s 0x%x not aligned to %u bytes %s:%d\n",	\
88 		    d, (uint32_t)(p), (uint32_t)sizeof(t), __FILE__,	\
89 		    __LINE__);						\
90 	}								\
91 	(void) 0;							\
92 })
93 
94 #define	BUS_SPACE_ALIGNED_POINTER(p, t) __BUS_SPACE_ALIGNED_ADDRESS(p, t)
95 #else
96 #define	__BUS_SPACE_ADDRESS_SANITY(p, t, d)	(void) 0
97 #define	BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t)
98 #endif /* BUS_SPACE_DEBUG */
99 #endif /* _KERNEL */
100 
101 /*
102  * Addresses (in bus space).
103  */
104 typedef long bus_addr_t;
105 typedef long bus_size_t;
106 
107 #define PRIxBUSADDR	"lx"
108 #define PRIxBUSSIZE	"lx"
109 #define PRIuBUSSIZE	"lu"
110 /*
111  * Access methods for bus space.
112  */
113 typedef struct ews4800mips_bus_space *bus_space_tag_t;
114 typedef bus_addr_t bus_space_handle_t;
115 
116 #define PRIxBSH		PRIxBUSADDR
117 
118 struct extent; /* forward declaration */
119 
120 struct ews4800mips_bus_space {
121 	struct extent	*ebs_extent;
122 	bus_addr_t	ebs_base_addr;
123 	bus_size_t	ebs_size;
124 
125 	/* cookie */
126 	void		*ebs_cookie;
127 
128 	/* mapping/unmapping */
129 	int		(*ebs_map)(void *, bus_addr_t, bus_size_t,
130 			    int, bus_space_handle_t *);
131 	void		(*ebs_unmap)(void *, bus_space_handle_t,
132 			    bus_size_t);
133 	int		(*ebs_subregion)(void *, bus_space_handle_t,
134 			    bus_size_t, bus_size_t, bus_space_handle_t *);
135 
136 	/* allocation/deallocation */
137 	int		(*ebs_alloc)(void *, bus_addr_t, bus_addr_t,
138 			    bus_size_t, bus_size_t, bus_size_t, int,
139 			    bus_addr_t *, bus_space_handle_t *);
140 	void		(*ebs_free)(void *, bus_space_handle_t,
141 			    bus_size_t);
142 
143 	/* get kernel virtual address */
144 	void *		(*ebs_vaddr)(void *, bus_space_handle_t);
145 
146 	/* read (single) */
147 	uint8_t		(*ebs_r_1)(void *, bus_space_handle_t,
148 			    bus_size_t);
149 	uint16_t	(*ebs_r_2)(void *, bus_space_handle_t,
150 			    bus_size_t);
151 	uint32_t	(*ebs_r_4)(void *, bus_space_handle_t,
152 			    bus_size_t);
153 	uint64_t	(*ebs_r_8)(void *, bus_space_handle_t,
154 			    bus_size_t);
155 
156 	/* read multiple */
157 	void		(*ebs_rm_1)(void *, bus_space_handle_t,
158 			    bus_size_t, uint8_t *, bus_size_t);
159 	void		(*ebs_rm_2)(void *, bus_space_handle_t,
160 			    bus_size_t, uint16_t *, bus_size_t);
161 	void		(*ebs_rm_4)(void *, bus_space_handle_t,
162 			    bus_size_t, uint32_t *, bus_size_t);
163 	void		(*ebs_rm_8)(void *, bus_space_handle_t,
164 			    bus_size_t, uint64_t *, bus_size_t);
165 
166 	/* read region */
167 	void		(*ebs_rr_1)(void *, bus_space_handle_t,
168 			    bus_size_t, uint8_t *, bus_size_t);
169 	void		(*ebs_rr_2)(void *, bus_space_handle_t,
170 			    bus_size_t, uint16_t *, bus_size_t);
171 	void		(*ebs_rr_4)(void *, bus_space_handle_t,
172 			    bus_size_t, uint32_t *, bus_size_t);
173 	void		(*ebs_rr_8)(void *, bus_space_handle_t,
174 			    bus_size_t, uint64_t *, bus_size_t);
175 
176 	/* write (single) */
177 	void		(*ebs_w_1)(void *, bus_space_handle_t,
178 			    bus_size_t, uint8_t);
179 	void		(*ebs_w_2)(void *, bus_space_handle_t,
180 			    bus_size_t, uint16_t);
181 	void		(*ebs_w_4)(void *, bus_space_handle_t,
182 			    bus_size_t, uint32_t);
183 	void		(*ebs_w_8)(void *, bus_space_handle_t,
184 			    bus_size_t, uint64_t);
185 
186 	/* write multiple */
187 	void		(*ebs_wm_1)(void *, bus_space_handle_t,
188 			    bus_size_t, const uint8_t *, bus_size_t);
189 	void		(*ebs_wm_2)(void *, bus_space_handle_t,
190 			    bus_size_t, const uint16_t *, bus_size_t);
191 	void		(*ebs_wm_4)(void *, bus_space_handle_t,
192 			    bus_size_t, const uint32_t *, bus_size_t);
193 	void		(*ebs_wm_8)(void *, bus_space_handle_t,
194 			    bus_size_t, const uint64_t *, bus_size_t);
195 
196 	/* write region */
197 	void		(*ebs_wr_1)(void *, bus_space_handle_t,
198 			    bus_size_t, const uint8_t *, bus_size_t);
199 	void		(*ebs_wr_2)(void *, bus_space_handle_t,
200 			    bus_size_t, const uint16_t *, bus_size_t);
201 	void		(*ebs_wr_4)(void *, bus_space_handle_t,
202 			    bus_size_t, const uint32_t *, bus_size_t);
203 	void		(*ebs_wr_8)(void *, bus_space_handle_t,
204 			    bus_size_t, const uint64_t *, bus_size_t);
205 
206 	/* set multiple */
207 	void		(*ebs_sm_1)(void *, bus_space_handle_t,
208 			    bus_size_t, uint8_t, bus_size_t);
209 	void		(*ebs_sm_2)(void *, bus_space_handle_t,
210 			    bus_size_t, uint16_t, bus_size_t);
211 	void		(*ebs_sm_4)(void *, bus_space_handle_t,
212 			    bus_size_t, uint32_t, bus_size_t);
213 	void		(*ebs_sm_8)(void *, bus_space_handle_t,
214 			    bus_size_t, uint64_t, bus_size_t);
215 
216 	/* set region */
217 	void		(*ebs_sr_1)(void *, bus_space_handle_t,
218 			    bus_size_t, uint8_t, bus_size_t);
219 	void		(*ebs_sr_2)(void *, bus_space_handle_t,
220 			    bus_size_t, uint16_t, bus_size_t);
221 	void		(*ebs_sr_4)(void *, bus_space_handle_t,
222 			    bus_size_t, uint32_t, bus_size_t);
223 	void		(*ebs_sr_8)(void *, bus_space_handle_t,
224 			    bus_size_t, uint64_t, bus_size_t);
225 
226 	/* copy */
227 	void		(*ebs_c_1)(void *, bus_space_handle_t, bus_size_t,
228 			    bus_space_handle_t, bus_size_t, bus_size_t);
229 	void		(*ebs_c_2)(void *, bus_space_handle_t, bus_size_t,
230 			    bus_space_handle_t, bus_size_t, bus_size_t);
231 	void		(*ebs_c_4)(void *, bus_space_handle_t, bus_size_t,
232 			    bus_space_handle_t, bus_size_t, bus_size_t);
233 	void		(*ebs_c_8)(void *, bus_space_handle_t, bus_size_t,
234 			    bus_space_handle_t, bus_size_t, bus_size_t);
235 };
236 
237 #ifdef _KERNEL
238 #ifdef _EWS4800MIPS_BUS_SPACE_PRIVATE
239 
240 #ifndef __read_1
241 #define	__read_1(a)	(*(volatile uint8_t *)(a))
242 #endif
243 #ifndef __read_2
244 #define	__read_2(a)	(*(volatile uint16_t *)(a))
245 #endif
246 #ifndef __read_4
247 #define	__read_4(a)	(*(volatile uint32_t *)(a))
248 #endif
249 #ifndef __read_8
250 #define	__read_8(a)	(*(volatile uint64_t *)(a))
251 #endif
252 #define	__read_16(a)	"error. not yet"
253 
254 #ifndef __write_1
255 #define	__write_1(a, v) {						\
256 	*(volatile uint8_t *)(a) = (v);				\
257 	wbflush();							\
258 }
259 #endif
260 #ifndef __write_2
261 #define	__write_2(a, v)	{						\
262 	*(volatile uint16_t *)(a) = (v);				\
263 	wbflush();							\
264 }
265 #endif
266 #ifndef __write_4
267 #define	__write_4(a, v)	{						\
268 	*(volatile uint32_t *)(a) = (v);				\
269 	wbflush();							\
270 }
271 #endif
272 #ifndef __write_8
273 #define	__write_8(a, v) {						\
274 	*(volatile uint64_t *)(a) = (v);				\
275 	wbflush();							\
276 }
277 #endif
278 
279 #define	__TYPENAME(BITS)	uint##BITS##_t
280 
281 #define	_BUS_SPACE_READ(PREFIX, BYTES, BITS)				\
282 static __TYPENAME(BITS)							\
283 PREFIX##_read_##BYTES(void *, bus_space_handle_t,  bus_size_t);		\
284 static __TYPENAME(BITS)							\
285 PREFIX##_read_##BYTES(void *tag, bus_space_handle_t bsh,		\
286     bus_size_t offset)							\
287 {									\
288 	return __read_##BYTES(VADDR(bsh, offset));			\
289 }
290 
291 #define	_BUS_SPACE_READ_MULTI(PREFIX, BYTES, BITS)			\
292 static void								\
293 PREFIX##_read_multi_##BYTES(void *, bus_space_handle_t,	bus_size_t,	\
294     __TYPENAME(BITS) *,	bus_size_t);					\
295 static void								\
296 PREFIX##_read_multi_##BYTES(void *tag, bus_space_handle_t bsh,		\
297     bus_size_t offset, __TYPENAME(BITS) *addr, bus_size_t count)	\
298 {									\
299 	bus_addr_t a = VADDR(bsh, offset);				\
300 	while (count--)							\
301 		*addr++ = __read_##BYTES(a);				\
302 }
303 
304 #define	_BUS_SPACE_READ_REGION(PREFIX, BYTES, BITS)			\
305 static void								\
306 PREFIX##_read_region_##BYTES(void *, bus_space_handle_t, bus_size_t,	\
307     __TYPENAME(BITS) *, bus_size_t);					\
308 static void								\
309 PREFIX##_read_region_##BYTES(void *tag, bus_space_handle_t bsh,		\
310     bus_size_t offset, __TYPENAME(BITS) *addr, bus_size_t count)	\
311 {									\
312 	while (count--) {						\
313 		*addr++ = __read_##BYTES(VADDR(bsh, offset));		\
314 		offset += BYTES;					\
315 	}								\
316 }
317 
318 #define	_BUS_SPACE_WRITE(PREFIX, BYTES, BITS)				\
319 static void								\
320 PREFIX##_write_##BYTES(void *, bus_space_handle_t, bus_size_t,		\
321     __TYPENAME(BITS));							\
322 static void								\
323 PREFIX##_write_##BYTES(void *tag, bus_space_handle_t bsh,		\
324     bus_size_t offset, __TYPENAME(BITS) value)				\
325 {									\
326 	__write_##BYTES(VADDR(bsh, offset), value);			\
327 }
328 
329 #define	_BUS_SPACE_WRITE_MULTI(PREFIX, BYTES, BITS)			\
330 static void								\
331 PREFIX##_write_multi_##BYTES(void *, bus_space_handle_t, bus_size_t,	\
332     const __TYPENAME(BITS) *, bus_size_t);				\
333 static void								\
334 PREFIX##_write_multi_##BYTES(void *tag, bus_space_handle_t bsh,		\
335     bus_size_t offset, const __TYPENAME(BITS) *addr, bus_size_t count)	\
336 {									\
337 	bus_addr_t a = VADDR(bsh, offset);				\
338 	while (count--) {						\
339 		__write_##BYTES(a, *addr++);				\
340 	}								\
341 }
342 
343 #define	_BUS_SPACE_WRITE_REGION(PREFIX, BYTES, BITS)			\
344 static void								\
345 PREFIX##_write_region_##BYTES(void *, bus_space_handle_t, bus_size_t,	\
346     const __TYPENAME(BITS) *, bus_size_t);				\
347 static void								\
348 PREFIX##_write_region_##BYTES(void *tag, bus_space_handle_t bsh,	\
349     bus_size_t offset, const __TYPENAME(BITS) *addr, bus_size_t count)	\
350 {									\
351 	while (count--) {						\
352 		__write_##BYTES(VADDR(bsh, offset), *addr++);		\
353 		offset += BYTES;					\
354 	}								\
355 }
356 
357 #define	_BUS_SPACE_SET_MULTI(PREFIX, BYTES, BITS)			\
358 static void								\
359 PREFIX##_set_multi_##BYTES(void *, bus_space_handle_t, bus_size_t,	\
360     __TYPENAME(BITS), bus_size_t);					\
361 static void								\
362 PREFIX##_set_multi_##BYTES(void *tag, bus_space_handle_t bsh,		\
363     bus_size_t offset, __TYPENAME(BITS) value, bus_size_t count)	\
364 {									\
365 	bus_addr_t a = VADDR(bsh, offset);				\
366 	while (count--) {						\
367 		__write_##BYTES(a, value);				\
368 	}								\
369 }
370 
371 #define	_BUS_SPACE_SET_REGION(PREFIX, BYTES, BITS)			\
372 static void								\
373 PREFIX##_set_region_##BYTES(void *, bus_space_handle_t, bus_size_t,	\
374     __TYPENAME(BITS), bus_size_t);					\
375 static void								\
376 PREFIX##_set_region_##BYTES(void *tag, bus_space_handle_t bsh,		\
377     bus_size_t offset, __TYPENAME(BITS) value, bus_size_t count)	\
378 {									\
379 	while (count--) {						\
380 		__write_##BYTES(VADDR(bsh, offset), value);		\
381 		offset += BYTES;					\
382 	}								\
383 }
384 
385 #define	_BUS_SPACE_COPY_REGION(PREFIX, BYTES, BITS)			\
386 static void								\
387 PREFIX##_copy_region_##BYTES(void *, bus_space_handle_t, bus_size_t,	\
388     bus_space_handle_t, bus_size_t, bus_size_t);			\
389 static void								\
390 PREFIX##_copy_region_##BYTES(void *t, bus_space_handle_t h1,		\
391     bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c)	\
392 {									\
393 	bus_size_t o;							\
394 	if ((h1 + o1) >= (h2 + o2)) {					\
395 		/* src after dest: copy forward */			\
396 		for (o = 0; c != 0; c--, o += BYTES)			\
397 			__write_##BYTES(VADDR(h2, o2 + o),		\
398 			    __read_##BYTES(VADDR(h1, o1 + o)));	\
399 	} else {							\
400 		/* dest after src: copy backwards */			\
401 		for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES)	\
402 			__write_##BYTES(VADDR(h2, o2 + o),		\
403 			    __read_##BYTES(VADDR(h1, o1 + o)));	\
404 	}								\
405 }
406 
407 #define	_BUS_SPACE_NO_MAP						\
408 	(int (*)(void *, bus_addr_t, bus_size_t, int,			\
409 	bus_space_handle_t *))_bus_space_invalid_access
410 #define	_BUS_SPACE_NO_UNMAP						\
411 	(void (*)(void *, bus_space_handle_t, bus_size_t))		\
412 	_bus_space_invalid_access
413 #define	_BUS_SPACE_NO_SUBREGION						\
414 	(int (*)(void *, bus_space_handle_t, bus_size_t, bus_size_t,	\
415 	bus_space_handle_t *))_bus_space_invalid_access
416 #define	_BUS_SPACE_NO_ALLOC						\
417 	(int (*)(void *, bus_addr_t, bus_addr_t, bus_size_t, bus_size_t,\
418 	 bus_size_t, int, bus_addr_t *,	bus_space_handle_t *))		\
419 	_bus_space_invalid_access
420 #define	_BUS_SPACE_NO_FREE						\
421 	(void (*)(void *, bus_space_handle_t, bus_size_t))		\
422 	_bus_space_invalid_access
423 #define	_BUS_SPACE_NO_VADDR						\
424 	(void *(*)(void *, bus_space_handle_t))_bus_space_invalid_access
425 #define	_BUS_SPACE_NO_READ(BYTES, BITS)					\
426 	(uint##BITS##_t (*)(void *, bus_space_handle_t, bus_size_t))	\
427 	_bus_space_invalid_access
428 #define	_BUS_SPACE_NO_READ_MULTI(BYTES, BITS)				\
429 	(void (*)(void *, bus_space_handle_t, bus_size_t,		\
430 	uint##BITS##_t *, bus_size_t))_bus_space_invalid_access
431 #define	_BUS_SPACE_NO_READ_REGION(BYTES, BITS)				\
432 	(void (*)(void *, bus_space_handle_t, bus_size_t,		\
433 	uint##BITS##_t *, bus_size_t))_bus_space_invalid_access
434 #define	_BUS_SPACE_NO_WRITE(BYTES, BITS)				\
435 	(void (*)(void *, bus_space_handle_t, bus_size_t,		\
436 	uint##BITS##_t))_bus_space_invalid_access
437 #define	_BUS_SPACE_NO_WRITE_MULTI(BYTES, BITS)				\
438 	(void (*)(void *, bus_space_handle_t, bus_size_t,		\
439 	const uint##BITS##_t *, bus_size_t))_bus_space_invalid_access
440 #define	_BUS_SPACE_NO_WRITE_REGION(BYTES, BITS)				\
441 	(void (*)(void *, bus_space_handle_t, bus_size_t,		\
442 	const uint##BITS##_t *, bus_size_t))_bus_space_invalid_access
443 #define	_BUS_SPACE_NO_SET_MULTI(BYTES, BITS)				\
444 	(void (*)(void *, bus_space_handle_t, bus_size_t,		\
445 	uint##BITS##_t, bus_size_t))_bus_space_invalid_access
446 #define	_BUS_SPACE_NO_SET_REGION(BYTES, BITS)				\
447 	(void (*)(void *, bus_space_handle_t, bus_size_t,		\
448 	uint##BITS##_t, bus_size_t))_bus_space_invalid_access
449 #define	_BUS_SPACE_NO_COPY_REGION(BYTES, BITS)				\
450 	(void (*)(void *, bus_space_handle_t, bus_size_t,		\
451 	bus_space_handle_t, bus_size_t, bus_size_t))_bus_space_invalid_access
452 
453 void _bus_space_invalid_access(void);
454 #endif /* _EWS4800MIPS_BUS_SPACE_PRIVATE */
455 
456 #define	__ebs_c(a,b)		__CONCAT(a,b)
457 #define	__ebs_opname(op,size)	__ebs_c(__ebs_c(__ebs_c(ebs_,op),_),size)
458 
459 #define	__ebs_rs(sz, tn, t, h, o)					\
460 	(__BUS_SPACE_ADDRESS_SANITY((h) + (o), tn, "bus addr"),		\
461 	 (*(t)->__ebs_opname(r,sz))((t)->ebs_cookie, h, o))
462 
463 #define	__ebs_ws(sz, tn, t, h, o, v)					\
464 ({									\
465 	__BUS_SPACE_ADDRESS_SANITY((h) + (o), tn, "bus addr");		\
466 	(*(t)->__ebs_opname(w,sz))((t)->ebs_cookie, h, o, v);		\
467 })
468 
469 #define	__ebs_nonsingle(type, sz, tn, t, h, o, a, c)			\
470 ({									\
471 	__BUS_SPACE_ADDRESS_SANITY((a), tn, "buffer");			\
472 	__BUS_SPACE_ADDRESS_SANITY((h) + (o), tn, "bus addr");		\
473 	(*(t)->__ebs_opname(type,sz))((t)->ebs_cookie, h, o, a, c);	\
474 })
475 
476 #define	__ebs_set(type, sz, tn, t, h, o, v, c)				\
477 ({									\
478 	__BUS_SPACE_ADDRESS_SANITY((h) + (o), tn, "bus addr");		\
479 	(*(t)->__ebs_opname(type,sz))((t)->ebs_cookie, h, o, v, c);	\
480 })
481 
482 #define	__ebs_copy(sz, tn, t, h1, o1, h2, o2, cnt)			\
483 ({									\
484 	__BUS_SPACE_ADDRESS_SANITY((h1) + (o1), tn, "bus addr 1");	\
485 	__BUS_SPACE_ADDRESS_SANITY((h2) + (o2), tn, "bus addr 2");	\
486 	(*(t)->__ebs_opname(c,sz))((t)->ebs_cookie, h1, o1, h2, o2, cnt); \
487 })
488 
489 /*
490  * Create/destroy default bus_space tag.
491  */
492 int bus_space_create(bus_space_tag_t, const char *, bus_addr_t, bus_size_t);
493 void bus_space_destroy(bus_space_tag_t);
494 
495 /*
496  * Mapping and unmapping operations.
497  */
498 #define	bus_space_map(t, a, s, f, hp)					\
499 	(*(t)->ebs_map)((t)->ebs_cookie, (a), (s), (f), (hp))
500 #define	bus_space_unmap(t, h, s)					\
501 	(*(t)->ebs_unmap)((t)->ebs_cookie, (h), (s))
502 #define	bus_space_subregion(t, h, o, s, hp)				\
503 	(*(t)->ebs_subregion)((t)->ebs_cookie, (h), (o), (s), (hp))
504 
505 #endif /* _KERNEL */
506 
507 #define	BUS_SPACE_MAP_CACHEABLE		0x01
508 #define	BUS_SPACE_MAP_LINEAR		0x02
509 #define	BUS_SPACE_MAP_PREFETCHABLE     	0x04
510 
511 #ifdef _KERNEL
512 /*
513  * Allocation and deallocation operations.
514  */
515 #define	bus_space_alloc(t, rs, re, s, a, b, f, ap, hp)			\
516 	(*(t)->ebs_alloc)((t)->ebs_cookie, (rs), (re), (s), (a), (b),	\
517 	    (f), (ap), (hp))
518 #define	bus_space_free(t, h, s)						\
519 	(*(t)->ebs_free)((t)->ebs_cookie, (h), (s))
520 
521 /*
522  * Get kernel virtual address for ranges mapped BUS_SPACE_MAP_LINEAR.
523  */
524 #define	bus_space_vaddr(t, h)						\
525 	(*(t)->ebs_vaddr)((t)->ebs_cookie, (h))
526 
527 /*
528  * Bus read/write barrier methods.
529  *
530  *	void bus_space_barrier(bus_space_tag_t tag,
531  *	    bus_space_handle_t bsh, bus_size_t offset,
532  *	    bus_size_t len, int flags);
533  *
534  * On the MIPS, we just flush the write buffer.
535  */
536 #define	bus_space_barrier(t, h, o, l, f)				\
537 	((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f),	\
538 	 wbflush()))
539 #define	BUS_SPACE_BARRIER_READ	0x01
540 #define	BUS_SPACE_BARRIER_WRITE	0x02
541 
542 
543 /*
544  * Bus read (single) operations.
545  */
546 #define	bus_space_read_1(t, h, o)	__ebs_rs(1,uint8_t,(t),(h),(o))
547 #define	bus_space_read_2(t, h, o)	__ebs_rs(2,uint16_t,(t),(h),(o))
548 #define	bus_space_read_4(t, h, o)	__ebs_rs(4,uint32_t,(t),(h),(o))
549 #define	bus_space_read_8(t, h, o)	__ebs_rs(8,uint64_t,(t),(h),(o))
550 
551 
552 /*
553  * Bus read multiple operations.
554  */
555 #define	bus_space_read_multi_1(t, h, o, a, c)				\
556 	__ebs_nonsingle(rm,1,uint8_t,(t),(h),(o),(a),(c))
557 #define	bus_space_read_multi_2(t, h, o, a, c)				\
558 	__ebs_nonsingle(rm,2,uint16_t,(t),(h),(o),(a),(c))
559 #define	bus_space_read_multi_4(t, h, o, a, c)				\
560 	__ebs_nonsingle(rm,4,uint32_t,(t),(h),(o),(a),(c))
561 #define	bus_space_read_multi_8(t, h, o, a, c)				\
562 	__ebs_nonsingle(rm,8,uint64_t,(t),(h),(o),(a),(c))
563 
564 
565 /*
566  * Bus read region operations.
567  */
568 #define	bus_space_read_region_1(t, h, o, a, c)				\
569 	__ebs_nonsingle(rr,1,uint8_t,(t),(h),(o),(a),(c))
570 #define	bus_space_read_region_2(t, h, o, a, c)				\
571 	__ebs_nonsingle(rr,2,uint16_t,(t),(h),(o),(a),(c))
572 #define	bus_space_read_region_4(t, h, o, a, c)				\
573 	__ebs_nonsingle(rr,4,uint32_t,(t),(h),(o),(a),(c))
574 #define	bus_space_read_region_8(t, h, o, a, c)				\
575 	__ebs_nonsingle(rr,8,uint64_t,(t),(h),(o),(a),(c))
576 
577 
578 /*
579  * Bus write (single) operations.
580  */
581 #define	bus_space_write_1(t, h, o, v)	__ebs_ws(1,uint8_t,(t),(h),(o),(v))
582 #define	bus_space_write_2(t, h, o, v)	__ebs_ws(2,uint16_t,(t),(h),(o),(v))
583 #define	bus_space_write_4(t, h, o, v)	__ebs_ws(4,uint32_t,(t),(h),(o),(v))
584 #define	bus_space_write_8(t, h, o, v)	__ebs_ws(8,uint64_t,(t),(h),(o),(v))
585 
586 
587 /*
588  * Bus write multiple operations.
589  */
590 #define	bus_space_write_multi_1(t, h, o, a, c)				\
591 	__ebs_nonsingle(wm,1,uint8_t,(t),(h),(o),(a),(c))
592 #define	bus_space_write_multi_2(t, h, o, a, c)				\
593 	__ebs_nonsingle(wm,2,uint16_t,(t),(h),(o),(a),(c))
594 #define	bus_space_write_multi_4(t, h, o, a, c)				\
595 	__ebs_nonsingle(wm,4,uint32_t,(t),(h),(o),(a),(c))
596 #define	bus_space_write_multi_8(t, h, o, a, c)				\
597 	__ebs_nonsingle(wm,8,uint64_t,(t),(h),(o),(a),(c))
598 
599 
600 /*
601  * Bus write region operations.
602  */
603 #define	bus_space_write_region_1(t, h, o, a, c)				\
604 	__ebs_nonsingle(wr,1,uint8_t,(t),(h),(o),(a),(c))
605 #define	bus_space_write_region_2(t, h, o, a, c)				\
606 	__ebs_nonsingle(wr,2,uint16_t,(t),(h),(o),(a),(c))
607 #define	bus_space_write_region_4(t, h, o, a, c)				\
608 	__ebs_nonsingle(wr,4,uint32_t,(t),(h),(o),(a),(c))
609 #define	bus_space_write_region_8(t, h, o, a, c)				\
610 	__ebs_nonsingle(wr,8,uint64_t,(t),(h),(o),(a),(c))
611 
612 
613 /*
614  * Set multiple operations.
615  */
616 #define	bus_space_set_multi_1(t, h, o, v, c)				\
617 	__ebs_set(sm,1,uint8_t,(t),(h),(o),(v),(c))
618 #define	bus_space_set_multi_2(t, h, o, v, c)				\
619 	__ebs_set(sm,2,uint16_t,(t),(h),(o),(v),(c))
620 #define	bus_space_set_multi_4(t, h, o, v, c)				\
621 	__ebs_set(sm,4,uint32_t,(t),(h),(o),(v),(c))
622 #define	bus_space_set_multi_8(t, h, o, v, c)				\
623 	__ebs_set(sm,8,uint64_t,(t),(h),(o),(v),(c))
624 
625 
626 /*
627  * Set region operations.
628  */
629 #define	bus_space_set_region_1(t, h, o, v, c)				\
630 	__ebs_set(sr,1,uint8_t,(t),(h),(o),(v),(c))
631 #define	bus_space_set_region_2(t, h, o, v, c)				\
632 	__ebs_set(sr,2,uint16_t,(t),(h),(o),(v),(c))
633 #define	bus_space_set_region_4(t, h, o, v, c)				\
634 	__ebs_set(sr,4,uint32_t,(t),(h),(o),(v),(c))
635 #define	bus_space_set_region_8(t, h, o, v, c)				\
636 	__ebs_set(sr,8,uint64_t,(t),(h),(o),(v),(c))
637 
638 
639 /*
640  * Copy region operations.
641  */
642 #define	bus_space_copy_region_1(t, h1, o1, h2, o2, c)			\
643 	__ebs_copy(1, uint8_t, (t), (h1), (o1), (h2), (o2), (c))
644 #define	bus_space_copy_region_2(t, h1, o1, h2, o2, c)			\
645 	__ebs_copy(2, uint16_t, (t), (h1), (o1), (h2), (o2), (c))
646 #define	bus_space_copy_region_4(t, h1, o1, h2, o2, c)			\
647 	__ebs_copy(4, uint32_t, (t), (h1), (o1), (h2), (o2), (c))
648 #define	bus_space_copy_region_8(t, h1, o1, h2, o2, c)			\
649 	__ebs_copy(8, uint64_t, (t), (h1), (o1), (h2), (o2), (c))
650 
651 /*
652  * Bus stream operations--defined in terms of non-stream counterparts
653  */
654 #define	__BUS_SPACE_HAS_STREAM_METHODS 1
655 #define	bus_space_read_stream_1 bus_space_read_1
656 #define	bus_space_read_stream_2 bus_space_read_2
657 #define	bus_space_read_stream_4 bus_space_read_4
658 #define	bus_space_read_stream_8 bus_space_read_8
659 #define	bus_space_read_multi_stream_1 bus_space_read_multi_1
660 #define	bus_space_read_multi_stream_2 bus_space_read_multi_2
661 #define	bus_space_read_multi_stream_4 bus_space_read_multi_4
662 #define	bus_space_read_multi_stream_8 bus_space_read_multi_8
663 #define	bus_space_read_region_stream_1 bus_space_read_region_1
664 #define	bus_space_read_region_stream_2 bus_space_read_region_2
665 #define	bus_space_read_region_stream_4 bus_space_read_region_4
666 #define	bus_space_read_region_stream_8 bus_space_read_region_8
667 #define	bus_space_write_stream_1 bus_space_write_1
668 #define	bus_space_write_stream_2 bus_space_write_2
669 #define	bus_space_write_stream_4 bus_space_write_4
670 #define	bus_space_write_stream_8 bus_space_write_8
671 #define	bus_space_write_multi_stream_1 bus_space_write_multi_1
672 #define	bus_space_write_multi_stream_2 bus_space_write_multi_2
673 #define	bus_space_write_multi_stream_4 bus_space_write_multi_4
674 #define	bus_space_write_multi_stream_8 bus_space_write_multi_8
675 #define	bus_space_write_region_stream_1 bus_space_write_region_1
676 #define	bus_space_write_region_stream_2 bus_space_write_region_2
677 #define	bus_space_write_region_stream_4 bus_space_write_region_4
678 #define	bus_space_write_region_stream_8	bus_space_write_region_8
679 
680 #endif /* _KERNEL */
681 
682 /*
683  * Flags used in various bus DMA methods.
684  */
685 #define	BUS_DMA_WAITOK		0x000	/* safe to sleep (pseudo-flag) */
686 #define	BUS_DMA_NOWAIT		0x001	/* not safe to sleep */
687 #define	BUS_DMA_ALLOCNOW	0x002	/* perform resource allocation now */
688 #define	BUS_DMA_COHERENT	0x004	/* hint: map memory DMA coherent */
689 #define	BUS_DMA_STREAMING	0x008	/* hint: sequential, unidirectional */
690 #define	BUS_DMA_BUS1		0x010	/* placeholders for bus functions... */
691 #define	BUS_DMA_BUS2		0x020
692 #define	BUS_DMA_BUS3		0x040
693 #define	BUS_DMA_BUS4		0x080
694 #define	BUS_DMA_READ		0x100	/* mapping is device -> memory only */
695 #define	BUS_DMA_WRITE		0x200	/* mapping is memory -> device only */
696 #define	BUS_DMA_NOCACHE		0x400	/* hint: map non-cached memory */
697 
698 #define	EWS4800MIPS_DMAMAP_COHERENT	0x10000	/* no cache flush necessary on sync */
699 
700 /* Forwards needed by prototypes below. */
701 struct mbuf;
702 struct uio;
703 
704 /*
705  * Operations performed by bus_dmamap_sync().
706  */
707 #define	BUS_DMASYNC_PREREAD	0x01	/* pre-read synchronization */
708 #define	BUS_DMASYNC_POSTREAD	0x02	/* post-read synchronization */
709 #define	BUS_DMASYNC_PREWRITE	0x04	/* pre-write synchronization */
710 #define	BUS_DMASYNC_POSTWRITE	0x08	/* post-write synchronization */
711 
712 typedef struct ews4800mips_bus_dma_tag		*bus_dma_tag_t;
713 typedef struct ews4800mips_bus_dmamap		*bus_dmamap_t;
714 
715 #define	BUS_DMA_TAG_VALID(t)    ((t) != (bus_dma_tag_t)0)
716 
717 /*
718  *	bus_dma_segment_t
719  *
720  *	Describes a single contiguous DMA transaction.  Values
721  *	are suitable for programming into DMA registers.
722  */
723 struct ews4800mips_bus_dma_segment {
724 	bus_addr_t	ds_addr;	/* DMA address */
725 	bus_size_t	ds_len;		/* length of transfer */
726 	vaddr_t		_ds_vaddr;	/* virtual address, 0 if invalid */
727 };
728 typedef struct ews4800mips_bus_dma_segment	bus_dma_segment_t;
729 
730 /*
731  *	bus_dma_tag_t
732  *
733  *	A machine-dependent opaque type describing the implementation of
734  *	DMA for a given bus.
735  */
736 
737 struct ews4800mips_bus_dma_tag {
738 	/*
739 	 * DMA mapping methods.
740 	 */
741 	int	(*_dmamap_create)(bus_dma_tag_t, bus_size_t, int,
742 		    bus_size_t, bus_size_t, int, bus_dmamap_t *);
743 	void	(*_dmamap_destroy)(bus_dma_tag_t, bus_dmamap_t);
744 	int	(*_dmamap_load)(bus_dma_tag_t, bus_dmamap_t, void *,
745 		    bus_size_t, struct proc *, int);
746 	int	(*_dmamap_load_mbuf)(bus_dma_tag_t, bus_dmamap_t,
747 		    struct mbuf *, int);
748 	int	(*_dmamap_load_uio)(bus_dma_tag_t, bus_dmamap_t,
749 		    struct uio *, int);
750 	int	(*_dmamap_load_raw)(bus_dma_tag_t, bus_dmamap_t,
751 		    bus_dma_segment_t *, int, bus_size_t, int);
752 	void	(*_dmamap_unload)(bus_dma_tag_t, bus_dmamap_t);
753 	void	(*_dmamap_sync)(bus_dma_tag_t, bus_dmamap_t,
754 		    bus_addr_t, bus_size_t, int);
755 
756 	/*
757 	 * DMA memory utility functions.
758 	 */
759 	int	(*_dmamem_alloc)(bus_dma_tag_t, bus_size_t, bus_size_t,
760 		    bus_size_t, bus_dma_segment_t *, int, int *, int);
761 	void	(*_dmamem_free)(bus_dma_tag_t,
762 		    bus_dma_segment_t *, int);
763 	int	(*_dmamem_map)(bus_dma_tag_t, bus_dma_segment_t *,
764 		    int, size_t, void **, int);
765 	void	(*_dmamem_unmap)(bus_dma_tag_t, void *, size_t);
766 	paddr_t	(*_dmamem_mmap)(bus_dma_tag_t, bus_dma_segment_t *,
767 		    int, off_t, int, int);
768 
769 	/*
770 	 * DMA controller private.
771 	 */
772 	void	*_dmachip_cookie;
773 };
774 
775 #define	bus_dmamap_create(t, s, n, m, b, f, p)			\
776 	(*(t)->_dmamap_create)((t), (s), (n), (m), (b), (f), (p))
777 #define	bus_dmamap_destroy(t, p)				\
778 	(*(t)->_dmamap_destroy)((t), (p))
779 #define	bus_dmamap_load(t, m, b, s, p, f)			\
780 	(*(t)->_dmamap_load)((t), (m), (b), (s), (p), (f))
781 #define	bus_dmamap_load_mbuf(t, m, b, f)			\
782 	(*(t)->_dmamap_load_mbuf)((t), (m), (b), (f))
783 #define	bus_dmamap_load_uio(t, m, u, f)				\
784 	(*(t)->_dmamap_load_uio)((t), (m), (u), (f))
785 #define	bus_dmamap_load_raw(t, m, sg, n, s, f)			\
786 	(*(t)->_dmamap_load_raw)((t), (m), (sg), (n), (s), (f))
787 #define	bus_dmamap_unload(t, p)					\
788 	(*(t)->_dmamap_unload)((t), (p))
789 #define	bus_dmamap_sync(t, p, o, l, ops)			\
790 	(*(t)->_dmamap_sync)((t), (p), (o), (l), (ops))
791 
792 #define	bus_dmamem_alloc(t, s, a, b, sg, n, r, f)		\
793 	(*(t)->_dmamem_alloc)((t), (s), (a), (b), (sg), (n), (r), (f))
794 #define	bus_dmamem_free(t, sg, n)				\
795 	(*(t)->_dmamem_free)((t), (sg), (n))
796 #define	bus_dmamem_map(t, sg, n, s, k, f)			\
797 	(*(t)->_dmamem_map)((t), (sg), (n), (s), (k), (f))
798 #define	bus_dmamem_unmap(t, k, s)				\
799 	(*(t)->_dmamem_unmap)((t), (k), (s))
800 #define	bus_dmamem_mmap(t, sg, n, o, p, f)			\
801 	(*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
802 
803 #define bus_dmatag_subregion(t, mna, mxa, nt, f) EOPNOTSUPP
804 #define bus_dmatag_destroy(t)
805 
806 /*
807  *	bus_dmamap_t
808  *
809  *	Describes a DMA mapping.
810  */
811 struct ews4800mips_bus_dmamap {
812 	/*
813 	 * PRIVATE MEMBERS: not for use my machine-independent code.
814 	 */
815 	bus_size_t	_dm_size;	/* largest DMA transfer mappable */
816 	int		_dm_segcnt;	/* number of segs this map can map */
817 	bus_size_t	_dm_maxmaxsegsz; /* fixed largest possible segment */
818 	bus_size_t	_dm_boundary;	/* don't cross this */
819 	int		_dm_flags;	/* misc. flags */
820 	struct vmspace	*_dm_vmspace;	/* vmspace that owns the mapping */
821 
822 	/*
823 	 * PUBLIC MEMBERS: these are used by machine-independent code.
824 	 */
825 	bus_size_t	dm_maxsegsz;	/* largest possible segment */
826 	bus_size_t	dm_mapsize;	/* size of the mapping */
827 	int		dm_nsegs;	/* # valid segments in mapping */
828 	bus_dma_segment_t dm_segs[1];	/* segments; variable length */
829 };
830 
831 #ifdef _EWS4800MIPS_BUS_DMA_PRIVATE
832 int	_bus_dmamap_create(bus_dma_tag_t, bus_size_t, int, bus_size_t,
833 	    bus_size_t, int, bus_dmamap_t *);
834 void	_bus_dmamap_destroy(bus_dma_tag_t, bus_dmamap_t);
835 int	_bus_dmamap_load(bus_dma_tag_t, bus_dmamap_t, void *,
836 	    bus_size_t, struct proc *, int);
837 int	_bus_dmamap_load_mbuf(bus_dma_tag_t, bus_dmamap_t,
838 	    struct mbuf *, int);
839 int	_bus_dmamap_load_uio(bus_dma_tag_t, bus_dmamap_t,
840 	    struct uio *, int);
841 int	_bus_dmamap_load_raw(bus_dma_tag_t, bus_dmamap_t,
842 	    bus_dma_segment_t *, int, bus_size_t, int);
843 void	_bus_dmamap_unload(bus_dma_tag_t, bus_dmamap_t);
844 void	_bus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t, bus_addr_t,
845 	    bus_size_t, int);
846 
847 int	_bus_dmamem_alloc(bus_dma_tag_t tag, bus_size_t size,
848 	    bus_size_t alignment, bus_size_t boundary,
849 	    bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags);
850 void	_bus_dmamem_free(bus_dma_tag_t tag, bus_dma_segment_t *segs,
851 	    int nsegs);
852 int	_bus_dmamem_map(bus_dma_tag_t tag, bus_dma_segment_t *segs,
853 	    int nsegs, size_t size, void **kvap, int flags);
854 void	_bus_dmamem_unmap(bus_dma_tag_t tag, void *kva,
855 	    size_t size);
856 paddr_t	_bus_dmamem_mmap(bus_dma_tag_t tag, bus_dma_segment_t *segs,
857 	    int nsegs, off_t off, int prot, int flags);
858 
859 int	_bus_dmamem_alloc_range(bus_dma_tag_t tag, bus_size_t size,
860 	    bus_size_t alignment, bus_size_t boundary,
861 	    bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags,
862 	    vaddr_t low, vaddr_t high);
863 
864 extern struct ews4800mips_bus_dma_tag ews4800mips_default_bus_dma_tag;
865 #endif /* _EWS4800MIPS_BUS_DMA_PRIVATE */
866 
867 #endif /* _EWS4800MIPS_BUS_H_ */
868