spl: fit: implement recording of loadables into /fit-images
If a FDT was loaded (e.g. to append it to U-Boot image), we store it's address and record information for all loadables into this FDT. This allows us to easily keep track of images for multiple privilege levels (e.g. with ATF) or of firmware images preloaded into temporary locations (e.g. PMU firmware that may overlap the SPL stage). Signed-off-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com> Reviewed-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
9f45aeb937
commit
a616c783f2
@ -2,7 +2,7 @@
|
|||||||
* Copyright (C) 2016 Google, Inc
|
* Copyright (C) 2016 Google, Inc
|
||||||
* Written by Simon Glass <sjg@chromium.org>
|
* Written by Simon Glass <sjg@chromium.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: GPL-2.0+
|
* SPDX-License-Identifier: GPL-2.0+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
@ -16,22 +16,24 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* spl_fit_get_image_node(): By using the matching configuration subnode,
|
* spl_fit_get_image_name(): By using the matching configuration subnode,
|
||||||
* retrieve the name of an image, specified by a property name and an index
|
* retrieve the name of an image, specified by a property name and an index
|
||||||
* into that.
|
* into that.
|
||||||
* @fit: Pointer to the FDT blob.
|
* @fit: Pointer to the FDT blob.
|
||||||
* @images: Offset of the /images subnode.
|
* @images: Offset of the /images subnode.
|
||||||
* @type: Name of the property within the configuration subnode.
|
* @type: Name of the property within the configuration subnode.
|
||||||
* @index: Index into the list of strings in this property.
|
* @index: Index into the list of strings in this property.
|
||||||
|
* @outname: Name of the image
|
||||||
*
|
*
|
||||||
* Return: the node offset of the respective image node or a negative
|
* Return: 0 on success, or a negative error number
|
||||||
* error number.
|
|
||||||
*/
|
*/
|
||||||
static int spl_fit_get_image_node(const void *fit, int images,
|
static int spl_fit_get_image_name(const void *fit, int images,
|
||||||
const char *type, int index)
|
const char *type, int index,
|
||||||
|
char **outname)
|
||||||
{
|
{
|
||||||
const char *name, *str;
|
const char *name, *str;
|
||||||
int node, conf_node;
|
__maybe_unused int node;
|
||||||
|
int conf_node;
|
||||||
int len, i;
|
int len, i;
|
||||||
|
|
||||||
conf_node = fit_find_config_node(fit);
|
conf_node = fit_find_config_node(fit);
|
||||||
@ -63,7 +65,35 @@ static int spl_fit_get_image_node(const void *fit, int images,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*outname = (char *)str;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
char *str;
|
||||||
|
int err;
|
||||||
|
int node;
|
||||||
|
|
||||||
|
err = spl_fit_get_image_name(fit, images, type, index, &str);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
debug("%s: '%s'\n", type, str);
|
debug("%s: '%s'\n", type, str);
|
||||||
|
|
||||||
node = fdt_subnode_offset(fit, images, str);
|
node = fdt_subnode_offset(fit, images, str);
|
||||||
if (node < 0) {
|
if (node < 0) {
|
||||||
debug("cannot find image node '%s': %d\n", str, node);
|
debug("cannot find image node '%s': %d\n", str, node);
|
||||||
@ -116,15 +146,15 @@ static int get_aligned_image_size(struct spl_load_info *info, int data_size,
|
|||||||
* @info: points to information about the device to load data from
|
* @info: points to information about the device to load data from
|
||||||
* @sector: the start sector of the FIT image on the device
|
* @sector: the start sector of the FIT image on the device
|
||||||
* @fit: points to the flattened device tree blob describing the FIT
|
* @fit: points to the flattened device tree blob describing the FIT
|
||||||
* image
|
* image
|
||||||
* @base_offset: the beginning of the data area containing the actual
|
* @base_offset: the beginning of the data area containing the actual
|
||||||
* image data, relative to the beginning of the FIT
|
* image data, relative to the beginning of the FIT
|
||||||
* @node: offset of the DT node describing the image to load (relative
|
* @node: offset of the DT node describing the image to load (relative
|
||||||
* to @fit)
|
* to @fit)
|
||||||
* @image_info: will be filled with information about the loaded image
|
* @image_info: will be filled with information about the loaded image
|
||||||
* If the FIT node does not contain a "load" (address) property,
|
* If the FIT node does not contain a "load" (address) property,
|
||||||
* the image gets loaded to the address pointed to by the
|
* the image gets loaded to the address pointed to by the
|
||||||
* load_addr member in this struct.
|
* load_addr member in this struct.
|
||||||
*
|
*
|
||||||
* Return: 0 on success or a negative error number.
|
* Return: 0 on success or a negative error number.
|
||||||
*/
|
*/
|
||||||
@ -239,6 +269,35 @@ static int spl_fit_append_fdt(struct spl_image_info *spl_image,
|
|||||||
image_info.load_addr = spl_image->load_addr + spl_image->size;
|
image_info.load_addr = spl_image->load_addr + spl_image->size;
|
||||||
ret = spl_load_fit_image(info, sector, fit, base_offset, node,
|
ret = spl_load_fit_image(info, sector, fit, base_offset, node,
|
||||||
&image_info);
|
&image_info);
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
/* Make the load-address of the FDT available for the SPL framework */
|
||||||
|
spl_image->fdt_addr = (void *)image_info.load_addr;
|
||||||
|
/* Try to make space, so we can inject details on the loadables */
|
||||||
|
ret = fdt_shrink_to_minimum(spl_image->fdt_addr, 8192);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int spl_fit_record_loadable(const void *fit, int images, int index,
|
||||||
|
void *blob, struct spl_image_info *image)
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
int node, ret;
|
||||||
|
|
||||||
|
ret = spl_fit_get_image_name(fit, images, "loadables",
|
||||||
|
index, &name);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
node = spl_fit_get_image_node(fit, images, "loadables", index);
|
||||||
|
|
||||||
|
ret = fdt_record_loadable(blob, index, name, image->load_addr,
|
||||||
|
image->size, image->entry_point,
|
||||||
|
fdt_getprop(fit, node, "type", NULL),
|
||||||
|
fdt_getprop(fit, node, "os", NULL));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -364,9 +423,11 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,
|
|||||||
if (!fit_image_get_os(fit, node, &os_type))
|
if (!fit_image_get_os(fit, node, &os_type))
|
||||||
debug("Loadable is %s\n", genimg_get_os_name(os_type));
|
debug("Loadable is %s\n", genimg_get_os_name(os_type));
|
||||||
|
|
||||||
if (spl_image->os == IH_OS_U_BOOT)
|
if (os_type == IH_OS_U_BOOT) {
|
||||||
spl_fit_append_fdt(spl_image, info, sector,
|
spl_fit_append_fdt(&image_info, info, sector,
|
||||||
fit, images, base_offset);
|
fit, images, base_offset);
|
||||||
|
spl_image->fdt_addr = image_info.fdt_addr;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the "firmware" image did not provide an entry point,
|
* If the "firmware" image did not provide an entry point,
|
||||||
@ -375,6 +436,12 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,
|
|||||||
if (spl_image->entry_point == FDT_ERROR &&
|
if (spl_image->entry_point == FDT_ERROR &&
|
||||||
image_info.entry_point != FDT_ERROR)
|
image_info.entry_point != FDT_ERROR)
|
||||||
spl_image->entry_point = image_info.entry_point;
|
spl_image->entry_point = image_info.entry_point;
|
||||||
|
|
||||||
|
/* Record our loadables into the FDT */
|
||||||
|
if (spl_image->fdt_addr)
|
||||||
|
spl_fit_record_loadable(fit, images, index,
|
||||||
|
spl_image->fdt_addr,
|
||||||
|
&image_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user