/* * (C) Copyright David Gibson , IBM Corporation. 2005. * * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA */ #include "dtc.h" #include "srcpos.h" extern FILE *yyin; extern int yyparse(void); extern void yyerror(char const *); struct boot_info *the_boot_info; struct boot_info *dt_from_source(const char *fname) { the_boot_info = NULL; push_input_file(fname); if (yyparse() != 0) return NULL; fill_fullpaths(the_boot_info->dt, ""); return the_boot_info; } static void write_prefix(FILE *f, int level) { int i; for (i = 0; i < level; i++) fputc('\t', f); } enum proptype { PROP_EMPTY, PROP_STRING, PROP_CELLS, PROP_BYTES, }; static enum proptype guess_type(struct property *prop) { int len = prop->val.len; char *p = prop->val.val; int nnoprint = 0; int i; if (len == 0) return PROP_EMPTY; for (i = 0; i < len; i++) { if (! isprint(p[i])) nnoprint++; } if ((nnoprint == 1) && (p[len-1] == '\0')) return PROP_STRING; else if ((len % sizeof(cell_t)) == 0) return PROP_CELLS; else return PROP_BYTES; } static void write_tree_source_node(FILE *f, struct node *tree, int level) { struct property *prop; struct node *child; write_prefix(f, level); if (tree->name && (*tree->name)) fprintf(f, "%s {\n", tree->name); else fprintf(f, "/ {\n"); for_each_property(tree, prop) { cell_t *cp; char *bp; void *propend; enum proptype type; write_prefix(f, level); fprintf(f, "\t%s", prop->name); type = guess_type(prop); propend = prop->val.val + prop->val.len; switch (type) { case PROP_EMPTY: fprintf(f, ";\n"); break; case PROP_STRING: fprintf(f, " = \"%s\";\n", (char *)prop->val.val); break; case PROP_CELLS: fprintf(f, " = <"); cp = (cell_t *)prop->val.val; for (;;) { fprintf(f, "%x", be32_to_cpu(*cp++)); if ((void *)cp >= propend) break; fprintf(f, " "); } fprintf(f, ">;\n"); break; case PROP_BYTES: fprintf(f, " = ["); bp = prop->val.val; for (;;) { fprintf(f, "%02hhx", *bp++); if ((void *)bp >= propend) break; fprintf(f, " "); } fprintf(f, "];\n"); break; } } for_each_child(tree, child) { fprintf(f, "\n"); write_tree_source_node(f, child, level+1); } write_prefix(f, level); fprintf(f, "};\n"); } void dt_to_source(FILE *f, struct boot_info *bi) { struct reserve_info *re; for (re = bi->reservelist; re; re = re->next) { fprintf(f, "/memreserve/\t%016llx-%016llx;\n", (unsigned long long)re->re.address, (unsigned long long)(re->re.address + re->re.size - 1)); } write_tree_source_node(f, bi->dt, 0); }