Allow use on headless EFI systems.

A headless EFI system may have no GOP devices. In this case, disable
output to the physical display, but continue to write to the shadow
buffer. This allows operation via a serial console.
This commit is contained in:
Martin Whitaker 2023-01-21 16:37:44 +00:00
parent 186ef6e913
commit 709b1b702a
3 changed files with 14 additions and 10 deletions

View File

@ -58,6 +58,7 @@ typedef struct {
#define VIDEO_TYPE_VLFB 0x23 // VESA VGA in graphic mode
#define VIDEO_TYPE_EFI 0x70 // EFI graphic mode
#define VIDEO_TYPE_NONE 0xff // no video display (added for Memtest86+)
#define LFB_CAPABILITY_64BIT_BASE (1 << 1)

View File

@ -334,9 +334,7 @@ static efi_status_t set_screen_info_from_gop(screen_info_t *si, efi_handle_t *ha
efi_graphics_output_t *gop = find_gop(handles, handles_size);
if (!gop) {
#if DEBUG
print_string("GOP not found\n");
#endif
print_string("No graphics display found\n");
return EFI_NOT_FOUND;
}
@ -365,9 +363,7 @@ static efi_status_t set_screen_info_from_gop(screen_info_t *si, efi_handle_t *ha
efi_call_bs(free_pool, info);
}
if (best_mode == UINT32_MAX) {
#if DEBUG
print_string("No suitable GOP screen resolution\n");
#endif
print_string("No suitable screen resolution found\n");
return EFI_NOT_FOUND;
}
@ -469,9 +465,7 @@ static efi_status_t set_screen_info_from_gop(screen_info_t *si, efi_handle_t *ha
status = efi_call_proto(gop, set_mode, best_mode);
if (status != EFI_SUCCESS) {
#if DEBUG
print_string("Set GOP mode failed\n");
#endif
return status;
}
@ -502,6 +496,11 @@ static efi_status_t set_screen_info(boot_params_t *boot_params)
if (status == EFI_SUCCESS) {
status = set_screen_info_from_gop(&boot_params->screen_info, handles, handles_size);
}
if (status == EFI_NOT_FOUND) {
// This may be a headless system. We can still output to a serial console.
boot_params->screen_info.orig_video_isVGA = VIDEO_TYPE_NONE;
status = EFI_SUCCESS;
}
efi_call_bs(free_pool, handles);
}

View File

@ -42,7 +42,7 @@ static const rgb_value_t vga_pallete[16] = {
{ 255, 255, 255 } // BOLD+WHITE
};
static vga_buffer_t *vga_buffer = (vga_buffer_t *)(0xb8000);
static vga_buffer_t *vga_buffer = NULL;
vga_buffer_t shadow_buffer;
@ -64,8 +64,10 @@ static void vga_put_char(int row, int col, uint8_t ch, uint8_t attr)
shadow_buffer[row][col].ch = ch;
shadow_buffer[row][col].attr = attr;
if (vga_buffer) {
(*vga_buffer)[row][col].value = shadow_buffer[row][col].value;
}
}
static void lfb8_put_char(int row, int col, uint8_t ch, uint8_t attr)
{
@ -239,6 +241,8 @@ void screen_init(void)
uint32_t b = ((vga_pallete[i].b * b_max) / 255) << screen_info->blue_pos;
lfb_pallete[i] = r | g | b;
}
} else if (screen_info->orig_video_isVGA != VIDEO_TYPE_NONE) {
vga_buffer = (vga_buffer_t *)(0xb8000);
}
}