|
|
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:
1.1.1.3 ! root 23: #include <string.h>
! 24: #include <kern/debug.h>
1.1 root 25: #include <sys/types.h>
26: #include <device/conf.h>
27: #include <mach/boolean.h>
1.1.1.3 ! root 28: #include <device/cons.h>
1.1 root 29:
1.1.1.2 root 30: #ifdef MACH_KMSG
31: #include <device/io_req.h>
1.1.1.3 ! root 32: #include <device/kmsg.h>
1.1.1.2 root 33: #endif
34:
1.1.1.3 ! root 35: static boolean_t cn_inited = FALSE;
1.1 root 36: static struct consdev *cn_tab = 0; /* physical console device info */
37:
38: /*
39: * ROM getc/putc primitives.
40: * On some architectures, the boot ROM provides basic character input/output
41: * routines that can be used before devices are configured or virtual memory
42: * is enabled. This can be useful to debug (or catch panics from) code early
43: * in the bootstrap procedure.
44: */
45: int (*romgetc)() = 0;
46: void (*romputc)() = 0;
47:
48: #if CONSBUFSIZE > 0
49: /*
50: * Temporary buffer to store console output before a console is selected.
51: * This is statically allocated so it can be called before malloc/kmem_alloc
52: * have been initialized. It is initialized so it won't be clobbered as
53: * part of the zeroing of BSS (on PA/Mach).
54: */
55: static char consbuf[CONSBUFSIZE] = { 0 };
56: static char *consbp = consbuf;
1.1.1.3 ! root 57: static boolean_t consbufused = FALSE;
1.1 root 58: #endif
59:
1.1.1.3 ! root 60: void
1.1 root 61: cninit()
62: {
63: struct consdev *cp;
64: dev_ops_t cn_ops;
65: int x;
66:
67: if (cn_inited)
68: return;
69:
70: /*
71: * Collect information about all possible consoles
72: * and find the one with highest priority
73: */
74: for (cp = constab; cp->cn_probe; cp++) {
75: (*cp->cn_probe)(cp);
76: if (cp->cn_pri > CN_DEAD &&
77: (cn_tab == NULL || cp->cn_pri > cn_tab->cn_pri))
78: cn_tab = cp;
79: }
1.1.1.2 root 80:
1.1 root 81: /*
82: * Found a console, initialize it.
83: */
1.1.1.3 ! root 84: if ((cp = cn_tab)) {
1.1 root 85: /*
86: * Initialize as console
87: */
88: (*cp->cn_init)(cp);
89: /*
90: * Look up its dev_ops pointer in the device table and
91: * place it in the device indirection table.
92: */
93: if (dev_name_lookup(cp->cn_name, &cn_ops, &x) == FALSE)
94: panic("cninit: dev_name_lookup failed");
95: dev_set_indirection("console", cn_ops, minor(cp->cn_dev));
96: #if CONSBUFSIZE > 0
97: /*
98: * Now that the console is initialized, dump any chars in
99: * the temporary console buffer.
100: */
101: if (consbufused) {
102: char *cbp = consbp;
103: do {
104: if (*cbp)
105: cnputc(*cbp);
106: if (++cbp == &consbuf[CONSBUFSIZE])
107: cbp = consbuf;
108: } while (cbp != consbp);
1.1.1.3 ! root 109: consbufused = FALSE;
1.1 root 110: }
111: #endif
1.1.1.3 ! root 112: cn_inited = TRUE;
1.1 root 113: return;
114: }
115: /*
116: * No console device found, not a problem for BSD, fatal for Mach
117: */
118: panic("can't find a console device");
119: }
120:
121:
1.1.1.3 ! root 122: int
1.1 root 123: cngetc()
124: {
125: if (cn_tab)
126: return ((*cn_tab->cn_getc)(cn_tab->cn_dev, 1));
127: if (romgetc)
128: return ((*romgetc)(1));
129: return (0);
130: }
131:
1.1.1.3 ! root 132: int
1.1 root 133: cnmaygetc()
134: {
135: if (cn_tab)
136: return((*cn_tab->cn_getc)(cn_tab->cn_dev, 0));
137: if (romgetc)
138: return ((*romgetc)(0));
139: return (0);
140: }
141:
1.1.1.3 ! root 142: void
1.1 root 143: cnputc(c)
1.1.1.3 ! root 144: char c;
1.1 root 145: {
146: if (c == 0)
147: return;
148:
1.1.1.2 root 149: #ifdef MACH_KMSG
150: /* XXX: Assume that All output routines always use cnputc. */
151: kmsg_putchar (c);
152: #endif
153:
1.1.1.3 ! root 154: #if defined(MACH_HYP) && 0
! 155: {
! 156: /* Also output on hypervisor's emergency console, for
! 157: * debugging */
! 158: unsigned char d = c;
! 159: hyp_console_write(&d, 1);
! 160: }
! 161: #endif /* MACH_HYP */
! 162:
1.1 root 163: if (cn_tab) {
164: (*cn_tab->cn_putc)(cn_tab->cn_dev, c);
165: if (c == '\n')
166: (*cn_tab->cn_putc)(cn_tab->cn_dev, '\r');
167: } else if (romputc) {
168: (*romputc)(c);
169: if (c == '\n')
170: (*romputc)('\r');
171: }
172: #if CONSBUFSIZE > 0
173: else {
1.1.1.3 ! root 174: if (consbufused == FALSE) {
1.1 root 175: consbp = consbuf;
1.1.1.3 ! root 176: consbufused = TRUE;
! 177: memset(consbuf, 0, CONSBUFSIZE);
1.1 root 178: }
179: *consbp++ = c;
180: if (consbp >= &consbuf[CONSBUFSIZE])
181: consbp = consbuf;
182: }
183: #endif
184: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.