diff options
Diffstat (limited to 'src/interface/efi/efi_fbcon.c')
-rw-r--r-- | src/interface/efi/efi_fbcon.c | 157 |
1 files changed, 90 insertions, 67 deletions
diff --git a/src/interface/efi/efi_fbcon.c b/src/interface/efi/efi_fbcon.c index d388e031..e3c4d001 100644 --- a/src/interface/efi/efi_fbcon.c +++ b/src/interface/efi/efi_fbcon.c @@ -519,68 +519,70 @@ static int efifb_init ( struct console_configuration *config ) { EFI_STATUS efirc; int rc; - /* Locate graphics output protocol */ - if ( ( efirc = bs->LocateProtocol ( &efi_graphics_output_protocol_guid, - NULL, &interface ) ) != 0 ) { - rc = -EEFI ( efirc ); - DBGC ( &efifb, "EFIFB could not locate graphics output " - "protocol: %s\n", strerror ( rc ) ); - goto err_locate_gop; - } - efifb.gop = interface; + if ( ! config->lazy_update ) { + /* Locate graphics output protocol */ + if ( ( efirc = bs->LocateProtocol ( &efi_graphics_output_protocol_guid, + NULL, &interface ) ) != 0 ) { + rc = -EEFI ( efirc ); + DBGC ( &efifb, "EFIFB could not locate graphics output " + "protocol: %s\n", strerror ( rc ) ); + goto err_locate_gop; + } + efifb.gop = interface; - /* Locate HII font protocol */ - if ( ( efirc = bs->LocateProtocol ( &efi_hii_font_protocol_guid, - NULL, &interface ) ) != 0 ) { - rc = -EEFI ( efirc ); - DBGC ( &efifb, "EFIFB could not locate HII font protocol: %s\n", - strerror ( rc ) ); - goto err_locate_hiifont; - } - efifb.hiifont = interface; + /* Locate HII font protocol */ + if ( ( efirc = bs->LocateProtocol ( &efi_hii_font_protocol_guid, + NULL, &interface ) ) != 0 ) { + rc = -EEFI ( efirc ); + DBGC ( &efifb, "EFIFB could not locate HII font protocol: %s\n", + strerror ( rc ) ); + goto err_locate_hiifont; + } + efifb.hiifont = interface; - /* Locate glyphs */ - if ( ( rc = efifb_glyphs() ) != 0 ) - goto err_glyphs; + /* Locate glyphs */ + if ( ( rc = efifb_glyphs() ) != 0 ) + goto err_glyphs; - /* Save original mode */ - efifb.saved_mode = efifb.gop->Mode->Mode; + /* Save original mode */ + efifb.saved_mode = efifb.gop->Mode->Mode; - /* Select mode */ - if ( ( mode = efifb_select_mode ( config->width, config->height, - config->depth ) ) < 0 ) { - rc = mode; - goto err_select_mode; - } + /* Select mode */ + if ( ( mode = efifb_select_mode ( config->width, config->height, + config->depth ) ) < 0 ) { + rc = mode; + goto err_select_mode; + } - /* Set mode */ - if ( ( efirc = efifb.gop->SetMode ( efifb.gop, mode ) ) != 0 ) { - rc = -EEFI ( efirc ); - DBGC ( &efifb, "EFIFB could not set mode %d: %s\n", - mode, strerror ( rc ) ); - goto err_set_mode; - } - info = efifb.gop->Mode->Info; - - /* Populate colour map */ - bpp = efifb_colour_map ( info, &efifb.map ); - if ( bpp < 0 ) { - rc = bpp; - DBGC ( &efifb, "EFIFB could not build colour map for " - "mode %d: %s\n", mode, strerror ( rc ) ); - goto err_map; - } + /* Set mode */ + if ( ( efirc = efifb.gop->SetMode ( efifb.gop, mode ) ) != 0 ) { + rc = -EEFI ( efirc ); + DBGC ( &efifb, "EFIFB could not set mode %d: %s\n", + mode, strerror ( rc ) ); + goto err_set_mode; + } + info = efifb.gop->Mode->Info; - /* Populate pixel geometry */ - efifb.pixel.width = info->HorizontalResolution; - efifb.pixel.height = info->VerticalResolution; - efifb.pixel.len = ( ( bpp + 7 ) / 8 ); - efifb.pixel.stride = ( efifb.pixel.len * info->PixelsPerScanLine ); + /* Populate colour map */ + bpp = efifb_colour_map ( info, &efifb.map ); + if ( bpp < 0 ) { + rc = bpp; + DBGC ( &efifb, "EFIFB could not build colour map for " + "mode %d: %s\n", mode, strerror ( rc ) ); + goto err_map; + } - /* Populate frame buffer address */ - efifb.start = efifb.gop->Mode->FrameBufferBase; - DBGC ( &efifb, "EFIFB using mode %d (%dx%d %dbpp at %#08lx)\n", - mode, efifb.pixel.width, efifb.pixel.height, bpp, efifb.start ); + /* Populate pixel geometry */ + efifb.pixel.width = info->HorizontalResolution; + efifb.pixel.height = info->VerticalResolution; + efifb.pixel.len = ( ( bpp + 7 ) / 8 ); + efifb.pixel.stride = ( efifb.pixel.len * info->PixelsPerScanLine ); + + /* Populate frame buffer address */ + efifb.start = efifb.gop->Mode->FrameBufferBase; + DBGC ( &efifb, "EFIFB using mode %d (%dx%d %dbpp at %#08lx)\n", + mode, efifb.pixel.width, efifb.pixel.height, bpp, efifb.start ); +} /* Initialise frame buffer console */ if ( ( rc = fbcon_init ( &efifb.fbcon, phys_to_user ( efifb.start ), @@ -638,13 +640,32 @@ static void efifb_putchar ( int character ) { static int efifb_configure ( struct console_configuration *config ) { int rc; - /* Reset console, if applicable */ - if ( ! efifb_console.disabled ) { - efifb_fini(); - efi_console.disabled &= ~CONSOLE_DISABLED_OUTPUT; - ansicol_reset_magic(); + if ( config && config->lazy_update ) { + if ( efifb_console.disabled ) + return 0; + /* No width/height given, use current so we can update the border */ + if ( ( config->width == 0 ) || ( config->height == 0 ) ) { + if ( ( efifb.pixel.width == 0 ) || ( efifb.pixel.height == 0 ) ) { + return -EINVAL; + } + config->width = efifb.pixel.width; + config->height = efifb.pixel.height; + } else { + /* Otherwise make sure the new dimensions match the old ones */ + if ( ( efifb.pixel.width != config->width ) || + ( efifb.pixel.height != config->height ) ) { + return -EINVAL; + } + } + } else { + /* Reset console, if applicable */ + if ( ! efifb_console.disabled ) { + efifb_fini(); + efi_console.disabled &= ~CONSOLE_DISABLED_OUTPUT; + ansicol_reset_magic(); + } + efifb_console.disabled = CONSOLE_DISABLED; } - efifb_console.disabled = CONSOLE_DISABLED; /* Do nothing more unless we have a usable configuration */ if ( ( config == NULL ) || @@ -656,13 +677,15 @@ static int efifb_configure ( struct console_configuration *config ) { if ( ( rc = efifb_init ( config ) ) != 0 ) return rc; - /* Mark console as enabled */ - efifb_console.disabled = 0; - efi_console.disabled |= CONSOLE_DISABLED_OUTPUT; + if ( ! config->lazy_update ) { + /* Mark console as enabled */ + efifb_console.disabled = 0; + efi_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; } |