Module Name: src Committed By: jmcneill Date: Wed Oct 6 10:13:20 UTC 2021
Modified Files: src/sys/stand/efiboot: Makefile.efiboot boot.c bootmenu.c efiacpi.c efiacpi.h efiboot.c efiboot.h efifdt.c efifdt.h efigetsecs.c efigop.c exec.c src/sys/stand/efiboot/bootaa64: Makefile src/sys/stand/efiboot/bootarm: Makefile src/sys/stand/efiboot/bootriscv64: Makefile Log Message: efiboot: Make FDT support optional on a per-arch basis. To generate a diff of this commit: cvs rdiff -u -r1.23 -r1.24 src/sys/stand/efiboot/Makefile.efiboot cvs rdiff -u -r1.37 -r1.38 src/sys/stand/efiboot/boot.c cvs rdiff -u -r1.2 -r1.3 src/sys/stand/efiboot/bootmenu.c \ src/sys/stand/efiboot/efiacpi.h cvs rdiff -u -r1.10 -r1.11 src/sys/stand/efiboot/efiacpi.c \ src/sys/stand/efiboot/efifdt.h cvs rdiff -u -r1.21 -r1.22 src/sys/stand/efiboot/efiboot.c cvs rdiff -u -r1.17 -r1.18 src/sys/stand/efiboot/efiboot.h cvs rdiff -u -r1.29 -r1.30 src/sys/stand/efiboot/efifdt.c cvs rdiff -u -r1.4 -r1.5 src/sys/stand/efiboot/efigetsecs.c cvs rdiff -u -r1.1 -r1.2 src/sys/stand/efiboot/efigop.c cvs rdiff -u -r1.22 -r1.23 src/sys/stand/efiboot/exec.c cvs rdiff -u -r1.10 -r1.11 src/sys/stand/efiboot/bootaa64/Makefile cvs rdiff -u -r1.6 -r1.7 src/sys/stand/efiboot/bootarm/Makefile cvs rdiff -u -r1.1 -r1.2 src/sys/stand/efiboot/bootriscv64/Makefile Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/stand/efiboot/Makefile.efiboot diff -u src/sys/stand/efiboot/Makefile.efiboot:1.23 src/sys/stand/efiboot/Makefile.efiboot:1.24 --- src/sys/stand/efiboot/Makefile.efiboot:1.23 Tue Sep 28 11:37:45 2021 +++ src/sys/stand/efiboot/Makefile.efiboot Wed Oct 6 10:13:19 2021 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile.efiboot,v 1.23 2021/09/28 11:37:45 jmcneill Exp $ +# $NetBSD: Makefile.efiboot,v 1.24 2021/10/06 10:13:19 jmcneill Exp $ S= ${.CURDIR}/../../.. @@ -22,15 +22,24 @@ AFLAGS.start.S= ${${ACTIVE_CC} == "clang .PATH: ${EFIDIR}/gnuefi SOURCES= crt0-efi-${GNUEFIARCH}.S reloc_${GNUEFIARCH}.c SOURCES+= boot.c bootmenu.c conf.c console.c dev_net.c devopen.c exec.c \ - module.c overlay.c panic.c prompt.c -SOURCES+= efiboot.c efichar.c efidev.c efigetsecs.c efifdt.c \ - efifile.c efiblock.c efinet.c efipxe.c efiacpi.c efirng.c \ + module.c panic.c prompt.c +SOURCES+= efiboot.c efichar.c efidev.c efigetsecs.c \ + efifile.c efiblock.c efinet.c efipxe.c efirng.c \ efiwatchdog.c efigop.c smbios.c +.if ${EFIBOOT_FDT:Uno} == "yes" +CPPFLAGS+= -DEFIBOOT_FDT +SOURCES+= efifdt.c overlay.c .PATH: ${S}/external/bsd/libfdt/dist CPPFLAGS+= -I${S}/external/bsd/libfdt/dist SOURCES+= fdt.c fdt_addresses.c fdt_empty_tree.c fdt_overlay.c SOURCES+= fdt_ro.c fdt_rw.c fdt_strerror.c fdt_sw.c fdt_wip.c +.endif + +.if ${EFIBOOT_ACPI:Uno} == "yes" +CPPFLAGS+= -DEFIBOOT_ACPI +SOURCES+= efiacpi.c +.endif SRCS= ${SOURCES} ${EXTRA_SOURCES} @@ -146,9 +155,9 @@ VERSIONMACHINE=${MACHINE} CLEANFILES+= ${PROG}.so ${PROG}.tmp ${PROG}: ${PROG}.so - ${OBJCOPY} -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel \ + ${OBJCOPY} -j .text -j .sdata -j .data -j .dynamic -j .dynsym \ -j .rela -j .rel.* -j .rela.* -j .rel* -j .rela* \ - -j .reloc -O binary ${PROG}.so ${.TARGET} + -j .reloc ${OBJCOPY_FORMAT} ${PROG}.so ${.TARGET} .include <bsd.prog.mk> Index: src/sys/stand/efiboot/boot.c diff -u src/sys/stand/efiboot/boot.c:1.37 src/sys/stand/efiboot/boot.c:1.38 --- src/sys/stand/efiboot/boot.c:1.37 Tue Sep 28 11:37:45 2021 +++ src/sys/stand/efiboot/boot.c Wed Oct 6 10:13:19 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: boot.c,v 1.37 2021/09/28 11:37:45 jmcneill Exp $ */ +/* $NetBSD: boot.c,v 1.38 2021/10/06 10:13:19 jmcneill Exp $ */ /*- * Copyright (c) 2016 Kimihiro Nonaka <non...@netbsd.org> @@ -30,13 +30,19 @@ #include "efiboot.h" #include "efiblock.h" #include "efifile.h" -#include "efifdt.h" -#include "efiacpi.h" #include "efirng.h" #include "module.h" -#include "overlay.h" #include "bootmenu.h" +#ifdef EFIBOOT_FDT +#include "efifdt.h" +#include "overlay.h" +#endif + +#ifdef EFIBOOT_ACPI +#include "efiacpi.h" +#endif + #include <sys/bootblock.h> #include <sys/boot_flag.h> #include <machine/limits.h> @@ -90,11 +96,13 @@ int set_bootargs(const char *); void command_boot(char *); void command_dev(char *); -void command_dtb(char *); void command_initrd(char *); void command_rndseed(char *); +#ifdef EFIBOOT_FDT +void command_dtb(char *); void command_dtoverlay(char *); void command_dtoverlays(char *); +#endif void command_modules(char *); void command_load(char *); void command_unload(char *); @@ -109,12 +117,14 @@ void command_quit(char *); const struct boot_command commands[] = { { "boot", command_boot, "boot [dev:][filename] [args]\n (ex. \"hd0a:\\netbsd.old -s\"" }, { "dev", command_dev, "dev" }, +#ifdef EFIBOOT_FDT { "dtb", command_dtb, "dtb [dev:][filename]" }, + { "dtoverlay", command_dtoverlay, "dtoverlay [dev:][filename]" }, + { "dtoverlays", command_dtoverlays, "dtoverlays [{on|off|reset}]" }, +#endif { "initrd", command_initrd, "initrd [dev:][filename]" }, { "fs", command_initrd, NULL }, { "rndseed", command_rndseed, "rndseed [dev:][filename]" }, - { "dtoverlay", command_dtoverlay, "dtoverlay [dev:][filename]" }, - { "dtoverlays", command_dtoverlays, "dtoverlays [{on|off|reset}]" }, { "modules", command_modules, "modules [{on|off|reset}]" }, { "load", command_load, "load <module_name>" }, { "unload", command_unload, "unload <module_name>" }, @@ -196,12 +206,6 @@ command_dev(char *arg) } void -command_dtb(char *arg) -{ - set_dtb_path(arg); -} - -void command_initrd(char *arg) { set_initrd_path(arg); @@ -213,6 +217,13 @@ command_rndseed(char *arg) set_rndseed_path(arg); } +#ifdef EFIBOOT_FDT +void +command_dtb(char *arg) +{ + set_dtb_path(arg); +} + void command_dtoverlays(char *arg) { @@ -243,6 +254,7 @@ command_dtoverlay(char *arg) dtoverlay_add(arg); } +#endif void command_modules(char *arg) @@ -359,8 +371,12 @@ command_version(char *arg) printf("Config path: %s\n", pathbuf); } +#ifdef EFIBOOT_FDT efi_fdt_show(); +#endif +#ifdef EFIBOOT_ACPI efi_acpi_show(); +#endif efi_rng_show(); efi_md_show(); efi_gop_show(); Index: src/sys/stand/efiboot/bootmenu.c diff -u src/sys/stand/efiboot/bootmenu.c:1.2 src/sys/stand/efiboot/bootmenu.c:1.3 --- src/sys/stand/efiboot/bootmenu.c:1.2 Fri Jun 26 03:23:04 2020 +++ src/sys/stand/efiboot/bootmenu.c Wed Oct 6 10:13:19 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: bootmenu.c,v 1.2 2020/06/26 03:23:04 thorpej Exp $ */ +/* $NetBSD: bootmenu.c,v 1.3 2021/10/06 10:13:19 jmcneill Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -64,8 +64,10 @@ do_bootcfg_command(const char *cmd, char else if (strcmp(cmd, BOOTCFG_CMD_USERCONF) == 0) userconf_add(arg); #endif +#ifdef EFIBOOT_FDT else if (strcmp(cmd, "dtoverlay") == 0) dtoverlay_add(arg); +#endif } int Index: src/sys/stand/efiboot/efiacpi.h diff -u src/sys/stand/efiboot/efiacpi.h:1.2 src/sys/stand/efiboot/efiacpi.h:1.3 --- src/sys/stand/efiboot/efiacpi.h:1.2 Fri May 21 21:53:15 2021 +++ src/sys/stand/efiboot/efiacpi.h Wed Oct 6 10:13:19 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: efiacpi.h,v 1.2 2021/05/21 21:53:15 jmcneill Exp $ */ +/* $NetBSD: efiacpi.h,v 1.3 2021/10/06 10:13:19 jmcneill Exp $ */ /*- * Copyright (c) 2018 The NetBSD Foundation, Inc. @@ -29,9 +29,16 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#if !defined(EFIBOOT_ACPI) +#error ACPI support not enabled +#endif + int efi_acpi_probe(void); void efi_acpi_show(void); int efi_acpi_available(void); int efi_acpi_enabled(void); void efi_acpi_enable(int); int efi_acpi_create_fdt(void); +const char *efi_acpi_get_model(void); +void *efi_acpi_root(void); +void *efi_acpi_smbios(void); Index: src/sys/stand/efiboot/efiacpi.c diff -u src/sys/stand/efiboot/efiacpi.c:1.10 src/sys/stand/efiboot/efiacpi.c:1.11 --- src/sys/stand/efiboot/efiacpi.c:1.10 Fri Jul 23 21:33:00 2021 +++ src/sys/stand/efiboot/efiacpi.c Wed Oct 6 10:13:19 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: efiacpi.c,v 1.10 2021/07/23 21:33:00 jmcneill Exp $ */ +/* $NetBSD: efiacpi.c,v 1.11 2021/10/06 10:13:19 jmcneill Exp $ */ /*- * Copyright (c) 2018 The NetBSD Foundation, Inc. @@ -31,7 +31,6 @@ #include "efiboot.h" #include "efiacpi.h" -#include "efifdt.h" #include "smbios.h" struct acpi_rdsp { @@ -46,10 +45,6 @@ struct acpi_rdsp { uint8_t reserved[3]; }; -#include <libfdt.h> - -#define ACPI_FDT_SIZE (128 * 1024) - static EFI_GUID Acpi20TableGuid = ACPI_20_TABLE_GUID; static EFI_GUID Smbios3TableGuid = SMBIOS3_TABLE_GUID; static EFI_GUID SmbiosTableGuid = SMBIOS_TABLE_GUID; @@ -96,9 +91,21 @@ efi_acpi_enable(int enable) acpi_enable = enable; } +void * +efi_acpi_root(void) +{ + return acpi_root; +} + +void * +efi_acpi_smbios(void) +{ + return smbios_table; +} + static char model_buf[128]; -static const char * +const char * efi_acpi_get_model(void) { struct smbtable smbios; @@ -144,38 +151,3 @@ efi_acpi_show(void) if (smbios_table) printf("SMBIOS: %s\n", efi_acpi_get_model()); } - -int -efi_acpi_create_fdt(void) -{ - int error; - void *fdt; - - if (acpi_root == NULL) - return EINVAL; - - fdt = AllocatePool(ACPI_FDT_SIZE); - if (fdt == NULL) - return ENOMEM; - - error = fdt_create_empty_tree(fdt, ACPI_FDT_SIZE); - if (error) - return EIO; - - const char *model = efi_acpi_get_model(); - - fdt_setprop_string(fdt, fdt_path_offset(fdt, "/"), "compatible", "netbsd,generic-acpi"); - fdt_setprop_string(fdt, fdt_path_offset(fdt, "/"), "model", model); - fdt_setprop_cell(fdt, fdt_path_offset(fdt, "/"), "#address-cells", 2); - fdt_setprop_cell(fdt, fdt_path_offset(fdt, "/"), "#size-cells", 2); - - fdt_add_subnode(fdt, fdt_path_offset(fdt, "/"), "chosen"); - fdt_setprop_u64(fdt, fdt_path_offset(fdt, "/chosen"), "netbsd,acpi-root-table", (uint64_t)(uintptr_t)acpi_root); - if (smbios_table) - fdt_setprop_u64(fdt, fdt_path_offset(fdt, "/chosen"), "netbsd,smbios-table", (uint64_t)(uintptr_t)smbios_table); - - fdt_add_subnode(fdt, fdt_path_offset(fdt, "/"), "acpi"); - fdt_setprop_string(fdt, fdt_path_offset(fdt, "/acpi"), "compatible", "netbsd,acpi"); - - return efi_fdt_set_data(fdt); -} Index: src/sys/stand/efiboot/efifdt.h diff -u src/sys/stand/efiboot/efifdt.h:1.10 src/sys/stand/efiboot/efifdt.h:1.11 --- src/sys/stand/efiboot/efifdt.h:1.10 Sat Oct 10 19:17:39 2020 +++ src/sys/stand/efiboot/efifdt.h Wed Oct 6 10:13:19 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: efifdt.h,v 1.10 2020/10/10 19:17:39 jmcneill Exp $ */ +/* $NetBSD: efifdt.h,v 1.11 2021/10/06 10:13:19 jmcneill Exp $ */ /*- * Copyright (c) 2018 Jared McNeill <jmcne...@invisible.ca> @@ -26,6 +26,10 @@ * SUCH DAMAGE. */ +#if !defined(EFIBOOT_FDT) +#error FDT support not enabled +#endif + int efi_fdt_probe(void); void efi_fdt_memory_map(void); void efi_fdt_gop(void); Index: src/sys/stand/efiboot/efiboot.c diff -u src/sys/stand/efiboot/efiboot.c:1.21 src/sys/stand/efiboot/efiboot.c:1.22 --- src/sys/stand/efiboot/efiboot.c:1.21 Tue Sep 28 11:37:45 2021 +++ src/sys/stand/efiboot/efiboot.c Wed Oct 6 10:13:19 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: efiboot.c,v 1.21 2021/09/28 11:37:45 jmcneill Exp $ */ +/* $NetBSD: efiboot.c,v 1.22 2021/10/06 10:13:19 jmcneill Exp $ */ /*- * Copyright (c) 2018 Jared McNeill <jmcne...@invisible.ca> @@ -29,14 +29,18 @@ #include "efiboot.h" #include "efifile.h" #include "efiblock.h" +#include "efirng.h" + +#ifdef EFIBOOT_FDT #include "efifdt.h" +#endif + +#ifdef EFIBOOT_ACPI #include "efiacpi.h" -#include "efirng.h" +#endif #include <sys/reboot.h> -#include <libfdt.h> - EFI_HANDLE IH; EFI_DEVICE_PATH *efi_bootdp; EFI_LOADED_IMAGE *efi_li; @@ -91,8 +95,12 @@ efi_main(EFI_HANDLE imageHandle, EFI_SYS Print(L"Image file : %s\n", DevicePathToStr(efi_li->FilePath)); #endif +#ifdef EFIBOOT_ACPI efi_acpi_probe(); +#endif +#ifdef EFIBOOT_FDT efi_fdt_probe(); +#endif efi_pxe_probe(); efi_net_probe(); efi_file_system_probe(); @@ -105,78 +113,6 @@ efi_main(EFI_HANDLE imageHandle, EFI_SYS return EFI_SUCCESS; } -#ifdef EFIBOOT_RUNTIME_ADDRESS -static uint64_t -efi_runtime_alloc_va(uint64_t npages) -{ - static uint64_t va = EFIBOOT_RUNTIME_ADDRESS; - static uint64_t sz = EFIBOOT_RUNTIME_SIZE; - uint64_t nva; - - if (sz < (npages * EFI_PAGE_SIZE)) - panic("efi_acpi_alloc_va: couldn't allocate %" PRIu64 " pages", npages); - - nva = va; - va += (npages * EFI_PAGE_SIZE); - sz -= (npages * EFI_PAGE_SIZE); - - return nva; -} -#endif - -#ifdef EFIBOOT_RUNTIME_ADDRESS -static void -efi_set_virtual_address_map(EFI_MEMORY_DESCRIPTOR *memmap, UINTN nentries, UINTN mapkey, UINTN descsize, UINT32 descver) -{ - EFI_MEMORY_DESCRIPTOR *md, *vmd, *vmemmap; - EFI_STATUS status; - int n, nrt; - void *fdt; - - fdt = efi_fdt_data(); - - vmemmap = alloc(nentries * descsize); - if (vmemmap == NULL) - panic("FATAL: couldn't allocate virtual memory map"); - - for (n = 0, nrt = 0, vmd = vmemmap, md = memmap; n < nentries; n++, md = NextMemoryDescriptor(md, descsize)) { - if ((md->Attribute & EFI_MEMORY_RUNTIME) == 0) - continue; - md->VirtualStart = efi_runtime_alloc_va(md->NumberOfPages); - - switch (md->Type) { - case EfiRuntimeServicesCode: - fdt_appendprop_u64(fdt, fdt_path_offset(fdt, "/chosen"), "netbsd,uefi-runtime-code", md->PhysicalStart); - fdt_appendprop_u64(fdt, fdt_path_offset(fdt, "/chosen"), "netbsd,uefi-runtime-code", md->VirtualStart); - fdt_appendprop_u64(fdt, fdt_path_offset(fdt, "/chosen"), "netbsd,uefi-runtime-code", md->NumberOfPages * EFI_PAGE_SIZE); - break; - case EfiRuntimeServicesData: - fdt_appendprop_u64(fdt, fdt_path_offset(fdt, "/chosen"), "netbsd,uefi-runtime-data", md->PhysicalStart); - fdt_appendprop_u64(fdt, fdt_path_offset(fdt, "/chosen"), "netbsd,uefi-runtime-data", md->VirtualStart); - fdt_appendprop_u64(fdt, fdt_path_offset(fdt, "/chosen"), "netbsd,uefi-runtime-data", md->NumberOfPages * EFI_PAGE_SIZE); - break; - case EfiMemoryMappedIO: - fdt_appendprop_u64(fdt, fdt_path_offset(fdt, "/chosen"), "netbsd,uefi-runtime-mmio", md->PhysicalStart); - fdt_appendprop_u64(fdt, fdt_path_offset(fdt, "/chosen"), "netbsd,uefi-runtime-mmio", md->VirtualStart); - fdt_appendprop_u64(fdt, fdt_path_offset(fdt, "/chosen"), "netbsd,uefi-runtime-mmio", md->NumberOfPages * EFI_PAGE_SIZE); - break; - default: - break; - } - - *vmd = *md; - vmd = NextMemoryDescriptor(vmd, descsize); - ++nrt; - } - - status = uefi_call_wrapper(RT->SetVirtualAddressMap, 4, nrt * descsize, descsize, descver, vmemmap); - if (EFI_ERROR(status)) { - printf("WARNING: SetVirtualAddressMap failed\n"); - return; - } -} -#endif - void efi_cleanup(void) { @@ -194,7 +130,7 @@ efi_cleanup(void) } #ifdef EFIBOOT_RUNTIME_ADDRESS - efi_set_virtual_address_map(memmap, nentries, mapkey, descsize, descver); + arch_set_virtual_address_map(memmap, nentries, mapkey, descsize, descver); #endif } Index: src/sys/stand/efiboot/efiboot.h diff -u src/sys/stand/efiboot/efiboot.h:1.17 src/sys/stand/efiboot/efiboot.h:1.18 --- src/sys/stand/efiboot/efiboot.h:1.17 Tue Sep 28 11:37:45 2021 +++ src/sys/stand/efiboot/efiboot.h Wed Oct 6 10:13:19 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: efiboot.h,v 1.17 2021/09/28 11:37:45 jmcneill Exp $ */ +/* $NetBSD: efiboot.h,v 1.18 2021/10/06 10:13:19 jmcneill Exp $ */ /*- * Copyright (c) 2016 Kimihiro Nonaka <non...@netbsd.org> @@ -43,6 +43,11 @@ struct boot_command { const char *c_help; }; +int arch_prepare_boot(const char *, const char *, u_long *); +void arch_cleanup_boot(void); +size_t arch_alloc_size(void); +void arch_set_virtual_address_map(EFI_MEMORY_DESCRIPTOR *, UINTN, UINTN, UINTN, UINT32); + /* conf.c */ extern struct fs_ops null_fs_ops; extern struct fs_ops tftp_fs_ops; @@ -75,6 +80,7 @@ void efi_cleanup(void); void efi_exit(void); void efi_delay(int); void efi_reboot(void); +void efi_progress(const char *, ...); extern int howto; /* efichar.c */ @@ -113,6 +119,7 @@ void efi_gop_dump(void); void efi_gop_setmode(UINT32); /* exec.c */ +int load_file(const char *, u_long, bool, EFI_PHYSICAL_ADDRESS *, u_long *); int exec_netbsd(const char *, const char *); /* panic.c */ Index: src/sys/stand/efiboot/efifdt.c diff -u src/sys/stand/efiboot/efifdt.c:1.29 src/sys/stand/efiboot/efifdt.c:1.30 --- src/sys/stand/efiboot/efifdt.c:1.29 Fri May 21 21:53:15 2021 +++ src/sys/stand/efiboot/efifdt.c Wed Oct 6 10:13:19 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: efifdt.c,v 1.29 2021/05/21 21:53:15 jmcneill Exp $ */ +/* $NetBSD: efifdt.c,v 1.30 2021/10/06 10:13:19 jmcneill Exp $ */ /*- * Copyright (c) 2019 Jason R. Thorpe @@ -30,7 +30,12 @@ #include "efiboot.h" #include "efifdt.h" #include "efiblock.h" +#include "overlay.h" +#include "module.h" + +#ifdef EFIBOOT_ACPI #include "efiacpi.h" +#endif #include <libfdt.h> @@ -48,6 +53,9 @@ static EFI_GUID FdtTableGuid = FDT_TABLE (_md)->Type == EfiBootServicesCode || (_md)->Type == EfiBootServicesData || \ (_md)->Type == EfiConventionalMemory) +#define FDT_SPACE (4 * 1024 * 1024) +#define FDT_ALIGN (2 * 1024 * 1024) + #ifdef _LP64 #define PRIdUINTN "ld" #define PRIxUINTN "lx" @@ -58,6 +66,18 @@ static EFI_GUID FdtTableGuid = FDT_TABLE static void *fdt_data = NULL; static size_t fdt_data_size = 512*1024; +static EFI_PHYSICAL_ADDRESS initrd_addr, dtb_addr, rndseed_addr; +static u_long initrd_size = 0, dtb_size = 0, rndseed_size = 0; + +/* exec.c */ +extern EFI_PHYSICAL_ADDRESS efirng_addr; +extern u_long efirng_size; + +#ifdef EFIBOOT_ACPI +#define ACPI_FDT_SIZE (128 * 1024) +static int efi_fdt_create_acpifdt(void); +#endif + int efi_fdt_probe(void) { @@ -435,18 +455,16 @@ efi_fdt_initrd(u_long initrd_addr, u_lon /* pass in the NetBSD on-disk random seed */ void -efi_fdt_rndseed(u_long rndseed_addr, u_long rndseed_size) +efi_fdt_rndseed(u_long addr, u_long size) { int chosen; - if (rndseed_size == 0) + if (size == 0) return; chosen = efi_fdt_chosen(); - fdt_setprop_u64(fdt_data, chosen, "netbsd,rndseed-start", - rndseed_addr); - fdt_setprop_u64(fdt_data, chosen, "netbsd,rndseed-end", - rndseed_addr + rndseed_size); + fdt_setprop_u64(fdt_data, chosen, "netbsd,rndseed-start", addr); + fdt_setprop_u64(fdt_data, chosen, "netbsd,rndseed-end", addr + size); } /* pass in output from the EFI firmware's RNG from some unknown source */ @@ -479,3 +497,294 @@ efi_fdt_module(const char *module_name, fdt_appendprop_u64(fdt_data, chosen, "netbsd,modules", module_addr); fdt_appendprop_u64(fdt_data, chosen, "netbsd,modules", module_size); } + +static void +apply_overlay(const char *path, void *dtbo) +{ + + if (!efi_fdt_overlay_is_compatible(dtbo)) { + printf("boot: %s: incompatible overlay\n", path); + return; + } + + int fdterr; + + if (efi_fdt_overlay_apply(dtbo, &fdterr) != 0) { + printf("boot: %s: error %d applying overlay\n", path, fdterr); + } +} + +static void +apply_overlay_file(const char *path) +{ + EFI_PHYSICAL_ADDRESS dtbo_addr; + u_long dtbo_size; + + if (strlen(path) == 0) + return; + + if (load_file(path, 0, false, &dtbo_addr, &dtbo_size) != 0 || + dtbo_addr == 0) { + /* Error messages have already been displayed. */ + goto out; + } + + apply_overlay(path, (void *)(uintptr_t)dtbo_addr); + +out: + if (dtbo_addr) { + uefi_call_wrapper(BS->FreePages, 2, dtbo_addr, + EFI_SIZE_TO_PAGES(dtbo_size)); + } +} + +static void +load_fdt_overlays(void) +{ + if (!dtoverlay_enabled) + return; + + dtoverlay_foreach(apply_overlay_file); +} + +static void +load_module(const char *module_name) +{ + EFI_PHYSICAL_ADDRESS addr; + u_long size; + char path[PATH_MAX]; + + snprintf(path, sizeof(path), "%s/%s/%s.kmod", module_prefix, + module_name, module_name); + + if (load_file(path, 0, false, &addr, &size) != 0 || addr == 0 || size == 0) + return; + + efi_fdt_module(module_name, (u_long)addr, size); +} + +static void +load_modules(const char *kernel_name) +{ + if (!module_enabled) + return; + + module_init(kernel_name); + module_foreach(load_module); +} + + +/* + * Prepare kernel arguments and shutdown boot services. + */ +int +arch_prepare_boot(const char *fname, const char *args, u_long *marks) +{ + load_file(get_initrd_path(), 0, false, &initrd_addr, &initrd_size); + load_file(get_dtb_path(), 0, false, &dtb_addr, &dtb_size); + +#ifdef EFIBOOT_ACPI + /* ACPI support only works for little endian kernels */ + efi_acpi_enable(netbsd_elf_data == ELFDATA2LSB); + + if (efi_acpi_available() && efi_acpi_enabled()) { + int error = efi_fdt_create_acpifdt(); + if (error != 0) { + return error; + } + } else +#endif + if (dtb_addr && efi_fdt_set_data((void *)(uintptr_t)dtb_addr) != 0) { + printf("boot: invalid DTB data\n"); + return EINVAL; + } + + if (efi_fdt_size() > 0) { + /* + * Load the rndseed as late as possible -- after we + * have committed to using fdt and executing this + * kernel -- so that it doesn't hang around in memory + * if we have to bail or the kernel won't use it. + */ + load_file(get_rndseed_path(), 0, false, + &rndseed_addr, &rndseed_size); + + efi_fdt_init((marks[MARK_END] + FDT_ALIGN - 1) & -FDT_ALIGN, FDT_ALIGN); + load_modules(fname); + load_fdt_overlays(); + efi_fdt_initrd(initrd_addr, initrd_size); + efi_fdt_rndseed(rndseed_addr, rndseed_size); + efi_fdt_efirng(efirng_addr, efirng_size); + efi_fdt_bootargs(args); + efi_fdt_system_table(); + efi_fdt_gop(); + efi_fdt_memory_map(); + } + + efi_cleanup(); + + if (efi_fdt_size() > 0) { + efi_fdt_fini(); + } + + return 0; +} + +/* + * Free memory after a failed boot. + */ +void +arch_cleanup_boot(void) +{ + if (rndseed_addr) { + uefi_call_wrapper(BS->FreePages, 2, rndseed_addr, EFI_SIZE_TO_PAGES(rndseed_size)); + rndseed_addr = 0; + rndseed_size = 0; + } + if (initrd_addr) { + uefi_call_wrapper(BS->FreePages, 2, initrd_addr, EFI_SIZE_TO_PAGES(initrd_size)); + initrd_addr = 0; + initrd_size = 0; + } + if (dtb_addr) { + uefi_call_wrapper(BS->FreePages, 2, dtb_addr, EFI_SIZE_TO_PAGES(dtb_size)); + dtb_addr = 0; + dtb_size = 0; + } +} + +size_t +arch_alloc_size(void) +{ + return FDT_SPACE; +} + +#ifdef EFIBOOT_ACPI +int +efi_fdt_create_acpifdt(void) +{ + void *acpi_root = efi_acpi_root(); + void *smbios_table = efi_acpi_smbios(); + void *fdt; + int error; + + if (acpi_root == NULL) + return EINVAL; + + fdt = AllocatePool(ACPI_FDT_SIZE); + if (fdt == NULL) + return ENOMEM; + + error = fdt_create_empty_tree(fdt, ACPI_FDT_SIZE); + if (error) + return EIO; + + const char *model = efi_acpi_get_model(); + + fdt_setprop_string(fdt, fdt_path_offset(fdt, "/"), "compatible", "netbsd,generic-acpi"); + fdt_setprop_string(fdt, fdt_path_offset(fdt, "/"), "model", model); + fdt_setprop_cell(fdt, fdt_path_offset(fdt, "/"), "#address-cells", 2); + fdt_setprop_cell(fdt, fdt_path_offset(fdt, "/"), "#size-cells", 2); + + fdt_add_subnode(fdt, fdt_path_offset(fdt, "/"), "chosen"); + fdt_setprop_u64(fdt, fdt_path_offset(fdt, "/chosen"), "netbsd,acpi-root-table", (uint64_t)(uintptr_t)acpi_root); + if (smbios_table) + fdt_setprop_u64(fdt, fdt_path_offset(fdt, "/chosen"), "netbsd,smbios-table", (uint64_t)(uintptr_t)smbios_table); + + fdt_add_subnode(fdt, fdt_path_offset(fdt, "/"), "acpi"); + fdt_setprop_string(fdt, fdt_path_offset(fdt, "/acpi"), "compatible", "netbsd,acpi"); + + return efi_fdt_set_data(fdt); +} +#endif + +#ifdef EFIBOOT_RUNTIME_ADDRESS +static uint64_t +efi_fdt_runtime_alloc_va(uint64_t npages) +{ + static uint64_t va = EFIBOOT_RUNTIME_ADDRESS; + static uint64_t sz = EFIBOOT_RUNTIME_SIZE; + uint64_t nva; + + if (sz < (npages * EFI_PAGE_SIZE)) { + panic("efi_acpi_alloc_va: couldn't allocate %" PRIu64 " pages", + npages); + } + + nva = va; + va += (npages * EFI_PAGE_SIZE); + sz -= (npages * EFI_PAGE_SIZE); + + return nva; +} + +void +arch_set_virtual_address_map(EFI_MEMORY_DESCRIPTOR *memmap, UINTN nentries, + UINTN mapkey, UINTN descsize, UINT32 descver) +{ + EFI_MEMORY_DESCRIPTOR *md, *vmd, *vmemmap; + EFI_STATUS status; + int n, nrt; + void *fdt; + + fdt = efi_fdt_data(); + + vmemmap = alloc(nentries * descsize); + if (vmemmap == NULL) + panic("FATAL: couldn't allocate virtual memory map"); + + for (n = 0, nrt = 0, vmd = vmemmap, md = memmap; + n < nentries; + n++, md = NextMemoryDescriptor(md, descsize)) { + + if ((md->Attribute & EFI_MEMORY_RUNTIME) == 0) { + continue; + } + + md->VirtualStart = efi_fdt_runtime_alloc_va(md->NumberOfPages); + + switch (md->Type) { + case EfiRuntimeServicesCode: + fdt_appendprop_u64(fdt, fdt_path_offset(fdt, "/chosen"), + "netbsd,uefi-runtime-code", md->PhysicalStart); + fdt_appendprop_u64(fdt, fdt_path_offset(fdt, "/chosen"), + "netbsd,uefi-runtime-code", md->VirtualStart); + fdt_appendprop_u64(fdt, fdt_path_offset(fdt, "/chosen"), + "netbsd,uefi-runtime-code", + md->NumberOfPages * EFI_PAGE_SIZE); + break; + case EfiRuntimeServicesData: + fdt_appendprop_u64(fdt, fdt_path_offset(fdt, "/chosen"), + "netbsd,uefi-runtime-data", md->PhysicalStart); + fdt_appendprop_u64(fdt, fdt_path_offset(fdt, "/chosen"), + "netbsd,uefi-runtime-data", md->VirtualStart); + fdt_appendprop_u64(fdt, fdt_path_offset(fdt, "/chosen"), + "netbsd,uefi-runtime-data", + md->NumberOfPages * EFI_PAGE_SIZE); + break; + case EfiMemoryMappedIO: + fdt_appendprop_u64(fdt, fdt_path_offset(fdt, "/chosen"), + "netbsd,uefi-runtime-mmio", md->PhysicalStart); + fdt_appendprop_u64(fdt, fdt_path_offset(fdt, "/chosen"), + "netbsd,uefi-runtime-mmio", md->VirtualStart); + fdt_appendprop_u64(fdt, fdt_path_offset(fdt, "/chosen"), + "netbsd,uefi-runtime-mmio", + md->NumberOfPages * EFI_PAGE_SIZE); + break; + default: + break; + } + + *vmd = *md; + vmd = NextMemoryDescriptor(vmd, descsize); + ++nrt; + } + + status = uefi_call_wrapper(RT->SetVirtualAddressMap, 4, nrt * descsize, + descsize, descver, vmemmap); + if (EFI_ERROR(status)) { + printf("WARNING: SetVirtualAddressMap failed\n"); + return; + } +} +#endif Index: src/sys/stand/efiboot/efigetsecs.c diff -u src/sys/stand/efiboot/efigetsecs.c:1.4 src/sys/stand/efiboot/efigetsecs.c:1.5 --- src/sys/stand/efiboot/efigetsecs.c:1.4 Sat Mar 30 12:47:53 2019 +++ src/sys/stand/efiboot/efigetsecs.c Wed Oct 6 10:13:19 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: efigetsecs.c,v 1.4 2019/03/30 12:47:53 jmcneill Exp $ */ +/* $NetBSD: efigetsecs.c,v 1.5 2021/10/06 10:13:19 jmcneill Exp $ */ /* * Copyright (c) 2015 YASUOKA Masahiko <yasu...@yasuoka.net> @@ -55,7 +55,7 @@ getsecs_rtc(void) return r; } -static void +static EFIAPI void getsecs_notify_func(EFI_EVENT ev, VOID *context) { getsecs_val++; Index: src/sys/stand/efiboot/efigop.c diff -u src/sys/stand/efiboot/efigop.c:1.1 src/sys/stand/efiboot/efigop.c:1.2 --- src/sys/stand/efiboot/efigop.c:1.1 Tue Sep 28 11:38:07 2021 +++ src/sys/stand/efiboot/efigop.c Wed Oct 6 10:13:19 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: efigop.c,v 1.1 2021/09/28 11:38:07 jmcneill Exp $ */ +/* $NetBSD: efigop.c,v 1.2 2021/10/06 10:13:19 jmcneill Exp $ */ /*- * Copyright (c) 2021 Jared McNeill <jmcne...@invisible.ca> @@ -28,8 +28,6 @@ #include "efiboot.h" -#include <libfdt.h> - static EFI_GRAPHICS_OUTPUT_PROTOCOL *gop = NULL; void Index: src/sys/stand/efiboot/exec.c diff -u src/sys/stand/efiboot/exec.c:1.22 src/sys/stand/efiboot/exec.c:1.23 --- src/sys/stand/efiboot/exec.c:1.22 Sun Jun 20 19:07:39 2021 +++ src/sys/stand/efiboot/exec.c Wed Oct 6 10:13:19 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: exec.c,v 1.22 2021/06/20 19:07:39 jmcneill Exp $ */ +/* $NetBSD: exec.c,v 1.23 2021/10/06 10:13:19 jmcneill Exp $ */ /*- * Copyright (c) 2019 Jason R. Thorpe @@ -28,11 +28,14 @@ */ #include "efiboot.h" +#ifdef EFIBOOT_FDT #include "efifdt.h" +#endif +#ifdef EFIBOOT_ACPI #include "efiacpi.h" +#endif #include "efirng.h" #include "module.h" -#include "overlay.h" #include <sys/param.h> #include <sys/reboot.h> @@ -41,13 +44,10 @@ extern char twiddle_toggle; u_long load_offset = 0; -#define FDT_SPACE (4 * 1024 * 1024) -#define FDT_ALIGN (2 * 1024 * 1024) - -static EFI_PHYSICAL_ADDRESS initrd_addr, dtb_addr, rndseed_addr, efirng_addr; -static u_long initrd_size = 0, dtb_size = 0, rndseed_size = 0, efirng_size = 0; +EFI_PHYSICAL_ADDRESS efirng_addr; +u_long efirng_size = 0; -static int +int load_file(const char *path, u_long extra, bool quiet_errors, EFI_PHYSICAL_ADDRESS *paddr, u_long *psize) { @@ -123,81 +123,6 @@ load_file(const char *path, u_long extra } static void -apply_overlay(const char *path, void *dtbo) -{ - - if (!efi_fdt_overlay_is_compatible(dtbo)) { - printf("boot: %s: incompatible overlay\n", path); - return; - } - - int fdterr; - - if (efi_fdt_overlay_apply(dtbo, &fdterr) != 0) { - printf("boot: %s: error %d applying overlay\n", path, fdterr); - } -} - -static void -apply_overlay_file(const char *path) -{ - EFI_PHYSICAL_ADDRESS dtbo_addr; - u_long dtbo_size; - - if (strlen(path) == 0) - return; - - if (load_file(path, 0, false, &dtbo_addr, &dtbo_size) != 0 || - dtbo_addr == 0) { - /* Error messages have already been displayed. */ - goto out; - } - - apply_overlay(path, (void *)(uintptr_t)dtbo_addr); - -out: - if (dtbo_addr) { - uefi_call_wrapper(BS->FreePages, 2, dtbo_addr, - EFI_SIZE_TO_PAGES(dtbo_size)); - } -} - -static void -load_fdt_overlays(void) -{ - if (!dtoverlay_enabled) - return; - - dtoverlay_foreach(apply_overlay_file); -} - -static void -load_module(const char *module_name) -{ - EFI_PHYSICAL_ADDRESS addr; - u_long size; - char path[PATH_MAX]; - - snprintf(path, sizeof(path), "%s/%s/%s.kmod", module_prefix, - module_name, module_name); - - if (load_file(path, 0, false, &addr, &size) != 0 || addr == 0 || size == 0) - return; - - efi_fdt_module(module_name, (u_long)addr, size); -} - -static void -load_modules(const char *kernel_name) -{ - if (!module_enabled) - return; - - module_init(kernel_name); - module_foreach(load_module); -} - -static void generate_efirng(void) { EFI_PHYSICAL_ADDRESS addr; @@ -248,8 +173,6 @@ exec_netbsd(const char *fname, const cha twiddle_toggle = 0; - load_file(get_initrd_path(), 0, false, &initrd_addr, &initrd_size); - load_file(get_dtb_path(), 0, false, &dtb_addr, &dtb_size); generate_efirng(); memset(marks, 0, sizeof(marks)); @@ -263,7 +186,7 @@ exec_netbsd(const char *fname, const cha } close(fd); marks[MARK_END] = (((u_long) marks[MARK_END] + sizeof(int) - 1)) & -sizeof(int); - alloc_size = marks[MARK_END] - marks[MARK_START] + FDT_SPACE + EFIBOOT_ALIGN; + alloc_size = marks[MARK_END] - marks[MARK_START] + arch_alloc_size() + EFIBOOT_ALIGN; #ifdef EFIBOOT_ALLOCATE_MAX_ADDRESS addr = EFIBOOT_ALLOCATE_MAX_ADDRESS; @@ -290,47 +213,10 @@ exec_netbsd(const char *fname, const cha close(fd); load_offset = 0; -#ifdef EFIBOOT_ACPI - /* ACPI support only works for little endian kernels */ - efi_acpi_enable(netbsd_elf_data == ELFDATA2LSB); - - if (efi_acpi_available() && efi_acpi_enabled()) { - efi_acpi_create_fdt(); - } else -#endif - if (dtb_addr && efi_fdt_set_data((void *)(uintptr_t)dtb_addr) != 0) { - printf("boot: invalid DTB data\n"); + if (arch_prepare_boot(fname, args, marks) != 0) { goto cleanup; } - if (efi_fdt_size() > 0) { - /* - * Load the rndseed as late as possible -- after we - * have committed to using fdt and executing this - * kernel -- so that it doesn't hang around in memory - * if we have to bail or the kernel won't use it. - */ - load_file(get_rndseed_path(), 0, false, - &rndseed_addr, &rndseed_size); - - efi_fdt_init((marks[MARK_END] + FDT_ALIGN - 1) & -FDT_ALIGN, FDT_ALIGN); - load_modules(fname); - load_fdt_overlays(); - efi_fdt_initrd(initrd_addr, initrd_size); - efi_fdt_rndseed(rndseed_addr, rndseed_size); - efi_fdt_efirng(efirng_addr, efirng_size); - efi_fdt_bootargs(args); - efi_fdt_system_table(); - efi_fdt_gop(); - efi_fdt_memory_map(); - } - - efi_cleanup(); - - if (efi_fdt_size() > 0) { - efi_fdt_fini(); - } - efi_boot_kernel(marks); /* This should not happen.. */ @@ -338,15 +224,7 @@ exec_netbsd(const char *fname, const cha cleanup: uefi_call_wrapper(BS->FreePages, 2, addr, EFI_SIZE_TO_PAGES(alloc_size)); - if (initrd_addr) { - uefi_call_wrapper(BS->FreePages, 2, initrd_addr, EFI_SIZE_TO_PAGES(initrd_size)); - initrd_addr = 0; - initrd_size = 0; - } - if (dtb_addr) { - uefi_call_wrapper(BS->FreePages, 2, dtb_addr, EFI_SIZE_TO_PAGES(dtb_size)); - dtb_addr = 0; - dtb_size = 0; - } + arch_cleanup_boot(); + return EIO; } Index: src/sys/stand/efiboot/bootaa64/Makefile diff -u src/sys/stand/efiboot/bootaa64/Makefile:1.10 src/sys/stand/efiboot/bootaa64/Makefile:1.11 --- src/sys/stand/efiboot/bootaa64/Makefile:1.10 Thu Sep 10 14:30:14 2020 +++ src/sys/stand/efiboot/bootaa64/Makefile Wed Oct 6 10:13:19 2021 @@ -1,10 +1,14 @@ -# $NetBSD: Makefile,v 1.10 2020/09/10 14:30:14 jakllsch Exp $ +# $NetBSD: Makefile,v 1.11 2021/10/06 10:13:19 jmcneill Exp $ PROG= bootaa64.efi OBJFMT= binary NEWVERSWHAT= "efiboot (arm64)" GNUEFIARCH= aarch64 LIBGNUEFI_ARCH= aarch64 +OBJCOPY_FORMAT= -O binary + +EFIBOOT_ACPI= yes +EFIBOOT_FDT= yes EXTRA_SOURCES= efibootaa64.c EXTRA_SOURCES+= cache.S @@ -14,7 +18,6 @@ AFLAGS+= -mlittle-endian CFLAGS+= -DEFIBOOT_ALIGN=0x200000 CFLAGS+= -DEFIBOOT_RUNTIME_ADDRESS=0xffff800000000000L CFLAGS+= -DEFIBOOT_RUNTIME_SIZE=0x40000000UL -CFLAGS+= -DEFIBOOT_ACPI CFLAGS+= -DEFIBOOT_MODULE_MACHINE=\"evbarm\" LDFLAGS+= -EL Index: src/sys/stand/efiboot/bootarm/Makefile diff -u src/sys/stand/efiboot/bootarm/Makefile:1.6 src/sys/stand/efiboot/bootarm/Makefile:1.7 --- src/sys/stand/efiboot/bootarm/Makefile:1.6 Tue Sep 8 15:36:37 2020 +++ src/sys/stand/efiboot/bootarm/Makefile Wed Oct 6 10:13:20 2021 @@ -1,10 +1,11 @@ -# $NetBSD: Makefile,v 1.6 2020/09/08 15:36:37 jmcneill Exp $ +# $NetBSD: Makefile,v 1.7 2021/10/06 10:13:20 jmcneill Exp $ PROG= bootarm.efi OBJFMT= binary NEWVERSWHAT= "efiboot (arm)" GNUEFIARCH= arm LIBGNUEFI_ARCH= arm +OBJCOPY_FORMAT= -O binary EXTRA_SOURCES= efibootarm.c EXTRA_SOURCES+= cache.S Index: src/sys/stand/efiboot/bootriscv64/Makefile diff -u src/sys/stand/efiboot/bootriscv64/Makefile:1.1 src/sys/stand/efiboot/bootriscv64/Makefile:1.2 --- src/sys/stand/efiboot/bootriscv64/Makefile:1.1 Sun May 2 15:22:27 2021 +++ src/sys/stand/efiboot/bootriscv64/Makefile Wed Oct 6 10:13:20 2021 @@ -1,10 +1,11 @@ -# $NetBSD: Makefile,v 1.1 2021/05/02 15:22:27 jmcneill Exp $ +# $NetBSD: Makefile,v 1.2 2021/10/06 10:13:20 jmcneill Exp $ PROG= bootriscv64.efi OBJFMT= binary NEWVERSWHAT= "efiboot (riscv64)" GNUEFIARCH= riscv64 LIBGNUEFI_ARCH= riscv64 +OBJCOPY_FORMAT= -O binary EXTRA_SOURCES= efibootriscv64.c