[PATCH] Framebuffer support for initial and later console.

13 views
Skip to first unread message

Himanshu Chauhan

unread,
Feb 21, 2021, 12:24:16 AM2/21/21
to xvisor...@googlegroups.com, Himanshu Chauhan
In UEFI case, the grub can hand over the console in FB mode
than the text case. This patch adds supports to take over
the console in FB mode from GRUB. It can choose to stay
with same configuration or switch to generic FB driver.

Signed-off-by: Himanshu Chauhan <hcha...@xvisor-x86.org>
---
.../board/common/devices/serial/objects.mk | 24 +
arch/x86/board/common/devices/serial/serial.c | 277 +++++++
.../board/common/devices/video/fb_console.c | 369 ++++++++++
.../x86/board/common/devices/video/objects.mk | 26 +
arch/x86/board/common/devices/video/svga.c | 79 ++
arch/x86/board/common/devices/video/vga.c | 401 ++++++++++
arch/x86/board/common/include/brd_defterm.h | 50 ++
arch/x86/board/common/include/serial.h | 30 +
.../board/common/include/video/fb_console.h | 34 +
arch/x86/board/common/include/video/svga.h | 66 ++
.../x86/board/common/include/video/ter-i16b.h | 266 +++++++
.../x86/board/common/include/video/ter-i16n.h | 267 +++++++
arch/x86/board/common/include/video/vga.h | 32 +
arch/x86/board/x86_64_generic/brd_defterm.c | 684 +-----------------
14 files changed, 1961 insertions(+), 644 deletions(-)
create mode 100644 arch/x86/board/common/devices/serial/objects.mk
create mode 100644 arch/x86/board/common/devices/serial/serial.c
create mode 100644 arch/x86/board/common/devices/video/fb_console.c
create mode 100644 arch/x86/board/common/devices/video/objects.mk
create mode 100644 arch/x86/board/common/devices/video/svga.c
create mode 100644 arch/x86/board/common/devices/video/vga.c
create mode 100644 arch/x86/board/common/include/brd_defterm.h
create mode 100644 arch/x86/board/common/include/serial.h
create mode 100644 arch/x86/board/common/include/video/fb_console.h
create mode 100644 arch/x86/board/common/include/video/svga.h
create mode 100644 arch/x86/board/common/include/video/ter-i16b.h
create mode 100644 arch/x86/board/common/include/video/ter-i16n.h
create mode 100644 arch/x86/board/common/include/video/vga.h

diff --git a/arch/x86/board/common/devices/serial/objects.mk b/arch/x86/board/common/devices/serial/objects.mk
new file mode 100644
index 00000000..39161d3c
--- /dev/null
+++ b/arch/x86/board/common/devices/serial/objects.mk
@@ -0,0 +1,24 @@
+#/**
+# Copyright (c) 2021 Himanshu Chauhan.
+# All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+# @file objects.mk
+# @author Himanshu Chauhan (hcha...@xvisor-x86.org)
+# @brief list of board specific objects to be build
+# */
+
+board-common-objs-y+= devices/serial/serial.o
diff --git a/arch/x86/board/common/devices/serial/serial.c b/arch/x86/board/common/devices/serial/serial.c
new file mode 100644
index 00000000..d2115371
--- /dev/null
+++ b/arch/x86/board/common/devices/serial/serial.c
@@ -0,0 +1,277 @@
+/**
+ * Copyright (c) 2021 Himanshu Chauhan.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * @file serial.c
+ * @author Himanshu Chauhan (hcha...@xvisor-x86.org)
+ * @brief Serial console
+ */
+
+#include <vmm_types.h>
+#include <vmm_error.h>
+#include <vmm_compiler.h>
+#include <vmm_host_io.h>
+#include <vmm_host_aspace.h>
+#include <vmm_completion.h>
+#include <vmm_params.h>
+#include <libs/vtemu.h>
+#include <libs/fifo.h>
+#include <drv/input.h>
+#include <brd_defterm.h>
+#include <drv/serial/8250-uart.h>
+
+#if defined(CONFIG_SERIAL_8250_UART)
+
+static struct uart_8250_port uart8250_port;
+
+static int parse_early_serial_options(char *options, physical_addr_t *addr,
+ u32 *baud, u32 *clock)
+{
+ char *opt_token, *opt_save;
+ const char *opt_delim = ",";
+ u32 opt_tok_len;
+ u32 opt_number = 0;
+ char *token;
+
+ *addr = 0x3f8;
+ *baud = 115200;
+ *clock = 24000000;
+
+ for (opt_token = strtok_r(options, opt_delim,
+ &opt_save); opt_token;
+ opt_token = strtok_r(NULL, opt_delim,
+ &opt_save)) {
+
+ /* @,11520,24000000 -> @, is empty */
+ opt_tok_len = strlen(opt_token);
+
+ /* Empty */
+ if (!opt_tok_len) {
+ opt_number++;
+ continue;
+ }
+
+ token = skip_spaces(opt_token);
+
+ switch(opt_number) {
+ case 0:
+ *addr = (physical_addr_t)strtoull(token, NULL, 16);
+
+ /* Port mnenomics */
+ if (*addr == 0) {
+ *addr = 0x3f8;
+ } else if (*addr == 1) {
+ *addr = 0x2f8;
+ }
+
+ opt_number++;
+ break;
+
+ case 1:
+ *baud = strtoul(token, NULL, 10);
+ opt_number++;
+ break;
+
+ case 2:
+ *clock = strtoul(token, NULL, 10);
+ opt_number++;
+ break;
+ }
+ }
+
+ return VMM_OK;
+}
+
+static int uart8250_defterm_putc(u8 ch)
+{
+ if (!uart_8250_lowlevel_can_putc(&uart8250_port)) {
+ return VMM_EFAIL;
+ }
+ uart_8250_lowlevel_putc(&uart8250_port, ch);
+ return VMM_OK;
+}
+
+static int setup_early_serial_console(physical_addr_t addr, u32 baud, u32 clock)
+{
+ uart8250_port.base = addr;
+ uart8250_port.input_clock = clock;
+ uart8250_port.baudrate = baud;
+ uart8250_port.reg_shift = 2;
+ uart8250_port.reg_width = 1;
+
+ uart_8250_lowlevel_init(&uart8250_port);
+
+ early_putc = &uart8250_defterm_putc;
+
+ return VMM_OK;
+}
+
+/* earlyprint=serial@<addr>,<baudrate> */
+int init_early_serial_console(char *setup_string)
+{
+ char *port_token, *port_save;
+ const char *port_delim = "@";
+ u32 centry = 0, found = 0, port_tok_len, check_len;
+ physical_addr_t addr;
+ u32 baud, clock;
+
+ for (port_token = strtok_r(setup_string, port_delim,
+ &port_save); port_token;
+ port_token = strtok_r(NULL, port_delim,
+ &port_save)) {
+ port_tok_len = strlen(port_token);
+ if (!centry) {
+
+ check_len = (strlen(SERIAL_CONSOLE_NAME) > port_tok_len
+ ? port_tok_len
+ : strlen(SERIAL_CONSOLE_NAME));
+
+ if (!strncmp(setup_string, SERIAL_CONSOLE_NAME,
+ check_len))
+ found = 1;
+ } else {
+ if (found) {
+ if (parse_early_serial_options(port_token,
+ &addr, &baud,
+ &clock) != VMM_OK) {
+ return VMM_EFAIL;
+ }
+ setup_early_serial_console(addr, baud, clock);
+ found = 0;
+ return VMM_OK;
+ }
+ }
+ centry++;
+ }
+
+ return VMM_EFAIL;
+}
+
+static int uart8250_defterm_getc(u8 *ch)
+{
+ if (!uart_8250_lowlevel_can_getc(&uart8250_port)) {
+ return VMM_EFAIL;
+ }
+ *ch = uart_8250_lowlevel_getc(&uart8250_port);
+ return VMM_OK;
+}
+
+static int __init uart8250_defterm_init(void)
+{
+ uart_8250_lowlevel_init(&uart8250_port);
+
+ return VMM_OK;
+}
+
+static struct defterm_ops uart8250_ops = {
+ .putc = uart8250_defterm_putc,
+ .getc = uart8250_defterm_getc,
+ .init = uart8250_defterm_init
+};
+
+/*-------------- UART DEFTERM --------------- */
+static struct vmm_devtree_nodeid defterm_devid_table[] = {
+ { .compatible = "ns8250", .data = &uart8250_ops },
+ { .compatible = "ns16450", .data = &uart8250_ops },
+ { .compatible = "ns16550a", .data = &uart8250_ops },
+ { .compatible = "ns16550", .data = &uart8250_ops },
+ { .compatible = "ns16750", .data = &uart8250_ops },
+ { .compatible = "ns16850", .data = &uart8250_ops },
+ { /* end of list */ },
+};
+
+struct defterm_ops *get_serial_defterm_ops(void *data)
+{
+ int rc;
+ const char *attr = NULL;
+ struct vmm_devtree_node *node;
+ const struct vmm_devtree_nodeid *nodeid;
+ struct defterm_ops *ops = NULL;
+ physical_addr_t addr;
+ char *cmdline_console_string = (char *)data;
+
+ /* Find choosen console node */
+ node = vmm_devtree_getnode(VMM_DEVTREE_PATH_SEPARATOR_STRING
+ VMM_DEVTREE_CHOSEN_NODE_NAME);
+ if (!node) {
+ return NULL;
+ }
+
+ if (!strcmp(cmdline_console_string, "serial@0"))
+ attr = SERIAL0_CONFIG_DTS_PATH;
+ else if (!strcmp(cmdline_console_string, "serial@1"))
+ attr = SERIAL1_CONFIG_DTS_PATH;
+
+ rc = vmm_devtree_setattr(node, VMM_DEVTREE_CONSOLE_ATTR_NAME,
+ (void *)attr, VMM_DEVTREE_ATTRTYPE_STRING,
+ strlen(attr)+1, FALSE);
+
+ rc = vmm_devtree_read_string(node,
+ VMM_DEVTREE_CONSOLE_ATTR_NAME, &attr);
+ vmm_devtree_dref_node(node);
+ if (rc) {
+ return NULL;
+ }
+
+ node = vmm_devtree_getnode(attr);
+ if (!node) {
+ return NULL;
+ }
+
+ /* Find appropriate defterm ops */
+ nodeid = vmm_devtree_match_node(defterm_devid_table, node);
+
+ if (!nodeid)
+ return NULL;
+
+ ops = (struct defterm_ops *)nodeid->data;
+
+ if (vmm_devtree_read_physaddr(node,
+ VMM_DEVTREE_REG_ATTR_NAME,
+ &addr) == VMM_OK) {
+ uart8250_port.base = (virtual_addr_t)addr;
+ }
+
+ rc = vmm_devtree_clock_frequency(node,
+ &uart8250_port.input_clock);
+ if (rc) {
+ return NULL;
+ }
+
+ if (vmm_devtree_read_u32(node, "baudrate",
+ &uart8250_port.baudrate)) {
+ uart8250_port.baudrate = 115200;
+ }
+
+ if (vmm_devtree_read_u32(node, "reg-shift",
+ &uart8250_port.reg_shift)) {
+ uart8250_port.reg_shift = 2;
+ }
+
+ if (vmm_devtree_read_u32(node, "reg-io-width",
+ &uart8250_port.reg_width)) {
+ uart8250_port.reg_width = 1;
+ }
+
+ return ops;
+}
+#else
+struct defterm_ops *get_uart8250_defterm_ops(void)
+{
+ return NULL;
+}
+#endif
diff --git a/arch/x86/board/common/devices/video/fb_console.c b/arch/x86/board/common/devices/video/fb_console.c
new file mode 100644
index 00000000..30063ee6
--- /dev/null
+++ b/arch/x86/board/common/devices/video/fb_console.c
@@ -0,0 +1,369 @@
+/**
+ * Copyright (c) 2021 Himanshu Chauhan.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * @file fb_console.c
+ * @author Himanshu Chauhan (hcha...@xvisor-x86.org)
+ * @brief Framebuffer console.
+ */
+
+#include <vmm_types.h>
+#include <libs/fifo.h>
+#include <vmm_error.h>
+#include <vmm_compiler.h>
+#include <vmm_host_io.h>
+#include <vmm_host_aspace.h>
+#include <vmm_completion.h>
+#include <vmm_params.h>
+#include <libs/vtemu.h>
+#include <drv/input.h>
+#include <video/fb_console.h>
+#include <video/svga.h>
+#include <video/ter-i16b.h>
+#include <video/ter-i16n.h>
+#include <brd_defterm.h>
+#include <multiboot.h>
+
+#if defined(CONFIG_VTEMU)
+
+static struct fifo *fb_fifo;
+static struct vmm_completion fb_fifo_cmpl;
+static u32 fb_key_flags;
+static struct input_handler fb_hndl;
+static bool fb_key_handler_registered;
+
+//static void fb_console_putpixel_24bpp(u8* screen, int x, int y, u32 color);
+static void fb_console_scroll_up(unsigned int num_rows);
+
+/* Pointers to fonts */
+static u8 *font_reg, *font_bold;
+/* Video mode info */
+static u16 width, height, depth, bytesPerLine;
+static void *video_base;//, video_size;
+/* Cursor location (in text cells) */
+static u16 col, row;
+/* Set by escape sequences */
+static u8 fg_colour, bg_colour;
+/* Used to parse escape codes */
+static bool next_char_is_escape_seq, is_bold;
+
+/* Colour code -> 16bpp */
+static u32 fb_console_col_map[16] = {
+ 0x000000, 0x0000AA, 0x00AA00, 0x00AAAA,
+ 0xAA0000, 0xAA00AA, 0xAA5500, 0xAAAAAA,
+
+ 0x555555, 0x5555FF, 0x55FF55, 0x55FFFF,
+ 0xFF5555, 0xFF55FF, 0xFFFF55, 0xFFFFFF
+};
+
+static void memclr(void *area, u32 size)
+{
+ memset(area, 0, size);
+}
+
+static int fb_key_event(struct input_handler *ihnd,
+ struct input_dev *idev,
+ unsigned int type, unsigned int code, int value)
+{
+ int rc, i, len;
+ char str[16];
+ u32 key_flags;
+
+ if (value) { /* value=1 (key-up) or value=2 (auto-repeat) */
+ /* Update input key flags */
+ key_flags = vtemu_key2flags(code);
+ if ((key_flags & VTEMU_KEYFLAG_LOCKS) &&
+ (fb_key_flags & key_flags)) {
+ fb_key_flags &= ~key_flags;
+ } else {
+ fb_key_flags |= key_flags;
+ }
+
+ /* Retrive input key string */
+ rc = vtemu_key2str(code, fb_key_flags, str);
+ if (rc) {
+ return VMM_OK;
+ }
+
+ /* Add input key string to input buffer */
+ len = strlen(str);
+ for (i = 0; i < len; i++) {
+ fifo_enqueue(fb_fifo, &str[i], TRUE);
+ vmm_completion_complete(&fb_fifo_cmpl);
+ }
+ } else { /* value=0 (key-down) */
+ /* Update input key flags */
+ key_flags = vtemu_key2flags(code);
+ if (!(key_flags & VTEMU_KEYFLAG_LOCKS)) {
+ fb_key_flags &= ~key_flags;
+ }
+ }
+
+ return VMM_OK;
+}
+
+int fb_defterm_getc(u8 *ch)
+{
+ int rc;
+
+ if (!fb_key_handler_registered) {
+ memset(&fb_hndl, 0, sizeof(fb_hndl));
+ fb_hndl.name = "fbterm";
+ fb_hndl.evbit[0] |= BIT_MASK(EV_KEY);
+ fb_hndl.event = fb_key_event;
+ fb_hndl.priv = NULL;
+
+ rc = input_register_handler(&fb_hndl);
+ if (rc) {
+ return rc;
+ }
+
+ rc = input_connect_handler(&fb_hndl);
+ if (rc) {
+ return rc;
+ }
+
+ fb_key_handler_registered = TRUE;
+ }
+
+ if (fb_fifo) {
+ /* Assume that we are always called from
+ * Orphan (or Thread) context hence we can
+ * sleep waiting for input characters.
+ */
+ vmm_completion_wait(&fb_fifo_cmpl);
+
+ /* Try to dequeue from defterm fifo */
+ if (!fifo_dequeue(fb_fifo, ch)) {
+ return VMM_ENOTAVAIL;
+ }
+
+ return VMM_OK;
+ }
+
+ return VMM_EFAIL;
+}
+
+extern struct multiboot_info boot_info;
+
+/*
+ * Initialises the framebuffer console
+ */
+int fb_defterm_init(void)
+{
+ vmm_printf("%s: init\n", __func__);
+ svga_mode_info_t *svga_mode_info;
+
+ fb_fifo = fifo_alloc(sizeof(u8), 128);
+ if (!fb_fifo) {
+ vmm_printf("%s: No memory for fifo\n", __func__);
+ return VMM_ENOMEM;
+ }
+ INIT_COMPLETION(&fb_fifo_cmpl);
+
+ fb_key_flags = 0;
+ fb_key_handler_registered = FALSE;
+
+ svga_mode_info = svga_mode_get_info(SVGA_DEFAULT_MODE);
+ //vmm_printf("%s: svga mode: 0x%lx\n", __func__, (unsigned long)svga_mode_info);
+ //bytesPerLine = svga_mode_info->pitch;
+ //width = svga_mode_info->screen_width;
+ //height = svga_mode_info->screen_height;
+ //depth = svga_mode_info->bpp / 8;
+ bytesPerLine = boot_info.framebuffer_pitch;
+ width = boot_info.framebuffer_width;
+ height = boot_info.framebuffer_height;
+ depth = boot_info.framebuffer_bpp/8;
+ vmm_printf("%s: BPL: %d width: %d height: %d depth: %d\n", __func__,
+ bytesPerLine, width, height, depth);
+
+ //video_base = (void *)svga_map_fb(svga_mode_info->physbase, svga_mode_info->pitch * svga_mode_info->screen_height);
+ video_base = (void*)svga_map_fb(boot_info.framebuffer_addr, bytesPerLine*height);
+ vmm_printf("%s: Video base: %p\n", __func__, video_base);
+ fb_console_set_font(&ter_i16n_raw, &ter_i16b_raw);
+
+ /* Clear screen */
+ memclr((void *) video_base, bytesPerLine * height);
+
+ is_bold = false;
+ next_char_is_escape_seq = false;
+ fg_colour = 0x0F;
+ bg_colour = 0x00;
+
+ col = row = 0;
+
+ return VMM_OK;
+}
+
+/*
+ * Handles the character as a control character.
+ */
+void fb_console_control(unsigned char c)
+{
+ switch(c) {
+ case '\n':
+ col = 0;
+ /* We're on the last row, a newline should only scroll the viewport up */
+ if(row == (height / CHAR_HEIGHT)-1) {
+ fb_console_scroll_up(1);
+ } else {
+ row++;
+ }
+
+ break;
+
+ default:
+ break;
+ }
+}
+
+/*
+ * Prints a character to the framebuffer console.
+ */
+int fb_defterm_putc(unsigned char c)
+{
+ if (c == '\n') {
+ fb_console_control('\n');
+ return VMM_OK;
+ }
+
+ if(c == 0x01) {
+ next_char_is_escape_seq = true;
+ return VMM_OK;
+ }
+
+ /* Check if the following character is part of an escape sequence */
+ if(next_char_is_escape_seq) {
+ /* Codes 0x00 to 0x0F are colours */
+ if(c >= 0x00 && c <= 0x0F) {
+ fg_colour = c;
+ next_char_is_escape_seq = false;
+ } else if(c == 0x10 || c == 0x11) {
+ is_bold = (c == 0x11) ? true : false;
+
+ next_char_is_escape_seq = false;
+ } else {
+ next_char_is_escape_seq = false;
+ }
+ } else { /* Handle printing of a regular character */
+ /* Characters are 16 px tall, i.e. 0x10 bytes in stored rep */
+ u8 *read_ptr = (u8 *) ((is_bold) ? font_bold : font_reg) + (c * CHAR_HEIGHT);
+ u32 *write_base;
+
+ const u8 x_to_bitmap[CHAR_WIDTH] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
+ u8 fontChar = 0;
+ u32 out = 0;
+
+ for(u8 y = 0; y < CHAR_HEIGHT; y++) {
+ fontChar = read_ptr[y];
+
+ /* Process one column at a time */
+ if(depth == 4) {
+ write_base = (u32 *) (video_base) + (((bytesPerLine / 4) * CHAR_HEIGHT * row)) + (CHAR_WIDTH * col);
+
+ for(u8 x = 0; x < CHAR_WIDTH; x++) {
+ if(x_to_bitmap[x] & fontChar) {
+ write_base[x+(y * (bytesPerLine / 4))] = fb_console_col_map[fg_colour];
+ }
+ }
+ } else if(depth == 2) {
+ write_base = (u32 *) (video_base) + (((bytesPerLine / 4) * CHAR_HEIGHT * row)) + ((CHAR_WIDTH * (col)) >> 1);
+
+ /* In 16bpp, process two pixels at once */
+ for(u8 x = 0; x < CHAR_WIDTH; x+=2) {
+ out = 0;
+
+ if(x_to_bitmap[x] & fontChar) {
+ out = ((SVGA_24TO16BPP(fb_console_col_map[fg_colour])) & 0xFFFF) << 16;
+ }
+
+ if(x_to_bitmap[x+1] & fontChar) {
+ out |= ((SVGA_24TO16BPP(fb_console_col_map[fg_colour])) & 0xFFFF);
+ }
+
+ write_base[(x >> 1) + (y * (bytesPerLine / 4))] = out;
+ }
+ }
+ }
+
+ /* Increment column and check row */
+ col++;
+
+ if(col > (width / CHAR_WIDTH)) {
+ fb_console_control('\n');
+ }
+ }
+
+ return VMM_OK;
+}
+
+/*
+ * Sets the regular and bold fonts. If a font pointer is NULL, it is ignored.
+ */
+void fb_console_set_font(void* reg, void* bold)
+{
+ if(reg) font_reg = reg;
+ if(bold) font_bold = bold;
+}
+
+/*
+ * Scrolls the display up number of rows
+ */
+static void fb_console_scroll_up(unsigned int num_rows)
+{
+ /* Copy rows upwards */
+ u8 *read_ptr = (u8 *) video_base + ((num_rows * CHAR_HEIGHT) * bytesPerLine);
+ u8 *write_ptr = (u8 *) video_base;
+ unsigned int num_bytes = (bytesPerLine * height) - (bytesPerLine * (num_rows * CHAR_HEIGHT));
+ memcpy(write_ptr, read_ptr, num_bytes);
+
+ /* Clear the rows at the end */
+ read_ptr = (u8 *)(video_base + (bytesPerLine * height) - (bytesPerLine * (num_rows * CHAR_HEIGHT)));
+ memclr(read_ptr, bytesPerLine * (num_rows * CHAR_HEIGHT));
+}
+
+#if 0
+/*
+ * Plots a pixel in 24bpp mode.
+ */
+static void fb_console_putpixel_24bpp(u8* screen, int x, int y, u32 color)
+{
+ int where = (x * depth) + (y * bytesPerLine);
+ screen[where] = color & 255; // BLUE
+ screen[where + 1] = (color >> 8) & 255; // GREEN
+ screen[where + 2] = (color >> 16) & 255; // RED
+}
+#endif
+
+static struct defterm_ops fb_ops = {
+ .putc = fb_defterm_putc,
+ .getc = fb_defterm_getc,
+ .init = fb_defterm_init
+};
+
+struct defterm_ops *get_fb_defterm_ops(void *data)
+{
+ return &fb_ops;
+}
+
+#else /* !CONFIG_VT_EMU */
+
+struct defterm_ops *get_fb_defterm_ops(void *data)
+{
+ return NULL;
+}
+#endif
diff --git a/arch/x86/board/common/devices/video/objects.mk b/arch/x86/board/common/devices/video/objects.mk
new file mode 100644
index 00000000..17217df2
--- /dev/null
+++ b/arch/x86/board/common/devices/video/objects.mk
@@ -0,0 +1,26 @@
+#/**
+# Copyright (c) 2021 Himanshu Chauhan.
+# All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+# @file objects.mk
+# @author Himanshu Chauhan (hcha...@xvisor-x86.org)
+# @brief list of board specific objects to be build
+# */
+
+board-common-objs-y+= devices/video/vga.o
+board-common-objs-y+= devices/video/svga.o
+board-common-objs-y+= devices/video/fb_console.o
diff --git a/arch/x86/board/common/devices/video/svga.c b/arch/x86/board/common/devices/video/svga.c
new file mode 100644
index 00000000..006f6d50
--- /dev/null
+++ b/arch/x86/board/common/devices/video/svga.c
@@ -0,0 +1,79 @@
+/**
+ * Copyright (c) 2021 Himanshu Chauhan.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * @file svga.c
+ * @author Himanshu Chauhan (hcha...@xvisor-x86.org)
+ * @brief SVGA initialization
+ */
+
+#include <vmm_types.h>
+#include <vmm_error.h>
+#include <vmm_compiler.h>
+#include <vmm_host_io.h>
+#include <vmm_host_aspace.h>
+#include <vmm_completion.h>
+#include <vmm_params.h>
+#include <libs/vtemu.h>
+#include <libs/fifo.h>
+#include <drv/input.h>
+#include <multiboot.h>
+#include <brd_defterm.h>
+#include <video/svga.h>
+
+extern struct multiboot_info boot_info;
+svga_mode_info_t svga_mode_info;
+
+/*
+ * Switches the SVGA mode to the specified mode number.
+ */
+void svga_change_mode(u16 mode)
+{
+ vmm_printf("Changing SVGA mode not supported (mode = 0x%X)\n", mode);
+}
+
+/*
+ * Returns a pointer to the info struct about a certain SVGA mode.
+ */
+svga_mode_info_t* svga_mode_get_info(u16 mode)
+{
+ return &svga_mode_info;
+}
+
+/*
+ * Requests the physical frame buffer address be mapped at the logical frame
+ * buffer address.
+ *
+ * This function will map fb_length bytes.
+ *
+ * On success, it returns the virtual address where the framebuffer was mapped,
+ * or 0 on failure.
+ */
+virtual_addr_t svga_map_fb(physical_addr_t real_addr, virtual_size_t fb_length)
+{
+ virtual_addr_t fb_base;
+
+ /* Align framebuffer length to page boundaries */
+ fb_length = VMM_ROUNDUP2_PAGE_SIZE(fb_length);
+
+ vmm_printf("%s: physical: 0x%lx size: 0x%lx\n", __func__,
+ real_addr, fb_length);
+ fb_base = vmm_host_memmap(real_addr, fb_length,
+ VMM_MEMORY_FLAGS_IO);
+
+ return fb_base;
+}
diff --git a/arch/x86/board/common/devices/video/vga.c b/arch/x86/board/common/devices/video/vga.c
new file mode 100644
index 00000000..c01b2ffa
--- /dev/null
+++ b/arch/x86/board/common/devices/video/vga.c
@@ -0,0 +1,401 @@
+/**
+ * Copyright (c) 2021 Himanshu Chauhan.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * @file vga.c
+ * @author Himanshu Chauhan (hcha...@xvisor-x86.org)
+ * @brief text-mode VGA console as default terminal.
+ */
+
+#include <vmm_types.h>
+#include <vmm_error.h>
+#include <vmm_compiler.h>
+#include <vmm_host_io.h>
+#include <vmm_host_aspace.h>
+#include <vmm_completion.h>
+#include <vmm_params.h>
+#include <libs/vtemu.h>
+#include <libs/fifo.h>
+#include <drv/input.h>
+#include <brd_defterm.h>
+#include <video/vga.h>
+
+/*
+ * These define our textpointer, our background and foreground
+ * colors (attributes), and x and y cursor coordinates
+ */
+static u16 *textmemptr;
+static u32 attrib = 0x0E;
+static u32 csr_x = 0, csr_y = 0;
+static char esc_seq[16] = { 0 };
+static u32 esc_seq_count = 0;
+
+#if defined(CONFIG_VTEMU)
+static struct fifo *defterm_fifo;
+static struct vmm_completion defterm_fifo_cmpl;
+static u32 defterm_key_flags;
+static struct input_handler defterm_hndl;
+static bool defterm_key_handler_registered;
+#endif
+
+static u16 *memsetw(u16 *dest, u16 val, size_t count)
+{
+ u16 *temp = (u16 *)dest;
+
+ for( ; count != 0; count--) {
+ *temp++ = val;
+ }
+
+ return dest;
+}
+
+static void update_cursor(void)
+{
+ u16 pos = (csr_y * 80) + csr_x;
+
+ /* cursor LOW port to vga INDEX register */
+ vmm_outb(0x0F, 0x3D4);
+ vmm_outb((u8)(pos & 0xFF), 0x3D5);
+
+ /* cursor HIGH port to vga INDEX register */
+ vmm_outb(0x0E, 0x3D4);
+ vmm_outb((u8)((pos >> 8) & 0xFF), 0x3D5);
+}
+
+static void scroll_up_byline(void)
+{
+ u8 *dest, *src;
+ u32 copylen;
+ u32 blank, temp;
+
+ /*
+ * A blank is defined as a space... we need to give it
+ * backcolor too
+ */
+ blank = (0x20 | (attrib << 8));
+
+
+ /*
+ * Move the current text chunk that makes up the screen
+ * back in the buffer by a line.
+ */
+ temp = csr_y - 25 + 1;
+
+ dest = (u8 *)textmemptr;
+ src = (u8 *)(textmemptr + temp * 80);
+ copylen = ((25 - temp) * 80 * 2);
+
+ while (copylen) {
+ *dest = *src;
+ copylen--;
+ dest++;
+ src++;
+ }
+
+ /*
+ * Finally, we set the chunk of memory that occupies
+ * the last line of text to our 'blank' character
+ */
+ memsetw(textmemptr + (25 - temp) * 80, blank, 80);
+ csr_y = 25 - 1;
+}
+
+/* Scrolls the screen */
+void scroll(void)
+{
+ /* Row 25 is the end, this means we need to scroll up */
+ if (csr_y >= 25)
+ scroll_up_byline();
+}
+
+/* Clears the screen */
+static void cls()
+{
+ u32 i, blank;
+
+ /*
+ * Again, we need the 'short' that will be used to
+ * represent a space with color
+ */
+ blank = 0x20 | (attrib << 8);
+
+ /* Sets the entire screen to spaces in our current color */
+ for(i = 0; i < 25; i++) {
+ memsetw (textmemptr + i * 80, blank, 80);
+ }
+
+ /*
+ * Update out virtual cursor, and then move the
+ * hardware cursor
+ */
+ csr_x = 0;
+ csr_y = 0;
+}
+
+/* Puts a single character on the screen */
+int vga_putc(unsigned char c)
+{
+ u16 *where;
+ u32 att = attrib << 8;
+
+ if (esc_seq_count) {
+ esc_seq[esc_seq_count] = c;
+ esc_seq_count++;
+ if ((esc_seq_count == 2) && (esc_seq[1] == '[')) {
+ /* Do nothing */
+ } else if ((esc_seq_count == 3) &&
+ (esc_seq[1] == '[') &&
+ (esc_seq[2] == 'D')) {
+ /* Move left */
+ if (csr_x != 0) {
+ csr_x--;
+ }
+ esc_seq_count = 0;
+ } else if ((esc_seq_count == 3) &&
+ (esc_seq[1] == '[') &&
+ (esc_seq[2] == 'C')) {
+ /* Move right */
+ if (csr_x != 0) {
+ csr_x++;
+ }
+ esc_seq_count = 0;
+ } else {
+ /* Ignore unknown escape sequences */
+ esc_seq_count = 0;
+ }
+ goto done;
+ }
+
+ /* Handle a backspace, by moving the cursor back one space */
+ if (c == '\e') {
+ esc_seq_count = 1;
+ esc_seq[0] = '\e';
+ goto done;
+ } else if (c == '\b') {
+ if (csr_x != 0) {
+ csr_x--;
+ }
+ } else if (c == '\t') {
+ /*
+ * Handles a tab by incrementing the cursor's x, but only
+ * to a point that will make it divisible by 8
+ */
+ csr_x = (csr_x + 8) & ~(8 - 1);
+ } else if (c == '\r') {
+ /*
+ * Handles a 'Carriage Return', which simply brings the
+ * cursor back to the margin
+ */
+ csr_x = 0;
+ } else if (c == '\n') {
+ /*
+ * We handle our newlines the way DOS and the BIOS do: we
+ * treat it as if a 'CR' was also there, so we bring the
+ * cursor to the margin and we increment the 'y' value
+ */
+ csr_x = 0;
+ csr_y++;
+ } else if (c >= ' ') {
+ /*
+ * Any character greater than and including a space, is a
+ * printable character. The equation for finding the index
+ * in a linear chunk of memory can be represented by:
+ * Index = [(y * width) + x]
+ */
+ where = textmemptr + (csr_y * 80 + csr_x);
+ *where = c | att; /* Character AND attributes: color */
+ csr_x++;
+ }
+
+ /*
+ * If the cursor has reached the edge of the screen's width, we
+ * insert a new line in there
+ */
+ if (csr_x >= 80) {
+ csr_x = 0;
+ csr_y++;
+ }
+
+done:
+ /* Scroll the screen if needed, and finally move the cursor */
+ scroll();
+
+ /* Update cursor location */
+ update_cursor();
+
+ return 0;
+}
+
+/* Sets the forecolor and backcolor that we will use */
+void vga_settextcolor(u8 forecolor, u8 backcolor)
+{
+ /*
+ * Top 4 bytes are the background, bottom 4 bytes
+ * are the foreground color
+ */
+ attrib = (backcolor << 4) | (forecolor & 0x0F);
+}
+
+/* Sets our text-mode VGA pointer, then clears the screen for us */
+void init_vga_console(void)
+{
+ vga_settextcolor(15 /* White foreground */, 0 /* Black background */);
+ textmemptr = (u16 *)vmm_host_iomap(0xB8000, 0x4000);
+ cls();
+}
+
+int init_early_vga_console(void)
+{
+ vga_settextcolor(15 /* White foreground */, 0 /* Black background */);
+ textmemptr = (u16 *)(0xB8000UL);
+ cls();
+
+ early_putc = vga_putc;
+
+ return 0;
+}
+
+int arch_std_defterm_putc(u8 ch)
+{
+ vga_putc(ch);
+
+ return VMM_OK;
+}
+
+#if defined(CONFIG_VTEMU)
+static int defterm_key_event(struct input_handler *ihnd,
+ struct input_dev *idev,
+ unsigned int type, unsigned int code, int value)
+{
+ int rc, i, len;
+ char str[16];
+ u32 key_flags;
+
+ if (value) { /* value=1 (key-up) or value=2 (auto-repeat) */
+ /* Update input key flags */
+ key_flags = vtemu_key2flags(code);
+ if ((key_flags & VTEMU_KEYFLAG_LOCKS) &&
+ (defterm_key_flags & key_flags)) {
+ defterm_key_flags &= ~key_flags;
+ } else {
+ defterm_key_flags |= key_flags;
+ }
+
+ /* Retrive input key string */
+ rc = vtemu_key2str(code, defterm_key_flags, str);
+ if (rc) {
+ return VMM_OK;
+ }
+
+ /* Add input key string to input buffer */
+ len = strlen(str);
+ for (i = 0; i < len; i++) {
+ fifo_enqueue(defterm_fifo, &str[i], TRUE);
+ vmm_completion_complete(&defterm_fifo_cmpl);
+ }
+ } else { /* value=0 (key-down) */
+ /* Update input key flags */
+ key_flags = vtemu_key2flags(code);
+ if (!(key_flags & VTEMU_KEYFLAG_LOCKS)) {
+ defterm_key_flags &= ~key_flags;
+ }
+ }
+
+ return VMM_OK;
+}
+
+int arch_std_defterm_getc(u8 *ch)
+{
+ int rc;
+
+ if (!defterm_key_handler_registered) {
+ memset(&defterm_hndl, 0, sizeof(defterm_hndl));
+ defterm_hndl.name = "defterm";
+ defterm_hndl.evbit[0] |= BIT_MASK(EV_KEY);
+ defterm_hndl.event = defterm_key_event;
+ defterm_hndl.priv = NULL;
+
+ rc = input_register_handler(&defterm_hndl);
+ if (rc) {
+ return rc;
+ }
+
+ rc = input_connect_handler(&defterm_hndl);
+ if (rc) {
+ return rc;
+ }
+
+ defterm_key_handler_registered = TRUE;
+ }
+
+ if (defterm_fifo) {
+ /* Assume that we are always called from
+ * Orphan (or Thread) context hence we can
+ * sleep waiting for input characters.
+ */
+ vmm_completion_wait(&defterm_fifo_cmpl);
+
+ /* Try to dequeue from defterm fifo */
+ if (!fifo_dequeue(defterm_fifo, ch)) {
+ return VMM_ENOTAVAIL;
+ }
+
+ return VMM_OK;
+ }
+
+ return VMM_EFAIL;
+}
+
+int __init arch_std_defterm_init(void)
+{
+ init_vga_console();
+
+#if defined(CONFIG_VTEMU)
+ defterm_fifo = fifo_alloc(sizeof(u8), 128);
+ if (!defterm_fifo) {
+ return VMM_ENOMEM;
+ }
+ INIT_COMPLETION(&defterm_fifo_cmpl);
+
+ defterm_key_flags = 0;
+ defterm_key_handler_registered = FALSE;
+#endif
+
+ return VMM_OK;
+}
+
+static struct defterm_ops vga_ops = {
+ .putc = arch_std_defterm_putc,
+ .getc = arch_std_defterm_getc,
+ .init = arch_std_defterm_init
+};
+
+struct defterm_ops *get_vga_defterm_ops(void *data)
+{
+ return &vga_ops;
+}
+#else
+static struct defterm_ops vga_ops = {
+ .putc = arch_std_defterm_putc,
+ .getc = NULL;
+ .init = arch_std_defterm_init
+};
+struct defterm_ops *get_vga_defterm_ops(void)
+{
+ return &vga_ops
+}
+#endif
diff --git a/arch/x86/board/common/include/brd_defterm.h b/arch/x86/board/common/include/brd_defterm.h
new file mode 100644
index 00000000..5a96891a
--- /dev/null
+++ b/arch/x86/board/common/include/brd_defterm.h
@@ -0,0 +1,50 @@
+/**
+ * Copyright (c) 2021 Himanshu Chauhan.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * @file brd_defterm.h
+ * @author Himanshu Chauhan (hcha...@xvisor-x86.org)
+ * @brief Board default terminal data structures.
+ */
+
+#ifndef __BRD_DEFTERM_H
+#define __BRD_DEFTERM_H
+
+#define SERIAL_CONSOLE_NAME "serial"
+#define VGA_CONSOLE_NAME "vga"
+#define FB_CONSOLE_NAME "fb"
+
+#define SERIAL0_CONFIG_DTS_PATH "/motherboard/uart0"
+#define SERIAL1_CONFIG_DTS_PATH "/motherboard/uart1"
+#define VGA_CONFIG_DTS_PATH "/motherboard/vga"
+#define FB_CONFIG_DTS_PATH "/motherboard/fb"
+
+#define DEFAULT_CONSOLE_STR "console=vga"
+
+#define CONSOLE_SETUP_STR_LEN 1024
+
+struct defterm_ops {
+ int (*putc)(u8 ch);
+ int (*getc)(u8 *ch);
+ int (*init)(void);
+};
+
+typedef int (*EARLY_PUTC)(u8 ch);
+
+extern EARLY_PUTC early_putc;
+
+#endif /* __BRD_DEFTERM_H */
diff --git a/arch/x86/board/common/include/serial.h b/arch/x86/board/common/include/serial.h
new file mode 100644
index 00000000..77ea121b
--- /dev/null
+++ b/arch/x86/board/common/include/serial.h
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) 2021 Himanshu Chauhan.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * @file serial.h
+ * @author Himanshu Chauhan (hcha...@xvisor-x86.org)
+ * @brief UART access functions declarations
+ */
+
+#ifndef __SERIAL_H
+#define __SERIAL_H
+
+int init_early_serial_console(char *setup_string);
+struct defterm_ops *get_serial_defterm_ops(void *data);
+
+#endif
diff --git a/arch/x86/board/common/include/video/fb_console.h b/arch/x86/board/common/include/video/fb_console.h
new file mode 100644
index 00000000..33f3c6a4
--- /dev/null
+++ b/arch/x86/board/common/include/video/fb_console.h
@@ -0,0 +1,34 @@
+/**
+ * Copyright (c) 2021 Himanshu Chauhan.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * @file fb_console.h
+ * @author Himanshu Chauhan (hcha...@xvisor-x86.org)
+ * @brief Framebuffer console header file.
+ */
+
+#ifndef __FRAMEBUFFER_CONSOLE_H
+#define __FRAMEBUFFER_CONSOLE_H
+
+#define CHAR_HEIGHT 16
+#define CHAR_WIDTH 8
+
+void fb_console_set_font(void* reg, void* bold);
+
+struct defterm_ops *get_fb_defterm_ops(void *data);
+
+#endif /* __FRAMEBUFFER_CONSOLE_H */
diff --git a/arch/x86/board/common/include/video/svga.h b/arch/x86/board/common/include/video/svga.h
new file mode 100644
index 00000000..ec4ea545
--- /dev/null
+++ b/arch/x86/board/common/include/video/svga.h
@@ -0,0 +1,66 @@
+/**
+ * Copyright (c) 2021 Himanshu Chauhan.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * @file fb_console.h
+ * @author Himanshu Chauhan (hcha...@xvisor-x86.org)
+ * @brief Framebuffer console header file.
+ */
+
+#ifndef SVGA_H
+#define SVGA_H
+
+#include <vmm_types.h>
+#include <vmm_host_aspace.h>
+
+#define SVGA_DEFAULT_MODE 0x117
+
+/* RRRRR GGGGGG BBBBB */
+#define SVGA_24TO16BPP(x) ((x & 0xF80000) >> 8) | ((x & 0xFC00) >> 5) | ((x & 0xF8) >> 3)
+
+typedef struct svga_mode_info {
+ u16 attributes;
+ u8 windowA, windowB;
+ u16 granularity;
+ u16 windowSize;
+ u16 segmentA, segmentB;
+ u32 winFuncPtr; /* ptr to INT 0x10 Function 0x4F05 */
+ u16 pitch; /* bytes per scan line */
+
+ u16 screen_width, screen_height; /* resolution */
+ u8 wChar, yChar, planes, bpp, banks; /* number of banks */
+ u8 memoryModel, bankSize, imagePages;
+ u8 reserved0;
+
+ // color masks
+ u8 readMask, redPosition;
+ u8 greenMask, greenPosition;
+ u8 blueMask, bluePosition;
+ u8 reservedMask, reservedPosition;
+ u8 directColorAttributes;
+
+ u32 physbase; /* pointer to LFB in LFB modes */
+ u32 offScreenMemOff;
+ u16 offScreenMemSize;
+ u8 reserved1[206];
+} __attribute__((packed)) svga_mode_info_t;
+
+void svga_change_mode(u16);
+svga_mode_info_t* svga_mode_get_info(u16);
+virtual_addr_t svga_map_fb(physical_addr_t, virtual_size_t);
+
+#endif
diff --git a/arch/x86/board/common/include/video/ter-i16b.h b/arch/x86/board/common/include/video/ter-i16b.h
new file mode 100644
index 00000000..7f8fc5de
--- /dev/null
+++ b/arch/x86/board/common/include/video/ter-i16b.h
@@ -0,0 +1,266 @@
+/*
+ * Bold version of the 8x16 Terminus font.
+ *
+ * See http://terminus-font.sourceforge.net/ for more info.
+ */
+#include <vmm_types.h>
+
+u8 ter_i16b_raw[] = {
+ 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0x82, 0xaa, 0x82, 0x82, 0xba, 0x92, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xfe, 0xd6, 0xfe, 0xfe, 0xc6, 0xee, 0xfe, 0xfe, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x5a, 0xff, 0xff, 0x5a, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x3e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7e, 0x66, 0x7e, 0x60, 0x60, 0x60, 0x60, 0x60, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7e, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6e, 0xec, 0xc0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x18, 0xdb, 0x7e, 0x3c, 0xe7, 0x3c, 0x7e, 0xdb, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xc0, 0xf0, 0xfc, 0xff, 0xff, 0xfc, 0xf0, 0xc0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x0f, 0x3f, 0xff, 0xff, 0x3f, 0x0f, 0x03, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7e, 0xd6, 0xd6, 0xd6, 0xd6, 0x76, 0x16, 0x16, 0x16, 0x16, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x3c, 0x66, 0x60, 0x38, 0x6c, 0x66, 0x66, 0x36, 0x1c, 0x06, 0x66, 0x3c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0c, 0xfe, 0xfe, 0x0c, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x60, 0xfe, 0xfe, 0x60, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x66, 0xff, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x3c, 0x3c, 0x7e, 0x7e, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7e, 0x7e, 0x3c, 0x3c, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x10, 0x10, 0x7c, 0xd6, 0xd0, 0xd0, 0x7c, 0x16, 0x16, 0xd6, 0x7c, 0x10, 0x10, 0x00, 0x00,
+ 0x00, 0x00, 0x66, 0xd6, 0x6c, 0x0c, 0x18, 0x18, 0x30, 0x36, 0x6b, 0x66, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x38, 0xfe, 0x38, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x06, 0x06, 0x0c, 0x0c, 0x18, 0x18, 0x30, 0x30, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x06, 0x3c, 0x06, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x06, 0x0e, 0x1e, 0x36, 0x66, 0xc6, 0xfe, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfe, 0x06, 0x06, 0x0c, 0x0c, 0x18, 0x18, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xce, 0xd6, 0xd6, 0xd6, 0xd6, 0xce, 0xc0, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfc, 0xc6, 0xc6, 0xc6, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xfc, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xf8, 0xcc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xcc, 0xf8, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xf8, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xf8, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0xc6, 0xcc, 0xd8, 0xf0, 0xf0, 0xd8, 0xcc, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x82, 0xc6, 0xee, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xde, 0x7c, 0x06, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xfc, 0xf0, 0xd8, 0xcc, 0xc6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0x7c, 0x06, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x82, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x6c, 0x38, 0x38, 0x6c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfe, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x60, 0x60, 0x30, 0x30, 0x18, 0x18, 0x0c, 0x0c, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x18, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00,
+ 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x06, 0x7e, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xfc, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x06, 0x06, 0x06, 0x7e, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc0, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x1e, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x7c, 0x00,
+ 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00,
+ 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc6, 0xcc, 0xd8, 0xf0, 0xd8, 0xcc, 0xc6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xfc, 0xc0, 0xc0, 0xc0, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xf0, 0xe0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xc0, 0xc0, 0x7c, 0x06, 0x06, 0xfc, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x30, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x30, 0x1e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x7c, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x1c, 0x30, 0x30, 0x30, 0x60, 0x30, 0x30, 0x30, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0c, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x73, 0xdb, 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc6, 0xc6, 0x7c, 0x30, 0x30, 0x60, 0x00,
+ 0x00, 0x00, 0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc0, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x6c, 0x00, 0x7c, 0x06, 0x7e, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0x06, 0x7e, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x30, 0x18, 0x00, 0x7c, 0x06, 0x7e, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x6c, 0x38, 0x7c, 0x06, 0x7e, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x30, 0x30, 0x60, 0x00,
+ 0x00, 0x00, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc0, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc0, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc0, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x6c, 0x6c, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x6c, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+ 0x38, 0x6c, 0x38, 0x7c, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x30, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xf8, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x16, 0x16, 0x7e, 0xd0, 0xd0, 0x6c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xfe, 0xd8, 0xd8, 0xd8, 0xd8, 0xde, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x30, 0x18, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x7c, 0x00,
+ 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x10, 0x7c, 0xd6, 0xd0, 0xd0, 0xd0, 0xd6, 0x7c, 0x10, 0x10, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x6c, 0x60, 0x60, 0xf8, 0x60, 0x60, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xfa, 0xc6, 0xcf, 0xc6, 0xc6, 0xc3, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00,
+ 0x00, 0x00, 0x18, 0x30, 0x00, 0x7c, 0x06, 0x7e, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0c, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x30, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x76, 0xdc, 0x00, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+ 0x76, 0xdc, 0x00, 0xc6, 0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x60, 0xe0, 0x62, 0x66, 0x6c, 0x18, 0x30, 0x60, 0xdc, 0xb6, 0x0c, 0x18, 0x3e, 0x00, 0x00,
+ 0x00, 0x60, 0xe0, 0x62, 0x66, 0x6c, 0x18, 0x30, 0x66, 0xce, 0x9a, 0x3e, 0x06, 0x06, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x1b, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x1b, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00,
+ 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22,
+ 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55,
+ 0xee, 0xbb, 0xee, 0xbb, 0xee, 0xbb, 0xee, 0xbb, 0xee, 0xbb, 0xee, 0xbb, 0xee, 0xbb, 0xee, 0xbb,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x18, 0xf8, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0xec, 0xec, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xf8, 0x18, 0xf8, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0xec, 0xec, 0x0c, 0xec, 0xec, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c,
+ 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x0c, 0xec, 0xec, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c,
+ 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0xec, 0xec, 0x0c, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x18, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6f, 0x6f, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c,
+ 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6f, 0x6f, 0x60, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x60, 0x6f, 0x6f, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c,
+ 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0xef, 0xef, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xef, 0xef, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c,
+ 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6f, 0x6f, 0x60, 0x6f, 0x6f, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0xef, 0xef, 0x00, 0xef, 0xef, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c,
+ 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x18, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c,
+ 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0xff, 0xff, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0xff, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7a, 0xce, 0xcc, 0xcc, 0xcc, 0xce, 0x7a, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xc8, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xfc, 0xc0, 0xc0, 0xc0, 0x00,
+ 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfe, 0xc0, 0x60, 0x30, 0x18, 0x18, 0x30, 0x60, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xce, 0xf6, 0xc0, 0xc0, 0xc0, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0x7c, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x7c, 0x10, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7e, 0x30, 0x18, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xd6, 0xd6, 0xd6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x06, 0x0c, 0x7c, 0xce, 0xde, 0xf6, 0xe6, 0x7c, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x3e, 0x60, 0xc0, 0xfe, 0xc0, 0x60, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0e, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x78, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x38, 0x6c, 0x18, 0x30, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+unsigned int ter_i16b_raw_len = 4096;
diff --git a/arch/x86/board/common/include/video/ter-i16n.h b/arch/x86/board/common/include/video/ter-i16n.h
new file mode 100644
index 00000000..3eb3d786
--- /dev/null
+++ b/arch/x86/board/common/include/video/ter-i16n.h
@@ -0,0 +1,267 @@
+/*
+ * Regular version of the 8x16 Terminus font.
+ *
+ * See http://terminus-font.sourceforge.net/ for more info.
+ */
+#include <vmm_types.h>
+
+u8 ter_i16n_raw[] = {
+ 0x00, 0x00, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0x82, 0xaa, 0x82, 0x82, 0xba, 0x92, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xfe, 0xd6, 0xfe, 0xfe, 0xc6, 0xee, 0xfe, 0xfe, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0x38, 0x38, 0x10, 0x54, 0xfe, 0xfe, 0x54, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0x10, 0x38, 0x7c, 0xfe, 0xfe, 0x7c, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xdb, 0xdb, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x1e, 0x06, 0x0a, 0x12, 0x38, 0x44, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x44, 0x44, 0x44, 0x44, 0x38, 0x10, 0x7c, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3e, 0x22, 0x3e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xc0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7e, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x44, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x92, 0x54, 0x38, 0xee, 0x38, 0x54, 0x92, 0x10, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xc0, 0xf0, 0xfc, 0xff, 0xfc, 0xf0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x0f, 0x3f, 0xff, 0x3f, 0x0f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0x38, 0x54, 0x10, 0x10, 0x10, 0x10, 0x54, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x00, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7e, 0x92, 0x92, 0x92, 0x92, 0x72, 0x12, 0x12, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x38, 0x44, 0x40, 0x30, 0x48, 0x44, 0x44, 0x24, 0x18, 0x04, 0x44, 0x38, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0x38, 0x54, 0x10, 0x10, 0x10, 0x54, 0x38, 0x10, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0x38, 0x54, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x54, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0xfe, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x40, 0xfe, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x42, 0xff, 0x42, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x24, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x24, 0x24, 0x24, 0x7e, 0x24, 0x24, 0x7e, 0x24, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x10, 0x10, 0x7c, 0x92, 0x90, 0x90, 0x7c, 0x12, 0x12, 0x92, 0x7c, 0x10, 0x10, 0x00, 0x00,
+ 0x00, 0x00, 0x64, 0x94, 0x68, 0x08, 0x10, 0x10, 0x20, 0x2c, 0x52, 0x4c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x24, 0x24, 0x18, 0x30, 0x4a, 0x44, 0x44, 0x44, 0x3a, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x08, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x20, 0x10, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x18, 0x7e, 0x18, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x20, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x42, 0x42, 0x46, 0x4a, 0x52, 0x62, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x08, 0x18, 0x28, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x42, 0x42, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x42, 0x42, 0x02, 0x1c, 0x02, 0x02, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x02, 0x06, 0x0a, 0x12, 0x22, 0x42, 0x7e, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x7c, 0x02, 0x02, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x1c, 0x20, 0x40, 0x40, 0x7c, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7e, 0x02, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x3e, 0x02, 0x02, 0x04, 0x38, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x10, 0x10, 0x20, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x04, 0x08, 0x10, 0x20, 0x40, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x20, 0x10, 0x08, 0x04, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x04, 0x08, 0x08, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0x82, 0x9e, 0xa2, 0xa2, 0xa2, 0xa6, 0x9a, 0x80, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0x42, 0x42, 0x42, 0x7c, 0x42, 0x42, 0x42, 0x42, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x42, 0x42, 0x40, 0x40, 0x40, 0x40, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x78, 0x44, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x44, 0x78, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x78, 0x40, 0x40, 0x40, 0x40, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x78, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x42, 0x42, 0x40, 0x40, 0x4e, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0e, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x42, 0x44, 0x48, 0x50, 0x60, 0x60, 0x50, 0x48, 0x44, 0x42, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x82, 0xc6, 0xaa, 0x92, 0x92, 0x82, 0x82, 0x82, 0x82, 0x82, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x42, 0x42, 0x42, 0x62, 0x52, 0x4a, 0x46, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0x42, 0x42, 0x42, 0x42, 0x7c, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x4a, 0x3c, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0x42, 0x42, 0x42, 0x42, 0x7c, 0x50, 0x48, 0x44, 0x42, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x42, 0x40, 0x40, 0x3c, 0x02, 0x02, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfe, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x24, 0x24, 0x24, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x82, 0x82, 0x82, 0x82, 0x82, 0x92, 0x92, 0xaa, 0xc6, 0x82, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x42, 0x42, 0x24, 0x24, 0x18, 0x18, 0x24, 0x24, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x82, 0x82, 0x44, 0x44, 0x28, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7e, 0x02, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x40, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x38, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x40, 0x40, 0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x10, 0x28, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00,
+ 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x02, 0x3e, 0x42, 0x42, 0x42, 0x3e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x40, 0x40, 0x40, 0x7c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x40, 0x40, 0x40, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x02, 0x02, 0x02, 0x3e, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x7e, 0x40, 0x40, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0e, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3e, 0x02, 0x02, 0x3c, 0x00,
+ 0x00, 0x00, 0x40, 0x40, 0x40, 0x7c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0x10, 0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x04, 0x04, 0x00, 0x0c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x44, 0x44, 0x38, 0x00,
+ 0x00, 0x00, 0x40, 0x40, 0x40, 0x42, 0x44, 0x48, 0x70, 0x48, 0x44, 0x42, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x7c, 0x40, 0x40, 0x40, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3e, 0x02, 0x02, 0x02, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x60, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x40, 0x40, 0x3c, 0x02, 0x02, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x24, 0x24, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x82, 0x92, 0x92, 0x92, 0x92, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x24, 0x18, 0x24, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3e, 0x02, 0x02, 0x3c, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x04, 0x08, 0x10, 0x20, 0x40, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0c, 0x10, 0x10, 0x10, 0x20, 0x10, 0x10, 0x10, 0x10, 0x0c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x30, 0x08, 0x08, 0x08, 0x04, 0x08, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x62, 0x92, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x44, 0x82, 0x82, 0x82, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x42, 0x42, 0x40, 0x40, 0x40, 0x40, 0x42, 0x42, 0x3c, 0x10, 0x10, 0x20, 0x00,
+ 0x00, 0x00, 0x24, 0x24, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x08, 0x10, 0x00, 0x3c, 0x42, 0x42, 0x7e, 0x40, 0x40, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x24, 0x00, 0x3c, 0x02, 0x3e, 0x42, 0x42, 0x42, 0x3e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x24, 0x24, 0x00, 0x3c, 0x02, 0x3e, 0x42, 0x42, 0x42, 0x3e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0x08, 0x00, 0x3c, 0x02, 0x3e, 0x42, 0x42, 0x42, 0x3e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x24, 0x18, 0x3c, 0x02, 0x3e, 0x42, 0x42, 0x42, 0x3e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x40, 0x40, 0x40, 0x42, 0x3c, 0x10, 0x10, 0x20, 0x00,
+ 0x00, 0x00, 0x18, 0x24, 0x00, 0x3c, 0x42, 0x42, 0x7e, 0x40, 0x40, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x24, 0x24, 0x00, 0x3c, 0x42, 0x42, 0x7e, 0x40, 0x40, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0x08, 0x00, 0x3c, 0x42, 0x42, 0x7e, 0x40, 0x40, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x48, 0x48, 0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x30, 0x48, 0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x20, 0x10, 0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00,
+ 0x24, 0x24, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x24, 0x18, 0x3c, 0x42, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00,
+ 0x08, 0x10, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x78, 0x40, 0x40, 0x40, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x12, 0x72, 0x9e, 0x90, 0x90, 0x6c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7e, 0x90, 0x90, 0x90, 0xfc, 0x90, 0x90, 0x90, 0x90, 0x9e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x24, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x24, 0x24, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0x08, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x24, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0x08, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x24, 0x24, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3e, 0x02, 0x02, 0x3c, 0x00,
+ 0x24, 0x24, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x24, 0x24, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x10, 0x7c, 0x92, 0x90, 0x90, 0x90, 0x92, 0x7c, 0x10, 0x10, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x24, 0x20, 0x20, 0x78, 0x20, 0x20, 0x20, 0x22, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x82, 0x82, 0x44, 0x28, 0x10, 0x7c, 0x10, 0x7c, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xf0, 0x88, 0x88, 0x88, 0xf4, 0x84, 0x8e, 0x84, 0x84, 0x82, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0c, 0x12, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x90, 0x60, 0x00,
+ 0x00, 0x00, 0x08, 0x10, 0x00, 0x3c, 0x02, 0x3e, 0x42, 0x42, 0x42, 0x3e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x08, 0x10, 0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x08, 0x10, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x08, 0x10, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x32, 0x4c, 0x00, 0x7c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00,
+ 0x32, 0x4c, 0x00, 0x42, 0x42, 0x62, 0x52, 0x4a, 0x46, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x38, 0x04, 0x3c, 0x44, 0x3c, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x38, 0x44, 0x44, 0x44, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0x10, 0x00, 0x10, 0x10, 0x20, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x20, 0x60, 0x20, 0x22, 0x24, 0x08, 0x10, 0x20, 0x4c, 0x92, 0x04, 0x08, 0x1e, 0x00, 0x00,
+ 0x00, 0x20, 0x60, 0x20, 0x22, 0x24, 0x08, 0x10, 0x22, 0x46, 0x8a, 0x1e, 0x02, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0x10, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x24, 0x48, 0x90, 0x48, 0x24, 0x12, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x48, 0x24, 0x12, 0x24, 0x48, 0x90, 0x00, 0x00, 0x00, 0x00,
+ 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22,
+ 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55,
+ 0xee, 0xbb, 0xee, 0xbb, 0xee, 0xbb, 0xee, 0xbb, 0xee, 0xbb, 0xee, 0xbb, 0xee, 0xbb, 0xee, 0xbb,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0xe8, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x10, 0xf0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0xe8, 0x08, 0xe8, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x08, 0xe8, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0xe8, 0x08, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xf0, 0x10, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1f, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xff, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1f, 0x10, 0x1f, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x2f, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x2f, 0x20, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x20, 0x2f, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0xef, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xef, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x2f, 0x20, 0x2f, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0xef, 0x00, 0xef, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1f, 0x10, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0xff, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xff, 0x10, 0xff, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x46, 0x44, 0x44, 0x44, 0x46, 0x3a, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x44, 0x44, 0x48, 0x7c, 0x42, 0x42, 0x42, 0x42, 0x7c, 0x40, 0x40, 0x40, 0x00,
+ 0x00, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7e, 0x40, 0x20, 0x10, 0x08, 0x08, 0x10, 0x20, 0x40, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x44, 0x44, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x46, 0x7a, 0x40, 0x40, 0x40, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0x7c, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x7c, 0x10, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x5a, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x24, 0x24, 0x66, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3e, 0x10, 0x08, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x92, 0x92, 0x92, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x02, 0x04, 0x7c, 0x8a, 0x92, 0x92, 0xa2, 0x7c, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x1e, 0x20, 0x40, 0x7e, 0x40, 0x20, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, 0x04, 0x08, 0x10, 0x20, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x04, 0x08, 0x10, 0x20, 0x10, 0x08, 0x04, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0c, 0x12, 0x12, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x90, 0x90, 0x60, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x7c, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x4c, 0x00, 0x32, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x18, 0x24, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x06, 0x04, 0x04, 0x04, 0x04, 0x44, 0x44, 0x44, 0x24, 0x14, 0x0c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x38, 0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x18, 0x24, 0x08, 0x10, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+unsigned int ter_i16n_raw_len = 4096;
diff --git a/arch/x86/board/common/include/video/vga.h b/arch/x86/board/common/include/video/vga.h
new file mode 100644
index 00000000..76f86024
--- /dev/null
+++ b/arch/x86/board/common/include/video/vga.h
@@ -0,0 +1,32 @@
+/**
+ * Copyright (c) 2021 Himanshu Chauhan.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * @file vga.h
+ * @author Himanshu Chauhan (hcha...@xvisor-x86.org)
+ * @brief Framebuffer console header file.
+ */
+
+#ifndef __VGA_H
+#define __VGA_H
+
+int vga_putc(unsigned char c);
+void vga_settextcolor(u8 forecolor, u8 backcolor);
+int init_early_vga_console(void);
+struct defterm_ops *get_vga_defterm_ops(void *data);
+
+#endif
diff --git a/arch/x86/board/x86_64_generic/brd_defterm.c b/arch/x86/board/x86_64_generic/brd_defterm.c
index 0e14b18f..11a44932 100644
--- a/arch/x86/board/x86_64_generic/brd_defterm.c
+++ b/arch/x86/board/x86_64_generic/brd_defterm.c
@@ -1,5 +1,5 @@
/**
- * Copyright (c) 2010-20 Himanshu Chauhan.
+ * Copyright (c) 2021 Himanshu Chauhan.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -31,574 +31,14 @@
#include <libs/vtemu.h>
#include <libs/fifo.h>
#include <drv/input.h>
-
-#define SERIAL_CONSOLE_NAME "serial"
-#define VGA_CONSOLE_NAME "vga"
-
-#define SERIAL0_CONFIG_DTS_PATH "/motherboard/uart0"
-#define SERIAL1_CONFIG_DTS_PATH "/motherboard/uart1"
-#define VGA_CONFIG_DTS_PATH "/motherboard/vga"
-
-#define DEFAULT_CONSOLE_STR "console=vga"
-
-#define CONSOLE_SETUP_STR_LEN 1024
+#include <brd_defterm.h>
+#include <video/vga.h>
+#include <video/fb_console.h>
+#include <serial.h>

static char cmdline_console_string[CONSOLE_SETUP_STR_LEN];
-
-struct defterm_ops {
- int (*putc)(u8 ch);
- int (*getc)(u8 *ch);
- int (*init)(struct vmm_devtree_node *node);
-};
-
-/*
- * These define our textpointer, our background and foreground
- * colors (attributes), and x and y cursor coordinates
- */
-static u16 *textmemptr;
-static u32 attrib = 0x0E;
-static u32 csr_x = 0, csr_y = 0;
-static char esc_seq[16] = { 0 };
-static u32 esc_seq_count = 0;
-
-#if defined(CONFIG_VTEMU)
-static struct fifo *defterm_fifo;
-static struct vmm_completion defterm_fifo_cmpl;
-static u32 defterm_key_flags;
-static struct input_handler defterm_hndl;
-static bool defterm_key_handler_registered;
-#endif
-
-static u16 *memsetw(u16 *dest, u16 val, size_t count)
-{
- u16 *temp = (u16 *)dest;
-
- for( ; count != 0; count--) {
- *temp++ = val;
- }
-
- return dest;
-}
-
-static void update_cursor(void)
-{
- u16 pos = (csr_y * 80) + csr_x;
-
- /* cursor LOW port to vga INDEX register */
- vmm_outb(0x0F, 0x3D4);
- vmm_outb((u8)(pos & 0xFF), 0x3D5);
-
- /* cursor HIGH port to vga INDEX register */
- vmm_outb(0x0E, 0x3D4);
- vmm_outb((u8)((pos >> 8) & 0xFF), 0x3D5);
-}
-
-static void scroll_up_byline(void)
-{
- u8 *dest, *src;
- u32 copylen;
- u32 blank, temp;
-
- /*
- * A blank is defined as a space... we need to give it
- * backcolor too
- */
- blank = (0x20 | (attrib << 8));
-
-
- /*
- * Move the current text chunk that makes up the screen
- * back in the buffer by a line.
- */
- temp = csr_y - 25 + 1;
-
- dest = (u8 *)textmemptr;
- src = (u8 *)(textmemptr + temp * 80);
- copylen = ((25 - temp) * 80 * 2);
-
- while (copylen) {
- *dest = *src;
- copylen--;
- dest++;
- src++;
- }
-
- /*
- * Finally, we set the chunk of memory that occupies
- * the last line of text to our 'blank' character
- */
- memsetw(textmemptr + (25 - temp) * 80, blank, 80);
- csr_y = 25 - 1;
-}
-
-/* Scrolls the screen */
-void scroll(void)
-{
- /* Row 25 is the end, this means we need to scroll up */
- if (csr_y >= 25)
- scroll_up_byline();
-}
-
-/* Clears the screen */
-static void cls()
-{
- u32 i, blank;
-
- /*
- * Again, we need the 'short' that will be used to
- * represent a space with color
- */
- blank = 0x20 | (attrib << 8);
-
- /* Sets the entire screen to spaces in our current color */
- for(i = 0; i < 25; i++) {
- memsetw (textmemptr + i * 80, blank, 80);
- }
-
- /*
- * Update out virtual cursor, and then move the
- * hardware cursor
- */
- csr_x = 0;
- csr_y = 0;
-}
-
-/* Puts a single character on the screen */
-static int putch(unsigned char c)
-{
- u16 *where;
- u32 att = attrib << 8;
-
- if (esc_seq_count) {
- esc_seq[esc_seq_count] = c;
- esc_seq_count++;
- if ((esc_seq_count == 2) && (esc_seq[1] == '[')) {
- /* Do nothing */
- } else if ((esc_seq_count == 3) &&
- (esc_seq[1] == '[') &&
- (esc_seq[2] == 'D')) {
- /* Move left */
- if (csr_x != 0) {
- csr_x--;
- }
- esc_seq_count = 0;
- } else if ((esc_seq_count == 3) &&
- (esc_seq[1] == '[') &&
- (esc_seq[2] == 'C')) {
- /* Move right */
- if (csr_x != 0) {
- csr_x++;
- }
- esc_seq_count = 0;
- } else {
- /* Ignore unknown escape sequences */
- esc_seq_count = 0;
- }
- goto done;
- }
-
- /* Handle a backspace, by moving the cursor back one space */
- if (c == '\e') {
- esc_seq_count = 1;
- esc_seq[0] = '\e';
- goto done;
- } else if (c == '\b') {
- if (csr_x != 0) {
- csr_x--;
- }
- } else if (c == '\t') {
- /*
- * Handles a tab by incrementing the cursor's x, but only
- * to a point that will make it divisible by 8
- */
- csr_x = (csr_x + 8) & ~(8 - 1);
- } else if (c == '\r') {
- /*
- * Handles a 'Carriage Return', which simply brings the
- * cursor back to the margin
- */
- csr_x = 0;
- } else if (c == '\n') {
- /*
- * We handle our newlines the way DOS and the BIOS do: we
- * treat it as if a 'CR' was also there, so we bring the
- * cursor to the margin and we increment the 'y' value
- */
- csr_x = 0;
- csr_y++;
- } else if (c >= ' ') {
- /*
- * Any character greater than and including a space, is a
- * printable character. The equation for finding the index
- * in a linear chunk of memory can be represented by:
- * Index = [(y * width) + x]
- */
- where = textmemptr + (csr_y * 80 + csr_x);
- *where = c | att; /* Character AND attributes: color */
- csr_x++;
- }
-
- /*
- * If the cursor has reached the edge of the screen's width, we
- * insert a new line in there
- */
- if (csr_x >= 80) {
- csr_x = 0;
- csr_y++;
- }
-
-done:
- /* Scroll the screen if needed, and finally move the cursor */
- scroll();
-
- /* Update cursor location */
- update_cursor();
-
- return 0;
-}
-
-/* Sets the forecolor and backcolor that we will use */
-static void settextcolor(u8 forecolor, u8 backcolor)
-{
- /*
- * Top 4 bytes are the background, bottom 4 bytes
- * are the foreground color
- */
- attrib = (backcolor << 4) | (forecolor & 0x0F);
-}
-
-/* Sets our text-mode VGA pointer, then clears the screen for us */
-static void init_console(struct vmm_devtree_node *node)
-{
- settextcolor(15 /* White foreground */, 0 /* Black background */);
- textmemptr = (u16 *)vmm_host_iomap(0xB8000, 0x4000);
- cls();
-}
-
-#if defined(CONFIG_VTEMU)
-
-static int defterm_key_event(struct input_handler *ihnd,
- struct input_dev *idev,
- unsigned int type, unsigned int code, int value)
-{
- int rc, i, len;
- char str[16];
- u32 key_flags;
-
- if (value) { /* value=1 (key-up) or value=2 (auto-repeat) */
- /* Update input key flags */
- key_flags = vtemu_key2flags(code);
- if ((key_flags & VTEMU_KEYFLAG_LOCKS) &&
- (defterm_key_flags & key_flags)) {
- defterm_key_flags &= ~key_flags;
- } else {
- defterm_key_flags |= key_flags;
- }
-
- /* Retrive input key string */
- rc = vtemu_key2str(code, defterm_key_flags, str);
- if (rc) {
- return VMM_OK;
- }
-
- /* Add input key string to input buffer */
- len = strlen(str);
- for (i = 0; i < len; i++) {
- fifo_enqueue(defterm_fifo, &str[i], TRUE);
- vmm_completion_complete(&defterm_fifo_cmpl);
- }
- } else { /* value=0 (key-down) */
- /* Update input key flags */
- key_flags = vtemu_key2flags(code);
- if (!(key_flags & VTEMU_KEYFLAG_LOCKS)) {
- defterm_key_flags &= ~key_flags;
- }
- }
-
- return VMM_OK;
-}
-
-int arch_std_defterm_getc(u8 *ch)
-{
- int rc;
-
- if (!defterm_key_handler_registered) {
- memset(&defterm_hndl, 0, sizeof(defterm_hndl));
- defterm_hndl.name = "defterm";
- defterm_hndl.evbit[0] |= BIT_MASK(EV_KEY);
- defterm_hndl.event = defterm_key_event;
- defterm_hndl.priv = NULL;
-
- rc = input_register_handler(&defterm_hndl);
- if (rc) {
- return rc;
- }
-
- rc = input_connect_handler(&defterm_hndl);
- if (rc) {
- return rc;
- }
-
- defterm_key_handler_registered = TRUE;
- }
-
- if (defterm_fifo) {
- /* Assume that we are always called from
- * Orphan (or Thread) context hence we can
- * sleep waiting for input characters.
- */
- vmm_completion_wait(&defterm_fifo_cmpl);
-
- /* Try to dequeue from defterm fifo */
- if (!fifo_dequeue(defterm_fifo, ch)) {
- return VMM_ENOTAVAIL;
- }
-
- return VMM_OK;
- }
-
- return VMM_EFAIL;
-}
-
-#else
-
-int arch_std_defterm_getc(u8 *ch)
-{
- return VMM_EFAIL;
-}
-
-#endif
-
-int arch_std_defterm_putc(u8 ch)
-{
- putch(ch);
-
- return VMM_OK;
-}
-
-int __init arch_std_defterm_init(struct vmm_devtree_node *node)
-{
- init_console(node);
-
-#if defined(CONFIG_VTEMU)
- defterm_fifo = fifo_alloc(sizeof(u8), 128);
- if (!defterm_fifo) {
- return VMM_ENOMEM;
- }
- INIT_COMPLETION(&defterm_fifo_cmpl);
-
- defterm_key_flags = 0;
- defterm_key_handler_registered = FALSE;
-#endif
-
- return VMM_OK;
-}
-
-static struct defterm_ops stdio_ops = {
- .putc = arch_std_defterm_putc,
- .getc = arch_std_defterm_getc,
- .init = arch_std_defterm_init
-};
-
-#if defined(CONFIG_SERIAL_8250_UART)
-
-#include <drv/serial/8250-uart.h>
-
-static struct uart_8250_port uart8250_port;
-
-static int uart8250_defterm_putc(u8 ch)
-{
- if (!uart_8250_lowlevel_can_putc(&uart8250_port)) {
- return VMM_EFAIL;
- }
- uart_8250_lowlevel_putc(&uart8250_port, ch);
- return VMM_OK;
-}
-
-static int uart8250_defterm_getc(u8 *ch)
-{
- if (!uart_8250_lowlevel_can_getc(&uart8250_port)) {
- return VMM_EFAIL;
- }
- *ch = uart_8250_lowlevel_getc(&uart8250_port);
- return VMM_OK;
-}
-
-static int __init uart8250_defterm_init(struct vmm_devtree_node *node)
-{
- int rc;
- physical_addr_t addr;
-
- if (vmm_devtree_read_physaddr(node,
- VMM_DEVTREE_REG_ATTR_NAME,
- &addr) == VMM_OK) {
- uart8250_port.base = (virtual_addr_t)addr;
- }
-
- rc = vmm_devtree_clock_frequency(node,
- &uart8250_port.input_clock);
- if (rc) {
- return rc;
- }
-
- if (vmm_devtree_read_u32(node, "baudrate",
- &uart8250_port.baudrate)) {
- uart8250_port.baudrate = 115200;
- }
-
- if (vmm_devtree_read_u32(node, "reg-shift",
- &uart8250_port.reg_shift)) {
- uart8250_port.reg_shift = 2;
- }
-
- if (vmm_devtree_read_u32(node, "reg-io-width",
- &uart8250_port.reg_width)) {
- uart8250_port.reg_width = 1;
- }
-
- uart_8250_lowlevel_init(&uart8250_port);
-
- return VMM_OK;
-}
-
-static struct defterm_ops uart8250_ops = {
- .putc = uart8250_defterm_putc,
- .getc = uart8250_defterm_getc,
- .init = uart8250_defterm_init
-};
-#endif
-
-typedef int (*EARLY_PUTC)(u8 ch);
-
-static EARLY_PUTC early_putc = NULL;
-
-static int init_early_vga_console(void)
-{
- settextcolor(15 /* White foreground */, 0 /* Black background */);
- textmemptr = (u16 *)(0xB8000UL);
- cls();
-
- early_putc = putch;
-
- return 0;
-}
-
-#if defined(CONFIG_SERIAL_8250_UART)
-static int setup_early_serial_console(physical_addr_t addr, u32 baud, u32 clock)
-{
- uart8250_port.base = addr;
- uart8250_port.input_clock = clock;
- uart8250_port.baudrate = baud;
- uart8250_port.reg_shift = 2;
- uart8250_port.reg_width = 1;
-
- uart_8250_lowlevel_init(&uart8250_port);
-
- early_putc = &uart8250_defterm_putc;
-
- return VMM_OK;
-}
-
-static int parse_early_serial_options(char *options, physical_addr_t *addr,
- u32 *baud, u32 *clock)
-{
- char *opt_token, *opt_save;
- const char *opt_delim = ",";
- u32 opt_tok_len;
- u32 opt_number = 0;
- char *token;
-
- *addr = 0x3f8;
- *baud = 115200;
- *clock = 24000000;
-
- for (opt_token = strtok_r(options, opt_delim,
- &opt_save); opt_token;
- opt_token = strtok_r(NULL, opt_delim,
- &opt_save)) {
-
- /* @,11520,24000000 -> @, is empty */
- opt_tok_len = strlen(opt_token);
-
- /* Empty */
- if (!opt_tok_len) {
- opt_number++;
- continue;
- }
-
- token = skip_spaces(opt_token);
-
- switch(opt_number) {
- case 0:
- *addr = (physical_addr_t)strtoull(token, NULL, 16);
-
- /* Port mnenomics */
- if (*addr == 0) {
- *addr = 0x3f8;
- } else if (*addr == 1) {
- *addr = 0x2f8;
- }
-
- opt_number++;
- break;
-
- case 1:
- *baud = strtoul(token, NULL, 10);
- opt_number++;
- break;
-
- case 2:
- *clock = strtoul(token, NULL, 10);
- opt_number++;
- break;
- }
- }
-
- return VMM_OK;
-}
-
-/* earlyprint=serial@<addr>,<baudrate> */
-static int init_early_serial_console(char *setup_string)
-{
- char *port_token, *port_save;
- const char *port_delim = "@";
- u32 centry = 0, found = 0, port_tok_len, check_len;
- physical_addr_t addr;
- u32 baud, clock;
-
- for (port_token = strtok_r(setup_string, port_delim,
- &port_save); port_token;
- port_token = strtok_r(NULL, port_delim,
- &port_save)) {
- port_tok_len = strlen(port_token);
- if (!centry) {
-
- check_len = (strlen(SERIAL_CONSOLE_NAME) > port_tok_len
- ? port_tok_len
- : strlen(SERIAL_CONSOLE_NAME));
-
- if (!strncmp(setup_string, SERIAL_CONSOLE_NAME,
- check_len))
- found = 1;
- } else {
- if (found) {
- if (parse_early_serial_options(port_token,
- &addr, &baud,
- &clock) != VMM_OK) {
- return VMM_EFAIL;
- }
- setup_early_serial_console(addr, baud, clock);
- found = 0;
- return VMM_OK;
- }
- }
- centry++;
- }
-
- return VMM_EFAIL;
-
-}
-#endif /* CONFIG_SERIAL_8250_UART */
+static struct defterm_ops *ops = NULL;
+EARLY_PUTC early_putc = NULL;

void arch_defterm_early_putc(u8 ch)
{
@@ -606,125 +46,81 @@ void arch_defterm_early_putc(u8 ch)
early_putc(ch);
}

-static const struct defterm_ops *ops = &stdio_ops;
-
/*
* Just set what is needed. Ops will be initialzied when
* arch_defterm_init will be called.
*/
static int __init setup_early_print(char *buf)
{
-#if defined(CONFIG_SERIAL_8250_UART)
- if (!strncmp(buf, SERIAL_CONSOLE_NAME, strlen(SERIAL_CONSOLE_NAME))) {
- init_early_serial_console(buf);
- return 0;
- }
-#endif
+ if (!strncmp(buf, SERIAL_CONSOLE_NAME, strlen(SERIAL_CONSOLE_NAME)))
+ return init_early_serial_console(buf);

if(!strncmp(buf, VGA_CONSOLE_NAME, strlen(VGA_CONSOLE_NAME)))
- init_early_vga_console();
+ return init_early_vga_console();

- return 0;
+ return VMM_EFAIL;
}

vmm_early_param("earlyprint", setup_early_print);

static int __init set_default_console(char *buf)
{
- if (buf == NULL) return 0;
+ if (buf == NULL) return VMM_OK;

-#if defined(CONFIG_SERIAL_8250_UART)
if (!strncmp(buf, SERIAL_CONSOLE_NAME, strlen(SERIAL_CONSOLE_NAME))) {
memcpy(cmdline_console_string, buf, CONSOLE_SETUP_STR_LEN);
- return 0;
+ return VMM_OK;
+ }
+
+ if (!strncmp(buf, FB_CONSOLE_NAME, strlen(FB_CONSOLE_NAME))) {
+ memcpy(cmdline_console_string, buf, CONSOLE_SETUP_STR_LEN);
+ return VMM_OK;
}
-#endif

vmm_snprintf(cmdline_console_string, strlen(DEFAULT_CONSOLE_STR),
DEFAULT_CONSOLE_STR);
- return 0;
+ return VMM_OK;
}

vmm_early_param("console", set_default_console);

int arch_defterm_putc(u8 ch)
{
- return (ops) ? ops->putc(ch) : VMM_EFAIL;
+ if (ops)
+ return ops->putc(ch);
+
+ return VMM_EFAIL;
}

int arch_defterm_getc(u8 *ch)
{
- return (ops) ? ops->getc(ch) : VMM_EFAIL;
-}
+ if (ops)
+ return ops->getc(ch);

-#if defined(CONFIG_SERIAL_8250_UART)
-/*-------------- UART DEFTERM --------------- */
-static struct vmm_devtree_nodeid defterm_devid_table[] = {
- { .compatible = "ns8250", .data = &uart8250_ops },
- { .compatible = "ns16450", .data = &uart8250_ops },
- { .compatible = "ns16550a", .data = &uart8250_ops },
- { .compatible = "ns16550", .data = &uart8250_ops },
- { .compatible = "ns16750", .data = &uart8250_ops },
- { .compatible = "ns16850", .data = &uart8250_ops },
- { /* end of list */ },
-};
-#endif
+ return VMM_EFAIL;
+}

int __init arch_defterm_init(void)
{
int rc;
- const char *attr;
- struct vmm_devtree_node *node;
-#if defined(CONFIG_SERIAL_8250_UART)
- const struct vmm_devtree_nodeid *nodeid;
-#endif
- /* Find choosen console node */
- node = vmm_devtree_getnode(VMM_DEVTREE_PATH_SEPARATOR_STRING
- VMM_DEVTREE_CHOSEN_NODE_NAME);
- if (!node) {
- return VMM_ENODEV;
- }
-
-#if defined(CONFIG_SERIAL_8250_UART)
- if (!strcmp(cmdline_console_string, "serial@0"))
- attr = SERIAL0_CONFIG_DTS_PATH;
- else if (!strcmp(cmdline_console_string, "serial@1"))
- attr = SERIAL1_CONFIG_DTS_PATH;
- else
-#endif
- attr = VGA_CONFIG_DTS_PATH;
-
- rc = vmm_devtree_setattr(node, VMM_DEVTREE_CONSOLE_ATTR_NAME,
- (void *)attr, VMM_DEVTREE_ATTRTYPE_STRING,
- strlen(attr)+1, FALSE);
-
-
- rc = vmm_devtree_read_string(node,
- VMM_DEVTREE_CONSOLE_ATTR_NAME, &attr);
- vmm_devtree_dref_node(node);
- if (rc) {
- return rc;
- }

- node = vmm_devtree_getnode(attr);
- if (!node) {
- return VMM_ENODEV;
+ vmm_printf("%s: init (%s)\n", __func__, cmdline_console_string);
+ if (!strcmp(cmdline_console_string, "fb")) {
+ vmm_printf("%s: Framebuffer as console\n", __func__);
+ ops = get_fb_defterm_ops(NULL);
+ goto out;
}

-#if defined(CONFIG_SERIAL_8250_UART)
- /* Find appropriate defterm ops */
- nodeid = vmm_devtree_match_node(defterm_devid_table, node);
- if (nodeid) {
- ops = nodeid->data;
- } else {
- /* default console is always VGA unless specified otherwise */
- ops = &stdio_ops;
+ if (!strcmp(cmdline_console_string, "serial")) {
+ vmm_printf("%s: Serial as console\n", __func__);
+ ops = get_serial_defterm_ops((char *)&cmdline_console_string[0]);
+ goto out;
}
-#else
- ops = &stdio_ops;
-#endif

- rc = ops->init(node);
+ vmm_printf("%s: Defaulting to vga as console\n", __func__);
+ ops = get_vga_defterm_ops(NULL);
+ out:
+ rc = ops->init();

return rc;
}
--
2.27.0

Anup Patel

unread,
Feb 26, 2021, 6:20:51 AM2/26/21
to Xvisor Devel, Himanshu Chauhan
On Sun, Feb 21, 2021 at 10:54 AM Himanshu Chauhan
<hcha...@xvisor-x86.org> wrote:
>
> In UEFI case, the grub can hand over the console in FB mode
> than the text case. This patch adds supports to take over
> the console in FB mode from GRUB. It can choose to stay
> with same configuration or switch to generic FB driver.
>
> Signed-off-by: Himanshu Chauhan <hcha...@xvisor-x86.org>

Reviewed-by: Anup Patel <an...@brainfautl.org>

Applied this patch to xvisor-next tree.

Thanks,
Anup
> --
> You received this message because you are subscribed to the Google Groups "Xvisor Development" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to xvisor-devel...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/xvisor-devel/20210221040211.2606641-1-hchauhan%40xvisor-x86.org.
Reply all
Reply to author
Forward
0 new messages