xref: /illumos-gate/usr/src/uts/i86pc/io/consplat.c (revision 82bb7c22)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5fea9cb91Slq  * Common Development and Distribution License (the "License").
6fea9cb91Slq  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
21fea9cb91Slq 
227c478bd9Sstevel@tonic-gate /*
230d928757SGary Mills  * Copyright (c) 2012 Gary Mills
240d928757SGary Mills  *
2593a18d6dSEnrico Perla - Sun Microsystems  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
267c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
277c478bd9Sstevel@tonic-gate  */
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate /*
307c478bd9Sstevel@tonic-gate  * isa-specific console configuration routines
317c478bd9Sstevel@tonic-gate  */
327c478bd9Sstevel@tonic-gate 
337c478bd9Sstevel@tonic-gate #include <sys/types.h>
347c478bd9Sstevel@tonic-gate #include <sys/param.h>
357c478bd9Sstevel@tonic-gate #include <sys/cmn_err.h>
367c478bd9Sstevel@tonic-gate #include <sys/systm.h>
377c478bd9Sstevel@tonic-gate #include <sys/conf.h>
387c478bd9Sstevel@tonic-gate #include <sys/debug.h>
397c478bd9Sstevel@tonic-gate #include <sys/ddi.h>
407c478bd9Sstevel@tonic-gate #include <sys/sunddi.h>
4128cdc3d7Sszhou #include <sys/sunndi.h>
427c478bd9Sstevel@tonic-gate #include <sys/esunddi.h>
437c478bd9Sstevel@tonic-gate #include <sys/ddi_impldefs.h>
447c478bd9Sstevel@tonic-gate #include <sys/promif.h>
457c478bd9Sstevel@tonic-gate #include <sys/modctl.h>
467c478bd9Sstevel@tonic-gate #include <sys/termios.h>
4745e46d06Srui zang - Sun Microsystems - Beijing China #include <sys/pci.h>
484dfe872dSToomas Soome #include <sys/framebuffer.h>
494dfe872dSToomas Soome #include <sys/boot_console.h>
50843e1988Sjohnlev #if defined(__xpv)
51843e1988Sjohnlev #include <sys/hypervisor.h>
52843e1988Sjohnlev #endif
537c478bd9Sstevel@tonic-gate 
5478323854SJudy Chen extern int pseudo_isa;
5578323854SJudy Chen 
567c478bd9Sstevel@tonic-gate int
plat_use_polled_debug()57993e3fafSRobert Mustacchi plat_use_polled_debug()
58993e3fafSRobert Mustacchi {
597c478bd9Sstevel@tonic-gate 	return (0);
607c478bd9Sstevel@tonic-gate }
617c478bd9Sstevel@tonic-gate 
627c478bd9Sstevel@tonic-gate int
plat_support_serial_kbd_and_ms()63993e3fafSRobert Mustacchi plat_support_serial_kbd_and_ms()
64993e3fafSRobert Mustacchi {
657c478bd9Sstevel@tonic-gate 	return (0);
667c478bd9Sstevel@tonic-gate }
677c478bd9Sstevel@tonic-gate 
68843e1988Sjohnlev #define	A_CNT(arr)	(sizeof (arr) / sizeof (arr[0]))
69843e1988Sjohnlev 
700d928757SGary Mills #ifndef	CONS_INVALID
710d928757SGary Mills #define	CONS_INVALID		-1
720d928757SGary Mills #define	CONS_SCREEN_TEXT	0
730d928757SGary Mills #define	CONS_TTY		1
740d928757SGary Mills #define	CONS_XXX		2	/* Unused */
750d928757SGary Mills #define	CONS_USBSER		3
760d928757SGary Mills #define	CONS_HYPERVISOR		4
770d928757SGary Mills #define	CONS_SCREEN_GRAPHICS	5
780d928757SGary Mills #endif	/* CONS_INVALID */
797c478bd9Sstevel@tonic-gate 
80583da248Srz char *plat_fbpath(void);
81583da248Srz 
827c478bd9Sstevel@tonic-gate static int
console_type(int * tnum)830d928757SGary Mills console_type(int *tnum)
847c478bd9Sstevel@tonic-gate {
857c478bd9Sstevel@tonic-gate 	static int boot_console = CONS_INVALID;
860d928757SGary Mills 	static int tty_num = 0;
877c478bd9Sstevel@tonic-gate 
887c478bd9Sstevel@tonic-gate 	char *cons;
897c478bd9Sstevel@tonic-gate 	dev_info_t *root;
907c478bd9Sstevel@tonic-gate 
910d928757SGary Mills 	/* If we already have determined the console, just return it. */
920d928757SGary Mills 	if (boot_console != CONS_INVALID) {
930d928757SGary Mills 		if (tnum != NULL)
940d928757SGary Mills 			*tnum = tty_num;
957c478bd9Sstevel@tonic-gate 		return (boot_console);
960d928757SGary Mills 	}
977c478bd9Sstevel@tonic-gate 
98843e1988Sjohnlev #if defined(__xpv)
99843e1988Sjohnlev 	if (!DOMAIN_IS_INITDOMAIN(xen_info) || bcons_hypervisor_redirect()) {
100843e1988Sjohnlev 		boot_console = CONS_HYPERVISOR;
1010d928757SGary Mills 		if (tnum != NULL)
1020d928757SGary Mills 			*tnum = tty_num;
103843e1988Sjohnlev 		return (boot_console);
104843e1988Sjohnlev 	}
105843e1988Sjohnlev #endif /* __xpv */
106843e1988Sjohnlev 
1077c478bd9Sstevel@tonic-gate 	/*
1087c478bd9Sstevel@tonic-gate 	 * console is defined by "console" property, with
1097c478bd9Sstevel@tonic-gate 	 * fallback on the old "input-device" property.
110583da248Srz 	 * If "input-device" is not defined either, also check "output-device".
1117c478bd9Sstevel@tonic-gate 	 */
1120d928757SGary Mills 	boot_console = CONS_SCREEN_TEXT;	/* default is screen/kb */
1137c478bd9Sstevel@tonic-gate 	root = ddi_root_node();
1147c478bd9Sstevel@tonic-gate 	if ((ddi_prop_lookup_string(DDI_DEV_T_ANY, root,
1157c478bd9Sstevel@tonic-gate 	    DDI_PROP_DONTPASS, "console", &cons) == DDI_SUCCESS) ||
1167c478bd9Sstevel@tonic-gate 	    (ddi_prop_lookup_string(DDI_DEV_T_ANY, root,
117583da248Srz 	    DDI_PROP_DONTPASS, "input-device", &cons) == DDI_SUCCESS) ||
118583da248Srz 	    (ddi_prop_lookup_string(DDI_DEV_T_ANY, root,
119583da248Srz 	    DDI_PROP_DONTPASS, "output-device", &cons) == DDI_SUCCESS)) {
1200d928757SGary Mills 		if (strlen(cons) == 4 && strncmp(cons, "tty", 3) == 0 &&
1210d928757SGary Mills 		    cons[3] >= 'a' && cons[3] <= 'd') {
1220d928757SGary Mills 			boot_console = CONS_TTY;
1230d928757SGary Mills 			tty_num = cons[3] - 'a';
124843e1988Sjohnlev 		} else if (strcmp(cons, "usb-serial") == 0) {
125993e3fafSRobert Mustacchi 			(void) i_ddi_attach_hw_nodes("xhci");
12628cdc3d7Sszhou 			(void) i_ddi_attach_hw_nodes("ehci");
12728cdc3d7Sszhou 			(void) i_ddi_attach_hw_nodes("uhci");
12828cdc3d7Sszhou 			(void) i_ddi_attach_hw_nodes("ohci");
12928cdc3d7Sszhou 			/*
13028cdc3d7Sszhou 			 * USB device enumerate asynchronously.
13128cdc3d7Sszhou 			 * Wait 2 seconds for USB serial devices to attach.
13228cdc3d7Sszhou 			 */
13328cdc3d7Sszhou 			delay(drv_usectohz(2000000));
13428cdc3d7Sszhou 			boot_console = CONS_USBSER;
135843e1988Sjohnlev #if defined(__xpv)
136843e1988Sjohnlev 		} else if (strcmp(cons, "hypervisor") == 0) {
137843e1988Sjohnlev 			boot_console = CONS_HYPERVISOR;
138843e1988Sjohnlev #endif /* __xpv */
13928cdc3d7Sszhou 		}
1407c478bd9Sstevel@tonic-gate 		ddi_prop_free(cons);
1417c478bd9Sstevel@tonic-gate 	}
142583da248Srz 
143583da248Srz 	/*
144583da248Srz 	 * If the console is configured to use a framebuffer but none
145583da248Srz 	 * could be found, fallback to "ttya" since it's likely to exist
146583da248Srz 	 * and it matches longstanding behavior on SPARC.
147583da248Srz 	 */
1480d928757SGary Mills 	if (boot_console == CONS_SCREEN_TEXT && plat_fbpath() == NULL) {
1490d928757SGary Mills 		boot_console = CONS_TTY;
1500d928757SGary Mills 		tty_num = 0;
1510d928757SGary Mills 	}
152583da248Srz 
1530d928757SGary Mills 	if (tnum != NULL)
1540d928757SGary Mills 		*tnum = tty_num;
1557c478bd9Sstevel@tonic-gate 	return (boot_console);
1567c478bd9Sstevel@tonic-gate }
1577c478bd9Sstevel@tonic-gate 
1587c478bd9Sstevel@tonic-gate int
plat_stdin_is_keyboard(void)1597c478bd9Sstevel@tonic-gate plat_stdin_is_keyboard(void)
1607c478bd9Sstevel@tonic-gate {
1610d928757SGary Mills 	return (console_type(NULL) == CONS_SCREEN_TEXT);
1627c478bd9Sstevel@tonic-gate }
1637c478bd9Sstevel@tonic-gate 
1647c478bd9Sstevel@tonic-gate int
plat_stdout_is_framebuffer(void)1657c478bd9Sstevel@tonic-gate plat_stdout_is_framebuffer(void)
1667c478bd9Sstevel@tonic-gate {
1670d928757SGary Mills 	return (console_type(NULL) == CONS_SCREEN_TEXT);
1687c478bd9Sstevel@tonic-gate }
1697c478bd9Sstevel@tonic-gate 
17078323854SJudy Chen static char *
plat_devpath(char * name,char * path)17178323854SJudy Chen plat_devpath(char *name, char *path)
17278323854SJudy Chen {
17378323854SJudy Chen 	major_t major;
17478323854SJudy Chen 	dev_info_t *dip, *pdip;
17578323854SJudy Chen 
17678323854SJudy Chen 	if ((major = ddi_name_to_major(name)) == (major_t)-1)
17778323854SJudy Chen 		return (NULL);
17878323854SJudy Chen 
17978323854SJudy Chen 	if ((dip = devnamesp[major].dn_head) == NULL)
18078323854SJudy Chen 		return (NULL);
18178323854SJudy Chen 
18278323854SJudy Chen 	pdip = ddi_get_parent(dip);
18378323854SJudy Chen 	if (i_ddi_attach_node_hierarchy(pdip) != DDI_SUCCESS)
18478323854SJudy Chen 		return (NULL);
18578323854SJudy Chen 	if (ddi_initchild(pdip, dip) != DDI_SUCCESS)
18678323854SJudy Chen 		return (NULL);
18778323854SJudy Chen 
18878323854SJudy Chen 	(void) ddi_pathname(dip, path);
18978323854SJudy Chen 
19078323854SJudy Chen 	return (path);
19178323854SJudy Chen }
19278323854SJudy Chen 
1937c478bd9Sstevel@tonic-gate /*
1947c478bd9Sstevel@tonic-gate  * Return generic path to keyboard device from the alias.
1957c478bd9Sstevel@tonic-gate  */
1967c478bd9Sstevel@tonic-gate char *
plat_kbdpath(void)1977c478bd9Sstevel@tonic-gate plat_kbdpath(void)
1987c478bd9Sstevel@tonic-gate {
19978323854SJudy Chen 	static char kbpath[MAXPATHLEN];
20078323854SJudy Chen 
2017c478bd9Sstevel@tonic-gate 	/*
2027c478bd9Sstevel@tonic-gate 	 * Hardcode to isa keyboard path
2037c478bd9Sstevel@tonic-gate 	 * XXX make it settable via bootprop?
2047c478bd9Sstevel@tonic-gate 	 */
20578323854SJudy Chen 	if (pseudo_isa)
20678323854SJudy Chen 		return ("/isa/i8042@1,60/keyboard@0");
20778323854SJudy Chen 
20878323854SJudy Chen 	if (plat_devpath("kb8042", kbpath) == NULL)
20978323854SJudy Chen 		return (NULL);
21078323854SJudy Chen 
21178323854SJudy Chen 	return (kbpath);
2127c478bd9Sstevel@tonic-gate }
2137c478bd9Sstevel@tonic-gate 
21493a18d6dSEnrico Perla - Sun Microsystems /*
21593a18d6dSEnrico Perla - Sun Microsystems  * NOTE: this function is duplicated here and in gfx_private/vgatext while
21693a18d6dSEnrico Perla - Sun Microsystems  *       we work on a set of commitable interfaces to sunpci.c.
21793a18d6dSEnrico Perla - Sun Microsystems  *
21893a18d6dSEnrico Perla - Sun Microsystems  * Use the class code to determine if the device is a PCI-to-PCI bridge.
21993a18d6dSEnrico Perla - Sun Microsystems  * Returns:  B_TRUE  if the device is a bridge.
22093a18d6dSEnrico Perla - Sun Microsystems  *           B_FALSE if the device is not a bridge or the property cannot be
22193a18d6dSEnrico Perla - Sun Microsystems  *		     retrieved.
22293a18d6dSEnrico Perla - Sun Microsystems  */
22393a18d6dSEnrico Perla - Sun Microsystems static boolean_t
is_pci_bridge(dev_info_t * dip)22493a18d6dSEnrico Perla - Sun Microsystems is_pci_bridge(dev_info_t *dip)
22593a18d6dSEnrico Perla - Sun Microsystems {
22693a18d6dSEnrico Perla - Sun Microsystems 	uint32_t class_code;
22793a18d6dSEnrico Perla - Sun Microsystems 
22893a18d6dSEnrico Perla - Sun Microsystems 	class_code = (uint32_t)ddi_prop_get_int(DDI_DEV_T_ANY, dip,
22993a18d6dSEnrico Perla - Sun Microsystems 	    DDI_PROP_DONTPASS, "class-code", 0xffffffff);
23093a18d6dSEnrico Perla - Sun Microsystems 
23193a18d6dSEnrico Perla - Sun Microsystems 	if (class_code == 0xffffffff || class_code == DDI_PROP_NOT_FOUND)
23293a18d6dSEnrico Perla - Sun Microsystems 		return (B_FALSE);
23393a18d6dSEnrico Perla - Sun Microsystems 
23493a18d6dSEnrico Perla - Sun Microsystems 	class_code &= 0x00ffff00;
23593a18d6dSEnrico Perla - Sun Microsystems 	if (class_code == ((PCI_CLASS_BRIDGE << 16) | (PCI_BRIDGE_PCI << 8)))
23693a18d6dSEnrico Perla - Sun Microsystems 		return (B_TRUE);
23793a18d6dSEnrico Perla - Sun Microsystems 
23893a18d6dSEnrico Perla - Sun Microsystems 	return (B_FALSE);
23993a18d6dSEnrico Perla - Sun Microsystems }
24093a18d6dSEnrico Perla - Sun Microsystems 
24148b3f8deSEdward Shu /*
24248b3f8deSEdward Shu  * Type for the parameter of find_fb_dev()
24348b3f8deSEdward Shu  */
24448b3f8deSEdward Shu struct find_fb_dev_param
24548b3f8deSEdward Shu {
24648b3f8deSEdward Shu 	dev_info_t *found_dip;	/* dip found for VGA console */
24748b3f8deSEdward Shu 	int vga_enable;		/* check PCI_BCNF_BCNTRL_VGA_ENABLE or not */
24848b3f8deSEdward Shu };
24948b3f8deSEdward Shu 
25048b3f8deSEdward Shu /*
25148b3f8deSEdward Shu  * The VGA device could be under a subtractive PCI bridge on some systems.
25248b3f8deSEdward Shu  * Though the PCI_BCNF_BCNTRL_VGA_ENABLE bit is not set on such subtractive
25348b3f8deSEdward Shu  * PCI bridge, the subtractive PCI bridge can forward VGA access if no other
25448b3f8deSEdward Shu  * agent claims the access.
25548b3f8deSEdward Shu  * The vga_enable element in param acts as a flag, if not set, ignore the
25648b3f8deSEdward Shu  * checking for the PCI_BCNF_BCNTRL_VGA_ENABLE bit of the PCI bridge during
25748b3f8deSEdward Shu  * the search.
25848b3f8deSEdward Shu  */
25945e46d06Srui zang - Sun Microsystems - Beijing China static int
find_fb_dev(dev_info_t * dip,void * param)26048b3f8deSEdward Shu find_fb_dev(dev_info_t *dip, void *param)
26145e46d06Srui zang - Sun Microsystems - Beijing China {
26248b3f8deSEdward Shu 	struct find_fb_dev_param *p = param;
26345e46d06Srui zang - Sun Microsystems - Beijing China 	char *dev_type;
26445e46d06Srui zang - Sun Microsystems - Beijing China 	dev_info_t *pdip;
26545e46d06Srui zang - Sun Microsystems - Beijing China 	char *parent_type;
26645e46d06Srui zang - Sun Microsystems - Beijing China 
26745e46d06Srui zang - Sun Microsystems - Beijing China 	if (dip == ddi_root_node())
26845e46d06Srui zang - Sun Microsystems - Beijing China 		return (DDI_WALK_CONTINUE);
26945e46d06Srui zang - Sun Microsystems - Beijing China 
27045e46d06Srui zang - Sun Microsystems - Beijing China 	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
27145e46d06Srui zang - Sun Microsystems - Beijing China 	    "device_type", &dev_type) != DDI_SUCCESS)
27245e46d06Srui zang - Sun Microsystems - Beijing China 		return (DDI_WALK_PRUNECHILD);
27345e46d06Srui zang - Sun Microsystems - Beijing China 
27445e46d06Srui zang - Sun Microsystems - Beijing China 	if ((strcmp(dev_type, "isa") == 0) || (strcmp(dev_type, "eisa") == 0)) {
27545e46d06Srui zang - Sun Microsystems - Beijing China 		ddi_prop_free(dev_type);
27645e46d06Srui zang - Sun Microsystems - Beijing China 		return (DDI_WALK_CONTINUE);
27745e46d06Srui zang - Sun Microsystems - Beijing China 	}
27845e46d06Srui zang - Sun Microsystems - Beijing China 
27945e46d06Srui zang - Sun Microsystems - Beijing China 	if ((strcmp(dev_type, "pci") == 0) ||
28045e46d06Srui zang - Sun Microsystems - Beijing China 	    (strcmp(dev_type, "pciex") == 0)) {
28145e46d06Srui zang - Sun Microsystems - Beijing China 		ddi_acc_handle_t pci_conf;
28245e46d06Srui zang - Sun Microsystems - Beijing China 		uint16_t data16;
283c401c7a8Srui zang - Sun Microsystems - Beijing China 		char *nodename;
28445e46d06Srui zang - Sun Microsystems - Beijing China 
28545e46d06Srui zang - Sun Microsystems - Beijing China 		ddi_prop_free(dev_type);
28645e46d06Srui zang - Sun Microsystems - Beijing China 
28748b3f8deSEdward Shu 		if (!p->vga_enable)
28848b3f8deSEdward Shu 			return (DDI_WALK_CONTINUE);
28948b3f8deSEdward Shu 
290c401c7a8Srui zang - Sun Microsystems - Beijing China 		nodename = ddi_node_name(dip);
29145e46d06Srui zang - Sun Microsystems - Beijing China 
29293a18d6dSEnrico Perla - Sun Microsystems 		/*
29393a18d6dSEnrico Perla - Sun Microsystems 		 * If the node is not a PCI-to-PCI bridge, continue traversing
29493a18d6dSEnrico Perla - Sun Microsystems 		 * (it could be the root node), otherwise, check for the
29593a18d6dSEnrico Perla - Sun Microsystems 		 * VGAEnable bit to be set in the Bridge Control Register.
29693a18d6dSEnrico Perla - Sun Microsystems 		 */
297c401c7a8Srui zang - Sun Microsystems - Beijing China 		if (strcmp(nodename, "pci") == 0) {
29893a18d6dSEnrico Perla - Sun Microsystems 			if (is_pci_bridge(dip) == B_FALSE)
29993a18d6dSEnrico Perla - Sun Microsystems 				return (DDI_WALK_CONTINUE);
30045e46d06Srui zang - Sun Microsystems - Beijing China 		}
30145e46d06Srui zang - Sun Microsystems - Beijing China 
302c401c7a8Srui zang - Sun Microsystems - Beijing China 		if (i_ddi_attach_node_hierarchy(dip) != DDI_SUCCESS)
303c401c7a8Srui zang - Sun Microsystems - Beijing China 			return (DDI_WALK_PRUNECHILD);
304c401c7a8Srui zang - Sun Microsystems - Beijing China 
305c401c7a8Srui zang - Sun Microsystems - Beijing China 		if (pci_config_setup(dip, &pci_conf) != DDI_SUCCESS)
306c401c7a8Srui zang - Sun Microsystems - Beijing China 			return (DDI_WALK_PRUNECHILD);
307c401c7a8Srui zang - Sun Microsystems - Beijing China 
30845e46d06Srui zang - Sun Microsystems - Beijing China 		data16 = pci_config_get16(pci_conf, PCI_BCNF_BCNTRL);
30945e46d06Srui zang - Sun Microsystems - Beijing China 		pci_config_teardown(&pci_conf);
31045e46d06Srui zang - Sun Microsystems - Beijing China 
31145e46d06Srui zang - Sun Microsystems - Beijing China 		if (data16 & PCI_BCNF_BCNTRL_VGA_ENABLE)
31245e46d06Srui zang - Sun Microsystems - Beijing China 			return (DDI_WALK_CONTINUE);
31345e46d06Srui zang - Sun Microsystems - Beijing China 
31445e46d06Srui zang - Sun Microsystems - Beijing China 		return (DDI_WALK_PRUNECHILD);
31545e46d06Srui zang - Sun Microsystems - Beijing China 	}
31645e46d06Srui zang - Sun Microsystems - Beijing China 
31745e46d06Srui zang - Sun Microsystems - Beijing China 	if (strcmp(dev_type, "display") != 0) {
31845e46d06Srui zang - Sun Microsystems - Beijing China 		ddi_prop_free(dev_type);
31945e46d06Srui zang - Sun Microsystems - Beijing China 		return (DDI_WALK_CONTINUE);
32045e46d06Srui zang - Sun Microsystems - Beijing China 	}
32145e46d06Srui zang - Sun Microsystems - Beijing China 
32245e46d06Srui zang - Sun Microsystems - Beijing China 	ddi_prop_free(dev_type);
32345e46d06Srui zang - Sun Microsystems - Beijing China 
32445e46d06Srui zang - Sun Microsystems - Beijing China 	if ((pdip = ddi_get_parent(dip)) == NULL)
325c401c7a8Srui zang - Sun Microsystems - Beijing China 		return (DDI_WALK_PRUNECHILD);
32645e46d06Srui zang - Sun Microsystems - Beijing China 
32745e46d06Srui zang - Sun Microsystems - Beijing China 	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, pdip, DDI_PROP_DONTPASS,
32845e46d06Srui zang - Sun Microsystems - Beijing China 	    "device_type", &parent_type) != DDI_SUCCESS)
329c401c7a8Srui zang - Sun Microsystems - Beijing China 		return (DDI_WALK_PRUNECHILD);
33045e46d06Srui zang - Sun Microsystems - Beijing China 
33145e46d06Srui zang - Sun Microsystems - Beijing China 	if ((strcmp(parent_type, "isa") == 0) ||
33245e46d06Srui zang - Sun Microsystems - Beijing China 	    (strcmp(parent_type, "eisa") == 0)) {
33348b3f8deSEdward Shu 		p->found_dip = dip;
33445e46d06Srui zang - Sun Microsystems - Beijing China 		ddi_prop_free(parent_type);
33545e46d06Srui zang - Sun Microsystems - Beijing China 		return (DDI_WALK_TERMINATE);
33645e46d06Srui zang - Sun Microsystems - Beijing China 	}
33745e46d06Srui zang - Sun Microsystems - Beijing China 
33845e46d06Srui zang - Sun Microsystems - Beijing China 	if ((strcmp(parent_type, "pci") == 0) ||
33945e46d06Srui zang - Sun Microsystems - Beijing China 	    (strcmp(parent_type, "pciex") == 0)) {
34045e46d06Srui zang - Sun Microsystems - Beijing China 		ddi_acc_handle_t pci_conf;
34145e46d06Srui zang - Sun Microsystems - Beijing China 		uint16_t data16;
34245e46d06Srui zang - Sun Microsystems - Beijing China 
34345e46d06Srui zang - Sun Microsystems - Beijing China 		ddi_prop_free(parent_type);
34445e46d06Srui zang - Sun Microsystems - Beijing China 
34545e46d06Srui zang - Sun Microsystems - Beijing China 		if (i_ddi_attach_node_hierarchy(dip) != DDI_SUCCESS)
346c401c7a8Srui zang - Sun Microsystems - Beijing China 			return (DDI_WALK_PRUNECHILD);
34745e46d06Srui zang - Sun Microsystems - Beijing China 
34845e46d06Srui zang - Sun Microsystems - Beijing China 		if (pci_config_setup(dip, &pci_conf) != DDI_SUCCESS)
349c401c7a8Srui zang - Sun Microsystems - Beijing China 			return (DDI_WALK_PRUNECHILD);
35045e46d06Srui zang - Sun Microsystems - Beijing China 
35145e46d06Srui zang - Sun Microsystems - Beijing China 		data16 = pci_config_get16(pci_conf, PCI_CONF_COMM);
35245e46d06Srui zang - Sun Microsystems - Beijing China 		pci_config_teardown(&pci_conf);
35345e46d06Srui zang - Sun Microsystems - Beijing China 
35445e46d06Srui zang - Sun Microsystems - Beijing China 		if (!(data16 & PCI_COMM_IO))
355c401c7a8Srui zang - Sun Microsystems - Beijing China 			return (DDI_WALK_PRUNECHILD);
35645e46d06Srui zang - Sun Microsystems - Beijing China 
35748b3f8deSEdward Shu 		p->found_dip = dip;
35845e46d06Srui zang - Sun Microsystems - Beijing China 		return (DDI_WALK_TERMINATE);
35945e46d06Srui zang - Sun Microsystems - Beijing China 	}
36045e46d06Srui zang - Sun Microsystems - Beijing China 
36145e46d06Srui zang - Sun Microsystems - Beijing China 	ddi_prop_free(parent_type);
362c401c7a8Srui zang - Sun Microsystems - Beijing China 	return (DDI_WALK_PRUNECHILD);
36345e46d06Srui zang - Sun Microsystems - Beijing China }
36445e46d06Srui zang - Sun Microsystems - Beijing China 
3657c478bd9Sstevel@tonic-gate /*
36648b3f8deSEdward Shu  * The first round search is to find:
36745e46d06Srui zang - Sun Microsystems - Beijing China  * 1) a VGA device.
36845e46d06Srui zang - Sun Microsystems - Beijing China  * 2) a PCI VGA compatible device whose IO space is enabled
36945e46d06Srui zang - Sun Microsystems - Beijing China  *    and the VGA Enable bit of any PCI-PCI bridge above it is set.
37048b3f8deSEdward Shu  * If the first round search succeeds, prune the second round search.
37148b3f8deSEdward Shu  *
37248b3f8deSEdward Shu  * The second round seach does not check the VGA Enable bit.
37345e46d06Srui zang - Sun Microsystems - Beijing China  *
37445e46d06Srui zang - Sun Microsystems - Beijing China  * Return the device path as the console fb path.
3757c478bd9Sstevel@tonic-gate  */
3767c478bd9Sstevel@tonic-gate char *
plat_fbpath(void)3777c478bd9Sstevel@tonic-gate plat_fbpath(void)
3787c478bd9Sstevel@tonic-gate {
37948b3f8deSEdward Shu 	struct find_fb_dev_param param;
3807c478bd9Sstevel@tonic-gate 	static char *fbpath = NULL;
3817c478bd9Sstevel@tonic-gate 	static char fbpath_buf[MAXPATHLEN];
3827c478bd9Sstevel@tonic-gate 
38348b3f8deSEdward Shu 	/* first round search */
38448b3f8deSEdward Shu 	param.found_dip = NULL;
38548b3f8deSEdward Shu 	param.vga_enable = 1;
38648b3f8deSEdward Shu 	ddi_walk_devs(ddi_root_node(), find_fb_dev, &param);
38748b3f8deSEdward Shu 
38848b3f8deSEdward Shu 	if (param.found_dip != NULL) {
38948b3f8deSEdward Shu 		(void) ddi_pathname(param.found_dip, fbpath_buf);
39048b3f8deSEdward Shu 		fbpath = fbpath_buf;
39148b3f8deSEdward Shu 		return (fbpath);
39248b3f8deSEdward Shu 	}
39345e46d06Srui zang - Sun Microsystems - Beijing China 
39448b3f8deSEdward Shu 	/*
39548b3f8deSEdward Shu 	 * second round search, do not check the
39648b3f8deSEdward Shu 	 * PCI_BCNF_BCNTRL_VGA_ENABLE bit
39748b3f8deSEdward Shu 	 */
39848b3f8deSEdward Shu 	param.found_dip = NULL;
39948b3f8deSEdward Shu 	param.vga_enable = 0;
40048b3f8deSEdward Shu 	ddi_walk_devs(ddi_root_node(), find_fb_dev, &param);
40148b3f8deSEdward Shu 
40248b3f8deSEdward Shu 	if (param.found_dip == NULL)
40345e46d06Srui zang - Sun Microsystems - Beijing China 		return (NULL);
4047c478bd9Sstevel@tonic-gate 
40548b3f8deSEdward Shu 	(void) ddi_pathname(param.found_dip, fbpath_buf);
40645e46d06Srui zang - Sun Microsystems - Beijing China 	fbpath = fbpath_buf;
407843e1988Sjohnlev 	return (fbpath);
4087c478bd9Sstevel@tonic-gate }
4097c478bd9Sstevel@tonic-gate 
4107c478bd9Sstevel@tonic-gate char *
plat_mousepath(void)4117c478bd9Sstevel@tonic-gate plat_mousepath(void)
4127c478bd9Sstevel@tonic-gate {
41378323854SJudy Chen 	static char mpath[MAXPATHLEN];
41478323854SJudy Chen 
4157c478bd9Sstevel@tonic-gate 	/*
4167c478bd9Sstevel@tonic-gate 	 * Hardcode to isa mouse path
4177c478bd9Sstevel@tonic-gate 	 * XXX make it settable via bootprop?
4187c478bd9Sstevel@tonic-gate 	 */
41978323854SJudy Chen 	if (pseudo_isa)
42078323854SJudy Chen 		return ("/isa/i8042@1,60/mouse@1");
42178323854SJudy Chen 
42278323854SJudy Chen 	if (plat_devpath("mouse8042", mpath) == NULL)
42378323854SJudy Chen 		return (NULL);
42478323854SJudy Chen 
42578323854SJudy Chen 	return (mpath);
4267c478bd9Sstevel@tonic-gate }
4277c478bd9Sstevel@tonic-gate 
42828cdc3d7Sszhou /* return path of first usb serial device */
42928cdc3d7Sszhou static char *
plat_usbser_path(void)43028cdc3d7Sszhou plat_usbser_path(void)
43128cdc3d7Sszhou {
43228cdc3d7Sszhou 	extern dev_info_t *usbser_first_device(void);
43328cdc3d7Sszhou 
43428cdc3d7Sszhou 	dev_info_t *us_dip;
43528cdc3d7Sszhou 	static char *us_path = NULL;
43628cdc3d7Sszhou 
43728cdc3d7Sszhou 	if (us_path)
43828cdc3d7Sszhou 		return (us_path);
43928cdc3d7Sszhou 
44028cdc3d7Sszhou 	us_dip = usbser_first_device();
44128cdc3d7Sszhou 	if (us_dip == NULL)
44228cdc3d7Sszhou 		return (NULL);
44328cdc3d7Sszhou 
44428cdc3d7Sszhou 	us_path = kmem_alloc(MAXPATHLEN, KM_SLEEP);
44528cdc3d7Sszhou 	(void) ddi_pathname(us_dip, us_path);
44628cdc3d7Sszhou 	ndi_rele_devi(us_dip);	/* held from usbser_first_device */
44728cdc3d7Sszhou 	return (us_path);
44828cdc3d7Sszhou }
44928cdc3d7Sszhou 
45078323854SJudy Chen static char *
plat_ttypath(int inum)45178323854SJudy Chen plat_ttypath(int inum)
45278323854SJudy Chen {
45378323854SJudy Chen 	static char *defaultpath[] = {
45478323854SJudy Chen 	    "/isa/asy@1,3f8:a",
4550d928757SGary Mills 	    "/isa/asy@1,2f8:b",
4560d928757SGary Mills 	    "/isa/asy@1,3e8:c",
4570d928757SGary Mills 	    "/isa/asy@1,2e8:d"
45878323854SJudy Chen 	};
45978323854SJudy Chen 	static char path[MAXPATHLEN];
46078323854SJudy Chen 	char *bp;
46178323854SJudy Chen 	major_t major;
46278323854SJudy Chen 	dev_info_t *dip;
46378323854SJudy Chen 
46478323854SJudy Chen 	if (pseudo_isa)
46578323854SJudy Chen 		return (defaultpath[inum]);
46678323854SJudy Chen 
46778323854SJudy Chen 	if ((major = ddi_name_to_major("asy")) == (major_t)-1)
46878323854SJudy Chen 		return (NULL);
46978323854SJudy Chen 
47078323854SJudy Chen 	if ((dip = devnamesp[major].dn_head) == NULL)
47178323854SJudy Chen 		return (NULL);
47278323854SJudy Chen 
47301457ffdSJudy Chen 	for (; dip != NULL; dip = ddi_get_next(dip)) {
47401457ffdSJudy Chen 		if (i_ddi_attach_node_hierarchy(dip) != DDI_SUCCESS)
47578323854SJudy Chen 			return (NULL);
47678323854SJudy Chen 
47701457ffdSJudy Chen 		if (DEVI(dip)->devi_minor->ddm_name[0] == ('a' + (char)inum))
47801457ffdSJudy Chen 			break;
47901457ffdSJudy Chen 	}
48001457ffdSJudy Chen 	if (dip == NULL)
48178323854SJudy Chen 		return (NULL);
48278323854SJudy Chen 
48378323854SJudy Chen 	(void) ddi_pathname(dip, path);
48478323854SJudy Chen 	bp = path + strlen(path);
48578323854SJudy Chen 	(void) snprintf(bp, 3, ":%s", DEVI(dip)->devi_minor->ddm_name);
48678323854SJudy Chen 
48778323854SJudy Chen 	return (path);
48878323854SJudy Chen }
48978323854SJudy Chen 
4907c478bd9Sstevel@tonic-gate /*
4917c478bd9Sstevel@tonic-gate  * Another possible enhancement could be to use properties
4927c478bd9Sstevel@tonic-gate  * for the port mapping rather than simply hard-code them.
4937c478bd9Sstevel@tonic-gate  */
4947c478bd9Sstevel@tonic-gate char *
plat_stdinpath(void)4957c478bd9Sstevel@tonic-gate plat_stdinpath(void)
4967c478bd9Sstevel@tonic-gate {
4970d928757SGary Mills 	int tty_num = 0;
4980d928757SGary Mills 
4990d928757SGary Mills 	switch (console_type(&tty_num)) {
500843e1988Sjohnlev #if defined(__xpv)
501843e1988Sjohnlev 	case CONS_HYPERVISOR:
502843e1988Sjohnlev 		return ("/xpvd/xencons@0");
503843e1988Sjohnlev #endif /* __xpv */
5040d928757SGary Mills 	case CONS_TTY:
5050d928757SGary Mills 		return (plat_ttypath(tty_num));
50628cdc3d7Sszhou 	case CONS_USBSER:
50728cdc3d7Sszhou 		return (plat_usbser_path());
5080d928757SGary Mills 	case CONS_SCREEN_TEXT:
5097c478bd9Sstevel@tonic-gate 	default:
5107c478bd9Sstevel@tonic-gate 		break;
5117c478bd9Sstevel@tonic-gate 	};
5127c478bd9Sstevel@tonic-gate 	return (plat_kbdpath());
5137c478bd9Sstevel@tonic-gate }
5147c478bd9Sstevel@tonic-gate 
5157c478bd9Sstevel@tonic-gate char *
plat_stdoutpath(void)5167c478bd9Sstevel@tonic-gate plat_stdoutpath(void)
5177c478bd9Sstevel@tonic-gate {
5180d928757SGary Mills 	int tty_num = 0;
5190d928757SGary Mills 
5200d928757SGary Mills 	switch (console_type(&tty_num)) {
521843e1988Sjohnlev #if defined(__xpv)
522843e1988Sjohnlev 	case CONS_HYPERVISOR:
523843e1988Sjohnlev 		return ("/xpvd/xencons@0");
524843e1988Sjohnlev #endif /* __xpv */
5250d928757SGary Mills 	case CONS_TTY:
5260d928757SGary Mills 		return (plat_ttypath(tty_num));
52728cdc3d7Sszhou 	case CONS_USBSER:
52828cdc3d7Sszhou 		return (plat_usbser_path());
5290d928757SGary Mills 	case CONS_SCREEN_TEXT:
5307c478bd9Sstevel@tonic-gate 	default:
5317c478bd9Sstevel@tonic-gate 		break;
5327c478bd9Sstevel@tonic-gate 	};
5337c478bd9Sstevel@tonic-gate 	return (plat_fbpath());
5347c478bd9Sstevel@tonic-gate }
535fea9cb91Slq 
536dbad7380SToomas Soome char *
plat_diagpath(void)537dbad7380SToomas Soome plat_diagpath(void)
538dbad7380SToomas Soome {
539dbad7380SToomas Soome 	dev_info_t *root;
540dbad7380SToomas Soome 	char *diag;
541dbad7380SToomas Soome 	int tty_num = -1;
542dbad7380SToomas Soome 
543dbad7380SToomas Soome 	root = ddi_root_node();
544dbad7380SToomas Soome 
545dbad7380SToomas Soome 	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, root, DDI_PROP_DONTPASS,
546dbad7380SToomas Soome 	    "diag-device", &diag) == DDI_SUCCESS) {
547dbad7380SToomas Soome 		if (strlen(diag) == 4 && strncmp(diag, "tty", 3) == 0 &&
548dbad7380SToomas Soome 		    diag[3] >= 'a' && diag[3] <= 'd') {
549dbad7380SToomas Soome 			tty_num = diag[3] - 'a';
550dbad7380SToomas Soome 		}
551dbad7380SToomas Soome 		ddi_prop_free(diag);
552dbad7380SToomas Soome 	}
553dbad7380SToomas Soome 
554dbad7380SToomas Soome 	if (tty_num != -1)
555dbad7380SToomas Soome 		return (plat_ttypath(tty_num));
556dbad7380SToomas Soome 	return (NULL);
557dbad7380SToomas Soome }
558dbad7380SToomas Soome 
559fea9cb91Slq /*
560fea9cb91Slq  * If VIS_PIXEL mode will be implemented on x86, these following
561fea9cb91Slq  * functions should be re-considered. Now these functions are
562fea9cb91Slq  * unused on x86.
563fea9cb91Slq  */
5644dfe872dSToomas Soome void
plat_tem_get_colors(uint8_t * fg,uint8_t * bg)5654dfe872dSToomas Soome plat_tem_get_colors(uint8_t *fg, uint8_t *bg)
5664dfe872dSToomas Soome {
5674dfe872dSToomas Soome 	*fg = fb_info.fg_color;
5684dfe872dSToomas Soome 	*bg = fb_info.bg_color;
5694dfe872dSToomas Soome }
5704dfe872dSToomas Soome 
571c9503a49Slq void
plat_tem_get_inverses(int * inverse,int * inverse_screen)572c9503a49Slq plat_tem_get_inverses(int *inverse, int *inverse_screen)
573c9503a49Slq {
574*82bb7c22SToomas Soome 	*inverse = fb_info.inverse == B_TRUE? 1 : 0;
575*82bb7c22SToomas Soome 	*inverse_screen = fb_info.inverse_screen == B_TRUE? 1 : 0;
576c9503a49Slq }
577c9503a49Slq 
578fea9cb91Slq void
plat_tem_get_prom_font_size(int * charheight,int * windowtop)579fea9cb91Slq plat_tem_get_prom_font_size(int *charheight, int *windowtop)
580fea9cb91Slq {
581*82bb7c22SToomas Soome 	*charheight = fb_info.font_height;
582*82bb7c22SToomas Soome 	*windowtop = fb_info.terminal_origin.y;
583fea9cb91Slq }
584fea9cb91Slq 
585843e1988Sjohnlev /*ARGSUSED*/
586fea9cb91Slq void
plat_tem_get_prom_size(size_t * height,size_t * width)587fea9cb91Slq plat_tem_get_prom_size(size_t *height, size_t *width)
588fea9cb91Slq {
589*82bb7c22SToomas Soome 	*height = fb_info.terminal.y;
590*82bb7c22SToomas Soome 	*width = fb_info.terminal.x;
591fea9cb91Slq }
592fea9cb91Slq 
593*82bb7c22SToomas Soome /* this gets called once at boot time and only in case of VIS_PIXEL */
594fea9cb91Slq void
plat_tem_hide_prom_cursor(void)595fea9cb91Slq plat_tem_hide_prom_cursor(void)
596fea9cb91Slq {
597*82bb7c22SToomas Soome 	if (boot_console_type(NULL) == CONS_FRAMEBUFFER)
598*82bb7c22SToomas Soome 		boot_fb_cursor(B_FALSE);
599fea9cb91Slq }
600fea9cb91Slq 
601843e1988Sjohnlev /*ARGSUSED*/
602fea9cb91Slq void
plat_tem_get_prom_pos(uint32_t * row,uint32_t * col)603fea9cb91Slq plat_tem_get_prom_pos(uint32_t *row, uint32_t *col)
604fea9cb91Slq {
605*82bb7c22SToomas Soome 	*row = fb_info.cursor.pos.y;
606*82bb7c22SToomas Soome 	*col = fb_info.cursor.pos.x;
607fea9cb91Slq }
608