blob: 4ab1df956af48b2fac36f882756e8ff84d7a8e33 [file] [log] [blame]
David Gibsonfc14dad2005-06-08 17:18:34 +10001/*
2 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
3 *
David Gibson63dc9c72007-09-18 11:44:04 +10004 *
David Gibsonfc14dad2005-06-08 17:18:34 +10005 * 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.
David Gibson63dc9c72007-09-18 11:44:04 +100014 *
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
David Gibsonfc14dad2005-06-08 17:18:34 +100019 */
20
David Gibson86dbcbd2005-10-19 16:00:31 +100021%locations
22
David Gibsonfc14dad2005-06-08 17:18:34 +100023%{
24#include "dtc.h"
Jon Loeligere45e6fd2007-03-23 15:18:41 -050025#include "srcpos.h"
David Gibsonfc14dad2005-06-08 17:18:34 +100026
David Gibson6b8e0562008-03-05 11:47:54 +110027extern int yylex(void);
David Gibsonfc14dad2005-06-08 17:18:34 +100028
David Gibsonf0517db2005-07-15 17:14:24 +100029extern struct boot_info *the_boot_info;
Scott Woodad4f54a2008-01-03 17:43:33 -060030extern int treesource_error;
David Gibsonfc14dad2005-06-08 17:18:34 +100031
David Gibson6b8e0562008-03-05 11:47:54 +110032static unsigned long long eval_literal(const char *s, int base, int bits);
David Gibsonfc14dad2005-06-08 17:18:34 +100033%}
34
35%union {
David Gibson9ed27a22007-11-07 11:16:19 +110036 char *propnodename;
37 char *literal;
38 char *labelref;
Jon Loeligeraf0278a2007-02-15 10:59:27 -060039 unsigned int cbase;
David Gibson03a9b9d2005-07-11 16:49:52 +100040 u8 byte;
David Gibsonfc14dad2005-06-08 17:18:34 +100041 struct data data;
David Gibson9ed27a22007-11-07 11:16:19 +110042
43 u64 addr;
44 cell_t cell;
David Gibsonfc14dad2005-06-08 17:18:34 +100045 struct property *prop;
46 struct property *proplist;
47 struct node *node;
48 struct node *nodelist;
David Gibsonf040d952005-10-24 18:18:38 +100049 struct reserve_info *re;
David Gibsonfc14dad2005-06-08 17:18:34 +100050}
51
David Gibson9138db52007-11-07 11:17:17 +110052%token DT_V1
David Gibsonf0517db2005-07-15 17:14:24 +100053%token DT_MEMRESERVE
David Gibson9ed27a22007-11-07 11:16:19 +110054%token <propnodename> DT_PROPNODENAME
55%token <literal> DT_LITERAL
David Gibson9138db52007-11-07 11:17:17 +110056%token <literal> DT_LEGACYLITERAL
Jon Loeligeraf0278a2007-02-15 10:59:27 -060057%token <cbase> DT_BASE
David Gibsonfc14dad2005-06-08 17:18:34 +100058%token <byte> DT_BYTE
59%token <data> DT_STRING
David Gibson9ed27a22007-11-07 11:16:19 +110060%token <labelref> DT_LABEL
61%token <labelref> DT_REF
David Gibsonfc14dad2005-06-08 17:18:34 +100062
63%type <data> propdata
David Gibson32da4752007-02-07 16:37:50 +110064%type <data> propdataprefix
David Gibsonf0517db2005-07-15 17:14:24 +100065%type <re> memreserve
David Gibsonf040d952005-10-24 18:18:38 +100066%type <re> memreserves
David Gibson9138db52007-11-07 11:17:17 +110067%type <re> v0_memreserve
68%type <re> v0_memreserves
David Gibson9ed27a22007-11-07 11:16:19 +110069%type <addr> addr
David Gibsonfc14dad2005-06-08 17:18:34 +100070%type <data> celllist
David Gibson9ed27a22007-11-07 11:16:19 +110071%type <cbase> cellbase
72%type <cell> cellval
David Gibsonfc14dad2005-06-08 17:18:34 +100073%type <data> bytestring
74%type <prop> propdef
75%type <proplist> proplist
76
David Gibsonf0517db2005-07-15 17:14:24 +100077%type <node> devicetree
David Gibsonfc14dad2005-06-08 17:18:34 +100078%type <node> nodedef
79%type <node> subnode
80%type <nodelist> subnodes
David Gibson9ed27a22007-11-07 11:16:19 +110081%type <labelref> label
David Gibson4102d842005-06-16 14:36:37 +100082
David Gibsonfc14dad2005-06-08 17:18:34 +100083%%
84
Jon Loeliger30807ca2007-10-18 09:42:16 -050085sourcefile:
David Gibson9138db52007-11-07 11:17:17 +110086 DT_V1 ';' memreserves devicetree
87 {
88 the_boot_info = build_boot_info($3, $4);
89 }
90 | v0_memreserves devicetree
Jon Loeliger30807ca2007-10-18 09:42:16 -050091 {
David Gibsonf0517db2005-07-15 17:14:24 +100092 the_boot_info = build_boot_info($1, $2);
93 }
94 ;
95
Jon Loeliger30807ca2007-10-18 09:42:16 -050096memreserves:
Jon Loeliger56412892007-10-23 09:28:54 -050097 /* empty */
Jon Loeliger30807ca2007-10-18 09:42:16 -050098 {
David Gibsonf040d952005-10-24 18:18:38 +100099 $$ = NULL;
David Gibsonf0517db2005-07-15 17:14:24 +1000100 }
Jon Loeliger56412892007-10-23 09:28:54 -0500101 | memreserve memreserves
102 {
103 $$ = chain_reserve_entry($1, $2);
104 }
David Gibsonf0517db2005-07-15 17:14:24 +1000105 ;
106
Jon Loeliger30807ca2007-10-18 09:42:16 -0500107memreserve:
David Gibson9ed27a22007-11-07 11:16:19 +1100108 label DT_MEMRESERVE addr addr ';'
Jon Loeliger30807ca2007-10-18 09:42:16 -0500109 {
Milton Millerd4290332007-07-07 01:18:49 -0500110 $$ = build_reserve_entry($3, $4, $1);
David Gibsonf0517db2005-07-15 17:14:24 +1000111 }
David Gibson9138db52007-11-07 11:17:17 +1100112 ;
113
114v0_memreserves:
115 /* empty */
116 {
117 $$ = NULL;
118 }
119 | v0_memreserve v0_memreserves
120 {
121 $$ = chain_reserve_entry($1, $2);
122 };
123 ;
124
125v0_memreserve:
126 memreserve
127 {
128 $$ = $1;
129 }
David Gibson9ed27a22007-11-07 11:16:19 +1100130 | label DT_MEMRESERVE addr '-' addr ';'
Jon Loeliger30807ca2007-10-18 09:42:16 -0500131 {
Milton Millerd4290332007-07-07 01:18:49 -0500132 $$ = build_reserve_entry($3, $5 - $3 + 1, $1);
David Gibsonf0517db2005-07-15 17:14:24 +1000133 }
134 ;
135
David Gibson9ed27a22007-11-07 11:16:19 +1100136addr:
137 DT_LITERAL
138 {
David Gibson9138db52007-11-07 11:17:17 +1100139 $$ = eval_literal($1, 0, 64);
140 }
141 | DT_LEGACYLITERAL
142 {
David Gibson9ed27a22007-11-07 11:16:19 +1100143 $$ = eval_literal($1, 16, 64);
144 }
145 ;
146
Jon Loeliger30807ca2007-10-18 09:42:16 -0500147devicetree:
148 '/' nodedef
149 {
David Gibsonf0517db2005-07-15 17:14:24 +1000150 $$ = name_node($2, "", NULL);
151 }
David Gibsonfc14dad2005-06-08 17:18:34 +1000152 ;
153
Jon Loeliger30807ca2007-10-18 09:42:16 -0500154nodedef:
155 '{' proplist subnodes '}' ';'
156 {
David Gibsonfc14dad2005-06-08 17:18:34 +1000157 $$ = build_node($2, $3);
158 }
159 ;
160
Jon Loeliger30807ca2007-10-18 09:42:16 -0500161proplist:
Jon Loeliger56412892007-10-23 09:28:54 -0500162 /* empty */
Jon Loeliger30807ca2007-10-18 09:42:16 -0500163 {
David Gibsonfc14dad2005-06-08 17:18:34 +1000164 $$ = NULL;
165 }
Jon Loeliger7b3fb782007-10-22 16:09:56 -0500166 | proplist propdef
Jon Loeliger56412892007-10-23 09:28:54 -0500167 {
Jon Loeliger7b3fb782007-10-22 16:09:56 -0500168 $$ = chain_property($2, $1);
Jon Loeliger56412892007-10-23 09:28:54 -0500169 }
David Gibsonfc14dad2005-06-08 17:18:34 +1000170 ;
171
Jon Loeliger30807ca2007-10-18 09:42:16 -0500172propdef:
David Gibson9ed27a22007-11-07 11:16:19 +1100173 label DT_PROPNODENAME '=' propdata ';'
Jon Loeliger30807ca2007-10-18 09:42:16 -0500174 {
David Gibson4102d842005-06-16 14:36:37 +1000175 $$ = build_property($2, $4, $1);
David Gibsonfc14dad2005-06-08 17:18:34 +1000176 }
David Gibson9ed27a22007-11-07 11:16:19 +1100177 | label DT_PROPNODENAME ';'
Jon Loeliger30807ca2007-10-18 09:42:16 -0500178 {
David Gibson9ad45872005-06-17 14:32:32 +1000179 $$ = build_property($2, empty_data, $1);
David Gibsonfc14dad2005-06-08 17:18:34 +1000180 }
181 ;
182
Jon Loeliger30807ca2007-10-18 09:42:16 -0500183propdata:
184 propdataprefix DT_STRING
185 {
186 $$ = data_merge($1, $2);
David Gibson32da4752007-02-07 16:37:50 +1100187 }
Jon Loeliger30807ca2007-10-18 09:42:16 -0500188 | propdataprefix '<' celllist '>'
189 {
David Gibsonf7497dc2007-11-02 16:54:26 +1100190 $$ = data_merge($1, $3);
Jon Loeliger30807ca2007-10-18 09:42:16 -0500191 }
192 | propdataprefix '[' bytestring ']'
193 {
194 $$ = data_merge($1, $3);
195 }
David Gibsonefbbef82007-12-05 10:43:50 +1100196 | propdataprefix DT_REF
197 {
198 $$ = data_add_marker($1, REF_PATH, $2);
199 }
Jon Loeliger30807ca2007-10-18 09:42:16 -0500200 | propdata DT_LABEL
201 {
David Gibsondc941772007-11-22 14:39:23 +1100202 $$ = data_add_marker($1, LABEL, $2);
Jon Loeliger30807ca2007-10-18 09:42:16 -0500203 }
David Gibson32da4752007-02-07 16:37:50 +1100204 ;
205
Jon Loeliger30807ca2007-10-18 09:42:16 -0500206propdataprefix:
Jon Loeliger56412892007-10-23 09:28:54 -0500207 /* empty */
208 {
209 $$ = empty_data;
210 }
211 | propdata ','
Jon Loeliger30807ca2007-10-18 09:42:16 -0500212 {
213 $$ = $1;
214 }
215 | propdataprefix DT_LABEL
216 {
David Gibsondc941772007-11-22 14:39:23 +1100217 $$ = data_add_marker($1, LABEL, $2);
Jon Loeliger30807ca2007-10-18 09:42:16 -0500218 }
David Gibsonfc14dad2005-06-08 17:18:34 +1000219 ;
220
Jon Loeliger30807ca2007-10-18 09:42:16 -0500221celllist:
Jon Loeliger56412892007-10-23 09:28:54 -0500222 /* empty */
223 {
224 $$ = empty_data;
225 }
David Gibson9ed27a22007-11-07 11:16:19 +1100226 | celllist cellval
Jon Loeliger30807ca2007-10-18 09:42:16 -0500227 {
David Gibson9ed27a22007-11-07 11:16:19 +1100228 $$ = data_append_cell($1, $2);
Jon Loeligeraf0278a2007-02-15 10:59:27 -0600229 }
Jon Loeliger30807ca2007-10-18 09:42:16 -0500230 | celllist DT_REF
231 {
David Gibsondc941772007-11-22 14:39:23 +1100232 $$ = data_append_cell(data_add_marker($1, REF_PHANDLE,
233 $2), -1);
David Gibson81f2e892005-06-16 17:04:00 +1000234 }
Jon Loeliger30807ca2007-10-18 09:42:16 -0500235 | celllist DT_LABEL
236 {
David Gibsondc941772007-11-22 14:39:23 +1100237 $$ = data_add_marker($1, LABEL, $2);
Jon Loeliger30807ca2007-10-18 09:42:16 -0500238 }
David Gibsonfc14dad2005-06-08 17:18:34 +1000239 ;
240
David Gibson9ed27a22007-11-07 11:16:19 +1100241cellbase:
242 /* empty */
243 {
244 $$ = 16;
245 }
246 | DT_BASE
247 ;
248
249cellval:
David Gibson9138db52007-11-07 11:17:17 +1100250 DT_LITERAL
251 {
252 $$ = eval_literal($1, 0, 32);
253 }
254 | cellbase DT_LEGACYLITERAL
David Gibson9ed27a22007-11-07 11:16:19 +1100255 {
256 $$ = eval_literal($2, $1, 32);
257 }
258 ;
259
Jon Loeliger30807ca2007-10-18 09:42:16 -0500260bytestring:
Jon Loeliger56412892007-10-23 09:28:54 -0500261 /* empty */
262 {
263 $$ = empty_data;
264 }
265 | bytestring DT_BYTE
Jon Loeliger30807ca2007-10-18 09:42:16 -0500266 {
267 $$ = data_append_byte($1, $2);
268 }
269 | bytestring DT_LABEL
270 {
David Gibsondc941772007-11-22 14:39:23 +1100271 $$ = data_add_marker($1, LABEL, $2);
Jon Loeliger30807ca2007-10-18 09:42:16 -0500272 }
David Gibsonfc14dad2005-06-08 17:18:34 +1000273 ;
274
Jon Loeliger30807ca2007-10-18 09:42:16 -0500275subnodes:
Jon Loeliger56412892007-10-23 09:28:54 -0500276 /* empty */
Jon Loeliger30807ca2007-10-18 09:42:16 -0500277 {
278 $$ = NULL;
279 }
Jon Loeliger56412892007-10-23 09:28:54 -0500280 | subnode subnodes
281 {
282 $$ = chain_node($1, $2);
283 }
David Gibsonc0481022007-12-05 10:27:04 +1100284 | subnode propdef
285 {
Scott Wood3c3ecaa2008-01-04 15:10:47 -0600286 yyerror("syntax error: properties must precede subnodes");
David Gibsonc0481022007-12-05 10:27:04 +1100287 YYERROR;
288 }
David Gibsonfc14dad2005-06-08 17:18:34 +1000289 ;
290
Jon Loeliger30807ca2007-10-18 09:42:16 -0500291subnode:
David Gibson9ed27a22007-11-07 11:16:19 +1100292 label DT_PROPNODENAME nodedef
Jon Loeliger30807ca2007-10-18 09:42:16 -0500293 {
294 $$ = name_node($3, $2, $1);
295 }
David Gibson4102d842005-06-16 14:36:37 +1000296 ;
297
Jon Loeliger30807ca2007-10-18 09:42:16 -0500298label:
Jon Loeliger56412892007-10-23 09:28:54 -0500299 /* empty */
Jon Loeliger30807ca2007-10-18 09:42:16 -0500300 {
301 $$ = NULL;
302 }
Jon Loeliger56412892007-10-23 09:28:54 -0500303 | DT_LABEL
304 {
305 $$ = $1;
306 }
David Gibsonfc14dad2005-06-08 17:18:34 +1000307 ;
308
309%%
310
Scott Woodf77fe6a2008-01-03 17:43:29 -0600311void yyerrorf(char const *s, ...)
David Gibsonfc14dad2005-06-08 17:18:34 +1000312{
Scott Wood910efac2008-01-03 17:43:31 -0600313 const char *fname = srcpos_file ? srcpos_file->name : "<no-file>";
Scott Woodf77fe6a2008-01-03 17:43:29 -0600314 va_list va;
315 va_start(va, s);
Jon Loeligere45e6fd2007-03-23 15:18:41 -0500316
317 if (strcmp(fname, "-") == 0)
318 fname = "stdin";
319
Scott Woodf77fe6a2008-01-03 17:43:29 -0600320 fprintf(stderr, "%s:%d ", fname, yylloc.first_line);
321 vfprintf(stderr, s, va);
322 fprintf(stderr, "\n");
323
Scott Woodad4f54a2008-01-03 17:43:33 -0600324 treesource_error = 1;
Scott Woodf77fe6a2008-01-03 17:43:29 -0600325 va_end(va);
326}
327
328void yyerror (char const *s)
329{
330 yyerrorf("%s", s);
David Gibsonfc14dad2005-06-08 17:18:34 +1000331}
Jon Loeliger39488492007-02-16 09:33:54 -0600332
David Gibson6b8e0562008-03-05 11:47:54 +1100333static unsigned long long eval_literal(const char *s, int base, int bits)
Jon Loeliger39488492007-02-16 09:33:54 -0600334{
David Gibson9ed27a22007-11-07 11:16:19 +1100335 unsigned long long val;
Milton Miller85ab5cc2007-07-07 01:18:48 -0500336 char *e;
Jon Loeliger39488492007-02-16 09:33:54 -0600337
David Gibson9ed27a22007-11-07 11:16:19 +1100338 errno = 0;
339 val = strtoull(s, &e, base);
340 if (*e)
341 yyerror("bad characters in literal");
342 else if ((errno == ERANGE)
343 || ((bits < 64) && (val >= (1ULL << bits))))
344 yyerror("literal out of range");
345 else if (errno != 0)
346 yyerror("bad literal");
347 return val;
Jon Loeliger39488492007-02-16 09:33:54 -0600348}