bus_space.h revision 1.3 1 /* $NetBSD: bus_space.h,v 1.3 1999/01/02 13:42:17 dbj 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 #ifndef _NEXT68K_BUS_SPACE_H_
67 #define _NEXT68K_BUS_SPACE_H_
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 resources and address space.
76 */
77 typedef volatile char * bus_space_tag_t;
78 typedef u_long bus_space_handle_t;
79
80 /*
81 * Value for the next68k bus space tag, not to be used directly by MI code.
82 */
83 #define NEXT68K_INTIO_BUS_SPACE intiobase
84
85 /*
86 * Value for the next68k video bus space tag, not to be used directly by MI code.
87 */
88 #define NEXT68K_VIDEO_BUS_SPACE videobase
89
90 /*
91 * Mapping and unmapping operations.
92 */
93 #define bus_space_map(t, a, s, f, hp) \
94 ((((a)>=INTIOBASE)&&((a)+(s)<INTIOTOP)) ? \
95 ((*(hp)=(bus_space_handle_t)((t)+((a)-INTIOBASE))),0) : \
96 ((((a)>=VIDEOBASE)&&((a)+(s)<VIDEOTOP)) ? \
97 ((*(hp)=(bus_space_handle_t)((t)+((a)-VIDEOBASE))),0) : \
98 (-1)))
99
100 #define bus_space_unmap(t, h, s)
101
102 #define bus_space_subregion(t, h, o, s, hp) \
103 (*(hp)=(h)+(o))
104
105 #define BUS_SPACE_MAP_CACHEABLE 0x01
106 #define BUS_SPACE_MAP_LINEAR 0x02
107
108 /*
109 * Allocation and deallocation operations.
110 */
111 #define bus_space_alloc(t, rs, re, s, a, b, f, ap, hp) \
112 (-1)
113
114 #define bus_space_free(t, h, s)
115
116 /*
117 * u_intN_t bus_space_read_N __P((bus_space_tag_t tag,
118 * bus_space_handle_t bsh, bus_size_t offset));
119 *
120 * Read a 1, 2, 4, or 8 byte quantity from bus space
121 * described by tag/handle/offset.
122 */
123
124 #define bus_space_read_1(t, h, o) \
125 ((void) t, (*(volatile u_int8_t *)((h) + (o))))
126
127 #define bus_space_read_2(t, h, o) \
128 ((void) t, (*(volatile u_int16_t *)((h) + (o))))
129
130 #define bus_space_read_4(t, h, o) \
131 ((void) t, (*(volatile u_int32_t *)((h) + (o))))
132
133 #if 0 /* Cause a link error for bus_space_read_8 */
134 #define bus_space_read_8(t, h, o) !!! bus_space_read_8 unimplemented !!!
135 #endif
136
137 /*
138 * void bus_space_read_multi_N __P((bus_space_tag_t tag,
139 * bus_space_handle_t bsh, bus_size_t offset,
140 * u_intN_t *addr, size_t count));
141 *
142 * Read `count' 1, 2, 4, or 8 byte quantities from bus space
143 * described by tag/handle/offset and copy into buffer provided.
144 */
145
146 #define bus_space_read_multi_1(t, h, o, a, c) do { \
147 (void) t; \
148 __asm __volatile (" \
149 movl %0,a0 ; \
150 movl %1,a1 ; \
151 movl %2,d0 ; \
152 1: movb a0@,a1@+ ; \
153 subql #1,d0 ; \
154 jne 1b" : \
155 : \
156 "r" ((h) + (o)), "g" (a), "g" (c) : \
157 "a0","a1","d0"); \
158 } while (0);
159
160 #define bus_space_read_multi_2(t, h, o, a, c) do { \
161 (void) t; \
162 __asm __volatile (" \
163 movl %0,a0 ; \
164 movl %1,a1 ; \
165 movl %2,d0 ; \
166 1: movw a0@,a1@+ ; \
167 subql #1,d0 ; \
168 jne 1b" : \
169 : \
170 "r" ((h) + (o)), "g" (a), "g" (c) : \
171 "a0","a1","d0"); \
172 } while (0);
173
174 #define bus_space_read_multi_4(t, h, o, a, c) do { \
175 (void) t; \
176 __asm __volatile (" \
177 movl %0,a0 ; \
178 movl %1,a1 ; \
179 movl %2,d0 ; \
180 1: movl a0@,a1@+ ; \
181 subql #1,d0 ; \
182 jne 1b" : \
183 : \
184 "r" ((h) + (o)), "g" (a), "g" (c) : \
185 "a0","a1","d0"); \
186 } while (0);
187
188 #if 0 /* Cause a link error for bus_space_read_multi_8 */
189 #define bus_space_read_multi_8 !!! bus_space_read_multi_8 unimplemented !!!
190 #endif
191
192 /*
193 * void bus_space_read_region_N __P((bus_space_tag_t tag,
194 * bus_space_handle_t bsh, bus_size_t offset,
195 * u_intN_t *addr, size_t count));
196 *
197 * Read `count' 1, 2, 4, or 8 byte quantities from bus space
198 * described by tag/handle and starting at `offset' and copy into
199 * buffer provided.
200 */
201
202 #define bus_space_read_region_1(t, h, o, a, c) do { \
203 (void) t; \
204 __asm __volatile (" \
205 movl %0,a0 ; \
206 movl %1,a1 ; \
207 movl %2,d0 ; \
208 1: movb a0@+,a1@+ ; \
209 subql #1,d0 ; \
210 jne 1b" : \
211 : \
212 "r" ((h) + (o)), "g" (a), "g" (c) : \
213 "a0","a1","d0"); \
214 } while (0);
215
216 #define bus_space_read_region_2(t, h, o, a, c) do { \
217 (void) t; \
218 __asm __volatile (" \
219 movl %0,a0 ; \
220 movl %1,a1 ; \
221 movl %2,d0 ; \
222 1: movw a0@+,a1@+ ; \
223 subql #1,d0 ; \
224 jne 1b" : \
225 : \
226 "r" ((h) + (o)), "g" (a), "g" (c) : \
227 "a0","a1","d0"); \
228 } while (0);
229
230 #define bus_space_read_region_4(t, h, o, a, c) do { \
231 (void) t; \
232 __asm __volatile (" \
233 movl %0,a0 ; \
234 movl %1,a1 ; \
235 movl %2,d0 ; \
236 1: movl a0@+,a1@+ ; \
237 subql #1,d0 ; \
238 jne 1b" : \
239 : \
240 "r" ((h) + (o)), "g" (a), "g" (c) : \
241 "a0","a1","d0"); \
242 } while (0);
243
244 #if 0 /* Cause a link error for bus_space_read_region_8 */
245 #define bus_space_read_region_8 !!! bus_space_read_region_8 unimplemented !!!
246 #endif
247
248 /*
249 * void bus_space_write_N __P((bus_space_tag_t tag,
250 * bus_space_handle_t bsh, bus_size_t offset,
251 * u_intN_t value));
252 *
253 * Write the 1, 2, 4, or 8 byte value `value' to bus space
254 * described by tag/handle/offset.
255 */
256
257 #define bus_space_write_1(t, h, o, v) \
258 ((void) t, ((void)(*(volatile u_int8_t *)((h) + (o)) = (v))))
259
260 #define bus_space_write_2(t, h, o, v) \
261 ((void) t, ((void)(*(volatile u_int16_t *)((h) + (o)) = (v))))
262
263 #define bus_space_write_4(t, h, o, v) \
264 ((void) t, ((void)(*(volatile u_int32_t *)((h) + (o)) = (v))))
265
266 #if 0 /* Cause a link error for bus_space_write_8 */
267 #define bus_space_write_8 !!! bus_space_write_8 not implemented !!!
268 #endif
269
270 /*
271 * void bus_space_write_multi_N __P((bus_space_tag_t tag,
272 * bus_space_handle_t bsh, bus_size_t offset,
273 * const u_intN_t *addr, size_t count));
274 *
275 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
276 * provided to bus space described by tag/handle/offset.
277 */
278
279 #define bus_space_write_multi_1(t, h, o, a, c) do { \
280 (void) t; \
281 __asm __volatile (" \
282 movl %0,a0 ; \
283 movl %1,a1 ; \
284 movl %2,d0 ; \
285 1: movb a1@+,a0@ ; \
286 subql #1,d0 ; \
287 jne 1b" : \
288 : \
289 "r" ((h) + (o)), "g" (a), "g" (c) : \
290 "a0","a1","d0"); \
291 } while (0);
292
293 #define bus_space_write_multi_2(t, h, o, a, c) do { \
294 (void) t; \
295 __asm __volatile (" \
296 movl %0,a0 ; \
297 movl %1,a1 ; \
298 movl %2,d0 ; \
299 1: movw a1@+,a0@ ; \
300 subql #1,d0 ; \
301 jne 1b" : \
302 : \
303 "r" ((h) + (o)), "g" (a), "g" (c) : \
304 "a0","a1","d0"); \
305 } while (0);
306
307 #define bus_space_write_multi_4(t, h, o, a, c) do { \
308 (void) t; \
309 __asm __volatile (" \
310 movl %0,a0 ; \
311 movl %1,a1 ; \
312 movl %2,d0 ; \
313 1: movl a1@+,a0@ ; \
314 subql #1,d0 ; \
315 jne 1b" : \
316 : \
317 "r" ((h) + (o)), "g" (a), "g" (c) : \
318 "a0","a1","d0"); \
319 } while (0);
320
321 #if 0 /* Cause a link error for bus_space_write_8 */
322 #define bus_space_write_multi_8(t, h, o, a, c) \
323 !!! bus_space_write_multi_8 unimplimented !!!
324 #endif
325
326 /*
327 * void bus_space_write_region_N __P((bus_space_tag_t tag,
328 * bus_space_handle_t bsh, bus_size_t offset,
329 * const u_intN_t *addr, size_t count));
330 *
331 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
332 * to bus space described by tag/handle starting at `offset'.
333 */
334
335 #define bus_space_write_region_1(t, h, o, a, c) do { \
336 (void) t; \
337 __asm __volatile (" \
338 movl %0,a0 ; \
339 movl %1,a1 ; \
340 movl %2,d0 ; \
341 1: movb a1@+,a0@+ ; \
342 subql #1,d0 ; \
343 jne 1b" : \
344 : \
345 "r" ((h) + (o)), "g" (a), "g" (c) : \
346 "a0","a1","d0"); \
347 } while (0);
348
349 #define bus_space_write_region_2(t, h, o, a, c) do { \
350 (void) t; \
351 __asm __volatile (" \
352 movl %0,a0 ; \
353 movl %1,a1 ; \
354 movl %2,d0 ; \
355 1: movw a1@+,a0@+ ; \
356 subql #1,d0 ; \
357 jne 1b" : \
358 : \
359 "r" ((h) + (o)), "g" (a), "g" (c) : \
360 "a0","a1","d0"); \
361 } while (0);
362
363 #define bus_space_write_region_4(t, h, o, a, c) do { \
364 (void) t; \
365 __asm __volatile (" \
366 movl %0,a0 ; \
367 movl %1,a1 ; \
368 movl %2,d0 ; \
369 1: movl a1@+,a0@+ ; \
370 subql #1,d0 ; \
371 jne 1b" : \
372 : \
373 "r" ((h) + (o)), "g" (a), "g" (c) : \
374 "a0","a1","d0"); \
375 } while (0);
376
377 #if 0 /* Cause a link error for bus_space_write_region_8 */
378 #define bus_space_write_region_8 \
379 !!! bus_space_write_region_8 unimplemented !!!
380 #endif
381
382 /*
383 * void bus_space_set_multi_N __P((bus_space_tag_t tag,
384 * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
385 * size_t count));
386 *
387 * Write the 1, 2, 4, or 8 byte value `val' to bus space described
388 * by tag/handle/offset `count' times.
389 */
390
391 #define bus_space_set_multi_1(t, h, o, val, c) do { \
392 (void) t; \
393 __asm __volatile (" \
394 movl %0,a0 ; \
395 movl %1,d1 ; \
396 movl %2,d0 ; \
397 1: movb d1,a0@ ; \
398 subql #1,d0 ; \
399 jne 1b" : \
400 : \
401 "r" ((h) + (o)), "g" (val), "g" (c) : \
402 "a0","d0","d1"); \
403 } while (0);
404
405 #define bus_space_set_multi_2(t, h, o, val, c) do { \
406 (void) t; \
407 __asm __volatile (" \
408 movl %0,a0 ; \
409 movl %1,d1 ; \
410 movl %2,d0 ; \
411 1: movw d1,a0@ ; \
412 subql #1,d0 ; \
413 jne 1b" : \
414 : \
415 "r" ((h) + (o)), "g" (val), "g" (c) : \
416 "a0","d0","d1"); \
417 } while (0);
418
419 #define bus_space_set_multi_4(t, h, o, val, c) do { \
420 (void) t; \
421 __asm __volatile (" \
422 movl %0,a0 ; \
423 movl %1,d1 ; \
424 movl %2,d0 ; \
425 1: movl d1,a0@ ; \
426 subql #1,d0 ; \
427 jne 1b" : \
428 : \
429 "r" ((h) + (o)), "g" (val), "g" (c) : \
430 "a0","d0","d1"); \
431 } while (0);
432
433 #if 0 /* Cause a link error for bus_space_set_multi_8 */
434 #define bus_space_set_multi_8 \
435 !!! bus_space_set_multi_8 unimplemented !!!
436 #endif
437
438 /*
439 * void bus_space_set_region_N __P((bus_space_tag_t tag,
440 * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
441 * size_t count));
442 *
443 * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
444 * by tag/handle starting at `offset'.
445 */
446
447 #define bus_space_set_region_1(t, h, o, val, c) do { \
448 (void) t; \
449 __asm __volatile (" \
450 movl %0,a0 ; \
451 movl %1,d1 ; \
452 movl %2,d0 ; \
453 1: movb d1,a0@+ ; \
454 subql #1,d0 ; \
455 jne 1b" : \
456 : \
457 "r" ((h) + (o)), "g" (val), "g" (c) : \
458 "a0","d0","d1"); \
459 } while (0);
460
461 #define bus_space_set_region_2(t, h, o, val, c) do { \
462 (void) t; \
463 __asm __volatile (" \
464 movl %0,a0 ; \
465 movl %1,d1 ; \
466 movl %2,d0 ; \
467 1: movw d1,a0@+ ; \
468 subql #1,d0 ; \
469 jne 1b" : \
470 : \
471 "r" ((h) + (o)), "g" (val), "g" (c) : \
472 "a0","d0","d1"); \
473 } while (0);
474
475 #define bus_space_set_region_4(t, h, o, val, c) do { \
476 (void) t; \
477 __asm __volatile (" \
478 movl %0,a0 ; \
479 movl %1,d1 ; \
480 movl %2,d0 ; \
481 1: movl d1,a0@+ ; \
482 subql #1,d0 ; \
483 jne 1b" : \
484 : \
485 "r" ((h) + (o)), "g" (val), "g" (c) : \
486 "a0","d0","d1"); \
487 } while (0);
488
489 #if 0 /* Cause a link error for bus_space_set_region_8 */
490 #define bus_space_set_region_8 \
491 !!! bus_space_set_region_8 unimplemented !!!
492 #endif
493
494 /*
495 * void bus_space_copy_N __P((bus_space_tag_t tag,
496 * bus_space_handle_t bsh1, bus_size_t off1,
497 * bus_space_handle_t bsh2, bus_size_t off2,
498 * size_t count));
499 *
500 * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
501 * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
502 */
503
504 #define __NEXT68K_copy_region_N(BYTES) \
505 static __inline void __CONCAT(bus_space_copy_region_,BYTES) \
506 __P((bus_space_tag_t, \
507 bus_space_handle_t bsh1, bus_size_t off1, \
508 bus_space_handle_t bsh2, bus_size_t off2, \
509 bus_size_t count)); \
510 \
511 static __inline void \
512 __CONCAT(bus_space_copy_region_,BYTES)(t, h1, o1, h2, o2, c) \
513 bus_space_tag_t t; \
514 bus_space_handle_t h1, h2; \
515 bus_size_t o1, o2, c; \
516 { \
517 bus_size_t o; \
518 \
519 if ((h1 + o1) >= (h2 + o2)) { \
520 /* src after dest: copy forward */ \
521 for (o = 0; c != 0; c--, o += BYTES) \
522 __CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o, \
523 __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \
524 } else { \
525 /* dest after src: copy backwards */ \
526 for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES) \
527 __CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o, \
528 __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \
529 } \
530 }
531 __NEXT68K_copy_region_N(1)
532 __NEXT68K_copy_region_N(2)
533 __NEXT68K_copy_region_N(4)
534 #if 0 /* Cause a link error for bus_space_copy_8 */
535 #define bus_space_copy_8 \
536 !!! bus_space_copy_8 unimplemented !!!
537 #endif
538
539 #undef __NEXT68K_copy_region_N
540
541 /*
542 * Bus read/write barrier methods.
543 *
544 * void bus_space_barrier __P((bus_space_tag_t tag,
545 * bus_space_handle_t bsh, bus_size_t offset,
546 * bus_size_t len, int flags));
547 *
548 * Note: the 680x0 does not currently require barriers, but we must
549 * provide the flags to MI code.
550 */
551 #define bus_space_barrier(t, h, o, l, f) \
552 ((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f)))
553 #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */
554 #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */
555
556 #endif /* _NEXT68K_BUS_SPACE_H_ */
557