graphics: Clean up the corebootfb driver.

This driver uses the framebuffer information passed through the coreboot
tables to draw text for a graphical console. The whole graphic stack probably
needs to be reworked, but this makes that a bit easier and is a good cleanup
generally speaking.

It also gets rid of support for a visible cursor, clears up some typing, and
switches to a more depthcharge like interface which cuts out most of the
global variables.

Change-Id: I7e83892936a591a7f7141fb86bb960769c02fbe6
diff --git a/src/base/graphics.c b/src/base/graphics.c
index d73cfcb..dc43c76 100644
--- a/src/base/graphics.c
+++ b/src/base/graphics.c
@@ -33,7 +33,6 @@
 	/* initialize video console */
 	video_init();
 	video_console_clear();
-	video_console_cursor_enable(0);
 
 	backlight_update(1);
 
diff --git a/src/libpayload/drivers/video/corebootfb.c b/src/libpayload/drivers/video/corebootfb.c
index 5fd484a..31649c1 100644
--- a/src/libpayload/drivers/video/corebootfb.c
+++ b/src/libpayload/drivers/video/corebootfb.c
@@ -26,241 +26,219 @@
  * SUCH DAMAGE.
  */
 
+#include "base/xalloc.h"
+#include "base/container_of.h"
+
 #include <coreboot_tables.h>
+#include <endian.h>
 #include <pci.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sysinfo.h>
 #include <video_console.h>
+
 #include "font8x16.h"
 
-struct video_console coreboot_video_console;
+// Color definitions for the 16 standard colors.
 
-static unsigned int cursor_x = 0, cursor_y = 0, cursor_en = 0;
+typedef struct
+{
+	uint8_t blue;
+	uint8_t green;
+	uint8_t red;
+} VgaColor;
 
-/* color definitions for the 16 standard colors */
-
-#define VGA_COLOR_DEFAULT 7
-static const uint32_t vga_colors[] = {
-	// BLUE      | GREEN       | RED
-	(0x00 << 16) | (0x00 << 8) | 0x00,
-	(0xAA << 16) | (0x00 << 8) | 0x00,
-	(0x00 << 16) | (0xAA << 8) | 0x00,
-	(0xAA << 16) | (0x55 << 8) | 0x00,
-	(0x00 << 16) | (0x00 << 8) | 0xAA,
-	(0xAA << 16) | (0x00 << 8) | 0xAA,
-	(0x00 << 16) | (0xAA << 8) | 0xAA,
-	(0xAA << 16) | (0xAA << 8) | 0xAA,
-	(0x55 << 16) | (0x55 << 8) | 0x55,
-	(0xFF << 16) | (0x55 << 8) | 0x55,
-	(0x55 << 16) | (0xFF << 8) | 0x55,
-	(0xFF << 16) | (0xFF << 8) | 0x55,
-	(0x55 << 16) | (0x55 << 8) | 0xFF,
-	(0xFF << 16) | (0x55 << 8) | 0xFF,
-	(0x55 << 16) | (0xFF << 8) | 0xFF,
-	(0xFF << 16) | (0xFF << 8) | 0xFF,
+static const VgaColor vga_colors[] = {
+	{ .blue = 0x00, .green = 0x00, .red = 0x00 }, // Black.
+	{ .blue = 0xAA, .green = 0x00, .red = 0x00 }, // Blue.
+	{ .blue = 0x00, .green = 0xAA, .red = 0x00 }, // Green.
+	{ .blue = 0xAA, .green = 0x55, .red = 0x00 }, // Cyan.
+	{ .blue = 0x00, .green = 0x00, .red = 0xAA }, // Red.
+	{ .blue = 0xAA, .green = 0x00, .red = 0xAA }, // Magenta.
+	{ .blue = 0x00, .green = 0xAA, .red = 0xAA }, // Brown.
+	{ .blue = 0xAA, .green = 0xAA, .red = 0xAA }, // Gray.
+	{ .blue = 0x55, .green = 0x55, .red = 0x55 }, // Dark gray.
+	{ .blue = 0xFF, .green = 0x55, .red = 0x55 }, // Bright blue.
+	{ .blue = 0x55, .green = 0xFF, .red = 0x55 }, // Bright green.
+	{ .blue = 0xFF, .green = 0xFF, .red = 0x55 }, // Bright cyan.
+	{ .blue = 0x55, .green = 0x55, .red = 0xFF }, // Bright red.
+	{ .blue = 0xFF, .green = 0x55, .red = 0xFF }, // Bright magenta.
+	{ .blue = 0x55, .green = 0xFF, .red = 0xFF }, // Yellow.
+	{ .blue = 0xFF, .green = 0xFF, .red = 0xFF }, // White.
 };
 
-/* Addresses for the various components */
-static unsigned long fbinfo;
-static unsigned long fbaddr;
-static unsigned long chars;
+#define VGA_COLOR_DEFAULT 7
 
-#define FI ((struct cb_framebuffer *)(uintptr_t)fbinfo)
-#define FB ((unsigned char *)(uintptr_t)fbaddr)
-#define CHARS ((unsigned short *)(uintptr_t)chars)
 
-static void corebootfb_scroll_up(void)
+typedef struct {
+	VideoConsole vc;
+
+	struct cb_framebuffer *info;
+	uint8_t *buf;
+	uint16_t *chars;
+	int char_count;
+
+	uint32_t cursor_x;
+	uint32_t cursor_y;
+} CorebootFb;
+
+static inline uint32_t pixel_val(const CorebootFb *fb, const VgaColor *color)
 {
-	unsigned char *dst = FB;
-	unsigned char *src = FB + (FI->bytes_per_line * FONT_HEIGHT);
-	int y;
+	uint32_t blue = color->blue >> (8 - fb->info->blue_mask_size);
+	uint32_t green = color->green >> (8 - fb->info->green_mask_size);
+	uint32_t red = color->red >> (8 - fb->info->red_mask_size);
 
-	/* Scroll all lines up */
-	for(y = 0; y < FI->y_resolution - FONT_HEIGHT; y++) {
-		memcpy(dst, src, FI->x_resolution * (FI->bits_per_pixel >> 3));
-
-		dst += FI->bytes_per_line;
-		src += FI->bytes_per_line;
-	}
-
-	/* Erase last line */
-	dst = FB + (FI->y_resolution - FONT_HEIGHT) * FI->bytes_per_line;
-
-	for(; y < FI->y_resolution; y++) {
-		memset(dst, 0, FI->x_resolution * (FI->bits_per_pixel >> 3));
-		dst += FI->bytes_per_line;
-	}
-
-	/* And update the char buffer */
-	dst = (unsigned char *) CHARS;
-	src = (unsigned char *) (CHARS + coreboot_video_console.columns);
-	memcpy(dst, src, coreboot_video_console.columns *
-			(coreboot_video_console.rows - 1) * 2);
-	int column;
-	for (column = 0; column < coreboot_video_console.columns; column++)
-		CHARS[(coreboot_video_console.rows - 1) * coreboot_video_console.columns + column] = (VGA_COLOR_DEFAULT << 8);
-
-	cursor_y--;
+	return (blue << fb->info->blue_mask_pos) |
+	       (green << fb->info->green_mask_pos) |
+	       (red << fb->info->red_mask_pos);
 }
 
-static void corebootfb_clear(void)
+static void corebootfb_scroll_up(VideoConsole *me)
 {
-	int row, column;
-	unsigned char *ptr = FB;
+	CorebootFb *fb = container_of(me, CorebootFb, vc);
 
-	/* Clear the screen */
-	for(row = 0; row < FI->y_resolution; row++) {
-		memset(ptr, 0, FI->x_resolution * (FI->bits_per_pixel >> 3));
-		ptr += FI->bytes_per_line;
-	}
+	int bytes_per_row = fb->info->bytes_per_line * FONT_HEIGHT;
+	int fb_size = fb->info->bytes_per_line * fb->info->y_resolution;
 
-	/* And update the char buffer */
-	for(row = 0; row < coreboot_video_console.rows; row++)
-		for (column = 0; column < coreboot_video_console.columns; column++)
-			CHARS[row * coreboot_video_console.columns + column] = (VGA_COLOR_DEFAULT << 8);
+	// Scroll the text up.
+	memmove(fb->buf, fb->buf + bytes_per_row, fb_size - bytes_per_row);
+
+	// Erase the last line.
+	memset(fb->buf + fb_size - bytes_per_row, 0, bytes_per_row);
+
+	// Update the char buffer.
+	memmove(fb->chars, &fb->chars[me->columns],
+		(fb->char_count - me->columns) * sizeof(*fb->chars));
+
+	uint16_t *last_row = &fb->chars[(me->rows - 1) * me->columns];
+	for (int column = 0; column < me->columns; column++)
+		last_row[column] = VGA_COLOR_DEFAULT << 8;
+
+	fb->cursor_y--;
 }
 
-static void corebootfb_putchar(uint8_t row, uint8_t col, unsigned int ch)
+static void corebootfb_clear(VideoConsole *me)
 {
-	unsigned char *dst;
-	unsigned char *glyph = font8x16 + ((ch & 0xFF) * FONT_HEIGHT);
+	CorebootFb *fb = container_of(me, CorebootFb, vc);
 
-	unsigned char bg = (ch >> 12) & 0xF;
-	unsigned char fg = (ch >> 8) & 0xF;
-	uint32_t fgval = 0, bgval = 0;
-	uint16_t *dst16;
-	uint32_t *dst32;
+	// Clear the screen.
+	memset(fb->buf, 0, fb->info->bytes_per_line * fb->info->y_resolution);
 
-	int x, y;
+	// And update the char buffer.
+	for (int i = 0; i < fb->char_count; i++)
+		fb->chars[i] = VGA_COLOR_DEFAULT << 8;
+}
 
-	if (FI->bits_per_pixel > 8) {
-		bgval = ((((vga_colors[bg] >> 0) & 0xff) >> (8 - FI->blue_mask_size)) << FI->blue_mask_pos) |
-			((((vga_colors[bg] >> 8) & 0xff) >> (8 - FI->green_mask_size)) << FI->green_mask_pos) |
-			((((vga_colors[bg] >> 16) & 0xff) >> (8 - FI->red_mask_size)) << FI->red_mask_pos);
-		fgval = ((((vga_colors[fg] >> 0) & 0xff) >> (8 - FI->blue_mask_size)) << FI->blue_mask_pos) |
-			((((vga_colors[fg] >> 8) & 0xff) >> (8 - FI->green_mask_size)) << FI->green_mask_pos) |
-			((((vga_colors[fg] >> 16) & 0xff) >> (8 - FI->red_mask_size)) << FI->red_mask_pos);
+static void corebootfb_putc(VideoConsole *me,
+			    uint32_t row, uint32_t col, uint16_t ch)
+{
+	static int putting_char = 0;
+	if (putting_char)
+		return;
+	putting_char = 1;
+	CorebootFb *fb = container_of(me, CorebootFb, vc);
+
+	fb->chars[row * me->columns + col] = ch;
+
+	uint8_t *glyph = font8x16 + ((ch & 0xFF) * FONT_HEIGHT);
+
+	uint32_t bgval = (ch >> 12) & 0xf;
+	uint32_t fgval = (ch >> 8) & 0xf;
+	if (fb->info->bits_per_pixel > 8) {
+		bgval = pixel_val(fb, &vga_colors[bgval]);
+		fgval = pixel_val(fb, &vga_colors[fgval]);
 	}
 
+	int bits_per_pixel = fb->info->bits_per_pixel;
+	int bytes_per_pixel = bits_per_pixel / 8;
+	int bytes_per_line = fb->info->bytes_per_line;
 
-	dst = FB + ((row * FONT_HEIGHT) * FI->bytes_per_line);
-	dst += (col * FONT_WIDTH * (FI->bits_per_pixel >> 3));
 
-	for(y = 0; y < FONT_HEIGHT; y++) {
-		for(x = FONT_WIDTH - 1; x >= 0; x--) {
+	uint8_t *line = fb->buf + (row * FONT_HEIGHT) * bytes_per_line;
+	for (int y = 0; y < FONT_HEIGHT; y++) {
 
-			switch (FI->bits_per_pixel) {
-			case 8: /* Indexed */
-				dst[(FONT_WIDTH - x) * (FI->bits_per_pixel >> 3)] = (*glyph & (1 << x)) ?  fg : bg;
+		uint8_t *pixel = line + col * FONT_WIDTH * bytes_per_pixel;
+		for (int x = FONT_WIDTH - 1; x >= 0; x--) {
+			uint32_t val = *glyph & (1 << x) ? fgval : bgval;
+
+			switch (bits_per_pixel) {
+			case 8: // Indexed.
+				*pixel = val;
 				break;
-			case 16: /* 16 bpp */
-				dst16 = (uint16_t *)(dst + (FONT_WIDTH - x) * (FI->bits_per_pixel >> 3));
-				*dst16 = (*glyph & (1 << x)) ? fgval : bgval;
+			case 16:
+				*(uint16_t *)pixel = htole16(val);
 				break;
-			case 24: /* 24 bpp */
-				if (*glyph & (1 << x)) {
-					dst[(FONT_WIDTH - x) * (FI->bits_per_pixel >> 3) + 0] = fgval & 0xff;
-					dst[(FONT_WIDTH - x) * (FI->bits_per_pixel >> 3) + 1] = (fgval >> 8) & 0xff;
-					dst[(FONT_WIDTH - x) * (FI->bits_per_pixel >> 3) + 2] = (fgval >> 16) & 0xff;
-				} else {
-					dst[(FONT_WIDTH - x) * (FI->bits_per_pixel >> 3) + 0] = bgval & 0xff;
-					dst[(FONT_WIDTH - x) * (FI->bits_per_pixel >> 3) + 1] = (bgval >> 8) & 0xff;
-					dst[(FONT_WIDTH - x) * (FI->bits_per_pixel >> 3) + 2] = (bgval >> 16) & 0xff;
-				}
+			case 24:
+				pixel[0] = val & 0xff;
+				pixel[1] = (val >> 8) & 0xff;
+				pixel[2] = (val >> 16) & 0xff;
 				break;
-			case 32: /* 32 bpp */
-				dst32 = (uint32_t *)(dst + (FONT_WIDTH - x) * (FI->bits_per_pixel >> 3));
-				*dst32 = (*glyph & (1 << x)) ? fgval : bgval;
+			case 32:
+				*(uint32_t *)pixel = htole32(val);
 				break;
 			}
+
+			pixel += bytes_per_pixel;
 		}
 
-		dst += FI->bytes_per_line;
+		line += bytes_per_line;
 		glyph++;
 	}
+	putting_char = 0;
 }
 
-static void corebootfb_putc(uint8_t row, uint8_t col, unsigned int ch)
+static void corebootfb_get_cursor(VideoConsole *me, uint32_t *x, uint32_t *y)
 {
-	CHARS[row * coreboot_video_console.columns + col] = ch;
-	corebootfb_putchar(row, col, ch);
+	CorebootFb *fb = container_of(me, CorebootFb, vc);
+
+	*x = fb->cursor_x;
+	*y = fb->cursor_y;
 }
 
-static void corebootfb_update_cursor(void)
+static void corebootfb_set_cursor(VideoConsole *me, uint32_t x, uint32_t y)
 {
-	int ch, paint;
-	if(cursor_en) {
-		ch = CHARS[cursor_y * coreboot_video_console.columns + cursor_x];
-		paint = (ch & 0xff) | ((ch<<4) & 0xf000) | ((ch >> 4) & 0x0f00);
-	} else {
-		paint = CHARS[cursor_y * coreboot_video_console.columns + cursor_x];
-	}
+	CorebootFb *fb = container_of(me, CorebootFb, vc);
 
-	if (cursor_y < coreboot_video_console.rows)
-		corebootfb_putchar(cursor_y, cursor_x, paint);
+	fb->cursor_x = x;
+	fb->cursor_y = y;
 }
 
-static void corebootfb_enable_cursor(int state)
+static int corebootfb_init(VideoConsole *me)
 {
-	cursor_en = state;
-	corebootfb_update_cursor();
-}
+	CorebootFb *fb = container_of(me, CorebootFb, vc);
 
-static void corebootfb_get_cursor(unsigned int *x, unsigned int *y, unsigned int *en)
-{
-	*x = cursor_x;
-	*y = cursor_y;
-	*en = cursor_en;
-}
-
-static void corebootfb_set_cursor(unsigned int x, unsigned int y)
-{
-	int cursor_remember = cursor_en;
-	if (cursor_remember)
-		corebootfb_enable_cursor(0);
-
-	cursor_x = x;
-	cursor_y = y;
-
-	if (cursor_remember)
-		corebootfb_enable_cursor(1);
-}
-
-static int corebootfb_init(void)
-{
 	if (lib_sysinfo.framebuffer == NULL)
 		return -1;
 
-	/* We might have been called before relocation (like FILO does). So
-	   just keep the physical address which won't break on relocation. */
-	fbinfo = (uintptr_t)lib_sysinfo.framebuffer;
+	fb->info = lib_sysinfo.framebuffer;
 
-	fbaddr = FI->physical_address;
+	fb->buf = (uint8_t *)(uintptr_t)fb->info->physical_address;
 
-	coreboot_video_console.columns = FI->x_resolution / FONT_WIDTH;
-	coreboot_video_console.rows = FI->y_resolution / FONT_HEIGHT;
+	me->columns = fb->info->x_resolution / FONT_WIDTH;
+	me->rows = fb->info->y_resolution / FONT_HEIGHT;
 
-	/* See setting of fbinfo above. */
-	chars = (uintptr_t)malloc(coreboot_video_console.rows *
-				  coreboot_video_console.columns * 2);
+	if (me->columns > (1ULL << 16) || me->rows > (1ULL << 16))
+		return -1;
 
-	// clear boot splash screen if there is one.
-	corebootfb_clear();
+	fb->char_count = me->rows * me->columns;
+	fb->chars = xmalloc(fb->char_count * sizeof(*fb->chars));
+
+	// Clear boot splash screen if there is one.
+	corebootfb_clear(me);
 	return 0;
 }
 
-struct video_console coreboot_video_console = {
-	.init = corebootfb_init,
-	.putc = corebootfb_putc,
-	.clear = corebootfb_clear,
-	.scroll_up = corebootfb_scroll_up,
+static CorebootFb coreboot_fb = {
+	.vc = {
+		.init = &corebootfb_init,
+		.putc = &corebootfb_putc,
+		.clear = &corebootfb_clear,
+		.scroll_up = &corebootfb_scroll_up,
 
-	.get_cursor = corebootfb_get_cursor,
-	.set_cursor = corebootfb_set_cursor,
-	.enable_cursor = corebootfb_enable_cursor,
-
-	.columns = 80,
-	.rows    = 25
+		.get_cursor = &corebootfb_get_cursor,
+		.set_cursor = &corebootfb_set_cursor,
+	},
 };
+
+VideoConsole *coreboot_video_console = &coreboot_fb.vc;
diff --git a/src/libpayload/drivers/video/video.c b/src/libpayload/drivers/video/video.c
index 97cca80..9c52e71 100644
--- a/src/libpayload/drivers/video/video.c
+++ b/src/libpayload/drivers/video/video.c
@@ -32,18 +32,7 @@
 #include "base/algorithm.h"
 #include "drivers/console/console.h"
 
-#if CONFIG_COREBOOT_VIDEO_CONSOLE
-extern struct video_console coreboot_video_console;
-#endif
-
-static struct video_console *video_console_list[] =
-{
-#if CONFIG_COREBOOT_VIDEO_CONSOLE
-	&coreboot_video_console,
-#endif
-};
-
-static struct video_console *console;
+static VideoConsole *console;
 
 static int cursorx;
 static int cursory;
@@ -74,40 +63,34 @@
 		cursory++;
 	}
 
-	while(cursory >= console->rows) {
-		console->scroll_up();
+	while (cursory >= console->rows) {
+		console->scroll_up(console);
 		cursory--;
 	}
 
 	if (console->set_cursor)
-		console->set_cursor(cursorx, cursory);
-}
-
-void video_console_cursor_enable(int state)
-{
-	if (console && console->enable_cursor)
-		console->enable_cursor(state);
+		console->set_cursor(console, cursorx, cursory);
 }
 
 void video_console_clear(void)
 {
 	if (console)
-		console->clear();
+		console->clear(console);
 
 	cursorx = 0;
 	cursory = 0;
 
 	if (console && console->set_cursor)
-		console->set_cursor(cursorx, cursory);
+		console->set_cursor(console, cursorx, cursory);
 }
 
-void video_console_putc(uint8_t row, uint8_t col, unsigned int ch)
+void video_console_putc(uint32_t row, uint32_t col, uint16_t ch)
 {
 	if (console)
-		console->putc(row, col, ch);
+		console->putc(console, row, col, ch);
 }
 
-void video_console_putchar(unsigned int ch)
+void video_console_putchar(uint16_t ch)
 {
 	if (!console)
 		return;
@@ -138,11 +121,12 @@
 		break;
 
 	case '\t':
-		while(cursorx % 8 && cursorx < console->columns)
-			console->putc(cursory, cursorx++, (ch & 0xFF00) | ' ');
+		while (cursorx % 8 && cursorx < console->columns)
+			console->putc(console, cursory, cursorx++,
+				      (ch & 0xFF00) | ' ');
 		break;
 	default:
-		console->putc(cursory, cursorx++, ch);
+		console->putc(console, cursory, cursorx++, ch);
 		break;
 	}
 
@@ -199,20 +183,7 @@
 		video_console_putchar(str[i++] | foreground | background);
 }
 
-void video_console_get_cursor(unsigned int *x, unsigned int *y, unsigned int *en)
-{
-	*x=0;
-	*y=0;
-	*en=0;
-
-	if (console && console->get_cursor)
-		console->get_cursor(x, y, en);
-
-	*x = cursorx;
-	*y = cursory;
-}
-
-void video_console_set_cursor(unsigned int x, unsigned int y)
+void video_console_set_cursor(uint32_t x, uint32_t y)
 {
 	cursorx = x;
 	cursory = y;
@@ -225,21 +196,31 @@
 	}
 };
 
+#if CONFIG_COREBOOT_VIDEO_CONSOLE
+extern VideoConsole *coreboot_video_console;
+#endif
+
 int video_init(void)
 {
-	int i;
-	unsigned int dummy_cursor_enabled;
+	VideoConsole *video_console_list[] =
+	{
+	#if CONFIG_COREBOOT_VIDEO_CONSOLE
+		coreboot_video_console,
+	#endif
+	};
 
-	for (i = 0; i < ARRAY_SIZE(video_console_list); i++) {
-		if (video_console_list[i]->init())
+	for (int i = 0; i < ARRAY_SIZE(video_console_list); i++) {
+		if (video_console_list[i]->init(video_console_list[i]))
 			continue;
 
 		console = video_console_list[i];
 
-		if (console->get_cursor)
-			console->get_cursor((unsigned int*)&cursorx,
-					    (unsigned int*)&cursory,
-					    &dummy_cursor_enabled);
+		if (console->get_cursor) {
+			uint32_t x, y;
+			console->get_cursor(console, &x, &y);
+			cursorx = x;
+			cursory = y;
+		}
 
 		if (cursorx) {
 			cursorx = 0;
diff --git a/src/libpayload/include/libpayload.h b/src/libpayload/include/libpayload.h
index c4d92cb..e388a6b 100644
--- a/src/libpayload/include/libpayload.h
+++ b/src/libpayload/include/libpayload.h
@@ -38,13 +38,11 @@
 
 int video_init(void);
 int video_console_init(void);
-void video_get_rows_cols(unsigned int *rows, unsigned int *cols);
-void video_console_putchar(unsigned int ch);
-void video_console_putc(uint8_t row, uint8_t col, unsigned int ch);
+void video_get_rows_cols(uint32_t *rows, uint32_t *cols);
+void video_console_putchar(uint16_t ch);
+void video_console_putc(uint32_t row, uint32_t col, uint16_t ch);
 void video_console_clear(void);
-void video_console_cursor_enable(int state);
-void video_console_get_cursor(unsigned int *x, unsigned int *y, unsigned int *en);
-void video_console_set_cursor(unsigned int cursorx, unsigned int cursory);
+void video_console_set_cursor(uint32_t x, uint32_t y);
 /*
  * print characters on video console with colors. note that there is a size
  * restriction for the internal buffer. so, output string can be truncated.
diff --git a/src/libpayload/include/video_console.h b/src/libpayload/include/video_console.h
index dcac9cd..3ced6ac 100644
--- a/src/libpayload/include/video_console.h
+++ b/src/libpayload/include/video_console.h
@@ -28,18 +28,18 @@
 #ifndef _VIDEO_CONSOLE_H
 #define _VIDEO_CONSOLE_H
 
-struct video_console {
-	int (*init)(void);
-	void (*putc)(uint8_t, uint8_t, unsigned int);
-	void (*clear)(void);
-	void (*scroll_up)(void);
+typedef struct VideoConsole {
+	int (*init)(struct VideoConsole *me);
+	void (*putc)(struct VideoConsole *me,
+		     uint32_t row, uint32_t col, uint16_t ch);
+	void (*clear)(struct VideoConsole *me);
+	void (*scroll_up)(struct VideoConsole *me);
 
-	void (*get_cursor)(unsigned int *, unsigned int *, unsigned int *);
-	void (*set_cursor)(unsigned int, unsigned int);
-	void (*enable_cursor)(int);
+	void (*get_cursor)(struct VideoConsole *me, uint32_t *x, uint32_t *y);
+	void (*set_cursor)(struct VideoConsole *me, uint32_t x, uint32_t y);
 
-	unsigned int rows;
-	unsigned int columns;
-};
+	uint32_t rows;
+	uint32_t columns;
+} VideoConsole;
 
 #endif
diff --git a/src/vboot/callbacks/display.c b/src/vboot/callbacks/display.c
index dfda61f..cbeb46a 100644
--- a/src/vboot/callbacks/display.c
+++ b/src/vboot/callbacks/display.c
@@ -39,7 +39,6 @@
 		return VBERROR_UNKNOWN;
 
 	video_init();
-	video_console_cursor_enable(0);
 
 	if (lib_sysinfo.framebuffer) {
 		*width = lib_sysinfo.framebuffer->x_resolution;