3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2012 Gary Mills
23 *
24 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
26 */
27
28 #include <sys/types.h>
29 #include <sys/systm.h>
30 #include <sys/archsystm.h>
31 #include <sys/framebuffer.h>
32 #include <sys/boot_console.h>
33 #include <sys/panic.h>
34 #include <sys/ctype.h>
35 #include <sys/ascii.h>
36 #include <sys/vgareg.h>
37 #if defined(__xpv)
38 #include <sys/hypervisor.h>
39 #endif /* __xpv */
40
41 #include "boot_console_impl.h"
42 #include "boot_serial.h"
43
44 #if defined(_BOOT)
45 #include <dboot/dboot_asm.h>
46 #include <dboot/dboot_xboot.h>
47 #else /* _BOOT */
84 A_STATE_CSI_QMARK,
85 A_STATE_CSI_EQUAL
86 } btem_state_type_t;
87
88 #define BTEM_MAXPARAMS 5
89 typedef struct btem_state {
90 btem_state_type_t btem_state;
91 boolean_t btem_gotparam;
92 int btem_curparam;
93 int btem_paramval;
94 int btem_params[BTEM_MAXPARAMS];
95 } btem_state_t;
96
97 static btem_state_t boot_tem;
98
99 static int serial_ischar(void);
100 static int serial_getchar(void);
101 static void serial_putchar(int);
102 static void serial_adjust_prop(void);
103
104 #if !defined(_BOOT)
105 /* Set if the console or mode are expressed in the boot line */
106 static int console_set, console_mode_set;
107 #endif
108
109 #if defined(__xpv)
110 static int console_hypervisor_redirect = B_FALSE;
111 static int console_hypervisor_device = CONS_INVALID;
112 static int console_hypervisor_tty_num = 0;
113
114 /* Obtain the hypervisor console type */
115 int
116 console_hypervisor_dev_type(int *tnum)
117 {
118 if (tnum != NULL)
119 *tnum = console_hypervisor_tty_num;
120 return (console_hypervisor_device);
121 }
122 #endif /* __xpv */
123
124 static int port;
125
126 static void
393 #endif
394 }
395
396 /*
397 * adjust serial port based on properties
398 * These come either from the cmdline or from boot properties.
399 */
400 static void
401 serial_adjust_prop(void)
402 {
403 char propname[20];
404 const char *propval;
405 const char *p;
406 ulong_t baud;
407 uchar_t lcr = 0;
408 uchar_t mcr = DTR | RTS;
409
410 (void) strcpy(propname, "ttyX-mode");
411 propname[3] = 'a' + tty_num;
412 propval = get_mode_value(propname);
413 if (propval == NULL)
414 propval = "9600,8,n,1,-";
415 #if !defined(_BOOT)
416 else
417 console_mode_set = 1;
418 #endif
419
420 /* property is of the form: "9600,8,n,1,-" */
421 p = propval;
422 if (MATCHES(p, "110,"))
423 baud = ASY110;
424 else if (MATCHES(p, "150,"))
425 baud = ASY150;
426 else if (MATCHES(p, "300,"))
427 baud = ASY300;
428 else if (MATCHES(p, "600,"))
429 baud = ASY600;
430 else if (MATCHES(p, "1200,"))
431 baud = ASY1200;
432 else if (MATCHES(p, "2400,"))
433 baud = ASY2400;
434 else if (MATCHES(p, "4800,"))
435 baud = ASY4800;
436 else if (MATCHES(p, "19200,"))
437 baud = ASY19200;
438 else if (MATCHES(p, "38400,"))
663 * Load cursor position from bootloader only in dboot,
664 * dboot will pass cursor position to kernel via xboot info.
665 */
666 propval = find_boot_prop("tem.cursor.row");
667 if (propval != NULL) {
668 intval = atoi(propval);
669 if (intval >= 0 && intval <= 0xFFFF)
670 fb_info.cursor.pos.y = intval;
671 }
672
673 propval = find_boot_prop("tem.cursor.col");
674 if (propval != NULL) {
675 intval = atoi(propval);
676 if (intval >= 0 && intval <= 0xFFFF)
677 fb_info.cursor.pos.x = intval;
678 }
679 #endif
680 }
681
682 /*
683 * Go through the console_devices array trying to match the string
684 * we were given. The string on the command line must end with
685 * a comma or white space.
686 *
687 * This function does set tty_num as an side effect, this does imply that
688 * only one of the main console and the diag-device can be using serial.
689 */
690 static int
691 lookup_console_devices(const char *cons_str)
692 {
693 int n, cons;
694 size_t len, cons_len;
695 console_value_t *consolep;
696
697 cons = CONS_INVALID;
698 if (cons_str != NULL) {
699
700 cons_len = strlen(cons_str);
701 for (n = 0; console_devices[n].name != NULL; n++) {
702 consolep = &console_devices[n];
703 len = strlen(consolep->name);
704 if ((len <= cons_len) && ((cons_str[len] == '\0') ||
705 (cons_str[len] == ',') || (cons_str[len] == '\'') ||
706 (cons_str[len] == '"') || ISSPACE(cons_str[len])) &&
707 (strncmp(cons_str, consolep->name, len) == 0)) {
708 cons = consolep->value;
709 if (cons == CONS_TTY)
710 tty_num = n;
711 break;
712 }
713 }
714 }
715 return (cons);
716 }
717
718 void
719 bcons_init(struct xboot_info *xbi)
720 {
721 const char *cons_str;
722 #if !defined(_BOOT)
723 static char console_text[] = "text";
724 extern int post_fastreboot;
725 #endif
726
727 if (xbi == NULL) {
728 /* This is very early dboot console, set up ttya. */
729 console = CONS_TTY;
730 serial_init();
731 return;
732 }
733
734 /* Set up data to fetch properties from commad line and boot env. */
735 boot_line = (char *)(uintptr_t)xbi->bi_cmdline;
736 bcons_init_env(xbi);
737 console = CONS_INVALID;
738
739 /* set up initial fb_info */
740 bcons_init_fb();
741
742 #if defined(__xpv)
743 bcons_init_xen(boot_line);
744 #endif /* __xpv */
745
746 /*
747 * First check for diag-device.
748 */
749 cons_str = find_boot_prop("diag-device");
750 if (cons_str != NULL)
751 diag = lookup_console_devices(cons_str);
752
753 cons_str = find_boot_prop("console");
754 if (cons_str == NULL)
755 cons_str = find_boot_prop("output-device");
756
757 #if !defined(_BOOT)
758 if (post_fastreboot && strcmp(cons_str, "graphics") == 0)
759 cons_str = console_text;
760 #endif
761
762 if (cons_str != NULL)
763 console = lookup_console_devices(cons_str);
764
765 #if defined(__xpv)
766 /*
767 * domU's always use the hypervisor regardless of what
768 * the console variable may be set to.
769 */
770 if (!DOMAIN_IS_INITDOMAIN(xen_info)) {
771 console = CONS_HYPERVISOR;
772 console_hypervisor_redirect = B_TRUE;
773 }
774 #endif /* __xpv */
775
776 /*
777 * If no console device specified, default to text.
778 * Remember what was specified for second phase.
779 */
780 if (console == CONS_INVALID)
781 console = CONS_SCREEN_TEXT;
782 #if !defined(_BOOT)
783 else
784 console_set = 1;
785 #endif
786
787 #if defined(__xpv)
788 if (DOMAIN_IS_INITDOMAIN(xen_info)) {
789 switch (HYPERVISOR_console_io(CONSOLEIO_get_device, 0, NULL)) {
790 case XEN_CONSOLE_COM1:
791 case XEN_CONSOLE_COM2:
792 console_hypervisor_device = CONS_TTY;
793 console_hypervisor_tty_num = tty_num;
794 break;
795 case XEN_CONSOLE_VGA:
796 /*
797 * Currently xen doesn't really support
798 * keyboard/display console devices.
799 * What this setting means is that
800 * "vga=keep" has been enabled, which is
801 * more of a xen debugging tool that a
802 * true console mode. Hence, we're going
803 * to ignore this xen "console" setting.
804 */
805 /*FALLTHROUGH*/
850
851 /*
852 * Initialize diag device unless already done.
853 */
854 switch (diag) {
855 case CONS_TTY:
856 if (console != CONS_TTY)
857 serial_init();
858 break;
859 case CONS_SCREEN_GRAPHICS:
860 case CONS_SCREEN_TEXT:
861 if (console != CONS_SCREEN_GRAPHICS &&
862 console != CONS_SCREEN_TEXT)
863 kb_init();
864 break;
865 default:
866 break;
867 }
868 }
869
870 #if !defined(_BOOT)
871 /*
872 * 2nd part of console initialization.
873 * In the kernel (ie. fakebop), this can be used only to switch to
874 * using a serial port instead of screen based on the contents
875 * of the bootenv.rc file.
876 */
877 /*ARGSUSED*/
878 void
879 bcons_init2(char *inputdev, char *outputdev, char *consoledev)
880 {
881 int cons = CONS_INVALID;
882 int ttyn;
883 char *devnames[] = { consoledev, outputdev, inputdev, NULL };
884 console_value_t *consolep;
885 int i;
886 extern int post_fastreboot;
887
888 if (post_fastreboot && console == CONS_SCREEN_GRAPHICS)
889 console = CONS_SCREEN_TEXT;
890
891 if (console != CONS_USBSER && console != CONS_SCREEN_GRAPHICS) {
892 if (console_set) {
893 /*
894 * If the console was set on the command line,
895 * but the ttyX-mode was not, we only need to
896 * check bootenv.rc for that setting.
897 */
898 if ((!console_mode_set) && (console == CONS_TTY))
899 serial_init();
900 return;
901 }
902
903 for (i = 0; devnames[i] != NULL; i++) {
904 int n;
905
906 for (n = 0; console_devices[n].name != NULL; n++) {
907 consolep = &console_devices[n];
908 if (strcmp(devnames[i], consolep->name) == 0) {
909 cons = consolep->value;
910 if (cons == CONS_TTY)
911 ttyn = n;
912 }
913 }
914 if (cons != CONS_INVALID)
915 break;
916 }
917
918 #if defined(__xpv)
919 /*
920 * if the hypervisor is using the currently selected console
921 * device then default to using the hypervisor as the console
922 * device.
923 */
924 if (cons == console_hypervisor_device) {
925 cons = CONS_HYPERVISOR;
926 console_hypervisor_redirect = B_TRUE;
927 }
928 #endif /* __xpv */
929
930 if ((cons == CONS_INVALID) || (cons == console)) {
931 /*
932 * we're sticking with whatever the current setting is
933 */
934 return;
935 }
936
937 console = cons;
938 if (cons == CONS_TTY) {
939 tty_num = ttyn;
940 serial_init();
941 return;
942 }
943 } else {
944 /*
945 * USB serial and GRAPHICS console
946 * we just collect data into a buffer
947 */
948 extern void *defcons_init(size_t);
949 defcons_buf = defcons_cur = defcons_init(MMU_PAGESIZE);
950 }
951 }
952
953 #if defined(__xpv)
954 boolean_t
955 bcons_hypervisor_redirect(void)
956 {
957 return (console_hypervisor_redirect);
958 }
959
960 void
961 bcons_device_change(int new_console)
962 {
963 if (new_console < CONS_MIN || new_console > CONS_MAX)
964 return;
965
966 /*
967 * If we are asked to switch the console to the hypervisor, that
968 * really means to switch the console to whichever device the
969 * hypervisor is/was using.
970 */
971 if (new_console == CONS_HYPERVISOR)
972 new_console = console_hypervisor_device;
973
974 console = new_console;
975
976 if (new_console == CONS_TTY) {
977 tty_num = console_hypervisor_tty_num;
978 serial_init();
979 }
980 }
981 #endif /* __xpv */
982
983 static void
984 defcons_putchar(int c)
985 {
986 if (defcons_buf != NULL &&
987 defcons_cur + 1 - defcons_buf < MMU_PAGESIZE) {
988 *defcons_cur++ = c;
989 *defcons_cur = 0;
990 }
991 }
992 #endif /* _BOOT */
993
994 static void
995 serial_putchar(int c)
996 {
997 int checks = 10000;
998
999 while (((inb(port + LSR) & XHRE) == 0) && checks--)
1000 ;
1001 outb(port + DAT, (char)c);
1002 }
1003
1004 static int
1005 serial_getchar(void)
1006 {
1007 uchar_t lsr;
1008
1009 while (serial_ischar() == 0)
1010 ;
1011
1012 lsr = inb(port + LSR);
1013 if (lsr & (SERIAL_BREAK | SERIAL_FRAME |
1014 SERIAL_PARITY | SERIAL_OVERRUN)) {
1256 bcons_getchar(void)
1257 {
1258 #if defined(__xpv)
1259 if (!DOMAIN_IS_INITDOMAIN(xen_info) ||
1260 console == CONS_HYPERVISOR)
1261 return (bcons_getchar_xen());
1262 #endif /* __xpv */
1263
1264 for (;;) {
1265 if (console == CONS_TTY || diag == CONS_TTY) {
1266 if (serial_ischar())
1267 return (serial_getchar());
1268 }
1269 if (console != CONS_INVALID || diag != CONS_INVALID) {
1270 if (kb_ischar())
1271 return (kb_getchar());
1272 }
1273 }
1274 }
1275
1276 #if !defined(_BOOT)
1277
1278 int
1279 bcons_ischar(void)
1280 {
1281 int c = 0;
1282
1283 #if defined(__xpv)
1284 if (!DOMAIN_IS_INITDOMAIN(xen_info) ||
1285 console == CONS_HYPERVISOR)
1286 return (bcons_ischar_xen());
1287 #endif /* __xpv */
1288
1289 switch (console) {
1290 case CONS_TTY:
1291 c = serial_ischar();
1292 break;
1293
1294 case CONS_INVALID:
1295 break;
1298 c = kb_ischar();
1299 }
1300 if (c != 0)
1301 return (c);
1302
1303 switch (diag) {
1304 case CONS_TTY:
1305 c = serial_ischar();
1306 break;
1307
1308 case CONS_INVALID:
1309 break;
1310
1311 default:
1312 c = kb_ischar();
1313 }
1314
1315 return (c);
1316 }
1317
1318 #endif /* _BOOT */
|
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2012 Gary Mills
23 * Copyright 2020 Joyent, Inc.
24 *
25 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
26 * Use is subject to license terms.
27 */
28
29 /*
30 * Boot console support. Most of the file is shared between dboot, and the
31 * early kernel / fakebop.
32 */
33
34 #include <sys/types.h>
35 #include <sys/systm.h>
36 #include <sys/archsystm.h>
37 #include <sys/framebuffer.h>
38 #include <sys/boot_console.h>
39 #include <sys/panic.h>
40 #include <sys/ctype.h>
41 #include <sys/ascii.h>
42 #include <sys/vgareg.h>
43 #if defined(__xpv)
44 #include <sys/hypervisor.h>
45 #endif /* __xpv */
46
47 #include "boot_console_impl.h"
48 #include "boot_serial.h"
49
50 #if defined(_BOOT)
51 #include <dboot/dboot_asm.h>
52 #include <dboot/dboot_xboot.h>
53 #else /* _BOOT */
90 A_STATE_CSI_QMARK,
91 A_STATE_CSI_EQUAL
92 } btem_state_type_t;
93
94 #define BTEM_MAXPARAMS 5
95 typedef struct btem_state {
96 btem_state_type_t btem_state;
97 boolean_t btem_gotparam;
98 int btem_curparam;
99 int btem_paramval;
100 int btem_params[BTEM_MAXPARAMS];
101 } btem_state_t;
102
103 static btem_state_t boot_tem;
104
105 static int serial_ischar(void);
106 static int serial_getchar(void);
107 static void serial_putchar(int);
108 static void serial_adjust_prop(void);
109
110 static void defcons_putchar(int);
111
112 #if !defined(_BOOT)
113 static boolean_t bootprop_set_tty_mode;
114 #endif
115
116 #if defined(__xpv)
117 static int console_hypervisor_redirect = B_FALSE;
118 static int console_hypervisor_device = CONS_INVALID;
119 static int console_hypervisor_tty_num = 0;
120
121 /* Obtain the hypervisor console type */
122 int
123 console_hypervisor_dev_type(int *tnum)
124 {
125 if (tnum != NULL)
126 *tnum = console_hypervisor_tty_num;
127 return (console_hypervisor_device);
128 }
129 #endif /* __xpv */
130
131 static int port;
132
133 static void
400 #endif
401 }
402
403 /*
404 * adjust serial port based on properties
405 * These come either from the cmdline or from boot properties.
406 */
407 static void
408 serial_adjust_prop(void)
409 {
410 char propname[20];
411 const char *propval;
412 const char *p;
413 ulong_t baud;
414 uchar_t lcr = 0;
415 uchar_t mcr = DTR | RTS;
416
417 (void) strcpy(propname, "ttyX-mode");
418 propname[3] = 'a' + tty_num;
419 propval = get_mode_value(propname);
420 #if !defined(_BOOT)
421 if (propval != NULL)
422 bootprop_set_tty_mode = B_TRUE;
423 #endif
424 if (propval == NULL)
425 propval = "9600,8,n,1,-";
426
427 /* property is of the form: "9600,8,n,1,-" */
428 p = propval;
429 if (MATCHES(p, "110,"))
430 baud = ASY110;
431 else if (MATCHES(p, "150,"))
432 baud = ASY150;
433 else if (MATCHES(p, "300,"))
434 baud = ASY300;
435 else if (MATCHES(p, "600,"))
436 baud = ASY600;
437 else if (MATCHES(p, "1200,"))
438 baud = ASY1200;
439 else if (MATCHES(p, "2400,"))
440 baud = ASY2400;
441 else if (MATCHES(p, "4800,"))
442 baud = ASY4800;
443 else if (MATCHES(p, "19200,"))
444 baud = ASY19200;
445 else if (MATCHES(p, "38400,"))
670 * Load cursor position from bootloader only in dboot,
671 * dboot will pass cursor position to kernel via xboot info.
672 */
673 propval = find_boot_prop("tem.cursor.row");
674 if (propval != NULL) {
675 intval = atoi(propval);
676 if (intval >= 0 && intval <= 0xFFFF)
677 fb_info.cursor.pos.y = intval;
678 }
679
680 propval = find_boot_prop("tem.cursor.col");
681 if (propval != NULL) {
682 intval = atoi(propval);
683 if (intval >= 0 && intval <= 0xFFFF)
684 fb_info.cursor.pos.x = intval;
685 }
686 #endif
687 }
688
689 /*
690 * Go through the known console device names trying to match the string we were
691 * given. The string on the command line must end with a comma or white space.
692 *
693 * For convenience, we provide the caller with an integer index for the CONS_TTY
694 * case.
695 */
696 static int
697 lookup_console_device(const char *cons_str, int *indexp)
698 {
699 int n, cons;
700 size_t len, cons_len;
701 console_value_t *consolep;
702
703 cons = CONS_INVALID;
704 if (cons_str != NULL) {
705
706 cons_len = strlen(cons_str);
707 for (n = 0; console_devices[n].name != NULL; n++) {
708 consolep = &console_devices[n];
709 len = strlen(consolep->name);
710 if ((len <= cons_len) && ((cons_str[len] == '\0') ||
711 (cons_str[len] == ',') || (cons_str[len] == '\'') ||
712 (cons_str[len] == '"') || ISSPACE(cons_str[len])) &&
713 (strncmp(cons_str, consolep->name, len) == 0)) {
714 cons = consolep->value;
715 if (cons == CONS_TTY)
716 *indexp = n;
717 break;
718 }
719 }
720 }
721 return (cons);
722 }
723
724 void
725 bcons_init(struct xboot_info *xbi)
726 {
727 const char *cons_str;
728 #if !defined(_BOOT)
729 static char console_text[] = "text";
730 extern int post_fastreboot;
731 #endif
732
733 if (xbi == NULL) {
734 /* This is very early dboot console, set up ttya. */
735 console = CONS_TTY;
736 serial_init();
737 return;
738 }
739
740 /* Set up data to fetch properties from commad line and boot env. */
741 boot_line = (char *)(uintptr_t)xbi->bi_cmdline;
742 bcons_init_env(xbi);
743 console = CONS_INVALID;
744
745 /* set up initial fb_info */
746 bcons_init_fb();
747
748 #if defined(__xpv)
749 bcons_init_xen(boot_line);
750 #endif /* __xpv */
751
752 /*
753 * First check for diag-device.
754 */
755 cons_str = find_boot_prop("diag-device");
756 if (cons_str != NULL)
757 diag = lookup_console_device(cons_str, &tty_num);
758
759 cons_str = find_boot_prop("console");
760 if (cons_str == NULL)
761 cons_str = find_boot_prop("output-device");
762
763 #if !defined(_BOOT)
764 if (post_fastreboot && strcmp(cons_str, "graphics") == 0)
765 cons_str = console_text;
766 #endif
767
768 if (cons_str != NULL)
769 console = lookup_console_device(cons_str, &tty_num);
770
771 #if defined(__xpv)
772 /*
773 * domU's always use the hypervisor regardless of what
774 * the console variable may be set to.
775 */
776 if (!DOMAIN_IS_INITDOMAIN(xen_info)) {
777 console = CONS_HYPERVISOR;
778 console_hypervisor_redirect = B_TRUE;
779 }
780 #endif /* __xpv */
781
782 if (console == CONS_INVALID)
783 console = CONS_SCREEN_TEXT;
784
785 #if defined(__xpv)
786 if (DOMAIN_IS_INITDOMAIN(xen_info)) {
787 switch (HYPERVISOR_console_io(CONSOLEIO_get_device, 0, NULL)) {
788 case XEN_CONSOLE_COM1:
789 case XEN_CONSOLE_COM2:
790 console_hypervisor_device = CONS_TTY;
791 console_hypervisor_tty_num = tty_num;
792 break;
793 case XEN_CONSOLE_VGA:
794 /*
795 * Currently xen doesn't really support
796 * keyboard/display console devices.
797 * What this setting means is that
798 * "vga=keep" has been enabled, which is
799 * more of a xen debugging tool that a
800 * true console mode. Hence, we're going
801 * to ignore this xen "console" setting.
802 */
803 /*FALLTHROUGH*/
848
849 /*
850 * Initialize diag device unless already done.
851 */
852 switch (diag) {
853 case CONS_TTY:
854 if (console != CONS_TTY)
855 serial_init();
856 break;
857 case CONS_SCREEN_GRAPHICS:
858 case CONS_SCREEN_TEXT:
859 if (console != CONS_SCREEN_GRAPHICS &&
860 console != CONS_SCREEN_TEXT)
861 kb_init();
862 break;
863 default:
864 break;
865 }
866 }
867
868 static void
869 serial_putchar(int c)
870 {
871 int checks = 10000;
872
873 while (((inb(port + LSR) & XHRE) == 0) && checks--)
874 ;
875 outb(port + DAT, (char)c);
876 }
877
878 static int
879 serial_getchar(void)
880 {
881 uchar_t lsr;
882
883 while (serial_ischar() == 0)
884 ;
885
886 lsr = inb(port + LSR);
887 if (lsr & (SERIAL_BREAK | SERIAL_FRAME |
888 SERIAL_PARITY | SERIAL_OVERRUN)) {
1130 bcons_getchar(void)
1131 {
1132 #if defined(__xpv)
1133 if (!DOMAIN_IS_INITDOMAIN(xen_info) ||
1134 console == CONS_HYPERVISOR)
1135 return (bcons_getchar_xen());
1136 #endif /* __xpv */
1137
1138 for (;;) {
1139 if (console == CONS_TTY || diag == CONS_TTY) {
1140 if (serial_ischar())
1141 return (serial_getchar());
1142 }
1143 if (console != CONS_INVALID || diag != CONS_INVALID) {
1144 if (kb_ischar())
1145 return (kb_getchar());
1146 }
1147 }
1148 }
1149
1150 /*
1151 * Nothing below is used by dboot.
1152 */
1153 #if !defined(_BOOT)
1154
1155 int
1156 bcons_ischar(void)
1157 {
1158 int c = 0;
1159
1160 #if defined(__xpv)
1161 if (!DOMAIN_IS_INITDOMAIN(xen_info) ||
1162 console == CONS_HYPERVISOR)
1163 return (bcons_ischar_xen());
1164 #endif /* __xpv */
1165
1166 switch (console) {
1167 case CONS_TTY:
1168 c = serial_ischar();
1169 break;
1170
1171 case CONS_INVALID:
1172 break;
1175 c = kb_ischar();
1176 }
1177 if (c != 0)
1178 return (c);
1179
1180 switch (diag) {
1181 case CONS_TTY:
1182 c = serial_ischar();
1183 break;
1184
1185 case CONS_INVALID:
1186 break;
1187
1188 default:
1189 c = kb_ischar();
1190 }
1191
1192 return (c);
1193 }
1194
1195 /*
1196 * 2nd part of console initialization: we've now processed bootenv.rc; update
1197 * console settings as appropriate. This only really processes serial console
1198 * modifications.
1199 */
1200 void
1201 bcons_post_bootenvrc(char *inputdev, char *outputdev, char *consoledev)
1202 {
1203 int cons = CONS_INVALID;
1204 int ttyn;
1205 char *devnames[] = { consoledev, outputdev, inputdev, NULL };
1206 console_value_t *consolep;
1207 int i;
1208 extern int post_fastreboot;
1209
1210 if (post_fastreboot && console == CONS_SCREEN_GRAPHICS)
1211 console = CONS_SCREEN_TEXT;
1212
1213 /*
1214 * USB serial and GRAPHICS console: we just collect data into a buffer.
1215 */
1216 if (console == CONS_USBSER || console == CONS_SCREEN_GRAPHICS) {
1217 extern void *defcons_init(size_t);
1218 defcons_buf = defcons_cur = defcons_init(MMU_PAGESIZE);
1219 return;
1220 }
1221
1222 for (i = 0; devnames[i] != NULL; i++) {
1223 cons = lookup_console_device(devnames[i], &ttyn);
1224 if (cons != CONS_INVALID)
1225 break;
1226 }
1227
1228 if (cons == CONS_INVALID) {
1229 /*
1230 * No console change, but let's see if bootenv.rc had a mode
1231 * setting we should apply.
1232 */
1233 if (console == CONS_TTY && !bootprop_set_tty_mode)
1234 serial_init();
1235 return;
1236 }
1237
1238 #if defined(__xpv)
1239 /*
1240 * if the hypervisor is using the currently selected console device then
1241 * default to using the hypervisor as the console device.
1242 */
1243 if (cons == console_hypervisor_device) {
1244 cons = CONS_HYPERVISOR;
1245 console_hypervisor_redirect = B_TRUE;
1246 }
1247 #endif /* __xpv */
1248
1249 console = cons;
1250
1251 if (console == CONS_TTY) {
1252 tty_num = ttyn;
1253 serial_init();
1254 }
1255 }
1256
1257 #if defined(__xpv)
1258 boolean_t
1259 bcons_hypervisor_redirect(void)
1260 {
1261 return (console_hypervisor_redirect);
1262 }
1263
1264 void
1265 bcons_device_change(int new_console)
1266 {
1267 if (new_console < CONS_MIN || new_console > CONS_MAX)
1268 return;
1269
1270 /*
1271 * If we are asked to switch the console to the hypervisor, that
1272 * really means to switch the console to whichever device the
1273 * hypervisor is/was using.
1274 */
1275 if (new_console == CONS_HYPERVISOR)
1276 new_console = console_hypervisor_device;
1277
1278 console = new_console;
1279
1280 if (new_console == CONS_TTY) {
1281 tty_num = console_hypervisor_tty_num;
1282 serial_init();
1283 }
1284 }
1285 #endif /* __xpv */
1286
1287 static void
1288 defcons_putchar(int c)
1289 {
1290 if (defcons_buf != NULL &&
1291 defcons_cur + 1 - defcons_buf < MMU_PAGESIZE) {
1292 *defcons_cur++ = c;
1293 *defcons_cur = 0;
1294 }
1295 }
1296
1297 #endif /* _BOOT */
|