Print this page
12220 loader multi-console shouldn't override bootenv.rc
@@ -18,15 +18,21 @@
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2012 Gary Mills
+ * Copyright 2020 Joyent, Inc.
*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+/*
+ * Boot console support. Most of the file is shared between dboot, and the
+ * early kernel / fakebop.
+ */
+
#include <sys/types.h>
#include <sys/systm.h>
#include <sys/archsystm.h>
#include <sys/framebuffer.h>
#include <sys/boot_console.h>
@@ -99,13 +105,14 @@
static int serial_ischar(void);
static int serial_getchar(void);
static void serial_putchar(int);
static void serial_adjust_prop(void);
+static void defcons_putchar(int);
+
#if !defined(_BOOT)
-/* Set if the console or mode are expressed in the boot line */
-static int console_set, console_mode_set;
+static boolean_t bootprop_set_tty_mode;
#endif
#if defined(__xpv)
static int console_hypervisor_redirect = B_FALSE;
static int console_hypervisor_device = CONS_INVALID;
@@ -408,16 +415,16 @@
uchar_t mcr = DTR | RTS;
(void) strcpy(propname, "ttyX-mode");
propname[3] = 'a' + tty_num;
propval = get_mode_value(propname);
- if (propval == NULL)
- propval = "9600,8,n,1,-";
#if !defined(_BOOT)
- else
- console_mode_set = 1;
+ if (propval != NULL)
+ bootprop_set_tty_mode = B_TRUE;
#endif
+ if (propval == NULL)
+ propval = "9600,8,n,1,-";
/* property is of the form: "9600,8,n,1,-" */
p = propval;
if (MATCHES(p, "110,"))
baud = ASY110;
@@ -678,19 +685,18 @@
}
#endif
}
/*
- * Go through the console_devices array trying to match the string
- * we were given. The string on the command line must end with
- * a comma or white space.
+ * Go through the known console device names trying to match the string we were
+ * given. The string on the command line must end with a comma or white space.
*
- * This function does set tty_num as an side effect, this does imply that
- * only one of the main console and the diag-device can be using serial.
+ * For convenience, we provide the caller with an integer index for the CONS_TTY
+ * case.
*/
static int
-lookup_console_devices(const char *cons_str)
+lookup_console_device(const char *cons_str, int *indexp)
{
int n, cons;
size_t len, cons_len;
console_value_t *consolep;
@@ -705,11 +711,11 @@
(cons_str[len] == ',') || (cons_str[len] == '\'') ||
(cons_str[len] == '"') || ISSPACE(cons_str[len])) &&
(strncmp(cons_str, consolep->name, len) == 0)) {
cons = consolep->value;
if (cons == CONS_TTY)
- tty_num = n;
+ *indexp = n;
break;
}
}
}
return (cons);
@@ -746,11 +752,11 @@
/*
* First check for diag-device.
*/
cons_str = find_boot_prop("diag-device");
if (cons_str != NULL)
- diag = lookup_console_devices(cons_str);
+ diag = lookup_console_device(cons_str, &tty_num);
cons_str = find_boot_prop("console");
if (cons_str == NULL)
cons_str = find_boot_prop("output-device");
@@ -758,11 +764,11 @@
if (post_fastreboot && strcmp(cons_str, "graphics") == 0)
cons_str = console_text;
#endif
if (cons_str != NULL)
- console = lookup_console_devices(cons_str);
+ console = lookup_console_device(cons_str, &tty_num);
#if defined(__xpv)
/*
* domU's always use the hypervisor regardless of what
* the console variable may be set to.
@@ -771,20 +777,12 @@
console = CONS_HYPERVISOR;
console_hypervisor_redirect = B_TRUE;
}
#endif /* __xpv */
- /*
- * If no console device specified, default to text.
- * Remember what was specified for second phase.
- */
if (console == CONS_INVALID)
console = CONS_SCREEN_TEXT;
-#if !defined(_BOOT)
- else
- console_set = 1;
-#endif
#if defined(__xpv)
if (DOMAIN_IS_INITDOMAIN(xen_info)) {
switch (HYPERVISOR_console_io(CONSOLEIO_get_device, 0, NULL)) {
case XEN_CONSOLE_COM1:
@@ -865,135 +863,11 @@
default:
break;
}
}
-#if !defined(_BOOT)
-/*
- * 2nd part of console initialization.
- * In the kernel (ie. fakebop), this can be used only to switch to
- * using a serial port instead of screen based on the contents
- * of the bootenv.rc file.
- */
-/*ARGSUSED*/
-void
-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;
- extern int post_fastreboot;
-
- if (post_fastreboot && console == CONS_SCREEN_GRAPHICS)
- console = CONS_SCREEN_TEXT;
-
- if (console != CONS_USBSER && console != CONS_SCREEN_GRAPHICS) {
- if (console_set) {
- /*
- * If the console was set on the command line,
- * but the ttyX-mode was not, we only need to
- * check bootenv.rc for that setting.
- */
- if ((!console_mode_set) && (console == CONS_TTY))
- serial_init();
- return;
- }
-
- for (i = 0; devnames[i] != NULL; i++) {
- 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)
- break;
- }
-
-#if defined(__xpv)
- /*
- * if the hypervisor is using the currently selected console
- * device then default to using the hypervisor as the console
- * device.
- */
- if (cons == console_hypervisor_device) {
- cons = CONS_HYPERVISOR;
- console_hypervisor_redirect = B_TRUE;
- }
-#endif /* __xpv */
-
- if ((cons == CONS_INVALID) || (cons == console)) {
- /*
- * we're sticking with whatever the current setting is
- */
- return;
- }
-
- console = cons;
- if (cons == CONS_TTY) {
- tty_num = ttyn;
- serial_init();
- return;
- }
- } else {
- /*
- * USB serial and GRAPHICS console
- * we just collect data into a buffer
- */
- extern void *defcons_init(size_t);
- defcons_buf = defcons_cur = defcons_init(MMU_PAGESIZE);
- }
-}
-
-#if defined(__xpv)
-boolean_t
-bcons_hypervisor_redirect(void)
-{
- return (console_hypervisor_redirect);
-}
-
-void
-bcons_device_change(int new_console)
-{
- if (new_console < CONS_MIN || new_console > CONS_MAX)
- return;
-
- /*
- * If we are asked to switch the console to the hypervisor, that
- * really means to switch the console to whichever device the
- * hypervisor is/was using.
- */
- if (new_console == CONS_HYPERVISOR)
- new_console = console_hypervisor_device;
-
- console = new_console;
-
- if (new_console == CONS_TTY) {
- tty_num = console_hypervisor_tty_num;
- serial_init();
- }
-}
-#endif /* __xpv */
-
static void
-defcons_putchar(int c)
-{
- if (defcons_buf != NULL &&
- defcons_cur + 1 - defcons_buf < MMU_PAGESIZE) {
- *defcons_cur++ = c;
- *defcons_cur = 0;
- }
-}
-#endif /* _BOOT */
-
-static void
serial_putchar(int c)
{
int checks = 10000;
while (((inb(port + LSR) & XHRE) == 0) && checks--)
@@ -1271,10 +1145,13 @@
return (kb_getchar());
}
}
}
+/*
+ * Nothing below is used by dboot.
+ */
#if !defined(_BOOT)
int
bcons_ischar(void)
{
@@ -1313,6 +1190,108 @@
}
return (c);
}
+/*
+ * 2nd part of console initialization: we've now processed bootenv.rc; update
+ * console settings as appropriate. This only really processes serial console
+ * modifications.
+ */
+void
+bcons_post_bootenvrc(char *inputdev, char *outputdev, char *consoledev)
+{
+ int cons = CONS_INVALID;
+ int ttyn;
+ char *devnames[] = { consoledev, outputdev, inputdev, NULL };
+ console_value_t *consolep;
+ int i;
+ extern int post_fastreboot;
+
+ if (post_fastreboot && console == CONS_SCREEN_GRAPHICS)
+ console = CONS_SCREEN_TEXT;
+
+ /*
+ * USB serial and GRAPHICS console: we just collect data into a buffer.
+ */
+ if (console == CONS_USBSER || console == CONS_SCREEN_GRAPHICS) {
+ extern void *defcons_init(size_t);
+ defcons_buf = defcons_cur = defcons_init(MMU_PAGESIZE);
+ return;
+ }
+
+ for (i = 0; devnames[i] != NULL; i++) {
+ cons = lookup_console_device(devnames[i], &ttyn);
+ if (cons != CONS_INVALID)
+ break;
+ }
+
+ if (cons == CONS_INVALID) {
+ /*
+ * No console change, but let's see if bootenv.rc had a mode
+ * setting we should apply.
+ */
+ if (console == CONS_TTY && !bootprop_set_tty_mode)
+ serial_init();
+ return;
+ }
+
+#if defined(__xpv)
+ /*
+ * if the hypervisor is using the currently selected console device then
+ * default to using the hypervisor as the console device.
+ */
+ if (cons == console_hypervisor_device) {
+ cons = CONS_HYPERVISOR;
+ console_hypervisor_redirect = B_TRUE;
+ }
+#endif /* __xpv */
+
+ console = cons;
+
+ if (console == CONS_TTY) {
+ tty_num = ttyn;
+ serial_init();
+ }
+}
+
+#if defined(__xpv)
+boolean_t
+bcons_hypervisor_redirect(void)
+{
+ return (console_hypervisor_redirect);
+}
+
+void
+bcons_device_change(int new_console)
+{
+ if (new_console < CONS_MIN || new_console > CONS_MAX)
+ return;
+
+ /*
+ * If we are asked to switch the console to the hypervisor, that
+ * really means to switch the console to whichever device the
+ * hypervisor is/was using.
+ */
+ if (new_console == CONS_HYPERVISOR)
+ new_console = console_hypervisor_device;
+
+ console = new_console;
+
+ if (new_console == CONS_TTY) {
+ tty_num = console_hypervisor_tty_num;
+ serial_init();
+ }
+}
+#endif /* __xpv */
+
+static void
+defcons_putchar(int c)
+{
+ if (defcons_buf != NULL &&
+ defcons_cur + 1 - defcons_buf < MMU_PAGESIZE) {
+ *defcons_cur++ = c;
+ *defcons_cur = 0;
+ }
+}
+
#endif /* _BOOT */