1/* $OpenBSD: bus.h,v 1.19 2025/08/11 07:18:40 miod Exp $ */
2/* $NetBSD: bus.h,v 1.12 2003/10/23 15:03:24 scw Exp $ */
3
4/*-
5 * Copyright (c) 1996, 1997, 1998, 2001 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
10 * NASA Ames Research Center.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33
34/*
35 * Copyright (c) 1996 Charles M. Hannum. All rights reserved.
36 * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
37 *
38 * Redistribution and use in source and binary forms, with or without
39 * modification, are permitted provided that the following conditions
40 * are met:
41 * 1. Redistributions of source code must retain the above copyright
42 * notice, this list of conditions and the following disclaimer.
43 * 2. Redistributions in binary form must reproduce the above copyright
44 * notice, this list of conditions and the following disclaimer in the
45 * documentation and/or other materials provided with the distribution.
46 * 3. All advertising materials mentioning features or use of this software
47 * must display the following acknowledgement:
48 * This product includes software developed by Christopher G. Demetriou
49 * for the NetBSD Project.
50 * 4. The name of the author may not be used to endorse or promote products
51 * derived from this software without specific prior written permission
52 *
53 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
54 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
55 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
56 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
57 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
58 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
59 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
60 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
61 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
62 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
63 */
64
65#ifndef _ARM_BUS_H_
66#define _ARM_BUS_H_
67
68/*
69 * Addresses (in bus space).
70 */
71typedef u_long bus_addr_t;
72typedef u_long bus_size_t;
73
74/*
75 * Access methods for bus space.
76 */
77typedef struct bus_space *bus_space_tag_t;
78typedef u_long bus_space_handle_t;
79
80/*
81 * int bus_space_map (bus_space_tag_t t, bus_addr_t addr,
82 * bus_size_t size, int flags, bus_space_handle_t *bshp);
83 *
84 * Map a region of bus space.
85 */
86
87#define BUS_SPACE_MAP_CACHEABLE 0x01
88#define BUS_SPACE_MAP_LINEAR 0x02
89#define BUS_SPACE_MAP_PREFETCHABLE 0x04
90
91struct bus_space {
92 /* cookie */
93 void *bs_cookie;
94
95 /* mapping/unmapping */
96 int (*bs_map) (void *, uint64_t, bus_size_t,
97 int, bus_space_handle_t *);
98 void (*bs_unmap) (void *, bus_space_handle_t,
99 bus_size_t);
100 int (*bs_subregion) (void *, bus_space_handle_t,
101 bus_size_t, bus_size_t, bus_space_handle_t *);
102
103 /* allocation/deallocation */
104 int (*bs_alloc) (void *, bus_addr_t, bus_addr_t,
105 bus_size_t, bus_size_t, bus_size_t, int,
106 bus_addr_t *, bus_space_handle_t *);
107 void (*bs_free) (void *, bus_space_handle_t,
108 bus_size_t);
109
110 /* get kernel virtual address */
111 void * (*bs_vaddr) (void *, bus_space_handle_t);
112
113 /* mmap bus space for user */
114 paddr_t (*bs_mmap) (void *, bus_addr_t, off_t, int, int);
115
116 /* barrier */
117 void (*bs_barrier) (void *, bus_space_handle_t,
118 bus_size_t, bus_size_t, int);
119
120 /* read (single) */
121 u_int8_t (*bs_r_1) (void *, bus_space_handle_t,
122 bus_size_t);
123 u_int16_t (*bs_r_2) (void *, bus_space_handle_t,
124 bus_size_t);
125 u_int32_t (*bs_r_4) (void *, bus_space_handle_t,
126 bus_size_t);
127 u_int64_t (*bs_r_8) (void *, bus_space_handle_t,
128 bus_size_t);
129
130 /* read multiple */
131 void (*bs_rm_1) (void *, bus_space_handle_t,
132 bus_size_t, u_int8_t *, bus_size_t);
133 void (*bs_rm_2) (void *, bus_space_handle_t,
134 bus_size_t, u_int16_t *, bus_size_t);
135 void (*bs_rm_4) (void *, bus_space_handle_t,
136 bus_size_t, u_int32_t *, bus_size_t);
137 void (*bs_rm_8) (void *, bus_space_handle_t,
138 bus_size_t, u_int64_t *, bus_size_t);
139
140 /* read region */
141 void (*bs_rr_1) (void *, bus_space_handle_t,
142 bus_size_t, u_int8_t *, bus_size_t);
143 void (*bs_rr_2) (void *, bus_space_handle_t,
144 bus_size_t, u_int16_t *, bus_size_t);
145 void (*bs_rr_4) (void *, bus_space_handle_t,
146 bus_size_t, u_int32_t *, bus_size_t);
147 void (*bs_rr_8) (void *, bus_space_handle_t,
148 bus_size_t, u_int64_t *, bus_size_t);
149
150 /* write (single) */
151 void (*bs_w_1) (void *, bus_space_handle_t,
152 bus_size_t, u_int8_t);
153 void (*bs_w_2) (void *, bus_space_handle_t,
154 bus_size_t, u_int16_t);
155 void (*bs_w_4) (void *, bus_space_handle_t,
156 bus_size_t, u_int32_t);
157 void (*bs_w_8) (void *, bus_space_handle_t,
158 bus_size_t, u_int64_t);
159
160 /* write multiple */
161 void (*bs_wm_1) (void *, bus_space_handle_t,
162 bus_size_t, const u_int8_t *, bus_size_t);
163 void (*bs_wm_2) (void *, bus_space_handle_t,
164 bus_size_t, const u_int16_t *, bus_size_t);
165 void (*bs_wm_4) (void *, bus_space_handle_t,
166 bus_size_t, const u_int32_t *, bus_size_t);
167 void (*bs_wm_8) (void *, bus_space_handle_t,
168 bus_size_t, const u_int64_t *, bus_size_t);
169
170 /* write region */
171 void (*bs_wr_1) (void *, bus_space_handle_t,
172 bus_size_t, const u_int8_t *, bus_size_t);
173 void (*bs_wr_2) (void *, bus_space_handle_t,
174 bus_size_t, const u_int16_t *, bus_size_t);
175 void (*bs_wr_4) (void *, bus_space_handle_t,
176 bus_size_t, const u_int32_t *, bus_size_t);
177 void (*bs_wr_8) (void *, bus_space_handle_t,
178 bus_size_t, const u_int64_t *, bus_size_t);
179
180 /* set multiple */
181 void (*bs_sm_1) (void *, bus_space_handle_t,
182 bus_size_t, u_int8_t, bus_size_t);
183 void (*bs_sm_2) (void *, bus_space_handle_t,
184 bus_size_t, u_int16_t, bus_size_t);
185 void (*bs_sm_4) (void *, bus_space_handle_t,
186 bus_size_t, u_int32_t, bus_size_t);
187 void (*bs_sm_8) (void *, bus_space_handle_t,
188 bus_size_t, u_int64_t, bus_size_t);
189
190 /* set region */
191 void (*bs_sr_1) (void *, bus_space_handle_t,
192 bus_size_t, u_int8_t, bus_size_t);
193 void (*bs_sr_2) (void *, bus_space_handle_t,
194 bus_size_t, u_int16_t, bus_size_t);
195 void (*bs_sr_4) (void *, bus_space_handle_t,
196 bus_size_t, u_int32_t, bus_size_t);
197 void (*bs_sr_8) (void *, bus_space_handle_t,
198 bus_size_t, u_int64_t, bus_size_t);
199
200 /* copy */
201 void (*bs_c_1) (void *, bus_space_handle_t, bus_size_t,
202 bus_space_handle_t, bus_size_t, bus_size_t);
203 void (*bs_c_2) (void *, bus_space_handle_t, bus_size_t,
204 bus_space_handle_t, bus_size_t, bus_size_t);
205 void (*bs_c_4) (void *, bus_space_handle_t, bus_size_t,
206 bus_space_handle_t, bus_size_t, bus_size_t);
207 void (*bs_c_8) (void *, bus_space_handle_t, bus_size_t,
208 bus_space_handle_t, bus_size_t, bus_size_t);
209};
210
211
212/*
213 * Utility macros; INTERNAL USE ONLY.
214 */
215#define __bs_c(a,b) __CONCAT(a,b)
216#define __bs_opname(op,size) __bs_c(__bs_c(__bs_c(bs_,op),_),size)
217
218#define __bs_rs(sz, t, h, o) \
219 (*(t)->__bs_opname(r,sz))((t)->bs_cookie, h, o)
220#define __bs_ws(sz, t, h, o, v) \
221 (*(t)->__bs_opname(w,sz))((t)->bs_cookie, h, o, v)
222#define __bs_nonsingle(type, sz, t, h, o, a, c) \
223 (*(t)->__bs_opname(type,sz))((t)->bs_cookie, h, o, a, c)
224#define __bs_set(type, sz, t, h, o, v, c) \
225 (*(t)->__bs_opname(type,sz))((t)->bs_cookie, h, o, v, c)
226#define __bs_copy(sz, t, h1, o1, h2, o2, cnt) \
227 (*(t)->__bs_opname(c,sz))((t)->bs_cookie, h1, o1, h2, o2, cnt)
228
229/*
230 * Mapping and unmapping operations.
231 */
232#define bus_space_map(t, a, s, c, hp) \
233 (*(t)->bs_map)((t)->bs_cookie, (a), (s), (c), (hp))
234#define bus_space_unmap(t, h, s) \
235 (*(t)->bs_unmap)((t)->bs_cookie, (h), (s))
236#define bus_space_subregion(t, h, o, s, hp) \
237 (*(t)->bs_subregion)((t)->bs_cookie, (h), (o), (s), (hp))
238
239
240/*
241 * Allocation and deallocation operations.
242 */
243#define bus_space_alloc(t, rs, re, s, a, b, c, ap, hp) \
244 (*(t)->bs_alloc)((t)->bs_cookie, (rs), (re), (s), (a), (b), \
245 (c), (ap), (hp))
246#define bus_space_free(t, h, s) \
247 (*(t)->bs_free)((t)->bs_cookie, (h), (s))
248
249/*
250 * Get kernel virtual address for ranges mapped BUS_SPACE_MAP_LINEAR.
251 */
252#define bus_space_vaddr(t, h) \
253 (*(t)->bs_vaddr)((t)->bs_cookie, (h))
254
255/*
256 * MMap bus space for a user application.
257 */
258#define bus_space_mmap(t, a, o, p, f) \
259 (*(t)->bs_mmap)((t)->bs_cookie, (a), (o), (p), (f))
260
261/*
262 * Bus barrier operations.
263 */
264#define bus_space_barrier(t, h, o, l, f) \
265 (*(t)->bs_barrier)((t)->bs_cookie, (h), (o), (l), (f))
266
267#define BUS_SPACE_BARRIER_READ 0x01
268#define BUS_SPACE_BARRIER_WRITE 0x02
269
270/*
271 * Bus read (single) operations.
272 */
273#define bus_space_read_1(t, h, o) __bs_rs(1,(t),(h),(o))
274#define bus_space_read_2(t, h, o) __bs_rs(2,(t),(h),(o))
275#define bus_space_read_4(t, h, o) __bs_rs(4,(t),(h),(o))
276#define bus_space_read_8(t, h, o) __bs_rs(8,(t),(h),(o))
277
278/*
279 * Bus read multiple operations.
280 */
281#define bus_space_read_multi_1(t, h, o, a, c) \
282 __bs_nonsingle(rm,1,(t),(h),(o),(a),(c))
283#define bus_space_read_multi_2(t, h, o, a, c) \
284 __bs_nonsingle(rm,2,(t),(h),(o),(a),(c))
285#define bus_space_read_multi_4(t, h, o, a, c) \
286 __bs_nonsingle(rm,4,(t),(h),(o),(a),(c))
287#define bus_space_read_multi_8(t, h, o, a, c) \
288 __bs_nonsingle(rm,8,(t),(h),(o),(a),(c))
289
290/*
291 * Bus read region operations.
292 */
293#define bus_space_read_region_1(t, h, o, a, c) \
294 __bs_nonsingle(rr,1,(t),(h),(o),(a),(c))
295#define bus_space_read_region_2(t, h, o, a, c) \
296 __bs_nonsingle(rr,2,(t),(h),(o),(a),(c))
297#define bus_space_read_region_4(t, h, o, a, c) \
298 __bs_nonsingle(rr,4,(t),(h),(o),(a),(c))
299#define bus_space_read_region_8(t, h, o, a, c) \
300 __bs_nonsingle(rr,8,(t),(h),(o),(a),(c))
301
302/*
303 * Bus write (single) operations.
304 */
305#define bus_space_write_1(t, h, o, v) __bs_ws(1,(t),(h),(o),(v))
306#define bus_space_write_2(t, h, o, v) __bs_ws(2,(t),(h),(o),(v))
307#define bus_space_write_4(t, h, o, v) __bs_ws(4,(t),(h),(o),(v))
308#define bus_space_write_8(t, h, o, v) __bs_ws(8,(t),(h),(o),(v))
309
310/*
311 * Bus write multiple operations.
312 */
313#define bus_space_write_multi_1(t, h, o, a, c) \
314 __bs_nonsingle(wm,1,(t),(h),(o),(a),(c))
315#define bus_space_write_multi_2(t, h, o, a, c) \
316 __bs_nonsingle(wm,2,(t),(h),(o),(a),(c))
317#define bus_space_write_multi_4(t, h, o, a, c) \
318 __bs_nonsingle(wm,4,(t),(h),(o),(a),(c))
319#define bus_space_write_multi_8(t, h, o, a, c) \
320 __bs_nonsingle(wm,8,(t),(h),(o),(a),(c))
321
322/*
323 * Bus write region operations.
324 */
325#define bus_space_write_region_1(t, h, o, a, c) \
326 __bs_nonsingle(wr,1,(t),(h),(o),(a),(c))
327#define bus_space_write_region_2(t, h, o, a, c) \
328 __bs_nonsingle(wr,2,(t),(h),(o),(a),(c))
329#define bus_space_write_region_4(t, h, o, a, c) \
330 __bs_nonsingle(wr,4,(t),(h),(o),(a),(c))
331#define bus_space_write_region_8(t, h, o, a, c) \
332 __bs_nonsingle(wr,8,(t),(h),(o),(a),(c))
333
334/*
335 * Set multiple operations.
336 */
337#define bus_space_set_multi_1(t, h, o, v, c) \
338 __bs_set(sm,1,(t),(h),(o),(v),(c))
339#define bus_space_set_multi_2(t, h, o, v, c) \
340 __bs_set(sm,2,(t),(h),(o),(v),(c))
341#define bus_space_set_multi_4(t, h, o, v, c) \
342 __bs_set(sm,4,(t),(h),(o),(v),(c))
343#define bus_space_set_multi_8(t, h, o, v, c) \
344 __bs_set(sm,8,(t),(h),(o),(v),(c))
345
346/*
347 * Set region operations.
348 */
349#define bus_space_set_region_1(t, h, o, v, c) \
350 __bs_set(sr,1,(t),(h),(o),(v),(c))
351#define bus_space_set_region_2(t, h, o, v, c) \
352 __bs_set(sr,2,(t),(h),(o),(v),(c))
353#define bus_space_set_region_4(t, h, o, v, c) \
354 __bs_set(sr,4,(t),(h),(o),(v),(c))
355#define bus_space_set_region_8(t, h, o, v, c) \
356 __bs_set(sr,8,(t),(h),(o),(v),(c))
357
358/*
359 * Copy operations.
360 */
361#define bus_space_copy_1(t, h1, o1, h2, o2, c) \
362 __bs_copy(1, t, h1, o1, h2, o2, c)
363#define bus_space_copy_2(t, h1, o1, h2, o2, c) \
364 __bs_copy(2, t, h1, o1, h2, o2, c)
365#define bus_space_copy_4(t, h1, o1, h2, o2, c) \
366 __bs_copy(4, t, h1, o1, h2, o2, c)
367#define bus_space_copy_8(t, h1, o1, h2, o2, c) \
368 __bs_copy(8, t, h1, o1, h2, o2, c)
369
370/*
371 * Macros to provide prototypes for all the functions used in the
372 * bus_space structure
373 */
374
375#define bs_map_proto(f) \
376int __bs_c(f,_bs_map) (void *t, uint64_t addr, \
377 bus_size_t size, int flags, bus_space_handle_t *bshp);
378
379#define bs_unmap_proto(f) \
380void __bs_c(f,_bs_unmap) (void *t, bus_space_handle_t bsh, \
381 bus_size_t size);
382
383#define bs_subregion_proto(f) \
384int __bs_c(f,_bs_subregion) (void *t, bus_space_handle_t bsh, \
385 bus_size_t offset, bus_size_t size, \
386 bus_space_handle_t *nbshp);
387
388#define bs_alloc_proto(f) \
389int __bs_c(f,_bs_alloc) (void *t, bus_addr_t rstart, \
390 bus_addr_t rend, bus_size_t size, bus_size_t align, \
391 bus_size_t boundary, int flags, bus_addr_t *addrp, \
392 bus_space_handle_t *bshp);
393
394#define bs_free_proto(f) \
395void __bs_c(f,_bs_free) (void *t, bus_space_handle_t bsh, \
396 bus_size_t size);
397
398#define bs_vaddr_proto(f) \
399void * __bs_c(f,_bs_vaddr) (void *t, bus_space_handle_t bsh);
400
401#define bs_mmap_proto(f) \
402paddr_t __bs_c(f,_bs_mmap) (void *, bus_addr_t, off_t, int, int);
403
404#define bs_barrier_proto(f) \
405void __bs_c(f,_bs_barrier) (void *t, bus_space_handle_t bsh, \
406 bus_size_t offset, bus_size_t len, int flags);
407
408#define bs_r_1_proto(f) \
409u_int8_t __bs_c(f,_bs_r_1) (void *t, bus_space_handle_t bsh, \
410 bus_size_t offset);
411
412#define bs_r_2_proto(f) \
413u_int16_t __bs_c(f,_bs_r_2) (void *t, bus_space_handle_t bsh, \
414 bus_size_t offset);
415
416#define bs_r_4_proto(f) \
417u_int32_t __bs_c(f,_bs_r_4) (void *t, bus_space_handle_t bsh, \
418 bus_size_t offset);
419
420#define bs_r_8_proto(f) \
421u_int64_t __bs_c(f,_bs_r_8) (void *t, bus_space_handle_t bsh, \
422 bus_size_t offset);
423
424#define bs_w_1_proto(f) \
425void __bs_c(f,_bs_w_1) (void *t, bus_space_handle_t bsh, \
426 bus_size_t offset, u_int8_t value);
427
428#define bs_w_2_proto(f) \
429void __bs_c(f,_bs_w_2) (void *t, bus_space_handle_t bsh, \
430 bus_size_t offset, u_int16_t value);
431
432#define bs_w_4_proto(f) \
433void __bs_c(f,_bs_w_4) (void *t, bus_space_handle_t bsh, \
434 bus_size_t offset, u_int32_t value);
435
436#define bs_w_8_proto(f) \
437void __bs_c(f,_bs_w_8) (void *t, bus_space_handle_t bsh, \
438 bus_size_t offset, u_int64_t value);
439
440#define bs_rm_1_proto(f) \
441void __bs_c(f,_bs_rm_1) (void *t, bus_space_handle_t bsh, \
442 bus_size_t offset, u_int8_t *addr, bus_size_t count);
443
444#define bs_rm_2_proto(f) \
445void __bs_c(f,_bs_rm_2) (void *t, bus_space_handle_t bsh, \
446 bus_size_t offset, u_int16_t *addr, bus_size_t count);
447
448#define bs_rm_4_proto(f) \
449void __bs_c(f,_bs_rm_4) (void *t, bus_space_handle_t bsh, \
450 bus_size_t offset, u_int32_t *addr, bus_size_t count);
451
452#define bs_rm_8_proto(f) \
453void __bs_c(f,_bs_rm_8) (void *t, bus_space_handle_t bsh, \
454 bus_size_t offset, u_int64_t *addr, bus_size_t count);
455
456#define bs_wm_1_proto(f) \
457void __bs_c(f,_bs_wm_1) (void *t, bus_space_handle_t bsh, \
458 bus_size_t offset, const u_int8_t *addr, bus_size_t count);
459
460#define bs_wm_2_proto(f) \
461void __bs_c(f,_bs_wm_2) (void *t, bus_space_handle_t bsh, \
462 bus_size_t offset, const u_int16_t *addr, bus_size_t count);
463
464#define bs_wm_4_proto(f) \
465void __bs_c(f,_bs_wm_4) (void *t, bus_space_handle_t bsh, \
466 bus_size_t offset, const u_int32_t *addr, bus_size_t count);
467
468#define bs_wm_8_proto(f) \
469void __bs_c(f,_bs_wm_8) (void *t, bus_space_handle_t bsh, \
470 bus_size_t offset, const u_int64_t *addr, bus_size_t count);
471
472#define bs_rr_1_proto(f) \
473void __bs_c(f, _bs_rr_1) (void *t, bus_space_handle_t bsh, \
474 bus_size_t offset, u_int8_t *addr, bus_size_t count);
475
476#define bs_rr_2_proto(f) \
477void __bs_c(f, _bs_rr_2) (void *t, bus_space_handle_t bsh, \
478 bus_size_t offset, u_int16_t *addr, bus_size_t count);
479
480#define bs_rr_4_proto(f) \
481void __bs_c(f, _bs_rr_4) (void *t, bus_space_handle_t bsh, \
482 bus_size_t offset, u_int32_t *addr, bus_size_t count);
483
484#define bs_rr_8_proto(f) \
485void __bs_c(f, _bs_rr_8) (void *t, bus_space_handle_t bsh, \
486 bus_size_t offset, u_int64_t *addr, bus_size_t count);
487
488#define bs_wr_1_proto(f) \
489void __bs_c(f, _bs_wr_1) (void *t, bus_space_handle_t bsh, \
490 bus_size_t offset, const u_int8_t *addr, bus_size_t count);
491
492#define bs_wr_2_proto(f) \
493void __bs_c(f, _bs_wr_2) (void *t, bus_space_handle_t bsh, \
494 bus_size_t offset, const u_int16_t *addr, bus_size_t count);
495
496#define bs_wr_4_proto(f) \
497void __bs_c(f, _bs_wr_4) (void *t, bus_space_handle_t bsh, \
498 bus_size_t offset, const u_int32_t *addr, bus_size_t count);
499
500#define bs_wr_8_proto(f) \
501void __bs_c(f, _bs_wr_8) (void *t, bus_space_handle_t bsh, \
502 bus_size_t offset, const u_int64_t *addr, bus_size_t count);
503
504#define bs_sm_1_proto(f) \
505void __bs_c(f,_bs_sm_1) (void *t, bus_space_handle_t bsh, \
506 bus_size_t offset, u_int8_t value, bus_size_t count);
507
508#define bs_sm_2_proto(f) \
509void __bs_c(f,_bs_sm_2) (void *t, bus_space_handle_t bsh, \
510 bus_size_t offset, u_int16_t value, bus_size_t count);
511
512#define bs_sm_4_proto(f) \
513void __bs_c(f,_bs_sm_4) (void *t, bus_space_handle_t bsh, \
514 bus_size_t offset, u_int32_t value, bus_size_t count);
515
516#define bs_sm_8_proto(f) \
517void __bs_c(f,_bs_sm_8) (void *t, bus_space_handle_t bsh, \
518 bus_size_t offset, u_int64_t value, bus_size_t count);
519
520#define bs_sr_1_proto(f) \
521void __bs_c(f,_bs_sr_1) (void *t, bus_space_handle_t bsh, \
522 bus_size_t offset, u_int8_t value, bus_size_t count);
523
524#define bs_sr_2_proto(f) \
525void __bs_c(f,_bs_sr_2) (void *t, bus_space_handle_t bsh, \
526 bus_size_t offset, u_int16_t value, bus_size_t count);
527
528#define bs_sr_4_proto(f) \
529void __bs_c(f,_bs_sr_4) (void *t, bus_space_handle_t bsh, \
530 bus_size_t offset, u_int32_t value, bus_size_t count);
531
532#define bs_sr_8_proto(f) \
533void __bs_c(f,_bs_sr_8) (void *t, bus_space_handle_t bsh, \
534 bus_size_t offset, u_int64_t value, bus_size_t count);
535
536#define bs_c_1_proto(f) \
537void __bs_c(f,_bs_c_1) (void *t, bus_space_handle_t bsh1, \
538 bus_size_t offset1, bus_space_handle_t bsh2, \
539 bus_size_t offset2, bus_size_t count);
540
541#define bs_c_2_proto(f) \
542void __bs_c(f,_bs_c_2) (void *t, bus_space_handle_t bsh1, \
543 bus_size_t offset1, bus_space_handle_t bsh2, \
544 bus_size_t offset2, bus_size_t count);
545
546#define bs_c_4_proto(f) \
547void __bs_c(f,_bs_c_4) (void *t, bus_space_handle_t bsh1, \
548 bus_size_t offset1, bus_space_handle_t bsh2, \
549 bus_size_t offset2, bus_size_t count);
550
551#define bs_c_8_proto(f) \
552void __bs_c(f,_bs_c_8) (void *t, bus_space_handle_t bsh1, \
553 bus_size_t offset1, bus_space_handle_t bsh2, \
554 bus_size_t offset2, bus_size_t count);
555
556#define bs_protos(f) \
557bs_map_proto(f); \
558bs_unmap_proto(f); \
559bs_subregion_proto(f); \
560bs_alloc_proto(f); \
561bs_free_proto(f); \
562bs_vaddr_proto(f); \
563bs_mmap_proto(f); \
564bs_barrier_proto(f); \
565bs_r_1_proto(f); \
566bs_r_2_proto(f); \
567bs_r_4_proto(f); \
568bs_r_8_proto(f); \
569bs_w_1_proto(f); \
570bs_w_2_proto(f); \
571bs_w_4_proto(f); \
572bs_w_8_proto(f); \
573bs_rm_1_proto(f); \
574bs_rm_2_proto(f); \
575bs_rm_4_proto(f); \
576bs_rm_8_proto(f); \
577bs_wm_1_proto(f); \
578bs_wm_2_proto(f); \
579bs_wm_4_proto(f); \
580bs_wm_8_proto(f); \
581bs_rr_1_proto(f); \
582bs_rr_2_proto(f); \
583bs_rr_4_proto(f); \
584bs_rr_8_proto(f); \
585bs_wr_1_proto(f); \
586bs_wr_2_proto(f); \
587bs_wr_4_proto(f); \
588bs_wr_8_proto(f); \
589bs_sm_1_proto(f); \
590bs_sm_2_proto(f); \
591bs_sm_4_proto(f); \
592bs_sm_8_proto(f); \
593bs_sr_1_proto(f); \
594bs_sr_2_proto(f); \
595bs_sr_4_proto(f); \
596bs_sr_8_proto(f); \
597bs_c_1_proto(f); \
598bs_c_2_proto(f); \
599bs_c_4_proto(f); \
600bs_c_8_proto(f);
601
602/* Bus Space DMA macros */
603
604/*
605 * Flags used in various bus DMA methods.
606 */
607#define BUS_DMA_WAITOK 0x0000 /* safe to sleep (pseudo-flag) */
608#define BUS_DMA_NOWAIT 0x0001 /* not safe to sleep */
609#define BUS_DMA_ALLOCNOW 0x0002 /* perform resource allocation now */
610#define BUS_DMA_COHERENT 0x0004 /* hint: map memory DMA coherent */
611#define BUS_DMA_STREAMING 0x0008 /* hint: sequential, unidirectional */
612#define BUS_DMA_BUS1 0x0010 /* placeholders for bus functions... */
613#define BUS_DMA_BUS2 0x0020
614#define BUS_DMA_BUS3 0x0040
615#define BUS_DMA_BUS4 0x0080
616#define BUS_DMA_READ 0x0100 /* mapping is device -> memory only */
617#define BUS_DMA_WRITE 0x0200 /* mapping is memory -> device only */
618#define BUS_DMA_NOCACHE 0x0400 /* hint: map non-cached memory */
619#define BUS_DMA_ZERO 0x0800 /* dmamem_alloc returns zeroed mem */
620#define BUS_DMA_64BIT 0x1000 /* device handles 64bit dva */
621
622/*
623 * Private flags stored in the DMA map.
624 */
625#define ARM32_DMAMAP_COHERENT 0x10000 /* no cache flush necessary on sync */
626
627/* Forwards needed by prototypes below. */
628struct mbuf;
629struct uio;
630
631/*
632 * Operations performed by bus_dmamap_sync().
633 */
634#define BUS_DMASYNC_PREREAD 0x01 /* pre-read synchronization */
635#define BUS_DMASYNC_POSTREAD 0x02 /* post-read synchronization */
636#define BUS_DMASYNC_PREWRITE 0x04 /* pre-write synchronization */
637#define BUS_DMASYNC_POSTWRITE 0x08 /* post-write synchronization */
638
639typedef struct arm32_bus_dma_tag *bus_dma_tag_t;
640typedef struct arm32_bus_dmamap *bus_dmamap_t;
641
642#define BUS_DMA_TAG_VALID(t) ((t) != (bus_dma_tag_t)0)
643
644/*
645 * bus_dma_segment_t
646 *
647 * Describes a single contiguous DMA transaction. Values
648 * are suitable for programming into DMA registers.
649 */
650struct arm32_bus_dma_segment {
651 /*
652 * PUBLIC MEMBERS: these are used by machine-independent code.
653 */
654 bus_addr_t ds_addr; /* DMA address */
655 bus_size_t ds_len; /* length of transfer */
656 /*
657 * PRIVATE MEMBERS: not for use by machine-independent code.
658 */
659 bus_addr_t _ds_vaddr; /* Virtual mapped address
660 * Used by bus_dmamem_sync() */
661 int _ds_coherent; /* Coherently mapped */
662};
663typedef struct arm32_bus_dma_segment bus_dma_segment_t;
664
665/*
666 * bus_dma_tag_t
667 *
668 * A machine-dependent opaque type describing the implementation of
669 * DMA for a given bus.
670 */
671
672struct arm32_bus_dma_tag {
673 /*
674 * Opaque cookie for use by back-end.
675 */
676 void *_cookie;
677
678 /*
679 * DMA mapping methods.
680 */
681 int (*_dmamap_create) (bus_dma_tag_t, bus_size_t, int,
682 bus_size_t, bus_size_t, int, bus_dmamap_t *);
683 void (*_dmamap_destroy) (bus_dma_tag_t, bus_dmamap_t);
684 int (*_dmamap_load) (bus_dma_tag_t, bus_dmamap_t, void *,
685 bus_size_t, struct proc *, int);
686 int (*_dmamap_load_mbuf) (bus_dma_tag_t, bus_dmamap_t,
687 struct mbuf *, int);
688 int (*_dmamap_load_uio) (bus_dma_tag_t, bus_dmamap_t,
689 struct uio *, int);
690 int (*_dmamap_load_raw) (bus_dma_tag_t, bus_dmamap_t,
691 bus_dma_segment_t *, int, bus_size_t, int);
692 int (*_dmamap_load_buffer)(bus_dma_tag_t, bus_dmamap_t, void *,
693 bus_size_t, struct proc *, int, paddr_t *, int *, int);
694 void (*_dmamap_unload) (bus_dma_tag_t, bus_dmamap_t);
695 void (*_dmamap_sync) (bus_dma_tag_t, bus_dmamap_t,
696 bus_addr_t, bus_size_t, int);
697
698 /*
699 * DMA memory utility functions.
700 */
701 int (*_dmamem_alloc) (bus_dma_tag_t, bus_size_t, bus_size_t,
702 bus_size_t, bus_dma_segment_t *, int, int *, int);
703 int (*_dmamem_alloc_range) (bus_dma_tag_t, bus_size_t, bus_size_t,
704 bus_size_t, bus_dma_segment_t *, int, int *, int,
705 paddr_t, paddr_t);
706 void (*_dmamem_free) (bus_dma_tag_t,
707 bus_dma_segment_t *, int);
708 int (*_dmamem_map) (bus_dma_tag_t, bus_dma_segment_t *,
709 int, size_t, caddr_t *, int);
710 void (*_dmamem_unmap) (bus_dma_tag_t, caddr_t, size_t);
711 paddr_t (*_dmamem_mmap) (bus_dma_tag_t, bus_dma_segment_t *,
712 int, off_t, int, int);
713};
714
715#define bus_dmamap_create(t, s, n, m, b, f, p) \
716 (*(t)->_dmamap_create)((t), (s), (n), (m), (b), (f), (p))
717#define bus_dmamap_destroy(t, p) \
718 (*(t)->_dmamap_destroy)((t), (p))
719#define bus_dmamap_load(t, m, b, s, p, f) \
720 (*(t)->_dmamap_load)((t), (m), (b), (s), (p), (f))
721#define bus_dmamap_load_mbuf(t, m, b, f) \
722 (*(t)->_dmamap_load_mbuf)((t), (m), (b), (f))
723#define bus_dmamap_load_uio(t, m, u, f) \
724 (*(t)->_dmamap_load_uio)((t), (m), (u), (f))
725#define bus_dmamap_load_raw(t, m, sg, n, s, f) \
726 (*(t)->_dmamap_load_raw)((t), (m), (sg), (n), (s), (f))
727#define bus_dmamap_unload(t, p) \
728 (*(t)->_dmamap_unload)((t), (p))
729#define bus_dmamap_sync(t, p, o, l, ops) \
730 (void)((t)->_dmamap_sync ? \
731 (*(t)->_dmamap_sync)((t), (p), (o), (l), (ops)) : (void)0)
732
733#define bus_dmamem_alloc(t, s, a, b, sg, n, r, f) \
734 (*(t)->_dmamem_alloc)((t), (s), (a), (b), (sg), (n), (r), (f))
735#define bus_dmamem_alloc_range(t, s, a, b, sg, n, r, f, l, h) \
736 (*(t)->_dmamem_alloc_range)((t), (s), (a), (b), (sg), \
737 (n), (r), (f), (l), (h))
738#define bus_dmamem_free(t, sg, n) \
739 (*(t)->_dmamem_free)((t), (sg), (n))
740#define bus_dmamem_map(t, sg, n, s, k, f) \
741 (*(t)->_dmamem_map)((t), (sg), (n), (s), (k), (f))
742#define bus_dmamem_unmap(t, k, s) \
743 (*(t)->_dmamem_unmap)((t), (k), (s))
744#define bus_dmamem_mmap(t, sg, n, o, p, f) \
745 (*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
746
747/*
748 * bus_dmamap_t
749 *
750 * Describes a DMA mapping.
751 */
752struct arm32_bus_dmamap {
753 /*
754 * PRIVATE MEMBERS: not for use by machine-independent code.
755 */
756 bus_size_t _dm_size; /* largest DMA transfer mappable */
757 int _dm_segcnt; /* number of segs this map can map */
758 bus_size_t _dm_maxsegsz; /* largest possible segment */
759 bus_size_t _dm_boundary; /* don't cross this */
760 int _dm_flags; /* misc. flags */
761
762 void *_dm_origbuf; /* pointer to original buffer */
763 int _dm_buftype; /* type of buffer */
764 struct proc *_dm_proc; /* proc that owns the mapping */
765
766 void *_dm_cookie; /* cookie for bus-specific functions */
767
768 /*
769 * PUBLIC MEMBERS: these are used by machine-independent code.
770 */
771 bus_size_t dm_mapsize; /* size of the mapping */
772 int dm_nsegs; /* # valid segments in mapping */
773 bus_dma_segment_t dm_segs[1]; /* segments; variable length */
774};
775
776#ifdef _ARM32_BUS_DMA_PRIVATE
777
778/* _dm_buftype */
779#define ARM32_BUFTYPE_INVALID 0
780#define ARM32_BUFTYPE_LINEAR 1
781#define ARM32_BUFTYPE_MBUF 2
782#define ARM32_BUFTYPE_UIO 3
783#define ARM32_BUFTYPE_RAW 4
784
785int _bus_dmamap_create (bus_dma_tag_t, bus_size_t, int, bus_size_t,
786 bus_size_t, int, bus_dmamap_t *);
787void _bus_dmamap_destroy (bus_dma_tag_t, bus_dmamap_t);
788int _bus_dmamap_load (bus_dma_tag_t, bus_dmamap_t, void *,
789 bus_size_t, struct proc *, int);
790int _bus_dmamap_load_mbuf (bus_dma_tag_t, bus_dmamap_t,
791 struct mbuf *, int);
792int _bus_dmamap_load_uio (bus_dma_tag_t, bus_dmamap_t,
793 struct uio *, int);
794int _bus_dmamap_load_raw (bus_dma_tag_t, bus_dmamap_t,
795 bus_dma_segment_t *, int, bus_size_t, int);
796int _bus_dmamap_load_buffer(bus_dma_tag_t, bus_dmamap_t, void *,
797 bus_size_t, struct proc *, int, paddr_t *, int *, int);
798void _bus_dmamap_unload (bus_dma_tag_t, bus_dmamap_t);
799void _bus_dmamap_sync (bus_dma_tag_t, bus_dmamap_t, bus_addr_t,
800 bus_size_t, int);
801
802int _bus_dmamem_alloc (bus_dma_tag_t tag, bus_size_t size,
803 bus_size_t alignment, bus_size_t boundary,
804 bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags);
805void _bus_dmamem_free (bus_dma_tag_t tag, bus_dma_segment_t *segs,
806 int nsegs);
807int _bus_dmamem_map (bus_dma_tag_t tag, bus_dma_segment_t *segs,
808 int nsegs, size_t size, caddr_t *kvap, int flags);
809void _bus_dmamem_unmap (bus_dma_tag_t tag, caddr_t kva,
810 size_t size);
811paddr_t _bus_dmamem_mmap (bus_dma_tag_t tag, bus_dma_segment_t *segs,
812 int nsegs, off_t off, int prot, int flags);
813
814int _bus_dmamem_alloc_range (bus_dma_tag_t tag, bus_size_t size,
815 bus_size_t alignment, bus_size_t boundary,
816 bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags,
817 vaddr_t low, vaddr_t high);
818#endif /* _ARM32_BUS_DMA_PRIVATE */
819/* These are OpenBSD extensions to the general NetBSD bus interface. */
820void
821bus_space_read_raw_multi_2(bus_space_tag_t bst, bus_space_handle_t bsh,
822 bus_addr_t ba, u_int8_t *dst, bus_size_t size);
823void
824bus_space_read_raw_multi_4(bus_space_tag_t bst, bus_space_handle_t bsh,
825 bus_addr_t ba, u_int8_t *dst, bus_size_t size);
826#define bus_space_read_raw_multi_8 \
827 !!! bus_space_read_raw_multi_8 not implemented !!!
828
829void
830bus_space_write_raw_multi_2(bus_space_tag_t bst, bus_space_handle_t bsh,
831 bus_addr_t ba, const u_int8_t *src, bus_size_t size);
832void
833bus_space_write_raw_multi_4(bus_space_tag_t bst, bus_space_handle_t bsh,
834 bus_addr_t ba, const u_int8_t *src, bus_size_t size);
835#define bus_space_write_raw_multi_8 \
836 !!! bus_space_write_raw_multi_8 not implemented !!!
837
838/*
839 * void bus_space_read_raw_region_N(bus_space_tag_t tag,
840 * bus_space_handle_t bsh, bus_size_t offset,
841 * u_int8_t *addr, size_t count);
842 *
843 * Read `count' bytes in 2, 4 or 8 byte wide quantities from bus space
844 * described by tag/handle and starting at `offset' and copy into
845 * buffer provided. The buffer must have proper alignment for the N byte
846 * wide entities. Furthermore possible byte-swapping should be done by
847 * these functions.
848 */
849
850#define bus_space_read_raw_region_2(t, h, o, a, c) \
851 bus_space_read_region_2((t), (h), (o), (u_int16_t *)(a), (c) >> 1)
852#define bus_space_read_raw_region_4(t, h, o, a, c) \
853 bus_space_read_region_4((t), (h), (o), (u_int32_t *)(a), (c) >> 2)
854
855#if 0 /* Cause a link error for bus_space_read_raw_region_8 */
856#define bus_space_read_raw_region_8 \
857 !!! bus_space_read_raw_region_8 unimplemented !!!
858#endif
859
860/*
861 * void bus_space_write_raw_region_N(bus_space_tag_t tag,
862 * bus_space_handle_t bsh, bus_size_t offset,
863 * const u_int8_t *addr, size_t count);
864 *
865 * Write `count' bytes in 2, 4 or 8 byte wide quantities to bus space
866 * described by tag/handle and starting at `offset' from the
867 * buffer provided. The buffer must have proper alignment for the N byte
868 * wide entities. Furthermore possible byte-swapping should be done by
869 * these functions.
870 */
871
872#define bus_space_write_raw_region_2(t, h, o, a, c) \
873 bus_space_write_region_2((t), (h), (o), (const u_int16_t *)(a), (c) >> 1)
874#define bus_space_write_raw_region_4(t, h, o, a, c) \
875 bus_space_write_region_4((t), (h), (o), (const u_int32_t *)(a), (c) >> 2)
876
877#if 0 /* Cause a link error for bus_space_write_raw_region_8 */
878#define bus_space_write_raw_region_8 \
879 !!! bus_space_write_raw_region_8 unimplemented !!!
880#endif
881
882#endif /* _ARM_BUS_H_ */