xref: /onnv-gate/usr/src/uts/i86pc/io/consplat.c (revision 11842:7df39529966f)
13446Smrj /*
23446Smrj  * CDDL HEADER START
33446Smrj  *
43446Smrj  * The contents of this file are subject to the terms of the
53446Smrj  * Common Development and Distribution License (the "License").
63446Smrj  * You may not use this file except in compliance with the License.
73446Smrj  *
83446Smrj  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
93446Smrj  * or http://www.opensolaris.org/os/licensing.
103446Smrj  * See the License for the specific language governing permissions
113446Smrj  * and limitations under the License.
123446Smrj  *
133446Smrj  * When distributing Covered Code, include this CDDL HEADER in each
143446Smrj  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
153446Smrj  * If applicable, add the following below this CDDL HEADER, with the
163446Smrj  * fields enclosed by brackets "[]" replaced with your own identifying
173446Smrj  * information: Portions Copyright [yyyy] [name of copyright owner]
183446Smrj  *
193446Smrj  * CDDL HEADER END
203446Smrj  */
213446Smrj 
223446Smrj /*
2311762SEnrico.Perla@Sun.COM  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
243446Smrj  * Use is subject to license terms.
253446Smrj  */
263446Smrj 
273446Smrj /*
283446Smrj  * isa-specific console configuration routines
293446Smrj  */
303446Smrj 
313446Smrj #include <sys/types.h>
323446Smrj #include <sys/param.h>
333446Smrj #include <sys/cmn_err.h>
343446Smrj #include <sys/systm.h>
353446Smrj #include <sys/conf.h>
363446Smrj #include <sys/debug.h>
373446Smrj #include <sys/ddi.h>
383446Smrj #include <sys/sunddi.h>
393446Smrj #include <sys/sunndi.h>
403446Smrj #include <sys/esunddi.h>
413446Smrj #include <sys/ddi_impldefs.h>
423446Smrj #include <sys/promif.h>
433446Smrj #include <sys/modctl.h>
443446Smrj #include <sys/termios.h>
459306SAaron.Zang@Sun.COM #include <sys/pci.h>
465084Sjohnlev #if defined(__xpv)
475084Sjohnlev #include <sys/hypervisor.h>
485084Sjohnlev #include <sys/boot_console.h>
495084Sjohnlev #endif
503446Smrj 
519149SJudy.Chen@Sun.COM extern int pseudo_isa;
529149SJudy.Chen@Sun.COM 
533446Smrj int
plat_use_polled_debug()543446Smrj plat_use_polled_debug() {
553446Smrj 	return (0);
563446Smrj }
573446Smrj 
583446Smrj int
plat_support_serial_kbd_and_ms()593446Smrj plat_support_serial_kbd_and_ms() {
603446Smrj 	return (0);
613446Smrj }
623446Smrj 
635084Sjohnlev #define	A_CNT(arr)	(sizeof (arr) / sizeof (arr[0]))
645084Sjohnlev 
653446Smrj #define	CONS_INVALID	-1
663446Smrj #define	CONS_SCREEN	0
673446Smrj #define	CONS_TTYA	1
683446Smrj #define	CONS_TTYB	2
693446Smrj #define	CONS_USBSER	3
705084Sjohnlev #define	CONS_HYPERVISOR	4
713446Smrj 
725594Srz201010 char *plat_fbpath(void);
735594Srz201010 
743446Smrj static int
console_type()753446Smrj console_type()
763446Smrj {
773446Smrj 	static int boot_console = CONS_INVALID;
783446Smrj 
793446Smrj 	char *cons;
803446Smrj 	dev_info_t *root;
813446Smrj 
823446Smrj 	if (boot_console != CONS_INVALID)
833446Smrj 		return (boot_console);
843446Smrj 
855084Sjohnlev #if defined(__xpv)
865084Sjohnlev 	if (!DOMAIN_IS_INITDOMAIN(xen_info) || bcons_hypervisor_redirect()) {
875084Sjohnlev 		boot_console = CONS_HYPERVISOR;
885084Sjohnlev 		return (boot_console);
895084Sjohnlev 	}
905084Sjohnlev #endif /* __xpv */
915084Sjohnlev 
923446Smrj 	/*
933446Smrj 	 * console is defined by "console" property, with
943446Smrj 	 * fallback on the old "input-device" property.
955594Srz201010 	 * If "input-device" is not defined either, also check "output-device".
963446Smrj 	 */
973446Smrj 	boot_console = CONS_SCREEN;	/* default is screen/kb */
983446Smrj 	root = ddi_root_node();
993446Smrj 	if ((ddi_prop_lookup_string(DDI_DEV_T_ANY, root,
1003446Smrj 	    DDI_PROP_DONTPASS, "console", &cons) == DDI_SUCCESS) ||
1013446Smrj 	    (ddi_prop_lookup_string(DDI_DEV_T_ANY, root,
1025594Srz201010 	    DDI_PROP_DONTPASS, "input-device", &cons) == DDI_SUCCESS) ||
1035594Srz201010 	    (ddi_prop_lookup_string(DDI_DEV_T_ANY, root,
1045594Srz201010 	    DDI_PROP_DONTPASS, "output-device", &cons) == DDI_SUCCESS)) {
1055084Sjohnlev 		if (strcmp(cons, "ttya") == 0) {
1063446Smrj 			boot_console = CONS_TTYA;
1075084Sjohnlev 		} else if (strcmp(cons, "ttyb") == 0) {
1083446Smrj 			boot_console = CONS_TTYB;
1095084Sjohnlev 		} else if (strcmp(cons, "usb-serial") == 0) {
1103446Smrj 			(void) i_ddi_attach_hw_nodes("ehci");
1113446Smrj 			(void) i_ddi_attach_hw_nodes("uhci");
1123446Smrj 			(void) i_ddi_attach_hw_nodes("ohci");
1133446Smrj 			/*
1143446Smrj 			 * USB device enumerate asynchronously.
1153446Smrj 			 * Wait 2 seconds for USB serial devices to attach.
1163446Smrj 			 */
1173446Smrj 			delay(drv_usectohz(2000000));
1183446Smrj 			boot_console = CONS_USBSER;
1195084Sjohnlev #if defined(__xpv)
1205084Sjohnlev 		} else if (strcmp(cons, "hypervisor") == 0) {
1215084Sjohnlev 			boot_console = CONS_HYPERVISOR;
1225084Sjohnlev #endif /* __xpv */
1233446Smrj 		}
1243446Smrj 		ddi_prop_free(cons);
1253446Smrj 	}
1265594Srz201010 
1275594Srz201010 	/*
1285594Srz201010 	 * If the console is configured to use a framebuffer but none
1295594Srz201010 	 * could be found, fallback to "ttya" since it's likely to exist
1305594Srz201010 	 * and it matches longstanding behavior on SPARC.
1315594Srz201010 	 */
1325594Srz201010 	if (boot_console == CONS_SCREEN && plat_fbpath() == NULL)
1335594Srz201010 		boot_console = CONS_TTYA;
1345594Srz201010 
1353446Smrj 	return (boot_console);
1363446Smrj }
1373446Smrj 
1383446Smrj int
plat_stdin_is_keyboard(void)1393446Smrj plat_stdin_is_keyboard(void)
1403446Smrj {
1413446Smrj 	return (console_type() == CONS_SCREEN);
1423446Smrj }
1433446Smrj 
1443446Smrj int
plat_stdout_is_framebuffer(void)1453446Smrj plat_stdout_is_framebuffer(void)
1463446Smrj {
1473446Smrj 	return (console_type() == CONS_SCREEN);
1483446Smrj }
1493446Smrj 
1509149SJudy.Chen@Sun.COM static char *
plat_devpath(char * name,char * path)1519149SJudy.Chen@Sun.COM plat_devpath(char *name, char *path)
1529149SJudy.Chen@Sun.COM {
1539149SJudy.Chen@Sun.COM 	major_t major;
1549149SJudy.Chen@Sun.COM 	dev_info_t *dip, *pdip;
1559149SJudy.Chen@Sun.COM 
1569149SJudy.Chen@Sun.COM 	if ((major = ddi_name_to_major(name)) == (major_t)-1)
1579149SJudy.Chen@Sun.COM 		return (NULL);
1589149SJudy.Chen@Sun.COM 
1599149SJudy.Chen@Sun.COM 	if ((dip = devnamesp[major].dn_head) == NULL)
1609149SJudy.Chen@Sun.COM 		return (NULL);
1619149SJudy.Chen@Sun.COM 
1629149SJudy.Chen@Sun.COM 	pdip = ddi_get_parent(dip);
1639149SJudy.Chen@Sun.COM 	if (i_ddi_attach_node_hierarchy(pdip) != DDI_SUCCESS)
1649149SJudy.Chen@Sun.COM 		return (NULL);
1659149SJudy.Chen@Sun.COM 	if (ddi_initchild(pdip, dip) != DDI_SUCCESS)
1669149SJudy.Chen@Sun.COM 		return (NULL);
1679149SJudy.Chen@Sun.COM 
1689149SJudy.Chen@Sun.COM 	(void) ddi_pathname(dip, path);
1699149SJudy.Chen@Sun.COM 
1709149SJudy.Chen@Sun.COM 	return (path);
1719149SJudy.Chen@Sun.COM }
1729149SJudy.Chen@Sun.COM 
1733446Smrj /*
1743446Smrj  * Return generic path to keyboard device from the alias.
1753446Smrj  */
1763446Smrj char *
plat_kbdpath(void)1773446Smrj plat_kbdpath(void)
1783446Smrj {
1799149SJudy.Chen@Sun.COM 	static char kbpath[MAXPATHLEN];
1809149SJudy.Chen@Sun.COM 
1813446Smrj 	/*
1823446Smrj 	 * Hardcode to isa keyboard path
1833446Smrj 	 * XXX make it settable via bootprop?
1843446Smrj 	 */
1859149SJudy.Chen@Sun.COM 	if (pseudo_isa)
1869149SJudy.Chen@Sun.COM 		return ("/isa/i8042@1,60/keyboard@0");
1879149SJudy.Chen@Sun.COM 
1889149SJudy.Chen@Sun.COM 	if (plat_devpath("kb8042", kbpath) == NULL)
1899149SJudy.Chen@Sun.COM 		return (NULL);
1909149SJudy.Chen@Sun.COM 
1919149SJudy.Chen@Sun.COM 	return (kbpath);
1923446Smrj }
1933446Smrj 
19411762SEnrico.Perla@Sun.COM /*
19511762SEnrico.Perla@Sun.COM  * NOTE: this function is duplicated here and in gfx_private/vgatext while
19611762SEnrico.Perla@Sun.COM  *       we work on a set of commitable interfaces to sunpci.c.
19711762SEnrico.Perla@Sun.COM  *
19811762SEnrico.Perla@Sun.COM  * Use the class code to determine if the device is a PCI-to-PCI bridge.
19911762SEnrico.Perla@Sun.COM  * Returns:  B_TRUE  if the device is a bridge.
20011762SEnrico.Perla@Sun.COM  *           B_FALSE if the device is not a bridge or the property cannot be
20111762SEnrico.Perla@Sun.COM  *		     retrieved.
20211762SEnrico.Perla@Sun.COM  */
20311762SEnrico.Perla@Sun.COM static boolean_t
is_pci_bridge(dev_info_t * dip)20411762SEnrico.Perla@Sun.COM is_pci_bridge(dev_info_t *dip)
20511762SEnrico.Perla@Sun.COM {
20611762SEnrico.Perla@Sun.COM 	uint32_t class_code;
20711762SEnrico.Perla@Sun.COM 
20811762SEnrico.Perla@Sun.COM 	class_code = (uint32_t)ddi_prop_get_int(DDI_DEV_T_ANY, dip,
20911762SEnrico.Perla@Sun.COM 	    DDI_PROP_DONTPASS, "class-code", 0xffffffff);
21011762SEnrico.Perla@Sun.COM 
21111762SEnrico.Perla@Sun.COM 	if (class_code == 0xffffffff || class_code == DDI_PROP_NOT_FOUND)
21211762SEnrico.Perla@Sun.COM 		return (B_FALSE);
21311762SEnrico.Perla@Sun.COM 
21411762SEnrico.Perla@Sun.COM 	class_code &= 0x00ffff00;
21511762SEnrico.Perla@Sun.COM 	if (class_code == ((PCI_CLASS_BRIDGE << 16) | (PCI_BRIDGE_PCI << 8)))
21611762SEnrico.Perla@Sun.COM 		return (B_TRUE);
21711762SEnrico.Perla@Sun.COM 
21811762SEnrico.Perla@Sun.COM 	return (B_FALSE);
21911762SEnrico.Perla@Sun.COM }
22011762SEnrico.Perla@Sun.COM 
221*11842SEdward.Shu@Sun.COM /*
222*11842SEdward.Shu@Sun.COM  * Type for the parameter of find_fb_dev()
223*11842SEdward.Shu@Sun.COM  */
224*11842SEdward.Shu@Sun.COM struct find_fb_dev_param
225*11842SEdward.Shu@Sun.COM {
226*11842SEdward.Shu@Sun.COM 	dev_info_t *found_dip;	/* dip found for VGA console */
227*11842SEdward.Shu@Sun.COM 	int vga_enable;		/* check PCI_BCNF_BCNTRL_VGA_ENABLE or not */
228*11842SEdward.Shu@Sun.COM };
229*11842SEdward.Shu@Sun.COM 
230*11842SEdward.Shu@Sun.COM /*
231*11842SEdward.Shu@Sun.COM  * The VGA device could be under a subtractive PCI bridge on some systems.
232*11842SEdward.Shu@Sun.COM  * Though the PCI_BCNF_BCNTRL_VGA_ENABLE bit is not set on such subtractive
233*11842SEdward.Shu@Sun.COM  * PCI bridge, the subtractive PCI bridge can forward VGA access if no other
234*11842SEdward.Shu@Sun.COM  * agent claims the access.
235*11842SEdward.Shu@Sun.COM  * The vga_enable element in param acts as a flag, if not set, ignore the
236*11842SEdward.Shu@Sun.COM  * checking for the PCI_BCNF_BCNTRL_VGA_ENABLE bit of the PCI bridge during
237*11842SEdward.Shu@Sun.COM  * the search.
238*11842SEdward.Shu@Sun.COM  */
2399306SAaron.Zang@Sun.COM static int
find_fb_dev(dev_info_t * dip,void * param)240*11842SEdward.Shu@Sun.COM find_fb_dev(dev_info_t *dip, void *param)
2419306SAaron.Zang@Sun.COM {
242*11842SEdward.Shu@Sun.COM 	struct find_fb_dev_param *p = param;
2439306SAaron.Zang@Sun.COM 	char *dev_type;
2449306SAaron.Zang@Sun.COM 	dev_info_t *pdip;
2459306SAaron.Zang@Sun.COM 	char *parent_type;
2469306SAaron.Zang@Sun.COM 
2479306SAaron.Zang@Sun.COM 	if (dip == ddi_root_node())
2489306SAaron.Zang@Sun.COM 		return (DDI_WALK_CONTINUE);
2499306SAaron.Zang@Sun.COM 
2509306SAaron.Zang@Sun.COM 	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
2519306SAaron.Zang@Sun.COM 	    "device_type", &dev_type) != DDI_SUCCESS)
2529306SAaron.Zang@Sun.COM 		return (DDI_WALK_PRUNECHILD);
2539306SAaron.Zang@Sun.COM 
2549306SAaron.Zang@Sun.COM 	if ((strcmp(dev_type, "isa") == 0) || (strcmp(dev_type, "eisa") == 0)) {
2559306SAaron.Zang@Sun.COM 		ddi_prop_free(dev_type);
2569306SAaron.Zang@Sun.COM 		return (DDI_WALK_CONTINUE);
2579306SAaron.Zang@Sun.COM 	}
2589306SAaron.Zang@Sun.COM 
2599306SAaron.Zang@Sun.COM 	if ((strcmp(dev_type, "pci") == 0) ||
2609306SAaron.Zang@Sun.COM 	    (strcmp(dev_type, "pciex") == 0)) {
2619306SAaron.Zang@Sun.COM 		ddi_acc_handle_t pci_conf;
2629306SAaron.Zang@Sun.COM 		uint16_t data16;
26310221SAaron.Zang@Sun.COM 		char *nodename;
2649306SAaron.Zang@Sun.COM 
2659306SAaron.Zang@Sun.COM 		ddi_prop_free(dev_type);
2669306SAaron.Zang@Sun.COM 
267*11842SEdward.Shu@Sun.COM 		if (!p->vga_enable)
268*11842SEdward.Shu@Sun.COM 			return (DDI_WALK_CONTINUE);
269*11842SEdward.Shu@Sun.COM 
27010221SAaron.Zang@Sun.COM 		nodename = ddi_node_name(dip);
2719306SAaron.Zang@Sun.COM 
27211762SEnrico.Perla@Sun.COM 		/*
27311762SEnrico.Perla@Sun.COM 		 * If the node is not a PCI-to-PCI bridge, continue traversing
27411762SEnrico.Perla@Sun.COM 		 * (it could be the root node), otherwise, check for the
27511762SEnrico.Perla@Sun.COM 		 * VGAEnable bit to be set in the Bridge Control Register.
27611762SEnrico.Perla@Sun.COM 		 */
27710221SAaron.Zang@Sun.COM 		if (strcmp(nodename, "pci") == 0) {
27811762SEnrico.Perla@Sun.COM 			if (is_pci_bridge(dip) == B_FALSE)
27911762SEnrico.Perla@Sun.COM 				return (DDI_WALK_CONTINUE);
2809306SAaron.Zang@Sun.COM 		}
2819306SAaron.Zang@Sun.COM 
28210221SAaron.Zang@Sun.COM 		if (i_ddi_attach_node_hierarchy(dip) != DDI_SUCCESS)
28310221SAaron.Zang@Sun.COM 			return (DDI_WALK_PRUNECHILD);
28410221SAaron.Zang@Sun.COM 
28510221SAaron.Zang@Sun.COM 		if (pci_config_setup(dip, &pci_conf) != DDI_SUCCESS)
28610221SAaron.Zang@Sun.COM 			return (DDI_WALK_PRUNECHILD);
28710221SAaron.Zang@Sun.COM 
2889306SAaron.Zang@Sun.COM 		data16 = pci_config_get16(pci_conf, PCI_BCNF_BCNTRL);
2899306SAaron.Zang@Sun.COM 		pci_config_teardown(&pci_conf);
2909306SAaron.Zang@Sun.COM 
2919306SAaron.Zang@Sun.COM 		if (data16 & PCI_BCNF_BCNTRL_VGA_ENABLE)
2929306SAaron.Zang@Sun.COM 			return (DDI_WALK_CONTINUE);
2939306SAaron.Zang@Sun.COM 
2949306SAaron.Zang@Sun.COM 		return (DDI_WALK_PRUNECHILD);
2959306SAaron.Zang@Sun.COM 	}
2969306SAaron.Zang@Sun.COM 
2979306SAaron.Zang@Sun.COM 	if (strcmp(dev_type, "display") != 0) {
2989306SAaron.Zang@Sun.COM 		ddi_prop_free(dev_type);
2999306SAaron.Zang@Sun.COM 		return (DDI_WALK_CONTINUE);
3009306SAaron.Zang@Sun.COM 	}
3019306SAaron.Zang@Sun.COM 
3029306SAaron.Zang@Sun.COM 	ddi_prop_free(dev_type);
3039306SAaron.Zang@Sun.COM 
3049306SAaron.Zang@Sun.COM 	if ((pdip = ddi_get_parent(dip)) == NULL)
30510221SAaron.Zang@Sun.COM 		return (DDI_WALK_PRUNECHILD);
3069306SAaron.Zang@Sun.COM 
3079306SAaron.Zang@Sun.COM 	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, pdip, DDI_PROP_DONTPASS,
3089306SAaron.Zang@Sun.COM 	    "device_type", &parent_type) != DDI_SUCCESS)
30910221SAaron.Zang@Sun.COM 		return (DDI_WALK_PRUNECHILD);
3109306SAaron.Zang@Sun.COM 
3119306SAaron.Zang@Sun.COM 	if ((strcmp(parent_type, "isa") == 0) ||
3129306SAaron.Zang@Sun.COM 	    (strcmp(parent_type, "eisa") == 0)) {
313*11842SEdward.Shu@Sun.COM 		p->found_dip = dip;
3149306SAaron.Zang@Sun.COM 		ddi_prop_free(parent_type);
3159306SAaron.Zang@Sun.COM 		return (DDI_WALK_TERMINATE);
3169306SAaron.Zang@Sun.COM 	}
3179306SAaron.Zang@Sun.COM 
3189306SAaron.Zang@Sun.COM 	if ((strcmp(parent_type, "pci") == 0) ||
3199306SAaron.Zang@Sun.COM 	    (strcmp(parent_type, "pciex") == 0)) {
3209306SAaron.Zang@Sun.COM 		ddi_acc_handle_t pci_conf;
3219306SAaron.Zang@Sun.COM 		uint16_t data16;
3229306SAaron.Zang@Sun.COM 
3239306SAaron.Zang@Sun.COM 		ddi_prop_free(parent_type);
3249306SAaron.Zang@Sun.COM 
3259306SAaron.Zang@Sun.COM 		if (i_ddi_attach_node_hierarchy(dip) != DDI_SUCCESS)
32610221SAaron.Zang@Sun.COM 			return (DDI_WALK_PRUNECHILD);
3279306SAaron.Zang@Sun.COM 
3289306SAaron.Zang@Sun.COM 		if (pci_config_setup(dip, &pci_conf) != DDI_SUCCESS)
32910221SAaron.Zang@Sun.COM 			return (DDI_WALK_PRUNECHILD);
3309306SAaron.Zang@Sun.COM 
3319306SAaron.Zang@Sun.COM 		data16 = pci_config_get16(pci_conf, PCI_CONF_COMM);
3329306SAaron.Zang@Sun.COM 		pci_config_teardown(&pci_conf);
3339306SAaron.Zang@Sun.COM 
3349306SAaron.Zang@Sun.COM 		if (!(data16 & PCI_COMM_IO))
33510221SAaron.Zang@Sun.COM 			return (DDI_WALK_PRUNECHILD);
3369306SAaron.Zang@Sun.COM 
337*11842SEdward.Shu@Sun.COM 		p->found_dip = dip;
3389306SAaron.Zang@Sun.COM 		return (DDI_WALK_TERMINATE);
3399306SAaron.Zang@Sun.COM 	}
3409306SAaron.Zang@Sun.COM 
3419306SAaron.Zang@Sun.COM 	ddi_prop_free(parent_type);
34210221SAaron.Zang@Sun.COM 	return (DDI_WALK_PRUNECHILD);
3439306SAaron.Zang@Sun.COM }
3449306SAaron.Zang@Sun.COM 
3453446Smrj /*
346*11842SEdward.Shu@Sun.COM  * The first round search is to find:
3479306SAaron.Zang@Sun.COM  * 1) a VGA device.
3489306SAaron.Zang@Sun.COM  * 2) a PCI VGA compatible device whose IO space is enabled
3499306SAaron.Zang@Sun.COM  *    and the VGA Enable bit of any PCI-PCI bridge above it is set.
350*11842SEdward.Shu@Sun.COM  * If the first round search succeeds, prune the second round search.
351*11842SEdward.Shu@Sun.COM  *
352*11842SEdward.Shu@Sun.COM  * The second round seach does not check the VGA Enable bit.
3539306SAaron.Zang@Sun.COM  *
3549306SAaron.Zang@Sun.COM  * Return the device path as the console fb path.
3553446Smrj  */
3563446Smrj char *
plat_fbpath(void)3573446Smrj plat_fbpath(void)
3583446Smrj {
359*11842SEdward.Shu@Sun.COM 	struct find_fb_dev_param param;
3603446Smrj 	static char *fbpath = NULL;
3613446Smrj 	static char fbpath_buf[MAXPATHLEN];
3623446Smrj 
363*11842SEdward.Shu@Sun.COM 	/* first round search */
364*11842SEdward.Shu@Sun.COM 	param.found_dip = NULL;
365*11842SEdward.Shu@Sun.COM 	param.vga_enable = 1;
366*11842SEdward.Shu@Sun.COM 	ddi_walk_devs(ddi_root_node(), find_fb_dev, &param);
3675084Sjohnlev 
368*11842SEdward.Shu@Sun.COM 	if (param.found_dip != NULL) {
369*11842SEdward.Shu@Sun.COM 		(void) ddi_pathname(param.found_dip, fbpath_buf);
370*11842SEdward.Shu@Sun.COM 		fbpath = fbpath_buf;
371*11842SEdward.Shu@Sun.COM 		return (fbpath);
372*11842SEdward.Shu@Sun.COM 	}
373*11842SEdward.Shu@Sun.COM 
374*11842SEdward.Shu@Sun.COM 	/*
375*11842SEdward.Shu@Sun.COM 	 * second round search, do not check the
376*11842SEdward.Shu@Sun.COM 	 * PCI_BCNF_BCNTRL_VGA_ENABLE bit
377*11842SEdward.Shu@Sun.COM 	 */
378*11842SEdward.Shu@Sun.COM 	param.found_dip = NULL;
379*11842SEdward.Shu@Sun.COM 	param.vga_enable = 0;
380*11842SEdward.Shu@Sun.COM 	ddi_walk_devs(ddi_root_node(), find_fb_dev, &param);
381*11842SEdward.Shu@Sun.COM 
382*11842SEdward.Shu@Sun.COM 	if (param.found_dip == NULL)
3839306SAaron.Zang@Sun.COM 		return (NULL);
3845084Sjohnlev 
385*11842SEdward.Shu@Sun.COM 	(void) ddi_pathname(param.found_dip, fbpath_buf);
3869306SAaron.Zang@Sun.COM 	fbpath = fbpath_buf;
3875084Sjohnlev 	return (fbpath);
3883446Smrj }
3893446Smrj 
3903446Smrj char *
plat_mousepath(void)3913446Smrj plat_mousepath(void)
3923446Smrj {
3939149SJudy.Chen@Sun.COM 	static char mpath[MAXPATHLEN];
3949149SJudy.Chen@Sun.COM 
3953446Smrj 	/*
3963446Smrj 	 * Hardcode to isa mouse path
3973446Smrj 	 * XXX make it settable via bootprop?
3983446Smrj 	 */
3999149SJudy.Chen@Sun.COM 	if (pseudo_isa)
4009149SJudy.Chen@Sun.COM 		return ("/isa/i8042@1,60/mouse@1");
4019149SJudy.Chen@Sun.COM 
4029149SJudy.Chen@Sun.COM 	if (plat_devpath("mouse8042", mpath) == NULL)
4039149SJudy.Chen@Sun.COM 		return (NULL);
4049149SJudy.Chen@Sun.COM 
4059149SJudy.Chen@Sun.COM 	return (mpath);
4063446Smrj }
4073446Smrj 
4083446Smrj /* return path of first usb serial device */
4093446Smrj static char *
plat_usbser_path(void)4103446Smrj plat_usbser_path(void)
4113446Smrj {
4123446Smrj 	extern dev_info_t *usbser_first_device(void);
4133446Smrj 
4143446Smrj 	dev_info_t *us_dip;
4153446Smrj 	static char *us_path = NULL;
4163446Smrj 
4173446Smrj 	if (us_path)
4183446Smrj 		return (us_path);
4193446Smrj 
4203446Smrj 	us_dip = usbser_first_device();
4213446Smrj 	if (us_dip == NULL)
4223446Smrj 		return (NULL);
4233446Smrj 
4243446Smrj 	us_path = kmem_alloc(MAXPATHLEN, KM_SLEEP);
4253446Smrj 	(void) ddi_pathname(us_dip, us_path);
4263446Smrj 	ndi_rele_devi(us_dip);	/* held from usbser_first_device */
4273446Smrj 	return (us_path);
4283446Smrj }
4293446Smrj 
4309149SJudy.Chen@Sun.COM static char *
plat_ttypath(int inum)4319149SJudy.Chen@Sun.COM plat_ttypath(int inum)
4329149SJudy.Chen@Sun.COM {
4339149SJudy.Chen@Sun.COM 	static char *defaultpath[] = {
4349149SJudy.Chen@Sun.COM 	    "/isa/asy@1,3f8:a",
4359149SJudy.Chen@Sun.COM 	    "/isa/asy@1,2f8:b"
4369149SJudy.Chen@Sun.COM 	};
4379149SJudy.Chen@Sun.COM 	static char path[MAXPATHLEN];
4389149SJudy.Chen@Sun.COM 	char *bp;
4399149SJudy.Chen@Sun.COM 	major_t major;
4409149SJudy.Chen@Sun.COM 	dev_info_t *dip;
4419149SJudy.Chen@Sun.COM 
4429149SJudy.Chen@Sun.COM 	if (pseudo_isa)
4439149SJudy.Chen@Sun.COM 		return (defaultpath[inum]);
4449149SJudy.Chen@Sun.COM 
4459149SJudy.Chen@Sun.COM 	if ((major = ddi_name_to_major("asy")) == (major_t)-1)
4469149SJudy.Chen@Sun.COM 		return (NULL);
4479149SJudy.Chen@Sun.COM 
4489149SJudy.Chen@Sun.COM 	if ((dip = devnamesp[major].dn_head) == NULL)
4499149SJudy.Chen@Sun.COM 		return (NULL);
4509149SJudy.Chen@Sun.COM 
4519157SJudy.Chen@Sun.COM 	for (; dip != NULL; dip = ddi_get_next(dip)) {
4529157SJudy.Chen@Sun.COM 		if (i_ddi_attach_node_hierarchy(dip) != DDI_SUCCESS)
4539149SJudy.Chen@Sun.COM 			return (NULL);
4549157SJudy.Chen@Sun.COM 
4559157SJudy.Chen@Sun.COM 		if (DEVI(dip)->devi_minor->ddm_name[0] == ('a' + (char)inum))
4569157SJudy.Chen@Sun.COM 			break;
4579149SJudy.Chen@Sun.COM 	}
4589157SJudy.Chen@Sun.COM 	if (dip == NULL)
4599149SJudy.Chen@Sun.COM 		return (NULL);
4609149SJudy.Chen@Sun.COM 
4619149SJudy.Chen@Sun.COM 	(void) ddi_pathname(dip, path);
4629149SJudy.Chen@Sun.COM 	bp = path + strlen(path);
4639149SJudy.Chen@Sun.COM 	(void) snprintf(bp, 3, ":%s", DEVI(dip)->devi_minor->ddm_name);
4649149SJudy.Chen@Sun.COM 
4659149SJudy.Chen@Sun.COM 	return (path);
4669149SJudy.Chen@Sun.COM }
4679149SJudy.Chen@Sun.COM 
4683446Smrj /*
4693446Smrj  * Lacking support for com2 and com3, if that matters.
4703446Smrj  * Another possible enhancement could be to use properties
4713446Smrj  * for the port mapping rather than simply hard-code them.
4723446Smrj  */
4733446Smrj char *
plat_stdinpath(void)4743446Smrj plat_stdinpath(void)
4753446Smrj {
4763446Smrj 	switch (console_type()) {
4775084Sjohnlev #if defined(__xpv)
4785084Sjohnlev 	case CONS_HYPERVISOR:
4795084Sjohnlev 		return ("/xpvd/xencons@0");
4805084Sjohnlev #endif /* __xpv */
4813446Smrj 	case CONS_TTYA:
4829149SJudy.Chen@Sun.COM 		return (plat_ttypath(0));
4833446Smrj 	case CONS_TTYB:
4849149SJudy.Chen@Sun.COM 		return (plat_ttypath(1));
4853446Smrj 	case CONS_USBSER:
4863446Smrj 		return (plat_usbser_path());
4873446Smrj 	case CONS_SCREEN:
4883446Smrj 	default:
4893446Smrj 		break;
4903446Smrj 	};
4913446Smrj 	return (plat_kbdpath());
4923446Smrj }
4933446Smrj 
4943446Smrj char *
plat_stdoutpath(void)4953446Smrj plat_stdoutpath(void)
4963446Smrj {
4973446Smrj 	switch (console_type()) {
4985084Sjohnlev #if defined(__xpv)
4995084Sjohnlev 	case CONS_HYPERVISOR:
5005084Sjohnlev 		return ("/xpvd/xencons@0");
5015084Sjohnlev #endif /* __xpv */
5023446Smrj 	case CONS_TTYA:
5039149SJudy.Chen@Sun.COM 		return (plat_ttypath(0));
5043446Smrj 	case CONS_TTYB:
5059149SJudy.Chen@Sun.COM 		return (plat_ttypath(1));
5063446Smrj 	case CONS_USBSER:
5073446Smrj 		return (plat_usbser_path());
5083446Smrj 	case CONS_SCREEN:
5093446Smrj 	default:
5103446Smrj 		break;
5113446Smrj 	};
5123446Smrj 	return (plat_fbpath());
5133446Smrj }
5143446Smrj 
5153446Smrj /*
5163446Smrj  * If VIS_PIXEL mode will be implemented on x86, these following
5173446Smrj  * functions should be re-considered. Now these functions are
5183446Smrj  * unused on x86.
5193446Smrj  */
5203446Smrj void
plat_tem_get_inverses(int * inverse,int * inverse_screen)5213994Slq150181 plat_tem_get_inverses(int *inverse, int *inverse_screen)
5223994Slq150181 {
5233994Slq150181 	*inverse = 0;
5243994Slq150181 	*inverse_screen = 0;
5253994Slq150181 }
5263994Slq150181 
5273994Slq150181 void
plat_tem_get_prom_font_size(int * charheight,int * windowtop)5283446Smrj plat_tem_get_prom_font_size(int *charheight, int *windowtop)
5293446Smrj {
5303446Smrj 	*charheight = 0;
5313446Smrj 	*windowtop = 0;
5323446Smrj }
5333446Smrj 
5345084Sjohnlev /*ARGSUSED*/
5353446Smrj void
plat_tem_get_prom_size(size_t * height,size_t * width)5363446Smrj plat_tem_get_prom_size(size_t *height, size_t *width)
5373446Smrj {
5385084Sjohnlev 	panic("unimplemented at line %d of %s", __LINE__, __FILE__);
5393446Smrj }
5403446Smrj 
5413446Smrj void
plat_tem_hide_prom_cursor(void)5423446Smrj plat_tem_hide_prom_cursor(void)
5433446Smrj {
5445084Sjohnlev 	panic("unimplemented at line %d of %s", __LINE__, __FILE__);
5453446Smrj }
5463446Smrj 
5475084Sjohnlev /*ARGSUSED*/
5483446Smrj void
plat_tem_get_prom_pos(uint32_t * row,uint32_t * col)5493446Smrj plat_tem_get_prom_pos(uint32_t *row, uint32_t *col)
5503446Smrj {
5515084Sjohnlev 	panic("unimplemented at line %d of %s", __LINE__, __FILE__);
5523446Smrj }
553