Skip to content

Commit 08cebee

Browse files
committed
Merge git://git.denx.de/u-boot-fdt
2 parents 110ba62 + ea28e48 commit 08cebee

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1656
-132
lines changed

.travis.yml

+2-3
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,11 @@ addons:
2626
- grub-efi-ia32-bin
2727
- rpm2cpio
2828
- wget
29-
- device-tree-compiler
3029

3130
install:
3231
# install latest device tree compiler
33-
#- git clone --depth=1 git://git.kernel.org/pub/scm/utils/dtc/dtc.git /tmp/dtc
34-
#- make -j4 -C /tmp/dtc
32+
- git clone --depth=1 git://git.kernel.org/pub/scm/utils/dtc/dtc.git /tmp/dtc
33+
- make -j4 -C /tmp/dtc
3534
# Clone uboot-test-hooks
3635
- git clone --depth=1 git://github.com/swarren/uboot-test-hooks.git /tmp/uboot-test-hooks
3736
- ln -s travis-ci /tmp/uboot-test-hooks/bin/`hostname`

cmd/fdt.c

+3-4
Original file line numberDiff line numberDiff line change
@@ -667,11 +667,10 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
667667
if (!fdt_valid(&blob))
668668
return CMD_RET_FAILURE;
669669

670-
ret = fdt_overlay_apply(working_fdt, blob);
671-
if (ret) {
672-
printf("fdt_overlay_apply(): %s\n", fdt_strerror(ret));
670+
/* apply method prints messages on error */
671+
ret = fdt_overlay_apply_verbose(working_fdt, blob);
672+
if (ret)
673673
return CMD_RET_FAILURE;
674-
}
675674
}
676675
#endif
677676
/* resize the fdt */

common/fdt_support.c

+31
Original file line numberDiff line numberDiff line change
@@ -1655,3 +1655,34 @@ int fdt_fixup_display(void *blob, const char *path, const char *display)
16551655
}
16561656
return toff;
16571657
}
1658+
1659+
#ifdef CONFIG_OF_LIBFDT_OVERLAY
1660+
/**
1661+
* fdt_overlay_apply_verbose - Apply an overlay with verbose error reporting
1662+
*
1663+
* @fdt: ptr to device tree
1664+
* @fdto: ptr to device tree overlay
1665+
*
1666+
* Convenience function to apply an overlay and display helpful messages
1667+
* in the case of an error
1668+
*/
1669+
int fdt_overlay_apply_verbose(void *fdt, void *fdto)
1670+
{
1671+
int err;
1672+
bool has_symbols;
1673+
1674+
err = fdt_path_offset(fdt, "/__symbols__");
1675+
has_symbols = err >= 0;
1676+
1677+
err = fdt_overlay_apply(fdt, fdto);
1678+
if (err < 0) {
1679+
printf("failed on fdt_overlay_apply(): %s\n",
1680+
fdt_strerror(err));
1681+
if (!has_symbols) {
1682+
printf("base fdt does did not have a /__symbols__ node\n");
1683+
printf("make sure you've compiled with -@\n");
1684+
}
1685+
}
1686+
return err;
1687+
}
1688+
#endif

common/image-fdt.c

+3-4
Original file line numberDiff line numberDiff line change
@@ -356,17 +356,16 @@ int boot_get_fdt(int flag, int argc, char * const argv[], uint8_t arch,
356356
if (fit_check_format(buf)) {
357357
ulong load, len;
358358

359-
fdt_noffset = fit_image_load(images,
359+
fdt_noffset = boot_get_fdt_fit(images,
360360
fdt_addr, &fit_uname_fdt,
361361
&fit_uname_config,
362-
arch, IH_TYPE_FLATDT,
363-
BOOTSTAGE_ID_FIT_FDT_START,
364-
FIT_LOAD_OPTIONAL, &load, &len);
362+
arch, &load, &len);
365363

366364
images->fit_hdr_fdt = map_sysmem(fdt_addr, 0);
367365
images->fit_uname_fdt = fit_uname_fdt;
368366
images->fit_noffset_fdt = fdt_noffset;
369367
fdt_addr = load;
368+
370369
break;
371370
} else
372371
#endif

common/image-fit.c

+199-11
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <errno.h>
2020
#include <mapmem.h>
2121
#include <asm/io.h>
22+
#include <malloc.h>
2223
DECLARE_GLOBAL_DATA_PTR;
2324
#endif /* !USE_HOSTCC*/
2425

@@ -434,6 +435,10 @@ void fit_image_print(const void *fit, int image_noffset, const char *p)
434435
printf("0x%08lx\n", load);
435436
}
436437

438+
/* optional load address for FDT */
439+
if (type == IH_TYPE_FLATDT && !fit_image_get_load(fit, image_noffset, &load))
440+
printf("%s Load Address: 0x%08lx\n", p, load);
441+
437442
if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
438443
(type == IH_TYPE_RAMDISK)) {
439444
ret = fit_image_get_entry(fit, image_noffset, &entry);
@@ -1454,6 +1459,8 @@ int fit_conf_get_node(const void *fit, const char *conf_uname)
14541459
{
14551460
int noffset, confs_noffset;
14561461
int len;
1462+
const char *s;
1463+
char *conf_uname_copy = NULL;
14571464

14581465
confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
14591466
if (confs_noffset < 0) {
@@ -1475,29 +1482,58 @@ int fit_conf_get_node(const void *fit, const char *conf_uname)
14751482
debug("Found default configuration: '%s'\n", conf_uname);
14761483
}
14771484

1485+
s = strchr(conf_uname, '#');
1486+
if (s) {
1487+
len = s - conf_uname;
1488+
conf_uname_copy = malloc(len + 1);
1489+
if (!conf_uname_copy) {
1490+
debug("Can't allocate uname copy: '%s'\n",
1491+
conf_uname);
1492+
return -ENOMEM;
1493+
}
1494+
memcpy(conf_uname_copy, conf_uname, len);
1495+
conf_uname_copy[len] = '\0';
1496+
conf_uname = conf_uname_copy;
1497+
}
1498+
14781499
noffset = fdt_subnode_offset(fit, confs_noffset, conf_uname);
14791500
if (noffset < 0) {
14801501
debug("Can't get node offset for configuration unit name: '%s' (%s)\n",
14811502
conf_uname, fdt_strerror(noffset));
14821503
}
14831504

1505+
if (conf_uname_copy)
1506+
free(conf_uname_copy);
1507+
14841508
return noffset;
14851509
}
14861510

1487-
int fit_conf_get_prop_node(const void *fit, int noffset,
1511+
int fit_conf_get_prop_node_count(const void *fit, int noffset,
14881512
const char *prop_name)
14891513
{
1490-
char *uname;
1514+
return fdt_stringlist_count(fit, noffset, prop_name);
1515+
}
1516+
1517+
int fit_conf_get_prop_node_index(const void *fit, int noffset,
1518+
const char *prop_name, int index)
1519+
{
1520+
const char *uname;
14911521
int len;
14921522

14931523
/* get kernel image unit name from configuration kernel property */
1494-
uname = (char *)fdt_getprop(fit, noffset, prop_name, &len);
1524+
uname = fdt_stringlist_get(fit, noffset, prop_name, index, &len);
14951525
if (uname == NULL)
14961526
return len;
14971527

14981528
return fit_image_get_node(fit, uname);
14991529
}
15001530

1531+
int fit_conf_get_prop_node(const void *fit, int noffset,
1532+
const char *prop_name)
1533+
{
1534+
return fit_conf_get_prop_node_index(fit, noffset, prop_name, 0);
1535+
}
1536+
15011537
/**
15021538
* fit_conf_print - prints out the FIT configuration details
15031539
* @fit: pointer to the FIT format image header
@@ -1515,7 +1551,7 @@ void fit_conf_print(const void *fit, int noffset, const char *p)
15151551
char *desc;
15161552
const char *uname;
15171553
int ret;
1518-
int loadables_index;
1554+
int fdt_index, loadables_index;
15191555

15201556
/* Mandatory properties */
15211557
ret = fit_get_desc(fit, noffset, &desc);
@@ -1537,9 +1573,17 @@ void fit_conf_print(const void *fit, int noffset, const char *p)
15371573
if (uname)
15381574
printf("%s Init Ramdisk: %s\n", p, uname);
15391575

1540-
uname = fdt_getprop(fit, noffset, FIT_FDT_PROP, NULL);
1541-
if (uname)
1542-
printf("%s FDT: %s\n", p, uname);
1576+
for (fdt_index = 0;
1577+
uname = fdt_stringlist_get(fit, noffset, FIT_FDT_PROP,
1578+
fdt_index, NULL), uname;
1579+
fdt_index++) {
1580+
1581+
if (fdt_index == 0)
1582+
printf("%s FDT: ", p);
1583+
else
1584+
printf("%s ", p);
1585+
printf("%s\n", uname);
1586+
}
15431587

15441588
uname = fdt_getprop(fit, noffset, FIT_FPGA_PROP, NULL);
15451589
if (uname)
@@ -1641,6 +1685,7 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
16411685
int cfg_noffset, noffset;
16421686
const char *fit_uname;
16431687
const char *fit_uname_config;
1688+
const char *fit_base_uname_config;
16441689
const void *fit;
16451690
const void *buf;
16461691
size_t size;
@@ -1656,6 +1701,7 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
16561701
fit = map_sysmem(addr, 0);
16571702
fit_uname = fit_unamep ? *fit_unamep : NULL;
16581703
fit_uname_config = fit_uname_configp ? *fit_uname_configp : NULL;
1704+
fit_base_uname_config = NULL;
16591705
prop_name = fit_get_image_type_property(image_type);
16601706
printf("## Loading %s from FIT Image at %08lx ...\n", prop_name, addr);
16611707

@@ -1689,11 +1735,11 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
16891735
BOOTSTAGE_SUB_NO_UNIT_NAME);
16901736
return -ENOENT;
16911737
}
1692-
fit_uname_config = fdt_get_name(fit, cfg_noffset, NULL);
1693-
printf(" Using '%s' configuration\n", fit_uname_config);
1738+
fit_base_uname_config = fdt_get_name(fit, cfg_noffset, NULL);
1739+
printf(" Using '%s' configuration\n", fit_base_uname_config);
16941740
if (image_type == IH_TYPE_KERNEL) {
16951741
/* Remember (and possibly verify) this config */
1696-
images->fit_uname_cfg = fit_uname_config;
1742+
images->fit_uname_cfg = fit_base_uname_config;
16971743
if (IMAGE_ENABLE_VERIFY && images->verify) {
16981744
puts(" Verifying Hash Integrity ... ");
16991745
if (fit_config_verify(fit, cfg_noffset)) {
@@ -1849,7 +1895,8 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
18491895
if (fit_unamep)
18501896
*fit_unamep = (char *)fit_uname;
18511897
if (fit_uname_configp)
1852-
*fit_uname_configp = (char *)fit_uname_config;
1898+
*fit_uname_configp = (char *)(fit_uname_config ? :
1899+
fit_base_uname_config);
18531900

18541901
return noffset;
18551902
}
@@ -1873,3 +1920,144 @@ int boot_get_setup_fit(bootm_headers_t *images, uint8_t arch,
18731920

18741921
return ret;
18751922
}
1923+
1924+
#ifndef USE_HOSTCC
1925+
int boot_get_fdt_fit(bootm_headers_t *images, ulong addr,
1926+
const char **fit_unamep, const char **fit_uname_configp,
1927+
int arch, ulong *datap, ulong *lenp)
1928+
{
1929+
int fdt_noffset, cfg_noffset, count;
1930+
const void *fit;
1931+
const char *fit_uname = NULL;
1932+
const char *fit_uname_config = NULL;
1933+
char *fit_uname_config_copy = NULL;
1934+
char *next_config = NULL;
1935+
ulong load, len;
1936+
#ifdef CONFIG_OF_LIBFDT_OVERLAY
1937+
ulong image_start, image_end;
1938+
ulong ovload, ovlen;
1939+
const char *uconfig;
1940+
const char *uname;
1941+
void *base, *ov;
1942+
int i, err, noffset, ov_noffset;
1943+
#endif
1944+
1945+
fit_uname = fit_unamep ? *fit_unamep : NULL;
1946+
1947+
if (fit_uname_configp && *fit_uname_configp) {
1948+
fit_uname_config_copy = strdup(*fit_uname_configp);
1949+
if (!fit_uname_config_copy)
1950+
return -ENOMEM;
1951+
1952+
next_config = strchr(fit_uname_config_copy, '#');
1953+
if (next_config)
1954+
*next_config++ = '\0';
1955+
if (next_config - 1 > fit_uname_config_copy)
1956+
fit_uname_config = fit_uname_config_copy;
1957+
}
1958+
1959+
fdt_noffset = fit_image_load(images,
1960+
addr, &fit_uname, &fit_uname_config,
1961+
arch, IH_TYPE_FLATDT,
1962+
BOOTSTAGE_ID_FIT_FDT_START,
1963+
FIT_LOAD_OPTIONAL, &load, &len);
1964+
1965+
if (fdt_noffset < 0)
1966+
goto out;
1967+
1968+
debug("fit_uname=%s, fit_uname_config=%s\n",
1969+
fit_uname ? fit_uname : "<NULL>",
1970+
fit_uname_config ? fit_uname_config : "<NULL>");
1971+
1972+
fit = map_sysmem(addr, 0);
1973+
1974+
cfg_noffset = fit_conf_get_node(fit, fit_uname_config);
1975+
1976+
/* single blob, or error just return as well */
1977+
count = fit_conf_get_prop_node_count(fit, cfg_noffset, FIT_FDT_PROP);
1978+
if (count <= 1 && !next_config)
1979+
goto out;
1980+
1981+
/* we need to apply overlays */
1982+
1983+
#ifdef CONFIG_OF_LIBFDT_OVERLAY
1984+
image_start = addr;
1985+
image_end = addr + fit_get_size(fit);
1986+
/* verify that relocation took place by load address not being in fit */
1987+
if (load >= image_start && load < image_end) {
1988+
/* check is simplified; fit load checks for overlaps */
1989+
printf("Overlayed FDT requires relocation\n");
1990+
fdt_noffset = -EBADF;
1991+
goto out;
1992+
}
1993+
1994+
base = map_sysmem(load, len);
1995+
1996+
/* apply extra configs in FIT first, followed by args */
1997+
for (i = 1; ; i++) {
1998+
if (i < count) {
1999+
noffset = fit_conf_get_prop_node_index(fit, cfg_noffset,
2000+
FIT_FDT_PROP, i);
2001+
uname = fit_get_name(fit, noffset, NULL);
2002+
uconfig = NULL;
2003+
} else {
2004+
if (!next_config)
2005+
break;
2006+
uconfig = next_config;
2007+
next_config = strchr(next_config, '#');
2008+
if (next_config)
2009+
*next_config++ = '\0';
2010+
uname = NULL;
2011+
}
2012+
2013+
debug("%d: using uname=%s uconfig=%s\n", i, uname, uconfig);
2014+
2015+
ov_noffset = fit_image_load(images,
2016+
addr, &uname, &uconfig,
2017+
arch, IH_TYPE_FLATDT,
2018+
BOOTSTAGE_ID_FIT_FDT_START,
2019+
FIT_LOAD_REQUIRED, &ovload, &ovlen);
2020+
if (ov_noffset < 0) {
2021+
printf("load of %s failed\n", uname);
2022+
continue;
2023+
}
2024+
debug("%s loaded at 0x%08lx len=0x%08lx\n",
2025+
uname, ovload, ovlen);
2026+
ov = map_sysmem(ovload, ovlen);
2027+
2028+
base = map_sysmem(load, len + ovlen);
2029+
err = fdt_open_into(base, base, len + ovlen);
2030+
if (err < 0) {
2031+
printf("failed on fdt_open_into\n");
2032+
fdt_noffset = err;
2033+
goto out;
2034+
}
2035+
/* the verbose method prints out messages on error */
2036+
err = fdt_overlay_apply_verbose(base, ov);
2037+
if (err < 0) {
2038+
fdt_noffset = err;
2039+
goto out;
2040+
}
2041+
fdt_pack(base);
2042+
len = fdt_totalsize(base);
2043+
}
2044+
#else
2045+
printf("config with overlays but CONFIG_OF_LIBFDT_OVERLAY not set\n");
2046+
fdt_noffset = -EBADF;
2047+
#endif
2048+
2049+
out:
2050+
if (datap)
2051+
*datap = load;
2052+
if (lenp)
2053+
*lenp = len;
2054+
if (fit_unamep)
2055+
*fit_unamep = fit_uname;
2056+
if (fit_uname_configp)
2057+
*fit_uname_configp = fit_uname_config;
2058+
2059+
if (fit_uname_config_copy)
2060+
free(fit_uname_config_copy);
2061+
return fdt_noffset;
2062+
}
2063+
#endif

0 commit comments

Comments
 (0)