/*
 * Copyright (C) 2013 Michael Brown <mbrown@fensystems.co.uk>.
 *
 * 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 of the
 * License, or 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., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 *
 * You can also choose to distribute this program under the terms of
 * the Unmodified Binary Distribution Licence (as given in the file
 * COPYING.UBDL), provided that you have satisfied its requirements.
 */

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );

/** @file
 *
 * Frame buffer console
 *
 */

#include <string.h>
#include <errno.h>
#include <assert.h>
#include <byteswap.h>
#include <ipxe/ansiesc.h>
#include <ipxe/image.h>
#include <ipxe/pixbuf.h>
#include <ipxe/umalloc.h>
#include <ipxe/console.h>
#include <ipxe/fbcon.h>

/**
 * Calculate raw colour value
 *
 * @v fbcon		Frame buffer console
 * @v rgb		24-bit RGB value
 * @ret raw		Raw colour
 */
static uint32_t fbcon_colour ( struct fbcon *fbcon, uint32_t rgb ) {
	struct fbcon_colour_map *map = fbcon->map;
	uint8_t red = ( rgb >> 16 );
	uint8_t green = ( rgb >> 8 );
	uint8_t blue = ( rgb >> 0 );
	uint32_t mapped;

	mapped = ( ( ( red >> map->red_scale ) << map->red_lsb ) |
		   ( ( green >> map->green_scale ) << map->green_lsb ) |
		   ( ( blue >> map->blue_scale ) << map->blue_lsb ) );
	return cpu_to_le32 ( mapped );
}

/**
 * Calculate ANSI font colour
 *
 * @v fbcon		Frame buffer console
 * @v ansicol		ANSI colour value (0-based)
 * @ret colour		Raw colour
 */
static uint32_t fbcon_ansi_colour ( struct fbcon *fbcon,
				    unsigned int ansicol ) {
	uint32_t rgb;

	/* Treat ansicol as 3-bit BGR with intensity 0xaa */
	rgb = ( ( ( ansicol & ( 1 << 0 ) ) ? 0xaa0000 : 0 ) |
		( ( ansicol & ( 1 << 1 ) ) ? 0x00aa00 : 0 ) |
		( ( ansicol & ( 1 << 2 ) ) ? 0x0000aa : 0 ) );

	return fbcon_colour ( fbcon, rgb );
}

/**
 * Set default foreground colour
 *
 * @v fbcon		Frame buffer console
 */
static void fbcon_set_default_foreground ( struct fbcon *fbcon ) {

	/* Default to non-bold white foreground */
	fbcon->foreground = fbcon_ansi_colour ( fbcon, 0x7 );
	fbcon->bold = 0;
}

/**
 * Set default background colour
 *
 * @v fbcon		Frame buffer console
 */
static void fbcon_set_default_background ( struct fbcon *fbcon ) {

	/* Default to transparent background */
	fbcon->background = FBCON_TRANSPARENT;
}

/**
 * Clear rows of characters
 *
 * @v fbcon		Frame buffer console
 * @v ypos		Starting Y position
 */
static void fbcon_clear ( struct fbcon *fbcon, unsigned int ypos ) {
	struct fbcon_text_cell cell = {
		.foreground = fbcon->foreground,
		.background = fbcon->background,
		.character = ' ',
	};
	size_t offset;
	unsigned int xpos;

	/* Clear stored character array */
	for ( ; ypos < fbcon->character.height ; ypos++ ) {
		offset = ( ypos * fbcon->character.width * sizeof ( cell ) );
		for ( xpos = 0 ; xpos < fbcon->character.width ; xpos++ ) {
			copy_to_user ( fbcon->text.start, offset, &cell,
				       sizeof ( cell ) );
			offset += sizeof ( cell );
		}
	}
}

/**
 * Store character at specified position
 *
 * @v fbcon		Frame buffer console
 * @v cell		Text cell
 * @v xpos		X position
 * @v ypos		Y position
 */
static void fbcon_store ( struct fbcon *fbcon, struct fbcon_text_cell *cell,
			  unsigned int xpos, unsigned int ypos ) {
	size_t offset;

	/* Store cell */
	offset = ( ( ( ypos * fbcon->character.width ) + xpos ) *
		   sizeof ( *cell ) );
	copy_to_user ( fbcon->text.start, offset, cell, sizeof ( *cell ) );
}

/**
 * Draw character at specified position
 *
 * @v fbcon		Frame buffer console
 * @v cell		Text cell
 * @v xpos		X position
 * @v ypos		Y position
 */
static void fbcon_draw ( struct fbcon *fbcon, struct fbcon_text_cell *cell,
			 unsigned int xpos, unsigned int ypos ) {
	uint8_t glyph[fbcon->font->height];
	size_t offset;
	size_t pixel_len;
	size_t skip_len;
	unsigned int row;
	unsigned int column;
	uint8_t bitmask;
	int transparent;
	void *src;

	/* Get font character */
	fbcon->font->glyph ( cell->character, glyph );

	/* Calculate pixel geometry */
	offset = ( fbcon->indent +
		   ( ypos * fbcon->character.stride ) +
		   ( xpos * fbcon->character.len ) );
	pixel_len = fbcon->pixel->len;
	skip_len = ( fbcon->pixel->stride - fbcon->character.len );

	/* Check for transparent background colour */
	transparent = ( cell->background == FBCON_TRANSPARENT );

	/* Draw character rows */
	for ( row = 0 ; row < fbcon->font->height ; row++ ) {

		/* Draw background picture, if applicable */
		if ( transparent ) {
			if ( fbcon->picture.start ) {
				memcpy_user ( fbcon->start, offset,
					      fbcon->picture.start, offset,
					      fbcon->character.len );
			} else {
				memset_user ( fbcon->start, offset, 0,
					      fbcon->character.len );
			}
		}

		/* Draw character row */
		for ( column = FBCON_CHAR_WIDTH, bitmask = glyph[row] ;
		      column ; column--, bitmask <<= 1, offset += pixel_len ) {
			if ( bitmask & 0x80 ) {
				src = &cell->foreground;
			} else if ( ! transparent ) {
				src = &cell->background;
			} else {
				continue;
			}
			copy_to_user ( fbcon->start, offset, src, pixel_len );
		}

		/* Move to next row */
		offset += skip_len;
	}
}

/**
 * Redraw all characters
 *
 * @v fbcon		Frame buffer console
 */
static void fbcon_redraw ( struct fbcon *fbcon ) {
	struct fbcon_text_cell cell;
	size_t offset = 0;
	unsigned int xpos;
	unsigned int ypos;

	/* Redraw characters */
	for ( ypos = 0 ; ypos < fbcon->character.height ; ypos++ ) {
		for ( xpos = 0 ; xpos < fbcon->character.width ; xpos++ ) {
			copy_from_user ( &cell, fbcon->text.start, offset,
					 sizeof ( cell ) );
			fbcon_draw ( fbcon, &cell, xpos, ypos );
			offset += sizeof ( cell );
		}
	}
}

/**
 * Scroll screen
 *
 * @v fbcon		Frame buffer console
 */
static void fbcon_scroll ( struct fbcon *fbcon ) {
	size_t row_len;

	/* Sanity check */
	assert ( fbcon->ypos == fbcon->character.height );

	/* Scroll up character array */
	row_len = ( fbcon->character.width * sizeof ( struct fbcon_text_cell ));
	memmove_user ( fbcon->text.start, 0, fbcon->text.start, row_len,
		       ( row_len * ( fbcon->character.height - 1 ) ) );
	fbcon_clear ( fbcon, ( fbcon->character.height - 1 ) );

	/* Update cursor position */
	fbcon->ypos--;

	/* Redraw all characters */
	fbcon_redraw ( fbcon );
}

/**
 * Draw character at cursor position
 *
 * @v fbcon		Frame buffer console
 * @v show_cursor	Show cursor
 */
static void fbcon_draw_cursor ( struct fbcon *fbcon, int show_cursor ) {
	struct fbcon_text_cell cell;
	size_t offset;

	offset = ( ( ( fbcon->ypos * fbcon->character.width ) + fbcon->xpos ) *
		   sizeof ( cell ) );
	copy_from_user ( &cell, fbcon->text.start, offset, sizeof ( cell ) );
	if ( show_cursor ) {
		cell.background = fbcon->foreground;
		cell.foreground = ( ( fbcon->background == FBCON_TRANSPARENT ) ?
				    0 : fbcon->background );
	}
	fbcon_draw ( fbcon, &cell, fbcon->xpos, fbcon->ypos );
}

/**
 * Handle ANSI CUP (cursor position)
 *
 * @v ctx		ANSI escape sequence context
 * @v count		Parameter count
 * @v params[0]		Row (1 is top)
 * @v params[1]		Column (1 is left)
 */
static void fbcon_handle_cup ( struct ansiesc_context *ctx,
			       unsigned int count __unused, int params[] ) {
	struct fbcon *fbcon = container_of ( ctx, struct fbcon, ctx );
	int cx = ( params[1] - 1 );
	int cy = ( params[0] - 1 );

	fbcon_draw_cursor ( fbcon, 0 );
	fbcon->xpos = cx;
	if ( fbcon->xpos >= fbcon->character.width )
		fbcon->xpos = 0;
	fbcon->ypos = cy;
	if ( fbcon->ypos >= fbcon->character.height )
		fbcon->ypos = 0;
	fbcon_draw_cursor ( fbcon, fbcon->show_cursor );
}

/**
 * Handle ANSI ED (erase in page)
 *
 * @v ctx		ANSI escape sequence context
 * @v count		Parameter count
 * @v params[0]		Region to erase
 */
static void fbcon_handle_ed ( struct ansiesc_context *ctx,
			      unsigned int count __unused,
			      int params[] __unused ) {
	struct fbcon *fbcon = container_of ( ctx, struct fbcon, ctx );

	/* We assume that we always clear the whole screen */
	assert ( params[0] == ANSIESC_ED_ALL );

	/* Clear character array */
	fbcon_clear ( fbcon, 0 );

	/* Redraw all characters */
	fbcon_redraw ( fbcon );

	/* Reset cursor position */
	fbcon->xpos = 0;
	fbcon->ypos = 0;
	fbcon_draw_cursor ( fbcon, fbcon->show_cursor );
}

/**
 * Handle ANSI SGR (set graphics rendition)
 *
 * @v ctx		ANSI escape sequence context
 * @v count		Parameter count
 * @v params		List of graphic rendition aspects
 */
static void fbcon_handle_sgr ( struct ansiesc_context *ctx, unsigned int count,
			       int params[] ) {
	struct fbcon *fbcon = container_of ( ctx, struct fbcon, ctx );
	uint32_t *custom = NULL;
	uint32_t rgb;
	unsigned int end;
	unsigned int i;
	int aspect;

	for ( i = 0 ; i < count ; i++ ) {

		/* Process aspect */
		aspect = params[i];
		if ( aspect == 0 ) {
			fbcon_set_default_foreground ( fbcon );
			fbcon_set_default_background ( fbcon );
		} else if ( aspect == 1 ) {
			fbcon->bold = fbcon_colour ( fbcon, FBCON_BOLD );
		} else if ( aspect == 22 ) {
			fbcon->bold = 0;
		} else if ( ( aspect >= 30 ) && ( aspect <= 37 ) ) {
			fbcon->foreground =
				fbcon_ansi_colour ( fbcon, aspect - 30 );
		} else if ( aspect == 38 ) {
			custom = &fbcon->foreground;
		} else if ( aspect == 39 ) {
			fbcon_set_default_foreground ( fbcon );
		} else if ( ( aspect >= 40 ) && ( aspect <= 47 ) ) {
			fbcon->background =
				fbcon_ansi_colour ( fbcon, aspect - 40 );
		} else if ( aspect == 48 ) {
			custom = &fbcon->background;
		} else if ( aspect == 49 ) {
			fbcon_set_default_background ( fbcon );
		}

		/* Process custom RGB colour, if applicable
		 *
		 * We support the xterm-compatible
		 * "<ESC>[38;2;<red>;<green>;<blue>m" and
		 * "<ESC>[48;2;<red>;<green>;<blue>m" sequences.
		 */
		if ( custom ) {
			rgb = 0;
			end = ( i + 5 );
			for ( ; ( i < count ) && ( i < end ) ; i++ )
				rgb = ( ( rgb << 8 ) | params[i] );
			*custom = fbcon_colour ( fbcon, rgb );
			custom = NULL;
		}
	}
}

/**
 * Handle ANSI DECTCEM set (show cursor)
 *
 * @v ctx		ANSI escape sequence context
 * @v count		Parameter count
 * @v params		List of graphic rendition aspects
 */
static void fbcon_handle_dectcem_set ( struct ansiesc_context *ctx,
				       unsigned int count __unused,
				       int params[] __unused ) {
	struct fbcon *fbcon = container_of ( ctx, struct fbcon, ctx );

	fbcon->show_cursor = 1;
	fbcon_draw_cursor ( fbcon, 1 );
}

/**
 * Handle ANSI DECTCEM reset (hide cursor)
 *
 * @v ctx		ANSI escape sequence context
 * @v count		Parameter count
 * @v params		List of graphic rendition aspects
 */
static void fbcon_handle_dectcem_reset ( struct ansiesc_context *ctx,
					 unsigned int count __unused,
					 int params[] __unused ) {
	struct fbcon *fbcon = container_of ( ctx, struct fbcon, ctx );

	fbcon->show_cursor = 0;
	fbcon_draw_cursor ( fbcon, 0 );
}

/** ANSI escape sequence handlers */
static struct ansiesc_handler fbcon_ansiesc_handlers[] = {
	{ ANSIESC_CUP, fbcon_handle_cup },
	{ ANSIESC_ED, fbcon_handle_ed },
	{ ANSIESC_SGR, fbcon_handle_sgr },
	{ ANSIESC_DECTCEM_SET, fbcon_handle_dectcem_set },
	{ ANSIESC_DECTCEM_RESET, fbcon_handle_dectcem_reset },
	{ 0, NULL }
};

/**
 * Print a character to current cursor position
 *
 * @v fbcon		Frame buffer console
 * @v character		Character
 */
void fbcon_putchar ( struct fbcon *fbcon, int character ) {
	struct fbcon_text_cell cell;

	/* Intercept ANSI escape sequences */
	character = ansiesc_process ( &fbcon->ctx, character );
	if ( character < 0 )
		return;

	/* Accumulate Unicode characters */
	character = utf8_accumulate ( &fbcon->utf8, character );
	if ( character == 0 )
		return;

	/* Handle control characters */
	switch ( character ) {
	case '\r':
		fbcon_draw_cursor ( fbcon, 0 );
		fbcon->xpos = 0;
		break;
	case '\n':
		fbcon_draw_cursor ( fbcon, 0 );
		fbcon->xpos = 0;
		fbcon->ypos++;
		break;
	case '\b':
		fbcon_draw_cursor ( fbcon, 0 );
		if ( fbcon->xpos ) {
			fbcon->xpos--;
		} else if ( fbcon->ypos ) {
			fbcon->xpos = ( fbcon->character.width - 1 );
			fbcon->ypos--;
		}
		break;
	default:
		/* Print character at current cursor position */
		cell.foreground = ( fbcon->foreground | fbcon->bold );
		cell.background = fbcon->background;
		cell.character = character;
		fbcon_store ( fbcon, &cell, fbcon->xpos, fbcon->ypos );
		fbcon_draw ( fbcon, &cell, fbcon->xpos, fbcon->ypos );

		/* Advance cursor */
		fbcon->xpos++;
		if ( fbcon->xpos >= fbcon->character.width ) {
			fbcon->xpos = 0;
			fbcon->ypos++;
		}
		break;
	}

	/* Scroll screen if necessary */
	if ( fbcon->ypos >= fbcon->character.height )
		fbcon_scroll ( fbcon );

	/* Show cursor */
	fbcon_draw_cursor ( fbcon, fbcon->show_cursor );
}

/**
 * Initialise background picture
 *
 * @v fbcon		Frame buffer console
 * @v pixbuf		Background picture
 * @ret rc		Return status code
 */
static int fbcon_picture_init ( struct fbcon *fbcon,
				struct pixel_buffer *pixbuf ) {
	struct fbcon_geometry *pixel = fbcon->pixel;
	struct fbcon_picture *picture = &fbcon->picture;
	size_t len;
	size_t pixbuf_stride;
	size_t indent;
	size_t pixbuf_indent;
	size_t offset;
	size_t pixbuf_offset;
	uint32_t rgb;
	uint32_t raw;
	unsigned int x;
	unsigned int y;
	unsigned int width;
	unsigned int height;
	int xgap;
	int ygap;
	int rc;

	/* Allocate buffer */
	len = ( pixel->height * pixel->stride );
	picture->start = umalloc ( len );
	if ( ! picture->start ) {
		DBGC ( fbcon, "FBCON %p could not allocate %zd bytes for "
		       "picture\n", fbcon, len );
		rc = -ENOMEM;
		goto err_umalloc;
	}

	/* Centre picture on console */
	pixbuf_stride = ( pixbuf->width * sizeof ( rgb ) );
	xgap = ( ( ( int ) ( pixel->width - pixbuf->width ) ) / 2 );
	ygap = ( ( ( int ) ( pixel->height - pixbuf->height ) ) / 2 );
	indent = ( ( ( ( ygap >= 0 ) ? ygap : 0 ) * pixel->stride ) +
		   ( ( ( xgap >= 0 ) ? xgap : 0 ) * pixel->len ) );
	pixbuf_indent =	( ( ( ( ygap < 0 ) ? -ygap : 0 ) * pixbuf_stride ) +
			  ( ( ( xgap < 0 ) ? -xgap : 0 ) * sizeof ( rgb ) ) );
	width = pixbuf->width;
	if ( width > pixel->width )
		width = pixel->width;
	height = pixbuf->height;
	if ( height > pixel->height )
		height = pixel->height;
	DBGC ( fbcon, "FBCON %p picture is pixel %dx%d at [%d,%d),[%d,%d)\n",
	       fbcon, width, height, xgap, ( xgap + pixbuf->width ), ygap,
	       ( ygap + pixbuf->height ) );

	/* Convert to frame buffer raw format */
	memset_user ( picture->start, 0, 0, len );
	for ( y = 0 ; y < height ; y++ ) {
		offset = ( indent + ( y * pixel->stride ) );
		pixbuf_offset = ( pixbuf_indent + ( y * pixbuf_stride ) );
		for ( x = 0 ; x < width ; x++ ) {
			copy_from_user ( &rgb, pixbuf->data, pixbuf_offset,
					 sizeof ( rgb ) );
			raw = fbcon_colour ( fbcon, rgb );
			copy_to_user ( picture->start, offset, &raw,
				       pixel->len );
			offset += pixel->len;
			pixbuf_offset += sizeof ( rgb );
		}
	}

	return 0;

	ufree ( picture->start );
 err_umalloc:
	return rc;
}

/**
 * Initialise frame buffer console
 *
 * @v fbcon		Frame buffer console
 * @v start		Start address
 * @v pixel		Pixel geometry
 * @v map		Colour mapping
 * @v font		Font definition
 * @v config		Console configuration
 * @ret rc		Return status code
 */
int fbcon_init ( struct fbcon *fbcon, userptr_t start,
		 struct fbcon_geometry *pixel,
		 struct fbcon_colour_map *map,
		 struct fbcon_font *font,
		 struct console_configuration *config ) {
	int width;
	int height;
	unsigned int xgap;
	unsigned int ygap;
	unsigned int left;
	unsigned int right;
	unsigned int top;
	unsigned int bottom;
	int rc;

	/* Initialise data structure */
	memset ( fbcon, 0, sizeof ( *fbcon ) );
	fbcon->start = start;
	fbcon->pixel = pixel;
	assert ( pixel->len <= sizeof ( uint32_t ) );
	fbcon->map = map;
	fbcon->font = font;
	fbcon->ctx.handlers = fbcon_ansiesc_handlers;
	fbcon->show_cursor = 1;

	/* Derive overall length */
	fbcon->len = ( pixel->height * pixel->stride );
	DBGC ( fbcon, "FBCON %p at [%08lx,%08lx)\n", fbcon,
	       user_to_phys ( fbcon->start, 0 ),
	       user_to_phys ( fbcon->start, fbcon->len ) );

	/* Calculate margin.  If the actual screen size is larger than
	 * the requested screen size, then update the margins so that
	 * the margin remains relative to the requested screen size.
	 * (As an exception, if a zero margin was specified then treat
	 * this as meaning "expand to edge of actual screen".)
	 */
	xgap = ( pixel->width - config->width );
	ygap = ( pixel->height - config->height );
	left = ( xgap / 2 );
	right = ( xgap - left );
	top = ( ygap / 2 );
	bottom = ( ygap - top );
	fbcon->margin.left = ( config->left + ( config->left ? left : 0 ) );
	fbcon->margin.right = ( config->right + ( config->right ? right : 0 ) );
	fbcon->margin.top = ( config->top + ( config->top ? top : 0 ) );
	fbcon->margin.bottom =
		( config->bottom + ( config->bottom ? bottom : 0 ) );

	/* Expand margin to accommodate whole characters */
	width = ( pixel->width - fbcon->margin.left - fbcon->margin.right );
	height = ( pixel->height - fbcon->margin.top - fbcon->margin.bottom );
	if ( ( width < FBCON_CHAR_WIDTH ) ||
	     ( height < ( ( int ) font->height ) ) ) {
		DBGC ( fbcon, "FBCON %p has unusable character area "
		       "[%d-%d),[%d-%d)\n", fbcon, fbcon->margin.left,
		       ( pixel->width - fbcon->margin.right ),
		       fbcon->margin.top,
		       ( pixel->height - fbcon->margin.bottom ) );
		rc = -EINVAL;
		goto err_margin;
	}
	xgap = ( width % FBCON_CHAR_WIDTH );
	ygap = ( height % font->height );
	fbcon->margin.left += ( xgap / 2 );
	fbcon->margin.top += ( ygap / 2 );
	fbcon->margin.right += ( xgap - ( xgap / 2 ) );
	fbcon->margin.bottom += ( ygap - ( ygap / 2 ) );
	fbcon->indent = ( ( fbcon->margin.top * pixel->stride ) +
			  ( fbcon->margin.left * pixel->len ) );

	/* Derive character geometry from pixel geometry */
	fbcon->character.width = ( width / FBCON_CHAR_WIDTH );
	fbcon->character.height = ( height / font->height );
	fbcon->character.len = ( pixel->len * FBCON_CHAR_WIDTH );
	fbcon->character.stride = ( pixel->stride * font->height );
	DBGC ( fbcon, "FBCON %p is pixel %dx%d, char %dx%d at "
	       "[%d-%d),[%d-%d)\n", fbcon, fbcon->pixel->width,
	       fbcon->pixel->height, fbcon->character.width,
	       fbcon->character.height, fbcon->margin.left,
	       ( fbcon->pixel->width - fbcon->margin.right ),
	       fbcon->margin.top,
	       ( fbcon->pixel->height - fbcon->margin.bottom ) );

	/* Set default colours */
	fbcon_set_default_foreground ( fbcon );
	fbcon_set_default_background ( fbcon );

	/* Allocate and initialise stored character array */
	fbcon->text.start = umalloc ( fbcon->character.width *
				      fbcon->character.height *
				      sizeof ( struct fbcon_text_cell ) );
	if ( ! fbcon->text.start ) {
		rc = -ENOMEM;
		goto err_text;
	}
	fbcon_clear ( fbcon, 0 );

	/* Set framebuffer to all black (including margins) */
	memset_user ( fbcon->start, 0, 0, fbcon->len );

	/* Generate pixel buffer from background image, if applicable */
	if ( config->pixbuf &&
	     ( ( rc = fbcon_picture_init ( fbcon, config->pixbuf ) ) != 0 ) )
		goto err_picture;

	/* Draw background picture (including margins), if applicable */
	if ( fbcon->picture.start ) {
		memcpy_user ( fbcon->start, 0, fbcon->picture.start, 0,
			      fbcon->len );
	}

	/* Update console width and height */
	console_set_size ( fbcon->character.width, fbcon->character.height );

	return 0;

	ufree ( fbcon->picture.start );
 err_picture:
	ufree ( fbcon->text.start );
 err_text:
 err_margin:
	return rc;
}

/**
 * Finalise frame buffer console
 *
 * @v fbcon		Frame buffer console
 */
void fbcon_fini ( struct fbcon *fbcon ) {

	ufree ( fbcon->text.start );
	ufree ( fbcon->picture.start );
}
