Create a convenience function which can write a UPL handoff into an abuf and return it.
Signed-off-by: Simon Glass <s...@chromium.org> --- boot/upl_common.c | 48 ++++++++++++++++++++++++++++++++++++++++++++ boot/upl_write.c | 28 ++++++++++++++++++++++++++ common/spl/spl_upl.c | 26 ++++-------------------- include/upl.h | 23 +++++++++++++++++++++ 4 files changed, 103 insertions(+), 22 deletions(-) diff --git a/boot/upl_common.c b/boot/upl_common.c index 01301049341..b0246f72597 100644 --- a/boot/upl_common.c +++ b/boot/upl_common.c @@ -8,6 +8,7 @@ #define LOG_CATEGORY UCLASS_BOOTSTD +#include <cpu.h> #include <dm.h> #include <serial.h> #include <string.h> @@ -130,6 +131,53 @@ int upl_add_graphics(struct upl_graphics *gra, ulong *basep, ulong *sizep) return 0; } +int upl_create(struct upl *upl) +{ + ulong base, size; + int ret; + + /* hard-code this for now to keep Tianocore happy */ + upl->addr_cells = 2; + upl->size_cells = 1; + + upl->bootmode = 0; + log_debug("conf_offset %d\n", upl->conf_offset); + if (IS_ENABLED(CONFIG_X86)) + upl->addr_width = cpu_phys_address_size(); + + /* no reserved memory */ + + ret = upl_add_serial(&upl->serial); + if (ret && ret != -ENOENT) + return log_msg_ret("ser", ret); + ret = upl_add_graphics(&upl->graphics, &base, &size); + if (ret && ret != -ENOENT) + return log_msg_ret("gra", ret); + + return 0; +} + +int upl_write_to_buf(struct upl *upl, ofnode root, struct abuf *buf) +{ + int ret; + + ret = upl_create(upl); + if (ret) + return log_msg_ret("uwr", ret); + + log_debug("writing to root node %d\n", ofnode_to_offset(root)); + ret = upl_write_handoff(upl, root, true); + if (ret) + return log_msg_ret("wr", ret); + + ret = oftree_to_fdt(oftree_default(), buf); + if (ret) + return log_msg_ret("fdt", ret); + log_debug("FDT size %zx\n", abuf_size(buf)); + + return 0; +} + void upl_init(struct upl *upl) { memset(upl, '\0', sizeof(struct upl)); diff --git a/boot/upl_write.c b/boot/upl_write.c index 60548937090..c53fa5396e8 100644 --- a/boot/upl_write.c +++ b/boot/upl_write.c @@ -625,3 +625,31 @@ int upl_create_handoff_tree(const struct upl *upl, oftree *treep) return 0; } + +int upl_create_handoff(struct upl *upl, ulong addr, struct abuf *buf) +{ + oftree tree; + int ret; + + ret = upl_create(upl); + if (ret) { + log_debug("Failed to create handoff (err=%dE)\n", ret); + return log_msg_ret("cho", ret); + } + log_debug("2a images %d\n", upl->image.count); + + ret = oftree_new(&tree); + if (ret) + return log_msg_ret("new", ret); + + ret = upl_write_handoff(upl, oftree_root(tree), true); + if (ret) + return log_msg_ret("wr", ret); + + ret = oftree_to_fdt(tree, buf); + if (ret) + return log_msg_ret("fdt", ret); + oftree_dispose(tree); + + return 0; +} diff --git a/common/spl/spl_upl.c b/common/spl/spl_upl.c index a78ae75e56c..2bc0e265661 100644 --- a/common/spl/spl_upl.c +++ b/common/spl/spl_upl.c @@ -15,8 +15,6 @@ #include <spl.h> #include <upl.h> -DECLARE_GLOBAL_DATA_PTR; - struct upl s_upl; void upl_set_fit_addr(ulong fit) @@ -53,38 +51,22 @@ int _upl_add_image(int node, ulong load_addr, ulong size, const char *desc) int spl_write_upl_handoff(void) { - struct upl *upl = &s_upl; - ulong addr, size; + struct upl s_upl, *upl = &s_upl; struct abuf buf; - ofnode root; void *ptr; int ret; log_debug("UPL: Writing handoff - image_count=%d\n", upl->image.count); - upl->addr_cells = IS_ENABLED(CONFIG_PHYS_64BIT) ? 2 : 1; - upl->size_cells = IS_ENABLED(CONFIG_PHYS_64BIT) ? 2 : 1; - upl->bootmode = UPLBM_DEFAULT; - ret = upl_add_serial(&upl->serial); - if (ret) - return log_msg_ret("ser", ret); - ret = upl_add_graphics(&upl->graphics, &addr, &size); - if (ret && ret != -ENOENT) - return log_msg_ret("gra", ret); - - root = ofnode_root(); - ret = upl_write_handoff(upl, root, true); - if (ret) - return log_msg_ret("wr", ret); - ret = oftree_to_fdt(oftree_default(), &buf); + ret = upl_write_to_buf(upl, ofnode_root(), &buf); if (ret) - return log_msg_ret("fdt", ret); - log_debug("FDT size %zx\n", abuf_size(&buf)); + return log_msg_ret("wuh", ret); ptr = bloblist_add(BLOBLISTT_CONTROL_FDT, abuf_size(&buf), 0); if (!ptr) return log_msg_ret("blo", -ENOENT); memcpy(ptr, abuf_data(&buf), abuf_size(&buf)); + abuf_uninit(&buf); return 0; } diff --git a/include/upl.h b/include/upl.h index edd333f648a..ce357d16ebe 100644 --- a/include/upl.h +++ b/include/upl.h @@ -394,6 +394,29 @@ int upl_add_serial(struct upl_serial *ser); */ int upl_add_graphics(struct upl_graphics *gra, ulong *basep, ulong *sizep); +/** + * upl_create() - Create a basic UPL handoff structure + * + * Sets up common fields which don't depend on having a FIT available + * + * @upl: UPL structure to create + * Return: 0 if OK, -ve on error + */ +int upl_create(struct upl *upl); + +#ifndef USE_HOSTCC +/** + * upl_write_to_buf() - Write a UPL struct to a tree then flatten it into a buf + * + * @upl: UPL struct to fill up + * @root: Root node to write UPL information to (this is updated before the + * finally buffer is written) + * @buf: Buffer to contain the final flattened tree + * Return: 0 if OK, -ve on error + */ +int upl_write_to_buf(struct upl *upl, ofnode root, struct abuf *buf); +#endif + /** upl_init() - Set up a UPL struct */ void upl_init(struct upl *upl); -- 2.43.0