/*
 * 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
 *
 * VESA frame buffer console
 *
 */

#include <stdlib.h>
#include <errno.h>
#include <limits.h>
#include <realmode.h>
#include <ipxe/console.h>
#include <ipxe/io.h>
#include <ipxe/ansicol.h>
#include <ipxe/fbcon.h>
#include <ipxe/vesafb.h>
#include <config/console.h>

/* Avoid dragging in BIOS console if not otherwise used */
extern struct console_driver bios_console;
struct console_driver bios_console __attribute__ (( weak ));

/* Disambiguate the various error causes */
#define EIO_FAILED __einfo_error ( EINFO_EIO_FAILED )
#define EINFO_EIO_FAILED						\
	__einfo_uniqify ( EINFO_EIO, 0x01,				\
			  "Function call failed" )
#define EIO_HARDWARE __einfo_error ( EINFO_EIO_HARDWARE )
#define EINFO_EIO_HARDWARE						\
	__einfo_uniqify ( EINFO_EIO, 0x02,				\
			  "Not supported in current configuration" )
#define EIO_MODE __einfo_error ( EINFO_EIO_MODE )
#define EINFO_EIO_MODE							\
	__einfo_uniqify ( EINFO_EIO, 0x03,				\
			  "Invalid in current video mode" )
#define EIO_VBE( code )							\
	EUNIQ ( EINFO_EIO, (code), EIO_FAILED, EIO_HARDWARE, EIO_MODE )

/* Set default console usage if applicable
 *
 * We accept either CONSOLE_FRAMEBUFFER or CONSOLE_VESAFB.
 */
#if ( defined ( CONSOLE_FRAMEBUFFER ) && ! defined ( CONSOLE_VESAFB ) )
#define CONSOLE_VESAFB CONSOLE_FRAMEBUFFER
#endif
#if ! ( defined ( CONSOLE_VESAFB ) && CONSOLE_EXPLICIT ( CONSOLE_VESAFB ) )
#undef CONSOLE_VESAFB
#define CONSOLE_VESAFB ( CONSOLE_USAGE_ALL & ~CONSOLE_USAGE_LOG )
#endif

/** Character height */
#define VESAFB_CHAR_HEIGHT 16

/** Font corresponding to selected character width and height */
#define VESAFB_FONT VBE_FONT_8x16

/** Number of ASCII glyphs within the font */
#define VESAFB_ASCII 128

/** Glyph to render for non-ASCII characters
 *
 * We choose to use one of the box-drawing glyphs.
 */
#define VESAFB_UNKNOWN 0xfe

/* Forward declaration */
struct console_driver vesafb_console __console_driver;

/** A VESA frame buffer */
struct vesafb {
	/** Frame buffer console */
	struct fbcon fbcon;
	/** Physical start address */
	physaddr_t start;
	/** Pixel geometry */
	struct fbcon_geometry pixel;
	/** Colour mapping */
	struct fbcon_colour_map map;
	/** Font definition */
	struct fbcon_font font;
	/** Character glyphs */
	struct segoff glyphs;
	/** Saved VGA mode */
	uint8_t saved_mode;
};

/** The VESA frame buffer */
static struct vesafb vesafb;

/** Base memory buffer used for VBE calls */
union vbe_buffer {
	/** VBE controller information block */
	struct vbe_controller_info controller;
	/** VBE mode information block */
	struct vbe_mode_info mode;
};
static union vbe_buffer __bss16 ( vbe_buf );
#define vbe_buf __use_data16 ( vbe_buf )

/**
 * Convert VBE status code to iPXE status code
 *
 * @v status		VBE status code
 * @ret rc		Return status code
 */
static int vesafb_rc ( unsigned int status ) {
	unsigned int code;

	if ( ( status & 0xff ) != 0x4f )
		return -ENOTSUP;
	code = ( ( status >> 8 ) & 0xff );
	return ( code ? -EIO_VBE ( code ) : 0 );
}

/**
 * Get character glyph
 *
 * @v character		Unicode character
 * @v glyph		Character glyph to fill in
 */
static void vesafb_glyph ( unsigned int character, uint8_t *glyph ) {
	unsigned int index;
	size_t offset;

	/* Identify glyph */
	if ( character < VESAFB_ASCII ) {
		/* ASCII character: use corresponding glyph */
		index = character;
	} else {
		/* Non-ASCII character: use "unknown" glyph */
		index = VESAFB_UNKNOWN;
	}

	/* Copy glyph from BIOS font table */
	offset = ( index * VESAFB_CHAR_HEIGHT );
	copy_from_real ( glyph, vesafb.glyphs.segment,
			 ( vesafb.glyphs.offset + offset ), VESAFB_CHAR_HEIGHT);
}

/**
 * Get font definition
 *
 */
static void vesafb_font ( void ) {

	/* Get font information
	 *
	 * Working around gcc bugs is icky here.  The value we want is
	 * returned in %ebp, but there's no way to specify %ebp in an
	 * output constraint.  We can't put %ebp in the clobber list,
	 * because this tends to cause random build failures on some
	 * gcc versions.  We can't manually push/pop %ebp and return
	 * the value via a generic register output constraint, because
	 * gcc might choose to use %ebp to satisfy that constraint
	 * (and we have no way to prevent it from so doing).
	 *
	 * Work around this hideous mess by using %ecx and %edx as the
	 * output registers, since they get clobbered anyway.
	 */
	__asm__ __volatile__ ( REAL_CODE ( "pushw %%bp\n\t" /* gcc bug */
					   "int $0x10\n\t"
					   "movw %%es, %%cx\n\t"
					   "movw %%bp, %%dx\n\t"
					   "popw %%bp\n\t" /* gcc bug */ )
			       : "=c" ( vesafb.glyphs.segment ),
				 "=d" ( vesafb.glyphs.offset )
			       : "a" ( VBE_GET_FONT ),
				 "b" ( VESAFB_FONT ) );
	DBGC ( &vbe_buf, "VESAFB has font %04x at %04x:%04x\n",
	       VESAFB_FONT, vesafb.glyphs.segment, vesafb.glyphs.offset );
	vesafb.font.height = VESAFB_CHAR_HEIGHT;
	vesafb.font.glyph = vesafb_glyph;
}

/**
 * Get VBE mode list
 *
 * @ret mode_numbers	Mode number list (terminated with VBE_MODE_END)
 * @ret rc		Return status code
 *
 * The caller is responsible for eventually freeing the mode list.
 */
static int vesafb_mode_list ( uint16_t **mode_numbers ) {
	struct vbe_controller_info *controller = &vbe_buf.controller;
	userptr_t video_mode_ptr;
	uint16_t mode_number;
	uint16_t status;
	size_t len;
	int rc;

	/* Avoid returning uninitialised data on error */
	*mode_numbers = NULL;

	/* Get controller information block */
	controller->vbe_signature = 0;
	__asm__ __volatile__ ( REAL_CODE ( "int $0x10" )
			       : "=a" ( status )
			       : "a" ( VBE_CONTROLLER_INFO ),
				 "D" ( __from_data16 ( controller ) )
			       : "memory", "ebx", "edx" );
	if ( ( rc = vesafb_rc ( status ) ) != 0 ) {
		DBGC ( &vbe_buf, "VESAFB could not get controller information: "
		       "[%04x] %s\n", status, strerror ( rc ) );
		return rc;
	}
	if ( controller->vbe_signature != VBE_CONTROLLER_SIGNATURE ) {
		DBGC ( &vbe_buf, "VESAFB invalid controller signature "
		       "\"%c%c%c%c\"\n", ( controller->vbe_signature >> 0 ),
		       ( controller->vbe_signature >> 8 ),
		       ( controller->vbe_signature >> 16 ),
		       ( controller->vbe_signature >> 24 ) );
		DBGC_HDA ( &vbe_buf, 0, controller, sizeof ( *controller ) );
		return -EINVAL;
	}
	DBGC ( &vbe_buf, "VESAFB found VBE version %d.%d with mode list at "
	       "%04x:%04x\n", controller->vbe_major_version,
	       controller->vbe_minor_version,
	       controller->video_mode_ptr.segment,
	       controller->video_mode_ptr.offset );

	/* Calculate length of mode list */
	video_mode_ptr = real_to_user ( controller->video_mode_ptr.segment,
					controller->video_mode_ptr.offset );
	len = 0;
	do {
		copy_from_user ( &mode_number, video_mode_ptr, len,
				 sizeof ( mode_number ) );
		len += sizeof ( mode_number );
	} while ( mode_number != VBE_MODE_END );

	/* Allocate and fill mode list */
	*mode_numbers = malloc ( len );
	if ( ! *mode_numbers )
		return -ENOMEM;
	copy_from_user ( *mode_numbers, video_mode_ptr, 0, len );

	return 0;
}

/**
 * Get video mode information
 *
 * @v mode_number	Mode number
 * @ret rc		Return status code
 */
static int vesafb_mode_info ( unsigned int mode_number ) {
	struct vbe_mode_info *mode = &vbe_buf.mode;
	uint16_t status;
	int rc;

	/* Get mode information */
	__asm__ __volatile__ ( REAL_CODE ( "int $0x10" )
			       : "=a" ( status )
			       : "a" ( VBE_MODE_INFO ),
				 "c" ( mode_number ),
				 "D" ( __from_data16 ( mode ) )
			       : "memory" );
	if ( ( rc = vesafb_rc ( status ) ) != 0 ) {
		DBGC ( &vbe_buf, "VESAFB could not get mode %04x information: "
		       "[%04x] %s\n", mode_number, status, strerror ( rc ) );
		return rc;
	}
	DBGC ( &vbe_buf, "VESAFB mode %04x %dx%d %dbpp(%d:%d:%d:%d) model "
	       "%02x [x%d]%s%s%s%s%s\n", mode_number, mode->x_resolution,
	       mode->y_resolution, mode->bits_per_pixel, mode->rsvd_mask_size,
	       mode->red_mask_size, mode->green_mask_size, mode->blue_mask_size,
	       mode->memory_model, ( mode->number_of_image_pages + 1 ),
	       ( ( mode->mode_attributes & VBE_MODE_ATTR_SUPPORTED ) ?
		 "" : " [unsupported]" ),
	       ( ( mode->mode_attributes & VBE_MODE_ATTR_TTY ) ?
		 " [tty]" : "" ),
	       ( ( mode->mode_attributes & VBE_MODE_ATTR_GRAPHICS ) ?
		 "" : " [text]" ),
	       ( ( mode->mode_attributes & VBE_MODE_ATTR_LINEAR ) ?
		 "" : " [nonlinear]" ),
	       ( ( mode->mode_attributes & VBE_MODE_ATTR_TRIPLE_BUF ) ?
		 " [buf]" : "" ) );

	return 0;
}

/**
 * Set video mode
 *
 * @v mode_number	Mode number
 * @ret rc		Return status code
 */
static int vesafb_set_mode ( unsigned int mode_number ) {
	struct vbe_mode_info *mode = &vbe_buf.mode;
	uint16_t status;
	int rc;

	/* Get mode information */
	if ( ( rc = vesafb_mode_info ( mode_number ) ) != 0 )
		return rc;

	/* Record mode parameters */
	vesafb.start = mode->phys_base_ptr;
	vesafb.pixel.width = mode->x_resolution;
	vesafb.pixel.height = mode->y_resolution;
	vesafb.pixel.len = ( ( mode->bits_per_pixel + 7 ) / 8 );
	vesafb.pixel.stride = mode->bytes_per_scan_line;
	DBGC ( &vbe_buf, "VESAFB mode %04x has frame buffer at %08x\n",
	       mode_number, mode->phys_base_ptr );

	/* Initialise font colours */
	vesafb.map.red_scale = ( 8 - mode->red_mask_size );
	vesafb.map.green_scale = ( 8 - mode->green_mask_size );
	vesafb.map.blue_scale = ( 8 - mode->blue_mask_size );
	vesafb.map.red_lsb = mode->red_field_position;
	vesafb.map.green_lsb = mode->green_field_position;
	vesafb.map.blue_lsb = mode->blue_field_position;

	/* Select this mode */
	__asm__ __volatile__ ( REAL_CODE ( "int $0x10" )
			       : "=a" ( status )
			       : "a" ( VBE_SET_MODE ),
				 "b" ( mode_number ) );
	if ( ( rc = vesafb_rc ( status ) ) != 0 ) {
		DBGC ( &vbe_buf, "VESAFB could not set mode %04x: [%04x] %s\n",
		       mode_number, status, strerror ( rc ) );
		return rc;
	}

	return 0;
}

/**
 * Select video mode
 *
 * @v mode_numbers	Mode number list (terminated with VBE_MODE_END)
 * @v min_width		Minimum required width (in pixels)
 * @v min_height	Minimum required height (in pixels)
 * @v min_bpp		Minimum required colour depth (in bits per pixel)
 * @ret mode_number	Mode number, or negative error
 */
static int vesafb_select_mode ( const uint16_t *mode_numbers,
				unsigned int min_width, unsigned int min_height,
				unsigned int min_bpp ) {
	struct vbe_mode_info *mode = &vbe_buf.mode;
	int best_mode_number = -ENOENT;
	unsigned int best_score = INT_MAX;
	unsigned int score;
	uint16_t mode_number;
	int rc;

	/* Find the first suitable mode */
	while ( ( mode_number = *(mode_numbers++) ) != VBE_MODE_END ) {

		/* Force linear mode variant */
		mode_number |= VBE_MODE_LINEAR;

		/* Get mode information */
		if ( ( rc = vesafb_mode_info ( mode_number ) ) != 0 )
			continue;

		/* Skip unusable modes */
		if ( ( mode->mode_attributes & ( VBE_MODE_ATTR_SUPPORTED |
						 VBE_MODE_ATTR_GRAPHICS |
						 VBE_MODE_ATTR_LINEAR ) ) !=
		     ( VBE_MODE_ATTR_SUPPORTED | VBE_MODE_ATTR_GRAPHICS |
		       VBE_MODE_ATTR_LINEAR ) ) {
			continue;
		}
		if ( mode->memory_model != VBE_MODE_MODEL_DIRECT_COLOUR )
			continue;

		/* Skip modes not meeting the requirements */
		if ( ( mode->x_resolution < min_width ) ||
		     ( mode->y_resolution < min_height ) ||
		     ( mode->bits_per_pixel < min_bpp ) ) {
			continue;
		}

		/* Select this mode if it has the best (i.e. lowest)
		 * score.  We choose the scoring system to favour
		 * modes close to the specified width and height;
		 * within modes of the same width and height we prefer
		 * a higher colour depth.
		 */
		score = ( ( mode->x_resolution * mode->y_resolution ) -
			  mode->bits_per_pixel );
		if ( score < best_score ) {
			best_mode_number = mode_number;
			best_score = score;
		}
	}

	if ( best_mode_number >= 0 ) {
		DBGC ( &vbe_buf, "VESAFB selected mode %04x\n",
		       best_mode_number );
	} else {
		DBGC ( &vbe_buf, "VESAFB found no suitable mode\n" );
	}

	return best_mode_number;
}

/**
 * Restore video mode
 *
 */
static void vesafb_restore ( void ) {
	uint32_t discard_a;

	/* Restore saved VGA mode */
	__asm__ __volatile__ ( REAL_CODE ( "int $0x10" )
			       : "=a" ( discard_a )
			       : "a" ( VBE_SET_VGA_MODE | vesafb.saved_mode ) );
	DBGC ( &vbe_buf, "VESAFB restored VGA mode %#02x\n",
	       vesafb.saved_mode );
}

/**
 * Initialise VESA frame buffer
 *
 * @v config		Console configuration, or NULL to reset
 * @ret rc		Return status code
 */
static int vesafb_init ( struct console_configuration *config ) {
	uint32_t discard_b;
	uint16_t *mode_numbers;
	int mode_number;
	int rc;

	/* Record current VGA mode */
	__asm__ __volatile__ ( REAL_CODE ( "int $0x10" )
			       : "=a" ( vesafb.saved_mode ), "=b" ( discard_b )
			       : "a" ( VBE_GET_VGA_MODE ) );
	DBGC ( &vbe_buf, "VESAFB saved VGA mode %#02x\n", vesafb.saved_mode );

	/* Get VESA mode list */
	if ( ( rc = vesafb_mode_list ( &mode_numbers ) ) != 0 )
		goto err_mode_list;

	/* Select mode */
	if ( ( mode_number = vesafb_select_mode ( mode_numbers, config->width,
						  config->height,
						  config->depth ) ) < 0 ) {
		rc = mode_number;
		goto err_select_mode;
	}

	/* Set mode */
	if ( ( rc = vesafb_set_mode ( mode_number ) ) != 0 )
		goto err_set_mode;

	/* Get font data */
	vesafb_font();

	/* Initialise frame buffer console */
	if ( ( rc = fbcon_init ( &vesafb.fbcon, phys_to_user ( vesafb.start ),
				 &vesafb.pixel, &vesafb.map, &vesafb.font,
				 config ) ) != 0 )
		goto err_fbcon_init;

	free ( mode_numbers );
	return 0;

	fbcon_fini ( &vesafb.fbcon );
 err_fbcon_init:
 err_set_mode:
	vesafb_restore();
 err_select_mode:
	free ( mode_numbers );
 err_mode_list:
	return rc;
}

/**
 * Finalise VESA frame buffer
 *
 */
static void vesafb_fini ( void ) {

	/* Finalise frame buffer console */
	fbcon_fini ( &vesafb.fbcon );

	/* Restore saved VGA mode */
	vesafb_restore();
}

/**
 * Print a character to current cursor position
 *
 * @v character		Character
 */
static void vesafb_putchar ( int character ) {

	fbcon_putchar ( &vesafb.fbcon, character );
}

/**
 * Configure console
 *
 * @v config		Console configuration, or NULL to reset
 * @ret rc		Return status code
 */
static int vesafb_configure ( struct console_configuration *config ) {
	int rc;

	/* Reset console, if applicable */
	if ( ! vesafb_console.disabled ) {
		vesafb_fini();
		bios_console.disabled &= ~CONSOLE_DISABLED_OUTPUT;
		ansicol_reset_magic();
	}
	vesafb_console.disabled = CONSOLE_DISABLED;

	/* Do nothing more unless we have a usable configuration */
	if ( ( config == NULL ) ||
	     ( config->width == 0 ) || ( config->height == 0 ) ) {
		return 0;
	}

	/* Initialise VESA frame buffer */
	if ( ( rc = vesafb_init ( config ) ) != 0 )
		return rc;

	/* Mark console as enabled */
	vesafb_console.disabled = 0;
	bios_console.disabled |= CONSOLE_DISABLED_OUTPUT;

	/* Set magic colour to transparent if we have a background picture */
	if ( config->pixbuf )
		ansicol_set_magic_transparent();

	return 0;
}

/** VESA frame buffer console driver */
struct console_driver vesafb_console __console_driver = {
	.usage = CONSOLE_VESAFB,
	.putchar = vesafb_putchar,
	.configure = vesafb_configure,
	.disabled = CONSOLE_DISABLED,
};
