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>
This commit is contained in:
Martin Roth 2021-01-20 12:07:31 -07:00 committed by Patrick Georgi
parent 656743fb6b
commit aeffa86cc5
1 changed files with 39 additions and 17 deletions

View File

@ -218,7 +218,7 @@ const vbe_mode_info_t *vbe_mode_info(void)
static int vbe_check_for_failure(int ah); 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); char *buffer = PTR_TO_REAL_MODE(__realmode_buffer);
u16 buffer_seg = (((unsigned long)buffer) >> 4) & 0xff00; 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, X86_EAX = realmode_interrupt(0x10, VESA_GET_INFO, 0x0000, 0x0000,
0x0000, buffer_seg, buffer_adr); 0x0000, buffer_seg, buffer_adr);
/* If the VBE function completed successfully, 0x0 is returned in AH */ /* If the VBE function completed successfully, 0x0 is returned in AH */
if (X86_AH) if (X86_AH) {
die("\nError: In %s function\n", __func__); printk(BIOS_WARNING, "Warning: Error from VGA BIOS in %s\n", __func__);
return 1;
}
memcpy(info, buffer, sizeof(vbe_info_block)); memcpy(info, buffer, sizeof(vbe_info_block));
return 0;
} }
static void vbe_oprom_list_supported_mode(uint16_t *video_mode_ptr) 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); } while (mode != 0xffff);
} }
static void vbe_oprom_supported_mode_list(void) static u8 vbe_oprom_supported_mode_list(void)
{ {
uint16_t segment, offset; uint16_t segment, offset;
vbe_info_block info; vbe_info_block info;
vbe_get_ctrl_info(&info); if (vbe_get_ctrl_info(&info))
return 1;
offset = info.video_mode_ptr; offset = info.video_mode_ptr;
segment = info.video_mode_ptr >> 16; segment = info.video_mode_ptr >> 16;
vbe_oprom_list_supported_mode((uint16_t *)((segment << 4) + offset)); vbe_oprom_list_supported_mode((uint16_t *)((segment << 4) + offset));
return 0;
} }
/* /*
* EAX register is used to indicate the completion status upon return from * 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: default:
printk(BIOS_DEBUG, "VBE: Unsupported video mode %x!\n", printk(BIOS_DEBUG, "VBE: Unsupported video mode %x!\n",
CONFIG_FRAMEBUFFER_VESA_MODE); 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; status = -1;
break; break;
} }
@ -304,8 +310,10 @@ static u8 vbe_get_mode_info(vbe_mode_info_t * mi)
u16 buffer_adr = ((unsigned long)buffer) & 0xffff; u16 buffer_adr = ((unsigned long)buffer) & 0xffff;
X86_EAX = realmode_interrupt(0x10, VESA_GET_MODE_INFO, 0x0000, X86_EAX = realmode_interrupt(0x10, VESA_GET_MODE_INFO, 0x0000,
mi->video_mode, 0x0000, buffer_seg, buffer_adr); mi->video_mode, 0x0000, buffer_seg, buffer_adr);
if (vbe_check_for_failure(X86_AH)) if (vbe_check_for_failure(X86_AH)) {
die("\nError: In %s function\n", __func__); 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)); memcpy(mi->mode_info_block, buffer, sizeof(mi->mode_info_block));
mode_info_valid = 1; mode_info_valid = 1;
return 0; return 0;
@ -320,8 +328,10 @@ static u8 vbe_set_mode(vbe_mode_info_t * mi)
mi->video_mode &= ~(1 << 15); mi->video_mode &= ~(1 << 15);
X86_EAX = realmode_interrupt(0x10, VESA_SET_MODE, mi->video_mode, X86_EAX = realmode_interrupt(0x10, VESA_SET_MODE, mi->video_mode,
0x0000, 0x0000, 0x0000, 0x0000); 0x0000, 0x0000, 0x0000, 0x0000);
if (vbe_check_for_failure(X86_AH)) if (vbe_check_for_failure(X86_AH)) {
die("\nError: In %s function\n", __func__); printk(BIOS_WARNING, "VBE Warning: Error from VGA BIOS in %s\n", __func__);
return 1;
}
return 0; return 0;
} }
@ -331,7 +341,10 @@ static u8 vbe_set_mode(vbe_mode_info_t * mi)
void vbe_set_graphics(void) void vbe_set_graphics(void)
{ {
mode_info.video_mode = (1 << 14) | CONFIG_FRAMEBUFFER_VESA_MODE; 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 *framebuffer =
(unsigned char *)mode_info.vesa.phys_base_ptr; (unsigned char *)mode_info.vesa.phys_base_ptr;
printk(BIOS_DEBUG, "VBE: resolution: %dx%d@%d\n", printk(BIOS_DEBUG, "VBE: resolution: %dx%d@%d\n",
@ -346,7 +359,10 @@ void vbe_set_graphics(void)
return; 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 = { const struct lb_framebuffer fb = {
.physical_address = mode_info.vesa.phys_base_ptr, .physical_address = mode_info.vesa.phys_base_ptr,
.x_resolution = le16_to_cpu(mode_info.vesa.x_resolution), .x_resolution = le16_to_cpu(mode_info.vesa.x_resolution),
@ -369,11 +385,17 @@ void vbe_set_graphics(void)
void vbe_textmode_console(void) void vbe_textmode_console(void)
{ {
delay(2); u8 retval = 1;
X86_EAX = realmode_interrupt(0x10, 0x0003, 0x0000, 0x0000, if (mode_info.vesa.phys_base_ptr) {
0x0000, 0x0000, 0x0000); delay(2);
if (vbe_check_for_failure(X86_AH)) X86_EAX = realmode_interrupt(0x10, 0x0003, 0x0000, 0x0000,
die("\nError: In %s function\n", __func__); 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 #endif