Module Name: src
Committed By: martin
Date: Mon Feb 10 16:47:30 UTC 2020
Modified Files:
src/sys/arch/i386/stand/efiboot [netbsd-8]: eficons.c
Log Message:
Pull up following revision(s) (requested by nonaka in ticket #1498):
sys/arch/i386/stand/efiboot/eficons.c: revision 1.8
Fix a few bugs related to the framebuffer:
- If a GOP mode wasn't explicitly requested, the bootloader was passing
fb info to the kernel even if the console was in text mode! This
results in garbled console output on at least ThinkPad T420 and
likely many others. If a mode isn't specified, default to 800x600.
- The "gop" command was incorrectly parsing video modes in the form
WxHxD as WxWxD.
- Allow a short form WxH for the "gop" command to select any mode with
the target dimensions.
To generate a diff of this commit:
cvs rdiff -u -r1.4.2.3 -r1.4.2.4 src/sys/arch/i386/stand/efiboot/eficons.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/i386/stand/efiboot/eficons.c
diff -u src/sys/arch/i386/stand/efiboot/eficons.c:1.4.2.3 src/sys/arch/i386/stand/efiboot/eficons.c:1.4.2.4
--- src/sys/arch/i386/stand/efiboot/eficons.c:1.4.2.3 Wed Sep 18 17:30:05 2019
+++ src/sys/arch/i386/stand/efiboot/eficons.c Mon Feb 10 16:47:29 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: eficons.c,v 1.4.2.3 2019/09/18 17:30:05 martin Exp $ */
+/* $NetBSD: eficons.c,v 1.4.2.4 2020/02/10 16:47:29 martin Exp $ */
/*-
* Copyright (c) 2016 Kimihiro Nonaka <[email protected]>
@@ -34,6 +34,10 @@
#include "bootinfo.h"
#include "vbe.h"
+#ifndef DEFAULT_GOP_MODE
+#define DEFAULT_GOP_MODE "800x600"
+#endif
+
extern struct x86_boot_params boot_params;
struct btinfo_console btinfo_console;
@@ -71,6 +75,8 @@ static int efi_com_putc(int);
static int efi_com_status(int);
static int efi_com_waitforinputevent(uint64_t);
+static int efi_find_gop_mode(char *);
+
static int iodev;
static int (*internal_getchar)(void) = efi_cons_getc;
static int (*internal_putchar)(int) = efi_cons_putc;
@@ -415,46 +421,36 @@ bi_framebuffer(void)
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info;
struct btinfo_framebuffer fb;
INT32 bestmode = -1;
+ UINTN sz;
- if (efi_gop == NULL) {
- framebuffer_configure(NULL);
- return;
- }
+ if (efi_gop == NULL)
+ goto nofb;
if (efi_gop_mode >= 0) {
bestmode = efi_gop_mode;
} else {
-#if 0
- UINT64 res, bestres = 0;
- UINTN sz;
- UINT32 i;
-
- /* XXX EDID? EFI_EDID_DISCOVERED_PROTOCOL */
- for (i = 0; i < efi_gop->Mode->MaxMode; i++) {
- status = uefi_call_wrapper(efi_gop->QueryMode, 4,
- efi_gop, i, &sz, &info);
- if (EFI_ERROR(status))
- continue;
+ /* If a mode has not been selected, choose a default */
+ bestmode = efi_find_gop_mode(DEFAULT_GOP_MODE);
+ }
+ if (bestmode == -1)
+ goto nofb;
- res = (UINT64)info->HorizontalResolution *
- (UINT64)info->VerticalResolution *
- (UINT64)getdepth(info);
- if (res > bestres) {
- bestmode = i;
- bestres = res;
- }
- }
-#endif
+ status = uefi_call_wrapper(efi_gop->SetMode, 2, efi_gop,
+ bestmode);
+ if (EFI_ERROR(status) || efi_gop->Mode->Mode != bestmode) {
+ printf("GOP setmode failed: %" PRIxMAX "\n",
+ (uintmax_t)status);
+ goto nofb;
}
- if (bestmode >= 0) {
- status = uefi_call_wrapper(efi_gop->SetMode, 2, efi_gop,
- bestmode);
- if (EFI_ERROR(status) || efi_gop->Mode->Mode != bestmode)
- printf("GOP setmode failed: %" PRIxMAX "\n",
- (uintmax_t)status);
+
+ status = uefi_call_wrapper(efi_gop->QueryMode, 4,
+ efi_gop, bestmode, &sz, &info);
+ if (EFI_ERROR(status)) {
+ printf("GOP querymode failed: %" PRIxMAX "\n",
+ (uintmax_t)status);
+ goto nofb;
}
- info = efi_gop->Mode->Info;
memset(&fb, 0, sizeof(fb));
fb.physaddr = efi_gop->Mode->FrameBufferBase;
fb.flags = 0;
@@ -499,6 +495,10 @@ bi_framebuffer(void)
}
framebuffer_configure(&fb);
+ return;
+
+nofb:
+ framebuffer_configure(NULL);
}
int
@@ -658,10 +658,16 @@ efi_find_gop_mode(char *arg)
snprintf(mode, sizeof(mode), "%lux%lux%u",
(long)info->HorizontalResolution,
- (long)info->HorizontalResolution,
+ (long)info->VerticalResolution,
depth);
if (strcmp(arg, mode) == 0)
return i;
+
+ snprintf(mode, sizeof(mode), "%lux%lu",
+ (long)info->HorizontalResolution,
+ (long)info->VerticalResolution);
+ if (strcmp(arg, mode) == 0)
+ return i;
}
return -1;
}