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); +}