Expand PMF_FN_* macros.
[netbsd-mini2440.git] / sys / arch / ews4800mips / include / bus.h
blob8a883dba57ba6ee548ca47742ee4fa74855875b4
1 /* $NetBSD: bus.h,v 1.5 2007/03/04 05:59:47 christos Exp $ */
3 /*-
4 * Copyright (c) 1997, 1998, 2000, 2001, 2005 The NetBSD Foundation, Inc.
5 * All rights reserved.
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
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.
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 Carnegie-Mellon University.
35 * All rights reserved.
37 * Author: Chris G. Demetriou
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.
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.
49 * Carnegie Mellon requests users of this software to return to
51 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
52 * School of Computer Science
53 * Carnegie Mellon University
54 * Pittsburgh PA 15213-3890
56 * any improvements or extensions that they make and grant Carnegie the
57 * rights to redistribute these changes.
60 #ifndef _EWS4800MIPS_BUS_H_
61 #define _EWS4800MIPS_BUS_H_
63 #include <sys/types.h>
64 #ifdef _KERNEL
66 * Turn on BUS_SPACE_DEBUG if the global DEBUG option is enabled.
68 #if defined(DEBUG) && !defined(BUS_SPACE_DEBUG)
69 #define BUS_SPACE_DEBUG
70 #endif
72 #ifdef BUS_SPACE_DEBUG
73 #include <sys/systm.h> /* for printf() prototype */
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.
81 #define __BUS_SPACE_ALIGNED_ADDRESS(p, t) \
82 ((((uint32_t)(p)) & (sizeof(t)-1)) == 0)
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; \
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 */
102 * Addresses (in bus space).
104 typedef long bus_addr_t;
105 typedef long bus_size_t;
108 * Access methods for bus space.
110 typedef struct ews4800mips_bus_space *bus_space_tag_t;
111 typedef bus_addr_t bus_space_handle_t;
113 struct extent; /* forward declaration */
115 struct ews4800mips_bus_space {
116 struct extent *ebs_extent;
117 bus_addr_t ebs_base_addr;
118 bus_size_t ebs_size;
120 /* cookie */
121 void *ebs_cookie;
123 /* mapping/unmapping */
124 int (*ebs_map)(void *, bus_addr_t, bus_size_t,
125 int, bus_space_handle_t *);
126 void (*ebs_unmap)(void *, bus_space_handle_t,
127 bus_size_t);
128 int (*ebs_subregion)(void *, bus_space_handle_t,
129 bus_size_t, bus_size_t, bus_space_handle_t *);
131 /* allocation/deallocation */
132 int (*ebs_alloc)(void *, bus_addr_t, bus_addr_t,
133 bus_size_t, bus_size_t, bus_size_t, int,
134 bus_addr_t *, bus_space_handle_t *);
135 void (*ebs_free)(void *, bus_space_handle_t,
136 bus_size_t);
138 /* get kernel virtual address */
139 void * (*ebs_vaddr)(void *, bus_space_handle_t);
141 /* read (single) */
142 uint8_t (*ebs_r_1)(void *, bus_space_handle_t,
143 bus_size_t);
144 uint16_t (*ebs_r_2)(void *, bus_space_handle_t,
145 bus_size_t);
146 uint32_t (*ebs_r_4)(void *, bus_space_handle_t,
147 bus_size_t);
148 uint64_t (*ebs_r_8)(void *, bus_space_handle_t,
149 bus_size_t);
151 /* read multiple */
152 void (*ebs_rm_1)(void *, bus_space_handle_t,
153 bus_size_t, uint8_t *, bus_size_t);
154 void (*ebs_rm_2)(void *, bus_space_handle_t,
155 bus_size_t, uint16_t *, bus_size_t);
156 void (*ebs_rm_4)(void *, bus_space_handle_t,
157 bus_size_t, uint32_t *, bus_size_t);
158 void (*ebs_rm_8)(void *, bus_space_handle_t,
159 bus_size_t, uint64_t *, bus_size_t);
161 /* read region */
162 void (*ebs_rr_1)(void *, bus_space_handle_t,
163 bus_size_t, uint8_t *, bus_size_t);
164 void (*ebs_rr_2)(void *, bus_space_handle_t,
165 bus_size_t, uint16_t *, bus_size_t);
166 void (*ebs_rr_4)(void *, bus_space_handle_t,
167 bus_size_t, uint32_t *, bus_size_t);
168 void (*ebs_rr_8)(void *, bus_space_handle_t,
169 bus_size_t, uint64_t *, bus_size_t);
171 /* write (single) */
172 void (*ebs_w_1)(void *, bus_space_handle_t,
173 bus_size_t, uint8_t);
174 void (*ebs_w_2)(void *, bus_space_handle_t,
175 bus_size_t, uint16_t);
176 void (*ebs_w_4)(void *, bus_space_handle_t,
177 bus_size_t, uint32_t);
178 void (*ebs_w_8)(void *, bus_space_handle_t,
179 bus_size_t, uint64_t);
181 /* write multiple */
182 void (*ebs_wm_1)(void *, bus_space_handle_t,
183 bus_size_t, const uint8_t *, bus_size_t);
184 void (*ebs_wm_2)(void *, bus_space_handle_t,
185 bus_size_t, const uint16_t *, bus_size_t);
186 void (*ebs_wm_4)(void *, bus_space_handle_t,
187 bus_size_t, const uint32_t *, bus_size_t);
188 void (*ebs_wm_8)(void *, bus_space_handle_t,
189 bus_size_t, const uint64_t *, bus_size_t);
191 /* write region */
192 void (*ebs_wr_1)(void *, bus_space_handle_t,
193 bus_size_t, const uint8_t *, bus_size_t);
194 void (*ebs_wr_2)(void *, bus_space_handle_t,
195 bus_size_t, const uint16_t *, bus_size_t);
196 void (*ebs_wr_4)(void *, bus_space_handle_t,
197 bus_size_t, const uint32_t *, bus_size_t);
198 void (*ebs_wr_8)(void *, bus_space_handle_t,
199 bus_size_t, const uint64_t *, bus_size_t);
201 /* set multiple */
202 void (*ebs_sm_1)(void *, bus_space_handle_t,
203 bus_size_t, uint8_t, bus_size_t);
204 void (*ebs_sm_2)(void *, bus_space_handle_t,
205 bus_size_t, uint16_t, bus_size_t);
206 void (*ebs_sm_4)(void *, bus_space_handle_t,
207 bus_size_t, uint32_t, bus_size_t);
208 void (*ebs_sm_8)(void *, bus_space_handle_t,
209 bus_size_t, uint64_t, bus_size_t);
211 /* set region */
212 void (*ebs_sr_1)(void *, bus_space_handle_t,
213 bus_size_t, uint8_t, bus_size_t);
214 void (*ebs_sr_2)(void *, bus_space_handle_t,
215 bus_size_t, uint16_t, bus_size_t);
216 void (*ebs_sr_4)(void *, bus_space_handle_t,
217 bus_size_t, uint32_t, bus_size_t);
218 void (*ebs_sr_8)(void *, bus_space_handle_t,
219 bus_size_t, uint64_t, bus_size_t);
221 /* copy */
222 void (*ebs_c_1)(void *, bus_space_handle_t, bus_size_t,
223 bus_space_handle_t, bus_size_t, bus_size_t);
224 void (*ebs_c_2)(void *, bus_space_handle_t, bus_size_t,
225 bus_space_handle_t, bus_size_t, bus_size_t);
226 void (*ebs_c_4)(void *, bus_space_handle_t, bus_size_t,
227 bus_space_handle_t, bus_size_t, bus_size_t);
228 void (*ebs_c_8)(void *, bus_space_handle_t, bus_size_t,
229 bus_space_handle_t, bus_size_t, bus_size_t);
232 #ifdef _KERNEL
233 /* Don't use locore.h wbflush */
234 #undef wbflush
235 #define wbflush() platform.wbflush()
236 #ifdef _EWS4800MIPS_BUS_SPACE_PRIVATE
238 #ifndef __read_1
239 #define __read_1(a) (*(volatile uint8_t *)(a))
240 #endif
241 #ifndef __read_2
242 #define __read_2(a) (*(volatile uint16_t *)(a))
243 #endif
244 #ifndef __read_4
245 #define __read_4(a) (*(volatile uint32_t *)(a))
246 #endif
247 #ifndef __read_8
248 #define __read_8(a) (*(volatile uint64_t *)(a))
249 #endif
250 #define __read_16(a) "error. not yet"
252 #ifndef __write_1
253 #define __write_1(a, v) { \
254 *(volatile uint8_t *)(a) = (v); \
255 wbflush(); \
257 #endif
258 #ifndef __write_2
259 #define __write_2(a, v) { \
260 *(volatile uint16_t *)(a) = (v); \
261 wbflush(); \
263 #endif
264 #ifndef __write_4
265 #define __write_4(a, v) { \
266 *(volatile uint32_t *)(a) = (v); \
267 wbflush(); \
269 #endif
270 #ifndef __write_8
271 #define __write_8(a, v) { \
272 *(volatile uint64_t *)(a) = (v); \
273 wbflush(); \
275 #endif
277 #define __TYPENAME(BITS) uint##BITS##_t
279 #define _BUS_SPACE_READ(PREFIX, BYTES, BITS) \
280 static __TYPENAME(BITS) \
281 PREFIX##_read_##BYTES(void *, bus_space_handle_t, bus_size_t); \
282 static __TYPENAME(BITS) \
283 PREFIX##_read_##BYTES(void *tag, bus_space_handle_t bsh, \
284 bus_size_t offset) \
286 return __read_##BYTES(VADDR(bsh, offset)); \
289 #define _BUS_SPACE_READ_MULTI(PREFIX, BYTES, BITS) \
290 static void \
291 PREFIX##_read_multi_##BYTES(void *, bus_space_handle_t, bus_size_t, \
292 __TYPENAME(BITS) *, bus_size_t); \
293 static void \
294 PREFIX##_read_multi_##BYTES(void *tag, bus_space_handle_t bsh, \
295 bus_size_t offset, __TYPENAME(BITS) *addr, bus_size_t count) \
297 bus_addr_t a = VADDR(bsh, offset); \
298 while (count--) \
299 *addr++ = __read_##BYTES(a); \
302 #define _BUS_SPACE_READ_REGION(PREFIX, BYTES, BITS) \
303 static void \
304 PREFIX##_read_region_##BYTES(void *, bus_space_handle_t, bus_size_t, \
305 __TYPENAME(BITS) *, bus_size_t); \
306 static void \
307 PREFIX##_read_region_##BYTES(void *tag, bus_space_handle_t bsh, \
308 bus_size_t offset, __TYPENAME(BITS) *addr, bus_size_t count) \
310 while (count--) { \
311 *addr++ = __read_##BYTES(VADDR(bsh, offset)); \
312 offset += BYTES; \
316 #define _BUS_SPACE_WRITE(PREFIX, BYTES, BITS) \
317 static void \
318 PREFIX##_write_##BYTES(void *, bus_space_handle_t, bus_size_t, \
319 __TYPENAME(BITS)); \
320 static void \
321 PREFIX##_write_##BYTES(void *tag, bus_space_handle_t bsh, \
322 bus_size_t offset, __TYPENAME(BITS) value) \
324 __write_##BYTES(VADDR(bsh, offset), value); \
327 #define _BUS_SPACE_WRITE_MULTI(PREFIX, BYTES, BITS) \
328 static void \
329 PREFIX##_write_multi_##BYTES(void *, bus_space_handle_t, bus_size_t, \
330 const __TYPENAME(BITS) *, bus_size_t); \
331 static void \
332 PREFIX##_write_multi_##BYTES(void *tag, bus_space_handle_t bsh, \
333 bus_size_t offset, const __TYPENAME(BITS) *addr, bus_size_t count) \
335 bus_addr_t a = VADDR(bsh, offset); \
336 while (count--) { \
337 __write_##BYTES(a, *addr++); \
341 #define _BUS_SPACE_WRITE_REGION(PREFIX, BYTES, BITS) \
342 static void \
343 PREFIX##_write_region_##BYTES(void *, bus_space_handle_t, bus_size_t, \
344 const __TYPENAME(BITS) *, bus_size_t); \
345 static void \
346 PREFIX##_write_region_##BYTES(void *tag, bus_space_handle_t bsh, \
347 bus_size_t offset, const __TYPENAME(BITS) *addr, bus_size_t count) \
349 while (count--) { \
350 __write_##BYTES(VADDR(bsh, offset), *addr++); \
351 offset += BYTES; \
355 #define _BUS_SPACE_SET_MULTI(PREFIX, BYTES, BITS) \
356 static void \
357 PREFIX##_set_multi_##BYTES(void *, bus_space_handle_t, bus_size_t, \
358 __TYPENAME(BITS), bus_size_t); \
359 static void \
360 PREFIX##_set_multi_##BYTES(void *tag, bus_space_handle_t bsh, \
361 bus_size_t offset, __TYPENAME(BITS) value, bus_size_t count) \
363 bus_addr_t a = VADDR(bsh, offset); \
364 while (count--) { \
365 __write_##BYTES(a, value); \
369 #define _BUS_SPACE_SET_REGION(PREFIX, BYTES, BITS) \
370 static void \
371 PREFIX##_set_region_##BYTES(void *, bus_space_handle_t, bus_size_t, \
372 __TYPENAME(BITS), bus_size_t); \
373 static void \
374 PREFIX##_set_region_##BYTES(void *tag, bus_space_handle_t bsh, \
375 bus_size_t offset, __TYPENAME(BITS) value, bus_size_t count) \
377 while (count--) { \
378 __write_##BYTES(VADDR(bsh, offset), value); \
379 offset += BYTES; \
383 #define _BUS_SPACE_COPY_REGION(PREFIX, BYTES, BITS) \
384 static void \
385 PREFIX##_copy_region_##BYTES(void *, bus_space_handle_t, bus_size_t, \
386 bus_space_handle_t, bus_size_t, bus_size_t); \
387 static void \
388 PREFIX##_copy_region_##BYTES(void *t, bus_space_handle_t h1, \
389 bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c) \
391 bus_size_t o; \
392 if ((h1 + o1) >= (h2 + o2)) { \
393 /* src after dest: copy forward */ \
394 for (o = 0; c != 0; c--, o += BYTES) \
395 __write_##BYTES(VADDR(h2, o2 + o), \
396 __read_##BYTES(VADDR(h1, o1 + o))); \
397 } else { \
398 /* dest after src: copy backwards */ \
399 for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES) \
400 __write_##BYTES(VADDR(h2, o2 + o), \
401 __read_##BYTES(VADDR(h1, o1 + o))); \
405 #define _BUS_SPACE_NO_MAP \
406 (int (*)(void *, bus_addr_t, bus_size_t, int, \
407 bus_space_handle_t *))_bus_space_invalid_access
408 #define _BUS_SPACE_NO_UNMAP \
409 (void (*)(void *, bus_space_handle_t, bus_size_t)) \
410 _bus_space_invalid_access
411 #define _BUS_SPACE_NO_SUBREGION \
412 (int (*)(void *, bus_space_handle_t, bus_size_t, bus_size_t, \
413 bus_space_handle_t *))_bus_space_invalid_access
414 #define _BUS_SPACE_NO_ALLOC \
415 (int (*)(void *, bus_addr_t, bus_addr_t, bus_size_t, bus_size_t,\
416 bus_size_t, int, bus_addr_t *, bus_space_handle_t *)) \
417 _bus_space_invalid_access
418 #define _BUS_SPACE_NO_FREE \
419 (void (*)(void *, bus_space_handle_t, bus_size_t)) \
420 _bus_space_invalid_access
421 #define _BUS_SPACE_NO_VADDR \
422 (void *(*)(void *, bus_space_handle_t))_bus_space_invalid_access
423 #define _BUS_SPACE_NO_READ(BYTES, BITS) \
424 (uint##BITS##_t (*)(void *, bus_space_handle_t, bus_size_t)) \
425 _bus_space_invalid_access
426 #define _BUS_SPACE_NO_READ_MULTI(BYTES, BITS) \
427 (void (*)(void *, bus_space_handle_t, bus_size_t, \
428 uint##BITS##_t *, bus_size_t))_bus_space_invalid_access
429 #define _BUS_SPACE_NO_READ_REGION(BYTES, BITS) \
430 (void (*)(void *, bus_space_handle_t, bus_size_t, \
431 uint##BITS##_t *, bus_size_t))_bus_space_invalid_access
432 #define _BUS_SPACE_NO_WRITE(BYTES, BITS) \
433 (void (*)(void *, bus_space_handle_t, bus_size_t, \
434 uint##BITS##_t))_bus_space_invalid_access
435 #define _BUS_SPACE_NO_WRITE_MULTI(BYTES, BITS) \
436 (void (*)(void *, bus_space_handle_t, bus_size_t, \
437 const uint##BITS##_t *, bus_size_t))_bus_space_invalid_access
438 #define _BUS_SPACE_NO_WRITE_REGION(BYTES, BITS) \
439 (void (*)(void *, bus_space_handle_t, bus_size_t, \
440 const uint##BITS##_t *, bus_size_t))_bus_space_invalid_access
441 #define _BUS_SPACE_NO_SET_MULTI(BYTES, BITS) \
442 (void (*)(void *, bus_space_handle_t, bus_size_t, \
443 uint##BITS##_t, bus_size_t))_bus_space_invalid_access
444 #define _BUS_SPACE_NO_SET_REGION(BYTES, BITS) \
445 (void (*)(void *, bus_space_handle_t, bus_size_t, \
446 uint##BITS##_t, bus_size_t))_bus_space_invalid_access
447 #define _BUS_SPACE_NO_COPY_REGION(BYTES, BITS) \
448 (void (*)(void *, bus_space_handle_t, bus_size_t, \
449 bus_space_handle_t, bus_size_t, bus_size_t))_bus_space_invalid_access
451 void _bus_space_invalid_access(void);
452 #endif /* _EWS4800MIPS_BUS_SPACE_PRIVATE */
454 #define __ebs_c(a,b) __CONCAT(a,b)
455 #define __ebs_opname(op,size) __ebs_c(__ebs_c(__ebs_c(ebs_,op),_),size)
457 #define __ebs_rs(sz, tn, t, h, o) \
458 (__BUS_SPACE_ADDRESS_SANITY((h) + (o), tn, "bus addr"), \
459 (*(t)->__ebs_opname(r,sz))((t)->ebs_cookie, h, o))
461 #define __ebs_ws(sz, tn, t, h, o, v) \
462 ({ \
463 __BUS_SPACE_ADDRESS_SANITY((h) + (o), tn, "bus addr"); \
464 (*(t)->__ebs_opname(w,sz))((t)->ebs_cookie, h, o, v); \
467 #define __ebs_nonsingle(type, sz, tn, t, h, o, a, c) \
468 ({ \
469 __BUS_SPACE_ADDRESS_SANITY((a), tn, "buffer"); \
470 __BUS_SPACE_ADDRESS_SANITY((h) + (o), tn, "bus addr"); \
471 (*(t)->__ebs_opname(type,sz))((t)->ebs_cookie, h, o, a, c); \
474 #define __ebs_set(type, sz, tn, t, h, o, v, c) \
475 ({ \
476 __BUS_SPACE_ADDRESS_SANITY((h) + (o), tn, "bus addr"); \
477 (*(t)->__ebs_opname(type,sz))((t)->ebs_cookie, h, o, v, c); \
480 #define __ebs_copy(sz, tn, t, h1, o1, h2, o2, cnt) \
481 ({ \
482 __BUS_SPACE_ADDRESS_SANITY((h1) + (o1), tn, "bus addr 1"); \
483 __BUS_SPACE_ADDRESS_SANITY((h2) + (o2), tn, "bus addr 2"); \
484 (*(t)->__ebs_opname(c,sz))((t)->ebs_cookie, h1, o1, h2, o2, cnt); \
488 * Create/destroy default bus_space tag.
490 int bus_space_create(bus_space_tag_t, const char *, bus_addr_t, bus_size_t);
491 void bus_space_destroy(bus_space_tag_t);
494 * Mapping and unmapping operations.
496 #define bus_space_map(t, a, s, f, hp) \
497 (*(t)->ebs_map)((t)->ebs_cookie, (a), (s), (f), (hp))
498 #define bus_space_unmap(t, h, s) \
499 (*(t)->ebs_unmap)((t)->ebs_cookie, (h), (s))
500 #define bus_space_subregion(t, h, o, s, hp) \
501 (*(t)->ebs_subregion)((t)->ebs_cookie, (h), (o), (s), (hp))
503 #endif /* _KERNEL */
505 #define BUS_SPACE_MAP_CACHEABLE 0x01
506 #define BUS_SPACE_MAP_LINEAR 0x02
507 #define BUS_SPACE_MAP_PREFETCHABLE 0x04
509 #ifdef _KERNEL
511 * Allocation and deallocation operations.
513 #define bus_space_alloc(t, rs, re, s, a, b, f, ap, hp) \
514 (*(t)->ebs_alloc)((t)->ebs_cookie, (rs), (re), (s), (a), (b), \
515 (f), (ap), (hp))
516 #define bus_space_free(t, h, s) \
517 (*(t)->ebs_free)((t)->ebs_cookie, (h), (s))
520 * Get kernel virtual address for ranges mapped BUS_SPACE_MAP_LINEAR.
522 #define bus_space_vaddr(t, h) \
523 (*(t)->ebs_vaddr)((t)->ebs_cookie, (h))
526 * Bus read/write barrier methods.
528 * void bus_space_barrier(bus_space_tag_t tag,
529 * bus_space_handle_t bsh, bus_size_t offset,
530 * bus_size_t len, int flags);
532 * On the MIPS, we just flush the write buffer.
534 #define bus_space_barrier(t, h, o, l, f) \
535 ((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f), \
536 wbflush()))
537 #define BUS_SPACE_BARRIER_READ 0x01
538 #define BUS_SPACE_BARRIER_WRITE 0x02
542 * Bus read (single) operations.
544 #define bus_space_read_1(t, h, o) __ebs_rs(1,uint8_t,(t),(h),(o))
545 #define bus_space_read_2(t, h, o) __ebs_rs(2,uint16_t,(t),(h),(o))
546 #define bus_space_read_4(t, h, o) __ebs_rs(4,uint32_t,(t),(h),(o))
547 #define bus_space_read_8(t, h, o) __ebs_rs(8,uint64_t,(t),(h),(o))
551 * Bus read multiple operations.
553 #define bus_space_read_multi_1(t, h, o, a, c) \
554 __ebs_nonsingle(rm,1,uint8_t,(t),(h),(o),(a),(c))
555 #define bus_space_read_multi_2(t, h, o, a, c) \
556 __ebs_nonsingle(rm,2,uint16_t,(t),(h),(o),(a),(c))
557 #define bus_space_read_multi_4(t, h, o, a, c) \
558 __ebs_nonsingle(rm,4,uint32_t,(t),(h),(o),(a),(c))
559 #define bus_space_read_multi_8(t, h, o, a, c) \
560 __ebs_nonsingle(rm,8,uint64_t,(t),(h),(o),(a),(c))
564 * Bus read region operations.
566 #define bus_space_read_region_1(t, h, o, a, c) \
567 __ebs_nonsingle(rr,1,uint8_t,(t),(h),(o),(a),(c))
568 #define bus_space_read_region_2(t, h, o, a, c) \
569 __ebs_nonsingle(rr,2,uint16_t,(t),(h),(o),(a),(c))
570 #define bus_space_read_region_4(t, h, o, a, c) \
571 __ebs_nonsingle(rr,4,uint32_t,(t),(h),(o),(a),(c))
572 #define bus_space_read_region_8(t, h, o, a, c) \
573 __ebs_nonsingle(rr,8,uint64_t,(t),(h),(o),(a),(c))
577 * Bus write (single) operations.
579 #define bus_space_write_1(t, h, o, v) __ebs_ws(1,uint8_t,(t),(h),(o),(v))
580 #define bus_space_write_2(t, h, o, v) __ebs_ws(2,uint16_t,(t),(h),(o),(v))
581 #define bus_space_write_4(t, h, o, v) __ebs_ws(4,uint32_t,(t),(h),(o),(v))
582 #define bus_space_write_8(t, h, o, v) __ebs_ws(8,uint64_t,(t),(h),(o),(v))
586 * Bus write multiple operations.
588 #define bus_space_write_multi_1(t, h, o, a, c) \
589 __ebs_nonsingle(wm,1,uint8_t,(t),(h),(o),(a),(c))
590 #define bus_space_write_multi_2(t, h, o, a, c) \
591 __ebs_nonsingle(wm,2,uint16_t,(t),(h),(o),(a),(c))
592 #define bus_space_write_multi_4(t, h, o, a, c) \
593 __ebs_nonsingle(wm,4,uint32_t,(t),(h),(o),(a),(c))
594 #define bus_space_write_multi_8(t, h, o, a, c) \
595 __ebs_nonsingle(wm,8,uint64_t,(t),(h),(o),(a),(c))
599 * Bus write region operations.
601 #define bus_space_write_region_1(t, h, o, a, c) \
602 __ebs_nonsingle(wr,1,uint8_t,(t),(h),(o),(a),(c))
603 #define bus_space_write_region_2(t, h, o, a, c) \
604 __ebs_nonsingle(wr,2,uint16_t,(t),(h),(o),(a),(c))
605 #define bus_space_write_region_4(t, h, o, a, c) \
606 __ebs_nonsingle(wr,4,uint32_t,(t),(h),(o),(a),(c))
607 #define bus_space_write_region_8(t, h, o, a, c) \
608 __ebs_nonsingle(wr,8,uint64_t,(t),(h),(o),(a),(c))
612 * Set multiple operations.
614 #define bus_space_set_multi_1(t, h, o, v, c) \
615 __ebs_set(sm,1,uint8_t,(t),(h),(o),(v),(c))
616 #define bus_space_set_multi_2(t, h, o, v, c) \
617 __ebs_set(sm,2,uint16_t,(t),(h),(o),(v),(c))
618 #define bus_space_set_multi_4(t, h, o, v, c) \
619 __ebs_set(sm,4,uint32_t,(t),(h),(o),(v),(c))
620 #define bus_space_set_multi_8(t, h, o, v, c) \
621 __ebs_set(sm,8,uint64_t,(t),(h),(o),(v),(c))
625 * Set region operations.
627 #define bus_space_set_region_1(t, h, o, v, c) \
628 __ebs_set(sr,1,uint8_t,(t),(h),(o),(v),(c))
629 #define bus_space_set_region_2(t, h, o, v, c) \
630 __ebs_set(sr,2,uint16_t,(t),(h),(o),(v),(c))
631 #define bus_space_set_region_4(t, h, o, v, c) \
632 __ebs_set(sr,4,uint32_t,(t),(h),(o),(v),(c))
633 #define bus_space_set_region_8(t, h, o, v, c) \
634 __ebs_set(sr,8,uint64_t,(t),(h),(o),(v),(c))
638 * Copy region operations.
640 #define bus_space_copy_region_1(t, h1, o1, h2, o2, c) \
641 __ebs_copy(1, uint8_t, (t), (h1), (o1), (h2), (o2), (c))
642 #define bus_space_copy_region_2(t, h1, o1, h2, o2, c) \
643 __ebs_copy(2, uint16_t, (t), (h1), (o1), (h2), (o2), (c))
644 #define bus_space_copy_region_4(t, h1, o1, h2, o2, c) \
645 __ebs_copy(4, uint32_t, (t), (h1), (o1), (h2), (o2), (c))
646 #define bus_space_copy_region_8(t, h1, o1, h2, o2, c) \
647 __ebs_copy(8, uint64_t, (t), (h1), (o1), (h2), (o2), (c))
650 * Bus stream operations--defined in terms of non-stream counterparts
652 #define __BUS_SPACE_HAS_STREAM_METHODS 1
653 #define bus_space_read_stream_1 bus_space_read_1
654 #define bus_space_read_stream_2 bus_space_read_2
655 #define bus_space_read_stream_4 bus_space_read_4
656 #define bus_space_read_stream_8 bus_space_read_8
657 #define bus_space_read_multi_stream_1 bus_space_read_multi_1
658 #define bus_space_read_multi_stream_2 bus_space_read_multi_2
659 #define bus_space_read_multi_stream_4 bus_space_read_multi_4
660 #define bus_space_read_multi_stream_8 bus_space_read_multi_8
661 #define bus_space_read_region_stream_1 bus_space_read_region_1
662 #define bus_space_read_region_stream_2 bus_space_read_region_2
663 #define bus_space_read_region_stream_4 bus_space_read_region_4
664 #define bus_space_read_region_stream_8 bus_space_read_region_8
665 #define bus_space_write_stream_1 bus_space_write_1
666 #define bus_space_write_stream_2 bus_space_write_2
667 #define bus_space_write_stream_4 bus_space_write_4
668 #define bus_space_write_stream_8 bus_space_write_8
669 #define bus_space_write_multi_stream_1 bus_space_write_multi_1
670 #define bus_space_write_multi_stream_2 bus_space_write_multi_2
671 #define bus_space_write_multi_stream_4 bus_space_write_multi_4
672 #define bus_space_write_multi_stream_8 bus_space_write_multi_8
673 #define bus_space_write_region_stream_1 bus_space_write_region_1
674 #define bus_space_write_region_stream_2 bus_space_write_region_2
675 #define bus_space_write_region_stream_4 bus_space_write_region_4
676 #define bus_space_write_region_stream_8 bus_space_write_region_8
678 #endif /* _KERNEL */
681 * Flags used in various bus DMA methods.
683 #define BUS_DMA_WAITOK 0x000 /* safe to sleep (pseudo-flag) */
684 #define BUS_DMA_NOWAIT 0x001 /* not safe to sleep */
685 #define BUS_DMA_ALLOCNOW 0x002 /* perform resource allocation now */
686 #define BUS_DMA_COHERENT 0x004 /* hint: map memory DMA coherent */
687 #define BUS_DMA_STREAMING 0x008 /* hint: sequential, unidirectional */
688 #define BUS_DMA_BUS1 0x010 /* placeholders for bus functions... */
689 #define BUS_DMA_BUS2 0x020
690 #define BUS_DMA_BUS3 0x040
691 #define BUS_DMA_BUS4 0x080
692 #define BUS_DMA_READ 0x100 /* mapping is device -> memory only */
693 #define BUS_DMA_WRITE 0x200 /* mapping is memory -> device only */
694 #define BUS_DMA_NOCACHE 0x400 /* hint: map non-cached memory */
696 #define EWS4800MIPS_DMAMAP_COHERENT 0x10000 /* no cache flush necessary on sync */
698 /* Forwards needed by prototypes below. */
699 struct mbuf;
700 struct uio;
703 * Operations performed by bus_dmamap_sync().
705 #define BUS_DMASYNC_PREREAD 0x01 /* pre-read synchronization */
706 #define BUS_DMASYNC_POSTREAD 0x02 /* post-read synchronization */
707 #define BUS_DMASYNC_PREWRITE 0x04 /* pre-write synchronization */
708 #define BUS_DMASYNC_POSTWRITE 0x08 /* post-write synchronization */
710 typedef struct ews4800mips_bus_dma_tag *bus_dma_tag_t;
711 typedef struct ews4800mips_bus_dmamap *bus_dmamap_t;
713 #define BUS_DMA_TAG_VALID(t) ((t) != (bus_dma_tag_t)0)
716 * bus_dma_segment_t
718 * Describes a single contiguous DMA transaction. Values
719 * are suitable for programming into DMA registers.
721 struct ews4800mips_bus_dma_segment {
722 bus_addr_t ds_addr; /* DMA address */
723 bus_size_t ds_len; /* length of transfer */
724 vaddr_t _ds_vaddr; /* virtual address, 0 if invalid */
726 typedef struct ews4800mips_bus_dma_segment bus_dma_segment_t;
729 * bus_dma_tag_t
731 * A machine-dependent opaque type describing the implementation of
732 * DMA for a given bus.
735 struct ews4800mips_bus_dma_tag {
737 * DMA mapping methods.
739 int (*_dmamap_create)(bus_dma_tag_t, bus_size_t, int,
740 bus_size_t, bus_size_t, int, bus_dmamap_t *);
741 void (*_dmamap_destroy)(bus_dma_tag_t, bus_dmamap_t);
742 int (*_dmamap_load)(bus_dma_tag_t, bus_dmamap_t, void *,
743 bus_size_t, struct proc *, int);
744 int (*_dmamap_load_mbuf)(bus_dma_tag_t, bus_dmamap_t,
745 struct mbuf *, int);
746 int (*_dmamap_load_uio)(bus_dma_tag_t, bus_dmamap_t,
747 struct uio *, int);
748 int (*_dmamap_load_raw)(bus_dma_tag_t, bus_dmamap_t,
749 bus_dma_segment_t *, int, bus_size_t, int);
750 void (*_dmamap_unload)(bus_dma_tag_t, bus_dmamap_t);
751 void (*_dmamap_sync)(bus_dma_tag_t, bus_dmamap_t,
752 bus_addr_t, bus_size_t, int);
755 * DMA memory utility functions.
757 int (*_dmamem_alloc)(bus_dma_tag_t, bus_size_t, bus_size_t,
758 bus_size_t, bus_dma_segment_t *, int, int *, int);
759 void (*_dmamem_free)(bus_dma_tag_t,
760 bus_dma_segment_t *, int);
761 int (*_dmamem_map)(bus_dma_tag_t, bus_dma_segment_t *,
762 int, size_t, void **, int);
763 void (*_dmamem_unmap)(bus_dma_tag_t, void *, size_t);
764 paddr_t (*_dmamem_mmap)(bus_dma_tag_t, bus_dma_segment_t *,
765 int, off_t, int, int);
768 * DMA controller private.
770 void *_dmachip_cookie;
773 #define bus_dmamap_create(t, s, n, m, b, f, p) \
774 (*(t)->_dmamap_create)((t), (s), (n), (m), (b), (f), (p))
775 #define bus_dmamap_destroy(t, p) \
776 (*(t)->_dmamap_destroy)((t), (p))
777 #define bus_dmamap_load(t, m, b, s, p, f) \
778 (*(t)->_dmamap_load)((t), (m), (b), (s), (p), (f))
779 #define bus_dmamap_load_mbuf(t, m, b, f) \
780 (*(t)->_dmamap_load_mbuf)((t), (m), (b), (f))
781 #define bus_dmamap_load_uio(t, m, u, f) \
782 (*(t)->_dmamap_load_uio)((t), (m), (u), (f))
783 #define bus_dmamap_load_raw(t, m, sg, n, s, f) \
784 (*(t)->_dmamap_load_raw)((t), (m), (sg), (n), (s), (f))
785 #define bus_dmamap_unload(t, p) \
786 (*(t)->_dmamap_unload)((t), (p))
787 #define bus_dmamap_sync(t, p, o, l, ops) \
788 (*(t)->_dmamap_sync)((t), (p), (o), (l), (ops))
790 #define bus_dmamem_alloc(t, s, a, b, sg, n, r, f) \
791 (*(t)->_dmamem_alloc)((t), (s), (a), (b), (sg), (n), (r), (f))
792 #define bus_dmamem_free(t, sg, n) \
793 (*(t)->_dmamem_free)((t), (sg), (n))
794 #define bus_dmamem_map(t, sg, n, s, k, f) \
795 (*(t)->_dmamem_map)((t), (sg), (n), (s), (k), (f))
796 #define bus_dmamem_unmap(t, k, s) \
797 (*(t)->_dmamem_unmap)((t), (k), (s))
798 #define bus_dmamem_mmap(t, sg, n, o, p, f) \
799 (*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
801 #define bus_dmatag_subregion(t, mna, mxa, nt, f) EOPNOTSUPP
802 #define bus_dmatag_destroy(t)
805 * bus_dmamap_t
807 * Describes a DMA mapping.
809 struct ews4800mips_bus_dmamap {
811 * PRIVATE MEMBERS: not for use my machine-independent code.
813 bus_size_t _dm_size; /* largest DMA transfer mappable */
814 int _dm_segcnt; /* number of segs this map can map */
815 bus_size_t _dm_maxmaxsegsz; /* fixed largest possible segment */
816 bus_size_t _dm_boundary; /* don't cross this */
817 int _dm_flags; /* misc. flags */
818 struct vmspace *_dm_vmspace; /* vmspace that owns the mapping */
821 * PUBLIC MEMBERS: these are used by machine-independent code.
823 bus_size_t dm_maxsegsz; /* largest possible segment */
824 bus_size_t dm_mapsize; /* size of the mapping */
825 int dm_nsegs; /* # valid segments in mapping */
826 bus_dma_segment_t dm_segs[1]; /* segments; variable length */
829 #ifdef _EWS4800MIPS_BUS_DMA_PRIVATE
830 int _bus_dmamap_create(bus_dma_tag_t, bus_size_t, int, bus_size_t,
831 bus_size_t, int, bus_dmamap_t *);
832 void _bus_dmamap_destroy(bus_dma_tag_t, bus_dmamap_t);
833 int _bus_dmamap_load(bus_dma_tag_t, bus_dmamap_t, void *,
834 bus_size_t, struct proc *, int);
835 int _bus_dmamap_load_mbuf(bus_dma_tag_t, bus_dmamap_t,
836 struct mbuf *, int);
837 int _bus_dmamap_load_uio(bus_dma_tag_t, bus_dmamap_t,
838 struct uio *, int);
839 int _bus_dmamap_load_raw(bus_dma_tag_t, bus_dmamap_t,
840 bus_dma_segment_t *, int, bus_size_t, int);
841 void _bus_dmamap_unload(bus_dma_tag_t, bus_dmamap_t);
842 void _bus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t, bus_addr_t,
843 bus_size_t, int);
845 int _bus_dmamem_alloc(bus_dma_tag_t tag, bus_size_t size,
846 bus_size_t alignment, bus_size_t boundary,
847 bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags);
848 void _bus_dmamem_free(bus_dma_tag_t tag, bus_dma_segment_t *segs,
849 int nsegs);
850 int _bus_dmamem_map(bus_dma_tag_t tag, bus_dma_segment_t *segs,
851 int nsegs, size_t size, void **kvap, int flags);
852 void _bus_dmamem_unmap(bus_dma_tag_t tag, void *kva,
853 size_t size);
854 paddr_t _bus_dmamem_mmap(bus_dma_tag_t tag, bus_dma_segment_t *segs,
855 int nsegs, off_t off, int prot, int flags);
857 int _bus_dmamem_alloc_range(bus_dma_tag_t tag, bus_size_t size,
858 bus_size_t alignment, bus_size_t boundary,
859 bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags,
860 vaddr_t low, vaddr_t high);
862 extern struct ews4800mips_bus_dma_tag ews4800mips_default_bus_dma_tag;
863 #endif /* _EWS4800MIPS_BUS_DMA_PRIVATE */
865 #endif /* _EWS4800MIPS_BUS_H_ */