All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/16] passage: Define a standard for firmware data flow
@ 2022-01-17 15:04 Simon Glass
  2022-01-17 15:04 ` [PATCH v2 01/16] spl: Tidy up the header includes Simon Glass
                   ` (15 more replies)
  0 siblings, 16 replies; 18+ messages in thread
From: Simon Glass @ 2022-01-17 15:04 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Ilias Apalodimas, Tom Rini, François Ozog,
	Heinrich Schuchardt, Bill Mills, Simon Glass, Albert Aribaud,
	Alexandru Gagniuc, Anatolij Gustschin, Artem Lapkin,
	Bharat Gooty, Bin Meng, Chia-Wei Wang, Daniel Schwierzeck,
	Dario Binacchi, Fabio Estevam, Harald Seiler, Heiko Schocher,
	Joel Peshkin, Jorge Ramirez-Ortiz, Kristian Amlie,
	Kunihiko Hayashi, Leo, Lukasz Majewski, Marek Vasut, Marek Vasut,
	Mario Six, Matthias Brugger, Michal Simek, NXP i.MX U-Boot Team,
	Pali Rohár, Patrick Delaunay, Peng Fan, Rasmus Villemoes,
	Rayagonda Kokatanur, Ricardo Salveti, Rick Chen, Stefan Roese,
	Stefano Babic, Tom Warren, Tuomas Tynkkynen, Ye Li


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. This
should cover all cases (small memory footprint as well as complex data
flow) and be easy enough to implement on all architectures.

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 available at u-boot-dm/pass-working

Changes in v2:
- Add a devicetree for qemu-arm so that qemu_arm_spl can work
- Add comments about how to pass standard passage to EFI
- Add comments about passing a bloblist to Linux
- Add detailed arch-specific information
- Add new patch with the arm-specific standard passage implementation
- Incorporate devicetree source
- Make the stdpass calling standard arch-specific
- Rebase to master
- Rebase to master (dropping bloblist patches already applied)
- Rework global_data for new stdpass convention
- Split the jump_to_image_no_args() change into its own patch
- Use three registers instead of two for the entry

Simon Glass (16):
  spl: Tidy up the header includes
  arm: qemu: Add an SPL build
  spl: Rename jump_to_image_no_args()
  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: arm: Add the arch-specific standard passage impl
  passage: Add a qemu test for ARM
  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 +
 arch/arm/Kconfig                              |   2 +-
 arch/arm/cpu/armv7/cpu.c                      |  28 ++
 arch/arm/cpu/armv7/start.S                    |   7 +-
 arch/arm/cpu/armv8/cpu.c                      |  20 +
 arch/arm/dts/qemu-arm-u-boot.dtsi             |  22 +
 arch/arm/dts/qemu-arm.dts                     | 393 ++++++++++++++++-
 arch/arm/lib/crt0.S                           |   5 +
 arch/arm/mach-imx/imx8ulp/soc.c               |   2 +-
 arch/arm/mach-imx/spl.c                       |   2 +-
 arch/arm/mach-k3/common.c                     |   2 +-
 arch/arm/mach-omap2/boot-common.c             |   2 +-
 arch/arm/mach-qemu/Kconfig                    |   9 +
 arch/arm/mach-tegra/spl.c                     |   2 +-
 arch/mips/lib/spl.c                           |   2 +-
 arch/riscv/lib/spl.c                          |   2 +-
 arch/sandbox/cpu/spl.c                        |   4 +-
 arch/x86/cpu/apollolake/acpi.c                |   2 +-
 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/freescale/common/fsl_chain_of_trust.c   |   2 +-
 board/google/chromebook_coral/coral.c         |   2 +-
 board/renesas/rcar-common/gen3-spl.c          |   2 +-
 board/sandbox/Makefile                        |   3 +-
 board/sandbox/stdpass_check.c                 | 107 +++++
 common/Kconfig                                |  51 +++
 common/bloblist.c                             |   8 +-
 common/board_f.c                              |  48 ++-
 common/spl/spl.c                              |  95 ++++-
 configs/qemu_arm_spl_defconfig                |  78 ++++
 doc/board/emulation/qemu-arm.rst              |  37 ++
 doc/develop/bloblist.rst                      |   4 +-
 doc/develop/index.rst                         |   1 +
 doc/develop/std_passage.rst                   | 396 ++++++++++++++++++
 drivers/usb/gadget/f_sdp.c                    |   2 +-
 dts/Kconfig                                   |  12 +
 include/asm-generic/global_data.h             |  38 ++
 include/bloblist.h                            |   1 +
 include/fdtdec.h                              |   4 +
 include/handoff.h                             |   8 +-
 .../x86/include/asm => include}/intel_gnvs.h  |   0
 include/passage.h                             |  28 ++
 include/spl.h                                 |   4 +-
 include/stdpass/README                        |   4 +
 include/stdpass/tpm2_eventlog.h               |  42 ++
 include/stdpass/vboot_ctx.h                   | 267 ++++++++++++
 lib/asm-offsets.c                             |   6 +
 lib/fdtdec.c                                  |  33 ++
 test/py/tests/test_passage.py                 |  11 +
 56 files changed, 1804 insertions(+), 72 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/passage.h
 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.34.1.703.g22d0c6ccf7-goog


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

* [PATCH v2 01/16] spl: Tidy up the header includes
  2022-01-17 15:04 [PATCH v2 00/16] passage: Define a standard for firmware data flow Simon Glass
@ 2022-01-17 15:04 ` Simon Glass
  2022-01-17 15:04 ` [PATCH v2 02/16] arm: qemu: Add an SPL build Simon Glass
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Simon Glass @ 2022-01-17 15:04 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Ilias Apalodimas, Tom Rini, François Ozog,
	Heinrich Schuchardt, Bill Mills, Simon Glass, Alexandru Gagniuc,
	Bin Meng, Pali Rohár, Patrick Delaunay

These are out of order. Fix them.

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

(no changes since v1)

 common/spl/spl.c | 20 +++++++++-----------
 1 file changed, 9 insertions(+), 11 deletions(-)

diff --git a/common/spl/spl.c b/common/spl/spl.c
index f51d1f32052..932ad53614d 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -9,33 +9,31 @@
 #include <common.h>
 #include <bloblist.h>
 #include <binman_sym.h>
+#include <bootcount.h>
 #include <bootstage.h>
 #include <dm.h>
+#include <fdt_support.h>
 #include <handoff.h>
 #include <hang.h>
+#include <image.h>
 #include <init.h>
 #include <irq_func.h>
 #include <log.h>
+#include <malloc.h>
 #include <mapmem.h>
+#include <nand.h>
 #include <serial.h>
 #include <spl.h>
-#include <asm/global_data.h>
-#include <asm/u-boot.h>
-#include <nand.h>
-#include <fat.h>
-#include <u-boot/crc.h>
 #if CONFIG_IS_ENABLED(BANNER_PRINT)
 #include <timestamp.h>
 #endif
 #include <version.h>
-#include <image.h>
-#include <malloc.h>
-#include <mapmem.h>
+#include <wdt.h>
+#include <asm/global_data.h>
+#include <asm/u-boot.h>
 #include <dm/root.h>
 #include <linux/compiler.h>
-#include <fdt_support.h>
-#include <bootcount.h>
-#include <wdt.h>
+#include <u-boot/crc.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
-- 
2.34.1.703.g22d0c6ccf7-goog


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

* [PATCH v2 02/16] arm: qemu: Add an SPL build
  2022-01-17 15:04 [PATCH v2 00/16] passage: Define a standard for firmware data flow Simon Glass
  2022-01-17 15:04 ` [PATCH v2 01/16] spl: Tidy up the header includes Simon Glass
@ 2022-01-17 15:04 ` Simon Glass
  2022-01-17 15:04 ` [PATCH v2 03/16] spl: Rename jump_to_image_no_args() Simon Glass
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Simon Glass @ 2022-01-17 15:04 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Ilias Apalodimas, Tom Rini, François Ozog,
	Heinrich Schuchardt, Bill Mills, Simon Glass, Albert Aribaud,
	Tuomas Tynkkynen

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.
This requires adding a proper devicetree file for qemu_arm. It is only
used for the SPL build.

For now this just boots to a prompt.

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

(no changes since v1)

 arch/arm/dts/qemu-arm-u-boot.dtsi    |  22 ++
 arch/arm/dts/qemu-arm.dts            | 393 ++++++++++++++++++++++++++-
 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     |  37 +++
 9 files changed, 580 insertions(+), 5 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/dts/qemu-arm.dts b/arch/arm/dts/qemu-arm.dts
index 230c630f04f..fed558ced98 100644
--- a/arch/arm/dts/qemu-arm.dts
+++ b/arch/arm/dts/qemu-arm.dts
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0+ OR MIT
 /*
- * Empty device tree for qemu_arm
+ * Sample device tree for qemu_arm
 
  * Copyright 2021 Google LLC
  */
@@ -8,4 +8,395 @@
 /dts-v1/;
 
 / {
+	interrupt-parent = <0x8001>;
+	#size-cells = <0x02>;
+	#address-cells = <0x02>;
+	compatible = "linux,dummy-virt";
+
+	psci {
+		migrate = <0x84000005>;
+		cpu_on = <0x84000003>;
+		cpu_off = <0x84000002>;
+		cpu_suspend = <0x84000001>;
+		method = "hvc";
+		compatible = "arm,psci-0.2\0arm,psci";
+	};
+
+	memory@40000000 {
+		reg = <0x00 0x40000000 0x00 0x8000000>;
+		device_type = "memory";
+	};
+
+	platform@c000000 {
+		interrupt-parent = <0x8001>;
+		ranges = <0x00 0x00 0xc000000 0x2000000>;
+		#address-cells = <0x01>;
+		#size-cells = <0x01>;
+		compatible = "qemu,platform\0simple-bus";
+	};
+
+	fw-cfg@9020000 {
+		dma-coherent;
+		reg = <0x00 0x9020000 0x00 0x18>;
+		compatible = "qemu,fw-cfg-mmio";
+	};
+
+	virtio_mmio@a000000 {
+		dma-coherent;
+		interrupts = <0x00 0x10 0x01>;
+		reg = <0x00 0xa000000 0x00 0x200>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@a000200 {
+		dma-coherent;
+		interrupts = <0x00 0x11 0x01>;
+		reg = <0x00 0xa000200 0x00 0x200>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@a000400 {
+		dma-coherent;
+		interrupts = <0x00 0x12 0x01>;
+		reg = <0x00 0xa000400 0x00 0x200>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@a000600 {
+		dma-coherent;
+		interrupts = <0x00 0x13 0x01>;
+		reg = <0x00 0xa000600 0x00 0x200>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@a000800 {
+		dma-coherent;
+		interrupts = <0x00 0x14 0x01>;
+		reg = <0x00 0xa000800 0x00 0x200>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@a000a00 {
+		dma-coherent;
+		interrupts = <0x00 0x15 0x01>;
+		reg = <0x00 0xa000a00 0x00 0x200>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@a000c00 {
+		dma-coherent;
+		interrupts = <0x00 0x16 0x01>;
+		reg = <0x00 0xa000c00 0x00 0x200>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@a000e00 {
+		dma-coherent;
+		interrupts = <0x00 0x17 0x01>;
+		reg = <0x00 0xa000e00 0x00 0x200>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@a001000 {
+		dma-coherent;
+		interrupts = <0x00 0x18 0x01>;
+		reg = <0x00 0xa001000 0x00 0x200>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@a001200 {
+		dma-coherent;
+		interrupts = <0x00 0x19 0x01>;
+		reg = <0x00 0xa001200 0x00 0x200>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@a001400 {
+		dma-coherent;
+		interrupts = <0x00 0x1a 0x01>;
+		reg = <0x00 0xa001400 0x00 0x200>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@a001600 {
+		dma-coherent;
+		interrupts = <0x00 0x1b 0x01>;
+		reg = <0x00 0xa001600 0x00 0x200>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@a001800 {
+		dma-coherent;
+		interrupts = <0x00 0x1c 0x01>;
+		reg = <0x00 0xa001800 0x00 0x200>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@a001a00 {
+		dma-coherent;
+		interrupts = <0x00 0x1d 0x01>;
+		reg = <0x00 0xa001a00 0x00 0x200>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@a001c00 {
+		dma-coherent;
+		interrupts = <0x00 0x1e 0x01>;
+		reg = <0x00 0xa001c00 0x00 0x200>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@a001e00 {
+		dma-coherent;
+		interrupts = <0x00 0x1f 0x01>;
+		reg = <0x00 0xa001e00 0x00 0x200>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@a002000 {
+		dma-coherent;
+		interrupts = <0x00 0x20 0x01>;
+		reg = <0x00 0xa002000 0x00 0x200>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@a002200 {
+		dma-coherent;
+		interrupts = <0x00 0x21 0x01>;
+		reg = <0x00 0xa002200 0x00 0x200>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@a002400 {
+		dma-coherent;
+		interrupts = <0x00 0x22 0x01>;
+		reg = <0x00 0xa002400 0x00 0x200>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@a002600 {
+		dma-coherent;
+		interrupts = <0x00 0x23 0x01>;
+		reg = <0x00 0xa002600 0x00 0x200>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@a002800 {
+		dma-coherent;
+		interrupts = <0x00 0x24 0x01>;
+		reg = <0x00 0xa002800 0x00 0x200>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@a002a00 {
+		dma-coherent;
+		interrupts = <0x00 0x25 0x01>;
+		reg = <0x00 0xa002a00 0x00 0x200>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@a002c00 {
+		dma-coherent;
+		interrupts = <0x00 0x26 0x01>;
+		reg = <0x00 0xa002c00 0x00 0x200>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@a002e00 {
+		dma-coherent;
+		interrupts = <0x00 0x27 0x01>;
+		reg = <0x00 0xa002e00 0x00 0x200>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@a003000 {
+		dma-coherent;
+		interrupts = <0x00 0x28 0x01>;
+		reg = <0x00 0xa003000 0x00 0x200>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@a003200 {
+		dma-coherent;
+		interrupts = <0x00 0x29 0x01>;
+		reg = <0x00 0xa003200 0x00 0x200>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@a003400 {
+		dma-coherent;
+		interrupts = <0x00 0x2a 0x01>;
+		reg = <0x00 0xa003400 0x00 0x200>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@a003600 {
+		dma-coherent;
+		interrupts = <0x00 0x2b 0x01>;
+		reg = <0x00 0xa003600 0x00 0x200>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@a003800 {
+		dma-coherent;
+		interrupts = <0x00 0x2c 0x01>;
+		reg = <0x00 0xa003800 0x00 0x200>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@a003a00 {
+		dma-coherent;
+		interrupts = <0x00 0x2d 0x01>;
+		reg = <0x00 0xa003a00 0x00 0x200>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@a003c00 {
+		dma-coherent;
+		interrupts = <0x00 0x2e 0x01>;
+		reg = <0x00 0xa003c00 0x00 0x200>;
+		compatible = "virtio,mmio";
+	};
+
+	virtio_mmio@a003e00 {
+		dma-coherent;
+		interrupts = <0x00 0x2f 0x01>;
+		reg = <0x00 0xa003e00 0x00 0x200>;
+		compatible = "virtio,mmio";
+	};
+
+	gpio-keys {
+		#address-cells = <0x01>;
+		#size-cells = <0x00>;
+		compatible = "gpio-keys";
+
+		poweroff {
+			gpios = <0x8003 0x03 0x00>;
+			linux,code = <0x74>;
+			label = "GPIO Key Poweroff";
+		};
+	};
+
+	pl061@9030000 {
+		phandle = <0x8003>;
+		clock-names = "apb_pclk";
+		clocks = <0x8000>;
+		interrupts = <0x00 0x07 0x04>;
+		gpio-controller;
+		#gpio-cells = <0x02>;
+		compatible = "arm,pl061\0arm,primecell";
+		reg = <0x00 0x9030000 0x00 0x1000>;
+	};
+
+	pcie@10000000 {
+		interrupt-map-mask = <0x1800 0x00 0x00 0x07>;
+		interrupt-map = <0x00 0x00 0x00 0x01 0x8001 0x00 0x00 0x00
+			0x03 0x04 0x00 0x00 0x00 0x02 0x8001 0x00
+			0x00 0x00 0x04 0x04 0x00 0x00 0x00 0x03
+			0x8001 0x00 0x00 0x00 0x05 0x04 0x00 0x00
+			0x00 0x04 0x8001 0x00 0x00 0x00 0x06 0x04
+			0x800 0x00 0x00 0x01 0x8001 0x00 0x00 0x00
+			0x04 0x04 0x800 0x00 0x00 0x02 0x8001 0x00
+			0x00 0x00 0x05 0x04 0x800 0x00 0x00 0x03
+			0x8001 0x00 0x00 0x00 0x06 0x04 0x800 0x00
+			0x00 0x04 0x8001 0x00 0x00 0x00 0x03 0x04
+			0x1000 0x00 0x00 0x01 0x8001 0x00 0x00 0x00
+			0x05 0x04 0x1000 0x00 0x00 0x02 0x8001 0x00
+			0x00 0x00 0x06 0x04 0x1000 0x00 0x00 0x03
+			0x8001 0x00 0x00 0x00 0x03 0x04 0x1000 0x00
+			0x00 0x04 0x8001 0x00 0x00 0x00 0x04 0x04
+			0x1800 0x00 0x00 0x01 0x8001 0x00 0x00 0x00
+			0x06 0x04 0x1800 0x00 0x00 0x02 0x8001 0x00
+			0x00 0x00 0x03 0x04 0x1800 0x00 0x00 0x03
+			0x8001 0x00 0x00 0x00 0x04 0x04 0x1800 0x00
+			0x00 0x04 0x8001 0x00 0x00 0x00 0x05 0x04>;
+		#interrupt-cells = <0x01>;
+		ranges = <0x1000000 0x00 0x00 0x00
+			0x3eff0000 0x00 0x10000 0x2000000
+			0x00 0x10000000 0x00 0x10000000
+			0x00 0x2eff0000 0x3000000 0x80
+			0x00 0x80 0x00 0x80
+			0x00>;
+		reg = <0x00000000 0x3f000000 0x00000000 0x01000000>;
+		msi-parent = <0x8002>;
+		dma-coherent;
+		bus-range = <0x00 0x0f>;
+		linux,pci-domain = <0x00>;
+		#size-cells = <0x02>;
+		#address-cells = <0x03>;
+		device_type = "pci";
+		compatible = "pci-host-ecam-generic";
+	};
+
+	pl031@9010000 {
+		clock-names = "apb_pclk";
+		clocks = <0x8000>;
+		interrupts = <0x00 0x02 0x04>;
+		reg = <0x00 0x9010000 0x00 0x1000>;
+		compatible = "arm,pl031\0arm,primecell";
+	};
+
+	pl011@9000000 {
+		clock-names = "uartclk\0apb_pclk";
+		clocks = <0x8000 0x8000>;
+		interrupts = <0x00 0x01 0x04>;
+		reg = <0x00 0x9000000 0x00 0x1000>;
+		compatible = "arm,pl011\0arm,primecell";
+	};
+
+	pmu {
+	};
+
+	intc@8000000 {
+		phandle = <0x8001>;
+		reg = <0x00 0x8000000 0x00 0x10000 0x00 0x8010000 0x00 0x10000>;
+		compatible = "arm,cortex-a15-gic";
+		ranges;
+		#size-cells = <0x02>;
+		#address-cells = <0x02>;
+		interrupt-controller;
+		#interrupt-cells = <0x03>;
+
+		v2m@8020000 {
+			phandle = <0x8002>;
+			reg = <0x00 0x8020000 0x00 0x1000>;
+			msi-controller;
+			compatible = "arm,gic-v2m-frame";
+		};
+	};
+
+	flash@0 {
+		bank-width = <0x04>;
+		reg = <0x00 0x00 0x00 0x4000000 0x00 0x4000000 0x00 0x4000000>;
+		compatible = "cfi-flash";
+	};
+
+	cpus {
+		#size-cells = <0x00>;
+		#address-cells = <0x01>;
+
+		cpu@0 {
+			reg = <0x00>;
+			compatible = "arm,cortex-a15";
+			device_type = "cpu";
+		};
+	};
+
+	timer {
+		interrupts = <0x01 0x0d 0x104 0x01 0x0e 0x104 0x01 0x0b 0x104 0x01 0x0a 0x104>;
+		always-on;
+		compatible = "arm,armv7-timer";
+	};
+
+	apb-pclk {
+		phandle = <0x8000>;
+		clock-output-names = "clk24mhz";
+		clock-frequency = <0x16e3600>;
+		#clock-cells = <0x00>;
+		compatible = "fixed-clock";
+	};
+
+	chosen {
+		stdout-path = "/pl011@9000000";
+	};
 };
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 16f66388eb1..931a8ad05b7 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.
@@ -115,6 +124,34 @@ Enable the TPM on U-Boot's command line with::
 
     tpm2 startup TPM2_SU_CLEAR
 
+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.34.1.703.g22d0c6ccf7-goog


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

* [PATCH v2 03/16] spl: Rename jump_to_image_no_args()
  2022-01-17 15:04 [PATCH v2 00/16] passage: Define a standard for firmware data flow Simon Glass
  2022-01-17 15:04 ` [PATCH v2 01/16] spl: Tidy up the header includes Simon Glass
  2022-01-17 15:04 ` [PATCH v2 02/16] arm: qemu: Add an SPL build Simon Glass
@ 2022-01-17 15:04 ` Simon Glass
  2022-01-17 15:04 ` [PATCH v2 04/16] passage: Support an incoming passage Simon Glass
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Simon Glass @ 2022-01-17 15:04 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Ilias Apalodimas, Tom Rini, François Ozog,
	Heinrich Schuchardt, Bill Mills, Simon Glass, Alexandru Gagniuc,
	Bin Meng, Daniel Schwierzeck, Fabio Estevam, Harald Seiler, Leo,
	Lukasz Majewski, Marek Vasut, NXP i.MX U-Boot Team,
	Pali Rohár, Patrick Delaunay, Peng Fan, Ricardo Salveti,
	Rick Chen, Stefan Roese, Stefano Babic, Tom Warren, Ye Li

This is about to become a misnomer since with standard passage we need to
pass arguments to U-Boot. Rename the function.

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

Changes in v2:
- Split the jump_to_image_no_args() change into its own patch

 arch/arm/mach-imx/imx8ulp/soc.c             | 2 +-
 arch/arm/mach-imx/spl.c                     | 2 +-
 arch/arm/mach-k3/common.c                   | 2 +-
 arch/arm/mach-omap2/boot-common.c           | 2 +-
 arch/arm/mach-tegra/spl.c                   | 2 +-
 arch/mips/lib/spl.c                         | 2 +-
 arch/riscv/lib/spl.c                        | 2 +-
 arch/sandbox/cpu/spl.c                      | 4 ++--
 arch/x86/lib/spl.c                          | 2 +-
 arch/x86/lib/tpl.c                          | 2 +-
 board/freescale/common/fsl_chain_of_trust.c | 2 +-
 board/renesas/rcar-common/gen3-spl.c        | 2 +-
 common/spl/spl.c                            | 4 ++--
 drivers/usb/gadget/f_sdp.c                  | 2 +-
 include/spl.h                               | 2 +-
 15 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/arch/arm/mach-imx/imx8ulp/soc.c b/arch/arm/mach-imx/imx8ulp/soc.c
index bba6323f96f..ad2ee880f53 100644
--- a/arch/arm/mach-imx/imx8ulp/soc.c
+++ b/arch/arm/mach-imx/imx8ulp/soc.c
@@ -512,7 +512,7 @@ int arch_cpu_init_dm(void)
 }
 
 #if defined(CONFIG_SPL_BUILD)
-__weak void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
+__weak void __noreturn jump_to_image(struct spl_image_info *spl_image)
 {
 	debug("image entry point: 0x%lx\n", spl_image->entry_point);
 
diff --git a/arch/arm/mach-imx/spl.c b/arch/arm/mach-imx/spl.c
index 427b7f78599..1055b126e39 100644
--- a/arch/arm/mach-imx/spl.c
+++ b/arch/arm/mach-imx/spl.c
@@ -279,7 +279,7 @@ u32 spl_mmc_boot_mode(const u32 boot_device)
  * +------------+ + CSF_PAD_SIZE
  */
 
-__weak void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
+__weak void __noreturn jump_to_image(struct spl_image_info *spl_image)
 {
 	typedef void __noreturn (*image_entry_noargs_t)(void);
 	uint32_t offset;
diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c
index 2666cd2d7b1..aba554e262a 100644
--- a/arch/arm/mach-k3/common.c
+++ b/arch/arm/mach-k3/common.c
@@ -198,7 +198,7 @@ __weak void release_resources_for_core_shutdown(void)
 	debug("%s not implemented...\n", __func__);
 }
 
-void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
+void __noreturn jump_to_image(struct spl_image_info *spl_image)
 {
 	typedef void __noreturn (*image_entry_noargs_t)(void);
 	struct ti_sci_handle *ti_sci = get_ti_sci_handle();
diff --git a/arch/arm/mach-omap2/boot-common.c b/arch/arm/mach-omap2/boot-common.c
index fdb8b479ea0..ee7d1240dbf 100644
--- a/arch/arm/mach-omap2/boot-common.c
+++ b/arch/arm/mach-omap2/boot-common.c
@@ -216,7 +216,7 @@ void spl_board_init(void)
 #endif
 }
 
-void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
+void __noreturn jump_to_image(struct spl_image_info *spl_image)
 {
 	typedef void __noreturn (*image_entry_noargs_t)(u32 *);
 	image_entry_noargs_t image_entry =
diff --git a/arch/arm/mach-tegra/spl.c b/arch/arm/mach-tegra/spl.c
index ed897efc5f0..1e4efa325ee 100644
--- a/arch/arm/mach-tegra/spl.c
+++ b/arch/arm/mach-tegra/spl.c
@@ -44,7 +44,7 @@ u32 spl_boot_device(void)
 	return BOOT_DEVICE_RAM;
 }
 
-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("image entry point: 0x%lX\n", spl_image->entry_point);
 
diff --git a/arch/mips/lib/spl.c b/arch/mips/lib/spl.c
index f96fda5b2de..e07cd398d02 100644
--- a/arch/mips/lib/spl.c
+++ b/arch/mips/lib/spl.c
@@ -8,7 +8,7 @@
 #include <log.h>
 #include <spl.h>
 
-void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
+void __noreturn jump_to_image(struct spl_image_info *spl_image)
 {
 	typedef void __noreturn (*image_entry_noargs_t)(void);
 	image_entry_noargs_t image_entry =
diff --git a/arch/riscv/lib/spl.c b/arch/riscv/lib/spl.c
index 8baee07beac..c8238ecbeb0 100644
--- a/arch/riscv/lib/spl.c
+++ b/arch/riscv/lib/spl.c
@@ -36,7 +36,7 @@ __weak void board_init_f(ulong dummy)
 		panic("spl_board_init_f() failed: %d\n", ret);
 }
 
-void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
+void __noreturn jump_to_image(struct spl_image_info *spl_image)
 {
 	typedef void __noreturn (*image_entry_riscv_t)(ulong hart, void *dtb);
 	void *fdt_blob;
diff --git a/arch/sandbox/cpu/spl.c b/arch/sandbox/cpu/spl.c
index 650bdb0a701..22df543e6b7 100644
--- a/arch/sandbox/cpu/spl.c
+++ b/arch/sandbox/cpu/spl.c
@@ -58,7 +58,7 @@ static int spl_board_load_image(struct spl_image_info *spl_image,
 	}
 
 	/*
-	 * Set up spl_image to boot from jump_to_image_no_args(). Allocate this
+	 * Set up spl_image to boot from jump_to_image(). Allocate this
 	 * outsdide the RAM buffer (i.e. don't use strdup()).
 	 */
 	spl_image->arg = os_malloc(strlen(fname) + 1);
@@ -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/board/freescale/common/fsl_chain_of_trust.c b/board/freescale/common/fsl_chain_of_trust.c
index cafb24971b2..ab0ace88487 100644
--- a/board/freescale/common/fsl_chain_of_trust.c
+++ b/board/freescale/common/fsl_chain_of_trust.c
@@ -140,7 +140,7 @@ void spl_validate_uboot(uint32_t hdr_addr, uintptr_t img_addr)
 /* Override weak funtion defined in SPL framework to enable validation
  * of main u-boot image before jumping to u-boot image.
  */
-void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
+void __noreturn jump_to_image(struct spl_image_info *spl_image)
 {
 	typedef void __noreturn (*image_entry_noargs_t)(void);
 	uint32_t hdr_addr;
diff --git a/board/renesas/rcar-common/gen3-spl.c b/board/renesas/rcar-common/gen3-spl.c
index b02a946a21d..de8f9a423de 100644
--- a/board/renesas/rcar-common/gen3-spl.c
+++ b/board/renesas/rcar-common/gen3-spl.c
@@ -34,7 +34,7 @@ u32 spl_boot_device(void)
 	return BOOT_DEVICE_UART;
 }
 
-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("image entry point: 0x%lx\n", spl_image->entry_point);
 	if (spl_image->os == IH_OS_ARM_TRUSTED_FIRMWARE) {
diff --git a/common/spl/spl.c b/common/spl/spl.c
index 932ad53614d..d54356b6a28 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -385,7 +385,7 @@ int spl_parse_image_header(struct spl_image_info *spl_image,
 	return 0;
 }
 
-__weak void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
+__weak void __noreturn jump_to_image(struct spl_image_info *spl_image)
 {
 	typedef void __noreturn (*image_entry_noargs_t)(void);
 
@@ -820,7 +820,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/drivers/usb/gadget/f_sdp.c b/drivers/usb/gadget/f_sdp.c
index e48aa2f90df..500a8c8f8bd 100644
--- a/drivers/usb/gadget/f_sdp.c
+++ b/drivers/usb/gadget/f_sdp.c
@@ -863,7 +863,7 @@ static int sdp_handle_in_ep(struct spl_image_info *spl_image)
 			/* In SPL, allow jumps to U-Boot images */
 			struct spl_image_info spl_image = {};
 			spl_parse_image_header(&spl_image, header);
-			jump_to_image_no_args(&spl_image);
+			jump_to_image(&spl_image);
 #else
 			/* In U-Boot, allow jumps to scripts */
 			image_source_script(sdp_func->jmp_address, "script@1");
diff --git a/include/spl.h b/include/spl.h
index 0af0ee30034..a4d5cedad3a 100644
--- a/include/spl.h
+++ b/include/spl.h
@@ -579,7 +579,7 @@ 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);
 
-void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image);
+void __noreturn jump_to_image(struct spl_image_info *spl_image);
 
 /* SPL EXT image functions */
 int spl_load_image_ext(struct spl_image_info *spl_image,
-- 
2.34.1.703.g22d0c6ccf7-goog


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

* [PATCH v2 04/16] passage: Support an incoming passage
  2022-01-17 15:04 [PATCH v2 00/16] passage: Define a standard for firmware data flow Simon Glass
                   ` (2 preceding siblings ...)
  2022-01-17 15:04 ` [PATCH v2 03/16] spl: Rename jump_to_image_no_args() Simon Glass
@ 2022-01-17 15:04 ` Simon Glass
  2022-01-17 15:04 ` [PATCH v2 05/16] passage: Support a control devicetree Simon Glass
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Simon Glass @ 2022-01-17 15:04 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Ilias Apalodimas, Tom Rini, François Ozog,
	Heinrich Schuchardt, Bill Mills, Simon Glass, Anatolij Gustschin,
	Bin Meng, Dario Binacchi, Heiko Schocher, Joel Peshkin,
	Kunihiko Hayashi, Marek Vasut, Matthias Brugger, Michal Simek,
	Patrick Delaunay, Rasmus Villemoes, Rick Chen

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>
---

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

 common/Kconfig                    | 31 ++++++++++++++++++++++++++++++
 common/bloblist.c                 |  7 ++++++-
 common/board_f.c                  | 32 ++++++++++++++++---------------
 include/asm-generic/global_data.h | 28 +++++++++++++++++++++++++++
 lib/asm-offsets.c                 |  6 ++++++
 5 files changed, 88 insertions(+), 16 deletions(-)

diff --git a/common/Kconfig b/common/Kconfig
index 82cd864baf9..59783d66cb8 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -757,6 +757,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
@@ -815,6 +823,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
@@ -850,6 +865,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 406073c8105..df45d45de90 100644
--- a/common/bloblist.c
+++ b/common/bloblist.c
@@ -441,7 +441,8 @@ int bloblist_init(void)
 	 * allocated bloblist from a previous stage, so it must be at a fixed
 	 * address.
 	 */
-	expected = fixed && !u_boot_first_phase();
+	expected = (fixed || CONFIG_IS_ENABLED(BLOBLIST_PASSAGE)) &&
+		!u_boot_first_phase();
 	if (spl_prev_phase() == PHASE_TPL && !IS_ENABLED(CONFIG_TPL_BLOBLIST))
 		expected = false;
 	if (fixed)
@@ -449,6 +450,10 @@ int bloblist_init(void)
 				      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 a68760092ac..04d98366bd6 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 104282bd479..3fe1534ed9d 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -119,6 +119,34 @@ struct global_data {
 	 */
 	unsigned long precon_buf_idx;
 #endif
+	/**
+	 * @passage_mach: Incoming machine information from standard passage
+	 *
+	 * Provides a value which indicates whether passage is used, e.g.
+	 * PASSAGE_ABI_MACH
+	 */
+	ulong passage_mach;
+	/**
+	 * @passage_bloblist: Incoming bloblist from standard passage
+	 *
+	 * Provides the address of the bloblist passed in by the previous stage
+	 * or phase. If this is zero, there is none.
+	 */
+	ulong passage_bloblist;
+
+	/**
+	 * @passage_dtb: Incoming control devicetree within standard passage
+	 *
+	 * Provides the address (typically within the bloblist) where the
+	 * control DTB is stored. If this is zero, there is none.
+	 *
+	 * Note: This must be set to the correct value if the control DTB exists
+	 * since SPL may use this and ignore the bloblist, e.g. if bloblist
+	 * support is not enabled for code-size reasons. If this value is not
+	 * valid, any devicetree passed in the passage_bloblist is ignored.
+	 */
+	ulong passage_dtb;
+
 	/**
 	 * @env_addr: address of environment structure
 	 *
diff --git a/lib/asm-offsets.c b/lib/asm-offsets.c
index 0808cd4b0c1..624230be5f5 100644
--- a/lib/asm-offsets.c
+++ b/lib/asm-offsets.c
@@ -46,5 +46,11 @@ int main(void)
 
 	DEFINE(GD_ENV_ADDR, offsetof(struct global_data, env_addr));
 
+	DEFINE(GD_PASSAGE_MACH, offsetof(struct global_data, passage_mach));
+	DEFINE(GD_PASSAGE_BLOBLIST,
+	       offsetof(struct global_data, passage_bloblist));
+	DEFINE(GD_PASSAGE_DTB,
+	       offsetof(struct global_data, passage_dtb));
+
 	return 0;
 }
-- 
2.34.1.703.g22d0c6ccf7-goog


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

* [PATCH v2 05/16] passage: Support a control devicetree
  2022-01-17 15:04 [PATCH v2 00/16] passage: Define a standard for firmware data flow Simon Glass
                   ` (3 preceding siblings ...)
  2022-01-17 15:04 ` [PATCH v2 04/16] passage: Support an incoming passage Simon Glass
@ 2022-01-17 15:04 ` Simon Glass
  2022-01-17 15:04 ` [PATCH v2 06/16] passage: arm: Accept a passage from the previous phase Simon Glass
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Simon Glass @ 2022-01-17 15:04 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Ilias Apalodimas, Tom Rini, François Ozog,
	Heinrich Schuchardt, Bill Mills, Simon Glass, Bin Meng,
	Dario Binacchi, Heiko Schocher, Leo Yu-Chi Liang, Marek Vasut,
	Patrick Delaunay, Rasmus Villemoes, Rick Chen, Stefan Roese

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>
---

Changes in v2:
- Incorporate devicetree source
- Rebase to master

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

diff --git a/common/bloblist.c b/common/bloblist.c
index df45d45de90..3a2fba212c9 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 04d98366bd6..0794cc50a57 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) {
@@ -821,6 +826,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
@@ -830,7 +838,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,
@@ -940,9 +948,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 fb7df533f92..65d129453c6 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 || OF_HAS_PRIOR_STAGE
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
index 3fe1534ed9d..34b4139e498 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -638,6 +638,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 d0e128acf10..c0045572275 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/include/fdtdec.h b/include/fdtdec.h
index 15f2d2bbbaa..b4e452326b3 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -56,6 +56,9 @@ struct bd_info;
  *
  * @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
@@ -68,6 +71,7 @@ struct bd_info;
  */
 enum fdt_source_t {
 	FDTSRC_SEPARATE,
+	FDTSRC_PASSAGE,
 	FDTSRC_FIT,
 	FDTSRC_BOARD,
 	FDTSRC_EMBED,
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 280cda61a72..86613208b14 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>
@@ -78,6 +81,7 @@ static const char * const compat_names[COMPAT_COUNT] = {
 
 static const char *const fdt_src_name[] = {
 	[FDTSRC_SEPARATE] = "separate",
+	[FDTSRC_PASSAGE] = "passage",
 	[FDTSRC_FIT] = "fit",
 	[FDTSRC_BOARD] = "board",
 	[FDTSRC_EMBED] = "embed",
@@ -1649,6 +1653,35 @@ int fdtdec_setup(void)
 		gd->fdt_src = FDTSRC_EMBED;
 	}
 
+	/* Passed in via the standard passage */
+	if (IS_ENABLED(CONFIG_OF_PASSAGE) && gd->passage_dtb) {
+		void *passage_dtb = map_sysmem(gd->passage_dtb, 0);
+		void *fdt = NULL;
+
+		/* Use the bloblist if available */
+		if (CONFIG_IS_ENABLED(BLOBLIST)) {
+			fdt = bloblist_find(BLOBLISTT_CONTROL_DTB, 0);
+
+			if (fdt == passage_dtb)
+				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 = passage_dtb;
+				log_debug("passage: Found dtb addr %lx\n",
+					  gd->passage_dtb);
+			}
+		}
+		if (fdt) {
+			gd->fdt_blob = fdt;
+			gd->fdt_src = FDTSRC_PASSAGE;
+			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.34.1.703.g22d0c6ccf7-goog


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

* [PATCH v2 06/16] passage: arm: Accept a passage from the previous phase
  2022-01-17 15:04 [PATCH v2 00/16] passage: Define a standard for firmware data flow Simon Glass
                   ` (4 preceding siblings ...)
  2022-01-17 15:04 ` [PATCH v2 05/16] passage: Support a control devicetree Simon Glass
@ 2022-01-17 15:04 ` Simon Glass
  2022-01-17 15:04 ` [PATCH v2 07/16] passage: spl: Support adding the dtb to the passage bloblist Simon Glass
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Simon Glass @ 2022-01-17 15:04 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Ilias Apalodimas, Tom Rini, François Ozog,
	Heinrich Schuchardt, Bill Mills, Simon Glass, Albert Aribaud,
	Chia-Wei Wang

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

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

Changes in v2:
- Use three registers instead of two for the entry

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

diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S
index 698e15b8e18..494f4abdb1f 100644
--- a/arch/arm/cpu/armv7/start.S
+++ b/arch/arm/cpu/armv7/start.S
@@ -36,6 +36,11 @@
 #endif
 
 reset:
+	# Keep passage information in case it is provided
+	mov	r6, r1
+	mov	r7, r2
+	mov	r8, r3
+
 	/* Allow the board to save important registers */
 	b	save_boot_params
 save_boot_params_ret:
@@ -124,7 +129,7 @@ switch_to_hypervisor_ret:
 	bl	cpu_init_crit
 #endif
 #endif
-
+	# Note: r6-r8 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 ba312901f33..68282ebfd02 100644
--- a/arch/arm/lib/crt0.S
+++ b/arch/arm/lib/crt0.S
@@ -117,6 +117,11 @@ ENTRY(_main)
 	CLEAR_BSS
 #endif
 
+#if CONFIG_IS_ENABLED(PASSAGE_IN)
+	str	r6, [r9, #GD_PASSAGE_MACH]
+	str	r7, [r9, #GD_PASSAGE_DTB]
+	str	r8, [r9, #GD_PASSAGE_BLOBLIST]
+#endif
 	mov	r0, #0
 	bl	board_init_f
 
-- 
2.34.1.703.g22d0c6ccf7-goog


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

* [PATCH v2 07/16] passage: spl: Support adding the dtb to the passage bloblist
  2022-01-17 15:04 [PATCH v2 00/16] passage: Define a standard for firmware data flow Simon Glass
                   ` (5 preceding siblings ...)
  2022-01-17 15:04 ` [PATCH v2 06/16] passage: arm: Accept a passage from the previous phase Simon Glass
@ 2022-01-17 15:04 ` Simon Glass
  2022-01-17 15:04 ` [PATCH v2 08/16] passage: spl: Support passing the passage to U-Boot Simon Glass
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Simon Glass @ 2022-01-17 15:04 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Ilias Apalodimas, Tom Rini, François Ozog,
	Heinrich Schuchardt, Bill Mills, Simon Glass, Alexandru Gagniuc,
	Anatolij Gustschin, Artem Lapkin, Bin Meng, Heiko Schocher,
	Joel Peshkin, Jorge Ramirez-Ortiz, Marek Vasut, Michal Simek,
	Pali Rohár, Patrick Delaunay, Peng Fan, Ricardo Salveti,
	Stefan Roese

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>
---

(no changes since v1)

 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 59783d66cb8..bf6bff22e71 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -881,6 +881,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 d54356b6a28..be770d0226c 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -56,6 +56,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")));
 
@@ -406,7 +411,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;
 
@@ -423,7 +429,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);
@@ -440,6 +447,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
  *
@@ -761,6 +795,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 a4d5cedad3a..472b171f5be 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.34.1.703.g22d0c6ccf7-goog


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

* [PATCH v2 08/16] passage: spl: Support passing the passage to U-Boot
  2022-01-17 15:04 [PATCH v2 00/16] passage: Define a standard for firmware data flow Simon Glass
                   ` (6 preceding siblings ...)
  2022-01-17 15:04 ` [PATCH v2 07/16] passage: spl: Support adding the dtb to the passage bloblist Simon Glass
@ 2022-01-17 15:04 ` Simon Glass
  2022-01-17 15:04 ` [PATCH v2 09/16] passage: arm: Add the arch-specific standard passage impl Simon Glass
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Simon Glass @ 2022-01-17 15:04 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Ilias Apalodimas, Tom Rini, François Ozog,
	Heinrich Schuchardt, Bill Mills, Simon Glass, Alexandru Gagniuc,
	Bin Meng, Dario Binacchi, Heiko Schocher, Pali Rohár,
	Patrick Delaunay, Rasmus Villemoes

Create a new arch-specific way of creating a standard passage to the
next phase.

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

Changes in v2:
- Make the stdpass calling standard arch-specific

 common/spl/spl.c                  | 27 ++++++++++++++++++++++-----
 include/asm-generic/global_data.h |  6 ++++++
 include/passage.h                 | 28 ++++++++++++++++++++++++++++
 3 files changed, 56 insertions(+), 5 deletions(-)
 create mode 100644 include/passage.h

diff --git a/common/spl/spl.c b/common/spl/spl.c
index be770d0226c..0b78fdd5eae 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -22,6 +22,7 @@
 #include <malloc.h>
 #include <mapmem.h>
 #include <nand.h>
+#include <passage.h>
 #include <serial.h>
 #include <spl.h>
 #if CONFIG_IS_ENABLED(BANNER_PRINT)
@@ -392,13 +393,29 @@ int spl_parse_image_header(struct spl_image_info *spl_image,
 
 __weak void __noreturn jump_to_image(struct spl_image_info *spl_image)
 {
-	typedef void __noreturn (*image_entry_noargs_t)(void);
-
-	image_entry_noargs_t image_entry =
-		(image_entry_noargs_t)spl_image->entry_point;
+	typedef void __noreturn (*image_entry_t)(void);
+	ulong bloblist = 0;
+	ulong dtb_offset = 0;
 
 	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);
+
+		log_debug("passage: sending bloblist at %lx, dtb offset %lx\n",
+			  bloblist, dtb_offset);
+		arch_passage_entry(spl_image->entry_point,
+				   map_to_sysmem(gd_bloblist()),
+				   map_to_sysmem(fdt));
+	} else {
+		image_entry_t image_entry;
+
+		image_entry = (image_entry_t)spl_image->entry_point;
+		image_entry();
+	}
 }
 
 #if CONFIG_IS_ENABLED(HANDOFF)
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
index 34b4139e498..71a60115cee 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -552,6 +552,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/passage.h b/include/passage.h
new file mode 100644
index 00000000000..51c40154711
--- /dev/null
+++ b/include/passage.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Standard passage implementation
+ *
+ * Copyright 2022 Google LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#ifndef __PASSAGE_H
+#define __PASSAGE_H
+
+enum {
+	PASSAGE_ABI_MACH	= 0xb00757a3,
+	PASSAGE_ABI_VERSION	= 1,
+};
+
+static inline ulong passage_mach_version(void)
+{
+#if BITS_PER_LONG == 64
+	return (ulong)PASSAGE_ABI_MACH << 32 | PASSAGE_ABI_VERSION;
+#else
+	return (PASSAGE_ABI_MACH & ~0xff) | PASSAGE_ABI_VERSION;
+#endif
+}
+
+void __noreturn arch_passage_entry(ulong entry_addr, ulong bloblist, ulong fdt);
+
+#endif
-- 
2.34.1.703.g22d0c6ccf7-goog


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

* [PATCH v2 09/16] passage: arm: Add the arch-specific standard passage impl
  2022-01-17 15:04 [PATCH v2 00/16] passage: Define a standard for firmware data flow Simon Glass
                   ` (7 preceding siblings ...)
  2022-01-17 15:04 ` [PATCH v2 08/16] passage: spl: Support passing the passage to U-Boot Simon Glass
@ 2022-01-17 15:04 ` Simon Glass
  2022-01-17 15:04 ` [PATCH v2 10/16] passage: Add a qemu test for ARM Simon Glass
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Simon Glass @ 2022-01-17 15:04 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Ilias Apalodimas, Tom Rini, François Ozog,
	Heinrich Schuchardt, Bill Mills, Simon Glass, Albert Aribaud

Add implementations for 32- and 64-bit ARM.

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

Changes in v2:
- Add new patch with the arm-specific standard passage implementation

 arch/arm/cpu/armv7/cpu.c | 28 ++++++++++++++++++++++++++++
 arch/arm/cpu/armv8/cpu.c | 20 ++++++++++++++++++++
 2 files changed, 48 insertions(+)

diff --git a/arch/arm/cpu/armv7/cpu.c b/arch/arm/cpu/armv7/cpu.c
index 68807d20997..4f16ea0058a 100644
--- a/arch/arm/cpu/armv7/cpu.c
+++ b/arch/arm/cpu/armv7/cpu.c
@@ -18,6 +18,7 @@
 #include <command.h>
 #include <cpu_func.h>
 #include <irq_func.h>
+#include <passage.h>
 #include <asm/system.h>
 #include <asm/cache.h>
 #include <asm/armv7.h>
@@ -83,3 +84,30 @@ int cleanup_before_linux(void)
 {
 	return cleanup_before_linux_select(CBL_ALL);
 }
+
+void __noreturn arch_passage_entry(ulong entry_addr, ulong bloblist, ulong fdt)
+{
+	typedef void __noreturn (*passage_entry_t)(ulong zero1, ulong mach,
+						   ulong fdt, ulong bloblist);
+	passage_entry_t entry = (passage_entry_t)entry_addr;
+
+	/*
+	 * Register   Contents
+	 * r0         0
+	 * r1         0xb0075701 (indicates standard passage v1)
+	 * r2         Address of devicetree
+	 * r3         Address of bloblist
+	 * r4         0
+	 * lr         Return address
+	 *
+	 * The ARMv7 calling convention only passes 4 arguments in registers, so
+	 * set r4 to 0 manually.
+	 */
+	__asm__ volatile (
+		"mov r4, #0\n"
+		:
+		:
+		: "r4"
+	);
+	entry(0, passage_mach_version(), fdt, bloblist);
+}
diff --git a/arch/arm/cpu/armv8/cpu.c b/arch/arm/cpu/armv8/cpu.c
index ea40c55dd2c..4d67152f033 100644
--- a/arch/arm/cpu/armv8/cpu.c
+++ b/arch/arm/cpu/armv8/cpu.c
@@ -14,6 +14,7 @@
 #include <command.h>
 #include <cpu_func.h>
 #include <irq_func.h>
+#include <passage.h>
 #include <asm/cache.h>
 #include <asm/system.h>
 #include <asm/secure.h>
@@ -84,3 +85,22 @@ void armv8_setup_psci(void)
 	secure_ram_addr(psci_arch_init)();
 }
 #endif
+
+void __noreturn arch_passage_entry(ulong entry_addr, ulong bloblist, ulong fdt)
+{
+	typedef void __noreturn (*passage_entry_t)(ulong fdt, ulong abi,
+						   ulong zero1, ulong bloblist,
+						   ulong zero2);
+	passage_entry_t entry = (passage_entry_t)entry_addr;
+
+	/*
+	 * Register   Contents
+	 * x0         Address of devicetree
+	 * x1         0xb00757a300000001 (indicates standard passage v1)
+	 * x2         0
+	 * x3         Address of bloblist
+	 * x4         0
+	 * x30        Return address
+	 */
+	entry(fdt, passage_mach_version(), 0, bloblist, 0);
+}
-- 
2.34.1.703.g22d0c6ccf7-goog


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

* [PATCH v2 10/16] passage: Add a qemu test for ARM
  2022-01-17 15:04 [PATCH v2 00/16] passage: Define a standard for firmware data flow Simon Glass
                   ` (8 preceding siblings ...)
  2022-01-17 15:04 ` [PATCH v2 09/16] passage: arm: Add the arch-specific standard passage impl Simon Glass
@ 2022-01-17 15:04 ` Simon Glass
  2022-01-17 15:04 ` [PATCH v2 11/16] sandbox: Add a way of checking structs for standard passage Simon Glass
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Simon Glass @ 2022-01-17 15:04 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Ilias Apalodimas, Tom Rini, François Ozog,
	Heinrich Schuchardt, Bill Mills, Simon Glass, Bharat Gooty,
	Rayagonda Kokatanur, Tuomas Tynkkynen

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>
---

Changes in v2:
- Add a devicetree for qemu-arm so that qemu_arm_spl can work

 arch/arm/Kconfig               |  2 +-
 configs/qemu_arm_spl_defconfig |  8 +++++++-
 test/py/tests/test_passage.py  | 11 +++++++++++
 3 files changed, 19 insertions(+), 2 deletions(-)
 create mode 100644 test/py/tests/test_passage.py

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 78c6b2e92dc..c4d06d2f1a0 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -974,7 +974,7 @@ config ARCH_QEMU
 	imply DM_RNG
 	imply DM_RTC
 	imply RTC_PL031
-	imply OF_HAS_PRIOR_STAGE
+	imply OF_HAS_PRIOR_STAGE if !TARGET_QEMU_ARM_32BIT_SPL
 
 config ARCH_RMOBILE
 	bool "Renesas ARM SoCs"
diff --git a/configs/qemu_arm_spl_defconfig b/configs/qemu_arm_spl_defconfig
index a6950584542..e91fed8f5e0 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_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.34.1.703.g22d0c6ccf7-goog


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

* [PATCH v2 11/16] sandbox: Add a way of checking structs for standard passage
  2022-01-17 15:04 [PATCH v2 00/16] passage: Define a standard for firmware data flow Simon Glass
                   ` (9 preceding siblings ...)
  2022-01-17 15:04 ` [PATCH v2 10/16] passage: Add a qemu test for ARM Simon Glass
@ 2022-01-17 15:04 ` Simon Glass
  2022-01-17 15:04 ` [PATCH v2 12/16] passage: Add documentation Simon Glass
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Simon Glass @ 2022-01-17 15:04 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Ilias Apalodimas, Tom Rini, François Ozog,
	Heinrich Schuchardt, Bill Mills, Simon Glass, Mario Six

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>
---

(no changes since v1)

 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.34.1.703.g22d0c6ccf7-goog


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

* [PATCH v2 12/16] passage: Add documentation
  2022-01-17 15:04 [PATCH v2 00/16] passage: Define a standard for firmware data flow Simon Glass
                   ` (10 preceding siblings ...)
  2022-01-17 15:04 ` [PATCH v2 11/16] sandbox: Add a way of checking structs for standard passage Simon Glass
@ 2022-01-17 15:04 ` Simon Glass
  2022-01-17 16:39   ` Mark Kettenis
  2022-01-17 15:04 ` [PATCH v2 13/16] passage: Add docs for spl_handoff Simon Glass
                   ` (3 subsequent siblings)
  15 siblings, 1 reply; 18+ messages in thread
From: Simon Glass @ 2022-01-17 15:04 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Ilias Apalodimas, Tom Rini, François Ozog,
	Heinrich Schuchardt, Bill Mills, Simon Glass, Mario Six

Add documentation about standard passage and update the maintainers.

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

Changes in v2:
- Add comments about how to pass standard passage to EFI
- Add comments about passing a bloblist to Linux
- Add detailed arch-specific information

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

diff --git a/MAINTAINERS b/MAINTAINERS
index 38c68ee87d4..63723d43b63 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1177,6 +1177,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 9592d193fca..d0aecc30059 100644
--- a/doc/develop/index.rst
+++ b/doc/develop/index.rst
@@ -21,6 +21,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..461098e01e7
--- /dev/null
+++ b/doc/develop/std_passage.rst
@@ -0,0 +1,396 @@
+.. 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-bit ARM and x86, for example, if only because of the different register
+naming.
+
+The bloblist is mandatory. If there is no information to pass, the bloblist must
+still be provided. Following firmware stages may add blobs to the bloblist,
+making use of the existing space.
+
+The minimum bloblist size is 256 bytes, but 4KB is recommended.
+
+Two registers are used to pass the bloblist and devicetree pointers. Others may
+be used depending on the architecture. The protocol chosen for each architecture
+should be compatible with the Linux protocol, with a way of determining whether
+standard passage is used. This is done not because Linux might start using
+standard passage, but to avoid reinventing the wheel.
+
+For 32-bit ARM:
+
+  =========  ==============================================
+  Register   Contents
+  =========  ==============================================
+  r0         0
+  r1         0xb0075701 (indicates standard passage v1)
+  r2         Address of devicetree
+  r3         Address of bloblist
+  r4         0
+  lr         Return address
+  =========  ==============================================
+
+For 64-bit ARM:
+
+  =========  ===================================================
+  Register   Contents
+  =========  ===================================================
+  x0         Address of devicetree
+  x1         0xb00757a300000001 (indicates standard passage v1)
+  x2         0
+  x3         Address of bloblist
+  x4         0
+  x30        Return address
+  =========  ===================================================
+
+The devicetree is provided as an address but it normally included within the
+bloblist, meaning that searching for the BLOBLISTT_CONTROL_DTB blob with the
+bloblist produces the same result as the devicetree address passed here. Having
+everything in a bloblist makes it easier to manage memory, since it is all in
+one contiguous block.
+
+
+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.
+
+
+EFI
+---
+
+When using EFI a different calling convention is used. For example, with 64-bit
+ARM we have:
+
+  =========  ===================================================
+  Register   Contents
+  =========  ===================================================
+  x0         handle
+  x1         system table
+  x30        Return address
+  =========  ===================================================
+
+It is not possible to pass the bloblist in a register in this case. Instead, a
+config table can be used. The GUID for a bloblist is
+4effe9da-7728-11ec-8df6-136969a780ff
+
+
+Linux and bloblists
+-------------------
+
+It is possible to effectively pass a bloblist to Linux, or other Operating
+Systems. However it is not expected that Linux would actually implement the
+bloblist data structure. How does this work?
+
+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
+can work the same way. There is no need to teach Linux about bloblist when it
+already has a perfectly good means to accept these items (via devicetree).
+
+ACPI can operate in 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. In fact the ACPI tables themselves may well be in a bloblist, as they
+are in U-Boot.
+
+
+Private firmware
+----------------
+
+Standard passage is intended to operate with open-source firmware. It may be
+that closed-source firmware may use standard passage, or happen to work with it.
+If so, that is a happy coincidence, but the focus here is on open-source
+firmware.
+
+
+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.34.1.703.g22d0c6ccf7-goog


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

* [PATCH v2 13/16] passage: Add docs for spl_handoff
  2022-01-17 15:04 [PATCH v2 00/16] passage: Define a standard for firmware data flow Simon Glass
                   ` (11 preceding siblings ...)
  2022-01-17 15:04 ` [PATCH v2 12/16] passage: Add documentation Simon Glass
@ 2022-01-17 15:04 ` Simon Glass
  2022-01-17 15:04 ` [PATCH v2 14/16] x86: Move Intel GNVS file into the common include directory Simon Glass
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 18+ messages in thread
From: Simon Glass @ 2022-01-17 15:04 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Ilias Apalodimas, Tom Rini, François Ozog,
	Heinrich Schuchardt, Bill Mills, Simon Glass, Mario Six

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

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

(no changes since v1)

 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.34.1.703.g22d0c6ccf7-goog


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

* [PATCH v2 14/16] x86: Move Intel GNVS file into the common include directory
  2022-01-17 15:04 [PATCH v2 00/16] passage: Define a standard for firmware data flow Simon Glass
                   ` (12 preceding siblings ...)
  2022-01-17 15:04 ` [PATCH v2 13/16] passage: Add docs for spl_handoff Simon Glass
@ 2022-01-17 15:04 ` Simon Glass
  2022-01-17 15:04 ` [PATCH v2 15/16] passage: Add checks for pre-existing blobs Simon Glass
  2022-01-17 15:04 ` [PATCH v2 16/16] WIP: RFC: Add a gitlab test Simon Glass
  15 siblings, 0 replies; 18+ messages in thread
From: Simon Glass @ 2022-01-17 15:04 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Ilias Apalodimas, Tom Rini, François Ozog,
	Heinrich Schuchardt, Bill Mills, Simon Glass, Bin Meng

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>
---

(no changes since v1)

 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.34.1.703.g22d0c6ccf7-goog


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

* [PATCH v2 15/16] passage: Add checks for pre-existing blobs
  2022-01-17 15:04 [PATCH v2 00/16] passage: Define a standard for firmware data flow Simon Glass
                   ` (13 preceding siblings ...)
  2022-01-17 15:04 ` [PATCH v2 14/16] x86: Move Intel GNVS file into the common include directory Simon Glass
@ 2022-01-17 15:04 ` Simon Glass
  2022-01-17 15:04 ` [PATCH v2 16/16] WIP: RFC: Add a gitlab test Simon Glass
  15 siblings, 0 replies; 18+ messages in thread
From: Simon Glass @ 2022-01-17 15:04 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Ilias Apalodimas, Tom Rini, François Ozog,
	Heinrich Schuchardt, Bill Mills, Simon Glass, Mario Six

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>
---

(no changes since v1)

 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.34.1.703.g22d0c6ccf7-goog


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

* [PATCH v2 16/16] WIP: RFC: Add a gitlab test
  2022-01-17 15:04 [PATCH v2 00/16] passage: Define a standard for firmware data flow Simon Glass
                   ` (14 preceding siblings ...)
  2022-01-17 15:04 ` [PATCH v2 15/16] passage: Add checks for pre-existing blobs Simon Glass
@ 2022-01-17 15:04 ` Simon Glass
  15 siblings, 0 replies; 18+ messages in thread
From: Simon Glass @ 2022-01-17 15:04 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Ilias Apalodimas, Tom Rini, François Ozog,
	Heinrich Schuchardt, Bill Mills, Simon Glass, Bin Meng,
	Daniel Schwierzeck, Kristian Amlie

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

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

Changes in v2:
- Rebase to master (dropping bloblist patches already applied)

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

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 4c44c01e7bf..31f3d7e55a9 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -261,6 +261,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.34.1.703.g22d0c6ccf7-goog


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

* Re: [PATCH v2 12/16] passage: Add documentation
  2022-01-17 15:04 ` [PATCH v2 12/16] passage: Add documentation Simon Glass
@ 2022-01-17 16:39   ` Mark Kettenis
  0 siblings, 0 replies; 18+ messages in thread
From: Mark Kettenis @ 2022-01-17 16:39 UTC (permalink / raw)
  To: Simon Glass
  Cc: u-boot, ilias.apalodimas, trini, francois.ozog, xypron.glpk,
	bill.mills, sjg, mario.six

> From: Simon Glass <sjg@chromium.org>
> Date: Mon, 17 Jan 2022 08:04:24 -0700
> 
> Add documentation about standard passage and update the maintainers.
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
> 
> Changes in v2:
> - Add comments about how to pass standard passage to EFI
> - Add comments about passing a bloblist to Linux
> - Add detailed arch-specific information
> 
>  MAINTAINERS                   |  10 +
>  board/sandbox/stdpass_check.c |  10 +-
>  doc/develop/bloblist.rst      |   4 +-
>  doc/develop/index.rst         |   1 +
>  doc/develop/std_passage.rst   | 396 ++++++++++++++++++++++++++++++++++
>  5 files changed, 411 insertions(+), 10 deletions(-)
>  create mode 100644 doc/develop/std_passage.rst
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 38c68ee87d4..63723d43b63 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1177,6 +1177,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 9592d193fca..d0aecc30059 100644
> --- a/doc/develop/index.rst
> +++ b/doc/develop/index.rst
> @@ -21,6 +21,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..461098e01e7
> --- /dev/null
> +++ b/doc/develop/std_passage.rst
> @@ -0,0 +1,396 @@
> +.. 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-bit ARM and x86, for example, if only because of the different register
> +naming.
> +
> +The bloblist is mandatory. If there is no information to pass, the bloblist must
> +still be provided. Following firmware stages may add blobs to the bloblist,
> +making use of the existing space.
> +
> +The minimum bloblist size is 256 bytes, but 4KB is recommended.
> +
> +Two registers are used to pass the bloblist and devicetree pointers. Others may
> +be used depending on the architecture. The protocol chosen for each architecture
> +should be compatible with the Linux protocol, with a way of determining whether
> +standard passage is used. This is done not because Linux might start using
> +standard passage, but to avoid reinventing the wheel.
> +
> +For 32-bit ARM:
> +
> +  =========  ==============================================
> +  Register   Contents
> +  =========  ==============================================
> +  r0         0
> +  r1         0xb0075701 (indicates standard passage v1)
> +  r2         Address of devicetree
> +  r3         Address of bloblist
> +  r4         0
> +  lr         Return address
> +  =========  ==============================================
> +
> +For 64-bit ARM:
> +
> +  =========  ===================================================
> +  Register   Contents
> +  =========  ===================================================
> +  x0         Address of devicetree
> +  x1         0xb00757a300000001 (indicates standard passage v1)
> +  x2         0
> +  x3         Address of bloblist
> +  x4         0
> +  x30        Return address
> +  =========  ===================================================
> +
> +The devicetree is provided as an address but it normally included within the
                                                ^^
						is?

> +bloblist, meaning that searching for the BLOBLISTT_CONTROL_DTB blob with the
> +bloblist produces the same result as the devicetree address passed here. Having
> +everything in a bloblist makes it easier to manage memory, since it is all in
> +one contiguous block.
> +
> +
> +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.
> +
> +
> +EFI
> +---
> +
> +When using EFI a different calling convention is used. For example, with 64-bit
> +ARM we have:
> +
> +  =========  ===================================================
> +  Register   Contents
> +  =========  ===================================================
> +  x0         handle
> +  x1         system table
> +  x30        Return address
> +  =========  ===================================================
> +
> +It is not possible to pass the bloblist in a register in this case. Instead, a
> +config table can be used. The GUID for a bloblist is
> +4effe9da-7728-11ec-8df6-136969a780ff
> +
> +
> +Linux and bloblists
> +-------------------
> +
> +It is possible to effectively pass a bloblist to Linux, or other Operating
> +Systems. However it is not expected that Linux would actually implement the
> +bloblist data structure. How does this work?
> +
> +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
> +can work the same way. There is no need to teach Linux about bloblist when it
> +already has a perfectly good means to accept these items (via devicetree).
> +
> +ACPI can operate in 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. In fact the ACPI tables themselves may well be in a bloblist, as they
> +are in U-Boot.
> +
> +
> +Private firmware
> +----------------
> +
> +Standard passage is intended to operate with open-source firmware. It may be
> +that closed-source firmware may use standard passage, or happen to work with it.
> +If so, that is a happy coincidence, but the focus here is on open-source
> +firmware.
> +
> +
> +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
                                                     ^^^^^^^^^^^

I had to look that word up in a dictionary...

> +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.34.1.703.g22d0c6ccf7-goog
> 
> 

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

end of thread, other threads:[~2022-01-17 16:39 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-17 15:04 [PATCH v2 00/16] passage: Define a standard for firmware data flow Simon Glass
2022-01-17 15:04 ` [PATCH v2 01/16] spl: Tidy up the header includes Simon Glass
2022-01-17 15:04 ` [PATCH v2 02/16] arm: qemu: Add an SPL build Simon Glass
2022-01-17 15:04 ` [PATCH v2 03/16] spl: Rename jump_to_image_no_args() Simon Glass
2022-01-17 15:04 ` [PATCH v2 04/16] passage: Support an incoming passage Simon Glass
2022-01-17 15:04 ` [PATCH v2 05/16] passage: Support a control devicetree Simon Glass
2022-01-17 15:04 ` [PATCH v2 06/16] passage: arm: Accept a passage from the previous phase Simon Glass
2022-01-17 15:04 ` [PATCH v2 07/16] passage: spl: Support adding the dtb to the passage bloblist Simon Glass
2022-01-17 15:04 ` [PATCH v2 08/16] passage: spl: Support passing the passage to U-Boot Simon Glass
2022-01-17 15:04 ` [PATCH v2 09/16] passage: arm: Add the arch-specific standard passage impl Simon Glass
2022-01-17 15:04 ` [PATCH v2 10/16] passage: Add a qemu test for ARM Simon Glass
2022-01-17 15:04 ` [PATCH v2 11/16] sandbox: Add a way of checking structs for standard passage Simon Glass
2022-01-17 15:04 ` [PATCH v2 12/16] passage: Add documentation Simon Glass
2022-01-17 16:39   ` Mark Kettenis
2022-01-17 15:04 ` [PATCH v2 13/16] passage: Add docs for spl_handoff Simon Glass
2022-01-17 15:04 ` [PATCH v2 14/16] x86: Move Intel GNVS file into the common include directory Simon Glass
2022-01-17 15:04 ` [PATCH v2 15/16] passage: Add checks for pre-existing blobs Simon Glass
2022-01-17 15:04 ` [PATCH v2 16/16] WIP: RFC: Add a gitlab test 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.