All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jerome Forissier <jerome.forissier@linaro.org>
To: Simon Glass <sjg@chromium.org>,
	U-Boot Mailing List <u-boot@lists.denx.de>
Cc: Tom Rini <trini@konsulko.com>, huang lin <hl@rock-chips.com>,
	Jeffy Chen <jeffy.chen@rock-chips.com>,
	Kever Yang <kever.yang@rock-chips.com>,
	Philipp Tomsich <philipp.tomsich@theobroma-systems.com>,
	Ivan Mikhaylov <ivan.mikhaylov@siemens.com>,
	Quentin Schulz <quentin.schulz@theobroma-systems.com>,
	Roger Quadros <rogerq@ti.com>,
	Philippe Reynes <philippe.reynes@softathome.com>,
	Alper Nebi Yasak <alpernebiyasak@gmail.com>,
	Peter Geis <pgwipeout@gmail.com>
Subject: Re: [PATCH v8 06/13] binman: Support new op-tee binary format
Date: Thu, 22 Dec 2022 16:36:17 +0100	[thread overview]
Message-ID: <39733f31-347a-53fe-6186-1891354413c6@linaro.org> (raw)
In-Reply-To: <20221221230726.638740-7-sjg@chromium.org>



On 12/22/22 00:07, Simon Glass wrote:
> OP-TEE has a format with a binary header that can be used instead of the
> ELF file. With newer versions of OP-TEE this may be required on some
> platforms.
> 
> Add support for this in binman. First, add a method to obtain the ELF
> sections from an entry, then use that in the FIT support. We then end up
> with the ability to support both types of OP-TEE files, depending on which
> one is passed in with the entry argument (TEE=xxx in the U-Boot build).

So, with:

BL31=/path/to/bl31.elf TEE=/path/to/tee.bin make -C u-boot \
  CROSS_COMPILE=aarch64-linux-gnu- CC=aarch64-linux-gnu-gcc \
  HOSTCC=gcc BINMAN_DEBUG=1 BINMAN_VERBOSE=4


...I get:

Entry '/binman/simple-bin/fit/images/@tee-SEQ/tee-os' marked absent: uses v1 format which must be in a FIT


More complete log at https://pastebin.com/UZzZeicQ

Thanks,
-- 
Jerome

> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
> 
> (no changes since v7)
> 
> Changes in v7:
> - Correct missing test coverage
> 
> Changes in v6:
> - Update op-tee to support new v1 binary header
> 
>  tools/binman/entries.rst                     | 35 ++++++++-
>  tools/binman/entry.py                        | 13 +++
>  tools/binman/etype/fit.py                    | 69 +++++++++-------
>  tools/binman/etype/section.py                |  9 +++
>  tools/binman/etype/tee_os.py                 | 68 +++++++++++++++-
>  tools/binman/ftest.py                        | 83 ++++++++++++++++++++
>  tools/binman/test/263_tee_os_opt.dts         | 22 ++++++
>  tools/binman/test/264_tee_os_opt_fit.dts     | 33 ++++++++
>  tools/binman/test/265_tee_os_opt_fit_bad.dts | 40 ++++++++++
>  9 files changed, 340 insertions(+), 32 deletions(-)
>  create mode 100644 tools/binman/test/263_tee_os_opt.dts
>  create mode 100644 tools/binman/test/264_tee_os_opt_fit.dts
>  create mode 100644 tools/binman/test/265_tee_os_opt_fit_bad.dts
> 
> diff --git a/tools/binman/entries.rst b/tools/binman/entries.rst
> index b2ce7960d3b..a3e4493a44f 100644
> --- a/tools/binman/entries.rst
> +++ b/tools/binman/entries.rst
> @@ -1508,12 +1508,45 @@ Entry: tee-os: Entry containing an OP-TEE Trusted OS (TEE) blob
>  
>  Properties / Entry arguments:
>      - tee-os-path: Filename of file to read into entry. This is typically
> -        called tee-pager.bin
> +        called tee.bin or tee.elf
>  
>  This entry holds the run-time firmware, typically started by U-Boot SPL.
>  See the U-Boot README for your architecture or board for how to use it. See
>  https://github.com/OP-TEE/optee_os for more information about OP-TEE.
>  
> +Note that if the file is in ELF format, it must go in a FIT. In that case,
> +this entry will mark itself as absent, providing the data only through the
> +read_elf_segments() method.
> +
> +Marking this entry as absent means that it if is used in the wrong context
> +it can be automatically dropped. Thus it is possible to add anb OP-TEE entry
> +like this::
> +
> +    binman {
> +        tee-os {
> +        };
> +    };
> +
> +and pass either an ELF or plain binary in with -a tee-os-path <filename>
> +and have binman do the right thing:
> +
> +   - include the entry if tee.bin is provided and it doesn't have the v1
> +     header
> +   - drop it otherwise
> +
> +When used within a FIT, we can do::
> +
> +    binman {
> +        fit {
> +            tee-os {
> +            };
> +        };
> +    };
> +
> +which will split the ELF into separate nodes for each segment, if an ELF
> +file is provide (see Flat Image Tree / FIT), or produce a single node if
> +the binary v1 format is provided.
> +
>  
>  
>  .. _etype_text:
> diff --git a/tools/binman/entry.py b/tools/binman/entry.py
> index 637aece3705..de51d295891 100644
> --- a/tools/binman/entry.py
> +++ b/tools/binman/entry.py
> @@ -1290,3 +1290,16 @@ features to produce new behaviours.
>      def mark_absent(self, msg):
>          tout.info("Entry '%s' marked absent: %s" % (self._node.path, msg))
>          self.absent = True
> +
> +    def read_elf_segments(self):
> +        """Read segments from an entry that can generate an ELF file
> +
> +        Returns:
> +            tuple:
> +                list of segments, each:
> +                    int: Segment number (0 = first)
> +                    int: Start address of segment in memory
> +                    bytes: Contents of segment
> +                int: entry address of ELF file
> +        """
> +        return None
> diff --git a/tools/binman/etype/fit.py b/tools/binman/etype/fit.py
> index 8ad4f3a8a83..21c769a1cbe 100644
> --- a/tools/binman/etype/fit.py
> +++ b/tools/binman/etype/fit.py
> @@ -540,41 +540,34 @@ class Entry_fit(Entry_section):
>                      else:
>                          self.Raise("Generator node requires 'fit,fdt-list' property")
>  
> -        def _gen_split_elf(base_node, node, elf_data, missing):
> +        def _gen_split_elf(base_node, node, segments, entry_addr):
>              """Add nodes for the ELF file, one per group of contiguous segments
>  
>              Args:
>                  base_node (Node): Template node from the binman definition
>                  node (Node): Node to replace (in the FIT being built)
> -                data (bytes): ELF-format data to process (may be empty)
> -                missing (bool): True if any of the data is missing
>  
> +                segments, entry_addr
> +
> +                data (bytes): ELF-format data to process (may be empty)
>              """
> -            # If any pieces are missing, skip this. The missing entries will
> -            # show an error
> -            if not missing:
> -                try:
> -                    segments, entry = elf.read_loadable_segments(elf_data)
> -                except ValueError as exc:
> -                    self._raise_subnode(node,
> -                                        f'Failed to read ELF file: {str(exc)}')
> -                for (seq, start, data) in segments:
> -                    node_name = node.name[1:].replace('SEQ', str(seq + 1))
> -                    with fsw.add_node(node_name):
> -                        loadables.append(node_name)
> -                        for pname, prop in node.props.items():
> -                            if not pname.startswith('fit,'):
> -                                fsw.property(pname, prop.bytes)
> -                            elif pname == 'fit,load':
> -                                fsw.property_u32('load', start)
> -                            elif pname == 'fit,entry':
> -                                if seq == 0:
> -                                    fsw.property_u32('entry', entry)
> -                            elif pname == 'fit,data':
> -                                fsw.property('data', bytes(data))
> -                            elif pname != 'fit,operation':
> -                                self._raise_subnode(
> -                                    node, f"Unknown directive '{pname}'")
> +            for (seq, start, data) in segments:
> +                node_name = node.name[1:].replace('SEQ', str(seq + 1))
> +                with fsw.add_node(node_name):
> +                    loadables.append(node_name)
> +                    for pname, prop in node.props.items():
> +                        if not pname.startswith('fit,'):
> +                            fsw.property(pname, prop.bytes)
> +                        elif pname == 'fit,load':
> +                            fsw.property_u32('load', start)
> +                        elif pname == 'fit,entry':
> +                            if seq == 0:
> +                                fsw.property_u32('entry', entry_addr)
> +                        elif pname == 'fit,data':
> +                            fsw.property('data', bytes(data))
> +                        elif pname != 'fit,operation':
> +                            self._raise_subnode(
> +                                node, f"Unknown directive '{pname}'")
>  
>          def _gen_node(base_node, node, depth, in_images, entry):
>              """Generate nodes from a template
> @@ -598,6 +591,8 @@ class Entry_fit(Entry_section):
>                  depth (int): Current node depth (0 is the base 'fit' node)
>                  in_images (bool): True if this is inside the 'images' node, so
>                      that 'data' properties should be generated
> +                entry (entry_Section): Entry for the second containing the
> +                    contents of this node
>              """
>              oper = self._get_operation(base_node, node)
>              if oper == OP_GEN_FDT_NODES:
> @@ -609,10 +604,24 @@ class Entry_fit(Entry_section):
>                  missing_list = []
>                  entry.ObtainContents()
>                  entry.Pack(0)
> -                data = entry.GetData()
>                  entry.CheckMissing(missing_list)
>  
> -                _gen_split_elf(base_node, node, data, bool(missing_list))
> +                # If any pieces are missing, skip this. The missing entries will
> +                # show an error
> +                if not missing_list:
> +                    segs = entry.read_elf_segments()
> +                    if segs:
> +                        segments, entry_addr = segs
> +                    else:
> +                        elf_data = entry.GetData()
> +                        try:
> +                            segments, entry_addr = (
> +                                    elf.read_loadable_segments(elf_data))
> +                        except ValueError as exc:
> +                            self._raise_subnode(
> +                                node, f'Failed to read ELF file: {str(exc)}')
> +
> +                    _gen_split_elf(base_node, node, segments, entry_addr)
>  
>          def _add_node(base_node, depth, node):
>              """Add nodes to the output FIT
> diff --git a/tools/binman/etype/section.py b/tools/binman/etype/section.py
> index dcb7a062047..57bfee0b286 100644
> --- a/tools/binman/etype/section.py
> +++ b/tools/binman/etype/section.py
> @@ -948,3 +948,12 @@ class Entry_section(Entry):
>          super().AddBintools(btools)
>          for entry in self._entries.values():
>              entry.AddBintools(btools)
> +
> +    def read_elf_segments(self):
> +        entries = self.GetEntries()
> +
> +        # If the section only has one entry, see if it can provide ELF segments
> +        if len(entries) == 1:
> +            for entry in entries.values():
> +                return entry.read_elf_segments()
> +        return None
> diff --git a/tools/binman/etype/tee_os.py b/tools/binman/etype/tee_os.py
> index 6ce4b672de4..687acd4689f 100644
> --- a/tools/binman/etype/tee_os.py
> +++ b/tools/binman/etype/tee_os.py
> @@ -4,19 +4,85 @@
>  # Entry-type module for OP-TEE Trusted OS firmware blob
>  #
>  
> +import struct
> +
>  from binman.etype.blob_named_by_arg import Entry_blob_named_by_arg
> +from binman import elf
>  
>  class Entry_tee_os(Entry_blob_named_by_arg):
>      """Entry containing an OP-TEE Trusted OS (TEE) blob
>  
>      Properties / Entry arguments:
>          - tee-os-path: Filename of file to read into entry. This is typically
> -            called tee-pager.bin
> +            called tee.bin or tee.elf
>  
>      This entry holds the run-time firmware, typically started by U-Boot SPL.
>      See the U-Boot README for your architecture or board for how to use it. See
>      https://github.com/OP-TEE/optee_os for more information about OP-TEE.
> +
> +    Note that if the file is in ELF format, it must go in a FIT. In that case,
> +    this entry will mark itself as absent, providing the data only through the
> +    read_elf_segments() method.
> +
> +    Marking this entry as absent means that it if is used in the wrong context
> +    it can be automatically dropped. Thus it is possible to add anb OP-TEE entry
> +    like this::
> +
> +        binman {
> +            tee-os {
> +            };
> +        };
> +
> +    and pass either an ELF or plain binary in with -a tee-os-path <filename>
> +    and have binman do the right thing:
> +
> +       - include the entry if tee.bin is provided and it doesn't have the v1
> +         header
> +       - drop it otherwise
> +
> +    When used within a FIT, we can do::
> +
> +        binman {
> +            fit {
> +                tee-os {
> +                };
> +            };
> +        };
> +
> +    which will split the ELF into separate nodes for each segment, if an ELF
> +    file is provide (see Flat Image Tree / FIT), or produce a single node if
> +    the binary v1 format is provided.
>      """
>      def __init__(self, section, etype, node):
>          super().__init__(section, etype, node, 'tee-os')
>          self.external = True
> +
> +    @staticmethod
> +    def is_optee_bin(data):
> +        return len(data) >= 8 and data[0:5] == b'OPTE\x01'
> +
> +    def ObtainContents(self, fake_size=0):
> +        super().ObtainContents(fake_size)
> +        if not self.missing:
> +            if elf.is_valid(self.data):
> +                self.mark_absent('uses Elf format which must be in a FIT')
> +            elif self.is_optee_bin(self.data):
> +                self.mark_absent('uses v1 format which must be in a FIT')
> +        return True
> +
> +    def read_elf_segments(self):
> +        data = self.GetData()
> +        if self.is_optee_bin(data):
> +            # OP-TEE v1 format (tee.bin)
> +            init_sz, start_hi, start_lo, _, paged_sz = (
> +                struct.unpack_from('<5I', data, 0x8))
> +            if paged_sz != 0:
> +                self.Raise("OP-TEE paged mode not supported")
> +            e_entry = (start_hi << 32) + start_lo
> +            p_addr = e_entry
> +            p_data = data[0x1c:]
> +            if len(p_data) != init_sz:
> +                self.Raise("Invalid OP-TEE file: size mismatch (expected %#x, have %#x)" %
> +                           (init_sz, len(p_data)))
> +            return [[0, p_addr, p_data]], e_entry
> +        return None
> diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
> index f47a745f1e1..f893050e706 100644
> --- a/tools/binman/ftest.py
> +++ b/tools/binman/ftest.py
> @@ -112,6 +112,8 @@ REPACK_DTB_PROPS = ['orig-offset', 'orig-size']
>  # Supported compression bintools
>  COMP_BINTOOLS = ['bzip2', 'gzip', 'lz4', 'lzma_alone', 'lzop', 'xz', 'zstd']
>  
> +TEE_ADDR = 0x5678
> +
>  class TestFunctional(unittest.TestCase):
>      """Functional tests for binman
>  
> @@ -219,6 +221,9 @@ class TestFunctional(unittest.TestCase):
>          TestFunctional._MakeInputFile('tee.elf',
>              tools.read_file(cls.ElfTestFile('elf_sections')))
>  
> +        # Newer OP_TEE file in v1 binary format
> +        cls.make_tee_bin('tee.bin')
> +
>          cls.comp_bintools = {}
>          for name in COMP_BINTOOLS:
>              cls.comp_bintools[name] = bintool.Bintool.create(name)
> @@ -644,6 +649,14 @@ class TestFunctional(unittest.TestCase):
>      def ElfTestFile(cls, fname):
>          return os.path.join(cls._elf_testdir, fname)
>  
> +    @classmethod
> +    def make_tee_bin(cls, fname, paged_sz=0, extra_data=b''):
> +        init_sz, start_hi, start_lo, dummy = (len(U_BOOT_DATA), 0, TEE_ADDR, 0)
> +        data = b'OPTE\x01xxx' + struct.pack('<5I', init_sz, start_hi, start_lo,
> +                                            dummy, paged_sz) + U_BOOT_DATA
> +        data += extra_data
> +        TestFunctional._MakeInputFile(fname, data)
> +
>      def AssertInList(self, grep_list, target):
>          """Assert that at least one of a list of things is in a target
>  
> @@ -6095,6 +6108,76 @@ fdt         fdtmap                Extract the devicetree blob from the fdtmap
>          data = self._DoReadFile('262_absent.dts')
>          self.assertEqual(U_BOOT_DATA + U_BOOT_IMG_DATA, data)
>  
> +    def testPackTeeOsOptional(self):
> +        """Test that an image with an optional TEE binary can be created"""
> +        entry_args = {
> +            'tee-os-path': 'tee.elf',
> +        }
> +        data = self._DoReadFileDtb('263_tee_os_opt.dts',
> +                                   entry_args=entry_args)[0]
> +        self.assertEqual(U_BOOT_DATA + U_BOOT_IMG_DATA, data)
> +
> +    def checkFitTee(self, dts, tee_fname):
> +        """Check that a tee-os entry works and returns data
> +
> +        Args:
> +            dts (str): Device tree filename to use
> +            tee_fname (str): filename containing tee-os
> +
> +        Returns:
> +            bytes: Image contents
> +        """
> +        if not elf.ELF_TOOLS:
> +            self.skipTest('Python elftools not available')
> +        entry_args = {
> +            'of-list': 'test-fdt1 test-fdt2',
> +            'default-dt': 'test-fdt2',
> +            'tee-os-path': tee_fname,
> +        }
> +        test_subdir = os.path.join(self._indir, TEST_FDT_SUBDIR)
> +        data = self._DoReadFileDtb(dts, entry_args=entry_args,
> +                                   extra_indirs=[test_subdir])[0]
> +        return data
> +
> +    def testFitTeeOsOptionalFit(self):
> +        """Test an image with a FIT with an optional OP-TEE binary"""
> +        data = self.checkFitTee('264_tee_os_opt_fit.dts', 'tee.bin')
> +
> +        # There should be only one node, holding the data set up in SetUpClass()
> +        # for tee.bin
> +        dtb = fdt.Fdt.FromData(data)
> +        dtb.Scan()
> +        node = dtb.GetNode('/images/tee-1')
> +        self.assertEqual(TEE_ADDR,
> +                         fdt_util.fdt32_to_cpu(node.props['load'].value))
> +        self.assertEqual(TEE_ADDR,
> +                         fdt_util.fdt32_to_cpu(node.props['entry'].value))
> +        self.assertEqual(U_BOOT_DATA, node.props['data'].bytes)
> +
> +    def testFitTeeOsOptionalFitBad(self):
> +        """Test an image with a FIT with an optional OP-TEE binary"""
> +        with self.assertRaises(ValueError) as exc:
> +            self.checkFitTee('265_tee_os_opt_fit_bad.dts', 'tee.bin')
> +        self.assertIn(
> +            "Node '/binman/fit': subnode 'images/@tee-SEQ': Failed to read ELF file: Magic number does not match",
> +            str(exc.exception))
> +
> +    def testFitTeeOsBad(self):
> +        """Test an OP-TEE binary with wrong formats"""
> +        self.make_tee_bin('tee.bad1', 123)
> +        with self.assertRaises(ValueError) as exc:
> +            self.checkFitTee('264_tee_os_opt_fit.dts', 'tee.bad1')
> +        self.assertIn(
> +            "Node '/binman/fit/images/@tee-SEQ/tee-os': OP-TEE paged mode not supported",
> +            str(exc.exception))
> +
> +        self.make_tee_bin('tee.bad2', 0, b'extra data')
> +        with self.assertRaises(ValueError) as exc:
> +            self.checkFitTee('264_tee_os_opt_fit.dts', 'tee.bad2')
> +        self.assertIn(
> +            "Node '/binman/fit/images/@tee-SEQ/tee-os': Invalid OP-TEE file: size mismatch (expected 0x4, have 0xe)",
> +            str(exc.exception))
> +
>  
>  if __name__ == "__main__":
>      unittest.main()
> diff --git a/tools/binman/test/263_tee_os_opt.dts b/tools/binman/test/263_tee_os_opt.dts
> new file mode 100644
> index 00000000000..2e4ec24ac2c
> --- /dev/null
> +++ b/tools/binman/test/263_tee_os_opt.dts
> @@ -0,0 +1,22 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> +/dts-v1/;
> +
> +/ {
> +	#address-cells = <1>;
> +	#size-cells = <1>;
> +
> +	binman {
> +		u-boot {
> +		};
> +		tee-os {
> +			/*
> +			 * this results in nothing being added since only the
> +			 * .bin format is supported by this etype, unless it is
> +			 * part of a FIT
> +			 */
> +		};
> +		u-boot-img {
> +		};
> +	};
> +};
> diff --git a/tools/binman/test/264_tee_os_opt_fit.dts b/tools/binman/test/264_tee_os_opt_fit.dts
> new file mode 100644
> index 00000000000..ae44b433edf
> --- /dev/null
> +++ b/tools/binman/test/264_tee_os_opt_fit.dts
> @@ -0,0 +1,33 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> +/dts-v1/;
> +
> +/ {
> +	#address-cells = <1>;
> +	#size-cells = <1>;
> +
> +	binman {
> +		fit {
> +			description = "test-desc";
> +			#address-cells = <1>;
> +			fit,fdt-list = "of-list";
> +
> +			images {
> +				@tee-SEQ {
> +					fit,operation = "split-elf";
> +					description = "TEE";
> +					type = "tee";
> +					arch = "arm64";
> +					os = "tee";
> +					compression = "none";
> +					fit,load;
> +					fit,entry;
> +					fit,data;
> +
> +					tee-os {
> +					};
> +				};
> +			};
> +		};
> +	};
> +};
> diff --git a/tools/binman/test/265_tee_os_opt_fit_bad.dts b/tools/binman/test/265_tee_os_opt_fit_bad.dts
> new file mode 100644
> index 00000000000..7fa363cc199
> --- /dev/null
> +++ b/tools/binman/test/265_tee_os_opt_fit_bad.dts
> @@ -0,0 +1,40 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> +/dts-v1/;
> +
> +/ {
> +	#address-cells = <1>;
> +	#size-cells = <1>;
> +
> +	binman {
> +		fit {
> +			description = "test-desc";
> +			#address-cells = <1>;
> +			fit,fdt-list = "of-list";
> +
> +			images {
> +				@tee-SEQ {
> +					fit,operation = "split-elf";
> +					description = "TEE";
> +					type = "tee";
> +					arch = "arm64";
> +					os = "tee";
> +					compression = "none";
> +					fit,load;
> +					fit,entry;
> +					fit,data;
> +
> +					tee-os {
> +					};
> +
> +					/*
> +					 * mess up the ELF data by adding
> +					 * another bit of data at the end
> +					 */
> +					u-boot {
> +					};
> +				};
> +			};
> +		};
> +	};
> +};

  reply	other threads:[~2022-12-22 15:36 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-12-21 23:07 [PATCH v8 00/13] binman: rockchip: Migrate from rockchip SPL_FIT_GENERATOR script Simon Glass
2022-12-21 23:07 ` [PATCH v8 01/13] binman: Allow writing section contents to a file Simon Glass
2022-12-21 23:07 ` [PATCH v8 02/13] binman: Tidy up comment in fit _gen_node Simon Glass
2022-12-21 23:07 ` [PATCH v8 03/13] binman: Update entry docs Simon Glass
2023-01-02 16:19   ` Quentin Schulz
2022-12-21 23:07 ` [PATCH v8 04/13] binman: Support optional entries Simon Glass
2022-12-21 23:07 ` [PATCH v8 05/13] binman: Add a way to check for a valid ELF file Simon Glass
2023-01-02 16:26   ` Quentin Schulz
2022-12-21 23:07 ` [PATCH v8 06/13] binman: Support new op-tee binary format Simon Glass
2022-12-22 15:36   ` Jerome Forissier [this message]
2022-12-22 20:18     ` Simon Glass
2022-12-22 20:23       ` Simon Glass
2022-12-22 22:20         ` Jerome Forissier
2023-01-07 18:55           ` Simon Glass
2023-01-07 21:58             ` Jerome Forissier
2023-01-02 17:53   ` Quentin Schulz
2023-01-07 18:55     ` Simon Glass
2023-01-07 21:51       ` Jerome Forissier
2022-12-21 23:07 ` [PATCH v8 07/13] binman: Support optional external blobs Simon Glass
2022-12-21 23:07 ` [PATCH v8 08/13] rockchip: evb-rk3288: Drop raw-image support Simon Glass
2022-12-21 23:07 ` [PATCH v8 09/13] rockchip: Use multiple-images for rk3399 Simon Glass
2023-01-02 16:42   ` Quentin Schulz
2023-01-04 20:01     ` Simon Glass
2023-01-05  9:47       ` Quentin Schulz
2023-01-07  0:13         ` Simon Glass
2022-12-21 23:07 ` [PATCH v8 10/13] rockchip: Support building the all output files in binman Simon Glass
2022-12-21 23:07 ` [PATCH v8 11/13] rockchip: Convert all boards to use binman Simon Glass
2022-12-21 23:07 ` [PATCH v8 12/13] rockchip: Drop the FIT generator script Simon Glass
2022-12-21 23:07 ` [PATCH v8 13/13] treewide: Disable USE_SPL_FIT_GENERATOR by default Simon Glass
2022-12-21 23:11   ` Tom Rini
2022-12-22 17:41     ` Simon Glass
2022-12-22 17:57       ` Tom Rini
2022-12-22 19:25         ` Simon Glass

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=39733f31-347a-53fe-6186-1891354413c6@linaro.org \
    --to=jerome.forissier@linaro.org \
    --cc=alpernebiyasak@gmail.com \
    --cc=hl@rock-chips.com \
    --cc=ivan.mikhaylov@siemens.com \
    --cc=jeffy.chen@rock-chips.com \
    --cc=kever.yang@rock-chips.com \
    --cc=pgwipeout@gmail.com \
    --cc=philipp.tomsich@theobroma-systems.com \
    --cc=philippe.reynes@softathome.com \
    --cc=quentin.schulz@theobroma-systems.com \
    --cc=rogerq@ti.com \
    --cc=sjg@chromium.org \
    --cc=trini@konsulko.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.