kernel: Use hashdestroy() to free hash tables allocated with hashinit().
[dragonfly.git] / usr.bin / doscmd / port.c
CommitLineData
984263bc
MD
1/*
2 * Copyright (c) 1992, 1993, 1996
3 * Berkeley Software Design, Inc. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
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
16 * Design, Inc.
17 *
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
28 * SUCH DAMAGE.
29 *
30 * BSDI port.c,v 2.2 1996/04/08 19:33:03 bostic Exp
1de703da
MD
31 *
32 * $FreeBSD: src/usr.bin/doscmd/port.c,v 1.5.2.1 2002/04/25 11:04:51 tg Exp $
984263bc
MD
33 */
34
984263bc
MD
35#include <sys/ioctl.h>
36#include <machine/sysarch.h>
37
38#include "doscmd.h"
39#include "tty.h"
40
41#define MINPORT 0x000
42#define MAXPORT_MASK (MAXPORT - 1)
43
44#define in(port) \
45({ \
e0aca170 46 int _inb_result; \
984263bc
MD
47\
48 asm volatile ("xorl %%eax,%%eax; inb %%dx,%%al" : \
49 "=a" (_inb_result) : "d" (port)); \
50 _inb_result; \
51})
52
53#define out(port, data) \
54 asm volatile ("outb %%al,%%dx" : : "a" (data), "d" (port))
55
678e8cc6 56FILE *iolog = NULL;
984263bc 57u_long ioports[MAXPORT/32];
54775880 58#ifdef __DragonFly__
984263bc
MD
59static void
60iomap(int port, int cnt)
61{
62 if (port + cnt >= MAXPORT) {
63 errno = ERANGE;
64 goto bad;
65 }
66 if (i386_set_ioperm(port, cnt, 1) < 0) {
67 bad:
68 perror("iomap");
69 quit(1);
70 }
71}
72
73static void
74iounmap(int port, int cnt)
75{
76 if (port + cnt >= MAXPORT) {
77 errno = ERANGE;
78 goto bad;
79 }
80 if (i386_set_ioperm(port, cnt, 0) < 0) {
81 bad:
82 perror("iounmap");
83 quit(1);
84 }
85}
86#else
87static void
88iomap(int port, int cnt)
89{
90
91 if (port + cnt >= MAXPORT) {
92 errno = ERANGE;
93 goto bad;
94 }
95 while (cnt--) {
96 ioports[port/32] |= (1 << (port%32));
97 port++;
98 }
99 if (i386_set_ioperm(ioports) < 0) {
100 bad:
101 perror("iomap");
102 quit(1);
103 }
104}
105
106static void
107iounmap(int port, int cnt)
108{
109
110 if (port + cnt >= MAXPORT) {
111 errno = ERANGE;
112 goto bad;
113 }
114 while (cnt--) {
115 ioports[port/32] &= ~(1 << (port%32));
116 port++;
117 }
118 if (i386_set_ioperm(ioports) < 0) {
119 bad:
120 perror("iounmap");
121 quit(1);
122 }
123}
124#endif
125void
126outb_traceport(int port, unsigned char byte)
127{
128/*
129 if (!iolog && !(iolog = fopen("/tmp/iolog", "a")))
130 iolog = stderr;
131
132 fprintf(iolog, "0x%03X -> %02X\n", port, byte);
133 */
134
135 iomap(port, 1);
136 out(port, byte);
137 iounmap(port, 1);
138}
139
140unsigned char
141inb_traceport(int port)
142{
143 unsigned char byte;
144
145/*
146 if (!iolog && !(iolog = fopen("/tmp/iolog", "a")))
147 iolog = stderr;
148 */
149
150 iomap(port, 1);
151 byte = in(port);
152 iounmap(port, 1);
153
154/*
155 fprintf(iolog, "0x%03X <- %02X\n", port, byte);
156 fflush(iolog);
157 */
158 return(byte);
159}
160
161/*
162 * Real input/output to (hopefully) iomapped port
163 */
164void
165outb_port(int port, unsigned char byte)
166{
167 out(port, byte);
168}
169
170unsigned char
171inb_port(int port)
172{
173 return in(port);
174}
175
176/*
177 * Fake input/output ports
178 */
179
180static void
181outb_nullport(int port __unused, unsigned char byte __unused)
182{
183/*
184 debug(D_PORT, "outb_nullport called for port 0x%03X = 0x%02X.\n",
185 port, byte);
186 */
187}
188
189static unsigned char
190inb_nullport(int port __unused)
191{
192/*
193 debug(D_PORT, "inb_nullport called for port 0x%03X.\n", port);
194 */
195 return(0xff);
196}
197
198/*
199 * configuration table for ports' emulators
200 */
201
202struct portsw {
203 unsigned char (*p_inb)(int port);
204 void (*p_outb)(int port, unsigned char byte);
205} portsw[MAXPORT];
206
207void
208init_io_port_handlers(void)
209{
210 int i;
211
212 for (i = 0; i < MAXPORT; i++) {
678e8cc6 213 if (portsw[i].p_inb == NULL)
984263bc 214 portsw[i].p_inb = inb_nullport;
678e8cc6 215 if (portsw[i].p_outb == NULL)
984263bc
MD
216 portsw[i].p_outb = outb_nullport;
217 }
218
219}
220
221void
222define_input_port_handler(int port, unsigned char (*p_inb)(int port))
223{
224 if ((port >= MINPORT) && (port < MAXPORT)) {
225 portsw[port].p_inb = p_inb;
226 } else
227 fprintf (stderr, "attempt to handle invalid port 0x%04x", port);
228}
229
230void
231define_output_port_handler(int port, void (*p_outb)(int port, unsigned char byte))
232{
233 if ((port >= MINPORT) && (port < MAXPORT)) {
234 portsw[port].p_outb = p_outb;
235 } else
236 fprintf (stderr, "attempt to handle invalid port 0x%04x", port);
237}
238
239
240void
241inb(regcontext_t *REGS, int port)
242{
243 unsigned char (*in_handler)(int);
244
245 if ((port >= MINPORT) && (port < MAXPORT))
246 in_handler = portsw[port].p_inb;
247 else
248 in_handler = inb_nullport;
249 R_AL = (*in_handler)(port);
250 debug(D_PORT, "IN on port %02x -> %02x\n", port, R_AL);
251}
252
253void
254insb(regcontext_t *REGS, int port)
255{
256 unsigned char (*in_handler)(int);
257 unsigned char data;
258
259 if ((port >= MINPORT) && (port < MAXPORT))
260 in_handler = portsw[port].p_inb;
261 else
262 in_handler = inb_nullport;
263 data = (*in_handler)(port);
264 *(u_char *)MAKEPTR(R_ES, R_DI) = data;
265 debug(D_PORT, "INS on port %02x -> %02x\n", port, data);
266
267 if (R_FLAGS & PSL_D)
268 R_DI--;
269 else
270 R_DI++;
271}
272
273void
274inx(regcontext_t *REGS, int port)
275{
276 unsigned char (*in_handler)(int);
277
278 if ((port >= MINPORT) && (port < MAXPORT))
279 in_handler = portsw[port].p_inb;
280 else
281 in_handler = inb_nullport;
282 R_AL = (*in_handler)(port);
283 if ((port >= MINPORT) && (port < MAXPORT))
284 in_handler = portsw[port + 1].p_inb;
285 else
286 in_handler = inb_nullport;
287 R_AH = (*in_handler)(port + 1);
288 debug(D_PORT, "IN on port %02x -> %04x\n", port, R_AX);
289}
290
291void
292insx(regcontext_t *REGS, int port)
293{
294 unsigned char (*in_handler)(int);
295 unsigned char data;
296
297 if ((port >= MINPORT) && (port < MAXPORT))
298 in_handler = portsw[port].p_inb;
299 else
300 in_handler = inb_nullport;
301 data = (*in_handler)(port);
302 *(u_char *)MAKEPTR(R_ES, R_DI) = data;
303 debug(D_PORT, "INS on port %02x -> %02x\n", port, data);
304
305 if ((port >= MINPORT) && (port < MAXPORT))
306 in_handler = portsw[port + 1].p_inb;
307 else
308 in_handler = inb_nullport;
309 data = (*in_handler)(port + 1);
310 ((u_char *)MAKEPTR(R_ES, R_DI))[1] = data;
311 debug(D_PORT, "INS on port %02x -> %02x\n", port, data);
312
313 if (R_FLAGS & PSL_D)
314 R_DI -= 2;
315 else
316 R_DI += 2;
317}
318
319void
320outb(regcontext_t *REGS, int port)
321{
322 void (*out_handler)(int, unsigned char);
323
324 if ((port >= MINPORT) && (port < MAXPORT))
325 out_handler = portsw[port].p_outb;
326 else
327 out_handler = outb_nullport;
328 (*out_handler)(port, R_AL);
329 debug(D_PORT, "OUT on port %02x <- %02x\n", port, R_AL);
330/*
331 if (port == 0x3bc && R_AL == 0x55)
332 tmode = 1;
333*/
334}
335
336void
337outx(regcontext_t *REGS, int port)
338{
339 void (*out_handler)(int, unsigned char);
340
341 if ((port >= MINPORT) && (port < MAXPORT))
342 out_handler = portsw[port].p_outb;
343 else
344 out_handler = outb_nullport;
345 (*out_handler)(port, R_AL);
346 debug(D_PORT, "OUT on port %02x <- %02x\n", port, R_AL);
347 if ((port >= MINPORT) && (port < MAXPORT))
348 out_handler = portsw[port + 1].p_outb;
349 else
350 out_handler = outb_nullport;
351 (*out_handler)(port + 1, R_AH);
352 debug(D_PORT, "OUT on port %02x <- %02x\n", port + 1, R_AH);
353}
354
355void
356outsb(regcontext_t *REGS, int port)
357{
358 void (*out_handler)(int, unsigned char);
359 unsigned char value;
360
361 if ((port >= MINPORT) && (port < MAXPORT))
362 out_handler = portsw[port].p_outb;
363 else
364 out_handler = outb_nullport;
365 value = *(u_char *)MAKEPTR(R_ES, R_DI);
366 debug(D_PORT, "OUT on port %02x <- %02x\n", port, value);
367 (*out_handler)(port, value);
368
369 if (R_FLAGS & PSL_D)
370 R_DI--;
371 else
372 R_DI++;
373}
374
375void
376outsx(regcontext_t *REGS, int port)
377{
378 void (*out_handler)(int, unsigned char);
379 unsigned char value;
380
381 if ((port >= MINPORT) && (port < MAXPORT))
382 out_handler = portsw[port].p_outb;
383 else
384 out_handler = outb_nullport;
385 value = *(u_char *)MAKEPTR(R_ES, R_DI);
386 debug(D_PORT, "OUT on port %02x <- %02x\n", port, value);
387 (*out_handler)(port, value);
388
389 if ((port >= MINPORT) && (port < MAXPORT))
390 out_handler = portsw[port + 1].p_outb;
391 else
392 out_handler = outb_nullport;
393 value = ((u_char *)MAKEPTR(R_ES, R_DI))[1];
394 debug(D_PORT, "OUT on port %02x <- %02x\n", port+1, value);
395 (*out_handler)(port + 1, value);
396
397 if (R_FLAGS & PSL_D)
398 R_DI -= 2;
399 else
400 R_DI += 2;
401}
402
403unsigned char port_61 = 0x10;
404int sound_on = 1;
405int sound_freq = 1000;
406
407void
408outb_speaker(int port __unused, unsigned char byte)
409{
410#if 0 /*XXXXX*/
411 if (raw_kbd) {
412 if ((port_61 & 3) != 3) {
413 if ((byte & 3) == 3 && /* prtim[2].gate && */ sound_on)
414 ioctl(kbd_fd, PCCONIOCSTARTBEEP, &sound_freq);
415 } else if ((byte & 3) != 3)
416 ioctl(kbd_fd, PCCONIOCSTOPBEEP);
417 }
418#endif
419 port_61 = byte;
420}
421
422unsigned char
423inb_speaker(int port __unused)
424{
425/* port_61 = (port_61 + 1) & 0xff; */
426 return(port_61);
427}
428
429void
1d1731fa 430speaker_init(void)
984263bc
MD
431{
432 define_input_port_handler(0x61, inb_speaker);
433 define_output_port_handler(0x61, outb_speaker);
434
435}