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