xref: /netbsd-src/sys/arch/sun2/dev/consinit.c (revision 254bb11f9647fc96d8ddf87d6f668d417445fd08)
1*254bb11fStsutsui /*	$NetBSD: consinit.c,v 1.9 2012/08/10 14:52:26 tsutsui Exp $	*/
2ae1f6b9eSfredette 
3ae1f6b9eSfredette /*-
4ae1f6b9eSfredette  * Copyright (c) 2001 Matthew Fredette
5ae1f6b9eSfredette  * Copyright (c) 1999 Eduardo E. Horvath
6ae1f6b9eSfredette  * All rights reserved.
7ae1f6b9eSfredette  *
8ae1f6b9eSfredette  * Redistribution and use in source and binary forms, with or without
9ae1f6b9eSfredette  * modification, are permitted provided that the following conditions
10ae1f6b9eSfredette  * are met:
11ae1f6b9eSfredette  * 1. Redistributions of source code must retain the above copyright
12ae1f6b9eSfredette  *    notice, this list of conditions and the following disclaimer.
13ae1f6b9eSfredette  * 2. Redistributions in binary form must reproduce the above copyright
14ae1f6b9eSfredette  *    notice, this list of conditions and the following disclaimer in the
15ae1f6b9eSfredette  *    documentation and/or other materials provided with the distribution.
16ae1f6b9eSfredette  * 3. The name of the author may not be used to endorse or promote products
17ae1f6b9eSfredette  *    derived from this software without specific prior written permission.
18ae1f6b9eSfredette  *
19ae1f6b9eSfredette  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20ae1f6b9eSfredette  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21ae1f6b9eSfredette  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22ae1f6b9eSfredette  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23ae1f6b9eSfredette  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24ae1f6b9eSfredette  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25ae1f6b9eSfredette  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26ae1f6b9eSfredette  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27ae1f6b9eSfredette  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28ae1f6b9eSfredette  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29ae1f6b9eSfredette  * SUCH DAMAGE.
30ae1f6b9eSfredette  */
31ae1f6b9eSfredette 
32ed517291Slukem #include <sys/cdefs.h>
33*254bb11fStsutsui __KERNEL_RCSID(0, "$NetBSD: consinit.c,v 1.9 2012/08/10 14:52:26 tsutsui Exp $");
34ed517291Slukem 
35ae1f6b9eSfredette #include "opt_ddb.h"
36ae1f6b9eSfredette #include "opt_kgdb.h"
37ae1f6b9eSfredette #include "pcons.h"
38ae1f6b9eSfredette #include "kbd.h"
39ae1f6b9eSfredette #include "zs.h"
40ae1f6b9eSfredette 
41ae1f6b9eSfredette #include <sys/param.h>
42ae1f6b9eSfredette #include <sys/systm.h>
43ae1f6b9eSfredette #include <sys/conf.h>
44ae1f6b9eSfredette #include <sys/device.h>
45ae1f6b9eSfredette #include <sys/file.h>
46ae1f6b9eSfredette #include <sys/ioctl.h>
47ae1f6b9eSfredette #include <sys/kernel.h>
48ae1f6b9eSfredette #include <sys/proc.h>
49ae1f6b9eSfredette #include <sys/tty.h>
50ae1f6b9eSfredette #include <sys/time.h>
51ae1f6b9eSfredette #include <sys/syslog.h>
52ae1f6b9eSfredette #include <sys/kgdb.h>
53ae1f6b9eSfredette 
54ae1f6b9eSfredette #include <machine/autoconf.h>
55ae1f6b9eSfredette #include <machine/promlib.h>
56ae1f6b9eSfredette #include <machine/cpu.h>
57ae1f6b9eSfredette #include <machine/eeprom.h>
58ae1f6b9eSfredette #include <machine/psl.h>
59ae1f6b9eSfredette #include <machine/z8530var.h>
60ae1f6b9eSfredette 
61ae1f6b9eSfredette #include <dev/cons.h>
62ae1f6b9eSfredette 
63ae1f6b9eSfredette #include <sun2/dev/cons.h>
64ae1f6b9eSfredette 
6510b1a7beSchs static void prom_cnprobe(struct consdev *);
6610b1a7beSchs static void prom_cninit(struct consdev *);
6710b1a7beSchs int  prom_cngetc(dev_t);
6810b1a7beSchs static void prom_cnputc(dev_t, int);
6910b1a7beSchs static void prom_cnpollc(dev_t, int);
7010b1a7beSchs static void prom_cnputc(dev_t, int);
71ae1f6b9eSfredette 
72ae1f6b9eSfredette #ifdef	PROM_OBP_V2
73ae1f6b9eSfredette /*
74ae1f6b9eSfredette  * The following several variables are related to
75ae1f6b9eSfredette  * the configuration process, and are used in initializing
76ae1f6b9eSfredette  * the machine.
77ae1f6b9eSfredette  */
78ae1f6b9eSfredette int	prom_stdin_node;	/* node ID of ROM's console input device */
79ae1f6b9eSfredette int	prom_stdout_node;	/* node ID of ROM's console output device */
80ae1f6b9eSfredette char	prom_stdin_args[16];
81ae1f6b9eSfredette char	prom_stdout_args[16];
82ae1f6b9eSfredette #endif	/* PROM_OBP_V2 */
83ae1f6b9eSfredette 
84ae1f6b9eSfredette /*
85ae1f6b9eSfredette  * The console is set to this one initially,
86ae1f6b9eSfredette  * which lets us use the PROM until consinit()
87ae1f6b9eSfredette  * is called to select a real console.
88ae1f6b9eSfredette  */
89ae1f6b9eSfredette struct consdev consdev_prom = {
90ae1f6b9eSfredette 	prom_cnprobe,
91ae1f6b9eSfredette 	prom_cninit,
92ae1f6b9eSfredette 	prom_cngetc,
93ae1f6b9eSfredette 	prom_cnputc,
94ae1f6b9eSfredette 	prom_cnpollc,
95ae1f6b9eSfredette 	NULL,
96ae1f6b9eSfredette };
97ae1f6b9eSfredette 
98ae1f6b9eSfredette void
prom_cnprobe(struct consdev * cd)9910b1a7beSchs prom_cnprobe(struct consdev *cd)
100ae1f6b9eSfredette {
101ae1f6b9eSfredette #if NPCONS > 0
10277a6b82bSgehenna 	extern const struct cdevsw pcons_cdevsw;
103ae1f6b9eSfredette 
10477a6b82bSgehenna 	cd->cn_dev = makedev(cdevsw_lookup_major(&pcons_cdevsw), 0);
105ae1f6b9eSfredette 	cd->cn_pri = CN_INTERNAL;
106ae1f6b9eSfredette #endif
107ae1f6b9eSfredette }
108ae1f6b9eSfredette 
109ae1f6b9eSfredette int
prom_cngetc(dev_t dev)11010b1a7beSchs prom_cngetc(dev_t dev)
111ae1f6b9eSfredette {
112ae1f6b9eSfredette 	int ch;
113ae1f6b9eSfredette #ifdef DDB
114ae1f6b9eSfredette 	static int nplus = 0;
115ae1f6b9eSfredette #endif
116ae1f6b9eSfredette 
117ae1f6b9eSfredette 	ch = prom_getchar();
118ae1f6b9eSfredette #ifdef DDB
119ae1f6b9eSfredette 	if (ch == '+') {
120ae1f6b9eSfredette 		if (nplus++ > 3) Debugger();
121ae1f6b9eSfredette 	} else nplus = 0;
122ae1f6b9eSfredette #endif
123ae1f6b9eSfredette 	return ch;
124ae1f6b9eSfredette }
125ae1f6b9eSfredette 
126ae1f6b9eSfredette static void
prom_cninit(struct consdev * cn)12710b1a7beSchs prom_cninit(struct consdev *cn)
128ae1f6b9eSfredette {
129ae1f6b9eSfredette }
130ae1f6b9eSfredette 
131ae1f6b9eSfredette /*
132ae1f6b9eSfredette  * PROM console output putchar.
133ae1f6b9eSfredette  */
134ae1f6b9eSfredette static void
prom_cnputc(dev_t dev,int c)13510b1a7beSchs prom_cnputc(dev_t dev, int c)
136ae1f6b9eSfredette {
137ae1f6b9eSfredette 	int s;
138ae1f6b9eSfredette 
139ae1f6b9eSfredette 	s = splhigh();
140ae1f6b9eSfredette 	prom_putchar(c);
141ae1f6b9eSfredette 	splx(s);
142ae1f6b9eSfredette }
143ae1f6b9eSfredette 
144ae1f6b9eSfredette void
prom_cnpollc(dev_t dev,int on)14510b1a7beSchs prom_cnpollc(dev_t dev, int on)
146ae1f6b9eSfredette {
147ae1f6b9eSfredette 	if (on) {
148ae1f6b9eSfredette                 /* Entering debugger. */
149ae1f6b9eSfredette #if NFB > 0
150ae1f6b9eSfredette                 fb_unblank();
151ae1f6b9eSfredette #endif
152ae1f6b9eSfredette 	} else {
153ae1f6b9eSfredette                 /* Resuming kernel. */
154ae1f6b9eSfredette 	}
155ae1f6b9eSfredette #if NPCONS > 0
156ae1f6b9eSfredette 	pcons_cnpollc(dev, on);
157ae1f6b9eSfredette #endif
158ae1f6b9eSfredette }
159ae1f6b9eSfredette 
160ae1f6b9eSfredette /*****************************************************************/
161ae1f6b9eSfredette 
162ae1f6b9eSfredette #ifdef	DEBUG
163ae1f6b9eSfredette #define	DBPRINT(x)	prom_printf x
164ae1f6b9eSfredette #else
165ae1f6b9eSfredette #define	DBPRINT(x)
166ae1f6b9eSfredette #endif
167ae1f6b9eSfredette 
168ae1f6b9eSfredette #ifdef notyet /* PROM_OBP_V2 */
169ae1f6b9eSfredette void
prom_get_device_args(const char * prop,char * dev,unsigned int dev_sz,char * args,unsigned int args_sz)17010b1a7beSchs prom_get_device_args(const char *prop, char *dev, unsigned int dev_sz,
17110b1a7beSchs     char *args, unsigned int args_sz)
172ae1f6b9eSfredette {
173ae1f6b9eSfredette 	char *cp, buffer[128];
174ae1f6b9eSfredette 
175ae1f6b9eSfredette 	getpropstringA(prom_findroot(), (char *)prop, buffer, sizeof buffer);
176ae1f6b9eSfredette 
177ae1f6b9eSfredette 	/*
178ae1f6b9eSfredette  	* Extract device-specific arguments from a PROM device path (if any)
179ae1f6b9eSfredette  	*/
180ae1f6b9eSfredette 	cp = buffer + strlen(buffer);
181ae1f6b9eSfredette 	while (cp >= buffer) {
182ae1f6b9eSfredette 		if (*cp == ':') {
183ae1f6b9eSfredette 			strncpy(args, cp+1, args_sz);
184ae1f6b9eSfredette 			*cp = '\0';
185ae1f6b9eSfredette 			strncpy(dev, buffer, dev_sz);
186ae1f6b9eSfredette 			break;
187ae1f6b9eSfredette 		}
188ae1f6b9eSfredette 		cp--;
189ae1f6b9eSfredette 	}
190ae1f6b9eSfredette }
191ae1f6b9eSfredette #endif	/* PROM_OBP_V2 */
192ae1f6b9eSfredette 
193ae1f6b9eSfredette /*
194ae1f6b9eSfredette  * This function replaces sys/dev/cninit.c
195ae1f6b9eSfredette  * Determine which device is the console using
196ae1f6b9eSfredette  * the PROM "input source" and "output sink".
197ae1f6b9eSfredette  */
198ae1f6b9eSfredette void
consinit(void)19910b1a7beSchs consinit(void)
200ae1f6b9eSfredette {
201ae1f6b9eSfredette #ifdef	notyet /* PROM_OBP_V2 */
202ae1f6b9eSfredette 	char buffer[128];
203ae1f6b9eSfredette #endif	/* PROM_OBP_V2 */
2046df30aa4Stsutsui 	const char *consname = "unknown";
20577a6b82bSgehenna #if KGDB
20677a6b82bSgehenna #if NZS > 0
20777a6b82bSgehenna 	extern const struct cdevsw zstty_cdevsw;
20877a6b82bSgehenna #endif
20977a6b82bSgehenna #endif
210ae1f6b9eSfredette 
211ae1f6b9eSfredette 	DBPRINT(("consinit()\r\n"));
212ae1f6b9eSfredette 	if (cn_tab != &consdev_prom) return;
213ae1f6b9eSfredette 
214ae1f6b9eSfredette 	switch(prom_version()) {
215ae1f6b9eSfredette #ifdef	PROM_OLDMON
216ae1f6b9eSfredette 	case PROM_OLDMON:
217ae1f6b9eSfredette 	case PROM_OBP_V0:
218ae1f6b9eSfredette 		switch(prom_stdin()) {
219ae1f6b9eSfredette 		case PROMDEV_KBD:
220ae1f6b9eSfredette 			consname = "keyboard/display";
221ae1f6b9eSfredette 			break;
222ae1f6b9eSfredette 		case PROMDEV_TTYA:
223ae1f6b9eSfredette 			consname = "ttya";
224ae1f6b9eSfredette 			break;
225ae1f6b9eSfredette 		case PROMDEV_TTYB:
226ae1f6b9eSfredette 			consname = "ttyb";
227ae1f6b9eSfredette 			break;
228ae1f6b9eSfredette 		}
229ae1f6b9eSfredette 		break;
230ae1f6b9eSfredette #endif	/* PROM_OLDMON */
231ae1f6b9eSfredette 
232ae1f6b9eSfredette #ifdef	notyet /* PROM_OBP_V2 */
233ae1f6b9eSfredette 	case PROM_OBP_V2:
234ae1f6b9eSfredette 	case PROM_OBP_V3:
235ae1f6b9eSfredette 	case PROM_OPENFIRM:
236ae1f6b9eSfredette 
237ae1f6b9eSfredette 		/* Save PROM arguments for device matching */
238ae1f6b9eSfredette 		prom_get_device_args("stdin-path",
239ae1f6b9eSfredette 				     buffer,
240ae1f6b9eSfredette 				     sizeof(buffer),
241ae1f6b9eSfredette 				     prom_stdin_args,
242ae1f6b9eSfredette 				     sizeof(prom_stdin_args));
243ae1f6b9eSfredette 		prom_get_device_args("stdout-path",
244ae1f6b9eSfredette 				     buffer,
245ae1f6b9eSfredette 				     sizeof(buffer),
246ae1f6b9eSfredette 				     prom_stdout_args,
247ae1f6b9eSfredette 				     sizeof(prom_stdout_args));
248ae1f6b9eSfredette 
249ae1f6b9eSfredette 		/*
250ae1f6b9eSfredette 		 * Translate the STDIO package instance (`ihandle') -- that
251ae1f6b9eSfredette 		 * the PROM has already opened for us -- to a device tree
252ae1f6b9eSfredette 		 * node (i.e. a `phandle').
253ae1f6b9eSfredette 		 */
254ae1f6b9eSfredette 		DBPRINT(("stdin instance = %x\r\n", prom_stdin()));
255ae1f6b9eSfredette 		if ((prom_stdin_node = prom_instance_to_package(prom_stdin())) == 0) {
256ae1f6b9eSfredette 			printf("WARNING: no PROM stdin\n");
257ae1f6b9eSfredette 		}
258ae1f6b9eSfredette 		DBPRINT(("stdin package = %x\r\n", prom_stdin_node));
259ae1f6b9eSfredette 
260ae1f6b9eSfredette 		DBPRINT(("stdout instance = %x\r\n", prom_stdout()));
261ae1f6b9eSfredette 		if ((prom_stdout_node = prom_instance_to_package(prom_stdout())) == 0) {
262ae1f6b9eSfredette 			printf("WARNING: no PROM stdout\n");
263ae1f6b9eSfredette 		}
264ae1f6b9eSfredette 		DBPRINT(("stdout package = %x\r\n", prom_stdout_node));
265ae1f6b9eSfredette 		DBPRINT(("buffer @ %p\r\n", buffer));
266ae1f6b9eSfredette 
267df41171fStsutsui 		if (prom_stdin_node && prom_node_has_property(prom_stdin_node, "keyboard")) {
268ae1f6b9eSfredette #if NKBD == 0
269ae1f6b9eSfredette 			printf("cninit: kdb/display not configured\n");
270ae1f6b9eSfredette #endif
271ae1f6b9eSfredette 			consname = "keyboard/display";
272ae1f6b9eSfredette 		} else if (prom_stdout_node)
273ae1f6b9eSfredette 			consname = buffer;
274ae1f6b9eSfredette #endif	/* PROM_OBP_V2 */
275ae1f6b9eSfredette 	}
276ae1f6b9eSfredette 	printf("console is %s\n", consname);
277ae1f6b9eSfredette 
278ae1f6b9eSfredette 	/* Initialize PROM console */
279ae1f6b9eSfredette 	(*cn_tab->cn_probe)(cn_tab);
280ae1f6b9eSfredette 	(*cn_tab->cn_init)(cn_tab);
281ae1f6b9eSfredette 
282ae1f6b9eSfredette #ifdef	KGDB
283ae1f6b9eSfredette 	/* Set up KGDB */
284ae1f6b9eSfredette #if NZS > 0
28577a6b82bSgehenna 	if (cdevsw_lookup(kgdb_dev) == &zstty_cdevsw)
286ae1f6b9eSfredette 		zs_kgdb_init();
287ae1f6b9eSfredette #endif	/* NZS > 0 */
288ae1f6b9eSfredette #endif	/* KGDB */
289ae1f6b9eSfredette }
290ae1f6b9eSfredette 
291