blob: 0a4367ac4c5a4215ec071e84dafd53c825a2b3ad [file] [log] [blame]
David Gibsonfc14dad2005-06-08 17:18:34 +10001/*
2 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
3 *
David Gibson63dc9c72007-09-18 11:44:04 +10004 *
David Gibsonfc14dad2005-06-08 17:18:34 +10005 * 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.
David Gibson63dc9c72007-09-18 11:44:04 +100014 *
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
David Gibsonfc14dad2005-06-08 17:18:34 +100019 */
20
21#include "dtc.h"
Jon Loeligere45e6fd2007-03-23 15:18:41 -050022#include "srcpos.h"
David Gibsonfc14dad2005-06-08 17:18:34 +100023
David Gibsonfc14dad2005-06-08 17:18:34 +100024extern FILE *yyin;
25extern int yyparse(void);
David Gibsonf0517db2005-07-15 17:14:24 +100026extern void yyerror(char const *);
David Gibsonfc14dad2005-06-08 17:18:34 +100027
David Gibsonf0517db2005-07-15 17:14:24 +100028struct boot_info *the_boot_info;
29
Jon Loeligere45e6fd2007-03-23 15:18:41 -050030struct boot_info *dt_from_source(const char *fname)
David Gibsonf0517db2005-07-15 17:14:24 +100031{
32 the_boot_info = NULL;
33
Jon Loeligere45e6fd2007-03-23 15:18:41 -050034 push_input_file(fname);
35
David Gibsonfc14dad2005-06-08 17:18:34 +100036 if (yyparse() != 0)
37 return NULL;
38
David Gibsonf0517db2005-07-15 17:14:24 +100039 fill_fullpaths(the_boot_info->dt, "");
David Gibsonfc14dad2005-06-08 17:18:34 +100040
David Gibsonf0517db2005-07-15 17:14:24 +100041 return the_boot_info;
David Gibsonfc14dad2005-06-08 17:18:34 +100042}
43
44static void write_prefix(FILE *f, int level)
45{
46 int i;
47
48 for (i = 0; i < level; i++)
49 fputc('\t', f);
50}
51
David Gibson5a98ddd2007-10-17 12:39:10 +100052int isstring(char c)
53{
54 return (isprint(c)
55 || (c == '\0')
56 || strchr("\a\b\t\n\v\f\r", c));
57}
58
David Gibson5a98ddd2007-10-17 12:39:10 +100059static void write_propval_string(FILE *f, struct data val)
60{
61 char *str = val.val;
62 int i;
63
64 assert(str[val.len-1] == '\0');
65
David Gibsoned01ae42007-11-07 10:21:20 +110066 fprintf(f, "\"");
David Gibson5a98ddd2007-10-17 12:39:10 +100067 for (i = 0; i < (val.len-1); i++) {
68 char c = str[i];
69
70 switch (c) {
71 case '\a':
72 fprintf(f, "\\a");
73 break;
74 case '\b':
75 fprintf(f, "\\b");
76 break;
77 case '\t':
78 fprintf(f, "\\t");
79 break;
80 case '\n':
81 fprintf(f, "\\n");
82 break;
83 case '\v':
84 fprintf(f, "\\v");
85 break;
86 case '\f':
87 fprintf(f, "\\f");
88 break;
89 case '\r':
90 fprintf(f, "\\r");
91 break;
92 case '\\':
93 fprintf(f, "\\\\");
94 break;
95 case '\"':
96 fprintf(f, "\\\"");
97 break;
98 case '\0':
99 fprintf(f, "\", \"");
100 break;
101 default:
102 if (isprint(c))
103 fprintf(f, "%c", c);
104 else
105 fprintf(f, "\\x%02hhx", c);
106 }
107 }
David Gibsoned01ae42007-11-07 10:21:20 +1100108 fprintf(f, "\"");
David Gibson5a98ddd2007-10-17 12:39:10 +1000109}
110
111static void write_propval_cells(FILE *f, struct data val)
112{
113 void *propend = val.val + val.len;
114 cell_t *cp = (cell_t *)val.val;
115
David Gibsoned01ae42007-11-07 10:21:20 +1100116 fprintf(f, "<");
David Gibson5a98ddd2007-10-17 12:39:10 +1000117 for (;;) {
118 fprintf(f, "%x", be32_to_cpu(*cp++));
119 if ((void *)cp >= propend)
120 break;
121 fprintf(f, " ");
122 }
David Gibsoned01ae42007-11-07 10:21:20 +1100123 fprintf(f, ">");
David Gibson5a98ddd2007-10-17 12:39:10 +1000124}
125
126static void write_propval_bytes(FILE *f, struct data val)
127{
128 void *propend = val.val + val.len;
129 char *bp = val.val;
130
David Gibsoned01ae42007-11-07 10:21:20 +1100131 fprintf(f, "[");
David Gibson5a98ddd2007-10-17 12:39:10 +1000132 for (;;) {
133 fprintf(f, "%02hhx", *bp++);
134 if ((void *)bp >= propend)
135 break;
136 fprintf(f, " ");
137 }
David Gibsoned01ae42007-11-07 10:21:20 +1100138 fprintf(f, "]");
139}
140
141static void write_propval(FILE *f, struct property *prop)
142{
143 int len = prop->val.len;
144 char *p = prop->val.val;
145 int nnotstring = 0, nnul = 0;
146 int i;
147
148 if (len == 0) {
149 fprintf(f, ";\n");
150 return;
151 }
152
153 for (i = 0; i < len; i++) {
154 if (! isstring(p[i]))
155 nnotstring++;
156 if (p[i] == '\0')
157 nnul++;
158 }
159
160 fprintf(f, " = ");
161
162 if ((p[len-1] == '\0') && (nnotstring == 0) && (nnul < (len-nnul))) {
163 write_propval_string(f, prop->val);
164 } else if (((len % sizeof(cell_t)) == 0)) {
165 write_propval_cells(f, prop->val);
166 } else {
167 write_propval_bytes(f, prop->val);
168 }
169 fprintf(f, ";\n");
David Gibson5a98ddd2007-10-17 12:39:10 +1000170}
David Gibsonf0517db2005-07-15 17:14:24 +1000171
David Gibson230f2532005-08-29 12:48:02 +1000172static void write_tree_source_node(FILE *f, struct node *tree, int level)
David Gibsonfc14dad2005-06-08 17:18:34 +1000173{
174 struct property *prop;
175 struct node *child;
176
177 write_prefix(f, level);
David Gibson02563ad2007-11-02 16:10:30 +1100178 if (tree->label)
179 fprintf(f, "%s: ", tree->label);
David Gibsonfc14dad2005-06-08 17:18:34 +1000180 if (tree->name && (*tree->name))
181 fprintf(f, "%s {\n", tree->name);
182 else
183 fprintf(f, "/ {\n");
184
185 for_each_property(tree, prop) {
David Gibson02563ad2007-11-02 16:10:30 +1100186 write_prefix(f, level+1);
187 if (prop->label)
188 fprintf(f, "%s: ", prop->label);
189 fprintf(f, "%s", prop->name);
David Gibsoned01ae42007-11-07 10:21:20 +1100190 write_propval(f, prop);
David Gibsonfc14dad2005-06-08 17:18:34 +1000191 }
192 for_each_child(tree, child) {
193 fprintf(f, "\n");
David Gibsonf0517db2005-07-15 17:14:24 +1000194 write_tree_source_node(f, child, level+1);
David Gibsonfc14dad2005-06-08 17:18:34 +1000195 }
196 write_prefix(f, level);
197 fprintf(f, "};\n");
198}
David Gibsonf0517db2005-07-15 17:14:24 +1000199
200
David Gibson712e52e2005-10-26 16:56:26 +1000201void dt_to_source(FILE *f, struct boot_info *bi)
David Gibsonf0517db2005-07-15 17:14:24 +1000202{
David Gibsonf040d952005-10-24 18:18:38 +1000203 struct reserve_info *re;
David Gibsonf0517db2005-07-15 17:14:24 +1000204
David Gibsonf040d952005-10-24 18:18:38 +1000205 for (re = bi->reservelist; re; re = re->next) {
David Gibson02563ad2007-11-02 16:10:30 +1100206 if (re->label)
207 fprintf(f, "%s: ", re->label);
David Gibsonf0517db2005-07-15 17:14:24 +1000208 fprintf(f, "/memreserve/\t%016llx-%016llx;\n",
David Gibsonf040d952005-10-24 18:18:38 +1000209 (unsigned long long)re->re.address,
210 (unsigned long long)(re->re.address + re->re.size - 1));
David Gibsonf0517db2005-07-15 17:14:24 +1000211 }
212
213 write_tree_source_node(f, bi->dt, 0);
214}
215