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