Initial import from FreeBSD RELENG_4:
[games.git] / sys / i386 / include / bus_pc98.h
1 /* $FreeBSD: src/sys/i386/include/bus_pc98.h,v 1.8.2.5 2002/03/03 05:42:50 nyan Exp $ */
2 /*      $NecBSD: busio.h,v 3.25.4.2.2.1 2000/06/12 03:53:08 honda Exp $ */
3 /*      $NetBSD: bus.h,v 1.12 1997/10/01 08:25:15 fvdl Exp $    */
4
5 /*
6  * [NetBSD for NEC PC-98 series]
7  *  Copyright (c) 1997, 1998
8  *      NetBSD/pc98 porting staff. All rights reserved.
9  *
10  * [Ported for FreeBSD]
11  *  Copyright (c) 2001
12  *      TAKAHASHI Yoshihiro. All rights reserved.
13  *
14  *  Redistribution and use in source and binary forms, with or without
15  *  modification, are permitted provided that the following conditions
16  *  are met:
17  *  1. Redistributions of source code must retain the above copyright
18  *     notice, this list of conditions and the following disclaimer.
19  *  2. Redistributions in binary form must reproduce the above copyright
20  *     notice, this list of conditions and the following disclaimer in the
21  *     documentation and/or other materials provided with the distribution.
22  *  3. The name of the author may not be used to endorse or promote products
23  *     derived from this software without specific prior written permission.
24  * 
25  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
26  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
27  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
29  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
30  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
33  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  * POSSIBILITY OF SUCH DAMAGE.
36  */
37
38 /*
39  * Copyright (c) 1997, 1998
40  *      Naofumi HONDA.  All rights reserved.
41  *
42  * This module support generic bus address relocation mechanism.
43  * To reduce a function call overhead, we employ pascal call methods.
44  */
45
46 #ifndef _I386_BUS_PC98_H_
47 #define _I386_BUS_PC98_H_
48
49 #include <sys/systm.h>
50
51 #include <machine/cpufunc.h>
52
53 /*
54  * Bus address and size types
55  */
56 typedef u_int bus_addr_t;
57 typedef u_int bus_size_t;
58
59 #define BUS_SPACE_MAXSIZE_24BIT 0xFFFFFF
60 #define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF
61 #define BUS_SPACE_MAXSIZE       (64 * 1024) /* Maximum supported size */
62 #define BUS_SPACE_MAXADDR_24BIT 0xFFFFFF
63 #define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF
64 #define BUS_SPACE_MAXADDR       0xFFFFFFFF
65
66 #define BUS_SPACE_UNRESTRICTED  (~0)
67
68 #define BUS_SPACE_IAT_MAXSIZE   32
69
70 /*
71  * Access methods for bus resources and address space.
72  */
73 struct resource;
74
75 /*
76  * bus space tag
77  */
78 #define _PASCAL_CALL    __P((void))
79
80 #define _BUS_SPACE_CALL_FUNCS_TAB(NAME,TYPE,BWN) \
81         NAME##_space_read_##BWN##,                              \
82         NAME##_space_read_multi_##BWN##,                        \
83         NAME##_space_read_region_##BWN##,                       \
84         NAME##_space_write_##BWN##,                             \
85         NAME##_space_write_multi_##BWN##,                       \
86         NAME##_space_write_region_##BWN##,                      \
87         NAME##_space_set_multi_##BWN##,                         \
88         NAME##_space_set_region_##BWN##,                        \
89         NAME##_space_copy_region_##BWN
90
91 #define _BUS_SPACE_CALL_FUNCS_PROTO(NAME,TYPE,BWN) \
92         TYPE NAME##_space_read_##BWN _PASCAL_CALL;              \
93         void NAME##_space_read_multi_##BWN _PASCAL_CALL;        \
94         void NAME##_space_read_region_##BWN _PASCAL_CALL;       \
95         void NAME##_space_write_##BWN _PASCAL_CALL;             \
96         void NAME##_space_write_multi_##BWN _PASCAL_CALL;       \
97         void NAME##_space_write_region_##BWN _PASCAL_CALL;      \
98         void NAME##_space_set_multi_##BWN _PASCAL_CALL;         \
99         void NAME##_space_set_region_##BWN _PASCAL_CALL;        \
100         void NAME##_space_copy_region_##BWN _PASCAL_CALL;
101
102 #define _BUS_SPACE_CALL_FUNCS(NAME,TYPE,BWN) \
103         TYPE (*##NAME##_read_##BWN) _PASCAL_CALL;               \
104         void (*##NAME##_read_multi_##BWN) _PASCAL_CALL;         \
105         void (*##NAME##_read_region_##BWN) _PASCAL_CALL;        \
106         void (*##NAME##_write_##BWN) _PASCAL_CALL;              \
107         void (*##NAME##_write_multi_##BWN) _PASCAL_CALL;        \
108         void (*##NAME##_write_region_##BWN) _PASCAL_CALL;       \
109         void (*##NAME##_set_multi_##BWN) _PASCAL_CALL;          \
110         void (*##NAME##_set_region_##BWN) _PASCAL_CALL;         \
111         void (*##NAME##_copy_region_##BWN) _PASCAL_CALL;        
112
113 struct bus_space_access_methods {
114         /* 8 bits access methods */
115         _BUS_SPACE_CALL_FUNCS(bs,u_int8_t,1)
116
117         /* 16 bits access methods */
118         _BUS_SPACE_CALL_FUNCS(bs,u_int16_t,2)
119
120         /* 32 bits access methods */
121         _BUS_SPACE_CALL_FUNCS(bs,u_int32_t,4)
122 };
123
124 struct bus_space_tag {
125 #define BUS_SPACE_IO    0
126 #define BUS_SPACE_MEM   1
127         u_int   bs_tag;                 /* bus space flags */
128
129         struct bus_space_access_methods bs_da;  /* direct access */
130         struct bus_space_access_methods bs_ra;  /* relocate access */
131 #if     0
132         struct bus_space_access_methods bs_ida; /* indexed direct access */
133 #endif
134 };
135 typedef struct bus_space_tag *bus_space_tag_t;
136
137 /*
138  * Values for the i386 bus space tag, not to be used directly by MI code.
139  */
140 extern struct bus_space_tag SBUS_io_space_tag;
141 extern struct bus_space_tag SBUS_mem_space_tag;
142
143 #define I386_BUS_SPACE_IO       (&SBUS_io_space_tag)
144 #define I386_BUS_SPACE_MEM      (&SBUS_mem_space_tag)
145
146 /*
147  * bus space handle
148  */
149 struct bus_space_handle {
150         bus_addr_t      bsh_base;
151         size_t          bsh_sz;
152
153         bus_addr_t      bsh_iat[BUS_SPACE_IAT_MAXSIZE];
154         size_t          bsh_maxiatsz;
155         size_t          bsh_iatsz;
156
157         struct resource **bsh_res;
158         size_t          bsh_ressz;
159
160         struct bus_space_access_methods bsh_bam;
161 };
162 typedef struct bus_space_handle *bus_space_handle_t;
163
164 /*
165  * Allocate/Free bus_space_handle
166  */
167 int i386_bus_space_handle_alloc(bus_space_tag_t t, bus_addr_t bpa,
168                                 bus_size_t size, bus_space_handle_t *bshp);
169 void i386_bus_space_handle_free(bus_space_tag_t t, bus_space_handle_t bsh,
170                                 size_t size);
171
172 /*
173  *      int bus_space_unmap (bus_space_tag_t t,
174  *          bus_space_handle_t bsh, bus_size_t size);
175  *
176  * Unmap a region of bus space.
177  */
178
179 void i386_memio_unmap(bus_space_tag_t t, bus_space_handle_t bsh,
180                        bus_size_t size);
181
182 #define bus_space_unmap(t, h, s)                                        \
183         i386_memio_unmap((t), (h), (s))
184
185 /*
186  *      int bus_space_subregion (bus_space_tag_t t,
187  *          bus_space_handle_t bsh, bus_size_t offset, bus_size_t size,
188  *          bus_space_handle_t *nbshp);
189  *
190  * Get a new handle for a subregion of an already-mapped area of bus space.
191  */
192
193 int i386_memio_subregion(bus_space_tag_t t, bus_space_handle_t bsh,
194                          bus_size_t offset, bus_size_t size,
195                          bus_space_handle_t *nbshp);
196
197 #define bus_space_subregion(t, h, o, s, nhp)                            \
198         i386_memio_subregion((t), (h), (o), (s), (nhp))
199
200 /*
201  *      int bus_space_free (bus_space_tag_t t,
202  *          bus_space_handle_t bsh, bus_size_t size);
203  *
204  * Free a region of bus space.
205  */
206
207 void i386_memio_free(bus_space_tag_t t, bus_space_handle_t bsh,
208                      bus_size_t size);
209
210 #define bus_space_free(t, h, s)                                         \
211         i386_memio_free((t), (h), (s))
212
213 /*
214  * Access methods for bus resources and address space.
215  */
216 #define _BUS_ACCESS_METHODS_PROTO(TYPE,BWN) \
217         static __inline TYPE bus_space_read_##BWN                       \
218         __P((bus_space_tag_t, bus_space_handle_t, bus_size_t offset));  \
219         static __inline void bus_space_read_multi_##BWN                 \
220         __P((bus_space_tag_t, bus_space_handle_t,                       \
221              bus_size_t, TYPE *, size_t));                              \
222         static __inline void bus_space_read_region_##BWN                \
223         __P((bus_space_tag_t, bus_space_handle_t,                       \
224              bus_size_t, TYPE *, size_t));                              \
225         static __inline void bus_space_write_##BWN                      \
226         __P((bus_space_tag_t, bus_space_handle_t, bus_size_t, TYPE));   \
227         static __inline void bus_space_write_multi_##BWN                \
228         __P((bus_space_tag_t, bus_space_handle_t,                       \
229              bus_size_t, const TYPE *, size_t));                        \
230         static __inline void bus_space_write_region_##BWN               \
231         __P((bus_space_tag_t, bus_space_handle_t,                       \
232              bus_size_t, const TYPE *, size_t));                        \
233         static __inline void bus_space_set_multi_##BWN                  \
234         __P((bus_space_tag_t, bus_space_handle_t, bus_size_t, TYPE, size_t));\
235         static __inline void bus_space_set_region_##BWN                 \
236         __P((bus_space_tag_t, bus_space_handle_t, bus_size_t, TYPE, size_t));\
237         static __inline void bus_space_copy_region_##BWN                \
238         __P((bus_space_tag_t, bus_space_handle_t, bus_size_t,           \
239              bus_space_handle_t, bus_size_t, size_t));
240
241 _BUS_ACCESS_METHODS_PROTO(u_int8_t,1)
242 _BUS_ACCESS_METHODS_PROTO(u_int16_t,2)
243 _BUS_ACCESS_METHODS_PROTO(u_int32_t,4)
244
245 /*
246  * read methods
247  */
248 #define _BUS_SPACE_READ(TYPE,BWN)                               \
249 static __inline TYPE                                            \
250 bus_space_read_##BWN##(tag, bsh, offset)                        \
251         bus_space_tag_t tag;                                    \
252         bus_space_handle_t bsh;                                 \
253         bus_size_t offset;                                      \
254 {                                                               \
255         register TYPE result;                                   \
256                                                                 \
257         __asm __volatile("call *%2"                             \
258                         :"=a" (result),                         \
259                          "=d" (offset)                          \
260                         :"o" (bsh->bsh_bam.bs_read_##BWN),      \
261                          "b" (bsh),                             \
262                          "1" (offset)                           \
263                         );                                      \
264                                                                 \
265         return result;                                          \
266 }
267
268 _BUS_SPACE_READ(u_int8_t,1)
269 _BUS_SPACE_READ(u_int16_t,2)
270 _BUS_SPACE_READ(u_int32_t,4)
271
272 /*
273  * write methods
274  */
275 #define _BUS_SPACE_WRITE(TYPE,BWN)                              \
276 static __inline void                                            \
277 bus_space_write_##BWN##(tag, bsh, offset, val)                  \
278         bus_space_tag_t tag;                                    \
279         bus_space_handle_t bsh;                                 \
280         bus_size_t offset;                                      \
281         TYPE val;                                               \
282 {                                                               \
283                                                                 \
284         __asm __volatile("call *%1"                             \
285                         :"=d" (offset)                          \
286                         :"o" (bsh->bsh_bam.bs_write_##BWN),     \
287                          "a" (val),                             \
288                          "b" (bsh),                             \
289                          "0" (offset)                           \
290                         );                                      \
291 }                                                               
292
293 _BUS_SPACE_WRITE(u_int8_t,1)
294 _BUS_SPACE_WRITE(u_int16_t,2)
295 _BUS_SPACE_WRITE(u_int32_t,4)
296
297 /*
298  * multi read
299  */
300 #define _BUS_SPACE_READ_MULTI(TYPE,BWN)                                 \
301 static __inline void                                                    \
302 bus_space_read_multi_##BWN##(tag, bsh, offset, buf, cnt)                \
303         bus_space_tag_t tag;                                            \
304         bus_space_handle_t bsh;                                         \
305         bus_size_t offset;                                              \
306         TYPE *buf;                                                      \
307         size_t cnt;                                                     \
308 {                                                                       \
309                                                                         \
310         __asm __volatile("call *%3"                                     \
311                         :"=c" (cnt),                                    \
312                          "=d" (offset),                                 \
313                          "=D" (buf)                                     \
314                         :"o" (bsh->bsh_bam.bs_read_multi_##BWN),        \
315                          "b" (bsh),                                     \
316                          "0" (cnt),                                     \
317                          "1" (offset),                                  \
318                          "2" (buf)                                      \
319                         :"memory");                                     \
320 }
321
322 _BUS_SPACE_READ_MULTI(u_int8_t,1)
323 _BUS_SPACE_READ_MULTI(u_int16_t,2)
324 _BUS_SPACE_READ_MULTI(u_int32_t,4)
325
326 /*
327  * multi write
328  */
329 #define _BUS_SPACE_WRITE_MULTI(TYPE,BWN)                                \
330 static __inline void                                                    \
331 bus_space_write_multi_##BWN##(tag, bsh, offset, buf, cnt)               \
332         bus_space_tag_t tag;                                            \
333         bus_space_handle_t bsh;                                         \
334         bus_size_t offset;                                              \
335         const TYPE *buf;                                                \
336         size_t cnt;                                                     \
337 {                                                                       \
338                                                                         \
339         __asm __volatile("call *%3"                                     \
340                         :"=c" (cnt),                                    \
341                          "=d" (offset),                                 \
342                          "=S" (buf)                                     \
343                         :"o" (bsh->bsh_bam.bs_write_multi_##BWN),       \
344                          "b" (bsh),                                     \
345                          "0" (cnt),                                     \
346                          "1" (offset),                                  \
347                          "2" (buf)                                      \
348                         );                                              \
349 }
350
351 _BUS_SPACE_WRITE_MULTI(u_int8_t,1)
352 _BUS_SPACE_WRITE_MULTI(u_int16_t,2)
353 _BUS_SPACE_WRITE_MULTI(u_int32_t,4)
354
355 /*
356  * region read
357  */
358 #define _BUS_SPACE_READ_REGION(TYPE,BWN)                                \
359 static __inline void                                                    \
360 bus_space_read_region_##BWN##(tag, bsh, offset, buf, cnt)               \
361         bus_space_tag_t tag;                                            \
362         bus_space_handle_t bsh;                                         \
363         bus_size_t offset;                                              \
364         TYPE *buf;                                              \
365         size_t cnt;                                                     \
366 {                                                                       \
367                                                                         \
368         __asm __volatile("call *%3"                                     \
369                         :"=c" (cnt),                                    \
370                          "=d" (offset),                                 \
371                          "=D" (buf)                                     \
372                         :"o" (bsh->bsh_bam.bs_read_region_##BWN),       \
373                          "b" (bsh),                                     \
374                          "0" (cnt),                                     \
375                          "1" (offset),                                  \
376                          "2" (buf)                                      \
377                         :"memory");                                     \
378 }
379
380 _BUS_SPACE_READ_REGION(u_int8_t,1)
381 _BUS_SPACE_READ_REGION(u_int16_t,2)
382 _BUS_SPACE_READ_REGION(u_int32_t,4)
383
384 /*
385  * region write
386  */
387 #define _BUS_SPACE_WRITE_REGION(TYPE,BWN)                               \
388 static __inline void                                                    \
389 bus_space_write_region_##BWN##(tag, bsh, offset, buf, cnt)              \
390         bus_space_tag_t tag;                                            \
391         bus_space_handle_t bsh;                                         \
392         bus_size_t offset;                                              \
393         const TYPE *buf;                                                \
394         size_t cnt;                                                     \
395 {                                                                       \
396                                                                         \
397         __asm __volatile("call *%3"                                     \
398                         :"=c" (cnt),                                    \
399                          "=d" (offset),                                 \
400                          "=S" (buf)                                     \
401                         :"o" (bsh->bsh_bam.bs_write_region_##BWN),      \
402                          "b" (bsh),                                     \
403                          "0" (cnt),                                     \
404                          "1" (offset),                                  \
405                          "2" (buf)                                      \
406                         );                                              \
407 }
408
409 _BUS_SPACE_WRITE_REGION(u_int8_t,1)
410 _BUS_SPACE_WRITE_REGION(u_int16_t,2)
411 _BUS_SPACE_WRITE_REGION(u_int32_t,4)
412
413 /*
414  * multi set
415  */
416 #define _BUS_SPACE_SET_MULTI(TYPE,BWN)                                  \
417 static __inline void                                                    \
418 bus_space_set_multi_##BWN##(tag, bsh, offset, val, cnt)                 \
419         bus_space_tag_t tag;                                            \
420         bus_space_handle_t bsh;                                         \
421         bus_size_t offset;                                              \
422         TYPE val;                                                       \
423         size_t cnt;                                                     \
424 {                                                                       \
425                                                                         \
426         __asm __volatile("call *%2"                                     \
427                         :"=c" (cnt),                                    \
428                          "=d" (offset)                                  \
429                         :"o" (bsh->bsh_bam.bs_set_multi_##BWN),         \
430                          "a" (val),                                     \
431                          "b" (bsh),                                     \
432                          "0" (cnt),                                     \
433                          "1" (offset)                                   \
434                         );                                              \
435 }
436
437 _BUS_SPACE_SET_MULTI(u_int8_t,1)
438 _BUS_SPACE_SET_MULTI(u_int16_t,2)
439 _BUS_SPACE_SET_MULTI(u_int32_t,4)
440
441 /*
442  * region set
443  */
444 #define _BUS_SPACE_SET_REGION(TYPE,BWN)                                 \
445 static __inline void                                                    \
446 bus_space_set_region_##BWN##(tag, bsh, offset, val, cnt)                \
447         bus_space_tag_t tag;                                            \
448         bus_space_handle_t bsh;                                         \
449         bus_size_t offset;                                              \
450         TYPE val;                                                       \
451         size_t cnt;                                                     \
452 {                                                                       \
453                                                                         \
454         __asm __volatile("call *%2"                                     \
455                         :"=c" (cnt),                                    \
456                          "=d" (offset)                                  \
457                         :"o" (bsh->bsh_bam.bs_set_region_##BWN),        \
458                          "a" (val),                                     \
459                          "b" (bsh),                                     \
460                          "0" (cnt),                                     \
461                          "1" (offset)                                   \
462                         );                                              \
463 }
464
465 _BUS_SPACE_SET_REGION(u_int8_t,1)
466 _BUS_SPACE_SET_REGION(u_int16_t,2)
467 _BUS_SPACE_SET_REGION(u_int32_t,4)
468
469 /*
470  * copy
471  */
472 #define _BUS_SPACE_COPY_REGION(BWN)                                     \
473 static __inline void                                                    \
474 bus_space_copy_region_##BWN##(tag, sbsh, src, dbsh, dst, cnt)           \
475         bus_space_tag_t tag;                                            \
476         bus_space_handle_t sbsh;                                        \
477         bus_size_t src;                                                 \
478         bus_space_handle_t dbsh;                                        \
479         bus_size_t dst;                                                 \
480         size_t cnt;                                                     \
481 {                                                                       \
482                                                                         \
483         if (dbsh->bsh_bam.bs_copy_region_1 != sbsh->bsh_bam.bs_copy_region_1) \
484                 panic("bus_space_copy_region: funcs mismatch (ENOSUPPORT)");\
485                                                                         \
486         __asm __volatile("call *%3"                                     \
487                         :"=c" (cnt),                                    \
488                          "=S" (src),                                    \
489                          "=D" (dst)                                     \
490                         :"o" (dbsh->bsh_bam.bs_copy_region_##BWN),      \
491                          "a" (sbsh),                                    \
492                          "b" (dbsh),                                    \
493                          "0" (cnt),                                     \
494                          "1" (src),                                     \
495                          "2" (dst)                                      \
496                         );                                              \
497 }
498
499 _BUS_SPACE_COPY_REGION(1)
500 _BUS_SPACE_COPY_REGION(2)
501 _BUS_SPACE_COPY_REGION(4)
502
503 /*
504  * Bus read/write barrier methods.
505  *
506  *      void bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh,
507  *                             bus_size_t offset, bus_size_t len, int flags);
508  *
509  * Note: the i386 does not currently require barriers, but we must
510  * provide the flags to MI code.
511  */
512 #define bus_space_barrier(t, h, o, l, f)        \
513         ((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f)))
514 #define BUS_SPACE_BARRIER_READ  0x01            /* force read barrier */
515 #define BUS_SPACE_BARRIER_WRITE 0x02            /* force write barrier */
516
517 #endif /* _I386_BUS_PC98_H_ */