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");