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>

*** 26,42 **** --- 26,45 ---- */ #include <sys/types.h> #include <sys/systm.h> #include <sys/archsystm.h> + #include <sys/framebuffer.h> #include <sys/boot_console.h> #include <sys/panic.h> #include <sys/ctype.h> + #include <sys/ascii.h> #if defined(__xpv) #include <sys/hypervisor.h> #endif /* __xpv */ + #include "boot_console_impl.h" #include "boot_serial.h" #include "boot_vga.h" #if defined(_BOOT) #include <dboot/dboot_asm.h>
*** 55,74 **** extern void bcons_putchar_xen(int); extern int bcons_getchar_xen(void); extern int bcons_ischar_xen(void); #endif /* __xpv */ ! static int cons_color = CONS_COLOR; static int console = CONS_SCREEN_TEXT; static int tty_num = 0; static int tty_addr[] = {0x3f8, 0x2f8, 0x3e8, 0x2e8}; static char *boot_line; static struct boot_env { char *be_env; /* ends with double ascii nul */ size_t be_size; /* size of the environment, including nul */ } boot_env; static int serial_ischar(void); static int serial_getchar(void); static void serial_putchar(int); static void serial_adjust_prop(void); --- 58,103 ---- extern void bcons_putchar_xen(int); extern int bcons_getchar_xen(void); extern int bcons_ischar_xen(void); #endif /* __xpv */ ! fb_info_t fb_info; ! static bcons_dev_t bcons_dev; /* Device callbacks */ static int console = CONS_SCREEN_TEXT; + static int diag = CONS_INVALID; static int tty_num = 0; static int tty_addr[] = {0x3f8, 0x2f8, 0x3e8, 0x2e8}; static char *boot_line; static struct boot_env { char *be_env; /* ends with double ascii nul */ size_t be_size; /* size of the environment, including nul */ } boot_env; + /* + * Simple console terminal emulator for early boot. + * We need this to support kmdb, all other console output is supposed + * to be simple text output. + */ + typedef enum btem_state_type { + A_STATE_START, + A_STATE_ESC, + A_STATE_CSI, + A_STATE_CSI_QMARK, + A_STATE_CSI_EQUAL + } btem_state_type_t; + + #define BTEM_MAXPARAMS 5 + typedef struct btem_state { + btem_state_type_t btem_state; + boolean_t btem_gotparam; + int btem_curparam; + int btem_paramval; + int btem_params[BTEM_MAXPARAMS]; + } btem_state_t; + + static btem_state_t boot_tem; + static int serial_ischar(void); static int serial_getchar(void); static void serial_putchar(int); static void serial_adjust_prop(void);
*** 90,160 **** *tnum = console_hypervisor_tty_num; return (console_hypervisor_device); } #endif /* __xpv */ - /* Clear the screen and initialize VIDEO, XPOS and YPOS. */ - void - clear_screen(void) - { - /* - * XXX should set vga mode so we don't depend on the - * state left by the boot loader. Note that we have to - * enable the cursor before clearing the screen since - * the cursor position is dependant upon the cursor - * skew, which is initialized by vga_cursor_display() - */ - vga_cursor_display(); - vga_clear(cons_color); - vga_setpos(0, 0); - } - - /* Put the character C on the screen. */ - static void - screen_putchar(int c) - { - int row, col; - - vga_getpos(&row, &col); - switch (c) { - case '\t': - col += 8 - (col % 8); - if (col == VGA_TEXT_COLS) - col = 79; - vga_setpos(row, col); - break; - - case '\r': - vga_setpos(row, 0); - break; - - case '\b': - if (col > 0) - vga_setpos(row, col - 1); - break; - - case '\n': - if (row < VGA_TEXT_ROWS - 1) - vga_setpos(row + 1, col); - else - vga_scroll(cons_color); - break; - - default: - vga_drawc(c, cons_color); - if (col < VGA_TEXT_COLS -1) - vga_setpos(row, col + 1); - else if (row < VGA_TEXT_ROWS - 1) - vga_setpos(row + 1, 0); - else { - vga_setpos(row, 0); - vga_scroll(cons_color); - } - break; - } - } - static int port; static void serial_init(void) { --- 119,128 ----
*** 201,217 **** --- 169,187 ---- /* adjust setting based on tty properties */ serial_adjust_prop(); #if defined(_BOOT) + #if 0 /* * Do a full reset to match console behavior. * 0x1B + c - reset everything */ serial_putchar(0x1B); serial_putchar('c'); #endif + #endif } /* Advance str pointer past white space */ #define EAT_WHITE_SPACE(str) { \ while ((*str != '\0') && ISSPACE(*str)) \
*** 603,665 **** boot_env.be_env = (char *)(uintptr_t)modules[i].bm_addr; boot_env.be_size = modules[i].bm_size; } void bcons_init(struct xboot_info *xbi) { - console_value_t *consolep; - size_t len, cons_len; const char *cons_str; #if !defined(_BOOT) static char console_text[] = "text"; extern int post_fastreboot; #endif /* Set up data to fetch properties from commad line and boot env. */ boot_line = (char *)(uintptr_t)xbi->bi_cmdline; bcons_init_env(xbi); console = CONS_INVALID; #if defined(__xpv) bcons_init_xen(boot_line); #endif /* __xpv */ cons_str = find_boot_prop("console"); if (cons_str == NULL) cons_str = find_boot_prop("output-device"); #if !defined(_BOOT) if (post_fastreboot && strcmp(cons_str, "graphics") == 0) cons_str = console_text; #endif ! /* ! * Go through the console_devices array trying to match the string ! * we were given. The string on the command line must end with ! * a comma or white space. ! */ ! if (cons_str != NULL) { ! int n; - cons_len = strlen(cons_str); - for (n = 0; console_devices[n].name != NULL; n++) { - consolep = &console_devices[n]; - len = strlen(consolep->name); - if ((len <= cons_len) && ((cons_str[len] == '\0') || - (cons_str[len] == ',') || (cons_str[len] == '\'') || - (cons_str[len] == '"') || ISSPACE(cons_str[len])) && - (strncmp(cons_str, consolep->name, len) == 0)) { - console = consolep->value; - if (console == CONS_TTY) - tty_num = n; - break; - } - } - } - #if defined(__xpv) /* * domU's always use the hypervisor regardless of what * the console variable may be set to. */ --- 573,781 ---- boot_env.be_env = (char *)(uintptr_t)modules[i].bm_addr; boot_env.be_size = modules[i].bm_size; } + int + boot_fb(struct xboot_info *xbi, int console) + { + if (xbi_fb_init(xbi, &bcons_dev) == B_FALSE) + return (console); + + /* FB address is not set, fall back to serial terminal. */ + if (fb_info.paddr == 0) { + return (CONS_TTY); + } + + fb_info.terminal.x = VGA_TEXT_COLS; + fb_info.terminal.y = VGA_TEXT_ROWS; + boot_fb_init(CONS_FRAMEBUFFER); + + if (console == CONS_SCREEN_TEXT) + return (CONS_FRAMEBUFFER); + return (console); + } + + /* + * TODO. + * quick and dirty local atoi. Perhaps should build with strtol, but + * dboot & early boot mix does overcomplicate things much. + * Stolen from libc anyhow. + */ + static int + atoi(const char *p) + { + int n, c, neg = 0; + unsigned char *up = (unsigned char *)p; + + if (!isdigit(c = *up)) { + while (isspace(c)) + c = *++up; + switch (c) { + case '-': + neg++; + /* FALLTHROUGH */ + case '+': + c = *++up; + } + if (!isdigit(c)) + return (0); + } + for (n = '0' - c; isdigit(c = *++up); ) { + n *= 10; /* two steps to avoid unnecessary overflow */ + n += '0' - c; /* accum neg to avoid surprises at MAX */ + } + return (neg ? n : -n); + } + + static void + bcons_init_fb(void) + { + const char *propval; + int intval; + + /* initialize with explicit default values */ + fb_info.fg_color = CONS_COLOR; + fb_info.bg_color = 0; + fb_info.inverse = B_FALSE; + fb_info.inverse_screen = B_FALSE; + + /* color values are 0 - 7 */ + propval = find_boot_prop("tem.fg_color"); + if (propval != NULL) { + intval = atoi(propval); + if (intval >= 0 && intval <= 7) + fb_info.fg_color = intval; + } + + /* color values are 0 - 7 */ + propval = find_boot_prop("tem.bg_color"); + if (propval != NULL && ISDIGIT(*propval)) { + intval = atoi(propval); + if (intval >= 0 && intval <= 7) + fb_info.bg_color = intval; + } + + /* get inverses. allow 0, 1, true, false */ + propval = find_boot_prop("tem.inverse"); + if (propval != NULL) { + if (*propval == '1' || MATCHES(propval, "true")) + fb_info.inverse = B_TRUE; + } + + propval = find_boot_prop("tem.inverse-screen"); + if (propval != NULL) { + if (*propval == '1' || MATCHES(propval, "true")) + fb_info.inverse_screen = B_TRUE; + } + + #if defined(_BOOT) + /* + * Load cursor position from bootloader only in dboot, + * dboot will pass cursor position to kernel via xboot info. + */ + propval = find_boot_prop("tem.cursor.row"); + if (propval != NULL) { + intval = atoi(propval); + if (intval >= 0 && intval <= 0xFFFF) + fb_info.cursor.pos.y = intval; + } + + propval = find_boot_prop("tem.cursor.col"); + if (propval != NULL) { + intval = atoi(propval); + if (intval >= 0 && intval <= 0xFFFF) + fb_info.cursor.pos.x = intval; + } + #endif + } + + /* + * Go through the console_devices array trying to match the string + * we were given. The string on the command line must end with + * a comma or white space. + * + * Eventually we need to rework this to process dual console setup. + * This function does set tty_num as an side effect. + */ + static int + lookup_console_devices(const char *cons_str) + { + int n, cons; + size_t len, cons_len; + console_value_t *consolep; + + cons = CONS_INVALID; + if (cons_str != NULL) { + + cons_len = strlen(cons_str); + for (n = 0; console_devices[n].name != NULL; n++) { + consolep = &console_devices[n]; + len = strlen(consolep->name); + if ((len <= cons_len) && ((cons_str[len] == '\0') || + (cons_str[len] == ',') || (cons_str[len] == '\'') || + (cons_str[len] == '"') || ISSPACE(cons_str[len])) && + (strncmp(cons_str, consolep->name, len) == 0)) { + cons = consolep->value; + if (cons == CONS_TTY) + tty_num = n; + break; + } + } + } + return (cons); + } + void bcons_init(struct xboot_info *xbi) { const char *cons_str; #if !defined(_BOOT) static char console_text[] = "text"; extern int post_fastreboot; #endif + if (xbi == NULL) { + /* This is very early dboot console, set up ttya. */ + console = CONS_TTY; + serial_init(); + return; + } + /* Set up data to fetch properties from commad line and boot env. */ boot_line = (char *)(uintptr_t)xbi->bi_cmdline; bcons_init_env(xbi); console = CONS_INVALID; + /* set up initial fb_info */ + bcons_init_fb(); + #if defined(__xpv) bcons_init_xen(boot_line); #endif /* __xpv */ + /* + * First check for diag-device. + */ + cons_str = find_boot_prop("diag-device"); + if (cons_str != NULL) { + diag = lookup_console_devices(cons_str); + serial_init(); + } + cons_str = find_boot_prop("console"); if (cons_str == NULL) cons_str = find_boot_prop("output-device"); #if !defined(_BOOT) if (post_fastreboot && strcmp(cons_str, "graphics") == 0) cons_str = console_text; #endif ! if (cons_str != NULL) ! console = lookup_console_devices(cons_str); #if defined(__xpv) /* * domU's always use the hypervisor regardless of what * the console variable may be set to. */
*** 713,722 **** --- 829,840 ---- console = CONS_HYPERVISOR; console_hypervisor_redirect = B_TRUE; } #endif /* __xpv */ + /* make sure the FB is set up if present */ + console = boot_fb(xbi, console); switch (console) { case CONS_TTY: serial_init(); break;
*** 733,746 **** #endif case CONS_SCREEN_GRAPHICS: kb_init(); break; case CONS_SCREEN_TEXT: default: - #if defined(_BOOT) - clear_screen(); /* clears the grub or xen screen */ - #endif /* _BOOT */ kb_init(); break; } } --- 851,863 ---- #endif case CONS_SCREEN_GRAPHICS: kb_init(); break; case CONS_SCREEN_TEXT: + boot_vga_init(&bcons_dev); + /* Fall through */ default: kb_init(); break; } }
*** 905,964 **** { return (inb(port + LSR) & RCA); } static void ! _doputchar(int c) { ! switch (console) { case CONS_TTY: serial_putchar(c); return; case CONS_SCREEN_TEXT: ! screen_putchar(c); return; case CONS_SCREEN_GRAPHICS: #if !defined(_BOOT) case CONS_USBSER: defcons_putchar(c); #endif /* _BOOT */ return; } } void bcons_putchar(int c) { - static int bhcharpos = 0; - #if defined(__xpv) if (!DOMAIN_IS_INITDOMAIN(xen_info) || console == CONS_HYPERVISOR) { bcons_putchar_xen(c); return; } #endif /* __xpv */ ! if (c == '\t') { ! do { ! _doputchar(' '); ! } while (++bhcharpos % 8); ! return; ! } else if (c == '\n' || c == '\r') { ! bhcharpos = 0; ! _doputchar('\r'); ! _doputchar(c); ! return; ! } else if (c == '\b') { ! if (bhcharpos) ! bhcharpos--; ! _doputchar(c); ! return; } ! ! bhcharpos++; ! _doputchar(c); } /* * kernel character input functions */ --- 1022,1248 ---- { return (inb(port + LSR) & RCA); } static void ! btem_control(btem_state_t *btem, int c) { ! int y, rows, cols; ! ! rows = fb_info.cursor.pos.y; ! cols = fb_info.cursor.pos.x; ! ! btem->btem_state = A_STATE_START; ! switch (c) { ! case A_BS: ! bcons_dev.bd_setpos(rows, cols - 1); ! break; ! ! case A_HT: ! cols += 8 - (cols % 8); ! if (cols == fb_info.terminal.x) ! cols = fb_info.terminal.x - 1; ! bcons_dev.bd_setpos(rows, cols); ! break; ! ! case A_CR: ! bcons_dev.bd_setpos(rows, 0); ! break; ! ! case A_FF: ! for (y = 0; y < fb_info.terminal.y; y++) { ! bcons_dev.bd_setpos(y, 0); ! bcons_dev.bd_eraseline(); ! } ! bcons_dev.bd_setpos(0, 0); ! break; ! ! case A_ESC: ! btem->btem_state = A_STATE_ESC; ! break; ! ! default: ! bcons_dev.bd_putchar(c); ! break; ! } ! } ! ! /* ! * if parameters [0..count - 1] are not set, set them to the value ! * of newparam. ! */ ! static void ! btem_setparam(btem_state_t *btem, int count, int newparam) ! { ! int i; ! ! for (i = 0; i < count; i++) { ! if (btem->btem_params[i] == -1) ! btem->btem_params[i] = newparam; ! } ! } ! ! static void ! btem_chkparam(btem_state_t *btem, int c) ! { ! int rows, cols; ! ! rows = fb_info.cursor.pos.y; ! cols = fb_info.cursor.pos.x; ! switch (c) { ! case '@': /* insert char */ ! btem_setparam(btem, 1, 1); ! bcons_dev.bd_shift(btem->btem_params[0]); ! break; ! ! case 'A': /* cursor up */ ! btem_setparam(btem, 1, 1); ! bcons_dev.bd_setpos(rows - btem->btem_params[0], cols); ! break; ! ! case 'B': /* cursor down */ ! btem_setparam(btem, 1, 1); ! bcons_dev.bd_setpos(rows + btem->btem_params[0], cols); ! break; ! ! case 'C': /* cursor right */ ! btem_setparam(btem, 1, 1); ! bcons_dev.bd_setpos(rows, cols + btem->btem_params[0]); ! break; ! ! case 'D': /* cursor left */ ! btem_setparam(btem, 1, 1); ! bcons_dev.bd_setpos(rows, cols - btem->btem_params[0]); ! break; ! ! case 'K': ! bcons_dev.bd_eraseline(); ! break; ! default: ! /* bcons_dev.bd_putchar(c); */ ! break; ! } ! btem->btem_state = A_STATE_START; ! } ! ! static void ! btem_getparams(btem_state_t *btem, int c) ! { ! if (c >= '0' && c <= '9') { ! btem->btem_paramval = btem->btem_paramval * 10 + c - '0'; ! btem->btem_gotparam = B_TRUE; ! return; ! } ! ! if (btem->btem_curparam < BTEM_MAXPARAMS) { ! if (btem->btem_gotparam == B_TRUE) { ! btem->btem_params[btem->btem_curparam] = ! btem->btem_paramval; ! } ! btem->btem_curparam++; ! } ! ! if (c == ';') { ! /* Restart parameter search */ ! btem->btem_gotparam = B_FALSE; ! btem->btem_paramval = 0; ! } else { ! btem_chkparam(btem, c); ! } ! } ! ! /* Simple boot terminal parser. */ ! static void ! btem_parse(btem_state_t *btem, int c) ! { ! int i; ! ! /* Normal state? */ ! if (btem->btem_state == A_STATE_START) { ! if (c == A_CSI || c < ' ') ! btem_control(btem, c); ! else ! bcons_dev.bd_putchar(c); ! return; ! } ! ! /* In <ESC> sequence */ ! if (btem->btem_state != A_STATE_ESC) { ! btem_getparams(btem, c); ! return; ! } ! ! /* Previous char was <ESC> */ ! switch (c) { ! case '[': ! btem->btem_curparam = 0; ! btem->btem_paramval = 0; ! btem->btem_gotparam = B_FALSE; ! /* clear the parameters */ ! for (i = 0; i < BTEM_MAXPARAMS; i++) ! btem->btem_params[i] = -1; ! btem->btem_state = A_STATE_CSI; ! return; ! ! case 'Q': /* <ESC>Q */ ! case 'C': /* <ESC>C */ ! btem->btem_state = A_STATE_START; ! return; ! ! default: ! btem->btem_state = A_STATE_START; ! break; ! } ! ! if (c < ' ') ! btem_control(btem, c); ! else ! bcons_dev.bd_putchar(c); ! } ! ! static void ! _doputchar(int device, int c) ! { ! switch (device) { case CONS_TTY: serial_putchar(c); return; case CONS_SCREEN_TEXT: ! case CONS_FRAMEBUFFER: ! bcons_dev.bd_cursor(B_FALSE); ! btem_parse(&boot_tem, c); ! bcons_dev.bd_cursor(B_TRUE); return; case CONS_SCREEN_GRAPHICS: #if !defined(_BOOT) case CONS_USBSER: defcons_putchar(c); #endif /* _BOOT */ + default: return; } } void bcons_putchar(int c) { #if defined(__xpv) if (!DOMAIN_IS_INITDOMAIN(xen_info) || console == CONS_HYPERVISOR) { bcons_putchar_xen(c); return; } #endif /* __xpv */ ! if (c == '\n') { ! _doputchar(console, '\r'); ! if (diag != console) ! _doputchar(diag, '\r'); } ! _doputchar(console, c); ! if (diag != console) ! _doputchar(diag, c); } /* * kernel character input functions */
*** 969,1002 **** if (!DOMAIN_IS_INITDOMAIN(xen_info) || console == CONS_HYPERVISOR) return (bcons_getchar_xen()); #endif /* __xpv */ ! switch (console) { ! case CONS_TTY: return (serial_getchar()); ! default: return (kb_getchar()); } } #if !defined(_BOOT) int bcons_ischar(void) { #if defined(__xpv) if (!DOMAIN_IS_INITDOMAIN(xen_info) || console == CONS_HYPERVISOR) return (bcons_ischar_xen()); #endif /* __xpv */ switch (console) { case CONS_TTY: return (serial_ischar()); default: return (kb_ischar()); } } #endif /* _BOOT */ --- 1253,1311 ---- if (!DOMAIN_IS_INITDOMAIN(xen_info) || console == CONS_HYPERVISOR) return (bcons_getchar_xen()); #endif /* __xpv */ ! for (;;) { ! if (console == CONS_TTY || diag == CONS_TTY) { ! if (serial_ischar()) return (serial_getchar()); ! } ! if (console != CONS_INVALID || diag != CONS_INVALID) { ! if (kb_ischar()) return (kb_getchar()); } + } } #if !defined(_BOOT) int bcons_ischar(void) { + int c = 0; #if defined(__xpv) if (!DOMAIN_IS_INITDOMAIN(xen_info) || console == CONS_HYPERVISOR) return (bcons_ischar_xen()); #endif /* __xpv */ switch (console) { case CONS_TTY: + c = serial_ischar(); + break; + + case CONS_INVALID: + break; + + default: + c = kb_ischar(); + } + if (c != 0) + return (c); + + switch (diag) { + case CONS_TTY: return (serial_ischar()); + + case CONS_INVALID: + break; + default: return (kb_ischar()); } + + return (c); } #endif /* _BOOT */