bus.h revision 1.12 1 /* $NetBSD: bus.h,v 1.12 2021/01/23 19:38:08 christos 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 /* bus_space(9) functions for news68k. Just taken from hp300. */
60
61 #ifndef _NEWS68K_BUS_H_
62 #define _NEWS68K_BUS_H_
63
64 /*
65 * Values for the news68k bus space tag, not to be used directly by MI code.
66 */
67 #define NEWS68K_BUS_SPACE_INTIO 0 /* space is intio space */
68 #define NEWS68K_BUS_SPACE_EIO 1 /* space is eio space */
69
70 /*
71 * Bus address and size types
72 */
73 typedef u_long bus_addr_t;
74 typedef u_long bus_size_t;
75
76 #define PRIxBUSADDR "lx"
77 #define PRIxBUSSIZE "lx"
78 #define PRIuBUSSIZE "lu"
79
80 /*
81 * Access methods for bus resources and address space.
82 */
83 typedef int bus_space_tag_t;
84 typedef u_long bus_space_handle_t;
85
86 #define PRIxBSH "lx"
87
88 /*
89 * int bus_space_map(bus_space_tag_t t, bus_addr_t addr,
90 * bus_size_t size, int flags, bus_space_handle_t *bshp);
91 *
92 * Map a region of bus space.
93 */
94
95 #define BUS_SPACE_MAP_CACHEABLE 0x01
96 #define BUS_SPACE_MAP_LINEAR 0x02
97 #define BUS_SPACE_MAP_PREFETCHABLE 0x04
98
99 int bus_space_map(bus_space_tag_t, bus_addr_t, bus_size_t,
100 int, bus_space_handle_t *);
101
102 /*
103 * void bus_space_unmap(bus_space_tag_t t,
104 * bus_space_handle_t bsh, bus_size_t size);
105 *
106 * Unmap a region of bus space.
107 */
108
109 void bus_space_unmap(bus_space_tag_t, bus_space_handle_t, bus_size_t);
110
111 /*
112 * int bus_space_subregion(bus_space_tag_t t,
113 * bus_space_handle_t bsh, bus_size_t offset, bus_size_t size,
114 * bus_space_handle_t *nbshp);
115 *
116 * Get a new handle for a subregion of an already-mapped area of bus space.
117 */
118
119 int bus_space_subregion(bus_space_tag_t t, bus_space_handle_t bsh,
120 bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp);
121
122 /*
123 * int bus_space_alloc(bus_space_tag_t t, bus_addr_t, rstart,
124 * bus_addr_t rend, bus_size_t size, bus_size_t align,
125 * bus_size_t boundary, int flags, bus_addr_t *addrp,
126 * bus_space_handle_t *bshp);
127 *
128 * Allocate a region of bus space.
129 */
130
131 int bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart,
132 bus_addr_t rend, bus_size_t size, bus_size_t align,
133 bus_size_t boundary, int cacheable, bus_addr_t *addrp,
134 bus_space_handle_t *bshp);
135
136 /*
137 * int bus_space_free(bus_space_tag_t t,
138 * bus_space_handle_t bsh, bus_size_t size);
139 *
140 * Free a region of bus space.
141 */
142
143 void bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh,
144 bus_size_t size);
145
146 /*
147 * int news68k_bus_space_probe(bus_space_tag_t t,
148 * bus_space_handle_t bsh, bus_size_t offset, int sz);
149 *
150 * Probe the bus at t/bsh/offset, using sz as the size of the load.
151 *
152 * This is a machine-dependent extension, and is not to be used by
153 * machine-independent code.
154 */
155
156 int news68k_bus_space_probe(bus_space_tag_t t,
157 bus_space_handle_t bsh, bus_size_t offset, int sz);
158
159 /*
160 * uintN_t bus_space_read_N(bus_space_tag_t tag,
161 * bus_space_handle_t bsh, bus_size_t offset);
162 *
163 * Read a 1, 2, 4, or 8 byte quantity from bus space
164 * described by tag/handle/offset.
165 */
166
167 #define bus_space_read_1(t, h, o) \
168 ((void) t, (*(volatile uint8_t *)((h) + (o))))
169
170 #define bus_space_read_2(t, h, o) \
171 ((void) t, (*(volatile uint16_t *)((h) + (o))))
172
173 #define bus_space_read_4(t, h, o) \
174 ((void) t, (*(volatile uint32_t *)((h) + (o))))
175
176 /*
177 * void bus_space_read_multi_N(bus_space_tag_t tag,
178 * bus_space_handle_t bsh, bus_size_t offset,
179 * uintN_t *addr, size_t count);
180 *
181 * Read `count' 1, 2, 4, or 8 byte quantities from bus space
182 * described by tag/handle/offset and copy into buffer provided.
183 */
184
185 #define bus_space_read_multi_1(t, h, o, a, c) do { \
186 (void) t; \
187 __asm volatile (" \
188 movl %0,%%a0 ; \
189 movl %1,%%a1 ; \
190 movl %2,%%d0 ; \
191 1: movb %%a0@,%%a1@+ ; \
192 subql #1,%%d0 ; \
193 jne 1b" : \
194 : \
195 "r" ((h) + (o)), "g" (a), "g" (c) : \
196 "%a0","%a1","%d0"); \
197 } while (0)
198
199 #define bus_space_read_multi_2(t, h, o, a, c) do { \
200 (void) t; \
201 __asm volatile (" \
202 movl %0,%%a0 ; \
203 movl %1,%%a1 ; \
204 movl %2,%%d0 ; \
205 1: movw %%a0@,%%a1@+ ; \
206 subql #1,%%d0 ; \
207 jne 1b" : \
208 : \
209 "r" ((h) + (o)), "g" (a), "g" (c) : \
210 "%a0","%a1","%d0"); \
211 } while (0)
212
213 #define bus_space_read_multi_4(t, h, o, a, c) do { \
214 (void) t; \
215 __asm volatile (" \
216 movl %0,%%a0 ; \
217 movl %1,%%a1 ; \
218 movl %2,%%d0 ; \
219 1: movl %%a0@,%%a1@+ ; \
220 subql #1,%%d0 ; \
221 jne 1b" : \
222 : \
223 "r" ((h) + (o)), "g" (a), "g" (c) : \
224 "%a0","%a1","%d0"); \
225 } while (0)
226
227 /*
228 * void bus_space_read_region_N(bus_space_tag_t tag,
229 * bus_space_handle_t bsh, bus_size_t offset,
230 * uintN_t *addr, size_t count);
231 *
232 * Read `count' 1, 2, 4, or 8 byte quantities from bus space
233 * described by tag/handle and starting at `offset' and copy into
234 * buffer provided.
235 */
236
237 #define bus_space_read_region_1(t, h, o, a, c) do { \
238 (void) t; \
239 __asm volatile (" \
240 movl %0,%%a0 ; \
241 movl %1,%%a1 ; \
242 movl %2,%%d0 ; \
243 1: movb %%a0@+,%%a1@+ ; \
244 subql #1,%%d0 ; \
245 jne 1b" : \
246 : \
247 "r" ((h) + (o)), "g" (a), "g" (c) : \
248 "%a0","%a1","%d0"); \
249 } while (0)
250
251 #define bus_space_read_region_2(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: movw %%a0@+,%%a1@+ ; \
258 subql #1,%%d0 ; \
259 jne 1b" : \
260 : \
261 "r" ((h) + (o)), "g" (a), "g" (c) : \
262 "%a0","%a1","%d0"); \
263 } while (0)
264
265 #define bus_space_read_region_4(t, h, o, a, c) do { \
266 (void) t; \
267 __asm volatile (" \
268 movl %0,%%a0 ; \
269 movl %1,%%a1 ; \
270 movl %2,%%d0 ; \
271 1: movl %%a0@+,%%a1@+ ; \
272 subql #1,%%d0 ; \
273 jne 1b" : \
274 : \
275 "r" ((h) + (o)), "g" (a), "g" (c) : \
276 "%a0","%a1","%d0"); \
277 } while (0)
278
279 /*
280 * void bus_space_write_N(bus_space_tag_t tag,
281 * bus_space_handle_t bsh, bus_size_t offset,
282 * uintN_t value);
283 *
284 * Write the 1, 2, 4, or 8 byte value `value' to bus space
285 * described by tag/handle/offset.
286 */
287
288 #define bus_space_write_1(t, h, o, v) \
289 ((void) t, ((void)(*(volatile uint8_t *)((h) + (o)) = (v))))
290
291 #define bus_space_write_2(t, h, o, v) \
292 ((void) t, ((void)(*(volatile uint16_t *)((h) + (o)) = (v))))
293
294 #define bus_space_write_4(t, h, o, v) \
295 ((void) t, ((void)(*(volatile uint32_t *)((h) + (o)) = (v))))
296
297 /*
298 * void bus_space_write_multi_N(bus_space_tag_t tag,
299 * bus_space_handle_t bsh, bus_size_t offset,
300 * const uintN_t *addr, size_t count);
301 *
302 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
303 * provided to bus space described by tag/handle/offset.
304 */
305
306 #define bus_space_write_multi_1(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: movb %%a1@+,%%a0@ ; \
313 subql #1,%%d0 ; \
314 jne 1b" : \
315 : \
316 "r" ((h) + (o)), "g" (a), "g" (c) : \
317 "%a0","%a1","%d0"); \
318 } while (0)
319
320 #define bus_space_write_multi_2(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: movw %%a1@+,%%a0@ ; \
327 subql #1,%%d0 ; \
328 jne 1b" : \
329 : \
330 "r" ((h) + (o)), "g" (a), "g" (c) : \
331 "%a0","%a1","%d0"); \
332 } while (0)
333
334 #define bus_space_write_multi_4(t, h, o, a, c) do { \
335 (void) t; \
336 __asm volatile (" \
337 movl %0,%%a0 ; \
338 movl %1,%%a1 ; \
339 movl %2,%%d0 ; \
340 1: movl %%a1@+,%%a0@ ; \
341 subql #1,%%d0 ; \
342 jne 1b" : \
343 : \
344 "r" ((h) + (o)), "g" (a), "g" (c) : \
345 "%a0","%a1","%d0"); \
346 } while (0)
347
348 /*
349 * void bus_space_write_region_N(bus_space_tag_t tag,
350 * bus_space_handle_t bsh, bus_size_t offset,
351 * const uintN_t *addr, size_t count);
352 *
353 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
354 * to bus space described by tag/handle starting at `offset'.
355 */
356
357 #define bus_space_write_region_1(t, h, o, a, c) do { \
358 (void) t; \
359 __asm volatile (" \
360 movl %0,%%a0 ; \
361 movl %1,%%a1 ; \
362 movl %2,%%d0 ; \
363 1: movb %%a1@+,%%a0@+ ; \
364 subql #1,%%d0 ; \
365 jne 1b" : \
366 : \
367 "r" ((h) + (o)), "g" (a), "g" (c) : \
368 "%a0","%a1","%d0"); \
369 } while (0)
370
371 #define bus_space_write_region_2(t, h, o, a, c) do { \
372 (void) t; \
373 __asm volatile (" \
374 movl %0,%%a0 ; \
375 movl %1,%%a1 ; \
376 movl %2,%%d0 ; \
377 1: movw %%a1@+,%%a0@+ ; \
378 subql #1,%%d0 ; \
379 jne 1b" : \
380 : \
381 "r" ((h) + (o)), "g" (a), "g" (c) : \
382 "%a0","%a1","%d0"); \
383 } while (0)
384
385 #define bus_space_write_region_4(t, h, o, a, c) do { \
386 (void) t; \
387 __asm volatile (" \
388 movl %0,%%a0 ; \
389 movl %1,%%a1 ; \
390 movl %2,%%d0 ; \
391 1: movl %%a1@+,%%a0@+ ; \
392 subql #1,%%d0 ; \
393 jne 1b" : \
394 : \
395 "r" ((h) + (o)), "g" (a), "g" (c) : \
396 "%a0","%a1","%d0"); \
397 } while (0)
398
399 /*
400 * void bus_space_set_multi_N(bus_space_tag_t tag,
401 * bus_space_handle_t bsh, bus_size_t offset, uintN_t val,
402 * size_t count);
403 *
404 * Write the 1, 2, 4, or 8 byte value `val' to bus space described
405 * by tag/handle/offset `count' times.
406 */
407
408 #define bus_space_set_multi_1(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: movb %%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_2(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: movw %%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 #define bus_space_set_multi_4(t, h, o, val, c) do { \
437 (void) t; \
438 __asm volatile (" \
439 movl %0,%%a0 ; \
440 movl %1,%%d1 ; \
441 movl %2,%%d0 ; \
442 1: movl %%d1,%%a0@ ; \
443 subql #1,%%d0 ; \
444 jne 1b" : \
445 : \
446 "r" ((h) + (o)), "g" (val), "g" (c) : \
447 "%a0","%d0","%d1"); \
448 } while (0)
449
450 /*
451 * void bus_space_set_region_N(bus_space_tag_t tag,
452 * bus_space_handle_t bsh, bus_size_t offset, uintN_t val,
453 * size_t count);
454 *
455 * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
456 * by tag/handle starting at `offset'.
457 */
458
459 #define bus_space_set_region_1(t, h, o, val, c) do { \
460 (void) t; \
461 __asm volatile (" \
462 movl %0,%%a0 ; \
463 movl %1,%%d1 ; \
464 movl %2,%%d0 ; \
465 1: movb %%d1,%%a0@+ ; \
466 subql #1,%%d0 ; \
467 jne 1b" : \
468 : \
469 "r" ((h) + (o)), "g" (val), "g" (c) : \
470 "%a0","%d0","%d1"); \
471 } while (0)
472
473 #define bus_space_set_region_2(t, h, o, val, c) do { \
474 (void) t; \
475 __asm volatile (" \
476 movl %0,%%a0 ; \
477 movl %1,%%d1 ; \
478 movl %2,%%d0 ; \
479 1: movw %%d1,%%a0@+ ; \
480 subql #1,%%d0 ; \
481 jne 1b" : \
482 : \
483 "r" ((h) + (o)), "g" (val), "g" (c) : \
484 "%a0","%d0","%d1"); \
485 } while (0)
486
487 #define bus_space_set_region_4(t, h, o, val, c) do { \
488 (void) t; \
489 __asm volatile (" \
490 movl %0,%%a0 ; \
491 movl %1,%%d1 ; \
492 movl %2,%%d0 ; \
493 1: movl %%d1,%%a0@+ ; \
494 subql #1,%%d0 ; \
495 jne 1b" : \
496 : \
497 "r" ((h) + (o)), "g" (val), "g" (c) : \
498 "%a0","%d0","%d1"); \
499 } while (0)
500
501 /*
502 * void bus_space_copy_region_N(bus_space_tag_t tag,
503 * bus_space_handle_t bsh1, bus_size_t off1,
504 * bus_space_handle_t bsh2, bus_size_t off2,
505 * bus_size_t count);
506 *
507 * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
508 * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
509 */
510
511 #define __NEWS68K_copy_region_N(BYTES) \
512 static __inline void __CONCAT(bus_space_copy_region_,BYTES) \
513 (bus_space_tag_t, \
514 bus_space_handle_t bsh1, bus_size_t off1, \
515 bus_space_handle_t bsh2, bus_size_t off2, \
516 bus_size_t count); \
517 \
518 static __inline void \
519 __CONCAT(bus_space_copy_region_,BYTES)(bus_space_tag_t t, \
520 bus_space_handle_t h1, bus_space_handle_t h2, \
521 bus_size_t o1, bus_size_t o2, 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 __NEWS68K_copy_region_N(1)
538 __NEWS68K_copy_region_N(2)
539 __NEWS68K_copy_region_N(4)
540
541 #undef __NEWS68K_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 /* _NEWS68K_BUS_H_ */
566