Module Name:    src
Committed By:   jmcneill
Date:           Sun Sep  9 13:37:54 UTC 2018

Modified Files:
        src/sys/stand/efiboot: boot.c efiboot.h efifdt.c efifdt.h exec.c

Log Message:
Add "dtb" command for loading a custom .dtb file.


To generate a diff of this commit:
cvs rdiff -u -r1.6 -r1.7 src/sys/stand/efiboot/boot.c
cvs rdiff -u -r1.4 -r1.5 src/sys/stand/efiboot/efiboot.h \
    src/sys/stand/efiboot/exec.c
cvs rdiff -u -r1.8 -r1.9 src/sys/stand/efiboot/efifdt.c
cvs rdiff -u -r1.3 -r1.4 src/sys/stand/efiboot/efifdt.h

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/boot.c
diff -u src/sys/stand/efiboot/boot.c:1.6 src/sys/stand/efiboot/boot.c:1.7
--- src/sys/stand/efiboot/boot.c:1.6	Fri Sep  7 17:30:58 2018
+++ src/sys/stand/efiboot/boot.c	Sun Sep  9 13:37:54 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: boot.c,v 1.6 2018/09/07 17:30:58 jmcneill Exp $	*/
+/*	$NetBSD: boot.c,v 1.7 2018/09/09 13:37:54 jmcneill Exp $	*/
 
 /*-
  * Copyright (c) 2016 Kimihiro Nonaka <non...@netbsd.org>
@@ -54,9 +54,11 @@ static const char * const names[][2] = {
 
 static char default_device[32];
 static char initrd_path[255];
+static char dtb_path[255];
 
 void	command_boot(char *);
 void	command_dev(char *);
+void	command_dtb(char *);
 void	command_initrd(char *);
 void	command_ls(char *);
 void	command_reset(char *);
@@ -66,6 +68,7 @@ void	command_quit(char *);
 const struct boot_command commands[] = {
 	{ "boot",	command_boot,		"boot [dev:][filename] [args]\n     (ex. \"hd0a:\\netbsd.old -s\"" },
 	{ "dev",	command_dev,		"dev" },
+	{ "dtb",	command_dtb,		"dtb [dev:][filename]" },
 	{ "initrd",	command_initrd,		"initrd [dev:][filename]" },
 	{ "ls",		command_ls,		"ls [hdNn:/path]" },
 	{ "version",	command_version,	"version" },
@@ -114,6 +117,12 @@ command_dev(char *arg)
 }
 
 void
+command_dtb(char *arg)
+{
+	set_dtb_path(arg);
+}
+
+void
 command_initrd(char *arg)
 {
 	set_initrd_path(arg);
@@ -181,6 +190,21 @@ get_initrd_path(void)
 	return initrd_path;
 }
 
+int
+set_dtb_path(char *arg)
+{
+	if (strlen(arg) + 1 > sizeof(dtb_path))
+		return ERANGE;
+	strcpy(dtb_path, arg);
+	return 0;
+}
+
+char *
+get_dtb_path(void)
+{
+	return dtb_path;
+}
+
 void
 print_banner(void)
 {

Index: src/sys/stand/efiboot/efiboot.h
diff -u src/sys/stand/efiboot/efiboot.h:1.4 src/sys/stand/efiboot/efiboot.h:1.5
--- src/sys/stand/efiboot/efiboot.h:1.4	Fri Sep  7 17:30:58 2018
+++ src/sys/stand/efiboot/efiboot.h	Sun Sep  9 13:37:54 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: efiboot.h,v 1.4 2018/09/07 17:30:58 jmcneill Exp $	*/
+/*	$NetBSD: efiboot.h,v 1.5 2018/09/09 13:37:54 jmcneill Exp $	*/
 
 /*-
  * Copyright (c) 2016 Kimihiro Nonaka <non...@netbsd.org>
@@ -54,6 +54,8 @@ int set_default_device(char *);
 char *get_default_device(void);
 int set_initrd_path(char *);
 char *get_initrd_path(void);
+int set_dtb_path(char *);
+char *get_dtb_path(void);
 
 /* console.c */
 int ischar(void);
Index: src/sys/stand/efiboot/exec.c
diff -u src/sys/stand/efiboot/exec.c:1.4 src/sys/stand/efiboot/exec.c:1.5
--- src/sys/stand/efiboot/exec.c:1.4	Fri Sep  7 17:30:58 2018
+++ src/sys/stand/efiboot/exec.c	Sun Sep  9 13:37:54 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: exec.c,v 1.4 2018/09/07 17:30:58 jmcneill Exp $ */
+/* $NetBSD: exec.c,v 1.5 2018/09/09 13:37:54 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2018 Jared McNeill <jmcne...@invisible.ca>
@@ -36,19 +36,17 @@ u_long load_offset = 0;
 #define	FDT_SPACE	(4 * 1024 * 1024)
 #define	FDT_ALIGN	((2 * 1024 * 1024) - 1)
 
-static EFI_PHYSICAL_ADDRESS initrd_addr;
-static u_long initrd_size = 0;
+static EFI_PHYSICAL_ADDRESS initrd_addr, dtb_addr;
+static u_long initrd_size = 0, dtb_size = 0;
 
 static int
-load_initrd(void)
+load_file(char *path, EFI_PHYSICAL_ADDRESS *paddr, u_long *psize)
 {
 	EFI_STATUS status;
 	struct stat st;
 	ssize_t len;
-	char *path;
 	int fd;
 
-	path = get_initrd_path();
 	if (strlen(path) == 0)
 		return 0;
 
@@ -63,44 +61,44 @@ load_initrd(void)
 		return errno;
 	}
 	if (st.st_size == 0) {
-		printf("boot: empty initrd %s\n", path);
+		printf("boot: empty file %s\n", path);
 		close(fd);
 		return EINVAL;
 	}
 
-	initrd_size = st.st_size;
+	*psize = st.st_size;
 
 #ifdef EFIBOOT_ALLOCATE_MAX_ADDRESS
-	initrd_addr = EFIBOOT_ALLOCATE_MAX_ADDRESS;
+	*paddr = EFIBOOT_ALLOCATE_MAX_ADDRESS;
 	status = uefi_call_wrapper(BS->AllocatePages, 4, AllocateMaxAddress, EfiLoaderData,
-	    EFI_SIZE_TO_PAGES(initrd_size), &initrd_addr);
+	    EFI_SIZE_TO_PAGES(*psize), paddr);
 #else
-	initrd_addr = 0;
+	*paddr = 0;
 	status = uefi_call_wrapper(BS->AllocatePages, 4, AllocateAnyPages, EfiLoaderData,
-	    EFI_SIZE_TO_PAGES(initrd_size), &initrd_addr);
+	    EFI_SIZE_TO_PAGES(*psize), paddr);
 #endif
 	if (EFI_ERROR(status)) {
-		printf("Failed to allocate %lu bytes for initrd image (error %lu)\n",
-		    initrd_size, status);
+		printf("Failed to allocate %lu bytes for %s (error %lu)\n",
+		    *psize, path, status);
 		close(fd);
 		return ENOMEM;
 	}
 
 	printf("boot: loading %s ", path);
-	len = read(fd, (void *)initrd_addr, initrd_size);
+	len = read(fd, (void *)*paddr, *psize);
 	close(fd);
 
-	if (len != initrd_size) {
+	if (len != *psize) {
 		if (len < 0)
 			printf(": %s\n", strerror(errno));
 		else
-			printf(": returned %ld (expected %ld)\n", len, initrd_size);
+			printf(": returned %ld (expected %ld)\n", len, *psize);
 		return EIO;
 	}
 
 	printf("done.\n");
 
-	efi_dcache_flush(initrd_addr, initrd_size);
+	efi_dcache_flush(*paddr, *psize);
 
 	return 0;
 }
@@ -113,7 +111,8 @@ exec_netbsd(const char *fname, const cha
 	EFI_STATUS status;
 	int fd;
 
-	load_initrd();
+	load_file(get_initrd_path(), &initrd_addr, &initrd_size);
+	load_file(get_dtb_path(), &dtb_addr, &dtb_size);
 
 	memset(marks, 0, sizeof(marks));
 	fd = loadfile(fname, marks, COUNT_KERNEL | LOAD_NOTE);
@@ -150,6 +149,11 @@ exec_netbsd(const char *fname, const cha
 	close(fd);
 	load_offset = 0;
 
+	if (dtb_addr && efi_fdt_set_data((void *)dtb_addr) != 0) {
+		printf("boot: invalid DTB data\n");
+		goto cleanup;
+	}
+
 	if (efi_fdt_size() > 0) {
 		efi_fdt_init((marks[MARK_END] + FDT_ALIGN) & ~FDT_ALIGN, FDT_ALIGN + 1);
 		efi_fdt_initrd(initrd_addr, initrd_size);
@@ -171,5 +175,10 @@ cleanup:
 		initrd_addr = 0;
 		initrd_size = 0;
 	}
+	if (dtb_addr) {
+		uefi_call_wrapper(BS->FreePages, 2, dtb_addr, EFI_SIZE_TO_PAGES(dtb_size));
+		dtb_addr = 0;
+		dtb_size = 0;
+	}
 	return EIO;
 }

Index: src/sys/stand/efiboot/efifdt.c
diff -u src/sys/stand/efiboot/efifdt.c:1.8 src/sys/stand/efiboot/efifdt.c:1.9
--- src/sys/stand/efiboot/efifdt.c:1.8	Fri Sep  7 17:30:58 2018
+++ src/sys/stand/efiboot/efifdt.c	Sun Sep  9 13:37:54 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: efifdt.c,v 1.8 2018/09/07 17:30:58 jmcneill Exp $ */
+/* $NetBSD: efifdt.c,v 1.9 2018/09/09 13:37:54 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2018 Jared McNeill <jmcne...@invisible.ca>
@@ -65,6 +65,16 @@ efi_fdt_probe(void)
 	return 0;
 }
 
+int
+efi_fdt_set_data(void *data)
+{
+	if (fdt_check_header(data) != 0)
+		return EINVAL;
+
+	fdt_data = data;
+	return 0;
+}
+
 void *
 efi_fdt_data(void)
 {

Index: src/sys/stand/efiboot/efifdt.h
diff -u src/sys/stand/efiboot/efifdt.h:1.3 src/sys/stand/efiboot/efifdt.h:1.4
--- src/sys/stand/efiboot/efifdt.h:1.3	Fri Sep  7 17:30:58 2018
+++ src/sys/stand/efiboot/efifdt.h	Sun Sep  9 13:37:54 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: efifdt.h,v 1.3 2018/09/07 17:30:58 jmcneill Exp $ */
+/* $NetBSD: efifdt.h,v 1.4 2018/09/09 13:37:54 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2018 Jared McNeill <jmcne...@invisible.ca>
@@ -28,6 +28,7 @@
 
 int efi_fdt_probe(void);
 void efi_fdt_memory_map(void);
+int efi_fdt_set_data(void *);
 void *efi_fdt_data(void);
 int efi_fdt_size(void);
 void efi_fdt_show(void);

Reply via email to