1*cd60bc56SAndroid Build Coastguard Worker // SPDX-License-Identifier: LGPL-2.1-or-later
2*cd60bc56SAndroid Build Coastguard Worker /*
3*cd60bc56SAndroid Build Coastguard Worker * libfdt - Flat Device Tree manipulation
4*cd60bc56SAndroid Build Coastguard Worker * Testcase for string handling
5*cd60bc56SAndroid Build Coastguard Worker * Copyright (C) 2015 NVIDIA Corporation
6*cd60bc56SAndroid Build Coastguard Worker */
7*cd60bc56SAndroid Build Coastguard Worker
8*cd60bc56SAndroid Build Coastguard Worker #include <stdlib.h>
9*cd60bc56SAndroid Build Coastguard Worker #include <stdio.h>
10*cd60bc56SAndroid Build Coastguard Worker #include <string.h>
11*cd60bc56SAndroid Build Coastguard Worker #include <stdint.h>
12*cd60bc56SAndroid Build Coastguard Worker
13*cd60bc56SAndroid Build Coastguard Worker #include <libfdt.h>
14*cd60bc56SAndroid Build Coastguard Worker
15*cd60bc56SAndroid Build Coastguard Worker #include "tests.h"
16*cd60bc56SAndroid Build Coastguard Worker #include "testdata.h"
17*cd60bc56SAndroid Build Coastguard Worker
check_expected_failure(const void * fdt,const char * path,const char * property)18*cd60bc56SAndroid Build Coastguard Worker static void check_expected_failure(const void *fdt, const char *path,
19*cd60bc56SAndroid Build Coastguard Worker const char *property)
20*cd60bc56SAndroid Build Coastguard Worker {
21*cd60bc56SAndroid Build Coastguard Worker int offset, err;
22*cd60bc56SAndroid Build Coastguard Worker
23*cd60bc56SAndroid Build Coastguard Worker offset = fdt_path_offset(fdt, "/");
24*cd60bc56SAndroid Build Coastguard Worker if (offset < 0)
25*cd60bc56SAndroid Build Coastguard Worker FAIL("Couldn't find path %s", path);
26*cd60bc56SAndroid Build Coastguard Worker
27*cd60bc56SAndroid Build Coastguard Worker err = fdt_stringlist_count(fdt, offset, "#address-cells");
28*cd60bc56SAndroid Build Coastguard Worker if (err != -FDT_ERR_BADVALUE)
29*cd60bc56SAndroid Build Coastguard Worker FAIL("unexpectedly succeeded in parsing #address-cells\n");
30*cd60bc56SAndroid Build Coastguard Worker
31*cd60bc56SAndroid Build Coastguard Worker err = fdt_stringlist_search(fdt, offset, "#address-cells", "foo");
32*cd60bc56SAndroid Build Coastguard Worker if (err != -FDT_ERR_BADVALUE)
33*cd60bc56SAndroid Build Coastguard Worker FAIL("found string in #address-cells: %d\n", err);
34*cd60bc56SAndroid Build Coastguard Worker
35*cd60bc56SAndroid Build Coastguard Worker /*
36*cd60bc56SAndroid Build Coastguard Worker * Note that the #address-cells property contains a small 32-bit
37*cd60bc56SAndroid Build Coastguard Worker * unsigned integer, hence some bytes will be zero, and searching for
38*cd60bc56SAndroid Build Coastguard Worker * the empty string will succeed.
39*cd60bc56SAndroid Build Coastguard Worker *
40*cd60bc56SAndroid Build Coastguard Worker * The reason for this oddity is that the function will exit when the
41*cd60bc56SAndroid Build Coastguard Worker * first occurrence of the string is found, but in order to determine
42*cd60bc56SAndroid Build Coastguard Worker * that the property does not contain a valid string list it would
43*cd60bc56SAndroid Build Coastguard Worker * need to process the whole value.
44*cd60bc56SAndroid Build Coastguard Worker */
45*cd60bc56SAndroid Build Coastguard Worker err = fdt_stringlist_search(fdt, offset, "#address-cells", "");
46*cd60bc56SAndroid Build Coastguard Worker if (err != 0)
47*cd60bc56SAndroid Build Coastguard Worker FAIL("empty string not found in #address-cells: %d\n", err);
48*cd60bc56SAndroid Build Coastguard Worker
49*cd60bc56SAndroid Build Coastguard Worker /*
50*cd60bc56SAndroid Build Coastguard Worker * fdt_getprop_string() can successfully extract strings from
51*cd60bc56SAndroid Build Coastguard Worker * non-string properties. This is because it doesn't
52*cd60bc56SAndroid Build Coastguard Worker * necessarily parse the whole property value, which would be
53*cd60bc56SAndroid Build Coastguard Worker * necessary for it to determine if a valid string or string
54*cd60bc56SAndroid Build Coastguard Worker * list is present.
55*cd60bc56SAndroid Build Coastguard Worker */
56*cd60bc56SAndroid Build Coastguard Worker }
57*cd60bc56SAndroid Build Coastguard Worker
check_string_count(const void * fdt,const char * path,const char * property,int count)58*cd60bc56SAndroid Build Coastguard Worker static void check_string_count(const void *fdt, const char *path,
59*cd60bc56SAndroid Build Coastguard Worker const char *property, int count)
60*cd60bc56SAndroid Build Coastguard Worker {
61*cd60bc56SAndroid Build Coastguard Worker int offset, err;
62*cd60bc56SAndroid Build Coastguard Worker
63*cd60bc56SAndroid Build Coastguard Worker offset = fdt_path_offset(fdt, path);
64*cd60bc56SAndroid Build Coastguard Worker if (offset < 0)
65*cd60bc56SAndroid Build Coastguard Worker FAIL("Couldn't find path %s", path);
66*cd60bc56SAndroid Build Coastguard Worker
67*cd60bc56SAndroid Build Coastguard Worker err = fdt_stringlist_count(fdt, offset, property);
68*cd60bc56SAndroid Build Coastguard Worker if (err < 0)
69*cd60bc56SAndroid Build Coastguard Worker FAIL("Couldn't count strings in property %s of node %s: %d\n",
70*cd60bc56SAndroid Build Coastguard Worker property, path, err);
71*cd60bc56SAndroid Build Coastguard Worker
72*cd60bc56SAndroid Build Coastguard Worker if (err != count)
73*cd60bc56SAndroid Build Coastguard Worker FAIL("String count for property %s of node %s is %d instead of %d\n",
74*cd60bc56SAndroid Build Coastguard Worker path, property, err, count);
75*cd60bc56SAndroid Build Coastguard Worker }
76*cd60bc56SAndroid Build Coastguard Worker
check_string_index(const void * fdt,const char * path,const char * property,const char * string,int idx)77*cd60bc56SAndroid Build Coastguard Worker static void check_string_index(const void *fdt, const char *path,
78*cd60bc56SAndroid Build Coastguard Worker const char *property, const char *string,
79*cd60bc56SAndroid Build Coastguard Worker int idx)
80*cd60bc56SAndroid Build Coastguard Worker {
81*cd60bc56SAndroid Build Coastguard Worker int offset, err;
82*cd60bc56SAndroid Build Coastguard Worker
83*cd60bc56SAndroid Build Coastguard Worker offset = fdt_path_offset(fdt, path);
84*cd60bc56SAndroid Build Coastguard Worker if (offset < 0)
85*cd60bc56SAndroid Build Coastguard Worker FAIL("Couldn't find path %s", path);
86*cd60bc56SAndroid Build Coastguard Worker
87*cd60bc56SAndroid Build Coastguard Worker err = fdt_stringlist_search(fdt, offset, property, string);
88*cd60bc56SAndroid Build Coastguard Worker
89*cd60bc56SAndroid Build Coastguard Worker if (err != idx)
90*cd60bc56SAndroid Build Coastguard Worker FAIL("Index of %s in property %s of node %s is %d, expected %d\n",
91*cd60bc56SAndroid Build Coastguard Worker string, property, path, err, idx);
92*cd60bc56SAndroid Build Coastguard Worker }
93*cd60bc56SAndroid Build Coastguard Worker
check_string(const void * fdt,const char * path,const char * property,int idx,const char * string)94*cd60bc56SAndroid Build Coastguard Worker static void check_string(const void *fdt, const char *path,
95*cd60bc56SAndroid Build Coastguard Worker const char *property, int idx,
96*cd60bc56SAndroid Build Coastguard Worker const char *string)
97*cd60bc56SAndroid Build Coastguard Worker {
98*cd60bc56SAndroid Build Coastguard Worker const char *result;
99*cd60bc56SAndroid Build Coastguard Worker int offset, len;
100*cd60bc56SAndroid Build Coastguard Worker
101*cd60bc56SAndroid Build Coastguard Worker offset = fdt_path_offset(fdt, path);
102*cd60bc56SAndroid Build Coastguard Worker if (offset < 0)
103*cd60bc56SAndroid Build Coastguard Worker FAIL("Couldn't find path %s", path);
104*cd60bc56SAndroid Build Coastguard Worker
105*cd60bc56SAndroid Build Coastguard Worker result = fdt_stringlist_get(fdt, offset, property, idx, &len);
106*cd60bc56SAndroid Build Coastguard Worker if (!result)
107*cd60bc56SAndroid Build Coastguard Worker FAIL("Couldn't extract string %d from property %s of node %s: %d\n",
108*cd60bc56SAndroid Build Coastguard Worker idx, property, path, len);
109*cd60bc56SAndroid Build Coastguard Worker
110*cd60bc56SAndroid Build Coastguard Worker if (strcmp(string, result) != 0)
111*cd60bc56SAndroid Build Coastguard Worker FAIL("String %d in property %s of node %s is %s, expected %s\n",
112*cd60bc56SAndroid Build Coastguard Worker idx, property, path, result, string);
113*cd60bc56SAndroid Build Coastguard Worker }
114*cd60bc56SAndroid Build Coastguard Worker
main(int argc,char * argv[])115*cd60bc56SAndroid Build Coastguard Worker int main(int argc, char *argv[])
116*cd60bc56SAndroid Build Coastguard Worker {
117*cd60bc56SAndroid Build Coastguard Worker void *fdt;
118*cd60bc56SAndroid Build Coastguard Worker
119*cd60bc56SAndroid Build Coastguard Worker if (argc != 2)
120*cd60bc56SAndroid Build Coastguard Worker CONFIG("Usage: %s <dtb file>\n", argv[0]);
121*cd60bc56SAndroid Build Coastguard Worker
122*cd60bc56SAndroid Build Coastguard Worker test_init(argc, argv);
123*cd60bc56SAndroid Build Coastguard Worker fdt = load_blob(argv[1]);
124*cd60bc56SAndroid Build Coastguard Worker
125*cd60bc56SAndroid Build Coastguard Worker check_expected_failure(fdt, "/", "#address-cells");
126*cd60bc56SAndroid Build Coastguard Worker check_expected_failure(fdt, "/", "#size-cells");
127*cd60bc56SAndroid Build Coastguard Worker
128*cd60bc56SAndroid Build Coastguard Worker check_string_count(fdt, "/", "compatible", 1);
129*cd60bc56SAndroid Build Coastguard Worker check_string_count(fdt, "/device", "compatible", 2);
130*cd60bc56SAndroid Build Coastguard Worker check_string_count(fdt, "/device", "big-endian", 0);
131*cd60bc56SAndroid Build Coastguard Worker
132*cd60bc56SAndroid Build Coastguard Worker check_string_index(fdt, "/", "compatible", "test-strings", 0);
133*cd60bc56SAndroid Build Coastguard Worker check_string_index(fdt, "/device", "compatible", "foo", 0);
134*cd60bc56SAndroid Build Coastguard Worker check_string_index(fdt, "/device", "compatible", "bar", 1);
135*cd60bc56SAndroid Build Coastguard Worker check_string_index(fdt, "/device", "big-endian", "baz", -1);
136*cd60bc56SAndroid Build Coastguard Worker
137*cd60bc56SAndroid Build Coastguard Worker check_string(fdt, "/", "compatible", 0, "test-strings");
138*cd60bc56SAndroid Build Coastguard Worker check_string(fdt, "/device", "compatible", 0, "foo");
139*cd60bc56SAndroid Build Coastguard Worker check_string(fdt, "/device", "compatible", 1, "bar");
140*cd60bc56SAndroid Build Coastguard Worker
141*cd60bc56SAndroid Build Coastguard Worker PASS();
142*cd60bc56SAndroid Build Coastguard Worker }
143