[PATCH 07/22] sandbox: Support executables for more phases
Simon Glass
sjg at chromium.org
Tue Jul 6 00:32:45 CEST 2021
The SPL header has a function for obtaining the phase in capital letters,
e.g. 'SPL'. Add one for lower-case also, as used by sandbox.
Use this to generalise the sandbox logic for determining the filename of
the next sandbox executable. This can provide support for VPL.
Signed-off-by: Simon Glass <sjg at chromium.org>
---
arch/sandbox/cpu/os.c | 63 +++++++++++++++-------------------
arch/sandbox/cpu/spl.c | 18 ++++++++--
arch/sandbox/include/asm/spl.h | 13 +++++++
include/os.h | 5 ++-
include/spl.h | 23 +++++++++++++
test/image/spl_load.c | 6 +++-
6 files changed, 89 insertions(+), 39 deletions(-)
diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c
index 0d21827e1b7..a8aa9def27f 100644
--- a/arch/sandbox/cpu/os.c
+++ b/arch/sandbox/cpu/os.c
@@ -783,12 +783,14 @@ int os_jump_to_image(const void *dest, int size)
return os_jump_to_file(fname, true);
}
-int os_find_u_boot(char *fname, int maxlen, bool use_img)
+int os_find_u_boot(char *fname, int maxlen, bool use_img,
+ const char *cur_prefix, const char *next_prefix)
{
struct sandbox_state *state = state_get_current();
const char *progname = state->argv[0];
int len = strlen(progname);
- const char *suffix;
+ char subdir[10];
+ char *suffix;
char *p;
int fd;
@@ -798,45 +800,36 @@ int os_find_u_boot(char *fname, int maxlen, bool use_img)
strcpy(fname, progname);
suffix = fname + len - 4;
- /* If we are TPL, boot to SPL */
- if (!strcmp(suffix, "-tpl")) {
- fname[len - 3] = 's';
- fd = os_open(fname, O_RDONLY);
- if (fd >= 0) {
- close(fd);
- return 0;
- }
-
- /* Look for 'u-boot-spl' in the spl/ directory */
- p = strstr(fname, "/spl/");
- if (p) {
- p[1] = 's';
- fd = os_open(fname, O_RDONLY);
- if (fd >= 0) {
- close(fd);
- return 0;
- }
- }
- return -ENOENT;
- }
+ /* Change the existing suffix to the new one */
+ if (*suffix != '-')
+ return -EINVAL;
- /* Look for 'u-boot' in the same directory as 'u-boot-spl' */
- if (!strcmp(suffix, "-spl")) {
- fname[len - 4] = '\0';
- fd = os_open(fname, O_RDONLY);
- if (fd >= 0) {
- close(fd);
- return 0;
- }
+ if (*next_prefix)
+ strcpy(suffix + 1, next_prefix); /* e.g. "-tpl" to "-spl" */
+ else
+ *suffix = '\0'; /* e.g. "-spl" to "" */
+ fd = os_open(fname, O_RDONLY);
+ if (fd >= 0) {
+ close(fd);
+ return 0;
}
- /* Look for 'u-boot' in the parent directory of spl/ */
- p = strstr(fname, "spl/");
+ /*
+ * We didn't find it, so try looking for 'u-boot-xxx' in the xxx/
+ * directory. Replace the old dirname with the new one.
+ */
+ snprintf(subdir, sizeof(subdir), "/%s/", cur_prefix);
+ p = strstr(fname, subdir);
if (p) {
- /* Remove the "spl" characters */
- memmove(p, p + 4, strlen(p + 4) + 1);
+ if (*next_prefix)
+ /* e.g. ".../tpl/u-boot-spl" to "../spl/u-boot-spl" */
+ memcpy(p + 1, next_prefix, strlen(next_prefix));
+ else
+ /* e.g. ".../spl/u-boot" to ".../u-boot" */
+ strcpy(p, p + 1 + strlen(cur_prefix));
if (use_img)
strcat(p, ".img");
+
fd = os_open(fname, O_RDONLY);
if (fd >= 0) {
close(fd);
diff --git a/arch/sandbox/cpu/spl.c b/arch/sandbox/cpu/spl.c
index f82b0d3de16..be86182fd85 100644
--- a/arch/sandbox/cpu/spl.c
+++ b/arch/sandbox/cpu/spl.c
@@ -17,7 +17,21 @@
DECLARE_GLOBAL_DATA_PTR;
-/* SPL / TPL init function */
+int sandbox_find_next_phase(char *fname, int maxlen, bool use_img)
+{
+ const char *cur_prefix, *next_prefix;
+ int ret;
+
+ cur_prefix = spl_phase_prefix(spl_phase());
+ next_prefix = spl_phase_prefix(spl_next_phase());
+ ret = os_find_u_boot(fname, maxlen, use_img, cur_prefix, next_prefix);
+ if (ret)
+ return log_msg_ret("find", ret);
+
+ return 0;
+}
+
+/* SPL / TPL / VPL init function */
void board_init_f(ulong flag)
{
struct sandbox_state *state = state_get_current();
@@ -37,7 +51,7 @@ static int spl_board_load_image(struct spl_image_info *spl_image,
char fname[256];
int ret;
- ret = os_find_u_boot(fname, sizeof(fname), false);
+ ret = sandbox_find_next_phase(fname, sizeof(fname), false);
if (ret) {
printf("(%s not found, error %d)\n", fname, ret);
return ret;
diff --git a/arch/sandbox/include/asm/spl.h b/arch/sandbox/include/asm/spl.h
index 51e9d95d557..d25dc7c82a0 100644
--- a/arch/sandbox/include/asm/spl.h
+++ b/arch/sandbox/include/asm/spl.h
@@ -12,4 +12,17 @@ enum {
BOOT_DEVICE_BOARD,
};
+/**
+ * sandbox_find_next_phase() - Find the next phase of U-Boot
+ *
+ * This function is intended to be called from within sandbox SPL. It uses
+ * a few rules to find the filename of the next U-Boot phase. See also
+ * os_find_u_boot().
+ *
+ * @fname: place to put full path to U-Boot
+ * @maxlen: maximum size of @fname
+ * @use_img: select the 'u-boot.img' file instead of the 'u-boot' ELF file
+ */
+int sandbox_find_next_phase(char *fname, int maxlen, bool use_img);
+
#endif
diff --git a/include/os.h b/include/os.h
index bd1096eb8b3..7b20d606dd0 100644
--- a/include/os.h
+++ b/include/os.h
@@ -327,9 +327,12 @@ int os_jump_to_image(const void *dest, int size);
* @fname: place to put full path to U-Boot
* @maxlen: maximum size of @fname
* @use_img: select the 'u-boot.img' file instead of the 'u-boot' ELF file
+ * @cur_prefix: prefix of current executable, e.g. "spl" or "tpl"
+ * @next_prefix: prefix of executable to find, e.g. "spl" or ""
* Return: 0 if OK, -NOSPC if the filename is too large, -ENOENT if not found
*/
-int os_find_u_boot(char *fname, int maxlen, bool use_img);
+int os_find_u_boot(char *fname, int maxlen, bool use_img,
+ const char *cur_prefix, const char *next_prefix);
/**
* os_spl_to_uboot() - Run U-Boot proper
diff --git a/include/spl.h b/include/spl.h
index d9fe4e1bfd4..cf77d379da2 100644
--- a/include/spl.h
+++ b/include/spl.h
@@ -188,6 +188,29 @@ static inline const char *spl_phase_name(enum u_boot_phase phase)
}
}
+/**
+ * spl_phase_prefix() - Get the prefix of the current phase
+ *
+ * @phase: Phase to look up
+ * @return phase prefix ("spl", "tpl", etc.)
+ */
+static inline const char *spl_phase_prefix(enum u_boot_phase phase)
+{
+ switch (phase) {
+ case PHASE_TPL:
+ return "tpl";
+ case PHASE_VPL:
+ return "vpl";
+ case PHASE_SPL:
+ return "spl";
+ case PHASE_BOARD_F:
+ case PHASE_BOARD_R:
+ return "";
+ default:
+ return "phase?";
+ }
+}
+
/* A string name for SPL or TPL */
#ifdef CONFIG_SPL_BUILD
# ifdef CONFIG_TPL_BUILD
diff --git a/test/image/spl_load.c b/test/image/spl_load.c
index 851603ddd75..e7cabf5680c 100644
--- a/test/image/spl_load.c
+++ b/test/image/spl_load.c
@@ -56,6 +56,7 @@ struct image_header *spl_get_load_buffer(ssize_t offset, size_t size)
static int spl_test_load(struct unit_test_state *uts)
{
+ const char *cur_prefix, *next_prefix;
struct spl_image_info image;
struct image_header *header;
struct text_ctx text_ctx;
@@ -68,7 +69,10 @@ static int spl_test_load(struct unit_test_state *uts)
load.bl_len = 512;
load.read = read_fit_image;
- ret = os_find_u_boot(fname, sizeof(fname), true);
+ cur_prefix = spl_phase_prefix(spl_phase());
+ next_prefix = spl_phase_prefix(spl_next_phase());
+ ret = os_find_u_boot(fname, sizeof(fname), true, cur_prefix,
+ next_prefix);
if (ret) {
printf("(%s not found, error %d)\n", fname, ret);
return ret;
--
2.32.0.93.g670b81a890-goog
More information about the U-Boot
mailing list