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