Print this page
NEX-16819 loader UEFI support
Includes work by Toomas Soome <tsoome@me.com>
Upstream commits:
    loader: pxe receive cleanup
    9475 libefi: Do not return only if ReceiveFilter
    installboot: should support efi system partition
    8931 boot1.efi: scan all display modes rather than
    loader: spinconsole updates
    loader: gfx experiment to try GOP Blt() function.
    sha1 build test
    loader: add sha1 hash calculation
    common/sha1: update for loader build
    loader: biosdisk rework
    uts: 32-bit kernel FB needs mapping in low memory
    uts: add diag-device
    uts: boot console mirror with diag-device
    uts: enable very early console on ttya
    kmdb: add diag-device as input/output device
    uts: test VGA memory exclusion from mapping
    uts: clear boot mapping and protect boot pages test
    uts: add dboot map debug printf
    uts: need to release FB pages in release_bootstrap()
    uts: add screenmap ioctl
    uts: update sys/queue.h
    loader: add illumos uts/common to include path
    loader: tem/gfx font cleanup
    loader: vbe checks
    uts: gfx_private set KD_TEXT when KD_RESETTEXT is
    uts: gfx 8-bit update
    loader: gfx 8-bit fix
    loader: always set media size from partition.
    uts: MB2 support for 32-bit kernel
    loader: x86 should have tem 80x25
    uts: x86 should have tem 80x25
    uts: font update
    loader: font update
    uts: tem attributes
    loader: tem.c comment added
    uts: use font module
    loader: add font module
    loader: build rules for new font setup
    uts: gfx_private update for new font structure
    uts: early boot update for new font structure
    uts: font update
    uts: font build rules update for new fonts
    uts: tem update to new font structure
    loader: module.c needs to include tem_impl.h
    uts: gfx_private 8x16 font rework
    uts: make font_lookup public
    loader: font rework
    uts: font rework
    9259 libefi: efi_alloc_and_read should check for PMBR
    uts: tem utf-8 support
    loader: implement tem utf-8 support
    loader: tem should be able to display UTF-8
    7784 uts: console input should support utf-8
    7796 uts: ldterm default to utf-8
    uts: do not reset serial console
    uts: set up colors even if tem is not console
    uts: add type for early boot properties
    uts: gfx_private experiment with drm and vga
    uts: gfx_private should use setmode drm callback.
    uts: identify FB types and set up gfx_private based
    loader: replace gop and vesa with framebuffer
    uts: boot needs simple tem to support mdb
    uts: boot_keyboard should emit esc sequences for
    uts: gfx_private FB showuld be written by line
    kmdb: set terminal window size
    uts: gfx_private needs to keep track of early boot FB
    pnglite: move pnglite to usr/src/common
    loader: gfx_fb
    ficl-sys: add gfx primitives
    loader: add illumos.png logo
    ficl: add fb-putimage
    loader: add png support
    loader: add alpha blending for gfx_fb
    loader: use term-drawrect for menu frame
    ficl: add simple gfx words
    uts: provide fb_info via fbgattr dev_specific array.
    uts: gfx_private add alpha blending
    uts: update sys/ascii.h
    uts: tem OSC support (incomplete)
    uts: implement env module support and use data from
    uts: tem get colors from early boot data
    loader: use crc32 from libstand (libz)
    loader: optimize for size
    loader: pass tem info to the environment
    loader: import tem for loader console
    loader: UEFI loader needs to set ISADIR based on
    loader: need UEFI32 support
    8918 loader.efi: add vesa edid support
    uts: tem_safe_pix_clear_prom_output() should only
    uts: tem_safe_pix_clear_entire_screen() should use
    uts: tem_safe_check_first_time() should query cursor
    uts: tem implement cls callback & visual_io v4
    uts: gfx_vgatext use block cursor for vgatext
    uts: gfx_private implement cls callback & visual_io
    uts: gfx_private bitmap framebuffer implementation
    uts: early start frame buffer console support
    uts: font functions should check the input char
    uts: font rendering should support 16/24/32bit depths
    uts: use smallest font as fallback default.
    uts: update terminal dimensions based on selected
    7834 uts: vgatext should use gfx_private
    uts: add spacing property to 8859-1.bdf
    terminfo: add underline for sun-color
    terminfo: sun-color has 16 colors
    uts: add font load callback type
    loader: do not repeat int13 calls with error 0x20 and
    8905 loader: add skein/edonr support
    8904 common/crypto: make skein and edonr loader
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Revert "NEX-16819 loader UEFI support"
This reverts commit ec06b9fc617b99234e538bf2e7e4d02a24993e0c.
Reverting due to failures in the zfs-tests and the sharefs-tests
NEX-16819 loader UEFI support
Includes work by Toomas Soome <tsoome@me.com>
Upstream commits:
    loader: pxe receive cleanup
    9475 libefi: Do not return only if ReceiveFilter
    installboot: should support efi system partition
    8931 boot1.efi: scan all display modes rather than
    loader: spinconsole updates
    loader: gfx experiment to try GOP Blt() function.
    sha1 build test
    loader: add sha1 hash calculation
    common/sha1: update for loader build
    loader: biosdisk rework
    uts: 32-bit kernel FB needs mapping in low memory
    uts: add diag-device
    uts: boot console mirror with diag-device
    uts: enable very early console on ttya
    kmdb: add diag-device as input/output device
    uts: test VGA memory exclusion from mapping
    uts: clear boot mapping and protect boot pages test
    uts: add dboot map debug printf
    uts: need to release FB pages in release_bootstrap()
    uts: add screenmap ioctl
    uts: update sys/queue.h
    loader: add illumos uts/common to include path
    loader: tem/gfx font cleanup
    loader: vbe checks
    uts: gfx_private set KD_TEXT when KD_RESETTEXT is
    uts: gfx 8-bit update
    loader: gfx 8-bit fix
    loader: always set media size from partition.
    uts: MB2 support for 32-bit kernel
    loader: x86 should have tem 80x25
    uts: x86 should have tem 80x25
    uts: font update
    loader: font update
    uts: tem attributes
    loader: tem.c comment added
    uts: use font module
    loader: add font module
    loader: build rules for new font setup
    uts: gfx_private update for new font structure
    uts: early boot update for new font structure
    uts: font update
    uts: font build rules update for new fonts
    uts: tem update to new font structure
    loader: module.c needs to include tem_impl.h
    uts: gfx_private 8x16 font rework
    uts: make font_lookup public
    loader: font rework
    uts: font rework
    libefi: efi_alloc_and_read should check for PMBR
    uts: tem utf-8 support
    loader: implement tem utf-8 support
    loader: tem should be able to display UTF-8
    7784 uts: console input should support utf-8
    7796 uts: ldterm default to utf-8
    uts: do not reset serial console
    uts: set up colors even if tem is not console
    uts: add type for early boot properties
    uts: gfx_private experiment with drm and vga
    uts: gfx_private should use setmode drm callback.
    uts: identify FB types and set up gfx_private based
    loader: replace gop and vesa with framebuffer
    uts: boot needs simple tem to support mdb
    uts: boot_keyboard should emit esc sequences for
    uts: gfx_private FB showuld be written by line
    kmdb: set terminal window size
    uts: gfx_private needs to keep track of early boot FB
    pnglite: move pnglite to usr/src/common
    loader: gfx_fb
    ficl-sys: add gfx primitives
    loader: add illumos.png logo
    ficl: add fb-putimage
    loader: add png support
    loader: add alpha blending for gfx_fb
    loader: use term-drawrect for menu frame
    ficl: add simple gfx words
    uts: provide fb_info via fbgattr dev_specific array.
    uts: gfx_private add alpha blending
    uts: update sys/ascii.h
    uts: tem OSC support (incomplete)
    uts: implement env module support and use data from
    uts: tem get colors from early boot data
    loader: use crc32 from libstand (libz)
    loader: optimize for size
    loader: pass tem info to the environment
    loader: import tem for loader console
    loader: UEFI loader needs to set ISADIR based on
    loader: need UEFI32 support
    8918 loader.efi: add vesa edid support
    uts: tem_safe_pix_clear_prom_output() should only
    uts: tem_safe_pix_clear_entire_screen() should use
    uts: tem_safe_check_first_time() should query cursor
    uts: tem implement cls callback & visual_io v4
    uts: gfx_vgatext use block cursor for vgatext
    uts: gfx_private implement cls callback & visual_io
    uts: gfx_private bitmap framebuffer implementation
    uts: early start frame buffer console support
    uts: font functions should check the input char
    uts: font rendering should support 16/24/32bit depths
    uts: use smallest font as fallback default.
    uts: update terminal dimensions based on selected
    7834 uts: vgatext should use gfx_private
    uts: add spacing property to 8859-1.bdf
    terminfo: add underline for sun-color
    terminfo: sun-color has 16 colors
    uts: add font load callback type
    loader: do not repeat int13 calls with error 0x20 and
    8905 loader: add skein/edonr support
    8904 common/crypto: make skein and edonr loader
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>

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 ↓ 20 lines elided ↑ open up ↑
  21   21  /*
  22   22   * Copyright (c) 2012 Gary Mills
  23   23   *
  24   24   * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  25   25   * Use is subject to license terms.
  26   26   */
  27   27  
  28   28  #include <sys/types.h>
  29   29  #include <sys/systm.h>
  30   30  #include <sys/archsystm.h>
       31 +#include <sys/framebuffer.h>
  31   32  #include <sys/boot_console.h>
  32   33  #include <sys/panic.h>
  33   34  #include <sys/ctype.h>
       35 +#include <sys/ascii.h>
  34   36  #if defined(__xpv)
  35   37  #include <sys/hypervisor.h>
  36   38  #endif /* __xpv */
  37   39  
       40 +#include "boot_console_impl.h"
  38   41  #include "boot_serial.h"
  39   42  #include "boot_vga.h"
  40   43  
  41   44  #if defined(_BOOT)
  42   45  #include <dboot/dboot_asm.h>
  43   46  #include <dboot/dboot_xboot.h>
  44   47  #else /* _BOOT */
  45   48  #include <sys/bootconf.h>
  46   49  #if defined(__xpv)
  47   50  #include <sys/evtchn_impl.h>
↓ open down ↓ 2 lines elided ↑ open up ↑
  50   53  static char *defcons_cur;
  51   54  #endif /* _BOOT */
  52   55  
  53   56  #if defined(__xpv)
  54   57  extern void bcons_init_xen(char *);
  55   58  extern void bcons_putchar_xen(int);
  56   59  extern int bcons_getchar_xen(void);
  57   60  extern int bcons_ischar_xen(void);
  58   61  #endif /* __xpv */
  59   62  
  60      -static int cons_color = CONS_COLOR;
       63 +fb_info_t fb_info;
       64 +static bcons_dev_t bcons_dev;                           /* Device callbacks */
  61   65  static int console = CONS_SCREEN_TEXT;
       66 +static int diag = CONS_INVALID;
  62   67  static int tty_num = 0;
  63   68  static int tty_addr[] = {0x3f8, 0x2f8, 0x3e8, 0x2e8};
  64   69  static char *boot_line;
  65   70  static struct boot_env {
  66   71          char    *be_env;        /* ends with double ascii nul */
  67   72          size_t  be_size;        /* size of the environment, including nul */
  68   73  } boot_env;
  69   74  
       75 +/*
       76 + * Simple console terminal emulator for early boot.
       77 + * We need this to support kmdb, all other console output is supposed
       78 + * to be simple text output.
       79 + */
       80 +typedef enum btem_state_type {
       81 +        A_STATE_START,
       82 +        A_STATE_ESC,
       83 +        A_STATE_CSI,
       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 +
  70   99  static int serial_ischar(void);
  71  100  static int serial_getchar(void);
  72  101  static void serial_putchar(int);
  73  102  static void serial_adjust_prop(void);
  74  103  
  75  104  #if !defined(_BOOT)
  76  105  /* Set if the console or mode are expressed in the boot line */
  77  106  static int console_set, console_mode_set;
  78  107  #endif
  79  108  
↓ open down ↓ 5 lines elided ↑ open up ↑
  85  114  /* Obtain the hypervisor console type */
  86  115  int
  87  116  console_hypervisor_dev_type(int *tnum)
  88  117  {
  89  118          if (tnum != NULL)
  90  119                  *tnum = console_hypervisor_tty_num;
  91  120          return (console_hypervisor_device);
  92  121  }
  93  122  #endif /* __xpv */
  94  123  
  95      -/* Clear the screen and initialize VIDEO, XPOS and YPOS. */
  96      -void
  97      -clear_screen(void)
  98      -{
  99      -        /*
 100      -         * XXX should set vga mode so we don't depend on the
 101      -         * state left by the boot loader.  Note that we have to
 102      -         * enable the cursor before clearing the screen since
 103      -         * the cursor position is dependant upon the cursor
 104      -         * skew, which is initialized by vga_cursor_display()
 105      -         */
 106      -        vga_cursor_display();
 107      -        vga_clear(cons_color);
 108      -        vga_setpos(0, 0);
 109      -}
 110      -
 111      -/* Put the character C on the screen. */
 112      -static void
 113      -screen_putchar(int c)
 114      -{
 115      -        int row, col;
 116      -
 117      -        vga_getpos(&row, &col);
 118      -        switch (c) {
 119      -        case '\t':
 120      -                col += 8 - (col % 8);
 121      -                if (col == VGA_TEXT_COLS)
 122      -                        col = 79;
 123      -                vga_setpos(row, col);
 124      -                break;
 125      -
 126      -        case '\r':
 127      -                vga_setpos(row, 0);
 128      -                break;
 129      -
 130      -        case '\b':
 131      -                if (col > 0)
 132      -                        vga_setpos(row, col - 1);
 133      -                break;
 134      -
 135      -        case '\n':
 136      -                if (row < VGA_TEXT_ROWS - 1)
 137      -                        vga_setpos(row + 1, col);
 138      -                else
 139      -                        vga_scroll(cons_color);
 140      -                break;
 141      -
 142      -        default:
 143      -                vga_drawc(c, cons_color);
 144      -                if (col < VGA_TEXT_COLS -1)
 145      -                        vga_setpos(row, col + 1);
 146      -                else if (row < VGA_TEXT_ROWS - 1)
 147      -                        vga_setpos(row + 1, 0);
 148      -                else {
 149      -                        vga_setpos(row, 0);
 150      -                        vga_scroll(cons_color);
 151      -                }
 152      -                break;
 153      -        }
 154      -}
 155      -
 156  124  static int port;
 157  125  
 158  126  static void
 159  127  serial_init(void)
 160  128  {
 161  129          port = tty_addr[tty_num];
 162  130  
 163  131          outb(port + ISR, 0x20);
 164  132          if (inb(port + ISR) & 0x20) {
 165  133                  /*
↓ open down ↓ 30 lines elided ↑ open up ↑
 196  164  
 197  165  #if !defined(_BOOT)
 198  166          if (IN_XPV_PANIC())
 199  167                  return;
 200  168  #endif
 201  169  
 202  170          /* adjust setting based on tty properties */
 203  171          serial_adjust_prop();
 204  172  
 205  173  #if defined(_BOOT)
      174 +#if 0
 206  175          /*
 207  176           * Do a full reset to match console behavior.
 208  177           * 0x1B + c - reset everything
 209  178           */
 210  179          serial_putchar(0x1B);
 211  180          serial_putchar('c');
 212  181  #endif
      182 +#endif
 213  183  }
 214  184  
 215  185  /* Advance str pointer past white space */
 216  186  #define EAT_WHITE_SPACE(str)    {                       \
 217  187          while ((*str != '\0') && ISSPACE(*str))         \
 218  188                  str++;                                  \
 219  189  }
 220  190  
 221  191  /*
 222  192   * boot_line is set when we call here.  Search it for the argument name,
↓ open down ↓ 375 lines elided ↑ open up ↑
 598  568                  if (modules[i].bm_type == BMT_ENV)
 599  569                          break;
 600  570          }
 601  571          if (i == xbi->bi_module_cnt)
 602  572                  return;
 603  573  
 604  574          boot_env.be_env = (char *)(uintptr_t)modules[i].bm_addr;
 605  575          boot_env.be_size = modules[i].bm_size;
 606  576  }
 607  577  
      578 +int
      579 +boot_fb(struct xboot_info *xbi, int console)
      580 +{
      581 +        if (xbi_fb_init(xbi, &bcons_dev) == B_FALSE)
      582 +                return (console);
      583 +
      584 +        /* FB address is not set, fall back to serial terminal. */
      585 +        if (fb_info.paddr == 0) {
      586 +                return (CONS_TTY);
      587 +        }
      588 +
      589 +        fb_info.terminal.x = VGA_TEXT_COLS;
      590 +        fb_info.terminal.y = VGA_TEXT_ROWS;
      591 +        boot_fb_init(CONS_FRAMEBUFFER);
      592 +
      593 +        if (console == CONS_SCREEN_TEXT)
      594 +                return (CONS_FRAMEBUFFER);
      595 +        return (console);
      596 +}
      597 +
      598 +/*
      599 + * TODO.
      600 + * quick and dirty local atoi. Perhaps should build with strtol, but
      601 + * dboot & early boot mix does overcomplicate things much.
      602 + * Stolen from libc anyhow.
      603 + */
      604 +static int
      605 +atoi(const char *p)
      606 +{
      607 +        int n, c, neg = 0;
      608 +        unsigned char *up = (unsigned char *)p;
      609 +
      610 +        if (!isdigit(c = *up)) {
      611 +                while (isspace(c))
      612 +                        c = *++up;
      613 +                switch (c) {
      614 +                case '-':
      615 +                        neg++;
      616 +                        /* FALLTHROUGH */
      617 +                case '+':
      618 +                        c = *++up;
      619 +                }
      620 +                if (!isdigit(c))
      621 +                        return (0);
      622 +        }
      623 +        for (n = '0' - c; isdigit(c = *++up); ) {
      624 +                n *= 10; /* two steps to avoid unnecessary overflow */
      625 +                n += '0' - c; /* accum neg to avoid surprises at MAX */
      626 +        }
      627 +        return (neg ? n : -n);
      628 +}
      629 +
      630 +static void
      631 +bcons_init_fb(void)
      632 +{
      633 +        const char *propval;
      634 +        int intval;
      635 +
      636 +        /* initialize with explicit default values */
      637 +        fb_info.fg_color = CONS_COLOR;
      638 +        fb_info.bg_color = 0;
      639 +        fb_info.inverse = B_FALSE;
      640 +        fb_info.inverse_screen = B_FALSE;
      641 +
      642 +        /* color values are 0 - 7 */
      643 +        propval = find_boot_prop("tem.fg_color");
      644 +        if (propval != NULL) {
      645 +                intval = atoi(propval);
      646 +                if (intval >= 0 && intval <= 7)
      647 +                        fb_info.fg_color = intval;
      648 +        }
      649 +
      650 +        /* color values are 0 - 7 */
      651 +        propval = find_boot_prop("tem.bg_color");
      652 +        if (propval != NULL && ISDIGIT(*propval)) {
      653 +                intval = atoi(propval);
      654 +                if (intval >= 0 && intval <= 7)
      655 +                        fb_info.bg_color = intval;
      656 +        }
      657 +
      658 +        /* get inverses. allow 0, 1, true, false */
      659 +        propval = find_boot_prop("tem.inverse");
      660 +        if (propval != NULL) {
      661 +                if (*propval == '1' || MATCHES(propval, "true"))
      662 +                        fb_info.inverse = B_TRUE;
      663 +        }
      664 +
      665 +        propval = find_boot_prop("tem.inverse-screen");
      666 +        if (propval != NULL) {
      667 +                if (*propval == '1' || MATCHES(propval, "true"))
      668 +                        fb_info.inverse_screen = B_TRUE;
      669 +        }
      670 +
      671 +#if defined(_BOOT)
      672 +        /*
      673 +         * Load cursor position from bootloader only in dboot,
      674 +         * dboot will pass cursor position to kernel via xboot info.
      675 +         */
      676 +        propval = find_boot_prop("tem.cursor.row");
      677 +        if (propval != NULL) {
      678 +                intval = atoi(propval);
      679 +                if (intval >= 0 && intval <= 0xFFFF)
      680 +                        fb_info.cursor.pos.y = intval;
      681 +        }
      682 +
      683 +        propval = find_boot_prop("tem.cursor.col");
      684 +        if (propval != NULL) {
      685 +                intval = atoi(propval);
      686 +                if (intval >= 0 && intval <= 0xFFFF)
      687 +                        fb_info.cursor.pos.x = intval;
      688 +        }
      689 +#endif
      690 +}
      691 +
      692 +/*
      693 + * Go through the console_devices array trying to match the string
      694 + * we were given.  The string on the command line must end with
      695 + * a comma or white space.
      696 + *
      697 + * Eventually we need to rework this to process dual console setup.
      698 + * This function does set tty_num as an side effect.
      699 + */
      700 +static int
      701 +lookup_console_devices(const char *cons_str)
      702 +{
      703 +        int n, cons;
      704 +        size_t len, cons_len;
      705 +        console_value_t *consolep;
      706 +
      707 +        cons = CONS_INVALID;
      708 +        if (cons_str != NULL) {
      709 +
      710 +                cons_len = strlen(cons_str);
      711 +                for (n = 0; console_devices[n].name != NULL; n++) {
      712 +                        consolep = &console_devices[n];
      713 +                        len = strlen(consolep->name);
      714 +                        if ((len <= cons_len) && ((cons_str[len] == '\0') ||
      715 +                            (cons_str[len] == ',') || (cons_str[len] == '\'') ||
      716 +                            (cons_str[len] == '"') || ISSPACE(cons_str[len])) &&
      717 +                            (strncmp(cons_str, consolep->name, len) == 0)) {
      718 +                                cons = consolep->value;
      719 +                                if (cons == CONS_TTY)
      720 +                                        tty_num = n;
      721 +                                break;
      722 +                        }
      723 +                }
      724 +        }
      725 +        return (cons);
      726 +}
      727 +
 608  728  void
 609  729  bcons_init(struct xboot_info *xbi)
 610  730  {
 611      -        console_value_t *consolep;
 612      -        size_t len, cons_len;
 613  731          const char *cons_str;
 614  732  #if !defined(_BOOT)
 615  733          static char console_text[] = "text";
 616  734          extern int post_fastreboot;
 617  735  #endif
 618  736  
      737 +        if (xbi == NULL) {
      738 +                /* This is very early dboot console, set up ttya. */
      739 +                console = CONS_TTY;
      740 +                serial_init();
      741 +                return;
      742 +        }
      743 +
 619  744          /* Set up data to fetch properties from commad line and boot env. */
 620  745          boot_line = (char *)(uintptr_t)xbi->bi_cmdline;
 621  746          bcons_init_env(xbi);
 622  747          console = CONS_INVALID;
 623  748  
      749 +        /* set up initial fb_info */
      750 +        bcons_init_fb();
      751 +
 624  752  #if defined(__xpv)
 625  753          bcons_init_xen(boot_line);
 626  754  #endif /* __xpv */
 627  755  
      756 +        /*
      757 +         * First check for diag-device.
      758 +         */
      759 +        cons_str = find_boot_prop("diag-device");
      760 +        if (cons_str != NULL) {
      761 +                diag = lookup_console_devices(cons_str);
      762 +                serial_init();
      763 +        }
      764 +
 628  765          cons_str = find_boot_prop("console");
 629  766          if (cons_str == NULL)
 630  767                  cons_str = find_boot_prop("output-device");
 631  768  
 632  769  #if !defined(_BOOT)
 633  770          if (post_fastreboot && strcmp(cons_str, "graphics") == 0)
 634  771                  cons_str = console_text;
 635  772  #endif
 636  773  
 637      -        /*
 638      -         * Go through the console_devices array trying to match the string
 639      -         * we were given.  The string on the command line must end with
 640      -         * a comma or white space.
 641      -         */
 642      -        if (cons_str != NULL) {
 643      -                int n;
      774 +        if (cons_str != NULL)
      775 +                console = lookup_console_devices(cons_str);
 644  776  
 645      -                cons_len = strlen(cons_str);
 646      -                for (n = 0; console_devices[n].name != NULL; n++) {
 647      -                        consolep = &console_devices[n];
 648      -                        len = strlen(consolep->name);
 649      -                        if ((len <= cons_len) && ((cons_str[len] == '\0') ||
 650      -                            (cons_str[len] == ',') || (cons_str[len] == '\'') ||
 651      -                            (cons_str[len] == '"') || ISSPACE(cons_str[len])) &&
 652      -                            (strncmp(cons_str, consolep->name, len) == 0)) {
 653      -                                console = consolep->value;
 654      -                                if (console == CONS_TTY)
 655      -                                        tty_num = n;
 656      -                                break;
 657      -                        }
 658      -                }
 659      -        }
 660      -
 661  777  #if defined(__xpv)
 662  778          /*
 663  779           * domU's always use the hypervisor regardless of what
 664  780           * the console variable may be set to.
 665  781           */
 666  782          if (!DOMAIN_IS_INITDOMAIN(xen_info)) {
 667  783                  console = CONS_HYPERVISOR;
 668  784                  console_hypervisor_redirect = B_TRUE;
 669  785          }
 670  786  #endif /* __xpv */
↓ open down ↓ 37 lines elided ↑ open up ↑
 708  824           * if the hypervisor is using the currently selected serial
 709  825           * port then default to using the hypervisor as the console
 710  826           * device.
 711  827           */
 712  828          if (console == console_hypervisor_device) {
 713  829                  console = CONS_HYPERVISOR;
 714  830                  console_hypervisor_redirect = B_TRUE;
 715  831          }
 716  832  #endif /* __xpv */
 717  833  
      834 +        /* make sure the FB is set up if present */
      835 +        console = boot_fb(xbi, console);
 718  836          switch (console) {
 719  837          case CONS_TTY:
 720  838                  serial_init();
 721  839                  break;
 722  840  
 723  841          case CONS_HYPERVISOR:
 724  842                  break;
 725  843  
 726  844  #if !defined(_BOOT)
 727  845          case CONS_USBSER:
 728  846                  /*
 729  847                   * We can't do anything with the usb serial
 730  848                   * until we have memory management.
 731  849                   */
 732  850                  break;
 733  851  #endif
 734  852          case CONS_SCREEN_GRAPHICS:
 735  853                  kb_init();
 736  854                  break;
 737  855          case CONS_SCREEN_TEXT:
      856 +                boot_vga_init(&bcons_dev);
      857 +                /* Fall through */
 738  858          default:
 739      -#if defined(_BOOT)
 740      -                clear_screen(); /* clears the grub or xen screen */
 741      -#endif /* _BOOT */
 742  859                  kb_init();
 743  860                  break;
 744  861          }
 745  862  }
 746  863  
 747  864  #if !defined(_BOOT)
 748  865  /*
 749  866   * 2nd part of console initialization.
 750  867   * In the kernel (ie. fakebop), this can be used only to switch to
 751  868   * using a serial port instead of screen based on the contents
↓ open down ↓ 148 lines elided ↑ open up ↑
 900 1017          return (inb(port + DAT));
 901 1018  }
 902 1019  
 903 1020  static int
 904 1021  serial_ischar(void)
 905 1022  {
 906 1023          return (inb(port + LSR) & RCA);
 907 1024  }
 908 1025  
 909 1026  static void
 910      -_doputchar(int c)
     1027 +btem_control(btem_state_t *btem, int c)
 911 1028  {
 912      -        switch (console) {
     1029 +        int y, rows, cols;
     1030 +
     1031 +        rows = fb_info.cursor.pos.y;
     1032 +        cols = fb_info.cursor.pos.x;
     1033 +
     1034 +        btem->btem_state = A_STATE_START;
     1035 +        switch (c) {
     1036 +        case A_BS:
     1037 +                bcons_dev.bd_setpos(rows, cols - 1);
     1038 +                break;
     1039 +
     1040 +        case A_HT:
     1041 +                cols += 8 - (cols % 8);
     1042 +                if (cols == fb_info.terminal.x)
     1043 +                        cols = fb_info.terminal.x - 1;
     1044 +                bcons_dev.bd_setpos(rows, cols);
     1045 +                break;
     1046 +
     1047 +        case A_CR:
     1048 +                bcons_dev.bd_setpos(rows, 0);
     1049 +                break;
     1050 +
     1051 +        case A_FF:
     1052 +                for (y = 0; y < fb_info.terminal.y; y++) {
     1053 +                        bcons_dev.bd_setpos(y, 0);
     1054 +                        bcons_dev.bd_eraseline();
     1055 +                }
     1056 +                bcons_dev.bd_setpos(0, 0);
     1057 +                break;
     1058 +
     1059 +        case A_ESC:
     1060 +                btem->btem_state = A_STATE_ESC;
     1061 +                break;
     1062 +
     1063 +        default:
     1064 +                bcons_dev.bd_putchar(c);
     1065 +                break;
     1066 +        }
     1067 +}
     1068 +
     1069 +/*
     1070 + * if parameters [0..count - 1] are not set, set them to the value
     1071 + * of newparam.
     1072 + */
     1073 +static void
     1074 +btem_setparam(btem_state_t *btem, int count, int newparam)
     1075 +{
     1076 +        int i;
     1077 +
     1078 +        for (i = 0; i < count; i++) {
     1079 +                if (btem->btem_params[i] == -1)
     1080 +                        btem->btem_params[i] = newparam;
     1081 +        }
     1082 +}
     1083 +
     1084 +static void
     1085 +btem_chkparam(btem_state_t *btem, int c)
     1086 +{
     1087 +        int rows, cols;
     1088 +
     1089 +        rows = fb_info.cursor.pos.y;
     1090 +        cols = fb_info.cursor.pos.x;
     1091 +        switch (c) {
     1092 +        case '@':                       /* insert char */
     1093 +                btem_setparam(btem, 1, 1);
     1094 +                bcons_dev.bd_shift(btem->btem_params[0]);
     1095 +                break;
     1096 +
     1097 +        case 'A':                       /* cursor up */
     1098 +                btem_setparam(btem, 1, 1);
     1099 +                bcons_dev.bd_setpos(rows - btem->btem_params[0], cols);
     1100 +                break;
     1101 +
     1102 +        case 'B':                       /* cursor down */
     1103 +                btem_setparam(btem, 1, 1);
     1104 +                bcons_dev.bd_setpos(rows + btem->btem_params[0], cols);
     1105 +                break;
     1106 +
     1107 +        case 'C':                       /* cursor right */
     1108 +                btem_setparam(btem, 1, 1);
     1109 +                bcons_dev.bd_setpos(rows, cols + btem->btem_params[0]);
     1110 +                break;
     1111 +
     1112 +        case 'D':                       /* cursor left */
     1113 +                btem_setparam(btem, 1, 1);
     1114 +                bcons_dev.bd_setpos(rows, cols - btem->btem_params[0]);
     1115 +                break;
     1116 +
     1117 +        case 'K':
     1118 +                bcons_dev.bd_eraseline();
     1119 +                break;
     1120 +        default:
     1121 +                /* bcons_dev.bd_putchar(c); */
     1122 +                break;
     1123 +        }
     1124 +        btem->btem_state = A_STATE_START;
     1125 +}
     1126 +
     1127 +static void
     1128 +btem_getparams(btem_state_t *btem, int c)
     1129 +{
     1130 +        if (c >= '0' && c <= '9') {
     1131 +                btem->btem_paramval = btem->btem_paramval * 10 + c - '0';
     1132 +                btem->btem_gotparam = B_TRUE;
     1133 +                return;
     1134 +        }
     1135 +
     1136 +        if (btem->btem_curparam < BTEM_MAXPARAMS) {
     1137 +                if (btem->btem_gotparam == B_TRUE) {
     1138 +                        btem->btem_params[btem->btem_curparam] =
     1139 +                            btem->btem_paramval;
     1140 +                }
     1141 +                btem->btem_curparam++;
     1142 +        }
     1143 +
     1144 +        if (c == ';') {
     1145 +                /* Restart parameter search */
     1146 +                btem->btem_gotparam = B_FALSE;
     1147 +                btem->btem_paramval = 0;
     1148 +        } else {
     1149 +                btem_chkparam(btem, c);
     1150 +        }
     1151 +}
     1152 +
     1153 +/* Simple boot terminal parser. */
     1154 +static void
     1155 +btem_parse(btem_state_t *btem, int c)
     1156 +{
     1157 +        int i;
     1158 +
     1159 +        /* Normal state? */
     1160 +        if (btem->btem_state == A_STATE_START) {
     1161 +                if (c == A_CSI || c < ' ')
     1162 +                        btem_control(btem, c);
     1163 +                else
     1164 +                        bcons_dev.bd_putchar(c);
     1165 +                return;
     1166 +        }
     1167 +
     1168 +        /* In <ESC> sequence */
     1169 +        if (btem->btem_state != A_STATE_ESC) {
     1170 +                btem_getparams(btem, c);
     1171 +                return;
     1172 +        }
     1173 +
     1174 +        /* Previous char was <ESC> */
     1175 +        switch (c) {
     1176 +        case '[':
     1177 +                btem->btem_curparam = 0;
     1178 +                btem->btem_paramval = 0;
     1179 +                btem->btem_gotparam = B_FALSE;
     1180 +                /* clear the parameters */
     1181 +                for (i = 0; i < BTEM_MAXPARAMS; i++)
     1182 +                        btem->btem_params[i] = -1;
     1183 +                btem->btem_state = A_STATE_CSI;
     1184 +                return;
     1185 +
     1186 +        case 'Q':       /* <ESC>Q */
     1187 +        case 'C':       /* <ESC>C */
     1188 +                btem->btem_state = A_STATE_START;
     1189 +                return;
     1190 +
     1191 +        default:
     1192 +                btem->btem_state = A_STATE_START;
     1193 +                break;
     1194 +        }
     1195 +
     1196 +        if (c < ' ')
     1197 +                btem_control(btem, c);
     1198 +        else
     1199 +                bcons_dev.bd_putchar(c);
     1200 +}
     1201 +
     1202 +static void
     1203 +_doputchar(int device, int c)
     1204 +{
     1205 +        switch (device) {
 913 1206          case CONS_TTY:
 914 1207                  serial_putchar(c);
 915 1208                  return;
 916 1209          case CONS_SCREEN_TEXT:
 917      -                screen_putchar(c);
     1210 +        case CONS_FRAMEBUFFER:
     1211 +                bcons_dev.bd_cursor(B_FALSE);
     1212 +                btem_parse(&boot_tem, c);
     1213 +                bcons_dev.bd_cursor(B_TRUE);
 918 1214                  return;
 919 1215          case CONS_SCREEN_GRAPHICS:
 920 1216  #if !defined(_BOOT)
 921 1217          case CONS_USBSER:
 922 1218                  defcons_putchar(c);
 923 1219  #endif /* _BOOT */
     1220 +        default:
 924 1221                  return;
 925 1222          }
 926 1223  }
 927 1224  
 928 1225  void
 929 1226  bcons_putchar(int c)
 930 1227  {
 931      -        static int bhcharpos = 0;
 932      -
 933 1228  #if defined(__xpv)
 934 1229          if (!DOMAIN_IS_INITDOMAIN(xen_info) ||
 935 1230              console == CONS_HYPERVISOR) {
 936 1231                  bcons_putchar_xen(c);
 937 1232                  return;
 938 1233          }
 939 1234  #endif /* __xpv */
 940 1235  
 941      -        if (c == '\t') {
 942      -                do {
 943      -                        _doputchar(' ');
 944      -                } while (++bhcharpos % 8);
 945      -                return;
 946      -        } else  if (c == '\n' || c == '\r') {
 947      -                bhcharpos = 0;
 948      -                _doputchar('\r');
 949      -                _doputchar(c);
 950      -                return;
 951      -        } else if (c == '\b') {
 952      -                if (bhcharpos)
 953      -                        bhcharpos--;
 954      -                _doputchar(c);
 955      -                return;
     1236 +        if (c == '\n') {
     1237 +                _doputchar(console, '\r');
     1238 +                if (diag != console)
     1239 +                        _doputchar(diag, '\r');
 956 1240          }
 957      -
 958      -        bhcharpos++;
 959      -        _doputchar(c);
     1241 +        _doputchar(console, c);
     1242 +        if (diag != console)
     1243 +                _doputchar(diag, c);
 960 1244  }
 961 1245  
 962 1246  /*
 963 1247   * kernel character input functions
 964 1248   */
 965 1249  int
 966 1250  bcons_getchar(void)
 967 1251  {
 968 1252  #if defined(__xpv)
 969 1253          if (!DOMAIN_IS_INITDOMAIN(xen_info) ||
 970 1254              console == CONS_HYPERVISOR)
 971 1255                  return (bcons_getchar_xen());
 972 1256  #endif /* __xpv */
 973 1257  
 974      -        switch (console) {
 975      -        case CONS_TTY:
 976      -                return (serial_getchar());
 977      -        default:
 978      -                return (kb_getchar());
     1258 +        for (;;) {
     1259 +                if (console == CONS_TTY || diag == CONS_TTY) {
     1260 +                        if (serial_ischar())
     1261 +                                return (serial_getchar());
     1262 +                }
     1263 +                if (console != CONS_INVALID || diag != CONS_INVALID) {
     1264 +                        if (kb_ischar())
     1265 +                                return (kb_getchar());
     1266 +                }
 979 1267          }
 980 1268  }
 981 1269  
 982 1270  #if !defined(_BOOT)
 983 1271  
 984 1272  int
 985 1273  bcons_ischar(void)
 986 1274  {
     1275 +        int c = 0;
 987 1276  
 988 1277  #if defined(__xpv)
 989 1278          if (!DOMAIN_IS_INITDOMAIN(xen_info) ||
 990 1279              console == CONS_HYPERVISOR)
 991 1280                  return (bcons_ischar_xen());
 992 1281  #endif /* __xpv */
 993 1282  
 994 1283          switch (console) {
 995 1284          case CONS_TTY:
     1285 +                c = serial_ischar();
     1286 +                break;
     1287 +
     1288 +        case CONS_INVALID:
     1289 +                break;
     1290 +
     1291 +        default:
     1292 +                c = kb_ischar();
     1293 +        }
     1294 +        if (c != 0)
     1295 +                return (c);
     1296 +
     1297 +        switch (diag) {
     1298 +        case CONS_TTY:
 996 1299                  return (serial_ischar());
     1300 +
     1301 +        case CONS_INVALID:
     1302 +                break;
     1303 +
 997 1304          default:
 998 1305                  return (kb_ischar());
 999 1306          }
     1307 +
     1308 +        return (c);
1000 1309  }
1001 1310  
1002 1311  #endif /* _BOOT */
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX