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