bus.h revision 1.18 1 /* $NetBSD: bus.h,v 1.18 2023/01/27 19:49:21 tsutsui 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 #define PRIxBUSADDR "lx"
74 #define PRIxBUSSIZE "lx"
75 #define PRIuBUSSIZE "lu"
76
77 /*
78 * Access methods for bus resources and address space.
79 */
80 typedef int bus_space_tag_t;
81 typedef u_long bus_space_handle_t;
82
83 #define PRIxBSH "lx"
84
85 /*
86 * int bus_space_map(bus_space_tag_t t, bus_addr_t addr,
87 * bus_size_t size, int flags, bus_space_handle_t *bshp);
88 *
89 * Map a region of bus space.
90 */
91
92 #define BUS_SPACE_MAP_CACHEABLE 0x01
93 #define BUS_SPACE_MAP_LINEAR 0x02
94 #define BUS_SPACE_MAP_PREFETCHABLE 0x04
95
96 int bus_space_map(bus_space_tag_t, bus_addr_t, bus_size_t,
97 int, bus_space_handle_t *);
98
99 /*
100 * void bus_space_unmap(bus_space_tag_t t,
101 * bus_space_handle_t bsh, bus_size_t size);
102 *
103 * Unmap a region of bus space.
104 */
105
106 void bus_space_unmap(bus_space_tag_t, bus_space_handle_t, bus_size_t);
107
108 /*
109 * int bus_space_subregion(bus_space_tag_t t,
110 * bus_space_handle_t bsh, bus_size_t offset, bus_size_t size,
111 * bus_space_handle_t *nbshp);
112 *
113 * Get a new handle for a subregion of an already-mapped area of bus space.
114 */
115
116 int bus_space_subregion(bus_space_tag_t t, bus_space_handle_t bsh,
117 bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp);
118
119 /*
120 * int bus_space_alloc(bus_space_tag_t t, bus_addr_t, rstart,
121 * bus_addr_t rend, bus_size_t size, bus_size_t align,
122 * bus_size_t boundary, int flags, bus_addr_t *addrp,
123 * bus_space_handle_t *bshp);
124 *
125 * Allocate a region of bus space.
126 */
127
128 int bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart,
129 bus_addr_t rend, bus_size_t size, bus_size_t align,
130 bus_size_t boundary, int cacheable, bus_addr_t *addrp,
131 bus_space_handle_t *bshp);
132
133 /*
134 * int bus_space_free(bus_space_tag_t t,
135 * bus_space_handle_t bsh, bus_size_t size);
136 *
137 * Free a region of bus space.
138 */
139
140 void bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh,
141 bus_size_t size);
142
143 /*
144 * u_intN_t bus_space_read_N(bus_space_tag_t tag,
145 * bus_space_handle_t bsh, bus_size_t offset);
146 *
147 * Read a 1, 2, 4, or 8 byte quantity from bus space
148 * described by tag/handle/offset.
149 */
150
151 #define bus_space_read_1(t, h, o) \
152 ((void) t, (*(volatile u_int8_t *)((h) + (o)*4)))
153
154 #define bus_space_read_2(t, h, o) \
155 ((void) t, (*(volatile u_int16_t *)((h) + (o)*2)))
156
157 #define bus_space_read_4(t, h, o) \
158 ((void) t, (*(volatile u_int32_t *)((h) + (o))))
159
160 /*
161 * void bus_space_read_multi_N(bus_space_tag_t tag,
162 * bus_space_handle_t bsh, bus_size_t offset,
163 * u_intN_t *addr, size_t count);
164 *
165 * Read `count' 1, 2, 4, or 8 byte quantities from bus space
166 * described by tag/handle/offset and copy into buffer provided.
167 */
168
169 #define bus_space_read_multi_1(t, h, o, a, c) do { \
170 (void) t; \
171 __asm volatile (" \
172 movl %0,%%a0 ; \
173 movl %1,%%a1 ; \
174 movl %2,%%d0 ; \
175 1: movb %%a0@,%%a1@+ ; \
176 subql #1,%%d0 ; \
177 jne 1b" : \
178 : \
179 "r" ((h) + (o)*4), "g" (a), "g" ((size_t)(c)) : \
180 "a0","a1","d0","memory"); \
181 } while (0)
182
183 #define bus_space_read_multi_2(t, h, o, a, c) do { \
184 (void) t; \
185 __asm volatile (" \
186 movl %0,%%a0 ; \
187 movl %1,%%a1 ; \
188 movl %2,%%d0 ; \
189 1: movw %%a0@,%%a1@+ ; \
190 subql #1,%%d0 ; \
191 jne 1b" : \
192 : \
193 "r" ((h) + (o)*2), "g" (a), "g" ((size_t)(c)) : \
194 "a0","a1","d0","memory"); \
195 } while (0)
196
197 #define bus_space_read_multi_4(t, h, o, a, c) do { \
198 (void) t; \
199 __asm volatile (" \
200 movl %0,%%a0 ; \
201 movl %1,%%a1 ; \
202 movl %2,%%d0 ; \
203 1: movl %%a0@,%%a1@+ ; \
204 subql #1,%%d0 ; \
205 jne 1b" : \
206 : \
207 "r" ((h) + (o)), "g" (a), "g" ((size_t)(c)) : \
208 "a0","a1","d0","memory"); \
209 } while (0)
210
211 /*
212 * void bus_space_read_region_N(bus_space_tag_t tag,
213 * bus_space_handle_t bsh, bus_size_t offset,
214 * u_intN_t *addr, size_t count);
215 *
216 * Read `count' 1, 2, 4, or 8 byte quantities from bus space
217 * described by tag/handle and starting at `offset' and copy into
218 * buffer provided.
219 */
220
221 #define bus_space_read_region_1(t, h, o, a, c) do { \
222 (void) t; \
223 __asm volatile (" \
224 movl %0,%%a0 ; \
225 movl %1,%%a1 ; \
226 movl %2,%%d0 ; \
227 1: movb %%a0@,%%a1@+ ; \
228 addql #4,%%a0 ; \
229 subql #1,%%d0 ; \
230 jne 1b" : \
231 : \
232 "r" ((h) + (o)*4), "g" (a), "g" ((size_t)(c)) : \
233 "a0","a1","d0","memory"); \
234 } while (0)
235
236 #define bus_space_read_region_2(t, h, o, a, c) do { \
237 (void) t; \
238 __asm volatile (" \
239 movl %0,%%a0 ; \
240 movl %1,%%a1 ; \
241 movl %2,%%d0 ; \
242 1: movw %%a0@,%%a1@+ ; \
243 addql #4,%%a0 ; \
244 subql #1,%%d0 ; \
245 jne 1b" : \
246 : \
247 "r" ((h) + (o)*2), "g" (a), "g" ((size_t)(c)) : \
248 "a0","a1","d0","memory"); \
249 } while (0)
250
251 #define bus_space_read_region_4(t, h, o, a, c) do { \
252 (void) t; \
253 __asm volatile (" \
254 movl %0,%%a0 ; \
255 movl %1,%%a1 ; \
256 movl %2,%%d0 ; \
257 1: movl %%a0@+,%%a1@+ ; \
258 subql #1,%%d0 ; \
259 jne 1b" : \
260 : \
261 "r" ((h) + (o)), "g" (a), "g" ((size_t)(c)) : \
262 "a0","a1","d0","memory"); \
263 } while (0)
264
265 /*
266 * void bus_space_write_N(bus_space_tag_t tag,
267 * bus_space_handle_t bsh, bus_size_t offset,
268 * u_intN_t value);
269 *
270 * Write the 1, 2, 4, or 8 byte value `value' to bus space
271 * described by tag/handle/offset.
272 */
273
274 #define bus_space_write_1(t, h, o, v) \
275 ((void) t, ((void)(*(volatile u_int8_t *)((h) + (o)*4) = (v))))
276
277 #define bus_space_write_2(t, h, o, v) \
278 ((void) t, ((void)(*(volatile u_int16_t *)((h) + (o)*2) = (v))))
279
280 #define bus_space_write_4(t, h, o, v) \
281 ((void) t, ((void)(*(volatile u_int32_t *)((h) + (o)) = (v))))
282
283 /*
284 * void bus_space_write_multi_N(bus_space_tag_t tag,
285 * bus_space_handle_t bsh, bus_size_t offset,
286 * const u_intN_t *addr, size_t count);
287 *
288 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
289 * provided to bus space described by tag/handle/offset.
290 */
291
292 #define bus_space_write_multi_1(t, h, o, a, c) do { \
293 (void) t; \
294 __asm volatile (" \
295 movl %0,%%a0 ; \
296 movl %1,%%a1 ; \
297 movl %2,%%d0 ; \
298 1: movb %%a1@+,%%a0@ ; \
299 subql #1,%%d0 ; \
300 jne 1b" : \
301 : \
302 "r" ((h) + (o)*4), "g" (a), "g" ((size_t)(c)) : \
303 "a0","a1","d0"); \
304 } while (0)
305
306 #define bus_space_write_multi_2(t, h, o, a, c) do { \
307 (void) t; \
308 __asm volatile (" \
309 movl %0,%%a0 ; \
310 movl %1,%%a1 ; \
311 movl %2,%%d0 ; \
312 1: movw %%a1@+,%%a0@ ; \
313 subql #1,%%d0 ; \
314 jne 1b" : \
315 : \
316 "r" ((h) + (o)*2), "g" (a), "g" ((size_t)(c)) : \
317 "a0","a1","d0"); \
318 } while (0)
319
320 #define bus_space_write_multi_4(t, h, o, a, c) do { \
321 (void) t; \
322 __asm volatile (" \
323 movl %0,%%a0 ; \
324 movl %1,%%a1 ; \
325 movl %2,%%d0 ; \
326 1: movl %%a1@+,%%a0@ ; \
327 subql #1,%%d0 ; \
328 jne 1b" : \
329 : \
330 "r" ((h) + (o)), "g" (a), "g" ((size_t)(c)) : \
331 "a0","a1","d0"); \
332 } while (0)
333
334 /*
335 * void bus_space_write_region_N(bus_space_tag_t tag,
336 * bus_space_handle_t bsh, bus_size_t offset,
337 * const u_intN_t *addr, size_t count);
338 *
339 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
340 * to bus space described by tag/handle starting at `offset'.
341 */
342
343 #define bus_space_write_region_1(t, h, o, a, c) do { \
344 (void) t; \
345 __asm volatile (" \
346 movl %0,%%a0 ; \
347 movl %1,%%a1 ; \
348 movl %2,%%d0 ; \
349 1: movb %%a1@+,%%a0@ ; \
350 addql #4,%%a0 ; \
351 subql #1,%%d0 ; \
352 jne 1b" : \
353 : \
354 "r" ((h) + (o)*4), "g" (a), "g" ((size_t)(c)) : \
355 "a0","a1","d0"); \
356 } while (0)
357
358 #define bus_space_write_region_2(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: movw %%a1@+,%%a0@ ; \
365 addql #4,%%a0 ; \
366 subql #1,%%d0 ; \
367 jne 1b" : \
368 : \
369 "r" ((h) + (o)*2), "g" (a), "g" ((size_t)(c)) : \
370 "a0","a1","d0"); \
371 } while (0)
372
373 #define bus_space_write_region_4(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: movl %%a1@+,%%a0@+ ; \
380 subql #1,%%d0 ; \
381 jne 1b" : \
382 : \
383 "r" ((h) + (o)), "g" (a), "g" ((size_t)(c)) : \
384 "a0","a1","d0"); \
385 } while (0)
386
387 /*
388 * void bus_space_set_multi_N(bus_space_tag_t tag,
389 * bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
390 * size_t count);
391 *
392 * Write the 1, 2, 4, or 8 byte value `val' to bus space described
393 * by tag/handle/offset `count' times.
394 */
395
396 #define bus_space_set_multi_1(t, h, o, val, c) do { \
397 (void) t; \
398 __asm volatile (" \
399 movl %0,%%a0 ; \
400 movl %1,%%d1 ; \
401 movl %2,%%d0 ; \
402 1: movb %%d1,%%a0@ ; \
403 subql #1,%%d0 ; \
404 jne 1b" : \
405 : \
406 "r" ((h)+(o)*4), "g" ((u_long)val), \
407 "g" ((size_t)(c)) : \
408 "a0","d0","d1"); \
409 } while (0)
410
411 #define bus_space_set_multi_2(t, h, o, val, c) do { \
412 (void) t; \
413 __asm volatile (" \
414 movl %0,%%a0 ; \
415 movl %1,%%d1 ; \
416 movl %2,%%d0 ; \
417 1: movw %%d1,%%a0@ ; \
418 subql #1,%%d0 ; \
419 jne 1b" : \
420 : \
421 "r" ((h)+(o)*2), "g" ((u_long)val), \
422 "g" ((size_t)(c)) : \
423 "a0","d0","d1"); \
424 } while (0)
425
426 #define bus_space_set_multi_4(t, h, o, val, c) do { \
427 (void) t; \
428 __asm volatile (" \
429 movl %0,%%a0 ; \
430 movl %1,%%d1 ; \
431 movl %2,%%d0 ; \
432 1: movl %%d1,%%a0@ ; \
433 subql #1,%%d0 ; \
434 jne 1b" : \
435 : \
436 "r" ((h)+(o)), "g" ((u_long)val), \
437 "g" ((size_t)(c)) : \
438 "a0","d0","d1"); \
439 } while (0)
440
441 /*
442 * void bus_space_set_region_N(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 addql #4,%%a0 ; \
458 subql #1,%%d0 ; \
459 jne 1b" : \
460 : \
461 "r" ((h)+(o)*4), "g" ((u_long)val), \
462 "g" ((size_t)(c)) : \
463 "a0","d0","d1"); \
464 } while (0)
465
466 #define bus_space_set_region_2(t, h, o, val, c) do { \
467 (void) t; \
468 __asm volatile (" \
469 movl %0,%%a0 ; \
470 movl %1,%%d1 ; \
471 movl %2,%%d0 ; \
472 1: movw %%d1,%%a0@ ; \
473 addql #4,%%a0 ; \
474 subql #1,%%d0 ; \
475 jne 1b" : \
476 : \
477 "r" ((h)+(o)*2), "g" ((u_long)val), \
478 "g" ((size_t)(c)) : \
479 "a0","d0","d1"); \
480 } while (0)
481
482 #define bus_space_set_region_4(t, h, o, val, c) do { \
483 (void) t; \
484 __asm volatile (" \
485 movl %0,%%a0 ; \
486 movl %1,%%d1 ; \
487 movl %2,%%d0 ; \
488 1: movl %%d1,%%a0@+ ; \
489 subql #1,%%d0 ; \
490 jne 1b" : \
491 : \
492 "r" ((h)+(o)), "g" ((u_long)val), \
493 "g" ((size_t)(c)) : \
494 "a0","d0","d1"); \
495 } while (0)
496
497 /*
498 * void bus_space_copy_N(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 __MACHINE_copy_region_N(BYTES) \
508 static __inline void __CONCAT(bus_space_copy_region_,BYTES) \
509 (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)( \
516 bus_space_tag_t t, \
517 bus_space_handle_t h1, \
518 bus_size_t o1, \
519 bus_space_handle_t h2, \
520 bus_size_t o2, \
521 bus_size_t c) \
522 { \
523 bus_size_t o; \
524 \
525 if ((h1 + o1) >= (h2 + o2)) { \
526 /* src after dest: copy forward */ \
527 for (o = 0; 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 } else { \
531 /* dest after src: copy backwards */ \
532 for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES) \
533 __CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o, \
534 __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \
535 } \
536 }
537 __MACHINE_copy_region_N(1)
538 __MACHINE_copy_region_N(2)
539 __MACHINE_copy_region_N(4)
540
541 #undef __MACHINE_copy_region_N
542
543 /*
544 * Bus read/write barrier methods.
545 *
546 * void bus_space_barrier(bus_space_tag_t tag,
547 * bus_space_handle_t bsh, bus_size_t offset,
548 * bus_size_t len, int flags);
549 *
550 * Note: the 680x0 does not currently require barriers, but we must
551 * provide the flags to MI code.
552 */
553 #define bus_space_barrier(t, h, o, l, f) \
554 ((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f)))
555 #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */
556 #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */
557
558 #define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t)
559
560 /*
561 * There is no bus_dma(9)'fied bus drivers on this port.
562 */
563 #define __HAVE_NO_BUS_DMA
564
565 #endif /* _MACHINE_BUS_H_ */
566