All of lore.kernel.org
 help / color / mirror / Atom feed
From: Simon Glass <sjg@chromium.org>
To: U-Boot Mailing List <u-boot@lists.denx.de>
Cc: Mark Kettenis <kettenis@openbsd.org>,
	Tom Rini <trini@konsulko.com>, Simon Glass <sjg@chromium.org>
Subject: [PATCH v2 2/2] bootstd: Replicate the dtb-filename quirks of distroboot
Date: Sat, 28 Jan 2023 18:27:15 -0700	[thread overview]
Message-ID: <20230129012715.83657-2-sjg@chromium.org> (raw)
In-Reply-To: <20230129012715.83657-1-sjg@chromium.org>

For EFI, the distro boot scripts search in three different directories
for the .dtb file. The SOC-based filename fallback is supported only for
32-bit ARM.

Adjust the code to mirror this behaviour.

Also some boards can use a prior-stage FDT if one is not found in the
normal way. Support this and show a warning in that case.

Signed-off-by: Simon Glass <sjg@chromium.org>
Suggested-by: Mark Kettenis <kettenis@openbsd.org>
---

Changes in v2:
- Allow use of the prior-stage FDT if nothing else is found
- Warn about using a prior-stage FDT

 boot/bootflow.c     |  3 ++
 boot/bootmeth_efi.c | 70 +++++++++++++++++++++++++++++++++++++++------
 include/bootflow.h  | 14 +++++++++
 3 files changed, 78 insertions(+), 9 deletions(-)

diff --git a/boot/bootflow.c b/boot/bootflow.c
index 4999018e36e..5ee12eb2bab 100644
--- a/boot/bootflow.c
+++ b/boot/bootflow.c
@@ -463,6 +463,9 @@ int bootflow_run_boot(struct bootflow_iter *iter, struct bootflow *bflow)
 
 	printf("** Booting bootflow '%s' with %s\n", bflow->name,
 	       bflow->method->name);
+	if (IS_ENABLED(CONFIG_OF_HAS_PRIOR_STAGE) &&
+	    (bflow->flags & BOOTFLOWF_USE_PRIOR_FDT))
+		printf("** Warning: Using prior-stage device tree\n");
 	ret = bootflow_boot(bflow);
 	if (!IS_ENABLED(CONFIG_BOOTSTD_FULL)) {
 		printf("Boot failed (err=%d)\n", ret);
diff --git a/boot/bootmeth_efi.c b/boot/bootmeth_efi.c
index 67c972e3fe4..6a97ac02ff5 100644
--- a/boot/bootmeth_efi.c
+++ b/boot/bootmeth_efi.c
@@ -147,25 +147,60 @@ static int distro_efi_check(struct udevice *dev, struct bootflow_iter *iter)
 	return 0;
 }
 
-static void distro_efi_get_fdt_name(char *fname, int size)
+/**
+ * distro_efi_get_fdt_name() - Get the filename for reading the .dtb file
+ *
+ * @fname: Place to put filename
+ * @size: Max size of filename
+ * @seq: Sequence number, to cycle through options (0=first)
+ * Returns: 0 on success, -ENOENT if the "fdtfile" env var does not exist,
+ * -EINVAL if there are no more options, -EALREADY if the control FDT should be
+ * used
+ */
+static int distro_efi_get_fdt_name(char *fname, int size, int seq)
 {
 	const char *fdt_fname;
+	const char *prefix;
+
+	/* select the prefix */
+	switch (seq) {
+	case 0:
+		/* this is the default */
+		prefix = "/dtb";
+		break;
+	case 1:
+		prefix = "";
+		break;
+	case 2:
+		prefix = "/dtb/current";
+		break;
+	default:
+		return log_msg_ret("pref", -EINVAL);
+	}
 
 	fdt_fname = env_get("fdtfile");
 	if (fdt_fname) {
-		snprintf(fname, size, "dtb/%s", fdt_fname);
+		snprintf(fname, size, "%s/%s", prefix, fdt_fname);
 		log_debug("Using device tree: %s\n", fname);
-	} else {
+	} else if (IS_ENABLED(CONFIG_OF_HAS_PRIOR_STAGE)) {
+		strcpy(fname, "<prior>");
+		return log_msg_ret("pref", -EALREADY);
+	/* Use this fallback only for 32-bit ARM */
+	} else if (IS_ENABLED(CONFIG_ARM) && !IS_ENABLED(CONFIG_ARM64)) {
 		const char *soc = env_get("soc");
 		const char *board = env_get("board");
 		const char *boardver = env_get("boardver");
 
 		/* cf the code in label_boot() which seems very complex */
-		snprintf(fname, size, "dtb/%s%s%s%s.dtb",
+		snprintf(fname, size, "%s/%s%s%s%s.dtb", prefix,
 			 soc ? soc : "", soc ? "-" : "", board ? board : "",
 			 boardver ? boardver : "");
 		log_debug("Using default device tree: %s\n", fname);
+	} else {
+		return log_msg_ret("env", -ENOENT);
 	}
+
+	return 0;
 }
 
 static int distro_efi_read_bootflow_file(struct udevice *dev,
@@ -174,7 +209,7 @@ static int distro_efi_read_bootflow_file(struct udevice *dev,
 	struct blk_desc *desc = NULL;
 	ulong fdt_addr, size;
 	char fname[256];
-	int ret;
+	int ret, seq;
 
 	/* We require a partition table */
 	if (!bflow->part)
@@ -196,13 +231,26 @@ static int distro_efi_read_bootflow_file(struct udevice *dev,
 	if (ret)
 		return log_msg_ret("read", -EINVAL);
 
-	distro_efi_get_fdt_name(fname, sizeof(fname));
+	fdt_addr = env_get_hex("fdt_addr_r", 0);
+
+	/* try the various available names */
+	ret = -ENOENT;
+	for (seq = 0; ret; seq++) {
+		ret = distro_efi_get_fdt_name(fname, sizeof(fname), seq);
+		if (ret == -EALREADY) {
+			bflow->flags = BOOTFLOWF_USE_PRIOR_FDT;
+			break;
+		}
+		if (ret)
+			return log_msg_ret("nam", ret);
+		ret = bootmeth_common_read_file(dev, bflow, fname, fdt_addr,
+						&size);
+	}
+
 	bflow->fdt_fname = strdup(fname);
 	if (!bflow->fdt_fname)
 		return log_msg_ret("fil", -ENOMEM);
 
-	fdt_addr = env_get_hex("fdt_addr_r", 0);
-	ret = bootmeth_common_read_file(dev, bflow, fname, fdt_addr, &size);
 	if (!ret) {
 		bflow->fdt_size = size;
 		bflow->fdt_addr = fdt_addr;
@@ -277,7 +325,11 @@ static int distro_efi_read_bootflow_net(struct bootflow *bflow)
 	fdt_addr = hextoul(fdt_addr_str, NULL);
 	sprintf(file_addr, "%lx", fdt_addr);
 
-	distro_efi_get_fdt_name(fname, sizeof(fname));
+	/* We only allow the first prefix with PXE */
+	ret = distro_efi_get_fdt_name(fname, sizeof(fname), 0);
+	if (ret)
+		return log_msg_ret("nam", ret);
+
 	bflow->fdt_fname = strdup(fname);
 	if (!bflow->fdt_fname)
 		return log_msg_ret("fil", -ENOMEM);
diff --git a/include/bootflow.h b/include/bootflow.h
index e5fdf5f29d1..f20f575030f 100644
--- a/include/bootflow.h
+++ b/include/bootflow.h
@@ -36,6 +36,18 @@ enum bootflow_state_t {
 	BOOTFLOWST_COUNT
 };
 
+/**
+ * enum bootflow_flags_t - flags for bootflows
+ *
+ * @BOOTFLOWF_USE_PRIOR_FDT: Indicates that an FDT was not found by the bootmeth
+ *	and it is using the prior-stage FDT, which is the U-Boot control FDT.
+ *	This is only possible with the EFI bootmeth (distro-efi) and only when
+ *	CONFIG_OF_HAS_PRIOR_STAGE is enabled
+ */
+enum bootflow_flags_t {
+	BOOTFLOWF_USE_PRIOR_FDT	= 1 << 0,
+};
+
 /**
  * struct bootflow - information about a bootflow
  *
@@ -68,6 +80,7 @@ enum bootflow_state_t {
  * @fdt_fname: Filename of FDT file
  * @fdt_size: Size of FDT file
  * @fdt_addr: Address of loaded fdt
+ * @flags: Flags for the bootflow (see enum bootflow_flags_t)
  */
 struct bootflow {
 	struct list_head bm_node;
@@ -90,6 +103,7 @@ struct bootflow {
 	char *fdt_fname;
 	int fdt_size;
 	ulong fdt_addr;
+	int flags;
 };
 
 /**
-- 
2.39.1.456.gfc5497dd1b-goog


  reply	other threads:[~2023-01-29  1:28 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-01-29  1:27 [PATCH v2 1/2] bootflow: Rename bootflow_flags_t Simon Glass
2023-01-29  1:27 ` Simon Glass [this message]
2023-01-30 17:10   ` [PATCH v2 2/2] bootstd: Replicate the dtb-filename quirks of distroboot Tom Rini
2023-02-07  4:02     ` 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=20230129012715.83657-2-sjg@chromium.org \
    --to=sjg@chromium.org \
    --cc=kettenis@openbsd.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.