summaryrefslogtreecommitdiffstats
path: root/src/interface/efi
diff options
context:
space:
mode:
authorMichael Brown2016-03-10 19:06:26 +0100
committerMichael Brown2016-03-10 19:09:59 +0100
commite303a6b387628d4c65d1085f66a5d97855755ace (patch)
treed30d106765976c6b335dd9162a80fad9c5e42a26 /src/interface/efi
parent[xsigo] Add support for Xsigo virtual Ethernet (XVE) EoIB devices (diff)
downloadipxe-e303a6b387628d4c65d1085f66a5d97855755ace.tar.gz
ipxe-e303a6b387628d4c65d1085f66a5d97855755ace.tar.xz
ipxe-e303a6b387628d4c65d1085f66a5d97855755ace.zip
[efi] Work around broken GetFontInfo() implementations
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>
Diffstat (limited to 'src/interface/efi')
-rw-r--r--src/interface/efi/efi_fbcon.c54
1 files changed, 38 insertions, 16 deletions
diff --git a/src/interface/efi/efi_fbcon.c b/src/interface/efi/efi_fbcon.c
index 01b691b6..abc5a939 100644
--- a/src/interface/efi/efi_fbcon.c
+++ b/src/interface/efi/efi_fbcon.c
@@ -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;
@@ -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 ) );
@@ -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",
@@ -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;
}