1 /* $NetBSD: bus_space.h,v 1.12 2008/01/12 09:54:28 tsutsui Exp $ */
4 * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
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.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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.
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.
34 * Copyright (C) 1997 Scott Reynolds. All rights reserved.
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
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
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.
60 * Lifted from the Next68k port.
61 * Modified for mvme68k by Steve Woodford.
63 * TODO: Support for VMEbus...
64 * (Do any existing VME card drivers use bus_space_* ?)
67 #ifndef _MVME68K_BUS_SPACE_H_
68 #define _MVME68K_BUS_SPACE_H_
71 * Addresses (in bus space).
73 typedef u_long bus_addr_t
;
74 typedef u_long bus_size_t
;
77 * Access methods for bus resources and address space.
79 struct mvme68k_bus_space_tag
;
80 typedef struct mvme68k_bus_space_tag
*bus_space_tag_t
;
81 typedef u_long bus_space_handle_t
;
83 struct mvme68k_bus_space_tag
{
85 int (*bs_map
)(void *, bus_addr_t
, bus_size_t
,
86 int, bus_space_handle_t
*);
87 void (*bs_unmap
)(void *, bus_space_handle_t
, bus_size_t
);
88 int (*bs_peek_1
)(void *, bus_space_handle_t
,
89 bus_size_t
, uint8_t *);
90 int (*bs_peek_2
)(void *, bus_space_handle_t
,
91 bus_size_t
, uint16_t *);
92 int (*bs_peek_4
)(void *, bus_space_handle_t
,
93 bus_size_t
, uint32_t *);
95 int (*bs_peek_8
)(void *, bus_space_handle_t
,
96 bus_size_t
, uint64_t *);
98 int (*bs_poke_1
)(void *, bus_space_handle_t
,
100 int (*bs_poke_2
)(void *, bus_space_handle_t
,
101 bus_size_t
, uint16_t);
102 int (*bs_poke_4
)(void *, bus_space_handle_t
,
103 bus_size_t
, uint32_t);
105 int (*bs_poke_8
)(void *, bus_space_handle_t
,
106 bus_size_t
, uint64_t);
111 * int bus_space_map(bus_space_tag_t t, bus_addr_t addr,
112 * bus_size_t size, int flags,
113 * bus_space_handle_t *bshp);
115 * Map a region of bus space.
117 #define bus_space_map(tag, offset, size, flags, handlep) \
118 (*((tag)->bs_map))((tag)->bs_cookie, (offset), (size), (flags), (handlep))
121 * Possible values for the 'flags' parameter of bus_space_map()
123 #define BUS_SPACE_MAP_CACHEABLE 0x01
124 #define BUS_SPACE_MAP_LINEAR 0x02
125 #define BUS_SPACE_MAP_PREFETCHABLE 0x04
128 * void bus_space_unmap(bus_space_tag_t t,
129 * bus_space_handle_t bsh, bus_size_t size);
131 * Unmap a region of bus space.
133 #define bus_space_unmap(tag, handle, size) \
134 (*((tag)->bs_unmap))((tag)->bs_cookie, (handle), (size))
137 * int bus_space_subregion(bus_space_tag_t t, bus_space_handle_t h
138 * bus_addr_t offset, bus_size_t size, bus_space_handle_t *newh);
140 * Allocate a sub-region of an existing map
142 #define bus_space_subregion(t, h, o, s, hp) \
146 * Allocation and deallocation operations.
148 #define bus_space_alloc(t, rs, re, s, a, b, f, ap, hp) \
151 #define bus_space_free(t, h, s)
154 * int bus_space_peek_N(bus_space_tag_t tag,
155 * bus_space_handle_t bsh, bus_size_t offset, uintN_t *valuep);
157 * Cautiously read 1, 2, 4 or 8 byte quantity from bus space described
158 * by tag/handle/offset.
159 * If no hardware responds to the read access, the function returns a
160 * non-zero value. Otherwise the value read is placed in `valuep'.
162 #define bus_space_peek_1(t, h, o, vp) \
163 (*((t)->bs_peek_1))((t)->bs_cookie, (h), (o), (vp))
165 #define bus_space_peek_2(t, h, o, vp) \
166 (*((t)->bs_peek_2))((t)->bs_cookie, (h), (o), (vp))
168 #define bus_space_peek_4(t, h, o, vp) \
169 (*((t)->bs_peek_4))((t)->bs_cookie, (h), (o), (vp))
171 #if 0 /* Cause a link error for bus_space_peek_8 */
172 #define bus_space_peek_8(t, h, o, vp) \
173 (*((t)->bs_peek_8))((t)->bs_cookie, (h), (o), (vp))
177 * int bus_space_poke_N(bus_space_tag_t tag,
178 * bus_space_handle_t bsh, bus_size_t offset, uintN_t value);
180 * Cautiously write 1, 2, 4 or 8 byte quantity to bus space described
181 * by tag/handle/offset.
182 * If no hardware responds to the write access, the function returns a
185 #define bus_space_poke_1(t, h, o, v) \
186 (*((t)->bs_poke_1))((t)->bs_cookie, (h), (o), (v))
188 #define bus_space_poke_2(t, h, o, v) \
189 (*((t)->bs_poke_2))((t)->bs_cookie, (h), (o), (v))
191 #define bus_space_poke_4(t, h, o, v) \
192 (*((t)->bs_poke_4))((t)->bs_cookie, (h), (o), (v))
194 #if 0 /* Cause a link error for bus_space_poke_8 */
195 #define bus_space_poke_8(t, h, o, v) \
196 (*((t)->bs_poke_8))((t)->bs_cookie, (h), (o), (v))
200 * uintN_t bus_space_read_N(bus_space_tag_t tag,
201 * bus_space_handle_t bsh, bus_size_t offset);
203 * Read a 1, 2, 4, or 8 byte quantity from bus space
204 * described by tag/handle/offset.
206 #define bus_space_read_1(t,h,o) \
207 (*((volatile uint8_t *)(intptr_t)((h) + (o))))
208 #define bus_space_read_2(t,h,o) \
209 (*((volatile uint16_t *)(intptr_t)((h) + (o))))
210 #define bus_space_read_4(t,h,o) \
211 (*((volatile uint32_t *)(intptr_t)((h) + (o))))
214 * void bus_space_read_multi_N(bus_space_tag_t tag,
215 * bus_space_handle_t bsh, bus_size_t offset,
216 * uintN_t *addr, size_t count);
218 * Read `count' 1, 2, 4, or 8 byte quantities from bus space
219 * described by tag/handle/offset and copy into buffer provided.
222 #define bus_space_read_multi_1(t, h, o, a, c) do { \
228 1: movb %%a0@,%%a1@+ ; \
232 "r" ((h) + (o)), "g" (a), "g" (c) : \
236 #define bus_space_read_multi_2(t, h, o, a, c) do { \
242 1: movw %%a0@,%%a1@+ ; \
246 "r" ((h) + (o)), "g" (a), "g" (c) : \
250 #define bus_space_read_multi_4(t, h, o, a, c) do { \
256 1: movl %%a0@,%%a1@+ ; \
260 "r" ((h) + (o)), "g" (a), "g" (c) : \
264 #if 0 /* Cause a link error for bus_space_read_multi_8 */
265 #define bus_space_read_multi_8 !!! bus_space_read_multi_8 unimplemented !!!
269 * void bus_space_read_region_N(bus_space_tag_t tag,
270 * bus_space_handle_t bsh, bus_size_t offset,
271 * uintN_t *addr, size_t count);
273 * Read `count' 1, 2, 4, or 8 byte quantities from bus space
274 * described by tag/handle and starting at `offset' and copy into
278 #define bus_space_read_region_1(t, h, o, a, c) do { \
284 1: movb %%a0@+,%%a1@+ ; \
288 "r" ((h) + (o)), "g" (a), "g" (c) : \
292 #define bus_space_read_region_2(t, h, o, a, c) do { \
298 1: movw %%a0@+,%%a1@+ ; \
302 "r" ((h) + (o)), "g" (a), "g" (c) : \
306 #define bus_space_read_region_4(t, h, o, a, c) do { \
312 1: movl %%a0@+,%%a1@+ ; \
316 "r" ((h) + (o)), "g" (a), "g" (c) : \
320 #if 0 /* Cause a link error for bus_space_read_region_8 */
321 #define bus_space_read_region_8 !!! bus_space_read_region_8 unimplemented !!!
325 * void bus_space_write_N(bus_space_tag_t tag,
326 * bus_space_handle_t bsh, bus_size_t offset,
329 * Write the 1, 2, 4, or 8 byte value `value' to bus space
330 * described by tag/handle/offset.
332 #define bus_space_write_1(t,h,o,v) \
334 *((volatile uint8_t *)(intptr_t)((h) + (o))) = (v); \
335 } while (/*CONSTCOND*/0)
336 #define bus_space_write_2(t,h,o,v) \
338 *((volatile uint16_t *)(intptr_t)((h) + (o))) = (v); \
339 } while (/*CONSTCOND*/0)
340 #define bus_space_write_4(t,h,o,v) \
342 *((volatile uint32_t *)(intptr_t)((h) + (o))) = (v); \
343 } while (/*CONSTCOND*/0)
346 * void bus_space_write_multi_N(bus_space_tag_t tag,
347 * bus_space_handle_t bsh, bus_size_t offset,
348 * const uintN_t *addr, size_t count);
350 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
351 * provided to bus space described by tag/handle/offset.
354 #define bus_space_write_multi_1(t, h, o, a, c) do { \
360 1: movb %%a1@+,%%a0@ ; \
364 "r" ((h) + (o)), "g" (a), "g" (c) : \
368 #define bus_space_write_multi_2(t, h, o, a, c) do { \
374 1: movw %%a1@+,%%a0@ ; \
378 "r" ((h) + (o)), "g" (a), "g" (c) : \
382 #define bus_space_write_multi_4(t, h, o, a, c) do { \
388 1: movl a1@+,%%a0@ ; \
392 "r" ((h) + (o)), "g" (a), "g" (c) : \
396 #if 0 /* Cause a link error for bus_space_write_8 */
397 #define bus_space_write_multi_8(t, h, o, a, c) \
398 !!! bus_space_write_multi_8 unimplimented !!!
402 * void bus_space_write_region_N(bus_space_tag_t tag,
403 * bus_space_handle_t bsh, bus_size_t offset,
404 * const uintN_t *addr, size_t count);
406 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
407 * to bus space described by tag/handle starting at `offset'.
410 #define bus_space_write_region_1(t, h, o, a, c) do { \
416 1: movb %%a1@+,%%a0@+ ; \
420 "r" ((h) + (o)), "g" (a), "g" (c) : \
424 #define bus_space_write_region_2(t, h, o, a, c) do { \
430 1: movw %%a1@+,%%a0@+ ; \
434 "r" ((h) + (o)), "g" (a), "g" (c) : \
438 #define bus_space_write_region_4(t, h, o, a, c) do { \
444 1: movl %%a1@+,%%a0@+ ; \
448 "r" ((h) + (o)), "g" (a), "g" (c) : \
452 #if 0 /* Cause a link error for bus_space_write_region_8 */
453 #define bus_space_write_region_8 \
454 !!! bus_space_write_region_8 unimplemented !!!
458 * void bus_space_set_multi_N(bus_space_tag_t tag,
459 * bus_space_handle_t bsh, bus_size_t offset, uintN_t val,
462 * Write the 1, 2, 4, or 8 byte value `val' to bus space described
463 * by tag/handle/offset `count' times.
466 #define bus_space_set_multi_1(t, h, o, val, c) do { \
472 1: movb %%d1,%%a0@ ; \
476 "r" ((h) + (o)), "g" (val), "g" (c) : \
480 #define bus_space_set_multi_2(t, h, o, val, c) do { \
486 1: movw %%d1,%%a0@ ; \
490 "r" ((h) + (o)), "g" (val), "g" (c) : \
494 #define bus_space_set_multi_4(t, h, o, val, c) do { \
500 1: movl %%d1,%%a0@ ; \
504 "r" ((h) + (o)), "g" (val), "g" (c) : \
508 #if 0 /* Cause a link error for bus_space_set_multi_8 */
509 #define bus_space_set_multi_8 \
510 !!! bus_space_set_multi_8 unimplemented !!!
514 * void bus_space_set_region_N(bus_space_tag_t tag,
515 * bus_space_handle_t bsh, bus_size_t offset, uintN_t val,
518 * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
519 * by tag/handle starting at `offset'.
522 #define bus_space_set_region_1(t, h, o, val, c) do { \
528 1: movb %%d1,%%a0@+ ; \
532 "r" ((h) + (o)), "g" (val), "g" (c) : \
536 #define bus_space_set_region_2(t, h, o, val, c) do { \
542 1: movw %%d1,%%a0@+ ; \
546 "r" ((h) + (o)), "g" (val), "g" (c) : \
550 #define bus_space_set_region_4(t, h, o, val, c) do { \
556 1: movl d1,%%a0@+ ; \
560 "r" ((h) + (o)), "g" (val), "g" (c) : \
564 #if 0 /* Cause a link error for bus_space_set_region_8 */
565 #define bus_space_set_region_8 \
566 !!! bus_space_set_region_8 unimplemented !!!
570 * void bus_space_copy_N(bus_space_tag_t tag,
571 * bus_space_handle_t bsh1, bus_size_t off1,
572 * bus_space_handle_t bsh2, bus_size_t off2,
575 * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
576 * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
579 #define __MVME68K_copy_region_N(BYTES) \
580 static __inline void __CONCAT(bus_space_copy_region_,BYTES) \
582 bus_space_handle_t bsh1, bus_size_t off1, \
583 bus_space_handle_t bsh2, bus_size_t off2, \
586 static __inline void \
587 __CONCAT(bus_space_copy_region_,BYTES)(t, h1, o1, h2, o2, c) \
589 bus_space_handle_t h1, h2; \
590 bus_size_t o1, o2, c; \
594 if ((h1 + o1) >= (h2 + o2)) { \
595 /* src after dest: copy forward */ \
596 for (o = 0; c != 0; c--, o += BYTES) \
597 __CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o, \
598 __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \
600 /* dest after src: copy backwards */ \
601 for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES) \
602 __CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o, \
603 __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \
606 __MVME68K_copy_region_N(1)
607 __MVME68K_copy_region_N(2)
608 __MVME68K_copy_region_N(4)
609 #if 0 /* Cause a link error for bus_space_copy_8 */
610 #define bus_space_copy_8 \
611 !!! bus_space_copy_8 unimplemented !!!
614 #undef __MVME68K_copy_region_N
617 * Bus read/write barrier methods.
619 * void bus_space_barrier(bus_space_tag_t tag,
620 * bus_space_handle_t bsh, bus_size_t offset,
621 * bus_size_t len, int flags);
623 * Note: the 680x0 does not currently require barriers, but we must
624 * provide the flags to MI code.
626 #define bus_space_barrier(t, h, o, l, f) \
627 ((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f)))
628 #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */
629 #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */
631 #define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t)
634 #ifdef _MVME68K_BUS_SPACE_PRIVATE
635 extern int _bus_space_map(void *, bus_addr_t
, bus_size_t
,
636 int, bus_space_handle_t
*);
637 extern void _bus_space_unmap(void *, bus_space_handle_t
, bus_size_t
);
638 extern int _bus_space_peek_1(void *, bus_space_handle_t
,
639 bus_size_t
, uint8_t *);
640 extern int _bus_space_peek_2(void *, bus_space_handle_t
,
641 bus_size_t
, uint16_t *);
642 extern int _bus_space_peek_4(void *, bus_space_handle_t
,
643 bus_size_t
, uint32_t *);
644 extern int _bus_space_poke_1(void *, bus_space_handle_t
, bus_size_t
, uint8_t);
645 extern int _bus_space_poke_2(void *, bus_space_handle_t
, bus_size_t
, uint16_t);
646 extern int _bus_space_poke_4(void *, bus_space_handle_t
, bus_size_t
, uint32_t);
647 #endif /* _MVME68K_BUS_SPACE_PRIVATE */
649 #endif /* _MVME68K_BUS_SPACE_H_ */