xref: /titanic_44/usr/src/uts/i86pc/io/consplat.c (revision 0d928757379972073af9fb22bdc827b74e8ba6ac)
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 /*
23*0d928757SGary Mills  * Copyright (c) 2012 Gary Mills
24*0d928757SGary Mills  *
2593a18d6dSEnrico Perla - Sun Microsystems  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
26ae115bc7Smrj  * Use is subject to license terms.
27ae115bc7Smrj  */
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>
4745e46d06Srui zang - Sun Microsystems - Beijing China #include <sys/pci.h>
48843e1988Sjohnlev #if defined(__xpv)
49843e1988Sjohnlev #include <sys/hypervisor.h>
50843e1988Sjohnlev #include <sys/boot_console.h>
51843e1988Sjohnlev #endif
52ae115bc7Smrj 
5378323854SJudy Chen extern int pseudo_isa;
5478323854SJudy Chen 
55ae115bc7Smrj int
plat_use_polled_debug()56ae115bc7Smrj plat_use_polled_debug() {
57ae115bc7Smrj 	return (0);
58ae115bc7Smrj }
59ae115bc7Smrj 
60ae115bc7Smrj int
plat_support_serial_kbd_and_ms()61ae115bc7Smrj plat_support_serial_kbd_and_ms() {
62ae115bc7Smrj 	return (0);
63ae115bc7Smrj }
64ae115bc7Smrj 
65843e1988Sjohnlev #define	A_CNT(arr)	(sizeof (arr) / sizeof (arr[0]))
66843e1988Sjohnlev 
67*0d928757SGary Mills #ifndef	CONS_INVALID
68ae115bc7Smrj #define	CONS_INVALID		-1
69*0d928757SGary Mills #define	CONS_SCREEN_TEXT	0
70*0d928757SGary Mills #define	CONS_TTY		1
71*0d928757SGary Mills #define	CONS_XXX		2	/* Unused */
72ae115bc7Smrj #define	CONS_USBSER		3
73843e1988Sjohnlev #define	CONS_HYPERVISOR		4
74*0d928757SGary Mills #define	CONS_SCREEN_GRAPHICS	5
75*0d928757SGary Mills #endif	/* CONS_INVALID */
76ae115bc7Smrj 
77583da248Srz201010 char *plat_fbpath(void);
78583da248Srz201010 
79ae115bc7Smrj static int
console_type(int * tnum)80*0d928757SGary Mills console_type(int *tnum)
81ae115bc7Smrj {
82ae115bc7Smrj 	static int boot_console = CONS_INVALID;
83*0d928757SGary Mills 	static int tty_num = 0;
84ae115bc7Smrj 
85ae115bc7Smrj 	char *cons;
86ae115bc7Smrj 	dev_info_t *root;
87ae115bc7Smrj 
88*0d928757SGary Mills 	/* If we already have determined the console, just return it. */
89*0d928757SGary Mills 	if (boot_console != CONS_INVALID) {
90*0d928757SGary Mills 		if (tnum != NULL)
91*0d928757SGary Mills 			*tnum = tty_num;
92ae115bc7Smrj 		return (boot_console);
93*0d928757SGary Mills 	}
94ae115bc7Smrj 
95843e1988Sjohnlev #if defined(__xpv)
96843e1988Sjohnlev 	if (!DOMAIN_IS_INITDOMAIN(xen_info) || bcons_hypervisor_redirect()) {
97843e1988Sjohnlev 		boot_console = CONS_HYPERVISOR;
98*0d928757SGary Mills 		if (tnum != NULL)
99*0d928757SGary Mills 			*tnum = tty_num;
100843e1988Sjohnlev 		return (boot_console);
101843e1988Sjohnlev 	}
102843e1988Sjohnlev #endif /* __xpv */
103843e1988Sjohnlev 
104ae115bc7Smrj 	/*
105ae115bc7Smrj 	 * console is defined by "console" property, with
106ae115bc7Smrj 	 * fallback on the old "input-device" property.
107583da248Srz201010 	 * If "input-device" is not defined either, also check "output-device".
108ae115bc7Smrj 	 */
109*0d928757SGary Mills 	boot_console = CONS_SCREEN_TEXT;	/* default is screen/kb */
110ae115bc7Smrj 	root = ddi_root_node();
111ae115bc7Smrj 	if ((ddi_prop_lookup_string(DDI_DEV_T_ANY, root,
112ae115bc7Smrj 	    DDI_PROP_DONTPASS, "console", &cons) == DDI_SUCCESS) ||
113ae115bc7Smrj 	    (ddi_prop_lookup_string(DDI_DEV_T_ANY, root,
114583da248Srz201010 	    DDI_PROP_DONTPASS, "input-device", &cons) == DDI_SUCCESS) ||
115583da248Srz201010 	    (ddi_prop_lookup_string(DDI_DEV_T_ANY, root,
116583da248Srz201010 	    DDI_PROP_DONTPASS, "output-device", &cons) == DDI_SUCCESS)) {
117*0d928757SGary Mills 		if (strlen(cons) == 4 && strncmp(cons, "tty", 3) == 0 &&
118*0d928757SGary Mills 		    cons[3] >= 'a' && cons[3] <= 'd') {
119*0d928757SGary Mills 			boot_console = CONS_TTY;
120*0d928757SGary Mills 			tty_num = cons[3] - 'a';
121843e1988Sjohnlev 		} else if (strcmp(cons, "usb-serial") == 0) {
122ae115bc7Smrj 			(void) i_ddi_attach_hw_nodes("ehci");
123ae115bc7Smrj 			(void) i_ddi_attach_hw_nodes("uhci");
124ae115bc7Smrj 			(void) i_ddi_attach_hw_nodes("ohci");
125ae115bc7Smrj 			/*
126ae115bc7Smrj 			 * USB device enumerate asynchronously.
127ae115bc7Smrj 			 * Wait 2 seconds for USB serial devices to attach.
128ae115bc7Smrj 			 */
129ae115bc7Smrj 			delay(drv_usectohz(2000000));
130ae115bc7Smrj 			boot_console = CONS_USBSER;
131843e1988Sjohnlev #if defined(__xpv)
132843e1988Sjohnlev 		} else if (strcmp(cons, "hypervisor") == 0) {
133843e1988Sjohnlev 			boot_console = CONS_HYPERVISOR;
134843e1988Sjohnlev #endif /* __xpv */
135ae115bc7Smrj 		}
136ae115bc7Smrj 		ddi_prop_free(cons);
137ae115bc7Smrj 	}
138583da248Srz201010 
139583da248Srz201010 	/*
140583da248Srz201010 	 * If the console is configured to use a framebuffer but none
141583da248Srz201010 	 * could be found, fallback to "ttya" since it's likely to exist
142583da248Srz201010 	 * and it matches longstanding behavior on SPARC.
143583da248Srz201010 	 */
144*0d928757SGary Mills 	if (boot_console == CONS_SCREEN_TEXT && plat_fbpath() == NULL) {
145*0d928757SGary Mills 		boot_console = CONS_TTY;
146*0d928757SGary Mills 		tty_num = 0;
147*0d928757SGary Mills 	}
148583da248Srz201010 
149*0d928757SGary Mills 	if (tnum != NULL)
150*0d928757SGary Mills 		*tnum = tty_num;
151ae115bc7Smrj 	return (boot_console);
152ae115bc7Smrj }
153ae115bc7Smrj 
154ae115bc7Smrj int
plat_stdin_is_keyboard(void)155ae115bc7Smrj plat_stdin_is_keyboard(void)
156ae115bc7Smrj {
157*0d928757SGary Mills 	return (console_type(NULL) == CONS_SCREEN_TEXT);
158ae115bc7Smrj }
159ae115bc7Smrj 
160ae115bc7Smrj int
plat_stdout_is_framebuffer(void)161ae115bc7Smrj plat_stdout_is_framebuffer(void)
162ae115bc7Smrj {
163*0d928757SGary Mills 	return (console_type(NULL) == CONS_SCREEN_TEXT);
164ae115bc7Smrj }
165ae115bc7Smrj 
16678323854SJudy Chen static char *
plat_devpath(char * name,char * path)16778323854SJudy Chen plat_devpath(char *name, char *path)
16878323854SJudy Chen {
16978323854SJudy Chen 	major_t major;
17078323854SJudy Chen 	dev_info_t *dip, *pdip;
17178323854SJudy Chen 
17278323854SJudy Chen 	if ((major = ddi_name_to_major(name)) == (major_t)-1)
17378323854SJudy Chen 		return (NULL);
17478323854SJudy Chen 
17578323854SJudy Chen 	if ((dip = devnamesp[major].dn_head) == NULL)
17678323854SJudy Chen 		return (NULL);
17778323854SJudy Chen 
17878323854SJudy Chen 	pdip = ddi_get_parent(dip);
17978323854SJudy Chen 	if (i_ddi_attach_node_hierarchy(pdip) != DDI_SUCCESS)
18078323854SJudy Chen 		return (NULL);
18178323854SJudy Chen 	if (ddi_initchild(pdip, dip) != DDI_SUCCESS)
18278323854SJudy Chen 		return (NULL);
18378323854SJudy Chen 
18478323854SJudy Chen 	(void) ddi_pathname(dip, path);
18578323854SJudy Chen 
18678323854SJudy Chen 	return (path);
18778323854SJudy Chen }
18878323854SJudy Chen 
189ae115bc7Smrj /*
190ae115bc7Smrj  * Return generic path to keyboard device from the alias.
191ae115bc7Smrj  */
192ae115bc7Smrj char *
plat_kbdpath(void)193ae115bc7Smrj plat_kbdpath(void)
194ae115bc7Smrj {
19578323854SJudy Chen 	static char kbpath[MAXPATHLEN];
19678323854SJudy Chen 
197ae115bc7Smrj 	/*
198ae115bc7Smrj 	 * Hardcode to isa keyboard path
199ae115bc7Smrj 	 * XXX make it settable via bootprop?
200ae115bc7Smrj 	 */
20178323854SJudy Chen 	if (pseudo_isa)
202ae115bc7Smrj 		return ("/isa/i8042@1,60/keyboard@0");
20378323854SJudy Chen 
20478323854SJudy Chen 	if (plat_devpath("kb8042", kbpath) == NULL)
20578323854SJudy Chen 		return (NULL);
20678323854SJudy Chen 
20778323854SJudy Chen 	return (kbpath);
208ae115bc7Smrj }
209ae115bc7Smrj 
21093a18d6dSEnrico Perla - Sun Microsystems /*
21193a18d6dSEnrico Perla - Sun Microsystems  * NOTE: this function is duplicated here and in gfx_private/vgatext while
21293a18d6dSEnrico Perla - Sun Microsystems  *       we work on a set of commitable interfaces to sunpci.c.
21393a18d6dSEnrico Perla - Sun Microsystems  *
21493a18d6dSEnrico Perla - Sun Microsystems  * Use the class code to determine if the device is a PCI-to-PCI bridge.
21593a18d6dSEnrico Perla - Sun Microsystems  * Returns:  B_TRUE  if the device is a bridge.
21693a18d6dSEnrico Perla - Sun Microsystems  *           B_FALSE if the device is not a bridge or the property cannot be
21793a18d6dSEnrico Perla - Sun Microsystems  *		     retrieved.
21893a18d6dSEnrico Perla - Sun Microsystems  */
21993a18d6dSEnrico Perla - Sun Microsystems static boolean_t
is_pci_bridge(dev_info_t * dip)22093a18d6dSEnrico Perla - Sun Microsystems is_pci_bridge(dev_info_t *dip)
22193a18d6dSEnrico Perla - Sun Microsystems {
22293a18d6dSEnrico Perla - Sun Microsystems 	uint32_t class_code;
22393a18d6dSEnrico Perla - Sun Microsystems 
22493a18d6dSEnrico Perla - Sun Microsystems 	class_code = (uint32_t)ddi_prop_get_int(DDI_DEV_T_ANY, dip,
22593a18d6dSEnrico Perla - Sun Microsystems 	    DDI_PROP_DONTPASS, "class-code", 0xffffffff);
22693a18d6dSEnrico Perla - Sun Microsystems 
22793a18d6dSEnrico Perla - Sun Microsystems 	if (class_code == 0xffffffff || class_code == DDI_PROP_NOT_FOUND)
22893a18d6dSEnrico Perla - Sun Microsystems 		return (B_FALSE);
22993a18d6dSEnrico Perla - Sun Microsystems 
23093a18d6dSEnrico Perla - Sun Microsystems 	class_code &= 0x00ffff00;
23193a18d6dSEnrico Perla - Sun Microsystems 	if (class_code == ((PCI_CLASS_BRIDGE << 16) | (PCI_BRIDGE_PCI << 8)))
23293a18d6dSEnrico Perla - Sun Microsystems 		return (B_TRUE);
23393a18d6dSEnrico Perla - Sun Microsystems 
23493a18d6dSEnrico Perla - Sun Microsystems 	return (B_FALSE);
23593a18d6dSEnrico Perla - Sun Microsystems }
23693a18d6dSEnrico Perla - Sun Microsystems 
23748b3f8deSEdward Shu /*
23848b3f8deSEdward Shu  * Type for the parameter of find_fb_dev()
23948b3f8deSEdward Shu  */
24048b3f8deSEdward Shu struct find_fb_dev_param
24145e46d06Srui zang - Sun Microsystems - Beijing China {
24248b3f8deSEdward Shu 	dev_info_t *found_dip;	/* dip found for VGA console */
24348b3f8deSEdward Shu 	int vga_enable;		/* check PCI_BCNF_BCNTRL_VGA_ENABLE or not */
24448b3f8deSEdward Shu };
24548b3f8deSEdward Shu 
24648b3f8deSEdward Shu /*
24748b3f8deSEdward Shu  * The VGA device could be under a subtractive PCI bridge on some systems.
24848b3f8deSEdward Shu  * Though the PCI_BCNF_BCNTRL_VGA_ENABLE bit is not set on such subtractive
24948b3f8deSEdward Shu  * PCI bridge, the subtractive PCI bridge can forward VGA access if no other
25048b3f8deSEdward Shu  * agent claims the access.
25148b3f8deSEdward Shu  * The vga_enable element in param acts as a flag, if not set, ignore the
25248b3f8deSEdward Shu  * checking for the PCI_BCNF_BCNTRL_VGA_ENABLE bit of the PCI bridge during
25348b3f8deSEdward Shu  * the search.
25448b3f8deSEdward Shu  */
25548b3f8deSEdward Shu static int
find_fb_dev(dev_info_t * dip,void * param)25648b3f8deSEdward Shu find_fb_dev(dev_info_t *dip, void *param)
25748b3f8deSEdward Shu {
25848b3f8deSEdward Shu 	struct find_fb_dev_param *p = param;
25945e46d06Srui zang - Sun Microsystems - Beijing China 	char *dev_type;
26045e46d06Srui zang - Sun Microsystems - Beijing China 	dev_info_t *pdip;
26145e46d06Srui zang - Sun Microsystems - Beijing China 	char *parent_type;
26245e46d06Srui zang - Sun Microsystems - Beijing China 
26345e46d06Srui zang - Sun Microsystems - Beijing China 	if (dip == ddi_root_node())
26445e46d06Srui zang - Sun Microsystems - Beijing China 		return (DDI_WALK_CONTINUE);
26545e46d06Srui zang - Sun Microsystems - Beijing China 
26645e46d06Srui zang - Sun Microsystems - Beijing China 	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
26745e46d06Srui zang - Sun Microsystems - Beijing China 	    "device_type", &dev_type) != DDI_SUCCESS)
26845e46d06Srui zang - Sun Microsystems - Beijing China 		return (DDI_WALK_PRUNECHILD);
26945e46d06Srui zang - Sun Microsystems - Beijing China 
27045e46d06Srui zang - Sun Microsystems - Beijing China 	if ((strcmp(dev_type, "isa") == 0) || (strcmp(dev_type, "eisa") == 0)) {
27145e46d06Srui zang - Sun Microsystems - Beijing China 		ddi_prop_free(dev_type);
27245e46d06Srui zang - Sun Microsystems - Beijing China 		return (DDI_WALK_CONTINUE);
27345e46d06Srui zang - Sun Microsystems - Beijing China 	}
27445e46d06Srui zang - Sun Microsystems - Beijing China 
27545e46d06Srui zang - Sun Microsystems - Beijing China 	if ((strcmp(dev_type, "pci") == 0) ||
27645e46d06Srui zang - Sun Microsystems - Beijing China 	    (strcmp(dev_type, "pciex") == 0)) {
27745e46d06Srui zang - Sun Microsystems - Beijing China 		ddi_acc_handle_t pci_conf;
27845e46d06Srui zang - Sun Microsystems - Beijing China 		uint16_t data16;
279c401c7a8Srui zang - Sun Microsystems - Beijing China 		char *nodename;
28045e46d06Srui zang - Sun Microsystems - Beijing China 
28145e46d06Srui zang - Sun Microsystems - Beijing China 		ddi_prop_free(dev_type);
28245e46d06Srui zang - Sun Microsystems - Beijing China 
28348b3f8deSEdward Shu 		if (!p->vga_enable)
28448b3f8deSEdward Shu 			return (DDI_WALK_CONTINUE);
28548b3f8deSEdward Shu 
286c401c7a8Srui zang - Sun Microsystems - Beijing China 		nodename = ddi_node_name(dip);
28745e46d06Srui zang - Sun Microsystems - Beijing China 
28893a18d6dSEnrico Perla - Sun Microsystems 		/*
28993a18d6dSEnrico Perla - Sun Microsystems 		 * If the node is not a PCI-to-PCI bridge, continue traversing
29093a18d6dSEnrico Perla - Sun Microsystems 		 * (it could be the root node), otherwise, check for the
29193a18d6dSEnrico Perla - Sun Microsystems 		 * VGAEnable bit to be set in the Bridge Control Register.
29293a18d6dSEnrico Perla - Sun Microsystems 		 */
293c401c7a8Srui zang - Sun Microsystems - Beijing China 		if (strcmp(nodename, "pci") == 0) {
29493a18d6dSEnrico Perla - Sun Microsystems 			if (is_pci_bridge(dip) == B_FALSE)
29545e46d06Srui zang - Sun Microsystems - Beijing China 				return (DDI_WALK_CONTINUE);
29645e46d06Srui zang - Sun Microsystems - Beijing China 		}
29745e46d06Srui zang - Sun Microsystems - Beijing China 
298c401c7a8Srui zang - Sun Microsystems - Beijing China 		if (i_ddi_attach_node_hierarchy(dip) != DDI_SUCCESS)
299c401c7a8Srui zang - Sun Microsystems - Beijing China 			return (DDI_WALK_PRUNECHILD);
300c401c7a8Srui zang - Sun Microsystems - Beijing China 
301c401c7a8Srui zang - Sun Microsystems - Beijing China 		if (pci_config_setup(dip, &pci_conf) != DDI_SUCCESS)
302c401c7a8Srui zang - Sun Microsystems - Beijing China 			return (DDI_WALK_PRUNECHILD);
303c401c7a8Srui zang - Sun Microsystems - Beijing China 
30445e46d06Srui zang - Sun Microsystems - Beijing China 		data16 = pci_config_get16(pci_conf, PCI_BCNF_BCNTRL);
30545e46d06Srui zang - Sun Microsystems - Beijing China 		pci_config_teardown(&pci_conf);
30645e46d06Srui zang - Sun Microsystems - Beijing China 
30745e46d06Srui zang - Sun Microsystems - Beijing China 		if (data16 & PCI_BCNF_BCNTRL_VGA_ENABLE)
30845e46d06Srui zang - Sun Microsystems - Beijing China 			return (DDI_WALK_CONTINUE);
30945e46d06Srui zang - Sun Microsystems - Beijing China 
31045e46d06Srui zang - Sun Microsystems - Beijing China 		return (DDI_WALK_PRUNECHILD);
31145e46d06Srui zang - Sun Microsystems - Beijing China 	}
31245e46d06Srui zang - Sun Microsystems - Beijing China 
31345e46d06Srui zang - Sun Microsystems - Beijing China 	if (strcmp(dev_type, "display") != 0) {
31445e46d06Srui zang - Sun Microsystems - Beijing China 		ddi_prop_free(dev_type);
31545e46d06Srui zang - Sun Microsystems - Beijing China 		return (DDI_WALK_CONTINUE);
31645e46d06Srui zang - Sun Microsystems - Beijing China 	}
31745e46d06Srui zang - Sun Microsystems - Beijing China 
31845e46d06Srui zang - Sun Microsystems - Beijing China 	ddi_prop_free(dev_type);
31945e46d06Srui zang - Sun Microsystems - Beijing China 
32045e46d06Srui zang - Sun Microsystems - Beijing China 	if ((pdip = ddi_get_parent(dip)) == NULL)
321c401c7a8Srui zang - Sun Microsystems - Beijing China 		return (DDI_WALK_PRUNECHILD);
32245e46d06Srui zang - Sun Microsystems - Beijing China 
32345e46d06Srui zang - Sun Microsystems - Beijing China 	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, pdip, DDI_PROP_DONTPASS,
32445e46d06Srui zang - Sun Microsystems - Beijing China 	    "device_type", &parent_type) != DDI_SUCCESS)
325c401c7a8Srui zang - Sun Microsystems - Beijing China 		return (DDI_WALK_PRUNECHILD);
32645e46d06Srui zang - Sun Microsystems - Beijing China 
32745e46d06Srui zang - Sun Microsystems - Beijing China 	if ((strcmp(parent_type, "isa") == 0) ||
32845e46d06Srui zang - Sun Microsystems - Beijing China 	    (strcmp(parent_type, "eisa") == 0)) {
32948b3f8deSEdward Shu 		p->found_dip = dip;
33045e46d06Srui zang - Sun Microsystems - Beijing China 		ddi_prop_free(parent_type);
33145e46d06Srui zang - Sun Microsystems - Beijing China 		return (DDI_WALK_TERMINATE);
33245e46d06Srui zang - Sun Microsystems - Beijing China 	}
33345e46d06Srui zang - Sun Microsystems - Beijing China 
33445e46d06Srui zang - Sun Microsystems - Beijing China 	if ((strcmp(parent_type, "pci") == 0) ||
33545e46d06Srui zang - Sun Microsystems - Beijing China 	    (strcmp(parent_type, "pciex") == 0)) {
33645e46d06Srui zang - Sun Microsystems - Beijing China 		ddi_acc_handle_t pci_conf;
33745e46d06Srui zang - Sun Microsystems - Beijing China 		uint16_t data16;
33845e46d06Srui zang - Sun Microsystems - Beijing China 
33945e46d06Srui zang - Sun Microsystems - Beijing China 		ddi_prop_free(parent_type);
34045e46d06Srui zang - Sun Microsystems - Beijing China 
34145e46d06Srui zang - Sun Microsystems - Beijing China 		if (i_ddi_attach_node_hierarchy(dip) != DDI_SUCCESS)
342c401c7a8Srui zang - Sun Microsystems - Beijing China 			return (DDI_WALK_PRUNECHILD);
34345e46d06Srui zang - Sun Microsystems - Beijing China 
34445e46d06Srui zang - Sun Microsystems - Beijing China 		if (pci_config_setup(dip, &pci_conf) != DDI_SUCCESS)
345c401c7a8Srui zang - Sun Microsystems - Beijing China 			return (DDI_WALK_PRUNECHILD);
34645e46d06Srui zang - Sun Microsystems - Beijing China 
34745e46d06Srui zang - Sun Microsystems - Beijing China 		data16 = pci_config_get16(pci_conf, PCI_CONF_COMM);
34845e46d06Srui zang - Sun Microsystems - Beijing China 		pci_config_teardown(&pci_conf);
34945e46d06Srui zang - Sun Microsystems - Beijing China 
35045e46d06Srui zang - Sun Microsystems - Beijing China 		if (!(data16 & PCI_COMM_IO))
351c401c7a8Srui zang - Sun Microsystems - Beijing China 			return (DDI_WALK_PRUNECHILD);
35245e46d06Srui zang - Sun Microsystems - Beijing China 
35348b3f8deSEdward Shu 		p->found_dip = dip;
35445e46d06Srui zang - Sun Microsystems - Beijing China 		return (DDI_WALK_TERMINATE);
35545e46d06Srui zang - Sun Microsystems - Beijing China 	}
35645e46d06Srui zang - Sun Microsystems - Beijing China 
35745e46d06Srui zang - Sun Microsystems - Beijing China 	ddi_prop_free(parent_type);
358c401c7a8Srui zang - Sun Microsystems - Beijing China 	return (DDI_WALK_PRUNECHILD);
35945e46d06Srui zang - Sun Microsystems - Beijing China }
36045e46d06Srui zang - Sun Microsystems - Beijing China 
361ae115bc7Smrj /*
36248b3f8deSEdward Shu  * The first round search is to find:
36345e46d06Srui zang - Sun Microsystems - Beijing China  * 1) a VGA device.
36445e46d06Srui zang - Sun Microsystems - Beijing China  * 2) a PCI VGA compatible device whose IO space is enabled
36545e46d06Srui zang - Sun Microsystems - Beijing China  *    and the VGA Enable bit of any PCI-PCI bridge above it is set.
36648b3f8deSEdward Shu  * If the first round search succeeds, prune the second round search.
36748b3f8deSEdward Shu  *
36848b3f8deSEdward Shu  * The second round seach does not check the VGA Enable bit.
36945e46d06Srui zang - Sun Microsystems - Beijing China  *
37045e46d06Srui zang - Sun Microsystems - Beijing China  * Return the device path as the console fb path.
371ae115bc7Smrj  */
372ae115bc7Smrj char *
plat_fbpath(void)373ae115bc7Smrj plat_fbpath(void)
374ae115bc7Smrj {
37548b3f8deSEdward Shu 	struct find_fb_dev_param param;
376ae115bc7Smrj 	static char *fbpath = NULL;
377ae115bc7Smrj 	static char fbpath_buf[MAXPATHLEN];
378ae115bc7Smrj 
37948b3f8deSEdward Shu 	/* first round search */
38048b3f8deSEdward Shu 	param.found_dip = NULL;
38148b3f8deSEdward Shu 	param.vga_enable = 1;
38248b3f8deSEdward Shu 	ddi_walk_devs(ddi_root_node(), find_fb_dev, &param);
383843e1988Sjohnlev 
38448b3f8deSEdward Shu 	if (param.found_dip != NULL) {
38548b3f8deSEdward Shu 		(void) ddi_pathname(param.found_dip, fbpath_buf);
38648b3f8deSEdward Shu 		fbpath = fbpath_buf;
38748b3f8deSEdward Shu 		return (fbpath);
38848b3f8deSEdward Shu 	}
38948b3f8deSEdward Shu 
39048b3f8deSEdward Shu 	/*
39148b3f8deSEdward Shu 	 * second round search, do not check the
39248b3f8deSEdward Shu 	 * PCI_BCNF_BCNTRL_VGA_ENABLE bit
39348b3f8deSEdward Shu 	 */
39448b3f8deSEdward Shu 	param.found_dip = NULL;
39548b3f8deSEdward Shu 	param.vga_enable = 0;
39648b3f8deSEdward Shu 	ddi_walk_devs(ddi_root_node(), find_fb_dev, &param);
39748b3f8deSEdward Shu 
39848b3f8deSEdward Shu 	if (param.found_dip == NULL)
39945e46d06Srui zang - Sun Microsystems - Beijing China 		return (NULL);
400843e1988Sjohnlev 
40148b3f8deSEdward Shu 	(void) ddi_pathname(param.found_dip, fbpath_buf);
402ae115bc7Smrj 	fbpath = fbpath_buf;
403843e1988Sjohnlev 	return (fbpath);
404ae115bc7Smrj }
405ae115bc7Smrj 
406ae115bc7Smrj char *
plat_mousepath(void)407ae115bc7Smrj plat_mousepath(void)
408ae115bc7Smrj {
40978323854SJudy Chen 	static char mpath[MAXPATHLEN];
41078323854SJudy Chen 
411ae115bc7Smrj 	/*
412ae115bc7Smrj 	 * Hardcode to isa mouse path
413ae115bc7Smrj 	 * XXX make it settable via bootprop?
414ae115bc7Smrj 	 */
41578323854SJudy Chen 	if (pseudo_isa)
416ae115bc7Smrj 		return ("/isa/i8042@1,60/mouse@1");
41778323854SJudy Chen 
41878323854SJudy Chen 	if (plat_devpath("mouse8042", mpath) == NULL)
41978323854SJudy Chen 		return (NULL);
42078323854SJudy Chen 
42178323854SJudy Chen 	return (mpath);
422ae115bc7Smrj }
423ae115bc7Smrj 
424ae115bc7Smrj /* return path of first usb serial device */
425ae115bc7Smrj static char *
plat_usbser_path(void)426ae115bc7Smrj plat_usbser_path(void)
427ae115bc7Smrj {
428ae115bc7Smrj 	extern dev_info_t *usbser_first_device(void);
429ae115bc7Smrj 
430ae115bc7Smrj 	dev_info_t *us_dip;
431ae115bc7Smrj 	static char *us_path = NULL;
432ae115bc7Smrj 
433ae115bc7Smrj 	if (us_path)
434ae115bc7Smrj 		return (us_path);
435ae115bc7Smrj 
436ae115bc7Smrj 	us_dip = usbser_first_device();
437ae115bc7Smrj 	if (us_dip == NULL)
438ae115bc7Smrj 		return (NULL);
439ae115bc7Smrj 
440ae115bc7Smrj 	us_path = kmem_alloc(MAXPATHLEN, KM_SLEEP);
441ae115bc7Smrj 	(void) ddi_pathname(us_dip, us_path);
442ae115bc7Smrj 	ndi_rele_devi(us_dip);	/* held from usbser_first_device */
443ae115bc7Smrj 	return (us_path);
444ae115bc7Smrj }
445ae115bc7Smrj 
44678323854SJudy Chen static char *
plat_ttypath(int inum)44778323854SJudy Chen plat_ttypath(int inum)
44878323854SJudy Chen {
44978323854SJudy Chen 	static char *defaultpath[] = {
45078323854SJudy Chen 	    "/isa/asy@1,3f8:a",
451*0d928757SGary Mills 	    "/isa/asy@1,2f8:b",
452*0d928757SGary Mills 	    "/isa/asy@1,3e8:c",
453*0d928757SGary Mills 	    "/isa/asy@1,2e8:d"
45478323854SJudy Chen 	};
45578323854SJudy Chen 	static char path[MAXPATHLEN];
45678323854SJudy Chen 	char *bp;
45778323854SJudy Chen 	major_t major;
45878323854SJudy Chen 	dev_info_t *dip;
45978323854SJudy Chen 
46078323854SJudy Chen 	if (pseudo_isa)
46178323854SJudy Chen 		return (defaultpath[inum]);
46278323854SJudy Chen 
46378323854SJudy Chen 	if ((major = ddi_name_to_major("asy")) == (major_t)-1)
46478323854SJudy Chen 		return (NULL);
46578323854SJudy Chen 
46678323854SJudy Chen 	if ((dip = devnamesp[major].dn_head) == NULL)
46778323854SJudy Chen 		return (NULL);
46878323854SJudy Chen 
46901457ffdSJudy Chen 	for (; dip != NULL; dip = ddi_get_next(dip)) {
47078323854SJudy Chen 		if (i_ddi_attach_node_hierarchy(dip) != DDI_SUCCESS)
47178323854SJudy Chen 			return (NULL);
47278323854SJudy Chen 
47301457ffdSJudy Chen 		if (DEVI(dip)->devi_minor->ddm_name[0] == ('a' + (char)inum))
47401457ffdSJudy Chen 			break;
47501457ffdSJudy Chen 	}
47601457ffdSJudy Chen 	if (dip == NULL)
47701457ffdSJudy Chen 		return (NULL);
47801457ffdSJudy Chen 
47978323854SJudy Chen 	(void) ddi_pathname(dip, path);
48078323854SJudy Chen 	bp = path + strlen(path);
48178323854SJudy Chen 	(void) snprintf(bp, 3, ":%s", DEVI(dip)->devi_minor->ddm_name);
48278323854SJudy Chen 
48378323854SJudy Chen 	return (path);
48478323854SJudy Chen }
48578323854SJudy Chen 
486ae115bc7Smrj /*
487ae115bc7Smrj  * Another possible enhancement could be to use properties
488ae115bc7Smrj  * for the port mapping rather than simply hard-code them.
489ae115bc7Smrj  */
490ae115bc7Smrj char *
plat_stdinpath(void)491ae115bc7Smrj plat_stdinpath(void)
492ae115bc7Smrj {
493*0d928757SGary Mills 	int tty_num = 0;
494*0d928757SGary Mills 
495*0d928757SGary Mills 	switch (console_type(&tty_num)) {
496843e1988Sjohnlev #if defined(__xpv)
497843e1988Sjohnlev 	case CONS_HYPERVISOR:
498843e1988Sjohnlev 		return ("/xpvd/xencons@0");
499843e1988Sjohnlev #endif /* __xpv */
500*0d928757SGary Mills 	case CONS_TTY:
501*0d928757SGary Mills 		return (plat_ttypath(tty_num));
502ae115bc7Smrj 	case CONS_USBSER:
503ae115bc7Smrj 		return (plat_usbser_path());
504*0d928757SGary Mills 	case CONS_SCREEN_TEXT:
505ae115bc7Smrj 	default:
506ae115bc7Smrj 		break;
507ae115bc7Smrj 	};
508ae115bc7Smrj 	return (plat_kbdpath());
509ae115bc7Smrj }
510ae115bc7Smrj 
511ae115bc7Smrj char *
plat_stdoutpath(void)512ae115bc7Smrj plat_stdoutpath(void)
513ae115bc7Smrj {
514*0d928757SGary Mills 	int tty_num = 0;
515*0d928757SGary Mills 
516*0d928757SGary Mills 	switch (console_type(&tty_num)) {
517843e1988Sjohnlev #if defined(__xpv)
518843e1988Sjohnlev 	case CONS_HYPERVISOR:
519843e1988Sjohnlev 		return ("/xpvd/xencons@0");
520843e1988Sjohnlev #endif /* __xpv */
521*0d928757SGary Mills 	case CONS_TTY:
522*0d928757SGary Mills 		return (plat_ttypath(tty_num));
523ae115bc7Smrj 	case CONS_USBSER:
524ae115bc7Smrj 		return (plat_usbser_path());
525*0d928757SGary Mills 	case CONS_SCREEN_TEXT:
526ae115bc7Smrj 	default:
527ae115bc7Smrj 		break;
528ae115bc7Smrj 	};
529ae115bc7Smrj 	return (plat_fbpath());
530ae115bc7Smrj }
531ae115bc7Smrj 
532ae115bc7Smrj /*
533ae115bc7Smrj  * If VIS_PIXEL mode will be implemented on x86, these following
534ae115bc7Smrj  * functions should be re-considered. Now these functions are
535ae115bc7Smrj  * unused on x86.
536ae115bc7Smrj  */
537ae115bc7Smrj void
plat_tem_get_inverses(int * inverse,int * inverse_screen)538c9503a49Slq150181 plat_tem_get_inverses(int *inverse, int *inverse_screen)
539c9503a49Slq150181 {
540c9503a49Slq150181 	*inverse = 0;
541c9503a49Slq150181 	*inverse_screen = 0;
542c9503a49Slq150181 }
543c9503a49Slq150181 
544c9503a49Slq150181 void
plat_tem_get_prom_font_size(int * charheight,int * windowtop)545ae115bc7Smrj plat_tem_get_prom_font_size(int *charheight, int *windowtop)
546ae115bc7Smrj {
547ae115bc7Smrj 	*charheight = 0;
548ae115bc7Smrj 	*windowtop = 0;
549ae115bc7Smrj }
550ae115bc7Smrj 
551843e1988Sjohnlev /*ARGSUSED*/
552ae115bc7Smrj void
plat_tem_get_prom_size(size_t * height,size_t * width)553ae115bc7Smrj plat_tem_get_prom_size(size_t *height, size_t *width)
554ae115bc7Smrj {
555843e1988Sjohnlev 	panic("unimplemented at line %d of %s", __LINE__, __FILE__);
556ae115bc7Smrj }
557ae115bc7Smrj 
558ae115bc7Smrj void
plat_tem_hide_prom_cursor(void)559ae115bc7Smrj plat_tem_hide_prom_cursor(void)
560ae115bc7Smrj {
561843e1988Sjohnlev 	panic("unimplemented at line %d of %s", __LINE__, __FILE__);
562ae115bc7Smrj }
563ae115bc7Smrj 
564843e1988Sjohnlev /*ARGSUSED*/
565ae115bc7Smrj void
plat_tem_get_prom_pos(uint32_t * row,uint32_t * col)566ae115bc7Smrj plat_tem_get_prom_pos(uint32_t *row, uint32_t *col)
567ae115bc7Smrj {
568843e1988Sjohnlev 	panic("unimplemented at line %d of %s", __LINE__, __FILE__);
569ae115bc7Smrj }
570