git: df065f699f1f - main - stand: More sensible defaults when ConOut is missing

From: Warner Losh <imp_at_FreeBSD.org>
Date: Sat, 27 Aug 2022 04:18:46 UTC
The branch main has been updated by imp:

URL: https://cgit.FreeBSD.org/src/commit/?id=df065f699f1ff819bb9607c44a6754275ab335ed

commit df065f699f1ff819bb9607c44a6754275ab335ed
Author:     Warner Losh <imp@FreeBSD.org>
AuthorDate: 2022-08-26 21:46:33 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2022-08-27 04:17:56 +0000

    stand: More sensible defaults when ConOut is missing
    
    When ConOut is missing, we used to default to serial. Except we did it
    in the worst way possible by just setting the howto bits and not
    updating the console setting, which lead to weird behavior where we'd
    get some things on the video port, others on serial.
    
    Instead, set console to "efi,comconsole" for this case. Also set
    RB_MULTIPLE always (so we get dual consoles from the kernel) and or in
    RB_SERIAL when we can't find GOPs that suggest the precense of a video
    console. This will put output in the most places and have a sensible
    default for 'primary' console.
    
    Sponsored by:           Netflix
    Reviewed by:            emaste, manu
    Differential Revision:  https://reviews.freebsd.org/D36299
---
 stand/efi/loader/Makefile      |  2 ++
 stand/efi/loader/framebuffer.c | 15 +++++++++++++++
 stand/efi/loader/framebuffer.h |  2 ++
 stand/efi/loader/main.c        | 20 ++++++++++++++++++--
 4 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/stand/efi/loader/Makefile b/stand/efi/loader/Makefile
index 1edb5674712e..e6083c2dd450 100644
--- a/stand/efi/loader/Makefile
+++ b/stand/efi/loader/Makefile
@@ -39,6 +39,8 @@ CFLAGS.bootinfo.c += -I$(SRCTOP)/sys/teken
 CFLAGS.bootinfo.c += -I${SRCTOP}/contrib/pnglite
 CFLAGS.framebuffer.c += -I$(SRCTOP)/sys/teken
 CFLAGS.framebuffer.c += -I${SRCTOP}/contrib/pnglite
+CFLAGS.main.c += -I$(SRCTOP)/sys/teken
+CFLAGS.main.c += -I${SRCTOP}/contrib/pnglite
 CFLAGS.gfx_fb.c += -I$(SRCTOP)/sys/teken
 CFLAGS.gfx_fb.c += -I${SRCTOP}/sys/cddl/contrib/opensolaris/common/lz4
 CFLAGS.gfx_fb.c += -I${SRCTOP}/contrib/pnglite
diff --git a/stand/efi/loader/framebuffer.c b/stand/efi/loader/framebuffer.c
index afae18603f9e..9dfe547d7557 100644
--- a/stand/efi/loader/framebuffer.c
+++ b/stand/efi/loader/framebuffer.c
@@ -535,6 +535,21 @@ efifb_get_edid(edid_res_list_t *res)
 	return (rv);
 }
 
+bool
+efi_has_gop(void)
+{
+	EFI_STATUS status;
+	EFI_HANDLE *hlist;
+	UINTN hsize;
+
+	hsize = 0;
+	hlist = NULL;
+	status = BS->LocateHandle(ByProtocol, &gop_guid, NULL, &hsize, hlist);
+
+	return (status == EFI_BUFFER_TOO_SMALL);
+}
+
+
 int
 efi_find_framebuffer(teken_gfx_t *gfx_state)
 {
diff --git a/stand/efi/loader/framebuffer.h b/stand/efi/loader/framebuffer.h
index 6c47a136f7be..a9377984de2b 100644
--- a/stand/efi/loader/framebuffer.h
+++ b/stand/efi/loader/framebuffer.h
@@ -27,11 +27,13 @@
  * $FreeBSD$
  */
 
+#include <teken.h>
 #include <gfx_fb.h>
 
 #ifndef	_EFIFB_H_
 #define	_EFIFB_H_
 
+bool	efi_has_gop(void);
 int	efi_find_framebuffer(teken_gfx_t *gfx_state);
 
 #endif /* _EFIFB_H_ */
diff --git a/stand/efi/loader/main.c b/stand/efi/loader/main.c
index 346c600da3df..a6fccf9e93c5 100644
--- a/stand/efi/loader/main.c
+++ b/stand/efi/loader/main.c
@@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$");
 #include <smbios.h>
 
 #include "efizfs.h"
+#include "framebuffer.h"
 
 #include "loader_efi.h"
 
@@ -760,8 +761,20 @@ parse_uefi_con_out(void)
 	if (rv != EFI_SUCCESS)
 		rv = efi_global_getenv("ConOutDev", buf, &sz);
 	if (rv != EFI_SUCCESS) {
-		/* If we don't have any ConOut default to serial */
-		how = RB_SERIAL;
+		/*
+		 * If we don't have any ConOut default to both. If we have GOP
+		 * make video primary, otherwise just make serial primary. In
+		 * either case, try to use both the 'efi' console which will use
+		 * the GOP, if present and serial. If there's an EFI BIOS that
+		 * omits this, but has a serial port redirect, we'll
+		 * unavioidably get doubled characters (but we'll be right in
+		 * all the other more common cases).
+		 */
+		if (efi_has_gop())
+			how = RB_MULTIPLE;
+		else
+			how = RB_MULTIPLE | RB_SERIAL;
+		setenv("console", "efi,comconsole", 1);
 		goto out;
 	}
 	ep = buf + sz;
@@ -949,6 +962,9 @@ main(int argc, CHAR16 *argv[])
 	setenv("console", "efi", 1);
 	uhowto = parse_uefi_con_out();
 #if defined(__riscv)
+	/*
+	 * This workaround likely is papering over a real issue
+	 */
 	if ((uhowto & RB_SERIAL) != 0)
 		setenv("console", "comconsole", 1);
 #endif