Blame view

scripts/dtc/dtc-parser.y 5.83 KB
a4da2e3ec   David Gibson   [POWERPC] Merge d...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  /*
   * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005.
   *
   *
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU General Public License as
   * published by the Free Software Foundation; either version 2 of the
   * License, or (at your option) any later version.
   *
   *  This program is distributed in the hope that it will be useful,
   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   *  General Public License for more details.
   *
   *  You should have received a copy of the GNU General Public License
   *  along with this program; if not, write to the Free Software
   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
   *                                                                   USA
   */
a4da2e3ec   David Gibson   [POWERPC] Merge d...
20
  %{
ed95d7450   David Gibson   powerpc: Update i...
21
  #include <stdio.h>
a4da2e3ec   David Gibson   [POWERPC] Merge d...
22
23
  #include "dtc.h"
  #include "srcpos.h"
658f29a51   John Bonesio   of/flattree: Upda...
24
  YYLTYPE yylloc;
ed95d7450   David Gibson   powerpc: Update i...
25
  extern int yylex(void);
658f29a51   John Bonesio   of/flattree: Upda...
26
27
  extern void print_error(char const *fmt, ...);
  extern void yyerror(char const *s);
a4da2e3ec   David Gibson   [POWERPC] Merge d...
28
29
  
  extern struct boot_info *the_boot_info;
ed95d7450   David Gibson   powerpc: Update i...
30
  extern int treesource_error;
a4da2e3ec   David Gibson   [POWERPC] Merge d...
31

ed95d7450   David Gibson   powerpc: Update i...
32
  static unsigned long long eval_literal(const char *s, int base, int bits);
a4da2e3ec   David Gibson   [POWERPC] Merge d...
33
34
35
36
37
38
39
  %}
  
  %union {
  	char *propnodename;
  	char *literal;
  	char *labelref;
  	unsigned int cbase;
ed95d7450   David Gibson   powerpc: Update i...
40
  	uint8_t byte;
a4da2e3ec   David Gibson   [POWERPC] Merge d...
41
  	struct data data;
ed95d7450   David Gibson   powerpc: Update i...
42
  	uint64_t addr;
a4da2e3ec   David Gibson   [POWERPC] Merge d...
43
44
45
46
47
48
49
50
51
52
53
54
  	cell_t cell;
  	struct property *prop;
  	struct property *proplist;
  	struct node *node;
  	struct node *nodelist;
  	struct reserve_info *re;
  }
  
  %token DT_V1
  %token DT_MEMRESERVE
  %token <propnodename> DT_PROPNODENAME
  %token <literal> DT_LITERAL
a4da2e3ec   David Gibson   [POWERPC] Merge d...
55
56
57
58
59
  %token <cbase> DT_BASE
  %token <byte> DT_BYTE
  %token <data> DT_STRING
  %token <labelref> DT_LABEL
  %token <labelref> DT_REF
ed95d7450   David Gibson   powerpc: Update i...
60
  %token DT_INCBIN
a4da2e3ec   David Gibson   [POWERPC] Merge d...
61
62
63
64
65
  
  %type <data> propdata
  %type <data> propdataprefix
  %type <re> memreserve
  %type <re> memreserves
a4da2e3ec   David Gibson   [POWERPC] Merge d...
66
67
  %type <addr> addr
  %type <data> celllist
a4da2e3ec   David Gibson   [POWERPC] Merge d...
68
69
70
71
72
73
74
75
76
  %type <cell> cellval
  %type <data> bytestring
  %type <prop> propdef
  %type <proplist> proplist
  
  %type <node> devicetree
  %type <node> nodedef
  %type <node> subnode
  %type <nodelist> subnodes
a4da2e3ec   David Gibson   [POWERPC] Merge d...
77
78
79
80
81
82
  
  %%
  
  sourcefile:
  	  DT_V1 ';' memreserves devicetree
  		{
658f29a51   John Bonesio   of/flattree: Upda...
83
84
  			the_boot_info = build_boot_info($3, $4,
  							guess_boot_cpuid($4));
a4da2e3ec   David Gibson   [POWERPC] Merge d...
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
  		}
  	;
  
  memreserves:
  	  /* empty */
  		{
  			$$ = NULL;
  		}
  	| memreserve memreserves
  		{
  			$$ = chain_reserve_entry($1, $2);
  		}
  	;
  
  memreserve:
658f29a51   John Bonesio   of/flattree: Upda...
100
  	  DT_MEMRESERVE addr addr ';'
a4da2e3ec   David Gibson   [POWERPC] Merge d...
101
  		{
658f29a51   John Bonesio   of/flattree: Upda...
102
  			$$ = build_reserve_entry($2, $3);
a4da2e3ec   David Gibson   [POWERPC] Merge d...
103
  		}
658f29a51   John Bonesio   of/flattree: Upda...
104
  	| DT_LABEL memreserve
a4da2e3ec   David Gibson   [POWERPC] Merge d...
105
  		{
658f29a51   John Bonesio   of/flattree: Upda...
106
107
  			add_label(&$2->labels, $1);
  			$$ = $2;
a4da2e3ec   David Gibson   [POWERPC] Merge d...
108
109
110
111
112
113
114
115
  		}
  	;
  
  addr:
  	  DT_LITERAL
  		{
  			$$ = eval_literal($1, 0, 64);
  		}
a4da2e3ec   David Gibson   [POWERPC] Merge d...
116
117
118
119
120
  	  ;
  
  devicetree:
  	  '/' nodedef
  		{
658f29a51   John Bonesio   of/flattree: Upda...
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
  			$$ = name_node($2, "");
  		}
  	| devicetree '/' nodedef
  		{
  			$$ = merge_nodes($1, $3);
  		}
  	| devicetree DT_REF nodedef
  		{
  			struct node *target = get_node_by_ref($1, $2);
  
  			if (target)
  				merge_nodes(target, $3);
  			else
  				print_error("label or path, '%s', not found", $2);
  			$$ = $1;
a4da2e3ec   David Gibson   [POWERPC] Merge d...
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
  		}
  	;
  
  nodedef:
  	  '{' proplist subnodes '}' ';'
  		{
  			$$ = build_node($2, $3);
  		}
  	;
  
  proplist:
  	  /* empty */
  		{
  			$$ = NULL;
  		}
  	| proplist propdef
  		{
  			$$ = chain_property($2, $1);
  		}
  	;
  
  propdef:
658f29a51   John Bonesio   of/flattree: Upda...
158
159
160
161
162
  	  DT_PROPNODENAME '=' propdata ';'
  		{
  			$$ = build_property($1, $3);
  		}
  	| DT_PROPNODENAME ';'
a4da2e3ec   David Gibson   [POWERPC] Merge d...
163
  		{
658f29a51   John Bonesio   of/flattree: Upda...
164
  			$$ = build_property($1, empty_data);
a4da2e3ec   David Gibson   [POWERPC] Merge d...
165
  		}
658f29a51   John Bonesio   of/flattree: Upda...
166
  	| DT_LABEL propdef
a4da2e3ec   David Gibson   [POWERPC] Merge d...
167
  		{
658f29a51   John Bonesio   of/flattree: Upda...
168
169
  			add_label(&$2->labels, $1);
  			$$ = $2;
a4da2e3ec   David Gibson   [POWERPC] Merge d...
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
  		}
  	;
  
  propdata:
  	  propdataprefix DT_STRING
  		{
  			$$ = data_merge($1, $2);
  		}
  	| propdataprefix '<' celllist '>'
  		{
  			$$ = data_merge($1, $3);
  		}
  	| propdataprefix '[' bytestring ']'
  		{
  			$$ = data_merge($1, $3);
  		}
  	| propdataprefix DT_REF
  		{
  			$$ = data_add_marker($1, REF_PATH, $2);
  		}
ed95d7450   David Gibson   powerpc: Update i...
190
191
  	| propdataprefix DT_INCBIN '(' DT_STRING ',' addr ',' addr ')'
  		{
658f29a51   John Bonesio   of/flattree: Upda...
192
193
  			FILE *f = srcfile_relative_open($4.val, NULL);
  			struct data d;
ed95d7450   David Gibson   powerpc: Update i...
194
195
  
  			if ($6 != 0)
658f29a51   John Bonesio   of/flattree: Upda...
196
197
198
199
200
  				if (fseek(f, $6, SEEK_SET) != 0)
  					print_error("Couldn't seek to offset %llu in \"%s\": %s",
  						     (unsigned long long)$6,
  						     $4.val,
  						     strerror(errno));
ed95d7450   David Gibson   powerpc: Update i...
201

658f29a51   John Bonesio   of/flattree: Upda...
202
  			d = data_copy_file(f, $8);
ed95d7450   David Gibson   powerpc: Update i...
203
204
  
  			$$ = data_merge($1, d);
658f29a51   John Bonesio   of/flattree: Upda...
205
  			fclose(f);
ed95d7450   David Gibson   powerpc: Update i...
206
207
208
  		}
  	| propdataprefix DT_INCBIN '(' DT_STRING ')'
  		{
658f29a51   John Bonesio   of/flattree: Upda...
209
  			FILE *f = srcfile_relative_open($4.val, NULL);
ed95d7450   David Gibson   powerpc: Update i...
210
  			struct data d = empty_data;
658f29a51   John Bonesio   of/flattree: Upda...
211
  			d = data_copy_file(f, -1);
ed95d7450   David Gibson   powerpc: Update i...
212
213
  
  			$$ = data_merge($1, d);
658f29a51   John Bonesio   of/flattree: Upda...
214
  			fclose(f);
ed95d7450   David Gibson   powerpc: Update i...
215
  		}
a4da2e3ec   David Gibson   [POWERPC] Merge d...
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
  	| propdata DT_LABEL
  		{
  			$$ = data_add_marker($1, LABEL, $2);
  		}
  	;
  
  propdataprefix:
  	  /* empty */
  		{
  			$$ = empty_data;
  		}
  	| propdata ','
  		{
  			$$ = $1;
  		}
  	| propdataprefix DT_LABEL
  		{
  			$$ = data_add_marker($1, LABEL, $2);
  		}
  	;
  
  celllist:
  	  /* empty */
  		{
  			$$ = empty_data;
  		}
  	| celllist cellval
  		{
  			$$ = data_append_cell($1, $2);
  		}
  	| celllist DT_REF
  		{
  			$$ = data_append_cell(data_add_marker($1, REF_PHANDLE,
  							      $2), -1);
  		}
  	| celllist DT_LABEL
  		{
  			$$ = data_add_marker($1, LABEL, $2);
  		}
  	;
a4da2e3ec   David Gibson   [POWERPC] Merge d...
256
257
258
259
260
  cellval:
  	  DT_LITERAL
  		{
  			$$ = eval_literal($1, 0, 32);
  		}
a4da2e3ec   David Gibson   [POWERPC] Merge d...
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
  	;
  
  bytestring:
  	  /* empty */
  		{
  			$$ = empty_data;
  		}
  	| bytestring DT_BYTE
  		{
  			$$ = data_append_byte($1, $2);
  		}
  	| bytestring DT_LABEL
  		{
  			$$ = data_add_marker($1, LABEL, $2);
  		}
  	;
  
  subnodes:
  	  /* empty */
  		{
  			$$ = NULL;
  		}
658f29a51   John Bonesio   of/flattree: Upda...
283
  	| subnode subnodes
a4da2e3ec   David Gibson   [POWERPC] Merge d...
284
285
286
287
288
  		{
  			$$ = chain_node($1, $2);
  		}
  	| subnode propdef
  		{
658f29a51   John Bonesio   of/flattree: Upda...
289
  			print_error("syntax error: properties must precede subnodes");
a4da2e3ec   David Gibson   [POWERPC] Merge d...
290
291
292
293
294
  			YYERROR;
  		}
  	;
  
  subnode:
658f29a51   John Bonesio   of/flattree: Upda...
295
  	  DT_PROPNODENAME nodedef
a4da2e3ec   David Gibson   [POWERPC] Merge d...
296
  		{
658f29a51   John Bonesio   of/flattree: Upda...
297
  			$$ = name_node($2, $1);
a4da2e3ec   David Gibson   [POWERPC] Merge d...
298
  		}
658f29a51   John Bonesio   of/flattree: Upda...
299
  	| DT_LABEL subnode
a4da2e3ec   David Gibson   [POWERPC] Merge d...
300
  		{
658f29a51   John Bonesio   of/flattree: Upda...
301
302
  			add_label(&$2->labels, $1);
  			$$ = $2;
a4da2e3ec   David Gibson   [POWERPC] Merge d...
303
304
305
306
  		}
  	;
  
  %%
658f29a51   John Bonesio   of/flattree: Upda...
307
  void print_error(char const *fmt, ...)
a4da2e3ec   David Gibson   [POWERPC] Merge d...
308
  {
ed95d7450   David Gibson   powerpc: Update i...
309
  	va_list va;
a4da2e3ec   David Gibson   [POWERPC] Merge d...
310

658f29a51   John Bonesio   of/flattree: Upda...
311
312
313
  	va_start(va, fmt);
  	srcpos_verror(&yylloc, fmt, va);
  	va_end(va);
ed95d7450   David Gibson   powerpc: Update i...
314
315
  
  	treesource_error = 1;
ed95d7450   David Gibson   powerpc: Update i...
316
  }
658f29a51   John Bonesio   of/flattree: Upda...
317
318
  void yyerror(char const *s) {
  	print_error("%s", s);
a4da2e3ec   David Gibson   [POWERPC] Merge d...
319
  }
ed95d7450   David Gibson   powerpc: Update i...
320
  static unsigned long long eval_literal(const char *s, int base, int bits)
a4da2e3ec   David Gibson   [POWERPC] Merge d...
321
322
323
324
325
326
327
  {
  	unsigned long long val;
  	char *e;
  
  	errno = 0;
  	val = strtoull(s, &e, base);
  	if (*e)
658f29a51   John Bonesio   of/flattree: Upda...
328
  		print_error("bad characters in literal");
a4da2e3ec   David Gibson   [POWERPC] Merge d...
329
330
  	else if ((errno == ERANGE)
  		 || ((bits < 64) && (val >= (1ULL << bits))))
658f29a51   John Bonesio   of/flattree: Upda...
331
  		print_error("literal out of range");
a4da2e3ec   David Gibson   [POWERPC] Merge d...
332
  	else if (errno != 0)
658f29a51   John Bonesio   of/flattree: Upda...
333
  		print_error("bad literal");
a4da2e3ec   David Gibson   [POWERPC] Merge d...
334
335
  	return val;
  }