SPL: extend FIT loading support
Subsystems (3)
v4 cover SPL: extend FIT loading support
Another round of smaller fixes for the SPL FIT loading series and the respective patches to enable this feature on 64-bit Allwinner SoCs. The README has been changed to address all 64-bit Allwinner boards and has consequently been renamed to README.sunxi64. Also we can now point U-Boot to the ARM Trusted Firmware build by specifying the filename in the BL31 environment variable. If this is not set, we default to look for bl31.bin in U-Boot's build directory.
The other minor fixes are detailed in the Changelog below.
---
The first five patches introduce the core of the extened SPL FIT loading support, see below for a description. Patch 6 fixes a Kconfig dependency to simplify the usage of this option.
Patches 7-10 make some room in the sunxi 64-bit SPL to allow compiling in the FIT loading bits. Patch 11 and 12 let the SPL choose the proper DT from the FIT image.
The next two patches add the infrastructure and an actual generator script, so the FIT image is automatically created at build time.
Patches 14, 15 and 16 enable the SPL FIT support for Allwinner 64-bit SoCs in general and for the Pine64 and OrangePi PC 2 in particular.
The following two patches store a DT file name in the SPL header, so U-Boot can easily pick the proper DT when scanning the FIT image. The idea is that this DT name should stay with the board, ideally on eMMC or SPI flash. So both U-Boot and a firmware update tool could identify a board, updating with compatible firmware while keeping the DT name in place. Ideally a board vendor would once seed this name onto on-board storage like SPI flash.
I kept those two patches in, as the work on replacing mksunxiboot with an mkimage extension is not ready yet. Feel free to drop those from the series if this is a problem.
The penultimate patch updates the Pine64 README file to document the current way of building U-Boot, which now includes the ARM Trusted Firmware build in its image.
The last patch moves the maintainership from Hans over to me.
I would be delighted if that series could get merged into the sunxi tree. This finally enables the fully open source firmware for the 64-bit Allwinner SoCs (including the ATF binary).
This series is based on current sunxi/master.
Cheers,
Andre.
-------
Currently the FIT format is not used to its full potential in the SPL:
It only loads the first image from the /images node and appends the proper FDT.
Some boards and platforms would benefit from loading more images before starting U-Boot proper, notably Allwinner A64 and ARMv8 Rockchip boards, which use an ARM Trusted Firmware (ATF) image to be executed before U-Boot.
This series tries to solve this in a board agnostic and generic way:
We extend the SPL FIT loading scheme to allow loading multiple images. So apart from loading the image which is referenced by the "firmware" property in the respective configuration node and placing the DTB right behind it, we iterate over all strings in the "loadable" property. Each image referenced there will be loaded to its specified load address. The entry point U-Boot eventually branches to will be taken from the first image to explicitly provide the "entry" property, or, if none of them does so, from the load address of the "firmware" image. This keeps the scheme compatible with the FIT images our Makefile creates automatically at the moment.
Apart from the already mentioned ATF scenario this opens up more usage scenarios, of which the commit message of patch 04/11 lists some. The remaining patches prepare ane finally enable this scheme for the 64-bit Allwinner boards.
Changelog v3 ... v4:
- [01/20]: return proper error codes instead of just -1 (+Simon's RB)
- [02/20]: improve kernel-doc comment (+Simon's RB)
- [03/20]: return proper error codes instead of just -1 (+Simon's RB)
- [04/20]: improve kernel-doc comment and error codes (+Simon's RB)
- [05/20]: add example .its source file (+Simon's RB)
- [10,11,12/20]: add Maxime's Acked-by
- [14/20]: add BL31 environment variable (+Maxime's Acked-by)
- [15/20]: drop unneeded OrangePi PC2 change
- [16/20]: add Maxime's Acked-by
- [19/20]: rewrite to be more generic, rename to README.sunxi64
- [20/20]: new patch to change maintainership
Changelog v2 ... v3:
- new patch 06/19 to improve SPL_FIT Kconfig dependencies
- rename symbol in mksunxiboot (SUNXI_SRAM instead of SUN4I_SRAM)
- enable SPL_LOAD_FIT for all Allwinner A64 and H5 boards in Kconfig
- add only CONFIG_OF_LIST to defconfigs (patch 15/19)
Changelog v1 ... v2:
- Add some function comments to spl_fit.c (patch 1-5)
- Improve error handling in SPL FIT code (patch 1-5)
- Fix bisectability (observing entry-point property)
- add documentation to doc/uImage.FIT/howto.txt
- fix Freescale CCN504 build failure
- (no changes in the last 10 patches)
- update README.pine64 (new last patch)
- add Reviewed-by's from Simon and Lokesh
--
Andre Przywara (19):
SPL: FIT: refactor FDT loading
SPL: FIT: rework U-Boot image loading
SPL: FIT: improve error handling
SPL: FIT: factor out spl_load_fit_image()
SPL: FIT: allow loading multiple images
Kconfig: fix SPL_FIT dependency
tools: mksunxiboot: allow larger SPL binaries
armv8: SPL: only compile GIC code if needed
armv8: fsl: move ccn504 code into FSL Makefile
sunxi: A64: move SPL stack to end of SRAM A2
sunxi: SPL: store RAM size in gd
sunxi: SPL: add FIT config selector for Pine64 boards
Makefile: add rules to generate SPL FIT images
sunxi: 64-bit SoCs: introduce FIT generator script
sunxi: defconfig: add supported DT list for Pine64
sunxi: enable automatic FIT build for 64-bit SoCs
sunxi: use SPL header DT name for FIT board matching
sunxi: update Pine64 README
sunxi: Move maintainership for Pine64
Siarhei Siamashka (1):
sunxi: Store the device tree name in the SPL header
Kconfig | 22 ++- Makefile | 20 +++ arch/arm/include/asm/arch-sunxi/spl.h | 19 ++- arch/arm/lib/Makefile | 4 +- board/sunxi/Kconfig | 4 + board/sunxi/MAINTAINERS | 6 +- board/sunxi/README.pine64 | 98 ----------- board/sunxi/README.sunxi64 | 165 +++++++++++++++++++ board/sunxi/board.c | 36 +++- board/sunxi/mksunxi_fit_atf.sh | 75 +++++++++ common/spl/spl_fit.c | 301 ++++++++++++++++++++++------------ configs/am335x_evm_defconfig | 1 - configs/evb-rk3399_defconfig | 1 - configs/pine64_plus_defconfig | 1 + doc/uImage.FIT/howto.txt | 21 +++ doc/uImage.FIT/multi_spl.its | 89 ++++++++++ include/configs/sunxi-common.h | 17 +- scripts/Makefile.spl | 3 +- tools/mksunxiboot.c | 53 +++++- 19 files changed, 710 insertions(+), 226 deletions(-) delete mode 100644 board/sunxi/README.pine64 create mode 100644 board/sunxi/README.sunxi64 create mode 100755 board/sunxi/mksunxi_fit_atf.sh create mode 100644 doc/uImage.FIT/multi_spl.its
Signature · 1 line
2.8.2
PATCH v4 1/20 SPL: FIT: refactor FDT loading
Currently the SPL FIT loader uses the spl_fit_select_fdt() function to find the offset to the right DTB within the FIT image.
For this it iterates over all subnodes of the /configuration node in the FIT tree and compares all "description" strings therein using a board specific matching function.
If that finds a match, it uses the string in the "fdt" property of that subnode to locate the matching subnode in the /images node, which points to the DTB data.
Now this works very well, but is quite specific to cover this particular use case. To open up the door for a more generic usage, let's split this function into:
1) a function that just returns the node offset for the matching configuration node (spl_fit_find_config_node())
2) a function that returns the image data any given property in a given configuration node points to, additionally using a given index into a possbile list of strings (spl_fit_select_index())
This allows us to replace the specific function above by asking for the image the _first string of the "fdt" property_ in the matching configuration subnode points to.
This patch introduces no functional changes, it just refactors the code to allow reusing it later.
(diff is overly clever here and produces a hard-to-read patch, so I recommend to throw a look at the result instead).
--- common/spl/spl_fit.c | 88 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 57 insertions(+), 31 deletions(-)
common/spl/spl_fit.c +57 -31
@@ -22,13 +22,16 @@ static ulong fdt_getprop_u32(const void *fdt, int node, const char *prop)return fdt32_to_cpu (*cell); } -static int spl_fit_select_fdt (const void *fdt,int images,int *fdt_offsetp) +/* +* Iterate over all /configurations subnodes and call a platform specific +* function to find the matching configuration. +* Returns the node offset or a negative error number. +*/ +static int spl_fit_find_config_node (const void *fdt) { -const char *name, *fdt_name; -int conf, node, fdt_node; -int len; +const char *name; +int conf, node, len; - *fdt_offsetp =0 ; conf =fdt_path_offset (fdt,FIT_CONFS_PATH );if (conf <0 ) { debug("%s: Cannot find /configurations node: %d\n", __func__,
@@ -50,39 +53,61 @@ static int spl_fit_select_fdt(const void *fdt, int images, int *fdt_offsetp)continue ;debug ("Selecting config '%s'" , name); - fdt_name =fdt_getprop (fdt, node,FIT_FDT_PROP , &len); -if (!fdt_name) { -debug ("%s: Cannot find fdt name property: %d\n" , - __func__, len); -return -EINVAL ; - } -debug (", fdt '%s'\n" , fdt_name); - fdt_node =fdt_subnode_offset (fdt, images, fdt_name); -if (fdt_node <0 ) { -debug ("%s: Cannot find fdt node '%s': %d\n" , - __func__, fdt_name, fdt_node); -return -EINVAL ; +return node; + } + +return -ENOENT ; +} + +static int spl_fit_select_index (const void *fit,int images,int *offsetp, +const char *type,int index) +{ +const char *name, *str; +int node, conf_node; +int len, i; + + *offsetp =0 ; + conf_node =spl_fit_find_config_node (fit); +if (conf_node <0 ) { +#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT +printf ("No matching DT out of these options:\n" ); +for (node =fdt_first_subnode (fit, conf_node); + node >=0 ; + node =fdt_next_subnode (fit, node)) { + name =fdt_getprop (fit, node,"description" , &len); +printf (" %s\n" , name); } +#endif +return conf_node; + } - *fdt_offsetp =fdt_getprop_u32 (fdt, fdt_node,"data-offset" ); - len =fdt_getprop_u32 (fdt, fdt_node,"data-size" ); -debug ("FIT: Selected '%s'\n" , name); + name =fdt_getprop (fit, conf_node, type, &len); +if (!name) { +debug ("cannot find property '%s': %d\n" , type, len); +return -EINVAL ; + } -return len; + str = name; +for (i =0 ; i < index; i++) { + str =strchr (str,'\0' ) +1 ; +if (!str || (str - name >= len)) { +debug ("no string for index %d\n" , index); +return -E2BIG ; + } } -#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT -printf ("No matching DT out of these options:\n" ); -for (node =fdt_first_subnode (fdt, conf); - node >=0 ; - node =fdt_next_subnode (fdt, node)) { - name =fdt_getprop (fdt, node,"description" , &len); -printf (" %s\n" , name); +debug ("%s: '%s'\n" , type, str); + node =fdt_subnode_offset (fit, images, str); +if (node <0 ) { +debug ("cannot find image node '%s': %d\n" , str, node); +return -EINVAL ; } -#endif -return -ENOENT ; + *offsetp =fdt_getprop_u32 (fit, node,"data-offset" ); + len =fdt_getprop_u32 (fit, node,"data-size" ); + +return len; }static int get_aligned_image_offset (struct spl_load_info *info,int offset)
@@ -218,7 +243,8 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,memcpy (dst, src, data_size);/* Figure out which device tree the board wants to use */ - fdt_len =spl_fit_select_fdt (fit, images, &fdt_offset); + fdt_len =spl_fit_select_index (fit, images, &fdt_offset, +FIT_FDT_PROP ,0 );if (fdt_len <0 )return fdt_len;
Signature · 1 line
2.8.2
PATCH v4 1/20 SPL: FIT: refactor FDT loading
Am Mittwoch, 26. April 2017, 01:32:33 CEST schrieb Andre Przywara:
Quoted 23 lines
Currently the SPL FIT loader uses the
spl_fit_select_fdt()function to find the offset to the right DTB within the FIT image.
For this it iterates over all subnodes of the /configuration node in the FIT tree and compares all "description" strings therein using a board specific matching function.
If that finds a match, it uses the string in the "fdt" property of that subnode to locate the matching subnode in the /images node, which points to the DTB data.
Now this works very well, but is quite specific to cover this particular use case. To open up the door for a more generic usage, let's split this function into:
1) a function that just returns the node offset for the matching configuration node (spl_fit_find_config_node())
2) a function that returns the image data any given property in a given configuration node points to, additionally using a given index into a possbile list of strings (spl_fit_select_index())
This allows us to replace the specific function above by asking for the image the_firststring of the "fdt"property_in the matching configuration subnode points to.This patch introduces no functional changes, it just refactors the code to allow reusing it later.
Quoted 6 lines
(diff is overly clever here and produces a hard-to-read patch, so I recommend to throw a look at the result instead).
Signed-off-by Andre Przywara <[email protected]>Reviewed-by Lokesh Vutla <[email protected]>Reviewed-by Simon Glass <[email protected]>
On a rk3399-firefly
PATCH v4 1/20 SPL: FIT: refactor FDT loading
In reply to Andre PrzywaraQuoted 23 lines · Andre Przywara
Currently the SPL FIT loader uses the
spl_fit_select_fdt()function to find the offset to the right DTB within the FIT image.
For this it iterates over all subnodes of the /configuration node in the FIT tree and compares all "description" strings therein using a board specific matching function.
If that finds a match, it uses the string in the "fdt" property of that subnode to locate the matching subnode in the /images node, which points to the DTB data.
Now this works very well, but is quite specific to cover this particular use case. To open up the door for a more generic usage, let's split this function into:
1) a function that just returns the node offset for the matching configuration node (spl_fit_find_config_node())
2) a function that returns the image data any given property in a given configuration node points to, additionally using a given index into a possbile list of strings (spl_fit_select_index())
This allows us to replace the specific function above by asking for the image the_firststring of the "fdt"property_in the matching configuration subnode points to.This patch introduces no functional changes, it just refactors the code to allow reusing it later.
Quoted 6 lines
(diff is overly clever here and produces a hard-to-read patch, so I recommend to throw a look at the result instead).
Signed-off-by Andre Przywara <[email protected]>Reviewed-by Lokesh Vutla <[email protected]>Reviewed-by Simon Glass <[email protected]>
Thanks,
- Kever
Quoted 127 lines
--- common/spl/spl_fit.c | 88 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 57 insertions(+), 31 deletions(-)common/spl/spl_fit.c +57
-31@@ -22,13 +22,16 @@ static ulong fdt_getprop_u32(const void *fdt, int node, const char *prop)return fdt32_to_cpu (*cell); } -static int spl_fit_select_fdt (const void *fdt,int images,int *fdt_offsetp) +/* +* Iterate over all /configurations subnodes and call a platform specific +* function to find the matching configuration. +* Returns the node offset or a negative error number. +*/ +static int spl_fit_find_config_node (const void *fdt) { -const char *name, *fdt_name; -int conf, node, fdt_node; -int len; +const char *name; +int conf, node, len; - *fdt_offsetp =0 ; conf =fdt_path_offset (fdt,FIT_CONFS_PATH );if (conf <0 ) { debug("%s: Cannot find /configurations node: %d\n", __func__,@@ -50,39 +53,61 @@ static int spl_fit_select_fdt(const void *fdt, int images, int *fdt_offsetp)continue ;debug ("Selecting config '%s'" , name); - fdt_name =fdt_getprop (fdt, node,FIT_FDT_PROP , &len); -if (!fdt_name) { -debug ("%s: Cannot find fdt name property: %d\n" , - __func__, len); -return -EINVAL ; - } -debug (", fdt '%s'\n" , fdt_name); - fdt_node =fdt_subnode_offset (fdt, images, fdt_name); -if (fdt_node <0 ) { -debug ("%s: Cannot find fdt node '%s': %d\n" , - __func__, fdt_name, fdt_node); -return -EINVAL ; +return node; + } + +return -ENOENT ; +} + +static int spl_fit_select_index (const void *fit,int images,int *offsetp, +const char *type,int index) +{ +const char *name, *str; +int node, conf_node; +int len, i; + + *offsetp =0 ; + conf_node =spl_fit_find_config_node (fit); +if (conf_node <0 ) { +#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT +printf ("No matching DT out of these options:\n" ); +for (node =fdt_first_subnode (fit, conf_node); + node >=0 ; + node =fdt_next_subnode (fit, node)) { + name =fdt_getprop (fit, node,"description" , &len); +printf (" %s\n" , name); } +#endif +return conf_node; + } - *fdt_offsetp =fdt_getprop_u32 (fdt, fdt_node,"data-offset" ); - len =fdt_getprop_u32 (fdt, fdt_node,"data-size" ); -debug ("FIT: Selected '%s'\n" , name); + name =fdt_getprop (fit, conf_node, type, &len); +if (!name) { +debug ("cannot find property '%s': %d\n" , type, len); +return -EINVAL ; + } -return len; + str = name; +for (i =0 ; i < index; i++) { + str =strchr (str,'\0' ) +1 ; +if (!str || (str - name >= len)) { +debug ("no string for index %d\n" , index); +return -E2BIG ; + } } -#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT -printf ("No matching DT out of these options:\n" ); -for (node =fdt_first_subnode (fdt, conf); - node >=0 ; - node =fdt_next_subnode (fdt, node)) { - name =fdt_getprop (fdt, node,"description" , &len); -printf (" %s\n" , name); +debug ("%s: '%s'\n" , type, str); + node =fdt_subnode_offset (fit, images, str); +if (node <0 ) { +debug ("cannot find image node '%s': %d\n" , str, node); +return -EINVAL ; } -#endif -return -ENOENT ; + *offsetp =fdt_getprop_u32 (fit, node,"data-offset" ); + len =fdt_getprop_u32 (fit, node,"data-size" ); + +return len; }static int get_aligned_image_offset (struct spl_load_info *info,int offset)@@ -218,7 +243,8 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,memcpy (dst, src, data_size);/* Figure out which device tree the board wants to use */ - fdt_len =spl_fit_select_fdt (fit, images, &fdt_offset); + fdt_len =spl_fit_select_index (fit, images, &fdt_offset, +FIT_FDT_PROP ,0 );if (fdt_len <0 )return fdt_len;
PATCH v4 1/20 SPL: FIT: refactor FDT loading
In reply to Andre PrzywaraHi Andre,
Quoted 20 lines · Andre Przywara
Currently the SPL FIT loader uses the
spl_fit_select_fdt()function to find the offset to the right DTB within the FIT image.
For this it iterates over all subnodes of the /configuration node in the FIT tree and compares all "description" strings therein using a board specific matching function.
If that finds a match, it uses the string in the "fdt" property of that subnode to locate the matching subnode in the /images node, which points to the DTB data.
Now this works very well, but is quite specific to cover this particular use case. To open up the door for a more generic usage, let's split this function into:
1) a function that just returns the node offset for the matching configuration node (spl_fit_find_config_node())
2) a function that returns the image data any given property in a given configuration node points to, additionally using a given index into a possbile list of strings (spl_fit_select_index())
This allows us to replace the specific function above by asking for the image the_firststring of the "fdt"property_in the matching configuration subnode points to.
Quoted 8 lines
This patch introduces no functional changes, it just refactors the code to allow reusing it later.
(diff is overly clever here and produces a hard-to-read patch, so I recommend to throw a look at the result instead).
Signed-off-by Andre Przywara <[email protected]>Reviewed-by Lokesh Vutla <[email protected]>
Can you please fix my email address. lokeshvutla at ti.com
Thanks and regards,
Lokesh
PATCH v4 2/20 SPL: FIT: rework U-Boot image loading
In reply to Andre PrzywaraCurrently the SPL FIT loader always looks only for the first image in the /images node a FIT tree, which it loads and later executes.
Generalize this by looking for a "firmware" property in the matched configuration subnode, or, if that does not exist, for the first string in the "loadables" property. Then using the string in that property, load the image of that name from the /images node.
This still loads only one image at the moment, but refactors the code to allow extending this in a following patch.
To simplify later re-usage, we also generalize the spl_fit_select_index() function to not return the image location, but just the node offset.
--- common/spl/spl_fit.c | 46 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 14 deletions(-)
common/spl/spl_fit.c +32 -14
@@ -60,14 +60,25 @@ static int spl_fit_find_config_node(const void *fdt)return -ENOENT ; } -static int spl_fit_select_index (const void *fit,int images,int *offsetp, -const char *type,int index) +/** +* spl_fit_get_image_node(): By using the matching configuration subnode, +* retrieve the name of an image, specified by a property name and an index +* into that. +* @fit: Pointer to the FDT blob. +* @images: Offset of the /images subnode. +* @type: Name of the property within the configuration subnode. +* @index: Index into the list of strings in this property. +* +* Return: the node offset of the respective image node or a negative +* error number. +*/ +static int spl_fit_get_image_node (const void *fit,int images, +const char *type,int index) {const char *name, *str;int node, conf_node;int len, i; - *offsetp =0 ; conf_node =spl_fit_find_config_node (fit);if (conf_node <0 ) {#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
@@ -104,10 +115,7 @@ static int spl_fit_select_index(const void *fit, int images, int *offsetp,return -EINVAL ; } - *offsetp =fdt_getprop_u32 (fit, node,"data-offset" ); - len =fdt_getprop_u32 (fit, node,"data-size" ); - -return len; +return node; }static int get_aligned_image_offset (struct spl_load_info *info,int offset)
@@ -193,15 +201,22 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,if (count ==0 )return -EIO ; -/* find the firmware image to load */ +/* find the node holding the images information */ images =fdt_path_offset (fit,FIT_IMAGES_PATH );if (images <0 ) {debug ("%s: Cannot find /images node: %d\n" , __func__, images);return -1 ; } - node =fdt_first_subnode (fit, images); + +/* find the U-Boot image */ + node =spl_fit_get_image_node (fit, images,"firmware" ,0 );if (node <0 ) { -debug ("%s: Cannot find first image node: %d\n" , __func__, node); +debug ("could not find firmware image, trying loadables...\n" ); + node =spl_fit_get_image_node (fit, images,"loadables" ,0 ); + } +if (node <0 ) { +debug ("%s: Cannot find u-boot image node: %d\n" , + __func__, node);return -1 ; }
@@ -243,10 +258,13 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,memcpy (dst, src, data_size);/* Figure out which device tree the board wants to use */ - fdt_len =spl_fit_select_index (fit, images, &fdt_offset, -FIT_FDT_PROP ,0 ); -if (fdt_len <0 ) -return fdt_len; + node =spl_fit_get_image_node (fit, images,FIT_FDT_PROP ,0 ); +if (node <0 ) { +debug ("%s: cannot find FDT node\n" , __func__); +return node; + } + fdt_offset =fdt_getprop_u32 (fit, node,"data-offset" ); + fdt_len =fdt_getprop_u32 (fit, node,"data-size" );/* * Read the device tree and place it after the image. There may be
Signature · 1 line
2.8.2
PATCH v4 2/20 SPL: FIT: rework U-Boot image loading
Am Mittwoch, 26. April 2017, 01:32:34 CEST schrieb Andre Przywara:
Quoted 12 lines
Currently the SPL FIT loader always looks only for the first image in the /images node a FIT tree, which it loads and later executes.
Generalize this by looking for a "firmware" property in the matched configuration subnode, or, if that does not exist, for the first string in the "loadables" property. Then using the string in that property, load the image of that name from the /images node.
This still loads only one image at the moment, but refactors the code to allow extending this in a following patch.
To simplify later re-usage, we also generalize thespl_fit_select_index()function to not return the image location, but just the node offset.
Quoted 3 lines
Signed-off-by Andre Przywara <[email protected]>Reviewed-by Lokesh Vutla <[email protected]>Reviewed-by Simon Glass <[email protected]>
On a rk3399-firefly
PATCH v4 2/20 SPL: FIT: rework U-Boot image loading
In reply to Andre PrzywaraQuoted 12 lines · Andre Przywara
Currently the SPL FIT loader always looks only for the first image in the /images node a FIT tree, which it loads and later executes.
Generalize this by looking for a "firmware" property in the matched configuration subnode, or, if that does not exist, for the first string in the "loadables" property. Then using the string in that property, load the image of that name from the /images node.
This still loads only one image at the moment, but refactors the code to allow extending this in a following patch.
To simplify later re-usage, we also generalize thespl_fit_select_index()function to not return the image location, but just the node offset.
Quoted 3 lines
Signed-off-by Andre Przywara <[email protected]>Reviewed-by Lokesh Vutla <[email protected]>Reviewed-by Simon Glass <[email protected]>
Thanks,
- Kever
Quoted 93 lines
--- common/spl/spl_fit.c | 46 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 14 deletions(-)common/spl/spl_fit.c +32
-14@@ -60,14 +60,25 @@ static int spl_fit_find_config_node(const void *fdt)return -ENOENT ; } -static int spl_fit_select_index (const void *fit,int images,int *offsetp, -const char *type,int index) +/** +* spl_fit_get_image_node(): By using the matching configuration subnode, +* retrieve the name of an image, specified by a property name and an index +* into that. +* @fit: Pointer to the FDT blob. +* @images: Offset of the /images subnode. +* @type: Name of the property within the configuration subnode. +* @index: Index into the list of strings in this property. +* +* Return: the node offset of the respective image node or a negative +* error number. +*/ +static int spl_fit_get_image_node (const void *fit,int images, +const char *type,int index) {const char *name, *str;int node, conf_node;int len, i; - *offsetp =0 ; conf_node =spl_fit_find_config_node (fit);if (conf_node <0 ) {#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT @@ -104,10 +115,7 @@ static int spl_fit_select_index(const void *fit, int images, int *offsetp,return -EINVAL ; } - *offsetp =fdt_getprop_u32 (fit, node,"data-offset" ); - len =fdt_getprop_u32 (fit, node,"data-size" ); - -return len; +return node; }static int get_aligned_image_offset (struct spl_load_info *info,int offset)@@ -193,15 +201,22 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,if (count ==0 )return -EIO ; -/* find the firmware image to load */ +/* find the node holding the images information */ images =fdt_path_offset (fit,FIT_IMAGES_PATH );if (images <0 ) {debug ("%s: Cannot find /images node: %d\n" , __func__, images);return -1 ; } - node =fdt_first_subnode (fit, images); + +/* find the U-Boot image */ + node =spl_fit_get_image_node (fit, images,"firmware" ,0 );if (node <0 ) { -debug ("%s: Cannot find first image node: %d\n" , __func__, node); +debug ("could not find firmware image, trying loadables...\n" ); + node =spl_fit_get_image_node (fit, images,"loadables" ,0 ); + } +if (node <0 ) { +debug ("%s: Cannot find u-boot image node: %d\n" , + __func__, node);return -1 ; }@@ -243,10 +258,13 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,memcpy (dst, src, data_size);/* Figure out which device tree the board wants to use */ - fdt_len =spl_fit_select_index (fit, images, &fdt_offset, -FIT_FDT_PROP ,0 ); -if (fdt_len <0 ) -return fdt_len; + node =spl_fit_get_image_node (fit, images,FIT_FDT_PROP ,0 ); +if (node <0 ) { +debug ("%s: cannot find FDT node\n" , __func__); +return node; + } + fdt_offset =fdt_getprop_u32 (fit, node,"data-offset" ); + fdt_len =fdt_getprop_u32 (fit, node,"data-size" );/* * Read the device tree and place it after the image. There may be
PATCH v4 3/20 SPL: FIT: improve error handling
In reply to Andre PrzywaraAt the moment we ignore any errors due to missing FIT properties, instead go ahead and calculate our addresses with the -1 return value. Fix this and bail out if any of the mandatory properties are missing.
--- common/spl/spl_fit.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-)
common/spl/spl_fit.c +13 -2
@@ -11,14 +11,17 @@#include <libfdt.h> #include <spl.h> +#define FDT_ERROR ((ulong)(-1)) +static ulong fdt_getprop_u32 (const void *fdt,int node,const char *prop) {const u32 *cell;int len; cell =fdt_getprop (fdt, node, prop, &len); -if (len !=sizeof (*cell)) -return -1U ; +if (!cell || len !=sizeof (*cell)) +return FDT_ERROR ; +return fdt32_to_cpu (*cell); }
@@ -222,7 +225,11 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,/* Get its information and set up the spl_image structure */ data_offset =fdt_getprop_u32 (fit, node,"data-offset" ); +if (data_offset ==FDT_ERROR ) +return -ENOENT ; data_size =fdt_getprop_u32 (fit, node,"data-size" ); +if (data_size ==FDT_ERROR ) +return -ENOENT ; load =fdt_getprop_u32 (fit, node,"load" );debug ("data_offset=%x, data_size=%x\n" , data_offset, data_size); spl_image->load_addr = load;
@@ -265,6 +272,10 @@ int spl_load_simple_fit(struct spl_image_info *spl_image, } fdt_offset =fdt_getprop_u32 (fit, node,"data-offset" ); fdt_len =fdt_getprop_u32 (fit, node,"data-size" ); +if (fdt_offset ==FDT_ERROR || fdt_len ==FDT_ERROR ) { +debug ("%s: cannot load FDT data\n" __func__); +return -ENOENT ; + }/* * Read the device tree and place it after the image. There may be
Signature · 1 line
2.8.2
PATCH v4 3/20 SPL: FIT: improve error handling
Am Mittwoch, 26. April 2017, 01:32:35 CEST schrieb Andre Przywara:
Quoted 6 lines
At the moment we ignore any errors due to missing FIT properties, instead go ahead and calculate our addresses with the -1 return value. Fix this and bail out if any of the mandatory properties are missing.
Signed-off-by Andre Przywara <[email protected]>Reviewed-by Simon Glass <[email protected]>
On a rk3399-firefly
PATCH v4 3/20 SPL: FIT: improve error handling
In reply to Andre PrzywaraQuoted 6 lines · Andre Przywara
At the moment we ignore any errors due to missing FIT properties, instead go ahead and calculate our addresses with the -1 return value. Fix this and bail out if any of the mandatory properties are missing.
Signed-off-by Andre Przywara <[email protected]>Reviewed-by Simon Glass <[email protected]>
Thanks,
- Kever
Quoted 51 lines
--- common/spl/spl_fit.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-)common/spl/spl_fit.c +13
-2@@ -11,14 +11,17 @@#include <libfdt.h> #include <spl.h> +#define FDT_ERROR ((ulong)(-1)) +static ulong fdt_getprop_u32 (const void *fdt,int node,const char *prop) {const u32 *cell;int len; cell =fdt_getprop (fdt, node, prop, &len); -if (len !=sizeof (*cell)) -return -1U ; +if (!cell || len !=sizeof (*cell)) +return FDT_ERROR ; +return fdt32_to_cpu (*cell); }@@ -222,7 +225,11 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,/* Get its information and set up the spl_image structure */ data_offset =fdt_getprop_u32 (fit, node,"data-offset" ); +if (data_offset ==FDT_ERROR ) +return -ENOENT ; data_size =fdt_getprop_u32 (fit, node,"data-size" ); +if (data_size ==FDT_ERROR ) +return -ENOENT ; load =fdt_getprop_u32 (fit, node,"load" );debug ("data_offset=%x, data_size=%x\n" , data_offset, data_size); spl_image->load_addr = load;@@ -265,6 +272,10 @@ int spl_load_simple_fit(struct spl_image_info *spl_image, } fdt_offset =fdt_getprop_u32 (fit, node,"data-offset" ); fdt_len =fdt_getprop_u32 (fit, node,"data-size" ); +if (fdt_offset ==FDT_ERROR || fdt_len ==FDT_ERROR ) { +debug ("%s: cannot load FDT data\n" __func__); +return -ENOENT ; + }/* * Read the device tree and place it after the image. There may be
PATCH v4 4/20 SPL: FIT: factor out spl_load_fit_image()
In reply to Andre PrzywaraAt the moment we load two images from a FIT image: the actual U-Boot image and the .dtb file. Both times we have very similar code, that deals with alignment requirements the media we load from imposes upon us. Factor out this code into a new function, which we just call twice.
--- common/spl/spl_fit.c | 162 +++++++++++++++++++++++++-------------------------- 1 file changed, 80 insertions(+), 82 deletions(-)
common/spl/spl_fit.c +80 -82
@@ -159,19 +159,81 @@ static int get_aligned_image_size(struct spl_load_info *info, int data_size,return (data_size + info->bl_len -1 ) / info->bl_len; } +/** +* spl_load_fit_image(): load the image described in a certain FIT node +* @info: points to information about the device to load data from +* @sector: the start sector of the FIT image on the device +* @fit: points to the flattened device tree blob describing the FIT +* image +* @base_offset: the beginning of the data area containing the actual +* image data, relative to the beginning of the FIT +* @node: offset of the DT node describing the image to load (relative +* to @fit) +* @image_info: will be filled with information about the loaded image +* If the FIT node does not contain a "load" (address) property, +* the image gets loaded to the address pointed to by the +* load_addr member in this struct. +* +* Return: 0 on success or a negative error number. +*/ +static int spl_load_fit_image (struct spl_load_info *info,ulong sector, +void *fit,ulong base_offset,int node, +struct spl_image_info *image_info) +{ +ulong offset; +size_t length; +ulong load_addr, load_ptr; +void *src; +ulong overhead; +int nr_sectors; +int align_len =ARCH_DMA_MINALIGN -1 ; + + offset =fdt_getprop_u32 (fit, node,"data-offset" ); +if (offset ==FDT_ERROR ) +return -ENOENT ; + offset += base_offset; + length =fdt_getprop_u32 (fit, node,"data-size" ); +if (length ==FDT_ERROR ) +return -ENOENT ; + load_addr =fdt_getprop_u32 (fit, node,"load" ); +if (load_addr ==FDT_ERROR && image_info) + load_addr = image_info->load_addr; + load_ptr = (load_addr + align_len) & ~align_len; + + overhead =get_aligned_image_overhead (info, offset); + nr_sectors =get_aligned_image_size (info, length, offset); + +if (info->read (info, sector +get_aligned_image_offset (info, offset), + nr_sectors, (void *)load_ptr) != nr_sectors) +return -EIO ; +debug ("image: dst=%lx, offset=%lx, size=%lx\n" , load_ptr, offset, + (unsigned long )length); + + src = (void *)load_ptr + overhead; +#ifdef CONFIG_SPL_FIT_IMAGE_POST_PROCESS +board_fit_image_post_process (&src, &length); +#endif + +memcpy ((void *)load_addr, src, length); + +if (image_info) { + image_info->load_addr = load_addr; + image_info->size = length; + image_info->entry_point =fdt_getprop_u32 (fit, node,"entry" ); + } + +return 0 ; +} +int spl_load_simple_fit (struct spl_image_info *spl_image,struct spl_load_info *info,ulong sector,void *fit) {int sectors; -ulong size, load; +ulong size;unsigned long count; -int node, images; -void *load_ptr; -int fdt_offset, fdt_len; -int data_offset, data_size; +struct spl_image_info image_info; +int node, images, ret;int base_offset, align_len =ARCH_DMA_MINALIGN -1 ; -int src_sector; -void *dst, *src;/* * Figure out where the external images start. This is the base for the
@@ -223,46 +285,13 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,return -1 ; } -/* Get its information and set up the spl_image structure */ - data_offset =fdt_getprop_u32 (fit, node,"data-offset" ); -if (data_offset ==FDT_ERROR ) -return -ENOENT ; - data_size =fdt_getprop_u32 (fit, node,"data-size" ); -if (data_size ==FDT_ERROR ) -return -ENOENT ; - load =fdt_getprop_u32 (fit, node,"load" ); -debug ("data_offset=%x, data_size=%x\n" , data_offset, data_size); - spl_image->load_addr = load; - spl_image->entry_point = load; - spl_image->os =IH_OS_U_BOOT ; - -/* -* Work out where to place the image. We read it so that the first -* byte will be at 'load'. This may mean we need to load it starting -* before then, since we can only read whole blocks. -*/ - data_offset += base_offset; - sectors =get_aligned_image_size (info, data_size, data_offset); - load_ptr = (void *)load; -debug ("U-Boot size %x, data %p\n" , data_size, load_ptr); - dst = load_ptr; - -/* Read the image */ - src_sector = sector +get_aligned_image_offset (info, data_offset); -debug ("Aligned image read: dst=%p, src_sector=%x, sectors=%x\n" , - dst, src_sector, sectors); - count = info->read (info, src_sector, sectors, dst); -if (count != sectors) -return -EIO ; -debug ("image: dst=%p, data_offset=%x, size=%x\n" , dst, data_offset, - data_size); - src = dst +get_aligned_image_overhead (info, data_offset); +/* Load the image and set up the spl_image structure */ + ret =spl_load_fit_image (info, sector, fit, base_offset, node, + spl_image); +if (ret) +return ret; -#ifdef CONFIG_SPL_FIT_IMAGE_POST_PROCESS -board_fit_image_post_process ((void **)&src, (size_t *)&data_size); -#endif - -memcpy (dst, src, data_size); + spl_image->os =IH_OS_U_BOOT ;/* Figure out which device tree the board wants to use */ node =spl_fit_get_image_node (fit, images,FIT_FDT_PROP ,0 );
@@ -270,43 +299,12 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,debug ("%s: cannot find FDT node\n" , __func__);return node; } - fdt_offset =fdt_getprop_u32 (fit, node,"data-offset" ); - fdt_len =fdt_getprop_u32 (fit, node,"data-size" ); -if (fdt_offset ==FDT_ERROR || fdt_len ==FDT_ERROR ) { -debug ("%s: cannot load FDT data\n" __func__); -return -ENOENT ; - }/* -* Read the device tree and place it after the image. There may be -* some extra data before it since we can only read entire blocks. -* And also align the destination address to ARCH_DMA_MINALIGN. +* Read the device tree and place it after the image. +* Align the destination address to ARCH_DMA_MINALIGN. */ - dst = (void *)((load + data_size + align_len) & ~align_len); - fdt_offset += base_offset; - sectors =get_aligned_image_size (info, fdt_len, fdt_offset); - src_sector = sector +get_aligned_image_offset (info, fdt_offset); - count = info->read (info, src_sector, sectors, dst); -debug ("Aligned fdt read: dst %p, src_sector = %x, sectors %x\n" , - dst, src_sector, sectors); -if (count != sectors) -return -EIO ; - -/* -* Copy the device tree so that it starts immediately after the image. -* After this we will have the U-Boot image and its device tree ready -* for us to start. -*/ -debug ("fdt: dst=%p, data_offset=%x, size=%x\n" , dst, fdt_offset, - fdt_len); - src = dst +get_aligned_image_overhead (info, fdt_offset); - dst = load_ptr + data_size; - -#ifdef CONFIG_SPL_FIT_IMAGE_POST_PROCESS -board_fit_image_post_process ((void **)&src, (size_t *)&fdt_len); -#endif - -memcpy (dst, src, fdt_len); - -return 0 ; + image_info.load_addr = spl_image->load_addr + spl_image->size; +return spl_load_fit_image (info, sector, fit, base_offset, node, + &image_info); }
Signature · 1 line
2.8.2
PATCH v4 4/20 SPL: FIT: factor out spl_load_fit_image()
Am Mittwoch, 26. April 2017, 01:32:36 CEST schrieb Andre Przywara:
Quoted 7 lines
At the moment we load two images from a FIT image: the actual U-Boot image and the .dtb file. Both times we have very similar code, that deals with alignment requirements the media we load from imposes upon us. Factor out this code into a new function, which we just call twice.
Signed-off-by Andre Przywara <[email protected]>Reviewed-by Simon Glass <[email protected]>
On a rk3399-firefly
PATCH v4 4/20 SPL: FIT: factor out spl_load_fit_image()
In reply to Andre PrzywaraQuoted 7 lines · Andre Przywara
At the moment we load two images from a FIT image: the actual U-Boot image and the .dtb file. Both times we have very similar code, that deals with alignment requirements the media we load from imposes upon us. Factor out this code into a new function, which we just call twice.
Signed-off-by Andre Przywara <[email protected]>Reviewed-by Simon Glass <[email protected]>
Thanks,
- Kever
Quoted 199 lines
--- common/spl/spl_fit.c | 162 +++++++++++++++++++++++++-------------------------- 1 file changed, 80 insertions(+), 82 deletions(-)common/spl/spl_fit.c +80
-82@@ -159,19 +159,81 @@ static int get_aligned_image_size(struct spl_load_info *info, int data_size,return (data_size + info->bl_len -1 ) / info->bl_len; } +/** +* spl_load_fit_image(): load the image described in a certain FIT node +* @info: points to information about the device to load data from +* @sector: the start sector of the FIT image on the device +* @fit: points to the flattened device tree blob describing the FIT +* image +* @base_offset: the beginning of the data area containing the actual +* image data, relative to the beginning of the FIT +* @node: offset of the DT node describing the image to load (relative +* to @fit) +* @image_info: will be filled with information about the loaded image +* If the FIT node does not contain a "load" (address) property, +* the image gets loaded to the address pointed to by the +* load_addr member in this struct. +* +* Return: 0 on success or a negative error number. +*/ +static int spl_load_fit_image (struct spl_load_info *info,ulong sector, +void *fit,ulong base_offset,int node, +struct spl_image_info *image_info) +{ +ulong offset; +size_t length; +ulong load_addr, load_ptr; +void *src; +ulong overhead; +int nr_sectors; +int align_len =ARCH_DMA_MINALIGN -1 ; + + offset =fdt_getprop_u32 (fit, node,"data-offset" ); +if (offset ==FDT_ERROR ) +return -ENOENT ; + offset += base_offset; + length =fdt_getprop_u32 (fit, node,"data-size" ); +if (length ==FDT_ERROR ) +return -ENOENT ; + load_addr =fdt_getprop_u32 (fit, node,"load" ); +if (load_addr ==FDT_ERROR && image_info) + load_addr = image_info->load_addr; + load_ptr = (load_addr + align_len) & ~align_len; + + overhead =get_aligned_image_overhead (info, offset); + nr_sectors =get_aligned_image_size (info, length, offset); + +if (info->read (info, sector +get_aligned_image_offset (info, offset), + nr_sectors, (void *)load_ptr) != nr_sectors) +return -EIO ; +debug ("image: dst=%lx, offset=%lx, size=%lx\n" , load_ptr, offset, + (unsigned long )length); + + src = (void *)load_ptr + overhead; +#ifdef CONFIG_SPL_FIT_IMAGE_POST_PROCESS +board_fit_image_post_process (&src, &length); +#endif + +memcpy ((void *)load_addr, src, length); + +if (image_info) { + image_info->load_addr = load_addr; + image_info->size = length; + image_info->entry_point =fdt_getprop_u32 (fit, node,"entry" ); + } + +return 0 ; +} +int spl_load_simple_fit (struct spl_image_info *spl_image,struct spl_load_info *info,ulong sector,void *fit) {int sectors; -ulong size, load; +ulong size;unsigned long count; -int node, images; -void *load_ptr; -int fdt_offset, fdt_len; -int data_offset, data_size; +struct spl_image_info image_info; +int node, images, ret;int base_offset, align_len =ARCH_DMA_MINALIGN -1 ; -int src_sector; -void *dst, *src;/* * Figure out where the external images start. This is the base for the @@ -223,46 +285,13 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,return -1 ; } -/* Get its information and set up the spl_image structure */ - data_offset =fdt_getprop_u32 (fit, node,"data-offset" ); -if (data_offset ==FDT_ERROR ) -return -ENOENT ; - data_size =fdt_getprop_u32 (fit, node,"data-size" ); -if (data_size ==FDT_ERROR ) -return -ENOENT ; - load =fdt_getprop_u32 (fit, node,"load" ); -debug ("data_offset=%x, data_size=%x\n" , data_offset, data_size); - spl_image->load_addr = load; - spl_image->entry_point = load; - spl_image->os =IH_OS_U_BOOT ; - -/* -* Work out where to place the image. We read it so that the first -* byte will be at 'load'. This may mean we need to load it starting -* before then, since we can only read whole blocks. -*/ - data_offset += base_offset; - sectors =get_aligned_image_size (info, data_size, data_offset); - load_ptr = (void *)load; -debug ("U-Boot size %x, data %p\n" , data_size, load_ptr); - dst = load_ptr; - -/* Read the image */ - src_sector = sector +get_aligned_image_offset (info, data_offset); -debug ("Aligned image read: dst=%p, src_sector=%x, sectors=%x\n" , - dst, src_sector, sectors); - count = info->read (info, src_sector, sectors, dst); -if (count != sectors) -return -EIO ; -debug ("image: dst=%p, data_offset=%x, size=%x\n" , dst, data_offset, - data_size); - src = dst +get_aligned_image_overhead (info, data_offset); +/* Load the image and set up the spl_image structure */ + ret =spl_load_fit_image (info, sector, fit, base_offset, node, + spl_image); +if (ret) +return ret; -#ifdef CONFIG_SPL_FIT_IMAGE_POST_PROCESS -board_fit_image_post_process ((void **)&src, (size_t *)&data_size); -#endif - -memcpy (dst, src, data_size); + spl_image->os =IH_OS_U_BOOT ;/* Figure out which device tree the board wants to use */ node =spl_fit_get_image_node (fit, images,FIT_FDT_PROP ,0 );@@ -270,43 +299,12 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,debug ("%s: cannot find FDT node\n" , __func__);return node; } - fdt_offset =fdt_getprop_u32 (fit, node,"data-offset" ); - fdt_len =fdt_getprop_u32 (fit, node,"data-size" ); -if (fdt_offset ==FDT_ERROR || fdt_len ==FDT_ERROR ) { -debug ("%s: cannot load FDT data\n" __func__); -return -ENOENT ; - }/* -* Read the device tree and place it after the image. There may be -* some extra data before it since we can only read entire blocks. -* And also align the destination address to ARCH_DMA_MINALIGN. +* Read the device tree and place it after the image. +* Align the destination address to ARCH_DMA_MINALIGN. */ - dst = (void *)((load + data_size + align_len) & ~align_len); - fdt_offset += base_offset; - sectors =get_aligned_image_size (info, fdt_len, fdt_offset); - src_sector = sector +get_aligned_image_offset (info, fdt_offset); - count = info->read (info, src_sector, sectors, dst); -debug ("Aligned fdt read: dst %p, src_sector = %x, sectors %x\n" , - dst, src_sector, sectors); -if (count != sectors) -return -EIO ; - -/* -* Copy the device tree so that it starts immediately after the image. -* After this we will have the U-Boot image and its device tree ready -* for us to start. -*/ -debug ("fdt: dst=%p, data_offset=%x, size=%x\n" , dst, fdt_offset, - fdt_len); - src = dst +get_aligned_image_overhead (info, fdt_offset); - dst = load_ptr + data_size; - -#ifdef CONFIG_SPL_FIT_IMAGE_POST_PROCESS -board_fit_image_post_process ((void **)&src, (size_t *)&fdt_len); -#endif - -memcpy (dst, src, fdt_len); - -return 0 ; + image_info.load_addr = spl_image->load_addr + spl_image->size; +return spl_load_fit_image (info, sector, fit, base_offset, node, + &image_info); }
PATCH v4 5/20 SPL: FIT: allow loading multiple images
In reply to Andre PrzywaraSo far we were not using the FIT image format to its full potential:
The SPL FIT loader was just loading the first image from the /images node plus one of the listed DTBs.
Now with the refactored loader code it's easy to load an arbitrary number of images in addition to the two mentioned above.
As described in the FIT image source file format description, iterate over all images listed at the "loadables" property in the configuration node and load every image at its desired location.
This allows to load any kind of images:
- firmware images to execute before U-Boot proper (for instance ARM Trusted Firmware (ATF))
- firmware images for management processors (SCP, arisc, ...)
- firmware images for devices like WiFi controllers
- bit files for FPGAs
- additional configuration data
- kernels and/or ramdisks
The actual usage of this feature would be platform and/or board specific.
Also update the FIT documentation to mention the new SPL feature and provide an example .its file to demonstrate its features.
--- common/spl/spl_fit.c | 42 ++++++++++++++++++++- doc/uImage.FIT/howto.txt | 21 +++++++++++ doc/uImage.FIT/multi_spl.its | 89 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 150 insertions(+), 2 deletions(-) create mode 100644 doc/uImage.FIT/multi_spl.its
common/spl/spl_fit.c +40 -2
@@ -234,6 +234,7 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,struct spl_image_info image_info;int node, images, ret;int base_offset, align_len =ARCH_DMA_MINALIGN -1 ; +int index =0 ;/* * Figure out where the external images start. This is the base for the
@@ -278,6 +279,11 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,if (node <0 ) {debug ("could not find firmware image, trying loadables...\n" ); node =spl_fit_get_image_node (fit, images,"loadables" ,0 ); +/* +* If we pick the U-Boot image from "loadables", start at +* the second image when later loading additional images. +*/ + index =1 ; }if (node <0 ) { debug("%s: Cannot find u-boot image node: %d\n",
@@ -305,6 +311,38 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,* Align the destination address to ARCH_DMA_MINALIGN. */ image_info.load_addr = spl_image->load_addr + spl_image->size; -return spl_load_fit_image (info, sector, fit, base_offset, node, - &image_info); + ret =spl_load_fit_image (info, sector, fit, base_offset, node, + &image_info); +if (ret <0 ) +return ret; + +/* Now check if there are more images for us to load */ +for (; ; index++) { + node =spl_fit_get_image_node (fit, images,"loadables" , index); +if (node <0 ) +break ; + + ret =spl_load_fit_image (info, sector, fit, base_offset, node, + &image_info); +if (ret <0 ) +continue ; + +/* +* If the "firmware" image did not provide an entry point, +* use the first valid entry point from the loadables. +*/ +if (spl_image->entry_point ==FDT_ERROR && + image_info.entry_point !=FDT_ERROR ) + spl_image->entry_point = image_info.entry_point; + } + +/* +* If a platform does not provide CONFIG_SYS_UBOOT_START, U-Boot's +* Makefile will set it to 0 and it will end up as the entry point +* here. What it actually means is: use the load address. +*/ +if (spl_image->entry_point ==FDT_ERROR || spl_image->entry_point ==0 ) + spl_image->entry_point = spl_image->load_addr; + +return 0 ; }
doc/uImage.FIT/howto.txt +21 -0
@@ -44,6 +44,27 @@ image source file mkimage + dtc transfer to target + ---------------> image file --------------------> bootm image data file(s) +SPL usage +--------- + +The SPL can make use of the new image format as well, this traditionally +is used to ship multiple device tree files within one image. Code in the SPL +will choose the one matching the current board and append this to the +U-Boot proper binary to be automatically used up by it. +Aside from U-Boot proper and one device tree blob the SPL can load multiple, +arbitrary image files as well. These binaries should be specified in their +own subnode under the /images node, which should then be referenced from one or +multiple /configurations subnodes. The required images must be enumerated in +the "loadables" property as a list of strings. + +If a platform specific image source file (.its) is shipped with the U-Boot +source, it can be specified using the CONFIG_SPL_FIT_SOURCE Kconfig symbol. +In this case it will be automatically used by U-Boot's Makefile to generate +the image. +If a static source file is not flexible enough, CONFIG_SPL_FIT_GENERATOR +can point to a script which generates this image source file during +the build process. It gets passed a list of device tree files (taken from the +CONFIG_OF_LIST symbol). Example 1 -- old-style (non-FDT) kernel booting -----------------------------------------------
doc/uImage.FIT/multi_spl.its new file +89 -0
89 lines not on this page · raw message
Signature · 1 line
2.8.2
PATCH v4 5/20 SPL: FIT: allow loading multiple images
Am Mittwoch, 26. April 2017, 01:32:37 CEST schrieb Andre Przywara:
Quoted 18 lines
So far we were not using the FIT image format to its full potential:
The SPL FIT loader was just loading the first image from the /images node plus one of the listed DTBs.
Now with the refactored loader code it's easy to load an arbitrary number of images in addition to the two mentioned above.
As described in the FIT image source file format description, iterate over all images listed at the "loadables" property in the configuration node and load every image at its desired location.
This allows to load any kind of images:
- firmware images to execute before U-Boot proper (for instance ARM Trusted Firmware (ATF))
- firmware images for management processors (SCP, arisc, ...)
- firmware images for devices like WiFi controllers
- bit files for FPGAs
- additional configuration data
- kernels and/or ramdisks
The actual usage of this feature would be platform and/or board specific.
Quoted 6 lines
Also update the FIT documentation to mention the new SPL feature and provide an example .its file to demonstrate its features.
Signed-off-by Andre Przywara <[email protected]>Reviewed-by Lokesh Vutla <[email protected]>Reviewed-by Simon Glass <[email protected]>
On a rk3399-firefly
PATCH v4 5/20 SPL: FIT: allow loading multiple images
In reply to Andre PrzywaraQuoted 18 lines · Andre Przywara
So far we were not using the FIT image format to its full potential:
The SPL FIT loader was just loading the first image from the /images node plus one of the listed DTBs.
Now with the refactored loader code it's easy to load an arbitrary number of images in addition to the two mentioned above.
As described in the FIT image source file format description, iterate over all images listed at the "loadables" property in the configuration node and load every image at its desired location.
This allows to load any kind of images:
- firmware images to execute before U-Boot proper (for instance ARM Trusted Firmware (ATF))
- firmware images for management processors (SCP, arisc, ...)
- firmware images for devices like WiFi controllers
- bit files for FPGAs
- additional configuration data
- kernels and/or ramdisks
The actual usage of this feature would be platform and/or board specific.
Quoted 6 lines
Also update the FIT documentation to mention the new SPL feature and provide an example .its file to demonstrate its features.
Signed-off-by Andre Przywara <[email protected]>Reviewed-by Lokesh Vutla <[email protected]>Reviewed-by Simon Glass <[email protected]>
Thanks,
- Kever
Quoted 199 lines
--- common/spl/spl_fit.c | 42 ++++++++++++++++++++- doc/uImage.FIT/howto.txt | 21 +++++++++++ doc/uImage.FIT/multi_spl.its | 89 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 150 insertions(+), 2 deletions(-)create mode 100644 doc/uImage.FIT/multi_spl.its
common/spl/spl_fit.c +40
-2@@ -234,6 +234,7 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,struct spl_image_info image_info;int node, images, ret;int base_offset, align_len =ARCH_DMA_MINALIGN -1 ; +int index =0 ;/* * Figure out where the external images start. This is the base for the @@ -278,6 +279,11 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,if (node <0 ) {debug ("could not find firmware image, trying loadables...\n" ); node =spl_fit_get_image_node (fit, images,"loadables" ,0 ); +/* +* If we pick the U-Boot image from "loadables", start at +* the second image when later loading additional images. +*/ + index =1 ; }if (node <0 ) { debug("%s: Cannot find u-boot image node: %d\n",@@ -305,6 +311,38 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,* Align the destination address to ARCH_DMA_MINALIGN. */ image_info.load_addr = spl_image->load_addr + spl_image->size; -return spl_load_fit_image (info, sector, fit, base_offset, node, - &image_info); + ret =spl_load_fit_image (info, sector, fit, base_offset, node, + &image_info); +if (ret <0 ) +return ret; + +/* Now check if there are more images for us to load */ +for (; ; index++) { + node =spl_fit_get_image_node (fit, images,"loadables" , index); +if (node <0 ) +break ; + + ret =spl_load_fit_image (info, sector, fit, base_offset, node, + &image_info); +if (ret <0 ) +continue ; + +/* +* If the "firmware" image did not provide an entry point, +* use the first valid entry point from the loadables. +*/ +if (spl_image->entry_point ==FDT_ERROR && + image_info.entry_point !=FDT_ERROR ) + spl_image->entry_point = image_info.entry_point; + } + +/* +* If a platform does not provide CONFIG_SYS_UBOOT_START, U-Boot's +* Makefile will set it to 0 and it will end up as the entry point +* here. What it actually means is: use the load address. +*/ +if (spl_image->entry_point ==FDT_ERROR || spl_image->entry_point ==0 ) + spl_image->entry_point = spl_image->load_addr; + +return 0 ; }doc/uImage.FIT/howto.txt +21
-0@@ -44,6 +44,27 @@ image source file mkimage + dtc transfer to target + ---------------> image file --------------------> bootm image data file(s) +SPL usage +--------- + +The SPL can make use of the new image format as well, this traditionally +is used to ship multiple device tree files within one image. Code in the SPL +will choose the one matching the current board and append this to the +U-Boot proper binary to be automatically used up by it. +Aside from U-Boot proper and one device tree blob the SPL can load multiple, +arbitrary image files as well. These binaries should be specified in their +own subnode under the /images node, which should then be referenced from one or +multiple /configurations subnodes. The required images must be enumerated in +the "loadables" property as a list of strings. + +If a platform specific image source file (.its) is shipped with the U-Boot +source, it can be specified using the CONFIG_SPL_FIT_SOURCE Kconfig symbol. +In this case it will be automatically used by U-Boot's Makefile to generate +the image. +If a static source file is not flexible enough, CONFIG_SPL_FIT_GENERATOR +can point to a script which generates this image source file during +the build process. It gets passed a list of device tree files (taken from the +CONFIG_OF_LIST symbol). Example 1 -- old-style (non-FDT) kernel booting -----------------------------------------------doc/uImage.FIT/multi_spl.its new file +89
-0@@ -0,0 +1,89 @@ +/dts-v1/; + +/* + * (Bogus) example FIT image description file demonstrating the usage + * of multiple images loaded by the SPL. + * Several binaries will be loaded at their respective load addresses. + * Finally the one image specifying an entry point will be entered by the SPL. + */ + +/ { + description = "multiple firmware blobs and U-Boot, loaded by SPL"; + #address-cells = <0x1>; + + images { + + uboot { + description = "U-Boot (64-bit)"; + type = "standalone"; + arch = "arm64"; + compression = "none"; + load = <0x4a000000>; + }; + + atf { + description = "ARM Trusted Firmware"; + type = "firmware"; + arch = "arm64"; + compression = "none"; + load = <0x18000>; + entry = <0x18000>; + }; + + mgmt-firmware { + description = "arisc management processor firmware"; + type = "firmware"; + arch = "or1k"; + compression = "none"; + load = <0x40000>; + }; + + fdt at 1 { + description = "Pine64+ DT"; + type = "flat_dt"; + compression = "none"; + load = <0x4fa00000>; + arch = "arm64"; + }; + + fdt at 2 { + description = "Pine64 DT"; + type = "flat_dt"; + compression = "none"; + load = <0x4fa00000>; + arch = "arm64"; + }; + + kernel { + description = "4.7-rc5 kernel"; + type = "kernel"; + compression = "none"; + load = <0x40080000>; + arch = "arm64"; + }; + + initrd { + description = "Debian installer initrd"; + type = "ramdisk"; + compression = "none"; + load = <0x4fe00000>; + arch = "arm64"; + }; + }; + + configurations { + default = "config at 1"; + + config at 1 { + description = "sun50i-a64-pine64-plus"; + loadables = "uboot", "atf", "kernel", "initrd"; + fdt = "fdt at 1"; + }; + + config at 2 { + description = "sun50i-a64-pine64"; + loadables = "uboot", "atf", "mgmt-firmware"; + fdt = "fdt at 2"; + }; + }; +};
PATCH v4 6/20 Kconfig: fix SPL_FIT dependency
In reply to Andre PrzywaraSPL_FIT obviously requires libfdt in SPL, so let Kconfig express that by selecting SPL_OF_LIBFDT.
Also make the actual options that users want (SPL signature and SPL FIT loading) visible in the menu and let them select the SPL_FIT as a requirement.
Also remove the now redundant SPL_OF_LIBFDT from those Kconfigs that had it in for the SPL FIT loading feature.
--- Kconfig | 4 +++- configs/am335x_evm_defconfig | 1 - configs/evb-rk3399_defconfig | 1 - 3 files changed, 3 insertions(+), 3 deletions(-)
Kconfig +3 -1
@@ -208,15 +208,17 @@ config FIT_IMAGE_POST_PROCESS config SPL_FIT bool "Support Flattened Image Tree within SPL" depends on SPL + select SPL_OF_LIBFDT config SPL_FIT_SIGNATURE bool "Enable signature verification of FIT firmware within SPL" - depends on SPL_FIT depends on SPL_DM + select SPL_FIT select SPL_RSA config SPL_LOAD_FIT bool "Enable SPL loading U-Boot as a FIT" + select SPL_FIT help Normally with the SPL framework a legacy image is generated as part of the build. This contains U-Boot along with information as to
configs/am335x_evm_defconfig +0 -1
@@ -57,4 +57,3 @@ CONFIG_G_DNL_MANUFACTURER="Texas Instruments" CONFIG_G_DNL_VENDOR_NUM=0x0451 CONFIG_G_DNL_PRODUCT_NUM=0xd022 CONFIG_RSA=y -CONFIG_SPL_OF_LIBFDT=y
configs/evb-rk3399_defconfig +0 -1
@@ -4,7 +4,6 @@ CONFIG_ROCKCHIP_RK3399=y CONFIG_DEFAULT_DEVICE_TREE="rk3399-evb" CONFIG_FIT=y CONFIG_SPL_LOAD_FIT=y -CONFIG_SPL_OF_LIBFDT=y CONFIG_SPL_ATF_SUPPORT=y CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x200 CONFIG_SPL_ATF_TEXT_BASE=0x00010000
Signature · 1 line
2.8.2
PATCH v4 6/20 Kconfig: fix SPL_FIT dependency
Quoted 8 lines · Andre Przywara
SPL_FITobviously requires libfdt in SPL, so letKconfigexpress that by selectingSPL_OF_LIBFDT.
Also make the actual options that users want (SPL signature and SPL FIT loading) visible in the menu and let them select theSPL_FITas a requirement.
Also remove the now redundantSPL_OF_LIBFDTfrom those Kconfigs that had it in for the SPL FIT loading feature.
Quoted 6 lines
Signed-off-by Andre Przywara <[email protected]>--- Kconfig | 4 +++- configs/am335x_evm_defconfig | 1 - configs/evb-rk3399_defconfig | 1 - 3 files changed, 3 insertions(+), 3 deletions(-)
PATCH v4 7/20 tools: mksunxiboot: allow larger SPL binaries
In reply to Andre Przywaramksunxiboot limits the size of the resulting SPL binaries to pretty conservative values to cover all SoCs and all boot media (NAND). It turns out that we have limit checks in place in the build process, so mksunxiboot can be relaxed and allow packaging binaries up to the actual 32KB the mask boot ROM actually imposes.
This allows to have a bigger SPL, which is crucial for AArch64 builds.
--- tools/mksunxiboot.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
tools/mksunxiboot.c +2 -2
@@ -48,8 +48,8 @@ int gen_check_sum(struct boot_file_head *head_p)#define ALIGN (x, a) __ALIGN_MASK((x), (typeof(x))(a)-1)#define __ALIGN_MASK (x, mask) (((x)+(mask))&~(mask)) -#define SUN4I_SRAM_SIZE 0x7600/* 0x7748+ is used by BROM */ -#define SRAM_LOAD_MAX_SIZE (SUN4I_SRAM_SIZE - sizeof(struct boot_file_head)) +#define SUNXI_SRAM_SIZE 0x8000/* SoC with smaller size are limited before */ +#define SRAM_LOAD_MAX_SIZE (SUNXI_SRAM_SIZE - sizeof(struct boot_file_head))/* * BROM (at least on A10 and A20) requires NAND-images to be explicitly aligned
Signature · 1 line
2.8.2
PATCH v4 8/20 armv8: SPL: only compile GIC code if needed
In reply to Andre PrzywaraNot every SoC needs to set up the GIC interrupt controller, so link think code only when the respective config option is set. This shaves off some bytes from the SPL code size.
--- arch/arm/lib/Makefile | 2 ++ 1 file changed, 2 insertions(+)
arch/arm/lib/Makefile +2 -0
@@ -44,7 +44,9 @@ ifdef CONFIG_CPU_V7M obj-y += interrupts_m.o else ifdef CONFIG_ARM64 obj-y += ccn504.o +ifneq ($(CONFIG_GICV2)$(CONFIG_GICV3),) obj-y += gic_64.o +endif obj-y += interrupts_64.o else obj-y += interrupts.o
Signature · 1 line
2.8.2
PATCH v4 9/20 armv8: fsl: move ccn504 code into FSL Makefile
In reply to Andre PrzywaraThe generic ARMv8 assembly code contains routines for setting up a CCN interconnect, though the Freescale SoCs are the only user. Link this code only for Freescale targets, this saves some precious bytes in the chronically tight SPL.
--- arch/arm/lib/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/lib/Makefile +1 -1
@@ -43,7 +43,7 @@ obj-y += stack.o ifdef CONFIG_CPU_V7M obj-y += interrupts_m.o else ifdef CONFIG_ARM64 -obj-y += ccn504.o +obj-$(CONFIG_FSL_LAYERSCAPE) += ccn504.o ifneq ($(CONFIG_GICV2)$(CONFIG_GICV3),) obj-y += gic_64.o endif
Signature · 1 line
2.8.2
PATCH v4 10/20 sunxi: A64: move SPL stack to end of SRAM A2
In reply to Andre PrzywaraThe SPL stack is usually located at the end of SRAM A1, where it grows towards the end of the SPL.
For the really big AArch64 binaries the stack overwrites code pretty soon, so move the SPL stack to the end of SRAM A2, which is unused at this time.
--- include/configs/sunxi-common.h | 5 +++++ 1 file changed, 5 insertions(+)
include/configs/sunxi-common.h +5 -0
@@ -187,7 +187,12 @@#ifdef CONFIG_SUNXI_HIGH_SRAM #define CONFIG_SPL_TEXT_BASE 0x10040/* sram start+header */ #define CONFIG_SPL_MAX_SIZE 0x7fc0/* 32 KiB */ +#ifdef CONFIG_ARM64 +/* end of SRAM A2 for now, as SRAM A1 is pretty tight for an ARM64 build */ +#define LOW_LEVEL_SRAM_STACK 0x00054000 +#else #define LOW_LEVEL_SRAM_STACK 0x00018000 +#endif /* !CONFIG_ARM64 */ #else #define CONFIG_SPL_TEXT_BASE 0x40/* sram start+header */ #define CONFIG_SPL_MAX_SIZE 0x5fc0/* 24KB on sun4i/sun7i */
Signature · 1 line
2.8.2
PATCH v4 11/20 sunxi: SPL: store RAM size in gd
In reply to Andre PrzywaraThe sunxi SPL was holding the detected RAM size in some local variable only, so it wasn't accessible for other functions.
Store the value in gd->ram_size instead, so it can be used later on.
--- board/sunxi/board.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
board/sunxi/board.c +3 -4
@@ -504,7 +504,6 @@ void i2c_init_board(void)void sunxi_board_init (void ) {int power_failed =0 ; -unsigned long ramsize;#ifdef CONFIG_SY8106A_POWER power_failed =sy8106a_set_vout1 (CONFIG_SY8106A_VOUT1_VOLT );
@@ -565,9 +564,9 @@ void sunxi_board_init(void)#endif #endif printf ("DRAM:" ); - ramsize =sunxi_dram_init (); -printf (" %d MiB\n" , (int )(ramsize >>20 )); -if (!ramsize) + gd->ram_size =sunxi_dram_init (); +printf (" %d MiB\n" , (int )(gd->ram_size >>20 )); +if (!gd->ram_size)hang ();/*
Signature · 1 line
2.8.2
PATCH v4 12/20 sunxi: SPL: add FIT config selector for Pine64 boards
In reply to Andre PrzywaraFor a board or platform to support FIT loading in the SPL, it has to provide a board_fit_config_name_match() routine, which helps to select one of possibly multiple DTBs contained in a FIT image. Provide a simple function which chooses the DT name U-Boot was configured with.
If the DT name is one of the two Pine64 versions, determine the exact model by checking the DRAM size.
--- board/sunxi/board.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
board/sunxi/board.c +23 -0
@@ -749,3 +749,26 @@ int ft_board_setup(void *blob, bd_t *bd)#endif return 0 ; } + +#ifdef CONFIG_SPL_LOAD_FIT +int board_fit_config_name_match (const char *name) +{ +const char *cmp_str; + +#ifdef CONFIG_DEFAULT_DEVICE_TREE + cmp_str =CONFIG_DEFAULT_DEVICE_TREE ; +#else +return 0 ; +#endif + +/* Differentiate the two Pine64 board DTs by their DRAM size. */ +if (strstr (name,"-pine64" ) &&strstr (cmp_str,"-pine64" )) { +if ((gd->ram_size >512 *1024 *1024 )) +return !strstr (name,"plus" ); +else +return !!strstr (name,"plus" ); + }else { +return strcmp (name, cmp_str); + } +} +#endif
Signature · 1 line
2.8.2
PATCH v4 13/20 Makefile: add rules to generate SPL FIT images
In reply to Andre PrzywaraSome platforms require more complex U-Boot images than we can easily generate via the mkimage command line, for instance to load additional image files.
Introduce a CONFIG_SPL_FIT_SOURCE and CONFIG_SPL_FIT_GENERATOR symbol, which can either hold an .its source file describing the image layout, or, in the second case, a generator tool (script) to create such a source file. This script gets passed the list of device tree files from the CONFIG_OF_LIST variable.
A platform or board can define either of those in their defconfig file to allow an easy building of such an image.
--- Kconfig | 17 +++++++++++++++++ Makefile | 20 ++++++++++++++++++++ 2 files changed, 37 insertions(+)
Kconfig +17 -0
@@ -241,6 +241,23 @@ config SPL_FIT_IMAGE_POST_PROCESS injected into the FIT creation (i.e. the blobs would have been pre- processed before being added to the FIT image). +config SPL_FIT_SOURCE + string ".its source file for U-Boot FIT image" + depends on SPL_FIT + help + Specifies a (platform specific) FIT source file to generate the + U-Boot FIT image. This could specify further image to load and/or + execute. + +config SPL_FIT_GENERATOR + string ".its file generator script for U-Boot FIT image" + depends on SPL_FIT + help + Specifies a (platform specific) script file to generate the FIT + source file used to build the U-Boot FIT image file. This gets + passed a list of supported device tree file stub names to + include in the generated image. + endif # FIT config OF_BOARD_SETUP
Makefile +20 -0
@@ -831,6 +831,10 @@ quiet_cmd_mkimage = MKIMAGE $@ cmd_mkimage = $(objtree)/tools/mkimage $(MKIMAGEFLAGS_$(@F)) -d $< $@ \ $(if $(KBUILD_VERBOSE:1=), >$(MKIMAGEOUTPUT)) +quiet_cmd_mkfitimage = MKIMAGE $@ +cmd_mkfitimage = $(objtree)/tools/mkimage $(MKIMAGEFLAGS_$(@F)) -f $(U_BOOT_ITS) -E $@ \ + $(if $(KBUILD_VERBOSE:1=), >$(MKIMAGEOUTPUT)) + quiet_cmd_cat = CAT $@ cmd_cat = cat $(filter-out $(PHONY), $^) > $@
@@ -950,6 +954,19 @@ quiet_cmd_cpp_cfg = CFG $@ cmd_cpp_cfg = $(CPP) -Wp,-MD,$(depfile) $(cpp_flags) $(LDPPFLAGS) -ansi \ -DDO_DEPS_ONLY -D__ASSEMBLY__ -x assembler-with-cpp -P -dM -E -o $@ $< +# Boards with more complex image requirments can provide an .its source file +# or a generator script +ifneq ($(CONFIG_SPL_FIT_SOURCE),"") +U_BOOT_ITS = $(subst ",,$(CONFIG_SPL_FIT_SOURCE)) +else +ifneq ($(CONFIG_SPL_FIT_GENERATOR),"") +U_BOOT_ITS := u-boot.its +$(U_BOOT_ITS): FORCE + $(srctree)/$(CONFIG_SPL_FIT_GENERATOR) \ + $(patsubst %,arch/$(ARCH)/dts/%.dtb,$(subst ",,$(CONFIG_OF_LIST))) > $@ +endif +endif + ifdef CONFIG_SPL_LOAD_FIT MKIMAGEFLAGS_u-boot.img = -f auto -A $(ARCH) -T firmware -C none -O u-boot \ -a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_UBOOT_START) \
@@ -982,6 +999,9 @@ u-boot-dtb.img u-boot.img u-boot.kwb u-boot.pbl u-boot-ivt.img: \ $(if $(CONFIG_SPL_LOAD_FIT),u-boot-nodtb.bin dts/dt.dtb,u-boot.bin) FORCE $(call if_changed,mkimage) +u-boot.itb: u-boot-nodtb.bin dts/dt.dtb $(U_BOOT_ITS) FORCE + $(call if_changed,mkfitimage) + u-boot-spl.kwb: u-boot.img spl/u-boot-spl.bin FORCE $(call if_changed,mkimage)
Signature · 1 line
2.8.2
PATCH v4 14/20 sunxi: 64-bit SoCs: introduce FIT generator script
In reply to Andre PrzywaraNow that the Makefile can call a generator script to build a more advanced FIT image, let's use this feature to address the needs of Allwinner boards with 64-bit SoCs (A64 and H5).
The (DTB stripped) U-Boot binary and the ATF are static, but we allow an arbitrary number of supported device trees to be passed. The script enters both a DT entry in the /images node and the respective subnode in /configurations to support all listed DTBs.
The location of the bl31.bin image from the ARM Trusted Firmware build can either by specified via the BL31 environment variable. If this is not set, the script looks for bl31.bin in U-Boot's build directory (which could be a symlink as well).
--- board/sunxi/mksunxi_fit_atf.sh | 75 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100755 board/sunxi/mksunxi_fit_atf.sh
board/sunxi/mksunxi_fit_atf.sh new file +75 -0
@@ -0,0 +1,75 @@ +#!/bin/sh +# +# script to generate FIT image source for 64-bit sunxi boards with +# ARM Trusted Firmware and multiple device trees (given on the command line) +# +# usage: $0 <dt_name> [<dt_name> [<dt_name] ...] + +[ -z "$BL31" ] && BL31="bl31.bin" + +cat << __HEADER_EOF +/dts-v1/; + +/ { + description = "Configuration to load ATF before U-Boot"; + #address-cells = <1>; + + images { + uboot at 1 { + description = "U-Boot (64-bit)"; + data = /incbin/("u-boot-nodtb.bin"); + type = "standalone"; + arch = "arm64"; + compression = "none"; + load = <0x4a000000>; + }; + atf at 1 { + description = "ARM Trusted Firmware"; + data = /incbin/("$BL31"); + type = "firmware"; + arch = "arm64"; + compression = "none"; + load = <0x44000>; + entry = <0x44000>; + }; +__HEADER_EOF + +cnt=1 +for dtname in $* +do + cat << __FDT_IMAGE_EOF + fdt@$cnt { + description = "$(basename $dtname .dtb)"; + data = /incbin/("$dtname"); + type = "flat_dt"; + compression = "none"; + }; +__FDT_IMAGE_EOF + cnt=$((cnt+1)) +done + +cat << __CONF_HEADER_EOF + }; + configurations { + default = "config at 1"; + +__CONF_HEADER_EOF + +cnt=1 +for dtname in $* +do + cat << __CONF_SECTION_EOF + config@$cnt { + description = "$(basename $dtname .dtb)"; + firmware = "uboot at 1"; + loadables = "atf@1"; + fdt = "fdt@$cnt"; + }; +__CONF_SECTION_EOF + cnt=$((cnt+1)) +done + +cat << __ITS_EOF + }; +}; +__ITS_EOF
Signature · 1 line
2.8.2
PATCH v4 15/20 sunxi: defconfig: add supported DT list for Pine64
In reply to Andre PrzywaraWhen a board uses a FIT image to load U-Boot proper, it requires a list of supported device trees to be supplied in CONFIG_OF_LIST, from which it chooses the right one at runtime.
For boards with just one possible DT (like the OrangePi PC2) this defaults to CONFIG_DEFAULT_DEVICE_TREE, but for the Pine64 with its two possible models we provide all compatible DTs in this config symbol.
--- configs/pine64_plus_defconfig | 1 + 1 file changed, 1 insertion(+)
configs/pine64_plus_defconfig +1 -0
@@ -3,6 +3,7 @@ CONFIG_ARCH_SUNXI=y CONFIG_MACH_SUN50I=y CONFIG_RESERVE_ALLWINNER_BOOT0_HEADER=y CONFIG_DEFAULT_DEVICE_TREE="sun50i-a64-pine64-plus" +CONFIG_OF_LIST="sun50i-a64-pine64 sun50i-a64-pine64-plus" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set CONFIG_CONSOLE_MUX=y CONFIG_SPL=y
Signature · 1 line
2.8.2
PATCH v4 15/20 sunxi: defconfig: add supported DT list for Pine64
Quoted 17 lines · Andre Przywara
When a board uses a FIT image to load U-Boot proper, it requires a list of supported device trees to be supplied in
CONFIG_OF_LIST, from which it chooses the right one at runtime.
For boards with just one possible DT (like the OrangePi PC2) this defaults toCONFIG_DEFAULT_DEVICE_TREE, but for the Pine64 with its two possible models we provide all compatible DTs in this config symbol.Signed-off-by Andre Przywara <[email protected]>--- configs/pine64_plus_defconfig | 1 + 1 file changed, 1 insertion(+)configs/pine64_plus_defconfig +0
-0
configs/pine64_plus_defconfig CONFIG_ARCH_SUNXI=y · line 6
Quoted 4 lines
configs/pine64_plus_defconfig +1
-0@@ -3,6 +3,7 @@ CONFIG_ARCH_SUNXI=y CONFIG_MACH_SUN50I=y CONFIG_RESERVE_ALLWINNER_BOOT0_HEADER=y CONFIG_DEFAULT_DEVICE_TREE="sun50i-a64-pine64-plus" +CONFIG_OF_LIST="sun50i-a64-pine64 sun50i-a64-pine64-plus"
fdtfile env is compile option now, so it all ways assign CONFIG_DEFAULT_DEVICE_TREE so it can't pick sun50i-a64-pine64.dtb here, are you manage this in runtime board code?
thanks!
Signature · 4 lines
Jagan Teki Free Software Engineer | www.openedev.com U-Boot, Linux | Upstream Maintainer Hyderabad, India.
PATCH v4 15/20 sunxi: defconfig: add supported DT list for Pine64
Hi,
Quoted 13 lines · Jagan Teki
Quoted 12 lines · Andre Przywara
When a board uses a FIT image to load U-Boot proper, it requires a list of supported device trees to be supplied in
CONFIG_OF_LIST, from which it chooses the right one at runtime.
For boards with just one possible DT (like the OrangePi PC2) this defaults toCONFIG_DEFAULT_DEVICE_TREE, but for the Pine64 with its two possible models we provide all compatible DTs in this config symbol.Signed-off-by Andre Przywara <[email protected]>--- configs/pine64_plus_defconfig | 1 + 1 file changed, 1 insertion(+)
Quoted 13 lines
configs/pine64_plus_defconfig CONFIG_ARCH_SUNXI=y · line 6
Quoted 9 lines
configs/pine64_plus_defconfig +1
-0@@ -3,6 +3,7 @@ CONFIG_ARCH_SUNXI=y CONFIG_MACH_SUN50I=y CONFIG_RESERVE_ALLWINNER_BOOT0_HEADER=y CONFIG_DEFAULT_DEVICE_TREE="sun50i-a64-pine64-plus" +CONFIG_OF_LIST="sun50i-a64-pine64 sun50i-a64-pine64-plus"fdtfile env is compile option now, so it all ways assign
CONFIG_DEFAULT_DEVICE_TREEso it can't pick sun50i-a64-pine64.dtb here, are you manage this in runtime board code?
There may be a confusion about two different uses of DT:CONFIG_DEFAULT_DEVICE_TREE and CONFIG_OF_LIST are there to tell which DT U-Boot (proper) *itself* uses: and yes, we pick one of OF_LIST at runtime (based on some board-specific code, for instance 512MB RAM on the Pine64(non-plus).
The "fdtfile" environment variable is to give a filename stub for loading an *external* DT for the *OS*.
Eventually we hopefully won't need that variable and .dtb loading at all, instead we just pass U-Boot's DT ($fdtcontroladdr) on the OS. This removes the churn distributions have these days with having to provide .dtb files for each and every board they want to support.
Cheers,
Andre.
PATCH v4 15/20 sunxi: defconfig: add supported DT list for Pine64
In reply to Andre PrzywaraQuoted 11 lines · Andre Przywara
When a board uses a FIT image to load U-Boot proper, it requires a list of supported device trees to be supplied in
CONFIG_OF_LIST, from which it chooses the right one at runtime.
For boards with just one possible DT (like the OrangePi PC2) this defaults toCONFIG_DEFAULT_DEVICE_TREE, but for the Pine64 with its two possible models we provide all compatible DTs in this config symbol.Signed-off-by Andre Przywara <[email protected]>--- configs/pine64_plus_defconfig | 1 + 1 file changed, 1 insertion(+)
PATCH v4 16/20 sunxi: enable automatic FIT build for 64-bit SoCs
In reply to Andre PrzywaraThe Allwinner SoCs with 64-bit cores use an ARM Trusted Firmware binary, which needs to be loaded alongside U-Boot proper.
Set the respective Kconfig options to let them select this feature and also automatically build the FIT image.
--- Kconfig | 1 + board/sunxi/Kconfig | 4 ++++ include/configs/sunxi-common.h | 4 ++++ 3 files changed, 9 insertions(+)
Kconfig +1 -0
@@ -252,6 +252,7 @@ config SPL_FIT_SOURCE config SPL_FIT_GENERATOR string ".its file generator script for U-Boot FIT image" depends on SPL_FIT + default "board/sunxi/mksunxi_fit_atf.sh" if SPL_LOAD_FIT && ARCH_SUNXI help Specifies a (platform specific) script file to generate the FIT source file used to build the U-Boot FIT image file. This gets
board/sunxi/Kconfig +4 -0
@@ -167,12 +167,16 @@ config MACH_SUN50I select SUNXI_GEN_SUN6I select SUNXI_HIGH_SRAM select SUPPORT_SPL + select FIT + select SPL_LOAD_FIT config MACH_SUN50I_H5 bool "sun50i (Allwinner H5)" select ARM64 select MACH_SUNXI_H3_H5 select SUNXI_HIGH_SRAM + select FIT + select SPL_LOAD_FIT endchoice
include/configs/sunxi-common.h +4 -0
@@ -32,6 +32,10 @@# define CONFIG_MACH_TYPE_COMPAT_REV 1#endif +#ifdef CONFIG_ARM64 +#define CONFIG_BUILD_TARGET "u-boot.itb" +#endif +/* Serial & console */ #define CONFIG_SYS_NS16550_SERIAL /* ns16550 reg in the low bits of cpu reg */
Signature · 1 line
2.8.2
PATCH v4 17/20 sunxi: Store the device tree name in the SPL header
In reply to Andre PrzywaraFrom: Siarhei Siamashka <[email protected]>
This patch updates the mksunxiboot tool to optionally add the default device tree name string to the SPL header. This information can be used by the firmware upgrade tools to protect users from harming themselves by trying to upgrade to an incompatible bootloader.
The primary use case here is a non-removable bootable media (such as NAND, eMMC or SPI flash), which already may have a properly working, but a little bit outdated bootloader installed. For example, the user may download or build a new U-Boot image for "Cubieboard", and then attemept to install it on a "Cubieboard2" hardware by mistake as a replacement for the already existing bootloader. If this happens, the flash programming tool can identify this problem and warn the user.
The size of the SPL header is also increased from 64 bytes to 96 bytes to provide enough space for the device tree name string.
[Andre: split patch to remove OF_LIST hash feature]
--- arch/arm/include/asm/arch-sunxi/spl.h | 19 +++++++++++--- include/configs/sunxi-common.h | 8 +++--- scripts/Makefile.spl | 3 ++- tools/mksunxiboot.c | 49 ++++++++++++++++++++++++++++++++--- 4 files changed, 67 insertions(+), 12 deletions(-)
arch/arm/include/asm/arch-sunxi/spl.h +16 -3
@@ -10,7 +10,7 @@#define BOOT0_MAGIC "eGON.BT0"#define SPL_SIGNATURE "SPL"/* marks "sunxi" SPL header */ -#define SPL_HEADER_VERSION 1 +#define SPL_HEADER_VERSION 2#ifdef CONFIG_SUNXI_HIGH_SRAM #define SPL_ADDR 0x10000
@@ -58,11 +58,24 @@ struct boot_file_head {* compatible format, ready to be imported via "env import -t". */ uint32_t fel_uEnv_length; -uint32_t reserved1[2 ]; +/* +* Offset of an ASCIIZ string (relative to the SPL header), which +* contains the default device tree name (CONFIG_DEFAULT_DEVICE_TREE). +* This is optional and may be set to NULL. Is intended to be used +* by flash programming tools for providing nice informative messages +* to the users. +*/ +uint32_t dt_name_offset; +uint32_t reserved1;uint32_t boot_media;/* written here by the boot ROM */ - uint32_t reserved2[5]; /* padding, align to 64 bytes */ +/* A padding area (may be used for storing text strings) */ +uint32_t string_pool[13 ]; + /* The header must be a multiple of 32 bytes (for VBAR alignment) */ }; +/* Compile time check to assure proper alignment of structure */ +typedef char boot_file_head_not_multiple_of_32 [1 -2 *(sizeof (struct boot_file_head ) %32 )]; +#define is_boot0_magic (addr) (memcmp((void *)addr, BOOT0_MAGIC, 8) == 0)#endif
include/configs/sunxi-common.h +4 -4
@@ -189,8 +189,8 @@#endif #ifdef CONFIG_SUNXI_HIGH_SRAM -#define CONFIG_SPL_TEXT_BASE 0x10040/* sram start+header */ -#define CONFIG_SPL_MAX_SIZE 0x7fc0/* 32 KiB */ +#define CONFIG_SPL_TEXT_BASE 0x10060/* sram start+header */ +#define CONFIG_SPL_MAX_SIZE 0x7fa0/* 32 KiB */ #ifdef CONFIG_ARM64 /* end of SRAM A2 for now, as SRAM A1 is pretty tight for an ARM64 build */ #define LOW_LEVEL_SRAM_STACK 0x00054000
@@ -198,8 +198,8 @@#define LOW_LEVEL_SRAM_STACK 0x00018000#endif /* !CONFIG_ARM64 */ #else -#define CONFIG_SPL_TEXT_BASE 0x40/* sram start+header */ -#define CONFIG_SPL_MAX_SIZE 0x5fc0/* 24KB on sun4i/sun7i */ +#define CONFIG_SPL_TEXT_BASE 0x60/* sram start+header */ +#define CONFIG_SPL_MAX_SIZE 0x5fa0/* 24KB on sun4i/sun7i */ #define LOW_LEVEL_SRAM_STACK 0x00008000/* End of sram */ #endif
scripts/Makefile.spl +2 -1
@@ -304,7 +304,8 @@ $(obj)/$(SPL_BIN).sfp: $(obj)/$(SPL_BIN).bin FORCE $(call if_changed,mkimage) quiet_cmd_mksunxiboot = MKSUNXI $@ -cmd_mksunxiboot = $(objtree)/tools/mksunxiboot $< $@ +cmd_mksunxiboot = $(objtree)/tools/mksunxiboot \ + --default-dt $(CONFIG_DEFAULT_DEVICE_TREE) $< $@ $(obj)/sunxi-spl.bin: $(obj)/$(SPL_BIN).bin FORCE $(call if_changed,mksunxiboot)
tools/mksunxiboot.c +45 -4
62 lines not on this page · raw message
Signature · 1 line
2.8.2
PATCH v4 18/20 sunxi: use SPL header DT name for FIT board matching
In reply to Andre PrzywaraNow that we can store a DT name in the SPL header, use this string (if available) when finding the right DT blob to load for U-Boot proper. This allows a generic U-Boot (proper) image to be combined with a bunch of supported DTs, with just the SPL (possibly only that string) to be different.
Eventually this string can be written after the build process by some firmware update tool.
--- board/sunxi/board.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
board/sunxi/board.c +9 -3
@@ -753,13 +753,19 @@ int ft_board_setup(void *blob, bd_t *bd)#ifdef CONFIG_SPL_LOAD_FIT int board_fit_config_name_match (const char *name) { -const char *cmp_str; +struct boot_file_head *spl = (void *)(ulong )SPL_ADDR ; +const char *cmp_str = (void *)(ulong )SPL_ADDR ; +/* Check if there is a DT name stored in the SPL header and use that. */ +if (spl->dt_name_offset) { + cmp_str += spl->dt_name_offset; + }else {#ifdef CONFIG_DEFAULT_DEVICE_TREE - cmp_str =CONFIG_DEFAULT_DEVICE_TREE ; + cmp_str =CONFIG_DEFAULT_DEVICE_TREE ;#else -return 0 ; +return 0 ;#endif + };/* Differentiate the two Pine64 board DTs by their DRAM size. */ if (strstr (name,"-pine64" ) &&strstr (cmp_str,"-pine64" )) {
Signature · 1 line
2.8.2
PATCH v4 19/20 sunxi: update Pine64 README
In reply to Andre PrzywaraWith the DRAM init code and the SPL's ability to load the ATF binary as well, we can now officially get rid of the boot0 boot method, which involed a closed-source proprietary blob to be used.
Rework the Pine64 README file to document how to build the firmware. Also since these instructions now cover more boards, rename the file to README.sunxi64 to reflect this.
--- board/sunxi/README.pine64 | 98 --------------------------- board/sunxi/README.sunxi64 | 165 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 165 insertions(+), 98 deletions(-) delete mode 100644 board/sunxi/README.pine64 create mode 100644 board/sunxi/README.sunxi64
board/sunxi/README.pine64 deleted +0 -98
@@ -1,98 +0,0 @@ -Pine64 board README -==================== - -The Pine64(+) is a single board computer equipped with an AArch64 capable ARMv8 -compliant Allwinner A64 SoC. -This chip has ARM Cortex A-53 cores and thus can run both in AArch32 -(compatible to 32-bit ARMv7) and AArch64 modes. Upon reset the SoC starts -in AArch32 mode and executes 32-bit code from the Boot ROM (BROM). -This has some implications on U-Boot. - -Quick start -============ -- Get hold of a boot0.img file (see below for more details). -- Get the boot0img tool source from the tools directory in [1] and compile - that on your host. -- Build U-Boot: -$ export CROSS_COMPILE=aarch64-linux-gnu- -$ make pine64_plus_defconfig -$ make -- You also need a compiled ARM Trusted Firmware (ATF) binary. Checkout the - "allwinner" branch from the github repository [2] and build it: -$ export CROSS_COMPILE=aarch64-linux-gnu- -$ make PLAT=sun50iw1p1 DEBUG=1 bl31 - The resulting binary is build/sun50iw1p1/debug/bl31.bin. - -Now put an empty (or disposable) micro SD card in your card reader and learn -its device file name, replacing /dev/sd<x> below with the result (that could -be /dev/mmcblk<x> as well): - -$ ./boot0img --device /dev/sd<x> -e -u u-boot.bin -B boot0.img \ - -d trampoline64:0x44000 -s bl31.bin -a 0x44008 -p 100 -(either copying the respective files to the working directory or specifying -the paths directly) - -This will create a new partition table (with a 100 MB FAT boot partition), -copies boot0.img, ATF and U-Boot to the proper locations on the SD card and -will fill in the magic Allwinner header to be recognized by boot0. -Prefix the above call with "sudo" if you don't have write access to the -uSD card. You can also use "-o output.img" instead of "--device /dev/sd<x>" -to create an image file and "dd" that to the uSD card. -Omitting the "-p" option will skip the partition table. - -Now put this uSD card in the board and power it on. You should be greeted by -the U-Boot prompt. - - -Main U-Boot -============ -The main U-Boot proper is a real 64-bit ARMv8 port and runs entirely in the -64-bit AArch64 mode. It can load any AArch64 code, EFI applications or arm64 -Linux kernel images (often named "Image") using the booti command. -Launching 32-bit code and kernels is technically possible, though not without -drawbacks (or hacks to avoid them) and currently not implemented. - -SPL support -============ -The main task of the SPL support is to bring up the DRAM controller and make -DRAM actually accessible. At the moment there is no documentation or source -code available which would do this. -There are currently two ways to overcome this situation: using a tainted 32-bit -SPL (involving some hacks and resulting in a non-redistributable binary, thus -not described here) or using the Allwinner boot0 blob. - -boot0 method -------------- -boot0 is Allwiner's secondary program loader and it can be used as some kind -of SPL replacement to get U-Boot up and running. -The binary is a 32 KByte blob and contained on every Pine64 image distributed -so far. It can be easily extracted from a micro SD card or an image file: -# dd if=/dev/sd<x> of=boot0.bin bs=8k skip=1 count=4 -where /dev/sd<x> is the device name of the uSD card or the name of the image -file. Apparently Allwinner allows re-distribution of this proprietary code -as-is. -For the time being this boot0 blob is the only redistributable way of making -U-Boot work on the Pine64. Beside loading the various parts of the (original) -firmware it also switches the core into AArch64 mode. -The original boot0 code looks for U-Boot at a certain place on an uSD card -(at 19096 KB), also it expects a header with magic bytes and a checksum. -There is a tool called boot0img[1] which takes a boot0.bin image and a compiled -U-Boot binary (plus other binaries) and will populate that header accordingly. -To make space for the magic header, the pine64_plus_defconfig will make sure -there is sufficient space at the beginning of the U-Boot binary. -boot0img will also take care of putting the different binaries at the right -places on the uSD card and works around unused, but mandatory parts by using -trampoline code. See the output of "boot0img -h" for more information. -boot0img can also patch boot0 to avoid loading U-Boot from 19MB, instead -fetching it from just behind the boot0 binary (-B option). - -FEL boot -========= -FEL is the name of the Allwinner defined USB boot protocol built-in the -mask ROM of most Allwinner SoCs. It allows to bootstrap a board solely -by using the USB-OTG interface and a host port on another computer. -Since FEL boot does not work with boot0, it requires the libdram hack, which -is not described here. - -[1] https://github.com/apritzel/pine64/ -[2] https://github.com/apritzel/arm-trusted-firmware.git
board/sunxi/README.sunxi64 new file +165 -0
165 lines not on this page · raw message
Signature · 1 line
2.8.2
PATCH v4 20/20 sunxi: Move maintainership for Pine64
In reply to Andre PrzywaraAfter speaking to Hans at FOSDEM, he is fine with transferring the maintainership of the Pine64 boards over to me.
--- board/sunxi/MAINTAINERS | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
board/sunxi/MAINTAINERS +5 -1
@@ -72,7 +72,6 @@ F: configs/q8_a33_tablet_1024x600_defconfig F: include/configs/sun9i.h F: configs/Merrii_A80_Optimus_defconfig F: include/configs/sun50i.h -F: configs/pine64_plus_defconfig A20-OLIMEX-SOM-EVB BOARD M: Marcus Cooper <[email protected]>
@@ -263,6 +262,11 @@ M: Andre Przywara <[email protected]> S: Maintained F: configs/orangepi_pc2_defconfig +PINE64 BOARDS +M: Andre Przywara <[email protected]> +S: Maintained +F: configs/pine64_plus_defconfig + R16 EVB PARROT BOARD M: Quentin Schulz <[email protected]> S: Maintained
Signature · 1 line
2.8.2
v4 cover SPL: extend FIT loading support
In reply to Andre PrzywaraI though I have add review and test tags for the first 5 patches, anyway,
I will add again.
Not sure if some patches for sunxi still need to wait, can we merge patches
for SPL/FIT first?
Thanks,
- Kever
Quoted 147 lines · Andre Przywara
Another round of smaller fixes for the SPL FIT loading series and the respective patches to enable this feature on 64-bit Allwinner SoCs. The README has been changed to address all 64-bit Allwinner boards and has consequently been renamed to README.sunxi64. Also we can now point U-Boot to the ARM Trusted Firmware build by specifying the filename in the BL31 environment variable. If this is not set, we default to look for bl31.bin in U-Boot's build directory.
The other minor fixes are detailed in the Changelog below.
---The first five patches introduce the core of the extened SPL FIT loading support, see below for a description. Patch 6 fixes a
Kconfigdependency to simplify the usage of this option.
Patches 7-10 make some room in the sunxi 64-bit SPL to allow compiling in the FIT loading bits. Patch 11 and 12 let the SPL choose the proper DT from the FIT image.
The next two patches add the infrastructure and an actual generator script, so the FIT image is automatically created at build time.
Patches 14, 15 and 16 enable the SPL FIT support for Allwinner 64-bit SoCs in general and for the Pine64 and OrangePi PC 2 in particular.
The following two patches store a DT file name in the SPL header, so U-Boot can easily pick the proper DT when scanning the FIT image. The idea is that this DT name should stay with the board, ideally on eMMC or SPI flash. So both U-Boot and a firmware update tool could identify a board, updating with compatible firmware while keeping the DT name in place. Ideally a board vendor would once seed this name onto on-board storage like SPI flash.
I kept those two patches in, as the work on replacing mksunxiboot with an mkimage extension is not ready yet. Feel free to drop those from the series if this is a problem.
The penultimate patch updates the Pine64 README file to document the current way of building U-Boot, which now includes the ARM Trusted Firmware build in its image.
The last patch moves the maintainership from Hans over to me.I would be delighted if that series could get merged into the sunxi tree. This finally enables the fully open source firmware for the 64-bit Allwinner SoCs (including the ATF binary).
This series is based on current sunxi/master.
Cheers,
Andre.-------
Currently the FIT format is not used to its full potential in the SPL:
It only loads the first image from the /images node and appends the proper FDT.
Some boards and platforms would benefit from loading more images before starting U-Boot proper, notably Allwinner A64 and ARMv8 Rockchip boards, which use an ARM Trusted Firmware (ATF) image to be executed before U-Boot.This series tries to solve this in a board agnostic and generic way:
We extend the SPL FIT loading scheme to allow loading multiple images. So apart from loading the image which is referenced by the "firmware" property in the respective configuration node and placing the DTB right behind it, we iterate over all strings in the "loadable" property. Each image referenced there will be loaded to its specified load address. The entry point U-Boot eventually branches to will be taken from the first image to explicitly provide the "entry" property, or, if none of them does so, from the load address of the "firmware" image. This keeps the scheme compatible with the FIT images ourMakefilecreates automatically at the moment.
Apart from the already mentioned ATF scenario this opens up more usage scenarios, of which the commit message of patch 04/11 lists some. The remaining patches prepare ane finally enable this scheme for the 64-bit Allwinner boards.Changelog v3 ... v4:
- [01/20]: return proper error codes instead of just -1 (+Simon's RB)
- [02/20]: improve kernel-doc comment (+Simon's RB)
- [03/20]: return proper error codes instead of just -1 (+Simon's RB)
- [04/20]: improve kernel-doc comment and error codes (+Simon's RB)
- [05/20]: add example .its source file (+Simon's RB)
- [10,11,12/20]: add Maxime's Acked-by
- [14/20]: add BL31 environment variable (+Maxime's Acked-by)
- [15/20]: drop unneeded OrangePi PC2 change
- [16/20]: add Maxime's Acked-by
- [19/20]: rewrite to be more generic, rename to README.sunxi64
- [20/20]: new patch to change maintainershipChangelog v2 ... v3:
- new patch 06/19 to improveSPL_FITKconfigdependencies
- rename symbol in mksunxiboot (SUNXI_SRAMinstead ofSUN4I_SRAM)
- enableSPL_LOAD_FITfor all Allwinner A64 and H5 boards inKconfig
- add onlyCONFIG_OF_LISTto defconfigs (patch 15/19)Changelog v1 ... v2:
- Add some function comments tospl_fit.c(patch 1-5)
- Improve error handling in SPL FIT code (patch 1-5)
- Fix bisectability (observing entry-point property)
- add documentation todoc/uImage.FIT/howto.txt
- fix Freescale CCN504 build failure
- (no changes in the last 10 patches)
- update README.pine64 (new last patch)
- add Reviewed-by's from Simon and Lokesh--
Andre Przywara (19):
SPL: FIT: refactor FDT loading
SPL: FIT: rework U-Boot image loading
SPL: FIT: improve error handling
SPL: FIT: factor outspl_load_fit_image()
SPL: FIT: allow loading multiple images
Kconfig: fixSPL_FITdependency
tools: mksunxiboot: allow larger SPL binaries
armv8: SPL: only compile GIC code if needed
armv8: fsl: move ccn504 code into FSLMakefile
sunxi: A64: move SPL stack to end of SRAM A2
sunxi: SPL: store RAM size in gd
sunxi: SPL: add FIT config selector for Pine64 boards
Makefile: add rules to generate SPL FIT images
sunxi: 64-bit SoCs: introduce FIT generator script
sunxi: defconfig: add supported DT list for Pine64
sunxi: enable automatic FIT build for 64-bit SoCs
sunxi: use SPL header DT name for FIT board matching
sunxi: update Pine64 README
sunxi: Move maintainership for Pine64Siarhei Siamashka (1):
sunxi: Store the device tree name in the SPL headerKconfig | 22 ++- Makefile | 20 +++ arch/arm/include/asm/arch-sunxi/spl.h | 19 ++- arch/arm/lib/Makefile | 4 +- board/sunxi/Kconfig | 4 + board/sunxi/MAINTAINERS | 6 +- board/sunxi/README.pine64 | 98 ----------- board/sunxi/README.sunxi64 | 165 +++++++++++++++++++ board/sunxi/board.c | 36 +++- board/sunxi/mksunxi_fit_atf.sh | 75 +++++++++ common/spl/spl_fit.c | 301 ++++++++++++++++++++++------------ configs/am335x_evm_defconfig | 1 - configs/evb-rk3399_defconfig | 1 - configs/pine64_plus_defconfig | 1 + doc/uImage.FIT/howto.txt | 21 +++ doc/uImage.FIT/multi_spl.its | 89 ++++++++++ include/configs/sunxi-common.h | 17 +- scripts/Makefile.spl | 3 +- tools/mksunxiboot.c | 53 +++++- 19 files changed, 710 insertions(+), 226 deletions(-)delete mode 100644 board/sunxi/README.pine64 create mode 100644 board/sunxi/README.sunxi64 create mode 100755
board/sunxi/mksunxi_fit_atf.shcreate mode 100644 doc/uImage.FIT/multi_spl.its
v4 cover SPL: extend FIT loading support
Hi,
Quoted 1 line · Kever Yang
I though I have add review and test tags for the first 5 patches, anyway,
Sorry, I must have missed that. Thanks for the review and testing!
Quoted 5 lines
I will add again.
Not sure if some patches for sunxi still need to wait, can we merge patches for SPL/FIT first?
That is a good question.
Tom, Simon: Are you OK with these (first six) patches? Are we good to merge them? Who will take them?
I see that "spl: add support to booting with ATF" from Kever has been merged already, my understanding is that this series here is a prerequisite for this?
Shall I repost the first six patches separately, rebased and with the new tags added?
Cheers,
Andre.
Quoted 158 lines
Thanks,
- KeverQuoted 153 lines · Andre Przywara
Another round of smaller fixes for the SPL FIT loading series and the respective patches to enable this feature on 64-bit Allwinner SoCs. The README has been changed to address all 64-bit Allwinner boards and has consequently been renamed to README.sunxi64. Also we can now point U-Boot to the ARM Trusted Firmware build by specifying the filename in the BL31 environment variable. If this is not set, we default to look for bl31.bin in U-Boot's build directory.
The other minor fixes are detailed in the Changelog below.
---The first five patches introduce the core of the extened SPL FIT loading support, see below for a description. Patch 6 fixes a
Kconfigdependency to simplify the usage of this option.
Patches 7-10 make some room in the sunxi 64-bit SPL to allow compiling in the FIT loading bits. Patch 11 and 12 let the SPL choose the proper DT from the FIT image.
The next two patches add the infrastructure and an actual generator script,
so the FIT image is automatically created at build time. Patches 14, 15 and 16 enable the SPL FIT support for Allwinner 64-bit SoCs in
general and for the Pine64 and OrangePi PC 2 in particular. The following two patches store a DT file name in the SPL header, so U-Boot can easily pick the proper DT when scanning the FIT image. The idea is that this DT name should stay with the board, ideally on eMMC or SPI flash. So both U-Boot and a firmware update tool could identify a board, updating with compatible firmware while keeping the DT name in place. Ideally a board vendor would once seed this name onto on-board storage like SPI flash.
I kept those two patches in, as the work on replacing mksunxiboot with an mkimage extension is not ready yet. Feel free to drop those from the series if this is a problem.
The penultimate patch updates the Pine64 README file to document the current
way of building U-Boot, which now includes the ARM Trusted Firmware build in its image.
The last patch moves the maintainership from Hans over to me.I would be delighted if that series could get merged into the sunxi tree. This finally enables the fully open source firmware for the 64-bit Allwinner SoCs (including the ATF binary).
This series is based on current sunxi/master.
Cheers,
Andre.-------
Currently the FIT format is not used to its full potential in the SPL:
It only loads the first image from the /images node and appends the proper FDT.
Some boards and platforms would benefit from loading more images before starting U-Boot proper, notably Allwinner A64 and ARMv8 Rockchip boards, which use an ARM Trusted Firmware (ATF) image to be executed before U-Boot.This series tries to solve this in a board agnostic and generic way:
We extend the SPL FIT loading scheme to allow loading multiple images. So apart from loading the image which is referenced by the "firmware" property in the respective configuration node and placing the DTB right behind it, we iterate over all strings in the "loadable" property. Each image referenced there will be loaded to its specified load address. The entry point U-Boot eventually branches to will be taken from the first image to explicitly provide the "entry" property, or, if none of them does so, from the load address of the "firmware" image. This keeps the scheme compatible with the FIT images ourMakefilecreates automatically at the moment.
Apart from the already mentioned ATF scenario this opens up more usage scenarios, of which the commit message of patch 04/11 lists some. The remaining patches prepare ane finally enable this scheme for the 64-bit
Allwinner boards.Changelog v3 ... v4:
- [01/20]: return proper error codes instead of just -1 (+Simon's RB)
- [02/20]: improve kernel-doc comment (+Simon's RB)
- [03/20]: return proper error codes instead of just -1 (+Simon's RB)
- [04/20]: improve kernel-doc comment and error codes (+Simon's RB)
- [05/20]: add example .its source file (+Simon's RB)
- [10,11,12/20]: add Maxime's Acked-by
- [14/20]: add BL31 environment variable (+Maxime's Acked-by)
- [15/20]: drop unneeded OrangePi PC2 change
- [16/20]: add Maxime's Acked-by
- [19/20]: rewrite to be more generic, rename to README.sunxi64
- [20/20]: new patch to change maintainershipChangelog v2 ... v3:
- new patch 06/19 to improveSPL_FITKconfigdependencies
- rename symbol in mksunxiboot (SUNXI_SRAMinstead ofSUN4I_SRAM)
- enableSPL_LOAD_FITfor all Allwinner A64 and H5 boards inKconfig
- add onlyCONFIG_OF_LISTto defconfigs (patch 15/19)Changelog v1 ... v2:
- Add some function comments tospl_fit.c(patch 1-5)
- Improve error handling in SPL FIT code (patch 1-5)
- Fix bisectability (observing entry-point property)
- add documentation todoc/uImage.FIT/howto.txt
- fix Freescale CCN504 build failure
- (no changes in the last 10 patches)
- update README.pine64 (new last patch)
- add Reviewed-by's from Simon and LokeshSignature · 49 lines
Andre Przywara (19): SPL: FIT: refactor FDT loading SPL: FIT: rework U-Boot image loading SPL: FIT: improve error handling SPL: FIT: factor out spl_load_fit_image() SPL: FIT: allow loading multiple images Kconfig: fix SPL_FIT dependency tools: mksunxiboot: allow larger SPL binaries armv8: SPL: only compile GIC code if needed armv8: fsl: move ccn504 code into FSL Makefile sunxi: A64: move SPL stack to end of SRAM A2 sunxi: SPL: store RAM size in gd sunxi: SPL: add FIT config selector for Pine64 boards Makefile: add rules to generate SPL FIT images sunxi: 64-bit SoCs: introduce FIT generator script sunxi: defconfig: add supported DT list for Pine64 sunxi: enable automatic FIT build for 64-bit SoCs sunxi: use SPL header DT name for FIT board matching sunxi: update Pine64 README sunxi: Move maintainership for Pine64 Siarhei Siamashka (1): sunxi: Store the device tree name in the SPL header Kconfig | 22 ++- Makefile | 20 +++ arch/arm/include/asm/arch-sunxi/spl.h | 19 ++- arch/arm/lib/Makefile | 4 +- board/sunxi/Kconfig | 4 + board/sunxi/MAINTAINERS | 6 +- board/sunxi/README.pine64 | 98 ----------- board/sunxi/README.sunxi64 | 165 +++++++++++++++++++ board/sunxi/board.c | 36 +++- board/sunxi/mksunxi_fit_atf.sh | 75 +++++++++ common/spl/spl_fit.c | 301 ++++++++++++++++++++++------------ configs/am335x_evm_defconfig | 1 - configs/evb-rk3399_defconfig | 1 - configs/pine64_plus_defconfig | 1 + doc/uImage.FIT/howto.txt | 21 +++ doc/uImage.FIT/multi_spl.its | 89 ++++++++++ include/configs/sunxi-common.h | 17 +- scripts/Makefile.spl | 3 +- tools/mksunxiboot.c | 53 +++++- 19 files changed, 710 insertions(+), 226 deletions(-) delete mode 100644 board/sunxi/README.pine64 create mode 100644 board/sunxi/README.sunxi64 create mode 100755 board/sunxi/mksunxi_fit_atf.sh create mode 100644 doc/uImage.FIT/multi_spl.its
v4 cover SPL: extend FIT loading support
Quoted 14 lines
From: Andre Przywara <[email protected]>
Date: Tue, 16 May 2017 09:10:06 +0100Hi,
Quoted 2 lines · Kever Yang
Not sure if some patches for sunxi still need to wait, can we merge patches for SPL/FIT first?
That is a good question.
Tom, Simon: Are you OK with these (first six) patches? Are we good to merge them? Who will take them?
Quoted 6 lines
I see that "spl: add support to booting with ATF" from Kever has been merged already, my understanding is that this series here is a prerequisite for this?
Shall I repost the first six patches separately, rebased and with the new tags added?
It'd be great if this would happen. It'll allow us (OpenBSD) to distribute a working "firmware" image for the Firefly-RK3399 and bring the number of patches that we need to juggle for the Pine64 and other Allwinner A64/H5 boards down to a more manageable level.
I myself tested these patches on the Firefly-RK3399, so feel free to add a
Cheers,
Mark
v4 cover SPL: extend FIT loading support
Hi,
Quoted 6 lines · Mark Kettenis
Quoted 6 lines
From: Andre Przywara <[email protected]>
Date: Tue, 16 May 2017 09:10:06 +0100Hi,
Quoted 8 lines
Quoted 8 lines · Kever Yang
Quoted 2 lines
Not sure if some patches for sunxi still need to wait, can we merge patches for SPL/FIT first?
That is a good question.
Tom, Simon: Are you OK with these (first six) patches? Are we good to merge them? Who will take them?
It looks like it is assigned to Jagan in patchwork so I expect he will pick them up soon.
Quoted 13 lines
Quoted 7 lines
I see that "spl: add support to booting with ATF" from Kever has been merged already, my understanding is that this series here is a prerequisite for this?
Shall I repost the first six patches separately, rebased and with the new tags added?
It'd be great if this would happen. It'll allow us (OpenBSD) to distribute a working "firmware" image for the Firefly-RK3399 and bring the number of patches that we need to juggle for the Pine64 and other Allwinner A64/H5 boards down to a more manageable level.
Quoted 8 lines
I myself tested these patches on the Firefly-RK3399, so feel free to add a
Tested-by Mark Kettenis <[email protected]>Cheers,
Mark
Regards,
Simon
v4 cover SPL: extend FIT loading support
In reply to Andre PrzywaraQuoted 97 lines · Andre Przywara
Another round of smaller fixes for the SPL FIT loading series and the respective patches to enable this feature on 64-bit Allwinner SoCs. The README has been changed to address all 64-bit Allwinner boards and has consequently been renamed to README.sunxi64. Also we can now point U-Boot to the ARM Trusted Firmware build by specifying the filename in the BL31 environment variable. If this is not set, we default to look for bl31.bin in U-Boot's build directory.
The other minor fixes are detailed in the Changelog below.
---The first five patches introduce the core of the extened SPL FIT loading support, see below for a description. Patch 6 fixes a
Kconfigdependency to simplify the usage of this option.
Patches 7-10 make some room in the sunxi 64-bit SPL to allow compiling in the FIT loading bits. Patch 11 and 12 let the SPL choose the proper DT from the FIT image.
The next two patches add the infrastructure and an actual generator script, so the FIT image is automatically created at build time.
Patches 14, 15 and 16 enable the SPL FIT support for Allwinner 64-bit SoCs in general and for the Pine64 and OrangePi PC 2 in particular.
The following two patches store a DT file name in the SPL header, so U-Boot can easily pick the proper DT when scanning the FIT image. The idea is that this DT name should stay with the board, ideally on eMMC or SPI flash. So both U-Boot and a firmware update tool could identify a board, updating with compatible firmware while keeping the DT name in place. Ideally a board vendor would once seed this name onto on-board storage like SPI flash.
I kept those two patches in, as the work on replacing mksunxiboot with an mkimage extension is not ready yet. Feel free to drop those from the series if this is a problem.
The penultimate patch updates the Pine64 README file to document the current way of building U-Boot, which now includes the ARM Trusted Firmware build in its image.
The last patch moves the maintainership from Hans over to me.I would be delighted if that series could get merged into the sunxi tree. This finally enables the fully open source firmware for the 64-bit Allwinner SoCs (including the ATF binary).
This series is based on current sunxi/master.
Cheers,
Andre.-------
Currently the FIT format is not used to its full potential in the SPL:
It only loads the first image from the /images node and appends the proper FDT.
Some boards and platforms would benefit from loading more images before starting U-Boot proper, notably Allwinner A64 and ARMv8 Rockchip boards, which use an ARM Trusted Firmware (ATF) image to be executed before U-Boot.This series tries to solve this in a board agnostic and generic way:
We extend the SPL FIT loading scheme to allow loading multiple images. So apart from loading the image which is referenced by the "firmware" property in the respective configuration node and placing the DTB right behind it, we iterate over all strings in the "loadable" property. Each image referenced there will be loaded to its specified load address. The entry point U-Boot eventually branches to will be taken from the first image to explicitly provide the "entry" property, or, if none of them does so, from the load address of the "firmware" image. This keeps the scheme compatible with the FIT images ourMakefilecreates automatically at the moment.
Apart from the already mentioned ATF scenario this opens up more usage scenarios, of which the commit message of patch 04/11 lists some. The remaining patches prepare ane finally enable this scheme for the 64-bit Allwinner boards.Changelog v3 ... v4:
- [01/20]: return proper error codes instead of just -1 (+Simon's RB)
- [02/20]: improve kernel-doc comment (+Simon's RB)
- [03/20]: return proper error codes instead of just -1 (+Simon's RB)
- [04/20]: improve kernel-doc comment and error codes (+Simon's RB)
- [05/20]: add example .its source file (+Simon's RB)
- [10,11,12/20]: add Maxime's Acked-by
- [14/20]: add BL31 environment variable (+Maxime's Acked-by)
- [15/20]: drop unneeded OrangePi PC2 change
- [16/20]: add Maxime's Acked-by
- [19/20]: rewrite to be more generic, rename to README.sunxi64
- [20/20]: new patch to change maintainershipChangelog v2 ... v3:
- new patch 06/19 to improveSPL_FITKconfigdependencies
- rename symbol in mksunxiboot (SUNXI_SRAMinstead ofSUN4I_SRAM)
- enableSPL_LOAD_FITfor all Allwinner A64 and H5 boards inKconfig
- add onlyCONFIG_OF_LISTto defconfigs (patch 15/19)Changelog v1 ... v2:
- Add some function comments tospl_fit.c(patch 1-5)
- Improve error handling in SPL FIT code (patch 1-5)
- Fix bisectability (observing entry-point property)
- add documentation todoc/uImage.FIT/howto.txt
- fix Freescale CCN504 build failure
- (no changes in the last 10 patches)
- update README.pine64 (new last patch)
- add Reviewed-by's from Simon and Lokesh
Quoted 8 lines
--
Andre Przywara (19):
SPL: FIT: refactor FDT loading
SPL: FIT: rework U-Boot image loading
SPL: FIT: improve error handling
SPL: FIT: factor outspl_load_fit_image()
SPL: FIT: allow loading multiple images
Kconfig: fixSPL_FITdependency
Remove change from configs/evb-rk3399_defconfig
Quoted 10 lines
tools: mksunxiboot: allow larger SPL binaries
armv8: SPL: only compile GIC code if needed
armv8: fsl: move ccn504 code into FSLMakefile
sunxi: A64: move SPL stack to end of SRAM A2
sunxi: SPL: store RAM size in gd
sunxi: SPL: add FIT config selector for Pine64 boards
Makefile: add rules to generate SPL FIT images
sunxi: 64-bit SoCs: introduce FIT generator script
sunxi: defconfig: add supported DT list for Pine64
sunxi: enable automatic FIT build for 64-bit SoCs
Update Kconfig path to arch/arm/mach-sunxi/ while applying.
Quoted 6 lines
sunxi: use SPL header DT name for FIT board matching
sunxi: update Pine64 README
sunxi: Move maintainership for Pine64Siarhei Siamashka (1):
sunxi: Store the device tree name in the SPL header
Series tested on pine64 board.
Applied to u-boot-sunxi/master
thanks!
Signature · 4 lines
Jagan Teki Free Software Engineer | www.openedev.com U-Boot, Linux | Upstream Maintainer Hyderabad, India.