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