Skip to content

Commit

Permalink
[efi] Work around broken GetFontInfo() implementations
Browse files Browse the repository at this point in the history
Several UEFI platforms are known to return EFI_NOT_FOUND when asked to
retrieve the system default font information via GetFontInfo().  Work
around these broken platforms by iterating over the glyphs to find the
maximum height used by a printable character.

Originally-fixed-by: Jonathan Dieter <jdieter@lesbg.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
  • Loading branch information
mcb30 committed Mar 10, 2016
1 parent e44f6dc commit e303a6b
Showing 1 changed file with 38 additions and 16 deletions.
54 changes: 38 additions & 16 deletions src/interface/efi/efi_fbcon.c
Expand Up @@ -110,7 +110,6 @@ static void efifb_glyph ( unsigned int character, uint8_t *glyph ) {
*/
static int efifb_glyphs ( void ) {
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
EFI_FONT_DISPLAY_INFO *info;
EFI_IMAGE_OUTPUT *blt;
EFI_GRAPHICS_OUTPUT_BLT_PIXEL *pixel;
size_t offset;
Expand All @@ -122,16 +121,42 @@ static int efifb_glyphs ( void ) {
EFI_STATUS efirc;
int rc;

/* Get font height */
if ( ( efirc = efifb.hiifont->GetFontInfo ( efifb.hiifont, NULL, NULL,
&info, NULL ) ) != 0 ) {
rc = -EEFI ( efirc );
DBGC ( &efifb, "EFIFB could not get font information: %s\n",
strerror ( rc ) );
goto err_info;
/* Get font height. The GetFontInfo() call nominally returns
* this information in an EFI_FONT_DISPLAY_INFO structure, but
* is known to fail on many UEFI implementations. Instead, we
* iterate over all printable characters to find the maximum
* height.
*/
efifb.font.height = 0;
for ( character = 0 ; character < 256 ; character++ ) {

/* Skip non-printable characters */
if ( ! isprint ( character ) )
continue;

/* Get glyph */
blt = NULL;
if ( ( efirc = efifb.hiifont->GetGlyph ( efifb.hiifont,
character, NULL, &blt,
NULL ) ) != 0 ) {
rc = -EEFI ( efirc );
DBGC ( &efifb, "EFIFB could not get glyph %d: %s\n",
character, strerror ( rc ) );
continue;
}
assert ( blt != NULL );

/* Calculate maximum height */
if ( efifb.font.height < blt->Height )
efifb.font.height = blt->Height;

/* Free glyph */
bs->FreePool ( blt );
}
if ( ! efifb.font.height ) {
DBGC ( &efifb, "EFIFB could not get font height\n" );
return -ENOENT;
}
assert ( info != NULL );
efifb.font.height = info->FontInfo.FontSize;

/* Allocate glyph data */
len = ( 256 * efifb.font.height * sizeof ( bitmask ) );
Expand All @@ -152,7 +177,7 @@ static int efifb_glyphs ( void ) {
/* Get glyph */
blt = NULL;
if ( ( efirc = efifb.hiifont->GetGlyph ( efifb.hiifont,
character, info, &blt,
character, NULL, &blt,
NULL ) ) != 0 ) {
rc = -EEFI ( efirc );
DBGC ( &efifb, "EFIFB could not get glyph %d: %s\n",
Expand Down Expand Up @@ -187,19 +212,16 @@ static int efifb_glyphs ( void ) {
copy_to_user ( efifb.glyphs, offset++, &bitmask,
sizeof ( bitmask ) );
}

/* Free glyph */
bs->FreePool ( blt );
}

/* Free font information */
bs->FreePool ( info );

efifb.font.glyph = efifb_glyph;
return 0;

ufree ( efifb.glyphs );
err_alloc:
bs->FreePool ( info );
err_info:
return rc;
}

Expand Down

0 comments on commit e303a6b

Please sign in to comment.