At present sandbox runs the next phase from discrete executables, so for
example u-boot-tpl runs u-boot-vpl to get to the next phase.

In some cases the phases are all built into a single firmware image, as is
done for real boards. Add support for this to sandbox.

Make it higher priority so that it takes precedence over the existing
method.

Signed-off-by: Simon Glass <s...@chromium.org>
---

(no changes since v1)

 arch/sandbox/cpu/spl.c | 52 +++++++++++++++++++++++++++++++++++++++++-
 include/spl.h          |  3 +++
 2 files changed, 54 insertions(+), 1 deletion(-)

diff --git a/arch/sandbox/cpu/spl.c b/arch/sandbox/cpu/spl.c
index 2678370481a..75f4601fdfb 100644
--- a/arch/sandbox/cpu/spl.c
+++ b/arch/sandbox/cpu/spl.c
@@ -78,7 +78,48 @@ static int spl_board_load_file(struct spl_image_info 
*spl_image,
 
        return 0;
 }
-SPL_LOAD_IMAGE_METHOD("sandbox", 9, BOOT_DEVICE_BOARD, spl_board_load_file);
+SPL_LOAD_IMAGE_METHOD("sandbox_file", 9, BOOT_DEVICE_BOARD,
+                     spl_board_load_file);
+
+static int load_from_image(struct spl_image_info *spl_image,
+                          struct spl_boot_device *bootdev)
+{
+       struct sandbox_state *state = state_get_current();
+       enum u_boot_phase next_phase;
+       const char *fname;
+       ulong pos, size;
+       int full_size;
+       void *buf;
+       int ret;
+
+       if (!IS_ENABLED(CONFIG_SANDBOX_VPL))
+               return -ENOENT;
+
+       next_phase = spl_next_phase();
+       pos = spl_get_image_pos();
+       size = spl_get_image_size();
+       if (pos == BINMAN_SYM_MISSING || size == BINMAN_SYM_MISSING) {
+               log_debug("No image found\n");
+               return -ENOENT;
+       }
+       log_info("Reading from pos %lx size %lx\n", pos, size);
+
+       /*
+        * Set up spl_image to boot from jump_to_image_no_args(). Allocate this
+        * outside the RAM buffer (i.e. don't use strdup()).
+        */
+       fname = state->prog_fname ? state->prog_fname : state->argv[0];
+       ret = os_read_file(fname, &buf, &full_size);
+       if (ret)
+               return log_msg_ret("rd", -ENOMEM);
+       spl_image->flags = SPL_SANDBOXF_ARG_IS_BUF;
+       spl_image->arg = buf;
+       spl_image->offset = pos;
+       spl_image->size = size;
+
+       return 0;
+}
+SPL_LOAD_IMAGE_METHOD("sandbox_image", 7, BOOT_DEVICE_BOARD, load_from_image);
 
 void spl_board_init(void)
 {
@@ -109,6 +150,15 @@ void __noreturn jump_to_image_no_args(struct 
spl_image_info *spl_image)
                }
                break;
        }
+       case SPL_SANDBOXF_ARG_IS_BUF: {
+               int ret;
+
+               ret = os_jump_to_image(spl_image->arg + spl_image->offset,
+                                      spl_image->size);
+               if (ret)
+                       log_err("Failed to load image\n");
+               break;
+       }
        default:
                log_err("Invalid flags\n");
                break;
diff --git a/include/spl.h b/include/spl.h
index e711fb13654..e407c7fe55b 100644
--- a/include/spl.h
+++ b/include/spl.h
@@ -232,9 +232,12 @@ static inline const char *spl_phase_prefix(enum 
u_boot_phase phase)
  * enum spl_sandbox_flags - flags for sandbox's use of spl_image_info->flags
  *
  * @SPL_SANDBOXF_ARG_IS_FNAME: arg is the filename to jump to (default)
+ * @SPL_SANDBOXF_ARG_IS_BUF: arg is the containing image to jump to, @offset is
+ *     the start offset within the image, @size is the size of the image
  */
 enum spl_sandbox_flags {
        SPL_SANDBOXF_ARG_IS_FNAME = 0,
+       SPL_SANDBOXF_ARG_IS_BUF,
 };
 
 struct spl_image_info {
-- 
2.38.0.135.g90850a2211-goog

Reply via email to