Module Name:    src
Committed By:   jmcneill
Date:           Fri Aug 24 02:01:07 UTC 2018

Added Files:
        src/sys/stand/efiboot: Makefile.efiboot boot.c conf.c console.c
            devopen.c devopen.h efiboot.c efiboot.h efiboot_machdep.h efichar.c
            efifdt.c efifdt.h efifile.c efifile.h efigetsecs.c exec.c panic.c
            prompt.c version
        src/sys/stand/efiboot/bootaa64: Makefile cache.S efibootaa64.c

Log Message:
Add MI EFI bootloader and AArch64 glue.


To generate a diff of this commit:
cvs rdiff -u -r0 -r1.1 src/sys/stand/efiboot/Makefile.efiboot \
    src/sys/stand/efiboot/boot.c src/sys/stand/efiboot/conf.c \
    src/sys/stand/efiboot/console.c src/sys/stand/efiboot/devopen.c \
    src/sys/stand/efiboot/devopen.h src/sys/stand/efiboot/efiboot.c \
    src/sys/stand/efiboot/efiboot.h src/sys/stand/efiboot/efiboot_machdep.h \
    src/sys/stand/efiboot/efichar.c src/sys/stand/efiboot/efifdt.c \
    src/sys/stand/efiboot/efifdt.h src/sys/stand/efiboot/efifile.c \
    src/sys/stand/efiboot/efifile.h src/sys/stand/efiboot/efigetsecs.c \
    src/sys/stand/efiboot/exec.c src/sys/stand/efiboot/panic.c \
    src/sys/stand/efiboot/prompt.c src/sys/stand/efiboot/version
cvs rdiff -u -r0 -r1.1 src/sys/stand/efiboot/bootaa64/Makefile \
    src/sys/stand/efiboot/bootaa64/cache.S \
    src/sys/stand/efiboot/bootaa64/efibootaa64.c

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

Added files:

Index: src/sys/stand/efiboot/Makefile.efiboot
diff -u /dev/null src/sys/stand/efiboot/Makefile.efiboot:1.1
--- /dev/null	Fri Aug 24 02:01:07 2018
+++ src/sys/stand/efiboot/Makefile.efiboot	Fri Aug 24 02:01:06 2018
@@ -0,0 +1,148 @@
+# $NetBSD: Makefile.efiboot,v 1.1 2018/08/24 02:01:06 jmcneill Exp $
+
+S=		${.CURDIR}/../../..
+
+NOMAN=		# defined
+NOPIE=		# defined
+NOLIBCSANITIZER=# defined
+NOSANITIZER=	# defined
+NORELRO=	# defined
+PROG?=		boot.efi
+NEWVERSWHAT?=	"EFI Boot"
+
+EFIDIR= ${S}/external/bsd/gnu-efi/dist
+GNUEFIARCH?= ${MACHINE_CPU}
+CPPFLAGS+= -I${EFIDIR}/inc -I${EFIDIR}/inc/${GNUEFIARCH}
+CPPFLAGS+= -I${EFIDIR}/inc/protocol
+
+LDSCRIPT?= ${EFIDIR}/gnuefi/elf_${GNUEFIARCH}_efi.lds
+
+AFLAGS.start.S= ${${ACTIVE_CC} == "clang":?-no-integrated-as:}
+
+.PATH: ${EFIDIR}/gnuefi
+SOURCES=	crt0-efi-${GNUEFIARCH}.S reloc_${GNUEFIARCH}.c
+SOURCES+=	boot.c conf.c console.c devopen.c exec.c panic.c prompt.c
+SOURCES+=	efiboot.c efichar.c efifdt.c efifile.c
+
+.PATH: ${S}/external/bsd/libfdt/dist
+CPPFLAGS+=	-I${S}/external/bsd/libfdt/dist
+SOURCES+=	fdt.c fdt_addresses.c fdt_empty_tree.c
+SOURCES+=	fdt_ro.c fdt_rw.c fdt_strerror.c fdt_sw.c fdt_wip.c
+
+SRCS= ${SOURCES} ${EXTRA_SOURCES}
+
+.include <bsd.init.mk>
+
+STRIPFLAG=	# nothing
+
+LIBCRT0=	# nothing
+LIBCRTI=	# nothing
+LIBCRTBEGIN=	# nothing
+LIBCRTEND=	# nothing
+LIBC=		# nothing
+
+BINDIR=/usr/mdec
+BINMODE=444
+
+.PATH:	${.CURDIR} ${.CURDIR}/..
+.PATH:	${.CURDIR}/../../lib
+
+LDFLAGS+= -nostdlib -T${LDSCRIPT} -Bsymbolic -shared
+CPPFLAGS+= -I$S -I${.CURDIR} -I${.CURDIR}/../common -I$S/lib/libsa
+CPPFLAGS+= -I${.OBJDIR}
+CPPFLAGS+= -I${.CURDIR}/../../lib
+
+COPTS+=	-fpic -g -O2
+COPTS+=	-fshort-wchar -fno-strict-aliasing
+COPTS+=	-ffreestanding -fno-stack-protector
+LDFLAGS+= --defsym=EFI_SUBSYSTEM=0xa
+
+
+COPTS+= ${${ACTIVE_CC} == "gcc":? -Wno-error=unused-but-set-variable :}
+CPPFLAGS+= -nostdinc -D_STANDALONE
+CPPFLAGS+= -DEFIBOOT
+
+CPPFLAGS+= -Wall -Wmissing-prototypes
+CPPFLAGS+= -Wno-pointer-sign
+
+CPPFLAGS+= -DHEAP_VARIABLE
+#CPPFLAGS+= -DSUPPORT_CD9660
+CPPFLAGS+= -D"devb2cdb(bno)=(bno)"
+#CPPFLAGS+= -DSUPPORT_DOSFS
+#CPPFLAGS+= -DSUPPORT_EXT2FS
+#CPPFLAGS+= -DSUPPORT_BOOTP
+#CPPFLAGS+= -DSUPPORT_DHCP
+#CPPFLAGS+= -DSUPPORT_NFS
+#CPPFLAGS+= -DSUPPORT_TFTP
+#CPPFLAGS+= -DLIBSA_ENABLE_LS_OP
+
+#CPPFLAGS+= -DARP_DEBUG
+#CPPFLAGS+= -DBOOTP_DEBUG
+#CPPFLAGS+= -DNET_DEBUG
+#CPPFLAGS+= -DNETIF_DEBUG
+#CPPFLAGS+= -DNFS_DEBUG
+#CPPFLAGS+= -DRARP_DEBUG
+#CPPFLAGS+= -DRPC_DEBUG
+
+SAMISCCPPFLAGS+= -DLIBSA_PRINTF_LONGLONG_SUPPORT
+SAMISCCPPFLAGS+= -DLIBSA_PRINTF_WIDTH_SUPPORT
+SAMISCCPPFLAGS+= -D"cdb2devb(bno)=(bno)"
+
+### find out what to use for libsa
+SA_AS= library
+SAMISCMAKEFLAGS+="SA_USE_LOADFILE=yes"
+SAMISCMAKEFLAGS+="SA_USE_CREAD=yes"
+#SAMISCMAKEFLAGS+="SA_INCLUDE_NET=yes"
+#SAMISCMAKEFLAGS+="SA_ENABLE_LS_OP=yes"
+.include "${S}/lib/libsa/Makefile.inc"
+LIBSA= ${SALIB}
+
+### find out what to use for libkern
+KERN_AS= library
+LIBKERN_ARCH?= ${MACHINE_ARCH}
+KERNMISCMAKEFLAGS+="LIBKERN_ARCH=${LIBKERN_ARCH}"
+.include "${S}/lib/libkern/Makefile.inc"
+LIBKERN= ${KERNLIB}
+
+### find out what to use for libz
+Z_AS= library
+.include "${S}/lib/libz/Makefile.inc"
+LIBZ= ${ZLIB}
+
+### find out what to use for libgnuefi
+GNUEFI_AS= library
+LIBGNUEFI_ARCH?= ${MACHINE_ARCH}
+GNUEFIMISCMAKEFLAGS+="LIBGNUEFI_ARCH=${LIBGNUEFI_ARCH}"
+GNUEFIMISCCPPFLAGS+= -I${EFIDIR}/lib
+.include "${S}/lib/libgnuefi/Makefile.inc"
+LIBGNUEFI= ${GNUEFILIB}
+
+cleandir distclean: .WAIT cleanlibdir
+
+cleanlibdir:
+	-rm -rf lib
+
+LIBLIST= ${LIBGNUEFI} ${LIBSA} ${LIBZ} ${LIBKERN} ${LIBSA}
+
+VERSIONMACHINE=evbarm
+.include "${S}/conf/newvers_stand.mk"
+
+CLEANFILES+=	${PROG}.so ${PROG}.tmp
+
+${PROG}: ${PROG}.so
+	${OBJCOPY} -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel \
+	    -j .rela -j .rel.* -j .rela.* -j .rel* -j .rela* \
+	    -j .reloc -O binary ${PROG}.so ${.TARGET}
+
+.include <bsd.prog.mk>
+
+${PROG}.so: ${OBJS} ${LIBLIST} ${LDSCRIPT} ${.CURDIR}/../Makefile.efiboot
+	${LD} ${LDFLAGS} -o ${.TARGET}.tmp ${OBJS} ${LIBLIST}
+	@if ${OBJDUMP} -t ${.TARGET}.tmp | grep 'UND'; then		\
+	    (echo Undefined symbols; false);				\
+	fi
+	rm -f ${.TARGET}
+	mv ${.TARGET}.tmp ${.TARGET}
+
+KLINK_MACHINE?=	${MACHINE}
+.include <bsd.klinks.mk>
Index: src/sys/stand/efiboot/boot.c
diff -u /dev/null src/sys/stand/efiboot/boot.c:1.1
--- /dev/null	Fri Aug 24 02:01:07 2018
+++ src/sys/stand/efiboot/boot.c	Fri Aug 24 02:01:06 2018
@@ -0,0 +1,144 @@
+/*	$NetBSD: boot.c,v 1.1 2018/08/24 02:01:06 jmcneill Exp $	*/
+
+/*-
+ * Copyright (c) 2016 Kimihiro Nonaka <non...@netbsd.org>
+ * Copyright (c) 2018 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.
+ */
+
+#include "efiboot.h"
+
+#include <sys/bootblock.h>
+#include <sys/boot_flag.h>
+#include <machine/limits.h>
+
+#include <loadfile.h>
+
+extern const char bootprog_name[], bootprog_rev[], bootprog_kernrev[];
+
+extern char twiddle_toggle;
+
+static const char * const names[][2] = {
+	{ "netbsd", "netbsd.gz" },
+	{ "onetbsd", "onetbsd.gz" },
+	{ "netbsd.old", "netbsd.old.gz" },
+};
+
+#define NUMNAMES	__arraycount(names)
+#define DEFFILENAME	names[0][0]
+
+#define	DEFTIMEOUT	5
+
+void	command_boot(char *);
+void	command_reset(char *);
+void	command_version(char *);
+void	command_quit(char *);
+
+const struct boot_command commands[] = {
+	{ "boot",	command_boot,		"boot [fsN:][filename] [args]\n     (ex. \"fs0:\\netbsd.old -s\"" },
+	{ "version",	command_version,	"version" },
+	{ "help",	command_help,		"help|?" },
+	{ "?",		command_help,		NULL },
+	{ "quit",	command_quit,		"quit" },
+	{ NULL,		NULL },
+};
+
+void
+command_help(char *arg)
+{
+	int n;
+
+	printf("commands are:\n");
+	for (n = 0; commands[n].c_name; n++) {
+		if (commands[n].c_help)
+			printf("%s\n", commands[n].c_help);
+	}
+}
+
+void
+command_boot(char *arg)
+{
+	char *fname = arg;
+	char *bootargs = gettrailer(arg);
+
+	exec_netbsd(*fname ? fname : DEFFILENAME, bootargs);
+}
+
+void
+command_version(char *arg)
+{
+	char *ufirmware;
+	int rv;
+
+	printf("EFI version: %d.%02d\n",
+	    ST->Hdr.Revision >> 16, ST->Hdr.Revision & 0xffff);
+	ufirmware = NULL;
+	rv = ucs2_to_utf8(ST->FirmwareVendor, &ufirmware);
+	if (rv == 0) {
+		printf("EFI Firmware: %s (rev %d.%02d)\n", ufirmware,
+		    ST->FirmwareRevision >> 16,
+		    ST->FirmwareRevision & 0xffff);
+		FreePool(ufirmware);
+	}
+}
+
+void
+command_quit(char *arg)
+{
+	efi_exit();
+}
+
+void
+print_banner(void)
+{
+	printf("\n\n"
+	    ">> %s, Revision %s (from NetBSD %s)\n",
+	    bootprog_name, bootprog_rev, bootprog_kernrev);
+}
+
+void
+boot(void)
+{
+	int currname, c;
+
+	print_banner();
+
+	printf("Press return to boot now, any other key for boot prompt\n");
+	for (currname = 0; currname < NUMNAMES; currname++) {
+		printf("booting %s - starting in ", names[currname][0]);
+
+		c = awaitkey(DEFTIMEOUT, 1);
+		if ((c != '\r') && (c != '\n') && (c != '\0')) {
+			bootprompt(); /* does not return */
+		}
+
+		/*
+		 * try pairs of names[] entries, foo and foo.gz
+		 */
+		exec_netbsd(names[currname][0], "");
+		exec_netbsd(names[currname][1], "");
+	}
+
+	bootprompt();	/* does not return */
+}
Index: src/sys/stand/efiboot/conf.c
diff -u /dev/null src/sys/stand/efiboot/conf.c:1.1
--- /dev/null	Fri Aug 24 02:01:07 2018
+++ src/sys/stand/efiboot/conf.c	Fri Aug 24 02:01:06 2018
@@ -0,0 +1,43 @@
+/* $NetBSD: conf.c,v 1.1 2018/08/24 02:01:06 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2018 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.
+ */
+
+#include "efiboot.h"
+#include "efifile.h"
+
+struct devsw devsw[] = {
+	{ "efifile", efi_file_strategy, efi_file_open, efi_file_close, noioctl },
+};
+int ndevs = __arraycount(devsw);
+
+struct netif_driver *netif_drivers[] = {
+};
+int n_netif_drivers = __arraycount(netif_drivers);
+
+struct fs_ops file_system[] = {
+};
+int nfsys = __arraycount(file_system);
Index: src/sys/stand/efiboot/console.c
diff -u /dev/null src/sys/stand/efiboot/console.c:1.1
--- /dev/null	Fri Aug 24 02:01:07 2018
+++ src/sys/stand/efiboot/console.c	Fri Aug 24 02:01:06 2018
@@ -0,0 +1,63 @@
+/* $NetBSD: console.c,v 1.1 2018/08/24 02:01:06 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2018 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.
+ */
+
+#include "efiboot.h"
+
+int
+getchar(void)
+{
+	EFI_STATUS status;
+	EFI_INPUT_KEY key;
+
+	status = uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, &key);
+	while (status == EFI_NOT_READY) {
+		WaitForSingleEvent(ST->ConIn->WaitForKey, 0);
+		status = uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, &key);
+	}
+
+	return key.UnicodeChar;
+}
+
+void
+putchar(int c)
+{
+	CHAR16 buf[2] = { c, '\0' };
+	if (c == '\n')
+		putchar('\r');
+	uefi_call_wrapper(ST->ConOut->OutputString, 2, ST->ConOut, buf);
+}
+
+int
+ischar(void)
+{
+	EFI_STATUS status;
+
+	status = uefi_call_wrapper(BS->CheckEvent, 1, ST->ConIn->WaitForKey);
+
+	return status == EFI_SUCCESS;
+}
Index: src/sys/stand/efiboot/devopen.c
diff -u /dev/null src/sys/stand/efiboot/devopen.c:1.1
--- /dev/null	Fri Aug 24 02:01:07 2018
+++ src/sys/stand/efiboot/devopen.c	Fri Aug 24 02:01:06 2018
@@ -0,0 +1,40 @@
+/* $NetBSD: devopen.c,v 1.1 2018/08/24 02:01:06 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2018 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.
+ */
+
+#include "efiboot.h"
+#include "efifile.h"
+
+int
+devopen(struct open_file *f, const char *fname, char **file)
+{
+	int error;
+
+	error = efi_file_open(f, fname);
+
+	return error;
+}
Index: src/sys/stand/efiboot/devopen.h
diff -u /dev/null src/sys/stand/efiboot/devopen.h:1.1
--- /dev/null	Fri Aug 24 02:01:07 2018
+++ src/sys/stand/efiboot/devopen.h	Fri Aug 24 02:01:06 2018
@@ -0,0 +1,34 @@
+/*	$NetBSD: devopen.h,v 1.1 2018/08/24 02:01:06 jmcneill Exp $	*/
+
+/*-
+ * Copyright (c) 2016 Kimihiro Nonaka <non...@netbsd.org>
+ * 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.
+ */
+
+#define	MAXDEVNAME	16
+
+struct devdesc {
+	char	d_name[MAXDEVNAME];
+	char	d_unit;
+};
Index: src/sys/stand/efiboot/efiboot.c
diff -u /dev/null src/sys/stand/efiboot/efiboot.c:1.1
--- /dev/null	Fri Aug 24 02:01:07 2018
+++ src/sys/stand/efiboot/efiboot.c	Fri Aug 24 02:01:06 2018
@@ -0,0 +1,123 @@
+/* $NetBSD: efiboot.c,v 1.1 2018/08/24 02:01:06 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2018 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.
+ */
+
+#include "efiboot.h"
+#include "efifile.h"
+#include "efifdt.h"
+
+EFI_HANDLE efi_ih;
+EFI_DEVICE_PATH *efi_bootdp;
+EFI_LOADED_IMAGE *efi_li;
+
+static EFI_PHYSICAL_ADDRESS heap_start;
+static UINTN heap_size = 1 * 1024 * 1024;
+static EFI_EVENT delay_ev = 0;
+
+EFI_STATUS EFIAPI efi_main(EFI_HANDLE, EFI_SYSTEM_TABLE *);
+
+EFI_STATUS EFIAPI
+efi_main(EFI_HANDLE imageHandle, EFI_SYSTEM_TABLE *systemTable)
+{
+	EFI_STATUS status;
+	u_int sz = EFI_SIZE_TO_PAGES(heap_size);
+
+	efi_ih = imageHandle;
+
+	InitializeLib(imageHandle, systemTable);
+
+	status = uefi_call_wrapper(ST->ConOut->Reset, 2, ST->ConOut, FALSE);
+	if (EFI_ERROR(status))
+		return status;
+
+	status = uefi_call_wrapper(BS->AllocatePages, 4, AllocateAnyPages, EfiLoaderData, sz, &heap_start);
+	if (EFI_ERROR(status))
+		return status;
+	setheap((void *)heap_start, (void *)(heap_start + heap_size));
+
+	status = uefi_call_wrapper(BS->HandleProtocol, 3, imageHandle, &LoadedImageProtocol, (void **)&efi_li);
+	if (EFI_ERROR(status))
+		return status;
+	status = uefi_call_wrapper(BS->HandleProtocol, 3, efi_li->DeviceHandle, &DevicePathProtocol, (void **)&efi_bootdp);
+	if (EFI_ERROR(status))
+		return status;
+
+#ifdef EFIBOOT_DEBUG
+	Print(L"Loaded image      : 0x%lX\n", efi_li);
+	Print(L"FilePath          : 0x%lX\n", efi_li->FilePath);
+	Print(L"ImageBase         : 0x%lX\n", efi_li->ImageBase);
+	Print(L"ImageSize         : 0x%lX\n", efi_li->ImageSize);
+	Print(L"Image file        : %s\n", DevicePathToStr(efi_li->FilePath));
+#endif
+
+	efi_fdt_probe();
+	efi_file_system_probe();
+
+	boot();
+
+	return EFI_SUCCESS;
+}
+
+void
+efi_cleanup(void)
+{
+	EFI_STATUS status;
+	UINTN nentries, mapkey, descsize;
+	UINT32 descver;
+
+	LibMemoryMap(&nentries, &mapkey, &descsize, &descver);
+
+	status = uefi_call_wrapper(BS->ExitBootServices, 2, efi_ih, mapkey);
+	if (EFI_ERROR(status))
+		printf("WARNING: ExitBootServices failed\n");
+}
+
+void
+efi_exit(void)
+{
+	EFI_STATUS status;
+
+	status = uefi_call_wrapper(BS->Exit, 4, efi_ih, EFI_ABORTED, 0, NULL);
+	if (EFI_ERROR(status))
+		printf("WARNING: Exit failed\n");
+}
+
+void
+efi_delay(int us)
+{
+	EFI_STATUS status;
+	UINTN val;
+
+	if (delay_ev == 0) {
+		status = uefi_call_wrapper(BS->CreateEvent, 5, EVT_TIMER, TPL_APPLICATION, 0, 0, &delay_ev);
+		if (EFI_ERROR(status))
+			return;
+	}
+
+	uefi_call_wrapper(BS->SetTimer, 3, delay_ev, TimerRelative, us * 10);
+	uefi_call_wrapper(BS->WaitForEvent, 3, 1, &delay_ev, &val);
+}
Index: src/sys/stand/efiboot/efiboot.h
diff -u /dev/null src/sys/stand/efiboot/efiboot.h:1.1
--- /dev/null	Fri Aug 24 02:01:07 2018
+++ src/sys/stand/efiboot/efiboot.h	Fri Aug 24 02:01:06 2018
@@ -0,0 +1,77 @@
+/*	$NetBSD: efiboot.h,v 1.1 2018/08/24 02:01:06 jmcneill Exp $	*/
+
+/*-
+ * Copyright (c) 2016 Kimihiro Nonaka <non...@netbsd.org>
+ * 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.
+ */
+
+#include <efi.h>
+#include <efilib.h>
+
+#include <lib/libsa/stand.h>
+#include <lib/libkern/libkern.h>
+
+#include "efiboot_machdep.h"
+
+struct boot_command {
+	const char *c_name;
+	void (*c_fn)(char *);
+	const char *c_help;
+};
+
+/* boot.c */
+void boot(void);
+void clearit(void);
+void print_banner(void);
+extern const struct boot_command commands[];
+void command_help(char *);
+
+/* console.c */
+int ischar(void);
+
+/* efiboot.c */
+extern EFI_HANDLE IH;
+extern EFI_DEVICE_PATH *efi_bootdp;
+extern EFI_LOADED_IMAGE *efi_li;
+void efi_cleanup(void);
+void efi_exit(void);
+void efi_delay(int);
+
+/* efichar.c */
+size_t ucs2len(const CHAR16 *);
+int ucs2_to_utf8(const CHAR16 *, char **);
+int utf8_to_ucs2(const char *, CHAR16 **, size_t *);
+
+/* exec.c */
+int exec_netbsd(const char *, const char *);
+
+/* panic.c */
+__dead VOID Panic(IN CHAR16 *, ...);
+__dead void reboot(void);
+
+/* prompt.c */
+char *gettrailer(char *);
+void docommand(char *);
+char awaitkey(int, int);
+__dead void bootprompt(void);
Index: src/sys/stand/efiboot/efiboot_machdep.h
diff -u /dev/null src/sys/stand/efiboot/efiboot_machdep.h:1.1
--- /dev/null	Fri Aug 24 02:01:07 2018
+++ src/sys/stand/efiboot/efiboot_machdep.h	Fri Aug 24 02:01:06 2018
@@ -0,0 +1,33 @@
+/* $NetBSD: efiboot_machdep.h,v 1.1 2018/08/24 02:01:06 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2018 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.
+ */
+
+#ifndef EFIBOOT_ALIGN
+#define	EFIBOOT_ALIGN 0
+#endif
+
+void efi_boot_kernel(u_long[]);
Index: src/sys/stand/efiboot/efichar.c
diff -u /dev/null src/sys/stand/efiboot/efichar.c:1.1
--- /dev/null	Fri Aug 24 02:01:07 2018
+++ src/sys/stand/efiboot/efichar.c	Fri Aug 24 02:01:06 2018
@@ -0,0 +1,195 @@
+/*	$NetBSD: efichar.c,v 1.1 2018/08/24 02:01:06 jmcneill Exp $	*/
+
+/*-
+ * Copyright (c) 2010 Marcel Moolenaar
+ * 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 AUTHOR 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 AUTHOR 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 <sys/cdefs.h>
+#if 0
+__FBSDID("$FreeBSD: head/stand/efi/libefi/efichar.c 328061 2018-01-16 20:35:54Z tsoome $");
+#endif
+
+#include "efiboot.h"
+
+size_t
+ucs2len(const CHAR16 *str)
+{
+	size_t i;
+
+	i = 0;
+	while (*str++)
+		i++;
+	return i;
+}
+
+/*
+ * If nm were converted to utf8, what what would strlen
+ * return on the resulting string?
+ */
+static size_t
+utf8_len_of_ucs2(const CHAR16 *nm)
+{
+	size_t len;
+	CHAR16 c;
+
+	len = 0;
+	while (*nm) {
+		c = *nm++;
+		if (c > 0x7ff)
+			len += 3;
+		else if (c > 0x7f)
+			len += 2;
+		else
+			len++;
+	}
+
+	return len;
+}
+
+int
+ucs2_to_utf8(const CHAR16 *nm, char **name)
+{
+	size_t len, sz;
+	CHAR16 c;
+	char *cp;
+	int freeit = *name == NULL;
+
+	sz = utf8_len_of_ucs2(nm) + 1;
+	len = 0;
+	if (*name != NULL)
+		cp = *name;
+	else
+		cp = *name = AllocatePool(sz);
+	if (*name == NULL)
+		return ENOMEM;
+
+	while (*nm) {
+		c = *nm++;
+		if (c > 0x7ff) {
+			if (len++ < sz)
+				*cp++ = (char)(0xE0 | (c >> 12));
+			if (len++ < sz)
+				*cp++ = (char)(0x80 | ((c >> 6) & 0x3f));
+			if (len++ < sz)
+				*cp++ = (char)(0x80 | (c & 0x3f));
+		} else if (c > 0x7f) {
+			if (len++ < sz)
+				*cp++ = (char)(0xC0 | ((c >> 6) & 0x1f));
+			if (len++ < sz)
+				*cp++ = (char)(0x80 | (c & 0x3f));
+		} else {
+			if (len++ < sz)
+				*cp++ = (char)(c & 0x7f);
+		}
+	}
+
+	if (len >= sz) {
+		/* Absent bugs, we'll never return EOVERFLOW */
+		if (freeit) {
+			FreePool(*name);
+			*name = NULL;
+		}
+		return EOVERFLOW;
+	}
+	*cp++ = '\0';
+
+	return 0;
+}
+
+int
+utf8_to_ucs2(const char *name, CHAR16 **nmp, size_t *len)
+{
+	CHAR16 *nm;
+	size_t sz;
+	uint32_t ucs4;
+	int c, bytes;
+	int freeit = *nmp == NULL;
+
+	sz = strlen(name) * 2 + 2;
+	if (*nmp == NULL)
+		*nmp = AllocatePool(sz);
+	if (*nmp == NULL)
+		return ENOMEM;
+	nm = *nmp;
+	*len = sz;
+
+	ucs4 = 0;
+	bytes = 0;
+	while (sz > 1 && *name != '\0') {
+		c = *name++;
+		/*
+		 * Conditionalize on the two major character types:
+		 * initial and followup characters.
+		 */
+		if ((c & 0xc0) != 0x80) {
+			/* Initial characters. */
+			if (bytes != 0)
+				goto ilseq;
+			if ((c & 0xf8) == 0xf0) {
+				ucs4 = c & 0x07;
+				bytes = 3;
+			} else if ((c & 0xf0) == 0xe0) {
+				ucs4 = c & 0x0f;
+				bytes = 2;
+			} else if ((c & 0xe0) == 0xc0) {
+				ucs4 = c & 0x1f;
+				bytes = 1;
+			} else {
+				ucs4 = c & 0x7f;
+				bytes = 0;
+			}
+		} else {
+			/* Followup characters. */
+			if (bytes > 0) {
+				ucs4 = (ucs4 << 6) + (c & 0x3f);
+				bytes--;
+			} else if (bytes == 0)
+				goto ilseq;
+		}
+		if (bytes == 0) {
+			if (ucs4 > 0xffff)
+				goto ilseq;
+			*nm++ = (CHAR16)ucs4;
+			sz -= 2;
+		}
+	}
+	if (sz < 2) {
+		if (freeit) {
+			FreePool(nm);
+			*nmp = NULL;
+		}
+		return EINVAL;
+	}
+	sz -= 2;
+	*nm = 0;
+	*len -= sz;
+	return 0;
+ilseq:
+	if (freeit) {
+		FreePool(nm);
+		*nmp = NULL;
+	}
+	return EILSEQ;
+}
Index: src/sys/stand/efiboot/efifdt.c
diff -u /dev/null src/sys/stand/efiboot/efifdt.c:1.1
--- /dev/null	Fri Aug 24 02:01:07 2018
+++ src/sys/stand/efiboot/efifdt.c	Fri Aug 24 02:01:06 2018
@@ -0,0 +1,124 @@
+/* $NetBSD: efifdt.c,v 1.1 2018/08/24 02:01:06 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2018 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.
+ */
+
+#include "efiboot.h"
+#include "efifdt.h"
+
+#include <libfdt.h>
+
+#define FDT_TABLE_GUID	\
+	{ 0xb1b621d5, 0xf19c, 0x41a5, { 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0 } }
+static EFI_GUID FdtTableGuid = FDT_TABLE_GUID;
+
+#define	FDT_MEMORY_NODE_PATH	"/memory"
+#define	FDT_MEMORY_NODE_NAME	"memory"
+#define	FDT_CHOSEN_NODE_PATH	"/chosen"
+
+#define	FDT_MEMORY_USABLE(_md)	\
+	((_md)->Type == EfiLoaderCode || (_md)->Type == EfiLoaderData || \
+	 (_md)->Type == EfiBootServicesCode || (_md)->Type == EfiBootServicesData || \
+	 (_md)->Type == EfiConventionalMemory)
+
+static void *fdt_data = NULL;
+
+int
+efi_fdt_probe(void)
+{
+	EFI_STATUS status;
+
+	status = LibGetSystemConfigurationTable(&FdtTableGuid, &fdt_data);
+	if (EFI_ERROR(status))
+		return EIO;
+
+	if (fdt_check_header(fdt_data) != 0) {
+		fdt_data = NULL;
+		return EINVAL;
+	}
+
+	return 0;
+}
+
+void *
+efi_fdt_data(void)
+{
+	return fdt_data;
+}
+
+int
+efi_fdt_size(void)
+{
+	return fdt_data == NULL ? 0 : fdt_totalsize(fdt_data);
+}
+
+void
+efi_fdt_memory_map(void)
+{
+	UINTN nentries = 0, mapkey, descsize;
+	EFI_MEMORY_DESCRIPTOR *md;
+	UINT32 descver;
+	int n, memory;
+
+	memory = fdt_path_offset(fdt_data, FDT_MEMORY_NODE_PATH);
+	if (memory < 0)
+		memory = fdt_add_subnode(fdt_data, fdt_path_offset(fdt_data, "/"), FDT_MEMORY_NODE_NAME);
+	if (memory < 0)
+		panic("FDT: Failed to create " FDT_MEMORY_NODE_PATH " node");
+
+	fdt_delprop(fdt_data, memory, "reg");
+
+	const int address_cells = fdt_address_cells(fdt_data, fdt_path_offset(fdt_data, "/"));
+	const int size_cells = fdt_size_cells(fdt_data, fdt_path_offset(fdt_data, "/"));
+
+	md = LibMemoryMap(&nentries, &mapkey, &descsize, &descver);
+	for (n = 0; n < nentries; n++, md = NextMemoryDescriptor(md, descsize)) {
+		if ((md->Attribute & EFI_MEMORY_WB) == 0)
+			continue;
+		if (!FDT_MEMORY_USABLE(md))
+			continue;
+
+		if (address_cells == 1)
+			fdt_appendprop_u32(fdt_data, fdt_path_offset(fdt_data, FDT_MEMORY_NODE_PATH),
+			    "reg", (uint32_t)md->PhysicalStart);
+		else
+			fdt_appendprop_u64(fdt_data, fdt_path_offset(fdt_data, FDT_MEMORY_NODE_PATH),
+			    "reg", md->PhysicalStart);
+
+		if (size_cells == 1)
+			fdt_appendprop_u32(fdt_data, fdt_path_offset(fdt_data, FDT_MEMORY_NODE_PATH),
+			    "reg", (uint32_t)md->NumberOfPages * EFI_PAGE_SIZE);
+		else
+			fdt_appendprop_u64(fdt_data, fdt_path_offset(fdt_data, FDT_MEMORY_NODE_PATH),
+			    "reg", (uint64_t)md->NumberOfPages * EFI_PAGE_SIZE);
+	}
+}
+
+void
+efi_fdt_bootargs(const char *bootargs)
+{
+	fdt_setprop_string(fdt_data, fdt_path_offset(fdt_data, FDT_CHOSEN_NODE_PATH), "bootargs", bootargs);
+}
Index: src/sys/stand/efiboot/efifdt.h
diff -u /dev/null src/sys/stand/efiboot/efifdt.h:1.1
--- /dev/null	Fri Aug 24 02:01:07 2018
+++ src/sys/stand/efiboot/efifdt.h	Fri Aug 24 02:01:06 2018
@@ -0,0 +1,33 @@
+/* $NetBSD: efifdt.h,v 1.1 2018/08/24 02:01:06 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2018 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.
+ */
+
+int efi_fdt_probe(void);
+void efi_fdt_memory_map(void);
+void *efi_fdt_data(void);
+int efi_fdt_size(void);
+void efi_fdt_bootargs(const char *);
Index: src/sys/stand/efiboot/efifile.c
diff -u /dev/null src/sys/stand/efiboot/efifile.c:1.1
--- /dev/null	Fri Aug 24 02:01:07 2018
+++ src/sys/stand/efiboot/efifile.c	Fri Aug 24 02:01:06 2018
@@ -0,0 +1,163 @@
+/* $NetBSD: efifile.c,v 1.1 2018/08/24 02:01:06 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2018 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.
+ */
+
+#include <sys/param.h>
+
+#include "efiboot.h"
+#include "efifile.h"
+
+static EFI_HANDLE *efi_vol;
+static UINTN efi_nvol;
+static int efi_bootvol = -1;
+
+static int
+efi_file_parse(const char *fname, UINTN *pvol, const char **pfile)
+{
+	intmax_t vol;
+	char *ep = NULL;
+
+	if (strchr(fname, ':') != NULL) {
+		if (strncasecmp(fname, "fs", 2) != 0)
+			return EINVAL;
+		vol = strtoimax(fname + 2, &ep, 10);
+		if (vol < 0 || vol >= efi_nvol || *ep != ':')
+			return ENXIO;
+		*pvol = vol;
+		*pfile = ep + 1;
+	} else if (efi_bootvol != -1) {
+		*pvol = efi_bootvol;
+		*pfile = fname;
+	} else {
+		return EINVAL;
+	}
+
+	return 0;
+}
+
+void
+efi_file_system_probe(void)
+{
+	EFI_FILE_SYSTEM_INFO *fsi;
+	EFI_FILE_HANDLE fh;
+	EFI_STATUS status;
+	int n;
+
+	status = LibLocateHandle(ByProtocol, &FileSystemProtocol, NULL, &efi_nvol, &efi_vol);
+	if (EFI_ERROR(status))
+		return;
+
+	for (n = 0; n < efi_nvol; n++) {
+		fh = LibOpenRoot(efi_vol[n]);
+		if (!fh)
+			continue;
+
+		fsi = LibFileSystemInfo(fh);
+		if (!fsi)
+			continue;
+
+		if (efi_bootdp && LibMatchDevicePaths(DevicePathFromHandle(efi_vol[n]), efi_bootdp) == TRUE)
+			efi_bootvol = n;
+	}
+}
+
+int
+efi_file_open(struct open_file *f, ...)
+{
+	EFI_DEVICE_PATH *dp;
+	SIMPLE_READ_FILE srf;
+	EFI_HANDLE device, file;
+	EFI_STATUS status;
+	UINTN vol;
+	const char *fname, *path;
+	CHAR16 *upath;
+	va_list ap;
+	size_t len;
+	int rv;
+
+	va_start(ap, f);
+	fname = va_arg(ap, const char *);
+	va_end(ap);
+
+	rv = efi_file_parse(fname, &vol, &path);
+	if (rv != 0)
+		return rv;
+
+	device = efi_vol[vol];
+
+	upath = NULL;
+	rv = utf8_to_ucs2(path, &upath, &len);
+	if (rv != 0)
+		return rv;
+
+	dp = FileDevicePath(device, upath);
+	FreePool(upath);
+	if (dp == NULL)
+		return EINVAL;
+
+	status = OpenSimpleReadFile(TRUE, NULL, 0, &dp, &file, &srf);
+	FreePool(dp);
+	if (EFI_ERROR(status))
+		return status == EFI_NOT_FOUND ? ENOENT : EIO;
+
+	f->f_dev = &devsw[0];
+	f->f_devdata = f;
+	f->f_fsdata = srf;
+	f->f_flags = F_NODEV | F_READ;
+
+	return 0;
+}
+
+int
+efi_file_close(struct open_file *f)
+{
+	SIMPLE_READ_FILE srf = f->f_fsdata;
+
+	CloseSimpleReadFile(srf);
+
+	return 0;
+}
+
+int
+efi_file_strategy(void *devdata, int rw, daddr_t dblk, size_t size, void *buf, size_t *rsize)
+{
+	struct open_file *f = devdata;
+	SIMPLE_READ_FILE srf = f->f_fsdata;
+	EFI_STATUS status;
+	UINTN len;
+
+	if (rw != F_READ)
+		return EROFS;
+
+	len = size;
+	status = ReadSimpleReadFile(srf, f->f_offset, &len, buf);
+	if (EFI_ERROR(status))
+		return EIO;
+	*rsize = len;
+
+	return 0;
+}
Index: src/sys/stand/efiboot/efifile.h
diff -u /dev/null src/sys/stand/efiboot/efifile.h:1.1
--- /dev/null	Fri Aug 24 02:01:07 2018
+++ src/sys/stand/efiboot/efifile.h	Fri Aug 24 02:01:06 2018
@@ -0,0 +1,33 @@
+/* $NetBSD: efifile.h,v 1.1 2018/08/24 02:01:06 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2018 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.
+ */
+
+void efi_file_system_probe(void);
+
+int efi_file_open(struct open_file *, ...);
+int efi_file_close(struct open_file *);
+int efi_file_strategy(void *, int, daddr_t, size_t, void *, size_t *);
Index: src/sys/stand/efiboot/efigetsecs.c
diff -u /dev/null src/sys/stand/efiboot/efigetsecs.c:1.1
--- /dev/null	Fri Aug 24 02:01:07 2018
+++ src/sys/stand/efiboot/efigetsecs.c	Fri Aug 24 02:01:06 2018
@@ -0,0 +1,52 @@
+/*	$NetBSD: efigetsecs.c,v 1.1 2018/08/24 02:01:06 jmcneill Exp $	*/
+
+/*
+ * Copyright (c) 2015 YASUOKA Masahiko <yasu...@yasuoka.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "efiboot.h"
+
+#include <lib/libsa/net.h>
+
+satime_t
+getsecs(void)
+{
+	static const int daytab[][14] = {
+	    { 0, -1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364 },
+	    { 0, -1, 30, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
+	};
+	EFI_TIME t;
+	satime_t r;
+	int y;
+#define isleap(_y) (((_y) % 4) == 0 && (((_y) % 100) != 0 || ((_y) % 400) == 0))
+
+	uefi_call_wrapper(RT->GetTime, 2, &t, NULL);
+
+	/* Calc days from UNIX epoch */
+	r = (t.Year - 1970) * 365;
+	for (y = 1970; y < t.Year; y++) {
+		if (isleap(y))
+			r++;
+	}
+	r += daytab[isleap(t.Year) ? 1 : 0][t.Month] + t.Day;
+
+	/* Calc secs */
+	r *= 60 * 60 * 24;
+	r += ((t.Hour * 60) + t.Minute) * 60 + t.Second;
+	if (-24 * 60 < t.TimeZone && t.TimeZone < 24 * 60)
+		r += t.TimeZone * 60;
+
+	return r;
+}
Index: src/sys/stand/efiboot/exec.c
diff -u /dev/null src/sys/stand/efiboot/exec.c:1.1
--- /dev/null	Fri Aug 24 02:01:07 2018
+++ src/sys/stand/efiboot/exec.c	Fri Aug 24 02:01:06 2018
@@ -0,0 +1,91 @@
+/* $NetBSD: exec.c,v 1.1 2018/08/24 02:01:06 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2018 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.
+ */
+
+#include "efiboot.h"
+#include "efifdt.h"
+
+#include <loadfile.h>
+
+int
+exec_netbsd(const char *fname, const char *args)
+{
+	EFI_PHYSICAL_ADDRESS addr;
+	u_long marks[MARK_MAX], alloc_size;
+	EFI_STATUS status;
+	int fd;
+
+	memset(marks, 0, sizeof(marks));
+	fd = loadfile(fname, marks, COUNT_KERNEL | LOAD_NOTE);
+	if (fd < 0) {
+		printf("boot: %s: %s\n", fname, strerror(errno));
+		return EIO;
+	}
+	close(fd);
+	marks[MARK_END] = (((u_long) marks[MARK_END] + sizeof(int) - 1)) & (-sizeof(int));
+	alloc_size = marks[MARK_END] - marks[MARK_START] + EFIBOOT_ALIGN;
+
+#ifdef EFIBOOT_ALLOCATE_MAX_ADDRESS
+	addr = EFIBOOT_ALLOCATE_MAX_ADDRESS;
+	status = uefi_call_wrapper(BS->AllocatePages, 4, AllocateMaxAddress, EfiLoaderData,
+	    EFI_SIZE_TO_PAGES(alloc_size), &addr);
+#else
+	addr = 0;
+	status = uefi_call_wrapper(BS->AllocatePages, 4, AllocateAnyPages, EfiLoaderData,
+	    EFI_SIZE_TO_PAGES(alloc_size), &addr);
+#endif
+	if (EFI_ERROR(status)) {
+		printf("Failed to allocate %lu bytes for kernel image (error %lu)\n",
+		    alloc_size, status);
+		return ENOMEM;
+	}
+
+	memset(marks, 0, sizeof(marks));
+	marks[MARK_START] = (addr + EFIBOOT_ALIGN) & ~(EFIBOOT_ALIGN - 1);
+	fd = loadfile(fname, marks, LOAD_KERNEL);
+	if (fd < 0) {
+		printf("boot: %s: %s\n", fname, strerror(errno));
+		goto cleanup;
+	}
+	close(fd);
+
+	if (efi_fdt_size() > 0) {
+		if (args && *args)
+			efi_fdt_bootargs(args);
+		efi_fdt_memory_map();	
+	}
+
+	efi_cleanup();
+	efi_boot_kernel(marks);
+
+	/* This should not happen.. */
+	printf("boot returned\n");
+
+cleanup:
+	uefi_call_wrapper(BS->FreePages, 2, addr, EFI_SIZE_TO_PAGES(alloc_size));
+	return EIO;
+}
Index: src/sys/stand/efiboot/panic.c
diff -u /dev/null src/sys/stand/efiboot/panic.c:1.1
--- /dev/null	Fri Aug 24 02:01:07 2018
+++ src/sys/stand/efiboot/panic.c	Fri Aug 24 02:01:06 2018
@@ -0,0 +1,46 @@
+/*	$NetBSD: panic.c,v 1.1 2018/08/24 02:01:06 jmcneill Exp $	*/
+
+/*-
+ * Copyright (c) 2016 Kimihiro Nonaka <non...@netbsd.org>
+ * 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.
+ */
+
+#include "efiboot.h"
+
+__dead void
+reboot(void)
+{
+
+	uefi_call_wrapper(RT->ResetSystem, 4, EfiResetCold, EFI_SUCCESS,
+	    0, NULL);
+	for (;;)
+		continue;
+}
+
+__dead void
+_rtt(void)
+{
+
+	reboot();
+}
Index: src/sys/stand/efiboot/prompt.c
diff -u /dev/null src/sys/stand/efiboot/prompt.c:1.1
--- /dev/null	Fri Aug 24 02:01:07 2018
+++ src/sys/stand/efiboot/prompt.c	Fri Aug 24 02:01:06 2018
@@ -0,0 +1,152 @@
+/*	$NetBSD: prompt.c,v 1.1 2018/08/24 02:01:06 jmcneill Exp $	*/
+
+/*
+ * Copyright (c) 1996, 1997
+ * 	Matthias Drochner.  All rights reserved.
+ * Copyright (c) 1996, 1997
+ * 	Perry E. Metzger.  All rights reserved.
+ * Copyright (c) 1997
+ *	Jason R. Thorpe.  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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgements:
+ *	This product includes software developed for the NetBSD Project
+ *	by Matthias Drochner.
+ *	This product includes software developed for the NetBSD Project
+ *	by Perry E. Metzger.
+ * 4. The names of the authors may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 <lib/libsa/net.h>
+
+#define	POLL_FREQ	10
+
+char *
+gettrailer(char *arg)
+{
+	char *options;
+
+	for (options = arg; *options; options++) {
+		switch (*options) {
+		case ' ':
+		case '\t':
+			*options++ = '\0';
+			break;
+		default:
+			continue;
+		}
+		break;
+	}
+	if (*options == '\0')
+		return options;
+
+	/* trim leading blanks/tabs */
+	while (*options == ' ' || *options == '\t')
+		options++;
+
+	return options;
+}
+
+char
+awaitkey(int timeout, int tell)
+{
+	int i = timeout * POLL_FREQ;
+	char c = 0;
+
+	for (;;) {
+		if (tell) {
+			char buf[32];
+			int len;
+
+			len = snprintf(buf, sizeof(buf), "%d seconds. ", i / POLL_FREQ);
+			if (len > 0 && len < sizeof(buf)) {
+				char *p = buf;
+				printf("%s", buf);
+				while (*p)
+					*p++ = '\b';
+				printf("%s", buf);
+			}
+		}
+		if (ischar()) {
+			while (ischar())
+				c = getchar();
+			if (c == 0)
+				c = -1;
+			goto out;
+		}
+		if (--i > 0) {
+			efi_delay(1000000 / POLL_FREQ);
+		} else {
+			break;
+		}
+	}
+
+out:
+	if (tell)
+		printf("0 seconds.     \n");
+
+	return c;
+}
+
+void
+docommand(char *arg)
+{
+	char *options;
+	int i;
+
+	options = gettrailer(arg);
+
+	for (i = 0; commands[i].c_name != NULL; i++) {
+		if (strcmp(arg, commands[i].c_name) == 0) {
+			(*commands[i].c_fn)(options);
+			return;
+		}
+	}
+
+	printf("unknown command\n");
+	command_help(NULL);
+}
+
+__dead void
+bootprompt(void)
+{
+	char input[80];
+
+	for (;;) {
+		char *c = input;
+
+		input[0] = '\0';
+		printf("> ");
+		kgets(input, sizeof(input));
+
+		/*
+		 * Skip leading whitespace.
+		 */
+		while (*c == ' ')
+			c++;
+		if (*c)
+			docommand(c);
+	}
+}
Index: src/sys/stand/efiboot/version
diff -u /dev/null src/sys/stand/efiboot/version:1.1
--- /dev/null	Fri Aug 24 02:01:07 2018
+++ src/sys/stand/efiboot/version	Fri Aug 24 02:01:06 2018
@@ -0,0 +1,7 @@
+$NetBSD: version,v 1.1 2018/08/24 02:01:06 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
+is taken as the current.
+
+1.0:	Initial version.

Index: src/sys/stand/efiboot/bootaa64/Makefile
diff -u /dev/null src/sys/stand/efiboot/bootaa64/Makefile:1.1
--- /dev/null	Fri Aug 24 02:01:07 2018
+++ src/sys/stand/efiboot/bootaa64/Makefile	Fri Aug 24 02:01:06 2018
@@ -0,0 +1,14 @@
+# $NetBSD: Makefile,v 1.1 2018/08/24 02:01:06 jmcneill Exp $
+
+PROG=		bootaa64.efi
+OBJFMT=		binary
+NEWVERSWHAT=	"EFI Boot (aarch64)"
+
+EXTRA_SOURCES=	efibootaa64.c
+EXTRA_SOURCES+=	cache.S
+
+COPTS+=		-mgeneral-regs-only -fno-jump-tables
+CFLAGS+=	-DEFIBOOT_ALIGN=0x200000
+
+.include "${.CURDIR}/../Makefile.efiboot"
+
Index: src/sys/stand/efiboot/bootaa64/cache.S
diff -u /dev/null src/sys/stand/efiboot/bootaa64/cache.S:1.1
--- /dev/null	Fri Aug 24 02:01:07 2018
+++ src/sys/stand/efiboot/bootaa64/cache.S	Fri Aug 24 02:01:06 2018
@@ -0,0 +1,98 @@
+/*	$NetBSD: cache.S,v 1.1 2018/08/24 02:01:06 jmcneill Exp $	*/
+
+/*-
+ * Copyright (c) 2014 Robin Randhawa
+ * Copyright (c) 2015 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Portions of this software were developed by Andrew Turner
+ * under sponsorship from the FreeBSD Foundation
+ *
+ * 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 AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD: head/sys/arm64/arm64/cpufunc_asm.S 313347 2017-02-06 17:50:09Z andrew $
+ */
+
+#include <aarch64/asm.h>
+
+	.text
+	.align	2
+
+/*
+ * Macro to handle the cache. This takes the start address in x0, length
+ * in x1. It will corrupt x0, x1, x2, and x3.
+ */
+.macro cache_handle_range dcop = 0, ic = 0, icop = 0
+.if \ic == 0
+	mrs	x3, ctr_el0
+	ubfx	x3, x3, #16, #4		/* x3 = D cache shift */
+	mov	x2, #4			/* size of word */
+	lsl	x3, x2, x3		/* x3 = D cache line size */
+.else
+	mrs	x3, ctr_el0
+	ubfx	x2, x3, #16, #4		/* x2 = D cache shift */
+	and	x3, x3, #15		/* x3 = I cache shift */
+	cmp	x3, x2
+	bcs	1f
+	mov	x3, x2
+1:					/* x3 = MAX(IcacheShift,DcacheShift) */
+	mov	x2, #4			/* size of word */
+	lsl	x3, x2, x3		/* x3 = cache line size */
+.endif
+	sub	x4, x3, #1		/* Get the address mask */
+	and	x2, x0, x4		/* Get the low bits of the address */
+	add	x1, x1, x2		/* Add these to the size */
+	bic	x0, x0, x4		/* Clear the low bit of the address */
+1:
+	dc	\dcop, x0
+	dsb	ish
+.if \ic != 0
+	ic	\icop, x0
+	dsb	ish
+.endif
+	add	x0, x0, x3		/* Move to the next line */
+	subs	x1, x1, x3		/* Reduce the size */
+	b.hi	1b			/* Check if we are done */
+.if \ic != 0
+	isb
+.endif
+	ret
+.endm
+
+
+/*
+ * void aarch64_dcache_wbinv_range(vaddr_t, vsize_t)
+ */
+ENTRY(aarch64_dcache_wbinv_range)
+	cache_handle_range	dcop = civac
+END(aarch64_dcache_wbinv_range)
+
+/*
+ * void aarch64_icache_inv_all(void)
+ */
+ENTRY(aarch64_icache_inv_all)
+	dsb	ish
+	ic	ialluis
+	dsb	ish
+	isb
+	ret
+END(aarch64_icache_inv_all)
Index: src/sys/stand/efiboot/bootaa64/efibootaa64.c
diff -u /dev/null src/sys/stand/efiboot/bootaa64/efibootaa64.c:1.1
--- /dev/null	Fri Aug 24 02:01:07 2018
+++ src/sys/stand/efiboot/bootaa64/efibootaa64.c	Fri Aug 24 02:01:06 2018
@@ -0,0 +1,55 @@
+/*	$NetBSD: efibootaa64.c,v 1.1 2018/08/24 02:01:06 jmcneill Exp $	*/
+
+/*-
+ * Copyright (c) 2016 Kimihiro Nonaka <non...@netbsd.org>
+ * 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.
+ */
+
+#include "../efiboot.h"
+#include "../efifdt.h"
+
+#include <sys/bootblock.h>
+
+#include <loadfile.h>
+
+/* cache.S */
+void aarch64_dcache_wbinv_range(vaddr_t, vsize_t);
+void aarch64_icache_inv_all(void);
+
+void
+efi_boot_kernel(u_long marks[MARK_MAX])
+{
+	void (*kernel_entry)(register_t, register_t, register_t, register_t);
+	u_long kernel_size;
+
+	kernel_entry = (void *)marks[MARK_ENTRY];
+	kernel_size = marks[MARK_END] - marks[MARK_START];
+
+	aarch64_dcache_wbinv_range((u_long)kernel_entry, kernel_size);
+	if (efi_fdt_size() > 0)
+		aarch64_dcache_wbinv_range((u_long)efi_fdt_data(), efi_fdt_size());
+	aarch64_icache_inv_all();
+
+	kernel_entry((register_t)efi_fdt_data(), 0, 0, 0);
+}

Reply via email to