Module Name:    src
Committed By:   jmcneill
Date:           Sun Jun 21 17:24:26 UTC 2020

Modified Files:
        src/sys/stand/efiboot: Makefile.efiboot boot.c efifdt.c efifdt.h exec.c
            version
        src/sys/stand/efiboot/bootaa64: Makefile
        src/sys/stand/efiboot/bootarm: Makefile
Added Files:
        src/sys/stand/efiboot: module.c module.h

Log Message:
Add module support.


To generate a diff of this commit:
cvs rdiff -u -r1.13 -r1.14 src/sys/stand/efiboot/Makefile.efiboot
cvs rdiff -u -r1.21 -r1.22 src/sys/stand/efiboot/boot.c
cvs rdiff -u -r1.23 -r1.24 src/sys/stand/efiboot/efifdt.c
cvs rdiff -u -r1.8 -r1.9 src/sys/stand/efiboot/efifdt.h
cvs rdiff -u -r1.15 -r1.16 src/sys/stand/efiboot/exec.c \
    src/sys/stand/efiboot/version
cvs rdiff -u -r0 -r1.1 src/sys/stand/efiboot/module.c \
    src/sys/stand/efiboot/module.h
cvs rdiff -u -r1.7 -r1.8 src/sys/stand/efiboot/bootaa64/Makefile
cvs rdiff -u -r1.4 -r1.5 src/sys/stand/efiboot/bootarm/Makefile

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/stand/efiboot/Makefile.efiboot
diff -u src/sys/stand/efiboot/Makefile.efiboot:1.13 src/sys/stand/efiboot/Makefile.efiboot:1.14
--- src/sys/stand/efiboot/Makefile.efiboot:1.13	Thu May 14 19:19:08 2020
+++ src/sys/stand/efiboot/Makefile.efiboot	Sun Jun 21 17:24:26 2020
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile.efiboot,v 1.13 2020/05/14 19:19:08 riastradh Exp $
+# $NetBSD: Makefile.efiboot,v 1.14 2020/06/21 17:24:26 jmcneill Exp $
 
 S=		${.CURDIR}/../../..
 
@@ -21,8 +21,10 @@ AFLAGS.start.S= ${${ACTIVE_CC} == "clang
 
 .PATH: ${EFIDIR}/gnuefi
 SOURCES=	crt0-efi-${GNUEFIARCH}.S reloc_${GNUEFIARCH}.c
-SOURCES+=	boot.c conf.c console.c dev_net.c devopen.c exec.c panic.c prompt.c
-SOURCES+=	efiboot.c efichar.c efidev.c efienv.c efigetsecs.c efifdt.c efifile.c efiblock.c efinet.c efipxe.c efiacpi.c efirng.c smbios.c
+SOURCES+=	boot.c conf.c console.c dev_net.c devopen.c exec.c module.c \
+		panic.c prompt.c
+SOURCES+=	efiboot.c efichar.c efidev.c efienv.c efigetsecs.c efifdt.c \
+		efifile.c efiblock.c efinet.c efipxe.c efiacpi.c efirng.c smbios.c
 
 .PATH: ${S}/external/bsd/libfdt/dist
 CPPFLAGS+=	-I${S}/external/bsd/libfdt/dist

Index: src/sys/stand/efiboot/boot.c
diff -u src/sys/stand/efiboot/boot.c:1.21 src/sys/stand/efiboot/boot.c:1.22
--- src/sys/stand/efiboot/boot.c:1.21	Thu May 14 19:19:08 2020
+++ src/sys/stand/efiboot/boot.c	Sun Jun 21 17:24:26 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: boot.c,v 1.21 2020/05/14 19:19:08 riastradh Exp $	*/
+/*	$NetBSD: boot.c,v 1.22 2020/06/21 17:24:26 jmcneill Exp $	*/
 
 /*-
  * Copyright (c) 2016 Kimihiro Nonaka <non...@netbsd.org>
@@ -33,6 +33,7 @@
 #include "efiacpi.h"
 #include "efienv.h"
 #include "efirng.h"
+#include "module.h"
 
 #include <sys/bootblock.h>
 #include <sys/boot_flag.h>
@@ -90,6 +91,9 @@ void	command_dtb(char *);
 void	command_plist(char *);
 void	command_initrd(char *);
 void	command_rndseed(char *);
+void	command_modules(char *);
+void	command_load(char *);
+void	command_unload(char *);
 void	command_ls(char *);
 void	command_mem(char *);
 void	command_printenv(char *);
@@ -107,6 +111,9 @@ const struct boot_command commands[] = {
 	{ "plist",	command_plist,		"plist [dev:][filename]" },
 	{ "initrd",	command_initrd,		"initrd [dev:][filename]" },
 	{ "rndseed",	command_rndseed,	"rndseed [dev:][filename]" },
+	{ "modules",	command_modules,	"modules [{on|off|reset}]" },
+	{ "load",	command_load,		"load <module_name>" },
+	{ "unload",	command_unload,		"unload <module_name>" },
 	{ "ls",		command_ls,		"ls [hdNn:/path]" },
 	{ "mem",	command_mem,		"mem" },
 	{ "printenv",	command_printenv,	"printenv [key]" },
@@ -193,6 +200,47 @@ command_rndseed(char *arg)
 }
 
 void
+command_modules(char *arg)
+{
+	if (arg && *arg) {
+		if (strcmp(arg, "on") == 0)
+			module_enable(1);
+		else if (strcmp(arg, "off") == 0)
+			module_enable(0);
+		else if (strcmp(arg, "reset") == 0)
+			module_remove_all();
+		else {
+			command_help("");
+			return;
+		}
+	} else {
+		printf("modules are %sabled\n", module_enabled ? "en" : "dis");
+	}
+}
+
+void
+command_load(char *arg)
+{
+	if (!arg || !*arg) {
+		command_help("");
+		return;
+	}
+
+	module_add(arg);
+}
+
+void
+command_unload(char *arg)
+{
+	if (!arg || !*arg) {
+		command_help("");
+		return;
+	}
+
+	module_remove(arg);
+}
+
+void
 command_ls(char *arg)
 {
 	ls(arg);

Index: src/sys/stand/efiboot/efifdt.c
diff -u src/sys/stand/efiboot/efifdt.c:1.23 src/sys/stand/efiboot/efifdt.c:1.24
--- src/sys/stand/efiboot/efifdt.c:1.23	Thu May 14 19:21:53 2020
+++ src/sys/stand/efiboot/efifdt.c	Sun Jun 21 17:24:26 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: efifdt.c,v 1.23 2020/05/14 19:21:53 riastradh Exp $ */
+/* $NetBSD: efifdt.c,v 1.24 2020/06/21 17:24:26 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2019 Jason R. Thorpe
@@ -425,3 +425,18 @@ efi_fdt_efirng(u_long efirng_addr, u_lon
 	fdt_setprop_u64(fdt_data, chosen, "netbsd,efirng-end",
 	    efirng_addr + efirng_size);
 }
+
+/* pass in module information */
+void
+efi_fdt_module(const char *module_name, u_long module_addr, u_long module_size)
+{
+	int chosen;
+
+	if (module_size == 0)
+		return;
+
+	chosen = efi_fdt_chosen();
+	fdt_appendprop_string(fdt_data, chosen, "netbsd,module-names", module_name);
+	fdt_appendprop_u64(fdt_data, chosen, "netbsd,modules", module_addr);
+	fdt_appendprop_u64(fdt_data, chosen, "netbsd,modules", module_size);
+}

Index: src/sys/stand/efiboot/efifdt.h
diff -u src/sys/stand/efiboot/efifdt.h:1.8 src/sys/stand/efiboot/efifdt.h:1.9
--- src/sys/stand/efiboot/efifdt.h:1.8	Thu May 14 19:20:08 2020
+++ src/sys/stand/efiboot/efifdt.h	Sun Jun 21 17:24:26 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: efifdt.h,v 1.8 2020/05/14 19:20:08 riastradh Exp $ */
+/* $NetBSD: efifdt.h,v 1.9 2020/06/21 17:24:26 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2018 Jared McNeill <jmcne...@invisible.ca>
@@ -39,5 +39,6 @@ void efi_fdt_bootargs(const char *);
 void efi_fdt_initrd(u_long, u_long);
 void efi_fdt_rndseed(u_long, u_long);
 void efi_fdt_efirng(u_long, u_long);
+void efi_fdt_module(const char *, u_long, u_long);
 void efi_fdt_init(u_long, u_long);
 void efi_fdt_fini(void);

Index: src/sys/stand/efiboot/exec.c
diff -u src/sys/stand/efiboot/exec.c:1.15 src/sys/stand/efiboot/exec.c:1.16
--- src/sys/stand/efiboot/exec.c:1.15	Sat May 23 16:40:41 2020
+++ src/sys/stand/efiboot/exec.c	Sun Jun 21 17:24:26 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: exec.c,v 1.15 2020/05/23 16:40:41 thorpej Exp $ */
+/* $NetBSD: exec.c,v 1.16 2020/06/21 17:24:26 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2019 Jason R. Thorpe
@@ -32,7 +32,9 @@
 #include "efifdt.h"
 #include "efiacpi.h"
 #include "efirng.h"
+#include "module.h"
 
+#include <sys/param.h>
 #include <sys/reboot.h>
 
 extern char twiddle_toggle;
@@ -276,6 +278,32 @@ load_fdt_overlays(void)
 }
 
 static void
+load_module(const char *module_name)
+{
+	EFI_PHYSICAL_ADDRESS addr;
+	u_long size;
+	char path[PATH_MAX];
+
+	snprintf(path, sizeof(path), "%s/%s/%s.kmod", module_prefix,
+	    module_name, module_name);
+
+	if (load_file(path, 0, false, &addr, &size) != 0 || addr == 0 || size == 0)
+		return;
+
+	efi_fdt_module(module_name, (u_long)addr, size);
+}
+
+static void
+load_modules(const char *kernel_name)
+{
+	if (!module_enabled)
+		return;
+
+	module_init(kernel_name);
+	module_foreach(load_module);
+}
+
+static void
 generate_efirng(void)
 {
 	EFI_PHYSICAL_ADDRESS addr;
@@ -387,6 +415,7 @@ exec_netbsd(const char *fname, const cha
 		    &rndseed_addr, &rndseed_size);
 
 		efi_fdt_init((marks[MARK_END] + FDT_ALIGN) & ~FDT_ALIGN, FDT_ALIGN + 1);
+		load_modules(fname);
 		load_fdt_overlays();
 		efi_fdt_initrd(initrd_addr, initrd_size);
 		efi_fdt_rndseed(rndseed_addr, rndseed_size);
Index: src/sys/stand/efiboot/version
diff -u src/sys/stand/efiboot/version:1.15 src/sys/stand/efiboot/version:1.16
--- src/sys/stand/efiboot/version:1.15	Thu May 14 19:25:16 2020
+++ src/sys/stand/efiboot/version	Sun Jun 21 17:24:26 2020
@@ -1,4 +1,4 @@
-$NetBSD: version,v 1.15 2020/05/14 19:25:16 riastradh Exp $
+$NetBSD: version,v 1.16 2020/06/21 17:24:26 jmcneill Exp $
 
 NOTE ANY CHANGES YOU MAKE TO THE EFI BOOTLOADER HERE.  The format of this
 file is important - make sure the entries are appended on end, last item
@@ -19,3 +19,4 @@ is taken as the current.
 1.12:	Derive ACPI model string from SMBIOS.
 1.13:	Add rndseed support.
 1.14:	Add EFI RNG support.
+1.15:	Add module support.

Index: src/sys/stand/efiboot/bootaa64/Makefile
diff -u src/sys/stand/efiboot/bootaa64/Makefile:1.7 src/sys/stand/efiboot/bootaa64/Makefile:1.8
--- src/sys/stand/efiboot/bootaa64/Makefile:1.7	Sat Jan 25 11:24:20 2020
+++ src/sys/stand/efiboot/bootaa64/Makefile	Sun Jun 21 17:24:26 2020
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.7 2020/01/25 11:24:20 jmcneill Exp $
+# $NetBSD: Makefile,v 1.8 2020/06/21 17:24:26 jmcneill Exp $
 
 PROG=		bootaa64.efi
 OBJFMT=		binary
@@ -12,6 +12,7 @@ CFLAGS+=	-DEFIBOOT_ALIGN=0x200000
 CFLAGS+=	-DEFIBOOT_RUNTIME_ADDRESS=0xffff800000000000L
 CFLAGS+=	-DEFIBOOT_RUNTIME_SIZE=0x40000000UL
 CFLAGS+=	-DEFIBOOT_ACPI
+CFLAGS+=	-DEFIBOOT_MODULE_MACHINE=\"evbarm\"
 
 .include "${.CURDIR}/../Makefile.efiboot"
 

Index: src/sys/stand/efiboot/bootarm/Makefile
diff -u src/sys/stand/efiboot/bootarm/Makefile:1.4 src/sys/stand/efiboot/bootarm/Makefile:1.5
--- src/sys/stand/efiboot/bootarm/Makefile:1.4	Sat Jan 25 11:24:20 2020
+++ src/sys/stand/efiboot/bootarm/Makefile	Sun Jun 21 17:24:26 2020
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.4 2020/01/25 11:24:20 jmcneill Exp $
+# $NetBSD: Makefile,v 1.5 2020/06/21 17:24:26 jmcneill Exp $
 
 PROG=		bootarm.efi
 OBJFMT=		binary
@@ -11,6 +11,7 @@ EXTRA_SOURCES+=	cache.S
 
 COPTS+=		-mfloat-abi=soft -mno-unaligned-access -ffreestanding -fno-unwind-tables
 CFLAGS+=	-DEFIBOOT_ALIGN=0x1000000
+CFLAGS+=	-DEFIBOOT_MODULE_MACHINE=\"evbarm\"
 LDFLAGS+=	-N
 
 .include "${.CURDIR}/../Makefile.efiboot"

Added files:

Index: src/sys/stand/efiboot/module.c
diff -u /dev/null src/sys/stand/efiboot/module.c:1.1
--- /dev/null	Sun Jun 21 17:24:26 2020
+++ src/sys/stand/efiboot/module.c	Sun Jun 21 17:24:26 2020
@@ -0,0 +1,153 @@
+/* $NetBSD: module.c,v 1.1 2020/06/21 17:24:26 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2020 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jared McNeill <jmcne...@invisible.ca>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "efiboot.h"
+#include "module.h"
+
+#include <sys/queue.h>
+
+int module_enabled = 1;
+char module_prefix[128];
+
+struct boot_module {
+	char *module_name;
+	TAILQ_ENTRY(boot_module) entries;
+};
+TAILQ_HEAD(, boot_module) boot_modules = TAILQ_HEAD_INITIALIZER(boot_modules);
+
+static const char *
+module_machine(void)
+{
+	return EFIBOOT_MODULE_MACHINE;
+}
+
+static void
+module_set_prefix(const char *kernel_path)
+{
+#ifdef KERNEL_DIR
+	char *ptr = strrchr(kernel_path, '/');
+	if (ptr)
+		*ptr = '\0';
+	snprintf(module_prefix, sizeof(module_prefix), "%s/modules", kernel_path);
+	if (ptr)
+		*ptr = '/';
+#else
+	const u_int vmajor = netbsd_version / 100000000;
+	const u_int vminor = netbsd_version / 1000000 % 100;
+	const u_int vpatch = netbsd_version / 100 % 100;
+
+	if (vminor == 99) {
+		snprintf(module_prefix, sizeof(module_prefix),
+		    "/stand/%s/%u.%u.%u/modules", module_machine(),
+		    vmajor, vminor, vpatch);
+	} else if (vmajor != 0) {
+		snprintf(module_prefix, sizeof(module_prefix),
+		    "/stand/%s/%u.%u/modules", module_machine(),
+		    vmajor, vminor);
+	}
+#endif
+}
+
+void
+module_init(const char *kernel_path)
+{
+	module_set_prefix(kernel_path);
+}
+
+void
+module_foreach(void (*fn)(const char *))
+{
+	struct boot_module *bm;
+
+	TAILQ_FOREACH(bm, &boot_modules, entries) {
+		fn(bm->module_name);
+	}
+}
+
+void
+module_add(const char *module_name)
+{
+	struct boot_module *bm;
+
+	/* Trim leading whitespace */
+	while (*module_name == ' ' || *module_name == '\t')
+		++module_name;
+
+	/* Duplicate check */
+	TAILQ_FOREACH(bm, &boot_modules, entries) {
+		if (strcmp(bm->module_name, module_name) == 0)
+			return;
+	}
+
+	/* Add to list of modules */
+	bm = alloc(sizeof(*bm));
+	const int slen = strlen(module_name) + 1;
+	bm->module_name = alloc(slen);
+	memcpy(bm->module_name, module_name, slen);
+	TAILQ_INSERT_TAIL(&boot_modules, bm, entries);
+}
+
+void
+module_remove(const char *module_name)
+{
+	struct boot_module *bm;
+
+	/* Trim leading whitespace */
+	while (*module_name == ' ' || *module_name == '\t')
+		++module_name;
+
+	TAILQ_FOREACH(bm, &boot_modules, entries) {
+		if (strcmp(bm->module_name, module_name) == 0) {
+			TAILQ_REMOVE(&boot_modules, bm, entries);
+			dealloc(bm->module_name, strlen(bm->module_name) + 1);
+			dealloc(bm, sizeof(*bm));
+			return;
+		}
+	}
+}
+
+void
+module_remove_all(void)
+{
+	struct boot_module *bm;
+
+	while ((bm = TAILQ_FIRST(&boot_modules)) != NULL) {
+		TAILQ_REMOVE(&boot_modules, bm, entries);
+		dealloc(bm->module_name, strlen(bm->module_name) + 1);
+		dealloc(bm, sizeof(*bm));
+	}
+}
+
+void
+module_enable(int onoff)
+{
+	module_enabled = onoff;
+}
Index: src/sys/stand/efiboot/module.h
diff -u /dev/null src/sys/stand/efiboot/module.h:1.1
--- /dev/null	Sun Jun 21 17:24:26 2020
+++ src/sys/stand/efiboot/module.h	Sun Jun 21 17:24:26 2020
@@ -0,0 +1,37 @@
+/* $NetBSD: module.h,v 1.1 2020/06/21 17:24:26 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2020 Jared McNeill <jmcne...@invisible.ca>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* module.c */
+extern int	module_enabled;
+extern char	module_prefix[];
+void		module_init(const char *);
+void		module_foreach(void (*)(const char *));
+void		module_enable(int);
+void		module_add(const char *);
+void		module_remove(const char *);
+void		module_remove_all(void);

Reply via email to