Linux Audio

Check our new training course

Loading...
v3.1
  1/*
  2 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005.
  3 *
  4 *
  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.
  9 *
 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.
 14 *
 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
 18 *                                                                   USA
 19 */
 20
 21%{
 22#include <stdio.h>
 23
 24#include "dtc.h"
 25#include "srcpos.h"
 26
 27YYLTYPE yylloc;
 28
 29extern int yylex(void);
 30extern void print_error(char const *fmt, ...);
 31extern void yyerror(char const *s);
 32
 33extern struct boot_info *the_boot_info;
 34extern int treesource_error;
 35
 36static unsigned long long eval_literal(const char *s, int base, int bits);
 37%}
 38
 39%union {
 40	char *propnodename;
 41	char *literal;
 42	char *labelref;
 43	unsigned int cbase;
 44	uint8_t byte;
 45	struct data data;
 46
 47	uint64_t addr;
 48	cell_t cell;
 49	struct property *prop;
 50	struct property *proplist;
 51	struct node *node;
 52	struct node *nodelist;
 53	struct reserve_info *re;
 54}
 55
 56%token DT_V1
 57%token DT_MEMRESERVE
 58%token <propnodename> DT_PROPNODENAME
 59%token <literal> DT_LITERAL
 60%token <cbase> DT_BASE
 61%token <byte> DT_BYTE
 62%token <data> DT_STRING
 63%token <labelref> DT_LABEL
 64%token <labelref> DT_REF
 65%token DT_INCBIN
 66
 67%type <data> propdata
 68%type <data> propdataprefix
 69%type <re> memreserve
 70%type <re> memreserves
 71%type <addr> addr
 72%type <data> celllist
 73%type <cell> cellval
 74%type <data> bytestring
 75%type <prop> propdef
 76%type <proplist> proplist
 77
 78%type <node> devicetree
 79%type <node> nodedef
 80%type <node> subnode
 81%type <nodelist> subnodes
 82
 83%%
 84
 85sourcefile:
 86	  DT_V1 ';' memreserves devicetree
 87		{
 88			the_boot_info = build_boot_info($3, $4,
 89							guess_boot_cpuid($4));
 90		}
 91	;
 92
 93memreserves:
 94	  /* empty */
 95		{
 96			$$ = NULL;
 97		}
 98	| memreserve memreserves
 99		{
100			$$ = chain_reserve_entry($1, $2);
101		}
102	;
103
104memreserve:
105	  DT_MEMRESERVE addr addr ';'
106		{
107			$$ = build_reserve_entry($2, $3);
108		}
109	| DT_LABEL memreserve
110		{
111			add_label(&$2->labels, $1);
112			$$ = $2;
113		}
114	;
115
116addr:
117	  DT_LITERAL
118		{
119			$$ = eval_literal($1, 0, 64);
120		}
121	  ;
122
123devicetree:
124	  '/' nodedef
125		{
126			$$ = name_node($2, "");
127		}
128	| devicetree '/' nodedef
129		{
130			$$ = merge_nodes($1, $3);
131		}
132	| devicetree DT_REF nodedef
133		{
134			struct node *target = get_node_by_ref($1, $2);
135
136			if (target)
137				merge_nodes(target, $3);
138			else
139				print_error("label or path, '%s', not found", $2);
140			$$ = $1;
141		}
142	;
143
144nodedef:
145	  '{' proplist subnodes '}' ';'
146		{
147			$$ = build_node($2, $3);
148		}
149	;
150
151proplist:
152	  /* empty */
153		{
154			$$ = NULL;
155		}
156	| proplist propdef
157		{
158			$$ = chain_property($2, $1);
159		}
160	;
161
162propdef:
163	  DT_PROPNODENAME '=' propdata ';'
164		{
165			$$ = build_property($1, $3);
166		}
167	| DT_PROPNODENAME ';'
168		{
169			$$ = build_property($1, empty_data);
170		}
171	| DT_LABEL propdef
172		{
173			add_label(&$2->labels, $1);
174			$$ = $2;
175		}
176	;
177
178propdata:
179	  propdataprefix DT_STRING
180		{
181			$$ = data_merge($1, $2);
182		}
183	| propdataprefix '<' celllist '>'
184		{
185			$$ = data_merge($1, $3);
186		}
187	| propdataprefix '[' bytestring ']'
188		{
189			$$ = data_merge($1, $3);
190		}
191	| propdataprefix DT_REF
192		{
193			$$ = data_add_marker($1, REF_PATH, $2);
194		}
195	| propdataprefix DT_INCBIN '(' DT_STRING ',' addr ',' addr ')'
196		{
197			FILE *f = srcfile_relative_open($4.val, NULL);
198			struct data d;
199
200			if ($6 != 0)
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,
204						     $4.val,
205						     strerror(errno));
206
207			d = data_copy_file(f, $8);
208
209			$$ = data_merge($1, d);
210			fclose(f);
211		}
212	| propdataprefix DT_INCBIN '(' DT_STRING ')'
213		{
214			FILE *f = srcfile_relative_open($4.val, NULL);
215			struct data d = empty_data;
216
217			d = data_copy_file(f, -1);
218
219			$$ = data_merge($1, d);
220			fclose(f);
221		}
222	| propdata DT_LABEL
223		{
224			$$ = data_add_marker($1, LABEL, $2);
225		}
226	;
227
228propdataprefix:
229	  /* empty */
230		{
231			$$ = empty_data;
232		}
233	| propdata ','
234		{
235			$$ = $1;
236		}
237	| propdataprefix DT_LABEL
238		{
239			$$ = data_add_marker($1, LABEL, $2);
240		}
241	;
242
243celllist:
244	  /* empty */
245		{
246			$$ = empty_data;
247		}
248	| celllist cellval
249		{
250			$$ = data_append_cell($1, $2);
251		}
252	| celllist DT_REF
253		{
254			$$ = data_append_cell(data_add_marker($1, REF_PHANDLE,
255							      $2), -1);
256		}
257	| celllist DT_LABEL
258		{
259			$$ = data_add_marker($1, LABEL, $2);
260		}
261	;
262
263cellval:
264	  DT_LITERAL
265		{
266			$$ = eval_literal($1, 0, 32);
267		}
268	;
269
270bytestring:
271	  /* empty */
272		{
273			$$ = empty_data;
274		}
275	| bytestring DT_BYTE
276		{
277			$$ = data_append_byte($1, $2);
278		}
279	| bytestring DT_LABEL
280		{
281			$$ = data_add_marker($1, LABEL, $2);
282		}
283	;
284
285subnodes:
286	  /* empty */
287		{
288			$$ = NULL;
289		}
290	| subnode subnodes
291		{
292			$$ = chain_node($1, $2);
293		}
294	| subnode propdef
295		{
296			print_error("syntax error: properties must precede subnodes");
297			YYERROR;
298		}
299	;
300
301subnode:
302	  DT_PROPNODENAME nodedef
303		{
304			$$ = name_node($2, $1);
305		}
306	| DT_LABEL subnode
307		{
308			add_label(&$2->labels, $1);
309			$$ = $2;
310		}
311	;
312
313%%
314
315void print_error(char const *fmt, ...)
316{
317	va_list va;
318
319	va_start(va, fmt);
320	srcpos_verror(&yylloc, fmt, va);
321	va_end(va);
322
323	treesource_error = 1;
324}
325
326void yyerror(char const *s) {
327	print_error("%s", s);
328}
329
330static unsigned long long eval_literal(const char *s, int base, int bits)
331{
332	unsigned long long val;
333	char *e;
334
335	errno = 0;
336	val = strtoull(s, &e, base);
337	if (*e)
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");
342	else if (errno != 0)
343		print_error("bad literal");
344	return val;
345}
v3.5.6
  1/*
  2 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005.
  3 *
  4 *
  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.
  9 *
 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.
 14 *
 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
 18 *                                                                   USA
 19 */
 20
 21%{
 22#include <stdio.h>
 23
 24#include "dtc.h"
 25#include "srcpos.h"
 26
 27YYLTYPE yylloc;
 28
 29extern int yylex(void);
 30extern void print_error(char const *fmt, ...);
 31extern void yyerror(char const *s);
 32
 33extern struct boot_info *the_boot_info;
 34extern int treesource_error;
 35
 36static unsigned long long eval_literal(const char *s, int base, int bits);
 37%}
 38
 39%union {
 40	char *propnodename;
 41	char *literal;
 42	char *labelref;
 43	unsigned int cbase;
 44	uint8_t byte;
 45	struct data data;
 46
 47	uint64_t addr;
 48	cell_t cell;
 49	struct property *prop;
 50	struct property *proplist;
 51	struct node *node;
 52	struct node *nodelist;
 53	struct reserve_info *re;
 54}
 55
 56%token DT_V1
 57%token DT_MEMRESERVE
 58%token <propnodename> DT_PROPNODENAME
 59%token <literal> DT_LITERAL
 60%token <cbase> DT_BASE
 61%token <byte> DT_BYTE
 62%token <data> DT_STRING
 63%token <labelref> DT_LABEL
 64%token <labelref> DT_REF
 65%token DT_INCBIN
 66
 67%type <data> propdata
 68%type <data> propdataprefix
 69%type <re> memreserve
 70%type <re> memreserves
 71%type <addr> addr
 72%type <data> celllist
 73%type <cell> cellval
 74%type <data> bytestring
 75%type <prop> propdef
 76%type <proplist> proplist
 77
 78%type <node> devicetree
 79%type <node> nodedef
 80%type <node> subnode
 81%type <nodelist> subnodes
 82
 83%%
 84
 85sourcefile:
 86	  DT_V1 ';' memreserves devicetree
 87		{
 88			the_boot_info = build_boot_info($3, $4,
 89							guess_boot_cpuid($4));
 90		}
 91	;
 92
 93memreserves:
 94	  /* empty */
 95		{
 96			$$ = NULL;
 97		}
 98	| memreserve memreserves
 99		{
100			$$ = chain_reserve_entry($1, $2);
101		}
102	;
103
104memreserve:
105	  DT_MEMRESERVE addr addr ';'
106		{
107			$$ = build_reserve_entry($2, $3);
108		}
109	| DT_LABEL memreserve
110		{
111			add_label(&$2->labels, $1);
112			$$ = $2;
113		}
114	;
115
116addr:
117	  DT_LITERAL
118		{
119			$$ = eval_literal($1, 0, 64);
120		}
121	  ;
122
123devicetree:
124	  '/' nodedef
125		{
126			$$ = name_node($2, "");
127		}
128	| devicetree '/' nodedef
129		{
130			$$ = merge_nodes($1, $3);
131		}
132	| devicetree DT_REF nodedef
133		{
134			struct node *target = get_node_by_ref($1, $2);
135
136			if (target)
137				merge_nodes(target, $3);
138			else
139				print_error("label or path, '%s', not found", $2);
140			$$ = $1;
141		}
142	;
143
144nodedef:
145	  '{' proplist subnodes '}' ';'
146		{
147			$$ = build_node($2, $3);
148		}
149	;
150
151proplist:
152	  /* empty */
153		{
154			$$ = NULL;
155		}
156	| proplist propdef
157		{
158			$$ = chain_property($2, $1);
159		}
160	;
161
162propdef:
163	  DT_PROPNODENAME '=' propdata ';'
164		{
165			$$ = build_property($1, $3);
166		}
167	| DT_PROPNODENAME ';'
168		{
169			$$ = build_property($1, empty_data);
170		}
171	| DT_LABEL propdef
172		{
173			add_label(&$2->labels, $1);
174			$$ = $2;
175		}
176	;
177
178propdata:
179	  propdataprefix DT_STRING
180		{
181			$$ = data_merge($1, $2);
182		}
183	| propdataprefix '<' celllist '>'
184		{
185			$$ = data_merge($1, $3);
186		}
187	| propdataprefix '[' bytestring ']'
188		{
189			$$ = data_merge($1, $3);
190		}
191	| propdataprefix DT_REF
192		{
193			$$ = data_add_marker($1, REF_PATH, $2);
194		}
195	| propdataprefix DT_INCBIN '(' DT_STRING ',' addr ',' addr ')'
196		{
197			FILE *f = srcfile_relative_open($4.val, NULL);
198			struct data d;
199
200			if ($6 != 0)
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,
204						     $4.val,
205						     strerror(errno));
206
207			d = data_copy_file(f, $8);
208
209			$$ = data_merge($1, d);
210			fclose(f);
211		}
212	| propdataprefix DT_INCBIN '(' DT_STRING ')'
213		{
214			FILE *f = srcfile_relative_open($4.val, NULL);
215			struct data d = empty_data;
216
217			d = data_copy_file(f, -1);
218
219			$$ = data_merge($1, d);
220			fclose(f);
221		}
222	| propdata DT_LABEL
223		{
224			$$ = data_add_marker($1, LABEL, $2);
225		}
226	;
227
228propdataprefix:
229	  /* empty */
230		{
231			$$ = empty_data;
232		}
233	| propdata ','
234		{
235			$$ = $1;
236		}
237	| propdataprefix DT_LABEL
238		{
239			$$ = data_add_marker($1, LABEL, $2);
240		}
241	;
242
243celllist:
244	  /* empty */
245		{
246			$$ = empty_data;
247		}
248	| celllist cellval
249		{
250			$$ = data_append_cell($1, $2);
251		}
252	| celllist DT_REF
253		{
254			$$ = data_append_cell(data_add_marker($1, REF_PHANDLE,
255							      $2), -1);
256		}
257	| celllist DT_LABEL
258		{
259			$$ = data_add_marker($1, LABEL, $2);
260		}
261	;
262
263cellval:
264	  DT_LITERAL
265		{
266			$$ = eval_literal($1, 0, 32);
267		}
268	;
269
270bytestring:
271	  /* empty */
272		{
273			$$ = empty_data;
274		}
275	| bytestring DT_BYTE
276		{
277			$$ = data_append_byte($1, $2);
278		}
279	| bytestring DT_LABEL
280		{
281			$$ = data_add_marker($1, LABEL, $2);
282		}
283	;
284
285subnodes:
286	  /* empty */
287		{
288			$$ = NULL;
289		}
290	| subnode subnodes
291		{
292			$$ = chain_node($1, $2);
293		}
294	| subnode propdef
295		{
296			print_error("syntax error: properties must precede subnodes");
297			YYERROR;
298		}
299	;
300
301subnode:
302	  DT_PROPNODENAME nodedef
303		{
304			$$ = name_node($2, $1);
305		}
306	| DT_LABEL subnode
307		{
308			add_label(&$2->labels, $1);
309			$$ = $2;
310		}
311	;
312
313%%
314
315void print_error(char const *fmt, ...)
316{
317	va_list va;
318
319	va_start(va, fmt);
320	srcpos_verror(&yylloc, fmt, va);
321	va_end(va);
322
323	treesource_error = 1;
324}
325
326void yyerror(char const *s) {
327	print_error("%s", s);
328}
329
330static unsigned long long eval_literal(const char *s, int base, int bits)
331{
332	unsigned long long val;
333	char *e;
334
335	errno = 0;
336	val = strtoull(s, &e, base);
337	if (*e)
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");
342	else if (errno != 0)
343		print_error("bad literal");
344	return val;
345}