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

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/i86pc/boot/boot_console.c
          +++ new/usr/src/uts/i86pc/boot/boot_console.c
↓ open down ↓ 12 lines elided ↑ open up ↑
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright (c) 2012 Gary Mills
       23 + * Copyright 2020 Joyent, Inc.
  23   24   *
  24   25   * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  25   26   * Use is subject to license terms.
  26   27   */
  27   28  
       29 +/*
       30 + * Boot console support.  Most of the file is shared between dboot, and the
       31 + * early kernel / fakebop.
       32 + */
       33 +
  28   34  #include <sys/types.h>
  29   35  #include <sys/systm.h>
  30   36  #include <sys/archsystm.h>
  31   37  #include <sys/framebuffer.h>
  32   38  #include <sys/boot_console.h>
  33   39  #include <sys/panic.h>
  34   40  #include <sys/ctype.h>
  35   41  #include <sys/ascii.h>
  36   42  #include <sys/vgareg.h>
  37   43  #if defined(__xpv)
↓ open down ↓ 56 lines elided ↑ open up ↑
  94  100          int btem_params[BTEM_MAXPARAMS];
  95  101  } btem_state_t;
  96  102  
  97  103  static btem_state_t boot_tem;
  98  104  
  99  105  static int serial_ischar(void);
 100  106  static int serial_getchar(void);
 101  107  static void serial_putchar(int);
 102  108  static void serial_adjust_prop(void);
 103  109  
      110 +static void defcons_putchar(int);
      111 +
 104  112  #if !defined(_BOOT)
 105      -/* Set if the console or mode are expressed in the boot line */
 106      -static int console_set, console_mode_set;
      113 +static boolean_t bootprop_set_tty_mode;
 107  114  #endif
 108  115  
 109  116  #if defined(__xpv)
 110  117  static int console_hypervisor_redirect = B_FALSE;
 111  118  static int console_hypervisor_device = CONS_INVALID;
 112  119  static int console_hypervisor_tty_num = 0;
 113  120  
 114  121  /* Obtain the hypervisor console type */
 115  122  int
 116  123  console_hypervisor_dev_type(int *tnum)
↓ open down ↓ 286 lines elided ↑ open up ↑
 403  410          char propname[20];
 404  411          const char *propval;
 405  412          const char *p;
 406  413          ulong_t baud;
 407  414          uchar_t lcr = 0;
 408  415          uchar_t mcr = DTR | RTS;
 409  416  
 410  417          (void) strcpy(propname, "ttyX-mode");
 411  418          propname[3] = 'a' + tty_num;
 412  419          propval = get_mode_value(propname);
 413      -        if (propval == NULL)
 414      -                propval = "9600,8,n,1,-";
 415  420  #if !defined(_BOOT)
 416      -        else
 417      -                console_mode_set = 1;
      421 +        if (propval != NULL)
      422 +                bootprop_set_tty_mode = B_TRUE;
 418  423  #endif
      424 +        if (propval == NULL)
      425 +                propval = "9600,8,n,1,-";
 419  426  
 420  427          /* property is of the form: "9600,8,n,1,-" */
 421  428          p = propval;
 422  429          if (MATCHES(p, "110,"))
 423  430                  baud = ASY110;
 424  431          else if (MATCHES(p, "150,"))
 425  432                  baud = ASY150;
 426  433          else if (MATCHES(p, "300,"))
 427  434                  baud = ASY300;
 428  435          else if (MATCHES(p, "600,"))
↓ open down ↓ 244 lines elided ↑ open up ↑
 673  680          propval = find_boot_prop("tem.cursor.col");
 674  681          if (propval != NULL) {
 675  682                  intval = atoi(propval);
 676  683                  if (intval >= 0 && intval <= 0xFFFF)
 677  684                          fb_info.cursor.pos.x = intval;
 678  685          }
 679  686  #endif
 680  687  }
 681  688  
 682  689  /*
 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.
      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.
 686  692   *
 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.
      693 + * For convenience, we provide the caller with an integer index for the CONS_TTY
      694 + * case.
 689  695   */
 690  696  static int
 691      -lookup_console_devices(const char *cons_str)
      697 +lookup_console_device(const char *cons_str, int *indexp)
 692  698  {
 693  699          int n, cons;
 694  700          size_t len, cons_len;
 695  701          console_value_t *consolep;
 696  702  
 697  703          cons = CONS_INVALID;
 698  704          if (cons_str != NULL) {
 699  705  
 700  706                  cons_len = strlen(cons_str);
 701  707                  for (n = 0; console_devices[n].name != NULL; n++) {
 702  708                          consolep = &console_devices[n];
 703  709                          len = strlen(consolep->name);
 704  710                          if ((len <= cons_len) && ((cons_str[len] == '\0') ||
 705  711                              (cons_str[len] == ',') || (cons_str[len] == '\'') ||
 706  712                              (cons_str[len] == '"') || ISSPACE(cons_str[len])) &&
 707  713                              (strncmp(cons_str, consolep->name, len) == 0)) {
 708  714                                  cons = consolep->value;
 709  715                                  if (cons == CONS_TTY)
 710      -                                        tty_num = n;
      716 +                                        *indexp = n;
 711  717                                  break;
 712  718                          }
 713  719                  }
 714  720          }
 715  721          return (cons);
 716  722  }
 717  723  
 718  724  void
 719  725  bcons_init(struct xboot_info *xbi)
 720  726  {
↓ open down ↓ 20 lines elided ↑ open up ↑
 741  747  
 742  748  #if defined(__xpv)
 743  749          bcons_init_xen(boot_line);
 744  750  #endif /* __xpv */
 745  751  
 746  752          /*
 747  753           * First check for diag-device.
 748  754           */
 749  755          cons_str = find_boot_prop("diag-device");
 750  756          if (cons_str != NULL)
 751      -                diag = lookup_console_devices(cons_str);
      757 +                diag = lookup_console_device(cons_str, &tty_num);
 752  758  
 753  759          cons_str = find_boot_prop("console");
 754  760          if (cons_str == NULL)
 755  761                  cons_str = find_boot_prop("output-device");
 756  762  
 757  763  #if !defined(_BOOT)
 758  764          if (post_fastreboot && strcmp(cons_str, "graphics") == 0)
 759  765                  cons_str = console_text;
 760  766  #endif
 761  767  
 762  768          if (cons_str != NULL)
 763      -                console = lookup_console_devices(cons_str);
      769 +                console = lookup_console_device(cons_str, &tty_num);
 764  770  
 765  771  #if defined(__xpv)
 766  772          /*
 767  773           * domU's always use the hypervisor regardless of what
 768  774           * the console variable may be set to.
 769  775           */
 770  776          if (!DOMAIN_IS_INITDOMAIN(xen_info)) {
 771  777                  console = CONS_HYPERVISOR;
 772  778                  console_hypervisor_redirect = B_TRUE;
 773  779          }
 774  780  #endif /* __xpv */
 775  781  
 776      -        /*
 777      -         * If no console device specified, default to text.
 778      -         * Remember what was specified for second phase.
 779      -         */
 780  782          if (console == CONS_INVALID)
 781  783                  console = CONS_SCREEN_TEXT;
 782      -#if !defined(_BOOT)
 783      -        else
 784      -                console_set = 1;
 785      -#endif
 786  784  
 787  785  #if defined(__xpv)
 788  786          if (DOMAIN_IS_INITDOMAIN(xen_info)) {
 789  787                  switch (HYPERVISOR_console_io(CONSOLEIO_get_device, 0, NULL)) {
 790  788                          case XEN_CONSOLE_COM1:
 791  789                          case XEN_CONSOLE_COM2:
 792  790                                  console_hypervisor_device = CONS_TTY;
 793  791                                  console_hypervisor_tty_num = tty_num;
 794  792                                  break;
 795  793                          case XEN_CONSOLE_VGA:
↓ open down ↓ 64 lines elided ↑ open up ↑
 860  858          case CONS_SCREEN_TEXT:
 861  859                  if (console != CONS_SCREEN_GRAPHICS &&
 862  860                      console != CONS_SCREEN_TEXT)
 863  861                          kb_init();
 864  862                  break;
 865  863          default:
 866  864                  break;
 867  865          }
 868  866  }
 869  867  
 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  868  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  869  serial_putchar(int c)
 996  870  {
 997  871          int checks = 10000;
 998  872  
 999  873          while (((inb(port + LSR) & XHRE) == 0) && checks--)
1000  874                  ;
1001  875          outb(port + DAT, (char)c);
1002  876  }
1003  877  
1004  878  static int
↓ open down ↓ 261 lines elided ↑ open up ↑
1266 1140                          if (serial_ischar())
1267 1141                                  return (serial_getchar());
1268 1142                  }
1269 1143                  if (console != CONS_INVALID || diag != CONS_INVALID) {
1270 1144                          if (kb_ischar())
1271 1145                                  return (kb_getchar());
1272 1146                  }
1273 1147          }
1274 1148  }
1275 1149  
     1150 +/*
     1151 + * Nothing below is used by dboot.
     1152 + */
1276 1153  #if !defined(_BOOT)
1277 1154  
1278 1155  int
1279 1156  bcons_ischar(void)
1280 1157  {
1281 1158          int c = 0;
1282 1159  
1283 1160  #if defined(__xpv)
1284 1161          if (!DOMAIN_IS_INITDOMAIN(xen_info) ||
1285 1162              console == CONS_HYPERVISOR)
↓ open down ↓ 22 lines elided ↑ open up ↑
1308 1185          case CONS_INVALID:
1309 1186                  break;
1310 1187  
1311 1188          default:
1312 1189                  c = kb_ischar();
1313 1190          }
1314 1191  
1315 1192          return (c);
1316 1193  }
1317 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 +
1318 1297  #endif /* _BOOT */
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX