1/* $NetBSD: references.c,v 1.1.1.3 2019/12/22 12:34:07 skrll Exp $ */ 2 3// SPDX-License-Identifier: LGPL-2.1-or-later 4/* 5 * libfdt - Flat Device Tree manipulation 6 * Testcase for phandle references in dtc 7 * Copyright (C) 2006 David Gibson, IBM Corporation. 8 */ 9#include <stdlib.h> 10#include <stdio.h> 11#include <string.h> 12#include <stdint.h> 13 14#include <libfdt.h> 15 16#include "tests.h" 17#include "testdata.h" 18 19static void check_ref(const void *fdt, int node, uint32_t checkref) 20{ 21 const fdt32_t *p; 22 uint32_t ref; 23 int len; 24 25 p = fdt_getprop(fdt, node, "ref", &len); 26 if (!p) 27 FAIL("fdt_getprop(%d, \"ref\"): %s", node, fdt_strerror(len)); 28 if (len != sizeof(*p)) 29 FAIL("'ref' in node at %d has wrong size (%d instead of %zd)", 30 node, len, sizeof(*p)); 31 ref = fdt32_to_cpu(*p); 32 if (ref != checkref) 33 FAIL("'ref' in node at %d has value 0x%x instead of 0x%x", 34 node, ref, checkref); 35 36 p = fdt_getprop(fdt, node, "lref", &len); 37 if (!p) 38 FAIL("fdt_getprop(%d, \"lref\"): %s", node, fdt_strerror(len)); 39 if (len != sizeof(*p)) 40 FAIL("'lref' 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("'lref' in node at %d has value 0x%x instead of 0x%x", 45 node, ref, checkref); 46} 47 48static void check_rref(const void *fdt) 49{ 50 const fdt32_t *p; 51 uint32_t ref; 52 int len; 53 54 p = fdt_getprop(fdt, 0, "rref", &len); 55 if (!p) 56 FAIL("fdt_getprop(0, \"rref\"): %s", fdt_strerror(len)); 57 if (len != sizeof(*p)) 58 FAIL("'rref' in root node has wrong size (%d instead of %zd)", 59 len, sizeof(*p)); 60 ref = fdt32_to_cpu(*p); 61 if (ref != fdt_get_phandle(fdt, 0)) 62 FAIL("'rref' in root node has value 0x%x instead of 0x0", ref); 63} 64 65int main(int argc, char *argv[]) 66{ 67 void *fdt; 68 int n1, n2, n3, n4, n5, n6, err; 69 uint32_t h1, h2, h4, h5, h6, hn; 70 71 test_init(argc, argv); 72 fdt = load_blob_arg(argc, argv); 73 74 n1 = fdt_path_offset(fdt, "/node1"); 75 if (n1 < 0) 76 FAIL("fdt_path_offset(/node1): %s", fdt_strerror(n1)); 77 n2 = fdt_path_offset(fdt, "/node2"); 78 if (n2 < 0) 79 FAIL("fdt_path_offset(/node2): %s", fdt_strerror(n2)); 80 n3 = fdt_path_offset(fdt, "/node3"); 81 if (n3 < 0) 82 FAIL("fdt_path_offset(/node3): %s", fdt_strerror(n3)); 83 n4 = fdt_path_offset(fdt, "/node4"); 84 if (n4 < 0) 85 FAIL("fdt_path_offset(/node4): %s", fdt_strerror(n4)); 86 n5 = fdt_path_offset(fdt, "/node5"); 87 if (n5 < 0) 88 FAIL("fdt_path_offset(/node5): %s", fdt_strerror(n5)); 89 n6 = fdt_path_offset(fdt, "/node6"); 90 if (n6 < 0) 91 FAIL("fdt_path_offset(/node6): %s", fdt_strerror(n6)); 92 93 h1 = fdt_get_phandle(fdt, n1); 94 h2 = fdt_get_phandle(fdt, n2); 95 h4 = fdt_get_phandle(fdt, n4); 96 h5 = fdt_get_phandle(fdt, n5); 97 h6 = fdt_get_phandle(fdt, n6); 98 99 if (h1 != 0x2000) 100 FAIL("/node1 has wrong phandle, 0x%x instead of 0x%x", 101 h1, 0x2000); 102 if (h2 != 0x1) 103 FAIL("/node2 has wrong phandle, 0x%x instead of 0x%x", 104 h2, 0x1); 105 if (h6 != FDT_MAX_PHANDLE) 106 FAIL("/node6 has wrong phandle, 0x%x instead of 0x%x", 107 h6, FDT_MAX_PHANDLE); 108 if ((h4 == 0x2000) || (h4 == 0x1) || (h4 == 0)) 109 FAIL("/node4 has bad phandle, 0x%x", h4); 110 111 if ((h5 == 0) || (h5 == -1)) 112 FAIL("/node5 has bad phandle, 0x%x", h5); 113 if ((h5 == h4) || (h5 == h2) || (h5 == h1)) 114 FAIL("/node5 has duplicate phandle, 0x%x", h5); 115 116 /* 117 * /node6 has phandle FDT_MAX_PHANDLE, so fdt_generate_phandle() is 118 * expected to fail. 119 */ 120 err = fdt_generate_phandle(fdt, &hn); 121 if (err != -FDT_ERR_NOPHANDLES) 122 FAIL("generated invalid phandle 0x%x\n", hn); 123 124 check_ref(fdt, n1, h2); 125 check_ref(fdt, n2, h1); 126 check_ref(fdt, n3, h4); 127 128 check_rref(fdt); 129 130 PASS(); 131} 132