Date: Thu, 28 Feb 2013 05:02:54 +0000 (UTC) From: Benno Rice <benno@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r247446 - in projects/uefi/sys/boot: amd64 amd64/efi amd64/efi/amd64 i386/efi Message-ID: <201302280502.r1S52suB051740@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: benno Date: Thu Feb 28 05:02:53 2013 New Revision: 247446 URL: http://svnweb.freebsd.org/changeset/base/247446 Log: Move UEFI loader to amd64. Added: projects/uefi/sys/boot/amd64/ projects/uefi/sys/boot/amd64/Makefile projects/uefi/sys/boot/amd64/Makefile.inc projects/uefi/sys/boot/amd64/efi/ projects/uefi/sys/boot/amd64/efi/Makefile - copied unchanged from r247444, projects/uefi/sys/boot/i386/efi/Makefile projects/uefi/sys/boot/amd64/efi/amd64/ - copied from r247443, projects/uefi/sys/boot/i386/efi/amd64/ projects/uefi/sys/boot/amd64/efi/amd64_tramp.S - copied unchanged from r247443, projects/uefi/sys/boot/i386/efi/amd64_tramp.S projects/uefi/sys/boot/amd64/efi/autoload.c - copied unchanged from r247444, projects/uefi/sys/boot/i386/efi/autoload.c projects/uefi/sys/boot/amd64/efi/bootinfo.c - copied unchanged from r247444, projects/uefi/sys/boot/i386/efi/bootinfo.c projects/uefi/sys/boot/amd64/efi/bootinfo64.c - copied unchanged from r247444, projects/uefi/sys/boot/i386/efi/bootinfo64.c projects/uefi/sys/boot/amd64/efi/conf.c - copied unchanged from r247443, projects/uefi/sys/boot/i386/efi/conf.c projects/uefi/sys/boot/amd64/efi/copy.c - copied unchanged from r247444, projects/uefi/sys/boot/i386/efi/copy.c projects/uefi/sys/boot/amd64/efi/devicename.c - copied unchanged from r247444, projects/uefi/sys/boot/i386/efi/devicename.c projects/uefi/sys/boot/amd64/efi/efifb.c - copied unchanged from r247443, projects/uefi/sys/boot/i386/efi/efifb.c projects/uefi/sys/boot/amd64/efi/efifb.h - copied unchanged from r247443, projects/uefi/sys/boot/i386/efi/efifb.h projects/uefi/sys/boot/amd64/efi/efimd.c - copied unchanged from r247443, projects/uefi/sys/boot/i386/efi/efimd.c projects/uefi/sys/boot/amd64/efi/elf64_freebsd.c - copied unchanged from r247445, projects/uefi/sys/boot/i386/efi/elf64_freebsd.c projects/uefi/sys/boot/amd64/efi/ldscript.amd64 - copied unchanged from r247443, projects/uefi/sys/boot/i386/efi/ldscript.amd64 projects/uefi/sys/boot/amd64/efi/main.c - copied unchanged from r247444, projects/uefi/sys/boot/i386/efi/main.c projects/uefi/sys/boot/amd64/efi/reloc.c - copied unchanged from r247443, projects/uefi/sys/boot/i386/efi/reloc.c projects/uefi/sys/boot/amd64/efi/start.S - copied unchanged from r247443, projects/uefi/sys/boot/i386/efi/start.S projects/uefi/sys/boot/amd64/efi/version - copied unchanged from r247443, projects/uefi/sys/boot/i386/efi/version projects/uefi/sys/boot/amd64/efi/x86_efi.h - copied unchanged from r247444, projects/uefi/sys/boot/i386/efi/x86_efi.h Deleted: projects/uefi/sys/boot/i386/efi/ Added: projects/uefi/sys/boot/amd64/Makefile ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/uefi/sys/boot/amd64/Makefile Thu Feb 28 05:02:53 2013 (r247446) @@ -0,0 +1,7 @@ +# $FreeBSD$ + +.include <bsd.own.mk> + +SUBDIR= efi + +.include <bsd.subdir.mk> Added: projects/uefi/sys/boot/amd64/Makefile.inc ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/uefi/sys/boot/amd64/Makefile.inc Thu Feb 28 05:02:53 2013 (r247446) @@ -0,0 +1,11 @@ +# Common defines for all of /sys/boot/i386/ +# +# $FreeBSD$ + +BINDIR?= /boot + +CFLAGS+= -ffreestanding -mno-mmx -mno-3dnow -mno-sse -mno-sse2 \ + -mno-sse3 -msoft-float +LDFLAGS+= -nostdlib + +.include "../Makefile.inc" Copied: projects/uefi/sys/boot/amd64/efi/Makefile (from r247444, projects/uefi/sys/boot/i386/efi/Makefile) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/uefi/sys/boot/amd64/efi/Makefile Thu Feb 28 05:02:53 2013 (r247446, copy of r247444, projects/uefi/sys/boot/i386/efi/Makefile) @@ -0,0 +1,96 @@ +# $FreeBSD$ + +NO_MAN= +WITHOUT_SSP= +BUILDING_EFI= + +.include <bsd.own.mk> + +PROG= loader.sym +INTERNALPROG= + +# architecture-specific loader code +SRCS= main.c conf.c vers.c reloc.c elf64_freebsd.c +SRCS+= copy.c bootinfo.c bootinfo64.c autoload.c devicename.c efimd.c +SRCS+= efifb.c amd64_tramp.S start.S + +CFLAGS+= -fPIC +CFLAGS+= -I. +CFLAGS+= -I${.CURDIR}/../../efi/include +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/${MACHINE_CPUARCH} +.if ${MACHINE_CPUARCH} == "amd64" +LIBFICL= ${.OBJDIR}/../../ficl64/libficl.a +.else +LIBFICL= ${.OBJDIR}/../../ficl/libficl.a +.endif +.endif + +# Include bcache code. +HAVE_BCACHE= yes + +# Always add MI sources +.PATH: ${.CURDIR}/../../common +.include "${.CURDIR}/../../common/Makefile.inc" +CFLAGS+= -I${.CURDIR}/../../common + +FILES= loader.efi +FILESMODE_loader.efi= ${BINMODE} + +LDSCRIPT= ${.CURDIR}/ldscript.${MACHINE_CPUARCH} +LDFLAGS= -Wl,-T${LDSCRIPT} -Wl,-Bsymbolic -shared -Wl,-znocombreloc + +${PROG}: ${LDSCRIPT} + +CLEANFILES= vers.c loader.efi + +NEWVERSWHAT= "EFI loader" ${MACHINE_CPUARCH} + +vers.c: ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version + sh ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version ${NEWVERSWHAT} + +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 .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 +CFLAGS+= -I${.CURDIR}/../libi386 +CFLAGS+= -I${.CURDIR}/../btx/lib +CFLAGS+= -I${.CURDIR}/../../common + +DPADD= ${LIBFICL} ${LIBEFI} ${LIBSTAND} +LDADD= ${LIBFICL} ${LIBEFI} ${LIBSTAND} + +.include <bsd.prog.mk> + +beforedepend ${OBJS}: machine x86 + +CLEANFILES+= machine x86 + +machine: + ln -sf ${.CURDIR}/../../../amd64/include machine + +x86: + ln -sf ${.CURDIR}/../../../x86/include x86 Copied: projects/uefi/sys/boot/amd64/efi/amd64_tramp.S (from r247443, projects/uefi/sys/boot/i386/efi/amd64_tramp.S) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/uefi/sys/boot/amd64/efi/amd64_tramp.S Thu Feb 28 05:02:53 2013 (r247446, copy of r247443, projects/uefi/sys/boot/i386/efi/amd64_tramp.S) @@ -0,0 +1,34 @@ +#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 + + call %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 Copied: projects/uefi/sys/boot/amd64/efi/autoload.c (from r247444, projects/uefi/sys/boot/i386/efi/autoload.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/uefi/sys/boot/amd64/efi/autoload.c Thu Feb 28 05:02:53 2013 (r247446, copy of r247444, projects/uefi/sys/boot/i386/efi/autoload.c) @@ -0,0 +1,35 @@ +/*- + * Copyright (c) 2010 Rui Paulo <rpaulo@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +int +x86_efi_autoload(void) +{ + + return (0); +} Copied: projects/uefi/sys/boot/amd64/efi/bootinfo.c (from r247444, projects/uefi/sys/boot/i386/efi/bootinfo.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/uefi/sys/boot/amd64/efi/bootinfo.c Thu Feb 28 05:02:53 2013 (r247446, copy of r247444, projects/uefi/sys/boot/i386/efi/bootinfo.c) @@ -0,0 +1,142 @@ +/*- + * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> + * Copyright (c) 2006 Marcel Moolenaar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stand.h> +#include <string.h> +#include <sys/param.h> +#include <sys/reboot.h> +#include <sys/linker.h> + +#include <efi.h> +#include <efilib.h> + +#include "bootstrap.h" +#include "x86_efi.h" + +/* + * Return a 'boothowto' value corresponding to the kernel arguments in + * (kargs) and any relevant environment variables. + */ +static struct +{ + const char *ev; + int mask; +} howto_names[] = { + { "boot_askname", RB_ASKNAME}, + { "boot_cdrom", RB_CDROM}, + { "boot_ddb", RB_KDB}, + { "boot_dfltroot", RB_DFLTROOT}, + { "boot_gdb", RB_GDB}, + { "boot_multicons", RB_MULTIPLE}, + { "boot_mute", RB_MUTE}, + { "boot_pause", RB_PAUSE}, + { "boot_serial", RB_SERIAL}, + { "boot_single", RB_SINGLE}, + { "boot_verbose", RB_VERBOSE}, + { NULL, 0} +}; + +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 +}; + +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. + */ +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); +} Copied: projects/uefi/sys/boot/amd64/efi/bootinfo64.c (from r247444, projects/uefi/sys/boot/i386/efi/bootinfo64.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/uefi/sys/boot/amd64/efi/bootinfo64.c Thu Feb 28 05:02:53 2013 (r247446, copy of r247444, projects/uefi/sys/boot/i386/efi/bootinfo64.c) @@ -0,0 +1,209 @@ +/*- + * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stand.h> +#include <sys/param.h> +#include <sys/reboot.h> +#include <sys/linker.h> +#include <machine/cpufunc.h> +#include <machine/psl.h> +#include <machine/specialreg.h> +#include "bootstrap.h" +#include "x86_efi.h" + +/* + * 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) { \ + u_int32_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(u_int64_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(u_int64_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(u_int64_t));\ +} + +#define MOD_END(a, c) { \ + COPY32(MODINFO_END, a, c); \ + COPY32(0, a, c); \ +} + +static vm_offset_t +bi_copymodules64(vm_offset_t addr) +{ + struct preloaded_file *fp; + struct file_metadata *md; + int c; + u_int64_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 field 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); +} + +extern int ldr_bootinfo(struct preloaded_file *kfp); + +/* + * 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_load64(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; + u_int64_t kernend; + u_int64_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) { /* bad $rootdev/$currdev */ + 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)); + + /* find the last module in the chain */ + 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); + ldr_bootinfo(kfp); + + /* Figure out the size and location of the metadata */ + *modulep = addr; + size = bi_copymodules64(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_copymodules64(addr); + + return(0); +} Copied: projects/uefi/sys/boot/amd64/efi/conf.c (from r247443, projects/uefi/sys/boot/i386/efi/conf.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/uefi/sys/boot/amd64/efi/conf.c Thu Feb 28 05:02:53 2013 (r247446, copy of r247443, projects/uefi/sys/boot/i386/efi/conf.c) @@ -0,0 +1,69 @@ +/*- + * Copyright (c) 2006 Marcel Moolenaar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stand.h> +#include <bootstrap.h> +#include <efi.h> +#include <efilib.h> + +struct devsw *devsw[] = { + &efipart_dev, + &efinet_dev, + NULL +}; + +struct fs_ops *file_system[] = { + &dosfs_fsops, + &ufs_fsops, + &cd9660_fsops, + &nfs_fsops, + &gzipfs_fsops, + NULL +}; + +struct netif_driver *netif_drivers[] = { + &efinetif, + NULL +}; + +extern struct file_format amd64_elf; +extern struct file_format amd64_elf_obj; + +struct file_format *file_formats[] = { + &amd64_elf, + &amd64_elf_obj, + NULL +}; + +extern struct console efi_console; + +struct console *consoles[] = { + &efi_console, + NULL +}; Copied: projects/uefi/sys/boot/amd64/efi/copy.c (from r247444, projects/uefi/sys/boot/i386/efi/copy.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/uefi/sys/boot/amd64/efi/copy.c Thu Feb 28 05:02:53 2013 (r247446, copy of r247444, projects/uefi/sys/boot/i386/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: %d\n", + 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++; +} Copied: projects/uefi/sys/boot/amd64/efi/devicename.c (from r247444, projects/uefi/sys/boot/i386/efi/devicename.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/uefi/sys/boot/amd64/efi/devicename.c Thu Feb 28 05:02:53 2013 (r247446, copy of r247444, projects/uefi/sys/boot/i386/efi/devicename.c) @@ -0,0 +1,169 @@ +/*- + * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> + * Copyright (c) 2006 Marcel Moolenaar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stand.h> +#include <string.h> +#include <sys/disklabel.h> +#include "bootstrap.h" + +#include <efi.h> +#include <efilib.h> + +static int x86_efi_parsedev(struct devdesc **, const char *, const char **); + +/* + * Point (dev) at an allocated device specifier for the device matching the + * path in (devspec). If it contains an explicit device specification, + * use that. If not, use the default device. + */ +int +x86_efi_getdev(void **vdev, const char *devspec, const char **path) +{ + struct devdesc **dev = (struct devdesc **)vdev; + int rv; + + /* + * If it looks like this is just a path and no device, then + * use the current device instead. + */ + if (devspec == NULL || *devspec == '/' || !strchr(devspec, ':')) { + 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 (x86_efi_parsedev(dev, devspec, path)); +} + +/* + * Point (dev) at an allocated device specifier matching the string version + * at the beginning of (devspec). Return a pointer to the remaining + * text in (path). + * + * In all cases, the beginning of (devspec) is compared to the names + * of known devices in the device switch, and then any following text + * is parsed according to the rules applied to the device type. + * + * For disk-type devices, the syntax is: + * + * fs<unit>: + */ +static int +x86_efi_parsedev(struct devdesc **dev, const char *devspec, const char **path) +{ + struct devdesc *idev; + struct devsw *dv; + char *cp; + const char *np; + int i, err; + + /* minimum length check */ + if (strlen(devspec) < 2) + return (EINVAL); + + /* look for a device that matches */ + for (i = 0; devsw[i] != NULL; i++) { + dv = devsw[i]; + if (!strncmp(devspec, dv->dv_name, strlen(dv->dv_name))) + break; + } + if (devsw[i] == NULL) + return (ENOENT); + + idev = malloc(sizeof(struct devdesc)); + if (idev == NULL) + return (ENOMEM); + + idev->d_dev = dv; + idev->d_type = dv->dv_type; + idev->d_unit = -1; + + err = 0; + np = devspec + strlen(dv->dv_name); + if (*np != '\0' && *np != ':') { + idev->d_unit = strtol(np, &cp, 0); + if (cp == np) { + idev->d_unit = -1; + free(idev); + return (EUNIT); + } + } + if (*cp != '\0' && *cp != ':') { + free(idev); + return (EINVAL); + } + + if (path != NULL) + *path = (*cp == 0) ? cp : cp + 1; + if (dev != NULL) + *dev = idev; + else + free(idev); + return (0); +} + +char * +x86_efi_fmtdev(void *vdev) +{ + struct devdesc *dev = (struct devdesc *)vdev; + static char buf[32]; /* XXX device length constant? */ + + switch(dev->d_type) { + case DEVT_NONE: + strcpy(buf, "(no device)"); + break; + + default: + sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_unit); + break; + } + + return(buf); +} + +/* + * Set currdev to suit the value being supplied in (value) + */ +int +x86_efi_setcurrdev(struct env_var *ev, int flags, const void *value) +{ + struct devdesc *ncurr; + int rv; + + rv = x86_efi_parsedev(&ncurr, value, NULL); + if (rv != 0) + return(rv); + + free(ncurr); + env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL); + return (0); +} Copied: projects/uefi/sys/boot/amd64/efi/efifb.c (from r247443, projects/uefi/sys/boot/i386/efi/efifb.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/uefi/sys/boot/amd64/efi/efifb.c Thu Feb 28 05:02:53 2013 (r247446, copy of r247443, projects/uefi/sys/boot/i386/efi/efifb.c) @@ -0,0 +1,88 @@ +/*- + * 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/efi.h> + +static EFI_GUID gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; + +void +efi_find_framebuffer(struct efi_header *efihdr) +{ + 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)) { + efihdr->fb.fb_present = 0; + return; + } + + mode = gop->Mode; + info = gop->Mode->Info; + + efihdr->fb.fb_present = 1; + efihdr->fb.fb_addr = mode->FrameBufferBase; + efihdr->fb.fb_size = mode->FrameBufferSize; + efihdr->fb.fb_height = info->VerticalResolution; + efihdr->fb.fb_width = info->HorizontalResolution; + efihdr->fb.fb_stride = info->PixelsPerScanLine; + + switch (info->PixelFormat) { + case PixelRedGreenBlueReserved8BitPerColor: + efihdr->fb.fb_mask_red = 0x000000ff; + efihdr->fb.fb_mask_green = 0x0000ff00; + efihdr->fb.fb_mask_blue = 0x00ff0000; + efihdr->fb.fb_mask_reserved = 0xff000000; + break; + case PixelBlueGreenRedReserved8BitPerColor: + efihdr->fb.fb_mask_red = 0x00ff0000; + efihdr->fb.fb_mask_green = 0x0000ff00; + efihdr->fb.fb_mask_blue = 0x000000ff; + efihdr->fb.fb_mask_reserved = 0xff000000; + break; + case PixelBitMask: + efihdr->fb.fb_mask_red = info->PixelInformation.RedMask; + efihdr->fb.fb_mask_green = info->PixelInformation.GreenMask; + efihdr->fb.fb_mask_blue = info->PixelInformation.BlueMask; + efihdr->fb.fb_mask_reserved = + info->PixelInformation.ReservedMask; + break; + default: + efihdr->fb.fb_present = 0; + } +} Copied: projects/uefi/sys/boot/amd64/efi/efifb.h (from r247443, projects/uefi/sys/boot/i386/efi/efifb.h) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/uefi/sys/boot/amd64/efi/efifb.h Thu Feb 28 05:02:53 2013 (r247446, copy of r247443, projects/uefi/sys/boot/i386/efi/efifb.h) @@ -0,0 +1,6 @@ +#ifndef _EFIFB_H_ +#define _EFIFB_H_ *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201302280502.r1S52suB051740>