iPXE
fdt_test.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2025 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 /** @file
27  *
28  * Flattened device tree self-tests
29  *
30  */
31 
32 /* Forcibly enable assertions */
33 #undef NDEBUG
34 
35 #include <string.h>
36 #include <ipxe/fdt.h>
37 #include <ipxe/image.h>
38 #include <ipxe/test.h>
39 
40 /** Simplified QEMU sifive_u device tree blob */
41 static const uint8_t sifive_u[] = {
42  0xd0, 0x0d, 0xfe, 0xed, 0x00, 0x00, 0x05, 0x8f, 0x00, 0x00, 0x00, 0x38,
43  0x00, 0x00, 0x04, 0x9c, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x11,
44  0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3,
45  0x00, 0x00, 0x04, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
46  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
47  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
48  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03,
49  0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x02,
50  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x1b,
51  0x73, 0x69, 0x66, 0x69, 0x76, 0x65, 0x2c, 0x68, 0x69, 0x66, 0x69, 0x76,
52  0x65, 0x2d, 0x75, 0x6e, 0x6c, 0x65, 0x61, 0x73, 0x68, 0x65, 0x64, 0x2d,
53  0x61, 0x30, 0x30, 0x00, 0x73, 0x69, 0x66, 0x69, 0x76, 0x65, 0x2c, 0x68,
54  0x69, 0x66, 0x69, 0x76, 0x65, 0x2d, 0x75, 0x6e, 0x6c, 0x65, 0x61, 0x73,
55  0x68, 0x65, 0x64, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1c,
56  0x00, 0x00, 0x00, 0x26, 0x53, 0x69, 0x46, 0x69, 0x76, 0x65, 0x20, 0x48,
57  0x69, 0x46, 0x69, 0x76, 0x65, 0x20, 0x55, 0x6e, 0x6c, 0x65, 0x61, 0x73,
58  0x68, 0x65, 0x64, 0x20, 0x41, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x01,
59  0x63, 0x68, 0x6f, 0x73, 0x65, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
60  0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x2c, 0x2f, 0x73, 0x6f, 0x63,
61  0x2f, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x40, 0x31, 0x30, 0x30, 0x31,
62  0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
63  0x00, 0x00, 0x00, 0x01, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x00,
64  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x38,
65  0x2f, 0x73, 0x6f, 0x63, 0x2f, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x40,
66  0x31, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00,
67  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x40,
68  0x2f, 0x73, 0x6f, 0x63, 0x2f, 0x65, 0x74, 0x68, 0x65, 0x72, 0x6e, 0x65,
69  0x74, 0x40, 0x31, 0x30, 0x30, 0x39, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00,
70  0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x63, 0x70, 0x75, 0x73,
71  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
72  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03,
73  0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00,
74  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x4a,
75  0x00, 0x0f, 0x42, 0x40, 0x00, 0x00, 0x00, 0x01, 0x63, 0x70, 0x75, 0x40,
76  0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
77  0x00, 0x00, 0x00, 0x5d, 0x63, 0x70, 0x75, 0x00, 0x00, 0x00, 0x00, 0x03,
78  0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00,
79  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x6d,
80  0x6f, 0x6b, 0x61, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
81  0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1b, 0x72, 0x69, 0x73, 0x63,
82  0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x25,
83  0x00, 0x00, 0x00, 0x74, 0x72, 0x76, 0x36, 0x34, 0x69, 0x6d, 0x61, 0x63,
84  0x5f, 0x7a, 0x69, 0x63, 0x6e, 0x74, 0x72, 0x5f, 0x7a, 0x69, 0x63, 0x73,
85  0x72, 0x5f, 0x7a, 0x69, 0x66, 0x65, 0x6e, 0x63, 0x65, 0x69, 0x5f, 0x7a,
86  0x69, 0x68, 0x70, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
87  0x69, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x75, 0x70, 0x74, 0x2d, 0x63, 0x6f,
88  0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x00, 0x00, 0x00, 0x00,
89  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7e,
90  0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
91  0x00, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0f,
92  0x00, 0x00, 0x00, 0x1b, 0x72, 0x69, 0x73, 0x63, 0x76, 0x2c, 0x63, 0x70,
93  0x75, 0x2d, 0x69, 0x6e, 0x74, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
94  0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x03,
95  0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02,
96  0x00, 0x00, 0x00, 0x01, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x40, 0x38,
97  0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x03,
98  0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x5d, 0x6d, 0x65, 0x6d, 0x6f,
99  0x72, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10,
100  0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
101  0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
102  0x00, 0x00, 0x00, 0x01, 0x73, 0x6f, 0x63, 0x00, 0x00, 0x00, 0x00, 0x03,
103  0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
104  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0f,
105  0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0b,
106  0x00, 0x00, 0x00, 0x1b, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x2d, 0x62,
107  0x75, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
108  0x00, 0x00, 0x00, 0xb2, 0x00, 0x00, 0x00, 0x01, 0x73, 0x65, 0x72, 0x69,
109  0x61, 0x6c, 0x40, 0x31, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x00,
110  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x69,
111  0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
112  0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0d,
113  0x00, 0x00, 0x00, 0x1b, 0x73, 0x69, 0x66, 0x69, 0x76, 0x65, 0x2c, 0x75,
114  0x61, 0x72, 0x74, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
115  0x00, 0x00, 0x00, 0x01, 0x65, 0x74, 0x68, 0x65, 0x72, 0x6e, 0x65, 0x74,
116  0x40, 0x31, 0x30, 0x30, 0x39, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00,
117  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0f,
118  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
119  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03,
120  0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0xb9, 0x52, 0x54, 0x00, 0x12,
121  0x34, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
122  0x00, 0x00, 0x00, 0xcb, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03,
123  0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xd6, 0x67, 0x6d, 0x69, 0x69,
124  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08,
125  0x00, 0x00, 0x00, 0xdf, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x00,
126  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x69,
127  0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
128  0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x00, 0x00,
129  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x03,
130  0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x1b, 0x73, 0x69, 0x66, 0x69,
131  0x76, 0x65, 0x2c, 0x66, 0x75, 0x35, 0x34, 0x30, 0x2d, 0x63, 0x30, 0x30,
132  0x30, 0x2d, 0x67, 0x65, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
133  0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0xe9, 0x00, 0x00, 0x00, 0x02,
134  0x54, 0x0b, 0xe4, 0x00, 0x00, 0x00, 0x00, 0x01, 0x65, 0x74, 0x68, 0x65,
135  0x72, 0x6e, 0x65, 0x74, 0x2d, 0x70, 0x68, 0x79, 0x40, 0x30, 0x00, 0x00,
136  0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x69,
137  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
138  0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02,
139  0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02,
140  0x00, 0x00, 0x00, 0x09, 0x23, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73,
141  0x2d, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x00, 0x23, 0x73, 0x69, 0x7a, 0x65,
142  0x2d, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x00, 0x63, 0x6f, 0x6d, 0x70, 0x61,
143  0x74, 0x69, 0x62, 0x6c, 0x65, 0x00, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x00,
144  0x73, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x2d, 0x70, 0x61, 0x74, 0x68, 0x00,
145  0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x30, 0x00, 0x65, 0x74, 0x68, 0x65,
146  0x72, 0x6e, 0x65, 0x74, 0x30, 0x00, 0x74, 0x69, 0x6d, 0x65, 0x62, 0x61,
147  0x73, 0x65, 0x2d, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79,
148  0x00, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65,
149  0x00, 0x72, 0x65, 0x67, 0x00, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x00,
150  0x72, 0x69, 0x73, 0x63, 0x76, 0x2c, 0x69, 0x73, 0x61, 0x00, 0x23, 0x69,
151  0x6e, 0x74, 0x65, 0x72, 0x72, 0x75, 0x70, 0x74, 0x2d, 0x63, 0x65, 0x6c,
152  0x6c, 0x73, 0x00, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x75, 0x70, 0x74,
153  0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x00,
154  0x6c, 0x69, 0x6e, 0x75, 0x78, 0x2c, 0x70, 0x68, 0x61, 0x6e, 0x64, 0x6c,
155  0x65, 0x00, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x00, 0x6c, 0x6f, 0x63,
156  0x61, 0x6c, 0x2d, 0x6d, 0x61, 0x63, 0x2d, 0x61, 0x64, 0x64, 0x72, 0x65,
157  0x73, 0x73, 0x00, 0x70, 0x68, 0x79, 0x2d, 0x68, 0x61, 0x6e, 0x64, 0x6c,
158  0x65, 0x00, 0x70, 0x68, 0x79, 0x2d, 0x6d, 0x6f, 0x64, 0x65, 0x00, 0x72,
159  0x65, 0x67, 0x2d, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x00, 0x6d, 0x61, 0x78,
160  0x2d, 0x73, 0x70, 0x65, 0x65, 0x64, 0x00
161 };
162 
163 /**
164  * Perform FDT self-test
165  *
166  */
167 static void fdt_test_exec ( void ) {
168  struct fdt_descriptor desc;
169  struct fdt_header *hdr;
170  struct fdt fdt;
171  const char *string;
172  struct image *image;
173  uint32_t u32;
174  uint64_t u64;
175  unsigned int count;
176  unsigned int offset;
177 
178  /* Verify parsing */
179  hdr = ( ( struct fdt_header * ) sifive_u );
180  ok ( fdt_parse ( &fdt, hdr, 0 ) != 0 );
181  ok ( fdt_parse ( &fdt, hdr, 1 ) != 0 );
182  ok ( fdt_parse ( &fdt, hdr, ( sizeof ( sifive_u ) - 1 ) ) != 0 );
183  ok ( fdt_parse ( &fdt, hdr, -1UL ) == 0 );
184  ok ( fdt.len == sizeof ( sifive_u ) );
185  ok ( fdt_parse ( &fdt, hdr, sizeof ( sifive_u ) ) == 0 );
186  ok ( fdt.len == sizeof ( sifive_u ) );
187 
188  /* Verify string properties */
189  ok ( ( string = fdt_string ( &fdt, 0, "model" ) ) != NULL );
190  ok ( strcmp ( string, "SiFive HiFive Unleashed A00" ) == 0 );
191  ok ( ( string = fdt_string ( &fdt, 0, "nonexistent" ) ) == NULL );
192 
193  /* Verify string list properties */
194  ok ( ( string = fdt_strings ( &fdt, 0, "model", &count ) ) != NULL );
195  ok ( count == 1 );
196  ok ( memcmp ( string, "SiFive HiFive Unleashed A00", 28 ) == 0 );
197  ok ( ( string = fdt_strings ( &fdt, 0, "compatible",
198  &count ) ) != NULL );
199  ok ( count == 2 );
200  ok ( memcmp ( string, "sifive,hifive-unleashed-a00\0"
201  "sifive,hifive-unleashed", 52 ) == 0 );
202  ok ( ( string = fdt_strings ( &fdt, 0, "nonexistent",
203  &count ) ) == NULL );
204  ok ( count == 0 );
205 
206  /* Verify path lookup */
207  ok ( fdt_path ( &fdt, "", &offset ) == 0 );
208  ok ( offset == 0 );
209  ok ( fdt_path ( &fdt, "/", &offset ) == 0 );
210  ok ( offset == 0 );
211  ok ( fdt_path ( &fdt, "/cpus/cpu@0/interrupt-controller",
212  &offset ) == 0 );
213  ok ( ( string = fdt_string ( &fdt, offset, "compatible" ) ) != NULL );
214  ok ( strcmp ( string, "riscv,cpu-intc" ) == 0 );
215  ok ( fdt_path ( &fdt, "//soc/serial@10010000//", &offset ) == 0 );
216  ok ( ( string = fdt_string ( &fdt, offset, "compatible" ) ) != NULL );
217  ok ( strcmp ( string, "sifive,uart0" ) == 0 );
218  ok ( fdt_path ( &fdt, "/nonexistent", &offset ) != 0 );
219  ok ( fdt_path ( &fdt, "/cpus/nonexistent", &offset ) != 0 );
220  ok ( fdt_path ( &fdt, "/soc/serial@10010000:115200n8",
221  &offset ) == 0 );
222  ok ( ( string = fdt_string ( &fdt, offset, "compatible" ) ) != NULL );
223  ok ( strcmp ( string, "sifive,uart0" ) == 0 );
224 
225  /* Verify 64-bit integer properties */
226  ok ( fdt_u64 ( &fdt, 0, "#address-cells", &u64 ) == 0 );
227  ok ( u64 == 2 );
228  ok ( fdt_path ( &fdt, "/soc/ethernet@10090000", &offset ) == 0 );
229  ok ( fdt_u64 ( &fdt, offset, "max-speed", &u64 ) == 0 );
230  ok ( u64 == 10000000000ULL );
231  ok ( fdt_u64 ( &fdt, offset, "#nonexistent", &u64 ) != 0 );
232 
233  /* Verify 32-bit integer properties */
234  ok ( fdt_u32 ( &fdt, 0, "#address-cells", &u32 ) == 0 );
235  ok ( u32 == 2 );
236  ok ( fdt_u32 ( &fdt, 0, "#nonexistent", &u32 ) != 0 );
237  ok ( fdt_path ( &fdt, "/soc/ethernet@10090000", &offset ) == 0 );
238  ok ( fdt_u32 ( &fdt, offset, "max-speed", &u32 ) != 0 );
239 
240  /* Verify phandle properties */
241  ok ( fdt_path ( &fdt, "/cpus/cpu@0/interrupt-controller",
242  &offset ) == 0 );
243  ok ( fdt_phandle ( &fdt, offset ) == 0x03 );
244  ok ( fdt_path ( &fdt, "/soc/ethernet@10090000/ethernet-phy@0",
245  &offset ) == 0 );
246  ok ( fdt_phandle ( &fdt, offset ) == 0x08 );
247  ok ( fdt_path ( &fdt, "/soc/serial@10010000", &offset ) == 0 );
248  ok ( fdt_phandle ( &fdt, offset ) == 0 );
249 
250  /* Verify cell properties */
251  ok ( fdt_path ( &fdt, "/soc/ethernet@10090000", &offset ) == 0 );
252  ok ( fdt_cells ( &fdt, offset, "reg", 4, 2, &u64 ) == 0 );
253  ok ( u64 == 0x100a0000 );
254  ok ( fdt_cells ( &fdt, offset, "reg", 6, 2, &u64 ) == 0 );
255  ok ( u64 == 0x1000 );
256  ok ( fdt_cells ( &fdt, offset, "reg", 0, 2, &u64 ) == 0 );
257  ok ( u64 == 0x10090000 );
258  ok ( fdt_cells ( &fdt, offset, "reg", 6, 0, &u64 ) == 0 );
259  ok ( u64 == 0x1000 );
260  ok ( fdt_cells ( &fdt, offset, "reg", 8, 0, &u64 ) == 0 );
261  ok ( u64 == 0 );
262  ok ( fdt_cells ( &fdt, offset, "reg", 7, 2, &u64 ) != 0 );
263  ok ( fdt_cells ( &fdt, offset, "notareg", 0, 1, &u64 ) != 0 );
264 
265  /* Verify alias lookup */
266  ok ( fdt_alias ( &fdt, "serial0", &offset ) == 0 );
267  ok ( ( string = fdt_string ( &fdt, offset, "compatible" ) ) != NULL );
268  ok ( strcmp ( string, "sifive,uart0" ) == 0 );
269  ok ( fdt_alias ( &fdt, "nonexistent0", &offset ) != 0 );
270  ok ( fdt_alias ( &fdt, "ethernet0:params", &offset ) == 0 );
271  ok ( ( string = fdt_string ( &fdt, offset, "phy-mode" ) ) != NULL );
272  ok ( strcmp ( string, "gmii" ) == 0 );
273 
274  /* Verify node description */
275  ok ( fdt_path ( &fdt, "/memory@80000000", &offset ) == 0 );
276  ok ( fdt_describe ( &fdt, offset, &desc ) == 0 );
277  ok ( desc.offset == offset );
278  ok ( strcmp ( desc.name, "memory@80000000" ) == 0 );
279  ok ( desc.data == NULL );
280  ok ( desc.len == 0 );
281  ok ( desc.depth == +1 );
282  ok ( fdt_describe ( &fdt, desc.next, &desc ) == 0 );
283  ok ( strcmp ( desc.name, "device_type" ) == 0 );
284  ok ( strcmp ( desc.data, "memory" ) == 0 );
285  ok ( desc.depth == 0 );
286 
287  /* Verify parent lookup */
288  ok ( fdt_path ( &fdt, "/soc/ethernet@10090000/ethernet-phy@0",
289  &offset ) == 0 );
290  ok ( fdt_parent ( &fdt, offset, &offset ) == 0 );
291  ok ( fdt_describe ( &fdt, offset, &desc ) == 0 );
292  ok ( strcmp ( desc.name, "ethernet@10090000" ) == 0 );
293  ok ( fdt_parent ( &fdt, offset, &offset ) == 0 );
294  ok ( fdt_describe ( &fdt, offset, &desc ) == 0 );
295  ok ( strcmp ( desc.name, "soc" ) == 0 );
296  ok ( fdt_parent ( &fdt, offset, &offset ) == 0 );
297  ok ( offset == 0 );
298 
299  /* Verify device tree creation */
300  image = image_memory ( "test.dtb", sifive_u, sizeof ( sifive_u ) );
301  ok ( image != NULL );
302  image_tag ( image, &fdt_image );
303  ok ( fdt_create ( &hdr, "hello world", 0xabcd0000, 0x00001234 ) == 0 );
304  ok ( fdt_parse ( &fdt, hdr, -1UL ) == 0 );
305  ok ( fdt_path ( &fdt, "/chosen", &offset ) == 0 );
306  ok ( ( string = fdt_string ( &fdt, offset, "bootargs" ) ) != NULL );
307  ok ( strcmp ( string, "hello world" ) == 0 );
308  ok ( fdt_u64 ( &fdt, offset, "linux,initrd-start", &u64 ) == 0 );
309  ok ( u64 == 0xabcd0000 );
310  ok ( fdt_u64 ( &fdt, offset, "linux,initrd-end", &u64 ) == 0 );
311  ok ( u64 == 0xabcd1234 );
312  fdt_remove ( hdr );
314 }
315 
316 /** FDT self-test */
317 struct self_test fdt_test __self_test = {
318  .name = "fdt",
319  .exec = fdt_test_exec,
320 };
int fdt_parent(struct fdt *fdt, unsigned int offset, unsigned int *parent)
Find parent node.
Definition: fdt.c:292
int fdt_alias(struct fdt *fdt, const char *name, unsigned int *offset)
Find node by alias.
Definition: fdt.c:465
static void fdt_test_exec(void)
Perform FDT self-test.
Definition: fdt_test.c:167
size_t len
Length of tree.
Definition: fdt.h:97
int fdt_parse(struct fdt *fdt, struct fdt_header *hdr, size_t max_len)
Parse device tree.
Definition: fdt.c:903
Device tree header.
Definition: fdt.h:18
static const uint8_t sifive_u[]
Simplified QEMU sifive_u device tree blob.
Definition: fdt_test.c:41
struct golan_inbox_hdr hdr
Message header.
Definition: CIB_PRM.h:28
int fdt_describe(struct fdt *fdt, unsigned int offset, struct fdt_descriptor *desc)
Describe device tree token.
Definition: fdt.c:89
int fdt_path(struct fdt *fdt, const char *path, unsigned int *offset)
Find node by path.
Definition: fdt.c:425
const char * fdt_strings(struct fdt *fdt, unsigned int offset, const char *name, unsigned int *count)
Find strings property.
Definition: fdt.c:539
unsigned long long uint64_t
Definition: stdint.h:13
uint32_t string
Definition: multiboot.h:14
Self-test infrastructure.
const char * name
Test set name.
Definition: test.h:17
An executable image.
Definition: image.h:23
struct self_test fdt_test __self_test
FDT self-test.
Definition: fdt_test.c:317
A self-test set.
Definition: test.h:15
struct ena_llq_option desc
Descriptor counts.
Definition: ena.h:20
uint32_t fdt_phandle(struct fdt *fdt, unsigned int offset)
Get package handle (phandle) property.
Definition: fdt.c:689
Executable images.
int fdt_u32(struct fdt *fdt, unsigned int offset, const char *name, uint32_t *value)
Get 32-bit integer property.
Definition: fdt.c:663
#define u32
Definition: vga.h:21
void fdt_remove(struct fdt_header *hdr)
Remove device tree.
Definition: fdt.c:1458
uint64_t u64
Definition: stdint.h:25
static unsigned int count
Number of entries.
Definition: dwmac.h:225
const char * fdt_string(struct fdt *fdt, unsigned int offset, const char *name)
Find string property.
Definition: fdt.c:578
unsigned char uint8_t
Definition: stdint.h:10
unsigned int uint32_t
Definition: stdint.h:12
struct image * image_memory(const char *name, const void *data, size_t len)
Create registered image from block of memory.
Definition: image.c:608
void unregister_image(struct image *image)
Unregister executable image.
Definition: image.c:357
A device tree.
Definition: fdt.h:88
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
int strcmp(const char *first, const char *second)
Compare strings.
Definition: string.c:173
Flattened Device Tree.
A device tree token descriptor.
Definition: fdt.h:120
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
static struct image * image_tag(struct image *image, struct image_tag *tag)
Tag image.
Definition: image.h:296
#define ok(success)
Definition: test.h:46
int fdt_create(struct fdt_header **hdr, const char *cmdline, physaddr_t initrd, size_t initrd_len)
Create device tree.
Definition: fdt.c:1407
int fdt_u64(struct fdt *fdt, unsigned int offset, const char *name, uint64_t *value)
Get 64-bit integer property.
Definition: fdt.c:643
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:114
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
String functions.
int fdt_cells(struct fdt *fdt, unsigned int offset, const char *name, unsigned int index, unsigned int count, uint64_t *value)
Get integer property.
Definition: fdt.c:597
uint32_t u32
Definition: stdint.h:23