[PATCH 54/67] upl: Use a reg property to specify the FIT address and size
Simon Glass
sjg at chromium.org
Wed Jan 1 23:09:40 CET 2025
The spec has changed to use a unit address and reg property for this
value. Update the implementation to match. It is now possible to obtain
the size of the FIT as well as its address.
Add #address/size-cells properties as well.
Signed-off-by: Simon Glass <sjg at chromium.org>
---
boot/upl_read.c | 12 +++++++++---
boot/upl_write.c | 25 +++++++++++++++++++++----
cmd/upl.c | 2 +-
common/spl/spl_upl.c | 4 ++--
include/upl.h | 4 ++--
test/boot/upl.c | 10 ++++++----
6 files changed, 41 insertions(+), 16 deletions(-)
diff --git a/boot/upl_read.c b/boot/upl_read.c
index 1b6290ffb1c..8fcc5a77c15 100644
--- a/boot/upl_read.c
+++ b/boot/upl_read.c
@@ -310,6 +310,8 @@ static int decode_upl_params(struct upl *upl, ofnode options)
static int decode_upl_images(struct upl *upl, ofnode options)
{
ofnode node, images;
+ const char *buf;
+ int size;
int ret;
images = ofnode_find_subnode(options, UPLN_UPL_IMAGES);
@@ -317,9 +319,13 @@ static int decode_upl_images(struct upl *upl, ofnode options)
return log_msg_ret("img", -EINVAL);
log_debug("decoding '%s'\n", ofnode_get_name(images));
- ret = read_addr(upl, images, UPLP_FIT, &upl->fit);
- if (!ret)
- ret = read_uint(images, UPLP_CONF_OFFSET, &upl->conf_offset);
+ buf = ofnode_read_prop(images, UPLP_REG, &size);
+ if (buf) {
+ ret = decode_addr_size(upl, buf, size, &upl->fit);
+ if (ret < 0)
+ return log_msg_ret("uft", ret);
+ }
+ ret = read_uint(images, UPLP_CONF_OFFSET, &upl->conf_offset);
if (ret)
return log_msg_ret("cnf", ret);
diff --git a/boot/upl_write.c b/boot/upl_write.c
index 9702ef91930..32c68308149 100644
--- a/boot/upl_write.c
+++ b/boot/upl_write.c
@@ -244,6 +244,9 @@ static int add_upl_params(const struct upl *upl, ofnode options)
ofnode node;
int ret;
+ ret = add_addr_size_cells(options, upl->addr_cells, upl->size_cells);
+ if (ret)
+ return log_msg_ret("upa", ret);
ret = ofnode_add_subnode(options, UPLN_UPL_PARAMS, &node);
if (ret)
return log_msg_ret("img", ret);
@@ -276,21 +279,35 @@ static int add_upl_params(const struct upl *upl, ofnode options)
*/
static int add_upl_images(const struct upl *upl, ofnode options)
{
+ char name[40];
ofnode node;
int ret, i;
- ret = ofnode_add_subnode(options, UPLN_UPL_IMAGES, &node);
+ snprintf(name, sizeof(name), UPLN_UPL_IMAGES "@%llx", upl->fit.base);
+ ret = ofnode_add_subnode(options, name, &node);
if (ret)
return log_msg_ret("img", ret);
- if (upl->fit)
- ret = ofnode_write_u32(node, UPLP_FIT, upl->fit);
- if (!ret && upl->conf_offset)
+ if (upl->fit.base) {
+ char buf[4 * sizeof(u64)];
+
+ ret = encode_addr_size(upl, buf, sizeof(buf), &upl->fit);
+ if (ret < 0)
+ return log_msg_ret("uft", ret);
+ ret = ofnode_write_prop(node, UPLP_REG, buf, ret, true);
+ if (ret)
+ return log_msg_ret("ufw", ret);
+ }
+ if (upl->conf_offset)
ret = ofnode_write_u32(node, UPLP_CONF_OFFSET,
upl->conf_offset);
if (ret)
return log_msg_ret("cnf", ret);
+ ret = add_addr_size_cells(node, upl->addr_cells, upl->size_cells);
+ if (ret)
+ return log_msg_ret("upi", ret);
+
for (i = 0; i < upl->image.count; i++) {
const struct upl_image *img = alist_get(&upl->image, i,
struct upl_image);
diff --git a/cmd/upl.c b/cmd/upl.c
index d8d46cdf34f..676e8f1f9e2 100644
--- a/cmd/upl.c
+++ b/cmd/upl.c
@@ -31,7 +31,7 @@ static int do_upl_info(struct cmd_tbl *cmdtp, int flag, int argc,
if (argc > 1 && !strcmp("-v", argv[1])) {
int i;
- printf("fit %lx\n", upl->fit);
+ printf("fit %llx size %lx\n", upl->fit.base, upl->fit.size);
printf("conf_offset %x\n", upl->conf_offset);
for (i = 0; i < upl->image.count; i++) {
const struct upl_image *img =
diff --git a/common/spl/spl_upl.c b/common/spl/spl_upl.c
index 2bc0e265661..5777148bbe4 100644
--- a/common/spl/spl_upl.c
+++ b/common/spl/spl_upl.c
@@ -21,14 +21,14 @@ void upl_set_fit_addr(ulong fit)
{
struct upl *upl = &s_upl;
- upl->fit = fit;
+ upl->fit.base = fit;
}
void upl_set_fit_info(ulong fit, int conf_offset, ulong entry_addr)
{
struct upl *upl = &s_upl;
- upl->fit = fit;
+ upl->fit.base = fit;
upl->conf_offset = conf_offset;
log_debug("upl: add fit %lx conf %x\n", fit, conf_offset);
}
diff --git a/include/upl.h b/include/upl.h
index dd43e8e8529..cff3401a932 100644
--- a/include/upl.h
+++ b/include/upl.h
@@ -250,7 +250,7 @@ struct upl_graphics {
* @addr_cells: Number of address cells used in the handoff
* @size_cells: Number of size cells used in the handoff
* @bootmode: Boot-mode mask (enum upl_boot_mode)
- * @fit: Address of FIT image that was loaded
+ * @fit: Address and size of FIT image that was loaded
* @conf_offset: Offset in FIT of the configuration that was selected
* @addr_width: Adress-bus width of machine, e.g. 46 for 46 bits
* @acpi_nvs_size: Size of the ACPI non-volatile-storage area in bytes
@@ -266,7 +266,7 @@ struct upl {
ulong smbios;
ulong acpi;
uint bootmode;
- ulong fit;
+ struct memregion fit;
uint conf_offset;
uint addr_width;
uint acpi_nvs_size;
diff --git a/test/boot/upl.c b/test/boot/upl.c
index e1454ba3469..8e1a016943a 100644
--- a/test/boot/upl.c
+++ b/test/boot/upl.c
@@ -46,7 +46,8 @@ int upl_get_test_data(struct unit_test_state *uts, struct upl *upl)
upl->smbios = 0x123;
upl->acpi = 0x456;
upl->bootmode = BIT(UPLBM_DEFAULT) | BIT(UPLBM_S3);
- upl->fit = 0x789;
+ upl->fit.base = 0x789;
+ upl->fit.size = 0xabc;
upl->conf_offset = 0x234;
upl->addr_width = 46;
upl->acpi_nvs_size = 0x100;
@@ -294,7 +295,8 @@ static int compare_upl(struct unit_test_state *uts, struct upl *base,
ut_asserteq(base->smbios, cmp->smbios);
ut_asserteq(base->acpi, cmp->acpi);
ut_asserteq(base->bootmode, cmp->bootmode);
- ut_asserteq(base->fit, cmp->fit);
+ ut_asserteq(base->fit.base, cmp->fit.base);
+ ut_asserteq(base->fit.size, cmp->fit.size);
ut_asserteq(base->conf_offset, cmp->conf_offset);
ut_asserteq(base->addr_width, cmp->addr_width);
ut_asserteq(base->acpi_nvs_size, cmp->acpi_nvs_size);
@@ -411,14 +413,14 @@ static int upl_test_info_norun(struct unit_test_state *uts)
ut_assertok(run_command("upl info -v", 0));
ut_assert_nextline("UPL state: active");
- ut_assert_nextline("fit %lx", upl->fit);
+ ut_assert_nextline("fit %llx (size %lx)", upl->fit.base, upl->fit.size);
ut_assert_nextline("conf_offset %x", upl->conf_offset);
ut_assert_nextlinen("image 0");
ut_assert_nextlinen("image 1");
ut_assert_console_end();
/* check the offsets */
- fit = map_sysmem(upl->fit, 0);
+ fit = map_sysmem(upl->fit.base, 0);
ut_asserteq_str("conf-1", fdt_get_name(fit, upl->conf_offset, NULL));
ut_asserteq(2, upl->image.count);
--
2.43.0
More information about the U-Boot
mailing list