Date: Thu, 13 Feb 2014 20:41:25 +0000 (UTC) From: Andrew Turner <andrew@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r261854 - in projects/arm64/sys/boot: . arm64 arm64/efi Message-ID: <201402132041.s1DKfPXH049707@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: andrew Date: Thu Feb 13 20:41:25 2014 New Revision: 261854 URL: http://svnweb.freebsd.org/changeset/base/261854 Log: Add the arm64 bits to build an efi loader. We can't use objcopy to build the efi header in assembly, then use objcopy to create a 'binary' file with this header at the start. Added: projects/arm64/sys/boot/Makefile.arm64 (contents, props changed) projects/arm64/sys/boot/arm64/ projects/arm64/sys/boot/arm64/Makefile (contents, props changed) projects/arm64/sys/boot/arm64/Makefile.inc (contents, props changed) projects/arm64/sys/boot/arm64/efi/ projects/arm64/sys/boot/arm64/efi/Makefile (contents, props changed) projects/arm64/sys/boot/arm64/efi/autoload.c (contents, props changed) projects/arm64/sys/boot/arm64/efi/conf.c (contents, props changed) projects/arm64/sys/boot/arm64/efi/devicename.c (contents, props changed) projects/arm64/sys/boot/arm64/efi/ldscript.arm64 projects/arm64/sys/boot/arm64/efi/libarm64.h (contents, props changed) projects/arm64/sys/boot/arm64/efi/main.c (contents, props changed) projects/arm64/sys/boot/arm64/efi/reloc.c (contents, props changed) projects/arm64/sys/boot/arm64/efi/start.S (contents, props changed) projects/arm64/sys/boot/arm64/efi/version Added: projects/arm64/sys/boot/Makefile.arm64 ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/arm64/sys/boot/Makefile.arm64 Thu Feb 13 20:41:25 2014 (r261854) @@ -0,0 +1,3 @@ +# $FreeBSD$ + +SUBDIR+= efi Added: projects/arm64/sys/boot/arm64/Makefile ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/arm64/sys/boot/arm64/Makefile Thu Feb 13 20:41:25 2014 (r261854) @@ -0,0 +1,5 @@ +# $FreeBSD$ + +SUBDIR= efi + +.include <bsd.subdir.mk> Added: projects/arm64/sys/boot/arm64/Makefile.inc ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/arm64/sys/boot/arm64/Makefile.inc Thu Feb 13 20:41:25 2014 (r261854) @@ -0,0 +1,9 @@ +# $FreeBSD$ + +BINDIR?= /boot + +# Options used when building standalone components +CFLAGS+= -ffreestanding -fshort-wchar -Wformat +LDFLAGS+= -nostdlib + +.include "../Makefile.inc" Added: projects/arm64/sys/boot/arm64/efi/Makefile ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/arm64/sys/boot/arm64/efi/Makefile Thu Feb 13 20:41:25 2014 (r261854) @@ -0,0 +1,70 @@ +# $FreeBSD$ + +NO_MAN= +BUILDING_EFI= + +.include <bsd.own.mk> +MK_SSP= no + +PROG= loader.sym +INTERNALPROG= + +# architecture-specific loader code +SRCS= start.S main.c conf.c vers.c reloc.c autoload.c +SRCS+= devicename.c + +CFLAGS+= -fno-builtin +CFLAGS+= -I${.CURDIR} +CFLAGS+= -I${.CURDIR}/../../efi/include +CFLAGS+= -I${.CURDIR}/../../efi/include/arm64 + +.if ${MK_FORTH} != "no" +BOOT_FORTH= yes +CFLAGS+= -DBOOT_FORTH +CFLAGS+= -I${.CURDIR}/../../ficl +CFLAGS+= -I${.CURDIR}/../../ficl/arm64 +LIBFICL= ${.OBJDIR}/../../ficl/libficl.a +.endif + +# 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.arm64 +LDFLAGS= -Wl,-T${LDSCRIPT} -Wl,-Bsymbolic -shared + +${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= /home/andrew/freebsd/repo/aarch64-freebsd-sandbox/toolchain/build/bin/aarch64-none-freebsd10-objcopy +OBJDUMP= /home/andrew/freebsd/repo/aarch64-freebsd-sandbox/toolchain/build/bin/aarch64-none-freebsd10-objdump +#OBJCOPY?= objcopy +#OBJDUMP?= objdump + +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 .rela.dyn -j .reloc -j .sdata -j .text -j set_Xcommand_set \ + -j .sbss -j .bss -O binary ${.ALLSRC} ${.TARGET} + +LIBEFI= ${.OBJDIR}/../../efi/libefi/libefi.a + +DPADD= ${LIBFICL} ${LIBEFI} ${LIBSTAND} +LDADD= ${LIBFICL} ${LIBEFI} ${.OBJDIR}/../../../../lib/libstand/libstand.a +#${LIBSTAND} + +.include <bsd.prog.mk> + Added: projects/arm64/sys/boot/arm64/efi/autoload.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/arm64/sys/boot/arm64/efi/autoload.c Thu Feb 13 20:41:25 2014 (r261854) @@ -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 +amd64_autoload(void) +{ + + return (0); +} Added: projects/arm64/sys/boot/arm64/efi/conf.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/arm64/sys/boot/arm64/efi/conf.c Thu Feb 13 20:41:25 2014 (r261854) @@ -0,0 +1,66 @@ +/*- + * 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[] = { +#if 0 + &dosfs_fsops, + &ufs_fsops, + &cd9660_fsops, + &nfs_fsops, + &gzipfs_fsops, +#endif + NULL +}; + +struct netif_driver *netif_drivers[] = { + &efinetif, + NULL +}; + +struct file_format *file_formats[] = { + NULL +}; + +extern struct console efi_console; + +struct console *consoles[] = { + &efi_console, + NULL +}; Added: projects/arm64/sys/boot/arm64/efi/devicename.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/arm64/sys/boot/arm64/efi/devicename.c Thu Feb 13 20:41:25 2014 (r261854) @@ -0,0 +1,170 @@ +/*- + * 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 arm64_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 +arm64_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 = arm64_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 (arm64_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 +arm64_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 * +arm64_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 +arm64_setcurrdev(struct env_var *ev, int flags, const void *value) +{ + struct devdesc *ncurr; + int rv; + + rv = arm64_parsedev(&ncurr, value, NULL); + if (rv != 0) + return(rv); + + free(ncurr); + env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL); + return (0); +} + Added: projects/arm64/sys/boot/arm64/efi/ldscript.arm64 ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/arm64/sys/boot/arm64/efi/ldscript.arm64 Thu Feb 13 20:41:25 2014 (r261854) @@ -0,0 +1,84 @@ +/* $FreeBSD$ */ +/* +OUTPUT_FORMAT("elf64-aarch64-freebsd", "elf64-aarch64-freebsd", "elf64-aarch64-freebsd") +*/ +OUTPUT_ARCH(aarch64) +ENTRY(_start) +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = 0; + ImageBase = .; + . = SIZEOF_HEADERS; + . = ALIGN(4096); + .eh_frame : { + *(.eh_frame) + } + .text : { + *(.text .stub .text.* .gnu.linkonce.t.*) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.plt) + } =0x00300000010070000002000001000400 + . = ALIGN(4096); + .data : { + *(.rodata .rodata.* .gnu.linkonce.r.*) + *(.rodata1) + *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) + *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) + *(.opd) + *(.data .data.* .gnu.linkonce.d.*) + *(.data1) + *(.plabel) + + . = ALIGN(16); + __bss_start = .; + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + *(.dynbss) + *(.bss *.bss.*) + *(COMMON) + . = ALIGN(16); + __bss_end = .; + } + . = ALIGN(4096); + set_Xcommand_set : { + __start_set_Xcommand_set = .; + *(set_Xcommand_set) + __stop_set_Xcommand_set = .; + } + . = ALIGN(4096); + __gp = .; + .sdata : { + *(.got.plt .got) + *(.sdata .sdata.* .gnu.linkonce.s.*) + *(dynsbss) + *(.scommon) + } + . = ALIGN(4096); + .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.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.*) + } + . = ALIGN(4096); + .reloc : { *(.reloc) } + . = ALIGN(4096); + .hash : { *(.hash) } + . = ALIGN(4096); + .dynsym : { *(.dynsym) } + . = ALIGN(4096); + .dynstr : { *(.dynstr) } + _edata = .; +} Added: projects/arm64/sys/boot/arm64/efi/libarm64.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/arm64/sys/boot/arm64/efi/libarm64.h Thu Feb 13 20:41:25 2014 (r261854) @@ -0,0 +1,38 @@ +/*- + * Copyright (c) 2014 Andrew Turner + * 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. + * + * $FreeBSD$ + */ + +#ifndef _LIBARM64_H_ +#define _LIBARM64_H_ + +int amd64_autoload(void); +int arm64_getdev(void **vdev, const char *devspec, const char **path); +char *arm64_fmtdev(void *vdev); +int arm64_setcurrdev(struct env_var *ev, int flags, const void *value); + +#endif /* _LIBARM64_H_ */ + Added: projects/arm64/sys/boot/arm64/efi/main.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/arm64/sys/boot/arm64/efi/main.c Thu Feb 13 20:41:25 2014 (r261854) @@ -0,0 +1,410 @@ +/*- + * Copyright (c) 2008-2010 Rui Paulo + * 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 <string.h> +#include <setjmp.h> + +#include <efi.h> +#include <efilib.h> + +#include <bootstrap.h> + +#include <libarm64.h> + +extern char bootprog_name[]; +extern char bootprog_rev[]; +extern char bootprog_date[]; +extern char bootprog_maker[]; + +struct devdesc currdev; /* our current device */ +struct arch_switch archsw; /* MI/MD interface boundary */ + +ssize_t +arm64_copyin(const void *src, vm_offset_t dest, const size_t len) +{ + bcopy(src, (void *)dest, len); + return (len); +} + +ssize_t +arm64_copyout(vm_offset_t src, void *dest, const size_t len) +{ + bcopy((void *)src, dest, len); + return (len); +} + +ssize_t +arm64_readin(int fd, vm_offset_t va, size_t len) +{ + return read(fd, va, len); +} + +#if 0 +EFI_GUID acpi = ACPI_TABLE_GUID; +EFI_GUID acpi20 = ACPI_20_TABLE_GUID; +EFI_GUID devid = DEVICE_PATH_PROTOCOL; +#endif +EFI_GUID imgid = LOADED_IMAGE_PROTOCOL; +#if 0 +EFI_GUID mps = MPS_TABLE_GUID; +EFI_GUID netid = EFI_SIMPLE_NETWORK_PROTOCOL; +EFI_GUID smbios = SMBIOS_TABLE_GUID; +#endif + +EFI_STATUS +main(int argc, CHAR16 *argv[]) +{ + char vendor[128]; + EFI_LOADED_IMAGE *img; + int i, status; + + /* + * 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 + * printf() etc. once this is done. + */ + cons_probe(); + + /* + * March through the device switch probing for things. + */ + for (i = 0; devsw[i] != NULL; i++) + if (devsw[i]->dv_init != NULL) + (devsw[i]->dv_init)(); + + /* Get our loaded image protocol interface structure. */ + BS->HandleProtocol(IH, &imgid, (VOID**)&img); + + printf("Image base: 0x%lx\n", (u_long)img->ImageBase); + printf("EFI version: %d.%02d\n", ST->Hdr.Revision >> 16, + ST->Hdr.Revision & 0xffff); + printf("EFI Firmware: "); + /* printf doesn't understand EFI Unicode */ + ST->ConOut->OutputString(ST->ConOut, ST->FirmwareVendor); + printf(" (rev %d.%02d)\n", ST->FirmwareRevision >> 16, + ST->FirmwareRevision & 0xffff); + + printf("\n"); + printf("%s, Revision %s\n", bootprog_name, bootprog_rev); + printf("(%s, %s)\n", bootprog_maker, bootprog_date); + + status = efi_handle_lookup(img->DeviceHandle, &currdev.d_dev, + &currdev.d_unit); + if (status != 0) { + status = efi_handle_any(&currdev.d_dev, &currdev.d_unit); + if (status != 0) { + printf("Boot device not found\n"); + /* TODO: What error should we use? */ + return (EFI_SUCCESS); + } + } + currdev.d_type = currdev.d_dev->dv_type; + + /* + * Disable the watchdog timer. By default the boot manager sets + * the timer to 5 minutes before invoking a boot option. If we + * want to return to the boot manager, we have to disable the + * watchdog timer and since we're an interactive program, we don't + * want to wait until the user types "quit". The timer may have + * fired by then. We don't care if this fails. It does not prevent + * normal functioning in any way... + */ + BS->SetWatchdogTimer(0, 0, 0, NULL); + + env_setenv("currdev", EV_VOLATILE, arm64_fmtdev(&currdev), + arm64_setcurrdev, env_nounset); + env_setenv("loaddev", EV_VOLATILE, arm64_fmtdev(&currdev), env_noset, + env_nounset); + +#if 0 + setenv("LINES", "24", 1); /* optional */ +#endif + + archsw.arch_autoload = amd64_autoload; + archsw.arch_getdev = arm64_getdev; + archsw.arch_copyin = arm64_copyin; + archsw.arch_copyout = arm64_copyout; + archsw.arch_readin = arm64_readin; + + interact(); /* doesn't return */ + + return (EFI_SUCCESS); /* keep compiler happy */ +} + +#if 0 +COMMAND_SET(reboot, "reboot", "reboot the system", command_reboot); + +static int +command_reboot(int argc, char *argv[]) +{ + int i; + + for (i = 0; devsw[i] != NULL; ++i) + if (devsw[i]->dv_cleanup != NULL) + (devsw[i]->dv_cleanup)(); + + RS->ResetSystem(EfiResetCold, EFI_SUCCESS, 23, + (CHAR16 *)"Reboot from the loader"); + + /* NOTREACHED */ + return (CMD_ERROR); +} + +COMMAND_SET(quit, "quit", "exit the loader", command_quit); + +static int +command_quit(int argc, char *argv[]) +{ + exit(0); + return (CMD_OK); +} + +COMMAND_SET(memmap, "memmap", "print memory map", command_memmap); + +static int +command_memmap(int argc, char *argv[]) +{ + UINTN sz; + EFI_MEMORY_DESCRIPTOR *map, *p; + UINTN key, dsz; + UINT32 dver; + EFI_STATUS status; + int i, ndesc; + static char *types[] = { + "Reserved", + "LoaderCode", + "LoaderData", + "BootServicesCode", + "BootServicesData", + "RuntimeServicesCode", + "RuntimeServicesData", + "ConventionalMemory", + "UnusableMemory", + "ACPIReclaimMemory", + "ACPIMemoryNVS", + "MemoryMappedIO", + "MemoryMappedIOPortSpace", + "PalCode" + }; + + sz = 0; + status = BS->GetMemoryMap(&sz, 0, &key, &dsz, &dver); + if (status != EFI_BUFFER_TOO_SMALL) { + printf("Can't determine memory map size\n"); + return CMD_ERROR; + } + map = malloc(sz); + status = BS->GetMemoryMap(&sz, map, &key, &dsz, &dver); + if (EFI_ERROR(status)) { + printf("Can't read memory map\n"); + return CMD_ERROR; + } + + 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 ", + types[p->Type], + p->PhysicalStart, + p->VirtualStart, + p->NumberOfPages); + if (p->Attribute & EFI_MEMORY_UC) + printf("UC "); + if (p->Attribute & EFI_MEMORY_WC) + printf("WC "); + if (p->Attribute & EFI_MEMORY_WT) + printf("WT "); + if (p->Attribute & EFI_MEMORY_WB) + printf("WB "); + if (p->Attribute & EFI_MEMORY_UCE) + printf("UCE "); + if (p->Attribute & EFI_MEMORY_WP) + printf("WP "); + if (p->Attribute & EFI_MEMORY_RP) + printf("RP "); + if (p->Attribute & EFI_MEMORY_XP) + printf("XP "); + printf("\n"); + } + + return CMD_OK; +} + +COMMAND_SET(configuration, "configuration", + "print configuration tables", command_configuration); + +static const char * +guid_to_string(EFI_GUID *guid) +{ + static char buf[40]; + + sprintf(buf, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", + guid->Data1, guid->Data2, guid->Data3, guid->Data4[0], + guid->Data4[1], guid->Data4[2], guid->Data4[3], guid->Data4[4], + guid->Data4[5], guid->Data4[6], guid->Data4[7]); + return (buf); +} + +static int +command_configuration(int argc, char *argv[]) +{ + int i; + + printf("NumberOfTableEntries=%ld\n", ST->NumberOfTableEntries); + for (i = 0; i < ST->NumberOfTableEntries; i++) { + EFI_GUID *guid; + + printf(" "); + guid = &ST->ConfigurationTable[i].VendorGuid; + if (!memcmp(guid, &mps, sizeof(EFI_GUID))) + printf("MPS Table"); + else if (!memcmp(guid, &acpi, sizeof(EFI_GUID))) + printf("ACPI Table"); + else if (!memcmp(guid, &acpi20, sizeof(EFI_GUID))) + printf("ACPI 2.0 Table"); + else if (!memcmp(guid, &smbios, sizeof(EFI_GUID))) + printf("SMBIOS Table"); + else + printf("Unknown Table (%s)", guid_to_string(guid)); + printf(" at %p\n", ST->ConfigurationTable[i].VendorTable); + } + + return CMD_OK; +} + + +COMMAND_SET(mode, "mode", "change or display text modes", command_mode); + +static int +command_mode(int argc, char *argv[]) +{ + unsigned int cols, rows, mode; + int i; + char *cp; + char rowenv[8]; + EFI_STATUS status; + SIMPLE_TEXT_OUTPUT_INTERFACE *conout; + + conout = ST->ConOut; + + if (argc > 1) { + mode = strtol(argv[1], &cp, 0); + if (cp[0] != '\0') { + printf("Invalid mode\n"); + return (CMD_ERROR); + } + status = conout->QueryMode(conout, mode, &cols, &rows); + if (EFI_ERROR(status)) { + printf("invalid mode %d\n", mode); + return (CMD_ERROR); + } + status = conout->SetMode(conout, mode); + if (EFI_ERROR(status)) { + printf("couldn't set mode %d\n", mode); + return (CMD_ERROR); + } + sprintf(rowenv, "%d", rows); + setenv("LINES", rowenv, 1); + + return (CMD_OK); + } + + for (i = 0; ; i++) { + status = conout->QueryMode(conout, i, &cols, &rows); + if (EFI_ERROR(status)) + break; + printf("Mode %d: %d columns, %d rows\n", i, cols, rows); + } + + if (i != 0) + printf("Choose the mode with \"col <mode number>\"\n"); + + return (CMD_OK); +} + + +COMMAND_SET(nvram, "nvram", "get or set NVRAM variables", command_nvram); + +static int +command_nvram(int argc, char *argv[]) +{ + CHAR16 var[128]; + 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; + SIMPLE_TEXT_OUTPUT_INTERFACE *conout; + int i; + + conout = ST->ConOut; + + /* Initiate the search */ + status = RS->GetNextVariableName(&varsz, NULL, NULL); + + for (; status != EFI_NOT_FOUND; ) { + status = RS->GetNextVariableName(&varsz, var, + &varguid); + //if (EFI_ERROR(status)) + //break; + + conout->OutputString(conout, var); + printf("="); + datasz = 0; + status = RS->GetVariable(var, &varguid, NULL, &datasz, + NULL); + /* XXX: check status */ + data = malloc(datasz); + status = RS->GetVariable(var, &varguid, NULL, &datasz, + data); + if (EFI_ERROR(status)) + printf("<error retrieving variable>"); + else { + for (i = 0; i < datasz; i++) { + if (isalnum(data[i]) || isspace(data[i])) + printf("%c", data[i]); + else + printf("\\x%02x", data[i]); + } + } + /* XXX */ + pager_output("\n"); + free(data); + } + + return (CMD_OK); +} +#endif + Added: projects/arm64/sys/boot/arm64/efi/reloc.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/arm64/sys/boot/arm64/efi/reloc.c Thu Feb 13 20:41:25 2014 (r261854) @@ -0,0 +1,86 @@ +/*- + * 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> + +/* + * A simple relocator for ARM64 EFI binaries. + */ +EFI_STATUS +_reloc(unsigned long ImageBase, Elf64_Dyn *dynamic) +{ + unsigned long relent, relcnt; + unsigned long *newaddr; + Elf64_Rela *rel; + Elf64_Dyn *dynp; + + /* + * Find the relocation address, its size and the relocation entry. + */ + relent = 0; + relcnt = 0; + for (dynp = dynamic; dynp->d_tag != DT_NULL; dynp++) { + switch (dynp->d_tag) { + case DT_RELA: + rel = (Elf64_Rela *)((caddr_t)dynp->d_un.d_ptr + + ImageBase); + break; + case DT_RELACOUNT: + relcnt = dynp->d_un.d_val; + break; + case DT_RELAENT: + relent = dynp->d_un.d_val; + break; + default: + break; + } + } + + /* + * Perform the actual relocation. + */ + for (; relcnt != 0; relcnt--) { + switch (ELF64_R_TYPE(rel->r_info)) { + case R_AARCH64_RELATIVE: + newaddr = (unsigned long *)(ImageBase + rel->r_offset); + *newaddr = ImageBase + rel->r_addend; + break; + default: *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201402132041.s1DKfPXH049707>