19
19
#include <errno.h>
20
20
#include <mapmem.h>
21
21
#include <asm/io.h>
22
+ #include <malloc.h>
22
23
DECLARE_GLOBAL_DATA_PTR ;
23
24
#endif /* !USE_HOSTCC*/
24
25
@@ -434,6 +435,10 @@ void fit_image_print(const void *fit, int image_noffset, const char *p)
434
435
printf ("0x%08lx\n" , load );
435
436
}
436
437
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
+
437
442
if ((type == IH_TYPE_KERNEL ) || (type == IH_TYPE_STANDALONE ) ||
438
443
(type == IH_TYPE_RAMDISK )) {
439
444
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)
1454
1459
{
1455
1460
int noffset , confs_noffset ;
1456
1461
int len ;
1462
+ const char * s ;
1463
+ char * conf_uname_copy = NULL ;
1457
1464
1458
1465
confs_noffset = fdt_path_offset (fit , FIT_CONFS_PATH );
1459
1466
if (confs_noffset < 0 ) {
@@ -1475,29 +1482,58 @@ int fit_conf_get_node(const void *fit, const char *conf_uname)
1475
1482
debug ("Found default configuration: '%s'\n" , conf_uname );
1476
1483
}
1477
1484
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
+
1478
1499
noffset = fdt_subnode_offset (fit , confs_noffset , conf_uname );
1479
1500
if (noffset < 0 ) {
1480
1501
debug ("Can't get node offset for configuration unit name: '%s' (%s)\n" ,
1481
1502
conf_uname , fdt_strerror (noffset ));
1482
1503
}
1483
1504
1505
+ if (conf_uname_copy )
1506
+ free (conf_uname_copy );
1507
+
1484
1508
return noffset ;
1485
1509
}
1486
1510
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 ,
1488
1512
const char * prop_name )
1489
1513
{
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 ;
1491
1521
int len ;
1492
1522
1493
1523
/* 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 );
1495
1525
if (uname == NULL )
1496
1526
return len ;
1497
1527
1498
1528
return fit_image_get_node (fit , uname );
1499
1529
}
1500
1530
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
+
1501
1537
/**
1502
1538
* fit_conf_print - prints out the FIT configuration details
1503
1539
* @fit: pointer to the FIT format image header
@@ -1515,7 +1551,7 @@ void fit_conf_print(const void *fit, int noffset, const char *p)
1515
1551
char * desc ;
1516
1552
const char * uname ;
1517
1553
int ret ;
1518
- int loadables_index ;
1554
+ int fdt_index , loadables_index ;
1519
1555
1520
1556
/* Mandatory properties */
1521
1557
ret = fit_get_desc (fit , noffset , & desc );
@@ -1537,9 +1573,17 @@ void fit_conf_print(const void *fit, int noffset, const char *p)
1537
1573
if (uname )
1538
1574
printf ("%s Init Ramdisk: %s\n" , p , uname );
1539
1575
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
+ }
1543
1587
1544
1588
uname = fdt_getprop (fit , noffset , FIT_FPGA_PROP , NULL );
1545
1589
if (uname )
@@ -1641,6 +1685,7 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
1641
1685
int cfg_noffset , noffset ;
1642
1686
const char * fit_uname ;
1643
1687
const char * fit_uname_config ;
1688
+ const char * fit_base_uname_config ;
1644
1689
const void * fit ;
1645
1690
const void * buf ;
1646
1691
size_t size ;
@@ -1656,6 +1701,7 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
1656
1701
fit = map_sysmem (addr , 0 );
1657
1702
fit_uname = fit_unamep ? * fit_unamep : NULL ;
1658
1703
fit_uname_config = fit_uname_configp ? * fit_uname_configp : NULL ;
1704
+ fit_base_uname_config = NULL ;
1659
1705
prop_name = fit_get_image_type_property (image_type );
1660
1706
printf ("## Loading %s from FIT Image at %08lx ...\n" , prop_name , addr );
1661
1707
@@ -1689,11 +1735,11 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
1689
1735
BOOTSTAGE_SUB_NO_UNIT_NAME );
1690
1736
return - ENOENT ;
1691
1737
}
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 );
1694
1740
if (image_type == IH_TYPE_KERNEL ) {
1695
1741
/* Remember (and possibly verify) this config */
1696
- images -> fit_uname_cfg = fit_uname_config ;
1742
+ images -> fit_uname_cfg = fit_base_uname_config ;
1697
1743
if (IMAGE_ENABLE_VERIFY && images -> verify ) {
1698
1744
puts (" Verifying Hash Integrity ... " );
1699
1745
if (fit_config_verify (fit , cfg_noffset )) {
@@ -1849,7 +1895,8 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
1849
1895
if (fit_unamep )
1850
1896
* fit_unamep = (char * )fit_uname ;
1851
1897
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 );
1853
1900
1854
1901
return noffset ;
1855
1902
}
@@ -1873,3 +1920,144 @@ int boot_get_setup_fit(bootm_headers_t *images, uint8_t arch,
1873
1920
1874
1921
return ret ;
1875
1922
}
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