From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0467D34A773; Wed, 26 Aug 2026 09:50:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737842; cv=none; b=lSOsQDVxZ0UbOQvet8g1zPXX9D7jXLE8dmI+rsRiDrvIGzhSWhSuR95BZmPobNVcSoaHkT5dHqtxLbwUh4yc/1GrZLztlhoW5o+YSir1WMHyR3/E1seo72rc/1wZx/ZA9W+qKEIernWXru1JeyBNUb6wGJCFYh9lHZzODF+nVhU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737842; c=relaxed/simple; bh=a8yWwWwuaeV1ND4PZ/6EpeUN2fdNqL2jl0/3BSi4xx4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=PRgL1X+URry/wyld88AcL6JjzRK9yEPsIAhSj3DzA9lpmKLRoA3DJl5OOs0nCqZ5iLhuVjb97K1Qlhp/dM1S4HAVSvp6e7LNWfXSO1Tg4vqJhGacFu/Jgb2CUzxl3YQDQxNMlYqzTFkBHMeIb+DW/UinvsW4fv9/tKIQ6EB/IhA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=hBQJSwKl; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="hBQJSwKl" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 62A564E413BF; Wed, 26 Aug 2026 09:50:35 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 310C0604EC; Wed, 26 Aug 2026 09:50:35 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id D652411C7AD52; Wed, 26 Aug 2026 11:50:32 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737834; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=qZA52EnhjJI6y63U2fQLoVVzoZiNH25f6cUFrSM/XlA=; b=hBQJSwKlkILFw+PvE0Zw9cWK3PuvJz9fnhvPkJRw+aMpQuUUojePKQgzi+uQQRmQZ480Xv rjQieDilh9aI3g8a8om0MDo5abcaymTn5KEmpek/zQsA2DHxh/Rvl445TlWvNuCWIjbpnY 3d72XVDgH335vx50Z/djxM9DXwrzIqvwHQU5VWVY60UcVoGHr7v65AwFNIbDW/JbfQ+BR/ AYHjkjlX++OXPZcV+fuXhC3nh45u+b2Kv1Z8ZMV33OdPcd7S2USgfeoh0XtGdN0ZNf82e1 6ZkBPMFTw2MOKbhX6puQwlUYTzrmQp3Y/Du556tZWtOZkjRyGpZSspNfmKmElg== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 01/74] dtc-parser.y: Avoid an empty proplist Date: Wed, 26 Aug 2026 11:48:30 +0200 Message-ID: <20260826094950.1088288-2-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" In the dts parser grammar, a nodedef is defined by '{' proplist subnodes '}' ';' with both proplist and subnodes that can be empty lists. Having multiple possible empty list can lead to Bison warnings such as warning: 4 shift/reduce conflicts [-Wconflicts-sr] warning: 1 reduce/reduce conflict [-Wconflicts-rr] This will happen as soon as a new list (which also could be empty) is added in the nodedef definition. The simpler way to remove those warning and thus have a robust parsing is to avoid multiple empty lists. Update the proplist definition and nodedef definition to avoid those multiple empty lists. Instead of allowing a proplist to be an empty list, force the list to be a non empty one and update the nodedef to handle explicitly the absence of the proplist to support the case where no properties are available, i.e. the case of a node composed only of sub-nodes. This doesn't change the functional behavior. Signed-off-by: Herve Codina --- dtc-parser.y | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/dtc-parser.y b/dtc-parser.y index 4d5eece5..e47f80d4 100644 --- a/dtc-parser.y +++ b/dtc-parser.y @@ -267,12 +267,16 @@ nodedef: { $$ =3D build_node($2, $3, &@$); } + | '{' subnodes '}' ';' + { + $$ =3D build_node(NULL, $2, &@$); + } ; =20 proplist: - /* empty */ + propdef { - $$ =3D NULL; + $$ =3D chain_property($1, NULL); } | proplist propdef { --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 447923BED56; Wed, 26 Aug 2026 09:50:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737845; cv=none; b=Y3gThdku/bdKBN3I6vSe8J+uyHzmm5s2k2680OQWSwxShRNNAQUDtWCTCdUZV3pxJhW1X4fDQl6LAk4YY++aFElJKBDXQh/5s//QuFfua7nHwamGV/diXzPfIIINh62Tu3LAWu6b0uoFzAZa2ea71DEz3LirfAhwFK5gnmO61TY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737845; c=relaxed/simple; bh=IdaWCbhLxuMADF65gAwmxOCt/ZiQ0u2hAYloZMxwQqs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=GZCzl+k9Xaue/BSFoq1wu9JSQzsknpDTNAEw19pKR5kH0N1+h/5F0psxuSOOR54Bahuomc7r+xbssZxXOYXnWGgjWTJhK86jIrPkEQBMqFMaRneNHqBQYcVa8muSRzaMGwHBM9FLqFyTLBZj6kTw0q8UONU/bbXzpE39bg4aAc4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=pW+Eikka; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="pW+Eikka" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id BB18B4E413C1; Wed, 26 Aug 2026 09:50:37 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 90CB0604EC; Wed, 26 Aug 2026 09:50:37 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id E23D911C7AD55; Wed, 26 Aug 2026 11:50:34 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737836; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=s/Qex1klhgUuSLDyTxLdJ4YDpclPW8lihSwWOKlLUo0=; b=pW+EikkaJMxmx5q46ggOk2m4o6FCEShCxgNcnk/bVEOhGx0bUVZkakj0L3FkNirne1xBCF L/LArz5QkaMuvw0BjAY8npTEVGOH+YeK1Vn/CxA9dClD8T/ytRFNX5MKYUTPIrLFN5mMNE AOWD3wG4uSzzSqEGRqOvaO5rx6yjCwSUceQocmNY9kItwuTEjLe8vEnnWddgcJFufhMojE fyrMfnE5a2IAgSTY6H7Js1DaMFXlpQP/g74yVlFnmrgLv+ZSFVHF6qdqCkJnjlaTfxykWV dlXVGeWcjMfNoidb9fYKiPq9XP7GdtdMLSvkLRhXFsAr5hCEywnPkYkntzcN5g== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 02/74] Introduce v20 dtb version Date: Wed, 26 Aug 2026 11:48:31 +0200 Message-ID: <20260826094950.1088288-3-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" This v20 version will add support for - metadata in device-tree blobs in order to have a better handling of phandles and unresolved references. - Addon device-tree blob (successor of device-tree overlay) - Import and export symbols feature - multiple trees in an addon device-tree blob (i.e. root device tree and orphan node tree) Signed-off-by: Herve Codina --- dtc.h | 2 +- fdtdump.c | 2 +- flattree.c | 3 +++ libfdt/fdt.h | 1 + libfdt/fdt_rw.c | 13 +++++++------ libfdt/libfdt.h | 6 +++--- tests/pylibfdt_tests.py | 6 +++--- tests/treegen.c | 2 +- .../unknown_tags_can_skip.fdtput.test.dtb.1.expect | 2 +- tests/unknown_tags_can_skip.wip.test.dtb.1.expect | 2 +- 10 files changed, 22 insertions(+), 17 deletions(-) diff --git a/dtc.h b/dtc.h index f0c2cde6..ef3f2682 100644 --- a/dtc.h +++ b/dtc.h @@ -29,7 +29,7 @@ #define debug(...) #endif =20 -#define DEFAULT_FDT_VERSION 18 +#define DEFAULT_FDT_VERSION 20 =20 /* * Command line options diff --git a/fdtdump.c b/fdtdump.c index 5994e1d7..20854752 100644 --- a/fdtdump.c +++ b/fdtdump.c @@ -18,7 +18,7 @@ #include "util.h" =20 #define FDT_MAGIC_SIZE 4 -#define MAX_VERSION 18U +#define MAX_VERSION 20U =20 #define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1)) #define PALIGN(p, a) ((void *)(ALIGN((uintptr_t)(p), (a)))) diff --git a/flattree.c b/flattree.c index ff57fc5d..dd451f0c 100644 --- a/flattree.c +++ b/flattree.c @@ -36,6 +36,9 @@ static struct version_info { {18, 16, 17, FDT_V18_SIZE, FTF_BOOTCPUID|FTF_STRTABSIZE|FTF_STRUCTSIZE|FTF_NOPS|FTF_DTFLAGS| FTF_LCVERSW}, + {20, 18, 18, FDT_V20_SIZE, + FTF_BOOTCPUID|FTF_STRTABSIZE|FTF_STRUCTSIZE|FTF_NOPS|FTF_DTFLAGS| + FTF_LCVERSW}, }; =20 struct emitter { diff --git a/libfdt/fdt.h b/libfdt/fdt.h index a43b85c1..7c59fed2 100644 --- a/libfdt/fdt.h +++ b/libfdt/fdt.h @@ -90,5 +90,6 @@ struct fdt_property { #define FDT_V16_SIZE FDT_V3_SIZE #define FDT_V17_SIZE (FDT_V16_SIZE + sizeof(fdt32_t)) #define FDT_V18_SIZE (FDT_V17_SIZE + 2 * sizeof(fdt32_t)) +#define FDT_V20_SIZE FDT_V18_SIZE =20 #endif /* FDT_H */ diff --git a/libfdt/fdt_rw.c b/libfdt/fdt_rw.c index 005efde8..1c6ce0a3 100644 --- a/libfdt/fdt_rw.c +++ b/libfdt/fdt_rw.c @@ -628,10 +628,11 @@ int fdt_open_into(const void *fdt, void *buf, int buf= size) err =3D fdt_move(fdt, buf, bufsize); if (err) return err; - if (can_assume(LATEST) || fdt_version(fdt) < 18) { - fdt_set_version(buf, 18); + + if (can_assume(LATEST) || fdt_version(fdt) < 20) { + fdt_set_version(buf, 20); fdt_set_dt_flags(buf, 0); - fdt_set_last_comp_version_w(buf, 17); + fdt_set_last_comp_version_w(buf, 18); } fdt_set_size_dt_struct(buf, struct_size); fdt_set_totalsize(buf, bufsize); @@ -661,10 +662,10 @@ int fdt_open_into(const void *fdt, void *buf, int buf= size) =20 fdt_set_magic(buf, FDT_MAGIC); fdt_set_totalsize(buf, bufsize); - fdt_set_version(buf, 18); - fdt_set_last_comp_version(buf, 16); + fdt_set_version(buf, 20); + fdt_set_last_comp_version(buf, 18); fdt_set_dt_flags(buf, 0); - fdt_set_last_comp_version_w(buf, 17); + fdt_set_last_comp_version_w(buf, 18); fdt_set_boot_cpuid_phys(buf, fdt_boot_cpuid_phys(fdt)); =20 return 0; diff --git a/libfdt/libfdt.h b/libfdt/libfdt.h index 8e99e644..5e1e0d06 100644 --- a/libfdt/libfdt.h +++ b/libfdt/libfdt.h @@ -14,9 +14,9 @@ extern "C" { #endif =20 #define FDT_FIRST_SUPPORTED_VERSION 0x02 -#define FDT_LAST_COMPATIBLE_VERSION 0x10 -#define FDT_LAST_COMPATIBLE_VERSION_W 0x11 -#define FDT_LAST_SUPPORTED_VERSION 0x12 +#define FDT_LAST_COMPATIBLE_VERSION 0x12 +#define FDT_LAST_COMPATIBLE_VERSION_W 0x12 +#define FDT_LAST_SUPPORTED_VERSION 0x14 =20 /* Error codes: informative error codes */ #define FDT_ERR_NOTFOUND 1 diff --git a/tests/pylibfdt_tests.py b/tests/pylibfdt_tests.py index c3aaf00f..bae52406 100644 --- a/tests/pylibfdt_tests.py +++ b/tests/pylibfdt_tests.py @@ -277,13 +277,13 @@ class PyLibfdtBasicTests(unittest.TestCase): self.assertEqual(self.fdt.off_dt_struct(), 96) self.assertEqual(self.fdt.off_dt_strings(), 660) self.assertEqual(self.fdt.off_mem_rsvmap(), 48) - self.assertEqual(self.fdt.version(), 18) - self.assertEqual(self.fdt.last_comp_version(), 16) + self.assertEqual(self.fdt.version(), 20) + self.assertEqual(self.fdt.last_comp_version(), 18) self.assertEqual(self.fdt.boot_cpuid_phys(), 0) self.assertEqual(self.fdt.size_dt_strings(), 105) self.assertEqual(self.fdt.size_dt_struct(), 564) self.assertEqual(self.fdt.dt_flags(), 0) - self.assertEqual(self.fdt.last_comp_version_w(), 17) + self.assertEqual(self.fdt.last_comp_version_w(), 18) =20 def testPack(self): """Test that we can pack the tree after deleting something""" diff --git a/tests/treegen.c b/tests/treegen.c index b0730ef6..36cb5508 100644 --- a/tests/treegen.c +++ b/tests/treegen.c @@ -127,7 +127,7 @@ static size_t emit_fdt_header_vers(struct buf *b, uint3= 2_t version, =20 static size_t emit_fdt_header(struct buf *b) { - return emit_fdt_header_vers(b, 0x12, 0x10, 0x11); + return emit_fdt_header_vers(b, 0x14, 0x12, 0x12); } =20 static void finish_rsvmap(struct buf *b, size_t hdr, size_t rsvmap) diff --git a/tests/unknown_tags_can_skip.fdtput.test.dtb.1.expect b/tests/u= nknown_tags_can_skip.fdtput.test.dtb.1.expect index 6d750f88..204d3d23 100644 --- a/tests/unknown_tags_can_skip.fdtput.test.dtb.1.expect +++ b/tests/unknown_tags_can_skip.fdtput.test.dtb.1.expect @@ -1,5 +1,5 @@ /dts-v1/; -// version: 18 +// version: 20 // last_comp_version: 16 // last_comp_version_w: 17 =20 diff --git a/tests/unknown_tags_can_skip.wip.test.dtb.1.expect b/tests/unkn= own_tags_can_skip.wip.test.dtb.1.expect index afd8a4af..a3f9307f 100644 --- a/tests/unknown_tags_can_skip.wip.test.dtb.1.expect +++ b/tests/unknown_tags_can_skip.wip.test.dtb.1.expect @@ -1,5 +1,5 @@ /dts-v1/; -// version: 18 +// version: 20 // last_comp_version: 16 // last_comp_version_w: 17 =20 --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 897A3379C37; Wed, 26 Aug 2026 09:50:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737848; cv=none; b=CjtEGRqHOLEhWY/YpK7qq8mGtwOarfeN85VEGPS+6brHzBr81Zja4dao2B3kpFmeteYZminXylqEXkZmAx2uPnvtafuha+VfgnGSF0HBtYEowcicnNgghbsq+cUu62QPW63lgh2NOxa4/udaQrg/WGNITmHA+Eu3fa9B44SFAus= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737848; c=relaxed/simple; bh=4ep8ocahczW0bykc33GnX25WIXJ2QmVQ9umxh6EK9To=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=L2x+MGVB52pqxCNg11Xn3AJIQIaUgJdGlQnGIdcfbcdLyNaekIaOyedZwr9XkC8yt8TOeH4pjdP/a03ad+3+g6qhYokUWFpbygjyFrOHJpvU1geEPluHA6bRMrvjq0RyoqlsI9mV7TrQu2znL0RQ0M1uRyzbZh2aSt/er7lUNrI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=gV5nX8mV; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="gV5nX8mV" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 835544E413BC; Wed, 26 Aug 2026 09:50:39 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 51520604EC; Wed, 26 Aug 2026 09:50:39 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 2F0C011C780F5; Wed, 26 Aug 2026 11:50:37 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737838; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=qdnwEeJ6vZ4qOpnJAMnHCeQdSLTyJM8xTsgm3ZkBt/A=; b=gV5nX8mVLc5xw9iYqRoYxDyAz250a5h9coDJvWZpgDW8e5OZwtFBblOpMeKg1fR9KPAojs H1+EJz8tmn2XLvZSq4XgQkfYwsbks5URMbTlmPzn2YJu/+FykCiqyuCbmjwrfSnDTQdWm+ Xco4Z8dkgW+JvDVThkyiNhY1Y7qqKiluVvTGBkT6n2rLF8Sl/eO2BLgyPSq3liJNPe0UZo qHkt569caTuX39PBZAd7WEyB7Ap02VchWIR+iUNENzfSRc96cz57igjkks20pOiXWAiux5 LG5eytN4POD3MTM9gFg03pSfqGKb1qkW1pqxrGNEhDrvbctmSKJ/UQZE722BeA== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 03/74] fdtdump: Introduce get_structured_tag_data() Date: Wed, 26 Aug 2026 11:48:32 +0200 Message-ID: <20260826094950.1088288-4-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" With structured tag, data len can be encoded in the tag itself (no data, 1 cell data, 2 cells) or with a dedicated cell (varlen) added between the tag and the data. In multiple places, getting the data related to the tag will be needed. In order to avoid code duplication, introduce get_structured_tag_data() which purpose is to get the tag data part and its length based on the tag value. Signed-off-by: Herve Codina --- fdtdump.c | 50 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/fdtdump.c b/fdtdump.c index 20854752..f26d3a89 100644 --- a/fdtdump.c +++ b/fdtdump.c @@ -44,6 +44,33 @@ static const char *tagname(uint32_t tag) #define dumpf(fmt, args...) \ do { if (debug) printf("// " fmt, ## args); } while (0) =20 +static const char *get_structured_tag_data(uint32_t tag, const char *blob, + const char **data, int *data_size) +{ + int sz =3D 0; + + switch (tag & FDT_TAG_DATA_MASK) { + case FDT_TAG_DATA_NONE: + break; + case FDT_TAG_DATA_1CELL: + sz =3D FDT_CELLSIZE; + break; + case FDT_TAG_DATA_2CELLS: + sz =3D 2 * FDT_CELLSIZE; + break; + case FDT_TAG_DATA_VARLEN: + /* Get the length */ + sz =3D fdt32_to_cpu(GET_CELL(blob)); + break; + } + + *data_size =3D sz; + *data =3D sz ? blob : NULL; + + /* Skip the data bytes */ + return PALIGN(blob + sz, 4); +} + static void dump_blob(void *blob, bool debug, int dump_unknown) { uintptr_t blob_off =3D (uintptr_t)blob; @@ -58,7 +85,7 @@ static void dump_blob(void *blob, bool debug, int dump_un= known) uint32_t version =3D fdt32_to_cpu(bph->version); uint32_t totalsize =3D fdt32_to_cpu(bph->totalsize); uint32_t tag; - const char *p, *s, *t; + const char *p, *d, *s, *t; int depth, sz, shift; int i; uint64_t addr, size; @@ -153,21 +180,7 @@ static void dump_blob(void *blob, bool debug, int dump= _unknown) } =20 if ((tag & FDT_TAG_STRUCTURED) && (tag & FDT_TAG_SKIP_SAFE)) { - sz =3D 0; - switch (tag & FDT_TAG_DATA_MASK) { - case FDT_TAG_DATA_NONE: - break; - case FDT_TAG_DATA_1CELL: - sz =3D FDT_CELLSIZE; - break; - case FDT_TAG_DATA_2CELLS: - sz =3D 2 * FDT_CELLSIZE; - break; - case FDT_TAG_DATA_VARLEN: - /* Get the length */ - sz =3D fdt32_to_cpu(GET_CELL(p)); - break; - } + p =3D get_structured_tag_data(tag, p, &d, &sz); =20 if (dump_unknown) { printf("%*s// Unknown tag ignored: 0x%08"PRIx32", data len %d", @@ -175,13 +188,10 @@ static void dump_blob(void *blob, bool debug, int dum= p_unknown) if (dump_unknown > 1 && sz !=3D 0) { printf(" "); for (i =3D 0; i < sz; i++) - printf("%02hhx", *(p + i)); + printf("%02hhx", *(d + i)); } printf("\n"); } - - /* Skip the data bytes */ - p =3D PALIGN(p + sz, 4); continue; } =20 --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E9EBB31D39A; Wed, 26 Aug 2026 09:50:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737849; cv=none; b=p+P08YPc5zZ6y9Iu+oO98cSi6/KqE/i3/3WPnYjqzheTwIwqJIDFufqyT1nxfaWIIaioXXg9ySJvST/soA/M+WFRJtqX01JzRuzEvwwRIBkJJQWjUoEj3IYTBjnvmh0k1X9GK80T4yqpVciHzau1P9OLMYwGwaRHfYJhAuFsNbA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737849; c=relaxed/simple; bh=ijw+VDfKjPKYEIbV6jTzOKaWmbW2Pyfy4qArUDYTNP8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KXCStL71vkQ6+vE4YCB821CoQWfOmF8XZ9NQ4SFWuP/gkdCvrueVPMioy9VqUywePBxfnD8yepVkODDcZ9+b9gpdXoIjSAZvw3tetmtVOpkKtj+s7XtOH3glTQvTJqPNxGr7jE8KFyy28iwX3FDtaMjW6D8RKueIoF3ivVJC6oA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=oOmY3qsR; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="oOmY3qsR" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 267184E413C2; Wed, 26 Aug 2026 09:50:42 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id EF8A4604EC; Wed, 26 Aug 2026 09:50:41 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id E20DF11C7AD52; Wed, 26 Aug 2026 11:50:38 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737841; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=Ef+rb3t4e8AalK99fxj/EVtI1AQNvNk/0pDqAH1wUVw=; b=oOmY3qsRleteSoUB3t6hnU/h/73y2F0L15kii+f5JgTkE2F3WdXM5fErXR/r0NhPt7+HK+ ynfeNFxOX6/WeYjMJrOk3tKxi0IX31nM+5G/YRwVveaMeUhrVMm7VchLBDDY5liubT4OPP Xgc+K1t73qNzlT7wkBPh1oW2WLgZkYnSAbTdpV+Fy4DvvyCMUph08yOipHaPPIA7ZmS2zx lwMCc7ZBHQGoAx9V5vjNW9fad4ucsZcKoyVr62NS7iVGqzLQ3352fVsSQj55AKKOSkRmkG EWcv25mq2X+yCY6KBP77kILx7YBeRt0ccAIR/mCSIik1adKeEY5dhL6VLc6Iww== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 04/74] libfdt: Introduce fdt_get_structured_tag_data() Date: Wed, 26 Aug 2026 11:48:33 +0200 Message-ID: <20260826094950.1088288-5-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" With structured tag, data len can be encoded in the tag itself (no data, 1 cell data, 2 cells) or with a dedicated cell (varlen) added between the tag and the data. In multiple places, getting the data related to the tag will be needed. To avoid code duplication, introduce fdt_get_structured_tag_data() which purpose is to get the tag data part and its length based on the tag value. Signed-off-by: Herve Codina --- libfdt/fdt.c | 80 ++++++++++++++++++++++++++-------------- libfdt/libfdt_internal.h | 3 ++ 2 files changed, 55 insertions(+), 28 deletions(-) diff --git a/libfdt/fdt.c b/libfdt/fdt.c index 506e0dd3..7941632f 100644 --- a/libfdt/fdt.c +++ b/libfdt/fdt.c @@ -167,11 +167,56 @@ const void *fdt_offset_ptr(const void *fdt, int offse= t, unsigned int len) return fdt_offset_ptr_(fdt, offset); } =20 +int fdt_get_structured_tag_data(uint32_t tag, const void *fdt, int offset, + uint32_t *data_len) +{ + int data_offset =3D offset; + uint32_t len =3D 0, sum; + const fdt32_t *lenp; + + if (!(tag & FDT_TAG_STRUCTURED)) + return -FDT_ERR_INTERNAL; + + switch (tag & FDT_TAG_DATA_MASK) { + case FDT_TAG_DATA_NONE: + break; + case FDT_TAG_DATA_1CELL: + len =3D FDT_CELLSIZE; + break; + case FDT_TAG_DATA_2CELLS: + len =3D 2 * FDT_CELLSIZE; + break; + case FDT_TAG_DATA_VARLEN: + /* Get the length */ + lenp =3D fdt_offset_ptr(fdt, offset, sizeof(*lenp)); + if (!can_assume(VALID_DTB) && !lenp) + return -FDT_ERR_BADSTRUCTURE; + len =3D fdt32_to_cpu(*lenp); + + /* Skip the cell encoding the length */ + data_offset +=3D sizeof(*lenp); + + /* Check for the length value */ + sum =3D len + data_offset; + if (!can_assume(VALID_DTB) && + (sum >=3D INT_MAX || sum < (uint32_t) offset)) + return -FDT_ERR_BADSTRUCTURE; + + break; + } + + if (data_len) + *data_len =3D len; + + return data_offset; +} + static uint32_t fdt_next_tag_all(const void *fdt, int startoffset, int *ne= xtoffset) { const fdt32_t *tagp, *lenp; uint32_t tag, len, sum; int offset =3D startoffset; + int tmp_offset; const char *p; =20 *nextoffset =3D -FDT_ERR_TRUNCATED; @@ -221,34 +266,13 @@ static uint32_t fdt_next_tag_all(const void *fdt, int= startoffset, int *nextoffs if (!(tag & FDT_TAG_STRUCTURED) || !(tag & FDT_TAG_SKIP_SAFE)) return FDT_END; =20 - switch (tag & FDT_TAG_DATA_MASK) { - case FDT_TAG_DATA_NONE: - break; - case FDT_TAG_DATA_1CELL: - offset +=3D FDT_CELLSIZE; - break; - case FDT_TAG_DATA_2CELLS: - offset +=3D 2 * FDT_CELLSIZE; - break; - case FDT_TAG_DATA_VARLEN: - /* Get the length */ - lenp =3D fdt_offset_ptr(fdt, offset, sizeof(*lenp)); - if (!can_assume(VALID_DTB) && !lenp) - return FDT_END; /* premature end */ - len =3D fdt32_to_cpu(*lenp); - /* - * Skip the cell encoding the length and the - * following length bytes - */ - len +=3D sizeof(*lenp); - sum =3D len + offset; - if (!can_assume(VALID_DTB) && - (sum >=3D INT_MAX || sum < (uint32_t) offset)) - return FDT_END; /* premature end */ - - offset +=3D len; - break; - } + tmp_offset =3D fdt_get_structured_tag_data(tag, fdt, offset, &len); + if (tmp_offset < 0) + return FDT_END; /* premature end */ + + /* Skip the whole data bloc */ + offset =3D tmp_offset + len; + break; } =20 if (!fdt_offset_ptr(fdt, startoffset, offset - startoffset)) diff --git a/libfdt/libfdt_internal.h b/libfdt/libfdt_internal.h index ce128fda..d4154119 100644 --- a/libfdt/libfdt_internal.h +++ b/libfdt/libfdt_internal.h @@ -23,6 +23,9 @@ int32_t fdt_ro_probe_(const void *fdt); uint32_t fdt_next_tag_(const void *fdt, int startoffset, int *nextoffset, bool *is_unknown); =20 +int fdt_get_structured_tag_data(uint32_t tag, const void *fdt, int offset, + uint32_t *data_len); + int fdt_check_node_offset_(const void *fdt, int offset); int fdt_check_prop_offset_(const void *fdt, int offset); =20 --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 50A683BFAF7; Wed, 26 Aug 2026 09:50:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737852; cv=none; b=Xq6CZqGDwIr80xSdeT66U02gPq1F28elwupnkCf8T8TNywIsFbpypwH2rZkfz0FWSfzydbBRh47t9lExf/t9RtqXKO5k76yeAC0l3swyDImu6CM7M/7EI8b+akOxj9Ryva8/5e3l+ELePLc62ZhMwKHmyP6CB58GBY7DipoyJaw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737852; c=relaxed/simple; bh=5Gxcw4rep+TXz2WVH77ceRmT6PRWg8TLiOnUDvMzg+M=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=OkBEML1CbSAm7m2CBiqEW0J57trz6EET1XhyfYHCTiN7LZmYz5guL2DDeCnbgWoAdwXp8KxERL1lKwVdBoleqpIIotpy/3rvUjQuyC30b4Jys66CDgFzDoQWjB8f9S+pj4ljyFMiYm5e6+oXg3ksVFFlggbiYQ0s/BsN/XjknCA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=FPij+mON; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="FPij+mON" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 3E7E81A1840; Wed, 26 Aug 2026 09:50:44 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 12E8B604EC; Wed, 26 Aug 2026 09:50:44 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id A654811C7AD57; Wed, 26 Aug 2026 11:50:41 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737843; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=2Mh4nOQ6ZnAJl7S7+DsN1StmummKBipg0KObR3fPfSE=; b=FPij+mONcmwnhDJz8SZqSQUPYvejdi/UCwdEFNkiIZq90Ay338vMMLzmn6st7K1a2ocVMX PcR8aErMy2dlfpw8bq86QnBu0H2bfPIfAvVKAmXPZRK4nirO7pldJi/X9c9hbsIVMIElbS EPNXz2bBOOWo1RE4vArNZyluQ4dCGP2qIRPheXOzIS2gWMn/D/8ODiZPoQ1GA8wBnrdOvZ UTG+xBC3Z+SjeVd3TjaMOw8DTAhjCtGBAzCHWf6ORlJphKuJ3rqCYlZP22iilCYSCS7tB5 BOb4yFcyOrKpukP8Tim7ui67+hqwcVnUvs5sH9ar1ieWGujZB8YTKP9iY2zgow== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 05/74] libfdt: Prepare for metadata tag support Date: Wed, 26 Aug 2026 11:48:34 +0200 Message-ID: <20260826094950.1088288-6-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" Metadata tags are tags carrying extra information, either global to the DTB, specific to a node, or specific to a property. In several places (e.g. node/property iterators), these tags just need to be skipped. Introduce fdt_next_tag_filter() which wraps fdt_next_tag() and uses a user-supplied filter function to decide whether a tag should be hidden from the caller. Filtered-out tags are returned as FDT_NOP. Introduce fdt_tag_filter_skip_metadata() a filter function whose purpose is to filter metadata tags; actual metadata tag filtering will be added when metadata tags are defined. Metadata tags must also be handled when a DTB is modified. They have to be removed or skipped depending on the modification. Here also, introduce fdt_tag_is_property_metadata() to provide a central check for whether a tag is a property metadata tag; actual metadata check will be added when metadata tags are defined. Signed-off-by: Herve Codina --- libfdt/fdt.c | 34 +++++++++++++-- libfdt/fdt_ro.c | 3 +- libfdt/fdt_rw.c | 90 +++++++++++++++++++++++++++++++++------- libfdt/fdt_wip.c | 23 +++++++++- libfdt/libfdt_internal.h | 10 +++++ 5 files changed, 140 insertions(+), 20 deletions(-) diff --git a/libfdt/fdt.c b/libfdt/fdt.c index 7941632f..8c026f26 100644 --- a/libfdt/fdt.c +++ b/libfdt/fdt.c @@ -323,6 +323,33 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset= , int *nextoffset) return fdt_next_tag_(fdt, startoffset, nextoffset, NULL); } =20 +uint32_t fdt_next_tag_filter(const void *fdt, int offset, int *nextoffset, + bool (*tag_filter)(void *priv, uint32_t tag), + void *priv) +{ + int startoffset =3D offset; + uint32_t tag; + + tag =3D fdt_next_tag_(fdt, startoffset, nextoffset, NULL); + if (tag =3D=3D FDT_END) + return tag; + + if (tag_filter(priv, tag)) + return FDT_NOP; + + return tag; +} + +bool fdt_tag_filter_skip_metadata(void *data, uint32_t tag) +{ + return false; +} + +bool fdt_tag_is_property_metadata(uint32_t tag) +{ + return false; +} + int fdt_check_node_offset_(const void *fdt, int offset) { if (!can_assume(VALID_INPUT) @@ -355,7 +382,8 @@ int fdt_root_offset(const void *fdt) =20 do { offset =3D nextoffset; - tag =3D fdt_next_tag(fdt, offset, &nextoffset); + tag =3D fdt_next_tag_filter(fdt, offset, &nextoffset, + fdt_tag_filter_skip_metadata, NULL); switch (tag) { case FDT_END_NODE: case FDT_PROP: @@ -393,8 +421,8 @@ int fdt_next_node(const void *fdt, int offset, int *dep= th) =20 do { offset =3D nextoffset; - tag =3D fdt_next_tag(fdt, offset, &nextoffset); - + tag =3D fdt_next_tag_filter(fdt, offset, &nextoffset, + fdt_tag_filter_skip_metadata, NULL); switch (tag) { case FDT_PROP: case FDT_NOP: diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c index 50c0a8bc..ea6a540d 100644 --- a/libfdt/fdt_ro.c +++ b/libfdt/fdt_ro.c @@ -206,7 +206,8 @@ static int nextprop_(const void *fdt, int offset) int nextoffset; =20 do { - tag =3D fdt_next_tag(fdt, offset, &nextoffset); + tag =3D fdt_next_tag_filter(fdt, offset, &nextoffset, + fdt_tag_filter_skip_metadata, NULL); =20 switch (tag) { case FDT_END: diff --git a/libfdt/fdt_rw.c b/libfdt/fdt_rw.c index 1c6ce0a3..30f3da40 100644 --- a/libfdt/fdt_rw.c +++ b/libfdt/fdt_rw.c @@ -259,6 +259,42 @@ int fdt_prop_remove_unknown_tags(void *fdt, bool force= _inplace, return 0; } =20 +int fdt_prop_remove_metadata_tags(void *fdt, bool force_inplace, + int prop_offset) +{ + int nextoffset, offset; + uint32_t tag; + + /* + * Only inplace using nopify is supported even if we could use an other + * method involving splices if force_inplace is set to false. + */ + + tag =3D fdt_next_tag(fdt, prop_offset, &nextoffset); + if (tag =3D=3D FDT_END) + return nextoffset; + + /* + * Look at all tags related to the current property. I.e. tags after the + * current property and before either the next property, a sub-node or + * the end of current node + */ + do { + offset =3D nextoffset; + tag =3D fdt_next_tag(fdt, offset, &nextoffset); + if (tag =3D=3D FDT_END) + return nextoffset; + + /* Remove metadata tags related to the property */ + if (fdt_tag_is_property_metadata(tag)) + fdt_nopify_area(fdt, offset, nextoffset); + + } while ((tag !=3D FDT_PROP) && (tag !=3D FDT_BEGIN_NODE) && + (tag !=3D FDT_END_NODE)); + + return 0; +} + static int fdt_resize_property_(void *fdt, int nodeoffset, const char *name, int namelen, int len, struct fdt_property **prop) @@ -273,10 +309,18 @@ static int fdt_resize_property_(void *fdt, int nodeof= fset, return oldlen; =20 /* - * The property is resized. Remove possible unknown tags related to the - * property downgrading the dtb version. + * The property is resized and data are going to be modified. Remove + * property metadata tags */ prop_offset =3D fdt_ptr_offset_(fdt, *prop); + err =3D fdt_prop_remove_metadata_tags(fdt, false, prop_offset); + if (err) + return err; + + /* + * Remove also possible unknown tags related to the property downgrading + * the dtb version. + */ err =3D fdt_prop_remove_unknown_tags(fdt, false, prop_offset, true); if (err) return err; @@ -289,7 +333,7 @@ static int fdt_resize_property_(void *fdt, int nodeoffs= et, return 0; } =20 -static int fdt_node_skip_unknown_tags(void *fdt, int next) +static int fdt_node_skip_unknown_and_metadata_tags(void *fdt, int next) { int nextoffset =3D next; int offset; @@ -299,6 +343,7 @@ static int fdt_node_skip_unknown_tags(void *fdt, int ne= xt) * Skip all tags related to the current node. I.e. tags after the * current node and before either the next property, a sub-node or the * end of current node. + * FDT_NOP, unknown tags and potential node metadata tags are skipped. */ do { offset =3D nextoffset; @@ -332,10 +377,10 @@ static int fdt_add_property_(void *fdt, int nodeoffse= t, const char *name, =20 /* * nextoffset it at the first tag after the node. - * Skip possible unknown tags related to the node in order to add the - * property after those tags. + * Skip possible unknown tags and metadata tags related to the node in + * order to add the property after those tags. */ - nextoffset =3D fdt_node_skip_unknown_tags(fdt, nextoffset); + nextoffset =3D fdt_node_skip_unknown_and_metadata_tags(fdt, nextoffset); if (nextoffset < 0) return nextoffset; =20 @@ -453,6 +498,12 @@ int fdt_appendprop(void *fdt, int nodeoffset, const ch= ar *name, if (err) return err; =20 + /* + * We append data to the property. If known metadata tags are + * present, they are related to existing data and not impacted + * by data added. No need to remove them. + */ + newlen =3D len + oldlen; err =3D fdt_splice_struct_(fdt, prop->data, FDT_TAGALIGN(oldlen), @@ -484,11 +535,16 @@ int fdt_delprop(void *fdt, int nodeoffset, const char= *name) if (!prop) return len; =20 + /* The property is going to be removed. Remove its metadata tags */ + prop_offset =3D fdt_ptr_offset_(fdt, prop); + err =3D fdt_prop_remove_metadata_tags(fdt, false, prop_offset); + if (err) + return err; + /* - * The property is going to be removed. Remove also possible unknown - * tags related to this property. Keep the dtb version unchanged. + * Remove also possible unknown tags related to this property. + * Keep the dtb version unchanged. */ - prop_offset =3D fdt_ptr_offset_(fdt, prop); err =3D fdt_prop_remove_unknown_tags(fdt, false, prop_offset, false); if (err) return err; @@ -522,10 +578,15 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffs= et, return offset; =20 /* - * Try to place the new node after the parent's properties and unknown - * tags related to those properties. - * Unknown tags are reported as FDT_NOP tags by fdt_next_tag. - * Skipping FDT_NOP tags will correctly skip unknown tags. + * Try to place the new node after: + * - the parent's properties + * - the metadata tags related to those properties + * - unknown tags related to those properties. + * Unknown tags are reported as FDT_NOP tags by fdt_next_tag_filter. + * metadata tags are also reported as FDT_NOP by fdt_next_tag_filter + * thanks to the filter function used. + * Skipping FDT_NOP tags will correctly skip unknown tags and metadata + * tags. */ tag =3D fdt_next_tag(fdt, parentoffset, &nextoffset); /* the fdt_subnode_offset_namelen() should ensure this never hits */ @@ -533,7 +594,8 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset, return -FDT_ERR_INTERNAL; do { offset =3D nextoffset; - tag =3D fdt_next_tag(fdt, offset, &nextoffset); + tag =3D fdt_next_tag_filter(fdt, offset, &nextoffset, + fdt_tag_filter_skip_metadata, NULL); } while ((tag =3D=3D FDT_PROP) || (tag =3D=3D FDT_NOP)); =20 nh =3D fdt_offset_ptr_w_(fdt, offset); diff --git a/libfdt/fdt_wip.c b/libfdt/fdt_wip.c index 7ca3ffbc..b2f9f8d1 100644 --- a/libfdt/fdt_wip.c +++ b/libfdt/fdt_wip.c @@ -31,6 +31,17 @@ int fdt_setprop_inplace_namelen_partial(void *fdt, int n= odeoffset, if ((unsigned)proplen < (len + idx)) return -FDT_ERR_NOSPACE; =20 + if (idx < (unsigned)proplen) { + /* + * The property existing data are going to be modified. + * The property metadata tags are related to the property + * data. Remove them. + */ + err =3D fdt_prop_remove_metadata_tags(fdt, true, prop_offset); + if (err) + return err; + } + /* * Remove unknown tags related to the property downgrading the dtb * version. @@ -81,10 +92,18 @@ int fdt_nop_property(void *fdt, int nodeoffset, const c= har *name) return len; =20 /* - * The property is going to be removed (nopified). Remove unknown tags - * related to this property. Keep the dtb version unchanged. + * The property is going to be removed (nopified). Remove its metadata + * tags */ prop_offset =3D fdt_ptr_offset_(fdt, prop); + err =3D fdt_prop_remove_metadata_tags(fdt, true, prop_offset); + if (err) + return err; + + /* + * Remove also possible unknown tags related to this property. + * Keep the dtb version unchanged. + */ err =3D fdt_prop_remove_unknown_tags(fdt, true, prop_offset, false); if (err) return err; diff --git a/libfdt/libfdt_internal.h b/libfdt/libfdt_internal.h index d4154119..47dfc0d4 100644 --- a/libfdt/libfdt_internal.h +++ b/libfdt/libfdt_internal.h @@ -23,6 +23,14 @@ int32_t fdt_ro_probe_(const void *fdt); uint32_t fdt_next_tag_(const void *fdt, int startoffset, int *nextoffset, bool *is_unknown); =20 +uint32_t fdt_next_tag_filter(const void *fdt, int offset, int *nextoffset, + bool (*tag_filter)(void *priv, uint32_t tag), + void *priv); + +bool fdt_tag_filter_skip_metadata(void *data, uint32_t tag); + +bool fdt_tag_is_property_metadata(uint32_t tag); + int fdt_get_structured_tag_data(uint32_t tag, const void *fdt, int offset, uint32_t *data_len); =20 @@ -31,6 +39,8 @@ int fdt_check_prop_offset_(const void *fdt, int offset); =20 int fdt_prop_remove_unknown_tags(void *fdt, bool force_inplace, int prop_offset, bool downgrade_version); +int fdt_prop_remove_metadata_tags(void *fdt, bool force_inplace, + int prop_offset); =20 int fdt_getprop_offset_namelen(const void *fdt, int nodeoffset, const char *name, int namelen); --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E97813BFAF5; Wed, 26 Aug 2026 09:50:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737856; cv=none; b=Yc18PWQdTOzWg9qaejPJufbzCwOUSfjR9tfqs8AKnxHmrZ1PUMXIpZEpcT8H5U8kzOHkIPQYtD9pc5y14LQcpscE1AkUwE8nKb51cCYTSXyPPWvIk+Rt2HWCii6gjKeyFqj0Ft7qOnfXNAP7MA2xRqyy/gz9nobWyO07AHWyTbE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737856; c=relaxed/simple; bh=qGKkETYE0KCtR8h7Xqu60SUvNStWxJJUyP48j2JQ9NA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MAOExZhEu3uTBxqwDjjw6AfXSCR5IPkRAEusZvZyUmW3La9we1v0BJ1C9yCFSjwsJ58dMDWfv0rb5YUC/eGWKgjv3I36OjqFuwSf+Yn5N6sEauqjwcAEtu8Gbektw3f31W7js4o8X7uWg9LPO0g3aDiDEpVl/Xkje/Mwv3ZATaY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=o8NGR1+P; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="o8NGR1+P" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 8EE4D1A183A; Wed, 26 Aug 2026 09:50:46 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 62F9A604EC; Wed, 26 Aug 2026 09:50:46 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id B52D411C7AD56; Wed, 26 Aug 2026 11:50:43 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737845; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=EF95EYAVIjXmPQPZnHstkIoY4jBFJn736uZMQeOgu/8=; b=o8NGR1+P4JNx1JgmTXcQLxzKXGI8Wuhc8bau6xxHlNJWN29xL7BuZmdd8cBLvkLcXAkdmj 9eooepU7ellJnz5OiDPjqXSDX8XaEC3PmJIQEdCAZgu7kajeAMo7I47kFWW3rvnD+qghU1 ip7MunPL8/+4HVkiDHRrk5EzxWc7aIb6fFYoajEkYuSb1MKtwUuYfoiIVyeHqe+5HXX9KA NJ2aC4K3/hrjsZ2RiE7+XImQVv+uH0OGxYiRsgaMhJ6ZRKORFSKI/juFn1PWxeVmHQ8F2E 91WJuyiijYqZ2XRzsrQRKPQg92sVl6zW+PH6jpL0TNR7/hdQbtNARm9jvpL0NA== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 06/74] dtc: Move fill_fullpaths() into build_dt_info() Date: Wed, 26 Aug 2026 11:48:35 +0200 Message-ID: <20260826094950.1088288-7-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" fill_fullpaths() is called unconditionally after parsing to set the full path of each node in the parsed device tree. There is no reason to call it outside build_dt_info(). Furthermore, future metadata support will need post-parsing operations in build_dt_info() to produce a fully consistent dt_info. Those future operations will need the full paths filled by fill_fullpaths(). Move the fill_fullpaths() call into build_dt_info() in preparation. No functional change expected. Signed-off-by: Herve Codina --- dtc.c | 19 ------------------- livetree.c | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/dtc.c b/dtc.c index 6dae60de..e5068375 100644 --- a/dtc.c +++ b/dtc.c @@ -28,23 +28,6 @@ static int is_power_of_2(int x) return (x > 0) && ((x & (x - 1)) =3D=3D 0); } =20 -static void fill_fullpaths(struct node *tree, const char *prefix) -{ - struct node *child; - const char *unit; - - tree->fullpath =3D join_path(prefix, tree->name); - - unit =3D strchr(tree->name, '@'); - if (unit) - tree->basenamelen =3D unit - tree->name; - else - tree->basenamelen =3D strlen(tree->name); - - for_each_child(tree, child) - fill_fullpaths(child, tree->fullpath); -} - /* Usage related data. */ static const char usage_synopsis[] =3D "dtc [options] "; static const char usage_short_opts[] =3D "qI:O:o:V:d:R:S:p:a:fb:i:H:sW:E:@= LAThv"; @@ -326,8 +309,6 @@ int main(int argc, char *argv[]) if (cmdline_boot_cpuid !=3D -1) dti->boot_cpuid_phys =3D cmdline_boot_cpuid; =20 - fill_fullpaths(dti->dt, ""); - /* on a plugin, generate by default */ if (dti->dtsflags & DTSF_PLUGIN) { generate_fixups =3D 1; diff --git a/livetree.c b/livetree.c index 8baed1fc..abe73de1 100644 --- a/livetree.c +++ b/livetree.c @@ -448,6 +448,23 @@ struct reserve_info *add_reserve_entry(struct reserve_= info *list, return list; } =20 +static void fill_fullpaths(struct node *tree, const char *prefix) +{ + struct node *child; + const char *unit; + + tree->fullpath =3D join_path(prefix, tree->name); + + unit =3D strchr(tree->name, '@'); + if (unit) + tree->basenamelen =3D unit - tree->name; + else + tree->basenamelen =3D strlen(tree->name); + + for_each_child(tree, child) + fill_fullpaths(child, tree->fullpath); +} + struct dt_info *build_dt_info(unsigned int dtsflags, struct reserve_info *reservelist, struct node *tree, uint32_t boot_cpuid_phys) @@ -460,6 +477,8 @@ struct dt_info *build_dt_info(unsigned int dtsflags, dti->dt =3D tree; dti->boot_cpuid_phys =3D boot_cpuid_phys; =20 + fill_fullpaths(dti->dt, ""); + return dti; } =20 --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1D66C38F950; Wed, 26 Aug 2026 09:50:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737862; cv=none; b=sj9HlKgQWlYX9KCYD2rLDfqSt9Qda5J2h0rFuWnjHEVmnurJ4M7E7nTst7xbSoB7NDk3USGu6u7s06TXZsxQjV7Rh/EWUH+wcxWwCnRobVUzt856M5xN4ZUe2FC72czTMSnf5BYoAI8htGVAFCDWsQWUDDd8TTrWLNl6M7rTykQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737862; c=relaxed/simple; bh=D7xHo4kceGmmFdF/Hb4FSdlIC08QmG4nyyKBF0/fi10=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=rnTRlR7Ppj1D8PavpzsdzoaQNiQggCNaS8egUHY04EF7q6g2vk/mnS1AXqs8EdlO7EOkX5SQ+qoVkdDzvvWo7N1txHF9H4mz3IkKe9AUtGWtQfVIX/jV+jMpFpCYsIZ3leRK+VQnY8af4M4RosvaJBiHyL0LMRcDJMYCKcGZxak= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=uPaM3St+; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="uPaM3St+" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id C703F4E413C3; Wed, 26 Aug 2026 09:50:48 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 95BA5604EC; Wed, 26 Aug 2026 09:50:48 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id ABE3D11C7AD59; Wed, 26 Aug 2026 11:50:45 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737847; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=gzyjoTJJtakEbX8xtJOVm54sOg+W7HCFXvn1pYX5el0=; b=uPaM3St+XGwzsjsxI3pAqpTab4AIJbAtIt7RyuiN8Qw1yStqTuZBX3SMAtEvpbF1eyybBA Nceh/n7fMx7xXqNcbvK73+qlMqBrnF/hFLkCRb5usBhUhnf64A24IjOi9lnvlpkiqXY3WS 7AJOopiVLEzfJ8W1sc4mYJr/W7xFZ5CY0xusU+AgA3mMzWUryTTR8x4gg7WgOyH/C6ROmG XLtlv2wk1nqLUMt7Wwv3WI4O0fr9uEebhZeRMP9tRFaxZu/4i4ob6IKyyE+EroP5A1dXPv Fpykv8CStRGdMfRHvjj+Im/5irpJkYVh1u9o7ZpmzkFWTiP3gtZTcCVkdwyh1g== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 07/74] Add support for FDT_PROPDATA_PHANDLE dtb tag Date: Wed, 26 Aug 2026 11:48:36 +0200 Message-ID: <20260826094950.1088288-8-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" FDT_PROPDATA_PHANDLE dtb tag is a meta-data tag attached to a property. It indicates that the property defined before this tag (FDT_PROP) uses a phandle value and the node related to this phandle value is local (i.e. the node is present in the device-tree blob). It is followed by one value: - offset (32bit): Offset in the property data where the phandle is available. Example: FDT_PROP 0x00000008 xxxxxxxx 0xca 0xfe 0xde 0xca 0x01 0x02 0x03 0x04 FDT_PROPDATA_PHANDLE 0x00000004 This means that at the offset 4 of the property data, the value (0x01020304) is a phandle and the related node is available in the dtb. This is what is encoded in the dtb when the related dts has a property with the value set to <0xcafedeca &foo> with 'foo' a reference to an existing node where the phandle value is 0x01020304. If several local phandles are used in the property data, several FDT_PROPDATA_PHANDLE are present after the FDT_PROP tag. Each of them points with its offset value to the position of one phandle. For instance, if a first property with 8 bytes of data has a phandle value at offset 4 and a second property with 16 bytes of data has phandle values at offset 0 and 8, the following tags sequence is present: FDT_PROP 0x00000008 xxxxxxxx FDT_PROPDATA_PHANDLE 0x00000004 FDT_PROP 0x00000010 xxxxxxxx FDT_PROPDATA_PHANDLE 0x00000000 FDT_PROPDATA_PHANDLE 0x00000008 Add support for this new dtb tag. Suggested-by: David Gibson Link: https://lore.kernel.org/all/aL-2fmYsbexEtpNp@zatzit/ Signed-off-by: Herve Codina --- data.c | 3 ++- dtc.h | 2 ++ fdtdump.c | 15 ++++++++++- flattree.c | 63 ++++++++++++++++++++++++++++++++++++++++++++-- libfdt/fdt.c | 37 ++++++++++++++++++++++++++- libfdt/fdt.h | 11 ++++++++ libfdt/fdt_check.c | 46 ++++++++++++++++++++++++++++++--- libfdt/libfdt.h | 3 ++- treesource.c | 1 + 9 files changed, 171 insertions(+), 10 deletions(-) diff --git a/data.c b/data.c index 5b25aa06..9bae7047 100644 --- a/data.c +++ b/data.c @@ -127,7 +127,7 @@ struct data data_insert_at_marker(struct data d, struct= marker *m, return d; } =20 -static struct data data_append_markers(struct data d, struct marker *m) +struct data data_append_markers(struct data d, struct marker *m) { struct marker **mp =3D &d.markers; =20 @@ -288,6 +288,7 @@ struct marker *alloc_marker(unsigned int offset, enum m= arkertype type, m->type =3D type; m->ref =3D ref; m->next =3D NULL; + m->is_local =3D 0; =20 return m; } diff --git a/dtc.h b/dtc.h index ef3f2682..64eaffde 100644 --- a/dtc.h +++ b/dtc.h @@ -128,6 +128,7 @@ struct marker { enum markertype type; unsigned int offset; char *ref; + bool is_local; struct marker *next; }; =20 @@ -187,6 +188,7 @@ struct data data_insert_data(struct data d, struct mark= er *m, struct data old); struct marker *alloc_marker(unsigned int offset, enum markertype type, char *ref); struct data data_add_marker(struct data d, enum markertype type, char *ref= ); +struct data data_append_markers(struct data d, struct marker *m); =20 bool data_is_one_string(struct data d); =20 diff --git a/fdtdump.c b/fdtdump.c index f26d3a89..4ee9acc3 100644 --- a/fdtdump.c +++ b/fdtdump.c @@ -84,8 +84,9 @@ static void dump_blob(void *blob, bool debug, int dump_un= known) const char *p_strings =3D (const char *)blob + off_str; uint32_t version =3D fdt32_to_cpu(bph->version); uint32_t totalsize =3D fdt32_to_cpu(bph->totalsize); - uint32_t tag; + uint32_t tag, offset; const char *p, *d, *s, *t; + const char *last_prop_name =3D NULL; int depth, sz, shift; int i; uint64_t addr, size; @@ -138,6 +139,7 @@ static void dump_blob(void *blob, bool debug, int dump_= unknown) (uintptr_t)p - blob_off - 4, tag, tagname(tag)); =20 if (tag =3D=3D FDT_BEGIN_NODE) { + last_prop_name =3D NULL; s =3D p; p =3D PALIGN(p + strlen(s) + 1, 4); =20 @@ -151,6 +153,7 @@ static void dump_blob(void *blob, bool debug, int dump_= unknown) } =20 if (tag =3D=3D FDT_END_NODE) { + last_prop_name =3D NULL; depth--; =20 printf("%*s};\n", depth * shift, ""); @@ -176,6 +179,16 @@ static void dump_blob(void *blob, bool debug, int dump= _unknown) printf("%*s%s", depth * shift, "", s); utilfdt_print_data(t, sz); printf(";\n"); + last_prop_name =3D s; + continue; + } + + if (tag =3D=3D FDT_PROPDATA_PHANDLE) { + p =3D get_structured_tag_data(tag, p, &d, &sz); + offset =3D fdt32_to_cpu(GET_CELL(d)); + + printf("%*s// [FDT_PROPDATA_PHANDLE] %s[%"PRIu32"]\n", depth * shift, "= ", + last_prop_name, offset); continue; } =20 diff --git a/flattree.c b/flattree.c index dd451f0c..92d191d5 100644 --- a/flattree.c +++ b/flattree.c @@ -15,6 +15,7 @@ #define FTF_NOPS 0x40 #define FTF_DTFLAGS 0x80 #define FTF_LCVERSW 0x100 +#define FTF_PROPDATA_PHANDLE 0x200 =20 static struct version_info { int version; @@ -38,7 +39,7 @@ static struct version_info { FTF_LCVERSW}, {20, 18, 18, FDT_V20_SIZE, FTF_BOOTCPUID|FTF_STRTABSIZE|FTF_STRUCTSIZE|FTF_NOPS|FTF_DTFLAGS| - FTF_LCVERSW}, + FTF_LCVERSW|FTF_PROPDATA_PHANDLE}, }; =20 struct emitter { @@ -49,6 +50,7 @@ struct emitter { void (*beginnode)(void *, struct label *labels); void (*endnode)(void *, struct label *labels); void (*property)(void *, struct label *labels); + void (*propdata_phandle)(void *); }; =20 static void bin_emit_cell(void *e, cell_t val) @@ -98,6 +100,11 @@ static void bin_emit_property(void *e, struct label *la= bels) bin_emit_cell(e, FDT_PROP); } =20 +static void bin_emit_propdata_phandle(void *e) +{ + bin_emit_cell(e, FDT_PROPDATA_PHANDLE); +} + static struct emitter bin_emitter =3D { .cell =3D bin_emit_cell, .string =3D bin_emit_string, @@ -106,6 +113,7 @@ static struct emitter bin_emitter =3D { .beginnode =3D bin_emit_beginnode, .endnode =3D bin_emit_endnode, .property =3D bin_emit_property, + .propdata_phandle =3D bin_emit_propdata_phandle, }; =20 static void emit_label(FILE *f, const char *prefix, const char *label) @@ -217,6 +225,14 @@ static void asm_emit_property(void *e, struct label *l= abels) asm_emit_cell(e, FDT_PROP); } =20 +static void asm_emit_propdata_phandle(void *e) +{ + FILE *f =3D e; + + fprintf(f, "\t/* FDT_PROPDATA_PHANDLE */\n"); + asm_emit_cell(e, FDT_PROPDATA_PHANDLE); +} + static struct emitter asm_emitter =3D { .cell =3D asm_emit_cell, .string =3D asm_emit_string, @@ -225,6 +241,7 @@ static struct emitter asm_emitter =3D { .beginnode =3D asm_emit_beginnode, .endnode =3D asm_emit_endnode, .property =3D asm_emit_property, + .propdata_phandle =3D asm_emit_propdata_phandle, }; =20 static int stringtable_insert(struct data *d, const char *str) @@ -249,6 +266,7 @@ static void flatten_tree(struct node *tree, struct emit= ter *emit, struct property *prop; struct node *child; bool seen_name_prop =3D false; + struct marker *m; =20 if (tree->deleted) return; @@ -279,6 +297,17 @@ static void flatten_tree(struct node *tree, struct emi= tter *emit, =20 emit->data(etarget, prop->val); emit->align(etarget, sizeof(cell_t)); + + if (vi->flags & FTF_PROPDATA_PHANDLE) { + m =3D prop->val.markers; + for_each_marker_of_type(m, REF_PHANDLE) { + if (m->is_local) { + emit->propdata_phandle(etarget); + emit->cell(etarget, m->offset); + continue; + } + } + } } =20 if ((vi->flags & FTF_NAMEPROPS) && !seen_name_prop) { @@ -674,6 +703,7 @@ static uint32_t flat_read_tag(struct inbuf *inb) case FDT_PROP: case FDT_NOP: case FDT_END: + case FDT_PROPDATA_PHANDLE: return tag; default: break; @@ -811,9 +841,11 @@ static struct node *unflatten_tree(struct inbuf *dtbuf, struct inbuf *strbuf, const char *parent_flatname, int flags) { + struct property *prop =3D NULL; struct node *node; const char *flatname; uint32_t val; + uint32_t offset; =20 node =3D build_node(NULL, NULL, NULL); =20 @@ -826,8 +858,8 @@ static struct node *unflatten_tree(struct inbuf *dtbuf, node->name =3D xstrdup(flatname); =20 do { - struct property *prop; struct node *child; + struct marker *m; =20 val =3D flat_read_tag(dtbuf); switch (val) { @@ -840,11 +872,13 @@ static struct node *unflatten_tree(struct inbuf *dtbu= f, break; =20 case FDT_BEGIN_NODE: + prop =3D NULL; child =3D unflatten_tree(dtbuf,strbuf, flatname, flags); add_child(node, child); break; =20 case FDT_END_NODE: + prop =3D NULL; break; =20 case FDT_END: @@ -859,6 +893,28 @@ static struct node *unflatten_tree(struct inbuf *dtbuf, /* Ignore */ break; =20 + case FDT_PROPDATA_PHANDLE: + if (!(flags & FTF_PROPDATA_PHANDLE)) + die("PROPDATA_PHANDLE tag found in flat tree" + " version <20\n"); + + if (!prop) + die("PROPDATA_PHANDLE tag found without a previous PROP tag"); + + offset =3D flat_read_word(dtbuf); + + /* + * A reference to a phandle is present in the property + * Mark the whole property as TYPE_UINT32. + */ + property_add_marker(prop, TYPE_UINT32, 0, NULL); + + /* Mark the offset as a local phandle reference */ + m =3D alloc_marker(offset, REF_PHANDLE, NULL); + m->is_local =3D true; + prop->val =3D data_append_markers(prop->val, m); + break; + default: die("Invalid opcode word %08x in device tree blob\n", val); @@ -981,6 +1037,9 @@ struct dt_info *dt_from_blob(const char *fname) if (version >=3D 18) flags |=3D FTF_DTFLAGS | FTF_LCVERSW; =20 + if (version >=3D 20) + flags |=3D FTF_PROPDATA_PHANDLE; + inbuf_init(&memresvbuf, blob + off_mem_rsvmap, blob + totalsize); inbuf_init(&dtbuf, blob + off_dt, blob + totalsize); diff --git a/libfdt/fdt.c b/libfdt/fdt.c index 8c026f26..3762fbef 100644 --- a/libfdt/fdt.c +++ b/libfdt/fdt.c @@ -213,7 +213,7 @@ int fdt_get_structured_tag_data(uint32_t tag, const voi= d *fdt, int offset, =20 static uint32_t fdt_next_tag_all(const void *fdt, int startoffset, int *ne= xtoffset) { - const fdt32_t *tagp, *lenp; + const fdt32_t *tagp, *lenp, *tmp32p; uint32_t tag, len, sum; int offset =3D startoffset; int tmp_offset; @@ -262,6 +262,25 @@ static uint32_t fdt_next_tag_all(const void *fdt, int = startoffset, int *nextoffs case FDT_NOP: break; =20 + case FDT_PROPDATA_PHANDLE: + tmp_offset =3D fdt_get_structured_tag_data(tag, fdt, offset, &len); + if (tmp_offset < 0) + return FDT_END; /* premature end */ + + sum =3D tmp_offset + len; + + if (!can_assume(VALID_DTB) && len < FDT_CELLSIZE) + return FDT_END; /* premature end */ + + /* Check offset value */ + tmp32p =3D fdt_offset_ptr(fdt, tmp_offset, sizeof(*tmp32p)); + if (!can_assume(VALID_DTB) && !tmp32p) + return FDT_END; /* premature end */ + + /* Skip the whole data bloc */ + offset =3D sum; + break; + default: if (!(tag & FDT_TAG_STRUCTURED) || !(tag & FDT_TAG_SKIP_SAFE)) return FDT_END; @@ -290,6 +309,7 @@ static bool fdt_tag_is_unknown(uint32_t tag) case FDT_PROP: case FDT_NOP: case FDT_END: + case FDT_PROPDATA_PHANDLE: return false; default: break; @@ -342,11 +362,26 @@ uint32_t fdt_next_tag_filter(const void *fdt, int off= set, int *nextoffset, =20 bool fdt_tag_filter_skip_metadata(void *data, uint32_t tag) { + switch (tag) { + case FDT_PROPDATA_PHANDLE: + return true; + + default: + break; + } + return false; } =20 bool fdt_tag_is_property_metadata(uint32_t tag) { + switch (tag) { + case FDT_PROPDATA_PHANDLE: + return true; + default: + break; + } + return false; } =20 diff --git a/libfdt/fdt.h b/libfdt/fdt.h index 7c59fed2..2f681088 100644 --- a/libfdt/fdt.h +++ b/libfdt/fdt.h @@ -84,6 +84,17 @@ struct fdt_property { #define FDT_TEST_VARLEN_CAN_SKIP FDT_TAG_CAN_SKIP(FDT_TAG_DATA_VARLEN, 0) #define FDT_TEST_NONE_NO_SKIP FDT_TAG_NO_SKIP(FDT_TAG_DATA_NONE, 0) =20 +/* + * local phandle tag (meta-data). 1 cell: offset + * + * It indicates that the property defined before this tag (FDT_PROP) uses a + * phandle value and the node related to this phandle value is local (i.e. + * the node is present in the device-tree blob). + * + * offset: Offset in the property data where the phandle is available + */ +#define FDT_PROPDATA_PHANDLE FDT_TAG_CAN_SKIP(FDT_TAG_DATA_1CELL, 0x1000) + #define FDT_V1_SIZE (7*sizeof(fdt32_t)) #define FDT_V2_SIZE (FDT_V1_SIZE + sizeof(fdt32_t)) #define FDT_V3_SIZE (FDT_V2_SIZE + sizeof(fdt32_t)) diff --git a/libfdt/fdt_check.c b/libfdt/fdt_check.c index 2fd5b61d..ac297841 100644 --- a/libfdt/fdt_check.c +++ b/libfdt/fdt_check.c @@ -14,12 +14,15 @@ int fdt_check_full(const void *fdt, size_t bufsize) { int err; int num_memrsv; - int offset, nextoffset =3D 0; + int offset, nextoffset =3D 0, d, tmp; uint32_t tag; unsigned int depth =3D 0; - const void *prop; + const void *prop =3D NULL; const char *propname; + int proplen; bool expect_end =3D false; + const fdt32_t *pfdt32; + uint32_t val; =20 if (can_assume(PERFECT)) return 0; @@ -58,6 +61,7 @@ int fdt_check_full(const void *fdt, size_t bufsize) return 0; =20 case FDT_BEGIN_NODE: + prop =3D NULL; depth++; if (depth > INT_MAX) return -FDT_ERR_BADSTRUCTURE; @@ -77,6 +81,7 @@ int fdt_check_full(const void *fdt, size_t bufsize) break; =20 case FDT_END_NODE: + prop =3D NULL; if (depth =3D=3D 0) return -FDT_ERR_BADSTRUCTURE; depth--; @@ -86,9 +91,42 @@ int fdt_check_full(const void *fdt, size_t bufsize) =20 case FDT_PROP: prop =3D fdt_getprop_by_offset(fdt, offset, &propname, - &err); + &proplen); if (!prop) - return err; + return proplen; + break; + + case FDT_PROPDATA_PHANDLE: + /* Be sure that a property is available before this tag */ + if (!prop) + return -FDT_ERR_BADSTRUCTURE; + + d =3D fdt_get_structured_tag_data(tag, fdt, + offset + FDT_TAGSIZE, NULL); + if (d < 0) + return d; + + /* Retrieve the offset of the phandle in the property */ + pfdt32 =3D fdt_offset_ptr(fdt, d, sizeof(*pfdt32)); + if (!pfdt32) + return -FDT_ERR_BADSTRUCTURE; + tmp =3D fdt32_to_cpu(*pfdt32); + + /* Check this offset */ + if (tmp % sizeof(fdt32_t)) + return -FDT_ERR_BADVALUE; + if ((uint32_t)proplen < tmp + sizeof(fdt32_t)) + return -FDT_ERR_BADSTRUCTURE; + + /* Retrieve the phandle value from the property */ + pfdt32 =3D prop; + pfdt32 +=3D tmp / sizeof(fdt32_t); + val =3D fdt32_ld(pfdt32); + + /* Check the phandle value */ + tmp =3D fdt_node_offset_by_phandle(fdt, val); + if (tmp < 0) + return tmp; break; =20 default: diff --git a/libfdt/libfdt.h b/libfdt/libfdt.h index 5e1e0d06..ee811266 100644 --- a/libfdt/libfdt.h +++ b/libfdt/libfdt.h @@ -150,7 +150,8 @@ static inline void *fdt_offset_ptr_w(void *fdt, int off= set, int checklen) * be set to the offset immediately following the tag. * * returns: - * the tag type (FDT_BEGIN_NODE, FDT_END_NODE, FDT_PROP, FDT_NOP, FDT_END), + * the tag type (FDT_BEGIN_NODE, FDT_END_NODE, FDT_PROP, FDT_NOP, FDT_END + * or any other known tags), * FDT_END, if offset is out of bounds */ uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset); diff --git a/treesource.c b/treesource.c index bf648bf6..0e33e3e1 100644 --- a/treesource.c +++ b/treesource.c @@ -168,6 +168,7 @@ static struct marker **add_marker(struct marker **mi, nm->offset =3D offset; nm->ref =3D ref; nm->next =3D *mi; + nm->is_local =3D 0; *mi =3D nm; =20 return &nm->next; --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AC8DB3C0623; Wed, 26 Aug 2026 09:50:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737862; cv=none; b=oJfhNsS13IKkdkARNVk1ZJtqunfMlJTtzRI8oJEBn8vyWfepHmnSZbeDhPquE8umWyPucJoWbcYa/2b5j93PRdGx1Evyzft88eUjHGeOXaCmkCXEednBPDwEY9F9Sc4nGBil0ZfnGinHLkD3fnlpaBhvFWxQSJcYyN1mJZoFP+U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737862; c=relaxed/simple; bh=RdBFkMecL4wuSKPo/cQyMycG1M2ORqtMZfHz2lQEras=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=B5XxddcfbP5vst6PfTUfcAOP2rbMiHRFlbMHDZIcb7KfcZ8IG3JXRkWUaPuTGqtvndVBPIESXb5m8J/uQVRC/lBC2pIMIKSpGgM8zRaQ/Wv1AuvKi9qnCDKQo0dtWkt3WxmDAdcMQ5ULrbtH+XbH9RAW31YcOODorCHJBROrdhM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=TO4rmgGI; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="TO4rmgGI" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id CD0A04E413BC; Wed, 26 Aug 2026 09:50:54 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 999F3604EC; Wed, 26 Aug 2026 09:50:54 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 3943111C7AD5A; Wed, 26 Aug 2026 11:50:48 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737849; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=zbpn10RhSC4nlm/nIJyNq6oASYUb80vxfi05iGG20Rw=; b=TO4rmgGI2YGv547V0QFMU9Lb/A/DZc/pXe3EZScI6iyFMjlF0spVxShKljrXZoGWaH5C7v ekT5e8Mh0WOU+YM87kTocLgyeIYOL0V/pWi3z80HW+JCmTzDpjtgil8EGITalDAUQgWEgU xDbfYFHyQ58XYNqRRgcGVfV+LSJFcH510D5veHTWGHN1u8LrnfIGTxAhvELkN+V4QG8dVl vgxRGogDMbLoYO6VMM6UBmFmcw/P36e0AD8ojxko4Miit8oCNPwWlcnFGXHINi0ieP949M bseoSBY9EaY1TtqA4C5y+jTXCGxP8V7j+tMCq5ppRklhCBBAEuyCQ4VrbxD8bg== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 08/74] livetree: Improve get_node_by_phandle() Date: Wed, 26 Aug 2026 11:48:37 +0200 Message-ID: <20260826094950.1088288-9-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" get_node_by_phandle() allows to get a node based on its phandle value. It checks the phandle value against value available in internal node structure. This internal phandle value is updated during process_check() and so, get_node_by_phandle() cannot give correct results before the process_check() call. Improve get_node_by_phandle() to look at node phandle properties when the internal phandle value is not valid. This allows to return a correct matching node even if process_check() was not called yet. With the recently introduced FDT_PROPDATA_HANDLE dtb tag, this will be needed to update internal phandle references before the call to process_check(). Indeed, this tag allows to identify phandles and internal references need to be updated based on the phandle value before the process_check() call. Signed-off-by: Herve Codina --- livetree.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/livetree.c b/livetree.c index abe73de1..a9f8c5d2 100644 --- a/livetree.c +++ b/livetree.c @@ -628,16 +628,35 @@ struct node *get_node_by_label(struct node *tree, con= st char *label) return NULL; } =20 +static cell_t get_node_phandle_existing(struct node *node) +{ + struct property *prop; + + if (phandle_is_valid(node->phandle)) + return node->phandle; + + prop =3D get_property(node, "phandle"); + if (!prop) { + prop =3D get_property(node, "linux,phandle"); + if (!prop) + return 0; + } + + return propval_cell(prop); +} + struct node *get_node_by_phandle(struct node *tree, cell_t phandle) { struct node *child, *node; + cell_t tree_phandle; =20 if (!phandle_is_valid(phandle)) { assert(generate_fixups); return NULL; } =20 - if (tree->phandle =3D=3D phandle) { + tree_phandle =3D get_node_phandle_existing(tree); + if (phandle_is_valid(tree_phandle) && tree_phandle =3D=3D phandle) { if (tree->deleted) return NULL; return tree; --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9F1EF3BD638; Wed, 26 Aug 2026 09:51:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737868; cv=none; b=qD3tyEmfyo8oK58jcDnJh2TRib1bj8nIfJyQlfKfbFymJqeN4xCut6CFKL7R/QC6UjG+WcfYkHd323tNimCndTCA3e13HTJbk+kcByygT7EX9tTpmxg5GeizP5Doz8u5iIsdG/f2vAn8kGKicHKGPEGV2rsbLNWIIbBTQj4I7S8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737868; c=relaxed/simple; bh=OSkeY49k2KlTNyWcWpeZ9nLjye2bfNs0OFn7IHaXvDM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=i8SsT2sIh8CCQ+IaQ6r4PkePVFt2sb7sH1Wy+y06UsEqToPZv252r63HLqLeP0dyeWKUhXtSMryUhgiwFcGQZacx606pQgRmUghWJXTLpmYX94MvuJYdPzwS8Dnuw8M0ThDj5jPSwPGAmCuw/tSTT5ZzEh85INNRXfVAiq9TOiQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=iqIQxSwq; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="iqIQxSwq" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 5ED2D1A183A; Wed, 26 Aug 2026 09:51:01 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 2B34E604EC; Wed, 26 Aug 2026 09:51:01 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 2BCEA11C7AD61; Wed, 26 Aug 2026 11:50:54 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737856; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=f6y/P7CZOWm5zA57Sd5S8uAf7L/L4YoA6b7jKbkk6fo=; b=iqIQxSwqV7NKJ075Y7P1WyA+xiljOgqluXP7muLs27LGf+Xw+ukAnEH+CKUtUEgaNJFS2J bpoFqpVZIc06ePOxO5EZeViWDoTEpsgiV9iZaZuBhrzW6tfH4MabIXfnBvQ2jqVfdkninQ AtdQS4ZLYAxiLK3+0BQ+OKphbQe0j2knofsdHnAHX7dkYxt69DLdgtgBYT+FV1eS54gIIt VwBmjTmwU/0epZdgTFM4aIcaX8I6naUCRSIXT9ls1QgK8x7ZAnE7XuXOd/wKJBkuuu4XF3 oX70qqt62mngGZw1+pC06u24gLH7D3hKbGB3KUywENupieOoDA50QN4kx5BYiw== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 09/74] dtc: Complete REF_PHANDLE markers with ref strings and is_local flags Date: Wed, 26 Aug 2026 11:48:38 +0200 Message-ID: <20260826094950.1088288-10-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" REF_PHANDLE markers lack either the ref string or the is_local flag depending on the device-tree input format used. When the marker is created from a dtb blob (via FDT_PROPDATA_PHANDLE), only the raw phandle value is available. When created from dts source, the ref string is present but the is_local flag is not set. Add complete_references() to fill in the missing information. Call the new function from build_dt_info() in order ensure that a dt_info is always fully complete and consistent. Signed-off-by: Herve Codina --- livetree.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/livetree.c b/livetree.c index a9f8c5d2..2ad7fd09 100644 --- a/livetree.c +++ b/livetree.c @@ -465,6 +465,82 @@ static void fill_fullpaths(struct node *tree, const ch= ar *prefix) fill_fullpaths(child, tree->fullpath); } =20 +static void complete_ref_and_is_local(struct dt_info *dti, char **ref, + bool *is_local, cell_t phandle) +{ + struct node *refnode; + + /* + * When created from a dts, the reference is available but the is_local + * flag is not set. + * + * When created from a dtb, the is_local flag is set (and a valid + * phandle value is available) but not the reference. + * + * Complete both ref and is_local based on existing values. + */ + + if (*ref) { + refnode =3D get_node_by_ref(dti->dt, *ref); + if (refnode) + *is_local =3D true; + else + *is_local =3D false; + return; + } + + if (*is_local) { + refnode =3D get_node_by_phandle(dti->dt, phandle); + if (!refnode) + die("Node not found for phandle 0x%"PRIx32"\n", phandle); + + *ref =3D refnode->fullpath; + return; + } + + die("Cannot have a non local reference without a reference\n"); +} + +static void complete_references_internal(struct dt_info *dti, struct node = *node) +{ + struct property *prop; + struct marker *m; + struct node *c; + cell_t phandle; + + /* + * In order to have a complete state, a REF_PHANDLE marker needs to + * have a reference set (either a label or a path) and the is_local + * flag must be also correctly set. + * + * When created from dtb, references are not present in REF_PHANDLE + * markers created from the FDT_PROPDATA_PHANDLE tag. Indeed, only a + * phandle value is available with this tag. + * + * When created from dts, references are available for REF_PHANDLE + * markers but 'is_local' flag is not set. + * + * Completing a REF_PHANDLE marker consists in setting those fields. + */ + for_each_property(node, prop) { + m =3D prop->val.markers; + for_each_marker_of_type(m, REF_PHANDLE) { + phandle =3D propval_cell_n(prop, + m->offset / sizeof(cell_t)); + complete_ref_and_is_local(dti, &m->ref, &m->is_local, + phandle); + } + } + + for_each_child(node, c) + complete_references_internal(dti, c); +} + +static void complete_references(struct dt_info *dti) +{ + complete_references_internal(dti, dti->dt); +} + struct dt_info *build_dt_info(unsigned int dtsflags, struct reserve_info *reservelist, struct node *tree, uint32_t boot_cpuid_phys) @@ -479,6 +555,12 @@ struct dt_info *build_dt_info(unsigned int dtsflags, =20 fill_fullpaths(dti->dt, ""); =20 + /* + * Complete references (REF_PHANDLE). + * Set ref strings and set is_local flags + */ + complete_references(dti); + return dti; } =20 --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C84E43B71C5; Wed, 26 Aug 2026 09:51:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737875; cv=none; b=qxERety+cxnCJ78O2Sk3w/8PwFUY1jq09mS3Xi4Ug7fF20Q7ipxr7z2MPQ2//l/k1FIOCGpUu42Dn+HO5NnRDYACnyetX7+ySHUwCjK3b613UHTJo3/sgVQtUqb4klopqlrl8piI/CMiiP9qRUq2NbazDqVtbajF+UeFfHyDMJo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737875; c=relaxed/simple; bh=romTCpYRkypxj89mWq/yugo3+QK3pQGTsI+OV+8aPkA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=hEeTopC1D7nE+iRvlomBAifeb8CsClavjFtS08x0g7F36eY1wm3wOu/JoEyBDjXBF/wwEoK1oLzlSUK6k5mMOZUh9mkFYJeG/Rz/g3sMyyhFHfiBa9RW4umTJ/eD+vzFBZOwiptVXBKMDs+2r6K7dIXrC73LQByJRmATO+N4bwI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=qwD0vIUl; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="qwD0vIUl" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 5F87D4E413BC; Wed, 26 Aug 2026 09:51:07 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 33339604EC; Wed, 26 Aug 2026 09:51:07 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id B552611C7AD52; Wed, 26 Aug 2026 11:51:00 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737862; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=aqIeN+DRRM4prPj9xxID5A46vQ289Qirfguf0hJ38+s=; b=qwD0vIUlCVjpDJXzLgfeZdQUill+T0KLLGL2sfGy6/9bnL+Ge33RbgAmcMeJf88EQHnCzV 2HL51HbmMRD2yOb9oKChYNnO72jaThW7XrmnXFBgknQrbqveGo6wh5QWO3qWYF1hZoEGim UOfSjMzU+qt62a6TfLrtITZmuz3lIOBfrdGNOPL0oaulyNniHlBCtm1/0W6by9YWZTkLZ+ A9lX8IvOxwNzn87MQOFEXPvn9zU33lqSr8kMHcSLpoM7ma+P2FcV5vJg07Qh1y1j4Tzhwp FLDymWPc0H8HVpvIAeiCfAZcQDGvbAmyFy9eSNNwaPZ47TNWcB8mqUrdduecRQ== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 10/74] tests: Add basic metadata tests Date: Wed, 26 Aug 2026 11:48:39 +0200 Message-ID: <20260826094950.1088288-11-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" This first test is related to local phandle references used in properties (FDT_PROPDATA_PHANDLE dtb tag). The test pattern used is - Generate a dts (xxx.dts.dts) from an input dts - Check this generated dts against expected contents - Generate a dtb (xxx.dtb) from the same input dts - Check this generated dtb against expected contents - Generate a dts (xxx.dtb.dts) from the generated dtb - Check this generated dts against expected contents - Generate a dtb (xxx.dtb.dts.dtb) from the generated dts - Check this generated dtb, expect the same contents as for xxx.dtb Even if only one meta-data feature is currently tested in this tests introduction, use a loop in order to ease future addition consisting in adding new input dts as soon as new meta-data feature are supported. Signed-off-by: Herve Codina --- tests/meson.build | 1 + ...data_propdata_phandle_local.dtb.dts.expect | 23 ++++++++++++++++ ...metadata_propdata_phandle_local.dtb.expect | 20 ++++++++++++++ tests/metadata_propdata_phandle_local.dts | 27 +++++++++++++++++++ ...data_propdata_phandle_local.dts.dts.expect | 23 ++++++++++++++++ tests/run_tests.sh | 25 ++++++++++++++++- 6 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 tests/metadata_propdata_phandle_local.dtb.dts.expect create mode 100644 tests/metadata_propdata_phandle_local.dtb.expect create mode 100644 tests/metadata_propdata_phandle_local.dts create mode 100644 tests/metadata_propdata_phandle_local.dts.dts.expect diff --git a/tests/meson.build b/tests/meson.build index fcc73982..ec24f0af 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -143,6 +143,7 @@ run_test_types =3D [ 'fdtput', 'fdtdump', 'fdtoverlay', + 'metadata', ] run_test_deps =3D [ dtc_tools, treegen_dtb, tests_exe, diff --git a/tests/metadata_propdata_phandle_local.dtb.dts.expect b/tests/m= etadata_propdata_phandle_local.dtb.dts.expect new file mode 100644 index 00000000..076c17ae --- /dev/null +++ b/tests/metadata_propdata_phandle_local.dtb.dts.expect @@ -0,0 +1,23 @@ +/dts-v1/; + +/ { + + node-a { + + subnode-a { + phandle =3D <0x01>; + }; + }; + + node-b { + phandle =3D <0x02>; + }; + + node-c { + }; + + node-d { + ref-subnode-a =3D <&{/node-a/subnode-a}>; + ref-node-b =3D <0x123 0x456 &{/node-b} 0x789>; + }; +}; diff --git a/tests/metadata_propdata_phandle_local.dtb.expect b/tests/metad= ata_propdata_phandle_local.dtb.expect new file mode 100644 index 00000000..c923d2e2 --- /dev/null +++ b/tests/metadata_propdata_phandle_local.dtb.expect @@ -0,0 +1,20 @@ +/dts-v1/; + +/ { + node-a { + subnode-a { + phandle =3D <0x00000001>; + }; + }; + node-b { + phandle =3D <0x00000002>; + }; + node-c { + }; + node-d { + ref-subnode-a =3D <0x00000001>; + // [FDT_PROPDATA_PHANDLE] ref-subnode-a[0] + ref-node-b =3D <0x00000123 0x00000456 0x00000002 0x00000789>; + // [FDT_PROPDATA_PHANDLE] ref-node-b[8] + }; +}; diff --git a/tests/metadata_propdata_phandle_local.dts b/tests/metadata_pro= pdata_phandle_local.dts new file mode 100644 index 00000000..f04d24f9 --- /dev/null +++ b/tests/metadata_propdata_phandle_local.dts @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) +/* + * Copyright (C) 2026 Bootlin + */ + +/dts-v1/; + +/ { + node-a { + subnode_a: subnode-a { + }; + }; + + node_b: node-b { + }; + + node-c { + }; + + node_d: node-d { + ref-subnode-a =3D <&subnode_a>; + }; +}; + +&node_d { + ref-node-b =3D <0x123 0x456 &node_b 0x789>; +}; diff --git a/tests/metadata_propdata_phandle_local.dts.dts.expect b/tests/m= etadata_propdata_phandle_local.dts.dts.expect new file mode 100644 index 00000000..b72b545f --- /dev/null +++ b/tests/metadata_propdata_phandle_local.dts.dts.expect @@ -0,0 +1,23 @@ +/dts-v1/; + +/ { + + node-a { + + subnode_a: subnode-a { + phandle =3D <0x01>; + }; + }; + + node_b: node-b { + phandle =3D <0x02>; + }; + + node-c { + }; + + node_d: node-d { + ref-subnode-a =3D <&subnode_a>; + ref-node-b =3D <0x123 0x456 &node_b 0x789>; + }; +}; diff --git a/tests/run_tests.sh b/tests/run_tests.sh index 42b74e05..8c27b463 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -1239,6 +1239,26 @@ fdtoverlay_tests() { run_wrap_test test "$bd" =3D "$pd" } =20 +metadata_tests() { + for dt in metadata_propdata_phandle_local; do + run_dtc_test -I dts -O dts -o $dt.dts.dts "$SRCDIR/$dt.dts" + base_run_test check_diff $dt.dts.dts "$SRCDIR/$dt.dts.dts.expect" + run_dtc_test -I dts -O dtb -o $dt.dtb "$SRCDIR/$dt.dts" + base_run_test wrap_fdtdump $dt.dtb $dt.dtb.out + # Remove unneeded comments + sed -i '/^\/\/ /d' $dt.dtb.out + base_run_test check_diff $dt.dtb.out "$SRCDIR/$dt.dtb.expect" + run_test check_full $dt.dtb + run_dtc_test -I dtb -O dts -o $dt.dtb.dts $dt.dtb + base_run_test check_diff $dt.dtb.dts "$SRCDIR/$dt.dtb.dts.expect" + run_dtc_test -I dts -O dtb -o $dt.dtb.dts.dtb $dt.dtb.dts + base_run_test wrap_fdtdump $dt.dtb.dts.dtb $dt.dtb.dts.dtb.out + # Remove unneeded comments + sed -i '/^\/\/ /d' $dt.dtb.dts.dtb.out + base_run_test check_diff $dt.dtb.dts.dtb.out "$SRCDIR/$dt.dtb.expect" + done +} + pylibfdt_tests () { run_dtc_test -I dts -O dtb -o test_props.dtb "$SRCDIR/test_props.dts" TMP=3D/tmp/tests.stderr.$$ @@ -1278,7 +1298,7 @@ while getopts "vt:me" ARG ; do done =20 if [ -z "$TESTSETS" ]; then - TESTSETS=3D"libfdt utilfdt dtc dtbs_equal fdtget fdtput fdtdump fdtove= rlay" + TESTSETS=3D"libfdt utilfdt dtc dtbs_equal fdtget fdtput fdtdump fdtove= rlay metadata" =20 # Test pylibfdt if the libfdt Python module is available. if ! $no_python; then @@ -1318,6 +1338,9 @@ for set in $TESTSETS; do "fdtoverlay") fdtoverlay_tests ;; + "metadata") + metadata_tests + ;; esac done =20 --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DD3EA3BE650; Wed, 26 Aug 2026 09:51:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737881; cv=none; b=b0ctt6/ecJ7JEyQezmVzAUhrWv7dopqD9rUxBXOwciQJbPL/EG+s1HC/QsPtIPhfi6MvfxrBytxrktwKxou7MzDXt7sxNQO7v04Wbz5EtnJ7h4m8XNDD46fj6MvSiYGIOpTavEEPFO5DKBytqT+I5yNb3AVmVIeHGOJ+/4heK04= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737881; c=relaxed/simple; bh=8xQx1dcmDpBPqlITQY/JTLwfrdw8dGAx2ZQrD2sD/u8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=AcoJ9AeHRmhwTFFJOQ/Ge30c/MI9Y8h4Jd8mlQze3FH9mFCoDiPgEhBk05uejP/WqTCJZ/5enJvTNDiQKxbM4XD3qmkhJc34NdAJMLORtTZ4PwypJg8LhAyA6LZ6XrNcvie5wMPLi+SoHekIhalJwW7Lb+R6g33C64pBMi5Hx70= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=Pl8LKskT; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="Pl8LKskT" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 2F0134E413BF; Wed, 26 Aug 2026 09:51:10 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id F0A9C604EC; Wed, 26 Aug 2026 09:51:09 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 9394D11C780F5; Wed, 26 Aug 2026 11:51:06 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737869; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=mhdSEBHP6UBurcoeQQmbuoMjV9bmB9BBkPk4XB+lPzQ=; b=Pl8LKskTRCyRmJX6oFNMwhS3JcuCHMyEeuB1lazHY7RjYIUhNE5BydR12hd6xHwmeW/6Z8 rJfVmqtLANLMgLhx+s3PszpfjHgN/JsIDfdgzA8+7U37YwDdjC2/+UY6dtnH0K0x+vykI6 5kbwBxQWN9o1Si9IN4N5wofDnjWtaRzf+PBHE250tCH1Qm3K1ppTet197nBIohnYWylAF3 mnQlmycocO3n0wCbTaD/IMYn2/Vw4aubmP0LZG9Xap5Gc0t0XZwkABf+ESSVU1cU22YI/E J4QssZKmbt+y/KjZQf7b1EzNFAOpTidYh4M3mDUNJ4ANAQIz9aZlWIo+fCZOZA== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 11/74] Add support for FDT_PROPDATA_PHANDLE_REF dtb tag Date: Wed, 26 Aug 2026 11:48:40 +0200 Message-ID: <20260826094950.1088288-12-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" The FDT_PROPDATA_PHANDLE_REF dtb tag is similar to the FDT_PROPDATA_PHANDLE tag except that it identifies a reference to an external phandle. The node referenced by the phandle is not present in the device-tree blob. The FDT_PROPDATA_PHANDLE_REF dtb tag is a meta-data tag attached to a property. It indicates that the property defined before this tag (FDT_PROP) uses a phandle value and the node related to this phandle value is not local node (i.e. the node is not present in the device-tree blob). This tag can be available only in overlay or addon device-tree blobs. The phandle value used in the property has to be resolved when the device-tree blob is applied on top of a base device-tree. The tag is followed by the length of the data part (structured tag), two values and a possible alignment padding: - data part length (32bit): 4 + strlen(label) + 1 - offset (32bit): Offset in the property data where the phandle is available. - label (string including \0): The label to use to resolve the phandle value. - padding: Padding (0x00) added to have the next tag aligned on 32bit. Example: FDT_PROP 0x00000008 xxxxxxxx 0x00 0x01 0x02 0x03 0xff 0xff 0xff 0xff FDT_PROPDATA_PHANDLE_REF 9 0x00000004 "foo1" 0x00 0x00 0x00 This means that at the offset 4 of the property data, the value (0xffffffff) is an unresolved phandle value and the related node is the node referenced by "foo1". This is what is encoded in the dtb when the related dts has a property with the value set to <0x00010203 &foo1> with 'foo1' a reference to an non local node. If several non local phandles are used in the property data, several FDT_PROPDATA_PHANDLE_REF are present after the FDT_PROP tag. Each of them points with its offset value to the position of one phandle. For instance, if a first property with 8 bytes of data has a unresolved phandle value at offset 4 referenced by "foo" and a second property with 16 bytes of data has unresolved phandle values at offset 0 and 8 referenced by "bar" and "baz", the following tags sequence is present: FDT_PROP 0x00000008 xxxxxxxx FDT_PROPDATA_PHANDLE_REF 8 0x00000004 "foo" FDT_PROP 0x00000010 xxxxxxxx FDT_PROPDATA_PHANDLE_REF 8 0x00000000 "bar" FDT_PROPDATA_PHANDLE_REF 8 0x00000008 "baz" Add support for this new dtb tag. Suggested-by: David Gibson Link: https://lore.kernel.org/all/aL-2fmYsbexEtpNp@zatzit/ Signed-off-by: Herve Codina --- fdtdump.c | 10 ++++++ flattree.c | 78 +++++++++++++++++++++++++++++++++++++++++++++- libfdt/fdt.c | 30 ++++++++++++++++++ libfdt/fdt.h | 14 +++++++++ libfdt/fdt_check.c | 34 ++++++++++++++++++++ 5 files changed, 165 insertions(+), 1 deletion(-) diff --git a/fdtdump.c b/fdtdump.c index 4ee9acc3..2acf3210 100644 --- a/fdtdump.c +++ b/fdtdump.c @@ -192,6 +192,16 @@ static void dump_blob(void *blob, bool debug, int dump= _unknown) continue; } =20 + if (tag =3D=3D FDT_PROPDATA_PHANDLE_REF) { + p =3D get_structured_tag_data(tag, p, &d, &sz); + offset =3D fdt32_to_cpu(GET_CELL(d)); + s =3D d; + + printf("%*s// [FDT_PROPDATA_PHANDLE_REF] %s[%"PRIu32"], ref =3D %s\n", + depth * shift, "", last_prop_name, offset, s); + continue; + } + if ((tag & FDT_TAG_STRUCTURED) && (tag & FDT_TAG_SKIP_SAFE)) { p =3D get_structured_tag_data(tag, p, &d, &sz); =20 diff --git a/flattree.c b/flattree.c index 92d191d5..abc50873 100644 --- a/flattree.c +++ b/flattree.c @@ -51,6 +51,7 @@ struct emitter { void (*endnode)(void *, struct label *labels); void (*property)(void *, struct label *labels); void (*propdata_phandle)(void *); + void (*propdata_phandle_ref)(void *); }; =20 static void bin_emit_cell(void *e, cell_t val) @@ -105,6 +106,11 @@ static void bin_emit_propdata_phandle(void *e) bin_emit_cell(e, FDT_PROPDATA_PHANDLE); } =20 +static void bin_emit_propdata_phandle_ref(void *e) +{ + bin_emit_cell(e, FDT_PROPDATA_PHANDLE_REF); +} + static struct emitter bin_emitter =3D { .cell =3D bin_emit_cell, .string =3D bin_emit_string, @@ -114,6 +120,7 @@ static struct emitter bin_emitter =3D { .endnode =3D bin_emit_endnode, .property =3D bin_emit_property, .propdata_phandle =3D bin_emit_propdata_phandle, + .propdata_phandle_ref =3D bin_emit_propdata_phandle_ref, }; =20 static void emit_label(FILE *f, const char *prefix, const char *label) @@ -233,6 +240,14 @@ static void asm_emit_propdata_phandle(void *e) asm_emit_cell(e, FDT_PROPDATA_PHANDLE); } =20 +static void asm_emit_propdata_phandle_ref(void *e) +{ + FILE *f =3D e; + + fprintf(f, "\t/* FDT_PROPDATA_PHANDLE_REF */\n"); + asm_emit_cell(e, FDT_PROPDATA_PHANDLE_REF); +} + static struct emitter asm_emitter =3D { .cell =3D asm_emit_cell, .string =3D asm_emit_string, @@ -242,6 +257,7 @@ static struct emitter asm_emitter =3D { .endnode =3D asm_emit_endnode, .property =3D asm_emit_property, .propdata_phandle =3D asm_emit_propdata_phandle, + .propdata_phandle_ref =3D asm_emit_propdata_phandle_ref, }; =20 static int stringtable_insert(struct data *d, const char *str) @@ -306,6 +322,16 @@ static void flatten_tree(struct node *tree, struct emi= tter *emit, emit->cell(etarget, m->offset); continue; } + + if (m->ref[0] =3D=3D '/') + die("Phandle uses a non local reference by path (%s)\n", + m->ref); + + emit->propdata_phandle_ref(etarget); + emit->cell(etarget, sizeof(cell_t) + strlen(m->ref) + 1); + emit->cell(etarget, m->offset); + emit->string(etarget, m->ref, 0); + emit->align(etarget, sizeof(cell_t)); } } } @@ -626,6 +652,16 @@ static void inbuf_init(struct inbuf *inb, void *base, = void *limit) inb->ptr =3D inb->base; } =20 +static void flat_read_subbuf(struct inbuf *inb, struct inbuf *subbuf, int = len) +{ + if ((inb->ptr + len) > inb->limit) + die("Premature end of data parsing flat device tree\n"); + + inbuf_init(subbuf, inb->ptr, inb->ptr + len); + + inb->ptr +=3D len; +} + static void flat_read_chunk(struct inbuf *inb, void *p, int len) { if ((inb->ptr + len) > inb->limit) @@ -704,6 +740,7 @@ static uint32_t flat_read_tag(struct inbuf *inb) case FDT_NOP: case FDT_END: case FDT_PROPDATA_PHANDLE: + case FDT_PROPDATA_PHANDLE_REF: return tag; default: break; @@ -713,7 +750,7 @@ static uint32_t flat_read_tag(struct inbuf *inb) die("Cannot skip unknown tag 0x%08x\n", tag); } =20 -static const char *flat_read_string(struct inbuf *inb) +static const char *flat_read_string_norealign(struct inbuf *inb) { int len =3D 0; const char *p =3D inb->ptr; @@ -729,6 +766,15 @@ static const char *flat_read_string(struct inbuf *inb) =20 inb->ptr +=3D len; =20 + return str; +} + +static const char *flat_read_string(struct inbuf *inb) +{ + const char *str; + + str =3D flat_read_string_norealign(inb); + flat_realign(inb, sizeof(uint32_t)); =20 return str; @@ -844,8 +890,11 @@ static struct node *unflatten_tree(struct inbuf *dtbuf, struct property *prop =3D NULL; struct node *node; const char *flatname; + struct inbuf subbuf; uint32_t val; uint32_t offset; + uint32_t len; + const char *str; =20 node =3D build_node(NULL, NULL, NULL); =20 @@ -915,6 +964,33 @@ static struct node *unflatten_tree(struct inbuf *dtbuf, prop->val =3D data_append_markers(prop->val, m); break; =20 + case FDT_PROPDATA_PHANDLE_REF: + if (!(flags & FTF_PROPDATA_PHANDLE)) + die("PROPDATA_PHANDLE_REF tag found in flat tree" + " version <20\n"); + + if (!prop) + die("PROPDATA_PHANDLE_REF tag found without a previous PROP tag"); + + len =3D flat_read_word(dtbuf); + flat_read_subbuf(dtbuf, &subbuf, len); + flat_realign(dtbuf, sizeof(uint32_t)); + + offset =3D flat_read_word(&subbuf); + str =3D flat_read_string_norealign(&subbuf); + + /* + * A reference to a phandle is present in the property + * Mark the whole property as TYPE_UINT32. + */ + property_add_marker(prop, TYPE_UINT32, 0, NULL); + + /* Mark the offset as a external phandle reference */ + m =3D alloc_marker(offset, REF_PHANDLE, xstrdup(str)); + m->is_local =3D false; + prop->val =3D data_append_markers(prop->val, m); + break; + default: die("Invalid opcode word %08x in device tree blob\n", val); diff --git a/libfdt/fdt.c b/libfdt/fdt.c index 3762fbef..d23b886b 100644 --- a/libfdt/fdt.c +++ b/libfdt/fdt.c @@ -281,6 +281,33 @@ static uint32_t fdt_next_tag_all(const void *fdt, int = startoffset, int *nextoffs offset =3D sum; break; =20 + case FDT_PROPDATA_PHANDLE_REF: + tmp_offset =3D fdt_get_structured_tag_data(tag, fdt, offset, &len); + if (tmp_offset < 0) + return FDT_END; /* premature end */ + + sum =3D tmp_offset + len; + + /* Check offset value */ + tmp32p =3D fdt_offset_ptr(fdt, tmp_offset, sizeof(*tmp32p)); + if (!can_assume(VALID_DTB) && !tmp32p) + return FDT_END; /* premature end */ + tmp_offset +=3D sizeof(fdt32_t); + + /* Check ref string */ + do { + p =3D fdt_offset_ptr(fdt, tmp_offset++, 1); + } while (p && (*p !=3D '\0')); + if (!can_assume(VALID_DTB) && !p) + return FDT_END; /* premature end */ + + if (!can_assume(VALID_INPUT) && (uint32_t)tmp_offset > sum) + return FDT_END; /* premature end */ + + /* Skip the whole data bloc */ + offset =3D sum; + break; + default: if (!(tag & FDT_TAG_STRUCTURED) || !(tag & FDT_TAG_SKIP_SAFE)) return FDT_END; @@ -310,6 +337,7 @@ static bool fdt_tag_is_unknown(uint32_t tag) case FDT_NOP: case FDT_END: case FDT_PROPDATA_PHANDLE: + case FDT_PROPDATA_PHANDLE_REF: return false; default: break; @@ -364,6 +392,7 @@ bool fdt_tag_filter_skip_metadata(void *data, uint32_t = tag) { switch (tag) { case FDT_PROPDATA_PHANDLE: + case FDT_PROPDATA_PHANDLE_REF: return true; =20 default: @@ -377,6 +406,7 @@ bool fdt_tag_is_property_metadata(uint32_t tag) { switch (tag) { case FDT_PROPDATA_PHANDLE: + case FDT_PROPDATA_PHANDLE_REF: return true; default: break; diff --git a/libfdt/fdt.h b/libfdt/fdt.h index 2f681088..c151aa2b 100644 --- a/libfdt/fdt.h +++ b/libfdt/fdt.h @@ -95,6 +95,20 @@ struct fdt_property { */ #define FDT_PROPDATA_PHANDLE FDT_TAG_CAN_SKIP(FDT_TAG_DATA_1CELL, 0x1000) =20 +/* + * external phandle tag (meta-data). varlen: offset, string label + * + * It indicates that the property defined before this tag (FDT_PROP) uses a + * phandle value and the node related to this phandle value is not local + * node (i.e. the node is not present in the device-tree blob). The phandle + * value used in the property has to be resolved when the device-tree blob + * is applied on top of a base device-tree. + * + * offset: Offset in the property data where the phandle is available + * label: The label to use to resolve the phandle value + */ +#define FDT_PROPDATA_PHANDLE_REF FDT_TAG_CAN_SKIP(FDT_TAG_DATA_VARLEN, 0x= 1001) + #define FDT_V1_SIZE (7*sizeof(fdt32_t)) #define FDT_V2_SIZE (FDT_V1_SIZE + sizeof(fdt32_t)) #define FDT_V3_SIZE (FDT_V2_SIZE + sizeof(fdt32_t)) diff --git a/libfdt/fdt_check.c b/libfdt/fdt_check.c index ac297841..96dd7dc0 100644 --- a/libfdt/fdt_check.c +++ b/libfdt/fdt_check.c @@ -22,6 +22,7 @@ int fdt_check_full(const void *fdt, size_t bufsize) int proplen; bool expect_end =3D false; const fdt32_t *pfdt32; + const char *str; uint32_t val; =20 if (can_assume(PERFECT)) @@ -129,6 +130,39 @@ int fdt_check_full(const void *fdt, size_t bufsize) return tmp; break; =20 + case FDT_PROPDATA_PHANDLE_REF: + /* Be sure that a property is available before this tag */ + if (!prop) + return -FDT_ERR_BADSTRUCTURE; + + d =3D fdt_get_structured_tag_data(tag, fdt, + offset + FDT_TAGSIZE, NULL); + if (d < 0) + return d; + + /* Retrieve the offset of the phandle in the property */ + pfdt32 =3D fdt_offset_ptr(fdt, d, sizeof(*pfdt32)); + if (!pfdt32) + return -FDT_ERR_BADSTRUCTURE; + tmp =3D fdt32_to_cpu(*pfdt32); + + /* Check this offset */ + if (tmp % sizeof(fdt32_t)) + return -FDT_ERR_BADVALUE; + if ((uint32_t)proplen < tmp + sizeof(fdt32_t)) + return -FDT_ERR_BADSTRUCTURE; + + /* Retrieve the reference */ + d +=3D sizeof(fdt32_t); + str =3D fdt_offset_ptr(fdt, d, 1); + if (!str) + return -FDT_ERR_BADSTRUCTURE; + + /* Check that the reference is not an empty string */ + if (!strlen(str)) + return -FDT_ERR_BADVALUE; + break; + default: return -FDT_ERR_INTERNAL; } --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6BA2C3C4B93; Wed, 26 Aug 2026 09:51:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737881; cv=none; b=UIT6E0opsllzB8RXPbr5hKma+Sm8Zj+JGbr04Awd8cmYGmoHKlB2/weHg3kCJCw22bTupP60cLbgZ6pUHc5aXFiByjVQ0OfuSWJggmZwzcHyNjFka79pmZ7H73LmANtpTx40Qoon1Nd2m57dZEyzqVPOoKVKGOAdpje6VtXQE2w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737881; c=relaxed/simple; bh=uRh2sj/WLKWEXNAEVviKOEzrQ489d4X8/ox//WICEG8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=kqObX2YGad59FQiLjqDR1tR2MgTU/MMjWUq+tRJuQh+te1Lv16LPVyfxFcQ68V5K3NK0HFFaWawKJbKOtBX+WsQiAyBexc/pg7JprFZlTvz9ZB0zcTI72Uaqxtus+6R7+OvmiQKtqxAUhdlu345rX6asSXjkO2nL6eRmZMbDDS8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=bFOwavnT; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="bFOwavnT" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id A7CD04E413C1; Wed, 26 Aug 2026 09:51:12 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 748F1604EC; Wed, 26 Aug 2026 09:51:12 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 5165811C7AD5F; Wed, 26 Aug 2026 11:51:09 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737871; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=2PIbndfDwZB2ksXzfk5pD7iDFCgcIP1Yx+S/ij9EjL0=; b=bFOwavnTo+mPl+u4E5r8EzND0wKiVad9eAOlzPWe2ga91hoaujgly2JsU18vCQ5fs7GaeT RIDBXBIfz1et5UWJa2ujaeazDmOA+N+YoUDV4SU9V4alruWWLvs+hi5FvkM41C0S07p5g0 DOtjZJS3vVzKe61dD+U5Vf09+GJAvtv2QGsSVcw4wfnMRPLI7wsDYJRA3gxnAKq/HUd2jE CcXbwltAtLOlsgvbWH3ic6w7x6VkyQf6YyFT4/2jhI1kqj0UqgvqcP+yA3Qmv/aVjHauJD ikgE4NyjLGwSo6S3gVp6vfpdWLau4xL9sLicajsm2k1TrSWh5VK1Dy5dTGcTCA== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 12/74] tests: metadata: Add external phandle reference tests Date: Wed, 26 Aug 2026 11:48:41 +0200 Message-ID: <20260826094950.1088288-13-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" Add tests related to external phandle references used in properties (FDT_PROPDATA_PHANDLE_REF dtb tag). Signed-off-by: Herve Codina --- ...etadata_propdata_phandle_ref.dtb.dts.expect | 18 ++++++++++++++++++ tests/metadata_propdata_phandle_ref.dtb.expect | 16 ++++++++++++++++ tests/metadata_propdata_phandle_ref.dts | 11 +++++++++++ ...etadata_propdata_phandle_ref.dts.dts.expect | 18 ++++++++++++++++++ tests/run_tests.sh | 2 +- 5 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 tests/metadata_propdata_phandle_ref.dtb.dts.expect create mode 100644 tests/metadata_propdata_phandle_ref.dtb.expect create mode 100644 tests/metadata_propdata_phandle_ref.dts create mode 100644 tests/metadata_propdata_phandle_ref.dts.dts.expect diff --git a/tests/metadata_propdata_phandle_ref.dtb.dts.expect b/tests/met= adata_propdata_phandle_ref.dtb.dts.expect new file mode 100644 index 00000000..61ce943b --- /dev/null +++ b/tests/metadata_propdata_phandle_ref.dtb.dts.expect @@ -0,0 +1,18 @@ +/dts-v1/; +/plugin/; + +/ { + + fragment@0 { + target =3D <&test>; + + __overlay__ { + ref =3D <&node_a>; + }; + }; + + __fixups__ { + test =3D "/fragment@0:target:0"; + node_a =3D "/fragment@0/__overlay__:ref:0"; + }; +}; diff --git a/tests/metadata_propdata_phandle_ref.dtb.expect b/tests/metadat= a_propdata_phandle_ref.dtb.expect new file mode 100644 index 00000000..f79f542d --- /dev/null +++ b/tests/metadata_propdata_phandle_ref.dtb.expect @@ -0,0 +1,16 @@ +/dts-v1/; + +/ { + fragment@0 { + target =3D <0xffffffff>; + // [FDT_PROPDATA_PHANDLE_REF] target[0], ref =3D test + __overlay__ { + ref =3D <0xffffffff>; + // [FDT_PROPDATA_PHANDLE_REF] ref[0], ref =3D node_a + }; + }; + __fixups__ { + test =3D "/fragment@0:target:0"; + node_a =3D "/fragment@0/__overlay__:ref:0"; + }; +}; diff --git a/tests/metadata_propdata_phandle_ref.dts b/tests/metadata_propd= ata_phandle_ref.dts new file mode 100644 index 00000000..b8aa6509 --- /dev/null +++ b/tests/metadata_propdata_phandle_ref.dts @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) +/* + * Copyright (C) 2026 Bootlin + */ + +/dts-v1/; +/plugin/; + +&test { + ref =3D <&node_a>; +}; diff --git a/tests/metadata_propdata_phandle_ref.dts.dts.expect b/tests/met= adata_propdata_phandle_ref.dts.dts.expect new file mode 100644 index 00000000..61ce943b --- /dev/null +++ b/tests/metadata_propdata_phandle_ref.dts.dts.expect @@ -0,0 +1,18 @@ +/dts-v1/; +/plugin/; + +/ { + + fragment@0 { + target =3D <&test>; + + __overlay__ { + ref =3D <&node_a>; + }; + }; + + __fixups__ { + test =3D "/fragment@0:target:0"; + node_a =3D "/fragment@0/__overlay__:ref:0"; + }; +}; diff --git a/tests/run_tests.sh b/tests/run_tests.sh index 8c27b463..f5ea02bf 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -1240,7 +1240,7 @@ fdtoverlay_tests() { } =20 metadata_tests() { - for dt in metadata_propdata_phandle_local; do + for dt in metadata_propdata_phandle_local metadata_propdata_phandle_ref; = do run_dtc_test -I dts -O dts -o $dt.dts.dts "$SRCDIR/$dt.dts" base_run_test check_diff $dt.dts.dts "$SRCDIR/$dt.dts.dts.expect" run_dtc_test -I dts -O dtb -o $dt.dtb "$SRCDIR/$dt.dts" --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DE1A33C09F1; Wed, 26 Aug 2026 09:51:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737882; cv=none; b=Y5aWnmhZIDI5uZC5mtYnzmGBMFzmJ6pzMItJnAupqPYj0c2ZnL0/SBHT/bKZzrXq9A6ZQBEt5B2bcGi3t3J6gZAXaHSjnpX6iKKghdQvFCQel5ujbZkZfwVL3Lmz2OtYz0CLS4YRNkHaEvnzi7Kz/vrkERq/5/PqPfvnetmwpfg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737882; c=relaxed/simple; bh=5Jnp6ycGza3DttBOq1zB8qyIYV+6XCsMJQfRrvSngjA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=sieKuP1I1HgHy1Q727oWy36rl6TZ17sqAhCq5833fY5bg3Qwsalyi6hs1q7IVPa1dUNNakMRoYg8gCF5SN6anJzSg0I/IP+IffkBZZceq1u8cRnWSgsQvJPGoitj3upKA0l0IDS/U6zx0WYtRSpe5yVtAYSM1LJjgXUS+exEIZY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=lEBYK4Iy; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="lEBYK4Iy" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 09E6A1A183D; Wed, 26 Aug 2026 09:51:19 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id D23FC604EC; Wed, 26 Aug 2026 09:51:18 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 3185811C7AD5C; Wed, 26 Aug 2026 11:51:12 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737873; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=Zg4wutgCKtLkDUoNdaHBA97fW+9AdhMaGs/wxn7cDXc=; b=lEBYK4IyRscKrx7ujEWAoFPnvtyJ+wUOn6Vmb45nvZJwAVNad1xxmL9PaEK4xhOvznrzDw Xo1dQWfSCxS0lJfErQqv9a3SxLTa1YQb3rOJrPwckShO8nxOCbNXi6Ui0wAfsCg9sVgAQm Xz86P4/goJ1KfUTz6R8sztg4e06hM5QLcWYc8iCOwPZfVLBYvzrKiSZa6/b8huzS9CFAM3 GF8Sm9rM7lUBkY79CGEx0kyaC36XMKJYUAt+IAh4A7o0OFAIVxEDlupPhzC5GZ6T5ebmAI mzGhn9bjsQHZJL6LDhW6YTJXxf7dKcwrga2IHopymCAmQ9XdltHTnXFeoCBJzA== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 13/74] Add support for /addon/ keyword Date: Wed, 26 Aug 2026 11:48:42 +0200 Message-ID: <20260826094950.1088288-14-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" The dts /addon/ keyword allows to mark a dts as an addon dts. This is similar to /plugin/ used for overlay dts but specific to addon dts. It is also worth noting that a dts tagged with /addon/ will lead to a dtb with the dt_flags set to FDT_FLAG_ADDON (0x1). This allows to identify without any ambiguity an addon dts and an addon dtb. Signed-off-by: Herve Codina --- checks.c | 36 +++++++++++++++++++++++------------- dtc-lexer.l | 5 +++++ dtc-parser.y | 5 +++++ dtc.h | 1 + fdtdump.c | 4 ++++ flattree.c | 15 ++++++++++++--- libfdt/fdt.h | 1 + treesource.c | 6 ++++++ 8 files changed, 57 insertions(+), 16 deletions(-) diff --git a/checks.c b/checks.c index a6037ed0..cb3b4b16 100644 --- a/checks.c +++ b/checks.c @@ -624,7 +624,7 @@ static void fixup_phandle_references(struct check *c, s= truct dt_info *dti, =20 refnode =3D get_node_by_ref(dt, m->ref); if (! refnode) { - if (!(dti->dtsflags & DTSF_PLUGIN)) + if (!(dti->dtsflags & (DTSF_PLUGIN | DTSF_ADDON))) FAIL(c, dti, node, "Reference to non-existent node or " "label \"%s\"\n", m->ref); else /* mark the entry as unresolved */ @@ -726,8 +726,8 @@ static void check_alias_paths(struct check *c, struct d= t_info *dti, continue; } =20 - /* This check does not work for overlays with external paths */ - if (!(dti->dtsflags & DTSF_PLUGIN) && + /* This check does not work for overlays nor addons with external paths = */ + if (!(dti->dtsflags & (DTSF_PLUGIN | DTSF_ADDON)) && (!prop->val.val || !get_node_by_path(dti->dt, prop->val.val))) { FAIL_PROP(c, dti, node, prop, "aliases property is not a valid node (%s= )", prop->val.val); @@ -1425,8 +1425,8 @@ static void check_property_phandle_args(struct check = *c, * entries when each index position has a specific definition. */ if (!phandle_is_valid(phandle)) { - /* Give up if this is an overlay with external references */ - if (dti->dtsflags & DTSF_PLUGIN) + /* Give up if this is an overlay or addon with external references */ + if (dti->dtsflags & (DTSF_PLUGIN | DTSF_ADDON)) break; =20 cellsize =3D 0; @@ -1659,8 +1659,8 @@ static void check_interrupt_map(struct check *c, =20 phandle =3D propval_cell_n(irq_map_prop, cell); if (!phandle_is_valid(phandle)) { - /* Give up if this is an overlay with external references */ - if (!(dti->dtsflags & DTSF_PLUGIN)) + /* Give up if this is an overlay or an addon with external references */ + if (!(dti->dtsflags & (DTSF_PLUGIN | DTSF_ADDON))) FAIL_PROP(c, dti, node, irq_map_prop, "Cell %zu is not a phandle(%d)", cell, phandle); @@ -1728,9 +1728,9 @@ static void check_interrupts_property(struct check *c, if (prop) { phandle =3D propval_cell(prop); if (!phandle_is_valid(phandle)) { - /* Give up if this is an overlay with + /* Give up if this is an overlay with or an addon * external references */ - if (dti->dtsflags & DTSF_PLUGIN) + if (dti->dtsflags & (DTSF_PLUGIN | DTSF_ADDON)) return; FAIL_PROP(c, dti, parent, prop, "Invalid phandle"); continue; @@ -1846,8 +1846,8 @@ static void check_graph_port(struct check *c, struct = dt_info *dti, =20 check_graph_reg(c, dti, node); =20 - /* skip checks below for overlays */ - if (dti->dtsflags & DTSF_PLUGIN) + /* skip checks below for overlays or addons */ + if (dti->dtsflags & (DTSF_PLUGIN | DTSF_ADDON)) return; =20 if (!strprefixeq(node->name, node->basenamelen, "port")) @@ -1888,8 +1888,8 @@ static void check_graph_endpoint(struct check *c, str= uct dt_info *dti, =20 check_graph_reg(c, dti, node); =20 - /* skip checks below for overlays */ - if (dti->dtsflags & DTSF_PLUGIN) + /* skip checks below for overlays or addons */ + if (dti->dtsflags & (DTSF_PLUGIN | DTSF_ADDON)) return; =20 if (!strprefixeq(node->name, node->basenamelen, "endpoint")) @@ -2062,6 +2062,16 @@ void process_checks(bool force, struct dt_info *dti) unsigned int i; int error =3D 0; =20 + if ((dti->dtsflags & (DTSF_ADDON | DTSF_PLUGIN)) =3D=3D (DTSF_ADDON | DTS= F_PLUGIN)) { + /* + * Addons and overlays are mutually exclusive. The same input + * cannot be both. + */ + fprintf(stderr, + "ERROR: Input tree cannot be both an addon and an overlay\n"); + exit(2); + } + for (i =3D 0; i < ARRAY_SIZE(check_table); i++) { struct check *c =3D check_table[i]; =20 diff --git a/dtc-lexer.l b/dtc-lexer.l index 1b129b11..7e9b6796 100644 --- a/dtc-lexer.l +++ b/dtc-lexer.l @@ -108,6 +108,11 @@ static void PRINTF(1, 2) lexical_error(const char *fmt= , ...); return DT_PLUGIN; } =20 +<*>"/addon/" { + DPRINT("Keyword: /addon/\n"); + return DT_ADDON; + } + <*>"/memreserve/" { DPRINT("Keyword: /memreserve/\n"); BEGIN_DEFAULT(); diff --git a/dtc-parser.y b/dtc-parser.y index e47f80d4..2e152b0e 100644 --- a/dtc-parser.y +++ b/dtc-parser.y @@ -53,6 +53,7 @@ static bool is_ref_relative(const char *ref) =20 %token DT_V1 %token DT_PLUGIN +%token DT_ADDON %token DT_MEMRESERVE %token DT_LSHIFT DT_RSHIFT DT_LE DT_GE DT_EQ DT_NE DT_AND DT_OR %token DT_BITS @@ -120,6 +121,10 @@ header: { $$ =3D DTSF_V1 | DTSF_PLUGIN; } + | DT_V1 ';' DT_ADDON ';' + { + $$ =3D DTSF_V1 | DTSF_ADDON; + } ; =20 headers: diff --git a/dtc.h b/dtc.h index 64eaffde..40aab572 100644 --- a/dtc.h +++ b/dtc.h @@ -336,6 +336,7 @@ struct dt_info { /* DTS version flags definitions */ #define DTSF_V1 0x0001 /* /dts-v1/ */ #define DTSF_PLUGIN 0x0002 /* /plugin/ */ +#define DTSF_ADDON 0x0004 /* /addon/ */ =20 struct dt_info *build_dt_info(unsigned int dtsflags, struct reserve_info *reservelist, diff --git a/fdtdump.c b/fdtdump.c index 2acf3210..370db848 100644 --- a/fdtdump.c +++ b/fdtdump.c @@ -120,6 +120,10 @@ static void dump_blob(void *blob, bool debug, int dump= _unknown) printf("// last_comp_version_w:\t%"PRIu32"\n", fdt32_to_cpu(bph->last_comp_version_w)); } + if (version >=3D 18) { + if (fdt32_to_cpu(bph->dt_flags) & FDT_FLAG_ADDON) + printf("/addon/;\n"); + } printf("\n"); =20 for (i =3D 0; ; i++) { diff --git a/flattree.c b/flattree.c index abc50873..004119c4 100644 --- a/flattree.c +++ b/flattree.c @@ -420,6 +420,7 @@ void dt_to_blob(FILE *f, struct dt_info *dti, int versi= on) struct data dtbuf =3D empty_data; struct data strbuf =3D empty_data; struct fdt_header fdt; + uint32_t dt_flags =3D 0; int padlen =3D 0; =20 for (i =3D 0; i < ARRAY_SIZE(version_table); i++) { @@ -429,6 +430,8 @@ void dt_to_blob(FILE *f, struct dt_info *dti, int versi= on) if (!vi) die("Unknown device tree blob version %d\n", version); =20 + dt_flags |=3D dti->dtsflags & DTSF_ADDON ? FDT_FLAG_ADDON : 0; + flatten_tree(dti->dt, &bin_emitter, &dtbuf, &strbuf, vi); bin_emit_cell(&dtbuf, FDT_END); =20 @@ -436,7 +439,7 @@ void dt_to_blob(FILE *f, struct dt_info *dti, int versi= on) =20 /* Make header */ make_fdt_header(&fdt, vi, reservebuf.len, dtbuf.len, strbuf.len, - dti->boot_cpuid_phys, 0); + dti->boot_cpuid_phys, dt_flags); =20 /* * If the user asked for more space than is used, adjust the totalsize. @@ -519,6 +522,7 @@ void dt_to_asm(FILE *f, struct dt_info *dti, int versio= n) struct data strbuf =3D empty_data; struct reserve_info *re; const char *symprefix =3D "dt"; + uint32_t dt_flags =3D 0; =20 for (i =3D 0; i < ARRAY_SIZE(version_table); i++) { if (version_table[i].version =3D=3D version) @@ -527,6 +531,8 @@ void dt_to_asm(FILE *f, struct dt_info *dti, int versio= n) if (!vi) die("Unknown device tree blob version %d\n", version); =20 + dt_flags |=3D dti->dtsflags & DTSF_ADDON ? FDT_FLAG_ADDON : 0; + fprintf(f, "/* autogenerated by dtc, do not edit */\n\n"); =20 emit_label(f, symprefix, "blob_start"); @@ -569,7 +575,7 @@ void dt_to_asm(FILE *f, struct dt_info *dti, int versio= n) =20 if (vi->flags & FTF_DTFLAGS) { fprintf(f, "\t/* dt_flags */\n"); - asm_emit_cell(f, 0); + asm_emit_cell(f, dt_flags); } =20 if (vi->flags & FTF_LCVERSW) { @@ -1113,8 +1119,11 @@ struct dt_info *dt_from_blob(const char *fname) if (version >=3D 18) flags |=3D FTF_DTFLAGS | FTF_LCVERSW; =20 - if (version >=3D 20) + if (version >=3D 20) { flags |=3D FTF_PROPDATA_PHANDLE; + dtsflags |=3D fdt32_to_cpu(fdt->dt_flags) & FDT_FLAG_ADDON ? + DTSF_ADDON : 0; + } =20 inbuf_init(&memresvbuf, blob + off_mem_rsvmap, blob + totalsize); diff --git a/libfdt/fdt.h b/libfdt/fdt.h index c151aa2b..255e9447 100644 --- a/libfdt/fdt.h +++ b/libfdt/fdt.h @@ -52,6 +52,7 @@ struct fdt_property { #endif /* !__ASSEMBLER__ */ =20 #define FDT_MAGIC 0xd00dfeed /* 4: version, 4: total size */ +#define FDT_FLAG_ADDON 0x1 #define FDT_TAGSIZE sizeof(fdt32_t) #define FDT_CELLSIZE sizeof(fdt32_t) =20 diff --git a/treesource.c b/treesource.c index 0e33e3e1..9f6cf92d 100644 --- a/treesource.c +++ b/treesource.c @@ -420,8 +420,14 @@ void dt_to_source(FILE *f, struct dt_info *dti) struct reserve_info *re; =20 fprintf(f, "/dts-v1/;\n"); + /* + * DTSF_PLUGIN and DTSF_ADDON are mutually exclusive. This has been + * already checked. + */ if (dti->dtsflags & DTSF_PLUGIN) fprintf(f, "/plugin/;\n"); + if (dti->dtsflags & DTSF_ADDON) + fprintf(f, "/addon/;\n"); fprintf(f, "\n"); =20 for (re =3D dti->reservelist; re; re =3D re->next) { --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 06C2C3C1097; Wed, 26 Aug 2026 09:51:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737888; cv=none; b=jpP7ST6KV5t1q1RqnYG7TJseBd6mhXjjykQ7rNB5/LNfTbi04Gtip+E4uLelf6Rashnc9lGyIzzZBZ0mNLnmdah9PssRwDm0xkidW3tgMpGDJApMFOmBLsEIr8o2EsgQvxWeMx+lawuaEdKoPfoWzi5WHMraz+Zx6YVvBpGtXrk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737888; c=relaxed/simple; bh=jDRrStbxDEF27i9PKcMF71vSb8ERx1X9Tef6+60YxhU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=q99fMzivw+56a7TO8MSCvuIJ5ak7ih3o0EjcsNnhgx9ZnaAEkk+32ZpzscdUqj+8pVWcRLf6ChpRvAvaCA8tj+CKFx9BG7MFvBNwBz8zbVWwdAsmGZ9EyLg75rG7qXJlc7i3bToY1XEnKQu9r+AgclW5Orb3nkt9A7Aa9JPR3Ho= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=XRECA1N5; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="XRECA1N5" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 60B034E413BC; Wed, 26 Aug 2026 09:51:25 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 350C2604EC; Wed, 26 Aug 2026 09:51:25 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 4B51C11C7AD64; Wed, 26 Aug 2026 11:51:18 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737880; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=pJc3+Rr2qTZdW2JMtEFzukfNaw+Z+ZB2P/aYqtOrOyc=; b=XRECA1N5vfxYBumdHwdv4nOvKiucstVarFuhNX+SjE0W3HX5s0ccSsynfj8/GY8QDn6vU8 QC2SKQvhRSznEiDLE1BUbwCSSW8y3pICqgplpdWH3Cw5Io4pLvASRgdyPSKeXR1ua8neEo vCl4RqucTzsYBJb6rAJHqk16C6klIuT4hL1Uzi3kc28EbxhaL6THbMTMlTNym8M6Yh0cI2 mGOsQbZap5q0sal+8oYRDe6X6McQlBFdgzaBVvFy7mgqwfI9uSzUtg5j6+nkTNB0rRi6k2 N8IY2caaB4jzQdnqiBEyzlUcNw56lnba5br7GCMopLWAK+BLZJSvi+U0kiSdJQ== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 14/74] tests: Add a test related to addon dt_flags header value Date: Wed, 26 Aug 2026 11:48:43 +0200 Message-ID: <20260826094950.1088288-15-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" Addon dtbs leads to the dt_flags header field set to FDT_FLAG_ADDON (0x1). Add a specific test to check this value. Signed-off-by: Herve Codina --- tests/dtflags_addon.dtb.expect | 1 + tests/dtflags_addon.dts | 11 +++++++++++ tests/run_tests.sh | 8 ++++++++ 3 files changed, 20 insertions(+) create mode 100644 tests/dtflags_addon.dtb.expect create mode 100644 tests/dtflags_addon.dts diff --git a/tests/dtflags_addon.dtb.expect b/tests/dtflags_addon.dtb.expect new file mode 100644 index 00000000..00f98f32 --- /dev/null +++ b/tests/dtflags_addon.dtb.expect @@ -0,0 +1 @@ +// dt_flags: 0x1 diff --git a/tests/dtflags_addon.dts b/tests/dtflags_addon.dts new file mode 100644 index 00000000..d2b22951 --- /dev/null +++ b/tests/dtflags_addon.dts @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) +/* + * Copyright (C) 2026 Bootlin + */ + +/dts-v1/; +/addon/; + +/ { + prop =3D <1>; +}; diff --git a/tests/run_tests.sh b/tests/run_tests.sh index f5ea02bf..734fd39a 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -926,6 +926,14 @@ dtc_tests () { sed -i '/dt_flags/!d' dtflags_default.dtb.out base_run_test check_diff dtflags_default.dtb.out "$SRCDIR/dtflags_defa= ult.dtb.expect" run_test check_full dtflags_default.dtb + + # Tests dt_flags header field (FDT_FLAG_ADDON value) + run_dtc_test -I dts -O dtb -o dtflags_addon.dtb "$SRCDIR/dtflags_addon= .dts" + base_run_test wrap_fdtdump dtflags_addon.dtb dtflags_addon.dtb.out + # Keep only lines containing 'dt_flags' + sed -i '/dt_flags/!d' dtflags_addon.dtb.out + base_run_test check_diff dtflags_addon.dtb.out "$SRCDIR/dtflags_addon.= dtb.expect" + run_test check_full dtflags_addon.dtb } =20 cmp_tests () { --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 315B13BFAF2; Wed, 26 Aug 2026 09:51:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737894; cv=none; b=Kiibz3vPHTaxznYG9+pwr2CvlOhYOCWZF9wjP26uznsuohM7toLLOWAWghrp4jRl1ulejztPrZwvTGGs5vac2KcBgEAOrJQ9GtgYXCLNzmx0ioq2/k77hUfwKkPLPh1VbiC+iRWDLDU1qZ4SqHlgARrlOi3kZRJM1MzgpqargkM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737894; c=relaxed/simple; bh=dog13pytRgAm/nmQYDoTN2iPfbsX/zbQwUyECUfSkRQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=oTKZgMJ3C5W9wnJe25XEOwNqLGDaD2uVWXtiXpO8Q9S4PTpDZOIHPRuGpvbtbfdJ6YPA4D/g3U/WncDDm7JCx8cweAKWj+GwvuIP1zcXgW76pkkQmKlo9zKwh8pItJD61ivCUBxuLDxMJwLmElLPOrRF0HsX1IodBlMwF39oNJ8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=a+25KmOa; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="a+25KmOa" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id DC87F4E413BC; Wed, 26 Aug 2026 09:51:31 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id B13CB604EC; Wed, 26 Aug 2026 09:51:31 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id DA6D411C7AD52; Wed, 26 Aug 2026 11:51:24 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737886; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=WDr+ip3jj8bkSnf7P4NMN3NaKedzM/la/t7iz3ZOnUA=; b=a+25KmOaTixpKEe9aVjGUkFooDVM3bilc+RX8eNRmI6R9JAduOdfbYl7M8guHRcBweaS9i wYGkBDhckSHo8q8/Wh+N29HMxRLGfagF+SlU5MVLGEeq6T/C9F6l9RxjqDzKBC0p0bgdOt UQfMY/Ws0z9DYBl+uVZwIGcjxNfuxFdd9AZGyCk5uG0RE3/pZxA+g4CyUH3a9OlTNxh3IU 5ZQ1EANMZ4KEE67Ap52qQp9N8GPpcA1ZGLFQ/r/Q04Hgt4KIvwEOgDHXPqJPawn1hNOqQX 1LT3L++NAJAEQBjmMKWv4dhjwP76uL9/o3g9/ljSrX5b05nXXSpzOwDa4Lqt3g== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 15/74] tests: metadata: Add a basic addon test Date: Wed, 26 Aug 2026 11:48:44 +0200 Message-ID: <20260826094950.1088288-16-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" Support for addon dts (/addon/ keyword) and addon dtb (FDT_FLAG_ADDON header flag) have been recently introduced. Even if the FDT_FLAG_ADDON dtb flag itself has its own test already available, add a basic addon test in the metadata 'dts->dts and dts->dtb->dts' test patterns to check that addon dts/dtb are handled correctly. Signed-off-by: Herve Codina --- tests/metadata_addon_base.dtb.dts.expect | 10 ++++++++++ tests/metadata_addon_base.dtb.expect | 10 ++++++++++ tests/metadata_addon_base.dts | 14 ++++++++++++++ tests/metadata_addon_base.dts.dts.expect | 10 ++++++++++ tests/run_tests.sh | 3 ++- 5 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 tests/metadata_addon_base.dtb.dts.expect create mode 100644 tests/metadata_addon_base.dtb.expect create mode 100644 tests/metadata_addon_base.dts create mode 100644 tests/metadata_addon_base.dts.dts.expect diff --git a/tests/metadata_addon_base.dtb.dts.expect b/tests/metadata_addo= n_base.dtb.dts.expect new file mode 100644 index 00000000..739f9db3 --- /dev/null +++ b/tests/metadata_addon_base.dtb.dts.expect @@ -0,0 +1,10 @@ +/dts-v1/; +/addon/; + +/ { + + node-a { + prop =3D <0x01>; + ref-base =3D <&base>; + }; +}; diff --git a/tests/metadata_addon_base.dtb.expect b/tests/metadata_addon_ba= se.dtb.expect new file mode 100644 index 00000000..27378475 --- /dev/null +++ b/tests/metadata_addon_base.dtb.expect @@ -0,0 +1,10 @@ +/dts-v1/; +/addon/; + +/ { + node-a { + prop =3D <0x00000001>; + ref-base =3D <0xffffffff>; + // [FDT_PROPDATA_PHANDLE_REF] ref-base[0], ref =3D base + }; +}; diff --git a/tests/metadata_addon_base.dts b/tests/metadata_addon_base.dts new file mode 100644 index 00000000..5e29cef9 --- /dev/null +++ b/tests/metadata_addon_base.dts @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) +/* + * Copyright (C) 2026 Bootlin + */ + +/dts-v1/; +/addon/; + +/ { + node-a { + prop =3D <1>; + ref-base =3D <&base>; + }; +}; diff --git a/tests/metadata_addon_base.dts.dts.expect b/tests/metadata_addo= n_base.dts.dts.expect new file mode 100644 index 00000000..739f9db3 --- /dev/null +++ b/tests/metadata_addon_base.dts.dts.expect @@ -0,0 +1,10 @@ +/dts-v1/; +/addon/; + +/ { + + node-a { + prop =3D <0x01>; + ref-base =3D <&base>; + }; +}; diff --git a/tests/run_tests.sh b/tests/run_tests.sh index 734fd39a..f119acc0 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -1248,7 +1248,8 @@ fdtoverlay_tests() { } =20 metadata_tests() { - for dt in metadata_propdata_phandle_local metadata_propdata_phandle_ref; = do + for dt in metadata_propdata_phandle_local metadata_propdata_phandle_ref \ + metadata_addon_base; do run_dtc_test -I dts -O dts -o $dt.dts.dts "$SRCDIR/$dt.dts" base_run_test check_diff $dt.dts.dts "$SRCDIR/$dt.dts.dts.expect" run_dtc_test -I dts -O dtb -o $dt.dtb "$SRCDIR/$dt.dts" --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EA63227144B for ; Wed, 26 Aug 2026 09:51:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737897; cv=none; b=u7NQLeZ1C50Qfixxf/83RuI9+mT7MtTsbiZaT5PmLj8X5s8vqyVoAE93PAi9ZizddY98zcsIeQyDQWQJ3iWR0zQ6cYnJR1wxFFAYvg22bRZCzPU/xWFRWPh0i9TjaFbstft2MQuu5HdmH5B4dw/CnsrRxc97U9spa/bimS7uHyM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737897; c=relaxed/simple; bh=FafxXcWLHkT6mobjaPahraFM56aLYdhtmOWljdhGozI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ay5IxQeSVTgEKN/+ESWD7AFjEyJ0UFb1gPV6DctqDmfz/MFSzmxUvPFI3mOkDH5mEO1KY4eyMd+iXOPvHVP5/eMixI0NNq+rGeY0q6gupAH140fIwrLvd41AYgXtrXLaxEoXC/7ppBWydZ5DK8caV75EaTL3WP0nsULdupADCb0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=uBTEvyDc; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="uBTEvyDc" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 86AA01A183D; Wed, 26 Aug 2026 09:51:34 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 5B10A604EC; Wed, 26 Aug 2026 09:51:34 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 2200411C7AD59; Wed, 26 Aug 2026 11:51:31 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737893; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=0OOERp9GOpR0ilEqw6m/Mc9kXd1+dbUxBx6/f3UWhGg=; b=uBTEvyDcujxONUTlJtUT8l4efpSyeGVEdGJq1BBfMJEezQiadO1ocoOBOWl767C71TMFsR cK4DPIeHb4L9/0CA8OHE9aLKxUrXBrVKRT18472iHThmQw2ol5Vtzx4Tgycv4fLBebNOP4 qYTxikqREgWJhM62IuoBuJGmVHmCiA9TuHR/t6LRadmdgPxtrNfsto4jOfeq3mRg7wqBev SOAjlmn8V5V3hgZY/7nwonXLvsympY8KzRU+/jNI2HTEKxSHGfNghGQwag+prf7aiCbZs9 ynIgsd1fk+VkNNSQdoGy0EwFObPSBP/rnzvkqqHzpKS/E4tXAnbR2qEMatIPcg== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 16/74] dtc: Introduce export symbols Date: Wed, 26 Aug 2026 11:48:45 +0200 Message-ID: <20260826094950.1088288-17-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" Export symbols allow to define a list of symbols exported at a given node level. Those exported symbols can be used by an addon when the addon is applied on the node exporting the symbols. In order to perform its symbol resolution. Any unresolved phandle value will be resolved using those exported symbols. The feature is similar to __symbols__ involved with overlay but while all symbols are visible with __symbols__, only specific symbols (exported symbols) are visible with export symbols. Also an exported symbol has a specific name and this name has to used for symbol resolution. Having both specific exported symbol names and exported symbols at specific node level allow to: - Have several nodes providing the same exported symbols name but each of them pointing to different nodes. Without looking at the detail of the syntax, node-a and node-b export the same symbol foo but pointing to different node. node-a { /* export foo -> /path/foo1 */ }; node-b { /* export foo -> /path/foo2 */ }; This allow to have the exact same addon referencing 'foo' applied either on node-a or node-b. - Have several board describing a well defined node even if resources needed for exported symbols are not the same. On board A, the 'ctrl' exported symbols points to some ctrl device available on the SoC: node { /* export 'ctrl' -> /soc/ctrl@1000 }; On board B, the ctrl device used is on a i2c bus node { /* export 'ctrl' -> /soc/i2c@5000/ctrl@10 }; The addon can be used on board A and board B without any modification. It uses 'ctrl' exported by the node it is applied to. Introduce the 'symbol' internal data structure and the export symbol list related to a node. No functional change yet but preparation for the future support for export symbol parsing. Signed-off-by: Herve Codina --- dtc-parser.y | 6 +++--- dtc.h | 13 ++++++++++++- flattree.c | 2 +- fstree.c | 2 +- livetree.c | 7 ++++--- 5 files changed, 21 insertions(+), 9 deletions(-) diff --git a/dtc-parser.y b/dtc-parser.y index 2e152b0e..9c936736 100644 --- a/dtc-parser.y +++ b/dtc-parser.y @@ -183,7 +183,7 @@ devicetree: else if (is_ref_relative($1)) ERROR(&@2, "Label-relative reference %s not supported in plugin", $1); $$ =3D add_orphan_node( - name_node(build_node(NULL, NULL, NULL), + name_node(build_node(NULL, NULL, NULL, NULL), ""), $2, $1); } @@ -270,11 +270,11 @@ devicetree: nodedef: '{' proplist subnodes '}' ';' { - $$ =3D build_node($2, $3, &@$); + $$ =3D build_node($2, $3, NULL, &@$); } | '{' subnodes '}' ';' { - $$ =3D build_node(NULL, $2, &@$); + $$ =3D build_node(NULL, $2, NULL, &@$); } ; =20 diff --git a/dtc.h b/dtc.h index 40aab572..af69b193 100644 --- a/dtc.h +++ b/dtc.h @@ -204,6 +204,16 @@ struct label { struct label *next; }; =20 +struct symbol { + bool is_local; + char *name; + char *ref; + cell_t phandle; + char *fullpath; + struct symbol *next; + struct srcpos *srcpos; +}; + struct bus_type { const char *name; }; @@ -224,6 +234,7 @@ struct node { char *name; struct property *proplist; struct node *children; + struct symbol *exportsymlist; =20 struct node *parent; struct node *next_sibling; @@ -272,7 +283,7 @@ struct property *chain_property(struct property *first,= struct property *list); struct property *reverse_properties(struct property *first); =20 struct node *build_node(struct property *proplist, struct node *children, - struct srcpos *srcpos); + struct symbol *exportsymlist, struct srcpos *srcpos); struct node *build_node_delete(struct srcpos *srcpos); struct node *name_node(struct node *node, const char *name); struct node *omit_node_if_unused(struct node *node); diff --git a/flattree.c b/flattree.c index 004119c4..ac6bcd8f 100644 --- a/flattree.c +++ b/flattree.c @@ -902,7 +902,7 @@ static struct node *unflatten_tree(struct inbuf *dtbuf, uint32_t len; const char *str; =20 - node =3D build_node(NULL, NULL, NULL); + node =3D build_node(NULL, NULL, NULL, NULL); =20 flatname =3D flat_read_string(dtbuf); =20 diff --git a/fstree.c b/fstree.c index 0f9a534b..445ae53a 100644 --- a/fstree.c +++ b/fstree.c @@ -19,7 +19,7 @@ static struct node *read_fstree(const char *dirname) if (!d) die("Couldn't opendir() \"%s\": %s\n", dirname, strerror(errno)); =20 - tree =3D build_node(NULL, NULL, NULL); + tree =3D build_node(NULL, NULL, NULL, NULL); =20 while ((de =3D readdir(d)) !=3D NULL) { char *tmpname; diff --git a/livetree.c b/livetree.c index 2ad7fd09..a7f81a90 100644 --- a/livetree.c +++ b/livetree.c @@ -86,7 +86,7 @@ struct property *reverse_properties(struct property *firs= t) } =20 struct node *build_node(struct property *proplist, struct node *children, - struct srcpos *srcpos) + struct symbol *exportsymlist, struct srcpos *srcpos) { struct node *new =3D xmalloc(sizeof(*new)); struct node *child; @@ -95,6 +95,7 @@ struct node *build_node(struct property *proplist, struct= node *children, =20 new->proplist =3D reverse_properties(proplist); new->children =3D children; + new->exportsymlist =3D exportsymlist; new->srcpos =3D srcpos_copy(srcpos); =20 for_each_child(new, child) { @@ -248,7 +249,7 @@ struct node * add_orphan_node(struct node *dt, struct n= ode *new_node, char *ref) xasprintf(&name, "fragment@%u", next_orphan_fragment++); name_node(new_node, "__overlay__"); - node =3D build_node(p, new_node, NULL); + node =3D build_node(p, new_node, NULL, NULL); name_node(node, name); free(name); =20 @@ -993,7 +994,7 @@ static struct node *build_and_name_child_node(struct no= de *parent, const char *n { struct node *node; =20 - node =3D build_node(NULL, NULL, NULL); + node =3D build_node(NULL, NULL, NULL, NULL); name_node(node, name); add_child(parent, node); =20 --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A81403D412B; Wed, 26 Aug 2026 09:51:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737900; cv=none; b=Ru+WiwXoC7k51fq5200y6vNm7cGg/7qPP+7TCZwtwRq7V7tg0pM6IpnATtA3Im6YYjuWw/bo9PzwO474hl1NzB/G+mPvAAVurrzx1JiA7HAlWhkYWo1LO2g43YWlhJyAUITQ/rP1wq3rlTLaVr0zoisqffJ/HMnb0YC+GzrfBtc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737900; c=relaxed/simple; bh=UAQUsTLrm4veWIaqOZchnhj4ahTwHItlQ2runn2yaSU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MxE7ATFQHVDO3au4TiJ+uoFErn6LslAO/GPYBWdKNvy1o3CZja27CKqG73Q1JMQaTFYv8GCXs55r3ItJjhpYIWKWOkajWYlKWZJUbLmdDX0n0cTJM9NBWLRJAg2dNp5Hdtrzif0OkbLq14NY0GvnHfdnUDlUu4NDpCCbb6I40i4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=D5lLhyMo; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="D5lLhyMo" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 269B71A183A; Wed, 26 Aug 2026 09:51:37 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id EEAD4604EC; Wed, 26 Aug 2026 09:51:36 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id DD73F11C7AD5A; Wed, 26 Aug 2026 11:51:33 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737896; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=1AeT63QDoUkeqxJcVG6v/Nep9Jf8FTapThZMxMT3Lpc=; b=D5lLhyMoDL+th/W3dqNuAE3J9UR8Csrb+K86FC955Mn9K1WKMTvuLfD3qTjDHGyNCfeZtL LZSv2aZQVRHZ4qebASrBZgj3bLJc44e0jZJKH1//whPj82lbUUpzqO8hB8M2f+61zx5AD+ ON0aSODfCujZDigjIURvo9I2VjXpYiSoFOxQRiVouuSZ51+54bhgNKkyzb7nSO/W8y1FHy N9d7kD5SQa/l8q79A5p8b5UWMmfq0rJlHxOIp5ebfTUpMoHDIAWPoFEIyXmI77oa/4C3BP hU0ecpeCYjLKaxm2QzjkPO/giZV16bn6IZhXe2BVfDC/Ro3PIQsicIu7xzwjbA== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 17/74] dtc: Add support for /export/ dts keyword parsing Date: Wed, 26 Aug 2026 11:48:46 +0200 Message-ID: <20260826094950.1088288-18-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" The /export/ dts keyword is the keyword used to define an exported symbol at a given node level. This keyword can be present in a node definition (after properties and before subnodes) to export a symbol. If several symbols need to be exported, several /export/ keywords are present. The syntax used is the following: /export/ name: reference; with: name: The name of the exported symbol reference: The reference of a node the symbol is pointing to. For instance: - Reference by label: /export/ foo: &foo1; The exported symbol foo references the node identified by the label foo1. - Reference by path: /export/ foo: &{/path/to/foo@100}; The exported symbol foo references the node at /path/to/foo@100. Add support for /export/ dts keyword. Signed-off-by: Herve Codina --- dtc-lexer.l | 6 ++++ dtc-parser.y | 53 ++++++++++++++++++++++++++++++++++ dtc.h | 8 ++++++ livetree.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 147 insertions(+) diff --git a/dtc-lexer.l b/dtc-lexer.l index 7e9b6796..3c3f3413 100644 --- a/dtc-lexer.l +++ b/dtc-lexer.l @@ -146,6 +146,12 @@ static void PRINTF(1, 2) lexical_error(const char *fmt= , ...); return DT_OMIT_NO_REF; } =20 +<*>"/export/" { + DPRINT("Keyword: /export/\n"); + BEGIN_DEFAULT(); + return DT_EXPORT; + } + <*>{LABEL}: { DPRINT("Label: %s\n", yytext); yylval.labelref =3D xstrdup(yytext); diff --git a/dtc-parser.y b/dtc-parser.y index 9c936736..a0d0aef9 100644 --- a/dtc-parser.y +++ b/dtc-parser.y @@ -46,6 +46,8 @@ static bool is_ref_relative(const char *ref) struct property *proplist; struct node *node; struct node *nodelist; + struct symbol *symbol; + struct symbol *exportlist; struct reserve_info *re; uint64_t integer; unsigned int flags; @@ -60,6 +62,7 @@ static bool is_ref_relative(const char *ref) %token DT_DEL_PROP %token DT_DEL_NODE %token DT_OMIT_NO_REF +%token DT_EXPORT %token DT_PROPNODENAME %token DT_LITERAL %token DT_CHAR_LITERAL @@ -80,6 +83,8 @@ static bool is_ref_relative(const char *ref) %type bytestring %type propdef %type proplist +%type exportdef +%type exportlist %type dt_ref =20 %type devicetree @@ -276,6 +281,49 @@ nodedef: { $$ =3D build_node(NULL, $2, NULL, &@$); } + | '{' proplist exportlist subnodes '}' ';' + { + /* + * exportlist is created with chain_symbol() and so it + * is created in reverse order. Reverse it now to have + * it in correct order + */ + $$ =3D build_node($2, $4, reverse_symbol($3), &@$); + } + | '{' exportlist subnodes '}' ';' + { + /* + * exportlist is created with chain_symbol() and so it + * is created in reverse order. Reverse it now to have + * it in correct order + */ + $$ =3D build_node(NULL, $3, reverse_symbol($2), &@$); + } + ; + +exportlist: + exportdef + { + $$ =3D chain_symbol($1, NULL); + } + | exportlist exportdef + { + $$ =3D chain_symbol($2, $1); + } + | exportlist propdef + { + ERROR(&@2, "Properties must precede exports"); + YYERROR; + } + ; + +exportdef: + DT_EXPORT DT_LABEL dt_ref ';' + { + $$ =3D build_exportsym($2, $3, 0, &@$); + free($2); + free($3); + } ; =20 proplist: @@ -576,6 +624,11 @@ subnodes: ERROR(&@2, "Properties must precede subnodes"); YYERROR; } + | subnode exportdef + { + ERROR(&@2, "Exports must precede subnodes"); + YYERROR; + } ; =20 subnode: diff --git a/dtc.h b/dtc.h index af69b193..90341aa9 100644 --- a/dtc.h +++ b/dtc.h @@ -273,6 +273,9 @@ struct node { for_each_child_withdel(n, c) \ if (!(c)->deleted) =20 +#define for_each_symbol(s0, s) \ + for ((s) =3D (s0); (s); (s) =3D (s)->next) + void add_label(struct label **labels, char *label); void delete_labels(struct label **labels); =20 @@ -282,6 +285,11 @@ struct property *build_property_delete(const char *nam= e); struct property *chain_property(struct property *first, struct property *l= ist); struct property *reverse_properties(struct property *first); =20 +struct symbol *build_exportsym(const char *name, const char *ref, cell_t p= handle, + struct srcpos *srcpos); +struct symbol *chain_symbol(struct symbol *first, struct symbol *list); +struct symbol *reverse_symbol(struct symbol *list); + struct node *build_node(struct property *proplist, struct node *children, struct symbol *exportsymlist, struct srcpos *srcpos); struct node *build_node_delete(struct srcpos *srcpos); diff --git a/livetree.c b/livetree.c index a7f81a90..111c651b 100644 --- a/livetree.c +++ b/livetree.c @@ -36,6 +36,57 @@ void delete_labels(struct label **labels) label->deleted =3D 1; } =20 +struct symbol *build_exportsym(const char *name, const char *ref, cell_t p= handle, + struct srcpos *srcpos) +{ + struct symbol *new =3D xmalloc(sizeof(*new)); + + memset(new, 0, sizeof(*new)); + + new->name =3D xstrdup(name); + new->ref =3D ref ? xstrdup(ref) : NULL; + new->phandle =3D phandle; + new->srcpos =3D srcpos_copy(srcpos); + + return new; +} + +struct symbol *chain_symbol(struct symbol *first, struct symbol *list) +{ + assert(first->next =3D=3D NULL); + + first->next =3D list; + return first; +} + +struct symbol *reverse_symbol(struct symbol *list) +{ + struct symbol *p =3D list; + struct symbol *head =3D NULL; + struct symbol *next; + + while (p) { + next =3D p->next; + p->next =3D head; + head =3D p; + p =3D next; + } + return head; +} + +static void add_symbol(struct symbol **list, struct symbol *new) +{ + struct symbol **s; + + new->next =3D NULL; + + s =3D list; + while (*s) + s =3D &((*s)->next); + + *s =3D new; +} + struct property *build_property(const char *name, struct data val, struct srcpos *srcpos) { @@ -144,6 +195,7 @@ struct node *merge_nodes(struct node *old_node, struct = node *new_node) { struct property *new_prop, *old_prop; struct node *new_child, *old_child; + struct symbol *new_sym, *old_sym; struct label *l; =20 old_node->deleted =3D 0; @@ -217,6 +269,34 @@ struct node *merge_nodes(struct node *old_node, struct= node *new_node) add_child(old_node, new_child); } =20 + /* Merge exported symbols. If there is a collision, keep the new one */ + while (new_node->exportsymlist) { + /* Pop the symbol off the list */ + new_sym =3D new_node->exportsymlist; + new_node->exportsymlist =3D new_sym->next; + new_sym->next =3D NULL; + + /* Look for a collision, set new value if there is */ + for_each_symbol(old_node->exportsymlist, old_sym) { + if (streq(old_sym->name, new_sym->name)) { + old_sym->is_local =3D new_sym->is_local; + free(old_sym->ref); + old_sym->ref =3D new_sym->ref; + old_sym->phandle =3D new_sym->phandle; + old_sym->fullpath =3D new_sym->fullpath; + srcpos_free(old_sym->srcpos); + old_sym->srcpos =3D new_sym->srcpos; + free(new_sym); + new_sym =3D NULL; + break; + } + } + + /* if no collision occurred, add symbol to the old node list. */ + if (new_sym) + add_symbol(&old_node->exportsymlist, new_sym); + } + old_node->srcpos =3D srcpos_extend(old_node->srcpos, new_node->srcpos); =20 /* The new node contents are now merged into the old node. Free --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 92AD13D47DE; Wed, 26 Aug 2026 09:51:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737902; cv=none; b=VLX6ABeKpXhUiAFsqgyCCjK0bRzvp3Jtq/mZPDIPuDaHZTUikjowKcCydyGGC5ccsxhKqycGkY2k53EET19ONCnB+BC6OFSEPuihzVhpkgD1empM9OZ+IrK1GtogKC38y1NggOARkcqfBwY3Wwl6FrdUGGM7CIHkqpmmnwMWZGQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737902; c=relaxed/simple; bh=tHTPX6KoUCmyMITxuCoVYfmnjnE0EzR9yju9R4KgJJw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ZRvVkuAPJzGD+dLEKp2qcZ5P3jTjjNy1iue435eHu7crDB+KFIEroeYICpFT1wlH/lMI0oxpeSDsF4CWbJgqQiK/M3TO01DjuaANDyy+8QMn/O1PnuIxvbDWjZ5n5+YPLNo/QuSaZ9zEuN++ooLgERKvuCtK8TzDnAdiU9ZgggM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=x9X1q9Pm; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="x9X1q9Pm" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 4E21A4E413BC; Wed, 26 Aug 2026 09:51:39 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 2185F604EC; Wed, 26 Aug 2026 09:51:39 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 8D55B11C7AD5F; Wed, 26 Aug 2026 11:51:36 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737898; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=wqZujohaK0sAjx/xhCHMteLuLH6vHHuH9u0wjHd6wao=; b=x9X1q9PmWZF6Rb6e551WKKzMrnnNnRQO3iIVHJxhP9PA9+pjv03kkSVchP6fEEzuP6vEiH gb/LwXuCA74eMxQETjqI9oshhbrGayP9ZMdBa8bVORUiF32Ek2Nnlvj701lDqgrFTcqto9 W4QV9AhBMEkPnA33OIliG0ehwavWYEZ8Ldr0ClhbaJITs2Ve5W3cX6iCzrM6p6It19l0rk yQybGXK7PpsXAgOEFKMaQBnOP+H21nUa2M4pDpN91LEYr4EDwuV45lM4Rzr14sc8laKfor +vpCCBcd6CuYE0IUIuKwkFYLZMYZ5CCTrcmKrlNlJ6zEXvEC94IOrlRq+QgYAw== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 18/74] checks: Handle export symbols in fixup_phandle_references() Date: Wed, 26 Aug 2026 11:48:47 +0200 Message-ID: <20260826094950.1088288-19-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" Export symbols use phandle references. Referenced nodes must have a phandle property set in order to have those references working. fixup_phandle_references() does the needed operation for properties that use a phandle. Extend fixup_phandle_references() to perform exact same operation for export symbols. Signed-off-by: Herve Codina --- checks.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/checks.c b/checks.c index cb3b4b16..13e8b121 100644 --- a/checks.c +++ b/checks.c @@ -612,12 +612,13 @@ static void fixup_phandle_references(struct check *c,= struct dt_info *dti, struct node *node) { struct node *dt =3D dti->dt; + struct symbol *exportsym; struct property *prop; + struct node *refnode; + cell_t phandle; =20 for_each_property(node, prop) { struct marker *m =3D prop->val.markers; - struct node *refnode; - cell_t phandle; =20 for_each_marker_of_type(m, REF_PHANDLE) { assert(m->offset + sizeof(cell_t) <=3D prop->val.len); @@ -639,6 +640,25 @@ static void fixup_phandle_references(struct check *c, = struct dt_info *dti, reference_node(refnode); } } + + for_each_symbol(node->exportsymlist, exportsym) { + refnode =3D get_node_by_ref(dt, exportsym->ref); + if (!refnode) { + if (!(dti->dtsflags & (DTSF_PLUGIN | DTSF_ADDON))) { + FAIL(c, dti, node, + "Export \"%s\" references to non-existent node or label \"%s\"\n", + exportsym->name, exportsym->ref); + } + exportsym->phandle =3D cpu_to_fdt32(0xffffffff); + continue; + } + + /* Create the phandle property for this referenced node */ + phandle =3D get_node_phandle(dt, refnode); + exportsym->phandle =3D phandle; + + reference_node(refnode); + } } ERROR(phandle_references, fixup_phandle_references, NULL, &duplicate_node_names, &explicit_phandles); --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A4DEB3D79E2; Wed, 26 Aug 2026 09:51:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737905; cv=none; b=fRvcOhwGdfsj6A3Qx5y9L1hgTV1OjiVizsUN5aLiAJc8JPQoDk0JZJSb48bAmdhH2Ps4LtzK6VFay5SBq/xtoWquIxqg32ObZyS3k9hQpf6TOQ19LLKX+MYF753tZl7eYLcPc7/inp7OvYXEMs7EyKP+ykzo8+qeLNiwfkS7Vv0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737905; c=relaxed/simple; bh=sAwQnoO3xM4ObRwH/lj6Lqi6FMlOxwsGNoedO0ELfIs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=I7iG+3M8bV6U/9hcL0emFQ/tm0gYZ0tEEecXGhOfNZQwgCheq1YYDK/NXov5Lvxn7gWPkT3t1uchlpqzQI8U6nk00w5o6OlZNGM2nkI3ZRrk/lw5edqEJ7Ytv6nGfYT1vEjhYhhQla+7LPatli4XfeceyrlprXncpfBRJvWPbpI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=A1XSdnuM; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="A1XSdnuM" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id C6AD34E413BF; Wed, 26 Aug 2026 09:51:41 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 9B9CC604EC; Wed, 26 Aug 2026 09:51:41 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 811DB11C780F5; Wed, 26 Aug 2026 11:51:38 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737900; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=2IAT60NMhRbnjs/hFwW1xL6sDToXowEgmrekbo2BisE=; b=A1XSdnuMglJuFilGL5GlviVqhFn3B1MLgxHLUJ77r6gCFrg23RAtEfitvfc55eT1XZCWFb nTpADUOyeRUWhA4f+HVIzoDQyrFUkEQ2dzqpTOe53oDzdyxaNkuxu084Uwqg9Ww5I3V8iQ Z3oMx61SN6VKn8ylNhmVchGuTcwd8HIRsFoda11hdXQvLQ+OmVOtrHml9RmDmaiXOAKYLi lgr9czzONeHqBm4/WTmu9rbFmv8bZGqeffuEcOSaNS3zX8Wra6ZZrMG3YHsRtJUoUkhBJW 4ccifQEF21fGepMQ67ljPf/dnTNJU8ShyDRnOX3HHGnI4mTarHjMlMFTGTf/bw== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 19/74] dtc: Add export symbols (/export/ keyword) in generated dts file Date: Wed, 26 Aug 2026 11:48:48 +0200 Message-ID: <20260826094950.1088288-20-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" The export symbols (/export/ keyword) parsing from a dts file is supported. Add the support for this keyword in the dts file generation. Signed-off-by: Herve Codina --- treesource.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/treesource.c b/treesource.c index 9f6cf92d..a7228f60 100644 --- a/treesource.c +++ b/treesource.c @@ -370,6 +370,7 @@ static void write_propval(FILE *f, struct property *pro= p) =20 static void write_tree_source_node(FILE *f, struct node *tree, int level) { + struct symbol *exportsym; struct property *prop; struct node *child; struct label *l; @@ -399,6 +400,18 @@ static void write_tree_source_node(FILE *f, struct nod= e *tree, int level) fprintf(f, "%s", prop->name); write_propval(f, prop); } + + if (tree->exportsymlist) + fprintf(f, "\n"); + for_each_symbol(tree->exportsymlist, exportsym) { + write_prefix(f, level+1); + fprintf(f, "/export/ %s: ", exportsym->name); + if (exportsym->ref[0] =3D=3D '/') + fprintf(f, "&{%s};\n", exportsym->ref); + else + fprintf(f, "&%s;\n", exportsym->ref); + } + for_each_child(tree, child) { fprintf(f, "\n"); write_tree_source_node(f, child, level+1); --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0C4103D890D; Wed, 26 Aug 2026 09:51:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737909; cv=none; b=Aflt4zsz4zUfifTYKYePBeYHmHN54dcrTy6qTT0Eb6sOn/yrqMZoakja7IcqOg6yRBVdD22F0eRaoKRkmIZEVFyCL+LJ5amkFC6D2TXdjY8xXBsOiQBUdus02Gonzc7uO29ThTnNmwpLBOrprpuhMftLbA+PQbbVVivGHBh0n7o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737909; c=relaxed/simple; bh=5xqiFcAZi9RX2PdWXHIY4GaH2jOnbkRZ+naZwtNbbHM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WeQILTBm5pSjouFow2xC6Hqcu91mTdVU8ivbh/yqpEJMS4yL+XAQeg3ZvL/f6oNIs0/ZceQlucywz7IQDeVl4UOe2Me/nGiPmz3X92gR4pNcGvT4dfYK7pmvIBXAjPjwRlqrQB8FQdgQKKGBLZQEn+D0WHS9GkXnKDYIsFinYmk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=DL3V6j16; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="DL3V6j16" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id D5BD81A183A; Wed, 26 Aug 2026 09:51:43 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id AA346604EC; Wed, 26 Aug 2026 09:51:43 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 1752211C7AD68; Wed, 26 Aug 2026 11:51:41 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737902; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=Mikj5TNqsEyt+SiXGc+SpD7W2whIh6DoMhBvs5/JJrs=; b=DL3V6j16eTAH8rXNxnJCeTVcy8V11JPa40VCssjxBwHH7HhpShRWSR+X40QVLq7JULf4UU aqMcDDDpyFANwf4xlUkucw5gsjGU1K1GShap/UOOcICGrv4Me9vnQ6AZbYL8QEXQ6BTXf6 pzAsvWrYP7EnNgMgHnMIzvRk0Bge7ayd9RgBFTS7B0CXzC1Zqiihxndngzi3Hv2kaR7wQJ VqF67SJlx8u4P/Ol5/nMyhwap3dF/mZKT/o6bpQMXr7FXyCJKO4ETSIEI4JPmk2Oa9kjjo 0PGpHAybtHQUaV24O3zPmDBzTjy9CDnvIfbsM0z80ng1P9gL5RsWi1yh/iBFQw== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 20/74] dtc: Extend complete_references() to handle export symbols Date: Wed, 26 Aug 2026 11:48:49 +0200 Message-ID: <20260826094950.1088288-21-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" Export symbols parsed from a .dts or .dtb file suffer from the same incompleteness as REF_PHANDLE markers. They may lack either the ref string or the is_local flag depending on the device-tree input format used. Apply the same completion operation as the one done for REF_PHANDLE markers. Signed-off-by: Herve Codina --- livetree.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/livetree.c b/livetree.c index 111c651b..8c94e81f 100644 --- a/livetree.c +++ b/livetree.c @@ -584,6 +584,7 @@ static void complete_ref_and_is_local(struct dt_info *d= ti, char **ref, =20 static void complete_references_internal(struct dt_info *dti, struct node = *node) { + struct symbol *exportsym; struct property *prop; struct marker *m; struct node *c; @@ -613,6 +614,16 @@ static void complete_references_internal(struct dt_inf= o *dti, struct node *node) } } =20 + /* + * The exact same behavior exists for export symbols when a dts or a dtb + * is parsed. Perform the exact same completion for export symbols + */ + for_each_symbol(node->exportsymlist, exportsym) { + complete_ref_and_is_local(dti, &exportsym->ref, + &exportsym->is_local, + exportsym->phandle); + } + for_each_child(node, c) complete_references_internal(dti, c); } @@ -637,7 +648,7 @@ struct dt_info *build_dt_info(unsigned int dtsflags, fill_fullpaths(dti->dt, ""); =20 /* - * Complete references (REF_PHANDLE). + * Complete references (REF_PHANDLE and export symbols). * Set ref strings and set is_local flags */ complete_references(dti); --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C8E9D3D969E; Wed, 26 Aug 2026 09:51:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737912; cv=none; b=PtpMUISpvfU6Gl/LY7c7u3LmHXB9KAXgn2tvzbW5l30Qbi++hDd9/+RWa/XfWEh4EAqGm9Wkt5djbRFo95+XhoQ2q4vtXtIXQECMqIxl8X6M10488SH/8v/F1H+r4PZcUFpH8EqWfmcEVG7r7OCpgXRlsiRD8Veg+xgq7Y4Giyc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737912; c=relaxed/simple; bh=vTIi1wfLkG3g2giTz2gEsEHnM2eVclEx2Uj8ZlKHxxk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=QZxKPJ/dJhNTspvWqqvdVGSdqsblKbAd7QuUMN/oWmPkJPMXAYWUi6kdzSlShcNNCk+/iNGkzrxNFhxBgb37LUYpFoUgWiLSEB19RUv0irvssnFQQwmKfr/FDB6c1UT61PvDLVpHF2q5BP0sOOfk+omyBozw6EWFrjQC8JYF3/Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=0mtePrEP; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="0mtePrEP" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 8DD5B1A183D; Wed, 26 Aug 2026 09:51:46 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 61F70604EC; Wed, 26 Aug 2026 09:51:46 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 525F411C7AD52; Wed, 26 Aug 2026 11:51:43 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737905; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=VaY+fjwAIEwejGpSVj/58AGMV1/GWjDpvp3siuyaRFc=; b=0mtePrEPTZDUBY9m23JFf09nERz1arTdoLmM+coLsXoysc4krSlQZpcqEmglb64Y+0Cnq+ iJ9pXneTiY8vMamrFtrhcdjRGDCsVz6uuxpO0KYh/YOyKDu5HbK+ktqiPnxeuB0dOrND8j yob/eO8POe2lYYsG8mHGmdQMrYUtRHGDM2XpqBv/LTxUzgplJVpDPlZSjHmfVhm6jsWHLH vZBvu5ErbZrUwN+RtfZikILnLn7/DqnVHdfNQafZu9TVf+dd0VXhm4PONwUpBl3vyGsntL 0x0l32Gz4W6bWfg9bOAoiqJ/g8hUmpkX6kWv+GIdvSE+OPMyWvkYa5LP4BkIfQ== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 21/74] Add support for FDT_EXPORT_SYM dtb tag Date: Wed, 26 Aug 2026 11:48:50 +0200 Message-ID: <20260826094950.1088288-22-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" The FDT_EXPORT_SYM dtb tag is a meta-data tag defining an exported symbol. It can be present in a node bloc meaning that a symbol is exported at this node level. The node pointed to by this symbol is a local node and identified by a phandle value. The tag is followed by the length of the data part (structured tag), two values and a possible alignment padding: - data part length (32bit): 4 + strlen(name) + 1 - phandle (32bit) The phandle value identifying the node referenced by this symbol. - name (string including \0) The export symbol name. I.e. the name used to reference this exported symbol. - padding: Padding (0x00) added to have the next value aligned on 32bit. Example: FDT_EXPORT_SYM 9 0x00000004 'foo1' 0x00 0x00 0x00 This means that 'foo1' is an exported symbol and the node referenced by this symbol is the node with the phandle value equals 4. This is what is encoded in the dtb when the related dts has the following exported symbol defined: /export/ foo1: &foo; with 'foo' a reference to an existing node where the phandle value is 0x0000004. If several symbols are exported at a given node level, several FDT_EXPORT_SYM are present. Each of them defining one symbol. For instance, exporting 'foo' pointing to phandle 4 and 'bar' pointing to phandle 8 leads to the following sequence: FDT_EXPORT_SYM 8 0x00000004 'foo' FDT_EXPORT_SYM 8 0x00000008 'bar' Add support for this new dtb tag. Signed-off-by: Herve Codina --- dtc.h | 1 + fdtdump.c | 11 ++++++++- flattree.c | 53 ++++++++++++++++++++++++++++++++++++++-- libfdt/fdt.c | 29 ++++++++++++++++++++++ libfdt/fdt.h | 13 ++++++++++ libfdt/fdt_check.c | 40 ++++++++++++++++++++++++++++++ libfdt/libfdt_internal.h | 1 + livetree.c | 2 +- 8 files changed, 146 insertions(+), 4 deletions(-) diff --git a/dtc.h b/dtc.h index 90341aa9..8a20d6da 100644 --- a/dtc.h +++ b/dtc.h @@ -289,6 +289,7 @@ struct symbol *build_exportsym(const char *name, const = char *ref, cell_t phandle struct srcpos *srcpos); struct symbol *chain_symbol(struct symbol *first, struct symbol *list); struct symbol *reverse_symbol(struct symbol *list); +void add_symbol(struct symbol **list, struct symbol *new); =20 struct node *build_node(struct property *proplist, struct node *children, struct symbol *exportsymlist, struct srcpos *srcpos); diff --git a/fdtdump.c b/fdtdump.c index 370db848..f39f78c0 100644 --- a/fdtdump.c +++ b/fdtdump.c @@ -84,7 +84,7 @@ static void dump_blob(void *blob, bool debug, int dump_un= known) const char *p_strings =3D (const char *)blob + off_str; uint32_t version =3D fdt32_to_cpu(bph->version); uint32_t totalsize =3D fdt32_to_cpu(bph->totalsize); - uint32_t tag, offset; + uint32_t tag, offset, val32; const char *p, *d, *s, *t; const char *last_prop_name =3D NULL; int depth, sz, shift; @@ -206,6 +206,15 @@ static void dump_blob(void *blob, bool debug, int dump= _unknown) continue; } =20 + if (tag =3D=3D FDT_EXPORT_SYM) { + p =3D get_structured_tag_data(tag, p, &d, &sz); + val32 =3D fdt32_to_cpu(GET_CELL(d)); + s =3D d; + printf("%*s// [FDT_EXPORT_SYM] '%s' -> phandle 0x%08"PRIx32"\n", + depth * shift, "", s, val32); + continue; + } + if ((tag & FDT_TAG_STRUCTURED) && (tag & FDT_TAG_SKIP_SAFE)) { p =3D get_structured_tag_data(tag, p, &d, &sz); =20 diff --git a/flattree.c b/flattree.c index ac6bcd8f..84acbb35 100644 --- a/flattree.c +++ b/flattree.c @@ -16,6 +16,7 @@ #define FTF_DTFLAGS 0x80 #define FTF_LCVERSW 0x100 #define FTF_PROPDATA_PHANDLE 0x200 +#define FTF_EXPORT_IMPORT_SYM 0x400 =20 static struct version_info { int version; @@ -39,7 +40,7 @@ static struct version_info { FTF_LCVERSW}, {20, 18, 18, FDT_V20_SIZE, FTF_BOOTCPUID|FTF_STRTABSIZE|FTF_STRUCTSIZE|FTF_NOPS|FTF_DTFLAGS| - FTF_LCVERSW|FTF_PROPDATA_PHANDLE}, + FTF_LCVERSW|FTF_PROPDATA_PHANDLE|FTF_EXPORT_IMPORT_SYM}, }; =20 struct emitter { @@ -52,6 +53,7 @@ struct emitter { void (*property)(void *, struct label *labels); void (*propdata_phandle)(void *); void (*propdata_phandle_ref)(void *); + void (*export_sym)(void *); }; =20 static void bin_emit_cell(void *e, cell_t val) @@ -111,6 +113,11 @@ static void bin_emit_propdata_phandle_ref(void *e) bin_emit_cell(e, FDT_PROPDATA_PHANDLE_REF); } =20 +static void bin_emit_export_sym(void *e) +{ + bin_emit_cell(e, FDT_EXPORT_SYM); +} + static struct emitter bin_emitter =3D { .cell =3D bin_emit_cell, .string =3D bin_emit_string, @@ -121,6 +128,7 @@ static struct emitter bin_emitter =3D { .property =3D bin_emit_property, .propdata_phandle =3D bin_emit_propdata_phandle, .propdata_phandle_ref =3D bin_emit_propdata_phandle_ref, + .export_sym =3D bin_emit_export_sym, }; =20 static void emit_label(FILE *f, const char *prefix, const char *label) @@ -248,6 +256,14 @@ static void asm_emit_propdata_phandle_ref(void *e) asm_emit_cell(e, FDT_PROPDATA_PHANDLE_REF); } =20 +static void asm_emit_export_sym(void *e) +{ + FILE *f =3D e; + + fprintf(f, "\t/* FDT_EXPORT_SYM */\n"); + asm_emit_cell(e, FDT_EXPORT_SYM); +} + static struct emitter asm_emitter =3D { .cell =3D asm_emit_cell, .string =3D asm_emit_string, @@ -258,6 +274,7 @@ static struct emitter asm_emitter =3D { .property =3D asm_emit_property, .propdata_phandle =3D asm_emit_propdata_phandle, .propdata_phandle_ref =3D asm_emit_propdata_phandle_ref, + .export_sym =3D asm_emit_export_sym, }; =20 static int stringtable_insert(struct data *d, const char *str) @@ -279,6 +296,7 @@ static void flatten_tree(struct node *tree, struct emit= ter *emit, void *etarget, struct data *strbuf, struct version_info *vi) { + struct symbol *exportsym; struct property *prop; struct node *child; bool seen_name_prop =3D false; @@ -296,6 +314,19 @@ static void flatten_tree(struct node *tree, struct emi= tter *emit, =20 emit->align(etarget, sizeof(cell_t)); =20 + if (vi->flags & FTF_EXPORT_IMPORT_SYM) { + for_each_symbol(tree->exportsymlist, exportsym) { + if (exportsym->is_local) { + emit->export_sym(etarget); + emit->cell(etarget, sizeof(cell_t) + + strlen(exportsym->name) + 1); + emit->cell(etarget, exportsym->phandle); + emit->string(etarget, exportsym->name, 0); + emit->align(etarget, sizeof(cell_t)); + } + } + } + for_each_property(tree, prop) { int nameoff; =20 @@ -747,6 +778,7 @@ static uint32_t flat_read_tag(struct inbuf *inb) case FDT_END: case FDT_PROPDATA_PHANDLE: case FDT_PROPDATA_PHANDLE_REF: + case FDT_EXPORT_SYM: return tag; default: break; @@ -913,8 +945,10 @@ static struct node *unflatten_tree(struct inbuf *dtbuf, node->name =3D xstrdup(flatname); =20 do { + struct symbol *exportsym; struct node *child; struct marker *m; + cell_t phandle; =20 val =3D flat_read_tag(dtbuf); switch (val) { @@ -997,6 +1031,21 @@ static struct node *unflatten_tree(struct inbuf *dtbu= f, prop->val =3D data_append_markers(prop->val, m); break; =20 + case FDT_EXPORT_SYM: + if (!(flags & FTF_EXPORT_IMPORT_SYM)) + die("FDT_EXPORT_SYM tag found in flat tree" + " version <20\n"); + len =3D flat_read_word(dtbuf); + flat_read_subbuf(dtbuf, &subbuf, len); + flat_realign(dtbuf, sizeof(uint32_t)); + + phandle =3D flat_read_word(&subbuf); + str =3D flat_read_string_norealign(&subbuf); + exportsym =3D build_exportsym(str, NULL, phandle, NULL); + exportsym->is_local =3D true; + add_symbol(&node->exportsymlist, exportsym); + break; + default: die("Invalid opcode word %08x in device tree blob\n", val); @@ -1120,7 +1169,7 @@ struct dt_info *dt_from_blob(const char *fname) flags |=3D FTF_DTFLAGS | FTF_LCVERSW; =20 if (version >=3D 20) { - flags |=3D FTF_PROPDATA_PHANDLE; + flags |=3D FTF_PROPDATA_PHANDLE | FTF_EXPORT_IMPORT_SYM; dtsflags |=3D fdt32_to_cpu(fdt->dt_flags) & FDT_FLAG_ADDON ? DTSF_ADDON : 0; } diff --git a/libfdt/fdt.c b/libfdt/fdt.c index d23b886b..92732caf 100644 --- a/libfdt/fdt.c +++ b/libfdt/fdt.c @@ -308,6 +308,33 @@ static uint32_t fdt_next_tag_all(const void *fdt, int = startoffset, int *nextoffs offset =3D sum; break; =20 + case FDT_EXPORT_SYM: + tmp_offset =3D fdt_get_structured_tag_data(tag, fdt, offset, &len); + if (tmp_offset < 0) + return FDT_END; /* premature end */ + + sum =3D tmp_offset + len; + + /* Check phandle */ + tmp32p =3D fdt_offset_ptr(fdt, tmp_offset, sizeof(*tmp32p)); + if (!can_assume(VALID_DTB) && !tmp32p) + return FDT_END; /* premature end */ + tmp_offset +=3D sizeof(fdt32_t); + + /* Check name */ + do { + p =3D fdt_offset_ptr(fdt, tmp_offset++, 1); + } while (p && (*p !=3D '\0')); + if (!can_assume(VALID_DTB) && !p) + return FDT_END; /* premature end */ + + if (!can_assume(VALID_INPUT) && (uint32_t)tmp_offset > sum) + return FDT_END; /* premature end */ + + /* Skip the whole data bloc */ + offset =3D sum; + break; + default: if (!(tag & FDT_TAG_STRUCTURED) || !(tag & FDT_TAG_SKIP_SAFE)) return FDT_END; @@ -338,6 +365,7 @@ static bool fdt_tag_is_unknown(uint32_t tag) case FDT_END: case FDT_PROPDATA_PHANDLE: case FDT_PROPDATA_PHANDLE_REF: + case FDT_EXPORT_SYM: return false; default: break; @@ -393,6 +421,7 @@ bool fdt_tag_filter_skip_metadata(void *data, uint32_t = tag) switch (tag) { case FDT_PROPDATA_PHANDLE: case FDT_PROPDATA_PHANDLE_REF: + case FDT_EXPORT_SYM: return true; =20 default: diff --git a/libfdt/fdt.h b/libfdt/fdt.h index 255e9447..c6a5b3a1 100644 --- a/libfdt/fdt.h +++ b/libfdt/fdt.h @@ -110,6 +110,19 @@ struct fdt_property { */ #define FDT_PROPDATA_PHANDLE_REF FDT_TAG_CAN_SKIP(FDT_TAG_DATA_VARLEN, 0x= 1001) =20 +/* + * Export symbol tag (meta-data). varlen: name, phandle + * + * It defines an exported symbol. It can be present in a node bloc meaning= that + * a symbol is exported at this node level. The node pointed to by this sy= mbol + * is a local node and identified by a phandle value. + * + * phandle: phandle value identifying the node referenced by this symbol + * name: export symbol name, i.e. the name used to reference this exported + * symbol. + */ +#define FDT_EXPORT_SYM FDT_TAG_CAN_SKIP(FDT_TAG_DATA_VARLEN, 0x2000) + #define FDT_V1_SIZE (7*sizeof(fdt32_t)) #define FDT_V2_SIZE (FDT_V1_SIZE + sizeof(fdt32_t)) #define FDT_V3_SIZE (FDT_V2_SIZE + sizeof(fdt32_t)) diff --git a/libfdt/fdt_check.c b/libfdt/fdt_check.c index 96dd7dc0..101efd73 100644 --- a/libfdt/fdt_check.c +++ b/libfdt/fdt_check.c @@ -21,6 +21,7 @@ int fdt_check_full(const void *fdt, size_t bufsize) const char *propname; int proplen; bool expect_end =3D false; + bool subnode_found =3D false; const fdt32_t *pfdt32; const char *str; uint32_t val; @@ -63,6 +64,7 @@ int fdt_check_full(const void *fdt, size_t bufsize) =20 case FDT_BEGIN_NODE: prop =3D NULL; + subnode_found =3D false; depth++; if (depth > INT_MAX) return -FDT_ERR_BADSTRUCTURE; @@ -83,6 +85,7 @@ int fdt_check_full(const void *fdt, size_t bufsize) =20 case FDT_END_NODE: prop =3D NULL; + subnode_found =3D true; if (depth =3D=3D 0) return -FDT_ERR_BADSTRUCTURE; depth--; @@ -163,6 +166,43 @@ int fdt_check_full(const void *fdt, size_t bufsize) return -FDT_ERR_BADVALUE; break; =20 + case FDT_EXPORT_SYM: + /* Export symbols must be in a node */ + if (depth =3D=3D 0) + return -FDT_ERR_BADSTRUCTURE; + + /* and before any properties or subnodes */ + if (prop || subnode_found) + return -FDT_ERR_BADSTRUCTURE; + + d =3D fdt_get_structured_tag_data(tag, fdt, + offset + FDT_TAGSIZE, NULL); + if (d < 0) + return d; + + /* Retrieve the phandle value */ + pfdt32 =3D fdt_offset_ptr(fdt, d, sizeof(*pfdt32)); + if (!pfdt32) + return -FDT_ERR_BADSTRUCTURE; + val =3D fdt32_ld(pfdt32); + + /* Check the phandle value */ + tmp =3D fdt_node_offset_by_phandle(fdt, val); + if (tmp < 0) + return tmp; + + /* Retrieve the export symbol name */ + d +=3D sizeof(fdt32_t); + str =3D fdt_offset_ptr(fdt, d, 1); + if (!str) + return -FDT_ERR_BADSTRUCTURE; + + /* Check that the name is not an empty string */ + if (!strlen(str)) + return -FDT_ERR_BADVALUE; + + break; + default: return -FDT_ERR_INTERNAL; } diff --git a/libfdt/libfdt_internal.h b/libfdt/libfdt_internal.h index 47dfc0d4..7ef1d995 100644 --- a/libfdt/libfdt_internal.h +++ b/libfdt/libfdt_internal.h @@ -9,6 +9,7 @@ =20 #define FDT_ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) #define FDT_TAGALIGN(x) (FDT_ALIGN((x), FDT_TAGSIZE)) +#define FDT_CELLALIGN(x) (FDT_ALIGN((x), FDT_CELLSIZE)) =20 int32_t fdt_ro_probe_(const void *fdt); #define FDT_RO_PROBE(fdt) \ diff --git a/livetree.c b/livetree.c index 8c94e81f..35cf1de5 100644 --- a/livetree.c +++ b/livetree.c @@ -74,7 +74,7 @@ struct symbol *reverse_symbol(struct symbol *list) return head; } =20 -static void add_symbol(struct symbol **list, struct symbol *new) +void add_symbol(struct symbol **list, struct symbol *new) { struct symbol **s; =20 --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F2D033DA5C3; Wed, 26 Aug 2026 09:51:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737912; cv=none; b=Dl1/ivfgEW/rKGO6wkXddbF74C60FwX9P56Gbva+CImLzZaVmk2HSIdhlsMImG+9CA5gSEkW0uPC+98s7UnhxibOBNqiXdzxii1i+3W6jdT8lVfXx3HVeM59s+va2ia8LYKwOl7eY0z8OHDkWKELCzCgtkKtqeAfDQB3+jlago4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737912; c=relaxed/simple; bh=RZ9OKwfjb9UmzlASGFCjaFhIi4cX4D9FIuY66+RGyX8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BXCHdxK+t5WB+JI47uBtOLc16qItLbCJ6EkJsv9WNdNYRheWbTaFtDTd6R1jEFXflx5shtCG7fRyaIaPi7f50n+GLEZ1GOl3w4AOUySVpsrbjX6B/OzE3jcmx+pU8dW/hJcLsPqme1/nemXrp9rzpy+bGbICw1wGyjO9yn7j2GM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=XYAfGJwF; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="XYAfGJwF" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 844451A183E; Wed, 26 Aug 2026 09:51:48 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 58428604EC; Wed, 26 Aug 2026 09:51:48 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id C339411C780F5; Wed, 26 Aug 2026 11:51:45 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737907; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=3fpiGK3MoHlko4IQ+XEILhmqXIbPnabGHGo2TTb3Nfo=; b=XYAfGJwFazFt9hmWdTxWcUPSBVjXT/J9Uwg8fIdtxiZh8I14imgS6KSjun2+7ko5+uYbXk uO0wNXbRGPwnFkeLfIuk61DIqkAWGiNcA1Nd+RZk7lWbcGsiVrxt/0Pie0P9ap7mROvb1z 39IvAc6fOU6S3ggwHUjD4oBr93MnNR9xMPsPXtXYAwmW/zkecDLUuW41dZhhJRmsGyYwL0 5EVP2Tlx73jPIgpIGglU9mR2CTDCf4hADjhScPO2CP0lF0envaEx7PYd4u7301NelRt2xP qJGEJJrQmIWi/NdEiG+KUg4fpCArrywWYRFV2OCLJ92yDZYlAj+cqyXuJbg+mQ== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 22/74] tests: metadata: Add export symbols with local references tests Date: Wed, 26 Aug 2026 11:48:51 +0200 Message-ID: <20260826094950.1088288-23-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" Add tests related to export symbols using local phandle references (FDT_EXPORT_SYM dtb tag). Signed-off-by: Herve Codina --- .../metadata_exportsyms_local.dtb.dts.expect | 26 +++++++++++++++++ tests/metadata_exportsyms_local.dtb.expect | 20 +++++++++++++ tests/metadata_exportsyms_local.dts | 28 +++++++++++++++++++ .../metadata_exportsyms_local.dts.dts.expect | 26 +++++++++++++++++ tests/run_tests.sh | 2 +- 5 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 tests/metadata_exportsyms_local.dtb.dts.expect create mode 100644 tests/metadata_exportsyms_local.dtb.expect create mode 100644 tests/metadata_exportsyms_local.dts create mode 100644 tests/metadata_exportsyms_local.dts.dts.expect diff --git a/tests/metadata_exportsyms_local.dtb.dts.expect b/tests/metadat= a_exportsyms_local.dtb.dts.expect new file mode 100644 index 00000000..ac3d5b3a --- /dev/null +++ b/tests/metadata_exportsyms_local.dtb.dts.expect @@ -0,0 +1,26 @@ +/dts-v1/; + +/ { + + node-a { + }; + + node-b { + phandle =3D <0x03>; + }; + + node-c { + + sub-node { + phandle =3D <0x02>; + }; + }; + + node-d { + phandle =3D <0x01>; + + /export/ node_d: &{/node-d}; + /export/ subnode_c: &{/node-c/sub-node}; + /export/ node_b: &{/node-b}; + }; +}; diff --git a/tests/metadata_exportsyms_local.dtb.expect b/tests/metadata_ex= portsyms_local.dtb.expect new file mode 100644 index 00000000..e09437f8 --- /dev/null +++ b/tests/metadata_exportsyms_local.dtb.expect @@ -0,0 +1,20 @@ +/dts-v1/; + +/ { + node-a { + }; + node-b { + phandle =3D <0x00000003>; + }; + node-c { + sub-node { + phandle =3D <0x00000002>; + }; + }; + node-d { + // [FDT_EXPORT_SYM] 'node_d' -> phandle 0x00000001 + // [FDT_EXPORT_SYM] 'subnode_c' -> phandle 0x00000002 + // [FDT_EXPORT_SYM] 'node_b' -> phandle 0x00000003 + phandle =3D <0x00000001>; + }; +}; diff --git a/tests/metadata_exportsyms_local.dts b/tests/metadata_exportsym= s_local.dts new file mode 100644 index 00000000..10e6e47a --- /dev/null +++ b/tests/metadata_exportsyms_local.dts @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) +/* + * Copyright (C) 2026 Bootlin + */ + +/dts-v1/; + +/ { + node-a { + }; + + node_b: node-b { + }; + + node-c { + sub_node: sub-node { + }; + }; + + node_d: node-d { + /export/ node_d: &node_d; + /export/ subnode_c: &sub_node; + }; +}; + +&node_d { + /export/ node_b: &node_b; +}; diff --git a/tests/metadata_exportsyms_local.dts.dts.expect b/tests/metadat= a_exportsyms_local.dts.dts.expect new file mode 100644 index 00000000..4723e7e4 --- /dev/null +++ b/tests/metadata_exportsyms_local.dts.dts.expect @@ -0,0 +1,26 @@ +/dts-v1/; + +/ { + + node-a { + }; + + node_b: node-b { + phandle =3D <0x03>; + }; + + node-c { + + sub_node: sub-node { + phandle =3D <0x02>; + }; + }; + + node_d: node-d { + phandle =3D <0x01>; + + /export/ node_d: &node_d; + /export/ subnode_c: &sub_node; + /export/ node_b: &node_b; + }; +}; diff --git a/tests/run_tests.sh b/tests/run_tests.sh index f119acc0..06c27b71 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -1249,7 +1249,7 @@ fdtoverlay_tests() { =20 metadata_tests() { for dt in metadata_propdata_phandle_local metadata_propdata_phandle_ref \ - metadata_addon_base; do + metadata_addon_base metadata_exportsyms_local; do run_dtc_test -I dts -O dts -o $dt.dts.dts "$SRCDIR/$dt.dts" base_run_test check_diff $dt.dts.dts "$SRCDIR/$dt.dts.dts.expect" run_dtc_test -I dts -O dtb -o $dt.dtb "$SRCDIR/$dt.dts" --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 918853DAAC6 for ; Wed, 26 Aug 2026 09:51:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737914; cv=none; b=glJkNeyOaMGLc9s6IGggj4UWjhjIwijPrq9RHvvkjfs5s2eaihbZO6aKk6QkwwXR1fPTmSdOQcSCDaTBZdYzMjjZ7uEPlU0OiWC7duE3ZF0UstQQb/zlFluJX7HYxS1ZmdNSvqaqOdEhIgwKMMYIyW8swCK7Tz+kaOckOCmM8Yo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737914; c=relaxed/simple; bh=im4eZW+9wIZ9JGZTAfMHMVs13K7x67s6Foy9WlnlbNA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=A5xoIU1AqwkLtshZ2A05e1pCpx0ePXZJF78awt0P+MD63gelJMEmyNIAODfsiEKAB8dhc22ln992uU9bd8YMe0O9EnHL3t2tbAlZaGeDgixov5Wvu3035rJRWNDa5B2oDpqFgK1KuooOLILhJtl9VTHULoMbwGyHQ8Cgpbk9sdc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=OVZL3pHv; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="OVZL3pHv" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id BFDF01A183A; Wed, 26 Aug 2026 09:51:50 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 93C39604EC; Wed, 26 Aug 2026 09:51:50 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id CCACC11C7AD5A; Wed, 26 Aug 2026 11:51:47 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737909; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=pUjQSxF5HYREAJufTO0xLlCZpiys5dw7UOklKZJrfoE=; b=OVZL3pHvOgiU9C78i7kotsIyjE7HYeMP8zak34gA39kAQ+CT/AodtXechSyw8F/He2I4F9 InfoVIdfAWZ+TMdCKChbAI7/ZemoeWz9loB2uurf/ARZSvGMGr/+8GB+t+nelxTEiq7TSy hSC0hGDi9+uZ1g1ShE2wxki1XkaPAs1gHCwrZbdAMY99rtUnxNipuV5ZWTPc9F7Z9Pal2f A8CF4wQ9vH+4e7C0Vlu9xaBVN7IbA5z1MqybOQm22GAOMajEFt19zdJWB1jhvhcQ+d92m9 2FCR/SidlHu3ilCCYFHDy7V9z3LW96uHUaZRBju+446/O5SmfGZD0Ie1P2gBoA== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 23/74] dtc: Add support for export symbols sorting Date: Wed, 26 Aug 2026 11:48:52 +0200 Message-ID: <20260826094950.1088288-24-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" dtc can sort items when the command line --sort option is set. Add support for export symbols sorting when this option is used. Signed-off-by: Herve Codina --- livetree.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/livetree.c b/livetree.c index 35cf1de5..fe0f300b 100644 --- a/livetree.c +++ b/livetree.c @@ -1028,6 +1028,42 @@ static void sort_properties(struct node *node) free(tbl); } =20 +static int cmp_symbol(const void *ax, const void *bx) +{ + const struct symbol *a, *b; + + a =3D *((const struct symbol * const *)ax); + b =3D *((const struct symbol * const *)bx); + + return strcmp(a->name, b->name); +} + +static void sort_exportsyms(struct node *node) +{ + int n =3D 0, i =3D 0; + struct symbol *symbol, **tbl; + + for_each_symbol(node->exportsymlist, symbol) + n++; + + if (n =3D=3D 0) + return; + + tbl =3D xmalloc(n * sizeof(*tbl)); + + for_each_symbol(node->exportsymlist, symbol) + tbl[i++] =3D symbol; + + qsort(tbl, n, sizeof(*tbl), cmp_symbol); + + node->exportsymlist =3D tbl[0]; + for (i =3D 0; i < (n-1); i++) + tbl[i]->next =3D tbl[i+1]; + tbl[n-1]->next =3D NULL; + + free(tbl); +} + static int cmp_subnode(const void *ax, const void *bx) { const struct node *a, *b; @@ -1069,6 +1105,7 @@ static void sort_node(struct node *node) struct node *c; =20 sort_properties(node); + sort_exportsyms(node); sort_subnodes(node); for_each_child_withdel(node, c) sort_node(c); --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BDB913DC4A0; Wed, 26 Aug 2026 09:51:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737916; cv=none; b=WK8AEIaM/6UWwPcIN8DhxxAiufi4UevZ+hDhHcjSktRUBXKe4JL/je4av00K0BNbjpgts+sD6//Hgs/DjI8OFmFoXJpKuHcq+dm8O5j02gNNOCmI2SlfgKY2enxb5y9Unw3Poc0PDRNWiWOX7Y163MfpaE8kR9T6sy8y0jk450M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737916; c=relaxed/simple; bh=WkG10wqSpZt+o7CGVjM4PHr1dhyUXQJu+rrh5Lvd+MM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=QGBNjOTVDNZ+VqkyVE3LwCBdVaThyxoU3avE1D+5X6JI+l4Uo7SYkTDlfKDGTw4/P6tANHGe1Q6f8v7Brcjts3WCw61EBwsmub8SaOEOh2bqf2ZB+Ot7DsJ0FiRDrqvgOqSzI1yDM7hsS2cFad4up1Tz2LMT5NWbbWTP9vVrKdA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=nHY+Bq9b; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="nHY+Bq9b" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 488C34E413BF; Wed, 26 Aug 2026 09:51:53 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 1BD2D604EC; Wed, 26 Aug 2026 09:51:53 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 1E8DE11C7AD5B; Wed, 26 Aug 2026 11:51:50 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737912; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=XjMfx7c4mghrlelUrrqg7EoVqa7dbUdocfRTilLLReo=; b=nHY+Bq9bY6Tt8dOWG0qhGxY0/HpdzpuThwn3QR20XVWxOshWT2gTAzAulYjAmct22e3qVU hzrSsKnZdsbSrcrb7shlwXZZ1PQN5qbZoZ17faOlnrAYz0676YI5oXKu9x2+oCvCzEA5aT rZhVuX3Sx6jUoANew96Z8qCXmBoY6KR2c9HWPMh6zJL4euBicargM4+ejJMBMbYvb5Gp1H ihojwcjd6f6KbGpnOMZoBwoxyKCT7d5ni3wn/Ay6kja8RycmWx96WdM4+Qnka/ZxMRSQXv m9zCpgzWsW8EbpTqDyxnqI3ETyQ40J4mtVyuaZ954mYVFX4t04jx7nbWB9kVXg== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 24/74] tests: metadata: Add a test for export symbols sorting Date: Wed, 26 Aug 2026 11:48:53 +0200 Message-ID: <20260826094950.1088288-25-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" dtc is able to sort the export symbols list when the --sort option is used. Add a test for this feature. Signed-off-by: Herve Codina --- tests/metadata_sort.dtb.dts.expect | 18 ++++++++++++++++++ tests/metadata_sort.dtb.expect | 15 +++++++++++++++ tests/metadata_sort.dts | 21 +++++++++++++++++++++ tests/run_tests.sh | 9 +++++++++ 4 files changed, 63 insertions(+) create mode 100644 tests/metadata_sort.dtb.dts.expect create mode 100644 tests/metadata_sort.dtb.expect create mode 100644 tests/metadata_sort.dts diff --git a/tests/metadata_sort.dtb.dts.expect b/tests/metadata_sort.dtb.d= ts.expect new file mode 100644 index 00000000..f07a42b2 --- /dev/null +++ b/tests/metadata_sort.dtb.dts.expect @@ -0,0 +1,18 @@ +/dts-v1/; +/addon/; + +/ { + + node-a { + prop_a =3D <0x1c8>; + prop_b =3D <0x7b>; + + /export/ a: &{/node-b}; + /export/ ba: &{/node-b}; + /export/ bb: &{/node-b}; + }; + + node-b { + phandle =3D <0x01>; + }; +}; diff --git a/tests/metadata_sort.dtb.expect b/tests/metadata_sort.dtb.expect new file mode 100644 index 00000000..ed10b59a --- /dev/null +++ b/tests/metadata_sort.dtb.expect @@ -0,0 +1,15 @@ +/dts-v1/; +/addon/; + +/ { + node-a { + // [FDT_EXPORT_SYM] 'a' -> phandle 0x00000001 + // [FDT_EXPORT_SYM] 'ba' -> phandle 0x00000001 + // [FDT_EXPORT_SYM] 'bb' -> phandle 0x00000001 + prop_a =3D <0x000001c8>; + prop_b =3D <0x0000007b>; + }; + node-b { + phandle =3D <0x00000001>; + }; +}; diff --git a/tests/metadata_sort.dts b/tests/metadata_sort.dts new file mode 100644 index 00000000..7d1cca7e --- /dev/null +++ b/tests/metadata_sort.dts @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) +/* + * Copyright (C) 2026 Bootlin + */ + +/dts-v1/; +/addon/; + +/ { + node_b: node-b { + }; + + node-a { + prop_b =3D <123>; + prop_a =3D <456>; + + /export/ ba: &node_b; + /export/ bb: &node_b; + /export/ a: &node_b; + }; +}; diff --git a/tests/run_tests.sh b/tests/run_tests.sh index 06c27b71..0c5f2849 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -1266,6 +1266,15 @@ metadata_tests() { sed -i '/^\/\/ /d' $dt.dtb.dts.dtb.out base_run_test check_diff $dt.dtb.dts.dtb.out "$SRCDIR/$dt.dtb.expect" done + + run_dtc_test -I dts -O dtb -s -o metadata_sort.dtb "$SRCDIR/metadata_sort= .dts" + base_run_test wrap_fdtdump metadata_sort.dtb metadata_sort.dtb.out + # Remove unneeded comments + sed -i '/^\/\/ /d' metadata_sort.dtb.out + base_run_test check_diff metadata_sort.dtb.out "$SRCDIR/metadata_sort.dtb= .expect" + run_dtc_test -I dtb -O dts -o metadata_sort.dtb.dts metadata_sort.dtb + base_run_test check_diff metadata_sort.dtb.dts "$SRCDIR/metadata_sort.dtb= .dts.expect" + run_test check_full metadata_sort.dtb } =20 pylibfdt_tests () { --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BD16A3B7765; Wed, 26 Aug 2026 09:51:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737920; cv=none; b=LIOP3cF5Zm4u2cfycl6p1LIr0J2EwU7LPPryhbN3QencxDQu5046A+wOH/3eWdLGmO+Q0uVbFV/wJtcklVaoWsJyMZhQ2+215nrxX94+wqcY0QcHv5sAsGyBkfj8haTkIstcM4NTvKWV0bR9WAgmCFIO/Nsa1iSvPREcbmzwHgg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737920; c=relaxed/simple; bh=AYO+n6Dv9yEKFnwvFGYw7hryLy7gNag7ZWzAOEESmYk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=icIgpilwmUlb0r4CDh4kxf+T5/9HBPt2nzRyw/Mz5CapKIePPbiOjkQ/g0n9Eak671mRFVS0KUUTeXADClyD/SUxpOe/PWfgtlqqez8k/sLtM+44kYWAIBL6FMOmCeNyOlKw6V5Wvi9ggQ1XcWegVFg40RbxafFLYc6T7TS6AAg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=yoe7+LR8; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="yoe7+LR8" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 9351D1A183A; Wed, 26 Aug 2026 09:51:55 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 67D2C604EC; Wed, 26 Aug 2026 09:51:55 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 8BA6511C7AD5F; Wed, 26 Aug 2026 11:51:52 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737914; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=athVsAniPnfkJrxTge4D86IncTAbVzgSJZKyLxJhcts=; b=yoe7+LR8vVAOeMNjVnMd395TUEx+6rCUKoIwSrTAx13BgUFqEDMUINJ8/uHCspZPg9mg7c GeDhsms2/p0v/h/cZGjj/zKC9+Wwrz+tQPgfcjXuFybYomzAG3RhZn/5L+jjd+aLQ8Irhk P4Tq6+Pucv8fJcHqoPipUUpemIzwoOQjhnc8F0i4JQmp1ng4gbmjbE8GBzJSrAJITBAkpN lgWVE0O1XaiWzhK5pcCD5yu76Jw+deh6sRPsusgkXPK67jdoWNnxVt300GTQhj21nnDyzt yb8WH9/Y+mcQF9SiEc81S+ahccxzd0JIVbFse0udWqfpMx2GLz9oAlvdzo4Y6w== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 25/74] Add support for FDT_EXPORT_SYM_REF dtb tag Date: Wed, 26 Aug 2026 11:48:54 +0200 Message-ID: <20260826094950.1088288-26-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" The FDT_EXPORT_SYM_REF dtb tag is similar to the FDT_EXPORT_SYM tag except that it identifies a reference to an external phandle. The node referenced by the phandle is not present in the device-tree blob. The FDT_EXPORT_SYM_REF dtb tag is a meta-data tag defining an exported symbol. It can be present in a node bloc meaning that a symbol is exported at this node level. The node pointed to by this symbol is not a local node (i.e. the node is not present in the device-tree blob.). This tag can be available only in overlay or addon device-tree blobs. The symbol has to be resolved when the device-tree blob is applied on top of a base device-tree. The tag is followed by the length of the data part (structured tag), two values and a possible alignment padding: - data part length (32bit): strlen(label) + 1 + strlen(name) + 1 - label (string including \0): The label to use to resolve this symbol. This label is the reference to the external phandle. - name (string including \0) The export symbol name. I.e. the name used to reference this exported symbol. - padding: Padding (0x00) added to have the next value aligned on 32bit. Example: FDT_EXPORT_SYM_REF 11 'foo_a' 'foo1' 0x00 This means that 'foo1' is an exported symbol and the node referenced by this symbol is external to the dtb (unresolved symbol). This external node is referenced by the "foo_a" label. This is what is encoded in the dtb when the related dts has the following exported symbol defined: /export/ foo1: &foo_a; with 'foo_a' a reference to a non local node. If several non local symbols are exported at a given node level, several FDT_EXPORT_SYM_REF are present. Each of them defining one symbol. For instance, exporting 'foo1' pointing the node referenced by 'foo_a' and exporting 'bar' pointing to the node referenced by 'bar_b' leads to the following sequence: FDT_EXPORT_SYM_REF 11 'foo_a' 'foo1' 0x00 FDT_EXPORT_SYM_REF 10 'bar_b' 'bar' 0x00 0x00 Add support for this new dtb tag. Signed-off-by: Herve Codina --- fdtdump.c | 9 +++++++++ flattree.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ libfdt/fdt.c | 30 ++++++++++++++++++++++++++++++ libfdt/fdt.h | 17 +++++++++++++++++ libfdt/fdt_check.c | 38 +++++++++++++++++++++++++++++++++++++- 5 files changed, 137 insertions(+), 1 deletion(-) diff --git a/fdtdump.c b/fdtdump.c index f39f78c0..db5b53dc 100644 --- a/fdtdump.c +++ b/fdtdump.c @@ -215,6 +215,15 @@ static void dump_blob(void *blob, bool debug, int dump= _unknown) continue; } =20 + if (tag =3D=3D FDT_EXPORT_SYM_REF) { + p =3D get_structured_tag_data(tag, p, &d, &sz); + t =3D d; + s =3D d + strlen(t) + 1; + printf("%*s// [FDT_EXPORT_SYM_REF] '%s' -> '%s'\n", depth * shift, "", + s, t); + continue; + } + if ((tag & FDT_TAG_STRUCTURED) && (tag & FDT_TAG_SKIP_SAFE)) { p =3D get_structured_tag_data(tag, p, &d, &sz); =20 diff --git a/flattree.c b/flattree.c index 84acbb35..4e4727e9 100644 --- a/flattree.c +++ b/flattree.c @@ -54,6 +54,7 @@ struct emitter { void (*propdata_phandle)(void *); void (*propdata_phandle_ref)(void *); void (*export_sym)(void *); + void (*export_sym_ref)(void *); }; =20 static void bin_emit_cell(void *e, cell_t val) @@ -118,6 +119,11 @@ static void bin_emit_export_sym(void *e) bin_emit_cell(e, FDT_EXPORT_SYM); } =20 +static void bin_emit_export_sym_ref(void *e) +{ + bin_emit_cell(e, FDT_EXPORT_SYM_REF); +} + static struct emitter bin_emitter =3D { .cell =3D bin_emit_cell, .string =3D bin_emit_string, @@ -129,6 +135,7 @@ static struct emitter bin_emitter =3D { .propdata_phandle =3D bin_emit_propdata_phandle, .propdata_phandle_ref =3D bin_emit_propdata_phandle_ref, .export_sym =3D bin_emit_export_sym, + .export_sym_ref =3D bin_emit_export_sym_ref, }; =20 static void emit_label(FILE *f, const char *prefix, const char *label) @@ -264,6 +271,14 @@ static void asm_emit_export_sym(void *e) asm_emit_cell(e, FDT_EXPORT_SYM); } =20 +static void asm_emit_export_sym_ref(void *e) +{ + FILE *f =3D e; + + fprintf(f, "\t/* FDT_EXPORT_SYM_REF */\n"); + asm_emit_cell(e, FDT_EXPORT_SYM_REF); +} + static struct emitter asm_emitter =3D { .cell =3D asm_emit_cell, .string =3D asm_emit_string, @@ -275,6 +290,7 @@ static struct emitter asm_emitter =3D { .propdata_phandle =3D asm_emit_propdata_phandle, .propdata_phandle_ref =3D asm_emit_propdata_phandle_ref, .export_sym =3D asm_emit_export_sym, + .export_sym_ref =3D asm_emit_export_sym_ref, }; =20 static int stringtable_insert(struct data *d, const char *str) @@ -323,7 +339,19 @@ static void flatten_tree(struct node *tree, struct emi= tter *emit, emit->cell(etarget, exportsym->phandle); emit->string(etarget, exportsym->name, 0); emit->align(etarget, sizeof(cell_t)); + continue; } + + if (exportsym->ref[0] =3D=3D '/') + die("Export symbol uses a non local reference by path (%s)\n", + exportsym->ref); + + emit->export_sym_ref(etarget); + emit->cell(etarget, strlen(exportsym->ref) + 1 + + strlen(exportsym->name) + 1); + emit->string(etarget, exportsym->ref, 0); + emit->string(etarget, exportsym->name, 0); + emit->align(etarget, sizeof(cell_t)); } } =20 @@ -779,6 +807,7 @@ static uint32_t flat_read_tag(struct inbuf *inb) case FDT_PROPDATA_PHANDLE: case FDT_PROPDATA_PHANDLE_REF: case FDT_EXPORT_SYM: + case FDT_EXPORT_SYM_REF: return tag; default: break; @@ -933,6 +962,7 @@ static struct node *unflatten_tree(struct inbuf *dtbuf, uint32_t offset; uint32_t len; const char *str; + const char *str2; =20 node =3D build_node(NULL, NULL, NULL, NULL); =20 @@ -1046,6 +1076,20 @@ static struct node *unflatten_tree(struct inbuf *dtb= uf, add_symbol(&node->exportsymlist, exportsym); break; =20 + case FDT_EXPORT_SYM_REF: + if (!(flags & FTF_EXPORT_IMPORT_SYM)) + die("FDT_EXPORT_SYM_REF tag found in flat tree" + " version <20\n"); + len =3D flat_read_word(dtbuf); + flat_read_subbuf(dtbuf, &subbuf, len); + flat_realign(dtbuf, sizeof(uint32_t)); + + str =3D flat_read_string_norealign(&subbuf); /* Ref */ + str2 =3D flat_read_string_norealign(&subbuf); /* Name */ + exportsym =3D build_exportsym(str2, str, 0, NULL); + add_symbol(&node->exportsymlist, exportsym); + break; + default: die("Invalid opcode word %08x in device tree blob\n", val); diff --git a/libfdt/fdt.c b/libfdt/fdt.c index 92732caf..9bab9149 100644 --- a/libfdt/fdt.c +++ b/libfdt/fdt.c @@ -335,6 +335,34 @@ static uint32_t fdt_next_tag_all(const void *fdt, int = startoffset, int *nextoffs offset =3D sum; break; =20 + case FDT_EXPORT_SYM_REF: + tmp_offset =3D fdt_get_structured_tag_data(tag, fdt, offset, &len); + if (tmp_offset < 0) + return FDT_END; /* premature end */ + + sum =3D tmp_offset + len; + + /* Check ref */ + do { + p =3D fdt_offset_ptr(fdt, tmp_offset++, 1); + } while (p && (*p !=3D '\0')); + if (!can_assume(VALID_DTB) && !p) + return FDT_END; /* premature end */ + + /* Check name */ + do { + p =3D fdt_offset_ptr(fdt, tmp_offset++, 1); + } while (p && (*p !=3D '\0')); + if (!can_assume(VALID_DTB) && !p) + return FDT_END; /* premature end */ + + if (!can_assume(VALID_INPUT) && (uint32_t)tmp_offset > sum) + return FDT_END; /* premature end */ + + /* Skip the whole data bloc */ + offset =3D sum; + break; + default: if (!(tag & FDT_TAG_STRUCTURED) || !(tag & FDT_TAG_SKIP_SAFE)) return FDT_END; @@ -366,6 +394,7 @@ static bool fdt_tag_is_unknown(uint32_t tag) case FDT_PROPDATA_PHANDLE: case FDT_PROPDATA_PHANDLE_REF: case FDT_EXPORT_SYM: + case FDT_EXPORT_SYM_REF: return false; default: break; @@ -422,6 +451,7 @@ bool fdt_tag_filter_skip_metadata(void *data, uint32_t = tag) case FDT_PROPDATA_PHANDLE: case FDT_PROPDATA_PHANDLE_REF: case FDT_EXPORT_SYM: + case FDT_EXPORT_SYM_REF: return true; =20 default: diff --git a/libfdt/fdt.h b/libfdt/fdt.h index c6a5b3a1..624491a0 100644 --- a/libfdt/fdt.h +++ b/libfdt/fdt.h @@ -123,6 +123,23 @@ struct fdt_property { */ #define FDT_EXPORT_SYM FDT_TAG_CAN_SKIP(FDT_TAG_DATA_VARLEN, 0x2000) =20 +/* + * Export external symbol tag (meta-data). varlen: label, name + * + * It defines an exported symbol. It can be present in a node bloc meaning= that + * a symbol is exported at this node level. The node pointed to by this sy= mbol + * is not a local node (i.e. the node is not present in the device-tree bl= ob.). + * This tag can be available only in overlay or addon device-tree blobs. T= he + * symbol has to be resolved when the device-tree blob is applied on top o= f a + * base device-tree. + * + * label: Label to use to resolve this symbol. This label is the reference= to + * the external phandle. + * name: export symbol name, i.e. the name used to reference this exported + * symbol. + */ +#define FDT_EXPORT_SYM_REF FDT_TAG_CAN_SKIP(FDT_TAG_DATA_VARLEN, 0x2001) + #define FDT_V1_SIZE (7*sizeof(fdt32_t)) #define FDT_V2_SIZE (FDT_V1_SIZE + sizeof(fdt32_t)) #define FDT_V3_SIZE (FDT_V2_SIZE + sizeof(fdt32_t)) diff --git a/libfdt/fdt_check.c b/libfdt/fdt_check.c index 101efd73..19b35c8b 100644 --- a/libfdt/fdt_check.c +++ b/libfdt/fdt_check.c @@ -25,6 +25,7 @@ int fdt_check_full(const void *fdt, size_t bufsize) const fdt32_t *pfdt32; const char *str; uint32_t val; + int len; =20 if (can_assume(PERFECT)) return 0; @@ -72,7 +73,6 @@ int fdt_check_full(const void *fdt, size_t bufsize) /* The root node must have an empty name */ if (depth =3D=3D 1) { const char *name; - int len; =20 name =3D fdt_get_name(fdt, offset, &len); if (!name) @@ -203,6 +203,42 @@ int fdt_check_full(const void *fdt, size_t bufsize) =20 break; =20 + case FDT_EXPORT_SYM_REF: + /* Export symbols must be in a node */ + if (depth =3D=3D 0) + return -FDT_ERR_BADSTRUCTURE; + + /* and before any properties or subnodes */ + if (prop || subnode_found) + return -FDT_ERR_BADSTRUCTURE; + + d =3D fdt_get_structured_tag_data(tag, fdt, + offset + FDT_TAGSIZE, NULL); + if (d < 0) + return d; + + /* Retrieve the reference */ + str =3D fdt_offset_ptr(fdt, d, 1); + if (!str) + return -FDT_ERR_BADSTRUCTURE; + + /* Check that the reference is not an empty string */ + len =3D strlen(str); + if (!len) + return -FDT_ERR_BADVALUE; + + /* Retrieve the export symbol name */ + d +=3D len + 1; + str =3D fdt_offset_ptr(fdt, d, 1); + if (!str) + return -FDT_ERR_BADSTRUCTURE; + + /* Check that the name is not an empty string */ + if (!strlen(str)) + return -FDT_ERR_BADVALUE; + + break; + default: return -FDT_ERR_INTERNAL; } --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4FEB73DDAE9; Wed, 26 Aug 2026 09:51:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737921; cv=none; b=SkPDLbHAQPUjZnJEt+iCUFJRx4LCgujkATFUdzdOsIUmpg5oyDmYQwBvN6anAxeXUXr/wz56h2rLyqmRMC47ygV91J4tv/2WFoI6I5EWjPrSObQbHqcDeuQYRVCyQVr8A5/6NJnxalPjUcH+z6SUZo4aBZnD+XP3OqxwgUFaO4I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737921; c=relaxed/simple; bh=0UJ91EliIHMrYmF6hhnt+CR23FgAXC9L3OYxpWwaYU8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=aNM+0Q8CvgdzNxOq4UTV9koyUrMBF94Ad7wdkukqaf4bM7oRzWd/XIpji7fL5eiB1+GbgizYs4RdbWPTBfZrmDNKWtXfXLeEjZNyOXCA9u1THhu3Wk+worKujC98GdHr+EoCdF+WJvyB3Y3Jfj6wX/b4PANMnXDUbpu8KkGOBWw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=kdFX+1/L; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="kdFX+1/L" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 77C974E413BC; Wed, 26 Aug 2026 09:51:57 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 46B7E604EC; Wed, 26 Aug 2026 09:51:57 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 0245E11C7AD52; Wed, 26 Aug 2026 11:51:54 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737916; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=6fo5UaPE2VW1KtAYDqr1xUO0NzeMzLyeMMLT0paCN+o=; b=kdFX+1/L5MLwtGly5MOzRNfitoGdgROL/DeXKaI+OBWiy5zXPXwbi7bfOh/oGR71e9ncmg 6bCulE0E3W0qdf+eY84DfgLtW8H9TIEPKUSexKBdKftyiQi7NKtDPLYlfp1Ndpfd64ixif x1codX24Z8rm2TkJYqpkA2q+B1O0TfG5O8lsni0u5luU3A1vH/59BuyBTppJDlErcgZnOK KFCzSoA3t3gHiLP9rGsfFsZZTO5yr+m6XyB29HDLoOn4wL5zRc+JVjxfhfbdcCm7veuC4j mx3efWAqNhrprhEc6ddPrjcH13ICCVYeO5197XDBv3HOIHVsmhgCf0LUcs6Xbw== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 26/74] tests: metadata: Add export symbols with external references tests Date: Wed, 26 Aug 2026 11:48:55 +0200 Message-ID: <20260826094950.1088288-27-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" Add tests related to export symbols using external references (FDT_EXPORT_SYM_REF dtb tag). Signed-off-by: Herve Codina --- tests/metadata_exportsyms_ref.dtb.dts.expect | 25 +++++++++++++++++++ tests/metadata_exportsyms_ref.dtb.expect | 18 ++++++++++++++ tests/metadata_exportsyms_ref.dts | 26 ++++++++++++++++++++ tests/metadata_exportsyms_ref.dts.dts.expect | 25 +++++++++++++++++++ tests/run_tests.sh | 3 ++- 5 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 tests/metadata_exportsyms_ref.dtb.dts.expect create mode 100644 tests/metadata_exportsyms_ref.dtb.expect create mode 100644 tests/metadata_exportsyms_ref.dts create mode 100644 tests/metadata_exportsyms_ref.dts.dts.expect diff --git a/tests/metadata_exportsyms_ref.dtb.dts.expect b/tests/metadata_= exportsyms_ref.dtb.dts.expect new file mode 100644 index 00000000..d2c33203 --- /dev/null +++ b/tests/metadata_exportsyms_ref.dtb.dts.expect @@ -0,0 +1,25 @@ +/dts-v1/; +/addon/; + +/ { + + node-a { + }; + + node-b { + }; + + node-c { + + sub-node { + + /export/ ref_base_node_a: &base_node_a; + /export/ ref_base_node_b: &base_node_b; + }; + }; + + node-d { + + /export/ ref_base_node_c: &base_node_c; + }; +}; diff --git a/tests/metadata_exportsyms_ref.dtb.expect b/tests/metadata_expo= rtsyms_ref.dtb.expect new file mode 100644 index 00000000..395861bc --- /dev/null +++ b/tests/metadata_exportsyms_ref.dtb.expect @@ -0,0 +1,18 @@ +/dts-v1/; +/addon/; + +/ { + node-a { + }; + node-b { + }; + node-c { + sub-node { + // [FDT_EXPORT_SYM_REF] 'ref_base_node_a' -> 'base_node_a' + // [FDT_EXPORT_SYM_REF] 'ref_base_node_b' -> 'base_node_b' + }; + }; + node-d { + // [FDT_EXPORT_SYM_REF] 'ref_base_node_c' -> 'base_node_c' + }; +}; diff --git a/tests/metadata_exportsyms_ref.dts b/tests/metadata_exportsyms_= ref.dts new file mode 100644 index 00000000..c094be1e --- /dev/null +++ b/tests/metadata_exportsyms_ref.dts @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) +/* + * Copyright (C) 2026 Bootlin + */ + +/dts-v1/; +/addon/; + +/ { + node-a { + }; + + node-b { + }; + + node-c { + sub_node: sub-node { + /export/ ref_base_node_a: &base_node_a; + /export/ ref_base_node_b: &base_node_b; + }; + }; + + node-d { + /export/ ref_base_node_c: &base_node_c; + }; +}; diff --git a/tests/metadata_exportsyms_ref.dts.dts.expect b/tests/metadata_= exportsyms_ref.dts.dts.expect new file mode 100644 index 00000000..2654df12 --- /dev/null +++ b/tests/metadata_exportsyms_ref.dts.dts.expect @@ -0,0 +1,25 @@ +/dts-v1/; +/addon/; + +/ { + + node-a { + }; + + node-b { + }; + + node-c { + + sub_node: sub-node { + + /export/ ref_base_node_a: &base_node_a; + /export/ ref_base_node_b: &base_node_b; + }; + }; + + node-d { + + /export/ ref_base_node_c: &base_node_c; + }; +}; diff --git a/tests/run_tests.sh b/tests/run_tests.sh index 0c5f2849..f61f3e91 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -1249,7 +1249,8 @@ fdtoverlay_tests() { =20 metadata_tests() { for dt in metadata_propdata_phandle_local metadata_propdata_phandle_ref \ - metadata_addon_base metadata_exportsyms_local; do + metadata_addon_base metadata_exportsyms_local \ + metadata_exportsyms_ref; do run_dtc_test -I dts -O dts -o $dt.dts.dts "$SRCDIR/$dt.dts" base_run_test check_diff $dt.dts.dts "$SRCDIR/$dt.dts.dts.expect" run_dtc_test -I dts -O dtb -o $dt.dtb "$SRCDIR/$dt.dts" --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EF89B3E1736; Wed, 26 Aug 2026 09:52:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737922; cv=none; b=jHwVemDxliTEusB5BjooFe6ELuP68ka8NonYnIKMHq7ONu3LT/4zPWbbr6zjiWwhrl8pUhQCzgCmIxb+cKbULCgOmjZvp4olnSjLI0Cqa1v7BkEBCAChJ+8MobW71ieYZSatJCDptQh8ZfjVy9N2qKkEyPvFMj+l4qida4YMQDE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737922; c=relaxed/simple; bh=YrRB78bDzAxToXsFsesV2URHsP4n3DYGrpsb260vml4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Hz2c5rUL6tAq5WKSb3rExW1IHZ/o/ObTmyjs13X4dNTW/nQHcvM1mh02Gkr5YzfDrMFQF8EZiXPYyHYSCJMU0dbCMKJBx4x7nfzBt4AJugB9DumOmwpWqGRtY6ULXY2fVTj4ZBgh9NZYFAb4cHV0bHMS/j/2qg85DMh2Ng+0SiQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=luGhI7wX; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="luGhI7wX" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 76FE81A183D; Wed, 26 Aug 2026 09:51:59 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 4BB39604EC; Wed, 26 Aug 2026 09:51:59 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id CC9E811C7AD64; Wed, 26 Aug 2026 11:51:56 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737918; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=EVUIWjyZYaqFgmFKnR8vrxTiryS29hhPQyy6WYDQ8t8=; b=luGhI7wXU4MKqinBsWsd+kKq3XreXoVsTnov3sCAjqo8U/QxQ17RJ6PjopnUcO95jGrRpw CzI5/31RYc08neOV4Qyt25v8nKxk09TSSu8jI1eU7WiKsKhk5AKvvCWO0H9Pi5RDsRsgS4 DJm2IbDv2wGHIr7fE7jwO2rSlrtuO53jGmm3GUdid1i4S3sj7SgZfGab2qSXfQ9qDrNsCK TmqQerD8A6jMMyHI5/A7llznzgW4bIUr6eFQ+jQ5RtA0qD4F1DUgfTHVeUYY77YXsFi3Ua vfSHIYw6HaAfkFPN1LQew9Dx3SPzLohsiN6v0NNZhAPLMz/vaPUMUQFS+XGQHA== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 27/74] dtc: Introduce import symbols Date: Wed, 26 Aug 2026 11:48:56 +0200 Message-ID: <20260826094950.1088288-28-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" Import symbols allow to define a list of symbols imported and used by an addon. Those symbols have to be resolved when the addon is applied on a base device-tree and will involved exported symbols provided at the node the addon is applied to. Import symbols are similar in term of feature to __fixups__ available in device-tree overlays. The goal is to identify symbols which are used by an addon but not defined by the addon itself. Those specific symbols are the imported symbols. Introduce the import symbols list related to an addon. No functional change yet but preparation for the future support for import symbol parsing. Signed-off-by: Herve Codina --- dtc-parser.y | 3 ++- dtc.h | 4 +++- flattree.c | 2 +- fstree.c | 2 +- livetree.c | 4 +++- 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/dtc-parser.y b/dtc-parser.y index a0d0aef9..4e46e9d1 100644 --- a/dtc-parser.y +++ b/dtc-parser.y @@ -113,7 +113,8 @@ sourcefile: headers memreserves devicetree { parser_output =3D build_dt_info($1, $2, $3, - guess_boot_cpuid($3)); + guess_boot_cpuid($3), + NULL); } ; =20 diff --git a/dtc.h b/dtc.h index 8a20d6da..63fe4dc1 100644 --- a/dtc.h +++ b/dtc.h @@ -350,6 +350,7 @@ struct dt_info { struct reserve_info *reservelist; uint32_t boot_cpuid_phys; struct node *dt; /* the device tree */ + struct symbol *importsymlist; /* Import symbol list */ const char *outname; /* filename being written to, "-" for stdout */ }; =20 @@ -360,7 +361,8 @@ struct dt_info { =20 struct dt_info *build_dt_info(unsigned int dtsflags, struct reserve_info *reservelist, - struct node *tree, uint32_t boot_cpuid_phys); + struct node *tree, uint32_t boot_cpuid_phys, + struct symbol *importsymlist); void sort_tree(struct dt_info *dti); void generate_labels_from_tree(struct dt_info *dti, const char *name); void generate_label_tree(struct dt_info *dti, const char *name, bool alloc= ph); diff --git a/flattree.c b/flattree.c index 4e4727e9..45dc4ed4 100644 --- a/flattree.c +++ b/flattree.c @@ -1241,5 +1241,5 @@ struct dt_info *dt_from_blob(const char *fname) if (get_subnode(tree, "__fixups__") || get_subnode(tree, "__local_fixups_= _")) dtsflags |=3D DTSF_PLUGIN; =20 - return build_dt_info(dtsflags, reservelist, tree, boot_cpuid_phys); + return build_dt_info(dtsflags, reservelist, tree, boot_cpuid_phys, NULL); } diff --git a/fstree.c b/fstree.c index 445ae53a..a6aaf1e8 100644 --- a/fstree.c +++ b/fstree.c @@ -72,5 +72,5 @@ struct dt_info *dt_from_fs(const char *dirname) tree =3D read_fstree(dirname); tree =3D name_node(tree, ""); =20 - return build_dt_info(DTSF_V1, NULL, tree, guess_boot_cpuid(tree)); + return build_dt_info(DTSF_V1, NULL, tree, guess_boot_cpuid(tree), NULL); } diff --git a/livetree.c b/livetree.c index fe0f300b..a6c40642 100644 --- a/livetree.c +++ b/livetree.c @@ -635,7 +635,8 @@ static void complete_references(struct dt_info *dti) =20 struct dt_info *build_dt_info(unsigned int dtsflags, struct reserve_info *reservelist, - struct node *tree, uint32_t boot_cpuid_phys) + struct node *tree, uint32_t boot_cpuid_phys, + struct symbol *importsymlist) { struct dt_info *dti; =20 @@ -644,6 +645,7 @@ struct dt_info *build_dt_info(unsigned int dtsflags, dti->reservelist =3D reservelist; dti->dt =3D tree; dti->boot_cpuid_phys =3D boot_cpuid_phys; + dti->importsymlist =3D importsymlist; =20 fill_fullpaths(dti->dt, ""); =20 --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 23A183E49F7; Wed, 26 Aug 2026 09:52:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737927; cv=none; b=QOubHbtgPwZotyzHOthhOFyFPG762SAxfBPlgLZHms82eyQp3ZSC0mosra9wLW+Kkn7kOBr0sp9Ehi7cTCvN0XY/qEbhs32MXIQSlnO1/V7pDwLSzStQ2eOxpOasH1acGl/6S1ofkDVyC9PfXui27zJbpm9Ch/yAKorgjE62VrE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737927; c=relaxed/simple; bh=EmQ0g7cS+QClPGXEJX25jQzFzQ51QqjpWNGXNcFuaaQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jG0RvWW+45Nm5v7JdRzht0fNggI2D2Y2GoUSqHroyhH0EWffmSmgH1hziuTQOu/2MA8PQTfELd4AbNf3tReg7ueo4YHb22Q5r+LADa63kpOw9ZFZEjFleO45TB9THBUog5ZrdYKSmjvdH8J/e3t5F3titWiEBPq0whqGEuM5IyE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=ql0M1n9R; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="ql0M1n9R" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 71FAA4E413C2; Wed, 26 Aug 2026 09:52:01 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 40B2D604EC; Wed, 26 Aug 2026 09:52:01 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 9EC0711C7AD65; Wed, 26 Aug 2026 11:51:58 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737920; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=5zYtjI4st3gy8QUaislC3i8xU3pzXq4DgBUMQ/lQS3o=; b=ql0M1n9RXKlfeVlEFy/4BijXbKwyE1eGTkVzwcNuxYmxdbuZMPhucIyTHgNfHGBEtg6PL4 thGJtUpGCqyDnmFGe5pso5La+yBLCzKKZRLffm/qaR+GZV6WLRXHgW1otDs3I+qgCCbeQM NzE4YH/TejQh/6XheX8gNn9KkYlFgbw/g4C7a4WoRhiMUc7ARy13yUnx7i4+PusgRqsEyI 42Q0TYn6XdKvDKLjQOiUZI8//B8Fg4L9rElHlHMuweCWAxDzG5j9fyZxUhrmV+Jhx62p/8 EKm8hsoblwrOlv26sRg6jDovNwGKC6NqhQIW0MM75N/N0Tzbf9BNArcvbanohA== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 28/74] dtc-parser: Introduce last_header_flags Date: Wed, 26 Aug 2026 11:48:57 +0200 Message-ID: <20260826094950.1088288-29-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" The parser needs to get header flags value in different places. It relies on the fact that the rule used to parse the dts file is always headers memreserves devicetree With that only rule to parse the file, it uses '$-1' construct to get the flags value. With the future introduction of import symbols parsing, this rule will change and the parser couldn't rely anymore on '$-1' to get flags value. Indeed, import symbols parsing will add a new optional symbol in this rule leading to two possible rules (with and without the new symbol) to parse the source file. Introduce the last_header_flags variable to explicitly keep track of flags while also being agnostic of the rule structure and use this new variable instead of '$-1'. Signed-off-by: Herve Codina --- dtc-parser.y | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/dtc-parser.y b/dtc-parser.y index 4e46e9d1..48c40e81 100644 --- a/dtc-parser.y +++ b/dtc-parser.y @@ -24,6 +24,8 @@ extern void yyerror(char const *s); extern struct dt_info *parser_output; extern bool treesource_error; =20 +unsigned int last_header_flags; + static bool is_ref_relative(const char *ref) { return ref[0] !=3D '/' && strchr(&ref[1], '/'); @@ -122,14 +124,17 @@ header: DT_V1 ';' { $$ =3D DTSF_V1; + last_header_flags =3D $$; } | DT_V1 ';' DT_PLUGIN ';' { $$ =3D DTSF_V1 | DTSF_PLUGIN; + last_header_flags =3D $$; } | DT_V1 ';' DT_ADDON ';' { $$ =3D DTSF_V1 | DTSF_ADDON; + last_header_flags =3D $$; } ; =20 @@ -179,12 +184,7 @@ devicetree: } | dt_ref nodedef { - /* - * We rely on the rule being always: - * versioninfo plugindecl memreserves devicetree - * so $-1 is what we want (plugindecl) - */ - if (!($-1 & DTSF_PLUGIN)) + if (!(last_header_flags & DTSF_PLUGIN)) ERROR(&@2, "Label or path %s not found", $1); else if (is_ref_relative($1)) ERROR(&@2, "Label-relative reference %s not supported in plugin", $1); @@ -197,7 +197,7 @@ devicetree: { struct node *target =3D get_node_by_ref($1, $3); =20 - if (($-1 & DTSF_PLUGIN) && is_ref_relative($3)) + if ((last_header_flags & DTSF_PLUGIN) && is_ref_relative($3)) ERROR(&@2, "Label-relative reference %s not supported in plugin", $3); =20 if (target) { @@ -209,12 +209,7 @@ devicetree: } | devicetree DT_PATH_REF nodedef { - /* - * We rely on the rule being always: - * versioninfo plugindecl memreserves devicetree - * so $-1 is what we want (plugindecl) - */ - if ($-1 & DTSF_PLUGIN) { + if (last_header_flags & DTSF_PLUGIN) { if (is_ref_relative($2)) ERROR(&@2, "Label-relative reference %s not supported in plugin", $2); add_orphan_node($1, $3, $2); @@ -235,12 +230,7 @@ devicetree: if (target) { merge_nodes(target, $3); } else { - /* - * We rely on the rule being always: - * versioninfo plugindecl memreserves devicetree - * so $-1 is what we want (plugindecl) - */ - if ($-1 & DTSF_PLUGIN) + if (last_header_flags & DTSF_PLUGIN) add_orphan_node($1, $3, $2); else ERROR(&@2, "Label or path %s not found", $2); --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D45F13BF69E for ; Wed, 26 Aug 2026 09:52:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737933; cv=none; b=ul0H6unf8RkG16OiQ6hlALtthNsXQhQ3mFlf8Nu1g38vkv/nEmVbKgSDbCwi1ci440PdPNwCGvaVoU9iLSacWS0hzCdE9ht2HLH2j+hn8/h9RVTX35XeeiGpuRdllP62HpIik0bOqnTVI97i7S5BGVniF9gEzsENI/oB1IZnLvs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737933; c=relaxed/simple; bh=IDL8S9arxDp+eFsP3awElt8B4Ute9+D8mp9mKr5e6VM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=In5C0Vzr3WelhpIRHqeJGdhkE/uOgTFuvszq9Jw3D68lO51YOn51f1VvYF6SIN5OINVv7zVXAFapZ1oq92mJ7Jt3ohbCnr4LfHM987fyp2hRzCgh1mzxc7km004GB9m5aKZKGUyWJ4fVb+W9RBp/jf3NmxoOV/Yo26ZS1zOZhG8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=mQtHIAOT; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="mQtHIAOT" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 563591A183D; Wed, 26 Aug 2026 09:52:03 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 247C6604EC; Wed, 26 Aug 2026 09:52:03 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id EB72011C7AD67; Wed, 26 Aug 2026 11:52:00 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737922; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=0MEIiww7ZG8Q9mriq6yTwWHecJWVxx5LBg4A6l0T8/4=; b=mQtHIAOTv6CkgvZYacZeLaHm1dJmOYvm3OB+ZmCTKkqbeXf740QHYr9n5AwFceJwbioJUo CFdYWqm4tGaundfYmZYyY98guQWmiwFU4Tc/naWR4jldc9wrVV6ytre1LQQuvmXF5a5y61 wvut2fAFTsY7neIS1Cr5gqBEupJH75s4mrV9LILp77WWJh0BJWawYtPqTQ5QY6aakJjK3o ZU9VJrF8slQKXpsQIsoWLzQbPV9vJWzs1HnttfiYiAqkDQcX4FB1Kul2PLxvP1mbY75Fzm I09ruH+14nR2/CcuS0OkFxR0VB9SE9J9DV+sYOfwHbAOZesKVVloD0B5piKDnw== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 29/74] dtc: Add support for /import/ dts keyword parsing Date: Wed, 26 Aug 2026 11:48:58 +0200 Message-ID: <20260826094950.1088288-30-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" The /import/ dts keyword is the keyword used to define an imported symbol used by an addon device-tree. An imported symbol is not related to a specific node and it is global to a whole addon. It can be present after the header definition (and the possible memreserves definition) and before the devicetree nodes definition. If several symbols are imported, several /import/ keyword are present. The syntax used is the following: /import/ name: compatible; with: name: The name of the imported symbol compatible: a string indicating the kind of symbol is expected. This compatible string can be used when the addon is applied in order to help the symbol resolution. For instance: /import/ foo: "bar, foo"; The foo symbol is expected by the addon and should be "bar, foo" compatible. The addon uses this symbol (i.e. it references it) but it doesn't define the symbol itself. From the addon point of view, foo is an unresolved symbol and it will be resolved when the addon is applied. Add support for /import/ dts keyword. Signed-off-by: Herve Codina --- dtc-lexer.l | 6 ++++++ dtc-parser.y | 45 +++++++++++++++++++++++++++++++++++++++++++++ dtc.h | 3 +++ livetree.c | 13 +++++++++++++ 4 files changed, 67 insertions(+) diff --git a/dtc-lexer.l b/dtc-lexer.l index 3c3f3413..f21ae00d 100644 --- a/dtc-lexer.l +++ b/dtc-lexer.l @@ -152,6 +152,12 @@ static void PRINTF(1, 2) lexical_error(const char *fmt= , ...); return DT_EXPORT; } =20 +<*>"/import/" { + DPRINT("Keyword: /import/\n"); + BEGIN_DEFAULT(); + return DT_IMPORT; + } + <*>{LABEL}: { DPRINT("Label: %s\n", yytext); yylval.labelref =3D xstrdup(yytext); diff --git a/dtc-parser.y b/dtc-parser.y index 48c40e81..61ebde2d 100644 --- a/dtc-parser.y +++ b/dtc-parser.y @@ -50,6 +50,7 @@ static bool is_ref_relative(const char *ref) struct node *nodelist; struct symbol *symbol; struct symbol *exportlist; + struct symbol *importlist; struct reserve_info *re; uint64_t integer; unsigned int flags; @@ -65,6 +66,7 @@ static bool is_ref_relative(const char *ref) %token DT_DEL_NODE %token DT_OMIT_NO_REF %token DT_EXPORT +%token DT_IMPORT %token DT_PROPNODENAME %token DT_LITERAL %token DT_CHAR_LITERAL @@ -87,6 +89,8 @@ static bool is_ref_relative(const char *ref) %type proplist %type exportdef %type exportlist +%type importdef +%type importlist %type dt_ref =20 %type devicetree @@ -118,6 +122,17 @@ sourcefile: guess_boot_cpuid($3), NULL); } + | headers memreserves importlist devicetree + { + /* + * importlist is created with chain_symbol() and so it + * is created in reverse order. Reverse it now to have + * it in correct order + */ + parser_output =3D build_dt_info($1, $2, $4, + $4 ? guess_boot_cpuid($4) : 0, + reverse_symbol($3)); + } ; =20 header: @@ -171,6 +186,36 @@ memreserve: } ; =20 +importlist: + importdef + { + $$ =3D chain_symbol($1, NULL); + } + | importlist importdef + { + $$ =3D chain_symbol($2, $1); + } + | importlist memreserve + { + ERROR(&@2, "Mem reserve must precede imports"); + YYERROR; + } + ; + +importdef: + DT_IMPORT DT_LABEL DT_STRING ';' + { + struct data d =3D $3; + + if (!(last_header_flags & DTSF_ADDON)) + ERROR(&@2, "Import symbols supported only in addon"); + + $$ =3D build_importsym($2, d.val, &@$); + free($2); + data_free($3); + } + ; + dt_ref: DT_LABEL_REF | DT_PATH_REF; =20 devicetree: diff --git a/dtc.h b/dtc.h index 63fe4dc1..61521329 100644 --- a/dtc.h +++ b/dtc.h @@ -207,6 +207,7 @@ struct label { struct symbol { bool is_local; char *name; + char *compatible; char *ref; cell_t phandle; char *fullpath; @@ -287,6 +288,8 @@ struct property *reverse_properties(struct property *fi= rst); =20 struct symbol *build_exportsym(const char *name, const char *ref, cell_t p= handle, struct srcpos *srcpos); +struct symbol *build_importsym(const char *name, const char *compatible, + struct srcpos *srcpos); struct symbol *chain_symbol(struct symbol *first, struct symbol *list); struct symbol *reverse_symbol(struct symbol *list); void add_symbol(struct symbol **list, struct symbol *new); diff --git a/livetree.c b/livetree.c index a6c40642..30344fb8 100644 --- a/livetree.c +++ b/livetree.c @@ -51,6 +51,19 @@ struct symbol *build_exportsym(const char *name, const c= har *ref, cell_t phandle return new; } =20 +struct symbol *build_importsym(const char *name, const char *compatible, s= truct srcpos *srcpos) +{ + struct symbol *new =3D xmalloc(sizeof(*new)); + + memset(new, 0, sizeof(*new)); + + new->name =3D xstrdup(name); + new->compatible =3D xstrdup(compatible); + new->srcpos =3D srcpos_copy(srcpos); + + return new; +} + struct symbol *chain_symbol(struct symbol *first, struct symbol *list) { assert(first->next =3D=3D NULL); --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 66ECB3E49D3; Wed, 26 Aug 2026 09:52:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737930; cv=none; b=muJKhp+c+aotsdlqYPPnt7Hl4Iadirc5xKkf6wOGuW+j7QrI7HUWgMgkkWjpZ410HLEsMt0/OEpyplqmCgmKm+QNxoVtRezDCvz6UtYblPK0zITmP5tRvpcb980qRpEfwJlRJJHhLyfCNwcQMnGWUERCr1agpZMNuAhW48dCNM4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737930; c=relaxed/simple; bh=7gcOUZmUZJS2NLjclVPmerJZlhX2Lo8QV9jN+n9wx8E=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=USgA+JBHlbobRs1oFm3lvkl05KJ996kzgK2M27XF6K9uuGAYtwcWlBVerNZJ88Z6i8VhWdTu+fMIeyqfB/ojFNrIjBTW6GuWAew3s4CbpIe05VHsmHiXwrPQPsATupmZOnrtSW5RF0WcB9ZeTUnRQ/BI1tYqmzIo1y9dMVC8Z5A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=u1V114eV; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="u1V114eV" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 4391F4E413BC; Wed, 26 Aug 2026 09:52:05 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 18ACB604EC; Wed, 26 Aug 2026 09:52:05 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id BFD1F11C7AD66; Wed, 26 Aug 2026 11:52:02 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737924; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=t+VqTYvZ2BOAv4Bsz9T43U13SrmgT19IW2wnO3wG0a4=; b=u1V114eV5aMyKJ/owt7NvLTN3B5d1sp7Vg3ANRUc9Wa2lah1S9mMDoHHh8rYLZ9fkcRJ8x Imc2DbeIKVwvbRD48oBjHa6HGd1VCdA/vmjs4914xf5j/povkI9h6w4hngxezx02tLkvaK 92EFhgVnQK6kc5RX1GUI7ivnfIksjHD8Qs1H7vaA3ZAEu8uNmNx7FZFIMSOWXHNTQtt5gg oJVxVXsp2aQTFYeLPxAyQW0Jwidb4rRBwSEK7qEt1rvYwGNKQAeXvXzY6h+gPZ3UNurgTF bCiHpvfAQyj7cpk41/kt8JUNFSg4Vbif7NsxWQZYbWOElGnW/hNSBxcKVqoR5A== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 30/74] dtc: Add import symbols (/import/ keyword) in generated dts file Date: Wed, 26 Aug 2026 11:48:59 +0200 Message-ID: <20260826094950.1088288-31-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" The import symbols (/import/ keyword) parsing from a dts file is supported. Add the support for this keyword in the dts file generation. Signed-off-by: Herve Codina --- treesource.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/treesource.c b/treesource.c index a7228f60..d22f1d32 100644 --- a/treesource.c +++ b/treesource.c @@ -431,6 +431,7 @@ static void write_tree_source_node(FILE *f, struct node= *tree, int level) void dt_to_source(FILE *f, struct dt_info *dti) { struct reserve_info *re; + struct symbol *importsym; =20 fprintf(f, "/dts-v1/;\n"); /* @@ -453,5 +454,14 @@ void dt_to_source(FILE *f, struct dt_info *dti) (unsigned long long)re->size); } =20 + if (dti->importsymlist) { + for_each_symbol(dti->importsymlist, importsym) { + fprintf(f, "/import/ %s: \"%s\";\n", + importsym->name, + importsym->compatible); + } + fprintf(f, "\n"); + } + write_tree_source_node(f, dti->dt, 0); } --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D0BC33CBE74; Wed, 26 Aug 2026 09:52:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737934; cv=none; b=OHrf8N0m6GjvefF4kpGKddSJufxlTc4ODrN3Ukp3UEKof0mqCLVBuRAQV5qPkdVm7L+YdmB57/Y6J7bgluJlXxqwdij+6g0h9GZTeiq91L3ov6nQ7r+HClfA3NkxWhDYfaxeLVcoaOepEaItGmMRO5K1ln4Fo9Y8oypwyOBQmyU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737934; c=relaxed/simple; bh=BJ8Fj//sItWxO6bAsVqoNzg9t0tUvTN/tXDeI8l+eu8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=CHkD3HWhEByePM8H9VSpBaxhk7eD2qvGMIZjlavk3L7Rch/1daATpAMX/iGyBHVXzMNCFpxZ3X8xzgnD+oIFXolz21fgI+KyXVqIkP2+dz/Gx3eG3h2tj33lSS3qyXCmkHo8hnbF0WtvTwZx1otAhSEKHR1ytTDRSIjgEMKFMuA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=VZuRxuea; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="VZuRxuea" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 632EC1A183F; Wed, 26 Aug 2026 09:52:07 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 30332604EC; Wed, 26 Aug 2026 09:52:07 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id CB8D011C7AD68; Wed, 26 Aug 2026 11:52:04 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737926; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=hPRG4NHI02HcgZlEIXYdMfsHxz79JcKMx5zp7Mcw034=; b=VZuRxueaT67YacXdi1ll1qooce+qLKCKRRQ45OytD68Stn94Fbp4rObNX/8n6urYJiULbb Ljy/Oi0sao+EStoRrcoeWedE40f47uNiKpT8isZHwTpnW7o2aI1EHWKXWCCG4MQhdAJJDG tDQtbIoZUL3wS9rsjQ/ppZIHr9VygbUEX5/zOw6fJeQq5vDNB00mIlP9Cr7ziEptl7v3r1 m+lKwPCbWPnIhUUBMTEJrwOpmrNI+OoyGyhQ8yl3ffhCUPVX/XerPye4wuOUQZuEfUbOMl QAOdqkt3MyZ/umwut+q3ZTiEXWRCbi/12CDqXs+kWvWxDKB336t6xrxLLDktLQ== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 31/74] Add support for FDT_IMPORT_SYM dtb tag Date: Wed, 26 Aug 2026 11:49:00 +0200 Message-ID: <20260826094950.1088288-32-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" The FDT_IMPORT_SYM dtb tag is a meta-data tag defining an imported symbol. It can be present globally in an addon dtb (i.e. outside nodes definition) meaning that this symbol needs to be resolved when the dtb is applied. The tag is followed by the length of the data part (structured tag), two values and possible alignment paddings: - data part length (32bit): strlen(name) + 1 + strlen(compatible) + 1 - name (string including \0) The import symbol name. I.e. the name used to reference this imported symbol. - compatible (string including \0) The compatible string that can be used for symbol resolution. This string can be an empty string if it is not relevant. - padding: Padding (0x00) added to have the next value aligned on 32bit. Example: FDT_IMPORT_SYM 13 'foo1' 'bar,foo' 0x00 0x00 0x00 This means that 'foo1' is an imported symbol and it is 'bar,foo' compatible. This is what is encoded in the dtb when the related dts has the following imported symbol defined: /import/ foo1: "bar,foo"; If several symbols are imported, several FDT_IMPORT_SYM are present. Each of them defining one imported symbol. For instance, importing 'foo1' ("bar,foo" compatible) and 'baz' ("bar,baz" compatible) leads to the following sequence: FDT_IMPORT_SYM 13 'foo1' 'bar,foo' 0x00 0x00 0x00 FDT_IMPORT_SYM 12 'baz' 'bar,baz' If FDT_IMPORT_SYM tags are present in the dtb, they are present after the root node definition (i.e. after the FDT_END_NODE related to the first FDT_BEGIN_NODE). Add support for this new dtb tag. Signed-off-by: Herve Codina --- fdtdump.c | 10 ++++++ flattree.c | 76 +++++++++++++++++++++++++++++++++++++++++++++- libfdt/fdt.c | 30 ++++++++++++++++++ libfdt/fdt.h | 14 +++++++++ libfdt/fdt_check.c | 56 +++++++++++++++++++++++++++++----- 5 files changed, 177 insertions(+), 9 deletions(-) diff --git a/fdtdump.c b/fdtdump.c index db5b53dc..7e4c244d 100644 --- a/fdtdump.c +++ b/fdtdump.c @@ -224,6 +224,16 @@ static void dump_blob(void *blob, bool debug, int dump= _unknown) continue; } =20 + if (tag =3D=3D FDT_IMPORT_SYM) { + p =3D get_structured_tag_data(tag, p, &d, &sz); + s =3D d; + d =3D d + strlen(s) + 1; + t =3D d; + printf("%*s// [FDT_IMPORT_SYM] '%s' (%s)\n", depth * shift, "", + s, t); + continue; + } + if ((tag & FDT_TAG_STRUCTURED) && (tag & FDT_TAG_SKIP_SAFE)) { p =3D get_structured_tag_data(tag, p, &d, &sz); =20 diff --git a/flattree.c b/flattree.c index 45dc4ed4..4f4a185a 100644 --- a/flattree.c +++ b/flattree.c @@ -55,6 +55,7 @@ struct emitter { void (*propdata_phandle_ref)(void *); void (*export_sym)(void *); void (*export_sym_ref)(void *); + void (*import_sym)(void *); }; =20 static void bin_emit_cell(void *e, cell_t val) @@ -124,6 +125,11 @@ static void bin_emit_export_sym_ref(void *e) bin_emit_cell(e, FDT_EXPORT_SYM_REF); } =20 +static void bin_emit_import_sym(void *e) +{ + bin_emit_cell(e, FDT_IMPORT_SYM); +} + static struct emitter bin_emitter =3D { .cell =3D bin_emit_cell, .string =3D bin_emit_string, @@ -136,6 +142,7 @@ static struct emitter bin_emitter =3D { .propdata_phandle_ref =3D bin_emit_propdata_phandle_ref, .export_sym =3D bin_emit_export_sym, .export_sym_ref =3D bin_emit_export_sym_ref, + .import_sym =3D bin_emit_import_sym, }; =20 static void emit_label(FILE *f, const char *prefix, const char *label) @@ -279,6 +286,17 @@ static void asm_emit_export_sym_ref(void *e) asm_emit_cell(e, FDT_EXPORT_SYM_REF); } =20 +static void asm_emit_import_sym(void *e) +{ + /* + * Import symbols are an feature introduced for addons. + * Addons device-tree blob have to reason to be in the asm format. + * + * Need to be implemented if really needed. + */ + die("FDT_IMPORT_SYM not supported in asm output\n"); +} + static struct emitter asm_emitter =3D { .cell =3D asm_emit_cell, .string =3D asm_emit_string, @@ -291,6 +309,7 @@ static struct emitter asm_emitter =3D { .propdata_phandle_ref =3D asm_emit_propdata_phandle_ref, .export_sym =3D asm_emit_export_sym, .export_sym_ref =3D asm_emit_export_sym_ref, + .import_sym =3D asm_emit_import_sym, }; =20 static int stringtable_insert(struct data *d, const char *str) @@ -470,6 +489,27 @@ static void make_fdt_header(struct fdt_header *fdt, fdt->last_comp_version_w =3D cpu_to_fdt32(vi->last_comp_version_w); } =20 +static void flatten_imports(struct symbol *importsymlist, struct emitter *= emit, + void *etarget, struct version_info *vi, uint32_t dt_flags) +{ + struct symbol *importsym; + + if (!(vi->flags & FTF_EXPORT_IMPORT_SYM)) + return; + + if (!(dt_flags & FDT_FLAG_ADDON) && importsymlist) + die("Only addons can have an import list\n"); + + for_each_symbol(importsymlist, importsym) { + emit->import_sym(etarget); + emit->cell(etarget, strlen(importsym->name) + 1 + + strlen(importsym->compatible) + 1); + emit->string(etarget, importsym->name, 0); + emit->string(etarget, importsym->compatible, 0); + emit->align(etarget, sizeof(cell_t)); + } +} + void dt_to_blob(FILE *f, struct dt_info *dti, int version) { struct version_info *vi =3D NULL; @@ -492,6 +532,7 @@ void dt_to_blob(FILE *f, struct dt_info *dti, int versi= on) dt_flags |=3D dti->dtsflags & DTSF_ADDON ? FDT_FLAG_ADDON : 0; =20 flatten_tree(dti->dt, &bin_emitter, &dtbuf, &strbuf, vi); + flatten_imports(dti->importsymlist, &bin_emitter, &dtbuf, vi, dt_flags); bin_emit_cell(&dtbuf, FDT_END); =20 reservebuf =3D flatten_reserve_list(dti->reservelist, vi); @@ -583,6 +624,9 @@ void dt_to_asm(FILE *f, struct dt_info *dti, int versio= n) const char *symprefix =3D "dt"; uint32_t dt_flags =3D 0; =20 + if (dti->importsymlist) + die("Import symbols not supported in asm format\n"); + for (i =3D 0; i < ARRAY_SIZE(version_table); i++) { if (version_table[i].version =3D=3D version) vi =3D &version_table[i]; @@ -808,6 +852,7 @@ static uint32_t flat_read_tag(struct inbuf *inb) case FDT_PROPDATA_PHANDLE_REF: case FDT_EXPORT_SYM: case FDT_EXPORT_SYM_REF: + case FDT_IMPORT_SYM: return tag; default: break; @@ -903,6 +948,22 @@ static struct property *flat_read_property(struct inbu= f *dtbuf, return build_property(name, val, NULL); } =20 +static struct symbol *flat_read_importsym(struct inbuf *inb) +{ + struct inbuf subbuf; + uint32_t len; + const char *name; + const char *compatible; + + len =3D flat_read_word(inb); + flat_read_subbuf(inb, &subbuf, len); + flat_realign(inb, sizeof(uint32_t)); + + name =3D flat_read_string_norealign(&subbuf); + compatible =3D flat_read_string_norealign(&subbuf); + + return build_importsym(name, compatible, NULL); +} =20 static struct reserve_info *flat_read_mem_reserve(struct inbuf *inb) { @@ -1115,6 +1176,8 @@ struct dt_info *dt_from_blob(const char *fname) int sizeleft; struct reserve_info *reservelist; struct node *tree; + struct symbol *importsymlist =3D NULL; + struct symbol *importsym; uint32_t val; int flags =3D 0; unsigned int dtsflags =3D DTSF_V1; @@ -1231,6 +1294,17 @@ struct dt_info *dt_from_blob(const char *fname) tree =3D unflatten_tree(&dtbuf, &strbuf, "", flags); =20 val =3D flat_read_tag(&dtbuf); + + if (dtsflags & DTSF_ADDON) { + if (flags & FTF_EXPORT_IMPORT_SYM) { + while (val =3D=3D FDT_IMPORT_SYM) { + importsym =3D flat_read_importsym(&dtbuf); + add_symbol(&importsymlist, importsym); + val =3D flat_read_tag(&dtbuf); + } + } + } + if (val !=3D FDT_END) die("Device tree blob doesn't end with FDT_END\n"); =20 @@ -1241,5 +1315,5 @@ struct dt_info *dt_from_blob(const char *fname) if (get_subnode(tree, "__fixups__") || get_subnode(tree, "__local_fixups_= _")) dtsflags |=3D DTSF_PLUGIN; =20 - return build_dt_info(dtsflags, reservelist, tree, boot_cpuid_phys, NULL); + return build_dt_info(dtsflags, reservelist, tree, boot_cpuid_phys, import= symlist); } diff --git a/libfdt/fdt.c b/libfdt/fdt.c index 9bab9149..b48c3248 100644 --- a/libfdt/fdt.c +++ b/libfdt/fdt.c @@ -363,6 +363,34 @@ static uint32_t fdt_next_tag_all(const void *fdt, int = startoffset, int *nextoffs offset =3D sum; break; =20 + case FDT_IMPORT_SYM: + tmp_offset =3D fdt_get_structured_tag_data(tag, fdt, offset, &len); + if (tmp_offset < 0) + return FDT_END; /* premature end */ + + sum =3D tmp_offset + len; + + /* Check name */ + do { + p =3D fdt_offset_ptr(fdt, tmp_offset++, 1); + } while (p && (*p !=3D '\0')); + if (!can_assume(VALID_DTB) && !p) + return FDT_END; /* premature end */ + + /* Check compatible */ + do { + p =3D fdt_offset_ptr(fdt, tmp_offset++, 1); + } while (p && (*p !=3D '\0')); + if (!can_assume(VALID_DTB) && !p) + return FDT_END; /* premature end */ + + if (!can_assume(VALID_INPUT) && (uint32_t)tmp_offset > sum) + return FDT_END; /* premature end */ + + /* Skip the whole data bloc */ + offset =3D sum; + break; + default: if (!(tag & FDT_TAG_STRUCTURED) || !(tag & FDT_TAG_SKIP_SAFE)) return FDT_END; @@ -395,6 +423,7 @@ static bool fdt_tag_is_unknown(uint32_t tag) case FDT_PROPDATA_PHANDLE_REF: case FDT_EXPORT_SYM: case FDT_EXPORT_SYM_REF: + case FDT_IMPORT_SYM: return false; default: break; @@ -452,6 +481,7 @@ bool fdt_tag_filter_skip_metadata(void *data, uint32_t = tag) case FDT_PROPDATA_PHANDLE_REF: case FDT_EXPORT_SYM: case FDT_EXPORT_SYM_REF: + case FDT_IMPORT_SYM: return true; =20 default: diff --git a/libfdt/fdt.h b/libfdt/fdt.h index 624491a0..04f47784 100644 --- a/libfdt/fdt.h +++ b/libfdt/fdt.h @@ -140,6 +140,20 @@ struct fdt_property { */ #define FDT_EXPORT_SYM_REF FDT_TAG_CAN_SKIP(FDT_TAG_DATA_VARLEN, 0x2001) =20 +/* + * Import symbol tag (meta-data). varlen: name, compatible + * + * It defines an imported symbol. It can be present globally in an addon d= tb + * (i.e. outside nodes definition) meaning that this symbol needs to be re= solved + * when the dtb is applied. + * + * name: import symbol name, i.e. the name used to reference this imported + * symbol. + * compatible: compatible string that can be used for symbol resolution. + * This string can be an empty string if it is not relevant. + */ +#define FDT_IMPORT_SYM FDT_TAG_CAN_SKIP(FDT_TAG_DATA_VARLEN, 0x2100) + #define FDT_V1_SIZE (7*sizeof(fdt32_t)) #define FDT_V2_SIZE (FDT_V1_SIZE + sizeof(fdt32_t)) #define FDT_V3_SIZE (FDT_V2_SIZE + sizeof(fdt32_t)) diff --git a/libfdt/fdt_check.c b/libfdt/fdt_check.c index 19b35c8b..7ce3fdd2 100644 --- a/libfdt/fdt_check.c +++ b/libfdt/fdt_check.c @@ -20,8 +20,9 @@ int fdt_check_full(const void *fdt, size_t bufsize) const void *prop =3D NULL; const char *propname; int proplen; - bool expect_end =3D false; + bool root_node_found =3D false; bool subnode_found =3D false; + bool import_sym_found =3D false; const fdt32_t *pfdt32; const char *str; uint32_t val; @@ -50,10 +51,6 @@ int fdt_check_full(const void *fdt, size_t bufsize) if (nextoffset < 0) return nextoffset; =20 - /* If we see two root nodes, something is wrong */ - if (expect_end && tag !=3D FDT_END && tag !=3D FDT_NOP) - return -FDT_ERR_BADSTRUCTURE; - switch (tag) { case FDT_NOP: break; @@ -70,10 +67,20 @@ int fdt_check_full(const void *fdt, size_t bufsize) if (depth > INT_MAX) return -FDT_ERR_BADSTRUCTURE; =20 - /* The root node must have an empty name */ + /* Root node specific checks */ if (depth =3D=3D 1) { const char *name; =20 + /* If we see two root nodes, something is wrong */ + if (root_node_found) + return -FDT_ERR_BADSTRUCTURE; + root_node_found =3D true; + + /* Import symbols must be after the root node */ + if (import_sym_found) + return -FDT_ERR_BADSTRUCTURE; + + /* The root node must have an empty name */ name =3D fdt_get_name(fdt, offset, &len); if (!name) return len; @@ -89,8 +96,6 @@ int fdt_check_full(const void *fdt, size_t bufsize) if (depth =3D=3D 0) return -FDT_ERR_BADSTRUCTURE; depth--; - if (depth =3D=3D 0) - expect_end =3D true; break; =20 case FDT_PROP: @@ -239,6 +244,41 @@ int fdt_check_full(const void *fdt, size_t bufsize) =20 break; =20 + case FDT_IMPORT_SYM: + /* Import symbols are supported only in addons */ + if (!(fdt_dt_flags(fdt) & FDT_FLAG_ADDON)) + return -FDT_ERR_BADVALUE; + + import_sym_found =3D true; + + d =3D fdt_get_structured_tag_data(tag, fdt, + offset + FDT_TAGSIZE, NULL); + if (d < 0) + return d; + + /* Retrieve the import symbol name */ + str =3D fdt_offset_ptr(fdt, d, 1); + if (!str) + return -FDT_ERR_BADSTRUCTURE; + + /* Check that the name is not an empty string */ + len =3D strlen(str); + if (!len) + return -FDT_ERR_BADVALUE; + + /* Retrieve the compatible */ + d +=3D len + 1; + str =3D fdt_offset_ptr(fdt, d, 1); + if (!str) + return -FDT_ERR_BADSTRUCTURE; + + /* + * The compatible string can be an empty string + * -> No additional check + */ + + break; + default: return -FDT_ERR_INTERNAL; } --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CCE293E5A0F; Wed, 26 Aug 2026 09:52:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737933; cv=none; b=CY/RT/VIkhby6uE1ho8o1WxvjsmxMj/dUn3SlOq/a8bOzIBPqc/mtpNmKjNBipaLV0E8EAFIPwcK7eDVO98Y8lqf0FsRnL93S+qZDpVjRj2Z9JRD7yyC5T7UYa/Aa8zLrueh3K1v2qxwyFSBhSsispYXLu+E491Gs9x2h43pe/o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737933; c=relaxed/simple; bh=bkgRyyE/qnR5IaZjkz9G3XEna/bC7PCIOFhVcbkR/lY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=c1xrVg/Z/ndC7H2S57yZizP412K7o0fLMm6EXPw3Ogm70Y9ARItQq1MqXjTgO45Wt180tQWlHBsvDq9QziH8v/cy3J7/vz6Ogc8LHP+ztlsf3nf5wYj6kDuCMO8UD4eyE9zl96IiWOrKDocI5zJGUZyzq6bXPzysZWO1SWy2r6w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=N3L7IAHM; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="N3L7IAHM" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 4A7EE1A183A; Wed, 26 Aug 2026 09:52:09 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 1F8BE604EC; Wed, 26 Aug 2026 09:52:09 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 96C6C11C7AD6A; Wed, 26 Aug 2026 11:52:06 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737928; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=QwNPhcy1PagZ/1ECwu2v8KpqOlrxr1UO2KrdkLHMpj8=; b=N3L7IAHMl8FEJnT5uKUE+jyWkoL9yC0N/Ct7Jd2GxKctYAswMlLf3rqFigC3MaB/pHhqp0 L2eFGj27qgI8Sv4qtnZfUGr2FsYr/zg7Q789y+Ek6ioUIurMVgvUOwSrII9Ct4iZhjVsRZ K+1kZ5cJiT2zCUDdOzt3063Yt8nIpD9hi0qmqRTakeRDz0FjJRy35l2SQasOCMrpZTzCZU FUO0J5SaO6Qojtd9Xge6rRSEBIFlxqDOEkqm+xgjDDhq7/A8/pGTdFPxDly9oz2tVkFM+2 W6Dxpa4l3vlsl8EgzGVzF9F/OEmsxyoyhfV30Nz0QV7ESsgr/SZfztLcYvmUMw== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 32/74] tests: metadata: Add import symbols tests Date: Wed, 26 Aug 2026 11:49:01 +0200 Message-ID: <20260826094950.1088288-33-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" Add tests related to import symbols (FDT_IMPORT_SYM dtb tag). Signed-off-by: Herve Codina --- tests/metadata_importsyms.dtb.dts.expect | 9 +++++++++ tests/metadata_importsyms.dtb.expect | 8 ++++++++ tests/metadata_importsyms.dts | 14 ++++++++++++++ tests/metadata_importsyms.dts.dts.expect | 9 +++++++++ tests/run_tests.sh | 10 +++++----- 5 files changed, 45 insertions(+), 5 deletions(-) create mode 100644 tests/metadata_importsyms.dtb.dts.expect create mode 100644 tests/metadata_importsyms.dtb.expect create mode 100644 tests/metadata_importsyms.dts create mode 100644 tests/metadata_importsyms.dts.dts.expect diff --git a/tests/metadata_importsyms.dtb.dts.expect b/tests/metadata_impo= rtsyms.dtb.dts.expect new file mode 100644 index 00000000..eabf8c70 --- /dev/null +++ b/tests/metadata_importsyms.dtb.dts.expect @@ -0,0 +1,9 @@ +/dts-v1/; +/addon/; + +/import/ base_a: "foo,bar"; +/import/ base_b: "foo,baz"; + +/ { + prop =3D <0x01>; +}; diff --git a/tests/metadata_importsyms.dtb.expect b/tests/metadata_importsy= ms.dtb.expect new file mode 100644 index 00000000..21770262 --- /dev/null +++ b/tests/metadata_importsyms.dtb.expect @@ -0,0 +1,8 @@ +/dts-v1/; +/addon/; + +/ { + prop =3D <0x00000001>; +}; +// [FDT_IMPORT_SYM] 'base_a' (foo,bar) +// [FDT_IMPORT_SYM] 'base_b' (foo,baz) diff --git a/tests/metadata_importsyms.dts b/tests/metadata_importsyms.dts new file mode 100644 index 00000000..671586db --- /dev/null +++ b/tests/metadata_importsyms.dts @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) +/* + * Copyright (C) 2026 Bootlin + */ + +/dts-v1/; +/addon/; + +/import/ base_a: "foo,bar"; +/import/ base_b: "foo,baz"; + +/ { + prop =3D <1>; +}; diff --git a/tests/metadata_importsyms.dts.dts.expect b/tests/metadata_impo= rtsyms.dts.dts.expect new file mode 100644 index 00000000..eabf8c70 --- /dev/null +++ b/tests/metadata_importsyms.dts.dts.expect @@ -0,0 +1,9 @@ +/dts-v1/; +/addon/; + +/import/ base_a: "foo,bar"; +/import/ base_b: "foo,baz"; + +/ { + prop =3D <0x01>; +}; diff --git a/tests/run_tests.sh b/tests/run_tests.sh index f61f3e91..7a041aae 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -1250,21 +1250,21 @@ fdtoverlay_tests() { metadata_tests() { for dt in metadata_propdata_phandle_local metadata_propdata_phandle_ref \ metadata_addon_base metadata_exportsyms_local \ - metadata_exportsyms_ref; do + metadata_exportsyms_ref metadata_importsyms; do run_dtc_test -I dts -O dts -o $dt.dts.dts "$SRCDIR/$dt.dts" base_run_test check_diff $dt.dts.dts "$SRCDIR/$dt.dts.dts.expect" run_dtc_test -I dts -O dtb -o $dt.dtb "$SRCDIR/$dt.dts" base_run_test wrap_fdtdump $dt.dtb $dt.dtb.out - # Remove unneeded comments - sed -i '/^\/\/ /d' $dt.dtb.out + # Remove unneeded comments, keep comments in the form '// [xxxx' + sed -i '/^\/\/ [^\[]/d' $dt.dtb.out base_run_test check_diff $dt.dtb.out "$SRCDIR/$dt.dtb.expect" run_test check_full $dt.dtb run_dtc_test -I dtb -O dts -o $dt.dtb.dts $dt.dtb base_run_test check_diff $dt.dtb.dts "$SRCDIR/$dt.dtb.dts.expect" run_dtc_test -I dts -O dtb -o $dt.dtb.dts.dtb $dt.dtb.dts base_run_test wrap_fdtdump $dt.dtb.dts.dtb $dt.dtb.dts.dtb.out - # Remove unneeded comments - sed -i '/^\/\/ /d' $dt.dtb.dts.dtb.out + # Remove unneeded comments, keep comments in the form '// [xxxx' + sed -i '/^\/\/ [^\[]/d' $dt.dtb.dts.dtb.out base_run_test check_diff $dt.dtb.dts.dtb.out "$SRCDIR/$dt.dtb.expect" done =20 --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 63B063D524C for ; Wed, 26 Aug 2026 09:52:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737935; cv=none; b=CwOSGFDY8iiOU8I+9KroUTwcMRkpVxm1aecd8urwALsMg8AzWMnPCozXo24dIaR0Jwj3nCABcqnn+VVp9GT0C9csahCNI6YMIuLN7JhaBILj8MOY5/LQUh1iBIl1+kFtbqH6I1efoLf0wwG1OkWG7oDMFhtf3XGocm4dw4YvjGs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737935; c=relaxed/simple; bh=csy9YCtBKm6aTxukYKCqFV0UOYbFpHeAF2p4aeWvJVA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=AjozafkOReFdQlNcz0iwvuqVELBgAJdIpZ52taU7KdZ/bNDPp81yLE/Pb7YKDSzSZ/TMj7cR5+0zFZixow3lwkHh82zeHoST2nvsS+4PsxNH86t81LA93i6XDm2Pku+UKBfqEhNhLNIzsk5uS/qL/gVLQyRAib9BJUuI/7Gbduo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=TefKbpfj; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="TefKbpfj" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id C02F71A183E; Wed, 26 Aug 2026 09:52:11 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 8EE76604EC; Wed, 26 Aug 2026 09:52:11 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id B056F11C7AD6B; Wed, 26 Aug 2026 11:52:08 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737930; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=vekBZ1ODZdm7J9ZkfWlU6lJGtfrkL5q7Y9+W+ZLUHbA=; b=TefKbpfjSA4whMF7auYbmcU2j3w/7TfxRptuuWam+DC9rfjMbX8hLMBD8dgpPOMC1EUCje L1cnCON3N5Y+Z45Buc1mLL+kUnnkmmFhuv2T/60wfErMnNInMAPwJ10kCIBrP0A+m8djmg DACKTf7g+JXnObqet5GnDStdCwetBpuMHhKNWe/lzKCQI4AQHx9JEmQ8Dx/EFLXk59ZM1a ED4vcWGBfwQbGOt/Ms848ujfeiT4m0W+tkJxnKfSsLkF80Y1rdZZZ50fqfn1mErIX2hs3u scHkJ3kJ+0SXyL4xERHY1wMkeoI7gtPOthkM6WruMjUmyKR4cTrRNje7Y7CDUw== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 33/74] dtc: Add support for import symbols sorting Date: Wed, 26 Aug 2026 11:49:02 +0200 Message-ID: <20260826094950.1088288-34-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" dtc can sort items when the command line --sort option is set. Add support for import symbols sorting when this option is used. Signed-off-by: Herve Codina --- livetree.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/livetree.c b/livetree.c index 30344fb8..130ddf25 100644 --- a/livetree.c +++ b/livetree.c @@ -1126,9 +1126,36 @@ static void sort_node(struct node *node) sort_node(c); } =20 +static void sort_importsyms(struct dt_info *dti) +{ + int n =3D 0, i =3D 0; + struct symbol *symbol, **tbl; + + for_each_symbol(dti->importsymlist, symbol) + n++; + + if (n =3D=3D 0) + return; + + tbl =3D xmalloc(n * sizeof(*tbl)); + + for_each_symbol(dti->importsymlist, symbol) + tbl[i++] =3D symbol; + + qsort(tbl, n, sizeof(*tbl), cmp_symbol); + + dti->importsymlist =3D tbl[0]; + for (i =3D 0; i < (n-1); i++) + tbl[i]->next =3D tbl[i+1]; + tbl[n-1]->next =3D NULL; + + free(tbl); +} + void sort_tree(struct dt_info *dti) { sort_reserve_entries(dti); + sort_importsyms(dti); sort_node(dti->dt); } =20 --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 469693E5577; Wed, 26 Aug 2026 09:52:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737936; cv=none; b=EVfbV8dOo1iHv9J57/6lMjkBGMxny/rjO/qB0QgmbmfzdaKku/PJB/N2+F+n9gcGE5vK3AjW2is4dx0Ils8PCno1zS4exPQotwYh/NUWpNaNxJD2GGTxHnvzqSRL2vj8sCoUnrjnOHLFe5OT1ZYuY4Be6YPEybf9fdz347PrECU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737936; c=relaxed/simple; bh=95XNmSlZWRBa9XNGh4WHAmpLcqKTxfkO98NV72e94X8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=EML0zDS4AGK5Q5c1911vuSdptD1C9RcZT7W9wdSaz+0OB5WiB6mb1b5O0VfZphpYzIhIW9xdlBiSrXDwE9s7VjfY14Hv3K9OT6WB1W2sGyInVBYLYy5ivti9kL3z6juwQwcUSDuDrd1QciiA4H4CkpM1IY22hzLF5nKgve3uTk0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=Msk2HIMr; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="Msk2HIMr" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id E1B581A183D; Wed, 26 Aug 2026 09:52:13 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id AE073604EC; Wed, 26 Aug 2026 09:52:13 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id F19C411C780F5; Wed, 26 Aug 2026 11:52:10 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737932; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=xUxd4wJcHfNJlqPdC/l9eM5qHnYq57UKtdElf7FctcM=; b=Msk2HIMrrKqIUiSwNoA2FgwdPT4dc2Bhwq6N+YbyGus5cHbsXivgGq7zdCMeOuwxc/lO9j A+TaSZt+bm4QzIZXHnQZwBs7XR0sX5oJD3P7CfiVSBHObrn2lJyChdlXhlZKKlQT9oqPBe iRLGtpHCcdfIUa9LijZdyto6X8PuX3yh+D8UC0UluERAaKuYPj6PjOKwfTaXD70VB6KMTF JMzuHK0Lt3obAiQDR2mvURPYymWpfb6g6zFryzlHxRSPkWEzgmSxHJMb8CaP1BoL0gv/oj yQHOZF6bkIFONiIKnowgodclYceUMnHuKAzg+wBA62opOmJtll3tot/0yfvzOQ== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 34/74] tests: metadata: Improve sort test to check for import symbols sorting Date: Wed, 26 Aug 2026 11:49:03 +0200 Message-ID: <20260826094950.1088288-35-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" dtc is able to sort the import symbols list when the --sort option is used. Improve the metadata sort test to perform a check for this feature. Signed-off-by: Herve Codina --- tests/metadata_sort.dtb.dts.expect | 4 ++++ tests/metadata_sort.dtb.expect | 3 +++ tests/metadata_sort.dts | 4 ++++ tests/run_tests.sh | 4 ++-- 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/tests/metadata_sort.dtb.dts.expect b/tests/metadata_sort.dtb.d= ts.expect index f07a42b2..270c06db 100644 --- a/tests/metadata_sort.dtb.dts.expect +++ b/tests/metadata_sort.dtb.dts.expect @@ -1,6 +1,10 @@ /dts-v1/; /addon/; =20 +/import/ abc: "foo,bar"; +/import/ de1: "foo,bar"; +/import/ de2: "foo,bar"; + / { =20 node-a { diff --git a/tests/metadata_sort.dtb.expect b/tests/metadata_sort.dtb.expect index ed10b59a..d5e22674 100644 --- a/tests/metadata_sort.dtb.expect +++ b/tests/metadata_sort.dtb.expect @@ -13,3 +13,6 @@ phandle =3D <0x00000001>; }; }; +// [FDT_IMPORT_SYM] 'abc' (foo,bar) +// [FDT_IMPORT_SYM] 'de1' (foo,bar) +// [FDT_IMPORT_SYM] 'de2' (foo,bar) diff --git a/tests/metadata_sort.dts b/tests/metadata_sort.dts index 7d1cca7e..e523e209 100644 --- a/tests/metadata_sort.dts +++ b/tests/metadata_sort.dts @@ -6,6 +6,10 @@ /dts-v1/; /addon/; =20 +/import/ de1: "foo,bar"; +/import/ abc: "foo,bar"; +/import/ de2: "foo,bar"; + / { node_b: node-b { }; diff --git a/tests/run_tests.sh b/tests/run_tests.sh index 7a041aae..7c45835e 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -1270,8 +1270,8 @@ metadata_tests() { =20 run_dtc_test -I dts -O dtb -s -o metadata_sort.dtb "$SRCDIR/metadata_sort= .dts" base_run_test wrap_fdtdump metadata_sort.dtb metadata_sort.dtb.out - # Remove unneeded comments - sed -i '/^\/\/ /d' metadata_sort.dtb.out + # Remove unneeded comments, keep comments in the form '// [xxxx' + sed -i '/^\/\/ [^\[]/d' metadata_sort.dtb.out base_run_test check_diff metadata_sort.dtb.out "$SRCDIR/metadata_sort.dtb= .expect" run_dtc_test -I dtb -O dts -o metadata_sort.dtb.dts metadata_sort.dtb base_run_test check_diff metadata_sort.dtb.dts "$SRCDIR/metadata_sort.dtb= .dts.expect" --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 942583F12D3; Wed, 26 Aug 2026 09:52:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737939; cv=none; b=NwnylhoZ9ELXUSGmDn3SYzOGmeF1WpxHsgOyZE5luG+ufsmxymMDR48nmHeCFnD1x2CS48tvKcaZt5y/lpIk5YbV4TuR3/qvZ2BQhDoFzkVUMrEB3iJZBeqlKIF39qLjqv2Pz1/+cv925W+v/SJ26bNEOpi4IAf9+BEsdSdbxoA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737939; c=relaxed/simple; bh=a0WPqiq7buP5BIsCiievBjAbwTdSmlRm9Gu+RTgmTnw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=fR/60IO/HFOW7Kvx1PMp2ivzytkJpdRhA2WWYvbk5JkRIOwyG839zcE7sPtIxsdMwM4y3kQOOLSrFNhkeJdrnQYHyzZRhTt9FpFAhsROw9Grot4WrIyca1dUq1nspYiK6sasr6D8I9prIJ4sJ/OKDQdn/xUDACWRRO/VVtSVyNA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=R+XDdHMd; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="R+XDdHMd" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 4D1DB4E413BC; Wed, 26 Aug 2026 09:52:16 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 21A44604EC; Wed, 26 Aug 2026 09:52:16 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 3DDA711C7AD52; Wed, 26 Aug 2026 11:52:13 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737935; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=ZVQWpmEyygnjjaS4S1/YQs5wBXNGmyCDERQUlWo5ugU=; b=R+XDdHMdcwLHe5DdOCEm8znVKfwnBS7Pi+cpFQJdv4RcnQkKKmtwY0HT62bAqdlY8beeb0 yR2XeOMV2d8A0R1nX6RoOuGRwCCvV+3y6xnXeIzJb6sicS/p/KmLF5wdB4BU/5s8MwwKtz X+TBe7H3gI5UVq7Kg/NzdU/nGMKUTOKF07/WYZrjUXjZ4iruAF9svQs462ECesSu4kT4WP zmENue2pGm445CZL9ON0uHYXIVXcn99yxmr7IIDE4AtTbiz3b+o+DVNS5uYlqA++BrIwmP N4KTxMoomSGp1kTZXqsdhsbN9wfptdKkpV/SCE0DGOFRJvzL/ywgiWLEwLol9w== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 35/74] checks: Get 'chosen' node using get_subnode() Date: Wed, 26 Aug 2026 11:49:04 +0200 Message-ID: <20260826094950.1088288-36-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" get_node_by_path() is going to be updated in order to handle orphan node support for addon device-tree. The 'chosen' node is a subnode of the root node and can perfectly be retrieved using get_subnode(). In preparation of the future change related to get_node_by_path(), replace its usage to get the 'chosen' node by a call to get_subnode(). The modification doesn't introduce any functional changes. Signed-off-by: Herve Codina --- checks.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/checks.c b/checks.c index 13e8b121..1332acc4 100644 --- a/checks.c +++ b/checks.c @@ -1349,8 +1349,7 @@ static void check_obsolete_chosen_interrupt_controlle= r(struct check *c, if (node !=3D dt) return; =20 - - chosen =3D get_node_by_path(dt, "/chosen"); + chosen =3D get_subnode(dt, "chosen"); if (!chosen) return; =20 --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 966A23F12C2; Wed, 26 Aug 2026 09:52:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737941; cv=none; b=tQzWYAWjLX1o3L19aJTMdh7MsSa5xZcZCpszIXdVcU8f4ax1ySOI+/VSuF5w2IG3kiO0fMfAAKeHyZMkjzW3qN+d2Q8qnld4/Y4ryLIZPaqGIbJ32Xcbv5KnNbzNhogmARnL/dHzhgkExv5BLJ7NfdKP9h0oEcrHq/LbsV6E86c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737941; c=relaxed/simple; bh=NaNVUT6wvnmE8Ho+05Mk//9ZEq0oKP+SzwPacklKl18=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tfj79LFdBgN9Yaof9JWZF2RbNngIXO4Hr0iz1X2w03F5joNhzB52TnLY5ZDO3aYe+ED0yHg41FOcKV0cx8ZZstxy4+FNRHk5vM6CST6CWv3AMGI+2wmsjQP28wogadmBdy9ElssalffR0WDbtwiF6i5FnerTfqJJZyvB8/rXswQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=V3+dHRwu; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="V3+dHRwu" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 272564E413BF; Wed, 26 Aug 2026 09:52:18 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id EF9BC604EC; Wed, 26 Aug 2026 09:52:17 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 74A0511C7AD5F; Wed, 26 Aug 2026 11:52:15 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737936; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=FpmeaaUP4D5ANThl7zwuZhCEyKXYJbxhpxiPGmadqp8=; b=V3+dHRwuRPhjleWwp2KlK1OxTF46yt1Cerop/ouSKWsgcOYuQOnRoT2vo3XhYaQtjAnF0b yFABofU5SdzBBOgL5DEz9twCvDb3Ixuo24NA94EdCLsfFPyTLfB8ZvBIIx+QtEEy/E1k9b 4Kk6X1DAtQTr7eSR3TIXsEeUEP9YHAQgoR1dZZAoUxCl4vdNfpkA2ir7Vs2gUCJbAPzQq5 z0lvLEW5dg+NZsjsWAWVOCiwmdpf5FiWt7ezgSkwk42xpeZYEmRosvgA5sJ0FFuHiRnDt/ DcGHUZyw2JISGB6pBGvoPiBqceTFoOZ5RMCmyWDIVqxrn958KlYy/nCP6dgCig== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 36/74] dtc: Change get_node_by_path() signature to take dt_info Date: Wed, 26 Aug 2026 11:49:05 +0200 Message-ID: <20260826094950.1088288-37-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" The future introduction of orphan nodes for addons device-tree will lead to more than one tree in the addons data. Those trees will be: - the classical root tree starting at the root node - trees related to orphan nodes Also, an addon device-tree can have only trees based on orphan nodes. In other words an addon device-tree is valid without having the classical 'root' tree. To prepare orphan nodes introduction, move get_node_by_path() parameter one level up and use dt_info struct instead of the 'root' tree (i.e. dti->dt). This change doesn't lead to any functional changes. Signed-off-by: Herve Codina --- checks.c | 2 +- dtc.h | 3 ++- livetree.c | 20 ++++++++++++++------ 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/checks.c b/checks.c index 1332acc4..3b852a9d 100644 --- a/checks.c +++ b/checks.c @@ -748,7 +748,7 @@ static void check_alias_paths(struct check *c, struct d= t_info *dti, =20 /* This check does not work for overlays nor addons with external paths = */ if (!(dti->dtsflags & (DTSF_PLUGIN | DTSF_ADDON)) && - (!prop->val.val || !get_node_by_path(dti->dt, prop->val.val))) { + (!prop->val.val || !get_node_by_path(dti, prop->val.val))) { FAIL_PROP(c, dti, node, prop, "aliases property is not a valid node (%s= )", prop->val.val); continue; diff --git a/dtc.h b/dtc.h index 61521329..a07df2c8 100644 --- a/dtc.h +++ b/dtc.h @@ -323,7 +323,6 @@ struct property *get_property_by_label(struct node *tre= e, const char *label, struct marker *get_marker_label(struct node *tree, const char *label, struct node **node, struct property **prop); struct node *get_subnode(struct node *node, const char *nodename); -struct node *get_node_by_path(struct node *tree, const char *path); struct node *get_node_by_label(struct node *tree, const char *label); struct node *get_node_by_phandle(struct node *tree, cell_t phandle); struct node *get_node_by_ref(struct node *tree, const char *ref); @@ -357,6 +356,8 @@ struct dt_info { const char *outname; /* filename being written to, "-" for stdout */ }; =20 +struct node *get_node_by_path(struct dt_info *dti, const char *path); + /* DTS version flags definitions */ #define DTSF_V1 0x0001 /* /dts-v1/ */ #define DTSF_PLUGIN 0x0002 /* /plugin/ */ diff --git a/livetree.c b/livetree.c index 130ddf25..0120efd2 100644 --- a/livetree.c +++ b/livetree.c @@ -771,7 +771,7 @@ struct node *get_subnode(struct node *node, const char = *nodename) return NULL; } =20 -struct node *get_node_by_path(struct node *tree, const char *path) +static struct node *get_node_by_path_(struct node *tree, const char *path) { const char *p; struct node *child; @@ -789,7 +789,7 @@ struct node *get_node_by_path(struct node *tree, const = char *path) =20 for_each_child(tree, child) { if (p && strprefixeq(path, (size_t)(p - path), child->name)) - return get_node_by_path(child, p+1); + return get_node_by_path_(child, p+1); else if (!p && streq(path, child->name)) return child; } @@ -892,11 +892,19 @@ struct node *get_node_by_ref(struct node *tree, const= char *ref) } =20 if (path) - target =3D get_node_by_path(target, path); + target =3D get_node_by_path_(target, path); =20 return target; } =20 +struct node *get_node_by_path(struct dt_info *dti, const char *path) +{ + if (dti->dt) + return get_node_by_path_(dti->dt, path); + + return NULL; +} + static void add_phandle_property(struct node *node, const char *name, int format) { @@ -940,7 +948,7 @@ uint32_t guess_boot_cpuid(struct node *tree) struct node *cpus, *bootcpu; struct property *reg; =20 - cpus =3D get_node_by_path(tree, "/cpus"); + cpus =3D get_node_by_path_(tree, "/cpus"); if (!cpus) return 0; =20 @@ -1415,7 +1423,7 @@ void generate_labels_from_tree(struct dt_info *dti, c= onst char *name) for_each_property(an, p) { struct node *labeled_node; =20 - labeled_node =3D get_node_by_path(dti->dt, p->val.val); + labeled_node =3D get_node_by_path_(dti->dt, p->val.val); if (labeled_node) add_label(&labeled_node->labels, p->name); else if (quiet < 1) @@ -1497,7 +1505,7 @@ void fixup_phandles(struct dt_info *dti, const char *= name) */ *(propname - 1) =3D '\0'; =20 - n =3D get_node_by_path(dti->dt, fv); + n =3D get_node_by_path_(dti->dt, fv); if (!n && quiet < 1) fprintf(stderr, "Warning: Label %s references non-existing node %s\n", fp->name, fv); --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1C5E23BE638; Wed, 26 Aug 2026 09:52:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737947; cv=none; b=cAQih2Ji5O4uR8JCRlyezKEOvwVkno8XJ3Kkphz09Otz4N0HEhMtjYVLd27H3jOSjNSzjjvbCKhvT1Y970zaHI6jUiGgfNBhzn8FLrjhZBhW+I5Dm9EbXz04lbQkwJUdoUe1kEV05nYq05grJyFrsM4E6ZbhRILv+3QDhF5G22Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737947; c=relaxed/simple; bh=nD2OcS/K4Wd3IPOZ2dD5IZv6svHv/qo+znasNDJlosw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=G3+jvlHbyLe1qzB0hEjn4D3KffTdXcN/sSQGn+1pzU83V5tLhCIJ6b4RgmCuuHKVyxYv4Z1mYI6s1sS1l9VK8Ny4hPXz8YdZDRPYmPL97vxfvsjw3Deve5VSOrcK2OUBGF0mvWf7LhYxyw7f80/xSg/YJpSh3mR/L/nxE9etdwA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=RkEEHzLf; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="RkEEHzLf" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id D52321A183A; Wed, 26 Aug 2026 09:52:24 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id A56E8604EC; Wed, 26 Aug 2026 09:52:24 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 84D4011C780F5; Wed, 26 Aug 2026 11:52:17 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737939; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=GjuJPcsW5Ab4eYj6YvA1jVYNo1TBMC33woe0oyWmUG8=; b=RkEEHzLfqQdA5at1BCPHPovNfNnAy1YRZwLM+kqQag8jk0BebBTL2BExFyGz6eJiBS2/Em bf6LWp7ZKdu9qdG6DA2vrLqGqyqI1/s7Kq9oClN9AsLgTtIsuRK+z05ihW4BpvTiwIpoPX SmAhbBH3sFfIuFwa9lzh34uEnxdDi2QREI6s6hElEzJ4aF6M7nGdq9JzyTYkhghEKt00ih T+x2NU29ClCK9pZHt5EatdpHAUMawju5Uhs5J7egcGI6kD/rLICWiN35TGfoOFlt7qGFZP zhkt95IqVDQ0vGqxtt4yK3GVT+0Wxhj9xuXRgIaREVZxVuClU0uDCiD3Z7GgGA== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 37/74] dtc: Change get_node_by_label() signature to take dt_info Date: Wed, 26 Aug 2026 11:49:06 +0200 Message-ID: <20260826094950.1088288-38-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" The future introduction of orphan nodes for addons device-tree will lead to more than one tree in the addons data. Those trees will be: - the classical root tree starting at the root node - trees related to orphan nodes Also, an addon device-tree can have only trees based on orphan nodes. In other words an addon device-tree is valid without having the classical 'root' tree. To prepare orphan nodes introduction, move get_node_by_label() parameter one level up and use dt_info struct instead of the 'root' tree (i.e. dti->dt). This change doesn't lead to any functional changes. Signed-off-by: Herve Codina --- checks.c | 2 +- dtc.h | 2 +- livetree.c | 19 ++++++++++++++++--- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/checks.c b/checks.c index 3b852a9d..f4ae776b 100644 --- a/checks.c +++ b/checks.c @@ -452,7 +452,7 @@ static void check_duplicate_label(struct check *c, stru= ct dt_info *dti, struct property *otherprop =3D NULL; struct marker *othermark =3D NULL; =20 - othernode =3D get_node_by_label(dt, label); + othernode =3D get_node_by_label(dti, label); =20 if (!othernode) otherprop =3D get_property_by_label(dt, label, &othernode); diff --git a/dtc.h b/dtc.h index a07df2c8..bf8f0ce4 100644 --- a/dtc.h +++ b/dtc.h @@ -323,7 +323,6 @@ struct property *get_property_by_label(struct node *tre= e, const char *label, struct marker *get_marker_label(struct node *tree, const char *label, struct node **node, struct property **prop); struct node *get_subnode(struct node *node, const char *nodename); -struct node *get_node_by_label(struct node *tree, const char *label); struct node *get_node_by_phandle(struct node *tree, cell_t phandle); struct node *get_node_by_ref(struct node *tree, const char *ref); cell_t get_node_phandle(struct node *root, struct node *node); @@ -357,6 +356,7 @@ struct dt_info { }; =20 struct node *get_node_by_path(struct dt_info *dti, const char *path); +struct node *get_node_by_label(struct dt_info *dti, const char *label); =20 /* DTS version flags definitions */ #define DTSF_V1 0x0001 /* /dts-v1/ */ diff --git a/livetree.c b/livetree.c index 0120efd2..aec1e160 100644 --- a/livetree.c +++ b/livetree.c @@ -797,7 +797,7 @@ static struct node *get_node_by_path_(struct node *tree= , const char *path) return NULL; } =20 -struct node *get_node_by_label(struct node *tree, const char *label) +static struct node *get_node_by_label_(struct node *tree, const char *labe= l) { struct node *child, *node; struct label *l; @@ -809,7 +809,7 @@ struct node *get_node_by_label(struct node *tree, const= char *label) return tree; =20 for_each_child(tree, child) { - node =3D get_node_by_label(child, label); + node =3D get_node_by_label_(child, label); if (node) return node; } @@ -883,7 +883,7 @@ struct node *get_node_by_ref(struct node *tree, const c= har *ref) path =3D slash + 1; } =20 - target =3D get_node_by_label(tree, label); + target =3D get_node_by_label_(tree, label); =20 free(buf); =20 @@ -905,6 +905,19 @@ struct node *get_node_by_path(struct dt_info *dti, con= st char *path) return NULL; } =20 +struct node *get_node_by_label(struct dt_info *dti, const char *label) +{ + struct node *node; + + if (dti->dt) { + node =3D get_node_by_label_(dti->dt, label); + if (node) + return node; + } + + return NULL; +} + static void add_phandle_property(struct node *node, const char *name, int format) { --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 378063C09F1; Wed, 26 Aug 2026 09:52:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737954; cv=none; b=rw0640PoEFnowMCChgNQNFXJ/Hrq0yc0iiY2U5ayBAayaPUGL5QlwaPtLLOrFAOy6koUOUnaFArTy7QMBDUPdrdR5jIsKvFX5+Xf8fp4N1lyN6mYFaStygYZ1zmFvahSegjE9IaYSCXV4y7wsaWcfaKEQmBewZlNCNNHbTG/V5s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737954; c=relaxed/simple; bh=mkTEVuBwnL7cLByjCSgFifSvsLxriFjYuJgAg4CBXuY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=O/mG8BYWVnHvxdoFwx9QaZ6pUWhi0OxmnVhpmhIkZyEnKk8yqhSDd4xgLHQUaOrS4HvkHZDMwLQyHiVr5a9A+9lremhMGeN7/BZg4prj2cYufow0XjlqH0IrH/HEqr5Lg9JwgNRXgbLAPD0EO/WWLhwRza6tL/04sMRUzBl6oOY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=Ipq1M8N8; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="Ipq1M8N8" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id E8ECB1A183A; Wed, 26 Aug 2026 09:52:31 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id B6CD0604EC; Wed, 26 Aug 2026 09:52:31 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 3BA3B11C7AD64; Wed, 26 Aug 2026 11:52:24 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737946; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=wpUlkOVxyoiS/FboVOPBjzYeW7ZlKu5gmFmVI1uE68g=; b=Ipq1M8N8aSt/evST96fDI6UjjmxnM+CBoqxAYiSzg/EJJsErOFHS4DTcn+hmQ1pOUf3Inf we+dLrx/BNIPPJGAz0oNvMaAyUzmOT2PUVqhan/+HQ4bI4vN86Dh118aoCsHu49GUNy2D7 xECDIFpwiqQ3j3qp3MJVsG1JBXBWvNgQQ5lT25+s2DNwX/ruG6mnCAZU9Zb1EweHWoU9r4 T6TRM1jAdt0idCEdAY4M+h4BpG3OL7BSg1XEf7YDQ1EEx3AP+hitMupVKSUWMehg7a9vkt KWYzqwHmKqE5wS8mWn4xYuuNTbh6er3ZVFjAup2gQVm1lupZP7g/2AX41C7mdA== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 38/74] dtc: Change get_node_by_phandle() signature to take dt_info Date: Wed, 26 Aug 2026 11:49:07 +0200 Message-ID: <20260826094950.1088288-39-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" The future introduction of orphan nodes for addons device-tree will lead to more than one tree in the addons data. Those trees will be: - the classical root tree starting at the root node - trees related to orphan nodes Also, an addon device-tree can have only trees based on orphan nodes. In other words an addon device-tree is valid without having the classical 'root' tree. To prepare orphan nodes introduction, move get_node_by_phandle() parameter one level up and use dt_info struct instead of the 'root' tree (i.e. dti->dt). This change doesn't lead to any functional changes. Signed-off-by: Herve Codina --- checks.c | 14 +++++--------- dtc.h | 2 +- livetree.c | 21 +++++++++++++++++---- treesource.c | 2 +- 4 files changed, 24 insertions(+), 15 deletions(-) diff --git a/checks.c b/checks.c index f4ae776b..6b25c204 100644 --- a/checks.c +++ b/checks.c @@ -541,7 +541,6 @@ static cell_t check_phandle_prop(struct check *c, struc= t dt_info *dti, static void check_explicit_phandles(struct check *c, struct dt_info *dti, struct node *node) { - struct node *root =3D dti->dt; struct node *other; cell_t phandle, linux_phandle; =20 @@ -563,7 +562,7 @@ static void check_explicit_phandles(struct check *c, st= ruct dt_info *dti, if (linux_phandle && !phandle) phandle =3D linux_phandle; =20 - other =3D get_node_by_phandle(root, phandle); + other =3D get_node_by_phandle(dti, phandle); if (other && (other !=3D node)) { FAIL(c, dti, node, "duplicated phandle 0x%x (seen before at %s)", phandle, other->fullpath); @@ -1422,7 +1421,6 @@ static void check_property_phandle_args(struct check = *c, struct property *prop, const struct provider *provider) { - struct node *root =3D dti->dt; unsigned int cell, cellsize =3D 0; =20 if (!is_multiple_of(prop->val.len, sizeof(cell_t))) { @@ -1465,7 +1463,7 @@ static void check_property_phandle_args(struct check = *c, cell); } =20 - provider_node =3D get_node_by_phandle(root, phandle); + provider_node =3D get_node_by_phandle(dti, phandle); if (!provider_node) { FAIL_PROP(c, dti, node, prop, "Could not get phandle node for (cell %d)", @@ -1632,7 +1630,6 @@ static void check_interrupt_map(struct check *c, struct dt_info *dti, struct node *node) { - struct node *root =3D dti->dt; struct property *prop, *irq_map_prop; size_t cellsize, cell, map_cells; =20 @@ -1686,7 +1683,7 @@ static void check_interrupt_map(struct check *c, break; } =20 - provider_node =3D get_node_by_phandle(root, phandle); + provider_node =3D get_node_by_phandle(dti, phandle); if (!provider_node) { FAIL_PROP(c, dti, node, irq_map_prop, "Could not get phandle(%d) node for (cell %zu)", @@ -1724,7 +1721,6 @@ static void check_interrupts_property(struct check *c, struct dt_info *dti, struct node *node) { - struct node *root =3D dti->dt; struct node *irq_node =3D NULL, *parent =3D node; struct property *irq_prop, *prop =3D NULL; cell_t irq_cells, phandle; @@ -1755,7 +1751,7 @@ static void check_interrupts_property(struct check *c, continue; } =20 - irq_node =3D get_node_by_phandle(root, phandle); + irq_node =3D get_node_by_phandle(dti, phandle); if (!irq_node) { FAIL_PROP(c, dti, parent, prop, "Bad phandle"); return; @@ -1890,7 +1886,7 @@ static struct node *get_remote_endpoint(struct check = *c, struct dt_info *dti, if (!phandle_is_valid(phandle)) return NULL; =20 - node =3D get_node_by_phandle(dti->dt, phandle); + node =3D get_node_by_phandle(dti, phandle); if (!node) FAIL_PROP(c, dti, endpoint, prop, "graph phandle is not valid"); =20 diff --git a/dtc.h b/dtc.h index bf8f0ce4..27f49bc6 100644 --- a/dtc.h +++ b/dtc.h @@ -323,7 +323,6 @@ struct property *get_property_by_label(struct node *tre= e, const char *label, struct marker *get_marker_label(struct node *tree, const char *label, struct node **node, struct property **prop); struct node *get_subnode(struct node *node, const char *nodename); -struct node *get_node_by_phandle(struct node *tree, cell_t phandle); struct node *get_node_by_ref(struct node *tree, const char *ref); cell_t get_node_phandle(struct node *root, struct node *node); =20 @@ -357,6 +356,7 @@ struct dt_info { =20 struct node *get_node_by_path(struct dt_info *dti, const char *path); struct node *get_node_by_label(struct dt_info *dti, const char *label); +struct node *get_node_by_phandle(struct dt_info *dti, cell_t phandle); =20 /* DTS version flags definitions */ #define DTSF_V1 0x0001 /* /dts-v1/ */ diff --git a/livetree.c b/livetree.c index aec1e160..5bd65b1b 100644 --- a/livetree.c +++ b/livetree.c @@ -584,7 +584,7 @@ static void complete_ref_and_is_local(struct dt_info *d= ti, char **ref, } =20 if (*is_local) { - refnode =3D get_node_by_phandle(dti->dt, phandle); + refnode =3D get_node_by_phandle(dti, phandle); if (!refnode) die("Node not found for phandle 0x%"PRIx32"\n", phandle); =20 @@ -834,7 +834,7 @@ static cell_t get_node_phandle_existing(struct node *no= de) return propval_cell(prop); } =20 -struct node *get_node_by_phandle(struct node *tree, cell_t phandle) +static struct node *get_node_by_phandle_(struct node *tree, cell_t phandle) { struct node *child, *node; cell_t tree_phandle; @@ -852,7 +852,7 @@ struct node *get_node_by_phandle(struct node *tree, cel= l_t phandle) } =20 for_each_child(tree, child) { - node =3D get_node_by_phandle(child, phandle); + node =3D get_node_by_phandle_(child, phandle); if (node) return node; } @@ -918,6 +918,19 @@ struct node *get_node_by_label(struct dt_info *dti, co= nst char *label) return NULL; } =20 +struct node *get_node_by_phandle(struct dt_info *dti, cell_t phandle) +{ + struct node *node; + + if (dti->dt) { + node =3D get_node_by_phandle_(dti->dt, phandle); + if (node) + return node; + } + + return NULL; +} + static void add_phandle_property(struct node *node, const char *name, int format) { @@ -941,7 +954,7 @@ cell_t get_node_phandle(struct node *root, struct node = *node) if (phandle_is_valid(node->phandle)) return node->phandle; =20 - while (get_node_by_phandle(root, phandle)) + while (get_node_by_phandle_(root, phandle)) phandle++; =20 node->phandle =3D phandle; diff --git a/treesource.c b/treesource.c index d22f1d32..705fe9a6 100644 --- a/treesource.c +++ b/treesource.c @@ -205,7 +205,7 @@ void add_phandle_marker(struct dt_info *dti, struct pro= perty *prop, unsigned int } =20 phandle =3D dtb_ld32(prop->val.val + offset); - refn =3D get_node_by_phandle(dti->dt, phandle); + refn =3D get_node_by_phandle(dti, phandle); =20 if (!refn) { if (quiet < 1) --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 897453F6C28; Wed, 26 Aug 2026 09:52:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737961; cv=none; b=PMt6ydYE/7/3Wnln/dq7ikJB72iCrJktu3ez9+Owqw9H6ZLb2Y0cStZQLD+pKvhZ29KSt+wStjIi6jbTL7/71FfgAWdeWnTI+xEoqvdFjAN05EIJo0MEG6/ODr3VackfMu7XtbExPQusA+IYSmVmG9mS8CQvYOvrChv2Fu7O8Xo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737961; c=relaxed/simple; bh=CjrXTnH5Dnubdmnsg4ic1eB7NrVmntk5aPffvvFre3s=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mMgDRn3ekq8NewYK2S1KoYY10Jt15OLfIptRQSF2Ye3RVexM8BjVsdQJvYVfNnpcWXKct3Zmm246DQKG/Zs8tv9cAt403U3fOsITSUeKgY68l0995LzeOn7qlfalcoCBTzxsEQ6TC6bEuF0F5dvLAh0slJh8cy/CJ4hT2p+/w0E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=CH6sn+7Q; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="CH6sn+7Q" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 205634E413BC; Wed, 26 Aug 2026 09:52:38 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id E0EDB604EC; Wed, 26 Aug 2026 09:52:37 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 5083611C7AD5F; Wed, 26 Aug 2026 11:52:31 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737952; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=Vka/pgsTUYstdtcG9XIFnDMWJYhJRc0xtZUeqcnrmi8=; b=CH6sn+7QfgmDxnG/QWzz6/bnWTvs7wceDlMWJ2s3aGELNCgHNGuezpRu6exKTIHJOW10R5 3z7AfSseK6VwgJB1+IbuqKMWAYWRqo3yibTVPru5ge9alpazMtmZuPV2oehatD6o4ZSwNy BV4ebxWP/oujsGVuwAT3eXe9oILVdjvGyULeztNKgydwTxSkrQUfoa/TqmDxxycpyTaC9V RjCnc+Xh22Sg4qJMjS0nSor67cKPRG8rfIg4IRZSW7Haxu0wUNjqdROYPT4i/cPvbWInEu Oba+57q+WnXFsaE4+vtc56v3tM8moDwW83XquPSlfgoyW9xDmsSh5xHrhGBeXw== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 39/74] dtc: Change get_node_by_ref() signature to take dt_info Date: Wed, 26 Aug 2026 11:49:08 +0200 Message-ID: <20260826094950.1088288-40-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" The future introduction of orphan nodes for addons device-tree will lead to more than one tree in the addons data. Those trees will be: - the classical root tree starting at the root node - trees related to orphan nodes Also, an addon device-tree can have only trees based on orphan nodes. In other words an addon device-tree is valid without having the classical 'root' tree. To prepare orphan nodes introduction, move get_node_by_ref() parameter one level up and use dt_info struct instead of the 'root' tree (i.e. dti->dt). This change doesn't lead to any functional changes. Signed-off-by: Herve Codina --- checks.c | 10 ++++------ dtc-parser.y | 22 +++++++++++++++++----- dtc.h | 2 +- livetree.c | 25 +++++++++++++++++++------ 4 files changed, 41 insertions(+), 18 deletions(-) diff --git a/checks.c b/checks.c index 6b25c204..b22b616c 100644 --- a/checks.c +++ b/checks.c @@ -494,7 +494,6 @@ ERROR(duplicate_label, check_duplicate_label_node, NULL= ); static cell_t check_phandle_prop(struct check *c, struct dt_info *dti, struct node *node, const char *propname) { - struct node *root =3D dti->dt; struct property *prop; struct marker *m; cell_t phandle; @@ -512,7 +511,7 @@ static cell_t check_phandle_prop(struct check *c, struc= t dt_info *dti, m =3D prop->val.markers; for_each_marker_of_type(m, REF_PHANDLE) { assert(m->offset =3D=3D 0); - if (node !=3D get_node_by_ref(root, m->ref)) + if (node !=3D get_node_by_ref(dti, m->ref)) /* "Set this node's phandle equal to some * other node's phandle". That's nonsensical * by construction. */ { @@ -622,7 +621,7 @@ static void fixup_phandle_references(struct check *c, s= truct dt_info *dti, for_each_marker_of_type(m, REF_PHANDLE) { assert(m->offset + sizeof(cell_t) <=3D prop->val.len); =20 - refnode =3D get_node_by_ref(dt, m->ref); + refnode =3D get_node_by_ref(dti, m->ref); if (! refnode) { if (!(dti->dtsflags & (DTSF_PLUGIN | DTSF_ADDON))) FAIL(c, dti, node, "Reference to non-existent node or " @@ -641,7 +640,7 @@ static void fixup_phandle_references(struct check *c, s= truct dt_info *dti, } =20 for_each_symbol(node->exportsymlist, exportsym) { - refnode =3D get_node_by_ref(dt, exportsym->ref); + refnode =3D get_node_by_ref(dti, exportsym->ref); if (!refnode) { if (!(dti->dtsflags & (DTSF_PLUGIN | DTSF_ADDON))) { FAIL(c, dti, node, @@ -665,7 +664,6 @@ ERROR(phandle_references, fixup_phandle_references, NUL= L, static void fixup_path_references(struct check *c, struct dt_info *dti, struct node *node) { - struct node *dt =3D dti->dt; struct property *prop; =20 for_each_property(node, prop) { @@ -676,7 +674,7 @@ static void fixup_path_references(struct check *c, stru= ct dt_info *dti, for_each_marker_of_type(m, REF_PATH) { assert(m->offset <=3D prop->val.len); =20 - refnode =3D get_node_by_ref(dt, m->ref); + refnode =3D get_node_by_ref(dti, m->ref); if (!refnode) { FAIL(c, dti, node, "Reference to non-existent node or label \"%s\"\n", m->ref); diff --git a/dtc-parser.y b/dtc-parser.y index 61ebde2d..dd346fb4 100644 --- a/dtc-parser.y +++ b/dtc-parser.y @@ -31,6 +31,18 @@ static bool is_ref_relative(const char *ref) return ref[0] !=3D '/' && strchr(&ref[1], '/'); } =20 +static struct node *parser_get_node_by_ref(struct node *dt, const char *re= f) +{ + /* + * Use a temporary dt_info in order to use dti_get_node_by_ref() + */ + struct dt_info dti =3D {}; + + dti.dt =3D dt; + + return get_node_by_ref(&dti, ref); +} + %} =20 %union { @@ -240,7 +252,7 @@ devicetree: } | devicetree DT_LABEL dt_ref nodedef { - struct node *target =3D get_node_by_ref($1, $3); + struct node *target =3D parser_get_node_by_ref($1, $3); =20 if ((last_header_flags & DTSF_PLUGIN) && is_ref_relative($3)) ERROR(&@2, "Label-relative reference %s not supported in plugin", $3); @@ -259,7 +271,7 @@ devicetree: ERROR(&@2, "Label-relative reference %s not supported in plugin", $2); add_orphan_node($1, $3, $2); } else { - struct node *target =3D get_node_by_ref($1, $2); + struct node *target =3D parser_get_node_by_ref($1, $2); =20 if (target) merge_nodes(target, $3); @@ -270,7 +282,7 @@ devicetree: } | devicetree DT_LABEL_REF nodedef { - struct node *target =3D get_node_by_ref($1, $2); + struct node *target =3D parser_get_node_by_ref($1, $2); =20 if (target) { merge_nodes(target, $3); @@ -284,7 +296,7 @@ devicetree: } | devicetree DT_DEL_NODE dt_ref ';' { - struct node *target =3D get_node_by_ref($1, $3); + struct node *target =3D parser_get_node_by_ref($1, $3); =20 if (target) delete_node(target); @@ -296,7 +308,7 @@ devicetree: } | devicetree DT_OMIT_NO_REF dt_ref ';' { - struct node *target =3D get_node_by_ref($1, $3); + struct node *target =3D parser_get_node_by_ref($1, $3); =20 if (target) omit_node_if_unused(target); diff --git a/dtc.h b/dtc.h index 27f49bc6..d76ba6b7 100644 --- a/dtc.h +++ b/dtc.h @@ -323,7 +323,6 @@ struct property *get_property_by_label(struct node *tre= e, const char *label, struct marker *get_marker_label(struct node *tree, const char *label, struct node **node, struct property **prop); struct node *get_subnode(struct node *node, const char *nodename); -struct node *get_node_by_ref(struct node *tree, const char *ref); cell_t get_node_phandle(struct node *root, struct node *node); =20 uint32_t guess_boot_cpuid(struct node *tree); @@ -357,6 +356,7 @@ struct dt_info { struct node *get_node_by_path(struct dt_info *dti, const char *path); struct node *get_node_by_label(struct dt_info *dti, const char *label); struct node *get_node_by_phandle(struct dt_info *dti, cell_t phandle); +struct node *get_node_by_ref(struct dt_info *dti, const char *ref); =20 /* DTS version flags definitions */ #define DTSF_V1 0x0001 /* /dts-v1/ */ diff --git a/livetree.c b/livetree.c index 5bd65b1b..40ca873a 100644 --- a/livetree.c +++ b/livetree.c @@ -575,7 +575,7 @@ static void complete_ref_and_is_local(struct dt_info *d= ti, char **ref, */ =20 if (*ref) { - refnode =3D get_node_by_ref(dti->dt, *ref); + refnode =3D get_node_by_ref(dti, *ref); if (refnode) *is_local =3D true; else @@ -860,7 +860,7 @@ static struct node *get_node_by_phandle_(struct node *t= ree, cell_t phandle) return NULL; } =20 -struct node *get_node_by_ref(struct node *tree, const char *ref) +static struct node *get_node_by_ref_(struct node *tree, const char *ref) { struct node *target =3D tree; const char *label =3D NULL, *path =3D NULL; @@ -931,6 +931,19 @@ struct node *get_node_by_phandle(struct dt_info *dti, = cell_t phandle) return NULL; } =20 +struct node *get_node_by_ref(struct dt_info *dti, const char *ref) +{ + struct node *node; + + if (dti->dt) { + node =3D get_node_by_ref_(dti->dt, ref); + if (node) + return node; + } + + return NULL; +} + static void add_phandle_property(struct node *node, const char *name, int format) { @@ -1283,7 +1296,7 @@ static bool any_fixup_tree(struct dt_info *dti, struc= t node *node) for_each_property(node, prop) { m =3D prop->val.markers; for_each_marker_of_type(m, REF_PHANDLE) { - if (!get_node_by_ref(dti->dt, m->ref)) + if (!get_node_by_ref_(dti->dt, m->ref)) return true; } } @@ -1339,7 +1352,7 @@ static int generate_fixups_tree_internal(struct dt_in= fo *dti, for_each_property(node, prop) { m =3D prop->val.markers; for_each_marker_of_type(m, REF_PHANDLE) { - refnode =3D get_node_by_ref(dt, m->ref); + refnode =3D get_node_by_ref_(dt, m->ref); if (!refnode) if (add_fixup_entry(dti, fn, node, prop, m)) ret =3D -1; @@ -1362,7 +1375,7 @@ static bool any_local_fixup_tree(struct dt_info *dti,= struct node *node) for_each_property(node, prop) { m =3D prop->val.markers; for_each_marker_of_type(m, REF_PHANDLE) { - if (get_node_by_ref(dti->dt, m->ref)) + if (get_node_by_ref_(dti->dt, m->ref)) return true; } } @@ -1423,7 +1436,7 @@ static int generate_local_fixups_tree_internal(struct= dt_info *dti, for_each_property(node, prop) { m =3D prop->val.markers; for_each_marker_of_type(m, REF_PHANDLE) { - refnode =3D get_node_by_ref(dt, m->ref); + refnode =3D get_node_by_ref_(dt, m->ref); if (refnode) if (add_local_fixup_entry(dti, lfn, node, prop, m, refnode)) ret =3D -1; --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D92F43F7892; Wed, 26 Aug 2026 09:52:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737963; cv=none; b=X8rJDC1O0q30eDJ4IF0JTsJzgKw0xhd2nID+rusYCLXulq9oWN2rthFbmPZz4/NEbsnyRKuCa+NOagAkexl79jSDIl/1MNjgCIo7fGWXETnm3WxViAjnii1WTtNPItfCLUjeX4r78esENRz2rHC/jF9lXa0wphggyNEefcm9Z/U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737963; c=relaxed/simple; bh=Ae+J0Fp73WWMKpZ07y93E8FUkklv3etcE/CfM5G7Wow=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Oft9VDfDPUig0K2nGllpTRZQyvmoJy2zil+UP5ftGjXzoM7Xb+mPmNhloj+5V9zt/TtKqg9dFnmOZBlTRlf6Re/sltB5nJ6PymuL3rodWC7zA/AqdGsVgu8/qzFSE2pTDTmVL9lHdWKbw1O0qqLt+jX+OcpWGLKvpQRt+65BDKQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=CLZEcR43; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="CLZEcR43" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 9267A4E413BF; Wed, 26 Aug 2026 09:52:40 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 67CDB604EC; Wed, 26 Aug 2026 09:52:40 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 6E00011C7AD52; Wed, 26 Aug 2026 11:52:37 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737959; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=xyEGlRxncAFiW/2GYUo6g9GIqN9eaNjDBZgfRLAFvac=; b=CLZEcR43txjRWSSYC9qlVW2ks18s5oML1Kv8ku+jgqCq1c386NV09Z8sp49c7JkV771Fjx AeXnLjjFwpiepVIBEJQJCWw9B4UKF4OUX8ndMHVlGI/+Fo6pl1RDMrskIUTmvAc9PHEQdh pyK4jIn95auSbFd9VPNB98EdXDPN8/hWgRI+gDZevcrP6VKiNUdMye3QmQMPeauSVMo1Ae EScZOwMMxoS2zsiIoU2DxnTMHLj/psPP1HPJ8JzpOVMbGAupoa5cEWQidmVomktjr04m8d AP3HReF7L618+Xqo/yfXzhafUiQWge/Wn2GUMBgVFweKnzPUtjGgin++iFpiMw== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 40/74] dtc: Change get_node_phandle() signature to take dt_info Date: Wed, 26 Aug 2026 11:49:09 +0200 Message-ID: <20260826094950.1088288-41-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" The future introduction of orphan nodes for addons device-tree will lead to more than one tree in the addons data. Those trees will be: - the classical root tree starting at the root node - trees related to orphan nodes Also, an addon device-tree can have only trees based on orphan nodes. In other words an addon device-tree is valid without having the classical 'root' tree. To prepare orphan nodes introduction, move get_node_phandle() parameter one level up and use dt_info struct instead of the 'root' tree (i.e. dti->dt). This change doesn't lead to any functional changes. Signed-off-by: Herve Codina --- checks.c | 5 ++--- dtc.h | 2 +- livetree.c | 7 +++---- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/checks.c b/checks.c index b22b616c..f90a8eed 100644 --- a/checks.c +++ b/checks.c @@ -609,7 +609,6 @@ ERROR(name_properties, check_name_properties, NULL, &na= me_is_string); static void fixup_phandle_references(struct check *c, struct dt_info *dti, struct node *node) { - struct node *dt =3D dti->dt; struct symbol *exportsym; struct property *prop; struct node *refnode; @@ -632,7 +631,7 @@ static void fixup_phandle_references(struct check *c, s= truct dt_info *dti, continue; } =20 - phandle =3D get_node_phandle(dt, refnode); + phandle =3D get_node_phandle(dti, refnode); *((fdt32_t *)(prop->val.val + m->offset)) =3D cpu_to_fdt32(phandle); =20 reference_node(refnode); @@ -652,7 +651,7 @@ static void fixup_phandle_references(struct check *c, s= truct dt_info *dti, } =20 /* Create the phandle property for this referenced node */ - phandle =3D get_node_phandle(dt, refnode); + phandle =3D get_node_phandle(dti, refnode); exportsym->phandle =3D phandle; =20 reference_node(refnode); diff --git a/dtc.h b/dtc.h index d76ba6b7..5d39d31f 100644 --- a/dtc.h +++ b/dtc.h @@ -323,7 +323,6 @@ struct property *get_property_by_label(struct node *tre= e, const char *label, struct marker *get_marker_label(struct node *tree, const char *label, struct node **node, struct property **prop); struct node *get_subnode(struct node *node, const char *nodename); -cell_t get_node_phandle(struct node *root, struct node *node); =20 uint32_t guess_boot_cpuid(struct node *tree); =20 @@ -357,6 +356,7 @@ struct node *get_node_by_path(struct dt_info *dti, cons= t char *path); struct node *get_node_by_label(struct dt_info *dti, const char *label); struct node *get_node_by_phandle(struct dt_info *dti, cell_t phandle); struct node *get_node_by_ref(struct dt_info *dti, const char *ref); +cell_t get_node_phandle(struct dt_info *dti, struct node *node); =20 /* DTS version flags definitions */ #define DTSF_V1 0x0001 /* /dts-v1/ */ diff --git a/livetree.c b/livetree.c index 40ca873a..c42e9a97 100644 --- a/livetree.c +++ b/livetree.c @@ -960,14 +960,14 @@ static void add_phandle_property(struct node *node, add_property(node, build_property(name, d, NULL)); } =20 -cell_t get_node_phandle(struct node *root, struct node *node) +cell_t get_node_phandle(struct dt_info *dti, struct node *node) { static cell_t phandle =3D 1; /* FIXME: ick, static local */ =20 if (phandle_is_valid(node->phandle)) return node->phandle; =20 - while (get_node_by_phandle_(root, phandle)) + while (get_node_by_phandle(dti, phandle)) phandle++; =20 node->phandle =3D phandle; @@ -1250,7 +1250,6 @@ static void generate_label_tree_internal(struct dt_in= fo *dti, struct node *an, struct node *node, bool allocph) { - struct node *dt =3D dti->dt; struct node *c; struct property *p; struct label *l; @@ -1280,7 +1279,7 @@ static void generate_label_tree_internal(struct dt_in= fo *dti, =20 /* force allocation of a phandle for this node */ if (allocph) - (void)get_node_phandle(dt, node); + (void)get_node_phandle(dti, node); } =20 for_each_child(node, c) --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 56FC23C4B6A; Wed, 26 Aug 2026 09:52:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737965; cv=none; b=dx0Eu2CkbSRinT21emLlTrxyzcF6EH+VA2g7vzajEQOqIxchEUQe02LlDDFdFpwNcCnCosyM+gbdvstN78TY3ydiic5JBBhX6pw8CtMw8JB1kIe0fSct40HvcJ15WXZxiaxePG+RUTtRq1F2dVH5nx57FW+0++h38PWVKNIvAfM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737965; c=relaxed/simple; bh=ER1wpXHuOFXSc2YfRXwmOJQb9Kd2be2N50hEvOPb98U=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=VZVNG7x00G+iIajlbWFTby9erY61l2saoWXrWZUAZVzoneGnhKjiH10N5v5k6606FS4J3wtxxt0JsfR0wirTNxB+kev9KAnlWH4u7GHxQ6WxOyF90mBD+esFCOPNBpEFZtpOwriEw/S0jItlxX4cX14en7FUftWJN2abqwPQ6uw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=qDcfo5gR; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="qDcfo5gR" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id E88411A183E; Wed, 26 Aug 2026 09:52:42 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id BCD67604EC; Wed, 26 Aug 2026 09:52:42 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id DFC7611C7AD65; Wed, 26 Aug 2026 11:52:39 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737961; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=3TAZMcxQuW3Lm3yQGKPSTKq+cID7+OJiFxL6KynFLLo=; b=qDcfo5gR41dgQyK6zrNVdC7Tr3x9pfZNLwSNQzLnR+H1MJ0iVtH9OqtWoza8h6Y64anR78 W9z4gRDvXX0xK9frBey2ubEcfOBKim5QQBz5WFjecxpOqbh7qDp39OIrV1QympFRqL8WZ6 OxtMYhz4RHCb2xQvhqhK2mBuhyzsAmJKzc3GG5yNckFkgMHZPhP6vFSCwXMpTA5OvhwEZl FT4XIUz+UsX7B+djved0eoPy+5rbL0rPsxC5ftJ+pPNM/1accoYn7vgezOCUZ4SjbKuTLj HsZIQdr0Wpdc77hjH3gHtl3iI8PLHlQbN1tqNk8JT1XvCC7s1qegyePg7Z/CWA== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 41/74] dtc: Change get_property_by_label() signature to take dt_info Date: Wed, 26 Aug 2026 11:49:10 +0200 Message-ID: <20260826094950.1088288-42-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" The future introduction of orphan nodes for addons device-tree will lead to more than one tree in the addons data. Those trees will be: - the classical root tree starting at the root node - trees related to orphan nodes Also, an addon device-tree can have only trees based on orphan nodes. In other words an addon device-tree is valid without having the classical 'root' tree. To prepare orphan nodes introduction, move get_property_by_label() parameter one level up and use dt_info struct instead of the 'root' tree (i.e. dti->dt). This change doesn't lead to any functional changes. Signed-off-by: Herve Codina --- checks.c | 2 +- dtc.h | 4 ++-- livetree.c | 22 +++++++++++++++++++--- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/checks.c b/checks.c index f90a8eed..7b52f37c 100644 --- a/checks.c +++ b/checks.c @@ -455,7 +455,7 @@ static void check_duplicate_label(struct check *c, stru= ct dt_info *dti, othernode =3D get_node_by_label(dti, label); =20 if (!othernode) - otherprop =3D get_property_by_label(dt, label, &othernode); + otherprop =3D get_property_by_label(dti, label, &othernode); if (!othernode) othermark =3D get_marker_label(dt, label, &othernode, &otherprop); diff --git a/dtc.h b/dtc.h index 5d39d31f..b596cdd0 100644 --- a/dtc.h +++ b/dtc.h @@ -318,8 +318,6 @@ const char *get_unitname(struct node *node); struct property *get_property(struct node *node, const char *propname); cell_t propval_cell(struct property *prop); cell_t propval_cell_n(struct property *prop, unsigned int n); -struct property *get_property_by_label(struct node *tree, const char *labe= l, - struct node **node); struct marker *get_marker_label(struct node *tree, const char *label, struct node **node, struct property **prop); struct node *get_subnode(struct node *node, const char *nodename); @@ -357,6 +355,8 @@ struct node *get_node_by_label(struct dt_info *dti, con= st char *label); struct node *get_node_by_phandle(struct dt_info *dti, cell_t phandle); struct node *get_node_by_ref(struct dt_info *dti, const char *ref); cell_t get_node_phandle(struct dt_info *dti, struct node *node); +struct property *get_property_by_label(struct dt_info *dti, const char *la= bel, + struct node **node); =20 /* DTS version flags definitions */ #define DTSF_V1 0x0001 /* /dts-v1/ */ diff --git a/livetree.c b/livetree.c index c42e9a97..332f2196 100644 --- a/livetree.c +++ b/livetree.c @@ -706,8 +706,9 @@ cell_t propval_cell_n(struct property *prop, unsigned i= nt n) return fdt32_to_cpu(*((fdt32_t *)prop->val.val + n)); } =20 -struct property *get_property_by_label(struct node *tree, const char *labe= l, - struct node **node) +static struct property *get_property_by_label_(struct node *tree, + const char *label, + struct node **node) { struct property *prop; struct node *c; @@ -723,7 +724,7 @@ struct property *get_property_by_label(struct node *tre= e, const char *label, } =20 for_each_child(tree, c) { - prop =3D get_property_by_label(c, label, node); + prop =3D get_property_by_label_(c, label, node); if (prop) return prop; } @@ -944,6 +945,21 @@ struct node *get_node_by_ref(struct dt_info *dti, cons= t char *ref) return NULL; } =20 +struct property *get_property_by_label(struct dt_info *dti, const char *la= bel, + struct node **node) +{ + struct property *property; + + if (dti->dt) { + property =3D get_property_by_label_(dti->dt, label, node); + if (property) + return property; + } + + *node =3D NULL; + return NULL; +} + static void add_phandle_property(struct node *node, const char *name, int format) { --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CF6543F7A9F; Wed, 26 Aug 2026 09:52:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737968; cv=none; b=Zoapt40dt1HBkWOMmMSdIQlHEZrTUQQ2EJhXXHCuTim6GCcheyopk1ykwLL+LUYebkGOuJJYZpp0gNcXupQYq3G7K1axEzVBL7hKJBeBAwM9G2sSY+CpoPS92x21XqNjw2/kEh16Dpb/1a89vhwIpv3rI+NmZW0n8N5TxRXHiyU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737968; c=relaxed/simple; bh=X7pbhpg/101LTo9o/g7iMXtMT2XWu7B+pPxVH8av++M=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ugsFbltDttSxXq/vAdFBBl70AxPsZ4JcGrMpgYQ3xwDTdc5Klsx0baTPOLWnSzOWe/WYrkd8DoLOiVK5b6SX6jkVjeYoDSh3adXVyx02uEVtYIJ+hX6BKFunjQLBCm0fojqJ1gG3JX0YLHFgMKgHMWuO/CLr1KRD1p9swCrb6VI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=Il8RseLc; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="Il8RseLc" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 555B34E413BF; Wed, 26 Aug 2026 09:52:45 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 2982B604EC; Wed, 26 Aug 2026 09:52:45 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 3FD1A11C7AD5F; Wed, 26 Aug 2026 11:52:42 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737964; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=rypeYF4ruAu+q4k7ZH+e67Lzb0VdbijEBA0/zrRJ2tA=; b=Il8RseLc9Mx5hnMkmLQUeJzV4TP38f2WqVCz92emevxGgM5RiYXRQhxuv9sgxNBQowjSvA FtWr/394LMrYRoiGiM99II2zOCqxTck4jvR5MdLbi9/A7BzltbYW00UKOrcfJiNV6RYeKy ODJ81wqYopCgTuo4ir0fkABf1gZB4HhVAexNy0r1Ap+a2qM7+STivL5CNwgyeJokA8gSV1 nPa7ddbFQZRLmSNojkRBVvgI06jSl27YCL7n9UjRgA+dzy1SbixDvdqUeQ9CCJhiFOMh6x H9R6lVVmCsgQHv6YAIZWG1cZaAoIwiVFbEt5aK5va0XN5sDQv2GNCZwyzQILjw== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 42/74] dtc: Change get_marker_label() signature to take dt_info Date: Wed, 26 Aug 2026 11:49:11 +0200 Message-ID: <20260826094950.1088288-43-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" The future introduction of orphan nodes for addons device-tree will lead to more than one tree in the addons data. Those trees will be: - the classical root tree starting at the root node - trees related to orphan nodes Also, an addon device-tree can have only trees based on orphan nodes. In other words an addon device-tree is valid without having the classical 'root' tree. To prepare orphan nodes introduction, move get_marker_label() parameter one level up and use dt_info struct instead of the 'root' tree (i.e. dti->dt). This change doesn't lead to any functional changes. Signed-off-by: Herve Codina --- checks.c | 4 +--- dtc.h | 4 ++-- livetree.c | 22 +++++++++++++++++++--- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/checks.c b/checks.c index 7b52f37c..2b87e212 100644 --- a/checks.c +++ b/checks.c @@ -447,7 +447,6 @@ static void check_duplicate_label(struct check *c, stru= ct dt_info *dti, const char *label, struct node *node, struct property *prop, struct marker *mark) { - struct node *dt =3D dti->dt; struct node *othernode =3D NULL; struct property *otherprop =3D NULL; struct marker *othermark =3D NULL; @@ -457,8 +456,7 @@ static void check_duplicate_label(struct check *c, stru= ct dt_info *dti, if (!othernode) otherprop =3D get_property_by_label(dti, label, &othernode); if (!othernode) - othermark =3D get_marker_label(dt, label, &othernode, - &otherprop); + othermark =3D get_marker_label(dti, label, &othernode, &otherprop); =20 if (!othernode) return; diff --git a/dtc.h b/dtc.h index b596cdd0..e2d90f63 100644 --- a/dtc.h +++ b/dtc.h @@ -318,8 +318,6 @@ const char *get_unitname(struct node *node); struct property *get_property(struct node *node, const char *propname); cell_t propval_cell(struct property *prop); cell_t propval_cell_n(struct property *prop, unsigned int n); -struct marker *get_marker_label(struct node *tree, const char *label, - struct node **node, struct property **prop); struct node *get_subnode(struct node *node, const char *nodename); =20 uint32_t guess_boot_cpuid(struct node *tree); @@ -357,6 +355,8 @@ struct node *get_node_by_ref(struct dt_info *dti, const= char *ref); cell_t get_node_phandle(struct dt_info *dti, struct node *node); struct property *get_property_by_label(struct dt_info *dti, const char *la= bel, struct node **node); +struct marker *get_marker_label(struct dt_info *dti, const char *label, + struct node **node, struct property **prop); =20 /* DTS version flags definitions */ #define DTSF_V1 0x0001 /* /dts-v1/ */ diff --git a/livetree.c b/livetree.c index 332f2196..f8abc5d4 100644 --- a/livetree.c +++ b/livetree.c @@ -733,8 +733,8 @@ static struct property *get_property_by_label_(struct n= ode *tree, return NULL; } =20 -struct marker *get_marker_label(struct node *tree, const char *label, - struct node **node, struct property **prop) +static struct marker *get_marker_label_(struct node *tree, const char *lab= el, + struct node **node, struct property **prop) { struct marker *m; struct property *p; @@ -751,7 +751,7 @@ struct marker *get_marker_label(struct node *tree, cons= t char *label, } =20 for_each_child(tree, c) { - m =3D get_marker_label(c, label, node, prop); + m =3D get_marker_label_(c, label, node, prop); if (m) return m; } @@ -960,6 +960,22 @@ struct property *get_property_by_label(struct dt_info = *dti, const char *label, return NULL; } =20 +struct marker *get_marker_label(struct dt_info *dti, const char *label, + struct node **node, struct property **prop) +{ + struct marker *marker; + + if (dti->dt) { + marker =3D get_marker_label_(dti->dt, label, node, prop); + if (marker) + return marker; + } + + *prop =3D NULL; + *node =3D NULL; + return NULL; +} + static void add_phandle_property(struct node *node, const char *name, int format) { --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 64FBE3C76BB; Wed, 26 Aug 2026 09:52:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737974; cv=none; b=dIkLD9ADd7x6Vz1J66ZmYPynn/X5UW2BSZY/nogUinz6VlY80FF6WUMqQxxOTKesQ/MhLehVGZ5rdFUfkWc3/ya4p89ia6xrSNLUxOro1H+56sphh2OV8uI61tFlKfEMkzXDxLCuqH6fXUt/O/XQdcGRiigx1eIfhq49zXW98/I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737974; c=relaxed/simple; bh=32HXnz0JNhGXTTyzr73cCsDK+zjwFrp1hFYlxjim9uA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Q/0a32+Z1Mas/xSPw1yNVnOQzRnDIn8YEes5jBDPatFhImDEZLefhIAiA1avpkbNHJiehYv0x1+yHWI+VRpsrvotqrkJZY04PTl4UseWKiwXlp2oXa3aYmydBEdATY4Svru25X1RLkAEDvaGRARi9hbgFLY0Fc0kF7lBQLvhA+I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=TZQSUjNQ; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="TZQSUjNQ" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 0D26B4E413BC; Wed, 26 Aug 2026 09:52:52 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id D62EB604EC; Wed, 26 Aug 2026 09:52:51 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 99CDB11C7AD52; Wed, 26 Aug 2026 11:52:44 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737966; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=QlhrHe1hz0RMEFm2j7aa9Cg2yZSF7D/6JMN8E7kGdU0=; b=TZQSUjNQ295AZ5E7HrYdMpyAXvQ6XJXhk+hZuFRTItEiO230her7V1VRnfk6gNAagUZP7E 8HaHNaCof8UJ9nX0K2SNFGw6VLo4i+5K75qEF6YWW77GAcPjLm1RTdNIC/yVABnS8MlHME kuBXsKFQHFZ6bPmN1QbD4h1AiCR8Eyo38HZx3tCA3hI1z79mwh+mav511553aJYZ95dvWk x6ZzOsulxXbSm7U5F/6kyr6yo3T6J5QImobpxl3SEOgY/3sJJLsnP8bO/D/E8pS64/uArz cYZNdT1J7W68q2bsw2NXv6pNg7aC9JDnik42HPxcRC8yTyh7tJ894sjXy0sqcg== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 43/74] dtc: Change fill_fullpaths() signature to take dt_info Date: Wed, 26 Aug 2026 11:49:12 +0200 Message-ID: <20260826094950.1088288-44-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" The future introduction of orphan nodes for addons device-tree will lead to more than one tree in the addons data. Those trees will be: - the classical root tree starting at the root node - trees related to orphan nodes Also, an addon device-tree can have only trees based on orphan nodes. In other words an addon device-tree is valid without having the classical 'root' tree. To prepare orphan nodes introduction, move fill_fullpaths() parameter one level up and use dt_info struct instead of the 'root' tree (i.e. dti->dt). This change doesn't lead to any functional changes. Signed-off-by: Herve Codina --- livetree.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/livetree.c b/livetree.c index f8abc5d4..a8c7c852 100644 --- a/livetree.c +++ b/livetree.c @@ -542,7 +542,7 @@ struct reserve_info *add_reserve_entry(struct reserve_i= nfo *list, return list; } =20 -static void fill_fullpaths(struct node *tree, const char *prefix) +static void fill_fullpaths_(struct node *tree, const char *prefix) { struct node *child; const char *unit; @@ -556,7 +556,14 @@ static void fill_fullpaths(struct node *tree, const ch= ar *prefix) tree->basenamelen =3D strlen(tree->name); =20 for_each_child(tree, child) - fill_fullpaths(child, tree->fullpath); + fill_fullpaths_(child, tree->fullpath); +} + +static void fill_fullpaths(struct dt_info *dti) +{ + /* Fill fullpaths for the root node */ + if (dti->dt) + fill_fullpaths_(dti->dt, ""); } =20 static void complete_ref_and_is_local(struct dt_info *dti, char **ref, @@ -660,7 +667,7 @@ struct dt_info *build_dt_info(unsigned int dtsflags, dti->boot_cpuid_phys =3D boot_cpuid_phys; dti->importsymlist =3D importsymlist; =20 - fill_fullpaths(dti->dt, ""); + fill_fullpaths(dti); =20 /* * Complete references (REF_PHANDLE and export symbols). --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D6C3B3B83FB; Wed, 26 Aug 2026 09:52:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737981; cv=none; b=VXXdoPnXm2sUnl6q4fRFo1zrIawpZbH+deqtRw5occNp8g/Tff6hfPc4guPVQenrFnK0VT5ZIiLUb/QaYt6elQRUkHf2d4HsvY/dFDSiRuV+2YOKlmfnSvxyXDKvsZbwv1CkklhOi/dqmU+rIIfO77krrGXtBu3wKW5HrgU2B0A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737981; c=relaxed/simple; bh=5H5Xdqn7I59ry0S69k3x1GpYewCgUlHgFW2KbfC0ipY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=B0ubrx5q9Gx/lXV9zKjCoVfBLFmjsZsX3pQiIcvrqEsmHUb0Kaw4Ts5PG51Fspu9ZmUU8frn+MF+NwonWlkA1ACqX+OJvOv+iN3E3D6yjD90tM1vAsxk4jC6u6WMcxqewkfm50YtMRI4Iff3+mxyW9d9+kAxB62Q6IpNjz2RCtY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=Q3JAXjMt; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="Q3JAXjMt" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 9CB451A183A; Wed, 26 Aug 2026 09:52:58 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 6F873604EC; Wed, 26 Aug 2026 09:52:58 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 259FF11C7AD64; Wed, 26 Aug 2026 11:52:51 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737973; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=vWyZ7z2zCioyA4zv+IRLz5Gm/rmhGBSJA8vlRVBYNfw=; b=Q3JAXjMtKtWK+tp/T4Ws4qV0qdXHsBneN+xF7jmY4qvebRO+C0XAWizbY0ymdhXw0tu56b r0bTitpXEHN+9ok1ovHha7quzmav5TvbMDQBqHdDE4bpyErtJAInVLD+ikAH5jyHyHMGBv 6Kmd+YDwFg4Ceg2oqYOQMBFp6T5bvvPgkwIEfSP3mutudY7Gc9YPXNdLjLlsOeWmCS5ogO ZlDzkP8ph8tYqngQEbDaXtLKXSs2Ciw+XJGb/erNa++RR/b7JzOGlP8Kcb737vmjhVYN8V MbaP/jxlqgAEoXQN8JhViCWCUbF87jOluVmvWTa6ELkzqBFp4P6J6d4nJ44qzQ== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 44/74] dtc: Introduce orphan nodes Date: Wed, 26 Aug 2026 11:49:13 +0200 Message-ID: <20260826094950.1088288-45-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" Orphans nodes can be present in plugin and addon device-trees. Those nodes are nodes without a parent. The root device-tree node is a particular orphan node and is not part of those 'orphan' nodes group. The orphan nodes group is related to nodes identified by a reference in addons or plugins device-trees. For instance, the following node can be described in addons and plugins (overlay) device-trees: --- 8< --- &foo { subnode { prop =3D <1>; }; }; --- 8< --- The foo referenced node described here has no parent. Indeed, it is not a child of the root node. This kind of node is legit in plugins and addons device-tree in order to perform modification on existing node when the plugin or addon dtb is applied. The foo referenced node is an existing node in the base tree an the subnode node is added to the foo referenced node chen the dtb is applied. Even if foo itself doesn't exists in the plugin or addon device-tree, it needs to be referenced and modifications expected need to be described (new sub-node for instance). In plugin dts, when a orphan node is parsed, the dts structure is changed and the orphan node is merged in the /fragment@n/__overlay__ node. The foo referenced node mentioned in the previous snippet is transformed to: --- 8< --- / { fragment@0 { target =3D <&foo>; __overlay__ { subnode { prop =3D <0x01>; }; }; }; __fixups__ { foo =3D "/fragment@0:target:0"; }; }; --- 8< --- With this mechanism, the orphan node itself doesn't exist anymore in resulting plugin dtb but the resulting device-tree contains meta-data mixed with pure 'device-tree' data. Addons have been introduced to avoid this kind of mixing. For addons, instead of changing the device-tree structure to add something similar to fragments and __overlay__ present in plugins, the orphan node will be present as a new dtb block and will be identified as orphan thanks to meta-data added in dtb. Modification done in this commit doesn't add functional changes but just introduce orphan nodes entry points in data structures and functions in order to prepare future changes related to parsing/generating dts and dtb files. Signed-off-by: Herve Codina --- dtc-parser.y | 4 ++-- dtc.h | 10 +++++++++- flattree.c | 3 ++- fstree.c | 3 ++- livetree.c | 16 +++++++++++++++- 5 files changed, 30 insertions(+), 6 deletions(-) diff --git a/dtc-parser.y b/dtc-parser.y index dd346fb4..47f644eb 100644 --- a/dtc-parser.y +++ b/dtc-parser.y @@ -132,7 +132,7 @@ sourcefile: { parser_output =3D build_dt_info($1, $2, $3, guess_boot_cpuid($3), - NULL); + NULL, NULL); } | headers memreserves importlist devicetree { @@ -143,7 +143,7 @@ sourcefile: */ parser_output =3D build_dt_info($1, $2, $4, $4 ? guess_boot_cpuid($4) : 0, - reverse_symbol($3)); + reverse_symbol($3), NULL); } ; =20 diff --git a/dtc.h b/dtc.h index e2d90f63..06dd7db1 100644 --- a/dtc.h +++ b/dtc.h @@ -250,6 +250,8 @@ struct node { const struct bus_type *bus; struct srcpos *srcpos; =20 + char *ref; /* Use only for orphan nodes */ + bool omit_if_unused, is_referenced; }; =20 @@ -277,6 +279,9 @@ struct node { #define for_each_symbol(s0, s) \ for ((s) =3D (s0); (s); (s) =3D (s)->next) =20 +#define for_each_orphan(o0, o) \ + for ((o) =3D (o0); (o); (o) =3D (o)->next_sibling) + void add_label(struct label **labels, char *label); void delete_labels(struct label **labels); =20 @@ -345,6 +350,7 @@ struct dt_info { uint32_t boot_cpuid_phys; struct node *dt; /* the device tree */ struct symbol *importsymlist; /* Import symbol list */ + struct node *orphanlist; /* orphan nodes list */ const char *outname; /* filename being written to, "-" for stdout */ }; =20 @@ -357,6 +363,7 @@ struct property *get_property_by_label(struct dt_info *= dti, const char *label, struct node **node); struct marker *get_marker_label(struct dt_info *dti, const char *label, struct node **node, struct property **prop); +bool node_is_orphan(struct dt_info *dti, const struct node *node); =20 /* DTS version flags definitions */ #define DTSF_V1 0x0001 /* /dts-v1/ */ @@ -366,7 +373,8 @@ struct marker *get_marker_label(struct dt_info *dti, co= nst char *label, struct dt_info *build_dt_info(unsigned int dtsflags, struct reserve_info *reservelist, struct node *tree, uint32_t boot_cpuid_phys, - struct symbol *importsymlist); + struct symbol *importsymlist, + struct node *orphanlist); void sort_tree(struct dt_info *dti); void generate_labels_from_tree(struct dt_info *dti, const char *name); void generate_label_tree(struct dt_info *dti, const char *name, bool alloc= ph); diff --git a/flattree.c b/flattree.c index 4f4a185a..bd6974b8 100644 --- a/flattree.c +++ b/flattree.c @@ -1315,5 +1315,6 @@ struct dt_info *dt_from_blob(const char *fname) if (get_subnode(tree, "__fixups__") || get_subnode(tree, "__local_fixups_= _")) dtsflags |=3D DTSF_PLUGIN; =20 - return build_dt_info(dtsflags, reservelist, tree, boot_cpuid_phys, import= symlist); + return build_dt_info(dtsflags, reservelist, tree, boot_cpuid_phys, + importsymlist, NULL); } diff --git a/fstree.c b/fstree.c index a6aaf1e8..2be1ffaf 100644 --- a/fstree.c +++ b/fstree.c @@ -72,5 +72,6 @@ struct dt_info *dt_from_fs(const char *dirname) tree =3D read_fstree(dirname); tree =3D name_node(tree, ""); =20 - return build_dt_info(DTSF_V1, NULL, tree, guess_boot_cpuid(tree), NULL); + return build_dt_info(DTSF_V1, NULL, tree, guess_boot_cpuid(tree), NULL, + NULL); } diff --git a/livetree.c b/livetree.c index a8c7c852..fddb4b4f 100644 --- a/livetree.c +++ b/livetree.c @@ -656,7 +656,8 @@ static void complete_references(struct dt_info *dti) struct dt_info *build_dt_info(unsigned int dtsflags, struct reserve_info *reservelist, struct node *tree, uint32_t boot_cpuid_phys, - struct symbol *importsymlist) + struct symbol *importsymlist, + struct node *orphanlist) { struct dt_info *dti; =20 @@ -666,6 +667,7 @@ struct dt_info *build_dt_info(unsigned int dtsflags, dti->dt =3D tree; dti->boot_cpuid_phys =3D boot_cpuid_phys; dti->importsymlist =3D importsymlist; + dti->orphanlist =3D orphanlist; =20 fill_fullpaths(dti); =20 @@ -952,6 +954,18 @@ struct node *get_node_by_ref(struct dt_info *dti, cons= t char *ref) return NULL; } =20 +bool node_is_orphan(struct dt_info *dti, const struct node *node) +{ + struct node *orphan; + + for_each_orphan(dti->orphanlist, orphan) { + if (orphan =3D=3D node) + return true; + } + + return false; +} + struct property *get_property_by_label(struct dt_info *dti, const char *la= bel, struct node **node) { --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E040831D39A; Wed, 26 Aug 2026 09:53:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737987; cv=none; b=K5/HzaLOuXJvroDQ5zEodaQ+kxiM3umIjPdQQn1LA+62c4NcQ6u/yCseWBMOqclb9MIzFUr0jfbphoGkIcBWkThoCHkHWuAp1XoclYGfr5wauBMec0KLoNon8Jw8ryOX0qBLue4ce5Aeb9h1B+ZvukTg9rHUBHaklKXWm/53I38= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737987; c=relaxed/simple; bh=7uG7E4D9qhhXOQWHcZ6nAEsM827E5OiGTL6M3Ol5EUw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=qttlroI70xIKvOY61nkYR7aJeXnw/ggFB/fgDOSDuJBqNAu6/4Yt53cet4j92RWvcQrVqqxsk0udIHWS0F3Vsvpkty6wc3zoPqoWj1ZzV5h0vcoXWktY3Q1SQe3AVReWa+KjcZTF3rid2V/pGUfmtf+XMddfE38d/j89it7Pgvg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=arrXAn+p; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="arrXAn+p" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id A3FFF1A183A; Wed, 26 Aug 2026 09:53:04 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 77799604EC; Wed, 26 Aug 2026 09:53:04 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id E0F1C11C7AD35; Wed, 26 Aug 2026 11:52:57 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737979; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=X3QHQNsEvF+JwH/XQ0R8jOEuG/8AhpR8wL7FDcBtvew=; b=arrXAn+pRRe1vngJ45atN9T/kPj/9bs2AiHlf27hNqdFKOEATfGBshcWkzLNFKQp/C+/wi 8KvlHxmjH5/y5n9UWenOuGFW9ofT9CPdPPETAxle8cPj1PWCxDO63uiXJdX9mOOIWJfWhb KHqBoIS9SS8yYNqFhJcl4HjnFbalM2GZ1ISOR2O98pOAJt2L/34AMCR5vh7Mj2RH5j1neC FXS513gKfT/JY8K96NiwK4mpdCFX/MQHKieGz5qFD1VtAOupyWpK8jeBZcWdkV5GzRpZ2g B/4fi7CNBPOUVZxoRR/0BCJx2IGMqJKRvTdYWT8L7z7k3sZ9Nn+MhjRpY8NbCw== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 45/74] dtc: Handle orphan nodes in get_xxx_by_yyy() Date: Wed, 26 Aug 2026 11:49:14 +0200 Message-ID: <20260826094950.1088288-46-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" Orphan nodes have been introduced recently. Retrieving a node, a property and/or a marker from an orphan node tree is perfectly legit. Those retrievals are performed by the get_xxx_by_yyy() functions family. Update them to handle orphan nodes. Note: Retrieving a node by path (get_node_py_path() function) from an orphan node tree is not yet supported. Indeed, there is no way to define a path involving an orphan node. Signed-off-by: Herve Codina --- livetree.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/livetree.c b/livetree.c index fddb4b4f..c61025a5 100644 --- a/livetree.c +++ b/livetree.c @@ -917,6 +917,7 @@ struct node *get_node_by_path(struct dt_info *dti, cons= t char *path) =20 struct node *get_node_by_label(struct dt_info *dti, const char *label) { + struct node *orphan; struct node *node; =20 if (dti->dt) { @@ -925,11 +926,18 @@ struct node *get_node_by_label(struct dt_info *dti, c= onst char *label) return node; } =20 + for_each_orphan(dti->orphanlist, orphan) { + node =3D get_node_by_label_(orphan, label); + if (node) + return node; + } + return NULL; } =20 struct node *get_node_by_phandle(struct dt_info *dti, cell_t phandle) { + struct node *orphan; struct node *node; =20 if (dti->dt) { @@ -938,11 +946,18 @@ struct node *get_node_by_phandle(struct dt_info *dti,= cell_t phandle) return node; } =20 + for_each_orphan(dti->orphanlist, orphan) { + node =3D get_node_by_phandle_(orphan, phandle); + if (node) + return node; + } + return NULL; } =20 struct node *get_node_by_ref(struct dt_info *dti, const char *ref) { + struct node *orphan; struct node *node; =20 if (dti->dt) { @@ -951,6 +966,12 @@ struct node *get_node_by_ref(struct dt_info *dti, cons= t char *ref) return node; } =20 + for_each_orphan(dti->orphanlist, orphan) { + node =3D get_node_by_ref_(orphan, ref); + if (node) + return node; + } + return NULL; } =20 @@ -970,6 +991,7 @@ struct property *get_property_by_label(struct dt_info *= dti, const char *label, struct node **node) { struct property *property; + struct node *orphan; =20 if (dti->dt) { property =3D get_property_by_label_(dti->dt, label, node); @@ -977,6 +999,12 @@ struct property *get_property_by_label(struct dt_info = *dti, const char *label, return property; } =20 + for_each_orphan(dti->orphanlist, orphan) { + property =3D get_property_by_label_(orphan, label, node); + if (property) + return property; + } + *node =3D NULL; return NULL; } @@ -985,6 +1013,7 @@ struct marker *get_marker_label(struct dt_info *dti, c= onst char *label, struct node **node, struct property **prop) { struct marker *marker; + struct node *orphan; =20 if (dti->dt) { marker =3D get_marker_label_(dti->dt, label, node, prop); @@ -992,6 +1021,12 @@ struct marker *get_marker_label(struct dt_info *dti, = const char *label, return marker; } =20 + for_each_orphan(dti->orphanlist, orphan) { + marker =3D get_marker_label_(orphan, label, node, prop); + if (marker) + return marker; + } + *prop =3D NULL; *node =3D NULL; return NULL; --=20 2.55.0 From nobody Mon Sep 28 04:49:02 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4C4483F9F2F; Wed, 26 Aug 2026 09:53:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737989; cv=none; b=XxpGCh0foJpfmvz1kv36Oh17Alc76It6Q3zWbNhN7i4hvZDIxBOZZNMi3x6GJr0F2TurPRe+eJK12j4GiRQvnQpehu+YvrRXloHpi/+7t5haRKl04fIsDf9t5qezeoX5GfQl/bd6mzKxTR7Matjby1A6c8gH6pSR3U24MKYPrE0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737989; c=relaxed/simple; bh=CD1bpG7Cvi6RGJrc4qx9SlGoPdRjIGzcOLi9lRL5JZY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=P2PfbTgIlJghW0tjpoA6vXnOs5rQUqz8J5/JtUxLMbeSa9Ubn7ER3IP/8lh06e5SAydb6XBawjGg9wWkM+T/BsNtQCo4X0z7aYkz+wVqWGiQwZXKihhbyvvcqmR6RQGipvPYydrP9oktUiLQI3VzFuB+IN/kIWiGUP8bTIcNSqw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=i7rCTuv4; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="i7rCTuv4" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 061844E413BC; Wed, 26 Aug 2026 09:53:07 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id CF548604EC; Wed, 26 Aug 2026 09:53:06 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 127AB11C7AD37; Wed, 26 Aug 2026 11:53:03 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737985; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=4YS4HqvFeRpSjubmer6FhoDk+l6CJqKqfiB3rNIUEeM=; b=i7rCTuv467DVp0yhVaN2taCfCLp7GNw4Yfp05SkUtFicQnuJUjN/TEWmUQsIZtXFZhZuJJ FS5j3j4HfV2CKR4wKxSSHsGKAzNnZUDskjP0rsBuItHL4V5dalXlSHkab5veltP3ofaNdE xa0EtJvnYM1UTkDXptXNlqCsVYmCUG3oolO2+PruDNJok8oVTGaeHe+sMzBGbR/C4h2wdj RJICGLZqc8fPSPaoLZ6OIGNocpJ5pvWUYXPMpOByeBAY5QwrTfbZDWGnGr984dImNsJepM Z6B0pK/hJVe6GIuHEK6iZVzrMCGIyJxMo3Fd3NvL+vYGl/27BnpYNaucp+t6/A== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 46/74] dtc: Avoid NULL fullpath for nodes in orphan trees Date: Wed, 26 Aug 2026 11:49:15 +0200 Message-ID: <20260826094950.1088288-47-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" Orphan nodes have been introduced recently. The process_checks() function uses fullpath in several places and crashes due NULL pointer dereferences if fullpath is NULL. In order to have process_checks() function running without crashes with orphan trees (i.e. trees based on orphan nodes), the fullpath of node available in those orphan trees must not be NULL. Fullpath values are built by dti_fill_fullpaths(). Update it to handle fullpath in trees based on orphan nodes. Use a simple "__orphan__/" prefix to avoid the NULL pointer and to be distinct from the root node ("/" prefix). It is worth noting that this "__orphan__/" prefix is a temporary prefix and it will be change later when support for reference by path involving nodes in orphan tree is added. Signed-off-by: Herve Codina --- livetree.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/livetree.c b/livetree.c index c61025a5..8f0aa868 100644 --- a/livetree.c +++ b/livetree.c @@ -561,9 +561,14 @@ static void fill_fullpaths_(struct node *tree, const c= har *prefix) =20 static void fill_fullpaths(struct dt_info *dti) { + struct node *orphan; + /* Fill fullpaths for the root node */ if (dti->dt) fill_fullpaths_(dti->dt, ""); + + for_each_orphan(dti->orphanlist, orphan) + fill_fullpaths_(orphan, "__orphan__/"); } =20 static void complete_ref_and_is_local(struct dt_info *dti, char **ref, --=20 2.55.0 From nobody Mon Sep 28 04:49:03 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 515B73F9F4C; Wed, 26 Aug 2026 09:53:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737991; cv=none; b=oyEnsEocYjQaqsOJ59ikvjKx/FbX1XdtMD/k74U7F3HFibYoMIW/aDaxre7189A+Dwid6GtbqMBeO2WQhZ746+KOjxr8cw5F0O7ISItg7/y9r0fZomB2NLnFlEjJFXOvKpoPeDvSD2UPAwAq61VNWCQtf/V4vBqpH3guUw9nrfk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737991; c=relaxed/simple; bh=PFmytyHuQnrMV2ZFVJV44YUZuZ7Vug2ZIztzzJ1uARQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=uuJmqafUoYivsuZfVGbhOtxOJfq7R2/DT5No8j+F4nxXa4sWcSi5lBDqVo11ERfigpwDFVDlYRMcQ8t2/lR2Gur/EUAaHP64UFqU40etVHgjCF1XbxKIOcWM2wey7zbcA8wiVMOBctXCBY3HZhx4KuNV2YgM3LtJWzURTIGL5+s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=s1E7ULR/; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="s1E7ULR/" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 1087E1A183E; Wed, 26 Aug 2026 09:53:09 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id D92BA604EC; Wed, 26 Aug 2026 09:53:08 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 5214211C7AD65; Wed, 26 Aug 2026 11:53:06 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737987; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=BBpOfDPqB+DEsSfu2qjc8VkO36mrZzucihzjxLAntww=; b=s1E7ULR/hjCVoqJEm7lkGmV7T1QCAO8+i4h4wummv9TLzaCgqtCntp18IFbP/volakv2rt f6xtmQZ3SJIWkNBRnbCT4b1ZfvEGHIKxR9e9HGIvo+4vXIA+8OweO3d85L5zgS8HQBzRrW jjGPFyhMS/k21/X78E4Qjb+DBf3UzfwNQZa3/jeQnjflq7V9zslw9PNRVHVg9M/v5OK9/i zbC6SiqURpRhttXXEUQcgVZ1QL9W6SekGzvFEImsUCTVCoonpHqAt5cefD/TZ9WuB95MJ8 dY+NVgM0SuWmAja/1O8yEg41DWWUdaARCwlxeEoVufxrH6RElFXQ0gq7SfAm+A== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 47/74] dtc: Handle orphan nodes in complete_references() Date: Wed, 26 Aug 2026 11:49:16 +0200 Message-ID: <20260826094950.1088288-48-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" Orphan nodes have been introduced recently. Completing references involving orphan nodes is needed just like for the 'root' node. Also, it is worth noting that even if an orphan node can be referenced, this orphan node is an external node and so the references pointing to orphan nodes cannot be a local reference. Update related functions to handle orphan nodes. Signed-off-by: Herve Codina --- livetree.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/livetree.c b/livetree.c index 8f0aa868..71712649 100644 --- a/livetree.c +++ b/livetree.c @@ -584,11 +584,15 @@ static void complete_ref_and_is_local(struct dt_info = *dti, char **ref, * phandle value is available) but not the reference. * * Complete both ref and is_local based on existing values. + * + * Also take care of references pointing to an orphan node. Those + * reference are not local references. Indeed, an orphan node is an + * external node. */ =20 if (*ref) { refnode =3D get_node_by_ref(dti, *ref); - if (refnode) + if (refnode && !node_is_orphan(dti, refnode)) *is_local =3D true; else *is_local =3D false; @@ -655,7 +659,12 @@ static void complete_references_internal(struct dt_inf= o *dti, struct node *node) =20 static void complete_references(struct dt_info *dti) { + struct node *orphan; + complete_references_internal(dti, dti->dt); + + for_each_orphan(dti->orphanlist, orphan) + complete_references_internal(dti, orphan); } =20 struct dt_info *build_dt_info(unsigned int dtsflags, --=20 2.55.0 From nobody Mon Sep 28 04:49:03 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AEB823FC5AF; Wed, 26 Aug 2026 09:53:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737994; cv=none; b=MrQGFoaXENk4o3jpEF1Ui0IcIRxSwhywKh4Hqkj4/79CAbFotjndiZRcM4kaxQLqtjmST8pOzZuCY3Kva5vuRlJD8WFE6c+pnaj0A9zCwRcYnr1Q0CE/InsrkYMDB6kXxzjgOl4JrLi2iea1Lwlko2xm3HJ2IiHem30C1KPOfYY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737994; c=relaxed/simple; bh=NUD4YcxZSfhRExTbK6LeLNrFCOTxBlnwN4MTLjMfOYk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=NxgrCz2SCxbe1Y7QRd96xFWMmcjTgXasEX6xr1/QHNO3F60RJCQjEtkqF9OGiEEj3VSqklvv3CwuTkqGVAt9EGOIEdH15milv3s3Rw5T1OMHeul1+M8iSvmPcAtQA9ILEJmZ41qEEKKA008hieE/BlKG3viqpTcUMoet/5gWA7w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=AI0MAE+9; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="AI0MAE+9" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 47A821A183A; Wed, 26 Aug 2026 09:53:11 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 1C95C604EC; Wed, 26 Aug 2026 09:53:11 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 5E9FF11C7AD6C; Wed, 26 Aug 2026 11:53:08 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737990; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=fR4+mkB8Ep73YfuoneA+uOAgSJ2DGQUU6W45DVoKB1o=; b=AI0MAE+9eR5deNUSLSkHAYd9voHyKZgIGs+N1nBCGbhSDm3eA2jXkRUN4diH1YUgocsuyU tnR3D87Uka55ycqUxX+Dhj1xuYXZbrT+tOGa6G6YWV8n42OEer5EAsozJFNgettf5xns+Z a1gW2fFtGWSC2JuTDnts9Uqgp71Af4V/V9s5t0weyAAFEAgV4qwsQxdnWt7GNcKO3Y61Ox okon1mOnCpVOhvLQnDhIS8E/iDGtDaPVaYUAfYmuvk6rGLMxmhUWe47gHaJI3CJIstNbBU t6TcwmsgN5ObDtif4QPtNyEp/UQolGYnTY75H67TnkPOOifD009cvLPcNI7dCw== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 48/74] checks: Perform checks for orphan nodes Date: Wed, 26 Aug 2026 11:49:17 +0200 Message-ID: <20260826094950.1088288-49-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" Orphan nodes have been introduced recently. Those nodes and related trees need to be handled by the check process. Indeed, in addition to performing checks, phandles are allocated and referenced nodes are marked 'referenced' during the check process. Take into account orphan nodes in check process. Signed-off-by: Herve Codina --- checks.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/checks.c b/checks.c index 2b87e212..a0024389 100644 --- a/checks.c +++ b/checks.c @@ -155,6 +155,7 @@ static bool is_multiple_of(int multiple, int divisor) static bool run_check(struct check *c, struct dt_info *dti) { struct node *dt =3D dti->dt; + struct node *orphan; bool error =3D false; int i; =20 @@ -180,6 +181,9 @@ static bool run_check(struct check *c, struct dt_info *= dti) =20 check_nodes_props(c, dti, dt); =20 + for_each_orphan(dti->orphanlist, orphan) + check_nodes_props(c, dti, orphan); + if (c->status =3D=3D UNCHECKED) c->status =3D PASSED; =20 @@ -313,7 +317,12 @@ ERROR(duplicate_property_names, check_duplicate_proper= ty_names, NULL); static void check_node_name_chars(struct check *c, struct dt_info *dti, struct node *node) { - size_t n =3D strspn(node->name, c->data); + size_t n; + + if ((dti->dtsflags & DTSF_ADDON) && node_is_orphan(dti, node)) + return; /* Checking name doesn't make sense for an orphan node */ + + n =3D strspn(node->name, c->data); =20 if (n < strlen(node->name)) FAIL(c, dti, node, "Bad character '%c' in node name", @@ -324,7 +333,12 @@ ERROR(node_name_chars, check_node_name_chars, NODECHAR= S); static void check_node_name_chars_strict(struct check *c, struct dt_info *= dti, struct node *node) { - size_t n =3D strspn(node->name, c->data); + size_t n; + + if ((dti->dtsflags & DTSF_ADDON) && node_is_orphan(dti, node)) + return; /* Checking name doesn't make sense for an orphan node */ + + n =3D strspn(node->name, c->data); =20 if (n < node->basenamelen) FAIL(c, dti, node, "Character '%c' not recommended in node name", @@ -628,6 +642,15 @@ static void fixup_phandle_references(struct check *c, = struct dt_info *dti, cpu_to_fdt32(0xffffffff); continue; } + if (node_is_orphan(dti, refnode)) { + if (!(dti->dtsflags & DTSF_ADDON)) + FAIL(c, dti, node, "Reference to orphan node \"%s\"\n", + m->ref); + else /* mark the entry as unresolved */ + *((fdt32_t *)(prop->val.val + m->offset)) =3D + cpu_to_fdt32(0xffffffff); + continue; + } =20 phandle =3D get_node_phandle(dti, refnode); *((fdt32_t *)(prop->val.val + m->offset)) =3D cpu_to_fdt32(phandle); --=20 2.55.0 From nobody Mon Sep 28 04:49:03 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CF10E3D8900; Wed, 26 Aug 2026 09:53:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737996; cv=none; b=Tsv5YEVx2TyLbWkuEP6tQP1Nc720fFQC4k2sA8KKWkQZZFnLy/ZJQvLZxfTjTM/jDiNpYK1bYVr+pynjvZi9LT36uYk/7k1T693++zQRB6Ag1LpBjE42aWmnJP+RAp6j7VC9fVa/cYKuUeW2VVQ6NCnfNPM3y1e6lttoljlV/Xw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737996; c=relaxed/simple; bh=d9LYov45tYlEpzEj8R1MMFOs3pKjPYhMHcPGJ68mkNk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=fmbb2Ma+dGPHjbF3xFZwv1qTaowVFVPhtYL6H3a0UvokT/HmcTs9YTnE35fpi5TPm7aKFGzU6Yvqx2vRBqKtVGLI39LuJ7wnpbtUJfe8vAGdQEZVC437ImJQp02gRnm7prUM664+iTATu/Ya0Oc3Fu1uQkwr0Oy+nZd45p7OSfk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=1N9M6mUC; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="1N9M6mUC" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 733BF1A0E1B; Wed, 26 Aug 2026 09:53:13 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 41B10604EC; Wed, 26 Aug 2026 09:53:13 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id CBF5F11C7AD35; Wed, 26 Aug 2026 11:53:10 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737992; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=qfxlR2RQiwmgkv+b8NT3/RctLuodoQblwI+ysKo3gNs=; b=1N9M6mUClatuNdXNiPIgWHSEK9KuxwNIPlrYhyWR3w7uaBGVJLrOOsWyzrf2FXMpRW79gT hYP9xXVGI/u8AMojMi9V5zyyUSqYewvcbxbx5zxQTXB3Z2jG8uLbWlopHlcPOTpsh/yQTk UDNO7IHooA6NRBfMKt1BVZASUo9hp9EA29MhHTgYHKSxMUnCao6kVUJauA4aLe8NBeoI/S nG5Jl22ZxEhGE3DI9JhDNQShGDbr+RagxOSRnoo+DCwKa5Ms4wfwGSquRmaCyRveHa7GN2 Lc7fq6tJfYWkoVSsRq2pxiLoIVRWSqY4BTaTmNZ3sEqgv45iLCx3jRVLfQZ0uw== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 49/74] dtc: Rename add_orphan_node() to plugin_add_orphan_node() Date: Wed, 26 Aug 2026 11:49:18 +0200 Message-ID: <20260826094950.1088288-50-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" add_orphan_node() is used when a orphan node is parsed in a plugin (overlay) device-tree. This function creates some device-tree nodes (/fragment@n/__overlay__) in order to merge the parsed orphan node. This is specific to plugin device-trees and cannot be used for addon device-trees. In order to clarify that add_orphan_node() is specific to plugin device-trees and to prepare the support for orphan node parsing in the addon context, rename current add_orphan_node() to plugin_add_orphan_node(). Signed-off-by: Herve Codina --- dtc-parser.y | 6 +++--- dtc.h | 3 ++- livetree.c | 3 ++- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/dtc-parser.y b/dtc-parser.y index 47f644eb..885123af 100644 --- a/dtc-parser.y +++ b/dtc-parser.y @@ -245,7 +245,7 @@ devicetree: ERROR(&@2, "Label or path %s not found", $1); else if (is_ref_relative($1)) ERROR(&@2, "Label-relative reference %s not supported in plugin", $1); - $$ =3D add_orphan_node( + $$ =3D plugin_add_orphan_node( name_node(build_node(NULL, NULL, NULL, NULL), ""), $2, $1); @@ -269,7 +269,7 @@ devicetree: if (last_header_flags & DTSF_PLUGIN) { if (is_ref_relative($2)) ERROR(&@2, "Label-relative reference %s not supported in plugin", $2); - add_orphan_node($1, $3, $2); + plugin_add_orphan_node($1, $3, $2); } else { struct node *target =3D parser_get_node_by_ref($1, $2); =20 @@ -288,7 +288,7 @@ devicetree: merge_nodes(target, $3); } else { if (last_header_flags & DTSF_PLUGIN) - add_orphan_node($1, $3, $2); + plugin_add_orphan_node($1, $3, $2); else ERROR(&@2, "Label or path %s not found", $2); } diff --git a/dtc.h b/dtc.h index 06dd7db1..cad092c1 100644 --- a/dtc.h +++ b/dtc.h @@ -307,7 +307,8 @@ struct node *omit_node_if_unused(struct node *node); struct node *reference_node(struct node *node); struct node *chain_node(struct node *first, struct node *list); struct node *merge_nodes(struct node *old_node, struct node *new_node); -struct node *add_orphan_node(struct node *old_node, struct node *new_node,= char *ref); +struct node *plugin_add_orphan_node(struct node *old_node, struct node *ne= w_node, + char *ref); =20 void add_property(struct node *node, struct property *prop); void delete_property_by_name(struct node *node, char *name); diff --git a/livetree.c b/livetree.c index 71712649..ad9ae295 100644 --- a/livetree.c +++ b/livetree.c @@ -319,7 +319,8 @@ struct node *merge_nodes(struct node *old_node, struct = node *new_node) return old_node; } =20 -struct node * add_orphan_node(struct node *dt, struct node *new_node, char= *ref) +struct node *plugin_add_orphan_node(struct node *dt, struct node *new_node, + char *ref) { static unsigned int next_orphan_fragment =3D 0; struct node *node; --=20 2.55.0 From nobody Mon Sep 28 04:49:03 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3F9CC3C5855; Wed, 26 Aug 2026 09:53:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737999; cv=none; b=u/zmQkw+zHb2XfOXSNV3a42v/WpqxYzKRGXKSMvkrPIVbEFoVz02neO6xN9vgvCzRkvMm/4M58ltQhfgx96U2apMq1NreDh9aNDQLvZwz3DHsIKloldnbGzfGDIbidE1muIj989pmFF6sZ2rXn9FBXY32KQqcXD3n2VfuAOBYmE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787737999; c=relaxed/simple; bh=oyz3CsgYdxIfmJMyNM0huqvHDABcNMBSVcIQSGrzmyQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=QvYmxOs5Ih63x5Hy2u8ItmLqSTke7KMLKrTrBnTfn8nae5tnnZ0x7THq7zbR8E3yH+9bd8o+lYRpse0eAiD6lcpzkc3JjJtZ3WMshPcLRM5wJrUc3zf7uTPWHk1WFq7D7URLmXAK1aBjohn7KIvIeMH8wECGxJgTw3zDxsPCfgo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=yr5P4SCY; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="yr5P4SCY" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id DF8B24E413BF; Wed, 26 Aug 2026 09:53:15 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id AE29F604EC; Wed, 26 Aug 2026 09:53:15 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id D685211C7ACD5; Wed, 26 Aug 2026 11:53:12 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737994; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=sgF0PhQ58PpIbQcIJSGs/F6uEdAznO75JcU5b7dSayY=; b=yr5P4SCY5iEgB3YqqKAdSzaLaSncN0qWqgK1wtgk891K/DvZatdmWVwXXHmen2kLLxw/oP HthHmMLTaILqurmZbz7e4qrNEHuAuHf+HexQrNUNfZHLcUHTxgl/XuSOq1h7Jb5GRggypU txT3TJuvVO90V/Z8Z/nmTDRo2oxUkXTxekWsjhICpwDuiJuqVmUNsm5kgvCaxM/+4vD3SA V7BqhNDgwY5qUlfDE9VMttqqxDpMX5ekLVPLkBVuV+tK1Ij4IgWQ5HtnjMex5B2AeW9rHW HZaB4aVUGLASO8kvfD6+E4vUaJVFngwlc50WZUm4rPhUCNEnHQlv1XsRKh3BJg== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 50/74] dtc: Add basic support for addon orphan nodes in dts Date: Wed, 26 Aug 2026 11:49:19 +0200 Message-ID: <20260826094950.1088288-51-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" Orphan nodes are nodes without a parent. The root device-tree node is a particular orphan node and is not part of those 'orphan' nodes group. The orphan nodes group is related to nodes identified by a reference in addons or plugins device-trees. For instance, int the following snippet, foo is an orphan node: --- 8< --- /addon/ &foo { subnode { prop =3D <1>; }; }; --- 8< --- The foo referenced node described has no parent. Indeed, it is not a child of the root node. This kind of node is legit in addons device-tree in order to perform modification on existing node when the addon dtb is applied. Add support for addon orphan node in dts. Compared to plugin (overlay) orphan node parsing, the orphan node parsed in the addon context does not lead to any change in the device-tree structure. '/fragment@0/__overlay__' or similar kind of structure is not needed for addons. Signed-off-by: Herve Codina --- dtc-parser.y | 60 +++++++++++++++++++++++++++++++++++----------------- dtc.h | 2 ++ livetree.c | 30 ++++++++++++++++++++++++++ treesource.c | 8 +++++++ 4 files changed, 81 insertions(+), 19 deletions(-) diff --git a/dtc-parser.y b/dtc-parser.y index 885123af..197a9533 100644 --- a/dtc-parser.y +++ b/dtc-parser.y @@ -23,6 +23,7 @@ extern void yyerror(char const *s); =20 extern struct dt_info *parser_output; extern bool treesource_error; +extern struct node *parser_orphanlist; =20 unsigned int last_header_flags; =20 @@ -31,7 +32,8 @@ static bool is_ref_relative(const char *ref) return ref[0] !=3D '/' && strchr(&ref[1], '/'); } =20 -static struct node *parser_get_node_by_ref(struct node *dt, const char *re= f) +static struct node *parser_get_node_by_ref(struct node *dt, struct node *o= rphanlist, + const char *ref) { /* * Use a temporary dt_info in order to use dti_get_node_by_ref() @@ -39,6 +41,7 @@ static struct node *parser_get_node_by_ref(struct node *d= t, const char *ref) struct dt_info dti =3D {}; =20 dti.dt =3D dt; + dti.orphanlist =3D orphanlist; =20 return get_node_by_ref(&dti, ref); } @@ -132,7 +135,7 @@ sourcefile: { parser_output =3D build_dt_info($1, $2, $3, guess_boot_cpuid($3), - NULL, NULL); + NULL, parser_orphanlist); } | headers memreserves importlist devicetree { @@ -143,7 +146,8 @@ sourcefile: */ parser_output =3D build_dt_info($1, $2, $4, $4 ? guess_boot_cpuid($4) : 0, - reverse_symbol($3), NULL); + reverse_symbol($3), + parser_orphanlist); } ; =20 @@ -241,21 +245,28 @@ devicetree: } | dt_ref nodedef { - if (!(last_header_flags & DTSF_PLUGIN)) + if (!(last_header_flags & (DTSF_PLUGIN | DTSF_ADDON))) ERROR(&@2, "Label or path %s not found", $1); else if (is_ref_relative($1)) - ERROR(&@2, "Label-relative reference %s not supported in plugin", $1); - $$ =3D plugin_add_orphan_node( - name_node(build_node(NULL, NULL, NULL, NULL), - ""), - $2, $1); + ERROR(&@2, "Label-relative reference %s not supported in plugin nor ad= don", $1); + + if (last_header_flags & DTSF_PLUGIN) { + $$ =3D plugin_add_orphan_node( + name_node(build_node(NULL, NULL, NULL, NULL), + ""), + $2, $1); + } else { + ERROR(&@2, "Orphan node %s without a root node not yet supported", $1); + YYERROR; + } } | devicetree DT_LABEL dt_ref nodedef { - struct node *target =3D parser_get_node_by_ref($1, $3); + struct node *target =3D parser_get_node_by_ref( + $1, parser_orphanlist, $3); =20 - if ((last_header_flags & DTSF_PLUGIN) && is_ref_relative($3)) - ERROR(&@2, "Label-relative reference %s not supported in plugin", $3); + if ((last_header_flags & (DTSF_PLUGIN | DTSF_ADDON)) && is_ref_relative= ($3)) + ERROR(&@2, "Label-relative reference %s not supported in plugin nor ad= don", $3); =20 if (target) { add_label(&target->labels, $2); @@ -266,12 +277,17 @@ devicetree: } | devicetree DT_PATH_REF nodedef { - if (last_header_flags & DTSF_PLUGIN) { + if (last_header_flags & (DTSF_PLUGIN | DTSF_ADDON)) { if (is_ref_relative($2)) - ERROR(&@2, "Label-relative reference %s not supported in plugin", $2); - plugin_add_orphan_node($1, $3, $2); + ERROR(&@2, "Label-relative reference %s not supported in plugin nor a= ddon", $2); + if(last_header_flags & DTSF_PLUGIN) + plugin_add_orphan_node($1, $3, $2); + else + addon_add_orphan_node(&parser_orphanlist, + orphan_node($3, $2)); } else { - struct node *target =3D parser_get_node_by_ref($1, $2); + struct node *target =3D parser_get_node_by_ref( + $1, parser_orphanlist, $2); =20 if (target) merge_nodes(target, $3); @@ -282,13 +298,17 @@ devicetree: } | devicetree DT_LABEL_REF nodedef { - struct node *target =3D parser_get_node_by_ref($1, $2); + struct node *target =3D parser_get_node_by_ref( + $1, parser_orphanlist, $2); =20 if (target) { merge_nodes(target, $3); } else { if (last_header_flags & DTSF_PLUGIN) plugin_add_orphan_node($1, $3, $2); + else if (last_header_flags & DTSF_ADDON) + addon_add_orphan_node(&parser_orphanlist, + orphan_node($3, $2)); else ERROR(&@2, "Label or path %s not found", $2); } @@ -296,7 +316,8 @@ devicetree: } | devicetree DT_DEL_NODE dt_ref ';' { - struct node *target =3D parser_get_node_by_ref($1, $3); + struct node *target =3D parser_get_node_by_ref( + $1, parser_orphanlist, $3); =20 if (target) delete_node(target); @@ -308,7 +329,8 @@ devicetree: } | devicetree DT_OMIT_NO_REF dt_ref ';' { - struct node *target =3D parser_get_node_by_ref($1, $3); + struct node *target =3D parser_get_node_by_ref( + $1, parser_orphanlist, $3); =20 if (target) omit_node_if_unused(target); diff --git a/dtc.h b/dtc.h index cad092c1..de5fa266 100644 --- a/dtc.h +++ b/dtc.h @@ -309,6 +309,8 @@ struct node *chain_node(struct node *first, struct node= *list); struct node *merge_nodes(struct node *old_node, struct node *new_node); struct node *plugin_add_orphan_node(struct node *old_node, struct node *ne= w_node, char *ref); +struct node *orphan_node(struct node *node, const char *ref); +void addon_add_orphan_node(struct node **dt_orphan, struct node *new_orpha= n); =20 void add_property(struct node *node, struct property *prop); void delete_property_by_name(struct node *node, char *name); diff --git a/livetree.c b/livetree.c index ad9ae295..26c3c079 100644 --- a/livetree.c +++ b/livetree.c @@ -351,6 +351,36 @@ struct node *plugin_add_orphan_node(struct node *dt, s= truct node *new_node, return dt; } =20 +struct node *orphan_node(struct node *node, const char *ref) +{ + node->ref =3D xstrdup(ref); + + return node; +} + +void addon_add_orphan_node(struct node **dt_orphan, struct node *new_orpha= n) +{ + struct node **last_orphan; + char *name; + + /* + * For addon orphan node, the node name is set to '&reference' + * This ease the dts file generation and the usage of existing code + */ + xasprintf(&name, "&%s", new_orphan->ref); + + name_node(new_orphan, name); + free(name); + + new_orphan->next_sibling =3D NULL; + + last_orphan =3D dt_orphan; + while (*last_orphan) + last_orphan =3D &((*last_orphan)->next_sibling); + + *last_orphan =3D new_orphan; +} + struct node *chain_node(struct node *first, struct node *list) { assert(first->next_sibling =3D=3D NULL); diff --git a/treesource.c b/treesource.c index 705fe9a6..b50d9f81 100644 --- a/treesource.c +++ b/treesource.c @@ -12,11 +12,13 @@ extern YYLTYPE yylloc; =20 struct dt_info *parser_output; bool treesource_error; +struct node *parser_orphanlist; =20 struct dt_info *dt_from_source(const char *fname) { parser_output =3D NULL; treesource_error =3D false; + parser_orphanlist =3D NULL; =20 srcfile_push(fname); yyin =3D current_srcfile->f; @@ -432,6 +434,7 @@ void dt_to_source(FILE *f, struct dt_info *dti) { struct reserve_info *re; struct symbol *importsym; + struct node *orphan; =20 fprintf(f, "/dts-v1/;\n"); /* @@ -464,4 +467,9 @@ void dt_to_source(FILE *f, struct dt_info *dti) } =20 write_tree_source_node(f, dti->dt, 0); + + for_each_orphan(dti->orphanlist, orphan) { + fprintf(f, "\n"); + write_tree_source_node(f, orphan, 0); + } } --=20 2.55.0 From nobody Mon Sep 28 04:49:03 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9F162401494 for ; Wed, 26 Aug 2026 09:53:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738001; cv=none; b=vEiT3CATnpWC7BP7rFIbFnBEaPua/WXeCOXw+ndRqLXkOlOk6+CgtLNBRG9O05pQcnv+FXG0dy/fa4NdGcHXN8us3Al8Qg1u/FnJ/18bp2hxls8kps3B048tA0qRqDpUDc1XwKCwI/w8mi+TIfrVIHbaguA8zH95U+2dFh+XLlw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738001; c=relaxed/simple; bh=6LxYHe7p3QOVuiPMgefFUTWXsbSkAxNCdPuCY4acJXc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=i2SLG6gI0+Nfb02QeWonqlAiy1EBKpLbCQRQp98yvOA/Kx2crE4w1FcgNaauCFfKkpY2eDnGU7SNujAw+QNVFUIBrCJAprbdv82DFZsMeWsdNOHK0jpxA4ixaMsx2ScLlCES/fA9Jxol1XUFAEP/cZCXyWrEQUg9K5Y9DjRhFkk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=m6jL71lf; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="m6jL71lf" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 3E70E1A0E1B; Wed, 26 Aug 2026 09:53:18 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 12CE2604EC; Wed, 26 Aug 2026 09:53:18 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 8705711C7AD65; Wed, 26 Aug 2026 11:53:15 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737997; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=kPsatKdvDw0yzypuViRByxHI29/qFU4BeFECOdEb7kQ=; b=m6jL71lftZrcnMTSiUFzphnxf1nSrVYHOOmHnJlRrZC4KJxDJuqGIKmQwRciT9qsT45Bz0 42yJFkRjtbwwpnHwHvHsGByTqrpocihvyo5pF0Xb61L6gwYIWW3/9oGakRCxahMBcCCdhP 7fbmaTQSpK+bdQHtr3uk5/MZD7ebtains5u3eXHg5xru0EE2KaHPCBbhemBvi6X3HXkj8X R5JMql814Z1ghEDnKP/1S4XKVfFNJ6RY+zYS6CZx5/x1AKmZ9KT9Ea4Qb9hjUU2wBc1dQe HH9eTbE4zXHPrmvFPQxBJ0ZxM9ddBZuGBJmlzRM/5rw0N1TFhloK9f+RadVZTA== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 51/74] Add support for FDT_BEGIN_NODE_REF dtb tag Date: Wed, 26 Aug 2026 11:49:20 +0200 Message-ID: <20260826094950.1088288-52-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" The FDT_BEGIN_NODE_REF dtb tag is a tag defining a referenced node. This kind of nodes can be present in addon dtbs and identifies a node external to the addon dtb but modified by the addon. For instance, if an addon adds a sub-node to a node existing in the device-tree the addon is applied to, the existing node needs to be referenced by the addon dtb. This is the purpose of FDT_BEGIN_NODE_REF. This tag typically identifies what we call orphan nodes in dts. The structure of FDT_BEGIN_NODE_REF is identical to the structure of FDT_BEGIN_NODE except that the node name is not present and it is replaced by the node symbol reference needed to reference the node in the base device-tree when the addon device-tree blob is applied. The FDT_BEGIN_NODE_REF block is terminated by a FDT_END_NODE tag. The FDT_BEGIN_NODE_REF tag is followed by the length of the data part (structured tag), the node symbol name, a possible alignment padding and then the node structure. The FDT_BEGIN_NODE_REF block is terminated by a FDT_END_NODE tag: - data part length (32bit): strlen(node symbol name) + 1 - node symbol name (string including \0) The symbol name used to reference the node in the base device-tree when the addon is applied. - padding: Padding (0x00) added to have the next value aligned on 32bit. - Node structure (see FDT_BEGIN_NODE): Items provided by the addon to be merged in the referenced node when the addon is applied. - FDT_END_NODE tag Example: FDT_BEGIN_NODE_REF 5 'foo1' 0x00 0x00 0x00 ... FDT_END_NODE This means that the external node referenced by 'foo1' is modified by the addon. Items to merge when the addon is applied are represented by the '...' part. This is what is encoded in the dtb when the related dts has the following orphan node: &foo1 { ... }; If several external nodes are modified by the addon (several orphan nodes described in the addon), several FDT_BEGIN_NODE_REF are present. Each of them related to an external node. For instance, having 'foo1' and 'bar10' as external nodes leads to the following sequence: FDT_BEGIN_NODE_REF 5 'foo1' 0x00 0x00 0x00 ... FDT_END_NODE FDT_BEGIN_NODE_REF 6 'bar10' 0x00 0x00 ... FDT_END_NODE The FDT_BEGIN_NODE_REF can be present only for a top level node. Subnodes are identified by a FDT_BEGIN_NODE tag. If FDT_BEGIN_NODE_REF tags are present in the dtb, they are present after the root node definition (i.e. after the first FDT_BEGIN_NODE / FDT_END_NODE block). Add support for this new dtb tag. Signed-off-by: Herve Codina --- fdtdump.c | 12 +++++ flattree.c | 114 ++++++++++++++++++++++++++++++++------- libfdt/fdt.c | 95 +++++++++++++++++++++++++++++++- libfdt/fdt.h | 18 +++++++ libfdt/fdt_check.c | 47 +++++++++++++++- libfdt/fdt_ro.c | 46 +++++++++++++++- libfdt/libfdt_internal.h | 10 ++++ 7 files changed, 317 insertions(+), 25 deletions(-) diff --git a/fdtdump.c b/fdtdump.c index 7e4c244d..d68c07b9 100644 --- a/fdtdump.c +++ b/fdtdump.c @@ -206,6 +206,18 @@ static void dump_blob(void *blob, bool debug, int dump= _unknown) continue; } =20 + if (tag =3D=3D FDT_BEGIN_NODE_REF) { + last_prop_name =3D NULL; + + p =3D get_structured_tag_data(tag, p, &d, &sz); + s =3D d; + + printf("%*s&%s {\n", depth * shift, "", s); + + depth++; + continue; + } + if (tag =3D=3D FDT_EXPORT_SYM) { p =3D get_structured_tag_data(tag, p, &d, &sz); val32 =3D fdt32_to_cpu(GET_CELL(d)); diff --git a/flattree.c b/flattree.c index bd6974b8..b5223089 100644 --- a/flattree.c +++ b/flattree.c @@ -17,6 +17,7 @@ #define FTF_LCVERSW 0x100 #define FTF_PROPDATA_PHANDLE 0x200 #define FTF_EXPORT_IMPORT_SYM 0x400 +#define FTF_ORPHAN 0x800 =20 static struct version_info { int version; @@ -40,7 +41,7 @@ static struct version_info { FTF_LCVERSW}, {20, 18, 18, FDT_V20_SIZE, FTF_BOOTCPUID|FTF_STRTABSIZE|FTF_STRUCTSIZE|FTF_NOPS|FTF_DTFLAGS| - FTF_LCVERSW|FTF_PROPDATA_PHANDLE|FTF_EXPORT_IMPORT_SYM}, + FTF_LCVERSW|FTF_PROPDATA_PHANDLE|FTF_EXPORT_IMPORT_SYM|FTF_ORPHAN}, }; =20 struct emitter { @@ -56,6 +57,7 @@ struct emitter { void (*export_sym)(void *); void (*export_sym_ref)(void *); void (*import_sym)(void *); + void (*beginnode_ref)(void *, struct label *labels); }; =20 static void bin_emit_cell(void *e, cell_t val) @@ -130,6 +132,11 @@ static void bin_emit_import_sym(void *e) bin_emit_cell(e, FDT_IMPORT_SYM); } =20 +static void bin_emit_beginnode_ref(void *e, struct label *labels) +{ + bin_emit_cell(e, FDT_BEGIN_NODE_REF); +} + static struct emitter bin_emitter =3D { .cell =3D bin_emit_cell, .string =3D bin_emit_string, @@ -143,6 +150,7 @@ static struct emitter bin_emitter =3D { .export_sym =3D bin_emit_export_sym, .export_sym_ref =3D bin_emit_export_sym_ref, .import_sym =3D bin_emit_import_sym, + .beginnode_ref =3D bin_emit_beginnode_ref, }; =20 static void emit_label(FILE *f, const char *prefix, const char *label) @@ -297,6 +305,18 @@ static void asm_emit_import_sym(void *e) die("FDT_IMPORT_SYM not supported in asm output\n"); } =20 +static void asm_emit_beginnode_ref(void *e, struct label *labels) +{ + /* + * Orphan nodes (FDT_BEGIN_NODE_REF tags) are an feature + * introduced for addons. + * Addons device-tree blob have to reason to be in the asm format. + * + * Need to be implemented if really needed. + */ + die("FDT_BEGIN_NODE_REF not supported in asm output\n"); +} + static struct emitter asm_emitter =3D { .cell =3D asm_emit_cell, .string =3D asm_emit_string, @@ -310,6 +330,7 @@ static struct emitter asm_emitter =3D { .export_sym =3D asm_emit_export_sym, .export_sym_ref =3D asm_emit_export_sym_ref, .import_sym =3D asm_emit_import_sym, + .beginnode_ref =3D asm_emit_beginnode_ref, }; =20 static int stringtable_insert(struct data *d, const char *str) @@ -340,13 +361,18 @@ static void flatten_tree(struct node *tree, struct em= itter *emit, if (tree->deleted) return; =20 - emit->beginnode(etarget, tree->labels); - - if (vi->flags & FTF_FULLPATH) - emit->string(etarget, tree->fullpath, 0); - else - emit->string(etarget, tree->name, 0); + if ((vi->flags & FTF_ORPHAN) && tree->ref) { + emit->beginnode_ref(etarget, tree->labels); + emit->cell(etarget, strlen(tree->ref) + 1); + emit->string(etarget, tree->ref, 0); + } else { + emit->beginnode(etarget, tree->labels); =20 + if (vi->flags & FTF_FULLPATH) + emit->string(etarget, tree->fullpath, 0); + else + emit->string(etarget, tree->name, 0); + } emit->align(etarget, sizeof(cell_t)); =20 if (vi->flags & FTF_EXPORT_IMPORT_SYM) { @@ -510,6 +536,22 @@ static void flatten_imports(struct symbol *importsymli= st, struct emitter *emit, } } =20 +static void flatten_orphans(struct node *orphanlist, struct emitter *emit, + void *etarget, struct data *strbuf, + struct version_info *vi, uint32_t dt_flags) +{ + struct node *orphan; + + if (!(vi->flags & FTF_ORPHAN)) + return; + + if (!(dt_flags & FDT_FLAG_ADDON) && orphanlist) + die("Only addons can have orphan nodes\n"); + + for_each_orphan(orphanlist, orphan) + flatten_tree(orphan, emit, etarget, strbuf, vi); +} + void dt_to_blob(FILE *f, struct dt_info *dti, int version) { struct version_info *vi =3D NULL; @@ -533,6 +575,9 @@ void dt_to_blob(FILE *f, struct dt_info *dti, int versi= on) =20 flatten_tree(dti->dt, &bin_emitter, &dtbuf, &strbuf, vi); flatten_imports(dti->importsymlist, &bin_emitter, &dtbuf, vi, dt_flags); + flatten_orphans(dti->orphanlist, &bin_emitter, &dtbuf, &strbuf, vi, + dt_flags); + bin_emit_cell(&dtbuf, FDT_END); =20 reservebuf =3D flatten_reserve_list(dti->reservelist, vi); @@ -626,6 +671,9 @@ void dt_to_asm(FILE *f, struct dt_info *dti, int versio= n) =20 if (dti->importsymlist) die("Import symbols not supported in asm format\n"); + if (dti->orphanlist) + die("Orphan nodes not supported in asm format\n"); + =20 for (i =3D 0; i < ARRAY_SIZE(version_table); i++) { if (version_table[i].version =3D=3D version) @@ -850,6 +898,7 @@ static uint32_t flat_read_tag(struct inbuf *inb) case FDT_END: case FDT_PROPDATA_PHANDLE: case FDT_PROPDATA_PHANDLE_REF: + case FDT_BEGIN_NODE_REF: case FDT_EXPORT_SYM: case FDT_EXPORT_SYM_REF: case FDT_IMPORT_SYM: @@ -1013,7 +1062,8 @@ static const char *nodename_from_path(const char *ppa= th, const char *cpath) =20 static struct node *unflatten_tree(struct inbuf *dtbuf, struct inbuf *strbuf, - const char *parent_flatname, int flags) + const char *parent_flatname, int flags, + bool is_orphan_node) { struct property *prop =3D NULL; struct node *node; @@ -1026,14 +1076,22 @@ static struct node *unflatten_tree(struct inbuf *dt= buf, const char *str2; =20 node =3D build_node(NULL, NULL, NULL, NULL); - - flatname =3D flat_read_string(dtbuf); - - if (flags & FTF_FULLPATH) - node->name =3D xstrdup(nodename_from_path(parent_flatname, - flatname)); - else - node->name =3D xstrdup(flatname); + if (is_orphan_node) { + len =3D flat_read_word(dtbuf); + flat_read_subbuf(dtbuf, &subbuf, len); + flat_realign(dtbuf, sizeof(uint32_t)); + + str =3D flat_read_string_norealign(&subbuf); + orphan_node(node, str); + flatname =3D ""; + } else { + flatname =3D flat_read_string(dtbuf); + if (flags & FTF_FULLPATH) + node->name =3D xstrdup(nodename_from_path(parent_flatname, + flatname)); + else + node->name =3D xstrdup(flatname); + } =20 do { struct symbol *exportsym; @@ -1053,7 +1111,7 @@ static struct node *unflatten_tree(struct inbuf *dtbu= f, =20 case FDT_BEGIN_NODE: prop =3D NULL; - child =3D unflatten_tree(dtbuf,strbuf, flatname, flags); + child =3D unflatten_tree(dtbuf, strbuf, flatname, flags, false); add_child(node, child); break; =20 @@ -1151,6 +1209,11 @@ static struct node *unflatten_tree(struct inbuf *dtb= uf, add_symbol(&node->exportsymlist, exportsym); break; =20 + case FDT_BEGIN_NODE_REF: + /* FDT_BEGIN_NODE_REF can only be at the FDT top level. */ + die("Unexpected FDT_BEGIN_NODE_REF tag\n"); + break; + default: die("Invalid opcode word %08x in device tree blob\n", val); @@ -1178,6 +1241,8 @@ struct dt_info *dt_from_blob(const char *fname) struct node *tree; struct symbol *importsymlist =3D NULL; struct symbol *importsym; + struct node *orphanlist =3D NULL; + struct node *orphan; uint32_t val; int flags =3D 0; unsigned int dtsflags =3D DTSF_V1; @@ -1276,7 +1341,7 @@ struct dt_info *dt_from_blob(const char *fname) flags |=3D FTF_DTFLAGS | FTF_LCVERSW; =20 if (version >=3D 20) { - flags |=3D FTF_PROPDATA_PHANDLE | FTF_EXPORT_IMPORT_SYM; + flags |=3D FTF_PROPDATA_PHANDLE | FTF_EXPORT_IMPORT_SYM | FTF_ORPHAN; dtsflags |=3D fdt32_to_cpu(fdt->dt_flags) & FDT_FLAG_ADDON ? DTSF_ADDON : 0; } @@ -1291,7 +1356,7 @@ struct dt_info *dt_from_blob(const char *fname) if (val !=3D FDT_BEGIN_NODE) die("Device tree blob doesn't begin with FDT_BEGIN_NODE (begins with 0x%= 08x)\n", val); =20 - tree =3D unflatten_tree(&dtbuf, &strbuf, "", flags); + tree =3D unflatten_tree(&dtbuf, &strbuf, "", flags, false); =20 val =3D flat_read_tag(&dtbuf); =20 @@ -1303,6 +1368,15 @@ struct dt_info *dt_from_blob(const char *fname) val =3D flat_read_tag(&dtbuf); } } + + if (flags & FTF_ORPHAN) { + while (val =3D=3D FDT_BEGIN_NODE_REF) { + orphan =3D unflatten_tree(&dtbuf, &strbuf, "", flags, + true); + addon_add_orphan_node(&orphanlist, orphan); + val =3D flat_read_tag(&dtbuf); + } + } } =20 if (val !=3D FDT_END) @@ -1316,5 +1390,5 @@ struct dt_info *dt_from_blob(const char *fname) dtsflags |=3D DTSF_PLUGIN; =20 return build_dt_info(dtsflags, reservelist, tree, boot_cpuid_phys, - importsymlist, NULL); + importsymlist, orphanlist); } diff --git a/libfdt/fdt.c b/libfdt/fdt.c index b48c3248..f8dd0862 100644 --- a/libfdt/fdt.c +++ b/libfdt/fdt.c @@ -308,6 +308,27 @@ static uint32_t fdt_next_tag_all(const void *fdt, int = startoffset, int *nextoffs offset =3D sum; break; =20 + case FDT_BEGIN_NODE_REF: + tmp_offset =3D fdt_get_structured_tag_data(tag, fdt, offset, &len); + if (tmp_offset < 0) + return FDT_END; /* premature end */ + + sum =3D tmp_offset + len; + + /* Check ref */ + do { + p =3D fdt_offset_ptr(fdt, tmp_offset++, 1); + } while (p && (*p !=3D '\0')); + if (!can_assume(VALID_DTB) && !p) + return FDT_END; /* premature end */ + + if (!can_assume(VALID_INPUT) && (uint32_t)tmp_offset > sum) + return FDT_END; /* premature end */ + + /* Skip the whole data bloc */ + offset =3D sum; + break; + case FDT_EXPORT_SYM: tmp_offset =3D fdt_get_structured_tag_data(tag, fdt, offset, &len); if (tmp_offset < 0) @@ -424,6 +445,7 @@ static bool fdt_tag_is_unknown(uint32_t tag) case FDT_EXPORT_SYM: case FDT_EXPORT_SYM_REF: case FDT_IMPORT_SYM: + case FDT_BEGIN_NODE_REF: return false; default: break; @@ -484,6 +506,7 @@ bool fdt_tag_filter_skip_metadata(void *data, uint32_t = tag) case FDT_IMPORT_SYM: return true; =20 + case FDT_BEGIN_NODE_REF: /* Not metadata but rather node definition */ default: break; } @@ -506,11 +529,15 @@ bool fdt_tag_is_property_metadata(uint32_t tag) =20 int fdt_check_node_offset_(const void *fdt, int offset) { + uint32_t tag; + if (!can_assume(VALID_INPUT) && ((offset < 0) || (offset % FDT_TAGSIZE))) return -FDT_ERR_BADOFFSET; =20 - if (fdt_next_tag(fdt, offset, &offset) !=3D FDT_BEGIN_NODE) + + tag =3D fdt_next_tag(fdt, offset, &offset); + if (tag !=3D FDT_BEGIN_NODE && tag !=3D FDT_BEGIN_NODE_REF) return -FDT_ERR_BADOFFSET; =20 return offset; @@ -546,6 +573,10 @@ int fdt_root_offset(const void *fdt) case FDT_BEGIN_NODE: return offset; =20 + case FDT_BEGIN_NODE_REF: + /* An orphan node cannot be considered as a "first" node */ + return -FDT_ERR_NOTFOUND; + default: break; } @@ -587,6 +618,10 @@ int fdt_next_node(const void *fdt, int offset, int *de= pth) (*depth)++; break; =20 + case FDT_BEGIN_NODE_REF: + /* An orphan node cannot be found using fdt_next_node() */ + return -FDT_ERR_BADSTRUCTURE; + case FDT_END_NODE: if (depth && ((--(*depth)) < 0)) return nextoffset; @@ -632,6 +667,64 @@ int fdt_next_subnode(const void *fdt, int offset) return offset; } =20 +int fdt_check_orphan_offset(const void *fdt, int offset, int *data_offset) +{ + int nextoffset; + uint32_t tag; + int d; + + tag =3D fdt_next_tag(fdt, offset, &nextoffset); + switch (tag) { + case FDT_BEGIN_NODE_REF: + if (data_offset) { + d =3D fdt_get_structured_tag_data(tag, fdt, + offset + FDT_TAGSIZE, + NULL); + if (d < 0) + return d; + *data_offset =3D d; + } + break; + default: + return -FDT_ERR_BADOFFSET; + } + + return nextoffset; +} + +int fdt_next_orphan_offset(const void *fdt, int offset) +{ + int nextoffset =3D 0; + uint32_t tag; + + if (offset < 0) + return offset; + + if (offset !=3D 0) { + nextoffset =3D fdt_check_orphan_offset(fdt, offset, NULL); + if (nextoffset < 0) + return nextoffset; + } + + do { + offset =3D nextoffset; + tag =3D fdt_next_tag(fdt, offset, &nextoffset); + + switch (tag) { + case FDT_BEGIN_NODE_REF: + return offset; + + case FDT_END: + if (nextoffset < 0) + return nextoffset; + + return -FDT_ERR_NOTFOUND; + } + } while (tag !=3D FDT_BEGIN_NODE_REF); + + return offset; +} + const char *fdt_find_string_len_(const char *strtab, int tabsize, const ch= ar *s, int slen) { diff --git a/libfdt/fdt.h b/libfdt/fdt.h index 04f47784..52f5fd5f 100644 --- a/libfdt/fdt.h +++ b/libfdt/fdt.h @@ -154,6 +154,24 @@ struct fdt_property { */ #define FDT_IMPORT_SYM FDT_TAG_CAN_SKIP(FDT_TAG_DATA_VARLEN, 0x2100) =20 +/* + * Node reference tag. varlen: node symbol name + * + * It defines a node external to the dtb but modified by the dtb. It can be + * present in an addon dtb. + * + * For instance, if an addon adds a sub-node to a node existing in the + * device-tree the addon is applied to, the existing node needs to be + * referenced by the addon dtb. This is the purpose of FDT_BEGIN_NODE_REF. + * + * node symbol name: The symbol name used to reference the node in the base + * device-tree when the addon is applied. + * + * Following the tag and its related node symbol name, the node structure = is + * present. After the node structure, the FTD_END_NODE tag is present. + */ +#define FDT_BEGIN_NODE_REF FDT_TAG_NO_SKIP(FDT_TAG_DATA_VARLEN, 0x2200) + #define FDT_V1_SIZE (7*sizeof(fdt32_t)) #define FDT_V2_SIZE (FDT_V1_SIZE + sizeof(fdt32_t)) #define FDT_V3_SIZE (FDT_V2_SIZE + sizeof(fdt32_t)) diff --git a/libfdt/fdt_check.c b/libfdt/fdt_check.c index 7ce3fdd2..d2a959c0 100644 --- a/libfdt/fdt_check.c +++ b/libfdt/fdt_check.c @@ -23,6 +23,7 @@ int fdt_check_full(const void *fdt, size_t bufsize) bool root_node_found =3D false; bool subnode_found =3D false; bool import_sym_found =3D false; + bool orphan_found =3D false; const fdt32_t *pfdt32; const char *str; uint32_t val; @@ -80,6 +81,10 @@ int fdt_check_full(const void *fdt, size_t bufsize) if (import_sym_found) return -FDT_ERR_BADSTRUCTURE; =20 + /* Orphan nodes must be after the root node */ + if (orphan_found) + return -FDT_ERR_BADSTRUCTURE; + /* The root node must have an empty name */ name =3D fdt_get_name(fdt, offset, &len); if (!name) @@ -133,7 +138,10 @@ int fdt_check_full(const void *fdt, size_t bufsize) val =3D fdt32_ld(pfdt32); =20 /* Check the phandle value */ - tmp =3D fdt_node_offset_by_phandle(fdt, val); + if (!(fdt_dt_flags(fdt) & FDT_FLAG_ADDON)) + tmp =3D fdt_node_offset_by_phandle(fdt, val); + else + tmp =3D fdta_node_offset_by_phandle(fdt, val); if (tmp < 0) return tmp; break; @@ -192,7 +200,10 @@ int fdt_check_full(const void *fdt, size_t bufsize) val =3D fdt32_ld(pfdt32); =20 /* Check the phandle value */ - tmp =3D fdt_node_offset_by_phandle(fdt, val); + if (!(fdt_dt_flags(fdt) & FDT_FLAG_ADDON)) + tmp =3D fdt_node_offset_by_phandle(fdt, val); + else + tmp =3D fdta_node_offset_by_phandle(fdt, val); if (tmp < 0) return tmp; =20 @@ -249,6 +260,10 @@ int fdt_check_full(const void *fdt, size_t bufsize) if (!(fdt_dt_flags(fdt) & FDT_FLAG_ADDON)) return -FDT_ERR_BADVALUE; =20 + /* Orphans must be after import symbols */ + if (orphan_found) + return -FDT_ERR_BADSTRUCTURE; + import_sym_found =3D true; =20 d =3D fdt_get_structured_tag_data(tag, fdt, @@ -279,6 +294,34 @@ int fdt_check_full(const void *fdt, size_t bufsize) =20 break; =20 + case FDT_BEGIN_NODE_REF: + if (!(fdt_dt_flags(fdt) & FDT_FLAG_ADDON)) + return -FDT_ERR_BADVALUE; + + prop =3D NULL; + depth++; + + /* Orphan nodes can only be present as top level nodes */ + if (depth !=3D 1) + return -FDT_ERR_BADSTRUCTURE; + + orphan_found =3D true; + + d =3D fdt_get_structured_tag_data(tag, fdt, + offset + FDT_TAGSIZE, NULL); + if (d < 0) + return d; + + /* Retrieve the reference */ + str =3D fdt_offset_ptr(fdt, d, 1); + if (!str) + return -FDT_ERR_BADSTRUCTURE; + + /* Check that the reference is not an empty string */ + if (!strlen(str)) + return -FDT_ERR_BADVALUE; + break; + default: return -FDT_ERR_INTERNAL; } diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c index ea6a540d..917ecc33 100644 --- a/libfdt/fdt_ro.c +++ b/libfdt/fdt_ro.c @@ -317,6 +317,8 @@ const char *fdt_get_name(const void *fdt, int nodeoffse= t, int *len) { const struct fdt_node_header *nh; const char *nameptr; + int nextoffset; + uint32_t tag; int err; =20 if (!nodeoffset) { @@ -332,6 +334,18 @@ const char *fdt_get_name(const void *fdt, int nodeoffs= et, int *len) || ((err =3D fdt_check_node_offset_(fdt, nodeoffset)) < 0))) goto fail; =20 + /* + * fdt_check_node_offset_() considers FDT_BEGIN_NODE_REF as a node. + * A FDT_BEGIN_NODE_REF tag, which represents an orphan node, doesn't + * have any 'name' attached but only a reference to the external node + * the orphan node refers to. No way to get a name. + */ + tag =3D fdt_next_tag(fdt, nodeoffset, &nextoffset); + if (tag =3D=3D FDT_BEGIN_NODE_REF) { + err =3D FDT_ERR_BADOFFSET; + goto fail; + } + nh =3D fdt_offset_ptr_(fdt, nodeoffset); nameptr =3D nh->name; =20 @@ -760,7 +774,7 @@ int fdt_node_offset_by_prop_value(const void *fdt, int = startoffset, return offset; /* error from fdt_next_node() */ } =20 -int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle) +static int fdt_node_offset_by_phandle_(const void *fdt, int start_node_off= set, uint32_t phandle) { int offset; =20 @@ -775,7 +789,7 @@ int fdt_node_offset_by_phandle(const void *fdt, uint32_= t phandle) * we want, we scan over them again making our way to the next * node. Still it's the easiest to implement approach; * performance can come later. */ - for (offset =3D fdt_next_node(fdt, -1, NULL); + for (offset =3D fdt_next_node(fdt, start_node_offset, NULL); offset >=3D 0; offset =3D fdt_next_node(fdt, offset, NULL)) { if (fdt_get_phandle(fdt, offset) =3D=3D phandle) @@ -785,6 +799,34 @@ int fdt_node_offset_by_phandle(const void *fdt, uint32= _t phandle) return offset; /* error from fdt_next_node() */ } =20 +int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle) +{ + return fdt_node_offset_by_phandle_(fdt, -1, phandle); +} + +int fdta_node_offset_by_phandle(const void *fdta, uint32_t phandle) +{ + int orphan; + int node; + + /* Look at root node tree */ + node =3D fdt_node_offset_by_phandle_(fdta, -1, phandle); + if (node >=3D 0) + return node; + + /* Look at orphans and their trees */ + fdt_for_each_orphan(orphan, fdta) { + if (fdt_get_phandle(fdta, orphan) =3D=3D phandle) + return orphan; + + node =3D fdt_node_offset_by_phandle_(fdta, orphan, phandle); + if (node >=3D 0) + return node; + } + + return -FDT_ERR_NOTFOUND; +} + int fdt_stringlist_contains(const char *strlist, int listlen, const char *= str) { int len =3D strlen(str); diff --git a/libfdt/libfdt_internal.h b/libfdt/libfdt_internal.h index 7ef1d995..be47639d 100644 --- a/libfdt/libfdt_internal.h +++ b/libfdt/libfdt_internal.h @@ -61,6 +61,16 @@ static inline const char *fdt_find_string_(const char *s= trtab, int tabsize, =20 int fdt_node_end_offset_(void *fdt, int nodeoffset); =20 +int fdt_check_orphan_offset(const void *fdt, int offset, int *data_offset); +int fdt_next_orphan_offset(const void *fdt, int offset); + +#define fdt_for_each_orphan(orphan, fdt) \ + for (orphan =3D fdt_next_orphan_offset(fdt, 0); \ + orphan >=3D 0; \ + orphan =3D fdt_next_orphan_offset(fdt, orphan)) + +int fdta_node_offset_by_phandle(const void *fdta, uint32_t phandle); + static inline const void *fdt_offset_ptr_(const void *fdt, int offset) { return (const char *)fdt + fdt_off_dt_struct(fdt) + offset; --=20 2.55.0 From nobody Mon Sep 28 04:49:03 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D9668402B8C for ; Wed, 26 Aug 2026 09:53:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738003; cv=none; b=MD7IsLga9N+5tLeA7F9nluIlY5PQatL7ls1qzVn2NZ7k/9+rRsMygxeu82CxeXCjA5XUJp8m0K9Rp00n0izRHG/mY5v9akNqNdVCS9z9PAcdSTLkdgDohk61tne19eclhq+z6oFRVc+1bmk06H88m+pHARpMfBMx3g4rT9a/F/Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738003; c=relaxed/simple; bh=1qxpugmBn/4endoHwz9EILu7vYVoe9JP5zyZyyPAgY0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=AR3mqLbXV7SMHuWAtw6snKfDSRaBxvl28Y5jrvjFMXobkZ0MMu1uA+SDSyBpEccVEVJ19ol7kwiCnDLD9eOyZr7b5izjFntQ1+UGbtjwW2FPlyxSBa+V9cJYz89Ql/ek6rVGglufzcF19iufoMA0WqbjR2DWzynM4O2N7vqpJfs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=QTk4yox1; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="QTk4yox1" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 96EBE1A183A; Wed, 26 Aug 2026 09:53:20 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 69B40604EC; Wed, 26 Aug 2026 09:53:20 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id D17E711C7AD35; Wed, 26 Aug 2026 11:53:17 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787737999; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=7lhAwsiGlrSZc63/UADNNN1tDiNHpRD6jgmTzIo6Opc=; b=QTk4yox16k3M289U4NcAHLOIS07ke4WBc598pxbDh0mEQELS7qysyJLdaALTGBKkDu+QtC 5ZS/jFfN+GXw+yaWFDIDm1+TKl7aSXY2M3uOm8BfYBRT2TfzJwGf4uAuaH7TjHcME+OdT9 72iip/LQ5pRcpyvA9VvBWd+8fR0YACaDYZYFjWQPVa2xRof+AdrxF0tN8DCXWX0XoJLsMr kXc0ajYjtznAyRb5ZG3DS8bc4jYFKM1bxW82r2s3turFE7UN7R6mjwPKASqVwLZf64w4s2 OfdMvnpAvouSrnp3yngSZxPd715GwaA3WwvEA8/+cKxZX7rY8orHhe0UcrdwYg== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 52/74] tests: metadata: Add basic test for addon orphan nodes Date: Wed, 26 Aug 2026 11:49:21 +0200 Message-ID: <20260826094950.1088288-53-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" Add tests related to addon orphan nodes (FDT_BEGIN_NODE_REF dtb tag). Signed-off-by: Herve Codina --- tests/metadata_addon_orphan1.dtb.dts.expect | 16 ++++++++++++++++ tests/metadata_addon_orphan1.dtb.expect | 13 +++++++++++++ tests/metadata_addon_orphan1.dts | 19 +++++++++++++++++++ tests/metadata_addon_orphan1.dts.dts.expect | 16 ++++++++++++++++ tests/run_tests.sh | 3 ++- 5 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 tests/metadata_addon_orphan1.dtb.dts.expect create mode 100644 tests/metadata_addon_orphan1.dtb.expect create mode 100644 tests/metadata_addon_orphan1.dts create mode 100644 tests/metadata_addon_orphan1.dts.dts.expect diff --git a/tests/metadata_addon_orphan1.dtb.dts.expect b/tests/metadata_a= ddon_orphan1.dtb.dts.expect new file mode 100644 index 00000000..c24a00f1 --- /dev/null +++ b/tests/metadata_addon_orphan1.dtb.dts.expect @@ -0,0 +1,16 @@ +/dts-v1/; +/addon/; + +/ { + + node-a { + prop =3D <0x01>; + }; +}; + +&base { + + addon-node { + prop =3D <0x02>; + }; +}; diff --git a/tests/metadata_addon_orphan1.dtb.expect b/tests/metadata_addon= _orphan1.dtb.expect new file mode 100644 index 00000000..7058a2e0 --- /dev/null +++ b/tests/metadata_addon_orphan1.dtb.expect @@ -0,0 +1,13 @@ +/dts-v1/; +/addon/; + +/ { + node-a { + prop =3D <0x00000001>; + }; +}; +&base { + addon-node { + prop =3D <0x00000002>; + }; +}; diff --git a/tests/metadata_addon_orphan1.dts b/tests/metadata_addon_orphan= 1.dts new file mode 100644 index 00000000..f20d1791 --- /dev/null +++ b/tests/metadata_addon_orphan1.dts @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) +/* + * Copyright (C) 2026 Bootlin + */ + +/dts-v1/; +/addon/; + +/ { + node-a { + prop =3D <1>; + }; +}; + +&base { + addon-node { + prop =3D <2>; + }; +}; diff --git a/tests/metadata_addon_orphan1.dts.dts.expect b/tests/metadata_a= ddon_orphan1.dts.dts.expect new file mode 100644 index 00000000..c24a00f1 --- /dev/null +++ b/tests/metadata_addon_orphan1.dts.dts.expect @@ -0,0 +1,16 @@ +/dts-v1/; +/addon/; + +/ { + + node-a { + prop =3D <0x01>; + }; +}; + +&base { + + addon-node { + prop =3D <0x02>; + }; +}; diff --git a/tests/run_tests.sh b/tests/run_tests.sh index 7c45835e..0ce60c3f 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -1250,7 +1250,8 @@ fdtoverlay_tests() { metadata_tests() { for dt in metadata_propdata_phandle_local metadata_propdata_phandle_ref \ metadata_addon_base metadata_exportsyms_local \ - metadata_exportsyms_ref metadata_importsyms; do + metadata_exportsyms_ref metadata_importsyms \ + metadata_addon_orphan1; do run_dtc_test -I dts -O dts -o $dt.dts.dts "$SRCDIR/$dt.dts" base_run_test check_diff $dt.dts.dts "$SRCDIR/$dt.dts.dts.expect" run_dtc_test -I dts -O dtb -o $dt.dtb "$SRCDIR/$dt.dts" --=20 2.55.0 From nobody Mon Sep 28 04:49:03 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A9DDB403EA1 for ; Wed, 26 Aug 2026 09:53:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738006; cv=none; b=LdII/zM1lh/3SeeeUDiEwXpQP8TcPqdp9x0NMCm6YAsU62jm1Ka5ZuW+4tkL/YSvjNEz4jG8NZ8Bmde+lMR5jR9gLKlq4sp5/cso/h7zRhgNaJ+vDQ1aQFGnNWWTh21JTfv+ukpn0EDVQs79b18ST3VGCwCAsDYCcKcLFY5HgAs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738006; c=relaxed/simple; bh=Wp67rf63aoEeZmJOqdSlQ7BjcyBA17gPgw01eC2b+ao=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=AXuufRFnNfbrM9PrKf5KkLaIslSoyzJ0WkBm2AYN9X+pWveMZoPHqpspAKeysk1w8Rs3uId6qVZanjSHYO0/1Q0TGiXQe6Eis+v2798R+p0/mr1yFEYW6Ik996Qj0ywGJKRIrWVQ70B+ts8iISi6OhrD0snh+VNy3pN6f++NTrQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=H1XCEtCN; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="H1XCEtCN" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 293A11A0E1B; Wed, 26 Aug 2026 09:53:23 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id EAA4C604EC; Wed, 26 Aug 2026 09:53:22 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 34A5211C7AD37; Wed, 26 Aug 2026 11:53:19 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787738001; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=EsMsQfWGevD4uhbzz1lPR3JMyl7+baU+j5rVrn18Sz0=; b=H1XCEtCNznyJ9QOvMbHu2+95V/VBooSi9+5iB3O7hCMuf0MCqmjr9bMQakst08JAlIdFdP dRnGWlzaE93OC+Nf+TOulR1lIFZ2lDuhmyZJO1XbgqGKHKp3I6b3CW8nD+DVpkdLnXCM/F w58yQHZL16HFSBvFRC5w3nQGMKBvT96ydhuWU2j7bNswP3klQ907tGAyM7/LBiG55CEpyD uWtU/yFE1+bKplnLOLE5brd74WIvD4u1k5rdME9OuRezitRGUnw+VaI252xDD5k4pVhfRj XTYBp5XqtidlCKSybIVxmoYzckkg2NBWPMgDN33tsijXL7r6oovng8C21G+cjA== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 53/74] dtc: Add support for missing root node in addon device-tree Date: Wed, 26 Aug 2026 11:49:22 +0200 Message-ID: <20260826094950.1088288-54-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" Addon can have orphan nodes fully described (dts) and encoded (dtb) without the need for a root device tree. Contrary to plugin (overlay), addon doesn't need any specific root tree structure to described the orphans. Indeed, /fragment@n/__overlay__ doesn't exist for addons. Orphans are encoded in dtb using the FDT_BEGIN_NODE_REF tag without any impact on the root tree. The following snippet is fully legit for addon: --- 8< --- /addon/; &foo { subnode { prop =3D <1>; }; } --- 8< --- This snippet doesn't contains a root device tree, and the related dtb doesn't need any root device tree to encode the snippet. The root device is no more mandatory for addon. Add support for addon without a root device-tree. Signed-off-by: Herve Codina --- checks.c | 29 +++++++++++++++++++++++++++-- dtc-parser.y | 18 ++++++++++++++---- dtc.c | 21 ++++++++++++++++----- flattree.c | 43 ++++++++++++++++++++++++++++++------------- livetree.c | 13 +++++++++++-- treesource.c | 3 ++- 6 files changed, 100 insertions(+), 27 deletions(-) diff --git a/checks.c b/checks.c index a0024389..fee37ce0 100644 --- a/checks.c +++ b/checks.c @@ -154,7 +154,6 @@ static bool is_multiple_of(int multiple, int divisor) =20 static bool run_check(struct check *c, struct dt_info *dti) { - struct node *dt =3D dti->dt; struct node *orphan; bool error =3D false; int i; @@ -179,7 +178,8 @@ static bool run_check(struct check *c, struct dt_info *= dti) if (c->status !=3D UNCHECKED) goto out; =20 - check_nodes_props(c, dti, dt); + if (dti->dt) + check_nodes_props(c, dti, dti->dt); =20 for_each_orphan(dti->orphanlist, orphan) check_nodes_props(c, dti, orphan); @@ -2105,6 +2105,31 @@ void process_checks(bool force, struct dt_info *dti) exit(2); } =20 + if (!dti->dt) { + /* No root node is only allowed for addons */ + if (dti->dtsflags & DTSF_ADDON) { + if (!dti->orphanlist) { + /* + * but addons without a root node and without + * orphan nodes is really incorrect + */ + fprintf(stderr, + "ERROR: Input tree has no root or orphan nodes, aborting\n"); + exit(2); + } + } else { + fprintf(stderr, "ERROR: Input tree has no root node, aborting\n"); + exit(2); + } + } + + if (!(dti->dtsflags & DTSF_ADDON)) { + if (dti->orphanlist) { + fprintf(stderr, "ERROR: Input tree has orphan nodes, aborting\n"); + exit(2); + } + } + for (i =3D 0; i < ARRAY_SIZE(check_table); i++) { struct check *c =3D check_table[i]; =20 diff --git a/dtc-parser.y b/dtc-parser.y index 197a9533..8d43cc4e 100644 --- a/dtc-parser.y +++ b/dtc-parser.y @@ -133,12 +133,18 @@ static struct node *parser_get_node_by_ref(struct nod= e *dt, struct node *orphanl sourcefile: headers memreserves devicetree { + if (!($1 & DTSF_ADDON) && !$3) + ERROR(&@3, "Only addon support missing root node"); + parser_output =3D build_dt_info($1, $2, $3, - guess_boot_cpuid($3), + $3 ? guess_boot_cpuid($3) : 0, NULL, parser_orphanlist); } | headers memreserves importlist devicetree { + if (!($1 & DTSF_ADDON) && !$4) + ERROR(&@4, "Only addon support missing root node"); + /* * importlist is created with chain_symbol() and so it * is created in reverse order. Reverse it now to have @@ -241,7 +247,10 @@ devicetree: } | devicetree '/' nodedef { - $$ =3D merge_nodes($1, $3); + if ($1) + $$ =3D merge_nodes($1, $3); + else + $$ =3D name_node($3, ""); } | dt_ref nodedef { @@ -256,8 +265,9 @@ devicetree: ""), $2, $1); } else { - ERROR(&@2, "Orphan node %s without a root node not yet supported", $1); - YYERROR; + addon_add_orphan_node(&parser_orphanlist, + orphan_node($2, $1)); + $$ =3D NULL; } } | devicetree DT_LABEL dt_ref nodedef diff --git a/dtc.c b/dtc.c index e5068375..d0f8998e 100644 --- a/dtc.c +++ b/dtc.c @@ -316,18 +316,29 @@ int main(int argc, char *argv[]) =20 process_checks(force, dti); =20 - if (auto_label_aliases) + if (auto_label_aliases) { + if (!dti->dt) + die("auto-alias not supported without a root node\n"); generate_label_tree(dti, "aliases", false); + } =20 - generate_labels_from_tree(dti, "__symbols__"); + if (dti->dt) + generate_labels_from_tree(dti, "__symbols__"); =20 - if (generate_symbols) + if (generate_symbols) { + if (!dti->dt) + die("generation of symbols not supported without a root node\n"); generate_label_tree(dti, "__symbols__", true); + } =20 - fixup_phandles(dti, "__fixups__"); - local_fixup_phandles(dti, "__local_fixups__"); + if (dti->dt) { + fixup_phandles(dti, "__fixups__"); + local_fixup_phandles(dti, "__local_fixups__"); + } =20 if (generate_fixups) { + if (!dti->dt) + die("generation of fixups not supported without a root node\n"); generate_fixups_tree(dti, "__fixups__"); generate_local_fixups_tree(dti, "__local_fixups__"); } diff --git a/flattree.c b/flattree.c index b5223089..f680dec1 100644 --- a/flattree.c +++ b/flattree.c @@ -573,7 +573,9 @@ void dt_to_blob(FILE *f, struct dt_info *dti, int versi= on) =20 dt_flags |=3D dti->dtsflags & DTSF_ADDON ? FDT_FLAG_ADDON : 0; =20 - flatten_tree(dti->dt, &bin_emitter, &dtbuf, &strbuf, vi); + if (dti->dt) + flatten_tree(dti->dt, &bin_emitter, &dtbuf, &strbuf, vi); + flatten_imports(dti->importsymlist, &bin_emitter, &dtbuf, vi, dt_flags); flatten_orphans(dti->orphanlist, &bin_emitter, &dtbuf, &strbuf, vi, dt_flags); @@ -769,7 +771,9 @@ void dt_to_asm(FILE *f, struct dt_info *dti, int versio= n) fprintf(f, "\t.long\t0, 0\n\t.long\t0, 0\n"); =20 emit_label(f, symprefix, "struct_start"); - flatten_tree(dti->dt, &asm_emitter, f, &strbuf, vi); + + if (dti->dt) + flatten_tree(dti->dt, &asm_emitter, f, &strbuf, vi); =20 fprintf(f, "\t/* FDT_END */\n"); asm_emit_cell(f, FDT_END); @@ -1238,7 +1242,7 @@ struct dt_info *dt_from_blob(const char *fname) struct inbuf memresvbuf; int sizeleft; struct reserve_info *reservelist; - struct node *tree; + struct node *tree =3D NULL; struct symbol *importsymlist =3D NULL; struct symbol *importsym; struct node *orphanlist =3D NULL; @@ -1352,15 +1356,24 @@ struct dt_info *dt_from_blob(const char *fname) =20 reservelist =3D flat_read_mem_reserve(&memresvbuf); =20 - val =3D flat_read_tag(&dtbuf); - if (val !=3D FDT_BEGIN_NODE) - die("Device tree blob doesn't begin with FDT_BEGIN_NODE (begins with 0x%= 08x)\n", val); + if (!(dtsflags & DTSF_ADDON)) { + val =3D flat_read_tag(&dtbuf); + if (val !=3D FDT_BEGIN_NODE) + die("Device tree blob doesn't begin with FDT_BEGIN_NODE (begins with 0x= %08x)\n", + val); =20 - tree =3D unflatten_tree(&dtbuf, &strbuf, "", flags, false); + tree =3D unflatten_tree(&dtbuf, &strbuf, "", flags, false); =20 - val =3D flat_read_tag(&dtbuf); + val =3D flat_read_tag(&dtbuf); + if (val !=3D FDT_END) + die("Device tree blob doesn't end with FDT_END\n"); + } else { + val =3D flat_read_tag(&dtbuf); + if (val =3D=3D FDT_BEGIN_NODE) { + tree =3D unflatten_tree(&dtbuf, &strbuf, "", flags, false); + val =3D flat_read_tag(&dtbuf); + } =20 - if (dtsflags & DTSF_ADDON) { if (flags & FTF_EXPORT_IMPORT_SYM) { while (val =3D=3D FDT_IMPORT_SYM) { importsym =3D flat_read_importsym(&dtbuf); @@ -1377,16 +1390,20 @@ struct dt_info *dt_from_blob(const char *fname) val =3D flat_read_tag(&dtbuf); } } - } =20 - if (val !=3D FDT_END) - die("Device tree blob doesn't end with FDT_END\n"); + if (!tree && !orphanlist) + die("Device tree blob has 0x%08x tag instead of FDT_BEGIN_NODE or FDT_B= EGIN_NODE_REF\n", + val); + + if (val !=3D FDT_END) + die("Device tree blob doesn't end with FDT_END\n"); + } =20 free(blob); =20 fclose(f); =20 - if (get_subnode(tree, "__fixups__") || get_subnode(tree, "__local_fixups_= _")) + if (tree && (get_subnode(tree, "__fixups__") || get_subnode(tree, "__loca= l_fixups__"))) dtsflags |=3D DTSF_PLUGIN; =20 return build_dt_info(dtsflags, reservelist, tree, boot_cpuid_phys, diff --git a/livetree.c b/livetree.c index 26c3c079..f7c13585 100644 --- a/livetree.c +++ b/livetree.c @@ -692,7 +692,8 @@ static void complete_references(struct dt_info *dti) { struct node *orphan; =20 - complete_references_internal(dti, dti->dt); + if (dti->dt) + complete_references_internal(dti, dti->dt); =20 for_each_orphan(dti->orphanlist, orphan) complete_references_internal(dti, orphan); @@ -1336,7 +1337,9 @@ void sort_tree(struct dt_info *dti) { sort_reserve_entries(dti); sort_importsyms(dti); - sort_node(dti->dt); + + if (dti->dt) + sort_node(dti->dt); } =20 /* utility helper to avoid code duplication */ @@ -1605,6 +1608,8 @@ void generate_labels_from_tree(struct dt_info *dti, c= onst char *name) =20 void generate_label_tree(struct dt_info *dti, const char *name, bool alloc= ph) { + assert(dti->dt); + if (!any_label_tree(dti, dti->dt)) return; generate_label_tree_internal(dti, build_root_node(dti->dt, name), @@ -1613,6 +1618,8 @@ void generate_label_tree(struct dt_info *dti, const c= har *name, bool allocph) =20 void generate_fixups_tree(struct dt_info *dti, const char *name) { + assert(dti->dt); + if (!any_fixup_tree(dti, dti->dt)) return; if (generate_fixups_tree_internal(dti, build_root_node(dti->dt, name), dt= i->dt)) @@ -1719,6 +1726,8 @@ void fixup_phandles(struct dt_info *dti, const char *= name) =20 void generate_local_fixups_tree(struct dt_info *dti, const char *name) { + assert(dti->dt); + if (!any_local_fixup_tree(dti, dti->dt)) return; if (generate_local_fixups_tree_internal(dti, build_root_node(dti->dt, nam= e), dti->dt)) diff --git a/treesource.c b/treesource.c index b50d9f81..d18025c5 100644 --- a/treesource.c +++ b/treesource.c @@ -466,7 +466,8 @@ void dt_to_source(FILE *f, struct dt_info *dti) fprintf(f, "\n"); } =20 - write_tree_source_node(f, dti->dt, 0); + if (dti->dt) + write_tree_source_node(f, dti->dt, 0); =20 for_each_orphan(dti->orphanlist, orphan) { fprintf(f, "\n"); --=20 2.55.0 From nobody Mon Sep 28 04:49:03 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 05CEC3BCD05; Wed, 26 Aug 2026 09:53:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738008; cv=none; b=psFNSh1F+mXIrPNBXY74yzp8qnzGByCXl3ezyZ6iCsQOdoU9tG+oMbVloc0XePHiPjxFGzR6JS/Q8aKNiGkm+DhRSwv4K7HtjLA8GogqEoY5wa2G9Mr29sA6T3v1wRx4ulmW4hhURG7k1bRBilvhNQ0gCwXPHCMo1QgDur241sQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738008; c=relaxed/simple; bh=vRe5xJ2l7bgudHv+BdCPB4/Y2ACKzfLof/3o2r8LdTQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=J3BVOsLJHLmzxncTAymA4AfYI3fhY0XzRxzBGUPsQL619UP7J0+tZZUseDFeIxGurDjJUz1s7myx7B6tcEt8l+K/21xGW6hmdKIiMzY7MZrGcrLGKipKsd5RV3hDTbtS7Bc8vs2OTAwOcJUNAnNCRibNe/KtrfZxvmCtm06Urc8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=s6ppfEfy; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="s6ppfEfy" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 9D4304E413C1; Wed, 26 Aug 2026 09:53:25 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 6AC3D604EC; Wed, 26 Aug 2026 09:53:25 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 78E5F11C7ACD5; Wed, 26 Aug 2026 11:53:22 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787738004; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=sWS7zG+BLM4bEXwEI94Po9jYsGy+vM3v6+qapohqfDQ=; b=s6ppfEfyBwmiYh9cfQnkk7Pk/OqjPoQV+FTLY4wJVp4KAJ88EGOcV5mcGqtZbp7peM5vUz PAq077/a/Hr0o3f0HyQlXogaXW2HwXvZfUemMyduAdJH9bMN2qtxsET6BpkYUUThjBW2iz jPaBcHfx7A8p4V37jUrL/4/YU2vuzs0OV/Ok8C+m+znvbVOA33uhQ3RzdWxj2l11kKBUcl TG+eaSz+sf768K5vtAet6C3BfvmXcz+2g/F/pEoXidfw7TXu+yS3lEzvf+9Wv8ou6u28ch V8718W41Ch8XLjSwA/4VBN6/5hnu8VfqlDz2e7x+WW0W2IDtHeL3Fnn2OqUK/g== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 54/74] tests: metadata: Add a test for addon without root node Date: Wed, 26 Aug 2026 11:49:23 +0200 Message-ID: <20260826094950.1088288-55-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" The root device-tree node is no more mandatory for addons. Indeed, addons can be composed of only orphan nodes without any needs for the root device-tree node presence. Add a test related to addon dts and dtb without root node. Signed-off-by: Herve Codina --- tests/metadata_addon_orphan2.dtb.dts.expect | 10 ++++++++++ tests/metadata_addon_orphan2.dtb.expect | 8 ++++++++ tests/metadata_addon_orphan2.dts | 13 +++++++++++++ tests/metadata_addon_orphan2.dts.dts.expect | 10 ++++++++++ tests/run_tests.sh | 2 +- 5 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 tests/metadata_addon_orphan2.dtb.dts.expect create mode 100644 tests/metadata_addon_orphan2.dtb.expect create mode 100644 tests/metadata_addon_orphan2.dts create mode 100644 tests/metadata_addon_orphan2.dts.dts.expect diff --git a/tests/metadata_addon_orphan2.dtb.dts.expect b/tests/metadata_a= ddon_orphan2.dtb.dts.expect new file mode 100644 index 00000000..32c1b1ed --- /dev/null +++ b/tests/metadata_addon_orphan2.dtb.dts.expect @@ -0,0 +1,10 @@ +/dts-v1/; +/addon/; + + +&base { + + addon-node { + prop =3D <0x02>; + }; +}; diff --git a/tests/metadata_addon_orphan2.dtb.expect b/tests/metadata_addon= _orphan2.dtb.expect new file mode 100644 index 00000000..46e67d06 --- /dev/null +++ b/tests/metadata_addon_orphan2.dtb.expect @@ -0,0 +1,8 @@ +/dts-v1/; +/addon/; + +&base { + addon-node { + prop =3D <0x00000002>; + }; +}; diff --git a/tests/metadata_addon_orphan2.dts b/tests/metadata_addon_orphan= 2.dts new file mode 100644 index 00000000..d4ff42f7 --- /dev/null +++ b/tests/metadata_addon_orphan2.dts @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) +/* + * Copyright (C) 2026 Bootlin + */ + +/dts-v1/; +/addon/; + +&base { + addon-node { + prop =3D <2>; + }; +}; diff --git a/tests/metadata_addon_orphan2.dts.dts.expect b/tests/metadata_a= ddon_orphan2.dts.dts.expect new file mode 100644 index 00000000..32c1b1ed --- /dev/null +++ b/tests/metadata_addon_orphan2.dts.dts.expect @@ -0,0 +1,10 @@ +/dts-v1/; +/addon/; + + +&base { + + addon-node { + prop =3D <0x02>; + }; +}; diff --git a/tests/run_tests.sh b/tests/run_tests.sh index 0ce60c3f..e099bd39 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -1251,7 +1251,7 @@ metadata_tests() { for dt in metadata_propdata_phandle_local metadata_propdata_phandle_ref \ metadata_addon_base metadata_exportsyms_local \ metadata_exportsyms_ref metadata_importsyms \ - metadata_addon_orphan1; do + metadata_addon_orphan1 metadata_addon_orphan2; do run_dtc_test -I dts -O dts -o $dt.dts.dts "$SRCDIR/$dt.dts" base_run_test check_diff $dt.dts.dts "$SRCDIR/$dt.dts.dts.expect" run_dtc_test -I dts -O dtb -o $dt.dtb "$SRCDIR/$dt.dts" --=20 2.55.0 From nobody Mon Sep 28 04:49:03 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C8DD44071E5; Wed, 26 Aug 2026 09:53:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738011; cv=none; b=Prtz+JwILb3lBlIufCinrcut0j5HBdRVHe7nnaC0AgqeYCKIdzFXQdzGdZDXaYWCZqVV5y/gj69znb66uoQmIz/JK7BbDUZ1Spi0GdDlu8eTX+1q3i0TMkpftVHMMPVHFrnqcfLCAE0AyKtx//whgpJAXTrPn5olBJqJjcnnkTA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738011; c=relaxed/simple; bh=IaUg5BeyJfPvX6fljByZEXZb8D6ZyRUhQPDAJPhYxLc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=RE9WlxgoPDVjGxanfDLPL1QRFia8xLw5i7mb9+8qD6UqbbXzq7VJCdFmtJMfo98Eh/Il+pjBxWSwoPo7ExhcJbAkt+ZoXy0MueRhQY1uyBklG5VpSGkQBI5SoYfK2YTsHnHyuMnNKnJzRm+tdPnK72faxPgASvFcUNX5kizVq9g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=v3RReRnV; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="v3RReRnV" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 82E5F4E413BC; Wed, 26 Aug 2026 09:53:28 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 572F7604EC; Wed, 26 Aug 2026 09:53:28 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 267D911C7AD65; Wed, 26 Aug 2026 11:53:24 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787738007; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=kM0QWQRS6/0weW+j97TLc6mGgKU5/5L+AcqkH6EFFeE=; b=v3RReRnV2yLKVmkOmNGVUxcwS813M7j0xo1DkrZs0OqDj+aNgSP0+IKNB6F9rfYHgoH4WD j+W+Ny6iwK1yNw52GgSoRd9Jlq0RfrfgwwSTY8TDP3EzwxOrqXIjv6U1wJp+imyoaO70sZ IyNzYQOKjaWdMZ4HOCtZ/lEdBwEobsggHeGvYzcn0TZJLnPee6A6JbR/+hd7GPGt99DMH4 YCe3B+rg8Zf96ufncS/XOUh6cmH7wlfA1isCA7KJB+xJCfyIQ3oarCBLiZqa98+qPRx07E dUVQjG4843Qp/4TaSqBvjkY4i8Pinb8CMtib/HyERrUqxi8pCTzK6gj6o7EXnA== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 55/74] dtc: Allow parser_get_node_by_ref() to return an orphan node for merging purpose Date: Wed, 26 Aug 2026 11:49:24 +0200 Message-ID: <20260826094950.1088288-56-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" When the same orphan node is described multiple times in an addon dts, those multiple descriptions should be merged. For instance, in the following snippet: --- 8< --- /addon/; &foo { prop1 =3D <1>; }; &foo { prop2 =3D <2>; }; --- 8< --- The foo orphan node is described twice and should be merged in only one instance: --- 8< --- &foo { prop1 =3D <1>; prop2 =3D <2>; }; --- 8< --- The current mecanisme used to find a node for merging is based on label. Indeed, without orphan nodes, '&foo' is a reference to a node with the label 'foo'. This node labeled foo is the node found for merging. With addons and orphan nodes, '&foo' is not a reference to an existing node. Indeed, this node is an orphan one because the node referenced by foo is an external node (i.e. not available in the addon itself). The label 'foo' doesn't exist. No node in the addon are defined with a foo label attached. Take this orphan nodes specificity into account in order to find a possible orphan node candidate for merging. Signed-off-by: Herve Codina --- dtc-parser.y | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/dtc-parser.y b/dtc-parser.y index 8d43cc4e..6bf6bb50 100644 --- a/dtc-parser.y +++ b/dtc-parser.y @@ -39,11 +39,32 @@ static struct node *parser_get_node_by_ref(struct node = *dt, struct node *orphanl * Use a temporary dt_info in order to use dti_get_node_by_ref() */ struct dt_info dti =3D {}; + struct node *target; + struct node *orphan; =20 dti.dt =3D dt; dti.orphanlist =3D orphanlist; =20 - return get_node_by_ref(&dti, ref); + target =3D get_node_by_ref(&dti, ref); + if (target) + return target; + + /* + * No node were found by get_node_by_ref(). + * + * parser_get_node_by_ref() is called by the parser only to get a node + * in order to perform a possible merge. + * + * The referenced used can be a label matching an orphan node. In this + * merge context, returning a matching orphan node makes sense even if + * no label are defined for the orphan node. + */ + for_each_orphan(orphanlist, orphan) { + if (streq(orphan->ref, ref)) + return orphan; + } + + return NULL; } =20 %} --=20 2.55.0 From nobody Mon Sep 28 04:49:03 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 838C540B11B; Wed, 26 Aug 2026 09:53:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738014; cv=none; b=BAMgFVUqvyMK4M5K26RKpPoqlBaS+jDhzMBxgxKefpdqH61DFAVlS4DQMPN+5t6g6/zst4h3GtpKlyukK2532NCAuD7TzWhlOduojCrOGfkrar+edMF724G8d9urmYRMMjU0eTGM8rQMyQcK5p+v1PxuW617/0moJ0LuAGNGdD8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738014; c=relaxed/simple; bh=0t1gShhLMnScFlc+HTpNW7ec8b22R5S/ZlxX5BW8A0Q=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=r2IizVMek0ap6ts/lQpIJLtRZ55f84Zf95Oh0FXWq8CqOAUrEeW3X97iC/SFbym4vxKb5knBsDPltGathYhhwAz06IfKXeRin9nSLRC5ZeFDKc9FSLq6t1BSDo49y7r1W5sV4QVqCUCDebZyWyr9eQ5skZ2ClqNCKIrn6bSIZjY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=eR8ZkU/F; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="eR8ZkU/F" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id E11BF4E413BF; Wed, 26 Aug 2026 09:53:30 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id B4426604EC; Wed, 26 Aug 2026 09:53:30 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id C8F9D11C7ACD5; Wed, 26 Aug 2026 11:53:27 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787738009; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=8Z2TBvTt/Hk4pcXSEPftx1bbUO6H0/gNDTyYJFD44vA=; b=eR8ZkU/FsWft8t9dGEWyED8pD8kkMWBvinkPgZ+KLLUVzScEJ2RhZXmPguf9o30FJsb4T9 ELpu+BDsr/WSMdh8tr+6Z4tM3kx8WEyGb3VNFpryV1p7/VT1otfTLkWJ8elM2OnYr29JuN vFsegwT8cDWXHE8VOggx09wkms5Z9xlUwIgd3qQitV2jV3HM/aDxJ8xNL40mb4wi5gaiqH MPYulgE0xeo3ILT5txNo1+M7yv78LPhTBCnpJd87YpBQbsa0jiQuwGyhqfDDL2pD/4MJZM h5JXMdLhveunKGjRl9GvV0z1Oj+egvMd131lH49E6DQAuZpLn8oqyxmWsIVCnw== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 56/74] tests: metadata: Add a test related to orphan node merging Date: Wed, 26 Aug 2026 11:49:25 +0200 Message-ID: <20260826094950.1088288-57-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" Merging orphan node is supported. Add a test for this feature. Signed-off-by: Herve Codina --- tests/metadata_addon_orphan3.dtb.dts.expect | 22 ++++++++++++++++ tests/metadata_addon_orphan3.dtb.expect | 17 +++++++++++++ tests/metadata_addon_orphan3.dts | 28 +++++++++++++++++++++ tests/metadata_addon_orphan3.dts.dts.expect | 22 ++++++++++++++++ tests/run_tests.sh | 3 ++- 5 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 tests/metadata_addon_orphan3.dtb.dts.expect create mode 100644 tests/metadata_addon_orphan3.dtb.expect create mode 100644 tests/metadata_addon_orphan3.dts create mode 100644 tests/metadata_addon_orphan3.dts.dts.expect diff --git a/tests/metadata_addon_orphan3.dtb.dts.expect b/tests/metadata_a= ddon_orphan3.dtb.dts.expect new file mode 100644 index 00000000..2605e1b6 --- /dev/null +++ b/tests/metadata_addon_orphan3.dtb.dts.expect @@ -0,0 +1,22 @@ +/dts-v1/; +/addon/; + + +&base1 { + + addon-node1 { + prop1 =3D <0x01>; + prop2 =3D <0x02>; + }; + + addon-node2 { + prop3 =3D <0x03>; + }; +}; + +&base2 { + + addon-node { + prop =3D <0x00>; + }; +}; diff --git a/tests/metadata_addon_orphan3.dtb.expect b/tests/metadata_addon= _orphan3.dtb.expect new file mode 100644 index 00000000..5a654831 --- /dev/null +++ b/tests/metadata_addon_orphan3.dtb.expect @@ -0,0 +1,17 @@ +/dts-v1/; +/addon/; + +&base1 { + addon-node1 { + prop1 =3D <0x00000001>; + prop2 =3D <0x00000002>; + }; + addon-node2 { + prop3 =3D <0x00000003>; + }; +}; +&base2 { + addon-node { + prop =3D <0x00000000>; + }; +}; diff --git a/tests/metadata_addon_orphan3.dts b/tests/metadata_addon_orphan= 3.dts new file mode 100644 index 00000000..0fe52ec3 --- /dev/null +++ b/tests/metadata_addon_orphan3.dts @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) +/* + * Copyright (C) 2026 Bootlin + */ + +/dts-v1/; +/addon/; + +&base1 { + addon-node1 { + prop1 =3D <1>; + }; +}; + +&base2 { + addon-node { + prop =3D <0>; + }; +}; + +&base1 { + addon-node1 { + prop2 =3D <2>; + }; + addon-node2 { + prop3 =3D <3>; + }; +}; diff --git a/tests/metadata_addon_orphan3.dts.dts.expect b/tests/metadata_a= ddon_orphan3.dts.dts.expect new file mode 100644 index 00000000..2605e1b6 --- /dev/null +++ b/tests/metadata_addon_orphan3.dts.dts.expect @@ -0,0 +1,22 @@ +/dts-v1/; +/addon/; + + +&base1 { + + addon-node1 { + prop1 =3D <0x01>; + prop2 =3D <0x02>; + }; + + addon-node2 { + prop3 =3D <0x03>; + }; +}; + +&base2 { + + addon-node { + prop =3D <0x00>; + }; +}; diff --git a/tests/run_tests.sh b/tests/run_tests.sh index e099bd39..ab09d745 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -1251,7 +1251,8 @@ metadata_tests() { for dt in metadata_propdata_phandle_local metadata_propdata_phandle_ref \ metadata_addon_base metadata_exportsyms_local \ metadata_exportsyms_ref metadata_importsyms \ - metadata_addon_orphan1 metadata_addon_orphan2; do + metadata_addon_orphan1 metadata_addon_orphan2 \ + metadata_addon_orphan3; do run_dtc_test -I dts -O dts -o $dt.dts.dts "$SRCDIR/$dt.dts" base_run_test check_diff $dt.dts.dts "$SRCDIR/$dt.dts.dts.expect" run_dtc_test -I dts -O dtb -o $dt.dtb "$SRCDIR/$dt.dts" --=20 2.55.0 From nobody Mon Sep 28 04:49:03 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D983940DB36; Wed, 26 Aug 2026 09:53:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738017; cv=none; b=jGJ4c6sPUCo14qc/YK6sjU+UwTyzTsbCaGO+pf/D4wxmr0h9+Ce4yjvxI/5t7O4zcFiq70dc1f2euXAa4UWNxAxZkaF6PD4WNeHWcHS4dq8+egGOtUVLqbfWmBMkjmDj+LqSrwClImll0aR+lqAbVu1xQ+UoBa5oDdl7n6MBGQc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738017; c=relaxed/simple; bh=UKPFtsM9Y0dxHmr3RybJ6c3soGcTIkGoiEBbZ/dOTc0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ajaLg/6+fftWxZmidGLb8NkulowHRqqoxND/zkKxJ6/0DCrFkq7oEzS8yZvG3l/oWXkTdrsg5gZaRRY8E8bHsU0dIdPbyNEgSIGWKyopj50CuKDMkgOyhVZd1djubMhMQU86P1GBvfdolY7TgHLoiV+KoD3UM4b2VTJZu8pmMZ8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=YmpWgKtM; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="YmpWgKtM" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 191D24E413BC; Wed, 26 Aug 2026 09:53:33 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id E1D55604EC; Wed, 26 Aug 2026 09:53:32 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 12A8411C7AD6C; Wed, 26 Aug 2026 11:53:29 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787738011; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=ydI9Yn/zMnFOImYwImzFF2eDeccGOC3mwcZ5WgLZ45U=; b=YmpWgKtMV8v7atCNOS0/pWJxez1RAVFDIECvoPCpuUmchWYniBAp9gft1SAANa86pEAoiu NjW3qFaEAqgfEx+gNOjLTXWKZXkDId2T29gnXGtoC2RQrgFhtfoxNxjpo3fwLtdvmG2pu6 qa61vNFlgWcaI6kvW79piY6jUd07NqcTvOkOVREPaaEAwdLtoWRAWu5w2DlpKB2DL3CjoS QwldJkCOyAiUYYTE6hbglwnzMLINE8LgZSsgQWuit4ZRpQEOw836ATOeZ/uQYAbYkvpvlA oD/A+icnskWAFW2ZZPGTrZ/Nfr1XksXwDeop1vsOz1P3O/ZRMHYRDt78k5AiDw== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 57/74] dtc: Add support for orphan nodes sorting Date: Wed, 26 Aug 2026 11:49:26 +0200 Message-ID: <20260826094950.1088288-58-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" dtc can sort items when the command line --sort option is set. Add support for orphan nodes sorting when this option is used. Signed-off-by: Herve Codina --- livetree.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/livetree.c b/livetree.c index f7c13585..8d7803ab 100644 --- a/livetree.c +++ b/livetree.c @@ -1333,6 +1333,34 @@ static void sort_importsyms(struct dt_info *dti) free(tbl); } =20 +static void sort_orphans(struct dt_info *dti) +{ + int n =3D 0, i =3D 0; + struct node *orphan, **tbl; + + for_each_orphan(dti->orphanlist, orphan) { + sort_node(orphan); + n++; + } + + if (n =3D=3D 0) + return; + + tbl =3D xmalloc(n * sizeof(*tbl)); + + for_each_orphan(dti->orphanlist, orphan) + tbl[i++] =3D orphan; + + qsort(tbl, n, sizeof(*tbl), cmp_subnode); + + dti->orphanlist =3D tbl[0]; + for (i =3D 0; i < (n-1); i++) + tbl[i]->next_sibling =3D tbl[i+1]; + tbl[n-1]->next_sibling =3D NULL; + + free(tbl); +} + void sort_tree(struct dt_info *dti) { sort_reserve_entries(dti); @@ -1340,6 +1368,8 @@ void sort_tree(struct dt_info *dti) =20 if (dti->dt) sort_node(dti->dt); + + sort_orphans(dti); } =20 /* utility helper to avoid code duplication */ --=20 2.55.0 From nobody Mon Sep 28 04:49:03 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D5F2440EB91; Wed, 26 Aug 2026 09:53:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738018; cv=none; b=hoaAExUoGyPXngAMZ5ngQbdWG8nEGlLGYUhEkGII2XPO1LQRbDUOvPzr7NKqFAC+Afcu7WwrDO9Pm2MMjiEEZPLJQw13G/eblKdgfQ8cuB37ponNqrDpISF6yK4vbjxvOTHSF1j6eKKtfmDuX/2GZqlW8+pPOzrq0Ka0zcEN1L8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738018; c=relaxed/simple; bh=O0NUBMrXbm1LeInqs/4nkriarE+dfUKStPPehX8/fBU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=a6REJLODFswJweCalJi4elWdbSJxD4vDJlir/j5k6hn1UbvDEKug2woCcrEYqpr5G+EaZqa0AkI/NYHPMiZE1wLVBgbrwwKqgFFe3ZINyhLBuUVfrNKOj2iRQldCLAtEk/58wK/086qQp8+aoWKjuE6il8phtmzfIXw8qwlivbM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=z/KFvbDF; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="z/KFvbDF" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 776061A0E1B; Wed, 26 Aug 2026 09:53:35 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 4B91D604EC; Wed, 26 Aug 2026 09:53:35 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 8569B11C7AD65; Wed, 26 Aug 2026 11:53:32 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787738014; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=5Iym/uSDZti+GCtanRVfiK99EXl+ir/YWctdAPVSdCM=; b=z/KFvbDFucRiz5BFCHuXy9xv4GzMY3TaAipX2Mi/4bZtI2TL9s4wi+hHATE1nihakAL1UV tQaTFind1QrhyCPK0oicOz8FGRq+c7+z504coveEzguUxVgfADz+PMqKwfKbJ8KNUnQpke 8ukXTj/TFcEmTwMTo84MhBDstKdgVvQ72I1H06zGOWg6bORjCb0d55vngiCFR/vO+l5Onl CSBdEOUVGO3GhwhS3m2TRdkRmJDc/Axwf69tigA5Q54Nfw5XA7Dre5bVvO6lHwCY+lkXWV jn2mHmq0aCEDGE2gV1MVKSl6XPUtoBWGk+4libCzy0tSPh63o2TO24x8QDEwvw== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 58/74] tests: metadata: Improve sort test to check for orphan nodes sorting Date: Wed, 26 Aug 2026 11:49:27 +0200 Message-ID: <20260826094950.1088288-59-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" dtc is able to sort orphan nodes when the --sort option is used. Improve the metadata sort test to perform a check for this feature. Signed-off-by: Herve Codina --- tests/metadata_sort.dtb.dts.expect | 39 ++++++++++++++++++++++++++++++ tests/metadata_sort.dtb.expect | 30 +++++++++++++++++++++++ tests/metadata_sort.dts | 33 +++++++++++++++++++++++++ 3 files changed, 102 insertions(+) diff --git a/tests/metadata_sort.dtb.dts.expect b/tests/metadata_sort.dtb.d= ts.expect index 270c06db..df3c02ba 100644 --- a/tests/metadata_sort.dtb.dts.expect +++ b/tests/metadata_sort.dtb.dts.expect @@ -20,3 +20,42 @@ phandle =3D <0x01>; }; }; + +&abc { + prop-a =3D "a"; + prop-b =3D "b"; + + node-a { + prop =3D <0x01>; + }; + + node-b { + prop =3D <0x02>; + }; + + node-c { + prop =3D <0x03>; + }; +}; + +&de1 { + prop-a =3D "a"; + prop-b =3D "b"; + + node-a { + prop =3D <0x01>; + }; + + node-b { + prop =3D <0x02>; + }; + + node-c { + prop =3D <0x03>; + }; +}; + +&de2 { + prop-a =3D "a"; + prop-b =3D "b"; +}; diff --git a/tests/metadata_sort.dtb.expect b/tests/metadata_sort.dtb.expect index d5e22674..faca4f67 100644 --- a/tests/metadata_sort.dtb.expect +++ b/tests/metadata_sort.dtb.expect @@ -16,3 +16,33 @@ // [FDT_IMPORT_SYM] 'abc' (foo,bar) // [FDT_IMPORT_SYM] 'de1' (foo,bar) // [FDT_IMPORT_SYM] 'de2' (foo,bar) +&abc { + prop-a =3D "a"; + prop-b =3D "b"; + node-a { + prop =3D <0x00000001>; + }; + node-b { + prop =3D <0x00000002>; + }; + node-c { + prop =3D <0x00000003>; + }; +}; +&de1 { + prop-a =3D "a"; + prop-b =3D "b"; + node-a { + prop =3D <0x00000001>; + }; + node-b { + prop =3D <0x00000002>; + }; + node-c { + prop =3D <0x00000003>; + }; +}; +&de2 { + prop-a =3D "a"; + prop-b =3D "b"; +}; diff --git a/tests/metadata_sort.dts b/tests/metadata_sort.dts index e523e209..3b690a53 100644 --- a/tests/metadata_sort.dts +++ b/tests/metadata_sort.dts @@ -23,3 +23,36 @@ /export/ a: &node_b; }; }; + +&de2 { + prop-b =3D "b"; + prop-a =3D "a"; +}; + +&abc { + prop-b =3D "b"; + prop-a =3D "a"; + node-b { + prop =3D <2>; + }; + node-a { + prop =3D <1>; + }; + node-c { + prop =3D <3>; + }; +}; + +&de1 { + prop-b =3D "b"; + prop-a =3D "a"; + node-b { + prop =3D <2>; + }; + node-a { + prop =3D <1>; + }; + node-c { + prop =3D <3>; + }; +}; --=20 2.55.0 From nobody Mon Sep 28 04:49:03 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5C1AE414DF6; Wed, 26 Aug 2026 09:53:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738023; cv=none; b=R8MdB5y8Ye7xNn58FUcq46Xk0ifRcA7R1drB8owkrobO+Aj3C67TnVHj/qv7NzvjwWw93Z6UDEDQT3aHegsZbOnTX3afKs3gJS1jHkoc3zZUPCXBIs1a1EQH6EM0yrhZb1VOkeKqHykdYS/pPe9F7LjQaGnVzJTxRjsaeW+Dbzg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738023; c=relaxed/simple; bh=6E+wFWUy161S1rxriITZO7UE8PlQqF9UPXRPf/ZDivA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YqgvYv1QeB49bNmCBTH0Qlwn2cGMPfgEbo0gk1sj6Dx1D4udcjc/G0S3GA7+PGkTwE+99jDBaSJ4ubNpr5fRtzHHzJxvG1keSJ+KI+ndH4zeYBOQ+8QnzPukm/M6S5725+vnaq82X10GI30rkOL/OYztxzjVl4DJDelg/1PsJeI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=bwkmUAqf; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="bwkmUAqf" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 76D561A183A; Wed, 26 Aug 2026 09:53:38 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 45ACF604EC; Wed, 26 Aug 2026 09:53:38 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id BC77611C7ACD5; Wed, 26 Aug 2026 11:53:34 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787738017; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=N+qVzPTIzveFaIRrq2AZdIluWGl9LMhfGvGolUIoV2U=; b=bwkmUAqf9Sr61coHRxAXVtz/o5+8WdR1qYiJMxnbUYcymEu4euT9O9wCoH8yJu8oS7lW+j UkPYLMYrx48APQxCl7jdl1lgPSMl7QJgHlEhfMQoKnPNgT4vIan5DZalH11l5Ub1Wwd8yB GunVeaBOegOTmfiNrEaeB29iP7Xx9G05UO6+d0XNLfezjPwdnm6a8r7XYNSo0eAZtxlrNB 3+DE/hjfJ5oWAwq57Pnc5j82g9BGjNbXtP1PuEPLjT7x2hvDTTEEnuDy22uNCw/G3Io48Z 6qdAnhMuLrWUiuvqdNiTRHA9vsw3XyOKtfOQO1VFw+BdcvlTMl4qb3NeRZqDFw== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 59/74] dtc: Add support for references by path involving orphan nodes Date: Wed, 26 Aug 2026 11:49:28 +0200 Message-ID: <20260826094950.1088288-60-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" Referencing a sub-node from an orphan node using a path is needed. Indeed, using the following snippet: --- 8< --- /addon/; &node1 { subnode { foo-phandle =3D <&foo_label>; }; }; &node2 { foo_label: foo { prop =3D <1>; }; }; --- 8< --- Even if node2 is an orphan node, foo is a local node. foo-phandle references the foo node using a label. Once converted to a dtb, the label is lost. Only the phandle of the foo node is used in the foo-phandle property and this property is marked FDT_PROPDATA_PHANDLE. Converting back this dtb to a dts, the marked local phandle should be translated to a path to the related local node. The issue is that this local node is not in the root device tree. We need to identify the orphan node the foo node belongs to. We cannot use a path starting by '/'. This kind of path identify node in the root tree. This new syntax allows to identify the orphan node in a path: $/ This leads to a reference by path in the form &{$/}. Using the previous example, those both phandles points to the same node: foo-phandle1 =3D <&foo_label>; /* Reference by label */ foo-phandle2 =3D <&{$node2/foo}>; /* Reference by path */ When the dtb is converted back to a dts, the marked local phandle involving a subnode available from orphan nodes can be translated to a reference by path thanks to the new syntax. Add support for this &{$/} syntax to reference by path a local node from an orphan node. Signed-off-by: Herve Codina --- dtc-lexer.l | 7 ++++++ dtc-parser.y | 19 ++++++++++++++++ livetree.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++----- treesource.c | 3 ++- 4 files changed, 85 insertions(+), 7 deletions(-) diff --git a/dtc-lexer.l b/dtc-lexer.l index f21ae00d..9f611f01 100644 --- a/dtc-lexer.l +++ b/dtc-lexer.l @@ -236,6 +236,13 @@ static void PRINTF(1, 2) lexical_error(const char *fmt= , ...); return DT_PATH_REF; } =20 +<*>"&{\$"{LABEL}([/]{PATHCHAR}*)?\} { /* orphan path reference */ + yytext[yyleng-1] =3D '\0'; + DPRINT("Ref orphan path: %s\n", yytext+1); + yylval.labelref =3D xstrdup(yytext+2); + return DT_ORPHAN_PATH_REF; + } + [0-9a-fA-F]{2} { yylval.byte =3D strtol(yytext, NULL, 16); DPRINT("Byte: %02x\n", (int)yylval.byte); diff --git a/dtc-parser.y b/dtc-parser.y index 6bf6bb50..c32eb65f 100644 --- a/dtc-parser.y +++ b/dtc-parser.y @@ -111,6 +111,7 @@ static struct node *parser_get_node_by_ref(struct node = *dt, struct node *orphanl %token DT_LABEL %token DT_LABEL_REF %token DT_PATH_REF +%token DT_ORPHAN_PATH_REF %token DT_INCBIN =20 %type propdata @@ -589,6 +590,24 @@ arrayprefix: ERROR(&@2, "References are only allowed in " "arrays with 32-bit elements."); =20 + $$.data =3D data_append_integer($1.data, val, $1.bits); + } + | arrayprefix DT_ORPHAN_PATH_REF + { + uint64_t val =3D ~0ULL >> (64 - $1.bits); + + if ($1.bits =3D=3D 32) { + if (!(last_header_flags & DTSF_ADDON)) + ERROR(&@2, "Orphan path reference %s supported only in addon", $2); + + $1.data =3D data_add_marker($1.data, + REF_PHANDLE, + $2); + } else { + ERROR(&@2, "References are only allowed in " + "arrays with 32-bit elements."); + } + $$.data =3D data_append_integer($1.data, val, $1.bits); } | arrayprefix DT_LABEL diff --git a/livetree.c b/livetree.c index 8d7803ab..49912234 100644 --- a/livetree.c +++ b/livetree.c @@ -593,13 +593,31 @@ static void fill_fullpaths_(struct node *tree, const = char *prefix) static void fill_fullpaths(struct dt_info *dti) { struct node *orphan; + struct node *child; =20 /* Fill fullpaths for the root node */ if (dti->dt) fill_fullpaths_(dti->dt, ""); =20 - for_each_orphan(dti->orphanlist, orphan) - fill_fullpaths_(orphan, "__orphan__/"); + /* Fill fullpaths for orphan nodes */ + for_each_orphan(dti->orphanlist, orphan) { + if (!orphan->ref || orphan->ref[0] =3D=3D '\0') + die("orphan node has an empty ref\n"); + + /* + * An orphan node name is set with its reference. + * Its name is in the form "&xxxxx" with xxxxx its reference. + * For its full path, we use "$xxxxx" to make a clear + * distinction between a reference (&xxxxx) where a resolution + * could be involved vs a "simple" path where we just need to + * identified the orphan ($xxxxx). + */ + xasprintf(&orphan->fullpath, "$%s", orphan->ref); + orphan->basenamelen =3D strlen(orphan->ref) + 1; + + for_each_child(orphan, child) + fill_fullpaths_(child, orphan->fullpath); + } } =20 static void complete_ref_and_is_local(struct dt_info *dti, char **ref, @@ -619,14 +637,27 @@ static void complete_ref_and_is_local(struct dt_info = *dti, char **ref, * Also take care of references pointing to an orphan node. Those * reference are not local references. Indeed, an orphan node is an * external node. + * + * Even if a path to an orphan node is possible, force to use the + * orphan node reference instead of the path to avoid later complexity + * mostly in dtb generation. */ =20 if (*ref) { refnode =3D get_node_by_ref(dti, *ref); - if (refnode && !node_is_orphan(dti, refnode)) - *is_local =3D true; - else + if (!refnode) { *is_local =3D false; + return; + } + + if (node_is_orphan(dti, refnode)) { + *is_local =3D false; + /* Force to use its reference */ + *ref =3D refnode->ref; + return; + } + + *is_local =3D true; return; } =20 @@ -939,7 +970,19 @@ static struct node *get_node_by_ref_(struct node *tree= , const char *ref) path =3D slash + 1; } =20 - target =3D get_node_by_label_(tree, label); + if (label[0] =3D=3D '$' && tree->ref) { + /* + * We search for an orphan and the given tree is an + * orphan. Use the given tree only if it matches the + * expected orphan. + */ + if (streq(label + 1, tree->ref)) + target =3D tree; + else + target =3D NULL; + } else { + target =3D get_node_by_label_(tree, label); + } =20 free(buf); =20 @@ -955,6 +998,14 @@ static struct node *get_node_by_ref_(struct node *tree= , const char *ref) =20 struct node *get_node_by_path(struct dt_info *dti, const char *path) { + if (path && path[0] =3D=3D '$') { + /* + * The path starts from an orphan node. Use get node by ref to + * handle this path involving an orphan node. + */ + return get_node_by_ref(dti, path); + } + if (dti->dt) return get_node_by_path_(dti->dt, path); =20 diff --git a/treesource.c b/treesource.c index d18025c5..38932e50 100644 --- a/treesource.c +++ b/treesource.c @@ -328,7 +328,8 @@ static void write_propval(FILE *f, struct property *pro= p) break; =20 if (m_phandle) { - if (m_phandle->ref[0] =3D=3D '/') + if (m_phandle->ref[0] =3D=3D '/' /* Root node */ || + m_phandle->ref[0] =3D=3D '$' /* Orphan node */) fprintf(f, "&{%s}", m_phandle->ref); else fprintf(f, "&%s", m_phandle->ref); --=20 2.55.0 From nobody Mon Sep 28 04:49:03 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 909703DA5C1; Wed, 26 Aug 2026 09:53:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738024; cv=none; b=SSmLT5SQ6uHM6r+n0+aAefZlWfYWr/iDL6CEFfH5E6U11mt5T69XipSaIE4O2tvznF+kvUnSz0g6rNTG4cUcWwXYoJ9hA2wtdP+/ORVkMAkN3U+OGGy9eAu2X64GssV+5Y9yFlN92aUGhmHXzSsClOUWWx7nNn1wIZcQ9S3yW20= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738024; c=relaxed/simple; bh=GMAAqiQdcU0tZ5idYyQng0vbUQ5u9Ntk7T0lIHMgajk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=h8J+3iUbS0CDaNSm5H33NrNHszS0awTTYndyCHOS5sCv0Ghw6a9QSwcduUgP8GLpWo+Tte8W8VrP/GxcHitX2WyWeuxPxPgKQLrCaV77OA/pU1/ttuOvPL4fZdkwQN3HX2NP7/uqDQ0Pvem1jM7rMSa/tH+jaU2Ei3b8USmd1N8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=E+ZRFYkT; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="E+ZRFYkT" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id E750E1A183E; Wed, 26 Aug 2026 09:53:40 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id BBE6E604EC; Wed, 26 Aug 2026 09:53:40 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 9A37111C7AD65; Wed, 26 Aug 2026 11:53:37 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787738019; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=uYEYHzVamgMMqJiPZi+Ehy8nVDS2QRdmNXkGwIMFa24=; b=E+ZRFYkTPx99F5IkH7gVs1dVcV7PIVkpDJiesgMUa74WF0aGAY99jGLnQ9dmXFSjhJuATh 5C8x/Miv52K9WsTZV1oJOMYFRcLw3R7PJ3UYQ5/sMHtwJyFVu1DbWrXHa5nyVSpLj03dIx gO1tkdyD4N96B8jaul5jS9TkU31Q0JYbMjNXb9NcjqyrM8Eee5wuMb5htPFoo0ol4m5gOB VDfmvU7kUsknWxbrR+vTHfA0AElv+vYE6be8s+DqA1zewW6VNR70miFdB3iFhkyiwlXmlo U+5W8DtvkFv638FCck3/ibrn9XS2m00NslUaNRv2RIQl8B66hb9HaJh0AdzRSw== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 60/74] tests: metadata: Add a test for references by path involving orphan nodes Date: Wed, 26 Aug 2026 11:49:29 +0200 Message-ID: <20260826094950.1088288-61-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" The syntax '&{$/}' allows to reference by path a node that belongs to an orphan node. Add a test related to this kind of references. Signed-off-by: Herve Codina --- .../metadata_addon_references.dtb.dts.expect | 47 +++++++++++++++++++ tests/metadata_addon_references.dtb.expect | 47 +++++++++++++++++++ tests/metadata_addon_references.dts | 43 +++++++++++++++++ .../metadata_addon_references.dts.dts.expect | 47 +++++++++++++++++++ tests/run_tests.sh | 2 +- 5 files changed, 185 insertions(+), 1 deletion(-) create mode 100644 tests/metadata_addon_references.dtb.dts.expect create mode 100644 tests/metadata_addon_references.dtb.expect create mode 100644 tests/metadata_addon_references.dts create mode 100644 tests/metadata_addon_references.dts.dts.expect diff --git a/tests/metadata_addon_references.dtb.dts.expect b/tests/metadat= a_addon_references.dtb.dts.expect new file mode 100644 index 00000000..ccd7c849 --- /dev/null +++ b/tests/metadata_addon_references.dtb.dts.expect @@ -0,0 +1,47 @@ +/dts-v1/; +/addon/; + +/ { + + sub-node { + ref1-base1 =3D <&base1>; + ref2-base1-addon-node =3D <&{$base1/addon-node}>; + ref3-base1-addon-node =3D <&{$base1/addon-node}>; + ref4-base1-addon-node =3D <&{$base1/addon-node}>; + ref5-base3 =3D <&base3>; + ref6-base3 =3D <&base3>; + ref7-base3-subsubnode =3D <&{$base3/sub-node/sub-subnode}>; + phandle =3D <0x03>; + }; +}; + +&base1 { + + addon-node { + prop =3D <0x02>; + phandle =3D <0x01>; + }; +}; + +&base2 { + + addon-node1 { + ref-base1-addon-node =3D <&{$base1/addon-node}>; + }; + + addon-node2 { + ref-root-sub-node =3D <&{/sub-node}>; + }; +}; + +&base3 { + + sub-node { + prop =3D <0x03>; + + sub-subnode { + prop =3D <0x04>; + phandle =3D <0x02>; + }; + }; +}; diff --git a/tests/metadata_addon_references.dtb.expect b/tests/metadata_ad= don_references.dtb.expect new file mode 100644 index 00000000..c58e3b2d --- /dev/null +++ b/tests/metadata_addon_references.dtb.expect @@ -0,0 +1,47 @@ +/dts-v1/; +/addon/; + +/ { + sub-node { + ref1-base1 =3D <0xffffffff>; + // [FDT_PROPDATA_PHANDLE_REF] ref1-base1[0], ref =3D base1 + ref2-base1-addon-node =3D <0x00000001>; + // [FDT_PROPDATA_PHANDLE] ref2-base1-addon-node[0] + ref3-base1-addon-node =3D <0x00000001>; + // [FDT_PROPDATA_PHANDLE] ref3-base1-addon-node[0] + ref4-base1-addon-node =3D <0x00000001>; + // [FDT_PROPDATA_PHANDLE] ref4-base1-addon-node[0] + ref5-base3 =3D <0xffffffff>; + // [FDT_PROPDATA_PHANDLE_REF] ref5-base3[0], ref =3D base3 + ref6-base3 =3D <0xffffffff>; + // [FDT_PROPDATA_PHANDLE_REF] ref6-base3[0], ref =3D base3 + ref7-base3-subsubnode =3D <0x00000002>; + // [FDT_PROPDATA_PHANDLE] ref7-base3-subsubnode[0] + phandle =3D <0x00000003>; + }; +}; +&base1 { + addon-node { + prop =3D <0x00000002>; + phandle =3D <0x00000001>; + }; +}; +&base2 { + addon-node1 { + ref-base1-addon-node =3D <0x00000001>; + // [FDT_PROPDATA_PHANDLE] ref-base1-addon-node[0] + }; + addon-node2 { + ref-root-sub-node =3D <0x00000003>; + // [FDT_PROPDATA_PHANDLE] ref-root-sub-node[0] + }; +}; +&base3 { + sub-node { + prop =3D <0x00000003>; + sub-subnode { + prop =3D <0x00000004>; + phandle =3D <0x00000002>; + }; + }; +}; diff --git a/tests/metadata_addon_references.dts b/tests/metadata_addon_ref= erences.dts new file mode 100644 index 00000000..239c1416 --- /dev/null +++ b/tests/metadata_addon_references.dts @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) +/* + * Copyright (C) 2026 Bootlin + */ + +/dts-v1/; +/addon/; + +/ { + sub_node: sub-node { + ref1-base1 =3D <&base1>; + ref2-base1-addon-node =3D <&b1_addon>; + ref3-base1-addon-node =3D <&{$base1/addon-node}>; + ref4-base1-addon-node =3D <&{$base1/addon-node/}>; + ref5-base3 =3D <&{$base3}>; + ref6-base3 =3D <&{$base3/}>; + ref7-base3-subsubnode =3D <&{$base3/sub-node/sub-subnode}>; + }; +}; + +&base1 { + b1_addon: addon-node { + prop =3D <2>; + }; +}; + +&base2 { + addon-node1 { + ref-base1-addon-node =3D <&b1_addon>; + }; + addon-node2 { + ref-root-sub-node =3D <&sub_node>; + }; +}; + +&base3 { + sub-node { + prop =3D <3>; + sub-subnode { + prop =3D <4>; + }; + }; +}; diff --git a/tests/metadata_addon_references.dts.dts.expect b/tests/metadat= a_addon_references.dts.dts.expect new file mode 100644 index 00000000..47c30a1f --- /dev/null +++ b/tests/metadata_addon_references.dts.dts.expect @@ -0,0 +1,47 @@ +/dts-v1/; +/addon/; + +/ { + + sub_node: sub-node { + ref1-base1 =3D <&base1>; + ref2-base1-addon-node =3D <&b1_addon>; + ref3-base1-addon-node =3D <&{$base1/addon-node}>; + ref4-base1-addon-node =3D <&{$base1/addon-node/}>; + ref5-base3 =3D <&base3>; + ref6-base3 =3D <&base3>; + ref7-base3-subsubnode =3D <&{$base3/sub-node/sub-subnode}>; + phandle =3D <0x03>; + }; +}; + +&base1 { + + b1_addon: addon-node { + prop =3D <0x02>; + phandle =3D <0x01>; + }; +}; + +&base2 { + + addon-node1 { + ref-base1-addon-node =3D <&b1_addon>; + }; + + addon-node2 { + ref-root-sub-node =3D <&sub_node>; + }; +}; + +&base3 { + + sub-node { + prop =3D <0x03>; + + sub-subnode { + prop =3D <0x04>; + phandle =3D <0x02>; + }; + }; +}; diff --git a/tests/run_tests.sh b/tests/run_tests.sh index ab09d745..61a69fcb 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -1252,7 +1252,7 @@ metadata_tests() { metadata_addon_base metadata_exportsyms_local \ metadata_exportsyms_ref metadata_importsyms \ metadata_addon_orphan1 metadata_addon_orphan2 \ - metadata_addon_orphan3; do + metadata_addon_orphan3 metadata_addon_references; do run_dtc_test -I dts -O dts -o $dt.dts.dts "$SRCDIR/$dt.dts" base_run_test check_diff $dt.dts.dts "$SRCDIR/$dt.dts.dts.expect" run_dtc_test -I dts -O dtb -o $dt.dtb "$SRCDIR/$dt.dts" --=20 2.55.0 From nobody Mon Sep 28 04:49:03 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8DE2F4137BC; Wed, 26 Aug 2026 09:53:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738027; cv=none; b=Ltod2c3km3dRW7L+sdiXvu5HGDTY1ivKo0GFx3zF/3lYENTvo17NO7mnOieboz8jly7nNRdH0WV0dZXdv11zgjUtVnngNLz7pUdY+6z9UmuUk+ABzWnRuOEcT+mlEVy9ZHF9ARlIz3Vu0il/jeBiHjSLi1WHlizeLi4qm9FAKUw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738027; c=relaxed/simple; bh=WAwuOgOGW7yGhkVc9gpOvsidUgfpNMXIFUtTIUf037A=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=B0SSe/q0/ZtPf/FZMAIMcmXJPaghWU2Uh7WnI/zSOOM6sfA4b8x1Docv6t7whiaaVMyvKLuZKIMo+SbUhYUdZU2tMHxe5UYXlI/jCrtT4ybgo/CQLY5YGA/pnY8HPyfkBV6GbuxhE8N06MxbsB8Qb++7asr1riV8yqF3nMWbHEo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=PxBHfMP5; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="PxBHfMP5" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 0E29E4E413BF; Wed, 26 Aug 2026 09:53:44 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id D7431604EC; Wed, 26 Aug 2026 09:53:43 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id D397711C7AD6D; Wed, 26 Aug 2026 11:53:39 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787738022; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=egqqwQy0hHPWpxEp6kIK5+Ko8Vp2nN55yoHChJ1LMGA=; b=PxBHfMP5WolwqTNZitZGqiE7swqoP+/nwnzbzjzvKz8ZLXJw0HtXbKf/JX9Ay/V0+6l+Cz lSW79zYK0ee8uNyzBwsCEOIoMGsjXmhbf3rhvnjsavBFSv+XEOb1Scusz3ey/DhGRzBqNQ SHmGjSaO/8E5CWRKZPYG6h3J/y5FYBEsb4PXD7dt/vIIwYBleEZe600BZcIwqIDKmV4Kdu CeWfApcaliX3XQ2OEOgD9q1i50x4g3RwT+yCfzSdaZt9XP89TWjMpU0npsMGeWTrnDf3nC Ulbq64ptqnrtDXrpuiIhISCpsjRJ8xykS3gveq0jSXSLM8ZGM4GJwKjV5AAUuA== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 61/74] dtc: Add support for namespace labels references Date: Wed, 26 Aug 2026 11:49:30 +0200 Message-ID: <20260826094950.1088288-62-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" Namespace labels references can only be present in addons and involves import/exported symbols. They allow to 'jump' from node to node based on exported symbols defined at each node. When a label reference contains a dot ('.') char, it becomes a namespace labels reference. For instance &foo.bar.baz is a namespace label reference. The resolution of this reference is performed in a recursive way. - Get the node referenced by foo. - From this node get the node referenced by bar in exported symbols from foo. - From this node get the node referenced by baz in exported symbols from bar. - ... The first item (foo) involves import symbols defined in the addon and export symbols defined in the node the addon is applied to. Other items involves only exported symbols in referenced nodes to perform the resolution chain. We leave the addon thanks to the first item and import symbols. Other items allow to perform jumps from node to node in the base device-tree without leaving it. The full resolution can be summarized with the following diagram: (addon DT) &foo.bar.baz | | | | | +--------------------------------------------+ | | | | +-------------------------------+ | | | | | (addon DT) | | +-> /import/ foo: --+ | | | | | | | | addon applied at | | | target node in the | | | base DT | | | | | | | | (base DT) | | | +---> target { v | | /export/ foo: &n1; | | | | | | | | v (base DT) | | n1 { v | /export/ bar: &n2; | | | v (base DT) | n2 { v /export/ baz: &n3; | | v n3 { ... }; '&foo.bar.baz' references, in the end, the n3 node from the base DT. Implement support for namespace references parsing in dtc. The resolution part is out of dtc. Indeed, dtc has no support for applying an addon. Signed-off-by: Herve Codina --- dtc-lexer.l | 13 +++++++++++++ dtc-parser.y | 49 ++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 59 insertions(+), 3 deletions(-) diff --git a/dtc-lexer.l b/dtc-lexer.l index 9f611f01..a3291ff6 100644 --- a/dtc-lexer.l +++ b/dtc-lexer.l @@ -229,6 +229,12 @@ static void PRINTF(1, 2) lexical_error(const char *fmt= , ...); return DT_LABEL_REF; } =20 +<*>\&{LABEL}(\.{LABEL})+ { /* namespace label reference */ + DPRINT("Ref namespace: %s\n", yytext+1); + yylval.labelref =3D xstrdup(yytext+1); + return DT_LABEL_NAMESPACE_REF; + } + <*>"&{"{PATHCHAR}*\} { /* new-style path reference */ yytext[yyleng-1] =3D '\0'; DPRINT("Ref: %s\n", yytext+2); @@ -243,6 +249,13 @@ static void PRINTF(1, 2) lexical_error(const char *fmt= , ...); return DT_ORPHAN_PATH_REF; } =20 +<*>"&{\$"{LABEL}(\.{LABEL})+([/]{PATHCHAR}*)?\} { /* orphan path referenc= e */ + yytext[yyleng-1] =3D '\0'; + DPRINT("Ref (namespace) orphan path: %s\n", yytext+1); + yylval.labelref =3D xstrdup(yytext+2); + return DT_ORPHAN_PATH_REF; + } + [0-9a-fA-F]{2} { yylval.byte =3D strtol(yytext, NULL, 16); DPRINT("Byte: %02x\n", (int)yylval.byte); diff --git a/dtc-parser.y b/dtc-parser.y index c32eb65f..4139d96b 100644 --- a/dtc-parser.y +++ b/dtc-parser.y @@ -32,6 +32,11 @@ static bool is_ref_relative(const char *ref) return ref[0] !=3D '/' && strchr(&ref[1], '/'); } =20 +static bool is_ref_namespace(const char *ref) +{ + return strchr(ref, '.'); +} + static struct node *parser_get_node_by_ref(struct node *dt, struct node *o= rphanlist, const char *ref) { @@ -110,6 +115,7 @@ static struct node *parser_get_node_by_ref(struct node = *dt, struct node *orphanl %token DT_STRING %token DT_LABEL %token DT_LABEL_REF +%token DT_LABEL_NAMESPACE_REF %token DT_PATH_REF %token DT_ORPHAN_PATH_REF %token DT_INCBIN @@ -260,7 +266,7 @@ importdef: } ; =20 -dt_ref: DT_LABEL_REF | DT_PATH_REF; +dt_ref: DT_LABEL_REF | DT_PATH_REF | DT_LABEL_NAMESPACE_REF; =20 devicetree: '/' nodedef @@ -281,6 +287,9 @@ devicetree: else if (is_ref_relative($1)) ERROR(&@2, "Label-relative reference %s not supported in plugin nor ad= don", $1); =20 + if (!(last_header_flags & DTSF_ADDON) && is_ref_namespace($1)) + ERROR(&@2, "Namespaced label reference %s supported only in addon", $1= ); + if (last_header_flags & DTSF_PLUGIN) { $$ =3D plugin_add_orphan_node( name_node(build_node(NULL, NULL, NULL, NULL), @@ -300,6 +309,10 @@ devicetree: if ((last_header_flags & (DTSF_PLUGIN | DTSF_ADDON)) && is_ref_relative= ($3)) ERROR(&@2, "Label-relative reference %s not supported in plugin nor ad= don", $3); =20 + if (!(last_header_flags & DTSF_ADDON) && is_ref_namespace($3)) + ERROR(&@2, "Namespaced label reference %s supported only in addon", $3= ); + + if (target) { add_label(&target->labels, $2); merge_nodes(target, $4); @@ -346,6 +359,25 @@ devicetree: } $$ =3D $1; } + | devicetree DT_LABEL_NAMESPACE_REF nodedef + { + struct node *target =3D parser_get_node_by_ref( + $1, parser_orphanlist, $2); + + if (!(last_header_flags & DTSF_ADDON)) + ERROR(&@2, "Namespaced label reference %s supported only in addon", $2= ); + + if (target) { + merge_nodes(target, $3); + } else { + if (last_header_flags & DTSF_ADDON) + addon_add_orphan_node(&parser_orphanlist, + orphan_node($3, $2)); + else + ERROR(&@2, "Label or path %s not found", $2); + } + $$ =3D $1; + } | devicetree DT_DEL_NODE dt_ref ';' { struct node *target =3D parser_get_node_by_ref( @@ -422,6 +454,10 @@ exportlist: exportdef: DT_EXPORT DT_LABEL dt_ref ';' { + /* Only an addon can use namespaced labels references */ + if (!(last_header_flags & DTSF_ADDON) && is_ref_namespace($3)) + ERROR(&@2, "Namespaced label reference %s supported only in addon", $3= ); + $$ =3D build_exportsym($2, $3, 0, &@$); free($2); free($3); @@ -477,6 +513,9 @@ propdata: } | propdataprefix dt_ref { + if (!(last_header_flags & DTSF_ADDON) && is_ref_namespace($2)) + ERROR(&@2, "Namespaced label reference %s supported only in addon", $2= ); + $1 =3D data_add_marker($1, TYPE_STRING, $2); $$ =3D data_add_marker($1, REF_PATH, $2); } @@ -582,13 +621,17 @@ arrayprefix: { uint64_t val =3D ~0ULL >> (64 - $1.bits); =20 - if ($1.bits =3D=3D 32) + if ($1.bits =3D=3D 32) { + if (!(last_header_flags & DTSF_ADDON) && is_ref_namespace($2)) + ERROR(&@2, "Namespaced label reference %s supported only in addon", $= 2); + $1.data =3D data_add_marker($1.data, REF_PHANDLE, $2); - else + } else { ERROR(&@2, "References are only allowed in " "arrays with 32-bit elements."); + } =20 $$.data =3D data_append_integer($1.data, val, $1.bits); } --=20 2.55.0 From nobody Mon Sep 28 04:49:03 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E2EFE3BCD27; Wed, 26 Aug 2026 09:53:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738029; cv=none; b=U2jlPtEwXC+bCLHFj3OeWgkY7MVN5ZixPtdrqendww+Z/u/+xoNihe2278WNd4bE2PSLE7g7M2RipQGa1R3rGJbdoyHW6/fLiZHpMUJAPSwQz4VtYG9ijlorIZwm3Wa1brOnElw8H+M5t9UkDfAHFv7lGGYhNqXC3POUKhbj7zw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738029; c=relaxed/simple; bh=JPCB9M7KbROlMOvoQzAisGzc0NB3d9rM2Ty8NaZ2Kz8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=AiMYzPITNZ6dbF00ca1463w8WUBUHvgwAxLCZBOTaLyy6SUh5PbAFGanzFEEgZuf/TSvt0VgEflo3crz3dHzaIEu/URc2sgL9R8vA1wr7Uu8aSWxCH/x3asH7G7n6OrVpLcSzMMbLorq0eOYqzsEMStCx50Y8t5M1nwZhH5U3dg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=WxGYnUkX; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="WxGYnUkX" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 9D56C1A183A; Wed, 26 Aug 2026 09:53:46 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 6AB8B604EC; Wed, 26 Aug 2026 09:53:46 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 307E911C7AD65; Wed, 26 Aug 2026 11:53:43 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787738025; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=hrpktcQ0qyyNHgm6W4k1YNG5kh8x30F9bbqoltA7bW4=; b=WxGYnUkXqJBXzR0X6sW0SEvd4vQaLr8O6T3ZBr/z84wDow5i60+GIa34TKUNxtveAmw+uS ukXh1Ik550wvBp61K7DJABoDUnjXQcx6/2qvIuR4Vohqp1ofXJv0IssuehioXzztLs80uz hXMQ5cPNkG2DxD0fatkmTuUOAARxCGrK3UNPqcN8KtOLfU37GK9OIuM8PsUev5G6j7/gBu osc18lG2N1gmCof67jB44vSiXEVQuboJrQfav+0wBADtbLGtlPg93xddS0a9uOA4J5HuWM 57lKZe3woUhcqVCW6+pIXbVCfz4KpruEz6jJqgD6jDXY8+pMvo8id3eEseoEsw== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 62/74] tests: metadata: Add a test for namespace labels references Date: Wed, 26 Aug 2026 11:49:31 +0200 Message-ID: <20260826094950.1088288-63-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" Namespace labels references are references in the form '&foo.bar.baz'. Support for namespace labels references has been recently added to dtc. Add a test related to this kind of references. Signed-off-by: Herve Codina --- ...metadata_addon_refnamespace.dtb.dts.expect | 32 ++++++++++++++++ tests/metadata_addon_refnamespace.dtb.expect | 29 ++++++++++++++ tests/metadata_addon_refnamespace.dts | 38 +++++++++++++++++++ ...metadata_addon_refnamespace.dts.dts.expect | 32 ++++++++++++++++ tests/run_tests.sh | 3 +- 5 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 tests/metadata_addon_refnamespace.dtb.dts.expect create mode 100644 tests/metadata_addon_refnamespace.dtb.expect create mode 100644 tests/metadata_addon_refnamespace.dts create mode 100644 tests/metadata_addon_refnamespace.dts.dts.expect diff --git a/tests/metadata_addon_refnamespace.dtb.dts.expect b/tests/metad= ata_addon_refnamespace.dtb.dts.expect new file mode 100644 index 00000000..111a7462 --- /dev/null +++ b/tests/metadata_addon_refnamespace.dtb.dts.expect @@ -0,0 +1,32 @@ +/dts-v1/; +/addon/; + +/import/ foo: "abc,foo"; +/import/ bar: "abc,bar"; + + +&foo.x { + + addon-node { + ref0 =3D <&foo.x.y>; + ref1 =3D <0x0a &bar.other 0x14>; + ref2 =3D <&{$foo.x.y.z/addon-node}>; + ref3 =3D <&{$foo.x.y.z/addon-node}>; + }; +}; + +&foo.x.y.z { + + addon-node { + prop =3D <0x00>; + phandle =3D <0x01>; + }; +}; + +&foo.x.y { + + node { + prop1 =3D <0x01>; + prop2 =3D <0x02>; + }; +}; diff --git a/tests/metadata_addon_refnamespace.dtb.expect b/tests/metadata_= addon_refnamespace.dtb.expect new file mode 100644 index 00000000..8db63a1b --- /dev/null +++ b/tests/metadata_addon_refnamespace.dtb.expect @@ -0,0 +1,29 @@ +/dts-v1/; +/addon/; + +// [FDT_IMPORT_SYM] 'foo' (abc,foo) +// [FDT_IMPORT_SYM] 'bar' (abc,bar) +&foo.x { + addon-node { + ref0 =3D <0xffffffff>; + // [FDT_PROPDATA_PHANDLE_REF] ref0[0], ref =3D foo.x.y + ref1 =3D <0x0000000a 0xffffffff 0x00000014>; + // [FDT_PROPDATA_PHANDLE_REF] ref1[4], ref =3D bar.other + ref2 =3D <0x00000001>; + // [FDT_PROPDATA_PHANDLE] ref2[0] + ref3 =3D <0x00000001>; + // [FDT_PROPDATA_PHANDLE] ref3[0] + }; +}; +&foo.x.y.z { + addon-node { + prop =3D <0x00000000>; + phandle =3D <0x00000001>; + }; +}; +&foo.x.y { + node { + prop1 =3D <0x00000001>; + prop2 =3D <0x00000002>; + }; +}; diff --git a/tests/metadata_addon_refnamespace.dts b/tests/metadata_addon_r= efnamespace.dts new file mode 100644 index 00000000..51a17a9a --- /dev/null +++ b/tests/metadata_addon_refnamespace.dts @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) +/* + * Copyright (C) 2026 Bootlin + */ + +/dts-v1/; +/addon/; + +/import/ foo: "abc,foo"; +/import/ bar: "abc,bar"; + + +&foo.x { + addon-node { + ref0 =3D <&foo.x.y>; + ref1 =3D <10 &bar.other 20>; + ref2 =3D <&addon_node>; + ref3 =3D <&{$foo.x.y.z/addon-node}>; + }; +}; + +&foo.x.y.z { + addon_node: addon-node { + prop =3D <0>; + }; +}; + +&foo.x.y { + node { + prop1 =3D <1>; + }; +}; + +&foo.x.y { + node { + prop2 =3D <2>; + }; +}; diff --git a/tests/metadata_addon_refnamespace.dts.dts.expect b/tests/metad= ata_addon_refnamespace.dts.dts.expect new file mode 100644 index 00000000..94861c3b --- /dev/null +++ b/tests/metadata_addon_refnamespace.dts.dts.expect @@ -0,0 +1,32 @@ +/dts-v1/; +/addon/; + +/import/ foo: "abc,foo"; +/import/ bar: "abc,bar"; + + +&foo.x { + + addon-node { + ref0 =3D <&foo.x.y>; + ref1 =3D <0x0a &bar.other 0x14>; + ref2 =3D <&addon_node>; + ref3 =3D <&{$foo.x.y.z/addon-node}>; + }; +}; + +&foo.x.y.z { + + addon_node: addon-node { + prop =3D <0x00>; + phandle =3D <0x01>; + }; +}; + +&foo.x.y { + + node { + prop1 =3D <0x01>; + prop2 =3D <0x02>; + }; +}; diff --git a/tests/run_tests.sh b/tests/run_tests.sh index 61a69fcb..7f47b685 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -1252,7 +1252,8 @@ metadata_tests() { metadata_addon_base metadata_exportsyms_local \ metadata_exportsyms_ref metadata_importsyms \ metadata_addon_orphan1 metadata_addon_orphan2 \ - metadata_addon_orphan3 metadata_addon_references; do + metadata_addon_orphan3 metadata_addon_references \ + metadata_addon_refnamespace; do run_dtc_test -I dts -O dts -o $dt.dts.dts "$SRCDIR/$dt.dts" base_run_test check_diff $dt.dts.dts "$SRCDIR/$dt.dts.dts.expect" run_dtc_test -I dts -O dtb -o $dt.dtb "$SRCDIR/$dt.dts" --=20 2.55.0 From nobody Mon Sep 28 04:49:03 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DAED041D20D; Wed, 26 Aug 2026 09:53:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738035; cv=none; b=CklZiCuiU+nw9k5cLhNcQ2IEqAej6tUbTDNHIe3T+nQa5E68II0sHDB0wX4xuvOVnAX+YxpW2vYtryf9ZsQrRDsKa/2DAK2fBNggk0joiOVDMaUXMZW8dWIa7fdd6FMHxCGDy7FFsIAyVhGpWV0xGIlkQMNyhAXYdOEKbitlqiw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738035; c=relaxed/simple; bh=CrY3X4e16edH1lpROp9ugrA1jcTNkDYIdyZSwwA/kTU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=e79qSCA9Y5qTGCiGZOps3CxGjUPu/UejSEV/pw9uMAn26U/cASueoyLyWA5RBzf3UXTBI8TZeWm3UFNC8WklsdtU72PQTcArakIGICNf7gY2pVLN4Dzy69bAhyPdMxVWWILqFipNDn89qg1sC6jOnq11kFzX1E12G7aa8LonSPw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=TErXn3b/; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="TErXn3b/" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 74BE31A183E; Wed, 26 Aug 2026 09:53:49 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 41BD6604EC; Wed, 26 Aug 2026 09:53:49 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 9A94B11C7AD6E; Wed, 26 Aug 2026 11:53:45 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787738028; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=uA7SKRvMKnN25iH1hS2pi/D4C8lxGeWYDGFLjyPdLyc=; b=TErXn3b/gi6TXE9AdiwYVEM4rP96fn27Q6FX1JS42Oj5qI9aSIejzKyozjkBsIOZqb+02z zTktGiw+qojgYOi+f2j1CqlRWEEnCXrYNZbNQYTq9iOCLOEA3+nfXRJ0ByQX/8Nf+BJzQp PuekmFOCbRwF2WXS3fcPMnBB5Xo9krWHxLwVo0wPtLKxY3hzkCMDhkqpfewi/ut0D0ioHP PLwkb0ASKQ0kv+4hKoQKa7vvs4savfM3FpYq92KrHta1pE7tqot2C8sllDTCbit2XQlQs8 cj2FDAZkU4xBeUyuyBU1xun5BoR+SEzRd72MuqE825RtfcSWZ0ZFlV8DTfbZ9A== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 63/74] libfdt: Add support for applying an addon on a base device-tree blob Date: Wed, 26 Aug 2026 11:49:32 +0200 Message-ID: <20260826094950.1088288-64-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" Addon dtbs have been recently supported. The missing part is having some support for addon usage. The goal of addons is to extend a base device-tree. This feature is similar to the overlay feature but addons and recent modifications offer metadata and import/export symbol mechanism. This import/export symbol mechanism allow a fine tuning of symbols exported (i.e. symbol seen from the addon). To extend the base device-tree, an addon needs to be applied to this base device-tree at a specific node. The specific node, target node of the addon, is not encoded in the addon dtb. Indeed, addons do not depends on the exact base device tree structure. An addon can be applied on top of any base device tree as soon as the target node matches expectations of the addon. Exported symbols at this target node has to match imported symbols defined in the addon. When the addon is applied three macro operations have to be done: - Avoid phandle conflict The conflict avoidance consists in fixing local phandle to avoid conflict with already existing phandle available in the base device-tree. This operation involved metadata recently added in dtb format. - Resolve unresolved symbols The symbol resolution consists in replacing unresolved symbol references present in the addon dtb by a reference to an existing node in the base device tree. This operation involved metadata and import/export symbols. - Merge addon nodes into base device-tree This merging consists in adding additional nodes described in the addon into the base device-tree. fdt_addon_apply() allows to apply an addon on a base device-tree and performs internally all the needed operations. Signed-off-by: Herve Codina --- libfdt/Makefile.libfdt | 2 +- libfdt/fdt_addon.c | 1741 ++++++++++++++++++++++++++++++++++++++ libfdt/fdt_rw.c | 69 ++ libfdt/libfdt.h | 32 + libfdt/libfdt_internal.h | 5 + libfdt/meson.build | 1 + libfdt/version.lds | 1 + 7 files changed, 1850 insertions(+), 1 deletion(-) create mode 100644 libfdt/fdt_addon.c diff --git a/libfdt/Makefile.libfdt b/libfdt/Makefile.libfdt index b763b2ec..437d5b54 100644 --- a/libfdt/Makefile.libfdt +++ b/libfdt/Makefile.libfdt @@ -10,7 +10,7 @@ LIBFDT_soname =3D libfdt.$(SHAREDLIB_EXT).1 LIBFDT_INCLUDES =3D fdt.h libfdt.h libfdt_env.h LIBFDT_VERSION =3D version.lds LIBFDT_SRCS =3D fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c = fdt_empty_tree.c \ - fdt_addresses.c fdt_overlay.c fdt_check.c + fdt_addresses.c fdt_overlay.c fdt_addon.c fdt_check.c LIBFDT_OBJS =3D $(LIBFDT_SRCS:%.c=3D%.o) LIBFDT_LIB =3D libfdt.$(SHAREDLIB_EXT).$(DTC_VERSION) =20 diff --git a/libfdt/fdt_addon.c b/libfdt/fdt_addon.c new file mode 100644 index 00000000..54e71cbd --- /dev/null +++ b/libfdt/fdt_addon.c @@ -0,0 +1,1741 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) +/* + * libfdt - Flat Device Tree manipulation + * Copyright (C) 2025 Bootlin + */ +#include "libfdt_env.h" + +#include +#include + +#include "libfdt_internal.h" + +/** + * fdt_skip_string - Skip a string + * @fdt: device tree blob + * @offset: Offset of the string to skip + * + * fdt_skip_string() returns the offset of the first byte after the skipped + * string. + * + * returns: + * offset of the first byte after the skipped string + */ +static int fdt_skip_string(const void *fdt, int offset) +{ + const char *p; + int next; + + next =3D offset; + do { + p =3D fdt_offset_ptr(fdt, next++, 1); + } while (p && (*p !=3D '\0')); + + return next; +} + +/** + * addon_phandle_add_offset - Increases a phandle by an offset + * @fdta: Addon device tree blob + * @node: Device tree addon blob + * @name: Name of the property to modify (phandle or linux,phandle) + * @delta: offset to apply + * + * addon_phandle_add_offset() increments a node phandle by a given + * offset. + * + * returns: + * 0 on success. + * Negative error code on error + */ +static int addon_phandle_add_offset(void *fdta, int node, const char *name, + uint32_t delta) +{ + fdt32_t *valp, val; + int len; + + valp =3D fdt_getprop_w(fdta, node, name, &len); + if (!valp) + return len; + if (len !=3D sizeof(val)) + return -FDT_ERR_BADPHANDLE; + + val =3D fdt32_ld(valp); + if (val + delta < val || val + delta =3D=3D (uint32_t)-1) + return -FDT_ERR_NOPHANDLES; + fdt32_st(valp, val + delta); + return 0; +} + +/** + * addon_phandle_set_val - Set a phandle value + * @fdt: Addon device tree blob + * @node: Device tree addon blob + * @name: Name of the property to modify (phandle or linux,phandle) + * @val: Value to set + * + * addon_phandle_set_val() set a node phandle to a given offset. + * + * returns: + * 0 on success. + * Negative error code on error + */ +static int addon_phandle_set_val(void *fdta, int node, const char *name, + uint32_t val) +{ + fdt32_t *valp; + int len; + + valp =3D fdt_getprop_w(fdta, node, name, &len); + if (!valp) + return len; + if (len !=3D sizeof(val)) + return -FDT_ERR_BADPHANDLE; + + fdt32_st(valp, val); + return 0; +} + +/** + * addon_property_add_offset - Increases a property value (a phandle refer= ence) + * by an offset + * @fdta: Addon device tree blob + * @prop_offset: Property to update + * @data_offset: Offset in the property data to update + * @delta: Offset to apply + * + * returns: + * 0 on success. + * Negative error code on error + */ +static int addon_property_add_offset(void *fdta, int prop_offset, + unsigned int data_offset, uint32_t delta) +{ + unsigned int proplen; + char *propval; + uint32_t val; + fdt32_t *p; + int tmp; + + propval =3D fdt_getprop_by_offset_w(fdta, prop_offset, NULL, &tmp); + if (!propval) + return tmp; + + proplen =3D tmp; + if (proplen < data_offset + sizeof(fdt32_t)) + return -FDT_ERR_BADSTRUCTURE; + + /* Get the phandle pointer */ + p =3D (fdt32_t *)(propval + data_offset); + + /* Update the phandle value */ + val =3D fdt32_ld(p); + if (val + delta < val || val + delta =3D=3D (uint32_t)-1) + return -FDT_ERR_NOPHANDLES; + fdt32_st(p, val + delta); + return 0; +} + +/** + * addon_property_set_val - Set a property value (a phandle reference) + * @fdta: Addon device tree blob + * @prop_offset: Property to update + * @data_offset: Offset in the property data to update + * @value: Value to set + * + * returns: + * 0 on success. + * Negative error code on error + */ +static int addon_property_set_val(void *fdta, int prop_offset, + unsigned int data_offset, uint32_t val) +{ + unsigned int proplen; + char *propval; + fdt32_t *p; + int tmp; + + propval =3D fdt_getprop_by_offset_w(fdta, prop_offset, NULL, &tmp); + if (!propval) + return tmp; + + proplen =3D tmp; + if (proplen < data_offset + sizeof(fdt32_t)) + return -FDT_ERR_BADSTRUCTURE; + + /* Get the phandle pointer and update it */ + p =3D (fdt32_t *)(propval + data_offset); + fdt32_st(p, val); + return 0; +} + +/** + * addon_property_replace - Replace a property value (a phandle reference)= if + * the old value matches the current value. + * @fdta: Addon device tree blob + * @prop_offset: Property to update + * @data_offset: Offset in the property data to update + * @old_val: Old value + * @new_val: New value to set if the @old_val matches + * + * returns: + * 0 on success. + * Negative error code on error + */ +static int addon_property_replace(void *fdt, int prop_offset, + unsigned int data_offset, uint32_t old_val, + uint32_t new_val) +{ + unsigned int proplen; + char *propval; + uint32_t val; + fdt32_t *p; + int tmp; + + propval =3D fdt_getprop_by_offset_w(fdt, prop_offset, NULL, &tmp); + if (!propval) + return tmp; + + proplen =3D tmp; + if (proplen < data_offset + sizeof(fdt32_t)) + return -FDT_ERR_BADSTRUCTURE; + + /* Get the phandle pointer */ + p =3D (fdt32_t *)(propval + data_offset); + + val =3D fdt32_ld(p); + if (val =3D=3D old_val) + fdt32_st(p, new_val); + + return 0; +} + +/** + * addon_adjust_local_phandles - Adjust the local phandles of a whole addo= n blob + * @fdta: Addon device tree blob + * @delta: Offset to shift the phandles of + * + * addon_adjust_local_phandles() adds a constant to all the local phandles= of + * an addon. This is mainly use as part of the addon application process, = when + * we want to update all the local phandles of the addon to not conflict w= ith + * phandles of the base device tree. + * + * returns: + * 0 on success + * Negative error code on failure + */ +static int addon_adjust_local_phandles(void *fdta, uint32_t delta) +{ + int offset, next_offset, d; + int last_prop_offset =3D -1; + int prop_phandle_offset; + const fdt32_t *pfdt32; + fdt32_t *pfdt32w; + uint32_t tag; + uint32_t val; + int ret; + + /* + * phandles that need to be updated are: + * - phandles properties in nodes + * - phandles in properties where a FDT_PROPDATA_PHANDLE tag is + * available + * - phandles in FDT_EXPORT_SYM tags + */ + + next_offset =3D 0; + do { + offset =3D next_offset; + tag =3D fdt_next_tag(fdta, offset, &next_offset); + switch (tag) { + case FDT_BEGIN_NODE: + last_prop_offset =3D -1; + + ret =3D addon_phandle_add_offset(fdta, offset, "phandle", delta); + if (ret && ret !=3D -FDT_ERR_NOTFOUND) + return ret; + + ret =3D addon_phandle_add_offset(fdta, offset, "linux,phandle", delta); + if (ret && ret !=3D -FDT_ERR_NOTFOUND) + return ret; + break; + + case FDT_END_NODE: + last_prop_offset =3D -1; + break; + + case FDT_PROP: + last_prop_offset =3D offset; + break; + + case FDT_NOP: + break; + + case FDT_PROPDATA_PHANDLE: + d =3D fdt_get_structured_tag_data(tag, fdta, + offset + FDT_TAGSIZE, NULL); + if (d < 0) + return d; + /* + * The property references a phandle. Get the offset + * of this phandle reference in the property data area. + */ + pfdt32 =3D fdt_offset_ptr(fdta, d, sizeof(*pfdt32)); + prop_phandle_offset =3D fdt32_to_cpu(*pfdt32); + if (prop_phandle_offset % sizeof(fdt32_t)) + return -FDT_ERR_BADVALUE; + + if (last_prop_offset =3D=3D -1) + return -FDT_ERR_BADSTRUCTURE; + + /* Update the phandle reference */ + ret =3D addon_property_add_offset(fdta, last_prop_offset, + prop_phandle_offset, + delta); + if (ret) + return ret; + break; + + case FDT_PROPDATA_PHANDLE_REF: + break; + + case FDT_BEGIN_NODE_REF: + last_prop_offset =3D -1; + break; + + case FDT_END: + ret =3D (next_offset < 0) ? next_offset : 0; + break; + + case FDT_EXPORT_SYM: + d =3D fdt_get_structured_tag_data(tag, fdta, + offset + FDT_TAGSIZE, NULL); + if (d < 0) + return d; + + /* Get phandle pointer */ + pfdt32w =3D fdt_offset_ptr_w(fdta, d, sizeof(*pfdt32)); + + /* Update the phandle value */ + val =3D fdt32_ld(pfdt32w); + if (val + delta < val || val + delta =3D=3D (uint32_t)-1) + return -FDT_ERR_NOPHANDLES; + + fdt32_st(pfdt32w, val + delta); + break; + + case FDT_EXPORT_SYM_REF: + break; + case FDT_IMPORT_SYM: + break; + + default: + return -FDT_ERR_BADSTRUCTURE; + } + } while (tag !=3D FDT_END); + + return ret; +} + +static int fdt_check_exportsym_offset(const void *fdt, int offset, + uint32_t *exportsym_tag, int *data_offset) +{ + int nextoffset, d; + uint32_t tag; + + tag =3D fdt_next_tag(fdt, offset, &nextoffset); + switch (tag) { + case FDT_EXPORT_SYM: + case FDT_EXPORT_SYM_REF: + if (data_offset) { + d =3D fdt_get_structured_tag_data(tag, fdt, + offset + FDT_TAGSIZE, + NULL); + if (d < 0) + return d; + *data_offset =3D d; + } + break; + default: + return -FDT_ERR_BADOFFSET; + } + + if (exportsym_tag) + *exportsym_tag =3D tag; + + return nextoffset; +} + +static int fdt_next_exportsym_nextoffset_(const void *fdt, int nextoffset) +{ + uint32_t tag; + int offset; + + do { + offset =3D nextoffset; + tag =3D fdt_next_tag(fdt, offset, &nextoffset); + switch (tag) { + case FDT_EXPORT_SYM: + return offset; + + case FDT_EXPORT_SYM_REF: + return offset; + + case FDT_BEGIN_NODE: + /* We are going to leave the current node (sub-node) */ + return -FDT_ERR_NOTFOUND; + + case FDT_BEGIN_NODE_REF: + /* We cannot have a node ref inside an other node */ + return -FDT_ERR_BADSTRUCTURE; + + case FDT_END_NODE: + /* We are going to leave the current node (parent node) */ + return -FDT_ERR_NOTFOUND; + + case FDT_END: + if (nextoffset < 0) + return nextoffset; + + return -FDT_ERR_NOTFOUND; + } + } while (tag !=3D FDT_END); + + return offset; +} + +static int fdt_next_exportsym_offset(const void *fdt, int offset) +{ + int nextoffset; + + if (offset < 0) + return offset; + + nextoffset =3D fdt_check_exportsym_offset(fdt, offset, NULL, NULL); + if (nextoffset < 0) + return nextoffset; + + return fdt_next_exportsym_nextoffset_(fdt, nextoffset); +} + +static int fdt_first_exportsym_offset(const void *fdt, int node_offset) +{ + int nextoffset; + + if (node_offset < 0) + return node_offset; + + nextoffset =3D fdt_check_node_offset_(fdt, node_offset); + if (nextoffset < 0) + return nextoffset; + + return fdt_next_exportsym_nextoffset_(fdt, nextoffset); +} + +static bool fdt_exportsym_is_ref(const void *fdt, int offset) +{ + uint32_t tag; + + /* A exportsym ref has to be an exportsym ... */ + if (fdt_check_exportsym_offset(fdt, offset, &tag, NULL) < 0) + return false; + + if (tag !=3D FDT_EXPORT_SYM_REF) + return false; + + return true; +} + +static const char *fdt_exportsym_get_name(const void *fdt, int offset) +{ + int data_offset; + uint32_t tag; + + if (fdt_check_exportsym_offset(fdt, offset, &tag, &data_offset) < 0) + return NULL; + + switch (tag) { + case FDT_EXPORT_SYM: + data_offset +=3D FDT_CELLSIZE; /* Skip phandle value */ + break; + + case FDT_EXPORT_SYM_REF: + data_offset =3D fdt_skip_string(fdt, data_offset); /* Skip ref */ + break; + + default: + return NULL; + } + + return fdt_offset_ptr(fdt, data_offset, 1); +} + +static uint32_t fdt_exportsym_get_phandle(const void *fdt, int offset) +{ + const fdt32_t *pfdt32; + int data_offset; + uint32_t tag; + + if (fdt_check_exportsym_offset(fdt, offset, &tag, &data_offset) < 0) + return 0; + + /* Only FDT_EXPORT_SYM tag has a phandle in its data */ + if (tag !=3D FDT_EXPORT_SYM) + return 0; + + pfdt32 =3D fdt_offset_ptr(fdt, data_offset, sizeof(*pfdt32)); + if (!pfdt32) + return 0; + + return fdt32_ld_(pfdt32); +} + +static const char *fdt_exportsym_get_ref(const void *fdt, int offset) +{ + int data_offset; + uint32_t tag; + + if (fdt_check_exportsym_offset(fdt, offset, &tag, &data_offset) < 0) + return NULL; + + /* Only FDT_EXPORT_SYM_REF tag has a ref in its data */ + if (tag !=3D FDT_EXPORT_SYM_REF) + return NULL; + + /* Get the reference */ + return fdt_offset_ptr(fdt, data_offset, 1); +} + +#define fdt_for_each_exportsym(exportsym, fdt, node) \ + for (exportsym =3D fdt_first_exportsym_offset(fdt, node); \ + exportsym >=3D 0; \ + exportsym =3D fdt_next_exportsym_offset(fdt, exportsym)) + +/** + * fdt_resolve_symbol - Resolve a symbol + * @fdt: base device tree blob + * @target_node: Target node offset in the base device tree blob containing + * the exported symbols used for the resolution. + * @sym_name: Symbol name + * @sym_namelen: Length of the symbol name + * + * fdt_resolve_symbol() searches for a matching export symbol exported by = the + * @target_node. It returns the node offset in @fdt referenced by the matc= hing + * export symbol. + * + * returns: + * offset of the node matching the symbol after the resolution on suc= cess. + * Negative error code on failure + */ +static int fdt_resolve_symbol(const void *fdt, int target_node, + const char *sym_name, size_t sym_namelen) +{ + const char *exportsym_name; + uint32_t phandle; + int exportsym; + int ref_node; + + /* Look at export available at the target node */ + fdt_for_each_exportsym(exportsym, fdt, target_node) { + + /* + * Export symbols at target node cannot be reference ones. + * Indeed, those export symbols are all resolved symbols. They + * must point to a local node using a valid phandle. + */ + if (fdt_exportsym_is_ref(fdt, exportsym)) + return -FDT_ERR_BADSTRUCTURE; + + exportsym_name =3D fdt_exportsym_get_name(fdt, exportsym); + if (!exportsym_name) + return -FDT_ERR_BADSTRUCTURE; + + phandle =3D fdt_exportsym_get_phandle(fdt, exportsym); + if ((phandle =3D=3D 0) || (phandle =3D=3D ~0U)) + return -FDT_ERR_BADPHANDLE; + + if ((strlen(exportsym_name) !=3D sym_namelen) || + (memcmp(exportsym_name, sym_name, sym_namelen) !=3D 0)) + continue; + + ref_node =3D fdt_node_offset_by_phandle(fdt, phandle); + if (ref_node < 0) + return -FDT_ERR_NOTFOUND; + + return ref_node; + } + + return -FDT_ERR_NOTFOUND; +} + +/** + * fdt_resolve_import - Resolve an imported symbol + * @fdt: base device tree blob + * @target_node: Target node offset in the base device tree blob containing + * the exported symbols used for the resolution. + * @importsym_name: Import symbol name + * @importsym_compatible: Import symbol compatible string + * + * returns: + * offset of the node matching the symbol after the resolution on suc= cess. + * Negative error code on failure. + */ +static int fdt_resolve_import(const void *fdt, int target_node, + const char *importsym_name, + const char *importsym_compatible) +{ + /* + * Do not check the import symbol compatible string against the found + * node. Indeed, the found node can be a node without any compatible + * string and this is perfectly legit. + * + * The purpose of the import symbol compatible string is to give + * information related to the symbol imported. + * + * This can be use by a driver when it wants to dynamically resolve + * imported symbols based on some specific criteria. In that case, the + * compatible string helps the driver to identify the kind of symbol + * expected by the addon. + * + * Here, in libfdt, no driver are available to perform this dynamic + * resolution. Resolve the symbol using only its name. + */ + return fdt_resolve_symbol(fdt, target_node, importsym_name, + strlen(importsym_name)); +} + +static int fdt_check_importsym_offset(const void *fdt, int offset, int *da= ta_offset) +{ + int nextoffset, d; + uint32_t tag; + + tag =3D fdt_next_tag(fdt, offset, &nextoffset); + switch (tag) { + case FDT_IMPORT_SYM: + if (data_offset) { + d =3D fdt_get_structured_tag_data(tag, fdt, + offset + FDT_TAGSIZE, + NULL); + if (d < 0) + return d; + *data_offset =3D d; + } + break; + default: + return -FDT_ERR_BADOFFSET; + } + + return nextoffset; +} + +static int fdt_next_importsym_nextoffset_(const void *fdt, int nextoffset) +{ + uint32_t tag; + int offset; + + do { + offset =3D nextoffset; + tag =3D fdt_next_tag(fdt, offset, &nextoffset); + + switch (tag) { + case FDT_IMPORT_SYM: + return offset; + + case FDT_END: + if (nextoffset < 0) + return nextoffset; + + return -FDT_ERR_NOTFOUND; + } + } while (tag !=3D FDT_IMPORT_SYM); + + return offset; +} + +static int fdt_next_importsym_offset(const void *fdt, int offset) +{ + int nextoffset; + + if (offset < 0) + return offset; + + nextoffset =3D fdt_check_importsym_offset(fdt, offset, NULL); + if (nextoffset < 0) + return nextoffset; + + return fdt_next_importsym_nextoffset_(fdt, nextoffset); +} + +static int fdt_first_importsym_offset(const void *fdt) +{ + return fdt_next_importsym_nextoffset_(fdt, 0); +} + + +static const char *fdt_importsym_get_name(const void *fdt, int offset) +{ + int data_offset; + + if (fdt_check_importsym_offset(fdt, offset, &data_offset) < 0) + return NULL; + + return fdt_offset_ptr(fdt, data_offset, 1); +} + +static const char *fdt_importsym_get_compatible(const void *fdt, int offse= t) +{ + int data_offset; + + if (fdt_check_importsym_offset(fdt, offset, &data_offset) < 0) + return NULL; + + /* Skip name */ + data_offset =3D fdt_skip_string(fdt, data_offset); + + return fdt_offset_ptr(fdt, data_offset, 1); +} + +#define fdt_for_each_importsym(importsym, fdt) \ + for (importsym =3D fdt_first_importsym_offset(fdt); \ + importsym >=3D 0; \ + importsym =3D fdt_next_importsym_offset(fdt, importsym)) + +/** + * addon_resolve_symbol - Resolve a symbol from an addon + * @fdta: Addon device tree blob. + * @fdt: base device tree blob + * @target_node: Target node the addon is applied to. This node, in the ba= se + * device tree blob, must have exported symbols needed for t= he + * resolution. + * @sym_name: Symbol name + * @sym_namelen: Length of the symbol name + * + * addon_resolve_symbol() resolved a symbol used by an addon using the imp= ort + * symbol table available in the addon device tree blob. + * + * returns: + * offset (in the fdt device tree blob) of the node matching the symb= ol + * after the resolution on success. + * Negative error code on failure. + */ +static int addon_resolve_symbol(const void *fdta, const void *fdt, int tar= get_node, + const char *sym_name, size_t sym_namelen) +{ + const char *importsym_compat; + const char *importsym_name; + int importsym; + + /* Look at imported symbols */ + fdt_for_each_importsym(importsym, fdta) { + importsym_name =3D fdt_importsym_get_name(fdta, importsym); + if (!importsym_name) + return -FDT_ERR_BADSTRUCTURE; + importsym_compat =3D fdt_importsym_get_compatible(fdta, importsym); + if (!importsym_compat) + return -FDT_ERR_BADSTRUCTURE; + + if ((strlen(importsym_name) !=3D sym_namelen) || + (memcmp(importsym_name, sym_name, sym_namelen) !=3D 0)) + continue; + + return fdt_resolve_import(fdt, target_node, importsym_name, + importsym_compat); + } + /* Not found ... */ + return -FDT_ERR_NOTFOUND; +} + +/** + * addon_resolve_ref - Resolve a reference from an addon + * @fdta: Addon device tree blob. + * @fdt: base device tree blob + * @target_node: Target node the addon is applied to. This node, in the ba= se + * device tree blob, must have exported symbols needed for t= he + * resolution. + * @ref: The reference to resolve + * + * addon_resolve_ref() resolves a reference used by an addon. + * A reference can be composed of several symbols separated by a '.' char. + * For instance "foo.bar.baz". To resolve this reference, addon_resolve_re= f() + * resolves the "foo" symbol the based on node retrieve from this resoluti= on, + * it resolves "bar" and so on up to the last symbol available on the refe= rence. + * + * This last symbol resolution leads to the node offset returned by + * addon_resolve_ref(). + * + * returns: + * offset (in the fdt device tree blob) of the node matching the refe= rence + * after the resolution on success. + * Negative error code on failure. + */ +static int addon_resolve_ref(const void *fdta, const void *fdt, int target= _node, + const char *ref) +{ + const char *end =3D ref + strlen(ref); + const char *r =3D ref; + const char *d; + int tmp_node; + + /* + * A reference can be "foo.bar.baz" for instance. + * In that case, we need to resolve foo from the target_node exported + * symbols then bar from exported symbols defined in the node retrieve + * from foo resolution and so on to resolve the given reference. + * + * The first symbol (foo in the previous example reference) need to be + * resolved through import symbols to "jump" from the addon to the base + * device tree. The other ones are "jumps" in the base device tree + * without leaving it and so, import symbols are not involved for them. + */ + tmp_node =3D target_node; + while (r < end) { + d =3D memchr(r, '.', end - r); + if (!d) + d =3D end; + + if (r =3D=3D ref) + tmp_node =3D addon_resolve_symbol(fdta, fdt, tmp_node, r, d-r); + else + tmp_node =3D fdt_resolve_symbol(fdt, tmp_node, r, d-r); + + if (tmp_node < 0) + return tmp_node; + + r =3D d + 1; + } + + return tmp_node; +} + +/** + * addon_resolve_phandles - Resolve addon external references + * @fdta: Addon device tree blob + * @fdt: Device tree blob the addon is going to be applied to + * @target_node: Offset of the node in fdt the addon is going to be applie= d to + * + * addon_resolve_phandles() resolved unresolved phandle symbols available = in + * the addon. + * + * returns: + * 0 on success + * Negative error code on failure + */ +static int addon_resolve_phandles(void *fdta, const void *fdt, int target_= node) +{ + int offset, next_offset, d; + int last_prop_offset =3D -1; + int prop_phandle_offset; + const fdt32_t *pfdt32; + uint32_t phandle; + const char *ref; + uint32_t tag; + int ref_node; + int ret; + + /* + * phandles symbols that need to be resolved are: + * - reference in properties where a FDT_PROPDATA_PHANDLE_REF tag is + * available + * - reference in export symbols + */ + + next_offset =3D 0; + do { + offset =3D next_offset; + tag =3D fdt_next_tag(fdta, offset, &next_offset); + switch (tag) { + case FDT_BEGIN_NODE: + last_prop_offset =3D -1; + break; + + case FDT_END_NODE: + last_prop_offset =3D -1; + break; + + case FDT_PROP: + last_prop_offset =3D offset; + break; + + case FDT_NOP: + break; + + case FDT_PROPDATA_PHANDLE: + break; + + case FDT_PROPDATA_PHANDLE_REF: + /* + * A property references an unresolved phandle. Get + * the offset of this phandle in the property data area + * and the reference of the phandle + */ + d =3D fdt_get_structured_tag_data(tag, fdta, + offset + FDT_TAGSIZE, NULL); + if (d < 0) + return d; + + pfdt32 =3D fdt_offset_ptr(fdta, d, sizeof(*pfdt32)); + prop_phandle_offset =3D fdt32_to_cpu(*pfdt32); + + d +=3D sizeof(*pfdt32); + ref =3D fdt_offset_ptr(fdta, d, 1); + + /* Resolve this phandle */ + ref_node =3D addon_resolve_ref(fdta, fdt, target_node, ref); + if (ref_node < 0) + return ref_node; + + phandle =3D fdt_get_phandle(fdt, ref_node); + if ((phandle =3D=3D 0) || (phandle =3D=3D ~0U)) + return -FDT_ERR_BADPHANDLE; + + if (last_prop_offset =3D=3D -1) + return -FDT_ERR_BADSTRUCTURE; + + /* Update property value */ + ret =3D addon_property_set_val(fdta, last_prop_offset, + prop_phandle_offset, + phandle); + if (ret) + return ret; + + break; + + case FDT_BEGIN_NODE_REF: + last_prop_offset =3D -1; + break; + + case FDT_END: + ret =3D (next_offset < 0) ? next_offset : 0; + break; + + case FDT_EXPORT_SYM: + break; + + case FDT_EXPORT_SYM_REF: + d =3D fdt_get_structured_tag_data(tag, fdta, + offset + FDT_TAGSIZE, NULL); + if (d < 0) + return d; + + /* + * The export symbol references an unresolved phandle. + * Check that this reference can be resolved correctly. + * Even if there is no simple way to store the resolved + * phandle (resolution will be done again later when + * those export symbols are merged in the base device + * tree), it is consistent to check this resolution now + * in this function. + */ + + /* Get the reference */ + ref =3D fdt_offset_ptr(fdta, d, 1); + + /* Resolve the phandle */ + ref_node =3D addon_resolve_ref(fdta, fdt, target_node, ref); + if (ref_node < 0) + return ref_node; + + phandle =3D fdt_get_phandle(fdt, ref_node); + if ((phandle =3D=3D 0) || (phandle =3D=3D ~0U)) + return -FDT_ERR_BADPHANDLE; + + break; + + case FDT_IMPORT_SYM: + break; + + default: + return -FDT_ERR_BADSTRUCTURE; + } + } while (tag !=3D FDT_END); + + return ret; +} + +/** + * addon_replace_local_phandles - Replace the old value of phandles by a n= ew one + * for a whole addon + * @fdta: Device tree addon blob + * @old_phandle: Old phandle value + * @new_phandle: New phandle value + * + * addon_replace_local_phandles() replaces phandle values only if the + * old_phandle_value matches the current phandle value. + * + * returns: + * 0 on success + * Negative error code on failure + */ +static int addon_replace_local_phandles(void *fdta, uint32_t old_phandle, + uint32_t new_phandle) +{ + int offset, next_offset, d; + int last_prop_offset =3D -1; + int prop_phandle_offset; + const fdt32_t *pfdt32; + fdt32_t *pfdt32w; + uint32_t tag; + uint32_t val; + int ret; + + /* + * phandles that need to be updated are: + * - phandles in properties where a FDT_PROPDATA_PHANDLE tag is + * available + * - phandles in FDT_EXPORT_SYM tags + * + * phandles properties in nodes are replace by + * addon_prevent_phandle_overwrite_node() + */ + + next_offset =3D 0; + do { + offset =3D next_offset; + tag =3D fdt_next_tag(fdta, offset, &next_offset); + switch (tag) { + case FDT_BEGIN_NODE: + /* + * "phandle" and/of "linux,phandle" properties are + * already updated by addon_prevent_phandle_overwrite_node() + * Nothing more to update here. + */ + last_prop_offset =3D -1; + break; + + case FDT_END_NODE: + last_prop_offset =3D -1; + break; + + case FDT_PROP: + last_prop_offset =3D offset; + break; + + case FDT_NOP: + break; + + case FDT_PROPDATA_PHANDLE: + /* + * The property references a phandle. Get the offset + * of this phandle in the property data area. + */ + d =3D fdt_get_structured_tag_data(tag, fdta, + offset + FDT_TAGSIZE, NULL); + if (d < 0) + return d; + + pfdt32 =3D fdt_offset_ptr(fdta, d, sizeof(*pfdt32)); + prop_phandle_offset =3D fdt32_to_cpu(*pfdt32); + + if (last_prop_offset =3D=3D -1) + return -FDT_ERR_BADSTRUCTURE; + + /* Update the phandle value */ + ret =3D addon_property_replace(fdta, last_prop_offset, + prop_phandle_offset, + old_phandle, new_phandle); + if (ret) + return ret; + break; + + case FDT_PROPDATA_PHANDLE_REF: + break; + + case FDT_BEGIN_NODE_REF: + last_prop_offset =3D -1; + break; + + case FDT_END: + ret =3D (next_offset < 0) ? next_offset : 0; + break; + + case FDT_EXPORT_SYM: + d =3D fdt_get_structured_tag_data(tag, fdta, + offset + FDT_TAGSIZE, NULL); + if (d < 0) + return d; + + /* Get phandle pointer */ + pfdt32w =3D fdt_offset_ptr_w(fdta, d, sizeof(*pfdt32)); + + /* Update the phandle value */ + val =3D fdt32_ld(pfdt32w); + if (val =3D=3D old_phandle) + fdt32_st(pfdt32w, new_phandle); + break; + + case FDT_EXPORT_SYM_REF: + break; + case FDT_IMPORT_SYM: + break; + + default: + return -FDT_ERR_BADSTRUCTURE; + } + } while (tag !=3D FDT_END); + + return ret; +} + +/** + * addon_prevent_phandle_overwrite_node - Prevents phandle overwrite for a= given + * addon node. + * @fdta: Addon Device tree blob + * @fdta_node: Node in fdta + * @fdt: Base device tree blob + * @fdt_node: Node in fdt that could be overwrite by the fdta_node + * + * returns: + * 0 on success + * Negative error code on failure + */ +static int addon_prevent_phandle_overwrite_node(void *fdta, int fdta_node, + const void *fdt, int fdt_node) +{ + uint32_t fdta_phandle, fdt_phandle; + int fdta_child, fdt_child; + const char *name; + int ret; + + fdta_phandle =3D fdt_get_phandle(fdta, fdta_node); + fdt_phandle =3D fdt_get_phandle(fdt, fdt_node); + + if (fdta_phandle && fdt_phandle) { + ret =3D addon_phandle_set_val(fdta, fdta_node, "phandle", fdt_phandle); + if (ret && ret !=3D -FDT_ERR_NOTFOUND) + return ret; + + ret =3D addon_phandle_set_val(fdta, fdta_node, "linux,phandle", fdt_phan= dle); + if (ret && ret !=3D -FDT_ERR_NOTFOUND) + return ret; + + ret =3D addon_replace_local_phandles(fdta, fdta_phandle, fdt_phandle); + if (ret) + return ret; + } + + fdt_for_each_subnode(fdta_child, fdta, fdta_node) { + name =3D fdt_get_name(fdta, fdta_child, NULL); + if (!name) + return -FDT_ERR_BADSTRUCTURE; + + fdt_child =3D fdt_subnode_offset(fdt, fdt_node, name); + if (fdt_child =3D=3D -FDT_ERR_NOTFOUND) { + /* + * No further overwrites possible here as the addon node + * is new node. + */ + continue; + } + + ret =3D addon_prevent_phandle_overwrite_node(fdta, fdta_child, + fdt, fdt_child); + if (ret) + return ret; + } + + return 0; +} + +static const char *fdt_orphan_get_ref(const void *fdt, int offset) +{ + int data_offset; + + if (fdt_check_orphan_offset(fdt, offset, &data_offset) < 0) + return NULL; + + return fdt_offset_ptr(fdt, data_offset, 1); +} + +/** + * addon_prevent_phandles_overwrite - Fixes addon phandles to not overwrit= e base + * phandles + * @fdta Addon Device tree blob + * @fdt: Base Device Tree blob + * @target_node: Target node in the base device tree the addon is going to= be + * applied to + * + * Checks recursively if applying fdta overwrites phandle values in the ba= se + * fdt. When such a phandle is found, the fdta is changed to use the fdt's + * phandle value to not break references in the base. + * + * returns: + * 0 on success + * Negative error code on failure + */ +static int addon_prevent_phandles_overwrite(void *fdta, const void *fdt, + int target_node) +{ + int fdt_orphan_target; + int addon_root_node; + const char *ref; + int fdta_orphan; + int ret; + + addon_root_node =3D fdt_root_offset(fdta); + if (addon_root_node < 0 && addon_root_node !=3D -FDT_ERR_NOTFOUND) + return addon_root_node; + + if (addon_root_node >=3D 0) { + ret =3D addon_prevent_phandle_overwrite_node(fdta, addon_root_node, + fdt, target_node); + if (ret < 0) + return ret; + } + + fdt_for_each_orphan(fdta_orphan, fdta) { + ref =3D fdt_orphan_get_ref(fdta, fdta_orphan); + if (!ref) + return -FDT_ERR_BADSTRUCTURE; + + fdt_orphan_target =3D addon_resolve_ref(fdta, fdt, target_node, ref); + if (fdt_orphan_target < 0) + return fdt_orphan_target; + + ret =3D addon_prevent_phandle_overwrite_node(fdta, fdta_orphan, + fdt, fdt_orphan_target); + if (ret < 0) + return ret; + } + + return 0; +} + +static int fdt_check_propmarker_offset(const void *fdt, int offset, + uint32_t *propmarker_tag, int *data_offset) +{ + int nextoffset, d; + uint32_t tag; + + tag =3D fdt_next_tag(fdt, offset, &nextoffset); + switch (tag) { + case FDT_PROPDATA_PHANDLE: + case FDT_PROPDATA_PHANDLE_REF: + if (data_offset) { + d =3D fdt_get_structured_tag_data(tag, fdt, + offset + FDT_TAGSIZE, + NULL); + if (d < 0) + return d; + *data_offset =3D d; + } + break; + default: + return -FDT_ERR_BADOFFSET; + } + + if (propmarker_tag) + *propmarker_tag =3D tag; + + return nextoffset; +} + +static int fdt_next_propmarker_nextoffset_(const void *fdt, int nextoffset) +{ + uint32_t tag; + int offset; + + do { + offset =3D nextoffset; + tag =3D fdt_next_tag(fdt, offset, &nextoffset); + switch (tag) { + case FDT_EXPORT_SYM: + /* We are going to leave the current property (enter an export symbol) = */ + return -FDT_ERR_NOTFOUND; + + case FDT_EXPORT_SYM_REF: + /* We are going to leave the current property (enter an export symbol) = */ + return -FDT_ERR_NOTFOUND; + + case FDT_BEGIN_NODE: + /* We are going to leave the current property (new sub-node) */ + return -FDT_ERR_NOTFOUND; + + case FDT_BEGIN_NODE_REF: + /* We cannot have a node ref inside an other node */ + return -FDT_ERR_BADSTRUCTURE; + + case FDT_END_NODE: + /* We are going to leave the current node (parent node) */ + return -FDT_ERR_NOTFOUND; + + case FDT_PROP: + /* We are going to leave the current property (enter a new property) */ + return -FDT_ERR_NOTFOUND; + + case FDT_PROPDATA_PHANDLE: + return offset; + + case FDT_PROPDATA_PHANDLE_REF: + return offset; + + case FDT_END: + if (nextoffset < 0) + return nextoffset; + + return -FDT_ERR_NOTFOUND; + } + } while (tag !=3D FDT_END); + + return offset; +} + +static int fdt_next_propmarker_offset(const void *fdt, int offset) +{ + int nextoffset; + + if (offset < 0) + return offset; + + nextoffset =3D fdt_check_propmarker_offset(fdt, offset, NULL, NULL); + if (nextoffset < 0) + return nextoffset; + + return fdt_next_propmarker_nextoffset_(fdt, nextoffset); +} + +static int fdt_first_propmarker_offset(const void *fdt, int prop_offset) +{ + int nextoffset; + + if (prop_offset < 0) + return prop_offset; + + nextoffset =3D fdt_check_prop_offset_(fdt, prop_offset); + if (nextoffset < 0) + return nextoffset; + + return fdt_next_propmarker_nextoffset_(fdt, nextoffset); + +} + +static int fdt_propmarker_is_phandle(const void *fdt, int offset) +{ + uint32_t tag; + + /* + * Only property 'phandle' markers are currently supported but well, + * prevent some issue that would happen if some other markers are + * added in the future. + */ + + /* A propmarker phandle has to be propmarker ... */ + if (fdt_check_propmarker_offset(fdt, offset, &tag, NULL) < 0) + return false; + + /* ... and a 'phandle' */ + if ((tag !=3D FDT_PROPDATA_PHANDLE) && (tag !=3D FDT_PROPDATA_PHANDLE_REF= )) + return false; + + return true; +} + +static uint32_t fdt_propmarker_phandle_get_propoffset(const void *fdt, + int offset) +{ + const fdt32_t *pfdt32; + int data_offset; + + if (fdt_check_propmarker_offset(fdt, offset, NULL, &data_offset) < 0) + return ~0U; + + pfdt32 =3D fdt_offset_ptr(fdt, data_offset, sizeof(*pfdt32)); + if (!pfdt32) + return ~0U; + + return fdt32_ld_(pfdt32); +} + +#define fdt_for_each_propmarker(propmarker, fdt, prop) \ + for (propmarker =3D fdt_first_propmarker_offset(fdt, prop); \ + propmarker >=3D 0; \ + propmarker =3D fdt_next_propmarker_offset(fdt, propmarker)) + +static int fdt_mark_property_phandle(void *fdt, int fdt_property, + uint32_t propoffset) +{ + int propmarker; + uint32_t tmp; + + fdt_for_each_propmarker(propmarker, fdt, fdt_property) { + if (!fdt_propmarker_is_phandle(fdt, propmarker)) + continue; + + tmp =3D fdt_propmarker_phandle_get_propoffset(fdt, propmarker); + if (tmp =3D=3D ~0U) + return -FDT_ERR_BADSTRUCTURE; + + if (tmp =3D=3D propoffset) + return -FDT_ERR_EXISTS; + } + + return fdt_mark_property_phandle_(fdt, fdt_property, propoffset); +} + +static int fdt_add_exportsym(void *fdt, int fdt_node, + const char *exportsym_name, uint32_t phandle) +{ + const char *tmp; + int exportsym; + + fdt_for_each_exportsym(exportsym, fdt, fdt_node) { + tmp =3D fdt_exportsym_get_name(fdt, exportsym); + if (!tmp) + return -FDT_ERR_BADSTRUCTURE; + + if (!strcmp(tmp, exportsym_name)) + return -FDT_ERR_EXISTS; + } + + return fdt_add_exportsym_(fdt, fdt_node, exportsym_name, phandle); +} + +/** + * addon_merge_node_properties - Merges properties available in an addon n= ode + * into the base device tree node + * @fdta: Addon Device Tree blob + * @fdta_node: Addon node whose properties have to be merged + * @fdt: Base Device Tree blob + * @fdt_node: Base node the addon node properties have to be merged into + * @is_existing_node: True if the node was already existing in the base de= vice + * tree blob. + * + * returns: + * 0 on success + * Negative error code on failure + */ +static int addon_merge_node_properties(const void *fdta, int fdta_node, + void *fdt, int fdt_node, + bool is_existing_node) +{ + const void *prop, *prop2; + int prop_len, prop2_len; + uint32_t propoffset; + int fdta_property; + int fdt_property; + const char *name; + int propmarker; + int ret; + + fdt_for_each_property_offset(fdta_property, fdta, fdta_node) { + prop =3D fdt_getprop_by_offset(fdta, fdta_property, &name, + &prop_len); + if (prop_len =3D=3D -FDT_ERR_NOTFOUND) + return -FDT_ERR_INTERNAL; + if (prop_len < 0) + return prop_len; + + if (is_existing_node) { + if (!strcmp(name, "phandle") || + !strcmp(name, "linux,phandle")) { + /* + * phandles available in both addon and base dtb + * have the same values. This is ensured by + * previous operation related to phandle + * resolution done in addon_prevent_phandles_overwrite(). + * Just skip the property merge. + */ + continue; + } + + /* + * It is not allowed to add or modify a property in an + * existing node. + */ + prop2 =3D fdt_getprop(fdt, fdt_node, name, &prop2_len); + if (prop2_len =3D=3D -FDT_ERR_NOTFOUND) + return -FDT_ERR_EXISTS; /* Cannot add a property */ + if (prop2_len < 0) + return prop2_len; + + if (prop_len !=3D prop2_len) + return -FDT_ERR_EXISTS; /* Cannot modify a property */ + + if (memcmp(prop, prop2, prop_len) !=3D 0) + return -FDT_ERR_EXISTS; /* Cannot modify a property */ + + /* + * The property is already present but it has the exact + * same value. Ok, just skip the property merge. + */ + continue; + } + + ret =3D fdt_setprop(fdt, fdt_node, name, prop, prop_len); + if (ret) + return ret; + + /* Retrieve the newly created fdt property offset */ + fdt_property =3D fdt_getprop_offset(fdt, fdt_node, name); + if (fdt_property < 0) + return -FDT_ERR_INTERNAL; + + fdt_for_each_propmarker(propmarker, fdta, fdta_property) { + if (!fdt_propmarker_is_phandle(fdta, propmarker)) + continue; + + propoffset =3D fdt_propmarker_phandle_get_propoffset(fdta, + propmarker); + /* + * Mark the property as a local phandle reference. + * Either it was already a local phandle reference in + * the addon or it was an external phandle reference in + * the addon and has been resolved. + * In all cases it is local in the merged device tree + * blob. + */ + ret =3D fdt_mark_property_phandle(fdt, fdt_property, + propoffset); + if (ret) + return ret; + } + } + + return 0; +} + +/** + * addon_merge_node_exports - Merges exported symbols in an addon node + * into the base device tree node + * @fdta: Addon Device Tree blob + * @fdta_node: Addon node whose exported symbols have to be merged + * @fdt: Base Device Tree blob + * @fdt_node: Base node the addon node exported symbols have to be merged = into + * @is_existing_node: True if the node was already existing in the base de= vice + * tree blob. + * @target_path: Path in the base Device Tree to the node where the addon = is + * applied to. This is the node where export symbols used for symbol + * resolution are present. + * + * returns: + * 0 on success + * Negative error code on failure + */ +static int addon_merge_node_exports(const void *fdta, int fdta_node, + void *fdt, int fdt_node, + bool is_existing_node, const char *target_path) +{ + const char *exportsym_name; + const char *exportsym_ref; + uint32_t phandle; + int target_node; + int exportsym; + int ref_node; + int ret; + + fdt_for_each_exportsym(exportsym, fdta, fdta_node) { + + if (is_existing_node) { + /* + * It is not allowed to add or modify export symbols in + * existing nodes. + */ + return -FDT_ERR_EXISTS; + } + + exportsym_name =3D fdt_exportsym_get_name(fdta, exportsym); + if (!exportsym_name) + return -FDT_ERR_BADSTRUCTURE; + + if (fdt_exportsym_is_ref(fdta, exportsym)) { + /* + * The export symbol is a reference one. + * Get the phandle from the node referenced by the + * export symbol reference. + */ + + /* Get the reference */ + exportsym_ref =3D fdt_exportsym_get_ref(fdta, exportsym); + if (!exportsym_ref) + return FDT_ERR_BADSTRUCTURE; + + /* Get the target node */ + target_node =3D fdt_path_offset(fdt, target_path); + if (target_node < 0) + return target_node; + + /* Resolve the reference */ + ref_node =3D addon_resolve_ref(fdta, fdt, target_node, exportsym_ref); + if (ref_node < 0) + return ref_node; + + /* Finally get the phandle */ + phandle =3D fdt_get_phandle(fdt, ref_node); + } else { + /* + * The export symbol is not a reference one. + * Get directly the phandle attached the symbol. + */ + phandle =3D fdt_exportsym_get_phandle(fdta, exportsym); + } + + if ((phandle =3D=3D 0) || (phandle =3D=3D ~0U)) + return -FDT_ERR_BADPHANDLE; + + ret =3D fdt_add_exportsym(fdt, fdt_node, exportsym_name, phandle); + if (ret) + return ret; + } + + return 0; +} + +/** + * addon_merge_node - Merges an addon node and its sub-nodes into the base + * device tree + * @fdta: Addon Device Tree blob + * @fdta_node: Addon node to be merged + * @fdt: Base Device Tree blob + * @fdt_node: Base node the addon node has to be merged into + * @is_existing_node: Flag set to true if the node already exist in the Ba= se + * Device Tree blob + * @target_path: Path in the base Device Tree to the node where the addon = is + * applied to. This is the node where export symbols used for symbol + * resolution are present. + * + * returns: + * 0 on success + * Negative error code on failure + */ +static int addon_merge_node(const void *fdta, int fdta_node, void *fdt, + int fdt_node, bool is_existing_node, + const char *target_path) +{ + bool is_existing; + int fdta_subnode; + const char *name; + int fdt_subnode; + int ret; + + ret =3D addon_merge_node_exports(fdta, fdta_node, fdt, fdt_node, + is_existing_node, target_path); + if (ret) + return ret; + + ret =3D addon_merge_node_properties(fdta, fdta_node, fdt, fdt_node, + is_existing_node); + if (ret) + return ret; + + fdt_for_each_subnode(fdta_subnode, fdta, fdta_node) { + name =3D fdt_get_name(fdta, fdta_subnode, NULL); + + is_existing =3D false; + fdt_subnode =3D fdt_add_subnode(fdt, fdt_node, name); + if (fdt_subnode =3D=3D -FDT_ERR_EXISTS) { + is_existing =3D true; + fdt_subnode =3D fdt_subnode_offset(fdt, fdt_node, name); + if (fdt_subnode =3D=3D -FDT_ERR_NOTFOUND) + return -FDT_ERR_INTERNAL; + } + + if (fdt_subnode < 0) + return fdt_subnode; + + ret =3D addon_merge_node(fdta, fdta_subnode, fdt, fdt_subnode, + is_existing, target_path); + if (ret) + return ret; + } + + return 0; +} + +static int addon_merge(void *fdta, void *fdt, const char *target_path) +{ + int fdt_orphan_target; + int fdta_orphan; + const char *ref; + int target_node; + int ret; + + /* Get the target node from its path */ + target_node =3D fdt_path_offset(fdt, target_path); + if (target_node < 0) + return target_node; + + /* Merge the addon root node into the base target_node */ + ret =3D addon_merge_node(fdta, 0, fdt, target_node, true, target_path); + if (ret < 0) + return ret; + + fdt_for_each_orphan(fdta_orphan, fdta) { + ref =3D fdt_orphan_get_ref(fdta, fdta_orphan); + if (!ref) + return -FDT_ERR_BADSTRUCTURE; + + fdt_orphan_target =3D addon_resolve_ref(fdta, fdt, target_node, ref); + if (fdt_orphan_target < 0) + return fdt_orphan_target; + + ret =3D addon_merge_node(fdta, fdta_orphan, fdt, fdt_orphan_target, + true, target_path); + if (ret < 0) + return ret; + + /* + * An orphan node has been merged. The merged node can be + * anywhere in the fdt. Depending on the location of the merged + * node in the fdt, the target node offset can be no longer + * valid. + * + * Reload the offset from the target path to have a valid value. + */ + target_node =3D fdt_path_offset(fdt, target_path); + if (target_node < 0) + return target_node; + } + + return 0; +} + +int fdt_addon_apply(void *fdt, void *fdta, const char *target) +{ + int target_node; + uint32_t delta; + int ret; + + FDT_RO_PROBE(fdt); + FDT_RO_PROBE(fdta); + + /* Get the target node */ + target_node =3D fdt_path_offset(fdt, target); + if (target_node < 0) + return target_node; + + ret =3D fdt_find_max_phandle(fdt, &delta); + if (ret) + return ret; + + /* Increase all phandles in the fdta by delta */ + ret =3D addon_adjust_local_phandles(fdta, delta); + if (ret) + goto err; + + /* Resolve phandles */ + ret =3D addon_resolve_phandles(fdta, fdt, target_node); + if (ret < 0) + goto err; + + /* Don't overwrite phandles in fdt */ + ret =3D addon_prevent_phandles_overwrite(fdta, fdt, target_node); + if (ret < 0) + goto err; + + ret =3D addon_merge(fdta, fdt, target); + if (ret < 0) + goto err; + + /* The addon has been damaged, erase its magic */ + fdt_set_magic(fdta, ~0); + + return 0; + +err: + /* The addon might have been damaged, erase its magic */ + fdt_set_magic(fdta, ~0); + + /* The base device tree might have been damaged, erase its magic */ + fdt_set_magic(fdt, ~0); + + return ret; +} diff --git a/libfdt/fdt_rw.c b/libfdt/fdt_rw.c index 30f3da40..e0c01af5 100644 --- a/libfdt/fdt_rw.c +++ b/libfdt/fdt_rw.c @@ -553,6 +553,75 @@ int fdt_delprop(void *fdt, int nodeoffset, const char = *name) return fdt_splice_struct_(fdt, prop, proplen, 0); } =20 +int fdt_mark_property_phandle_(void *fdt, int fdt_property, uint32_t propo= ffset) +{ + fdt32_t *markerp; + int nextoffset; + int err; + + FDT_RW_PROBE(fdt); + + nextoffset =3D fdt_check_prop_offset_(fdt, fdt_property); + if (nextoffset < 0) + return nextoffset; + + /* Insert the marker at next_offset, i.e. right after the property */ + markerp =3D fdt_offset_ptr_w_(fdt, nextoffset); + err =3D fdt_splice_struct_(fdt, markerp, 0, FDT_TAGSIZE + FDT_CELLSIZE); + if (err) + return err; + + *(markerp++) =3D cpu_to_fdt32(FDT_PROPDATA_PHANDLE); + *markerp =3D cpu_to_fdt32(propoffset); + + return 0; +} + +int fdt_add_exportsym_(void *fdt, int nodeoffset, const char *name, + uint32_t phandle) +{ + int namelen, exportlen, datalen; + int nextoffset; + char *p; + int err; + + FDT_RW_PROBE(fdt); + + nextoffset =3D fdt_check_node_offset_(fdt, nodeoffset); + if (nextoffset < 0) + return nextoffset; + + /* + * nextoffset it at the first tag after the node. + * Skip possible unknown tags and metadata tags related to the node in + * order to add the new export sym tag after those tags. + */ + nextoffset =3D fdt_node_skip_unknown_and_metadata_tags(fdt, nextoffset); + if (nextoffset < 0) + return nextoffset; + + + p =3D fdt_offset_ptr_w_(fdt, nextoffset); + namelen =3D strlen(name); + datalen =3D FDT_CELLSIZE + namelen + 1; + exportlen =3D FDT_TAGSIZE + FDT_CELLSIZE + FDT_CELLALIGN(datalen); + + err =3D fdt_splice_struct_(fdt, p, 0, exportlen); + if (err) + return err; + + *((fdt32_t *)p) =3D cpu_to_fdt32(FDT_EXPORT_SYM); + p +=3D FDT_TAGSIZE; + *((fdt32_t *)p) =3D cpu_to_fdt32(datalen); + p +=3D FDT_CELLSIZE; + *((fdt32_t *)p) =3D cpu_to_fdt32(phandle); + p +=3D FDT_CELLSIZE; + memset(p, 0, FDT_CELLALIGN(namelen+1)); + memcpy(p, name, namelen); + + return 0; +} + int fdt_add_subnode_namelen(void *fdt, int parentoffset, const char *name, int namelen) { diff --git a/libfdt/libfdt.h b/libfdt/libfdt.h index ee811266..3ef29beb 100644 --- a/libfdt/libfdt.h +++ b/libfdt/libfdt.h @@ -2538,6 +2538,38 @@ int fdt_overlay_apply(void *fdt, void *fdto); int fdt_overlay_target_offset(const void *fdt, const void *fdto, int fragment_offset, char const **pathp); =20 +/** + * fdt_addon_apply - Applies a DT addon on a base DT + * @fdt: pointer to the base device tree blob + * @fdta: pointer to the device tree addon blob + * @target: target node path + * + * fdt_addon_apply() will apply the given device tree addon on the given t= arget + * node in base device tree. + * + * Expect the base device tree to be modified, even if the function + * returns an error. + * + * returns: + * 0, on success + * -FDT_ERR_NOSPACE, there's not enough space in the base device tree + * -FDT_ERR_NOTFOUND, the overlay points to some nonexistent nodes or + * properties in the base DT + * -FDT_ERR_BADPHANDLE, + * -FDT_ERR_BADOVERLAY, + * -FDT_ERR_NOPHANDLES, + * -FDT_ERR_INTERNAL, + * -FDT_ERR_BADLAYOUT, + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADOFFSET, + * -FDT_ERR_BADPATH, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_TRUNCATED, standard meanings + */ +int fdt_addon_apply(void *fdt, void *fdta, const char *target); + /**********************************************************************/ /* Debugging / informational functions */ /**********************************************************************/ diff --git a/libfdt/libfdt_internal.h b/libfdt/libfdt_internal.h index be47639d..9379a510 100644 --- a/libfdt/libfdt_internal.h +++ b/libfdt/libfdt_internal.h @@ -51,6 +51,11 @@ static inline int fdt_getprop_offset(const void *fdt, in= t nodeoffset, return fdt_getprop_offset_namelen(fdt, nodeoffset, name, strlen(name)); } =20 +int fdt_mark_property_phandle_(void *fdt, int fdt_property, + uint32_t propoffset); +int fdt_add_exportsym_(void *fdt, int nodeoffset, const char *name, + uint32_t phandle); + const char *fdt_find_string_len_(const char *strtab, int tabsize, const ch= ar *s, int s_len); static inline const char *fdt_find_string_(const char *strtab, int tabsize, diff --git a/libfdt/meson.build b/libfdt/meson.build index 68d4c1d1..a6e875f4 100644 --- a/libfdt/meson.build +++ b/libfdt/meson.build @@ -9,6 +9,7 @@ sources =3D files( 'fdt_check.c', 'fdt_empty_tree.c', 'fdt_overlay.c', + 'fdt_addon.c', 'fdt_ro.c', 'fdt_rw.c', 'fdt_strerror.c', diff --git a/libfdt/version.lds b/libfdt/version.lds index d0b71669..74925ac0 100644 --- a/libfdt/version.lds +++ b/libfdt/version.lds @@ -83,6 +83,7 @@ LIBFDT_1.2 { fdt_overlay_target_offset; fdt_get_symbol; fdt_get_symbol_namelen; + fdt_addon_apply; local: *; }; --=20 2.55.0 From nobody Mon Sep 28 04:49:03 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7A3953DAAA9; Wed, 26 Aug 2026 09:53:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738035; cv=none; b=bV43YIPqJoHEvWmymWIyTx4nWg7SORyjpEWUdvyQ3WxMmWBfiivQ6Y2K5ZbRCMXl0R3xe94InGYAPvUQirr6DkE4LNkgY266EWCtOmslLJd3/gTP+9JEcesHQRAke/WdDUsrE5dCe+rjXZd6LBNTmcuKt84gra4IGkrZtnDPcvY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738035; c=relaxed/simple; bh=rVP9lH04r7+ZI+x7f09H/c8hrugI0UMNoajcpdk0xQ0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=l79TRz7x/RcUa8PKRIroCR5Gbl9px9j5q0Eo9mdAqS6DBgXkZqrfnPicoyFmiXtvMsQQvPFRkzuB9S09ojbQ6y7HG+m+mfAmPE0V16HK7RTA/jVZtGlfJpTVRhWJ2WszfrPFTQ06aUVgOkWbNWc4213Erl6GVRfKuEKGv2DiqdE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=YAmGzPvX; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="YAmGzPvX" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id E9DF71A0E1B; Wed, 26 Aug 2026 09:53:51 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id BDA9F604EC; Wed, 26 Aug 2026 09:53:51 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id E138C11C7ACD5; Wed, 26 Aug 2026 11:53:48 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787738030; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=n163j0JJkv2/HlZShFYjce2tC1Ng0Jua0VmfrejqQXo=; b=YAmGzPvX7AOikBOwdti5tC2ta7wkclHFNz6EjYDVU7d8B7aqhQQ8P3SyX8HT0zUFC/7qyj 2CcWwdBZqFuNg9KsNt0ifORKUYlbtyfoCASwtLiFxfWpQShfPNygMxFk45bpzYUeoImZvu eF+PeiTAZdGS4DW8ULYj01T+oBEaJdEBks+4KMNEXjF9Y5se3iHFffZEHDMVj6TIj3ZkoP Z75sUN7kczUvbBFfChdrmUw0tF58Ad/wFZS8bBbxiuvlW3eCS2/jRJzu+9FA8LteOkIgJN Z5CVMaXoUth9qyi6xoh7fEOeUmTl+sejsbs3jW+hOz0yCCZKiA4CkMnzz3w6Qw== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 64/74] Add fdtaddon tool to apply an addon Date: Wed, 26 Aug 2026 11:49:33 +0200 Message-ID: <20260826094950.1088288-65-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" libfdt has support for applying an addon on top of a base device-tree. This is provided by the libfdt fdt_addon_apply() function. The fdtaddon tool is command line tool which allows to apply addon dtb file to a base device-tree dtb file. It relies on fdt_addon_apply(). Signed-off-by: Herve Codina --- Makefile | 5 ++ Makefile.utils | 6 ++ fdtaddon.c | 197 +++++++++++++++++++++++++++++++++++++++++++++++++ meson.build | 2 +- 4 files changed, 209 insertions(+), 1 deletion(-) create mode 100644 fdtaddon.c diff --git a/Makefile b/Makefile index 9110d177..175c400b 100644 --- a/Makefile +++ b/Makefile @@ -164,6 +164,7 @@ BIN +=3D fdtdump BIN +=3D fdtget BIN +=3D fdtput BIN +=3D fdtoverlay +BIN +=3D fdtaddon =20 SCRIPTS =3D dtdiff =20 @@ -177,6 +178,7 @@ ifneq ($(MAKECMDGOALS),libfdt) -include $(FDTGET_OBJS:%.o=3D%.d) -include $(FDTPUT_OBJS:%.o=3D%.d) -include $(FDTOVERLAY_OBJS:%.o=3D%.d) +-include $(FDTADDON_OBJS:%.o=3D%.d) endif endif =20 @@ -260,6 +262,8 @@ fdtput: $(FDTPUT_OBJS) $(LIBFDT_dep) =20 fdtoverlay: $(FDTOVERLAY_OBJS) $(LIBFDT_dep) =20 +fdtaddon: $(FDTADDON_OBJS) $(LIBFDT_dep) + tags: FORCE rm -f tags find . \( -name tests -type d -prune \) -o \ @@ -277,6 +281,7 @@ TESTS_BIN +=3D fdtput TESTS_BIN +=3D fdtget TESTS_BIN +=3D fdtdump TESTS_BIN +=3D fdtoverlay +TESTS_BIN +=3D fdtaddon =20 ifneq ($(MAKECMDGOALS),libfdt) include tests/Makefile.tests diff --git a/Makefile.utils b/Makefile.utils index 9436b34d..eae9222b 100644 --- a/Makefile.utils +++ b/Makefile.utils @@ -29,3 +29,9 @@ FDTOVERLAY_SRCS =3D \ util.c =20 FDTOVERLAY_OBJS =3D $(FDTOVERLAY_SRCS:%.c=3D%.o) + +FDTADDON_SRCS =3D \ + fdtaddon.c \ + util.c + +FDTADDON_OBJS =3D $(FDTADDON_SRCS:%.c=3D%.o) diff --git a/fdtaddon.c b/fdtaddon.c new file mode 100644 index 00000000..037851d9 --- /dev/null +++ b/fdtaddon.c @@ -0,0 +1,197 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2025 Bootlin. All rights reserved. + * + * Author: + * Herve Codina + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "util.h" + +/* Usage related data. */ +static const char usage_synopsis[] =3D + "apply an addon to a base blob\n" + " fdtaddon "; +static const char usage_short_opts[] =3D "i:o:t:v" USAGE_COMMON_SHORT_OPTS; +static const struct option usage_long_opts[] =3D { + { "input", required_argument, NULL, 'i' }, + { "output", required_argument, NULL, 'o' }, + { "target", required_argument, NULL, 't' }, + { "verbose", no_argument, NULL, 'v' }, + USAGE_COMMON_LONG_OPTS, +}; +static const char *const usage_opts_help[] =3D { "Input base DT blob", + "Output DT blob", "Target node", + "Verbose messages", + USAGE_COMMON_OPTS_HELP }; + +static void *do_apply(void *base, const void *addon, const char *target) +{ + void *tmp_merged; + void *tmp_addon; + size_t max_merged_size; + int ret; + + /* + * We take copies first, because a failed apply can trash + * both the base blob and the overlay. + */ + + /* + * The merged size should not be greater than the sum of the size of + * individual items. + */ + max_merged_size =3D fdt_totalsize(base) + fdt_totalsize(addon); + + tmp_merged =3D xmalloc(max_merged_size); + ret =3D fdt_open_into(base, tmp_merged, max_merged_size); + if (ret) { + fprintf(stderr, + "\nFailed to make temporary copy: %s\n", + fdt_strerror(ret)); + free(tmp_merged); + return NULL; + } + + tmp_addon =3D xmalloc(fdt_totalsize(addon)); + memcpy(tmp_addon, addon, fdt_totalsize(addon)); + + if (!(fdt_dt_flags(tmp_addon) & FDT_FLAG_ADDON)) { + fprintf(stderr, + "\nAddon dtb is not an 'addon'\n"); + goto fail; + } + + ret =3D fdt_addon_apply(tmp_merged, tmp_addon, target); + if (ret) { + fprintf(stderr, "\nFailed to apply %s\n", fdt_strerror(ret)); + goto fail; + } + + free(tmp_addon); + return tmp_merged; + +fail: + free(tmp_merged); + free(tmp_addon); + return NULL; +} + +static int do_fdtaddon(const char *input_filename, const char *output_file= name, + const char *addon_filename, const char *target) +{ + void *base_blob =3D NULL; + void *addon_blob =3D NULL; + void *merged_blob =3D NULL; + size_t base_buflen; + size_t addon_buflen; + int ret =3D -1; + + base_blob =3D utilfdt_read(input_filename, &base_buflen); + if (!base_blob) { + fprintf(stderr, "\nFailed to read '%s'\n", input_filename); + goto out_err; + } + if (fdt_totalsize(base_blob) > base_buflen) { + fprintf(stderr, + "\nBase blob is incomplete (%zu / %"PRIu32" bytes read)\n", + base_buflen, fdt_totalsize(base_blob)); + goto out_err; + } + + addon_blob =3D utilfdt_read(addon_filename, &addon_buflen); + if (!addon_blob) { + fprintf(stderr, "\nFailed to read '%s'\n", addon_filename); + goto out_err; + } + if (fdt_totalsize(addon_blob) > addon_buflen) { + fprintf(stderr, + "\nAddon blob is incomplete (%zu / %"PRIu32" bytes read)\n", + addon_buflen, fdt_totalsize(addon_blob)); + goto out_err; + } + + /* apply the addon */ + merged_blob =3D do_apply(base_blob, addon_blob, target); + if (!merged_blob) + goto out_err; + + fdt_pack(merged_blob); + ret =3D utilfdt_write(output_filename, merged_blob); + if (ret) + fprintf(stderr, "\nFailed to write '%s'\n", output_filename); + +out_err: + free(merged_blob); + free(addon_blob); + free(base_blob); + + return ret; +} + +int main(int argc, char *argv[]) +{ + char *input_filename =3D NULL; + char *output_filename =3D NULL; + char *addon_filename =3D NULL; + const char *target =3D NULL; + int verbose; + int opt; + + while ((opt =3D util_getopt_long()) !=3D EOF) { + switch (opt) { + case_USAGE_COMMON_FLAGS + + case 'i': + input_filename =3D optarg; + break; + case 'o': + output_filename =3D optarg; + break; + case 'v': + verbose =3D 1; + break; + case 't': + target =3D optarg; + break; + } + } + + if (!input_filename) + usage("missing input file"); + + if (!output_filename) + usage("missing output file"); + + if (!target) + usage("missing target"); + + argv +=3D optind; + argc -=3D optind; + + if (argc !=3D 1) + usage("missing addon file"); + + addon_filename =3D argv[0]; + + if (verbose) { + printf("input =3D %s\n", input_filename); + printf("output =3D %s\n", output_filename); + printf("addon =3D %s\n", addon_filename); + } + + if (do_fdtaddon(input_filename, output_filename, addon_filename, target)) + return 1; + + return 0; +} diff --git a/meson.build b/meson.build index 501b706c..7f7e83b4 100644 --- a/meson.build +++ b/meson.build @@ -108,7 +108,7 @@ if get_option('tools') and not wheel_only install: true, ) =20 - foreach e: ['fdtdump', 'fdtget', 'fdtput', 'fdtoverlay'] + foreach e: ['fdtdump', 'fdtget', 'fdtput', 'fdtoverlay', 'fdtaddon'] dtc_tools +=3D executable(e, files(e + '.c'), dependencies: util_dep, = install: true) endforeach =20 --=20 2.55.0 From nobody Mon Sep 28 04:49:03 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9E4FA3BCD27; Wed, 26 Aug 2026 09:53:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738038; cv=none; b=uS+UXRj/HZyQEhaHihlEn33Ue9ntrmLivRr7GPiD0Nlr4+p0cTPGuIZl0EAtxpF93RRf6QhqcxtaTtiBtlQuovnKGCFLzcx/vYtF9E975S0BxEaO8RswjTosJsgN5eLUgDGOM0Ovrm/n+QBuDte8BfMiiefSpRFIqs+xuOGG2tE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738038; c=relaxed/simple; bh=zW+C00oPGGlznz+vbQZbK4mmD8KDpuIYgjGZ+r6+9P8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=IPqzZwjRwAOxl3H86s7vbYnRpaaHHs8Bbcht67rFpiD3uuoEhcrm/aHY+tZBTccOI7lzlC3f2Z+eF41n6JHdpc9phsvZcKSirJPKRNe67x3zRR33c9uy/W5rLB1dDJat+9W12SZM3BdAsOWYbOPOlPD7TbYxP6/CQvqn3aaunFg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=EcZk3DGJ; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="EcZk3DGJ" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 578144E413C1; Wed, 26 Aug 2026 09:53:54 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 24672604EC; Wed, 26 Aug 2026 09:53:54 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 89E7C11C7AD6D; Wed, 26 Aug 2026 11:53:51 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787738033; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=8cMhEqVQh2DycY88vB1DpGb7R/2IixVPGtElx+1YGBA=; b=EcZk3DGJT53ajfsSDrSXalR0EKKeFxCvSnq0VmvrsSdmOl5sgK0G4a0h08kSwJ+PKKuc2K MGg3W1i3ZLMr7LEBd3NRR8gxbHNZWHlSggjXYYUgFFIjlMOP+WqngXXQXEbb+mxtShQotr mjL+31vbTMpDSMIBrXe5iH4zzCZEeqdMhBQ6KOxx5ysc/LlEYUDga9mk32nVhPgcfZBCo6 eNTifKnM4/g1WNqoBLLG6QCn7SrOYsimJ4JQma/GaPBkIv2PqOfn7OFuK2czoPFNRQcoQ1 xAVuKhgwodiQV4NP1wwtLGnNs327Viyu3fZU1kdVUw2yNuAEYSD/CSQvqKwG3A== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 65/74] tests: Add a first basic test for fdtaddon Date: Wed, 26 Aug 2026 11:49:34 +0200 Message-ID: <20260826094950.1088288-66-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" The fdtaddon tests family goal is to test features related the application of an addon to a base device tree. This first basic test added in fdtaddon tests is related to the application of a simple addon. The terminology used in the test is the following: - dts: A 'full' device tree source. This can be either a base device tree or a merged device tree (i.e. a base device tree where an addon has been applied to). - dtb: A 'full' device tree blob This can be either a dtb generated by dtc from a dts or the output of the fdtaddon command. - dtsa: An addon device tree source A dts with the '/addon/' keyword. - dtba: An addon device tree blob This a device tree blob generated from a dtsa. With this terminology in mind, the test pattern is the following: - Generate the base tree dtb (fdtaddon_base.dtb) - Check this generated dtb against expected contents - Generate a dtba (xxx.dtba) from an input dtsa - Check this generated dtba against expected contents - Apply the dtba to the base tree dtb at node-a1 (xxx-merged1.dtb) - Check this generated dtb against expected contents - Generate a dts (xxx-merged1.dtb.dts) from the generated xxx-merged1.dtb - Check this generated dts against expected contents - Apply the dtba to the base tree dtb at node-a2 (xxx-merged2.dtb) - Check this generated dtb against expected contents - Generate a dts (xxx-merged2.dtb.dts) from the generated xxx-merged2.dtb - Check this generated dts against expected contents Even if only one basic addon dsta is currently provided in this tests introduction, use a loop in order to ease future addition consisting in testing other features based on more complex addon dtsa. Signed-off-by: Herve Codina --- tests/fdtaddon_base.dtb.expect | 24 ++++++++++ tests/fdtaddon_base.dts | 27 +++++++++++ tests/fdtaddon_basics1-merged1.dtb.dts.expect | 35 ++++++++++++++ tests/fdtaddon_basics1-merged1.dtb.expect | 27 +++++++++++ tests/fdtaddon_basics1-merged2.dtb.dts.expect | 35 ++++++++++++++ tests/fdtaddon_basics1-merged2.dtb.expect | 27 +++++++++++ tests/fdtaddon_basics1.dtba.expect | 8 ++++ tests/fdtaddon_basics1.dtsa | 13 +++++ tests/meson.build | 1 + tests/run_tests.sh | 47 ++++++++++++++++++- tests/testutils.sh | 1 + 11 files changed, 244 insertions(+), 1 deletion(-) create mode 100644 tests/fdtaddon_base.dtb.expect create mode 100644 tests/fdtaddon_base.dts create mode 100644 tests/fdtaddon_basics1-merged1.dtb.dts.expect create mode 100644 tests/fdtaddon_basics1-merged1.dtb.expect create mode 100644 tests/fdtaddon_basics1-merged2.dtb.dts.expect create mode 100644 tests/fdtaddon_basics1-merged2.dtb.expect create mode 100644 tests/fdtaddon_basics1.dtba.expect create mode 100644 tests/fdtaddon_basics1.dtsa diff --git a/tests/fdtaddon_base.dtb.expect b/tests/fdtaddon_base.dtb.expect new file mode 100644 index 00000000..2da5be4d --- /dev/null +++ b/tests/fdtaddon_base.dtb.expect @@ -0,0 +1,24 @@ +/dts-v1/; + +/ { + base-node { + sub-node { + prop =3D <0x00000000>; + phandle =3D <0x00000002>; + }; + }; + somewhere { + node-a1 { + // [FDT_EXPORT_SYM] 'node_a' -> phandle 0x00000001 + // [FDT_EXPORT_SYM] 'other' -> phandle 0x00000002 + compatible =3D "abc,aaa"; + phandle =3D <0x00000001>; + }; + node-a2 { + // [FDT_EXPORT_SYM] 'node_a' -> phandle 0x00000003 + // [FDT_EXPORT_SYM] 'other' -> phandle 0x00000002 + compatible =3D "abc,aaa"; + phandle =3D <0x00000003>; + }; + }; +}; diff --git a/tests/fdtaddon_base.dts b/tests/fdtaddon_base.dts new file mode 100644 index 00000000..3b001461 --- /dev/null +++ b/tests/fdtaddon_base.dts @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) +/* + * Copyright (C) 2026 Bootlin + */ + +/dts-v1/; + +/ { + base-node { + other_a: sub-node { + prop =3D <0>; + }; + }; + + somewhere { + node_a1: node-a1 { + compatible =3D "abc,aaa"; + /export/ node_a: &node_a1; + /export/ other: &other_a; + }; + node_a2: node-a2 { + compatible =3D "abc,aaa"; + /export/ node_a: &node_a2; + /export/ other: &other_a; + }; + }; +}; diff --git a/tests/fdtaddon_basics1-merged1.dtb.dts.expect b/tests/fdtaddon= _basics1-merged1.dtb.dts.expect new file mode 100644 index 00000000..927733c1 --- /dev/null +++ b/tests/fdtaddon_basics1-merged1.dtb.dts.expect @@ -0,0 +1,35 @@ +/dts-v1/; + +/ { + + base-node { + + sub-node { + prop =3D <0x00>; + phandle =3D <0x02>; + }; + }; + + somewhere { + + node-a1 { + compatible =3D "abc,aaa"; + phandle =3D <0x01>; + + /export/ node_a: &{/somewhere/node-a1}; + /export/ other: &{/base-node/sub-node}; + + addon-node { + prop =3D <0x00>; + }; + }; + + node-a2 { + compatible =3D "abc,aaa"; + phandle =3D <0x03>; + + /export/ node_a: &{/somewhere/node-a2}; + /export/ other: &{/base-node/sub-node}; + }; + }; +}; diff --git a/tests/fdtaddon_basics1-merged1.dtb.expect b/tests/fdtaddon_bas= ics1-merged1.dtb.expect new file mode 100644 index 00000000..966a43df --- /dev/null +++ b/tests/fdtaddon_basics1-merged1.dtb.expect @@ -0,0 +1,27 @@ +/dts-v1/; + +/ { + base-node { + sub-node { + prop =3D <0x00000000>; + phandle =3D <0x00000002>; + }; + }; + somewhere { + node-a1 { + // [FDT_EXPORT_SYM] 'node_a' -> phandle 0x00000001 + // [FDT_EXPORT_SYM] 'other' -> phandle 0x00000002 + compatible =3D "abc,aaa"; + phandle =3D <0x00000001>; + addon-node { + prop =3D <0x00000000>; + }; + }; + node-a2 { + // [FDT_EXPORT_SYM] 'node_a' -> phandle 0x00000003 + // [FDT_EXPORT_SYM] 'other' -> phandle 0x00000002 + compatible =3D "abc,aaa"; + phandle =3D <0x00000003>; + }; + }; +}; diff --git a/tests/fdtaddon_basics1-merged2.dtb.dts.expect b/tests/fdtaddon= _basics1-merged2.dtb.dts.expect new file mode 100644 index 00000000..d85567b7 --- /dev/null +++ b/tests/fdtaddon_basics1-merged2.dtb.dts.expect @@ -0,0 +1,35 @@ +/dts-v1/; + +/ { + + base-node { + + sub-node { + prop =3D <0x00>; + phandle =3D <0x02>; + }; + }; + + somewhere { + + node-a1 { + compatible =3D "abc,aaa"; + phandle =3D <0x01>; + + /export/ node_a: &{/somewhere/node-a1}; + /export/ other: &{/base-node/sub-node}; + }; + + node-a2 { + compatible =3D "abc,aaa"; + phandle =3D <0x03>; + + /export/ node_a: &{/somewhere/node-a2}; + /export/ other: &{/base-node/sub-node}; + + addon-node { + prop =3D <0x00>; + }; + }; + }; +}; diff --git a/tests/fdtaddon_basics1-merged2.dtb.expect b/tests/fdtaddon_bas= ics1-merged2.dtb.expect new file mode 100644 index 00000000..ca9c7ba0 --- /dev/null +++ b/tests/fdtaddon_basics1-merged2.dtb.expect @@ -0,0 +1,27 @@ +/dts-v1/; + +/ { + base-node { + sub-node { + prop =3D <0x00000000>; + phandle =3D <0x00000002>; + }; + }; + somewhere { + node-a1 { + // [FDT_EXPORT_SYM] 'node_a' -> phandle 0x00000001 + // [FDT_EXPORT_SYM] 'other' -> phandle 0x00000002 + compatible =3D "abc,aaa"; + phandle =3D <0x00000001>; + }; + node-a2 { + // [FDT_EXPORT_SYM] 'node_a' -> phandle 0x00000003 + // [FDT_EXPORT_SYM] 'other' -> phandle 0x00000002 + compatible =3D "abc,aaa"; + phandle =3D <0x00000003>; + addon-node { + prop =3D <0x00000000>; + }; + }; + }; +}; diff --git a/tests/fdtaddon_basics1.dtba.expect b/tests/fdtaddon_basics1.dt= ba.expect new file mode 100644 index 00000000..1102923a --- /dev/null +++ b/tests/fdtaddon_basics1.dtba.expect @@ -0,0 +1,8 @@ +/dts-v1/; +/addon/; + +/ { + addon-node { + prop =3D <0x00000000>; + }; +}; diff --git a/tests/fdtaddon_basics1.dtsa b/tests/fdtaddon_basics1.dtsa new file mode 100644 index 00000000..84621c97 --- /dev/null +++ b/tests/fdtaddon_basics1.dtsa @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) +/* + * Copyright (C) 2026 Bootlin + */ + +/dts-v1/; +/addon/; + +/ { + addon-node { + prop =3D <0>; + }; +}; diff --git a/tests/meson.build b/tests/meson.build index ec24f0af..e1a2454e 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -144,6 +144,7 @@ run_test_types =3D [ 'fdtdump', 'fdtoverlay', 'metadata', + 'fdtaddon', ] run_test_deps =3D [ dtc_tools, treegen_dtb, tests_exe, diff --git a/tests/run_tests.sh b/tests/run_tests.sh index 7f47b685..3f80b183 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -1281,6 +1281,48 @@ metadata_tests() { run_test check_full metadata_sort.dtb } =20 +run_fdtaddon_test () { + printf "fdtaddon $*: " + base_run_test wrap_test $VALGRIND $FDTADDON "$@" +} + +check_dtb () { + local dtb=3D"$1" + base_run_test wrap_fdtdump "$dtb" "$dtb.out" + sed -i '/^\/\/ [^\[]/d' "$dtb.out" + base_run_test check_diff "$dtb.out" "$SRCDIR/$dtb.expect" + run_test check_full "$dtb" +} + +check_dts () { + local dts=3D"$1" + base_run_test check_diff "$dts" "$SRCDIR/$dts.expect" +} + +fdtaddon_tests() { + run_dtc_test -I dts -O dtb -o fdtaddon_base.dtb "$SRCDIR/fdtaddon_base.dt= s" + check_dtb fdtaddon_base.dtb + + for dt in fdtaddon_basics1; do + run_dtc_test -I dts -O dtb -o $dt.dtba "$SRCDIR/$dt.dtsa" + check_dtb $dt.dtba + + run_fdtaddon_test -i fdtaddon_base.dtb -o $dt-merged1.dtb \ + -t "/somewhere/node-a1" $dt.dtba + check_dtb $dt-merged1.dtb + + run_dtc_test -I dtb -O dts -o $dt-merged1.dtb.dts $dt-merged1.dtb + check_dts $dt-merged1.dtb.dts + + run_fdtaddon_test -i fdtaddon_base.dtb -o $dt-merged2.dtb \ + -t "/somewhere/node-a2" $dt.dtba + check_dtb $dt-merged2.dtb + + run_dtc_test -I dtb -O dts -o $dt-merged2.dtb.dts $dt-merged2.dtb + check_dts $dt-merged2.dtb.dts + done +} + pylibfdt_tests () { run_dtc_test -I dts -O dtb -o test_props.dtb "$SRCDIR/test_props.dts" TMP=3D/tmp/tests.stderr.$$ @@ -1320,7 +1362,7 @@ while getopts "vt:me" ARG ; do done =20 if [ -z "$TESTSETS" ]; then - TESTSETS=3D"libfdt utilfdt dtc dtbs_equal fdtget fdtput fdtdump fdtove= rlay metadata" + TESTSETS=3D"libfdt utilfdt dtc dtbs_equal fdtget fdtput fdtdump fdtove= rlay metadata fdtaddon" =20 # Test pylibfdt if the libfdt Python module is available. if ! $no_python; then @@ -1363,6 +1405,9 @@ for set in $TESTSETS; do "metadata") metadata_tests ;; + "fdtaddon") + fdtaddon_tests + ;; esac done =20 diff --git a/tests/testutils.sh b/tests/testutils.sh index 6b2f0d14..b5e121e7 100644 --- a/tests/testutils.sh +++ b/tests/testutils.sh @@ -27,6 +27,7 @@ DTGET=3D${TEST_BINDIR}/fdtget DTPUT=3D${TEST_BINDIR}/fdtput FDTDUMP=3D${TEST_BINDIR}/fdtdump FDTOVERLAY=3D${TEST_BINDIR}/fdtoverlay +FDTADDON=3D${TEST_BINDIR}/fdtaddon =20 verbose_run () { if [ -z "$QUIET_TEST" ]; then --=20 2.55.0 From nobody Mon Sep 28 04:49:03 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 37CB4416859 for ; Wed, 26 Aug 2026 09:54:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738045; cv=none; b=egd1d7Eo0doSjl95eBtTURTyLjSW5PeY/vBr7PqVebw2TbmVZ+ibhpN/jRqnpkLXYETBuYKX55J6gvDOmBT83Z6c+HqhbPBsWUcaYsgm/Bo5zeYBJeOctsm83yN7sJx8LFpT3b32MgG90UhUjUcIBVTbaWEAO4xk/Js8Z7WVZGU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738045; c=relaxed/simple; bh=JkWMrCyJ4iXRbFDdu5sFRz9JVPemNVB5upCHYVECUtY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=gbkfiBzxpm/pDSyHZ6D4ECWSBGdFBstOM8ieUnRzV+iXfCW09fb5PQt8E+rFgXXnSbe+gz1BqubmeJngIHo4J8jf/4hZUfCdFBQWcIG1QiwGTgkzE2JQXvsBvE5cjvreAekDHFEQf8D1SxK1/c/6du11m+gY7ciWAQKidSyhJk8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=emSTif9k; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="emSTif9k" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id A49354E413BC; Wed, 26 Aug 2026 09:54:00 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 7094B604EC; Wed, 26 Aug 2026 09:54:00 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 954C411C7AD6E; Wed, 26 Aug 2026 11:53:53 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787738035; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=Kq+3KzaSHF4QKpXXgYA6QkJuldrig8PqiNl5QyeuZkA=; b=emSTif9k8PtzOIXYfhfMNkuEnz0VuAuO0G7R89g02qMkUVKjOHZNwzNnYC0eT2ct0iRoKt wHvSlre0QQzqvr1Ap8NTcYptwws0Cr9RZFswlR3S4lQu6vcnTPM3JCFSO7sjERDod3oUcm QRxKbkC022dwZCUdKpt9orqGfvEH4SyMykFhndvBdM2f7utl+jb15WWW0yo0PsODiFxo9r vKvEnUGHB5vtqYAnwGpdq80HEKGBD2K+0JBX5TYzYDDZVfvvaloBIOIk0H5VcjINqyNW6C +9Uoya8HvHhBn2c09XxJLf1ewEVXLwUs6eYOrAnjTsefquTVirIlfAI2iaYcbQ== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 66/74] tests: fdtaddon: Add a basic test for addons using an orphan nodes Date: Wed, 26 Aug 2026 11:49:35 +0200 Message-ID: <20260826094950.1088288-67-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" Orphan nodes are available in addons. Add a test checking the application of an addon when orphan nodes are involved. Signed-off-by: Herve Codina --- tests/fdtaddon_basics2-merged1.dtb.dts.expect | 35 +++++++++++++++++++ tests/fdtaddon_basics2-merged1.dtb.expect | 27 ++++++++++++++ tests/fdtaddon_basics2-merged2.dtb.dts.expect | 35 +++++++++++++++++++ tests/fdtaddon_basics2-merged2.dtb.expect | 27 ++++++++++++++ tests/fdtaddon_basics2.dtba.expect | 9 +++++ tests/fdtaddon_basics2.dtsa | 15 ++++++++ tests/run_tests.sh | 2 +- 7 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 tests/fdtaddon_basics2-merged1.dtb.dts.expect create mode 100644 tests/fdtaddon_basics2-merged1.dtb.expect create mode 100644 tests/fdtaddon_basics2-merged2.dtb.dts.expect create mode 100644 tests/fdtaddon_basics2-merged2.dtb.expect create mode 100644 tests/fdtaddon_basics2.dtba.expect create mode 100644 tests/fdtaddon_basics2.dtsa diff --git a/tests/fdtaddon_basics2-merged1.dtb.dts.expect b/tests/fdtaddon= _basics2-merged1.dtb.dts.expect new file mode 100644 index 00000000..927733c1 --- /dev/null +++ b/tests/fdtaddon_basics2-merged1.dtb.dts.expect @@ -0,0 +1,35 @@ +/dts-v1/; + +/ { + + base-node { + + sub-node { + prop =3D <0x00>; + phandle =3D <0x02>; + }; + }; + + somewhere { + + node-a1 { + compatible =3D "abc,aaa"; + phandle =3D <0x01>; + + /export/ node_a: &{/somewhere/node-a1}; + /export/ other: &{/base-node/sub-node}; + + addon-node { + prop =3D <0x00>; + }; + }; + + node-a2 { + compatible =3D "abc,aaa"; + phandle =3D <0x03>; + + /export/ node_a: &{/somewhere/node-a2}; + /export/ other: &{/base-node/sub-node}; + }; + }; +}; diff --git a/tests/fdtaddon_basics2-merged1.dtb.expect b/tests/fdtaddon_bas= ics2-merged1.dtb.expect new file mode 100644 index 00000000..966a43df --- /dev/null +++ b/tests/fdtaddon_basics2-merged1.dtb.expect @@ -0,0 +1,27 @@ +/dts-v1/; + +/ { + base-node { + sub-node { + prop =3D <0x00000000>; + phandle =3D <0x00000002>; + }; + }; + somewhere { + node-a1 { + // [FDT_EXPORT_SYM] 'node_a' -> phandle 0x00000001 + // [FDT_EXPORT_SYM] 'other' -> phandle 0x00000002 + compatible =3D "abc,aaa"; + phandle =3D <0x00000001>; + addon-node { + prop =3D <0x00000000>; + }; + }; + node-a2 { + // [FDT_EXPORT_SYM] 'node_a' -> phandle 0x00000003 + // [FDT_EXPORT_SYM] 'other' -> phandle 0x00000002 + compatible =3D "abc,aaa"; + phandle =3D <0x00000003>; + }; + }; +}; diff --git a/tests/fdtaddon_basics2-merged2.dtb.dts.expect b/tests/fdtaddon= _basics2-merged2.dtb.dts.expect new file mode 100644 index 00000000..d85567b7 --- /dev/null +++ b/tests/fdtaddon_basics2-merged2.dtb.dts.expect @@ -0,0 +1,35 @@ +/dts-v1/; + +/ { + + base-node { + + sub-node { + prop =3D <0x00>; + phandle =3D <0x02>; + }; + }; + + somewhere { + + node-a1 { + compatible =3D "abc,aaa"; + phandle =3D <0x01>; + + /export/ node_a: &{/somewhere/node-a1}; + /export/ other: &{/base-node/sub-node}; + }; + + node-a2 { + compatible =3D "abc,aaa"; + phandle =3D <0x03>; + + /export/ node_a: &{/somewhere/node-a2}; + /export/ other: &{/base-node/sub-node}; + + addon-node { + prop =3D <0x00>; + }; + }; + }; +}; diff --git a/tests/fdtaddon_basics2-merged2.dtb.expect b/tests/fdtaddon_bas= ics2-merged2.dtb.expect new file mode 100644 index 00000000..ca9c7ba0 --- /dev/null +++ b/tests/fdtaddon_basics2-merged2.dtb.expect @@ -0,0 +1,27 @@ +/dts-v1/; + +/ { + base-node { + sub-node { + prop =3D <0x00000000>; + phandle =3D <0x00000002>; + }; + }; + somewhere { + node-a1 { + // [FDT_EXPORT_SYM] 'node_a' -> phandle 0x00000001 + // [FDT_EXPORT_SYM] 'other' -> phandle 0x00000002 + compatible =3D "abc,aaa"; + phandle =3D <0x00000001>; + }; + node-a2 { + // [FDT_EXPORT_SYM] 'node_a' -> phandle 0x00000003 + // [FDT_EXPORT_SYM] 'other' -> phandle 0x00000002 + compatible =3D "abc,aaa"; + phandle =3D <0x00000003>; + addon-node { + prop =3D <0x00000000>; + }; + }; + }; +}; diff --git a/tests/fdtaddon_basics2.dtba.expect b/tests/fdtaddon_basics2.dt= ba.expect new file mode 100644 index 00000000..ec1582e6 --- /dev/null +++ b/tests/fdtaddon_basics2.dtba.expect @@ -0,0 +1,9 @@ +/dts-v1/; +/addon/; + +// [FDT_IMPORT_SYM] 'node_a' (abc,aaa) +&node_a { + addon-node { + prop =3D <0x00000000>; + }; +}; diff --git a/tests/fdtaddon_basics2.dtsa b/tests/fdtaddon_basics2.dtsa new file mode 100644 index 00000000..0dc70af9 --- /dev/null +++ b/tests/fdtaddon_basics2.dtsa @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) +/* + * Copyright (C) 2026 Bootlin + */ + +/dts-v1/; +/addon/; + +/import/ node_a: "abc,aaa"; + +&node_a { + addon-node { + prop =3D <0>; + }; +}; diff --git a/tests/run_tests.sh b/tests/run_tests.sh index 3f80b183..558f4bd1 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -1303,7 +1303,7 @@ fdtaddon_tests() { run_dtc_test -I dts -O dtb -o fdtaddon_base.dtb "$SRCDIR/fdtaddon_base.dt= s" check_dtb fdtaddon_base.dtb =20 - for dt in fdtaddon_basics1; do + for dt in fdtaddon_basics1 fdtaddon_basics2; do run_dtc_test -I dts -O dtb -o $dt.dtba "$SRCDIR/$dt.dtsa" check_dtb $dt.dtba =20 --=20 2.55.0 From nobody Mon Sep 28 04:49:03 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DA1D13C2BBA; Wed, 26 Aug 2026 09:54:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738050; cv=none; b=ZNNa85tdxWXm+g/09jvcjCeFIc8M9LEEobyrbz6CmLgqWipqowlNr1WudM//QYxNB4Se4WdbUEnbKxDOMcWlSxOtAw2Pq6u1UTpMDRhA66EhxQV0xtAlJ+1firoJQTFmA6+APxo43ucg9X6WK7jc6BZpvb4zyaMVTvJX0aM7dfE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738050; c=relaxed/simple; bh=a4NXlVB5zZSzkiMLWzSwv7ABizKXCCoVs/PQc8UJ0Ms=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WX+jzkMn8FbJRlJD5quMuNYf2tWdDTSZ112JD+Z47OOwhZvNyN0JwoFs94op7vtbQJa6NqzBTkGjWNtJ1lp51+8kGJlPzliTJagz4YN75wN+VKBysBZm1QcgiC1w5rjMVsd+4YYPPEJUTFRHlilBFIg+TcqZrL0xClFRTJ1zFig= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=MWo1ZuZI; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="MWo1ZuZI" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 49BC34E413BC; Wed, 26 Aug 2026 09:54:07 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 1CBF3604EC; Wed, 26 Aug 2026 09:54:07 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id E21C511C7AD65; Wed, 26 Aug 2026 11:53:59 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787738042; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=75CsgcEdDtja8VUmeDx5kT2X9DM5QC5X/cDmRtn72LE=; b=MWo1ZuZI0kbUVNjLjJEOfPgX4pQRQR+GojFLrlBtSvEwchavdT8p4XIYlLd1veAen4PbzM ZlLzrYtfJzTIZcQReS5SpgXxhV56rl9vFISIBRIfKHZwZXtk7Uk4wAtPb9sHdnrBXitt+5 63FnXNSYzXR1hTroeTYDIs68qXzunBZHgDo7FEX0BN6Mte0usXdYa5dtEoM3Z+ucv+kx1Q BMXPQMiy0DN/HBIc4qgd3LLXKJWrQH1aWoBbgSRsyJkX73lURE2Cwt7cBMLp0LRXwSb31a YmCTR7yteO5/u8zMXbjh2CTzWneXbsM2p4ruhr2LRHopLwK2F5DKXY7nZ87Y0w== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 67/74] tests: fdtaddon: Add a basic test for addons with unresolved phandle references Date: Wed, 26 Aug 2026 11:49:36 +0200 Message-ID: <20260826094950.1088288-68-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" Addons can have unresolved phandle references. Those references are resolved when the addon is applied. Add a basic test for this feature. Signed-off-by: Herve Codina --- tests/fdtaddon_basics3-merged1.dtb.dts.expect | 36 +++++++++++++++++++ tests/fdtaddon_basics3-merged1.dtb.expect | 29 +++++++++++++++ tests/fdtaddon_basics3-merged2.dtb.dts.expect | 36 +++++++++++++++++++ tests/fdtaddon_basics3-merged2.dtb.expect | 29 +++++++++++++++ tests/fdtaddon_basics3.dtba.expect | 12 +++++++ tests/fdtaddon_basics3.dtsa | 17 +++++++++ tests/run_tests.sh | 2 +- 7 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 tests/fdtaddon_basics3-merged1.dtb.dts.expect create mode 100644 tests/fdtaddon_basics3-merged1.dtb.expect create mode 100644 tests/fdtaddon_basics3-merged2.dtb.dts.expect create mode 100644 tests/fdtaddon_basics3-merged2.dtb.expect create mode 100644 tests/fdtaddon_basics3.dtba.expect create mode 100644 tests/fdtaddon_basics3.dtsa diff --git a/tests/fdtaddon_basics3-merged1.dtb.dts.expect b/tests/fdtaddon= _basics3-merged1.dtb.dts.expect new file mode 100644 index 00000000..c1bf3cc2 --- /dev/null +++ b/tests/fdtaddon_basics3-merged1.dtb.dts.expect @@ -0,0 +1,36 @@ +/dts-v1/; + +/ { + + base-node { + + sub-node { + prop =3D <0x00>; + phandle =3D <0x02>; + }; + }; + + somewhere { + + node-a1 { + compatible =3D "abc,aaa"; + phandle =3D <0x01>; + + /export/ node_a: &{/somewhere/node-a1}; + /export/ other: &{/base-node/sub-node}; + + addon-node { + ref-other =3D <&{/base-node/sub-node} 0x0a>; + prop =3D <0x00>; + }; + }; + + node-a2 { + compatible =3D "abc,aaa"; + phandle =3D <0x03>; + + /export/ node_a: &{/somewhere/node-a2}; + /export/ other: &{/base-node/sub-node}; + }; + }; +}; diff --git a/tests/fdtaddon_basics3-merged1.dtb.expect b/tests/fdtaddon_bas= ics3-merged1.dtb.expect new file mode 100644 index 00000000..8dccf052 --- /dev/null +++ b/tests/fdtaddon_basics3-merged1.dtb.expect @@ -0,0 +1,29 @@ +/dts-v1/; + +/ { + base-node { + sub-node { + prop =3D <0x00000000>; + phandle =3D <0x00000002>; + }; + }; + somewhere { + node-a1 { + // [FDT_EXPORT_SYM] 'node_a' -> phandle 0x00000001 + // [FDT_EXPORT_SYM] 'other' -> phandle 0x00000002 + compatible =3D "abc,aaa"; + phandle =3D <0x00000001>; + addon-node { + ref-other =3D <0x00000002 0x0000000a>; + // [FDT_PROPDATA_PHANDLE] ref-other[0] + prop =3D <0x00000000>; + }; + }; + node-a2 { + // [FDT_EXPORT_SYM] 'node_a' -> phandle 0x00000003 + // [FDT_EXPORT_SYM] 'other' -> phandle 0x00000002 + compatible =3D "abc,aaa"; + phandle =3D <0x00000003>; + }; + }; +}; diff --git a/tests/fdtaddon_basics3-merged2.dtb.dts.expect b/tests/fdtaddon= _basics3-merged2.dtb.dts.expect new file mode 100644 index 00000000..8dc9fd25 --- /dev/null +++ b/tests/fdtaddon_basics3-merged2.dtb.dts.expect @@ -0,0 +1,36 @@ +/dts-v1/; + +/ { + + base-node { + + sub-node { + prop =3D <0x00>; + phandle =3D <0x02>; + }; + }; + + somewhere { + + node-a1 { + compatible =3D "abc,aaa"; + phandle =3D <0x01>; + + /export/ node_a: &{/somewhere/node-a1}; + /export/ other: &{/base-node/sub-node}; + }; + + node-a2 { + compatible =3D "abc,aaa"; + phandle =3D <0x03>; + + /export/ node_a: &{/somewhere/node-a2}; + /export/ other: &{/base-node/sub-node}; + + addon-node { + ref-other =3D <&{/base-node/sub-node} 0x0a>; + prop =3D <0x00>; + }; + }; + }; +}; diff --git a/tests/fdtaddon_basics3-merged2.dtb.expect b/tests/fdtaddon_bas= ics3-merged2.dtb.expect new file mode 100644 index 00000000..4761a8e5 --- /dev/null +++ b/tests/fdtaddon_basics3-merged2.dtb.expect @@ -0,0 +1,29 @@ +/dts-v1/; + +/ { + base-node { + sub-node { + prop =3D <0x00000000>; + phandle =3D <0x00000002>; + }; + }; + somewhere { + node-a1 { + // [FDT_EXPORT_SYM] 'node_a' -> phandle 0x00000001 + // [FDT_EXPORT_SYM] 'other' -> phandle 0x00000002 + compatible =3D "abc,aaa"; + phandle =3D <0x00000001>; + }; + node-a2 { + // [FDT_EXPORT_SYM] 'node_a' -> phandle 0x00000003 + // [FDT_EXPORT_SYM] 'other' -> phandle 0x00000002 + compatible =3D "abc,aaa"; + phandle =3D <0x00000003>; + addon-node { + ref-other =3D <0x00000002 0x0000000a>; + // [FDT_PROPDATA_PHANDLE] ref-other[0] + prop =3D <0x00000000>; + }; + }; + }; +}; diff --git a/tests/fdtaddon_basics3.dtba.expect b/tests/fdtaddon_basics3.dt= ba.expect new file mode 100644 index 00000000..20a87a19 --- /dev/null +++ b/tests/fdtaddon_basics3.dtba.expect @@ -0,0 +1,12 @@ +/dts-v1/; +/addon/; + +// [FDT_IMPORT_SYM] 'node_a' (abc,aaa) +// [FDT_IMPORT_SYM] 'other' () +&node_a { + addon-node { + prop =3D <0x00000000>; + ref-other =3D <0xffffffff 0x0000000a>; + // [FDT_PROPDATA_PHANDLE_REF] ref-other[0], ref =3D other + }; +}; diff --git a/tests/fdtaddon_basics3.dtsa b/tests/fdtaddon_basics3.dtsa new file mode 100644 index 00000000..8658b45e --- /dev/null +++ b/tests/fdtaddon_basics3.dtsa @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) +/* + * Copyright (C) 2026 Bootlin + */ + +/dts-v1/; +/addon/; + +/import/ node_a: "abc,aaa"; +/import/ other: ""; + +&node_a { + addon-node { + prop =3D <0>; + ref-other =3D <&other 10>; + }; +}; diff --git a/tests/run_tests.sh b/tests/run_tests.sh index 558f4bd1..de3d31a3 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -1303,7 +1303,7 @@ fdtaddon_tests() { run_dtc_test -I dts -O dtb -o fdtaddon_base.dtb "$SRCDIR/fdtaddon_base.dt= s" check_dtb fdtaddon_base.dtb =20 - for dt in fdtaddon_basics1 fdtaddon_basics2; do + for dt in fdtaddon_basics1 fdtaddon_basics2 fdtaddon_basics3; do run_dtc_test -I dts -O dtb -o $dt.dtba "$SRCDIR/$dt.dtsa" check_dtb $dt.dtba =20 --=20 2.55.0 From nobody Mon Sep 28 04:49:03 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id ECCDB3DB983; Wed, 26 Aug 2026 09:54:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738057; cv=none; b=GSDZDuo9lyyjIqVbqFqeKREvyln4hRXKkSU5pO2Hjo47Kfl9w/506EKzR0SH+gat+mrBclIDOwpfTM/pyS8PD3qfehFxETYDVsgvyWlmFp6hDgQTHS5TVuEuVoesyzkzHd0ifuYwp0k8uy5Y0Xx0RR0vEwP4NN4/Mh9K5zMLfNM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738057; c=relaxed/simple; bh=2Cw6vPyL3itLRaJnAnv5w4kyOBsoCLiTgO+22GcyMpk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=kHnNUakGXbgaQkwh1eFrnBxD9CDesIWliE2u6ivN0I+NZvP5Z/2Z5fny5hSLSrSzXjEXiGG2k1rTdGdJ+is422KTjqCFgLsZ3CEoYtwKnVnSWYcdWy6ViWo8/YOGoCa+zaQ2YmMKOVbOkb/uamZuOwfpraC8KYLCiOIju5BV1R4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=BkzxEzBB; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="BkzxEzBB" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 8FF951A0E1B; Wed, 26 Aug 2026 09:54:13 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 63F41604EC; Wed, 26 Aug 2026 09:54:13 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id B523B11C7AD6D; Wed, 26 Aug 2026 11:54:06 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787738048; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=v1Asp1WyFa8gfU5ZcHH4YO7YDdgU9M78nTcE4XMegSc=; b=BkzxEzBBEMT+FILGnUL1ktJ3hdaz6jTuA1Muux7qDJkJTz2zgEEUmlcZTGLR99pVIEIdJy Gb4SpWWuXF1u4ZO2mzuq4nVrO4fZAgN+A+GOUQAOYqiYwlqR99eI0OhE2WaTHVx39LULMu +HZBOlZn3p5JkDWRzuWuhB3TAZGLE7VphG2eJfB+d4lUHoLRi9GxBOxGlnZvS36Vif6fJk vu5SNfmJOL8bDKudjn/wpM65I4lymZKm2LrkcQPrJEx8DcN70LR2cBDYsIx3hMBGHtLrx7 pWVOxgdsxPBQT5dN/NDTN1vJLomoldXRiBUXYh38d8AjljSh4XPdP1UFYvWPWw== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 68/74] tests: fdtaddon: Add a basic test for addons with references by path to orphan nodes Date: Wed, 26 Aug 2026 11:49:37 +0200 Message-ID: <20260826094950.1088288-69-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" Addons can use references by path to reference by path to reference an orphan node or sub-nodes of an orphan node. Those references are converted to either local or external references and have to be handled when the addon is applied. Add a basic test for this feature. Signed-off-by: Herve Codina --- tests/fdtaddon_basics4-merged1.dtb.dts.expect | 43 +++++++++++++++++++ tests/fdtaddon_basics4-merged1.dtb.expect | 37 ++++++++++++++++ tests/fdtaddon_basics4-merged2.dtb.dts.expect | 43 +++++++++++++++++++ tests/fdtaddon_basics4-merged2.dtb.expect | 37 ++++++++++++++++ tests/fdtaddon_basics4.dtba.expect | 22 ++++++++++ tests/fdtaddon_basics4.dtsa | 25 +++++++++++ tests/run_tests.sh | 3 +- 7 files changed, 209 insertions(+), 1 deletion(-) create mode 100644 tests/fdtaddon_basics4-merged1.dtb.dts.expect create mode 100644 tests/fdtaddon_basics4-merged1.dtb.expect create mode 100644 tests/fdtaddon_basics4-merged2.dtb.dts.expect create mode 100644 tests/fdtaddon_basics4-merged2.dtb.expect create mode 100644 tests/fdtaddon_basics4.dtba.expect create mode 100644 tests/fdtaddon_basics4.dtsa diff --git a/tests/fdtaddon_basics4-merged1.dtb.dts.expect b/tests/fdtaddon= _basics4-merged1.dtb.dts.expect new file mode 100644 index 00000000..9e6bbf18 --- /dev/null +++ b/tests/fdtaddon_basics4-merged1.dtb.dts.expect @@ -0,0 +1,43 @@ +/dts-v1/; + +/ { + + base-node { + + sub-node { + prop =3D <0x00>; + phandle =3D <0x02>; + + sub-node { + phandle =3D <0x04>; + prop =3D <0x01>; + }; + }; + }; + + somewhere { + + node-a1 { + compatible =3D "abc,aaa"; + phandle =3D <0x01>; + + /export/ node_a: &{/somewhere/node-a1}; + /export/ other: &{/base-node/sub-node}; + + addon-node { + ref-other-subnode =3D <&{/base-node/sub-node/sub-node}>; + ref-other2 =3D <&{/base-node/sub-node}>; + ref-other1 =3D <&{/base-node/sub-node} 0x0a>; + prop =3D <0x00>; + }; + }; + + node-a2 { + compatible =3D "abc,aaa"; + phandle =3D <0x03>; + + /export/ node_a: &{/somewhere/node-a2}; + /export/ other: &{/base-node/sub-node}; + }; + }; +}; diff --git a/tests/fdtaddon_basics4-merged1.dtb.expect b/tests/fdtaddon_bas= ics4-merged1.dtb.expect new file mode 100644 index 00000000..f339430a --- /dev/null +++ b/tests/fdtaddon_basics4-merged1.dtb.expect @@ -0,0 +1,37 @@ +/dts-v1/; + +/ { + base-node { + sub-node { + prop =3D <0x00000000>; + phandle =3D <0x00000002>; + sub-node { + phandle =3D <0x00000004>; + prop =3D <0x00000001>; + }; + }; + }; + somewhere { + node-a1 { + // [FDT_EXPORT_SYM] 'node_a' -> phandle 0x00000001 + // [FDT_EXPORT_SYM] 'other' -> phandle 0x00000002 + compatible =3D "abc,aaa"; + phandle =3D <0x00000001>; + addon-node { + ref-other-subnode =3D <0x00000004>; + // [FDT_PROPDATA_PHANDLE] ref-other-subnode[0] + ref-other2 =3D <0x00000002>; + // [FDT_PROPDATA_PHANDLE] ref-other2[0] + ref-other1 =3D <0x00000002 0x0000000a>; + // [FDT_PROPDATA_PHANDLE] ref-other1[0] + prop =3D <0x00000000>; + }; + }; + node-a2 { + // [FDT_EXPORT_SYM] 'node_a' -> phandle 0x00000003 + // [FDT_EXPORT_SYM] 'other' -> phandle 0x00000002 + compatible =3D "abc,aaa"; + phandle =3D <0x00000003>; + }; + }; +}; diff --git a/tests/fdtaddon_basics4-merged2.dtb.dts.expect b/tests/fdtaddon= _basics4-merged2.dtb.dts.expect new file mode 100644 index 00000000..0c513c93 --- /dev/null +++ b/tests/fdtaddon_basics4-merged2.dtb.dts.expect @@ -0,0 +1,43 @@ +/dts-v1/; + +/ { + + base-node { + + sub-node { + prop =3D <0x00>; + phandle =3D <0x02>; + + sub-node { + phandle =3D <0x04>; + prop =3D <0x01>; + }; + }; + }; + + somewhere { + + node-a1 { + compatible =3D "abc,aaa"; + phandle =3D <0x01>; + + /export/ node_a: &{/somewhere/node-a1}; + /export/ other: &{/base-node/sub-node}; + }; + + node-a2 { + compatible =3D "abc,aaa"; + phandle =3D <0x03>; + + /export/ node_a: &{/somewhere/node-a2}; + /export/ other: &{/base-node/sub-node}; + + addon-node { + ref-other-subnode =3D <&{/base-node/sub-node/sub-node}>; + ref-other2 =3D <&{/base-node/sub-node}>; + ref-other1 =3D <&{/base-node/sub-node} 0x0a>; + prop =3D <0x00>; + }; + }; + }; +}; diff --git a/tests/fdtaddon_basics4-merged2.dtb.expect b/tests/fdtaddon_bas= ics4-merged2.dtb.expect new file mode 100644 index 00000000..f4072f16 --- /dev/null +++ b/tests/fdtaddon_basics4-merged2.dtb.expect @@ -0,0 +1,37 @@ +/dts-v1/; + +/ { + base-node { + sub-node { + prop =3D <0x00000000>; + phandle =3D <0x00000002>; + sub-node { + phandle =3D <0x00000004>; + prop =3D <0x00000001>; + }; + }; + }; + somewhere { + node-a1 { + // [FDT_EXPORT_SYM] 'node_a' -> phandle 0x00000001 + // [FDT_EXPORT_SYM] 'other' -> phandle 0x00000002 + compatible =3D "abc,aaa"; + phandle =3D <0x00000001>; + }; + node-a2 { + // [FDT_EXPORT_SYM] 'node_a' -> phandle 0x00000003 + // [FDT_EXPORT_SYM] 'other' -> phandle 0x00000002 + compatible =3D "abc,aaa"; + phandle =3D <0x00000003>; + addon-node { + ref-other-subnode =3D <0x00000004>; + // [FDT_PROPDATA_PHANDLE] ref-other-subnode[0] + ref-other2 =3D <0x00000002>; + // [FDT_PROPDATA_PHANDLE] ref-other2[0] + ref-other1 =3D <0x00000002 0x0000000a>; + // [FDT_PROPDATA_PHANDLE] ref-other1[0] + prop =3D <0x00000000>; + }; + }; + }; +}; diff --git a/tests/fdtaddon_basics4.dtba.expect b/tests/fdtaddon_basics4.dt= ba.expect new file mode 100644 index 00000000..14450cb9 --- /dev/null +++ b/tests/fdtaddon_basics4.dtba.expect @@ -0,0 +1,22 @@ +/dts-v1/; +/addon/; + +// [FDT_IMPORT_SYM] 'node_a' (abc,aaa) +// [FDT_IMPORT_SYM] 'other' () +&node_a { + addon-node { + prop =3D <0x00000000>; + ref-other1 =3D <0xffffffff 0x0000000a>; + // [FDT_PROPDATA_PHANDLE_REF] ref-other1[0], ref =3D other + ref-other2 =3D <0xffffffff>; + // [FDT_PROPDATA_PHANDLE_REF] ref-other2[0], ref =3D other + ref-other-subnode =3D <0x00000001>; + // [FDT_PROPDATA_PHANDLE] ref-other-subnode[0] + }; +}; +&other { + sub-node { + prop =3D <0x00000001>; + phandle =3D <0x00000001>; + }; +}; diff --git a/tests/fdtaddon_basics4.dtsa b/tests/fdtaddon_basics4.dtsa new file mode 100644 index 00000000..5ca19ce9 --- /dev/null +++ b/tests/fdtaddon_basics4.dtsa @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) +/* + * Copyright (C) 2026 Bootlin + */ + +/dts-v1/; +/addon/; + +/import/ node_a: "abc,aaa"; +/import/ other: ""; + +&node_a { + addon-node { + prop =3D <0>; + ref-other1 =3D <&other 10>; + ref-other2 =3D <&{$other}>; + ref-other-subnode =3D <&{$other/sub-node}>; + }; +}; + +&other { + sub-node { + prop =3D <1>; + }; +}; diff --git a/tests/run_tests.sh b/tests/run_tests.sh index de3d31a3..5f09bf47 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -1303,7 +1303,8 @@ fdtaddon_tests() { run_dtc_test -I dts -O dtb -o fdtaddon_base.dtb "$SRCDIR/fdtaddon_base.dt= s" check_dtb fdtaddon_base.dtb =20 - for dt in fdtaddon_basics1 fdtaddon_basics2 fdtaddon_basics3; do + for dt in fdtaddon_basics1 fdtaddon_basics2 fdtaddon_basics3 \ + fdtaddon_basics4; do run_dtc_test -I dts -O dtb -o $dt.dtba "$SRCDIR/$dt.dtsa" check_dtb $dt.dtba =20 --=20 2.55.0 From nobody Mon Sep 28 04:49:03 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A91C23B83E0; Wed, 26 Aug 2026 09:54:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738063; cv=none; b=TkDRIHbZecOr6fjiPtl6VM8C5190bBtH9paXMlnsKS3xcxM5jlPB79ZcBy6Ae6b6Jlc6Eu9lEcTmTZdEeG5ZehV0VAOiMt7X3IjwyIP242+G+qownvUQCp/RO2gRtIgBufrN+9Js6qNW5MPAUylYYi8A0grHWcJRC5M+xVc5ooI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738063; c=relaxed/simple; bh=gTjnDdjzLXNImWFuYw4EExm1I0v3x15NXuGmt/w5Q5I=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=gmh/qaW/lxVoO0vHtfSJnmVurZYz8jIRUDrwBoSCnz5yCKHEd3TAgnxj6vcVS132xYOvwTcxjQwZgd9CMeDdE9iU45Rx7zY2RdVjsTxU4RxGeEZrLZsMbziYr0FhjWgr1FtuHvYKrfAteSAfCz4nm+qostDFH6a+FXtLxpor6dc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=o4lKOQoF; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="o4lKOQoF" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 3DB864E413BC; Wed, 26 Aug 2026 09:54:20 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 0C0DF604EC; Wed, 26 Aug 2026 09:54:20 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id DE29F11C7AD65; Wed, 26 Aug 2026 11:54:12 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787738054; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=b9oQR74shA4BDKEeFIaO6NnQSEVFzaXwGxE7a6ZpWjo=; b=o4lKOQoFOIgO6CoJL5RyeMYgtCo+iJj1LtzhtaINGMY61+aXMjzvLBssAWlIXYLEYrVaB6 G+RkAF/qokdSq0c2E+trS7WwUbX8wM6e1E1gHKeFZuHzTf9PQ72gKZPCZ2dz1wjxKUyc5+ FU0sie11bJQQH+3HSrhRAgo/70VSKayIubsWH+faG/ujiaSIq+raLHAcl9v0+n33stiXxp 87qBq82ioJiOG1IicCRW22ChUeGiBjfQcRjaP4L1z23UuFURmiAYLIKrDjkBOHyPvJHjrn IDcrV3yBP4zJ6+9S67NrW44t1TBPpnj+Wv2/ApfZ8GPKsTFGfeBGPAbkDfHjnw== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 69/74] tests: fdtaddon: Add a test for addons with properties identical to existing ones Date: Wed, 26 Aug 2026 11:49:38 +0200 Message-ID: <20260826094950.1088288-70-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" An addon cannot modify or add a property in a existing node. If an addon has a property with the exact same value as an existing one, applying the addon doesn't lead to a property modification. Indeed, because both properties (the addon one and the existing one) are equal, the existing one is not modified. Add a test for this feature. Signed-off-by: Herve Codina --- ...n_addon_prop_existing_ok-merged.dtb.expect | 20 +++++++++++++++ ...dtaddon_addon_prop_existing_ok.dtba.expect | 17 +++++++++++++ tests/fdtaddon_addon_prop_existing_ok.dtsa | 25 +++++++++++++++++++ tests/fdtaddon_base_prop_existing.dtb.expect | 17 +++++++++++++ tests/fdtaddon_base_prop_existing.dts | 22 ++++++++++++++++ tests/run_tests.sh | 12 +++++++++ 6 files changed, 113 insertions(+) create mode 100644 tests/fdtaddon_addon_prop_existing_ok-merged.dtb.expect create mode 100644 tests/fdtaddon_addon_prop_existing_ok.dtba.expect create mode 100644 tests/fdtaddon_addon_prop_existing_ok.dtsa create mode 100644 tests/fdtaddon_base_prop_existing.dtb.expect create mode 100644 tests/fdtaddon_base_prop_existing.dts diff --git a/tests/fdtaddon_addon_prop_existing_ok-merged.dtb.expect b/test= s/fdtaddon_addon_prop_existing_ok-merged.dtb.expect new file mode 100644 index 00000000..a49c3f36 --- /dev/null +++ b/tests/fdtaddon_addon_prop_existing_ok-merged.dtb.expect @@ -0,0 +1,20 @@ +/dts-v1/; + +/ { + base-node { + // [FDT_EXPORT_SYM] 'base' -> phandle 0x00000001 + compatible =3D "abc,base"; + exist_bool; + exist_int =3D <0x0000007b>; + exist_string =3D "abcdef"; + phandle =3D <0x00000001>; + sub-node { + sub_exist_bool; + sub_exist_int =3D <0x000001c8>; + sub_exist_string =3D "ghi"; + addon-node { + prop; + }; + }; + }; +}; diff --git a/tests/fdtaddon_addon_prop_existing_ok.dtba.expect b/tests/fdta= ddon_addon_prop_existing_ok.dtba.expect new file mode 100644 index 00000000..c16c38c7 --- /dev/null +++ b/tests/fdtaddon_addon_prop_existing_ok.dtba.expect @@ -0,0 +1,17 @@ +/dts-v1/; +/addon/; + +// [FDT_IMPORT_SYM] 'base' (abc,base) +&base { + exist_bool; + exist_int =3D <0x0000007b>; + exist_string =3D "abcdef"; + sub-node { + sub_exist_bool; + sub_exist_int =3D <0x000001c8>; + sub_exist_string =3D "ghi"; + addon-node { + prop; + }; + }; +}; diff --git a/tests/fdtaddon_addon_prop_existing_ok.dtsa b/tests/fdtaddon_ad= don_prop_existing_ok.dtsa new file mode 100644 index 00000000..16e525c1 --- /dev/null +++ b/tests/fdtaddon_addon_prop_existing_ok.dtsa @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) +/* + * Copyright (C) 2026 Bootlin + */ + +/dts-v1/; +/addon/; + +/import/ base: "abc,base"; + +&base { + exist_bool; + exist_int =3D <123>; + exist_string =3D "abcdef"; + + sub-node { + sub_exist_bool; + sub_exist_int =3D <456>; + sub_exist_string =3D "ghi"; + + addon-node { + prop; + }; + }; +}; diff --git a/tests/fdtaddon_base_prop_existing.dtb.expect b/tests/fdtaddon_= base_prop_existing.dtb.expect new file mode 100644 index 00000000..2b9d3ac0 --- /dev/null +++ b/tests/fdtaddon_base_prop_existing.dtb.expect @@ -0,0 +1,17 @@ +/dts-v1/; + +/ { + base-node { + // [FDT_EXPORT_SYM] 'base' -> phandle 0x00000001 + compatible =3D "abc,base"; + exist_bool; + exist_int =3D <0x0000007b>; + exist_string =3D "abcdef"; + phandle =3D <0x00000001>; + sub-node { + sub_exist_bool; + sub_exist_int =3D <0x000001c8>; + sub_exist_string =3D "ghi"; + }; + }; +}; diff --git a/tests/fdtaddon_base_prop_existing.dts b/tests/fdtaddon_base_pr= op_existing.dts new file mode 100644 index 00000000..7b0f7102 --- /dev/null +++ b/tests/fdtaddon_base_prop_existing.dts @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) +/* + * Copyright (C) 2026 Bootlin + */ + +/dts-v1/; + +/ { + base_node: base-node { + compatible =3D "abc,base"; + exist_bool; + exist_int =3D <123>; + exist_string =3D "abcdef"; + /export/ base: &base_node; + + sub-node { + sub_exist_bool; + sub_exist_int =3D <456>; + sub_exist_string =3D "ghi"; + }; + }; +}; diff --git a/tests/run_tests.sh b/tests/run_tests.sh index 5f09bf47..0182dffc 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -1322,6 +1322,18 @@ fdtaddon_tests() { run_dtc_test -I dtb -O dts -o $dt-merged2.dtb.dts $dt-merged2.dtb check_dts $dt-merged2.dtb.dts done + + # Test addon with exact same properties as ones available in the base tree + run_dtc_test -I dts -O dtb -o fdtaddon_base_prop_existing.dtb "$SRCDIR/fd= taddon_base_prop_existing.dts" + check_dtb fdtaddon_base_prop_existing.dtb + + run_dtc_test -I dts -O dtb -o fdtaddon_addon_prop_existing_ok.dtba "$SRCD= IR/fdtaddon_addon_prop_existing_ok.dtsa" + check_dtb fdtaddon_addon_prop_existing_ok.dtba + + run_fdtaddon_test -i fdtaddon_base_prop_existing.dtb -o fdtaddon_addon_pr= op_existing_ok-merged.dtb \ + -t "/base-node" fdtaddon_addon_prop_existing_ok.dtba + check_dtb fdtaddon_addon_prop_existing_ok-merged.dtb + } =20 pylibfdt_tests () { --=20 2.55.0 From nobody Mon Sep 28 04:49:03 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4D4D942125B for ; Wed, 26 Aug 2026 09:54:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738070; cv=none; b=VhteDzFrXMqGrcCvdwsWH5kO5rBXOSFpgXVfF60aXNGlSjTL+joLxCqrWnyq+FgXdeHPribbPmIIQpSZodVWosOqhJuDCEBhWuR0E4BQbjmQh6p5dzqLqCg6CsVU6nlnDj/9eYbu8v1GXoI/ogdO5WTxVNcl+Ja3GdVMJNv4TwM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738070; c=relaxed/simple; bh=MHnNR2pV7IRFuaKfOt2KHUASy69UhfvCkta9wVvsJgI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=qqm1p+jRq9yORTXUhei6k5mVhimCLUcDsYvMbKMXm52+yZAFomdI+z67Xhb3fjJPAybUK1ndQUUeVzRYEn8sqYZrINX9Z/hCMYW770iFJQsm8YCzgFUhH1tWiW0I97srX1FrVeXfkGjKzGYpPKHzJCAc9k0t2zc48j64NahUL6M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=pbXcjOg3; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="pbXcjOg3" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 0F7681A0E1B; Wed, 26 Aug 2026 09:54:27 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id D0674604EC; Wed, 26 Aug 2026 09:54:26 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 6A52C11C7AD68; Wed, 26 Aug 2026 11:54:19 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787738061; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=9pMDiGyCLLstUmB3wiJhwi2oHDjtrJbG23U6ozFYFFY=; b=pbXcjOg3Y+8LHn26vgpi2xGfR9R6lorLxaUd+uJHnUysTNGUlox7nCvVwPu7KRLwlWPGDP ZqLb5ZPZu76QawjIVZyhHG2/YnW7P6Aa6bMIuPCXidbyP/h9/9ltbi0Cd7CdX+K8iP1qKr 5kdOsDrs8f7r3nsGYhkyuc6fDsvX/8811PwQFQ0mamj755aWFQre0kYntYqk3oiYR6yyEL q9kjWbqH8WagvLCPBHTiOAF45Lft70GGwCLFC7bDb4QHsutgM3H0oLlAlSzsnToxGxyz2M Znnwd4S+JnwkBX//L6Xisvox8cNQ96KGAPktYovKQ+REWzvU3yyt/6tJFCyi8Q== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 70/74] tests: fdtaddon: Add a test for addons using namespace label references Date: Wed, 26 Aug 2026 11:49:39 +0200 Message-ID: <20260826094950.1088288-71-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" Namespace label references are labels in the form &foo.bar.baz Those kind of labels allow to 'jump' from node to node based on exported symbols defined at each nodes. Add a test for this feature. Signed-off-by: Herve Codina --- ...ddon_addon_namespace-merged.dtb.dts.expect | 57 +++++++++++++++++++ ...fdtaddon_addon_namespace-merged.dtb.expect | 49 ++++++++++++++++ tests/fdtaddon_addon_namespace.dtba.expect | 31 ++++++++++ tests/fdtaddon_addon_namespace.dtsa | 34 +++++++++++ tests/fdtaddon_base_namespace.dtb.expect | 29 ++++++++++ tests/fdtaddon_base_namespace.dts | 33 +++++++++++ tests/run_tests.sh | 13 +++++ 7 files changed, 246 insertions(+) create mode 100644 tests/fdtaddon_addon_namespace-merged.dtb.dts.expect create mode 100644 tests/fdtaddon_addon_namespace-merged.dtb.expect create mode 100644 tests/fdtaddon_addon_namespace.dtba.expect create mode 100644 tests/fdtaddon_addon_namespace.dtsa create mode 100644 tests/fdtaddon_base_namespace.dtb.expect create mode 100644 tests/fdtaddon_base_namespace.dts diff --git a/tests/fdtaddon_addon_namespace-merged.dtb.dts.expect b/tests/f= dtaddon_addon_namespace-merged.dtb.dts.expect new file mode 100644 index 00000000..ff0e5fff --- /dev/null +++ b/tests/fdtaddon_addon_namespace-merged.dtb.dts.expect @@ -0,0 +1,57 @@ +/dts-v1/; + +/ { + + other_n1 { + prop =3D <0x00>; + phandle =3D <0x05>; + + /export/ a: &{/other-a}; + /export/ b: &{/other-b}; + }; + + other-a { + prop =3D <0x00>; + phandle =3D <0x01>; + + addon-node-1a { + phandle =3D <0x06>; + prop =3D <0x1a>; + }; + }; + + other-b { + prop =3D <0x00>; + phandle =3D <0x02>; + + /export/ x: &{/other-x}; + }; + + other-x { + prop =3D <0x00>; + phandle =3D <0x03>; + + addon-node-1bx { + phandle =3D <0x07>; + prop =3D <0x1b>; + }; + }; + + node { + compatible =3D "abc,aaa"; + phandle =3D <0x04>; + + /export/ node: &{/node}; + /export/ n1: &{/other_n1}; + + addon-node2 { + ref-addon-n1bx =3D <&{/other-x/addon-node-1bx}>; + ref-n1bx =3D <&{/other-x}>; + }; + + addon-node1 { + ref-addon-n1a =3D <&{/other-a/addon-node-1a}>; + ref-n1a =3D <&{/other-a}>; + }; + }; +}; diff --git a/tests/fdtaddon_addon_namespace-merged.dtb.expect b/tests/fdtad= don_addon_namespace-merged.dtb.expect new file mode 100644 index 00000000..71edbba8 --- /dev/null +++ b/tests/fdtaddon_addon_namespace-merged.dtb.expect @@ -0,0 +1,49 @@ +/dts-v1/; + +/ { + other_n1 { + // [FDT_EXPORT_SYM] 'a' -> phandle 0x00000001 + // [FDT_EXPORT_SYM] 'b' -> phandle 0x00000002 + prop =3D <0x00000000>; + phandle =3D <0x00000005>; + }; + other-a { + prop =3D <0x00000000>; + phandle =3D <0x00000001>; + addon-node-1a { + phandle =3D <0x00000006>; + prop =3D <0x0000001a>; + }; + }; + other-b { + // [FDT_EXPORT_SYM] 'x' -> phandle 0x00000003 + prop =3D <0x00000000>; + phandle =3D <0x00000002>; + }; + other-x { + prop =3D <0x00000000>; + phandle =3D <0x00000003>; + addon-node-1bx { + phandle =3D <0x00000007>; + prop =3D <0x0000001b>; + }; + }; + node { + // [FDT_EXPORT_SYM] 'node' -> phandle 0x00000004 + // [FDT_EXPORT_SYM] 'n1' -> phandle 0x00000005 + compatible =3D "abc,aaa"; + phandle =3D <0x00000004>; + addon-node2 { + ref-addon-n1bx =3D <0x00000007>; + // [FDT_PROPDATA_PHANDLE] ref-addon-n1bx[0] + ref-n1bx =3D <0x00000003>; + // [FDT_PROPDATA_PHANDLE] ref-n1bx[0] + }; + addon-node1 { + ref-addon-n1a =3D <0x00000006>; + // [FDT_PROPDATA_PHANDLE] ref-addon-n1a[0] + ref-n1a =3D <0x00000001>; + // [FDT_PROPDATA_PHANDLE] ref-n1a[0] + }; + }; +}; diff --git a/tests/fdtaddon_addon_namespace.dtba.expect b/tests/fdtaddon_ad= don_namespace.dtba.expect new file mode 100644 index 00000000..ec1090b5 --- /dev/null +++ b/tests/fdtaddon_addon_namespace.dtba.expect @@ -0,0 +1,31 @@ +/dts-v1/; +/addon/; + +// [FDT_IMPORT_SYM] 'node' (abc,aaa) +// [FDT_IMPORT_SYM] 'n1' () +&node { + addon-node1 { + ref-n1a =3D <0xffffffff>; + // [FDT_PROPDATA_PHANDLE_REF] ref-n1a[0], ref =3D n1.a + ref-addon-n1a =3D <0x00000001>; + // [FDT_PROPDATA_PHANDLE] ref-addon-n1a[0] + }; + addon-node2 { + ref-n1bx =3D <0xffffffff>; + // [FDT_PROPDATA_PHANDLE_REF] ref-n1bx[0], ref =3D n1.b.x + ref-addon-n1bx =3D <0x00000002>; + // [FDT_PROPDATA_PHANDLE] ref-addon-n1bx[0] + }; +}; +&n1.a { + addon-node-1a { + prop =3D <0x0000001a>; + phandle =3D <0x00000001>; + }; +}; +&n1.b.x { + addon-node-1bx { + prop =3D <0x0000001b>; + phandle =3D <0x00000002>; + }; +}; diff --git a/tests/fdtaddon_addon_namespace.dtsa b/tests/fdtaddon_addon_nam= espace.dtsa new file mode 100644 index 00000000..8c25d3d4 --- /dev/null +++ b/tests/fdtaddon_addon_namespace.dtsa @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) +/* + * Copyright (C) 2026 Bootlin + */ + +/dts-v1/; +/addon/; + +/import/ node: "abc,aaa"; +/import/ n1: ""; + +&node { + addon-node1 { + ref-n1a =3D <&n1.a>; + ref-addon-n1a =3D <&addon_n1a>; + }; + + addon-node2 { + ref-n1bx =3D <&n1.b.x>; + ref-addon-n1bx =3D <&addon_n1bx>; + }; +}; + +&n1.a { + addon_n1a: addon-node-1a { + prop =3D <0x1a>; + }; +}; + +&n1.b.x { + addon_n1bx: addon-node-1bx { + prop =3D <0x1b>; + }; +}; diff --git a/tests/fdtaddon_base_namespace.dtb.expect b/tests/fdtaddon_base= _namespace.dtb.expect new file mode 100644 index 00000000..879c4550 --- /dev/null +++ b/tests/fdtaddon_base_namespace.dtb.expect @@ -0,0 +1,29 @@ +/dts-v1/; + +/ { + other_n1 { + // [FDT_EXPORT_SYM] 'a' -> phandle 0x00000001 + // [FDT_EXPORT_SYM] 'b' -> phandle 0x00000002 + prop =3D <0x00000000>; + phandle =3D <0x00000005>; + }; + other-a { + prop =3D <0x00000000>; + phandle =3D <0x00000001>; + }; + other-b { + // [FDT_EXPORT_SYM] 'x' -> phandle 0x00000003 + prop =3D <0x00000000>; + phandle =3D <0x00000002>; + }; + other-x { + prop =3D <0x00000000>; + phandle =3D <0x00000003>; + }; + node { + // [FDT_EXPORT_SYM] 'node' -> phandle 0x00000004 + // [FDT_EXPORT_SYM] 'n1' -> phandle 0x00000005 + compatible =3D "abc,aaa"; + phandle =3D <0x00000004>; + }; +}; diff --git a/tests/fdtaddon_base_namespace.dts b/tests/fdtaddon_base_namesp= ace.dts new file mode 100644 index 00000000..e2bc4f04 --- /dev/null +++ b/tests/fdtaddon_base_namespace.dts @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) +/* + * Copyright (C) 2026 Bootlin + */ + +/dts-v1/; + +/ { + n1: other_n1 { + prop =3D <0>; + /export/ a: &other_a; + /export/ b: &other_b; + }; + + other_a: other-a { + prop =3D <0>; + }; + + other_b: other-b { + prop =3D <0>; + /export/ x: &other_x; + }; + + other_x: other-x { + prop =3D <0>; + }; + + node: node { + compatible =3D "abc,aaa"; + /export/ node: &node; + /export/ n1: &n1; + }; +}; diff --git a/tests/run_tests.sh b/tests/run_tests.sh index 0182dffc..8f8db608 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -1334,6 +1334,19 @@ fdtaddon_tests() { -t "/base-node" fdtaddon_addon_prop_existing_ok.dtba check_dtb fdtaddon_addon_prop_existing_ok-merged.dtb =20 + # Test namespace label reference + run_dtc_test -I dts -O dtb -o fdtaddon_base_namespace.dtb "$SRCDIR/fdtadd= on_base_namespace.dts" + check_dtb fdtaddon_base_namespace.dtb + + run_dtc_test -I dts -O dtb -o fdtaddon_addon_namespace.dtba "$SRCDIR/fdta= ddon_addon_namespace.dtsa" + check_dtb fdtaddon_addon_namespace.dtba + + run_fdtaddon_test -i fdtaddon_base_namespace.dtb -o fdtaddon_addon_namesp= ace-merged.dtb \ + -t "/node" fdtaddon_addon_namespace.dtba + check_dtb fdtaddon_addon_namespace-merged.dtb + + run_dtc_test -I dtb -O dts -o fdtaddon_addon_namespace-merged.dtb.dts fdt= addon_addon_namespace-merged.dtb + check_dts fdtaddon_addon_namespace-merged.dtb.dts } =20 pylibfdt_tests () { --=20 2.55.0 From nobody Mon Sep 28 04:49:03 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C42283DFC7F; Wed, 26 Aug 2026 09:54:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738077; cv=none; b=qUQIzACy+D99895Nz4ofuXZwBwLm51vBBeYMM4a8VJlLEXZVHsvMdhaCrLfzwowGryd/aa0DGWr5T0Cm6uHK8/iFXMZlW/hzxuJgTqWh2qzC++XlPPJKLBQwrMCqqUhBPYIOUhh/a+0ThRuH7JG8rVYHLK0T/4OELIu582HXPfw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738077; c=relaxed/simple; bh=O5IhQ/iDR3RIlHC6nNY5F2D7oss/2qXrH/QcBlRIArg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=TjgcpvMWaVn4FQU1T9MmsMo2xj3eUMYC4kNd+/nrdaERncrws0yMF3UnabeSbASJRobJUskxr51ygXxdCyssIM8e1NLszGDNuRV95j0GiinXQFWxTgIpwAqcoDI2IVn9CgZ3KEtrvbJJc+O+GOTyhahi8GHmaBiNhesEeFqRnIw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=cD5Z1HXT; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="cD5Z1HXT" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 816A11A0E1B; Wed, 26 Aug 2026 09:54:33 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 4E5DD604EC; Wed, 26 Aug 2026 09:54:33 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 658B611C7ACD5; Wed, 26 Aug 2026 11:54:26 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787738068; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=2BdnEMOy39b+aLJF43GGwMZUSCor1vCwKYvaphRBRvk=; b=cD5Z1HXTfXsVjnWXmoWd5nQ+kg59xxvpWhEjyMhvAQvHUvdk+mcJnTBYfpQG1ZQLZt6EoQ hI9omoPfEHflbeGP4WNx+q75Q+VpKS1E92inoQUhRgU4xNtfpfM5qVJ++rW1TTdvItDRat WaMdXg6iBz5A7SuBWl2XuI6k8mwfW5yGruS7xNIVqF5Q3CfAQVKaX8D8nloZJztH0Z/njY +piw74aJ7EYu5vWmUPyN8KkK3vcWqj2mmg8PA+ietMqNZEpv0m4c2n8P/JVur8RB28Hi/j Kn+JD4RYjbmiGYWfqVTVuu38+RwtPiL6wdrhJqVWMM+flEqKEuV4My6eX374xg== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 71/74] tests: fdtaddon: Add a test for using 'stacked' addons Date: Wed, 26 Aug 2026 11:49:40 +0200 Message-ID: <20260826094950.1088288-72-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" Addon can be stacked on top of each other. A first addon can be applied. This first addon exports some symbols and those exported symbols can be used by a second addon. Add a test for this feature. Signed-off-by: Herve Codina --- .../fdtaddon_stack_1st-merged.dtb.dts.expect | 51 ++++++++++++++ tests/fdtaddon_stack_1st-merged.dtb.expect | 41 +++++++++++ tests/fdtaddon_stack_1st.dtba.expect | 24 +++++++ tests/fdtaddon_stack_1st.dtsa | 28 ++++++++ .../fdtaddon_stack_2nd-merged.dtb.dts.expect | 70 +++++++++++++++++++ tests/fdtaddon_stack_2nd-merged.dtb.expect | 59 ++++++++++++++++ tests/fdtaddon_stack_2nd.dtba.expect | 30 ++++++++ tests/fdtaddon_stack_2nd.dtsa | 35 ++++++++++ tests/run_tests.sh | 21 ++++++ 9 files changed, 359 insertions(+) create mode 100644 tests/fdtaddon_stack_1st-merged.dtb.dts.expect create mode 100644 tests/fdtaddon_stack_1st-merged.dtb.expect create mode 100644 tests/fdtaddon_stack_1st.dtba.expect create mode 100644 tests/fdtaddon_stack_1st.dtsa create mode 100644 tests/fdtaddon_stack_2nd-merged.dtb.dts.expect create mode 100644 tests/fdtaddon_stack_2nd-merged.dtb.expect create mode 100644 tests/fdtaddon_stack_2nd.dtba.expect create mode 100644 tests/fdtaddon_stack_2nd.dtsa diff --git a/tests/fdtaddon_stack_1st-merged.dtb.dts.expect b/tests/fdtaddo= n_stack_1st-merged.dtb.dts.expect new file mode 100644 index 00000000..766f3c94 --- /dev/null +++ b/tests/fdtaddon_stack_1st-merged.dtb.dts.expect @@ -0,0 +1,51 @@ +/dts-v1/; + +/ { + + base-node { + + sub-node { + prop =3D <0x00>; + phandle =3D <0x02>; + }; + }; + + somewhere { + + node-a1 { + compatible =3D "abc,aaa"; + phandle =3D <0x01>; + + /export/ node_a: &{/somewhere/node-a1}; + /export/ other: &{/base-node/sub-node}; + + addon1-node { + ref-other =3D <&{/base-node/sub-node} 0x0a>; + prop =3D <0x00>; + + sub-node-other { + phandle =3D <0x05>; + prop =3D <0x01>; + }; + + sub-node-stack1 { + phandle =3D <0x04>; + prop =3D <0x00>; + compatible =3D "abc,bbb"; + + /export/ stack: &{/somewhere/node-a1/addon1-node/sub-node-stack1}; + /export/ base_other: &{/base-node/sub-node}; + /export/ other: &{/somewhere/node-a1/addon1-node/sub-node-other}; + }; + }; + }; + + node-a2 { + compatible =3D "abc,aaa"; + phandle =3D <0x03>; + + /export/ node_a: &{/somewhere/node-a2}; + /export/ other: &{/base-node/sub-node}; + }; + }; +}; diff --git a/tests/fdtaddon_stack_1st-merged.dtb.expect b/tests/fdtaddon_st= ack_1st-merged.dtb.expect new file mode 100644 index 00000000..367695a0 --- /dev/null +++ b/tests/fdtaddon_stack_1st-merged.dtb.expect @@ -0,0 +1,41 @@ +/dts-v1/; + +/ { + base-node { + sub-node { + prop =3D <0x00000000>; + phandle =3D <0x00000002>; + }; + }; + somewhere { + node-a1 { + // [FDT_EXPORT_SYM] 'node_a' -> phandle 0x00000001 + // [FDT_EXPORT_SYM] 'other' -> phandle 0x00000002 + compatible =3D "abc,aaa"; + phandle =3D <0x00000001>; + addon1-node { + ref-other =3D <0x00000002 0x0000000a>; + // [FDT_PROPDATA_PHANDLE] ref-other[0] + prop =3D <0x00000000>; + sub-node-other { + phandle =3D <0x00000005>; + prop =3D <0x00000001>; + }; + sub-node-stack1 { + // [FDT_EXPORT_SYM] 'stack' -> phandle 0x00000004 + // [FDT_EXPORT_SYM] 'base_other' -> phandle 0x00000002 + // [FDT_EXPORT_SYM] 'other' -> phandle 0x00000005 + phandle =3D <0x00000004>; + prop =3D <0x00000000>; + compatible =3D "abc,bbb"; + }; + }; + }; + node-a2 { + // [FDT_EXPORT_SYM] 'node_a' -> phandle 0x00000003 + // [FDT_EXPORT_SYM] 'other' -> phandle 0x00000002 + compatible =3D "abc,aaa"; + phandle =3D <0x00000003>; + }; + }; +}; diff --git a/tests/fdtaddon_stack_1st.dtba.expect b/tests/fdtaddon_stack_1s= t.dtba.expect new file mode 100644 index 00000000..cd0d89a0 --- /dev/null +++ b/tests/fdtaddon_stack_1st.dtba.expect @@ -0,0 +1,24 @@ +/dts-v1/; +/addon/; + +// [FDT_IMPORT_SYM] 'node_a' (abc,aaa) +// [FDT_IMPORT_SYM] 'other' () +&node_a { + addon1-node { + prop =3D <0x00000000>; + ref-other =3D <0xffffffff 0x0000000a>; + // [FDT_PROPDATA_PHANDLE_REF] ref-other[0], ref =3D other + sub-node-stack1 { + // [FDT_EXPORT_SYM] 'stack' -> phandle 0x00000001 + // [FDT_EXPORT_SYM_REF] 'base_other' -> 'other' + // [FDT_EXPORT_SYM] 'other' -> phandle 0x00000002 + compatible =3D "abc,bbb"; + prop =3D <0x00000000>; + phandle =3D <0x00000001>; + }; + sub-node-other { + prop =3D <0x00000001>; + phandle =3D <0x00000002>; + }; + }; +}; diff --git a/tests/fdtaddon_stack_1st.dtsa b/tests/fdtaddon_stack_1st.dtsa new file mode 100644 index 00000000..c4c86ff9 --- /dev/null +++ b/tests/fdtaddon_stack_1st.dtsa @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) +/* + * Copyright (C) 2026 Bootlin + */ + +/dts-v1/; +/addon/; + +/import/ node_a: "abc,aaa"; +/import/ other: ""; + +&node_a { + addon1-node { + prop =3D <0>; + ref-other =3D <&other 10>; + stack1: sub-node-stack1 { + compatible =3D "abc,bbb"; + prop =3D <0>; + /export/ stack: &stack1; + /export/ base_other: &other; + /export/ other: &new_other; + + }; + new_other: sub-node-other { + prop =3D <1>; + }; + }; +}; diff --git a/tests/fdtaddon_stack_2nd-merged.dtb.dts.expect b/tests/fdtaddo= n_stack_2nd-merged.dtb.dts.expect new file mode 100644 index 00000000..fd38dc8c --- /dev/null +++ b/tests/fdtaddon_stack_2nd-merged.dtb.dts.expect @@ -0,0 +1,70 @@ +/dts-v1/; + +/ { + + base-node { + + sub-node { + prop =3D <0x00>; + phandle =3D <0x02>; + + addon2-node-base-other { + ref =3D <&{/somewhere/node-a1/addon1-node/sub-node-stack1/addon2-node}= >; + prop =3D <0x01>; + }; + }; + }; + + somewhere { + + node-a1 { + compatible =3D "abc,aaa"; + phandle =3D <0x01>; + + /export/ node_a: &{/somewhere/node-a1}; + /export/ other: &{/base-node/sub-node}; + + addon1-node { + ref-other =3D <&{/base-node/sub-node} 0x0a>; + prop =3D <0x00>; + + sub-node-other { + phandle =3D <0x05>; + prop =3D <0x01>; + + addon2-node-other { + prop =3D <&{/base-node/sub-node}>; + + addon2-subnode { + prop =3D <0x02>; + }; + }; + }; + + sub-node-stack1 { + phandle =3D <0x04>; + prop =3D <0x00>; + compatible =3D "abc,bbb"; + + /export/ stack: &{/somewhere/node-a1/addon1-node/sub-node-stack1}; + /export/ base_other: &{/base-node/sub-node}; + /export/ other: &{/somewhere/node-a1/addon1-node/sub-node-other}; + + addon2-node { + phandle =3D <0x06>; + ref-other =3D <&{/somewhere/node-a1/addon1-node/sub-node-other} 0x0a= >; + prop =3D <0x00>; + }; + }; + }; + }; + + node-a2 { + compatible =3D "abc,aaa"; + phandle =3D <0x03>; + + /export/ node_a: &{/somewhere/node-a2}; + /export/ other: &{/base-node/sub-node}; + }; + }; +}; diff --git a/tests/fdtaddon_stack_2nd-merged.dtb.expect b/tests/fdtaddon_st= ack_2nd-merged.dtb.expect new file mode 100644 index 00000000..1d45dd23 --- /dev/null +++ b/tests/fdtaddon_stack_2nd-merged.dtb.expect @@ -0,0 +1,59 @@ +/dts-v1/; + +/ { + base-node { + sub-node { + prop =3D <0x00000000>; + phandle =3D <0x00000002>; + addon2-node-base-other { + ref =3D <0x00000006>; + // [FDT_PROPDATA_PHANDLE] ref[0] + prop =3D <0x00000001>; + }; + }; + }; + somewhere { + node-a1 { + // [FDT_EXPORT_SYM] 'node_a' -> phandle 0x00000001 + // [FDT_EXPORT_SYM] 'other' -> phandle 0x00000002 + compatible =3D "abc,aaa"; + phandle =3D <0x00000001>; + addon1-node { + ref-other =3D <0x00000002 0x0000000a>; + // [FDT_PROPDATA_PHANDLE] ref-other[0] + prop =3D <0x00000000>; + sub-node-other { + phandle =3D <0x00000005>; + prop =3D <0x00000001>; + addon2-node-other { + prop =3D <0x00000002>; + // [FDT_PROPDATA_PHANDLE] prop[0] + addon2-subnode { + prop =3D <0x00000002>; + }; + }; + }; + sub-node-stack1 { + // [FDT_EXPORT_SYM] 'stack' -> phandle 0x00000004 + // [FDT_EXPORT_SYM] 'base_other' -> phandle 0x00000002 + // [FDT_EXPORT_SYM] 'other' -> phandle 0x00000005 + phandle =3D <0x00000004>; + prop =3D <0x00000000>; + compatible =3D "abc,bbb"; + addon2-node { + phandle =3D <0x00000006>; + ref-other =3D <0x00000005 0x0000000a>; + // [FDT_PROPDATA_PHANDLE] ref-other[0] + prop =3D <0x00000000>; + }; + }; + }; + }; + node-a2 { + // [FDT_EXPORT_SYM] 'node_a' -> phandle 0x00000003 + // [FDT_EXPORT_SYM] 'other' -> phandle 0x00000002 + compatible =3D "abc,aaa"; + phandle =3D <0x00000003>; + }; + }; +}; diff --git a/tests/fdtaddon_stack_2nd.dtba.expect b/tests/fdtaddon_stack_2n= d.dtba.expect new file mode 100644 index 00000000..2e0f948a --- /dev/null +++ b/tests/fdtaddon_stack_2nd.dtba.expect @@ -0,0 +1,30 @@ +/dts-v1/; +/addon/; + +// [FDT_IMPORT_SYM] 'stack' (abc,bbb) +// [FDT_IMPORT_SYM] 'other' () +// [FDT_IMPORT_SYM] 'base_other' () +&stack { + addon2-node { + prop =3D <0x00000000>; + ref-other =3D <0xffffffff 0x0000000a>; + // [FDT_PROPDATA_PHANDLE_REF] ref-other[0], ref =3D other + phandle =3D <0x00000001>; + }; +}; +&other { + addon2-node-other { + prop =3D <0xffffffff>; + // [FDT_PROPDATA_PHANDLE_REF] prop[0], ref =3D base_other + addon2-subnode { + prop =3D <0x00000002>; + }; + }; +}; +&base_other { + addon2-node-base-other { + prop =3D <0x00000001>; + ref =3D <0x00000001>; + // [FDT_PROPDATA_PHANDLE] ref[0] + }; +}; diff --git a/tests/fdtaddon_stack_2nd.dtsa b/tests/fdtaddon_stack_2nd.dtsa new file mode 100644 index 00000000..21d80d2a --- /dev/null +++ b/tests/fdtaddon_stack_2nd.dtsa @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) +/* + * Copyright (C) 2026 Bootlin + */ + +/dts-v1/; +/addon/; + +/import/ stack: "abc,bbb"; +/import/ other: ""; +/import/ base_other: ""; + +&stack { + addon2_node: addon2-node { + prop =3D <0>; + ref-other =3D <&other 10>; + }; +}; + +&other { + addon2-node-other { + prop =3D <&base_other>; + + addon2-subnode { + prop =3D <2>; + }; + }; +}; + +&base_other { + addon2-node-base-other { + prop =3D <1>; + ref =3D <&addon2_node>; + }; +}; diff --git a/tests/run_tests.sh b/tests/run_tests.sh index 8f8db608..d634274d 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -1347,6 +1347,27 @@ fdtaddon_tests() { =20 run_dtc_test -I dtb -O dts -o fdtaddon_addon_namespace-merged.dtb.dts fdt= addon_addon_namespace-merged.dtb check_dts fdtaddon_addon_namespace-merged.dtb.dts + + # test stacked addons + run_dtc_test -I dts -O dtb -o fdtaddon_stack_1st.dtba "$SRCDIR/fdtaddon_s= tack_1st.dtsa" + check_dtb fdtaddon_stack_1st.dtba + + run_fdtaddon_test -i fdtaddon_base.dtb -o fdtaddon_stack_1st-merged.dtb \ + -t "/somewhere/node-a1" fdtaddon_stack_1st.dtba + check_dtb fdtaddon_stack_1st-merged.dtb + + run_dtc_test -I dtb -O dts -o fdtaddon_stack_1st-merged.dtb.dts fdtaddon_= stack_1st-merged.dtb + check_dts fdtaddon_stack_1st-merged.dtb.dts + + run_dtc_test -I dts -O dtb -o fdtaddon_stack_2nd.dtba "$SRCDIR/fdtaddon_s= tack_2nd.dtsa" + check_dtb fdtaddon_stack_2nd.dtba + + run_fdtaddon_test -i fdtaddon_stack_1st-merged.dtb -o fdtaddon_stack_2nd-= merged.dtb \ + -t "/somewhere/node-a1/addon1-node/sub-node-stack1" fdtaddon_stack_2n= d.dtba + check_dtb fdtaddon_stack_2nd-merged.dtb + + run_dtc_test -I dtb -O dts -o fdtaddon_stack_2nd-merged.dtb.dts fdtaddon_= stack_2nd-merged.dtb + check_dts fdtaddon_stack_2nd-merged.dtb.dts } =20 pylibfdt_tests () { --=20 2.55.0 From nobody Mon Sep 28 04:49:03 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DB2683DC4D7; Wed, 26 Aug 2026 09:54:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738083; cv=none; b=OL60er2dwzHPpt+VFFc0b9HFBkvGF6TNkFaWtG+6a9RkO7AfRuuLDWpnz+eHQI2CYfplHMCeH3w5RhjEI1Z0yxNBvJ6+Xun+LSzH6h0mHeZvLYH3MDd3jVADhQ22BEEowSd9eYEdHMGO760dqCdnwNi3CHMXYAO40FvD6D2oeDI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738083; c=relaxed/simple; bh=pp5pjzLX3R8XOg5YTjbFX9Po5TABtKJyKr+u38ZyZ2Y=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=el9XXhn9dCap2Wx9hHgXxloxIEcISRo5ZH0mu+1n+301+pemdYAL7kiPMVLa/1PcYye+UpLVcDND0LIB3Ygq4ASDejLaOhdvvt5xQ3fWQt2ykiaGAAGUHZZ4hqfVBurN6QwQy8QkJDVzYRkHIFG9I21Q/bpXUj/BIGyxG/4Tbw8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=mkNwUxHv; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="mkNwUxHv" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 717141A0E1B; Wed, 26 Aug 2026 09:54:39 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 46AB1604EC; Wed, 26 Aug 2026 09:54:39 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id DDDFB11C7AD65; Wed, 26 Aug 2026 11:54:32 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787738074; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=ujcA+q4BrF2Wbd9qcs7qyevIb+7xSXGR94mEhO/DkHI=; b=mkNwUxHvVs9+rqUJiHf72IjMyBablap8oMwLnkTLL5ksYq9RAbxAymmUbCAqGgiA3zyrpk ZGFQiUsmYmhRvgjQ0twtUdVmA9RCWOJ6MoHTsEX2dgJ/Xpm3DtNUPaFWlRsrIe/arkLtw+ zPzjMNwRH+sG8S9tgtwiA/lS1nGIQUi7GacikdUmIwqX0DNWNy3t5vtydZd+eun5KO+dB/ cF/rv4bmJ4iWpvqlqynr0NHUs01NxRXhX1272w9gVBoW8+xUUY2ERV2avBCIbgxVQgA7lD AW2aTYKK5hNYDAFiPEzf2ROI5DtyvBMkeD4D8FJwSeCWVSq90jjiRQRA91MB/g== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 72/74] tests: fdtaddon: Add a test using more realistic dts and dtsa Date: Wed, 26 Aug 2026 11:49:41 +0200 Message-ID: <20260826094950.1088288-73-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" The dts and dtsa files used in the fdtaddon tests were centered on specific addon features in order to test those specific features. In term of structure or naming, they are not representative of real use-cases. This new test uses realistic dts and dtsa files with naming and structures tradidionally found in real cases. The dts describes the hardware of the base board. The hardware structure of the base board is the following: +--------------+ | 5V regulator +-------+ +--------------+ | | +----------------------+ | +----------------+ | SOC | | | Connector A | | | | | | | +-----------------+ | +-------+ 5v | | + i2c1 controller +---------------+ i2c bus | | +-----------------+ | +-------+ gpio 0 / irq 0 | | | | +---+ gpio 1 / irq 1 | | +------------------+ | | | +----------------+ | | gpio1 controller | | | | | | gpio #10 +------+ | | +------------------+ | | | | | | +---------------- -+ | | | | gpio2 controller | | | | | gpio #3 +----------+ | +------------------+ | +----------------------+ The connector 'Connector A' is the connector where the pluggable board can be connected to. It is described in the dts and related export symbols are set in order to be usable by the dtsa describing the pluggable board. The hardware structure of the pluggable board is the following: +---------------+ | EEPROM | | i2c addr 0x51 | | + +-------+ i2c | | +---------------+ | | +---------------+ | | Expander IO | +----------------+ | | i2c addr 0x23 | | Connector | | | | | | | +---+ Vcc1 | | 5v +---|---+---+ Vcc2 | | i2c bus +---+-------+ i2c | | gpio 0 / irq 0 +-----------+ irq | | gpio 1 / irq 1 +-----------+ reset | +----------------+ +---------------+ This structure is described in the addon dtsa. This addon dtsa is expected to be applied to the base device tree node describing the connector the pluggable board is connected to. Signed-off-by: Herve Codina --- ...ddon_realistic_addon-merged.dtb.dts.expect | 91 ++++++++++++++++++ ...fdtaddon_realistic_addon-merged.dtb.expect | 93 +++++++++++++++++++ tests/fdtaddon_realistic_addon.dtba.expect | 32 +++++++ tests/fdtaddon_realistic_addon.dtsa | 50 ++++++++++ tests/fdtaddon_realistic_base.dtb.expect | 72 ++++++++++++++ tests/fdtaddon_realistic_base.dts | 74 +++++++++++++++ tests/run_tests.sh | 14 +++ 7 files changed, 426 insertions(+) create mode 100644 tests/fdtaddon_realistic_addon-merged.dtb.dts.expect create mode 100644 tests/fdtaddon_realistic_addon-merged.dtb.expect create mode 100644 tests/fdtaddon_realistic_addon.dtba.expect create mode 100644 tests/fdtaddon_realistic_addon.dtsa create mode 100644 tests/fdtaddon_realistic_base.dtb.expect create mode 100644 tests/fdtaddon_realistic_base.dts diff --git a/tests/fdtaddon_realistic_addon-merged.dtb.dts.expect b/tests/f= dtaddon_realistic_addon-merged.dtb.dts.expect new file mode 100644 index 00000000..49aa9500 --- /dev/null +++ b/tests/fdtaddon_realistic_addon-merged.dtb.dts.expect @@ -0,0 +1,91 @@ +/dts-v1/; + +/ { + + regulator { + compatible =3D "regulator-fixed"; + regulator-min-microvolt =3D <0x4c4b40>; + regulator-max-microvolt =3D <0x4c4b40>; + gpios =3D <&{/soc/gpio@2000} 0x05 0x00>; + phandle =3D <0x05>; + }; + + soc { + compatible =3D "simple-bus"; + #address-cells =3D <0x01>; + #size-cells =3D <0x01>; + + i2c@1000 { + compatible =3D "xyz,i2c-controller"; + reg =3D <0x1000 0x100>; + #address-cells =3D <0x01>; + #size-cells =3D <0x00>; + phandle =3D <0x06>; + }; + + gpio@2000 { + compatible =3D "xyz,gpio-controller"; + reg =3D <0x2000 0x100>; + gpio-controller; + #gpio-cells =3D <0x02>; + interrupt-controller; + #interrupt-cells =3D <0x02>; + #address-cells =3D <0x00>; + phandle =3D <0x01>; + }; + + gpio@3000 { + compatible =3D "xyz,gpio-controller"; + reg =3D <0x3000 0x100>; + gpio-controller; + #gpio-cells =3D <0x02>; + interrupt-controller; + #interrupt-cells =3D <0x02>; + #address-cells =3D <0x00>; + phandle =3D <0x02>; + }; + }; + + connector-a { + compatible =3D "abc,foo-connector"; + #address-cells =3D <0x00>; + #interrupt-cells =3D <0x02>; + interrupt-map =3D <0x00 0x00 &{/soc/gpio@2000} 0x0a 0x00 0x00 0x100 &{/s= oc/gpio@2000} 0x0a 0x100 0x01 0x00 &{/soc/gpio@3000} 0x03 0x00 0x01 0x100 &= {/soc/gpio@3000} 0x03 0x100>; + #gpio-cells =3D <0x02>; + gpio-map-mask =3D <0x0f 0x00>; + gpio-map-pass-thru =3D <0x00 0x0f>; + gpio-map =3D <0x00 0x00 &{/soc/gpio@2000} 0x0a 0x00 0x01 0x00 &{/soc/gpi= o@3000} 0x03 0x00>; + phandle =3D <0x03>; + + /export/ connector: &{/connector-a}; + /export/ conn_i2c: &{/connector-a/conn-i2c}; + /export/ conn_5v: &{/regulator}; + + conn-i2c { + compatible =3D "i2c-bus-extension"; + i2c-parent =3D <&{/soc/i2c@1000}>; + #address-cells =3D <0x01>; + #size-cells =3D <0x00>; + phandle =3D <0x04>; + + eeprom@51 { + reg =3D <0x51>; + compatible =3D "xxx,eeprom"; + }; + + gpio@23 { + reset-gpios =3D <&{/connector-a} 0x01 0x00>; + vcc2-supply =3D <&{/regulator}>; + vcc1-supply =3D <&{/regulator}>; + #interrupt-cells =3D <0x02>; + interrupt-controller; + interrupts =3D <0x00 0x100>; + interrupt-parent =3D <&{/connector-a}>; + #gpio-cells =3D <0x02>; + gpio-controller; + reg =3D <0x23>; + compatible =3D "xxx,expander-io"; + }; + }; + }; +}; diff --git a/tests/fdtaddon_realistic_addon-merged.dtb.expect b/tests/fdtad= don_realistic_addon-merged.dtb.expect new file mode 100644 index 00000000..54f47a1c --- /dev/null +++ b/tests/fdtaddon_realistic_addon-merged.dtb.expect @@ -0,0 +1,93 @@ +/dts-v1/; + +/ { + regulator { + compatible =3D "regulator-fixed"; + regulator-min-microvolt =3D <0x004c4b40>; + regulator-max-microvolt =3D <0x004c4b40>; + gpios =3D <0x00000001 0x00000005 0x00000000>; + // [FDT_PROPDATA_PHANDLE] gpios[0] + phandle =3D <0x00000005>; + }; + soc { + compatible =3D "simple-bus"; + #address-cells =3D <0x00000001>; + #size-cells =3D <0x00000001>; + i2c@1000 { + compatible =3D "xyz,i2c-controller"; + reg =3D <0x00001000 0x00000100>; + #address-cells =3D <0x00000001>; + #size-cells =3D <0x00000000>; + phandle =3D <0x00000006>; + }; + gpio@2000 { + compatible =3D "xyz,gpio-controller"; + reg =3D <0x00002000 0x00000100>; + gpio-controller; + #gpio-cells =3D <0x00000002>; + interrupt-controller; + #interrupt-cells =3D <0x00000002>; + #address-cells =3D <0x00000000>; + phandle =3D <0x00000001>; + }; + gpio@3000 { + compatible =3D "xyz,gpio-controller"; + reg =3D <0x00003000 0x00000100>; + gpio-controller; + #gpio-cells =3D <0x00000002>; + interrupt-controller; + #interrupt-cells =3D <0x00000002>; + #address-cells =3D <0x00000000>; + phandle =3D <0x00000002>; + }; + }; + connector-a { + // [FDT_EXPORT_SYM] 'connector' -> phandle 0x00000003 + // [FDT_EXPORT_SYM] 'conn_i2c' -> phandle 0x00000004 + // [FDT_EXPORT_SYM] 'conn_5v' -> phandle 0x00000005 + compatible =3D "abc,foo-connector"; + #address-cells =3D <0x00000000>; + #interrupt-cells =3D <0x00000002>; + interrupt-map =3D <0x00000000 0x00000000 0x00000001 0x0000000a 0x0= 0000000 0x00000000 0x00000100 0x00000001 0x0000000a 0x00000100 0x00000001 0= x00000000 0x00000002 0x00000003 0x00000000 0x00000001 0x00000100 0x00000002= 0x00000003 0x00000100>; + // [FDT_PROPDATA_PHANDLE] interrupt-map[8] + // [FDT_PROPDATA_PHANDLE] interrupt-map[28] + // [FDT_PROPDATA_PHANDLE] interrupt-map[48] + // [FDT_PROPDATA_PHANDLE] interrupt-map[68] + #gpio-cells =3D <0x00000002>; + gpio-map-mask =3D <0x0000000f 0x00000000>; + gpio-map-pass-thru =3D <0x00000000 0x0000000f>; + gpio-map =3D <0x00000000 0x00000000 0x00000001 0x0000000a 0x000000= 00 0x00000001 0x00000000 0x00000002 0x00000003 0x00000000>; + // [FDT_PROPDATA_PHANDLE] gpio-map[8] + // [FDT_PROPDATA_PHANDLE] gpio-map[28] + phandle =3D <0x00000003>; + conn-i2c { + compatible =3D "i2c-bus-extension"; + i2c-parent =3D <0x00000006>; + // [FDT_PROPDATA_PHANDLE] i2c-parent[0] + #address-cells =3D <0x00000001>; + #size-cells =3D <0x00000000>; + phandle =3D <0x00000004>; + eeprom@51 { + reg =3D <0x00000051>; + compatible =3D "xxx,eeprom"; + }; + gpio@23 { + reset-gpios =3D <0x00000003 0x00000001 0x00000000>; + // [FDT_PROPDATA_PHANDLE] reset-gpios[0] + vcc2-supply =3D <0x00000005>; + // [FDT_PROPDATA_PHANDLE] vcc2-supply[0] + vcc1-supply =3D <0x00000005>; + // [FDT_PROPDATA_PHANDLE] vcc1-supply[0] + #interrupt-cells =3D <0x00000002>; + interrupt-controller; + interrupts =3D <0x00000000 0x00000100>; + interrupt-parent =3D <0x00000003>; + // [FDT_PROPDATA_PHANDLE] interrupt-parent[0] + #gpio-cells =3D <0x00000002>; + gpio-controller; + reg =3D <0x00000023>; + compatible =3D "xxx,expander-io"; + }; + }; + }; +}; diff --git a/tests/fdtaddon_realistic_addon.dtba.expect b/tests/fdtaddon_re= alistic_addon.dtba.expect new file mode 100644 index 00000000..eeef4d43 --- /dev/null +++ b/tests/fdtaddon_realistic_addon.dtba.expect @@ -0,0 +1,32 @@ +/dts-v1/; +/addon/; + +// [FDT_IMPORT_SYM] 'connector' (abc,foo-connector) +// [FDT_IMPORT_SYM] 'conn_5v' () +&connector { + conn-i2c { + gpio@23 { + compatible =3D "xxx,expander-io"; + reg =3D <0x00000023>; + gpio-controller; + #gpio-cells =3D <0x00000002>; + interrupt-parent =3D <0xffffffff>; + // [FDT_PROPDATA_PHANDLE_REF] interrupt-parent[0], ref =3D con= nector + interrupts =3D <0x00000000 0x00000100>; + interrupt-controller; + #interrupt-cells =3D <0x00000002>; + vcc1-supply =3D <0xffffffff>; + // [FDT_PROPDATA_PHANDLE_REF] vcc1-supply[0], ref =3D conn_5v + vcc2-supply =3D <0xffffffff>; + // [FDT_PROPDATA_PHANDLE_REF] vcc2-supply[0], ref =3D connecto= r.conn_5v + reset-gpios =3D <0xffffffff 0x00000001 0x00000000>; + // [FDT_PROPDATA_PHANDLE_REF] reset-gpios[0], ref =3D connector + }; + }; +}; +&connector.conn_i2c { + eeprom@51 { + compatible =3D "xxx,eeprom"; + reg =3D <0x00000051>; + }; +}; diff --git a/tests/fdtaddon_realistic_addon.dtsa b/tests/fdtaddon_realistic= _addon.dtsa new file mode 100644 index 00000000..255a1ffc --- /dev/null +++ b/tests/fdtaddon_realistic_addon.dtsa @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) +/* + * Copyright (C) 2026 Bootlin + */ + +/dts-v1/; +/addon/; + +/import/ connector: "abc,foo-connector"; +/import/ conn_5v: ""; + +&connector { + /* + * Add a gpio expander at the conn-i2c node (i2c extension bus) + * available at the connector node + */ + conn-i2c { + gpio@23 { + compatible =3D "xxx,expander-io"; + reg =3D <0x23>; + gpio-controller; + #gpio-cells =3D <2>; + + /* Use the connector interrupt number 0 */ + interrupt-parent =3D <&connector>; + interrupts =3D <0 0x100>; + interrupt-controller; + #interrupt-cells =3D <2>; + + /* Use 5V power-supply wired to the connector */ + vcc1-supply =3D <&conn_5v>; /* Need to be an imported symbol */ + vcc2-supply =3D <&connector.conn_5v>; /* Only connector need to be impo= rted */ + + /* Use the connector gpio number 1 */ + reset-gpios =3D <&connector 1 0>; + }; + }; +}; + +/* + * Use namespace reference to add an EEPROM at i2c bus connected + * to the connector. It can be an i2c extension or the i2c controller itse= lf. + * We don't know and we don't have to know. + */ +&connector.conn_i2c { + eeprom@51 { + compatible =3D "xxx,eeprom"; + reg =3D <0x51>; + }; +}; diff --git a/tests/fdtaddon_realistic_base.dtb.expect b/tests/fdtaddon_real= istic_base.dtb.expect new file mode 100644 index 00000000..9addbbd8 --- /dev/null +++ b/tests/fdtaddon_realistic_base.dtb.expect @@ -0,0 +1,72 @@ +/dts-v1/; + +/ { + regulator { + compatible =3D "regulator-fixed"; + regulator-min-microvolt =3D <0x004c4b40>; + regulator-max-microvolt =3D <0x004c4b40>; + gpios =3D <0x00000001 0x00000005 0x00000000>; + // [FDT_PROPDATA_PHANDLE] gpios[0] + phandle =3D <0x00000005>; + }; + soc { + compatible =3D "simple-bus"; + #address-cells =3D <0x00000001>; + #size-cells =3D <0x00000001>; + i2c@1000 { + compatible =3D "xyz,i2c-controller"; + reg =3D <0x00001000 0x00000100>; + #address-cells =3D <0x00000001>; + #size-cells =3D <0x00000000>; + phandle =3D <0x00000006>; + }; + gpio@2000 { + compatible =3D "xyz,gpio-controller"; + reg =3D <0x00002000 0x00000100>; + gpio-controller; + #gpio-cells =3D <0x00000002>; + interrupt-controller; + #interrupt-cells =3D <0x00000002>; + #address-cells =3D <0x00000000>; + phandle =3D <0x00000001>; + }; + gpio@3000 { + compatible =3D "xyz,gpio-controller"; + reg =3D <0x00003000 0x00000100>; + gpio-controller; + #gpio-cells =3D <0x00000002>; + interrupt-controller; + #interrupt-cells =3D <0x00000002>; + #address-cells =3D <0x00000000>; + phandle =3D <0x00000002>; + }; + }; + connector-a { + // [FDT_EXPORT_SYM] 'connector' -> phandle 0x00000003 + // [FDT_EXPORT_SYM] 'conn_i2c' -> phandle 0x00000004 + // [FDT_EXPORT_SYM] 'conn_5v' -> phandle 0x00000005 + compatible =3D "abc,foo-connector"; + #address-cells =3D <0x00000000>; + #interrupt-cells =3D <0x00000002>; + interrupt-map =3D <0x00000000 0x00000000 0x00000001 0x0000000a 0x0= 0000000 0x00000000 0x00000100 0x00000001 0x0000000a 0x00000100 0x00000001 0= x00000000 0x00000002 0x00000003 0x00000000 0x00000001 0x00000100 0x00000002= 0x00000003 0x00000100>; + // [FDT_PROPDATA_PHANDLE] interrupt-map[8] + // [FDT_PROPDATA_PHANDLE] interrupt-map[28] + // [FDT_PROPDATA_PHANDLE] interrupt-map[48] + // [FDT_PROPDATA_PHANDLE] interrupt-map[68] + #gpio-cells =3D <0x00000002>; + gpio-map-mask =3D <0x0000000f 0x00000000>; + gpio-map-pass-thru =3D <0x00000000 0x0000000f>; + gpio-map =3D <0x00000000 0x00000000 0x00000001 0x0000000a 0x000000= 00 0x00000001 0x00000000 0x00000002 0x00000003 0x00000000>; + // [FDT_PROPDATA_PHANDLE] gpio-map[8] + // [FDT_PROPDATA_PHANDLE] gpio-map[28] + phandle =3D <0x00000003>; + conn-i2c { + compatible =3D "i2c-bus-extension"; + i2c-parent =3D <0x00000006>; + // [FDT_PROPDATA_PHANDLE] i2c-parent[0] + #address-cells =3D <0x00000001>; + #size-cells =3D <0x00000000>; + phandle =3D <0x00000004>; + }; + }; +}; diff --git a/tests/fdtaddon_realistic_base.dts b/tests/fdtaddon_realistic_b= ase.dts new file mode 100644 index 00000000..0c13f1af --- /dev/null +++ b/tests/fdtaddon_realistic_base.dts @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) +/* + * Copyright (C) 2026 Bootlin + */ + +/dts-v1/; + +/ { + conn_a_5v: regulator { + compatible =3D "regulator-fixed"; + regulator-min-microvolt =3D <5000000>; + regulator-max-microvolt =3D <5000000>; + gpios =3D <&gpio1 5 0>; + }; + + soc { + compatible =3D "simple-bus"; + #address-cells =3D <1>; + #size-cells =3D <1>; + + i2c1: i2c@1000 { + compatible =3D "xyz,i2c-controller"; + reg =3D <0x1000 0x100>; + #address-cells =3D <1>; + #size-cells =3D <0>; + }; + + gpio1: gpio@2000 { + compatible =3D "xyz,gpio-controller"; + reg =3D <0x2000 0x100>; + gpio-controller; + #gpio-cells =3D <2>; + interrupt-controller; + #interrupt-cells =3D <2>; + #address-cells =3D <0>; /* interrupt-map usage */ + }; + + gpio2: gpio@3000 { + compatible =3D "xyz,gpio-controller"; + reg =3D <0x3000 0x100>; + gpio-controller; + #gpio-cells =3D <2>; + interrupt-controller; + #interrupt-cells =3D <2>; + #address-cells =3D <0>; /* interrupt-map usage */ + }; + }; + + conn_a: connector-a { + compatible =3D "abc,foo-connector"; + #address-cells =3D <0>; + #interrupt-cells =3D <2>; + interrupt-map =3D <0 0 &gpio1 10 0>, + <0 0x100 &gpio1 10 0x100>, + <1 0 &gpio2 3 0>, + <1 0x100 &gpio2 3 0x100>; + #gpio-cells =3D <2>; + gpio-map-mask =3D <0xf 0x0>; + gpio-map-pass-thru =3D <0x0 0xf>; + gpio-map =3D <0 0 &gpio1 10 0>, + <1 0 &gpio2 3 0>; + + /export/ connector: &conn_a; + /export/ conn_i2c: &conn_a_i2c; + /export/ conn_5v: &conn_a_5v; + + conn_a_i2c: conn-i2c { + compatible =3D "i2c-bus-extension"; + i2c-parent =3D <&i2c1>; + #address-cells =3D <1>; + #size-cells =3D <0>; + }; + }; +}; diff --git a/tests/run_tests.sh b/tests/run_tests.sh index d634274d..664ebf5d 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -1368,6 +1368,20 @@ fdtaddon_tests() { =20 run_dtc_test -I dtb -O dts -o fdtaddon_stack_2nd-merged.dtb.dts fdtaddon_= stack_2nd-merged.dtb check_dts fdtaddon_stack_2nd-merged.dtb.dts + + # More realistic dts and dtsa input files + run_dtc_test -I dts -O dtb -o fdtaddon_realistic_base.dtb "$SRCDIR/fdtadd= on_realistic_base.dts" + check_dtb fdtaddon_realistic_base.dtb + + run_dtc_test -I dts -O dtb -o fdtaddon_realistic_addon.dtba "$SRCDIR/fdta= ddon_realistic_addon.dtsa" + check_dtb fdtaddon_realistic_addon.dtba + + run_fdtaddon_test -i fdtaddon_realistic_base.dtb -o fdtaddon_realistic_ad= don-merged.dtb \ + -t "/connector-a" fdtaddon_realistic_addon.dtba + check_dtb fdtaddon_realistic_addon-merged.dtb + + run_dtc_test -I dtb -O dts -o fdtaddon_realistic_addon-merged.dtb.dts fdt= addon_realistic_addon-merged.dtb + check_dts fdtaddon_realistic_addon-merged.dtb.dts } =20 pylibfdt_tests () { --=20 2.55.0 From nobody Mon Sep 28 04:49:03 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 89C4D3DA5AB; Wed, 26 Aug 2026 09:54:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738088; cv=none; b=VX0MAkiOCnaz4sg9wSOP6Sh8BrgGZG+aHbKHSS+bj4wcPtJwxXLgCHMYgyBz4+4uz+98On92TBr+CmmPV/vcA6rgNwfoGdNVYp5pH95KTsow6YlTNDP6ntvy+XCU8P0+G8l1r0fGlJ0QkEyDk5Ofu0V+M25EvrZX1jLUP1uHtqU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738088; c=relaxed/simple; bh=1SX7I+mNBJ264w2nmavu8MDlPskUkfu+5vJhwf/E+fU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Hbk+JcKLR/p8vnqieCGer3bFGl45FIgjbymfNSRULG9BKDNp8Y8DafrnNcN7p9kqJ1Aa8xf/oioiQmIZxPie4n1mP2yJOWCZgHH8TPOQlT6pGClZeL4iaXKzVg/CujdReL3xkSSI1JkMAL2sAVNx5CxVGDilF5iAJjPG3Pf4dNk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=YpujNEIf; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="YpujNEIf" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id 490531A0E1B; Wed, 26 Aug 2026 09:54:45 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 15CDE604EC; Wed, 26 Aug 2026 09:54:45 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id B40EC11C7AD72; Wed, 26 Aug 2026 11:54:38 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787738080; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=IOlJxADsKv2rEvlqPqIn/xFOwUgnW9qq8lcD9Dv1i0I=; b=YpujNEIfUlXKKw1xir5xMn2imGgppiKhu5Aby28//K3jitZcRH062lcTokmTO0B2XIUc9G PrpOzAIUZdiq9pCMaktn0SPzSYEVe2SlhFVTqkEk6u1XBwwB78bSaWjAvnNFHy22hxyFcz C1b7JK21os9CrwE5gEHvi2ygfSTrvXCiVBR9O/huFSEve3XtO73V/1f8VOUJwpccqYJnt2 nGTtxuAVL9lQIPYY6STd+T6uTorZpnVnkyCbh+AcXnaK9dHVGWPus5q82Ir7gLm1inDtfv a8CW7RBlZWOeOA/nObQ+tvD9gsnC1JCIT7ha+zye0twxOkaawKo7cHiNmj6L+Q== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 73/74] libfdt/fdt_addon.c: Add support for an external resolver Date: Wed, 26 Aug 2026 11:49:42 +0200 Message-ID: <20260826094950.1088288-74-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" fdt_addon.c uses its own default resolver to resolve import symbols. It expects a matching between the name of the import symbol to resolve and the name of export symbols available in the addon target node (node in the base dtb). In some cases, it makes sense to have a resolver that could choose the right export symbol to match based on some other criteria. The external resolver allows the user of libfdt to provide its own resolver and so match an import symbol based on its own criteria. Signed-off-by: Herve Codina --- libfdt/fdt_addon.c | 138 +++++++++++++++++++++++++++++++++------------ libfdt/libfdt.h | 98 +++++++++++++++++++++++++++++++- libfdt/version.lds | 2 + 3 files changed, 200 insertions(+), 38 deletions(-) diff --git a/libfdt/fdt_addon.c b/libfdt/fdt_addon.c index 54e71cbd..99d9c10a 100644 --- a/libfdt/fdt_addon.c +++ b/libfdt/fdt_addon.c @@ -10,6 +10,11 @@ =20 #include "libfdt_internal.h" =20 +struct fdt_addon_resolver { + const struct fdt_addon_resolver_ops *ops; + void *priv; +}; + /** * fdt_skip_string - Skip a string * @fdt: device tree blob @@ -568,21 +573,9 @@ static int fdt_resolve_symbol(const void *fdt, int tar= get_node, return -FDT_ERR_NOTFOUND; } =20 -/** - * fdt_resolve_import - Resolve an imported symbol - * @fdt: base device tree blob - * @target_node: Target node offset in the base device tree blob containing - * the exported symbols used for the resolution. - * @importsym_name: Import symbol name - * @importsym_compatible: Import symbol compatible string - * - * returns: - * offset of the node matching the symbol after the resolution on suc= cess. - * Negative error code on failure. - */ -static int fdt_resolve_import(const void *fdt, int target_node, - const char *importsym_name, - const char *importsym_compatible) +int fdt_addon_resolve_default(const void *fdt, int target_node, + const char *importsym_name, + const char *importsym_compatible) { /* * Do not check the import symbol compatible string against the found @@ -604,6 +597,33 @@ static int fdt_resolve_import(const void *fdt, int tar= get_node, strlen(importsym_name)); } =20 +/** + * fdt_resolve_import - Resolve an imported symbol + * @fdt: base device tree blob + * @target_node: Target node offset in the base device tree blob containing + * the exported symbols used for the resolution. + * @importsym_name: Import symbol name + * @importsym_compatible: Import symbol compatible string + * @resolver: Custom resolver. If NULL, the default resolver is used. + * + * returns: + * offset of the node matching the symbol after the resolution on suc= cess. + * Negative error code on failure. + */ +static int fdt_resolve_import(const void *fdt, int target_node, + const char *importsym_name, + const char *importsym_compatible, + const struct fdt_addon_resolver *resolver) +{ + if (resolver) + return resolver->ops->resolve(resolver->priv, fdt, target_node, + importsym_name, + importsym_compatible); + + return fdt_addon_resolve_default(fdt, target_node, importsym_name, + importsym_compatible); +} + static int fdt_check_importsym_offset(const void *fdt, int offset, int *da= ta_offset) { int nextoffset, d; @@ -709,6 +729,7 @@ static const char *fdt_importsym_get_compatible(const v= oid *fdt, int offset) * resolution. * @sym_name: Symbol name * @sym_namelen: Length of the symbol name + * @resolver: Custom resolver, NULL to use the default resolver. * * addon_resolve_symbol() resolved a symbol used by an addon using the imp= ort * symbol table available in the addon device tree blob. @@ -719,7 +740,8 @@ static const char *fdt_importsym_get_compatible(const v= oid *fdt, int offset) * Negative error code on failure. */ static int addon_resolve_symbol(const void *fdta, const void *fdt, int tar= get_node, - const char *sym_name, size_t sym_namelen) + const char *sym_name, size_t sym_namelen, + const struct fdt_addon_resolver *resolver) { const char *importsym_compat; const char *importsym_name; @@ -739,7 +761,7 @@ static int addon_resolve_symbol(const void *fdta, const= void *fdt, int target_no continue; =20 return fdt_resolve_import(fdt, target_node, importsym_name, - importsym_compat); + importsym_compat, resolver); } /* Not found ... */ return -FDT_ERR_NOTFOUND; @@ -753,6 +775,7 @@ static int addon_resolve_symbol(const void *fdta, const= void *fdt, int target_no * device tree blob, must have exported symbols needed for t= he * resolution. * @ref: The reference to resolve + * @resolver: Custom resolver, NULL to use the default resolver * * addon_resolve_ref() resolves a reference used by an addon. * A reference can be composed of several symbols separated by a '.' char. @@ -769,7 +792,8 @@ static int addon_resolve_symbol(const void *fdta, const= void *fdt, int target_no * Negative error code on failure. */ static int addon_resolve_ref(const void *fdta, const void *fdt, int target= _node, - const char *ref) + const char *ref, + const struct fdt_addon_resolver *resolver) { const char *end =3D ref + strlen(ref); const char *r =3D ref; @@ -794,7 +818,8 @@ static int addon_resolve_ref(const void *fdta, const vo= id *fdt, int target_node, d =3D end; =20 if (r =3D=3D ref) - tmp_node =3D addon_resolve_symbol(fdta, fdt, tmp_node, r, d-r); + tmp_node =3D addon_resolve_symbol(fdta, fdt, tmp_node, r, d-r, + resolver); else tmp_node =3D fdt_resolve_symbol(fdt, tmp_node, r, d-r); =20 @@ -812,6 +837,7 @@ static int addon_resolve_ref(const void *fdta, const vo= id *fdt, int target_node, * @fdta: Addon device tree blob * @fdt: Device tree blob the addon is going to be applied to * @target_node: Offset of the node in fdt the addon is going to be applie= d to + * @resolver: Custom resolver. NULL to use the default resolver * * addon_resolve_phandles() resolved unresolved phandle symbols available = in * the addon. @@ -820,7 +846,8 @@ static int addon_resolve_ref(const void *fdta, const vo= id *fdt, int target_node, * 0 on success * Negative error code on failure */ -static int addon_resolve_phandles(void *fdta, const void *fdt, int target_= node) +static int addon_resolve_phandles(void *fdta, const void *fdt, int target_= node, + const struct fdt_addon_resolver *resolver) { int offset, next_offset, d; int last_prop_offset =3D -1; @@ -880,7 +907,8 @@ static int addon_resolve_phandles(void *fdta, const voi= d *fdt, int target_node) ref =3D fdt_offset_ptr(fdta, d, 1); =20 /* Resolve this phandle */ - ref_node =3D addon_resolve_ref(fdta, fdt, target_node, ref); + ref_node =3D addon_resolve_ref(fdta, fdt, target_node, ref, + resolver); if (ref_node < 0) return ref_node; =20 @@ -931,7 +959,8 @@ static int addon_resolve_phandles(void *fdta, const voi= d *fdt, int target_node) ref =3D fdt_offset_ptr(fdta, d, 1); =20 /* Resolve the phandle */ - ref_node =3D addon_resolve_ref(fdta, fdt, target_node, ref); + ref_node =3D addon_resolve_ref(fdta, fdt, target_node, + ref, resolver); if (ref_node < 0) return ref_node; =20 @@ -1153,6 +1182,7 @@ static const char *fdt_orphan_get_ref(const void *fdt= , int offset) * @fdt: Base Device Tree blob * @target_node: Target node in the base device tree the addon is going to= be * applied to + * @resolver: Custom resolver, NULL to use the default resolver * * Checks recursively if applying fdta overwrites phandle values in the ba= se * fdt. When such a phandle is found, the fdta is changed to use the fdt's @@ -1163,7 +1193,8 @@ static const char *fdt_orphan_get_ref(const void *fdt= , int offset) * Negative error code on failure */ static int addon_prevent_phandles_overwrite(void *fdta, const void *fdt, - int target_node) + int target_node, + const struct fdt_addon_resolver *resolver) { int fdt_orphan_target; int addon_root_node; @@ -1187,7 +1218,8 @@ static int addon_prevent_phandles_overwrite(void *fdt= a, const void *fdt, if (!ref) return -FDT_ERR_BADSTRUCTURE; =20 - fdt_orphan_target =3D addon_resolve_ref(fdta, fdt, target_node, ref); + fdt_orphan_target =3D addon_resolve_ref(fdta, fdt, target_node, + ref, resolver); if (fdt_orphan_target < 0) return fdt_orphan_target; =20 @@ -1505,6 +1537,7 @@ static int addon_merge_node_properties(const void *fd= ta, int fdta_node, * @target_path: Path in the base Device Tree to the node where the addon = is * applied to. This is the node where export symbols used for symbol * resolution are present. + * @resolver: Custom resolver. NULL to use the default resolver. * * returns: * 0 on success @@ -1512,7 +1545,8 @@ static int addon_merge_node_properties(const void *fd= ta, int fdta_node, */ static int addon_merge_node_exports(const void *fdta, int fdta_node, void *fdt, int fdt_node, - bool is_existing_node, const char *target_path) + bool is_existing_node, const char *target_path, + const struct fdt_addon_resolver *resolver) { const char *exportsym_name; const char *exportsym_ref; @@ -1554,7 +1588,8 @@ static int addon_merge_node_exports(const void *fdta,= int fdta_node, return target_node; =20 /* Resolve the reference */ - ref_node =3D addon_resolve_ref(fdta, fdt, target_node, exportsym_ref); + ref_node =3D addon_resolve_ref(fdta, fdt, target_node, + exportsym_ref, resolver); if (ref_node < 0) return ref_node; =20 @@ -1591,6 +1626,7 @@ static int addon_merge_node_exports(const void *fdta,= int fdta_node, * @target_path: Path in the base Device Tree to the node where the addon = is * applied to. This is the node where export symbols used for symbol * resolution are present. + * @resolver: Custom resolver, NULL to use the default resolver. * * returns: * 0 on success @@ -1598,7 +1634,8 @@ static int addon_merge_node_exports(const void *fdta,= int fdta_node, */ static int addon_merge_node(const void *fdta, int fdta_node, void *fdt, int fdt_node, bool is_existing_node, - const char *target_path) + const char *target_path, + const struct fdt_addon_resolver *resolver) { bool is_existing; int fdta_subnode; @@ -1607,7 +1644,8 @@ static int addon_merge_node(const void *fdta, int fdt= a_node, void *fdt, int ret; =20 ret =3D addon_merge_node_exports(fdta, fdta_node, fdt, fdt_node, - is_existing_node, target_path); + is_existing_node, target_path, + resolver); if (ret) return ret; =20 @@ -1632,7 +1670,7 @@ static int addon_merge_node(const void *fdta, int fdt= a_node, void *fdt, return fdt_subnode; =20 ret =3D addon_merge_node(fdta, fdta_subnode, fdt, fdt_subnode, - is_existing, target_path); + is_existing, target_path, resolver); if (ret) return ret; } @@ -1640,7 +1678,8 @@ static int addon_merge_node(const void *fdta, int fdt= a_node, void *fdt, return 0; } =20 -static int addon_merge(void *fdta, void *fdt, const char *target_path) +static int addon_merge(void *fdta, void *fdt, const char *target_path, + const struct fdt_addon_resolver *resolver) { int fdt_orphan_target; int fdta_orphan; @@ -1654,7 +1693,8 @@ static int addon_merge(void *fdta, void *fdt, const c= har *target_path) return target_node; =20 /* Merge the addon root node into the base target_node */ - ret =3D addon_merge_node(fdta, 0, fdt, target_node, true, target_path); + ret =3D addon_merge_node(fdta, 0, fdt, target_node, true, target_path, + resolver); if (ret < 0) return ret; =20 @@ -1663,12 +1703,13 @@ static int addon_merge(void *fdta, void *fdt, const= char *target_path) if (!ref) return -FDT_ERR_BADSTRUCTURE; =20 - fdt_orphan_target =3D addon_resolve_ref(fdta, fdt, target_node, ref); + fdt_orphan_target =3D addon_resolve_ref(fdta, fdt, target_node, + ref, resolver); if (fdt_orphan_target < 0) return fdt_orphan_target; =20 ret =3D addon_merge_node(fdta, fdta_orphan, fdt, fdt_orphan_target, - true, target_path); + true, target_path, resolver); if (ret < 0) return ret; =20 @@ -1688,8 +1729,12 @@ static int addon_merge(void *fdta, void *fdt, const = char *target_path) return 0; } =20 -int fdt_addon_apply(void *fdt, void *fdta, const char *target) +int fdt_addon_apply_resolver(void *fdt, void *fdta, const char *target, + const struct fdt_addon_resolver_ops *resolver_ops, + void *resolver_priv) { + struct fdt_addon_resolver *resolver =3D NULL; + struct fdt_addon_resolver custom_resolver; int target_node; uint32_t delta; int ret; @@ -1697,11 +1742,25 @@ int fdt_addon_apply(void *fdt, void *fdta, const ch= ar *target) FDT_RO_PROBE(fdt); FDT_RO_PROBE(fdta); =20 + if (resolver_ops) { + /* Initialize the custom resolver */ + custom_resolver.ops =3D resolver_ops; + custom_resolver.priv =3D resolver_priv; + /* This custom resolver is the resolver used */ + resolver =3D &custom_resolver; + } + /* Get the target node */ target_node =3D fdt_path_offset(fdt, target); if (target_node < 0) return target_node; =20 + if (resolver && resolver->ops->validate) { + ret =3D resolver->ops->validate(resolver->priv, fdt, target_node); + if (ret < 0) + return ret; + } + ret =3D fdt_find_max_phandle(fdt, &delta); if (ret) return ret; @@ -1712,16 +1771,16 @@ int fdt_addon_apply(void *fdt, void *fdta, const ch= ar *target) goto err; =20 /* Resolve phandles */ - ret =3D addon_resolve_phandles(fdta, fdt, target_node); + ret =3D addon_resolve_phandles(fdta, fdt, target_node, resolver); if (ret < 0) goto err; =20 /* Don't overwrite phandles in fdt */ - ret =3D addon_prevent_phandles_overwrite(fdta, fdt, target_node); + ret =3D addon_prevent_phandles_overwrite(fdta, fdt, target_node, resolver= ); if (ret < 0) goto err; =20 - ret =3D addon_merge(fdta, fdt, target); + ret =3D addon_merge(fdta, fdt, target, resolver); if (ret < 0) goto err; =20 @@ -1739,3 +1798,8 @@ err: =20 return ret; } + +int fdt_addon_apply(void *fdt, void *fdta, const char *target) +{ + return fdt_addon_apply_resolver(fdt, fdta, target, NULL, NULL); +} diff --git a/libfdt/libfdt.h b/libfdt/libfdt.h index 3ef29beb..5df115b7 100644 --- a/libfdt/libfdt.h +++ b/libfdt/libfdt.h @@ -2545,7 +2545,8 @@ int fdt_overlay_target_offset(const void *fdt, const = void *fdto, * @target: target node path * * fdt_addon_apply() will apply the given device tree addon on the given t= arget - * node in base device tree. + * node in base device tree. fdt_addon_apply() uses the default resolver to + * resolve symbols. * * Expect the base device tree to be modified, even if the function * returns an error. @@ -2570,6 +2571,101 @@ int fdt_overlay_target_offset(const void *fdt, cons= t void *fdto, */ int fdt_addon_apply(void *fdt, void *fdta, const char *target); =20 +#ifndef SWIG /* Not available in Python */ +struct fdt_addon_resolver_ops { + /** + * Validate function (optional) + * @priv: Private data + * @fdt: fdt blob to look for validation + * @target_node: Target node offset the addon is applied to + * + * If non NULL, this function is called soon when an addon is applied + * and allows the resolver to perform some internal checks. If NULL, + * no resolver validation takes place and the applying process continues + * its operations. + * + * Return 0 if the validation of the resolver succeed. Negative error + * code on failure. On failure, the addon applying process is aborted. + * and the negative error code returned by this function is returned from + * the function applying the addon. + */ + int (*validate)(void *priv, const void *fdt, int target_node); + + /** + * Resolve function (mandatory) + * @priv: Private data + * @fdt: fdt blob to look for importsym matching node + * @target_node: Target node offset the addon is applied to + * @importsym_name: Import symbol name + * @importsym_compatible: Import symbol compatible string + * + * Return the node offset in fdt blob of the node matching the import + * symbol (identified by its name and compatible string) after the + * resolution on success. Negative error code on failure. + */ + int (*resolve)(void *priv, const void *fdt, int target_node, + const char *importsym_name, + const char *importsym_compatible); +}; + +/** + * fdt_resolve_default - Default libfdt resolver. + * @fdt: base device tree blob + * @target_node: Target node offset in the base device tree blob containing + * the exported symbols used for the resolution. + * @importsym_name: Import symbol name + * @importsym_compatible: Import symbol compatible string + * + * The default libfdt resolver search for a matching node in export symbols + * available at the @target_node. The @importsym_compatible string is not = used. + * + * returns: + * offset of the node matching the symbol after the resolution on suc= cess. + * Negative error code on failure. + */ +int fdt_addon_resolve_default(const void *fdt, int target_node, + const char *importsym_name, + const char *importsym_compatible); + + +/** + * fdt_addon_apply_resolver - Applies a DT addon on a base DT using the pr= ovided + * revolver. + * @fdt: pointer to the base device tree blob + * @fdta: pointer to the device tree addon blob + * @target: target node path + * @resolver_ops: Resolver operations to use, NULL to use the default reso= lver. + * @resolver_priv: Private data passed to function provided by resolver_ops + * + * fdt_addon_apply() will apply the given device tree addon on the given t= arget + * node in base device tree. + * + * Expect the base device tree to be modified, even if the function + * returns an error. + * + * returns: + * 0, on success + * -FDT_ERR_NOSPACE, there's not enough space in the base device tree + * -FDT_ERR_NOTFOUND, the overlay points to some nonexistent nodes or + * properties in the base DT + * -FDT_ERR_BADPHANDLE, + * -FDT_ERR_BADOVERLAY, + * -FDT_ERR_NOPHANDLES, + * -FDT_ERR_INTERNAL, + * -FDT_ERR_BADLAYOUT, + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADOFFSET, + * -FDT_ERR_BADPATH, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_TRUNCATED, standard meanings + */ +int fdt_addon_apply_resolver(void *fdt, void *fdta, const char *target, + const struct fdt_addon_resolver_ops *resolver_ops, + void *resolver_priv); +#endif /* SWIG */ + /**********************************************************************/ /* Debugging / informational functions */ /**********************************************************************/ diff --git a/libfdt/version.lds b/libfdt/version.lds index 74925ac0..0fa3490c 100644 --- a/libfdt/version.lds +++ b/libfdt/version.lds @@ -84,6 +84,8 @@ LIBFDT_1.2 { fdt_get_symbol; fdt_get_symbol_namelen; fdt_addon_apply; + fdt_addon_apply_resolver; + fdt_addon_resolve_default; local: *; }; --=20 2.55.0 From nobody Mon Sep 28 04:49:03 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DFD45429825; Wed, 26 Aug 2026 09:54:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738091; cv=none; b=N1PJWU8ECOruYZRtbUkEhHPGDMio1KglyAd0XVuTjzK4ZkB3fec2lBbHWEDBHLF2DMMTwyMK/Qrh4Y2TcFyW+jFX5beUlfQpKgBMFfTKUjdaolGrzPLxxYvK6pCve67oGc2IKV7iDLGUtUdvMBCYLj2rOwcjWq+avEwtfdPe0Hw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787738091; c=relaxed/simple; bh=08K8z7E2qT/i37KcXePY4tvqCh0QxUUtG1GgEWhELc4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=IbEo4NwLh5G9pGdHskvCejP205TqSQ3UAV4IZl1MfqJeX9/hOOy13OQFnaFzFJc5gxhSnOUQwRfE0zTd8YeJYA6S0qAWw2m7ryyay7yy3Eut6CdUkAtJZ54WtafvEMxBVIrjGo/6FE/8wbAP7IrLKcvVyOLFap2nAMN56dA/WHA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=K2y2+lAe; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="K2y2+lAe" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id 7918A4E413BF; Wed, 26 Aug 2026 09:54:47 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 4D72B604EC; Wed, 26 Aug 2026 09:54:47 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id B896611C7AD70; Wed, 26 Aug 2026 11:54:44 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1787738086; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=7VoJl6dLG+BIoVyuXucMhaeyw2jV/tYSa8t+aTz27nM=; b=K2y2+lAepwZ31AggaRYfOaKyUH8LqSWz5D0EE+xpUGpJSrdirwDvtUOLhureYujtVbY1YM +TeNgDu6mvcGyr24X4OWkdLipkhULFEf3XzM4wPLgrbls3EY5OIxNN8kg6zfNMzGAhZLTL r2dbsmZCbew4RpFIIUuRWorsCgudi/Y0Vzapm6T9mqYDDSg+q/WIA+EQbdgDbogxkL3wJK ruq4Z7+lVCZOWHiMiIB5L635eMzOIRWqa5c10AHPcXnwcpvTMSw9IX6oI1tOxBkFGykGym 8Y9dt9xVOmQlCCulc/RtOIudl5fajqU7wUqj2aQhYU7QkhvZj3wsdIKXwAiE1w== From: Herve Codina To: David Gibson , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Laurent Pinchart , David Lechner , Ayush Singh , Geert Uytterhoeven , devicetree-compiler@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree-spec@vger.kernel.org, Hui Pu , Ian Ray , Luca Ceresoli , Thomas Petazzoni , Herve Codina Subject: [RFC PATCH v2 74/74] fdtaddon: Add a simple external resolver Date: Wed, 26 Aug 2026 11:49:43 +0200 Message-ID: <20260826094950.1088288-75-herve.codina@bootlin.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260826094950.1088288-1-herve.codina@bootlin.com> References: <20260826094950.1088288-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" libfdt allows to use an external resolver to resolve import symbols when an addon is applied. Add a simple external resolver in fdtaddon based on export symbols given on the tool command line (-e or --export). Those export symbols are used to mach import symbols (match by names) in order to resolved them. Two syntaxes are available for the -e or --export option: - Export by symbol (--export '=3D&') The export symbol is created an reference the node identified by . This has to be an exported symbol available at the node the addon is applied to. For instance, assuming this base device-tree fragment in the base device-tree: target { /export/ bar: &{/somewhere/bar-node}; } The '--target "/target" --export "foo=3D&bar"' will export foo as an exported symbol pointing to /somewhere/bar-node. An addon can import the foo symbol an it will be resolved to /somewhere/bar-node. - Export by path (--export '=3D&{}') The export symbol is created and reference the node available at the given . This path must be an absolute path. The '--target "/target" --export "foo=3D&{/somewhere/baz-node}"' export the symbol 'foo' referencing the node at /somewhere/baz-node. Here again, an addon importing the foo symbol will see this foo symbol resolved to /somewhere/baz-node. It is worth noting that /somewhere/baz-node may not be referenced in the base device-tree. Indeed, /export/ could not be present to reference this node. If the node is not referenced, dtc will not create its phandle value and the resolution will failed. For this reason having a /export/ keyword at the target node pointing to the /somewhere/baz-node node is still recommended. This will ensure that dtc will create the needed phandle. Signed-off-by: Herve Codina --- fdtaddon.c | 232 +++++++++++++++++- ...n_custom_resolver_node_a-merged.dtb.expect | 39 +++ ...n_addon_custom_resolver_node_a.dtba.expect | 15 ++ ...fdtaddon_addon_custom_resolver_node_a.dtsa | 22 ++ ..._custom_resolver_node_ab-merged.dtb.expect | 42 ++++ ..._addon_custom_resolver_node_ab.dtba.expect | 21 ++ ...dtaddon_addon_custom_resolver_node_ab.dtsa | 29 +++ .../fdtaddon_base_custom_resolver.dtb.expect | 33 +++ tests/fdtaddon_base_custom_resolver.dts | 52 ++++ tests/run_tests.sh | 25 ++ 10 files changed, 503 insertions(+), 7 deletions(-) create mode 100644 tests/fdtaddon_addon_custom_resolver_node_a-merged.dtb.= expect create mode 100644 tests/fdtaddon_addon_custom_resolver_node_a.dtba.expect create mode 100644 tests/fdtaddon_addon_custom_resolver_node_a.dtsa create mode 100644 tests/fdtaddon_addon_custom_resolver_node_ab-merged.dtb= .expect create mode 100644 tests/fdtaddon_addon_custom_resolver_node_ab.dtba.expect create mode 100644 tests/fdtaddon_addon_custom_resolver_node_ab.dtsa create mode 100644 tests/fdtaddon_base_custom_resolver.dtb.expect create mode 100644 tests/fdtaddon_base_custom_resolver.dts diff --git a/fdtaddon.c b/fdtaddon.c index 037851d9..80073860 100644 --- a/fdtaddon.c +++ b/fdtaddon.c @@ -22,20 +22,215 @@ static const char usage_synopsis[] =3D "apply an addon to a base blob\n" " fdtaddon "; -static const char usage_short_opts[] =3D "i:o:t:v" USAGE_COMMON_SHORT_OPTS; +static const char usage_short_opts[] =3D "i:o:t:e:v" USAGE_COMMON_SHORT_OP= TS; static const struct option usage_long_opts[] =3D { { "input", required_argument, NULL, 'i' }, { "output", required_argument, NULL, 'o' }, { "target", required_argument, NULL, 't' }, + { "export", required_argument, NULL, 'e' }, { "verbose", no_argument, NULL, 'v' }, USAGE_COMMON_LONG_OPTS, }; static const char *const usage_opts_help[] =3D { "Input base DT blob", - "Output DT blob", "Target node", + "Output DT blob", + "Target node", + "Custom export symbol" + "\n\tMultiple --export or -e can be present in order to export= multiple symbols." + "\n\tThe following syntaxes are supported:" + "\n\t - Defines a export symbol pointing to a node using its = symbol" + "\n\t --export '=3D&'" + "\n\t - Defines a export symbol pointing to a node by path" + "\n\t --export '=3D&{path_to_node}'", "Verbose messages", USAGE_COMMON_OPTS_HELP }; =20 -static void *do_apply(void *base, const void *addon, const char *target) +struct export_symbol { + char *name; + char *ref; + struct export_symbol *next; +}; + +struct resolver { + struct export_symbol *export_list; + int verbose; +}; + +static void resolver_init(struct resolver *resolver) +{ + memset(resolver, 0, sizeof(*resolver)); +} + +static void resolver_exit(struct resolver *resolver) +{ + struct export_symbol *e, *next; + + e =3D resolver->export_list; + while (e) { + free(e->name); + free(e->ref); + next =3D e->next; + free(e); + e =3D next; + } +} + +static char *str_strip_spaces(char *str) +{ + char *strip, *tmp; + + tmp =3D str; + strip =3D str; + while (*tmp !=3D '\0') { + if (*tmp !=3D ' ' && *tmp !=3D '\t') + *(strip++) =3D *tmp; + tmp++; + } + *strip =3D *tmp; + return str; +} + +static char *str_split(char *str, char token, char **remaining) +{ + char *tmp; + + tmp =3D strchr(str, token); + if (!tmp) + return NULL; + *(tmp++) =3D '\0'; /* Split the string at token char */ + + *remaining =3D tmp; + return str; +} + +static int resolver_parse_export(struct resolver *resolver, const char *ar= g) +{ + struct export_symbol *export_symbol; + const char *name, *ref; + char *tmp, *strip; + + strip =3D xstrdup(arg); + strip =3D str_strip_spaces(strip); + + tmp =3D strip; + + name =3D str_split(tmp, '=3D', &tmp); + if (!name || !strlen(name)) + goto fail; + + if (*(tmp++) !=3D '&') + goto fail; + if (*tmp =3D=3D '\0') + goto fail; + + if (*tmp =3D=3D '{') { + /* ref by path : &{/xxxx/yyyy} */ + tmp++; + if (*(tmp) !=3D '/') + goto fail; + + ref =3D str_split(tmp, '}', &tmp); + if (!ref || !strlen(ref)) + goto fail; + if (*tmp !=3D '\0') + goto fail; + } else { + /* ref by symbol : &xxxx */ + ref =3D tmp; + if (!strlen(ref)) + goto fail; + } + + export_symbol =3D xmalloc(sizeof(*export_symbol)); + export_symbol->name =3D xstrdup(name); + export_symbol->ref =3D xstrdup(ref); + free(strip); + + export_symbol->next =3D resolver->export_list; + resolver->export_list =3D export_symbol; + return 0; +fail: + free(strip); + return -1; +} + +static int resolver_resolve(void *priv, const void *fdt, int target_node, + const char *importsym_name, + const char *importsym_compatible) +{ + struct resolver *resolver =3D priv; + int node =3D -FDT_ERR_NOTFOUND; + struct export_symbol *e; + + e =3D resolver->export_list; + while (e) { + if (strcmp(importsym_name, e->name)) { + e =3D e->next; + continue; + } + + if (e->ref[0] =3D=3D '/') + node =3D fdt_path_offset(fdt, e->ref); + else + node =3D fdt_addon_resolve_default(fdt, target_node, e->ref, + NULL); + + return node; + } + return -FDT_ERR_NOTFOUND; +} + +static int resolver_validate(void *priv, const void *fdt, int target_node) +{ + struct resolver *resolver =3D priv; + struct export_symbol *e; + uint32_t phandle; + int node; + + /* + * Check the export_symbol list. The related node must exist in the fdt + * blob and must have a valid phandle value. + * + * Simply revolve all export symbols available in the list to validate + * that they can be resolved. + */ + + e =3D resolver->export_list; + while (e) { + node =3D resolver_resolve(resolver, fdt, target_node, e->name, + NULL); + if (node < 0) { + fprintf(stderr, + "\nExport symbol '%s': Cannot find reference '%s'\n", + e->name, e->ref); + return node; + } + + phandle =3D fdt_get_phandle(fdt, node); + if ((phandle =3D=3D 0) || (phandle =3D=3D ~0U)) { + fprintf(stderr, + "\nExport symbol '%s', reference '%s': Invalid phandle\n", + e->name, e->ref); + return -FDT_ERR_BADPHANDLE; + } + + if (resolver->verbose) { + printf("Export symbol '%s', ref '%s' -> node at 0x%x, phandle 0x%"PRIx3= 2"\n", + e->name, e->ref, node, phandle); + } + + e =3D e->next; + } + return 0; +} + +static const struct fdt_addon_resolver_ops resolver_ops =3D { + .validate =3D resolver_validate, + .resolve =3D resolver_resolve, +}; + + +static void *do_apply(void *base, const void *addon, const char *target, + struct resolver *resolver) { void *tmp_merged; void *tmp_addon; @@ -72,7 +267,12 @@ static void *do_apply(void *base, const void *addon, co= nst char *target) goto fail; } =20 - ret =3D fdt_addon_apply(tmp_merged, tmp_addon, target); + if (resolver) + ret =3D fdt_addon_apply_resolver(tmp_merged, tmp_addon, target, + &resolver_ops, resolver); + else + ret =3D fdt_addon_apply(tmp_merged, tmp_addon, target); + if (ret) { fprintf(stderr, "\nFailed to apply %s\n", fdt_strerror(ret)); goto fail; @@ -88,7 +288,8 @@ fail: } =20 static int do_fdtaddon(const char *input_filename, const char *output_file= name, - const char *addon_filename, const char *target) + const char *addon_filename, const char *target, + struct resolver *resolver) { void *base_blob =3D NULL; void *addon_blob =3D NULL; @@ -122,7 +323,7 @@ static int do_fdtaddon(const char *input_filename, cons= t char *output_filename, } =20 /* apply the addon */ - merged_blob =3D do_apply(base_blob, addon_blob, target); + merged_blob =3D do_apply(base_blob, addon_blob, target, resolver); if (!merged_blob) goto out_err; =20 @@ -146,7 +347,12 @@ int main(int argc, char *argv[]) char *addon_filename =3D NULL; const char *target =3D NULL; int verbose; + bool use_resolver =3D false; + struct resolver resolver; int opt; + int ret; + + resolver_init(&resolver); =20 while ((opt =3D util_getopt_long()) !=3D EOF) { switch (opt) { @@ -164,6 +370,13 @@ int main(int argc, char *argv[]) case 't': target =3D optarg; break; + case 'e': + if (resolver_parse_export(&resolver, optarg) < 0) { + resolver_exit(&resolver); + return 1; + } + use_resolver =3D true; + break; } } =20 @@ -190,7 +403,12 @@ int main(int argc, char *argv[]) printf("addon =3D %s\n", addon_filename); } =20 - if (do_fdtaddon(input_filename, output_filename, addon_filename, target)) + resolver.verbose =3D verbose; + + ret =3D do_fdtaddon(input_filename, output_filename, addon_filename, targ= et, + use_resolver ? &resolver : NULL); + resolver_exit(&resolver); + if (ret) return 1; =20 return 0; diff --git a/tests/fdtaddon_addon_custom_resolver_node_a-merged.dtb.expect = b/tests/fdtaddon_addon_custom_resolver_node_a-merged.dtb.expect new file mode 100644 index 00000000..637387a7 --- /dev/null +++ b/tests/fdtaddon_addon_custom_resolver_node_a-merged.dtb.expect @@ -0,0 +1,39 @@ +/dts-v1/; + +/ { + base-node { + sub-node { + prop =3D <0x00000000>; + phandle =3D <0x00000003>; + addon-node { + prop =3D "other"; + }; + }; + }; + somewhere { + // [FDT_EXPORT_SYM] 'node_a1' -> phandle 0x00000001 + // [FDT_EXPORT_SYM] 'node_a2' -> phandle 0x00000002 + // [FDT_EXPORT_SYM] 'sub_node' -> phandle 0x00000003 + // [FDT_EXPORT_SYM] 'node_b1' -> phandle 0x00000004 + // [FDT_EXPORT_SYM] 'node_b2' -> phandle 0x00000005 + node-a1 { + compatible =3D "abc,aaa"; + phandle =3D <0x00000001>; + addon-node { + prop =3D "node_a"; + }; + }; + node-a2 { + compatible =3D "abc,aaa"; + phandle =3D <0x00000002>; + }; + node-b1 { + compatible =3D "abc,bbb"; + phandle =3D <0x00000004>; + }; + node-b2 { + compatible =3D "abc,bbb"; + phandle =3D <0x00000005>; + }; + }; +}; diff --git a/tests/fdtaddon_addon_custom_resolver_node_a.dtba.expect b/test= s/fdtaddon_addon_custom_resolver_node_a.dtba.expect new file mode 100644 index 00000000..60104190 --- /dev/null +++ b/tests/fdtaddon_addon_custom_resolver_node_a.dtba.expect @@ -0,0 +1,15 @@ +/dts-v1/; +/addon/; + +// [FDT_IMPORT_SYM] 'node_a' (abc,aaa) +// [FDT_IMPORT_SYM] 'other' () +&node_a { + addon-node { + prop =3D "node_a"; + }; +}; +&other { + addon-node { + prop =3D "other"; + }; +}; diff --git a/tests/fdtaddon_addon_custom_resolver_node_a.dtsa b/tests/fdtad= don_addon_custom_resolver_node_a.dtsa new file mode 100644 index 00000000..d400c4f2 --- /dev/null +++ b/tests/fdtaddon_addon_custom_resolver_node_a.dtsa @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) +/* + * Copyright (C) 2026 Bootlin + */ + +/dts-v1/; +/addon/; + +/import/ node_a: "abc,aaa"; +/import/ other: ""; + +&node_a { + addon-node { + prop =3D "node_a"; + }; +}; + +&other { + addon-node { + prop =3D "other"; + }; +}; diff --git a/tests/fdtaddon_addon_custom_resolver_node_ab-merged.dtb.expect= b/tests/fdtaddon_addon_custom_resolver_node_ab-merged.dtb.expect new file mode 100644 index 00000000..40678266 --- /dev/null +++ b/tests/fdtaddon_addon_custom_resolver_node_ab-merged.dtb.expect @@ -0,0 +1,42 @@ +/dts-v1/; + +/ { + base-node { + sub-node { + prop =3D <0x00000000>; + phandle =3D <0x00000003>; + addon-node { + prop =3D "other"; + }; + }; + }; + somewhere { + // [FDT_EXPORT_SYM] 'node_a1' -> phandle 0x00000001 + // [FDT_EXPORT_SYM] 'node_a2' -> phandle 0x00000002 + // [FDT_EXPORT_SYM] 'sub_node' -> phandle 0x00000003 + // [FDT_EXPORT_SYM] 'node_b1' -> phandle 0x00000004 + // [FDT_EXPORT_SYM] 'node_b2' -> phandle 0x00000005 + node-a1 { + compatible =3D "abc,aaa"; + phandle =3D <0x00000001>; + }; + node-a2 { + compatible =3D "abc,aaa"; + phandle =3D <0x00000002>; + addon-node { + prop =3D "node_a"; + }; + }; + node-b1 { + compatible =3D "abc,bbb"; + phandle =3D <0x00000004>; + addon-node { + prop =3D "node_b"; + }; + }; + node-b2 { + compatible =3D "abc,bbb"; + phandle =3D <0x00000005>; + }; + }; +}; diff --git a/tests/fdtaddon_addon_custom_resolver_node_ab.dtba.expect b/tes= ts/fdtaddon_addon_custom_resolver_node_ab.dtba.expect new file mode 100644 index 00000000..04116f47 --- /dev/null +++ b/tests/fdtaddon_addon_custom_resolver_node_ab.dtba.expect @@ -0,0 +1,21 @@ +/dts-v1/; +/addon/; + +// [FDT_IMPORT_SYM] 'node_a' (abc,aaa) +// [FDT_IMPORT_SYM] 'node_b' (abc,bbb) +// [FDT_IMPORT_SYM] 'other' () +&node_a { + addon-node { + prop =3D "node_a"; + }; +}; +&node_b { + addon-node { + prop =3D "node_b"; + }; +}; +&other { + addon-node { + prop =3D "other"; + }; +}; diff --git a/tests/fdtaddon_addon_custom_resolver_node_ab.dtsa b/tests/fdta= ddon_addon_custom_resolver_node_ab.dtsa new file mode 100644 index 00000000..74a9cab3 --- /dev/null +++ b/tests/fdtaddon_addon_custom_resolver_node_ab.dtsa @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) +/* + * Copyright (C) 2026 Bootlin + */ + +/dts-v1/; +/addon/; + +/import/ node_a: "abc,aaa"; +/import/ node_b: "abc,bbb"; +/import/ other: ""; + +&node_a { + addon-node { + prop =3D "node_a"; + }; +}; + +&node_b { + addon-node { + prop =3D "node_b"; + }; +}; + +&other { + addon-node { + prop =3D "other"; + }; +}; diff --git a/tests/fdtaddon_base_custom_resolver.dtb.expect b/tests/fdtaddo= n_base_custom_resolver.dtb.expect new file mode 100644 index 00000000..4a76672f --- /dev/null +++ b/tests/fdtaddon_base_custom_resolver.dtb.expect @@ -0,0 +1,33 @@ +/dts-v1/; + +/ { + base-node { + sub-node { + prop =3D <0x00000000>; + phandle =3D <0x00000003>; + }; + }; + somewhere { + // [FDT_EXPORT_SYM] 'node_a1' -> phandle 0x00000001 + // [FDT_EXPORT_SYM] 'node_a2' -> phandle 0x00000002 + // [FDT_EXPORT_SYM] 'sub_node' -> phandle 0x00000003 + // [FDT_EXPORT_SYM] 'node_b1' -> phandle 0x00000004 + // [FDT_EXPORT_SYM] 'node_b2' -> phandle 0x00000005 + node-a1 { + compatible =3D "abc,aaa"; + phandle =3D <0x00000001>; + }; + node-a2 { + compatible =3D "abc,aaa"; + phandle =3D <0x00000002>; + }; + node-b1 { + compatible =3D "abc,bbb"; + phandle =3D <0x00000004>; + }; + node-b2 { + compatible =3D "abc,bbb"; + phandle =3D <0x00000005>; + }; + }; +}; diff --git a/tests/fdtaddon_base_custom_resolver.dts b/tests/fdtaddon_base_= custom_resolver.dts new file mode 100644 index 00000000..b92475b2 --- /dev/null +++ b/tests/fdtaddon_base_custom_resolver.dts @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) +/* + * Copyright (C) 2026 Bootlin + */ + +/dts-v1/; + +/ { + base-node { + sub_node: sub-node { + prop =3D <0>; + }; + }; + + somewhere { + /* + * Nodes are referenced, either by path or by symbol, by the + * custom resolver available in the fdt_addon tool. + * + * Nodes referenced by symbols need to have the symbol exported + * here (i.e. in the node where the addon is applied to). + * + * For nodes referenced by path by the custom resolver, this is + * not strictly necessary but we need to ensure that DTC will + * create the phandle property for those nodes. + * + * DTC creates phandles when a node is referenced in the dts + * compiled by DTC. Using the /export/ keyword is a good way + * to ensure this reference and so to have the phandle created. + * Even if the exported symbol is not used (path instead of + * symbol), this ensures the phandle creation by DTC. + */ + /export/ node_a1: &node_a1; + /export/ node_a2: &node_a2; + /export/ sub_node: &sub_node; + /export/ node_b1: &node_b1; + /export/ node_b2: &node_b2; + + node_a1: node-a1 { + compatible =3D "abc,aaa"; + }; + node_a2: node-a2 { + compatible =3D "abc,aaa"; + }; + node_b1: node-b1 { + compatible =3D "abc,bbb"; + }; + node_b2: node-b2 { + compatible =3D "abc,bbb"; + }; + }; +}; diff --git a/tests/run_tests.sh b/tests/run_tests.sh index 664ebf5d..6f4f8386 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -1369,6 +1369,31 @@ fdtaddon_tests() { run_dtc_test -I dtb -O dts -o fdtaddon_stack_2nd-merged.dtb.dts fdtaddon_= stack_2nd-merged.dtb check_dts fdtaddon_stack_2nd-merged.dtb.dts =20 + # Custom resolver + run_dtc_test -I dts -O dtb -o fdtaddon_base_custom_resolver.dtb "$SRCDIR/= fdtaddon_base_custom_resolver.dts" + check_dtb fdtaddon_base_custom_resolver.dtb + + run_dtc_test -I dts -O dtb -o fdtaddon_addon_custom_resolver_node_a.dtba = "$SRCDIR/fdtaddon_addon_custom_resolver_node_a.dtsa" + check_dtb fdtaddon_addon_custom_resolver_node_a.dtba + + run_fdtaddon_test -i fdtaddon_base_custom_resolver.dtb -o fdtaddon_addon_= custom_resolver_node_a-merged.dtb \ + -t "/somewhere" \ + -e "node_a=3D&node_a1" \ + -e "other=3D&{/base-node/sub-node}" \ + fdtaddon_addon_custom_resolver_node_a.dtba + check_dtb fdtaddon_addon_custom_resolver_node_a-merged.dtb + + run_dtc_test -I dts -O dtb -o fdtaddon_addon_custom_resolver_node_ab.dtba= "$SRCDIR/fdtaddon_addon_custom_resolver_node_ab.dtsa" + check_dtb fdtaddon_addon_custom_resolver_node_ab.dtba + + run_fdtaddon_test -i fdtaddon_base_custom_resolver.dtb -o fdtaddon_addon_= custom_resolver_node_ab-merged.dtb \ + -t "/somewhere" \ + -e "node_a=3D&{/somewhere/node-a2}" \ + -e "node_b=3D&node_b1" \ + -e "other=3D&sub_node" \ + fdtaddon_addon_custom_resolver_node_ab.dtba + check_dtb fdtaddon_addon_custom_resolver_node_ab-merged.dtb + # More realistic dts and dtsa input files run_dtc_test -I dts -O dtb -o fdtaddon_realistic_base.dtb "$SRCDIR/fdtadd= on_realistic_base.dts" check_dtb fdtaddon_realistic_base.dtb --=20 2.55.0