From: Simon Glass <sjg@chromium.org>
To: U-Boot Mailing List <u-boot@lists.denx.de>
Cc: Tom Rini <trini@konsulko.com>, Simon Glass <sjg@chromium.org>
Subject: [PATCH 14/15] vbe: Support loading SPL images
Date: Thu, 9 Jan 2025 05:30:09 -0700 [thread overview]
Message-ID: <20250109123010.4005298-15-sjg@chromium.org> (raw)
In-Reply-To: <20250109123010.4005298-1-sjg@chromium.org>
VBE needs to load different images from a FIT depending on the xPL phase
in use. The IH_PHASE value is used to select the image to load.
Add the required logic to handle this. For compatibility with the
SPL-loader driver, fill out a struct spl_image_info with the details
needed to boot the next phase.
Signed-off-by: Simon Glass <sjg@chromium.org>
---
boot/vbe_common.c | 85 ++++++++++++++++++++++++++++++++++++++++++--
boot/vbe_common.h | 4 ++-
boot/vbe_simple_fw.c | 3 +-
3 files changed, 87 insertions(+), 5 deletions(-)
diff --git a/boot/vbe_common.c b/boot/vbe_common.c
index 46b39cf8910..799f33d9ffa 100644
--- a/boot/vbe_common.c
+++ b/boot/vbe_common.c
@@ -18,17 +18,48 @@
#include <u-boot/crc.h>
#include "vbe_common.h"
+binman_sym_declare(ulong, u_boot_vpl_nodtb, size);
+binman_sym_declare(ulong, u_boot_vpl_bss_pad, size);
+binman_sym_declare(ulong, u_boot_spl_nodtb, size);
+binman_sym_declare(ulong, u_boot_spl_bss_pad, size);
+
+/**
+ * h_vbe_load_read() - Handler for reading an SPL image from a FIT
+ *
+ * See spl_load_reader for the definition
+ */
+ulong h_vbe_load_read(struct spl_load_info *load, ulong off, ulong size,
+ void *buf)
+{
+ struct blk_desc *desc = load->priv;
+ lbaint_t sector = off >> desc->log2blksz;
+ lbaint_t count = size >> desc->log2blksz;
+ int ret;
+
+ log_debug("vbe read log2blksz %x offset %lx sector %lx count %lx\n",
+ desc->log2blksz, (ulong)off, (long)sector, (ulong)count);
+
+ ret = blk_dread(desc, sector, count, buf);
+ log_debug("ret=%x\n", ret);
+ if (ret < 0)
+ return ret;
+
+ return ret << desc->log2blksz;
+}
+
int vbe_read_fit(struct udevice *blk, ulong area_offset, ulong area_size,
- ulong *load_addrp, ulong *lenp, char **namep)
+ struct spl_image_info *image, ulong *load_addrp, ulong *lenp,
+ char **namep)
{
ALLOC_CACHE_ALIGN_BUFFER(u8, sbuf, MMC_MAX_BLOCK_LEN);
- ulong size, blknum, addr, len, load_addr, num_blks;
+ ulong size, blknum, addr, len, load_addr, num_blks, spl_load_addr;
ulong aligned_size, fdt_load_addr, fdt_size;
const char *fit_uname, *fit_uname_config;
struct bootm_headers images = {};
enum image_phase_t phase;
struct blk_desc *desc;
int node, ret;
+ bool for_xpl;
void *buf;
desc = dev_get_uclass_plat(blk);
@@ -81,7 +112,8 @@ int vbe_read_fit(struct udevice *blk, ulong area_offset, ulong area_size,
gd->malloc_base + gd->malloc_limit);
#endif
/* figure out the phase to load */
- phase = IS_ENABLED(CONFIG_VPL_BUILD) ? IH_PHASE_SPL : IH_PHASE_U_BOOT;
+ phase = IS_ENABLED(CONFIG_TPL_BUILD) ? IH_PHASE_NONE :
+ IS_ENABLED(CONFIG_VPL_BUILD) ? IH_PHASE_SPL : IH_PHASE_U_BOOT;
/*
* Load the image from the FIT. We ignore any load-address information
@@ -92,6 +124,20 @@ int vbe_read_fit(struct udevice *blk, ulong area_offset, ulong area_size,
fit_uname = NULL;
fit_uname_config = NULL;
log_debug("loading FIT\n");
+
+ if (xpl_phase() == PHASE_SPL && !IS_ENABLED(CONFIG_SANDBOX)) {
+ struct spl_load_info info;
+
+ spl_load_init(&info, h_vbe_load_read, desc, desc->blksz);
+ xpl_set_phase(&info, IH_PHASE_U_BOOT);
+ log_debug("doing SPL from %s blksz %lx log2blksz %x area_offset %lx + fdt_size %lx\n",
+ blk->name, desc->blksz, desc->log2blksz, area_offset, ALIGN(size, 4));
+ ret = spl_load_simple_fit(image, &info, area_offset, buf);
+ log_debug("spl_load_abrec_fit() ret=%d\n", ret);
+
+ return ret;
+ }
+
ret = fit_image_load(&images, addr, &fit_uname, &fit_uname_config,
IH_ARCH_DEFAULT, image_ph(phase, IH_TYPE_FIRMWARE),
BOOTSTAGE_ID_FIT_SPL_START, FIT_LOAD_IGNORED,
@@ -110,6 +156,31 @@ int vbe_read_fit(struct udevice *blk, ulong area_offset, ulong area_size,
fdt_load_addr = 0;
fdt_size = 0;
+ if ((xpl_phase() == PHASE_TPL || xpl_phase() == PHASE_VPL) &&
+ !IS_ENABLED(CONFIG_SANDBOX)) {
+ /* allow use of a different image from the configuration node */
+ fit_uname = NULL;
+ ret = fit_image_load(&images, addr, &fit_uname,
+ &fit_uname_config, IH_ARCH_DEFAULT,
+ image_ph(phase, IH_TYPE_FLATDT),
+ BOOTSTAGE_ID_FIT_SPL_START,
+ FIT_LOAD_IGNORED, &fdt_load_addr,
+ &fdt_size);
+ fdt_size = ALIGN(fdt_size, desc->blksz);
+ log_debug("FDT noload to %lx size %lx\n", fdt_load_addr,
+ fdt_size);
+ }
+
+ for_xpl = !USE_BOOTMETH && CONFIG_IS_ENABLED(RELOC_LOADER);
+ if (for_xpl) {
+ image->size = len;
+ image->fdt_size = fdt_size;
+ ret = spl_reloc_prepare(image, &spl_load_addr);
+ if (ret)
+ return log_msg_ret("spl", ret);
+ }
+ if (!IS_ENABLED(CONFIG_SANDBOX))
+ image->os = IH_OS_U_BOOT;
/* For FIT external data, read in the external data */
log_debug("load_addr %lx len %lx addr %lx aligned_size %lx\n",
@@ -137,6 +208,8 @@ int vbe_read_fit(struct udevice *blk, ulong area_offset, ulong area_size,
* to load to, then load the blocks
*/
num_blks = DIV_ROUND_UP(full_size, desc->blksz);
+ if (for_xpl)
+ base = spl_load_addr;
base_buf = map_sysmem(base, full_size);
ret = blk_read(blk, blknum, num_blks, base_buf);
log_debug("read foffset %lx blknum %lx full_size %lx num_blks %lx to %lx / %p: ret=%d\n",
@@ -152,6 +225,12 @@ int vbe_read_fit(struct udevice *blk, ulong area_offset, ulong area_size,
memmove(base_buf, base_buf + extra, len);
}
+ if ((xpl_phase() == PHASE_VPL || xpl_phase() == PHASE_TPL) &&
+ !IS_ENABLED(CONFIG_SANDBOX)) {
+ image->load_addr = spl_get_image_text_base();
+ image->entry_point = image->load_addr;
+ }
+
/* now the FDT */
if (fdt_size) {
fdt_offset = area_offset + fdt_load_addr - addr;
diff --git a/boot/vbe_common.h b/boot/vbe_common.h
index 403391ff1ea..98b7aff0b5d 100644
--- a/boot/vbe_common.h
+++ b/boot/vbe_common.h
@@ -155,6 +155,7 @@ int vbe_get_blk(const char *storage, struct udevice **blkp);
* @blk: Block device containing FIT
* @area_offset: Byte offset of the VBE area in @blk containing the FIT
* @area_size: Size of the VBE area
+ * @image: SPL image to fill in with details of the loaded image, or NULL
* @load_addrp: If non-null, returns the address where the image was loaded
* @lenp: If non-null, returns the size of the image loaded, in bytes
* @namep: If non-null, returns the name of the FIT-image node that was loaded
@@ -166,6 +167,7 @@ int vbe_get_blk(const char *storage, struct udevice **blkp);
* FIT-parsing (see fit_image_load()).
*/
int vbe_read_fit(struct udevice *blk, ulong area_offset, ulong area_size,
- ulong *load_addrp, ulong *lenp, char **namep);
+ struct spl_image_info *image, ulong *load_addrp, ulong *lenp,
+ char **namep);
#endif /* __VBE_ABREC_H */
diff --git a/boot/vbe_simple_fw.c b/boot/vbe_simple_fw.c
index 0bf25ccad23..9da3e49a66e 100644
--- a/boot/vbe_simple_fw.c
+++ b/boot/vbe_simple_fw.c
@@ -52,7 +52,8 @@ int vbe_simple_read_bootflow_fw(struct udevice *dev, struct bootflow *bflow)
log_debug("blk=%s\n", blk->name);
ret = vbe_read_fit(blk, priv->area_start + priv->skip_offset,
- priv->area_size, &load_addr, &len, &bflow->name);
+ priv->area_size, NULL, &load_addr, &len,
+ &bflow->name);
/* set up the bootflow with the info we obtained */
bflow->blk = blk;
--
2.34.1
next prev parent reply other threads:[~2025-01-09 12:33 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-01-09 12:29 [PATCH 00/15] vbe: Series part F Simon Glass
2025-01-09 12:29 ` [PATCH 01/15] vbe: Split out some VBE code into a common file Simon Glass
2025-01-14 1:22 ` Tom Rini
2025-01-14 12:58 ` Simon Glass
2025-01-14 13:26 ` Simon Glass
2025-01-14 16:58 ` Tom Rini
2025-01-14 17:33 ` Tom Rini
2025-01-15 1:18 ` Simon Glass
2025-01-15 1:41 ` Tom Rini
2025-01-15 2:48 ` Simon Glass
2025-01-15 14:10 ` Simon Glass
2025-01-09 12:29 ` [PATCH 02/15] vbe: Split out reading a FIT " Simon Glass
2025-01-11 22:54 ` Tom Rini
2025-01-13 20:03 ` Simon Glass
2025-01-13 20:44 ` Tom Rini
2025-01-14 0:13 ` Simon Glass
2025-01-14 1:22 ` Tom Rini
2025-01-15 14:43 ` Tom Rini
2025-01-15 23:21 ` Simon Glass
2025-01-09 12:29 ` [PATCH 03/15] vbe: Allocate space for the FIT header Simon Glass
2025-01-09 12:29 ` [PATCH 04/15] vbe: Allow VBE to load FITs on any architecture Simon Glass
2025-01-09 12:30 ` [PATCH 05/15] vbe: Tidy up error checking with blk_read() Simon Glass
2025-01-09 12:30 ` [PATCH 06/15] vbe: Handle loading from an unaligned offset Simon Glass
2025-01-09 12:30 ` [PATCH 07/15] vbe: Allow loading loadables if there is no firmware Simon Glass
2025-01-09 12:30 ` [PATCH 08/15] vbe: Support loading an FDT from the FIT Simon Glass
2025-01-09 12:30 ` [PATCH 09/15] spl: Add fields for VBE Simon Glass
2025-01-09 12:30 ` [PATCH 10/15] spl: Add a type for the jumper function Simon Glass
2025-01-09 12:30 ` [PATCH 11/15] spl: Add support for a relocating jump to the next phase Simon Glass
2025-01-09 12:30 ` [PATCH 12/15] spl: Plumb in the relocating loader Simon Glass
2025-01-09 12:30 ` [PATCH 13/15] vbe: Support loading an FDT with " Simon Glass
2025-01-09 12:30 ` Simon Glass [this message]
2025-01-09 12:30 ` [PATCH 15/15] vbe: Update simple-fw to support using the SPL loader Simon Glass
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250109123010.4005298-15-sjg@chromium.org \
--to=sjg@chromium.org \
--cc=trini@konsulko.com \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.