1204431Sraj/* 2204431Sraj * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005. 3204431Sraj * 4204431Sraj * 5204431Sraj * This program is free software; you can redistribute it and/or 6204431Sraj * modify it under the terms of the GNU General Public License as 7204431Sraj * published by the Free Software Foundation; either version 2 of the 8204431Sraj * License, or (at your option) any later version. 9204431Sraj * 10204431Sraj * This program is distributed in the hope that it will be useful, 11204431Sraj * but WITHOUT ANY WARRANTY; without even the implied warranty of 12204431Sraj * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13204431Sraj * General Public License for more details. 14204431Sraj * 15204431Sraj * You should have received a copy of the GNU General Public License 16204431Sraj * along with this program; if not, write to the Free Software 17204431Sraj * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 18204431Sraj * USA 19204431Sraj */ 20204431Sraj 21204431Sraj#include "dtc.h" 22204431Sraj#include "srcpos.h" 23204431Sraj 24204431Srajextern FILE *yyin; 25204431Srajextern int yyparse(void); 26238742Simpextern YYLTYPE yylloc; 27204431Sraj 28318102Sgonzostruct dt_info *parser_output; 29261215Simpbool treesource_error; 30204431Sraj 31318102Sgonzostruct dt_info *dt_from_source(const char *fname) 32204431Sraj{ 33318102Sgonzo parser_output = NULL; 34261215Simp treesource_error = false; 35204431Sraj 36238742Simp srcfile_push(fname); 37238742Simp yyin = current_srcfile->f; 38238742Simp yylloc.file = current_srcfile; 39204431Sraj 40204431Sraj if (yyparse() != 0) 41204431Sraj die("Unable to parse input tree\n"); 42204431Sraj 43204431Sraj if (treesource_error) 44204431Sraj die("Syntax error parsing input tree\n"); 45204431Sraj 46318102Sgonzo return parser_output; 47204431Sraj} 48204431Sraj 49204431Srajstatic void write_prefix(FILE *f, int level) 50204431Sraj{ 51204431Sraj int i; 52204431Sraj 53204431Sraj for (i = 0; i < level; i++) 54204431Sraj fputc('\t', f); 55204431Sraj} 56204431Sraj 57261215Simpstatic bool isstring(char c) 58204431Sraj{ 59261215Simp return (isprint((unsigned char)c) 60204431Sraj || (c == '\0') 61204431Sraj || strchr("\a\b\t\n\v\f\r", c)); 62204431Sraj} 63204431Sraj 64204431Srajstatic void write_propval_string(FILE *f, struct data val) 65204431Sraj{ 66204431Sraj const char *str = val.val; 67204431Sraj int i; 68204431Sraj struct marker *m = val.markers; 69204431Sraj 70204431Sraj assert(str[val.len-1] == '\0'); 71204431Sraj 72204433Sraj while (m && (m->offset == 0)) { 73204433Sraj if (m->type == LABEL) 74204433Sraj fprintf(f, "%s: ", m->ref); 75204433Sraj m = m->next; 76204433Sraj } 77204433Sraj fprintf(f, "\""); 78204433Sraj 79204431Sraj for (i = 0; i < (val.len-1); i++) { 80204431Sraj char c = str[i]; 81204431Sraj 82204431Sraj switch (c) { 83204431Sraj case '\a': 84204431Sraj fprintf(f, "\\a"); 85204431Sraj break; 86204431Sraj case '\b': 87204431Sraj fprintf(f, "\\b"); 88204431Sraj break; 89204431Sraj case '\t': 90204431Sraj fprintf(f, "\\t"); 91204431Sraj break; 92204431Sraj case '\n': 93204431Sraj fprintf(f, "\\n"); 94204431Sraj break; 95204431Sraj case '\v': 96204431Sraj fprintf(f, "\\v"); 97204431Sraj break; 98204431Sraj case '\f': 99204431Sraj fprintf(f, "\\f"); 100204431Sraj break; 101204431Sraj case '\r': 102204431Sraj fprintf(f, "\\r"); 103204431Sraj break; 104204431Sraj case '\\': 105204431Sraj fprintf(f, "\\\\"); 106204431Sraj break; 107204431Sraj case '\"': 108204431Sraj fprintf(f, "\\\""); 109204431Sraj break; 110204431Sraj case '\0': 111204431Sraj fprintf(f, "\", "); 112318102Sgonzo while (m && (m->offset <= (i + 1))) { 113204433Sraj if (m->type == LABEL) { 114204433Sraj assert(m->offset == (i+1)); 115204433Sraj fprintf(f, "%s: ", m->ref); 116204433Sraj } 117204433Sraj m = m->next; 118204433Sraj } 119204433Sraj fprintf(f, "\""); 120204431Sraj break; 121204431Sraj default: 122261215Simp if (isprint((unsigned char)c)) 123204431Sraj fprintf(f, "%c", c); 124204431Sraj else 125204431Sraj fprintf(f, "\\x%02hhx", c); 126204431Sraj } 127204431Sraj } 128204431Sraj fprintf(f, "\""); 129204431Sraj 130204431Sraj /* Wrap up any labels at the end of the value */ 131204431Sraj for_each_marker_of_type(m, LABEL) { 132204431Sraj assert (m->offset == val.len); 133204431Sraj fprintf(f, " %s:", m->ref); 134204431Sraj } 135204431Sraj} 136204431Sraj 137204431Srajstatic void write_propval_cells(FILE *f, struct data val) 138204431Sraj{ 139204431Sraj void *propend = val.val + val.len; 140204431Sraj cell_t *cp = (cell_t *)val.val; 141204431Sraj struct marker *m = val.markers; 142204431Sraj 143204431Sraj fprintf(f, "<"); 144204431Sraj for (;;) { 145204431Sraj while (m && (m->offset <= ((char *)cp - val.val))) { 146204431Sraj if (m->type == LABEL) { 147204431Sraj assert(m->offset == ((char *)cp - val.val)); 148204431Sraj fprintf(f, "%s: ", m->ref); 149204431Sraj } 150204431Sraj m = m->next; 151204431Sraj } 152204431Sraj 153204431Sraj fprintf(f, "0x%x", fdt32_to_cpu(*cp++)); 154204431Sraj if ((void *)cp >= propend) 155204431Sraj break; 156204431Sraj fprintf(f, " "); 157204431Sraj } 158204431Sraj 159204431Sraj /* Wrap up any labels at the end of the value */ 160204431Sraj for_each_marker_of_type(m, LABEL) { 161204431Sraj assert (m->offset == val.len); 162204431Sraj fprintf(f, " %s:", m->ref); 163204431Sraj } 164204431Sraj fprintf(f, ">"); 165204431Sraj} 166204431Sraj 167204431Srajstatic void write_propval_bytes(FILE *f, struct data val) 168204431Sraj{ 169204431Sraj void *propend = val.val + val.len; 170204431Sraj const char *bp = val.val; 171204431Sraj struct marker *m = val.markers; 172204431Sraj 173204431Sraj fprintf(f, "["); 174204431Sraj for (;;) { 175204431Sraj while (m && (m->offset == (bp-val.val))) { 176204431Sraj if (m->type == LABEL) 177204431Sraj fprintf(f, "%s: ", m->ref); 178204431Sraj m = m->next; 179204431Sraj } 180204431Sraj 181318102Sgonzo fprintf(f, "%02hhx", (unsigned char)(*bp++)); 182204431Sraj if ((const void *)bp >= propend) 183204431Sraj break; 184204431Sraj fprintf(f, " "); 185204431Sraj } 186204431Sraj 187204431Sraj /* Wrap up any labels at the end of the value */ 188204431Sraj for_each_marker_of_type(m, LABEL) { 189204431Sraj assert (m->offset == val.len); 190204431Sraj fprintf(f, " %s:", m->ref); 191204431Sraj } 192204431Sraj fprintf(f, "]"); 193204431Sraj} 194204431Sraj 195204431Srajstatic void write_propval(FILE *f, struct property *prop) 196204431Sraj{ 197204431Sraj int len = prop->val.len; 198204431Sraj const char *p = prop->val.val; 199204431Sraj struct marker *m = prop->val.markers; 200204431Sraj int nnotstring = 0, nnul = 0; 201204431Sraj int nnotstringlbl = 0, nnotcelllbl = 0; 202204431Sraj int i; 203204431Sraj 204204431Sraj if (len == 0) { 205204431Sraj fprintf(f, ";\n"); 206204431Sraj return; 207204431Sraj } 208204431Sraj 209204431Sraj for (i = 0; i < len; i++) { 210204431Sraj if (! isstring(p[i])) 211204431Sraj nnotstring++; 212204431Sraj if (p[i] == '\0') 213204431Sraj nnul++; 214204431Sraj } 215204431Sraj 216204431Sraj for_each_marker_of_type(m, LABEL) { 217204431Sraj if ((m->offset > 0) && (prop->val.val[m->offset - 1] != '\0')) 218204431Sraj nnotstringlbl++; 219204431Sraj if ((m->offset % sizeof(cell_t)) != 0) 220204431Sraj nnotcelllbl++; 221204431Sraj } 222204431Sraj 223204431Sraj fprintf(f, " = "); 224204431Sraj if ((p[len-1] == '\0') && (nnotstring == 0) && (nnul < (len-nnul)) 225204431Sraj && (nnotstringlbl == 0)) { 226204431Sraj write_propval_string(f, prop->val); 227204431Sraj } else if (((len % sizeof(cell_t)) == 0) && (nnotcelllbl == 0)) { 228204431Sraj write_propval_cells(f, prop->val); 229204431Sraj } else { 230204431Sraj write_propval_bytes(f, prop->val); 231204431Sraj } 232204431Sraj 233204431Sraj fprintf(f, ";\n"); 234204431Sraj} 235204431Sraj 236204431Srajstatic void write_tree_source_node(FILE *f, struct node *tree, int level) 237204431Sraj{ 238204431Sraj struct property *prop; 239204431Sraj struct node *child; 240238742Simp struct label *l; 241204431Sraj 242204431Sraj write_prefix(f, level); 243238742Simp for_each_label(tree->labels, l) 244238742Simp fprintf(f, "%s: ", l->label); 245204431Sraj if (tree->name && (*tree->name)) 246204431Sraj fprintf(f, "%s {\n", tree->name); 247204431Sraj else 248204431Sraj fprintf(f, "/ {\n"); 249204431Sraj 250204431Sraj for_each_property(tree, prop) { 251204431Sraj write_prefix(f, level+1); 252238742Simp for_each_label(prop->labels, l) 253238742Simp fprintf(f, "%s: ", l->label); 254204431Sraj fprintf(f, "%s", prop->name); 255204431Sraj write_propval(f, prop); 256204431Sraj } 257204431Sraj for_each_child(tree, child) { 258204431Sraj fprintf(f, "\n"); 259204431Sraj write_tree_source_node(f, child, level+1); 260204431Sraj } 261204431Sraj write_prefix(f, level); 262204431Sraj fprintf(f, "};\n"); 263204431Sraj} 264204431Sraj 265204431Sraj 266318102Sgonzovoid dt_to_source(FILE *f, struct dt_info *dti) 267204431Sraj{ 268204431Sraj struct reserve_info *re; 269204431Sraj 270204431Sraj fprintf(f, "/dts-v1/;\n\n"); 271204431Sraj 272318102Sgonzo for (re = dti->reservelist; re; re = re->next) { 273238742Simp struct label *l; 274238742Simp 275238742Simp for_each_label(re->labels, l) 276238742Simp fprintf(f, "%s: ", l->label); 277204431Sraj fprintf(f, "/memreserve/\t0x%016llx 0x%016llx;\n", 278204431Sraj (unsigned long long)re->re.address, 279204431Sraj (unsigned long long)re->re.size); 280204431Sraj } 281204431Sraj 282318102Sgonzo write_tree_source_node(f, dti->dt, 0); 283204431Sraj} 284204431Sraj 285