blob: ee0a7b86e88212ccc3dc5cd05d82a12e6497f9f3 [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
29struct data build_mem_reserve(struct data d)
David Gibsonfc14dad2005-06-08 17:18:34 +100030{
David Gibsonf0517db2005-07-15 17:14:24 +100031 /*
32 * FIXME: Should reconcile the -R parameter here now?
33 */
34 if (d.len % 16 != 0) {
35 yyerror("Memory Reserve entries are <u64 addr, u64 size>\n");
36 }
37 return d;
38}
39
40
41struct boot_info *dt_from_source(FILE *f)
42{
43 the_boot_info = NULL;
44
David Gibsonfc14dad2005-06-08 17:18:34 +100045 yyin = f;
46 if (yyparse() != 0)
47 return NULL;
48
David Gibsonf0517db2005-07-15 17:14:24 +100049 fill_fullpaths(the_boot_info->dt, "");
David Gibsonfc14dad2005-06-08 17:18:34 +100050
David Gibsonf0517db2005-07-15 17:14:24 +100051 return the_boot_info;
David Gibsonfc14dad2005-06-08 17:18:34 +100052}
53
54static void write_prefix(FILE *f, int level)
55{
56 int i;
57
58 for (i = 0; i < level; i++)
59 fputc('\t', f);
60}
61
62enum proptype {
63 PROP_EMPTY,
64 PROP_STRING,
65 PROP_CELLS,
66 PROP_BYTES,
67};
68
69static enum proptype guess_type(struct property *prop)
70{
71 int len = prop->val.len;
72 char *p = prop->val.val;
73 int nnoprint = 0;
74 int i;
75
76 if (len == 0)
77 return PROP_EMPTY;
78
79 for (i = 0; i < len; i++) {
80 if (! isprint(p[i]))
81 nnoprint++;
82 }
83
84 if ((nnoprint == 1) && (p[len-1] == '\0'))
85 return PROP_STRING;
86 else if ((len % sizeof(cell_t)) == 0)
87 return PROP_CELLS;
88 else
89 return PROP_BYTES;
90
91}
92
David Gibsonf0517db2005-07-15 17:14:24 +100093
94void write_tree_source_node(FILE *f, struct node *tree, int level)
David Gibsonfc14dad2005-06-08 17:18:34 +100095{
96 struct property *prop;
97 struct node *child;
98
99 write_prefix(f, level);
100 if (tree->name && (*tree->name))
101 fprintf(f, "%s {\n", tree->name);
102 else
103 fprintf(f, "/ {\n");
104
105 for_each_property(tree, prop) {
106 cell_t *cp;
107 char *bp;
108 void *propend;
109 enum proptype type;
110
111 write_prefix(f, level);
112 fprintf(f, "\t%s", prop->name);
113 type = guess_type(prop);
114 propend = prop->val.val + prop->val.len;
115
116 switch (type) {
117 case PROP_EMPTY:
118 fprintf(f, ";\n");
119 break;
120
121 case PROP_STRING:
122 fprintf(f, " = \"%s\";\n", (char *)prop->val.val);
123 break;
124
125 case PROP_CELLS:
126 fprintf(f, " = <");
127 cp = (cell_t *)prop->val.val;
128 for (;;) {
129 fprintf(f, "%x", be32_to_cpu(*cp++));
130 if ((void *)cp >= propend)
131 break;
132 fprintf(f, " ");
133 }
134 fprintf(f, ">;\n");
135 break;
136
137 case PROP_BYTES:
138 fprintf(f, " = [");
139 bp = prop->val.val;
140 for (;;) {
141 fprintf(f, "%02hhx", *bp++);
142 if ((void *)bp >= propend)
143 break;
144 fprintf(f, " ");
145 }
146 fprintf(f, "];\n");
147 break;
148 }
149 }
150 for_each_child(tree, child) {
151 fprintf(f, "\n");
David Gibsonf0517db2005-07-15 17:14:24 +1000152 write_tree_source_node(f, child, level+1);
David Gibsonfc14dad2005-06-08 17:18:34 +1000153 }
154 write_prefix(f, level);
155 fprintf(f, "};\n");
156}
David Gibsonf0517db2005-07-15 17:14:24 +1000157
158
159void write_tree_source(FILE *f, struct boot_info *bi)
160{
161 int i;
162
163 assert((bi->mem_reserve_data.len % sizeof(struct reserve_entry)) == 0);
164 for (i = 0;
165 i < (bi->mem_reserve_data.len / sizeof(struct reserve_entry));
166 i++) {
167 struct reserve_entry *re = ((struct reserve_entry *)
168 bi->mem_reserve_data.val) + i;
169
170 fprintf(f, "/memreserve/\t%016llx-%016llx;\n",
171 (unsigned long long)re->address,
172 (unsigned long long)re->address + re->size - 1);
173 }
174
175 write_tree_source_node(f, bi->dt, 0);
176}
177