1 /* $NetBSD: bus.h,v 1.26 2019/09/23 16:17:58 skrll Exp $ */
2
3 /*-
4 * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9 * NASA Ames Research Center.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 /*
34 * bus_space(9) and bus_dma(9) interface for NetBSD/x68k.
35 */
36
37 #ifndef _X68K_BUS_H_
38 #define _X68K_BUS_H_
39
40 /*
41 * Bus address and size types
42 */
43 typedef u_long bus_addr_t;
44 typedef u_long bus_size_t;
45 typedef u_long bus_space_handle_t;
46
47 #define PRIxBUSADDR "lx"
48 #define PRIxBUSSIZE "lx"
49 #define PRIuBUSSIZE "lu"
50 #define PRIxBSH "lx"
51
52 /*
53 * Bus space descripter
54 */
55 typedef struct x68k_bus_space *bus_space_tag_t;
56
57 struct x68k_bus_space {
58 #if 0
59 enum {
60 X68K_INTIO_BUS,
61 X68K_PCI_BUS,
62 X68K_NEPTUNE_BUS
63 } x68k_bus_type;
64 #endif
65
66 int (*x68k_bus_space_map)(
67 bus_space_tag_t,
68 bus_addr_t,
69 bus_size_t,
70 int, /* flags */
71 bus_space_handle_t *);
72 void (*x68k_bus_space_unmap)(
73 bus_space_tag_t,
74 bus_space_handle_t,
75 bus_size_t);
76 int (*x68k_bus_space_subregion)(
77 bus_space_tag_t,
78 bus_space_handle_t,
79 bus_size_t, /* offset */
80 bus_size_t, /* size */
81 bus_space_handle_t *);
82
83 int (*x68k_bus_space_alloc)(
84 bus_space_tag_t,
85 bus_addr_t, /* reg_start */
86 bus_addr_t, /* reg_end */
87 bus_size_t,
88 bus_size_t, /* alignment */
89 bus_size_t, /* boundary */
90 int, /* flags */
91 bus_addr_t *,
92 bus_space_handle_t *);
93 void (*x68k_bus_space_free)(
94 bus_space_tag_t,
95 bus_space_handle_t,
96 bus_size_t);
97
98 #if 0
99 void (*x68k_bus_space_barrier)(
100 bus_space_tag_t,
101 bus_space_handle_t,
102 bus_size_t, /* offset */
103 bus_size_t, /* length */
104 int); /* flags */
105 #endif
106
107 device_t x68k_bus_device;
108 };
109
110 int x68k_bus_space_alloc(bus_space_tag_t, bus_addr_t, bus_addr_t, bus_size_t,
111 bus_size_t, bus_size_t, int, bus_addr_t *, bus_space_handle_t *);
112 void x68k_bus_space_free(bus_space_tag_t, bus_space_handle_t, bus_size_t);
113
114 /*
115 * bus_space(9) interface
116 */
117
118 #define bus_space_map(t, a, s, f, h) \
119 ((*((t)->x68k_bus_space_map)) ((t), (a), (s), (f), (h)))
120 #define bus_space_unmap(t, h, s) \
121 ((*((t)->x68k_bus_space_unmap)) ((t), (h), (s)))
122 #define bus_space_subregion(t, h, o, s, p) \
123 ((*((t)->x68k_bus_space_subregion)) ((t), (h), (o), (s), (p)))
124 #define BUS_SPACE_MAP_CACHEABLE 0x0001
125 #define BUS_SPACE_MAP_LINEAR 0x0002
126 #define BUS_SPACE_MAP_PREFETCHABLE 0x0004
127 /*
128 * For simpler hardware, many x68k devices are mapped with shifted address
129 * i.e. only on even or odd addresses.
130 */
131 #define BUS_SPACE_MAP_SHIFTED_MASK 0x1001
132 #define BUS_SPACE_MAP_SHIFTED_ODD 0x1001
133 #define BUS_SPACE_MAP_SHIFTED_EVEN 0x1000
134 #define BUS_SPACE_MAP_SHIFTED BUS_SPACE_MAP_SHIFTED_ODD
135
136 #define bus_space_alloc(t, rs, re, s, a, b, f, r, h) \
137 ((*((t)->x68k_bus_space_alloc)) ((t), \
138 (rs), (re), (s), (a), (b), (f), (r), (h)))
139 #define bus_space_free(t, h, s) \
140 ((*((t)->x68k_bus_space_free)) ((t), (h), (s)))
141
142 /*
143 * Note: the 680x0 does not currently require barriers, but we must
144 * provide the flags to MI code.
145 */
146 #define bus_space_barrier(t, h, o, l, f) \
147 ((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f)))
148 #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */
149 #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */
150
151 #define bus_space_read_1(t,h,o) _bus_space_read_1(t,h,o)
152 #define bus_space_read_2(t,h,o) _bus_space_read_2(t,h,o)
153 #define bus_space_read_4(t,h,o) _bus_space_read_4(t,h,o)
154
155 #define bus_space_read_multi_1(t,h,o,p,c) _bus_space_read_multi_1(t,h,o,p,c)
156 #define bus_space_read_multi_2(t,h,o,p,c) _bus_space_read_multi_2(t,h,o,p,c)
157 #define bus_space_read_multi_4(t,h,o,p,c) _bus_space_read_multi_4(t,h,o,p,c)
158
159 #define bus_space_read_region_1(t,h,o,p,c) _bus_space_read_region_1(t,h,o,p,c)
160 #define bus_space_read_region_2(t,h,o,p,c) _bus_space_read_region_2(t,h,o,p,c)
161 #define bus_space_read_region_4(t,h,o,p,c) _bus_space_read_region_4(t,h,o,p,c)
162
163 #define bus_space_write_1(t,h,o,v) _bus_space_write_1(t,h,o,v)
164 #define bus_space_write_2(t,h,o,v) _bus_space_write_2(t,h,o,v)
165 #define bus_space_write_4(t,h,o,v) _bus_space_write_4(t,h,o,v)
166
167 #define bus_space_write_multi_1(t,h,o,p,c) _bus_space_write_multi_1(t,h,o,p,c)
168 #define bus_space_write_multi_2(t,h,o,p,c) _bus_space_write_multi_2(t,h,o,p,c)
169 #define bus_space_write_multi_4(t,h,o,p,c) _bus_space_write_multi_4(t,h,o,p,c)
170
171 #define bus_space_write_region_1(t,h,o,p,c) \
172 _bus_space_write_region_1(t,h,o,p,c)
173 #define bus_space_write_region_2(t,h,o,p,c) \
174 _bus_space_write_region_2(t,h,o,p,c)
175 #define bus_space_write_region_4(t,h,o,p,c) \
176 _bus_space_write_region_4(t,h,o,p,c)
177
178 #define bus_space_set_region_1(t,h,o,v,c) _bus_space_set_region_1(t,h,o,v,c)
179 #define bus_space_set_region_2(t,h,o,v,c) _bus_space_set_region_2(t,h,o,v,c)
180 #define bus_space_set_region_4(t,h,o,v,c) _bus_space_set_region_4(t,h,o,v,c)
181
182 #define bus_space_copy_region_1(t,sh,so,dh,do,c) \
183 _bus_space_copy_region_1(t,sh,so,dh,do,c)
184 #define bus_space_copy_region_2(t,sh,so,dh,do,c) \
185 _bus_space_copy_region_2(t,sh,so,dh,do,c)
186 #define bus_space_copy_region_4(t,sh,so,dh,do,c) \
187 _bus_space_copy_region_4(t,sh,so,dh,do,c)
188
189 static __inline uint8_t _bus_space_read_1
190 (bus_space_tag_t, bus_space_handle_t bsh, bus_size_t offset);
191 static __inline uint16_t _bus_space_read_2
192 (bus_space_tag_t, bus_space_handle_t, bus_size_t);
193 static __inline uint32_t _bus_space_read_4
194 (bus_space_tag_t, bus_space_handle_t, bus_size_t);
195
196 static __inline void _bus_space_read_multi_1
197 (bus_space_tag_t, bus_space_handle_t, bus_size_t,
198 uint8_t *, bus_size_t);
199 static __inline void _bus_space_read_multi_2
200 (bus_space_tag_t, bus_space_handle_t, bus_size_t,
201 uint16_t *, bus_size_t);
202 static __inline void _bus_space_read_multi_4
203 (bus_space_tag_t, bus_space_handle_t, bus_size_t,
204 uint32_t *, bus_size_t);
205
206 static __inline void _bus_space_read_region_1
207 (bus_space_tag_t, bus_space_handle_t, bus_size_t,
208 uint8_t *, bus_size_t);
209 static __inline void _bus_space_read_region_2
210 (bus_space_tag_t, bus_space_handle_t, bus_size_t,
211 uint16_t *, bus_size_t);
212 static __inline void _bus_space_read_region_4
213 (bus_space_tag_t, bus_space_handle_t, bus_size_t,
214 uint32_t *, bus_size_t);
215
216 static __inline void _bus_space_write_1
217 (bus_space_tag_t, bus_space_handle_t, bus_size_t, uint8_t);
218 static __inline void _bus_space_write_2
219 (bus_space_tag_t, bus_space_handle_t, bus_size_t, uint16_t);
220 static __inline void _bus_space_write_4
221 (bus_space_tag_t, bus_space_handle_t, bus_size_t, uint32_t);
222
223 static __inline void _bus_space_write_multi_1
224 (bus_space_tag_t, bus_space_handle_t, bus_size_t,
225 const uint8_t *, bus_size_t);
226 static __inline void _bus_space_write_multi_2
227 (bus_space_tag_t, bus_space_handle_t, bus_size_t,
228 const uint16_t *, bus_size_t);
229 static __inline void _bus_space_write_multi_4
230 (bus_space_tag_t, bus_space_handle_t, bus_size_t,
231 const uint32_t *, bus_size_t);
232
233 static __inline void _bus_space_write_region_1
234 (bus_space_tag_t, bus_space_handle_t, bus_size_t,
235 const uint8_t *, bus_size_t);
236 static __inline void _bus_space_write_region_2
237 (bus_space_tag_t, bus_space_handle_t, bus_size_t,
238 const uint16_t *, bus_size_t);
239 static __inline void _bus_space_write_region_4
240 (bus_space_tag_t, bus_space_handle_t, bus_size_t,
241 const uint32_t *, bus_size_t);
242
243 static __inline void _bus_space_set_region_1
244 (bus_space_tag_t, bus_space_handle_t, bus_size_t,
245 uint8_t, bus_size_t);
246 static __inline void _bus_space_set_region_2
247 (bus_space_tag_t, bus_space_handle_t, bus_size_t,
248 uint16_t, bus_size_t);
249 static __inline void _bus_space_set_region_4
250 (bus_space_tag_t, bus_space_handle_t, bus_size_t,
251 uint32_t, bus_size_t);
252
253 static __inline void _bus_space_copy_region_1
254 (bus_space_tag_t, bus_space_handle_t, bus_size_t,
255 bus_space_handle_t, bus_size_t, bus_size_t);
256 static __inline void _bus_space_copy_region_2
257 (bus_space_tag_t, bus_space_handle_t, bus_size_t,
258 bus_space_handle_t, bus_size_t, bus_size_t);
259 static __inline void _bus_space_copy_region_4
260 (bus_space_tag_t, bus_space_handle_t, bus_size_t,
261 bus_space_handle_t, bus_size_t, bus_size_t);
262
263
264 #define __X68K_BUS_ADDR(tag, handle, offset) \
265 (((long)(handle) < 0 ? (offset) * 2 : (offset)) \
266 + ((handle) & 0x7fffffff))
267
268 static __inline uint8_t
_bus_space_read_1(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset)269 _bus_space_read_1(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t offset)
270 {
271
272 return *((volatile uint8_t *) __X68K_BUS_ADDR(t, bsh, offset));
273 }
274
275 static __inline uint16_t
_bus_space_read_2(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset)276 _bus_space_read_2(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t offset)
277 {
278
279 return *((volatile uint16_t *) __X68K_BUS_ADDR(t, bsh, offset));
280 }
281
282 static __inline uint32_t
_bus_space_read_4(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset)283 _bus_space_read_4(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t offset)
284 {
285
286 return *((volatile uint32_t *) __X68K_BUS_ADDR(t, bsh, offset));
287 }
288
289 static __inline void
_bus_space_read_multi_1(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset,uint8_t * datap,bus_size_t count)290 _bus_space_read_multi_1(bus_space_tag_t t, bus_space_handle_t bsh,
291 bus_size_t offset, uint8_t *datap, bus_size_t count)
292 {
293 volatile uint8_t *regadr;
294
295 regadr = (volatile uint8_t *)__X68K_BUS_ADDR(t, bsh, offset);
296
297 for (; count; count--)
298 *datap++ = *regadr;
299 }
300
301 static __inline void
_bus_space_read_multi_2(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset,uint16_t * datap,bus_size_t count)302 _bus_space_read_multi_2(bus_space_tag_t t, bus_space_handle_t bsh,
303 bus_size_t offset, uint16_t *datap, bus_size_t count)
304 {
305 volatile uint16_t *regadr;
306
307 regadr = (volatile uint16_t *)__X68K_BUS_ADDR(t, bsh, offset);
308
309 for (; count; count--)
310 *datap++ = *regadr;
311 }
312
313 static __inline void
_bus_space_read_multi_4(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset,uint32_t * datap,bus_size_t count)314 _bus_space_read_multi_4(bus_space_tag_t t, bus_space_handle_t bsh,
315 bus_size_t offset, uint32_t *datap, bus_size_t count)
316 {
317 volatile uint32_t *regadr;
318
319 regadr = (volatile uint32_t *)__X68K_BUS_ADDR(t, bsh, offset);
320
321 for (; count; count--)
322 *datap++ = *regadr;
323 }
324
325 static __inline void
_bus_space_read_region_1(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset,uint8_t * datap,bus_size_t count)326 _bus_space_read_region_1(bus_space_tag_t t, bus_space_handle_t bsh,
327 bus_size_t offset, uint8_t *datap, bus_size_t count)
328 {
329 volatile uint8_t *addr;
330
331 addr = (volatile uint8_t *)__X68K_BUS_ADDR(t, bsh, offset);
332
333 for (; count; count--)
334 *datap++ = *addr++;
335 }
336
337 static __inline void
_bus_space_read_region_2(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset,uint16_t * datap,bus_size_t count)338 _bus_space_read_region_2(bus_space_tag_t t, bus_space_handle_t bsh,
339 bus_size_t offset, uint16_t *datap, bus_size_t count)
340 {
341 volatile uint16_t *addr;
342
343 addr = (volatile uint16_t *)__X68K_BUS_ADDR(t, bsh, offset);
344
345 for (; count; count--)
346 *datap++ = *addr++;
347 }
348
349 static __inline void
_bus_space_read_region_4(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset,uint32_t * datap,bus_size_t count)350 _bus_space_read_region_4(bus_space_tag_t t, bus_space_handle_t bsh,
351 bus_size_t offset, uint32_t *datap, bus_size_t count)
352 {
353 volatile uint32_t *addr;
354
355 addr = (volatile uint32_t *)__X68K_BUS_ADDR(t, bsh, offset);
356
357 for (; count; count--)
358 *datap++ = *addr++;
359 }
360
361 static __inline void
_bus_space_write_1(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset,uint8_t value)362 _bus_space_write_1(bus_space_tag_t t, bus_space_handle_t bsh,
363 bus_size_t offset, uint8_t value)
364 {
365
366 *(volatile uint8_t *) __X68K_BUS_ADDR(t, bsh, offset) = value;
367 }
368
369 static __inline void
_bus_space_write_2(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset,uint16_t value)370 _bus_space_write_2(bus_space_tag_t t, bus_space_handle_t bsh,
371 bus_size_t offset, uint16_t value)
372 {
373
374 *(volatile uint16_t *) __X68K_BUS_ADDR(t, bsh, offset) = value;
375 }
376
377 static __inline void
_bus_space_write_4(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset,uint32_t value)378 _bus_space_write_4(bus_space_tag_t t, bus_space_handle_t bsh,
379 bus_size_t offset, uint32_t value)
380 {
381
382 *(volatile uint32_t *) __X68K_BUS_ADDR(t, bsh, offset) = value;
383 }
384
385 static __inline void
_bus_space_write_multi_1(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset,const uint8_t * datap,bus_size_t count)386 _bus_space_write_multi_1(bus_space_tag_t t, bus_space_handle_t bsh,
387 bus_size_t offset, const uint8_t *datap, bus_size_t count)
388 {
389 volatile uint8_t *regadr;
390
391 regadr = (volatile uint8_t *)__X68K_BUS_ADDR(t, bsh, offset);
392
393 for (; count; count--)
394 *regadr = *datap++;
395 }
396
397 static __inline void
_bus_space_write_multi_2(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset,const uint16_t * datap,bus_size_t count)398 _bus_space_write_multi_2(bus_space_tag_t t, bus_space_handle_t bsh,
399 bus_size_t offset, const uint16_t *datap, bus_size_t count)
400 {
401 volatile uint16_t *regadr;
402
403 regadr = (volatile uint16_t *)__X68K_BUS_ADDR(t, bsh, offset);
404
405 for (; count; count--)
406 *regadr = *datap++;
407 }
408
409 static __inline void
_bus_space_write_multi_4(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset,const uint32_t * datap,bus_size_t count)410 _bus_space_write_multi_4(bus_space_tag_t t, bus_space_handle_t bsh,
411 bus_size_t offset, const uint32_t *datap, bus_size_t count)
412 {
413 volatile uint32_t *regadr;
414
415 regadr = (volatile uint32_t *)__X68K_BUS_ADDR(t, bsh, offset);
416
417 for (; count; count--)
418 *regadr = *datap++;
419 }
420
421 static __inline void
_bus_space_write_region_1(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset,const uint8_t * datap,bus_size_t count)422 _bus_space_write_region_1(bus_space_tag_t t, bus_space_handle_t bsh,
423 bus_size_t offset, const uint8_t *datap, bus_size_t count)
424 {
425 volatile uint8_t *addr;
426
427 addr = (volatile uint8_t *)__X68K_BUS_ADDR(t, bsh, offset);
428
429 for (; count; count--)
430 *addr++ = *datap++;
431 }
432
433 static __inline void
_bus_space_write_region_2(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset,const uint16_t * datap,bus_size_t count)434 _bus_space_write_region_2(bus_space_tag_t t, bus_space_handle_t bsh,
435 bus_size_t offset, const uint16_t *datap, bus_size_t count)
436 {
437 volatile uint16_t *addr;
438
439 addr = (volatile uint16_t *)__X68K_BUS_ADDR(t, bsh, offset);
440
441 for (; count; count--)
442 *addr++ = *datap++;
443 }
444
445 static __inline void
_bus_space_write_region_4(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset,const uint32_t * datap,bus_size_t count)446 _bus_space_write_region_4(bus_space_tag_t t, bus_space_handle_t bsh,
447 bus_size_t offset, const uint32_t *datap, bus_size_t count)
448 {
449 volatile uint32_t *addr;
450
451 addr = (volatile uint32_t *)__X68K_BUS_ADDR(t, bsh, offset);
452
453 for (; count; count--)
454 *addr++ = *datap++;
455 }
456
457 static __inline void
_bus_space_set_region_1(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset,uint8_t value,bus_size_t count)458 _bus_space_set_region_1(bus_space_tag_t t, bus_space_handle_t bsh,
459 bus_size_t offset, uint8_t value, bus_size_t count)
460 {
461 volatile uint8_t *addr;
462
463 addr = (volatile uint8_t *)__X68K_BUS_ADDR(t, bsh, offset);
464
465 for (; count; count--)
466 *addr++ = value;
467 }
468
469 static __inline void
_bus_space_set_region_2(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset,uint16_t value,bus_size_t count)470 _bus_space_set_region_2(bus_space_tag_t t, bus_space_handle_t bsh,
471 bus_size_t offset, uint16_t value, bus_size_t count)
472 {
473 volatile uint16_t *addr;
474
475 addr = (volatile uint16_t *)__X68K_BUS_ADDR(t, bsh, offset);
476
477 for (; count; count--)
478 *addr++ = value;
479 }
480
481 static __inline void
_bus_space_set_region_4(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset,uint32_t value,bus_size_t count)482 _bus_space_set_region_4(bus_space_tag_t t, bus_space_handle_t bsh,
483 bus_size_t offset, uint32_t value, bus_size_t count)
484 {
485 volatile uint32_t *addr;
486
487 addr = (volatile uint32_t *)__X68K_BUS_ADDR(t, bsh, offset);
488
489 for (; count; count--)
490 *addr++ = value;
491 }
492
493 static __inline void
_bus_space_copy_region_1(bus_space_tag_t t,bus_space_handle_t sbsh,bus_size_t soffset,bus_space_handle_t dbsh,bus_size_t doffset,bus_size_t count)494 _bus_space_copy_region_1(bus_space_tag_t t,
495 bus_space_handle_t sbsh, bus_size_t soffset,
496 bus_space_handle_t dbsh, bus_size_t doffset,
497 bus_size_t count)
498 {
499 volatile uint8_t *saddr = (void *) (sbsh + soffset);
500 volatile uint8_t *daddr = (void *) (dbsh + doffset);
501
502 if ((uint32_t) saddr >= (uint32_t) daddr)
503 while (count-- > 0)
504 *daddr++ = *saddr++;
505 else {
506 saddr += count;
507 daddr += count;
508 while (count-- > 0)
509 *--daddr = *--saddr;
510 }
511 }
512
513 static __inline void
_bus_space_copy_region_2(bus_space_tag_t t,bus_space_handle_t sbsh,bus_size_t soffset,bus_space_handle_t dbsh,bus_size_t doffset,bus_size_t count)514 _bus_space_copy_region_2(bus_space_tag_t t,
515 bus_space_handle_t sbsh, bus_size_t soffset,
516 bus_space_handle_t dbsh, bus_size_t doffset,
517 bus_size_t count)
518 {
519 volatile uint16_t *saddr = (void *) (sbsh + soffset);
520 volatile uint16_t *daddr = (void *) (dbsh + doffset);
521
522 if ((uint32_t) saddr >= (uint32_t) daddr)
523 while (count-- > 0)
524 *daddr++ = *saddr++;
525 else {
526 saddr += count;
527 daddr += count;
528 while (count-- > 0)
529 *--daddr = *--saddr;
530 }
531 }
532
533 static __inline void
_bus_space_copy_region_4(bus_space_tag_t t,bus_space_handle_t sbsh,bus_size_t soffset,bus_space_handle_t dbsh,bus_size_t doffset,bus_size_t count)534 _bus_space_copy_region_4(bus_space_tag_t t,
535 bus_space_handle_t sbsh, bus_size_t soffset,
536 bus_space_handle_t dbsh, bus_size_t doffset,
537 bus_size_t count)
538 {
539 volatile uint32_t *saddr = (void *) (sbsh + soffset);
540 volatile uint32_t *daddr = (void *) (dbsh + doffset);
541
542 if ((uint32_t) saddr >= (uint32_t) daddr)
543 while (count-- > 0)
544 *daddr++ = *saddr++;
545 else {
546 saddr += count;
547 daddr += count;
548 while (count-- > 0)
549 *--daddr = *--saddr;
550 }
551 }
552
553 #define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t)
554
555 /*
556 * DMA segment
557 */
558 struct x68k_bus_dma_segment {
559 bus_addr_t ds_addr;
560 bus_size_t ds_len;
561 };
562 typedef struct x68k_bus_dma_segment bus_dma_segment_t;
563
564 /*
565 * DMA descriptor
566 */
567 /* Forwards needed by prototypes below. */
568 struct mbuf;
569 struct uio;
570
571 typedef struct x68k_bus_dma *bus_dma_tag_t;
572 typedef struct x68k_bus_dmamap *bus_dmamap_t;
573
574 #define BUS_DMA_TAG_VALID(t) ((t) != (bus_dma_tag_t)0)
575
576 struct x68k_bus_dma {
577 /*
578 * The `bounce threshold' is checked while we are loading
579 * the DMA map. If the physical address of the segment
580 * exceeds the threshold, an error will be returned. The
581 * caller can then take whatever action is necessary to
582 * bounce the transfer. If this value is 0, it will be
583 * ignored.
584 */
585 bus_addr_t _bounce_thresh;
586
587 /*
588 * DMA mapping methods.
589 */
590 int (*x68k_dmamap_create)(bus_dma_tag_t, bus_size_t, int,
591 bus_size_t, bus_size_t, int, bus_dmamap_t *);
592 void (*x68k_dmamap_destroy)(bus_dma_tag_t, bus_dmamap_t);
593 int (*x68k_dmamap_load)(bus_dma_tag_t, bus_dmamap_t, void *,
594 bus_size_t, struct proc *, int);
595 int (*x68k_dmamap_load_mbuf)(bus_dma_tag_t, bus_dmamap_t,
596 struct mbuf *, int);
597 int (*x68k_dmamap_load_uio)(bus_dma_tag_t, bus_dmamap_t,
598 struct uio *, int);
599 int (*x68k_dmamap_load_raw)(bus_dma_tag_t, bus_dmamap_t,
600 bus_dma_segment_t *, int, bus_size_t, int);
601 void (*x68k_dmamap_unload)(bus_dma_tag_t, bus_dmamap_t);
602 void (*x68k_dmamap_sync)(bus_dma_tag_t, bus_dmamap_t,
603 bus_addr_t, bus_size_t, int);
604
605 /*
606 * DMA memory utility functions.
607 */
608 int (*x68k_dmamem_alloc)(bus_dma_tag_t, bus_size_t, bus_size_t,
609 bus_size_t, bus_dma_segment_t *, int, int *, int);
610 void (*x68k_dmamem_free)(bus_dma_tag_t,
611 bus_dma_segment_t *, int);
612 int (*x68k_dmamem_map)(bus_dma_tag_t, bus_dma_segment_t *,
613 int, size_t, void **, int);
614 void (*x68k_dmamem_unmap)(bus_dma_tag_t, void *, size_t);
615 paddr_t (*x68k_dmamem_mmap)(bus_dma_tag_t, bus_dma_segment_t *,
616 int, off_t, int, int);
617 };
618
619 /*
620 * bus_dmamap_t
621 *
622 * Describes a DMA mapping.
623 */
624 struct x68k_bus_dmamap {
625 /*
626 * PRIVATE MEMBERS: not for use my machine-independent code.
627 */
628 bus_size_t x68k_dm_size; /* largest DMA transfer mappable */
629 int x68k_dm_segcnt; /* number of segs this map can map */
630 bus_size_t x68k_dm_maxmaxsegsz; /* fixed largest possible segment*/
631 bus_size_t x68k_dm_boundary; /* don't cross this */
632 bus_addr_t x68k_dm_bounce_thresh; /* bounce threshold */
633 int x68k_dm_flags; /* misc. flags */
634
635 void *x68k_dm_cookie; /* cookie for bus-specific functions */
636
637 /*
638 * PUBLIC MEMBERS: these are used by machine-independent code.
639 */
640 bus_size_t dm_maxsegsz; /* largest possible segment */
641 bus_size_t dm_mapsize; /* size of the mapping */
642 int dm_nsegs; /* # valid segments in mapping */
643 bus_dma_segment_t dm_segs[1]; /* segments; variable length */
644 };
645
646 int x68k_bus_dmamap_create(bus_dma_tag_t, bus_size_t, int, bus_size_t,
647 bus_size_t, int, bus_dmamap_t *);
648 void x68k_bus_dmamap_destroy(bus_dma_tag_t, bus_dmamap_t);
649 int x68k_bus_dmamap_load(bus_dma_tag_t, bus_dmamap_t, void *,
650 bus_size_t, struct proc *, int);
651 int x68k_bus_dmamap_load_mbuf(bus_dma_tag_t, bus_dmamap_t,
652 struct mbuf *, int);
653 int x68k_bus_dmamap_load_uio(bus_dma_tag_t, bus_dmamap_t,
654 struct uio *, int);
655 int x68k_bus_dmamap_load_raw(bus_dma_tag_t, bus_dmamap_t,
656 bus_dma_segment_t *, int, bus_size_t, int);
657 void x68k_bus_dmamap_unload(bus_dma_tag_t, bus_dmamap_t);
658 void x68k_bus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t, bus_addr_t,
659 bus_size_t, int);
660
661 int x68k_bus_dmamem_alloc(bus_dma_tag_t tag, bus_size_t size,
662 bus_size_t alignment, bus_size_t boundary,
663 bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags);
664 void x68k_bus_dmamem_free(bus_dma_tag_t tag, bus_dma_segment_t *segs,
665 int nsegs);
666 int x68k_bus_dmamem_map(bus_dma_tag_t tag, bus_dma_segment_t *segs,
667 int nsegs, size_t size, void **kvap, int flags);
668 void x68k_bus_dmamem_unmap(bus_dma_tag_t tag, void *kva,
669 size_t size);
670 paddr_t x68k_bus_dmamem_mmap(bus_dma_tag_t tag, bus_dma_segment_t *segs,
671 int nsegs, off_t off, int prot, int flags);
672
673 int x68k_bus_dmamap_load_buffer(bus_dmamap_t, void *,
674 bus_size_t buflen, struct proc *, int, paddr_t *, int *, int);
675 int x68k_bus_dmamem_alloc_range(bus_dma_tag_t tag, bus_size_t size,
676 bus_size_t alignment, bus_size_t boundary,
677 bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags,
678 paddr_t low, paddr_t high);
679
680 #define bus_dmamap_create(t,s,n,m,b,f,p) \
681 ((*((t)->x68k_dmamap_create)) ((t),(s),(n),(m),(b),(f),(p)))
682 #define bus_dmamap_destroy(t,p) \
683 ((*((t)->x68k_dmamap_destroy)) ((t),(p)))
684 #define bus_dmamap_load(t,m,b,s,p,f) \
685 ((*((t)->x68k_dmamap_load)) ((t),(m),(b),(s),(p),(f)))
686 #define bus_dmamap_load_mbuf(t,m,b,f) \
687 ((*((t)->x68k_dmamap_load_mbuf)) ((t),(m),(b),(f)))
688 #define bus_dmamap_load_uio(t,m,u,f) \
689 ((*((t)->x68k_dmamap_load_uio)) ((t),(m),(u),(f)))
690 #define bus_dmamap_load_raw(t,m,sg,n,s,f) \
691 ((*((t)->x68k_dmamap_load_raw)) ((t),(m),(sg),(n),(s),(f)))
692 #define bus_dmamap_unload(t,p) \
693 ((*((t)->x68k_dmamap_unload)) ((t),(p)))
694 #define bus_dmamap_sync(t,p,o,l,ops) \
695 ((*((t)->x68k_dmamap_sync)) ((t),(p),(o),(l),(ops)))
696
697 #define bus_dmamem_alloc(t,s,a,b,sg,n,r,f) \
698 ((*((t)->x68k_dmamem_alloc)) ((t),(s),(a),(b),(sg),(n),(r),(f)))
699 #define bus_dmamem_free(t,sg,n) \
700 ((*((t)->x68k_dmamem_free)) ((t),(sg),(n)))
701 #define bus_dmamem_map(t,sg,n,s,k,f) \
702 ((*((t)->x68k_dmamem_map)) ((t),(sg),(n),(s),(k),(f)))
703 #define bus_dmamem_unmap(t,k,s) \
704 ((*((t)->x68k_dmamem_unmap)) ((t),(k),(s)))
705 #define bus_dmamem_mmap(t,sg,n,o,p,f) \
706 ((*((t)->x68k_dmamem_mmap)) ((t),(sg),(n),(o),(p),(f)))
707
708 #define bus_dmatag_subregion(t, mna, mxa, nt, f) EOPNOTSUPP
709 #define bus_dmatag_destroy(t)
710
711 /*
712 * Flags used in various bus DMA methods.
713 */
714 #define BUS_DMA_WAITOK 0x000 /* safe to sleep (pseudo-flag) */
715 #define BUS_DMA_NOWAIT 0x001 /* not safe to sleep */
716 #define BUS_DMA_ALLOCNOW 0x002 /* perform resource allocation now */
717 #define BUS_DMA_COHERENT 0x004 /* hint: map memory DMA coherent */
718 #define BUS_DMA_STREAMING 0x008 /* hint: sequential, unidirectional */
719 #define BUS_DMA_BUS1 0x010 /* placeholders for bus functions... */
720 #define BUS_DMA_BUS2 0x020
721 #define BUS_DMA_BUS3 0x040
722 #define BUS_DMA_BUS4 0x080
723 #define BUS_DMA_READ 0x100 /* mapping is device -> memory only */
724 #define BUS_DMA_WRITE 0x200 /* mapping is memory -> device only */
725 #define BUS_DMA_NOCACHE 0x400 /* hint: map non-cached memory */
726
727 /*
728 * Operations performed by bus_dmamap_sync().
729 */
730 #define BUS_DMASYNC_PREREAD 0x01 /* pre-read synchronization */
731 #define BUS_DMASYNC_POSTREAD 0x02 /* post-read synchronization */
732 #define BUS_DMASYNC_PREWRITE 0x04 /* pre-write synchronization */
733 #define BUS_DMASYNC_POSTWRITE 0x08 /* post-write synchronization */
734
735 #endif /* _X68K_BUS_H_ */
736