/*
 * 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 */
	if ( ( character = utf8_accumulate ( &fbcon->utf8, 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 );
}
