Print this page
12220 loader multi-console shouldn't override bootenv.rc


   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 */