xref: /freebsd/usr.bin/dtc/fdt.cc (revision fcb560670601b2a4d87bb31d7531c8dcc37ee71b)
1 /*-
2  * Copyright (c) 2013 David Chisnall
3  * All rights reserved.
4  *
5  * This software was developed by SRI International and the University of
6  * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
7  * ("CTSRD"), as part of the DARPA CRASH research programme.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  *
30  * $FreeBSD$
31  */
32 
33 #define __STDC_LIMIT_MACROS 1
34 
35 #include "fdt.hh"
36 
37 #include <algorithm>
38 #include <ctype.h>
39 #include <fcntl.h>
40 #include <inttypes.h>
41 #include <libgen.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <unistd.h>
45 #include <sys/types.h>
46 #include <sys/stat.h>
47 #include "dtb.hh"
48 
49 namespace dtc
50 {
51 
52 namespace fdt
53 {
54 
55 uint32_t
56 property_value::get_as_uint32()
57 {
58 	if (byte_data.size() != 4)
59 	{
60 		return 0;
61 	}
62 	uint32_t v = 0;
63 	v &= byte_data[0] << 24;
64 	v &= byte_data[1] << 16;
65 	v &= byte_data[2] << 8;
66 	v &= byte_data[3] << 0;
67 	return v;
68 }
69 
70 void
71 property_value::push_to_buffer(byte_buffer &buffer)
72 {
73 	if (!byte_data.empty())
74 	{
75 		buffer.insert(buffer.end(), byte_data.begin(), byte_data.end());
76 	}
77 	else
78 	{
79 		string_data.push_to_buffer(buffer, true);
80 		// Trailing nul
81 		buffer.push_back(0);
82 	}
83 }
84 
85 void
86 property_value::write_dts(FILE *file)
87 {
88 	resolve_type();
89 	switch (type)
90 	{
91 		default:
92 			assert(0 && "Invalid type");
93 		case STRING:
94 		case STRING_LIST:
95 		case CROSS_REFERENCE:
96 			write_as_string(file);
97 			break;
98 		case PHANDLE:
99 			write_as_cells(file);
100 			break;
101 		case BINARY:
102 			if (byte_data.size() % 4 == 0)
103 			{
104 				write_as_cells(file);
105 				break;
106 			}
107 			write_as_bytes(file);
108 			break;
109 	}
110 }
111 
112 void
113 property_value::resolve_type()
114 {
115 	if (type != UNKNOWN)
116 	{
117 		return;
118 	}
119 	if (byte_data.empty())
120 	{
121 		type = STRING;
122 		return;
123 	}
124 	if (byte_data.back() == 0)
125 	{
126 		bool is_all_printable = true;
127 		int nuls = 0;
128 		int bytes = 0;
129 		for (byte_buffer::iterator i=byte_data.begin(), e=byte_data.end()-1; i<e ; i++)
130 		{
131 			bytes++;
132 			is_all_printable &= (*i == '\0') || isprint(*i);
133 			if (*i == '\0')
134 			{
135 				nuls++;
136 			}
137 			if (!is_all_printable)
138 			{
139 				break;
140 			}
141 		}
142 		if ((is_all_printable && (bytes > nuls)) || bytes == 0)
143 		{
144 			type = STRING;
145 			if (nuls > 0)
146 			{
147 				type = STRING_LIST;
148 			}
149 			return;
150 		}
151 	}
152 	type = BINARY;
153 }
154 
155 void
156 property_value::write_as_string(FILE *file)
157 {
158 	putc('"', file);
159 	if (byte_data.empty())
160 	{
161 		string_data.print(file);
162 	}
163 	else
164 	{
165 		for (byte_buffer::iterator i=byte_data.begin(), e=byte_data.end()-1; i!=e ; ++i)
166 		{
167 			// FIXME Escape tabs, newlines, and so on.
168 			if (*i == '\0')
169 			{
170 				fputs("\", \"", file);
171 				continue;
172 			}
173 			putc(*i, file);
174 		}
175 	}
176 	putc('"', file);
177 }
178 
179 void
180 property_value::write_as_cells(FILE *file)
181 {
182 	putc('<', file);
183 	assert((byte_data.size() % 4) == 0);
184 	for (byte_buffer::iterator i=byte_data.begin(), e=byte_data.end(); i!=e ; ++i)
185 	{
186 		uint32_t v = 0;
187 		v = (v << 8) | *i;
188 		++i;
189 		v = (v << 8) | *i;
190 		++i;
191 		v = (v << 8) | *i;
192 		++i;
193 		v = (v << 8) | *i;
194 		fprintf(file, "0x%" PRIx32, v);
195 		if (i+1 != e)
196 		{
197 			putc(' ', file);
198 		}
199 	}
200 	putc('>', file);
201 }
202 
203 void
204 property_value::write_as_bytes(FILE *file)
205 {
206 	putc('[', file);
207 	for (byte_buffer::iterator i=byte_data.begin(), e=byte_data.end(); i!=e ; i++)
208 	{
209 		fprintf(file, "%02hhx", *i);
210 		if (i+1 != e)
211 		{
212 			putc(' ', file);
213 		}
214 	}
215 	putc(']', file);
216 }
217 
218 void
219 property::parse_string(input_buffer &input)
220 {
221 	property_value v;
222 	assert(input[0] == '"');
223 	++input;
224 	const char *start = (const char*)input;
225 	int length = 0;
226 	while (char c = input[0])
227 	{
228 		if (c == '"' && input[-1] != '\\')
229 		{
230 			input.consume('"');
231 			break;
232 		}
233 		++input;
234 		++length;
235 	}
236 	v.string_data = string(start, length);
237 	values.push_back(v);
238 }
239 
240 void
241 property::parse_cells(input_buffer &input)
242 {
243 	assert(input[0] == '<');
244 	++input;
245 	property_value v;
246 	input.next_token();
247 	while (!input.consume('>'))
248 	{
249 		input.next_token();
250 		// If this is a phandle then we need to get the name of the
251 		// referenced node
252 		if (input.consume('&'))
253 		{
254 			input.next_token();
255 			// FIXME: We should support full paths here, but we
256 			// don't.
257 			string referenced = string::parse_node_name(input);
258 			if (referenced.empty())
259 			{
260 				input.parse_error("Expected node name");
261 				valid = false;
262 				return;
263 			}
264 			input.next_token();
265 			// If we already have some bytes, make the phandle a
266 			// separate component.
267 			if (!v.byte_data.empty())
268 			{
269 				values.push_back(v);
270 				v = property_value();
271 			}
272 			v.string_data = referenced;
273 			v.type = property_value::PHANDLE;
274 			values.push_back(v);
275 			v = property_value();
276 		}
277 		else
278 		{
279 			//FIXME: We should support labels in the middle
280 			//of these, but we don't.
281 			long long val;
282 			if (!input.consume_integer(val))
283 			{
284 				input.parse_error("Expected numbers in array of cells");
285 				valid = false;
286 				return;
287 			}
288 			if ((val < 0) || (val > UINT32_MAX))
289 			{
290 				input.parse_error("Value out of range");
291 				valid = false;
292 				return;
293 			}
294 			push_big_endian(v.byte_data, (uint32_t)val);
295 			input.next_token();
296 		}
297 	}
298 	// Don't store an empty string value here.
299 	if (v.byte_data.size() > 0)
300 	{
301 		values.push_back(v);
302 	}
303 }
304 
305 void
306 property::parse_bytes(input_buffer &input)
307 {
308 	assert(input[0] == '[');
309 	++input;
310 	property_value v;
311 	input.next_token();
312 	while (!input.consume(']'))
313 	{
314 		{
315 			//FIXME: We should support
316 			//labels in the middle of
317 			//these, but we don't.
318 			uint8_t val;
319 			if (!input.consume_hex_byte(val))
320 			{
321 				input.parse_error("Expected hex bytes in array of bytes");
322 				valid = false;
323 				return;
324 			}
325 			v.byte_data.push_back(val);
326 			input.next_token();
327 		}
328 	}
329 	values.push_back(v);
330 }
331 
332 void
333 property::parse_reference(input_buffer &input)
334 {
335 	assert(input[0] == '&');
336 	++input;
337 	input.next_token();
338 	property_value v;
339 	v.string_data = string::parse_node_name(input);
340 	if (v.string_data.empty())
341 	{
342 		input.parse_error("Expected node name");
343 		valid = false;
344 		return;
345 	}
346 	v.type = property_value::CROSS_REFERENCE;
347 	values.push_back(v);
348 }
349 
350 property::property(input_buffer &structs, input_buffer &strings)
351 {
352 	uint32_t name_offset;
353 	uint32_t length;
354 	valid = structs.consume_binary(length) &&
355 		structs.consume_binary(name_offset);
356 	if (!valid)
357 	{
358 		fprintf(stderr, "Failed to read property\n");
359 		return;
360 	}
361 	// Find the name
362 	input_buffer name_buffer = strings.buffer_from_offset(name_offset);
363 	if (name_buffer.empty())
364 	{
365 		fprintf(stderr, "Property name offset %" PRIu32
366 			" is past the end of the strings table\n",
367 			name_offset);
368 		valid = false;
369 		return;
370 	}
371 	key = string(name_buffer);
372 
373 	// If we're empty, do not push anything as value.
374 	if (!length)
375 		return;
376 
377 	// Read the value
378 	uint8_t byte;
379 	property_value v;
380 	for (uint32_t i=0 ; i<length ; i++)
381 	{
382 		if (!(valid = structs.consume_binary(byte)))
383 		{
384 			fprintf(stderr, "Failed to read property value\n");
385 			return;
386 		}
387 		v.byte_data.push_back(byte);
388 	}
389 	values.push_back(v);
390 }
391 
392 void property::parse_define(input_buffer &input, define_map *defines)
393 {
394 	input.consume('$');
395 	if (!defines)
396 	{
397 		input.parse_error("No predefined properties to match name\n");
398 		valid = false;
399 		return;
400 	}
401 	string name = string::parse_property_name(input);
402 	define_map::iterator found;
403 	if ((name == string()) ||
404 	    ((found = defines->find(name)) == defines->end()))
405 	{
406 		input.parse_error("Undefined property name\n");
407 		valid = false;
408 		return;
409 	}
410 	values.push_back((*found).second->values[0]);
411 }
412 
413 property::property(input_buffer &input,
414                    string k,
415                    string l,
416                    bool semicolonTerminated,
417                    define_map *defines) : key(k), label(l), valid(true)
418 {
419 	do {
420 		input.next_token();
421 		switch (input[0])
422 		{
423 			case '$':
424 			{
425 				parse_define(input, defines);
426 				if (valid)
427 				{
428 					break;
429 				}
430 			}
431 			default:
432 				input.parse_error("Invalid property value.");
433 				valid = false;
434 				return;
435 			case '"':
436 				parse_string(input);
437 				break;
438 			case '<':
439 				parse_cells(input);
440 				break;
441 			case '[':
442 				parse_bytes(input);
443 				break;
444 			case '&':
445 				parse_reference(input);
446 				break;
447 			case ';':
448 			{
449 				break;
450 			}
451 		}
452 		input.next_token();
453 	} while (input.consume(','));
454 	if (semicolonTerminated && !input.consume(';'))
455 	{
456 		input.parse_error("Expected ; at end of property");
457 		valid = false;
458 	}
459 }
460 
461 property*
462 property::parse_dtb(input_buffer &structs, input_buffer &strings)
463 {
464 	property *p = new property(structs, strings);
465 	if (!p->valid)
466 	{
467 		delete p;
468 		p = 0;
469 	}
470 	return p;
471 }
472 
473 property*
474 property::parse(input_buffer &input, string key, string label,
475                 bool semicolonTerminated, define_map *defines)
476 {
477 	property *p = new property(input, key, label, semicolonTerminated, defines);
478 	if (!p->valid)
479 	{
480 		delete p;
481 		p = 0;
482 	}
483 	return p;
484 }
485 
486 void
487 property::write(dtb::output_writer &writer, dtb::string_table &strings)
488 {
489 	writer.write_token(dtb::FDT_PROP);
490 	byte_buffer value_buffer;
491 	for (value_iterator i=begin(), e=end() ; i!=e ; ++i)
492 	{
493 		i->push_to_buffer(value_buffer);
494 	}
495 	writer.write_data((uint32_t)value_buffer.size());
496 	writer.write_comment(key);
497 	writer.write_data(strings.add_string(key));
498 	writer.write_data(value_buffer);
499 }
500 
501 void
502 property::write_dts(FILE *file, int indent)
503 {
504 	for (int i=0 ; i<indent ; i++)
505 	{
506 		putc('\t', file);
507 	}
508 	if (label != string())
509 	{
510 		label.print(file);
511 		fputs(": ", file);
512 	}
513 	if (key != string())
514 	{
515 		key.print(file);
516 	}
517 	if (!values.empty())
518 	{
519 		fputs(" = ", file);
520 		for (value_iterator i=begin(), e=end() ; i!=e ; ++i)
521 		{
522 			i->write_dts(file);
523 			if (i+1 != e)
524 			{
525 				putc(',', file);
526 				putc(' ', file);
527 			}
528 		}
529 	}
530 	fputs(";\n", file);
531 }
532 
533 string
534 node::parse_name(input_buffer &input, bool &is_property, const char *error)
535 {
536 	if (!valid)
537 	{
538 		return string();
539 	}
540 	input.next_token();
541 	if (is_property)
542 	{
543 		return string::parse_property_name(input);
544 	}
545 	string n = string::parse_node_or_property_name(input, is_property);
546 	if (n.empty())
547 	{
548 		if (n.empty())
549 		{
550 			input.parse_error(error);
551 			valid = false;
552 		}
553 	}
554 	return n;
555 }
556 
557 node::node(input_buffer &structs, input_buffer &strings) : valid(true)
558 {
559 	const char *name_start = (const char*)structs;
560 	int name_length = 0;
561 	while (structs[0] != '\0' && structs[0] != '@')
562 	{
563 		name_length++;
564 		++structs;
565 	}
566 	name = string(name_start, name_length);
567 	if (structs[0] == '@')
568 	{
569 		++structs;
570 		name_start = (const char*)structs;
571 		name_length = 0;
572 		while (structs[0] != '\0')
573 		{
574 			name_length++;
575 			++structs;
576 		}
577 		unit_address = string(name_start, name_length);
578 	}
579 	++structs;
580 	uint32_t token;
581 	while (structs.consume_binary(token))
582 	{
583 		switch (token)
584 		{
585 			default:
586 				fprintf(stderr, "Unexpected token 0x%" PRIx32
587 					" while parsing node.\n", token);
588 				valid = false;
589 				return;
590 			// Child node, parse it.
591 			case dtb::FDT_BEGIN_NODE:
592 			{
593 				node *child = node::parse_dtb(structs, strings);
594 				if (child == 0)
595 				{
596 					valid = false;
597 					return;
598 				}
599 				children.push_back(child);
600 				break;
601 			}
602 			// End of this node, no errors.
603 			case dtb::FDT_END_NODE:
604 				return;
605 			// Property, parse it.
606 			case dtb::FDT_PROP:
607 			{
608 				property *prop = property::parse_dtb(structs, strings);
609 				if (prop == 0)
610 				{
611 					valid = false;
612 					return;
613 				}
614 				properties.push_back(prop);
615 				break;
616 			}
617 				break;
618 			// End of structs table.  Should appear after
619 			// the end of the last node.
620 			case dtb::FDT_END:
621 				fprintf(stderr, "Unexpected FDT_END token while parsing node.\n");
622 				valid = false;
623 				return;
624 			// NOPs are padding.  Ignore them.
625 			case dtb::FDT_NOP:
626 				break;
627 		}
628 	}
629 	fprintf(stderr, "Failed to read token from structs table while parsing node.\n");
630 	valid = false;
631 	return;
632 }
633 
634 node::node(input_buffer &input, string n, string l, string a, define_map *defines) :
635 	label(l), name(n), unit_address(a), valid(true)
636 {
637 	if (!input.consume('{'))
638 	{
639 		input.parse_error("Expected { to start new device tree node.\n");
640 	}
641 	input.next_token();
642 	while (valid && !input.consume('}'))
643 	{
644 		// flag set if we find any characters that are only in
645 		// the property name character set, not the node
646 		bool is_property = false;
647 		string child_name, child_label, child_address;
648 		child_name = parse_name(input, is_property,
649 				"Expected property or node name");
650 		if (input.consume(':'))
651 		{
652 			// Node labels can contain any characters?  The
653 			// spec doesn't say, so we guess so...
654 			is_property = false;
655 			child_label = child_name;
656 			child_name = parse_name(input, is_property, "Expected property or node name");
657 		}
658 		if (input.consume('@'))
659 		{
660 			child_address = parse_name(input, is_property, "Expected unit address");
661 		}
662 		if (!valid)
663 		{
664 			return;
665 		}
666 		input.next_token();
667 		// If we're parsing a property, then we must actually do that.
668 		if (input.consume('='))
669 		{
670 			property *p= property::parse(input, child_name,
671 					child_label, true, defines);
672 			if (p == 0)
673 			{
674 				valid = false;
675 			}
676 			else
677 			{
678 				properties.push_back(p);
679 			}
680 		}
681 		else if (!is_property && input[0] == ('{'))
682 		{
683 			node *child = node::parse(input, child_name,
684 					child_label, child_address, defines);
685 			if (child)
686 			{
687 				children.push_back(child);
688 			}
689 			else
690 			{
691 				valid = false;
692 			}
693 		}
694 		else if (input.consume(';'))
695 		{
696 			properties.push_back(new property(child_name, child_label));
697 		}
698 		else
699 		{
700 			input.parse_error("Error parsing property.");
701 			valid = false;
702 		}
703 		input.next_token();
704 	}
705 	input.consume(';');
706 }
707 
708 bool
709 node::cmp_properties(property *p1, property *p2)
710 {
711 	return p1->get_key() < p2->get_key();
712 }
713 
714 bool
715 node::cmp_children(node *c1, node *c2)
716 {
717 	if (c1->name == c2->name)
718 	{
719 		return c1->unit_address < c2->unit_address;
720 	}
721 	return c1->name < c2->name;
722 }
723 
724 void
725 node::sort()
726 {
727 	std::sort(property_begin(), property_end(), cmp_properties);
728 	std::sort(child_begin(), child_end(), cmp_children);
729 	for (child_iterator i=child_begin(), e=child_end() ; i!=e ; ++i)
730 	{
731 		(*i)->sort();
732 	}
733 }
734 
735 node*
736 node::parse(input_buffer &input,
737             string name,
738             string label,
739             string address,
740             define_map *defines)
741 {
742 	node *n = new node(input, name, label, address, defines);
743 	if (!n->valid)
744 	{
745 		delete n;
746 		n = 0;
747 	}
748 	return n;
749 }
750 
751 node*
752 node::parse_dtb(input_buffer &structs, input_buffer &strings)
753 {
754 	node *n = new node(structs, strings);
755 	if (!n->valid)
756 	{
757 		delete n;
758 		n = 0;
759 	}
760 	return n;
761 }
762 
763 node::~node()
764 {
765 	while (!children.empty())
766 	{
767 		delete children.back();
768 		children.pop_back();
769 	}
770 	while (!properties.empty())
771 	{
772 		delete properties.back();
773 		properties.pop_back();
774 	}
775 }
776 
777 property*
778 node::get_property(string key)
779 {
780 	for (property_iterator i=property_begin(), e=property_end() ; i!=e ; ++i)
781 	{
782 		if ((*i)->get_key() == key)
783 		{
784 			return *i;
785 		}
786 	}
787 	return 0;
788 }
789 
790 void
791 node::merge_node(node *other)
792 {
793 	if (!other->label.empty())
794 	{
795 		label = other->label;
796 	}
797 	// Note: this is an O(n*m) operation.  It might be sensible to
798 	// optimise this if we find that there are nodes with very
799 	// large numbers of properties, but for typical usage the
800 	// entire vector will fit (easily) into cache, so iterating
801 	// over it repeatedly isn't that expensive.
802 	while (!other->properties.empty())
803 	{
804 		property *p = other->properties.front();
805 		for (property_iterator i=property_begin(), e=property_end() ; i!=e ; ++i)
806 		{
807 			if ((*i)->get_key() == p->get_key())
808 			{
809 				delete *i;
810 				properties.erase(i);
811 				break;
812 			}
813 		}
814 		add_property(p);
815 		other->properties.erase(other->properties.begin());
816 	}
817 	while (!other->children.empty())
818 	{
819 		node *c = other->children.front();
820 		bool found = false;
821 		for (child_iterator i=child_begin(), e=child_end() ; i!=e ; ++i)
822 		{
823 			if ((*i)->name == c->name && (*i)->unit_address == c->unit_address)
824 			{
825 				(*i)->merge_node(c);
826 				delete c;
827 				found = true;
828 				break;
829 			}
830 		}
831 		if (!found)
832 		{
833 			children.push_back(c);
834 		}
835 		other->children.erase(other->children.begin());
836 	}
837 }
838 
839 void
840 node::write(dtb::output_writer &writer, dtb::string_table &strings)
841 {
842 	writer.write_token(dtb::FDT_BEGIN_NODE);
843 	byte_buffer name_buffer;
844 	name.push_to_buffer(name_buffer);
845 	if (unit_address != string())
846 	{
847 		name_buffer.push_back('@');
848 		unit_address.push_to_buffer(name_buffer);
849 	}
850 	writer.write_comment(name);
851 	writer.write_data(name_buffer);
852 	writer.write_data((uint8_t)0);
853 	for (property_iterator i=property_begin(), e=property_end() ; i!=e ; ++i)
854 	{
855 		(*i)->write(writer, strings);
856 	}
857 	for (child_iterator i=child_begin(), e=child_end() ; i!=e ; ++i)
858 	{
859 		(*i)->write(writer, strings);
860 	}
861 	writer.write_token(dtb::FDT_END_NODE);
862 }
863 
864 void
865 node::write_dts(FILE *file, int indent)
866 {
867 	for (int i=0 ; i<indent ; i++)
868 	{
869 		putc('\t', file);
870 	}
871 	if (label != string())
872 	{
873 		label.print(file);
874 		fputs(": ", file);
875 	}
876 	if (name != string())
877 	{
878 		name.print(file);
879 	}
880 	if (unit_address != string())
881 	{
882 		putc('@', file);
883 		unit_address.print(file);
884 	}
885 	fputs(" {\n\n", file);
886 	for (property_iterator i=property_begin(), e=property_end() ; i!=e ; ++i)
887 	{
888 		(*i)->write_dts(file, indent+1);
889 	}
890 	for (child_iterator i=child_begin(), e=child_end() ; i!=e ; ++i)
891 	{
892 		(*i)->write_dts(file, indent+1);
893 	}
894 	for (int i=0 ; i<indent ; i++)
895 	{
896 		putc('\t', file);
897 	}
898 	fputs("};\n", file);
899 }
900 
901 void
902 device_tree::collect_names_recursive(node* n, node_path &path)
903 {
904 	string name = n->label;
905 	path.push_back(std::make_pair(n->name, n->unit_address));
906 	if (name != string())
907 	{
908 		if (node_names.find(name) == node_names.end())
909 		{
910 			node_names.insert(std::make_pair(name, n));
911 			node_paths.insert(std::make_pair(name, path));
912 		}
913 		else
914 		{
915 			node_names[name] = (node*)-1;
916 			std::map<string, node_path>::iterator i = node_paths.find(name);
917 			if (i != node_paths.end())
918 			{
919 				node_paths.erase(name);
920 			}
921 			fprintf(stderr, "Label not unique: ");
922 			name.dump();
923 			fprintf(stderr, ".  References to this label will not be resolved.");
924 		}
925 	}
926 	for (node::child_iterator i=n->child_begin(), e=n->child_end() ; i!=e ; ++i)
927 	{
928 		collect_names_recursive(*i, path);
929 	}
930 	path.pop_back();
931 	// Now we collect the phandles and properties that reference
932 	// other nodes.
933 	for (node::property_iterator i=n->property_begin(), e=n->property_end() ; i!=e ; ++i)
934 	{
935 		for (property::value_iterator p=(*i)->begin(),pe=(*i)->end() ; p!=pe ; ++p)
936 		{
937 			if (p->is_phandle())
938 			{
939 				phandles.push_back(&*p);
940 			}
941 			if (p->is_cross_reference())
942 			{
943 				cross_references.push_back(&*p);
944 			}
945 		}
946 		if ((*i)->get_key() == string("phandle") ||
947 		    (*i)->get_key() == string("linux,phandle"))
948 		{
949 			if ((*i)->begin()->byte_data.size() != 4)
950 			{
951 				fprintf(stderr, "Invalid phandle value for node ");
952 				n->name.dump();
953 				fprintf(stderr, ".  Should be a 4-byte value.\n");
954 				valid = false;
955 			}
956 			else
957 			{
958 				uint32_t phandle = (*i)->begin()->get_as_uint32();
959 				used_phandles.insert(std::make_pair(phandle, n));
960 			}
961 		}
962 	}
963 }
964 
965 void
966 device_tree::collect_names()
967 {
968 	node_path p;
969 	collect_names_recursive(root, p);
970 }
971 
972 void
973 device_tree::resolve_cross_references()
974 {
975 	for (std::vector<property_value*>::iterator i=cross_references.begin(), e=cross_references.end() ; i!=e ; ++i)
976 	{
977 		property_value* pv = *i;
978 		node_path path = node_paths[pv->string_data];
979 		// Skip the first name in the path.  It's always "", and implicitly /
980 		for (node_path::iterator p=path.begin()+1, pe=path.end() ; p!=pe ; ++p)
981 		{
982 			pv->byte_data.push_back('/');
983 			p->first.push_to_buffer(pv->byte_data);
984 			if (!(p->second.empty()))
985 			{
986 				pv->byte_data.push_back('@');
987 				p->second.push_to_buffer(pv->byte_data);
988 			}
989 		}
990 		pv->byte_data.push_back(0);
991 	}
992 	uint32_t phandle = 1;
993 	for (std::vector<property_value*>::iterator i=phandles.begin(), e=phandles.end() ; i!=e ; ++i)
994 	{
995 		string target_name = (*i)->string_data;
996 		node *target = node_names[target_name];
997 		if (target == 0)
998 		{
999 			fprintf(stderr, "Failed to find node with label:");
1000 			target_name.dump();
1001 			fprintf(stderr, "\n");
1002 			valid = 0;
1003 			return;
1004 		}
1005 		// If there is an existing phandle, use it
1006 		property *p = target->get_property("phandle");
1007 		if (p == 0)
1008 		{
1009 			p = target->get_property("linux,phandle");
1010 		}
1011 		if (p == 0)
1012 		{
1013 			// Otherwise insert a new phandle node
1014 			property_value v;
1015 			while (used_phandles.find(phandle) != used_phandles.end())
1016 			{
1017 				// Note that we only don't need to
1018 				// store this phandle in the set,
1019 				// because we are monotonically
1020 				// increasing the value of phandle and
1021 				// so will only ever revisit this value
1022 				// if we have used 2^32 phandles, at
1023 				// which point our blob won't fit in
1024 				// any 32-bit system and we've done
1025 				// something badly wrong elsewhere
1026 				// already.
1027 				phandle++;
1028 			}
1029 			push_big_endian(v.byte_data, phandle++);
1030 			if (phandle_node_name == BOTH || phandle_node_name == LINUX)
1031 			{
1032 				p = new property(string("linux,phandle"));
1033 				p->add_value(v);
1034 				target->add_property(p);
1035 			}
1036 			if (phandle_node_name == BOTH || phandle_node_name == EPAPR)
1037 			{
1038 				p = new property(string("phandle"));
1039 				p->add_value(v);
1040 				target->add_property(p);
1041 			}
1042 		}
1043 		p->begin()->push_to_buffer((*i)->byte_data);
1044 		assert((*i)->byte_data.size() == 4);
1045 	}
1046 }
1047 
1048 void
1049 device_tree::parse_roots(input_buffer &input, std::vector<node*> &roots)
1050 {
1051 	input.next_token();
1052 	while (valid && input.consume('/'))
1053 	{
1054 		input.next_token();
1055 		node *n = node::parse(input, string("", 1), string(), string(), &defines);
1056 		if (n)
1057 		{
1058 			roots.push_back(n);
1059 		}
1060 		else
1061 		{
1062 			valid = false;
1063 		}
1064 		input.next_token();
1065 	}
1066 }
1067 
1068 input_buffer*
1069 device_tree::buffer_for_file(const char *path)
1070 {
1071 	if (string(path) == string("-"))
1072 	{
1073 		input_buffer *b = new stream_input_buffer();
1074 		buffers.push_back(b);
1075 		return b;
1076 	}
1077 	int source = open(path, O_RDONLY);
1078 	if (source == -1)
1079 	{
1080 		fprintf(stderr, "Unable to open file %s\n", path);
1081 		return 0;
1082 	}
1083 	struct stat st;
1084 	if (fstat(source, &st) == 0 && S_ISDIR(st.st_mode))
1085 	{
1086 		fprintf(stderr, "File %s is a directory\n", path);
1087 		close(source);
1088 		return 0;
1089 	}
1090 	input_buffer *b = new mmap_input_buffer(source);
1091 	// Keep the buffer that owns the memory around for the lifetime
1092 	// of this FDT.  Ones simply referring to it may have shorter
1093 	// lifetimes.
1094 	buffers.push_back(b);
1095 	close(source);
1096 	return b;
1097 }
1098 
1099 template<class writer> void
1100 device_tree::write(int fd)
1101 {
1102 	dtb::string_table st;
1103 	dtb::header head;
1104 	writer head_writer;
1105 	writer reservation_writer;
1106 	writer struct_writer;
1107 	writer strings_writer;
1108 
1109 	// Build the reservation table
1110 	reservation_writer.write_comment(string("Memory reservations"));
1111 	reservation_writer.write_label(string("dt_reserve_map"));
1112 	for (std::vector<reservation>::iterator i=reservations.begin(),
1113 	     e=reservations.end() ; i!=e ; ++i)
1114 	{
1115 		reservation_writer.write_comment(string("Reservation start"));
1116 		reservation_writer.write_data(i->first);
1117 		reservation_writer.write_comment(string("Reservation length"));
1118 		reservation_writer.write_data(i->first);
1119 	}
1120 	// Write n spare reserve map entries, plus the trailing 0.
1121 	for (uint32_t i=0 ; i<=spare_reserve_map_entries ; i++)
1122 	{
1123 		reservation_writer.write_data((uint64_t)0);
1124 		reservation_writer.write_data((uint64_t)0);
1125 	}
1126 
1127 
1128 	struct_writer.write_comment(string("Device tree"));
1129 	struct_writer.write_label(string("dt_struct_start"));
1130 	root->write(struct_writer, st);
1131 	struct_writer.write_token(dtb::FDT_END);
1132 	struct_writer.write_label(string("dt_struct_end"));
1133 
1134 	st.write(strings_writer);
1135 	// Find the strings size before we stick padding on the end.
1136 	// Note: We should possibly use a new writer for the padding.
1137 	head.size_dt_strings = strings_writer.size();
1138 
1139 	// Stick the padding in the strings writer, but after the
1140 	// marker indicating that it's the end.
1141 	// Note: We probably should add a padding call to the writer so
1142 	// that the asm back end can write padding directives instead
1143 	// of a load of 0 bytes.
1144 	for (uint32_t i=0 ; i<blob_padding ; i++)
1145 	{
1146 		strings_writer.write_data((uint8_t)0);
1147 	}
1148 	head.totalsize = sizeof(head) + strings_writer.size() +
1149 		struct_writer.size() + reservation_writer.size();
1150 	while (head.totalsize < minimum_blob_size)
1151 	{
1152 		head.totalsize++;
1153 		strings_writer.write_data((uint8_t)0);
1154 	}
1155 	head.off_dt_struct = sizeof(head) + reservation_writer.size();;
1156 	head.off_dt_strings = head.off_dt_struct + struct_writer.size();
1157 	head.off_mem_rsvmap = sizeof(head);
1158 	head.boot_cpuid_phys = boot_cpu;
1159 	head.size_dt_struct = struct_writer.size();
1160 	head.write(head_writer);
1161 
1162 	head_writer.write_to_file(fd);
1163 	reservation_writer.write_to_file(fd);
1164 	struct_writer.write_to_file(fd);
1165 	strings_writer.write_label(string("dt_blob_end"));
1166 	strings_writer.write_to_file(fd);
1167 }
1168 
1169 node*
1170 device_tree::referenced_node(property_value &v)
1171 {
1172 	if (v.is_phandle())
1173 	{
1174 		return node_names[v.string_data];
1175 	}
1176 	if (v.is_binary())
1177 	{
1178 		return used_phandles[v.get_as_uint32()];
1179 	}
1180 	return 0;
1181 }
1182 
1183 void
1184 device_tree::write_binary(int fd)
1185 {
1186 	write<dtb::binary_writer>(fd);
1187 }
1188 
1189 void
1190 device_tree::write_asm(int fd)
1191 {
1192 	write<dtb::asm_writer>(fd);
1193 }
1194 
1195 void
1196 device_tree::write_dts(int fd)
1197 {
1198 	FILE *file = fdopen(fd, "w");
1199 	fputs("/dts-v1/;\n\n", file);
1200 
1201 	if (!reservations.empty())
1202 	{
1203 		const char msg[] = "/memreserve/";
1204 		fwrite(msg, sizeof(msg), 1, file);
1205 		for (std::vector<reservation>::iterator i=reservations.begin(),
1206 		     e=reservations.end() ; i!=e ; ++i)
1207 		{
1208 			fprintf(file, " %" PRIx64 " %" PRIx64, i->first, i->second);
1209 		}
1210 		fputs(";\n\n", file);
1211 	}
1212 	putc('/', file);
1213 	putc(' ', file);
1214 	root->write_dts(file, 0);
1215 	fclose(file);
1216 }
1217 
1218 void
1219 device_tree::parse_dtb(const char *fn, FILE *depfile)
1220 {
1221 	input_buffer *in = buffer_for_file(fn);
1222 	if (in == 0)
1223 	{
1224 		valid = false;
1225 		return;
1226 	}
1227 	input_buffer &input = *in;
1228 	dtb::header h;
1229 	valid = h.read_dtb(input);
1230 	boot_cpu = h.boot_cpuid_phys;
1231 	if (h.last_comp_version > 17)
1232 	{
1233 		fprintf(stderr, "Don't know how to read this version of the device tree blob");
1234 		valid = false;
1235 	}
1236 	if (!valid)
1237 	{
1238 		return;
1239 	}
1240 	input_buffer reservation_map =
1241 		input.buffer_from_offset(h.off_mem_rsvmap, 0);
1242 	uint64_t start, length;
1243 	do
1244 	{
1245 		if (!(reservation_map.consume_binary(start) &&
1246 		      reservation_map.consume_binary(length)))
1247 		{
1248 			fprintf(stderr, "Failed to read memory reservation table\n");
1249 			valid = false;
1250 			return;
1251 		}
1252 	} while (!((start == 0) && (length == 0)));
1253 	input_buffer struct_table =
1254 		input.buffer_from_offset(h.off_dt_struct, h.size_dt_struct);
1255 	input_buffer strings_table =
1256 		input.buffer_from_offset(h.off_dt_strings, h.size_dt_strings);
1257 	uint32_t token;
1258 	if (!(struct_table.consume_binary(token) &&
1259 		(token == dtb::FDT_BEGIN_NODE)))
1260 	{
1261 		fprintf(stderr, "Expected FDT_BEGIN_NODE token.\n");
1262 		valid = false;
1263 		return;
1264 	}
1265 	root = node::parse_dtb(struct_table, strings_table);
1266 	if (!(struct_table.consume_binary(token) && (token == dtb::FDT_END)))
1267 	{
1268 		fprintf(stderr, "Expected FDT_END token after parsing root node.\n");
1269 		valid = false;
1270 		return;
1271 	}
1272 	valid = (root != 0);
1273 }
1274 
1275 void
1276 device_tree::parse_dts(const char *fn, FILE *depfile)
1277 {
1278 	input_buffer *in = buffer_for_file(fn);
1279 	if (in == 0)
1280 	{
1281 		valid = false;
1282 		return;
1283 	}
1284 	std::vector<node*> roots;
1285 	input_buffer &input = *in;
1286 	input.next_token();
1287 	bool read_header = false;
1288 	// Read the header
1289 	if (input.consume("/dts-v1/;"))
1290 	{
1291 		read_header = true;
1292 	}
1293 	input.next_token();
1294 	while(input.consume("/include/"))
1295 	{
1296 		bool reallyInclude = true;
1297 		if (input.consume("if "))
1298 		{
1299 			input.next_token();
1300 			string name = string::parse_property_name(input);
1301 			// XXX: Error handling
1302 			if (defines.find(name) == defines.end())
1303 			{
1304 				reallyInclude = false;
1305 			}
1306 			input.consume('/');
1307 		}
1308 		input.next_token();
1309 		if (!input.consume('"'))
1310 		{
1311 			input.parse_error("Expected quoted filename");
1312 			valid = false;
1313 			return;
1314 		}
1315 		int length = 0;
1316 		while (input[length] != '"') length++;
1317 
1318 		const char *file = (const char*)input;
1319 		const char *dir = dirname(fn);
1320 		int dir_length = strlen(dir);
1321 		char *include_file = (char*)malloc(strlen(dir) + length + 2);
1322 		memcpy(include_file, dir, dir_length);
1323 		include_file[dir_length] = '/';
1324 		memcpy(include_file+dir_length+1, file, length);
1325 		include_file[dir_length+length+1] = 0;
1326 
1327 		input.consume(include_file+dir_length+1);
1328 		input.consume('"');
1329 		if (!reallyInclude)
1330 		{
1331 			continue;
1332 		}
1333 
1334 		input_buffer *include_buffer = buffer_for_file(include_file);
1335 
1336 		if (include_buffer == 0)
1337 		{
1338 			for (std::vector<const char*>::iterator i=include_paths.begin(), e=include_paths.end() ; e!=i ; ++i)
1339 			{
1340 				free(include_file);
1341 				dir = *i;
1342 				dir_length = strlen(dir);
1343 				include_file = (char*)malloc(strlen(dir) +
1344 						length + 2);
1345 				memcpy(include_file, dir, dir_length);
1346 				include_file[dir_length] = '/';
1347 				memcpy(include_file+dir_length+1, file, length);
1348 				include_file[dir_length+length+1] = 0;
1349 				include_buffer = buffer_for_file(include_file);
1350 				if (include_buffer != 0)
1351 				{
1352 					break;
1353 				}
1354 			}
1355 		}
1356 		if (depfile != 0)
1357 		{
1358 			putc(' ', depfile);
1359 			fputs(include_file, depfile);
1360 		}
1361 		if (include_buffer == 0)
1362 		{
1363 			valid = false;
1364 			return;
1365 		}
1366 		input_buffer &include = *include_buffer;
1367 		free((void*)include_file);
1368 
1369 		if (!read_header)
1370 		{
1371 			include.next_token();
1372 			read_header = include.consume("/dts-v1/;");
1373 		}
1374 		parse_roots(include, roots);
1375 	}
1376 	input.next_token();
1377 	if (!read_header)
1378 	{
1379 		input.parse_error("Expected /dts-v1/; version string");
1380 	}
1381 	// Read any memory reservations
1382 	while(input.consume("/memreserve/"))
1383 	{
1384 		long long start, len;
1385 		input.next_token();
1386 		// Read the start and length.
1387 		if (!(input.consume_integer(start) &&
1388 		    (input.next_token(),
1389 		    input.consume_integer(len))))
1390 		{
1391 			input.parse_error("Expected size on /memreserve/ node.");
1392 		}
1393 		input.next_token();
1394 		input.consume(';');
1395 		reservations.push_back(reservation(start, len));
1396 	}
1397 	parse_roots(input, roots);
1398 	switch (roots.size())
1399 	{
1400 		case 0:
1401 			valid = false;
1402 			input.parse_error("Failed to find root node /.");
1403 			return;
1404 		case 1:
1405 			root = roots[0];
1406 			break;
1407 		default:
1408 		{
1409 			root = roots[0];
1410 			for (std::vector<node*>::iterator i=roots.begin()+1,
1411 			     e=roots.end() ; i!=e ; ++i)
1412 			{
1413 				root->merge_node(*i);
1414 				delete *i;
1415 			}
1416 			roots.resize(1);
1417 		}
1418 	}
1419 	collect_names();
1420 	resolve_cross_references();
1421 }
1422 
1423 device_tree::~device_tree()
1424 {
1425 	if (root != 0)
1426 	{
1427 		delete root;
1428 	}
1429 	while (!buffers.empty())
1430 	{
1431 		delete buffers.back();
1432 		buffers.pop_back();
1433 	}
1434 	for (define_map::iterator i=defines.begin(), e=defines.end() ;
1435 	     i!=e ; ++i)
1436 	{
1437 		delete i->second;
1438 	}
1439 }
1440 
1441 bool device_tree::parse_define(const char *def)
1442 {
1443 	char *val = strchr(def, '=');
1444 	if (!val)
1445 	{
1446 		if (strlen(def) != 0)
1447 		{
1448 			string name(def);
1449 			defines[name];
1450 			return true;
1451 		}
1452 		return false;
1453 	}
1454 	string name(def, val-def);
1455 	val++;
1456 	input_buffer in = input_buffer(val, strlen(val));
1457 	property *p = property::parse(in, name, string(), false);
1458 	if (p)
1459 		defines[name] = p;
1460 	return p;
1461 }
1462 
1463 } // namespace fdt
1464 
1465 } // namespace dtc
1466 
1467