summaryrefslogtreecommitdiffstats
path: root/src/interface/efi/efi_fbcon.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/interface/efi/efi_fbcon.c')
-rw-r--r--src/interface/efi/efi_fbcon.c157
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;
}