xref: /netbsd/sys/arch/sun2/dev/consinit.c (revision bf9ec67e)
1 /*	$NetBSD: consinit.c,v 1.1 2002/03/22 00:22:43 fredette Exp $	*/
2 
3 /*-
4  * Copyright (c) 2001 Matthew Fredette
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 "opt_ddb.h"
33 #include "opt_kgdb.h"
34 #include "pcons.h"
35 #include "kbd.h"
36 #include "zs.h"
37 
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/conf.h>
41 #include <sys/device.h>
42 #include <sys/file.h>
43 #include <sys/ioctl.h>
44 #include <sys/kernel.h>
45 #include <sys/proc.h>
46 #include <sys/tty.h>
47 #include <sys/time.h>
48 #include <sys/syslog.h>
49 #include <sys/kgdb.h>
50 
51 #include <machine/autoconf.h>
52 #include <machine/promlib.h>
53 #include <machine/conf.h>
54 #include <machine/cpu.h>
55 #include <machine/eeprom.h>
56 #include <machine/psl.h>
57 #include <machine/z8530var.h>
58 
59 #include <dev/cons.h>
60 
61 #include <sun2/dev/cons.h>
62 
63 static void prom_cnprobe __P((struct consdev *));
64 static void prom_cninit __P((struct consdev *));
65 int  prom_cngetc __P((dev_t));
66 static void prom_cnputc __P((dev_t, int));
67 static void prom_cnpollc __P((dev_t, int));
68 static void prom_cnputc __P((dev_t, int));
69 
70 #ifdef	PROM_OBP_V2
71 /*
72  * The following several variables are related to
73  * the configuration process, and are used in initializing
74  * the machine.
75  */
76 int	prom_stdin_node;	/* node ID of ROM's console input device */
77 int	prom_stdout_node;	/* node ID of ROM's console output device */
78 char	prom_stdin_args[16];
79 char	prom_stdout_args[16];
80 #endif	/* PROM_OBP_V2 */
81 
82 /*
83  * The console is set to this one initially,
84  * which lets us use the PROM until consinit()
85  * is called to select a real console.
86  */
87 struct consdev consdev_prom = {
88 	prom_cnprobe,
89 	prom_cninit,
90 	prom_cngetc,
91 	prom_cnputc,
92 	prom_cnpollc,
93 	NULL,
94 };
95 
96 /*
97  * The console table pointer is statically initialized
98  * to point to the PROM (output only) table, so that
99  * early calls to printf will work.
100  */
101 struct consdev *cn_tab = &consdev_prom;
102 
103 void
104 prom_cnprobe(cd)
105 	struct consdev *cd;
106 {
107 #if NPCONS > 0
108 	int maj;
109 
110 	for (maj = 0; maj < nchrdev; maj++)
111 		if (cdevsw[maj].d_open == pconsopen)
112 			break;
113 	cd->cn_dev = makedev(maj, 0);
114 	cd->cn_pri = CN_INTERNAL;
115 #endif
116 }
117 
118 int
119 prom_cngetc(dev)
120 	dev_t dev;
121 {
122 	int ch;
123 #ifdef DDB
124 	static int nplus = 0;
125 #endif
126 
127 	ch = prom_getchar();
128 #ifdef DDB
129 	if (ch == '+') {
130 		if (nplus++ > 3) Debugger();
131 	} else nplus = 0;
132 #endif
133 	return ch;
134 }
135 
136 static void
137 prom_cninit(cn)
138 	struct consdev *cn;
139 {
140 }
141 
142 /*
143  * PROM console output putchar.
144  */
145 static void
146 prom_cnputc(dev, c)
147 	dev_t dev;
148 	int c;
149 {
150 	int s;
151 
152 	s = splhigh();
153 	prom_putchar(c);
154 	splx(s);
155 }
156 
157 void
158 prom_cnpollc(dev, on)
159 	dev_t dev;
160 	int on;
161 {
162 	if (on) {
163                 /* Entering debugger. */
164 #if NFB > 0
165                 fb_unblank();
166 #endif
167 	} else {
168                 /* Resuming kernel. */
169 	}
170 #if NPCONS > 0
171 	pcons_cnpollc(dev, on);
172 #endif
173 }
174 
175 /*****************************************************************/
176 
177 #ifdef	DEBUG
178 #define	DBPRINT(x)	prom_printf x
179 #else
180 #define	DBPRINT(x)
181 #endif
182 
183 #ifdef notyet /* PROM_OBP_V2 */
184 void
185 prom_get_device_args(prop, dev, dev_sz, args, args_sz)
186 	const char *prop;
187 	char *dev;
188 	unsigned int dev_sz;
189 	char *args;
190 	unsigned int args_sz;
191 {
192 	char *cp, buffer[128];
193 
194 	getpropstringA(prom_findroot(), (char *)prop, buffer, sizeof buffer);
195 
196 	/*
197  	* Extract device-specific arguments from a PROM device path (if any)
198  	*/
199 	cp = buffer + strlen(buffer);
200 	while (cp >= buffer) {
201 		if (*cp == ':') {
202 			strncpy(args, cp+1, args_sz);
203 			*cp = '\0';
204 			strncpy(dev, buffer, dev_sz);
205 			break;
206 		}
207 		cp--;
208 	}
209 }
210 #endif	/* PROM_OBP_V2 */
211 
212 /*
213  * This function replaces sys/dev/cninit.c
214  * Determine which device is the console using
215  * the PROM "input source" and "output sink".
216  */
217 void
218 consinit()
219 {
220 #ifdef	notyet /* PROM_OBP_V2 */
221 	char buffer[128];
222 #endif	/* PROM_OBP_V2 */
223 	char *consname = "unknown";
224 
225 	DBPRINT(("consinit()\r\n"));
226 	if (cn_tab != &consdev_prom) return;
227 
228 	switch(prom_version()) {
229 #ifdef	PROM_OLDMON
230 	case PROM_OLDMON:
231 	case PROM_OBP_V0:
232 		switch(prom_stdin()) {
233 		case PROMDEV_KBD:
234 			consname = "keyboard/display";
235 			break;
236 		case PROMDEV_TTYA:
237 			consname = "ttya";
238 			break;
239 		case PROMDEV_TTYB:
240 			consname = "ttyb";
241 			break;
242 		}
243 		break;
244 #endif	/* PROM_OLDMON */
245 
246 #ifdef	notyet /* PROM_OBP_V2 */
247 	case PROM_OBP_V2:
248 	case PROM_OBP_V3:
249 	case PROM_OPENFIRM:
250 
251 		/* Save PROM arguments for device matching */
252 		prom_get_device_args("stdin-path",
253 				     buffer,
254 				     sizeof(buffer),
255 				     prom_stdin_args,
256 				     sizeof(prom_stdin_args));
257 		prom_get_device_args("stdout-path",
258 				     buffer,
259 				     sizeof(buffer),
260 				     prom_stdout_args,
261 				     sizeof(prom_stdout_args));
262 
263 		/*
264 		 * Translate the STDIO package instance (`ihandle') -- that
265 		 * the PROM has already opened for us -- to a device tree
266 		 * node (i.e. a `phandle').
267 		 */
268 		DBPRINT(("stdin instance = %x\r\n", prom_stdin()));
269 		if ((prom_stdin_node = prom_instance_to_package(prom_stdin())) == 0) {
270 			printf("WARNING: no PROM stdin\n");
271 		}
272 		DBPRINT(("stdin package = %x\r\n", prom_stdin_node));
273 
274 		DBPRINT(("stdout instance = %x\r\n", prom_stdout()));
275 		if ((prom_stdout_node = prom_instance_to_package(prom_stdout())) == 0) {
276 			printf("WARNING: no PROM stdout\n");
277 		}
278 		DBPRINT(("stdout package = %x\r\n", prom_stdout_node));
279 		DBPRINT(("buffer @ %p\r\n", buffer));
280 
281 		if (prom_stdin_node && prom_node_has_property(prom_stdin_node, "keyboard") {
282 #if NKBD == 0
283 			printf("cninit: kdb/display not configured\n");
284 #endif
285 			consname = "keyboard/display";
286 		} else if (prom_stdout_node)
287 			consname = buffer;
288 #endif	/* PROM_OBP_V2 */
289 	}
290 	printf("console is %s\n", consname);
291 
292 	/* Initialize PROM console */
293 	(*cn_tab->cn_probe)(cn_tab);
294 	(*cn_tab->cn_init)(cn_tab);
295 
296 #ifdef	KGDB
297 	/* Set up KGDB */
298 #if NZS > 0
299 	if (cdevsw[major(kgdb_dev)].d_open == zsopen)
300 		zs_kgdb_init();
301 #endif	/* NZS > 0 */
302 #endif	/* KGDB */
303 }
304 
305