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