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);