1 /* $OpenBSD: consinit.c,v 1.17 2017/12/30 20:46:59 guenther Exp $ */
2 /* $NetBSD: consinit.c,v 1.9 2000/10/20 05:32:35 mrg Exp $ */
3
4 /*-
5 * Copyright (c) 1999 Eduardo E. Horvath
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32 #include "pcons.h"
33 #include "ukbd.h"
34
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/conf.h>
38 #include <sys/device.h>
39 #include <sys/ioctl.h>
40 #include <sys/kernel.h>
41 #include <sys/proc.h>
42 #include <sys/tty.h>
43 #include <sys/time.h>
44 #include <sys/syslog.h>
45
46 #include <machine/autoconf.h>
47 #include <machine/openfirm.h>
48 #include <machine/conf.h>
49 #include <machine/cpu.h>
50 #include <machine/psl.h>
51 #include <machine/z8530var.h>
52 #include <machine/sparc64.h>
53
54 #include <dev/cons.h>
55
56 #include <sparc64/dev/cons.h>
57
58 #include <dev/usb/ukbdvar.h>
59
60 cons_decl(prom_);
61
62 int stdin = 0, stdout = 0;
63
64 /*
65 * The console is set to this one initially,
66 * which lets us use the PROM until consinit()
67 * is called to select a real console.
68 */
69 struct consdev consdev_prom = {
70 prom_cnprobe,
71 prom_cninit,
72 prom_cngetc,
73 prom_cnputc,
74 prom_cnpollc,
75 NULL
76 };
77
78 /*
79 * The console table pointer is statically initialized
80 * to point to the PROM (output only) table, so that
81 * early calls to printf will work.
82 */
83 struct consdev *cn_tab = &consdev_prom;
84
85 void
prom_cnprobe(struct consdev * cd)86 prom_cnprobe(struct consdev *cd)
87 {
88 #if NPCONS > 0
89 int maj;
90
91 for (maj = 0; maj < nchrdev; maj++)
92 if (cdevsw[maj].d_open == pconsopen)
93 break;
94 cd->cn_dev = makedev(maj, 0);
95 cd->cn_pri = CN_MIDPRI;
96 #endif
97 }
98
99 int
prom_cngetc(dev_t dev)100 prom_cngetc(dev_t dev)
101 {
102 unsigned char ch = '\0';
103 int l;
104 #ifdef DDB
105 static int nplus = 0;
106 #endif
107
108 while ((l = OF_read(stdin, &ch, 1)) != 1)
109 /* void */;
110 #ifdef DDB
111 if (ch == '+') {
112 if (nplus++ > 3)
113 db_enter();
114 } else
115 nplus = 0;
116 #endif
117 if (ch == '\r')
118 ch = '\n';
119 if (ch == '\b')
120 ch = '\177';
121 return ch;
122 }
123
124 void
prom_cninit(struct consdev * cn)125 prom_cninit(struct consdev *cn)
126 {
127 if (!stdin) stdin = OF_stdin();
128 if (!stdout) stdout = OF_stdout();
129 }
130
131 /*
132 * PROM console output putchar.
133 */
134 void
prom_cnputc(dev_t dev,int c)135 prom_cnputc(dev_t dev, int c)
136 {
137 int s;
138 char c0 = (c & 0x7f);
139
140 #if 0
141 if (!stdout) stdout = OF_stdout();
142 #endif
143 s = splhigh();
144 OF_write(stdout, &c0, 1);
145 splx(s);
146 }
147
148 void
prom_cnpollc(dev_t dev,int on)149 prom_cnpollc(dev_t dev, int on)
150 {
151 if (on) {
152 /* Entering debugger. */
153 fb_unblank();
154 } else {
155 /* Resuming kernel. */
156 }
157 #if NPCONS > 0
158 pcons_cnpollc(dev, on);
159 #endif
160 }
161
162 /*****************************************************************/
163
164 #ifdef DEBUG
165 #define DBPRINT(x) prom_printf x
166 #else
167 #define DBPRINT(x)
168 #endif
169
170 /*
171 * This function replaces sys/dev/cninit.c
172 * Determine which device is the console using
173 * the PROM "input source" and "output sink".
174 */
175 void
consinit(void)176 consinit(void)
177 {
178 register int chosen;
179 char buffer[128];
180 extern int stdinnode, fbnode;
181 char *consname = "unknown";
182
183 DBPRINT(("consinit()\r\n"));
184 if (cn_tab != &consdev_prom) return;
185
186 DBPRINT(("setting up stdin\r\n"));
187 chosen = OF_finddevice("/chosen");
188 OF_getprop(chosen, "stdin", &stdin, sizeof(stdin));
189 DBPRINT(("stdin instance = %x\r\n", stdin));
190
191 if ((stdinnode = OF_instance_to_package(stdin)) == 0) {
192 printf("WARNING: no PROM stdin\n");
193 }
194 #if NUKBD > 0
195 else {
196 if (OF_getprop(stdinnode, "compatible", buffer,
197 sizeof(buffer)) != -1 && strncmp("usb", buffer, 3) == 0)
198 ukbd_cnattach();
199 }
200 #endif
201
202 DBPRINT(("setting up stdout\r\n"));
203 OF_getprop(chosen, "stdout", &stdout, sizeof(stdout));
204
205 DBPRINT(("stdout instance = %x\r\n", stdout));
206
207 if ((fbnode = OF_instance_to_package(stdout)) == 0)
208 printf("WARNING: no PROM stdout\n");
209
210 DBPRINT(("stdout package = %x\r\n", fbnode));
211
212 if (stdinnode && (OF_getproplen(stdinnode,"keyboard") >= 0)) {
213 consname = "keyboard/display";
214 } else if (fbnode &&
215 (OF_instance_to_path(stdin, buffer, sizeof(buffer)) >= 0)) {
216 consname = buffer;
217 }
218 printf("console is %s\n", consname);
219
220 /* Initialize PROM console */
221 (*cn_tab->cn_probe)(cn_tab);
222 (*cn_tab->cn_init)(cn_tab);
223 }
224