treesource.c revision 204433
1304565Sed/* 2304565Sed * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005. 3304565Sed * 4304565Sed * 5304565Sed * This program is free software; you can redistribute it and/or 6304565Sed * modify it under the terms of the GNU General Public License as 7304565Sed * published by the Free Software Foundation; either version 2 of the 8304565Sed * License, or (at your option) any later version. 9304565Sed * 10304565Sed * This program is distributed in the hope that it will be useful, 11304565Sed * but WITHOUT ANY WARRANTY; without even the implied warranty of 12304565Sed * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13304565Sed * General Public License for more details. 14304565Sed * 15304565Sed * You should have received a copy of the GNU General Public License 16304565Sed * along with this program; if not, write to the Free Software 17304565Sed * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 18304565Sed * USA 19304565Sed */ 20304565Sed 21304565Sed#include "dtc.h" 22304565Sed#include "srcpos.h" 23304565Sed 24304565Sedextern FILE *yyin; 25304565Sedextern int yyparse(void); 26304565Sed 27304565Sedstruct boot_info *the_boot_info; 28304565Sedint treesource_error; 29304565Sed 30304565Sedstruct boot_info *dt_from_source(const char *fname) 31304565Sed{ 32304565Sed the_boot_info = NULL; 33304565Sed treesource_error = 0; 34304565Sed 35304565Sed srcpos_file = dtc_open_file(fname, NULL); 36304565Sed yyin = srcpos_file->file; 37304565Sed 38304565Sed if (yyparse() != 0) 39304565Sed die("Unable to parse input tree\n"); 40304565Sed 41304565Sed if (treesource_error) 42304565Sed die("Syntax error parsing input tree\n"); 43304565Sed 44304565Sed return the_boot_info; 45304565Sed} 46304565Sed 47304565Sedstatic void write_prefix(FILE *f, int level) 48304565Sed{ 49304565Sed int i; 50324250Sed 51324250Sed for (i = 0; i < level; i++) 52324250Sed fputc('\t', f); 53324250Sed} 54324250Sed 55325858Sedstatic int isstring(char c) 56325858Sed{ 57325858Sed return (isprint(c) 58325858Sed || (c == '\0') 59325858Sed || strchr("\a\b\t\n\v\f\r", c)); 60325858Sed} 61325858Sed 62325858Sedstatic void write_propval_string(FILE *f, struct data val) 63325858Sed{ 64325858Sed const char *str = val.val; 65325858Sed int i; 66304565Sed 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 135static 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 165static 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 193static 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 234static void write_tree_source_node(FILE *f, struct node *tree, int level) 235{ 236 struct property *prop; 237 struct node *child; 238 239 write_prefix(f, level); 240 if (tree->label) 241 fprintf(f, "%s: ", tree->label); 242 if (tree->name && (*tree->name)) 243 fprintf(f, "%s {\n", tree->name); 244 else 245 fprintf(f, "/ {\n"); 246 247 for_each_property(tree, prop) { 248 write_prefix(f, level+1); 249 if (prop->label) 250 fprintf(f, "%s: ", prop->label); 251 fprintf(f, "%s", prop->name); 252 write_propval(f, prop); 253 } 254 for_each_child(tree, child) { 255 fprintf(f, "\n"); 256 write_tree_source_node(f, child, level+1); 257 } 258 write_prefix(f, level); 259 fprintf(f, "};\n"); 260} 261 262 263void dt_to_source(FILE *f, struct boot_info *bi) 264{ 265 struct reserve_info *re; 266 267 fprintf(f, "/dts-v1/;\n\n"); 268 269 for (re = bi->reservelist; re; re = re->next) { 270 if (re->label) 271 fprintf(f, "%s: ", re->label); 272 fprintf(f, "/memreserve/\t0x%016llx 0x%016llx;\n", 273 (unsigned long long)re->re.address, 274 (unsigned long long)re->re.size); 275 } 276 277 write_tree_source_node(f, bi->dt, 0); 278} 279 280