Index: sys/boot/arm/uboot/Makefile =================================================================== --- sys/boot/arm/uboot/Makefile +++ sys/boot/arm/uboot/Makefile @@ -72,6 +72,7 @@ CFLAGS+= -I${.CURDIR}/../../fdt CFLAGS+= -I${.OBJDIR}/../../fdt CFLAGS+= -DLOADER_FDT_SUPPORT +LIBUBOOT_FDT= ${.OBJDIR}/../../uboot/fdt/libuboot_fdt.a LIBFDT= ${.OBJDIR}/../../fdt/libfdt.a .endif @@ -112,8 +113,8 @@ # clang doesn't understand %D as a specifier to printf NO_WERROR.clang= -DPADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBSTAND} -LDADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} -lstand +DPADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSTAND} +LDADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} -lstand vers.c: ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version sh ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version ${NEWVERSWHAT} Index: sys/boot/fdt/fdt_loader_cmd.c =================================================================== --- sys/boot/fdt/fdt_loader_cmd.c +++ sys/boot/fdt/fdt_loader_cmd.c @@ -39,6 +39,7 @@ #include "bootstrap.h" #include "glue.h" +#include "fdt_platform.h" #ifdef DEBUG #define debugf(fmt, args...) do { printf("%s(): ", __func__); \ @@ -52,9 +53,6 @@ #define FDT_PROP_SEP " = " -#define STR(number) #number -#define STRINGIFY(number) STR(number) - #define COPYOUT(s,d,l) archsw.arch_copyout(s, d, l) #define COPYIN(s,d,l) archsw.arch_copyin(s, d, l) @@ -228,7 +226,7 @@ return (0); } -static int +int fdt_load_dtb_addr(struct fdt_header *header) { int err; @@ -253,7 +251,7 @@ return (0); } -static int +int fdt_load_dtb_file(const char * filename) { struct preloaded_file *bfp, *oldbfp; @@ -283,9 +281,6 @@ fdt_setup_fdtp() { struct preloaded_file *bfp; - struct fdt_header *hdr; - const char *s; - char *p; vm_offset_t va; debugf("fdt_setup_fdtp()\n"); @@ -308,41 +303,8 @@ } } - /* - * If the U-boot environment contains a variable giving the address of a - * valid blob in memory, use it. The U-boot README says the right - * variable for fdt data loaded into ram is fdt_addr_r, so try that - * first. Board vendors also use both fdtaddr and fdt_addr names. - */ - s = ub_env_get("fdt_addr_r"); - if (s == NULL) - s = ub_env_get("fdtaddr"); - if (s == NULL) - s = ub_env_get("fdt_addr"); - if (s != NULL && *s != '\0') { - hdr = (struct fdt_header *)strtoul(s, &p, 16); - if (*p == '\0') { - if (fdt_load_dtb_addr(hdr) == 0) { - printf("Using DTB provided by U-Boot at " - "address %p.\n", hdr); - return (0); - } - } - } - - /* - * If the U-boot environment contains a variable giving the name of a - * file, use it if we can load and validate it. - */ - s = ub_env_get("fdtfile"); - if (s == NULL) - s = ub_env_get("fdt_file"); - if (s != NULL && *s != '\0') { - if (fdt_load_dtb_file(s) == 0) { - printf("Loaded DTB from file '%s'.\n", s); - return (0); - } - } + if (fdt_platform_load_dtb() == 0) + return (0); /* If there is a dtb compiled into the kernel, use it. */ if ((va = fdt_find_static_dtb()) != 0) { @@ -406,10 +368,8 @@ return (cnt); } -#define TMP_MAX_ETH 8 - -static void -fixup_ethernet(const char *env, char *ethstr, int *eth_no, int len) +void +fdt_fixup_ethernet(const char *env, char *ethstr, int *eth_no, int len) { char *end, *str; uint8_t tmp_addr[6]; @@ -445,8 +405,8 @@ *eth_no = n + 1; } -static void -fixup_cpubusfreqs(unsigned long cpufreq, unsigned long busfreq) +void +fdt_fixup_cpubusfreqs(unsigned long cpufreq, unsigned long busfreq) { int lo, o = 0, o2, maxo = 0, depth; const uint32_t zero = 0; @@ -525,8 +485,8 @@ return (0); } -static void -fixup_memory(struct sys_info *si) +void +fdt_fixup_memory(struct sys_info *si) { struct mem_region *curmr; uint32_t addr_cells, size_cells; @@ -680,8 +640,8 @@ free(sb); } -static void -fixup_stdout(const char *env) +void +fdt_fixup_stdout(const char *env) { const char *str; char *ptr; @@ -736,14 +696,8 @@ static int fdt_fixup(void) { - const char *env; - char *ethstr; - int chosen, eth_no, len; - struct sys_info *si; - - env = NULL; - eth_no = 0; - ethstr = NULL; + int chosen, len; + len = 0; debugf("fdt_fixup()\n"); @@ -760,45 +714,7 @@ if (fdt_getprop(fdtp, chosen, "fixup-applied", NULL)) return (1); - /* Acquire sys_info */ - si = ub_get_sys_info(); - - while ((env = ub_env_enum(env)) != NULL) { - if (strncmp(env, "eth", 3) == 0 && - strncmp(env + (strlen(env) - 4), "addr", 4) == 0) { - /* - * Handle Ethernet addrs: parse uboot env eth%daddr - */ - - if (!eth_no) { - /* - * Check how many chars we will need to store - * maximal eth iface number. - */ - len = strlen(STRINGIFY(TMP_MAX_ETH)) + - strlen("ethernet"); - - /* - * Reserve mem for string "ethernet" and len - * chars for iface no. - */ - ethstr = (char *)malloc(len * sizeof(char)); - bzero(ethstr, len * sizeof(char)); - strcpy(ethstr, "ethernet0"); - } - - /* Modify blob */ - fixup_ethernet(env, ethstr, ð_no, len); - - } else if (strcmp(env, "consoledev") == 0) - fixup_stdout(env); - } - - /* Modify cpu(s) and bus clock frequenties in /cpus node [Hz] */ - fixup_cpubusfreqs(si->clk_cpu, si->clk_bus); - - /* Fixup memory regions */ - fixup_memory(si); + fdt_platform_fixups(); fdt_setprop(fdtp, chosen, "fixup-applied", NULL, 0); return (1); Index: sys/boot/fdt/fdt_platform.h =================================================================== --- /dev/null +++ sys/boot/fdt/fdt_platform.h @@ -0,0 +1,46 @@ +/*- + * 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 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. + */ + +#ifndef FDT_PLATFORM_H +#define FDT_PLATFORM_H + +struct fdt_header; +struct sys_info; + +#define TMP_MAX_ETH 8 + +void fdt_fixup_cpubusfreqs(unsigned long, unsigned long); +void fdt_fixup_ethernet(const char *, char *, int *, int); +void fdt_fixup_memory(struct sys_info *); +void fdt_fixup_stdout(const char *); +int fdt_load_dtb_addr(struct fdt_header *); +int fdt_load_dtb_file(const char *); + +/* The platform library needs to implement these functions */ +int fdt_platform_load_dtb(void); +void fdt_platform_fixups(void); + +#endif /* FDT_PLATFORM_H */ Index: sys/boot/powerpc/uboot/Makefile =================================================================== --- sys/boot/powerpc/uboot/Makefile +++ sys/boot/powerpc/uboot/Makefile @@ -62,6 +62,7 @@ CFLAGS+= -I${.CURDIR}/../../fdt CFLAGS+= -I${.OBJDIR}/../../fdt CFLAGS+= -DLOADER_FDT_SUPPORT +LIBUBOOT_FDT= ${.OBJDIR}/../../uboot/fdt/libuboot_fdt.a LIBFDT= ${.OBJDIR}/../../fdt/libfdt.a .endif @@ -98,8 +99,8 @@ LIBSTAND= ${.OBJDIR}/../../libstand32/libstand.a CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/ -DPADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBSTAND} -LDADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBSTAND} +DPADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSTAND} +LDADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSTAND} vers.c: ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version sh ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version ${NEWVERSWHAT} Index: sys/boot/uboot/Makefile =================================================================== --- sys/boot/uboot/Makefile +++ sys/boot/uboot/Makefile @@ -1,5 +1,11 @@ # $FreeBSD$ +.include + SUBDIR= lib +.if ${MK_FDT} != "no" +SUBDIR+=fdt +.endif + .include Index: sys/boot/uboot/fdt/Makefile =================================================================== --- /dev/null +++ sys/boot/uboot/fdt/Makefile @@ -0,0 +1,33 @@ +# $FreeBSD$ + +.include + +.PATH: ${.CURDIR}/../../common + +LIB= uboot_fdt +INTERNALLIB= +WARNS?= 2 + +SRCS= uboot_fdt.c + +CFLAGS+= -ffreestanding -msoft-float + +CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/ + +# U-Boot library headers +CFLAGS+= -I${.CURDIR}/../lib + +# libfdt headers +CFLAGS+= -I${.CURDIR}/../../fdt + +# Pick up the bootstrap header for some interface items +CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}/../../.. -I. + +machine: + ln -sf ${.CURDIR}/../../../${MACHINE_CPUARCH}/include machine + +CLEANFILES+= machine + +.include + +beforedepend ${OBJS}: machine Index: sys/boot/uboot/fdt/uboot_fdt.c =================================================================== --- /dev/null +++ sys/boot/uboot/fdt/uboot_fdt.c @@ -0,0 +1,138 @@ +/*- + * Copyright (c) 2009-2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Semihalf 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 +__FBSDID("$FreeBSD$"); + +#include +#include + +#include "glue.h" + +#define STR(number) #number +#define STRINGIFY(number) STR(number) + +int +fdt_platform_load_dtb(void) +{ + struct fdt_header *hdr; + const char *s; + char *p; + + /* + * If the U-boot environment contains a variable giving the address of a + * valid blob in memory, use it. The U-boot README says the right + * variable for fdt data loaded into ram is fdt_addr_r, so try that + * first. Board vendors also use both fdtaddr and fdt_addr names. + */ + s = ub_env_get("fdt_addr_r"); + if (s == NULL) + s = ub_env_get("fdtaddr"); + if (s == NULL) + s = ub_env_get("fdt_addr"); + if (s != NULL && *s != '\0') { + hdr = (struct fdt_header *)strtoul(s, &p, 16); + if (*p == '\0') { + if (fdt_load_dtb_addr(hdr) == 0) { + printf("Using DTB provided by U-Boot at " + "address %p.\n", hdr); + return (0); + } + } + } + + /* + * If the U-boot environment contains a variable giving the name of a + * file, use it if we can load and validate it. + */ + s = ub_env_get("fdtfile"); + if (s == NULL) + s = ub_env_get("fdt_file"); + if (s != NULL && *s != '\0') { + if (fdt_load_dtb_file(s) == 0) { + printf("Loaded DTB from file '%s'.\n", s); + return (0); + } + } + + return (1); +} + +void +fdt_platform_fixups(void) +{ + const char *env; + char *ethstr; + int eth_no, len; + struct sys_info *si; + + env = NULL; + eth_no = 0; + ethstr = NULL; + + /* Acquire sys_info */ + si = ub_get_sys_info(); + + while ((env = ub_env_enum(env)) != NULL) { + if (strncmp(env, "eth", 3) == 0 && + strncmp(env + (strlen(env) - 4), "addr", 4) == 0) { + /* + * Handle Ethernet addrs: parse uboot env eth%daddr + */ + + if (!eth_no) { + /* + * Check how many chars we will need to store + * maximal eth iface number. + */ + len = strlen(STRINGIFY(TMP_MAX_ETH)) + + strlen("ethernet"); + + /* + * Reserve mem for string "ethernet" and len + * chars for iface no. + */ + ethstr = (char *)malloc(len * sizeof(char)); + bzero(ethstr, len * sizeof(char)); + strcpy(ethstr, "ethernet0"); + } + + /* Modify blob */ + fdt_fixup_ethernet(env, ethstr, ð_no, len); + + } else if (strcmp(env, "consoledev") == 0) + fdt_fixup_stdout(env); + } + + /* Modify cpu(s) and bus clock frequenties in /cpus node [Hz] */ + fdt_fixup_cpubusfreqs(si->clk_cpu, si->clk_bus); + + /* Fixup memory regions */ + fdt_fixup_memory(si); +}