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