2 * Copyright (c) KATO Takenori, 1999.
4 * All rights reserved. Unpublished rights reserved under the copyright
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer as
13 * the first lines of this file unmodified.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. The name of the author may not be used to endorse or promote products
18 * derived from this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 /* $NecBSD: busio.h,v 3.25.4.2.2.1 2000/06/12 03:53:08 honda Exp $ */
35 /* $NetBSD: bus.h,v 1.12 1997/10/01 08:25:15 fvdl Exp $ */
38 * [NetBSD for NEC PC-98 series]
39 * Copyright (c) 1997, 1998
40 * NetBSD/pc98 porting staff. All rights reserved.
42 * [Ported for FreeBSD]
44 * TAKAHASHI Yoshihiro. All rights reserved.
46 * Redistribution and use in source and binary forms, with or without
47 * modification, are permitted provided that the following conditions
49 * 1. Redistributions of source code must retain the above copyright
50 * notice, this list of conditions and the following disclaimer.
51 * 2. Redistributions in binary form must reproduce the above copyright
52 * notice, this list of conditions and the following disclaimer in the
53 * documentation and/or other materials provided with the distribution.
54 * 3. The name of the author may not be used to endorse or promote products
55 * derived from this software without specific prior written permission.
57 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
58 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
59 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
60 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
61 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
62 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
63 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
64 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
65 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
66 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
67 * POSSIBILITY OF SUCH DAMAGE.
71 * Copyright (c) 1997, 1998
72 * Naofumi HONDA. All rights reserved.
74 * This module support generic bus address relocation mechanism.
75 * To reduce a function call overhead, we employ pascal call methods.
81 #include <sys/systm.h>
83 #include <machine/_bus.h>
84 #include <machine/cpufunc.h>
86 #define BUS_SPACE_MAXSIZE_24BIT 0xFFFFFF
87 #define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF
88 #define BUS_SPACE_MAXSIZE 0xFFFFFFFF
89 #define BUS_SPACE_MAXADDR_24BIT 0xFFFFFF
90 #define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF
91 #define BUS_SPACE_MAXADDR 0xFFFFFFFF
93 #define BUS_SPACE_UNRESTRICTED (~0)
95 #define BUS_SPACE_IAT_MAXSIZE 33
98 * Access methods for bus resources and address space.
105 #define _PASCAL_CALL (void)
107 #define _BUS_SPACE_CALL_FUNCS_TAB(NAME,TYPE,BWN) \
108 NAME##_space_read_##BWN, \
109 NAME##_space_read_multi_##BWN, \
110 NAME##_space_read_region_##BWN, \
111 NAME##_space_write_##BWN, \
112 NAME##_space_write_multi_##BWN, \
113 NAME##_space_write_region_##BWN, \
114 NAME##_space_set_multi_##BWN, \
115 NAME##_space_set_region_##BWN, \
116 NAME##_space_copy_region_##BWN
118 #define _BUS_SPACE_CALL_FUNCS_PROTO(NAME,TYPE,BWN) \
119 TYPE NAME##_space_read_##BWN _PASCAL_CALL; \
120 void NAME##_space_read_multi_##BWN _PASCAL_CALL; \
121 void NAME##_space_read_region_##BWN _PASCAL_CALL; \
122 void NAME##_space_write_##BWN _PASCAL_CALL; \
123 void NAME##_space_write_multi_##BWN _PASCAL_CALL; \
124 void NAME##_space_write_region_##BWN _PASCAL_CALL; \
125 void NAME##_space_set_multi_##BWN _PASCAL_CALL; \
126 void NAME##_space_set_region_##BWN _PASCAL_CALL; \
127 void NAME##_space_copy_region_##BWN _PASCAL_CALL;
129 #define _BUS_SPACE_CALL_FUNCS(NAME,TYPE,BWN) \
130 TYPE (* NAME##_read_##BWN) _PASCAL_CALL; \
131 void (* NAME##_read_multi_##BWN) _PASCAL_CALL; \
132 void (* NAME##_read_region_##BWN) _PASCAL_CALL; \
133 void (* NAME##_write_##BWN) _PASCAL_CALL; \
134 void (* NAME##_write_multi_##BWN) _PASCAL_CALL; \
135 void (* NAME##_write_region_##BWN) _PASCAL_CALL; \
136 void (* NAME##_set_multi_##BWN) _PASCAL_CALL; \
137 void (* NAME##_set_region_##BWN) _PASCAL_CALL; \
138 void (* NAME##_copy_region_##BWN) _PASCAL_CALL;
140 struct bus_space_access_methods {
141 /* 8 bits access methods */
142 _BUS_SPACE_CALL_FUNCS(bs,u_int8_t,1)
144 /* 16 bits access methods */
145 _BUS_SPACE_CALL_FUNCS(bs,u_int16_t,2)
147 /* 32 bits access methods */
148 _BUS_SPACE_CALL_FUNCS(bs,u_int32_t,4)
152 * Access methods for bus resources and address space.
154 struct bus_space_tag {
155 #define BUS_SPACE_IO 0
156 #define BUS_SPACE_MEM 1
157 u_int bs_tag; /* bus space flags */
159 struct bus_space_access_methods bs_da; /* direct access */
160 struct bus_space_access_methods bs_ra; /* relocate access */
162 struct bus_space_access_methods bs_ida; /* indexed direct access */
169 struct bus_space_handle {
173 bus_addr_t bsh_iat[BUS_SPACE_IAT_MAXSIZE];
177 struct resource **bsh_res;
180 struct bus_space_access_methods bsh_bam;
184 * Values for the pc98 bus space tag, not to be used directly by MI code.
186 extern struct bus_space_tag SBUS_io_space_tag;
187 extern struct bus_space_tag SBUS_mem_space_tag;
189 #define I386_BUS_SPACE_IO (&SBUS_io_space_tag)
190 #define I386_BUS_SPACE_MEM (&SBUS_mem_space_tag)
193 * Allocate/Free bus_space_handle
195 int i386_bus_space_handle_alloc(bus_space_tag_t t, bus_addr_t bpa,
196 bus_size_t size, bus_space_handle_t *bshp);
197 void i386_bus_space_handle_free(bus_space_tag_t t, bus_space_handle_t bsh,
201 * int bus_space_map (bus_space_tag_t t, bus_addr_t addr,
202 * bus_size_t size, int flag, bus_space_handle_t *bshp);
204 * Map a region of bus space.
207 int i386_memio_map(bus_space_tag_t t, bus_addr_t addr, bus_size_t size,
208 int flag, bus_space_handle_t *bshp);
210 #define bus_space_map(t, a, s, f, hp) \
211 i386_memio_map((t), (a), (s), (f), (hp))
214 * int bus_space_unmap (bus_space_tag_t t,
215 * bus_space_handle_t bsh, bus_size_t size);
217 * Unmap a region of bus space.
220 void i386_memio_unmap(bus_space_tag_t t, bus_space_handle_t bsh,
223 #define bus_space_unmap(t, h, s) \
224 i386_memio_unmap((t), (h), (s))
227 * int bus_space_subregion (bus_space_tag_t t,
228 * bus_space_handle_t bsh, bus_size_t offset, bus_size_t size,
229 * bus_space_handle_t *nbshp);
231 * Get a new handle for a subregion of an already-mapped area of bus space.
234 int i386_memio_subregion(bus_space_tag_t t, bus_space_handle_t bsh,
235 bus_size_t offset, bus_size_t size,
236 bus_space_handle_t *nbshp);
238 #define bus_space_subregion(t, h, o, s, nhp) \
239 i386_memio_subregion((t), (h), (o), (s), (nhp))
242 * int bus_space_free (bus_space_tag_t t,
243 * bus_space_handle_t bsh, bus_size_t size);
245 * Free a region of bus space.
248 void i386_memio_free(bus_space_tag_t t, bus_space_handle_t bsh,
251 #define bus_space_free(t, h, s) \
252 i386_memio_free((t), (h), (s))
255 * Access methods for bus resources and address space.
257 #define _BUS_ACCESS_METHODS_PROTO(TYPE,BWN) \
258 static __inline TYPE bus_space_read_##BWN \
259 (bus_space_tag_t, bus_space_handle_t, bus_size_t offset); \
260 static __inline void bus_space_read_multi_##BWN \
261 (bus_space_tag_t, bus_space_handle_t, \
262 bus_size_t, TYPE *, size_t); \
263 static __inline void bus_space_read_region_##BWN \
264 (bus_space_tag_t, bus_space_handle_t, \
265 bus_size_t, TYPE *, size_t); \
266 static __inline void bus_space_write_##BWN \
267 (bus_space_tag_t, bus_space_handle_t, bus_size_t, TYPE); \
268 static __inline void bus_space_write_multi_##BWN \
269 (bus_space_tag_t, bus_space_handle_t, \
270 bus_size_t, const TYPE *, size_t); \
271 static __inline void bus_space_write_region_##BWN \
272 (bus_space_tag_t, bus_space_handle_t, \
273 bus_size_t, const TYPE *, size_t); \
274 static __inline void bus_space_set_multi_##BWN \
275 (bus_space_tag_t, bus_space_handle_t, bus_size_t, TYPE, size_t);\
276 static __inline void bus_space_set_region_##BWN \
277 (bus_space_tag_t, bus_space_handle_t, bus_size_t, TYPE, size_t);\
278 static __inline void bus_space_copy_region_##BWN \
279 (bus_space_tag_t, bus_space_handle_t, bus_size_t, \
280 bus_space_handle_t, bus_size_t, size_t);
282 _BUS_ACCESS_METHODS_PROTO(u_int8_t,1)
283 _BUS_ACCESS_METHODS_PROTO(u_int16_t,2)
284 _BUS_ACCESS_METHODS_PROTO(u_int32_t,4)
289 #define _BUS_SPACE_READ(TYPE,BWN) \
290 static __inline TYPE \
291 bus_space_read_##BWN (tag, bsh, offset) \
292 bus_space_tag_t tag; \
293 bus_space_handle_t bsh; \
296 register TYPE result; \
298 __asm __volatile("call *%2" \
301 :"o" (bsh->bsh_bam.bs_read_##BWN), \
309 _BUS_SPACE_READ(u_int8_t,1)
310 _BUS_SPACE_READ(u_int16_t,2)
311 _BUS_SPACE_READ(u_int32_t,4)
316 #define _BUS_SPACE_WRITE(TYPE,BWN) \
317 static __inline void \
318 bus_space_write_##BWN (tag, bsh, offset, val) \
319 bus_space_tag_t tag; \
320 bus_space_handle_t bsh; \
325 __asm __volatile("call *%1" \
327 :"o" (bsh->bsh_bam.bs_write_##BWN), \
334 _BUS_SPACE_WRITE(u_int8_t,1)
335 _BUS_SPACE_WRITE(u_int16_t,2)
336 _BUS_SPACE_WRITE(u_int32_t,4)
341 #define _BUS_SPACE_READ_MULTI(TYPE,BWN) \
342 static __inline void \
343 bus_space_read_multi_##BWN (tag, bsh, offset, buf, cnt) \
344 bus_space_tag_t tag; \
345 bus_space_handle_t bsh; \
351 __asm __volatile("call *%3" \
355 :"o" (bsh->bsh_bam.bs_read_multi_##BWN), \
363 _BUS_SPACE_READ_MULTI(u_int8_t,1)
364 _BUS_SPACE_READ_MULTI(u_int16_t,2)
365 _BUS_SPACE_READ_MULTI(u_int32_t,4)
370 #define _BUS_SPACE_WRITE_MULTI(TYPE,BWN) \
371 static __inline void \
372 bus_space_write_multi_##BWN (tag, bsh, offset, buf, cnt) \
373 bus_space_tag_t tag; \
374 bus_space_handle_t bsh; \
380 __asm __volatile("call *%3" \
384 :"o" (bsh->bsh_bam.bs_write_multi_##BWN), \
392 _BUS_SPACE_WRITE_MULTI(u_int8_t,1)
393 _BUS_SPACE_WRITE_MULTI(u_int16_t,2)
394 _BUS_SPACE_WRITE_MULTI(u_int32_t,4)
399 #define _BUS_SPACE_READ_REGION(TYPE,BWN) \
400 static __inline void \
401 bus_space_read_region_##BWN (tag, bsh, offset, buf, cnt) \
402 bus_space_tag_t tag; \
403 bus_space_handle_t bsh; \
409 __asm __volatile("call *%3" \
413 :"o" (bsh->bsh_bam.bs_read_region_##BWN), \
421 _BUS_SPACE_READ_REGION(u_int8_t,1)
422 _BUS_SPACE_READ_REGION(u_int16_t,2)
423 _BUS_SPACE_READ_REGION(u_int32_t,4)
428 #define _BUS_SPACE_WRITE_REGION(TYPE,BWN) \
429 static __inline void \
430 bus_space_write_region_##BWN (tag, bsh, offset, buf, cnt) \
431 bus_space_tag_t tag; \
432 bus_space_handle_t bsh; \
438 __asm __volatile("call *%3" \
442 :"o" (bsh->bsh_bam.bs_write_region_##BWN), \
450 _BUS_SPACE_WRITE_REGION(u_int8_t,1)
451 _BUS_SPACE_WRITE_REGION(u_int16_t,2)
452 _BUS_SPACE_WRITE_REGION(u_int32_t,4)
457 #define _BUS_SPACE_SET_MULTI(TYPE,BWN) \
458 static __inline void \
459 bus_space_set_multi_##BWN (tag, bsh, offset, val, cnt) \
460 bus_space_tag_t tag; \
461 bus_space_handle_t bsh; \
467 __asm __volatile("call *%2" \
470 :"o" (bsh->bsh_bam.bs_set_multi_##BWN), \
478 _BUS_SPACE_SET_MULTI(u_int8_t,1)
479 _BUS_SPACE_SET_MULTI(u_int16_t,2)
480 _BUS_SPACE_SET_MULTI(u_int32_t,4)
485 #define _BUS_SPACE_SET_REGION(TYPE,BWN) \
486 static __inline void \
487 bus_space_set_region_##BWN (tag, bsh, offset, val, cnt) \
488 bus_space_tag_t tag; \
489 bus_space_handle_t bsh; \
495 __asm __volatile("call *%2" \
498 :"o" (bsh->bsh_bam.bs_set_region_##BWN), \
506 _BUS_SPACE_SET_REGION(u_int8_t,1)
507 _BUS_SPACE_SET_REGION(u_int16_t,2)
508 _BUS_SPACE_SET_REGION(u_int32_t,4)
513 #define _BUS_SPACE_COPY_REGION(BWN) \
514 static __inline void \
515 bus_space_copy_region_##BWN (tag, sbsh, src, dbsh, dst, cnt) \
516 bus_space_tag_t tag; \
517 bus_space_handle_t sbsh; \
519 bus_space_handle_t dbsh; \
524 if (dbsh->bsh_bam.bs_copy_region_1 != sbsh->bsh_bam.bs_copy_region_1) \
525 panic("bus_space_copy_region: funcs mismatch (ENOSUPPORT)");\
527 __asm __volatile("call *%3" \
531 :"o" (dbsh->bsh_bam.bs_copy_region_##BWN), \
540 _BUS_SPACE_COPY_REGION(1)
541 _BUS_SPACE_COPY_REGION(2)
542 _BUS_SPACE_COPY_REGION(4)
545 * Bus read/write barrier methods.
547 * void bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh,
548 * bus_size_t offset, bus_size_t len, int flags);
551 * Note that BUS_SPACE_BARRIER_WRITE doesn't do anything other than
552 * prevent reordering by the compiler; all Intel x86 processors currently
553 * retire operations outside the CPU in program order.
555 #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */
556 #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */
559 bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh,
560 bus_size_t offset, bus_size_t len, int flags)
562 if (flags & BUS_SPACE_BARRIER_READ)
563 __asm __volatile("lock; addl $0,0(%%esp)" : : : "memory");
565 __asm __volatile("" : : : "memory");
568 #ifdef BUS_SPACE_NO_LEGACY
571 #define inb(a) compiler_error
572 #define inw(a) compiler_error
573 #define inl(a) compiler_error
574 #define outb(a, b) compiler_error
575 #define outw(a, b) compiler_error
576 #define outl(a, b) compiler_error
579 #include <machine/bus_dma.h>
582 * Stream accesses are the same as normal accesses on i386/pc98; there are no
583 * supported bus systems with an endianess different from the host one.
585 #define bus_space_read_stream_1(t, h, o) bus_space_read_1((t), (h), (o))
586 #define bus_space_read_stream_2(t, h, o) bus_space_read_2((t), (h), (o))
587 #define bus_space_read_stream_4(t, h, o) bus_space_read_4((t), (h), (o))
589 #define bus_space_read_multi_stream_1(t, h, o, a, c) \
590 bus_space_read_multi_1((t), (h), (o), (a), (c))
591 #define bus_space_read_multi_stream_2(t, h, o, a, c) \
592 bus_space_read_multi_2((t), (h), (o), (a), (c))
593 #define bus_space_read_multi_stream_4(t, h, o, a, c) \
594 bus_space_read_multi_4((t), (h), (o), (a), (c))
596 #define bus_space_write_stream_1(t, h, o, v) \
597 bus_space_write_1((t), (h), (o), (v))
598 #define bus_space_write_stream_2(t, h, o, v) \
599 bus_space_write_2((t), (h), (o), (v))
600 #define bus_space_write_stream_4(t, h, o, v) \
601 bus_space_write_4((t), (h), (o), (v))
603 #define bus_space_write_multi_stream_1(t, h, o, a, c) \
604 bus_space_write_multi_1((t), (h), (o), (a), (c))
605 #define bus_space_write_multi_stream_2(t, h, o, a, c) \
606 bus_space_write_multi_2((t), (h), (o), (a), (c))
607 #define bus_space_write_multi_stream_4(t, h, o, a, c) \
608 bus_space_write_multi_4((t), (h), (o), (a), (c))
610 #define bus_space_set_multi_stream_1(t, h, o, v, c) \
611 bus_space_set_multi_1((t), (h), (o), (v), (c))
612 #define bus_space_set_multi_stream_2(t, h, o, v, c) \
613 bus_space_set_multi_2((t), (h), (o), (v), (c))
614 #define bus_space_set_multi_stream_4(t, h, o, v, c) \
615 bus_space_set_multi_4((t), (h), (o), (v), (c))
617 #define bus_space_read_region_stream_1(t, h, o, a, c) \
618 bus_space_read_region_1((t), (h), (o), (a), (c))
619 #define bus_space_read_region_stream_2(t, h, o, a, c) \
620 bus_space_read_region_2((t), (h), (o), (a), (c))
621 #define bus_space_read_region_stream_4(t, h, o, a, c) \
622 bus_space_read_region_4((t), (h), (o), (a), (c))
624 #define bus_space_write_region_stream_1(t, h, o, a, c) \
625 bus_space_write_region_1((t), (h), (o), (a), (c))
626 #define bus_space_write_region_stream_2(t, h, o, a, c) \
627 bus_space_write_region_2((t), (h), (o), (a), (c))
628 #define bus_space_write_region_stream_4(t, h, o, a, c) \
629 bus_space_write_region_4((t), (h), (o), (a), (c))
631 #define bus_space_set_region_stream_1(t, h, o, v, c) \
632 bus_space_set_region_1((t), (h), (o), (v), (c))
633 #define bus_space_set_region_stream_2(t, h, o, v, c) \
634 bus_space_set_region_2((t), (h), (o), (v), (c))
635 #define bus_space_set_region_stream_4(t, h, o, v, c) \
636 bus_space_set_region_4((t), (h), (o), (v), (c))
638 #define bus_space_copy_region_stream_1(t, h1, o1, h2, o2, c) \
639 bus_space_copy_region_1((t), (h1), (o1), (h2), (o2), (c))
640 #define bus_space_copy_region_stream_2(t, h1, o1, h2, o2, c) \
641 bus_space_copy_region_2((t), (h1), (o1), (h2), (o2), (c))
642 #define bus_space_copy_region_stream_4(t, h1, o1, h2, o2, c) \
643 bus_space_copy_region_4((t), (h1), (o1), (h2), (o2), (c))
645 #endif /* _PC98_BUS_H_ */