1 /* $FreeBSD: releng/5.3/sys/i386/include/bus_pc98.h 128910 2004-05-04 06:38:13Z nyan $ */
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 33
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_map (bus_space_tag_t t, bus_addr_t addr,
174 * bus_size_t size, int flag, bus_space_handle_t *bshp);
175 *
176 * Map a region of bus space.
177 */
178
179 int i386_memio_map(bus_space_tag_t t, bus_addr_t addr, bus_size_t size,
180 int flag, bus_space_handle_t *bshp);
181
182 #define bus_space_map(t, a, s, f, hp) \
183 i386_memio_map((t), (a), (s), (f), (hp))
184
185 /*
186 * int bus_space_unmap (bus_space_tag_t t,
187 * bus_space_handle_t bsh, bus_size_t size);
188 *
189 * Unmap a region of bus space.
190 */
191
192 void i386_memio_unmap(bus_space_tag_t t, bus_space_handle_t bsh,
193 bus_size_t size);
194
195 #define bus_space_unmap(t, h, s) \
196 i386_memio_unmap((t), (h), (s))
197
198 /*
199 * int bus_space_subregion (bus_space_tag_t t,
200 * bus_space_handle_t bsh, bus_size_t offset, bus_size_t size,
201 * bus_space_handle_t *nbshp);
202 *
203 * Get a new handle for a subregion of an already-mapped area of bus space.
204 */
205
206 int i386_memio_subregion(bus_space_tag_t t, bus_space_handle_t bsh,
207 bus_size_t offset, bus_size_t size,
208 bus_space_handle_t *nbshp);
209
210 #define bus_space_subregion(t, h, o, s, nhp) \
211 i386_memio_subregion((t), (h), (o), (s), (nhp))
212
213 /*
214 * int bus_space_free (bus_space_tag_t t,
215 * bus_space_handle_t bsh, bus_size_t size);
216 *
217 * Free a region of bus space.
218 */
219
220 void i386_memio_free(bus_space_tag_t t, bus_space_handle_t bsh,
221 bus_size_t size);
222
223 #define bus_space_free(t, h, s) \
224 i386_memio_free((t), (h), (s))
225
226 /*
227 * Access methods for bus resources and address space.
228 */
229 #define _BUS_ACCESS_METHODS_PROTO(TYPE,BWN) \
230 static __inline TYPE bus_space_read_##BWN \
231 (bus_space_tag_t, bus_space_handle_t, bus_size_t offset); \
232 static __inline void bus_space_read_multi_##BWN \
233 (bus_space_tag_t, bus_space_handle_t, \
234 bus_size_t, TYPE *, size_t); \
235 static __inline void bus_space_read_region_##BWN \
236 (bus_space_tag_t, bus_space_handle_t, \
237 bus_size_t, TYPE *, size_t); \
238 static __inline void bus_space_write_##BWN \
239 (bus_space_tag_t, bus_space_handle_t, bus_size_t, TYPE); \
240 static __inline void bus_space_write_multi_##BWN \
241 (bus_space_tag_t, bus_space_handle_t, \
242 bus_size_t, const TYPE *, size_t); \
243 static __inline void bus_space_write_region_##BWN \
244 (bus_space_tag_t, bus_space_handle_t, \
245 bus_size_t, const TYPE *, size_t); \
246 static __inline void bus_space_set_multi_##BWN \
247 (bus_space_tag_t, bus_space_handle_t, bus_size_t, TYPE, size_t);\
248 static __inline void bus_space_set_region_##BWN \
249 (bus_space_tag_t, bus_space_handle_t, bus_size_t, TYPE, size_t);\
250 static __inline void bus_space_copy_region_##BWN \
251 (bus_space_tag_t, bus_space_handle_t, bus_size_t, \
252 bus_space_handle_t, bus_size_t, size_t);
253
254 _BUS_ACCESS_METHODS_PROTO(u_int8_t,1)
255 _BUS_ACCESS_METHODS_PROTO(u_int16_t,2)
256 _BUS_ACCESS_METHODS_PROTO(u_int32_t,4)
257
258 /*
259 * read methods
260 */
261 #define _BUS_SPACE_READ(TYPE,BWN) \
262 static __inline TYPE \
263 bus_space_read_##BWN (tag, bsh, offset) \
264 bus_space_tag_t tag; \
265 bus_space_handle_t bsh; \
266 bus_size_t offset; \
267 { \
268 register TYPE result; \
269 \
270 __asm __volatile("call *%2" \
271 :"=a" (result), \
272 "=d" (offset) \
273 :"o" (bsh->bsh_bam.bs_read_##BWN), \
274 "b" (bsh), \
275 "1" (offset) \
276 ); \
277 \
278 return result; \
279 }
280
281 _BUS_SPACE_READ(u_int8_t,1)
282 _BUS_SPACE_READ(u_int16_t,2)
283 _BUS_SPACE_READ(u_int32_t,4)
284
285 /*
286 * write methods
287 */
288 #define _BUS_SPACE_WRITE(TYPE,BWN) \
289 static __inline void \
290 bus_space_write_##BWN (tag, bsh, offset, val) \
291 bus_space_tag_t tag; \
292 bus_space_handle_t bsh; \
293 bus_size_t offset; \
294 TYPE val; \
295 { \
296 \
297 __asm __volatile("call *%1" \
298 :"=d" (offset) \
299 :"o" (bsh->bsh_bam.bs_write_##BWN), \
300 "a" (val), \
301 "b" (bsh), \
302 "" (offset) \
303 ); \
304 }
305
306 _BUS_SPACE_WRITE(u_int8_t,1)
307 _BUS_SPACE_WRITE(u_int16_t,2)
308 _BUS_SPACE_WRITE(u_int32_t,4)
309
310 /*
311 * multi read
312 */
313 #define _BUS_SPACE_READ_MULTI(TYPE,BWN) \
314 static __inline void \
315 bus_space_read_multi_##BWN (tag, bsh, offset, buf, cnt) \
316 bus_space_tag_t tag; \
317 bus_space_handle_t bsh; \
318 bus_size_t offset; \
319 TYPE *buf; \
320 size_t cnt; \
321 { \
322 \
323 __asm __volatile("call *%3" \
324 :"=c" (cnt), \
325 "=d" (offset), \
326 "=D" (buf) \
327 :"o" (bsh->bsh_bam.bs_read_multi_##BWN), \
328 "b" (bsh), \
329 "" (cnt), \
330 "1" (offset), \
331 "2" (buf) \
332 :"memory"); \
333 }
334
335 _BUS_SPACE_READ_MULTI(u_int8_t,1)
336 _BUS_SPACE_READ_MULTI(u_int16_t,2)
337 _BUS_SPACE_READ_MULTI(u_int32_t,4)
338
339 /*
340 * multi write
341 */
342 #define _BUS_SPACE_WRITE_MULTI(TYPE,BWN) \
343 static __inline void \
344 bus_space_write_multi_##BWN (tag, bsh, offset, buf, cnt) \
345 bus_space_tag_t tag; \
346 bus_space_handle_t bsh; \
347 bus_size_t offset; \
348 const TYPE *buf; \
349 size_t cnt; \
350 { \
351 \
352 __asm __volatile("call *%3" \
353 :"=c" (cnt), \
354 "=d" (offset), \
355 "=S" (buf) \
356 :"o" (bsh->bsh_bam.bs_write_multi_##BWN), \
357 "b" (bsh), \
358 "" (cnt), \
359 "1" (offset), \
360 "2" (buf) \
361 ); \
362 }
363
364 _BUS_SPACE_WRITE_MULTI(u_int8_t,1)
365 _BUS_SPACE_WRITE_MULTI(u_int16_t,2)
366 _BUS_SPACE_WRITE_MULTI(u_int32_t,4)
367
368 /*
369 * region read
370 */
371 #define _BUS_SPACE_READ_REGION(TYPE,BWN) \
372 static __inline void \
373 bus_space_read_region_##BWN (tag, bsh, offset, buf, cnt) \
374 bus_space_tag_t tag; \
375 bus_space_handle_t bsh; \
376 bus_size_t offset; \
377 TYPE *buf; \
378 size_t cnt; \
379 { \
380 \
381 __asm __volatile("call *%3" \
382 :"=c" (cnt), \
383 "=d" (offset), \
384 "=D" (buf) \
385 :"o" (bsh->bsh_bam.bs_read_region_##BWN), \
386 "b" (bsh), \
387 "" (cnt), \
388 "1" (offset), \
389 "2" (buf) \
390 :"memory"); \
391 }
392
393 _BUS_SPACE_READ_REGION(u_int8_t,1)
394 _BUS_SPACE_READ_REGION(u_int16_t,2)
395 _BUS_SPACE_READ_REGION(u_int32_t,4)
396
397 /*
398 * region write
399 */
400 #define _BUS_SPACE_WRITE_REGION(TYPE,BWN) \
401 static __inline void \
402 bus_space_write_region_##BWN (tag, bsh, offset, buf, cnt) \
403 bus_space_tag_t tag; \
404 bus_space_handle_t bsh; \
405 bus_size_t offset; \
406 const TYPE *buf; \
407 size_t cnt; \
408 { \
409 \
410 __asm __volatile("call *%3" \
411 :"=c" (cnt), \
412 "=d" (offset), \
413 "=S" (buf) \
414 :"o" (bsh->bsh_bam.bs_write_region_##BWN), \
415 "b" (bsh), \
416 "" (cnt), \
417 "1" (offset), \
418 "2" (buf) \
419 ); \
420 }
421
422 _BUS_SPACE_WRITE_REGION(u_int8_t,1)
423 _BUS_SPACE_WRITE_REGION(u_int16_t,2)
424 _BUS_SPACE_WRITE_REGION(u_int32_t,4)
425
426 /*
427 * multi set
428 */
429 #define _BUS_SPACE_SET_MULTI(TYPE,BWN) \
430 static __inline void \
431 bus_space_set_multi_##BWN (tag, bsh, offset, val, cnt) \
432 bus_space_tag_t tag; \
433 bus_space_handle_t bsh; \
434 bus_size_t offset; \
435 TYPE val; \
436 size_t cnt; \
437 { \
438 \
439 __asm __volatile("call *%2" \
440 :"=c" (cnt), \
441 "=d" (offset) \
442 :"o" (bsh->bsh_bam.bs_set_multi_##BWN), \
443 "a" (val), \
444 "b" (bsh), \
445 "" (cnt), \
446 "1" (offset) \
447 ); \
448 }
449
450 _BUS_SPACE_SET_MULTI(u_int8_t,1)
451 _BUS_SPACE_SET_MULTI(u_int16_t,2)
452 _BUS_SPACE_SET_MULTI(u_int32_t,4)
453
454 /*
455 * region set
456 */
457 #define _BUS_SPACE_SET_REGION(TYPE,BWN) \
458 static __inline void \
459 bus_space_set_region_##BWN (tag, bsh, offset, val, cnt) \
460 bus_space_tag_t tag; \
461 bus_space_handle_t bsh; \
462 bus_size_t offset; \
463 TYPE val; \
464 size_t cnt; \
465 { \
466 \
467 __asm __volatile("call *%2" \
468 :"=c" (cnt), \
469 "=d" (offset) \
470 :"o" (bsh->bsh_bam.bs_set_region_##BWN), \
471 "a" (val), \
472 "b" (bsh), \
473 "" (cnt), \
474 "1" (offset) \
475 ); \
476 }
477
478 _BUS_SPACE_SET_REGION(u_int8_t,1)
479 _BUS_SPACE_SET_REGION(u_int16_t,2)
480 _BUS_SPACE_SET_REGION(u_int32_t,4)
481
482 /*
483 * copy
484 */
485 #define _BUS_SPACE_COPY_REGION(BWN) \
486 static __inline void \
487 bus_space_copy_region_##BWN (tag, sbsh, src, dbsh, dst, cnt) \
488 bus_space_tag_t tag; \
489 bus_space_handle_t sbsh; \
490 bus_size_t src; \
491 bus_space_handle_t dbsh; \
492 bus_size_t dst; \
493 size_t cnt; \
494 { \
495 \
496 if (dbsh->bsh_bam.bs_copy_region_1 != sbsh->bsh_bam.bs_copy_region_1) \
497 panic("bus_space_copy_region: funcs mismatch (ENOSUPPORT)");\
498 \
499 __asm __volatile("call *%3" \
500 :"=c" (cnt), \
501 "=S" (src), \
502 "=D" (dst) \
503 :"o" (dbsh->bsh_bam.bs_copy_region_##BWN), \
504 "a" (sbsh), \
505 "b" (dbsh), \
506 "" (cnt), \
507 "1" (src), \
508 "2" (dst) \
509 ); \
510 }
511
512 _BUS_SPACE_COPY_REGION(1)
513 _BUS_SPACE_COPY_REGION(2)
514 _BUS_SPACE_COPY_REGION(4)
515
516 /*
517 * Bus read/write barrier methods.
518 *
519 * void bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh,
520 * bus_size_t offset, bus_size_t len, int flags);
521 *
522 *
523 * Note that BUS_SPACE_BARRIER_WRITE doesn't do anything other than
524 * prevent reordering by the compiler; all Intel x86 processors currently
525 * retire operations outside the CPU in program order.
526 */
527 #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */
528 #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */
529
530 static __inline void
531 bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh,
532 bus_size_t offset, bus_size_t len, int flags)
533 {
534 if (flags & BUS_SPACE_BARRIER_READ)
535 __asm __volatile("lock; addl $0,0(%%esp)" : : : "memory");
536 else
537 __asm __volatile("" : : : "memory");
538 }
539
540 #endif /* _I386_BUS_PC98_H_ */
Cache object: bc585b7d81d991f663077809e8d6fccd
|