This source file includes following definitions.
- pc_probe
- pc_init
- pc_getc
- pc_getshifts
- pc_putc
- com_probe
- com_init
- com_getc
- comspeed
- com_putc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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
37 #include <dev/cons.h>
38 #include <lib/libsa/stand.h>
39 #include "debug.h"
40 #include "biosdev.h"
41
42
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
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
85
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
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
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
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
166 int com_speed = 9600;
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
176 if (115200 < sp || sp < 75)
177 return -1;
178
179
180
181
182
183
184 for (i = sp; i != 75 && i != 14400; i >>= 1)
185 if (i & 1)
186 return -1;
187
188
189 #define divrnd(n, q) (((n)*2/(q)+1)/2)
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
226 __asm __volatile(DOINT(0x14) : "=a" (rv) :
227 "0" (0x300), "d" (dev) : "%ecx", "cc" );
228 if ( (rv & 0x20) == 0)
229 return;
230
231
232 __asm __volatile(DOINT(0x14) : "=a" (rv) :
233 "0" (c | 0x100), "d" (dev) : "%ecx", "cc" );
234 }