2 * Copyright (c) 1992, 1993, 1996
3 * Berkeley Software Design, Inc. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Berkeley Software
18 * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * BSDI port.c,v 2.2 1996/04/08 19:33:03 bostic Exp
32 * $FreeBSD: src/usr.bin/doscmd/port.c,v 1.5.2.1 2002/04/25 11:04:51 tg Exp $
33 * $DragonFly: src/usr.bin/doscmd/port.c,v 1.6 2005/04/10 20:55:38 drhodus Exp $
36 #include <sys/ioctl.h>
37 #include <machine/sysarch.h>
43 #define MAXPORT_MASK (MAXPORT - 1)
49 asm volatile ("xorl %%eax,%%eax; inb %%dx,%%al" : \
50 "=a" (_inb_result) : "d" (port)); \
54 #define out(port, data) \
55 asm volatile ("outb %%al,%%dx" : : "a" (data), "d" (port))
58 u_long ioports
[MAXPORT
/32];
61 iomap(int port
, int cnt
)
63 if (port
+ cnt
>= MAXPORT
) {
67 if (i386_set_ioperm(port
, cnt
, 1) < 0) {
75 iounmap(int port
, int cnt
)
77 if (port
+ cnt
>= MAXPORT
) {
81 if (i386_set_ioperm(port
, cnt
, 0) < 0) {
89 iomap(int port
, int cnt
)
92 if (port
+ cnt
>= MAXPORT
) {
97 ioports
[port
/32] |= (1 << (port
%32));
100 if (i386_set_ioperm(ioports
) < 0) {
108 iounmap(int port
, int cnt
)
111 if (port
+ cnt
>= MAXPORT
) {
116 ioports
[port
/32] &= ~(1 << (port
%32));
119 if (i386_set_ioperm(ioports
) < 0) {
127 outb_traceport(int port
, unsigned char byte
)
130 if (!iolog && !(iolog = fopen("/tmp/iolog", "a")))
133 fprintf(iolog, "0x%03X -> %02X\n", port, byte);
142 inb_traceport(int port
)
147 if (!iolog && !(iolog = fopen("/tmp/iolog", "a")))
156 fprintf(iolog, "0x%03X <- %02X\n", port, byte);
163 * Real input/output to (hopefully) iomapped port
166 outb_port(int port
, unsigned char byte
)
178 * Fake input/output ports
182 outb_nullport(int port __unused
, unsigned char byte __unused
)
185 debug(D_PORT, "outb_nullport called for port 0x%03X = 0x%02X.\n",
191 inb_nullport(int port __unused
)
194 debug(D_PORT, "inb_nullport called for port 0x%03X.\n", port);
200 * configuration table for ports' emulators
204 unsigned char (*p_inb
)(int port
);
205 void (*p_outb
)(int port
, unsigned char byte
);
209 init_io_port_handlers(void)
213 for (i
= 0; i
< MAXPORT
; i
++) {
214 if (portsw
[i
].p_inb
== 0)
215 portsw
[i
].p_inb
= inb_nullport
;
216 if (portsw
[i
].p_outb
== 0)
217 portsw
[i
].p_outb
= outb_nullport
;
223 define_input_port_handler(int port
, unsigned char (*p_inb
)(int port
))
225 if ((port
>= MINPORT
) && (port
< MAXPORT
)) {
226 portsw
[port
].p_inb
= p_inb
;
228 fprintf (stderr
, "attempt to handle invalid port 0x%04x", port
);
232 define_output_port_handler(int port
, void (*p_outb
)(int port
, unsigned char byte
))
234 if ((port
>= MINPORT
) && (port
< MAXPORT
)) {
235 portsw
[port
].p_outb
= p_outb
;
237 fprintf (stderr
, "attempt to handle invalid port 0x%04x", port
);
242 inb(regcontext_t
*REGS
, int port
)
244 unsigned char (*in_handler
)(int);
246 if ((port
>= MINPORT
) && (port
< MAXPORT
))
247 in_handler
= portsw
[port
].p_inb
;
249 in_handler
= inb_nullport
;
250 R_AL
= (*in_handler
)(port
);
251 debug(D_PORT
, "IN on port %02x -> %02x\n", port
, R_AL
);
255 insb(regcontext_t
*REGS
, int port
)
257 unsigned char (*in_handler
)(int);
260 if ((port
>= MINPORT
) && (port
< MAXPORT
))
261 in_handler
= portsw
[port
].p_inb
;
263 in_handler
= inb_nullport
;
264 data
= (*in_handler
)(port
);
265 *(u_char
*)MAKEPTR(R_ES
, R_DI
) = data
;
266 debug(D_PORT
, "INS on port %02x -> %02x\n", port
, data
);
275 inx(regcontext_t
*REGS
, int port
)
277 unsigned char (*in_handler
)(int);
279 if ((port
>= MINPORT
) && (port
< MAXPORT
))
280 in_handler
= portsw
[port
].p_inb
;
282 in_handler
= inb_nullport
;
283 R_AL
= (*in_handler
)(port
);
284 if ((port
>= MINPORT
) && (port
< MAXPORT
))
285 in_handler
= portsw
[port
+ 1].p_inb
;
287 in_handler
= inb_nullport
;
288 R_AH
= (*in_handler
)(port
+ 1);
289 debug(D_PORT
, "IN on port %02x -> %04x\n", port
, R_AX
);
293 insx(regcontext_t
*REGS
, int port
)
295 unsigned char (*in_handler
)(int);
298 if ((port
>= MINPORT
) && (port
< MAXPORT
))
299 in_handler
= portsw
[port
].p_inb
;
301 in_handler
= inb_nullport
;
302 data
= (*in_handler
)(port
);
303 *(u_char
*)MAKEPTR(R_ES
, R_DI
) = data
;
304 debug(D_PORT
, "INS on port %02x -> %02x\n", port
, data
);
306 if ((port
>= MINPORT
) && (port
< MAXPORT
))
307 in_handler
= portsw
[port
+ 1].p_inb
;
309 in_handler
= inb_nullport
;
310 data
= (*in_handler
)(port
+ 1);
311 ((u_char
*)MAKEPTR(R_ES
, R_DI
))[1] = data
;
312 debug(D_PORT
, "INS on port %02x -> %02x\n", port
, data
);
321 outb(regcontext_t
*REGS
, int port
)
323 void (*out_handler
)(int, unsigned char);
325 if ((port
>= MINPORT
) && (port
< MAXPORT
))
326 out_handler
= portsw
[port
].p_outb
;
328 out_handler
= outb_nullport
;
329 (*out_handler
)(port
, R_AL
);
330 debug(D_PORT
, "OUT on port %02x <- %02x\n", port
, R_AL
);
332 if (port == 0x3bc && R_AL == 0x55)
338 outx(regcontext_t
*REGS
, int port
)
340 void (*out_handler
)(int, unsigned char);
342 if ((port
>= MINPORT
) && (port
< MAXPORT
))
343 out_handler
= portsw
[port
].p_outb
;
345 out_handler
= outb_nullport
;
346 (*out_handler
)(port
, R_AL
);
347 debug(D_PORT
, "OUT on port %02x <- %02x\n", port
, R_AL
);
348 if ((port
>= MINPORT
) && (port
< MAXPORT
))
349 out_handler
= portsw
[port
+ 1].p_outb
;
351 out_handler
= outb_nullport
;
352 (*out_handler
)(port
+ 1, R_AH
);
353 debug(D_PORT
, "OUT on port %02x <- %02x\n", port
+ 1, R_AH
);
357 outsb(regcontext_t
*REGS
, int port
)
359 void (*out_handler
)(int, unsigned char);
362 if ((port
>= MINPORT
) && (port
< MAXPORT
))
363 out_handler
= portsw
[port
].p_outb
;
365 out_handler
= outb_nullport
;
366 value
= *(u_char
*)MAKEPTR(R_ES
, R_DI
);
367 debug(D_PORT
, "OUT on port %02x <- %02x\n", port
, value
);
368 (*out_handler
)(port
, value
);
377 outsx(regcontext_t
*REGS
, int port
)
379 void (*out_handler
)(int, unsigned char);
382 if ((port
>= MINPORT
) && (port
< MAXPORT
))
383 out_handler
= portsw
[port
].p_outb
;
385 out_handler
= outb_nullport
;
386 value
= *(u_char
*)MAKEPTR(R_ES
, R_DI
);
387 debug(D_PORT
, "OUT on port %02x <- %02x\n", port
, value
);
388 (*out_handler
)(port
, value
);
390 if ((port
>= MINPORT
) && (port
< MAXPORT
))
391 out_handler
= portsw
[port
+ 1].p_outb
;
393 out_handler
= outb_nullport
;
394 value
= ((u_char
*)MAKEPTR(R_ES
, R_DI
))[1];
395 debug(D_PORT
, "OUT on port %02x <- %02x\n", port
+1, value
);
396 (*out_handler
)(port
+ 1, value
);
404 unsigned char port_61
= 0x10;
406 int sound_freq
= 1000;
409 outb_speaker(int port __unused
, unsigned char byte
)
413 if ((port_61
& 3) != 3) {
414 if ((byte
& 3) == 3 && /* prtim[2].gate && */ sound_on
)
415 ioctl(kbd_fd
, PCCONIOCSTARTBEEP
, &sound_freq
);
416 } else if ((byte
& 3) != 3)
417 ioctl(kbd_fd
, PCCONIOCSTOPBEEP
);
424 inb_speaker(int port __unused
)
426 /* port_61 = (port_61 + 1) & 0xff; */
433 define_input_port_handler(0x61, inb_speaker
);
434 define_output_port_handler(0x61, outb_speaker
);