2 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
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.
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.
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
29 extern int yylex(void);
30 extern void print_error(char const *fmt, ...);
31 extern void yyerror(char const *s);
33 extern struct boot_info *the_boot_info;
34 extern int treesource_error;
36 static unsigned long long eval_literal(const char *s, int base, int bits);
49 struct property *prop;
50 struct property *proplist;
52 struct node *nodelist;
53 struct reserve_info *re;
58 %token <propnodename> DT_PROPNODENAME
59 %token <literal> DT_LITERAL
60 %token <cbase> DT_BASE
62 %token <data> DT_STRING
63 %token <labelref> DT_LABEL
64 %token <labelref> DT_REF
68 %type <data> propdataprefix
70 %type <re> memreserves
74 %type <data> bytestring
76 %type <proplist> proplist
78 %type <node> devicetree
81 %type <nodelist> subnodes
86 DT_V1 ';' memreserves devicetree
88 the_boot_info = build_boot_info($3, $4,
89 guess_boot_cpuid($4));
98 | memreserve memreserves
100 $$ = chain_reserve_entry($1, $2);
105 DT_MEMRESERVE addr addr ';'
107 $$ = build_reserve_entry($2, $3);
109 | DT_LABEL memreserve
111 add_label(&$2->labels, $1);
119 $$ = eval_literal($1, 0, 64);
126 $$ = name_node($2, "");
128 | devicetree '/' nodedef
130 $$ = merge_nodes($1, $3);
132 | devicetree DT_REF nodedef
134 struct node *target = get_node_by_ref($1, $2);
137 merge_nodes(target, $3);
139 print_error("label or path, '%s', not found", $2);
145 '{' proplist subnodes '}' ';'
147 $$ = build_node($2, $3);
158 $$ = chain_property($2, $1);
163 DT_PROPNODENAME '=' propdata ';'
165 $$ = build_property($1, $3);
167 | DT_PROPNODENAME ';'
169 $$ = build_property($1, empty_data);
173 add_label(&$2->labels, $1);
179 propdataprefix DT_STRING
181 $$ = data_merge($1, $2);
183 | propdataprefix '<' celllist '>'
185 $$ = data_merge($1, $3);
187 | propdataprefix '[' bytestring ']'
189 $$ = data_merge($1, $3);
191 | propdataprefix DT_REF
193 $$ = data_add_marker($1, REF_PATH, $2);
195 | propdataprefix DT_INCBIN '(' DT_STRING ',' addr ',' addr ')'
197 FILE *f = srcfile_relative_open($4.val, NULL);
201 if (fseek(f, $6, SEEK_SET) != 0)
202 print_error("Couldn't seek to offset %llu in \"%s\": %s",
203 (unsigned long long)$6,
207 d = data_copy_file(f, $8);
209 $$ = data_merge($1, d);
212 | propdataprefix DT_INCBIN '(' DT_STRING ')'
214 FILE *f = srcfile_relative_open($4.val, NULL);
215 struct data d = empty_data;
217 d = data_copy_file(f, -1);
219 $$ = data_merge($1, d);
224 $$ = data_add_marker($1, LABEL, $2);
237 | propdataprefix DT_LABEL
239 $$ = data_add_marker($1, LABEL, $2);
250 $$ = data_append_cell($1, $2);
254 $$ = data_append_cell(data_add_marker($1, REF_PHANDLE,
259 $$ = data_add_marker($1, LABEL, $2);
266 $$ = eval_literal($1, 0, 32);
277 $$ = data_append_byte($1, $2);
279 | bytestring DT_LABEL
281 $$ = data_add_marker($1, LABEL, $2);
292 $$ = chain_node($1, $2);
296 print_error("syntax error: properties must precede subnodes");
302 DT_PROPNODENAME nodedef
304 $$ = name_node($2, $1);
308 add_label(&$2->labels, $1);
315 void print_error(char const *fmt, ...)
320 srcpos_verror(&yylloc, fmt, va);
323 treesource_error = 1;
326 void yyerror(char const *s) {
327 print_error("%s", s);
330 static unsigned long long eval_literal(const char *s, int base, int bits)
332 unsigned long long val;
336 val = strtoull(s, &e, base);
338 print_error("bad characters in literal");
339 else if ((errno == ERANGE)
340 || ((bits < 64) && (val >= (1ULL << bits))))
341 print_error("literal out of range");
343 print_error("bad literal");