From aeffa86cc551110b62074fa6302f4960d87a9a8c Mon Sep 17 00:00:00 2001 From: Martin Roth Date: Wed, 20 Jan 2021 12:07:31 -0700 Subject: 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 Change-Id: I7d261321cdbe423dd754f6a354e5f50b53563fcb Reviewed-on: https://review.coreboot.org/c/coreboot/+/49764 Tested-by: build bot (Jenkins) Reviewed-by: Raul Rangel Reviewed-by: Angel Pons Reviewed-by: Nico Huber --- src/device/oprom/realmode/x86.c | 56 ++++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 17 deletions(-) (limited to 'src/device/oprom') 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 -- cgit v1.2.3