All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/31] passage: Define a standard for firmware data flow
@ 2021-11-01  1:17 ` Simon Glass
  0 siblings, 0 replies; 77+ messages in thread
From: Simon Glass @ 2021-11-01  1:17 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Tom Rini, Bin Meng, Ilias Apalodimas, Bill Mills,
	Heinrich Schuchardt, François Ozog, Simon Glass,
	Albert Aribaud, Jerry Van Baren, Marek Vasut, Masahiro Yamada,
	Pavel Herrmann, qemu-devel


This series adds a standard way of passing information between different
firmware phases. This already exists in U-Boot at a very basic level, in
the form of a bloblist containing an spl_handoff structure, but the intent
here is to define something useful across projects.

The need for this is growing as firmware fragments into multiple binaries
each with its own purpose. Without any run-time connection, we must rely
on build-time settings which are brittle and painful to keep in sync.

This feature is named 'standard passage' since the name is more unique
than many others that could be chosen, it is a passage in the sense that
information is flowing from one place to another and it is standard,
because that is what we want to create.

The implementation is simply a pointer to a bloblist in a register, with
an extra register to point to a devicetree, for more complex data, if one
is present in the bloblist. This should cover all cases (small memory
footprint as well as complex data flow) and be easy enough to implement on
all architectures.

The core bloblist code is relicensed to BSD-3-Clause in case it is useful
in non-GPL projects but there is no requirement to use the same code.

This series includes tweaks to the bloblist implementation in U-Boot to
make it more suitable for the task, including:

   - Allocate tags explicitly in the enum
   - Put the magic number first
   - Define a process for adding tags

The emphasis is on enabling open communcation between binaries, not
enabling passage of secret, undocumented data, although this is possible
in a private environment.

This series is built on the OF_BOARD series It is available at
u-boot-dm/pass-working or:

https://source.denx.de/u-boot/custodians/u-boot-dm/-/commit/073b5c156f222c69a98b8ebcaa563d1ff10eb217


Simon Glass (31):
  Makefile: Correct TPL rule for OF_REAL
  kconfig: Add support for conditional values
  dm: core: Allow getting some basic stats
  stddef: Avoid warning with clang with offsetof()
  fdt: Drop SPL_BUILD macro
  bloblist: Put the magic number first
  bloblist: Rename the SPL tag
  bloblist: Drop unused tags
  bloblist: Use explicit numbering for the tags
  bloblist: Support allocating the bloblist
  bloblist: Use LOG_CATEGORY to simply logging
  bloblist: Use 'phase' consistently for bloblists
  bloblist: Refactor Kconfig to support alloc or fixed
  arm: qemu: Add an SPL build
  bloblist: Add functions to obtain base address and size
  passage: Support an incoming passage
  passage: Support a control devicetree
  passage: arm: Accept a passage from the previous phase
  passage: spl: Support adding the dtb to the passage bloblist
  passage: spl: Support passing the passage to U-Boot
  passage: Record where the devicetree came from
  passage: Report the devicetree source
  passage: Add a qemu test for ARM
  bloblist: doc: Bring in the API documentation
  bloblist: Relicense to allow BSD-3-Clause
  sandbox: Add a way of checking structs for standard passage
  passage: Add documentation
  passage: Add docs for spl_handoff
  x86: Move Intel GNVS file into the common include directory
  passage: Add checks for pre-existing blobs
  WIP: RFC: Add a gitlab test

 .gitlab-ci.yml                                |   6 +
 MAINTAINERS                                   |  10 +
 Makefile                                      |   2 +-
 arch/arm/cpu/armv7/start.S                    |   7 +-
 arch/arm/dts/qemu-arm-u-boot.dtsi             |  22 ++
 arch/arm/lib/crt0.S                           |   4 +
 arch/arm/mach-qemu/Kconfig                    |   9 +
 arch/sandbox/cpu/spl.c                        |   2 +-
 arch/x86/cpu/apollolake/acpi.c                |   2 +-
 arch/x86/cpu/broadwell/cpu_from_spl.c         |   4 +-
 arch/x86/cpu/intel_common/acpi.c              |   2 +-
 .../include/asm/arch-apollolake/global_nvs.h  |   2 +-
 arch/x86/lib/spl.c                            |   2 +-
 arch/x86/lib/tpl.c                            |   2 +-
 board/emulation/qemu-arm/Kconfig              |  23 +-
 board/emulation/qemu-arm/MAINTAINERS          |   1 +
 board/emulation/qemu-arm/Makefile             |   1 +
 board/emulation/qemu-arm/spl.c                |  27 ++
 board/google/chromebook_coral/coral.c         |   2 +-
 board/sandbox/Makefile                        |   3 +-
 board/sandbox/stdpass_check.c                 | 107 ++++++
 cmd/bdinfo.c                                  |   2 +
 common/Kconfig                                | 161 ++++++++-
 common/bloblist.c                             | 124 +++++--
 common/board_f.c                              |  48 ++-
 common/board_r.c                              |  18 +
 common/spl/spl.c                              |  74 +++-
 configs/qemu_arm_spl_defconfig                |  78 +++++
 doc/board/emulation/qemu-arm.rst              |  38 +++
 doc/develop/bloblist.rst                      |  28 +-
 doc/develop/index.rst                         |   1 +
 doc/develop/std_passage.rst                   | 319 ++++++++++++++++++
 drivers/core/device.c                         |  11 +
 drivers/core/root.c                           |   7 +
 drivers/core/uclass.c                         |  13 +
 drivers/serial/serial-uclass.c                |   3 +-
 dts/Kconfig                                   |  12 +
 include/asm-generic/global_data.h             |  35 ++
 include/bloblist.h                            | 175 +++++++---
 include/dm/device.h                           |  11 +-
 include/dm/root.h                             |   8 +
 include/dm/uclass-internal.h                  |   7 +
 include/fdtdec.h                              |  40 ++-
 include/handoff.h                             |   8 +-
 .../x86/include/asm => include}/intel_gnvs.h  |   0
 include/linux/kconfig.h                       |  18 +
 include/linux/stddef.h                        |   8 +-
 include/spl.h                                 |  15 +
 include/stdpass/README                        |   4 +
 include/stdpass/tpm2_eventlog.h               |  42 +++
 include/stdpass/vboot_ctx.h                   | 267 +++++++++++++++
 lib/asm-offsets.c                             |   5 +
 lib/fdtdec.c                                  |  65 +++-
 scripts/config_whitelist.txt                  |   1 +
 test/bloblist.c                               |  21 +-
 test/dm/core.c                                |  41 +++
 test/py/tests/test_passage.py                 |  11 +
 57 files changed, 1798 insertions(+), 161 deletions(-)
 create mode 100644 arch/arm/dts/qemu-arm-u-boot.dtsi
 create mode 100644 board/emulation/qemu-arm/spl.c
 create mode 100644 board/sandbox/stdpass_check.c
 create mode 100644 configs/qemu_arm_spl_defconfig
 create mode 100644 doc/develop/std_passage.rst
 rename {arch/x86/include/asm => include}/intel_gnvs.h (100%)
 create mode 100644 include/stdpass/README
 create mode 100644 include/stdpass/tpm2_eventlog.h
 create mode 100644 include/stdpass/vboot_ctx.h
 create mode 100644 test/py/tests/test_passage.py

-- 
2.33.1.1089.g2158813163f-goog


^ permalink raw reply	[flat|nested] 77+ messages in thread

* [PATCH 00/31] passage: Define a standard for firmware data flow
@ 2021-11-01  1:17 ` Simon Glass
  0 siblings, 0 replies; 77+ messages in thread
From: Simon Glass @ 2021-11-01  1:17 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Marek Vasut, Tom Rini, Albert Aribaud, François Ozog,
	Heinrich Schuchardt, Bill Mills, Ilias Apalodimas, qemu-devel,
	Masahiro Yamada, Jerry Van Baren, Pavel Herrmann, Bin Meng,
	Simon Glass


This series adds a standard way of passing information between different
firmware phases. This already exists in U-Boot at a very basic level, in
the form of a bloblist containing an spl_handoff structure, but the intent
here is to define something useful across projects.

The need for this is growing as firmware fragments into multiple binaries
each with its own purpose. Without any run-time connection, we must rely
on build-time settings which are brittle and painful to keep in sync.

This feature is named 'standard passage' since the name is more unique
than many others that could be chosen, it is a passage in the sense that
information is flowing from one place to another and it is standard,
because that is what we want to create.

The implementation is simply a pointer to a bloblist in a register, with
an extra register to point to a devicetree, for more complex data, if one
is present in the bloblist. This should cover all cases (small memory
footprint as well as complex data flow) and be easy enough to implement on
all architectures.

The core bloblist code is relicensed to BSD-3-Clause in case it is useful
in non-GPL projects but there is no requirement to use the same code.

This series includes tweaks to the bloblist implementation in U-Boot to
make it more suitable for the task, including:

   - Allocate tags explicitly in the enum
   - Put the magic number first
   - Define a process for adding tags

The emphasis is on enabling open communcation between binaries, not
enabling passage of secret, undocumented data, although this is possible
in a private environment.

This series is built on the OF_BOARD series It is available at
u-boot-dm/pass-working or:

https://source.denx.de/u-boot/custodians/u-boot-dm/-/commit/073b5c156f222c69a98b8ebcaa563d1ff10eb217


Simon Glass (31):
  Makefile: Correct TPL rule for OF_REAL
  kconfig: Add support for conditional values
  dm: core: Allow getting some basic stats
  stddef: Avoid warning with clang with offsetof()
  fdt: Drop SPL_BUILD macro
  bloblist: Put the magic number first
  bloblist: Rename the SPL tag
  bloblist: Drop unused tags
  bloblist: Use explicit numbering for the tags
  bloblist: Support allocating the bloblist
  bloblist: Use LOG_CATEGORY to simply logging
  bloblist: Use 'phase' consistently for bloblists
  bloblist: Refactor Kconfig to support alloc or fixed
  arm: qemu: Add an SPL build
  bloblist: Add functions to obtain base address and size
  passage: Support an incoming passage
  passage: Support a control devicetree
  passage: arm: Accept a passage from the previous phase
  passage: spl: Support adding the dtb to the passage bloblist
  passage: spl: Support passing the passage to U-Boot
  passage: Record where the devicetree came from
  passage: Report the devicetree source
  passage: Add a qemu test for ARM
  bloblist: doc: Bring in the API documentation
  bloblist: Relicense to allow BSD-3-Clause
  sandbox: Add a way of checking structs for standard passage
  passage: Add documentation
  passage: Add docs for spl_handoff
  x86: Move Intel GNVS file into the common include directory
  passage: Add checks for pre-existing blobs
  WIP: RFC: Add a gitlab test

 .gitlab-ci.yml                                |   6 +
 MAINTAINERS                                   |  10 +
 Makefile                                      |   2 +-
 arch/arm/cpu/armv7/start.S                    |   7 +-
 arch/arm/dts/qemu-arm-u-boot.dtsi             |  22 ++
 arch/arm/lib/crt0.S                           |   4 +
 arch/arm/mach-qemu/Kconfig                    |   9 +
 arch/sandbox/cpu/spl.c                        |   2 +-
 arch/x86/cpu/apollolake/acpi.c                |   2 +-
 arch/x86/cpu/broadwell/cpu_from_spl.c         |   4 +-
 arch/x86/cpu/intel_common/acpi.c              |   2 +-
 .../include/asm/arch-apollolake/global_nvs.h  |   2 +-
 arch/x86/lib/spl.c                            |   2 +-
 arch/x86/lib/tpl.c                            |   2 +-
 board/emulation/qemu-arm/Kconfig              |  23 +-
 board/emulation/qemu-arm/MAINTAINERS          |   1 +
 board/emulation/qemu-arm/Makefile             |   1 +
 board/emulation/qemu-arm/spl.c                |  27 ++
 board/google/chromebook_coral/coral.c         |   2 +-
 board/sandbox/Makefile                        |   3 +-
 board/sandbox/stdpass_check.c                 | 107 ++++++
 cmd/bdinfo.c                                  |   2 +
 common/Kconfig                                | 161 ++++++++-
 common/bloblist.c                             | 124 +++++--
 common/board_f.c                              |  48 ++-
 common/board_r.c                              |  18 +
 common/spl/spl.c                              |  74 +++-
 configs/qemu_arm_spl_defconfig                |  78 +++++
 doc/board/emulation/qemu-arm.rst              |  38 +++
 doc/develop/bloblist.rst                      |  28 +-
 doc/develop/index.rst                         |   1 +
 doc/develop/std_passage.rst                   | 319 ++++++++++++++++++
 drivers/core/device.c                         |  11 +
 drivers/core/root.c                           |   7 +
 drivers/core/uclass.c                         |  13 +
 drivers/serial/serial-uclass.c                |   3 +-
 dts/Kconfig                                   |  12 +
 include/asm-generic/global_data.h             |  35 ++
 include/bloblist.h                            | 175 +++++++---
 include/dm/device.h                           |  11 +-
 include/dm/root.h                             |   8 +
 include/dm/uclass-internal.h                  |   7 +
 include/fdtdec.h                              |  40 ++-
 include/handoff.h                             |   8 +-
 .../x86/include/asm => include}/intel_gnvs.h  |   0
 include/linux/kconfig.h                       |  18 +
 include/linux/stddef.h                        |   8 +-
 include/spl.h                                 |  15 +
 include/stdpass/README                        |   4 +
 include/stdpass/tpm2_eventlog.h               |  42 +++
 include/stdpass/vboot_ctx.h                   | 267 +++++++++++++++
 lib/asm-offsets.c                             |   5 +
 lib/fdtdec.c                                  |  65 +++-
 scripts/config_whitelist.txt                  |   1 +
 test/bloblist.c                               |  21 +-
 test/dm/core.c                                |  41 +++
 test/py/tests/test_passage.py                 |  11 +
 57 files changed, 1798 insertions(+), 161 deletions(-)
 create mode 100644 arch/arm/dts/qemu-arm-u-boot.dtsi
 create mode 100644 board/emulation/qemu-arm/spl.c
 create mode 100644 board/sandbox/stdpass_check.c
 create mode 100644 configs/qemu_arm_spl_defconfig
 create mode 100644 doc/develop/std_passage.rst
 rename {arch/x86/include/asm => include}/intel_gnvs.h (100%)
 create mode 100644 include/stdpass/README
 create mode 100644 include/stdpass/tpm2_eventlog.h
 create mode 100644 include/stdpass/vboot_ctx.h
 create mode 100644 test/py/tests/test_passage.py

-- 
2.33.1.1089.g2158813163f-goog



^ permalink raw reply	[flat|nested] 77+ messages in thread

* [PATCH 01/31] Makefile: Correct TPL rule for OF_REAL
  2021-11-01  1:17 ` Simon Glass
  (?)
@ 2021-11-01  1:17 ` Simon Glass
  2021-11-01  6:54   ` Ilias Apalodimas
  2021-11-14  0:34   ` Simon Glass
  -1 siblings, 2 replies; 77+ messages in thread
From: Simon Glass @ 2021-11-01  1:17 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Tom Rini, Bin Meng, Ilias Apalodimas, Bill Mills,
	Heinrich Schuchardt, François Ozog, Simon Glass,
	Masahiro Yamada

Correct an error in the tpl-dtb parameter to binman. At present the TPL
rule follows SPL but this is not correct, if TPL uses of-platdata, for
example.

Fixes: f99cbe4e867 ("fdt: Update Makefile rules with the new OF_REAL Kconfig")
Signed-off-by: Simon Glass <sjg@chromium.org>
---

 Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Makefile b/Makefile
index 09a5cea8cb8..d256a3cdc33 100644
--- a/Makefile
+++ b/Makefile
@@ -1309,7 +1309,7 @@ cmd_binman = $(srctree)/tools/binman/binman $(if $(BINMAN_DEBUG),-D) \
 		-a spl-bss-pad=$(if $(CONFIG_SPL_SEPARATE_BSS),,1) \
 		-a tpl-bss-pad=$(if $(CONFIG_TPL_SEPARATE_BSS),,1) \
 		-a spl-dtb=$(CONFIG_SPL_OF_REAL) \
-		-a tpl-dtb=$(CONFIG_SPL_OF_REAL) \
+		-a tpl-dtb=$(CONFIG_TPL_OF_REAL) \
 		$(BINMAN_$(@F))
 
 OBJCOPYFLAGS_u-boot.ldr.hex := -I binary -O ihex
-- 
2.33.1.1089.g2158813163f-goog


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 02/31] kconfig: Add support for conditional values
  2021-11-01  1:17 ` Simon Glass
  (?)
  (?)
@ 2021-11-01  1:17 ` Simon Glass
  2021-11-01  7:05   ` Ilias Apalodimas
  -1 siblings, 1 reply; 77+ messages in thread
From: Simon Glass @ 2021-11-01  1:17 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Tom Rini, Bin Meng, Ilias Apalodimas, Bill Mills,
	Heinrich Schuchardt, François Ozog, Simon Glass,
	Masahiro Yamada

At present if an optional Kconfig value needs to be used it must be
bracketed by #ifdef. For example, with this Kconfig setup:

config WIBBLE
	bool "Support wibbles, the world needs more wibbles"

config WIBBLE_ADDR
	hex "Address of the wibble"
	depends on WIBBLE

then the following code must be used:

 #ifdef CONFIG_WIBBLE
 static void handle_wibble(void)
 {
 	int val = CONFIG_WIBBLE_ADDR;

	...
 }
 #endif

 static void init_machine()
 {
 ...
 #ifdef CONFIG_WIBBLE
	handle_wibble();
 #endif
 }

Add a new IF_ENABLED_INT() to help with this. So now it is possible to
write, without #ifdefs:

 static void handle_wibble(void)
 {
        int val = IF_ENABLED_INT(CONFIG_WIBBLE, CONFIG_WIBBLE_ADDR);

	...
 }

 static void init_machine()
 {
 ...
 if (IS_ENABLED(CONFIG_WIBBLE))
	handle_wibble();
 }

The value will be 0 if CONFIG_WIBBLE is not defined, and
CONFIG_WIBBLE_ADDR if it is. This allows us to reduce the use of #ifdef in
the code, ensuring that the compiler still checks the code even if it is
not ultimately used for a particular build.

Add a CONFIG_IF_ENABLED_INT() version as well.

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

 include/linux/kconfig.h      | 18 ++++++++++++++++++
 scripts/config_whitelist.txt |  1 +
 2 files changed, 19 insertions(+)

diff --git a/include/linux/kconfig.h b/include/linux/kconfig.h
index a1d1a298426..119c698a158 100644
--- a/include/linux/kconfig.h
+++ b/include/linux/kconfig.h
@@ -59,6 +59,18 @@
  */
 #define CONFIG_VAL(option)  config_val(option)
 
+/* This use a similar mechanism to config_enabled() above */
+#define config_opt_enabled(cfg, opt_cfg) _config_opt_enabled(cfg, opt_cfg)
+#define _config_opt_enabled(cfg_val, opt_value) \
+	__config_opt_enabled(__ARG_PLACEHOLDER_##cfg_val, opt_value)
+#define __config_opt_enabled(arg1_or_junk, arg2) \
+	___config_opt_enabled(arg1_or_junk arg2, 0)
+#define ___config_opt_enabled(__ignored, val, ...) val
+
+/* Evaluates to 0 if option is not defined, int_option if it is defined */
+#define IF_ENABLED_INT(option, int_option) \
+	config_opt_enabled(option, int_option)
+
 /*
  * Count number of arguments to a variadic macro. Currently only need
  * it for 1, 2 or 3 arguments.
@@ -113,5 +125,11 @@
 #define CONFIG_IS_ENABLED(option, ...)					\
 	__concat(__CONFIG_IS_ENABLED_, __count_args(option, ##__VA_ARGS__)) (option, ##__VA_ARGS__)
 
+/*
+ * Evaluates to 0 if SPL_/TPL_/option is not defined, SPL_/TPL_int_option if it
+ * is defined
+ */
+#define CONFIG_IF_ENABLED_INT(option, int_option) \
+	CONFIG_IS_ENABLED(option, (CONFIG_VAL(int_option)), (0))
 
 #endif /* __LINUX_KCONFIG_H */
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index 022a27288c9..f9d9f4a9cfe 100644
--- a/scripts/config_whitelist.txt
+++ b/scripts/config_whitelist.txt
@@ -609,6 +609,7 @@ CONFIG_ICS307_REFCLK_HZ
 CONFIG_IDE_PREINIT
 CONFIG_IDE_RESET
 CONFIG_IDE_SWAP_IO
+CONFIG_IF_ENABLED_INT
 CONFIG_IMA
 CONFIG_IMX
 CONFIG_IMX6_PWM_PER_CLK
-- 
2.33.1.1089.g2158813163f-goog


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 03/31] dm: core: Allow getting some basic stats
  2021-11-01  1:17 ` Simon Glass
                   ` (2 preceding siblings ...)
  (?)
@ 2021-11-01  1:17 ` Simon Glass
  2021-11-01  7:07   ` Ilias Apalodimas
  -1 siblings, 1 reply; 77+ messages in thread
From: Simon Glass @ 2021-11-01  1:17 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Tom Rini, Bin Meng, Ilias Apalodimas, Bill Mills,
	Heinrich Schuchardt, François Ozog, Simon Glass,
	Marek Vasut, Pavel Herrmann

Add a function that returns some basic stats about driver model. For now
we only have two.

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

 drivers/core/device.c        | 11 ++++++++++
 drivers/core/root.c          |  7 ++++++
 drivers/core/uclass.c        | 13 ++++++++++++
 include/dm/device.h          | 11 +++++++++-
 include/dm/root.h            |  8 +++++++
 include/dm/uclass-internal.h |  7 ++++++
 test/dm/core.c               | 41 ++++++++++++++++++++++++++++++++++++
 7 files changed, 97 insertions(+), 1 deletion(-)

diff --git a/drivers/core/device.c b/drivers/core/device.c
index d7a778a2413..7d327aba49e 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -723,6 +723,17 @@ int device_get_child_count(const struct udevice *parent)
 	return count;
 }
 
+int device_get_decendent_count(const struct udevice *parent)
+{
+	const struct udevice *dev;
+	int count = 1;
+
+	list_for_each_entry(dev, &parent->child_head, sibling_node)
+		count += device_get_decendent_count(dev);
+
+	return count;
+}
+
 int device_find_child_by_seq(const struct udevice *parent, int seq,
 			     struct udevice **devp)
 {
diff --git a/drivers/core/root.c b/drivers/core/root.c
index 26b8195faa3..815173f86eb 100644
--- a/drivers/core/root.c
+++ b/drivers/core/root.c
@@ -26,6 +26,7 @@
 #include <dm/read.h>
 #include <dm/root.h>
 #include <dm/uclass.h>
+#include <dm/uclass-internal.h>
 #include <dm/util.h>
 #include <linux/list.h>
 
@@ -407,6 +408,12 @@ int dm_init_and_scan(bool pre_reloc_only)
 	return 0;
 }
 
+void dm_get_stats(int *device_countp, int *uclass_countp)
+{
+	*device_countp = device_get_decendent_count(gd->dm_root);
+	*uclass_countp = uclass_get_count();
+}
+
 #ifdef CONFIG_ACPIGEN
 static int root_acpi_get_name(const struct udevice *dev, char *out_name)
 {
diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c
index c5a50952fd0..46b3e85fdbb 100644
--- a/drivers/core/uclass.c
+++ b/drivers/core/uclass.c
@@ -638,6 +638,19 @@ int uclass_next_device_check(struct udevice **devp)
 	return device_probe(*devp);
 }
 
+int uclass_get_count(void)
+{
+	const struct uclass *uc;
+	int count = 0;
+
+	if (gd->dm_root) {
+		list_for_each_entry(uc, gd->uclass_root, sibling_node)
+			count++;
+	}
+
+	return count;
+}
+
 int uclass_first_device_drvdata(enum uclass_id id, ulong driver_data,
 				struct udevice **devp)
 {
diff --git a/include/dm/device.h b/include/dm/device.h
index 3028d002ab0..68e783ea409 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -593,7 +593,7 @@ int device_get_child(const struct udevice *parent, int index,
 		     struct udevice **devp);
 
 /**
- * device_get_child_count() - Get the available child count of a device
+ * device_get_child_count() - Get the child count of a device
  *
  * Returns the number of children to a device.
  *
@@ -601,6 +601,15 @@ int device_get_child(const struct udevice *parent, int index,
  */
 int device_get_child_count(const struct udevice *parent);
 
+/**
+ * device_get_decendent_count() - Get the total number of decendents of a device
+ *
+ * Returns the total number of decendents, including all children
+ *
+ * @parent:	Parent device to check
+ */
+int device_get_decendent_count(const struct udevice *parent);
+
 /**
  * device_find_child_by_seq() - Find a child device based on a sequence
  *
diff --git a/include/dm/root.h b/include/dm/root.h
index 42510b106ab..780f269db65 100644
--- a/include/dm/root.h
+++ b/include/dm/root.h
@@ -131,4 +131,12 @@ int dm_remove_devices_flags(uint flags);
 static inline int dm_remove_devices_flags(uint flags) { return 0; }
 #endif
 
+/**
+ * dm_get_stats() - Get some stats for driver mode
+ *
+ * @device_countp: Returns total number of devices that are bound
+ * @uclass_countp: Returns total number of uclasses in use
+ */
+void dm_get_stats(int *device_countp, int *uclass_countp);
+
 #endif
diff --git a/include/dm/uclass-internal.h b/include/dm/uclass-internal.h
index 57c664c6daa..c71d8b1de45 100644
--- a/include/dm/uclass-internal.h
+++ b/include/dm/uclass-internal.h
@@ -294,6 +294,13 @@ int uclass_pre_remove_device(struct udevice *dev);
 static inline int uclass_pre_remove_device(struct udevice *dev) { return 0; }
 #endif
 
+/**
+ * uclass_get_count() - Get the number of uclasses
+ *
+ * Returns the number of uclasses instantiated in driver model
+ */
+int uclass_get_count(void);
+
 /**
  * uclass_find() - Find uclass by its id
  *
diff --git a/test/dm/core.c b/test/dm/core.c
index c9a7606666c..c76dfdb1651 100644
--- a/test/dm/core.c
+++ b/test/dm/core.c
@@ -307,11 +307,15 @@ static int dm_test_lifecycle(struct unit_test_state *uts)
 {
 	int op_count[DM_TEST_OP_COUNT];
 	struct udevice *dev, *test_dev;
+	int start_dev_count, start_uc_count;
+	int dev_count, uc_count;
 	int pingret;
 	int ret;
 
 	memcpy(op_count, dm_testdrv_op_count, sizeof(op_count));
 
+	dm_get_stats(&start_dev_count, &start_uc_count);
+
 	ut_assertok(device_bind_by_name(uts->root, false, &driver_info_manual,
 					&dev));
 	ut_assert(dev);
@@ -319,6 +323,11 @@ static int dm_test_lifecycle(struct unit_test_state *uts)
 			== op_count[DM_TEST_OP_BIND] + 1);
 	ut_assert(!dev_get_priv(dev));
 
+	/* We should have one more device */
+	dm_get_stats(&dev_count, &uc_count);
+	ut_asserteq(start_dev_count + 1, dev_count);
+	ut_asserteq(start_uc_count, uc_count);
+
 	/* Probe the device - it should fail allocating private data */
 	uts->force_fail_alloc = 1;
 	ret = device_probe(dev);
@@ -353,6 +362,11 @@ static int dm_test_lifecycle(struct unit_test_state *uts)
 	ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_UNBIND]);
 	ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_PRE_UNBIND]);
 
+	/* We should have one less device */
+	dm_get_stats(&dev_count, &uc_count);
+	ut_asserteq(start_dev_count, dev_count);
+	ut_asserteq(start_uc_count, uc_count);
+
 	return 0;
 }
 DM_TEST(dm_test_lifecycle, UT_TESTF_SCAN_PDATA | UT_TESTF_PROBE_TEST);
@@ -526,17 +540,31 @@ DM_TEST(dm_test_leak, 0);
 /* Test uclass init/destroy methods */
 static int dm_test_uclass(struct unit_test_state *uts)
 {
+	int dev_count, uc_count;
 	struct uclass *uc;
 
+	/* We should have just the root device and uclass */
+	dm_get_stats(&dev_count, &uc_count);
+	ut_asserteq(1, dev_count);
+	ut_asserteq(1, uc_count);
+
 	ut_assertok(uclass_get(UCLASS_TEST, &uc));
 	ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_INIT]);
 	ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_DESTROY]);
 	ut_assert(uclass_get_priv(uc));
 
+	dm_get_stats(&dev_count, &uc_count);
+	ut_asserteq(1, dev_count);
+	ut_asserteq(2, uc_count);
+
 	ut_assertok(uclass_destroy(uc));
 	ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_INIT]);
 	ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_DESTROY]);
 
+	dm_get_stats(&dev_count, &uc_count);
+	ut_asserteq(1, dev_count);
+	ut_asserteq(1, uc_count);
+
 	return 0;
 }
 DM_TEST(dm_test_uclass, 0);
@@ -1217,3 +1245,16 @@ static int dm_test_dma_offset(struct unit_test_state *uts)
 }
 DM_TEST(dm_test_dma_offset, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
 #endif
+
+/* Test dm_get_stats() */
+static int dm_test_get_stats(struct unit_test_state *uts)
+{
+	int dev_count, uc_count;
+
+	dm_get_stats(&dev_count, &uc_count);
+	ut_assert(dev_count > 50);
+	ut_assert(uc_count > 30);
+
+	return 0;
+}
+DM_TEST(dm_test_get_stats, UT_TESTF_SCAN_FDT);
-- 
2.33.1.1089.g2158813163f-goog


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 04/31] stddef: Avoid warning with clang with offsetof()
  2021-11-01  1:17 ` Simon Glass
                   ` (3 preceding siblings ...)
  (?)
@ 2021-11-01  1:17 ` Simon Glass
  2022-01-13  8:08   ` Rasmus Villemoes
  -1 siblings, 1 reply; 77+ messages in thread
From: Simon Glass @ 2021-11-01  1:17 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Tom Rini, Bin Meng, Ilias Apalodimas, Bill Mills,
	Heinrich Schuchardt, François Ozog, Simon Glass

Some bright sparks have decided that a cast on a constant cannot be a
constant, so offsetof() produces this warning on clang-10:

include/intel_gnvs.h:113:1: error: static_assert expression is not an
	integral constant expression
check_member(acpi_global_nvs, unused2, GNVS_CHROMEOS_ACPI_OFFSET);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/kernel.h:284:2: note: expanded from macro 'check_member'
        offsetof(struct structure, member) == (offset), \
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/stddef.h:20:32: note: expanded from macro 'offsetof'
                                ^
include/intel_gnvs.h:113:1: note: cast that performs the conversions of
	a reinterpret_cast is ot allowed in a constant expression
include/linux/stddef.h:20:33: note: expanded from macro 'offsetof'

Fix it by using the compiler built-in version, if available.

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

 include/linux/stddef.h | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/include/linux/stddef.h b/include/linux/stddef.h
index c540f6100d4..a7f546fdfe5 100644
--- a/include/linux/stddef.h
+++ b/include/linux/stddef.h
@@ -1,6 +1,8 @@
 #ifndef _LINUX_STDDEF_H
 #define _LINUX_STDDEF_H
 
+#include <linux/compiler_types.h>
+
 #undef NULL
 #if defined(__cplusplus)
 #define NULL 0
@@ -14,7 +16,11 @@
 
 #ifndef __CHECKER__
 #undef offsetof
-#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#ifdef __compiler_offsetof
+#define offsetof(TYPE, MEMBER)	__compiler_offsetof(TYPE, MEMBER)
+#else
+#define offsetof(TYPE, MEMBER)	((size_t)&((TYPE *)0)->MEMBER)
+#endif
 #endif
 
 #endif
-- 
2.33.1.1089.g2158813163f-goog


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 05/31] fdt: Drop SPL_BUILD macro
  2021-11-01  1:17 ` Simon Glass
                   ` (4 preceding siblings ...)
  (?)
@ 2021-11-01  1:17 ` Simon Glass
  2021-11-01  7:42   ` Ilias Apalodimas
  -1 siblings, 1 reply; 77+ messages in thread
From: Simon Glass @ 2021-11-01  1:17 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Tom Rini, Bin Meng, Ilias Apalodimas, Bill Mills,
	Heinrich Schuchardt, François Ozog, Simon Glass,
	Jerry Van Baren

This old macro is not needed anymore since we can use IS_ENABLED() now.
Drop it.

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

 drivers/serial/serial-uclass.c | 3 ++-
 include/fdtdec.h               | 6 ------
 2 files changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c
index 30d44214d7d..96a1cb65ba2 100644
--- a/drivers/serial/serial-uclass.c
+++ b/drivers/serial/serial-uclass.c
@@ -104,7 +104,8 @@ static void serial_find_console_or_panic(void)
 			}
 		}
 	}
-	if (!SPL_BUILD || !CONFIG_IS_ENABLED(OF_CONTROL) || !blob) {
+	if (!IS_ENABLED(CONFIG_SPL_BUILD) || !CONFIG_IS_ENABLED(OF_CONTROL) ||
+	    !blob) {
 		/*
 		 * Try to use CONFIG_CONS_INDEX if available (it is numbered
 		 * from 1!).
diff --git a/include/fdtdec.h b/include/fdtdec.h
index 68a36f10583..24992baed8b 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -49,12 +49,6 @@ struct fdt_memory {
 
 struct bd_info;
 
-#ifdef CONFIG_SPL_BUILD
-#define SPL_BUILD	1
-#else
-#define SPL_BUILD	0
-#endif
-
 /*
  * Information about a resource. start is the first address of the resource
  * and end is the last address (inclusive). The length of the resource will
-- 
2.33.1.1089.g2158813163f-goog


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 06/31] bloblist: Put the magic number first
  2021-11-01  1:17 ` Simon Glass
                   ` (5 preceding siblings ...)
  (?)
@ 2021-11-01  1:17 ` Simon Glass
  -1 siblings, 0 replies; 77+ messages in thread
From: Simon Glass @ 2021-11-01  1:17 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Tom Rini, Bin Meng, Ilias Apalodimas, Bill Mills,
	Heinrich Schuchardt, François Ozog, Simon Glass

It seems best to put the magic number right at the start of the bloblist
header, so it is easier to check. This is how devicetree works.

Make this change now, before other projects make use of bloblist. Other
changes may be needed / discussed, but that is TBD.

Add a checker function as well.

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

 include/bloblist.h | 25 +++++++++++++++++++++++--
 test/bloblist.c    |  7 +++++++
 2 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/include/bloblist.h b/include/bloblist.h
index 9f007c7a94d..29ea5a768a6 100644
--- a/include/bloblist.h
+++ b/include/bloblist.h
@@ -13,6 +13,8 @@
 #ifndef __BLOBLIST_H
 #define __BLOBLIST_H
 
+#include <mapmem.h>
+
 enum {
 	BLOBLIST_VERSION	= 0,
 	BLOBLIST_MAGIC		= 0xb00757a3,
@@ -59,11 +61,11 @@ enum bloblist_tag_t {
  * Each bloblist record is aligned to a 16-byte boundary and follows immediately
  * from the last.
  *
+ * @magic: BLOBLIST_MAGIC
  * @version: BLOBLIST_VERSION
  * @hdr_size: Size of this header, normally sizeof(struct bloblist_hdr). The
  *	first bloblist_rec starts at this offset from the start of the header
  * @flags: Space for BLOBLISTF_... flags (none yet)
- * @magic: BLOBLIST_MAGIC
  * @size: Total size of the bloblist (non-zero if valid) including this header.
  *	The bloblist extends for this many bytes from the start of this header.
  *	When adding new records, the bloblist can grow up to this size.
@@ -78,10 +80,10 @@ enum bloblist_tag_t {
  *	calculation.
  */
 struct bloblist_hdr {
+	u32 magic;
 	u32 version;
 	u32 hdr_size;
 	u32 flags;
-	u32 magic;
 
 	u32 size;
 	u32 alloced;
@@ -111,6 +113,25 @@ struct bloblist_rec {
 	u32 spare;
 };
 
+/**
+ * bloblist_check_magic() - return a bloblist if the magic matches
+ *
+ * @addr: Address to check
+ * @return pointer to bloblist, if the magic matches, else NULL
+ */
+static inline void *bloblist_check_magic(ulong addr)
+{
+	u32 *ptr;
+
+	if (!addr)
+		return NULL;
+	ptr = map_sysmem(addr, 0);
+	if (*ptr != BLOBLIST_MAGIC)
+		return NULL;
+
+	return ptr;
+}
+
 /**
  * bloblist_find() - Find a blob
  *
diff --git a/test/bloblist.c b/test/bloblist.c
index b48be38dc3e..525e94b7217 100644
--- a/test/bloblist.c
+++ b/test/bloblist.c
@@ -71,7 +71,9 @@ static int bloblist_test_init(struct unit_test_state *uts)
 
 	hdr = clear_bloblist();
 	ut_asserteq(-ENOENT, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
+	ut_asserteq_ptr(NULL, bloblist_check_magic(TEST_ADDR));
 	ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
+	ut_asserteq_ptr(hdr, bloblist_check_magic(TEST_ADDR));
 	hdr->version++;
 	ut_asserteq(-EPROTONOSUPPORT, bloblist_check(TEST_ADDR,
 						     TEST_BLOBLIST_SIZE));
@@ -83,6 +85,11 @@ static int bloblist_test_init(struct unit_test_state *uts)
 	ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
 	ut_assertok(bloblist_finish());
 	ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
+
+	hdr->magic++;
+	ut_asserteq_ptr(NULL, bloblist_check_magic(TEST_ADDR));
+	hdr->magic--;
+
 	hdr->flags++;
 	ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
 
-- 
2.33.1.1089.g2158813163f-goog


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 07/31] bloblist: Rename the SPL tag
  2021-11-01  1:17 ` Simon Glass
                   ` (6 preceding siblings ...)
  (?)
@ 2021-11-01  1:17 ` Simon Glass
  -1 siblings, 0 replies; 77+ messages in thread
From: Simon Glass @ 2021-11-01  1:17 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Tom Rini, Bin Meng, Ilias Apalodimas, Bill Mills,
	Heinrich Schuchardt, François Ozog, Simon Glass

Add a U_BOOT prefix to this tag since it is specific to the U-Boot
project.

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

 arch/x86/cpu/broadwell/cpu_from_spl.c | 4 ++--
 common/bloblist.c                     | 2 +-
 common/board_f.c                      | 2 +-
 common/spl/spl.c                      | 4 ++--
 include/bloblist.h                    | 2 +-
 5 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/x86/cpu/broadwell/cpu_from_spl.c b/arch/x86/cpu/broadwell/cpu_from_spl.c
index e5f62e7187c..df5a9675ee4 100644
--- a/arch/x86/cpu/broadwell/cpu_from_spl.c
+++ b/arch/x86/cpu/broadwell/cpu_from_spl.c
@@ -23,7 +23,7 @@ int dram_init(void)
 {
 	struct spl_handoff *ho;
 
-	ho = bloblist_find(BLOBLISTT_SPL_HANDOFF, sizeof(*ho));
+	ho = bloblist_find(BLOBLISTT_U_BOOT_SPL_HANDOFF, sizeof(*ho));
 	if (!ho)
 		return log_msg_ret("Missing SPL hand-off info", -ENOENT);
 	handoff_load_dram_size(ho);
@@ -56,7 +56,7 @@ int dram_init_banksize(void)
 {
 	struct spl_handoff *ho;
 
-	ho = bloblist_find(BLOBLISTT_SPL_HANDOFF, sizeof(*ho));
+	ho = bloblist_find(BLOBLISTT_U_BOOT_SPL_HANDOFF, sizeof(*ho));
 	if (!ho)
 		return log_msg_ret("Missing SPL hand-off info", -ENOENT);
 	handoff_load_dram_banks(ho);
diff --git a/common/bloblist.c b/common/bloblist.c
index 1290fff8504..557e892c854 100644
--- a/common/bloblist.c
+++ b/common/bloblist.c
@@ -31,7 +31,7 @@ DECLARE_GLOBAL_DATA_PTR;
 static const char *const tag_name[] = {
 	[BLOBLISTT_NONE]		= "(none)",
 	[BLOBLISTT_EC_HOSTEVENT]	= "EC host event",
-	[BLOBLISTT_SPL_HANDOFF]		= "SPL hand-off",
+	[BLOBLISTT_U_BOOT_SPL_HANDOFF]		= "SPL hand-off",
 	[BLOBLISTT_VBOOT_CTX]		= "Chrome OS vboot context",
 	[BLOBLISTT_VBOOT_HANDOFF]	= "Chrome OS vboot hand-off",
 	[BLOBLISTT_ACPI_GNVS]		= "ACPI GNVS",
diff --git a/common/board_f.c b/common/board_f.c
index 3dc0eaa59c5..261d0f52cd7 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -283,7 +283,7 @@ static int setup_mon_len(void)
 static int setup_spl_handoff(void)
 {
 #if CONFIG_IS_ENABLED(HANDOFF)
-	gd->spl_handoff = bloblist_find(BLOBLISTT_SPL_HANDOFF,
+	gd->spl_handoff = bloblist_find(BLOBLISTT_U_BOOT_SPL_HANDOFF,
 					sizeof(struct spl_handoff));
 	debug("Found SPL hand-off info %p\n", gd->spl_handoff);
 #endif
diff --git a/common/spl/spl.c b/common/spl/spl.c
index 0c08da06e8f..55e33d2fc44 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -408,7 +408,7 @@ static int setup_spl_handoff(void)
 {
 	struct spl_handoff *ho;
 
-	ho = bloblist_ensure(BLOBLISTT_SPL_HANDOFF, sizeof(struct spl_handoff));
+	ho = bloblist_ensure(BLOBLISTT_U_BOOT_SPL_HANDOFF, sizeof(struct spl_handoff));
 	if (!ho)
 		return -ENOENT;
 
@@ -425,7 +425,7 @@ static int write_spl_handoff(void)
 	struct spl_handoff *ho;
 	int ret;
 
-	ho = bloblist_find(BLOBLISTT_SPL_HANDOFF, sizeof(struct spl_handoff));
+	ho = bloblist_find(BLOBLISTT_U_BOOT_SPL_HANDOFF, sizeof(struct spl_handoff));
 	if (!ho)
 		return -ENOENT;
 	handoff_save_dram(ho);
diff --git a/include/bloblist.h b/include/bloblist.h
index 29ea5a768a6..d4d48f76ff4 100644
--- a/include/bloblist.h
+++ b/include/bloblist.h
@@ -27,7 +27,7 @@ enum bloblist_tag_t {
 
 	/* Vendor-specific tags are permitted here */
 	BLOBLISTT_EC_HOSTEVENT,		/* Chromium OS EC host-event mask */
-	BLOBLISTT_SPL_HANDOFF,		/* Hand-off info from SPL */
+	BLOBLISTT_U_BOOT_SPL_HANDOFF,		/* Hand-off info from SPL */
 	BLOBLISTT_VBOOT_CTX,		/* Chromium OS verified boot context */
 	BLOBLISTT_VBOOT_HANDOFF,	/* Chromium OS internal handoff info */
 	/*
-- 
2.33.1.1089.g2158813163f-goog


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 08/31] bloblist: Drop unused tags
  2021-11-01  1:17 ` Simon Glass
                   ` (7 preceding siblings ...)
  (?)
@ 2021-11-01  1:17 ` Simon Glass
  -1 siblings, 0 replies; 77+ messages in thread
From: Simon Glass @ 2021-11-01  1:17 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Tom Rini, Bin Meng, Ilias Apalodimas, Bill Mills,
	Heinrich Schuchardt, François Ozog, Simon Glass

The EC event log tag is no-longer used. The vboot handoff is now handled
by the vboot context instead.

Drop these unused tags.

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

 common/bloblist.c  | 4 +---
 include/bloblist.h | 2 --
 test/bloblist.c    | 4 ++--
 3 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/common/bloblist.c b/common/bloblist.c
index 557e892c854..2418241193a 100644
--- a/common/bloblist.c
+++ b/common/bloblist.c
@@ -30,10 +30,8 @@ DECLARE_GLOBAL_DATA_PTR;
 
 static const char *const tag_name[] = {
 	[BLOBLISTT_NONE]		= "(none)",
-	[BLOBLISTT_EC_HOSTEVENT]	= "EC host event",
-	[BLOBLISTT_U_BOOT_SPL_HANDOFF]		= "SPL hand-off",
+	[BLOBLISTT_U_BOOT_SPL_HANDOFF]	= "SPL hand-off",
 	[BLOBLISTT_VBOOT_CTX]		= "Chrome OS vboot context",
-	[BLOBLISTT_VBOOT_HANDOFF]	= "Chrome OS vboot hand-off",
 	[BLOBLISTT_ACPI_GNVS]		= "ACPI GNVS",
 	[BLOBLISTT_INTEL_VBT]		= "Intel Video-BIOS table",
 	[BLOBLISTT_TPM2_TCG_LOG]	= "TPM v2 log space",
diff --git a/include/bloblist.h b/include/bloblist.h
index d4d48f76ff4..fac25907c07 100644
--- a/include/bloblist.h
+++ b/include/bloblist.h
@@ -26,10 +26,8 @@ enum bloblist_tag_t {
 	BLOBLISTT_NONE = 0,
 
 	/* Vendor-specific tags are permitted here */
-	BLOBLISTT_EC_HOSTEVENT,		/* Chromium OS EC host-event mask */
 	BLOBLISTT_U_BOOT_SPL_HANDOFF,		/* Hand-off info from SPL */
 	BLOBLISTT_VBOOT_CTX,		/* Chromium OS verified boot context */
-	BLOBLISTT_VBOOT_HANDOFF,	/* Chromium OS internal handoff info */
 	/*
 	 * Advanced Configuration and Power Interface Global Non-Volatile
 	 * Sleeping table. This forms part of the ACPI tables passed to Linux.
diff --git a/test/bloblist.c b/test/bloblist.c
index 525e94b7217..2e8e23d77dd 100644
--- a/test/bloblist.c
+++ b/test/bloblist.c
@@ -289,9 +289,9 @@ static int bloblist_test_cmd_list(struct unit_test_state *uts)
 	console_record_reset();
 	run_command("bloblist list", 0);
 	ut_assert_nextline("Address       Size  Tag Name");
-	ut_assert_nextline("%08lx  %8x    1 EC host event",
+	ut_assert_nextline("%08lx  %8x    1 SPL hand-off",
 			   (ulong)map_to_sysmem(data), TEST_SIZE);
-	ut_assert_nextline("%08lx  %8x    2 SPL hand-off",
+	ut_assert_nextline("%08lx  %8x    2 Chrome OS vboot context",
 			   (ulong)map_to_sysmem(data2), TEST_SIZE2);
 	ut_assert_console_end();
 	ut_unsilence_console(uts);
-- 
2.33.1.1089.g2158813163f-goog


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 09/31] bloblist: Use explicit numbering for the tags
  2021-11-01  1:17 ` Simon Glass
                   ` (8 preceding siblings ...)
  (?)
@ 2021-11-01  1:17 ` Simon Glass
  -1 siblings, 0 replies; 77+ messages in thread
From: Simon Glass @ 2021-11-01  1:17 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Tom Rini, Bin Meng, Ilias Apalodimas, Bill Mills,
	Heinrich Schuchardt, François Ozog, Simon Glass

At present if someone adds a tag in the middle of the list it works well
enough within a U-Boot build. But if these tags are used in another
project, or with an older version of SPL, the numbers make become
inconsistent.

Use explicit tag numbers that never change, to resolve this problem.
Allocate areas for existing U-Boot tags and set up an area for use by
projects and vendors, as well as for private use. Keep tags above
0x10000 unallocated for now.

Update bloblist_tag_name() and the tests to work with this new setup.

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

 common/bloblist.c  | 45 +++++++++++++++++++++++------------
 include/bloblist.h | 58 +++++++++++++++++++++++++++++++++++++---------
 test/bloblist.c    | 12 +++++-----
 3 files changed, 83 insertions(+), 32 deletions(-)

diff --git a/common/bloblist.c b/common/bloblist.c
index 2418241193a..4a04e66576e 100644
--- a/common/bloblist.c
+++ b/common/bloblist.c
@@ -28,24 +28,39 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-static const char *const tag_name[] = {
-	[BLOBLISTT_NONE]		= "(none)",
-	[BLOBLISTT_U_BOOT_SPL_HANDOFF]	= "SPL hand-off",
-	[BLOBLISTT_VBOOT_CTX]		= "Chrome OS vboot context",
-	[BLOBLISTT_ACPI_GNVS]		= "ACPI GNVS",
-	[BLOBLISTT_INTEL_VBT]		= "Intel Video-BIOS table",
-	[BLOBLISTT_TPM2_TCG_LOG]	= "TPM v2 log space",
-	[BLOBLISTT_TCPA_LOG]		= "TPM log space",
-	[BLOBLISTT_ACPI_TABLES]		= "ACPI tables for x86",
-	[BLOBLISTT_SMBIOS_TABLES]	= "SMBIOS tables for x86",
+static struct tag_name {
+	enum bloblist_tag_t tag;
+	const char *name;
+} tag_name[] = {
+	{ BLOBLISTT_NONE, "(none)" },
+
+	/* BLOBLISTT_AREA_FIRMWARE_TOP */
+
+	/* BLOBLISTT_AREA_FIRMWARE */
+	{ BLOBLISTT_ACPI_GNVS, "ACPI GNVS" },
+	{ BLOBLISTT_INTEL_VBT, "Intel Video-BIOS table" },
+	{ BLOBLISTT_TPM2_TCG_LOG, "TPM v2 log space" },
+	{ BLOBLISTT_TCPA_LOG, "TPM log space" },
+	{ BLOBLISTT_ACPI_TABLES, "ACPI tables for x86" },
+	{ BLOBLISTT_SMBIOS_TABLES, "SMBIOS tables for x86" },
+	{ BLOBLISTT_VBOOT_CTX, "Chrome OS vboot context" },
+
+	/* BLOBLISTT_PROJECT_AREA */
+	{ BLOBLISTT_U_BOOT_SPL_HANDOFF, "SPL hand-off" },
+
+	/* BLOBLISTT_VENDOR_AREA */
 };
 
 const char *bloblist_tag_name(enum bloblist_tag_t tag)
 {
-	if (tag < 0 || tag >= BLOBLISTT_COUNT)
-		return "invalid";
+	int i;
 
-	return tag_name[tag];
+	for (i = 0; i < ARRAY_SIZE(tag_name); i++) {
+		if (tag_name[i].tag == tag)
+			return tag_name[i].name;
+	}
+
+	return "invalid";
 }
 
 static struct bloblist_rec *bloblist_first_blob(struct bloblist_hdr *hdr)
@@ -380,10 +395,10 @@ void bloblist_show_list(void)
 	struct bloblist_hdr *hdr = gd->bloblist;
 	struct bloblist_rec *rec;
 
-	printf("%-8s  %8s  Tag Name\n", "Address", "Size");
+	printf("%-8s  %8s   Tag Name\n", "Address", "Size");
 	for (rec = bloblist_first_blob(hdr); rec;
 	     rec = bloblist_next_blob(hdr, rec)) {
-		printf("%08lx  %8x  %3d %s\n",
+		printf("%08lx  %8x  %4x %s\n",
 		       (ulong)map_to_sysmem((void *)rec + rec->hdr_size),
 		       rec->size, rec->tag, bloblist_tag_name(rec->tag));
 	}
diff --git a/include/bloblist.h b/include/bloblist.h
index fac25907c07..5de4545160e 100644
--- a/include/bloblist.h
+++ b/include/bloblist.h
@@ -25,21 +25,57 @@ enum {
 enum bloblist_tag_t {
 	BLOBLISTT_NONE = 0,
 
-	/* Vendor-specific tags are permitted here */
-	BLOBLISTT_U_BOOT_SPL_HANDOFF,		/* Hand-off info from SPL */
-	BLOBLISTT_VBOOT_CTX,		/* Chromium OS verified boot context */
+	/*
+	 * Standard area to allocate blobs used across firmware components, for
+	 * things that are very commonly used, particularly in multiple
+	 * projects.
+	 */
+	BLOBLISTT_AREA_FIRMWARE_TOP = 0x1,
+
+	/* Standard area to allocate blobs used across firmware components */
+	BLOBLISTT_AREA_FIRMWARE = 0x100,
 	/*
 	 * Advanced Configuration and Power Interface Global Non-Volatile
 	 * Sleeping table. This forms part of the ACPI tables passed to Linux.
 	 */
-	BLOBLISTT_ACPI_GNVS,
-	BLOBLISTT_INTEL_VBT,		/* Intel Video-BIOS table */
-	BLOBLISTT_TPM2_TCG_LOG,		/* TPM v2 log space */
-	BLOBLISTT_TCPA_LOG,		/* TPM log space */
-	BLOBLISTT_ACPI_TABLES,		/* ACPI tables for x86 */
-	BLOBLISTT_SMBIOS_TABLES,	/* SMBIOS tables for x86 */
-
-	BLOBLISTT_COUNT
+	BLOBLISTT_ACPI_GNVS = 0x100,
+	BLOBLISTT_INTEL_VBT = 0x101,	/* Intel Video-BIOS table */
+	BLOBLISTT_TPM2_TCG_LOG = 0x102,	/* TPM v2 log space */
+	BLOBLISTT_TCPA_LOG = 0x103,	/* TPM log space */
+	BLOBLISTT_ACPI_TABLES = 0x104,	/* ACPI tables for x86 */
+	BLOBLISTT_SMBIOS_TABLES = 0x105, /* SMBIOS tables for x86 */
+	BLOBLISTT_VBOOT_CTX = 0x106,	/* Chromium OS verified boot context */
+
+	/*
+	 * Project-specific tags are permitted here. Projects can be open source
+	 * or not, but the format of the data must be fuily documented in an
+	 * open source project, including all fields, bits, etc. Naming should
+	 * be: BLOBLISTT_<project>_<purpose_here>
+	 */
+	BLOBLISTT_PROJECT_AREA = 0x8000,
+	BLOBLISTT_U_BOOT_SPL_HANDOFF = 0x8000, /* Hand-off info from SPL */
+
+	/*
+	 * Vendor-specific tags are permitted here. Projects can be open source
+	 * or not, but the format of the data must be fuily documented in an
+	 * open source project, including all fields, bits, etc. Naming should
+	 * be BLOBLISTT_<vendor>_<purpose_here>
+	 */
+	BLOBLISTT_VENDOR_AREA = 0xc000,
+
+	/* Tags after this are not allocated for now */
+	BLOBLISTT_EXPANSION = 0x10000,
+
+	/*
+	 * Tags from here are on reserved for private use within a single
+	 * firmware binary (i.e. a single executable or phase of a project).
+	 * These tags can be passed between binaries within a local
+	 * implementation, but cannot be used in upstream code. Allocate a
+	 * tag in one of the areas above if you want that.
+	 *
+	 * This area may move in future.
+	 */
+	BLOBLISTT_PRIVATE_AREA = 0xffff0000,
 };
 
 /**
diff --git a/test/bloblist.c b/test/bloblist.c
index 2e8e23d77dd..c5788d5cd82 100644
--- a/test/bloblist.c
+++ b/test/bloblist.c
@@ -19,9 +19,9 @@ DECLARE_GLOBAL_DATA_PTR;
 		UNIT_TEST(_name, _flags, bloblist_test)
 
 enum {
-	TEST_TAG		= 1,
-	TEST_TAG2		= 2,
-	TEST_TAG_MISSING	= 3,
+	TEST_TAG		= BLOBLISTT_U_BOOT_SPL_HANDOFF,
+	TEST_TAG2		= BLOBLISTT_VBOOT_CTX,
+	TEST_TAG_MISSING	= 0x10000,
 
 	TEST_SIZE		= 10,
 	TEST_SIZE2		= 20,
@@ -288,10 +288,10 @@ static int bloblist_test_cmd_list(struct unit_test_state *uts)
 	ut_silence_console(uts);
 	console_record_reset();
 	run_command("bloblist list", 0);
-	ut_assert_nextline("Address       Size  Tag Name");
-	ut_assert_nextline("%08lx  %8x    1 SPL hand-off",
+	ut_assert_nextline("Address       Size   Tag Name");
+	ut_assert_nextline("%08lx  %8x  8000 SPL hand-off",
 			   (ulong)map_to_sysmem(data), TEST_SIZE);
-	ut_assert_nextline("%08lx  %8x    2 Chrome OS vboot context",
+	ut_assert_nextline("%08lx  %8x   106 Chrome OS vboot context",
 			   (ulong)map_to_sysmem(data2), TEST_SIZE2);
 	ut_assert_console_end();
 	ut_unsilence_console(uts);
-- 
2.33.1.1089.g2158813163f-goog


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 10/31] bloblist: Support allocating the bloblist
  2021-11-01  1:17 ` Simon Glass
                   ` (9 preceding siblings ...)
  (?)
@ 2021-11-01  1:17 ` Simon Glass
  -1 siblings, 0 replies; 77+ messages in thread
From: Simon Glass @ 2021-11-01  1:17 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Tom Rini, Bin Meng, Ilias Apalodimas, Bill Mills,
	Heinrich Schuchardt, François Ozog, Simon Glass

Typically the bloblist is positioned at a fixed address in memory until
relocation. This is convenient when it is set up in SPL or before
relocation.

But for EFI we want to set it up only when U-Boot proper is running. Add
a way to allocate it using malloc() and update the documentation to cover
this aspect of bloblist.

Note there are no tests of this feature at present, nor any direct testing
of bloblist_init().

This can be added, e.g. by making this option controllable at runtime.

A test that uses sandbox_spl is possible but will need some more plumbing,
to come later. A qemu test for ARM is included later in this series.

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

 common/Kconfig           | 15 +++++++++++++--
 common/bloblist.c        | 16 ++++++++++++++--
 common/board_f.c         |  8 +++++++-
 doc/develop/bloblist.rst | 16 ++++++++++++++++
 4 files changed, 50 insertions(+), 5 deletions(-)

diff --git a/common/Kconfig b/common/Kconfig
index d6f77ab7b9c..00ccaf59fa4 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -719,6 +719,8 @@ config TPL_BLOBLIST
 	  This enables a bloblist in TPL. The bloblist is set up in TPL and
 	  passed to SPL and U-Boot proper.
 
+if BLOBLIST
+
 config BLOBLIST_SIZE
 	hex "Size of bloblist"
 	depends on BLOBLIST
@@ -729,17 +731,24 @@ config BLOBLIST_SIZE
 	  is set up in the first part of U-Boot to run (TPL, SPL or U-Boot
 	  proper), and this sane bloblist is used for subsequent stages.
 
+config BLOBLIST_ALLOC
+	bool "Allocate bloblist"
+	help
+	  Allocate the bloblist using malloc(). This avoids the need to
+	  specify a fixed address on systems where this is unknown or can
+	  change at runtime.
+
 config BLOBLIST_ADDR
 	hex "Address of bloblist"
-	depends on BLOBLIST
 	default 0xc000 if SANDBOX
 	help
 	  Sets the address of the bloblist, set up by the first part of U-Boot
 	  which runs. Subsequent U-Boot stages typically use the same address.
 
+	  This is not used if BLOBLIST_ALLOC is selected.
+
 config BLOBLIST_SIZE_RELOC
 	hex "Size of bloblist after relocation"
-	depends on BLOBLIST
 	default BLOBLIST_SIZE
 	help
 	  Sets the size of the bloblist in bytes after relocation. Since U-Boot
@@ -747,6 +756,8 @@ config BLOBLIST_SIZE_RELOC
 	  size than the one set up by SPL. This bloblist is set up during the
 	  relocation process.
 
+endif # BLOBLIST
+
 endmenu
 
 source "common/spl/Kconfig"
diff --git a/common/bloblist.c b/common/bloblist.c
index 4a04e66576e..baf1d371b71 100644
--- a/common/bloblist.c
+++ b/common/bloblist.c
@@ -7,6 +7,7 @@
 #include <common.h>
 #include <bloblist.h>
 #include <log.h>
+#include <malloc.h>
 #include <mapmem.h>
 #include <spl.h>
 #include <asm/global_data.h>
@@ -429,10 +430,21 @@ int bloblist_init(void)
 		ret = bloblist_check(CONFIG_BLOBLIST_ADDR,
 				     CONFIG_BLOBLIST_SIZE);
 	if (ret) {
+		ulong addr;
+
 		log(LOGC_BLOBLIST, expected ? LOGL_WARNING : LOGL_DEBUG,
 		    "Existing bloblist not found: creating new bloblist\n");
-		ret = bloblist_new(CONFIG_BLOBLIST_ADDR, CONFIG_BLOBLIST_SIZE,
-				   0);
+		if (IS_ENABLED(CONFIG_BLOBLIST_ALLOC)) {
+			void *ptr = memalign(BLOBLIST_ALIGN,
+					     CONFIG_BLOBLIST_SIZE);
+
+			if (!ptr)
+				return log_msg_ret("alloc", -ENOMEM);
+			addr = map_to_sysmem(ptr);
+		} else {
+			addr = CONFIG_BLOBLIST_ADDR;
+		}
+		ret = bloblist_new(addr, CONFIG_BLOBLIST_SIZE, 0);
 	} else {
 		log(LOGC_BLOBLIST, LOGL_DEBUG, "Found existing bloblist\n");
 	}
diff --git a/common/board_f.c b/common/board_f.c
index 261d0f52cd7..14e9286a70f 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -655,8 +655,14 @@ static int reloc_bootstage(void)
 static int reloc_bloblist(void)
 {
 #ifdef CONFIG_BLOBLIST
-	if (gd->flags & GD_FLG_SKIP_RELOC)
+	/*
+	 * Relocate only if we are supposed to send it
+	 */
+	if ((gd->flags & GD_FLG_SKIP_RELOC) &&
+	    CONFIG_BLOBLIST_SIZE == CONFIG_BLOBLIST_SIZE_RELOC) {
+		debug("Not relocating bloblist\n");
 		return 0;
+	}
 	if (gd->new_bloblist) {
 		int size = CONFIG_BLOBLIST_SIZE;
 
diff --git a/doc/develop/bloblist.rst b/doc/develop/bloblist.rst
index 317ebc4919d..47274cf8e26 100644
--- a/doc/develop/bloblist.rst
+++ b/doc/develop/bloblist.rst
@@ -59,6 +59,22 @@ Bloblist provides a fairly simple API which allows blobs to be created and
 found. All access is via the blob's tag. Blob records are zeroed when added.
 
 
+Placing the bloblist
+--------------------
+
+The bloblist is typically positioned at a fixed address by TPL, or SPL. This
+is controlled by `CONFIG_BLOBLIST_ADDR`. But in some cases it is preferable to
+allocate the bloblist in the malloc() space. Use the `CONFIG_BLOBLIST_ALLOC`
+option to enable this.
+
+The bloblist is automatically relocated as part of U-Boot relocation. Sometimes
+it is useful to expand the bloblist in U-Boot proper, since it may want to add
+information for use by Linux. Note that this does not mean that Linux needs to
+know anything about the bloblist format, just that it is convenient to use
+bloblist to place things contiguously in memory. Set
+`CONFIG_BLOBLIST_SIZE_RELOC` to define the expanded size, if needed.
+
+
 Finishing the bloblist
 ----------------------
 
-- 
2.33.1.1089.g2158813163f-goog


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 11/31] bloblist: Use LOG_CATEGORY to simply logging
  2021-11-01  1:17 ` Simon Glass
                   ` (10 preceding siblings ...)
  (?)
@ 2021-11-01  1:17 ` Simon Glass
  -1 siblings, 0 replies; 77+ messages in thread
From: Simon Glass @ 2021-11-01  1:17 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Tom Rini, Bin Meng, Ilias Apalodimas, Bill Mills,
	Heinrich Schuchardt, François Ozog, Simon Glass

Use the convenience functions to improve readability.

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

 common/bloblist.c | 21 ++++++++++-----------
 1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/common/bloblist.c b/common/bloblist.c
index baf1d371b71..b5fea12b697 100644
--- a/common/bloblist.c
+++ b/common/bloblist.c
@@ -4,6 +4,8 @@
  * Written by Simon Glass <sjg@chromium.org>
  */
 
+#define LOG_CATEGORY	LOGC_BLOBLIST
+
 #include <common.h>
 #include <bloblist.h>
 #include <log.h>
@@ -133,9 +135,8 @@ static int bloblist_addrec(uint tag, int size, int align,
 	new_alloced = data_start + ALIGN(size, align);
 
 	if (new_alloced > hdr->size) {
-		log(LOGC_BLOBLIST, LOGL_ERR,
-		    "Failed to allocate %x bytes size=%x, need size=%x\n",
-		    size, hdr->size, new_alloced);
+		log_err("Failed to allocate %x bytes size=%x, need size=%x\n",
+			size, hdr->size, new_alloced);
 		return log_msg_ret("bloblist add", -ENOSPC);
 	}
 	rec = (void *)hdr + hdr->alloced;
@@ -249,14 +250,13 @@ static int bloblist_resize_rec(struct bloblist_hdr *hdr,
 	expand_by = ALIGN(new_size - rec->size, BLOBLIST_ALIGN);
 	new_alloced = ALIGN(hdr->alloced + expand_by, BLOBLIST_ALIGN);
 	if (new_size < 0) {
-		log(LOGC_BLOBLIST, LOGL_DEBUG,
-		    "Attempt to shrink blob size below 0 (%x)\n", new_size);
+		log_debug("Attempt to shrink blob size below 0 (%x)\n",
+			  new_size);
 		return log_msg_ret("size", -EINVAL);
 	}
 	if (new_alloced > hdr->size) {
-		log(LOGC_BLOBLIST, LOGL_ERR,
-		    "Failed to allocate %x bytes size=%x, need size=%x\n",
-		    new_size, hdr->size, new_alloced);
+		log_err("Failed to allocate %x bytes size=%x, need size=%x\n",
+			new_size, hdr->size, new_alloced);
 		return log_msg_ret("alloc", -ENOSPC);
 	}
 
@@ -347,8 +347,7 @@ int bloblist_check(ulong addr, uint size)
 		return log_msg_ret("Bad size", -EFBIG);
 	chksum = bloblist_calc_chksum(hdr);
 	if (hdr->chksum != chksum) {
-		log(LOGC_BLOBLIST, LOGL_ERR, "Checksum %x != %x\n", hdr->chksum,
-		    chksum);
+		log_err("Checksum %x != %x\n", hdr->chksum, chksum);
 		return log_msg_ret("Bad checksum", -EIO);
 	}
 	gd->bloblist = hdr;
@@ -446,7 +445,7 @@ int bloblist_init(void)
 		}
 		ret = bloblist_new(addr, CONFIG_BLOBLIST_SIZE, 0);
 	} else {
-		log(LOGC_BLOBLIST, LOGL_DEBUG, "Found existing bloblist\n");
+		log_debug("Found existing bloblist\n");
 	}
 
 	return ret;
-- 
2.33.1.1089.g2158813163f-goog


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 12/31] bloblist: Use 'phase' consistently for bloblists
  2021-11-01  1:17 ` Simon Glass
                   ` (11 preceding siblings ...)
  (?)
@ 2021-11-01  1:17 ` Simon Glass
  -1 siblings, 0 replies; 77+ messages in thread
From: Simon Glass @ 2021-11-01  1:17 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Tom Rini, Bin Meng, Ilias Apalodimas, Bill Mills,
	Heinrich Schuchardt, François Ozog, Simon Glass

We typically refer to the different U-Boot builds that a board runs
through as phases. This avoids confusion with the word 'stage' which is
used with bootstage, for example. Fix up some bloblist Kconfig help
which uses the wrong term.

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

 common/Kconfig | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/common/Kconfig b/common/Kconfig
index 00ccaf59fa4..4cf1831f599 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -700,7 +700,7 @@ config BLOBLIST
 	  from TPL to SPL to U-Boot proper (and potentially to Linux). The
 	  blob list supports multiple binary blobs of data, each with a tag,
 	  so that different U-Boot components can store data which can survive
-	  through to the next stage of the boot.
+	  through to the next phase of the boot.
 
 config SPL_BLOBLIST
 	bool "Support for a bloblist in SPL"
@@ -729,7 +729,7 @@ config BLOBLIST_SIZE
 	  Sets the size of the bloblist in bytes. This must include all
 	  overhead (alignment, bloblist header, record header). The bloblist
 	  is set up in the first part of U-Boot to run (TPL, SPL or U-Boot
-	  proper), and this sane bloblist is used for subsequent stages.
+	  proper), and this sane bloblist is used for subsequent phases.
 
 config BLOBLIST_ALLOC
 	bool "Allocate bloblist"
@@ -743,7 +743,7 @@ config BLOBLIST_ADDR
 	default 0xc000 if SANDBOX
 	help
 	  Sets the address of the bloblist, set up by the first part of U-Boot
-	  which runs. Subsequent U-Boot stages typically use the same address.
+	  which runs. Subsequent U-Boot phases typically use the same address.
 
 	  This is not used if BLOBLIST_ALLOC is selected.
 
-- 
2.33.1.1089.g2158813163f-goog


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 13/31] bloblist: Refactor Kconfig to support alloc or fixed
  2021-11-01  1:17 ` Simon Glass
                   ` (12 preceding siblings ...)
  (?)
@ 2021-11-01  1:17 ` Simon Glass
  -1 siblings, 0 replies; 77+ messages in thread
From: Simon Glass @ 2021-11-01  1:17 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Tom Rini, Bin Meng, Ilias Apalodimas, Bill Mills,
	Heinrich Schuchardt, François Ozog, Simon Glass

At present we do support allocating the bloblist but the Kconfig is a bit
strange, since we still have to specify an address in that case. Partly
this is because it is a pain to have CONFIG options that disappears when
its dependency is enabled. It means that we must have #ifdefs in the code,
either in the C code or header file.

Make use of IF_ENABLED_INT() and its friend to solve that problem, so we
can separate out the location of bloblist into a choice. Put the address
and size into variables so we can log the result.

Add the options for SPL as well, so we can use CONFIG_IS_ENABLED().

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

 common/Kconfig    | 91 ++++++++++++++++++++++++++++++++++++++++++-----
 common/bloblist.c | 39 ++++++++++++--------
 2 files changed, 106 insertions(+), 24 deletions(-)

diff --git a/common/Kconfig b/common/Kconfig
index 4cf1831f599..2c6f5901c8a 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -721,15 +721,17 @@ config TPL_BLOBLIST
 
 if BLOBLIST
 
-config BLOBLIST_SIZE
-	hex "Size of bloblist"
-	depends on BLOBLIST
-	default 0x400
+choice
+	prompt "Bloblist location"
 	help
-	  Sets the size of the bloblist in bytes. This must include all
-	  overhead (alignment, bloblist header, record header). The bloblist
-	  is set up in the first part of U-Boot to run (TPL, SPL or U-Boot
-	  proper), and this sane bloblist is used for subsequent phases.
+	  Select the location of the bloblist, via various means.
+
+config BLOBLIST_FIXED
+	bool "Place bloblist at a fixed address in memory"
+	help
+	  Select this to used a fixed memory address for the bloblist. If the
+	  bloblist exists at this address from a previous phase, it used as is.
+	  If not it is created at this address in U-Boot.
 
 config BLOBLIST_ALLOC
 	bool "Allocate bloblist"
@@ -738,18 +740,31 @@ config BLOBLIST_ALLOC
 	  specify a fixed address on systems where this is unknown or can
 	  change at runtime.
 
+endchoice
+
 config BLOBLIST_ADDR
 	hex "Address of bloblist"
 	default 0xc000 if SANDBOX
+	depends on BLOBLIST_FIXED
 	help
 	  Sets the address of the bloblist, set up by the first part of U-Boot
 	  which runs. Subsequent U-Boot phases typically use the same address.
 
 	  This is not used if BLOBLIST_ALLOC is selected.
 
+config BLOBLIST_SIZE
+	hex "Size of bloblist"
+	default 0x400
+	help
+	  Sets the size of the bloblist in bytes. This must include all
+	  overhead (alignment, bloblist header, record header). The bloblist
+	  is set up in the first part of U-Boot to run (TPL, SPL or U-Boot
+	  proper), and this sane bloblist is used for subsequent phases.
+
 config BLOBLIST_SIZE_RELOC
 	hex "Size of bloblist after relocation"
-	default BLOBLIST_SIZE
+	default BLOBLIST_SIZE if BLOBLIST_FIXED || BLOBLIST_ALLOC
+	default 0 if BLOBLIST_PASSAGE
 	help
 	  Sets the size of the bloblist in bytes after relocation. Since U-Boot
 	  has a lot more memory available then, it is possible to use a larger
@@ -758,6 +773,64 @@ config BLOBLIST_SIZE_RELOC
 
 endif # BLOBLIST
 
+if SPL_BLOBLIST
+
+choice
+	prompt "Bloblist location in SPL"
+	help
+	  Select the location of the bloblist, via various means. Typically
+	  you should use the same value for SPL as for U-Boot, since they need
+	  to look in the same place. But if BLOBLIST_ALLOC is used, then a
+	  fresh bloblist will be created each time, since there is no shared
+	  address (between phases) for the bloblist.
+
+config SPL_BLOBLIST_FIXED
+	bool "Place bloblist at a fixed address in memory"
+	help
+	  Select this to used a fixed memory address for the bloblist. If the
+	  bloblist exists at this address from a previous phase, it used as is.
+	  If not it is created at this address in SPL.
+
+config SPL_BLOBLIST_ALLOC
+	bool "Allocate bloblist"
+	help
+	  Allocate the bloblist using malloc(). This avoids the need to
+	  specify a fixed address on systems where this is unknown or can
+	  change at runtime.
+
+endchoice
+
+endif # SPL_BLOBLIST
+
+if TPL_BLOBLIST
+
+choice
+	prompt "Bloblist location in TPL"
+	help
+	  Select the location of the bloblist, via various means. Typically
+	  you should use the same value for SPL as for U-Boot, since they need
+	  to look in the same place. But if BLOBLIST_ALLOC is used, then a
+	  fresh bloblist will be created each time, since there is no shared
+	  address (between phases) for the bloblist.
+
+config TPL_BLOBLIST_FIXED
+	bool "Place bloblist at a fixed address in memory"
+	help
+	  Select this to used a fixed memory address for the bloblist. If the
+	  bloblist exists at this address from a previous phase, it used as is.
+	  If not it is created at this address in TPL.
+
+config TPL_BLOBLIST_ALLOC
+	bool "Allocate bloblist"
+	help
+	  Allocate the bloblist using malloc(). This avoids the need to
+	  specify a fixed address on systems where this is unknown or can
+	  change at runtime.
+
+endchoice
+
+endif # TPL_BLOBLIST
+
 endmenu
 
 source "common/spl/Kconfig"
diff --git a/common/bloblist.c b/common/bloblist.c
index b5fea12b697..6e7f813db94 100644
--- a/common/bloblist.c
+++ b/common/bloblist.c
@@ -4,6 +4,7 @@
  * Written by Simon Glass <sjg@chromium.org>
  */
 
+#define LOG_DEBUG
 #define LOG_CATEGORY	LOGC_BLOBLIST
 
 #include <common.h>
@@ -360,6 +361,8 @@ int bloblist_finish(void)
 	struct bloblist_hdr *hdr = gd->bloblist;
 
 	hdr->chksum = bloblist_calc_chksum(hdr);
+	log_debug("Finished bloblist size %lx at %lx\n", (ulong)hdr->size,
+		  (ulong)map_to_sysmem(hdr));
 
 	return 0;
 }
@@ -415,8 +418,9 @@ void bloblist_reloc(void *to, uint to_size, void *from, uint from_size)
 
 int bloblist_init(void)
 {
-	bool expected;
 	int ret = -ENOENT;
+	ulong addr, size;
+	bool expected;
 
 	/**
 	 * Wed expect to find an existing bloblist in the first phase of U-Boot
@@ -425,27 +429,32 @@ int bloblist_init(void)
 	expected = !u_boot_first_phase();
 	if (spl_prev_phase() == PHASE_TPL && !IS_ENABLED(CONFIG_TPL_BLOBLIST))
 		expected = false;
-	if (expected)
-		ret = bloblist_check(CONFIG_BLOBLIST_ADDR,
-				     CONFIG_BLOBLIST_SIZE);
+	addr = IF_ENABLED_INT(CONFIG_BLOBLIST_FIXED, CONFIG_BLOBLIST_ADDR);
+	size = CONFIG_BLOBLIST_SIZE;
+	if (expected) {
+		ret = bloblist_check(addr, size);
+		if (ret) {
+			log_warning("Expected bloblist at %lx not found (err=%d)\n",
+				    addr, ret);
+		} else {
+			/* Get the real size, if it is not what we expected */
+			size = gd->bloblist->size;
+		}
+	}
 	if (ret) {
-		ulong addr;
-
-		log(LOGC_BLOBLIST, expected ? LOGL_WARNING : LOGL_DEBUG,
-		    "Existing bloblist not found: creating new bloblist\n");
-		if (IS_ENABLED(CONFIG_BLOBLIST_ALLOC)) {
-			void *ptr = memalign(BLOBLIST_ALIGN,
-					     CONFIG_BLOBLIST_SIZE);
+		if (CONFIG_IS_ENABLED(BLOBLIST_ALLOC)) {
+			void *ptr = memalign(BLOBLIST_ALIGN, size);
 
 			if (!ptr)
 				return log_msg_ret("alloc", -ENOMEM);
 			addr = map_to_sysmem(ptr);
-		} else {
-			addr = CONFIG_BLOBLIST_ADDR;
 		}
-		ret = bloblist_new(addr, CONFIG_BLOBLIST_SIZE, 0);
+		log_debug("Creating new bloblist size %lx at %lx\n", size,
+			  addr);
+		ret = bloblist_new(addr, size, 0);
 	} else {
-		log_debug("Found existing bloblist\n");
+		log_debug("Found existing bloblist size %lx at %lx\n", size,
+			  addr);
 	}
 
 	return ret;
-- 
2.33.1.1089.g2158813163f-goog


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 14/31] arm: qemu: Add an SPL build
  2021-11-01  1:17 ` Simon Glass
@ 2021-11-01  1:17   ` Simon Glass
  -1 siblings, 0 replies; 77+ messages in thread
From: Simon Glass @ 2021-11-01  1:17 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Tom Rini, Albert Aribaud, François Ozog,
	Heinrich Schuchardt, Bill Mills, Ilias Apalodimas, qemu-devel,
	Bin Meng, Simon Glass

Add an SPL build for qemu so we can test the standard passage feature.

Include a binman definition so that SPL and U-Boot are in the same image.

For now this just boots to a prompt.

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

 arch/arm/dts/qemu-arm-u-boot.dtsi    | 22 +++++++++
 arch/arm/mach-qemu/Kconfig           |  9 ++++
 board/emulation/qemu-arm/Kconfig     | 23 +++++++--
 board/emulation/qemu-arm/MAINTAINERS |  1 +
 board/emulation/qemu-arm/Makefile    |  1 +
 board/emulation/qemu-arm/spl.c       | 27 +++++++++++
 configs/qemu_arm_spl_defconfig       | 72 ++++++++++++++++++++++++++++
 doc/board/emulation/qemu-arm.rst     | 38 +++++++++++++++
 8 files changed, 189 insertions(+), 4 deletions(-)
 create mode 100644 arch/arm/dts/qemu-arm-u-boot.dtsi
 create mode 100644 board/emulation/qemu-arm/spl.c
 create mode 100644 configs/qemu_arm_spl_defconfig

diff --git a/arch/arm/dts/qemu-arm-u-boot.dtsi b/arch/arm/dts/qemu-arm-u-boot.dtsi
new file mode 100644
index 00000000000..2c5c7df62b4
--- /dev/null
+++ b/arch/arm/dts/qemu-arm-u-boot.dtsi
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Sample device tree for qemu_arm
+
+ * Copyright 2021 Google LLC
+ */
+
+/ {
+	binman {
+		u-boot-spl {
+			size = <0x10000>;
+		};
+
+		u-boot {
+		};
+	};
+
+	pl011@9000000 {
+		u-boot,dm-spl;
+	};
+
+};
diff --git a/arch/arm/mach-qemu/Kconfig b/arch/arm/mach-qemu/Kconfig
index 186c3582ebf..ab0651ce0b1 100644
--- a/arch/arm/mach-qemu/Kconfig
+++ b/arch/arm/mach-qemu/Kconfig
@@ -20,6 +20,15 @@ config TARGET_QEMU_ARM_32BIT
 	select CPU_V7A
 	select SYS_ARCH_TIMER
 
+config TARGET_QEMU_ARM_32BIT_SPL
+	bool "ARMv7-A, 32bit with SPL"
+	select ARCH_SUPPORT_PSCI
+	select BOARD_LATE_INIT
+	select CPU_V7A
+	select SYS_ARCH_TIMER
+	select SPL
+	select BINMAN
+
 config TARGET_QEMU_ARM_64BIT
 	bool "ARMv8, 64bit"
 	select ARM64
diff --git a/board/emulation/qemu-arm/Kconfig b/board/emulation/qemu-arm/Kconfig
index 95dbefa78ba..85fbe7a9a35 100644
--- a/board/emulation/qemu-arm/Kconfig
+++ b/board/emulation/qemu-arm/Kconfig
@@ -1,12 +1,10 @@
-if TARGET_QEMU_ARM_32BIT || TARGET_QEMU_ARM_64BIT
-
-config SYS_TEXT_BASE
-	default 0x00000000
+if ARCH_QEMU
 
 config BOARD_SPECIFIC_OPTIONS # dummy
 	def_bool y
 	select CMD_QFW
 	select QFW_MMIO
+	select SUPPORT_SPL
 	imply VIRTIO_MMIO
 	imply VIRTIO_PCI
 	imply VIRTIO_NET
@@ -14,6 +12,13 @@ config BOARD_SPECIFIC_OPTIONS # dummy
 
 endif
 
+if TARGET_QEMU_ARM_32BIT || TARGET_QEMU_ARM_64BIT
+
+config SYS_TEXT_BASE
+	default 0x00000000
+
+endif
+
 if TARGET_QEMU_ARM_64BIT && !TFABOOT
 config BOARD_SPECIFIC_OPTIONS
 	imply SYS_MTDPARTS_RUNTIME
@@ -21,3 +26,13 @@ config BOARD_SPECIFIC_OPTIONS
 
 source "board/emulation/common/Kconfig"
 endif
+
+if TARGET_QEMU_ARM_32BIT_SPL
+
+config SPL_TEXT_BASE
+	default 0x00000000
+
+config SYS_TEXT_BASE
+	default 0x00010000
+
+endif
diff --git a/board/emulation/qemu-arm/MAINTAINERS b/board/emulation/qemu-arm/MAINTAINERS
index e757ffc64f1..b79d4ab85b2 100644
--- a/board/emulation/qemu-arm/MAINTAINERS
+++ b/board/emulation/qemu-arm/MAINTAINERS
@@ -4,4 +4,5 @@ S:	Maintained
 F:	board/emulation/qemu-arm/
 F:	include/configs/qemu-arm.h
 F:	configs/qemu_arm_defconfig
+F:	configs/qemu_arm_spl_defconfig
 F:	configs/qemu_arm64_defconfig
diff --git a/board/emulation/qemu-arm/Makefile b/board/emulation/qemu-arm/Makefile
index a22d1237ff4..54635646e07 100644
--- a/board/emulation/qemu-arm/Makefile
+++ b/board/emulation/qemu-arm/Makefile
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0+
 
 obj-y	+= qemu-arm.o
+obj-$(CONFIG_SPL_BUILD)	+= spl.o
diff --git a/board/emulation/qemu-arm/spl.c b/board/emulation/qemu-arm/spl.c
new file mode 100644
index 00000000000..785177a6c8d
--- /dev/null
+++ b/board/emulation/qemu-arm/spl.c
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2021 Google LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <common.h>
+#include <cpu_func.h>
+#include <spl.h>
+#include <asm/spl.h>
+
+u32 spl_boot_device(void)
+{
+	return BOOT_DEVICE_BOARD;
+}
+
+static int spl_qemu_load_image(struct spl_image_info *spl_image,
+			       struct spl_boot_device *bootdev)
+{
+	spl_image->name = "U-Boot";
+	spl_image->load_addr = spl_get_image_pos();
+	spl_image->entry_point = spl_get_image_pos();
+	flush_cache(spl_image->load_addr, spl_get_image_size());
+
+	return 0;
+}
+SPL_LOAD_IMAGE_METHOD("QEMU", 0, BOOT_DEVICE_BOARD, spl_qemu_load_image);
diff --git a/configs/qemu_arm_spl_defconfig b/configs/qemu_arm_spl_defconfig
new file mode 100644
index 00000000000..a6950584542
--- /dev/null
+++ b/configs/qemu_arm_spl_defconfig
@@ -0,0 +1,72 @@
+CONFIG_ARM=y
+CONFIG_SYS_ICACHE_OFF=y
+CONFIG_SYS_DCACHE_OFF=y
+CONFIG_ARM_SMCCC=y
+CONFIG_ARCH_QEMU=y
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_ENV_SIZE=0x40000
+CONFIG_ENV_SECT_SIZE=0x40000
+CONFIG_SYS_MALLOC_LEN=0x1000000
+CONFIG_DEFAULT_DEVICE_TREE="qemu-arm"
+CONFIG_TARGET_QEMU_ARM_32BIT_SPL=y
+CONFIG_SPL_SERIAL=y
+CONFIG_DEBUG_UART_BASE=0x9000000
+CONFIG_DEBUG_UART_CLOCK=0
+CONFIG_ARMV7_LPAE=y
+CONFIG_DEBUG_UART=y
+CONFIG_AHCI=y
+CONFIG_DISTRO_DEFAULTS=y
+CONFIG_SYS_LOAD_ADDR=0x40200000
+CONFIG_FIT=y
+CONFIG_FIT_SIGNATURE=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_FIT_BEST_MATCH=y
+CONFIG_LEGACY_IMAGE_FORMAT=y
+CONFIG_USE_PREBOOT=y
+# CONFIG_DISPLAY_CPUINFO is not set
+# CONFIG_DISPLAY_BOARDINFO is not set
+CONFIG_PCI_INIT_R=y
+CONFIG_SPL_FRAMEWORK_BOARD_INIT_F=y
+CONFIG_CMD_BOOTEFI_SELFTEST=y
+CONFIG_CMD_NVEDIT_EFI=y
+CONFIG_CMD_DFU=y
+CONFIG_CMD_MTD=y
+CONFIG_CMD_PCI=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_MTDPARTS=y
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_OF_BOARD=y
+CONFIG_ENV_IS_IN_FLASH=y
+CONFIG_ENV_ADDR=0x4000000
+CONFIG_SPL_DM=y
+CONFIG_SCSI_AHCI=y
+CONFIG_AHCI_PCI=y
+CONFIG_DFU_TFTP=y
+CONFIG_DFU_MTD=y
+CONFIG_DFU_RAM=y
+# CONFIG_MMC is not set
+CONFIG_MTD=y
+CONFIG_DM_MTD=y
+CONFIG_MTD_NOR_FLASH=y
+CONFIG_CFI_FLASH=y
+CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y
+CONFIG_FLASH_CFI_MTD=y
+CONFIG_SYS_FLASH_CFI=y
+CONFIG_DM_ETH=y
+CONFIG_E1000=y
+CONFIG_NVME=y
+CONFIG_PCI=y
+CONFIG_PCIE_ECAM_GENERIC=y
+CONFIG_SCSI=y
+CONFIG_DM_SCSI=y
+CONFIG_DEBUG_UART_PL011=y
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_SYSRESET=y
+CONFIG_SPL_SYSRESET=y
+CONFIG_SYSRESET_PSCI=y
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_PCI=y
+# CONFIG_BINMAN_FDT is not set
diff --git a/doc/board/emulation/qemu-arm.rst b/doc/board/emulation/qemu-arm.rst
index a39df046fc3..aa05d0a5afe 100644
--- a/doc/board/emulation/qemu-arm.rst
+++ b/doc/board/emulation/qemu-arm.rst
@@ -38,6 +38,11 @@ Set the CROSS_COMPILE environment variable as usual, and run:
     make qemu_arm64_defconfig
     make
 
+- for ARM with SPL::
+
+    make qemu_arm_spl_defconfig
+    make
+
 Running U-Boot
 --------------
 The minimal QEMU command line to get U-Boot up and running is:
@@ -50,6 +55,10 @@ The minimal QEMU command line to get U-Boot up and running is:
 
     qemu-system-aarch64 -machine virt -nographic -cpu cortex-a57 -bios u-boot.bin
 
+- For ARM with SPL::
+
+    qemu-system-arm -machine virt -nographic -bios image.bin
+
 Note that for some odd reason qemu-system-aarch64 needs to be explicitly
 told to use a 64-bit CPU or it will boot in 32-bit mode. The -nographic argument
 ensures that output appears on the terminal. Use Ctrl-A X to quit.
@@ -85,6 +94,35 @@ can be enabled with the following command line parameters:
 
 These have been tested in QEMU 2.9.0 but should work in at least 2.5.0 as well.
 
+SPL Description
+---------------
+
+As you see above, running the SPL build is a little different, since there are
+two binaries to load into memory: SPL and U-Boot proper. Binman is used to
+produce the combined `image.bin` containing these. See
+`arch/arm/dts/qemu-arm-u-boot.dtsi` for the definition. A custom loader called
+`spl_qemu_load_image()` is used to access the U-Boot binary from within SPL.
+
+A sample run is shown below::
+
+    U-Boot SPL 2021.10 (Oct 28 2021 - 20:57:27 -0600)
+    Trying to boot from QEMU
+
+
+    U-Boot 2021.10 (Oct 28 2021 - 20:57:27 -0600)
+
+    DRAM:  128 MiB
+    Flash: 64 MiB
+    Loading Environment from Flash... *** Warning - bad CRC, using default environment
+
+    In:    pl011@9000000
+    Out:   pl011@9000000
+    Err:   pl011@9000000
+    Net:   eth0: virtio-net#32
+    Hit any key to stop autoboot:  0
+    =>
+
+
 Debug UART
 ----------
 
-- 
2.33.1.1089.g2158813163f-goog



^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 14/31] arm: qemu: Add an SPL build
@ 2021-11-01  1:17   ` Simon Glass
  0 siblings, 0 replies; 77+ messages in thread
From: Simon Glass @ 2021-11-01  1:17 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Tom Rini, Bin Meng, Ilias Apalodimas, Bill Mills,
	Heinrich Schuchardt, François Ozog, Simon Glass,
	Albert Aribaud, qemu-devel

Add an SPL build for qemu so we can test the standard passage feature.

Include a binman definition so that SPL and U-Boot are in the same image.

For now this just boots to a prompt.

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

 arch/arm/dts/qemu-arm-u-boot.dtsi    | 22 +++++++++
 arch/arm/mach-qemu/Kconfig           |  9 ++++
 board/emulation/qemu-arm/Kconfig     | 23 +++++++--
 board/emulation/qemu-arm/MAINTAINERS |  1 +
 board/emulation/qemu-arm/Makefile    |  1 +
 board/emulation/qemu-arm/spl.c       | 27 +++++++++++
 configs/qemu_arm_spl_defconfig       | 72 ++++++++++++++++++++++++++++
 doc/board/emulation/qemu-arm.rst     | 38 +++++++++++++++
 8 files changed, 189 insertions(+), 4 deletions(-)
 create mode 100644 arch/arm/dts/qemu-arm-u-boot.dtsi
 create mode 100644 board/emulation/qemu-arm/spl.c
 create mode 100644 configs/qemu_arm_spl_defconfig

diff --git a/arch/arm/dts/qemu-arm-u-boot.dtsi b/arch/arm/dts/qemu-arm-u-boot.dtsi
new file mode 100644
index 00000000000..2c5c7df62b4
--- /dev/null
+++ b/arch/arm/dts/qemu-arm-u-boot.dtsi
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Sample device tree for qemu_arm
+
+ * Copyright 2021 Google LLC
+ */
+
+/ {
+	binman {
+		u-boot-spl {
+			size = <0x10000>;
+		};
+
+		u-boot {
+		};
+	};
+
+	pl011@9000000 {
+		u-boot,dm-spl;
+	};
+
+};
diff --git a/arch/arm/mach-qemu/Kconfig b/arch/arm/mach-qemu/Kconfig
index 186c3582ebf..ab0651ce0b1 100644
--- a/arch/arm/mach-qemu/Kconfig
+++ b/arch/arm/mach-qemu/Kconfig
@@ -20,6 +20,15 @@ config TARGET_QEMU_ARM_32BIT
 	select CPU_V7A
 	select SYS_ARCH_TIMER
 
+config TARGET_QEMU_ARM_32BIT_SPL
+	bool "ARMv7-A, 32bit with SPL"
+	select ARCH_SUPPORT_PSCI
+	select BOARD_LATE_INIT
+	select CPU_V7A
+	select SYS_ARCH_TIMER
+	select SPL
+	select BINMAN
+
 config TARGET_QEMU_ARM_64BIT
 	bool "ARMv8, 64bit"
 	select ARM64
diff --git a/board/emulation/qemu-arm/Kconfig b/board/emulation/qemu-arm/Kconfig
index 95dbefa78ba..85fbe7a9a35 100644
--- a/board/emulation/qemu-arm/Kconfig
+++ b/board/emulation/qemu-arm/Kconfig
@@ -1,12 +1,10 @@
-if TARGET_QEMU_ARM_32BIT || TARGET_QEMU_ARM_64BIT
-
-config SYS_TEXT_BASE
-	default 0x00000000
+if ARCH_QEMU
 
 config BOARD_SPECIFIC_OPTIONS # dummy
 	def_bool y
 	select CMD_QFW
 	select QFW_MMIO
+	select SUPPORT_SPL
 	imply VIRTIO_MMIO
 	imply VIRTIO_PCI
 	imply VIRTIO_NET
@@ -14,6 +12,13 @@ config BOARD_SPECIFIC_OPTIONS # dummy
 
 endif
 
+if TARGET_QEMU_ARM_32BIT || TARGET_QEMU_ARM_64BIT
+
+config SYS_TEXT_BASE
+	default 0x00000000
+
+endif
+
 if TARGET_QEMU_ARM_64BIT && !TFABOOT
 config BOARD_SPECIFIC_OPTIONS
 	imply SYS_MTDPARTS_RUNTIME
@@ -21,3 +26,13 @@ config BOARD_SPECIFIC_OPTIONS
 
 source "board/emulation/common/Kconfig"
 endif
+
+if TARGET_QEMU_ARM_32BIT_SPL
+
+config SPL_TEXT_BASE
+	default 0x00000000
+
+config SYS_TEXT_BASE
+	default 0x00010000
+
+endif
diff --git a/board/emulation/qemu-arm/MAINTAINERS b/board/emulation/qemu-arm/MAINTAINERS
index e757ffc64f1..b79d4ab85b2 100644
--- a/board/emulation/qemu-arm/MAINTAINERS
+++ b/board/emulation/qemu-arm/MAINTAINERS
@@ -4,4 +4,5 @@ S:	Maintained
 F:	board/emulation/qemu-arm/
 F:	include/configs/qemu-arm.h
 F:	configs/qemu_arm_defconfig
+F:	configs/qemu_arm_spl_defconfig
 F:	configs/qemu_arm64_defconfig
diff --git a/board/emulation/qemu-arm/Makefile b/board/emulation/qemu-arm/Makefile
index a22d1237ff4..54635646e07 100644
--- a/board/emulation/qemu-arm/Makefile
+++ b/board/emulation/qemu-arm/Makefile
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0+
 
 obj-y	+= qemu-arm.o
+obj-$(CONFIG_SPL_BUILD)	+= spl.o
diff --git a/board/emulation/qemu-arm/spl.c b/board/emulation/qemu-arm/spl.c
new file mode 100644
index 00000000000..785177a6c8d
--- /dev/null
+++ b/board/emulation/qemu-arm/spl.c
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2021 Google LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <common.h>
+#include <cpu_func.h>
+#include <spl.h>
+#include <asm/spl.h>
+
+u32 spl_boot_device(void)
+{
+	return BOOT_DEVICE_BOARD;
+}
+
+static int spl_qemu_load_image(struct spl_image_info *spl_image,
+			       struct spl_boot_device *bootdev)
+{
+	spl_image->name = "U-Boot";
+	spl_image->load_addr = spl_get_image_pos();
+	spl_image->entry_point = spl_get_image_pos();
+	flush_cache(spl_image->load_addr, spl_get_image_size());
+
+	return 0;
+}
+SPL_LOAD_IMAGE_METHOD("QEMU", 0, BOOT_DEVICE_BOARD, spl_qemu_load_image);
diff --git a/configs/qemu_arm_spl_defconfig b/configs/qemu_arm_spl_defconfig
new file mode 100644
index 00000000000..a6950584542
--- /dev/null
+++ b/configs/qemu_arm_spl_defconfig
@@ -0,0 +1,72 @@
+CONFIG_ARM=y
+CONFIG_SYS_ICACHE_OFF=y
+CONFIG_SYS_DCACHE_OFF=y
+CONFIG_ARM_SMCCC=y
+CONFIG_ARCH_QEMU=y
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_ENV_SIZE=0x40000
+CONFIG_ENV_SECT_SIZE=0x40000
+CONFIG_SYS_MALLOC_LEN=0x1000000
+CONFIG_DEFAULT_DEVICE_TREE="qemu-arm"
+CONFIG_TARGET_QEMU_ARM_32BIT_SPL=y
+CONFIG_SPL_SERIAL=y
+CONFIG_DEBUG_UART_BASE=0x9000000
+CONFIG_DEBUG_UART_CLOCK=0
+CONFIG_ARMV7_LPAE=y
+CONFIG_DEBUG_UART=y
+CONFIG_AHCI=y
+CONFIG_DISTRO_DEFAULTS=y
+CONFIG_SYS_LOAD_ADDR=0x40200000
+CONFIG_FIT=y
+CONFIG_FIT_SIGNATURE=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_FIT_BEST_MATCH=y
+CONFIG_LEGACY_IMAGE_FORMAT=y
+CONFIG_USE_PREBOOT=y
+# CONFIG_DISPLAY_CPUINFO is not set
+# CONFIG_DISPLAY_BOARDINFO is not set
+CONFIG_PCI_INIT_R=y
+CONFIG_SPL_FRAMEWORK_BOARD_INIT_F=y
+CONFIG_CMD_BOOTEFI_SELFTEST=y
+CONFIG_CMD_NVEDIT_EFI=y
+CONFIG_CMD_DFU=y
+CONFIG_CMD_MTD=y
+CONFIG_CMD_PCI=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_MTDPARTS=y
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_OF_BOARD=y
+CONFIG_ENV_IS_IN_FLASH=y
+CONFIG_ENV_ADDR=0x4000000
+CONFIG_SPL_DM=y
+CONFIG_SCSI_AHCI=y
+CONFIG_AHCI_PCI=y
+CONFIG_DFU_TFTP=y
+CONFIG_DFU_MTD=y
+CONFIG_DFU_RAM=y
+# CONFIG_MMC is not set
+CONFIG_MTD=y
+CONFIG_DM_MTD=y
+CONFIG_MTD_NOR_FLASH=y
+CONFIG_CFI_FLASH=y
+CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y
+CONFIG_FLASH_CFI_MTD=y
+CONFIG_SYS_FLASH_CFI=y
+CONFIG_DM_ETH=y
+CONFIG_E1000=y
+CONFIG_NVME=y
+CONFIG_PCI=y
+CONFIG_PCIE_ECAM_GENERIC=y
+CONFIG_SCSI=y
+CONFIG_DM_SCSI=y
+CONFIG_DEBUG_UART_PL011=y
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_SYSRESET=y
+CONFIG_SPL_SYSRESET=y
+CONFIG_SYSRESET_PSCI=y
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_PCI=y
+# CONFIG_BINMAN_FDT is not set
diff --git a/doc/board/emulation/qemu-arm.rst b/doc/board/emulation/qemu-arm.rst
index a39df046fc3..aa05d0a5afe 100644
--- a/doc/board/emulation/qemu-arm.rst
+++ b/doc/board/emulation/qemu-arm.rst
@@ -38,6 +38,11 @@ Set the CROSS_COMPILE environment variable as usual, and run:
     make qemu_arm64_defconfig
     make
 
+- for ARM with SPL::
+
+    make qemu_arm_spl_defconfig
+    make
+
 Running U-Boot
 --------------
 The minimal QEMU command line to get U-Boot up and running is:
@@ -50,6 +55,10 @@ The minimal QEMU command line to get U-Boot up and running is:
 
     qemu-system-aarch64 -machine virt -nographic -cpu cortex-a57 -bios u-boot.bin
 
+- For ARM with SPL::
+
+    qemu-system-arm -machine virt -nographic -bios image.bin
+
 Note that for some odd reason qemu-system-aarch64 needs to be explicitly
 told to use a 64-bit CPU or it will boot in 32-bit mode. The -nographic argument
 ensures that output appears on the terminal. Use Ctrl-A X to quit.
@@ -85,6 +94,35 @@ can be enabled with the following command line parameters:
 
 These have been tested in QEMU 2.9.0 but should work in at least 2.5.0 as well.
 
+SPL Description
+---------------
+
+As you see above, running the SPL build is a little different, since there are
+two binaries to load into memory: SPL and U-Boot proper. Binman is used to
+produce the combined `image.bin` containing these. See
+`arch/arm/dts/qemu-arm-u-boot.dtsi` for the definition. A custom loader called
+`spl_qemu_load_image()` is used to access the U-Boot binary from within SPL.
+
+A sample run is shown below::
+
+    U-Boot SPL 2021.10 (Oct 28 2021 - 20:57:27 -0600)
+    Trying to boot from QEMU
+
+
+    U-Boot 2021.10 (Oct 28 2021 - 20:57:27 -0600)
+
+    DRAM:  128 MiB
+    Flash: 64 MiB
+    Loading Environment from Flash... *** Warning - bad CRC, using default environment
+
+    In:    pl011@9000000
+    Out:   pl011@9000000
+    Err:   pl011@9000000
+    Net:   eth0: virtio-net#32
+    Hit any key to stop autoboot:  0
+    =>
+
+
 Debug UART
 ----------
 
-- 
2.33.1.1089.g2158813163f-goog


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 15/31] bloblist: Add functions to obtain base address and size
  2021-11-01  1:17 ` Simon Glass
                   ` (14 preceding siblings ...)
  (?)
@ 2021-11-01  1:17 ` Simon Glass
  -1 siblings, 0 replies; 77+ messages in thread
From: Simon Glass @ 2021-11-01  1:17 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Tom Rini, Bin Meng, Ilias Apalodimas, Bill Mills,
	Heinrich Schuchardt, François Ozog, Simon Glass

Add a few convenience functions to obtain useful information about the
bloblist.

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

 common/bloblist.c  | 12 ++++++++++++
 include/bloblist.h | 14 ++++++++++++++
 test/bloblist.c    |  2 ++
 3 files changed, 28 insertions(+)

diff --git a/common/bloblist.c b/common/bloblist.c
index 6e7f813db94..29164c9b901 100644
--- a/common/bloblist.c
+++ b/common/bloblist.c
@@ -367,6 +367,18 @@ int bloblist_finish(void)
 	return 0;
 }
 
+ulong bloblist_get_base(void)
+{
+	return map_to_sysmem(gd->bloblist);
+}
+
+ulong bloblist_get_size(void)
+{
+	struct bloblist_hdr *hdr = gd->bloblist;
+
+	return hdr->size;
+}
+
 void bloblist_get_stats(ulong *basep, ulong *sizep, ulong *allocedp)
 {
 	struct bloblist_hdr *hdr = gd->bloblist;
diff --git a/include/bloblist.h b/include/bloblist.h
index 5de4545160e..88c62b54c54 100644
--- a/include/bloblist.h
+++ b/include/bloblist.h
@@ -292,6 +292,20 @@ int bloblist_finish(void);
  */
 void bloblist_get_stats(ulong *basep, ulong *sizep, ulong *allocedp);
 
+/**
+ * bloblist_get_base() - Get the base address of the bloblist
+ *
+ * @returns base address of bloblist
+ */
+ulong bloblist_get_base(void);
+
+/**
+ * bloblist_get_size() - Get the size of the bloblist
+ *
+ * @returns the size in bytes
+ */
+ulong bloblist_get_size(void);
+
 /**
  * bloblist_show_stats() - Show information about the bloblist
  *
diff --git a/test/bloblist.c b/test/bloblist.c
index c5788d5cd82..720be7e244f 100644
--- a/test/bloblist.c
+++ b/test/bloblist.c
@@ -107,6 +107,8 @@ static int bloblist_test_blob(struct unit_test_state *uts)
 	hdr = clear_bloblist();
 	ut_assertnull(bloblist_find(TEST_TAG, TEST_BLOBLIST_SIZE));
 	ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
+	ut_asserteq(TEST_BLOBLIST_SIZE, bloblist_get_size());
+	ut_asserteq(TEST_ADDR, bloblist_get_base());
 	ut_asserteq(map_to_sysmem(hdr), TEST_ADDR);
 
 	/* Add a record and check that we can find it */
-- 
2.33.1.1089.g2158813163f-goog


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 16/31] passage: Support an incoming passage
  2021-11-01  1:17 ` Simon Glass
                   ` (15 preceding siblings ...)
  (?)
@ 2021-11-01  1:17 ` Simon Glass
  -1 siblings, 0 replies; 77+ messages in thread
From: Simon Glass @ 2021-11-01  1:17 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Tom Rini, Bin Meng, Ilias Apalodimas, Bill Mills,
	Heinrich Schuchardt, François Ozog, Simon Glass

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 <sjg@chromium.org>
---

 common/Kconfig                    | 31 ++++++++++++++++++++++++++++++
 common/bloblist.c                 |  4 ++++
 common/board_f.c                  | 32 ++++++++++++++++---------------
 include/asm-generic/global_data.h | 21 ++++++++++++++++++++
 include/bloblist.h                |  9 +++++++++
 lib/asm-offsets.c                 |  5 +++++
 6 files changed, 87 insertions(+), 15 deletions(-)

diff --git a/common/Kconfig b/common/Kconfig
index 2c6f5901c8a..fa7915d2acc 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -740,6 +740,14 @@ config BLOBLIST_ALLOC
 	  specify a fixed address on systems where this is unknown or can
 	  change at runtime.
 
+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
@@ -798,6 +806,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
@@ -833,6 +848,22 @@ endif # TPL_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/bloblist.c b/common/bloblist.c
index 29164c9b901..d36e0a94dff 100644
--- a/common/bloblist.c
+++ b/common/bloblist.c
@@ -444,6 +444,10 @@ int bloblist_init(void)
 	addr = IF_ENABLED_INT(CONFIG_BLOBLIST_FIXED, CONFIG_BLOBLIST_ADDR);
 	size = CONFIG_BLOBLIST_SIZE;
 	if (expected) {
+		if (CONFIG_IS_ENABLED(BLOBLIST_PASSAGE)) {
+			addr = gd->passage_bloblist;
+			size = 0;
+		}
 		ret = bloblist_check(addr, size);
 		if (ret) {
 			log_warning("Expected bloblist at %lx not found (err=%d)\n",
diff --git a/common/board_f.c b/common/board_f.c
index 14e9286a70f..86c77a42847 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -570,11 +570,13 @@ static int reserve_stacks(void)
 static int reserve_bloblist(void)
 {
 #ifdef CONFIG_BLOBLIST
+	int new_size = CONFIG_BLOBLIST_SIZE_RELOC;
+
+	if (!new_size)
+		new_size = bloblist_get_size();
 	/* Align to a 4KB boundary for easier reading of addresses */
-	gd->start_addr_sp = ALIGN_DOWN(gd->start_addr_sp -
-				       CONFIG_BLOBLIST_SIZE_RELOC, 0x1000);
-	gd->new_bloblist = map_sysmem(gd->start_addr_sp,
-				      CONFIG_BLOBLIST_SIZE_RELOC);
+	gd->start_addr_sp = ALIGN_DOWN(gd->start_addr_sp - new_size, 0x1000);
+	gd->new_bloblist = map_sysmem(gd->start_addr_sp, new_size);
 #endif
 
 	return 0;
@@ -655,21 +657,21 @@ 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;
 	}
 	if (gd->new_bloblist) {
-		int size = CONFIG_BLOBLIST_SIZE;
-
-		debug("Copying bloblist from %p to %p, size %x\n",
-		      gd->bloblist, gd->new_bloblist, size);
-		bloblist_reloc(gd->new_bloblist, CONFIG_BLOBLIST_SIZE_RELOC,
-			       gd->bloblist, size);
+		debug("Copying bloblist from %p size %x to %p, size %x\n",
+		      gd->bloblist, size, gd->new_bloblist, new_size);
+		bloblist_reloc(gd->new_bloblist, new_size, gd->bloblist, size);
 		gd->bloblist = gd->new_bloblist;
 	}
 #endif
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
index 99daa20c765..ef4119f27f4 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -119,6 +119,27 @@ struct global_data {
 	 */
 	unsigned long precon_buf_idx;
 #endif
+	/**
+	 * @passage_bloblist: Incoming bloblist from the 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_off: Offset of dtb within the passage
+	 *
+	 * Provides the offset 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_off;
+
 	/**
 	 * @env_addr: address of environment structure
 	 *
diff --git a/include/bloblist.h b/include/bloblist.h
index 88c62b54c54..2ede0ce3150 100644
--- a/include/bloblist.h
+++ b/include/bloblist.h
@@ -292,6 +292,15 @@ int bloblist_finish(void);
  */
 void bloblist_get_stats(ulong *basep, ulong *sizep, ulong *allocedp);
 
+ulong bloblist_get_base(void);
+
+/**
+ * bloblist_get_size() - Get the size of the bloblist
+ *
+ * @returns the size in bytes
+ */
+ulong bloblist_get_size(void);
+
 /**
  * bloblist_get_base() - Get the base address of the bloblist
  *
diff --git a/lib/asm-offsets.c b/lib/asm-offsets.c
index c691066332d..5467b95cb47 100644
--- a/lib/asm-offsets.c
+++ b/lib/asm-offsets.c
@@ -43,5 +43,10 @@ int main(void)
 
 	DEFINE(GD_ENV_ADDR, offsetof(struct global_data, env_addr));
 
+	DEFINE(GD_PASSAGE_BLOBLIST,
+	       offsetof(struct global_data, passage_bloblist));
+	DEFINE(GD_PASSAGE_DTB_OFF,
+	       offsetof(struct global_data, passage_dtb_off));
+
 	return 0;
 }
-- 
2.33.1.1089.g2158813163f-goog


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 17/31] passage: Support a control devicetree
  2021-11-01  1:17 ` Simon Glass
                   ` (16 preceding siblings ...)
  (?)
@ 2021-11-01  1:17 ` Simon Glass
  -1 siblings, 0 replies; 77+ messages in thread
From: Simon Glass @ 2021-11-01  1:17 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Tom Rini, Bin Meng, Ilias Apalodimas, Bill Mills,
	Heinrich Schuchardt, François Ozog, Simon Glass

Add support for accepting a control devicetree from the incoming passage.
This allows SPL (or some other program) to pass a devicetree to U-Boot
proper in a standard way.

Pass the devicetree through the early parts of U-Boot needs a list care.
If it is in the bloblist, there is no need to reserve a separate space for
it to relocate into, since it will be relocated as part of the bloblist.

Also we must init the bloblist before calling fdtdec_setup(), so the
devicetree can be read from the bloblist*. This is not normally safe,
since malloc() is be called by bloblist_init() if CONFIG_BLOBLIST_ALLOC
is enabled. But in the case of a devicetree in the incoming passage, we
know we won't need to allocate the bloblist, since the previous phase has
set it up for us.

Finally, move the reloc_fdt() call after the reloc_bloblist() since, as
mentioned above, when the passage is used there is no need to relocate the
devicetree.

There is one subtlety here. If bloblist support is not enabled in U-Boot,
it can still receive a control devicetree, using the passage_dtb_off value
added to passage_bloblist. This allows the devicetree passing to work
even if the bloblist itself is ignored. In that case we do need to
relocate the devicetree. Use a global_data flag for this case.

* Actually we could init the bloblist later, since we have the offset of
the devicetree in a register, but that seems like an extreme measure,
bypassing U-Boot's own bloblist implementation to get at the data.

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

 common/bloblist.c                 |  1 +
 common/board_f.c                  | 16 ++++++++++++----
 dts/Kconfig                       | 12 ++++++++++++
 include/asm-generic/global_data.h |  4 ++++
 include/bloblist.h                |  1 +
 lib/fdtdec.c                      | 30 ++++++++++++++++++++++++++++++
 6 files changed, 60 insertions(+), 4 deletions(-)

diff --git a/common/bloblist.c b/common/bloblist.c
index d36e0a94dff..310ca87dbc4 100644
--- a/common/bloblist.c
+++ b/common/bloblist.c
@@ -39,6 +39,7 @@ static struct tag_name {
 	{ BLOBLISTT_NONE, "(none)" },
 
 	/* BLOBLISTT_AREA_FIRMWARE_TOP */
+	{ BLOBLISTT_CONTROL_DTB, "Control DTB" },
 
 	/* BLOBLISTT_AREA_FIRMWARE */
 	{ BLOBLISTT_ACPI_GNVS, "ACPI GNVS" },
diff --git a/common/board_f.c b/common/board_f.c
index 86c77a42847..3684c21a0f7 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -517,7 +517,7 @@ static int reserve_global_data(void)
 
 static int reserve_fdt(void)
 {
-	if (!IS_ENABLED(CONFIG_OF_EMBED)) {
+	if (!IS_ENABLED(CONFIG_OF_EMBED) && !(gd->flags & GD_FLG_OF_PASSAGE)) {
 		/*
 		 * If the device tree is sitting immediately above our image
 		 * then we must relocate it. If it is embedded in the data
@@ -622,7 +622,12 @@ static int init_post(void)
 
 static int reloc_fdt(void)
 {
-	if (!IS_ENABLED(CONFIG_OF_EMBED)) {
+	if (IS_ENABLED(CONFIG_OF_PASSAGE) && (gd->flags & GD_FLG_OF_PASSAGE)) {
+		void *blob = bloblist_find(BLOBLISTT_CONTROL_DTB, 0);
+
+		log_info("passage: Control dtb relocated to %p\n", blob);
+		gd->fdt_blob = blob;
+	} else if (!IS_ENABLED(CONFIG_OF_EMBED)) {
 		if (gd->flags & GD_FLG_SKIP_RELOC)
 			return 0;
 		if (gd->new_fdt) {
@@ -819,6 +824,9 @@ __weak int clear_bss(void)
 
 static const init_fnc_t init_sequence_f[] = {
 	setup_mon_len,
+#ifdef CONFIG_OF_PASSAGE
+	bloblist_init,
+#endif
 #ifdef CONFIG_OF_CONTROL
 	fdtdec_setup,
 #endif
@@ -828,7 +836,7 @@ static const init_fnc_t init_sequence_f[] = {
 	initf_malloc,
 	log_init,
 	initf_bootstage,	/* uses its own timer, so does not need DM */
-#ifdef CONFIG_BLOBLIST
+#if !defined(CONFIG_OF_PASSAGE) && defined(CONFIG_BLOBLIST)
 	bloblist_init,
 #endif
 	setup_spl_handoff,
@@ -938,9 +946,9 @@ static const init_fnc_t init_sequence_f[] = {
 	setup_bdinfo,
 	display_new_sp,
 	INIT_FUNC_WATCHDOG_RESET
-	reloc_fdt,
 	reloc_bootstage,
 	reloc_bloblist,
+	reloc_fdt,
 	setup_reloc,
 #if defined(CONFIG_X86) || defined(CONFIG_ARC)
 	copy_uboot_to_ram,
diff --git a/dts/Kconfig b/dts/Kconfig
index 5dcc79d5192..7e4d9852a44 100644
--- a/dts/Kconfig
+++ b/dts/Kconfig
@@ -96,6 +96,18 @@ config OF_EMBED
 
 endchoice
 
+config OF_PASSAGE
+	bool "Devicetree provided by the standard passage protocol"
+	help
+	  If this option is enabled, the device tree may be provided by the
+	  standard passage, meaning that a previous phase/stage passes a
+	  bloblist containing this. This is the standard way to pass a
+	  devicetree between firmware components at runtime. The device tree
+	  bundled with the image (if any) will be overridden / ignored.
+
+	  Note: If BLOBLIST is not enabled, this does not decode the
+	  bloblist, but just picks up the devicetree by itself.
+
 config OF_BOARD
 	bool "Provided by the board (e.g a previous loader) at runtime"
 	default y if SANDBOX
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
index ef4119f27f4..717fe2edb46 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -627,6 +627,10 @@ enum gd_flags {
 	 * @GD_FLG_SMP_READY: SMP initialization is complete
 	 */
 	GD_FLG_SMP_READY = 0x80000,
+	/**
+	 * @GD_FLG_OF_PASSAGE: Using devicetree from standard passage protocol
+	 */
+	GD_FLG_OF_PASSAGE = 0x80000,
 };
 
 #endif /* __ASSEMBLY__ */
diff --git a/include/bloblist.h b/include/bloblist.h
index 2ede0ce3150..607e42129d4 100644
--- a/include/bloblist.h
+++ b/include/bloblist.h
@@ -31,6 +31,7 @@ enum bloblist_tag_t {
 	 * projects.
 	 */
 	BLOBLISTT_AREA_FIRMWARE_TOP = 0x1,
+	BLOBLISTT_CONTROL_DTB = 1,	/* Devicetree used for control */
 
 	/* Standard area to allocate blobs used across firmware components */
 	BLOBLISTT_AREA_FIRMWARE = 0x100,
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 31a509bc221..4ca56e06b2f 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -3,8 +3,11 @@
  * Copyright (c) 2011 The Chromium OS Authors.
  */
 
+#define LOG_CATEGORY	LOGC_DT
+
 #ifndef USE_HOSTCC
 #include <common.h>
+#include <bloblist.h>
 #include <boot_fit.h>
 #include <dm.h>
 #include <hang.h>
@@ -1631,6 +1634,33 @@ int fdtdec_setup(void)
 	else /* embed dtb in ELF file for testing / development */
 		gd->fdt_blob = dtb_dt_embedded();
 
+	/* Passed in via the standard passage */
+	if (IS_ENABLED(CONFIG_OF_PASSAGE) && gd->passage_dtb_off) {
+		void *fdt = NULL;
+
+		/* Use the bloblist if available */
+		if (CONFIG_IS_ENABLED(BLOBLIST)) {
+			fdt = bloblist_find(BLOBLISTT_CONTROL_DTB, 0);
+
+			if (fdt)
+				gd->flags |= GD_FLG_OF_PASSAGE;
+		} else {
+			void *bloblist;
+
+			/* Cursory check for a valid bloblist; use the offset */
+			bloblist = bloblist_check_magic(gd->passage_bloblist);
+			if (bloblist) {
+				fdt = bloblist + gd->passage_dtb_off;
+				log_debug("passage: Found dtb offset %lx\n",
+					  gd->passage_dtb_off);
+			}
+		}
+		if (fdt) {
+			gd->fdt_blob = fdt;
+			log_debug("passage: Found control dtb at %p\n", fdt);
+		}
+	}
+
 	/* Allow the board to override the fdt address. */
 	if (IS_ENABLED(CONFIG_OF_BOARD)) {
 		gd->fdt_blob = board_fdt_blob_setup(&ret);
-- 
2.33.1.1089.g2158813163f-goog


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 18/31] passage: arm: Accept a passage from the previous phase
  2021-11-01  1:17 ` Simon Glass
                   ` (17 preceding siblings ...)
  (?)
@ 2021-11-01  1:17 ` Simon Glass
  -1 siblings, 0 replies; 77+ messages in thread
From: Simon Glass @ 2021-11-01  1:17 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Tom Rini, Bin Meng, Ilias Apalodimas, Bill Mills,
	Heinrich Schuchardt, François Ozog, Simon Glass,
	Albert Aribaud

Accept a bloblist and control devicetree from a previous phase in
registers r0 and r1

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

 arch/arm/cpu/armv7/start.S | 7 ++++++-
 arch/arm/lib/crt0.S        | 4 ++++
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S
index 698e15b8e18..5ebe2c26693 100644
--- a/arch/arm/cpu/armv7/start.S
+++ b/arch/arm/cpu/armv7/start.S
@@ -36,6 +36,10 @@
 #endif
 
 reset:
+	# Keep passage information in case it is provided
+	mov	r6, r0
+	mov	r7, r1
+
 	/* Allow the board to save important registers */
 	b	save_boot_params
 save_boot_params_ret:
@@ -124,7 +128,8 @@ switch_to_hypervisor_ret:
 	bl	cpu_init_crit
 #endif
 #endif
-
+	# Note: r6 and r7 are available to _main in case standard passage is
+	# used
 	bl	_main
 
 /*------------------------------------------------------------------------------*/
diff --git a/arch/arm/lib/crt0.S b/arch/arm/lib/crt0.S
index 956d258c9da..f5343b22683 100644
--- a/arch/arm/lib/crt0.S
+++ b/arch/arm/lib/crt0.S
@@ -113,6 +113,10 @@ ENTRY(_main)
 	CLEAR_BSS
 #endif
 
+#if CONFIG_IS_ENABLED(PASSAGE_IN)
+	str	r6, [r9, GD_PASSAGE_BLOBLIST]
+	str	r7, [r9, GD_PASSAGE_DTB_OFF]
+#endif
 	mov	r0, #0
 	bl	board_init_f
 
-- 
2.33.1.1089.g2158813163f-goog


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 19/31] passage: spl: Support adding the dtb to the passage bloblist
  2021-11-01  1:17 ` Simon Glass
                   ` (18 preceding siblings ...)
  (?)
@ 2021-11-01  1:17 ` Simon Glass
  -1 siblings, 0 replies; 77+ messages in thread
From: Simon Glass @ 2021-11-01  1:17 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Tom Rini, Bin Meng, Ilias Apalodimas, Bill Mills,
	Heinrich Schuchardt, François Ozog, Simon Glass

Add an option for SPL to add a devicetree to the passage bloblist, so
SPL can provide the devicetree to U-Boot.

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

 common/Kconfig   | 20 ++++++++++++++++++++
 common/spl/spl.c | 44 ++++++++++++++++++++++++++++++++++++++++++--
 include/spl.h    |  2 ++
 3 files changed, 64 insertions(+), 2 deletions(-)

diff --git a/common/Kconfig b/common/Kconfig
index fa7915d2acc..e0d7ee28c4d 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -864,6 +864,26 @@ config SPL_PASSAGE_IN
 	  firmware phases to communicate state and settings to following
 	  phases.
 
+config SPL_PASSAGE_OUT
+	bool "Support the standard-passage protocol in SPL (out)"
+	depends on SPL_BLOBLIST
+	default y if PASSAGE_IN
+	help
+	  This enables a standard protocol for entering U-Boot, providing
+	  parameters in a bloblist and a devicetree. It allows the various
+	  firmware stages to communicate state and settings to following
+	  stages.
+
+config SPL_PASSAGE_ADD_DTB
+	bool "Add devicetree to the outgoing passage"
+	depends on SPL_PASSAGE_OUT
+	default y if SPL_PASSAGE_OUT && !SPL_PASSAGE_IN
+	help
+	  Add the devicetree into the bloblist in SPL (it is assumed to not
+	  already be there) so that the next phase (U-Boot) can find it.
+
+	  This option should be enabled in the phase that sets up the passage.
+
 source "common/spl/Kconfig"
 
 config IMAGE_SIGN_INFO
diff --git a/common/spl/spl.c b/common/spl/spl.c
index 55e33d2fc44..7a9df9aaece 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -58,6 +58,11 @@ binman_sym_declare(ulong, spl, image_pos);
 binman_sym_declare(ulong, spl, size);
 #endif
 
+#if CONFIG_IS_ENABLED(PASSAGE_ADD_DTB)
+binman_sym_declare(ulong, u_boot_dtb, image_pos);
+binman_sym_declare(ulong, u_boot_dtb, size);
+#endif
+
 /* Define board data structure */
 static struct bd_info bdata __attribute__ ((section(".data")));
 
@@ -408,7 +413,8 @@ static int setup_spl_handoff(void)
 {
 	struct spl_handoff *ho;
 
-	ho = bloblist_ensure(BLOBLISTT_U_BOOT_SPL_HANDOFF, sizeof(struct spl_handoff));
+	ho = bloblist_ensure(BLOBLISTT_U_BOOT_SPL_HANDOFF,
+			     sizeof(struct spl_handoff));
 	if (!ho)
 		return -ENOENT;
 
@@ -425,7 +431,8 @@ static int write_spl_handoff(void)
 	struct spl_handoff *ho;
 	int ret;
 
-	ho = bloblist_find(BLOBLISTT_U_BOOT_SPL_HANDOFF, sizeof(struct spl_handoff));
+	ho = bloblist_find(BLOBLISTT_U_BOOT_SPL_HANDOFF,
+			   sizeof(struct spl_handoff));
 	if (!ho)
 		return -ENOENT;
 	handoff_save_dram(ho);
@@ -442,6 +449,33 @@ static inline int write_spl_handoff(void) { return 0; }
 
 #endif /* HANDOFF */
 
+/**
+ * Write the devicetree for the next phase into the passage
+ *
+ * For now we assume the next phase is U-Boot proper
+ *
+ * @return 0 on success,  -ENOSPC if it is missing and could not be added due to
+ *	lack of space, or -ESPIPE it exists but has the wrong size
+ */
+static int passage_write_dtb(void)
+{
+#if CONFIG_IS_ENABLED(PASSAGE_ADD_DTB)
+	ulong start = binman_sym(ulong, u_boot_dtb, image_pos);
+	ulong size = binman_sym(ulong, u_boot_dtb, size);
+	void *dtb;
+	int ret;
+
+	log_debug("passage: Adding control dtb size %lx\n", size);
+	ret = bloblist_ensure_size(BLOBLISTT_CONTROL_DTB, size, 0,
+				   (void **)&dtb);
+	if (ret)
+		return ret;
+	memcpy(dtb, map_sysmem(start, size), size);
+#endif
+
+	return 0;
+}
+
 /**
  * get_bootstage_id() - Get the bootstage ID to emit
  *
@@ -763,6 +797,12 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
 			printf(SPL_TPL_PROMPT
 			       "SPL hand-off write failed (err=%d)\n", ret);
 	}
+	if (CONFIG_IS_ENABLED(PASSAGE_ADD_DTB)) {
+		ret = passage_write_dtb();
+		if (ret)
+			printf(SPL_TPL_PROMPT
+			       "Write DTB failed (err=%d)\n", ret);
+	}
 	if (CONFIG_IS_ENABLED(BLOBLIST)) {
 		ret = bloblist_finish();
 		if (ret)
diff --git a/include/spl.h b/include/spl.h
index 0af0ee30034..7da8f7f92ab 100644
--- a/include/spl.h
+++ b/include/spl.h
@@ -270,6 +270,8 @@ binman_sym_extern(ulong, u_boot_any, image_pos);
 binman_sym_extern(ulong, u_boot_any, size);
 binman_sym_extern(ulong, spl, image_pos);
 binman_sym_extern(ulong, spl, size);
+binman_sym_extern(ulong, u_boot_dtb, image_pos);
+binman_sym_extern(ulong, u_boot_dtb, size);
 
 /**
  * spl_get_image_pos() - get the image position of the next phase
-- 
2.33.1.1089.g2158813163f-goog


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 20/31] passage: spl: Support passing the passage to U-Boot
  2021-11-01  1:17 ` Simon Glass
                   ` (19 preceding siblings ...)
  (?)
@ 2021-11-01  1:17 ` Simon Glass
  -1 siblings, 0 replies; 77+ messages in thread
From: Simon Glass @ 2021-11-01  1:17 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Tom Rini, Bin Meng, Ilias Apalodimas, Bill Mills,
	Heinrich Schuchardt, François Ozog, Simon Glass

Update the jump routine to support passing three parameters instead of
one. The two new parameters are the bloblist address and the offset from
there to the devicetree.

Add an accessor for gd->bloblist to avoid needing #ifdefs in the C code.

Note that this renames jump_to_image_no_args() to jump_to_image(), so will
not work on boards which have overridden that weak function. This can be
tided up by maintainers as they enable the standard passage. Fix up a
few that definitely need a tweak.

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

 arch/sandbox/cpu/spl.c            |  2 +-
 arch/x86/lib/spl.c                |  2 +-
 arch/x86/lib/tpl.c                |  2 +-
 common/spl/spl.c                  | 30 +++++++++++++++++++++++++-----
 include/asm-generic/global_data.h |  6 ++++++
 include/spl.h                     | 13 +++++++++++++
 6 files changed, 47 insertions(+), 8 deletions(-)

diff --git a/arch/sandbox/cpu/spl.c b/arch/sandbox/cpu/spl.c
index 650bdb0a701..7047613517b 100644
--- a/arch/sandbox/cpu/spl.c
+++ b/arch/sandbox/cpu/spl.c
@@ -87,7 +87,7 @@ void spl_board_init(void)
 	}
 }
 
-void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
+void __noreturn jump_to_image(struct spl_image_info *spl_image)
 {
 	const char *fname = spl_image->arg;
 
diff --git a/arch/x86/lib/spl.c b/arch/x86/lib/spl.c
index b18c1cd6092..c51514bfeb8 100644
--- a/arch/x86/lib/spl.c
+++ b/arch/x86/lib/spl.c
@@ -238,7 +238,7 @@ int spl_spi_load_image(void)
 }
 
 #ifdef CONFIG_X86_RUN_64BIT
-void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
+void __noreturn jump_to_image(struct spl_image_info *spl_image)
 {
 	int ret;
 
diff --git a/arch/x86/lib/tpl.c b/arch/x86/lib/tpl.c
index 5b57e53c2dd..b334f70e83e 100644
--- a/arch/x86/lib/tpl.c
+++ b/arch/x86/lib/tpl.c
@@ -110,7 +110,7 @@ int spl_spi_load_image(void)
 	return -EPERM;
 }
 
-void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
+void __noreturn jump_to_image(struct spl_image_info *spl_image)
 {
 	debug("Jumping to %s at %lx\n", spl_phase_name(spl_next_phase()),
 	      (ulong)spl_image->entry_point);
diff --git a/common/spl/spl.c b/common/spl/spl.c
index 7a9df9aaece..a226c2a2488 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -394,13 +394,33 @@ int spl_parse_image_header(struct spl_image_info *spl_image,
 
 __weak void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
 {
-	typedef void __noreturn (*image_entry_noargs_t)(void);
+	jump_to_image(spl_image);
+}
+
+__weak void __noreturn jump_to_image(struct spl_image_info *spl_image)
+{
+	typedef void __noreturn (*image_entry_t)(ulong bloblist,
+						 ulong dtb_offset);
+	ulong bloblist = 0;
+	ulong dtb_offset = 0;
 
-	image_entry_noargs_t image_entry =
-		(image_entry_noargs_t)spl_image->entry_point;
+	image_entry_t image_entry = (image_entry_t)spl_image->entry_point;
 
 	debug("image entry point: 0x%lx\n", spl_image->entry_point);
-	image_entry();
+
+	if (CONFIG_IS_ENABLED(PASSAGE_OUT)) {
+		const void *fdt;
+
+		bloblist = bloblist_get_base();
+		fdt = bloblist_find(BLOBLISTT_CONTROL_DTB, 0);
+		if (fdt)
+			dtb_offset = (ulong)fdt - (ulong)gd_bloblist();
+
+		log_debug("passage: sending bloblist at %lx, dtb offset %lx\n",
+			  bloblist, dtb_offset);
+	}
+
+	image_entry(bloblist, dtb_offset);
 }
 
 #if CONFIG_IS_ENABLED(HANDOFF)
@@ -862,7 +882,7 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
 #endif
 
 	spl_board_prepare_for_boot();
-	jump_to_image_no_args(&spl_image);
+	jump_to_image(&spl_image);
 }
 
 /*
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
index 717fe2edb46..6aba74dac10 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -541,6 +541,12 @@ static_assert(sizeof(struct global_data) == GD_SIZE);
 #define gd_set_multi_dtb_fit(_dtb)
 #endif
 
+#if CONFIG_IS_ENABLED(BLOBLIST)
+#define gd_bloblist()		gd->bloblist
+#else
+#define gd_bloblist()		NULL
+#endif
+
 /**
  * enum gd_flags - global data flags
  *
diff --git a/include/spl.h b/include/spl.h
index 7da8f7f92ab..3292ddeb512 100644
--- a/include/spl.h
+++ b/include/spl.h
@@ -581,6 +581,19 @@ int spl_load_image_fat(struct spl_image_info *spl_image,
 int spl_load_image_fat_os(struct spl_image_info *spl_image,
 			  struct blk_desc *block_dev, int partition);
 
+/**
+ * jump_to_image() - Jump to image, using standard passage if enabled
+ *
+ * This sets the machine registers correctly if standard passage is enabled for
+ * output. This allows the target image to read the info using the standard
+ * passage protocol
+ *
+ * This is a weak function, so may be overriddden
+ *
+ * @spl_image: Image to jump to
+ */
+void __noreturn jump_to_image(struct spl_image_info *spl_image);
+
 void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image);
 
 /* SPL EXT image functions */
-- 
2.33.1.1089.g2158813163f-goog


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 21/31] passage: Record where the devicetree came from
  2021-11-01  1:17 ` Simon Glass
                   ` (20 preceding siblings ...)
  (?)
@ 2021-11-01  1:17 ` Simon Glass
  -1 siblings, 0 replies; 77+ messages in thread
From: Simon Glass @ 2021-11-01  1:17 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Tom Rini, Bin Meng, Ilias Apalodimas, Bill Mills,
	Heinrich Schuchardt, François Ozog, Simon Glass

Keep track of where the devicetree came from, so we can report this later.

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

 include/asm-generic/global_data.h |  4 ++++
 include/fdtdec.h                  | 36 +++++++++++++++++++++++++++++++
 lib/fdtdec.c                      | 21 +++++++++++++-----
 3 files changed, 56 insertions(+), 5 deletions(-)

diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
index 6aba74dac10..d998581e179 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -265,6 +265,10 @@ struct global_data {
 	 * @fdt_size: space reserved for relocated device space
 	 */
 	unsigned long fdt_size;
+	/**
+	 * @fdt_src: Source of FDT
+	 */
+	enum fdt_source_t fdt_src;
 #if CONFIG_IS_ENABLED(OF_LIVE)
 	/**
 	 * @of_root: root node of the live tree
diff --git a/include/fdtdec.h b/include/fdtdec.h
index 24992baed8b..b4e452326b3 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -49,6 +49,35 @@ struct fdt_memory {
 
 struct bd_info;
 
+/**
+ * enum fdt_source_t - indicates where the devicetree came from
+ *
+ * These are listed in approximate order of desirability after FDTSRC_NONE
+ *
+ * @FDTSRC_SEPARATE: Appended to U-Boot. This is the normal approach if U-Boot
+ *	is the only firmware being booted
+ * @FDTSRC_PASSAGE: From the standard passage (passed in from previous
+ *	phase/stage). This is the normal approach if prior-stage firmware is
+ *	used, such as TF-A
+ * @FDTSRC_FIT: Found in a multi-dtb FIT. This should be used when U-Boot must
+ *	select a devicetree from many options
+ * @FDTSRC_BOARD: Located by custom board code. This should only be used when
+ *	the prior stage does not support FDTSRC_PASSAGE
+ * @FDTSRC_EMBED: Embedded into U-Boot executable. This should onyl be used when
+ *	U-Boot is packaged as an ELF file, e.g. for debugging purposes
+ * @FDTSRC_ENV: Provided by the fdtcontroladdr environment variable. This should
+ *	be used for debugging/development only
+ * @FDTSRC_NONE: No devicetree at all
+ */
+enum fdt_source_t {
+	FDTSRC_SEPARATE,
+	FDTSRC_PASSAGE,
+	FDTSRC_FIT,
+	FDTSRC_BOARD,
+	FDTSRC_EMBED,
+	FDTSRC_ENV,
+};
+
 /*
  * Information about a resource. start is the first address of the resource
  * and end is the last address (inclusive). The length of the resource will
@@ -1209,4 +1238,11 @@ int fdtdec_decode_ram_size(const void *blob, const char *area, int board_id,
 			   phys_addr_t *basep, phys_size_t *sizep,
 			   struct bd_info *bd);
 
+/**
+ * fdtdec_get_srcname() - Get the name of where the devicetree comes from
+ *
+ * @return source name
+ */
+const char *fdtdec_get_srcname(void);
+
 #endif
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 4ca56e06b2f..0a6e195f8ba 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -1621,6 +1621,7 @@ static void setup_multi_dtb_fit(void)
 	if (blob) {
 		gd_set_multi_dtb_fit(gd->fdt_blob);
 		gd->fdt_blob = blob;
+		gd->fdt_src = FDTSRC_FIT;
 	}
 }
 
@@ -1629,10 +1630,13 @@ int fdtdec_setup(void)
 	int ret;
 
 	/* The devicetree is typically appended to U-Boot */
-	if (IS_ENABLED(CONFIG_OF_SEPARATE))
+	if (IS_ENABLED(CONFIG_OF_SEPARATE)) {
 		gd->fdt_blob = fdt_find_separate();
-	else /* embed dtb in ELF file for testing / development */
+		gd->fdt_src = FDTSRC_SEPARATE;
+	} else { /* embed dtb in ELF file for testing / development */
 		gd->fdt_blob = dtb_dt_embedded();
+		gd->fdt_src = FDTSRC_EMBED;
+	}
 
 	/* Passed in via the standard passage */
 	if (IS_ENABLED(CONFIG_OF_PASSAGE) && gd->passage_dtb_off) {
@@ -1657,6 +1661,7 @@ int fdtdec_setup(void)
 		}
 		if (fdt) {
 			gd->fdt_blob = fdt;
+			gd->fdt_src = FDTSRC_PASSAGE;
 			log_debug("passage: Found control dtb at %p\n", fdt);
 		}
 	}
@@ -1666,12 +1671,18 @@ int fdtdec_setup(void)
 		gd->fdt_blob = board_fdt_blob_setup(&ret);
 		if (ret)
 			return ret;
+		gd->fdt_src = FDTSRC_BOARD;
 	}
 
+	/* Allow the early environment to override the fdt address */
 	if (!IS_ENABLED(CONFIG_SPL_BUILD)) {
-		/* Allow the early environment to override the fdt address */
-		gd->fdt_blob = map_sysmem(env_get_ulong("fdtcontroladdr", 16,
-			       (unsigned long)map_to_sysmem(gd->fdt_blob)), 0);
+		ulong addr;
+
+		addr = env_get_hex("fdtcontroladdr", 0);
+		if (addr) {
+			gd->fdt_blob = map_sysmem(addr, 0);
+			gd->fdt_src = FDTSRC_ENV;
+		}
 	}
 
 	if (CONFIG_IS_ENABLED(MULTI_DTB_FIT))
-- 
2.33.1.1089.g2158813163f-goog


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 22/31] passage: Report the devicetree source
  2021-11-01  1:17 ` Simon Glass
                   ` (21 preceding siblings ...)
  (?)
@ 2021-11-01  1:17 ` Simon Glass
  -1 siblings, 0 replies; 77+ messages in thread
From: Simon Glass @ 2021-11-01  1:17 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Tom Rini, Bin Meng, Ilias Apalodimas, Bill Mills,
	Heinrich Schuchardt, François Ozog, Simon Glass

It can be confusing to figure out where the devicetree came from. It seems
important enough to warrant a message during boot. Add information about
the number of devices and uclasses too since it is helpful to have some
idea what is going on with driver model.

Report the devicetree source in bdinfo too.

This looks something like this, with > marking the new line.

   U-Boot 2021.10-00190 (Oct 30 2021 - 09:01:29 -0600)

   DRAM:  128 MiB
>  Core:  42 devices, 11 uclasses, devicetree: passage
   Flash: 64 MiB

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

 cmd/bdinfo.c     |  2 ++
 common/board_r.c | 18 ++++++++++++++++++
 lib/fdtdec.c     | 14 ++++++++++++++
 3 files changed, 34 insertions(+)

diff --git a/cmd/bdinfo.c b/cmd/bdinfo.c
index bf63cc6d649..c56b3f4f6ec 100644
--- a/cmd/bdinfo.c
+++ b/cmd/bdinfo.c
@@ -128,6 +128,8 @@ int do_bdinfo(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
 
 		lmb_init_and_reserve(&lmb, gd->bd, (void *)gd->fdt_blob);
 		lmb_dump_all_force(&lmb);
+		if (IS_ENABLED(CONFIG_OF_REAL))
+			printf("devicetree  = %s\n", fdtdec_get_srcname());
 	}
 
 	arch_print_bdinfo();
diff --git a/common/board_r.c b/common/board_r.c
index 31a59c585a8..99adff14b39 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -586,6 +586,23 @@ int initr_mem(void)
 }
 #endif
 
+static int dm_announce(void)
+{
+	int device_count;
+	int uclass_count;
+
+	if (IS_ENABLED(CONFIG_DM)) {
+		dm_get_stats(&device_count, &uclass_count);
+		printf("Core:  %d devices, %d uclasses", device_count,
+		       uclass_count);
+		if (CONFIG_IS_ENABLED(OF_REAL))
+			printf(", devicetree: %s", fdtdec_get_srcname());
+		printf("\n");
+	}
+
+	return 0;
+}
+
 static int run_main_loop(void)
 {
 #ifdef CONFIG_SANDBOX
@@ -661,6 +678,7 @@ static init_fnc_t init_sequence_r[] = {
 	stdio_init_tables,
 	serial_initialize,
 	initr_announce,
+	dm_announce,
 #if CONFIG_IS_ENABLED(WDT)
 	initr_watchdog,
 #endif
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 0a6e195f8ba..3b2de717592 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -79,6 +79,20 @@ static const char * const compat_names[COMPAT_COUNT] = {
 	COMPAT(ALTERA_SOCFPGA_CLK_INIT, "altr,socfpga-a10-clk-init")
 };
 
+static const char *const fdt_src_name[] = {
+	[FDTSRC_SEPARATE] = "separate",
+	[FDTSRC_PASSAGE] = "passage",
+	[FDTSRC_FIT] = "fit",
+	[FDTSRC_BOARD] = "board",
+	[FDTSRC_EMBED] = "embed",
+	[FDTSRC_ENV] = "env",
+};
+
+const char *fdtdec_get_srcname(void)
+{
+	return fdt_src_name[gd->fdt_src];
+}
+
 const char *fdtdec_get_compatible(enum fdt_compat_id id)
 {
 	/* We allow reading of the 'unknown' ID for testing purposes */
-- 
2.33.1.1089.g2158813163f-goog


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 23/31] passage: Add a qemu test for ARM
  2021-11-01  1:17 ` Simon Glass
                   ` (22 preceding siblings ...)
  (?)
@ 2021-11-01  1:17 ` Simon Glass
  -1 siblings, 0 replies; 77+ messages in thread
From: Simon Glass @ 2021-11-01  1:17 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Tom Rini, Bin Meng, Ilias Apalodimas, Bill Mills,
	Heinrich Schuchardt, François Ozog, Simon Glass

Check that the standard passage works on ARM, by setting it up in SPL
and making sure that it comes through correctly in U-Boot proper.

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

 configs/qemu_arm_spl_defconfig |  8 +++++++-
 test/py/tests/test_passage.py  | 11 +++++++++++
 2 files changed, 18 insertions(+), 1 deletion(-)
 create mode 100644 test/py/tests/test_passage.py

diff --git a/configs/qemu_arm_spl_defconfig b/configs/qemu_arm_spl_defconfig
index a6950584542..6ca47ef4200 100644
--- a/configs/qemu_arm_spl_defconfig
+++ b/configs/qemu_arm_spl_defconfig
@@ -12,6 +12,7 @@ CONFIG_SYS_MALLOC_LEN=0x1000000
 CONFIG_DEFAULT_DEVICE_TREE="qemu-arm"
 CONFIG_TARGET_QEMU_ARM_32BIT_SPL=y
 CONFIG_SPL_SERIAL=y
+CONFIG_SPL_SYS_MALLOC_F_LEN=0x6000
 CONFIG_DEBUG_UART_BASE=0x9000000
 CONFIG_DEBUG_UART_CLOCK=0
 CONFIG_ARMV7_LPAE=y
@@ -28,6 +29,11 @@ CONFIG_USE_PREBOOT=y
 # CONFIG_DISPLAY_CPUINFO is not set
 # CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_PCI_INIT_R=y
+CONFIG_BLOBLIST=y
+CONFIG_BLOBLIST_PASSAGE=y
+CONFIG_SPL_BLOBLIST_ALLOC=y
+CONFIG_SPL_BLOBLIST_SIZE=0x4000
+CONFIG_PASSAGE_IN=y
 CONFIG_SPL_FRAMEWORK_BOARD_INIT_F=y
 CONFIG_CMD_BOOTEFI_SELFTEST=y
 CONFIG_CMD_NVEDIT_EFI=y
@@ -37,7 +43,7 @@ CONFIG_CMD_PCI=y
 CONFIG_CMD_USB=y
 CONFIG_CMD_MTDPARTS=y
 CONFIG_SPL_OF_CONTROL=y
-CONFIG_OF_BOARD=y
+CONFIG_OF_PASSAGE=y
 CONFIG_ENV_IS_IN_FLASH=y
 CONFIG_ENV_ADDR=0x4000000
 CONFIG_SPL_DM=y
diff --git a/test/py/tests/test_passage.py b/test/py/tests/test_passage.py
new file mode 100644
index 00000000000..594dc3cc685
--- /dev/null
+++ b/test/py/tests/test_passage.py
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0
+# Copyright 2021 Google LLC
+
+import pytest
+
+@pytest.mark.buildconfigspec('target_qemu_arm_32bit_spl')
+def test_passage(u_boot_console):
+    """Test that the standard passage on ARM from SPL to U-Boot works."""
+
+    response = u_boot_console.run_command('bdinfo')
+    assert 'devicetree  = passage' in response
-- 
2.33.1.1089.g2158813163f-goog


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 24/31] bloblist: doc: Bring in the API documentation
  2021-11-01  1:17 ` Simon Glass
                   ` (23 preceding siblings ...)
  (?)
@ 2021-11-01  1:17 ` Simon Glass
  -1 siblings, 0 replies; 77+ messages in thread
From: Simon Glass @ 2021-11-01  1:17 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Tom Rini, Bin Meng, Ilias Apalodimas, Bill Mills,
	Heinrich Schuchardt, François Ozog, Simon Glass

FIx up various minor errors and add the API documentation to the bloblist
docs, since it is quite useful to see it in the same place.

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

 doc/develop/bloblist.rst |  8 +++-
 include/bloblist.h       | 88 ++++++++++++++++++++--------------------
 2 files changed, 52 insertions(+), 44 deletions(-)

diff --git a/doc/develop/bloblist.rst b/doc/develop/bloblist.rst
index 47274cf8e26..572aa65d764 100644
--- a/doc/develop/bloblist.rst
+++ b/doc/develop/bloblist.rst
@@ -31,7 +31,7 @@ Blobs
 While each blob in the bloblist can be of any length, bloblists are designed to
 hold small amounts of data, typically a few KB at most. It is not possible to
 change the length of a blob once it has been written. Each blob is normally
-created from a C structure which can beused to access its fields.
+created from a C structure which can be used to access its fields.
 
 
 Blob tags
@@ -93,6 +93,12 @@ This should move to using bloblist, to avoid having its own mechanism for
 passing information between U-Boot parts.
 
 
+API documentation
+-----------------
+
+.. kernel-doc:: include/bloblist.h
+
+
 Simon Glass
 sjg@chromium.org
 12-Aug-2018
diff --git a/include/bloblist.h b/include/bloblist.h
index 607e42129d4..8303f712087 100644
--- a/include/bloblist.h
+++ b/include/bloblist.h
@@ -87,8 +87,8 @@ enum bloblist_tag_t {
  * same place in memory as SPL and U-Boot execute, but it can be safely moved
  * around.
  *
- * None of the bloblist structures contain pointers but it is possible to put
- * pointers inside a bloblist record if desired. This is not encouraged,
+ * None of the bloblist headers themselves contain pointers but it is possible
+ * to put pointers inside a bloblist record if desired. This is not encouraged,
  * since it can make part of the bloblist inaccessible if the pointer is
  * no-longer valid. It is better to just store all the data inside a bloblist
  * record.
@@ -100,7 +100,7 @@ enum bloblist_tag_t {
  * @version: BLOBLIST_VERSION
  * @hdr_size: Size of this header, normally sizeof(struct bloblist_hdr). The
  *	first bloblist_rec starts at this offset from the start of the header
- * @flags: Space for BLOBLISTF_... flags (none yet)
+ * @flags: Space for BLOBLISTF... flags (none yet)
  * @size: Total size of the bloblist (non-zero if valid) including this header.
  *	The bloblist extends for this many bytes from the start of this header.
  *	When adding new records, the bloblist can grow up to this size.
@@ -111,8 +111,8 @@ enum bloblist_tag_t {
  * @chksum: CRC32 for the entire bloblist allocated area. Since any of the
  *	blobs can be altered after being created, this checksum is only valid
  *	when the bloblist is finalised before jumping to the next stage of boot.
- *	Note: @chksum is last to make it easier to exclude it from the checksum
- *	calculation.
+ *	Note that chksum is last to make it easier to exclude it from the
+ *	checksum calculation.
  */
 struct bloblist_hdr {
 	u32 magic;
@@ -129,11 +129,11 @@ struct bloblist_hdr {
 /**
  * struct bloblist_rec - record for the bloblist
  *
- * NOTE: Only exported for testing purposes. Do not use this struct.
- *
  * The bloblist contains a number of records each consisting of this record
  * structure followed by the data contained. Each records is 16-byte aligned.
  *
+ * NOTE: Only exported for testing purposes. Do not use this struct.
+ *
  * @tag: Tag indicating what the record contains
  * @hdr_size: Size of this header, normally sizeof(struct bloblist_rec). The
  *	record's data starts at this offset from the start of the record
@@ -152,7 +152,7 @@ struct bloblist_rec {
  * bloblist_check_magic() - return a bloblist if the magic matches
  *
  * @addr: Address to check
- * @return pointer to bloblist, if the magic matches, else NULL
+ * Return: pointer to bloblist, if the magic matches, else NULL
  */
 static inline void *bloblist_check_magic(ulong addr)
 {
@@ -174,8 +174,8 @@ static inline void *bloblist_check_magic(ulong addr)
  *
  * @tag:	Tag to search for (enum bloblist_tag_t)
  * @size:	Expected size of the blob, or 0 for any size
- * @return pointer to blob if found, or NULL if not found, or a blob was found
- *	but it is the wrong size
+ * Return: pointer to blob if found, or NULL if not found, or a blob was found
+ * but it is the wrong size
  */
 void *bloblist_find(uint tag, int size);
 
@@ -191,8 +191,8 @@ void *bloblist_find(uint tag, int size);
  * @tag:	Tag to add (enum bloblist_tag_t)
  * @size:	Size of the blob
  * @align:	Alignment of the blob (in bytes), 0 for default
- * @return pointer to the newly added block, or NULL if there is not enough
- *	space for the blob
+ * Return: pointer to the newly added block, or NULL if there is not enough
+ * space for the blob
  */
 void *bloblist_add(uint tag, int size, int align);
 
@@ -205,8 +205,8 @@ void *bloblist_add(uint tag, int size, int align);
  * @size:	Size of the blob
  * @blobp:	Returns a pointer to blob on success
  * @align:	Alignment of the blob (in bytes), 0 for default
- * @return 0 if OK, -ENOSPC if it is missing and could not be added due to lack
- *	of space, or -ESPIPE it exists but has the wrong size
+ * Return: 0 if OK, -ENOSPC if it is missing and could not be added due to lack
+ * of space, or -ESPIPE it exists but has the wrong size
  */
 int bloblist_ensure_size(uint tag, int size, int align, void **blobp);
 
@@ -217,8 +217,8 @@ int bloblist_ensure_size(uint tag, int size, int align, void **blobp);
  *
  * @tag:	Tag to add (enum bloblist_tag_t)
  * @size:	Size of the blob
- * @return pointer to blob, or NULL if it is missing and could not be added due
- *	to lack of space, or it exists but has the wrong size
+ * Return: pointer to blob, or NULL if it is missing and could not be added due
+ * to lack of space, or it exists but has the wrong size
  */
 void *bloblist_ensure(uint tag, int size);
 
@@ -230,8 +230,8 @@ void *bloblist_ensure(uint tag, int size);
  * @tag:	Tag to add (enum bloblist_tag_t)
  * @sizep:	Size of the blob to create; returns size of actual blob
  * @blobp:	Returns a pointer to blob on success
- * @return 0 if OK, -ENOSPC if it is missing and could not be added due to lack
- *	of space
+ * Return: 0 if OK, -ENOSPC if it is missing and could not be added due to lack
+ * of space
  */
 int bloblist_ensure_size_ret(uint tag, int *sizep, void **blobp);
 
@@ -243,8 +243,8 @@ int bloblist_ensure_size_ret(uint tag, int *sizep, void **blobp);
  *
  * @tag:	Tag to add (enum bloblist_tag_t)
  * @new_size:	New size of the blob (>0 to expand, <0 to contract)
- * @return 0 if OK, -ENOSPC if the bloblist does not have enough space, -ENOENT
- *	if the tag is not found
+ * Return: 0 if OK, -ENOSPC if the bloblist does not have enough space, -ENOENT
+ * if the tag is not found
  */
 int bloblist_resize(uint tag, int new_size);
 
@@ -254,8 +254,8 @@ int bloblist_resize(uint tag, int new_size);
  * @addr: Address of bloblist
  * @size: Initial size for bloblist
  * @flags: Flags to use for bloblist
- * @return 0 if OK, -EFAULT if addr is not aligned correctly, -ENOSPC is the
- *	area is not large enough
+ * Return: 0 if OK, -EFAULT if addr is not aligned correctly, -ENOSPC is the
+ * area is not large enough
  */
 int bloblist_new(ulong addr, uint size, uint flags);
 
@@ -264,11 +264,11 @@ int bloblist_new(ulong addr, uint size, uint flags);
  *
  * @addr: Address of bloblist
  * @size: Expected size of blobsize, or 0 to detect the size
- * @return 0 if OK, -ENOENT if the magic number doesn't match (indicating that
- *	there problem is no bloblist at the given address), -EPROTONOSUPPORT
- *	if the version does not match, -EIO if the checksum does not match,
- *	-EFBIG if the expected size does not match the detected size, -ENOSPC
- *	if the size is not large enough to hold the headers
+ * Return: 0 if OK, -ENOENT if the magic number doesn't match (indicating that
+ * there problem is no bloblist at the given address), -EPROTONOSUPPORT
+ * if the version does not match, -EIO if the checksum does not match,
+ * -EFBIG if the expected size does not match the detected size, -ENOSPC
+ * if the size is not large enough to hold the headers
  */
 int bloblist_check(ulong addr, uint size);
 
@@ -278,7 +278,7 @@ int bloblist_check(ulong addr, uint size);
  * This sets the correct checksum for the bloblist. This ensures that the
  * bloblist will be detected correctly by the next phase of U-Boot.
  *
- * @return 0
+ * Return: 0
  */
 int bloblist_finish(void);
 
@@ -293,26 +293,17 @@ int bloblist_finish(void);
  */
 void bloblist_get_stats(ulong *basep, ulong *sizep, ulong *allocedp);
 
-ulong bloblist_get_base(void);
-
-/**
- * bloblist_get_size() - Get the size of the bloblist
- *
- * @returns the size in bytes
- */
-ulong bloblist_get_size(void);
-
 /**
  * bloblist_get_base() - Get the base address of the bloblist
  *
- * @returns base address of bloblist
+ * Return: base address of bloblist
  */
 ulong bloblist_get_base(void);
 
 /**
  * bloblist_get_size() - Get the size of the bloblist
  *
- * @returns the size in bytes
+ * Return: the size in bytes
  */
 ulong bloblist_get_size(void);
 
@@ -334,7 +325,7 @@ void bloblist_show_list(void);
  * bloblist_tag_name() - Get the name for a tag
  *
  * @tag: Tag to check
- * @return name of tag, or "invalid" if an invalid tag is provided
+ * Return: name of tag, or "invalid" if an invalid tag is provided
  */
 const char *bloblist_tag_name(enum bloblist_tag_t tag);
 
@@ -342,7 +333,7 @@ const char *bloblist_tag_name(enum bloblist_tag_t tag);
  * bloblist_reloc() - Relocate the bloblist and optionally resize it
  *
  * @to: Pointer to new bloblist location (must not overlap old location)
- * @to:size: New size for bloblist (must be larger than from_size)
+ * @to_size: New size for bloblist (must be larger than from_size)
  * @from: Pointer to bloblist to relocate
  * @from_size: Size of bloblist to relocate
  */
@@ -351,8 +342,19 @@ void bloblist_reloc(void *to, uint to_size, void *from, uint from_size);
 /**
  * bloblist_init() - Init the bloblist system with a single bloblist
  *
- * This uses CONFIG_BLOBLIST_ADDR and CONFIG_BLOBLIST_SIZE to set up a bloblist
- * for use by U-Boot.
+ * This locates and sets up the blocklist for use.
+ *
+ * If CONFIG_BLOBLIST_FIXED is selected, it uses CONFIG_BLOBLIST_ADDR and
+ * CONFIG_BLOBLIST_SIZE to set up a bloblist for use by U-Boot.
+ *
+ * If CONFIG_BLOBLIST_ALLOC is selected, it allocates memory for a bloblist of
+ * size CONFIG_BLOBLIST_SIZE.
+ *
+ * If CONFIG_BLOBLIST_PASSAGE is selected, it uses the bloblist in the incoming
+ * standard passage. The size is detected automatically so CONFIG_BLOBLIST_SIZE
+ * can be 0.
+ *
+ * Return: 0 if OK, -ve on error
  */
 int bloblist_init(void);
 
-- 
2.33.1.1089.g2158813163f-goog


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 25/31] bloblist: Relicense to allow BSD-3-Clause
  2021-11-01  1:17 ` Simon Glass
                   ` (24 preceding siblings ...)
  (?)
@ 2021-11-01  1:17 ` Simon Glass
  -1 siblings, 0 replies; 77+ messages in thread
From: Simon Glass @ 2021-11-01  1:17 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Tom Rini, Bin Meng, Ilias Apalodimas, Bill Mills,
	Heinrich Schuchardt, François Ozog, Simon Glass

This implementation is intended to be copied to other projects and
modified, to as to foster a standard means of communcating runtime
information between firmware projects.

The GPL-2 license is too restrictive for some projects, e.g. those
intended as reference implementations rather than designed for
collaborative open-source development.

Update the license to make this easier to share.

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

 common/bloblist.c  | 2 +-
 include/bloblist.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/common/bloblist.c b/common/bloblist.c
index 310ca87dbc4..d068adacf7e 100644
--- a/common/bloblist.c
+++ b/common/bloblist.c
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0+
+// SPDX-License-Identifier: GPL-2.0+ BSD-3-Clause
 /*
  * Copyright 2018 Google, Inc
  * Written by Simon Glass <sjg@chromium.org>
diff --git a/include/bloblist.h b/include/bloblist.h
index 8303f712087..c0045572275 100644
--- a/include/bloblist.h
+++ b/include/bloblist.h
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
+/* SPDX-License-Identifier: GPL-2.0+ BSD-3-Clause */
 /*
  * This provides a standard way of passing information between boot phases
  * (TPL -> SPL -> U-Boot proper.)
-- 
2.33.1.1089.g2158813163f-goog


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 26/31] sandbox: Add a way of checking structs for standard passage
  2021-11-01  1:17 ` Simon Glass
                   ` (25 preceding siblings ...)
  (?)
@ 2021-11-01  1:17 ` Simon Glass
  -1 siblings, 0 replies; 77+ messages in thread
From: Simon Glass @ 2021-11-01  1:17 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Tom Rini, Bin Meng, Ilias Apalodimas, Bill Mills,
	Heinrich Schuchardt, François Ozog, Simon Glass

Add a file which can be used to check that structs used in standard
passage do compile. No other validation is done at present, but could be
considered later.

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

 board/sandbox/Makefile        |  3 ++-
 board/sandbox/stdpass_check.c | 36 +++++++++++++++++++++++++++++++++++
 include/stdpass/README        |  4 ++++
 3 files changed, 42 insertions(+), 1 deletion(-)
 create mode 100644 board/sandbox/stdpass_check.c
 create mode 100644 include/stdpass/README

diff --git a/board/sandbox/Makefile b/board/sandbox/Makefile
index 411b53c2b8d..d9b56adbbb8 100644
--- a/board/sandbox/Makefile
+++ b/board/sandbox/Makefile
@@ -2,4 +2,5 @@
 #
 # Copyright (c) 2011 The Chromium OS Authors.
 
-obj-y	:= sandbox.o
+obj-y	+= sandbox.o
+obj-y	+= stdpass_check.o
diff --git a/board/sandbox/stdpass_check.c b/board/sandbox/stdpass_check.c
new file mode 100644
index 00000000000..565124e1564
--- /dev/null
+++ b/board/sandbox/stdpass_check.c
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * This file compiles all the struct definitions for standard passage, to ensure
+ * there are no errors
+ *
+ * Copyright 2021 Google LLC
+ */
+
+#include <common.h>
+
+/* BLOBLISTT_U_BOOT_SPL_HANDOFF */
+#include <handoff.h>
+void check_spl_handoff(void)
+{
+	__maybe_unused struct spl_handoff check;
+};
+
+/*
+ * See also doc/develop/std_passage.rst
+ *
+ * Instructions:
+ *
+ * 1. Add your header file to U-Boot, or to include/stdpass if it is not used in
+ * U-Boot
+ *
+ * 2. Add a function below to include the header and use the struct
+ *
+ * Template follows, see above for example
+ */
+
+/* BLOBLISTT_tag here */
+/* #include <stdpass/yourfile.h> if not used in U-Boot*/
+void check_struct_name(void)
+{
+	/* __maybe_unused struct struct_name check; */
+}
diff --git a/include/stdpass/README b/include/stdpass/README
new file mode 100644
index 00000000000..a972121f40c
--- /dev/null
+++ b/include/stdpass/README
@@ -0,0 +1,4 @@
+This directory contains standard passage structures
+
+See doc/develop/std_passage.rst for instructions
+
-- 
2.33.1.1089.g2158813163f-goog


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 27/31] passage: Add documentation
  2021-11-01  1:17 ` Simon Glass
                   ` (26 preceding siblings ...)
  (?)
@ 2021-11-01  1:17 ` Simon Glass
  -1 siblings, 0 replies; 77+ messages in thread
From: Simon Glass @ 2021-11-01  1:17 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Tom Rini, Bin Meng, Ilias Apalodimas, Bill Mills,
	Heinrich Schuchardt, François Ozog, Simon Glass

Add documentation about standard passage and update the maintainers.

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

 MAINTAINERS                   |  10 ++
 board/sandbox/stdpass_check.c |  10 +-
 doc/develop/bloblist.rst      |   4 +-
 doc/develop/index.rst         |   1 +
 doc/develop/std_passage.rst   | 319 ++++++++++++++++++++++++++++++++++
 5 files changed, 334 insertions(+), 10 deletions(-)
 create mode 100644 doc/develop/std_passage.rst

diff --git a/MAINTAINERS b/MAINTAINERS
index 5069f188065..4981e4d67a7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1124,6 +1124,16 @@ F:	common/stackprot.c
 F:	cmd/stackprot_test.c
 F:	test/py/tests/test_stackprotector.py
 
+STANDARD PASSAGE
+M:	Simon Glass <sjg@chromium.org>
+F:	board/sandbox/stdpass_check.c
+F:	cmd/bloblist.c
+F:	common/bloblist.c
+F:	doc/develop/std_passage.rst
+F:	include/bloblist.h
+F:	include/stdpass/
+F:	test/bloblist.c
+
 TARGET_BCMNS3
 M:	Bharat Gooty <bharat.gooty@broadcom.com>
 M:	Rayagonda Kokatanur <rayagonda.kokatanur@broadcom.com>
diff --git a/board/sandbox/stdpass_check.c b/board/sandbox/stdpass_check.c
index 565124e1564..8391c7a4aed 100644
--- a/board/sandbox/stdpass_check.c
+++ b/board/sandbox/stdpass_check.c
@@ -8,13 +8,6 @@
 
 #include <common.h>
 
-/* BLOBLISTT_U_BOOT_SPL_HANDOFF */
-#include <handoff.h>
-void check_spl_handoff(void)
-{
-	__maybe_unused struct spl_handoff check;
-};
-
 /*
  * See also doc/develop/std_passage.rst
  *
@@ -23,7 +16,8 @@ void check_spl_handoff(void)
  * 1. Add your header file to U-Boot, or to include/stdpass if it is not used in
  * U-Boot
  *
- * 2. Add a function below to include the header and use the struct
+ * 2. Add a function below to include the header and use the struct. Please put
+ * your function in order of tag ID (see bloblist.h)
  *
  * Template follows, see above for example
  */
diff --git a/doc/develop/bloblist.rst b/doc/develop/bloblist.rst
index 572aa65d764..e819c6dc76b 100644
--- a/doc/develop/bloblist.rst
+++ b/doc/develop/bloblist.rst
@@ -1,7 +1,7 @@
 .. SPDX-License-Identifier: GPL-2.0+
 
-Blob Lists - bloblist
-=====================
+Bloblist
+========
 
 Introduction
 ------------
diff --git a/doc/develop/index.rst b/doc/develop/index.rst
index 5e064a4dac1..6b79045a1a8 100644
--- a/doc/develop/index.rst
+++ b/doc/develop/index.rst
@@ -19,6 +19,7 @@ Implementation
    logging
    makefiles
    menus
+   std_passage
    uefi/index
    version
 
diff --git a/doc/develop/std_passage.rst b/doc/develop/std_passage.rst
new file mode 100644
index 00000000000..9c938636972
--- /dev/null
+++ b/doc/develop/std_passage.rst
@@ -0,0 +1,319 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+Standard Passage
+================
+
+Introduction
+------------
+
+It is sometimes necessary for SPL to communicate information to U-Boot proper,
+such as the RAM size. This can sometimes be handled by adding the value to a
+Kconfig which both SPL and U-Boot proper can use. But this does not work for
+values which are detected at runtime.
+
+In some cases other firmware binaries are used alongside U-Boot and these may
+need to pass information to U-Boot or receive information from it. In this case
+there is no shared build system and it is clumsy so have to specify matching
+build options across projects.
+
+U-Boot provides a standard way of passing information between different phases
+(TPL, SPL, U-Boot). This is called `standard passage` since it creates a
+standard passage through which any sort of information can flow.
+
+
+How it works
+------------
+
+The standard passage is very simple. It is really just a way of sending a
+bloblist between programs, either at a fixed address, or using registers to
+indicate the location.
+
+A :doc:`bloblist` is a simple, contiguous data structure containing a number of
+blobs. Each blob has a tag to indicate what it contains. It is designed for
+simple information, like a small C struct. For more complex data, a devicetree
+is preferred since it has bindings and is extensible.
+
+The bloblist is typically set up initially by one of the early phases of U-Boot,
+such as TPL. It starts either at a fixed address or is allocated in memory using
+malloc(). After that, TPL passes the location of the bloblist to SPL (using
+machine register in an architecture-specific way) and SPL passes it to U-Boot
+proper. It is possible to add new blobs to the bloblist at each phase. U-Boot
+proper relocates the bloblist so can expand it if desired.
+
+
+Use by other projects
+---------------------
+
+The standard passage is also intended to be used by other firmware projects,
+particularly if they interface with U-Boot. It allows that project's firmware
+binaries to pass information to U-Boot (if they run before U-Boot) or receive
+information from U-Boot (if they run afterwards).
+
+These projects can copy and modify the bloblist code provided they have a
+compatible license.
+
+
+Allocating tags
+---------------
+
+Tags are defined in the `bloblist.h` header file. For the moment, the U-Boot
+tree is the upstream repository for tags.
+
+Tags may be allocated in the following areas:
+
+BLOBLISTT_AREA_FIRMWARE_TOP
+    A small area for tags of considerable relevance to multiple projects
+
+BLOBLISTT_AREA_FIRMWARE
+    A larger area for tags likely to be relevant to multiple projects either now
+    or in the future
+
+BLOBLISTT_PROJECT_AREA
+    Used for specific projects that want to make sure their tags are correctly
+    ignored by other binaries in the firmware flow. This area should not be
+    used for tags that are used by multiple projects. Instead, use
+    `BLOBLISTT_AREA_FIRMWARE`.
+
+BLOBLISTT_VENDOR_AREA
+    Used for specific vendors that want to make sure their tags are correctly
+    ignored by other binaries in the firmware flow. This area should not be
+    used for tags that are used by multiple vendors. Instead, use
+    `BLOBLISTT_AREA_FIRMWARE`.
+
+BLOBLISTT_PRIVATE_AREA
+    Used for private flags. Do not send patches with these. They are for local
+    or temporary use. Standard firmware binaries which see these tags in the
+    bloblist typically refuse to boot.
+
+To add a new tag for your project, send a patch to the U-Boot project with:
+
+  - your new tag, using the next available number in the area your choose
+  - a header file in include/stdpass/ containing your struct definition if your
+    struct is not actually used in U-Boot
+  - a line of code in `board/sandbox/stdpass_check.c` to use the struct (see
+    that file for instructions)
+
+The struct definition does not need to match the code style or types names used
+in the other project. For example, your project might use a type like
+__UNSIGNED_INT32 which in U-Boot would be written as u32. Types should be sized
+so that the struct is the same on 32- and 64-bit machines. Avoid using __packed
+if possible. Instead try to order members so that it is not necessary.
+
+Conflicts are resolved before applying patches to mainline, so your actual tag
+value may change when the patch is applied. Once your patch is accepted your tag
+is allocated for all time.
+
+Devicetree
+----------
+
+Devicetree has a special place in the standard passage. One of the bloblist tags
+is BLOBLISTT_CONTROL_DTB which indicates that that blob contains a devicetree
+intended to control U-Boot (or other binaries). This devicetree provides
+hardware information and configuration in a generic way using standard bindings,
+so that it is available for any project to use. The bindings are compatible with
+operating systems (including Linux) so there is no need to remove them before
+calling the OS.
+
+In cases where a binary wants to access the devicetree but does not want to
+implement the bloblist feature, the offset of the devicetree within the
+bloblist is provided. This avoids the need to implement bloblists just to
+access the devicetree. This is a convenience feature intended for use in
+degenerate cases.
+
+However U-Boot itself does not permit accepting a devicetree through standard
+passage unless it is part of a valid bloblist. It is easy to turn on the
+bloblist feature in U-Boot, so such a variation would only serve to confuse
+things and encourage degeneration in other projects.
+
+
+Standard passage API
+--------------------
+
+The protocol for passing a bloblist through the standard passage from one
+binary to another is architecture-specific, meaning it works differently on
+32-/64-ARM and x86, for example, if only because of the different register
+naming.
+
+Two registers are used, the same ones as are used for passing the first two
+arguments to a C function using the architecture's procedure-call standard.
+For example, on 32-bit ARM this is:
+
+  =========  ============================
+  Register   Contents
+  =========  ============================
+  r0         Address of bloblist
+  r1         Offset of devicetree from r0
+  =========  ============================
+
+The devicetree is provided as an offset since it must be included within the
+bloblist. It is not permitted to pass a devicetree except in a bloblist, if
+standard passage is used. Boards which require some other arrangement will have
+to use some other, custom arrangement, not standard passage. No variations or
+exceptions are possible, since that would defeat the purpose of a standard.
+
+
+Usage guidelines
+----------------
+
+As mentioned above, blobs should contain small, simple blocks of information,
+typically represented by a C structure. Using it for large or complex structures
+is only permitted if these are defined by a standard byte-accurate form.
+Examples include devicetree, ACPI tables, SMBIOS tables and the like.
+There are also a lot of pre-existing firmware binaries which are quite complex
+but qualify because it is not possible to convert them to devicetree now. Apart
+from those exceptions, keep it simple!
+
+For complex data structures, devicetree can be used. The libfdt library has an
+overhead of around 5-10KB which is small enough that most firmware binaries can
+easily incorporate it. For those that must run in very constrained environments,
+like U-Boot TPL, a simple blob can be used instead, as explained in the
+preceding paragraph.
+
+Devicetree bindings must be defined so that the format of the data is well
+understood. This is done through the `dt-schema`_ project, although this process
+is still in its infancy.
+
+
+Updates
+-------
+
+Updates and patches to this documentation are welcome. Please submit them to
+the U-Boot project in the normal way.
+
+
+Design notes
+------------
+
+This section describes some of the reasons behind the design decisions implied
+by this feature.
+
+Why devicetree?
+~~~~~~~~~~~~~~~
+
+Firmware is getting large and complicated, with a concomitant need for more
+complex communication between binaries. We don't want to use C structs to pass
+around complex data, nor invent new binary formats for everything that comes up.
+The devicetree provides a useful format and is already widely used in firmware.
+It supports bindings and provides validation to check for compliance, by virtue
+of the Linux project and `dt-schema`_. It is easily extensible, being basically
+an efficient, hierarchical, ordered dictionary.
+
+Some examples of how complex and annoying binary formats can become are SMBIOS
+tables and Intel's Video BIOS tables. The world does not need another binary
+format.
+
+
+Why not *just* devicetree?
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Some early firmware binaries run in very little memory and only need to pass a
+few values on to later phases. Devicetree is too heavy-weight for these cases.
+For example, it is generally not possible for TPL to access a devicetree, which
+is one of the motivations for the of-platdata feature.
+
+
+Why not protobuf, YAML, JSON?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+They are not as efficient and either use a lot more code or require parsing
+before use. Devicetree happens to be a nice compromise.
+
+
+Why not something else?
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Possibly. Please propose it.
+
+
+Why not UUIDs?
+~~~~~~~~~~~~~~
+
+Why use a simple integer tag instead of an 'industry-standard' UUID? Many
+reasons:
+
+- Code should be as readable as possible. GUIDs require something like::
+
+    EFI_GUID(0x6dadf1d1, 0xd4cc, 0x4910, \
+        0xbb, 0x6e, 0x82, 0xb1, 0xfd, 0x80, 0xff, 0x3d)
+
+  which is much harder to read than::
+
+    enum {
+        BLOBLISTT_SPL_HANDOFF = 123,
+    };
+
+- UUIDs are more like a hash than a sequence number. Git uses them, although a
+  short form of the hash is commonly shown. Why use a hash to identify
+  something when we only have a small number of items?
+
+- We don't need to worry about collisions in open source software. We can have
+  a shared repo and allocate sequence numbers from there. UUIDs come from the
+  idea that everyone is working independently so people need to be able to
+  allocate their own numbers and be sure that they will not conflict. This is
+  needed in the PC BIOS industry where there is little shared source /
+  cooperation. It is not helpful with open source.
+
+- UUIDs come across as just obfuscation. Does anyone know what these values
+  mean? How would we look them up? Who owns which one? Is there a central
+  registry?::
+
+    EFI_GUID(0x721acf02, 0x4d77, 0x4c2a, 0xb3, 0xdc, 0x27, 0x0b, 0x7b, 0xa9, 0xe4, 0xb0)
+    EFI_GUID(0xa034147d, 0x690c, 0x4154, 0x8d, 0xe6, 0xc0, 0x44, 0x64, 0x1d, 0xe9, 0x42)
+    EFI_GUID(0xbbcff46c, 0xc8d3, 0x4113, 0x89, 0x85, 0xb9, 0xd4, 0xf3, 0xb3, 0xf6, 0x4e)
+    EFI_GUID(0x69a79759, 0x1373, 0x4367, 0xa6, 0xc4, 0xc7, 0xf5, 0x9e, 0xfd, 0x98, 0x6e)
+    EFI_GUID(0xd038747c, 0xd00c, 0x4980, 0xb3, 0x19, 0x49, 0x01, 0x99, 0xa4, 0x7d, 0x55)
+    EFI_GUID(0x9c7c3aa7, 0x5332, 0x4917, 0x82, 0xb9, 0x56, 0xa5, 0xf3, 0xe6, 0x2a, 0x07)
+
+- It is overkill to use 16 bytes for a unique identifier in a shared project.
+  It is about 10^38. Modern SoCs cannot keep that in a register and there is no
+  C int type to represent it on most common hardware today! Having to check that
+  adds time and code to no benefit. In early boot, space and time are
+  particularly precious.
+
+
+Why contiguous?
+~~~~~~~~~~~~~~~
+
+It is easier to allocate a single block of data than to allocate lots of little
+blocks. It is easy to relocate if needed (a simple copy of a block of memory).
+It can be expanded by relocating it. If we absolutely need to create a linked
+list then pointers to external data can be added to a blob.
+
+
+Why bloblist?
+~~~~~~~~~~~~~
+
+Bloblist is a simple format with an integer tag. It avoids UUIDs and meets the
+requirements above. Some tweaks may be desirable to the format, but that can be
+worked out in code review.
+
+
+Why pass the devicetree offset?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In cases where a binary wants to access the devicetree but does not want to
+implement the bloblist feature, the offset of the devicetree within the
+bloblist is provided. This avoids the need to implement bloblists just to
+access the devicetree. This is a convenience feature intended for use in
+degenerate cases.
+
+
+Why use registers to pass values between binaries?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+It seems like the obvious solution. We could use a shared memory region with
+shared configuration between projects, but that is error prone and difficult to
+keep in sync.
+
+
+Why not add magic values to indicate that standard passage is used?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+We could put a magic value in a register to tell the next phase that the
+standard-passage information is available (in other registers). But making it
+a build-time option saves at least one register and makes things a little more
+deterministic at built time. If we know we can rely on it, it is easier to
+use.
+
+
+.. _`dt-schema`: https://github.com/devicetree-org/dt-schema
-- 
2.33.1.1089.g2158813163f-goog


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 28/31] passage: Add docs for spl_handoff
  2021-11-01  1:17 ` Simon Glass
                   ` (27 preceding siblings ...)
  (?)
@ 2021-11-01  1:17 ` Simon Glass
  -1 siblings, 0 replies; 77+ messages in thread
From: Simon Glass @ 2021-11-01  1:17 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Tom Rini, Bin Meng, Ilias Apalodimas, Bill Mills,
	Heinrich Schuchardt, François Ozog, Simon Glass

This tag already exists in U-Boot. Add documentation, following the
format set out.

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

 board/sandbox/stdpass_check.c | 8 ++++++++
 include/handoff.h             | 8 +++++---
 2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/board/sandbox/stdpass_check.c b/board/sandbox/stdpass_check.c
index 8391c7a4aed..9c015b6783e 100644
--- a/board/sandbox/stdpass_check.c
+++ b/board/sandbox/stdpass_check.c
@@ -28,3 +28,11 @@ void check_struct_name(void)
 {
 	/* __maybe_unused struct struct_name check; */
 }
+
+/* BLOBLISTT_U_BOOT_SPL_HANDOFF */
+#include <handoff.h>
+void check_spl_handoff(void)
+{
+	__maybe_unused struct spl_handoff check;
+};
+
diff --git a/include/handoff.h b/include/handoff.h
index 070a79c1b97..30203033ec9 100644
--- a/include/handoff.h
+++ b/include/handoff.h
@@ -9,16 +9,20 @@
 #define __HANDOFF_H
 
 #if CONFIG_IS_ENABLED(HANDOFF)
-
 #include <asm/handoff.h>
+#endif
 
 /**
  * struct spl_handoff - information passed from SPL to U-Boot proper
  *
+ * bloblist_tag: BLOBLISTT_U_BOOT_SPL_HANDOFF
+ *
  * @ram_size: Value to use for gd->ram_size
  */
 struct spl_handoff {
+#if CONFIG_IS_ENABLED(HANDOFF)
 	struct arch_spl_handoff arch;
+#endif
 	u64 ram_size;
 	struct {
 		u64 start;
@@ -43,5 +47,3 @@ void handoff_load_dram_banks(struct spl_handoff *ho);
 int handoff_arch_save(struct spl_handoff *ho);
 
 #endif
-
-#endif
-- 
2.33.1.1089.g2158813163f-goog


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 29/31] x86: Move Intel GNVS file into the common include directory
  2021-11-01  1:17 ` Simon Glass
                   ` (28 preceding siblings ...)
  (?)
@ 2021-11-01  1:17 ` Simon Glass
  -1 siblings, 0 replies; 77+ messages in thread
From: Simon Glass @ 2021-11-01  1:17 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Tom Rini, Bin Meng, Ilias Apalodimas, Bill Mills,
	Heinrich Schuchardt, François Ozog, Simon Glass

Move this so we can include it from sandbox, needed since it is in a
bloblist and must have a check.

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

 arch/x86/cpu/apollolake/acpi.c                    | 2 +-
 arch/x86/cpu/intel_common/acpi.c                  | 2 +-
 arch/x86/include/asm/arch-apollolake/global_nvs.h | 2 +-
 board/google/chromebook_coral/coral.c             | 2 +-
 {arch/x86/include/asm => include}/intel_gnvs.h    | 0
 5 files changed, 4 insertions(+), 4 deletions(-)
 rename {arch/x86/include/asm => include}/intel_gnvs.h (100%)

diff --git a/arch/x86/cpu/apollolake/acpi.c b/arch/x86/cpu/apollolake/acpi.c
index fd21c0b4968..2822b8d06d1 100644
--- a/arch/x86/cpu/apollolake/acpi.c
+++ b/arch/x86/cpu/apollolake/acpi.c
@@ -13,6 +13,7 @@
 #include <common.h>
 #include <cpu.h>
 #include <dm.h>
+#include <intel_gnvs.h>
 #include <log.h>
 #include <p2sb.h>
 #include <pci.h>
@@ -21,7 +22,6 @@
 #include <asm/acpi_table.h>
 #include <asm/cpu_common.h>
 #include <asm/intel_acpi.h>
-#include <asm/intel_gnvs.h>
 #include <asm/intel_pinctrl.h>
 #include <asm/intel_pinctrl_defs.h>
 #include <asm/intel_regs.h>
diff --git a/arch/x86/cpu/intel_common/acpi.c b/arch/x86/cpu/intel_common/acpi.c
index 15f19da2067..4a288e85252 100644
--- a/arch/x86/cpu/intel_common/acpi.c
+++ b/arch/x86/cpu/intel_common/acpi.c
@@ -12,6 +12,7 @@
 #include <bloblist.h>
 #include <cpu.h>
 #include <dm.h>
+#include <intel_gnvs.h>
 #include <acpi/acpigen.h>
 #include <asm/acpigen.h>
 #include <asm/acpi_table.h>
@@ -23,7 +24,6 @@
 #include <asm/mpspec.h>
 #include <asm/smm.h>
 #include <asm/turbo.h>
-#include <asm/intel_gnvs.h>
 #include <asm/arch/iomap.h>
 #include <asm/arch/pm.h>
 #include <asm/arch/systemagent.h>
diff --git a/arch/x86/include/asm/arch-apollolake/global_nvs.h b/arch/x86/include/asm/arch-apollolake/global_nvs.h
index ef8eb228dbe..639d8f2de78 100644
--- a/arch/x86/include/asm/arch-apollolake/global_nvs.h
+++ b/arch/x86/include/asm/arch-apollolake/global_nvs.h
@@ -10,6 +10,6 @@
 #ifndef _GLOBAL_NVS_H_
 #define _GLOBAL_NVS_H_
 
-#include <asm/intel_gnvs.h>
+#include <intel_gnvs.h>
 
 #endif /* _GLOBAL_NVS_H_ */
diff --git a/board/google/chromebook_coral/coral.c b/board/google/chromebook_coral/coral.c
index 53c5171d02b..ca63cf4ef51 100644
--- a/board/google/chromebook_coral/coral.c
+++ b/board/google/chromebook_coral/coral.c
@@ -11,13 +11,13 @@
 #include <cros_ec.h>
 #include <dm.h>
 #include <init.h>
+#include <intel_gnvs.h>
 #include <log.h>
 #include <sysinfo.h>
 #include <acpi/acpigen.h>
 #include <asm-generic/gpio.h>
 #include <asm/acpi_nhlt.h>
 #include <asm/cb_sysinfo.h>
-#include <asm/intel_gnvs.h>
 #include <asm/intel_pinctrl.h>
 #include <dm/acpi.h>
 #include <linux/delay.h>
diff --git a/arch/x86/include/asm/intel_gnvs.h b/include/intel_gnvs.h
similarity index 100%
rename from arch/x86/include/asm/intel_gnvs.h
rename to include/intel_gnvs.h
-- 
2.33.1.1089.g2158813163f-goog


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 30/31] passage: Add checks for pre-existing blobs
  2021-11-01  1:17 ` Simon Glass
                   ` (29 preceding siblings ...)
  (?)
@ 2021-11-01  1:17 ` Simon Glass
  -1 siblings, 0 replies; 77+ messages in thread
From: Simon Glass @ 2021-11-01  1:17 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Tom Rini, Bin Meng, Ilias Apalodimas, Bill Mills,
	Heinrich Schuchardt, François Ozog, Simon Glass

Add checks / documentation for blobs which are already in the list. This
brings U-Boot up to the standard required by the standard-passage
documentation.

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

 board/sandbox/stdpass_check.c   |  71 ++++++++-
 include/stdpass/tpm2_eventlog.h |  42 +++++
 include/stdpass/vboot_ctx.h     | 267 ++++++++++++++++++++++++++++++++
 3 files changed, 379 insertions(+), 1 deletion(-)
 create mode 100644 include/stdpass/tpm2_eventlog.h
 create mode 100644 include/stdpass/vboot_ctx.h

diff --git a/board/sandbox/stdpass_check.c b/board/sandbox/stdpass_check.c
index 9c015b6783e..1db9ad357ee 100644
--- a/board/sandbox/stdpass_check.c
+++ b/board/sandbox/stdpass_check.c
@@ -29,10 +29,79 @@ void check_struct_name(void)
 	/* __maybe_unused struct struct_name check; */
 }
 
+/* BLOBLISTT_CONTROL_DTB */
+void check_control_dtb(void)
+{
+	/*
+	 * Defined by devicetree specification
+	 * https://github.com/devicetree-org/devicetree-specification/releases/tag/v0.3
+	 */
+};
+
+/* BLOBLISTT_ACPI_GNVS */
+#include <intel_gnvs.h>
+void check_acpi_gnvs(void)
+{
+	__maybe_unused struct acpi_global_nvs check;
+}
+
+/* BLOBLISTT_INTEL_VBT */
+void check_intel_vbt(void)
+{
+	/*
+	 * Pre-existing Intel blob, defined by source code
+	 *
+	 * https://github.com/freedesktop/xorg-intel-gpu-tools/blob/master/tools/intel_vbt_defs.h
+	 * https://github.com/freedesktop/xorg-intel-gpu-tools/blob/master/tools/intel_vbt_decode.c
+	 */
+}
+
+/* BLOBLISTT_TPM2_TCG_LOG */
+#include <stdpass/tpm2_eventlog.h>
+void check_tpm2_tcg_log(void)
+{
+	/* Struct for each record */
+	__maybe_unused struct tpm2_eventlog_context check;
+}
+
+/* BLOBLISTT_TCPA_LOG */
+#include <acpi/acpi_table.h>
+void check_tcpa_log(void)
+{
+	__maybe_unused struct acpi_tcpa check;
+};
+
+/* BLOBLISTT_ACPI_TABLES */
+void check_acpi_tables(void)
+{
+	/*
+	 * Defined by UEFI Advanced Configuration and Power Interface (ACPI)
+	 * Specification, Version 6.3, January 2019
+	 * https://uefi.org/sites/default/files/resources/ACPI_6_3_final_Jan30.pdf
+	 */
+}
+
+/* BLOBLISTT_SMBIOS_TABLES */
+void check_smbios_tables(void)
+{
+	/*
+	 * Defined by System Management BIOS (SMBIOS) Reference Specification
+	 * v3.5.0
+	 * https://www.dmtf.org/standards/smbios
+	 */
+}
+
+/* BLOBLISTT_VBOOT_CTX */
+#include <stdpass/vboot_ctx.h>
+void check_vboot_ctx(void)
+{
+	__maybe_unused struct vb2_shared_data check;
+
+}
+
 /* BLOBLISTT_U_BOOT_SPL_HANDOFF */
 #include <handoff.h>
 void check_spl_handoff(void)
 {
 	__maybe_unused struct spl_handoff check;
 };
-
diff --git a/include/stdpass/tpm2_eventlog.h b/include/stdpass/tpm2_eventlog.h
new file mode 100644
index 00000000000..6b258609149
--- /dev/null
+++ b/include/stdpass/tpm2_eventlog.h
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+
+/* taken from https://github.com/tpm2-software/tpm2-tss/blob/master/include/tss2/tss2_tpm2_types.h */
+#define TPM2_MAX_PCRS           32
+
+/* Hash algorithm sizes */
+#define TPM2_SHA_DIGEST_SIZE     20
+#define TPM2_SHA1_DIGEST_SIZE    20
+#define TPM2_SHA256_DIGEST_SIZE  32
+#define TPM2_SHA384_DIGEST_SIZE  48
+#define TPM2_SHA512_DIGEST_SIZE  64
+#define TPM2_SM3_256_DIGEST_SIZE 32
+
+/* taken from https://github.com/tpm2-software/tpm2-tools/blob/master/lib/tpm2_eventlog.h#L14 */
+
+typedef bool (*digest2_callback)(void const *digest, size_t size, void *data);
+typedef bool (*event2_callback)(void const *event_hdr, size_t size, void *data);
+typedef bool (*event2data_callback)(void const *event, u32 type, void *data,
+				    u32 eventlog_version);
+typedef bool (*specid_callback)(void const *event, void *data);
+typedef bool (*log_event_callback)(void const *event_hdr, size_t size,
+				   void *data);
+
+struct tpm2_eventlog_context {
+	void *data;
+	specid_callback specid_cb;
+	log_event_callback log_eventhdr_cb;
+	event2_callback event2hdr_cb;
+	digest2_callback digest2_cb;
+	event2data_callback event2_cb;
+	u32 sha1_used;
+	u32 sha256_used;
+	u32 sha384_used;
+	u32 sha512_used;
+	u32 sm3_256_used;
+	u8 sha1_pcrs[TPM2_MAX_PCRS][TPM2_SHA1_DIGEST_SIZE];
+	u8 sha256_pcrs[TPM2_MAX_PCRS][TPM2_SHA256_DIGEST_SIZE];
+	u8 sha384_pcrs[TPM2_MAX_PCRS][TPM2_SHA384_DIGEST_SIZE];
+	u8 sha512_pcrs[TPM2_MAX_PCRS][TPM2_SHA512_DIGEST_SIZE];
+	u8 sm3_256_pcrs[TPM2_MAX_PCRS][TPM2_SM3_256_DIGEST_SIZE];
+	u32 eventlog_version;
+};
diff --git a/include/stdpass/vboot_ctx.h b/include/stdpass/vboot_ctx.h
new file mode 100644
index 00000000000..ff74e8ba709
--- /dev/null
+++ b/include/stdpass/vboot_ctx.h
@@ -0,0 +1,267 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+
+/*
+ * Taken from https://chromium.googlesource.com/chromiumos/platform/vboot
+ *
+ * Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/*
+ * Size of non-volatile data used by vboot.
+ *
+ * If you only support non-volatile data format V1, then use VB2_NVDATA_SIZE.
+ * If you support V2, use VB2_NVDATA_SIZE_V2 and set context flag
+ * VB2_CONTEXT_NVDATA_V2.
+ */
+#define VB2_NVDATA_SIZE 16
+#define VB2_NVDATA_SIZE_V2 64
+
+/* Size of secure data spaces used by vboot */
+#define VB2_SECDATA_FIRMWARE_SIZE 10
+#define VB2_SECDATA_KERNEL_SIZE_V02 13
+#define VB2_SECDATA_KERNEL_SIZE_V10 40
+#define VB2_SECDATA_KERNEL_MIN_SIZE 13
+#define VB2_SECDATA_KERNEL_MAX_SIZE 64
+#define VB2_SECDATA_FWMP_MIN_SIZE 40
+#define VB2_SECDATA_FWMP_MAX_SIZE 64
+
+/* Helper for aligning fields in vb2_context. */
+#define VB2_PAD_STRUCT3(size, align, count) \
+	u8 _pad##count[align - (((size - 1) % align) + 1)]
+#define VB2_PAD_STRUCT2(size, align, count) VB2_PAD_STRUCT3(size, align, count)
+#define VB2_PAD_STRUCT(size, align) VB2_PAD_STRUCT2(size, align, __COUNTER__)
+
+/* MAX_SIZE should not be changed without bumping up DATA_VERSION_MAJOR. */
+#define VB2_CONTEXT_MAX_SIZE 384
+
+/*
+ * Context for firmware verification.  Pass this to all vboot APIs.
+ *
+ * Context is stored as part of vb2_shared_data, initialized with vb2api_init().
+ * Subsequent retrieval of the context object should be done by calling
+ * vb2api_reinit(), e.g. if switching firmware applications.
+ *
+ * The context struct can be seen as the "publicly accessible" portion of
+ * vb2_shared_data, and thus does not require its own magic and version fields.
+ */
+struct vb2_context {
+	/**********************************************************************
+	 * Fields caller must initialize before calling any API functions.
+	 */
+
+	/*
+	 * Flags; see vb2_context_flags.  Some flags may only be set by caller
+	 * prior to calling vboot functions.
+	 */
+	u64 flags;
+
+	/*
+	 * Non-volatile data.  Caller must fill this from some non-volatile
+	 * location before calling vb2api_fw_phase1.  If the
+	 * VB2_CONTEXT_NVDATA_CHANGED flag is set when a vb2api function
+	 * returns, caller must save the data back to the non-volatile location
+	 * and then clear the flag.
+	 */
+	u8 nvdata[VB2_NVDATA_SIZE_V2];
+	VB2_PAD_STRUCT(VB2_NVDATA_SIZE_V2, 8);
+
+	/*
+	 * Secure data for firmware verification stage.  Caller must fill this
+	 * from some secure non-volatile location before calling
+	 * vb2api_fw_phase1.  If the VB2_CONTEXT_SECDATA_FIRMWARE_CHANGED flag
+	 * is set when a function returns, caller must save the data back to the
+	 * secure non-volatile location and then clear the flag.
+	 */
+	u8 secdata_firmware[VB2_SECDATA_FIRMWARE_SIZE];
+	VB2_PAD_STRUCT(VB2_SECDATA_FIRMWARE_SIZE, 8);
+
+	/**********************************************************************
+	 * Fields caller must initialize before calling vb2api_kernel_phase1().
+	 */
+
+	/*
+	 * Secure data for kernel verification stage.  Caller must fill this
+	 * from some secure non-volatile location before calling
+	 * vb2api_kernel_phase1.  If the VB2_CONTEXT_SECDATA_KERNEL_CHANGED
+	 * flag is set when a function returns, caller must save the data back
+	 * to the secure non-volatile location and then clear the flag.
+	 */
+	u8 secdata_kernel[VB2_SECDATA_KERNEL_MAX_SIZE];
+	VB2_PAD_STRUCT(VB2_SECDATA_KERNEL_MAX_SIZE, 8);
+
+	/*
+	 * Firmware management parameters (FWMP) secure data.  Caller must fill
+	 * this from some secure non-volatile location before calling
+	 * vb2api_kernel_phase1.  Since FWMP is a variable-size space, caller
+	 * should initially fill in VB2_SECDATA_FWMP_MIN_SIZE bytes, and call
+	 * vb2_secdata_fwmp_check() to see whether more should be read.  If the
+	 * VB2_CONTEXT_SECDATA_FWMP_CHANGED flag is set when a function
+	 * returns, caller must save the data back to the secure non-volatile
+	 * location and then clear the flag.
+	 */
+	u8 secdata_fwmp[VB2_SECDATA_FWMP_MAX_SIZE];
+	VB2_PAD_STRUCT(VB2_SECDATA_FWMP_MAX_SIZE, 8);
+
+	/*
+	 * Context pointer for use by caller.  Verified boot never looks at
+	 * this.  Put context here if you need it for APIs that verified boot
+	 * may call (vb2ex_...() functions).
+	 */
+	void *non_vboot_context;
+};
+
+/*
+ * Data shared between vboot API calls.  Stored at the start of the work
+ * buffer.
+ */
+struct vb2_shared_data {
+	/* Magic number for struct (VB2_SHARED_DATA_MAGIC) */
+	u32 magic;
+
+	/* Version of this structure */
+	u16 struct_version_major;
+	u16 struct_version_minor;
+
+	/* Public fields are stored in the context object */
+	struct vb2_context ctx;
+
+	/* Padding for adding future vb2_context fields */
+	u8 padding[VB2_CONTEXT_MAX_SIZE - sizeof(struct vb2_context)];
+
+	/* Work buffer length in bytes. */
+	u32 workbuf_size;
+
+	/*
+	 * Amount of work buffer used so far.  Verified boot sub-calls use
+	 * this to know where the unused work area starts.
+	 */
+	u32 workbuf_used;
+
+	/* Flags; see enum vb2_shared_data_flags */
+	u32 flags;
+
+	/*
+	 * Reason we are in recovery mode this boot (enum vb2_nv_recovery), or
+	 * 0 if we aren't.
+	 */
+	u32 recovery_reason;
+
+	/* Firmware slot used last boot (0=A, 1=B) */
+	u32 last_fw_slot;
+
+	/* Result of last boot (enum vb2_fw_result) */
+	u32 last_fw_result;
+
+	/* Firmware slot used this boot */
+	u32 fw_slot;
+
+	/*
+	 * Version for this slot (top 16 bits = key, lower 16 bits = firmware).
+	 *
+	 * TODO: Make this a union to allow getting/setting those versions
+	 * separately?
+	 */
+	u32 fw_version;
+
+	/* Version from secdata_firmware (must be <= fw_version to boot). */
+	u32 fw_version_secdata;
+
+	/*
+	 * Status flags for this boot; see enum vb2_shared_data_status.  Status
+	 * is "what we've done"; flags above are "decisions we've made".
+	 */
+	u32 status;
+
+	/* Offset from start of this struct to GBB header */
+	u32 gbb_offset;
+
+	/**********************************************************************
+	 * Data from kernel verification stage.
+	 *
+	 * TODO: shouldn't be part of the main struct, since that needlessly
+	 * uses more memory during firmware verification.
+	 */
+
+	/*
+	 * Version for the current kernel (top 16 bits = key, lower 16 bits =
+	 * kernel preamble).
+	 *
+	 * TODO: Make this a union to allow getting/setting those versions
+	 * separately?
+	 */
+	u32 kernel_version;
+
+	/* Version from secdata_kernel (must be <= kernel_version to boot) */
+	u32 kernel_version_secdata;
+
+	/**********************************************************************
+	 * Temporary variables used during firmware verification.  These don't
+	 * really need to persist through to the OS, but there's nowhere else
+	 * we can put them.
+	 */
+
+	/* Offset of preamble from start of vblock */
+	u32 vblock_preamble_offset;
+
+	/*
+	 * Offset and size of packed data key in work buffer.  Size is 0 if
+	 * data key is not stored in the work buffer.
+	 */
+	u32 data_key_offset;
+	u32 data_key_size;
+
+	/*
+	 * Offset and size of firmware preamble in work buffer.  Size is 0 if
+	 * preamble is not stored in the work buffer.
+	 */
+	u32 preamble_offset;
+	u32 preamble_size;
+
+	/*
+	 * Offset and size of hash context in work buffer.  Size is 0 if
+	 * hash context is not stored in the work buffer.
+	 */
+	u32 hash_offset;
+	u32 hash_size;
+
+	/*
+	 * Current tag we're hashing
+	 *
+	 * For new structs, this is the offset of the vb2_signature struct
+	 * in the work buffer.
+	 *
+	 * TODO: rename to hash_sig_offset when vboot1 structs are deprecated.
+	 */
+	u32 hash_tag;
+
+	/* Amount of data we still expect to hash */
+	u32 hash_remaining_size;
+
+	/**********************************************************************
+	 * Temporary variables used during kernel verification.  These don't
+	 * really need to persist through to the OS, but there's nowhere else
+	 * we can put them.
+	 *
+	 * TODO: make a union with the firmware verification temp variables,
+	 * or make both of them workbuf-allocated sub-structs, so that we can
+	 * overlap them so kernel variables don't bloat firmware verification
+	 * stage memory requirements.
+	 */
+
+	/*
+	 * Formerly a pointer to vboot1 shared data header ("VBSD").  Caller
+	 * may now export a copy of VBSD via vb2api_export_vbsd().
+	 * TODO: Remove this field and bump struct_version_major.
+	 */
+	uintptr_t reserved0;
+
+	/*
+	 * Offset and size of packed kernel key in work buffer.  Size is 0 if
+	 * subkey is not stored in the work buffer.  Note that kernel key may
+	 * be inside the firmware preamble.
+	 */
+	u32 kernel_key_offset;
+	u32 kernel_key_size;
+} __packed;
-- 
2.33.1.1089.g2158813163f-goog


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 31/31] WIP: RFC: Add a gitlab test
  2021-11-01  1:17 ` Simon Glass
                   ` (30 preceding siblings ...)
  (?)
@ 2021-11-01  1:17 ` Simon Glass
  -1 siblings, 0 replies; 77+ messages in thread
From: Simon Glass @ 2021-11-01  1:17 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Tom Rini, Bin Meng, Ilias Apalodimas, Bill Mills,
	Heinrich Schuchardt, François Ozog, Simon Glass

This needs fixing up once the new hooks land as well as adding an
azure rule.

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

 .gitlab-ci.yml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index e7c65ebbcef..33466ec2a8a 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -240,6 +240,12 @@ qemu_arm64 test.py:
     TEST_PY_TEST_SPEC: "not sleep"
   <<: *buildman_and_testpy_dfn
 
+#qemu_arm spl_test.py:
+#  variables:
+#    TEST_PY_BD: "qemu_arm_spl"
+#    TEST_PY_TEST_SPEC: "not sleep"
+#  <<: *buildman_and_testpy_dfn
+
 qemu_malta test.py:
   variables:
     TEST_PY_BD: "malta"
-- 
2.33.1.1089.g2158813163f-goog


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* Re: [PATCH 01/31] Makefile: Correct TPL rule for OF_REAL
  2021-11-01  1:17 ` [PATCH 01/31] Makefile: Correct TPL rule for OF_REAL Simon Glass
@ 2021-11-01  6:54   ` Ilias Apalodimas
  2021-11-14  0:34   ` Simon Glass
  1 sibling, 0 replies; 77+ messages in thread
From: Ilias Apalodimas @ 2021-11-01  6:54 UTC (permalink / raw)
  To: Simon Glass
  Cc: U-Boot Mailing List, Tom Rini, Bin Meng, Bill Mills,
	Heinrich Schuchardt, François Ozog, Masahiro Yamada

Hi Simon,

As I expect this series to go through some versions before we agree on
something and this seems like a pure bugfix can you split it of as a
single patch?

On Mon, 1 Nov 2021 at 03:19, Simon Glass <sjg@chromium.org> wrote:
>
> Correct an error in the tpl-dtb parameter to binman. At present the TPL
> rule follows SPL but this is not correct, if TPL uses of-platdata, for
> example.
>
> Fixes: f99cbe4e867 ("fdt: Update Makefile rules with the new OF_REAL Kconfig")
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
>  Makefile | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/Makefile b/Makefile
> index 09a5cea8cb8..d256a3cdc33 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -1309,7 +1309,7 @@ cmd_binman = $(srctree)/tools/binman/binman $(if $(BINMAN_DEBUG),-D) \
>                 -a spl-bss-pad=$(if $(CONFIG_SPL_SEPARATE_BSS),,1) \
>                 -a tpl-bss-pad=$(if $(CONFIG_TPL_SEPARATE_BSS),,1) \
>                 -a spl-dtb=$(CONFIG_SPL_OF_REAL) \
> -               -a tpl-dtb=$(CONFIG_SPL_OF_REAL) \
> +               -a tpl-dtb=$(CONFIG_TPL_OF_REAL) \
>                 $(BINMAN_$(@F))
>
>  OBJCOPYFLAGS_u-boot.ldr.hex := -I binary -O ihex
> --
> 2.33.1.1089.g2158813163f-goog
>

Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 02/31] kconfig: Add support for conditional values
  2021-11-01  1:17 ` [PATCH 02/31] kconfig: Add support for conditional values Simon Glass
@ 2021-11-01  7:05   ` Ilias Apalodimas
  2022-01-12 21:28     ` Simon Glass
  0 siblings, 1 reply; 77+ messages in thread
From: Ilias Apalodimas @ 2021-11-01  7:05 UTC (permalink / raw)
  To: Simon Glass
  Cc: U-Boot Mailing List, Tom Rini, Bin Meng, Bill Mills,
	Heinrich Schuchardt, François Ozog, Masahiro Yamada

On Mon, 1 Nov 2021 at 03:19, Simon Glass <sjg@chromium.org> wrote:
>
> At present if an optional Kconfig value needs to be used it must be
> bracketed by #ifdef. For example, with this Kconfig setup:
>
> config WIBBLE
>         bool "Support wibbles, the world needs more wibbles"
>
> config WIBBLE_ADDR
>         hex "Address of the wibble"
>         depends on WIBBLE
>
> then the following code must be used:
>
>  #ifdef CONFIG_WIBBLE
>  static void handle_wibble(void)
>  {
>         int val = CONFIG_WIBBLE_ADDR;
>
>         ...
>  }
>  #endif
>

The example here might be a bit off and we might need this for int
related values. Was this function handle_wibble() supposed to return
an int or not?  We could shield the linker easier here without adding
macros. Something along the lines of
static void handle_wibble(void)
{
#ifdef CONFIG_WIBBLE
int val = CONFIG_WIBBLE_ADDR;
#endif
}

In that case you don't an extra ifdef to call handle_wibble().
Personally I find this easier to read.

>  static void init_machine()
>  {
>  ...
>  #ifdef CONFIG_WIBBLE
>         handle_wibble();
>  #endif
>  }
>
> Add a new IF_ENABLED_INT() to help with this. So now it is possible to
> write, without #ifdefs:
>
>  static void handle_wibble(void)
>  {
>         int val = IF_ENABLED_INT(CONFIG_WIBBLE, CONFIG_WIBBLE_ADDR);
>
>         ...
>  }
>
>  static void init_machine()
>  {
>  ...
>  if (IS_ENABLED(CONFIG_WIBBLE))
>         handle_wibble();
>  }
>
> The value will be 0 if CONFIG_WIBBLE is not defined, and
> CONFIG_WIBBLE_ADDR if it is. This allows us to reduce the use of #ifdef in
> the code, ensuring that the compiler still checks the code even if it is
> not ultimately used for a particular build.
>
> Add a CONFIG_IF_ENABLED_INT() version as well.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
>  include/linux/kconfig.h      | 18 ++++++++++++++++++
>  scripts/config_whitelist.txt |  1 +
>  2 files changed, 19 insertions(+)
>
> diff --git a/include/linux/kconfig.h b/include/linux/kconfig.h
> index a1d1a298426..119c698a158 100644
> --- a/include/linux/kconfig.h
> +++ b/include/linux/kconfig.h
> @@ -59,6 +59,18 @@
>   */
>  #define CONFIG_VAL(option)  config_val(option)
>
> +/* This use a similar mechanism to config_enabled() above */
> +#define config_opt_enabled(cfg, opt_cfg) _config_opt_enabled(cfg, opt_cfg)
> +#define _config_opt_enabled(cfg_val, opt_value) \
> +       __config_opt_enabled(__ARG_PLACEHOLDER_##cfg_val, opt_value)
> +#define __config_opt_enabled(arg1_or_junk, arg2) \
> +       ___config_opt_enabled(arg1_or_junk arg2, 0)
> +#define ___config_opt_enabled(__ignored, val, ...) val
> +
> +/* Evaluates to 0 if option is not defined, int_option if it is defined */
> +#define IF_ENABLED_INT(option, int_option) \
> +       config_opt_enabled(option, int_option)
> +
>  /*
>   * Count number of arguments to a variadic macro. Currently only need
>   * it for 1, 2 or 3 arguments.
> @@ -113,5 +125,11 @@
>  #define CONFIG_IS_ENABLED(option, ...)                                 \
>         __concat(__CONFIG_IS_ENABLED_, __count_args(option, ##__VA_ARGS__)) (option, ##__VA_ARGS__)
>
> +/*
> + * Evaluates to 0 if SPL_/TPL_/option is not defined, SPL_/TPL_int_option if it
> + * is defined
> + */
> +#define CONFIG_IF_ENABLED_INT(option, int_option) \
> +       CONFIG_IS_ENABLED(option, (CONFIG_VAL(int_option)), (0))
>
>  #endif /* __LINUX_KCONFIG_H */
> diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
> index 022a27288c9..f9d9f4a9cfe 100644
> --- a/scripts/config_whitelist.txt
> +++ b/scripts/config_whitelist.txt
> @@ -609,6 +609,7 @@ CONFIG_ICS307_REFCLK_HZ
>  CONFIG_IDE_PREINIT
>  CONFIG_IDE_RESET
>  CONFIG_IDE_SWAP_IO
> +CONFIG_IF_ENABLED_INT
>  CONFIG_IMA
>  CONFIG_IMX
>  CONFIG_IMX6_PWM_PER_CLK
> --
> 2.33.1.1089.g2158813163f-goog
>

Regards
/Ilias

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 03/31] dm: core: Allow getting some basic stats
  2021-11-01  1:17 ` [PATCH 03/31] dm: core: Allow getting some basic stats Simon Glass
@ 2021-11-01  7:07   ` Ilias Apalodimas
  0 siblings, 0 replies; 77+ messages in thread
From: Ilias Apalodimas @ 2021-11-01  7:07 UTC (permalink / raw)
  To: Simon Glass
  Cc: U-Boot Mailing List, Tom Rini, Bin Meng, Bill Mills,
	Heinrich Schuchardt, François Ozog, Marek Vasut,
	Pavel Herrmann

Hi Simon,

How is this related to the bloblist patchset? Is it required or it can split of?

Regards
/Ilias


On Mon, 1 Nov 2021 at 03:19, Simon Glass <sjg@chromium.org> wrote:
>
> Add a function that returns some basic stats about driver model. For now
> we only have two.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
>  drivers/core/device.c        | 11 ++++++++++
>  drivers/core/root.c          |  7 ++++++
>  drivers/core/uclass.c        | 13 ++++++++++++
>  include/dm/device.h          | 11 +++++++++-
>  include/dm/root.h            |  8 +++++++
>  include/dm/uclass-internal.h |  7 ++++++
>  test/dm/core.c               | 41 ++++++++++++++++++++++++++++++++++++
>  7 files changed, 97 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/core/device.c b/drivers/core/device.c
> index d7a778a2413..7d327aba49e 100644
> --- a/drivers/core/device.c
> +++ b/drivers/core/device.c
> @@ -723,6 +723,17 @@ int device_get_child_count(const struct udevice *parent)
>         return count;
>  }
>
> +int device_get_decendent_count(const struct udevice *parent)
> +{
> +       const struct udevice *dev;
> +       int count = 1;
> +
> +       list_for_each_entry(dev, &parent->child_head, sibling_node)
> +               count += device_get_decendent_count(dev);
> +
> +       return count;
> +}
> +
>  int device_find_child_by_seq(const struct udevice *parent, int seq,
>                              struct udevice **devp)
>  {
> diff --git a/drivers/core/root.c b/drivers/core/root.c
> index 26b8195faa3..815173f86eb 100644
> --- a/drivers/core/root.c
> +++ b/drivers/core/root.c
> @@ -26,6 +26,7 @@
>  #include <dm/read.h>
>  #include <dm/root.h>
>  #include <dm/uclass.h>
> +#include <dm/uclass-internal.h>
>  #include <dm/util.h>
>  #include <linux/list.h>
>
> @@ -407,6 +408,12 @@ int dm_init_and_scan(bool pre_reloc_only)
>         return 0;
>  }
>
> +void dm_get_stats(int *device_countp, int *uclass_countp)
> +{
> +       *device_countp = device_get_decendent_count(gd->dm_root);
> +       *uclass_countp = uclass_get_count();
> +}
> +
>  #ifdef CONFIG_ACPIGEN
>  static int root_acpi_get_name(const struct udevice *dev, char *out_name)
>  {
> diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c
> index c5a50952fd0..46b3e85fdbb 100644
> --- a/drivers/core/uclass.c
> +++ b/drivers/core/uclass.c
> @@ -638,6 +638,19 @@ int uclass_next_device_check(struct udevice **devp)
>         return device_probe(*devp);
>  }
>
> +int uclass_get_count(void)
> +{
> +       const struct uclass *uc;
> +       int count = 0;
> +
> +       if (gd->dm_root) {
> +               list_for_each_entry(uc, gd->uclass_root, sibling_node)
> +                       count++;
> +       }
> +
> +       return count;
> +}
> +
>  int uclass_first_device_drvdata(enum uclass_id id, ulong driver_data,
>                                 struct udevice **devp)
>  {
> diff --git a/include/dm/device.h b/include/dm/device.h
> index 3028d002ab0..68e783ea409 100644
> --- a/include/dm/device.h
> +++ b/include/dm/device.h
> @@ -593,7 +593,7 @@ int device_get_child(const struct udevice *parent, int index,
>                      struct udevice **devp);
>
>  /**
> - * device_get_child_count() - Get the available child count of a device
> + * device_get_child_count() - Get the child count of a device
>   *
>   * Returns the number of children to a device.
>   *
> @@ -601,6 +601,15 @@ int device_get_child(const struct udevice *parent, int index,
>   */
>  int device_get_child_count(const struct udevice *parent);
>
> +/**
> + * device_get_decendent_count() - Get the total number of decendents of a device
> + *
> + * Returns the total number of decendents, including all children
> + *
> + * @parent:    Parent device to check
> + */
> +int device_get_decendent_count(const struct udevice *parent);
> +
>  /**
>   * device_find_child_by_seq() - Find a child device based on a sequence
>   *
> diff --git a/include/dm/root.h b/include/dm/root.h
> index 42510b106ab..780f269db65 100644
> --- a/include/dm/root.h
> +++ b/include/dm/root.h
> @@ -131,4 +131,12 @@ int dm_remove_devices_flags(uint flags);
>  static inline int dm_remove_devices_flags(uint flags) { return 0; }
>  #endif
>
> +/**
> + * dm_get_stats() - Get some stats for driver mode
> + *
> + * @device_countp: Returns total number of devices that are bound
> + * @uclass_countp: Returns total number of uclasses in use
> + */
> +void dm_get_stats(int *device_countp, int *uclass_countp);
> +
>  #endif
> diff --git a/include/dm/uclass-internal.h b/include/dm/uclass-internal.h
> index 57c664c6daa..c71d8b1de45 100644
> --- a/include/dm/uclass-internal.h
> +++ b/include/dm/uclass-internal.h
> @@ -294,6 +294,13 @@ int uclass_pre_remove_device(struct udevice *dev);
>  static inline int uclass_pre_remove_device(struct udevice *dev) { return 0; }
>  #endif
>
> +/**
> + * uclass_get_count() - Get the number of uclasses
> + *
> + * Returns the number of uclasses instantiated in driver model
> + */
> +int uclass_get_count(void);
> +
>  /**
>   * uclass_find() - Find uclass by its id
>   *
> diff --git a/test/dm/core.c b/test/dm/core.c
> index c9a7606666c..c76dfdb1651 100644
> --- a/test/dm/core.c
> +++ b/test/dm/core.c
> @@ -307,11 +307,15 @@ static int dm_test_lifecycle(struct unit_test_state *uts)
>  {
>         int op_count[DM_TEST_OP_COUNT];
>         struct udevice *dev, *test_dev;
> +       int start_dev_count, start_uc_count;
> +       int dev_count, uc_count;
>         int pingret;
>         int ret;
>
>         memcpy(op_count, dm_testdrv_op_count, sizeof(op_count));
>
> +       dm_get_stats(&start_dev_count, &start_uc_count);
> +
>         ut_assertok(device_bind_by_name(uts->root, false, &driver_info_manual,
>                                         &dev));
>         ut_assert(dev);
> @@ -319,6 +323,11 @@ static int dm_test_lifecycle(struct unit_test_state *uts)
>                         == op_count[DM_TEST_OP_BIND] + 1);
>         ut_assert(!dev_get_priv(dev));
>
> +       /* We should have one more device */
> +       dm_get_stats(&dev_count, &uc_count);
> +       ut_asserteq(start_dev_count + 1, dev_count);
> +       ut_asserteq(start_uc_count, uc_count);
> +
>         /* Probe the device - it should fail allocating private data */
>         uts->force_fail_alloc = 1;
>         ret = device_probe(dev);
> @@ -353,6 +362,11 @@ static int dm_test_lifecycle(struct unit_test_state *uts)
>         ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_UNBIND]);
>         ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_PRE_UNBIND]);
>
> +       /* We should have one less device */
> +       dm_get_stats(&dev_count, &uc_count);
> +       ut_asserteq(start_dev_count, dev_count);
> +       ut_asserteq(start_uc_count, uc_count);
> +
>         return 0;
>  }
>  DM_TEST(dm_test_lifecycle, UT_TESTF_SCAN_PDATA | UT_TESTF_PROBE_TEST);
> @@ -526,17 +540,31 @@ DM_TEST(dm_test_leak, 0);
>  /* Test uclass init/destroy methods */
>  static int dm_test_uclass(struct unit_test_state *uts)
>  {
> +       int dev_count, uc_count;
>         struct uclass *uc;
>
> +       /* We should have just the root device and uclass */
> +       dm_get_stats(&dev_count, &uc_count);
> +       ut_asserteq(1, dev_count);
> +       ut_asserteq(1, uc_count);
> +
>         ut_assertok(uclass_get(UCLASS_TEST, &uc));
>         ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_INIT]);
>         ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_DESTROY]);
>         ut_assert(uclass_get_priv(uc));
>
> +       dm_get_stats(&dev_count, &uc_count);
> +       ut_asserteq(1, dev_count);
> +       ut_asserteq(2, uc_count);
> +
>         ut_assertok(uclass_destroy(uc));
>         ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_INIT]);
>         ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_DESTROY]);
>
> +       dm_get_stats(&dev_count, &uc_count);
> +       ut_asserteq(1, dev_count);
> +       ut_asserteq(1, uc_count);
> +
>         return 0;
>  }
>  DM_TEST(dm_test_uclass, 0);
> @@ -1217,3 +1245,16 @@ static int dm_test_dma_offset(struct unit_test_state *uts)
>  }
>  DM_TEST(dm_test_dma_offset, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
>  #endif
> +
> +/* Test dm_get_stats() */
> +static int dm_test_get_stats(struct unit_test_state *uts)
> +{
> +       int dev_count, uc_count;
> +
> +       dm_get_stats(&dev_count, &uc_count);
> +       ut_assert(dev_count > 50);
> +       ut_assert(uc_count > 30);
> +
> +       return 0;
> +}
> +DM_TEST(dm_test_get_stats, UT_TESTF_SCAN_FDT);
> --
> 2.33.1.1089.g2158813163f-goog
>

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 05/31] fdt: Drop SPL_BUILD macro
  2021-11-01  1:17 ` [PATCH 05/31] fdt: Drop SPL_BUILD macro Simon Glass
@ 2021-11-01  7:42   ` Ilias Apalodimas
  0 siblings, 0 replies; 77+ messages in thread
From: Ilias Apalodimas @ 2021-11-01  7:42 UTC (permalink / raw)
  To: Simon Glass
  Cc: U-Boot Mailing List, Tom Rini, Bin Meng, Bill Mills,
	Heinrich Schuchardt, François Ozog, Jerry Van Baren

Hi Simon,

Seems irrelevant to the current series, but can be sent with patch#1 separately?

On Mon, 1 Nov 2021 at 03:19, Simon Glass <sjg@chromium.org> wrote:
>
> This old macro is not needed anymore since we can use IS_ENABLED() now.
> Drop it.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
>  drivers/serial/serial-uclass.c | 3 ++-
>  include/fdtdec.h               | 6 ------
>  2 files changed, 2 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c
> index 30d44214d7d..96a1cb65ba2 100644
> --- a/drivers/serial/serial-uclass.c
> +++ b/drivers/serial/serial-uclass.c
> @@ -104,7 +104,8 @@ static void serial_find_console_or_panic(void)
>                         }
>                 }
>         }
> -       if (!SPL_BUILD || !CONFIG_IS_ENABLED(OF_CONTROL) || !blob) {
> +       if (!IS_ENABLED(CONFIG_SPL_BUILD) || !CONFIG_IS_ENABLED(OF_CONTROL) ||
> +           !blob) {
>                 /*
>                  * Try to use CONFIG_CONS_INDEX if available (it is numbered
>                  * from 1!).
> diff --git a/include/fdtdec.h b/include/fdtdec.h
> index 68a36f10583..24992baed8b 100644
> --- a/include/fdtdec.h
> +++ b/include/fdtdec.h
> @@ -49,12 +49,6 @@ struct fdt_memory {
>
>  struct bd_info;
>
> -#ifdef CONFIG_SPL_BUILD
> -#define SPL_BUILD      1
> -#else
> -#define SPL_BUILD      0
> -#endif
> -
>  /*
>   * Information about a resource. start is the first address of the resource
>   * and end is the last address (inclusive). The length of the resource will
> --
> 2.33.1.1089.g2158813163f-goog
>

Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 00/31] passage: Define a standard for firmware data flow
  2021-11-01  1:17 ` Simon Glass
@ 2021-11-01  8:53   ` François Ozog
  -1 siblings, 0 replies; 77+ messages in thread
From: François Ozog @ 2021-11-01  8:53 UTC (permalink / raw)
  To: Simon Glass
  Cc: U-Boot Mailing List, Tom Rini, Bin Meng, Ilias Apalodimas,
	Bill Mills, Heinrich Schuchardt, Albert Aribaud, Jerry Van Baren,
	Marek Vasut, Masahiro Yamada, Pavel Herrmann, qemu-devel

Hi Simon,

this seems a great endeavor. I'd like to better understand the scope of it.

Is it to be used as part of what could become a U-Boot entry ABI scheme? By
that I mean giving some fixed aspects
to U-Boot entry while letting boards to have flexibility (say for instance
that the first 5 architecture ABI
parameter registers are reserved for U-Boot), and the Passage is about
specifying either those reserved registers
or one of them?

Thinking entry ABI, here is what I observed on Arm:

Linux has two entry ABIs:
- plain: x0 = dtb;
          command line = dtb:/chosen/bootargs; initrd =
dtb:/chosen/linux,initrd-*
- EFI: x0=handle, x1=systemtable, x30=return address;
           dtb = EFI_UUID config table; initrd = efi:<loadfile2(INITRD
vendor media UUID); command line = efi: image_protocol::load_options

U-Boot (proper) has plenty of schemes:
- dtb is passed as either x0, x1, fixed memory area (Qemu which is bad in
itself), or other registers
- additional information passing: board specific register scheme, SMC calls
- U-Boot for RPI boards implement a Linux shaped entry ABI to be launched
by Videocore firmware

Based on all the above, I would tend to think that RPI scheme is a good
idea but also
shall not prevent additional schemes for the boards.

What about a U-Boot Arm entry ABI like:
- plain: x0=dtb, x1=<Passage defined>, x2-x5 = <reserved>, other registers
are per platform, SMC calls allowed too
- EFI: x0=handle, x1=systemtable, x30=return address;  (when U-Boot is
launched as an EFI app)
       dtb = EFI_UUID config table, + Passage = Passage UUID config table

We could further leverage Passage to pass Operating Systems parameters that
could be removed from device tree (migration of /chosen to Passage). Memory
inventory would still be in DT but allocations for CMA or GPUs would be in
Passage. This idea is to reach a point where  device tree is a "pristine"
hardware description.

Cheers

PS: as Ilias mentions, this patch set contains bug fixes, non immediately
related additional functions (DM stats). It would be great to carve those
out to fast path them and keep this one with the very core of your idea.

On Mon, 1 Nov 2021 at 02:17, Simon Glass <sjg@chromium.org> wrote:

>
> This series adds a standard way of passing information between different
> firmware phases. This already exists in U-Boot at a very basic level, in
> the form of a bloblist containing an spl_handoff structure, but the intent
> here is to define something useful across projects.
>
> The need for this is growing as firmware fragments into multiple binaries
> each with its own purpose. Without any run-time connection, we must rely
> on build-time settings which are brittle and painful to keep in sync.
>
> This feature is named 'standard passage' since the name is more unique
> than many others that could be chosen, it is a passage in the sense that
> information is flowing from one place to another and it is standard,
> because that is what we want to create.
>
> The implementation is simply a pointer to a bloblist in a register, with
> an extra register to point to a devicetree, for more complex data, if one
> is present in the bloblist. This should cover all cases (small memory
> footprint as well as complex data flow) and be easy enough to implement on
> all architectures.
>
> The core bloblist code is relicensed to BSD-3-Clause in case it is useful
> in non-GPL projects but there is no requirement to use the same code.
>
> This series includes tweaks to the bloblist implementation in U-Boot to
> make it more suitable for the task, including:
>
>    - Allocate tags explicitly in the enum
>    - Put the magic number first
>    - Define a process for adding tags
>
> The emphasis is on enabling open communcation between binaries, not
> enabling passage of secret, undocumented data, although this is possible
> in a private environment.
>
> This series is built on the OF_BOARD series It is available at
> u-boot-dm/pass-working or:
>
>
> https://source.denx.de/u-boot/custodians/u-boot-dm/-/commit/073b5c156f222c69a98b8ebcaa563d1ff10eb217
>
>
> Simon Glass (31):
>   Makefile: Correct TPL rule for OF_REAL
>   kconfig: Add support for conditional values
>   dm: core: Allow getting some basic stats
>   stddef: Avoid warning with clang with offsetof()
>   fdt: Drop SPL_BUILD macro
>   bloblist: Put the magic number first
>   bloblist: Rename the SPL tag
>   bloblist: Drop unused tags
>   bloblist: Use explicit numbering for the tags
>   bloblist: Support allocating the bloblist
>   bloblist: Use LOG_CATEGORY to simply logging
>   bloblist: Use 'phase' consistently for bloblists
>   bloblist: Refactor Kconfig to support alloc or fixed
>   arm: qemu: Add an SPL build
>   bloblist: Add functions to obtain base address and size
>   passage: Support an incoming passage
>   passage: Support a control devicetree
>   passage: arm: Accept a passage from the previous phase
>   passage: spl: Support adding the dtb to the passage bloblist
>   passage: spl: Support passing the passage to U-Boot
>   passage: Record where the devicetree came from
>   passage: Report the devicetree source
>   passage: Add a qemu test for ARM
>   bloblist: doc: Bring in the API documentation
>   bloblist: Relicense to allow BSD-3-Clause
>   sandbox: Add a way of checking structs for standard passage
>   passage: Add documentation
>   passage: Add docs for spl_handoff
>   x86: Move Intel GNVS file into the common include directory
>   passage: Add checks for pre-existing blobs
>   WIP: RFC: Add a gitlab test
>
>  .gitlab-ci.yml                                |   6 +
>  MAINTAINERS                                   |  10 +
>  Makefile                                      |   2 +-
>  arch/arm/cpu/armv7/start.S                    |   7 +-
>  arch/arm/dts/qemu-arm-u-boot.dtsi             |  22 ++
>  arch/arm/lib/crt0.S                           |   4 +
>  arch/arm/mach-qemu/Kconfig                    |   9 +
>  arch/sandbox/cpu/spl.c                        |   2 +-
>  arch/x86/cpu/apollolake/acpi.c                |   2 +-
>  arch/x86/cpu/broadwell/cpu_from_spl.c         |   4 +-
>  arch/x86/cpu/intel_common/acpi.c              |   2 +-
>  .../include/asm/arch-apollolake/global_nvs.h  |   2 +-
>  arch/x86/lib/spl.c                            |   2 +-
>  arch/x86/lib/tpl.c                            |   2 +-
>  board/emulation/qemu-arm/Kconfig              |  23 +-
>  board/emulation/qemu-arm/MAINTAINERS          |   1 +
>  board/emulation/qemu-arm/Makefile             |   1 +
>  board/emulation/qemu-arm/spl.c                |  27 ++
>  board/google/chromebook_coral/coral.c         |   2 +-
>  board/sandbox/Makefile                        |   3 +-
>  board/sandbox/stdpass_check.c                 | 107 ++++++
>  cmd/bdinfo.c                                  |   2 +
>  common/Kconfig                                | 161 ++++++++-
>  common/bloblist.c                             | 124 +++++--
>  common/board_f.c                              |  48 ++-
>  common/board_r.c                              |  18 +
>  common/spl/spl.c                              |  74 +++-
>  configs/qemu_arm_spl_defconfig                |  78 +++++
>  doc/board/emulation/qemu-arm.rst              |  38 +++
>  doc/develop/bloblist.rst                      |  28 +-
>  doc/develop/index.rst                         |   1 +
>  doc/develop/std_passage.rst                   | 319 ++++++++++++++++++
>  drivers/core/device.c                         |  11 +
>  drivers/core/root.c                           |   7 +
>  drivers/core/uclass.c                         |  13 +
>  drivers/serial/serial-uclass.c                |   3 +-
>  dts/Kconfig                                   |  12 +
>  include/asm-generic/global_data.h             |  35 ++
>  include/bloblist.h                            | 175 +++++++---
>  include/dm/device.h                           |  11 +-
>  include/dm/root.h                             |   8 +
>  include/dm/uclass-internal.h                  |   7 +
>  include/fdtdec.h                              |  40 ++-
>  include/handoff.h                             |   8 +-
>  .../x86/include/asm => include}/intel_gnvs.h  |   0
>  include/linux/kconfig.h                       |  18 +
>  include/linux/stddef.h                        |   8 +-
>  include/spl.h                                 |  15 +
>  include/stdpass/README                        |   4 +
>  include/stdpass/tpm2_eventlog.h               |  42 +++
>  include/stdpass/vboot_ctx.h                   | 267 +++++++++++++++
>  lib/asm-offsets.c                             |   5 +
>  lib/fdtdec.c                                  |  65 +++-
>  scripts/config_whitelist.txt                  |   1 +
>  test/bloblist.c                               |  21 +-
>  test/dm/core.c                                |  41 +++
>  test/py/tests/test_passage.py                 |  11 +
>  57 files changed, 1798 insertions(+), 161 deletions(-)
>  create mode 100644 arch/arm/dts/qemu-arm-u-boot.dtsi
>  create mode 100644 board/emulation/qemu-arm/spl.c
>  create mode 100644 board/sandbox/stdpass_check.c
>  create mode 100644 configs/qemu_arm_spl_defconfig
>  create mode 100644 doc/develop/std_passage.rst
>  rename {arch/x86/include/asm => include}/intel_gnvs.h (100%)
>  create mode 100644 include/stdpass/README
>  create mode 100644 include/stdpass/tpm2_eventlog.h
>  create mode 100644 include/stdpass/vboot_ctx.h
>  create mode 100644 test/py/tests/test_passage.py
>
> --
> 2.33.1.1089.g2158813163f-goog
>
>

-- 
François-Frédéric Ozog | *Director Business Development*
T: +33.67221.6485
francois.ozog@linaro.org | Skype: ffozog

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 00/31] passage: Define a standard for firmware data flow
@ 2021-11-01  8:53   ` François Ozog
  0 siblings, 0 replies; 77+ messages in thread
From: François Ozog @ 2021-11-01  8:53 UTC (permalink / raw)
  To: Simon Glass
  Cc: Marek Vasut, Tom Rini, Albert Aribaud, Masahiro Yamada,
	Heinrich Schuchardt, Bill Mills, Ilias Apalodimas, qemu-devel,
	U-Boot Mailing List, Jerry Van Baren, Bin Meng, Pavel Herrmann

[-- Attachment #1: Type: text/plain, Size: 9856 bytes --]

Hi Simon,

this seems a great endeavor. I'd like to better understand the scope of it.

Is it to be used as part of what could become a U-Boot entry ABI scheme? By
that I mean giving some fixed aspects
to U-Boot entry while letting boards to have flexibility (say for instance
that the first 5 architecture ABI
parameter registers are reserved for U-Boot), and the Passage is about
specifying either those reserved registers
or one of them?

Thinking entry ABI, here is what I observed on Arm:

Linux has two entry ABIs:
- plain: x0 = dtb;
          command line = dtb:/chosen/bootargs; initrd =
dtb:/chosen/linux,initrd-*
- EFI: x0=handle, x1=systemtable, x30=return address;
           dtb = EFI_UUID config table; initrd = efi:<loadfile2(INITRD
vendor media UUID); command line = efi: image_protocol::load_options

U-Boot (proper) has plenty of schemes:
- dtb is passed as either x0, x1, fixed memory area (Qemu which is bad in
itself), or other registers
- additional information passing: board specific register scheme, SMC calls
- U-Boot for RPI boards implement a Linux shaped entry ABI to be launched
by Videocore firmware

Based on all the above, I would tend to think that RPI scheme is a good
idea but also
shall not prevent additional schemes for the boards.

What about a U-Boot Arm entry ABI like:
- plain: x0=dtb, x1=<Passage defined>, x2-x5 = <reserved>, other registers
are per platform, SMC calls allowed too
- EFI: x0=handle, x1=systemtable, x30=return address;  (when U-Boot is
launched as an EFI app)
       dtb = EFI_UUID config table, + Passage = Passage UUID config table

We could further leverage Passage to pass Operating Systems parameters that
could be removed from device tree (migration of /chosen to Passage). Memory
inventory would still be in DT but allocations for CMA or GPUs would be in
Passage. This idea is to reach a point where  device tree is a "pristine"
hardware description.

Cheers

PS: as Ilias mentions, this patch set contains bug fixes, non immediately
related additional functions (DM stats). It would be great to carve those
out to fast path them and keep this one with the very core of your idea.

On Mon, 1 Nov 2021 at 02:17, Simon Glass <sjg@chromium.org> wrote:

>
> This series adds a standard way of passing information between different
> firmware phases. This already exists in U-Boot at a very basic level, in
> the form of a bloblist containing an spl_handoff structure, but the intent
> here is to define something useful across projects.
>
> The need for this is growing as firmware fragments into multiple binaries
> each with its own purpose. Without any run-time connection, we must rely
> on build-time settings which are brittle and painful to keep in sync.
>
> This feature is named 'standard passage' since the name is more unique
> than many others that could be chosen, it is a passage in the sense that
> information is flowing from one place to another and it is standard,
> because that is what we want to create.
>
> The implementation is simply a pointer to a bloblist in a register, with
> an extra register to point to a devicetree, for more complex data, if one
> is present in the bloblist. This should cover all cases (small memory
> footprint as well as complex data flow) and be easy enough to implement on
> all architectures.
>
> The core bloblist code is relicensed to BSD-3-Clause in case it is useful
> in non-GPL projects but there is no requirement to use the same code.
>
> This series includes tweaks to the bloblist implementation in U-Boot to
> make it more suitable for the task, including:
>
>    - Allocate tags explicitly in the enum
>    - Put the magic number first
>    - Define a process for adding tags
>
> The emphasis is on enabling open communcation between binaries, not
> enabling passage of secret, undocumented data, although this is possible
> in a private environment.
>
> This series is built on the OF_BOARD series It is available at
> u-boot-dm/pass-working or:
>
>
> https://source.denx.de/u-boot/custodians/u-boot-dm/-/commit/073b5c156f222c69a98b8ebcaa563d1ff10eb217
>
>
> Simon Glass (31):
>   Makefile: Correct TPL rule for OF_REAL
>   kconfig: Add support for conditional values
>   dm: core: Allow getting some basic stats
>   stddef: Avoid warning with clang with offsetof()
>   fdt: Drop SPL_BUILD macro
>   bloblist: Put the magic number first
>   bloblist: Rename the SPL tag
>   bloblist: Drop unused tags
>   bloblist: Use explicit numbering for the tags
>   bloblist: Support allocating the bloblist
>   bloblist: Use LOG_CATEGORY to simply logging
>   bloblist: Use 'phase' consistently for bloblists
>   bloblist: Refactor Kconfig to support alloc or fixed
>   arm: qemu: Add an SPL build
>   bloblist: Add functions to obtain base address and size
>   passage: Support an incoming passage
>   passage: Support a control devicetree
>   passage: arm: Accept a passage from the previous phase
>   passage: spl: Support adding the dtb to the passage bloblist
>   passage: spl: Support passing the passage to U-Boot
>   passage: Record where the devicetree came from
>   passage: Report the devicetree source
>   passage: Add a qemu test for ARM
>   bloblist: doc: Bring in the API documentation
>   bloblist: Relicense to allow BSD-3-Clause
>   sandbox: Add a way of checking structs for standard passage
>   passage: Add documentation
>   passage: Add docs for spl_handoff
>   x86: Move Intel GNVS file into the common include directory
>   passage: Add checks for pre-existing blobs
>   WIP: RFC: Add a gitlab test
>
>  .gitlab-ci.yml                                |   6 +
>  MAINTAINERS                                   |  10 +
>  Makefile                                      |   2 +-
>  arch/arm/cpu/armv7/start.S                    |   7 +-
>  arch/arm/dts/qemu-arm-u-boot.dtsi             |  22 ++
>  arch/arm/lib/crt0.S                           |   4 +
>  arch/arm/mach-qemu/Kconfig                    |   9 +
>  arch/sandbox/cpu/spl.c                        |   2 +-
>  arch/x86/cpu/apollolake/acpi.c                |   2 +-
>  arch/x86/cpu/broadwell/cpu_from_spl.c         |   4 +-
>  arch/x86/cpu/intel_common/acpi.c              |   2 +-
>  .../include/asm/arch-apollolake/global_nvs.h  |   2 +-
>  arch/x86/lib/spl.c                            |   2 +-
>  arch/x86/lib/tpl.c                            |   2 +-
>  board/emulation/qemu-arm/Kconfig              |  23 +-
>  board/emulation/qemu-arm/MAINTAINERS          |   1 +
>  board/emulation/qemu-arm/Makefile             |   1 +
>  board/emulation/qemu-arm/spl.c                |  27 ++
>  board/google/chromebook_coral/coral.c         |   2 +-
>  board/sandbox/Makefile                        |   3 +-
>  board/sandbox/stdpass_check.c                 | 107 ++++++
>  cmd/bdinfo.c                                  |   2 +
>  common/Kconfig                                | 161 ++++++++-
>  common/bloblist.c                             | 124 +++++--
>  common/board_f.c                              |  48 ++-
>  common/board_r.c                              |  18 +
>  common/spl/spl.c                              |  74 +++-
>  configs/qemu_arm_spl_defconfig                |  78 +++++
>  doc/board/emulation/qemu-arm.rst              |  38 +++
>  doc/develop/bloblist.rst                      |  28 +-
>  doc/develop/index.rst                         |   1 +
>  doc/develop/std_passage.rst                   | 319 ++++++++++++++++++
>  drivers/core/device.c                         |  11 +
>  drivers/core/root.c                           |   7 +
>  drivers/core/uclass.c                         |  13 +
>  drivers/serial/serial-uclass.c                |   3 +-
>  dts/Kconfig                                   |  12 +
>  include/asm-generic/global_data.h             |  35 ++
>  include/bloblist.h                            | 175 +++++++---
>  include/dm/device.h                           |  11 +-
>  include/dm/root.h                             |   8 +
>  include/dm/uclass-internal.h                  |   7 +
>  include/fdtdec.h                              |  40 ++-
>  include/handoff.h                             |   8 +-
>  .../x86/include/asm => include}/intel_gnvs.h  |   0
>  include/linux/kconfig.h                       |  18 +
>  include/linux/stddef.h                        |   8 +-
>  include/spl.h                                 |  15 +
>  include/stdpass/README                        |   4 +
>  include/stdpass/tpm2_eventlog.h               |  42 +++
>  include/stdpass/vboot_ctx.h                   | 267 +++++++++++++++
>  lib/asm-offsets.c                             |   5 +
>  lib/fdtdec.c                                  |  65 +++-
>  scripts/config_whitelist.txt                  |   1 +
>  test/bloblist.c                               |  21 +-
>  test/dm/core.c                                |  41 +++
>  test/py/tests/test_passage.py                 |  11 +
>  57 files changed, 1798 insertions(+), 161 deletions(-)
>  create mode 100644 arch/arm/dts/qemu-arm-u-boot.dtsi
>  create mode 100644 board/emulation/qemu-arm/spl.c
>  create mode 100644 board/sandbox/stdpass_check.c
>  create mode 100644 configs/qemu_arm_spl_defconfig
>  create mode 100644 doc/develop/std_passage.rst
>  rename {arch/x86/include/asm => include}/intel_gnvs.h (100%)
>  create mode 100644 include/stdpass/README
>  create mode 100644 include/stdpass/tpm2_eventlog.h
>  create mode 100644 include/stdpass/vboot_ctx.h
>  create mode 100644 test/py/tests/test_passage.py
>
> --
> 2.33.1.1089.g2158813163f-goog
>
>

-- 
François-Frédéric Ozog | *Director Business Development*
T: +33.67221.6485
francois.ozog@linaro.org | Skype: ffozog

[-- Attachment #2: Type: text/html, Size: 13303 bytes --]

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 00/31] passage: Define a standard for firmware data flow
  2021-11-01  8:53   ` François Ozog
@ 2021-11-01 18:19     ` Mark Kettenis
  -1 siblings, 0 replies; 77+ messages in thread
From: Mark Kettenis @ 2021-11-01 18:19 UTC (permalink / raw)
  To: François Ozog
  Cc: sjg, u-boot, trini, bmeng.cn, ilias.apalodimas, bill.mills,
	xypron.glpk, albert.u.boot, vanbaren, marex, yamada.masahiro,
	morpheus.ibis, qemu-devel

> From: François Ozog <francois.ozog@linaro.org>
> Date: Mon, 1 Nov 2021 09:53:40 +0100

[...]

> We could further leverage Passage to pass Operating Systems parameters that
> could be removed from device tree (migration of /chosen to Passage). Memory
> inventory would still be in DT but allocations for CMA or GPUs would be in
> Passage. This idea is to reach a point where  device tree is a "pristine"
> hardware description.

I wanted to react on something you said in an earlier thread, but this
discussion seems to be appropriate as well:

The notion that device trees only describe the hardware isn't really
correct.  Device trees have always been used to configure firmware
options (through the /options node) and between firmware and the OS
(through the /chosen node) and to describe firmware interfaces
(e.g. OpenFirmware calls, PSCI (on ARM), RTAS (on POWER)).  This was
the case on the original Open Firmware systems, and is still done on
PowerNV systems that use flattened device trees.

I don't see what the benefits are from using Passage instead.  It
would only fragment things even more.

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 00/31] passage: Define a standard for firmware data flow
@ 2021-11-01 18:19     ` Mark Kettenis
  0 siblings, 0 replies; 77+ messages in thread
From: Mark Kettenis @ 2021-11-01 18:19 UTC (permalink / raw)
  To: François Ozog
  Cc: marex, trini, albert.u.boot, yamada.masahiro, xypron.glpk, sjg,
	ilias.apalodimas, qemu-devel, u-boot, vanbaren, morpheus.ibis,
	bmeng.cn, bill.mills

> From: François Ozog <francois.ozog@linaro.org>
> Date: Mon, 1 Nov 2021 09:53:40 +0100

[...]

> We could further leverage Passage to pass Operating Systems parameters that
> could be removed from device tree (migration of /chosen to Passage). Memory
> inventory would still be in DT but allocations for CMA or GPUs would be in
> Passage. This idea is to reach a point where  device tree is a "pristine"
> hardware description.

I wanted to react on something you said in an earlier thread, but this
discussion seems to be appropriate as well:

The notion that device trees only describe the hardware isn't really
correct.  Device trees have always been used to configure firmware
options (through the /options node) and between firmware and the OS
(through the /chosen node) and to describe firmware interfaces
(e.g. OpenFirmware calls, PSCI (on ARM), RTAS (on POWER)).  This was
the case on the original Open Firmware systems, and is still done on
PowerNV systems that use flattened device trees.

I don't see what the benefits are from using Passage instead.  It
would only fragment things even more.


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 00/31] passage: Define a standard for firmware data flow
  2021-11-01 18:19     ` Mark Kettenis
@ 2021-11-01 20:45       ` François Ozog
  -1 siblings, 0 replies; 77+ messages in thread
From: François Ozog @ 2021-11-01 20:45 UTC (permalink / raw)
  To: Mark Kettenis
  Cc: albert.u.boot, bill.mills, bmeng.cn, ilias.apalodimas, marex,
	morpheus.ibis, qemu-devel, sjg, trini, u-boot, vanbaren,
	xypron.glpk, yamada.masahiro

Hi Mark,

Le lun. 1 nov. 2021 à 19:19, Mark Kettenis <mark.kettenis@xs4all.nl> a
écrit :

> > From: François Ozog <francois.ozog@linaro.org>
> > Date: Mon, 1 Nov 2021 09:53:40 +0100
>
> [...]
>
> > We could further leverage Passage to pass Operating Systems parameters
> that
> > could be removed from device tree (migration of /chosen to Passage).
> Memory
> > inventory would still be in DT but allocations for CMA or GPUs would be
> in
> > Passage. This idea is to reach a point where  device tree is a "pristine"
> > hardware description.
>
> I wanted to react on something you said in an earlier thread, but this
> discussion seems to be appropriate as well:
>
> The notion that device trees only describe the hardware isn't really
> correct.  Device trees have always been used to configure firmware
> options (through the /options node) and between firmware and the OS
> (through the /chosen node) and to describe firmware interfaces
> (e.g. OpenFirmware calls, PSCI (on ARM), RTAS (on POWER)).  This was
> the case on the original Open Firmware systems, and is still done on
> PowerNV systems that use flattened device trees.


> I understand and agree with the above.
Yet, PSCI is different from /options and /chosen: those are platform
services made available to the OS when the boot firmware code has been
unloaded/neutralized.

What I (not just myself but let’s simplify) am trying to decouple the
supply chain: loosely coupled platform provider (ODM), the firmware
provider, OS provider, application provider. So it is not to prevent
presence of those existing nodes, it is to be able introduce some
rationalization in their use:

Platform interfaces such as PSCI: The question is “who” injects them in the
DT (build time or runtime). There is no single good answer and you may want
the authoritative entity that implements the service to actually inject
itself in the DT passed to the OS. I know some platforms are using SMC
calls from U-Boot to know what to inject in the DT. I see those as the same
nature of DIMM sensing and injection in the DT.

/chosen:  a must have when you do not have UEFI but not necessary with UEFI.

/options: it should be possible for the end customer to make the decision
of integration: at build time or at runtime based on a separate flattened
device tree file.

This decoupling should result for instance, in the long run, in adjustable
memory layouts without headaches. changing the secure dram size is simple
from hardware perspective but a massive issue from a firmware perspective:
multiple firmware projects sources need to be adjusted, making manual
calculations on explicit constants or “hidden” ones. It should even be
possible to adjust it at runtime on the field (user selected firmware
parameter).


> I don't see what the benefits are from using Passage instead.  It
> would only fragment things even more.
>
-- 
François-Frédéric Ozog | *Director Business Development*
T: +33.67221.6485
francois.ozog@linaro.org | Skype: ffozog

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 00/31] passage: Define a standard for firmware data flow
@ 2021-11-01 20:45       ` François Ozog
  0 siblings, 0 replies; 77+ messages in thread
From: François Ozog @ 2021-11-01 20:45 UTC (permalink / raw)
  To: Mark Kettenis
  Cc: marex, albert.u.boot, trini, yamada.masahiro, xypron.glpk,
	bill.mills, ilias.apalodimas, qemu-devel, u-boot, vanbaren, sjg,
	bmeng.cn, morpheus.ibis

[-- Attachment #1: Type: text/plain, Size: 3075 bytes --]

Hi Mark,

Le lun. 1 nov. 2021 à 19:19, Mark Kettenis <mark.kettenis@xs4all.nl> a
écrit :

> > From: François Ozog <francois.ozog@linaro.org>
> > Date: Mon, 1 Nov 2021 09:53:40 +0100
>
> [...]
>
> > We could further leverage Passage to pass Operating Systems parameters
> that
> > could be removed from device tree (migration of /chosen to Passage).
> Memory
> > inventory would still be in DT but allocations for CMA or GPUs would be
> in
> > Passage. This idea is to reach a point where  device tree is a "pristine"
> > hardware description.
>
> I wanted to react on something you said in an earlier thread, but this
> discussion seems to be appropriate as well:
>
> The notion that device trees only describe the hardware isn't really
> correct.  Device trees have always been used to configure firmware
> options (through the /options node) and between firmware and the OS
> (through the /chosen node) and to describe firmware interfaces
> (e.g. OpenFirmware calls, PSCI (on ARM), RTAS (on POWER)).  This was
> the case on the original Open Firmware systems, and is still done on
> PowerNV systems that use flattened device trees.


> I understand and agree with the above.
Yet, PSCI is different from /options and /chosen: those are platform
services made available to the OS when the boot firmware code has been
unloaded/neutralized.

What I (not just myself but let’s simplify) am trying to decouple the
supply chain: loosely coupled platform provider (ODM), the firmware
provider, OS provider, application provider. So it is not to prevent
presence of those existing nodes, it is to be able introduce some
rationalization in their use:

Platform interfaces such as PSCI: The question is “who” injects them in the
DT (build time or runtime). There is no single good answer and you may want
the authoritative entity that implements the service to actually inject
itself in the DT passed to the OS. I know some platforms are using SMC
calls from U-Boot to know what to inject in the DT. I see those as the same
nature of DIMM sensing and injection in the DT.

/chosen:  a must have when you do not have UEFI but not necessary with UEFI.

/options: it should be possible for the end customer to make the decision
of integration: at build time or at runtime based on a separate flattened
device tree file.

This decoupling should result for instance, in the long run, in adjustable
memory layouts without headaches. changing the secure dram size is simple
from hardware perspective but a massive issue from a firmware perspective:
multiple firmware projects sources need to be adjusted, making manual
calculations on explicit constants or “hidden” ones. It should even be
possible to adjust it at runtime on the field (user selected firmware
parameter).


> I don't see what the benefits are from using Passage instead.  It
> would only fragment things even more.
>
-- 
François-Frédéric Ozog | *Director Business Development*
T: +33.67221.6485
francois.ozog@linaro.org | Skype: ffozog

[-- Attachment #2: Type: text/html, Size: 6347 bytes --]

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 00/31] passage: Define a standard for firmware data flow
  2021-11-01  8:53   ` François Ozog
@ 2021-11-02 14:58     ` Simon Glass
  -1 siblings, 0 replies; 77+ messages in thread
From: Simon Glass @ 2021-11-02 14:58 UTC (permalink / raw)
  To: François Ozog
  Cc: U-Boot Mailing List, Tom Rini, Bin Meng, Ilias Apalodimas,
	Bill Mills, Heinrich Schuchardt, Albert Aribaud, Jerry Van Baren,
	Marek Vasut, Masahiro Yamada, Pavel Herrmann, QEMU Developers

Hi François,

On Mon, 1 Nov 2021 at 02:53, François Ozog <francois.ozog@linaro.org> wrote:
>
> Hi Simon,
>
> this seems a great endeavor. I'd like to better understand the scope of it.
>
> Is it to be used as part of what could become a U-Boot entry ABI scheme? By that I mean giving some fixed aspects
> to U-Boot entry while letting boards to have flexibility (say for instance that the first 5 architecture ABI
> parameter registers are reserved for U-Boot), and the Passage is about specifying either those reserved registers
> or one of them?

The goal is to provide a standard entry scheme for all firmware
binaries. Whether it achieves that (or can with some mods) is up for
discussion.

Re the registers, do you think we need 5?

>
> Thinking entry ABI, here is what I observed on Arm:
>
> Linux has two entry ABIs:
> - plain: x0 = dtb;
>           command line = dtb:/chosen/bootargs; initrd = dtb:/chosen/linux,initrd-*
> - EFI: x0=handle, x1=systemtable, x30=return address;
>            dtb = EFI_UUID config table; initrd = efi:<loadfile2(INITRD vendor media UUID); command line = efi: image_protocol::load_options
>
> U-Boot (proper) has plenty of schemes:
> - dtb is passed as either x0, x1, fixed memory area (Qemu which is bad in itself), or other registers
> - additional information passing: board specific register scheme, SMC calls
> - U-Boot for RPI boards implement a Linux shaped entry ABI to be launched by Videocore firmware
>
> Based on all the above, I would tend to think that RPI scheme is a good idea but also
> shall not prevent additional schemes for the boards.

I was not actually considering Linux since I believe/assume its entry
scheme is fixed and not up for discussion.

I also did not think about the EFI case. As I understand it we cannot
touch it as it is used by UEFI today. Maybe it is even in the
standard?

Really I am hoping we can start afresh...?

>
> What about a U-Boot Arm entry ABI like:
> - plain: x0=dtb, x1=<Passage defined>, x2-x5 = <reserved>, other registers are per platform, SMC calls allowed too

Hmm we don't actually need the dtb as it is available in the bloblist.
But I added an offset to it as a convenience.

> - EFI: x0=handle, x1=systemtable, x30=return address;  (when U-Boot is launched as an EFI app)
>        dtb = EFI_UUID config table, + Passage = Passage UUID config table

I don't understand the last line. Where is the passage info /
bloblist? Do you mean it goes in the HOB list with a UUID? I suppose
that is the most EFI-compatible way.

What do you think about the idea of using an offset into the bloblist
for the dtb? Also, can we make the standard passage ABI a build-time
option, so it is deterministic?

>
> We could further leverage Passage to pass Operating Systems parameters that could be removed from device tree (migration of /chosen to Passage). Memory inventory would still be in DT but allocations for CMA or GPUs would be in Passage. This idea is to reach a point where  device tree is a "pristine" hardware description.

I'm worried about this becoming a substitute for devicetree. Really my
intent is to provide a way to pass simple info, whereas what you talk
about there seems like something that should be DT, just that it might
need suitable bindings.

As you know I have more expansive views about what should be in DT.

>
> Cheers
>
> PS: as Ilias mentions, this patch set contains bug fixes, non immediately related additional functions (DM stats). It would be great to carve those out to fast path them and keep this one with the very core of your idea.

The DM stats is used in 'passage: Report the devicetree source'. I
know it is sideways but I think it is better to make the output line
more useful than just reporting the devicetree source.

The first patch is indeed unrelated. I will pick it up so we can drop
it for the next rev.

Regards,
Simon


>
> On Mon, 1 Nov 2021 at 02:17, Simon Glass <sjg@chromium.org> wrote:
>>
>>
>> This series adds a standard way of passing information between different
>> firmware phases. This already exists in U-Boot at a very basic level, in
>> the form of a bloblist containing an spl_handoff structure, but the intent
>> here is to define something useful across projects.
>>
>> The need for this is growing as firmware fragments into multiple binaries
>> each with its own purpose. Without any run-time connection, we must rely
>> on build-time settings which are brittle and painful to keep in sync.
>>
>> This feature is named 'standard passage' since the name is more unique
>> than many others that could be chosen, it is a passage in the sense that
>> information is flowing from one place to another and it is standard,
>> because that is what we want to create.
>>
>> The implementation is simply a pointer to a bloblist in a register, with
>> an extra register to point to a devicetree, for more complex data, if one
>> is present in the bloblist. This should cover all cases (small memory
>> footprint as well as complex data flow) and be easy enough to implement on
>> all architectures.
>>
>> The core bloblist code is relicensed to BSD-3-Clause in case it is useful
>> in non-GPL projects but there is no requirement to use the same code.
>>
>> This series includes tweaks to the bloblist implementation in U-Boot to
>> make it more suitable for the task, including:
>>
>>    - Allocate tags explicitly in the enum
>>    - Put the magic number first
>>    - Define a process for adding tags
>>
>> The emphasis is on enabling open communcation between binaries, not
>> enabling passage of secret, undocumented data, although this is possible
>> in a private environment.
>>
>> This series is built on the OF_BOARD series It is available at
>> u-boot-dm/pass-working or:
>>
>> https://source.denx.de/u-boot/custodians/u-boot-dm/-/commit/073b5c156f222c69a98b8ebcaa563d1ff10eb217
>>
>>
>> Simon Glass (31):
>>   Makefile: Correct TPL rule for OF_REAL
>>   kconfig: Add support for conditional values
>>   dm: core: Allow getting some basic stats
>>   stddef: Avoid warning with clang with offsetof()
>>   fdt: Drop SPL_BUILD macro
>>   bloblist: Put the magic number first
>>   bloblist: Rename the SPL tag
>>   bloblist: Drop unused tags
>>   bloblist: Use explicit numbering for the tags
>>   bloblist: Support allocating the bloblist
>>   bloblist: Use LOG_CATEGORY to simply logging
>>   bloblist: Use 'phase' consistently for bloblists
>>   bloblist: Refactor Kconfig to support alloc or fixed
>>   arm: qemu: Add an SPL build
>>   bloblist: Add functions to obtain base address and size
>>   passage: Support an incoming passage
>>   passage: Support a control devicetree
>>   passage: arm: Accept a passage from the previous phase
>>   passage: spl: Support adding the dtb to the passage bloblist
>>   passage: spl: Support passing the passage to U-Boot
>>   passage: Record where the devicetree came from
>>   passage: Report the devicetree source
>>   passage: Add a qemu test for ARM
>>   bloblist: doc: Bring in the API documentation
>>   bloblist: Relicense to allow BSD-3-Clause
>>   sandbox: Add a way of checking structs for standard passage
>>   passage: Add documentation
>>   passage: Add docs for spl_handoff
>>   x86: Move Intel GNVS file into the common include directory
>>   passage: Add checks for pre-existing blobs
>>   WIP: RFC: Add a gitlab test
>>
>>  .gitlab-ci.yml                                |   6 +
>>  MAINTAINERS                                   |  10 +
>>  Makefile                                      |   2 +-
>>  arch/arm/cpu/armv7/start.S                    |   7 +-
>>  arch/arm/dts/qemu-arm-u-boot.dtsi             |  22 ++
>>  arch/arm/lib/crt0.S                           |   4 +
>>  arch/arm/mach-qemu/Kconfig                    |   9 +
>>  arch/sandbox/cpu/spl.c                        |   2 +-
>>  arch/x86/cpu/apollolake/acpi.c                |   2 +-
>>  arch/x86/cpu/broadwell/cpu_from_spl.c         |   4 +-
>>  arch/x86/cpu/intel_common/acpi.c              |   2 +-
>>  .../include/asm/arch-apollolake/global_nvs.h  |   2 +-
>>  arch/x86/lib/spl.c                            |   2 +-
>>  arch/x86/lib/tpl.c                            |   2 +-
>>  board/emulation/qemu-arm/Kconfig              |  23 +-
>>  board/emulation/qemu-arm/MAINTAINERS          |   1 +
>>  board/emulation/qemu-arm/Makefile             |   1 +
>>  board/emulation/qemu-arm/spl.c                |  27 ++
>>  board/google/chromebook_coral/coral.c         |   2 +-
>>  board/sandbox/Makefile                        |   3 +-
>>  board/sandbox/stdpass_check.c                 | 107 ++++++
>>  cmd/bdinfo.c                                  |   2 +
>>  common/Kconfig                                | 161 ++++++++-
>>  common/bloblist.c                             | 124 +++++--
>>  common/board_f.c                              |  48 ++-
>>  common/board_r.c                              |  18 +
>>  common/spl/spl.c                              |  74 +++-
>>  configs/qemu_arm_spl_defconfig                |  78 +++++
>>  doc/board/emulation/qemu-arm.rst              |  38 +++
>>  doc/develop/bloblist.rst                      |  28 +-
>>  doc/develop/index.rst                         |   1 +
>>  doc/develop/std_passage.rst                   | 319 ++++++++++++++++++
>>  drivers/core/device.c                         |  11 +
>>  drivers/core/root.c                           |   7 +
>>  drivers/core/uclass.c                         |  13 +
>>  drivers/serial/serial-uclass.c                |   3 +-
>>  dts/Kconfig                                   |  12 +
>>  include/asm-generic/global_data.h             |  35 ++
>>  include/bloblist.h                            | 175 +++++++---
>>  include/dm/device.h                           |  11 +-
>>  include/dm/root.h                             |   8 +
>>  include/dm/uclass-internal.h                  |   7 +
>>  include/fdtdec.h                              |  40 ++-
>>  include/handoff.h                             |   8 +-
>>  .../x86/include/asm => include}/intel_gnvs.h  |   0
>>  include/linux/kconfig.h                       |  18 +
>>  include/linux/stddef.h                        |   8 +-
>>  include/spl.h                                 |  15 +
>>  include/stdpass/README                        |   4 +
>>  include/stdpass/tpm2_eventlog.h               |  42 +++
>>  include/stdpass/vboot_ctx.h                   | 267 +++++++++++++++
>>  lib/asm-offsets.c                             |   5 +
>>  lib/fdtdec.c                                  |  65 +++-
>>  scripts/config_whitelist.txt                  |   1 +
>>  test/bloblist.c                               |  21 +-
>>  test/dm/core.c                                |  41 +++
>>  test/py/tests/test_passage.py                 |  11 +
>>  57 files changed, 1798 insertions(+), 161 deletions(-)
>>  create mode 100644 arch/arm/dts/qemu-arm-u-boot.dtsi
>>  create mode 100644 board/emulation/qemu-arm/spl.c
>>  create mode 100644 board/sandbox/stdpass_check.c
>>  create mode 100644 configs/qemu_arm_spl_defconfig
>>  create mode 100644 doc/develop/std_passage.rst
>>  rename {arch/x86/include/asm => include}/intel_gnvs.h (100%)
>>  create mode 100644 include/stdpass/README
>>  create mode 100644 include/stdpass/tpm2_eventlog.h
>>  create mode 100644 include/stdpass/vboot_ctx.h
>>  create mode 100644 test/py/tests/test_passage.py
>>
>> --
>> 2.33.1.1089.g2158813163f-goog
>>
>
>
> --
> François-Frédéric Ozog | Director Business Development
> T: +33.67221.6485
> francois.ozog@linaro.org | Skype: ffozog
>

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 00/31] passage: Define a standard for firmware data flow
@ 2021-11-02 14:58     ` Simon Glass
  0 siblings, 0 replies; 77+ messages in thread
From: Simon Glass @ 2021-11-02 14:58 UTC (permalink / raw)
  To: François Ozog
  Cc: Marek Vasut, Tom Rini, Albert Aribaud, Masahiro Yamada,
	Heinrich Schuchardt, Bill Mills, Ilias Apalodimas,
	QEMU Developers, U-Boot Mailing List, Jerry Van Baren, Bin Meng,
	Pavel Herrmann

Hi François,

On Mon, 1 Nov 2021 at 02:53, François Ozog <francois.ozog@linaro.org> wrote:
>
> Hi Simon,
>
> this seems a great endeavor. I'd like to better understand the scope of it.
>
> Is it to be used as part of what could become a U-Boot entry ABI scheme? By that I mean giving some fixed aspects
> to U-Boot entry while letting boards to have flexibility (say for instance that the first 5 architecture ABI
> parameter registers are reserved for U-Boot), and the Passage is about specifying either those reserved registers
> or one of them?

The goal is to provide a standard entry scheme for all firmware
binaries. Whether it achieves that (or can with some mods) is up for
discussion.

Re the registers, do you think we need 5?

>
> Thinking entry ABI, here is what I observed on Arm:
>
> Linux has two entry ABIs:
> - plain: x0 = dtb;
>           command line = dtb:/chosen/bootargs; initrd = dtb:/chosen/linux,initrd-*
> - EFI: x0=handle, x1=systemtable, x30=return address;
>            dtb = EFI_UUID config table; initrd = efi:<loadfile2(INITRD vendor media UUID); command line = efi: image_protocol::load_options
>
> U-Boot (proper) has plenty of schemes:
> - dtb is passed as either x0, x1, fixed memory area (Qemu which is bad in itself), or other registers
> - additional information passing: board specific register scheme, SMC calls
> - U-Boot for RPI boards implement a Linux shaped entry ABI to be launched by Videocore firmware
>
> Based on all the above, I would tend to think that RPI scheme is a good idea but also
> shall not prevent additional schemes for the boards.

I was not actually considering Linux since I believe/assume its entry
scheme is fixed and not up for discussion.

I also did not think about the EFI case. As I understand it we cannot
touch it as it is used by UEFI today. Maybe it is even in the
standard?

Really I am hoping we can start afresh...?

>
> What about a U-Boot Arm entry ABI like:
> - plain: x0=dtb, x1=<Passage defined>, x2-x5 = <reserved>, other registers are per platform, SMC calls allowed too

Hmm we don't actually need the dtb as it is available in the bloblist.
But I added an offset to it as a convenience.

> - EFI: x0=handle, x1=systemtable, x30=return address;  (when U-Boot is launched as an EFI app)
>        dtb = EFI_UUID config table, + Passage = Passage UUID config table

I don't understand the last line. Where is the passage info /
bloblist? Do you mean it goes in the HOB list with a UUID? I suppose
that is the most EFI-compatible way.

What do you think about the idea of using an offset into the bloblist
for the dtb? Also, can we make the standard passage ABI a build-time
option, so it is deterministic?

>
> We could further leverage Passage to pass Operating Systems parameters that could be removed from device tree (migration of /chosen to Passage). Memory inventory would still be in DT but allocations for CMA or GPUs would be in Passage. This idea is to reach a point where  device tree is a "pristine" hardware description.

I'm worried about this becoming a substitute for devicetree. Really my
intent is to provide a way to pass simple info, whereas what you talk
about there seems like something that should be DT, just that it might
need suitable bindings.

As you know I have more expansive views about what should be in DT.

>
> Cheers
>
> PS: as Ilias mentions, this patch set contains bug fixes, non immediately related additional functions (DM stats). It would be great to carve those out to fast path them and keep this one with the very core of your idea.

The DM stats is used in 'passage: Report the devicetree source'. I
know it is sideways but I think it is better to make the output line
more useful than just reporting the devicetree source.

The first patch is indeed unrelated. I will pick it up so we can drop
it for the next rev.

Regards,
Simon


>
> On Mon, 1 Nov 2021 at 02:17, Simon Glass <sjg@chromium.org> wrote:
>>
>>
>> This series adds a standard way of passing information between different
>> firmware phases. This already exists in U-Boot at a very basic level, in
>> the form of a bloblist containing an spl_handoff structure, but the intent
>> here is to define something useful across projects.
>>
>> The need for this is growing as firmware fragments into multiple binaries
>> each with its own purpose. Without any run-time connection, we must rely
>> on build-time settings which are brittle and painful to keep in sync.
>>
>> This feature is named 'standard passage' since the name is more unique
>> than many others that could be chosen, it is a passage in the sense that
>> information is flowing from one place to another and it is standard,
>> because that is what we want to create.
>>
>> The implementation is simply a pointer to a bloblist in a register, with
>> an extra register to point to a devicetree, for more complex data, if one
>> is present in the bloblist. This should cover all cases (small memory
>> footprint as well as complex data flow) and be easy enough to implement on
>> all architectures.
>>
>> The core bloblist code is relicensed to BSD-3-Clause in case it is useful
>> in non-GPL projects but there is no requirement to use the same code.
>>
>> This series includes tweaks to the bloblist implementation in U-Boot to
>> make it more suitable for the task, including:
>>
>>    - Allocate tags explicitly in the enum
>>    - Put the magic number first
>>    - Define a process for adding tags
>>
>> The emphasis is on enabling open communcation between binaries, not
>> enabling passage of secret, undocumented data, although this is possible
>> in a private environment.
>>
>> This series is built on the OF_BOARD series It is available at
>> u-boot-dm/pass-working or:
>>
>> https://source.denx.de/u-boot/custodians/u-boot-dm/-/commit/073b5c156f222c69a98b8ebcaa563d1ff10eb217
>>
>>
>> Simon Glass (31):
>>   Makefile: Correct TPL rule for OF_REAL
>>   kconfig: Add support for conditional values
>>   dm: core: Allow getting some basic stats
>>   stddef: Avoid warning with clang with offsetof()
>>   fdt: Drop SPL_BUILD macro
>>   bloblist: Put the magic number first
>>   bloblist: Rename the SPL tag
>>   bloblist: Drop unused tags
>>   bloblist: Use explicit numbering for the tags
>>   bloblist: Support allocating the bloblist
>>   bloblist: Use LOG_CATEGORY to simply logging
>>   bloblist: Use 'phase' consistently for bloblists
>>   bloblist: Refactor Kconfig to support alloc or fixed
>>   arm: qemu: Add an SPL build
>>   bloblist: Add functions to obtain base address and size
>>   passage: Support an incoming passage
>>   passage: Support a control devicetree
>>   passage: arm: Accept a passage from the previous phase
>>   passage: spl: Support adding the dtb to the passage bloblist
>>   passage: spl: Support passing the passage to U-Boot
>>   passage: Record where the devicetree came from
>>   passage: Report the devicetree source
>>   passage: Add a qemu test for ARM
>>   bloblist: doc: Bring in the API documentation
>>   bloblist: Relicense to allow BSD-3-Clause
>>   sandbox: Add a way of checking structs for standard passage
>>   passage: Add documentation
>>   passage: Add docs for spl_handoff
>>   x86: Move Intel GNVS file into the common include directory
>>   passage: Add checks for pre-existing blobs
>>   WIP: RFC: Add a gitlab test
>>
>>  .gitlab-ci.yml                                |   6 +
>>  MAINTAINERS                                   |  10 +
>>  Makefile                                      |   2 +-
>>  arch/arm/cpu/armv7/start.S                    |   7 +-
>>  arch/arm/dts/qemu-arm-u-boot.dtsi             |  22 ++
>>  arch/arm/lib/crt0.S                           |   4 +
>>  arch/arm/mach-qemu/Kconfig                    |   9 +
>>  arch/sandbox/cpu/spl.c                        |   2 +-
>>  arch/x86/cpu/apollolake/acpi.c                |   2 +-
>>  arch/x86/cpu/broadwell/cpu_from_spl.c         |   4 +-
>>  arch/x86/cpu/intel_common/acpi.c              |   2 +-
>>  .../include/asm/arch-apollolake/global_nvs.h  |   2 +-
>>  arch/x86/lib/spl.c                            |   2 +-
>>  arch/x86/lib/tpl.c                            |   2 +-
>>  board/emulation/qemu-arm/Kconfig              |  23 +-
>>  board/emulation/qemu-arm/MAINTAINERS          |   1 +
>>  board/emulation/qemu-arm/Makefile             |   1 +
>>  board/emulation/qemu-arm/spl.c                |  27 ++
>>  board/google/chromebook_coral/coral.c         |   2 +-
>>  board/sandbox/Makefile                        |   3 +-
>>  board/sandbox/stdpass_check.c                 | 107 ++++++
>>  cmd/bdinfo.c                                  |   2 +
>>  common/Kconfig                                | 161 ++++++++-
>>  common/bloblist.c                             | 124 +++++--
>>  common/board_f.c                              |  48 ++-
>>  common/board_r.c                              |  18 +
>>  common/spl/spl.c                              |  74 +++-
>>  configs/qemu_arm_spl_defconfig                |  78 +++++
>>  doc/board/emulation/qemu-arm.rst              |  38 +++
>>  doc/develop/bloblist.rst                      |  28 +-
>>  doc/develop/index.rst                         |   1 +
>>  doc/develop/std_passage.rst                   | 319 ++++++++++++++++++
>>  drivers/core/device.c                         |  11 +
>>  drivers/core/root.c                           |   7 +
>>  drivers/core/uclass.c                         |  13 +
>>  drivers/serial/serial-uclass.c                |   3 +-
>>  dts/Kconfig                                   |  12 +
>>  include/asm-generic/global_data.h             |  35 ++
>>  include/bloblist.h                            | 175 +++++++---
>>  include/dm/device.h                           |  11 +-
>>  include/dm/root.h                             |   8 +
>>  include/dm/uclass-internal.h                  |   7 +
>>  include/fdtdec.h                              |  40 ++-
>>  include/handoff.h                             |   8 +-
>>  .../x86/include/asm => include}/intel_gnvs.h  |   0
>>  include/linux/kconfig.h                       |  18 +
>>  include/linux/stddef.h                        |   8 +-
>>  include/spl.h                                 |  15 +
>>  include/stdpass/README                        |   4 +
>>  include/stdpass/tpm2_eventlog.h               |  42 +++
>>  include/stdpass/vboot_ctx.h                   | 267 +++++++++++++++
>>  lib/asm-offsets.c                             |   5 +
>>  lib/fdtdec.c                                  |  65 +++-
>>  scripts/config_whitelist.txt                  |   1 +
>>  test/bloblist.c                               |  21 +-
>>  test/dm/core.c                                |  41 +++
>>  test/py/tests/test_passage.py                 |  11 +
>>  57 files changed, 1798 insertions(+), 161 deletions(-)
>>  create mode 100644 arch/arm/dts/qemu-arm-u-boot.dtsi
>>  create mode 100644 board/emulation/qemu-arm/spl.c
>>  create mode 100644 board/sandbox/stdpass_check.c
>>  create mode 100644 configs/qemu_arm_spl_defconfig
>>  create mode 100644 doc/develop/std_passage.rst
>>  rename {arch/x86/include/asm => include}/intel_gnvs.h (100%)
>>  create mode 100644 include/stdpass/README
>>  create mode 100644 include/stdpass/tpm2_eventlog.h
>>  create mode 100644 include/stdpass/vboot_ctx.h
>>  create mode 100644 test/py/tests/test_passage.py
>>
>> --
>> 2.33.1.1089.g2158813163f-goog
>>
>
>
> --
> François-Frédéric Ozog | Director Business Development
> T: +33.67221.6485
> francois.ozog@linaro.org | Skype: ffozog
>


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 00/31] passage: Define a standard for firmware data flow
  2021-11-02 14:58     ` Simon Glass
@ 2021-11-02 16:03       ` François Ozog
  -1 siblings, 0 replies; 77+ messages in thread
From: François Ozog @ 2021-11-02 16:03 UTC (permalink / raw)
  To: Simon Glass
  Cc: U-Boot Mailing List, Tom Rini, Bin Meng, Ilias Apalodimas,
	Bill Mills, Heinrich Schuchardt, Albert Aribaud, Jerry Van Baren,
	Marek Vasut, Masahiro Yamada, Pavel Herrmann, QEMU Developers

Hi Simon,

On Tue, 2 Nov 2021 at 15:59, Simon Glass <sjg@chromium.org> wrote:

> Hi François,
>
> On Mon, 1 Nov 2021 at 02:53, François Ozog <francois.ozog@linaro.org>
> wrote:
> >
> > Hi Simon,
> >
> > this seems a great endeavor. I'd like to better understand the scope of
> it.
> >
> > Is it to be used as part of what could become a U-Boot entry ABI scheme?
> By that I mean giving some fixed aspects
> > to U-Boot entry while letting boards to have flexibility (say for
> instance that the first 5 architecture ABI
> > parameter registers are reserved for U-Boot), and the Passage is about
> specifying either those reserved registers
> > or one of them?
>
> The goal is to provide a standard entry scheme for all firmware
> binaries. Whether it achieves that (or can with some mods) is up for
> discussion.
>
> If you say
a) define a U-Boot entry ABI and providing a firmware-to-firmware
information passing facility which would be part of all firmware ABIs (as
the projects decide to define their own ABI) it looks good.
but If you say
b) define a standard entry scheme (register map, processor state, MMU
state, SMMU state, GIC state...) that does not look realistic.
I think you mean a) but just want to be sure.

> Re the registers, do you think we need 5?
>
> >
> > Thinking entry ABI, here is what I observed on Arm:
> >
> > Linux has two entry ABIs:
> > - plain: x0 = dtb;
> >           command line = dtb:/chosen/bootargs; initrd =
> dtb:/chosen/linux,initrd-*
> > - EFI: x0=handle, x1=systemtable, x30=return address;
> >            dtb = EFI_UUID config table; initrd = efi:<loadfile2(INITRD
> vendor media UUID); command line = efi: image_protocol::load_options
> >
> > U-Boot (proper) has plenty of schemes:
> > - dtb is passed as either x0, x1, fixed memory area (Qemu which is bad
> in itself), or other registers
> > - additional information passing: board specific register scheme, SMC
> calls
> > - U-Boot for RPI boards implement a Linux shaped entry ABI to be
> launched by Videocore firmware
> >
> > Based on all the above, I would tend to think that RPI scheme is a good
> idea but also
> > shall not prevent additional schemes for the boards.
>
> I was not actually considering Linux since I believe/assume its entry
> scheme is fixed and not up for discussion.
>
> I also did not think about the EFI case. As I understand it we cannot
> touch it as it is used by UEFI today. Maybe it is even in the
> standard?
>
It is in the spec and we are making it evolve, or its understanding evolve
(jurisprudence) for instance on initrd standard handling.

>
> Really I am hoping we can start afresh...?
>
> >
> > What about a U-Boot Arm entry ABI like:
> > - plain: x0=dtb, x1=<Passage defined>, x2-x5 = <reserved>, other
> registers are per platform, SMC calls allowed too
>
> Hmm we don't actually need the dtb as it is available in the bloblist.
>
If you don't have x0=dtb, then you will not be able to use U-Boot on RPI4.
Unless you want to redo everything the RPI firmware is doing.

> But I added an offset to it as a convenience.
>
> > - EFI: x0=handle, x1=systemtable, x30=return address;  (when U-Boot is
> launched as an EFI app)
> >        dtb = EFI_UUID config table, + Passage = Passage UUID config table
>
> I don't understand the last line. Where is the passage info /
> bloblist? Do you mean it goes in the HOB list with a UUID? I suppose
> that is the most EFI-compatible way.
>
The Passage config table  could just contain the "head" of the
bloblist/Passage information.

>
> What do you think about the idea of using an offset into the bloblist
> for the dtb?

It is possible but as I said, failing to mimic Linux entry ABI would miss
the opportunity to just boot without changes on RPI4.

> Also, can we make the standard passage ABI a build-time
> option, so it is deterministic?
>
> Looks good. I would look into stating that for SystemReady we would advise
to use that option and make it standard for Trusted Substrate (Linaro
recipes that we upstreaming to make SystemReady compliance easy and
consistent across platforms).

> >
> > We could further leverage Passage to pass Operating Systems parameters
> that could be removed from device tree (migration of /chosen to Passage).
> Memory inventory would still be in DT but allocations for CMA or GPUs would
> be in Passage. This idea is to reach a point where  device tree is a
> "pristine" hardware description.
>
> I'm worried about this becoming a substitute for devicetree. Really my
> intent is to provide a way to pass simple info, whereas what you talk
> about there seems like something that should be DT, just that it might
> need suitable bindings.
>
> I see your point and I agree It should not be a substitute.
here is an expanded version of what I had in mind when I wrote those lines.
cma, initrd and other Linux kernel parameters can be conveyed either
through command line or DT.
When using the non UEFI Linux entry ABI, you need to use the DT to pass
those parameters.
When using the UEFI Linux entry ABI, you *can* (not must) use the command
line to pass all information, leaving the DT passed to the OS without any
/chosen.
When introducing Passage, I was wondering if we could pass command line to
Linux and, same as UEFI, leave the DT free from /chosen.
I am not sure it is a good goal though. I may be too pushing for a DT free
from parameters.

> As you know I have more expansive views about what should be in DT.
>
I think both of us are huge supporters of DT format and self describing
capabilities.
I am inclined to put rules into what fits into what lands in the DT that is
passed to the OS.
I am a fan of having DT used more in ad-hoc files.

> >
> > Cheers
> >
> > PS: as Ilias mentions, this patch set contains bug fixes, non
> immediately related additional functions (DM stats). It would be great to
> carve those out to fast path them and keep this one with the very core of
> your idea.
>
> The DM stats is used in 'passage: Report the devicetree source'. I
> know it is sideways but I think it is better to make the output line
> more useful than just reporting the devicetree source.
>
> I believe the DM stats has merits in its own. You could upstream this
independently and then Passage would be yet another "customer" of the
feature.

> The first patch is indeed unrelated. I will pick it up so we can drop
> it for the next rev.
>
> Regards,
> Simon
>
>
> >
> > On Mon, 1 Nov 2021 at 02:17, Simon Glass <sjg@chromium.org> wrote:
> >>
> >>
> >> This series adds a standard way of passing information between different
> >> firmware phases. This already exists in U-Boot at a very basic level, in
> >> the form of a bloblist containing an spl_handoff structure, but the
> intent
> >> here is to define something useful across projects.
> >>
> >> The need for this is growing as firmware fragments into multiple
> binaries
> >> each with its own purpose. Without any run-time connection, we must rely
> >> on build-time settings which are brittle and painful to keep in sync.
> >>
> >> This feature is named 'standard passage' since the name is more unique
> >> than many others that could be chosen, it is a passage in the sense that
> >> information is flowing from one place to another and it is standard,
> >> because that is what we want to create.
> >>
> >> The implementation is simply a pointer to a bloblist in a register, with
> >> an extra register to point to a devicetree, for more complex data, if
> one
> >> is present in the bloblist. This should cover all cases (small memory
> >> footprint as well as complex data flow) and be easy enough to implement
> on
> >> all architectures.
> >>
> >> The core bloblist code is relicensed to BSD-3-Clause in case it is
> useful
> >> in non-GPL projects but there is no requirement to use the same code.
> >>
> >> This series includes tweaks to the bloblist implementation in U-Boot to
> >> make it more suitable for the task, including:
> >>
> >>    - Allocate tags explicitly in the enum
> >>    - Put the magic number first
> >>    - Define a process for adding tags
> >>
> >> The emphasis is on enabling open communcation between binaries, not
> >> enabling passage of secret, undocumented data, although this is possible
> >> in a private environment.
> >>
> >> This series is built on the OF_BOARD series It is available at
> >> u-boot-dm/pass-working or:
> >>
> >>
> https://source.denx.de/u-boot/custodians/u-boot-dm/-/commit/073b5c156f222c69a98b8ebcaa563d1ff10eb217
> >>
> >>
> >> Simon Glass (31):
> >>   Makefile: Correct TPL rule for OF_REAL
> >>   kconfig: Add support for conditional values
> >>   dm: core: Allow getting some basic stats
> >>   stddef: Avoid warning with clang with offsetof()
> >>   fdt: Drop SPL_BUILD macro
> >>   bloblist: Put the magic number first
> >>   bloblist: Rename the SPL tag
> >>   bloblist: Drop unused tags
> >>   bloblist: Use explicit numbering for the tags
> >>   bloblist: Support allocating the bloblist
> >>   bloblist: Use LOG_CATEGORY to simply logging
> >>   bloblist: Use 'phase' consistently for bloblists
> >>   bloblist: Refactor Kconfig to support alloc or fixed
> >>   arm: qemu: Add an SPL build
> >>   bloblist: Add functions to obtain base address and size
> >>   passage: Support an incoming passage
> >>   passage: Support a control devicetree
> >>   passage: arm: Accept a passage from the previous phase
> >>   passage: spl: Support adding the dtb to the passage bloblist
> >>   passage: spl: Support passing the passage to U-Boot
> >>   passage: Record where the devicetree came from
> >>   passage: Report the devicetree source
> >>   passage: Add a qemu test for ARM
> >>   bloblist: doc: Bring in the API documentation
> >>   bloblist: Relicense to allow BSD-3-Clause
> >>   sandbox: Add a way of checking structs for standard passage
> >>   passage: Add documentation
> >>   passage: Add docs for spl_handoff
> >>   x86: Move Intel GNVS file into the common include directory
> >>   passage: Add checks for pre-existing blobs
> >>   WIP: RFC: Add a gitlab test
> >>
> >>  .gitlab-ci.yml                                |   6 +
> >>  MAINTAINERS                                   |  10 +
> >>  Makefile                                      |   2 +-
> >>  arch/arm/cpu/armv7/start.S                    |   7 +-
> >>  arch/arm/dts/qemu-arm-u-boot.dtsi             |  22 ++
> >>  arch/arm/lib/crt0.S                           |   4 +
> >>  arch/arm/mach-qemu/Kconfig                    |   9 +
> >>  arch/sandbox/cpu/spl.c                        |   2 +-
> >>  arch/x86/cpu/apollolake/acpi.c                |   2 +-
> >>  arch/x86/cpu/broadwell/cpu_from_spl.c         |   4 +-
> >>  arch/x86/cpu/intel_common/acpi.c              |   2 +-
> >>  .../include/asm/arch-apollolake/global_nvs.h  |   2 +-
> >>  arch/x86/lib/spl.c                            |   2 +-
> >>  arch/x86/lib/tpl.c                            |   2 +-
> >>  board/emulation/qemu-arm/Kconfig              |  23 +-
> >>  board/emulation/qemu-arm/MAINTAINERS          |   1 +
> >>  board/emulation/qemu-arm/Makefile             |   1 +
> >>  board/emulation/qemu-arm/spl.c                |  27 ++
> >>  board/google/chromebook_coral/coral.c         |   2 +-
> >>  board/sandbox/Makefile                        |   3 +-
> >>  board/sandbox/stdpass_check.c                 | 107 ++++++
> >>  cmd/bdinfo.c                                  |   2 +
> >>  common/Kconfig                                | 161 ++++++++-
> >>  common/bloblist.c                             | 124 +++++--
> >>  common/board_f.c                              |  48 ++-
> >>  common/board_r.c                              |  18 +
> >>  common/spl/spl.c                              |  74 +++-
> >>  configs/qemu_arm_spl_defconfig                |  78 +++++
> >>  doc/board/emulation/qemu-arm.rst              |  38 +++
> >>  doc/develop/bloblist.rst                      |  28 +-
> >>  doc/develop/index.rst                         |   1 +
> >>  doc/develop/std_passage.rst                   | 319 ++++++++++++++++++
> >>  drivers/core/device.c                         |  11 +
> >>  drivers/core/root.c                           |   7 +
> >>  drivers/core/uclass.c                         |  13 +
> >>  drivers/serial/serial-uclass.c                |   3 +-
> >>  dts/Kconfig                                   |  12 +
> >>  include/asm-generic/global_data.h             |  35 ++
> >>  include/bloblist.h                            | 175 +++++++---
> >>  include/dm/device.h                           |  11 +-
> >>  include/dm/root.h                             |   8 +
> >>  include/dm/uclass-internal.h                  |   7 +
> >>  include/fdtdec.h                              |  40 ++-
> >>  include/handoff.h                             |   8 +-
> >>  .../x86/include/asm => include}/intel_gnvs.h  |   0
> >>  include/linux/kconfig.h                       |  18 +
> >>  include/linux/stddef.h                        |   8 +-
> >>  include/spl.h                                 |  15 +
> >>  include/stdpass/README                        |   4 +
> >>  include/stdpass/tpm2_eventlog.h               |  42 +++
> >>  include/stdpass/vboot_ctx.h                   | 267 +++++++++++++++
> >>  lib/asm-offsets.c                             |   5 +
> >>  lib/fdtdec.c                                  |  65 +++-
> >>  scripts/config_whitelist.txt                  |   1 +
> >>  test/bloblist.c                               |  21 +-
> >>  test/dm/core.c                                |  41 +++
> >>  test/py/tests/test_passage.py                 |  11 +
> >>  57 files changed, 1798 insertions(+), 161 deletions(-)
> >>  create mode 100644 arch/arm/dts/qemu-arm-u-boot.dtsi
> >>  create mode 100644 board/emulation/qemu-arm/spl.c
> >>  create mode 100644 board/sandbox/stdpass_check.c
> >>  create mode 100644 configs/qemu_arm_spl_defconfig
> >>  create mode 100644 doc/develop/std_passage.rst
> >>  rename {arch/x86/include/asm => include}/intel_gnvs.h (100%)
> >>  create mode 100644 include/stdpass/README
> >>  create mode 100644 include/stdpass/tpm2_eventlog.h
> >>  create mode 100644 include/stdpass/vboot_ctx.h
> >>  create mode 100644 test/py/tests/test_passage.py
> >>
> >> --
> >> 2.33.1.1089.g2158813163f-goog
> >>
> >
> >
> > --
> > François-Frédéric Ozog | Director Business Development
> > T: +33.67221.6485
> > francois.ozog@linaro.org | Skype: ffozog
> >
>


-- 
François-Frédéric Ozog | *Director Business Development*
T: +33.67221.6485
francois.ozog@linaro.org | Skype: ffozog

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 00/31] passage: Define a standard for firmware data flow
@ 2021-11-02 16:03       ` François Ozog
  0 siblings, 0 replies; 77+ messages in thread
From: François Ozog @ 2021-11-02 16:03 UTC (permalink / raw)
  To: Simon Glass
  Cc: Marek Vasut, Tom Rini, Albert Aribaud, Masahiro Yamada,
	Heinrich Schuchardt, Bill Mills, Ilias Apalodimas,
	QEMU Developers, U-Boot Mailing List, Jerry Van Baren, Bin Meng,
	Pavel Herrmann

[-- Attachment #1: Type: text/plain, Size: 14836 bytes --]

Hi Simon,

On Tue, 2 Nov 2021 at 15:59, Simon Glass <sjg@chromium.org> wrote:

> Hi François,
>
> On Mon, 1 Nov 2021 at 02:53, François Ozog <francois.ozog@linaro.org>
> wrote:
> >
> > Hi Simon,
> >
> > this seems a great endeavor. I'd like to better understand the scope of
> it.
> >
> > Is it to be used as part of what could become a U-Boot entry ABI scheme?
> By that I mean giving some fixed aspects
> > to U-Boot entry while letting boards to have flexibility (say for
> instance that the first 5 architecture ABI
> > parameter registers are reserved for U-Boot), and the Passage is about
> specifying either those reserved registers
> > or one of them?
>
> The goal is to provide a standard entry scheme for all firmware
> binaries. Whether it achieves that (or can with some mods) is up for
> discussion.
>
> If you say
a) define a U-Boot entry ABI and providing a firmware-to-firmware
information passing facility which would be part of all firmware ABIs (as
the projects decide to define their own ABI) it looks good.
but If you say
b) define a standard entry scheme (register map, processor state, MMU
state, SMMU state, GIC state...) that does not look realistic.
I think you mean a) but just want to be sure.

> Re the registers, do you think we need 5?
>
> >
> > Thinking entry ABI, here is what I observed on Arm:
> >
> > Linux has two entry ABIs:
> > - plain: x0 = dtb;
> >           command line = dtb:/chosen/bootargs; initrd =
> dtb:/chosen/linux,initrd-*
> > - EFI: x0=handle, x1=systemtable, x30=return address;
> >            dtb = EFI_UUID config table; initrd = efi:<loadfile2(INITRD
> vendor media UUID); command line = efi: image_protocol::load_options
> >
> > U-Boot (proper) has plenty of schemes:
> > - dtb is passed as either x0, x1, fixed memory area (Qemu which is bad
> in itself), or other registers
> > - additional information passing: board specific register scheme, SMC
> calls
> > - U-Boot for RPI boards implement a Linux shaped entry ABI to be
> launched by Videocore firmware
> >
> > Based on all the above, I would tend to think that RPI scheme is a good
> idea but also
> > shall not prevent additional schemes for the boards.
>
> I was not actually considering Linux since I believe/assume its entry
> scheme is fixed and not up for discussion.
>
> I also did not think about the EFI case. As I understand it we cannot
> touch it as it is used by UEFI today. Maybe it is even in the
> standard?
>
It is in the spec and we are making it evolve, or its understanding evolve
(jurisprudence) for instance on initrd standard handling.

>
> Really I am hoping we can start afresh...?
>
> >
> > What about a U-Boot Arm entry ABI like:
> > - plain: x0=dtb, x1=<Passage defined>, x2-x5 = <reserved>, other
> registers are per platform, SMC calls allowed too
>
> Hmm we don't actually need the dtb as it is available in the bloblist.
>
If you don't have x0=dtb, then you will not be able to use U-Boot on RPI4.
Unless you want to redo everything the RPI firmware is doing.

> But I added an offset to it as a convenience.
>
> > - EFI: x0=handle, x1=systemtable, x30=return address;  (when U-Boot is
> launched as an EFI app)
> >        dtb = EFI_UUID config table, + Passage = Passage UUID config table
>
> I don't understand the last line. Where is the passage info /
> bloblist? Do you mean it goes in the HOB list with a UUID? I suppose
> that is the most EFI-compatible way.
>
The Passage config table  could just contain the "head" of the
bloblist/Passage information.

>
> What do you think about the idea of using an offset into the bloblist
> for the dtb?

It is possible but as I said, failing to mimic Linux entry ABI would miss
the opportunity to just boot without changes on RPI4.

> Also, can we make the standard passage ABI a build-time
> option, so it is deterministic?
>
> Looks good. I would look into stating that for SystemReady we would advise
to use that option and make it standard for Trusted Substrate (Linaro
recipes that we upstreaming to make SystemReady compliance easy and
consistent across platforms).

> >
> > We could further leverage Passage to pass Operating Systems parameters
> that could be removed from device tree (migration of /chosen to Passage).
> Memory inventory would still be in DT but allocations for CMA or GPUs would
> be in Passage. This idea is to reach a point where  device tree is a
> "pristine" hardware description.
>
> I'm worried about this becoming a substitute for devicetree. Really my
> intent is to provide a way to pass simple info, whereas what you talk
> about there seems like something that should be DT, just that it might
> need suitable bindings.
>
> I see your point and I agree It should not be a substitute.
here is an expanded version of what I had in mind when I wrote those lines.
cma, initrd and other Linux kernel parameters can be conveyed either
through command line or DT.
When using the non UEFI Linux entry ABI, you need to use the DT to pass
those parameters.
When using the UEFI Linux entry ABI, you *can* (not must) use the command
line to pass all information, leaving the DT passed to the OS without any
/chosen.
When introducing Passage, I was wondering if we could pass command line to
Linux and, same as UEFI, leave the DT free from /chosen.
I am not sure it is a good goal though. I may be too pushing for a DT free
from parameters.

> As you know I have more expansive views about what should be in DT.
>
I think both of us are huge supporters of DT format and self describing
capabilities.
I am inclined to put rules into what fits into what lands in the DT that is
passed to the OS.
I am a fan of having DT used more in ad-hoc files.

> >
> > Cheers
> >
> > PS: as Ilias mentions, this patch set contains bug fixes, non
> immediately related additional functions (DM stats). It would be great to
> carve those out to fast path them and keep this one with the very core of
> your idea.
>
> The DM stats is used in 'passage: Report the devicetree source'. I
> know it is sideways but I think it is better to make the output line
> more useful than just reporting the devicetree source.
>
> I believe the DM stats has merits in its own. You could upstream this
independently and then Passage would be yet another "customer" of the
feature.

> The first patch is indeed unrelated. I will pick it up so we can drop
> it for the next rev.
>
> Regards,
> Simon
>
>
> >
> > On Mon, 1 Nov 2021 at 02:17, Simon Glass <sjg@chromium.org> wrote:
> >>
> >>
> >> This series adds a standard way of passing information between different
> >> firmware phases. This already exists in U-Boot at a very basic level, in
> >> the form of a bloblist containing an spl_handoff structure, but the
> intent
> >> here is to define something useful across projects.
> >>
> >> The need for this is growing as firmware fragments into multiple
> binaries
> >> each with its own purpose. Without any run-time connection, we must rely
> >> on build-time settings which are brittle and painful to keep in sync.
> >>
> >> This feature is named 'standard passage' since the name is more unique
> >> than many others that could be chosen, it is a passage in the sense that
> >> information is flowing from one place to another and it is standard,
> >> because that is what we want to create.
> >>
> >> The implementation is simply a pointer to a bloblist in a register, with
> >> an extra register to point to a devicetree, for more complex data, if
> one
> >> is present in the bloblist. This should cover all cases (small memory
> >> footprint as well as complex data flow) and be easy enough to implement
> on
> >> all architectures.
> >>
> >> The core bloblist code is relicensed to BSD-3-Clause in case it is
> useful
> >> in non-GPL projects but there is no requirement to use the same code.
> >>
> >> This series includes tweaks to the bloblist implementation in U-Boot to
> >> make it more suitable for the task, including:
> >>
> >>    - Allocate tags explicitly in the enum
> >>    - Put the magic number first
> >>    - Define a process for adding tags
> >>
> >> The emphasis is on enabling open communcation between binaries, not
> >> enabling passage of secret, undocumented data, although this is possible
> >> in a private environment.
> >>
> >> This series is built on the OF_BOARD series It is available at
> >> u-boot-dm/pass-working or:
> >>
> >>
> https://source.denx.de/u-boot/custodians/u-boot-dm/-/commit/073b5c156f222c69a98b8ebcaa563d1ff10eb217
> >>
> >>
> >> Simon Glass (31):
> >>   Makefile: Correct TPL rule for OF_REAL
> >>   kconfig: Add support for conditional values
> >>   dm: core: Allow getting some basic stats
> >>   stddef: Avoid warning with clang with offsetof()
> >>   fdt: Drop SPL_BUILD macro
> >>   bloblist: Put the magic number first
> >>   bloblist: Rename the SPL tag
> >>   bloblist: Drop unused tags
> >>   bloblist: Use explicit numbering for the tags
> >>   bloblist: Support allocating the bloblist
> >>   bloblist: Use LOG_CATEGORY to simply logging
> >>   bloblist: Use 'phase' consistently for bloblists
> >>   bloblist: Refactor Kconfig to support alloc or fixed
> >>   arm: qemu: Add an SPL build
> >>   bloblist: Add functions to obtain base address and size
> >>   passage: Support an incoming passage
> >>   passage: Support a control devicetree
> >>   passage: arm: Accept a passage from the previous phase
> >>   passage: spl: Support adding the dtb to the passage bloblist
> >>   passage: spl: Support passing the passage to U-Boot
> >>   passage: Record where the devicetree came from
> >>   passage: Report the devicetree source
> >>   passage: Add a qemu test for ARM
> >>   bloblist: doc: Bring in the API documentation
> >>   bloblist: Relicense to allow BSD-3-Clause
> >>   sandbox: Add a way of checking structs for standard passage
> >>   passage: Add documentation
> >>   passage: Add docs for spl_handoff
> >>   x86: Move Intel GNVS file into the common include directory
> >>   passage: Add checks for pre-existing blobs
> >>   WIP: RFC: Add a gitlab test
> >>
> >>  .gitlab-ci.yml                                |   6 +
> >>  MAINTAINERS                                   |  10 +
> >>  Makefile                                      |   2 +-
> >>  arch/arm/cpu/armv7/start.S                    |   7 +-
> >>  arch/arm/dts/qemu-arm-u-boot.dtsi             |  22 ++
> >>  arch/arm/lib/crt0.S                           |   4 +
> >>  arch/arm/mach-qemu/Kconfig                    |   9 +
> >>  arch/sandbox/cpu/spl.c                        |   2 +-
> >>  arch/x86/cpu/apollolake/acpi.c                |   2 +-
> >>  arch/x86/cpu/broadwell/cpu_from_spl.c         |   4 +-
> >>  arch/x86/cpu/intel_common/acpi.c              |   2 +-
> >>  .../include/asm/arch-apollolake/global_nvs.h  |   2 +-
> >>  arch/x86/lib/spl.c                            |   2 +-
> >>  arch/x86/lib/tpl.c                            |   2 +-
> >>  board/emulation/qemu-arm/Kconfig              |  23 +-
> >>  board/emulation/qemu-arm/MAINTAINERS          |   1 +
> >>  board/emulation/qemu-arm/Makefile             |   1 +
> >>  board/emulation/qemu-arm/spl.c                |  27 ++
> >>  board/google/chromebook_coral/coral.c         |   2 +-
> >>  board/sandbox/Makefile                        |   3 +-
> >>  board/sandbox/stdpass_check.c                 | 107 ++++++
> >>  cmd/bdinfo.c                                  |   2 +
> >>  common/Kconfig                                | 161 ++++++++-
> >>  common/bloblist.c                             | 124 +++++--
> >>  common/board_f.c                              |  48 ++-
> >>  common/board_r.c                              |  18 +
> >>  common/spl/spl.c                              |  74 +++-
> >>  configs/qemu_arm_spl_defconfig                |  78 +++++
> >>  doc/board/emulation/qemu-arm.rst              |  38 +++
> >>  doc/develop/bloblist.rst                      |  28 +-
> >>  doc/develop/index.rst                         |   1 +
> >>  doc/develop/std_passage.rst                   | 319 ++++++++++++++++++
> >>  drivers/core/device.c                         |  11 +
> >>  drivers/core/root.c                           |   7 +
> >>  drivers/core/uclass.c                         |  13 +
> >>  drivers/serial/serial-uclass.c                |   3 +-
> >>  dts/Kconfig                                   |  12 +
> >>  include/asm-generic/global_data.h             |  35 ++
> >>  include/bloblist.h                            | 175 +++++++---
> >>  include/dm/device.h                           |  11 +-
> >>  include/dm/root.h                             |   8 +
> >>  include/dm/uclass-internal.h                  |   7 +
> >>  include/fdtdec.h                              |  40 ++-
> >>  include/handoff.h                             |   8 +-
> >>  .../x86/include/asm => include}/intel_gnvs.h  |   0
> >>  include/linux/kconfig.h                       |  18 +
> >>  include/linux/stddef.h                        |   8 +-
> >>  include/spl.h                                 |  15 +
> >>  include/stdpass/README                        |   4 +
> >>  include/stdpass/tpm2_eventlog.h               |  42 +++
> >>  include/stdpass/vboot_ctx.h                   | 267 +++++++++++++++
> >>  lib/asm-offsets.c                             |   5 +
> >>  lib/fdtdec.c                                  |  65 +++-
> >>  scripts/config_whitelist.txt                  |   1 +
> >>  test/bloblist.c                               |  21 +-
> >>  test/dm/core.c                                |  41 +++
> >>  test/py/tests/test_passage.py                 |  11 +
> >>  57 files changed, 1798 insertions(+), 161 deletions(-)
> >>  create mode 100644 arch/arm/dts/qemu-arm-u-boot.dtsi
> >>  create mode 100644 board/emulation/qemu-arm/spl.c
> >>  create mode 100644 board/sandbox/stdpass_check.c
> >>  create mode 100644 configs/qemu_arm_spl_defconfig
> >>  create mode 100644 doc/develop/std_passage.rst
> >>  rename {arch/x86/include/asm => include}/intel_gnvs.h (100%)
> >>  create mode 100644 include/stdpass/README
> >>  create mode 100644 include/stdpass/tpm2_eventlog.h
> >>  create mode 100644 include/stdpass/vboot_ctx.h
> >>  create mode 100644 test/py/tests/test_passage.py
> >>
> >> --
> >> 2.33.1.1089.g2158813163f-goog
> >>
> >
> >
> > --
> > François-Frédéric Ozog | Director Business Development
> > T: +33.67221.6485
> > francois.ozog@linaro.org | Skype: ffozog
> >
>


-- 
François-Frédéric Ozog | *Director Business Development*
T: +33.67221.6485
francois.ozog@linaro.org | Skype: ffozog

[-- Attachment #2: Type: text/html, Size: 21058 bytes --]

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 00/31] passage: Define a standard for firmware data flow
  2021-11-02 16:03       ` François Ozog
@ 2021-11-05  2:02         ` Simon Glass
  -1 siblings, 0 replies; 77+ messages in thread
From: Simon Glass @ 2021-11-05  2:02 UTC (permalink / raw)
  To: François Ozog
  Cc: Marek Vasut, Tom Rini, Albert Aribaud, Masahiro Yamada,
	Heinrich Schuchardt, Bill Mills, Ilias Apalodimas,
	QEMU Developers, U-Boot Mailing List, Jerry Van Baren, Bin Meng,
	Pavel Herrmann

Hi François,

On Tue, 2 Nov 2021 at 10:03, François Ozog <francois.ozog@linaro.org> wrote:
>
> Hi Simon,
>
> On Tue, 2 Nov 2021 at 15:59, Simon Glass <sjg@chromium.org> wrote:
>>
>> Hi François,
>>
>> On Mon, 1 Nov 2021 at 02:53, François Ozog <francois.ozog@linaro.org> wrote:
>> >
>> > Hi Simon,
>> >
>> > this seems a great endeavor. I'd like to better understand the scope of it.
>> >
>> > Is it to be used as part of what could become a U-Boot entry ABI scheme? By that I mean giving some fixed aspects
>> > to U-Boot entry while letting boards to have flexibility (say for instance that the first 5 architecture ABI
>> > parameter registers are reserved for U-Boot), and the Passage is about specifying either those reserved registers
>> > or one of them?
>>
>> The goal is to provide a standard entry scheme for all firmware
>> binaries. Whether it achieves that (or can with some mods) is up for
>> discussion.
>>
> If you say
> a) define a U-Boot entry ABI and providing a firmware-to-firmware information passing facility which would be part of all firmware ABIs (as the projects decide to define their own ABI) it looks good.
> but If you say

It is an ABI to be adopted by U-Boot but also other firmware. For
example, if TF-A calls U-Boot it should use standard passage. If
U-Boot calls TF-A or Optee it should use standard passage.

> b) define a standard entry scheme (register map, processor state, MMU state, SMMU state, GIC state...) that does not look realistic.

No I don't mean that. This data structure could be used in any state,
so long as the two registers are set correctly.

> I think you mean a) but just want to be sure.

Yes I think so.

>>
>> Re the registers, do you think we need 5?
>>

I don't :-)

>> >
>> > Thinking entry ABI, here is what I observed on Arm:
>> >
>> > Linux has two entry ABIs:
>> > - plain: x0 = dtb;
>> >           command line = dtb:/chosen/bootargs; initrd = dtb:/chosen/linux,initrd-*
>> > - EFI: x0=handle, x1=systemtable, x30=return address;
>> >            dtb = EFI_UUID config table; initrd = efi:<loadfile2(INITRD vendor media UUID); command line = efi: image_protocol::load_options
>> >
>> > U-Boot (proper) has plenty of schemes:
>> > - dtb is passed as either x0, x1, fixed memory area (Qemu which is bad in itself), or other registers
>> > - additional information passing: board specific register scheme, SMC calls
>> > - U-Boot for RPI boards implement a Linux shaped entry ABI to be launched by Videocore firmware
>> >
>> > Based on all the above, I would tend to think that RPI scheme is a good idea but also
>> > shall not prevent additional schemes for the boards.
>>
>> I was not actually considering Linux since I believe/assume its entry
>> scheme is fixed and not up for discussion.
>>
>> I also did not think about the EFI case. As I understand it we cannot
>> touch it as it is used by UEFI today. Maybe it is even in the
>> standard?
>
> It is in the spec and we are making it evolve, or its understanding evolve (jurisprudence) for instance on initrd standard handling.

Well perhaps we could merge it with standard passage. But EFI is not
going to want to use a bloblist, it will want to use a HOB.

>>
>>
>> Really I am hoping we can start afresh...?
>>
>> >
>> > What about a U-Boot Arm entry ABI like:
>> > - plain: x0=dtb, x1=<Passage defined>, x2-x5 = <reserved>, other registers are per platform, SMC calls allowed too
>>
>> Hmm we don't actually need the dtb as it is available in the bloblist.
>
> If you don't have x0=dtb, then you will not be able to use U-Boot on RPI4.
> Unless you want to redo everything the RPI firmware is doing.

That's right, RPI cannot support standard passage. It is not
open-source firmware so it isn't really relevant to this discussion.
It will just do what it does and have limited functionality, with
work-arounds to deal with the pain, as one might expect.

>>
>> But I added an offset to it as a convenience.
>>
>> > - EFI: x0=handle, x1=systemtable, x30=return address;  (when U-Boot is launched as an EFI app)
>> >        dtb = EFI_UUID config table, + Passage = Passage UUID config table
>>
>> I don't understand the last line. Where is the passage info /
>> bloblist? Do you mean it goes in the HOB list with a UUID? I suppose
>> that is the most EFI-compatible way.
>
> The Passage config table  could just contain the "head" of the bloblist/Passage information.

If UEFI wants to deal with standard passage, that is...

>>
>>
>> What do you think about the idea of using an offset into the bloblist
>> for the dtb?
>
> It is possible but as I said, failing to mimic Linux entry ABI would miss the opportunity to just boot without changes on RPI4.

See above. Broadcom could look at open-sourcing their bootloader if they wish.

>>
>> Also, can we make the standard passage ABI a build-time
>> option, so it is deterministic?
>>
> Looks good. I would look into stating that for SystemReady we would advise to use that option and make it standard for Trusted Substrate (Linaro recipes that we upstreaming to make SystemReady compliance easy and consistent across platforms).

OK. I mean that if the option is enabled, then standard passage must
be provided / emitted or things won't work. If the option is disabled,
then standard passage is not used. In other words, we are looking for
magic values in registers, etc, just enabling/disabling it at
build-time.

>>
>> >
>> > We could further leverage Passage to pass Operating Systems parameters that could be removed from device tree (migration of /chosen to Passage). Memory inventory would still be in DT but allocations for CMA or GPUs would be in Passage. This idea is to reach a point where  device tree is a "pristine" hardware description.
>>
>> I'm worried about this becoming a substitute for devicetree. Really my
>> intent is to provide a way to pass simple info, whereas what you talk
>> about there seems like something that should be DT, just that it might
>> need suitable bindings.
>>
> I see your point and I agree It should not be a substitute.
> here is an expanded version of what I had in mind when I wrote those lines.
> cma, initrd and other Linux kernel parameters can be conveyed either through command line or DT.
> When using the non UEFI Linux entry ABI, you need to use the DT to pass those parameters.
> When using the UEFI Linux entry ABI, you *can* (not must) use the command line to pass all information, leaving the DT passed to the OS without any /chosen.
> When introducing Passage, I was wondering if we could pass command line to Linux and, same as UEFI, leave the DT free from /chosen.
> I am not sure it is a good goal though. I may be too pushing for a DT free from parameters.

We could. Are there benefits to that?

I doubt we would pass the standard passage to Linux as a bloblist. I
imagine something like this. The bloblist sits in memory with some
things in it, including a devicetree, perhaps an SMBIOS table and a
TPM log. But when U-Boot calls Linux it puts the address/size of those
individual things in the devicetree. They don't move and are still
contiguous in memory, but the bloblist around them is forgotten. Linux
doesn't know that the three separate things it is picking up are
actually part of a bloblist structure, since it doesn't care about
that. Even a console log could work the same way. That way we don't
end up trying to teach Linux about bloblist when it already has a
perfectly good means to accept these items.

For ACPI I see things a similar way. The ACPI tables can point to
things that *happen* to be in a bloblist, but without any knowledge of
that needed in Linux, grub, etc.

>>
>> As you know I have more expansive views about what should be in DT.
>
> I think both of us are huge supporters of DT format and self describing capabilities.
> I am inclined to put rules into what fits into what lands in the DT that is passed to the OS.
> I am a fan of having DT used more in ad-hoc files.

Me too.

>>
>> >
>> > Cheers
>> >
>> > PS: as Ilias mentions, this patch set contains bug fixes, non immediately related additional functions (DM stats). It would be great to carve those out to fast path them and keep this one with the very core of your idea.
>>
>> The DM stats is used in 'passage: Report the devicetree source'. I
>> know it is sideways but I think it is better to make the output line
>> more useful than just reporting the devicetree source.
>>
> I believe the DM stats has merits in its own. You could upstream this independently and then Passage would be yet another "customer" of the feature.

I could, but it would just be a debug feature so people might not
think it worth the code space. With the devicetree source it is more
compelling.

>>
>> The first patch is indeed unrelated. I will pick it up so we can drop
>> it for the next rev.
>>
[..]

Regards,
Simon


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 00/31] passage: Define a standard for firmware data flow
@ 2021-11-05  2:02         ` Simon Glass
  0 siblings, 0 replies; 77+ messages in thread
From: Simon Glass @ 2021-11-05  2:02 UTC (permalink / raw)
  To: François Ozog
  Cc: U-Boot Mailing List, Tom Rini, Bin Meng, Ilias Apalodimas,
	Bill Mills, Heinrich Schuchardt, Albert Aribaud, Jerry Van Baren,
	Marek Vasut, Masahiro Yamada, Pavel Herrmann, QEMU Developers

Hi François,

On Tue, 2 Nov 2021 at 10:03, François Ozog <francois.ozog@linaro.org> wrote:
>
> Hi Simon,
>
> On Tue, 2 Nov 2021 at 15:59, Simon Glass <sjg@chromium.org> wrote:
>>
>> Hi François,
>>
>> On Mon, 1 Nov 2021 at 02:53, François Ozog <francois.ozog@linaro.org> wrote:
>> >
>> > Hi Simon,
>> >
>> > this seems a great endeavor. I'd like to better understand the scope of it.
>> >
>> > Is it to be used as part of what could become a U-Boot entry ABI scheme? By that I mean giving some fixed aspects
>> > to U-Boot entry while letting boards to have flexibility (say for instance that the first 5 architecture ABI
>> > parameter registers are reserved for U-Boot), and the Passage is about specifying either those reserved registers
>> > or one of them?
>>
>> The goal is to provide a standard entry scheme for all firmware
>> binaries. Whether it achieves that (or can with some mods) is up for
>> discussion.
>>
> If you say
> a) define a U-Boot entry ABI and providing a firmware-to-firmware information passing facility which would be part of all firmware ABIs (as the projects decide to define their own ABI) it looks good.
> but If you say

It is an ABI to be adopted by U-Boot but also other firmware. For
example, if TF-A calls U-Boot it should use standard passage. If
U-Boot calls TF-A or Optee it should use standard passage.

> b) define a standard entry scheme (register map, processor state, MMU state, SMMU state, GIC state...) that does not look realistic.

No I don't mean that. This data structure could be used in any state,
so long as the two registers are set correctly.

> I think you mean a) but just want to be sure.

Yes I think so.

>>
>> Re the registers, do you think we need 5?
>>

I don't :-)

>> >
>> > Thinking entry ABI, here is what I observed on Arm:
>> >
>> > Linux has two entry ABIs:
>> > - plain: x0 = dtb;
>> >           command line = dtb:/chosen/bootargs; initrd = dtb:/chosen/linux,initrd-*
>> > - EFI: x0=handle, x1=systemtable, x30=return address;
>> >            dtb = EFI_UUID config table; initrd = efi:<loadfile2(INITRD vendor media UUID); command line = efi: image_protocol::load_options
>> >
>> > U-Boot (proper) has plenty of schemes:
>> > - dtb is passed as either x0, x1, fixed memory area (Qemu which is bad in itself), or other registers
>> > - additional information passing: board specific register scheme, SMC calls
>> > - U-Boot for RPI boards implement a Linux shaped entry ABI to be launched by Videocore firmware
>> >
>> > Based on all the above, I would tend to think that RPI scheme is a good idea but also
>> > shall not prevent additional schemes for the boards.
>>
>> I was not actually considering Linux since I believe/assume its entry
>> scheme is fixed and not up for discussion.
>>
>> I also did not think about the EFI case. As I understand it we cannot
>> touch it as it is used by UEFI today. Maybe it is even in the
>> standard?
>
> It is in the spec and we are making it evolve, or its understanding evolve (jurisprudence) for instance on initrd standard handling.

Well perhaps we could merge it with standard passage. But EFI is not
going to want to use a bloblist, it will want to use a HOB.

>>
>>
>> Really I am hoping we can start afresh...?
>>
>> >
>> > What about a U-Boot Arm entry ABI like:
>> > - plain: x0=dtb, x1=<Passage defined>, x2-x5 = <reserved>, other registers are per platform, SMC calls allowed too
>>
>> Hmm we don't actually need the dtb as it is available in the bloblist.
>
> If you don't have x0=dtb, then you will not be able to use U-Boot on RPI4.
> Unless you want to redo everything the RPI firmware is doing.

That's right, RPI cannot support standard passage. It is not
open-source firmware so it isn't really relevant to this discussion.
It will just do what it does and have limited functionality, with
work-arounds to deal with the pain, as one might expect.

>>
>> But I added an offset to it as a convenience.
>>
>> > - EFI: x0=handle, x1=systemtable, x30=return address;  (when U-Boot is launched as an EFI app)
>> >        dtb = EFI_UUID config table, + Passage = Passage UUID config table
>>
>> I don't understand the last line. Where is the passage info /
>> bloblist? Do you mean it goes in the HOB list with a UUID? I suppose
>> that is the most EFI-compatible way.
>
> The Passage config table  could just contain the "head" of the bloblist/Passage information.

If UEFI wants to deal with standard passage, that is...

>>
>>
>> What do you think about the idea of using an offset into the bloblist
>> for the dtb?
>
> It is possible but as I said, failing to mimic Linux entry ABI would miss the opportunity to just boot without changes on RPI4.

See above. Broadcom could look at open-sourcing their bootloader if they wish.

>>
>> Also, can we make the standard passage ABI a build-time
>> option, so it is deterministic?
>>
> Looks good. I would look into stating that for SystemReady we would advise to use that option and make it standard for Trusted Substrate (Linaro recipes that we upstreaming to make SystemReady compliance easy and consistent across platforms).

OK. I mean that if the option is enabled, then standard passage must
be provided / emitted or things won't work. If the option is disabled,
then standard passage is not used. In other words, we are looking for
magic values in registers, etc, just enabling/disabling it at
build-time.

>>
>> >
>> > We could further leverage Passage to pass Operating Systems parameters that could be removed from device tree (migration of /chosen to Passage). Memory inventory would still be in DT but allocations for CMA or GPUs would be in Passage. This idea is to reach a point where  device tree is a "pristine" hardware description.
>>
>> I'm worried about this becoming a substitute for devicetree. Really my
>> intent is to provide a way to pass simple info, whereas what you talk
>> about there seems like something that should be DT, just that it might
>> need suitable bindings.
>>
> I see your point and I agree It should not be a substitute.
> here is an expanded version of what I had in mind when I wrote those lines.
> cma, initrd and other Linux kernel parameters can be conveyed either through command line or DT.
> When using the non UEFI Linux entry ABI, you need to use the DT to pass those parameters.
> When using the UEFI Linux entry ABI, you *can* (not must) use the command line to pass all information, leaving the DT passed to the OS without any /chosen.
> When introducing Passage, I was wondering if we could pass command line to Linux and, same as UEFI, leave the DT free from /chosen.
> I am not sure it is a good goal though. I may be too pushing for a DT free from parameters.

We could. Are there benefits to that?

I doubt we would pass the standard passage to Linux as a bloblist. I
imagine something like this. The bloblist sits in memory with some
things in it, including a devicetree, perhaps an SMBIOS table and a
TPM log. But when U-Boot calls Linux it puts the address/size of those
individual things in the devicetree. They don't move and are still
contiguous in memory, but the bloblist around them is forgotten. Linux
doesn't know that the three separate things it is picking up are
actually part of a bloblist structure, since it doesn't care about
that. Even a console log could work the same way. That way we don't
end up trying to teach Linux about bloblist when it already has a
perfectly good means to accept these items.

For ACPI I see things a similar way. The ACPI tables can point to
things that *happen* to be in a bloblist, but without any knowledge of
that needed in Linux, grub, etc.

>>
>> As you know I have more expansive views about what should be in DT.
>
> I think both of us are huge supporters of DT format and self describing capabilities.
> I am inclined to put rules into what fits into what lands in the DT that is passed to the OS.
> I am a fan of having DT used more in ad-hoc files.

Me too.

>>
>> >
>> > Cheers
>> >
>> > PS: as Ilias mentions, this patch set contains bug fixes, non immediately related additional functions (DM stats). It would be great to carve those out to fast path them and keep this one with the very core of your idea.
>>
>> The DM stats is used in 'passage: Report the devicetree source'. I
>> know it is sideways but I think it is better to make the output line
>> more useful than just reporting the devicetree source.
>>
> I believe the DM stats has merits in its own. You could upstream this independently and then Passage would be yet another "customer" of the feature.

I could, but it would just be a debug feature so people might not
think it worth the code space. With the devicetree source it is more
compelling.

>>
>> The first patch is indeed unrelated. I will pick it up so we can drop
>> it for the next rev.
>>
[..]

Regards,
Simon

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 00/31] passage: Define a standard for firmware data flow
  2021-11-05  2:02         ` Simon Glass
@ 2021-11-05  8:26           ` François Ozog
  -1 siblings, 0 replies; 77+ messages in thread
From: François Ozog @ 2021-11-05  8:26 UTC (permalink / raw)
  To: Simon Glass
  Cc: U-Boot Mailing List, Tom Rini, Bin Meng, Ilias Apalodimas,
	Bill Mills, Heinrich Schuchardt, Albert Aribaud, Jerry Van Baren,
	Marek Vasut, Masahiro Yamada, Pavel Herrmann, QEMU Developers

On Fri, 5 Nov 2021 at 03:02, Simon Glass <sjg@chromium.org> wrote:

> Hi François,
>
> On Tue, 2 Nov 2021 at 10:03, François Ozog <francois.ozog@linaro.org>
> wrote:
> >
> > Hi Simon,
> >
> > On Tue, 2 Nov 2021 at 15:59, Simon Glass <sjg@chromium.org> wrote:
> >>
> >> Hi François,
> >>
> >> On Mon, 1 Nov 2021 at 02:53, François Ozog <francois.ozog@linaro.org>
> wrote:
> >> >
> >> > Hi Simon,
> >> >
> >> > this seems a great endeavor. I'd like to better understand the scope
> of it.
> >> >
> >> > Is it to be used as part of what could become a U-Boot entry ABI
> scheme? By that I mean giving some fixed aspects
> >> > to U-Boot entry while letting boards to have flexibility (say for
> instance that the first 5 architecture ABI
> >> > parameter registers are reserved for U-Boot), and the Passage is
> about specifying either those reserved registers
> >> > or one of them?
> >>
> >> The goal is to provide a standard entry scheme for all firmware
> >> binaries. Whether it achieves that (or can with some mods) is up for
> >> discussion.
> >>
> > If you say
> > a) define a U-Boot entry ABI and providing a firmware-to-firmware
> information passing facility which would be part of all firmware ABIs (as
> the projects decide to define their own ABI) it looks good.
> > but If you say
>
> It is an ABI to be adopted by U-Boot but also other firmware. For
> example, if TF-A calls U-Boot it should use standard passage. If
> U-Boot calls TF-A or Optee it should use standard passage.
>
> > b) define a standard entry scheme (register map, processor state, MMU
> state, SMMU state, GIC state...) that does not look realistic.
>
> No I don't mean that. This data structure could be used in any state,
> so long as the two registers are set correctly.
>
> > I think you mean a) but just want to be sure.
>
> Yes I think so.
>
> >>
> >> Re the registers, do you think we need 5?
> >>
>
> I don't :-)
>
> >> >
> >> > Thinking entry ABI, here is what I observed on Arm:
> >> >
> >> > Linux has two entry ABIs:
> >> > - plain: x0 = dtb;
> >> >           command line = dtb:/chosen/bootargs; initrd =
> dtb:/chosen/linux,initrd-*
> >> > - EFI: x0=handle, x1=systemtable, x30=return address;
> >> >            dtb = EFI_UUID config table; initrd =
> efi:<loadfile2(INITRD vendor media UUID); command line = efi:
> image_protocol::load_options
> >> >
> >> > U-Boot (proper) has plenty of schemes:
> >> > - dtb is passed as either x0, x1, fixed memory area (Qemu which is
> bad in itself), or other registers
> >> > - additional information passing: board specific register scheme, SMC
> calls
> >> > - U-Boot for RPI boards implement a Linux shaped entry ABI to be
> launched by Videocore firmware
> >> >
> >> > Based on all the above, I would tend to think that RPI scheme is a
> good idea but also
> >> > shall not prevent additional schemes for the boards.
> >>
> >> I was not actually considering Linux since I believe/assume its entry
> >> scheme is fixed and not up for discussion.
> >>
> >> I also did not think about the EFI case. As I understand it we cannot
> >> touch it as it is used by UEFI today. Maybe it is even in the
> >> standard?
> >
> > It is in the spec and we are making it evolve, or its understanding
> evolve (jurisprudence) for instance on initrd standard handling.
>
> Well perhaps we could merge it with standard passage. But EFI is not
> going to want to use a bloblist, it will want to use a HOB.
>
> >>
> >>
> >> Really I am hoping we can start afresh...?
> >>
> >> >
> >> > What about a U-Boot Arm entry ABI like:
> >> > - plain: x0=dtb, x1=<Passage defined>, x2-x5 = <reserved>, other
> registers are per platform, SMC calls allowed too
> >>
> >> Hmm we don't actually need the dtb as it is available in the bloblist.
> >
> > If you don't have x0=dtb, then you will not be able to use U-Boot on
> RPI4.
> > Unless you want to redo everything the RPI firmware is doing.
>
> That's right, RPI cannot support standard passage. It is not
> open-source firmware so it isn't really relevant to this discussion.
> It will just do what it does and have limited functionality, with
> work-arounds to deal with the pain, as one might expect.
>
> So you are seeing two "all-or-nothing" options:
<specific>: U-Boot entry is board specific as it is today
<purepassage>: A new form where the only parameter is a head of bloblist,
one of those blobs contain a DT
 You propose to mandate a DT for all boards make sense in that environment.
For RPI4, you just ignore everything the prior boot loader does because it
is not <passage> compliant.

This reinforces my opposition to the mandatory DT proposal.

a third option is I think way more attractive:
<optpassage>: shaped after the architecture Linux entry (ie. first
parameter is dtb) [+ passage head (i.e. second parameter is pointer to
passage head)]

This way, you make U-Boot entry clean in RPI4, Apple M1, Qemu, SystemReady
contexts
and get a well deserved standardized information passing between prior
loaders and U-Boot.

The three options are possible though, you could select a U-Boot entry
CONFIG option for:
<specific>
<optpassage>
<purepassage>

But despite it would be technically feasible, I don't think it is goes in
the right direction.

>>
> >> But I added an offset to it as a convenience.
> >>
> >> > - EFI: x0=handle, x1=systemtable, x30=return address;  (when U-Boot
> is launched as an EFI app)
> >> >        dtb = EFI_UUID config table, + Passage = Passage UUID config
> table
> >>
> >> I don't understand the last line. Where is the passage info /
> >> bloblist? Do you mean it goes in the HOB list with a UUID? I suppose
> >> that is the most EFI-compatible way.
> >
> > The Passage config table  could just contain the "head" of the
> bloblist/Passage information.
>
> If UEFI wants to deal with standard passage, that is...
>
> >>
> >>
> >> What do you think about the idea of using an offset into the bloblist
> >> for the dtb?
> >
> > It is possible but as I said, failing to mimic Linux entry ABI would
> miss the opportunity to just boot without changes on RPI4.
>
> See above. Broadcom could look at open-sourcing their bootloader if they
> wish.
>
> >>
> >> Also, can we make the standard passage ABI a build-time
> >> option, so it is deterministic?
> >>
> > Looks good. I would look into stating that for SystemReady we would
> advise to use that option and make it standard for Trusted Substrate
> (Linaro recipes that we upstreaming to make SystemReady compliance easy and
> consistent across platforms).
>
> OK. I mean that if the option is enabled, then standard passage must
> be provided / emitted or things won't work. If the option is disabled,
> then standard passage is not used. In other words, we are looking for
> magic values in registers, etc, just enabling/disabling it at
> build-time.
>
> >>
> >> >
> >> > We could further leverage Passage to pass Operating Systems
> parameters that could be removed from device tree (migration of /chosen to
> Passage). Memory inventory would still be in DT but allocations for CMA or
> GPUs would be in Passage. This idea is to reach a point where  device tree
> is a "pristine" hardware description.
> >>
> >> I'm worried about this becoming a substitute for devicetree. Really my
> >> intent is to provide a way to pass simple info, whereas what you talk
> >> about there seems like something that should be DT, just that it might
> >> need suitable bindings.
> >>
> > I see your point and I agree It should not be a substitute.
> > here is an expanded version of what I had in mind when I wrote those
> lines.
> > cma, initrd and other Linux kernel parameters can be conveyed either
> through command line or DT.
> > When using the non UEFI Linux entry ABI, you need to use the DT to pass
> those parameters.
> > When using the UEFI Linux entry ABI, you *can* (not must) use the
> command line to pass all information, leaving the DT passed to the OS
> without any /chosen.
> > When introducing Passage, I was wondering if we could pass command line
> to Linux and, same as UEFI, leave the DT free from /chosen.
> > I am not sure it is a good goal though. I may be too pushing for a DT
> free from parameters.
>
> We could. Are there benefits to that?
>
> I doubt we would pass the standard passage to Linux as a bloblist. I
> imagine something like this. The bloblist sits in memory with some
> things in it, including a devicetree, perhaps an SMBIOS table and a
> TPM log. But when U-Boot calls Linux it puts the address/size of those
> individual things in the devicetree. They don't move and are still
> contiguous in memory, but the bloblist around them is forgotten. Linux
> doesn't know that the three separate things it is picking up are
> actually part of a bloblist structure, since it doesn't care about
> that. Even a console log could work the same way. That way we don't
> end up trying to teach Linux about bloblist when it already has a
> perfectly good means to accept these items.
>
> For ACPI I see things a similar way. The ACPI tables can point to
> things that *happen* to be in a bloblist, but without any knowledge of
> that needed in Linux, grub, etc.
>
> >>
> >> As you know I have more expansive views about what should be in DT.
> >
> > I think both of us are huge supporters of DT format and self describing
> capabilities.
> > I am inclined to put rules into what fits into what lands in the DT that
> is passed to the OS.
> > I am a fan of having DT used more in ad-hoc files.
>
> Me too.
>
> >>
> >> >
> >> > Cheers
> >> >
> >> > PS: as Ilias mentions, this patch set contains bug fixes, non
> immediately related additional functions (DM stats). It would be great to
> carve those out to fast path them and keep this one with the very core of
> your idea.
> >>
> >> The DM stats is used in 'passage: Report the devicetree source'. I
> >> know it is sideways but I think it is better to make the output line
> >> more useful than just reporting the devicetree source.
> >>
> > I believe the DM stats has merits in its own. You could upstream this
> independently and then Passage would be yet another "customer" of the
> feature.
>
> I could, but it would just be a debug feature so people might not
> think it worth the code space. With the devicetree source it is more
> compelling.
>
> >>
> >> The first patch is indeed unrelated. I will pick it up so we can drop
> >> it for the next rev.
> >>
> [..]
>
> Regards,
> Simon
>


-- 
François-Frédéric Ozog | *Director Business Development*
T: +33.67221.6485
francois.ozog@linaro.org | Skype: ffozog

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 00/31] passage: Define a standard for firmware data flow
@ 2021-11-05  8:26           ` François Ozog
  0 siblings, 0 replies; 77+ messages in thread
From: François Ozog @ 2021-11-05  8:26 UTC (permalink / raw)
  To: Simon Glass
  Cc: Marek Vasut, Tom Rini, Albert Aribaud, Masahiro Yamada,
	Heinrich Schuchardt, Bill Mills, Ilias Apalodimas,
	QEMU Developers, U-Boot Mailing List, Jerry Van Baren, Bin Meng,
	Pavel Herrmann

[-- Attachment #1: Type: text/plain, Size: 10830 bytes --]

On Fri, 5 Nov 2021 at 03:02, Simon Glass <sjg@chromium.org> wrote:

> Hi François,
>
> On Tue, 2 Nov 2021 at 10:03, François Ozog <francois.ozog@linaro.org>
> wrote:
> >
> > Hi Simon,
> >
> > On Tue, 2 Nov 2021 at 15:59, Simon Glass <sjg@chromium.org> wrote:
> >>
> >> Hi François,
> >>
> >> On Mon, 1 Nov 2021 at 02:53, François Ozog <francois.ozog@linaro.org>
> wrote:
> >> >
> >> > Hi Simon,
> >> >
> >> > this seems a great endeavor. I'd like to better understand the scope
> of it.
> >> >
> >> > Is it to be used as part of what could become a U-Boot entry ABI
> scheme? By that I mean giving some fixed aspects
> >> > to U-Boot entry while letting boards to have flexibility (say for
> instance that the first 5 architecture ABI
> >> > parameter registers are reserved for U-Boot), and the Passage is
> about specifying either those reserved registers
> >> > or one of them?
> >>
> >> The goal is to provide a standard entry scheme for all firmware
> >> binaries. Whether it achieves that (or can with some mods) is up for
> >> discussion.
> >>
> > If you say
> > a) define a U-Boot entry ABI and providing a firmware-to-firmware
> information passing facility which would be part of all firmware ABIs (as
> the projects decide to define their own ABI) it looks good.
> > but If you say
>
> It is an ABI to be adopted by U-Boot but also other firmware. For
> example, if TF-A calls U-Boot it should use standard passage. If
> U-Boot calls TF-A or Optee it should use standard passage.
>
> > b) define a standard entry scheme (register map, processor state, MMU
> state, SMMU state, GIC state...) that does not look realistic.
>
> No I don't mean that. This data structure could be used in any state,
> so long as the two registers are set correctly.
>
> > I think you mean a) but just want to be sure.
>
> Yes I think so.
>
> >>
> >> Re the registers, do you think we need 5?
> >>
>
> I don't :-)
>
> >> >
> >> > Thinking entry ABI, here is what I observed on Arm:
> >> >
> >> > Linux has two entry ABIs:
> >> > - plain: x0 = dtb;
> >> >           command line = dtb:/chosen/bootargs; initrd =
> dtb:/chosen/linux,initrd-*
> >> > - EFI: x0=handle, x1=systemtable, x30=return address;
> >> >            dtb = EFI_UUID config table; initrd =
> efi:<loadfile2(INITRD vendor media UUID); command line = efi:
> image_protocol::load_options
> >> >
> >> > U-Boot (proper) has plenty of schemes:
> >> > - dtb is passed as either x0, x1, fixed memory area (Qemu which is
> bad in itself), or other registers
> >> > - additional information passing: board specific register scheme, SMC
> calls
> >> > - U-Boot for RPI boards implement a Linux shaped entry ABI to be
> launched by Videocore firmware
> >> >
> >> > Based on all the above, I would tend to think that RPI scheme is a
> good idea but also
> >> > shall not prevent additional schemes for the boards.
> >>
> >> I was not actually considering Linux since I believe/assume its entry
> >> scheme is fixed and not up for discussion.
> >>
> >> I also did not think about the EFI case. As I understand it we cannot
> >> touch it as it is used by UEFI today. Maybe it is even in the
> >> standard?
> >
> > It is in the spec and we are making it evolve, or its understanding
> evolve (jurisprudence) for instance on initrd standard handling.
>
> Well perhaps we could merge it with standard passage. But EFI is not
> going to want to use a bloblist, it will want to use a HOB.
>
> >>
> >>
> >> Really I am hoping we can start afresh...?
> >>
> >> >
> >> > What about a U-Boot Arm entry ABI like:
> >> > - plain: x0=dtb, x1=<Passage defined>, x2-x5 = <reserved>, other
> registers are per platform, SMC calls allowed too
> >>
> >> Hmm we don't actually need the dtb as it is available in the bloblist.
> >
> > If you don't have x0=dtb, then you will not be able to use U-Boot on
> RPI4.
> > Unless you want to redo everything the RPI firmware is doing.
>
> That's right, RPI cannot support standard passage. It is not
> open-source firmware so it isn't really relevant to this discussion.
> It will just do what it does and have limited functionality, with
> work-arounds to deal with the pain, as one might expect.
>
> So you are seeing two "all-or-nothing" options:
<specific>: U-Boot entry is board specific as it is today
<purepassage>: A new form where the only parameter is a head of bloblist,
one of those blobs contain a DT
 You propose to mandate a DT for all boards make sense in that environment.
For RPI4, you just ignore everything the prior boot loader does because it
is not <passage> compliant.

This reinforces my opposition to the mandatory DT proposal.

a third option is I think way more attractive:
<optpassage>: shaped after the architecture Linux entry (ie. first
parameter is dtb) [+ passage head (i.e. second parameter is pointer to
passage head)]

This way, you make U-Boot entry clean in RPI4, Apple M1, Qemu, SystemReady
contexts
and get a well deserved standardized information passing between prior
loaders and U-Boot.

The three options are possible though, you could select a U-Boot entry
CONFIG option for:
<specific>
<optpassage>
<purepassage>

But despite it would be technically feasible, I don't think it is goes in
the right direction.

>>
> >> But I added an offset to it as a convenience.
> >>
> >> > - EFI: x0=handle, x1=systemtable, x30=return address;  (when U-Boot
> is launched as an EFI app)
> >> >        dtb = EFI_UUID config table, + Passage = Passage UUID config
> table
> >>
> >> I don't understand the last line. Where is the passage info /
> >> bloblist? Do you mean it goes in the HOB list with a UUID? I suppose
> >> that is the most EFI-compatible way.
> >
> > The Passage config table  could just contain the "head" of the
> bloblist/Passage information.
>
> If UEFI wants to deal with standard passage, that is...
>
> >>
> >>
> >> What do you think about the idea of using an offset into the bloblist
> >> for the dtb?
> >
> > It is possible but as I said, failing to mimic Linux entry ABI would
> miss the opportunity to just boot without changes on RPI4.
>
> See above. Broadcom could look at open-sourcing their bootloader if they
> wish.
>
> >>
> >> Also, can we make the standard passage ABI a build-time
> >> option, so it is deterministic?
> >>
> > Looks good. I would look into stating that for SystemReady we would
> advise to use that option and make it standard for Trusted Substrate
> (Linaro recipes that we upstreaming to make SystemReady compliance easy and
> consistent across platforms).
>
> OK. I mean that if the option is enabled, then standard passage must
> be provided / emitted or things won't work. If the option is disabled,
> then standard passage is not used. In other words, we are looking for
> magic values in registers, etc, just enabling/disabling it at
> build-time.
>
> >>
> >> >
> >> > We could further leverage Passage to pass Operating Systems
> parameters that could be removed from device tree (migration of /chosen to
> Passage). Memory inventory would still be in DT but allocations for CMA or
> GPUs would be in Passage. This idea is to reach a point where  device tree
> is a "pristine" hardware description.
> >>
> >> I'm worried about this becoming a substitute for devicetree. Really my
> >> intent is to provide a way to pass simple info, whereas what you talk
> >> about there seems like something that should be DT, just that it might
> >> need suitable bindings.
> >>
> > I see your point and I agree It should not be a substitute.
> > here is an expanded version of what I had in mind when I wrote those
> lines.
> > cma, initrd and other Linux kernel parameters can be conveyed either
> through command line or DT.
> > When using the non UEFI Linux entry ABI, you need to use the DT to pass
> those parameters.
> > When using the UEFI Linux entry ABI, you *can* (not must) use the
> command line to pass all information, leaving the DT passed to the OS
> without any /chosen.
> > When introducing Passage, I was wondering if we could pass command line
> to Linux and, same as UEFI, leave the DT free from /chosen.
> > I am not sure it is a good goal though. I may be too pushing for a DT
> free from parameters.
>
> We could. Are there benefits to that?
>
> I doubt we would pass the standard passage to Linux as a bloblist. I
> imagine something like this. The bloblist sits in memory with some
> things in it, including a devicetree, perhaps an SMBIOS table and a
> TPM log. But when U-Boot calls Linux it puts the address/size of those
> individual things in the devicetree. They don't move and are still
> contiguous in memory, but the bloblist around them is forgotten. Linux
> doesn't know that the three separate things it is picking up are
> actually part of a bloblist structure, since it doesn't care about
> that. Even a console log could work the same way. That way we don't
> end up trying to teach Linux about bloblist when it already has a
> perfectly good means to accept these items.
>
> For ACPI I see things a similar way. The ACPI tables can point to
> things that *happen* to be in a bloblist, but without any knowledge of
> that needed in Linux, grub, etc.
>
> >>
> >> As you know I have more expansive views about what should be in DT.
> >
> > I think both of us are huge supporters of DT format and self describing
> capabilities.
> > I am inclined to put rules into what fits into what lands in the DT that
> is passed to the OS.
> > I am a fan of having DT used more in ad-hoc files.
>
> Me too.
>
> >>
> >> >
> >> > Cheers
> >> >
> >> > PS: as Ilias mentions, this patch set contains bug fixes, non
> immediately related additional functions (DM stats). It would be great to
> carve those out to fast path them and keep this one with the very core of
> your idea.
> >>
> >> The DM stats is used in 'passage: Report the devicetree source'. I
> >> know it is sideways but I think it is better to make the output line
> >> more useful than just reporting the devicetree source.
> >>
> > I believe the DM stats has merits in its own. You could upstream this
> independently and then Passage would be yet another "customer" of the
> feature.
>
> I could, but it would just be a debug feature so people might not
> think it worth the code space. With the devicetree source it is more
> compelling.
>
> >>
> >> The first patch is indeed unrelated. I will pick it up so we can drop
> >> it for the next rev.
> >>
> [..]
>
> Regards,
> Simon
>


-- 
François-Frédéric Ozog | *Director Business Development*
T: +33.67221.6485
francois.ozog@linaro.org | Skype: ffozog

[-- Attachment #2: Type: text/html, Size: 14370 bytes --]

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 00/31] passage: Define a standard for firmware data flow
  2021-11-05  8:26           ` François Ozog
@ 2021-11-05 16:12             ` Simon Glass
  -1 siblings, 0 replies; 77+ messages in thread
From: Simon Glass @ 2021-11-05 16:12 UTC (permalink / raw)
  To: François Ozog
  Cc: U-Boot Mailing List, Tom Rini, Bin Meng, Ilias Apalodimas,
	Bill Mills, Heinrich Schuchardt, Albert Aribaud, Jerry Van Baren,
	Marek Vasut, Masahiro Yamada, Pavel Herrmann, QEMU Developers

Hi François,

On Fri, 5 Nov 2021 at 02:27, François Ozog <francois.ozog@linaro.org> wrote:
>
>
>
> On Fri, 5 Nov 2021 at 03:02, Simon Glass <sjg@chromium.org> wrote:
>>
>> Hi François,
>>
>> On Tue, 2 Nov 2021 at 10:03, François Ozog <francois.ozog@linaro.org> wrote:
>> >
>> > Hi Simon,
>> >
>> > On Tue, 2 Nov 2021 at 15:59, Simon Glass <sjg@chromium.org> wrote:
>> >>
>> >> Hi François,
>> >>
>> >> On Mon, 1 Nov 2021 at 02:53, François Ozog <francois.ozog@linaro.org> wrote:
>> >> >
>> >> > Hi Simon,
>> >> >
>> >> > this seems a great endeavor. I'd like to better understand the scope of it.
>> >> >
>> >> > Is it to be used as part of what could become a U-Boot entry ABI scheme? By that I mean giving some fixed aspects
>> >> > to U-Boot entry while letting boards to have flexibility (say for instance that the first 5 architecture ABI
>> >> > parameter registers are reserved for U-Boot), and the Passage is about specifying either those reserved registers
>> >> > or one of them?
>> >>
>> >> The goal is to provide a standard entry scheme for all firmware
>> >> binaries. Whether it achieves that (or can with some mods) is up for
>> >> discussion.
>> >>
>> > If you say
>> > a) define a U-Boot entry ABI and providing a firmware-to-firmware information passing facility which would be part of all firmware ABIs (as the projects decide to define their own ABI) it looks good.
>> > but If you say
>>
>> It is an ABI to be adopted by U-Boot but also other firmware. For
>> example, if TF-A calls U-Boot it should use standard passage. If
>> U-Boot calls TF-A or Optee it should use standard passage.
>>
>> > b) define a standard entry scheme (register map, processor state, MMU state, SMMU state, GIC state...) that does not look realistic.
>>
>> No I don't mean that. This data structure could be used in any state,
>> so long as the two registers are set correctly.
>>
>> > I think you mean a) but just want to be sure.
>>
>> Yes I think so.
>>
>> >>
>> >> Re the registers, do you think we need 5?
>> >>
>>
>> I don't :-)
>>
>> >> >
>> >> > Thinking entry ABI, here is what I observed on Arm:
>> >> >
>> >> > Linux has two entry ABIs:
>> >> > - plain: x0 = dtb;
>> >> >           command line = dtb:/chosen/bootargs; initrd = dtb:/chosen/linux,initrd-*
>> >> > - EFI: x0=handle, x1=systemtable, x30=return address;
>> >> >            dtb = EFI_UUID config table; initrd = efi:<loadfile2(INITRD vendor media UUID); command line = efi: image_protocol::load_options
>> >> >
>> >> > U-Boot (proper) has plenty of schemes:
>> >> > - dtb is passed as either x0, x1, fixed memory area (Qemu which is bad in itself), or other registers
>> >> > - additional information passing: board specific register scheme, SMC calls
>> >> > - U-Boot for RPI boards implement a Linux shaped entry ABI to be launched by Videocore firmware
>> >> >
>> >> > Based on all the above, I would tend to think that RPI scheme is a good idea but also
>> >> > shall not prevent additional schemes for the boards.
>> >>
>> >> I was not actually considering Linux since I believe/assume its entry
>> >> scheme is fixed and not up for discussion.
>> >>
>> >> I also did not think about the EFI case. As I understand it we cannot
>> >> touch it as it is used by UEFI today. Maybe it is even in the
>> >> standard?
>> >
>> > It is in the spec and we are making it evolve, or its understanding evolve (jurisprudence) for instance on initrd standard handling.
>>
>> Well perhaps we could merge it with standard passage. But EFI is not
>> going to want to use a bloblist, it will want to use a HOB.
>>
>> >>
>> >>
>> >> Really I am hoping we can start afresh...?
>> >>
>> >> >
>> >> > What about a U-Boot Arm entry ABI like:
>> >> > - plain: x0=dtb, x1=<Passage defined>, x2-x5 = <reserved>, other registers are per platform, SMC calls allowed too
>> >>
>> >> Hmm we don't actually need the dtb as it is available in the bloblist.
>> >
>> > If you don't have x0=dtb, then you will not be able to use U-Boot on RPI4.
>> > Unless you want to redo everything the RPI firmware is doing.
>>
>> That's right, RPI cannot support standard passage. It is not
>> open-source firmware so it isn't really relevant to this discussion.
>> It will just do what it does and have limited functionality, with
>> work-arounds to deal with the pain, as one might expect.
>>
> So you are seeing two "all-or-nothing" options:
> <specific>: U-Boot entry is board specific as it is today
> <purepassage>: A new form where the only parameter is a head of bloblist, one of those blobs contain a DT
>  You propose to mandate a DT for all boards make sense in that environment.
> For RPI4, you just ignore everything the prior boot loader does because it is not <passage> compliant.

It's not that. It's just that it is closed-source, so not relevant to
the discussion here. They could open-source it and then we could
consider it, but it has been closed-source for years now, so why would
we think that would happen?

>
> This reinforces my opposition to the mandatory DT proposal.
>
> a third option is I think way more attractive:
> <optpassage>: shaped after the architecture Linux entry (ie. first parameter is dtb) [+ passage head (i.e. second parameter is pointer to passage head)]
>
> This way, you make U-Boot entry clean in RPI4, Apple M1, Qemu, SystemReady contexts
> and get a well deserved standardized information passing between prior loaders and U-Boot.
>
> The three options are possible though, you could select a U-Boot entry CONFIG option for:
> <specific>
> <optpassage>
> <purepassage>
>
> But despite it would be technically feasible, I don't think it is goes in the right direction.

OK. Do you think we need a separate devicetree pointer, rather than
forcing it to be inside the created bloblist?

I'd like to understand what problem you are solving with this. I am
trying to figure out a firmware-to-firmware mini-ABI (just a few
register values) that can be used in open-source projects. The ABI is
not intended to be used with Linux (I am unsure of the benefit it
would give and whether it is feasible to change the current one).

You are talking about the Linux entry mechanism. What relevance does
that have for firmware?

I understand that some projects already implement the Linux mechanism,
but that is because they expect to jump straight to Linux, not have
U-Boot in the path. So IMO standard passage offers no benefit to them.

To address them in turn:
- rpi4 - closed source, who cares?
- Apple M1 - we could probably expand it to pass a bloblist, but it
would be confusing unless we share registers, as you suggest
- Qemu - I already tried to update that and got pushback...do you
really think those guys are going to want to add a bloblist? So again,
who cares?
- SystemReady - not sure what this means in practice, but it would be
good if SystemReady could use standard passage

So let's say we have an optional standard-passage thing and we use
registers such that it is similar to Linux and EFI and just expands on
them.

The first problem is that Linux and EFI seem to be completely
incompatible. Can that be changed, perhaps on the EFI side? If not,
we need two separate protocols.

I'll ignore EFI for now. So we might have:

r0 = 0
r1 = machine number (0?)
r2 = dtb pointer
r3 = bloblist pointer, 0 if missing
r14 = return address

or

x0 = dtb
x1 = bloblist pointer, 0 if missing
x30 = return address

For EFI, we could add a blob to the bloblist containing the system
table and handle, perhaps? Otherwise:

x2 - efi handle
x3 - system table

Is that along the lines of what you are thinking?

But still, please respond above so I can understand what problem you
are worried about.

Regards,
Simon


>
>> >>
>> >> But I added an offset to it as a convenience.
>> >>
>> >> > - EFI: x0=handle, x1=systemtable, x30=return address;  (when U-Boot is launched as an EFI app)
>> >> >        dtb = EFI_UUID config table, + Passage = Passage UUID config table
>> >>
>> >> I don't understand the last line. Where is the passage info /
>> >> bloblist? Do you mean it goes in the HOB list with a UUID? I suppose
>> >> that is the most EFI-compatible way.
>> >
>> > The Passage config table  could just contain the "head" of the bloblist/Passage information.
>>
>> If UEFI wants to deal with standard passage, that is...
>>
>> >>
>> >>
>> >> What do you think about the idea of using an offset into the bloblist
>> >> for the dtb?
>> >
>> > It is possible but as I said, failing to mimic Linux entry ABI would miss the opportunity to just boot without changes on RPI4.
>>
>> See above. Broadcom could look at open-sourcing their bootloader if they wish.
>>
>> >>
>> >> Also, can we make the standard passage ABI a build-time
>> >> option, so it is deterministic?
>> >>
>> > Looks good. I would look into stating that for SystemReady we would advise to use that option and make it standard for Trusted Substrate (Linaro recipes that we upstreaming to make SystemReady compliance easy and consistent across platforms).
>>
>> OK. I mean that if the option is enabled, then standard passage must
>> be provided / emitted or things won't work. If the option is disabled,
>> then standard passage is not used. In other words, we are looking for
>> magic values in registers, etc, just enabling/disabling it at
>> build-time.
>>
>> >>
>> >> >
>> >> > We could further leverage Passage to pass Operating Systems parameters that could be removed from device tree (migration of /chosen to Passage). Memory inventory would still be in DT but allocations for CMA or GPUs would be in Passage. This idea is to reach a point where  device tree is a "pristine" hardware description.
>> >>
>> >> I'm worried about this becoming a substitute for devicetree. Really my
>> >> intent is to provide a way to pass simple info, whereas what you talk
>> >> about there seems like something that should be DT, just that it might
>> >> need suitable bindings.
>> >>
>> > I see your point and I agree It should not be a substitute.
>> > here is an expanded version of what I had in mind when I wrote those lines.
>> > cma, initrd and other Linux kernel parameters can be conveyed either through command line or DT.
>> > When using the non UEFI Linux entry ABI, you need to use the DT to pass those parameters.
>> > When using the UEFI Linux entry ABI, you *can* (not must) use the command line to pass all information, leaving the DT passed to the OS without any /chosen.
>> > When introducing Passage, I was wondering if we could pass command line to Linux and, same as UEFI, leave the DT free from /chosen.
>> > I am not sure it is a good goal though. I may be too pushing for a DT free from parameters.
>>
>> We could. Are there benefits to that?
>>
>> I doubt we would pass the standard passage to Linux as a bloblist. I
>> imagine something like this. The bloblist sits in memory with some
>> things in it, including a devicetree, perhaps an SMBIOS table and a
>> TPM log. But when U-Boot calls Linux it puts the address/size of those
>> individual things in the devicetree. They don't move and are still
>> contiguous in memory, but the bloblist around them is forgotten. Linux
>> doesn't know that the three separate things it is picking up are
>> actually part of a bloblist structure, since it doesn't care about
>> that. Even a console log could work the same way. That way we don't
>> end up trying to teach Linux about bloblist when it already has a
>> perfectly good means to accept these items.
>>
>> For ACPI I see things a similar way. The ACPI tables can point to
>> things that *happen* to be in a bloblist, but without any knowledge of
>> that needed in Linux, grub, etc.
>>
>> >>
>> >> As you know I have more expansive views about what should be in DT.
>> >
>> > I think both of us are huge supporters of DT format and self describing capabilities.
>> > I am inclined to put rules into what fits into what lands in the DT that is passed to the OS.
>> > I am a fan of having DT used more in ad-hoc files.
>>
>> Me too.
>>
>> >>
>> >> >
>> >> > Cheers
>> >> >
>> >> > PS: as Ilias mentions, this patch set contains bug fixes, non immediately related additional functions (DM stats). It would be great to carve those out to fast path them and keep this one with the very core of your idea.
>> >>
>> >> The DM stats is used in 'passage: Report the devicetree source'. I
>> >> know it is sideways but I think it is better to make the output line
>> >> more useful than just reporting the devicetree source.
>> >>
>> > I believe the DM stats has merits in its own. You could upstream this independently and then Passage would be yet another "customer" of the feature.
>>
>> I could, but it would just be a debug feature so people might not
>> think it worth the code space. With the devicetree source it is more
>> compelling.
>>
>> >>
>> >> The first patch is indeed unrelated. I will pick it up so we can drop
>> >> it for the next rev.
>> >>
>> [..]
>>
>> Regards,
>> Simon
>
>
>
> --
> François-Frédéric Ozog | Director Business Development
> T: +33.67221.6485
> francois.ozog@linaro.org | Skype: ffozog
>

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 00/31] passage: Define a standard for firmware data flow
@ 2021-11-05 16:12             ` Simon Glass
  0 siblings, 0 replies; 77+ messages in thread
From: Simon Glass @ 2021-11-05 16:12 UTC (permalink / raw)
  To: François Ozog
  Cc: Marek Vasut, Tom Rini, Albert Aribaud, Masahiro Yamada,
	Heinrich Schuchardt, Bill Mills, Ilias Apalodimas,
	QEMU Developers, U-Boot Mailing List, Jerry Van Baren, Bin Meng,
	Pavel Herrmann

Hi François,

On Fri, 5 Nov 2021 at 02:27, François Ozog <francois.ozog@linaro.org> wrote:
>
>
>
> On Fri, 5 Nov 2021 at 03:02, Simon Glass <sjg@chromium.org> wrote:
>>
>> Hi François,
>>
>> On Tue, 2 Nov 2021 at 10:03, François Ozog <francois.ozog@linaro.org> wrote:
>> >
>> > Hi Simon,
>> >
>> > On Tue, 2 Nov 2021 at 15:59, Simon Glass <sjg@chromium.org> wrote:
>> >>
>> >> Hi François,
>> >>
>> >> On Mon, 1 Nov 2021 at 02:53, François Ozog <francois.ozog@linaro.org> wrote:
>> >> >
>> >> > Hi Simon,
>> >> >
>> >> > this seems a great endeavor. I'd like to better understand the scope of it.
>> >> >
>> >> > Is it to be used as part of what could become a U-Boot entry ABI scheme? By that I mean giving some fixed aspects
>> >> > to U-Boot entry while letting boards to have flexibility (say for instance that the first 5 architecture ABI
>> >> > parameter registers are reserved for U-Boot), and the Passage is about specifying either those reserved registers
>> >> > or one of them?
>> >>
>> >> The goal is to provide a standard entry scheme for all firmware
>> >> binaries. Whether it achieves that (or can with some mods) is up for
>> >> discussion.
>> >>
>> > If you say
>> > a) define a U-Boot entry ABI and providing a firmware-to-firmware information passing facility which would be part of all firmware ABIs (as the projects decide to define their own ABI) it looks good.
>> > but If you say
>>
>> It is an ABI to be adopted by U-Boot but also other firmware. For
>> example, if TF-A calls U-Boot it should use standard passage. If
>> U-Boot calls TF-A or Optee it should use standard passage.
>>
>> > b) define a standard entry scheme (register map, processor state, MMU state, SMMU state, GIC state...) that does not look realistic.
>>
>> No I don't mean that. This data structure could be used in any state,
>> so long as the two registers are set correctly.
>>
>> > I think you mean a) but just want to be sure.
>>
>> Yes I think so.
>>
>> >>
>> >> Re the registers, do you think we need 5?
>> >>
>>
>> I don't :-)
>>
>> >> >
>> >> > Thinking entry ABI, here is what I observed on Arm:
>> >> >
>> >> > Linux has two entry ABIs:
>> >> > - plain: x0 = dtb;
>> >> >           command line = dtb:/chosen/bootargs; initrd = dtb:/chosen/linux,initrd-*
>> >> > - EFI: x0=handle, x1=systemtable, x30=return address;
>> >> >            dtb = EFI_UUID config table; initrd = efi:<loadfile2(INITRD vendor media UUID); command line = efi: image_protocol::load_options
>> >> >
>> >> > U-Boot (proper) has plenty of schemes:
>> >> > - dtb is passed as either x0, x1, fixed memory area (Qemu which is bad in itself), or other registers
>> >> > - additional information passing: board specific register scheme, SMC calls
>> >> > - U-Boot for RPI boards implement a Linux shaped entry ABI to be launched by Videocore firmware
>> >> >
>> >> > Based on all the above, I would tend to think that RPI scheme is a good idea but also
>> >> > shall not prevent additional schemes for the boards.
>> >>
>> >> I was not actually considering Linux since I believe/assume its entry
>> >> scheme is fixed and not up for discussion.
>> >>
>> >> I also did not think about the EFI case. As I understand it we cannot
>> >> touch it as it is used by UEFI today. Maybe it is even in the
>> >> standard?
>> >
>> > It is in the spec and we are making it evolve, or its understanding evolve (jurisprudence) for instance on initrd standard handling.
>>
>> Well perhaps we could merge it with standard passage. But EFI is not
>> going to want to use a bloblist, it will want to use a HOB.
>>
>> >>
>> >>
>> >> Really I am hoping we can start afresh...?
>> >>
>> >> >
>> >> > What about a U-Boot Arm entry ABI like:
>> >> > - plain: x0=dtb, x1=<Passage defined>, x2-x5 = <reserved>, other registers are per platform, SMC calls allowed too
>> >>
>> >> Hmm we don't actually need the dtb as it is available in the bloblist.
>> >
>> > If you don't have x0=dtb, then you will not be able to use U-Boot on RPI4.
>> > Unless you want to redo everything the RPI firmware is doing.
>>
>> That's right, RPI cannot support standard passage. It is not
>> open-source firmware so it isn't really relevant to this discussion.
>> It will just do what it does and have limited functionality, with
>> work-arounds to deal with the pain, as one might expect.
>>
> So you are seeing two "all-or-nothing" options:
> <specific>: U-Boot entry is board specific as it is today
> <purepassage>: A new form where the only parameter is a head of bloblist, one of those blobs contain a DT
>  You propose to mandate a DT for all boards make sense in that environment.
> For RPI4, you just ignore everything the prior boot loader does because it is not <passage> compliant.

It's not that. It's just that it is closed-source, so not relevant to
the discussion here. They could open-source it and then we could
consider it, but it has been closed-source for years now, so why would
we think that would happen?

>
> This reinforces my opposition to the mandatory DT proposal.
>
> a third option is I think way more attractive:
> <optpassage>: shaped after the architecture Linux entry (ie. first parameter is dtb) [+ passage head (i.e. second parameter is pointer to passage head)]
>
> This way, you make U-Boot entry clean in RPI4, Apple M1, Qemu, SystemReady contexts
> and get a well deserved standardized information passing between prior loaders and U-Boot.
>
> The three options are possible though, you could select a U-Boot entry CONFIG option for:
> <specific>
> <optpassage>
> <purepassage>
>
> But despite it would be technically feasible, I don't think it is goes in the right direction.

OK. Do you think we need a separate devicetree pointer, rather than
forcing it to be inside the created bloblist?

I'd like to understand what problem you are solving with this. I am
trying to figure out a firmware-to-firmware mini-ABI (just a few
register values) that can be used in open-source projects. The ABI is
not intended to be used with Linux (I am unsure of the benefit it
would give and whether it is feasible to change the current one).

You are talking about the Linux entry mechanism. What relevance does
that have for firmware?

I understand that some projects already implement the Linux mechanism,
but that is because they expect to jump straight to Linux, not have
U-Boot in the path. So IMO standard passage offers no benefit to them.

To address them in turn:
- rpi4 - closed source, who cares?
- Apple M1 - we could probably expand it to pass a bloblist, but it
would be confusing unless we share registers, as you suggest
- Qemu - I already tried to update that and got pushback...do you
really think those guys are going to want to add a bloblist? So again,
who cares?
- SystemReady - not sure what this means in practice, but it would be
good if SystemReady could use standard passage

So let's say we have an optional standard-passage thing and we use
registers such that it is similar to Linux and EFI and just expands on
them.

The first problem is that Linux and EFI seem to be completely
incompatible. Can that be changed, perhaps on the EFI side? If not,
we need two separate protocols.

I'll ignore EFI for now. So we might have:

r0 = 0
r1 = machine number (0?)
r2 = dtb pointer
r3 = bloblist pointer, 0 if missing
r14 = return address

or

x0 = dtb
x1 = bloblist pointer, 0 if missing
x30 = return address

For EFI, we could add a blob to the bloblist containing the system
table and handle, perhaps? Otherwise:

x2 - efi handle
x3 - system table

Is that along the lines of what you are thinking?

But still, please respond above so I can understand what problem you
are worried about.

Regards,
Simon


>
>> >>
>> >> But I added an offset to it as a convenience.
>> >>
>> >> > - EFI: x0=handle, x1=systemtable, x30=return address;  (when U-Boot is launched as an EFI app)
>> >> >        dtb = EFI_UUID config table, + Passage = Passage UUID config table
>> >>
>> >> I don't understand the last line. Where is the passage info /
>> >> bloblist? Do you mean it goes in the HOB list with a UUID? I suppose
>> >> that is the most EFI-compatible way.
>> >
>> > The Passage config table  could just contain the "head" of the bloblist/Passage information.
>>
>> If UEFI wants to deal with standard passage, that is...
>>
>> >>
>> >>
>> >> What do you think about the idea of using an offset into the bloblist
>> >> for the dtb?
>> >
>> > It is possible but as I said, failing to mimic Linux entry ABI would miss the opportunity to just boot without changes on RPI4.
>>
>> See above. Broadcom could look at open-sourcing their bootloader if they wish.
>>
>> >>
>> >> Also, can we make the standard passage ABI a build-time
>> >> option, so it is deterministic?
>> >>
>> > Looks good. I would look into stating that for SystemReady we would advise to use that option and make it standard for Trusted Substrate (Linaro recipes that we upstreaming to make SystemReady compliance easy and consistent across platforms).
>>
>> OK. I mean that if the option is enabled, then standard passage must
>> be provided / emitted or things won't work. If the option is disabled,
>> then standard passage is not used. In other words, we are looking for
>> magic values in registers, etc, just enabling/disabling it at
>> build-time.
>>
>> >>
>> >> >
>> >> > We could further leverage Passage to pass Operating Systems parameters that could be removed from device tree (migration of /chosen to Passage). Memory inventory would still be in DT but allocations for CMA or GPUs would be in Passage. This idea is to reach a point where  device tree is a "pristine" hardware description.
>> >>
>> >> I'm worried about this becoming a substitute for devicetree. Really my
>> >> intent is to provide a way to pass simple info, whereas what you talk
>> >> about there seems like something that should be DT, just that it might
>> >> need suitable bindings.
>> >>
>> > I see your point and I agree It should not be a substitute.
>> > here is an expanded version of what I had in mind when I wrote those lines.
>> > cma, initrd and other Linux kernel parameters can be conveyed either through command line or DT.
>> > When using the non UEFI Linux entry ABI, you need to use the DT to pass those parameters.
>> > When using the UEFI Linux entry ABI, you *can* (not must) use the command line to pass all information, leaving the DT passed to the OS without any /chosen.
>> > When introducing Passage, I was wondering if we could pass command line to Linux and, same as UEFI, leave the DT free from /chosen.
>> > I am not sure it is a good goal though. I may be too pushing for a DT free from parameters.
>>
>> We could. Are there benefits to that?
>>
>> I doubt we would pass the standard passage to Linux as a bloblist. I
>> imagine something like this. The bloblist sits in memory with some
>> things in it, including a devicetree, perhaps an SMBIOS table and a
>> TPM log. But when U-Boot calls Linux it puts the address/size of those
>> individual things in the devicetree. They don't move and are still
>> contiguous in memory, but the bloblist around them is forgotten. Linux
>> doesn't know that the three separate things it is picking up are
>> actually part of a bloblist structure, since it doesn't care about
>> that. Even a console log could work the same way. That way we don't
>> end up trying to teach Linux about bloblist when it already has a
>> perfectly good means to accept these items.
>>
>> For ACPI I see things a similar way. The ACPI tables can point to
>> things that *happen* to be in a bloblist, but without any knowledge of
>> that needed in Linux, grub, etc.
>>
>> >>
>> >> As you know I have more expansive views about what should be in DT.
>> >
>> > I think both of us are huge supporters of DT format and self describing capabilities.
>> > I am inclined to put rules into what fits into what lands in the DT that is passed to the OS.
>> > I am a fan of having DT used more in ad-hoc files.
>>
>> Me too.
>>
>> >>
>> >> >
>> >> > Cheers
>> >> >
>> >> > PS: as Ilias mentions, this patch set contains bug fixes, non immediately related additional functions (DM stats). It would be great to carve those out to fast path them and keep this one with the very core of your idea.
>> >>
>> >> The DM stats is used in 'passage: Report the devicetree source'. I
>> >> know it is sideways but I think it is better to make the output line
>> >> more useful than just reporting the devicetree source.
>> >>
>> > I believe the DM stats has merits in its own. You could upstream this independently and then Passage would be yet another "customer" of the feature.
>>
>> I could, but it would just be a debug feature so people might not
>> think it worth the code space. With the devicetree source it is more
>> compelling.
>>
>> >>
>> >> The first patch is indeed unrelated. I will pick it up so we can drop
>> >> it for the next rev.
>> >>
>> [..]
>>
>> Regards,
>> Simon
>
>
>
> --
> François-Frédéric Ozog | Director Business Development
> T: +33.67221.6485
> francois.ozog@linaro.org | Skype: ffozog
>


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 00/31] passage: Define a standard for firmware data flow
  2021-11-05 16:12             ` Simon Glass
@ 2021-11-05 16:31               ` François Ozog
  -1 siblings, 0 replies; 77+ messages in thread
From: François Ozog @ 2021-11-05 16:31 UTC (permalink / raw)
  To: Simon Glass
  Cc: Albert Aribaud, Bill Mills, Bin Meng, Heinrich Schuchardt,
	Ilias Apalodimas, Jerry Van Baren, Marek Vasut, Masahiro Yamada,
	Pavel Herrmann, QEMU Developers, Tom Rini, U-Boot Mailing List

Hi Simon,

Le ven. 5 nov. 2021 à 17:12, Simon Glass <sjg@chromium.org> a écrit :

> Hi François,
>
> On Fri, 5 Nov 2021 at 02:27, François Ozog <francois.ozog@linaro.org>
> wrote:
> >
> >
> >
> > On Fri, 5 Nov 2021 at 03:02, Simon Glass <sjg@chromium.org> wrote:
> >>
> >> Hi François,
> >>
> >> On Tue, 2 Nov 2021 at 10:03, François Ozog <francois.ozog@linaro.org>
> wrote:
> >> >
> >> > Hi Simon,
> >> >
> >> > On Tue, 2 Nov 2021 at 15:59, Simon Glass <sjg@chromium.org> wrote:
> >> >>
> >> >> Hi François,
> >> >>
> >> >> On Mon, 1 Nov 2021 at 02:53, François Ozog <francois.ozog@linaro.org>
> wrote:
> >> >> >
> >> >> > Hi Simon,
> >> >> >
> >> >> > this seems a great endeavor. I'd like to better understand the
> scope of it.
> >> >> >
> >> >> > Is it to be used as part of what could become a U-Boot entry ABI
> scheme? By that I mean giving some fixed aspects
> >> >> > to U-Boot entry while letting boards to have flexibility (say for
> instance that the first 5 architecture ABI
> >> >> > parameter registers are reserved for U-Boot), and the Passage is
> about specifying either those reserved registers
> >> >> > or one of them?
> >> >>
> >> >> The goal is to provide a standard entry scheme for all firmware
> >> >> binaries. Whether it achieves that (or can with some mods) is up for
> >> >> discussion.
> >> >>
> >> > If you say
> >> > a) define a U-Boot entry ABI and providing a firmware-to-firmware
> information passing facility which would be part of all firmware ABIs (as
> the projects decide to define their own ABI) it looks good.
> >> > but If you say
> >>
> >> It is an ABI to be adopted by U-Boot but also other firmware. For
> >> example, if TF-A calls U-Boot it should use standard passage. If
> >> U-Boot calls TF-A or Optee it should use standard passage.
> >>
> >> > b) define a standard entry scheme (register map, processor state, MMU
> state, SMMU state, GIC state...) that does not look realistic.
> >>
> >> No I don't mean that. This data structure could be used in any state,
> >> so long as the two registers are set correctly.
> >>
> >> > I think you mean a) but just want to be sure.
> >>
> >> Yes I think so.
> >>
> >> >>
> >> >> Re the registers, do you think we need 5?
> >> >>
> >>
> >> I don't :-)
> >>
> >> >> >
> >> >> > Thinking entry ABI, here is what I observed on Arm:
> >> >> >
> >> >> > Linux has two entry ABIs:
> >> >> > - plain: x0 = dtb;
> >> >> >           command line = dtb:/chosen/bootargs; initrd =
> dtb:/chosen/linux,initrd-*
> >> >> > - EFI: x0=handle, x1=systemtable, x30=return address;
> >> >> >            dtb = EFI_UUID config table; initrd =
> efi:<loadfile2(INITRD vendor media UUID); command line = efi:
> image_protocol::load_options
> >> >> >
> >> >> > U-Boot (proper) has plenty of schemes:
> >> >> > - dtb is passed as either x0, x1, fixed memory area (Qemu which is
> bad in itself), or other registers
> >> >> > - additional information passing: board specific register scheme,
> SMC calls
> >> >> > - U-Boot for RPI boards implement a Linux shaped entry ABI to be
> launched by Videocore firmware
> >> >> >
> >> >> > Based on all the above, I would tend to think that RPI scheme is a
> good idea but also
> >> >> > shall not prevent additional schemes for the boards.
> >> >>
> >> >> I was not actually considering Linux since I believe/assume its entry
> >> >> scheme is fixed and not up for discussion.
> >> >>
> >> >> I also did not think about the EFI case. As I understand it we cannot
> >> >> touch it as it is used by UEFI today. Maybe it is even in the
> >> >> standard?
> >> >
> >> > It is in the spec and we are making it evolve, or its understanding
> evolve (jurisprudence) for instance on initrd standard handling.
> >>
> >> Well perhaps we could merge it with standard passage. But EFI is not
> >> going to want to use a bloblist, it will want to use a HOB.
> >>
> >> >>
> >> >>
> >> >> Really I am hoping we can start afresh...?
> >> >>
> >> >> >
> >> >> > What about a U-Boot Arm entry ABI like:
> >> >> > - plain: x0=dtb, x1=<Passage defined>, x2-x5 = <reserved>, other
> registers are per platform, SMC calls allowed too
> >> >>
> >> >> Hmm we don't actually need the dtb as it is available in the
> bloblist.
> >> >
> >> > If you don't have x0=dtb, then you will not be able to use U-Boot on
> RPI4.
> >> > Unless you want to redo everything the RPI firmware is doing.
> >>
> >> That's right, RPI cannot support standard passage. It is not
> >> open-source firmware so it isn't really relevant to this discussion.
> >> It will just do what it does and have limited functionality, with
> >> work-arounds to deal with the pain, as one might expect.
> >>
> > So you are seeing two "all-or-nothing" options:
> > <specific>: U-Boot entry is board specific as it is today
> > <purepassage>: A new form where the only parameter is a head of
> bloblist, one of those blobs contain a DT
> >  You propose to mandate a DT for all boards make sense in that
> environment.
> > For RPI4, you just ignore everything the prior boot loader does because
> it is not <passage> compliant.
>
> It's not that. It's just that it is closed-source, so not relevant to
> the discussion here. They could open-source it and then we could
> consider it, but it has been closed-source for years now, so why would
> we think that would happen?
>
> >
> > This reinforces my opposition to the mandatory DT proposal.
> >
> > a third option is I think way more attractive:
> > <optpassage>: shaped after the architecture Linux entry (ie. first
> parameter is dtb) [+ passage head (i.e. second parameter is pointer to
> passage head)]
> >
> > This way, you make U-Boot entry clean in RPI4, Apple M1, Qemu,
> SystemReady contexts
> > and get a well deserved standardized information passing between prior
> loaders and U-Boot.
> >
> > The three options are possible though, you could select a U-Boot entry
> CONFIG option for:
> > <specific>
> > <optpassage>
> > <purepassage>
> >
> > But despite it would be technically feasible, I don't think it is goes
> in the right direction.
>
> OK. Do you think we need a separate devicetree pointer, rather than
> forcing it to be inside the created bloblist?
>
> I'd like to understand what problem you are solving with this. I am
> trying to figure out a firmware-to-firmware mini-ABI (just a few
> register values) that can be used in open-source projects. The ABI is
> not intended to be used with Linux (I am unsure of the benefit it
> would give and whether it is feasible to change the current one).
>
> You are talking about the Linux entry mechanism. What relevance does
> that have for firmware?
>
> I understand that some projects already implement the Linux mechanism,
> but that is because they expect to jump straight to Linux, not have
> U-Boot in the path. So IMO standard passage offers no benefit to them.
>
> To address them in turn:
> - rpi4 - closed source, who cares?
> - Apple M1 - we could probably expand it to pass a bloblist, but it
> would be confusing unless we share registers, as you suggest
> - Qemu - I already tried to update that and got pushback...do you
> really think those guys are going to want to add a bloblist? So again,
> who cares?
> - SystemReady - not sure what this means in practice, but it would be
> good if SystemReady could use standard passage
>
> So let's say we have an optional standard-passage thing and we use
> registers such that it is similar to Linux and EFI and just expands on
> them.
>
> The first problem is that Linux and EFI seem to be completely
> incompatible. Can that be changed, perhaps on the EFI side? If not,
> we need two separate protocols.
>
> I'll ignore EFI for now. So we might have:
>
> r0 = 0
> r1 = machine number (0?)
> r2 = dtb pointer
> r3 = bloblist pointer, 0 if missing
> r14 = return address
>
> or
>
> x0 = dtb
> x1 = bloblist pointer, 0 if missing
> x30 = return address
>
That’s essentially what I proposed!
you do not force the DTB to be found in the bloblist, and shape the U-Boot
entry after the Linux entry ABI. Good !
I was saving a few registers for future ABI evolution so that boards can be
guaranteed to have their board specific registers properly protected. The 5
registers, leaving 3 undefined was just « why not ». We could also have a
cookie in x1: high 48 bits magic low 16 ABI version, x2=bloblist pointer.


> For EFI, we could add a blob to the bloblist containing the system
> table and handle, perhaps? Otherwise:
>
> x2 - efi handle
> x3 - system table
>
> Is that along the lines of what you are thinking?
>
No, efi entry is only x0=efi handle, x1=system table . I was trying to find
a way to have passage when U-Boot is loaded as a UEFI app (your other patch
set to make U-Boot a more integrated UEFi app). Let’s say that a U-Boot
aware DXE driver/protocol actually populate such a table, it could be a
communication channel between that driver and U-Boot.

>
> But still, please respond above so I can understand what problem you
> are worried about.
>
> Regards,
> Simon
>
>
> >
> >> >>
> >> >> But I added an offset to it as a convenience.
> >> >>
> >> >> > - EFI: x0=handle, x1=systemtable, x30=return address;  (when
> U-Boot is launched as an EFI app)
> >> >> >        dtb = EFI_UUID config table, + Passage = Passage UUID
> config table
> >> >>
> >> >> I don't understand the last line. Where is the passage info /
> >> >> bloblist? Do you mean it goes in the HOB list with a UUID? I suppose
> >> >> that is the most EFI-compatible way.
> >> >
> >> > The Passage config table  could just contain the "head" of the
> bloblist/Passage information.
> >>
> >> If UEFI wants to deal with standard passage, that is...
> >>
> >> >>
> >> >>
> >> >> What do you think about the idea of using an offset into the bloblist
> >> >> for the dtb?
> >> >
> >> > It is possible but as I said, failing to mimic Linux entry ABI would
> miss the opportunity to just boot without changes on RPI4.
> >>
> >> See above. Broadcom could look at open-sourcing their bootloader if
> they wish.
> >>
> >> >>
> >> >> Also, can we make the standard passage ABI a build-time
> >> >> option, so it is deterministic?
> >> >>
> >> > Looks good. I would look into stating that for SystemReady we would
> advise to use that option and make it standard for Trusted Substrate
> (Linaro recipes that we upstreaming to make SystemReady compliance easy and
> consistent across platforms).
> >>
> >> OK. I mean that if the option is enabled, then standard passage must
> >> be provided / emitted or things won't work. If the option is disabled,
> >> then standard passage is not used. In other words, we are looking for
> >> magic values in registers, etc, just enabling/disabling it at
> >> build-time.
> >>
> >> >>
> >> >> >
> >> >> > We could further leverage Passage to pass Operating Systems
> parameters that could be removed from device tree (migration of /chosen to
> Passage). Memory inventory would still be in DT but allocations for CMA or
> GPUs would be in Passage. This idea is to reach a point where  device tree
> is a "pristine" hardware description.
> >> >>
> >> >> I'm worried about this becoming a substitute for devicetree. Really
> my
> >> >> intent is to provide a way to pass simple info, whereas what you talk
> >> >> about there seems like something that should be DT, just that it
> might
> >> >> need suitable bindings.
> >> >>
> >> > I see your point and I agree It should not be a substitute.
> >> > here is an expanded version of what I had in mind when I wrote those
> lines.
> >> > cma, initrd and other Linux kernel parameters can be conveyed either
> through command line or DT.
> >> > When using the non UEFI Linux entry ABI, you need to use the DT to
> pass those parameters.
> >> > When using the UEFI Linux entry ABI, you *can* (not must) use the
> command line to pass all information, leaving the DT passed to the OS
> without any /chosen.
> >> > When introducing Passage, I was wondering if we could pass command
> line to Linux and, same as UEFI, leave the DT free from /chosen.
> >> > I am not sure it is a good goal though. I may be too pushing for a DT
> free from parameters.
> >>
> >> We could. Are there benefits to that?
> >>
> >> I doubt we would pass the standard passage to Linux as a bloblist. I
> >> imagine something like this. The bloblist sits in memory with some
> >> things in it, including a devicetree, perhaps an SMBIOS table and a
> >> TPM log. But when U-Boot calls Linux it puts the address/size of those
> >> individual things in the devicetree. They don't move and are still
> >> contiguous in memory, but the bloblist around them is forgotten. Linux
> >> doesn't know that the three separate things it is picking up are
> >> actually part of a bloblist structure, since it doesn't care about
> >> that. Even a console log could work the same way. That way we don't
> >> end up trying to teach Linux about bloblist when it already has a
> >> perfectly good means to accept these items.
> >>
> >> For ACPI I see things a similar way. The ACPI tables can point to
> >> things that *happen* to be in a bloblist, but without any knowledge of
> >> that needed in Linux, grub, etc.
> >>
> >> >>
> >> >> As you know I have more expansive views about what should be in DT.
> >> >
> >> > I think both of us are huge supporters of DT format and self
> describing capabilities.
> >> > I am inclined to put rules into what fits into what lands in the DT
> that is passed to the OS.
> >> > I am a fan of having DT used more in ad-hoc files.
> >>
> >> Me too.
> >>
> >> >>
> >> >> >
> >> >> > Cheers
> >> >> >
> >> >> > PS: as Ilias mentions, this patch set contains bug fixes, non
> immediately related additional functions (DM stats). It would be great to
> carve those out to fast path them and keep this one with the very core of
> your idea.
> >> >>
> >> >> The DM stats is used in 'passage: Report the devicetree source'. I
> >> >> know it is sideways but I think it is better to make the output line
> >> >> more useful than just reporting the devicetree source.
> >> >>
> >> > I believe the DM stats has merits in its own. You could upstream this
> independently and then Passage would be yet another "customer" of the
> feature.
> >>
> >> I could, but it would just be a debug feature so people might not
> >> think it worth the code space. With the devicetree source it is more
> >> compelling.
> >>
> >> >>
> >> >> The first patch is indeed unrelated. I will pick it up so we can drop
> >> >> it for the next rev.
> >> >>
> >> [..]
> >>
> >> Regards,
> >> Simon
> >
> >
> >
> > --
> > François-Frédéric Ozog | Director Business Development
> > T: +33.67221.6485
> > francois.ozog@linaro.org | Skype: ffozog
> >
>
-- 
François-Frédéric Ozog | *Director Business Development*
T: +33.67221.6485
francois.ozog@linaro.org | Skype: ffozog

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 00/31] passage: Define a standard for firmware data flow
@ 2021-11-05 16:31               ` François Ozog
  0 siblings, 0 replies; 77+ messages in thread
From: François Ozog @ 2021-11-05 16:31 UTC (permalink / raw)
  To: Simon Glass
  Cc: Marek Vasut, Albert Aribaud, Tom Rini, U-Boot Mailing List,
	Heinrich Schuchardt, Bill Mills, Ilias Apalodimas,
	QEMU Developers, Masahiro Yamada, Jerry Van Baren, Bin Meng,
	Pavel Herrmann

[-- Attachment #1: Type: text/plain, Size: 15195 bytes --]

Hi Simon,

Le ven. 5 nov. 2021 à 17:12, Simon Glass <sjg@chromium.org> a écrit :

> Hi François,
>
> On Fri, 5 Nov 2021 at 02:27, François Ozog <francois.ozog@linaro.org>
> wrote:
> >
> >
> >
> > On Fri, 5 Nov 2021 at 03:02, Simon Glass <sjg@chromium.org> wrote:
> >>
> >> Hi François,
> >>
> >> On Tue, 2 Nov 2021 at 10:03, François Ozog <francois.ozog@linaro.org>
> wrote:
> >> >
> >> > Hi Simon,
> >> >
> >> > On Tue, 2 Nov 2021 at 15:59, Simon Glass <sjg@chromium.org> wrote:
> >> >>
> >> >> Hi François,
> >> >>
> >> >> On Mon, 1 Nov 2021 at 02:53, François Ozog <francois.ozog@linaro.org>
> wrote:
> >> >> >
> >> >> > Hi Simon,
> >> >> >
> >> >> > this seems a great endeavor. I'd like to better understand the
> scope of it.
> >> >> >
> >> >> > Is it to be used as part of what could become a U-Boot entry ABI
> scheme? By that I mean giving some fixed aspects
> >> >> > to U-Boot entry while letting boards to have flexibility (say for
> instance that the first 5 architecture ABI
> >> >> > parameter registers are reserved for U-Boot), and the Passage is
> about specifying either those reserved registers
> >> >> > or one of them?
> >> >>
> >> >> The goal is to provide a standard entry scheme for all firmware
> >> >> binaries. Whether it achieves that (or can with some mods) is up for
> >> >> discussion.
> >> >>
> >> > If you say
> >> > a) define a U-Boot entry ABI and providing a firmware-to-firmware
> information passing facility which would be part of all firmware ABIs (as
> the projects decide to define their own ABI) it looks good.
> >> > but If you say
> >>
> >> It is an ABI to be adopted by U-Boot but also other firmware. For
> >> example, if TF-A calls U-Boot it should use standard passage. If
> >> U-Boot calls TF-A or Optee it should use standard passage.
> >>
> >> > b) define a standard entry scheme (register map, processor state, MMU
> state, SMMU state, GIC state...) that does not look realistic.
> >>
> >> No I don't mean that. This data structure could be used in any state,
> >> so long as the two registers are set correctly.
> >>
> >> > I think you mean a) but just want to be sure.
> >>
> >> Yes I think so.
> >>
> >> >>
> >> >> Re the registers, do you think we need 5?
> >> >>
> >>
> >> I don't :-)
> >>
> >> >> >
> >> >> > Thinking entry ABI, here is what I observed on Arm:
> >> >> >
> >> >> > Linux has two entry ABIs:
> >> >> > - plain: x0 = dtb;
> >> >> >           command line = dtb:/chosen/bootargs; initrd =
> dtb:/chosen/linux,initrd-*
> >> >> > - EFI: x0=handle, x1=systemtable, x30=return address;
> >> >> >            dtb = EFI_UUID config table; initrd =
> efi:<loadfile2(INITRD vendor media UUID); command line = efi:
> image_protocol::load_options
> >> >> >
> >> >> > U-Boot (proper) has plenty of schemes:
> >> >> > - dtb is passed as either x0, x1, fixed memory area (Qemu which is
> bad in itself), or other registers
> >> >> > - additional information passing: board specific register scheme,
> SMC calls
> >> >> > - U-Boot for RPI boards implement a Linux shaped entry ABI to be
> launched by Videocore firmware
> >> >> >
> >> >> > Based on all the above, I would tend to think that RPI scheme is a
> good idea but also
> >> >> > shall not prevent additional schemes for the boards.
> >> >>
> >> >> I was not actually considering Linux since I believe/assume its entry
> >> >> scheme is fixed and not up for discussion.
> >> >>
> >> >> I also did not think about the EFI case. As I understand it we cannot
> >> >> touch it as it is used by UEFI today. Maybe it is even in the
> >> >> standard?
> >> >
> >> > It is in the spec and we are making it evolve, or its understanding
> evolve (jurisprudence) for instance on initrd standard handling.
> >>
> >> Well perhaps we could merge it with standard passage. But EFI is not
> >> going to want to use a bloblist, it will want to use a HOB.
> >>
> >> >>
> >> >>
> >> >> Really I am hoping we can start afresh...?
> >> >>
> >> >> >
> >> >> > What about a U-Boot Arm entry ABI like:
> >> >> > - plain: x0=dtb, x1=<Passage defined>, x2-x5 = <reserved>, other
> registers are per platform, SMC calls allowed too
> >> >>
> >> >> Hmm we don't actually need the dtb as it is available in the
> bloblist.
> >> >
> >> > If you don't have x0=dtb, then you will not be able to use U-Boot on
> RPI4.
> >> > Unless you want to redo everything the RPI firmware is doing.
> >>
> >> That's right, RPI cannot support standard passage. It is not
> >> open-source firmware so it isn't really relevant to this discussion.
> >> It will just do what it does and have limited functionality, with
> >> work-arounds to deal with the pain, as one might expect.
> >>
> > So you are seeing two "all-or-nothing" options:
> > <specific>: U-Boot entry is board specific as it is today
> > <purepassage>: A new form where the only parameter is a head of
> bloblist, one of those blobs contain a DT
> >  You propose to mandate a DT for all boards make sense in that
> environment.
> > For RPI4, you just ignore everything the prior boot loader does because
> it is not <passage> compliant.
>
> It's not that. It's just that it is closed-source, so not relevant to
> the discussion here. They could open-source it and then we could
> consider it, but it has been closed-source for years now, so why would
> we think that would happen?
>
> >
> > This reinforces my opposition to the mandatory DT proposal.
> >
> > a third option is I think way more attractive:
> > <optpassage>: shaped after the architecture Linux entry (ie. first
> parameter is dtb) [+ passage head (i.e. second parameter is pointer to
> passage head)]
> >
> > This way, you make U-Boot entry clean in RPI4, Apple M1, Qemu,
> SystemReady contexts
> > and get a well deserved standardized information passing between prior
> loaders and U-Boot.
> >
> > The three options are possible though, you could select a U-Boot entry
> CONFIG option for:
> > <specific>
> > <optpassage>
> > <purepassage>
> >
> > But despite it would be technically feasible, I don't think it is goes
> in the right direction.
>
> OK. Do you think we need a separate devicetree pointer, rather than
> forcing it to be inside the created bloblist?
>
> I'd like to understand what problem you are solving with this. I am
> trying to figure out a firmware-to-firmware mini-ABI (just a few
> register values) that can be used in open-source projects. The ABI is
> not intended to be used with Linux (I am unsure of the benefit it
> would give and whether it is feasible to change the current one).
>
> You are talking about the Linux entry mechanism. What relevance does
> that have for firmware?
>
> I understand that some projects already implement the Linux mechanism,
> but that is because they expect to jump straight to Linux, not have
> U-Boot in the path. So IMO standard passage offers no benefit to them.
>
> To address them in turn:
> - rpi4 - closed source, who cares?
> - Apple M1 - we could probably expand it to pass a bloblist, but it
> would be confusing unless we share registers, as you suggest
> - Qemu - I already tried to update that and got pushback...do you
> really think those guys are going to want to add a bloblist? So again,
> who cares?
> - SystemReady - not sure what this means in practice, but it would be
> good if SystemReady could use standard passage
>
> So let's say we have an optional standard-passage thing and we use
> registers such that it is similar to Linux and EFI and just expands on
> them.
>
> The first problem is that Linux and EFI seem to be completely
> incompatible. Can that be changed, perhaps on the EFI side? If not,
> we need two separate protocols.
>
> I'll ignore EFI for now. So we might have:
>
> r0 = 0
> r1 = machine number (0?)
> r2 = dtb pointer
> r3 = bloblist pointer, 0 if missing
> r14 = return address
>
> or
>
> x0 = dtb
> x1 = bloblist pointer, 0 if missing
> x30 = return address
>
That’s essentially what I proposed!
you do not force the DTB to be found in the bloblist, and shape the U-Boot
entry after the Linux entry ABI. Good !
I was saving a few registers for future ABI evolution so that boards can be
guaranteed to have their board specific registers properly protected. The 5
registers, leaving 3 undefined was just « why not ». We could also have a
cookie in x1: high 48 bits magic low 16 ABI version, x2=bloblist pointer.


> For EFI, we could add a blob to the bloblist containing the system
> table and handle, perhaps? Otherwise:
>
> x2 - efi handle
> x3 - system table
>
> Is that along the lines of what you are thinking?
>
No, efi entry is only x0=efi handle, x1=system table . I was trying to find
a way to have passage when U-Boot is loaded as a UEFI app (your other patch
set to make U-Boot a more integrated UEFi app). Let’s say that a U-Boot
aware DXE driver/protocol actually populate such a table, it could be a
communication channel between that driver and U-Boot.

>
> But still, please respond above so I can understand what problem you
> are worried about.
>
> Regards,
> Simon
>
>
> >
> >> >>
> >> >> But I added an offset to it as a convenience.
> >> >>
> >> >> > - EFI: x0=handle, x1=systemtable, x30=return address;  (when
> U-Boot is launched as an EFI app)
> >> >> >        dtb = EFI_UUID config table, + Passage = Passage UUID
> config table
> >> >>
> >> >> I don't understand the last line. Where is the passage info /
> >> >> bloblist? Do you mean it goes in the HOB list with a UUID? I suppose
> >> >> that is the most EFI-compatible way.
> >> >
> >> > The Passage config table  could just contain the "head" of the
> bloblist/Passage information.
> >>
> >> If UEFI wants to deal with standard passage, that is...
> >>
> >> >>
> >> >>
> >> >> What do you think about the idea of using an offset into the bloblist
> >> >> for the dtb?
> >> >
> >> > It is possible but as I said, failing to mimic Linux entry ABI would
> miss the opportunity to just boot without changes on RPI4.
> >>
> >> See above. Broadcom could look at open-sourcing their bootloader if
> they wish.
> >>
> >> >>
> >> >> Also, can we make the standard passage ABI a build-time
> >> >> option, so it is deterministic?
> >> >>
> >> > Looks good. I would look into stating that for SystemReady we would
> advise to use that option and make it standard for Trusted Substrate
> (Linaro recipes that we upstreaming to make SystemReady compliance easy and
> consistent across platforms).
> >>
> >> OK. I mean that if the option is enabled, then standard passage must
> >> be provided / emitted or things won't work. If the option is disabled,
> >> then standard passage is not used. In other words, we are looking for
> >> magic values in registers, etc, just enabling/disabling it at
> >> build-time.
> >>
> >> >>
> >> >> >
> >> >> > We could further leverage Passage to pass Operating Systems
> parameters that could be removed from device tree (migration of /chosen to
> Passage). Memory inventory would still be in DT but allocations for CMA or
> GPUs would be in Passage. This idea is to reach a point where  device tree
> is a "pristine" hardware description.
> >> >>
> >> >> I'm worried about this becoming a substitute for devicetree. Really
> my
> >> >> intent is to provide a way to pass simple info, whereas what you talk
> >> >> about there seems like something that should be DT, just that it
> might
> >> >> need suitable bindings.
> >> >>
> >> > I see your point and I agree It should not be a substitute.
> >> > here is an expanded version of what I had in mind when I wrote those
> lines.
> >> > cma, initrd and other Linux kernel parameters can be conveyed either
> through command line or DT.
> >> > When using the non UEFI Linux entry ABI, you need to use the DT to
> pass those parameters.
> >> > When using the UEFI Linux entry ABI, you *can* (not must) use the
> command line to pass all information, leaving the DT passed to the OS
> without any /chosen.
> >> > When introducing Passage, I was wondering if we could pass command
> line to Linux and, same as UEFI, leave the DT free from /chosen.
> >> > I am not sure it is a good goal though. I may be too pushing for a DT
> free from parameters.
> >>
> >> We could. Are there benefits to that?
> >>
> >> I doubt we would pass the standard passage to Linux as a bloblist. I
> >> imagine something like this. The bloblist sits in memory with some
> >> things in it, including a devicetree, perhaps an SMBIOS table and a
> >> TPM log. But when U-Boot calls Linux it puts the address/size of those
> >> individual things in the devicetree. They don't move and are still
> >> contiguous in memory, but the bloblist around them is forgotten. Linux
> >> doesn't know that the three separate things it is picking up are
> >> actually part of a bloblist structure, since it doesn't care about
> >> that. Even a console log could work the same way. That way we don't
> >> end up trying to teach Linux about bloblist when it already has a
> >> perfectly good means to accept these items.
> >>
> >> For ACPI I see things a similar way. The ACPI tables can point to
> >> things that *happen* to be in a bloblist, but without any knowledge of
> >> that needed in Linux, grub, etc.
> >>
> >> >>
> >> >> As you know I have more expansive views about what should be in DT.
> >> >
> >> > I think both of us are huge supporters of DT format and self
> describing capabilities.
> >> > I am inclined to put rules into what fits into what lands in the DT
> that is passed to the OS.
> >> > I am a fan of having DT used more in ad-hoc files.
> >>
> >> Me too.
> >>
> >> >>
> >> >> >
> >> >> > Cheers
> >> >> >
> >> >> > PS: as Ilias mentions, this patch set contains bug fixes, non
> immediately related additional functions (DM stats). It would be great to
> carve those out to fast path them and keep this one with the very core of
> your idea.
> >> >>
> >> >> The DM stats is used in 'passage: Report the devicetree source'. I
> >> >> know it is sideways but I think it is better to make the output line
> >> >> more useful than just reporting the devicetree source.
> >> >>
> >> > I believe the DM stats has merits in its own. You could upstream this
> independently and then Passage would be yet another "customer" of the
> feature.
> >>
> >> I could, but it would just be a debug feature so people might not
> >> think it worth the code space. With the devicetree source it is more
> >> compelling.
> >>
> >> >>
> >> >> The first patch is indeed unrelated. I will pick it up so we can drop
> >> >> it for the next rev.
> >> >>
> >> [..]
> >>
> >> Regards,
> >> Simon
> >
> >
> >
> > --
> > François-Frédéric Ozog | Director Business Development
> > T: +33.67221.6485
> > francois.ozog@linaro.org | Skype: ffozog
> >
>
-- 
François-Frédéric Ozog | *Director Business Development*
T: +33.67221.6485
francois.ozog@linaro.org | Skype: ffozog

[-- Attachment #2: Type: text/html, Size: 20272 bytes --]

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 00/31] passage: Define a standard for firmware data flow
  2021-11-05 16:31               ` François Ozog
@ 2021-11-05 17:16                 ` Simon Glass
  -1 siblings, 0 replies; 77+ messages in thread
From: Simon Glass @ 2021-11-05 17:16 UTC (permalink / raw)
  To: François Ozog
  Cc: Albert Aribaud, Bill Mills, Bin Meng, Heinrich Schuchardt,
	Ilias Apalodimas, Jerry Van Baren, Marek Vasut, Masahiro Yamada,
	Pavel Herrmann, QEMU Developers, Tom Rini, U-Boot Mailing List

) to signal Hi François,

On Fri, 5 Nov 2021 at 10:31, François Ozog <francois.ozog@linaro.org> wrote:
>
> Hi Simon,
>
> Le ven. 5 nov. 2021 à 17:12, Simon Glass <sjg@chromium.org> a écrit :
>>
>> Hi François,
>>
>> On Fri, 5 Nov 2021 at 02:27, François Ozog <francois.ozog@linaro.org> wrote:
>> >
>> >
>> >
>> > On Fri, 5 Nov 2021 at 03:02, Simon Glass <sjg@chromium.org> wrote:
>> >>
>> >> Hi François,
>> >>
>> >> On Tue, 2 Nov 2021 at 10:03, François Ozog <francois.ozog@linaro.org> wrote:
>> >> >
>> >> > Hi Simon,
>> >> >
>> >> > On Tue, 2 Nov 2021 at 15:59, Simon Glass <sjg@chromium.org> wrote:
>> >> >>
>> >> >> Hi François,
>> >> >>
>> >> >> On Mon, 1 Nov 2021 at 02:53, François Ozog <francois.ozog@linaro.org> wrote:
>> >> >> >
>> >> >> > Hi Simon,
>> >> >> >
>> >> >> > this seems a great endeavor. I'd like to better understand the scope of it.
>> >> >> >
>> >> >> > Is it to be used as part of what could become a U-Boot entry ABI scheme? By that I mean giving some fixed aspects
>> >> >> > to U-Boot entry while letting boards to have flexibility (say for instance that the first 5 architecture ABI
>> >> >> > parameter registers are reserved for U-Boot), and the Passage is about specifying either those reserved registers
>> >> >> > or one of them?
>> >> >>
>> >> >> The goal is to provide a standard entry scheme for all firmware
>> >> >> binaries. Whether it achieves that (or can with some mods) is up for
>> >> >> discussion.
>> >> >>
>> >> > If you say
>> >> > a) define a U-Boot entry ABI and providing a firmware-to-firmware information passing facility which would be part of all firmware ABIs (as the projects decide to define their own ABI) it looks good.
>> >> > but If you say
>> >>
>> >> It is an ABI to be adopted by U-Boot but also other firmware. For
>> >> example, if TF-A calls U-Boot it should use standard passage. If
>> >> U-Boot calls TF-A or Optee it should use standard passage.
>> >>
>> >> > b) define a standard entry scheme (register map, processor state, MMU state, SMMU state, GIC state...) that does not look realistic.
>> >>
>> >> No I don't mean that. This data structure could be used in any state,
>> >> so long as the two registers are set correctly.
>> >>
>> >> > I think you mean a) but just want to be sure.
>> >>
>> >> Yes I think so.
>> >>
>> >> >>
>> >> >> Re the registers, do you think we need 5?
>> >> >>
>> >>
>> >> I don't :-)
>> >>
>> >> >> >
>> >> >> > Thinking entry ABI, here is what I observed on Arm:
>> >> >> >
>> >> >> > Linux has two entry ABIs:
>> >> >> > - plain: x0 = dtb;
>> >> >> >           command line = dtb:/chosen/bootargs; initrd = dtb:/chosen/linux,initrd-*
>> >> >> > - EFI: x0=handle, x1=systemtable, x30=return address;
>> >> >> >            dtb = EFI_UUID config table; initrd = efi:<loadfile2(INITRD vendor media UUID); command line = efi: image_protocol::load_options
>> >> >> >
>> >> >> > U-Boot (proper) has plenty of schemes:
>> >> >> > - dtb is passed as either x0, x1, fixed memory area (Qemu which is bad in itself), or other registers
>> >> >> > - additional information passing: board specific register scheme, SMC calls
>> >> >> > - U-Boot for RPI boards implement a Linux shaped entry ABI to be launched by Videocore firmware
>> >> >> >
>> >> >> > Based on all the above, I would tend to think that RPI scheme is a good idea but also
>> >> >> > shall not prevent additional schemes for the boards.
>> >> >>
>> >> >> I was not actually considering Linux since I believe/assume its entry
>> >> >> scheme is fixed and not up for discussion.
>> >> >>
>> >> >> I also did not think about the EFI case. As I understand it we cannot
>> >> >> touch it as it is used by UEFI today. Maybe it is even in the
>> >> >> standard?
>> >> >
>> >> > It is in the spec and we are making it evolve, or its understanding evolve (jurisprudence) for instance on initrd standard handling.
>> >>
>> >> Well perhaps we could merge it with standard passage. But EFI is not
>> >> going to want to use a bloblist, it will want to use a HOB.
>> >>
>> >> >>
>> >> >>
>> >> >> Really I am hoping we can start afresh...?
>> >> >>
>> >> >> >
>> >> >> > What about a U-Boot Arm entry ABI like:
>> >> >> > - plain: x0=dtb, x1=<Passage defined>, x2-x5 = <reserved>, other registers are per platform, SMC calls allowed too
>> >> >>
>> >> >> Hmm we don't actually need the dtb as it is available in the bloblist.
>> >> >
>> >> > If you don't have x0=dtb, then you will not be able to use U-Boot on RPI4.
>> >> > Unless you want to redo everything the RPI firmware is doing.
>> >>
>> >> That's right, RPI cannot support standard passage. It is not
>> >> open-source firmware so it isn't really relevant to this discussion.
>> >> It will just do what it does and have limited functionality, with
>> >> work-arounds to deal with the pain, as one might expect.
>> >>
>> > So you are seeing two "all-or-nothing" options:
>> > <specific>: U-Boot entry is board specific as it is today
>> > <purepassage>: A new form where the only parameter is a head of bloblist, one of those blobs contain a DT
>> >  You propose to mandate a DT for all boards make sense in that environment.
>> > For RPI4, you just ignore everything the prior boot loader does because it is not <passage> compliant.
>>
>> It's not that. It's just that it is closed-source, so not relevant to
>> the discussion here. They could open-source it and then we could
>> consider it, but it has been closed-source for years now, so why would
>> we think that would happen?
>>
>> >
>> > This reinforces my opposition to the mandatory DT proposal.
>> >
>> > a third option is I think way more attractive:
>> > <optpassage>: shaped after the architecture Linux entry (ie. first parameter is dtb) [+ passage head (i.e. second parameter is pointer to passage head)]
>> >
>> > This way, you make U-Boot entry clean in RPI4, Apple M1, Qemu, SystemReady contexts
>> > and get a well deserved standardized information passing between prior loaders and U-Boot.
>> >
>> > The three options are possible though, you could select a U-Boot entry CONFIG option for:
>> > <specific>
>> > <optpassage>
>> > <purepassage>
>> >
>> > But despite it would be technically feasible, I don't think it is goes in the right direction.
>>
>> OK. Do you think we need a separate devicetree pointer, rather than
>> forcing it to be inside the created bloblist?
>>
>> I'd like to understand what problem you are solving with this. I am
>> trying to figure out a firmware-to-firmware mini-ABI (just a few
>> register values) that can be used in open-source projects. The ABI is
>> not intended to be used with Linux (I am unsure of the benefit it
>> would give and whether it is feasible to change the current one).
>>
>> You are talking about the Linux entry mechanism. What relevance does
>> that have for firmware?
>>
>> I understand that some projects already implement the Linux mechanism,
>> but that is because they expect to jump straight to Linux, not have
>> U-Boot in the path. So IMO standard passage offers no benefit to them.
>>
>> To address them in turn:
>> - rpi4 - closed source, who cares?
>> - Apple M1 - we could probably expand it to pass a bloblist, but it
>> would be confusing unless we share registers, as you suggest
>> - Qemu - I already tried to update that and got pushback...do you
>> really think those guys are going to want to add a bloblist? So again,
>> who cares?
>> - SystemReady - not sure what this means in practice, but it would be
>> good if SystemReady could use standard passage
>>
>> So let's say we have an optional standard-passage thing and we use
>> registers such that it is similar to Linux and EFI and just expands on
>> them.
>>
>> The first problem is that Linux and EFI seem to be completely
>> incompatible. Can that be changed, perhaps on the EFI side? If not,
>> we need two separate protocols.
>>
>> I'll ignore EFI for now. So we might have:
>>
>> r0 = 0
>> r1 = machine number (0?)
>> r2 = dtb pointer
>> r3 = bloblist pointer, 0 if missing
>> r14 = return address
>>
>> or
>>
>> x0 = dtb
>> x1 = bloblist pointer, 0 if missing
>> x30 = return address
>
> That’s essentially what I proposed!
> you do not force the DTB to be found in the bloblist, and shape the U-Boot entry after the Linux entry ABI. Good !
> I was saving a few registers for future ABI evolution so that boards can be guaranteed to have their board specific registers properly protected. The 5 registers, leaving 3 undefined was just « why not ». We could also have a cookie in x1: high 48 bits magic low 16 ABI version, x2=bloblist pointer.

Isn't 32 bits enough for a magic value?

Also x3 might be nicer, to match ARM 32-bit, so:

x0 = dtb
x1 = ABI indicator bits 63:32 0xb00757a3, bits 31:1 = 0, bit 0 = 1
(version 1) ? We don't need to decide how many bits for the version
right now. Perhaps 8 is plenty
x2 = 0
x3 = bloblist pointer, 0 if missing
x4 = 0
x30 = return address

For ARM:

r0 = 0
r1 = machine number (0xb00757xx to signal standard passage where xx is
the ABI version?)*
r2 = dtb pointer
r3 = bloblist pointer (if r1 is 0xb00757xx), else 0
r4 = 0
r14 = return address

* might be safe, looking at
https://elixir.bootlin.com/linux/latest/source/arch/arm/kernel/setup.c#L1094

>
>>
>> For EFI, we could add a blob to the bloblist containing the system
>> table and handle, perhaps? Otherwise:
>>
>> x2 - efi handle
>> x3 - system table
>>
>> Is that along the lines of what you are thinking?
>
> No, efi entry is only x0=efi handle, x1=system table . I was trying to find a way to have passage when U-Boot is loaded as a UEFI app (your other patch set to make U-Boot a more integrated UEFi app). Let’s say that a U-Boot aware DXE driver/protocol actually populate such a table, it could be a communication channel between that driver and U-Boot.

OK, I figured, so how about, for EFI on 64-bit:

x0 = handle
x1 = systable
x2 = ABI indicator bits 63:32 0xb00757a3, bits 31:1 = 0, bit 0 = 1 (version 1)
x3 = bloblist pointer
x4 = 0
x30 = return address

EFI 32-bit:

r0 = handle
r1 = systable
r2 = 0xb00757a3
r3 = bloblist pointer
r4 = 0
r14 = return address

Regards,
Simon

>>
>>
>> But still, please respond above so I can understand what problem you
>> are worried about.
>>
>> Regards,
>> Simon
>>
>>
>> >
>> >> >>
>> >> >> But I added an offset to it as a convenience.
>> >> >>
>> >> >> > - EFI: x0=handle, x1=systemtable, x30=return address;  (when U-Boot is launched as an EFI app)
>> >> >> >        dtb = EFI_UUID config table, + Passage = Passage UUID config table
>> >> >>
>> >> >> I don't understand the last line. Where is the passage info /
>> >> >> bloblist? Do you mean it goes in the HOB list with a UUID? I suppose
>> >> >> that is the most EFI-compatible way.
>> >> >
>> >> > The Passage config table  could just contain the "head" of the bloblist/Passage information.
>> >>
>> >> If UEFI wants to deal with standard passage, that is...
>> >>
>> >> >>
>> >> >>
>> >> >> What do you think about the idea of using an offset into the bloblist
>> >> >> for the dtb?
>> >> >
>> >> > It is possible but as I said, failing to mimic Linux entry ABI would miss the opportunity to just boot without changes on RPI4.
>> >>
>> >> See above. Broadcom could look at open-sourcing their bootloader if they wish.
>> >>
>> >> >>
>> >> >> Also, can we make the standard passage ABI a build-time
>> >> >> option, so it is deterministic?
>> >> >>
>> >> > Looks good. I would look into stating that for SystemReady we would advise to use that option and make it standard for Trusted Substrate (Linaro recipes that we upstreaming to make SystemReady compliance easy and consistent across platforms).
>> >>
>> >> OK. I mean that if the option is enabled, then standard passage must
>> >> be provided / emitted or things won't work. If the option is disabled,
>> >> then standard passage is not used. In other words, we are looking for
>> >> magic values in registers, etc, just enabling/disabling it at
>> >> build-time.
>> >>
>> >> >>
>> >> >> >
>> >> >> > We could further leverage Passage to pass Operating Systems parameters that could be removed from device tree (migration of /chosen to Passage). Memory inventory would still be in DT but allocations for CMA or GPUs would be in Passage. This idea is to reach a point where  device tree is a "pristine" hardware description.
>> >> >>
>> >> >> I'm worried about this becoming a substitute for devicetree. Really my
>> >> >> intent is to provide a way to pass simple info, whereas what you talk
>> >> >> about there seems like something that should be DT, just that it might
>> >> >> need suitable bindings.
>> >> >>
>> >> > I see your point and I agree It should not be a substitute.
>> >> > here is an expanded version of what I had in mind when I wrote those lines.
>> >> > cma, initrd and other Linux kernel parameters can be conveyed either through command line or DT.
>> >> > When using the non UEFI Linux entry ABI, you need to use the DT to pass those parameters.
>> >> > When using the UEFI Linux entry ABI, you *can* (not must) use the command line to pass all information, leaving the DT passed to the OS without any /chosen.
>> >> > When introducing Passage, I was wondering if we could pass command line to Linux and, same as UEFI, leave the DT free from /chosen.
>> >> > I am not sure it is a good goal though. I may be too pushing for a DT free from parameters.
>> >>
>> >> We could. Are there benefits to that?
>> >>
>> >> I doubt we would pass the standard passage to Linux as a bloblist. I
>> >> imagine something like this. The bloblist sits in memory with some
>> >> things in it, including a devicetree, perhaps an SMBIOS table and a
>> >> TPM log. But when U-Boot calls Linux it puts the address/size of those
>> >> individual things in the devicetree. They don't move and are still
>> >> contiguous in memory, but the bloblist around them is forgotten. Linux
>> >> doesn't know that the three separate things it is picking up are
>> >> actually part of a bloblist structure, since it doesn't care about
>> >> that. Even a console log could work the same way. That way we don't
>> >> end up trying to teach Linux about bloblist when it already has a
>> >> perfectly good means to accept these items.
>> >>
>> >> For ACPI I see things a similar way. The ACPI tables can point to
>> >> things that *happen* to be in a bloblist, but without any knowledge of
>> >> that needed in Linux, grub, etc.
>> >>
>> >> >>
>> >> >> As you know I have more expansive views about what should be in DT.
>> >> >
>> >> > I think both of us are huge supporters of DT format and self describing capabilities.
>> >> > I am inclined to put rules into what fits into what lands in the DT that is passed to the OS.
>> >> > I am a fan of having DT used more in ad-hoc files.
>> >>
>> >> Me too.
>> >>
>> >> >>
>> >> >> >
>> >> >> > Cheers
>> >> >> >
>> >> >> > PS: as Ilias mentions, this patch set contains bug fixes, non immediately related additional functions (DM stats). It would be great to carve those out to fast path them and keep this one with the very core of your idea.
>> >> >>
>> >> >> The DM stats is used in 'passage: Report the devicetree source'. I
>> >> >> know it is sideways but I think it is better to make the output line
>> >> >> more useful than just reporting the devicetree source.
>> >> >>
>> >> > I believe the DM stats has merits in its own. You could upstream this independently and then Passage would be yet another "customer" of the feature.
>> >>
>> >> I could, but it would just be a debug feature so people might not
>> >> think it worth the code space. With the devicetree source it is more
>> >> compelling.
>> >>
>> >> >>
>> >> >> The first patch is indeed unrelated. I will pick it up so we can drop
>> >> >> it for the next rev.
>> >> >>
>> >> [..]
>> >>
>> >> Regards,
>> >> Simon
>> >
>> >
>> >
>> > --
>> > François-Frédéric Ozog | Director Business Development
>> > T: +33.67221.6485
>> > francois.ozog@linaro.org | Skype: ffozog
>> >
>
> --
> François-Frédéric Ozog | Director Business Development
> T: +33.67221.6485
> francois.ozog@linaro.org | Skype: ffozog
>

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 00/31] passage: Define a standard for firmware data flow
@ 2021-11-05 17:16                 ` Simon Glass
  0 siblings, 0 replies; 77+ messages in thread
From: Simon Glass @ 2021-11-05 17:16 UTC (permalink / raw)
  To: François Ozog
  Cc: Marek Vasut, Albert Aribaud, Tom Rini, U-Boot Mailing List,
	Heinrich Schuchardt, Bill Mills, Ilias Apalodimas,
	QEMU Developers, Masahiro Yamada, Jerry Van Baren, Bin Meng,
	Pavel Herrmann

) to signal Hi François,

On Fri, 5 Nov 2021 at 10:31, François Ozog <francois.ozog@linaro.org> wrote:
>
> Hi Simon,
>
> Le ven. 5 nov. 2021 à 17:12, Simon Glass <sjg@chromium.org> a écrit :
>>
>> Hi François,
>>
>> On Fri, 5 Nov 2021 at 02:27, François Ozog <francois.ozog@linaro.org> wrote:
>> >
>> >
>> >
>> > On Fri, 5 Nov 2021 at 03:02, Simon Glass <sjg@chromium.org> wrote:
>> >>
>> >> Hi François,
>> >>
>> >> On Tue, 2 Nov 2021 at 10:03, François Ozog <francois.ozog@linaro.org> wrote:
>> >> >
>> >> > Hi Simon,
>> >> >
>> >> > On Tue, 2 Nov 2021 at 15:59, Simon Glass <sjg@chromium.org> wrote:
>> >> >>
>> >> >> Hi François,
>> >> >>
>> >> >> On Mon, 1 Nov 2021 at 02:53, François Ozog <francois.ozog@linaro.org> wrote:
>> >> >> >
>> >> >> > Hi Simon,
>> >> >> >
>> >> >> > this seems a great endeavor. I'd like to better understand the scope of it.
>> >> >> >
>> >> >> > Is it to be used as part of what could become a U-Boot entry ABI scheme? By that I mean giving some fixed aspects
>> >> >> > to U-Boot entry while letting boards to have flexibility (say for instance that the first 5 architecture ABI
>> >> >> > parameter registers are reserved for U-Boot), and the Passage is about specifying either those reserved registers
>> >> >> > or one of them?
>> >> >>
>> >> >> The goal is to provide a standard entry scheme for all firmware
>> >> >> binaries. Whether it achieves that (or can with some mods) is up for
>> >> >> discussion.
>> >> >>
>> >> > If you say
>> >> > a) define a U-Boot entry ABI and providing a firmware-to-firmware information passing facility which would be part of all firmware ABIs (as the projects decide to define their own ABI) it looks good.
>> >> > but If you say
>> >>
>> >> It is an ABI to be adopted by U-Boot but also other firmware. For
>> >> example, if TF-A calls U-Boot it should use standard passage. If
>> >> U-Boot calls TF-A or Optee it should use standard passage.
>> >>
>> >> > b) define a standard entry scheme (register map, processor state, MMU state, SMMU state, GIC state...) that does not look realistic.
>> >>
>> >> No I don't mean that. This data structure could be used in any state,
>> >> so long as the two registers are set correctly.
>> >>
>> >> > I think you mean a) but just want to be sure.
>> >>
>> >> Yes I think so.
>> >>
>> >> >>
>> >> >> Re the registers, do you think we need 5?
>> >> >>
>> >>
>> >> I don't :-)
>> >>
>> >> >> >
>> >> >> > Thinking entry ABI, here is what I observed on Arm:
>> >> >> >
>> >> >> > Linux has two entry ABIs:
>> >> >> > - plain: x0 = dtb;
>> >> >> >           command line = dtb:/chosen/bootargs; initrd = dtb:/chosen/linux,initrd-*
>> >> >> > - EFI: x0=handle, x1=systemtable, x30=return address;
>> >> >> >            dtb = EFI_UUID config table; initrd = efi:<loadfile2(INITRD vendor media UUID); command line = efi: image_protocol::load_options
>> >> >> >
>> >> >> > U-Boot (proper) has plenty of schemes:
>> >> >> > - dtb is passed as either x0, x1, fixed memory area (Qemu which is bad in itself), or other registers
>> >> >> > - additional information passing: board specific register scheme, SMC calls
>> >> >> > - U-Boot for RPI boards implement a Linux shaped entry ABI to be launched by Videocore firmware
>> >> >> >
>> >> >> > Based on all the above, I would tend to think that RPI scheme is a good idea but also
>> >> >> > shall not prevent additional schemes for the boards.
>> >> >>
>> >> >> I was not actually considering Linux since I believe/assume its entry
>> >> >> scheme is fixed and not up for discussion.
>> >> >>
>> >> >> I also did not think about the EFI case. As I understand it we cannot
>> >> >> touch it as it is used by UEFI today. Maybe it is even in the
>> >> >> standard?
>> >> >
>> >> > It is in the spec and we are making it evolve, or its understanding evolve (jurisprudence) for instance on initrd standard handling.
>> >>
>> >> Well perhaps we could merge it with standard passage. But EFI is not
>> >> going to want to use a bloblist, it will want to use a HOB.
>> >>
>> >> >>
>> >> >>
>> >> >> Really I am hoping we can start afresh...?
>> >> >>
>> >> >> >
>> >> >> > What about a U-Boot Arm entry ABI like:
>> >> >> > - plain: x0=dtb, x1=<Passage defined>, x2-x5 = <reserved>, other registers are per platform, SMC calls allowed too
>> >> >>
>> >> >> Hmm we don't actually need the dtb as it is available in the bloblist.
>> >> >
>> >> > If you don't have x0=dtb, then you will not be able to use U-Boot on RPI4.
>> >> > Unless you want to redo everything the RPI firmware is doing.
>> >>
>> >> That's right, RPI cannot support standard passage. It is not
>> >> open-source firmware so it isn't really relevant to this discussion.
>> >> It will just do what it does and have limited functionality, with
>> >> work-arounds to deal with the pain, as one might expect.
>> >>
>> > So you are seeing two "all-or-nothing" options:
>> > <specific>: U-Boot entry is board specific as it is today
>> > <purepassage>: A new form where the only parameter is a head of bloblist, one of those blobs contain a DT
>> >  You propose to mandate a DT for all boards make sense in that environment.
>> > For RPI4, you just ignore everything the prior boot loader does because it is not <passage> compliant.
>>
>> It's not that. It's just that it is closed-source, so not relevant to
>> the discussion here. They could open-source it and then we could
>> consider it, but it has been closed-source for years now, so why would
>> we think that would happen?
>>
>> >
>> > This reinforces my opposition to the mandatory DT proposal.
>> >
>> > a third option is I think way more attractive:
>> > <optpassage>: shaped after the architecture Linux entry (ie. first parameter is dtb) [+ passage head (i.e. second parameter is pointer to passage head)]
>> >
>> > This way, you make U-Boot entry clean in RPI4, Apple M1, Qemu, SystemReady contexts
>> > and get a well deserved standardized information passing between prior loaders and U-Boot.
>> >
>> > The three options are possible though, you could select a U-Boot entry CONFIG option for:
>> > <specific>
>> > <optpassage>
>> > <purepassage>
>> >
>> > But despite it would be technically feasible, I don't think it is goes in the right direction.
>>
>> OK. Do you think we need a separate devicetree pointer, rather than
>> forcing it to be inside the created bloblist?
>>
>> I'd like to understand what problem you are solving with this. I am
>> trying to figure out a firmware-to-firmware mini-ABI (just a few
>> register values) that can be used in open-source projects. The ABI is
>> not intended to be used with Linux (I am unsure of the benefit it
>> would give and whether it is feasible to change the current one).
>>
>> You are talking about the Linux entry mechanism. What relevance does
>> that have for firmware?
>>
>> I understand that some projects already implement the Linux mechanism,
>> but that is because they expect to jump straight to Linux, not have
>> U-Boot in the path. So IMO standard passage offers no benefit to them.
>>
>> To address them in turn:
>> - rpi4 - closed source, who cares?
>> - Apple M1 - we could probably expand it to pass a bloblist, but it
>> would be confusing unless we share registers, as you suggest
>> - Qemu - I already tried to update that and got pushback...do you
>> really think those guys are going to want to add a bloblist? So again,
>> who cares?
>> - SystemReady - not sure what this means in practice, but it would be
>> good if SystemReady could use standard passage
>>
>> So let's say we have an optional standard-passage thing and we use
>> registers such that it is similar to Linux and EFI and just expands on
>> them.
>>
>> The first problem is that Linux and EFI seem to be completely
>> incompatible. Can that be changed, perhaps on the EFI side? If not,
>> we need two separate protocols.
>>
>> I'll ignore EFI for now. So we might have:
>>
>> r0 = 0
>> r1 = machine number (0?)
>> r2 = dtb pointer
>> r3 = bloblist pointer, 0 if missing
>> r14 = return address
>>
>> or
>>
>> x0 = dtb
>> x1 = bloblist pointer, 0 if missing
>> x30 = return address
>
> That’s essentially what I proposed!
> you do not force the DTB to be found in the bloblist, and shape the U-Boot entry after the Linux entry ABI. Good !
> I was saving a few registers for future ABI evolution so that boards can be guaranteed to have their board specific registers properly protected. The 5 registers, leaving 3 undefined was just « why not ». We could also have a cookie in x1: high 48 bits magic low 16 ABI version, x2=bloblist pointer.

Isn't 32 bits enough for a magic value?

Also x3 might be nicer, to match ARM 32-bit, so:

x0 = dtb
x1 = ABI indicator bits 63:32 0xb00757a3, bits 31:1 = 0, bit 0 = 1
(version 1) ? We don't need to decide how many bits for the version
right now. Perhaps 8 is plenty
x2 = 0
x3 = bloblist pointer, 0 if missing
x4 = 0
x30 = return address

For ARM:

r0 = 0
r1 = machine number (0xb00757xx to signal standard passage where xx is
the ABI version?)*
r2 = dtb pointer
r3 = bloblist pointer (if r1 is 0xb00757xx), else 0
r4 = 0
r14 = return address

* might be safe, looking at
https://elixir.bootlin.com/linux/latest/source/arch/arm/kernel/setup.c#L1094

>
>>
>> For EFI, we could add a blob to the bloblist containing the system
>> table and handle, perhaps? Otherwise:
>>
>> x2 - efi handle
>> x3 - system table
>>
>> Is that along the lines of what you are thinking?
>
> No, efi entry is only x0=efi handle, x1=system table . I was trying to find a way to have passage when U-Boot is loaded as a UEFI app (your other patch set to make U-Boot a more integrated UEFi app). Let’s say that a U-Boot aware DXE driver/protocol actually populate such a table, it could be a communication channel between that driver and U-Boot.

OK, I figured, so how about, for EFI on 64-bit:

x0 = handle
x1 = systable
x2 = ABI indicator bits 63:32 0xb00757a3, bits 31:1 = 0, bit 0 = 1 (version 1)
x3 = bloblist pointer
x4 = 0
x30 = return address

EFI 32-bit:

r0 = handle
r1 = systable
r2 = 0xb00757a3
r3 = bloblist pointer
r4 = 0
r14 = return address

Regards,
Simon

>>
>>
>> But still, please respond above so I can understand what problem you
>> are worried about.
>>
>> Regards,
>> Simon
>>
>>
>> >
>> >> >>
>> >> >> But I added an offset to it as a convenience.
>> >> >>
>> >> >> > - EFI: x0=handle, x1=systemtable, x30=return address;  (when U-Boot is launched as an EFI app)
>> >> >> >        dtb = EFI_UUID config table, + Passage = Passage UUID config table
>> >> >>
>> >> >> I don't understand the last line. Where is the passage info /
>> >> >> bloblist? Do you mean it goes in the HOB list with a UUID? I suppose
>> >> >> that is the most EFI-compatible way.
>> >> >
>> >> > The Passage config table  could just contain the "head" of the bloblist/Passage information.
>> >>
>> >> If UEFI wants to deal with standard passage, that is...
>> >>
>> >> >>
>> >> >>
>> >> >> What do you think about the idea of using an offset into the bloblist
>> >> >> for the dtb?
>> >> >
>> >> > It is possible but as I said, failing to mimic Linux entry ABI would miss the opportunity to just boot without changes on RPI4.
>> >>
>> >> See above. Broadcom could look at open-sourcing their bootloader if they wish.
>> >>
>> >> >>
>> >> >> Also, can we make the standard passage ABI a build-time
>> >> >> option, so it is deterministic?
>> >> >>
>> >> > Looks good. I would look into stating that for SystemReady we would advise to use that option and make it standard for Trusted Substrate (Linaro recipes that we upstreaming to make SystemReady compliance easy and consistent across platforms).
>> >>
>> >> OK. I mean that if the option is enabled, then standard passage must
>> >> be provided / emitted or things won't work. If the option is disabled,
>> >> then standard passage is not used. In other words, we are looking for
>> >> magic values in registers, etc, just enabling/disabling it at
>> >> build-time.
>> >>
>> >> >>
>> >> >> >
>> >> >> > We could further leverage Passage to pass Operating Systems parameters that could be removed from device tree (migration of /chosen to Passage). Memory inventory would still be in DT but allocations for CMA or GPUs would be in Passage. This idea is to reach a point where  device tree is a "pristine" hardware description.
>> >> >>
>> >> >> I'm worried about this becoming a substitute for devicetree. Really my
>> >> >> intent is to provide a way to pass simple info, whereas what you talk
>> >> >> about there seems like something that should be DT, just that it might
>> >> >> need suitable bindings.
>> >> >>
>> >> > I see your point and I agree It should not be a substitute.
>> >> > here is an expanded version of what I had in mind when I wrote those lines.
>> >> > cma, initrd and other Linux kernel parameters can be conveyed either through command line or DT.
>> >> > When using the non UEFI Linux entry ABI, you need to use the DT to pass those parameters.
>> >> > When using the UEFI Linux entry ABI, you *can* (not must) use the command line to pass all information, leaving the DT passed to the OS without any /chosen.
>> >> > When introducing Passage, I was wondering if we could pass command line to Linux and, same as UEFI, leave the DT free from /chosen.
>> >> > I am not sure it is a good goal though. I may be too pushing for a DT free from parameters.
>> >>
>> >> We could. Are there benefits to that?
>> >>
>> >> I doubt we would pass the standard passage to Linux as a bloblist. I
>> >> imagine something like this. The bloblist sits in memory with some
>> >> things in it, including a devicetree, perhaps an SMBIOS table and a
>> >> TPM log. But when U-Boot calls Linux it puts the address/size of those
>> >> individual things in the devicetree. They don't move and are still
>> >> contiguous in memory, but the bloblist around them is forgotten. Linux
>> >> doesn't know that the three separate things it is picking up are
>> >> actually part of a bloblist structure, since it doesn't care about
>> >> that. Even a console log could work the same way. That way we don't
>> >> end up trying to teach Linux about bloblist when it already has a
>> >> perfectly good means to accept these items.
>> >>
>> >> For ACPI I see things a similar way. The ACPI tables can point to
>> >> things that *happen* to be in a bloblist, but without any knowledge of
>> >> that needed in Linux, grub, etc.
>> >>
>> >> >>
>> >> >> As you know I have more expansive views about what should be in DT.
>> >> >
>> >> > I think both of us are huge supporters of DT format and self describing capabilities.
>> >> > I am inclined to put rules into what fits into what lands in the DT that is passed to the OS.
>> >> > I am a fan of having DT used more in ad-hoc files.
>> >>
>> >> Me too.
>> >>
>> >> >>
>> >> >> >
>> >> >> > Cheers
>> >> >> >
>> >> >> > PS: as Ilias mentions, this patch set contains bug fixes, non immediately related additional functions (DM stats). It would be great to carve those out to fast path them and keep this one with the very core of your idea.
>> >> >>
>> >> >> The DM stats is used in 'passage: Report the devicetree source'. I
>> >> >> know it is sideways but I think it is better to make the output line
>> >> >> more useful than just reporting the devicetree source.
>> >> >>
>> >> > I believe the DM stats has merits in its own. You could upstream this independently and then Passage would be yet another "customer" of the feature.
>> >>
>> >> I could, but it would just be a debug feature so people might not
>> >> think it worth the code space. With the devicetree source it is more
>> >> compelling.
>> >>
>> >> >>
>> >> >> The first patch is indeed unrelated. I will pick it up so we can drop
>> >> >> it for the next rev.
>> >> >>
>> >> [..]
>> >>
>> >> Regards,
>> >> Simon
>> >
>> >
>> >
>> > --
>> > François-Frédéric Ozog | Director Business Development
>> > T: +33.67221.6485
>> > francois.ozog@linaro.org | Skype: ffozog
>> >
>
> --
> François-Frédéric Ozog | Director Business Development
> T: +33.67221.6485
> francois.ozog@linaro.org | Skype: ffozog
>


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 00/31] passage: Define a standard for firmware data flow
  2021-11-05 17:16                 ` Simon Glass
@ 2021-11-08 16:20                   ` François Ozog
  -1 siblings, 0 replies; 77+ messages in thread
From: François Ozog @ 2021-11-08 16:20 UTC (permalink / raw)
  To: Simon Glass
  Cc: Albert Aribaud, Bill Mills, Bin Meng, Heinrich Schuchardt,
	Ilias Apalodimas, Jerry Van Baren, Marek Vasut, Masahiro Yamada,
	Pavel Herrmann, QEMU Developers, Tom Rini, U-Boot Mailing List

On Fri, 5 Nov 2021 at 18:17, Simon Glass <sjg@chromium.org> wrote:

> ) to signal Hi François,
>
> On Fri, 5 Nov 2021 at 10:31, François Ozog <francois.ozog@linaro.org>
> wrote:
> >
> > Hi Simon,
> >
> > Le ven. 5 nov. 2021 à 17:12, Simon Glass <sjg@chromium.org> a écrit :
> >>
> >> Hi François,
> >>
> >> On Fri, 5 Nov 2021 at 02:27, François Ozog <francois.ozog@linaro.org>
> wrote:
> >> >
> >> >
> >> >
> >> > On Fri, 5 Nov 2021 at 03:02, Simon Glass <sjg@chromium.org> wrote:
> >> >>
> >> >> Hi François,
> >> >>
> >> >> On Tue, 2 Nov 2021 at 10:03, François Ozog <francois.ozog@linaro.org>
> wrote:
> >> >> >
> >> >> > Hi Simon,
> >> >> >
> >> >> > On Tue, 2 Nov 2021 at 15:59, Simon Glass <sjg@chromium.org> wrote:
> >> >> >>
> >> >> >> Hi François,
> >> >> >>
> >> >> >> On Mon, 1 Nov 2021 at 02:53, François Ozog <
> francois.ozog@linaro.org> wrote:
> >> >> >> >
> >> >> >> > Hi Simon,
> >> >> >> >
> >> >> >> > this seems a great endeavor. I'd like to better understand the
> scope of it.
> >> >> >> >
> >> >> >> > Is it to be used as part of what could become a U-Boot entry
> ABI scheme? By that I mean giving some fixed aspects
> >> >> >> > to U-Boot entry while letting boards to have flexibility (say
> for instance that the first 5 architecture ABI
> >> >> >> > parameter registers are reserved for U-Boot), and the Passage
> is about specifying either those reserved registers
> >> >> >> > or one of them?
> >> >> >>
> >> >> >> The goal is to provide a standard entry scheme for all firmware
> >> >> >> binaries. Whether it achieves that (or can with some mods) is up
> for
> >> >> >> discussion.
> >> >> >>
> >> >> > If you say
> >> >> > a) define a U-Boot entry ABI and providing a firmware-to-firmware
> information passing facility which would be part of all firmware ABIs (as
> the projects decide to define their own ABI) it looks good.
> >> >> > but If you say
> >> >>
> >> >> It is an ABI to be adopted by U-Boot but also other firmware. For
> >> >> example, if TF-A calls U-Boot it should use standard passage. If
> >> >> U-Boot calls TF-A or Optee it should use standard passage.
> >> >>
> >> >> > b) define a standard entry scheme (register map, processor state,
> MMU state, SMMU state, GIC state...) that does not look realistic.
> >> >>
> >> >> No I don't mean that. This data structure could be used in any state,
> >> >> so long as the two registers are set correctly.
> >> >>
> >> >> > I think you mean a) but just want to be sure.
> >> >>
> >> >> Yes I think so.
> >> >>
> >> >> >>
> >> >> >> Re the registers, do you think we need 5?
> >> >> >>
> >> >>
> >> >> I don't :-)
> >> >>
> >> >> >> >
> >> >> >> > Thinking entry ABI, here is what I observed on Arm:
> >> >> >> >
> >> >> >> > Linux has two entry ABIs:
> >> >> >> > - plain: x0 = dtb;
> >> >> >> >           command line = dtb:/chosen/bootargs; initrd =
> dtb:/chosen/linux,initrd-*
> >> >> >> > - EFI: x0=handle, x1=systemtable, x30=return address;
> >> >> >> >            dtb = EFI_UUID config table; initrd =
> efi:<loadfile2(INITRD vendor media UUID); command line = efi:
> image_protocol::load_options
> >> >> >> >
> >> >> >> > U-Boot (proper) has plenty of schemes:
> >> >> >> > - dtb is passed as either x0, x1, fixed memory area (Qemu which
> is bad in itself), or other registers
> >> >> >> > - additional information passing: board specific register
> scheme, SMC calls
> >> >> >> > - U-Boot for RPI boards implement a Linux shaped entry ABI to
> be launched by Videocore firmware
> >> >> >> >
> >> >> >> > Based on all the above, I would tend to think that RPI scheme
> is a good idea but also
> >> >> >> > shall not prevent additional schemes for the boards.
> >> >> >>
> >> >> >> I was not actually considering Linux since I believe/assume its
> entry
> >> >> >> scheme is fixed and not up for discussion.
> >> >> >>
> >> >> >> I also did not think about the EFI case. As I understand it we
> cannot
> >> >> >> touch it as it is used by UEFI today. Maybe it is even in the
> >> >> >> standard?
> >> >> >
> >> >> > It is in the spec and we are making it evolve, or its
> understanding evolve (jurisprudence) for instance on initrd standard
> handling.
> >> >>
> >> >> Well perhaps we could merge it with standard passage. But EFI is not
> >> >> going to want to use a bloblist, it will want to use a HOB.
> >> >>
> >> >> >>
> >> >> >>
> >> >> >> Really I am hoping we can start afresh...?
> >> >> >>
> >> >> >> >
> >> >> >> > What about a U-Boot Arm entry ABI like:
> >> >> >> > - plain: x0=dtb, x1=<Passage defined>, x2-x5 = <reserved>,
> other registers are per platform, SMC calls allowed too
> >> >> >>
> >> >> >> Hmm we don't actually need the dtb as it is available in the
> bloblist.
> >> >> >
> >> >> > If you don't have x0=dtb, then you will not be able to use U-Boot
> on RPI4.
> >> >> > Unless you want to redo everything the RPI firmware is doing.
> >> >>
> >> >> That's right, RPI cannot support standard passage. It is not
> >> >> open-source firmware so it isn't really relevant to this discussion.
> >> >> It will just do what it does and have limited functionality, with
> >> >> work-arounds to deal with the pain, as one might expect.
> >> >>
> >> > So you are seeing two "all-or-nothing" options:
> >> > <specific>: U-Boot entry is board specific as it is today
> >> > <purepassage>: A new form where the only parameter is a head of
> bloblist, one of those blobs contain a DT
> >> >  You propose to mandate a DT for all boards make sense in that
> environment.
> >> > For RPI4, you just ignore everything the prior boot loader does
> because it is not <passage> compliant.
> >>
> >> It's not that. It's just that it is closed-source, so not relevant to
> >> the discussion here. They could open-source it and then we could
> >> consider it, but it has been closed-source for years now, so why would
> >> we think that would happen?
> >>
> >> >
> >> > This reinforces my opposition to the mandatory DT proposal.
> >> >
> >> > a third option is I think way more attractive:
> >> > <optpassage>: shaped after the architecture Linux entry (ie. first
> parameter is dtb) [+ passage head (i.e. second parameter is pointer to
> passage head)]
> >> >
> >> > This way, you make U-Boot entry clean in RPI4, Apple M1, Qemu,
> SystemReady contexts
> >> > and get a well deserved standardized information passing between
> prior loaders and U-Boot.
> >> >
> >> > The three options are possible though, you could select a U-Boot
> entry CONFIG option for:
> >> > <specific>
> >> > <optpassage>
> >> > <purepassage>
> >> >
> >> > But despite it would be technically feasible, I don't think it is
> goes in the right direction.
> >>
> >> OK. Do you think we need a separate devicetree pointer, rather than
> >> forcing it to be inside the created bloblist?
> >>
> >> I'd like to understand what problem you are solving with this. I am
> >> trying to figure out a firmware-to-firmware mini-ABI (just a few
> >> register values) that can be used in open-source projects. The ABI is
> >> not intended to be used with Linux (I am unsure of the benefit it
> >> would give and whether it is feasible to change the current one).
> >>
> >> You are talking about the Linux entry mechanism. What relevance does
> >> that have for firmware?
> >>
> >> I understand that some projects already implement the Linux mechanism,
> >> but that is because they expect to jump straight to Linux, not have
> >> U-Boot in the path. So IMO standard passage offers no benefit to them.
> >>
> >> To address them in turn:
> >> - rpi4 - closed source, who cares?
> >> - Apple M1 - we could probably expand it to pass a bloblist, but it
> >> would be confusing unless we share registers, as you suggest
> >> - Qemu - I already tried to update that and got pushback...do you
> >> really think those guys are going to want to add a bloblist? So again,
> >> who cares?
> >> - SystemReady - not sure what this means in practice, but it would be
> >> good if SystemReady could use standard passage
> >>
> >> So let's say we have an optional standard-passage thing and we use
> >> registers such that it is similar to Linux and EFI and just expands on
> >> them.
> >>
> >> The first problem is that Linux and EFI seem to be completely
> >> incompatible. Can that be changed, perhaps on the EFI side? If not,
> >> we need two separate protocols.
> >>
> >> I'll ignore EFI for now. So we might have:
> >>
> >> r0 = 0
> >> r1 = machine number (0?)
> >> r2 = dtb pointer
> >> r3 = bloblist pointer, 0 if missing
> >> r14 = return address
> >>
> >> or
> >>
> >> x0 = dtb
> >> x1 = bloblist pointer, 0 if missing
> >> x30 = return address
> >
> > That’s essentially what I proposed!
> > you do not force the DTB to be found in the bloblist, and shape the
> U-Boot entry after the Linux entry ABI. Good !
> > I was saving a few registers for future ABI evolution so that boards can
> be guaranteed to have their board specific registers properly protected.
> The 5 registers, leaving 3 undefined was just « why not ». We could also
> have a cookie in x1: high 48 bits magic low 16 ABI version, x2=bloblist
> pointer.
>
> Isn't 32 bits enough for a magic value?
>
> Also x3 might be nicer, to match ARM 32-bit, so:
>
> x0 = dtb
> x1 = ABI indicator bits 63:32 0xb00757a3, bits 31:1 = 0, bit 0 = 1
> (version 1) ? We don't need to decide how many bits for the version
> right now. Perhaps 8 is plenty
> x2 = 0
> x3 = bloblist pointer, 0 if missing
> x4 = 0
> x30 = return address
>
> sounds usable. Need more comments on this.


> For ARM:
>
> r0 = 0
> r1 = machine number (0xb00757xx to signal standard passage where xx is
> the ABI version?)*
> r2 = dtb pointer
> r3 = bloblist pointer (if r1 is 0xb00757xx), else 0
> r4 = 0
> r14 = return address
>
> * might be safe, looking at
>
> https://elixir.bootlin.com/linux/latest/source/arch/arm/kernel/setup.c#L1094
>
> Indeed. Need more comments on this.



> >
> >>
> >> For EFI, we could add a blob to the bloblist containing the system
> >> table and handle, perhaps? Otherwise:
> >>
> >> x2 - efi handle
> >> x3 - system table
> >>
> >> Is that along the lines of what you are thinking?
> >
> > No, efi entry is only x0=efi handle, x1=system table . I was trying to
> find a way to have passage when U-Boot is loaded as a UEFI app (your other
> patch set to make U-Boot a more integrated UEFi app). Let’s say that a
> U-Boot aware DXE driver/protocol actually populate such a table, it could
> be a communication channel between that driver and U-Boot.
>
> OK, I figured, so how about, for EFI on 64-bit:
>
> x0 = handle
> x1 = systable
> x2 = ABI indicator bits 63:32 0xb00757a3, bits 31:1 = 0, bit 0 = 1
> (version 1)
> x3 = bloblist pointer
> x4 = 0
> x30 = return address
>
> EFI 32-bit:
>
> r0 = handle
> r1 = systable
> r2 = 0xb00757a3
> r3 = bloblist pointer
> r4 = 0
> r14 = return address
>
> Let's be clear that this is for an existing UEFI implementation to boot
U-Boot.
If the implementation cannot be changed to add the information, a UEFI
driver or protocol may be used.
Could SPL may be tweaked to craft the bloblist based on whatever
information I that case?

(side comment: LinuxBoot has developed techniques to replace most of an
EDK2 implementation by Linux.
This entry ABI does not apply in this use case as it is defined by EDK2.)

Now on the how.

EFI API has already defined extension mechanism, so that may be difficult
to add.

let's put the bloblist pointer in a <configtable>:

 typedef struct {
1936  ///
1937  /// The 128-bit GUID value that uniquely identifies the system
configuration table.
1938  ///
1939
<https://dox.ipxe.org/structEFI__CONFIGURATION__TABLE.html#a50a67cc76cea0a08e7fcfc868ea8a02f>
  EFI_GUID <https://dox.ipxe.org/structGUID.html> VendorGuid
<https://dox.ipxe.org/structEFI__CONFIGURATION__TABLE.html#a50a67cc76cea0a08e7fcfc868ea8a02f>;
/* set to BLOB_LIST_GUID */
1940  ///
1941  /// A pointer to the table associated with VendorGuid.
1942  ///
1943
<https://dox.ipxe.org/structEFI__CONFIGURATION__TABLE.html#a1acfe9c046bb4d3a1e7d0e3c7c06f11b>
  VOID <https://dox.ipxe.org/Base_8h.html#a7f319bfc2492a2136964194204e7a8cf>
*VendorTable
<https://dox.ipxe.org/structEFI__CONFIGURATION__TABLE.html#a1acfe9c046bb4d3a1e7d0e3c7c06f11b>;
/* bloblist pointer */
1944 } EFI_CONFIGURATION_TABLE
<https://dox.ipxe.org/structEFI__CONFIGURATION__TABLE.html>;

U-Boot or a driver or a protocol can set the VendorTable to bloblist
pointer and add this to the list of configuration tables via
https://edk2-docs.gitbook.io/edk-ii-uefi-driver-writer-s-guide/5_uefi_services/readme.2/5210_installconfigurationtable

The blobs should be already accounted for in the memory map as they were
pre-allocated before U-Boot entry. But that may be a topic to be checked.


Regards,
> Simon
>
> >>
> >>
> >> But still, please respond above so I can understand what problem you
> >> are worried about.
> >>
> >> Regards,
> >> Simon
> >>
> >>
> >> >
> >> >> >>
> >> >> >> But I added an offset to it as a convenience.
> >> >> >>
> >> >> >> > - EFI: x0=handle, x1=systemtable, x30=return address;  (when
> U-Boot is launched as an EFI app)
> >> >> >> >        dtb = EFI_UUID config table, + Passage = Passage UUID
> config table
> >> >> >>
> >> >> >> I don't understand the last line. Where is the passage info /
> >> >> >> bloblist? Do you mean it goes in the HOB list with a UUID? I
> suppose
> >> >> >> that is the most EFI-compatible way.
> >> >> >
> >> >> > The Passage config table  could just contain the "head" of the
> bloblist/Passage information.
> >> >>
> >> >> If UEFI wants to deal with standard passage, that is...
> >> >>
> >> >> >>
> >> >> >>
> >> >> >> What do you think about the idea of using an offset into the
> bloblist
> >> >> >> for the dtb?
> >> >> >
> >> >> > It is possible but as I said, failing to mimic Linux entry ABI
> would miss the opportunity to just boot without changes on RPI4.
> >> >>
> >> >> See above. Broadcom could look at open-sourcing their bootloader if
> they wish.
> >> >>
> >> >> >>
> >> >> >> Also, can we make the standard passage ABI a build-time
> >> >> >> option, so it is deterministic?
> >> >> >>
> >> >> > Looks good. I would look into stating that for SystemReady we
> would advise to use that option and make it standard for Trusted Substrate
> (Linaro recipes that we upstreaming to make SystemReady compliance easy and
> consistent across platforms).
> >> >>
> >> >> OK. I mean that if the option is enabled, then standard passage must
> >> >> be provided / emitted or things won't work. If the option is
> disabled,
> >> >> then standard passage is not used. In other words, we are looking for
> >> >> magic values in registers, etc, just enabling/disabling it at
> >> >> build-time.
> >> >>
> >> >> >>
> >> >> >> >
> >> >> >> > We could further leverage Passage to pass Operating Systems
> parameters that could be removed from device tree (migration of /chosen to
> Passage). Memory inventory would still be in DT but allocations for CMA or
> GPUs would be in Passage. This idea is to reach a point where  device tree
> is a "pristine" hardware description.
> >> >> >>
> >> >> >> I'm worried about this becoming a substitute for devicetree.
> Really my
> >> >> >> intent is to provide a way to pass simple info, whereas what you
> talk
> >> >> >> about there seems like something that should be DT, just that it
> might
> >> >> >> need suitable bindings.
> >> >> >>
> >> >> > I see your point and I agree It should not be a substitute.
> >> >> > here is an expanded version of what I had in mind when I wrote
> those lines.
> >> >> > cma, initrd and other Linux kernel parameters can be conveyed
> either through command line or DT.
> >> >> > When using the non UEFI Linux entry ABI, you need to use the DT to
> pass those parameters.
> >> >> > When using the UEFI Linux entry ABI, you *can* (not must) use the
> command line to pass all information, leaving the DT passed to the OS
> without any /chosen.
> >> >> > When introducing Passage, I was wondering if we could pass command
> line to Linux and, same as UEFI, leave the DT free from /chosen.
> >> >> > I am not sure it is a good goal though. I may be too pushing for a
> DT free from parameters.
> >> >>
> >> >> We could. Are there benefits to that?
> >> >>
> >> >> I doubt we would pass the standard passage to Linux as a bloblist. I
> >> >> imagine something like this. The bloblist sits in memory with some
> >> >> things in it, including a devicetree, perhaps an SMBIOS table and a
> >> >> TPM log. But when U-Boot calls Linux it puts the address/size of
> those
> >> >> individual things in the devicetree. They don't move and are still
> >> >> contiguous in memory, but the bloblist around them is forgotten.
> Linux
> >> >> doesn't know that the three separate things it is picking up are
> >> >> actually part of a bloblist structure, since it doesn't care about
> >> >> that. Even a console log could work the same way. That way we don't
> >> >> end up trying to teach Linux about bloblist when it already has a
> >> >> perfectly good means to accept these items.
> >> >>
> >> >> For ACPI I see things a similar way. The ACPI tables can point to
> >> >> things that *happen* to be in a bloblist, but without any knowledge
> of
> >> >> that needed in Linux, grub, etc.
> >> >>
> >> >> >>
> >> >> >> As you know I have more expansive views about what should be in
> DT.
> >> >> >
> >> >> > I think both of us are huge supporters of DT format and self
> describing capabilities.
> >> >> > I am inclined to put rules into what fits into what lands in the
> DT that is passed to the OS.
> >> >> > I am a fan of having DT used more in ad-hoc files.
> >> >>
> >> >> Me too.
> >> >>
> >> >> >>
> >> >> >> >
> >> >> >> > Cheers
> >> >> >> >
> >> >> >> > PS: as Ilias mentions, this patch set contains bug fixes, non
> immediately related additional functions (DM stats). It would be great to
> carve those out to fast path them and keep this one with the very core of
> your idea.
> >> >> >>
> >> >> >> The DM stats is used in 'passage: Report the devicetree source'. I
> >> >> >> know it is sideways but I think it is better to make the output
> line
> >> >> >> more useful than just reporting the devicetree source.
> >> >> >>
> >> >> > I believe the DM stats has merits in its own. You could upstream
> this independently and then Passage would be yet another "customer" of the
> feature.
> >> >>
> >> >> I could, but it would just be a debug feature so people might not
> >> >> think it worth the code space. With the devicetree source it is more
> >> >> compelling.
> >> >>
> >> >> >>
> >> >> >> The first patch is indeed unrelated. I will pick it up so we can
> drop
> >> >> >> it for the next rev.
> >> >> >>
> >> >> [..]
> >> >>
> >> >> Regards,
> >> >> Simon
> >> >
> >> >
> >> >
> >> > --
> >> > François-Frédéric Ozog | Director Business Development
> >> > T: +33.67221.6485
> >> > francois.ozog@linaro.org | Skype: ffozog
> >> >
> >
> > --
> > François-Frédéric Ozog | Director Business Development
> > T: +33.67221.6485
> > francois.ozog@linaro.org | Skype: ffozog
> >
>


-- 
François-Frédéric Ozog | *Director Business Development*
T: +33.67221.6485
francois.ozog@linaro.org | Skype: ffozog

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 00/31] passage: Define a standard for firmware data flow
@ 2021-11-08 16:20                   ` François Ozog
  0 siblings, 0 replies; 77+ messages in thread
From: François Ozog @ 2021-11-08 16:20 UTC (permalink / raw)
  To: Simon Glass
  Cc: Marek Vasut, Albert Aribaud, Tom Rini, U-Boot Mailing List,
	Heinrich Schuchardt, Bill Mills, Ilias Apalodimas,
	QEMU Developers, Masahiro Yamada, Jerry Van Baren, Bin Meng,
	Pavel Herrmann

[-- Attachment #1: Type: text/plain, Size: 19715 bytes --]

On Fri, 5 Nov 2021 at 18:17, Simon Glass <sjg@chromium.org> wrote:

> ) to signal Hi François,
>
> On Fri, 5 Nov 2021 at 10:31, François Ozog <francois.ozog@linaro.org>
> wrote:
> >
> > Hi Simon,
> >
> > Le ven. 5 nov. 2021 à 17:12, Simon Glass <sjg@chromium.org> a écrit :
> >>
> >> Hi François,
> >>
> >> On Fri, 5 Nov 2021 at 02:27, François Ozog <francois.ozog@linaro.org>
> wrote:
> >> >
> >> >
> >> >
> >> > On Fri, 5 Nov 2021 at 03:02, Simon Glass <sjg@chromium.org> wrote:
> >> >>
> >> >> Hi François,
> >> >>
> >> >> On Tue, 2 Nov 2021 at 10:03, François Ozog <francois.ozog@linaro.org>
> wrote:
> >> >> >
> >> >> > Hi Simon,
> >> >> >
> >> >> > On Tue, 2 Nov 2021 at 15:59, Simon Glass <sjg@chromium.org> wrote:
> >> >> >>
> >> >> >> Hi François,
> >> >> >>
> >> >> >> On Mon, 1 Nov 2021 at 02:53, François Ozog <
> francois.ozog@linaro.org> wrote:
> >> >> >> >
> >> >> >> > Hi Simon,
> >> >> >> >
> >> >> >> > this seems a great endeavor. I'd like to better understand the
> scope of it.
> >> >> >> >
> >> >> >> > Is it to be used as part of what could become a U-Boot entry
> ABI scheme? By that I mean giving some fixed aspects
> >> >> >> > to U-Boot entry while letting boards to have flexibility (say
> for instance that the first 5 architecture ABI
> >> >> >> > parameter registers are reserved for U-Boot), and the Passage
> is about specifying either those reserved registers
> >> >> >> > or one of them?
> >> >> >>
> >> >> >> The goal is to provide a standard entry scheme for all firmware
> >> >> >> binaries. Whether it achieves that (or can with some mods) is up
> for
> >> >> >> discussion.
> >> >> >>
> >> >> > If you say
> >> >> > a) define a U-Boot entry ABI and providing a firmware-to-firmware
> information passing facility which would be part of all firmware ABIs (as
> the projects decide to define their own ABI) it looks good.
> >> >> > but If you say
> >> >>
> >> >> It is an ABI to be adopted by U-Boot but also other firmware. For
> >> >> example, if TF-A calls U-Boot it should use standard passage. If
> >> >> U-Boot calls TF-A or Optee it should use standard passage.
> >> >>
> >> >> > b) define a standard entry scheme (register map, processor state,
> MMU state, SMMU state, GIC state...) that does not look realistic.
> >> >>
> >> >> No I don't mean that. This data structure could be used in any state,
> >> >> so long as the two registers are set correctly.
> >> >>
> >> >> > I think you mean a) but just want to be sure.
> >> >>
> >> >> Yes I think so.
> >> >>
> >> >> >>
> >> >> >> Re the registers, do you think we need 5?
> >> >> >>
> >> >>
> >> >> I don't :-)
> >> >>
> >> >> >> >
> >> >> >> > Thinking entry ABI, here is what I observed on Arm:
> >> >> >> >
> >> >> >> > Linux has two entry ABIs:
> >> >> >> > - plain: x0 = dtb;
> >> >> >> >           command line = dtb:/chosen/bootargs; initrd =
> dtb:/chosen/linux,initrd-*
> >> >> >> > - EFI: x0=handle, x1=systemtable, x30=return address;
> >> >> >> >            dtb = EFI_UUID config table; initrd =
> efi:<loadfile2(INITRD vendor media UUID); command line = efi:
> image_protocol::load_options
> >> >> >> >
> >> >> >> > U-Boot (proper) has plenty of schemes:
> >> >> >> > - dtb is passed as either x0, x1, fixed memory area (Qemu which
> is bad in itself), or other registers
> >> >> >> > - additional information passing: board specific register
> scheme, SMC calls
> >> >> >> > - U-Boot for RPI boards implement a Linux shaped entry ABI to
> be launched by Videocore firmware
> >> >> >> >
> >> >> >> > Based on all the above, I would tend to think that RPI scheme
> is a good idea but also
> >> >> >> > shall not prevent additional schemes for the boards.
> >> >> >>
> >> >> >> I was not actually considering Linux since I believe/assume its
> entry
> >> >> >> scheme is fixed and not up for discussion.
> >> >> >>
> >> >> >> I also did not think about the EFI case. As I understand it we
> cannot
> >> >> >> touch it as it is used by UEFI today. Maybe it is even in the
> >> >> >> standard?
> >> >> >
> >> >> > It is in the spec and we are making it evolve, or its
> understanding evolve (jurisprudence) for instance on initrd standard
> handling.
> >> >>
> >> >> Well perhaps we could merge it with standard passage. But EFI is not
> >> >> going to want to use a bloblist, it will want to use a HOB.
> >> >>
> >> >> >>
> >> >> >>
> >> >> >> Really I am hoping we can start afresh...?
> >> >> >>
> >> >> >> >
> >> >> >> > What about a U-Boot Arm entry ABI like:
> >> >> >> > - plain: x0=dtb, x1=<Passage defined>, x2-x5 = <reserved>,
> other registers are per platform, SMC calls allowed too
> >> >> >>
> >> >> >> Hmm we don't actually need the dtb as it is available in the
> bloblist.
> >> >> >
> >> >> > If you don't have x0=dtb, then you will not be able to use U-Boot
> on RPI4.
> >> >> > Unless you want to redo everything the RPI firmware is doing.
> >> >>
> >> >> That's right, RPI cannot support standard passage. It is not
> >> >> open-source firmware so it isn't really relevant to this discussion.
> >> >> It will just do what it does and have limited functionality, with
> >> >> work-arounds to deal with the pain, as one might expect.
> >> >>
> >> > So you are seeing two "all-or-nothing" options:
> >> > <specific>: U-Boot entry is board specific as it is today
> >> > <purepassage>: A new form where the only parameter is a head of
> bloblist, one of those blobs contain a DT
> >> >  You propose to mandate a DT for all boards make sense in that
> environment.
> >> > For RPI4, you just ignore everything the prior boot loader does
> because it is not <passage> compliant.
> >>
> >> It's not that. It's just that it is closed-source, so not relevant to
> >> the discussion here. They could open-source it and then we could
> >> consider it, but it has been closed-source for years now, so why would
> >> we think that would happen?
> >>
> >> >
> >> > This reinforces my opposition to the mandatory DT proposal.
> >> >
> >> > a third option is I think way more attractive:
> >> > <optpassage>: shaped after the architecture Linux entry (ie. first
> parameter is dtb) [+ passage head (i.e. second parameter is pointer to
> passage head)]
> >> >
> >> > This way, you make U-Boot entry clean in RPI4, Apple M1, Qemu,
> SystemReady contexts
> >> > and get a well deserved standardized information passing between
> prior loaders and U-Boot.
> >> >
> >> > The three options are possible though, you could select a U-Boot
> entry CONFIG option for:
> >> > <specific>
> >> > <optpassage>
> >> > <purepassage>
> >> >
> >> > But despite it would be technically feasible, I don't think it is
> goes in the right direction.
> >>
> >> OK. Do you think we need a separate devicetree pointer, rather than
> >> forcing it to be inside the created bloblist?
> >>
> >> I'd like to understand what problem you are solving with this. I am
> >> trying to figure out a firmware-to-firmware mini-ABI (just a few
> >> register values) that can be used in open-source projects. The ABI is
> >> not intended to be used with Linux (I am unsure of the benefit it
> >> would give and whether it is feasible to change the current one).
> >>
> >> You are talking about the Linux entry mechanism. What relevance does
> >> that have for firmware?
> >>
> >> I understand that some projects already implement the Linux mechanism,
> >> but that is because they expect to jump straight to Linux, not have
> >> U-Boot in the path. So IMO standard passage offers no benefit to them.
> >>
> >> To address them in turn:
> >> - rpi4 - closed source, who cares?
> >> - Apple M1 - we could probably expand it to pass a bloblist, but it
> >> would be confusing unless we share registers, as you suggest
> >> - Qemu - I already tried to update that and got pushback...do you
> >> really think those guys are going to want to add a bloblist? So again,
> >> who cares?
> >> - SystemReady - not sure what this means in practice, but it would be
> >> good if SystemReady could use standard passage
> >>
> >> So let's say we have an optional standard-passage thing and we use
> >> registers such that it is similar to Linux and EFI and just expands on
> >> them.
> >>
> >> The first problem is that Linux and EFI seem to be completely
> >> incompatible. Can that be changed, perhaps on the EFI side? If not,
> >> we need two separate protocols.
> >>
> >> I'll ignore EFI for now. So we might have:
> >>
> >> r0 = 0
> >> r1 = machine number (0?)
> >> r2 = dtb pointer
> >> r3 = bloblist pointer, 0 if missing
> >> r14 = return address
> >>
> >> or
> >>
> >> x0 = dtb
> >> x1 = bloblist pointer, 0 if missing
> >> x30 = return address
> >
> > That’s essentially what I proposed!
> > you do not force the DTB to be found in the bloblist, and shape the
> U-Boot entry after the Linux entry ABI. Good !
> > I was saving a few registers for future ABI evolution so that boards can
> be guaranteed to have their board specific registers properly protected.
> The 5 registers, leaving 3 undefined was just « why not ». We could also
> have a cookie in x1: high 48 bits magic low 16 ABI version, x2=bloblist
> pointer.
>
> Isn't 32 bits enough for a magic value?
>
> Also x3 might be nicer, to match ARM 32-bit, so:
>
> x0 = dtb
> x1 = ABI indicator bits 63:32 0xb00757a3, bits 31:1 = 0, bit 0 = 1
> (version 1) ? We don't need to decide how many bits for the version
> right now. Perhaps 8 is plenty
> x2 = 0
> x3 = bloblist pointer, 0 if missing
> x4 = 0
> x30 = return address
>
> sounds usable. Need more comments on this.


> For ARM:
>
> r0 = 0
> r1 = machine number (0xb00757xx to signal standard passage where xx is
> the ABI version?)*
> r2 = dtb pointer
> r3 = bloblist pointer (if r1 is 0xb00757xx), else 0
> r4 = 0
> r14 = return address
>
> * might be safe, looking at
>
> https://elixir.bootlin.com/linux/latest/source/arch/arm/kernel/setup.c#L1094
>
> Indeed. Need more comments on this.



> >
> >>
> >> For EFI, we could add a blob to the bloblist containing the system
> >> table and handle, perhaps? Otherwise:
> >>
> >> x2 - efi handle
> >> x3 - system table
> >>
> >> Is that along the lines of what you are thinking?
> >
> > No, efi entry is only x0=efi handle, x1=system table . I was trying to
> find a way to have passage when U-Boot is loaded as a UEFI app (your other
> patch set to make U-Boot a more integrated UEFi app). Let’s say that a
> U-Boot aware DXE driver/protocol actually populate such a table, it could
> be a communication channel between that driver and U-Boot.
>
> OK, I figured, so how about, for EFI on 64-bit:
>
> x0 = handle
> x1 = systable
> x2 = ABI indicator bits 63:32 0xb00757a3, bits 31:1 = 0, bit 0 = 1
> (version 1)
> x3 = bloblist pointer
> x4 = 0
> x30 = return address
>
> EFI 32-bit:
>
> r0 = handle
> r1 = systable
> r2 = 0xb00757a3
> r3 = bloblist pointer
> r4 = 0
> r14 = return address
>
> Let's be clear that this is for an existing UEFI implementation to boot
U-Boot.
If the implementation cannot be changed to add the information, a UEFI
driver or protocol may be used.
Could SPL may be tweaked to craft the bloblist based on whatever
information I that case?

(side comment: LinuxBoot has developed techniques to replace most of an
EDK2 implementation by Linux.
This entry ABI does not apply in this use case as it is defined by EDK2.)

Now on the how.

EFI API has already defined extension mechanism, so that may be difficult
to add.

let's put the bloblist pointer in a <configtable>:

 typedef struct {
1936  ///
1937  /// The 128-bit GUID value that uniquely identifies the system
configuration table.
1938  ///
1939
<https://dox.ipxe.org/structEFI__CONFIGURATION__TABLE.html#a50a67cc76cea0a08e7fcfc868ea8a02f>
  EFI_GUID <https://dox.ipxe.org/structGUID.html> VendorGuid
<https://dox.ipxe.org/structEFI__CONFIGURATION__TABLE.html#a50a67cc76cea0a08e7fcfc868ea8a02f>;
/* set to BLOB_LIST_GUID */
1940  ///
1941  /// A pointer to the table associated with VendorGuid.
1942  ///
1943
<https://dox.ipxe.org/structEFI__CONFIGURATION__TABLE.html#a1acfe9c046bb4d3a1e7d0e3c7c06f11b>
  VOID <https://dox.ipxe.org/Base_8h.html#a7f319bfc2492a2136964194204e7a8cf>
*VendorTable
<https://dox.ipxe.org/structEFI__CONFIGURATION__TABLE.html#a1acfe9c046bb4d3a1e7d0e3c7c06f11b>;
/* bloblist pointer */
1944 } EFI_CONFIGURATION_TABLE
<https://dox.ipxe.org/structEFI__CONFIGURATION__TABLE.html>;

U-Boot or a driver or a protocol can set the VendorTable to bloblist
pointer and add this to the list of configuration tables via
https://edk2-docs.gitbook.io/edk-ii-uefi-driver-writer-s-guide/5_uefi_services/readme.2/5210_installconfigurationtable

The blobs should be already accounted for in the memory map as they were
pre-allocated before U-Boot entry. But that may be a topic to be checked.


Regards,
> Simon
>
> >>
> >>
> >> But still, please respond above so I can understand what problem you
> >> are worried about.
> >>
> >> Regards,
> >> Simon
> >>
> >>
> >> >
> >> >> >>
> >> >> >> But I added an offset to it as a convenience.
> >> >> >>
> >> >> >> > - EFI: x0=handle, x1=systemtable, x30=return address;  (when
> U-Boot is launched as an EFI app)
> >> >> >> >        dtb = EFI_UUID config table, + Passage = Passage UUID
> config table
> >> >> >>
> >> >> >> I don't understand the last line. Where is the passage info /
> >> >> >> bloblist? Do you mean it goes in the HOB list with a UUID? I
> suppose
> >> >> >> that is the most EFI-compatible way.
> >> >> >
> >> >> > The Passage config table  could just contain the "head" of the
> bloblist/Passage information.
> >> >>
> >> >> If UEFI wants to deal with standard passage, that is...
> >> >>
> >> >> >>
> >> >> >>
> >> >> >> What do you think about the idea of using an offset into the
> bloblist
> >> >> >> for the dtb?
> >> >> >
> >> >> > It is possible but as I said, failing to mimic Linux entry ABI
> would miss the opportunity to just boot without changes on RPI4.
> >> >>
> >> >> See above. Broadcom could look at open-sourcing their bootloader if
> they wish.
> >> >>
> >> >> >>
> >> >> >> Also, can we make the standard passage ABI a build-time
> >> >> >> option, so it is deterministic?
> >> >> >>
> >> >> > Looks good. I would look into stating that for SystemReady we
> would advise to use that option and make it standard for Trusted Substrate
> (Linaro recipes that we upstreaming to make SystemReady compliance easy and
> consistent across platforms).
> >> >>
> >> >> OK. I mean that if the option is enabled, then standard passage must
> >> >> be provided / emitted or things won't work. If the option is
> disabled,
> >> >> then standard passage is not used. In other words, we are looking for
> >> >> magic values in registers, etc, just enabling/disabling it at
> >> >> build-time.
> >> >>
> >> >> >>
> >> >> >> >
> >> >> >> > We could further leverage Passage to pass Operating Systems
> parameters that could be removed from device tree (migration of /chosen to
> Passage). Memory inventory would still be in DT but allocations for CMA or
> GPUs would be in Passage. This idea is to reach a point where  device tree
> is a "pristine" hardware description.
> >> >> >>
> >> >> >> I'm worried about this becoming a substitute for devicetree.
> Really my
> >> >> >> intent is to provide a way to pass simple info, whereas what you
> talk
> >> >> >> about there seems like something that should be DT, just that it
> might
> >> >> >> need suitable bindings.
> >> >> >>
> >> >> > I see your point and I agree It should not be a substitute.
> >> >> > here is an expanded version of what I had in mind when I wrote
> those lines.
> >> >> > cma, initrd and other Linux kernel parameters can be conveyed
> either through command line or DT.
> >> >> > When using the non UEFI Linux entry ABI, you need to use the DT to
> pass those parameters.
> >> >> > When using the UEFI Linux entry ABI, you *can* (not must) use the
> command line to pass all information, leaving the DT passed to the OS
> without any /chosen.
> >> >> > When introducing Passage, I was wondering if we could pass command
> line to Linux and, same as UEFI, leave the DT free from /chosen.
> >> >> > I am not sure it is a good goal though. I may be too pushing for a
> DT free from parameters.
> >> >>
> >> >> We could. Are there benefits to that?
> >> >>
> >> >> I doubt we would pass the standard passage to Linux as a bloblist. I
> >> >> imagine something like this. The bloblist sits in memory with some
> >> >> things in it, including a devicetree, perhaps an SMBIOS table and a
> >> >> TPM log. But when U-Boot calls Linux it puts the address/size of
> those
> >> >> individual things in the devicetree. They don't move and are still
> >> >> contiguous in memory, but the bloblist around them is forgotten.
> Linux
> >> >> doesn't know that the three separate things it is picking up are
> >> >> actually part of a bloblist structure, since it doesn't care about
> >> >> that. Even a console log could work the same way. That way we don't
> >> >> end up trying to teach Linux about bloblist when it already has a
> >> >> perfectly good means to accept these items.
> >> >>
> >> >> For ACPI I see things a similar way. The ACPI tables can point to
> >> >> things that *happen* to be in a bloblist, but without any knowledge
> of
> >> >> that needed in Linux, grub, etc.
> >> >>
> >> >> >>
> >> >> >> As you know I have more expansive views about what should be in
> DT.
> >> >> >
> >> >> > I think both of us are huge supporters of DT format and self
> describing capabilities.
> >> >> > I am inclined to put rules into what fits into what lands in the
> DT that is passed to the OS.
> >> >> > I am a fan of having DT used more in ad-hoc files.
> >> >>
> >> >> Me too.
> >> >>
> >> >> >>
> >> >> >> >
> >> >> >> > Cheers
> >> >> >> >
> >> >> >> > PS: as Ilias mentions, this patch set contains bug fixes, non
> immediately related additional functions (DM stats). It would be great to
> carve those out to fast path them and keep this one with the very core of
> your idea.
> >> >> >>
> >> >> >> The DM stats is used in 'passage: Report the devicetree source'. I
> >> >> >> know it is sideways but I think it is better to make the output
> line
> >> >> >> more useful than just reporting the devicetree source.
> >> >> >>
> >> >> > I believe the DM stats has merits in its own. You could upstream
> this independently and then Passage would be yet another "customer" of the
> feature.
> >> >>
> >> >> I could, but it would just be a debug feature so people might not
> >> >> think it worth the code space. With the devicetree source it is more
> >> >> compelling.
> >> >>
> >> >> >>
> >> >> >> The first patch is indeed unrelated. I will pick it up so we can
> drop
> >> >> >> it for the next rev.
> >> >> >>
> >> >> [..]
> >> >>
> >> >> Regards,
> >> >> Simon
> >> >
> >> >
> >> >
> >> > --
> >> > François-Frédéric Ozog | Director Business Development
> >> > T: +33.67221.6485
> >> > francois.ozog@linaro.org | Skype: ffozog
> >> >
> >
> > --
> > François-Frédéric Ozog | Director Business Development
> > T: +33.67221.6485
> > francois.ozog@linaro.org | Skype: ffozog
> >
>


-- 
François-Frédéric Ozog | *Director Business Development*
T: +33.67221.6485
francois.ozog@linaro.org | Skype: ffozog

[-- Attachment #2: Type: text/html, Size: 34583 bytes --]

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 00/31] passage: Define a standard for firmware data flow
  2021-11-08 16:20                   ` François Ozog
@ 2021-11-10 19:37                     ` Simon Glass
  -1 siblings, 0 replies; 77+ messages in thread
From: Simon Glass @ 2021-11-10 19:37 UTC (permalink / raw)
  To: François Ozog
  Cc: Albert Aribaud, Bill Mills, Bin Meng, Heinrich Schuchardt,
	Ilias Apalodimas, Jerry Van Baren, Marek Vasut, Masahiro Yamada,
	Pavel Herrmann, QEMU Developers, Tom Rini, U-Boot Mailing List

Hi François,

On Mon, 8 Nov 2021 at 09:20, François Ozog <francois.ozog@linaro.org> wrote:
>
>
>
> On Fri, 5 Nov 2021 at 18:17, Simon Glass <sjg@chromium.org> wrote:
>>
>> ) to signal Hi François,
>>
>> On Fri, 5 Nov 2021 at 10:31, François Ozog <francois.ozog@linaro.org> wrote:
>> >
>> > Hi Simon,
>> >
>> > Le ven. 5 nov. 2021 à 17:12, Simon Glass <sjg@chromium.org> a écrit :
>> >>
>> >> Hi François,
>> >>
>> >> On Fri, 5 Nov 2021 at 02:27, François Ozog <francois.ozog@linaro.org> wrote:
>> >> >
>> >> >
>> >> >
>> >> > On Fri, 5 Nov 2021 at 03:02, Simon Glass <sjg@chromium.org> wrote:
>> >> >>
>> >> >> Hi François,
>> >> >>
>> >> >> On Tue, 2 Nov 2021 at 10:03, François Ozog <francois.ozog@linaro.org> wrote:
>> >> >> >
>> >> >> > Hi Simon,
>> >> >> >
>> >> >> > On Tue, 2 Nov 2021 at 15:59, Simon Glass <sjg@chromium.org> wrote:
>> >> >> >>
>> >> >> >> Hi François,
>> >> >> >>
>> >> >> >> On Mon, 1 Nov 2021 at 02:53, François Ozog <francois.ozog@linaro.org> wrote:
>> >> >> >> >
>> >> >> >> > Hi Simon,
>> >> >> >> >
>> >> >> >> > this seems a great endeavor. I'd like to better understand the scope of it.
>> >> >> >> >
>> >> >> >> > Is it to be used as part of what could become a U-Boot entry ABI scheme? By that I mean giving some fixed aspects
>> >> >> >> > to U-Boot entry while letting boards to have flexibility (say for instance that the first 5 architecture ABI
>> >> >> >> > parameter registers are reserved for U-Boot), and the Passage is about specifying either those reserved registers
>> >> >> >> > or one of them?
>> >> >> >>
>> >> >> >> The goal is to provide a standard entry scheme for all firmware
>> >> >> >> binaries. Whether it achieves that (or can with some mods) is up for
>> >> >> >> discussion.
>> >> >> >>
>> >> >> > If you say
>> >> >> > a) define a U-Boot entry ABI and providing a firmware-to-firmware information passing facility which would be part of all firmware ABIs (as the projects decide to define their own ABI) it looks good.
>> >> >> > but If you say
>> >> >>
>> >> >> It is an ABI to be adopted by U-Boot but also other firmware. For
>> >> >> example, if TF-A calls U-Boot it should use standard passage. If
>> >> >> U-Boot calls TF-A or Optee it should use standard passage.
>> >> >>
>> >> >> > b) define a standard entry scheme (register map, processor state, MMU state, SMMU state, GIC state...) that does not look realistic.
>> >> >>
>> >> >> No I don't mean that. This data structure could be used in any state,
>> >> >> so long as the two registers are set correctly.
>> >> >>
>> >> >> > I think you mean a) but just want to be sure.
>> >> >>
>> >> >> Yes I think so.
>> >> >>
>> >> >> >>
>> >> >> >> Re the registers, do you think we need 5?
>> >> >> >>
>> >> >>
>> >> >> I don't :-)
>> >> >>
>> >> >> >> >
>> >> >> >> > Thinking entry ABI, here is what I observed on Arm:
>> >> >> >> >
>> >> >> >> > Linux has two entry ABIs:
>> >> >> >> > - plain: x0 = dtb;
>> >> >> >> >           command line = dtb:/chosen/bootargs; initrd = dtb:/chosen/linux,initrd-*
>> >> >> >> > - EFI: x0=handle, x1=systemtable, x30=return address;
>> >> >> >> >            dtb = EFI_UUID config table; initrd = efi:<loadfile2(INITRD vendor media UUID); command line = efi: image_protocol::load_options
>> >> >> >> >
>> >> >> >> > U-Boot (proper) has plenty of schemes:
>> >> >> >> > - dtb is passed as either x0, x1, fixed memory area (Qemu which is bad in itself), or other registers
>> >> >> >> > - additional information passing: board specific register scheme, SMC calls
>> >> >> >> > - U-Boot for RPI boards implement a Linux shaped entry ABI to be launched by Videocore firmware
>> >> >> >> >
>> >> >> >> > Based on all the above, I would tend to think that RPI scheme is a good idea but also
>> >> >> >> > shall not prevent additional schemes for the boards.
>> >> >> >>
>> >> >> >> I was not actually considering Linux since I believe/assume its entry
>> >> >> >> scheme is fixed and not up for discussion.
>> >> >> >>
>> >> >> >> I also did not think about the EFI case. As I understand it we cannot
>> >> >> >> touch it as it is used by UEFI today. Maybe it is even in the
>> >> >> >> standard?
>> >> >> >
>> >> >> > It is in the spec and we are making it evolve, or its understanding evolve (jurisprudence) for instance on initrd standard handling.
>> >> >>
>> >> >> Well perhaps we could merge it with standard passage. But EFI is not
>> >> >> going to want to use a bloblist, it will want to use a HOB.
>> >> >>
>> >> >> >>
>> >> >> >>
>> >> >> >> Really I am hoping we can start afresh...?
>> >> >> >>
>> >> >> >> >
>> >> >> >> > What about a U-Boot Arm entry ABI like:
>> >> >> >> > - plain: x0=dtb, x1=<Passage defined>, x2-x5 = <reserved>, other registers are per platform, SMC calls allowed too
>> >> >> >>
>> >> >> >> Hmm we don't actually need the dtb as it is available in the bloblist.
>> >> >> >
>> >> >> > If you don't have x0=dtb, then you will not be able to use U-Boot on RPI4.
>> >> >> > Unless you want to redo everything the RPI firmware is doing.
>> >> >>
>> >> >> That's right, RPI cannot support standard passage. It is not
>> >> >> open-source firmware so it isn't really relevant to this discussion.
>> >> >> It will just do what it does and have limited functionality, with
>> >> >> work-arounds to deal with the pain, as one might expect.
>> >> >>
>> >> > So you are seeing two "all-or-nothing" options:
>> >> > <specific>: U-Boot entry is board specific as it is today
>> >> > <purepassage>: A new form where the only parameter is a head of bloblist, one of those blobs contain a DT
>> >> >  You propose to mandate a DT for all boards make sense in that environment.
>> >> > For RPI4, you just ignore everything the prior boot loader does because it is not <passage> compliant.
>> >>
>> >> It's not that. It's just that it is closed-source, so not relevant to
>> >> the discussion here. They could open-source it and then we could
>> >> consider it, but it has been closed-source for years now, so why would
>> >> we think that would happen?
>> >>
>> >> >
>> >> > This reinforces my opposition to the mandatory DT proposal.
>> >> >
>> >> > a third option is I think way more attractive:
>> >> > <optpassage>: shaped after the architecture Linux entry (ie. first parameter is dtb) [+ passage head (i.e. second parameter is pointer to passage head)]
>> >> >
>> >> > This way, you make U-Boot entry clean in RPI4, Apple M1, Qemu, SystemReady contexts
>> >> > and get a well deserved standardized information passing between prior loaders and U-Boot.
>> >> >
>> >> > The three options are possible though, you could select a U-Boot entry CONFIG option for:
>> >> > <specific>
>> >> > <optpassage>
>> >> > <purepassage>
>> >> >
>> >> > But despite it would be technically feasible, I don't think it is goes in the right direction.
>> >>
>> >> OK. Do you think we need a separate devicetree pointer, rather than
>> >> forcing it to be inside the created bloblist?
>> >>
>> >> I'd like to understand what problem you are solving with this. I am
>> >> trying to figure out a firmware-to-firmware mini-ABI (just a few
>> >> register values) that can be used in open-source projects. The ABI is
>> >> not intended to be used with Linux (I am unsure of the benefit it
>> >> would give and whether it is feasible to change the current one).
>> >>
>> >> You are talking about the Linux entry mechanism. What relevance does
>> >> that have for firmware?
>> >>
>> >> I understand that some projects already implement the Linux mechanism,
>> >> but that is because they expect to jump straight to Linux, not have
>> >> U-Boot in the path. So IMO standard passage offers no benefit to them.
>> >>
>> >> To address them in turn:
>> >> - rpi4 - closed source, who cares?
>> >> - Apple M1 - we could probably expand it to pass a bloblist, but it
>> >> would be confusing unless we share registers, as you suggest
>> >> - Qemu - I already tried to update that and got pushback...do you
>> >> really think those guys are going to want to add a bloblist? So again,
>> >> who cares?
>> >> - SystemReady - not sure what this means in practice, but it would be
>> >> good if SystemReady could use standard passage
>> >>
>> >> So let's say we have an optional standard-passage thing and we use
>> >> registers such that it is similar to Linux and EFI and just expands on
>> >> them.
>> >>
>> >> The first problem is that Linux and EFI seem to be completely
>> >> incompatible. Can that be changed, perhaps on the EFI side? If not,
>> >> we need two separate protocols.
>> >>
>> >> I'll ignore EFI for now. So we might have:
>> >>
>> >> r0 = 0
>> >> r1 = machine number (0?)
>> >> r2 = dtb pointer
>> >> r3 = bloblist pointer, 0 if missing
>> >> r14 = return address
>> >>
>> >> or
>> >>
>> >> x0 = dtb
>> >> x1 = bloblist pointer, 0 if missing
>> >> x30 = return address
>> >
>> > That’s essentially what I proposed!
>> > you do not force the DTB to be found in the bloblist, and shape the U-Boot entry after the Linux entry ABI. Good !
>> > I was saving a few registers for future ABI evolution so that boards can be guaranteed to have their board specific registers properly protected. The 5 registers, leaving 3 undefined was just « why not ». We could also have a cookie in x1: high 48 bits magic low 16 ABI version, x2=bloblist pointer.
>>
>> Isn't 32 bits enough for a magic value?
>>
>> Also x3 might be nicer, to match ARM 32-bit, so:
>>
>> x0 = dtb
>> x1 = ABI indicator bits 63:32 0xb00757a3, bits 31:1 = 0, bit 0 = 1
>> (version 1) ? We don't need to decide how many bits for the version
>> right now. Perhaps 8 is plenty
>> x2 = 0
>> x3 = bloblist pointer, 0 if missing
>> x4 = 0
>> x30 = return address
>>
> sounds usable. Need more comments on this.
>
>>
>> For ARM:
>>
>> r0 = 0
>> r1 = machine number (0xb00757xx to signal standard passage where xx is
>> the ABI version?)*
>> r2 = dtb pointer
>> r3 = bloblist pointer (if r1 is 0xb00757xx), else 0
>> r4 = 0
>> r14 = return address
>>
>> * might be safe, looking at
>> https://elixir.bootlin.com/linux/latest/source/arch/arm/kernel/setup.c#L1094
>>
> Indeed. Need more comments on this.
>
>
>>
>> >
>> >>
>> >> For EFI, we could add a blob to the bloblist containing the system
>> >> table and handle, perhaps? Otherwise:
>> >>
>> >> x2 - efi handle
>> >> x3 - system table
>> >>
>> >> Is that along the lines of what you are thinking?
>> >
>> > No, efi entry is only x0=efi handle, x1=system table . I was trying to find a way to have passage when U-Boot is loaded as a UEFI app (your other patch set to make U-Boot a more integrated UEFi app). Let’s say that a U-Boot aware DXE driver/protocol actually populate such a table, it could be a communication channel between that driver and U-Boot.
>>
>> OK, I figured, so how about, for EFI on 64-bit:
>>
>> x0 = handle
>> x1 = systable
>> x2 = ABI indicator bits 63:32 0xb00757a3, bits 31:1 = 0, bit 0 = 1 (version 1)
>> x3 = bloblist pointer
>> x4 = 0
>> x30 = return address
>>
>> EFI 32-bit:
>>
>> r0 = handle
>> r1 = systable
>> r2 = 0xb00757a3
>> r3 = bloblist pointer
>> r4 = 0
>> r14 = return address
>>
> Let's be clear that this is for an existing UEFI implementation to boot U-Boot.
> If the implementation cannot be changed to add the information, a UEFI driver or protocol may be used.
> Could SPL may be tweaked to craft the bloblist based on whatever information I that case?

Yes that is easy enough, but then how does SPL load U-Boot? UEFI
requires an efl file and we don't want to put the EFI app into SPL, I
think.

>
> (side comment: LinuxBoot has developed techniques to replace most of an EDK2 implementation by Linux.
> This entry ABI does not apply in this use case as it is defined by EDK2.)
>
> Now on the how.
>
> EFI API has already defined extension mechanism, so that may be difficult to add.
>
> let's put the bloblist pointer in a <configtable>:
>
>  typedef struct {
> 1936  ///
> 1937  /// The 128-bit GUID value that uniquely identifies the system configuration table.
> 1938  ///
> 1939  EFI_GUID VendorGuid; /* set to BLOB_LIST_GUID */
> 1940  ///
> 1941  /// A pointer to the table associated with VendorGuid.
> 1942  ///
> 1943  VOID *VendorTable; /* bloblist pointer */
> 1944 } EFI_CONFIGURATION_TABLE;
>
> U-Boot or a driver or a protocol can set the VendorTable to bloblist pointer and add this to the list of configuration tables via
> https://edk2-docs.gitbook.io/edk-ii-uefi-driver-writer-s-guide/5_uefi_services/readme.2/5210_installconfigurationtable
>
> The blobs should be already accounted for in the memory map as they were pre-allocated before U-Boot entry. But that may be a topic to be checked.

OK, well in that case I suppose we don't need to define it here? Or
are you saying that we should define this as an alternative way to get
the bloblist?

Everything we define, we need tests for, so I want to make sure only
useful cases are included.

Regards,
Simon


>
>
>> Regards,
>> Simon
>>
>> >>
>> >>
>> >> But still, please respond above so I can understand what problem you
>> >> are worried about.
>> >>
>> >> Regards,
>> >> Simon
>> >>
>> >>
>> >> >
>> >> >> >>
>> >> >> >> But I added an offset to it as a convenience.
>> >> >> >>
>> >> >> >> > - EFI: x0=handle, x1=systemtable, x30=return address;  (when U-Boot is launched as an EFI app)
>> >> >> >> >        dtb = EFI_UUID config table, + Passage = Passage UUID config table
>> >> >> >>
>> >> >> >> I don't understand the last line. Where is the passage info /
>> >> >> >> bloblist? Do you mean it goes in the HOB list with a UUID? I suppose
>> >> >> >> that is the most EFI-compatible way.
>> >> >> >
>> >> >> > The Passage config table  could just contain the "head" of the bloblist/Passage information.
>> >> >>
>> >> >> If UEFI wants to deal with standard passage, that is...
>> >> >>
>> >> >> >>
>> >> >> >>
>> >> >> >> What do you think about the idea of using an offset into the bloblist
>> >> >> >> for the dtb?
>> >> >> >
>> >> >> > It is possible but as I said, failing to mimic Linux entry ABI would miss the opportunity to just boot without changes on RPI4.
>> >> >>
>> >> >> See above. Broadcom could look at open-sourcing their bootloader if they wish.
>> >> >>
>> >> >> >>
>> >> >> >> Also, can we make the standard passage ABI a build-time
>> >> >> >> option, so it is deterministic?
>> >> >> >>
>> >> >> > Looks good. I would look into stating that for SystemReady we would advise to use that option and make it standard for Trusted Substrate (Linaro recipes that we upstreaming to make SystemReady compliance easy and consistent across platforms).
>> >> >>
>> >> >> OK. I mean that if the option is enabled, then standard passage must
>> >> >> be provided / emitted or things won't work. If the option is disabled,
>> >> >> then standard passage is not used. In other words, we are looking for
>> >> >> magic values in registers, etc, just enabling/disabling it at
>> >> >> build-time.
>> >> >>
>> >> >> >>
>> >> >> >> >
>> >> >> >> > We could further leverage Passage to pass Operating Systems parameters that could be removed from device tree (migration of /chosen to Passage). Memory inventory would still be in DT but allocations for CMA or GPUs would be in Passage. This idea is to reach a point where  device tree is a "pristine" hardware description.
>> >> >> >>
>> >> >> >> I'm worried about this becoming a substitute for devicetree. Really my
>> >> >> >> intent is to provide a way to pass simple info, whereas what you talk
>> >> >> >> about there seems like something that should be DT, just that it might
>> >> >> >> need suitable bindings.
>> >> >> >>
>> >> >> > I see your point and I agree It should not be a substitute.
>> >> >> > here is an expanded version of what I had in mind when I wrote those lines.
>> >> >> > cma, initrd and other Linux kernel parameters can be conveyed either through command line or DT.
>> >> >> > When using the non UEFI Linux entry ABI, you need to use the DT to pass those parameters.
>> >> >> > When using the UEFI Linux entry ABI, you *can* (not must) use the command line to pass all information, leaving the DT passed to the OS without any /chosen.
>> >> >> > When introducing Passage, I was wondering if we could pass command line to Linux and, same as UEFI, leave the DT free from /chosen.
>> >> >> > I am not sure it is a good goal though. I may be too pushing for a DT free from parameters.
>> >> >>
>> >> >> We could. Are there benefits to that?
>> >> >>
>> >> >> I doubt we would pass the standard passage to Linux as a bloblist. I
>> >> >> imagine something like this. The bloblist sits in memory with some
>> >> >> things in it, including a devicetree, perhaps an SMBIOS table and a
>> >> >> TPM log. But when U-Boot calls Linux it puts the address/size of those
>> >> >> individual things in the devicetree. They don't move and are still
>> >> >> contiguous in memory, but the bloblist around them is forgotten. Linux
>> >> >> doesn't know that the three separate things it is picking up are
>> >> >> actually part of a bloblist structure, since it doesn't care about
>> >> >> that. Even a console log could work the same way. That way we don't
>> >> >> end up trying to teach Linux about bloblist when it already has a
>> >> >> perfectly good means to accept these items.
>> >> >>
>> >> >> For ACPI I see things a similar way. The ACPI tables can point to
>> >> >> things that *happen* to be in a bloblist, but without any knowledge of
>> >> >> that needed in Linux, grub, etc.
>> >> >>
>> >> >> >>
>> >> >> >> As you know I have more expansive views about what should be in DT.
>> >> >> >
>> >> >> > I think both of us are huge supporters of DT format and self describing capabilities.
>> >> >> > I am inclined to put rules into what fits into what lands in the DT that is passed to the OS.
>> >> >> > I am a fan of having DT used more in ad-hoc files.
>> >> >>
>> >> >> Me too.
>> >> >>
>> >> >> >>
>> >> >> >> >
>> >> >> >> > Cheers
>> >> >> >> >
>> >> >> >> > PS: as Ilias mentions, this patch set contains bug fixes, non immediately related additional functions (DM stats). It would be great to carve those out to fast path them and keep this one with the very core of your idea.
>> >> >> >>
>> >> >> >> The DM stats is used in 'passage: Report the devicetree source'. I
>> >> >> >> know it is sideways but I think it is better to make the output line
>> >> >> >> more useful than just reporting the devicetree source.
>> >> >> >>
>> >> >> > I believe the DM stats has merits in its own. You could upstream this independently and then Passage would be yet another "customer" of the feature.
>> >> >>
>> >> >> I could, but it would just be a debug feature so people might not
>> >> >> think it worth the code space. With the devicetree source it is more
>> >> >> compelling.
>> >> >>
>> >> >> >>
>> >> >> >> The first patch is indeed unrelated. I will pick it up so we can drop
>> >> >> >> it for the next rev.
>> >> >> >>
>> >> >> [..]
>> >> >>
>> >> >> Regards,
>> >> >> Simon
>> >> >
>> >> >
>> >> >
>> >> > --
>> >> > François-Frédéric Ozog | Director Business Development
>> >> > T: +33.67221.6485
>> >> > francois.ozog@linaro.org | Skype: ffozog
>> >> >
>> >
>> > --
>> > François-Frédéric Ozog | Director Business Development
>> > T: +33.67221.6485
>> > francois.ozog@linaro.org | Skype: ffozog
>> >
>
>
>
> --
> François-Frédéric Ozog | Director Business Development
> T: +33.67221.6485
> francois.ozog@linaro.org | Skype: ffozog
>

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 00/31] passage: Define a standard for firmware data flow
@ 2021-11-10 19:37                     ` Simon Glass
  0 siblings, 0 replies; 77+ messages in thread
From: Simon Glass @ 2021-11-10 19:37 UTC (permalink / raw)
  To: François Ozog
  Cc: Marek Vasut, Albert Aribaud, Tom Rini, U-Boot Mailing List,
	Heinrich Schuchardt, Bill Mills, Ilias Apalodimas,
	QEMU Developers, Masahiro Yamada, Jerry Van Baren, Bin Meng,
	Pavel Herrmann

Hi François,

On Mon, 8 Nov 2021 at 09:20, François Ozog <francois.ozog@linaro.org> wrote:
>
>
>
> On Fri, 5 Nov 2021 at 18:17, Simon Glass <sjg@chromium.org> wrote:
>>
>> ) to signal Hi François,
>>
>> On Fri, 5 Nov 2021 at 10:31, François Ozog <francois.ozog@linaro.org> wrote:
>> >
>> > Hi Simon,
>> >
>> > Le ven. 5 nov. 2021 à 17:12, Simon Glass <sjg@chromium.org> a écrit :
>> >>
>> >> Hi François,
>> >>
>> >> On Fri, 5 Nov 2021 at 02:27, François Ozog <francois.ozog@linaro.org> wrote:
>> >> >
>> >> >
>> >> >
>> >> > On Fri, 5 Nov 2021 at 03:02, Simon Glass <sjg@chromium.org> wrote:
>> >> >>
>> >> >> Hi François,
>> >> >>
>> >> >> On Tue, 2 Nov 2021 at 10:03, François Ozog <francois.ozog@linaro.org> wrote:
>> >> >> >
>> >> >> > Hi Simon,
>> >> >> >
>> >> >> > On Tue, 2 Nov 2021 at 15:59, Simon Glass <sjg@chromium.org> wrote:
>> >> >> >>
>> >> >> >> Hi François,
>> >> >> >>
>> >> >> >> On Mon, 1 Nov 2021 at 02:53, François Ozog <francois.ozog@linaro.org> wrote:
>> >> >> >> >
>> >> >> >> > Hi Simon,
>> >> >> >> >
>> >> >> >> > this seems a great endeavor. I'd like to better understand the scope of it.
>> >> >> >> >
>> >> >> >> > Is it to be used as part of what could become a U-Boot entry ABI scheme? By that I mean giving some fixed aspects
>> >> >> >> > to U-Boot entry while letting boards to have flexibility (say for instance that the first 5 architecture ABI
>> >> >> >> > parameter registers are reserved for U-Boot), and the Passage is about specifying either those reserved registers
>> >> >> >> > or one of them?
>> >> >> >>
>> >> >> >> The goal is to provide a standard entry scheme for all firmware
>> >> >> >> binaries. Whether it achieves that (or can with some mods) is up for
>> >> >> >> discussion.
>> >> >> >>
>> >> >> > If you say
>> >> >> > a) define a U-Boot entry ABI and providing a firmware-to-firmware information passing facility which would be part of all firmware ABIs (as the projects decide to define their own ABI) it looks good.
>> >> >> > but If you say
>> >> >>
>> >> >> It is an ABI to be adopted by U-Boot but also other firmware. For
>> >> >> example, if TF-A calls U-Boot it should use standard passage. If
>> >> >> U-Boot calls TF-A or Optee it should use standard passage.
>> >> >>
>> >> >> > b) define a standard entry scheme (register map, processor state, MMU state, SMMU state, GIC state...) that does not look realistic.
>> >> >>
>> >> >> No I don't mean that. This data structure could be used in any state,
>> >> >> so long as the two registers are set correctly.
>> >> >>
>> >> >> > I think you mean a) but just want to be sure.
>> >> >>
>> >> >> Yes I think so.
>> >> >>
>> >> >> >>
>> >> >> >> Re the registers, do you think we need 5?
>> >> >> >>
>> >> >>
>> >> >> I don't :-)
>> >> >>
>> >> >> >> >
>> >> >> >> > Thinking entry ABI, here is what I observed on Arm:
>> >> >> >> >
>> >> >> >> > Linux has two entry ABIs:
>> >> >> >> > - plain: x0 = dtb;
>> >> >> >> >           command line = dtb:/chosen/bootargs; initrd = dtb:/chosen/linux,initrd-*
>> >> >> >> > - EFI: x0=handle, x1=systemtable, x30=return address;
>> >> >> >> >            dtb = EFI_UUID config table; initrd = efi:<loadfile2(INITRD vendor media UUID); command line = efi: image_protocol::load_options
>> >> >> >> >
>> >> >> >> > U-Boot (proper) has plenty of schemes:
>> >> >> >> > - dtb is passed as either x0, x1, fixed memory area (Qemu which is bad in itself), or other registers
>> >> >> >> > - additional information passing: board specific register scheme, SMC calls
>> >> >> >> > - U-Boot for RPI boards implement a Linux shaped entry ABI to be launched by Videocore firmware
>> >> >> >> >
>> >> >> >> > Based on all the above, I would tend to think that RPI scheme is a good idea but also
>> >> >> >> > shall not prevent additional schemes for the boards.
>> >> >> >>
>> >> >> >> I was not actually considering Linux since I believe/assume its entry
>> >> >> >> scheme is fixed and not up for discussion.
>> >> >> >>
>> >> >> >> I also did not think about the EFI case. As I understand it we cannot
>> >> >> >> touch it as it is used by UEFI today. Maybe it is even in the
>> >> >> >> standard?
>> >> >> >
>> >> >> > It is in the spec and we are making it evolve, or its understanding evolve (jurisprudence) for instance on initrd standard handling.
>> >> >>
>> >> >> Well perhaps we could merge it with standard passage. But EFI is not
>> >> >> going to want to use a bloblist, it will want to use a HOB.
>> >> >>
>> >> >> >>
>> >> >> >>
>> >> >> >> Really I am hoping we can start afresh...?
>> >> >> >>
>> >> >> >> >
>> >> >> >> > What about a U-Boot Arm entry ABI like:
>> >> >> >> > - plain: x0=dtb, x1=<Passage defined>, x2-x5 = <reserved>, other registers are per platform, SMC calls allowed too
>> >> >> >>
>> >> >> >> Hmm we don't actually need the dtb as it is available in the bloblist.
>> >> >> >
>> >> >> > If you don't have x0=dtb, then you will not be able to use U-Boot on RPI4.
>> >> >> > Unless you want to redo everything the RPI firmware is doing.
>> >> >>
>> >> >> That's right, RPI cannot support standard passage. It is not
>> >> >> open-source firmware so it isn't really relevant to this discussion.
>> >> >> It will just do what it does and have limited functionality, with
>> >> >> work-arounds to deal with the pain, as one might expect.
>> >> >>
>> >> > So you are seeing two "all-or-nothing" options:
>> >> > <specific>: U-Boot entry is board specific as it is today
>> >> > <purepassage>: A new form where the only parameter is a head of bloblist, one of those blobs contain a DT
>> >> >  You propose to mandate a DT for all boards make sense in that environment.
>> >> > For RPI4, you just ignore everything the prior boot loader does because it is not <passage> compliant.
>> >>
>> >> It's not that. It's just that it is closed-source, so not relevant to
>> >> the discussion here. They could open-source it and then we could
>> >> consider it, but it has been closed-source for years now, so why would
>> >> we think that would happen?
>> >>
>> >> >
>> >> > This reinforces my opposition to the mandatory DT proposal.
>> >> >
>> >> > a third option is I think way more attractive:
>> >> > <optpassage>: shaped after the architecture Linux entry (ie. first parameter is dtb) [+ passage head (i.e. second parameter is pointer to passage head)]
>> >> >
>> >> > This way, you make U-Boot entry clean in RPI4, Apple M1, Qemu, SystemReady contexts
>> >> > and get a well deserved standardized information passing between prior loaders and U-Boot.
>> >> >
>> >> > The three options are possible though, you could select a U-Boot entry CONFIG option for:
>> >> > <specific>
>> >> > <optpassage>
>> >> > <purepassage>
>> >> >
>> >> > But despite it would be technically feasible, I don't think it is goes in the right direction.
>> >>
>> >> OK. Do you think we need a separate devicetree pointer, rather than
>> >> forcing it to be inside the created bloblist?
>> >>
>> >> I'd like to understand what problem you are solving with this. I am
>> >> trying to figure out a firmware-to-firmware mini-ABI (just a few
>> >> register values) that can be used in open-source projects. The ABI is
>> >> not intended to be used with Linux (I am unsure of the benefit it
>> >> would give and whether it is feasible to change the current one).
>> >>
>> >> You are talking about the Linux entry mechanism. What relevance does
>> >> that have for firmware?
>> >>
>> >> I understand that some projects already implement the Linux mechanism,
>> >> but that is because they expect to jump straight to Linux, not have
>> >> U-Boot in the path. So IMO standard passage offers no benefit to them.
>> >>
>> >> To address them in turn:
>> >> - rpi4 - closed source, who cares?
>> >> - Apple M1 - we could probably expand it to pass a bloblist, but it
>> >> would be confusing unless we share registers, as you suggest
>> >> - Qemu - I already tried to update that and got pushback...do you
>> >> really think those guys are going to want to add a bloblist? So again,
>> >> who cares?
>> >> - SystemReady - not sure what this means in practice, but it would be
>> >> good if SystemReady could use standard passage
>> >>
>> >> So let's say we have an optional standard-passage thing and we use
>> >> registers such that it is similar to Linux and EFI and just expands on
>> >> them.
>> >>
>> >> The first problem is that Linux and EFI seem to be completely
>> >> incompatible. Can that be changed, perhaps on the EFI side? If not,
>> >> we need two separate protocols.
>> >>
>> >> I'll ignore EFI for now. So we might have:
>> >>
>> >> r0 = 0
>> >> r1 = machine number (0?)
>> >> r2 = dtb pointer
>> >> r3 = bloblist pointer, 0 if missing
>> >> r14 = return address
>> >>
>> >> or
>> >>
>> >> x0 = dtb
>> >> x1 = bloblist pointer, 0 if missing
>> >> x30 = return address
>> >
>> > That’s essentially what I proposed!
>> > you do not force the DTB to be found in the bloblist, and shape the U-Boot entry after the Linux entry ABI. Good !
>> > I was saving a few registers for future ABI evolution so that boards can be guaranteed to have their board specific registers properly protected. The 5 registers, leaving 3 undefined was just « why not ». We could also have a cookie in x1: high 48 bits magic low 16 ABI version, x2=bloblist pointer.
>>
>> Isn't 32 bits enough for a magic value?
>>
>> Also x3 might be nicer, to match ARM 32-bit, so:
>>
>> x0 = dtb
>> x1 = ABI indicator bits 63:32 0xb00757a3, bits 31:1 = 0, bit 0 = 1
>> (version 1) ? We don't need to decide how many bits for the version
>> right now. Perhaps 8 is plenty
>> x2 = 0
>> x3 = bloblist pointer, 0 if missing
>> x4 = 0
>> x30 = return address
>>
> sounds usable. Need more comments on this.
>
>>
>> For ARM:
>>
>> r0 = 0
>> r1 = machine number (0xb00757xx to signal standard passage where xx is
>> the ABI version?)*
>> r2 = dtb pointer
>> r3 = bloblist pointer (if r1 is 0xb00757xx), else 0
>> r4 = 0
>> r14 = return address
>>
>> * might be safe, looking at
>> https://elixir.bootlin.com/linux/latest/source/arch/arm/kernel/setup.c#L1094
>>
> Indeed. Need more comments on this.
>
>
>>
>> >
>> >>
>> >> For EFI, we could add a blob to the bloblist containing the system
>> >> table and handle, perhaps? Otherwise:
>> >>
>> >> x2 - efi handle
>> >> x3 - system table
>> >>
>> >> Is that along the lines of what you are thinking?
>> >
>> > No, efi entry is only x0=efi handle, x1=system table . I was trying to find a way to have passage when U-Boot is loaded as a UEFI app (your other patch set to make U-Boot a more integrated UEFi app). Let’s say that a U-Boot aware DXE driver/protocol actually populate such a table, it could be a communication channel between that driver and U-Boot.
>>
>> OK, I figured, so how about, for EFI on 64-bit:
>>
>> x0 = handle
>> x1 = systable
>> x2 = ABI indicator bits 63:32 0xb00757a3, bits 31:1 = 0, bit 0 = 1 (version 1)
>> x3 = bloblist pointer
>> x4 = 0
>> x30 = return address
>>
>> EFI 32-bit:
>>
>> r0 = handle
>> r1 = systable
>> r2 = 0xb00757a3
>> r3 = bloblist pointer
>> r4 = 0
>> r14 = return address
>>
> Let's be clear that this is for an existing UEFI implementation to boot U-Boot.
> If the implementation cannot be changed to add the information, a UEFI driver or protocol may be used.
> Could SPL may be tweaked to craft the bloblist based on whatever information I that case?

Yes that is easy enough, but then how does SPL load U-Boot? UEFI
requires an efl file and we don't want to put the EFI app into SPL, I
think.

>
> (side comment: LinuxBoot has developed techniques to replace most of an EDK2 implementation by Linux.
> This entry ABI does not apply in this use case as it is defined by EDK2.)
>
> Now on the how.
>
> EFI API has already defined extension mechanism, so that may be difficult to add.
>
> let's put the bloblist pointer in a <configtable>:
>
>  typedef struct {
> 1936  ///
> 1937  /// The 128-bit GUID value that uniquely identifies the system configuration table.
> 1938  ///
> 1939  EFI_GUID VendorGuid; /* set to BLOB_LIST_GUID */
> 1940  ///
> 1941  /// A pointer to the table associated with VendorGuid.
> 1942  ///
> 1943  VOID *VendorTable; /* bloblist pointer */
> 1944 } EFI_CONFIGURATION_TABLE;
>
> U-Boot or a driver or a protocol can set the VendorTable to bloblist pointer and add this to the list of configuration tables via
> https://edk2-docs.gitbook.io/edk-ii-uefi-driver-writer-s-guide/5_uefi_services/readme.2/5210_installconfigurationtable
>
> The blobs should be already accounted for in the memory map as they were pre-allocated before U-Boot entry. But that may be a topic to be checked.

OK, well in that case I suppose we don't need to define it here? Or
are you saying that we should define this as an alternative way to get
the bloblist?

Everything we define, we need tests for, so I want to make sure only
useful cases are included.

Regards,
Simon


>
>
>> Regards,
>> Simon
>>
>> >>
>> >>
>> >> But still, please respond above so I can understand what problem you
>> >> are worried about.
>> >>
>> >> Regards,
>> >> Simon
>> >>
>> >>
>> >> >
>> >> >> >>
>> >> >> >> But I added an offset to it as a convenience.
>> >> >> >>
>> >> >> >> > - EFI: x0=handle, x1=systemtable, x30=return address;  (when U-Boot is launched as an EFI app)
>> >> >> >> >        dtb = EFI_UUID config table, + Passage = Passage UUID config table
>> >> >> >>
>> >> >> >> I don't understand the last line. Where is the passage info /
>> >> >> >> bloblist? Do you mean it goes in the HOB list with a UUID? I suppose
>> >> >> >> that is the most EFI-compatible way.
>> >> >> >
>> >> >> > The Passage config table  could just contain the "head" of the bloblist/Passage information.
>> >> >>
>> >> >> If UEFI wants to deal with standard passage, that is...
>> >> >>
>> >> >> >>
>> >> >> >>
>> >> >> >> What do you think about the idea of using an offset into the bloblist
>> >> >> >> for the dtb?
>> >> >> >
>> >> >> > It is possible but as I said, failing to mimic Linux entry ABI would miss the opportunity to just boot without changes on RPI4.
>> >> >>
>> >> >> See above. Broadcom could look at open-sourcing their bootloader if they wish.
>> >> >>
>> >> >> >>
>> >> >> >> Also, can we make the standard passage ABI a build-time
>> >> >> >> option, so it is deterministic?
>> >> >> >>
>> >> >> > Looks good. I would look into stating that for SystemReady we would advise to use that option and make it standard for Trusted Substrate (Linaro recipes that we upstreaming to make SystemReady compliance easy and consistent across platforms).
>> >> >>
>> >> >> OK. I mean that if the option is enabled, then standard passage must
>> >> >> be provided / emitted or things won't work. If the option is disabled,
>> >> >> then standard passage is not used. In other words, we are looking for
>> >> >> magic values in registers, etc, just enabling/disabling it at
>> >> >> build-time.
>> >> >>
>> >> >> >>
>> >> >> >> >
>> >> >> >> > We could further leverage Passage to pass Operating Systems parameters that could be removed from device tree (migration of /chosen to Passage). Memory inventory would still be in DT but allocations for CMA or GPUs would be in Passage. This idea is to reach a point where  device tree is a "pristine" hardware description.
>> >> >> >>
>> >> >> >> I'm worried about this becoming a substitute for devicetree. Really my
>> >> >> >> intent is to provide a way to pass simple info, whereas what you talk
>> >> >> >> about there seems like something that should be DT, just that it might
>> >> >> >> need suitable bindings.
>> >> >> >>
>> >> >> > I see your point and I agree It should not be a substitute.
>> >> >> > here is an expanded version of what I had in mind when I wrote those lines.
>> >> >> > cma, initrd and other Linux kernel parameters can be conveyed either through command line or DT.
>> >> >> > When using the non UEFI Linux entry ABI, you need to use the DT to pass those parameters.
>> >> >> > When using the UEFI Linux entry ABI, you *can* (not must) use the command line to pass all information, leaving the DT passed to the OS without any /chosen.
>> >> >> > When introducing Passage, I was wondering if we could pass command line to Linux and, same as UEFI, leave the DT free from /chosen.
>> >> >> > I am not sure it is a good goal though. I may be too pushing for a DT free from parameters.
>> >> >>
>> >> >> We could. Are there benefits to that?
>> >> >>
>> >> >> I doubt we would pass the standard passage to Linux as a bloblist. I
>> >> >> imagine something like this. The bloblist sits in memory with some
>> >> >> things in it, including a devicetree, perhaps an SMBIOS table and a
>> >> >> TPM log. But when U-Boot calls Linux it puts the address/size of those
>> >> >> individual things in the devicetree. They don't move and are still
>> >> >> contiguous in memory, but the bloblist around them is forgotten. Linux
>> >> >> doesn't know that the three separate things it is picking up are
>> >> >> actually part of a bloblist structure, since it doesn't care about
>> >> >> that. Even a console log could work the same way. That way we don't
>> >> >> end up trying to teach Linux about bloblist when it already has a
>> >> >> perfectly good means to accept these items.
>> >> >>
>> >> >> For ACPI I see things a similar way. The ACPI tables can point to
>> >> >> things that *happen* to be in a bloblist, but without any knowledge of
>> >> >> that needed in Linux, grub, etc.
>> >> >>
>> >> >> >>
>> >> >> >> As you know I have more expansive views about what should be in DT.
>> >> >> >
>> >> >> > I think both of us are huge supporters of DT format and self describing capabilities.
>> >> >> > I am inclined to put rules into what fits into what lands in the DT that is passed to the OS.
>> >> >> > I am a fan of having DT used more in ad-hoc files.
>> >> >>
>> >> >> Me too.
>> >> >>
>> >> >> >>
>> >> >> >> >
>> >> >> >> > Cheers
>> >> >> >> >
>> >> >> >> > PS: as Ilias mentions, this patch set contains bug fixes, non immediately related additional functions (DM stats). It would be great to carve those out to fast path them and keep this one with the very core of your idea.
>> >> >> >>
>> >> >> >> The DM stats is used in 'passage: Report the devicetree source'. I
>> >> >> >> know it is sideways but I think it is better to make the output line
>> >> >> >> more useful than just reporting the devicetree source.
>> >> >> >>
>> >> >> > I believe the DM stats has merits in its own. You could upstream this independently and then Passage would be yet another "customer" of the feature.
>> >> >>
>> >> >> I could, but it would just be a debug feature so people might not
>> >> >> think it worth the code space. With the devicetree source it is more
>> >> >> compelling.
>> >> >>
>> >> >> >>
>> >> >> >> The first patch is indeed unrelated. I will pick it up so we can drop
>> >> >> >> it for the next rev.
>> >> >> >>
>> >> >> [..]
>> >> >>
>> >> >> Regards,
>> >> >> Simon
>> >> >
>> >> >
>> >> >
>> >> > --
>> >> > François-Frédéric Ozog | Director Business Development
>> >> > T: +33.67221.6485
>> >> > francois.ozog@linaro.org | Skype: ffozog
>> >> >
>> >
>> > --
>> > François-Frédéric Ozog | Director Business Development
>> > T: +33.67221.6485
>> > francois.ozog@linaro.org | Skype: ffozog
>> >
>
>
>
> --
> François-Frédéric Ozog | Director Business Development
> T: +33.67221.6485
> francois.ozog@linaro.org | Skype: ffozog
>


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 01/31] Makefile: Correct TPL rule for OF_REAL
  2021-11-01  1:17 ` [PATCH 01/31] Makefile: Correct TPL rule for OF_REAL Simon Glass
  2021-11-01  6:54   ` Ilias Apalodimas
@ 2021-11-14  0:34   ` Simon Glass
  1 sibling, 0 replies; 77+ messages in thread
From: Simon Glass @ 2021-11-14  0:34 UTC (permalink / raw)
  To: Ilias Apalodimas
  Cc: U-Boot Mailing List, Tom Rini, Bin Meng, Bill Mills,
	Heinrich Schuchardt, François Ozog, Masahiro Yamada,
	Simon Glass

Hi Simon,

As I expect this series to go through some versions before we agree on
something and this seems like a pure bugfix can you split it of as a
single patch?

On Mon, 1 Nov 2021 at 03:19, Simon Glass <sjg@chromium.org> wrote:
>
> Correct an error in the tpl-dtb parameter to binman. At present the TPL
> rule follows SPL but this is not correct, if TPL uses of-platdata, for
> example.
>
> Fixes: f99cbe4e867 ("fdt: Update Makefile rules with the new OF_REAL Kconfig")
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
>  Makefile | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
Applied to u-boot-dm, thanks!

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 02/31] kconfig: Add support for conditional values
  2021-11-01  7:05   ` Ilias Apalodimas
@ 2022-01-12 21:28     ` Simon Glass
  2022-01-12 21:56       ` Tom Rini
  0 siblings, 1 reply; 77+ messages in thread
From: Simon Glass @ 2022-01-12 21:28 UTC (permalink / raw)
  To: Ilias Apalodimas
  Cc: U-Boot Mailing List, Tom Rini, Bin Meng, Bill Mills,
	Heinrich Schuchardt, François Ozog, Masahiro Yamada

Hi Ilias,

On Mon, 1 Nov 2021 at 01:05, Ilias Apalodimas
<ilias.apalodimas@linaro.org> wrote:
>
> On Mon, 1 Nov 2021 at 03:19, Simon Glass <sjg@chromium.org> wrote:
> >
> > At present if an optional Kconfig value needs to be used it must be
> > bracketed by #ifdef. For example, with this Kconfig setup:
> >
> > config WIBBLE
> >         bool "Support wibbles, the world needs more wibbles"
> >
> > config WIBBLE_ADDR
> >         hex "Address of the wibble"
> >         depends on WIBBLE
> >
> > then the following code must be used:
> >
> >  #ifdef CONFIG_WIBBLE
> >  static void handle_wibble(void)
> >  {
> >         int val = CONFIG_WIBBLE_ADDR;
> >
> >         ...
> >  }
> >  #endif
> >
>
> The example here might be a bit off and we might need this for int
> related values. Was this function handle_wibble() supposed to return
> an int or not?  We could shield the linker easier here without adding
> macros. Something along the lines of
> static void handle_wibble(void)
> {
> #ifdef CONFIG_WIBBLE
> int val = CONFIG_WIBBLE_ADDR;
> #endif
> }
>
> In that case you don't an extra ifdef to call handle_wibble().
> Personally I find this easier to read.

But how does that help with the problem here? I am trying to avoid
using preprocessor macros in this case.

Regards,
Simon

>
> >  static void init_machine()
> >  {
> >  ...
> >  #ifdef CONFIG_WIBBLE
> >         handle_wibble();
> >  #endif
> >  }
> >
> > Add a new IF_ENABLED_INT() to help with this. So now it is possible to
> > write, without #ifdefs:
> >
> >  static void handle_wibble(void)
> >  {
> >         int val = IF_ENABLED_INT(CONFIG_WIBBLE, CONFIG_WIBBLE_ADDR);
> >
> >         ...
> >  }
> >
> >  static void init_machine()
> >  {
> >  ...
> >  if (IS_ENABLED(CONFIG_WIBBLE))
> >         handle_wibble();
> >  }
> >
> > The value will be 0 if CONFIG_WIBBLE is not defined, and
> > CONFIG_WIBBLE_ADDR if it is. This allows us to reduce the use of #ifdef in
> > the code, ensuring that the compiler still checks the code even if it is
> > not ultimately used for a particular build.
> >
> > Add a CONFIG_IF_ENABLED_INT() version as well.
> >
> > Signed-off-by: Simon Glass <sjg@chromium.org>
> > ---
> >
> >  include/linux/kconfig.h      | 18 ++++++++++++++++++
> >  scripts/config_whitelist.txt |  1 +
> >  2 files changed, 19 insertions(+)
> >
> > diff --git a/include/linux/kconfig.h b/include/linux/kconfig.h
> > index a1d1a298426..119c698a158 100644
> > --- a/include/linux/kconfig.h
> > +++ b/include/linux/kconfig.h
> > @@ -59,6 +59,18 @@
> >   */
> >  #define CONFIG_VAL(option)  config_val(option)
> >
> > +/* This use a similar mechanism to config_enabled() above */
> > +#define config_opt_enabled(cfg, opt_cfg) _config_opt_enabled(cfg, opt_cfg)
> > +#define _config_opt_enabled(cfg_val, opt_value) \
> > +       __config_opt_enabled(__ARG_PLACEHOLDER_##cfg_val, opt_value)
> > +#define __config_opt_enabled(arg1_or_junk, arg2) \
> > +       ___config_opt_enabled(arg1_or_junk arg2, 0)
> > +#define ___config_opt_enabled(__ignored, val, ...) val
> > +
> > +/* Evaluates to 0 if option is not defined, int_option if it is defined */
> > +#define IF_ENABLED_INT(option, int_option) \
> > +       config_opt_enabled(option, int_option)
> > +
> >  /*
> >   * Count number of arguments to a variadic macro. Currently only need
> >   * it for 1, 2 or 3 arguments.
> > @@ -113,5 +125,11 @@
> >  #define CONFIG_IS_ENABLED(option, ...)                                 \
> >         __concat(__CONFIG_IS_ENABLED_, __count_args(option, ##__VA_ARGS__)) (option, ##__VA_ARGS__)
> >
> > +/*
> > + * Evaluates to 0 if SPL_/TPL_/option is not defined, SPL_/TPL_int_option if it
> > + * is defined
> > + */
> > +#define CONFIG_IF_ENABLED_INT(option, int_option) \
> > +       CONFIG_IS_ENABLED(option, (CONFIG_VAL(int_option)), (0))
> >
> >  #endif /* __LINUX_KCONFIG_H */
> > diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
> > index 022a27288c9..f9d9f4a9cfe 100644
> > --- a/scripts/config_whitelist.txt
> > +++ b/scripts/config_whitelist.txt
> > @@ -609,6 +609,7 @@ CONFIG_ICS307_REFCLK_HZ
> >  CONFIG_IDE_PREINIT
> >  CONFIG_IDE_RESET
> >  CONFIG_IDE_SWAP_IO
> > +CONFIG_IF_ENABLED_INT
> >  CONFIG_IMA
> >  CONFIG_IMX
> >  CONFIG_IMX6_PWM_PER_CLK
> > --
> > 2.33.1.1089.g2158813163f-goog
> >
>
> Regards
> /Ilias

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 02/31] kconfig: Add support for conditional values
  2022-01-12 21:28     ` Simon Glass
@ 2022-01-12 21:56       ` Tom Rini
  2022-01-12 22:22         ` Simon Glass
  2022-01-13  7:56         ` Rasmus Villemoes
  0 siblings, 2 replies; 77+ messages in thread
From: Tom Rini @ 2022-01-12 21:56 UTC (permalink / raw)
  To: Simon Glass
  Cc: Ilias Apalodimas, U-Boot Mailing List, Bin Meng, Bill Mills,
	Heinrich Schuchardt, François Ozog, Masahiro Yamada

[-- Attachment #1: Type: text/plain, Size: 2212 bytes --]

On Wed, Jan 12, 2022 at 02:28:21PM -0700, Simon Glass wrote:
> Hi Ilias,
> 
> On Mon, 1 Nov 2021 at 01:05, Ilias Apalodimas
> <ilias.apalodimas@linaro.org> wrote:
> >
> > On Mon, 1 Nov 2021 at 03:19, Simon Glass <sjg@chromium.org> wrote:
> > >
> > > At present if an optional Kconfig value needs to be used it must be
> > > bracketed by #ifdef. For example, with this Kconfig setup:
> > >
> > > config WIBBLE
> > >         bool "Support wibbles, the world needs more wibbles"
> > >
> > > config WIBBLE_ADDR
> > >         hex "Address of the wibble"
> > >         depends on WIBBLE
> > >
> > > then the following code must be used:
> > >
> > >  #ifdef CONFIG_WIBBLE
> > >  static void handle_wibble(void)
> > >  {
> > >         int val = CONFIG_WIBBLE_ADDR;
> > >
> > >         ...
> > >  }
> > >  #endif
> > >
> >
> > The example here might be a bit off and we might need this for int
> > related values. Was this function handle_wibble() supposed to return
> > an int or not?  We could shield the linker easier here without adding
> > macros. Something along the lines of
> > static void handle_wibble(void)
> > {
> > #ifdef CONFIG_WIBBLE
> > int val = CONFIG_WIBBLE_ADDR;
> > #endif
> > }
> >
> > In that case you don't an extra ifdef to call handle_wibble().
> > Personally I find this easier to read.
> 
> But how does that help with the problem here? I am trying to avoid
> using preprocessor macros in this case.

I'm not sure I see a problem here.  A number of the finish-converting-X
that I did recently had a guard symbol first because usage wasn't fully
converted but really everyone using that area of code needed to set the
value, or use the default.

There might be some cases where we do still need a guard symbol because
usage is in common code and maybe shouldn't be, but instead moved to
other usage-specific files.

I also think I've seen cases where doing:
if (CONFIG_EVALUATES_TO_ZERO) {
  ...
}

takes more space in the binary than an #ifdef does.

And finally for the moment, we also have many cases where zero is a
valid value.  That's what leads to potentially harder to read code or
needing a guard, I think.

-- 
Tom

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 02/31] kconfig: Add support for conditional values
  2022-01-12 21:56       ` Tom Rini
@ 2022-01-12 22:22         ` Simon Glass
  2022-01-12 23:04           ` Tom Rini
  2022-01-13  7:56         ` Rasmus Villemoes
  1 sibling, 1 reply; 77+ messages in thread
From: Simon Glass @ 2022-01-12 22:22 UTC (permalink / raw)
  To: Tom Rini
  Cc: Ilias Apalodimas, U-Boot Mailing List, Bin Meng, Bill Mills,
	Heinrich Schuchardt, François Ozog, Masahiro Yamada

Hi Tom,

On Wed, 12 Jan 2022 at 14:56, Tom Rini <trini@konsulko.com> wrote:
>
> On Wed, Jan 12, 2022 at 02:28:21PM -0700, Simon Glass wrote:
> > Hi Ilias,
> >
> > On Mon, 1 Nov 2021 at 01:05, Ilias Apalodimas
> > <ilias.apalodimas@linaro.org> wrote:
> > >
> > > On Mon, 1 Nov 2021 at 03:19, Simon Glass <sjg@chromium.org> wrote:
> > > >
> > > > At present if an optional Kconfig value needs to be used it must be
> > > > bracketed by #ifdef. For example, with this Kconfig setup:
> > > >
> > > > config WIBBLE
> > > >         bool "Support wibbles, the world needs more wibbles"
> > > >
> > > > config WIBBLE_ADDR
> > > >         hex "Address of the wibble"
> > > >         depends on WIBBLE
> > > >
> > > > then the following code must be used:
> > > >
> > > >  #ifdef CONFIG_WIBBLE
> > > >  static void handle_wibble(void)
> > > >  {
> > > >         int val = CONFIG_WIBBLE_ADDR;
> > > >
> > > >         ...
> > > >  }
> > > >  #endif
> > > >
> > >
> > > The example here might be a bit off and we might need this for int
> > > related values. Was this function handle_wibble() supposed to return
> > > an int or not?  We could shield the linker easier here without adding
> > > macros. Something along the lines of
> > > static void handle_wibble(void)
> > > {
> > > #ifdef CONFIG_WIBBLE
> > > int val = CONFIG_WIBBLE_ADDR;
> > > #endif
> > > }
> > >
> > > In that case you don't an extra ifdef to call handle_wibble().
> > > Personally I find this easier to read.
> >
> > But how does that help with the problem here? I am trying to avoid
> > using preprocessor macros in this case.
>
> I'm not sure I see a problem here.  A number of the finish-converting-X
> that I did recently had a guard symbol first because usage wasn't fully
> converted but really everyone using that area of code needed to set the
> value, or use the default.
>
> There might be some cases where we do still need a guard symbol because
> usage is in common code and maybe shouldn't be, but instead moved to
> other usage-specific files.
>
> I also think I've seen cases where doing:
> if (CONFIG_EVALUATES_TO_ZERO) {
>   ...
> }
>
> takes more space in the binary than an #ifdef does.

I'd like to see that.

>
> And finally for the moment, we also have many cases where zero is a
> valid value.  That's what leads to potentially harder to read code or
> needing a guard, I think.

The specific case where this is (to be) used is here:

https://patchwork.ozlabs.org/project/uboot/patch/20211101011734.1614781-14-sjg@chromium.org/

addr = IF_ENABLED_INT(CONFIG_BLOBLIST_FIXED, CONFIG_BLOBLIST_ADDR);

This is because BLOBLIST_ADDR depends on BLOBLIST_FIXED (it is
meaningless to have an address if the bloblits is allocated).

One fix is to always have an address, and set it to 0 by default (and
not use it) when BLOBLIST_FIXED is not enabled.

But it does lead to a strange Kconfig since options are present which
are not really used.

Another option is to add an accessor to the header file, as is down
with global_data (e.g. as is done with gd_of_root()).

Thoughts?

Regards,
Simon

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 02/31] kconfig: Add support for conditional values
  2022-01-12 22:22         ` Simon Glass
@ 2022-01-12 23:04           ` Tom Rini
  0 siblings, 0 replies; 77+ messages in thread
From: Tom Rini @ 2022-01-12 23:04 UTC (permalink / raw)
  To: Simon Glass
  Cc: Ilias Apalodimas, U-Boot Mailing List, Bin Meng, Bill Mills,
	Heinrich Schuchardt, François Ozog, Masahiro Yamada

[-- Attachment #1: Type: text/plain, Size: 3767 bytes --]

On Wed, Jan 12, 2022 at 03:22:51PM -0700, Simon Glass wrote:
> Hi Tom,
> 
> On Wed, 12 Jan 2022 at 14:56, Tom Rini <trini@konsulko.com> wrote:
> >
> > On Wed, Jan 12, 2022 at 02:28:21PM -0700, Simon Glass wrote:
> > > Hi Ilias,
> > >
> > > On Mon, 1 Nov 2021 at 01:05, Ilias Apalodimas
> > > <ilias.apalodimas@linaro.org> wrote:
> > > >
> > > > On Mon, 1 Nov 2021 at 03:19, Simon Glass <sjg@chromium.org> wrote:
> > > > >
> > > > > At present if an optional Kconfig value needs to be used it must be
> > > > > bracketed by #ifdef. For example, with this Kconfig setup:
> > > > >
> > > > > config WIBBLE
> > > > >         bool "Support wibbles, the world needs more wibbles"
> > > > >
> > > > > config WIBBLE_ADDR
> > > > >         hex "Address of the wibble"
> > > > >         depends on WIBBLE
> > > > >
> > > > > then the following code must be used:
> > > > >
> > > > >  #ifdef CONFIG_WIBBLE
> > > > >  static void handle_wibble(void)
> > > > >  {
> > > > >         int val = CONFIG_WIBBLE_ADDR;
> > > > >
> > > > >         ...
> > > > >  }
> > > > >  #endif
> > > > >
> > > >
> > > > The example here might be a bit off and we might need this for int
> > > > related values. Was this function handle_wibble() supposed to return
> > > > an int or not?  We could shield the linker easier here without adding
> > > > macros. Something along the lines of
> > > > static void handle_wibble(void)
> > > > {
> > > > #ifdef CONFIG_WIBBLE
> > > > int val = CONFIG_WIBBLE_ADDR;
> > > > #endif
> > > > }
> > > >
> > > > In that case you don't an extra ifdef to call handle_wibble().
> > > > Personally I find this easier to read.
> > >
> > > But how does that help with the problem here? I am trying to avoid
> > > using preprocessor macros in this case.
> >
> > I'm not sure I see a problem here.  A number of the finish-converting-X
> > that I did recently had a guard symbol first because usage wasn't fully
> > converted but really everyone using that area of code needed to set the
> > value, or use the default.
> >
> > There might be some cases where we do still need a guard symbol because
> > usage is in common code and maybe shouldn't be, but instead moved to
> > other usage-specific files.
> >
> > I also think I've seen cases where doing:
> > if (CONFIG_EVALUATES_TO_ZERO) {
> >   ...
> > }
> >
> > takes more space in the binary than an #ifdef does.
> 
> I'd like to see that.

It's one of those fairly maddening cases when it happens.  I _think_
it's more correctly shown as:
if (CONFIG_FOO && bar->baz)
which yes, was excluded but resulted in different code optimization?  I
went to far as to compare the disassembly and just left scratching my
head why it changed.

> > And finally for the moment, we also have many cases where zero is a
> > valid value.  That's what leads to potentially harder to read code or
> > needing a guard, I think.
> 
> The specific case where this is (to be) used is here:
> 
> https://patchwork.ozlabs.org/project/uboot/patch/20211101011734.1614781-14-sjg@chromium.org/
> 
> addr = IF_ENABLED_INT(CONFIG_BLOBLIST_FIXED, CONFIG_BLOBLIST_ADDR);
> 
> This is because BLOBLIST_ADDR depends on BLOBLIST_FIXED (it is
> meaningless to have an address if the bloblits is allocated).
> 
> One fix is to always have an address, and set it to 0 by default (and
> not use it) when BLOBLIST_FIXED is not enabled.
> 
> But it does lead to a strange Kconfig since options are present which
> are not really used.
> 
> Another option is to add an accessor to the header file, as is down
> with global_data (e.g. as is done with gd_of_root()).

Yeah, lets solve this any other way.  If we can do it local to the file,
that's best.

-- 
Tom

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 02/31] kconfig: Add support for conditional values
  2022-01-12 21:56       ` Tom Rini
  2022-01-12 22:22         ` Simon Glass
@ 2022-01-13  7:56         ` Rasmus Villemoes
  2022-01-13 12:52           ` Tom Rini
  1 sibling, 1 reply; 77+ messages in thread
From: Rasmus Villemoes @ 2022-01-13  7:56 UTC (permalink / raw)
  To: Tom Rini, Simon Glass
  Cc: Ilias Apalodimas, U-Boot Mailing List, Bin Meng, Bill Mills,
	Heinrich Schuchardt, François Ozog, Masahiro Yamada

On 12/01/2022 22.56, Tom Rini wrote:
> On Wed, Jan 12, 2022 at 02:28:21PM -0700, Simon Glass wrote:
>> Hi Ilias,
>>
>> On Mon, 1 Nov 2021 at 01:05, Ilias Apalodimas
>> <ilias.apalodimas@linaro.org> wrote:
>>>
>>> On Mon, 1 Nov 2021 at 03:19, Simon Glass <sjg@chromium.org> wrote:
>>>>
>>>> At present if an optional Kconfig value needs to be used it must be
>>>> bracketed by #ifdef. For example, with this Kconfig setup:
>>>>
>>>> config WIBBLE
>>>>         bool "Support wibbles, the world needs more wibbles"
>>>>
>>>> config WIBBLE_ADDR
>>>>         hex "Address of the wibble"
>>>>         depends on WIBBLE
>>>>
>>>> then the following code must be used:
>>>>
>>>>  #ifdef CONFIG_WIBBLE
>>>>  static void handle_wibble(void)
>>>>  {
>>>>         int val = CONFIG_WIBBLE_ADDR;
>>>>
>>>>         ...
>>>>  }
>>>>  #endif
>>>>
>>>
>>> The example here might be a bit off and we might need this for int
>>> related values. Was this function handle_wibble() supposed to return
>>> an int or not?  We could shield the linker easier here without adding
>>> macros. Something along the lines of
>>> static void handle_wibble(void)
>>> {
>>> #ifdef CONFIG_WIBBLE
>>> int val = CONFIG_WIBBLE_ADDR;
>>> #endif
>>> }
>>>
>>> In that case you don't an extra ifdef to call handle_wibble().
>>> Personally I find this easier to read.
>>
>> But how does that help with the problem here? I am trying to avoid
>> using preprocessor macros in this case.
> 
> I'm not sure I see a problem here.  A number of the finish-converting-X
> that I did recently had a guard symbol first because usage wasn't fully
> converted but really everyone using that area of code needed to set the
> value, or use the default.
> 
> There might be some cases where we do still need a guard symbol because
> usage is in common code and maybe shouldn't be, but instead moved to
> other usage-specific files.
> 
> I also think I've seen cases where doing:
> if (CONFIG_EVALUATES_TO_ZERO) {
>   ...
> }
> 
> takes more space in the binary than an #ifdef does.

Please provide a specific example. If CONFIG_EVALUATES_TO_ZERO is any
integer-constant-expression evaluating at compile-time to 0, gcc throws
away the whole block very early during parsing. If it doesn't, that's a
compiler bug, so let's please not make decisions based on
not-even-anecdotal data.

> And finally for the moment, we also have many cases where zero is a
> valid value.  That's what leads to potentially harder to read code or
> needing a guard, I think.
> 

I like Simon's idea, but the replacement/fallback should _not_ be a
literal 0. We want a guarantee that the code has actually been discarded
by the compiler or linker (i.e., that the access is done in code that is
otherwise guarded by the "parent" Kconfig symbol), so instead the
fallback should be a call to (the nowhere defined of course)

extern long invalid_use_of_IF_ENABLED_INT(void);

Of course, if people don't build with -O2 and
-ffunction-sections,-fdata-sections and link with --gc-sections, that
may break, but why should we care?

Rasmus

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 04/31] stddef: Avoid warning with clang with offsetof()
  2021-11-01  1:17 ` [PATCH 04/31] stddef: Avoid warning with clang with offsetof() Simon Glass
@ 2022-01-13  8:08   ` Rasmus Villemoes
  2022-01-13 13:07     ` Tom Rini
  0 siblings, 1 reply; 77+ messages in thread
From: Rasmus Villemoes @ 2022-01-13  8:08 UTC (permalink / raw)
  To: Simon Glass, U-Boot Mailing List
  Cc: Tom Rini, Bin Meng, Ilias Apalodimas, Bill Mills,
	Heinrich Schuchardt, François Ozog

On 01/11/2021 02.17, Simon Glass wrote:
> Some bright sparks have decided that a cast on a constant cannot be a
> constant, so offsetof() produces this warning on clang-10:
> 
> include/intel_gnvs.h:113:1: error: static_assert expression is not an
> 	integral constant expression
> check_member(acpi_global_nvs, unused2, GNVS_CHROMEOS_ACPI_OFFSET);
> ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> include/linux/kernel.h:284:2: note: expanded from macro 'check_member'
>         offsetof(struct structure, member) == (offset), \
>         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> include/linux/stddef.h:20:32: note: expanded from macro 'offsetof'
>                                 ^
> include/intel_gnvs.h:113:1: note: cast that performs the conversions of
> 	a reinterpret_cast is ot allowed in a constant expression
> include/linux/stddef.h:20:33: note: expanded from macro 'offsetof'
> 
> Fix it by using the compiler built-in version, if available.
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
> 
>  include/linux/stddef.h | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/include/linux/stddef.h b/include/linux/stddef.h
> index c540f6100d4..a7f546fdfe5 100644
> --- a/include/linux/stddef.h
> +++ b/include/linux/stddef.h
> @@ -1,6 +1,8 @@
>  #ifndef _LINUX_STDDEF_H
>  #define _LINUX_STDDEF_H
>  
> +#include <linux/compiler_types.h>
> +
>  #undef NULL
>  #if defined(__cplusplus)
>  #define NULL 0
> @@ -14,7 +16,11 @@
>  
>  #ifndef __CHECKER__
>  #undef offsetof
> -#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
> +#ifdef __compiler_offsetof
> +#define offsetof(TYPE, MEMBER)	__compiler_offsetof(TYPE, MEMBER)
> +#else
> +#define offsetof(TYPE, MEMBER)	((size_t)&((TYPE *)0)->MEMBER)
> +#endif
>  #endif


Can we please just drop the useless indirections? Any compiler we care
about provides __builtin_offsetof(), so just make the whole thing

  #undef offsetof
  #define offsetof(TYPE, MEMBER)  __builtin_offsetof(TYPE, MEMBER)

And by "compilers we care about", that includes sparse - it has had
__builtin_offsetof ever since 2007.

And we can nuke the __compiler_offsetof definition in compiler_types.h,
and if any users exist, just mechanically convert them to offsetof().

Rasmus

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 02/31] kconfig: Add support for conditional values
  2022-01-13  7:56         ` Rasmus Villemoes
@ 2022-01-13 12:52           ` Tom Rini
  2022-01-13 13:56             ` Simon Glass
  2022-01-13 15:01             ` Rasmus Villemoes
  0 siblings, 2 replies; 77+ messages in thread
From: Tom Rini @ 2022-01-13 12:52 UTC (permalink / raw)
  To: Rasmus Villemoes
  Cc: Simon Glass, Ilias Apalodimas, U-Boot Mailing List, Bin Meng,
	Bill Mills, Heinrich Schuchardt, François Ozog,
	Masahiro Yamada

[-- Attachment #1: Type: text/plain, Size: 3647 bytes --]

On Thu, Jan 13, 2022 at 08:56:02AM +0100, Rasmus Villemoes wrote:
> On 12/01/2022 22.56, Tom Rini wrote:
> > On Wed, Jan 12, 2022 at 02:28:21PM -0700, Simon Glass wrote:
> >> Hi Ilias,
> >>
> >> On Mon, 1 Nov 2021 at 01:05, Ilias Apalodimas
> >> <ilias.apalodimas@linaro.org> wrote:
> >>>
> >>> On Mon, 1 Nov 2021 at 03:19, Simon Glass <sjg@chromium.org> wrote:
> >>>>
> >>>> At present if an optional Kconfig value needs to be used it must be
> >>>> bracketed by #ifdef. For example, with this Kconfig setup:
> >>>>
> >>>> config WIBBLE
> >>>>         bool "Support wibbles, the world needs more wibbles"
> >>>>
> >>>> config WIBBLE_ADDR
> >>>>         hex "Address of the wibble"
> >>>>         depends on WIBBLE
> >>>>
> >>>> then the following code must be used:
> >>>>
> >>>>  #ifdef CONFIG_WIBBLE
> >>>>  static void handle_wibble(void)
> >>>>  {
> >>>>         int val = CONFIG_WIBBLE_ADDR;
> >>>>
> >>>>         ...
> >>>>  }
> >>>>  #endif
> >>>>
> >>>
> >>> The example here might be a bit off and we might need this for int
> >>> related values. Was this function handle_wibble() supposed to return
> >>> an int or not?  We could shield the linker easier here without adding
> >>> macros. Something along the lines of
> >>> static void handle_wibble(void)
> >>> {
> >>> #ifdef CONFIG_WIBBLE
> >>> int val = CONFIG_WIBBLE_ADDR;
> >>> #endif
> >>> }
> >>>
> >>> In that case you don't an extra ifdef to call handle_wibble().
> >>> Personally I find this easier to read.
> >>
> >> But how does that help with the problem here? I am trying to avoid
> >> using preprocessor macros in this case.
> > 
> > I'm not sure I see a problem here.  A number of the finish-converting-X
> > that I did recently had a guard symbol first because usage wasn't fully
> > converted but really everyone using that area of code needed to set the
> > value, or use the default.
> > 
> > There might be some cases where we do still need a guard symbol because
> > usage is in common code and maybe shouldn't be, but instead moved to
> > other usage-specific files.
> > 
> > I also think I've seen cases where doing:
> > if (CONFIG_EVALUATES_TO_ZERO) {
> >   ...
> > }
> > 
> > takes more space in the binary than an #ifdef does.
> 
> Please provide a specific example. If CONFIG_EVALUATES_TO_ZERO is any
> integer-constant-expression evaluating at compile-time to 0, gcc throws
> away the whole block very early during parsing. If it doesn't, that's a
> compiler bug, so let's please not make decisions based on
> not-even-anecdotal data.

OK.  I believe it was commit 7856cd5a6dd6 ("Convert CONFIG_SYS_PCI_64BIT
to Kconfig") a few platforms changed size and as best I can tell, the
used / evaluated value for CONFIG_SYS_PCI_64BIT didn't change.

> > And finally for the moment, we also have many cases where zero is a
> > valid value.  That's what leads to potentially harder to read code or
> > needing a guard, I think.
> 
> I like Simon's idea, but the replacement/fallback should _not_ be a
> literal 0. We want a guarantee that the code has actually been discarded
> by the compiler or linker (i.e., that the access is done in code that is
> otherwise guarded by the "parent" Kconfig symbol), so instead the
> fallback should be a call to (the nowhere defined of course)
> 
> extern long invalid_use_of_IF_ENABLED_INT(void);
> 
> Of course, if people don't build with -O2 and
> -ffunction-sections,-fdata-sections and link with --gc-sections, that
> may break, but why should we care?

LTO also gets this correct I assume and yes, I like that better.

-- 
Tom

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 04/31] stddef: Avoid warning with clang with offsetof()
  2022-01-13  8:08   ` Rasmus Villemoes
@ 2022-01-13 13:07     ` Tom Rini
  2022-01-13 13:37       ` Simon Glass
  0 siblings, 1 reply; 77+ messages in thread
From: Tom Rini @ 2022-01-13 13:07 UTC (permalink / raw)
  To: Rasmus Villemoes
  Cc: Simon Glass, U-Boot Mailing List, Bin Meng, Ilias Apalodimas,
	Bill Mills, Heinrich Schuchardt, François Ozog

[-- Attachment #1: Type: text/plain, Size: 2652 bytes --]

On Thu, Jan 13, 2022 at 09:08:13AM +0100, Rasmus Villemoes wrote:
> On 01/11/2021 02.17, Simon Glass wrote:
> > Some bright sparks have decided that a cast on a constant cannot be a
> > constant, so offsetof() produces this warning on clang-10:
> > 
> > include/intel_gnvs.h:113:1: error: static_assert expression is not an
> > 	integral constant expression
> > check_member(acpi_global_nvs, unused2, GNVS_CHROMEOS_ACPI_OFFSET);
> > ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > include/linux/kernel.h:284:2: note: expanded from macro 'check_member'
> >         offsetof(struct structure, member) == (offset), \
> >         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > include/linux/stddef.h:20:32: note: expanded from macro 'offsetof'
> >                                 ^
> > include/intel_gnvs.h:113:1: note: cast that performs the conversions of
> > 	a reinterpret_cast is ot allowed in a constant expression
> > include/linux/stddef.h:20:33: note: expanded from macro 'offsetof'
> > 
> > Fix it by using the compiler built-in version, if available.
> > 
> > Signed-off-by: Simon Glass <sjg@chromium.org>
> > ---
> > 
> >  include/linux/stddef.h | 8 +++++++-
> >  1 file changed, 7 insertions(+), 1 deletion(-)
> > 
> > diff --git a/include/linux/stddef.h b/include/linux/stddef.h
> > index c540f6100d4..a7f546fdfe5 100644
> > --- a/include/linux/stddef.h
> > +++ b/include/linux/stddef.h
> > @@ -1,6 +1,8 @@
> >  #ifndef _LINUX_STDDEF_H
> >  #define _LINUX_STDDEF_H
> >  
> > +#include <linux/compiler_types.h>
> > +
> >  #undef NULL
> >  #if defined(__cplusplus)
> >  #define NULL 0
> > @@ -14,7 +16,11 @@
> >  
> >  #ifndef __CHECKER__
> >  #undef offsetof
> > -#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
> > +#ifdef __compiler_offsetof
> > +#define offsetof(TYPE, MEMBER)	__compiler_offsetof(TYPE, MEMBER)
> > +#else
> > +#define offsetof(TYPE, MEMBER)	((size_t)&((TYPE *)0)->MEMBER)
> > +#endif
> >  #endif
> 
> 
> Can we please just drop the useless indirections? Any compiler we care
> about provides __builtin_offsetof(), so just make the whole thing
> 
>   #undef offsetof
>   #define offsetof(TYPE, MEMBER)  __builtin_offsetof(TYPE, MEMBER)
> 
> And by "compilers we care about", that includes sparse - it has had
> __builtin_offsetof ever since 2007.
> 
> And we can nuke the __compiler_offsetof definition in compiler_types.h,
> and if any users exist, just mechanically convert them to offsetof().

We should re-sync this with upstream, but that will keep the indirection
you're objecting to here, I think.

-- 
Tom

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 04/31] stddef: Avoid warning with clang with offsetof()
  2022-01-13 13:07     ` Tom Rini
@ 2022-01-13 13:37       ` Simon Glass
  2022-01-13 13:41         ` Tom Rini
  0 siblings, 1 reply; 77+ messages in thread
From: Simon Glass @ 2022-01-13 13:37 UTC (permalink / raw)
  To: Tom Rini
  Cc: Rasmus Villemoes, U-Boot Mailing List, Bin Meng,
	Ilias Apalodimas, Bill Mills, Heinrich Schuchardt,
	François Ozog

Hi Tom, Rasmus,

On Thu, 13 Jan 2022 at 06:07, Tom Rini <trini@konsulko.com> wrote:
>
> On Thu, Jan 13, 2022 at 09:08:13AM +0100, Rasmus Villemoes wrote:
> > On 01/11/2021 02.17, Simon Glass wrote:
> > > Some bright sparks have decided that a cast on a constant cannot be a
> > > constant, so offsetof() produces this warning on clang-10:
> > >
> > > include/intel_gnvs.h:113:1: error: static_assert expression is not an
> > >     integral constant expression
> > > check_member(acpi_global_nvs, unused2, GNVS_CHROMEOS_ACPI_OFFSET);
> > > ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > > include/linux/kernel.h:284:2: note: expanded from macro 'check_member'
> > >         offsetof(struct structure, member) == (offset), \
> > >         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > > include/linux/stddef.h:20:32: note: expanded from macro 'offsetof'
> > >                                 ^
> > > include/intel_gnvs.h:113:1: note: cast that performs the conversions of
> > >     a reinterpret_cast is ot allowed in a constant expression
> > > include/linux/stddef.h:20:33: note: expanded from macro 'offsetof'
> > >
> > > Fix it by using the compiler built-in version, if available.
> > >
> > > Signed-off-by: Simon Glass <sjg@chromium.org>
> > > ---
> > >
> > >  include/linux/stddef.h | 8 +++++++-
> > >  1 file changed, 7 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/include/linux/stddef.h b/include/linux/stddef.h
> > > index c540f6100d4..a7f546fdfe5 100644
> > > --- a/include/linux/stddef.h
> > > +++ b/include/linux/stddef.h
> > > @@ -1,6 +1,8 @@
> > >  #ifndef _LINUX_STDDEF_H
> > >  #define _LINUX_STDDEF_H
> > >
> > > +#include <linux/compiler_types.h>
> > > +
> > >  #undef NULL
> > >  #if defined(__cplusplus)
> > >  #define NULL 0
> > > @@ -14,7 +16,11 @@
> > >
> > >  #ifndef __CHECKER__
> > >  #undef offsetof
> > > -#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
> > > +#ifdef __compiler_offsetof
> > > +#define offsetof(TYPE, MEMBER)     __compiler_offsetof(TYPE, MEMBER)
> > > +#else
> > > +#define offsetof(TYPE, MEMBER)     ((size_t)&((TYPE *)0)->MEMBER)
> > > +#endif
> > >  #endif
> >
> >
> > Can we please just drop the useless indirections? Any compiler we care
> > about provides __builtin_offsetof(), so just make the whole thing
> >
> >   #undef offsetof
> >   #define offsetof(TYPE, MEMBER)  __builtin_offsetof(TYPE, MEMBER)
> >
> > And by "compilers we care about", that includes sparse - it has had
> > __builtin_offsetof ever since 2007.
> >
> > And we can nuke the __compiler_offsetof definition in compiler_types.h,
> > and if any users exist, just mechanically convert them to offsetof().
>
> We should re-sync this with upstream, but that will keep the indirection
> you're objecting to here, I think.

Yes, with this patch, this part of the file is the same as Linux (e.g. v5.16).

So I'd like to apply it as is and deal with improvements later.
Perhaps in lockstep with Linux?

Regards,
Simon

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 04/31] stddef: Avoid warning with clang with offsetof()
  2022-01-13 13:37       ` Simon Glass
@ 2022-01-13 13:41         ` Tom Rini
  2022-01-13 13:50           ` Simon Glass
  0 siblings, 1 reply; 77+ messages in thread
From: Tom Rini @ 2022-01-13 13:41 UTC (permalink / raw)
  To: Simon Glass
  Cc: Rasmus Villemoes, U-Boot Mailing List, Bin Meng,
	Ilias Apalodimas, Bill Mills, Heinrich Schuchardt,
	François Ozog

[-- Attachment #1: Type: text/plain, Size: 3347 bytes --]

On Thu, Jan 13, 2022 at 06:37:27AM -0700, Simon Glass wrote:
> Hi Tom, Rasmus,
> 
> On Thu, 13 Jan 2022 at 06:07, Tom Rini <trini@konsulko.com> wrote:
> >
> > On Thu, Jan 13, 2022 at 09:08:13AM +0100, Rasmus Villemoes wrote:
> > > On 01/11/2021 02.17, Simon Glass wrote:
> > > > Some bright sparks have decided that a cast on a constant cannot be a
> > > > constant, so offsetof() produces this warning on clang-10:
> > > >
> > > > include/intel_gnvs.h:113:1: error: static_assert expression is not an
> > > >     integral constant expression
> > > > check_member(acpi_global_nvs, unused2, GNVS_CHROMEOS_ACPI_OFFSET);
> > > > ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > > > include/linux/kernel.h:284:2: note: expanded from macro 'check_member'
> > > >         offsetof(struct structure, member) == (offset), \
> > > >         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > > > include/linux/stddef.h:20:32: note: expanded from macro 'offsetof'
> > > >                                 ^
> > > > include/intel_gnvs.h:113:1: note: cast that performs the conversions of
> > > >     a reinterpret_cast is ot allowed in a constant expression
> > > > include/linux/stddef.h:20:33: note: expanded from macro 'offsetof'
> > > >
> > > > Fix it by using the compiler built-in version, if available.
> > > >
> > > > Signed-off-by: Simon Glass <sjg@chromium.org>
> > > > ---
> > > >
> > > >  include/linux/stddef.h | 8 +++++++-
> > > >  1 file changed, 7 insertions(+), 1 deletion(-)
> > > >
> > > > diff --git a/include/linux/stddef.h b/include/linux/stddef.h
> > > > index c540f6100d4..a7f546fdfe5 100644
> > > > --- a/include/linux/stddef.h
> > > > +++ b/include/linux/stddef.h
> > > > @@ -1,6 +1,8 @@
> > > >  #ifndef _LINUX_STDDEF_H
> > > >  #define _LINUX_STDDEF_H
> > > >
> > > > +#include <linux/compiler_types.h>
> > > > +
> > > >  #undef NULL
> > > >  #if defined(__cplusplus)
> > > >  #define NULL 0
> > > > @@ -14,7 +16,11 @@
> > > >
> > > >  #ifndef __CHECKER__
> > > >  #undef offsetof
> > > > -#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
> > > > +#ifdef __compiler_offsetof
> > > > +#define offsetof(TYPE, MEMBER)     __compiler_offsetof(TYPE, MEMBER)
> > > > +#else
> > > > +#define offsetof(TYPE, MEMBER)     ((size_t)&((TYPE *)0)->MEMBER)
> > > > +#endif
> > > >  #endif
> > >
> > >
> > > Can we please just drop the useless indirections? Any compiler we care
> > > about provides __builtin_offsetof(), so just make the whole thing
> > >
> > >   #undef offsetof
> > >   #define offsetof(TYPE, MEMBER)  __builtin_offsetof(TYPE, MEMBER)
> > >
> > > And by "compilers we care about", that includes sparse - it has had
> > > __builtin_offsetof ever since 2007.
> > >
> > > And we can nuke the __compiler_offsetof definition in compiler_types.h,
> > > and if any users exist, just mechanically convert them to offsetof().
> >
> > We should re-sync this with upstream, but that will keep the indirection
> > you're objecting to here, I think.
> 
> Yes, with this patch, this part of the file is the same as Linux (e.g. v5.16).
> 
> So I'd like to apply it as is and deal with improvements later.
> Perhaps in lockstep with Linux?

Please re-word to be clear this is a functional re-sync with v5.16,
thanks!

-- 
Tom

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 04/31] stddef: Avoid warning with clang with offsetof()
  2022-01-13 13:41         ` Tom Rini
@ 2022-01-13 13:50           ` Simon Glass
  0 siblings, 0 replies; 77+ messages in thread
From: Simon Glass @ 2022-01-13 13:50 UTC (permalink / raw)
  To: Tom Rini
  Cc: Rasmus Villemoes, U-Boot Mailing List, Bin Meng,
	Ilias Apalodimas, Bill Mills, Heinrich Schuchardt,
	François Ozog

Hi Tom,

On Thu, 13 Jan 2022 at 06:41, Tom Rini <trini@konsulko.com> wrote:
>
> On Thu, Jan 13, 2022 at 06:37:27AM -0700, Simon Glass wrote:
> > Hi Tom, Rasmus,
> >
> > On Thu, 13 Jan 2022 at 06:07, Tom Rini <trini@konsulko.com> wrote:
> > >
> > > On Thu, Jan 13, 2022 at 09:08:13AM +0100, Rasmus Villemoes wrote:
> > > > On 01/11/2021 02.17, Simon Glass wrote:
> > > > > Some bright sparks have decided that a cast on a constant cannot be a
> > > > > constant, so offsetof() produces this warning on clang-10:
> > > > >
> > > > > include/intel_gnvs.h:113:1: error: static_assert expression is not an
> > > > >     integral constant expression
> > > > > check_member(acpi_global_nvs, unused2, GNVS_CHROMEOS_ACPI_OFFSET);
> > > > > ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > > > > include/linux/kernel.h:284:2: note: expanded from macro 'check_member'
> > > > >         offsetof(struct structure, member) == (offset), \
> > > > >         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > > > > include/linux/stddef.h:20:32: note: expanded from macro 'offsetof'
> > > > >                                 ^
> > > > > include/intel_gnvs.h:113:1: note: cast that performs the conversions of
> > > > >     a reinterpret_cast is ot allowed in a constant expression
> > > > > include/linux/stddef.h:20:33: note: expanded from macro 'offsetof'
> > > > >
> > > > > Fix it by using the compiler built-in version, if available.
> > > > >
> > > > > Signed-off-by: Simon Glass <sjg@chromium.org>
> > > > > ---
> > > > >
> > > > >  include/linux/stddef.h | 8 +++++++-
> > > > >  1 file changed, 7 insertions(+), 1 deletion(-)
> > > > >
> > > > > diff --git a/include/linux/stddef.h b/include/linux/stddef.h
> > > > > index c540f6100d4..a7f546fdfe5 100644
> > > > > --- a/include/linux/stddef.h
> > > > > +++ b/include/linux/stddef.h
> > > > > @@ -1,6 +1,8 @@
> > > > >  #ifndef _LINUX_STDDEF_H
> > > > >  #define _LINUX_STDDEF_H
> > > > >
> > > > > +#include <linux/compiler_types.h>
> > > > > +
> > > > >  #undef NULL
> > > > >  #if defined(__cplusplus)
> > > > >  #define NULL 0
> > > > > @@ -14,7 +16,11 @@
> > > > >
> > > > >  #ifndef __CHECKER__
> > > > >  #undef offsetof
> > > > > -#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
> > > > > +#ifdef __compiler_offsetof
> > > > > +#define offsetof(TYPE, MEMBER)     __compiler_offsetof(TYPE, MEMBER)
> > > > > +#else
> > > > > +#define offsetof(TYPE, MEMBER)     ((size_t)&((TYPE *)0)->MEMBER)
> > > > > +#endif
> > > > >  #endif
> > > >
> > > >
> > > > Can we please just drop the useless indirections? Any compiler we care
> > > > about provides __builtin_offsetof(), so just make the whole thing
> > > >
> > > >   #undef offsetof
> > > >   #define offsetof(TYPE, MEMBER)  __builtin_offsetof(TYPE, MEMBER)
> > > >
> > > > And by "compilers we care about", that includes sparse - it has had
> > > > __builtin_offsetof ever since 2007.
> > > >
> > > > And we can nuke the __compiler_offsetof definition in compiler_types.h,
> > > > and if any users exist, just mechanically convert them to offsetof().
> > >
> > > We should re-sync this with upstream, but that will keep the indirection
> > > you're objecting to here, I think.
> >
> > Yes, with this patch, this part of the file is the same as Linux (e.g. v5.16).
> >
> > So I'd like to apply it as is and deal with improvements later.
> > Perhaps in lockstep with Linux?
>
> Please re-word to be clear this is a functional re-sync with v5.16,
> thanks!

OK, I sent it and cc'd Rasmus too.

I was planning to apply the bloblist stuff this morning, so let me know...

Regards,
Simon

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 02/31] kconfig: Add support for conditional values
  2022-01-13 12:52           ` Tom Rini
@ 2022-01-13 13:56             ` Simon Glass
  2022-01-13 15:01             ` Rasmus Villemoes
  1 sibling, 0 replies; 77+ messages in thread
From: Simon Glass @ 2022-01-13 13:56 UTC (permalink / raw)
  To: Tom Rini
  Cc: Rasmus Villemoes, Ilias Apalodimas, U-Boot Mailing List,
	Bin Meng, Bill Mills, Heinrich Schuchardt, François Ozog,
	Masahiro Yamada

Hi,

On Thu, 13 Jan 2022 at 05:52, Tom Rini <trini@konsulko.com> wrote:
>
> On Thu, Jan 13, 2022 at 08:56:02AM +0100, Rasmus Villemoes wrote:
> > On 12/01/2022 22.56, Tom Rini wrote:
> > > On Wed, Jan 12, 2022 at 02:28:21PM -0700, Simon Glass wrote:
> > >> Hi Ilias,
> > >>
> > >> On Mon, 1 Nov 2021 at 01:05, Ilias Apalodimas
> > >> <ilias.apalodimas@linaro.org> wrote:
> > >>>
> > >>> On Mon, 1 Nov 2021 at 03:19, Simon Glass <sjg@chromium.org> wrote:
> > >>>>
> > >>>> At present if an optional Kconfig value needs to be used it must be
> > >>>> bracketed by #ifdef. For example, with this Kconfig setup:
> > >>>>
> > >>>> config WIBBLE
> > >>>>         bool "Support wibbles, the world needs more wibbles"
> > >>>>
> > >>>> config WIBBLE_ADDR
> > >>>>         hex "Address of the wibble"
> > >>>>         depends on WIBBLE
> > >>>>
> > >>>> then the following code must be used:
> > >>>>
> > >>>>  #ifdef CONFIG_WIBBLE
> > >>>>  static void handle_wibble(void)
> > >>>>  {
> > >>>>         int val = CONFIG_WIBBLE_ADDR;
> > >>>>
> > >>>>         ...
> > >>>>  }
> > >>>>  #endif
> > >>>>
> > >>>
> > >>> The example here might be a bit off and we might need this for int
> > >>> related values. Was this function handle_wibble() supposed to return
> > >>> an int or not?  We could shield the linker easier here without adding
> > >>> macros. Something along the lines of
> > >>> static void handle_wibble(void)
> > >>> {
> > >>> #ifdef CONFIG_WIBBLE
> > >>> int val = CONFIG_WIBBLE_ADDR;
> > >>> #endif
> > >>> }
> > >>>
> > >>> In that case you don't an extra ifdef to call handle_wibble().
> > >>> Personally I find this easier to read.
> > >>
> > >> But how does that help with the problem here? I am trying to avoid
> > >> using preprocessor macros in this case.
> > >
> > > I'm not sure I see a problem here.  A number of the finish-converting-X
> > > that I did recently had a guard symbol first because usage wasn't fully
> > > converted but really everyone using that area of code needed to set the
> > > value, or use the default.
> > >
> > > There might be some cases where we do still need a guard symbol because
> > > usage is in common code and maybe shouldn't be, but instead moved to
> > > other usage-specific files.
> > >
> > > I also think I've seen cases where doing:
> > > if (CONFIG_EVALUATES_TO_ZERO) {
> > >   ...
> > > }
> > >
> > > takes more space in the binary than an #ifdef does.
> >
> > Please provide a specific example. If CONFIG_EVALUATES_TO_ZERO is any
> > integer-constant-expression evaluating at compile-time to 0, gcc throws
> > away the whole block very early during parsing. If it doesn't, that's a
> > compiler bug, so let's please not make decisions based on
> > not-even-anecdotal data.
>
> OK.  I believe it was commit 7856cd5a6dd6 ("Convert CONFIG_SYS_PCI_64BIT
> to Kconfig") a few platforms changed size and as best I can tell, the
> used / evaluated value for CONFIG_SYS_PCI_64BIT didn't change.
>
> > > And finally for the moment, we also have many cases where zero is a
> > > valid value.  That's what leads to potentially harder to read code or
> > > needing a guard, I think.
> >
> > I like Simon's idea, but the replacement/fallback should _not_ be a
> > literal 0. We want a guarantee that the code has actually been discarded
> > by the compiler or linker (i.e., that the access is done in code that is
> > otherwise guarded by the "parent" Kconfig symbol), so instead the
> > fallback should be a call to (the nowhere defined of course)
> >
> > extern long invalid_use_of_IF_ENABLED_INT(void);
> >
> > Of course, if people don't build with -O2 and
> > -ffunction-sections,-fdata-sections and link with --gc-sections, that
> > may break, but why should we care?
>
> LTO also gets this correct I assume and yes, I like that better.

Yes it should work fine and it checks there is no effective access,
which is nice.

For now I'm going ahead with the bloblist series without this, but
I'll send an updated patch on its own.

Regards,
Simon

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 02/31] kconfig: Add support for conditional values
  2022-01-13 12:52           ` Tom Rini
  2022-01-13 13:56             ` Simon Glass
@ 2022-01-13 15:01             ` Rasmus Villemoes
  2022-01-13 15:29               ` Tom Rini
  1 sibling, 1 reply; 77+ messages in thread
From: Rasmus Villemoes @ 2022-01-13 15:01 UTC (permalink / raw)
  To: Tom Rini
  Cc: Simon Glass, Ilias Apalodimas, U-Boot Mailing List, Bin Meng,
	Bill Mills, Heinrich Schuchardt, François Ozog,
	Masahiro Yamada

On 13/01/2022 13.52, Tom Rini wrote:
> On Thu, Jan 13, 2022 at 08:56:02AM +0100, Rasmus Villemoes wrote:
>> On 12/01/2022 22.56, Tom Rini wrote:
>>> I also think I've seen cases where doing:
>>> if (CONFIG_EVALUATES_TO_ZERO) {
>>>   ...
>>> }
>>>
>>> takes more space in the binary than an #ifdef does.
>>
>> Please provide a specific example. If CONFIG_EVALUATES_TO_ZERO is any
>> integer-constant-expression evaluating at compile-time to 0, gcc throws
>> away the whole block very early during parsing. If it doesn't, that's a
>> compiler bug, so let's please not make decisions based on
>> not-even-anecdotal data.
> 
> OK.  I believe it was commit 7856cd5a6dd6 ("Convert CONFIG_SYS_PCI_64BIT
> to Kconfig") a few platforms changed size 

Can you remember which ones? I'd like to see if I can reproduce.

That said, that commit made the Kconfig symbol 'default y if PPC'. Are
you really sure all ppc-boards that set CONFIG_PCI also used to set
SYS_PCI_64BIT?

And another thing I notice is that a lot of the #define removals remove

#define CONFIG_SYS_PCI_64BIT

and not

#define CONFIG_SYS_PCI_64BIT 1

Now that doesn't matter for the places that test the definedness of
CONFIG_SYS_PCI_64BIT, because kconfig either doesn't define it or define
it with value 1. But it does matter for (the single) IS_ENABLED() use,
because IS_ENABLED(bla) evaluates to 1 if and only if bla expands to 1.
Or rather, if and only if __ARG_PLACEHOLDER_ concatenated with the
expansion of bla in turn expands to "0, " - which only happens if we hit
the __ARG_PLACEHOLDER_1 macro.

So when bla is defined with an empty expansion, for the purpose of
IS_ENABLED, it might as well not be defined or expand to 0 or to
gobbledygook.

And when one knows what to look for, it's easy to demonstrate:

$ export ARCH=ppc
$ export CROSS_COMPILE=powerpc-linux-gnu-
$ git checkout 7856cd5a6dd6~1
$ make T1042D4RDB_defconfig
$ make drivers/pci/pci-uclass.i
$ grep -C3 'beyond the 32-bit boundary' drivers/pci/pci-uclass.i

  if (!(0) &&
      type == 0x00000000 && ((u32)(((pci_addr) >> 16) >> 16))) {
   ({ if (0) printf(" - beyond the 32-bit boundary, ignoring\n"); });
   continue;
  }

$ git checkout 7856cd5a6dd6
$ make T1042D4RDB_defconfig
$ make drivers/pci/pci-uclass.i
$ grep -C3 'beyond the 32-bit boundary' drivers/pci/pci-uclass.i

  if (!(1) &&
      type == 0x00000000 && ((u32)(((pci_addr) >> 16) >> 16))) {
   ({ if (0) printf(" - beyond the 32-bit boundary, ignoring\n"); });
   continue;
  }

Whether that change makes the generated code smaller or larger I can't
say, but it's certainly not a nop semantically. [Of course, the change
is for the better, as the generated code now matches the intention;
previously 64 bit pci addresses would be ignored for the boards that had
an empty definition of CONFIG_SYS_PCI_64BIT.]

But it has nothing whatsoever to do with whether gcc is capable of
throwing away a whole "if (0)" block. But I will believe that other
Kconfig conversions have been bit by the same issue, making it _seem_
like IS_ENABLED() is somehow at fault and #ifdefs are "better".

Rasmus

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 02/31] kconfig: Add support for conditional values
  2022-01-13 15:01             ` Rasmus Villemoes
@ 2022-01-13 15:29               ` Tom Rini
  0 siblings, 0 replies; 77+ messages in thread
From: Tom Rini @ 2022-01-13 15:29 UTC (permalink / raw)
  To: Rasmus Villemoes
  Cc: Simon Glass, Ilias Apalodimas, U-Boot Mailing List, Bin Meng,
	Bill Mills, Heinrich Schuchardt, François Ozog,
	Masahiro Yamada

[-- Attachment #1: Type: text/plain, Size: 3624 bytes --]

On Thu, Jan 13, 2022 at 04:01:45PM +0100, Rasmus Villemoes wrote:
> On 13/01/2022 13.52, Tom Rini wrote:
> > On Thu, Jan 13, 2022 at 08:56:02AM +0100, Rasmus Villemoes wrote:
> >> On 12/01/2022 22.56, Tom Rini wrote:
> >>> I also think I've seen cases where doing:
> >>> if (CONFIG_EVALUATES_TO_ZERO) {
> >>>   ...
> >>> }
> >>>
> >>> takes more space in the binary than an #ifdef does.
> >>
> >> Please provide a specific example. If CONFIG_EVALUATES_TO_ZERO is any
> >> integer-constant-expression evaluating at compile-time to 0, gcc throws
> >> away the whole block very early during parsing. If it doesn't, that's a
> >> compiler bug, so let's please not make decisions based on
> >> not-even-anecdotal data.
> > 
> > OK.  I believe it was commit 7856cd5a6dd6 ("Convert CONFIG_SYS_PCI_64BIT
> > to Kconfig") a few platforms changed size 
> 
> Can you remember which ones? I'd like to see if I can reproduce.
> 
> That said, that commit made the Kconfig symbol 'default y if PPC'. Are
> you really sure all ppc-boards that set CONFIG_PCI also used to set
> SYS_PCI_64BIT?
> 
> And another thing I notice is that a lot of the #define removals remove
> 
> #define CONFIG_SYS_PCI_64BIT
> 
> and not
> 
> #define CONFIG_SYS_PCI_64BIT 1
> 
> Now that doesn't matter for the places that test the definedness of
> CONFIG_SYS_PCI_64BIT, because kconfig either doesn't define it or define
> it with value 1. But it does matter for (the single) IS_ENABLED() use,
> because IS_ENABLED(bla) evaluates to 1 if and only if bla expands to 1.
> Or rather, if and only if __ARG_PLACEHOLDER_ concatenated with the
> expansion of bla in turn expands to "0, " - which only happens if we hit
> the __ARG_PLACEHOLDER_1 macro.
> 
> So when bla is defined with an empty expansion, for the purpose of
> IS_ENABLED, it might as well not be defined or expand to 0 or to
> gobbledygook.
> 
> And when one knows what to look for, it's easy to demonstrate:
> 
> $ export ARCH=ppc
> $ export CROSS_COMPILE=powerpc-linux-gnu-
> $ git checkout 7856cd5a6dd6~1
> $ make T1042D4RDB_defconfig
> $ make drivers/pci/pci-uclass.i
> $ grep -C3 'beyond the 32-bit boundary' drivers/pci/pci-uclass.i
> 
>   if (!(0) &&
>       type == 0x00000000 && ((u32)(((pci_addr) >> 16) >> 16))) {
>    ({ if (0) printf(" - beyond the 32-bit boundary, ignoring\n"); });
>    continue;
>   }
> 
> $ git checkout 7856cd5a6dd6
> $ make T1042D4RDB_defconfig
> $ make drivers/pci/pci-uclass.i
> $ grep -C3 'beyond the 32-bit boundary' drivers/pci/pci-uclass.i
> 
>   if (!(1) &&
>       type == 0x00000000 && ((u32)(((pci_addr) >> 16) >> 16))) {
>    ({ if (0) printf(" - beyond the 32-bit boundary, ignoring\n"); });
>    continue;
>   }
> 
> Whether that change makes the generated code smaller or larger I can't
> say, but it's certainly not a nop semantically. [Of course, the change
> is for the better, as the generated code now matches the intention;
> previously 64 bit pci addresses would be ignored for the boards that had
> an empty definition of CONFIG_SYS_PCI_64BIT.]
> 
> But it has nothing whatsoever to do with whether gcc is capable of
> throwing away a whole "if (0)" block. But I will believe that other
> Kconfig conversions have been bit by the same issue, making it _seem_
> like IS_ENABLED() is somehow at fault and #ifdefs are "better".

Yes, that's what happened there, thanks for digging in and explaining.
What I really meant by "better" was "same size when converting" which is
important when migrating a ton of machines I can only very partially
test.

-- 
Tom

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]

^ permalink raw reply	[flat|nested] 77+ messages in thread

end of thread, other threads:[~2022-01-13 15:29 UTC | newest]

Thread overview: 77+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-01  1:17 [PATCH 00/31] passage: Define a standard for firmware data flow Simon Glass
2021-11-01  1:17 ` Simon Glass
2021-11-01  1:17 ` [PATCH 01/31] Makefile: Correct TPL rule for OF_REAL Simon Glass
2021-11-01  6:54   ` Ilias Apalodimas
2021-11-14  0:34   ` Simon Glass
2021-11-01  1:17 ` [PATCH 02/31] kconfig: Add support for conditional values Simon Glass
2021-11-01  7:05   ` Ilias Apalodimas
2022-01-12 21:28     ` Simon Glass
2022-01-12 21:56       ` Tom Rini
2022-01-12 22:22         ` Simon Glass
2022-01-12 23:04           ` Tom Rini
2022-01-13  7:56         ` Rasmus Villemoes
2022-01-13 12:52           ` Tom Rini
2022-01-13 13:56             ` Simon Glass
2022-01-13 15:01             ` Rasmus Villemoes
2022-01-13 15:29               ` Tom Rini
2021-11-01  1:17 ` [PATCH 03/31] dm: core: Allow getting some basic stats Simon Glass
2021-11-01  7:07   ` Ilias Apalodimas
2021-11-01  1:17 ` [PATCH 04/31] stddef: Avoid warning with clang with offsetof() Simon Glass
2022-01-13  8:08   ` Rasmus Villemoes
2022-01-13 13:07     ` Tom Rini
2022-01-13 13:37       ` Simon Glass
2022-01-13 13:41         ` Tom Rini
2022-01-13 13:50           ` Simon Glass
2021-11-01  1:17 ` [PATCH 05/31] fdt: Drop SPL_BUILD macro Simon Glass
2021-11-01  7:42   ` Ilias Apalodimas
2021-11-01  1:17 ` [PATCH 06/31] bloblist: Put the magic number first Simon Glass
2021-11-01  1:17 ` [PATCH 07/31] bloblist: Rename the SPL tag Simon Glass
2021-11-01  1:17 ` [PATCH 08/31] bloblist: Drop unused tags Simon Glass
2021-11-01  1:17 ` [PATCH 09/31] bloblist: Use explicit numbering for the tags Simon Glass
2021-11-01  1:17 ` [PATCH 10/31] bloblist: Support allocating the bloblist Simon Glass
2021-11-01  1:17 ` [PATCH 11/31] bloblist: Use LOG_CATEGORY to simply logging Simon Glass
2021-11-01  1:17 ` [PATCH 12/31] bloblist: Use 'phase' consistently for bloblists Simon Glass
2021-11-01  1:17 ` [PATCH 13/31] bloblist: Refactor Kconfig to support alloc or fixed Simon Glass
2021-11-01  1:17 ` [PATCH 14/31] arm: qemu: Add an SPL build Simon Glass
2021-11-01  1:17   ` Simon Glass
2021-11-01  1:17 ` [PATCH 15/31] bloblist: Add functions to obtain base address and size Simon Glass
2021-11-01  1:17 ` [PATCH 16/31] passage: Support an incoming passage Simon Glass
2021-11-01  1:17 ` [PATCH 17/31] passage: Support a control devicetree Simon Glass
2021-11-01  1:17 ` [PATCH 18/31] passage: arm: Accept a passage from the previous phase Simon Glass
2021-11-01  1:17 ` [PATCH 19/31] passage: spl: Support adding the dtb to the passage bloblist Simon Glass
2021-11-01  1:17 ` [PATCH 20/31] passage: spl: Support passing the passage to U-Boot Simon Glass
2021-11-01  1:17 ` [PATCH 21/31] passage: Record where the devicetree came from Simon Glass
2021-11-01  1:17 ` [PATCH 22/31] passage: Report the devicetree source Simon Glass
2021-11-01  1:17 ` [PATCH 23/31] passage: Add a qemu test for ARM Simon Glass
2021-11-01  1:17 ` [PATCH 24/31] bloblist: doc: Bring in the API documentation Simon Glass
2021-11-01  1:17 ` [PATCH 25/31] bloblist: Relicense to allow BSD-3-Clause Simon Glass
2021-11-01  1:17 ` [PATCH 26/31] sandbox: Add a way of checking structs for standard passage Simon Glass
2021-11-01  1:17 ` [PATCH 27/31] passage: Add documentation Simon Glass
2021-11-01  1:17 ` [PATCH 28/31] passage: Add docs for spl_handoff Simon Glass
2021-11-01  1:17 ` [PATCH 29/31] x86: Move Intel GNVS file into the common include directory Simon Glass
2021-11-01  1:17 ` [PATCH 30/31] passage: Add checks for pre-existing blobs Simon Glass
2021-11-01  1:17 ` [PATCH 31/31] WIP: RFC: Add a gitlab test Simon Glass
2021-11-01  8:53 ` [PATCH 00/31] passage: Define a standard for firmware data flow François Ozog
2021-11-01  8:53   ` François Ozog
2021-11-01 18:19   ` Mark Kettenis
2021-11-01 18:19     ` Mark Kettenis
2021-11-01 20:45     ` François Ozog
2021-11-01 20:45       ` François Ozog
2021-11-02 14:58   ` Simon Glass
2021-11-02 14:58     ` Simon Glass
2021-11-02 16:03     ` François Ozog
2021-11-02 16:03       ` François Ozog
2021-11-05  2:02       ` Simon Glass
2021-11-05  2:02         ` Simon Glass
2021-11-05  8:26         ` François Ozog
2021-11-05  8:26           ` François Ozog
2021-11-05 16:12           ` Simon Glass
2021-11-05 16:12             ` Simon Glass
2021-11-05 16:31             ` François Ozog
2021-11-05 16:31               ` François Ozog
2021-11-05 17:16               ` Simon Glass
2021-11-05 17:16                 ` Simon Glass
2021-11-08 16:20                 ` François Ozog
2021-11-08 16:20                   ` François Ozog
2021-11-10 19:37                   ` Simon Glass
2021-11-10 19:37                     ` Simon Glass

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.