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