bus_space.h revision 1.2 1 /* $NetBSD: bus_space.h,v 1.2 1999/02/14 17:54:29 scw Exp $ */
2
3 /*-
4 * Copyright (c) 1996, 1997, 1998 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 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the NetBSD
22 * Foundation, Inc. and its contributors.
23 * 4. Neither the name of The NetBSD Foundation nor the names of its
24 * contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
38 */
39
40 /*
41 * Copyright (C) 1997 Scott Reynolds. All rights reserved.
42 *
43 * Redistribution and use in source and binary forms, with or without
44 * modification, are permitted provided that the following conditions
45 * are met:
46 * 1. Redistributions of source code must retain the above copyright
47 * notice, this list of conditions and the following disclaimer.
48 * 2. Redistributions in binary form must reproduce the above copyright
49 * notice, this list of conditions and the following disclaimer in the
50 * documentation and/or other materials provided with the distribution.
51 * 3. The name of the author may not be used to endorse or promote products
52 * derived from this software without specific prior written permission
53 *
54 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
55 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
56 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
57 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
58 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
59 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
60 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
61 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
62 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
63 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64 */
65
66 /*
67 * Lifted from the Next68k port.
68 * Modified for mvme68k by Steve Woodford.
69 *
70 * TODO: Support for VMEbus...
71 * (Do any existing VME card drivers use bus_space_* ?)
72 */
73
74 #ifndef _MVME68K_BUS_SPACE_H_
75 #define _MVME68K_BUS_SPACE_H_
76 /*
77 * Addresses (in bus space).
78 */
79 typedef u_long bus_addr_t;
80 typedef u_long bus_size_t;
81
82 /*
83 * Access methods for bus resources and address space.
84 */
85 typedef volatile char * bus_space_tag_t;
86 typedef u_long bus_space_handle_t;
87
88 /*
89 * Value for the mvme68k bus space tag, not to be used directly by MI code.
90 */
91 #define MVME68K_INTIO_BUS_SPACE intiobase
92
93 /*
94 * Mapping and unmapping operations.
95 */
96 #define bus_space_map(t, a, s, f, hp) \
97 ((((a) >= intiobase_phys) && (((a) + (s)) < intiotop_phys)) ? \
98 ((*(hp) = (bus_space_handle_t)((t) + ((a) - intiobase_phys))),0) : \
99 (-1))
100
101 #define bus_space_unmap(t, h, s)
102
103 #define bus_space_subregion(t, h, o, s, hp) \
104 (*(hp)=(h)+(o))
105
106 #define BUS_SPACE_MAP_CACHEABLE 0x01
107 #define BUS_SPACE_MAP_LINEAR 0x02
108
109 /*
110 * Allocation and deallocation operations.
111 */
112 #define bus_space_alloc(t, rs, re, s, a, b, f, ap, hp) \
113 (-1)
114
115 #define bus_space_free(t, h, s)
116
117 /*
118 * u_intN_t bus_space_read_N __P((bus_space_tag_t tag,
119 * bus_space_handle_t bsh, bus_size_t offset));
120 *
121 * Read a 1, 2, 4, or 8 byte quantity from bus space
122 * described by tag/handle/offset.
123 */
124
125 #define bus_space_read_1(t, h, o) \
126 ((void) t, (*(volatile u_int8_t *)((h) + (o))))
127
128 #define bus_space_read_2(t, h, o) \
129 ((void) t, (*(volatile u_int16_t *)((h) + (o))))
130
131 #define bus_space_read_4(t, h, o) \
132 ((void) t, (*(volatile u_int32_t *)((h) + (o))))
133
134 #if 0 /* Cause a link error for bus_space_read_8 */
135 #define bus_space_read_8(t, h, o) !!! bus_space_read_8 unimplemented !!!
136 #endif
137
138 /*
139 * void bus_space_read_multi_N __P((bus_space_tag_t tag,
140 * bus_space_handle_t bsh, bus_size_t offset,
141 * u_intN_t *addr, size_t count));
142 *
143 * Read `count' 1, 2, 4, or 8 byte quantities from bus space
144 * described by tag/handle/offset and copy into buffer provided.
145 */
146
147 #define bus_space_read_multi_1(t, h, o, a, c) do { \
148 (void) t; \
149 __asm __volatile (" \
150 movl %0,a0 ; \
151 movl %1,a1 ; \
152 movl %2,d0 ; \
153 1: movb a0@,a1@+ ; \
154 subql #1,d0 ; \
155 jne 1b" : \
156 : \
157 "r" ((h) + (o)), "g" (a), "g" (c) : \
158 "a0","a1","d0"); \
159 } while (0);
160
161 #define bus_space_read_multi_2(t, h, o, a, c) do { \
162 (void) t; \
163 __asm __volatile (" \
164 movl %0,a0 ; \
165 movl %1,a1 ; \
166 movl %2,d0 ; \
167 1: movw a0@,a1@+ ; \
168 subql #1,d0 ; \
169 jne 1b" : \
170 : \
171 "r" ((h) + (o)), "g" (a), "g" (c) : \
172 "a0","a1","d0"); \
173 } while (0);
174
175 #define bus_space_read_multi_4(t, h, o, a, c) do { \
176 (void) t; \
177 __asm __volatile (" \
178 movl %0,a0 ; \
179 movl %1,a1 ; \
180 movl %2,d0 ; \
181 1: movl a0@,a1@+ ; \
182 subql #1,d0 ; \
183 jne 1b" : \
184 : \
185 "r" ((h) + (o)), "g" (a), "g" (c) : \
186 "a0","a1","d0"); \
187 } while (0);
188
189 #if 0 /* Cause a link error for bus_space_read_multi_8 */
190 #define bus_space_read_multi_8 !!! bus_space_read_multi_8 unimplemented !!!
191 #endif
192
193 /*
194 * void bus_space_read_region_N __P((bus_space_tag_t tag,
195 * bus_space_handle_t bsh, bus_size_t offset,
196 * u_intN_t *addr, size_t count));
197 *
198 * Read `count' 1, 2, 4, or 8 byte quantities from bus space
199 * described by tag/handle and starting at `offset' and copy into
200 * buffer provided.
201 */
202
203 #define bus_space_read_region_1(t, h, o, a, c) do { \
204 (void) t; \
205 __asm __volatile (" \
206 movl %0,a0 ; \
207 movl %1,a1 ; \
208 movl %2,d0 ; \
209 1: movb a0@+,a1@+ ; \
210 subql #1,d0 ; \
211 jne 1b" : \
212 : \
213 "r" ((h) + (o)), "g" (a), "g" (c) : \
214 "a0","a1","d0"); \
215 } while (0);
216
217 #define bus_space_read_region_2(t, h, o, a, c) do { \
218 (void) t; \
219 __asm __volatile (" \
220 movl %0,a0 ; \
221 movl %1,a1 ; \
222 movl %2,d0 ; \
223 1: movw a0@+,a1@+ ; \
224 subql #1,d0 ; \
225 jne 1b" : \
226 : \
227 "r" ((h) + (o)), "g" (a), "g" (c) : \
228 "a0","a1","d0"); \
229 } while (0);
230
231 #define bus_space_read_region_4(t, h, o, a, c) do { \
232 (void) t; \
233 __asm __volatile (" \
234 movl %0,a0 ; \
235 movl %1,a1 ; \
236 movl %2,d0 ; \
237 1: movl a0@+,a1@+ ; \
238 subql #1,d0 ; \
239 jne 1b" : \
240 : \
241 "r" ((h) + (o)), "g" (a), "g" (c) : \
242 "a0","a1","d0"); \
243 } while (0);
244
245 #if 0 /* Cause a link error for bus_space_read_region_8 */
246 #define bus_space_read_region_8 !!! bus_space_read_region_8 unimplemented !!!
247 #endif
248
249 /*
250 * void bus_space_write_N __P((bus_space_tag_t tag,
251 * bus_space_handle_t bsh, bus_size_t offset,
252 * u_intN_t value));
253 *
254 * Write the 1, 2, 4, or 8 byte value `value' to bus space
255 * described by tag/handle/offset.
256 */
257
258 #define bus_space_write_1(t, h, o, v) \
259 ((void) t, ((void)(*(volatile u_int8_t *)((h) + (o)) = (v))))
260
261 #define bus_space_write_2(t, h, o, v) \
262 ((void) t, ((void)(*(volatile u_int16_t *)((h) + (o)) = (v))))
263
264 #define bus_space_write_4(t, h, o, v) \
265 ((void) t, ((void)(*(volatile u_int32_t *)((h) + (o)) = (v))))
266
267 #if 0 /* Cause a link error for bus_space_write_8 */
268 #define bus_space_write_8 !!! bus_space_write_8 not implemented !!!
269 #endif
270
271 /*
272 * void bus_space_write_multi_N __P((bus_space_tag_t tag,
273 * bus_space_handle_t bsh, bus_size_t offset,
274 * const u_intN_t *addr, size_t count));
275 *
276 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
277 * provided to bus space described by tag/handle/offset.
278 */
279
280 #define bus_space_write_multi_1(t, h, o, a, c) do { \
281 (void) t; \
282 __asm __volatile (" \
283 movl %0,a0 ; \
284 movl %1,a1 ; \
285 movl %2,d0 ; \
286 1: movb a1@+,a0@ ; \
287 subql #1,d0 ; \
288 jne 1b" : \
289 : \
290 "r" ((h) + (o)), "g" (a), "g" (c) : \
291 "a0","a1","d0"); \
292 } while (0);
293
294 #define bus_space_write_multi_2(t, h, o, a, c) do { \
295 (void) t; \
296 __asm __volatile (" \
297 movl %0,a0 ; \
298 movl %1,a1 ; \
299 movl %2,d0 ; \
300 1: movw a1@+,a0@ ; \
301 subql #1,d0 ; \
302 jne 1b" : \
303 : \
304 "r" ((h) + (o)), "g" (a), "g" (c) : \
305 "a0","a1","d0"); \
306 } while (0);
307
308 #define bus_space_write_multi_4(t, h, o, a, c) do { \
309 (void) t; \
310 __asm __volatile (" \
311 movl %0,a0 ; \
312 movl %1,a1 ; \
313 movl %2,d0 ; \
314 1: movl a1@+,a0@ ; \
315 subql #1,d0 ; \
316 jne 1b" : \
317 : \
318 "r" ((h) + (o)), "g" (a), "g" (c) : \
319 "a0","a1","d0"); \
320 } while (0);
321
322 #if 0 /* Cause a link error for bus_space_write_8 */
323 #define bus_space_write_multi_8(t, h, o, a, c) \
324 !!! bus_space_write_multi_8 unimplimented !!!
325 #endif
326
327 /*
328 * void bus_space_write_region_N __P((bus_space_tag_t tag,
329 * bus_space_handle_t bsh, bus_size_t offset,
330 * const u_intN_t *addr, size_t count));
331 *
332 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
333 * to bus space described by tag/handle starting at `offset'.
334 */
335
336 #define bus_space_write_region_1(t, h, o, a, c) do { \
337 (void) t; \
338 __asm __volatile (" \
339 movl %0,a0 ; \
340 movl %1,a1 ; \
341 movl %2,d0 ; \
342 1: movb a1@+,a0@+ ; \
343 subql #1,d0 ; \
344 jne 1b" : \
345 : \
346 "r" ((h) + (o)), "g" (a), "g" (c) : \
347 "a0","a1","d0"); \
348 } while (0);
349
350 #define bus_space_write_region_2(t, h, o, a, c) do { \
351 (void) t; \
352 __asm __volatile (" \
353 movl %0,a0 ; \
354 movl %1,a1 ; \
355 movl %2,d0 ; \
356 1: movw a1@+,a0@+ ; \
357 subql #1,d0 ; \
358 jne 1b" : \
359 : \
360 "r" ((h) + (o)), "g" (a), "g" (c) : \
361 "a0","a1","d0"); \
362 } while (0);
363
364 #define bus_space_write_region_4(t, h, o, a, c) do { \
365 (void) t; \
366 __asm __volatile (" \
367 movl %0,a0 ; \
368 movl %1,a1 ; \
369 movl %2,d0 ; \
370 1: movl a1@+,a0@+ ; \
371 subql #1,d0 ; \
372 jne 1b" : \
373 : \
374 "r" ((h) + (o)), "g" (a), "g" (c) : \
375 "a0","a1","d0"); \
376 } while (0);
377
378 #if 0 /* Cause a link error for bus_space_write_region_8 */
379 #define bus_space_write_region_8 \
380 !!! bus_space_write_region_8 unimplemented !!!
381 #endif
382
383 /*
384 * void bus_space_set_multi_N __P((bus_space_tag_t tag,
385 * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
386 * size_t count));
387 *
388 * Write the 1, 2, 4, or 8 byte value `val' to bus space described
389 * by tag/handle/offset `count' times.
390 */
391
392 #define bus_space_set_multi_1(t, h, o, val, c) do { \
393 (void) t; \
394 __asm __volatile (" \
395 movl %0,a0 ; \
396 movl %1,d1 ; \
397 movl %2,d0 ; \
398 1: movb d1,a0@ ; \
399 subql #1,d0 ; \
400 jne 1b" : \
401 : \
402 "r" ((h) + (o)), "g" (val), "g" (c) : \
403 "a0","d0","d1"); \
404 } while (0);
405
406 #define bus_space_set_multi_2(t, h, o, val, c) do { \
407 (void) t; \
408 __asm __volatile (" \
409 movl %0,a0 ; \
410 movl %1,d1 ; \
411 movl %2,d0 ; \
412 1: movw d1,a0@ ; \
413 subql #1,d0 ; \
414 jne 1b" : \
415 : \
416 "r" ((h) + (o)), "g" (val), "g" (c) : \
417 "a0","d0","d1"); \
418 } while (0);
419
420 #define bus_space_set_multi_4(t, h, o, val, c) do { \
421 (void) t; \
422 __asm __volatile (" \
423 movl %0,a0 ; \
424 movl %1,d1 ; \
425 movl %2,d0 ; \
426 1: movl d1,a0@ ; \
427 subql #1,d0 ; \
428 jne 1b" : \
429 : \
430 "r" ((h) + (o)), "g" (val), "g" (c) : \
431 "a0","d0","d1"); \
432 } while (0);
433
434 #if 0 /* Cause a link error for bus_space_set_multi_8 */
435 #define bus_space_set_multi_8 \
436 !!! bus_space_set_multi_8 unimplemented !!!
437 #endif
438
439 /*
440 * void bus_space_set_region_N __P((bus_space_tag_t tag,
441 * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
442 * size_t count));
443 *
444 * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
445 * by tag/handle starting at `offset'.
446 */
447
448 #define bus_space_set_region_1(t, h, o, val, c) do { \
449 (void) t; \
450 __asm __volatile (" \
451 movl %0,a0 ; \
452 movl %1,d1 ; \
453 movl %2,d0 ; \
454 1: movb d1,a0@+ ; \
455 subql #1,d0 ; \
456 jne 1b" : \
457 : \
458 "r" ((h) + (o)), "g" (val), "g" (c) : \
459 "a0","d0","d1"); \
460 } while (0);
461
462 #define bus_space_set_region_2(t, h, o, val, c) do { \
463 (void) t; \
464 __asm __volatile (" \
465 movl %0,a0 ; \
466 movl %1,d1 ; \
467 movl %2,d0 ; \
468 1: movw d1,a0@+ ; \
469 subql #1,d0 ; \
470 jne 1b" : \
471 : \
472 "r" ((h) + (o)), "g" (val), "g" (c) : \
473 "a0","d0","d1"); \
474 } while (0);
475
476 #define bus_space_set_region_4(t, h, o, val, c) do { \
477 (void) t; \
478 __asm __volatile (" \
479 movl %0,a0 ; \
480 movl %1,d1 ; \
481 movl %2,d0 ; \
482 1: movl d1,a0@+ ; \
483 subql #1,d0 ; \
484 jne 1b" : \
485 : \
486 "r" ((h) + (o)), "g" (val), "g" (c) : \
487 "a0","d0","d1"); \
488 } while (0);
489
490 #if 0 /* Cause a link error for bus_space_set_region_8 */
491 #define bus_space_set_region_8 \
492 !!! bus_space_set_region_8 unimplemented !!!
493 #endif
494
495 /*
496 * void bus_space_copy_N __P((bus_space_tag_t tag,
497 * bus_space_handle_t bsh1, bus_size_t off1,
498 * bus_space_handle_t bsh2, bus_size_t off2,
499 * size_t count));
500 *
501 * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
502 * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
503 */
504
505 #define __MVME68K_copy_region_N(BYTES) \
506 static __inline void __CONCAT(bus_space_copy_region_,BYTES) \
507 __P((bus_space_tag_t, \
508 bus_space_handle_t bsh1, bus_size_t off1, \
509 bus_space_handle_t bsh2, bus_size_t off2, \
510 bus_size_t count)); \
511 \
512 static __inline void \
513 __CONCAT(bus_space_copy_region_,BYTES)(t, h1, o1, h2, o2, c) \
514 bus_space_tag_t t; \
515 bus_space_handle_t h1, h2; \
516 bus_size_t o1, o2, c; \
517 { \
518 bus_size_t o; \
519 \
520 if ((h1 + o1) >= (h2 + o2)) { \
521 /* src after dest: copy forward */ \
522 for (o = 0; c != 0; c--, o += BYTES) \
523 __CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o, \
524 __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \
525 } else { \
526 /* dest after src: copy backwards */ \
527 for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES) \
528 __CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o, \
529 __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \
530 } \
531 }
532 __MVME68K_copy_region_N(1)
533 __MVME68K_copy_region_N(2)
534 __MVME68K_copy_region_N(4)
535 #if 0 /* Cause a link error for bus_space_copy_8 */
536 #define bus_space_copy_8 \
537 !!! bus_space_copy_8 unimplemented !!!
538 #endif
539
540 #undef __MVME68K_copy_region_N
541
542 /*
543 * Bus read/write barrier methods.
544 *
545 * void bus_space_barrier __P((bus_space_tag_t tag,
546 * bus_space_handle_t bsh, bus_size_t offset,
547 * bus_size_t len, int flags));
548 *
549 * Note: the 680x0 does not currently require barriers, but we must
550 * provide the flags to MI code.
551 */
552 #define bus_space_barrier(t, h, o, l, f) \
553 ((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f)))
554 #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */
555 #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */
556
557 #endif /* _MVME68K_BUS_SPACE_H_ */
558