symbian-qemu-0.9.1-12/dtc-trunk/treesource.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /*
       
     2  * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005.
       
     3  *
       
     4  *
       
     5  * This program is free software; you can redistribute it and/or
       
     6  * modify it under the terms of the GNU General Public License as
       
     7  * published by the Free Software Foundation; either version 2 of the
       
     8  * License, or (at your option) any later version.
       
     9  *
       
    10  *  This program is distributed in the hope that it will be useful,
       
    11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    13  *  General Public License for more details.
       
    14  *
       
    15  *  You should have received a copy of the GNU General Public License
       
    16  *  along with this program; if not, write to the Free Software
       
    17  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
       
    18  *                                                                   USA
       
    19  */
       
    20 
       
    21 #include "dtc.h"
       
    22 #include "srcpos.h"
       
    23 
       
    24 extern FILE *yyin;
       
    25 extern int yyparse(void);
       
    26 
       
    27 struct boot_info *the_boot_info;
       
    28 int treesource_error;
       
    29 
       
    30 struct boot_info *dt_from_source(const char *fname)
       
    31 {
       
    32 	the_boot_info = NULL;
       
    33 	treesource_error = 0;
       
    34 
       
    35 	srcpos_file = dtc_open_file(fname, NULL);
       
    36 	yyin = srcpos_file->file;
       
    37 
       
    38 	if (yyparse() != 0)
       
    39 		die("Unable to parse input tree\n");
       
    40 
       
    41 	if (treesource_error)
       
    42 		die("Syntax error parsing input tree\n");
       
    43 
       
    44 	return the_boot_info;
       
    45 }
       
    46 
       
    47 static void write_prefix(FILE *f, int level)
       
    48 {
       
    49 	int i;
       
    50 
       
    51 	for (i = 0; i < level; i++)
       
    52 		fputc('\t', f);
       
    53 }
       
    54 
       
    55 int isstring(char c)
       
    56 {
       
    57 	return (isprint(c)
       
    58 		|| (c == '\0')
       
    59 		|| strchr("\a\b\t\n\v\f\r", c));
       
    60 }
       
    61 
       
    62 static void write_propval_string(FILE *f, struct data val)
       
    63 {
       
    64 	const char *str = val.val;
       
    65 	int i;
       
    66 	int newchunk = 1;
       
    67 	struct marker *m = val.markers;
       
    68 
       
    69 	assert(str[val.len-1] == '\0');
       
    70 
       
    71 	for (i = 0; i < (val.len-1); i++) {
       
    72 		char c = str[i];
       
    73 
       
    74 		if (newchunk) {
       
    75 			while (m && (m->offset <= i)) {
       
    76 				if (m->type == LABEL) {
       
    77 					assert(m->offset == i);
       
    78 					fprintf(f, "%s: ", m->ref);
       
    79 				}
       
    80 				m = m->next;
       
    81 			}
       
    82 			fprintf(f, "\"");
       
    83 			newchunk = 0;
       
    84 		}
       
    85 
       
    86 		switch (c) {
       
    87 		case '\a':
       
    88 			fprintf(f, "\\a");
       
    89 			break;
       
    90 		case '\b':
       
    91 			fprintf(f, "\\b");
       
    92 			break;
       
    93 		case '\t':
       
    94 			fprintf(f, "\\t");
       
    95 			break;
       
    96 		case '\n':
       
    97 			fprintf(f, "\\n");
       
    98 			break;
       
    99 		case '\v':
       
   100 			fprintf(f, "\\v");
       
   101 			break;
       
   102 		case '\f':
       
   103 			fprintf(f, "\\f");
       
   104 			break;
       
   105 		case '\r':
       
   106 			fprintf(f, "\\r");
       
   107 			break;
       
   108 		case '\\':
       
   109 			fprintf(f, "\\\\");
       
   110 			break;
       
   111 		case '\"':
       
   112 			fprintf(f, "\\\"");
       
   113 			break;
       
   114 		case '\0':
       
   115 			fprintf(f, "\", ");
       
   116 			newchunk = 1;
       
   117 			break;
       
   118 		default:
       
   119 			if (isprint(c))
       
   120 				fprintf(f, "%c", c);
       
   121 			else
       
   122 				fprintf(f, "\\x%02hhx", c);
       
   123 		}
       
   124 	}
       
   125 	fprintf(f, "\"");
       
   126 
       
   127 	/* Wrap up any labels at the end of the value */
       
   128 	for_each_marker_of_type(m, LABEL) {
       
   129 		assert (m->offset == val.len);
       
   130 		fprintf(f, " %s:", m->ref);
       
   131 	}
       
   132 }
       
   133 
       
   134 static void write_propval_cells(FILE *f, struct data val)
       
   135 {
       
   136 	void *propend = val.val + val.len;
       
   137 	cell_t *cp = (cell_t *)val.val;
       
   138 	struct marker *m = val.markers;
       
   139 
       
   140 	fprintf(f, "<");
       
   141 	for (;;) {
       
   142 		while (m && (m->offset <= ((char *)cp - val.val))) {
       
   143 			if (m->type == LABEL) {
       
   144 				assert(m->offset == ((char *)cp - val.val));
       
   145 				fprintf(f, "%s: ", m->ref);
       
   146 			}
       
   147 			m = m->next;
       
   148 		}
       
   149 
       
   150 		fprintf(f, "0x%x", fdt32_to_cpu(*cp++));
       
   151 		if ((void *)cp >= propend)
       
   152 			break;
       
   153 		fprintf(f, " ");
       
   154 	}
       
   155 
       
   156 	/* Wrap up any labels at the end of the value */
       
   157 	for_each_marker_of_type(m, LABEL) {
       
   158 		assert (m->offset == val.len);
       
   159 		fprintf(f, " %s:", m->ref);
       
   160 	}
       
   161 	fprintf(f, ">");
       
   162 }
       
   163 
       
   164 static void write_propval_bytes(FILE *f, struct data val)
       
   165 {
       
   166 	void *propend = val.val + val.len;
       
   167 	const char *bp = val.val;
       
   168 	struct marker *m = val.markers;
       
   169 
       
   170 	fprintf(f, "[");
       
   171 	for (;;) {
       
   172 		while (m && (m->offset == (bp-val.val))) {
       
   173 			if (m->type == LABEL)
       
   174 				fprintf(f, "%s: ", m->ref);
       
   175 			m = m->next;
       
   176 		}
       
   177 
       
   178 		fprintf(f, "%02hhx", *bp++);
       
   179 		if ((const void *)bp >= propend)
       
   180 			break;
       
   181 		fprintf(f, " ");
       
   182 	}
       
   183 
       
   184 	/* Wrap up any labels at the end of the value */
       
   185 	for_each_marker_of_type(m, LABEL) {
       
   186 		assert (m->offset == val.len);
       
   187 		fprintf(f, " %s:", m->ref);
       
   188 	}
       
   189 	fprintf(f, "]");
       
   190 }
       
   191 
       
   192 static void write_propval(FILE *f, struct property *prop)
       
   193 {
       
   194 	int len = prop->val.len;
       
   195 	const char *p = prop->val.val;
       
   196 	struct marker *m = prop->val.markers;
       
   197 	int nnotstring = 0, nnul = 0;
       
   198 	int nnotstringlbl = 0, nnotcelllbl = 0;
       
   199 	int i;
       
   200 
       
   201 	if (len == 0) {
       
   202 		fprintf(f, ";\n");
       
   203 		return;
       
   204 	}
       
   205 
       
   206 	for (i = 0; i < len; i++) {
       
   207 		if (! isstring(p[i]))
       
   208 			nnotstring++;
       
   209 		if (p[i] == '\0')
       
   210 			nnul++;
       
   211 	}
       
   212 
       
   213 	for_each_marker_of_type(m, LABEL) {
       
   214 		if ((m->offset > 0) && (prop->val.val[m->offset - 1] != '\0'))
       
   215 			nnotstringlbl++;
       
   216 		if ((m->offset % sizeof(cell_t)) != 0)
       
   217 			nnotcelllbl++;
       
   218 	}
       
   219 
       
   220 	fprintf(f, " = ");
       
   221 	if ((p[len-1] == '\0') && (nnotstring == 0) && (nnul < (len-nnul))
       
   222 	    && (nnotstringlbl == 0)) {
       
   223 		write_propval_string(f, prop->val);
       
   224 	} else if (((len % sizeof(cell_t)) == 0) && (nnotcelllbl == 0)) {
       
   225 		write_propval_cells(f, prop->val);
       
   226 	} else {
       
   227 		write_propval_bytes(f, prop->val);
       
   228 	}
       
   229 
       
   230 	fprintf(f, ";\n");
       
   231 }
       
   232 
       
   233 static void write_tree_source_node(FILE *f, struct node *tree, int level)
       
   234 {
       
   235 	struct property *prop;
       
   236 	struct node *child;
       
   237 
       
   238 	write_prefix(f, level);
       
   239 	if (tree->label)
       
   240 		fprintf(f, "%s: ", tree->label);
       
   241 	if (tree->name && (*tree->name))
       
   242 		fprintf(f, "%s {\n", tree->name);
       
   243 	else
       
   244 		fprintf(f, "/ {\n");
       
   245 
       
   246 	for_each_property(tree, prop) {
       
   247 		write_prefix(f, level+1);
       
   248 		if (prop->label)
       
   249 			fprintf(f, "%s: ", prop->label);
       
   250 		fprintf(f, "%s", prop->name);
       
   251 		write_propval(f, prop);
       
   252 	}
       
   253 	for_each_child(tree, child) {
       
   254 		fprintf(f, "\n");
       
   255 		write_tree_source_node(f, child, level+1);
       
   256 	}
       
   257 	write_prefix(f, level);
       
   258 	fprintf(f, "};\n");
       
   259 }
       
   260 
       
   261 
       
   262 void dt_to_source(FILE *f, struct boot_info *bi)
       
   263 {
       
   264 	struct reserve_info *re;
       
   265 
       
   266 	fprintf(f, "/dts-v1/;\n\n");
       
   267 
       
   268 	for (re = bi->reservelist; re; re = re->next) {
       
   269 		if (re->label)
       
   270 			fprintf(f, "%s: ", re->label);
       
   271 		fprintf(f, "/memreserve/\t0x%016llx 0x%016llx;\n",
       
   272 			(unsigned long long)re->re.address,
       
   273 			(unsigned long long)re->re.size);
       
   274 	}
       
   275 
       
   276 	write_tree_source_node(f, bi->dt, 0);
       
   277 }
       
   278