xref: /openbsd/sys/arch/alpha/include/bus.h (revision 6f40fd34)
1 /*	$OpenBSD: bus.h,v 1.31 2017/05/08 00:27:45 dlg Exp $	*/
2 /*	$NetBSD: bus.h,v 1.10 1996/12/02 22:19:32 cgd Exp $	*/
3 
4 /*
5  * Copyright (c) 1996 Carnegie-Mellon University.
6  * All rights reserved.
7  *
8  * Author: Chris G. Demetriou
9  *
10  * Permission to use, copy, modify and distribute this software and
11  * its documentation is hereby granted, provided that both the copyright
12  * notice and this permission notice appear in all copies of the
13  * software, derivative works or modified versions, and any portions
14  * thereof, and that both notices appear in supporting documentation.
15  *
16  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
17  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
18  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
19  *
20  * Carnegie Mellon requests users of this software to return to
21  *
22  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
23  *  School of Computer Science
24  *  Carnegie Mellon University
25  *  Pittsburgh PA 15213-3890
26  *
27  * any improvements or extensions that they make and grant Carnegie the
28  * rights to redistribute these changes.
29  */
30 
31 #ifndef _MACHINE_BUS_H_
32 #define	_MACHINE_BUS_H_
33 
34 /*
35  * Addresses (in bus space).
36  */
37 typedef u_long bus_addr_t;
38 typedef u_long bus_size_t;
39 
40 /*
41  * Access methods for bus space.
42  */
43 typedef struct alpha_bus_space *bus_space_tag_t;
44 typedef u_long bus_space_handle_t;
45 
46 struct alpha_bus_space {
47 	/* cookie */
48 	void		*abs_cookie;
49 
50 	/* mapping/unmapping */
51 	int		(*abs_map)(void *, bus_addr_t, bus_size_t,
52 			    int, bus_space_handle_t *);
53 	void		(*abs_unmap)(void *, bus_space_handle_t,
54 			    bus_size_t);
55 	int		(*abs_subregion)(void *, bus_space_handle_t,
56 			    bus_size_t, bus_size_t, bus_space_handle_t *);
57 
58 	/* allocation/deallocation */
59 	int		(*abs_alloc)(void *, bus_addr_t, bus_addr_t,
60 			    bus_size_t, bus_size_t, bus_size_t, int,
61 			    bus_addr_t *, bus_space_handle_t *);
62 	void		(*abs_free)(void *, bus_space_handle_t,
63 			    bus_size_t);
64 
65 	/* get kernel virtual address */
66 	void *		(*abs_vaddr)(void *, bus_space_handle_t);
67 
68 	/* barrier */
69 	void		(*abs_barrier)(void *, bus_space_handle_t,
70 			    bus_size_t, bus_size_t, int);
71 
72 	/* read (single) */
73 	u_int8_t	(*abs_r_1)(void *, bus_space_handle_t,
74 			    bus_size_t);
75 	u_int16_t	(*abs_r_2)(void *, bus_space_handle_t,
76 			    bus_size_t);
77 	u_int32_t	(*abs_r_4)(void *, bus_space_handle_t,
78 			    bus_size_t);
79 	u_int64_t	(*abs_r_8)(void *, bus_space_handle_t,
80 			    bus_size_t);
81 
82 	/* read multiple */
83 	void		(*abs_rm_1)(void *, bus_space_handle_t,
84 			    bus_size_t, u_int8_t *, bus_size_t);
85 	void		(*abs_rm_2)(void *, bus_space_handle_t,
86 			    bus_size_t, u_int16_t *, bus_size_t);
87 	void		(*abs_rm_4)(void *, bus_space_handle_t,
88 			    bus_size_t, u_int32_t *, bus_size_t);
89 	void		(*abs_rm_8)(void *, bus_space_handle_t,
90 			    bus_size_t, u_int64_t *, bus_size_t);
91 
92 	/* read region */
93 	void		(*abs_rr_1)(void *, bus_space_handle_t,
94 			    bus_size_t, u_int8_t *, bus_size_t);
95 	void		(*abs_rr_2)(void *, bus_space_handle_t,
96 			    bus_size_t, u_int16_t *, bus_size_t);
97 	void		(*abs_rr_4)(void *, bus_space_handle_t,
98 			    bus_size_t, u_int32_t *, bus_size_t);
99 	void		(*abs_rr_8)(void *, bus_space_handle_t,
100 			    bus_size_t, u_int64_t *, bus_size_t);
101 
102 	/* write (single) */
103 	void		(*abs_w_1)(void *, bus_space_handle_t,
104 			    bus_size_t, u_int8_t);
105 	void		(*abs_w_2)(void *, bus_space_handle_t,
106 			    bus_size_t, u_int16_t);
107 	void		(*abs_w_4)(void *, bus_space_handle_t,
108 			    bus_size_t, u_int32_t);
109 	void		(*abs_w_8)(void *, bus_space_handle_t,
110 			    bus_size_t, u_int64_t);
111 
112 	/* write multiple */
113 	void		(*abs_wm_1)(void *, bus_space_handle_t,
114 			    bus_size_t, const u_int8_t *, bus_size_t);
115 	void		(*abs_wm_2)(void *, bus_space_handle_t,
116 			    bus_size_t, const u_int16_t *, bus_size_t);
117 	void		(*abs_wm_4)(void *, bus_space_handle_t,
118 			    bus_size_t, const u_int32_t *, bus_size_t);
119 	void		(*abs_wm_8)(void *, bus_space_handle_t,
120 			    bus_size_t, const u_int64_t *, bus_size_t);
121 
122 	/* write region */
123 	void		(*abs_wr_1)(void *, bus_space_handle_t,
124 			    bus_size_t, const u_int8_t *, bus_size_t);
125 	void		(*abs_wr_2)(void *, bus_space_handle_t,
126 			    bus_size_t, const u_int16_t *, bus_size_t);
127 	void		(*abs_wr_4)(void *, bus_space_handle_t,
128 			    bus_size_t, const u_int32_t *, bus_size_t);
129 	void		(*abs_wr_8)(void *, bus_space_handle_t,
130 			    bus_size_t, const u_int64_t *, bus_size_t);
131 
132 	/* set multiple */
133 	void		(*abs_sm_1)(void *, bus_space_handle_t,
134 			    bus_size_t, u_int8_t, bus_size_t);
135 	void		(*abs_sm_2)(void *, bus_space_handle_t,
136 			    bus_size_t, u_int16_t, bus_size_t);
137 	void		(*abs_sm_4)(void *, bus_space_handle_t,
138 			    bus_size_t, u_int32_t, bus_size_t);
139 	void		(*abs_sm_8)(void *, bus_space_handle_t,
140 			    bus_size_t, u_int64_t, bus_size_t);
141 
142 	/* set region */
143 	void		(*abs_sr_1)(void *, bus_space_handle_t,
144 			    bus_size_t, u_int8_t, bus_size_t);
145 	void		(*abs_sr_2)(void *, bus_space_handle_t,
146 			    bus_size_t, u_int16_t, bus_size_t);
147 	void		(*abs_sr_4)(void *, bus_space_handle_t,
148 			    bus_size_t, u_int32_t, bus_size_t);
149 	void		(*abs_sr_8)(void *, bus_space_handle_t,
150 			    bus_size_t, u_int64_t, bus_size_t);
151 
152 	/* copy */
153 	void		(*abs_c_1)(void *, bus_space_handle_t, bus_size_t,
154 			    bus_space_handle_t, bus_size_t, bus_size_t);
155 	void		(*abs_c_2)(void *, bus_space_handle_t, bus_size_t,
156 			    bus_space_handle_t, bus_size_t, bus_size_t);
157 	void		(*abs_c_4)(void *, bus_space_handle_t, bus_size_t,
158 			    bus_space_handle_t, bus_size_t, bus_size_t);
159 	void		(*abs_c_8)(void *, bus_space_handle_t, bus_size_t,
160 			    bus_space_handle_t, bus_size_t, bus_size_t);
161 
162 	/* OpenBSD extensions follows */
163 
164 	/* read multiple raw */
165 	void		(*abs_rrm_2)(void *, bus_space_handle_t,
166 			    bus_size_t, u_int8_t *, bus_size_t);
167 	void		(*abs_rrm_4)(void *, bus_space_handle_t,
168 			    bus_size_t, u_int8_t *, bus_size_t);
169 	void		(*abs_rrm_8)(void *, bus_space_handle_t,
170 			    bus_size_t, u_int8_t *, bus_size_t);
171 
172 	/* write multiple raw */
173 	void		(*abs_wrm_2)(void *, bus_space_handle_t,
174 			    bus_size_t, const u_int8_t *, bus_size_t);
175 	void		(*abs_wrm_4)(void *, bus_space_handle_t,
176 			    bus_size_t, const u_int8_t *, bus_size_t);
177 	void		(*abs_wrm_8)(void *, bus_space_handle_t,
178 			    bus_size_t, const u_int8_t *, bus_size_t);
179 };
180 
181 
182 /*
183  * Utility macros; INTERNAL USE ONLY.
184  */
185 #define	__abs_c(a,b)		__CONCAT(a,b)
186 #define	__abs_opname(op,size)	__abs_c(__abs_c(__abs_c(abs_,op),_),size)
187 
188 #define	__abs_rs(sz, t, h, o)						\
189 	(*(t)->__abs_opname(r,sz))((t)->abs_cookie, h, o)
190 #define	__abs_ws(sz, t, h, o, v)					\
191 	(*(t)->__abs_opname(w,sz))((t)->abs_cookie, h, o, v)
192 #define	__abs_nonsingle(type, sz, t, h, o, a, c)			\
193 	(*(t)->__abs_opname(type,sz))((t)->abs_cookie, h, o, a, c)
194 #ifndef DEBUG
195 #define	__abs_aligned_nonsingle(type, sz, t, h, o, a, c)		\
196 	__abs_nonsingle(type, sz, (t), (h), (o), (a), (c))
197 
198 #else
199 #define	__abs_aligned_nonsingle(type, sz, t, h, o, a, c)		\
200     do {								\
201 	if (((unsigned long)a & (sz - 1)) != 0)				\
202 		panic("bus non-single %d-byte unaligned (to %p) at %s:%d", \
203 		    sz, a, __FILE__, __LINE__);				\
204 	(*(t)->__abs_opname(type,sz))((t)->abs_cookie, h, o, a, c);	\
205     } while (0)
206 #endif
207 #define	__abs_set(type, sz, t, h, o, v, c)				\
208 	(*(t)->__abs_opname(type,sz))((t)->abs_cookie, h, o, v, c)
209 #define	__abs_copy(sz, t, h1, o1, h2, o2, cnt)			\
210 	(*(t)->__abs_opname(c,sz))((t)->abs_cookie, h1, o1, h2, o2, cnt)
211 
212 /*
213  * Mapping and unmapping operations.
214  */
215 #define	bus_space_map(t, a, s, c, hp)					\
216 	(*(t)->abs_map)((t)->abs_cookie, (a), (s), (c), (hp))
217 #define alpha_bus_space_map_noacct bus_space_map
218 #define	bus_space_unmap(t, h, s)					\
219 	(*(t)->abs_unmap)((t)->abs_cookie, (h), (s))
220 #define alpha_bus_space_unmap_noacct bus_space_unmap
221 #define	bus_space_subregion(t, h, o, s, hp)				\
222 	(*(t)->abs_subregion)((t)->abs_cookie, (h), (o), (s), (hp))
223 
224 #define	BUS_SPACE_MAP_CACHEABLE		0x01
225 #define	BUS_SPACE_MAP_LINEAR		0x02
226 #define	BUS_SPACE_MAP_PREFETCHABLE	0x04
227 
228 /*
229  * Allocation and deallocation operations.
230  */
231 #define	bus_space_alloc(t, rs, re, s, a, b, c, ap, hp)			\
232 	(*(t)->abs_alloc)((t)->abs_cookie, (rs), (re), (s), (a), (b),	\
233 	    (c), (ap), (hp))
234 #define	bus_space_free(t, h, s)						\
235 	(*(t)->abs_free)((t)->abs_cookie, (h), (s))
236 
237 /*
238  * Get kernel virtual address for ranges mapped BUS_SPACE_MAP_LINEAR.
239  */
240 #define bus_space_vaddr(t, h)						\
241 	(*(t)->abs_vaddr)((t)->abs_cookie, (h))
242 
243 /*
244  * Bus barrier operations.
245  */
246 #define	bus_space_barrier(t, h, o, l, f)				\
247 	(*(t)->abs_barrier)((t)->abs_cookie, (h), (o), (l), (f))
248 
249 #define BUS_SPACE_BARRIER_READ	0x01
250 #define BUS_SPACE_BARRIER_WRITE	0x02
251 
252 
253 /*
254  * Bus read (single) operations.
255  */
256 #define	bus_space_read_1(t, h, o)	__abs_rs(1,(t),(h),(o))
257 #define	bus_space_read_2(t, h, o)	__abs_rs(2,(t),(h),(o))
258 #define	bus_space_read_4(t, h, o)	__abs_rs(4,(t),(h),(o))
259 #define	bus_space_read_8(t, h, o)	__abs_rs(8,(t),(h),(o))
260 
261 
262 /*
263  * Bus read (single) operations.
264  */
265 #define	bus_space_read_raw_1(t, h, o)	__abs_rs(1,(t),(h),(o))
266 #define	bus_space_read_raw_2(t, h, o)	__abs_rs(2,(t),(h),(o))
267 #define	bus_space_read_raw_4(t, h, o)	__abs_rs(4,(t),(h),(o))
268 #define	bus_space_read_raw_8(t, h, o)	__abs_rs(8,(t),(h),(o))
269 
270 
271 /*
272  * Bus read multiple operations.
273  */
274 #define	bus_space_read_multi_1(t, h, o, a, c)				\
275 	__abs_nonsingle(rm,1,(t),(h),(o),(a),(c))
276 #define	bus_space_read_multi_2(t, h, o, a, c)				\
277 	__abs_aligned_nonsingle(rm,2,(t),(h),(o),(a),(c))
278 #define	bus_space_read_multi_4(t, h, o, a, c)				\
279 	__abs_aligned_nonsingle(rm,4,(t),(h),(o),(a),(c))
280 #define	bus_space_read_multi_8(t, h, o, a, c)				\
281 	__abs_aligned_nonsingle(rm,8,(t),(h),(o),(a),(c))
282 
283 
284 /*
285  *	void bus_space_read_raw_multi_N(bus_space_tag_t tag,
286  *	    bus_space_handle_t bsh, bus_size_t offset,
287  *	    u_int8_t *addr, size_t count);
288  *
289  * Read `count' bytes in 2, 4 or 8 byte wide quantities from bus space
290  * described by tag/handle/offset and copy into buffer provided.  The buffer
291  * must have proper alignment for the N byte wide entities.  Furthermore
292  * possible byte-swapping should be done by these functions.
293  */
294 
295 #define	bus_space_read_raw_multi_2(t, h, o, a, c)			\
296 	__abs_nonsingle(rrm,2,(t),(h),(o),(a),(c))
297 #define	bus_space_read_raw_multi_4(t, h, o, a, c)			\
298 	__abs_nonsingle(rrm,4,(t),(h),(o),(a),(c))
299 #define	bus_space_read_raw_multi_8(t, h, o, a, c)			\
300 	__abs_nonsingle(rrm,8,(t),(h),(o),(a),(c))
301 
302 /*
303  * Bus read region operations.
304  */
305 #define	bus_space_read_region_1(t, h, o, a, c)				\
306 	__abs_nonsingle(rr,1,(t),(h),(o),(a),(c))
307 #define	bus_space_read_region_2(t, h, o, a, c)				\
308 	__abs_aligned_nonsingle(rr,2,(t),(h),(o),(a),(c))
309 #define	bus_space_read_region_4(t, h, o, a, c)				\
310 	__abs_aligned_nonsingle(rr,4,(t),(h),(o),(a),(c))
311 #define	bus_space_read_region_8(t, h, o, a, c)				\
312 	__abs_aligned_nonsingle(rr,8,(t),(h),(o),(a),(c))
313 
314 
315 /*
316  *	void bus_space_read_raw_region_N(bus_space_tag_t tag,
317  *	    bus_space_handle_t bsh, bus_size_t offset,
318  *	    u_int8_t *addr, size_t count);
319  *
320  * Read `count' bytes in 2, 4 or 8 byte wide quantities from bus space
321  * described by tag/handle and starting at `offset' from the
322  * buffer provided.  The buffer must have proper alignment for the N byte
323  * wide entities.  Furthermore possible byte-swapping should be done by
324  * these functions.
325  */
326 
327 #define bus_space_read_raw_region_2(t, h, o, a, c)			\
328     bus_space_read_region_2((t), (h), (o), (u_int16_t *)(a), (c) >> 1)
329 #define bus_space_read_raw_region_4(t, h, o, a, c)			\
330     bus_space_read_region_4((t), (h), (o), (u_int32_t *)(a), (c) >> 2)
331 
332 /*
333  * Bus write (single) operations.
334  */
335 #define	bus_space_write_1(t, h, o, v)	__abs_ws(1,(t),(h),(o),(v))
336 #define	bus_space_write_2(t, h, o, v)	__abs_ws(2,(t),(h),(o),(v))
337 #define	bus_space_write_4(t, h, o, v)	__abs_ws(4,(t),(h),(o),(v))
338 #define	bus_space_write_8(t, h, o, v)	__abs_ws(8,(t),(h),(o),(v))
339 
340 
341 /*
342  * Bus write raw (single) operations.
343  */
344 #define	bus_space_write_raw_1(t, h, o, v)	__abs_ws(1,(t),(h),(o),(v))
345 #define	bus_space_write_raw_2(t, h, o, v)	__abs_ws(2,(t),(h),(o),(v))
346 #define	bus_space_write_raw_4(t, h, o, v)	__abs_ws(4,(t),(h),(o),(v))
347 #define	bus_space_write_raw_8(t, h, o, v)	__abs_ws(8,(t),(h),(o),(v))
348 
349 
350 /*
351  * Bus write multiple operations.
352  */
353 #define	bus_space_write_multi_1(t, h, o, a, c)				\
354 	__abs_nonsingle(wm,1,(t),(h),(o),(a),(c))
355 #define	bus_space_write_multi_2(t, h, o, a, c)				\
356 	__abs_aligned_nonsingle(wm,2,(t),(h),(o),(a),(c))
357 #define	bus_space_write_multi_4(t, h, o, a, c)				\
358 	__abs_aligned_nonsingle(wm,4,(t),(h),(o),(a),(c))
359 #define	bus_space_write_multi_8(t, h, o, a, c)				\
360 	__abs_aligned_nonsingle(wm,8,(t),(h),(o),(a),(c))
361 
362 /*
363  *	void bus_space_write_raw_multi_N(bus_space_tag_t tag,
364  *	    bus_space_handle_t bsh, bus_size_t offset,
365  *	    u_int8_t *addr, size_t count);
366  *
367  * Write `count' bytes in 2, 4 or 8 byte wide quantities from the buffer
368  * provided to bus space described by tag/handle/offset.  The buffer
369  * must have proper alignment for the N byte wide entities.  Furthermore
370  * possible byte-swapping should be done by these functions.
371  */
372 
373 #define	bus_space_write_raw_multi_2(t, h, o, a, c)			\
374 	__abs_nonsingle(wrm,2,(t),(h),(o),(a),(c))
375 #define	bus_space_write_raw_multi_4(t, h, o, a, c)			\
376 	__abs_nonsingle(wrm,4,(t),(h),(o),(a),(c))
377 #define	bus_space_write_raw_multi_8(t, h, o, a, c)			\
378 	__abs_nonsingle(wrm,8,(t),(h),(o),(a),(c))
379 
380 /*
381  * Bus write region operations.
382  */
383 #define	bus_space_write_region_1(t, h, o, a, c)				\
384 	__abs_nonsingle(wr,1,(t),(h),(o),(a),(c))
385 #define	bus_space_write_region_2(t, h, o, a, c)				\
386 	__abs_aligned_nonsingle(wr,2,(t),(h),(o),(a),(c))
387 #define	bus_space_write_region_4(t, h, o, a, c)				\
388 	__abs_aligned_nonsingle(wr,4,(t),(h),(o),(a),(c))
389 #define	bus_space_write_region_8(t, h, o, a, c)				\
390 	__abs_aligned_nonsingle(wr,8,(t),(h),(o),(a),(c))
391 
392 
393 /*
394  *	void bus_space_write_raw_region_N(bus_space_tag_t tag,
395  *	    bus_space_handle_t bsh, bus_size_t offset,
396  *	    const u_int8_t *addr, size_t count);
397  *
398  * Write `count' bytes in 2, 4 or 8 byte wide quantities to bus space
399  * described by tag/handle and starting at `offset' from the
400  * buffer provided.  The buffer must have proper alignment for the N byte
401  * wide entities.  Furthermore possible byte-swapping should be done by
402  * these functions.
403  */
404 
405 #define bus_space_write_raw_region_2(t, h, o, a, c)			\
406     bus_space_write_region_2((t), (h), (o), (const u_int16_t *)(a), (c) >> 1)
407 #define bus_space_write_raw_region_4(t, h, o, a, c)			\
408     bus_space_write_region_4((t), (h), (o), (const u_int32_t *)(a), (c) >> 2)
409 
410 /*
411  * Set multiple operations.
412  */
413 #define	bus_space_set_multi_1(t, h, o, v, c)				\
414 	__abs_set(sm,1,(t),(h),(o),(v),(c))
415 #define	bus_space_set_multi_2(t, h, o, v, c)				\
416 	__abs_set(sm,2,(t),(h),(o),(v),(c))
417 #define	bus_space_set_multi_4(t, h, o, v, c)				\
418 	__abs_set(sm,4,(t),(h),(o),(v),(c))
419 #define	bus_space_set_multi_8(t, h, o, v, c)				\
420 	__abs_set(sm,8,(t),(h),(o),(v),(c))
421 
422 
423 /*
424  * Set region operations.
425  */
426 #define	bus_space_set_region_1(t, h, o, v, c)				\
427 	__abs_set(sr,1,(t),(h),(o),(v),(c))
428 #define	bus_space_set_region_2(t, h, o, v, c)				\
429 	__abs_set(sr,2,(t),(h),(o),(v),(c))
430 #define	bus_space_set_region_4(t, h, o, v, c)				\
431 	__abs_set(sr,4,(t),(h),(o),(v),(c))
432 #define	bus_space_set_region_8(t, h, o, v, c)				\
433 	__abs_set(sr,8,(t),(h),(o),(v),(c))
434 
435 
436 /*
437  * Copy operations.
438  */
439 #define	bus_space_copy_1(t, h1, o1, h2, o2, c)				\
440 	__abs_copy(1, t, h1, o1, h2, o2, c)
441 #define	bus_space_copy_2(t, h1, o1, h2, o2, c)				\
442 	__abs_copy(2, t, h1, o1, h2, o2, c)
443 #define	bus_space_copy_4(t, h1, o1, h2, o2, c)				\
444 	__abs_copy(4, t, h1, o1, h2, o2, c)
445 #define	bus_space_copy_8(t, h1, o1, h2, o2, c)				\
446 	__abs_copy(8, t, h1, o1, h2, o2, c)
447 
448 /*
449  * Bus DMA methods.
450  */
451 
452 /*
453  * Flags used in various bus DMA methods.
454  */
455 #define	BUS_DMA_WAITOK		0x0000	/* safe to sleep (pseudo-flag) */
456 #define	BUS_DMA_NOWAIT		0x0001	/* not safe to sleep */
457 #define	BUS_DMA_ALLOCNOW	0x0002	/* perform resource allocation now */
458 #define	BUS_DMA_COHERENT	0x0004	/* hint: map memory DMA coherent */
459 #define	BUS_DMA_BUS1		0x0010	/* placeholders for bus functions... */
460 #define	BUS_DMA_BUS2		0x0020
461 #define	BUS_DMA_BUS3		0x0040
462 #define	BUS_DMA_24BIT		0x0080	/* isadma map */
463 #define	BUS_DMA_STREAMING	0x0100	/* hint: sequential, unidirectional */
464 #define	BUS_DMA_READ		0x0200	/* mapping is device -> memory only */
465 #define	BUS_DMA_WRITE		0x0400	/* mapping is memory -> device only */
466 #define	BUS_DMA_ZERO		0x1000	/* zero memory in dmamem_alloc */
467 #define	BUS_DMA_64BIT		0x2000	/* device handles 64bit dva */
468 
469 /*
470  * Private flags stored in the DMA map.
471  */
472 #define	DMAMAP_NO_COALESCE	0x40000000	/* don't coalesce adjacent
473 						   segments */
474 
475 /* Forwards needed by prototypes below. */
476 struct mbuf;
477 struct uio;
478 struct alpha_sgmap;
479 
480 /*
481  * Operations performed by bus_dmamap_sync().
482  */
483 #define BUS_DMASYNC_PREREAD	0x01
484 #define BUS_DMASYNC_POSTREAD	0x02
485 #define BUS_DMASYNC_PREWRITE	0x04
486 #define BUS_DMASYNC_POSTWRITE	0x08
487 
488 /*
489  *	alpha_bus_t
490  *
491  *	Busses supported by NetBSD/alpha, used by internal
492  *	utility functions.  NOT TO BE USED BY MACHINE-INDEPENDENT
493  *	CODE!
494  */
495 typedef enum {
496 	ALPHA_BUS_TURBOCHANNEL,
497 	ALPHA_BUS_PCI,
498 	ALPHA_BUS_EISA,
499 	ALPHA_BUS_ISA,
500 	ALPHA_BUS_TLSB,
501 } alpha_bus_t;
502 
503 typedef struct alpha_bus_dma_tag	*bus_dma_tag_t;
504 typedef struct alpha_bus_dmamap		*bus_dmamap_t;
505 
506 /*
507  *	bus_dma_segment_t
508  *
509  *	Describes a single contiguous DMA transaction.  Values
510  *	are suitable for programming into DMA registers.
511  */
512 struct alpha_bus_dma_segment {
513 	bus_addr_t	ds_addr;	/* DMA address */
514 	bus_size_t	ds_len;		/* length of transfer */
515 };
516 typedef struct alpha_bus_dma_segment	bus_dma_segment_t;
517 
518 /*
519  *	bus_dma_tag_t
520  *
521  *	A machine-dependent opaque type describing the implementation of
522  *	DMA for a given bus.
523  */
524 struct alpha_bus_dma_tag {
525 	void	*_cookie;		/* cookie used in the guts */
526 	bus_addr_t _wbase;		/* DMA window base */
527 
528 	/*
529 	 * The following two members are used to chain DMA windows
530 	 * together.  If, during the course of a map load, the
531 	 * resulting physical memory address is too large to
532 	 * be addressed by the window, the next window will be
533 	 * attempted.  These would be chained together like so:
534 	 *
535 	 *	direct -> sgmap -> NULL
536 	 *  or
537 	 *	sgmap -> NULL
538 	 *  or
539 	 *	direct -> NULL
540 	 *
541 	 * If the window size is 0, it will not be checked (e.g.
542 	 * TurboChannel DMA).
543 	 */
544 	bus_size_t _wsize;
545 	struct alpha_bus_dma_tag *_next_window;
546 
547 	/*
548 	 * Some chipsets have a built-in boundary constraint, independent
549 	 * of what the device requests.  This allows that boundary to
550 	 * be specified.  If the device has a more restrictive constraint,
551 	 * the map will use that, otherwise this boundary will be used.
552 	 * This value is ignored if 0.
553 	 */
554 	bus_size_t _boundary;
555 
556 	/*
557 	 * A chipset may have more than one SGMAP window, so SGMAP
558 	 * windows also get a pointer to their SGMAP state.
559 	 */
560 	struct alpha_sgmap *_sgmap;
561 
562 	/*
563 	 * Internal-use only utility methods.  NOT TO BE USED BY
564 	 * MACHINE-INDEPENDENT CODE!
565 	 */
566 	bus_dma_tag_t (*_get_tag)(bus_dma_tag_t, alpha_bus_t);
567 
568 	/*
569 	 * DMA mapping methods.
570 	 */
571 	int	(*_dmamap_create)(bus_dma_tag_t, bus_size_t, int,
572 		    bus_size_t, bus_size_t, int, bus_dmamap_t *);
573 	void	(*_dmamap_destroy)(bus_dma_tag_t, bus_dmamap_t);
574 	int	(*_dmamap_load)(bus_dma_tag_t, bus_dmamap_t, void *,
575 		    bus_size_t, struct proc *, int);
576 	int	(*_dmamap_load_mbuf)(bus_dma_tag_t, bus_dmamap_t,
577 		    struct mbuf *, int);
578 	int	(*_dmamap_load_uio)(bus_dma_tag_t, bus_dmamap_t,
579 		    struct uio *, int);
580 	int	(*_dmamap_load_raw)(bus_dma_tag_t, bus_dmamap_t,
581 		    bus_dma_segment_t *, int, bus_size_t, int);
582 	void	(*_dmamap_unload)(bus_dma_tag_t, bus_dmamap_t);
583 	void	(*_dmamap_sync)(bus_dma_tag_t, bus_dmamap_t,
584 		    bus_addr_t, bus_size_t, int);
585 
586 	/*
587 	 * DMA memory utility functions.
588 	 */
589 	int	(*_dmamem_alloc)(bus_dma_tag_t, bus_size_t, bus_size_t,
590 		    bus_size_t, bus_dma_segment_t *, int, int *, int);
591 	void	(*_dmamem_free)(bus_dma_tag_t,
592 		    bus_dma_segment_t *, int);
593 	int	(*_dmamem_map)(bus_dma_tag_t, bus_dma_segment_t *,
594 		    int, size_t, caddr_t *, int);
595 	void	(*_dmamem_unmap)(bus_dma_tag_t, caddr_t, size_t);
596 	paddr_t	(*_dmamem_mmap)(bus_dma_tag_t, bus_dma_segment_t *,
597 		    int, off_t, int, int);
598 };
599 
600 #define	alphabus_dma_get_tag(t, b)				\
601 	(*(t)->_get_tag)(t, b)
602 
603 #define	bus_dmamap_create(t, s, n, m, b, f, p)			\
604 	(*(t)->_dmamap_create)((t), (s), (n), (m), (b), (f), (p))
605 #define	bus_dmamap_destroy(t, p)				\
606 	(*(t)->_dmamap_destroy)((t), (p))
607 #define	bus_dmamap_load(t, m, b, s, p, f)			\
608 	(*(t)->_dmamap_load)((t), (m), (b), (s), (p), (f))
609 #define	bus_dmamap_load_mbuf(t, m, b, f)			\
610 	(*(t)->_dmamap_load_mbuf)((t), (m), (b), (f))
611 #define	bus_dmamap_load_uio(t, m, u, f)				\
612 	(*(t)->_dmamap_load_uio)((t), (m), (u), (f))
613 #define	bus_dmamap_load_raw(t, m, sg, n, s, f)			\
614 	(*(t)->_dmamap_load_raw)((t), (m), (sg), (n), (s), (f))
615 #define	bus_dmamap_unload(t, p)					\
616 	(void)(t),						\
617 	(*(p)->_dm_window->_dmamap_unload)((p)->_dm_window, (p))
618 #define	bus_dmamap_sync(t, p, a, s, op)				\
619 	(void)(t), 						\
620 	(*(p)->_dm_window->_dmamap_sync)((p)->_dm_window, (p), (a), (s), (op))
621 #define	bus_dmamem_alloc(t, s, a, b, sg, n, r, f)		\
622 	(*(t)->_dmamem_alloc)((t), (s), (a), (b), (sg), (n), (r), (f))
623 #define	bus_dmamem_free(t, sg, n)				\
624 	(*(t)->_dmamem_free)((t), (sg), (n))
625 #define	bus_dmamem_map(t, sg, n, s, k, f)			\
626 	(*(t)->_dmamem_map)((t), (sg), (n), (s), (k), (f))
627 #define	bus_dmamem_unmap(t, k, s)				\
628 	(*(t)->_dmamem_unmap)((t), (k), (s))
629 #define	bus_dmamem_mmap(t, sg, n, o, p, f)			\
630 	(*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
631 
632 /*
633  *	bus_dmamap_t
634  *
635  *	Describes a DMA mapping.
636  */
637 struct alpha_bus_dmamap {
638 	/*
639 	 * PRIVATE MEMBERS: not for use by machine-independent code.
640 	 */
641 	bus_size_t	_dm_size;	/* largest DMA transfer mappable */
642 	int		_dm_segcnt;	/* number of segs this map can map */
643 	bus_size_t	_dm_maxsegsz;	/* largest possible segment */
644 	bus_size_t	_dm_boundary;	/* don't cross this */
645 	int		_dm_flags;	/* misc. flags */
646 
647 	/*
648 	 * Private cookie to be used by the DMA back-end.
649 	 */
650 	void		*_dm_cookie;
651 
652 	/*
653 	 * The DMA window that we ended up being mapped in.
654 	 */
655 	bus_dma_tag_t	_dm_window;
656 
657 	/*
658 	 * PUBLIC MEMBERS: these are used by machine-independent code.
659 	 */
660 	bus_size_t	dm_mapsize;	/* size of the mapping */
661 	int		dm_nsegs;	/* # valid segments in mapping */
662 	bus_dma_segment_t dm_segs[1];	/* segments; variable length */
663 };
664 
665 #ifdef _ALPHA_BUS_DMA_PRIVATE
666 int	_bus_dmamap_create(bus_dma_tag_t, bus_size_t, int, bus_size_t,
667 	    bus_size_t, int, bus_dmamap_t *);
668 void	_bus_dmamap_destroy(bus_dma_tag_t, bus_dmamap_t);
669 
670 int	_bus_dmamap_load_direct(bus_dma_tag_t, bus_dmamap_t,
671 	    void *, bus_size_t, struct proc *, int);
672 int	_bus_dmamap_load_mbuf_direct(bus_dma_tag_t,
673 	    bus_dmamap_t, struct mbuf *, int);
674 int	_bus_dmamap_load_uio_direct(bus_dma_tag_t,
675 	    bus_dmamap_t, struct uio *, int);
676 int	_bus_dmamap_load_raw_direct(bus_dma_tag_t,
677 	    bus_dmamap_t, bus_dma_segment_t *, int, bus_size_t, int);
678 
679 void	_bus_dmamap_unload(bus_dma_tag_t, bus_dmamap_t);
680 void	_bus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t, bus_addr_t,
681 	    bus_size_t, int);
682 
683 int	_bus_dmamem_alloc(bus_dma_tag_t tag, bus_size_t size,
684 	    bus_size_t alignment, bus_size_t boundary,
685 	    bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags);
686 int	_bus_dmamem_alloc_range(bus_dma_tag_t tag, bus_size_t size,
687 	    bus_size_t alignment, bus_size_t boundary,
688 	    bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags,
689 	    paddr_t low, paddr_t high);
690 void	_bus_dmamem_free(bus_dma_tag_t tag, bus_dma_segment_t *segs,
691 	    int nsegs);
692 int	_bus_dmamem_map(bus_dma_tag_t tag, bus_dma_segment_t *segs,
693 	    int nsegs, size_t size, caddr_t *kvap, int flags);
694 void	_bus_dmamem_unmap(bus_dma_tag_t tag, caddr_t kva,
695 	    size_t size);
696 paddr_t	_bus_dmamem_mmap(bus_dma_tag_t tag, bus_dma_segment_t *segs,
697 	    int nsegs, off_t off, int prot, int flags);
698 #endif /* _ALPHA_BUS_DMA_PRIVATE */
699 
700 #endif /* _MACHINE_BUS_H_ */
701