xref: /openbsd/sys/arch/arm/include/bus.h (revision 37084e1e)
1 /*	$OpenBSD: bus.h,v 1.18 2020/04/29 15:25:07 kettenis 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  */
71 typedef u_long bus_addr_t;
72 typedef u_long bus_size_t;
73 
74 /*
75  * Access methods for bus space.
76  */
77 typedef struct bus_space *bus_space_tag_t;
78 typedef 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 
91 struct 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)							\
376 int	__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)						\
380 void	__bs_c(f,_bs_unmap) (void *t, bus_space_handle_t bsh,	\
381 	    bus_size_t size);
382 
383 #define bs_subregion_proto(f)						\
384 int	__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)						\
389 int	__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)						\
395 void	__bs_c(f,_bs_free) (void *t, bus_space_handle_t bsh,	\
396 	    bus_size_t size);
397 
398 #define bs_vaddr_proto(f)						\
399 void *	__bs_c(f,_bs_vaddr) (void *t, bus_space_handle_t bsh);
400 
401 #define bs_mmap_proto(f)						\
402 paddr_t	__bs_c(f,_bs_mmap) (void *, bus_addr_t, off_t, int, int);
403 
404 #define bs_barrier_proto(f)						\
405 void	__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)							\
409 u_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)							\
413 u_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)							\
417 u_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)							\
421 u_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)							\
425 void	__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)							\
429 void	__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)							\
433 void	__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)							\
437 void	__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)						\
441 void	__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)						\
445 void	__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)						\
449 void	__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)						\
453 void	__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)						\
457 void	__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)						\
461 void	__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)						\
465 void	__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)						\
469 void	__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)						\
473 void	__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)						\
477 void	__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)						\
481 void	__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)						\
485 void	__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)						\
489 void	__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)						\
493 void	__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)						\
497 void	__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)						\
501 void	__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)						\
505 void	__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)						\
509 void	__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)						\
513 void	__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)						\
517 void	__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)						\
521 void	__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)						\
525 void	__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)						\
529 void	__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)						\
533 void	__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)							\
537 void	__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)							\
542 void	__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)							\
547 void	__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)							\
552 void	__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)		\
557 bs_map_proto(f);		\
558 bs_unmap_proto(f);		\
559 bs_subregion_proto(f);		\
560 bs_alloc_proto(f);		\
561 bs_free_proto(f);		\
562 bs_vaddr_proto(f);		\
563 bs_mmap_proto(f);		\
564 bs_barrier_proto(f);		\
565 bs_r_1_proto(f);		\
566 bs_r_2_proto(f);		\
567 bs_r_4_proto(f);		\
568 bs_r_8_proto(f);		\
569 bs_w_1_proto(f);		\
570 bs_w_2_proto(f);		\
571 bs_w_4_proto(f);		\
572 bs_w_8_proto(f);		\
573 bs_rm_1_proto(f);		\
574 bs_rm_2_proto(f);		\
575 bs_rm_4_proto(f);		\
576 bs_rm_8_proto(f);		\
577 bs_wm_1_proto(f);		\
578 bs_wm_2_proto(f);		\
579 bs_wm_4_proto(f);		\
580 bs_wm_8_proto(f);		\
581 bs_rr_1_proto(f);		\
582 bs_rr_2_proto(f);		\
583 bs_rr_4_proto(f);		\
584 bs_rr_8_proto(f);		\
585 bs_wr_1_proto(f);		\
586 bs_wr_2_proto(f);		\
587 bs_wr_4_proto(f);		\
588 bs_wr_8_proto(f);		\
589 bs_sm_1_proto(f);		\
590 bs_sm_2_proto(f);		\
591 bs_sm_4_proto(f);		\
592 bs_sm_8_proto(f);		\
593 bs_sr_1_proto(f);		\
594 bs_sr_2_proto(f);		\
595 bs_sr_4_proto(f);		\
596 bs_sr_8_proto(f);		\
597 bs_c_1_proto(f);		\
598 bs_c_2_proto(f);		\
599 bs_c_4_proto(f);		\
600 bs_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. */
628 struct mbuf;
629 struct 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 
639 typedef struct arm32_bus_dma_tag	*bus_dma_tag_t;
640 typedef 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  */
650 struct 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 };
663 typedef 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 
672 struct 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 	void	(*_dmamem_free) (bus_dma_tag_t,
704 		    bus_dma_segment_t *, int);
705 	int	(*_dmamem_map) (bus_dma_tag_t, bus_dma_segment_t *,
706 		    int, size_t, caddr_t *, int);
707 	void	(*_dmamem_unmap) (bus_dma_tag_t, caddr_t, size_t);
708 	paddr_t	(*_dmamem_mmap) (bus_dma_tag_t, bus_dma_segment_t *,
709 		    int, off_t, int, int);
710 };
711 
712 #define	bus_dmamap_create(t, s, n, m, b, f, p)			\
713 	(*(t)->_dmamap_create)((t), (s), (n), (m), (b), (f), (p))
714 #define	bus_dmamap_destroy(t, p)				\
715 	(*(t)->_dmamap_destroy)((t), (p))
716 #define	bus_dmamap_load(t, m, b, s, p, f)			\
717 	(*(t)->_dmamap_load)((t), (m), (b), (s), (p), (f))
718 #define	bus_dmamap_load_mbuf(t, m, b, f)			\
719 	(*(t)->_dmamap_load_mbuf)((t), (m), (b), (f))
720 #define	bus_dmamap_load_uio(t, m, u, f)				\
721 	(*(t)->_dmamap_load_uio)((t), (m), (u), (f))
722 #define	bus_dmamap_load_raw(t, m, sg, n, s, f)			\
723 	(*(t)->_dmamap_load_raw)((t), (m), (sg), (n), (s), (f))
724 #define	bus_dmamap_unload(t, p)					\
725 	(*(t)->_dmamap_unload)((t), (p))
726 #define	bus_dmamap_sync(t, p, o, l, ops)			\
727 	(void)((t)->_dmamap_sync ?				\
728 	    (*(t)->_dmamap_sync)((t), (p), (o), (l), (ops)) : (void)0)
729 
730 #define	bus_dmamem_alloc(t, s, a, b, sg, n, r, f)		\
731 	(*(t)->_dmamem_alloc)((t), (s), (a), (b), (sg), (n), (r), (f))
732 #define	bus_dmamem_free(t, sg, n)				\
733 	(*(t)->_dmamem_free)((t), (sg), (n))
734 #define	bus_dmamem_map(t, sg, n, s, k, f)			\
735 	(*(t)->_dmamem_map)((t), (sg), (n), (s), (k), (f))
736 #define	bus_dmamem_unmap(t, k, s)				\
737 	(*(t)->_dmamem_unmap)((t), (k), (s))
738 #define	bus_dmamem_mmap(t, sg, n, o, p, f)			\
739 	(*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
740 
741 /*
742  *	bus_dmamap_t
743  *
744  *	Describes a DMA mapping.
745  */
746 struct arm32_bus_dmamap {
747 	/*
748 	 * PRIVATE MEMBERS: not for use by machine-independent code.
749 	 */
750 	bus_size_t	_dm_size;	/* largest DMA transfer mappable */
751 	int		_dm_segcnt;	/* number of segs this map can map */
752 	bus_size_t	_dm_maxsegsz;	/* largest possible segment */
753 	bus_size_t	_dm_boundary;	/* don't cross this */
754 	int		_dm_flags;	/* misc. flags */
755 
756 	void		*_dm_origbuf;	/* pointer to original buffer */
757 	int		_dm_buftype;	/* type of buffer */
758 	struct proc	*_dm_proc;	/* proc that owns the mapping */
759 
760 	void		*_dm_cookie;	/* cookie for bus-specific functions */
761 
762 	/*
763 	 * PUBLIC MEMBERS: these are used by machine-independent code.
764 	 */
765 	bus_size_t	dm_mapsize;	/* size of the mapping */
766 	int		dm_nsegs;	/* # valid segments in mapping */
767 	bus_dma_segment_t dm_segs[1];	/* segments; variable length */
768 };
769 
770 #ifdef _ARM32_BUS_DMA_PRIVATE
771 
772 /* _dm_buftype */
773 #define	ARM32_BUFTYPE_INVALID		0
774 #define	ARM32_BUFTYPE_LINEAR		1
775 #define	ARM32_BUFTYPE_MBUF		2
776 #define	ARM32_BUFTYPE_UIO		3
777 #define	ARM32_BUFTYPE_RAW		4
778 
779 int	_bus_dmamap_create (bus_dma_tag_t, bus_size_t, int, bus_size_t,
780 	    bus_size_t, int, bus_dmamap_t *);
781 void	_bus_dmamap_destroy (bus_dma_tag_t, bus_dmamap_t);
782 int	_bus_dmamap_load (bus_dma_tag_t, bus_dmamap_t, void *,
783 	    bus_size_t, struct proc *, int);
784 int	_bus_dmamap_load_mbuf (bus_dma_tag_t, bus_dmamap_t,
785 	    struct mbuf *, int);
786 int	_bus_dmamap_load_uio (bus_dma_tag_t, bus_dmamap_t,
787 	    struct uio *, int);
788 int	_bus_dmamap_load_raw (bus_dma_tag_t, bus_dmamap_t,
789 	    bus_dma_segment_t *, int, bus_size_t, int);
790 int	_bus_dmamap_load_buffer(bus_dma_tag_t, bus_dmamap_t, void *,
791 	    bus_size_t, struct proc *, int, paddr_t *, int *, int);
792 void	_bus_dmamap_unload (bus_dma_tag_t, bus_dmamap_t);
793 void	_bus_dmamap_sync (bus_dma_tag_t, bus_dmamap_t, bus_addr_t,
794 	    bus_size_t, int);
795 
796 int	_bus_dmamem_alloc (bus_dma_tag_t tag, bus_size_t size,
797 	    bus_size_t alignment, bus_size_t boundary,
798 	    bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags);
799 void	_bus_dmamem_free (bus_dma_tag_t tag, bus_dma_segment_t *segs,
800 	    int nsegs);
801 int	_bus_dmamem_map (bus_dma_tag_t tag, bus_dma_segment_t *segs,
802 	    int nsegs, size_t size, caddr_t *kvap, int flags);
803 void	_bus_dmamem_unmap (bus_dma_tag_t tag, caddr_t kva,
804 	    size_t size);
805 paddr_t	_bus_dmamem_mmap (bus_dma_tag_t tag, bus_dma_segment_t *segs,
806 	    int nsegs, off_t off, int prot, int flags);
807 
808 int	_bus_dmamem_alloc_range (bus_dma_tag_t tag, bus_size_t size,
809 	    bus_size_t alignment, bus_size_t boundary,
810 	    bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags,
811 	    vaddr_t low, vaddr_t high);
812 #endif /* _ARM32_BUS_DMA_PRIVATE */
813 /* These are OpenBSD extensions to the general NetBSD bus interface.  */
814 void
815 bus_space_read_raw_multi_2(bus_space_tag_t bst, bus_space_handle_t bsh,
816 	bus_addr_t ba, u_int8_t *dst, bus_size_t size);
817 void
818 bus_space_read_raw_multi_4(bus_space_tag_t bst, bus_space_handle_t bsh,
819 	bus_addr_t ba, u_int8_t *dst, bus_size_t size);
820 #define	bus_space_read_raw_multi_8 \
821     !!! bus_space_read_raw_multi_8 not implemented !!!
822 
823 void
824 bus_space_write_raw_multi_2(bus_space_tag_t bst, bus_space_handle_t bsh,
825 	bus_addr_t ba, const u_int8_t *src, bus_size_t size);
826 void
827 bus_space_write_raw_multi_4(bus_space_tag_t bst, bus_space_handle_t bsh,
828 	bus_addr_t ba, const u_int8_t *src, bus_size_t size);
829 #define	bus_space_write_raw_multi_8 \
830     !!! bus_space_write_raw_multi_8 not implemented !!!
831 
832 /*
833  *	void bus_space_read_raw_region_N(bus_space_tag_t tag,
834  *	    bus_space_handle_t bsh, bus_size_t offset,
835  *	    u_int8_t *addr, size_t count);
836  *
837  * Read `count' bytes in 2, 4 or 8 byte wide quantities from bus space
838  * described by tag/handle and starting at `offset' and copy into
839  * buffer provided.  The buffer must have proper alignment for the N byte
840  * wide entities.  Furthermore possible byte-swapping should be done by
841  * these functions.
842  */
843 
844 #define	bus_space_read_raw_region_2(t, h, o, a, c) \
845     bus_space_read_region_2((t), (h), (o), (u_int16_t *)(a), (c) >> 1)
846 #define	bus_space_read_raw_region_4(t, h, o, a, c) \
847     bus_space_read_region_4((t), (h), (o), (u_int32_t *)(a), (c) >> 2)
848 
849 #if 0	/* Cause a link error for bus_space_read_raw_region_8 */
850 #define	bus_space_read_raw_region_8 \
851     !!! bus_space_read_raw_region_8 unimplemented !!!
852 #endif
853 
854 /*
855  *	void bus_space_write_raw_region_N(bus_space_tag_t tag,
856  *	    bus_space_handle_t bsh, bus_size_t offset,
857  *	    const u_int8_t *addr, size_t count);
858  *
859  * Write `count' bytes in 2, 4 or 8 byte wide quantities to bus space
860  * described by tag/handle and starting at `offset' from the
861  * buffer provided.  The buffer must have proper alignment for the N byte
862  * wide entities.  Furthermore possible byte-swapping should be done by
863  * these functions.
864  */
865 
866 #define	bus_space_write_raw_region_2(t, h, o, a, c) \
867     bus_space_write_region_2((t), (h), (o), (const u_int16_t *)(a), (c) >> 1)
868 #define	bus_space_write_raw_region_4(t, h, o, a, c) \
869     bus_space_write_region_4((t), (h), (o), (const u_int32_t *)(a), (c) >> 2)
870 
871 #if 0	/* Cause a link error for bus_space_write_raw_region_8 */
872 #define	bus_space_write_raw_region_8 \
873     !!! bus_space_write_raw_region_8 unimplemented !!!
874 #endif
875 
876 #endif /* _ARM_BUS_H_ */
877