git: aaaa5a2e68e2 - main - loader: narrow the scope of gfx frame buffer wrt tg supported kernels

From: Warner Losh <imp_at_FreeBSD.org>
Date: Tue, 14 Dec 2021 22:28:02 UTC
The branch main has been updated by imp:

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

commit aaaa5a2e68e256101c9737c30ad142f1c3f05131
Author:     Warner Losh <imp@FreeBSD.org>
AuthorDate: 2021-12-14 21:38:43 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2021-12-14 22:27:47 +0000

    loader: narrow the scope of gfx frame buffer wrt tg supported kernels
    
    Store whether or not we found a vbefb module (eg, a tg supported kernel)
    in the preloaded_file structure. This automatically resets on reload and
    eliminates load_elf knowing about any gfx_* interface. Restrict this to
    i386, which is the only place it's used. Update libi386 to check in the
    preloaded_file struct. Eliminate this from the teken_gfx
    structure. Rewrite the parsing code to be more inline. Check this from
    the same place we check for a relocatable amd64 kernel.
    
    Sponsored by:           Netflix
    Reviewed by:            manu, tsoome
    Differential Revision:  https://reviews.freebsd.org/D33427
---
 stand/common/bootstrap.h      |  3 ++
 stand/common/gfx_fb.h         |  1 -
 stand/common/load_elf.c       | 85 ++++++++++++++++++++-----------------------
 stand/common/module.c         |  2 -
 stand/i386/libi386/bootinfo.c |  2 +-
 stand/loader.mk               |  3 --
 6 files changed, 44 insertions(+), 52 deletions(-)

diff --git a/stand/common/bootstrap.h b/stand/common/bootstrap.h
index ea03519f5b39..42b2c73f5774 100644
--- a/stand/common/bootstrap.h
+++ b/stand/common/bootstrap.h
@@ -232,6 +232,9 @@ struct preloaded_file
 #ifdef __amd64__
 	bool			f_kernphys_relocatable;
 #endif
+#if defined(__i386__)
+	bool			f_tg_kernel_support;
+#endif
 };
 
 struct file_format
diff --git a/stand/common/gfx_fb.h b/stand/common/gfx_fb.h
index 0a2bc966d445..e55f6fc13fe5 100644
--- a/stand/common/gfx_fb.h
+++ b/stand/common/gfx_fb.h
@@ -219,7 +219,6 @@ typedef struct teken_gfx {
 	uint32_t	*tg_shadow_fb;		/* units of 4 bytes */
 	teken_funcs_t	*tg_functions;
 	void		*tg_private;
-	bool		tg_kernel_supported;	/* Loaded kernel is supported */
 } teken_gfx_t;
 
 extern font_list_t fonts;
diff --git a/stand/common/load_elf.c b/stand/common/load_elf.c
index a213b34970f0..4ac4248a4e97 100644
--- a/stand/common/load_elf.c
+++ b/stand/common/load_elf.c
@@ -39,7 +39,6 @@ __FBSDID("$FreeBSD$");
 #include <stand.h>
 #define FREEBSD_ELF
 #include <sys/link_elf.h>
-#include <gfx_fb.h>
 
 #include "bootstrap.h"
 
@@ -91,8 +90,6 @@ static int __elfN(reloc_ptr)(struct preloaded_file *mp, elf_file_t ef,
     Elf_Addr p, void *val, size_t len);
 static int __elfN(parse_modmetadata)(struct preloaded_file *mp, elf_file_t ef,
     Elf_Addr p_start, Elf_Addr p_end);
-static bool __elfN(parse_vt_drv_set)(struct preloaded_file *mp, elf_file_t ef,
-    Elf_Addr p_start, Elf_Addr p_end);
 static symaddr_fn __elfN(symaddr);
 static char	*fake_modname(const char *name);
 
@@ -219,6 +216,43 @@ is_kernphys_relocatable(elf_file_t ef)
 }
 #endif
 
+#ifdef __i386__
+static bool
+is_tg_kernel_support(struct preloaded_file *fp, elf_file_t ef)
+{
+	Elf_Sym		sym;
+	Elf_Addr	p_start, p_end, v, p;
+	char		vd_name[16];
+	int		error;
+
+	if (__elfN(lookup_symbol)(ef, "__start_set_vt_drv_set", &sym, STT_NOTYPE) != 0)
+		return (false);
+	p_start = sym.st_value + ef->off;
+	if (__elfN(lookup_symbol)(ef, "__stop_set_vt_drv_set", &sym, STT_NOTYPE) != 0)
+		return (false);
+	p_end = sym.st_value + ef->off;
+
+	/*
+	 * Walk through vt_drv_set, each vt driver structure starts with
+	 * static 16 chars for driver name. If we have "vbefb", return true.
+	 */
+	for (p = p_start; p < p_end; p += sizeof(Elf_Addr)) {
+		COPYOUT(p, &v, sizeof(v));
+
+		error = __elfN(reloc_ptr)(fp, ef, p, &v, sizeof(v));
+		if (error == EOPNOTSUPP)
+			v += ef->off;
+		else if (error != 0)
+			return (false);
+		COPYOUT(v, &vd_name, sizeof(vd_name));
+		if (strncmp(vd_name, "vbefb", sizeof(vd_name)) == 0)
+			return (true);
+	}
+
+	return (false);
+}
+#endif
+
 static int
 __elfN(load_elf_header)(char *filename, elf_file_t ef)
 {
@@ -448,6 +482,9 @@ __elfN(loadfile_raw)(char *filename, uint64_t dest,
 	err = 0;
 #ifdef __amd64__
 	fp->f_kernphys_relocatable = multiboot || is_kernphys_relocatable(&ef);
+#endif
+#ifdef __i386__
+	fp->f_tg_kernel_support = is_tg_kernel_support(fp, &ef);
 #endif
 	goto out;
 
@@ -872,18 +909,6 @@ nosyms:
 	ef->buckets = ef->hashtab + 2;
 	ef->chains = ef->buckets + ef->nbuckets;
 
-	if (!gfx_state.tg_kernel_supported &&
-	    __elfN(lookup_symbol)(ef, "__start_set_vt_drv_set", &sym,
-	    STT_NOTYPE) == 0) {
-		p_start = sym.st_value + ef->off;
-		if (__elfN(lookup_symbol)(ef, "__stop_set_vt_drv_set", &sym,
-		    STT_NOTYPE) == 0) {
-			p_end = sym.st_value + ef->off;
-			gfx_state.tg_kernel_supported =
-			    __elfN(parse_vt_drv_set)(fp, ef, p_start, p_end);
-		}
-	}
-
 	if (__elfN(lookup_symbol)(ef, "__start_set_modmetadata_set", &sym,
 	    STT_NOTYPE) != 0)
 		return 0;
@@ -1084,36 +1109,6 @@ out:
 	return (err);
 }
 
-/*
- * Walk through vt_drv_set, each vt driver structure starts with
- * static 16 chars for driver name. If we have "vbefb", return true.
- */
-static bool
-__elfN(parse_vt_drv_set)(struct preloaded_file *fp, elf_file_t ef,
-    Elf_Addr p_start, Elf_Addr p_end)
-{
-	Elf_Addr v, p;
-	char vd_name[16];
-	int error;
-
-	p = p_start;
-	while (p < p_end) {
-		COPYOUT(p, &v, sizeof(v));
-
-		error = __elfN(reloc_ptr)(fp, ef, p, &v, sizeof(v));
-		if (error == EOPNOTSUPP)
-			v += ef->off;
-		else if (error != 0)
-			return (false);
-		COPYOUT(v, &vd_name, sizeof(vd_name));
-		if (strncmp(vd_name, "vbefb", sizeof(vd_name)) == 0)
-			return (true);
-		p += sizeof(Elf_Addr);
-	}
-
-	return (false);
-}
-
 int
 __elfN(parse_modmetadata)(struct preloaded_file *fp, elf_file_t ef,
     Elf_Addr p_start, Elf_Addr p_end)
diff --git a/stand/common/module.c b/stand/common/module.c
index 772fe2bc37ce..b9ddd868b8de 100644
--- a/stand/common/module.c
+++ b/stand/common/module.c
@@ -278,8 +278,6 @@ unload(void)
 	}
 	loadaddr = 0;
 	unsetenv("kernelname");
-	/* Reset tg_kernel_supported to allow next load to check it again. */
-	gfx_state.tg_kernel_supported = false;
 }
 
 COMMAND_SET(unload, "unload", "unload all modules", command_unload);
diff --git a/stand/i386/libi386/bootinfo.c b/stand/i386/libi386/bootinfo.c
index 57f926b76589..bdf409b00ec0 100644
--- a/stand/i386/libi386/bootinfo.c
+++ b/stand/i386/libi386/bootinfo.c
@@ -41,7 +41,7 @@ __FBSDID("$FreeBSD$");
 void
 bi_load_vbe_data(struct preloaded_file *kfp)
 {
-	if (!gfx_state.tg_kernel_supported) {
+	if (!kfp->f_tg_kernel_support) {
 		/*
 		 * Loaded kernel does not have vt/vbe backend,
 		 * switch console to text mode.
diff --git a/stand/loader.mk b/stand/loader.mk
index 49e9e88c842d..3eb70cde8b7a 100644
--- a/stand/loader.mk
+++ b/stand/loader.mk
@@ -29,9 +29,6 @@ SRCS+=	metadata.c
 SRCS+=	load_elf64.c reloc_elf64.c
 SRCS+=	metadata.c
 .endif
-# elf loaders set frame buffer things, so add includes for that.
-CFLAGS.load_elf32.c += -I$(SRCTOP)/sys/teken -I${SRCTOP}/contrib/pnglite
-CFLAGS.load_elf64.c += -I$(SRCTOP)/sys/teken -I${SRCTOP}/contrib/pnglite
 
 .if ${LOADER_DISK_SUPPORT:Uyes} == "yes"
 CFLAGS.part.c+= -DHAVE_MEMCPY -I${SRCTOP}/sys/contrib/zlib