1*cd60bc56SAndroid Build Coastguard Worker // SPDX-License-Identifier: GPL-2.0-or-later
2*cd60bc56SAndroid Build Coastguard Worker /*
3*cd60bc56SAndroid Build Coastguard Worker * (C) Copyright David Gibson <[email protected]>, IBM Corporation. 2005.
4*cd60bc56SAndroid Build Coastguard Worker */
5*cd60bc56SAndroid Build Coastguard Worker %locations
6*cd60bc56SAndroid Build Coastguard Worker
7*cd60bc56SAndroid Build Coastguard Worker %{
8*cd60bc56SAndroid Build Coastguard Worker #include <stdio.h>
9*cd60bc56SAndroid Build Coastguard Worker #include <inttypes.h>
10*cd60bc56SAndroid Build Coastguard Worker
11*cd60bc56SAndroid Build Coastguard Worker #include "dtc.h"
12*cd60bc56SAndroid Build Coastguard Worker #include "srcpos.h"
13*cd60bc56SAndroid Build Coastguard Worker
14*cd60bc56SAndroid Build Coastguard Worker extern int yylex(void);
15*cd60bc56SAndroid Build Coastguard Worker extern void yyerror(char const *s);
16*cd60bc56SAndroid Build Coastguard Worker #define ERROR(loc, ...) \
17*cd60bc56SAndroid Build Coastguard Worker do { \
18*cd60bc56SAndroid Build Coastguard Worker srcpos_error((loc), "Error", __VA_ARGS__); \
19*cd60bc56SAndroid Build Coastguard Worker treesource_error = true; \
20*cd60bc56SAndroid Build Coastguard Worker } while (0)
21*cd60bc56SAndroid Build Coastguard Worker
22*cd60bc56SAndroid Build Coastguard Worker #define YYERROR_CALL(msg) yyerror(msg)
23*cd60bc56SAndroid Build Coastguard Worker
24*cd60bc56SAndroid Build Coastguard Worker extern struct dt_info *parser_output;
25*cd60bc56SAndroid Build Coastguard Worker extern bool treesource_error;
26*cd60bc56SAndroid Build Coastguard Worker
is_ref_relative(const char * ref)27*cd60bc56SAndroid Build Coastguard Worker static bool is_ref_relative(const char *ref)
28*cd60bc56SAndroid Build Coastguard Worker {
29*cd60bc56SAndroid Build Coastguard Worker return ref[0] != '/' && strchr(&ref[1], '/');
30*cd60bc56SAndroid Build Coastguard Worker }
31*cd60bc56SAndroid Build Coastguard Worker
32*cd60bc56SAndroid Build Coastguard Worker %}
33*cd60bc56SAndroid Build Coastguard Worker
34*cd60bc56SAndroid Build Coastguard Worker %union {
35*cd60bc56SAndroid Build Coastguard Worker char *propnodename;
36*cd60bc56SAndroid Build Coastguard Worker char *labelref;
37*cd60bc56SAndroid Build Coastguard Worker uint8_t byte;
38*cd60bc56SAndroid Build Coastguard Worker struct data data;
39*cd60bc56SAndroid Build Coastguard Worker
40*cd60bc56SAndroid Build Coastguard Worker struct {
41*cd60bc56SAndroid Build Coastguard Worker struct data data;
42*cd60bc56SAndroid Build Coastguard Worker int bits;
43*cd60bc56SAndroid Build Coastguard Worker } array;
44*cd60bc56SAndroid Build Coastguard Worker
45*cd60bc56SAndroid Build Coastguard Worker struct property *prop;
46*cd60bc56SAndroid Build Coastguard Worker struct property *proplist;
47*cd60bc56SAndroid Build Coastguard Worker struct node *node;
48*cd60bc56SAndroid Build Coastguard Worker struct node *nodelist;
49*cd60bc56SAndroid Build Coastguard Worker struct reserve_info *re;
50*cd60bc56SAndroid Build Coastguard Worker uint64_t integer;
51*cd60bc56SAndroid Build Coastguard Worker unsigned int flags;
52*cd60bc56SAndroid Build Coastguard Worker }
53*cd60bc56SAndroid Build Coastguard Worker
54*cd60bc56SAndroid Build Coastguard Worker %token DT_V1
55*cd60bc56SAndroid Build Coastguard Worker %token DT_PLUGIN
56*cd60bc56SAndroid Build Coastguard Worker %token DT_MEMRESERVE
57*cd60bc56SAndroid Build Coastguard Worker %token DT_LSHIFT DT_RSHIFT DT_LE DT_GE DT_EQ DT_NE DT_AND DT_OR
58*cd60bc56SAndroid Build Coastguard Worker %token DT_BITS
59*cd60bc56SAndroid Build Coastguard Worker %token DT_DEL_PROP
60*cd60bc56SAndroid Build Coastguard Worker %token DT_DEL_NODE
61*cd60bc56SAndroid Build Coastguard Worker %token DT_OMIT_NO_REF
62*cd60bc56SAndroid Build Coastguard Worker %token <propnodename> DT_PROPNODENAME
63*cd60bc56SAndroid Build Coastguard Worker %token <integer> DT_LITERAL
64*cd60bc56SAndroid Build Coastguard Worker %token <integer> DT_CHAR_LITERAL
65*cd60bc56SAndroid Build Coastguard Worker %token <byte> DT_BYTE
66*cd60bc56SAndroid Build Coastguard Worker %token <data> DT_STRING
67*cd60bc56SAndroid Build Coastguard Worker %token <labelref> DT_LABEL
68*cd60bc56SAndroid Build Coastguard Worker %token <labelref> DT_LABEL_REF
69*cd60bc56SAndroid Build Coastguard Worker %token <labelref> DT_PATH_REF
70*cd60bc56SAndroid Build Coastguard Worker %token DT_INCBIN
71*cd60bc56SAndroid Build Coastguard Worker
72*cd60bc56SAndroid Build Coastguard Worker %type <data> propdata
73*cd60bc56SAndroid Build Coastguard Worker %type <data> propdataprefix
74*cd60bc56SAndroid Build Coastguard Worker %type <flags> header
75*cd60bc56SAndroid Build Coastguard Worker %type <flags> headers
76*cd60bc56SAndroid Build Coastguard Worker %type <re> memreserve
77*cd60bc56SAndroid Build Coastguard Worker %type <re> memreserves
78*cd60bc56SAndroid Build Coastguard Worker %type <array> arrayprefix
79*cd60bc56SAndroid Build Coastguard Worker %type <data> bytestring
80*cd60bc56SAndroid Build Coastguard Worker %type <prop> propdef
81*cd60bc56SAndroid Build Coastguard Worker %type <proplist> proplist
82*cd60bc56SAndroid Build Coastguard Worker %type <labelref> dt_ref
83*cd60bc56SAndroid Build Coastguard Worker
84*cd60bc56SAndroid Build Coastguard Worker %type <node> devicetree
85*cd60bc56SAndroid Build Coastguard Worker %type <node> nodedef
86*cd60bc56SAndroid Build Coastguard Worker %type <node> subnode
87*cd60bc56SAndroid Build Coastguard Worker %type <nodelist> subnodes
88*cd60bc56SAndroid Build Coastguard Worker
89*cd60bc56SAndroid Build Coastguard Worker %type <integer> integer_prim
90*cd60bc56SAndroid Build Coastguard Worker %type <integer> integer_unary
91*cd60bc56SAndroid Build Coastguard Worker %type <integer> integer_mul
92*cd60bc56SAndroid Build Coastguard Worker %type <integer> integer_add
93*cd60bc56SAndroid Build Coastguard Worker %type <integer> integer_shift
94*cd60bc56SAndroid Build Coastguard Worker %type <integer> integer_rela
95*cd60bc56SAndroid Build Coastguard Worker %type <integer> integer_eq
96*cd60bc56SAndroid Build Coastguard Worker %type <integer> integer_bitand
97*cd60bc56SAndroid Build Coastguard Worker %type <integer> integer_bitxor
98*cd60bc56SAndroid Build Coastguard Worker %type <integer> integer_bitor
99*cd60bc56SAndroid Build Coastguard Worker %type <integer> integer_and
100*cd60bc56SAndroid Build Coastguard Worker %type <integer> integer_or
101*cd60bc56SAndroid Build Coastguard Worker %type <integer> integer_trinary
102*cd60bc56SAndroid Build Coastguard Worker %type <integer> integer_expr
103*cd60bc56SAndroid Build Coastguard Worker
104*cd60bc56SAndroid Build Coastguard Worker %%
105*cd60bc56SAndroid Build Coastguard Worker
106*cd60bc56SAndroid Build Coastguard Worker sourcefile:
107*cd60bc56SAndroid Build Coastguard Worker headers memreserves devicetree
108*cd60bc56SAndroid Build Coastguard Worker {
109*cd60bc56SAndroid Build Coastguard Worker parser_output = build_dt_info($1, $2, $3,
110*cd60bc56SAndroid Build Coastguard Worker guess_boot_cpuid($3));
111*cd60bc56SAndroid Build Coastguard Worker }
112*cd60bc56SAndroid Build Coastguard Worker ;
113*cd60bc56SAndroid Build Coastguard Worker
114*cd60bc56SAndroid Build Coastguard Worker header:
115*cd60bc56SAndroid Build Coastguard Worker DT_V1 ';'
116*cd60bc56SAndroid Build Coastguard Worker {
117*cd60bc56SAndroid Build Coastguard Worker $$ = DTSF_V1;
118*cd60bc56SAndroid Build Coastguard Worker }
119*cd60bc56SAndroid Build Coastguard Worker | DT_V1 ';' DT_PLUGIN ';'
120*cd60bc56SAndroid Build Coastguard Worker {
121*cd60bc56SAndroid Build Coastguard Worker $$ = DTSF_V1 | DTSF_PLUGIN;
122*cd60bc56SAndroid Build Coastguard Worker }
123*cd60bc56SAndroid Build Coastguard Worker ;
124*cd60bc56SAndroid Build Coastguard Worker
125*cd60bc56SAndroid Build Coastguard Worker headers:
126*cd60bc56SAndroid Build Coastguard Worker header
127*cd60bc56SAndroid Build Coastguard Worker | header headers
128*cd60bc56SAndroid Build Coastguard Worker {
129*cd60bc56SAndroid Build Coastguard Worker if ($2 != $1)
130*cd60bc56SAndroid Build Coastguard Worker ERROR(&@2, "Header flags don't match earlier ones");
131*cd60bc56SAndroid Build Coastguard Worker $$ = $1;
132*cd60bc56SAndroid Build Coastguard Worker }
133*cd60bc56SAndroid Build Coastguard Worker ;
134*cd60bc56SAndroid Build Coastguard Worker
135*cd60bc56SAndroid Build Coastguard Worker memreserves:
136*cd60bc56SAndroid Build Coastguard Worker /* empty */
137*cd60bc56SAndroid Build Coastguard Worker {
138*cd60bc56SAndroid Build Coastguard Worker $$ = NULL;
139*cd60bc56SAndroid Build Coastguard Worker }
140*cd60bc56SAndroid Build Coastguard Worker | memreserve memreserves
141*cd60bc56SAndroid Build Coastguard Worker {
142*cd60bc56SAndroid Build Coastguard Worker $$ = chain_reserve_entry($1, $2);
143*cd60bc56SAndroid Build Coastguard Worker }
144*cd60bc56SAndroid Build Coastguard Worker ;
145*cd60bc56SAndroid Build Coastguard Worker
146*cd60bc56SAndroid Build Coastguard Worker memreserve:
147*cd60bc56SAndroid Build Coastguard Worker DT_MEMRESERVE integer_prim integer_prim ';'
148*cd60bc56SAndroid Build Coastguard Worker {
149*cd60bc56SAndroid Build Coastguard Worker $$ = build_reserve_entry($2, $3);
150*cd60bc56SAndroid Build Coastguard Worker }
151*cd60bc56SAndroid Build Coastguard Worker | DT_LABEL memreserve
152*cd60bc56SAndroid Build Coastguard Worker {
153*cd60bc56SAndroid Build Coastguard Worker add_label(&$2->labels, $1);
154*cd60bc56SAndroid Build Coastguard Worker $$ = $2;
155*cd60bc56SAndroid Build Coastguard Worker }
156*cd60bc56SAndroid Build Coastguard Worker ;
157*cd60bc56SAndroid Build Coastguard Worker
158*cd60bc56SAndroid Build Coastguard Worker dt_ref: DT_LABEL_REF | DT_PATH_REF;
159*cd60bc56SAndroid Build Coastguard Worker
160*cd60bc56SAndroid Build Coastguard Worker devicetree:
161*cd60bc56SAndroid Build Coastguard Worker '/' nodedef
162*cd60bc56SAndroid Build Coastguard Worker {
163*cd60bc56SAndroid Build Coastguard Worker $$ = name_node($2, "");
164*cd60bc56SAndroid Build Coastguard Worker }
165*cd60bc56SAndroid Build Coastguard Worker | devicetree '/' nodedef
166*cd60bc56SAndroid Build Coastguard Worker {
167*cd60bc56SAndroid Build Coastguard Worker $$ = merge_nodes($1, $3);
168*cd60bc56SAndroid Build Coastguard Worker }
169*cd60bc56SAndroid Build Coastguard Worker | dt_ref nodedef
170*cd60bc56SAndroid Build Coastguard Worker {
171*cd60bc56SAndroid Build Coastguard Worker /*
172*cd60bc56SAndroid Build Coastguard Worker * We rely on the rule being always:
173*cd60bc56SAndroid Build Coastguard Worker * versioninfo plugindecl memreserves devicetree
174*cd60bc56SAndroid Build Coastguard Worker * so $-1 is what we want (plugindecl)
175*cd60bc56SAndroid Build Coastguard Worker */
176*cd60bc56SAndroid Build Coastguard Worker if (!($<flags>-1 & DTSF_PLUGIN))
177*cd60bc56SAndroid Build Coastguard Worker ERROR(&@2, "Label or path %s not found", $1);
178*cd60bc56SAndroid Build Coastguard Worker else if (is_ref_relative($1))
179*cd60bc56SAndroid Build Coastguard Worker ERROR(&@2, "Label-relative reference %s not supported in plugin", $1);
180*cd60bc56SAndroid Build Coastguard Worker $$ = add_orphan_node(
181*cd60bc56SAndroid Build Coastguard Worker name_node(build_node(NULL, NULL, NULL),
182*cd60bc56SAndroid Build Coastguard Worker ""),
183*cd60bc56SAndroid Build Coastguard Worker $2, $1);
184*cd60bc56SAndroid Build Coastguard Worker }
185*cd60bc56SAndroid Build Coastguard Worker | devicetree DT_LABEL dt_ref nodedef
186*cd60bc56SAndroid Build Coastguard Worker {
187*cd60bc56SAndroid Build Coastguard Worker struct node *target = get_node_by_ref($1, $3);
188*cd60bc56SAndroid Build Coastguard Worker
189*cd60bc56SAndroid Build Coastguard Worker if (($<flags>-1 & DTSF_PLUGIN) && is_ref_relative($3))
190*cd60bc56SAndroid Build Coastguard Worker ERROR(&@2, "Label-relative reference %s not supported in plugin", $3);
191*cd60bc56SAndroid Build Coastguard Worker
192*cd60bc56SAndroid Build Coastguard Worker if (target) {
193*cd60bc56SAndroid Build Coastguard Worker add_label(&target->labels, $2);
194*cd60bc56SAndroid Build Coastguard Worker merge_nodes(target, $4);
195*cd60bc56SAndroid Build Coastguard Worker } else
196*cd60bc56SAndroid Build Coastguard Worker ERROR(&@3, "Label or path %s not found", $3);
197*cd60bc56SAndroid Build Coastguard Worker $$ = $1;
198*cd60bc56SAndroid Build Coastguard Worker }
199*cd60bc56SAndroid Build Coastguard Worker | devicetree DT_PATH_REF nodedef
200*cd60bc56SAndroid Build Coastguard Worker {
201*cd60bc56SAndroid Build Coastguard Worker /*
202*cd60bc56SAndroid Build Coastguard Worker * We rely on the rule being always:
203*cd60bc56SAndroid Build Coastguard Worker * versioninfo plugindecl memreserves devicetree
204*cd60bc56SAndroid Build Coastguard Worker * so $-1 is what we want (plugindecl)
205*cd60bc56SAndroid Build Coastguard Worker */
206*cd60bc56SAndroid Build Coastguard Worker if ($<flags>-1 & DTSF_PLUGIN) {
207*cd60bc56SAndroid Build Coastguard Worker if (is_ref_relative($2))
208*cd60bc56SAndroid Build Coastguard Worker ERROR(&@2, "Label-relative reference %s not supported in plugin", $2);
209*cd60bc56SAndroid Build Coastguard Worker add_orphan_node($1, $3, $2);
210*cd60bc56SAndroid Build Coastguard Worker } else {
211*cd60bc56SAndroid Build Coastguard Worker struct node *target = get_node_by_ref($1, $2);
212*cd60bc56SAndroid Build Coastguard Worker
213*cd60bc56SAndroid Build Coastguard Worker if (target)
214*cd60bc56SAndroid Build Coastguard Worker merge_nodes(target, $3);
215*cd60bc56SAndroid Build Coastguard Worker else
216*cd60bc56SAndroid Build Coastguard Worker ERROR(&@2, "Label or path %s not found", $2);
217*cd60bc56SAndroid Build Coastguard Worker }
218*cd60bc56SAndroid Build Coastguard Worker $$ = $1;
219*cd60bc56SAndroid Build Coastguard Worker }
220*cd60bc56SAndroid Build Coastguard Worker | devicetree DT_LABEL_REF nodedef
221*cd60bc56SAndroid Build Coastguard Worker {
222*cd60bc56SAndroid Build Coastguard Worker struct node *target = get_node_by_ref($1, $2);
223*cd60bc56SAndroid Build Coastguard Worker
224*cd60bc56SAndroid Build Coastguard Worker if (target) {
225*cd60bc56SAndroid Build Coastguard Worker merge_nodes(target, $3);
226*cd60bc56SAndroid Build Coastguard Worker } else {
227*cd60bc56SAndroid Build Coastguard Worker /*
228*cd60bc56SAndroid Build Coastguard Worker * We rely on the rule being always:
229*cd60bc56SAndroid Build Coastguard Worker * versioninfo plugindecl memreserves devicetree
230*cd60bc56SAndroid Build Coastguard Worker * so $-1 is what we want (plugindecl)
231*cd60bc56SAndroid Build Coastguard Worker */
232*cd60bc56SAndroid Build Coastguard Worker if ($<flags>-1 & DTSF_PLUGIN)
233*cd60bc56SAndroid Build Coastguard Worker add_orphan_node($1, $3, $2);
234*cd60bc56SAndroid Build Coastguard Worker else
235*cd60bc56SAndroid Build Coastguard Worker ERROR(&@2, "Label or path %s not found", $2);
236*cd60bc56SAndroid Build Coastguard Worker }
237*cd60bc56SAndroid Build Coastguard Worker $$ = $1;
238*cd60bc56SAndroid Build Coastguard Worker }
239*cd60bc56SAndroid Build Coastguard Worker | devicetree DT_DEL_NODE dt_ref ';'
240*cd60bc56SAndroid Build Coastguard Worker {
241*cd60bc56SAndroid Build Coastguard Worker struct node *target = get_node_by_ref($1, $3);
242*cd60bc56SAndroid Build Coastguard Worker
243*cd60bc56SAndroid Build Coastguard Worker if (target)
244*cd60bc56SAndroid Build Coastguard Worker delete_node(target);
245*cd60bc56SAndroid Build Coastguard Worker else
246*cd60bc56SAndroid Build Coastguard Worker ERROR(&@3, "Label or path %s not found", $3);
247*cd60bc56SAndroid Build Coastguard Worker
248*cd60bc56SAndroid Build Coastguard Worker
249*cd60bc56SAndroid Build Coastguard Worker $$ = $1;
250*cd60bc56SAndroid Build Coastguard Worker }
251*cd60bc56SAndroid Build Coastguard Worker | devicetree DT_OMIT_NO_REF dt_ref ';'
252*cd60bc56SAndroid Build Coastguard Worker {
253*cd60bc56SAndroid Build Coastguard Worker struct node *target = get_node_by_ref($1, $3);
254*cd60bc56SAndroid Build Coastguard Worker
255*cd60bc56SAndroid Build Coastguard Worker if (target)
256*cd60bc56SAndroid Build Coastguard Worker omit_node_if_unused(target);
257*cd60bc56SAndroid Build Coastguard Worker else
258*cd60bc56SAndroid Build Coastguard Worker ERROR(&@3, "Label or path %s not found", $3);
259*cd60bc56SAndroid Build Coastguard Worker
260*cd60bc56SAndroid Build Coastguard Worker
261*cd60bc56SAndroid Build Coastguard Worker $$ = $1;
262*cd60bc56SAndroid Build Coastguard Worker }
263*cd60bc56SAndroid Build Coastguard Worker | /* empty */
264*cd60bc56SAndroid Build Coastguard Worker {
265*cd60bc56SAndroid Build Coastguard Worker /* build empty node */
266*cd60bc56SAndroid Build Coastguard Worker $$ = name_node(build_node(NULL, NULL, NULL), "");
267*cd60bc56SAndroid Build Coastguard Worker }
268*cd60bc56SAndroid Build Coastguard Worker ;
269*cd60bc56SAndroid Build Coastguard Worker
270*cd60bc56SAndroid Build Coastguard Worker nodedef:
271*cd60bc56SAndroid Build Coastguard Worker '{' proplist subnodes '}' ';'
272*cd60bc56SAndroid Build Coastguard Worker {
273*cd60bc56SAndroid Build Coastguard Worker $$ = build_node($2, $3, &@$);
274*cd60bc56SAndroid Build Coastguard Worker }
275*cd60bc56SAndroid Build Coastguard Worker ;
276*cd60bc56SAndroid Build Coastguard Worker
277*cd60bc56SAndroid Build Coastguard Worker proplist:
278*cd60bc56SAndroid Build Coastguard Worker /* empty */
279*cd60bc56SAndroid Build Coastguard Worker {
280*cd60bc56SAndroid Build Coastguard Worker $$ = NULL;
281*cd60bc56SAndroid Build Coastguard Worker }
282*cd60bc56SAndroid Build Coastguard Worker | proplist propdef
283*cd60bc56SAndroid Build Coastguard Worker {
284*cd60bc56SAndroid Build Coastguard Worker $$ = chain_property($2, $1);
285*cd60bc56SAndroid Build Coastguard Worker }
286*cd60bc56SAndroid Build Coastguard Worker ;
287*cd60bc56SAndroid Build Coastguard Worker
288*cd60bc56SAndroid Build Coastguard Worker propdef:
289*cd60bc56SAndroid Build Coastguard Worker DT_PROPNODENAME '=' propdata ';'
290*cd60bc56SAndroid Build Coastguard Worker {
291*cd60bc56SAndroid Build Coastguard Worker $$ = build_property($1, $3, &@$);
292*cd60bc56SAndroid Build Coastguard Worker }
293*cd60bc56SAndroid Build Coastguard Worker | DT_PROPNODENAME ';'
294*cd60bc56SAndroid Build Coastguard Worker {
295*cd60bc56SAndroid Build Coastguard Worker $$ = build_property($1, empty_data, &@$);
296*cd60bc56SAndroid Build Coastguard Worker }
297*cd60bc56SAndroid Build Coastguard Worker | DT_DEL_PROP DT_PROPNODENAME ';'
298*cd60bc56SAndroid Build Coastguard Worker {
299*cd60bc56SAndroid Build Coastguard Worker $$ = build_property_delete($2);
300*cd60bc56SAndroid Build Coastguard Worker }
301*cd60bc56SAndroid Build Coastguard Worker | DT_LABEL propdef
302*cd60bc56SAndroid Build Coastguard Worker {
303*cd60bc56SAndroid Build Coastguard Worker add_label(&$2->labels, $1);
304*cd60bc56SAndroid Build Coastguard Worker $$ = $2;
305*cd60bc56SAndroid Build Coastguard Worker }
306*cd60bc56SAndroid Build Coastguard Worker ;
307*cd60bc56SAndroid Build Coastguard Worker
308*cd60bc56SAndroid Build Coastguard Worker propdata:
309*cd60bc56SAndroid Build Coastguard Worker propdataprefix DT_STRING
310*cd60bc56SAndroid Build Coastguard Worker {
311*cd60bc56SAndroid Build Coastguard Worker $$ = data_merge($1, $2);
312*cd60bc56SAndroid Build Coastguard Worker }
313*cd60bc56SAndroid Build Coastguard Worker | propdataprefix arrayprefix '>'
314*cd60bc56SAndroid Build Coastguard Worker {
315*cd60bc56SAndroid Build Coastguard Worker $$ = data_merge($1, $2.data);
316*cd60bc56SAndroid Build Coastguard Worker }
317*cd60bc56SAndroid Build Coastguard Worker | propdataprefix '[' bytestring ']'
318*cd60bc56SAndroid Build Coastguard Worker {
319*cd60bc56SAndroid Build Coastguard Worker $$ = data_merge($1, $3);
320*cd60bc56SAndroid Build Coastguard Worker }
321*cd60bc56SAndroid Build Coastguard Worker | propdataprefix dt_ref
322*cd60bc56SAndroid Build Coastguard Worker {
323*cd60bc56SAndroid Build Coastguard Worker $1 = data_add_marker($1, TYPE_STRING, $2);
324*cd60bc56SAndroid Build Coastguard Worker $$ = data_add_marker($1, REF_PATH, $2);
325*cd60bc56SAndroid Build Coastguard Worker }
326*cd60bc56SAndroid Build Coastguard Worker | propdataprefix DT_INCBIN '(' DT_STRING ',' integer_prim ',' integer_prim ')'
327*cd60bc56SAndroid Build Coastguard Worker {
328*cd60bc56SAndroid Build Coastguard Worker FILE *f = srcfile_relative_open($4.val, NULL);
329*cd60bc56SAndroid Build Coastguard Worker struct data d;
330*cd60bc56SAndroid Build Coastguard Worker
331*cd60bc56SAndroid Build Coastguard Worker if ($6 != 0)
332*cd60bc56SAndroid Build Coastguard Worker if (fseek(f, $6, SEEK_SET) != 0)
333*cd60bc56SAndroid Build Coastguard Worker die("Couldn't seek to offset %llu in \"%s\": %s",
334*cd60bc56SAndroid Build Coastguard Worker (unsigned long long)$6, $4.val,
335*cd60bc56SAndroid Build Coastguard Worker strerror(errno));
336*cd60bc56SAndroid Build Coastguard Worker
337*cd60bc56SAndroid Build Coastguard Worker d = data_copy_file(f, $8);
338*cd60bc56SAndroid Build Coastguard Worker
339*cd60bc56SAndroid Build Coastguard Worker $$ = data_merge($1, d);
340*cd60bc56SAndroid Build Coastguard Worker fclose(f);
341*cd60bc56SAndroid Build Coastguard Worker }
342*cd60bc56SAndroid Build Coastguard Worker | propdataprefix DT_INCBIN '(' DT_STRING ')'
343*cd60bc56SAndroid Build Coastguard Worker {
344*cd60bc56SAndroid Build Coastguard Worker FILE *f = srcfile_relative_open($4.val, NULL);
345*cd60bc56SAndroid Build Coastguard Worker struct data d = empty_data;
346*cd60bc56SAndroid Build Coastguard Worker
347*cd60bc56SAndroid Build Coastguard Worker d = data_copy_file(f, -1);
348*cd60bc56SAndroid Build Coastguard Worker
349*cd60bc56SAndroid Build Coastguard Worker $$ = data_merge($1, d);
350*cd60bc56SAndroid Build Coastguard Worker fclose(f);
351*cd60bc56SAndroid Build Coastguard Worker }
352*cd60bc56SAndroid Build Coastguard Worker | propdata DT_LABEL
353*cd60bc56SAndroid Build Coastguard Worker {
354*cd60bc56SAndroid Build Coastguard Worker $$ = data_add_marker($1, LABEL, $2);
355*cd60bc56SAndroid Build Coastguard Worker }
356*cd60bc56SAndroid Build Coastguard Worker ;
357*cd60bc56SAndroid Build Coastguard Worker
358*cd60bc56SAndroid Build Coastguard Worker propdataprefix:
359*cd60bc56SAndroid Build Coastguard Worker /* empty */
360*cd60bc56SAndroid Build Coastguard Worker {
361*cd60bc56SAndroid Build Coastguard Worker $$ = empty_data;
362*cd60bc56SAndroid Build Coastguard Worker }
363*cd60bc56SAndroid Build Coastguard Worker | propdata ','
364*cd60bc56SAndroid Build Coastguard Worker {
365*cd60bc56SAndroid Build Coastguard Worker $$ = $1;
366*cd60bc56SAndroid Build Coastguard Worker }
367*cd60bc56SAndroid Build Coastguard Worker | propdataprefix DT_LABEL
368*cd60bc56SAndroid Build Coastguard Worker {
369*cd60bc56SAndroid Build Coastguard Worker $$ = data_add_marker($1, LABEL, $2);
370*cd60bc56SAndroid Build Coastguard Worker }
371*cd60bc56SAndroid Build Coastguard Worker ;
372*cd60bc56SAndroid Build Coastguard Worker
373*cd60bc56SAndroid Build Coastguard Worker arrayprefix:
374*cd60bc56SAndroid Build Coastguard Worker DT_BITS DT_LITERAL '<'
375*cd60bc56SAndroid Build Coastguard Worker {
376*cd60bc56SAndroid Build Coastguard Worker unsigned long long bits;
377*cd60bc56SAndroid Build Coastguard Worker enum markertype type = TYPE_UINT32;
378*cd60bc56SAndroid Build Coastguard Worker
379*cd60bc56SAndroid Build Coastguard Worker bits = $2;
380*cd60bc56SAndroid Build Coastguard Worker
381*cd60bc56SAndroid Build Coastguard Worker switch (bits) {
382*cd60bc56SAndroid Build Coastguard Worker case 8: type = TYPE_UINT8; break;
383*cd60bc56SAndroid Build Coastguard Worker case 16: type = TYPE_UINT16; break;
384*cd60bc56SAndroid Build Coastguard Worker case 32: type = TYPE_UINT32; break;
385*cd60bc56SAndroid Build Coastguard Worker case 64: type = TYPE_UINT64; break;
386*cd60bc56SAndroid Build Coastguard Worker default:
387*cd60bc56SAndroid Build Coastguard Worker ERROR(&@2, "Array elements must be"
388*cd60bc56SAndroid Build Coastguard Worker " 8, 16, 32 or 64-bits");
389*cd60bc56SAndroid Build Coastguard Worker bits = 32;
390*cd60bc56SAndroid Build Coastguard Worker }
391*cd60bc56SAndroid Build Coastguard Worker
392*cd60bc56SAndroid Build Coastguard Worker $$.data = data_add_marker(empty_data, type, NULL);
393*cd60bc56SAndroid Build Coastguard Worker $$.bits = bits;
394*cd60bc56SAndroid Build Coastguard Worker }
395*cd60bc56SAndroid Build Coastguard Worker | '<'
396*cd60bc56SAndroid Build Coastguard Worker {
397*cd60bc56SAndroid Build Coastguard Worker $$.data = data_add_marker(empty_data, TYPE_UINT32, NULL);
398*cd60bc56SAndroid Build Coastguard Worker $$.bits = 32;
399*cd60bc56SAndroid Build Coastguard Worker }
400*cd60bc56SAndroid Build Coastguard Worker | arrayprefix integer_prim
401*cd60bc56SAndroid Build Coastguard Worker {
402*cd60bc56SAndroid Build Coastguard Worker if ($1.bits < 64) {
403*cd60bc56SAndroid Build Coastguard Worker uint64_t mask = (1ULL << $1.bits) - 1;
404*cd60bc56SAndroid Build Coastguard Worker /*
405*cd60bc56SAndroid Build Coastguard Worker * Bits above mask must either be all zero
406*cd60bc56SAndroid Build Coastguard Worker * (positive within range of mask) or all one
407*cd60bc56SAndroid Build Coastguard Worker * (negative and sign-extended). The second
408*cd60bc56SAndroid Build Coastguard Worker * condition is true if when we set all bits
409*cd60bc56SAndroid Build Coastguard Worker * within the mask to one (i.e. | in the
410*cd60bc56SAndroid Build Coastguard Worker * mask), all bits are one.
411*cd60bc56SAndroid Build Coastguard Worker */
412*cd60bc56SAndroid Build Coastguard Worker if (($2 > mask) && (($2 | mask) != -1ULL)) {
413*cd60bc56SAndroid Build Coastguard Worker char *loc = srcpos_string(&@2);
414*cd60bc56SAndroid Build Coastguard Worker fprintf(stderr,
415*cd60bc56SAndroid Build Coastguard Worker "WARNING: %s: Value 0x%016" PRIx64
416*cd60bc56SAndroid Build Coastguard Worker " truncated to 0x%0*" PRIx64 "\n",
417*cd60bc56SAndroid Build Coastguard Worker loc, $2, $1.bits / 4, ($2 & mask));
418*cd60bc56SAndroid Build Coastguard Worker free(loc);
419*cd60bc56SAndroid Build Coastguard Worker }
420*cd60bc56SAndroid Build Coastguard Worker }
421*cd60bc56SAndroid Build Coastguard Worker
422*cd60bc56SAndroid Build Coastguard Worker $$.data = data_append_integer($1.data, $2, $1.bits);
423*cd60bc56SAndroid Build Coastguard Worker }
424*cd60bc56SAndroid Build Coastguard Worker | arrayprefix dt_ref
425*cd60bc56SAndroid Build Coastguard Worker {
426*cd60bc56SAndroid Build Coastguard Worker uint64_t val = ~0ULL >> (64 - $1.bits);
427*cd60bc56SAndroid Build Coastguard Worker
428*cd60bc56SAndroid Build Coastguard Worker if ($1.bits == 32)
429*cd60bc56SAndroid Build Coastguard Worker $1.data = data_add_marker($1.data,
430*cd60bc56SAndroid Build Coastguard Worker REF_PHANDLE,
431*cd60bc56SAndroid Build Coastguard Worker $2);
432*cd60bc56SAndroid Build Coastguard Worker else
433*cd60bc56SAndroid Build Coastguard Worker ERROR(&@2, "References are only allowed in "
434*cd60bc56SAndroid Build Coastguard Worker "arrays with 32-bit elements.");
435*cd60bc56SAndroid Build Coastguard Worker
436*cd60bc56SAndroid Build Coastguard Worker $$.data = data_append_integer($1.data, val, $1.bits);
437*cd60bc56SAndroid Build Coastguard Worker }
438*cd60bc56SAndroid Build Coastguard Worker | arrayprefix DT_LABEL
439*cd60bc56SAndroid Build Coastguard Worker {
440*cd60bc56SAndroid Build Coastguard Worker $$.data = data_add_marker($1.data, LABEL, $2);
441*cd60bc56SAndroid Build Coastguard Worker }
442*cd60bc56SAndroid Build Coastguard Worker ;
443*cd60bc56SAndroid Build Coastguard Worker
444*cd60bc56SAndroid Build Coastguard Worker integer_prim:
445*cd60bc56SAndroid Build Coastguard Worker DT_LITERAL
446*cd60bc56SAndroid Build Coastguard Worker | DT_CHAR_LITERAL
447*cd60bc56SAndroid Build Coastguard Worker | '(' integer_expr ')'
448*cd60bc56SAndroid Build Coastguard Worker {
449*cd60bc56SAndroid Build Coastguard Worker $$ = $2;
450*cd60bc56SAndroid Build Coastguard Worker }
451*cd60bc56SAndroid Build Coastguard Worker ;
452*cd60bc56SAndroid Build Coastguard Worker
453*cd60bc56SAndroid Build Coastguard Worker integer_expr:
454*cd60bc56SAndroid Build Coastguard Worker integer_trinary
455*cd60bc56SAndroid Build Coastguard Worker ;
456*cd60bc56SAndroid Build Coastguard Worker
457*cd60bc56SAndroid Build Coastguard Worker integer_trinary:
458*cd60bc56SAndroid Build Coastguard Worker integer_or
459*cd60bc56SAndroid Build Coastguard Worker | integer_or '?' integer_expr ':' integer_trinary { $$ = $1 ? $3 : $5; }
460*cd60bc56SAndroid Build Coastguard Worker ;
461*cd60bc56SAndroid Build Coastguard Worker
462*cd60bc56SAndroid Build Coastguard Worker integer_or:
463*cd60bc56SAndroid Build Coastguard Worker integer_and
464*cd60bc56SAndroid Build Coastguard Worker | integer_or DT_OR integer_and { $$ = $1 || $3; }
465*cd60bc56SAndroid Build Coastguard Worker ;
466*cd60bc56SAndroid Build Coastguard Worker
467*cd60bc56SAndroid Build Coastguard Worker integer_and:
468*cd60bc56SAndroid Build Coastguard Worker integer_bitor
469*cd60bc56SAndroid Build Coastguard Worker | integer_and DT_AND integer_bitor { $$ = $1 && $3; }
470*cd60bc56SAndroid Build Coastguard Worker ;
471*cd60bc56SAndroid Build Coastguard Worker
472*cd60bc56SAndroid Build Coastguard Worker integer_bitor:
473*cd60bc56SAndroid Build Coastguard Worker integer_bitxor
474*cd60bc56SAndroid Build Coastguard Worker | integer_bitor '|' integer_bitxor { $$ = $1 | $3; }
475*cd60bc56SAndroid Build Coastguard Worker ;
476*cd60bc56SAndroid Build Coastguard Worker
477*cd60bc56SAndroid Build Coastguard Worker integer_bitxor:
478*cd60bc56SAndroid Build Coastguard Worker integer_bitand
479*cd60bc56SAndroid Build Coastguard Worker | integer_bitxor '^' integer_bitand { $$ = $1 ^ $3; }
480*cd60bc56SAndroid Build Coastguard Worker ;
481*cd60bc56SAndroid Build Coastguard Worker
482*cd60bc56SAndroid Build Coastguard Worker integer_bitand:
483*cd60bc56SAndroid Build Coastguard Worker integer_eq
484*cd60bc56SAndroid Build Coastguard Worker | integer_bitand '&' integer_eq { $$ = $1 & $3; }
485*cd60bc56SAndroid Build Coastguard Worker ;
486*cd60bc56SAndroid Build Coastguard Worker
487*cd60bc56SAndroid Build Coastguard Worker integer_eq:
488*cd60bc56SAndroid Build Coastguard Worker integer_rela
489*cd60bc56SAndroid Build Coastguard Worker | integer_eq DT_EQ integer_rela { $$ = $1 == $3; }
490*cd60bc56SAndroid Build Coastguard Worker | integer_eq DT_NE integer_rela { $$ = $1 != $3; }
491*cd60bc56SAndroid Build Coastguard Worker ;
492*cd60bc56SAndroid Build Coastguard Worker
493*cd60bc56SAndroid Build Coastguard Worker integer_rela:
494*cd60bc56SAndroid Build Coastguard Worker integer_shift
495*cd60bc56SAndroid Build Coastguard Worker | integer_rela '<' integer_shift { $$ = $1 < $3; }
496*cd60bc56SAndroid Build Coastguard Worker | integer_rela '>' integer_shift { $$ = $1 > $3; }
497*cd60bc56SAndroid Build Coastguard Worker | integer_rela DT_LE integer_shift { $$ = $1 <= $3; }
498*cd60bc56SAndroid Build Coastguard Worker | integer_rela DT_GE integer_shift { $$ = $1 >= $3; }
499*cd60bc56SAndroid Build Coastguard Worker ;
500*cd60bc56SAndroid Build Coastguard Worker
501*cd60bc56SAndroid Build Coastguard Worker integer_shift:
502*cd60bc56SAndroid Build Coastguard Worker integer_shift DT_LSHIFT integer_add { $$ = ($3 < 64) ? ($1 << $3) : 0; }
503*cd60bc56SAndroid Build Coastguard Worker | integer_shift DT_RSHIFT integer_add { $$ = ($3 < 64) ? ($1 >> $3) : 0; }
504*cd60bc56SAndroid Build Coastguard Worker | integer_add
505*cd60bc56SAndroid Build Coastguard Worker ;
506*cd60bc56SAndroid Build Coastguard Worker
507*cd60bc56SAndroid Build Coastguard Worker integer_add:
508*cd60bc56SAndroid Build Coastguard Worker integer_add '+' integer_mul { $$ = $1 + $3; }
509*cd60bc56SAndroid Build Coastguard Worker | integer_add '-' integer_mul { $$ = $1 - $3; }
510*cd60bc56SAndroid Build Coastguard Worker | integer_mul
511*cd60bc56SAndroid Build Coastguard Worker ;
512*cd60bc56SAndroid Build Coastguard Worker
513*cd60bc56SAndroid Build Coastguard Worker integer_mul:
514*cd60bc56SAndroid Build Coastguard Worker integer_mul '*' integer_unary { $$ = $1 * $3; }
515*cd60bc56SAndroid Build Coastguard Worker | integer_mul '/' integer_unary
516*cd60bc56SAndroid Build Coastguard Worker {
517*cd60bc56SAndroid Build Coastguard Worker if ($3 != 0) {
518*cd60bc56SAndroid Build Coastguard Worker $$ = $1 / $3;
519*cd60bc56SAndroid Build Coastguard Worker } else {
520*cd60bc56SAndroid Build Coastguard Worker ERROR(&@$, "Division by zero");
521*cd60bc56SAndroid Build Coastguard Worker $$ = 0;
522*cd60bc56SAndroid Build Coastguard Worker }
523*cd60bc56SAndroid Build Coastguard Worker }
524*cd60bc56SAndroid Build Coastguard Worker | integer_mul '%' integer_unary
525*cd60bc56SAndroid Build Coastguard Worker {
526*cd60bc56SAndroid Build Coastguard Worker if ($3 != 0) {
527*cd60bc56SAndroid Build Coastguard Worker $$ = $1 % $3;
528*cd60bc56SAndroid Build Coastguard Worker } else {
529*cd60bc56SAndroid Build Coastguard Worker ERROR(&@$, "Division by zero");
530*cd60bc56SAndroid Build Coastguard Worker $$ = 0;
531*cd60bc56SAndroid Build Coastguard Worker }
532*cd60bc56SAndroid Build Coastguard Worker }
533*cd60bc56SAndroid Build Coastguard Worker | integer_unary
534*cd60bc56SAndroid Build Coastguard Worker ;
535*cd60bc56SAndroid Build Coastguard Worker
536*cd60bc56SAndroid Build Coastguard Worker integer_unary:
537*cd60bc56SAndroid Build Coastguard Worker integer_prim
538*cd60bc56SAndroid Build Coastguard Worker | '-' integer_unary { $$ = -$2; }
539*cd60bc56SAndroid Build Coastguard Worker | '~' integer_unary { $$ = ~$2; }
540*cd60bc56SAndroid Build Coastguard Worker | '!' integer_unary { $$ = !$2; }
541*cd60bc56SAndroid Build Coastguard Worker ;
542*cd60bc56SAndroid Build Coastguard Worker
543*cd60bc56SAndroid Build Coastguard Worker bytestring:
544*cd60bc56SAndroid Build Coastguard Worker /* empty */
545*cd60bc56SAndroid Build Coastguard Worker {
546*cd60bc56SAndroid Build Coastguard Worker $$ = data_add_marker(empty_data, TYPE_UINT8, NULL);
547*cd60bc56SAndroid Build Coastguard Worker }
548*cd60bc56SAndroid Build Coastguard Worker | bytestring DT_BYTE
549*cd60bc56SAndroid Build Coastguard Worker {
550*cd60bc56SAndroid Build Coastguard Worker $$ = data_append_byte($1, $2);
551*cd60bc56SAndroid Build Coastguard Worker }
552*cd60bc56SAndroid Build Coastguard Worker | bytestring DT_LABEL
553*cd60bc56SAndroid Build Coastguard Worker {
554*cd60bc56SAndroid Build Coastguard Worker $$ = data_add_marker($1, LABEL, $2);
555*cd60bc56SAndroid Build Coastguard Worker }
556*cd60bc56SAndroid Build Coastguard Worker ;
557*cd60bc56SAndroid Build Coastguard Worker
558*cd60bc56SAndroid Build Coastguard Worker subnodes:
559*cd60bc56SAndroid Build Coastguard Worker /* empty */
560*cd60bc56SAndroid Build Coastguard Worker {
561*cd60bc56SAndroid Build Coastguard Worker $$ = NULL;
562*cd60bc56SAndroid Build Coastguard Worker }
563*cd60bc56SAndroid Build Coastguard Worker | subnode subnodes
564*cd60bc56SAndroid Build Coastguard Worker {
565*cd60bc56SAndroid Build Coastguard Worker $$ = chain_node($1, $2);
566*cd60bc56SAndroid Build Coastguard Worker }
567*cd60bc56SAndroid Build Coastguard Worker | subnode propdef
568*cd60bc56SAndroid Build Coastguard Worker {
569*cd60bc56SAndroid Build Coastguard Worker ERROR(&@2, "Properties must precede subnodes");
570*cd60bc56SAndroid Build Coastguard Worker YYERROR;
571*cd60bc56SAndroid Build Coastguard Worker }
572*cd60bc56SAndroid Build Coastguard Worker ;
573*cd60bc56SAndroid Build Coastguard Worker
574*cd60bc56SAndroid Build Coastguard Worker subnode:
575*cd60bc56SAndroid Build Coastguard Worker DT_PROPNODENAME nodedef
576*cd60bc56SAndroid Build Coastguard Worker {
577*cd60bc56SAndroid Build Coastguard Worker $$ = name_node($2, $1);
578*cd60bc56SAndroid Build Coastguard Worker }
579*cd60bc56SAndroid Build Coastguard Worker | DT_DEL_NODE DT_PROPNODENAME ';'
580*cd60bc56SAndroid Build Coastguard Worker {
581*cd60bc56SAndroid Build Coastguard Worker $$ = name_node(build_node_delete(&@$), $2);
582*cd60bc56SAndroid Build Coastguard Worker }
583*cd60bc56SAndroid Build Coastguard Worker | DT_OMIT_NO_REF subnode
584*cd60bc56SAndroid Build Coastguard Worker {
585*cd60bc56SAndroid Build Coastguard Worker $$ = omit_node_if_unused($2);
586*cd60bc56SAndroid Build Coastguard Worker }
587*cd60bc56SAndroid Build Coastguard Worker | DT_LABEL subnode
588*cd60bc56SAndroid Build Coastguard Worker {
589*cd60bc56SAndroid Build Coastguard Worker add_label(&$2->labels, $1);
590*cd60bc56SAndroid Build Coastguard Worker $$ = $2;
591*cd60bc56SAndroid Build Coastguard Worker }
592*cd60bc56SAndroid Build Coastguard Worker ;
593*cd60bc56SAndroid Build Coastguard Worker
594*cd60bc56SAndroid Build Coastguard Worker %%
595*cd60bc56SAndroid Build Coastguard Worker
596*cd60bc56SAndroid Build Coastguard Worker void yyerror(char const *s)
597*cd60bc56SAndroid Build Coastguard Worker {
598*cd60bc56SAndroid Build Coastguard Worker ERROR(&yylloc, "%s", s);
599*cd60bc56SAndroid Build Coastguard Worker }
600