1 /* 2 * libfdt - Flat Device Tree manipulation 3 * Testcase for phandle references in dtc 4 * Copyright (C) 2006 David Gibson, IBM Corporation. 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public License 8 * as published by the Free Software Foundation; either version 2.1 of 9 * the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, but 12 * WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 #include <stdlib.h> 21 #include <stdio.h> 22 #include <string.h> 23 #include <stdint.h> 24 25 #include <libfdt.h> 26 27 #include "tests.h" 28 #include "testdata.h" 29 30 static void check_ref(const void *fdt, int node, uint32_t checkref) 31 { 32 const fdt32_t *p; 33 uint32_t ref; 34 int len; 35 36 p = fdt_getprop(fdt, node, "ref", &len); 37 if (!p) 38 FAIL("fdt_getprop(%d, \"ref\"): %s", node, fdt_strerror(len)); 39 if (len != sizeof(*p)) 40 FAIL("'ref' in node at %d has wrong size (%d instead of %zd)", 41 node, len, sizeof(*p)); 42 ref = fdt32_to_cpu(*p); 43 if (ref != checkref) 44 FAIL("'ref' in node at %d has value 0x%x instead of 0x%x", 45 node, ref, checkref); 46 47 p = fdt_getprop(fdt, node, "lref", &len); 48 if (!p) 49 FAIL("fdt_getprop(%d, \"lref\"): %s", node, fdt_strerror(len)); 50 if (len != sizeof(*p)) 51 FAIL("'lref' in node at %d has wrong size (%d instead of %zd)", 52 node, len, sizeof(*p)); 53 ref = fdt32_to_cpu(*p); 54 if (ref != checkref) 55 FAIL("'lref' in node at %d has value 0x%x instead of 0x%x", 56 node, ref, checkref); 57 } 58 59 static void check_rref(const void *fdt) 60 { 61 const fdt32_t *p; 62 uint32_t ref; 63 int len; 64 65 p = fdt_getprop(fdt, 0, "rref", &len); 66 if (!p) 67 FAIL("fdt_getprop(0, \"rref\"): %s", fdt_strerror(len)); 68 if (len != sizeof(*p)) 69 FAIL("'rref' in root node has wrong size (%d instead of %zd)", 70 len, sizeof(*p)); 71 ref = fdt32_to_cpu(*p); 72 if (ref != fdt_get_phandle(fdt, 0)) 73 FAIL("'rref' in root node has value 0x%x instead of 0x0", ref); 74 } 75 76 int main(int argc, char *argv[]) 77 { 78 void *fdt; 79 int n1, n2, n3, n4, n5; 80 uint32_t h1, h2, h4, h5; 81 82 test_init(argc, argv); 83 fdt = load_blob_arg(argc, argv); 84 85 n1 = fdt_path_offset(fdt, "/node1"); 86 if (n1 < 0) 87 FAIL("fdt_path_offset(/node1): %s", fdt_strerror(n1)); 88 n2 = fdt_path_offset(fdt, "/node2"); 89 if (n2 < 0) 90 FAIL("fdt_path_offset(/node2): %s", fdt_strerror(n2)); 91 n3 = fdt_path_offset(fdt, "/node3"); 92 if (n3 < 0) 93 FAIL("fdt_path_offset(/node3): %s", fdt_strerror(n3)); 94 n4 = fdt_path_offset(fdt, "/node4"); 95 if (n4 < 0) 96 FAIL("fdt_path_offset(/node4): %s", fdt_strerror(n4)); 97 n5 = fdt_path_offset(fdt, "/node5"); 98 if (n5 < 0) 99 FAIL("fdt_path_offset(/node5): %s", fdt_strerror(n5)); 100 101 h1 = fdt_get_phandle(fdt, n1); 102 h2 = fdt_get_phandle(fdt, n2); 103 h4 = fdt_get_phandle(fdt, n4); 104 h5 = fdt_get_phandle(fdt, n5); 105 106 if (h1 != 0x2000) 107 FAIL("/node1 has wrong phandle, 0x%x instead of 0x%x", 108 h1, 0x2000); 109 if (h2 != 0x1) 110 FAIL("/node2 has wrong phandle, 0x%x instead of 0x%x", 111 h2, 0x1); 112 if ((h4 == 0x2000) || (h4 == 0x1) || (h4 == 0)) 113 FAIL("/node4 has bad phandle, 0x%x", h4); 114 115 if ((h5 == 0) || (h5 == -1)) 116 FAIL("/node5 has bad phandle, 0x%x", h5); 117 if ((h5 == h4) || (h5 == h2) || (h5 == h1)) 118 FAIL("/node5 has duplicate phandle, 0x%x", h5); 119 120 check_ref(fdt, n1, h2); 121 check_ref(fdt, n2, h1); 122 check_ref(fdt, n3, h4); 123 124 check_rref(fdt); 125 126 PASS(); 127 } 128