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,17 +26,20 @@
*/
#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,20 +58,46 @@
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;
+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,71 +119,10 @@
*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)
{
@@ -201,17 +169,19 @@
/* 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,63 +573,209 @@
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)
{
- 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
+ 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
- /*
- * 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;
+ if (cons_str != NULL)
+ console = lookup_console_devices(cons_str);
- 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.
*/
@@ -713,10 +829,12 @@
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,14 +851,13 @@
#endif
case CONS_SCREEN_GRAPHICS:
kb_init();
break;
case CONS_SCREEN_TEXT:
+ boot_vga_init(&bcons_dev);
+ /* Fall through */
default:
-#if defined(_BOOT)
- clear_screen(); /* clears the grub or xen screen */
-#endif /* _BOOT */
kb_init();
break;
}
}
@@ -905,60 +1022,227 @@
{
return (inb(port + LSR) & RCA);
}
static void
-_doputchar(int c)
+btem_control(btem_state_t *btem, int c)
{
- switch (console) {
+ 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:
- screen_putchar(c);
+ 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)
{
- 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;
+ if (c == '\n') {
+ _doputchar(console, '\r');
+ if (diag != console)
+ _doputchar(diag, '\r');
}
-
- bhcharpos++;
- _doputchar(c);
+ _doputchar(console, c);
+ if (diag != console)
+ _doputchar(diag, c);
}
/*
* kernel character input functions
*/
@@ -969,34 +1253,59 @@
if (!DOMAIN_IS_INITDOMAIN(xen_info) ||
console == CONS_HYPERVISOR)
return (bcons_getchar_xen());
#endif /* __xpv */
- switch (console) {
- case CONS_TTY:
+ for (;;) {
+ if (console == CONS_TTY || diag == CONS_TTY) {
+ if (serial_ischar())
return (serial_getchar());
- default:
+ }
+ 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 */