1 /* $NetBSD: bus.h,v 1.19 2008/04/28 20:23:14 martin Exp $ */
4 * Copyright (c) 1996, 1997, 1998, 2001 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9 * NASA Ames Research Center.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
34 * Copyright (c) 1996 Charles M. Hannum. All rights reserved.
35 * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions
40 * 1. Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in the
44 * documentation and/or other materials provided with the distribution.
45 * 3. All advertising materials mentioning features or use of this software
46 * must display the following acknowledgement:
47 * This product includes software developed by Christopher G. Demetriou
48 * for the NetBSD Project.
49 * 4. The name of the author may not be used to endorse or promote products
50 * derived from this software without specific prior written permission
52 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
53 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
54 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
55 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
56 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
57 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
58 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
59 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
60 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
61 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
67 #if defined(_KERNEL_OPT)
68 #include "opt_arm_bus_space.h"
72 * Addresses (in bus space).
74 typedef u_long bus_addr_t
;
75 typedef u_long bus_size_t
;
78 * Access methods for bus space.
80 typedef struct bus_space
*bus_space_tag_t
;
81 typedef u_long bus_space_handle_t
;
84 * int bus_space_map(bus_space_tag_t t, bus_addr_t addr,
85 * bus_size_t size, int flags, bus_space_handle_t *bshp);
87 * Map a region of bus space.
90 #define BUS_SPACE_MAP_CACHEABLE 0x01
91 #define BUS_SPACE_MAP_LINEAR 0x02
92 #define BUS_SPACE_MAP_PREFETCHABLE 0x04
98 /* mapping/unmapping */
99 int (*bs_map
)(void *, bus_addr_t
, bus_size_t
,
100 int, bus_space_handle_t
*);
101 void (*bs_unmap
)(void *, bus_space_handle_t
,
103 int (*bs_subregion
)(void *, bus_space_handle_t
,
104 bus_size_t
, bus_size_t
, bus_space_handle_t
*);
106 /* allocation/deallocation */
107 int (*bs_alloc
)(void *, bus_addr_t
, bus_addr_t
,
108 bus_size_t
, bus_size_t
, bus_size_t
, int,
109 bus_addr_t
*, bus_space_handle_t
*);
110 void (*bs_free
)(void *, bus_space_handle_t
,
113 /* get kernel virtual address */
114 void * (*bs_vaddr
)(void *, bus_space_handle_t
);
116 /* mmap bus space for user */
117 paddr_t (*bs_mmap
)(void *, bus_addr_t
, off_t
, int, int);
120 void (*bs_barrier
)(void *, bus_space_handle_t
,
121 bus_size_t
, bus_size_t
, int);
124 u_int8_t (*bs_r_1
)(void *, bus_space_handle_t
,
126 u_int16_t (*bs_r_2
)(void *, bus_space_handle_t
,
128 u_int32_t (*bs_r_4
)(void *, bus_space_handle_t
,
130 u_int64_t (*bs_r_8
)(void *, bus_space_handle_t
,
134 void (*bs_rm_1
)(void *, bus_space_handle_t
,
135 bus_size_t
, u_int8_t
*, bus_size_t
);
136 void (*bs_rm_2
)(void *, bus_space_handle_t
,
137 bus_size_t
, u_int16_t
*, bus_size_t
);
138 void (*bs_rm_4
)(void *, bus_space_handle_t
,
139 bus_size_t
, u_int32_t
*, bus_size_t
);
140 void (*bs_rm_8
)(void *, bus_space_handle_t
,
141 bus_size_t
, u_int64_t
*, bus_size_t
);
144 void (*bs_rr_1
)(void *, bus_space_handle_t
,
145 bus_size_t
, u_int8_t
*, bus_size_t
);
146 void (*bs_rr_2
)(void *, bus_space_handle_t
,
147 bus_size_t
, u_int16_t
*, bus_size_t
);
148 void (*bs_rr_4
)(void *, bus_space_handle_t
,
149 bus_size_t
, u_int32_t
*, bus_size_t
);
150 void (*bs_rr_8
)(void *, bus_space_handle_t
,
151 bus_size_t
, u_int64_t
*, bus_size_t
);
154 void (*bs_w_1
)(void *, bus_space_handle_t
,
155 bus_size_t
, u_int8_t
);
156 void (*bs_w_2
)(void *, bus_space_handle_t
,
157 bus_size_t
, u_int16_t
);
158 void (*bs_w_4
)(void *, bus_space_handle_t
,
159 bus_size_t
, u_int32_t
);
160 void (*bs_w_8
)(void *, bus_space_handle_t
,
161 bus_size_t
, u_int64_t
);
164 void (*bs_wm_1
)(void *, bus_space_handle_t
,
165 bus_size_t
, const u_int8_t
*, bus_size_t
);
166 void (*bs_wm_2
)(void *, bus_space_handle_t
,
167 bus_size_t
, const u_int16_t
*, bus_size_t
);
168 void (*bs_wm_4
)(void *, bus_space_handle_t
,
169 bus_size_t
, const u_int32_t
*, bus_size_t
);
170 void (*bs_wm_8
)(void *, bus_space_handle_t
,
171 bus_size_t
, const u_int64_t
*, bus_size_t
);
174 void (*bs_wr_1
)(void *, bus_space_handle_t
,
175 bus_size_t
, const u_int8_t
*, bus_size_t
);
176 void (*bs_wr_2
)(void *, bus_space_handle_t
,
177 bus_size_t
, const u_int16_t
*, bus_size_t
);
178 void (*bs_wr_4
)(void *, bus_space_handle_t
,
179 bus_size_t
, const u_int32_t
*, bus_size_t
);
180 void (*bs_wr_8
)(void *, bus_space_handle_t
,
181 bus_size_t
, const u_int64_t
*, bus_size_t
);
184 void (*bs_sm_1
)(void *, bus_space_handle_t
,
185 bus_size_t
, u_int8_t
, bus_size_t
);
186 void (*bs_sm_2
)(void *, bus_space_handle_t
,
187 bus_size_t
, u_int16_t
, bus_size_t
);
188 void (*bs_sm_4
)(void *, bus_space_handle_t
,
189 bus_size_t
, u_int32_t
, bus_size_t
);
190 void (*bs_sm_8
)(void *, bus_space_handle_t
,
191 bus_size_t
, u_int64_t
, bus_size_t
);
194 void (*bs_sr_1
)(void *, bus_space_handle_t
,
195 bus_size_t
, u_int8_t
, bus_size_t
);
196 void (*bs_sr_2
)(void *, bus_space_handle_t
,
197 bus_size_t
, u_int16_t
, bus_size_t
);
198 void (*bs_sr_4
)(void *, bus_space_handle_t
,
199 bus_size_t
, u_int32_t
, bus_size_t
);
200 void (*bs_sr_8
)(void *, bus_space_handle_t
,
201 bus_size_t
, u_int64_t
, bus_size_t
);
204 void (*bs_c_1
)(void *, bus_space_handle_t
, bus_size_t
,
205 bus_space_handle_t
, bus_size_t
, bus_size_t
);
206 void (*bs_c_2
)(void *, bus_space_handle_t
, bus_size_t
,
207 bus_space_handle_t
, bus_size_t
, bus_size_t
);
208 void (*bs_c_4
)(void *, bus_space_handle_t
, bus_size_t
,
209 bus_space_handle_t
, bus_size_t
, bus_size_t
);
210 void (*bs_c_8
)(void *, bus_space_handle_t
, bus_size_t
,
211 bus_space_handle_t
, bus_size_t
, bus_size_t
);
213 #ifdef __BUS_SPACE_HAS_STREAM_METHODS
214 /* read stream (single) */
215 u_int8_t (*bs_r_1_s
)(void *, bus_space_handle_t
,
217 u_int16_t (*bs_r_2_s
)(void *, bus_space_handle_t
,
219 u_int32_t (*bs_r_4_s
)(void *, bus_space_handle_t
,
221 u_int64_t (*bs_r_8_s
)(void *, bus_space_handle_t
,
224 /* read multiple stream */
225 void (*bs_rm_1_s
)(void *, bus_space_handle_t
,
226 bus_size_t
, u_int8_t
*, bus_size_t
);
227 void (*bs_rm_2_s
)(void *, bus_space_handle_t
,
228 bus_size_t
, u_int16_t
*, bus_size_t
);
229 void (*bs_rm_4_s
)(void *, bus_space_handle_t
,
230 bus_size_t
, u_int32_t
*, bus_size_t
);
231 void (*bs_rm_8_s
)(void *, bus_space_handle_t
,
232 bus_size_t
, u_int64_t
*, bus_size_t
);
234 /* read region stream */
235 void (*bs_rr_1_s
)(void *, bus_space_handle_t
,
236 bus_size_t
, u_int8_t
*, bus_size_t
);
237 void (*bs_rr_2_s
)(void *, bus_space_handle_t
,
238 bus_size_t
, u_int16_t
*, bus_size_t
);
239 void (*bs_rr_4_s
)(void *, bus_space_handle_t
,
240 bus_size_t
, u_int32_t
*, bus_size_t
);
241 void (*bs_rr_8_s
)(void *, bus_space_handle_t
,
242 bus_size_t
, u_int64_t
*, bus_size_t
);
244 /* write stream (single) */
245 void (*bs_w_1_s
)(void *, bus_space_handle_t
,
246 bus_size_t
, u_int8_t
);
247 void (*bs_w_2_s
)(void *, bus_space_handle_t
,
248 bus_size_t
, u_int16_t
);
249 void (*bs_w_4_s
)(void *, bus_space_handle_t
,
250 bus_size_t
, u_int32_t
);
251 void (*bs_w_8_s
)(void *, bus_space_handle_t
,
252 bus_size_t
, u_int64_t
);
254 /* write multiple stream */
255 void (*bs_wm_1_s
)(void *, bus_space_handle_t
,
256 bus_size_t
, const u_int8_t
*, bus_size_t
);
257 void (*bs_wm_2_s
)(void *, bus_space_handle_t
,
258 bus_size_t
, const u_int16_t
*, bus_size_t
);
259 void (*bs_wm_4_s
)(void *, bus_space_handle_t
,
260 bus_size_t
, const u_int32_t
*, bus_size_t
);
261 void (*bs_wm_8_s
)(void *, bus_space_handle_t
,
262 bus_size_t
, const u_int64_t
*, bus_size_t
);
264 /* write region stream */
265 void (*bs_wr_1_s
)(void *, bus_space_handle_t
,
266 bus_size_t
, const u_int8_t
*, bus_size_t
);
267 void (*bs_wr_2_s
)(void *, bus_space_handle_t
,
268 bus_size_t
, const u_int16_t
*, bus_size_t
);
269 void (*bs_wr_4_s
)(void *, bus_space_handle_t
,
270 bus_size_t
, const u_int32_t
*, bus_size_t
);
271 void (*bs_wr_8_s
)(void *, bus_space_handle_t
,
272 bus_size_t
, const u_int64_t
*, bus_size_t
);
273 #endif /* __BUS_SPACE_HAS_STREAM_METHODS */
278 * Utility macros; INTERNAL USE ONLY.
280 #define __bs_c(a,b) __CONCAT(a,b)
281 #define __bs_opname(op,size) __bs_c(__bs_c(__bs_c(bs_,op),_),size)
283 #define __bs_rs(sz, t, h, o) \
284 (*(t)->__bs_opname(r,sz))((t)->bs_cookie, h, o)
285 #define __bs_ws(sz, t, h, o, v) \
286 (*(t)->__bs_opname(w,sz))((t)->bs_cookie, h, o, v)
287 #define __bs_nonsingle(type, sz, t, h, o, a, c) \
288 (*(t)->__bs_opname(type,sz))((t)->bs_cookie, h, o, a, c)
289 #define __bs_set(type, sz, t, h, o, v, c) \
290 (*(t)->__bs_opname(type,sz))((t)->bs_cookie, h, o, v, c)
291 #define __bs_copy(sz, t, h1, o1, h2, o2, cnt) \
292 (*(t)->__bs_opname(c,sz))((t)->bs_cookie, h1, o1, h2, o2, cnt)
294 #ifdef __BUS_SPACE_HAS_STREAM_METHODS
295 #define __bs_opname_s(op,size) __bs_c(__bs_c(__bs_c(__bs_c(bs_,op),_),size),_s)
296 #define __bs_rs_s(sz, t, h, o) \
297 (*(t)->__bs_opname_s(r,sz))((t)->bs_cookie, h, o)
298 #define __bs_ws_s(sz, t, h, o, v) \
299 (*(t)->__bs_opname_s(w,sz))((t)->bs_cookie, h, o, v)
300 #define __bs_nonsingle_s(type, sz, t, h, o, a, c) \
301 (*(t)->__bs_opname_s(type,sz))((t)->bs_cookie, h, o, a, c)
302 #define __bs_set_s(type, sz, t, h, o, v, c) \
303 (*(t)->__bs_opname_s(type,sz))((t)->bs_cookie, h, o, v, c)
304 #define __bs_copy_s(sz, t, h1, o1, h2, o2, cnt) \
305 (*(t)->__bs_opname_s(c,sz))((t)->bs_cookie, h1, o1, h2, o2, cnt)
309 * Mapping and unmapping operations.
311 #define bus_space_map(t, a, s, c, hp) \
312 (*(t)->bs_map)((t)->bs_cookie, (a), (s), (c), (hp))
313 #define bus_space_unmap(t, h, s) \
314 (*(t)->bs_unmap)((t)->bs_cookie, (h), (s))
315 #define bus_space_subregion(t, h, o, s, hp) \
316 (*(t)->bs_subregion)((t)->bs_cookie, (h), (o), (s), (hp))
320 * Allocation and deallocation operations.
322 #define bus_space_alloc(t, rs, re, s, a, b, c, ap, hp) \
323 (*(t)->bs_alloc)((t)->bs_cookie, (rs), (re), (s), (a), (b), \
325 #define bus_space_free(t, h, s) \
326 (*(t)->bs_free)((t)->bs_cookie, (h), (s))
329 * Get kernel virtual address for ranges mapped BUS_SPACE_MAP_LINEAR.
331 #define bus_space_vaddr(t, h) \
332 (*(t)->bs_vaddr)((t)->bs_cookie, (h))
335 * MMap bus space for a user application.
337 #define bus_space_mmap(t, a, o, p, f) \
338 (*(t)->bs_mmap)((t)->bs_cookie, (a), (o), (p), (f))
341 * Bus barrier operations.
343 #define bus_space_barrier(t, h, o, l, f) \
344 (*(t)->bs_barrier)((t)->bs_cookie, (h), (o), (l), (f))
346 #define BUS_SPACE_BARRIER_READ 0x01
347 #define BUS_SPACE_BARRIER_WRITE 0x02
350 * Bus read (single) operations.
352 #define bus_space_read_1(t, h, o) __bs_rs(1,(t),(h),(o))
353 #define bus_space_read_2(t, h, o) __bs_rs(2,(t),(h),(o))
354 #define bus_space_read_4(t, h, o) __bs_rs(4,(t),(h),(o))
355 #define bus_space_read_8(t, h, o) __bs_rs(8,(t),(h),(o))
356 #ifdef __BUS_SPACE_HAS_STREAM_METHODS
357 #define bus_space_read_stream_1(t, h, o) __bs_rs_s(1,(t),(h),(o))
358 #define bus_space_read_stream_2(t, h, o) __bs_rs_s(2,(t),(h),(o))
359 #define bus_space_read_stream_4(t, h, o) __bs_rs_s(4,(t),(h),(o))
360 #define bus_space_read_stream_8(t, h, o) __bs_rs_s(8,(t),(h),(o))
365 * Bus read multiple operations.
367 #define bus_space_read_multi_1(t, h, o, a, c) \
368 __bs_nonsingle(rm,1,(t),(h),(o),(a),(c))
369 #define bus_space_read_multi_2(t, h, o, a, c) \
370 __bs_nonsingle(rm,2,(t),(h),(o),(a),(c))
371 #define bus_space_read_multi_4(t, h, o, a, c) \
372 __bs_nonsingle(rm,4,(t),(h),(o),(a),(c))
373 #define bus_space_read_multi_8(t, h, o, a, c) \
374 __bs_nonsingle(rm,8,(t),(h),(o),(a),(c))
375 #ifdef __BUS_SPACE_HAS_STREAM_METHODS
376 #define bus_space_read_multi_stream_1(t, h, o, a, c) \
377 __bs_nonsingle_s(rm,1,(t),(h),(o),(a),(c))
378 #define bus_space_read_multi_stream_2(t, h, o, a, c) \
379 __bs_nonsingle_s(rm,2,(t),(h),(o),(a),(c))
380 #define bus_space_read_multi_stream_4(t, h, o, a, c) \
381 __bs_nonsingle_s(rm,4,(t),(h),(o),(a),(c))
382 #define bus_space_read_multi_stream_8(t, h, o, a, c) \
383 __bs_nonsingle_s(rm,8,(t),(h),(o),(a),(c))
388 * Bus read region operations.
390 #define bus_space_read_region_1(t, h, o, a, c) \
391 __bs_nonsingle(rr,1,(t),(h),(o),(a),(c))
392 #define bus_space_read_region_2(t, h, o, a, c) \
393 __bs_nonsingle(rr,2,(t),(h),(o),(a),(c))
394 #define bus_space_read_region_4(t, h, o, a, c) \
395 __bs_nonsingle(rr,4,(t),(h),(o),(a),(c))
396 #define bus_space_read_region_8(t, h, o, a, c) \
397 __bs_nonsingle(rr,8,(t),(h),(o),(a),(c))
398 #ifdef __BUS_SPACE_HAS_STREAM_METHODS
399 #define bus_space_read_region_stream_1(t, h, o, a, c) \
400 __bs_nonsingle_s(rr,1,(t),(h),(o),(a),(c))
401 #define bus_space_read_region_stream_2(t, h, o, a, c) \
402 __bs_nonsingle_s(rr,2,(t),(h),(o),(a),(c))
403 #define bus_space_read_region_stream_4(t, h, o, a, c) \
404 __bs_nonsingle_s(rr,4,(t),(h),(o),(a),(c))
405 #define bus_space_read_region_stream_8(t, h, o, a, c) \
406 __bs_nonsingle_s(rr,8,(t),(h),(o),(a),(c))
411 * Bus write (single) operations.
413 #define bus_space_write_1(t, h, o, v) __bs_ws(1,(t),(h),(o),(v))
414 #define bus_space_write_2(t, h, o, v) __bs_ws(2,(t),(h),(o),(v))
415 #define bus_space_write_4(t, h, o, v) __bs_ws(4,(t),(h),(o),(v))
416 #define bus_space_write_8(t, h, o, v) __bs_ws(8,(t),(h),(o),(v))
417 #ifdef __BUS_SPACE_HAS_STREAM_METHODS
418 #define bus_space_write_stream_1(t, h, o, v) __bs_ws_s(1,(t),(h),(o),(v))
419 #define bus_space_write_stream_2(t, h, o, v) __bs_ws_s(2,(t),(h),(o),(v))
420 #define bus_space_write_stream_4(t, h, o, v) __bs_ws_s(4,(t),(h),(o),(v))
421 #define bus_space_write_stream_8(t, h, o, v) __bs_ws_s(8,(t),(h),(o),(v))
426 * Bus write multiple operations.
428 #define bus_space_write_multi_1(t, h, o, a, c) \
429 __bs_nonsingle(wm,1,(t),(h),(o),(a),(c))
430 #define bus_space_write_multi_2(t, h, o, a, c) \
431 __bs_nonsingle(wm,2,(t),(h),(o),(a),(c))
432 #define bus_space_write_multi_4(t, h, o, a, c) \
433 __bs_nonsingle(wm,4,(t),(h),(o),(a),(c))
434 #define bus_space_write_multi_8(t, h, o, a, c) \
435 __bs_nonsingle(wm,8,(t),(h),(o),(a),(c))
436 #ifdef __BUS_SPACE_HAS_STREAM_METHODS
437 #define bus_space_write_multi_stream_1(t, h, o, a, c) \
438 __bs_nonsingle_s(wm,1,(t),(h),(o),(a),(c))
439 #define bus_space_write_multi_stream_2(t, h, o, a, c) \
440 __bs_nonsingle_s(wm,2,(t),(h),(o),(a),(c))
441 #define bus_space_write_multi_stream_4(t, h, o, a, c) \
442 __bs_nonsingle_s(wm,4,(t),(h),(o),(a),(c))
443 #define bus_space_write_multi_stream_8(t, h, o, a, c) \
444 __bs_nonsingle_s(wm,8,(t),(h),(o),(a),(c))
449 * Bus write region operations.
451 #define bus_space_write_region_1(t, h, o, a, c) \
452 __bs_nonsingle(wr,1,(t),(h),(o),(a),(c))
453 #define bus_space_write_region_2(t, h, o, a, c) \
454 __bs_nonsingle(wr,2,(t),(h),(o),(a),(c))
455 #define bus_space_write_region_4(t, h, o, a, c) \
456 __bs_nonsingle(wr,4,(t),(h),(o),(a),(c))
457 #define bus_space_write_region_8(t, h, o, a, c) \
458 __bs_nonsingle(wr,8,(t),(h),(o),(a),(c))
459 #ifdef __BUS_SPACE_HAS_STREAM_METHODS
460 #define bus_space_write_region_stream_1(t, h, o, a, c) \
461 __bs_nonsingle_s(wr,1,(t),(h),(o),(a),(c))
462 #define bus_space_write_region_stream_2(t, h, o, a, c) \
463 __bs_nonsingle_s(wr,2,(t),(h),(o),(a),(c))
464 #define bus_space_write_region_stream_4(t, h, o, a, c) \
465 __bs_nonsingle_s(wr,4,(t),(h),(o),(a),(c))
466 #define bus_space_write_region_stream_8(t, h, o, a, c) \
467 __bs_nonsingle_s(wr,8,(t),(h),(o),(a),(c))
472 * Set multiple operations.
474 #define bus_space_set_multi_1(t, h, o, v, c) \
475 __bs_set(sm,1,(t),(h),(o),(v),(c))
476 #define bus_space_set_multi_2(t, h, o, v, c) \
477 __bs_set(sm,2,(t),(h),(o),(v),(c))
478 #define bus_space_set_multi_4(t, h, o, v, c) \
479 __bs_set(sm,4,(t),(h),(o),(v),(c))
480 #define bus_space_set_multi_8(t, h, o, v, c) \
481 __bs_set(sm,8,(t),(h),(o),(v),(c))
484 * Set region operations.
486 #define bus_space_set_region_1(t, h, o, v, c) \
487 __bs_set(sr,1,(t),(h),(o),(v),(c))
488 #define bus_space_set_region_2(t, h, o, v, c) \
489 __bs_set(sr,2,(t),(h),(o),(v),(c))
490 #define bus_space_set_region_4(t, h, o, v, c) \
491 __bs_set(sr,4,(t),(h),(o),(v),(c))
492 #define bus_space_set_region_8(t, h, o, v, c) \
493 __bs_set(sr,8,(t),(h),(o),(v),(c))
498 #define bus_space_copy_region_1(t, h1, o1, h2, o2, c) \
499 __bs_copy(1, t, h1, o1, h2, o2, c)
500 #define bus_space_copy_region_2(t, h1, o1, h2, o2, c) \
501 __bs_copy(2, t, h1, o1, h2, o2, c)
502 #define bus_space_copy_region_4(t, h1, o1, h2, o2, c) \
503 __bs_copy(4, t, h1, o1, h2, o2, c)
504 #define bus_space_copy_region_8(t, h1, o1, h2, o2, c) \
505 __bs_copy(8, t, h1, o1, h2, o2, c)
508 * Macros to provide prototypes for all the functions used in the
509 * bus_space structure
512 #define bs_map_proto(f) \
513 int __bs_c(f,_bs_map)(void *t, bus_addr_t addr, \
514 bus_size_t size, int cacheable, bus_space_handle_t *bshp);
516 #define bs_unmap_proto(f) \
517 void __bs_c(f,_bs_unmap)(void *t, bus_space_handle_t bsh, \
520 #define bs_subregion_proto(f) \
521 int __bs_c(f,_bs_subregion)(void *t, bus_space_handle_t bsh, \
522 bus_size_t offset, bus_size_t size, \
523 bus_space_handle_t *nbshp);
525 #define bs_alloc_proto(f) \
526 int __bs_c(f,_bs_alloc)(void *t, bus_addr_t rstart, \
527 bus_addr_t rend, bus_size_t size, bus_size_t align, \
528 bus_size_t boundary, int cacheable, bus_addr_t *addrp, \
529 bus_space_handle_t *bshp);
531 #define bs_free_proto(f) \
532 void __bs_c(f,_bs_free)(void *t, bus_space_handle_t bsh, \
535 #define bs_vaddr_proto(f) \
536 void * __bs_c(f,_bs_vaddr)(void *t, bus_space_handle_t bsh);
538 #define bs_mmap_proto(f) \
539 paddr_t __bs_c(f,_bs_mmap)(void *, bus_addr_t, off_t, int, int);
541 #define bs_barrier_proto(f) \
542 void __bs_c(f,_bs_barrier)(void *t, bus_space_handle_t bsh, \
543 bus_size_t offset, bus_size_t len, int flags);
545 #define bs_r_1_proto(f) \
546 u_int8_t __bs_c(f,_bs_r_1)(void *t, bus_space_handle_t bsh, \
549 #define bs_r_2_proto(f) \
550 u_int16_t __bs_c(f,_bs_r_2)(void *t, bus_space_handle_t bsh, \
553 #define bs_r_4_proto(f) \
554 u_int32_t __bs_c(f,_bs_r_4)(void *t, bus_space_handle_t bsh, \
557 #define bs_r_8_proto(f) \
558 u_int64_t __bs_c(f,_bs_r_8)(void *t, bus_space_handle_t bsh, \
561 #define bs_w_1_proto(f) \
562 void __bs_c(f,_bs_w_1)(void *t, bus_space_handle_t bsh, \
563 bus_size_t offset, u_int8_t value);
565 #define bs_w_2_proto(f) \
566 void __bs_c(f,_bs_w_2)(void *t, bus_space_handle_t bsh, \
567 bus_size_t offset, u_int16_t value);
569 #define bs_w_4_proto(f) \
570 void __bs_c(f,_bs_w_4)(void *t, bus_space_handle_t bsh, \
571 bus_size_t offset, u_int32_t value);
573 #define bs_w_8_proto(f) \
574 void __bs_c(f,_bs_w_8)(void *t, bus_space_handle_t bsh, \
575 bus_size_t offset, u_int64_t value);
577 #define bs_rm_1_proto(f) \
578 void __bs_c(f,_bs_rm_1)(void *t, bus_space_handle_t bsh, \
579 bus_size_t offset, u_int8_t *addr, bus_size_t count);
581 #define bs_rm_2_proto(f) \
582 void __bs_c(f,_bs_rm_2)(void *t, bus_space_handle_t bsh, \
583 bus_size_t offset, u_int16_t *addr, bus_size_t count);
585 #define bs_rm_4_proto(f) \
586 void __bs_c(f,_bs_rm_4)(void *t, bus_space_handle_t bsh, \
587 bus_size_t offset, u_int32_t *addr, bus_size_t count);
589 #define bs_rm_8_proto(f) \
590 void __bs_c(f,_bs_rm_8)(void *t, bus_space_handle_t bsh, \
591 bus_size_t offset, u_int64_t *addr, bus_size_t count);
593 #define bs_wm_1_proto(f) \
594 void __bs_c(f,_bs_wm_1)(void *t, bus_space_handle_t bsh, \
595 bus_size_t offset, const u_int8_t *addr, bus_size_t count);
597 #define bs_wm_2_proto(f) \
598 void __bs_c(f,_bs_wm_2)(void *t, bus_space_handle_t bsh, \
599 bus_size_t offset, const u_int16_t *addr, bus_size_t count);
601 #define bs_wm_4_proto(f) \
602 void __bs_c(f,_bs_wm_4)(void *t, bus_space_handle_t bsh, \
603 bus_size_t offset, const u_int32_t *addr, bus_size_t count);
605 #define bs_wm_8_proto(f) \
606 void __bs_c(f,_bs_wm_8)(void *t, bus_space_handle_t bsh, \
607 bus_size_t offset, const u_int64_t *addr, bus_size_t count);
609 #define bs_rr_1_proto(f) \
610 void __bs_c(f, _bs_rr_1)(void *t, bus_space_handle_t bsh, \
611 bus_size_t offset, u_int8_t *addr, bus_size_t count);
613 #define bs_rr_2_proto(f) \
614 void __bs_c(f, _bs_rr_2)(void *t, bus_space_handle_t bsh, \
615 bus_size_t offset, u_int16_t *addr, bus_size_t count);
617 #define bs_rr_4_proto(f) \
618 void __bs_c(f, _bs_rr_4)(void *t, bus_space_handle_t bsh, \
619 bus_size_t offset, u_int32_t *addr, bus_size_t count);
621 #define bs_rr_8_proto(f) \
622 void __bs_c(f, _bs_rr_8)(void *t, bus_space_handle_t bsh, \
623 bus_size_t offset, u_int64_t *addr, bus_size_t count);
625 #define bs_wr_1_proto(f) \
626 void __bs_c(f, _bs_wr_1)(void *t, bus_space_handle_t bsh, \
627 bus_size_t offset, const u_int8_t *addr, bus_size_t count);
629 #define bs_wr_2_proto(f) \
630 void __bs_c(f, _bs_wr_2)(void *t, bus_space_handle_t bsh, \
631 bus_size_t offset, const u_int16_t *addr, bus_size_t count);
633 #define bs_wr_4_proto(f) \
634 void __bs_c(f, _bs_wr_4)(void *t, bus_space_handle_t bsh, \
635 bus_size_t offset, const u_int32_t *addr, bus_size_t count);
637 #define bs_wr_8_proto(f) \
638 void __bs_c(f, _bs_wr_8)(void *t, bus_space_handle_t bsh, \
639 bus_size_t offset, const u_int64_t *addr, bus_size_t count);
641 #define bs_sm_1_proto(f) \
642 void __bs_c(f,_bs_sm_1)(void *t, bus_space_handle_t bsh, \
643 bus_size_t offset, u_int8_t value, bus_size_t count);
645 #define bs_sm_2_proto(f) \
646 void __bs_c(f,_bs_sm_2)(void *t, bus_space_handle_t bsh, \
647 bus_size_t offset, u_int16_t value, bus_size_t count);
649 #define bs_sm_4_proto(f) \
650 void __bs_c(f,_bs_sm_4)(void *t, bus_space_handle_t bsh, \
651 bus_size_t offset, u_int32_t value, bus_size_t count);
653 #define bs_sm_8_proto(f) \
654 void __bs_c(f,_bs_sm_8)(void *t, bus_space_handle_t bsh, \
655 bus_size_t offset, u_int64_t value, bus_size_t count);
657 #define bs_sr_1_proto(f) \
658 void __bs_c(f,_bs_sr_1)(void *t, bus_space_handle_t bsh, \
659 bus_size_t offset, u_int8_t value, bus_size_t count);
661 #define bs_sr_2_proto(f) \
662 void __bs_c(f,_bs_sr_2)(void *t, bus_space_handle_t bsh, \
663 bus_size_t offset, u_int16_t value, bus_size_t count);
665 #define bs_sr_4_proto(f) \
666 void __bs_c(f,_bs_sr_4)(void *t, bus_space_handle_t bsh, \
667 bus_size_t offset, u_int32_t value, bus_size_t count);
669 #define bs_sr_8_proto(f) \
670 void __bs_c(f,_bs_sr_8)(void *t, bus_space_handle_t bsh, \
671 bus_size_t offset, u_int64_t value, bus_size_t count);
673 #define bs_c_1_proto(f) \
674 void __bs_c(f,_bs_c_1)(void *t, bus_space_handle_t bsh1, \
675 bus_size_t offset1, bus_space_handle_t bsh2, \
676 bus_size_t offset2, bus_size_t count);
678 #define bs_c_2_proto(f) \
679 void __bs_c(f,_bs_c_2)(void *t, bus_space_handle_t bsh1, \
680 bus_size_t offset1, bus_space_handle_t bsh2, \
681 bus_size_t offset2, bus_size_t count);
683 #define bs_c_4_proto(f) \
684 void __bs_c(f,_bs_c_4)(void *t, bus_space_handle_t bsh1, \
685 bus_size_t offset1, bus_space_handle_t bsh2, \
686 bus_size_t offset2, bus_size_t count);
688 #define bs_c_8_proto(f) \
689 void __bs_c(f,_bs_c_8)(void *t, bus_space_handle_t bsh1, \
690 bus_size_t offset1, bus_space_handle_t bsh2, \
691 bus_size_t offset2, bus_size_t count);
693 #define bs_protos(f) \
696 bs_subregion_proto(f); \
701 bs_barrier_proto(f); \
739 #define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t)
741 /* Bus Space DMA macros */
744 * Flags used in various bus DMA methods.
746 #define BUS_DMA_WAITOK 0x000 /* safe to sleep (pseudo-flag) */
747 #define BUS_DMA_NOWAIT 0x001 /* not safe to sleep */
748 #define BUS_DMA_ALLOCNOW 0x002 /* perform resource allocation now */
749 #define BUS_DMA_COHERENT 0x004 /* hint: map memory DMA coherent */
750 #define BUS_DMA_STREAMING 0x008 /* hint: sequential, unidirectional */
751 #define BUS_DMA_BUS1 0x010 /* placeholders for bus functions... */
752 #define BUS_DMA_BUS2 0x020
753 #define BUS_DMA_BUS3 0x040
754 #define BUS_DMA_BUS4 0x080
755 #define BUS_DMA_READ 0x100 /* mapping is device -> memory only */
756 #define BUS_DMA_WRITE 0x200 /* mapping is memory -> device only */
757 #define BUS_DMA_NOCACHE 0x400 /* hint: map non-cached memory */
760 * Private flags stored in the DMA map.
762 #define ARM32_DMAMAP_COHERENT 0x10000 /* no cache flush necessary on sync */
764 /* Forwards needed by prototypes below. */
769 * Operations performed by bus_dmamap_sync().
771 #define BUS_DMASYNC_PREREAD 0x01 /* pre-read synchronization */
772 #define BUS_DMASYNC_POSTREAD 0x02 /* post-read synchronization */
773 #define BUS_DMASYNC_PREWRITE 0x04 /* pre-write synchronization */
774 #define BUS_DMASYNC_POSTWRITE 0x08 /* post-write synchronization */
776 typedef struct arm32_bus_dma_tag
*bus_dma_tag_t
;
777 typedef struct arm32_bus_dmamap
*bus_dmamap_t
;
779 #define BUS_DMA_TAG_VALID(t) ((t) != (bus_dma_tag_t)0)
784 * Describes a single contiguous DMA transaction. Values
785 * are suitable for programming into DMA registers.
787 struct arm32_bus_dma_segment
{
789 * PUBLIC MEMBERS: these are used by machine-independent code.
791 bus_addr_t ds_addr
; /* DMA address */
792 bus_size_t ds_len
; /* length of transfer */
794 typedef struct arm32_bus_dma_segment bus_dma_segment_t
;
799 * This structure describes a valid DMA range.
801 struct arm32_dma_range
{
802 bus_addr_t dr_sysbase
; /* system base address */
803 bus_addr_t dr_busbase
; /* appears here on bus */
804 bus_size_t dr_len
; /* length of range */
810 * A machine-dependent opaque type describing the implementation of
811 * DMA for a given bus.
814 struct arm32_bus_dma_tag
{
816 * DMA range for this tag. If the page doesn't fall within
817 * one of these ranges, an error is returned. The caller
818 * may then decide what to do with the transfer. If the
819 * range pointer is NULL, it is ignored.
821 struct arm32_dma_range
*_ranges
;
825 * Opaque cookie for use by back-end.
830 * DMA mapping methods.
832 int (*_dmamap_create
)(bus_dma_tag_t
, bus_size_t
, int,
833 bus_size_t
, bus_size_t
, int, bus_dmamap_t
*);
834 void (*_dmamap_destroy
)(bus_dma_tag_t
, bus_dmamap_t
);
835 int (*_dmamap_load
)(bus_dma_tag_t
, bus_dmamap_t
, void *,
836 bus_size_t
, struct proc
*, int);
837 int (*_dmamap_load_mbuf
)(bus_dma_tag_t
, bus_dmamap_t
,
839 int (*_dmamap_load_uio
)(bus_dma_tag_t
, bus_dmamap_t
,
841 int (*_dmamap_load_raw
)(bus_dma_tag_t
, bus_dmamap_t
,
842 bus_dma_segment_t
*, int, bus_size_t
, int);
843 void (*_dmamap_unload
)(bus_dma_tag_t
, bus_dmamap_t
);
844 void (*_dmamap_sync_pre
)(bus_dma_tag_t
, bus_dmamap_t
,
845 bus_addr_t
, bus_size_t
, int);
846 void (*_dmamap_sync_post
)(bus_dma_tag_t
, bus_dmamap_t
,
847 bus_addr_t
, bus_size_t
, int);
850 * DMA memory utility functions.
852 int (*_dmamem_alloc
)(bus_dma_tag_t
, bus_size_t
, bus_size_t
,
853 bus_size_t
, bus_dma_segment_t
*, int, int *, int);
854 void (*_dmamem_free
)(bus_dma_tag_t
,
855 bus_dma_segment_t
*, int);
856 int (*_dmamem_map
)(bus_dma_tag_t
, bus_dma_segment_t
*,
857 int, size_t, void **, int);
858 void (*_dmamem_unmap
)(bus_dma_tag_t
, void *, size_t);
859 paddr_t (*_dmamem_mmap
)(bus_dma_tag_t
, bus_dma_segment_t
*,
860 int, off_t
, int, int);
863 #define bus_dmamap_create(t, s, n, m, b, f, p) \
864 (*(t)->_dmamap_create)((t), (s), (n), (m), (b), (f), (p))
865 #define bus_dmamap_destroy(t, p) \
866 (*(t)->_dmamap_destroy)((t), (p))
867 #define bus_dmamap_load(t, m, b, s, p, f) \
868 (*(t)->_dmamap_load)((t), (m), (b), (s), (p), (f))
869 #define bus_dmamap_load_mbuf(t, m, b, f) \
870 (*(t)->_dmamap_load_mbuf)((t), (m), (b), (f))
871 #define bus_dmamap_load_uio(t, m, u, f) \
872 (*(t)->_dmamap_load_uio)((t), (m), (u), (f))
873 #define bus_dmamap_load_raw(t, m, sg, n, s, f) \
874 (*(t)->_dmamap_load_raw)((t), (m), (sg), (n), (s), (f))
875 #define bus_dmamap_unload(t, p) \
876 (*(t)->_dmamap_unload)((t), (p))
877 #define bus_dmamap_sync(t, p, o, l, ops) \
879 if (((ops) & (BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE)) != 0 \
880 && (t)->_dmamap_sync_pre != NULL) \
881 (*(t)->_dmamap_sync_pre)((t), (p), (o), (l), (ops)); \
882 else if (((ops) & (BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE)) != 0 \
883 && (t)->_dmamap_sync_post != NULL) \
884 (*(t)->_dmamap_sync_post)((t), (p), (o), (l), (ops)); \
885 } while (/*CONSTCOND*/0)
887 #define bus_dmamem_alloc(t, s, a, b, sg, n, r, f) \
888 (*(t)->_dmamem_alloc)((t), (s), (a), (b), (sg), (n), (r), (f))
889 #define bus_dmamem_free(t, sg, n) \
890 (*(t)->_dmamem_free)((t), (sg), (n))
891 #define bus_dmamem_map(t, sg, n, s, k, f) \
892 (*(t)->_dmamem_map)((t), (sg), (n), (s), (k), (f))
893 #define bus_dmamem_unmap(t, k, s) \
894 (*(t)->_dmamem_unmap)((t), (k), (s))
895 #define bus_dmamem_mmap(t, sg, n, o, p, f) \
896 (*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
898 #define bus_dmatag_subregion(t, mna, mxa, nt, f) EOPNOTSUPP
899 #define bus_dmatag_destroy(t)
904 * Describes a DMA mapping.
906 struct arm32_bus_dmamap
{
908 * PRIVATE MEMBERS: not for use by machine-independent code.
910 bus_size_t _dm_size
; /* largest DMA transfer mappable */
911 int _dm_segcnt
; /* number of segs this map can map */
912 bus_size_t _dm_maxmaxsegsz
; /* fixed largest possible segment */
913 bus_size_t _dm_boundary
; /* don't cross this */
914 int _dm_flags
; /* misc. flags */
916 void *_dm_origbuf
; /* pointer to original buffer */
917 int _dm_buftype
; /* type of buffer */
918 struct vmspace
*_dm_vmspace
; /* vmspace that owns the mapping */
920 void *_dm_cookie
; /* cookie for bus-specific functions */
923 * PUBLIC MEMBERS: these are used by machine-independent code.
925 bus_size_t dm_maxsegsz
; /* largest possible segment */
926 bus_size_t dm_mapsize
; /* size of the mapping */
927 int dm_nsegs
; /* # valid segments in mapping */
928 bus_dma_segment_t dm_segs
[1]; /* segments; variable length */
931 #ifdef _ARM32_BUS_DMA_PRIVATE
934 #define ARM32_BUFTYPE_INVALID 0
935 #define ARM32_BUFTYPE_LINEAR 1
936 #define ARM32_BUFTYPE_MBUF 2
937 #define ARM32_BUFTYPE_UIO 3
938 #define ARM32_BUFTYPE_RAW 4
940 int arm32_dma_range_intersect(struct arm32_dma_range
*, int,
941 paddr_t pa
, psize_t size
, paddr_t
*pap
, psize_t
*sizep
);
943 int _bus_dmamap_create(bus_dma_tag_t
, bus_size_t
, int, bus_size_t
,
944 bus_size_t
, int, bus_dmamap_t
*);
945 void _bus_dmamap_destroy(bus_dma_tag_t
, bus_dmamap_t
);
946 int _bus_dmamap_load(bus_dma_tag_t
, bus_dmamap_t
, void *,
947 bus_size_t
, struct proc
*, int);
948 int _bus_dmamap_load_mbuf(bus_dma_tag_t
, bus_dmamap_t
,
950 int _bus_dmamap_load_uio(bus_dma_tag_t
, bus_dmamap_t
,
952 int _bus_dmamap_load_raw(bus_dma_tag_t
, bus_dmamap_t
,
953 bus_dma_segment_t
*, int, bus_size_t
, int);
954 void _bus_dmamap_unload(bus_dma_tag_t
, bus_dmamap_t
);
955 void _bus_dmamap_sync(bus_dma_tag_t
, bus_dmamap_t
, bus_addr_t
,
958 int _bus_dmamem_alloc(bus_dma_tag_t tag
, bus_size_t size
,
959 bus_size_t alignment
, bus_size_t boundary
,
960 bus_dma_segment_t
*segs
, int nsegs
, int *rsegs
, int flags
);
961 void _bus_dmamem_free(bus_dma_tag_t tag
, bus_dma_segment_t
*segs
,
963 int _bus_dmamem_map(bus_dma_tag_t tag
, bus_dma_segment_t
*segs
,
964 int nsegs
, size_t size
, void **kvap
, int flags
);
965 void _bus_dmamem_unmap(bus_dma_tag_t tag
, void *kva
,
967 paddr_t
_bus_dmamem_mmap(bus_dma_tag_t tag
, bus_dma_segment_t
*segs
,
968 int nsegs
, off_t off
, int prot
, int flags
);
970 int _bus_dmamem_alloc_range(bus_dma_tag_t tag
, bus_size_t size
,
971 bus_size_t alignment
, bus_size_t boundary
,
972 bus_dma_segment_t
*segs
, int nsegs
, int *rsegs
, int flags
,
973 vaddr_t low
, vaddr_t high
);
974 #endif /* _ARM32_BUS_DMA_PRIVATE */
976 #endif /* _ARM32_BUS_H_ */