From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 58B3FC4332F for ; Thu, 22 Dec 2022 22:20:17 +0000 (UTC) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 43255852E5; Thu, 22 Dec 2022 23:20:15 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="snsvyWiJ"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 1707A85362; Thu, 22 Dec 2022 23:20:13 +0100 (CET) Received: from mail-ej1-x62a.google.com (mail-ej1-x62a.google.com [IPv6:2a00:1450:4864:20::62a]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 9AFF885225 for ; Thu, 22 Dec 2022 23:20:08 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=jerome.forissier@linaro.org Received: by mail-ej1-x62a.google.com with SMTP id ud5so8088203ejc.4 for ; Thu, 22 Dec 2022 14:20:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:date:message-id :from:to:cc:subject:date:message-id:reply-to; bh=In4FVGO/fwKKnos/Su1v7wLttIlWJt6t/5r9DuEfeh8=; b=snsvyWiJM1Ktl85YEtoZUCB9se9NuV5X6bqSMRyL5gELuwbcEY52aBu5dzecJzfCfj 3NIH0UA35yJ8GE2hNYwEAQk2iLkk65dbhCqPkzF7rkADWDbA4WbdX6oaEajMlQh19a5N NrASp3x5zzQeAV+eOOwK6c+xFqa0trVtD+9cDx2esDuKYZfisFi3nwyOv2Vp1GC8ejwM dGK1w8zJflCZ+8FIclDlQUWEy/QNzp5pg46oaaiYcYpj9w6uTK8BhvTdcOIpdIzOEAoT uOKc8rhvBFs9ijFZ8jPWTlL5c/sefQP5ioyhspfRlgJuEXyxdkGV7yWe3KAo0EWT79jv hd8w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=In4FVGO/fwKKnos/Su1v7wLttIlWJt6t/5r9DuEfeh8=; b=qiQV5ffPxKR7vS0KddhGTRi6aa1Xp44saUcazNHs2eGkyKQML6Ol6MYLyC7NA5pFAo MEulVfuezXAuU5tChhKb4QXyC9T8lczgmxCT0ZRLcXO7z5CivsYWLbTvYTtHLZUiisAf L5GjSyAJVDdeGjwE0wst6QyjWDTn3b1k/evAdNfGeMCeCfpBvWrV9dYhOdbTBEylVmSx rBRUeNn4ads0B2gFNUuC7Qgx18sFwuLNY7o1ME+CiccP9d8z4oX0K5pdY28fXweUPqeL tK74ZBR9wxYYzfXvj88nGi26wiXY7668hoU2kQ2zyFah3PmhMEeOgNU0EeM61KrLxUoH ancQ== X-Gm-Message-State: AFqh2kpkydYL5N3O5YbO+DlDQZm2mceItM86fowBPfcb6RyIwnSNO9hF E+a5GXtCQRM0AzkyPRxhE9s/Xw== X-Google-Smtp-Source: AMrXdXv4QoluJy9ylNpnXJ+BOi2dc5D9x2moZGt1z5q4nSsdMN6k4LjChshtldzMC89lYcC/Fowt3Q== X-Received: by 2002:a17:906:c44:b0:7c1:700:9c4b with SMTP id t4-20020a1709060c4400b007c107009c4bmr5133699ejf.75.1671747608001; Thu, 22 Dec 2022 14:20:08 -0800 (PST) Received: from [10.7.0.4] ([82.180.148.115]) by smtp.gmail.com with ESMTPSA id b13-20020a1709063f8d00b0073c8d4c9f38sm675579ejj.177.2022.12.22.14.20.06 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 22 Dec 2022 14:20:07 -0800 (PST) Message-ID: <040aed51-90e8-8751-6161-056dd391d634@linaro.org> Date: Thu, 22 Dec 2022 23:20:04 +0100 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.4.2 Subject: Re: [PATCH v8 06/13] binman: Support new op-tee binary format To: Simon Glass Cc: U-Boot Mailing List , Tom Rini , huang lin , Jeffy Chen , Kever Yang , Quentin Schulz , Roger Quadros , Philippe Reynes , Alper Nebi Yasak , Peter Geis References: <20221221230726.638740-1-sjg@chromium.org> <20221221230726.638740-7-sjg@chromium.org> <39733f31-347a-53fe-6186-1891354413c6@linaro.org> Content-Language: en-US From: Jerome Forissier In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.6 at phobos.denx.de X-Virus-Status: Clean On 12/22/22 21:23, Simon Glass wrote: > (dropping the two bounces from cc) > > On Thu, 22 Dec 2022 at 13:18, Simon Glass wrote: >> >> Hi Jerome, >> >> On Thu, 22 Dec 2022 at 08:36, Jerome Forissier >> wrote: >>> >>> >>> >>> 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. >> >> Is this file in the v1 binary format (with the custom header), Yes >> or is >> is a plain binary file? At present only the former is supported, as I >> thought that it can only be the elf or the v1 binary format these >> days? Correct >> Actually can you please send me the tee.bin ? Sure, here you go: https://ufile.io/f/ex5oy I have added bl31.elf too, although I suppose it is handled properly being an ELF file. Thanks, -- Jerome >> Regards, >> Simon >> >> >>> >>> Thanks, >>> -- >>> Jerome >>> >>>> Signed-off-by: Simon Glass >>>> --- >>>> >>>> (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 >>>> +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 >>>> + 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 { >>>> + }; >>>> + }; >>>> + }; >>>> + }; >>>> + }; >>>> +};