1218e1b3dSMauro Carvalho Chehab.. SPDX-License-Identifier: GPL-2.0
2218e1b3dSMauro Carvalho Chehab
37248213cSRob Herring=================================
47248213cSRob HerringOpen Firmware Devicetree Unittest
57248213cSRob Herring=================================
6218e1b3dSMauro Carvalho Chehab
7218e1b3dSMauro Carvalho ChehabAuthor: Gaurav Minocha <gaurav.minocha.os@gmail.com>
8218e1b3dSMauro Carvalho Chehab
9218e1b3dSMauro Carvalho Chehab1. Introduction
10218e1b3dSMauro Carvalho Chehab===============
11218e1b3dSMauro Carvalho Chehab
12218e1b3dSMauro Carvalho ChehabThis document explains how the test data required for executing OF unittest
13218e1b3dSMauro Carvalho Chehabis attached to the live tree dynamically, independent of the machine's
14218e1b3dSMauro Carvalho Chehabarchitecture.
15218e1b3dSMauro Carvalho Chehab
16218e1b3dSMauro Carvalho ChehabIt is recommended to read the following documents before moving ahead.
17218e1b3dSMauro Carvalho Chehab
18218e1b3dSMauro Carvalho Chehab(1) Documentation/devicetree/usage-model.rst
19218e1b3dSMauro Carvalho Chehab(2) http://www.devicetree.org/Device_Tree_Usage
20218e1b3dSMauro Carvalho Chehab
21218e1b3dSMauro Carvalho ChehabOF Selftest has been designed to test the interface (include/linux/of.h)
22218e1b3dSMauro Carvalho Chehabprovided to device driver developers to fetch the device information..etc.
23218e1b3dSMauro Carvalho Chehabfrom the unflattened device tree data structure. This interface is used by
24218e1b3dSMauro Carvalho Chehabmost of the device drivers in various use cases.
25218e1b3dSMauro Carvalho Chehab
26218e1b3dSMauro Carvalho Chehab
278e4296c2SFrank Rowand2. Verbose Output (EXPECT)
288e4296c2SFrank Rowand==========================
298e4296c2SFrank Rowand
308e4296c2SFrank RowandIf unittest detects a problem it will print a warning or error message to
318e4296c2SFrank Rowandthe console.  Unittest also triggers warning and error messages from other
328e4296c2SFrank Rowandkernel code as a result of intentionally bad unittest data.  This has led
338e4296c2SFrank Rowandto confusion as to whether the triggered messages are an expected result
348e4296c2SFrank Rowandof a test or whether there is a real problem that is independent of unittest.
358e4296c2SFrank Rowand
368e4296c2SFrank Rowand'EXPECT \ : text' (begin) and 'EXPECT / : text' (end) messages have been
378e4296c2SFrank Rowandadded to unittest to report that a warning or error is expected.  The
388e4296c2SFrank Rowandbegin is printed before triggering the warning or error, and the end is
398e4296c2SFrank Rowandprinted after triggering the warning or error.
408e4296c2SFrank Rowand
418e4296c2SFrank RowandThe EXPECT messages result in very noisy console messages that are difficult
428e4296c2SFrank Rowandto read.  The script scripts/dtc/of_unittest_expect was created to filter
438e4296c2SFrank Rowandthis verbosity and highlight mismatches between triggered warnings and
448e4296c2SFrank Rowanderrors vs expected warnings and errors.  More information is available
458e4296c2SFrank Rowandfrom 'scripts/dtc/of_unittest_expect --help'.
468e4296c2SFrank Rowand
478e4296c2SFrank Rowand
488e4296c2SFrank Rowand3. Test-data
49218e1b3dSMauro Carvalho Chehab============
50218e1b3dSMauro Carvalho Chehab
51218e1b3dSMauro Carvalho ChehabThe Device Tree Source file (drivers/of/unittest-data/testcases.dts) contains
52218e1b3dSMauro Carvalho Chehabthe test data required for executing the unit tests automated in
53218e1b3dSMauro Carvalho Chehabdrivers/of/unittest.c. Currently, following Device Tree Source Include files
54218e1b3dSMauro Carvalho Chehab(.dtsi) are included in testcases.dts::
55218e1b3dSMauro Carvalho Chehab
56218e1b3dSMauro Carvalho Chehab    drivers/of/unittest-data/tests-interrupts.dtsi
57218e1b3dSMauro Carvalho Chehab    drivers/of/unittest-data/tests-platform.dtsi
58218e1b3dSMauro Carvalho Chehab    drivers/of/unittest-data/tests-phandle.dtsi
59218e1b3dSMauro Carvalho Chehab    drivers/of/unittest-data/tests-match.dtsi
60218e1b3dSMauro Carvalho Chehab
61218e1b3dSMauro Carvalho ChehabWhen the kernel is build with OF_SELFTEST enabled, then the following make
62218e1b3dSMauro Carvalho Chehabrule::
63218e1b3dSMauro Carvalho Chehab
64218e1b3dSMauro Carvalho Chehab    $(obj)/%.dtb: $(src)/%.dts FORCE
65218e1b3dSMauro Carvalho Chehab	    $(call if_changed_dep, dtc)
66218e1b3dSMauro Carvalho Chehab
67218e1b3dSMauro Carvalho Chehabis used to compile the DT source file (testcases.dts) into a binary blob
68218e1b3dSMauro Carvalho Chehab(testcases.dtb), also referred as flattened DT.
69218e1b3dSMauro Carvalho Chehab
70218e1b3dSMauro Carvalho ChehabAfter that, using the following rule the binary blob above is wrapped as an
71218e1b3dSMauro Carvalho Chehabassembly file (testcases.dtb.S)::
72218e1b3dSMauro Carvalho Chehab
73218e1b3dSMauro Carvalho Chehab    $(obj)/%.dtb.S: $(obj)/%.dtb
74218e1b3dSMauro Carvalho Chehab	    $(call cmd, dt_S_dtb)
75218e1b3dSMauro Carvalho Chehab
76218e1b3dSMauro Carvalho ChehabThe assembly file is compiled into an object file (testcases.dtb.o), and is
77218e1b3dSMauro Carvalho Chehablinked into the kernel image.
78218e1b3dSMauro Carvalho Chehab
79218e1b3dSMauro Carvalho Chehab
808e4296c2SFrank Rowand3.1. Adding the test data
81218e1b3dSMauro Carvalho Chehab-------------------------
82218e1b3dSMauro Carvalho Chehab
83218e1b3dSMauro Carvalho ChehabUn-flattened device tree structure:
84218e1b3dSMauro Carvalho Chehab
85218e1b3dSMauro Carvalho ChehabUn-flattened device tree consists of connected device_node(s) in form of a tree
86218e1b3dSMauro Carvalho Chehabstructure described below::
87218e1b3dSMauro Carvalho Chehab
88218e1b3dSMauro Carvalho Chehab    // following struct members are used to construct the tree
89218e1b3dSMauro Carvalho Chehab    struct device_node {
90218e1b3dSMauro Carvalho Chehab	...
91218e1b3dSMauro Carvalho Chehab	struct  device_node *parent;
92218e1b3dSMauro Carvalho Chehab	struct  device_node *child;
93218e1b3dSMauro Carvalho Chehab	struct  device_node *sibling;
94218e1b3dSMauro Carvalho Chehab	...
95218e1b3dSMauro Carvalho Chehab    };
96218e1b3dSMauro Carvalho Chehab
97218e1b3dSMauro Carvalho ChehabFigure 1, describes a generic structure of machine's un-flattened device tree
98218e1b3dSMauro Carvalho Chehabconsidering only child and sibling pointers. There exists another pointer,
99218e1b3dSMauro Carvalho Chehab``*parent``, that is used to traverse the tree in the reverse direction. So, at
100218e1b3dSMauro Carvalho Chehaba particular level the child node and all the sibling nodes will have a parent
101218e1b3dSMauro Carvalho Chehabpointer pointing to a common node (e.g. child1, sibling2, sibling3, sibling4's
102218e1b3dSMauro Carvalho Chehabparent points to root node)::
103218e1b3dSMauro Carvalho Chehab
104218e1b3dSMauro Carvalho Chehab    root ('/')
105218e1b3dSMauro Carvalho Chehab    |
106218e1b3dSMauro Carvalho Chehab    child1 -> sibling2 -> sibling3 -> sibling4 -> null
107218e1b3dSMauro Carvalho Chehab    |         |           |           |
108218e1b3dSMauro Carvalho Chehab    |         |           |          null
109218e1b3dSMauro Carvalho Chehab    |         |           |
110218e1b3dSMauro Carvalho Chehab    |         |        child31 -> sibling32 -> null
111218e1b3dSMauro Carvalho Chehab    |         |           |          |
112218e1b3dSMauro Carvalho Chehab    |         |          null       null
113218e1b3dSMauro Carvalho Chehab    |         |
114218e1b3dSMauro Carvalho Chehab    |      child21 -> sibling22 -> sibling23 -> null
115218e1b3dSMauro Carvalho Chehab    |         |          |            |
116218e1b3dSMauro Carvalho Chehab    |        null       null         null
117218e1b3dSMauro Carvalho Chehab    |
118218e1b3dSMauro Carvalho Chehab    child11 -> sibling12 -> sibling13 -> sibling14 -> null
119218e1b3dSMauro Carvalho Chehab    |           |           |            |
120218e1b3dSMauro Carvalho Chehab    |           |           |           null
121218e1b3dSMauro Carvalho Chehab    |           |           |
122218e1b3dSMauro Carvalho Chehab    null        null       child131 -> null
123218e1b3dSMauro Carvalho Chehab			    |
124218e1b3dSMauro Carvalho Chehab			    null
125218e1b3dSMauro Carvalho Chehab
126218e1b3dSMauro Carvalho ChehabFigure 1: Generic structure of un-flattened device tree
127218e1b3dSMauro Carvalho Chehab
128218e1b3dSMauro Carvalho Chehab
129218e1b3dSMauro Carvalho ChehabBefore executing OF unittest, it is required to attach the test data to
130218e1b3dSMauro Carvalho Chehabmachine's device tree (if present). So, when selftest_data_add() is called,
131218e1b3dSMauro Carvalho Chehabat first it reads the flattened device tree data linked into the kernel image
132218e1b3dSMauro Carvalho Chehabvia the following kernel symbols::
133218e1b3dSMauro Carvalho Chehab
134218e1b3dSMauro Carvalho Chehab    __dtb_testcases_begin - address marking the start of test data blob
135218e1b3dSMauro Carvalho Chehab    __dtb_testcases_end   - address marking the end of test data blob
136218e1b3dSMauro Carvalho Chehab
137218e1b3dSMauro Carvalho ChehabSecondly, it calls of_fdt_unflatten_tree() to unflatten the flattened
138218e1b3dSMauro Carvalho Chehabblob. And finally, if the machine's device tree (i.e live tree) is present,
139218e1b3dSMauro Carvalho Chehabthen it attaches the unflattened test data tree to the live tree, else it
140218e1b3dSMauro Carvalho Chehabattaches itself as a live device tree.
141218e1b3dSMauro Carvalho Chehab
142218e1b3dSMauro Carvalho Chehabattach_node_and_children() uses of_attach_node() to attach the nodes into the
143218e1b3dSMauro Carvalho Chehablive tree as explained below. To explain the same, the test data tree described
144218e1b3dSMauro Carvalho Chehabin Figure 2 is attached to the live tree described in Figure 1::
145218e1b3dSMauro Carvalho Chehab
146218e1b3dSMauro Carvalho Chehab    root ('/')
147218e1b3dSMauro Carvalho Chehab	|
148218e1b3dSMauro Carvalho Chehab    testcase-data
149218e1b3dSMauro Carvalho Chehab	|
150218e1b3dSMauro Carvalho Chehab    test-child0 -> test-sibling1 -> test-sibling2 -> test-sibling3 -> null
151218e1b3dSMauro Carvalho Chehab	|               |                |                |
152218e1b3dSMauro Carvalho Chehab    test-child01      null             null             null
153218e1b3dSMauro Carvalho Chehab
154218e1b3dSMauro Carvalho Chehab
155218e1b3dSMauro Carvalho ChehabFigure 2: Example test data tree to be attached to live tree.
156218e1b3dSMauro Carvalho Chehab
157218e1b3dSMauro Carvalho ChehabAccording to the scenario above, the live tree is already present so it isn't
158218e1b3dSMauro Carvalho Chehabrequired to attach the root('/') node. All other nodes are attached by calling
159218e1b3dSMauro Carvalho Chehabof_attach_node() on each node.
160218e1b3dSMauro Carvalho Chehab
161218e1b3dSMauro Carvalho ChehabIn the function of_attach_node(), the new node is attached as the child of the
162218e1b3dSMauro Carvalho Chehabgiven parent in live tree. But, if parent already has a child then the new node
163218e1b3dSMauro Carvalho Chehabreplaces the current child and turns it into its sibling. So, when the testcase
164218e1b3dSMauro Carvalho Chehabdata node is attached to the live tree above (Figure 1), the final structure is
165218e1b3dSMauro Carvalho Chehabas shown in Figure 3::
166218e1b3dSMauro Carvalho Chehab
167218e1b3dSMauro Carvalho Chehab    root ('/')
168218e1b3dSMauro Carvalho Chehab    |
169218e1b3dSMauro Carvalho Chehab    testcase-data -> child1 -> sibling2 -> sibling3 -> sibling4 -> null
170218e1b3dSMauro Carvalho Chehab    |               |          |           |           |
171218e1b3dSMauro Carvalho Chehab    (...)             |          |           |          null
172218e1b3dSMauro Carvalho Chehab		    |          |         child31 -> sibling32 -> null
173218e1b3dSMauro Carvalho Chehab		    |          |           |           |
174218e1b3dSMauro Carvalho Chehab		    |          |          null        null
175218e1b3dSMauro Carvalho Chehab		    |          |
176218e1b3dSMauro Carvalho Chehab		    |        child21 -> sibling22 -> sibling23 -> null
177218e1b3dSMauro Carvalho Chehab		    |          |           |            |
178218e1b3dSMauro Carvalho Chehab		    |         null        null         null
179218e1b3dSMauro Carvalho Chehab		    |
180218e1b3dSMauro Carvalho Chehab		    child11 -> sibling12 -> sibling13 -> sibling14 -> null
181218e1b3dSMauro Carvalho Chehab		    |          |            |            |
182218e1b3dSMauro Carvalho Chehab		    null       null          |           null
183218e1b3dSMauro Carvalho Chehab					    |
184218e1b3dSMauro Carvalho Chehab					    child131 -> null
185218e1b3dSMauro Carvalho Chehab					    |
186218e1b3dSMauro Carvalho Chehab					    null
187218e1b3dSMauro Carvalho Chehab    -----------------------------------------------------------------------
188218e1b3dSMauro Carvalho Chehab
189218e1b3dSMauro Carvalho Chehab    root ('/')
190218e1b3dSMauro Carvalho Chehab    |
191218e1b3dSMauro Carvalho Chehab    testcase-data -> child1 -> sibling2 -> sibling3 -> sibling4 -> null
192218e1b3dSMauro Carvalho Chehab    |               |          |           |           |
193218e1b3dSMauro Carvalho Chehab    |             (...)      (...)       (...)        null
194218e1b3dSMauro Carvalho Chehab    |
195218e1b3dSMauro Carvalho Chehab    test-sibling3 -> test-sibling2 -> test-sibling1 -> test-child0 -> null
196218e1b3dSMauro Carvalho Chehab    |                |                   |                |
197218e1b3dSMauro Carvalho Chehab    null             null                null         test-child01
198218e1b3dSMauro Carvalho Chehab
199218e1b3dSMauro Carvalho Chehab
200218e1b3dSMauro Carvalho ChehabFigure 3: Live device tree structure after attaching the testcase-data.
201218e1b3dSMauro Carvalho Chehab
202218e1b3dSMauro Carvalho Chehab
203218e1b3dSMauro Carvalho ChehabAstute readers would have noticed that test-child0 node becomes the last
204218e1b3dSMauro Carvalho Chehabsibling compared to the earlier structure (Figure 2). After attaching first
205218e1b3dSMauro Carvalho Chehabtest-child0 the test-sibling1 is attached that pushes the child node
206218e1b3dSMauro Carvalho Chehab(i.e. test-child0) to become a sibling and makes itself a child node,
207218e1b3dSMauro Carvalho Chehabas mentioned above.
208218e1b3dSMauro Carvalho Chehab
209218e1b3dSMauro Carvalho ChehabIf a duplicate node is found (i.e. if a node with same full_name property is
210218e1b3dSMauro Carvalho Chehabalready present in the live tree), then the node isn't attached rather its
211218e1b3dSMauro Carvalho Chehabproperties are updated to the live tree's node by calling the function
212218e1b3dSMauro Carvalho Chehabupdate_node_properties().
213218e1b3dSMauro Carvalho Chehab
214218e1b3dSMauro Carvalho Chehab
2158e4296c2SFrank Rowand3.2. Removing the test data
216218e1b3dSMauro Carvalho Chehab---------------------------
217218e1b3dSMauro Carvalho Chehab
218218e1b3dSMauro Carvalho ChehabOnce the test case execution is complete, selftest_data_remove is called in
219218e1b3dSMauro Carvalho Chehaborder to remove the device nodes attached initially (first the leaf nodes are
220218e1b3dSMauro Carvalho Chehabdetached and then moving up the parent nodes are removed, and eventually the
221218e1b3dSMauro Carvalho Chehabwhole tree). selftest_data_remove() calls detach_node_and_children() that uses
222218e1b3dSMauro Carvalho Chehabof_detach_node() to detach the nodes from the live device tree.
223218e1b3dSMauro Carvalho Chehab
224218e1b3dSMauro Carvalho ChehabTo detach a node, of_detach_node() either updates the child pointer of given
225218e1b3dSMauro Carvalho Chehabnode's parent to its sibling or attaches the previous sibling to the given
226218e1b3dSMauro Carvalho Chehabnode's sibling, as appropriate. That is it :)
227