diff options
author | Martin Roth <martinroth@chromium.org> | 2021-01-20 12:07:31 -0700 |
---|---|---|
committer | Patrick Georgi <pgeorgi@google.com> | 2021-01-27 10:24:44 +0000 |
commit | aeffa86cc551110b62074fa6302f4960d87a9a8c (patch) | |
tree | 340a85a1f1642b89340e2045864f0ac4dd8d8cfb | |
parent | 656743fb6b5f43c717b8d1685f32ee9e33694b4b (diff) | |
download | coreboot-aeffa86cc551110b62074fa6302f4960d87a9a8c.tar.xz |
src/device: Don't die() on vBIOS errors
Systems can boot to the OS without a display. Don't kill the boot
process based on a vBIOS error, instead just display a warning.
If the issue is actually fatal for some reason, it's going to die
at some point anyway.
BUG=b:175843172
TEST=Boot morphius to OS without a display
BRANCH=Zork
Signed-off-by: Martin Roth <martinroth@chromium.org>
Change-Id: I7d261321cdbe423dd754f6a354e5f50b53563fcb
Reviewed-on: https://review.coreboot.org/c/coreboot/+/49764
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Reviewed-by: Nico Huber <nico.h@gmx.de>
-rw-r--r-- | src/device/oprom/realmode/x86.c | 56 |
1 files changed, 39 insertions, 17 deletions
diff --git a/src/device/oprom/realmode/x86.c b/src/device/oprom/realmode/x86.c index 6b80ac5f62..224e49b97d 100644 --- a/src/device/oprom/realmode/x86.c +++ b/src/device/oprom/realmode/x86.c @@ -218,7 +218,7 @@ const vbe_mode_info_t *vbe_mode_info(void) static int vbe_check_for_failure(int ah); -static void vbe_get_ctrl_info(vbe_info_block *info) +static u8 vbe_get_ctrl_info(vbe_info_block *info) { char *buffer = PTR_TO_REAL_MODE(__realmode_buffer); u16 buffer_seg = (((unsigned long)buffer) >> 4) & 0xff00; @@ -226,9 +226,12 @@ static void vbe_get_ctrl_info(vbe_info_block *info) X86_EAX = realmode_interrupt(0x10, VESA_GET_INFO, 0x0000, 0x0000, 0x0000, buffer_seg, buffer_adr); /* If the VBE function completed successfully, 0x0 is returned in AH */ - if (X86_AH) - die("\nError: In %s function\n", __func__); + if (X86_AH) { + printk(BIOS_WARNING, "Warning: Error from VGA BIOS in %s\n", __func__); + return 1; + } memcpy(info, buffer, sizeof(vbe_info_block)); + return 0; } static void vbe_oprom_list_supported_mode(uint16_t *video_mode_ptr) @@ -242,17 +245,19 @@ static void vbe_oprom_list_supported_mode(uint16_t *video_mode_ptr) } while (mode != 0xffff); } -static void vbe_oprom_supported_mode_list(void) +static u8 vbe_oprom_supported_mode_list(void) { uint16_t segment, offset; vbe_info_block info; - vbe_get_ctrl_info(&info); + if (vbe_get_ctrl_info(&info)) + return 1; offset = info.video_mode_ptr; segment = info.video_mode_ptr >> 16; vbe_oprom_list_supported_mode((uint16_t *)((segment << 4) + offset)); + return 0; } /* * EAX register is used to indicate the completion status upon return from @@ -288,7 +293,8 @@ static int vbe_check_for_failure(int ah) default: printk(BIOS_DEBUG, "VBE: Unsupported video mode %x!\n", CONFIG_FRAMEBUFFER_VESA_MODE); - vbe_oprom_supported_mode_list(); + if (vbe_oprom_supported_mode_list()) + printk(BIOS_WARNING, "VBE Warning: Could not get VBE mode list.\n"); status = -1; break; } @@ -304,8 +310,10 @@ static u8 vbe_get_mode_info(vbe_mode_info_t * mi) u16 buffer_adr = ((unsigned long)buffer) & 0xffff; X86_EAX = realmode_interrupt(0x10, VESA_GET_MODE_INFO, 0x0000, mi->video_mode, 0x0000, buffer_seg, buffer_adr); - if (vbe_check_for_failure(X86_AH)) - die("\nError: In %s function\n", __func__); + if (vbe_check_for_failure(X86_AH)) { + printk(BIOS_WARNING, "VBE Warning: Error from VGA BIOS in %s\n", __func__); + return 1; + } memcpy(mi->mode_info_block, buffer, sizeof(mi->mode_info_block)); mode_info_valid = 1; return 0; @@ -320,8 +328,10 @@ static u8 vbe_set_mode(vbe_mode_info_t * mi) mi->video_mode &= ~(1 << 15); X86_EAX = realmode_interrupt(0x10, VESA_SET_MODE, mi->video_mode, 0x0000, 0x0000, 0x0000, 0x0000); - if (vbe_check_for_failure(X86_AH)) - die("\nError: In %s function\n", __func__); + if (vbe_check_for_failure(X86_AH)) { + printk(BIOS_WARNING, "VBE Warning: Error from VGA BIOS in %s\n", __func__); + return 1; + } return 0; } @@ -331,7 +341,10 @@ static u8 vbe_set_mode(vbe_mode_info_t * mi) void vbe_set_graphics(void) { mode_info.video_mode = (1 << 14) | CONFIG_FRAMEBUFFER_VESA_MODE; - vbe_get_mode_info(&mode_info); + if (vbe_get_mode_info(&mode_info)) { + printk(BIOS_WARNING, "VBE Warning: Could not get VBE graphics mode info.\n"); + return; + } unsigned char *framebuffer = (unsigned char *)mode_info.vesa.phys_base_ptr; printk(BIOS_DEBUG, "VBE: resolution: %dx%d@%d\n", @@ -346,7 +359,10 @@ void vbe_set_graphics(void) return; } - vbe_set_mode(&mode_info); + if (vbe_set_mode(&mode_info)) { + printk(BIOS_WARNING, "VBE Warning: Could not set VBE graphics mode.\n"); + return; + } const struct lb_framebuffer fb = { .physical_address = mode_info.vesa.phys_base_ptr, .x_resolution = le16_to_cpu(mode_info.vesa.x_resolution), @@ -369,11 +385,17 @@ void vbe_set_graphics(void) void vbe_textmode_console(void) { - delay(2); - X86_EAX = realmode_interrupt(0x10, 0x0003, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000); - if (vbe_check_for_failure(X86_AH)) - die("\nError: In %s function\n", __func__); + u8 retval = 1; + if (mode_info.vesa.phys_base_ptr) { + delay(2); + X86_EAX = realmode_interrupt(0x10, 0x0003, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000); + if (!vbe_check_for_failure(X86_AH)) + retval = 0; + } + + if (retval) + printk(BIOS_WARNING, "VBE Warning: Could not set VBE text mode.\n"); } #endif |