summaryrefslogtreecommitdiffstats
path: root/src/arch
diff options
context:
space:
mode:
authorSimon Rettberg2018-05-28 15:33:56 +0200
committerSimon Rettberg2018-05-28 15:45:25 +0200
commit85b64c16424ce690ba7f640c2f0bde6e70295112 (patch)
tree5043b7eede0364ff48be6859a1d31298e4e36bd6 /src/arch
parent[icplus] Add driver for IC+ network card (diff)
downloadipxe-85b64c16424ce690ba7f640c2f0bde6e70295112.tar.gz
ipxe-85b64c16424ce690ba7f640c2f0bde6e70295112.tar.xz
ipxe-85b64c16424ce690ba7f640c2f0bde6e70295112.zip
[console] Add option to update margins and bg-image of vesa mode console
Adding --update to the console call will prevent the vesa mode from being initialized again. The existing mode will be reused. This makes it possible to quickly update the background image or console margins without ugly flickering.
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/x86/interface/pcbios/vesafb.c101
1 files changed, 64 insertions, 37 deletions
diff --git a/src/arch/x86/interface/pcbios/vesafb.c b/src/arch/x86/interface/pcbios/vesafb.c
index 50e485852..9cdffd32c 100644
--- a/src/arch/x86/interface/pcbios/vesafb.c
+++ b/src/arch/x86/interface/pcbios/vesafb.c
@@ -422,34 +422,36 @@ static void vesafb_restore ( void ) {
*/
static int vesafb_init ( struct console_configuration *config ) {
uint32_t discard_b;
- uint16_t *mode_numbers;
+ uint16_t *mode_numbers = NULL;
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;
- }
+ if ( ! config->lazy_update ) {
+ /* 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;
+ /* Set mode */
+ if ( ( rc = vesafb_set_mode ( mode_number ) ) != 0 )
+ goto err_set_mode;
- /* Get font data */
- vesafb_font();
+ /* Get font data */
+ vesafb_font();
+ }
/* Initialise frame buffer console */
if ( ( rc = fbcon_init ( &vesafb.fbcon, phys_to_user ( vesafb.start ),
@@ -502,17 +504,40 @@ static void vesafb_putchar ( int character ) {
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();
+ if ( config == NULL ) {
+ return 0;
+ }
+ if ( config->lazy_update ) {
+ if ( vesafb_console.disabled ) {
+ /* --update mode with disabled console -> nothing to do */
+ return 0;
+ }
+ /* No width/height given, use current so we can update the border */
+ if ( ( config->width == 0 ) || ( config->height == 0 ) ) {
+ if ( ( vesafb.pixel.width == 0 ) || ( vesafb.pixel.height == 0 ) ) {
+ return -EINVAL;
+ }
+ config->width = vesafb.pixel.width;
+ config->height = vesafb.pixel.height;
+ } else {
+ /* Otherwise make sure the new dimensions match the old ones */
+ if ( ( vesafb.pixel.width != config->width ) ||
+ ( vesafb.pixel.height != config->height ) ) {
+ return -EINVAL;
+ }
+ }
+ } else {
+ /* Reset console, if applicable */
+ if ( ! vesafb_console.disabled ) {
+ vesafb_fini();
+ bios_console.disabled &= ~CONSOLE_DISABLED_OUTPUT;
+ ansicol_reset_magic();
+ }
+ vesafb_console.disabled = CONSOLE_DISABLED;
}
- vesafb_console.disabled = CONSOLE_DISABLED;
/* Do nothing more unless we have a usable configuration */
- if ( ( config == NULL ) ||
- ( config->width == 0 ) || ( config->height == 0 ) ) {
+ if ( ( config->width == 0 ) || ( config->height == 0 ) ) {
return 0;
}
@@ -520,13 +545,15 @@ static int vesafb_configure ( struct console_configuration *config ) {
if ( ( rc = vesafb_init ( config ) ) != 0 )
return rc;
- /* Mark console as enabled */
- vesafb_console.disabled = 0;
- bios_console.disabled |= CONSOLE_DISABLED_OUTPUT;
+ if ( ! config->lazy_update ) {
+ /* 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();
+ /* Set magic colour to transparent if we have a background picture */
+ if ( config->pixbuf )
+ ansicol_set_magic_transparent();
+ }
return 0;
}