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 <[email protected]>
+ * Copyright (c) 2018 Jared McNeill <[email protected]>
+ * 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 <[email protected]>
+ * 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 <[email protected]>
+ * 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 <[email protected]>
+ * 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 <[email protected]>
+ * 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 <[email protected]>
+ * 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 <[email protected]>
+ * 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 <[email protected]>
+ * 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 <[email protected]>
+ * 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 <[email protected]>
+ * 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 <[email protected]>
+ * 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 <[email protected]>
+ * 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 <[email protected]>
+ *
+ * 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 <[email protected]>
+ * 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 <[email protected]>
+ * 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 <[email protected]>
+ * 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);
+}