xref: /titanic_53/usr/src/uts/i86pc/io/consplat.c (revision 843e19887f64dde75055cf8842fc4db2171eff45)
1ae115bc7Smrj /*
2ae115bc7Smrj  * CDDL HEADER START
3ae115bc7Smrj  *
4ae115bc7Smrj  * The contents of this file are subject to the terms of the
5ae115bc7Smrj  * Common Development and Distribution License (the "License").
6ae115bc7Smrj  * You may not use this file except in compliance with the License.
7ae115bc7Smrj  *
8ae115bc7Smrj  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9ae115bc7Smrj  * or http://www.opensolaris.org/os/licensing.
10ae115bc7Smrj  * See the License for the specific language governing permissions
11ae115bc7Smrj  * and limitations under the License.
12ae115bc7Smrj  *
13ae115bc7Smrj  * When distributing Covered Code, include this CDDL HEADER in each
14ae115bc7Smrj  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15ae115bc7Smrj  * If applicable, add the following below this CDDL HEADER, with the
16ae115bc7Smrj  * fields enclosed by brackets "[]" replaced with your own identifying
17ae115bc7Smrj  * information: Portions Copyright [yyyy] [name of copyright owner]
18ae115bc7Smrj  *
19ae115bc7Smrj  * CDDL HEADER END
20ae115bc7Smrj  */
21ae115bc7Smrj 
22ae115bc7Smrj /*
23c9503a49Slq150181  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24ae115bc7Smrj  * Use is subject to license terms.
25ae115bc7Smrj  */
26ae115bc7Smrj 
27ae115bc7Smrj #pragma ident	"%Z%%M%	%I%	%E% SMI"
28ae115bc7Smrj 
29ae115bc7Smrj /*
30ae115bc7Smrj  * isa-specific console configuration routines
31ae115bc7Smrj  */
32ae115bc7Smrj 
33ae115bc7Smrj #include <sys/types.h>
34ae115bc7Smrj #include <sys/param.h>
35ae115bc7Smrj #include <sys/cmn_err.h>
36ae115bc7Smrj #include <sys/systm.h>
37ae115bc7Smrj #include <sys/conf.h>
38ae115bc7Smrj #include <sys/debug.h>
39ae115bc7Smrj #include <sys/ddi.h>
40ae115bc7Smrj #include <sys/sunddi.h>
41ae115bc7Smrj #include <sys/sunndi.h>
42ae115bc7Smrj #include <sys/esunddi.h>
43ae115bc7Smrj #include <sys/ddi_impldefs.h>
44ae115bc7Smrj #include <sys/promif.h>
45ae115bc7Smrj #include <sys/modctl.h>
46ae115bc7Smrj #include <sys/termios.h>
47*843e1988Sjohnlev #if defined(__xpv)
48*843e1988Sjohnlev #include <sys/hypervisor.h>
49*843e1988Sjohnlev #include <sys/boot_console.h>
50*843e1988Sjohnlev #endif
51ae115bc7Smrj 
52ae115bc7Smrj /* The names of currently supported graphics drivers on x86 */
53ae115bc7Smrj static char *
54ae115bc7Smrj gfxdrv_name[] = {
55ae115bc7Smrj 	"vgatext",
56ae115bc7Smrj 	"i915",
57ae115bc7Smrj 	"nvidia"
58ae115bc7Smrj };
59ae115bc7Smrj 
60ae115bc7Smrj int
61ae115bc7Smrj plat_use_polled_debug() {
62ae115bc7Smrj 	return (0);
63ae115bc7Smrj }
64ae115bc7Smrj 
65ae115bc7Smrj int
66ae115bc7Smrj plat_support_serial_kbd_and_ms() {
67ae115bc7Smrj 	return (0);
68ae115bc7Smrj }
69ae115bc7Smrj 
70*843e1988Sjohnlev #define	A_CNT(arr)	(sizeof (arr) / sizeof (arr[0]))
71*843e1988Sjohnlev 
72ae115bc7Smrj #define	CONS_INVALID	-1
73ae115bc7Smrj #define	CONS_SCREEN	0
74ae115bc7Smrj #define	CONS_TTYA	1
75ae115bc7Smrj #define	CONS_TTYB	2
76ae115bc7Smrj #define	CONS_USBSER	3
77*843e1988Sjohnlev #define	CONS_HYPERVISOR	4
78ae115bc7Smrj 
79ae115bc7Smrj static int
80ae115bc7Smrj console_type()
81ae115bc7Smrj {
82ae115bc7Smrj 	static int boot_console = CONS_INVALID;
83ae115bc7Smrj 
84ae115bc7Smrj 	char *cons;
85ae115bc7Smrj 	dev_info_t *root;
86ae115bc7Smrj 
87ae115bc7Smrj 	if (boot_console != CONS_INVALID)
88ae115bc7Smrj 		return (boot_console);
89ae115bc7Smrj 
90*843e1988Sjohnlev #if defined(__xpv)
91*843e1988Sjohnlev 	if (!DOMAIN_IS_INITDOMAIN(xen_info) || bcons_hypervisor_redirect()) {
92*843e1988Sjohnlev 		boot_console = CONS_HYPERVISOR;
93*843e1988Sjohnlev 		return (boot_console);
94*843e1988Sjohnlev 	}
95*843e1988Sjohnlev #endif /* __xpv */
96*843e1988Sjohnlev 
97ae115bc7Smrj 	/*
98ae115bc7Smrj 	 * console is defined by "console" property, with
99ae115bc7Smrj 	 * fallback on the old "input-device" property.
100ae115bc7Smrj 	 */
101ae115bc7Smrj 	boot_console = CONS_SCREEN;	/* default is screen/kb */
102ae115bc7Smrj 	root = ddi_root_node();
103ae115bc7Smrj 	if ((ddi_prop_lookup_string(DDI_DEV_T_ANY, root,
104ae115bc7Smrj 	    DDI_PROP_DONTPASS, "console", &cons) == DDI_SUCCESS) ||
105ae115bc7Smrj 	    (ddi_prop_lookup_string(DDI_DEV_T_ANY, root,
106ae115bc7Smrj 	    DDI_PROP_DONTPASS, "input-device", &cons) == DDI_SUCCESS)) {
107*843e1988Sjohnlev 		if (strcmp(cons, "ttya") == 0) {
108ae115bc7Smrj 			boot_console = CONS_TTYA;
109*843e1988Sjohnlev 		} else if (strcmp(cons, "ttyb") == 0) {
110ae115bc7Smrj 			boot_console = CONS_TTYB;
111*843e1988Sjohnlev 		} else if (strcmp(cons, "usb-serial") == 0) {
112ae115bc7Smrj 			(void) i_ddi_attach_hw_nodes("ehci");
113ae115bc7Smrj 			(void) i_ddi_attach_hw_nodes("uhci");
114ae115bc7Smrj 			(void) i_ddi_attach_hw_nodes("ohci");
115ae115bc7Smrj 			/*
116ae115bc7Smrj 			 * USB device enumerate asynchronously.
117ae115bc7Smrj 			 * Wait 2 seconds for USB serial devices to attach.
118ae115bc7Smrj 			 */
119ae115bc7Smrj 			delay(drv_usectohz(2000000));
120ae115bc7Smrj 			boot_console = CONS_USBSER;
121*843e1988Sjohnlev #if defined(__xpv)
122*843e1988Sjohnlev 		} else if (strcmp(cons, "hypervisor") == 0) {
123*843e1988Sjohnlev 			boot_console = CONS_HYPERVISOR;
124*843e1988Sjohnlev #endif /* __xpv */
125ae115bc7Smrj 		}
126ae115bc7Smrj 		ddi_prop_free(cons);
127ae115bc7Smrj 	}
128ae115bc7Smrj 	return (boot_console);
129ae115bc7Smrj }
130ae115bc7Smrj 
131ae115bc7Smrj int
132ae115bc7Smrj plat_stdin_is_keyboard(void)
133ae115bc7Smrj {
134ae115bc7Smrj 	return (console_type() == CONS_SCREEN);
135ae115bc7Smrj }
136ae115bc7Smrj 
137ae115bc7Smrj int
138ae115bc7Smrj plat_stdout_is_framebuffer(void)
139ae115bc7Smrj {
140ae115bc7Smrj 	return (console_type() == CONS_SCREEN);
141ae115bc7Smrj }
142ae115bc7Smrj 
143ae115bc7Smrj /*
144ae115bc7Smrj  * Return generic path to keyboard device from the alias.
145ae115bc7Smrj  */
146ae115bc7Smrj char *
147ae115bc7Smrj plat_kbdpath(void)
148ae115bc7Smrj {
149ae115bc7Smrj 	/*
150ae115bc7Smrj 	 * Hardcode to isa keyboard path
151ae115bc7Smrj 	 * XXX make it settable via bootprop?
152ae115bc7Smrj 	 */
153ae115bc7Smrj 	return ("/isa/i8042@1,60/keyboard@0");
154ae115bc7Smrj }
155ae115bc7Smrj 
156ae115bc7Smrj /*
157ae115bc7Smrj  * Return generic path to display device from the alias.
158ae115bc7Smrj  */
159ae115bc7Smrj char *
160ae115bc7Smrj plat_fbpath(void)
161ae115bc7Smrj {
162ae115bc7Smrj 	static char *fbpath = NULL;
163ae115bc7Smrj 	static char fbpath_buf[MAXPATHLEN];
164ae115bc7Smrj 	major_t major;
165*843e1988Sjohnlev 	dev_info_t *dip, *dip_pseudo = NULL;
166ae115bc7Smrj 	int i;
167ae115bc7Smrj 
168*843e1988Sjohnlev 	/* lookup the dip for the pseudo device */
169*843e1988Sjohnlev 	(void) resolve_pathname("/pseudo", &dip_pseudo, NULL, NULL);
170*843e1988Sjohnlev 
171*843e1988Sjohnlev 	for (i = 0; i < A_CNT(gfxdrv_name); i++) {
172ae115bc7Smrj 		/*
173ae115bc7Smrj 		 * look for first instance of each driver
174ae115bc7Smrj 		 */
175*843e1988Sjohnlev 		if ((major = ddi_name_to_major(gfxdrv_name[i])) == (major_t)-1)
176*843e1988Sjohnlev 			continue;
177*843e1988Sjohnlev 
178*843e1988Sjohnlev 		if ((dip = devnamesp[major].dn_head) == NULL)
179*843e1988Sjohnlev 			continue;
180*843e1988Sjohnlev 
181*843e1988Sjohnlev 		/*
182*843e1988Sjohnlev 		 * We're looking for a real hardware device here so skip
183*843e1988Sjohnlev 		 * any pseudo devices.  When could a framebuffer hardware
184*843e1988Sjohnlev 		 * driver also have a pseudo node?  Well, some framebuffer
185*843e1988Sjohnlev 		 * hardware drivers (nvidia) also create pseudo nodes for
186*843e1988Sjohnlev 		 * administration purposes, and these nodes will exist
187*843e1988Sjohnlev 		 * regardless of if the actual associated hardware
188*843e1988Sjohnlev 		 * is present or not.
189*843e1988Sjohnlev 		 */
190*843e1988Sjohnlev 		if (ddi_get_parent(dip) == dip_pseudo)
191*843e1988Sjohnlev 			continue;
192*843e1988Sjohnlev 
193*843e1988Sjohnlev 		if (i_ddi_attach_node_hierarchy(dip) == DDI_SUCCESS) {
194ae115bc7Smrj 			(void) ddi_pathname(dip, fbpath_buf);
195ae115bc7Smrj 			fbpath = fbpath_buf;
196ae115bc7Smrj 		}
197ae115bc7Smrj 
198ae115bc7Smrj 		if (fbpath)
199*843e1988Sjohnlev 			break;
200ae115bc7Smrj 	}
201ae115bc7Smrj 
202*843e1988Sjohnlev 	if (dip_pseudo != NULL)
203*843e1988Sjohnlev 		ddi_release_devi(dip_pseudo);
204*843e1988Sjohnlev 
205ae115bc7Smrj 	/* No screen found */
206*843e1988Sjohnlev 	return (fbpath);
207ae115bc7Smrj }
208ae115bc7Smrj 
209ae115bc7Smrj char *
210ae115bc7Smrj plat_mousepath(void)
211ae115bc7Smrj {
212ae115bc7Smrj 	/*
213ae115bc7Smrj 	 * Hardcode to isa mouse path
214ae115bc7Smrj 	 * XXX make it settable via bootprop?
215ae115bc7Smrj 	 */
216ae115bc7Smrj 	return ("/isa/i8042@1,60/mouse@1");
217ae115bc7Smrj }
218ae115bc7Smrj 
219ae115bc7Smrj /* return path of first usb serial device */
220ae115bc7Smrj static char *
221ae115bc7Smrj plat_usbser_path(void)
222ae115bc7Smrj {
223ae115bc7Smrj 	extern dev_info_t *usbser_first_device(void);
224ae115bc7Smrj 
225ae115bc7Smrj 	dev_info_t *us_dip;
226ae115bc7Smrj 	static char *us_path = NULL;
227ae115bc7Smrj 
228ae115bc7Smrj 	if (us_path)
229ae115bc7Smrj 		return (us_path);
230ae115bc7Smrj 
231ae115bc7Smrj 	us_dip = usbser_first_device();
232ae115bc7Smrj 	if (us_dip == NULL)
233ae115bc7Smrj 		return (NULL);
234ae115bc7Smrj 
235ae115bc7Smrj 	us_path = kmem_alloc(MAXPATHLEN, KM_SLEEP);
236ae115bc7Smrj 	(void) ddi_pathname(us_dip, us_path);
237ae115bc7Smrj 	ndi_rele_devi(us_dip);	/* held from usbser_first_device */
238ae115bc7Smrj 	return (us_path);
239ae115bc7Smrj }
240ae115bc7Smrj 
241ae115bc7Smrj /*
242ae115bc7Smrj  * Lacking support for com2 and com3, if that matters.
243ae115bc7Smrj  * Another possible enhancement could be to use properties
244ae115bc7Smrj  * for the port mapping rather than simply hard-code them.
245ae115bc7Smrj  */
246ae115bc7Smrj char *
247ae115bc7Smrj plat_stdinpath(void)
248ae115bc7Smrj {
249ae115bc7Smrj 	switch (console_type()) {
250*843e1988Sjohnlev #if defined(__xpv)
251*843e1988Sjohnlev 	case CONS_HYPERVISOR:
252*843e1988Sjohnlev 		return ("/xpvd/xencons@0");
253*843e1988Sjohnlev #endif /* __xpv */
254ae115bc7Smrj 	case CONS_TTYA:
255ae115bc7Smrj 		return ("/isa/asy@1,3f8:a");
256ae115bc7Smrj 	case CONS_TTYB:
257ae115bc7Smrj 		return ("/isa/asy@1,2f8:b");
258ae115bc7Smrj 	case CONS_USBSER:
259ae115bc7Smrj 		return (plat_usbser_path());
260ae115bc7Smrj 	case CONS_SCREEN:
261ae115bc7Smrj 	default:
262ae115bc7Smrj 		break;
263ae115bc7Smrj 	};
264ae115bc7Smrj 	return (plat_kbdpath());
265ae115bc7Smrj }
266ae115bc7Smrj 
267ae115bc7Smrj char *
268ae115bc7Smrj plat_stdoutpath(void)
269ae115bc7Smrj {
270ae115bc7Smrj 	switch (console_type()) {
271*843e1988Sjohnlev #if defined(__xpv)
272*843e1988Sjohnlev 	case CONS_HYPERVISOR:
273*843e1988Sjohnlev 		return ("/xpvd/xencons@0");
274*843e1988Sjohnlev #endif /* __xpv */
275ae115bc7Smrj 	case CONS_TTYA:
276ae115bc7Smrj 		return ("/isa/asy@1,3f8:a");
277ae115bc7Smrj 	case CONS_TTYB:
278ae115bc7Smrj 		return ("/isa/asy@1,2f8:b");
279ae115bc7Smrj 	case CONS_USBSER:
280ae115bc7Smrj 		return (plat_usbser_path());
281ae115bc7Smrj 	case CONS_SCREEN:
282ae115bc7Smrj 	default:
283ae115bc7Smrj 		break;
284ae115bc7Smrj 	};
285ae115bc7Smrj 	return (plat_fbpath());
286ae115bc7Smrj }
287ae115bc7Smrj 
288ae115bc7Smrj /*
289ae115bc7Smrj  * If VIS_PIXEL mode will be implemented on x86, these following
290ae115bc7Smrj  * functions should be re-considered. Now these functions are
291ae115bc7Smrj  * unused on x86.
292ae115bc7Smrj  */
293ae115bc7Smrj void
294c9503a49Slq150181 plat_tem_get_inverses(int *inverse, int *inverse_screen)
295c9503a49Slq150181 {
296c9503a49Slq150181 	*inverse = 0;
297c9503a49Slq150181 	*inverse_screen = 0;
298c9503a49Slq150181 }
299c9503a49Slq150181 
300c9503a49Slq150181 void
301ae115bc7Smrj plat_tem_get_prom_font_size(int *charheight, int *windowtop)
302ae115bc7Smrj {
303ae115bc7Smrj 	*charheight = 0;
304ae115bc7Smrj 	*windowtop = 0;
305ae115bc7Smrj }
306ae115bc7Smrj 
307*843e1988Sjohnlev /*ARGSUSED*/
308ae115bc7Smrj void
309ae115bc7Smrj plat_tem_get_prom_size(size_t *height, size_t *width)
310ae115bc7Smrj {
311*843e1988Sjohnlev 	panic("unimplemented at line %d of %s", __LINE__, __FILE__);
312ae115bc7Smrj }
313ae115bc7Smrj 
314ae115bc7Smrj void
315ae115bc7Smrj plat_tem_hide_prom_cursor(void)
316ae115bc7Smrj {
317*843e1988Sjohnlev 	panic("unimplemented at line %d of %s", __LINE__, __FILE__);
318ae115bc7Smrj }
319ae115bc7Smrj 
320*843e1988Sjohnlev /*ARGSUSED*/
321ae115bc7Smrj void
322ae115bc7Smrj plat_tem_get_prom_pos(uint32_t *row, uint32_t *col)
323ae115bc7Smrj {
324*843e1988Sjohnlev 	panic("unimplemented at line %d of %s", __LINE__, __FILE__);
325ae115bc7Smrj }
326