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); 26204431Sraj 27204431Srajstruct boot_info *the_boot_info; 28204431Srajint treesource_error; 29204431Sraj 30204431Srajstruct boot_info *dt_from_source(const char *fname) 31204431Sraj{ 32204431Sraj the_boot_info = NULL; 33204431Sraj treesource_error = 0; 34204431Sraj 35204431Sraj srcpos_file = dtc_open_file(fname, NULL); 36204431Sraj yyin = srcpos_file->file; 37204431Sraj 38204431Sraj if (yyparse() != 0) 39204431Sraj die("Unable to parse input tree\n"); 40204431Sraj 41204431Sraj if (treesource_error) 42204431Sraj die("Syntax error parsing input tree\n"); 43204431Sraj 44204431Sraj return the_boot_info; 45204431Sraj} 46204431Sraj 47204431Srajstatic void write_prefix(FILE *f, int level) 48204431Sraj{ 49204431Sraj int i; 50204431Sraj 51204431Sraj for (i = 0; i < level; i++) 52204431Sraj fputc('\t', f); 53204431Sraj} 54204431Sraj 55204433Srajstatic int isstring(char c) 56204431Sraj{ 57204431Sraj return (isprint(c) 58204431Sraj || (c == '\0') 59204431Sraj || strchr("\a\b\t\n\v\f\r", c)); 60204431Sraj} 61204431Sraj 62204431Srajstatic void write_propval_string(FILE *f, struct data val) 63204431Sraj{ 64204431Sraj const char *str = val.val; 65204431Sraj int i; 66204431Sraj struct marker *m = val.markers; 67204431Sraj 68204431Sraj assert(str[val.len-1] == '\0'); 69204431Sraj 70204433Sraj while (m && (m->offset == 0)) { 71204433Sraj if (m->type == LABEL) 72204433Sraj fprintf(f, "%s: ", m->ref); 73204433Sraj m = m->next; 74204433Sraj } 75204433Sraj fprintf(f, "\""); 76204433Sraj 77204431Sraj for (i = 0; i < (val.len-1); i++) { 78204431Sraj char c = str[i]; 79204431Sraj 80204431Sraj switch (c) { 81204431Sraj case '\a': 82204431Sraj fprintf(f, "\\a"); 83204431Sraj break; 84204431Sraj case '\b': 85204431Sraj fprintf(f, "\\b"); 86204431Sraj break; 87204431Sraj case '\t': 88204431Sraj fprintf(f, "\\t"); 89204431Sraj break; 90204431Sraj case '\n': 91204431Sraj fprintf(f, "\\n"); 92204431Sraj break; 93204431Sraj case '\v': 94204431Sraj fprintf(f, "\\v"); 95204431Sraj break; 96204431Sraj case '\f': 97204431Sraj fprintf(f, "\\f"); 98204431Sraj break; 99204431Sraj case '\r': 100204431Sraj fprintf(f, "\\r"); 101204431Sraj break; 102204431Sraj case '\\': 103204431Sraj fprintf(f, "\\\\"); 104204431Sraj break; 105204431Sraj case '\"': 106204431Sraj fprintf(f, "\\\""); 107204431Sraj break; 108204431Sraj case '\0': 109204431Sraj fprintf(f, "\", "); 110204433Sraj while (m && (m->offset < i)) { 111204433Sraj if (m->type == LABEL) { 112204433Sraj assert(m->offset == (i+1)); 113204433Sraj fprintf(f, "%s: ", m->ref); 114204433Sraj } 115204433Sraj m = m->next; 116204433Sraj } 117204433Sraj fprintf(f, "\""); 118204431Sraj break; 119204431Sraj default: 120204431Sraj if (isprint(c)) 121204431Sraj fprintf(f, "%c", c); 122204431Sraj else 123204431Sraj fprintf(f, "\\x%02hhx", c); 124204431Sraj } 125204431Sraj } 126204431Sraj fprintf(f, "\""); 127204431Sraj 128204431Sraj /* Wrap up any labels at the end of the value */ 129204431Sraj for_each_marker_of_type(m, LABEL) { 130204431Sraj assert (m->offset == val.len); 131204431Sraj fprintf(f, " %s:", m->ref); 132204431Sraj } 133204431Sraj} 134204431Sraj 135204431Srajstatic void write_propval_cells(FILE *f, struct data val) 136204431Sraj{ 137204431Sraj void *propend = val.val + val.len; 138204431Sraj cell_t *cp = (cell_t *)val.val; 139204431Sraj struct marker *m = val.markers; 140204431Sraj 141204431Sraj fprintf(f, "<"); 142204431Sraj for (;;) { 143204431Sraj while (m && (m->offset <= ((char *)cp - val.val))) { 144204431Sraj if (m->type == LABEL) { 145204431Sraj assert(m->offset == ((char *)cp - val.val)); 146204431Sraj fprintf(f, "%s: ", m->ref); 147204431Sraj } 148204431Sraj m = m->next; 149204431Sraj } 150204431Sraj 151204431Sraj fprintf(f, "0x%x", fdt32_to_cpu(*cp++)); 152204431Sraj if ((void *)cp >= propend) 153204431Sraj break; 154204431Sraj fprintf(f, " "); 155204431Sraj } 156204431Sraj 157204431Sraj /* Wrap up any labels at the end of the value */ 158204431Sraj for_each_marker_of_type(m, LABEL) { 159204431Sraj assert (m->offset == val.len); 160204431Sraj fprintf(f, " %s:", m->ref); 161204431Sraj } 162204431Sraj fprintf(f, ">"); 163204431Sraj} 164204431Sraj 165204431Srajstatic void write_propval_bytes(FILE *f, struct data val) 166204431Sraj{ 167204431Sraj void *propend = val.val + val.len; 168204431Sraj const char *bp = val.val; 169204431Sraj struct marker *m = val.markers; 170204431Sraj 171204431Sraj fprintf(f, "["); 172204431Sraj for (;;) { 173204431Sraj while (m && (m->offset == (bp-val.val))) { 174204431Sraj if (m->type == LABEL) 175204431Sraj fprintf(f, "%s: ", m->ref); 176204431Sraj m = m->next; 177204431Sraj } 178204431Sraj 179204431Sraj fprintf(f, "%02hhx", *bp++); 180204431Sraj if ((const void *)bp >= propend) 181204431Sraj break; 182204431Sraj fprintf(f, " "); 183204431Sraj } 184204431Sraj 185204431Sraj /* Wrap up any labels at the end of the value */ 186204431Sraj for_each_marker_of_type(m, LABEL) { 187204431Sraj assert (m->offset == val.len); 188204431Sraj fprintf(f, " %s:", m->ref); 189204431Sraj } 190204431Sraj fprintf(f, "]"); 191204431Sraj} 192204431Sraj 193204431Srajstatic void write_propval(FILE *f, struct property *prop) 194204431Sraj{ 195204431Sraj int len = prop->val.len; 196204431Sraj const char *p = prop->val.val; 197204431Sraj struct marker *m = prop->val.markers; 198204431Sraj int nnotstring = 0, nnul = 0; 199204431Sraj int nnotstringlbl = 0, nnotcelllbl = 0; 200204431Sraj int i; 201204431Sraj 202204431Sraj if (len == 0) { 203204431Sraj fprintf(f, ";\n"); 204204431Sraj return; 205204431Sraj } 206204431Sraj 207204431Sraj for (i = 0; i < len; i++) { 208204431Sraj if (! isstring(p[i])) 209204431Sraj nnotstring++; 210204431Sraj if (p[i] == '\0') 211204431Sraj nnul++; 212204431Sraj } 213204431Sraj 214204431Sraj for_each_marker_of_type(m, LABEL) { 215204431Sraj if ((m->offset > 0) && (prop->val.val[m->offset - 1] != '\0')) 216204431Sraj nnotstringlbl++; 217204431Sraj if ((m->offset % sizeof(cell_t)) != 0) 218204431Sraj nnotcelllbl++; 219204431Sraj } 220204431Sraj 221204431Sraj fprintf(f, " = "); 222204431Sraj if ((p[len-1] == '\0') && (nnotstring == 0) && (nnul < (len-nnul)) 223204431Sraj && (nnotstringlbl == 0)) { 224204431Sraj write_propval_string(f, prop->val); 225204431Sraj } else if (((len % sizeof(cell_t)) == 0) && (nnotcelllbl == 0)) { 226204431Sraj write_propval_cells(f, prop->val); 227204431Sraj } else { 228204431Sraj write_propval_bytes(f, prop->val); 229204431Sraj } 230204431Sraj 231204431Sraj fprintf(f, ";\n"); 232204431Sraj} 233204431Sraj 234204431Srajstatic void write_tree_source_node(FILE *f, struct node *tree, int level) 235204431Sraj{ 236204431Sraj struct property *prop; 237204431Sraj struct node *child; 238204431Sraj 239204431Sraj write_prefix(f, level); 240204431Sraj if (tree->label) 241204431Sraj fprintf(f, "%s: ", tree->label); 242204431Sraj if (tree->name && (*tree->name)) 243204431Sraj fprintf(f, "%s {\n", tree->name); 244204431Sraj else 245204431Sraj fprintf(f, "/ {\n"); 246204431Sraj 247204431Sraj for_each_property(tree, prop) { 248204431Sraj write_prefix(f, level+1); 249204431Sraj if (prop->label) 250204431Sraj fprintf(f, "%s: ", prop->label); 251204431Sraj fprintf(f, "%s", prop->name); 252204431Sraj write_propval(f, prop); 253204431Sraj } 254204431Sraj for_each_child(tree, child) { 255204431Sraj fprintf(f, "\n"); 256204431Sraj write_tree_source_node(f, child, level+1); 257204431Sraj } 258204431Sraj write_prefix(f, level); 259204431Sraj fprintf(f, "};\n"); 260204431Sraj} 261204431Sraj 262204431Sraj 263204431Srajvoid dt_to_source(FILE *f, struct boot_info *bi) 264204431Sraj{ 265204431Sraj struct reserve_info *re; 266204431Sraj 267204431Sraj fprintf(f, "/dts-v1/;\n\n"); 268204431Sraj 269204431Sraj for (re = bi->reservelist; re; re = re->next) { 270204431Sraj if (re->label) 271204431Sraj fprintf(f, "%s: ", re->label); 272204431Sraj fprintf(f, "/memreserve/\t0x%016llx 0x%016llx;\n", 273204431Sraj (unsigned long long)re->re.address, 274204431Sraj (unsigned long long)re->re.size); 275204431Sraj } 276204431Sraj 277204431Sraj write_tree_source_node(f, bi->dt, 0); 278204431Sraj} 279204431Sraj 280