Plumb in the ability for U-Boot proper to accept an incoming standard
passage from a previous phase, such as SPL or TF-A. This allows data to
be passed from binary to binary when firmware is booting.

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

Changes in v3:
- Add passage_valid() to decide if stdpass was provided
- Make the global_data fields present only when needed
- Move arch_passage_entry() into this patch
- Move passage.h into this patch

Changes in v2:
- Rebase to master
- Rework global_data for new stdpass convention

 Makefile                          |  2 +-
 common/Kconfig                    | 31 ++++++++++++++++++
 common/board_f.c                  | 13 +++++---
 include/asm-generic/global_data.h | 37 +++++++++++++++++++++
 include/passage.h                 | 53 +++++++++++++++++++++++++++++++
 lib/asm-offsets.c                 |  8 +++++
 scripts/Makefile.xpl              |  2 +-
 7 files changed, 139 insertions(+), 7 deletions(-)
 create mode 100644 include/passage.h

diff --git a/Makefile b/Makefile
index 73939748e54..3577c2c9a22 100644
--- a/Makefile
+++ b/Makefile
@@ -1396,7 +1396,7 @@ endif
 
 binman_dtb := $(shell echo $(CONFIG_BINMAN_DTB))
 ifeq ($(strip $(binman_dtb)),)
-ifeq ($(CONFIG_OF_EMBED),y)
+ifneq ($(CONFIG_OF_EMBED)$(CONFIG_OF_PASSAGE),)
 binman_dtb = ./dts/dt.dtb
 else
 binman_dtb = ./u-boot.dtb
diff --git a/common/Kconfig b/common/Kconfig
index be517b80eb5..c6a8fa54363 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -1089,6 +1089,14 @@ config BLOBLIST_PASSAGE_MANDATORY
          U-Boot will report an error when a valid incoming bloblist does not
          exist.
 
+config BLOBLIST_PASSAGE
+       bool "Obtain bloblist from standard passage information"
+       help
+         Rather than allocating the bloblist, get it from the standard
+         passage provided by an earlier phase, e.g. SPL. The bloblist address
+         and size are used as is, except that the bloblist is of course
+         relocated when U-Boot relocates.
+
 endchoice
 
 config BLOBLIST_ADDR
@@ -1148,6 +1156,13 @@ config SPL_BLOBLIST_ALLOC
          specify a fixed address on systems where this is unknown or can
          change at runtime.
 
+config SPL_BLOBLIST_PASSAGE
+       bool "Obtain bloblist from standard passage information"
+       help
+         Rather than allocating the bloblist, get it from the standard
+         passage provided by an earlier phase, e.g. TPL. The bloblist address
+         and size are used as is within SPL, then passed on to U-Boot.
+
 endchoice
 
 endif # SPL_BLOBLIST
@@ -1212,6 +1227,22 @@ endif # VPL_BLOBLIST
 
 endmenu
 
+config PASSAGE_IN
+       bool "Support the standard-passage protocol (in)"
+       help
+         This enables a standard protocol for entering U-Boot, providing
+         parameters in a bloblist with a devicetree. It allows the various
+         firmware phases to communicate state and settings to following
+         phases.
+
+config SPL_PASSAGE_IN
+       bool "Support the standard-passage protocol in SPL (in)"
+       help
+         This enables a standard protocol for entering SPL, providing
+         parameters in a bloblist and a devicetree. It allows the various
+         firmware phases to communicate state and settings to following
+         phases.
+
 source "common/spl/Kconfig"
 
 config IMAGE_SIGN_INFO
diff --git a/common/board_f.c b/common/board_f.c
index bff465d9cb2..e9ffa2d7fed 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -700,11 +700,14 @@ static int reloc_bootstage(void)
 static int reloc_bloblist(void)
 {
 #ifdef CONFIG_BLOBLIST
-       /*
-        * Relocate only if we are supposed to send it
-        */
-       if ((gd->flags & GD_FLG_SKIP_RELOC) &&
-           CONFIG_BLOBLIST_SIZE == CONFIG_BLOBLIST_SIZE_RELOC) {
+       int size = bloblist_get_size();
+       int new_size = CONFIG_BLOBLIST_SIZE_RELOC;
+
+       if (!new_size)
+               new_size = size;
+
+       /* Relocate only if we are supposed to send it */
+       if ((gd->flags & GD_FLG_SKIP_RELOC) && size == new_size) {
                debug("Not relocating bloblist\n");
                return 0;
        }
diff --git a/include/asm-generic/global_data.h 
b/include/asm-generic/global_data.h
index 506ee51cdb0..464b9c3eee1 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -219,6 +219,35 @@ struct global_data {
         */
        long precon_buf_idx;
 #endif
+#if CONFIG_IS_ENABLED(PASSAGE_IN)
+       /**
+        * @passage_mach: Incoming machine information from standard passage
+        *
+        * Provides a value which indicates whether passage is used, e.g.
+        * PASSAGE_ABI_MACH
+        */
+       ulong passage_mach;
+       /**
+        * @passage_bloblist: Incoming bloblist from standard passage
+        *
+        * Provides the address of the bloblist passed in by the previous stage
+        * or phase. If this is zero, there is none.
+        */
+       ulong passage_bloblist;
+
+       /**
+        * @passage_dtb: Incoming control devicetree within standard passage
+        *
+        * Provides the address (typically within the bloblist) where the
+        * control DTB is stored. If this is zero, there is none.
+        *
+        * Note: This must be set to the correct value if the control DTB exists
+        * since SPL may use this and ignore the bloblist, e.g. if bloblist
+        * support is not enabled for code-size reasons. If this value is not
+        * valid, any devicetree passed in the passage_bloblist is ignored.
+        */
+       ulong passage_dtb;
+#endif
 #ifdef CONFIG_DM
        /**
         * @dm_root: root instance for Driver Model
@@ -581,6 +610,14 @@ static_assert(sizeof(struct global_data) == GD_SIZE);
 #define gd_video_size()                0
 #endif
 
+#if CONFIG_IS_ENABLED(PASSAGE_IN)
+#define gd_passage_bloblist()  gd->passage_bloblist
+#define gd_passage_dtb()       gd->passage_dtb
+#else
+#define gd_passage_bloblist()  0
+#define gd_passage_dtb()       0
+#endif
+
 /**
  * enum gd_flags - global data flags
  *
diff --git a/include/passage.h b/include/passage.h
new file mode 100644
index 00000000000..b71796f5eaf
--- /dev/null
+++ b/include/passage.h
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Standard passage implementation
+ *
+ * Copyright 2022 Google LLC
+ * Written by Simon Glass <s...@chromium.org>
+ */
+
+#ifndef __PASSAGE_H
+#define __PASSAGE_H
+
+#include <stdbool.h>
+#include <asm/global_data.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+enum {
+       PASSAGE_ABI_MACH        = 0x4a0fb10bul,
+       PASSAGE_ABI_VERSION     = 1ul,
+};
+
+static inline ulong passage_mach_version(void)
+{
+#if BITS_PER_LONG == 64
+       return PASSAGE_ABI_MACH | (ulong)PASSAGE_ABI_VERSION << 32;
+#else
+       return (PASSAGE_ABI_MACH & 0xffffff) | (PASSAGE_ABI_VERSION << 24);
+#endif
+}
+
+/**
+ * passage_valid() - See if standard passage was provided by the previous phase
+ *
+ * Return: true if standard passage was provided, else false
+ */
+static inline bool passage_valid(void)
+{
+#if CONFIG_IS_ENABLED(BLOBLIST_PASSAGE)
+       return gd->passage_mach == passage_mach_version();
+#else
+       return false;
+#endif
+}
+
+/* arch_passage_entry() - Jump to the next phase, using standard passage
+ *
+ * @entry_addr: Address to jump to
+ * @bloblist: Bloblist address to pass
+ * @fdt: FDT to pass
+ */
+void __noreturn arch_passage_entry(ulong entry_addr, ulong bloblist, ulong 
fdt);
+
+#endif
diff --git a/lib/asm-offsets.c b/lib/asm-offsets.c
index b6bbcbf76ca..23ee9aab47e 100644
--- a/lib/asm-offsets.c
+++ b/lib/asm-offsets.c
@@ -48,5 +48,13 @@ int main(void)
        DEFINE(GD_ENV_ADDR, offsetof(struct global_data, env_addr));
 #endif
 
+#if CONFIG_IS_ENABLED(PASSAGE_IN)
+       DEFINE(GD_PASSAGE_MACH, offsetof(struct global_data, passage_mach));
+       DEFINE(GD_PASSAGE_BLOBLIST,
+              offsetof(struct global_data, passage_bloblist));
+       DEFINE(GD_PASSAGE_DTB,
+              offsetof(struct global_data, passage_dtb));
+#endif
+
        return 0;
 }
diff --git a/scripts/Makefile.xpl b/scripts/Makefile.xpl
index 43f27874f9f..b25866e9676 100644
--- a/scripts/Makefile.xpl
+++ b/scripts/Makefile.xpl
@@ -322,7 +322,7 @@ endif
 #   - we have either OF_SEPARATE or OF_HOSTFILE
 build_dtb :=
 ifneq ($(CONFIG_$(PHASE_)OF_REAL),)
-ifneq ($(CONFIG_OF_SEPARATE)$(CONFIG_SANDBOX),)
+ifneq ($(CONFIG_OF_SEPARATE)$(CONFIG_OF_PASSAGE),$(CONFIG_SANDBOX),)
 build_dtb := y
 endif
 endif
-- 
2.43.0

Reply via email to