Blame treesource.c

Packit 2ad57b
/*
Packit 2ad57b
 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005.
Packit 2ad57b
 *
Packit 2ad57b
 *
Packit 2ad57b
 * This program is free software; you can redistribute it and/or
Packit 2ad57b
 * modify it under the terms of the GNU General Public License as
Packit 2ad57b
 * published by the Free Software Foundation; either version 2 of the
Packit 2ad57b
 * License, or (at your option) any later version.
Packit 2ad57b
 *
Packit 2ad57b
 *  This program is distributed in the hope that it will be useful,
Packit 2ad57b
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 2ad57b
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 2ad57b
 *  General Public License for more details.
Packit 2ad57b
 *
Packit 2ad57b
 *  You should have received a copy of the GNU General Public License
Packit 2ad57b
 *  along with this program; if not, write to the Free Software
Packit 2ad57b
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
Packit 2ad57b
 *                                                                   USA
Packit 2ad57b
 */
Packit 2ad57b
Packit 2ad57b
#include "dtc.h"
Packit 2ad57b
#include "srcpos.h"
Packit 2ad57b
Packit 2ad57b
extern FILE *yyin;
Packit 2ad57b
extern int yyparse(void);
Packit 2ad57b
extern YYLTYPE yylloc;
Packit 2ad57b
Packit 2ad57b
struct dt_info *parser_output;
Packit 2ad57b
bool treesource_error;
Packit 2ad57b
Packit 2ad57b
struct dt_info *dt_from_source(const char *fname)
Packit 2ad57b
{
Packit 2ad57b
	parser_output = NULL;
Packit 2ad57b
	treesource_error = false;
Packit 2ad57b
Packit 2ad57b
	srcfile_push(fname);
Packit 2ad57b
	yyin = current_srcfile->f;
Packit 2ad57b
	yylloc.file = current_srcfile;
Packit 2ad57b
Packit 2ad57b
	if (yyparse() != 0)
Packit 2ad57b
		die("Unable to parse input tree\n");
Packit 2ad57b
Packit 2ad57b
	if (treesource_error)
Packit 2ad57b
		die("Syntax error parsing input tree\n");
Packit 2ad57b
Packit 2ad57b
	return parser_output;
Packit 2ad57b
}
Packit 2ad57b
Packit 2ad57b
static void write_prefix(FILE *f, int level)
Packit 2ad57b
{
Packit 2ad57b
	int i;
Packit 2ad57b
Packit 2ad57b
	for (i = 0; i < level; i++)
Packit 2ad57b
		fputc('\t', f);
Packit 2ad57b
}
Packit 2ad57b
Packit 2ad57b
static bool isstring(char c)
Packit 2ad57b
{
Packit 2ad57b
	return (isprint((unsigned char)c)
Packit 2ad57b
		|| (c == '\0')
Packit 2ad57b
		|| strchr("\a\b\t\n\v\f\r", c));
Packit 2ad57b
}
Packit 2ad57b
Packit 2ad57b
static void write_propval_string(FILE *f, struct data val)
Packit 2ad57b
{
Packit 2ad57b
	const char *str = val.val;
Packit 2ad57b
	int i;
Packit 2ad57b
	struct marker *m = val.markers;
Packit 2ad57b
Packit 2ad57b
	assert(str[val.len-1] == '\0');
Packit 2ad57b
Packit 2ad57b
	while (m && (m->offset == 0)) {
Packit 2ad57b
		if (m->type == LABEL)
Packit 2ad57b
			fprintf(f, "%s: ", m->ref);
Packit 2ad57b
		m = m->next;
Packit 2ad57b
	}
Packit 2ad57b
	fprintf(f, "\"");
Packit 2ad57b
Packit 2ad57b
	for (i = 0; i < (val.len-1); i++) {
Packit 2ad57b
		char c = str[i];
Packit 2ad57b
Packit 2ad57b
		switch (c) {
Packit 2ad57b
		case '\a':
Packit 2ad57b
			fprintf(f, "\\a");
Packit 2ad57b
			break;
Packit 2ad57b
		case '\b':
Packit 2ad57b
			fprintf(f, "\\b");
Packit 2ad57b
			break;
Packit 2ad57b
		case '\t':
Packit 2ad57b
			fprintf(f, "\\t");
Packit 2ad57b
			break;
Packit 2ad57b
		case '\n':
Packit 2ad57b
			fprintf(f, "\\n");
Packit 2ad57b
			break;
Packit 2ad57b
		case '\v':
Packit 2ad57b
			fprintf(f, "\\v");
Packit 2ad57b
			break;
Packit 2ad57b
		case '\f':
Packit 2ad57b
			fprintf(f, "\\f");
Packit 2ad57b
			break;
Packit 2ad57b
		case '\r':
Packit 2ad57b
			fprintf(f, "\\r");
Packit 2ad57b
			break;
Packit 2ad57b
		case '\\':
Packit 2ad57b
			fprintf(f, "\\\\");
Packit 2ad57b
			break;
Packit 2ad57b
		case '\"':
Packit 2ad57b
			fprintf(f, "\\\"");
Packit 2ad57b
			break;
Packit 2ad57b
		case '\0':
Packit 2ad57b
			fprintf(f, "\", ");
Packit 2ad57b
			while (m && (m->offset <= (i + 1))) {
Packit 2ad57b
				if (m->type == LABEL) {
Packit 2ad57b
					assert(m->offset == (i+1));
Packit 2ad57b
					fprintf(f, "%s: ", m->ref);
Packit 2ad57b
				}
Packit 2ad57b
				m = m->next;
Packit 2ad57b
			}
Packit 2ad57b
			fprintf(f, "\"");
Packit 2ad57b
			break;
Packit 2ad57b
		default:
Packit 2ad57b
			if (isprint((unsigned char)c))
Packit 2ad57b
				fprintf(f, "%c", c);
Packit 2ad57b
			else
Packit 2ad57b
				fprintf(f, "\\x%02hhx", c);
Packit 2ad57b
		}
Packit 2ad57b
	}
Packit 2ad57b
	fprintf(f, "\"");
Packit 2ad57b
Packit 2ad57b
	/* Wrap up any labels at the end of the value */
Packit 2ad57b
	for_each_marker_of_type(m, LABEL) {
Packit 2ad57b
		assert (m->offset == val.len);
Packit 2ad57b
		fprintf(f, " %s:", m->ref);
Packit 2ad57b
	}
Packit 2ad57b
}
Packit 2ad57b
Packit 2ad57b
static void write_propval_cells(FILE *f, struct data val)
Packit 2ad57b
{
Packit 2ad57b
	void *propend = val.val + val.len;
Packit 2ad57b
	fdt32_t *cp = (fdt32_t *)val.val;
Packit 2ad57b
	struct marker *m = val.markers;
Packit 2ad57b
Packit 2ad57b
	fprintf(f, "<");
Packit 2ad57b
	for (;;) {
Packit 2ad57b
		while (m && (m->offset <= ((char *)cp - val.val))) {
Packit 2ad57b
			if (m->type == LABEL) {
Packit 2ad57b
				assert(m->offset == ((char *)cp - val.val));
Packit 2ad57b
				fprintf(f, "%s: ", m->ref);
Packit 2ad57b
			}
Packit 2ad57b
			m = m->next;
Packit 2ad57b
		}
Packit 2ad57b
Packit 2ad57b
		fprintf(f, "0x%x", fdt32_to_cpu(*cp++));
Packit 2ad57b
		if ((void *)cp >= propend)
Packit 2ad57b
			break;
Packit 2ad57b
		fprintf(f, " ");
Packit 2ad57b
	}
Packit 2ad57b
Packit 2ad57b
	/* Wrap up any labels at the end of the value */
Packit 2ad57b
	for_each_marker_of_type(m, LABEL) {
Packit 2ad57b
		assert (m->offset == val.len);
Packit 2ad57b
		fprintf(f, " %s:", m->ref);
Packit 2ad57b
	}
Packit 2ad57b
	fprintf(f, ">");
Packit 2ad57b
}
Packit 2ad57b
Packit 2ad57b
static void write_propval_bytes(FILE *f, struct data val)
Packit 2ad57b
{
Packit 2ad57b
	void *propend = val.val + val.len;
Packit 2ad57b
	const char *bp = val.val;
Packit 2ad57b
	struct marker *m = val.markers;
Packit 2ad57b
Packit 2ad57b
	fprintf(f, "[");
Packit 2ad57b
	for (;;) {
Packit 2ad57b
		while (m && (m->offset == (bp-val.val))) {
Packit 2ad57b
			if (m->type == LABEL)
Packit 2ad57b
				fprintf(f, "%s: ", m->ref);
Packit 2ad57b
			m = m->next;
Packit 2ad57b
		}
Packit 2ad57b
Packit 2ad57b
		fprintf(f, "%02hhx", (unsigned char)(*bp++));
Packit 2ad57b
		if ((const void *)bp >= propend)
Packit 2ad57b
			break;
Packit 2ad57b
		fprintf(f, " ");
Packit 2ad57b
	}
Packit 2ad57b
Packit 2ad57b
	/* Wrap up any labels at the end of the value */
Packit 2ad57b
	for_each_marker_of_type(m, LABEL) {
Packit 2ad57b
		assert (m->offset == val.len);
Packit 2ad57b
		fprintf(f, " %s:", m->ref);
Packit 2ad57b
	}
Packit 2ad57b
	fprintf(f, "]");
Packit 2ad57b
}
Packit 2ad57b
Packit 2ad57b
static void write_propval(FILE *f, struct property *prop)
Packit 2ad57b
{
Packit 2ad57b
	int len = prop->val.len;
Packit 2ad57b
	const char *p = prop->val.val;
Packit 2ad57b
	struct marker *m = prop->val.markers;
Packit 2ad57b
	int nnotstring = 0, nnul = 0;
Packit 2ad57b
	int nnotstringlbl = 0, nnotcelllbl = 0;
Packit 2ad57b
	int i;
Packit 2ad57b
Packit 2ad57b
	if (len == 0) {
Packit 2ad57b
		fprintf(f, ";\n");
Packit 2ad57b
		return;
Packit 2ad57b
	}
Packit 2ad57b
Packit 2ad57b
	for (i = 0; i < len; i++) {
Packit 2ad57b
		if (! isstring(p[i]))
Packit 2ad57b
			nnotstring++;
Packit 2ad57b
		if (p[i] == '\0')
Packit 2ad57b
			nnul++;
Packit 2ad57b
	}
Packit 2ad57b
Packit 2ad57b
	for_each_marker_of_type(m, LABEL) {
Packit 2ad57b
		if ((m->offset > 0) && (prop->val.val[m->offset - 1] != '\0'))
Packit 2ad57b
			nnotstringlbl++;
Packit 2ad57b
		if ((m->offset % sizeof(cell_t)) != 0)
Packit 2ad57b
			nnotcelllbl++;
Packit 2ad57b
	}
Packit 2ad57b
Packit 2ad57b
	fprintf(f, " = ");
Packit 2ad57b
	if ((p[len-1] == '\0') && (nnotstring == 0) && (nnul < (len-nnul))
Packit 2ad57b
	    && (nnotstringlbl == 0)) {
Packit 2ad57b
		write_propval_string(f, prop->val);
Packit 2ad57b
	} else if (((len % sizeof(cell_t)) == 0) && (nnotcelllbl == 0)) {
Packit 2ad57b
		write_propval_cells(f, prop->val);
Packit 2ad57b
	} else {
Packit 2ad57b
		write_propval_bytes(f, prop->val);
Packit 2ad57b
	}
Packit 2ad57b
Packit 2ad57b
	fprintf(f, ";\n");
Packit 2ad57b
}
Packit 2ad57b
Packit 2ad57b
static void write_tree_source_node(FILE *f, struct node *tree, int level)
Packit 2ad57b
{
Packit 2ad57b
	struct property *prop;
Packit 2ad57b
	struct node *child;
Packit 2ad57b
	struct label *l;
Packit 2ad57b
Packit 2ad57b
	write_prefix(f, level);
Packit 2ad57b
	for_each_label(tree->labels, l)
Packit 2ad57b
		fprintf(f, "%s: ", l->label);
Packit 2ad57b
	if (tree->name && (*tree->name))
Packit 2ad57b
		fprintf(f, "%s {\n", tree->name);
Packit 2ad57b
	else
Packit 2ad57b
		fprintf(f, "/ {\n");
Packit 2ad57b
Packit 2ad57b
	for_each_property(tree, prop) {
Packit 2ad57b
		write_prefix(f, level+1);
Packit 2ad57b
		for_each_label(prop->labels, l)
Packit 2ad57b
			fprintf(f, "%s: ", l->label);
Packit 2ad57b
		fprintf(f, "%s", prop->name);
Packit 2ad57b
		write_propval(f, prop);
Packit 2ad57b
	}
Packit 2ad57b
	for_each_child(tree, child) {
Packit 2ad57b
		fprintf(f, "\n");
Packit 2ad57b
		write_tree_source_node(f, child, level+1);
Packit 2ad57b
	}
Packit 2ad57b
	write_prefix(f, level);
Packit 2ad57b
	fprintf(f, "};\n");
Packit 2ad57b
}
Packit 2ad57b
Packit 2ad57b
Packit 2ad57b
void dt_to_source(FILE *f, struct dt_info *dti)
Packit 2ad57b
{
Packit 2ad57b
	struct reserve_info *re;
Packit 2ad57b
Packit 2ad57b
	fprintf(f, "/dts-v1/;\n\n");
Packit 2ad57b
Packit 2ad57b
	for (re = dti->reservelist; re; re = re->next) {
Packit 2ad57b
		struct label *l;
Packit 2ad57b
Packit 2ad57b
		for_each_label(re->labels, l)
Packit 2ad57b
			fprintf(f, "%s: ", l->label);
Packit 2ad57b
		fprintf(f, "/memreserve/\t0x%016llx 0x%016llx;\n",
Packit 2ad57b
			(unsigned long long)re->address,
Packit 2ad57b
			(unsigned long long)re->size);
Packit 2ad57b
	}
Packit 2ad57b
Packit 2ad57b
	write_tree_source_node(f, dti->dt, 0);
Packit 2ad57b
}
Packit 2ad57b