aboutsummaryrefslogtreecommitdiff
path: root/stand/efi
diff options
context:
space:
mode:
Diffstat (limited to 'stand/efi')
-rw-r--r--stand/efi/fdt/efi_fdt.c1
-rw-r--r--stand/efi/include/efilib.h1
-rw-r--r--stand/efi/libefi/devicename.c26
-rw-r--r--stand/efi/libefi/efihttp.c2
-rw-r--r--stand/efi/libefi/efinet.c2
-rw-r--r--stand/efi/libefi/efipart.c7
-rw-r--r--stand/efi/loader/Makefile4
-rw-r--r--stand/efi/loader/arch/amd64/amd64_tramp.S1
-rw-r--r--stand/efi/loader/arch/amd64/elf64_freebsd.c12
-rw-r--r--stand/efi/loader/arch/amd64/exc.S1
-rw-r--r--stand/efi/loader/arch/amd64/trap.c38
-rw-r--r--stand/efi/loader/arch/arm64/exec.c15
-rw-r--r--stand/efi/loader/bootinfo.c137
-rw-r--r--stand/efi/loader/copy.c11
-rw-r--r--stand/efi/loader/framebuffer.c16
-rw-r--r--stand/efi/loader/framebuffer.h3
-rw-r--r--stand/efi/loader/loader_efi.h4
-rw-r--r--stand/efi/loader/main.c35
18 files changed, 112 insertions, 204 deletions
diff --git a/stand/efi/fdt/efi_fdt.c b/stand/efi/fdt/efi_fdt.c
index cf3cbabee722..21107bb2ccbf 100644
--- a/stand/efi/fdt/efi_fdt.c
+++ b/stand/efi/fdt/efi_fdt.c
@@ -1,6 +1,5 @@
/*-
* Copyright (c) 2014 The FreeBSD Foundation
- * All rights reserved.
*
* This software was developed by Andrew Turner under
* sponsorship from the FreeBSD Foundation.
diff --git a/stand/efi/include/efilib.h b/stand/efi/include/efilib.h
index 903e1f0d00e5..bbef44fca4b3 100644
--- a/stand/efi/include/efilib.h
+++ b/stand/efi/include/efilib.h
@@ -85,7 +85,6 @@ efi_exit_boot_services(UINTN key)
}
int efi_getdev(void **vdev, const char *devspec, const char **path);
-char *efi_fmtdev(void *vdev);
int efi_setcurrdev(struct env_var *ev, int flags, const void *value);
diff --git a/stand/efi/libefi/devicename.c b/stand/efi/libefi/devicename.c
index cdf4830697fd..67a2e24d9da1 100644
--- a/stand/efi/libefi/devicename.c
+++ b/stand/efi/libefi/devicename.c
@@ -171,32 +171,6 @@ fail:
return (err);
}
-char *
-efi_fmtdev(void *vdev)
-{
- struct devdesc *dev = (struct devdesc *)vdev;
- static char buf[SPECNAMELEN + 1];
-
- switch(dev->d_dev->dv_type) {
- case DEVT_NONE:
- strcpy(buf, "(no device)");
- break;
-
- case DEVT_DISK:
- return (disk_fmtdev(vdev));
-
-#ifdef EFI_ZFS_BOOT
- case DEVT_ZFS:
- return (zfs_fmtdev(dev));
-#endif
- default:
- sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_unit);
- break;
- }
-
- return (buf);
-}
-
/*
* Set currdev to suit the value being supplied in (value)
*/
diff --git a/stand/efi/libefi/efihttp.c b/stand/efi/libefi/efihttp.c
index 05d338fbaf04..728f95a47b42 100644
--- a/stand/efi/libefi/efihttp.c
+++ b/stand/efi/libefi/efihttp.c
@@ -94,7 +94,7 @@ struct devsw efihttp_dev = {
.dv_close = efihttp_dev_close,
.dv_ioctl = noioctl,
.dv_print = NULL,
- .dv_cleanup = NULL,
+ .dv_cleanup = nullsys,
};
struct fs_ops efihttp_fsops = {
diff --git a/stand/efi/libefi/efinet.c b/stand/efi/libefi/efinet.c
index c52b11d32ec8..a6582bd2c1b5 100644
--- a/stand/efi/libefi/efinet.c
+++ b/stand/efi/libefi/efinet.c
@@ -351,7 +351,7 @@ struct devsw efinet_dev = {
.dv_close = NULL, /* Will be set in efinet_dev_init */
.dv_ioctl = noioctl,
.dv_print = efinet_dev_print,
- .dv_cleanup = NULL
+ .dv_cleanup = nullsys,
};
static int
diff --git a/stand/efi/libefi/efipart.c b/stand/efi/libefi/efipart.c
index 7807c17077a6..88587192a1b7 100644
--- a/stand/efi/libefi/efipart.c
+++ b/stand/efi/libefi/efipart.c
@@ -78,7 +78,7 @@ struct devsw efipart_fddev = {
.dv_close = efipart_close,
.dv_ioctl = efipart_ioctl,
.dv_print = efipart_printfd,
- .dv_cleanup = NULL
+ .dv_cleanup = nullsys,
};
struct devsw efipart_cddev = {
@@ -90,7 +90,7 @@ struct devsw efipart_cddev = {
.dv_close = efipart_close,
.dv_ioctl = efipart_ioctl,
.dv_print = efipart_printcd,
- .dv_cleanup = NULL
+ .dv_cleanup = nullsys,
};
struct devsw efipart_hddev = {
@@ -102,7 +102,8 @@ struct devsw efipart_hddev = {
.dv_close = efipart_close,
.dv_ioctl = efipart_ioctl,
.dv_print = efipart_printhd,
- .dv_cleanup = NULL
+ .dv_cleanup = nullsys,
+ .dv_fmtdev = disk_fmtdev,
};
static pdinfo_list_t fdinfo = STAILQ_HEAD_INITIALIZER(fdinfo);
diff --git a/stand/efi/loader/Makefile b/stand/efi/loader/Makefile
index 1edb5674712e..2aaba4fbb377 100644
--- a/stand/efi/loader/Makefile
+++ b/stand/efi/loader/Makefile
@@ -39,6 +39,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
@@ -103,7 +105,7 @@ 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 \
diff --git a/stand/efi/loader/arch/amd64/amd64_tramp.S b/stand/efi/loader/arch/amd64/amd64_tramp.S
index 877705407f92..7e15eeb4a035 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.
diff --git a/stand/efi/loader/arch/amd64/elf64_freebsd.c b/stand/efi/loader/arch/amd64/elf64_freebsd.c
index 4bdf675cd5a3..290d1c4696da 100644
--- a/stand/efi/loader/arch/amd64/elf64_freebsd.c
+++ b/stand/efi/loader/arch/amd64/elf64_freebsd.c
@@ -119,12 +119,6 @@ elf64_exec(struct preloaded_file *fp)
/*
* 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);
@@ -133,29 +127,23 @@ elf64_exec(struct preloaded_file *fp)
}
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);
}
}
diff --git a/stand/efi/loader/arch/amd64/exc.S b/stand/efi/loader/arch/amd64/exc.S
index 0035d4a37e20..19981e6e7152 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.
diff --git a/stand/efi/loader/arch/amd64/trap.c b/stand/efi/loader/arch/amd64/trap.c
index e8cf188cf22f..81357e558185 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.
@@ -79,11 +78,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 +118,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/arm64/exec.c b/stand/efi/loader/arch/arm64/exec.c
index 6cf4a4fd8e4d..3cf1c1857f51 100644
--- a/stand/efi/loader/arch/arm64/exec.c
+++ b/stand/efi/loader/arch/arm64/exec.c
@@ -81,6 +81,15 @@ elf64_exec(struct preloaded_file *fp)
int err, revision;
void (*entry)(vm_offset_t);
+ /*
+ * Report the RSDP to the kernel. 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 15.
+ */
+
rsdp = efi_get_table(&acpi20_guid);
if (rsdp == NULL) {
rsdp = efi_get_table(&acpi_guid);
@@ -88,23 +97,29 @@ elf64_exec(struct preloaded_file *fp)
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);
}
}
diff --git a/stand/efi/loader/bootinfo.c b/stand/efi/loader/bootinfo.c
index c7b682819a98..558f7bdae91e 100644
--- a/stand/efi/loader/bootinfo.c
+++ b/stand/efi/loader/bootinfo.c
@@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
#include <efilib.h>
#include "bootstrap.h"
+#include "modinfo.h"
#include "loader_efi.h"
#if defined(__amd64__)
@@ -125,134 +126,6 @@ bi_getboothowto(char *kargs)
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);
-}
-
static EFI_STATUS
efi_do_vmap(EFI_MEMORY_DESCRIPTOR *mm, UINTN sz, UINTN mmsz, UINT32 mmver)
{
@@ -478,7 +351,7 @@ 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) {
@@ -496,7 +369,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);
@@ -540,7 +413,7 @@ bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp, bool exit_bs)
#endif
bi_load_efi_data(kfp, exit_bs);
- size = bi_copymodules(0);
+ size = md_copymodules(0, true);
kernend = roundup(addr + size, PAGE_SIZE);
*kernendp = kernend;
@@ -565,7 +438,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, true);
return (0);
}
diff --git a/stand/efi/loader/copy.c b/stand/efi/loader/copy.c
index 47e613ccc2f3..d5e24439ed49 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.
@@ -201,7 +200,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 +208,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;
}
@@ -287,7 +286,7 @@ COMMAND_SET(staging_slop, "staging_slop", "set staging slop",
#if defined(__i386__) || 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.
*/
@@ -479,7 +478,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 +509,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/framebuffer.c b/stand/efi/loader/framebuffer.c
index d5504c9cff35..9dfe547d7557 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.
@@ -536,6 +535,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..a9377984de2b 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.
@@ -28,11 +27,13 @@
* $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..49434698fa03 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.
@@ -33,6 +32,7 @@
#include <stand.h>
#include <readin.h>
+#include <efi.h>
#ifdef __amd64__
enum {
@@ -43,6 +43,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..5edc06c9e0d5 100644
--- a/stand/efi/loader/main.c
+++ b/stand/efi/loader/main.c
@@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$");
#include <smbios.h>
#include "efizfs.h"
+#include "framebuffer.h"
#include "loader_efi.h"
@@ -203,7 +204,7 @@ 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);
}
@@ -273,7 +274,7 @@ probe_zfs_currdev(uint64_t guid)
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();
@@ -719,7 +720,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 +761,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;
@@ -949,6 +962,9 @@ 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
@@ -1280,15 +1296,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