|
|
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:
1.1.1.2 ! root 40: #ifdef MACH_KMSG
! 41: #include <device/io_req.h>
! 42: #include <kmsg.h>
! 43: #endif
! 44:
1.1 root 45: static int cn_inited = 0;
46: static struct consdev *cn_tab = 0; /* physical console device info */
47: #ifndef MACH_KERNEL
48: static struct tty *constty = 0; /* virtual console output device */
49: #endif
50:
51: /*
52: * ROM getc/putc primitives.
53: * On some architectures, the boot ROM provides basic character input/output
54: * routines that can be used before devices are configured or virtual memory
55: * is enabled. This can be useful to debug (or catch panics from) code early
56: * in the bootstrap procedure.
57: */
58: int (*romgetc)() = 0;
59: void (*romputc)() = 0;
60:
61: #if CONSBUFSIZE > 0
62: /*
63: * Temporary buffer to store console output before a console is selected.
64: * This is statically allocated so it can be called before malloc/kmem_alloc
65: * have been initialized. It is initialized so it won't be clobbered as
66: * part of the zeroing of BSS (on PA/Mach).
67: */
68: static char consbuf[CONSBUFSIZE] = { 0 };
69: static char *consbp = consbuf;
70: static int consbufused = 0;
71: #endif
72:
73: cninit()
74: {
75: struct consdev *cp;
76: #ifdef MACH_KERNEL
77: dev_ops_t cn_ops;
78: int x;
79: #endif
80:
81: if (cn_inited)
82: return;
83:
84: /*
85: * Collect information about all possible consoles
86: * and find the one with highest priority
87: */
88: for (cp = constab; cp->cn_probe; cp++) {
89: (*cp->cn_probe)(cp);
90: if (cp->cn_pri > CN_DEAD &&
91: (cn_tab == NULL || cp->cn_pri > cn_tab->cn_pri))
92: cn_tab = cp;
93: }
1.1.1.2 ! root 94:
1.1 root 95: /*
96: * Found a console, initialize it.
97: */
98: if (cp = cn_tab) {
99: /*
100: * Initialize as console
101: */
102: (*cp->cn_init)(cp);
103: #ifdef MACH_KERNEL
104: /*
105: * Look up its dev_ops pointer in the device table and
106: * place it in the device indirection table.
107: */
108: if (dev_name_lookup(cp->cn_name, &cn_ops, &x) == FALSE)
109: panic("cninit: dev_name_lookup failed");
110: dev_set_indirection("console", cn_ops, minor(cp->cn_dev));
111: #endif
112: #if CONSBUFSIZE > 0
113: /*
114: * Now that the console is initialized, dump any chars in
115: * the temporary console buffer.
116: */
117: if (consbufused) {
118: char *cbp = consbp;
119: do {
120: if (*cbp)
121: cnputc(*cbp);
122: if (++cbp == &consbuf[CONSBUFSIZE])
123: cbp = consbuf;
124: } while (cbp != consbp);
125: consbufused = 0;
126: }
127: #endif
128: cn_inited = 1;
129: return;
130: }
131: /*
132: * No console device found, not a problem for BSD, fatal for Mach
133: */
134: #ifdef MACH_KERNEL
135: panic("can't find a console device");
136: #endif
137: }
138:
139: #ifndef MACH_KERNEL
140: cnopen(dev, flag)
141: dev_t dev;
142: {
143: if (cn_tab == NULL)
144: return(0);
145: dev = cn_tab->cn_dev;
146: return ((*cdevsw[major(dev)].d_open)(dev, flag));
147: }
148:
149: cnclose(dev, flag)
150: dev_t dev;
151: {
152: if (cn_tab == NULL)
153: return(0);
154: dev = cn_tab->cn_dev;
155: return ((*cdevsw[major(dev)].d_close)(dev, flag));
156: }
157:
158: cnread(dev, uio)
159: dev_t dev;
160: struct uio *uio;
161: {
162: if (cn_tab == NULL)
163: return(0);
164: dev = cn_tab->cn_dev;
165: return ((*cdevsw[major(dev)].d_read)(dev, uio));
166: }
167:
168: cnwrite(dev, uio)
169: dev_t dev;
170: struct uio *uio;
171: {
172: if (cn_tab == NULL)
173: return(0);
174: dev = cn_tab->cn_dev;
175: return ((*cdevsw[major(dev)].d_write)(dev, uio));
176: }
177:
178: cnioctl(dev, cmd, data, flag)
179: dev_t dev;
180: caddr_t data;
181: {
182: if (cn_tab == NULL)
183: return(0);
184: /*
185: * Superuser can always use this to wrest control of console
186: * output from the "virtual" console.
187: */
188: if (cmd == TIOCCONS && constty) {
189: if (!suser())
190: return(EPERM);
191: constty = NULL;
192: return(0);
193: }
194: dev = cn_tab->cn_dev;
195: return ((*cdevsw[major(dev)].d_ioctl)(dev, cmd, data, flag));
196: }
197:
198: cnselect(dev, rw)
199: dev_t dev;
200: int rw;
201: {
202: if (cn_tab == NULL)
203: return(1);
204: return(ttselect(cn_tab->cn_dev, rw));
205: }
206:
207: #ifndef hp300
208: /*
209: * XXX Should go away when the new CIO MUX driver is in place
210: */
211: #define d_control d_mmap
212: cncontrol(dev, cmd, data)
213: dev_t dev;
214: int cmd;
215: int data;
216: {
217: if (cn_tab == NULL)
218: return(0);
219: dev = cn_tab->cn_dev;
220: return((*cdevsw[major(dev)].d_control)(dev, cmd, data));
221: }
222: #undef d_control
223: #endif
224: #endif
225:
226: cngetc()
227: {
228: if (cn_tab)
229: return ((*cn_tab->cn_getc)(cn_tab->cn_dev, 1));
230: if (romgetc)
231: return ((*romgetc)(1));
232: return (0);
233: }
234:
235: #ifdef MACH_KERNEL
236: cnmaygetc()
237: {
238: if (cn_tab)
239: return((*cn_tab->cn_getc)(cn_tab->cn_dev, 0));
240: if (romgetc)
241: return ((*romgetc)(0));
242: return (0);
243: }
244: #endif
245:
246: cnputc(c)
247: int c;
248: {
249: if (c == 0)
250: return;
251:
1.1.1.2 ! root 252: #ifdef MACH_KMSG
! 253: /* XXX: Assume that All output routines always use cnputc. */
! 254: kmsg_putchar (c);
! 255: #endif
! 256:
1.1 root 257: if (cn_tab) {
258: (*cn_tab->cn_putc)(cn_tab->cn_dev, c);
259: if (c == '\n')
260: (*cn_tab->cn_putc)(cn_tab->cn_dev, '\r');
261: } else if (romputc) {
262: (*romputc)(c);
263: if (c == '\n')
264: (*romputc)('\r');
265: }
266: #if CONSBUFSIZE > 0
267: else {
268: if (consbufused == 0) {
269: consbp = consbuf;
270: consbufused = 1;
271: bzero(consbuf, CONSBUFSIZE);
272: }
273: *consbp++ = c;
274: if (consbp >= &consbuf[CONSBUFSIZE])
275: consbp = consbuf;
276: }
277: #endif
278: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.