summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorandrew <andrew@FreeBSD.org>2015-04-05 18:37:39 +0000
committerandrew <andrew@FreeBSD.org>2015-04-05 18:37:39 +0000
commit9b13105d8dec85c362a35862ba2f9f382a2444a6 (patch)
treebec1710d8bb5bfdcfc328a9206c3b28271fe89b4
parent1e93730b8cf2f5b02bd29e2f368a83e12469a145 (diff)
downloadFreeBSD-src-9b13105d8dec85c362a35862ba2f9f382a2444a6.zip
FreeBSD-src-9b13105d8dec85c362a35862ba2f9f382a2444a6.tar.gz
Add FDT support to loader.efi. This will be used on arm and arm64.
Differential Revision: https://reviews.freebsd.org/D2219
-rw-r--r--sys/boot/efi/Makefile8
-rw-r--r--sys/boot/efi/loader/Makefile14
-rw-r--r--sys/boot/efi/loader/bootinfo.c25
-rw-r--r--sys/boot/efi/loader/main.c19
4 files changed, 64 insertions, 2 deletions
diff --git a/sys/boot/efi/Makefile b/sys/boot/efi/Makefile
index 5dfb648..d695017 100644
--- a/sys/boot/efi/Makefile
+++ b/sys/boot/efi/Makefile
@@ -1,7 +1,15 @@
# $FreeBSD$
+.include <src.opts.mk>
+
SUBDIR= libefi
+.if ${TARGET_CPUARCH} == "aarch64" || ${TARGET_CPUARCH} == "arm"
+.if ${MK_FDT} != "no"
+SUBDIR+= fdt
+.endif
+.endif
+
.if ${MACHINE_CPUARCH} == "amd64"
SUBDIR+= loader boot1
.endif
diff --git a/sys/boot/efi/loader/Makefile b/sys/boot/efi/loader/Makefile
index e109b72..af85a89 100644
--- a/sys/boot/efi/loader/Makefile
+++ b/sys/boot/efi/loader/Makefile
@@ -42,6 +42,15 @@ CFLAGS+= -I${.CURDIR}/../../ficl/${MACHINE_CPUARCH}
LIBFICL= ${.OBJDIR}/../../ficl/libficl.a
.endif
+LOADER_FDT_SUPPORT?= no
+.if ${MK_FDT} != "no" && ${LOADER_FDT_SUPPORT} != "no"
+CFLAGS+= -I${.CURDIR}/../../fdt
+CFLAGS+= -I${.OBJDIR}/../../fdt
+CFLAGS+= -DLOADER_FDT_SUPPORT
+LIBEFI_FDT= ${.OBJDIR}/../../efi/fdt/libefi_fdt.a
+LIBFDT= ${.OBJDIR}/../../fdt/libfdt.a
+.endif
+
# Include bcache code.
HAVE_BCACHE= yes
@@ -88,8 +97,9 @@ loader.efi: loader.sym
LIBEFI= ${.OBJDIR}/../libefi/libefi.a
-DPADD= ${LIBFICL} ${LIBEFI} ${LIBSTAND} ${LDSCRIPT}
-LDADD= ${LIBFICL} ${LIBEFI} ${LIBSTAND}
+DPADD= ${LIBFICL} ${LIBEFI} ${LIBFDT} ${LIBEFI_FDT} ${LIBSTAND} \
+ ${LDSCRIPT}
+LDADD= ${LIBFICL} ${LIBEFI} ${LIBFDT} ${LIBEFI_FDT} ${LIBSTAND}
.endif # ${COMPILER_TYPE} != "gcc"
diff --git a/sys/boot/efi/loader/bootinfo.c b/sys/boot/efi/loader/bootinfo.c
index 28ec620..d6607cd 100644
--- a/sys/boot/efi/loader/bootinfo.c
+++ b/sys/boot/efi/loader/bootinfo.c
@@ -51,6 +51,10 @@ __FBSDID("$FreeBSD$");
#include "framebuffer.h"
#endif
+#if defined(LOADER_FDT_SUPPORT)
+#include <fdt_platform.h>
+#endif
+
UINTN efi_mapkey;
static const char howto_switches[] = "aCdrgDmphsv";
@@ -324,6 +328,10 @@ bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp)
vm_offset_t size;
char *rootdevname;
int howto;
+#if defined(LOADER_FDT_SUPPORT)
+ vm_offset_t dtbp;
+ int dtb_size;
+#endif
howto = bi_getboothowto(args);
@@ -358,6 +366,16 @@ bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp)
/* Pad to a page boundary. */
addr = roundup(addr, PAGE_SIZE);
+#if defined(LOADER_FDT_SUPPORT)
+ /* Handle device tree blob */
+ dtbp = addr;
+ dtb_size = fdt_copy(addr);
+
+ /* Pad to a page boundary */
+ if (dtb_size)
+ addr += roundup(dtb_size, PAGE_SIZE);
+#endif
+
kfp = file_findfile(NULL, "elf kernel");
if (kfp == NULL)
kfp = file_findfile(NULL, "elf64 kernel");
@@ -366,6 +384,13 @@ bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp)
kernend = 0; /* fill it in later */
file_addmetadata(kfp, MODINFOMD_HOWTO, sizeof howto, &howto);
file_addmetadata(kfp, MODINFOMD_ENVP, sizeof envp, &envp);
+#if defined(LOADER_FDT_SUPPORT)
+ if (dtb_size)
+ file_addmetadata(kfp, MODINFOMD_DTBP, sizeof dtbp, &dtbp);
+ else
+ pager_output("WARNING! Trying to fire up the kernel, but no "
+ "device tree blob found!\n");
+#endif
file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof kernend, &kernend);
bi_load_efi_data(kfp);
diff --git a/sys/boot/efi/loader/main.c b/sys/boot/efi/loader/main.c
index 1c89ddf..8697adc 100644
--- a/sys/boot/efi/loader/main.c
+++ b/sys/boot/efi/loader/main.c
@@ -387,3 +387,22 @@ command_nvram(int argc, char *argv[])
return (CMD_OK);
}
+
+#ifdef LOADER_FDT_SUPPORT
+extern int command_fdt_internal(int argc, char *argv[]);
+
+/*
+ * Since proper fdt command handling function is defined in fdt_loader_cmd.c,
+ * and declaring it as extern is in contradiction with COMMAND_SET() macro
+ * (which uses static pointer), we're defining wrapper function, which
+ * calls the proper fdt handling routine.
+ */
+static int
+command_fdt(int argc, char *argv[])
+{
+
+ return (command_fdt_internal(argc, argv));
+}
+
+COMMAND_SET(fdt, "fdt", "flattened device tree handling", command_fdt);
+#endif
OpenPOWER on IntegriCloud