|
|
1.1 root 1: /*
2: * Copyright (c) 1988-1994, The University of Utah and
3: * the Computer Systems Laboratory (CSL). All rights reserved.
4: *
5: * Permission to use, copy, modify and distribute this software is hereby
6: * granted provided that (1) source code retains these copyright, permission,
7: * and disclaimer notices, and (2) redistributions including binaries
8: * reproduce the notices in supporting documentation, and (3) all advertising
9: * materials mentioning features or use of this software display the following
10: * acknowledgement: ``This product includes software developed by the
11: * Computer Systems Laboratory at the University of Utah.''
12: *
13: * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS
14: * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF
15: * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
16: *
17: * CSL requests users of this software to return to [email protected] any
18: * improvements that they make and grant CSL redistribution rights.
19: *
20: * Utah $Hdr: cons.c 1.14 94/12/14$
21: */
22:
23: #ifdef MACH_KERNEL
24: #include <sys/types.h>
25: #include <device/conf.h>
26: #include <mach/boolean.h>
27: #include <cons.h>
28: #else
29: #include <sys/param.h>
30: #include <sys/user.h>
31: #include <sys/systm.h>
32: #include <sys/buf.h>
33: #include <sys/ioctl.h>
34: #include <sys/tty.h>
35: #include <sys/file.h>
36: #include <sys/conf.h>
37: #include <hpdev/cons.h>
38: #endif
39:
40: static int cn_inited = 0;
41: static struct consdev *cn_tab = 0; /* physical console device info */
42: #ifndef MACH_KERNEL
43: static struct tty *constty = 0; /* virtual console output device */
44: #endif
45:
46: /*
47: * ROM getc/putc primitives.
48: * On some architectures, the boot ROM provides basic character input/output
49: * routines that can be used before devices are configured or virtual memory
50: * is enabled. This can be useful to debug (or catch panics from) code early
51: * in the bootstrap procedure.
52: */
53: int (*romgetc)() = 0;
54: void (*romputc)() = 0;
55:
56: #if CONSBUFSIZE > 0
57: /*
58: * Temporary buffer to store console output before a console is selected.
59: * This is statically allocated so it can be called before malloc/kmem_alloc
60: * have been initialized. It is initialized so it won't be clobbered as
61: * part of the zeroing of BSS (on PA/Mach).
62: */
63: static char consbuf[CONSBUFSIZE] = { 0 };
64: static char *consbp = consbuf;
65: static int consbufused = 0;
66: #endif
67:
68: cninit()
69: {
70: struct consdev *cp;
71: #ifdef MACH_KERNEL
72: dev_ops_t cn_ops;
73: int x;
74: #endif
75:
76: if (cn_inited)
77: return;
78:
79: /*
80: * Collect information about all possible consoles
81: * and find the one with highest priority
82: */
83: for (cp = constab; cp->cn_probe; cp++) {
84: (*cp->cn_probe)(cp);
85: if (cp->cn_pri > CN_DEAD &&
86: (cn_tab == NULL || cp->cn_pri > cn_tab->cn_pri))
87: cn_tab = cp;
88: }
89: /*
90: * Found a console, initialize it.
91: */
92: if (cp = cn_tab) {
93: /*
94: * Initialize as console
95: */
96: (*cp->cn_init)(cp);
97: #ifdef MACH_KERNEL
98: /*
99: * Look up its dev_ops pointer in the device table and
100: * place it in the device indirection table.
101: */
102: if (dev_name_lookup(cp->cn_name, &cn_ops, &x) == FALSE)
103: panic("cninit: dev_name_lookup failed");
104: dev_set_indirection("console", cn_ops, minor(cp->cn_dev));
105: #endif
106: #if CONSBUFSIZE > 0
107: /*
108: * Now that the console is initialized, dump any chars in
109: * the temporary console buffer.
110: */
111: if (consbufused) {
112: char *cbp = consbp;
113: do {
114: if (*cbp)
115: cnputc(*cbp);
116: if (++cbp == &consbuf[CONSBUFSIZE])
117: cbp = consbuf;
118: } while (cbp != consbp);
119: consbufused = 0;
120: }
121: #endif
122: cn_inited = 1;
123: return;
124: }
125: /*
126: * No console device found, not a problem for BSD, fatal for Mach
127: */
128: #ifdef MACH_KERNEL
129: panic("can't find a console device");
130: #endif
131: }
132:
133: #ifndef MACH_KERNEL
134: cnopen(dev, flag)
135: dev_t dev;
136: {
137: if (cn_tab == NULL)
138: return(0);
139: dev = cn_tab->cn_dev;
140: return ((*cdevsw[major(dev)].d_open)(dev, flag));
141: }
142:
143: cnclose(dev, flag)
144: dev_t dev;
145: {
146: if (cn_tab == NULL)
147: return(0);
148: dev = cn_tab->cn_dev;
149: return ((*cdevsw[major(dev)].d_close)(dev, flag));
150: }
151:
152: cnread(dev, uio)
153: dev_t dev;
154: struct uio *uio;
155: {
156: if (cn_tab == NULL)
157: return(0);
158: dev = cn_tab->cn_dev;
159: return ((*cdevsw[major(dev)].d_read)(dev, uio));
160: }
161:
162: cnwrite(dev, uio)
163: dev_t dev;
164: struct uio *uio;
165: {
166: if (cn_tab == NULL)
167: return(0);
168: dev = cn_tab->cn_dev;
169: return ((*cdevsw[major(dev)].d_write)(dev, uio));
170: }
171:
172: cnioctl(dev, cmd, data, flag)
173: dev_t dev;
174: caddr_t data;
175: {
176: if (cn_tab == NULL)
177: return(0);
178: /*
179: * Superuser can always use this to wrest control of console
180: * output from the "virtual" console.
181: */
182: if (cmd == TIOCCONS && constty) {
183: if (!suser())
184: return(EPERM);
185: constty = NULL;
186: return(0);
187: }
188: dev = cn_tab->cn_dev;
189: return ((*cdevsw[major(dev)].d_ioctl)(dev, cmd, data, flag));
190: }
191:
192: cnselect(dev, rw)
193: dev_t dev;
194: int rw;
195: {
196: if (cn_tab == NULL)
197: return(1);
198: return(ttselect(cn_tab->cn_dev, rw));
199: }
200:
201: #ifndef hp300
202: /*
203: * XXX Should go away when the new CIO MUX driver is in place
204: */
205: #define d_control d_mmap
206: cncontrol(dev, cmd, data)
207: dev_t dev;
208: int cmd;
209: int data;
210: {
211: if (cn_tab == NULL)
212: return(0);
213: dev = cn_tab->cn_dev;
214: return((*cdevsw[major(dev)].d_control)(dev, cmd, data));
215: }
216: #undef d_control
217: #endif
218: #endif
219:
220: cngetc()
221: {
222: if (cn_tab)
223: return ((*cn_tab->cn_getc)(cn_tab->cn_dev, 1));
224: if (romgetc)
225: return ((*romgetc)(1));
226: return (0);
227: }
228:
229: #ifdef MACH_KERNEL
230: cnmaygetc()
231: {
232: if (cn_tab)
233: return((*cn_tab->cn_getc)(cn_tab->cn_dev, 0));
234: if (romgetc)
235: return ((*romgetc)(0));
236: return (0);
237: }
238: #endif
239:
240: cnputc(c)
241: int c;
242: {
243: if (c == 0)
244: return;
245:
246: if (cn_tab) {
247: (*cn_tab->cn_putc)(cn_tab->cn_dev, c);
248: if (c == '\n')
249: (*cn_tab->cn_putc)(cn_tab->cn_dev, '\r');
250: } else if (romputc) {
251: (*romputc)(c);
252: if (c == '\n')
253: (*romputc)('\r');
254: }
255: #if CONSBUFSIZE > 0
256: else {
257: if (consbufused == 0) {
258: consbp = consbuf;
259: consbufused = 1;
260: bzero(consbuf, CONSBUFSIZE);
261: }
262: *consbp++ = c;
263: if (consbp >= &consbuf[CONSBUFSIZE])
264: consbp = consbuf;
265: }
266: #endif
267: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.