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>
diff --git a/src/device/oprom/realmode/x86.c b/src/device/oprom/realmode/x86.c
index 6b80ac5..224e49b 100644
--- a/src/device/oprom/realmode/x86.c
+++ b/src/device/oprom/realmode/x86.c
@@ -218,7 +218,7 @@
 
 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 @@
 	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 @@
 	} 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 @@
 	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 @@
 	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 @@
 	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 @@
 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 @@
 		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_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