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 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 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 279