diff options
Diffstat (limited to 'stand/efi/loader')
42 files changed, 327 insertions, 1311 deletions
diff --git a/stand/efi/loader/Makefile b/stand/efi/loader/Makefile index 1edb5674712e..5a755c1d329f 100644 --- a/stand/efi/loader/Makefile +++ b/stand/efi/loader/Makefile @@ -1,4 +1,3 @@ -# $FreeBSD$ LOADER_NET_SUPPORT?= yes LOADER_MSDOS_SUPPORT?= yes @@ -39,6 +38,8 @@ CFLAGS.bootinfo.c += -I$(SRCTOP)/sys/teken CFLAGS.bootinfo.c += -I${SRCTOP}/contrib/pnglite CFLAGS.framebuffer.c += -I$(SRCTOP)/sys/teken CFLAGS.framebuffer.c += -I${SRCTOP}/contrib/pnglite +CFLAGS.main.c += -I$(SRCTOP)/sys/teken +CFLAGS.main.c += -I${SRCTOP}/contrib/pnglite CFLAGS.gfx_fb.c += -I$(SRCTOP)/sys/teken CFLAGS.gfx_fb.c += -I${SRCTOP}/sys/cddl/contrib/opensolaris/common/lz4 CFLAGS.gfx_fb.c += -I${SRCTOP}/contrib/pnglite @@ -66,6 +67,7 @@ CFLAGS+= -DEFI .if defined(HAVE_FDT) && ${MK_FDT} != "no" .include "${BOOTSRC}/fdt.mk" LIBEFI_FDT= ${BOOTOBJ}/efi/fdt/libefi_fdt.a +HELP_FILES+= ${FDTSRC}/help.fdt .endif # Include bcache code. @@ -81,6 +83,7 @@ CFLAGS+= -DEFI_SECUREBOOT NEWVERSWHAT= "EFI loader" ${MACHINE} VERSION_FILE= ${.CURDIR}/../loader/version +HELP_FILENAME= loader.help.efi # Always add MI sources .include "${BOOTSRC}/loader.mk" @@ -103,10 +106,10 @@ LDFLAGS+= -Wl,-T${LDSCRIPT},-Bsymbolic,-znotext -pie LDFLAGS+= -Wl,--no-dynamic-linker .endif -CLEANFILES+= loader.efi +CLEANFILES+= ${LOADER}.efi ${LOADER}.efi: ${PROG} - if ${NM} ${.ALLSRC} | grep ' U '; then \ + @if ${NM} ${.ALLSRC} | grep ' U '; then \ echo "Undefined symbols in ${.ALLSRC}"; \ exit 1; \ fi @@ -119,7 +122,7 @@ ${LOADER}.efi: ${PROG} LIBEFI= ${BOOTOBJ}/efi/libefi/libefi.a -DPADD= ${LDR_INTERP} ${LIBEFI} ${LIBFDT} ${LIBEFI_FDT} ${LIBSA} ${LDSCRIPT} -LDADD= ${LDR_INTERP} ${LIBEFI} ${LIBFDT} ${LIBEFI_FDT} ${LIBSA} +DPADD= ${LDR_INTERP} ${LIBEFI} ${LIBSAFDT} ${LIBEFI_FDT} ${LIBSA} ${LDSCRIPT} +LDADD= ${LDR_INTERP} ${LIBEFI} ${LIBSAFDT} ${LIBEFI_FDT} ${LIBSA} .include <bsd.prog.mk> diff --git a/stand/efi/loader/Makefile.depend b/stand/efi/loader/Makefile.depend index 06e5b772c214..ae9e6b6efaa4 100644 --- a/stand/efi/loader/Makefile.depend +++ b/stand/efi/loader/Makefile.depend @@ -1,10 +1,10 @@ -# $FreeBSD$ # Autogenerated - do NOT edit! DIRDEPS = \ + bin/sh.host \ stand/efi/libefi \ - stand/ficl \ stand/libsa \ + usr.bin/awk.host \ .include <dirdeps.mk> diff --git a/stand/efi/loader/Makefile.depend.arm b/stand/efi/loader/Makefile.depend.arm new file mode 100644 index 000000000000..4ba1445d8a5f --- /dev/null +++ b/stand/efi/loader/Makefile.depend.arm @@ -0,0 +1,16 @@ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + bin/sh.host \ + stand/efi/fdt \ + stand/efi/libefi \ + stand/fdt \ + stand/libsa \ + usr.bin/awk.host \ + + +.include <dirdeps.mk> + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/stand/efi/loader/Makefile.depend.arm64 b/stand/efi/loader/Makefile.depend.arm64 new file mode 100644 index 000000000000..4ba1445d8a5f --- /dev/null +++ b/stand/efi/loader/Makefile.depend.arm64 @@ -0,0 +1,16 @@ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + bin/sh.host \ + stand/efi/fdt \ + stand/efi/libefi \ + stand/fdt \ + stand/libsa \ + usr.bin/awk.host \ + + +.include <dirdeps.mk> + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/stand/efi/loader/Makefile.depend.options b/stand/efi/loader/Makefile.depend.options new file mode 100644 index 000000000000..20292bab9bcd --- /dev/null +++ b/stand/efi/loader/Makefile.depend.options @@ -0,0 +1,7 @@ +# options that impact our dependencies +DIRDEPS_OPTIONS = LOADER_LUA + +DIRDEPS.LOADER_LUA.yes += \ + stand/liblua \ + +.include <dirdeps-options.mk> diff --git a/stand/efi/loader/Makefile.depend.riscv b/stand/efi/loader/Makefile.depend.riscv new file mode 100644 index 000000000000..4ba1445d8a5f --- /dev/null +++ b/stand/efi/loader/Makefile.depend.riscv @@ -0,0 +1,16 @@ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + bin/sh.host \ + stand/efi/fdt \ + stand/efi/libefi \ + stand/fdt \ + stand/libsa \ + usr.bin/awk.host \ + + +.include <dirdeps.mk> + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/stand/efi/loader/arch/amd64/Makefile.inc b/stand/efi/loader/arch/amd64/Makefile.inc index 0d9e2648cb59..00658b3b8636 100644 --- a/stand/efi/loader/arch/amd64/Makefile.inc +++ b/stand/efi/loader/arch/amd64/Makefile.inc @@ -1,4 +1,3 @@ -# $FreeBSD$ SRCS+= amd64_tramp.S \ start.S \ diff --git a/stand/efi/loader/arch/amd64/amd64_tramp.S b/stand/efi/loader/arch/amd64/amd64_tramp.S index 877705407f92..515ffc5d784d 100644 --- a/stand/efi/loader/arch/amd64/amd64_tramp.S +++ b/stand/efi/loader/arch/amd64/amd64_tramp.S @@ -1,6 +1,5 @@ /*- * Copyright (c) 2013 The FreeBSD Foundation - * All rights reserved. * * This software was developed by Benno Rice under sponsorship from * the FreeBSD Foundation. @@ -24,8 +23,6 @@ * 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$ */ #include <machine/asmacros.h> diff --git a/stand/efi/loader/arch/amd64/elf64_freebsd.c b/stand/efi/loader/arch/amd64/elf64_freebsd.c index 4bdf675cd5a3..5a41ea99867e 100644 --- a/stand/efi/loader/arch/amd64/elf64_freebsd.c +++ b/stand/efi/loader/arch/amd64/elf64_freebsd.c @@ -26,8 +26,6 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #define __ELF_WORD_SIZE 64 #include <sys/param.h> #include <sys/exec.h> @@ -43,17 +41,8 @@ __FBSDID("$FreeBSD$"); #include "bootstrap.h" -#include "platform/acfreebsd.h" -#include "acconfig.h" -#define ACPI_SYSTEM_XFACE -#include "actypes.h" -#include "actbl.h" - #include "loader_efi.h" -static EFI_GUID acpi_guid = ACPI_TABLE_GUID; -static EFI_GUID acpi20_guid = ACPI_20_TABLE_GUID; - extern int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp, bool exit_bs); @@ -106,9 +95,6 @@ elf64_exec(struct preloaded_file *fp) Elf_Ehdr *ehdr; vm_offset_t modulep, kernend, trampcode, trampstack; int err, i; - ACPI_TABLE_RSDP *rsdp; - char buf[24]; - int revision; bool copy_auto; copy_auto = copy_staging == COPY_STAGING_AUTO; @@ -116,50 +102,6 @@ elf64_exec(struct preloaded_file *fp) copy_staging = fp->f_kernphys_relocatable ? COPY_STAGING_DISABLE : COPY_STAGING_ENABLE; - /* - * Report the RSDP to the kernel. While this can be found with - * a BIOS boot, the RSDP may be elsewhere when booted from UEFI. - * The old code used the 'hints' method to communite this to - * the kernel. However, while convenient, the 'hints' method - * is fragile and does not work when static hints are compiled - * into the kernel. Instead, move to setting different tunables - * that start with acpi. The old 'hints' can be removed before - * we branch for FreeBSD 12. - */ - - rsdp = efi_get_table(&acpi20_guid); - if (rsdp == NULL) { - rsdp = efi_get_table(&acpi_guid); - } - if (rsdp != NULL) { - sprintf(buf, "0x%016llx", (unsigned long long)rsdp); - setenv("hint.acpi.0.rsdp", buf, 1); - setenv("acpi.rsdp", buf, 1); - revision = rsdp->Revision; - if (revision == 0) - revision = 1; - sprintf(buf, "%d", revision); - setenv("hint.acpi.0.revision", buf, 1); - setenv("acpi.revision", buf, 1); - strncpy(buf, rsdp->OemId, sizeof(rsdp->OemId)); - buf[sizeof(rsdp->OemId)] = '\0'; - setenv("hint.acpi.0.oem", buf, 1); - setenv("acpi.oem", buf, 1); - sprintf(buf, "0x%016x", rsdp->RsdtPhysicalAddress); - setenv("hint.acpi.0.rsdt", buf, 1); - setenv("acpi.rsdt", buf, 1); - if (revision >= 2) { - /* XXX extended checksum? */ - sprintf(buf, "0x%016llx", - (unsigned long long)rsdp->XsdtPhysicalAddress); - setenv("hint.acpi.0.xsdt", buf, 1); - setenv("acpi.xsdt", buf, 1); - sprintf(buf, "%d", rsdp->Length); - setenv("hint.acpi.0.xsdt_length", buf, 1); - setenv("acpi.xsdt_length", buf, 1); - } - } - if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) return (EFTYPE); ehdr = (Elf_Ehdr *)&(md->md_data); @@ -181,7 +123,7 @@ elf64_exec(struct preloaded_file *fp) trampoline = (void *)trampcode; if (copy_staging == COPY_STAGING_ENABLE) { - PT4 = (pml4_entry_t *)0x0000000040000000; + PT4 = (pml4_entry_t *)0x0000000040000000; /* 1G */ err = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, 3, (EFI_PHYSICAL_ADDRESS *)&PT4); if (EFI_ERROR(err)) { diff --git a/stand/efi/loader/arch/amd64/exc.S b/stand/efi/loader/arch/amd64/exc.S index 0035d4a37e20..940bfa160161 100644 --- a/stand/efi/loader/arch/amd64/exc.S +++ b/stand/efi/loader/arch/amd64/exc.S @@ -1,6 +1,5 @@ /*- * Copyright (c) 2016 The FreeBSD Foundation - * All rights reserved. * * This software was developed by Konstantin Belousov under sponsorship * from the FreeBSD Foundation. @@ -25,8 +24,6 @@ * 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$ */ .macro EH N, err=1 diff --git a/stand/efi/loader/arch/amd64/ldscript.amd64 b/stand/efi/loader/arch/amd64/ldscript.amd64 index 874df9b08f9e..57014aefc025 100644 --- a/stand/efi/loader/arch/amd64/ldscript.amd64 +++ b/stand/efi/loader/arch/amd64/ldscript.amd64 @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ OUTPUT_FORMAT("elf64-x86-64-freebsd", "elf64-x86-64-freebsd", "elf64-x86-64-freebsd") OUTPUT_ARCH(i386:x86-64) ENTRY(_start) diff --git a/stand/efi/loader/arch/amd64/start.S b/stand/efi/loader/arch/amd64/start.S index 774ef4fa7901..34bf166c6501 100644 --- a/stand/efi/loader/arch/amd64/start.S +++ b/stand/efi/loader/arch/amd64/start.S @@ -33,7 +33,6 @@ /* * crt0-efi-x86_64.S - x86_64 EFI startup code. - * $FreeBSD$ */ .text diff --git a/stand/efi/loader/arch/amd64/trap.c b/stand/efi/loader/arch/amd64/trap.c index e8cf188cf22f..56a3ee67da6f 100644 --- a/stand/efi/loader/arch/amd64/trap.c +++ b/stand/efi/loader/arch/amd64/trap.c @@ -1,6 +1,5 @@ /*- * Copyright (c) 2016 The FreeBSD Foundation - * All rights reserved. * * This software was developed by Konstantin Belousov under sponsorship * from the FreeBSD Foundation. @@ -28,8 +27,6 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <string.h> #include <sys/param.h> @@ -79,11 +76,21 @@ static uint32_t loader_tss; /* Loader TSS segment */ static struct region_descriptor fw_gdt; /* Descriptor of pristine GDT */ static EFI_PHYSICAL_ADDRESS loader_gdt_pa; /* Address of loader shadow GDT */ +struct frame { + struct frame *fr_savfp; + uintptr_t fr_savpc; +}; + void report_exc(struct trapframe *tf); void report_exc(struct trapframe *tf) { + struct frame *fp; + uintptr_t pc, base; + char buf[80]; + int ret; + base = (uintptr_t)boot_img->ImageBase; /* * printf() depends on loader runtime and UEFI firmware health * to produce the console output, in case of exception, the @@ -109,6 +116,33 @@ report_exc(struct trapframe *tf) tf->tf_rdi, tf->tf_rsi, tf->tf_rdx, tf->tf_rcx, tf->tf_r8, tf->tf_r9, tf->tf_rax, tf->tf_rbx, tf->tf_rbp, tf->tf_r10, tf->tf_r11, tf->tf_r12, tf->tf_r13, tf->tf_r14, tf->tf_r15); + + fp = (struct frame *)tf->tf_rbp; + pc = tf->tf_rip; + + printf("Stack trace:\n"); + pager_open(); + while (fp != NULL || pc != 0) { + char *source = "PC"; + + if (pc >= base && pc < base + boot_img->ImageSize) { + pc -= base; + source = "loader PC"; + } + (void) snprintf(buf, sizeof (buf), "FP %016lx: %s 0x%016lx\n", + (uintptr_t)fp, source, pc); + if (pager_output(buf)) + break; + + if (fp != NULL) + fp = fp->fr_savfp; + + if (fp != NULL) + pc = fp->fr_savpc; + else + pc = 0; + } + pager_close(); printf("Machine stopped.\n"); } diff --git a/stand/efi/loader/arch/arm/Makefile.inc b/stand/efi/loader/arch/arm/Makefile.inc index 284e517bfbb8..5761c8062117 100644 --- a/stand/efi/loader/arch/arm/Makefile.inc +++ b/stand/efi/loader/arch/arm/Makefile.inc @@ -1,7 +1,5 @@ -# $FreeBSD$ SRCS+= exec.c \ - efiserialio.c \ start.S HAVE_FDT=yes diff --git a/stand/efi/loader/arch/arm/exec.c b/stand/efi/loader/arch/arm/exec.c index a110f3d07cbc..85a8c26ade30 100644 --- a/stand/efi/loader/arch/arm/exec.c +++ b/stand/efi/loader/arch/arm/exec.c @@ -25,9 +25,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <sys/linker.h> @@ -43,7 +40,6 @@ __FBSDID("$FreeBSD$"); #include "bootstrap.h" #include "loader_efi.h" -extern vm_offset_t md_load(char *, vm_offset_t *); extern int bi_load(char *, vm_offset_t *, vm_offset_t *, bool); static int diff --git a/stand/efi/loader/arch/arm/ldscript.arm b/stand/efi/loader/arch/arm/ldscript.arm index 68775a88a9cd..13affe12bbba 100644 --- a/stand/efi/loader/arch/arm/ldscript.arm +++ b/stand/efi/loader/arch/arm/ldscript.arm @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ OUTPUT_ARCH(arm) ENTRY(_start) SECTIONS diff --git a/stand/efi/loader/arch/arm/start.S b/stand/efi/loader/arch/arm/start.S index 5b6182d67d0a..5e4301ec7141 100644 --- a/stand/efi/loader/arch/arm/start.S +++ b/stand/efi/loader/arch/arm/start.S @@ -22,8 +22,6 @@ * 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$ */ #include <machine/asm.h> @@ -140,6 +138,7 @@ section_table: _end_header: .text + .globl _start _start: /* Save the boot params to the stack */ push {r0, r1} diff --git a/stand/efi/loader/arch/arm64/Makefile.inc b/stand/efi/loader/arch/arm64/Makefile.inc index 9978d9c4ea9c..d19a23af0e9e 100644 --- a/stand/efi/loader/arch/arm64/Makefile.inc +++ b/stand/efi/loader/arch/arm64/Makefile.inc @@ -1,9 +1,7 @@ -# $FreeBSD$ HAVE_FDT=yes SRCS+= exec.c \ - efiserialio.c \ start.S .PATH: ${BOOTSRC}/arm64/libarm64 diff --git a/stand/efi/loader/arch/arm64/exec.c b/stand/efi/loader/arch/arm64/exec.c index 6cf4a4fd8e4d..ef410a7d556c 100644 --- a/stand/efi/loader/arch/arm64/exec.c +++ b/stand/efi/loader/arch/arm64/exec.c @@ -25,8 +25,6 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <string.h> @@ -42,16 +40,6 @@ __FBSDID("$FreeBSD$"); #include "loader_efi.h" #include "cache.h" -#include "platform/acfreebsd.h" -#include "acconfig.h" -#define ACPI_SYSTEM_XFACE -#define ACPI_USE_SYSTEM_INTTYPES -#include "actypes.h" -#include "actbl.h" - -static EFI_GUID acpi_guid = ACPI_TABLE_GUID; -static EFI_GUID acpi20_guid = ACPI_20_TABLE_GUID; - static int elf64_exec(struct preloaded_file *amp); static int elf64_obj_exec(struct preloaded_file *amp); @@ -75,39 +63,10 @@ elf64_exec(struct preloaded_file *fp) vm_offset_t clean_addr; size_t clean_size; struct file_metadata *md; - ACPI_TABLE_RSDP *rsdp; Elf_Ehdr *ehdr; - char buf[24]; - int err, revision; + int err; void (*entry)(vm_offset_t); - rsdp = efi_get_table(&acpi20_guid); - if (rsdp == NULL) { - rsdp = efi_get_table(&acpi_guid); - } - if (rsdp != NULL) { - sprintf(buf, "0x%016llx", (unsigned long long)rsdp); - setenv("hint.acpi.0.rsdp", buf, 1); - revision = rsdp->Revision; - if (revision == 0) - revision = 1; - sprintf(buf, "%d", revision); - setenv("hint.acpi.0.revision", buf, 1); - strncpy(buf, rsdp->OemId, sizeof(rsdp->OemId)); - buf[sizeof(rsdp->OemId)] = '\0'; - setenv("hint.acpi.0.oem", buf, 1); - sprintf(buf, "0x%016x", rsdp->RsdtPhysicalAddress); - setenv("hint.acpi.0.rsdt", buf, 1); - if (revision >= 2) { - /* XXX extended checksum? */ - sprintf(buf, "0x%016llx", - (unsigned long long)rsdp->XsdtPhysicalAddress); - setenv("hint.acpi.0.xsdt", buf, 1); - sprintf(buf, "%d", rsdp->Length); - setenv("hint.acpi.0.xsdt_length", buf, 1); - } - } - if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) return(EFTYPE); diff --git a/stand/efi/loader/arch/arm64/ldscript.arm64 b/stand/efi/loader/arch/arm64/ldscript.arm64 index d0ed320a319c..bacb81b5032f 100644 --- a/stand/efi/loader/arch/arm64/ldscript.arm64 +++ b/stand/efi/loader/arch/arm64/ldscript.arm64 @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ /* OUTPUT_FORMAT("elf64-aarch64-freebsd", "elf64-aarch64-freebsd", "elf64-aarch64-freebsd") */ @@ -16,7 +15,9 @@ SECTIONS *(.gnu.warning) *(.plt) } =0xD4200000 - . = ALIGN(16); + . = ALIGN(4096); + _etext = .; + __data_start = .; .data : { *(.rodata .rodata.* .gnu.linkonce.r.*) *(.rodata1) @@ -78,6 +79,7 @@ SECTIONS . = ALIGN(16); .dynsym : { *(.dynsym) } _edata = .; + __data_size = . - __data_start; /* Unused sections */ .interp : { *(.interp) } diff --git a/stand/efi/loader/arch/arm64/start.S b/stand/efi/loader/arch/arm64/start.S index 675d4e153f36..6e30287453c5 100644 --- a/stand/efi/loader/arch/arm64/start.S +++ b/stand/efi/loader/arch/arm64/start.S @@ -22,8 +22,6 @@ * 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$ */ /* @@ -34,11 +32,14 @@ #define IMAGE_FILE_MACHINE_ARM64 0xaa64 +#define IMAGE_FILE_EXECUTABLE 0x0002 + #define IMAGE_SCN_CNT_CODE 0x00000020 #define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 #define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 #define IMAGE_SCN_MEM_EXECUTE 0x20000000 #define IMAGE_SCN_MEM_READ 0x40000000 +#define IMAGE_SCN_MEM_WRITE 0x80000000 .section .peheader,"a" efi_start: @@ -60,22 +61,22 @@ coff_head: .long 0 /* No symbol table */ .long 0 /* No symbols */ .short section_table - optional_header /* Optional header size */ - .short 0 /* Characteristics TODO: Fill in */ + .short IMAGE_FILE_EXECUTABLE /* Characteristics */ optional_header: .short 0x020b /* PE32+ (64-bit addressing) */ .byte 0 /* Major linker version */ .byte 0 /* Minor linker version */ - .long _edata - _end_header /* Code size */ - .long 0 /* No initialized data */ + .long _etext - _end_header /* Code size */ + .long __data_size /* Initialized data size */ .long 0 /* No uninitialized data */ .long _start - efi_start /* Entry point */ .long _end_header - efi_start /* Start of code */ optional_windows_header: .quad 0 /* Image base */ - .long 32 /* Section Alignment */ - .long 8 /* File alignment */ + .long 4096 /* Section Alignment */ + .long 512 /* File alignment */ .short 0 /* Major OS version */ .short 0 /* Minor OS version */ .short 0 /* Major image version */ @@ -104,36 +105,37 @@ optional_windows_header: .quad 0 section_table: - /* We need a .reloc section for EFI */ - .ascii ".reloc" + .ascii ".text" + .byte 0 .byte 0 .byte 0 /* Pad to 8 bytes */ - .long 0 /* Virtual size */ - .long 0 /* Virtual address */ - .long 0 /* Size of raw data */ - .long 0 /* Pointer to raw data */ + .long _etext - _end_header /* Virtual size */ + .long _end_header - efi_start /* Virtual address */ + .long _etext - _end_header /* Size of raw data */ + .long _end_header - efi_start /* Pointer to raw data */ .long 0 /* Pointer to relocations */ .long 0 /* Pointer to line numbers */ .short 0 /* Number of relocations */ .short 0 /* Number of line numbers */ - .long (IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | \ - IMAGE_SCN_MEM_DISCARDABLE) /* Characteristics */ + .long (IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | \ + IMAGE_SCN_MEM_READ) /* Characteristics */ - /* The contents of the loader */ - .ascii ".text" + .ascii ".data" .byte 0 .byte 0 .byte 0 /* Pad to 8 bytes */ - .long _edata - _end_header /* Virtual size */ - .long _end_header - efi_start /* Virtual address */ - .long _edata - _end_header /* Size of raw data */ - .long _end_header - efi_start /* Pointer to raw data */ + .long __data_size /* Virtual size */ + .long __data_start - efi_start /* Virtual address */ + .long __data_size /* Size of raw data */ + .long __data_start - efi_start /* Pointer to raw data */ .long 0 /* Pointer to relocations */ .long 0 /* Pointer to line numbers */ .short 0 /* Number of relocations */ .short 0 /* Number of line numbers */ - .long (IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | \ - IMAGE_SCN_MEM_READ) /* Characteristics */ + .long (IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | \ + IMAGE_SCN_MEM_WRITE) /* Characteristics */ + + .align 12 _end_header: .text diff --git a/stand/efi/loader/arch/i386/Makefile.inc b/stand/efi/loader/arch/i386/Makefile.inc deleted file mode 100644 index fcdb6324b2f0..000000000000 --- a/stand/efi/loader/arch/i386/Makefile.inc +++ /dev/null @@ -1,13 +0,0 @@ -# $FreeBSD$ - -SRCS+= start.S \ - elf32_freebsd.c \ - exec.c - -.PATH: ${BOOTSRC}/i386/libi386 -SRCS+= nullconsole.c \ - comconsole.c \ - spinconsole.c - -CFLAGS+= -fPIC -LDFLAGS+= -Wl,-znocombreloc diff --git a/stand/efi/loader/arch/i386/elf32_freebsd.c b/stand/efi/loader/arch/i386/elf32_freebsd.c deleted file mode 100644 index 97d114f09610..000000000000 --- a/stand/efi/loader/arch/i386/elf32_freebsd.c +++ /dev/null @@ -1,103 +0,0 @@ -/*- - * Copyright (c) 1998 Michael Smith <msmith@freebsd.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 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> -__FBSDID("$FreeBSD$"); - -#include <sys/param.h> -#include <sys/exec.h> -#include <sys/linker.h> -#include <string.h> -#include <machine/bootinfo.h> -#include <machine/elf.h> -#include <stand.h> - -#include <efi.h> -#include <efilib.h> - -#include "bootstrap.h" -#include "../libi386/libi386.h" -#include "../btx/lib/btxv86.h" - -extern void __exec(caddr_t addr, ...); -extern int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp, - bool exit_bs); - -static int elf32_exec(struct preloaded_file *amp); -static int elf32_obj_exec(struct preloaded_file *amp); - -struct file_format i386_elf = { elf32_loadfile, elf32_exec }; -struct file_format i386_elf_obj = { elf32_obj_loadfile, elf32_obj_exec }; - -struct file_format *file_formats[] = { - &i386_elf, - &i386_elf_obj, - NULL -}; - -/* - * There is an ELF kernel and one or more ELF modules loaded. - * We wish to start executing the kernel image, so make such - * preparations as are required, and do so. - */ -static int -elf32_exec(struct preloaded_file *fp) -{ - struct file_metadata *md; - Elf_Ehdr *ehdr; - vm_offset_t entry, bootinfop, modulep, kernend; - int boothowto, err, bootdev; - - if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) - return(EFTYPE); - ehdr = (Elf_Ehdr *)&(md->md_data); - - efi_time_fini(); - - entry = ehdr->e_entry & 0xffffff; - - printf("Start @ 0x%x ...\n", entry); - - err = bi_load(fp->f_args, &modulep, &kernend, true); - if (err != 0) { - efi_time_init(); - return(err); - } - - /* At this point we've called ExitBootServices, so we can't call - * printf or any other function that uses Boot Services */ - - dev_cleanup(); - __exec((void *)entry, boothowto, bootdev, 0, 0, 0, bootinfop, modulep, kernend); - - panic("exec returned"); -} - -static int -elf32_obj_exec(struct preloaded_file *fp) -{ - return (EFTYPE); -} diff --git a/stand/efi/loader/arch/i386/exec.c b/stand/efi/loader/arch/i386/exec.c deleted file mode 100644 index 579f5593b24b..000000000000 --- a/stand/efi/loader/arch/i386/exec.c +++ /dev/null @@ -1,49 +0,0 @@ -/*- - * Copyright (c) 2010 Rui Paulo <rpaulo@FreeBSD.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 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 <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <stand.h> -#include <machine/elf.h> -#include "../btx/lib/btxv86.h" - -#include "../../common/bootstrap.h" - -uint32_t __base; -struct __v86 __v86; - -void -__v86int() -{ - printf("%s\n", __func__); - exit(1); -} - -void -__exec(caddr_t addr, ...) -{ -} diff --git a/stand/efi/loader/arch/i386/i386_copy.c b/stand/efi/loader/arch/i386/i386_copy.c deleted file mode 100644 index 2c4b0deb49cf..000000000000 --- a/stand/efi/loader/arch/i386/i386_copy.c +++ /dev/null @@ -1,58 +0,0 @@ -/*- - * Copyright (c) 1998 Michael Smith <msmith@freebsd.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 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> -__FBSDID("$FreeBSD$"); - -/* - * MD primitives supporting placement of module data - * - * XXX should check load address/size against memory top. - */ -#include <stand.h> - -#include "libi386.h" -#include "btxv86.h" - -ssize_t -i386_copyin(const void *src, vm_offset_t dest, const size_t len) -{ - bcopy(src, PTOV(dest), len); - return(len); -} - -ssize_t -i386_copyout(const vm_offset_t src, void *dest, const size_t len) -{ - bcopy(PTOV(src), dest, len); - return(len); -} - -ssize_t -i386_readin(readin_handle_t fd, vm_offset_t dest, const size_t len) -{ - return (VECTX_READ(fd, PTOV(dest), len)); -} diff --git a/stand/efi/loader/arch/i386/ldscript.i386 b/stand/efi/loader/arch/i386/ldscript.i386 deleted file mode 100644 index e17212a1bddd..000000000000 --- a/stand/efi/loader/arch/i386/ldscript.i386 +++ /dev/null @@ -1,77 +0,0 @@ -/* $FreeBSD$ */ -OUTPUT_FORMAT("elf32-i386-freebsd", "elf32-i386-freebsd", "elf32-i386-freebsd") -OUTPUT_ARCH(i386) -ENTRY(_start) -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - . = 0; - ImageBase = .; - . = SIZEOF_HEADERS; - . = ALIGN(4096); - .text : { - *(.text .stub .text.* .gnu.linkonce.t.*) - /* .gnu.warning sections are handled specially by elf32.em. */ - *(.gnu.warning) - *(.plt) - } =0xCCCCCCCC - . = ALIGN(4096); - .data : { - *(.rodata .rodata.* .gnu.linkonce.r.*) - *(.rodata1) - *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) - *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) - *(.opd) - *(.data .data.* .gnu.linkonce.d.*) - *(.data1) - *(.plabel) - *(.dynbss) - *(.bss .bss.* .gnu.linkonce.b.*) - *(COMMON) - } - . = ALIGN(4096); - set_Xcommand_set : { - __start_set_Xcommand_set = .; - *(set_Xcommand_set) - __stop_set_Xcommand_set = .; - } - set_Xficl_compile_set : { - __start_set_Xficl_compile_set = .; - *(set_Xficl_compile_set) - __stop_set_Xficl_compile_set = .; - } - . = ALIGN(4096); - __gp = .; - .sdata : { - *(.got.plt .got) - *(.sdata .sdata.* .gnu.linkonce.s.*) - *(dynsbss) - *(.sbss .sbss.* .gnu.linkonce.sb.*) - *(.scommon) - } - . = ALIGN(4096); - .dynamic : { *(.dynamic) } - . = ALIGN(4096); - .rel.dyn : { - *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) - *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) - *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) - *(.rel.got) - *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) - *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) - *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) - *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) - *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) - *(.rel.plt) - *(.relset_*) - *(.rel.dyn .rel.dyn.*) - } - . = ALIGN(4096); - .reloc : { *(.reloc) } - . = ALIGN(4096); - .hash : { *(.hash) } - . = ALIGN(4096); - .dynsym : { *(.dynsym) } - . = ALIGN(4096); - .dynstr : { *(.dynstr) } -} diff --git a/stand/efi/loader/arch/i386/start.S b/stand/efi/loader/arch/i386/start.S deleted file mode 100644 index b597f419d4a1..000000000000 --- a/stand/efi/loader/arch/i386/start.S +++ /dev/null @@ -1,68 +0,0 @@ -/*- - * Copyright (c) 2008-2010 Rui Paulo <rpaulo@FreeBSD.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 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$ - */ - - .text - -#include <machine/asm.h> - -#define EFI_SUCCESS 0 - -/* - * EFI entry point. - * _start(EFI_IMAGE image_handle, EFI_SYSTEM_TABLE *system_table); - * - * We calculate the base address along with _DYNAMIC, relocate us and finally - * pass control to efi_main. - */ - -ENTRY(_start) - pushl %ebp - movl %esp, %ebp - - pushl 12(%ebp) /* image_handle */ - pushl 8(%ebp) /* system_table */ - call 0f -0: popl %eax - movl %eax, %ebx - addl $ImageBase-0b, %eax - addl $_DYNAMIC-0b, %ebx - pushl %ebx /* dynamic */ - pushl %eax /* ImageBase */ - call self_reloc - popl %ebx /* remove ImageBase from the stack */ - popl %ebx /* remove dynamic from the stack */ - call efi_main -1: leave - ret -END(_start) - - .data - .section .reloc, "a" - .long 0 - .long 10 - .word 0 diff --git a/stand/efi/loader/arch/riscv/Makefile.inc b/stand/efi/loader/arch/riscv/Makefile.inc index 333b789e935d..c25f63c0b3b7 100644 --- a/stand/efi/loader/arch/riscv/Makefile.inc +++ b/stand/efi/loader/arch/riscv/Makefile.inc @@ -1,7 +1,5 @@ -# $FreeBSD$ HAVE_FDT=yes SRCS+= exec.c \ - efiserialio.c \ start.S diff --git a/stand/efi/loader/arch/riscv/exec.c b/stand/efi/loader/arch/riscv/exec.c index c7d90a4f31d0..3c40517ea968 100644 --- a/stand/efi/loader/arch/riscv/exec.c +++ b/stand/efi/loader/arch/riscv/exec.c @@ -25,9 +25,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <sys/linker.h> diff --git a/stand/efi/loader/arch/riscv/ldscript.riscv b/stand/efi/loader/arch/riscv/ldscript.riscv index aa736f0d9b2a..342ec62cf03e 100644 --- a/stand/efi/loader/arch/riscv/ldscript.riscv +++ b/stand/efi/loader/arch/riscv/ldscript.riscv @@ -1,4 +1,3 @@ -/* $FreeBSD$ */ OUTPUT_FORMAT("elf64-littleriscv", "elf64-littleriscv", "elf64-littleriscv") OUTPUT_ARCH(riscv64) ENTRY(_start) diff --git a/stand/efi/loader/arch/riscv/start.S b/stand/efi/loader/arch/riscv/start.S index e63ce68d86ba..fb7d65f17c99 100644 --- a/stand/efi/loader/arch/riscv/start.S +++ b/stand/efi/loader/arch/riscv/start.S @@ -1,5 +1,5 @@ /*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2020 Mitchell Horne <mhorne@FreeBSD.org> * @@ -23,8 +23,6 @@ * 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$ */ #include <machine/asm.h> diff --git a/stand/efi/loader/autoload.c b/stand/efi/loader/autoload.c index d409285834c3..a7a5f8212e9c 100644 --- a/stand/efi/loader/autoload.c +++ b/stand/efi/loader/autoload.c @@ -25,8 +25,6 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #if defined(LOADER_FDT_SUPPORT) #include <sys/param.h> #include <fdt_platform.h> diff --git a/stand/efi/loader/bootinfo.c b/stand/efi/loader/bootinfo.c index c7b682819a98..f47d81e23591 100644 --- a/stand/efi/loader/bootinfo.c +++ b/stand/efi/loader/bootinfo.c @@ -27,8 +27,6 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <string.h> #include <sys/param.h> @@ -40,17 +38,24 @@ __FBSDID("$FreeBSD$"); #include <machine/metadata.h> #include <machine/psl.h> +#ifdef EFI #include <efi.h> #include <efilib.h> +#else +#include "kboot.h" +#endif #include "bootstrap.h" -#include "loader_efi.h" +#include "modinfo.h" #if defined(__amd64__) #include <machine/specialreg.h> #endif +#ifdef EFI +#include "loader_efi.h" #include "gfx_fb.h" +#endif #if defined(LOADER_FDT_SUPPORT) #include <fdt_platform.h> @@ -66,11 +71,14 @@ int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp, static int bi_getboothowto(char *kargs) { +#ifdef EFI const char *sw, *tmp; char *opts; - char *console; - int howto, speed, port; + int speed, port; char buf[50]; +#endif + char *console; + int howto; howto = boot_parse_cmdline(kargs); howto |= boot_env_to_howto(); @@ -81,6 +89,7 @@ bi_getboothowto(char *kargs) howto |= RB_SERIAL; if (strcmp(console, "nullconsole") == 0) howto |= RB_MUTE; +#ifdef EFI #if defined(__i386__) || defined(__amd64__) if (strcmp(console, "efi") == 0 && getenv("efi_8250_uid") != NULL && @@ -108,10 +117,17 @@ bi_getboothowto(char *kargs) if (tmp != NULL) speed = strtol(tmp, NULL, 0); tmp = getenv("efi_com_port"); - if (tmp == NULL) - tmp = getenv("comconsole_port"); if (tmp != NULL) port = strtol(tmp, NULL, 0); + if (port <= 0) { + tmp = getenv("comconsole_port"); + if (tmp != NULL) + port = strtol(tmp, NULL, 0); + else { + if (port == 0) + port = 0x3f8; + } + } if (speed != -1 && port != -1) { snprintf(buf, sizeof(buf), "io:%d,br:%d", port, speed); @@ -120,139 +136,13 @@ bi_getboothowto(char *kargs) } } #endif +#endif } return (howto); } -/* - * Copy the environment into the load area starting at (addr). - * Each variable is formatted as <name>=<value>, with a single nul - * separating each variable, and a double nul terminating the environment. - */ -static vm_offset_t -bi_copyenv(vm_offset_t start) -{ - struct env_var *ep; - vm_offset_t addr, last; - size_t len; - - addr = last = start; - - /* Traverse the environment. */ - for (ep = environ; ep != NULL; ep = ep->ev_next) { - len = strlen(ep->ev_name); - if ((size_t)archsw.arch_copyin(ep->ev_name, addr, len) != len) - break; - addr += len; - if (archsw.arch_copyin("=", addr, 1) != 1) - break; - addr++; - if (ep->ev_value != NULL) { - len = strlen(ep->ev_value); - if ((size_t)archsw.arch_copyin(ep->ev_value, addr, len) != len) - break; - addr += len; - } - if (archsw.arch_copyin("", addr, 1) != 1) - break; - last = ++addr; - } - - if (archsw.arch_copyin("", last++, 1) != 1) - last = start; - return(last); -} - -/* - * Copy module-related data into the load area, where it can be - * used as a directory for loaded modules. - * - * Module data is presented in a self-describing format. Each datum - * is preceded by a 32-bit identifier and a 32-bit size field. - * - * Currently, the following data are saved: - * - * MOD_NAME (variable) module name (string) - * MOD_TYPE (variable) module type (string) - * MOD_ARGS (variable) module parameters (string) - * MOD_ADDR sizeof(vm_offset_t) module load address - * MOD_SIZE sizeof(size_t) module size - * MOD_METADATA (variable) type-specific metadata - */ -#define COPY32(v, a, c) { \ - uint32_t x = (v); \ - if (c) \ - archsw.arch_copyin(&x, a, sizeof(x)); \ - a += sizeof(x); \ -} - -#define MOD_STR(t, a, s, c) { \ - COPY32(t, a, c); \ - COPY32(strlen(s) + 1, a, c); \ - if (c) \ - archsw.arch_copyin(s, a, strlen(s) + 1); \ - a += roundup(strlen(s) + 1, sizeof(u_long)); \ -} - -#define MOD_NAME(a, s, c) MOD_STR(MODINFO_NAME, a, s, c) -#define MOD_TYPE(a, s, c) MOD_STR(MODINFO_TYPE, a, s, c) -#define MOD_ARGS(a, s, c) MOD_STR(MODINFO_ARGS, a, s, c) - -#define MOD_VAR(t, a, s, c) { \ - COPY32(t, a, c); \ - COPY32(sizeof(s), a, c); \ - if (c) \ - archsw.arch_copyin(&s, a, sizeof(s)); \ - a += roundup(sizeof(s), sizeof(u_long)); \ -} - -#define MOD_ADDR(a, s, c) MOD_VAR(MODINFO_ADDR, a, s, c) -#define MOD_SIZE(a, s, c) MOD_VAR(MODINFO_SIZE, a, s, c) - -#define MOD_METADATA(a, mm, c) { \ - COPY32(MODINFO_METADATA | mm->md_type, a, c); \ - COPY32(mm->md_size, a, c); \ - if (c) \ - archsw.arch_copyin(mm->md_data, a, mm->md_size); \ - a += roundup(mm->md_size, sizeof(u_long)); \ -} - -#define MOD_END(a, c) { \ - COPY32(MODINFO_END, a, c); \ - COPY32(0, a, c); \ -} - -static vm_offset_t -bi_copymodules(vm_offset_t addr) -{ - struct preloaded_file *fp; - struct file_metadata *md; - int c; - uint64_t v; - - c = addr != 0; - /* Start with the first module on the list, should be the kernel. */ - for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) { - MOD_NAME(addr, fp->f_name, c); /* This must come first. */ - MOD_TYPE(addr, fp->f_type, c); - if (fp->f_args) - MOD_ARGS(addr, fp->f_args, c); - v = fp->f_addr; -#if defined(__arm__) - v -= __elfN(relocation_offset); -#endif - MOD_ADDR(addr, v, c); - v = fp->f_size; - MOD_SIZE(addr, v, c); - for (md = fp->f_metadata; md != NULL; md = md->md_next) - if (!(md->md_type & MODINFOMD_NOCOPY)) - MOD_METADATA(addr, md, c); - } - MOD_END(addr, c); - return(addr); -} - +#ifdef EFI static EFI_STATUS efi_do_vmap(EFI_MEMORY_DESCRIPTOR *mm, UINTN sz, UINTN mmsz, UINT32 mmver) { @@ -309,16 +199,19 @@ bi_load_efi_data(struct preloaded_file *kfp, bool exit_bs) efifb.fb_mask_blue = gfx_state.tg_fb.fb_mask_blue; efifb.fb_mask_reserved = gfx_state.tg_fb.fb_mask_reserved; - printf("EFI framebuffer information:\n"); - printf("addr, size 0x%jx, 0x%jx\n", efifb.fb_addr, efifb.fb_size); - printf("dimensions %d x %d\n", efifb.fb_width, efifb.fb_height); - printf("stride %d\n", efifb.fb_stride); - printf("masks 0x%08x, 0x%08x, 0x%08x, 0x%08x\n", - efifb.fb_mask_red, efifb.fb_mask_green, efifb.fb_mask_blue, - efifb.fb_mask_reserved); + if (efifb.fb_addr != 0) { + printf("EFI framebuffer information:\n"); + printf("addr, size 0x%jx, 0x%jx\n", + efifb.fb_addr, efifb.fb_size); + printf("dimensions %d x %d\n", + efifb.fb_width, efifb.fb_height); + printf("stride %d\n", efifb.fb_stride); + printf("masks 0x%08x, 0x%08x, 0x%08x, 0x%08x\n", + efifb.fb_mask_red, efifb.fb_mask_green, efifb.fb_mask_blue, + efifb.fb_mask_reserved); - if (efifb.fb_addr != 0) file_addmetadata(kfp, MODINFOMD_EFI_FB, sizeof(efifb), &efifb); + } #endif do_vmap = true; @@ -421,6 +314,7 @@ bi_load_efi_data(struct preloaded_file *kfp, bool exit_bs) return (0); } +#endif /* * Load the information expected by an amd64 kernel. @@ -438,11 +332,15 @@ bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp, bool exit_bs) struct devdesc *rootdev; struct file_metadata *md; vm_offset_t addr; - uint64_t kernend, module; + uint64_t kernend; +#ifdef MODINFOMD_MODULEP + uint64_t module; +#endif uint64_t envp; vm_offset_t size; char *rootdevname; int howto; + bool is64 = sizeof(long) == 8; #if defined(LOADER_FDT_SUPPORT) vm_offset_t dtbp; int dtb_size; @@ -462,7 +360,6 @@ bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp, bool exit_bs) #endif }; #endif - howto = bi_getboothowto(args); /* @@ -478,11 +375,11 @@ bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp, bool exit_bs) } /* Try reading the /etc/fstab file to select the root device */ - getrootmount(efi_fmtdev((void *)rootdev)); + getrootmount(devformat(rootdev)); addr = 0; for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) { - if (addr < (xp->f_addr + xp->f_size)) + if (addr < xp->f_addr + xp->f_size) addr = xp->f_addr + xp->f_size; } @@ -496,7 +393,7 @@ bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp, bool exit_bs) /* Copy our environment. */ envp = addr; - addr = bi_copyenv(addr); + addr = md_copyenv(addr); /* Pad to a page boundary. */ addr = roundup(addr, PAGE_SIZE); @@ -519,7 +416,7 @@ bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp, bool exit_bs) kernend = 0; /* fill it in later */ /* Figure out the size and location of the metadata. */ - module = *modulep = addr; + *modulep = addr; file_addmetadata(kfp, MODINFOMD_HOWTO, sizeof(howto), &howto); file_addmetadata(kfp, MODINFOMD_ENVP, sizeof(envp), &envp); @@ -532,15 +429,22 @@ bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp, bool exit_bs) #endif file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof(kernend), &kernend); #ifdef MODINFOMD_MODULEP + module = *modulep; file_addmetadata(kfp, MODINFOMD_MODULEP, sizeof(module), &module); #endif +#ifdef EFI file_addmetadata(kfp, MODINFOMD_FW_HANDLE, sizeof(ST), &ST); +#endif #ifdef LOADER_GELI_SUPPORT geli_export_key_metadata(kfp); #endif +#ifdef EFI bi_load_efi_data(kfp, exit_bs); +#else + bi_loadsmap(kfp); +#endif - size = bi_copymodules(0); + size = md_copymodules(0, is64); /* Find the size of the modules */ kernend = roundup(addr + size, PAGE_SIZE); *kernendp = kernend; @@ -565,7 +469,7 @@ bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp, bool exit_bs) #endif /* Copy module list and metadata. */ - (void)bi_copymodules(addr); + (void)md_copymodules(addr, is64); return (0); } diff --git a/stand/efi/loader/conf.c b/stand/efi/loader/conf.c index 863c9188c72c..389489726d84 100644 --- a/stand/efi/loader/conf.c +++ b/stand/efi/loader/conf.c @@ -25,8 +25,6 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <bootstrap.h> #include <efi.h> @@ -80,16 +78,25 @@ struct netif_driver *netif_drivers[] = { }; extern struct console efi_console; +extern struct console eficom; +#if defined(__aarch64__) && __FreeBSD_version < 1500000 +/* Hack for backward compatibility -- but only for a while */ +extern struct console comconsole; +#endif +#if defined(__amd64__) extern struct console comconsole; -#if defined(__amd64__) || defined(__i386__) extern struct console nullconsole; extern struct console spinconsole; #endif struct console *consoles[] = { &efi_console, + &eficom, +#if defined(__aarch64__) && __FreeBSD_version < 1500000 + &comconsole, +#endif +#if defined(__amd64__) &comconsole, -#if defined(__amd64__) || defined(__i386__) &nullconsole, &spinconsole, #endif diff --git a/stand/efi/loader/copy.c b/stand/efi/loader/copy.c index 47e613ccc2f3..3f2d1c6c20b0 100644 --- a/stand/efi/loader/copy.c +++ b/stand/efi/loader/copy.c @@ -1,6 +1,5 @@ /*- * Copyright (c) 2013 The FreeBSD Foundation - * All rights reserved. * * This software was developed by Benno Rice under sponsorship from * the FreeBSD Foundation. @@ -26,9 +25,6 @@ * SUCH DAMAGE. */ -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/param.h> #include <stand.h> @@ -42,7 +38,7 @@ __FBSDID("$FreeBSD$"); #define M(x) ((x) * 1024 * 1024) #define G(x) (1UL * (x) * 1024 * 1024 * 1024) -#if defined(__i386__) || defined(__amd64__) +#if defined(__amd64__) #include <machine/cpufunc.h> #include <machine/specialreg.h> #include <machine/vmparam.h> @@ -174,7 +170,7 @@ efi_verify_staging_size(unsigned long *nr_pages) out: free(map); } -#endif /* __i386__ || __amd64__ */ +#endif /* __amd64__ */ #if defined(__arm__) #define DEFAULT_EFI_STAGING_SIZE 32 @@ -201,7 +197,7 @@ out: static u_long staging_slop = EFI_STAGING_SLOP; EFI_PHYSICAL_ADDRESS staging, staging_end, staging_base; -int stage_offset_set = 0; +bool stage_offset_set = false; ssize_t stage_offset; static void @@ -209,7 +205,7 @@ efi_copy_free(void) { BS->FreePages(staging_base, (staging_end - staging_base) / EFI_PAGE_SIZE); - stage_offset_set = 0; + stage_offset_set = false; stage_offset = 0; } @@ -285,9 +281,9 @@ command_staging_slop(int argc, char *argv[]) COMMAND_SET(staging_slop, "staging_slop", "set staging slop", command_staging_slop); -#if defined(__i386__) || defined(__amd64__) +#if defined(__amd64__) /* - * The staging area must reside in the the first 1GB or 4GB physical + * The staging area must reside in the first 1GB or 4GB physical * memory: see elf64_exec() in * boot/efi/loader/arch/amd64/elf64_freebsd.c. */ @@ -296,11 +292,7 @@ get_staging_max(void) { EFI_PHYSICAL_ADDRESS res; -#if defined(__i386__) - res = G(1); -#elif defined(__amd64__) res = copy_staging == COPY_STAGING_ENABLE ? G(1) : G(4); -#endif return (res); } #define EFI_ALLOC_METHOD AllocateMaxAddress @@ -320,7 +312,7 @@ efi_copy_init(void) ess = DEFAULT_EFI_STAGING_SIZE; nr_pages = EFI_SIZE_TO_PAGES(M(1) * ess); -#if defined(__i386__) || defined(__amd64__) +#if defined(__amd64__) /* * We'll decrease nr_pages, if it's too big. Currently we only * apply this to FreeBSD VM running on Hyper-V. Why? Please see @@ -331,7 +323,7 @@ efi_copy_init(void) staging = get_staging_max(); #endif - status = BS->AllocatePages(EFI_ALLOC_METHOD, EfiLoaderData, + status = BS->AllocatePages(EFI_ALLOC_METHOD, EfiLoaderCode, nr_pages, &staging); if (EFI_ERROR(status)) { printf("failed to allocate staging area: %lu\n", @@ -388,9 +380,8 @@ efi_check_space(vm_offset_t end) end += staging_slop; nr_pages = EFI_SIZE_TO_PAGES(end - staging_end); -#if defined(__i386__) || defined(__amd64__) +#if defined(__amd64__) /* - * i386 needs all memory to be allocated under the 1G boundary. * amd64 needs all memory to be allocated under the 1G or 4G boundary. */ if (end > get_staging_max()) @@ -399,7 +390,7 @@ efi_check_space(vm_offset_t end) /* Try to allocate more space after the previous allocation */ addr = staging_end; - status = BS->AllocatePages(AllocateAddress, EfiLoaderData, nr_pages, + status = BS->AllocatePages(AllocateAddress, EfiLoaderCode, nr_pages, &addr); if (!EFI_ERROR(status)) { staging_end = staging_end + nr_pages * EFI_PAGE_SIZE; @@ -416,7 +407,7 @@ before_staging: addr = rounddown2(addr, M(2)); #endif nr_pages = EFI_SIZE_TO_PAGES(staging_base - addr); - status = BS->AllocatePages(AllocateAddress, EfiLoaderData, nr_pages, + status = BS->AllocatePages(AllocateAddress, EfiLoaderCode, nr_pages, &addr); if (!EFI_ERROR(status)) { /* @@ -436,10 +427,10 @@ expand: #if EFI_STAGING_2M_ALIGN nr_pages += M(2) / EFI_PAGE_SIZE; #endif -#if defined(__i386__) || defined(__amd64__) +#if defined(__amd64__) new_base = get_staging_max(); #endif - status = BS->AllocatePages(EFI_ALLOC_METHOD, EfiLoaderData, + status = BS->AllocatePages(EFI_ALLOC_METHOD, EfiLoaderCode, nr_pages, &new_base); if (!EFI_ERROR(status)) { #if EFI_STAGING_2M_ALIGN @@ -479,7 +470,7 @@ efi_copyin(const void *src, vm_offset_t dest, const size_t len) if (!stage_offset_set) { stage_offset = (vm_offset_t)staging - dest; - stage_offset_set = 1; + stage_offset_set = true; } /* XXX: Callers do not check for failure. */ @@ -510,7 +501,7 @@ efi_readin(readin_handle_t fd, vm_offset_t dest, const size_t len) if (!stage_offset_set) { stage_offset = (vm_offset_t)staging - dest; - stage_offset_set = 1; + stage_offset_set = true; } if (!efi_check_space(dest + stage_offset + len)) { diff --git a/stand/efi/loader/efi_main.c b/stand/efi/loader/efi_main.c index 3e1fa06638e9..25b13d5d3728 100644 --- a/stand/efi/loader/efi_main.c +++ b/stand/efi/loader/efi_main.c @@ -25,8 +25,6 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <bootstrap.h> #include <efi.h> #include <eficonsctl.h> diff --git a/stand/efi/loader/efiserialio.c b/stand/efi/loader/efiserialio.c deleted file mode 100644 index 8b3f8e83e0b3..000000000000 --- a/stand/efi/loader/efiserialio.c +++ /dev/null @@ -1,515 +0,0 @@ -/*- - * Copyright (c) 1998 Michael Smith (msmith@freebsd.org) - * - * 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> -__FBSDID("$FreeBSD$"); - -#include <stand.h> -#include <sys/errno.h> -#include <bootstrap.h> -#include <stdbool.h> - -#include <efi.h> -#include <efilib.h> - -#include "loader_efi.h" - -static EFI_GUID serial = SERIAL_IO_PROTOCOL; - -#define COMC_TXWAIT 0x40000 /* transmit timeout */ - -#ifndef COMSPEED -#define COMSPEED 9600 -#endif - -#define PNP0501 0x501 /* 16550A-compatible COM port */ - -struct serial { - uint64_t baudrate; - uint8_t databits; - EFI_PARITY_TYPE parity; - EFI_STOP_BITS_TYPE stopbits; - uint8_t ignore_cd; /* boolean */ - uint8_t rtsdtr_off; /* boolean */ - int ioaddr; /* index in handles array */ - EFI_HANDLE currdev; /* current serial device */ - EFI_HANDLE condev; /* EFI Console device */ - SERIAL_IO_INTERFACE *sio; -}; - -static void comc_probe(struct console *); -static int comc_init(int); -static void comc_putchar(int); -static int comc_getchar(void); -static int comc_ischar(void); -static bool comc_setup(void); -static int comc_parse_intval(const char *, unsigned *); -static int comc_port_set(struct env_var *, int, const void *); -static int comc_speed_set(struct env_var *, int, const void *); - -static struct serial *comc_port; -extern struct console efi_console; - -struct console comconsole = { - .c_name = "comconsole", - .c_desc = "serial port", - .c_flags = 0, - .c_probe = comc_probe, - .c_init = comc_init, - .c_out = comc_putchar, - .c_in = comc_getchar, - .c_ready = comc_ischar, -}; - -static EFI_STATUS -efi_serial_init(EFI_HANDLE **handlep, int *nhandles) -{ - UINTN bufsz = 0; - EFI_STATUS status; - EFI_HANDLE *handles; - - /* - * get buffer size - */ - *nhandles = 0; - handles = NULL; - status = BS->LocateHandle(ByProtocol, &serial, NULL, &bufsz, handles); - if (status != EFI_BUFFER_TOO_SMALL) - return (status); - - if ((handles = malloc(bufsz)) == NULL) - return (ENOMEM); - - *nhandles = (int)(bufsz / sizeof (EFI_HANDLE)); - /* - * get handle array - */ - status = BS->LocateHandle(ByProtocol, &serial, NULL, &bufsz, handles); - if (EFI_ERROR(status)) { - free(handles); - *nhandles = 0; - } else - *handlep = handles; - return (status); -} - -/* - * Find serial device number from device path. - * Return -1 if not found. - */ -static int -efi_serial_get_index(EFI_DEVICE_PATH *devpath, int idx) -{ - ACPI_HID_DEVICE_PATH *acpi; - CHAR16 *text; - - while (!IsDevicePathEnd(devpath)) { - if (DevicePathType(devpath) == MESSAGING_DEVICE_PATH && - DevicePathSubType(devpath) == MSG_UART_DP) - return (idx); - - if (DevicePathType(devpath) == ACPI_DEVICE_PATH && - (DevicePathSubType(devpath) == ACPI_DP || - DevicePathSubType(devpath) == ACPI_EXTENDED_DP)) { - - acpi = (ACPI_HID_DEVICE_PATH *)devpath; - if (acpi->HID == EISA_PNP_ID(PNP0501)) { - return (acpi->UID); - } - } - - devpath = NextDevicePathNode(devpath); - } - return (-1); -} - -/* - * The order of handles from LocateHandle() is not known, we need to - * iterate handles, pick device path for handle, and check the device - * number. - */ -static EFI_HANDLE -efi_serial_get_handle(int port, EFI_HANDLE condev) -{ - EFI_STATUS status; - EFI_HANDLE *handles, handle; - EFI_DEVICE_PATH *devpath; - int index, nhandles; - - if (port == -1) - return (NULL); - - handles = NULL; - nhandles = 0; - status = efi_serial_init(&handles, &nhandles); - if (EFI_ERROR(status)) - return (NULL); - - /* - * We have console handle, set ioaddr for it. - */ - if (condev != NULL) { - for (index = 0; index < nhandles; index++) { - if (condev == handles[index]) { - devpath = efi_lookup_devpath(condev); - comc_port->ioaddr = - efi_serial_get_index(devpath, index); - efi_close_devpath(condev); - free(handles); - return (condev); - } - } - } - - handle = NULL; - for (index = 0; handle == NULL && index < nhandles; index++) { - devpath = efi_lookup_devpath(handles[index]); - if (port == efi_serial_get_index(devpath, index)) - handle = (handles[index]); - efi_close_devpath(handles[index]); - } - - /* - * In case we did fail to identify the device by path, use port as - * array index. Note, we did check port == -1 above. - */ - if (port < nhandles && handle == NULL) - handle = handles[port]; - - free(handles); - return (handle); -} - -static EFI_HANDLE -comc_get_con_serial_handle(const char *name) -{ - EFI_HANDLE handle; - EFI_DEVICE_PATH *node; - EFI_STATUS status; - char *buf, *ep; - size_t sz; - - buf = NULL; - sz = 0; - status = efi_global_getenv(name, buf, &sz); - if (status == EFI_BUFFER_TOO_SMALL) { - buf = malloc(sz); - if (buf == NULL) - return (NULL); - status = efi_global_getenv(name, buf, &sz); - } - if (status != EFI_SUCCESS) { - free(buf); - return (NULL); - } - - ep = buf + sz; - node = (EFI_DEVICE_PATH *)buf; - while ((char *)node < ep) { - status = BS->LocateDevicePath(&serial, &node, &handle); - if (status == EFI_SUCCESS) { - free(buf); - return (handle); - } - - /* Sanity check the node before moving to the next node. */ - if (DevicePathNodeLength(node) < sizeof(*node)) - break; - - /* Start of next device path in list. */ - node = NextDevicePathNode(node); - } - free(buf); - return (NULL); -} - -static void -comc_probe(struct console *sc) -{ - EFI_STATUS status; - EFI_HANDLE handle; - char name[20]; - char value[20]; - unsigned val; - char *env, *buf, *ep; - size_t sz; - - if (comc_port == NULL) { - comc_port = malloc(sizeof (struct serial)); - if (comc_port == NULL) - return; - } - comc_port->baudrate = COMSPEED; - comc_port->ioaddr = 0; /* default port */ - comc_port->databits = 8; /* 8,n,1 */ - comc_port->parity = NoParity; /* 8,n,1 */ - comc_port->stopbits = OneStopBit; /* 8,n,1 */ - comc_port->ignore_cd = 1; /* ignore cd */ - comc_port->rtsdtr_off = 0; /* rts-dtr is on */ - comc_port->sio = NULL; - - handle = NULL; - env = getenv("efi_com_port"); - if (comc_parse_intval(env, &val) == CMD_OK) { - comc_port->ioaddr = val; - } else { - /* - * efi_com_port is not set, we need to select default. - * First, we consult ConOut variable to see if - * we have serial port redirection. If not, we just - * pick first device. - */ - handle = comc_get_con_serial_handle("ConOut"); - comc_port->condev = handle; - } - - handle = efi_serial_get_handle(comc_port->ioaddr, handle); - if (handle != NULL) { - comc_port->currdev = handle; - status = BS->OpenProtocol(handle, &serial, - (void**)&comc_port->sio, IH, NULL, - EFI_OPEN_PROTOCOL_GET_PROTOCOL); - - if (EFI_ERROR(status)) - comc_port->sio = NULL; - } - - if (env != NULL) - unsetenv("efi_com_port"); - snprintf(value, sizeof (value), "%u", comc_port->ioaddr); - env_setenv("efi_com_port", EV_VOLATILE, value, - comc_port_set, env_nounset); - - env = getenv("efi_com_speed"); - if (comc_parse_intval(env, &val) == CMD_OK) - comc_port->baudrate = val; - - if (env != NULL) - unsetenv("efi_com_speed"); - snprintf(value, sizeof (value), "%ju", (uintmax_t)comc_port->baudrate); - env_setenv("efi_com_speed", EV_VOLATILE, value, - comc_speed_set, env_nounset); - - comconsole.c_flags = 0; - if (comc_setup()) - sc->c_flags = C_PRESENTIN | C_PRESENTOUT; -} - -static int -comc_init(int arg __unused) -{ - - if (comc_setup()) - return (CMD_OK); - - comconsole.c_flags = 0; - return (CMD_ERROR); -} - -static void -comc_putchar(int c) -{ - int wait; - EFI_STATUS status; - UINTN bufsz = 1; - char cb = c; - - if (comc_port->sio == NULL) - return; - - for (wait = COMC_TXWAIT; wait > 0; wait--) { - status = comc_port->sio->Write(comc_port->sio, &bufsz, &cb); - if (status != EFI_TIMEOUT) - break; - } -} - -static int -comc_getchar(void) -{ - EFI_STATUS status; - UINTN bufsz = 1; - char c; - - - /* - * if this device is also used as ConIn, some firmwares - * fail to return all input via SIO protocol. - */ - if (comc_port->currdev == comc_port->condev) { - if ((efi_console.c_flags & C_ACTIVEIN) == 0) - return (efi_console.c_in()); - return (-1); - } - - if (comc_port->sio == NULL) - return (-1); - - status = comc_port->sio->Read(comc_port->sio, &bufsz, &c); - if (EFI_ERROR(status) || bufsz == 0) - return (-1); - - return (c); -} - -static int -comc_ischar(void) -{ - EFI_STATUS status; - uint32_t control; - - /* - * if this device is also used as ConIn, some firmwares - * fail to return all input via SIO protocol. - */ - if (comc_port->currdev == comc_port->condev) { - if ((efi_console.c_flags & C_ACTIVEIN) == 0) - return (efi_console.c_ready()); - return (0); - } - - if (comc_port->sio == NULL) - return (0); - - status = comc_port->sio->GetControl(comc_port->sio, &control); - if (EFI_ERROR(status)) - return (0); - - return (!(control & EFI_SERIAL_INPUT_BUFFER_EMPTY)); -} - -static int -comc_parse_intval(const char *value, unsigned *valp) -{ - unsigned n; - char *ep; - - if (value == NULL || *value == '\0') - return (CMD_ERROR); - - errno = 0; - n = strtoul(value, &ep, 10); - if (errno != 0 || *ep != '\0') - return (CMD_ERROR); - *valp = n; - - return (CMD_OK); -} - -static int -comc_port_set(struct env_var *ev, int flags, const void *value) -{ - unsigned port; - SERIAL_IO_INTERFACE *sio; - EFI_HANDLE handle; - EFI_STATUS status; - - if (value == NULL) - return (CMD_ERROR); - - if (comc_parse_intval(value, &port) != CMD_OK) - return (CMD_ERROR); - - handle = efi_serial_get_handle(port, NULL); - if (handle == NULL) { - printf("no handle\n"); - return (CMD_ERROR); - } - - status = BS->OpenProtocol(handle, &serial, - (void**)&sio, IH, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); - - if (EFI_ERROR(status)) { - printf("OpenProtocol: %lu\n", EFI_ERROR_CODE(status)); - return (CMD_ERROR); - } - - comc_port->currdev = handle; - comc_port->ioaddr = port; - comc_port->sio = sio; - - (void) comc_setup(); - - env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL); - return (CMD_OK); -} - -static int -comc_speed_set(struct env_var *ev, int flags, const void *value) -{ - unsigned speed; - - if (value == NULL) - return (CMD_ERROR); - - if (comc_parse_intval(value, &speed) != CMD_OK) - return (CMD_ERROR); - - comc_port->baudrate = speed; - (void) comc_setup(); - - env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL); - - return (CMD_OK); -} - -/* - * In case of error, we also reset ACTIVE flags, so the console - * framefork will try alternate consoles. - */ -static bool -comc_setup(void) -{ - EFI_STATUS status; - UINT32 control; - - /* port is not usable */ - if (comc_port->sio == NULL) - return (false); - - status = comc_port->sio->Reset(comc_port->sio); - if (EFI_ERROR(status)) - return (false); - - status = comc_port->sio->SetAttributes(comc_port->sio, - comc_port->baudrate, 0, 0, comc_port->parity, - comc_port->databits, comc_port->stopbits); - if (EFI_ERROR(status)) - return (false); - - status = comc_port->sio->GetControl(comc_port->sio, &control); - if (EFI_ERROR(status)) - return (false); - if (comc_port->rtsdtr_off) { - control &= ~(EFI_SERIAL_REQUEST_TO_SEND | - EFI_SERIAL_DATA_TERMINAL_READY); - } else { - control |= EFI_SERIAL_REQUEST_TO_SEND; - } - (void) comc_port->sio->SetControl(comc_port->sio, control); - /* Mark this port usable. */ - comconsole.c_flags |= (C_PRESENTIN | C_PRESENTOUT); - return (true); -} diff --git a/stand/efi/loader/framebuffer.c b/stand/efi/loader/framebuffer.c index d5504c9cff35..b8e61dc73acf 100644 --- a/stand/efi/loader/framebuffer.c +++ b/stand/efi/loader/framebuffer.c @@ -1,6 +1,5 @@ /*- * Copyright (c) 2013 The FreeBSD Foundation - * All rights reserved. * * This software was developed by Benno Rice under sponsorship from * the FreeBSD Foundation. @@ -27,8 +26,6 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <bootstrap.h> #include <sys/endian.h> #include <sys/param.h> @@ -536,6 +533,21 @@ efifb_get_edid(edid_res_list_t *res) return (rv); } +bool +efi_has_gop(void) +{ + EFI_STATUS status; + EFI_HANDLE *hlist; + UINTN hsize; + + hsize = 0; + hlist = NULL; + status = BS->LocateHandle(ByProtocol, &gop_guid, NULL, &hsize, hlist); + + return (status == EFI_BUFFER_TOO_SMALL); +} + + int efi_find_framebuffer(teken_gfx_t *gfx_state) { diff --git a/stand/efi/loader/framebuffer.h b/stand/efi/loader/framebuffer.h index 008df7f6c167..c6015f4ccbd3 100644 --- a/stand/efi/loader/framebuffer.h +++ b/stand/efi/loader/framebuffer.h @@ -1,6 +1,5 @@ /*- * Copyright (c) 2013 The FreeBSD Foundation - * All rights reserved. * * This software was developed by Benno Rice under sponsorship from * the FreeBSD Foundation. @@ -24,15 +23,15 @@ * 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$ */ +#include <teken.h> #include <gfx_fb.h> #ifndef _EFIFB_H_ #define _EFIFB_H_ +bool efi_has_gop(void); int efi_find_framebuffer(teken_gfx_t *gfx_state); #endif /* _EFIFB_H_ */ diff --git a/stand/efi/loader/loader_efi.h b/stand/efi/loader/loader_efi.h index 8254d16b1592..249860aa5e91 100644 --- a/stand/efi/loader/loader_efi.h +++ b/stand/efi/loader/loader_efi.h @@ -1,6 +1,5 @@ /*- * Copyright (c) 2013 The FreeBSD Foundation - * All rights reserved. * * This software was developed by Benno Rice under sponsorship from * the FreeBSD Foundation. @@ -24,8 +23,6 @@ * 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$ */ #ifndef _LOADER_EFI_COPY_H_ @@ -33,6 +30,7 @@ #include <stand.h> #include <readin.h> +#include <efi.h> #ifdef __amd64__ enum { @@ -43,6 +41,8 @@ enum { extern int copy_staging; #endif +extern EFI_LOADED_IMAGE *boot_img; + int efi_autoload(void); int efi_copy_init(void); diff --git a/stand/efi/loader/main.c b/stand/efi/loader/main.c index eb143989190d..d6ba7ec3da44 100644 --- a/stand/efi/loader/main.c +++ b/stand/efi/loader/main.c @@ -28,8 +28,6 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <stand.h> #include <sys/disk.h> @@ -60,6 +58,13 @@ __FBSDID("$FreeBSD$"); #include <smbios.h> #include "efizfs.h" +#include "framebuffer.h" + +#include "platform/acfreebsd.h" +#include "acconfig.h" +#define ACPI_SYSTEM_XFACE +#include "actypes.h" +#include "actbl.h" #include "loader_efi.h" @@ -185,25 +190,11 @@ out: } static void -set_currdev(const char *devname) -{ - - env_setenv("currdev", EV_VOLATILE, devname, efi_setcurrdev, - env_nounset); - /* - * Don't execute hook here; the loaddev hook makes it immutable - * once we've determined what the proper currdev is. - */ - env_setenv("loaddev", EV_VOLATILE | EV_NOHOOK, devname, env_noset, - env_nounset); -} - -static void set_currdev_devdesc(struct devdesc *currdev) { const char *devname; - devname = efi_fmtdev(currdev); + devname = devformat(currdev); printf("Setting currdev to %s\n", devname); set_currdev(devname); } @@ -263,34 +254,26 @@ sanity_check_currdev(void) static bool probe_zfs_currdev(uint64_t guid) { + char buf[VDEV_PAD_SIZE]; char *devname; struct zfs_devdesc currdev; - char *buf = NULL; - bool rv; currdev.dd.d_dev = &zfs_dev; currdev.dd.d_unit = 0; currdev.pool_guid = guid; currdev.root_guid = 0; set_currdev_devdesc((struct devdesc *)&currdev); - devname = efi_fmtdev(&currdev); + devname = devformat(&currdev.dd); init_zfs_boot_options(devname); - rv = sanity_check_currdev(); - if (rv) { - buf = malloc(VDEV_PAD_SIZE); - if (buf != NULL) { - if (zfs_get_bootonce(&currdev, OS_BOOTONCE, buf, - VDEV_PAD_SIZE) == 0) { - printf("zfs bootonce: %s\n", buf); - set_currdev(buf); - setenv("zfs-bootonce", buf, 1); - } - free(buf); - (void) zfs_attach_nvstore(&currdev); - } + if (zfs_get_bootonce(&currdev, OS_BOOTONCE, buf, sizeof(buf)) == 0) { + printf("zfs bootonce: %s\n", buf); + set_currdev(buf); + setenv("zfs-bootonce", buf, 1); } - return (rv); + (void)zfs_attach_nvstore(&currdev); + + return (sanity_check_currdev()); } #endif @@ -701,8 +684,7 @@ interactive_interrupt(const char *msg) static int parse_args(int argc, CHAR16 *argv[]) { - int i, j, howto; - bool vargood; + int i, howto; char var[128]; /* @@ -719,7 +701,7 @@ parse_args(int argc, CHAR16 *argv[]) * method is flawed for non-ASCII characters). */ howto = 0; - for (i = 1; i < argc; i++) { + for (i = 0; i < argc; i++) { cpy16to8(argv[i], var, sizeof(var)); howto |= boot_parse_arg(var); } @@ -760,8 +742,20 @@ parse_uefi_con_out(void) if (rv != EFI_SUCCESS) rv = efi_global_getenv("ConOutDev", buf, &sz); if (rv != EFI_SUCCESS) { - /* If we don't have any ConOut default to serial */ - how = RB_SERIAL; + /* + * If we don't have any ConOut default to both. If we have GOP + * make video primary, otherwise just make serial primary. In + * either case, try to use both the 'efi' console which will use + * the GOP, if present and serial. If there's an EFI BIOS that + * omits this, but has a serial port redirect, we'll + * unavioidably get doubled characters (but we'll be right in + * all the other more common cases). + */ + if (efi_has_gop()) + how = RB_MULTIPLE; + else + how = RB_MULTIPLE | RB_SERIAL; + setenv("console", "efi,comconsole", 1); goto out; } ep = buf + sz; @@ -908,6 +902,39 @@ ptov(uintptr_t x) return ((caddr_t)x); } +static void +acpi_detect(void) +{ + ACPI_TABLE_RSDP *rsdp; + char buf[24]; + int revision; + + if ((rsdp = efi_get_table(&acpi20)) == NULL) + if ((rsdp = efi_get_table(&acpi)) == NULL) + return; + + sprintf(buf, "0x%016llx", (unsigned long long)rsdp); + setenv("acpi.rsdp", buf, 1); + revision = rsdp->Revision; + if (revision == 0) + revision = 1; + sprintf(buf, "%d", revision); + setenv("acpi.revision", buf, 1); + strncpy(buf, rsdp->OemId, sizeof(rsdp->OemId)); + buf[sizeof(rsdp->OemId)] = '\0'; + setenv("acpi.oem", buf, 1); + sprintf(buf, "0x%016x", rsdp->RsdtPhysicalAddress); + setenv("acpi.rsdt", buf, 1); + if (revision >= 2) { + /* XXX extended checksum? */ + sprintf(buf, "0x%016llx", + (unsigned long long)rsdp->XsdtPhysicalAddress); + setenv("acpi.xsdt", buf, 1); + sprintf(buf, "%d", rsdp->Length); + setenv("acpi.xsdt_length", buf, 1); + } +} + EFI_STATUS main(int argc, CHAR16 *argv[]) { @@ -935,9 +962,28 @@ main(int argc, CHAR16 *argv[]) archsw.arch_readin = efi_readin; archsw.arch_zfs_probe = efi_zfs_probe; +#if !defined(__arm__) + for (k = 0; k < ST->NumberOfTableEntries; k++) { + guid = &ST->ConfigurationTable[k].VendorGuid; + if (!memcmp(guid, &smbios, sizeof(EFI_GUID)) || + !memcmp(guid, &smbios3, sizeof(EFI_GUID))) { + char buf[40]; + + snprintf(buf, sizeof(buf), "%p", + ST->ConfigurationTable[k].VendorTable); + setenv("hint.smbios.0.mem", buf, 1); + smbios_detect(ST->ConfigurationTable[k].VendorTable); + break; + } + } +#endif + /* Get our loaded image protocol interface structure. */ (void) OpenProtocolByHandle(IH, &imgid, (void **)&boot_img); + /* Report the RSDP early. */ + acpi_detect(); + /* * Chicken-and-egg problem; we want to have console output early, but * some console attributes may depend on reading from eg. the boot @@ -949,13 +995,16 @@ main(int argc, CHAR16 *argv[]) setenv("console", "efi", 1); uhowto = parse_uefi_con_out(); #if defined(__riscv) + /* + * This workaround likely is papering over a real issue + */ if ((uhowto & RB_SERIAL) != 0) setenv("console", "comconsole", 1); #endif cons_probe(); /* Set up currdev variable to have hooks in place. */ - env_setenv("currdev", EV_VOLATILE, "", efi_setcurrdev, env_nounset); + env_setenv("currdev", EV_VOLATILE, "", gen_setcurrdev, env_nounset); /* Init the time source */ efi_time_init(); @@ -975,9 +1024,7 @@ main(int argc, CHAR16 *argv[]) "failures\n", i); } - for (i = 0; devsw[i] != NULL; i++) - if (devsw[i]->dv_init != NULL) - (devsw[i]->dv_init)(); + devinit(); /* * Detect console settings two different ways: one via the command @@ -1055,10 +1102,8 @@ main(int argc, CHAR16 *argv[]) */ boot_howto_to_env(howto); - if (efi_copy_init()) { - printf("failed to allocate staging area\n"); + if (efi_copy_init()) return (EFI_BUFFER_TOO_SMALL); - } if ((s = getenv("fail_timeout")) != NULL) fail_timeout = strtol(s, NULL, 10); @@ -1185,21 +1230,6 @@ main(int argc, CHAR16 *argv[]) autoload_font(false); /* Set up the font list for console. */ efi_init_environment(); -#if !defined(__arm__) - for (k = 0; k < ST->NumberOfTableEntries; k++) { - guid = &ST->ConfigurationTable[k].VendorGuid; - if (!memcmp(guid, &smbios, sizeof(EFI_GUID))) { - char buf[40]; - - snprintf(buf, sizeof(buf), "%p", - ST->ConfigurationTable[k].VendorTable); - setenv("hint.smbios.0.mem", buf, 1); - smbios_detect(ST->ConfigurationTable[k].VendorTable); - break; - } - } -#endif - interact(); /* doesn't return */ return (EFI_SUCCESS); /* keep compiler happy */ @@ -1280,15 +1310,6 @@ command_reboot(int argc, char *argv[]) return (CMD_ERROR); } -COMMAND_SET(quit, "quit", "exit the loader", command_quit); - -static int -command_quit(int argc, char *argv[]) -{ - exit(0); - return (CMD_OK); -} - COMMAND_SET(memmap, "memmap", "print memory map", command_memmap); static int diff --git a/stand/efi/loader/version b/stand/efi/loader/version index 3a4c47c5efb1..2bed97c231d2 100644 --- a/stand/efi/loader/version +++ b/stand/efi/loader/version @@ -1,4 +1,3 @@ -$FreeBSD$ NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this file is important. Make sure the current version number is on line 6. |