changeset 13659:57451298f940

1469 ttyc/ttyd should be an allowed console device Reviewed by: Milan Jurik <milan.jurik@xylab.cz> Reviewed by: Alexander Eremin <alexander.r.eremin@gmail.com> Approved by: Richard Lowe <richlowe@richlowe.net>
author Gary Mills <gary_mills@fastmail.fm>
date Thu, 05 Apr 2012 08:47:21 -0500
parents 1e6115622470
children 1905bad7dc63
files usr/src/man/man1m/eeprom.1m usr/src/pkg/manifests/system-boot-real-mode.mf usr/src/uts/i86pc/boot/boot_console.c usr/src/uts/i86pc/dboot/dboot_printf.c usr/src/uts/i86pc/io/consplat.c usr/src/uts/i86pc/io/isa.c usr/src/uts/i86pc/os/mlsetup.c usr/src/uts/i86pc/sys/boot_console.h usr/src/uts/i86xpv/os/xpv_panic.c usr/src/uts/intel/os/bootenv.rc
diffstat 10 files changed, 217 insertions(+), 141 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/man/man1m/eeprom.1m	Fri Mar 30 20:20:55 2012 +0200
+++ b/usr/src/man/man1m/eeprom.1m	Thu Apr 05 08:47:21 2012 -0500
@@ -104,7 +104,8 @@
 .ad
 .sp .6
 .RS 4n
-Specifies the console device. Possible values are \fBttya\fR, \fBttyb\fR, and
+Specifies the console device.
+Possible values are \fBttya\fR, \fBttyb\fR, \fBttyc\fR, \fBttyd\fR, and
 \fBtext\fR. In \fBtext\fR mode, console output goes to the frame buffer and
 input comes from the keyboard. When this property is not present, the console
 device falls back to the device specified by \fBinput-device\fR and
@@ -360,8 +361,8 @@
 .ad
 .sp .6
 .RS 4n
-Input device used at power-on (usually \fBkeyboard\fR, \fBttya\fR, or
-\fBttyb\fR). Defaults to \fBkeyboard\fR.
+Input device used at power-on (usually \fBkeyboard\fR, \fBttya\fR,
+\fBttyb\fR, \fBttyc\fR, or \fBttyd\fR). Defaults to \fBkeyboard\fR.
 .RE
 
 .sp
@@ -680,8 +681,8 @@
 .ad
 .sp .6
 .RS 4n
-Output device used at power-on (usually \fBscreen\fR, \fBttya\fR, or
-\fBttyb\fR). Defaults to \fBscreen\fR.
+Output device used at power-on (usually \fBscreen\fR, \fBttya\fR,
+\fBttyb\fR, \fBttyc\fR, or \fBttyd\fR). Defaults to \fBscreen\fR.
 .RE
 
 .sp
@@ -959,11 +960,11 @@
 .sp
 .ne 2
 .na
-\fBttyb-mode\fR
+\fBtty\fIX\fR-mode\fR
 .ad
 .sp .6
 .RS 4n
-\fBTTYB\fR (baud rate, #bits, parity, #stop, handshake). Defaults to
+\fBTTYB, TTYC, or TTYD\fR (baud rate, #bits, parity, #stop, handshake). Defaults to
 \fB9600,8,n,1,\(mi\fR.
 .sp
 Fields, in left-to-right order, are:
@@ -1033,12 +1034,12 @@
 .sp
 .ne 2
 .na
-\fBttyb-ignore-cd\fR
+\fBtty\fIX\fR-ignore-cd\fR
 .ad
 .sp .6
 .RS 4n
-If \fBtrue\fR, operating system ignores carrier-detect on TTYB. Defaults to
-\fBtrue\fR.
+If \fBtrue\fR, operating system ignores carrier-detect on TTYB, TTYC, or TTYD.
+Defaults to \fBtrue\fR.
 .RE
 
 .sp
@@ -1055,12 +1056,12 @@
 .sp
 .ne 2
 .na
-\fBttyb-rts-dtr-off\fR
+\fBtty\fIX\fR-rts-dtr-off\fR
 .ad
 .sp .6
 .RS 4n
-If \fBtrue\fR, operating system does not assert DTR and RTS on TTYB. Defaults
-to \fBfalse\fR.
+If \fBtrue\fR, operating system does not assert DTR and RTS on TTYB, TTYC,
+or TTYD. Defaults to \fBfalse\fR.
 .RE
 
 .sp
--- a/usr/src/pkg/manifests/system-boot-real-mode.mf	Fri Mar 30 20:20:55 2012 +0200
+++ b/usr/src/pkg/manifests/system-boot-real-mode.mf	Thu Apr 05 08:47:21 2012 -0500
@@ -41,7 +41,7 @@
 $(i386_ONLY)dir path=usr/lib/fs group=sys
 $(i386_ONLY)dir path=usr/lib/fs/ufs group=sys
 $(i386_ONLY)file path=boot/solaris/bootenv.rc group=sys \
-    original_name=SUNWrmodr:boot/solaris/bootenv.rc preserve=true
+    original_name=SUNWrmodr:boot/solaris/bootenv.rc preserve=renamenew
 $(i386_ONLY)file path=boot/solaris/devicedb/master group=sys \
     original_name=SUNWrmod:boot/solaris/devicedb/master preserve=true
 $(i386_ONLY)file path=boot/splashimage.xpm group=sys
--- a/usr/src/uts/i86pc/boot/boot_console.c	Fri Mar 30 20:20:55 2012 +0200
+++ b/usr/src/uts/i86pc/boot/boot_console.c	Thu Apr 05 08:47:21 2012 -0500
@@ -19,6 +19,8 @@
  * CDDL HEADER END
  */
 /*
+ * Copyright (c) 2012 Gary Mills
+ *
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
@@ -56,10 +58,22 @@
 #endif /* __xpv */
 
 static int cons_color = CONS_COLOR;
-int console = CONS_SCREEN_TEXT;
+static int console = CONS_SCREEN_TEXT;
+static int tty_num = 0;
+static int tty_addr[] = {0x3f8, 0x2f8, 0x3e8, 0x2e8};
 #if defined(__xpv)
 static int console_hypervisor_redirect = B_FALSE;
-int console_hypervisor_device = CONS_INVALID;
+static int console_hypervisor_device = CONS_INVALID;
+static int console_hypervisor_tty_num = 0;
+
+/* Obtain the hypervisor console type */
+int
+console_hypervisor_dev_type(int *tnum)
+{
+	if (tnum != NULL)
+		*tnum = console_hypervisor_tty_num;
+	return (console_hypervisor_device);
+}
 #endif /* __xpv */
 
 static int serial_ischar(void);
@@ -140,14 +154,7 @@
 static void
 serial_init(void)
 {
-	switch (console) {
-	case CONS_TTYA:
-		port = 0x3f8;
-		break;
-	case CONS_TTYB:
-		port = 0x2f8;
-		break;
-	}
+	port = tty_addr[tty_num];
 
 	outb(port + ISR, 0x20);
 	if (inb(port + ISR) & 0x20) {
@@ -377,7 +384,7 @@
 	uchar_t mcr = DTR | RTS;
 
 	(void) strcpy(propname, "ttyX-mode");
-	propname[3] = 'a' + console - CONS_TTYA;
+	propname[3] = 'a' + tty_num;
 	propval = get_mode_value(propname);
 	if (propval == NULL)
 		propval = "9600,8,n,1,-";
@@ -472,7 +479,7 @@
 	outb(port + LCR, lcr);
 
 	(void) strcpy(propname, "ttyX-rts-dtr-off");
-	propname[3] = 'a' + console - CONS_TTYA;
+	propname[3] = 'a' + tty_num;
 	propval = get_mode_value(propname);
 	if (propval == NULL)
 		propval = "false";
@@ -482,6 +489,15 @@
 	outb(port + MCR, mcr | OUT2);
 }
 
+/* Obtain the console type */
+int
+boot_console_type(int *tnum)
+{
+	if (tnum != NULL)
+		*tnum = tty_num;
+	return (console);
+}
+
 /*
  * A structure to map console names to values.
  */
@@ -491,8 +507,10 @@
 } console_value_t;
 
 console_value_t console_devices[] = {
-	{ "ttya", CONS_TTYA },
-	{ "ttyb", CONS_TTYB },
+	{ "ttya", CONS_TTY },	/* 0 */
+	{ "ttyb", CONS_TTY },	/* 1 */
+	{ "ttyc", CONS_TTY },	/* 2 */
+	{ "ttyd", CONS_TTY },	/* 3 */
 	{ "text", CONS_SCREEN_TEXT },
 	{ "graphics", CONS_SCREEN_GRAPHICS },
 #if defined(__xpv)
@@ -501,7 +519,7 @@
 #if !defined(_BOOT)
 	{ "usb-serial", CONS_USBSER },
 #endif
-	{ "", CONS_INVALID }
+	{ NULL, CONS_INVALID }
 };
 
 void
@@ -537,15 +555,19 @@
 	 * a comma or white space.
 	 */
 	if (cons_str != NULL) {
+		int n;
+
 		cons_len = strlen(cons_str);
-		consolep = console_devices;
-		for (; consolep->name[0] != '\0'; consolep++) {
+		for (n = 0; console_devices[n].name != NULL; n++) {
+			consolep = &console_devices[n];
 			len = strlen(consolep->name);
 			if ((len <= cons_len) && ((cons_str[len] == '\0') ||
 			    (cons_str[len] == ',') || (cons_str[len] == '\'') ||
 			    (cons_str[len] == '"') || ISSPACE(cons_str[len])) &&
 			    (strncmp(cons_str, consolep->name, len) == 0)) {
 				console = consolep->value;
+				if (console == CONS_TTY)
+					tty_num = n;
 				break;
 			}
 		}
@@ -577,10 +599,9 @@
 	if (DOMAIN_IS_INITDOMAIN(xen_info)) {
 		switch (HYPERVISOR_console_io(CONSOLEIO_get_device, 0, NULL)) {
 			case XEN_CONSOLE_COM1:
-				console_hypervisor_device = CONS_TTYA;
-				break;
 			case XEN_CONSOLE_COM2:
-				console_hypervisor_device = CONS_TTYB;
+				console_hypervisor_device = CONS_TTY;
+				console_hypervisor_tty_num = tty_num;
 				break;
 			case XEN_CONSOLE_VGA:
 				/*
@@ -610,8 +631,7 @@
 #endif /* __xpv */
 
 	switch (console) {
-	case CONS_TTYA:
-	case CONS_TTYB:
+	case CONS_TTY:
 		serial_init();
 		break;
 
@@ -652,6 +672,7 @@
 bcons_init2(char *inputdev, char *outputdev, char *consoledev)
 {
 	int cons = CONS_INVALID;
+	int ttyn;
 	char *devnames[] = { consoledev, outputdev, inputdev, NULL };
 	console_value_t *consolep;
 	int i;
@@ -667,17 +688,20 @@
 			 * but the ttyX-mode was not, we only need to
 			 * check bootenv.rc for that setting.
 			 */
-			if ((!console_mode_set) &&
-			    (console == CONS_TTYA || console == CONS_TTYB))
+			if ((!console_mode_set) && (console == CONS_TTY))
 				serial_init();
 			return;
 		}
 
 		for (i = 0; devnames[i] != NULL; i++) {
-			consolep = console_devices;
-			for (; consolep->name[0] != '\0'; consolep++) {
+			int n;
+
+			for (n = 0; console_devices[n].name != NULL; n++) {
+				consolep = &console_devices[n];
 				if (strcmp(devnames[i], consolep->name) == 0) {
 					cons = consolep->value;
+					if (cons == CONS_TTY)
+						ttyn = n;
 				}
 			}
 			if (cons != CONS_INVALID)
@@ -704,7 +728,8 @@
 		}
 
 		console = cons;
-		if (cons == CONS_TTYA || cons == CONS_TTYB) {
+		if (cons == CONS_TTY) {
+			tty_num = ttyn;
 			serial_init();
 			return;
 		}
@@ -741,8 +766,10 @@
 
 	console = new_console;
 
-	if (new_console == CONS_TTYA || new_console == CONS_TTYB)
+	if (new_console == CONS_TTY) {
+		tty_num = console_hypervisor_tty_num;
 		serial_init();
+	}
 }
 #endif /* __xpv */
 
@@ -799,8 +826,7 @@
 _doputchar(int c)
 {
 	switch (console) {
-	case CONS_TTYA:
-	case CONS_TTYB:
+	case CONS_TTY:
 		serial_putchar(c);
 		return;
 	case CONS_SCREEN_TEXT:
@@ -862,8 +888,7 @@
 #endif /* __xpv */
 
 	switch (console) {
-	case CONS_TTYA:
-	case CONS_TTYB:
+	case CONS_TTY:
 		return (serial_getchar());
 	default:
 		return (kb_getchar());
@@ -883,8 +908,7 @@
 #endif /* __xpv */
 
 	switch (console) {
-	case CONS_TTYA:
-	case CONS_TTYB:
+	case CONS_TTY:
 		return (serial_ischar());
 	default:
 		return (kb_ischar());
--- a/usr/src/uts/i86pc/dboot/dboot_printf.c	Fri Mar 30 20:20:55 2012 +0200
+++ b/usr/src/uts/i86pc/dboot/dboot_printf.c	Thu Apr 05 08:47:21 2012 -0500
@@ -20,12 +20,12 @@
  */
 
 /*
+ * Copyright (c) 2012 Gary Mills
+ *
  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <sys/types.h>
 #include <sys/param.h>
 #include <sys/machparam.h>
@@ -59,7 +59,7 @@
 	va_start(args, fmt);
 	do_dboot_printf(fmt, args);
 
-	if (console == CONS_SCREEN_TEXT) {
+	if (boot_console_type(NULL) == CONS_SCREEN_TEXT) {
 		dboot_printf("Press any key to reboot\n");
 		(void) bcons_getchar();
 	}
--- a/usr/src/uts/i86pc/io/consplat.c	Fri Mar 30 20:20:55 2012 +0200
+++ b/usr/src/uts/i86pc/io/consplat.c	Thu Apr 05 08:47:21 2012 -0500
@@ -20,6 +20,8 @@
  */
 
 /*
+ * Copyright (c) 2012 Gary Mills
+ *
  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
@@ -62,29 +64,39 @@
 
 #define	A_CNT(arr)	(sizeof (arr) / sizeof (arr[0]))
 
-#define	CONS_INVALID	-1
-#define	CONS_SCREEN	0
-#define	CONS_TTYA	1
-#define	CONS_TTYB	2
-#define	CONS_USBSER	3
-#define	CONS_HYPERVISOR	4
+#ifndef	CONS_INVALID
+#define	CONS_INVALID		-1
+#define	CONS_SCREEN_TEXT	0
+#define	CONS_TTY		1
+#define	CONS_XXX		2	/* Unused */
+#define	CONS_USBSER		3
+#define	CONS_HYPERVISOR		4
+#define	CONS_SCREEN_GRAPHICS	5
+#endif	/* CONS_INVALID */
 
 char *plat_fbpath(void);
 
 static int
-console_type()
+console_type(int *tnum)
 {
 	static int boot_console = CONS_INVALID;
+	static int tty_num = 0;
 
 	char *cons;
 	dev_info_t *root;
 
-	if (boot_console != CONS_INVALID)
+	/* If we already have determined the console, just return it. */
+	if (boot_console != CONS_INVALID) {
+		if (tnum != NULL)
+			*tnum = tty_num;
 		return (boot_console);
+	}
 
 #if defined(__xpv)
 	if (!DOMAIN_IS_INITDOMAIN(xen_info) || bcons_hypervisor_redirect()) {
 		boot_console = CONS_HYPERVISOR;
+		if (tnum != NULL)
+			*tnum = tty_num;
 		return (boot_console);
 	}
 #endif /* __xpv */
@@ -94,7 +106,7 @@
 	 * fallback on the old "input-device" property.
 	 * If "input-device" is not defined either, also check "output-device".
 	 */
-	boot_console = CONS_SCREEN;	/* default is screen/kb */
+	boot_console = CONS_SCREEN_TEXT;	/* default is screen/kb */
 	root = ddi_root_node();
 	if ((ddi_prop_lookup_string(DDI_DEV_T_ANY, root,
 	    DDI_PROP_DONTPASS, "console", &cons) == DDI_SUCCESS) ||
@@ -102,10 +114,10 @@
 	    DDI_PROP_DONTPASS, "input-device", &cons) == DDI_SUCCESS) ||
 	    (ddi_prop_lookup_string(DDI_DEV_T_ANY, root,
 	    DDI_PROP_DONTPASS, "output-device", &cons) == DDI_SUCCESS)) {
-		if (strcmp(cons, "ttya") == 0) {
-			boot_console = CONS_TTYA;
-		} else if (strcmp(cons, "ttyb") == 0) {
-			boot_console = CONS_TTYB;
+		if (strlen(cons) == 4 && strncmp(cons, "tty", 3) == 0 &&
+		    cons[3] >= 'a' && cons[3] <= 'd') {
+			boot_console = CONS_TTY;
+			tty_num = cons[3] - 'a';
 		} else if (strcmp(cons, "usb-serial") == 0) {
 			(void) i_ddi_attach_hw_nodes("ehci");
 			(void) i_ddi_attach_hw_nodes("uhci");
@@ -129,22 +141,26 @@
 	 * could be found, fallback to "ttya" since it's likely to exist
 	 * and it matches longstanding behavior on SPARC.
 	 */
-	if (boot_console == CONS_SCREEN && plat_fbpath() == NULL)
-		boot_console = CONS_TTYA;
+	if (boot_console == CONS_SCREEN_TEXT && plat_fbpath() == NULL) {
+		boot_console = CONS_TTY;
+		tty_num = 0;
+	}
 
+	if (tnum != NULL)
+		*tnum = tty_num;
 	return (boot_console);
 }
 
 int
 plat_stdin_is_keyboard(void)
 {
-	return (console_type() == CONS_SCREEN);
+	return (console_type(NULL) == CONS_SCREEN_TEXT);
 }
 
 int
 plat_stdout_is_framebuffer(void)
 {
-	return (console_type() == CONS_SCREEN);
+	return (console_type(NULL) == CONS_SCREEN_TEXT);
 }
 
 static char *
@@ -432,7 +448,9 @@
 {
 	static char *defaultpath[] = {
 	    "/isa/asy@1,3f8:a",
-	    "/isa/asy@1,2f8:b"
+	    "/isa/asy@1,2f8:b",
+	    "/isa/asy@1,3e8:c",
+	    "/isa/asy@1,2e8:d"
 	};
 	static char path[MAXPATHLEN];
 	char *bp;
@@ -466,25 +484,24 @@
 }
 
 /*
- * Lacking support for com2 and com3, if that matters.
  * Another possible enhancement could be to use properties
  * for the port mapping rather than simply hard-code them.
  */
 char *
 plat_stdinpath(void)
 {
-	switch (console_type()) {
+	int tty_num = 0;
+
+	switch (console_type(&tty_num)) {
 #if defined(__xpv)
 	case CONS_HYPERVISOR:
 		return ("/xpvd/xencons@0");
 #endif /* __xpv */
-	case CONS_TTYA:
-		return (plat_ttypath(0));
-	case CONS_TTYB:
-		return (plat_ttypath(1));
+	case CONS_TTY:
+		return (plat_ttypath(tty_num));
 	case CONS_USBSER:
 		return (plat_usbser_path());
-	case CONS_SCREEN:
+	case CONS_SCREEN_TEXT:
 	default:
 		break;
 	};
@@ -494,18 +511,18 @@
 char *
 plat_stdoutpath(void)
 {
-	switch (console_type()) {
+	int tty_num = 0;
+
+	switch (console_type(&tty_num)) {
 #if defined(__xpv)
 	case CONS_HYPERVISOR:
 		return ("/xpvd/xencons@0");
 #endif /* __xpv */
-	case CONS_TTYA:
-		return (plat_ttypath(0));
-	case CONS_TTYB:
-		return (plat_ttypath(1));
+	case CONS_TTY:
+		return (plat_ttypath(tty_num));
 	case CONS_USBSER:
 		return (plat_usbser_path());
-	case CONS_SCREEN:
+	case CONS_SCREEN_TEXT:
 	default:
 		break;
 	};
--- a/usr/src/uts/i86pc/io/isa.c	Fri Mar 30 20:20:55 2012 +0200
+++ b/usr/src/uts/i86pc/io/isa.c	Thu Apr 05 08:47:21 2012 -0500
@@ -19,6 +19,7 @@
  * CDDL HEADER END
  */
 /*
+ * Copyright (c) 2012 Gary Mills
  * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2012 Garrett D'Amore <garrett@damore.org>.  All rights reserved.
  */
@@ -53,7 +54,7 @@
 #include <sys/hypervisor.h>
 #include <sys/evtchn_impl.h>
 
-extern int console_hypervisor_device;
+extern int console_hypervisor_dev_type(int *);
 #endif
 
 
@@ -62,12 +63,13 @@
 extern int (*psm_intr_ops)(dev_info_t *, ddi_intr_handle_impl_t *,
     psm_intr_op_t, int *);
 extern void pci_register_isa_resources(int, uint32_t, uint32_t);
-static char USED_RESOURCES[] = "used-resources";
 static void isa_enumerate(int);
 static void enumerate_BIOS_serial(dev_info_t *);
 static void adjust_prtsz(dev_info_t *isa_dip);
 static void isa_create_ranges_prop(dev_info_t *);
 
+#define	USED_RESOURCES	"used-resources"
+
 /*
  * The following typedef is used to represent an entry in the "ranges"
  * property of a pci-isa bridge device node.
@@ -89,11 +91,16 @@
 #define	USED_CELL_SIZE	2	/* 1 byte addr, 1 byte size */
 #define	ISA_ADDR_IO	1	/* IO address space */
 #define	ISA_ADDR_MEM	0	/* memory adress space */
-#define	BIOS_DATA_AREA	0x400
+
 /*
  * #define ISA_DEBUG 1
  */
 
+#define	num_BIOS_serial	4	/* number of BIOS serial ports to look at */
+#define	min_BIOS_serial	2	/* minimum number of BIOS serial ports */
+#define	COM_ISR		2	/* 16550 intr status register */
+#define	COM_SCR		7	/* 16550 scratch register */
+
 /*
  * For serial ports not enumerated by ACPI, and parallel ports with
  * illegal size. Typically, a system can have as many as 4 serial
@@ -103,6 +110,17 @@
 static struct regspec isa_extra_resource[MAX_EXTRA_RESOURCE];
 static int isa_extra_count = 0;
 
+/* Register definitions for COM1 to COM4. */
+static struct regspec asy_regs[] = {
+	{1, 0x3f8, 0x8},
+	{1, 0x2f8, 0x8},
+	{1, 0x3e8, 0x8},
+	{1, 0x2e8, 0x8}
+};
+
+/* Serial port interrupt vectors for COM1 to COM4. */
+static int asy_intrs[] = {0x4, 0x3, 0x4, 0x3};
+
 /*
  *      Local data
  */
@@ -346,7 +364,7 @@
 	uint_t nio = 0, nmem = 0, nrng = 0, n;
 	pib_ranges_t *ranges;
 
-	used = ddi_find_devinfo("used-resources", -1, 0);
+	used = ddi_find_devinfo(USED_RESOURCES, -1, 0);
 	if (used == NULL) {
 		cmn_err(CE_WARN, "Failed to find used-resources <%s>\n",
 		    ddi_get_name(dip));
@@ -439,8 +457,10 @@
 	 * BIOS data area. Parallel port on some machines comes with
 	 * illegal size.
 	 */
-	if (isa_reg_p->regspec_bustype != ISA_ADDR_IO)
-		goto out_of_range;
+	if (isa_reg_p->regspec_bustype != ISA_ADDR_IO) {
+		cmn_err(CE_WARN, "Bus type not ISA I/O\n");
+		return (DDI_ME_REGSPEC_RANGE);
+	}
 
 	for (i = 0; i < isa_extra_count; i++) {
 		struct regspec *reg_p = &isa_extra_resource[i];
@@ -461,7 +481,6 @@
 	if (i < isa_extra_count)
 		return (DDI_SUCCESS);
 
-out_of_range:
 	cmn_err(CE_WARN, "isa_apply_range: Out of range base <0x%x>, size <%d>",
 	    isa_reg_p->regspec_addr, isa_reg_p->regspec_size);
 	return (DDI_ME_REGSPEC_RANGE);
@@ -753,7 +772,11 @@
     ddi_intr_handle_impl_t *hdlp, void *result)
 {
 	struct intrspec *ispec;
+#if defined(__xpv)
+	int cons, ttyn;
 
+	cons = console_hypervisor_dev_type(&ttyn);
+#endif
 	if (pseudo_isa)
 		return (i_ddi_intr_ops(pdip, rdip, intr_op, hdlp, result));
 
@@ -827,12 +850,8 @@
 		 * console, make sure we don't try to use that interrupt as
 		 * it will cause us to panic when xen_bind_pirq() fails.
 		 */
-		if (((ispec->intrspec_vec == 4) &&
-		    (console_hypervisor_device == CONS_TTYA)) ||
-		    ((ispec->intrspec_vec == 3) &&
-		    (console_hypervisor_device == CONS_TTYB))) {
+		if (cons == CONS_TTY && ispec->intrspec_vec == asy_intrs[ttyn])
 			return (DDI_FAILURE);
-		}
 #endif
 		((ihdl_plat_t *)hdlp->ih_private)->ip_ispecp = ispec;
 		if ((*psm_intr_ops)(rdip, hdlp, PSM_INTR_OP_XLATE_VECTOR,
@@ -1148,6 +1167,17 @@
 
 }
 
+/*
+ * Return non-zero if UART device exists.
+ */
+static int
+uart_exists(ushort_t port)
+{
+	outb(port + COM_SCR, (char)0x5a);
+	outb(port + COM_ISR, (char)0x00);
+	return (inb(port + COM_SCR) == (char)0x5a);
+}
+
 static void
 isa_enumerate(int reprogram)
 {
@@ -1155,13 +1185,6 @@
 	dev_info_t *xdip;
 	dev_info_t *isa_dip = ddi_find_devinfo("isa", -1, 0);
 
-	/* hard coded isa stuff */
-	struct regspec asy_regs[] = {
-		{1, 0x3f8, 0x8},
-		{1, 0x2f8, 0x8}
-	};
-	int asy_intrs[] = {0x4, 0x3};
-
 	struct regspec i8042_regs[] = {
 		{1, 0x60, 0x1},
 		{1, 0x64, 0x1}
@@ -1169,7 +1192,11 @@
 	int i8042_intrs[] = {0x1, 0xc};
 	char *acpi_prop;
 	int acpi_enum = 1; /* ACPI is default to be on */
+#if defined(__xpv)
+	int cons, ttyn;
 
+	cons = console_hypervisor_dev_type(&ttyn);
+#endif
 	if (reprogram || !isa_dip)
 		return;
 
@@ -1205,20 +1232,27 @@
 	cmn_err(CE_NOTE, "!ACPI is off");
 
 	/* serial ports */
-	for (i = 0; i < 2; i++) {
+	for (i = 0; i < min_BIOS_serial; i++) {
+		ushort_t addr = asy_regs[i].regspec_addr;
+		if (!uart_exists(addr))
+			continue;
 #if defined(__xpv)
-		if ((i == 0 && console_hypervisor_device == CONS_TTYA) ||
-		    (i == 1 && console_hypervisor_device == CONS_TTYB)) {
+		if (cons == CONS_TTY && ttyn == i)
 			continue;
-		}
 #endif
 		ndi_devi_alloc_sleep(isa_dip, "asy",
 		    (pnode_t)DEVI_SID_NODEID, &xdip);
+		(void) ndi_prop_update_string(DDI_DEV_T_NONE, xdip,
+		    "compatible", "PNP0500");
+		/* This should be gotten from master file: */
+		(void) ndi_prop_update_string(DDI_DEV_T_NONE, xdip,
+		    "model", "Standard PC COM port");
 		(void) ndi_prop_update_int_array(DDI_DEV_T_NONE, xdip,
 		    "reg", (int *)&asy_regs[i], 3);
 		(void) ndi_prop_update_int(DDI_DEV_T_NONE, xdip,
 		    "interrupts", asy_intrs[i]);
 		(void) ndi_devi_bind_driver(xdip, 0);
+		/* Adjusting isa_extra here causes a kernel dump later. */
 	}
 
 	/* i8042 node */
@@ -1241,40 +1275,31 @@
 
 /*
  * On some machines, serial port 2 isn't listed in the ACPI table.
- * This function goes through the BIOS data area and makes sure all
+ * This function goes through the base I/O addresses and makes sure all
  * the serial ports there are in the dev_info tree.  If any are missing,
  * this function will add them.
  */
 
-static int num_BIOS_serial = 2;	/* number of BIOS serial ports to look at */
-
 static void
 enumerate_BIOS_serial(dev_info_t *isa_dip)
 {
-	ushort_t *bios_data;
 	int i;
 	dev_info_t *xdip;
 	int found;
 	int ret;
 	struct regspec *tmpregs;
 	int tmpregs_len;
-	static struct regspec tmp_asy_regs[] = {
-		{1, 0x3f8, 0x8},
-	};
-	static int default_asy_intrs[] = { 4, 3, 4, 3 };
-	static size_t size = 4;
+#if defined(__xpv)
+	int cons, ttyn;
+
+	cons = console_hypervisor_dev_type(&ttyn);
+#endif
 
 	/*
-	 * The first four 2-byte quantities of the BIOS data area contain
-	 * the base I/O addresses of the first four serial ports.
+	 * Scan the base I/O addresses of the first four serial ports.
 	 */
-	bios_data = (ushort_t *)psm_map_new((paddr_t)BIOS_DATA_AREA, size,
-	    PSM_PROT_READ);
 	for (i = 0; i < num_BIOS_serial; i++) {
-		if (bios_data[i] == 0) {
-			/* no COM[i]: port */
-			continue;
-		}
+		ushort_t addr = asy_regs[i].regspec_addr;
 
 		/* Look for it in the dev_info tree */
 		found = 0;
@@ -1294,18 +1319,21 @@
 				continue;
 			}
 
-			if (tmpregs->regspec_addr == bios_data[i])
+			if (tmpregs->regspec_addr == addr)
 				found = 1;
+
 			/*
 			 * Free the memory allocated by
 			 * ddi_prop_lookup_int_array().
 			 */
 			ddi_prop_free(tmpregs);
 
+			if (found)
+				break;
 		}
 
 		/* If not found, then add it */
-		if (!found) {
+		if (!found && uart_exists(addr)) {
 			ndi_devi_alloc_sleep(isa_dip, "asy",
 			    (pnode_t)DEVI_SID_NODEID, &xdip);
 			(void) ndi_prop_update_string(DDI_DEV_T_NONE, xdip,
@@ -1313,15 +1341,14 @@
 			/* This should be gotten from master file: */
 			(void) ndi_prop_update_string(DDI_DEV_T_NONE, xdip,
 			    "model", "Standard PC COM port");
-			tmp_asy_regs[0].regspec_addr = bios_data[i];
 			(void) ndi_prop_update_int_array(DDI_DEV_T_NONE, xdip,
-			    "reg", (int *)&tmp_asy_regs[0], 3);
+			    "reg", (int *)&asy_regs[i], 3);
 			(void) ndi_prop_update_int(DDI_DEV_T_NONE, xdip,
-			    "interrupts", default_asy_intrs[i]);
+			    "interrupts", asy_intrs[i]);
 			(void) ndi_devi_bind_driver(xdip, 0);
 
 			ASSERT(isa_extra_count < MAX_EXTRA_RESOURCE);
-			bcopy(tmp_asy_regs,
+			bcopy(&asy_regs[i],
 			    isa_extra_resource + isa_extra_count,
 			    sizeof (struct regspec));
 			isa_extra_count++;
@@ -1346,8 +1373,7 @@
 		if (strncmp(ddi_node_name(curdip), "asy", 3) != 0)
 			continue;
 
-		if ((i == 0 && console_hypervisor_device == CONS_TTYA) ||
-		    (i == 1 && console_hypervisor_device == CONS_TTYB)) {
+		if (cons == CONS_TTY && ttyn == i) {
 			ret = ndi_devi_free(curdip);
 			if (ret != DDI_SUCCESS) {
 				cmn_err(CE_WARN,
@@ -1362,7 +1388,6 @@
 	}
 #endif
 
-	psm_unmap((caddr_t)bios_data, size);
 }
 
 /*
--- a/usr/src/uts/i86pc/os/mlsetup.c	Fri Mar 30 20:20:55 2012 +0200
+++ b/usr/src/uts/i86pc/os/mlsetup.c	Thu Apr 05 08:47:21 2012 -0500
@@ -19,6 +19,8 @@
  * CDDL HEADER END
  */
 /*
+ * Copyright (c) 2012 Gary Mills
+ *
  * Copyright (c) 1993, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2011 by Delphix. All rights reserved.
  */
@@ -110,7 +112,6 @@
 	extern disp_t cpu0_disp;
 	extern char t0stack[];
 	extern int post_fastreboot;
-	extern int console;
 	extern uint64_t plat_dr_options;
 
 	ASSERT_STACK_ALIGNED();
@@ -348,7 +349,7 @@
 	 * Explicitly set console to text mode (0x3) if this is a boot
 	 * post Fast Reboot, and the console is set to CONS_SCREEN_TEXT.
 	 */
-	if (post_fastreboot && console == CONS_SCREEN_TEXT)
+	if (post_fastreboot && boot_console_type(NULL) == CONS_SCREEN_TEXT)
 		set_console_mode(0x3);
 
 	/*
--- a/usr/src/uts/i86pc/sys/boot_console.h	Fri Mar 30 20:20:55 2012 +0200
+++ b/usr/src/uts/i86pc/sys/boot_console.h	Thu Apr 05 08:47:21 2012 -0500
@@ -19,6 +19,8 @@
  * CDDL HEADER END
  */
 /*
+ * Copyright (c) 2012 Gary Mills
+ *
  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
@@ -36,8 +38,8 @@
 
 #define	CONS_INVALID		-1
 #define	CONS_SCREEN_TEXT	0
-#define	CONS_TTYA		1
-#define	CONS_TTYB		2
+#define	CONS_TTY		1
+#define	CONS_XXX		2	/* Unused */
 #define	CONS_USBSER		3
 #define	CONS_HYPERVISOR		4
 #define	CONS_SCREEN_GRAPHICS	5
@@ -51,6 +53,8 @@
 extern int kb_getchar(void);
 extern int kb_ischar(void);
 
+extern int boot_console_type(int *);
+
 extern void bcons_init(char *);
 extern void bcons_putchar(int);
 extern int bcons_getchar(void);
@@ -63,8 +67,6 @@
 extern void bcons_device_change(int);
 #endif /* !_BOOT */
 
-extern int console;
-
 #ifdef __cplusplus
 }
 #endif
--- a/usr/src/uts/i86xpv/os/xpv_panic.c	Fri Mar 30 20:20:55 2012 +0200
+++ b/usr/src/uts/i86xpv/os/xpv_panic.c	Thu Apr 05 08:47:21 2012 -0500
@@ -19,6 +19,8 @@
  * CDDL HEADER END
  */
 /*
+ * Copyright (c) 2012 Gary Mills
+ *
  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
@@ -121,7 +123,7 @@
 	struct cons_polledio *c = cons_polledio;
 
 	/* This really shouldn't happen */
-	if (console == CONS_HYPERVISOR)
+	if (boot_console_type(NULL) == CONS_HYPERVISOR)
 		return;
 
 	if (use_polledio == B_TRUE)
@@ -700,7 +702,7 @@
 	 * to stop.
 	 */
 	use_polledio = B_FALSE;
-	if (console == CONS_HYPERVISOR) {
+	if (boot_console_type(NULL) == CONS_HYPERVISOR) {
 		bcons_device_change(CONS_HYPERVISOR);
 	} else if (cons_polledio != NULL &&
 	    cons_polledio->cons_polledio_putchar != NULL)  {
--- a/usr/src/uts/intel/os/bootenv.rc	Fri Mar 30 20:20:55 2012 +0200
+++ b/usr/src/uts/intel/os/bootenv.rc	Thu Apr 05 08:47:21 2012 -0500
@@ -21,17 +21,21 @@
 #
 # CDDL HEADER END
 #
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-#
 #	bootenv.rc -- boot "environment variables"
 #
 setprop keyboard-layout Unknown
 setprop ata-dma-enabled 1
 setprop atapi-cd-dma-enabled 1
+setprop ttyd-rts-dtr-off false
+setprop ttyd-ignore-cd true
+setprop ttyc-rts-dtr-off false
+setprop ttyc-ignore-cd true
 setprop ttyb-rts-dtr-off false
 setprop ttyb-ignore-cd true
 setprop ttya-rts-dtr-off false
 setprop ttya-ignore-cd true
+setprop ttyd-mode 9600,8,n,1,-
+setprop ttyc-mode 9600,8,n,1,-
 setprop ttyb-mode 9600,8,n,1,-
 setprop ttya-mode 9600,8,n,1,-
 setprop lba-access-ok 1