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 29348CD5BC8 for ; Mon, 25 May 2026 23:52:08 +0000 (UTC) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 1CED0848F0; Tue, 26 May 2026 01:52:06 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=reject dis=none) header.from=nabladev.com 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=nabladev.com header.i=@nabladev.com header.b="WabW2qqh"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 9DCCA84926; Tue, 26 May 2026 01:52:05 +0200 (CEST) Received: from mx.nabladev.com (mx.nabladev.com [IPv6:2a00:f820:417:0:178:251:229:89]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 6D64C848BF for ; Tue, 26 May 2026 01:52:03 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=reject dis=none) header.from=nabladev.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=marex@nabladev.com Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 4C381115D1F; Tue, 26 May 2026 01:52:01 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nabladev.com; s=dkim; t=1779753122; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding; bh=0KLZ65Z+lbmcbXmxXZtE8XdI2swrU3t3MBAErrH7P3s=; b=WabW2qqh7MRhMVDDvjzLrcAvqppPd01tlgHFrSicqdKKyT25i5UrnztEWeBUQvR3mGEcAU MgZm/6PxK5nBhcVkGXCUbl4Vsc2JNCRhIe0HxBC9RTEPdGrGjI75qUXzUl/DBIAg6WQ+Z/ MiDSR7zfcxcl+LvPMCvJPOSxocGblnOiHqWB/+CCOgaH1hqU4BgEUoznoCG+yyo50x7u7f l/ODlwj6ZtT7HGhqPcDJS+rUejiyv5p2I9u7XMTP0GpFKwIFcfhL0vGzTop5nMaoiOV5nj LrUO4UceMNHxeguZTJll+ANwFNWa0CI9zBuNIPcBxwdZCxjGUgKtT6F+Puc0pg== From: Marek Vasut To: u-boot@lists.denx.de Cc: Marek Vasut , "NXP i.MX U-Boot Team" , Adam Ford , Alexander Koch , Fabio Estevam , Peng Fan , Simon Glass , Tom Rini Subject: [PATCH v2 1/3] binman: imx8mimage: Handle nxp,boot-from = "fspi" Date: Tue, 26 May 2026 01:51:01 +0200 Message-ID: <20260525235155.96167-1-marex@nabladev.com> X-Mailer: git-send-email 2.53.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Last-TLS-Session-Version: TLSv1.3 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.8 at phobos.denx.de X-Virus-Status: Clean Boot from FSPI requires additional 448 Byte long header, with U-Boot SPL starting at offset 0x1000. Currently, both i.MX8MM and i.MX8MN attempt to generate this header using fspi_conf_block with filename pointing at CONFIG_FSPI_CONF_FILE file. This does not work, for two reasons. First, the CONFIG_FSPI_CONF_FILE is generated by mkimage -T imx8mimage and may not be available yet when the fspi_conf_block is evaluated. That leads to a race condition where highly parallel builds fail to find the CONFIG_FSPI_CONF_FILE, which is usually called fspi_header.bin, on first build attempt. Second, binman gets confused and patches incorrect offset of DDR PHY firmware blobs into U-Boot SPL, the offset is incremented by exactly 0x1000 which is the size of fspi_conf_block. Fix both problems at once, make imx8mimage handle the generated FSPI header and prepend it in front of the imx8mimage processed data. This way, the race condition is solved, because the data generated by the imx8mimage are surely combined only after mkimage -T imx8mimage ran. The binman offset calculation is also solved, because there is no fspi_conf_block node in the DT anymore. Signed-off-by: Marek Vasut --- Cc: "NXP i.MX U-Boot Team" Cc: Adam Ford Cc: Alexander Koch Cc: Fabio Estevam Cc: Peng Fan Cc: Simon Glass Cc: Tom Rini Cc: u-boot@lists.denx.de --- V2: - Move test into vendor/nxp_imx8m_fspi.dts - Fix up path handling in both etype and test --- tools/binman/etype/nxp_imx8mimage.py | 11 ++++++++++- tools/binman/ftest.py | 9 +++++++++ tools/binman/test/vendor/nxp_imx8m_fspi.dts | 18 ++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 tools/binman/test/vendor/nxp_imx8m_fspi.dts diff --git a/tools/binman/etype/nxp_imx8mimage.py b/tools/binman/etype/nxp_imx8mimage.py index 8ad177b3b65..008d2f914db 100644 --- a/tools/binman/etype/nxp_imx8mimage.py +++ b/tools/binman/etype/nxp_imx8mimage.py @@ -7,6 +7,8 @@ # configuration file and input data. # +import os + from collections import OrderedDict from binman.entry import Entry @@ -33,6 +35,7 @@ class Entry_nxp_imx8mimage(Entry_mkimage): def ReadNode(self): super().ReadNode() self.boot_from = fdt_util.GetString(self._node, 'nxp,boot-from') + self.fspi_header = fdt_util.GetString(self._node, 'nxp,fspi-header-filename') self.loader_address = fdt_util.GetInt(self._node, 'nxp,loader-address') self.rom_version = fdt_util.GetInt(self._node, 'nxp,rom-version') self.ReadEntries() @@ -52,7 +55,13 @@ class Entry_nxp_imx8mimage(Entry_mkimage): args = ['-d', input_fname, '-n', cfg_fname, '-T', 'imx8mimage', output_fname] if self.mkimage.run_cmd(*args) is not None: - return tools.read_file(output_fname) + outdata = tools.read_file(output_fname) + if self.boot_from == 'fspi' and self.fspi_header: + spidata = tools.read_file(os.path.join(tools.get_output_dir(), self.fspi_header)) + if len(spidata) < 0x1000: + spidata += tools.get_bytes(0, 0x1000 - len(spidata)) + outdata = spidata + outdata + return outdata else: # Bintool is missing; just use the input data as the output self.record_missing_bintool(self.mkimage) diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 9a3811c1732..d85ecffdc21 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -8099,6 +8099,15 @@ fdt fdtmap Extract the devicetree blob from the fdtmap result = cst.fetch(bintool.FETCH_BUILD) self.assertEqual(('cst', None), result) + def testNxpImx8MFSPI(self): + """Test that binman can produce an iMX8m FSPI image""" + testdir = tempfile.mkdtemp(prefix='binman.') + image_path = os.path.join(testdir, 'fspi_header.bin') + with open(image_path, 'w') as f: + f.write(bytes([0x87]).decode('latin1') * 448) + with terminal.capture(): + self._DoTestFile('vendor/nxp_imx8m_fspi.dts', output_dir=testdir) + def testNxpHeaderDdrfw(self): """Test that binman can add a header to DDR PHY firmware images""" data = self._DoReadFile('vendor/nxp_ddrfw_imx95.dts') diff --git a/tools/binman/test/vendor/nxp_imx8m_fspi.dts b/tools/binman/test/vendor/nxp_imx8m_fspi.dts new file mode 100644 index 00000000000..6b04eca757c --- /dev/null +++ b/tools/binman/test/vendor/nxp_imx8m_fspi.dts @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + nxp-imx8mimage { + args; /* TODO: Needed by mkimage etype superclass */ + nxp,boot-from = "fspi"; + nxp,fspi-header-filename = "fspi_header.bin"; + nxp,rom-version = <2>; + nxp,loader-address = <0x10>; + }; + }; +}; -- 2.53.0