svn commit: r261854 - in projects/arm64/sys/boot: . arm64 arm64/efi

Andrew Turner andrew at FreeBSD.org
Thu Feb 13 20:41:28 UTC 2014


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 at 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 at 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 at 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 ***


More information about the svn-src-projects mailing list