Browse Source

sandbox: Support executables for more phases

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@chromium.org>
Simon Glass 2 years ago
parent
commit
f178bebf55
6 changed files with 86 additions and 38 deletions
  1. 28 35
      arch/sandbox/cpu/os.c
  2. 15 1
      arch/sandbox/cpu/spl.c
  3. 13 0
      arch/sandbox/include/asm/spl.h
  4. 4 1
      include/os.h
  5. 21 0
      include/spl.h
  6. 5 1
      test/image/spl_load.c

+ 28 - 35
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);

+ 15 - 1
arch/sandbox/cpu/spl.c

@@ -17,6 +17,20 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+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 init function */
 void board_init_f(ulong flag)
 {
@@ -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;

+ 13 - 0
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

+ 4 - 1
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

+ 21 - 0
include/spl.h

@@ -176,6 +176,27 @@ 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_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

+ 5 - 1
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;