1 /* $FreeBSD: releng/5.1/sys/i386/include/bus_pc98.h 111524 2003-02-26 02:16:06Z mux $ */
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 0xFFFFFFFF
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 (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 (bus_space_tag_t, bus_space_handle_t, bus_size_t offset); \
219 static __inline void bus_space_read_multi_##BWN \
220 (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 (bus_space_tag_t, bus_space_handle_t, \
224 bus_size_t, TYPE *, size_t); \
225 static __inline void bus_space_write_##BWN \
226 (bus_space_tag_t, bus_space_handle_t, bus_size_t, TYPE); \
227 static __inline void bus_space_write_multi_##BWN \
228 (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 (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 (bus_space_tag_t, bus_space_handle_t, bus_size_t, TYPE, size_t);\
235 static __inline void bus_space_set_region_##BWN \
236 (bus_space_tag_t, bus_space_handle_t, bus_size_t, TYPE, size_t);\
237 static __inline void bus_space_copy_region_##BWN \
238 (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 "" (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 "" (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 "" (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 "" (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 "" (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 "" (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 "" (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 "" (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 *
510 * Note that BUS_SPACE_BARRIER_WRITE doesn't do anything other than
511 * prevent reordering by the compiler; all Intel x86 processors currently
512 * retire operations outside the CPU in program order.
513 */
514 #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */
515 #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */
516
517 static __inline void
518 bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh,
519 bus_size_t offset, bus_size_t len, int flags)
520 {
521 if (flags & BUS_SPACE_BARRIER_READ)
522 __asm __volatile("lock; addl $0,0(%%esp)" : : : "memory");
523 else
524 __asm __volatile("" : : : "memory");
525 }
526
527 #endif /* _I386_BUS_PC98_H_ */
Cache object: 58d93036e3ea3c31bd0508a58524a941
|