summaryrefslogtreecommitdiffstats
path: root/sys/boot
diff options
context:
space:
mode:
Diffstat (limited to 'sys/boot')
-rw-r--r--sys/boot/Makefile5
-rw-r--r--sys/boot/Makefile.amd644
-rw-r--r--sys/boot/amd64/Makefile7
-rw-r--r--sys/boot/amd64/Makefile.inc12
-rw-r--r--sys/boot/amd64/efi/Makefile (renamed from sys/boot/i386/efi/Makefile)67
-rw-r--r--sys/boot/amd64/efi/amd64_tramp.S64
-rw-r--r--sys/boot/amd64/efi/autoload.c (renamed from sys/boot/i386/efi/autoload.c)2
-rw-r--r--sys/boot/amd64/efi/bootinfo.c360
-rw-r--r--sys/boot/amd64/efi/conf.c (renamed from sys/boot/i386/efi/conf.c)8
-rw-r--r--sys/boot/amd64/efi/copy.c102
-rw-r--r--sys/boot/amd64/efi/devicename.c (renamed from sys/boot/i386/efi/devicename.c)16
-rw-r--r--sys/boot/amd64/efi/elf64_freebsd.c190
-rw-r--r--sys/boot/amd64/efi/framebuffer.c85
-rw-r--r--sys/boot/amd64/efi/framebuffer.h36
-rw-r--r--sys/boot/amd64/efi/ldscript.amd64 (renamed from sys/boot/i386/efi/ldscript.amd64)24
-rw-r--r--sys/boot/amd64/efi/main.c (renamed from sys/boot/i386/efi/main.c)42
-rw-r--r--sys/boot/amd64/efi/reloc.c107
-rw-r--r--sys/boot/amd64/efi/start.S76
-rw-r--r--sys/boot/amd64/efi/version (renamed from sys/boot/i386/efi/version)0
-rw-r--r--sys/boot/amd64/efi/x86_efi.h49
-rw-r--r--sys/boot/efi/Makefile.inc9
-rw-r--r--sys/boot/efi/include/amd64/efibind.h267
-rw-r--r--sys/boot/efi/include/amd64/pe.h592
-rw-r--r--sys/boot/efi/include/efi.h1
-rw-r--r--sys/boot/efi/include/efigop.h122
-rw-r--r--sys/boot/efi/include/efilib.h2
-rw-r--r--sys/boot/efi/libefi/Makefile9
-rw-r--r--sys/boot/efi/libefi/efinet.c2
-rw-r--r--sys/boot/efi/libefi/efipart.c48
-rw-r--r--sys/boot/efi/libefi/handles.c10
-rw-r--r--sys/boot/ficl/Makefile23
-rw-r--r--sys/boot/ficl/tools.c22
-rw-r--r--sys/boot/ficl/words.c2
-rw-r--r--sys/boot/ficl32/Makefile (renamed from sys/boot/ficl64/Makefile)2
-rw-r--r--sys/boot/forth/beastie.4th5
-rw-r--r--sys/boot/forth/beastie.4th.84
-rw-r--r--sys/boot/forth/loader.conf.54
-rw-r--r--sys/boot/i386/libi386/Makefile3
-rw-r--r--sys/boot/i386/loader/Makefile4
39 files changed, 2274 insertions, 113 deletions
diff --git a/sys/boot/Makefile b/sys/boot/Makefile
index 06cffb1..0d6441d 100644
--- a/sys/boot/Makefile
+++ b/sys/boot/Makefile
@@ -9,9 +9,12 @@ SUBDIR+= ficl
.endif
# Pick the machine-dependent subdir based on the target architecture.
-ADIR= ${MACHINE:S/amd64/i386/:S/powerpc64/powerpc/}
+ADIR= ${MACHINE:S/powerpc64/powerpc/}
.if exists(${.CURDIR}/${ADIR}/.)
SUBDIR+= ${ADIR}
.endif
+.if ${MACHINE} == "amd64"
+SUBDIR+= i386
+.endif
.include <bsd.subdir.mk>
diff --git a/sys/boot/Makefile.amd64 b/sys/boot/Makefile.amd64
index 34ffb6c..2b85283 100644
--- a/sys/boot/Makefile.amd64
+++ b/sys/boot/Makefile.amd64
@@ -4,3 +4,7 @@ SUBDIR+= efi
SUBDIR+= libstand32
SUBDIR+= zfs
SUBDIR+= userboot
+
+.if ${MK_FORTH} != "no"
+SUBDIR+= ficl32
+.endif
diff --git a/sys/boot/amd64/Makefile b/sys/boot/amd64/Makefile
new file mode 100644
index 0000000..d0013fa
--- /dev/null
+++ b/sys/boot/amd64/Makefile
@@ -0,0 +1,7 @@
+# $FreeBSD$
+
+.include <bsd.own.mk>
+
+SUBDIR= efi
+
+.include <bsd.subdir.mk>
diff --git a/sys/boot/amd64/Makefile.inc b/sys/boot/amd64/Makefile.inc
new file mode 100644
index 0000000..ee96a42
--- /dev/null
+++ b/sys/boot/amd64/Makefile.inc
@@ -0,0 +1,12 @@
+# Common defines for all of /sys/boot/amd64/
+#
+# $FreeBSD$
+
+BINDIR?= /boot
+
+# See conf/kern.mk for the correct set of these
+CFLAGS+= -ffreestanding
+CFLAGS+= -mno-mmx -mno-sse -mno-aes -mno-avx -msoft-float
+LDFLAGS+= -nostdlib
+
+.include "../Makefile.inc"
diff --git a/sys/boot/i386/efi/Makefile b/sys/boot/amd64/efi/Makefile
index 5a04466..8802605 100644
--- a/sys/boot/i386/efi/Makefile
+++ b/sys/boot/amd64/efi/Makefile
@@ -1,26 +1,43 @@
# $FreeBSD$
NO_MAN=
-BUILDING_EFI=
.include <bsd.own.mk>
+
+# In-tree GCC does not support __attribute__((ms_abi)).
+.if ${COMPILER_TYPE} != "gcc"
+
MK_SSP= no
PROG= loader.sym
INTERNALPROG=
# architecture-specific loader code
-SRCS= main.c exec.c conf.c vers.c reloc.c start.S elf32_freebsd.c
-SRCS+= i386_copy.c bootinfo.c autoload.c devicename.c efimd.c
-
+SRCS= autoload.c \
+ bootinfo.c \
+ conf.c \
+ copy.c \
+ devicename.c \
+ elf64_freebsd.c \
+ framebuffer.c \
+ main.c \
+ reloc.c \
+ vers.c
+SRCS+= amd64_tramp.S \
+ start.S
+
+CFLAGS+= -fPIC
+CFLAGS+= -I.
CFLAGS+= -I${.CURDIR}/../../efi/include
-CFLAGS+= -I${.CURDIR}/../../efi/include/i386
+CFLAGS+= -I${.CURDIR}/../../efi/include/${MACHINE_CPUARCH}
+CFLAGS+= -I${.CURDIR}/../../../contrib/dev/acpica/include
+CFLAGS+= -I${.CURDIR}/../../..
.if ${MK_FORTH} != "no"
BOOT_FORTH= yes
CFLAGS+= -DBOOT_FORTH
CFLAGS+= -I${.CURDIR}/../../ficl
-CFLAGS+= -I${.CURDIR}/../../ficl/i386
+CFLAGS+= -I${.CURDIR}/../../ficl/${MACHINE_CPUARCH}
LIBFICL= ${.OBJDIR}/../../ficl/libficl.a
.endif
@@ -35,14 +52,14 @@ CFLAGS+= -I${.CURDIR}/../../common
FILES= loader.efi
FILESMODE_loader.efi= ${BINMODE}
-LDSCRIPT= ${.CURDIR}/ldscript.i386
-LDFLAGS= -Wl,-T${LDSCRIPT} -Wl,-Bsymbolic -shared
+LDSCRIPT= ${.CURDIR}/ldscript.${MACHINE_CPUARCH}
+LDFLAGS= -Wl,-T${LDSCRIPT} -Wl,-Bsymbolic -shared -Wl,-znocombreloc
${PROG}: ${LDSCRIPT}
CLEANFILES= vers.c loader.efi
-NEWVERSWHAT= "EFI loader" x86
+NEWVERSWHAT= "EFI loader" ${MACHINE_CPUARCH}
vers.c: ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version
sh ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version ${NEWVERSWHAT}
@@ -50,28 +67,38 @@ vers.c: ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version
OBJCOPY?= objcopy
OBJDUMP?= objdump
+.if ${MACHINE_CPUARCH} == "amd64"
+EFI_TARGET= efi-app-x86_64
+.else
+EFI_TARGET= efi-app-ia32
+.endif
+
loader.efi: loader.sym
if [ `${OBJDUMP} -t ${.ALLSRC} | fgrep '*UND*' | wc -l` != 0 ]; then \
${OBJDUMP} -t ${.ALLSRC} | fgrep '*UND*'; \
exit 1; \
fi
- ${OBJCOPY} -j .data -j .dynamic -j .dynstr -j .dynsym -j .hash \
- -j .rel.dyn -j .reloc -j .sdata -j .text -j set_Xcommand_set \
- --target=efi-app-ia32 ${.ALLSRC} ${.TARGET}
+ ${OBJCOPY} -j .text -j .sdata -j .data \
+ -j .dynamic -j .dynsym -j .rel.dyn \
+ -j .rela.dyn -j .reloc -j .eh_frame -j set_Xcommand_set \
+ --target=${EFI_TARGET} ${.ALLSRC} ${.TARGET}
LIBEFI= ${.OBJDIR}/../../efi/libefi/libefi.a
-LIBSTAND= ${.OBJDIR}/../../libstand32/libstand.a
-CFLAGS+= -I${.CURDIR}/../libi386
-CFLAGS+= -I${.CURDIR}/../btx/lib
+CFLAGS+= -I${.CURDIR}/../../common
DPADD= ${LIBFICL} ${LIBEFI} ${LIBSTAND}
LDADD= ${LIBFICL} ${LIBEFI} ${LIBSTAND}
+.endif # ${COMPILER_TYPE} != "gcc"
+
.include <bsd.prog.mk>
-.if ${MACHINE_CPUARCH} == "amd64"
-CFLAGS+= -I.
-beforedepend ${OBJS}: machine
+beforedepend ${OBJS}: machine x86
+
+CLEANFILES+= machine x86
+
machine:
- ln -sf ${.CURDIR}/../../../i386/include machine
-.endif
+ ln -sf ${.CURDIR}/../../../amd64/include machine
+
+x86:
+ ln -sf ${.CURDIR}/../../../x86/include x86
diff --git a/sys/boot/amd64/efi/amd64_tramp.S b/sys/boot/amd64/efi/amd64_tramp.S
new file mode 100644
index 0000000..c102d92
--- /dev/null
+++ b/sys/boot/amd64/efi/amd64_tramp.S
@@ -0,0 +1,64 @@
+/*-
+ * Copyright (c) 2013 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Benno Rice under sponsorship from
+ * the FreeBSD Foundation.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <machine/asmacros.h>
+
+ .text
+ .globl amd64_tramp
+
+/*
+ * void amd64_tramp(uint64_t stack, void *copy_finish, uint64_t kernend,
+ * uint64_t modulep, uint64_t pagetable, uint64_t entry)
+ */
+amd64_tramp:
+ cli /* Make sure we don't get interrupted. */
+ movq %rdi,%rsp /* Switch to our temporary stack. */
+
+ movq %rdx,%r12 /* Stash the kernel values for later. */
+ movq %rcx,%r13
+ movq %r8,%r14
+ movq %r9,%r15
+
+ callq *%rsi /* Call copy_finish so we're all ready to go. */
+
+ pushq %r12 /* Push kernend. */
+ salq $32,%r13 /* Shift modulep and push it. */
+ pushq %r13
+ pushq %r15 /* Push the entry address. */
+ movq %r14,%cr3 /* Switch page tables. */
+ ret /* "Return" to kernel entry. */
+
+ ALIGN_TEXT
+amd64_tramp_end:
+
+ .data
+ .globl amd64_tramp_size
+amd64_tramp_size:
+ .long amd64_tramp_end-amd64_tramp
diff --git a/sys/boot/i386/efi/autoload.c b/sys/boot/amd64/efi/autoload.c
index 26370d6..efb32d4 100644
--- a/sys/boot/i386/efi/autoload.c
+++ b/sys/boot/amd64/efi/autoload.c
@@ -28,7 +28,7 @@
__FBSDID("$FreeBSD$");
int
-i386_autoload(void)
+x86_efi_autoload(void)
{
return (0);
diff --git a/sys/boot/amd64/efi/bootinfo.c b/sys/boot/amd64/efi/bootinfo.c
new file mode 100644
index 0000000..bf11f5b
--- /dev/null
+++ b/sys/boot/amd64/efi/bootinfo.c
@@ -0,0 +1,360 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * Copyright (c) 2004, 2006 Marcel Moolenaar
+ * Copyright (c) 2014 The FreeBSD Foundation
+ * 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 <stand.h>
+#include <string.h>
+#include <sys/param.h>
+#include <sys/reboot.h>
+#include <sys/linker.h>
+#include <sys/boot.h>
+#include <machine/cpufunc.h>
+#include <machine/metadata.h>
+#include <machine/psl.h>
+#include <machine/specialreg.h>
+
+#include <efi.h>
+#include <efilib.h>
+
+#include "bootstrap.h"
+#include "framebuffer.h"
+#include "x86_efi.h"
+
+UINTN x86_efi_mapkey;
+
+static const char howto_switches[] = "aCdrgDmphsv";
+static int howto_masks[] = {
+ RB_ASKNAME, RB_CDROM, RB_KDB, RB_DFLTROOT, RB_GDB, RB_MULTIPLE,
+ RB_MUTE, RB_PAUSE, RB_SERIAL, RB_SINGLE, RB_VERBOSE
+};
+
+static int
+bi_getboothowto(char *kargs)
+{
+ const char *sw;
+ char *opts;
+ int howto, i;
+
+ howto = 0;
+
+ /* Get the boot options from the environment first. */
+ for (i = 0; howto_names[i].ev != NULL; i++) {
+ if (getenv(howto_names[i].ev) != NULL)
+ howto |= howto_names[i].mask;
+ }
+
+ /* Parse kargs */
+ if (kargs == NULL)
+ return (howto);
+
+ opts = strchr(kargs, '-');
+ while (opts != NULL) {
+ while (*(++opts) != '\0') {
+ sw = strchr(howto_switches, *opts);
+ if (sw == NULL)
+ break;
+ howto |= howto_masks[sw - howto_switches];
+ }
+ opts = strchr(opts, '-');
+ }
+
+ 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 (x86_efi_copyin(ep->ev_name, addr, len) != len)
+ break;
+ addr += len;
+ if (x86_efi_copyin("=", addr, 1) != 1)
+ break;
+ addr++;
+ if (ep->ev_value != NULL) {
+ len = strlen(ep->ev_value);
+ if (x86_efi_copyin(ep->ev_value, addr, len) != len)
+ break;
+ addr += len;
+ }
+ if (x86_efi_copyin("", addr, 1) != 1)
+ break;
+ last = ++addr;
+ }
+
+ if (x86_efi_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) \
+ x86_efi_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) \
+ x86_efi_copyin(s, a, strlen(s) + 1); \
+ a += roundup(strlen(s) + 1, sizeof(uint64_t)); \
+}
+
+#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) \
+ x86_efi_copyin(&s, a, sizeof(s)); \
+ a += roundup(sizeof(s), sizeof(uint64_t)); \
+}
+
+#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) \
+ x86_efi_copyin(mm->md_data, a, mm->md_size); \
+ a += roundup(mm->md_size, sizeof(uint64_t)); \
+}
+
+#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;
+ 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 int
+bi_load_efi_data(struct preloaded_file *kfp)
+{
+ EFI_MEMORY_DESCRIPTOR *mm;
+ EFI_PHYSICAL_ADDRESS addr;
+ EFI_STATUS status;
+ size_t efisz;
+ UINTN mmsz, pages, sz;
+ UINT32 mmver;
+ struct efi_map_header *efihdr;
+ struct efi_fb efifb;
+
+ if (efi_find_framebuffer(&efifb) == 0)
+ file_addmetadata(kfp, MODINFOMD_EFI_FB, sizeof(efifb), &efifb);
+
+ efisz = (sizeof(struct efi_map_header) + 0xf) & ~0xf;
+
+ /*
+ * Allocate enough pages to hold the bootinfo block and the memory
+ * map EFI will return to us. The memory map has an unknown size,
+ * so we have to determine that first. Note that the AllocatePages
+ * call can itself modify the memory map, so we have to take that
+ * into account as well. The changes to the memory map are caused
+ * by splitting a range of free memory into two (AFAICT), so that
+ * one is marked as being loader data.
+ */
+ sz = 0;
+ BS->GetMemoryMap(&sz, NULL, &x86_efi_mapkey, &mmsz, &mmver);
+ sz += mmsz;
+ sz = (sz + 0xf) & ~0xf;
+ pages = EFI_SIZE_TO_PAGES(sz + efisz);
+ status = BS->AllocatePages(AllocateAnyPages, EfiLoaderData, pages,
+ &addr);
+ if (EFI_ERROR(status)) {
+ printf("%s: AllocatePages() returned 0x%lx\n", __func__,
+ (long)status);
+ return (ENOMEM);
+ }
+
+ /*
+ * Read the memory map and stash it after bootinfo. Align the
+ * memory map on a 16-byte boundary (the bootinfo block is page
+ * aligned).
+ */
+ efihdr = (struct efi_map_header *)addr;
+ mm = (void *)((uint8_t *)efihdr + efisz);
+ sz = (EFI_PAGE_SIZE * pages) - efisz;
+ status = BS->GetMemoryMap(&sz, mm, &x86_efi_mapkey, &mmsz, &mmver);
+ if (EFI_ERROR(status)) {
+ printf("%s: GetMemoryMap() returned 0x%lx\n", __func__,
+ (long)status);
+ return (EINVAL);
+ }
+
+ efihdr->memory_size = sz;
+ efihdr->descriptor_size = mmsz;
+ efihdr->descriptor_version = mmver;
+
+ file_addmetadata(kfp, MODINFOMD_EFI_MAP, efisz + sz, efihdr);
+
+ return (0);
+}
+
+/*
+ * Load the information expected by an amd64 kernel.
+ *
+ * - The 'boothowto' argument is constructed.
+ * - The 'bootdev' argument is constructed.
+ * - The 'bootinfo' struct is constructed, and copied into the kernel space.
+ * - The kernel environment is copied into kernel space.
+ * - Module metadata are formatted and placed in kernel space.
+ */
+int
+bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp)
+{
+ struct preloaded_file *xp, *kfp;
+ struct devdesc *rootdev;
+ struct file_metadata *md;
+ vm_offset_t addr;
+ uint64_t kernend;
+ uint64_t envp;
+ vm_offset_t size;
+ char *rootdevname;
+ int howto;
+
+ howto = bi_getboothowto(args);
+
+ /*
+ * Allow the environment variable 'rootdev' to override the supplied
+ * device. This should perhaps go to MI code and/or have $rootdev
+ * tested/set by MI code before launching the kernel.
+ */
+ rootdevname = getenv("rootdev");
+ x86_efi_getdev((void**)(&rootdev), rootdevname, NULL);
+ if (rootdev == NULL) {
+ printf("Can't determine root device.\n");
+ return(EINVAL);
+ }
+
+ /* Try reading the /etc/fstab file to select the root device */
+ getrootmount(x86_efi_fmtdev((void *)rootdev));
+
+ addr = 0;
+ for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) {
+ if (addr < (xp->f_addr + xp->f_size))
+ addr = xp->f_addr + xp->f_size;
+ }
+
+ /* Pad to a page boundary. */
+ addr = roundup(addr, PAGE_SIZE);
+
+ /* Copy our environment. */
+ envp = addr;
+ addr = bi_copyenv(addr);
+
+ /* Pad to a page boundary. */
+ addr = roundup(addr, PAGE_SIZE);
+
+ kfp = file_findfile(NULL, "elf kernel");
+ if (kfp == NULL)
+ kfp = file_findfile(NULL, "elf64 kernel");
+ if (kfp == NULL)
+ panic("can't find kernel file");
+ kernend = 0; /* fill it in later */
+ file_addmetadata(kfp, MODINFOMD_HOWTO, sizeof howto, &howto);
+ file_addmetadata(kfp, MODINFOMD_ENVP, sizeof envp, &envp);
+ file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof kernend, &kernend);
+
+ bi_load_efi_data(kfp);
+
+ /* Figure out the size and location of the metadata. */
+ *modulep = addr;
+ size = bi_copymodules(0);
+ kernend = roundup(addr + size, PAGE_SIZE);
+ *kernendp = kernend;
+
+ /* patch MODINFOMD_KERNEND */
+ md = file_findmetadata(kfp, MODINFOMD_KERNEND);
+ bcopy(&kernend, md->md_data, sizeof kernend);
+
+ /* Copy module list and metadata. */
+ (void)bi_copymodules(addr);
+
+ return (0);
+}
diff --git a/sys/boot/i386/efi/conf.c b/sys/boot/amd64/efi/conf.c
index 13c2145..0e67b6b 100644
--- a/sys/boot/i386/efi/conf.c
+++ b/sys/boot/amd64/efi/conf.c
@@ -52,20 +52,12 @@ struct netif_driver *netif_drivers[] = {
NULL
};
-#ifdef notyet
extern struct file_format amd64_elf;
extern struct file_format amd64_elf_obj;
-#endif
-extern struct file_format i386_elf;
-extern struct file_format i386_elf_obj;
struct file_format *file_formats[] = {
-#ifdef notyet
&amd64_elf,
&amd64_elf_obj,
-#endif
- &i386_elf,
- &i386_elf_obj,
NULL
};
diff --git a/sys/boot/amd64/efi/copy.c b/sys/boot/amd64/efi/copy.c
new file mode 100644
index 0000000..c6cc349
--- /dev/null
+++ b/sys/boot/amd64/efi/copy.c
@@ -0,0 +1,102 @@
+/*-
+ * Copyright (c) 2013 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Benno Rice under sponsorship from
+ * the FreeBSD Foundation.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+
+#include <stand.h>
+#include <bootstrap.h>
+
+#include <efi.h>
+#include <efilib.h>
+
+#define STAGE_PAGES 8192 /* 32MB */
+
+EFI_PHYSICAL_ADDRESS staging;
+int stage_offset_set = 0;
+ssize_t stage_offset;
+
+int
+x86_efi_copy_init(void)
+{
+ EFI_STATUS status;
+
+ status = BS->AllocatePages(AllocateAnyPages, EfiLoaderData,
+ STAGE_PAGES, &staging);
+ if (EFI_ERROR(status)) {
+ printf("failed to allocate staging area: %lu\n",
+ (unsigned long)(status & EFI_ERROR_MASK));
+ return (status);
+ }
+
+ return (0);
+}
+
+ssize_t
+x86_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;
+ }
+
+ bcopy(src, (void *)(dest + stage_offset), len);
+ return (len);
+}
+
+ssize_t
+x86_efi_copyout(const vm_offset_t src, void *dest, const size_t len)
+{
+
+ bcopy((void *)(src + stage_offset), dest, len);
+ return (len);
+}
+
+
+ssize_t
+x86_efi_readin(const int fd, vm_offset_t dest, const size_t len)
+{
+
+ return (read(fd, (void *)(dest + stage_offset), len));
+}
+
+void
+x86_efi_copy_finish(void)
+{
+ uint64_t *src, *dst, *last;
+
+ src = (uint64_t *)staging;
+ dst = (uint64_t *)(staging - stage_offset);
+ last = (uint64_t *)(staging + STAGE_PAGES * EFI_PAGE_SIZE);
+
+ while (src < last)
+ *dst++ = *src++;
+}
diff --git a/sys/boot/i386/efi/devicename.c b/sys/boot/amd64/efi/devicename.c
index c3d9062..aa43628 100644
--- a/sys/boot/i386/efi/devicename.c
+++ b/sys/boot/amd64/efi/devicename.c
@@ -36,7 +36,7 @@ __FBSDID("$FreeBSD$");
#include <efi.h>
#include <efilib.h>
-static int i386_parsedev(struct devdesc **, const char *, const char **);
+static int x86_efi_parsedev(struct devdesc **, const char *, const char **);
/*
* Point (dev) at an allocated device specifier for the device matching the
@@ -44,7 +44,7 @@ static int i386_parsedev(struct devdesc **, const char *, const char **);
* use that. If not, use the default device.
*/
int
-i386_getdev(void **vdev, const char *devspec, const char **path)
+x86_efi_getdev(void **vdev, const char *devspec, const char **path)
{
struct devdesc **dev = (struct devdesc **)vdev;
int rv;
@@ -54,14 +54,14 @@ i386_getdev(void **vdev, const char *devspec, const char **path)
* use the current device instead.
*/
if (devspec == NULL || *devspec == '/' || !strchr(devspec, ':')) {
- rv = i386_parsedev(dev, getenv("currdev"), NULL);
+ rv = x86_efi_parsedev(dev, getenv("currdev"), NULL);
if (rv == 0 && path != NULL)
*path = devspec;
return (rv);
}
/* Parse the device name off the beginning of the devspec. */
- return (i386_parsedev(dev, devspec, path));
+ return (x86_efi_parsedev(dev, devspec, path));
}
/*
@@ -78,7 +78,7 @@ i386_getdev(void **vdev, const char *devspec, const char **path)
* fs<unit>:
*/
static int
-i386_parsedev(struct devdesc **dev, const char *devspec, const char **path)
+x86_efi_parsedev(struct devdesc **dev, const char *devspec, const char **path)
{
struct devdesc *idev;
struct devsw *dv;
@@ -132,7 +132,7 @@ i386_parsedev(struct devdesc **dev, const char *devspec, const char **path)
}
char *
-i386_fmtdev(void *vdev)
+x86_efi_fmtdev(void *vdev)
{
struct devdesc *dev = (struct devdesc *)vdev;
static char buf[32]; /* XXX device length constant? */
@@ -154,12 +154,12 @@ i386_fmtdev(void *vdev)
* Set currdev to suit the value being supplied in (value)
*/
int
-i386_setcurrdev(struct env_var *ev, int flags, const void *value)
+x86_efi_setcurrdev(struct env_var *ev, int flags, const void *value)
{
struct devdesc *ncurr;
int rv;
- rv = i386_parsedev(&ncurr, value, NULL);
+ rv = x86_efi_parsedev(&ncurr, value, NULL);
if (rv != 0)
return(rv);
diff --git a/sys/boot/amd64/efi/elf64_freebsd.c b/sys/boot/amd64/efi/elf64_freebsd.c
new file mode 100644
index 0000000..0fb82b0
--- /dev/null
+++ b/sys/boot/amd64/efi/elf64_freebsd.c
@@ -0,0 +1,190 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * Copyright (c) 2014 The FreeBSD Foundation
+ * 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$");
+
+#define __ELF_WORD_SIZE 64
+#include <sys/param.h>
+#include <sys/exec.h>
+#include <sys/linker.h>
+#include <string.h>
+#include <machine/elf.h>
+#include <stand.h>
+
+#include <efi.h>
+#include <efilib.h>
+
+#include "bootstrap.h"
+
+#include "platform/acfreebsd.h"
+#include "acconfig.h"
+#define ACPI_SYSTEM_XFACE
+#include "actypes.h"
+#include "actbl.h"
+
+#include "x86_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);
+
+static int elf64_exec(struct preloaded_file *amp);
+static int elf64_obj_exec(struct preloaded_file *amp);
+
+struct file_format amd64_elf = { elf64_loadfile, elf64_exec };
+struct file_format amd64_elf_obj = { elf64_obj_loadfile, elf64_obj_exec };
+
+#define PG_V 0x001
+#define PG_RW 0x002
+#define PG_U 0x004
+#define PG_PS 0x080
+
+typedef u_int64_t p4_entry_t;
+typedef u_int64_t p3_entry_t;
+typedef u_int64_t p2_entry_t;
+static p4_entry_t *PT4;
+static p3_entry_t *PT3;
+static p2_entry_t *PT2;
+
+static void (*trampoline)(uint64_t stack, void *copy_finish, uint64_t kernend,
+ uint64_t modulep, p4_entry_t *pagetable,
+ uint64_t entry);
+
+extern uintptr_t amd64_tramp;
+extern uint32_t amd64_tramp_size;
+
+/*
+ * 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
+elf64_exec(struct preloaded_file *fp)
+{
+ struct file_metadata *md;
+ Elf_Ehdr *ehdr;
+ vm_offset_t modulep, kernend, trampcode, trampstack;
+ int err, i;
+ ACPI_TABLE_RSDP *rsdp;
+ char buf[24];
+ int revision;
+ EFI_STATUS status;
+
+ 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);
+ ehdr = (Elf_Ehdr *)&(md->md_data);
+
+ trampcode = (vm_offset_t)0x0000000040000000;
+ err = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, 1,
+ (EFI_PHYSICAL_ADDRESS *)&trampcode);
+ bzero((void *)trampcode, EFI_PAGE_SIZE);
+ trampstack = trampcode + EFI_PAGE_SIZE - 8;
+ bcopy((void *)&amd64_tramp, (void *)trampcode, amd64_tramp_size);
+ trampoline = (void *)trampcode;
+
+ PT4 = (p4_entry_t *)0x0000000040000000;
+ err = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, 3,
+ (EFI_PHYSICAL_ADDRESS *)&PT4);
+ bzero(PT4, 3 * EFI_PAGE_SIZE);
+
+ PT3 = &PT4[512];
+ PT2 = &PT3[512];
+
+ /*
+ * This is kinda brutal, but every single 1GB VM memory segment points
+ * to the same first 1GB of physical memory. But it is more than
+ * adequate.
+ */
+ for (i = 0; i < 512; i++) {
+ /* Each slot of the L4 pages points to the same L3 page. */
+ PT4[i] = (p4_entry_t)PT3;
+ PT4[i] |= PG_V | PG_RW | PG_U;
+
+ /* Each slot of the L3 pages points to the same L2 page. */
+ PT3[i] = (p3_entry_t)PT2;
+ PT3[i] |= PG_V | PG_RW | PG_U;
+
+ /* The L2 page slots are mapped with 2MB pages for 1GB. */
+ PT2[i] = i * (2 * 1024 * 1024);
+ PT2[i] |= PG_V | PG_RW | PG_PS | PG_U;
+ }
+
+ printf("Start @ 0x%lx ...\n", ehdr->e_entry);
+
+ err = bi_load(fp->f_args, &modulep, &kernend);
+ if (err != 0)
+ return(err);
+
+ status = BS->ExitBootServices(IH, x86_efi_mapkey);
+ if (EFI_ERROR(status)) {
+ printf("%s: ExitBootServices() returned 0x%lx\n", __func__,
+ (long)status);
+ return (EINVAL);
+ }
+
+ dev_cleanup();
+
+ trampoline(trampstack, x86_efi_copy_finish, kernend, modulep, PT4,
+ ehdr->e_entry);
+
+ panic("exec returned");
+}
+
+static int
+elf64_obj_exec(struct preloaded_file *fp)
+{
+ return (EFTYPE);
+}
diff --git a/sys/boot/amd64/efi/framebuffer.c b/sys/boot/amd64/efi/framebuffer.c
new file mode 100644
index 0000000..90bf992
--- /dev/null
+++ b/sys/boot/amd64/efi/framebuffer.c
@@ -0,0 +1,85 @@
+/*-
+ * Copyright (c) 2013 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Benno Rice under sponsorship from
+ * the FreeBSD Foundation.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+
+#include <efi.h>
+#include <efilib.h>
+#include <machine/metadata.h>
+
+static EFI_GUID gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
+
+int
+efi_find_framebuffer(struct efi_fb *efifb)
+{
+ EFI_GRAPHICS_OUTPUT *gop;
+ EFI_STATUS status;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *mode;
+ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info;
+
+ status = BS->LocateProtocol(&gop_guid, NULL, (VOID **)&gop);
+ if (EFI_ERROR(status))
+ return (1);
+
+ mode = gop->Mode;
+ info = gop->Mode->Info;
+
+ efifb->fb_addr = mode->FrameBufferBase;
+ efifb->fb_size = mode->FrameBufferSize;
+ efifb->fb_height = info->VerticalResolution;
+ efifb->fb_width = info->HorizontalResolution;
+ efifb->fb_stride = info->PixelsPerScanLine;
+
+ switch (info->PixelFormat) {
+ case PixelRedGreenBlueReserved8BitPerColor:
+ efifb->fb_mask_red = 0x000000ff;
+ efifb->fb_mask_green = 0x0000ff00;
+ efifb->fb_mask_blue = 0x00ff0000;
+ efifb->fb_mask_reserved = 0xff000000;
+ break;
+ case PixelBlueGreenRedReserved8BitPerColor:
+ efifb->fb_mask_red = 0x00ff0000;
+ efifb->fb_mask_green = 0x0000ff00;
+ efifb->fb_mask_blue = 0x000000ff;
+ efifb->fb_mask_reserved = 0xff000000;
+ break;
+ case PixelBitMask:
+ efifb->fb_mask_red = info->PixelInformation.RedMask;
+ efifb->fb_mask_green = info->PixelInformation.GreenMask;
+ efifb->fb_mask_blue = info->PixelInformation.BlueMask;
+ efifb->fb_mask_reserved =
+ info->PixelInformation.ReservedMask;
+ break;
+ default:
+ return (1);
+ }
+ return (0);
+}
diff --git a/sys/boot/amd64/efi/framebuffer.h b/sys/boot/amd64/efi/framebuffer.h
new file mode 100644
index 0000000..2ec9017
--- /dev/null
+++ b/sys/boot/amd64/efi/framebuffer.h
@@ -0,0 +1,36 @@
+/*-
+ * Copyright (c) 2013 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Benno Rice under sponsorship from
+ * the FreeBSD Foundation.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _EFIFB_H_
+#define _EFIFB_H_
+
+int efi_find_framebuffer(struct efi_fb *efifb);
+
+#endif /* _EFIFB_H_ */
diff --git a/sys/boot/i386/efi/ldscript.amd64 b/sys/boot/amd64/efi/ldscript.amd64
index face49e..14e1f06 100644
--- a/sys/boot/i386/efi/ldscript.amd64
+++ b/sys/boot/amd64/efi/ldscript.amd64
@@ -7,11 +7,13 @@ SECTIONS
/* Read-only sections, merged into text segment: */
. = 0;
ImageBase = .;
- . = SIZEOF_HEADERS;
+ .hash : { *(.hash) } /* this MUST come first! */
. = ALIGN(4096);
- .eh_frame : {
+ .eh_frame :
+ {
*(.eh_frame)
- }
+ }
+ . = ALIGN(4096);
.text : {
*(.text .stub .text.* .gnu.linkonce.t.*)
/* .gnu.warning sections are handled specially by elf32.em. */
@@ -51,24 +53,14 @@ SECTIONS
.dynamic : { *(.dynamic) }
. = ALIGN(4096);
.rela.dyn : {
- *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
- *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
- *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
+ *(.rela.data*)
*(.rela.got)
- *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*)
- *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*)
- *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*)
- *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*)
- *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
- *(.rela.plt)
- *(.relset_*)
- *(.rela.dyn .rela.dyn.*)
+ *(.rela.stab)
+ *(.relaset_*)
}
. = ALIGN(4096);
.reloc : { *(.reloc) }
. = ALIGN(4096);
- .hash : { *(.hash) }
- . = ALIGN(4096);
.dynsym : { *(.dynsym) }
. = ALIGN(4096);
.dynstr : { *(.dynstr) }
diff --git a/sys/boot/i386/efi/main.c b/sys/boot/amd64/efi/main.c
index 1ea5c24..d1ea9c3 100644
--- a/sys/boot/i386/efi/main.c
+++ b/sys/boot/amd64/efi/main.c
@@ -36,7 +36,7 @@ __FBSDID("$FreeBSD$");
#include <efilib.h>
#include <bootstrap.h>
-#include "../libi386/libi386.h"
+#include "x86_efi.h"
extern char bootprog_name[];
extern char bootprog_rev[];
@@ -61,7 +61,7 @@ main(int argc, CHAR16 *argv[])
EFI_LOADED_IMAGE *img;
int i;
- /*
+ /*
* XXX Chicken-and-egg problem; we want to have console output
* early, but some console attributes may depend on reading from
* eg. the boot device, which we can't do yet. We can use
@@ -69,6 +69,11 @@ main(int argc, CHAR16 *argv[])
*/
cons_probe();
+ if (x86_efi_copy_init()) {
+ printf("failed to allocate staging area\n");
+ return (EFI_BUFFER_TOO_SMALL);
+ }
+
/*
* March through the device switch probing for things.
*/
@@ -106,18 +111,18 @@ main(int argc, CHAR16 *argv[])
*/
BS->SetWatchdogTimer(0, 0, 0, NULL);
- env_setenv("currdev", EV_VOLATILE, i386_fmtdev(&currdev),
- i386_setcurrdev, env_nounset);
- env_setenv("loaddev", EV_VOLATILE, i386_fmtdev(&currdev), env_noset,
+ env_setenv("currdev", EV_VOLATILE, x86_efi_fmtdev(&currdev),
+ x86_efi_setcurrdev, env_nounset);
+ env_setenv("loaddev", EV_VOLATILE, x86_efi_fmtdev(&currdev), env_noset,
env_nounset);
setenv("LINES", "24", 1); /* optional */
-
- archsw.arch_autoload = i386_autoload;
- archsw.arch_getdev = i386_getdev;
- archsw.arch_copyin = i386_copyin;
- archsw.arch_copyout = i386_copyout;
- archsw.arch_readin = i386_readin;
+
+ archsw.arch_autoload = x86_efi_autoload;
+ archsw.arch_getdev = x86_efi_getdev;
+ archsw.arch_copyin = x86_efi_copyin;
+ archsw.arch_copyout = x86_efi_copyout;
+ archsw.arch_readin = x86_efi_readin;
interact(); /* doesn't return */
@@ -195,7 +200,7 @@ command_memmap(int argc, char *argv[])
ndesc = sz / dsz;
printf("%23s %12s %12s %8s %4s\n",
"Type", "Physical", "Virtual", "#Pages", "Attr");
-
+
for (i = 0, p = map; i < ndesc;
i++, p = NextMemoryDescriptor(p, dsz)) {
printf("%23s %012lx %012lx %08lx ",
@@ -265,7 +270,7 @@ command_configuration(int argc, char *argv[])
}
return CMD_OK;
-}
+}
COMMAND_SET(mode, "mode", "change or display text modes", command_mode);
@@ -273,7 +278,8 @@ COMMAND_SET(mode, "mode", "change or display text modes", command_mode);
static int
command_mode(int argc, char *argv[])
{
- unsigned int cols, rows, mode;
+ UINTN cols, rows;
+ unsigned int mode;
int i;
char *cp;
char rowenv[8];
@@ -298,7 +304,7 @@ command_mode(int argc, char *argv[])
printf("couldn't set mode %d\n", mode);
return (CMD_ERROR);
}
- sprintf(rowenv, "%d", rows);
+ sprintf(rowenv, "%u", (unsigned)rows);
setenv("LINES", rowenv, 1);
return (CMD_OK);
@@ -308,7 +314,8 @@ command_mode(int argc, char *argv[])
status = conout->QueryMode(conout, i, &cols, &rows);
if (EFI_ERROR(status))
break;
- printf("Mode %d: %d columns, %d rows\n", i, cols, rows);
+ printf("Mode %d: %u columns, %u rows\n", i, (unsigned)cols,
+ (unsigned)rows);
}
if (i != 0)
@@ -327,8 +334,7 @@ command_nvram(int argc, char *argv[])
CHAR16 *data;
EFI_STATUS status;
EFI_GUID varguid = { 0,0,0,{0,0,0,0,0,0,0,0} };
- unsigned int varsz;
- unsigned int datasz;
+ UINTN varsz, datasz;
SIMPLE_TEXT_OUTPUT_INTERFACE *conout;
int i;
diff --git a/sys/boot/amd64/efi/reloc.c b/sys/boot/amd64/efi/reloc.c
new file mode 100644
index 0000000..98bcf8e
--- /dev/null
+++ b/sys/boot/amd64/efi/reloc.c
@@ -0,0 +1,107 @@
+/*-
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <elf.h>
+#include <efi.h>
+#include <bootstrap.h>
+
+#ifdef __i386__
+#define ElfW_Rel Elf32_Rel
+#define ElfW_Dyn Elf32_Dyn
+#define ELFW_R_TYPE ELF32_R_TYPE
+#elif __amd64__
+#define ElfW_Rel Elf64_Rel
+#define ElfW_Dyn Elf64_Dyn
+#define ELFW_R_TYPE ELF64_R_TYPE
+#endif
+
+/*
+ * A simple relocator for IA32/AMD64 EFI binaries.
+ */
+EFI_STATUS
+_reloc(unsigned long ImageBase, ElfW_Dyn *dynamic, EFI_HANDLE image_handle,
+ EFI_SYSTEM_TABLE *system_table)
+{
+ unsigned long relsz, relent;
+ unsigned long *newaddr;
+ ElfW_Rel *rel;
+ ElfW_Dyn *dynp;
+
+ /*
+ * Find the relocation address, its size and the relocation entry.
+ */
+ relsz = 0;
+ relent = 0;
+ for (dynp = dynamic; dynp->d_tag != DT_NULL; dynp++) {
+ switch (dynp->d_tag) {
+ case DT_REL:
+ case DT_RELA:
+ rel = (ElfW_Rel *) ((unsigned long) dynp->d_un.d_ptr +
+ ImageBase);
+ break;
+ case DT_RELSZ:
+ case DT_RELASZ:
+ relsz = dynp->d_un.d_val;
+ break;
+ case DT_RELENT:
+ case DT_RELAENT:
+ relent = dynp->d_un.d_val;
+ break;
+ default:
+ break;
+ }
+ }
+
+ /*
+ * Perform the actual relocation.
+ * XXX: We are reusing code for the amd64 version of this, but
+ * we must make sure the relocation types are the same.
+ */
+ CTASSERT(R_386_NONE == R_X86_64_NONE);
+ CTASSERT(R_386_RELATIVE == R_X86_64_RELATIVE);
+ for (; relsz > 0; relsz -= relent) {
+ switch (ELFW_R_TYPE(rel->r_info)) {
+ case R_386_NONE:
+ /* No relocation needs be performed. */
+ break;
+ case R_386_RELATIVE:
+ /* Address relative to the base address. */
+ newaddr = (unsigned long *)(ImageBase + rel->r_offset);
+ *newaddr += ImageBase;
+ break;
+ default:
+ /* XXX: do we need other relocations ? */
+ break;
+ }
+ rel = (ElfW_Rel *) ((caddr_t) rel + relent);
+ }
+
+ return (EFI_SUCCESS);
+}
diff --git a/sys/boot/amd64/efi/start.S b/sys/boot/amd64/efi/start.S
new file mode 100644
index 0000000..beaeeff
--- /dev/null
+++ b/sys/boot/amd64/efi/start.S
@@ -0,0 +1,76 @@
+/*-
+ * Copyright (C) 1999 Hewlett-Packard Co.
+ * Contributed by David Mosberger <davidm@hpl.hp.com>.
+ * Copyright (C) 2005 Intel Co.
+ * Contributed by Fenghua Yu <fenghua.yu@intel.com>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hewlett-Packard Co. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT
+ * OWNER 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.
+ */
+
+/*
+ * crt0-efi-x86_64.S - x86_64 EFI startup code.
+ * $FreeBSD$
+ */
+
+ .text
+ .align 4
+
+ .globl _start
+_start:
+ subq $8, %rsp
+ pushq %rcx
+ pushq %rdx
+
+0:
+ lea ImageBase(%rip), %rdi
+ lea _DYNAMIC(%rip), %rsi
+
+ popq %rcx
+ popq %rdx
+ pushq %rcx
+ pushq %rdx
+ call _reloc
+
+ popq %rdi
+ popq %rsi
+
+ call efi_main
+ addq $8, %rsp
+
+.exit:
+ ret
+
+ /*
+ * hand-craft a dummy .reloc section so EFI knows it's a relocatable
+ * executable:
+ */
+
+ .data
+ .section .reloc, "a"
+ .long 0
+ .long 10
+ .word 0
diff --git a/sys/boot/i386/efi/version b/sys/boot/amd64/efi/version
index 3a4c47c..3a4c47c 100644
--- a/sys/boot/i386/efi/version
+++ b/sys/boot/amd64/efi/version
diff --git a/sys/boot/amd64/efi/x86_efi.h b/sys/boot/amd64/efi/x86_efi.h
new file mode 100644
index 0000000..73a61c8
--- /dev/null
+++ b/sys/boot/amd64/efi/x86_efi.h
@@ -0,0 +1,49 @@
+/*-
+ * Copyright (c) 2013 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Benno Rice under sponsorship from
+ * the FreeBSD Foundation.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _X86_EFI_COPY_H_
+#define _X86_EFI_COPY_H_
+
+int x86_efi_autoload(void);
+
+int x86_efi_getdev(void **vdev, const char *devspec, const char **path);
+char *x86_efi_fmtdev(void *vdev);
+int x86_efi_setcurrdev(struct env_var *ev, int flags, const void *value);
+
+int x86_efi_copy_init(void);
+void x86_efi_copy_finish(void);
+
+ssize_t x86_efi_copyin(const void *src, vm_offset_t dest, const size_t len);
+ssize_t x86_efi_copyout(const vm_offset_t src, void *dest, const size_t len);
+ssize_t x86_efi_readin(const int fd, vm_offset_t dest, const size_t len);
+
+extern UINTN x86_efi_mapkey;
+
+#endif /* _X86_EFI_COPY_H_ */
diff --git a/sys/boot/efi/Makefile.inc b/sys/boot/efi/Makefile.inc
index 7446d31..29ebae4 100644
--- a/sys/boot/efi/Makefile.inc
+++ b/sys/boot/efi/Makefile.inc
@@ -2,17 +2,10 @@
BINDIR?= /boot
-.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64"
+.if ${MACHINE_CPUARCH} == "i386"
CFLAGS+= -march=i386
.endif
-.if ${MACHINE_CPUARCH} == "amd64"
-CFLAGS+= -m32
-ACFLAGS+= -m32
-LDFLAGS+= -m elf_i386_fbsd
-AFLAGS+= --32
-.endif
-
# Options used when building app-specific efi components
CFLAGS+= -ffreestanding -fshort-wchar -Wformat
LDFLAGS+= -nostdlib
diff --git a/sys/boot/efi/include/amd64/efibind.h b/sys/boot/efi/include/amd64/efibind.h
new file mode 100644
index 0000000..1905596
--- /dev/null
+++ b/sys/boot/efi/include/amd64/efibind.h
@@ -0,0 +1,267 @@
+/* $FreeBSD$ */
+/*++
+
+Copyright (c) 1999 - 2003 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+Module Name:
+
+ efefind.h
+
+Abstract:
+
+ EFI to compile bindings
+
+
+
+
+Revision History
+
+--*/
+
+#pragma pack()
+
+
+#ifdef __FreeBSD__
+#include <sys/stdint.h>
+#else
+//
+// Basic int types of various widths
+//
+
+#if (__STDC_VERSION__ < 199901L )
+
+ // No ANSI C 1999/2000 stdint.h integer width declarations
+
+ #if _MSC_EXTENSIONS
+
+ // Use Microsoft C compiler integer width declarations
+
+ typedef unsigned __int64 uint64_t;
+ typedef __int64 int64_t;
+ typedef unsigned __int32 uint32_t;
+ typedef __int32 int32_t;
+ typedef unsigned short uint16_t;
+ typedef short int16_t;
+ typedef unsigned char uint8_t;
+ typedef char int8_t;
+ #else
+ #ifdef UNIX_LP64
+
+ // Use LP64 programming model from C_FLAGS for integer width declarations
+
+ typedef unsigned long uint64_t;
+ typedef long int64_t;
+ typedef unsigned int uint32_t;
+ typedef int int32_t;
+ typedef unsigned short uint16_t;
+ typedef short int16_t;
+ typedef unsigned char uint8_t;
+ typedef char int8_t;
+ #else
+
+ // Assume P64 programming model from C_FLAGS for integer width declarations
+
+ typedef unsigned long long uint64_t;
+ typedef long long int64_t;
+ typedef unsigned int uint32_t;
+ typedef int int32_t;
+ typedef unsigned short uint16_t;
+ typedef short int16_t;
+ typedef unsigned char uint8_t;
+ typedef char int8_t;
+ #endif
+ #endif
+#endif
+#endif /* __FreeBSD__ */
+
+//
+// Basic EFI types of various widths
+//
+
+typedef uint64_t UINT64;
+typedef int64_t INT64;
+
+#ifndef _BASETSD_H_
+ typedef uint32_t UINT32;
+ typedef int32_t INT32;
+#endif
+
+typedef uint16_t UINT16;
+typedef int16_t INT16;
+typedef uint8_t UINT8;
+typedef int8_t INT8;
+
+
+#undef VOID
+#define VOID void
+
+
+typedef int64_t INTN;
+typedef uint64_t UINTN;
+
+#ifdef EFI_NT_EMULATOR
+ #define POST_CODE(_Data)
+#else
+ #ifdef EFI_DEBUG
+#define POST_CODE(_Data) __asm mov eax,(_Data) __asm out 0x80,al
+ #else
+ #define POST_CODE(_Data)
+ #endif
+#endif
+
+#define EFIERR(a) (0x8000000000000000 | a)
+#define EFI_ERROR_MASK 0x8000000000000000
+#define EFIERR_OEM(a) (0xc000000000000000 | a)
+
+
+#define BAD_POINTER 0xFBFBFBFBFBFBFBFB
+#define MAX_ADDRESS 0xFFFFFFFFFFFFFFFF
+
+#define BREAKPOINT() __asm { int 3 }
+
+//
+// Pointers must be aligned to these address to function
+//
+
+#define MIN_ALIGNMENT_SIZE 4
+
+#define ALIGN_VARIABLE(Value ,Adjustment) \
+ (UINTN)Adjustment = 0; \
+ if((UINTN)Value % MIN_ALIGNMENT_SIZE) \
+ (UINTN)Adjustment = MIN_ALIGNMENT_SIZE - ((UINTN)Value % MIN_ALIGNMENT_SIZE); \
+ Value = (UINTN)Value + (UINTN)Adjustment
+
+
+//
+// Define macros to build data structure signatures from characters.
+//
+
+#define EFI_SIGNATURE_16(A,B) ((A) | (B<<8))
+#define EFI_SIGNATURE_32(A,B,C,D) (EFI_SIGNATURE_16(A,B) | (EFI_SIGNATURE_16(C,D) << 16))
+#define EFI_SIGNATURE_64(A,B,C,D,E,F,G,H) (EFI_SIGNATURE_32(A,B,C,D) | ((UINT64)(EFI_SIGNATURE_32(E,F,G,H)) << 32))
+
+//
+// EFIAPI - prototype calling convention for EFI function pointers
+// BOOTSERVICE - prototype for implementation of a boot service interface
+// RUNTIMESERVICE - prototype for implementation of a runtime service interface
+// RUNTIMEFUNCTION - prototype for implementation of a runtime function that is not a service
+// RUNTIME_CODE - pragma macro for declaring runtime code
+//
+
+#ifdef __amd64__
+#define EFIAPI __attribute__((ms_abi))
+#endif
+
+#ifndef EFIAPI // Forces EFI calling conventions reguardless of compiler options
+ #if _MSC_EXTENSIONS
+ #define EFIAPI __cdecl // Force C calling convention for Microsoft C compiler
+ #else
+ #define EFIAPI // Substitute expresion to force C calling convention
+ #endif
+#endif
+
+#define BOOTSERVICE
+//#define RUNTIMESERVICE(proto,a) alloc_text("rtcode",a); proto a
+//#define RUNTIMEFUNCTION(proto,a) alloc_text("rtcode",a); proto a
+#define RUNTIMESERVICE
+#define RUNTIMEFUNCTION
+
+
+#define RUNTIME_CODE(a) alloc_text("rtcode", a)
+#define BEGIN_RUNTIME_DATA() data_seg("rtdata")
+#define END_RUNTIME_DATA() data_seg("")
+
+#define VOLATILE volatile
+
+#define MEMORY_FENCE()
+
+#ifdef EFI_NO_INTERFACE_DECL
+ #define EFI_FORWARD_DECLARATION(x)
+ #define EFI_INTERFACE_DECL(x)
+#else
+ #define EFI_FORWARD_DECLARATION(x) typedef struct _##x x
+ #define EFI_INTERFACE_DECL(x) typedef struct x
+#endif
+
+#ifdef EFI_NT_EMULATOR
+
+//
+// To help ensure proper coding of integrated drivers, they are
+// compiled as DLLs. In NT they require a dll init entry pointer.
+// The macro puts a stub entry point into the DLL so it will load.
+//
+
+#define EFI_DRIVER_ENTRY_POINT(InitFunction) \
+ EFI_STATUS \
+ InitFunction ( \
+ EFI_HANDLE ImageHandle, \
+ EFI_SYSTEM_TABLE *SystemTable \
+ ); \
+ \
+ UINTN \
+ __stdcall \
+ _DllMainCRTStartup ( \
+ UINTN Inst, \
+ UINTN reason_for_call, \
+ VOID *rserved \
+ ) \
+ { \
+ return 1; \
+ } \
+ \
+ int \
+ __declspec( dllexport ) \
+ __cdecl \
+ InitializeDriver ( \
+ void *ImageHandle, \
+ void *SystemTable \
+ ) \
+ { \
+ return InitFunction(ImageHandle, SystemTable); \
+ }
+
+
+ #define LOAD_INTERNAL_DRIVER(_if, type, name, entry) \
+ (_if)->LoadInternal(type, name, NULL)
+
+#else // EFI_NT_EMULATOR
+
+//
+// When build similiar to FW, then link everything together as
+// one big module.
+//
+
+ #define EFI_DRIVER_ENTRY_POINT(InitFunction)
+
+ #define LOAD_INTERNAL_DRIVER(_if, type, name, entry) \
+ (_if)->LoadInternal(type, name, entry)
+
+#endif // EFI_FW_NT
+
+#ifdef __FreeBSD__
+#define INTERFACE_DECL(x) struct x
+#else
+//
+// Some compilers don't support the forward reference construct:
+// typedef struct XXXXX
+//
+// The following macro provide a workaround for such cases.
+//
+#ifdef NO_INTERFACE_DECL
+#define INTERFACE_DECL(x)
+#else
+#define INTERFACE_DECL(x) typedef struct x
+#endif
+#endif /* __FreeBSD__ */
+
+#if _MSC_EXTENSIONS
+#pragma warning ( disable : 4731 ) // Suppress warnings about modification of EBP
+#endif
+
diff --git a/sys/boot/efi/include/amd64/pe.h b/sys/boot/efi/include/amd64/pe.h
new file mode 100644
index 0000000..1120464
--- /dev/null
+++ b/sys/boot/efi/include/amd64/pe.h
@@ -0,0 +1,592 @@
+/* $FreeBSD$ */
+/*
+ PE32+ header file
+ */
+#ifndef _PE_H
+#define _PE_H
+
+#define IMAGE_DOS_SIGNATURE 0x5A4D // MZ
+#define IMAGE_OS2_SIGNATURE 0x454E // NE
+#define IMAGE_OS2_SIGNATURE_LE 0x454C // LE
+#define IMAGE_NT_SIGNATURE 0x00004550 // PE00
+#define IMAGE_EDOS_SIGNATURE 0x44454550 // PEED
+
+
+typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header
+ UINT16 e_magic; // Magic number
+ UINT16 e_cblp; // Bytes on last page of file
+ UINT16 e_cp; // Pages in file
+ UINT16 e_crlc; // Relocations
+ UINT16 e_cparhdr; // Size of header in paragraphs
+ UINT16 e_minalloc; // Minimum extra paragraphs needed
+ UINT16 e_maxalloc; // Maximum extra paragraphs needed
+ UINT16 e_ss; // Initial (relative) SS value
+ UINT16 e_sp; // Initial SP value
+ UINT16 e_csum; // Checksum
+ UINT16 e_ip; // Initial IP value
+ UINT16 e_cs; // Initial (relative) CS value
+ UINT16 e_lfarlc; // File address of relocation table
+ UINT16 e_ovno; // Overlay number
+ UINT16 e_res[4]; // Reserved words
+ UINT16 e_oemid; // OEM identifier (for e_oeminfo)
+ UINT16 e_oeminfo; // OEM information; e_oemid specific
+ UINT16 e_res2[10]; // Reserved words
+ UINT32 e_lfanew; // File address of new exe header
+ } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
+
+typedef struct _IMAGE_OS2_HEADER { // OS/2 .EXE header
+ UINT16 ne_magic; // Magic number
+ UINT8 ne_ver; // Version number
+ UINT8 ne_rev; // Revision number
+ UINT16 ne_enttab; // Offset of Entry Table
+ UINT16 ne_cbenttab; // Number of bytes in Entry Table
+ UINT32 ne_crc; // Checksum of whole file
+ UINT16 ne_flags; // Flag UINT16
+ UINT16 ne_autodata; // Automatic data segment number
+ UINT16 ne_heap; // Initial heap allocation
+ UINT16 ne_stack; // Initial stack allocation
+ UINT32 ne_csip; // Initial CS:IP setting
+ UINT32 ne_sssp; // Initial SS:SP setting
+ UINT16 ne_cseg; // Count of file segments
+ UINT16 ne_cmod; // Entries in Module Reference Table
+ UINT16 ne_cbnrestab; // Size of non-resident name table
+ UINT16 ne_segtab; // Offset of Segment Table
+ UINT16 ne_rsrctab; // Offset of Resource Table
+ UINT16 ne_restab; // Offset of resident name table
+ UINT16 ne_modtab; // Offset of Module Reference Table
+ UINT16 ne_imptab; // Offset of Imported Names Table
+ UINT32 ne_nrestab; // Offset of Non-resident Names Table
+ UINT16 ne_cmovent; // Count of movable entries
+ UINT16 ne_align; // Segment alignment shift count
+ UINT16 ne_cres; // Count of resource segments
+ UINT8 ne_exetyp; // Target Operating system
+ UINT8 ne_flagsothers; // Other .EXE flags
+ UINT16 ne_pretthunks; // offset to return thunks
+ UINT16 ne_psegrefbytes; // offset to segment ref. bytes
+ UINT16 ne_swaparea; // Minimum code swap area size
+ UINT16 ne_expver; // Expected Windows version number
+ } IMAGE_OS2_HEADER, *PIMAGE_OS2_HEADER;
+
+//
+// File header format.
+//
+
+typedef struct _IMAGE_FILE_HEADER {
+ UINT16 Machine;
+ UINT16 NumberOfSections;
+ UINT32 TimeDateStamp;
+ UINT32 PointerToSymbolTable;
+ UINT32 NumberOfSymbols;
+ UINT16 SizeOfOptionalHeader;
+ UINT16 Characteristics;
+} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
+
+#define IMAGE_SIZEOF_FILE_HEADER 20
+
+#define IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file.
+#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // File is executable (i.e. no unresolved externel references).
+#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // Line nunbers stripped from file.
+#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 // Local symbols stripped from file.
+#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 // Bytes of machine word are reversed.
+#define IMAGE_FILE_32BIT_MACHINE 0x0100 // 32 bit word machine.
+#define IMAGE_FILE_DEBUG_STRIPPED 0x0200 // Debugging info stripped from file in .DBG file
+#define IMAGE_FILE_SYSTEM 0x1000 // System File.
+#define IMAGE_FILE_DLL 0x2000 // File is a DLL.
+#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 // Bytes of machine word are reversed.
+
+#define IMAGE_FILE_MACHINE_UNKNOWN 0
+#define IMAGE_FILE_MACHINE_I386 0x14c // Intel 386.
+#define IMAGE_FILE_MACHINE_R3000 0x162 // MIPS little-endian, 0540 big-endian
+#define IMAGE_FILE_MACHINE_R4000 0x166 // MIPS little-endian
+#define IMAGE_FILE_MACHINE_ALPHA 0x184 // Alpha_AXP
+#define IMAGE_FILE_MACHINE_POWERPC 0x1F0 // IBM PowerPC Little-Endian
+#define IMAGE_FILE_MACHINE_TAHOE 0x7cc // Intel EM machine
+//
+// Directory format.
+//
+
+typedef struct _IMAGE_DATA_DIRECTORY {
+ UINT32 VirtualAddress;
+ UINT32 Size;
+} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
+
+#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
+
+//
+// Optional header format.
+//
+
+typedef struct _IMAGE_OPTIONAL_HEADER {
+ //
+ // Standard fields.
+ //
+
+ UINT16 Magic;
+ UINT8 MajorLinkerVersion;
+ UINT8 MinorLinkerVersion;
+ UINT32 SizeOfCode;
+ UINT32 SizeOfInitializedData;
+ UINT32 SizeOfUninitializedData;
+ UINT32 AddressOfEntryPoint;
+ UINT32 BaseOfCode;
+ UINT32 BaseOfData;
+
+ //
+ // NT additional fields.
+ //
+
+ UINT32 ImageBase;
+ UINT32 SectionAlignment;
+ UINT32 FileAlignment;
+ UINT16 MajorOperatingSystemVersion;
+ UINT16 MinorOperatingSystemVersion;
+ UINT16 MajorImageVersion;
+ UINT16 MinorImageVersion;
+ UINT16 MajorSubsystemVersion;
+ UINT16 MinorSubsystemVersion;
+ UINT32 Reserved1;
+ UINT32 SizeOfImage;
+ UINT32 SizeOfHeaders;
+ UINT32 CheckSum;
+ UINT16 Subsystem;
+ UINT16 DllCharacteristics;
+ UINT32 SizeOfStackReserve;
+ UINT32 SizeOfStackCommit;
+ UINT32 SizeOfHeapReserve;
+ UINT32 SizeOfHeapCommit;
+ UINT32 LoaderFlags;
+ UINT32 NumberOfRvaAndSizes;
+ IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
+} IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER;
+
+typedef struct _IMAGE_ROM_OPTIONAL_HEADER {
+ UINT16 Magic;
+ UINT8 MajorLinkerVersion;
+ UINT8 MinorLinkerVersion;
+ UINT32 SizeOfCode;
+ UINT32 SizeOfInitializedData;
+ UINT32 SizeOfUninitializedData;
+ UINT32 AddressOfEntryPoint;
+ UINT32 BaseOfCode;
+ UINT32 BaseOfData;
+ UINT32 BaseOfBss;
+ UINT32 GprMask;
+ UINT32 CprMask[4];
+ UINT32 GpValue;
+} IMAGE_ROM_OPTIONAL_HEADER, *PIMAGE_ROM_OPTIONAL_HEADER;
+
+#define IMAGE_SIZEOF_ROM_OPTIONAL_HEADER 56
+#define IMAGE_SIZEOF_STD_OPTIONAL_HEADER 28
+#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER 224
+
+#define IMAGE_NT_OPTIONAL_HDR_MAGIC 0x10b
+#define IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107
+
+typedef struct _IMAGE_NT_HEADERS {
+ UINT32 Signature;
+ IMAGE_FILE_HEADER FileHeader;
+ IMAGE_OPTIONAL_HEADER OptionalHeader;
+} IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS;
+
+typedef struct _IMAGE_ROM_HEADERS {
+ IMAGE_FILE_HEADER FileHeader;
+ IMAGE_ROM_OPTIONAL_HEADER OptionalHeader;
+} IMAGE_ROM_HEADERS, *PIMAGE_ROM_HEADERS;
+
+#define IMAGE_FIRST_SECTION( ntheader ) ((PIMAGE_SECTION_HEADER) \
+ ((UINT32)ntheader + \
+ FIELD_OFFSET( IMAGE_NT_HEADERS, OptionalHeader ) + \
+ ((PIMAGE_NT_HEADERS)(ntheader))->FileHeader.SizeOfOptionalHeader \
+ ))
+
+
+// Subsystem Values
+
+#define IMAGE_SUBSYSTEM_UNKNOWN 0 // Unknown subsystem.
+#define IMAGE_SUBSYSTEM_NATIVE 1 // Image doesn't require a subsystem.
+#define IMAGE_SUBSYSTEM_WINDOWS_GUI 2 // Image runs in the Windows GUI subsystem.
+#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3 // Image runs in the Windows character subsystem.
+#define IMAGE_SUBSYSTEM_OS2_CUI 5 // image runs in the OS/2 character subsystem.
+#define IMAGE_SUBSYSTEM_POSIX_CUI 7 // image run in the Posix character subsystem.
+
+
+// Directory Entries
+
+#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory
+#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory
+#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory
+#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory
+#define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory
+#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table
+#define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Debug Directory
+#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 // Description String
+#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // Machine Value (MIPS GP)
+#define IMAGE_DIRECTORY_ENTRY_TLS 9 // TLS Directory
+#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory
+
+//
+// Section header format.
+//
+
+#define IMAGE_SIZEOF_SHORT_NAME 8
+
+typedef struct _IMAGE_SECTION_HEADER {
+ UINT8 Name[IMAGE_SIZEOF_SHORT_NAME];
+ union {
+ UINT32 PhysicalAddress;
+ UINT32 VirtualSize;
+ } Misc;
+ UINT32 VirtualAddress;
+ UINT32 SizeOfRawData;
+ UINT32 PointerToRawData;
+ UINT32 PointerToRelocations;
+ UINT32 PointerToLinenumbers;
+ UINT16 NumberOfRelocations;
+ UINT16 NumberOfLinenumbers;
+ UINT32 Characteristics;
+} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
+
+#define IMAGE_SIZEOF_SECTION_HEADER 40
+
+#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 // Reserved.
+
+#define IMAGE_SCN_CNT_CODE 0x00000020 // Section contains code.
+#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 // Section contains initialized data.
+#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 // Section contains uninitialized data.
+
+#define IMAGE_SCN_LNK_OTHER 0x00000100 // Reserved.
+#define IMAGE_SCN_LNK_INFO 0x00000200 // Section contains comments or some other type of information.
+#define IMAGE_SCN_LNK_REMOVE 0x00000800 // Section contents will not become part of image.
+#define IMAGE_SCN_LNK_COMDAT 0x00001000 // Section contents comdat.
+
+#define IMAGE_SCN_ALIGN_1BYTES 0x00100000 //
+#define IMAGE_SCN_ALIGN_2BYTES 0x00200000 //
+#define IMAGE_SCN_ALIGN_4BYTES 0x00300000 //
+#define IMAGE_SCN_ALIGN_8BYTES 0x00400000 //
+#define IMAGE_SCN_ALIGN_16BYTES 0x00500000 // Default alignment if no others are specified.
+#define IMAGE_SCN_ALIGN_32BYTES 0x00600000 //
+#define IMAGE_SCN_ALIGN_64BYTES 0x00700000 //
+
+#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 // Section can be discarded.
+#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 // Section is not cachable.
+#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 // Section is not pageable.
+#define IMAGE_SCN_MEM_SHARED 0x10000000 // Section is shareable.
+#define IMAGE_SCN_MEM_EXECUTE 0x20000000 // Section is executable.
+#define IMAGE_SCN_MEM_READ 0x40000000 // Section is readable.
+#define IMAGE_SCN_MEM_WRITE 0x80000000 // Section is writeable.
+
+//
+// Symbol format.
+//
+
+
+#define IMAGE_SIZEOF_SYMBOL 18
+
+//
+// Section values.
+//
+// Symbols have a section number of the section in which they are
+// defined. Otherwise, section numbers have the following meanings:
+//
+
+#define IMAGE_SYM_UNDEFINED (UINT16)0 // Symbol is undefined or is common.
+#define IMAGE_SYM_ABSOLUTE (UINT16)-1 // Symbol is an absolute value.
+#define IMAGE_SYM_DEBUG (UINT16)-2 // Symbol is a special debug item.
+
+//
+// Type (fundamental) values.
+//
+
+#define IMAGE_SYM_TYPE_NULL 0 // no type.
+#define IMAGE_SYM_TYPE_VOID 1 //
+#define IMAGE_SYM_TYPE_CHAR 2 // type character.
+#define IMAGE_SYM_TYPE_SHORT 3 // type short integer.
+#define IMAGE_SYM_TYPE_INT 4 //
+#define IMAGE_SYM_TYPE_LONG 5 //
+#define IMAGE_SYM_TYPE_FLOAT 6 //
+#define IMAGE_SYM_TYPE_DOUBLE 7 //
+#define IMAGE_SYM_TYPE_STRUCT 8 //
+#define IMAGE_SYM_TYPE_UNION 9 //
+#define IMAGE_SYM_TYPE_ENUM 10 // enumeration.
+#define IMAGE_SYM_TYPE_MOE 11 // member of enumeration.
+#define IMAGE_SYM_TYPE_BYTE 12 //
+#define IMAGE_SYM_TYPE_WORD 13 //
+#define IMAGE_SYM_TYPE_UINT 14 //
+#define IMAGE_SYM_TYPE_DWORD 15 //
+
+//
+// Type (derived) values.
+//
+
+#define IMAGE_SYM_DTYPE_NULL 0 // no derived type.
+#define IMAGE_SYM_DTYPE_POINTER 1 // pointer.
+#define IMAGE_SYM_DTYPE_FUNCTION 2 // function.
+#define IMAGE_SYM_DTYPE_ARRAY 3 // array.
+
+//
+// Storage classes.
+//
+
+#define IMAGE_SYM_CLASS_END_OF_FUNCTION (BYTE )-1
+#define IMAGE_SYM_CLASS_NULL 0
+#define IMAGE_SYM_CLASS_AUTOMATIC 1
+#define IMAGE_SYM_CLASS_EXTERNAL 2
+#define IMAGE_SYM_CLASS_STATIC 3
+#define IMAGE_SYM_CLASS_REGISTER 4
+#define IMAGE_SYM_CLASS_EXTERNAL_DEF 5
+#define IMAGE_SYM_CLASS_LABEL 6
+#define IMAGE_SYM_CLASS_UNDEFINED_LABEL 7
+#define IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 8
+#define IMAGE_SYM_CLASS_ARGUMENT 9
+#define IMAGE_SYM_CLASS_STRUCT_TAG 10
+#define IMAGE_SYM_CLASS_MEMBER_OF_UNION 11
+#define IMAGE_SYM_CLASS_UNION_TAG 12
+#define IMAGE_SYM_CLASS_TYPE_DEFINITION 13
+#define IMAGE_SYM_CLASS_UNDEFINED_STATIC 14
+#define IMAGE_SYM_CLASS_ENUM_TAG 15
+#define IMAGE_SYM_CLASS_MEMBER_OF_ENUM 16
+#define IMAGE_SYM_CLASS_REGISTER_PARAM 17
+#define IMAGE_SYM_CLASS_BIT_FIELD 18
+#define IMAGE_SYM_CLASS_BLOCK 100
+#define IMAGE_SYM_CLASS_FUNCTION 101
+#define IMAGE_SYM_CLASS_END_OF_STRUCT 102
+#define IMAGE_SYM_CLASS_FILE 103
+// new
+#define IMAGE_SYM_CLASS_SECTION 104
+#define IMAGE_SYM_CLASS_WEAK_EXTERNAL 105
+
+// type packing constants
+
+#define N_BTMASK 017
+#define N_TMASK 060
+#define N_TMASK1 0300
+#define N_TMASK2 0360
+#define N_BTSHFT 4
+#define N_TSHIFT 2
+
+// MACROS
+
+//
+// Communal selection types.
+//
+
+#define IMAGE_COMDAT_SELECT_NODUPLICATES 1
+#define IMAGE_COMDAT_SELECT_ANY 2
+#define IMAGE_COMDAT_SELECT_SAME_SIZE 3
+#define IMAGE_COMDAT_SELECT_EXACT_MATCH 4
+#define IMAGE_COMDAT_SELECT_ASSOCIATIVE 5
+
+#define IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1
+#define IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2
+#define IMAGE_WEAK_EXTERN_SEARCH_ALIAS 3
+
+
+//
+// Relocation format.
+//
+
+typedef struct _IMAGE_RELOCATION {
+ UINT32 VirtualAddress;
+ UINT32 SymbolTableIndex;
+ UINT16 Type;
+} IMAGE_RELOCATION;
+
+#define IMAGE_SIZEOF_RELOCATION 10
+
+//
+// I386 relocation types.
+//
+
+#define IMAGE_REL_I386_ABSOLUTE 0 // Reference is absolute, no relocation is necessary
+#define IMAGE_REL_I386_DIR16 01 // Direct 16-bit reference to the symbols virtual address
+#define IMAGE_REL_I386_REL16 02 // PC-relative 16-bit reference to the symbols virtual address
+#define IMAGE_REL_I386_DIR32 06 // Direct 32-bit reference to the symbols virtual address
+#define IMAGE_REL_I386_DIR32NB 07 // Direct 32-bit reference to the symbols virtual address, base not included
+#define IMAGE_REL_I386_SEG12 011 // Direct 16-bit reference to the segment-selector bits of a 32-bit virtual address
+#define IMAGE_REL_I386_SECTION 012
+#define IMAGE_REL_I386_SECREL 013
+#define IMAGE_REL_I386_REL32 024 // PC-relative 32-bit reference to the symbols virtual address
+
+//
+// MIPS relocation types.
+//
+
+#define IMAGE_REL_MIPS_ABSOLUTE 0 // Reference is absolute, no relocation is necessary
+#define IMAGE_REL_MIPS_REFHALF 01
+#define IMAGE_REL_MIPS_REFWORD 02
+#define IMAGE_REL_MIPS_JMPADDR 03
+#define IMAGE_REL_MIPS_REFHI 04
+#define IMAGE_REL_MIPS_REFLO 05
+#define IMAGE_REL_MIPS_GPREL 06
+#define IMAGE_REL_MIPS_LITERAL 07
+#define IMAGE_REL_MIPS_SECTION 012
+#define IMAGE_REL_MIPS_SECREL 013
+#define IMAGE_REL_MIPS_REFWORDNB 042
+#define IMAGE_REL_MIPS_PAIR 045
+
+//
+// Alpha Relocation types.
+//
+
+#define IMAGE_REL_ALPHA_ABSOLUTE 0x0
+#define IMAGE_REL_ALPHA_REFLONG 0x1
+#define IMAGE_REL_ALPHA_REFQUAD 0x2
+#define IMAGE_REL_ALPHA_GPREL32 0x3
+#define IMAGE_REL_ALPHA_LITERAL 0x4
+#define IMAGE_REL_ALPHA_LITUSE 0x5
+#define IMAGE_REL_ALPHA_GPDISP 0x6
+#define IMAGE_REL_ALPHA_BRADDR 0x7
+#define IMAGE_REL_ALPHA_HINT 0x8
+#define IMAGE_REL_ALPHA_INLINE_REFLONG 0x9
+#define IMAGE_REL_ALPHA_REFHI 0xA
+#define IMAGE_REL_ALPHA_REFLO 0xB
+#define IMAGE_REL_ALPHA_PAIR 0xC
+#define IMAGE_REL_ALPHA_MATCH 0xD
+#define IMAGE_REL_ALPHA_SECTION 0xE
+#define IMAGE_REL_ALPHA_SECREL 0xF
+#define IMAGE_REL_ALPHA_REFLONGNB 0x10
+
+//
+// IBM PowerPC relocation types.
+//
+
+#define IMAGE_REL_PPC_ABSOLUTE 0x0000 // NOP
+#define IMAGE_REL_PPC_ADDR64 0x0001 // 64-bit address
+#define IMAGE_REL_PPC_ADDR32 0x0002 // 32-bit address
+#define IMAGE_REL_PPC_ADDR24 0x0003 // 26-bit address, shifted left 2 (branch absolute)
+#define IMAGE_REL_PPC_ADDR16 0x0004 // 16-bit address
+#define IMAGE_REL_PPC_ADDR14 0x0005 // 16-bit address, shifted left 2 (load doubleword)
+#define IMAGE_REL_PPC_REL24 0x0006 // 26-bit PC-relative offset, shifted left 2 (branch relative)
+#define IMAGE_REL_PPC_REL14 0x0007 // 16-bit PC-relative offset, shifted left 2 (br cond relative)
+#define IMAGE_REL_PPC_TOCREL16 0x0008 // 16-bit offset from TOC base
+#define IMAGE_REL_PPC_TOCREL14 0x0009 // 16-bit offset from TOC base, shifted left 2 (load doubleword)
+
+#define IMAGE_REL_PPC_ADDR32NB 0x000A // 32-bit addr w/o image base
+#define IMAGE_REL_PPC_SECREL 0x000B // va of containing section (as in an image sectionhdr)
+#define IMAGE_REL_PPC_SECTION 0x000C // sectionheader number
+#define IMAGE_REL_PPC_IFGLUE 0x000D // substitute TOC restore instruction iff symbol is glue code
+#define IMAGE_REL_PPC_IMGLUE 0x000E // symbol is glue code; virtual address is TOC restore instruction
+
+#define IMAGE_REL_PPC_TYPEMASK 0x00FF // mask to isolate above values in IMAGE_RELOCATION.Type
+
+// Flag bits in IMAGE_RELOCATION.TYPE
+
+#define IMAGE_REL_PPC_NEG 0x0100 // subtract reloc value rather than adding it
+#define IMAGE_REL_PPC_BRTAKEN 0x0200 // fix branch prediction bit to predict branch taken
+#define IMAGE_REL_PPC_BRNTAKEN 0x0400 // fix branch prediction bit to predict branch not taken
+#define IMAGE_REL_PPC_TOCDEFN 0x0800 // toc slot defined in file (or, data in toc)
+
+//
+// Based relocation format.
+//
+
+typedef struct _IMAGE_BASE_RELOCATION {
+ UINT32 VirtualAddress;
+ UINT32 SizeOfBlock;
+// UINT16 TypeOffset[1];
+} IMAGE_BASE_RELOCATION, *PIMAGE_BASE_RELOCATION;
+
+#define IMAGE_SIZEOF_BASE_RELOCATION 8
+
+//
+// Based relocation types.
+//
+
+#define IMAGE_REL_BASED_ABSOLUTE 0
+#define IMAGE_REL_BASED_HIGH 1
+#define IMAGE_REL_BASED_LOW 2
+#define IMAGE_REL_BASED_HIGHLOW 3
+#define IMAGE_REL_BASED_HIGHADJ 4
+#define IMAGE_REL_BASED_MIPS_JMPADDR 5
+#define IMAGE_REL_BASED_IA64_IMM64 9
+#define IMAGE_REL_BASED_DIR64 10
+
+//
+// Line number format.
+//
+
+typedef struct _IMAGE_LINENUMBER {
+ union {
+ UINT32 SymbolTableIndex; // Symbol table index of function name if Linenumber is 0.
+ UINT32 VirtualAddress; // Virtual address of line number.
+ } Type;
+ UINT16 Linenumber; // Line number.
+} IMAGE_LINENUMBER;
+
+#define IMAGE_SIZEOF_LINENUMBER 6
+
+//
+// Archive format.
+//
+
+#define IMAGE_ARCHIVE_START_SIZE 8
+#define IMAGE_ARCHIVE_START "!<arch>\n"
+#define IMAGE_ARCHIVE_END "`\n"
+#define IMAGE_ARCHIVE_PAD "\n"
+#define IMAGE_ARCHIVE_LINKER_MEMBER "/ "
+#define IMAGE_ARCHIVE_LONGNAMES_MEMBER "// "
+
+typedef struct _IMAGE_ARCHIVE_MEMBER_HEADER {
+ UINT8 Name[16]; // File member name - `/' terminated.
+ UINT8 Date[12]; // File member date - decimal.
+ UINT8 UserID[6]; // File member user id - decimal.
+ UINT8 GroupID[6]; // File member group id - decimal.
+ UINT8 Mode[8]; // File member mode - octal.
+ UINT8 Size[10]; // File member size - decimal.
+ UINT8 EndHeader[2]; // String to end header.
+} IMAGE_ARCHIVE_MEMBER_HEADER, *PIMAGE_ARCHIVE_MEMBER_HEADER;
+
+#define IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60
+
+//
+// DLL support.
+//
+
+//
+// Export Format
+//
+
+typedef struct _IMAGE_EXPORT_DIRECTORY {
+ UINT32 Characteristics;
+ UINT32 TimeDateStamp;
+ UINT16 MajorVersion;
+ UINT16 MinorVersion;
+ UINT32 Name;
+ UINT32 Base;
+ UINT32 NumberOfFunctions;
+ UINT32 NumberOfNames;
+ UINT32 *AddressOfFunctions;
+ UINT32 *AddressOfNames;
+ UINT32 *AddressOfNameOrdinals;
+} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
+
+//
+// Import Format
+//
+
+typedef struct _IMAGE_IMPORT_BY_NAME {
+ UINT16 Hint;
+ UINT8 Name[1];
+} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;
+
+typedef struct _IMAGE_THUNK_DATA {
+ union {
+ UINT32 Function;
+ UINT32 Ordinal;
+ PIMAGE_IMPORT_BY_NAME AddressOfData;
+ } u1;
+} IMAGE_THUNK_DATA, *PIMAGE_THUNK_DATA;
+
+#define IMAGE_ORDINAL_FLAG 0x80000000
+#define IMAGE_SNAP_BY_ORDINAL(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG) != 0)
+#define IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff)
+
+typedef struct _IMAGE_IMPORT_DESCRIPTOR {
+ UINT32 Characteristics;
+ UINT32 TimeDateStamp;
+ UINT32 ForwarderChain;
+ UINT32 Name;
+ PIMAGE_THUNK_DATA FirstThunk;
+} IMAGE_IMPORT_DESCRIPTOR, *PIMAGE_IMPORT_DESCRIPTOR;
+
+#endif
diff --git a/sys/boot/efi/include/efi.h b/sys/boot/efi/include/efi.h
index 4869e38..513ab9d 100644
--- a/sys/boot/efi/include/efi.h
+++ b/sys/boot/efi/include/efi.h
@@ -52,6 +52,7 @@ Revision History
#include "efiapi.h"
#include "efifs.h"
#include "efierr.h"
+#include "efigop.h"
#define EFI_STRINGIZE(a) #a
#define EFI_PROTOCOL_DEFINITION(a) EFI_STRINGIZE(Protocol/a/a.h)
diff --git a/sys/boot/efi/include/efigop.h b/sys/boot/efi/include/efigop.h
new file mode 100644
index 0000000..dfc4bba
--- /dev/null
+++ b/sys/boot/efi/include/efigop.h
@@ -0,0 +1,122 @@
+/* $FreeBSD$ */
+/*++
+
+Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+Module Name:
+
+ efigop.h
+
+Abstract:
+ Info about framebuffers
+
+
+
+
+Revision History
+
+--*/
+
+#ifndef _EFIGOP_H
+#define _EFIGOP_H
+
+#define EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID \
+ { 0x9042a9de, 0x23dc, 0x4a38, 0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, \
+ 0x51, 0x6a }
+
+INTERFACE_DECL(_EFI_GRAPHICS_OUTPUT);
+
+typedef struct {
+ UINT32 RedMask;
+ UINT32 GreenMask;
+ UINT32 BlueMask;
+ UINT32 ReservedMask;
+} EFI_PIXEL_BITMASK;
+
+typedef enum {
+ PixelRedGreenBlueReserved8BitPerColor,
+ PixelBlueGreenRedReserved8BitPerColor,
+ PixelBitMask,
+ PixelBltOnly,
+ PixelFormatMax,
+} EFI_GRAPHICS_PIXEL_FORMAT;
+
+typedef struct {
+ UINT32 Version;
+ UINT32 HorizontalResolution;
+ UINT32 VerticalResolution;
+ EFI_GRAPHICS_PIXEL_FORMAT PixelFormat;
+ EFI_PIXEL_BITMASK PixelInformation;
+ UINT32 PixelsPerScanLine;
+} EFI_GRAPHICS_OUTPUT_MODE_INFORMATION;
+
+typedef struct {
+ UINT32 MaxMode;
+ UINT32 Mode;
+ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
+ UINTN SizeOfInfo;
+ EFI_PHYSICAL_ADDRESS FrameBufferBase;
+ UINTN FrameBufferSize;
+} EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_QUERY_MODE) (
+ IN struct _EFI_GRAPHICS_OUTPUT *This,
+ IN UINT32 ModeNumber,
+ OUT UINTN *SizeOfInfo,
+ OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_SET_MODE) (
+ IN struct _EFI_GRAPHICS_OUTPUT *This,
+ IN UINT32 ModeNumber
+ );
+
+typedef struct {
+ UINT8 Blue;
+ UINT8 Green;
+ UINT8 Red;
+ UINT8 Reserved;
+} EFI_GRAPHICS_OUTPUT_BLT_PIXEL;
+
+typedef enum {
+ EfiBltVideoFill,
+ EfiBltVideoToBltBuffer,
+ EfiBltBufferToVideo,
+ EfiBltVideoToVideo,
+ EfiGraphcisOutputBltOperationMax,
+} EFI_GRAPHICS_OUTPUT_BLT_OPERATION;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_BLT) (
+ IN struct _EFI_GRAPHICS_OUTPUT *This,
+ IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer,
+ IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
+ IN UINTN SourceX,
+ IN UINTN SourceY,
+ IN UINTN DestinationX,
+ IN UINTN DestinationY,
+ IN UINTN Width,
+ IN UINTN Height,
+ IN UINTN Delta
+ );
+
+typedef struct _EFI_GRAPHICS_OUTPUT {
+ EFI_GRAPHICS_OUTPUT_PROTOCOL_QUERY_MODE QueryMode;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL_SET_MODE SetMode;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL_BLT Blt;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Mode;
+} EFI_GRAPHICS_OUTPUT;
+
+#endif /* _EFIGOP_H */
diff --git a/sys/boot/efi/include/efilib.h b/sys/boot/efi/include/efilib.h
index cf825a6..ef03028 100644
--- a/sys/boot/efi/include/efilib.h
+++ b/sys/boot/efi/include/efilib.h
@@ -41,7 +41,7 @@ extern struct netif_driver efinetif;
void *efi_get_table(EFI_GUID *tbl);
void efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table);
-int efi_register_handles(struct devsw *, EFI_HANDLE *, int);
+int efi_register_handles(struct devsw *, EFI_HANDLE *, EFI_HANDLE *, int);
EFI_HANDLE efi_find_handle(struct devsw *, int);
int efi_handle_lookup(EFI_HANDLE, struct devsw **, int *);
diff --git a/sys/boot/efi/libefi/Makefile b/sys/boot/efi/libefi/Makefile
index beb9269..60cb43f 100644
--- a/sys/boot/efi/libefi/Makefile
+++ b/sys/boot/efi/libefi/Makefile
@@ -6,11 +6,18 @@ INTERNALLIB=
SRCS= delay.c efi_console.c efinet.c efipart.c errno.c handles.c \
libefi.c time.c
+.if ${MACHINE_ARCH} == "amd64"
+CFLAGS+= -fPIC
+.endif
CFLAGS+= -I${.CURDIR}/../include
-CFLAGS+= -I${.CURDIR}/../include/${MACHINE_CPUARCH:S/amd64/i386/}
+CFLAGS+= -I${.CURDIR}/../include/${MACHINE_CPUARCH}
CFLAGS+= -I${.CURDIR}/../../../../lib/libstand
# Pick up the bootstrap header for some interface items
CFLAGS+= -I${.CURDIR}/../../common
+
+# Suppress warning from clang for FreeBSD %b and %D formats
+CFLAGS+= -fformat-extensions
+
.include <bsd.lib.mk>
diff --git a/sys/boot/efi/libefi/efinet.c b/sys/boot/efi/libefi/efinet.c
index 5b3e401..3f08ed2 100644
--- a/sys/boot/efi/libefi/efinet.c
+++ b/sys/boot/efi/libefi/efinet.c
@@ -274,7 +274,7 @@ efinet_dev_init()
if (EFI_ERROR(status))
return (efi_status_to_errno(status));
nifs = sz / sizeof(EFI_HANDLE);
- err = efi_register_handles(&efinet_dev, handles, nifs);
+ err = efi_register_handles(&efinet_dev, handles, NULL, nifs);
free(handles);
if (err != 0)
return (err);
diff --git a/sys/boot/efi/libefi/efipart.c b/sys/boot/efi/libefi/efipart.c
index 264a2a4..13dc0ac 100644
--- a/sys/boot/efi/libefi/efipart.c
+++ b/sys/boot/efi/libefi/efipart.c
@@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
#include <efiprot.h>
static EFI_GUID blkio_guid = BLOCK_IO_PROTOCOL;
+static EFI_GUID devpath_guid = DEVICE_PATH_PROTOCOL;
static int efipart_init(void);
static int efipart_strategy(void *, int, daddr_t, size_t, char *, size_t *);
@@ -62,9 +63,11 @@ static int
efipart_init(void)
{
EFI_BLOCK_IO *blkio;
- EFI_HANDLE *hin, *hout;
+ EFI_DEVICE_PATH *devpath, *node;
+ EFI_HANDLE *hin, *hout, *aliases, handle;
EFI_STATUS status;
UINTN sz;
+ CHAR16 *path;
u_int n, nin, nout;
int err;
@@ -72,7 +75,7 @@ efipart_init(void)
hin = NULL;
status = BS->LocateHandle(ByProtocol, &blkio_guid, 0, &sz, 0);
if (status == EFI_BUFFER_TOO_SMALL) {
- hin = (EFI_HANDLE *)malloc(sz * 2);
+ hin = (EFI_HANDLE *)malloc(sz * 3);
status = BS->LocateHandle(ByProtocol, &blkio_guid, 0, &sz,
hin);
if (EFI_ERROR(status))
@@ -84,19 +87,50 @@ efipart_init(void)
/* Filter handles to only include FreeBSD partitions. */
nin = sz / sizeof(EFI_HANDLE);
hout = hin + nin;
+ aliases = hout + nin;
nout = 0;
+ bzero(aliases, nin * sizeof(EFI_HANDLE));
+
for (n = 0; n < nin; n++) {
- status = BS->HandleProtocol(hin[n], &blkio_guid, &blkio);
+ status = BS->HandleProtocol(hin[n], &devpath_guid,
+ (void **)&devpath);
+ if (EFI_ERROR(status)) {
+ continue;
+ }
+ node = devpath;
+ while (!IsDevicePathEnd(NextDevicePathNode(node)))
+ node = NextDevicePathNode(node);
+ status = BS->HandleProtocol(hin[n], &blkio_guid,
+ (void**)&blkio);
if (EFI_ERROR(status))
continue;
if (!blkio->Media->LogicalPartition)
continue;
- hout[nout] = hin[n];
+
+ /*
+ * If we come across a logical partition of subtype CDROM
+ * it doesn't refer to the CD filesystem itself, but rather
+ * to any usable El Torito boot image on it. In this case
+ * we try to find the parent device and add that instead as
+ * that will be the CD filesystem.
+ */
+ if (DevicePathType(node) == MEDIA_DEVICE_PATH &&
+ DevicePathSubType(node) == MEDIA_CDROM_DP) {
+ node->Type = END_DEVICE_PATH_TYPE;
+ node->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
+ status = BS->LocateDevicePath(&blkio_guid, &devpath,
+ &handle);
+ if (EFI_ERROR(status))
+ continue;
+ hout[nout] = handle;
+ aliases[nout] = hin[n];
+ } else
+ hout[nout] = hin[n];
nout++;
}
- err = efi_register_handles(&efipart_dev, hout, nout);
+ err = efi_register_handles(&efipart_dev, hout, aliases, nout);
free(hin);
return (err);
}
@@ -115,7 +149,7 @@ efipart_print(int verbose)
sprintf(line, " %s%d:", efipart_dev.dv_name, unit);
pager_output(line);
- status = BS->HandleProtocol(h, &blkio_guid, &blkio);
+ status = BS->HandleProtocol(h, &blkio_guid, (void **)&blkio);
if (!EFI_ERROR(status)) {
sprintf(line, " %llu blocks",
(unsigned long long)(blkio->Media->LastBlock + 1));
@@ -144,7 +178,7 @@ efipart_open(struct open_file *f, ...)
if (h == NULL)
return (EINVAL);
- status = BS->HandleProtocol(h, &blkio_guid, &blkio);
+ status = BS->HandleProtocol(h, &blkio_guid, (void **)&blkio);
if (EFI_ERROR(status))
return (efi_status_to_errno(status));
diff --git a/sys/boot/efi/libefi/handles.c b/sys/boot/efi/libefi/handles.c
index 7c78a15..b15c0a5 100644
--- a/sys/boot/efi/libefi/handles.c
+++ b/sys/boot/efi/libefi/handles.c
@@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");
struct entry {
EFI_HANDLE handle;
+ EFI_HANDLE alias;
struct devsw *dev;
int unit;
};
@@ -40,7 +41,8 @@ struct entry *entry;
int nentries;
int
-efi_register_handles(struct devsw *sw, EFI_HANDLE *handles, int count)
+efi_register_handles(struct devsw *sw, EFI_HANDLE *handles,
+ EFI_HANDLE *aliases, int count)
{
size_t sz;
int idx, unit;
@@ -51,6 +53,10 @@ efi_register_handles(struct devsw *sw, EFI_HANDLE *handles, int count)
entry = (entry == NULL) ? malloc(sz) : realloc(entry, sz);
for (unit = 0; idx < nentries; idx++, unit++) {
entry[idx].handle = handles[unit];
+ if (aliases != NULL)
+ entry[idx].alias = aliases[unit];
+ else
+ entry[idx].alias = NULL;
entry[idx].dev = sw;
entry[idx].unit = unit;
}
@@ -78,7 +84,7 @@ efi_handle_lookup(EFI_HANDLE h, struct devsw **dev, int *unit)
int idx;
for (idx = 0; idx < nentries; idx++) {
- if (entry[idx].handle != h)
+ if (entry[idx].handle != h && entry[idx].alias != h)
continue;
if (dev != NULL)
*dev = entry[idx].dev;
diff --git a/sys/boot/ficl/Makefile b/sys/boot/ficl/Makefile
index 9a3e399..6fad54f 100644
--- a/sys/boot/ficl/Makefile
+++ b/sys/boot/ficl/Makefile
@@ -3,7 +3,7 @@
FICLDIR?= ${.CURDIR}
-.if !defined(FICL64)
+.if defined(FICL32)
.PATH: ${FICLDIR}/${MACHINE_CPUARCH:S/amd64/i386/}
.else
.PATH: ${FICLDIR}/${MACHINE_CPUARCH}
@@ -14,11 +14,12 @@ BASE_SRCS= dict.c ficl.c fileaccess.c float.c loader.c math64.c \
SRCS= ${BASE_SRCS} sysdep.c softcore.c
CLEANFILES= softcore.c testmain testmain.o
CFLAGS+= -ffreestanding
-.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64"
-.if !defined(FICL64)
+.if ${MACHINE_CPUARCH} == "i386" || \
+ (${MACHINE_CPUARCH} == "amd64" && defined(FICL32))
CFLAGS+= -march=i386
CFLAGS.gcc+= -mpreferred-stack-boundary=2
.endif
+.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64"
CFLAGS+= -mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 -msoft-float
.endif
.if ${MACHINE_CPUARCH} == "powerpc" || ${MACHINE_CPUARCH} == "arm"
@@ -48,22 +49,32 @@ SOFTWORDS= softcore.fr jhlocal.fr marker.fr freebsd.fr ficllocal.fr \
# Optional OO extension softwords
#SOFTWORDS+= oo.fr classes.fr
-.if ${MACHINE_CPUARCH} == "amd64" && !defined(FICL64)
+.if ${MACHINE_CPUARCH} == "amd64"
+.if defined(FICL32)
CFLAGS+= -m32 -I.
+.else
+CFLAGS+= -fPIC
+.endif
.endif
.if ${MACHINE_ARCH} == "powerpc64"
CFLAGS+= -m32 -mcpu=powerpc -I.
.endif
-CFLAGS+= -I${FICLDIR} -I${FICLDIR}/${MACHINE_CPUARCH:S/amd64/i386/} \
+.if ${MACHINE_CPUARCH} == "amd64" && defined(FICL32)
+FICL_CPUARCH= i386
+.else
+FICL_CPUARCH= ${MACHINE_CPUARCH}
+.endif
+
+CFLAGS+= -I${FICLDIR} -I${FICLDIR}/${FICL_CPUARCH} \
-I${FICLDIR}/../common
softcore.c: ${SOFTWORDS} softcore.awk
(cd ${FICLDIR}/softwords; cat ${SOFTWORDS} \
| awk -f softcore.awk -v datestamp="`LC_ALL=C date`") > ${.TARGET}
-.if ${MACHINE_CPUARCH} == "amd64"
+.if ${MACHINE_CPUARCH} == "amd64" && defined(FICL32)
.if !exists(machine)
${SRCS:M*.c:R:S/$/.o/g}: machine
diff --git a/sys/boot/ficl/tools.c b/sys/boot/ficl/tools.c
index 7201663..db1e948 100644
--- a/sys/boot/ficl/tools.c
+++ b/sys/boot/ficl/tools.c
@@ -201,7 +201,7 @@ static void seeColon(FICL_VM *pVM, CELL *pc)
*cp++ = '>';
else
*cp++ = ' ';
- cp += sprintf(cp, "%3d ", pc-param0);
+ cp += sprintf(cp, "%3d ", (int)(pc-param0));
if (isAFiclWord(pd, pFW))
{
@@ -239,40 +239,40 @@ static void seeColon(FICL_VM *pVM, CELL *pc)
case IF:
c = *++pc;
if (c.i > 0)
- sprintf(cp, "if / while (branch %d)", pc+c.i-param0);
+ sprintf(cp, "if / while (branch %d)", (int)(pc+c.i-param0));
else
- sprintf(cp, "until (branch %d)", pc+c.i-param0);
+ sprintf(cp, "until (branch %d)", (int)(pc+c.i-param0));
break;
case BRANCH:
c = *++pc;
if (c.i == 0)
- sprintf(cp, "repeat (branch %d)", pc+c.i-param0);
+ sprintf(cp, "repeat (branch %d)", (int)(pc+c.i-param0));
else if (c.i == 1)
- sprintf(cp, "else (branch %d)", pc+c.i-param0);
+ sprintf(cp, "else (branch %d)", (int)(pc+c.i-param0));
else
- sprintf(cp, "endof (branch %d)", pc+c.i-param0);
+ sprintf(cp, "endof (branch %d)", (int)(pc+c.i-param0));
break;
case OF:
c = *++pc;
- sprintf(cp, "of (branch %d)", pc+c.i-param0);
+ sprintf(cp, "of (branch %d)", (int)(pc+c.i-param0));
break;
case QDO:
c = *++pc;
- sprintf(cp, "?do (leave %d)", (CELL *)c.p-param0);
+ sprintf(cp, "?do (leave %d)", (int)((CELL *)c.p-param0));
break;
case DO:
c = *++pc;
- sprintf(cp, "do (leave %d)", (CELL *)c.p-param0);
+ sprintf(cp, "do (leave %d)", (int)((CELL *)c.p-param0));
break;
case LOOP:
c = *++pc;
- sprintf(cp, "loop (branch %d)", pc+c.i-param0);
+ sprintf(cp, "loop (branch %d)", (int)(pc+c.i-param0));
break;
case PLOOP:
c = *++pc;
- sprintf(cp, "+loop (branch %d)", pc+c.i-param0);
+ sprintf(cp, "+loop (branch %d)", (int)(pc+c.i-param0));
break;
default:
sprintf(cp, "%.*s", pFW->nName, pFW->name);
diff --git a/sys/boot/ficl/words.c b/sys/boot/ficl/words.c
index 48e073d..c32e352 100644
--- a/sys/boot/ficl/words.c
+++ b/sys/boot/ficl/words.c
@@ -2567,7 +2567,7 @@ static void setObjectFlag(FICL_VM *pVM)
static void isObject(FICL_VM *pVM)
{
- int flag;
+ FICL_INT flag;
FICL_WORD *pFW = (FICL_WORD *)stackPopPtr(pVM->pStack);
flag = ((pFW != NULL) && (pFW->flags & FW_ISOBJECT)) ? FICL_TRUE : FICL_FALSE;
diff --git a/sys/boot/ficl64/Makefile b/sys/boot/ficl32/Makefile
index 4c6777b..57c44ca 100644
--- a/sys/boot/ficl64/Makefile
+++ b/sys/boot/ficl32/Makefile
@@ -1,6 +1,6 @@
# $FreeBSD$
-FICL64=
+FICL32=
FICLDIR= ${.CURDIR}/../ficl
.PATH: ${FICLDIR}
diff --git a/sys/boot/forth/beastie.4th b/sys/boot/forth/beastie.4th
index 7a2cbb0..2fc073d 100644
--- a/sys/boot/forth/beastie.4th
+++ b/sys/boot/forth/beastie.4th
@@ -242,6 +242,11 @@ variable logoY
;
: beastie-start ( -- ) \ starts the menu
+ s" console" getenv dup -1 <> if
+ s" efi" 2swap contains? if
+ s" set beastie_disable=YES" evaluate
+ then
+ else drop then
s" beastie_disable" getenv
dup -1 <> if
s" YES" compare-insensitive 0= if
diff --git a/sys/boot/forth/beastie.4th.8 b/sys/boot/forth/beastie.4th.8
index 30d29b2..534a60c 100644
--- a/sys/boot/forth/beastie.4th.8
+++ b/sys/boot/forth/beastie.4th.8
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd May 16, 2011
+.Dd April 27, 2014
.Dt BEASTIE.4TH 8
.Os
.Sh NAME
@@ -119,6 +119,8 @@ Sets the desired row position of the logo. Default is 4.
If set to
.Dq YES ,
the beastie boot menu will be skipped.
+The beastie boot menu is always skipped if booting UEFI or running non-x86
+hardware.
.It Va loader_delay
If set to a number higher than zero, introduces a delay before starting the
beastie boot menu. During the delay the user can press either Ctrl-C to skip
diff --git a/sys/boot/forth/loader.conf.5 b/sys/boot/forth/loader.conf.5
index d638909..3c1ce1d 100644
--- a/sys/boot/forth/loader.conf.5
+++ b/sys/boot/forth/loader.conf.5
@@ -23,7 +23,7 @@
.\" SUCH DAMAGE.
.\"
.\" $FreeBSD$
-.Dd October 18, 2013
+.Dd April 27, 2014
.Dt LOADER.CONF 5
.Os
.Sh NAME
@@ -236,6 +236,8 @@ be displayed.
If set to
.Dq YES ,
the beastie boot menu will be skipped.
+The beastie boot menu is always skipped if booting UEFI or running non-x86
+hardware.
.It Va loader_logo Pq Dq Li orbbw
Selects a desired logo in the beastie boot menu.
Possible values are:
diff --git a/sys/boot/i386/libi386/Makefile b/sys/boot/i386/libi386/Makefile
index 20ed02c..1c4f049 100644
--- a/sys/boot/i386/libi386/Makefile
+++ b/sys/boot/i386/libi386/Makefile
@@ -52,6 +52,9 @@ CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}/../common \
# the location of libstand
CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/
+# Suppress warning from clang for FreeBSD %b and %D formats
+CFLAGS+= -fformat-extensions
+
.if ${MACHINE_CPUARCH} == "amd64"
CLEANFILES+= machine
machine:
diff --git a/sys/boot/i386/loader/Makefile b/sys/boot/i386/loader/Makefile
index b0a129e..b98a725 100644
--- a/sys/boot/i386/loader/Makefile
+++ b/sys/boot/i386/loader/Makefile
@@ -41,8 +41,12 @@ HAVE_ISABUS= yes
# Enable BootForth
BOOT_FORTH= yes
CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl -I${.CURDIR}/../../ficl/i386
+.if ${MACHINE_CPUARCH} == "amd64"
+LIBFICL= ${.OBJDIR}/../../ficl32/libficl.a
+.else
LIBFICL= ${.OBJDIR}/../../ficl/libficl.a
.endif
+.endif
.if defined(LOADER_BZIP2_SUPPORT)
CFLAGS+= -DLOADER_BZIP2_SUPPORT
OpenPOWER on IntegriCloud