Annotation of sys/arch/i386/stand/libsa/bioscons.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: bioscons.c,v 1.29 2007/04/27 10:08:34 tom Exp $ */
2:
3: /*
4: * Copyright (c) 1997-1999 Michael Shalayeff
5: * All rights reserved.
6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
15: *
16: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19: * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
20: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22: * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
25: * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26: * THE POSSIBILITY OF SUCH DAMAGE.
27: */
28:
29: #include <sys/types.h>
30: #include <machine/biosvar.h>
31: #include <machine/pio.h>
32: #include <dev/isa/isareg.h>
33: #include <dev/ic/mc146818reg.h>
34: #include <dev/ic/comreg.h>
35: #include <dev/ic/ns16450reg.h>
36: /* #include <i386/isa/nvram.h> */
37: #include <dev/cons.h>
38: #include <lib/libsa/stand.h>
39: #include "debug.h"
40: #include "biosdev.h"
41:
42: /* XXX cannot trust NVRAM on this. Maybe later we make a real probe. */
43: #if 0
44: #define PRESENT_MASK (NVRAM_EQUIPMENT_KBD|NVRAM_EQUIPMENT_DISPLAY)
45: #else
46: #define PRESENT_MASK 0
47: #endif
48:
49: void
50: pc_probe(struct consdev *cn)
51: {
52: cn->cn_pri = CN_INTERNAL;
53: cn->cn_dev = makedev(12, 0);
54: printf(" pc%d", minor(cn->cn_dev));
55:
56: #if 0
57: outb(IO_RTC, NVRAM_EQUIPMENT);
58: if ((inb(IO_RTC+1) & PRESENT_MASK) == PRESENT_MASK) {
59: cn->cn_pri = CN_INTERNAL;
60: /* XXX from i386/conf.c */
61: cn->cn_dev = makedev(12, 0);
62: printf(" pc%d", minor(cn->cn_dev));
63: }
64: #endif
65: }
66:
67: void
68: pc_init(struct consdev *cn)
69: {
70: }
71:
72: int
73: pc_getc(dev_t dev)
74: {
75: register int rv;
76:
77: if (dev & 0x80) {
78: __asm __volatile(DOINT(0x16) "; setnz %b0" : "=a" (rv) :
79: "0" (0x100) : "%ecx", "%edx", "cc" );
80: return (rv & 0xff);
81: }
82:
83: /*
84: * Wait for a character to actually become available. Appears to
85: * be necessary on (at least) the Intel Mac Mini.
86: */
87: do {
88: __asm __volatile(DOINT(0x16) "; setnz %b0" : "=a" (rv) :
89: "0" (0x100) : "%ecx", "%edx", "cc" );
90: } while ((rv & 0xff) == 0);
91:
92: __asm __volatile(DOINT(0x16) : "=a" (rv) : "0" (0x000) :
93: "%ecx", "%edx", "cc" );
94:
95: return (rv & 0xff);
96: }
97:
98: int
99: pc_getshifts(dev_t dev)
100: {
101: register int rv;
102:
103: __asm __volatile(DOINT(0x16) : "=a" (rv) : "0" (0x200) :
104: "%ecx", "%edx", "cc" );
105:
106: return (rv & 0xff);
107: }
108:
109: void
110: pc_putc(dev_t dev, int c)
111: {
112: __asm __volatile(DOINT(0x10) : : "a" (c | 0xe00), "b" (1) :
113: "%ecx", "%edx", "cc" );
114: }
115:
116: const int comports[4] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
117:
118: void
119: com_probe(struct consdev *cn)
120: {
121: register int i, n;
122:
123: /* get equip. (9-11 # of coms) */
124: __asm __volatile(DOINT(0x11) : "=a" (n) : : "%ecx", "%edx", "cc");
125: n >>= 9;
126: n &= 7;
127: for (i = 0; i < n; i++)
128: printf(" com%d", i);
129: if (n) {
130: cn->cn_pri = CN_NORMAL;
131: /* XXX from i386/conf.c */
132: cn->cn_dev = makedev(8, 0);
133: }
134: }
135:
136: void
137: com_init(struct consdev *cn)
138: {
139: register int unit = minor(cn->cn_dev);
140:
141: /* let bios do necessary init first, 9600-N-1 */
142: __asm __volatile(DOINT(0x14) : : "a" (0xe3), "d" (unit) :
143: "%ecx", "cc" );
144: }
145:
146: int
147: com_getc(dev_t dev)
148: {
149: register int rv;
150:
151: if (dev & 0x80) {
152: __asm __volatile(DOINT(0x14) : "=a" (rv) :
153: "0" (0x300), "d" (minor(dev&0x7f)) : "%ecx", "cc" );
154: return ((rv & 0x100) == 0x100);
155: }
156:
157: do
158: __asm __volatile(DOINT(0x14) : "=a" (rv) :
159: "0" (0x200), "d" (minor(dev)) : "%ecx", "cc" );
160: while (rv & 0x8000);
161:
162: return (rv & 0xff);
163: }
164:
165: /* call with sp == 0 to query the current speed */
166: int com_speed = 9600; /* default speed is 9600 baud */
167: int
168: comspeed(dev_t dev, int sp)
169: {
170: int i, newsp;
171: int err;
172:
173: if (sp <= 0)
174: return com_speed;
175: /* valid baud rate? */
176: if (115200 < sp || sp < 75)
177: return -1;
178:
179: /*
180: * Accepted speeds:
181: * 75 150 300 600 1200 2400 4800 9600 19200 38400 76800 and
182: * 14400 28800 57600 115200
183: */
184: for (i = sp; i != 75 && i != 14400; i >>= 1)
185: if (i & 1)
186: return -1;
187:
188: /* ripped screaming from dev/ic/com.c */
189: #define divrnd(n, q) (((n)*2/(q)+1)/2) /* divide and round off */
190: newsp = divrnd((COM_FREQ / 16), sp);
191: if (newsp <= 0)
192: return -1;
193: err = divrnd((COM_FREQ / 16) * 1000, sp * newsp) - 1000;
194: if (err < 0)
195: err = -err;
196: if (err > COM_TOLERANCE)
197: return -1;
198: #undef divrnd
199:
200: if (cn_tab && cn_tab->cn_dev == dev && com_speed != sp) {
201: printf("com%d: changing speed to %d baud in 5 seconds, "
202: "change your terminal to match!\n\a",
203: minor(dev), sp);
204: sleep(5);
205: }
206:
207: outb(comports[minor(dev)] + com_cfcr, LCR_DLAB);
208: outb(comports[minor(dev)] + com_dlbl, newsp);
209: outb(comports[minor(dev)] + com_dlbh, newsp>>8);
210: outb(comports[minor(dev)] + com_cfcr, LCR_8BITS);
211: printf("\ncom%d: %d baud\n", minor(dev), sp);
212:
213: newsp = com_speed;
214: com_speed = sp;
215: return newsp;
216: }
217:
218: void
219: com_putc(dev_t dev, int c)
220: {
221: register int rv;
222:
223: dev = minor(dev) & 0x7f;
224:
225: /* check online (DSR) */
226: __asm __volatile(DOINT(0x14) : "=a" (rv) :
227: "0" (0x300), "d" (dev) : "%ecx", "cc" );
228: if ( (rv & 0x20) == 0)
229: return;
230:
231: /* send character */
232: __asm __volatile(DOINT(0x14) : "=a" (rv) :
233: "0" (c | 0x100), "d" (dev) : "%ecx", "cc" );
234: }
CVSweb