• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/scripts/dtc/
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%locations
22
23%{
24#include <stdio.h>
25
26#include "dtc.h"
27#include "srcpos.h"
28
29extern int yylex(void);
30
31extern struct boot_info *the_boot_info;
32extern int treesource_error;
33
34static unsigned long long eval_literal(const char *s, int base, int bits);
35%}
36
37%union {
38	char *propnodename;
39	char *literal;
40	char *labelref;
41	unsigned int cbase;
42	uint8_t byte;
43	struct data data;
44
45	uint64_t addr;
46	cell_t cell;
47	struct property *prop;
48	struct property *proplist;
49	struct node *node;
50	struct node *nodelist;
51	struct reserve_info *re;
52}
53
54%token DT_V1
55%token DT_MEMRESERVE
56%token <propnodename> DT_PROPNODENAME
57%token <literal> DT_LITERAL
58%token <literal> DT_LEGACYLITERAL
59%token <cbase> DT_BASE
60%token <byte> DT_BYTE
61%token <data> DT_STRING
62%token <labelref> DT_LABEL
63%token <labelref> DT_REF
64%token DT_INCBIN
65
66%type <data> propdata
67%type <data> propdataprefix
68%type <re> memreserve
69%type <re> memreserves
70%type <re> v0_memreserve
71%type <re> v0_memreserves
72%type <addr> addr
73%type <data> celllist
74%type <cbase> cellbase
75%type <cell> cellval
76%type <data> bytestring
77%type <prop> propdef
78%type <proplist> proplist
79
80%type <node> devicetree
81%type <node> nodedef
82%type <node> subnode
83%type <nodelist> subnodes
84%type <labelref> label
85
86%%
87
88sourcefile:
89	  DT_V1 ';' memreserves devicetree
90		{
91			the_boot_info = build_boot_info($3, $4, 0);
92		}
93	| v0_memreserves devicetree
94		{
95			the_boot_info = build_boot_info($1, $2, 0);
96		}
97	;
98
99memreserves:
100	  /* empty */
101		{
102			$$ = NULL;
103		}
104	| memreserve memreserves
105		{
106			$$ = chain_reserve_entry($1, $2);
107		}
108	;
109
110memreserve:
111	  label DT_MEMRESERVE addr addr ';'
112		{
113			$$ = build_reserve_entry($3, $4, $1);
114		}
115	;
116
117v0_memreserves:
118	  /* empty */
119		{
120			$$ = NULL;
121		}
122	| v0_memreserve v0_memreserves
123		{
124			$$ = chain_reserve_entry($1, $2);
125		};
126	;
127
128v0_memreserve:
129	  memreserve
130		{
131			$$ = $1;
132		}
133	| label DT_MEMRESERVE addr '-' addr ';'
134		{
135			$$ = build_reserve_entry($3, $5 - $3 + 1, $1);
136		}
137	;
138
139addr:
140	  DT_LITERAL
141		{
142			$$ = eval_literal($1, 0, 64);
143		}
144	| DT_LEGACYLITERAL
145		{
146			$$ = eval_literal($1, 16, 64);
147		}
148	  ;
149
150devicetree:
151	  '/' nodedef
152		{
153			$$ = name_node($2, "", NULL);
154		}
155	;
156
157nodedef:
158	  '{' proplist subnodes '}' ';'
159		{
160			$$ = build_node($2, $3);
161		}
162	;
163
164proplist:
165	  /* empty */
166		{
167			$$ = NULL;
168		}
169	| proplist propdef
170		{
171			$$ = chain_property($2, $1);
172		}
173	;
174
175propdef:
176	  label DT_PROPNODENAME '=' propdata ';'
177		{
178			$$ = build_property($2, $4, $1);
179		}
180	| label DT_PROPNODENAME ';'
181		{
182			$$ = build_property($2, empty_data, $1);
183		}
184	;
185
186propdata:
187	  propdataprefix DT_STRING
188		{
189			$$ = data_merge($1, $2);
190		}
191	| propdataprefix '<' celllist '>'
192		{
193			$$ = data_merge($1, $3);
194		}
195	| propdataprefix '[' bytestring ']'
196		{
197			$$ = data_merge($1, $3);
198		}
199	| propdataprefix DT_REF
200		{
201			$$ = data_add_marker($1, REF_PATH, $2);
202		}
203	| propdataprefix DT_INCBIN '(' DT_STRING ',' addr ',' addr ')'
204		{
205			struct search_path path = { srcpos_file->dir, NULL, NULL };
206			struct dtc_file *file = dtc_open_file($4.val, &path);
207			struct data d = empty_data;
208
209			if ($6 != 0)
210				if (fseek(file->file, $6, SEEK_SET) != 0)
211					yyerrorf("Couldn't seek to offset %llu in \"%s\": %s",
212						 (unsigned long long)$6,
213						 $4.val, strerror(errno));
214
215			d = data_copy_file(file->file, $8);
216
217			$$ = data_merge($1, d);
218			dtc_close_file(file);
219		}
220	| propdataprefix DT_INCBIN '(' DT_STRING ')'
221		{
222			struct search_path path = { srcpos_file->dir, NULL, NULL };
223			struct dtc_file *file = dtc_open_file($4.val, &path);
224			struct data d = empty_data;
225
226			d = data_copy_file(file->file, -1);
227
228			$$ = data_merge($1, d);
229			dtc_close_file(file);
230		}
231	| propdata DT_LABEL
232		{
233			$$ = data_add_marker($1, LABEL, $2);
234		}
235	;
236
237propdataprefix:
238	  /* empty */
239		{
240			$$ = empty_data;
241		}
242	| propdata ','
243		{
244			$$ = $1;
245		}
246	| propdataprefix DT_LABEL
247		{
248			$$ = data_add_marker($1, LABEL, $2);
249		}
250	;
251
252celllist:
253	  /* empty */
254		{
255			$$ = empty_data;
256		}
257	| celllist cellval
258		{
259			$$ = data_append_cell($1, $2);
260		}
261	| celllist DT_REF
262		{
263			$$ = data_append_cell(data_add_marker($1, REF_PHANDLE,
264							      $2), -1);
265		}
266	| celllist DT_LABEL
267		{
268			$$ = data_add_marker($1, LABEL, $2);
269		}
270	;
271
272cellbase:
273	  /* empty */
274		{
275			$$ = 16;
276		}
277	| DT_BASE
278	;
279
280cellval:
281	  DT_LITERAL
282		{
283			$$ = eval_literal($1, 0, 32);
284		}
285	| cellbase DT_LEGACYLITERAL
286		{
287			$$ = eval_literal($2, $1, 32);
288		}
289	;
290
291bytestring:
292	  /* empty */
293		{
294			$$ = empty_data;
295		}
296	| bytestring DT_BYTE
297		{
298			$$ = data_append_byte($1, $2);
299		}
300	| bytestring DT_LABEL
301		{
302			$$ = data_add_marker($1, LABEL, $2);
303		}
304	;
305
306subnodes:
307	  /* empty */
308		{
309			$$ = NULL;
310		}
311	|  subnode subnodes
312		{
313			$$ = chain_node($1, $2);
314		}
315	| subnode propdef
316		{
317			yyerror("syntax error: properties must precede subnodes");
318			YYERROR;
319		}
320	;
321
322subnode:
323	  label DT_PROPNODENAME nodedef
324		{
325			$$ = name_node($3, $2, $1);
326		}
327	;
328
329label:
330	  /* empty */
331		{
332			$$ = NULL;
333		}
334	| DT_LABEL
335		{
336			$$ = $1;
337		}
338	;
339
340%%
341
342void yyerrorf(char const *s, ...)
343{
344	const char *fname = srcpos_file ? srcpos_file->name : "<no-file>";
345	va_list va;
346	va_start(va, s);
347
348	if (strcmp(fname, "-") == 0)
349		fname = "stdin";
350
351	fprintf(stderr, "%s:%d ", fname, yylloc.first_line);
352	vfprintf(stderr, s, va);
353	fprintf(stderr, "\n");
354
355	treesource_error = 1;
356	va_end(va);
357}
358
359void yyerror (char const *s)
360{
361	yyerrorf("%s", s);
362}
363
364static unsigned long long eval_literal(const char *s, int base, int bits)
365{
366	unsigned long long val;
367	char *e;
368
369	errno = 0;
370	val = strtoull(s, &e, base);
371	if (*e)
372		yyerror("bad characters in literal");
373	else if ((errno == ERANGE)
374		 || ((bits < 64) && (val >= (1ULL << bits))))
375		yyerror("literal out of range");
376	else if (errno != 0)
377		yyerror("bad literal");
378	return val;
379}
380