blob: e9bbaa51bbfc6a4305c9ecf44e3291317994ee30 [file] [log] [blame]
David Gibsonfc14dad2005-06-08 17:18:34 +10001/*
2 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
3 *
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18 * USA
19 */
20
21#include "dtc.h"
22
David Gibsonfc14dad2005-06-08 17:18:34 +100023extern FILE *yyin;
24extern int yyparse(void);
David Gibsonf0517db2005-07-15 17:14:24 +100025extern void yyerror(char const *);
David Gibsonfc14dad2005-06-08 17:18:34 +100026
David Gibsonf0517db2005-07-15 17:14:24 +100027struct boot_info *the_boot_info;
28
David Gibsonf0517db2005-07-15 17:14:24 +100029struct boot_info *dt_from_source(FILE *f)
30{
31 the_boot_info = NULL;
32
David Gibsonfc14dad2005-06-08 17:18:34 +100033 yyin = f;
34 if (yyparse() != 0)
35 return NULL;
36
David Gibsonf0517db2005-07-15 17:14:24 +100037 fill_fullpaths(the_boot_info->dt, "");
David Gibsonfc14dad2005-06-08 17:18:34 +100038
David Gibsonf0517db2005-07-15 17:14:24 +100039 return the_boot_info;
David Gibsonfc14dad2005-06-08 17:18:34 +100040}
41
42static void write_prefix(FILE *f, int level)
43{
44 int i;
45
46 for (i = 0; i < level; i++)
47 fputc('\t', f);
48}
49
50enum proptype {
51 PROP_EMPTY,
52 PROP_STRING,
53 PROP_CELLS,
54 PROP_BYTES,
55};
56
57static enum proptype guess_type(struct property *prop)
58{
59 int len = prop->val.len;
60 char *p = prop->val.val;
61 int nnoprint = 0;
62 int i;
63
64 if (len == 0)
65 return PROP_EMPTY;
66
67 for (i = 0; i < len; i++) {
68 if (! isprint(p[i]))
69 nnoprint++;
70 }
71
72 if ((nnoprint == 1) && (p[len-1] == '\0'))
73 return PROP_STRING;
74 else if ((len % sizeof(cell_t)) == 0)
75 return PROP_CELLS;
76 else
77 return PROP_BYTES;
78
79}
80
David Gibsonf0517db2005-07-15 17:14:24 +100081
David Gibson230f2532005-08-29 12:48:02 +100082static void write_tree_source_node(FILE *f, struct node *tree, int level)
David Gibsonfc14dad2005-06-08 17:18:34 +100083{
84 struct property *prop;
85 struct node *child;
86
87 write_prefix(f, level);
88 if (tree->name && (*tree->name))
89 fprintf(f, "%s {\n", tree->name);
90 else
91 fprintf(f, "/ {\n");
92
93 for_each_property(tree, prop) {
94 cell_t *cp;
95 char *bp;
96 void *propend;
97 enum proptype type;
98
99 write_prefix(f, level);
100 fprintf(f, "\t%s", prop->name);
101 type = guess_type(prop);
102 propend = prop->val.val + prop->val.len;
103
104 switch (type) {
105 case PROP_EMPTY:
106 fprintf(f, ";\n");
107 break;
108
109 case PROP_STRING:
110 fprintf(f, " = \"%s\";\n", (char *)prop->val.val);
111 break;
112
113 case PROP_CELLS:
114 fprintf(f, " = <");
115 cp = (cell_t *)prop->val.val;
116 for (;;) {
117 fprintf(f, "%x", be32_to_cpu(*cp++));
118 if ((void *)cp >= propend)
119 break;
120 fprintf(f, " ");
121 }
122 fprintf(f, ">;\n");
123 break;
124
125 case PROP_BYTES:
126 fprintf(f, " = [");
127 bp = prop->val.val;
128 for (;;) {
129 fprintf(f, "%02hhx", *bp++);
130 if ((void *)bp >= propend)
131 break;
132 fprintf(f, " ");
133 }
134 fprintf(f, "];\n");
135 break;
136 }
137 }
138 for_each_child(tree, child) {
139 fprintf(f, "\n");
David Gibsonf0517db2005-07-15 17:14:24 +1000140 write_tree_source_node(f, child, level+1);
David Gibsonfc14dad2005-06-08 17:18:34 +1000141 }
142 write_prefix(f, level);
143 fprintf(f, "};\n");
144}
David Gibsonf0517db2005-07-15 17:14:24 +1000145
146
David Gibson712e52e2005-10-26 16:56:26 +1000147void dt_to_source(FILE *f, struct boot_info *bi)
David Gibsonf0517db2005-07-15 17:14:24 +1000148{
David Gibsonf040d952005-10-24 18:18:38 +1000149 struct reserve_info *re;
David Gibsonf0517db2005-07-15 17:14:24 +1000150
David Gibsonf040d952005-10-24 18:18:38 +1000151 for (re = bi->reservelist; re; re = re->next) {
David Gibsonf0517db2005-07-15 17:14:24 +1000152 fprintf(f, "/memreserve/\t%016llx-%016llx;\n",
David Gibsonf040d952005-10-24 18:18:38 +1000153 (unsigned long long)re->re.address,
154 (unsigned long long)(re->re.address + re->re.size - 1));
David Gibsonf0517db2005-07-15 17:14:24 +1000155 }
156
157 write_tree_source_node(f, bi->dt, 0);
158}
159