Commit | Line | Data |
---|---|---|
15637ed4 RG |
1 | /*- |
2 | * Copyright (c) 1990 The Regents of the University of California. | |
3 | * Copyright (c) 1992 by Holger Veit | |
4 | * All rights reserved. | |
5 | * | |
6 | * This code is derived from software contributed to Berkeley by | |
7 | * William Jolitz and Don Ahn. | |
8 | * Significant parts are added and rewritten by Holger Veit. | |
9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | |
15 | * 2. Redistributions in binary form must reproduce the above copyright | |
16 | * notice, this list of conditions and the following disclaimer in the | |
17 | * documentation and/or other materials provided with the distribution. | |
18 | * 3. All advertising materials mentioning features or use of this software | |
19 | * must display the following acknowledgement: | |
20 | * This product includes software developed by the University of | |
21 | * California, Berkeley and its contributors. | |
22 | * 4. Neither the name of the University nor the names of its contributors | |
23 | * may be used to endorse or promote products derived from this software | |
24 | * without specific prior written permission. | |
25 | * | |
26 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
27 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
28 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
29 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
30 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
31 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
32 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
33 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
34 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
35 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
36 | * SUCH DAMAGE. | |
37 | * | |
38 | * @(#)co_cons.c $Revision: 1.11 $ (Contributed to 386bsd) $Date: 93/01/23 23:14:33 $ | |
39 | */ | |
40 | static char *rcsid = "$Header: /usr/src/sys.386bsd/i386/isa/codrv/RCS/co_cons.c,v 1.11 93/01/23 23:14:33 root Exp Locker: root $"; | |
41 | ||
42 | /* | |
43 | * History: See CO_HISTORY | |
44 | */ | |
45 | ||
46 | #include "co.h" | |
47 | #include "pc.h" | |
48 | #if NCO == 1 | |
49 | #if NPC == 0 | |
50 | ||
51 | /* | |
52 | * code to work keyboard & display for PC-style console | |
53 | */ | |
54 | #include "co_hdr.h" | |
55 | ||
56 | unsigned __debug = 0; /* 0xffe, exported to elsewhere */ | |
57 | static unsigned __color; | |
58 | ||
59 | struct tty *dev2tty(dev_t dev) | |
60 | { | |
61 | register n = minor(dev); | |
62 | ||
63 | /* also checks valid minor # */ | |
64 | if (n < nvty) | |
65 | return &pccons[n]; | |
66 | else | |
67 | return 0; | |
68 | } | |
69 | ||
70 | static int tty2vty(struct tty *tp) | |
71 | { | |
72 | int i; | |
73 | for (i=0; i<nvty; i++) | |
74 | if (vtys[i].ttyp==tp) return i; | |
75 | return -1; | |
76 | } | |
77 | ||
78 | /* | |
79 | * open a vty device. Name 'pcopen' is historical | |
80 | * | |
81 | */ | |
82 | int pcopen(dev_t dev, int flag, int mode, struct proc *p) | |
83 | { | |
84 | register struct tty *tp = dev2tty(dev); | |
85 | ||
86 | if (!tp) return ENXIO; | |
87 | ||
88 | /* increment ref count */ | |
89 | vtys[minor(dev)].ttycnt++; | |
90 | ||
91 | tp->t_oproc = pcstart; | |
92 | tp->t_param = pcparam; | |
93 | tp->t_dev = dev; | |
94 | ||
95 | consoftc.cs_flags |= CO_OPEN|CO_INITTTY; | |
96 | consoftc.cs_opencnt++; | |
97 | ||
98 | if ((tp->t_state & TS_ISOPEN) == 0) { | |
99 | tp->t_state |= TS_WOPEN; | |
100 | ttychars(tp); | |
101 | tp->t_iflag = TTYDEF_IFLAG; | |
102 | tp->t_oflag = TTYDEF_OFLAG; | |
103 | tp->t_cflag = TTYDEF_CFLAG; | |
104 | tp->t_lflag = TTYDEF_LFLAG; | |
105 | tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; | |
106 | tp->t_iflag &= ~ISTRIP; | |
107 | pcparam(tp, &tp->t_termios); | |
108 | ttsetwater(tp); | |
109 | } else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0) | |
110 | return (EBUSY); | |
111 | tp->t_state |= TS_CARR_ON; | |
112 | return ((*linesw[tp->t_line].l_open)(dev, tp)); | |
113 | } | |
114 | ||
115 | /* | |
116 | * Close a vty | |
117 | */ | |
118 | /*ARGSUSED*/ | |
119 | int pcclose(dev_t dev, int flag, int mode, struct proc *p) | |
120 | { | |
121 | register struct tty *tp = dev2tty(dev); | |
122 | struct vty *vp = &vtys[minor(dev)]; | |
123 | ||
124 | if (!tp) return ENXIO; | |
125 | ||
126 | /* decrement vty reference count */ | |
127 | if (vp->ttycnt > 0) vp->ttycnt--; | |
128 | ||
129 | if (consoftc.cs_opencnt==0) { | |
130 | consoftc.cs_flags &= ~CO_OPEN; | |
131 | ||
132 | /* reset the keyboard state */ | |
133 | reset_kbd_flags(); | |
134 | initrb(&co_buf); | |
135 | } | |
136 | else | |
137 | consoftc.cs_opencnt--; | |
138 | ||
139 | (*linesw[tp->t_line].l_close)(tp, flag); | |
140 | ttyclose(tp); | |
141 | ||
142 | return(0); | |
143 | } | |
144 | ||
145 | /* | |
146 | * read from vty | |
147 | */ | |
148 | /*ARGSUSED*/ | |
149 | int pcread(dev_t dev, struct uio *uio, int flag) | |
150 | { | |
151 | register struct tty *tp = dev2tty(dev); | |
152 | if (!tp) return ENXIO; | |
153 | ||
154 | /* this does not belong to here, but anybody always wants to | |
155 | strip the 8th bit, very likely the shell */ | |
156 | tp->t_iflag &= ~ISTRIP; | |
157 | return ((*linesw[tp->t_line].l_read)(tp, uio, flag)); | |
158 | } | |
159 | ||
160 | /* | |
161 | * write to vty | |
162 | */ | |
163 | /*ARGSUSED*/ | |
164 | int pcwrite(dev_t dev, struct uio *uio, int flag) | |
165 | { | |
166 | register struct tty *tp = dev2tty(dev); | |
167 | if (!tp) return ENXIO; | |
168 | ||
169 | /* we allow writing, but we don't know where it goes to */ | |
170 | /*if (consoftc.cs_flags & CO_OPENRAW) return EBUSY; */ | |
171 | ||
172 | return ((*linesw[tp->t_line].l_write)(tp, uio, flag)); | |
173 | } | |
174 | ||
175 | /* | |
176 | * execute vty ioctl | |
177 | * This does no longer accept keyboard and vga oriented ioctls | |
178 | */ | |
179 | int pcioctl(dev_t dev, int cmd, caddr_t data, int flag) | |
180 | { | |
181 | /* call the ioctl handler */ | |
182 | return consioctl(dev, cmd, data, flag); | |
183 | } | |
184 | ||
185 | int pcconsintr = 1; | |
186 | /* | |
187 | * Got a console transmission interrupt - | |
188 | * the console processor wants another character. | |
189 | * | |
190 | * -hv- is this really used? | |
191 | */ | |
192 | pcxint(dev) | |
193 | dev_t dev; | |
194 | { | |
195 | register struct tty *tp = dev2tty(dev); | |
196 | register int unit; | |
197 | ||
198 | if (!tp) return; | |
199 | ||
200 | if (!pcconsintr) | |
201 | return; | |
202 | tp->t_state &= ~TS_BUSY; | |
203 | consoftc.cs_timo = 0; | |
204 | if (tp->t_line) | |
205 | (*linesw[tp->t_line].l_start)(tp); | |
206 | else | |
207 | pcstart(tp); | |
208 | } | |
209 | ||
210 | int pcstart(register struct tty *tp) | |
211 | { | |
212 | int c, s, vp; | |
213 | ||
214 | s = spltty(); | |
215 | if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) | |
216 | goto out; | |
217 | do { | |
218 | if (RB_LEN(&tp->t_out) <= tp->t_lowat) { | |
219 | if (tp->t_state&TS_ASLEEP) { | |
220 | tp->t_state &= ~TS_ASLEEP; | |
221 | wakeup((caddr_t)&tp->t_out); | |
222 | } | |
223 | if (tp->t_wsel) { | |
224 | selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); | |
225 | tp->t_wsel = 0; | |
226 | tp->t_state &= ~TS_WCOLL; | |
227 | } | |
228 | } | |
229 | if (RB_LEN(&tp->t_out) == 0) | |
230 | goto out; | |
231 | c = getc(&tp->t_out); | |
232 | tp->t_state |= TS_BUSY; | |
233 | splx(s); | |
234 | vp = tty2vty(tp); | |
235 | if (vp < 0) panic("pcstart: unknown vty"); | |
236 | sput(vp, c, 0); | |
237 | tp->t_state &= ~TS_BUSY; | |
238 | (void)spltty(); | |
239 | } while(1); | |
240 | out: | |
241 | splx(s); | |
242 | } | |
243 | ||
244 | /* interface for console device */ | |
245 | void pccnprobe(struct consdev *cp) | |
246 | { | |
247 | int maj; | |
248 | int dev = 0; | |
249 | ||
250 | /* locate the major number */ | |
251 | for (maj = 0; maj < nchrdev; maj++) | |
252 | if (cdevsw[maj].d_open == pcopen) | |
253 | break; | |
254 | ||
255 | maj = 12; | |
256 | /* initialize required fields */ | |
257 | cp->cn_dev = makedev(maj, 0); | |
258 | cp->cn_tp = &pccons[0]; | |
259 | cp->cn_pri = CN_INTERNAL; | |
260 | } | |
261 | ||
262 | /* interface for console device */ | |
263 | /* ARGSUSED */ | |
264 | void pccninit(struct consdev *cp) | |
265 | { | |
266 | /* | |
267 | * For now, don't screw with it. | |
268 | */ | |
269 | /* crtat = 0; */ | |
270 | } | |
271 | ||
272 | /* interface for console device */ | |
273 | /* ARGSUSED */ | |
274 | void pccnputc(dev_t dev, int c) | |
275 | { | |
276 | int clr = __color; | |
277 | ||
278 | if (!dev2tty(dev)) return; /* ignore if invalid */ | |
279 | ||
280 | if (clr == 0) | |
281 | clr = 0x30; | |
282 | else | |
283 | clr |= 0x60; | |
284 | ||
285 | if (c == '\n') | |
286 | sput(minor(dev), '\r', clr); | |
287 | sput(minor(dev), c, clr); | |
288 | } | |
289 | ||
290 | #ifdef notyetused | |
291 | /* | |
292 | * Print a character on console. | |
293 | */ | |
294 | pcputchar(c, tp) | |
295 | char c; | |
296 | register struct tty *tp; | |
297 | { | |
298 | sput(0, c, 0x2); | |
299 | if (c=='\n') getchar(); | |
300 | } | |
301 | #endif | |
302 | ||
303 | /* interface for console device */ | |
304 | /* ARGSUSED */ | |
305 | int pccngetc(dev_t dev) | |
306 | { | |
307 | register int s; | |
308 | register XCHAR *cp; | |
309 | ||
310 | s = spltty(); /* block cointr while we poll */ | |
311 | while ((cp = kbd_sgetc(0))==NULL); | |
312 | splx(s); | |
313 | if (*cp == '\r') return('\n'); | |
314 | return (char)*cp; | |
315 | } | |
316 | ||
317 | #ifdef notyetused | |
318 | pcgetchar(tp) | |
319 | register struct tty *tp; | |
320 | { | |
321 | XCHAR *cp; | |
322 | ||
323 | cp = kbd_sgetc(0); /* this is surely ASCII */ | |
324 | return (char)(*cp&0xff); | |
325 | } | |
326 | #endif | |
327 | ||
328 | /* | |
329 | * Set line parameters | |
330 | */ | |
331 | int pcparam(struct tty *tp, struct termios *t) | |
332 | { | |
333 | register int cflag = t->c_cflag; | |
334 | /* and copy to tty */ | |
335 | tp->t_ispeed = t->c_ispeed; | |
336 | tp->t_ospeed = t->c_ospeed; | |
337 | tp->t_cflag = cflag; | |
338 | ||
339 | return(0); | |
340 | } | |
341 | ||
342 | #ifdef KDB | |
343 | /* | |
344 | * Turn input polling on/off (used by debugger). | |
345 | */ | |
346 | /*ARGSUSED*/ | |
347 | int pcpoll(int onoff) | |
348 | { | |
349 | } | |
350 | #endif | |
351 | ||
352 | #ifdef OLD_PATCHKIT | |
353 | int pg(char *p,int q,int r,int s,int t,int u,int v,int w,int x,int y,int z) | |
354 | { | |
355 | printf(p,q,r,s,t,u,v,w,x,y,z); | |
356 | printf("\n"); | |
357 | return(getchar()); | |
358 | } | |
359 | #endif | |
360 | ||
361 | /* special characters */ | |
362 | #define bs 8 | |
363 | #define lf 10 | |
364 | #define cr 13 | |
365 | #define cntlc 3 | |
366 | #define del 0177 | |
367 | #define cntld 4 | |
368 | ||
369 | int getchar() | |
370 | { | |
371 | XCHAR thechar,*c; | |
372 | register delay; | |
373 | int x; | |
374 | ||
375 | consoftc.cs_flags |= CO_POLLING; | |
376 | x = splhigh(); | |
377 | sput(0, '>', 1); | |
378 | /*while (1) {*/ | |
379 | while ((c=kbd_sgetc(0))==NULL); | |
380 | thechar = *c; | |
381 | consoftc.cs_flags &= ~CO_POLLING; | |
382 | splx(x); | |
383 | switch (thechar) { | |
384 | default: if (thechar >= ' ') | |
385 | sput(0, thechar, 1); | |
386 | return(thechar); | |
387 | case cr: | |
388 | case lf: sput(0, '\r', 1); | |
389 | sput(0, '\n', 1); | |
390 | return(lf); | |
391 | case bs: | |
392 | case del: | |
393 | sput(0, '\b', 1); | |
394 | sput(0, ' ', 1); | |
395 | sput(0, '\b', 1); | |
396 | return(thechar); | |
397 | case cntlc: | |
398 | sput(0, '^', 1) ; sput(0, 'C', 1) ; sput(0, '\r', 1) ; sput(0, '\n', 1) ; | |
399 | cpu_reset(); | |
400 | case cntld: | |
401 | sput(0, '^', 1) ; sput(0, 'D', 1) ; sput(0, '\r', 1) ; sput(0, '\n', 1) ; | |
402 | return(0); | |
403 | } | |
404 | /*}*/ | |
405 | } | |
406 | ||
407 | #ifdef notyetused | |
408 | #include "machine/stdarg.h" | |
409 | static nrow; | |
410 | ||
411 | #define DPAUSE 1 | |
412 | void | |
413 | #ifdef __STDC__ | |
414 | dprintf(unsigned flgs, const char *fmt, ...) | |
415 | #else | |
416 | dprintf(flgs, fmt /*, va_alist */) | |
417 | char *fmt; | |
418 | unsigned flgs; | |
419 | #endif | |
420 | { extern unsigned __debug; | |
421 | va_list ap; | |
422 | ||
423 | if((flgs&__debug) > DPAUSE) { | |
424 | __color = ffs(flgs&__debug)+1; | |
425 | va_start(ap,fmt); | |
426 | kprintf(fmt, 1, (struct tty *)0, ap); | |
427 | va_end(ap); | |
428 | if (flgs&DPAUSE || nrow%24 == 23) { | |
429 | int x; | |
430 | x = splhigh(); | |
431 | if (nrow%24 == 23) nrow = 0; | |
432 | (void)kbd_sgetc(0); | |
433 | splx(x); | |
434 | } | |
435 | } | |
436 | __color = 0; | |
437 | } | |
438 | #endif | |
439 | ||
440 | #endif /* NPC=0 */ | |
441 | #endif /* NCO=1 */ |