1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 /*
3 * libfdt - Flat Device Tree manipulation
4 * Testcase/tool constructing an fs tree for further test
5 * Copyright (C) 2018 David Gibson, Red Hat Inc.
6 */
7
8 #include <stdlib.h>
9 #include <stdio.h>
10 #include <string.h>
11 #include <limits.h>
12 #include <stdint.h>
13 #include <sys/stat.h>
14 #include <errno.h>
15 #include <unistd.h>
16 #include <fcntl.h>
17
18 #include <libfdt.h>
19
20 #include "tests.h"
21 #include "testdata.h"
22
start_dir(const char * name)23 static void start_dir(const char *name)
24 {
25 int rc;
26
27 rc = mkdir(name, 0777);
28 if (rc != 0)
29 FAIL("mkdir(\"%s\"): %s", name, strerror(errno));
30
31 rc = chdir(name);
32 if (rc != 0)
33 FAIL("chdir(\"%s\"): %s", name, strerror(errno));
34 }
35
end_dir(void)36 static void end_dir(void)
37 {
38 int rc;
39
40 rc = chdir("..");
41 if (rc != 0)
42 FAIL("chdir(..): %s", strerror(errno));
43 }
44
mkfile(const char * name,void * data,size_t len)45 static void mkfile(const char *name, void *data, size_t len)
46 {
47 int fd;
48 int rc;
49
50 fd = open(name, O_WRONLY|O_CREAT, 0666);
51 if (fd < 0)
52 FAIL("open(\"%s\"): %s", name, strerror(errno));
53
54 rc = write(fd, data, len);
55 if (rc < 0)
56 FAIL("write(\"%s\"): %s", name, strerror(errno));
57 if (rc != len)
58 FAIL("write(\"%s\"): short write", name);
59
60 rc = close(fd);
61 if (rc != 0)
62 FAIL("close(\"%s\"): %s", name, strerror(errno));
63 }
64
65 #define mkfile_str(name, s) \
66 do { \
67 char str[] = s; \
68 mkfile((name), str, sizeof(str)); \
69 } while (0)
70
mkfile_u32(const char * name,uint32_t val)71 static void mkfile_u32(const char *name, uint32_t val)
72 {
73 val = cpu_to_fdt32(val);
74 mkfile(name, &val, sizeof(val));
75 }
76
mkfile_u64(const char * name,uint64_t val)77 static void mkfile_u64(const char *name, uint64_t val)
78 {
79 val = cpu_to_fdt64(val);
80 mkfile(name, &val, sizeof(val));
81 }
82
main(int argc,char * argv[])83 int main(int argc, char *argv[])
84 {
85 const char *base;
86
87 test_init(argc, argv);
88 if (argc != 2)
89 CONFIG("Usage: %s <path>", argv[0]);
90
91 base = argv[1];
92
93 start_dir(base);
94 mkfile_str("compatible", "test_tree1");
95 mkfile_u32("prop-int", TEST_VALUE_1);
96 mkfile_u64("prop-int64", 0xdeadbeef01abcdefULL);
97 mkfile_str("prop-str", "hello world");
98 mkfile_u32("#address-cells", 1);
99 mkfile_u32("#size-cells", 0);
100
101 {
102 start_dir("subnode@1");
103
104 mkfile_str("compatible", "subnode1");
105 mkfile_u32("reg", 1);
106 mkfile_u32("prop-int", TEST_VALUE_1);
107
108 {
109 start_dir("subsubnode");
110
111 mkfile_str("compatible", "subsubnode1\0subsubnode");
112 mkfile_str("placeholder", "this is a placeholder string\0string2");
113 mkfile_u32("prop-int", TEST_VALUE_1);
114
115 end_dir();
116 }
117
118 {
119 start_dir("ss1");
120 end_dir();
121 }
122
123 end_dir();
124 }
125
126 {
127 start_dir("subnode@2");
128
129 mkfile_u32("reg", 2);
130 mkfile_u32("linux,phandle", 0x2000);
131 mkfile_u32("prop-int", TEST_VALUE_2);
132 mkfile_u32("#address-cells", 1);
133 mkfile_u32("#size-cells", 0);
134
135 {
136 start_dir("subsubnode@0");
137
138 mkfile_u32("reg", 0);
139 mkfile_u32("phandle", 0x2001);
140 mkfile_str("compatible", "subsubnode2\0subsubnode");
141 mkfile_u32("prop-int", TEST_VALUE_2);
142
143 end_dir();
144 }
145
146 {
147 start_dir("ss2");
148 end_dir();
149 }
150
151 end_dir();
152 }
153
154 PASS();
155 }
156