1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
12 extern
int yylex(void);
13 extern
void yyerror(char const *s
);
14 #define ERROR(loc, ...) \
16 srcpos_error
((loc
), "Error", __VA_ARGS__
); \
17 treesource_error
= true
; \
20 extern
struct dt_info
*parser_output
;
21 extern
bool treesource_error
;
35 struct property
*prop
;
36 struct property
*proplist
;
38 struct node
*nodelist
;
39 struct reserve_info
*re
;
47 %token DT_LSHIFT DT_RSHIFT DT_LE DT_GE DT_EQ DT_NE DT_AND DT_OR
52 %token
<propnodename
> DT_PROPNODENAME
53 %token
<integer
> DT_LITERAL
54 %token
<integer
> DT_CHAR_LITERAL
56 %token
<data
> DT_STRING
57 %token
<labelref
> DT_LABEL
58 %token
<labelref
> DT_LABEL_REF
59 %token
<labelref
> DT_PATH_REF
63 %type
<data
> propdataprefix
67 %type
<re
> memreserves
68 %type
<array
> arrayprefix
69 %type
<data
> bytestring
71 %type
<proplist
> proplist
72 %type
<labelref
> dt_ref
74 %type
<node
> devicetree
77 %type
<nodelist
> subnodes
79 %type
<integer
> integer_prim
80 %type
<integer
> integer_unary
81 %type
<integer
> integer_mul
82 %type
<integer
> integer_add
83 %type
<integer
> integer_shift
84 %type
<integer
> integer_rela
85 %type
<integer
> integer_eq
86 %type
<integer
> integer_bitand
87 %type
<integer
> integer_bitxor
88 %type
<integer
> integer_bitor
89 %type
<integer
> integer_and
90 %type
<integer
> integer_or
91 %type
<integer
> integer_trinary
92 %type
<integer
> integer_expr
97 headers memreserves devicetree
99 parser_output
= build_dt_info
($1, $2, $3,
100 guess_boot_cpuid
($3));
109 | DT_V1
';' DT_PLUGIN
';'
111 $$
= DTSF_V1 | DTSF_PLUGIN
;
120 ERROR
(&@
2, "Header flags don't match earlier ones");
130 | memreserve memreserves
132 $$
= chain_reserve_entry
($1, $2);
137 DT_MEMRESERVE integer_prim integer_prim
';'
139 $$
= build_reserve_entry
($2, $3);
141 | DT_LABEL memreserve
143 add_label
(&$2->labels
, $1);
148 dt_ref: DT_LABEL_REF | DT_PATH_REF
;
153 $$
= name_node
($2, "");
155 | devicetree
'/' nodedef
157 $$
= merge_nodes
($1, $3);
162 * We rely on the rule being always:
163 * versioninfo plugindecl memreserves devicetree
164 * so $-1 is what we want (plugindecl)
166 if
(!($
<flags
>-1 & DTSF_PLUGIN
))
167 ERROR
(&@
2, "Label or path %s not found", $1);
168 $$
= add_orphan_node
(
169 name_node
(build_node
(NULL
, NULL
, NULL
),
173 | devicetree DT_LABEL dt_ref nodedef
175 struct node
*target
= get_node_by_ref
($1, $3);
178 add_label
(&target
->labels
, $2);
179 merge_nodes
(target
, $4);
181 ERROR
(&@
3, "Label or path %s not found", $3);
184 | devicetree DT_PATH_REF nodedef
187 * We rely on the rule being always:
188 * versioninfo plugindecl memreserves devicetree
189 * so $-1 is what we want (plugindecl)
191 if
($
<flags
>-1 & DTSF_PLUGIN
) {
192 add_orphan_node
($1, $3, $2);
194 struct node
*target
= get_node_by_ref
($1, $2);
197 merge_nodes
(target
, $3);
199 ERROR
(&@
2, "Label or path %s not found", $2);
203 | devicetree DT_LABEL_REF nodedef
205 struct node
*target
= get_node_by_ref
($1, $2);
208 merge_nodes
(target
, $3);
211 * We rely on the rule being always:
212 * versioninfo plugindecl memreserves devicetree
213 * so $-1 is what we want (plugindecl)
215 if
($
<flags
>-1 & DTSF_PLUGIN
)
216 add_orphan_node
($1, $3, $2);
218 ERROR
(&@
2, "Label or path %s not found", $2);
222 | devicetree DT_DEL_NODE dt_ref
';'
224 struct node
*target
= get_node_by_ref
($1, $3);
229 ERROR
(&@
3, "Label or path %s not found", $3);
234 | devicetree DT_OMIT_NO_REF dt_ref
';'
236 struct node
*target
= get_node_by_ref
($1, $3);
239 omit_node_if_unused
(target
);
241 ERROR
(&@
3, "Label or path %s not found", $3);
249 '{' proplist subnodes
'}' ';'
251 $$
= build_node
($2, $3, &@$
);
262 $$
= chain_property
($2, $1);
267 DT_PROPNODENAME
'=' propdata
';'
269 $$
= build_property
($1, $3, &@$
);
271 | DT_PROPNODENAME
';'
273 $$
= build_property
($1, empty_data
, &@$
);
275 | DT_DEL_PROP DT_PROPNODENAME
';'
277 $$
= build_property_delete
($2);
281 add_label
(&$2->labels
, $1);
287 propdataprefix DT_STRING
289 $$
= data_merge
($1, $2);
291 | propdataprefix arrayprefix
'>'
293 $$
= data_merge
($1, $2.data
);
295 | propdataprefix
'[' bytestring
']'
297 $$
= data_merge
($1, $3);
299 | propdataprefix dt_ref
301 $1 = data_add_marker
($1, TYPE_STRING
, $2);
302 $$
= data_add_marker
($1, REF_PATH
, $2);
304 | propdataprefix DT_INCBIN
'(' DT_STRING
',' integer_prim
',' integer_prim
')'
306 FILE *f
= srcfile_relative_open
($4.val
, NULL
);
310 if
(fseek
(f
, $6, SEEK_SET
) != 0)
311 die
("Couldn't seek to offset %llu in \"%s\": %s",
312 (unsigned long long)$6, $4.val
,
315 d
= data_copy_file
(f
, $8);
317 $$
= data_merge
($1, d
);
320 | propdataprefix DT_INCBIN
'(' DT_STRING
')'
322 FILE *f
= srcfile_relative_open
($4.val
, NULL
);
323 struct data d
= empty_data
;
325 d
= data_copy_file
(f
, -1);
327 $$
= data_merge
($1, d
);
332 $$
= data_add_marker
($1, LABEL
, $2);
345 | propdataprefix DT_LABEL
347 $$
= data_add_marker
($1, LABEL
, $2);
352 DT_BITS DT_LITERAL
'<'
354 unsigned long long bits
;
355 enum markertype type
= TYPE_UINT32
;
360 case
8: type
= TYPE_UINT8
; break
;
361 case
16: type
= TYPE_UINT16
; break
;
362 case
32: type
= TYPE_UINT32
; break
;
363 case
64: type
= TYPE_UINT64
; break
;
365 ERROR
(&@
2, "Array elements must be"
366 " 8, 16, 32 or 64-bits");
370 $$.data
= data_add_marker
(empty_data
, type
, NULL
);
375 $$.data
= data_add_marker
(empty_data
, TYPE_UINT32
, NULL
);
378 | arrayprefix integer_prim
381 uint64_t mask
= (1ULL << $1.bits
) - 1;
383 * Bits above mask must either be all zero
384 * (positive within range of mask) or all one
385 * (negative and sign-extended). The second
386 * condition is true if when we set all bits
387 * within the mask to one (i.e. | in the
388 * mask), all bits are one.
390 if
(($2 > mask
) && (($2 | mask
) != -1ULL))
391 ERROR
(&@
2, "Value out of range for"
392 " %d-bit array element", $1.bits
);
395 $$.data
= data_append_integer
($1.data
, $2, $1.bits
);
399 uint64_t val
= ~
0ULL >> (64 - $1.bits
);
402 $1.data
= data_add_marker
($1.data
,
406 ERROR
(&@
2, "References are only allowed in "
407 "arrays with 32-bit elements.");
409 $$.data
= data_append_integer
($1.data
, val
, $1.bits
);
411 | arrayprefix DT_LABEL
413 $$.data
= data_add_marker
($1.data
, LABEL
, $2);
420 |
'(' integer_expr
')'
432 | integer_or
'?' integer_expr
':' integer_trinary
{ $$
= $1 ?
$3 : $5; }
437 | integer_or DT_OR integer_and
{ $$
= $1 ||
$3; }
442 | integer_and DT_AND integer_bitor
{ $$
= $1 && $3; }
447 | integer_bitor
'|' integer_bitxor
{ $$
= $1 |
$3; }
452 | integer_bitxor
'^' integer_bitand
{ $$
= $1 ^
$3; }
457 | integer_bitand
'&' integer_eq
{ $$
= $1 & $3; }
462 | integer_eq DT_EQ integer_rela
{ $$
= $1 == $3; }
463 | integer_eq DT_NE integer_rela
{ $$
= $1 != $3; }
468 | integer_rela
'<' integer_shift
{ $$
= $1 < $3; }
469 | integer_rela
'>' integer_shift
{ $$
= $1 > $3; }
470 | integer_rela DT_LE integer_shift
{ $$
= $1 <= $3; }
471 | integer_rela DT_GE integer_shift
{ $$
= $1 >= $3; }
475 integer_shift DT_LSHIFT integer_add
{ $$
= $1 << $3; }
476 | integer_shift DT_RSHIFT integer_add
{ $$
= $1 >> $3; }
481 integer_add
'+' integer_mul
{ $$
= $1 + $3; }
482 | integer_add
'-' integer_mul
{ $$
= $1 - $3; }
487 integer_mul
'*' integer_unary
{ $$
= $1 * $3; }
488 | integer_mul
'/' integer_unary
493 ERROR
(&@$
, "Division by zero");
497 | integer_mul
'%' integer_unary
502 ERROR
(&@$
, "Division by zero");
511 |
'-' integer_unary
{ $$
= -$2; }
512 |
'~' integer_unary
{ $$
= ~
$2; }
513 |
'!' integer_unary
{ $$
= !$2; }
519 $$
= data_add_marker
(empty_data
, TYPE_UINT8
, NULL
);
523 $$
= data_append_byte
($1, $2);
525 | bytestring DT_LABEL
527 $$
= data_add_marker
($1, LABEL
, $2);
538 $$
= chain_node
($1, $2);
542 ERROR
(&@
2, "Properties must precede subnodes");
548 DT_PROPNODENAME nodedef
550 $$
= name_node
($2, $1);
552 | DT_DEL_NODE DT_PROPNODENAME
';'
554 $$
= name_node
(build_node_delete
(&@$
), $2);
556 | DT_OMIT_NO_REF subnode
558 $$
= omit_node_if_unused
($2);
562 add_label
(&$2->labels
, $1);
569 void yyerror(char const *s
)
571 ERROR
(&yylloc, "%s", s
);