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 srcfile_push(fname); 36 yyin = current_srcfile->f; 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 static 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 struct marker *m = val.markers; 67 68 assert(str[val.len-1] == '\0'); 69 70 while (m && (m->offset == 0)) { 71 if (m->type == LABEL) 72 fprintf(f, "%s: ", m->ref); 73 m = m->next; 74 } 75 fprintf(f, "\""); 76 77 for (i = 0; i < (val.len-1); i++) { 78 char c = str[i]; 79 80 switch (c) { 81 case '\a': 82 fprintf(f, "\\a"); 83 break; 84 case '\b': 85 fprintf(f, "\\b"); 86 break; 87 case '\t': 88 fprintf(f, "\\t"); 89 break; 90 case '\n': 91 fprintf(f, "\\n"); 92 break; 93 case '\v': 94 fprintf(f, "\\v"); 95 break; 96 case '\f': 97 fprintf(f, "\\f"); 98 break; 99 case '\r': 100 fprintf(f, "\\r"); 101 break; 102 case '\\': 103 fprintf(f, "\\\\"); 104 break; 105 case '\"': 106 fprintf(f, "\\\""); 107 break; 108 case '\0': 109 fprintf(f, "\", "); 110 while (m && (m->offset < i)) { 111 if (m->type == LABEL) { 112 assert(m->offset == (i+1)); 113 fprintf(f, "%s: ", m->ref); 114 } 115 m = m->next; 116 } 117 fprintf(f, "\""); 118 break; 119 default: 120 if (isprint(c)) 121 fprintf(f, "%c", c); 122 else 123 fprintf(f, "\\x%02hhx", c); 124 } 125 } 126 fprintf(f, "\""); 127 128 /* Wrap up any labels at the end of the value */ 129 for_each_marker_of_type(m, LABEL) { 130 assert (m->offset == val.len); 131 fprintf(f, " %s:", m->ref); 132 } 133 } 134 135 static void write_propval_cells(FILE *f, struct data val) 136 { 137 void *propend = val.val + val.len; 138 cell_t *cp = (cell_t *)val.val; 139 struct marker *m = val.markers; 140 141 fprintf(f, "<"); 142 for (;;) { 143 while (m && (m->offset <= ((char *)cp - val.val))) { 144 if (m->type == LABEL) { 145 assert(m->offset == ((char *)cp - val.val)); 146 fprintf(f, "%s: ", m->ref); 147 } 148 m = m->next; 149 } 150 151 fprintf(f, "0x%x", fdt32_to_cpu(*cp++)); 152 if ((void *)cp >= propend) 153 break; 154 fprintf(f, " "); 155 } 156 157 /* Wrap up any labels at the end of the value */ 158 for_each_marker_of_type(m, LABEL) { 159 assert (m->offset == val.len); 160 fprintf(f, " %s:", m->ref); 161 } 162 fprintf(f, ">"); 163 } 164 165 static void write_propval_bytes(FILE *f, struct data val) 166 { 167 void *propend = val.val + val.len; 168 const char *bp = val.val; 169 struct marker *m = val.markers; 170 171 fprintf(f, "["); 172 for (;;) { 173 while (m && (m->offset == (bp-val.val))) { 174 if (m->type == LABEL) 175 fprintf(f, "%s: ", m->ref); 176 m = m->next; 177 } 178 179 fprintf(f, "%02hhx", *bp++); 180 if ((const void *)bp >= propend) 181 break; 182 fprintf(f, " "); 183 } 184 185 /* Wrap up any labels at the end of the value */ 186 for_each_marker_of_type(m, LABEL) { 187 assert (m->offset == val.len); 188 fprintf(f, " %s:", m->ref); 189 } 190 fprintf(f, "]"); 191 } 192 193 static void write_propval(FILE *f, struct property *prop) 194 { 195 int len = prop->val.len; 196 const char *p = prop->val.val; 197 struct marker *m = prop->val.markers; 198 int nnotstring = 0, nnul = 0; 199 int nnotstringlbl = 0, nnotcelllbl = 0; 200 int i; 201 202 if (len == 0) { 203 fprintf(f, ";\n"); 204 return; 205 } 206 207 for (i = 0; i < len; i++) { 208 if (! isstring(p[i])) 209 nnotstring++; 210 if (p[i] == '\0') 211 nnul++; 212 } 213 214 for_each_marker_of_type(m, LABEL) { 215 if ((m->offset > 0) && (prop->val.val[m->offset - 1] != '\0')) 216 nnotstringlbl++; 217 if ((m->offset % sizeof(cell_t)) != 0) 218 nnotcelllbl++; 219 } 220 221 fprintf(f, " = "); 222 if ((p[len-1] == '\0') && (nnotstring == 0) && (nnul < (len-nnul)) 223 && (nnotstringlbl == 0)) { 224 write_propval_string(f, prop->val); 225 } else if (((len % sizeof(cell_t)) == 0) && (nnotcelllbl == 0)) { 226 write_propval_cells(f, prop->val); 227 } else { 228 write_propval_bytes(f, prop->val); 229 } 230 231 fprintf(f, ";\n"); 232 } 233 234 static void write_tree_source_node(FILE *f, struct node *tree, int level) 235 { 236 struct property *prop; 237 struct node *child; 238 struct label *l; 239 240 write_prefix(f, level); 241 for_each_label(tree->labels, l) 242 fprintf(f, "%s: ", l->label); 243 if (tree->name && (*tree->name)) 244 fprintf(f, "%s {\n", tree->name); 245 else 246 fprintf(f, "/ {\n"); 247 248 for_each_property(tree, prop) { 249 write_prefix(f, level+1); 250 for_each_label(prop->labels, l) 251 fprintf(f, "%s: ", l->label); 252 fprintf(f, "%s", prop->name); 253 write_propval(f, prop); 254 } 255 for_each_child(tree, child) { 256 fprintf(f, "\n"); 257 write_tree_source_node(f, child, level+1); 258 } 259 write_prefix(f, level); 260 fprintf(f, "};\n"); 261 } 262 263 264 void dt_to_source(FILE *f, struct boot_info *bi) 265 { 266 struct reserve_info *re; 267 268 fprintf(f, "/dts-v1/;\n\n"); 269 270 for (re = bi->reservelist; re; re = re->next) { 271 struct label *l; 272 273 for_each_label(re->labels, l) 274 fprintf(f, "%s: ", l->label); 275 fprintf(f, "/memreserve/\t0x%016llx 0x%016llx;\n", 276 (unsigned long long)re->re.address, 277 (unsigned long long)re->re.size); 278 } 279 280 write_tree_source_node(f, bi->dt, 0); 281 } 282 283